From 9d906f17a616a23aeaee20988da950fc027f49a5 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Mon, 6 Nov 2023 13:02:01 -0500 Subject: [PATCH] bgpd: Ensure BGP does not stop monitoring nexthops In some cases BGP can be monitoring the same prefix in both the nexthop and import check tables. If this is the case, when unregistering one bnc from one table make sure we are not still registered in the other Signed-off-by: Donald Sharp --- bgpd/bgp_nexthop.h | 2 ++ bgpd/bgp_nht.c | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/bgpd/bgp_nexthop.h b/bgpd/bgp_nexthop.h index 49cbbaf885f4..90e0074e358d 100644 --- a/bgpd/bgp_nexthop.h +++ b/bgpd/bgp_nexthop.h @@ -26,6 +26,8 @@ PREDECL_RBTREE_UNIQ(bgp_nexthop_cache); /* BGP nexthop cache value structure. */ struct bgp_nexthop_cache { + afi_t afi; + /* The ifindex of the outgoing interface *if* it's a v6 LL */ ifindex_t ifindex_ipv6_ll; diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 9a2166c86bd6..10c0382f6f51 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -386,6 +386,7 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop, bnc = bnc_find(tree, &p, srte_color, ifindex); if (!bnc) { bnc = bnc_new(tree, &p, srte_color, ifindex); + bnc->afi = afi; bnc->bgp = bgp_nexthop; if (BGP_DEBUG(nht, NHT)) zlog_debug("Allocated bnc %pFX(%d)(%u)(%s) peer %p", @@ -1162,6 +1163,11 @@ static void register_zebra_rnh(struct bgp_nexthop_cache *bnc) */ static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc) { + struct bgp_nexthop_cache *import; + struct bgp_nexthop_cache *nexthop; + + struct bgp *bgp = bnc->bgp; + /* Check if we have already registered */ if (!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED)) return; @@ -1171,6 +1177,19 @@ static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc) return; } + import = bnc_find(&bgp->import_check_table[bnc->afi], &bnc->prefix, 0, + 0); + nexthop = bnc_find(&bgp->nexthop_cache_table[bnc->afi], &bnc->prefix, 0, + 0); + + /* + * If this entry has both a import and a nexthop entry + * then let's not send the unregister quite as of yet + * wait until we only have 1 left + */ + if (import && nexthop) + return; + sendmsg_zebra_rnh(bnc, ZEBRA_NEXTHOP_UNREGISTER); }