diff options
Diffstat (limited to 'pimd/pim_ifchannel.c')
| -rw-r--r-- | pimd/pim_ifchannel.c | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index e7ff434f4b..cdaf7bcdd4 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -550,8 +550,21 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp, struct pim_upstream *up; ch = pim_ifchannel_find(ifp, sg); - if (ch) + if (ch) { + if (up_flags == PIM_UPSTREAM_FLAG_MASK_SRC_PIM) + PIM_IF_FLAG_SET_PROTO_PIM(ch->flags); + + if (up_flags == PIM_UPSTREAM_FLAG_MASK_SRC_IGMP) + PIM_IF_FLAG_SET_PROTO_IGMP(ch->flags); + + if (ch->upstream) + ch->upstream->flags |= up_flags; + else if (PIM_DEBUG_EVENTS) + zlog_debug("%s:%s No Upstream found", __func__, + pim_str_sg_dump(sg)); + return ch; + } pim_ifp = ifp->info; @@ -642,6 +655,12 @@ static void ifjoin_to_noinfo(struct pim_ifchannel *ch, bool ch_del) { pim_forward_stop(ch, !ch_del); pim_ifchannel_ifjoin_switch(__func__, ch, PIM_IFJOIN_NOINFO); + + if (ch->upstream) + PIM_UPSTREAM_FLAG_UNSET_SRC_PIM(ch->upstream->flags); + + PIM_IF_FLAG_UNSET_PROTO_PIM(ch->flags); + if (ch_del) delete_on_noinfo(ch); } @@ -710,6 +729,21 @@ static int on_ifjoin_prune_pending_timer(struct thread *t) pim_jp_agg_single_upstream_send(&parent->rpf, parent, true); + /* + * SGRpt prune pending expiry has to install + * SG entry with empty olist to drop the SG + * traffic incase no other intf exists. + * On that scenario, SG entry wouldn't have + * got installed until Prune pending timer + * expired. So install now. + */ + pim_channel_del_oif( + ch->upstream->channel_oil, ifp, + PIM_OIF_FLAG_PROTO_STAR, __func__); + if (!ch->upstream->channel_oil->installed) + pim_upstream_mroute_add( + ch->upstream->channel_oil, + __PRETTY_FUNCTION__); } } /* from here ch may have been deleted */ @@ -1094,6 +1128,24 @@ void pim_ifchannel_prune(struct interface *ifp, struct in_addr upstream, case PIM_IFJOIN_PRUNE: if (source_flags & PIM_ENCODE_RPT_BIT) { THREAD_OFF(ch->t_ifjoin_prune_pending_timer); + /* + * While in Prune State, Receive SGRpt Prune. + * RFC 7761 Sec 4.5.3: + * The (S,G,rpt) downstream state machine on interface I + * remains in Prune state. The Expiry Timer (ET) is + * restarted and is then set to the maximum of its + * current value and the HoldTime from the triggering + * Join/Prune message. + */ + if (ch->t_ifjoin_expiry_timer) { + unsigned long rem = thread_timer_remain_second( + ch->t_ifjoin_expiry_timer); + + if (rem > holdtime) + return; + THREAD_OFF(ch->t_ifjoin_expiry_timer); + } + thread_add_timer(router->master, on_ifjoin_expiry_timer, ch, holdtime, &ch->t_ifjoin_expiry_timer); @@ -1272,6 +1324,13 @@ void pim_ifchannel_local_membership_del(struct interface *ifp, * parent' delete_no_info */ } } + + /* Resettng the IGMP flags here */ + if (orig->upstream) + PIM_UPSTREAM_FLAG_UNSET_SRC_IGMP(orig->upstream->flags); + + PIM_IF_FLAG_UNSET_PROTO_IGMP(orig->flags); + delete_on_noinfo(orig); } |
