summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss White <russ@riw.us>2025-04-01 10:21:07 -0400
committerGitHub <noreply@github.com>2025-04-01 10:21:07 -0400
commitcd854223a42bd961533611853d082fd60cacc8a9 (patch)
tree13135a64984002478290a859084c135a0c3314e3
parente55d6f149cf22426f6d13cc8783e6113f01c11e5 (diff)
parentb5e40d4554a68297b4f4d4187c01c06b796288a4 (diff)
Merge pull request #18518 from opensourcerouting/fix/backport_18498_10.0stable/10.0
bgpd: Retain the routes if we do a clear with N-bit set for Graceful-Restart (backport)
-rw-r--r--bgpd/bgp_packet.c7
-rw-r--r--tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py51
2 files changed, 39 insertions, 19 deletions
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 24742b4c07..f372d419b6 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -1037,6 +1037,13 @@ static void bgp_notify_send_internal(struct peer_connection *connection,
/* Add packet to peer's output queue */
stream_fifo_push(connection->obuf, s);
+ /* If Graceful-Restart N-bit (Notification) is exchanged,
+ * and it's not a Hard Reset, let's retain the routes.
+ */
+ if (bgp_has_graceful_restart_notification(peer) && !hard_reset &&
+ CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_MODE))
+ SET_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT);
+
bgp_peer_gr_flags_update(peer);
BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(peer->bgp,
peer->bgp->peer);
diff --git a/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py b/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py
index 2ffcb723ec..9e886771f9 100644
--- a/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py
+++ b/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py
@@ -165,8 +165,8 @@ def test_bgp_administrative_reset_gr():
}
return topotest.json_cmp(output, expected)
- def _bgp_check_gr_notification_stale():
- output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast 172.16.255.2/32 json"))
+ def _bgp_check_gr_notification_stale(router, prefix):
+ output = json.loads(router.vtysh_cmd(f"show bgp ipv4 unicast {prefix} json"))
expected = {
"paths": [
{
@@ -177,34 +177,47 @@ def test_bgp_administrative_reset_gr():
}
return topotest.json_cmp(output, expected)
- def _bgp_clear_r1_and_shutdown():
- r2.vtysh_cmd(
- """
- clear ip bgp 192.168.255.1
- configure terminal
- router bgp
- neighbor 192.168.255.1 shutdown
- """
- )
-
step("Initial BGP converge")
test_func = functools.partial(_bgp_converge)
_, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result is None, "Failed to see BGP convergence on R2"
- step("Reset and shutdown R1")
- _bgp_clear_r1_and_shutdown()
+ step("Reset and delay the session establishement for R1")
+ r1.vtysh_cmd(
+ """
+ configure terminal"
+ router bgp
+ neighbor 192.168.255.2 timers delayopen 60
+ """
+ )
+ r2.vtysh_cmd(
+ """
+ configure terminal"
+ router bgp
+ neighbor 192.168.255.1 timers delayopen 60
+ """
+ )
+ r2.vtysh_cmd("clear ip bgp 192.168.255.1")
+
+ step("Check if stale routes are retained on R1")
+ test_func = functools.partial(
+ _bgp_check_gr_notification_stale, r1, "172.16.255.2/32"
+ )
+ _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+ assert result is None, "Failed to see retained stale routes on R1"
+
+ step("Check if stale routes are retained on R2")
+ test_func = functools.partial(
+ _bgp_check_gr_notification_stale, r2, "172.16.255.1/32"
+ )
+ _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+ assert result is None, "Failed to see retained stale routes on R2"
step("Check if Hard Reset notification wasn't sent from R2")
test_func = functools.partial(_bgp_check_hard_reset)
_, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result is None, "Failed to send Administrative Reset notification from R2"
- step("Check if stale routes are retained on R1")
- test_func = functools.partial(_bgp_check_gr_notification_stale)
- _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
- assert result is None, "Failed to see retained stale routes on R1"
-
if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]