From d8689cc630aff0fb96a471be19061f82ec9d1b45 Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Wed, 20 Dec 2023 16:23:25 -0800 Subject: [PATCH] bgpd: unimport evpn routes when implicit withdraw When bgp update is received for EVPN prefix where for an existing path's nexthop becomes unreachable, the path is marked as not VALID but the routes were not unimported from tenant vrfs, which lead to stale unicast route(s) and nexthop(s). In Multipath scenario only a specific path may have marked as not VALID, then specific path info for the EVPN prefix required to be unimported from tenant vrf. Ticket: #3671288 Signed-off-by: Chirag Shah Signed-off-by: Donald Sharp --- bgpd/bgp_route.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 08fdb40a0852..2899b94d2ffd 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -4777,9 +4777,10 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, BGP_PATH_VALID); } else { if (BGP_DEBUG(nht, NHT)) { - zlog_debug("%s(%pI4): NH unresolved", + zlog_debug("%s(%pI4): NH unresolved for existing %pFX pi %p flags 0x%x", __func__, - (in_addr_t *)&attr_new->nexthop); + (in_addr_t *)&attr_new->nexthop, + p, pi, pi->flags); } bgp_path_info_unset_flag(dest, pi, BGP_PATH_VALID); @@ -4824,10 +4825,23 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, * updating * the attributes for the route in the VNI(s). */ - if (safi == SAFI_EVPN && - (!same_attr || force_evpn_import) && - CHECK_FLAG(pi->flags, BGP_PATH_VALID)) - bgp_evpn_import_route(bgp, afi, safi, p, pi); + if (safi == SAFI_EVPN) { + if ((!same_attr || force_evpn_import) && + CHECK_FLAG(pi->flags, BGP_PATH_VALID)) + bgp_evpn_import_route(bgp, afi, safi, p, pi); + + /* If existing path is marked invalid then unimport the + * path from EVPN prefix. This will ensure EVPN route + * has only valid paths and path refcount maintained in + * EVPN nexthop is decremented appropriately. + */ + else if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)) { + if (BGP_DEBUG(nht, NHT)) + zlog_debug("%s unimport EVPN %pFX as pi %p is not VALID", + __func__, p, pi); + bgp_evpn_unimport_route(bgp, afi, safi, p, pi); + } + } /* Process change. */ bgp_aggregate_increment(bgp, p, pi, afi, safi);