From 01150ad9b9bbc50dac777949f4d8866b548be206 Mon Sep 17 00:00:00 2001 From: Pat Ruddy Date: Fri, 26 Jun 2020 17:37:30 +0100 Subject: [PATCH] bgpd: do not unregister for prefix nexthop updates if nh exists since the addition of srte_color to the comparison for bgp nexthops it is possible to have several nexthops per prefix but since zebra only sores a per prefix registration we should not unregister for nh notifications for a prefix unti all the nexthops for that prefix have been deleted. Otherwise we can get into a deadlock situation where BGP thinks we have registered but we have unregistered from zebra. Signed-off-by: Pat Ruddy --- bgpd/bgp_nexthop.c | 13 +++++++++++++ bgpd/bgp_nexthop.h | 1 + bgpd/bgp_nht.c | 7 +++++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index e1989746ab99..47e7651bbd0d 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -87,6 +87,19 @@ struct bgp_nexthop_cache *bnc_new(struct bgp_nexthop_cache_head *tree, return bnc; } +bool bnc_existing_for_prefix(struct bgp_nexthop_cache *bnc) +{ + struct bgp_nexthop_cache *bnc_tmp; + + RB_FOREACH (bnc_tmp, bgp_nexthop_cache_head, bnc->tree) { + if (bnc_tmp == bnc) + continue; + if (prefix_cmp(&bnc->prefix, &bnc_tmp->prefix) == 0) + return true; + } + return false; +} + void bnc_free(struct bgp_nexthop_cache *bnc) { bnc_nexthop_free(bnc); diff --git a/bgpd/bgp_nexthop.h b/bgpd/bgp_nexthop.h index 0e2f16791db0..9434ce284765 100644 --- a/bgpd/bgp_nexthop.h +++ b/bgpd/bgp_nexthop.h @@ -114,6 +114,7 @@ extern bool bgp_nexthop_self(struct bgp *bgp, afi_t afi, uint8_t type, extern struct bgp_nexthop_cache *bnc_new(struct bgp_nexthop_cache_head *tree, struct prefix *prefix, uint32_t srte_color); +extern bool bnc_existing_for_prefix(struct bgp_nexthop_cache *bnc); extern void bnc_free(struct bgp_nexthop_cache *bnc); extern struct bgp_nexthop_cache *bnc_find(struct bgp_nexthop_cache_head *tree, struct prefix *prefix, diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 8950f21247aa..0379a5f636c3 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -76,8 +76,11 @@ static void bgp_unlink_nexthop_check(struct bgp_nexthop_cache *bnc) bnc_str(bnc, buf, PREFIX2STR_BUFFER), bnc->srte_color, bnc->bgp->name_pretty); } - unregister_zebra_rnh(bnc, - CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE)); + /* only unregister if this is the last nh for this prefix*/ + if (!bnc_existing_for_prefix(bnc)) + unregister_zebra_rnh(bnc, + CHECK_FLAG(bnc->flags, + BGP_STATIC_ROUTE)); bnc_free(bnc); } }