summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_nexthop.c13
-rw-r--r--bgpd/bgp_nexthop.h1
-rw-r--r--bgpd/bgp_nht.c6
3 files changed, 18 insertions, 2 deletions
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index 6f36fd1394..ed026a2fff 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -84,6 +84,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;
+
+ frr_each (bgp_nexthop_cache, bnc->tree, bnc_tmp) {
+ 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 356af54002..c4b913faf4 100644
--- a/bgpd/bgp_nexthop.h
+++ b/bgpd/bgp_nexthop.h
@@ -118,6 +118,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 80ee5f5349..9573d118e5 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -76,8 +76,10 @@ 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);
}
}