From: Donald Sharp Date: Wed, 13 Sep 2017 23:43:39 +0000 (-0400) Subject: pimd: More S,G RPT prune state missinformation X-Git-Tag: frr-4.0-dev~308^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=37736d087067cda2bc6a6371cc20e42f5cd92cdd;p=mirror%2Ffrr.git pimd: More S,G RPT prune state missinformation If you read the extra fine print of the PIM RFC it asks you to stop the PP Timer and the Expiry Timer when you are certain S,G RPT states. This commit puts this into practice and it also deletes the S,G ifchannel if necessary. Signed-off-by: Donald Sharp interface->info)->pim; @@ -1339,7 +1339,7 @@ void pim_ifchannel_set_star_g_join_state(struct pim_ifchannel *ch, int eom, if (!ch->sources) return; - for (ALL_LIST_ELEMENTS_RO(ch->sources, ch_node, child)) { + for (ALL_LIST_ELEMENTS(ch->sources, ch_node, nch_node, child)) { if (!PIM_IF_FLAG_TEST_S_G_RPT(child->flags)) continue; @@ -1358,30 +1358,36 @@ void pim_ifchannel_set_star_g_join_state(struct pim_ifchannel *ch, int eom, break; case PIM_IFJOIN_PRUNE_TMP: case PIM_IFJOIN_PRUNE_PENDING_TMP: - if (eom) { - struct pim_upstream *parent = - child->upstream->parent; - - PIM_IF_FLAG_UNSET_S_G_RPT(child->flags); - child->ifjoin_state = PIM_IFJOIN_NOINFO; - - if (I_am_RP(pim, child->sg.grp)) { - pim_channel_add_oif( - child->upstream->channel_oil, - ch->interface, - PIM_OIF_FLAG_PROTO_STAR); - pim_upstream_switch( - pim, child->upstream, - PIM_UPSTREAM_JOINED); - pim_jp_agg_single_upstream_send( - &child->upstream->rpf, - child->upstream, true); - } - if (parent) - pim_jp_agg_single_upstream_send( - &parent->rpf, - parent, true); + if (!eom) + break; + + if (child->ifjoin_state == PIM_IFJOIN_PRUNE_PENDING_TMP) + THREAD_OFF(child->t_ifjoin_prune_pending_timer); + THREAD_OFF(child->t_ifjoin_expiry_timer); + struct pim_upstream *parent = + child->upstream->parent; + + PIM_IF_FLAG_UNSET_S_G_RPT(child->flags); + child->ifjoin_state = PIM_IFJOIN_NOINFO; + + if (I_am_RP(pim, child->sg.grp)) { + pim_channel_add_oif( + child->upstream->channel_oil, + ch->interface, + PIM_OIF_FLAG_PROTO_STAR); + pim_upstream_switch( + pim, child->upstream, + PIM_UPSTREAM_JOINED); + pim_jp_agg_single_upstream_send( + &child->upstream->rpf, + child->upstream, true); } + if (parent) + pim_jp_agg_single_upstream_send( + &parent->rpf, + parent, true); + + delete_on_noinfo(child); break; } }