From: Donald Sharp Date: Thu, 31 Mar 2022 17:07:06 +0000 (-0400) Subject: pimd: Send immediate join( with possible SG RPT prune bit set X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=a577583f64fa7e76fa268a979633956b04225a0e;p=mirror%2Ffrr.git pimd: Send immediate join( with possible SG RPT prune bit set 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 What is actually happening: rtr receives a *,G igmp join, sends a *,G join towards the rp rtr receives a S,G packet 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 (cherry picked from commit 33ec4015b628143a09274421ad31debce788858d) --- diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index 2bf0f8bcca..989e1f4ffe 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -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);