Skip to content

Commit 40dd394

Browse files
committed
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 Example of the problem: r1(config-router)# address-family ipv4 uni r1(config-router-af)# no network 192.168.100.41/32 r1(config-router-af)# exit r1# show bgp import-check-table Current BGP import check cache: r1# show bgp nexthop Current BGP nexthop cache: 192.168.100.41 valid [IGP metric 0], #paths 1, peer 192.168.100.41 if r1-eth0 Last update: Wed Dec 6 11:01:40 2023 BGP now believes it is only watching 192.168.100.41 in the nexthop cache, but zebra doesn't have anything: r1# show ip import-check VRF default: Resolve via default: on r1# show ip nht VRF default: Resolve via default: on So if anything happens to the route that is being matched for 192.168.100.41 bgp is no longer going to be notified about this. The source of this problem is that zebra has dropped the two different tables into 1 table, while bgp has 2 tables to track this. The solution to this problem (other than the rewrite that is being done ) is to have BGP have a bit of smarts about looking in both tables for the bnc and if found in both don't send the delete of the prefix tracking to zebra. Signed-off-by: Donald Sharp <[email protected]>
1 parent cad5ee5 commit 40dd394

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

bgpd/bgp_nexthop.h

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ PREDECL_RBTREE_UNIQ(bgp_nexthop_cache);
2626

2727
/* BGP nexthop cache value structure. */
2828
struct bgp_nexthop_cache {
29+
afi_t afi;
30+
2931
/* The ifindex of the outgoing interface *if* it's a v6 LL */
3032
ifindex_t ifindex_ipv6_ll;
3133

bgpd/bgp_nht.c

+19
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
386386
bnc = bnc_find(tree, &p, srte_color, ifindex);
387387
if (!bnc) {
388388
bnc = bnc_new(tree, &p, srte_color, ifindex);
389+
bnc->afi = afi;
389390
bnc->bgp = bgp_nexthop;
390391
if (BGP_DEBUG(nht, NHT))
391392
zlog_debug("Allocated bnc %pFX(%d)(%u)(%s) peer %p",
@@ -1162,6 +1163,11 @@ static void register_zebra_rnh(struct bgp_nexthop_cache *bnc)
11621163
*/
11631164
static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc)
11641165
{
1166+
struct bgp_nexthop_cache *import;
1167+
struct bgp_nexthop_cache *nexthop;
1168+
1169+
struct bgp *bgp = bnc->bgp;
1170+
11651171
/* Check if we have already registered */
11661172
if (!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
11671173
return;
@@ -1171,6 +1177,19 @@ static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc)
11711177
return;
11721178
}
11731179

1180+
import = bnc_find(&bgp->import_check_table[bnc->afi], &bnc->prefix, 0,
1181+
0);
1182+
nexthop = bnc_find(&bgp->nexthop_cache_table[bnc->afi], &bnc->prefix, 0,
1183+
0);
1184+
1185+
/*
1186+
* If this entry has both a import and a nexthop entry
1187+
* then let's not send the unregister quite as of yet
1188+
* wait until we only have 1 left
1189+
*/
1190+
if (import && nexthop)
1191+
return;
1192+
11741193
sendmsg_zebra_rnh(bnc, ZEBRA_NEXTHOP_UNREGISTER);
11751194
}
11761195

0 commit comments

Comments
 (0)