From: Donald Sharp Date: Mon, 15 Aug 2016 11:28:36 +0000 (-0400) Subject: pimd: Fix igmp(*,G) not influencing S,G mroutes X-Git-Tag: frr-3.0-branchpoint~64^2~10^2~292 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=dfbbce1dcec213368beb4a0e3d24dcf8f1e06acd;p=mirror%2Ffrr.git pimd: Fix igmp(*,G) not influencing S,G mroutes When we receive a (*,G) route decide if we need to cause any output interfaces to be added to any S,G route associated. Signed-off-by: Donald Sharp --- diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index dcd9da64b6..b83f0072b4 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -37,6 +37,7 @@ #include "pim_join.h" #include "pim_rpf.h" #include "pim_macro.h" +#include "pim_oil.h" /* * A (*,G) or a (*,*) is going away @@ -773,6 +774,35 @@ void pim_ifchannel_local_membership_add(struct interface *ifp, ifmembership_set(ch, PIM_IFMEMBERSHIP_INCLUDE); zassert(!IFCHANNEL_NOINFO(ch)); + + if (sg->src.s_addr == INADDR_ANY) + { + struct pim_upstream *up = pim_upstream_find (sg); + struct pim_upstream *child; + struct listnode *up_node; + + for (ALL_LIST_ELEMENTS_RO (qpim_upstream_list, up_node, child)) + { + if (child->parent == up) + { + if (PIM_DEBUG_EVENTS) + { + char buff[100]; + + strcpy (buff, pim_str_sg_dump (&up->sg)); + zlog_debug("%s %s: IGMP (S,G)=%s from %s", + __FILE__, __PRETTY_FUNCTION__, + buff, pim_str_sg_dump (sg)); + } + + if (pim_upstream_evaluate_join_desired (child)) + { + pim_channel_add_oif (child->channel_oil, ifp, PIM_OIF_FLAG_PROTO_PIM); + pim_upstream_switch (child, PIM_UPSTREAM_JOINED); + } + } + } + } } void pim_ifchannel_local_membership_del(struct interface *ifp, @@ -794,6 +824,42 @@ void pim_ifchannel_local_membership_del(struct interface *ifp, ifmembership_set(ch, PIM_IFMEMBERSHIP_NOINFO); + if (sg->src.s_addr == INADDR_ANY) + { + struct pim_upstream *up = pim_upstream_find (sg); + struct pim_upstream *child; + struct listnode *up_node; + + for (ALL_LIST_ELEMENTS_RO (qpim_upstream_list, up_node, child)) + { + if (child->parent == up) + { + struct channel_oil *c_oil = child->channel_oil; + struct pim_ifchannel *ch = pim_ifchannel_find (ifp, &child->sg); + struct pim_interface *pim_ifp = ifp->info; + + if (PIM_DEBUG_EVENTS) + { + char buff[100]; + strcpy (buff, pim_str_sg_dump (&up->sg)); + zlog_debug("%s %s: Prune(S,G)=%s from %s", + __FILE__, __PRETTY_FUNCTION__, + buff, pim_str_sg_dump (&child->sg)); + } + + if (!pim_upstream_evaluate_join_desired (child)) + pim_channel_del_oif (c_oil, ifp, PIM_OIF_FLAG_PROTO_PIM); + + /* + * If the S,G has no if channel and the c_oil still + * has output here then the *,G was supplying the implied + * if channel. So remove it. + */ + if (!ch && c_oil->oil.mfcc_ttls[pim_ifp->mroute_vif_index]) + pim_channel_del_oif (c_oil, ifp, PIM_OIF_FLAG_PROTO_PIM); + } + } + } delete_on_noinfo(ch); }