From da01ccb2216e57767dfcd2d04f237246a1afabfa Mon Sep 17 00:00:00 2001 From: Rajesh Varatharaj Date: Wed, 7 Feb 2024 18:58:39 -0800 Subject: [PATCH] pimd: re-evaluated S,G OILs upon RP changes and for empty SG upstream oils Topology: TOR11 (FHR) --- LEAF-11---SPINE1 (RP)MSDP SPINE-2(RP)MSDP --- LEAF-12 -- TOR12 (LHR) | | | | | | -----------------------------------------------------(ECMP) | | | | | -----------------------------------------------------------------------(ECMP) Issue: In some triggers, S,G upstream is preserved even with the PP timer expiry, resulting in S,G with NULL OILS. This could be because we create a dummy S,G upstream and dummy channel_oif for *,G, where RPF is UNKNOWN. As a result, PIM+VXLAN traffic is never forwarded downstream to LHR. Fix: when the S,G stream is running, Determine if a reevaluation of the outgoing interface list (OIL) is required. S,G upstream should then inherit the OIL from *,G. Testing: - Evpn pim tests - TestEvpnPimSingleVtepOneMdt.test_02_broadcast_traffic_spt_zero - pim-smoke Ticket: #3463827 Signed-off-by: Rajesh Varatharaj --- pimd/pim_mroute.c | 2 +- pimd/pim_upstream.c | 36 +++++++++++++++++++++++++++++++++++- pimd/pim_upstream.h | 2 ++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index 82da3eab253a..cae8391084e4 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -1223,7 +1223,7 @@ int pim_upstream_mroute_add(struct channel_oil *c_oil, const char *name) return pim_upstream_mroute_update(c_oil, name); } -/* Look for IIF changes and update the dateplane entry only if the IIF +/* Look for IIF changes and update the dataplane entry only if the IIF * has changed. */ int pim_upstream_mroute_iif_update(struct channel_oil *c_oil, const char *name) diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 2fb7b9b1c424..b18dedc8d692 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -1972,6 +1972,40 @@ void pim_upstream_terminate(struct pim_instance *pim) wheel_delete(pim->upstream_sg_wheel); pim->upstream_sg_wheel = NULL; } +bool pim_sg_is_reevaluate_oil_req(struct pim_instance *pim, + struct pim_upstream *up) +{ + struct pim_interface *pim_ifp = NULL; + + /* + * Attempt to retrieve the PIM interface information if the RPF + * interface is present + */ + if (up->rpf.source_nexthop.interface) { + pim_ifp = up->rpf.source_nexthop.interface->info; + } else { + if (PIM_DEBUG_PIM_TRACE) { + zlog_debug("%s: up %s RPF is not present", __func__, + up->sg_str); + } + } + + /* + * Determine if a reevaluation of the outgoing interface list (OIL) is + * required. This may be necessary in scenarios such as MSDP where the + * RP role for a group changes from secondary to primary. In such cases, + * SGRpt may receive a prune, resulting in an S,G entry with a NULL OIL. + * The S,G upstream should then inherit the OIL from *,G, which is + * particularly important for VXLAN setups. + */ + if (up->channel_oil->oil_inherited_rescan || + (pim_ifp && I_am_RP(pim_ifp->pim, up->sg.grp)) || + pim_upstream_empty_inherited_olist(up)) { + return true; + } + + return false; +} bool pim_upstream_equal(const void *arg1, const void *arg2) { @@ -2110,7 +2144,7 @@ static void pim_upstream_sg_running(void *arg) * only doing this at this point in time * to get us up and working for the moment */ - if (up->channel_oil->oil_inherited_rescan) { + if (pim_sg_is_reevaluate_oil_req(pim, up)) { if (PIM_DEBUG_TRACE) zlog_debug( "%s: Handling unscanned inherited_olist for %s[%s]", diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h index 3841d1af7b7b..15c4fcfe7ef3 100644 --- a/pimd/pim_upstream.h +++ b/pimd/pim_upstream.h @@ -396,4 +396,6 @@ uint32_t pim_up_mlag_local_cost(struct pim_upstream *up); uint32_t pim_up_mlag_peer_cost(struct pim_upstream *up); void pim_upstream_reeval_use_rpt(struct pim_instance *pim); int pim_upstream_could_register(struct pim_upstream *up); +bool pim_sg_is_reevaluate_oil_req(struct pim_instance *pim, + struct pim_upstream *up); #endif /* PIM_UPSTREAM_H */