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 60d6f74e1478..b0157e8feacc 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", @@ -1170,6 +1171,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; @@ -1179,6 +1185,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); }