#include "pim_join.h"
#include "pim_rpf.h"
#include "pim_macro.h"
+#include "pim_oil.h"
/*
* A (*,G) or a (*,*) is going away
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,
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);
}