summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsaravanank <saravanank@vmware.com>2020-03-19 03:33:41 -0700
committerIgor Ryzhov <iryzhov@nfware.com>2021-02-16 20:58:47 +0300
commit49d73d8be84dbd23d767697474019165e511786c (patch)
treeb3e40bc2987cf4d6416411b2c6dcd4416db8a833
parent1d0d19afa9bb7cd4bc476d00c887876bc04eee95 (diff)
pimd: SGRpt prune received during prune didn't override holdtime
RCA: There were 2 problems. 1. SGRpt prune expiry didn't create S,G entry with none oil when no other interfaces were part of the oil. 2. When restarting the timer with new hold value, comparision was missing and old timer was not stopping. Fix: SGRpt Prune pending expiry will put SG entry with none oil if no other Signed-off-by: Saravanan K <saravanank@vmware.com> interfaces present. If present we will be deleting the inherited oif from oil. Deleting the oif in that scenario will take care of changing mroute. When alone interface expires in SGRpt prune pending state, we shall detect by checking installed flag. if not installed, install mroute.
-rw-r--r--pimd/pim_ifchannel.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c
index 212c77c039..7957b0799b 100644
--- a/pimd/pim_ifchannel.c
+++ b/pimd/pim_ifchannel.c
@@ -710,6 +710,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 */
@@ -1057,6 +1072,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);