diff options
| author | whitespace / reindent <invalid@invalid.invalid> | 2017-07-17 14:03:14 +0200 | 
|---|---|---|
| committer | whitespace / reindent <invalid@invalid.invalid> | 2017-07-17 14:04:07 +0200 | 
| commit | d62a17aedeb0eebdba98238874bb13d62c48dbf9 (patch) | |
| tree | 3b319b1d61c8b85b4d1f06adf8b844bb8a9b5107 /pimd/pim_zebra.c | |
| parent | 888ac268a0077fc9ebd1218cec6ae472af0bfc40 (diff) | |
*: reindentreindent-master-after
indent.py `git ls-files | pcregrep '\.[ch]$' | pcregrep -v '^(ldpd|babeld|nhrpd)/'`
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'pimd/pim_zebra.c')
| -rw-r--r-- | pimd/pim_zebra.c | 1994 | 
1 files changed, 1027 insertions, 967 deletions
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index b4fff97120..c5cca7d1b4 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -58,906 +58,950 @@ static struct zclient *zclient = NULL;  static int pim_router_id_update_zebra(int command, struct zclient *zclient,  				      zebra_size_t length, vrf_id_t vrf_id)  { -  struct prefix router_id; +	struct prefix router_id; -  zebra_router_id_update_read(zclient->ibuf, &router_id); +	zebra_router_id_update_read(zclient->ibuf, &router_id); -  return 0; +	return 0;  }  static int pim_zebra_if_add(int command, struct zclient *zclient,  			    zebra_size_t length, vrf_id_t vrf_id)  { -  struct interface *ifp; - -  /* -    zebra api adds/dels interfaces using the same call -    interface_add_read below, see comments in lib/zclient.c -  */ -  ifp = zebra_interface_add_read(zclient->ibuf, vrf_id); -  if (!ifp) -    return 0; - -  if (PIM_DEBUG_ZEBRA) { -    zlog_debug("%s: %s index %d flags %ld metric %d mtu %d operative %d", -	       __PRETTY_FUNCTION__, -	       ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric, -	       ifp->mtu, if_is_operative(ifp)); -  } - -  if (if_is_operative(ifp)) -    pim_if_addr_add_all(ifp); - -  return 0; +	struct interface *ifp; + +	/* +	  zebra api adds/dels interfaces using the same call +	  interface_add_read below, see comments in lib/zclient.c +	*/ +	ifp = zebra_interface_add_read(zclient->ibuf, vrf_id); +	if (!ifp) +		return 0; + +	if (PIM_DEBUG_ZEBRA) { +		zlog_debug( +			"%s: %s index %d flags %ld metric %d mtu %d operative %d", +			__PRETTY_FUNCTION__, ifp->name, ifp->ifindex, +			(long)ifp->flags, ifp->metric, ifp->mtu, +			if_is_operative(ifp)); +	} + +	if (if_is_operative(ifp)) +		pim_if_addr_add_all(ifp); + +	return 0;  }  static int pim_zebra_if_del(int command, struct zclient *zclient,  			    zebra_size_t length, vrf_id_t vrf_id)  { -  struct interface *ifp; - -  /* -    zebra api adds/dels interfaces using the same call -    interface_add_read below, see comments in lib/zclient.c -     -    comments in lib/zclient.c seem to indicate that calling -    zebra_interface_add_read is the correct call, but that -    results in an attemted out of bounds read which causes -    pimd to assert. Other clients use zebra_interface_state_read -    and it appears to work just fine. -  */ -  ifp = zebra_interface_state_read(zclient->ibuf, vrf_id); -  if (!ifp) -    return 0; - -  if (PIM_DEBUG_ZEBRA) { -    zlog_debug("%s: %s index %d flags %ld metric %d mtu %d operative %d", -	       __PRETTY_FUNCTION__, -	       ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric, -	       ifp->mtu, if_is_operative(ifp)); -  } - -  if (!if_is_operative(ifp)) -    pim_if_addr_del_all(ifp); - -  return 0; +	struct interface *ifp; + +	/* +	  zebra api adds/dels interfaces using the same call +	  interface_add_read below, see comments in lib/zclient.c + +	  comments in lib/zclient.c seem to indicate that calling +	  zebra_interface_add_read is the correct call, but that +	  results in an attemted out of bounds read which causes +	  pimd to assert. Other clients use zebra_interface_state_read +	  and it appears to work just fine. +	*/ +	ifp = zebra_interface_state_read(zclient->ibuf, vrf_id); +	if (!ifp) +		return 0; + +	if (PIM_DEBUG_ZEBRA) { +		zlog_debug( +			"%s: %s index %d flags %ld metric %d mtu %d operative %d", +			__PRETTY_FUNCTION__, ifp->name, ifp->ifindex, +			(long)ifp->flags, ifp->metric, ifp->mtu, +			if_is_operative(ifp)); +	} + +	if (!if_is_operative(ifp)) +		pim_if_addr_del_all(ifp); + +	return 0;  }  static int pim_zebra_if_state_up(int command, struct zclient *zclient,  				 zebra_size_t length, vrf_id_t vrf_id)  { -  struct interface *ifp; - -  /* -    zebra api notifies interface up/down events by using the same call -    zebra_interface_state_read below, see comments in lib/zclient.c -  */ -  ifp = zebra_interface_state_read(zclient->ibuf, vrf_id); -  if (!ifp) -    return 0; - -  if (PIM_DEBUG_ZEBRA) { -    zlog_debug("%s: %s index %d flags %ld metric %d mtu %d operative %d", -	       __PRETTY_FUNCTION__, -	       ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric, -	       ifp->mtu, if_is_operative(ifp)); -  } - -  if (if_is_operative(ifp)) { -    /* -      pim_if_addr_add_all() suffices for bringing up both IGMP and PIM -    */ -    pim_if_addr_add_all(ifp); -  } - -  return 0; +	struct interface *ifp; + +	/* +	  zebra api notifies interface up/down events by using the same call +	  zebra_interface_state_read below, see comments in lib/zclient.c +	*/ +	ifp = zebra_interface_state_read(zclient->ibuf, vrf_id); +	if (!ifp) +		return 0; + +	if (PIM_DEBUG_ZEBRA) { +		zlog_debug( +			"%s: %s index %d flags %ld metric %d mtu %d operative %d", +			__PRETTY_FUNCTION__, ifp->name, ifp->ifindex, +			(long)ifp->flags, ifp->metric, ifp->mtu, +			if_is_operative(ifp)); +	} + +	if (if_is_operative(ifp)) { +		/* +		  pim_if_addr_add_all() suffices for bringing up both IGMP and +		  PIM +		*/ +		pim_if_addr_add_all(ifp); +	} + +	return 0;  }  static int pim_zebra_if_state_down(int command, struct zclient *zclient,  				   zebra_size_t length, vrf_id_t vrf_id)  { -  struct interface *ifp; - -  /* -    zebra api notifies interface up/down events by using the same call -    zebra_interface_state_read below, see comments in lib/zclient.c -  */ -  ifp = zebra_interface_state_read(zclient->ibuf, vrf_id); -  if (!ifp) -    return 0; - -  if (PIM_DEBUG_ZEBRA) { -    zlog_debug("%s: %s index %d flags %ld metric %d mtu %d operative %d", -	       __PRETTY_FUNCTION__, -	       ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric, -	       ifp->mtu, if_is_operative(ifp)); -  } - -  if (!if_is_operative(ifp)) { -    pim_ifchannel_delete_all(ifp); -    /* -      pim_if_addr_del_all() suffices for shutting down IGMP, -      but not for shutting down PIM -    */ -    pim_if_addr_del_all(ifp); - -    /* -      pim_sock_delete() closes the socket, stops read and timer threads, -      and kills all neighbors. -    */ -    if (ifp->info) { -      pim_sock_delete(ifp, "link down"); -    } -  } - -  if (ifp->info) -    pim_if_del_vif(ifp); - -  return 0; +	struct interface *ifp; + +	/* +	  zebra api notifies interface up/down events by using the same call +	  zebra_interface_state_read below, see comments in lib/zclient.c +	*/ +	ifp = zebra_interface_state_read(zclient->ibuf, vrf_id); +	if (!ifp) +		return 0; + +	if (PIM_DEBUG_ZEBRA) { +		zlog_debug( +			"%s: %s index %d flags %ld metric %d mtu %d operative %d", +			__PRETTY_FUNCTION__, ifp->name, ifp->ifindex, +			(long)ifp->flags, ifp->metric, ifp->mtu, +			if_is_operative(ifp)); +	} + +	if (!if_is_operative(ifp)) { +		pim_ifchannel_delete_all(ifp); +		/* +		  pim_if_addr_del_all() suffices for shutting down IGMP, +		  but not for shutting down PIM +		*/ +		pim_if_addr_del_all(ifp); + +		/* +		  pim_sock_delete() closes the socket, stops read and timer +		  threads, +		  and kills all neighbors. +		*/ +		if (ifp->info) { +			pim_sock_delete(ifp, "link down"); +		} +	} + +	if (ifp->info) +		pim_if_del_vif(ifp); + +	return 0;  }  #ifdef PIM_DEBUG_IFADDR_DUMP  static void dump_if_address(struct interface *ifp)  { -  struct connected *ifc; -  struct listnode *node; - -  zlog_debug("%s %s: interface %s addresses:", -	     __FILE__, __PRETTY_FUNCTION__, -	     ifp->name); -   -  for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) { -    struct prefix *p = ifc->address; -     -    if (p->family != AF_INET) -      continue; -     -    zlog_debug("%s %s: interface %s address %s %s", -	       __FILE__, __PRETTY_FUNCTION__, -	       ifp->name, -	       inet_ntoa(p->u.prefix4), -	       CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) ?  -	       "secondary" : "primary"); -  } +	struct connected *ifc; +	struct listnode *node; + +	zlog_debug("%s %s: interface %s addresses:", __FILE__, +		   __PRETTY_FUNCTION__, ifp->name); + +	for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) { +		struct prefix *p = ifc->address; + +		if (p->family != AF_INET) +			continue; + +		zlog_debug("%s %s: interface %s address %s %s", __FILE__, +			   __PRETTY_FUNCTION__, ifp->name, +			   inet_ntoa(p->u.prefix4), +			   CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) +				   ? "secondary" +				   : "primary"); +	}  }  #endif  static int pim_zebra_if_address_add(int command, struct zclient *zclient,  				    zebra_size_t length, vrf_id_t vrf_id)  { -  struct connected *c; -  struct prefix *p; -  struct pim_interface *pim_ifp; - -  /* -    zebra api notifies address adds/dels events by using the same call -    interface_add_read below, see comments in lib/zclient.c - -    zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD, ...) -    will add address to interface list by calling -    connected_add_by_prefix() -  */ -  c = zebra_interface_address_read(command, zclient->ibuf, vrf_id); -  if (!c) -    return 0; - -  pim_ifp = c->ifp->info; -  p = c->address; - -  if (PIM_DEBUG_ZEBRA) { -    char buf[BUFSIZ]; -    prefix2str(p, buf, BUFSIZ); -    zlog_debug("%s: %s connected IP address %s flags %u %s", -	       __PRETTY_FUNCTION__, -	       c->ifp->name, buf, c->flags, -	       CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY) ? "secondary" : "primary"); -     +	struct connected *c; +	struct prefix *p; +	struct pim_interface *pim_ifp; + +	/* +	  zebra api notifies address adds/dels events by using the same call +	  interface_add_read below, see comments in lib/zclient.c + +	  zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD, ...) +	  will add address to interface list by calling +	  connected_add_by_prefix() +	*/ +	c = zebra_interface_address_read(command, zclient->ibuf, vrf_id); +	if (!c) +		return 0; + +	pim_ifp = c->ifp->info; +	p = c->address; + +	if (PIM_DEBUG_ZEBRA) { +		char buf[BUFSIZ]; +		prefix2str(p, buf, BUFSIZ); +		zlog_debug("%s: %s connected IP address %s flags %u %s", +			   __PRETTY_FUNCTION__, c->ifp->name, buf, c->flags, +			   CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY) +				   ? "secondary" +				   : "primary"); +  #ifdef PIM_DEBUG_IFADDR_DUMP -    dump_if_address(c->ifp); +		dump_if_address(c->ifp);  #endif -  } +	} -  if (!CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)) { -    /* trying to add primary address */ +	if (!CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)) { +		/* trying to add primary address */ -    struct in_addr primary_addr = pim_find_primary_addr(c->ifp); -    if (p->family != AF_INET || primary_addr.s_addr != p->u.prefix4.s_addr) { -      if (PIM_DEBUG_ZEBRA) { -	/* but we had a primary address already */ +		struct in_addr primary_addr = pim_find_primary_addr(c->ifp); +		if (p->family != AF_INET +		    || primary_addr.s_addr != p->u.prefix4.s_addr) { +			if (PIM_DEBUG_ZEBRA) { +				/* but we had a primary address already */ -	char buf[BUFSIZ]; +				char buf[BUFSIZ]; -	prefix2str(p, buf, BUFSIZ); +				prefix2str(p, buf, BUFSIZ); -	zlog_warn("%s: %s : forcing secondary flag on %s", -		  __PRETTY_FUNCTION__, -		  c->ifp->name, buf); -      } -      SET_FLAG(c->flags, ZEBRA_IFA_SECONDARY); -    } -  } +				zlog_warn( +					"%s: %s : forcing secondary flag on %s", +					__PRETTY_FUNCTION__, c->ifp->name, buf); +			} +			SET_FLAG(c->flags, ZEBRA_IFA_SECONDARY); +		} +	} -  pim_if_addr_add(c); -  if (pim_ifp) -    pim_rp_check_on_if_add(pim_ifp); +	pim_if_addr_add(c); +	if (pim_ifp) +		pim_rp_check_on_if_add(pim_ifp); -  if (if_is_loopback (c->ifp)) -    { -      struct listnode *ifnode; -      struct interface *ifp; +	if (if_is_loopback(c->ifp)) { +		struct listnode *ifnode; +		struct interface *ifp; -      for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) -        { -	  if (!if_is_loopback (ifp) && if_is_operative (ifp)) -	    pim_if_addr_add_all (ifp); -        } -    } +		for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), ifnode, +					  ifp)) { +			if (!if_is_loopback(ifp) && if_is_operative(ifp)) +				pim_if_addr_add_all(ifp); +		} +	} -  return 0; +	return 0;  }  static int pim_zebra_if_address_del(int command, struct zclient *client,  				    zebra_size_t length, vrf_id_t vrf_id)  { -  struct connected *c; -  struct prefix *p; - -  /* -    zebra api notifies address adds/dels events by using the same call -    interface_add_read below, see comments in lib/zclient.c - -    zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE, ...) -    will remove address from interface list by calling -    connected_delete_by_prefix() -  */ -  c = zebra_interface_address_read(command, client->ibuf, vrf_id); -  if (!c) -    return 0; -   -  p = c->address; -  if (p->family == AF_INET) -    { -        if (PIM_DEBUG_ZEBRA) { -          char buf[BUFSIZ]; -          prefix2str(p, buf, BUFSIZ); -          zlog_debug("%s: %s disconnected IP address %s flags %u %s", -                     __PRETTY_FUNCTION__, -                     c->ifp->name, buf, c->flags, -                     CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY) ? "secondary" : "primary"); +	struct connected *c; +	struct prefix *p; + +	/* +	  zebra api notifies address adds/dels events by using the same call +	  interface_add_read below, see comments in lib/zclient.c + +	  zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE, ...) +	  will remove address from interface list by calling +	  connected_delete_by_prefix() +	*/ +	c = zebra_interface_address_read(command, client->ibuf, vrf_id); +	if (!c) +		return 0; + +	p = c->address; +	if (p->family == AF_INET) { +		if (PIM_DEBUG_ZEBRA) { +			char buf[BUFSIZ]; +			prefix2str(p, buf, BUFSIZ); +			zlog_debug( +				"%s: %s disconnected IP address %s flags %u %s", +				__PRETTY_FUNCTION__, c->ifp->name, buf, +				c->flags, +				CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY) +					? "secondary" +					: "primary");  #ifdef PIM_DEBUG_IFADDR_DUMP -          dump_if_address(c->ifp); +			dump_if_address(c->ifp);  #endif -        } +		} -        pim_if_addr_del(c, 0); -        pim_rp_setup(); -        pim_i_am_rp_re_evaluate(); -    } +		pim_if_addr_del(c, 0); +		pim_rp_setup(); +		pim_i_am_rp_re_evaluate(); +	} -  connected_free (c); -  return 0; +	connected_free(c); +	return 0;  }  static void scan_upstream_rpf_cache()  { -  struct listnode     *up_node; -  struct listnode     *ifnode; -  struct listnode     *up_nextnode; -  struct listnode     *node; -  struct pim_upstream *up; -  struct interface    *ifp; - -  for (ALL_LIST_ELEMENTS(pim_upstream_list, up_node, up_nextnode, up)) { -    enum pim_rpf_result rpf_result; -    struct pim_rpf      old; -    struct prefix nht_p; - -    nht_p.family = AF_INET; -    nht_p.prefixlen = IPV4_MAX_BITLEN; -    nht_p.u.prefix4.s_addr = up->upstream_addr.s_addr; -    pim_resolve_upstream_nh (&nht_p); - -    old.source_nexthop.interface = up->rpf.source_nexthop.interface; -    old.source_nexthop.nbr       = up->rpf.source_nexthop.nbr; -    rpf_result = pim_rpf_update(up, &old, 0); - -    if (rpf_result == PIM_RPF_FAILURE) -      continue; - -    if (rpf_result == PIM_RPF_CHANGED) { -      struct pim_neighbor *nbr; - -      nbr = pim_neighbor_find (old.source_nexthop.interface, -                               old.rpf_addr.u.prefix4); -      if (nbr) -        pim_jp_agg_remove_group (nbr->upstream_jp_agg, up); - -      /* -       * We have detected a case where we might need to rescan -       * the inherited o_list so do it. -       */ -      if (up->channel_oil->oil_inherited_rescan) -	{ -	  pim_upstream_inherited_olist_decide (up); -	  up->channel_oil->oil_inherited_rescan = 0; -	} - -      if (up->join_state == PIM_UPSTREAM_JOINED) { -	/* -         * If we come up real fast we can be here -	 * where the mroute has not been installed -	 * so install it. -	 */ -	if (!up->channel_oil->installed) -	  pim_mroute_add (up->channel_oil, __PRETTY_FUNCTION__); - -        /* -         * RFC 4601: 4.5.7.  Sending (S,G) Join/Prune Messages -         * -         * Transitions from Joined State -         * -         * RPF'(S,G) changes not due to an Assert -         * -         * The upstream (S,G) state machine remains in Joined -         * state. Send Join(S,G) to the new upstream neighbor, which is -         * the new value of RPF'(S,G).  Send Prune(S,G) to the old -         * upstream neighbor, which is the old value of RPF'(S,G).  Set -         * the Join Timer (JT) to expire after t_periodic seconds. -         */ -        pim_jp_agg_switch_interface (&old, &up->rpf, up); - -        pim_upstream_join_timer_restart(up, &old); -      } /* up->join_state == PIM_UPSTREAM_JOINED */ - -      /* FIXME can join_desired actually be changed by pim_rpf_update() -	 returning PIM_RPF_CHANGED ? */ -      pim_upstream_update_join_desired(up); - -    } /* PIM_RPF_CHANGED */ - -  } /* for (qpim_upstream_list) */ - -  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) -    if (ifp->info) -      { -        struct pim_interface *pim_ifp = ifp->info; -        struct pim_iface_upstream_switch *us; - -        for (ALL_LIST_ELEMENTS_RO(pim_ifp->upstream_switch_list, node, us)) -          { -            struct pim_rpf rpf; -            rpf.source_nexthop.interface = ifp; -            rpf.rpf_addr.u.prefix4 = us->address; -            pim_joinprune_send(&rpf, us->us); -            pim_jp_agg_clear_group(us->us); -          } -      } +	struct listnode *up_node; +	struct listnode *ifnode; +	struct listnode *up_nextnode; +	struct listnode *node; +	struct pim_upstream *up; +	struct interface *ifp; + +	for (ALL_LIST_ELEMENTS(pim_upstream_list, up_node, up_nextnode, up)) { +		enum pim_rpf_result rpf_result; +		struct pim_rpf old; +		struct prefix nht_p; + +		nht_p.family = AF_INET; +		nht_p.prefixlen = IPV4_MAX_BITLEN; +		nht_p.u.prefix4.s_addr = up->upstream_addr.s_addr; +		pim_resolve_upstream_nh(&nht_p); + +		old.source_nexthop.interface = up->rpf.source_nexthop.interface; +		old.source_nexthop.nbr = up->rpf.source_nexthop.nbr; +		rpf_result = pim_rpf_update(up, &old, 0); + +		if (rpf_result == PIM_RPF_FAILURE) +			continue; + +		if (rpf_result == PIM_RPF_CHANGED) { +			struct pim_neighbor *nbr; + +			nbr = pim_neighbor_find(old.source_nexthop.interface, +						old.rpf_addr.u.prefix4); +			if (nbr) +				pim_jp_agg_remove_group(nbr->upstream_jp_agg, +							up); + +			/* +			 * We have detected a case where we might need to rescan +			 * the inherited o_list so do it. +			 */ +			if (up->channel_oil->oil_inherited_rescan) { +				pim_upstream_inherited_olist_decide(up); +				up->channel_oil->oil_inherited_rescan = 0; +			} + +			if (up->join_state == PIM_UPSTREAM_JOINED) { +				/* +				 * If we come up real fast we can be here +				 * where the mroute has not been installed +				 * so install it. +				 */ +				if (!up->channel_oil->installed) +					pim_mroute_add(up->channel_oil, +						       __PRETTY_FUNCTION__); + +				/* +				 * RFC 4601: 4.5.7.  Sending (S,G) Join/Prune +				 * Messages +				 * +				 * Transitions from Joined State +				 * +				 * RPF'(S,G) changes not due to an Assert +				 * +				 * The upstream (S,G) state machine remains in +				 * Joined +				 * state. Send Join(S,G) to the new upstream +				 * neighbor, which is +				 * the new value of RPF'(S,G).  Send Prune(S,G) +				 * to the old +				 * upstream neighbor, which is the old value of +				 * RPF'(S,G).  Set +				 * the Join Timer (JT) to expire after +				 * t_periodic seconds. +				 */ +				pim_jp_agg_switch_interface(&old, &up->rpf, up); + +				pim_upstream_join_timer_restart(up, &old); +			} /* up->join_state == PIM_UPSTREAM_JOINED */ + +			/* FIXME can join_desired actually be changed by +			   pim_rpf_update() +			   returning PIM_RPF_CHANGED ? */ +			pim_upstream_update_join_desired(up); + +		} /* PIM_RPF_CHANGED */ + +	} /* for (qpim_upstream_list) */ + +	for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), ifnode, ifp)) +		if (ifp->info) { +			struct pim_interface *pim_ifp = ifp->info; +			struct pim_iface_upstream_switch *us; + +			for (ALL_LIST_ELEMENTS_RO(pim_ifp->upstream_switch_list, +						  node, us)) { +				struct pim_rpf rpf; +				rpf.source_nexthop.interface = ifp; +				rpf.rpf_addr.u.prefix4 = us->address; +				pim_joinprune_send(&rpf, us->us); +				pim_jp_agg_clear_group(us->us); +			} +		}  } -void -pim_scan_individual_oil (struct channel_oil *c_oil, int in_vif_index) +void pim_scan_individual_oil(struct channel_oil *c_oil, int in_vif_index)  { -  struct in_addr vif_source; -  int input_iface_vif_index; -  int old_vif_index; - -  if (!pim_rp_set_upstream_addr (&vif_source, c_oil->oil.mfcc_origin, c_oil->oil.mfcc_mcastgrp)) -    return; - -  if (in_vif_index) -    input_iface_vif_index = in_vif_index; -  else -    { -      struct prefix src, grp; - -      src.family = AF_INET; -      src.prefixlen = IPV4_MAX_BITLEN; -      src.u.prefix4 = vif_source; -      grp.family = AF_INET; -      grp.prefixlen = IPV4_MAX_BITLEN; -      grp.u.prefix4 = c_oil->oil.mfcc_mcastgrp; - -      if (PIM_DEBUG_ZEBRA) -        { -          char source_str[INET_ADDRSTRLEN]; -          char group_str[INET_ADDRSTRLEN]; -          pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str)); -          pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str)); -          zlog_debug ("%s: channel_oil (%s, %s) upstream info is not present.", -                      __PRETTY_FUNCTION__, source_str, group_str); -        } -      input_iface_vif_index = pim_ecmp_fib_lookup_if_vif_index(vif_source, &src, &grp); -    } - -  if (input_iface_vif_index < 1) -    { -      if (PIM_DEBUG_ZEBRA) -        { -          char source_str[INET_ADDRSTRLEN]; -          char group_str[INET_ADDRSTRLEN]; -          pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str)); -          pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str)); -          zlog_debug("%s %s: could not find input interface(%d) for (S,G)=(%s,%s)", -		     __FILE__, __PRETTY_FUNCTION__, c_oil->oil.mfcc_parent, -		     source_str, group_str); -        } -      pim_mroute_del (c_oil, __PRETTY_FUNCTION__); -      return; -    } - -  if (input_iface_vif_index == c_oil->oil.mfcc_parent) -    { -      if (!c_oil->installed) -        pim_mroute_add (c_oil, __PRETTY_FUNCTION__); - -      /* RPF unchanged */ -      return; -    } - -  if (PIM_DEBUG_ZEBRA) -    { -      struct interface *old_iif = pim_if_find_by_vif_index(c_oil->oil.mfcc_parent); -      struct interface *new_iif = pim_if_find_by_vif_index(input_iface_vif_index); -      char source_str[INET_ADDRSTRLEN]; -      char group_str[INET_ADDRSTRLEN]; -      pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str)); -      pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str)); -      zlog_debug("%s %s: (S,G)=(%s,%s) input interface changed from %s vif_index=%d to %s vif_index=%d", -		 __FILE__, __PRETTY_FUNCTION__, -		 source_str, group_str, -		 old_iif->name, c_oil->oil.mfcc_parent, -		 new_iif->name, input_iface_vif_index); -    } - -  /* new iif loops to existing oif ? */ -  if (c_oil->oil.mfcc_ttls[input_iface_vif_index]) -    { -      struct interface *new_iif = pim_if_find_by_vif_index(input_iface_vif_index); - -      if (PIM_DEBUG_ZEBRA) { -	char source_str[INET_ADDRSTRLEN]; -	char group_str[INET_ADDRSTRLEN]; -	pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str)); -	pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str)); -	zlog_debug("%s %s: (S,G)=(%s,%s) new iif loops to existing oif: %s vif_index=%d", -		   __FILE__, __PRETTY_FUNCTION__, -		   source_str, group_str, -		   new_iif->name, input_iface_vif_index); -      } -    } - -    /* update iif vif_index */ -    old_vif_index = c_oil->oil.mfcc_parent; -    c_oil->oil.mfcc_parent = input_iface_vif_index; - -    /* update kernel multicast forwarding cache (MFC) */ -    if (pim_mroute_add(c_oil, __PRETTY_FUNCTION__)) -      { -	if (PIM_DEBUG_MROUTE) -	  { -	    /* just log warning */ -	    struct interface *old_iif = pim_if_find_by_vif_index(old_vif_index); -	    struct interface *new_iif = pim_if_find_by_vif_index(input_iface_vif_index); -	    char source_str[INET_ADDRSTRLEN]; -	    char group_str[INET_ADDRSTRLEN]; -	    pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, sizeof(source_str)); -	    pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, sizeof(group_str)); -	    zlog_debug("%s %s: (S,G)=(%s,%s) failure updating input interface from %s vif_index=%d to %s vif_index=%d", -		       __FILE__, __PRETTY_FUNCTION__, -		       source_str, group_str, -		       old_iif ? old_iif->name : "<old_iif?>", c_oil->oil.mfcc_parent, -		       new_iif ? new_iif->name : "<new_iif?>", input_iface_vif_index); -	  } -    } +	struct in_addr vif_source; +	int input_iface_vif_index; +	int old_vif_index; + +	if (!pim_rp_set_upstream_addr(&vif_source, c_oil->oil.mfcc_origin, +				      c_oil->oil.mfcc_mcastgrp)) +		return; + +	if (in_vif_index) +		input_iface_vif_index = in_vif_index; +	else { +		struct prefix src, grp; + +		src.family = AF_INET; +		src.prefixlen = IPV4_MAX_BITLEN; +		src.u.prefix4 = vif_source; +		grp.family = AF_INET; +		grp.prefixlen = IPV4_MAX_BITLEN; +		grp.u.prefix4 = c_oil->oil.mfcc_mcastgrp; + +		if (PIM_DEBUG_ZEBRA) { +			char source_str[INET_ADDRSTRLEN]; +			char group_str[INET_ADDRSTRLEN]; +			pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, +				       source_str, sizeof(source_str)); +			pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, +				       group_str, sizeof(group_str)); +			zlog_debug( +				"%s: channel_oil (%s, %s) upstream info is not present.", +				__PRETTY_FUNCTION__, source_str, group_str); +		} +		input_iface_vif_index = pim_ecmp_fib_lookup_if_vif_index( +			vif_source, &src, &grp); +	} + +	if (input_iface_vif_index < 1) { +		if (PIM_DEBUG_ZEBRA) { +			char source_str[INET_ADDRSTRLEN]; +			char group_str[INET_ADDRSTRLEN]; +			pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, +				       source_str, sizeof(source_str)); +			pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, +				       group_str, sizeof(group_str)); +			zlog_debug( +				"%s %s: could not find input interface(%d) for (S,G)=(%s,%s)", +				__FILE__, __PRETTY_FUNCTION__, +				c_oil->oil.mfcc_parent, source_str, group_str); +		} +		pim_mroute_del(c_oil, __PRETTY_FUNCTION__); +		return; +	} + +	if (input_iface_vif_index == c_oil->oil.mfcc_parent) { +		if (!c_oil->installed) +			pim_mroute_add(c_oil, __PRETTY_FUNCTION__); + +		/* RPF unchanged */ +		return; +	} + +	if (PIM_DEBUG_ZEBRA) { +		struct interface *old_iif = +			pim_if_find_by_vif_index(c_oil->oil.mfcc_parent); +		struct interface *new_iif = +			pim_if_find_by_vif_index(input_iface_vif_index); +		char source_str[INET_ADDRSTRLEN]; +		char group_str[INET_ADDRSTRLEN]; +		pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str, +			       sizeof(source_str)); +		pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str, +			       sizeof(group_str)); +		zlog_debug( +			"%s %s: (S,G)=(%s,%s) input interface changed from %s vif_index=%d to %s vif_index=%d", +			__FILE__, __PRETTY_FUNCTION__, source_str, group_str, +			old_iif->name, c_oil->oil.mfcc_parent, new_iif->name, +			input_iface_vif_index); +	} + +	/* new iif loops to existing oif ? */ +	if (c_oil->oil.mfcc_ttls[input_iface_vif_index]) { +		struct interface *new_iif = +			pim_if_find_by_vif_index(input_iface_vif_index); + +		if (PIM_DEBUG_ZEBRA) { +			char source_str[INET_ADDRSTRLEN]; +			char group_str[INET_ADDRSTRLEN]; +			pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, +				       source_str, sizeof(source_str)); +			pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, +				       group_str, sizeof(group_str)); +			zlog_debug( +				"%s %s: (S,G)=(%s,%s) new iif loops to existing oif: %s vif_index=%d", +				__FILE__, __PRETTY_FUNCTION__, source_str, +				group_str, new_iif->name, +				input_iface_vif_index); +		} +	} + +	/* update iif vif_index */ +	old_vif_index = c_oil->oil.mfcc_parent; +	c_oil->oil.mfcc_parent = input_iface_vif_index; + +	/* update kernel multicast forwarding cache (MFC) */ +	if (pim_mroute_add(c_oil, __PRETTY_FUNCTION__)) { +		if (PIM_DEBUG_MROUTE) { +			/* just log warning */ +			struct interface *old_iif = +				pim_if_find_by_vif_index(old_vif_index); +			struct interface *new_iif = +				pim_if_find_by_vif_index(input_iface_vif_index); +			char source_str[INET_ADDRSTRLEN]; +			char group_str[INET_ADDRSTRLEN]; +			pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, +				       source_str, sizeof(source_str)); +			pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, +				       group_str, sizeof(group_str)); +			zlog_debug( +				"%s %s: (S,G)=(%s,%s) failure updating input interface from %s vif_index=%d to %s vif_index=%d", +				__FILE__, __PRETTY_FUNCTION__, source_str, +				group_str, +				old_iif ? old_iif->name : "<old_iif?>", +				c_oil->oil.mfcc_parent, +				new_iif ? new_iif->name : "<new_iif?>", +				input_iface_vif_index); +		} +	}  }  void pim_scan_oil()  { -  struct listnode    *node; -  struct listnode    *nextnode; -  struct channel_oil *c_oil; -  ifindex_t          ifindex; -  int                vif_index = 0; - -  qpim_scan_oil_last = pim_time_monotonic_sec(); -  ++qpim_scan_oil_events; - -  for (ALL_LIST_ELEMENTS(pim_channel_oil_list, node, nextnode, c_oil)) -    { -      if (c_oil->up && c_oil->up->rpf.source_nexthop.interface) -        { -          ifindex = c_oil->up->rpf.source_nexthop.interface->ifindex; -          vif_index = pim_if_find_vifindex_by_ifindex (ifindex); -          /* Pass Current selected NH vif index to mroute download */ -          if (vif_index) -            pim_scan_individual_oil (c_oil, vif_index); -        } -      else -        pim_scan_individual_oil (c_oil, 0); -    } +	struct listnode *node; +	struct listnode *nextnode; +	struct channel_oil *c_oil; +	ifindex_t ifindex; +	int vif_index = 0; + +	qpim_scan_oil_last = pim_time_monotonic_sec(); +	++qpim_scan_oil_events; + +	for (ALL_LIST_ELEMENTS(pim_channel_oil_list, node, nextnode, c_oil)) { +		if (c_oil->up && c_oil->up->rpf.source_nexthop.interface) { +			ifindex = c_oil->up->rpf.source_nexthop +					  .interface->ifindex; +			vif_index = pim_if_find_vifindex_by_ifindex(ifindex); +			/* Pass Current selected NH vif index to mroute download +			 */ +			if (vif_index) +				pim_scan_individual_oil(c_oil, vif_index); +		} else +			pim_scan_individual_oil(c_oil, 0); +	}  }  static int on_rpf_cache_refresh(struct thread *t)  { -  /* update PIM protocol state */ -  scan_upstream_rpf_cache(); +	/* update PIM protocol state */ +	scan_upstream_rpf_cache(); -  /* update kernel multicast forwarding cache (MFC) */ -  pim_scan_oil(); +	/* update kernel multicast forwarding cache (MFC) */ +	pim_scan_oil(); -  qpim_rpf_cache_refresh_last = pim_time_monotonic_sec(); -  ++qpim_rpf_cache_refresh_events; +	qpim_rpf_cache_refresh_last = pim_time_monotonic_sec(); +	++qpim_rpf_cache_refresh_events; -  //It is called as part of pim_neighbor_add -  //pim_rp_setup (); -  return 0; +	// It is called as part of pim_neighbor_add +	// pim_rp_setup (); +	return 0;  }  void sched_rpf_cache_refresh(void)  { -  ++qpim_rpf_cache_refresh_requests; +	++qpim_rpf_cache_refresh_requests; -  pim_rpf_set_refresh_time (); +	pim_rpf_set_refresh_time(); -  if (qpim_rpf_cache_refresher) { -    /* Refresh timer is already running */ -    return; -  } +	if (qpim_rpf_cache_refresher) { +		/* Refresh timer is already running */ +		return; +	} -  /* Start refresh timer */ +	/* Start refresh timer */ -  if (PIM_DEBUG_ZEBRA) { -    zlog_debug("%s: triggering %ld msec timer", -               __PRETTY_FUNCTION__, -               qpim_rpf_cache_refresh_delay_msec); -  } +	if (PIM_DEBUG_ZEBRA) { +		zlog_debug("%s: triggering %ld msec timer", __PRETTY_FUNCTION__, +			   qpim_rpf_cache_refresh_delay_msec); +	} -  thread_add_timer_msec(master, on_rpf_cache_refresh, 0, -                        qpim_rpf_cache_refresh_delay_msec, -                        &qpim_rpf_cache_refresher); +	thread_add_timer_msec(master, on_rpf_cache_refresh, 0, +			      qpim_rpf_cache_refresh_delay_msec, +			      &qpim_rpf_cache_refresher);  } -static void -pim_zebra_connected (struct zclient *zclient) +static void pim_zebra_connected(struct zclient *zclient)  { -  /* Send the client registration */ -  bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER); +	/* Send the client registration */ +	bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER); -  zclient_send_reg_requests (zclient, VRF_DEFAULT); +	zclient_send_reg_requests(zclient, VRF_DEFAULT);  }  void pim_zebra_init(void)  { -  int i; +	int i;  #ifdef HAVE_TCP_ZEBRA -  zlog_notice("zclient update contacting ZEBRA daemon at socket TCP %s,%d", "127.0.0.1", ZEBRA_PORT); +	zlog_notice( +		"zclient update contacting ZEBRA daemon at socket TCP %s,%d", +		"127.0.0.1", ZEBRA_PORT);  #else -  zlog_notice("zclient update contacting ZEBRA daemon at socket UNIX %s", zclient_serv_path_get()); +	zlog_notice("zclient update contacting ZEBRA daemon at socket UNIX %s", +		    zclient_serv_path_get());  #endif -  /* Socket for receiving updates from Zebra daemon */ -  zclient = zclient_new (master); - -  zclient->zebra_connected          = pim_zebra_connected; -  zclient->router_id_update         = pim_router_id_update_zebra; -  zclient->interface_add            = pim_zebra_if_add; -  zclient->interface_delete         = pim_zebra_if_del; -  zclient->interface_up             = pim_zebra_if_state_up; -  zclient->interface_down           = pim_zebra_if_state_down; -  zclient->interface_address_add    = pim_zebra_if_address_add; -  zclient->interface_address_delete = pim_zebra_if_address_del; -  zclient->nexthop_update           = pim_parse_nexthop_update; - -  zclient_init(zclient, ZEBRA_ROUTE_PIM, 0); -  if (PIM_DEBUG_PIM_TRACE) { -    zlog_info("zclient_init cleared redistribution request"); -  } - -  zassert(zclient->redist_default == ZEBRA_ROUTE_PIM); - -  /* Request all redistribution */ -  for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { -    if (i == zclient->redist_default) -      continue; -    vrf_bitmap_set (zclient->redist[AFI_IP][i], VRF_DEFAULT);; -    if (PIM_DEBUG_PIM_TRACE) { -      zlog_debug("%s: requesting redistribution for %s (%i)",  -		 __PRETTY_FUNCTION__, zebra_route_string(i), i); -    } -  } - -  /* Request default information */ -  zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_ADD, -				zclient, VRF_DEFAULT); -   -  if (PIM_DEBUG_PIM_TRACE) { -    zlog_info("%s: requesting default information redistribution", -	      __PRETTY_FUNCTION__); - -    zlog_notice("%s: zclient update socket initialized", -		__PRETTY_FUNCTION__); -  } - -  zclient_lookup_new(); +	/* Socket for receiving updates from Zebra daemon */ +	zclient = zclient_new(master); + +	zclient->zebra_connected = pim_zebra_connected; +	zclient->router_id_update = pim_router_id_update_zebra; +	zclient->interface_add = pim_zebra_if_add; +	zclient->interface_delete = pim_zebra_if_del; +	zclient->interface_up = pim_zebra_if_state_up; +	zclient->interface_down = pim_zebra_if_state_down; +	zclient->interface_address_add = pim_zebra_if_address_add; +	zclient->interface_address_delete = pim_zebra_if_address_del; +	zclient->nexthop_update = pim_parse_nexthop_update; + +	zclient_init(zclient, ZEBRA_ROUTE_PIM, 0); +	if (PIM_DEBUG_PIM_TRACE) { +		zlog_info("zclient_init cleared redistribution request"); +	} + +	zassert(zclient->redist_default == ZEBRA_ROUTE_PIM); + +	/* Request all redistribution */ +	for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { +		if (i == zclient->redist_default) +			continue; +		vrf_bitmap_set(zclient->redist[AFI_IP][i], VRF_DEFAULT); +		; +		if (PIM_DEBUG_PIM_TRACE) { +			zlog_debug("%s: requesting redistribution for %s (%i)", +				   __PRETTY_FUNCTION__, zebra_route_string(i), +				   i); +		} +	} + +	/* Request default information */ +	zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient, +				     VRF_DEFAULT); + +	if (PIM_DEBUG_PIM_TRACE) { +		zlog_info("%s: requesting default information redistribution", +			  __PRETTY_FUNCTION__); + +		zlog_notice("%s: zclient update socket initialized", +			    __PRETTY_FUNCTION__); +	} + +	zclient_lookup_new();  }  void igmp_anysource_forward_start(struct igmp_group *group)  { -  struct igmp_source *source; -  struct in_addr src_addr = { .s_addr = 0 }; -  /* Any source (*,G) is forwarded only if mode is EXCLUDE {empty} */ -  zassert(group->group_filtermode_isexcl); -  zassert(listcount(group->group_source_list) < 1); - -  source = source_new (group, src_addr); -  if (!source) -    { -      zlog_warn ("%s: Failure to create * source", __PRETTY_FUNCTION__); -      return; -    } - -  igmp_source_forward_start (source); +	struct igmp_source *source; +	struct in_addr src_addr = {.s_addr = 0}; +	/* Any source (*,G) is forwarded only if mode is EXCLUDE {empty} */ +	zassert(group->group_filtermode_isexcl); +	zassert(listcount(group->group_source_list) < 1); + +	source = source_new(group, src_addr); +	if (!source) { +		zlog_warn("%s: Failure to create * source", +			  __PRETTY_FUNCTION__); +		return; +	} + +	igmp_source_forward_start(source);  }  void igmp_anysource_forward_stop(struct igmp_group *group)  { -  struct igmp_source *source; -  struct in_addr star = { .s_addr = 0 }; +	struct igmp_source *source; +	struct in_addr star = {.s_addr = 0}; -  source = igmp_find_source_by_addr (group, star); -  if (source) -    igmp_source_forward_stop (source); +	source = igmp_find_source_by_addr(group, star); +	if (source) +		igmp_source_forward_stop(source);  } -static void -igmp_source_forward_reevaluate_one(struct igmp_source *source) +static void igmp_source_forward_reevaluate_one(struct igmp_source *source)  { -  struct prefix_sg sg; -  struct igmp_group *group = source->source_group; -  struct pim_ifchannel *ch; - -  if ((source->source_addr.s_addr != INADDR_ANY) || -      !IGMP_SOURCE_TEST_FORWARDING (source->source_flags)) -    return; - -  memset (&sg, 0, sizeof (struct prefix_sg)); -  sg.src = source->source_addr; -  sg.grp = group->group_addr; - -  ch = pim_ifchannel_find (group->group_igmp_sock->interface, &sg); -  if (pim_is_grp_ssm (group->group_addr)) -    { -      /* If SSM group withdraw local membership */ -      if (ch && (ch->local_ifmembership == PIM_IFMEMBERSHIP_INCLUDE)) -        { -          if (PIM_DEBUG_PIM_EVENTS) -            zlog_debug ("local membership del for %s as G is now SSM", -                        pim_str_sg_dump (&sg)); -          pim_ifchannel_local_membership_del (group->group_igmp_sock->interface, &sg); -        } -    } -  else -    { -      /* If ASM group add local membership */ -      if (!ch || (ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO)) -        { -          if (PIM_DEBUG_PIM_EVENTS) -            zlog_debug ("local membership add for %s as G is now ASM", -                        pim_str_sg_dump (&sg)); -          pim_ifchannel_local_membership_add (group->group_igmp_sock->interface, &sg); -        } -    } +	struct prefix_sg sg; +	struct igmp_group *group = source->source_group; +	struct pim_ifchannel *ch; + +	if ((source->source_addr.s_addr != INADDR_ANY) +	    || !IGMP_SOURCE_TEST_FORWARDING(source->source_flags)) +		return; + +	memset(&sg, 0, sizeof(struct prefix_sg)); +	sg.src = source->source_addr; +	sg.grp = group->group_addr; + +	ch = pim_ifchannel_find(group->group_igmp_sock->interface, &sg); +	if (pim_is_grp_ssm(group->group_addr)) { +		/* If SSM group withdraw local membership */ +		if (ch +		    && (ch->local_ifmembership == PIM_IFMEMBERSHIP_INCLUDE)) { +			if (PIM_DEBUG_PIM_EVENTS) +				zlog_debug( +					"local membership del for %s as G is now SSM", +					pim_str_sg_dump(&sg)); +			pim_ifchannel_local_membership_del( +				group->group_igmp_sock->interface, &sg); +		} +	} else { +		/* If ASM group add local membership */ +		if (!ch +		    || (ch->local_ifmembership == PIM_IFMEMBERSHIP_NOINFO)) { +			if (PIM_DEBUG_PIM_EVENTS) +				zlog_debug( +					"local membership add for %s as G is now ASM", +					pim_str_sg_dump(&sg)); +			pim_ifchannel_local_membership_add( +				group->group_igmp_sock->interface, &sg); +		} +	}  } -void -igmp_source_forward_reevaluate_all(void) +void igmp_source_forward_reevaluate_all(void)  { -  struct listnode *ifnode; -  struct interface *ifp; - -  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp)) -    { -      struct pim_interface *pim_ifp = ifp->info; -      struct listnode  *sock_node; -      struct igmp_sock *igmp; - -      if (!pim_ifp) -        continue; - -      /* scan igmp sockets */ -      for (ALL_LIST_ELEMENTS_RO (pim_ifp->igmp_socket_list, sock_node, igmp)) -        { -          struct listnode *grpnode; -          struct igmp_group *grp; - -          /* scan igmp groups */ -          for (ALL_LIST_ELEMENTS_RO (igmp->igmp_group_list, grpnode, grp)) -            { -              struct listnode    *srcnode; -              struct igmp_source *src; - -              /* scan group sources */ -              for (ALL_LIST_ELEMENTS_RO (grp->group_source_list, -                                        srcnode, src)) -                { -                  igmp_source_forward_reevaluate_one (src); -                } /* scan group sources */ -            } /* scan igmp groups */ -        } /* scan igmp sockets */ -    } /* scan interfaces */ +	struct listnode *ifnode; +	struct interface *ifp; + +	for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), ifnode, ifp)) { +		struct pim_interface *pim_ifp = ifp->info; +		struct listnode *sock_node; +		struct igmp_sock *igmp; + +		if (!pim_ifp) +			continue; + +		/* scan igmp sockets */ +		for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, +					  igmp)) { +			struct listnode *grpnode; +			struct igmp_group *grp; + +			/* scan igmp groups */ +			for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, +						  grpnode, grp)) { +				struct listnode *srcnode; +				struct igmp_source *src; + +				/* scan group sources */ +				for (ALL_LIST_ELEMENTS_RO( +					     grp->group_source_list, srcnode, +					     src)) { +					igmp_source_forward_reevaluate_one(src); +				} /* scan group sources */ +			}	 /* scan igmp groups */ +		}		  /* scan igmp sockets */ +	}			  /* scan interfaces */  }  void igmp_source_forward_start(struct igmp_source *source)  { -  struct igmp_group *group; -  struct prefix_sg sg; -  int result; -  int input_iface_vif_index = 0; - -  memset (&sg, 0, sizeof (struct prefix_sg)); -  sg.src = source->source_addr; -  sg.grp = source->source_group->group_addr; - -  if (PIM_DEBUG_IGMP_TRACE) { -    zlog_debug("%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d", -	       __PRETTY_FUNCTION__, - 	       pim_str_sg_dump (&sg), -	       source->source_group->group_igmp_sock->fd, -	       source->source_group->group_igmp_sock->interface->name, -	       IGMP_SOURCE_TEST_FORWARDING(source->source_flags)); -  } - -  /* Prevent IGMP interface from installing multicast route multiple -     times */ -  if (IGMP_SOURCE_TEST_FORWARDING(source->source_flags)) { -    return; -  } - -  group = source->source_group; - -  if (!source->source_channel_oil) { -    struct in_addr vif_source; -    struct pim_interface *pim_oif; -    struct prefix nht_p, src, grp; -    int ret = 0; -    struct pim_nexthop_cache out_pnc; -    struct pim_nexthop nexthop; -    struct pim_upstream *up = NULL; - -    if (!pim_rp_set_upstream_addr (&vif_source, source->source_addr, sg.grp)) -      return; - -    /* Register addr with Zebra NHT */ -    nht_p.family = AF_INET; -    nht_p.prefixlen = IPV4_MAX_BITLEN; -    nht_p.u.prefix4 = vif_source; -    memset (&out_pnc, 0, sizeof (struct pim_nexthop_cache)); - -    src.family = AF_INET; -    src.prefixlen = IPV4_MAX_BITLEN; -    src.u.prefix4 = vif_source;   //RP or Src address -    grp.family = AF_INET; -    grp.prefixlen = IPV4_MAX_BITLEN; -    grp.u.prefix4 = sg.grp; - -    if ((ret = pim_find_or_track_nexthop (&nht_p, NULL, NULL, &out_pnc)) == 1) -      { -        if (out_pnc.nexthop_num) -          { -            up = pim_upstream_find (&sg); -            memset (&nexthop, 0, sizeof (struct pim_nexthop)); -            if (up) -              memcpy (&nexthop, &up->rpf.source_nexthop, sizeof (struct pim_nexthop)); -            //Compute PIM RPF using Cached nexthop -            pim_ecmp_nexthop_search (&out_pnc, &nexthop, &src, &grp, 0); -            if (nexthop.interface) -              input_iface_vif_index = pim_if_find_vifindex_by_ifindex (nexthop.interface->ifindex); -          } -        else -          { -            if (PIM_DEBUG_ZEBRA) -              { -                char buf1[INET_ADDRSTRLEN]; -                char buf2[INET_ADDRSTRLEN]; -                pim_inet4_dump("<source?>", nht_p.u.prefix4, buf1, sizeof(buf1)); -                pim_inet4_dump("<source?>", grp.u.prefix4, buf2, sizeof(buf2)); -                zlog_debug ("%s: NHT Nexthop not found for addr %s grp %s" , -                          __PRETTY_FUNCTION__, buf1, buf2); -              } -          } -      } -    else -      input_iface_vif_index = pim_ecmp_fib_lookup_if_vif_index(vif_source, &src, &grp); - -    if (PIM_DEBUG_ZEBRA) -      { -        char buf2[INET_ADDRSTRLEN]; -        pim_inet4_dump("<source?>", vif_source, buf2, sizeof(buf2)); -        zlog_debug ("%s: NHT %s vif_source %s vif_index:%d ", __PRETTY_FUNCTION__, -            pim_str_sg_dump (&sg), buf2, input_iface_vif_index); -      } - -    if (input_iface_vif_index < 1) { -      if (PIM_DEBUG_IGMP_TRACE) -	{ -	  char source_str[INET_ADDRSTRLEN]; -	  pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str)); -	  zlog_debug("%s %s: could not find input interface for source %s", -		     __FILE__, __PRETTY_FUNCTION__, -		     source_str); +	struct igmp_group *group; +	struct prefix_sg sg; +	int result; +	int input_iface_vif_index = 0; + +	memset(&sg, 0, sizeof(struct prefix_sg)); +	sg.src = source->source_addr; +	sg.grp = source->source_group->group_addr; + +	if (PIM_DEBUG_IGMP_TRACE) { +		zlog_debug( +			"%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d", +			__PRETTY_FUNCTION__, pim_str_sg_dump(&sg), +			source->source_group->group_igmp_sock->fd, +			source->source_group->group_igmp_sock->interface->name, +			IGMP_SOURCE_TEST_FORWARDING(source->source_flags)); +	} + +	/* Prevent IGMP interface from installing multicast route multiple +	   times */ +	if (IGMP_SOURCE_TEST_FORWARDING(source->source_flags)) { +		return;  	} -      return; -    } - -    /* -      Protect IGMP against adding looped MFC entries created by both -      source and receiver attached to the same interface. See TODO -      T22. -    */ -    pim_oif = source->source_group->group_igmp_sock->interface->info; -    if (!pim_oif) { -      if (PIM_DEBUG_IGMP_TRACE) -	{ -	  zlog_debug("%s: multicast not enabled on oif=%s ?", -		     __PRETTY_FUNCTION__, -		     source->source_group->group_igmp_sock->interface->name); + +	group = source->source_group; + +	if (!source->source_channel_oil) { +		struct in_addr vif_source; +		struct pim_interface *pim_oif; +		struct prefix nht_p, src, grp; +		int ret = 0; +		struct pim_nexthop_cache out_pnc; +		struct pim_nexthop nexthop; +		struct pim_upstream *up = NULL; + +		if (!pim_rp_set_upstream_addr(&vif_source, source->source_addr, +					      sg.grp)) +			return; + +		/* Register addr with Zebra NHT */ +		nht_p.family = AF_INET; +		nht_p.prefixlen = IPV4_MAX_BITLEN; +		nht_p.u.prefix4 = vif_source; +		memset(&out_pnc, 0, sizeof(struct pim_nexthop_cache)); + +		src.family = AF_INET; +		src.prefixlen = IPV4_MAX_BITLEN; +		src.u.prefix4 = vif_source; // RP or Src address +		grp.family = AF_INET; +		grp.prefixlen = IPV4_MAX_BITLEN; +		grp.u.prefix4 = sg.grp; + +		if ((ret = pim_find_or_track_nexthop(&nht_p, NULL, NULL, +						     &out_pnc)) +		    == 1) { +			if (out_pnc.nexthop_num) { +				up = pim_upstream_find(&sg); +				memset(&nexthop, 0, sizeof(struct pim_nexthop)); +				if (up) +					memcpy(&nexthop, +					       &up->rpf.source_nexthop, +					       sizeof(struct pim_nexthop)); +				// Compute PIM RPF using Cached nexthop +				pim_ecmp_nexthop_search(&out_pnc, &nexthop, +							&src, &grp, 0); +				if (nexthop.interface) +					input_iface_vif_index = +						pim_if_find_vifindex_by_ifindex( +							nexthop.interface->ifindex); +			} else { +				if (PIM_DEBUG_ZEBRA) { +					char buf1[INET_ADDRSTRLEN]; +					char buf2[INET_ADDRSTRLEN]; +					pim_inet4_dump("<source?>", +						       nht_p.u.prefix4, buf1, +						       sizeof(buf1)); +					pim_inet4_dump("<source?>", +						       grp.u.prefix4, buf2, +						       sizeof(buf2)); +					zlog_debug( +						"%s: NHT Nexthop not found for addr %s grp %s", +						__PRETTY_FUNCTION__, buf1, +						buf2); +				} +			} +		} else +			input_iface_vif_index = +				pim_ecmp_fib_lookup_if_vif_index(vif_source, +								 &src, &grp); + +		if (PIM_DEBUG_ZEBRA) { +			char buf2[INET_ADDRSTRLEN]; +			pim_inet4_dump("<source?>", vif_source, buf2, +				       sizeof(buf2)); +			zlog_debug("%s: NHT %s vif_source %s vif_index:%d ", +				   __PRETTY_FUNCTION__, pim_str_sg_dump(&sg), +				   buf2, input_iface_vif_index); +		} + +		if (input_iface_vif_index < 1) { +			if (PIM_DEBUG_IGMP_TRACE) { +				char source_str[INET_ADDRSTRLEN]; +				pim_inet4_dump("<source?>", source->source_addr, +					       source_str, sizeof(source_str)); +				zlog_debug( +					"%s %s: could not find input interface for source %s", +					__FILE__, __PRETTY_FUNCTION__, +					source_str); +			} +			return; +		} + +		/* +		  Protect IGMP against adding looped MFC entries created by both +		  source and receiver attached to the same interface. See TODO +		  T22. +		*/ +		pim_oif = +			source->source_group->group_igmp_sock->interface->info; +		if (!pim_oif) { +			if (PIM_DEBUG_IGMP_TRACE) { +				zlog_debug( +					"%s: multicast not enabled on oif=%s ?", +					__PRETTY_FUNCTION__, +					source->source_group->group_igmp_sock +						->interface->name); +			} +			return; +		} + +		if (input_iface_vif_index == pim_oif->mroute_vif_index) { +			/* ignore request for looped MFC entry */ +			if (PIM_DEBUG_IGMP_TRACE) { +				zlog_debug( +					"%s: ignoring request for looped MFC entry (S,G)=%s: igmp_sock=%d oif=%s vif_index=%d", +					__PRETTY_FUNCTION__, +					pim_str_sg_dump(&sg), +					source->source_group->group_igmp_sock +						->fd, +					source->source_group->group_igmp_sock +						->interface->name, +					input_iface_vif_index); +			} +			return; +		} + +		source->source_channel_oil = +			pim_channel_oil_add(&sg, input_iface_vif_index); +		if (!source->source_channel_oil) { +			if (PIM_DEBUG_IGMP_TRACE) { +				zlog_debug( +					"%s %s: could not create OIL for channel (S,G)=%s", +					__FILE__, __PRETTY_FUNCTION__, +					pim_str_sg_dump(&sg)); +			} +			return; +		}  	} -      return; -    } - -    if (input_iface_vif_index == pim_oif->mroute_vif_index) { -      /* ignore request for looped MFC entry */ -      if (PIM_DEBUG_IGMP_TRACE) { -	zlog_debug("%s: ignoring request for looped MFC entry (S,G)=%s: igmp_sock=%d oif=%s vif_index=%d", -		   __PRETTY_FUNCTION__, -		   pim_str_sg_dump (&sg), -		   source->source_group->group_igmp_sock->fd, -		   source->source_group->group_igmp_sock->interface->name, -		   input_iface_vif_index); -      } -      return; -    } - -    source->source_channel_oil = pim_channel_oil_add(&sg, -						     input_iface_vif_index); -    if (!source->source_channel_oil) { -      if (PIM_DEBUG_IGMP_TRACE) -	{ -	  zlog_debug("%s %s: could not create OIL for channel (S,G)=%s", -		    __FILE__, __PRETTY_FUNCTION__, -		    pim_str_sg_dump (&sg)); + +	result = pim_channel_add_oif(source->source_channel_oil, +				     group->group_igmp_sock->interface, +				     PIM_OIF_FLAG_PROTO_IGMP); +	if (result) { +		if (PIM_DEBUG_MROUTE) { +			zlog_warn("%s: add_oif() failed with return=%d", +				  __func__, result); +		} +		return;  	} -      return; -    } -  } - -  result = pim_channel_add_oif(source->source_channel_oil, -			       group->group_igmp_sock->interface, -			       PIM_OIF_FLAG_PROTO_IGMP); -  if (result) { -    if (PIM_DEBUG_MROUTE) -      { -        zlog_warn("%s: add_oif() failed with return=%d", -                  __func__, result); -      } -    return; -  } - -  /* -    Feed IGMPv3-gathered local membership information into PIM -    per-interface (S,G) state. -   */ -  if (!pim_ifchannel_local_membership_add(group->group_igmp_sock->interface, &sg)) -    { -      if (PIM_DEBUG_MROUTE) -	zlog_warn ("%s: Failure to add local membership for %s", -		   __PRETTY_FUNCTION__, pim_str_sg_dump (&sg)); -      return; -    } - -  IGMP_SOURCE_DO_FORWARDING(source->source_flags); + +	/* +	  Feed IGMPv3-gathered local membership information into PIM +	  per-interface (S,G) state. +	 */ +	if (!pim_ifchannel_local_membership_add( +		    group->group_igmp_sock->interface, &sg)) { +		if (PIM_DEBUG_MROUTE) +			zlog_warn("%s: Failure to add local membership for %s", +				  __PRETTY_FUNCTION__, pim_str_sg_dump(&sg)); +		return; +	} + +	IGMP_SOURCE_DO_FORWARDING(source->source_flags);  }  /* @@ -966,203 +1010,219 @@ void igmp_source_forward_start(struct igmp_source *source)   */  void igmp_source_forward_stop(struct igmp_source *source)  { -  struct igmp_group *group; -  struct prefix_sg sg; -  int result; - -  memset (&sg, 0, sizeof (struct prefix_sg)); -  sg.src = source->source_addr; -  sg.grp = source->source_group->group_addr; - -  if (PIM_DEBUG_IGMP_TRACE) { -    zlog_debug("%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d", -	       __PRETTY_FUNCTION__, -	       pim_str_sg_dump (&sg), -	       source->source_group->group_igmp_sock->fd, -	       source->source_group->group_igmp_sock->interface->name, -	       IGMP_SOURCE_TEST_FORWARDING(source->source_flags)); -  } - -  /* Prevent IGMP interface from removing multicast route multiple -     times */ -  if (!IGMP_SOURCE_TEST_FORWARDING(source->source_flags)) { -    return; -  } - -  group = source->source_group; - -  /* -   It appears that in certain circumstances that  -   igmp_source_forward_stop is called when IGMP forwarding -   was not enabled in oif_flags for this outgoing interface. -   Possibly because of multiple calls. When that happens, we -   enter the below if statement and this function returns early -   which in turn triggers the calling function to assert. -   Making the call to pim_channel_del_oif and ignoring the return code -   fixes the issue without ill effect, similar to -   pim_forward_stop below. -  */ -  result = pim_channel_del_oif(source->source_channel_oil, -                               group->group_igmp_sock->interface, -                               PIM_OIF_FLAG_PROTO_IGMP); -  if (result) { -    if (PIM_DEBUG_IGMP_TRACE) -      zlog_debug("%s: pim_channel_del_oif() failed with return=%d", -		 __func__, result); -    return; -  } - -  /* -    Feed IGMPv3-gathered local membership information into PIM -    per-interface (S,G) state. -   */ -  pim_ifchannel_local_membership_del(group->group_igmp_sock->interface, -				     &sg); - -  IGMP_SOURCE_DONT_FORWARDING(source->source_flags); +	struct igmp_group *group; +	struct prefix_sg sg; +	int result; + +	memset(&sg, 0, sizeof(struct prefix_sg)); +	sg.src = source->source_addr; +	sg.grp = source->source_group->group_addr; + +	if (PIM_DEBUG_IGMP_TRACE) { +		zlog_debug( +			"%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d", +			__PRETTY_FUNCTION__, pim_str_sg_dump(&sg), +			source->source_group->group_igmp_sock->fd, +			source->source_group->group_igmp_sock->interface->name, +			IGMP_SOURCE_TEST_FORWARDING(source->source_flags)); +	} + +	/* Prevent IGMP interface from removing multicast route multiple +	   times */ +	if (!IGMP_SOURCE_TEST_FORWARDING(source->source_flags)) { +		return; +	} + +	group = source->source_group; + +	/* +	 It appears that in certain circumstances that +	 igmp_source_forward_stop is called when IGMP forwarding +	 was not enabled in oif_flags for this outgoing interface. +	 Possibly because of multiple calls. When that happens, we +	 enter the below if statement and this function returns early +	 which in turn triggers the calling function to assert. +	 Making the call to pim_channel_del_oif and ignoring the return code +	 fixes the issue without ill effect, similar to +	 pim_forward_stop below. +	*/ +	result = pim_channel_del_oif(source->source_channel_oil, +				     group->group_igmp_sock->interface, +				     PIM_OIF_FLAG_PROTO_IGMP); +	if (result) { +		if (PIM_DEBUG_IGMP_TRACE) +			zlog_debug( +				"%s: pim_channel_del_oif() failed with return=%d", +				__func__, result); +		return; +	} + +	/* +	  Feed IGMPv3-gathered local membership information into PIM +	  per-interface (S,G) state. +	 */ +	pim_ifchannel_local_membership_del(group->group_igmp_sock->interface, +					   &sg); + +	IGMP_SOURCE_DONT_FORWARDING(source->source_flags);  }  void pim_forward_start(struct pim_ifchannel *ch)  { -  struct pim_upstream *up = ch->upstream; -  uint32_t mask = PIM_OIF_FLAG_PROTO_PIM; -  int input_iface_vif_index =  0; - -  if (PIM_DEBUG_PIM_TRACE) { -    char source_str[INET_ADDRSTRLEN]; -    char group_str[INET_ADDRSTRLEN]; -    char upstream_str[INET_ADDRSTRLEN]; - -    pim_inet4_dump("<source?>", ch->sg.src, source_str, sizeof(source_str)); -    pim_inet4_dump("<group?>", ch->sg.grp, group_str, sizeof(group_str)); -    pim_inet4_dump("<upstream?>", up->upstream_addr, upstream_str, sizeof(upstream_str)); -    zlog_debug("%s: (S,G)=(%s,%s) oif=%s (%s)", -	       __PRETTY_FUNCTION__, -	       source_str, group_str, ch->interface->name, upstream_str); -  } - -  /* Resolve IIF for upstream as mroute_del sets mfcc_parent to MAXVIFS, -     as part of mroute_del called by pim_forward_stop. -  */ -  if (!up->channel_oil || -      (up->channel_oil && up->channel_oil->oil.mfcc_parent >= MAXVIFS)) -    { -      struct prefix nht_p, src, grp; -      int ret = 0; -      struct pim_nexthop_cache out_pnc; - -      /* Register addr with Zebra NHT */ -      nht_p.family = AF_INET; -      nht_p.prefixlen = IPV4_MAX_BITLEN; -      nht_p.u.prefix4.s_addr = up->upstream_addr.s_addr; -      grp.family = AF_INET; -      grp.prefixlen = IPV4_MAX_BITLEN; -      grp.u.prefix4 = up->sg.grp; -      memset (&out_pnc, 0, sizeof (struct pim_nexthop_cache)); - -      if ((ret = pim_find_or_track_nexthop (&nht_p, NULL, NULL, &out_pnc)) == 1) -        { -          if (out_pnc.nexthop_num) -            { -              src.family = AF_INET; -              src.prefixlen = IPV4_MAX_BITLEN; -              src.u.prefix4 = up->upstream_addr; //RP or Src address -              grp.family = AF_INET; -              grp.prefixlen = IPV4_MAX_BITLEN; -              grp.u.prefix4 = up->sg.grp; -              //Compute PIM RPF using Cached nexthop -              if (pim_ecmp_nexthop_search (&out_pnc, &up->rpf.source_nexthop, &src, &grp, 0) == 0) -                input_iface_vif_index = pim_if_find_vifindex_by_ifindex (up->rpf.source_nexthop.interface->ifindex); -              else -                { -                  if (PIM_DEBUG_TRACE) -                    zlog_debug ("%s: Nexthop selection failed for %s ", __PRETTY_FUNCTION__, up->sg_str); -                } -            } -          else -            { -              if (PIM_DEBUG_ZEBRA) -                { -                  char buf1[INET_ADDRSTRLEN]; -                  char buf2[INET_ADDRSTRLEN]; -                  pim_inet4_dump("<source?>", nht_p.u.prefix4, buf1, sizeof(buf1)); -                  pim_inet4_dump("<source?>", grp.u.prefix4, buf2, sizeof(buf2)); -                  zlog_debug ("%s: NHT pnc is NULL for addr %s grp %s" , -                          __PRETTY_FUNCTION__, buf1, buf2); -                } -            } -        } -      else -        input_iface_vif_index = pim_ecmp_fib_lookup_if_vif_index(up->upstream_addr, &src, &grp); - -      if (input_iface_vif_index < 1) -        { -          if (PIM_DEBUG_PIM_TRACE) -            { -              char source_str[INET_ADDRSTRLEN]; -              pim_inet4_dump("<source?>", up->sg.src, source_str, sizeof(source_str)); -              zlog_debug("%s %s: could not find input interface for source %s", -                      __FILE__, __PRETTY_FUNCTION__, -                      source_str); -            } -          return; -        } -      if (PIM_DEBUG_TRACE) -        { -          struct interface *in_intf = pim_if_find_by_vif_index (input_iface_vif_index); -          zlog_debug ("%s: Update channel_oil IIF %s VIFI %d entry %s ", -                      __PRETTY_FUNCTION__, in_intf ? in_intf->name : "NIL", -                      input_iface_vif_index, up->sg_str); -        } -      up->channel_oil = pim_channel_oil_add (&up->sg, input_iface_vif_index); -      if (!up->channel_oil) -        { -          if (PIM_DEBUG_PIM_TRACE) -            zlog_debug ("%s %s: could not create OIL for channel (S,G)=%s", -                        __FILE__, __PRETTY_FUNCTION__, up->sg_str); -          return; -        } -    } - -  if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP) -    mask = PIM_OIF_FLAG_PROTO_IGMP; - -  pim_channel_add_oif (up->channel_oil, ch->interface, mask); +	struct pim_upstream *up = ch->upstream; +	uint32_t mask = PIM_OIF_FLAG_PROTO_PIM; +	int input_iface_vif_index = 0; + +	if (PIM_DEBUG_PIM_TRACE) { +		char source_str[INET_ADDRSTRLEN]; +		char group_str[INET_ADDRSTRLEN]; +		char upstream_str[INET_ADDRSTRLEN]; + +		pim_inet4_dump("<source?>", ch->sg.src, source_str, +			       sizeof(source_str)); +		pim_inet4_dump("<group?>", ch->sg.grp, group_str, +			       sizeof(group_str)); +		pim_inet4_dump("<upstream?>", up->upstream_addr, upstream_str, +			       sizeof(upstream_str)); +		zlog_debug("%s: (S,G)=(%s,%s) oif=%s (%s)", __PRETTY_FUNCTION__, +			   source_str, group_str, ch->interface->name, +			   upstream_str); +	} + +	/* Resolve IIF for upstream as mroute_del sets mfcc_parent to MAXVIFS, +	   as part of mroute_del called by pim_forward_stop. +	*/ +	if (!up->channel_oil +	    || (up->channel_oil +		&& up->channel_oil->oil.mfcc_parent >= MAXVIFS)) { +		struct prefix nht_p, src, grp; +		int ret = 0; +		struct pim_nexthop_cache out_pnc; + +		/* Register addr with Zebra NHT */ +		nht_p.family = AF_INET; +		nht_p.prefixlen = IPV4_MAX_BITLEN; +		nht_p.u.prefix4.s_addr = up->upstream_addr.s_addr; +		grp.family = AF_INET; +		grp.prefixlen = IPV4_MAX_BITLEN; +		grp.u.prefix4 = up->sg.grp; +		memset(&out_pnc, 0, sizeof(struct pim_nexthop_cache)); + +		if ((ret = pim_find_or_track_nexthop(&nht_p, NULL, NULL, +						     &out_pnc)) +		    == 1) { +			if (out_pnc.nexthop_num) { +				src.family = AF_INET; +				src.prefixlen = IPV4_MAX_BITLEN; +				src.u.prefix4 = +					up->upstream_addr; // RP or Src address +				grp.family = AF_INET; +				grp.prefixlen = IPV4_MAX_BITLEN; +				grp.u.prefix4 = up->sg.grp; +				// Compute PIM RPF using Cached nexthop +				if (pim_ecmp_nexthop_search( +					    &out_pnc, &up->rpf.source_nexthop, +					    &src, &grp, 0) +				    == 0) +					input_iface_vif_index = +						pim_if_find_vifindex_by_ifindex( +							up->rpf.source_nexthop +								.interface->ifindex); +				else { +					if (PIM_DEBUG_TRACE) +						zlog_debug( +							"%s: Nexthop selection failed for %s ", +							__PRETTY_FUNCTION__, +							up->sg_str); +				} +			} else { +				if (PIM_DEBUG_ZEBRA) { +					char buf1[INET_ADDRSTRLEN]; +					char buf2[INET_ADDRSTRLEN]; +					pim_inet4_dump("<source?>", +						       nht_p.u.prefix4, buf1, +						       sizeof(buf1)); +					pim_inet4_dump("<source?>", +						       grp.u.prefix4, buf2, +						       sizeof(buf2)); +					zlog_debug( +						"%s: NHT pnc is NULL for addr %s grp %s", +						__PRETTY_FUNCTION__, buf1, +						buf2); +				} +			} +		} else +			input_iface_vif_index = +				pim_ecmp_fib_lookup_if_vif_index( +					up->upstream_addr, &src, &grp); + +		if (input_iface_vif_index < 1) { +			if (PIM_DEBUG_PIM_TRACE) { +				char source_str[INET_ADDRSTRLEN]; +				pim_inet4_dump("<source?>", up->sg.src, +					       source_str, sizeof(source_str)); +				zlog_debug( +					"%s %s: could not find input interface for source %s", +					__FILE__, __PRETTY_FUNCTION__, +					source_str); +			} +			return; +		} +		if (PIM_DEBUG_TRACE) { +			struct interface *in_intf = +				pim_if_find_by_vif_index(input_iface_vif_index); +			zlog_debug( +				"%s: Update channel_oil IIF %s VIFI %d entry %s ", +				__PRETTY_FUNCTION__, +				in_intf ? in_intf->name : "NIL", +				input_iface_vif_index, up->sg_str); +		} +		up->channel_oil = +			pim_channel_oil_add(&up->sg, input_iface_vif_index); +		if (!up->channel_oil) { +			if (PIM_DEBUG_PIM_TRACE) +				zlog_debug( +					"%s %s: could not create OIL for channel (S,G)=%s", +					__FILE__, __PRETTY_FUNCTION__, +					up->sg_str); +			return; +		} +	} + +	if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP) +		mask = PIM_OIF_FLAG_PROTO_IGMP; + +	pim_channel_add_oif(up->channel_oil, ch->interface, mask);  }  void pim_forward_stop(struct pim_ifchannel *ch)  { -  struct pim_upstream *up = ch->upstream; +	struct pim_upstream *up = ch->upstream; -  if (PIM_DEBUG_PIM_TRACE) { -    zlog_debug("%s: (S,G)=%s oif=%s", -	       __PRETTY_FUNCTION__, -	       ch->sg_str, ch->interface->name); -  } +	if (PIM_DEBUG_PIM_TRACE) { +		zlog_debug("%s: (S,G)=%s oif=%s", __PRETTY_FUNCTION__, +			   ch->sg_str, ch->interface->name); +	} -  pim_channel_del_oif(up->channel_oil, -                      ch->interface, -                      PIM_OIF_FLAG_PROTO_PIM); +	pim_channel_del_oif(up->channel_oil, ch->interface, +			    PIM_OIF_FLAG_PROTO_PIM);  } -void -pim_zebra_zclient_update (struct vty *vty) +void pim_zebra_zclient_update(struct vty *vty)  { -  vty_out(vty, "Zclient update socket: "); - -  if (zclient) { -    vty_out (vty, "%d failures=%d\n", zclient->sock, -	    zclient->fail); -  } -  else { -    vty_out (vty, "<null zclient>\n"); -  } +	vty_out(vty, "Zclient update socket: "); + +	if (zclient) { +		vty_out(vty, "%d failures=%d\n", zclient->sock, zclient->fail); +	} else { +		vty_out(vty, "<null zclient>\n"); +	}  } -struct zclient *pim_zebra_zclient_get (void) +struct zclient *pim_zebra_zclient_get(void)  { -  if (zclient) -    return zclient; -  else -    return NULL; +	if (zclient) +		return zclient; +	else +		return NULL;  }  | 
