]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: Send immediate join( with possible SG RPT prune bit set 10963/head
authorDonald Sharp <sharpd@nvidia.com>
Thu, 31 Mar 2022 17:07:06 +0000 (13:07 -0400)
committermergify-bot <noreply@mergify.com>
Mon, 4 Apr 2022 19:01:29 +0000 (19:01 +0000)
When pimd has this setup:

src ----- rtr ------ receiver
           |
          rp

And the receiver sends a *,G join to rtr.  When the
src starts sending a S,G, rtr can wait up to one join/prune
interval before sending a S,G rpt prune.  This interval
causes the pimreg device to be in the S,G OIL as that the
RP does not know to prune this leg off.

before:

Timestamp: Thu Mar 31 10:15:18 2022 288767 usec
[MROUTE](10.103.0.5,239.0.0.4)           Iif: rtr-lan_src Oifs: rtr-lan  State: resolved Table: default
Timestamp: Thu Mar 31 10:15:18 2022 288777 usec
[MROUTE](10.103.0.5,239.0.0.4)           Iif: rtr-lan_src Oifs: rtr-lan rtr-lan-1  State: resolved Table: default
Timestamp: Thu Mar 31 10:15:18 2022 288789 usec
[MROUTE](10.103.0.5,239.0.0.4)           Iif: rtr-lan_src Oifs: pimreg rtr-lan rtr-lan-1  State: resolved Table: default
Timestamp: Thu Mar 31 10:15:49 2022 324995 usec
[MROUTE](10.103.0.5,239.0.0.4)           Iif: rtr-lan_src Oifs: rtr-lan rtr-lan-1  State: resolved Table: default
<31 seconds>

After:

Timestamp: Thu Mar 31 12:56:15 2022 501921 usec
(10.103.0.5,239.0.0.27)          Iif: rtr-lan_src Oifs: pimreg rtr-lan  State: resolved Table: default
Timestamp: Thu Mar 31 12:56:15 2022 501930 usec
(10.103.0.5,239.0.0.27)          Iif: rtr-lan_src Oifs: pimreg rtr-lan rtr-lan-1  State: resolved Table: default
Timestamp: Thu Mar 31 12:56:15 2022 502181 usec
(10.103.0.5,239.0.0.27)          Iif: rtr-lan_src Oifs: rtr-lan rtr-lan-1  State: resolved Table: default
<sub second>

What is actually happening:

rtr receives a *,G igmp join, sends a *,G join towards the rp
rtr receives a S,G packet <WRVIFWHOLE>
creates the S,G upstream, sends the register packet to the rp
the rp sees that it still has downstream interest so it forwards the packet on
After (up to 60 seconds ) the rtr, sends the normally scheduled join for
the G and sends the S,GRPT prune as part of it.

What is being done to fix it:

In wrvifwhole handling, when pimd detects that this is the FHR
and is not the RP *and* the incoming interface for the *,G
is different than the incomding interface for the S,G immediately
send a single join packet for the G( which will have the S,G RPT
prune in it ).  Only do this on the first time receiving the
WRVIFWHOLE.

Ticket: #2755650
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
(cherry picked from commit 33ec4015b628143a09274421ad31debce788858d)

pimd/pim_mroute.c

index 2bf0f8bccaa6f610948dd4774fca01ff4db202c8..989e1f4ffe6f47df484e68782219bb3534999a65 100644 (file)
@@ -542,6 +542,28 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp,
                                                pim_ifp->primary_address,
                                                up->upstream_register);
                                up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
+                       } else {
+                               /*
+                                * At this point pimd is connected to
+                                * the source, it has a parent, we are not
+                                * the RP  and the SPTBIT should be set
+                                * since we know *the* S,G is on the SPT.
+                                * The first time this happens, let's cause
+                                * an immediate join to go out so that
+                                * the RP can trim this guy immediately
+                                * if necessary, instead of waiting
+                                * one join/prune send cycle
+                                */
+                               if (up->sptbit != PIM_UPSTREAM_SPTBIT_TRUE &&
+                                   up->parent &&
+                                   up->rpf.source_nexthop.interface !=
+                                           up->parent->rpf.source_nexthop
+                                                   .interface) {
+                                       up->sptbit = PIM_UPSTREAM_SPTBIT_TRUE;
+                                       pim_jp_agg_single_upstream_send(
+                                               &up->parent->rpf, up->parent,
+                                               true);
+                               }
                        }
                        pim_upstream_keep_alive_timer_start(
                                up, pim_ifp->pim->keep_alive_time);