]> git.puffer.fish Git - matthieu/frr.git/commitdiff
pimd: SGRpt prune received during prune didn't override holdtime
authorsaravanank <saravanank@vmware.com>
Thu, 19 Mar 2020 10:33:41 +0000 (03:33 -0700)
committerIgor Ryzhov <iryzhov@nfware.com>
Tue, 16 Feb 2021 17:58:47 +0000 (20:58 +0300)
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.

pimd/pim_ifchannel.c

index 212c77c039dc6d630f56fdef78245a9a01536778..7957b0799b331790963e5878f5e2272497ef653d 100644 (file)
@@ -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);