Skip to content

Commit 9cd7d59

Browse files
committed
bgpd: don't advertise LLGR stale routes to non-LLGR peers
When a BGP peer goes down, an LLGR helper keeps the routes it learned from that peer, tags them with the LLGR_STALE community, and holds them as a last resort. RFC 9494 (4.3) says a stale route like that shouldn't be advertised to any neighbor that hasn't advertised the LLGR capability to us - a speaker that doesn't implement LLGR has no notion of staleness and would treat the route as a normal, live path. The advertise check only withheld a stale route when LLGR had been negotiated in neither direction (!RCV && !ADV), but since we advertise the LLGR capability to every peer, ADV is effectively always set and the route went out anyway. The capability that matters here is the neighbor's, so key the decision off whether they advertised it to us (RCV) - which is what the comment sitting right above that check already says we do. That alone isn't enough: the advertise decision is made once per update-subgroup, and an LLGR peer and a non-LLGR peer with the same outbound policy land in the same subgroup, so there's no way to send the route to one but not the other. Add PEER_CAP_LLGR_RCV to PEER_UPDGRP_CAP_FLAGS so the received capability feeds both the update-group hash key and the cmp function - keying off the same axis the advertise check uses - so a non-LLGR peer gets its own update-group and is never merged back in on a hash collision. The new bgp_llgr_no_capability topotest covers it: kill the peer that advertised the route, then confirm r2 keeps feeding the stale route to its LLGR-capable peer r3 while withdrawing it from the non-LLGR peer r4. Worth noting in the config - FRR advertises LLGR whenever it advertises graceful restart, and the default helper mode counts too, so r4 has to set "bgp graceful-restart-disable" to actually be a non-LLGR peer. Signed-off-by: Inder Pooni <inder@nexthop.ai>
1 parent de5eb9e commit 9cd7d59

12 files changed

Lines changed: 270 additions & 3 deletions

File tree

bgpd/bgp_route.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2957,8 +2957,7 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
29572957
if (bgp_attr_get_community(attr) &&
29582958
community_include(bgp_attr_get_community(attr),
29592959
COMMUNITY_LLGR_STALE) &&
2960-
!CHECK_FLAG(peer->cap, PEER_CAP_LLGR_RCV) &&
2961-
!CHECK_FLAG(peer->cap, PEER_CAP_LLGR_ADV))
2960+
!CHECK_FLAG(peer->cap, PEER_CAP_LLGR_RCV))
29622961
return false;
29632962

29642963
/* Perform operations that involve memory allocation.

bgpd/bgp_updgrp.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,14 @@
5252
PEER_FLAG_CONFIG_ENCAPSULATION_SRV6 | PEER_FLAG_CONFIG_ENCAPSULATION_SRV6_RELAX | \
5353
PEER_FLAG_CONFIG_ENCAPSULATION_MPLS)
5454

55-
#define PEER_UPDGRP_CAP_FLAGS (PEER_CAP_AS4_RCV)
55+
/*
56+
* PEER_CAP_LLGR_RCV is included so peers that differ in the received Long-Lived
57+
* Graceful Restart capability land in separate update groups: an LLGR_STALE-tagged
58+
* route is advertised only to peers from which LLGR was received (RFC 9494 Section
59+
* 4.3), and that per-subgroup decision must not merge an LLGR and a non-LLGR peer.
60+
* Folding it into this mask covers both the hash key and the cmp function.
61+
*/
62+
#define PEER_UPDGRP_CAP_FLAGS (PEER_CAP_AS4_RCV | PEER_CAP_LLGR_RCV)
5663

5764
#define PEER_UPDGRP_AF_CAP_FLAGS \
5865
(PEER_CAP_ORF_PREFIX_SM_RCV | PEER_CAP_ADDPATH_AF_TX_ADV | \

tests/topotests/bgp_llgr_no_capability/__init__.py

Whitespace-only changes.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
router bgp 65001
2+
no bgp ebgp-requires-policy
3+
bgp graceful-restart
4+
bgp graceful-restart restart-time 0
5+
bgp long-lived-graceful-restart stale-time 600
6+
neighbor 192.168.1.2 remote-as external
7+
neighbor 192.168.1.2 timers 3 10
8+
neighbor 192.168.1.2 timers connect 1
9+
address-family ipv4 unicast
10+
redistribute connected
11+
exit-address-family
12+
!
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
!
2+
int lo
3+
ip address 172.16.1.1/32
4+
!
5+
int r1-eth0
6+
ip address 192.168.1.1/24
7+
!
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
router bgp 65002
2+
no bgp ebgp-requires-policy
3+
bgp graceful-restart
4+
bgp long-lived-graceful-restart stale-time 600
5+
neighbor 192.168.1.1 remote-as external
6+
neighbor 192.168.1.1 timers 3 10
7+
neighbor 192.168.1.1 timers connect 1
8+
neighbor 192.168.2.2 remote-as external
9+
neighbor 192.168.2.2 timers 3 10
10+
neighbor 192.168.2.2 timers connect 1
11+
neighbor 192.168.3.2 remote-as external
12+
neighbor 192.168.3.2 timers 3 10
13+
neighbor 192.168.3.2 timers connect 1
14+
!
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
!
2+
int r2-eth0
3+
ip address 192.168.1.2/24
4+
!
5+
int r2-eth1
6+
ip address 192.168.2.1/24
7+
!
8+
int r2-eth2
9+
ip address 192.168.3.1/24
10+
!
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
router bgp 65003
2+
no bgp ebgp-requires-policy
3+
bgp graceful-restart
4+
bgp long-lived-graceful-restart stale-time 600
5+
neighbor 192.168.2.1 remote-as external
6+
neighbor 192.168.2.1 timers 3 10
7+
neighbor 192.168.2.1 timers connect 1
8+
!
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
!
2+
int r3-eth0
3+
ip address 192.168.2.2/24
4+
!
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
router bgp 65004
2+
no bgp ebgp-requires-policy
3+
! FRR advertises Graceful Restart (and therefore the LLGR capability) by
4+
! default in helper mode. Disable GR entirely so r4 is a genuine non-LLGR
5+
! peer: it advertises neither the GR nor the LLGR capability to r2.
6+
bgp graceful-restart-disable
7+
neighbor 192.168.3.1 remote-as external
8+
neighbor 192.168.3.1 timers 3 10
9+
neighbor 192.168.3.1 timers connect 1
10+
!

0 commit comments

Comments
 (0)