From 29f7874cff0f84e7d28e859f246e89edf094b21c Mon Sep 17 00:00:00 2001 From: Andreas Scholdan Date: Wed, 14 Oct 2026 20:20:13 +0200 Subject: [PATCH] Netlab: Add cf-ebgp-gshut case for the BGP gshut command Three nodes: m1 exports two static routes, one of them already carrying a community, to a static eBGP peer (m2) and to a dynamic BGP listener that spawns a session for m3. The case checks, as seen on the peers, that "gshut" adds the GRACEFUL_SHUTDOWN community and keeps an existing one, that the state survives a reconfiguration restarting the instance, that a session spawned by a drained listener inherits it, and that "gshut off" removes it again. Adds a gshut helper next to the existing enable/disable ones. Reference data saved with BIRD 2.20.0 plus the gshut patch. --- netlab/cf-ebgp-gshut/README.md | 12 ++ netlab/cf-ebgp-gshut/bird_m1.conf | 35 +++++ netlab/cf-ebgp-gshut/bird_m1_restart.conf | 36 +++++ netlab/cf-ebgp-gshut/bird_m2.conf | 13 ++ netlab/cf-ebgp-gshut/bird_m3.conf | 14 ++ netlab/cf-ebgp-gshut/config | 12 ++ .../data-v2.20/master4-01-initial-m2 | 17 +++ .../data-v2.20/master4-01-initial-m3 | 2 + .../data-v2.20/master4-02-gshut-m2 | 18 +++ .../data-v2.20/master4-02-gshut-m3 | 2 + .../data-v2.20/master4-03-restart-m2 | 18 +++ .../data-v2.20/master4-03-restart-m3 | 2 + .../data-v2.20/master4-04-dynamic-m2 | 18 +++ .../data-v2.20/master4-04-dynamic-m3 | 18 +++ .../data-v2.20/master4-05-off-m2 | 17 +++ .../data-v2.20/master4-05-off-m3 | 17 +++ .../data-v2.20/proto-01-initial-m1 | 71 ++++++++++ .../data-v2.20/proto-02-gshut-m1 | 72 ++++++++++ .../data-v2.20/proto-03-restart-m1 | 72 ++++++++++ .../data-v2.20/proto-04-dynamic-m1 | 115 +++++++++++++++ .../cf-ebgp-gshut/data-v2.20/proto-05-off-m1 | 112 +++++++++++++++ netlab/cf-ebgp-gshut/test-cf-ebgp-gshut.py | 133 ++++++++++++++++++ netlab/tests/kernel.py | 4 + 23 files changed, 830 insertions(+) create mode 100644 netlab/cf-ebgp-gshut/README.md create mode 100644 netlab/cf-ebgp-gshut/bird_m1.conf create mode 100644 netlab/cf-ebgp-gshut/bird_m1_restart.conf create mode 100644 netlab/cf-ebgp-gshut/bird_m2.conf create mode 100644 netlab/cf-ebgp-gshut/bird_m3.conf create mode 100644 netlab/cf-ebgp-gshut/config create mode 100644 netlab/cf-ebgp-gshut/data-v2.20/master4-01-initial-m2 create mode 100644 netlab/cf-ebgp-gshut/data-v2.20/master4-01-initial-m3 create mode 100644 netlab/cf-ebgp-gshut/data-v2.20/master4-02-gshut-m2 create mode 100644 netlab/cf-ebgp-gshut/data-v2.20/master4-02-gshut-m3 create mode 100644 netlab/cf-ebgp-gshut/data-v2.20/master4-03-restart-m2 create mode 100644 netlab/cf-ebgp-gshut/data-v2.20/master4-03-restart-m3 create mode 100644 netlab/cf-ebgp-gshut/data-v2.20/master4-04-dynamic-m2 create mode 100644 netlab/cf-ebgp-gshut/data-v2.20/master4-04-dynamic-m3 create mode 100644 netlab/cf-ebgp-gshut/data-v2.20/master4-05-off-m2 create mode 100644 netlab/cf-ebgp-gshut/data-v2.20/master4-05-off-m3 create mode 100644 netlab/cf-ebgp-gshut/data-v2.20/proto-01-initial-m1 create mode 100644 netlab/cf-ebgp-gshut/data-v2.20/proto-02-gshut-m1 create mode 100644 netlab/cf-ebgp-gshut/data-v2.20/proto-03-restart-m1 create mode 100644 netlab/cf-ebgp-gshut/data-v2.20/proto-04-dynamic-m1 create mode 100644 netlab/cf-ebgp-gshut/data-v2.20/proto-05-off-m1 create mode 100644 netlab/cf-ebgp-gshut/test-cf-ebgp-gshut.py diff --git a/netlab/cf-ebgp-gshut/README.md b/netlab/cf-ebgp-gshut/README.md new file mode 100644 index 0000000..f79f5e2 --- /dev/null +++ b/netlab/cf-ebgp-gshut/README.md @@ -0,0 +1,12 @@ + +##### Description +This test case exercises the `gshut` command (RFC 8326 graceful shutdown). +The m1 node exports two static routes, one of them already carrying a +community, to a static eBGP peer (m2) and to a dynamic BGP listener that +spawns a session for m3 once m3 is enabled. + +The test checks that `gshut` adds the GRACEFUL_SHUTDOWN community (65535, 0) +to the routes as seen by the peer, that an existing community is preserved, +that the state survives a reconfiguration which restarts the protocol +instance, that a session spawned by a drained dynamic listener inherits the +state, and that `gshut off` removes the community again. diff --git a/netlab/cf-ebgp-gshut/bird_m1.conf b/netlab/cf-ebgp-gshut/bird_m1.conf new file mode 100644 index 0000000..6fb623a --- /dev/null +++ b/netlab/cf-ebgp-gshut/bird_m1.conf @@ -0,0 +1,35 @@ +log "bird.log" all; +router id 10.1.1.1; + +protocol device {} + +protocol static static4 { + ipv4; + route 10.111.1.0/24 unreachable; + route 10.111.2.0/24 unreachable; +} + +filter export_static { + if source != RTS_STATIC then reject; + if net = 10.111.2.0/24 then bgp_community.add((65000, 1)); + accept; +} + +protocol bgp ebgp_m2 { + ipv4 { + import all; + export filter export_static; + }; + local 10.0.12.1 as 65001; + neighbor 10.0.12.2 as 65002; +} + +protocol bgp ebgp_dyn { + ipv4 { + import all; + export filter export_static; + }; + local 10.0.13.1 as 65001; + neighbor range 10.0.13.0/24 as 65003; + dynamic name "ebgp_m3"; +} diff --git a/netlab/cf-ebgp-gshut/bird_m1_restart.conf b/netlab/cf-ebgp-gshut/bird_m1_restart.conf new file mode 100644 index 0000000..4ea5650 --- /dev/null +++ b/netlab/cf-ebgp-gshut/bird_m1_restart.conf @@ -0,0 +1,36 @@ +log "bird.log" all; +router id 10.1.1.1; + +protocol device {} + +protocol static static4 { + ipv4; + route 10.111.1.0/24 unreachable; + route 10.111.2.0/24 unreachable; +} + +filter export_static { + if source != RTS_STATIC then reject; + if net = 10.111.2.0/24 then bgp_community.add((65000, 1)); + accept; +} + +protocol bgp ebgp_m2 { + ipv4 { + import all; + export filter export_static; + }; + local 10.0.12.1 as 65001; + hold time 90; + neighbor 10.0.12.2 as 65002; +} + +protocol bgp ebgp_dyn { + ipv4 { + import all; + export filter export_static; + }; + local 10.0.13.1 as 65001; + neighbor range 10.0.13.0/24 as 65003; + dynamic name "ebgp_m3"; +} diff --git a/netlab/cf-ebgp-gshut/bird_m2.conf b/netlab/cf-ebgp-gshut/bird_m2.conf new file mode 100644 index 0000000..e35324f --- /dev/null +++ b/netlab/cf-ebgp-gshut/bird_m2.conf @@ -0,0 +1,13 @@ +log "bird.log" all; +router id 10.2.1.1; + +protocol device {} + +protocol bgp ebgp_m1 { + ipv4 { + import all; + export none; + }; + local 10.0.12.2 as 65002; + neighbor 10.0.12.1 as 65001; +} diff --git a/netlab/cf-ebgp-gshut/bird_m3.conf b/netlab/cf-ebgp-gshut/bird_m3.conf new file mode 100644 index 0000000..27c8cfe --- /dev/null +++ b/netlab/cf-ebgp-gshut/bird_m3.conf @@ -0,0 +1,14 @@ +log "bird.log" all; +router id 10.3.1.1; + +protocol device {} + +protocol bgp ebgp_m1 { + disabled; + ipv4 { + import all; + export none; + }; + local 10.0.13.2 as 65003; + neighbor 10.0.13.1 as 65001; +} diff --git a/netlab/cf-ebgp-gshut/config b/netlab/cf-ebgp-gshut/config new file mode 100644 index 0000000..5454115 --- /dev/null +++ b/netlab/cf-ebgp-gshut/config @@ -0,0 +1,12 @@ +NETLAB_NODES="m1 m2 m3" + +netlab_init + +if_dummy m1 ve0 10.1.1 2001:db8:1:1 +if_dummy m2 ve0 10.2.1 2001:db8:2:1 +if_dummy m3 ve0 10.3.1 2001:db8:3:1 + +if_veth m1 ve2 m2 ve1 10.0.12 2001:db8:0:12 +if_veth m1 ve3 m3 ve1 10.0.13 2001:db8:0:13 + +netlab_start diff --git a/netlab/cf-ebgp-gshut/data-v2.20/master4-01-initial-m2 b/netlab/cf-ebgp-gshut/data-v2.20/master4-01-initial-m2 new file mode 100644 index 0000000..2140fab --- /dev/null +++ b/netlab/cf-ebgp-gshut/data-v2.20/master4-01-initial-m2 @@ -0,0 +1,17 @@ +BIRD ready. +Table master4: +10.111.1.0/24 unicast [ebgp_m1 ] * (100) [AS65001i] + via 10.0.12.1 on ve1 + Type: BGP univ + BGP.origin: IGP + BGP.as_path: 65001 + BGP.next_hop: 10.0.12.1 + BGP.local_pref: 100 +10.111.2.0/24 unicast [ebgp_m1 ] * (100) [AS65001i] + via 10.0.12.1 on ve1 + Type: BGP univ + BGP.origin: IGP + BGP.as_path: 65001 + BGP.next_hop: 10.0.12.1 + BGP.local_pref: 100 + BGP.community: (65000,1) diff --git a/netlab/cf-ebgp-gshut/data-v2.20/master4-01-initial-m3 b/netlab/cf-ebgp-gshut/data-v2.20/master4-01-initial-m3 new file mode 100644 index 0000000..332ac07 --- /dev/null +++ b/netlab/cf-ebgp-gshut/data-v2.20/master4-01-initial-m3 @@ -0,0 +1,2 @@ +BIRD ready. +Table master4: diff --git a/netlab/cf-ebgp-gshut/data-v2.20/master4-02-gshut-m2 b/netlab/cf-ebgp-gshut/data-v2.20/master4-02-gshut-m2 new file mode 100644 index 0000000..4e68b0e --- /dev/null +++ b/netlab/cf-ebgp-gshut/data-v2.20/master4-02-gshut-m2 @@ -0,0 +1,18 @@ +BIRD ready. +Table master4: +10.111.1.0/24 unicast [ebgp_m1 ] * (100) [AS65001i] + via 10.0.12.1 on ve1 + Type: BGP univ + BGP.origin: IGP + BGP.as_path: 65001 + BGP.next_hop: 10.0.12.1 + BGP.local_pref: 100 + BGP.community: (65535,0) +10.111.2.0/24 unicast [ebgp_m1 ] * (100) [AS65001i] + via 10.0.12.1 on ve1 + Type: BGP univ + BGP.origin: IGP + BGP.as_path: 65001 + BGP.next_hop: 10.0.12.1 + BGP.local_pref: 100 + BGP.community: (65000,1) (65535,0) diff --git a/netlab/cf-ebgp-gshut/data-v2.20/master4-02-gshut-m3 b/netlab/cf-ebgp-gshut/data-v2.20/master4-02-gshut-m3 new file mode 100644 index 0000000..332ac07 --- /dev/null +++ b/netlab/cf-ebgp-gshut/data-v2.20/master4-02-gshut-m3 @@ -0,0 +1,2 @@ +BIRD ready. +Table master4: diff --git a/netlab/cf-ebgp-gshut/data-v2.20/master4-03-restart-m2 b/netlab/cf-ebgp-gshut/data-v2.20/master4-03-restart-m2 new file mode 100644 index 0000000..4e68b0e --- /dev/null +++ b/netlab/cf-ebgp-gshut/data-v2.20/master4-03-restart-m2 @@ -0,0 +1,18 @@ +BIRD ready. +Table master4: +10.111.1.0/24 unicast [ebgp_m1 ] * (100) [AS65001i] + via 10.0.12.1 on ve1 + Type: BGP univ + BGP.origin: IGP + BGP.as_path: 65001 + BGP.next_hop: 10.0.12.1 + BGP.local_pref: 100 + BGP.community: (65535,0) +10.111.2.0/24 unicast [ebgp_m1 ] * (100) [AS65001i] + via 10.0.12.1 on ve1 + Type: BGP univ + BGP.origin: IGP + BGP.as_path: 65001 + BGP.next_hop: 10.0.12.1 + BGP.local_pref: 100 + BGP.community: (65000,1) (65535,0) diff --git a/netlab/cf-ebgp-gshut/data-v2.20/master4-03-restart-m3 b/netlab/cf-ebgp-gshut/data-v2.20/master4-03-restart-m3 new file mode 100644 index 0000000..332ac07 --- /dev/null +++ b/netlab/cf-ebgp-gshut/data-v2.20/master4-03-restart-m3 @@ -0,0 +1,2 @@ +BIRD ready. +Table master4: diff --git a/netlab/cf-ebgp-gshut/data-v2.20/master4-04-dynamic-m2 b/netlab/cf-ebgp-gshut/data-v2.20/master4-04-dynamic-m2 new file mode 100644 index 0000000..4e68b0e --- /dev/null +++ b/netlab/cf-ebgp-gshut/data-v2.20/master4-04-dynamic-m2 @@ -0,0 +1,18 @@ +BIRD ready. +Table master4: +10.111.1.0/24 unicast [ebgp_m1 ] * (100) [AS65001i] + via 10.0.12.1 on ve1 + Type: BGP univ + BGP.origin: IGP + BGP.as_path: 65001 + BGP.next_hop: 10.0.12.1 + BGP.local_pref: 100 + BGP.community: (65535,0) +10.111.2.0/24 unicast [ebgp_m1 ] * (100) [AS65001i] + via 10.0.12.1 on ve1 + Type: BGP univ + BGP.origin: IGP + BGP.as_path: 65001 + BGP.next_hop: 10.0.12.1 + BGP.local_pref: 100 + BGP.community: (65000,1) (65535,0) diff --git a/netlab/cf-ebgp-gshut/data-v2.20/master4-04-dynamic-m3 b/netlab/cf-ebgp-gshut/data-v2.20/master4-04-dynamic-m3 new file mode 100644 index 0000000..b287ef3 --- /dev/null +++ b/netlab/cf-ebgp-gshut/data-v2.20/master4-04-dynamic-m3 @@ -0,0 +1,18 @@ +BIRD ready. +Table master4: +10.111.1.0/24 unicast [ebgp_m1 ] * (100) [AS65001i] + via 10.0.13.1 on ve1 + Type: BGP univ + BGP.origin: IGP + BGP.as_path: 65001 + BGP.next_hop: 10.0.13.1 + BGP.local_pref: 100 + BGP.community: (65535,0) +10.111.2.0/24 unicast [ebgp_m1 ] * (100) [AS65001i] + via 10.0.13.1 on ve1 + Type: BGP univ + BGP.origin: IGP + BGP.as_path: 65001 + BGP.next_hop: 10.0.13.1 + BGP.local_pref: 100 + BGP.community: (65000,1) (65535,0) diff --git a/netlab/cf-ebgp-gshut/data-v2.20/master4-05-off-m2 b/netlab/cf-ebgp-gshut/data-v2.20/master4-05-off-m2 new file mode 100644 index 0000000..2140fab --- /dev/null +++ b/netlab/cf-ebgp-gshut/data-v2.20/master4-05-off-m2 @@ -0,0 +1,17 @@ +BIRD ready. +Table master4: +10.111.1.0/24 unicast [ebgp_m1 ] * (100) [AS65001i] + via 10.0.12.1 on ve1 + Type: BGP univ + BGP.origin: IGP + BGP.as_path: 65001 + BGP.next_hop: 10.0.12.1 + BGP.local_pref: 100 +10.111.2.0/24 unicast [ebgp_m1 ] * (100) [AS65001i] + via 10.0.12.1 on ve1 + Type: BGP univ + BGP.origin: IGP + BGP.as_path: 65001 + BGP.next_hop: 10.0.12.1 + BGP.local_pref: 100 + BGP.community: (65000,1) diff --git a/netlab/cf-ebgp-gshut/data-v2.20/master4-05-off-m3 b/netlab/cf-ebgp-gshut/data-v2.20/master4-05-off-m3 new file mode 100644 index 0000000..3f00f05 --- /dev/null +++ b/netlab/cf-ebgp-gshut/data-v2.20/master4-05-off-m3 @@ -0,0 +1,17 @@ +BIRD ready. +Table master4: +10.111.1.0/24 unicast [ebgp_m1 ] * (100) [AS65001i] + via 10.0.13.1 on ve1 + Type: BGP univ + BGP.origin: IGP + BGP.as_path: 65001 + BGP.next_hop: 10.0.13.1 + BGP.local_pref: 100 +10.111.2.0/24 unicast [ebgp_m1 ] * (100) [AS65001i] + via 10.0.13.1 on ve1 + Type: BGP univ + BGP.origin: IGP + BGP.as_path: 65001 + BGP.next_hop: 10.0.13.1 + BGP.local_pref: 100 + BGP.community: (65000,1) diff --git a/netlab/cf-ebgp-gshut/data-v2.20/proto-01-initial-m1 b/netlab/cf-ebgp-gshut/data-v2.20/proto-01-initial-m1 new file mode 100644 index 0000000..c44a542 --- /dev/null +++ b/netlab/cf-ebgp-gshut/data-v2.20/proto-01-initial-m1 @@ -0,0 +1,71 @@ +BIRD ready. +Name Proto Table State Since Info +device1 Device --- up + +static4 Static master4 up + Channel ipv4 + State: UP + Table: master4 + Preference: 200 + Input filter: ACCEPT + Output filter: REJECT + Routes: 2 imported, 0 exported, 2 preferred + Route change stats: received rejected filtered ignored accepted + Import updates: + Import withdraws: + Export updates: + Export withdraws: + +ebgp_m2 BGP --- up Established + BGP state: Established + Neighbor address: 10.0.12.2 + Neighbor AS: 65002 + Local AS: 65001 + Neighbor ID: 10.2.1.1 + Local capabilities + Multiprotocol + AF announced: ipv4 + Route refresh + Graceful restart + 4-octet AS numbers + Enhanced refresh + Long-lived graceful restart + Neighbor capabilities + Multiprotocol + AF announced: ipv4 + Route refresh + Graceful restart + 4-octet AS numbers + Enhanced refresh + Long-lived graceful restart + Session: external AS4 + Source address: 10.0.12.1 + Hold timer: /240 + Keepalive timer: /80 + Send hold timer: /480 + Channel ipv4 + State: UP + Table: master4 + Preference: 100 + Input filter: ACCEPT + Output filter: export_static + Routes: 0 imported, 2 exported, 0 preferred + Route change stats: received rejected filtered ignored accepted + Import updates: + Import withdraws: + Export updates: + Export withdraws: + BGP Next hop: 10.0.12.1 + +ebgp_dyn BGP --- start Passive + BGP state: Passive + Neighbor range: 10.0.13.0/24 + Neighbor AS: 65003 + Local AS: 65001 + Channel ipv4 + State: DOWN + Table: master4 + Preference: 100 + Input filter: ACCEPT + Output filter: export_static + diff --git a/netlab/cf-ebgp-gshut/data-v2.20/proto-02-gshut-m1 b/netlab/cf-ebgp-gshut/data-v2.20/proto-02-gshut-m1 new file mode 100644 index 0000000..e6d5bf5 --- /dev/null +++ b/netlab/cf-ebgp-gshut/data-v2.20/proto-02-gshut-m1 @@ -0,0 +1,72 @@ +BIRD ready. +Name Proto Table State Since Info +device1 Device --- up + +static4 Static master4 up + Channel ipv4 + State: UP + Table: master4 + Preference: 200 + Input filter: ACCEPT + Output filter: REJECT + Routes: 2 imported, 0 exported, 2 preferred + Route change stats: received rejected filtered ignored accepted + Import updates: + Import withdraws: + Export updates: + Export withdraws: + +ebgp_m2 BGP --- up Established + BGP state: Established + Neighbor address: 10.0.12.2 + Neighbor AS: 65002 + Local AS: 65001 + Graceful shutdown active + Neighbor ID: 10.2.1.1 + Local capabilities + Multiprotocol + AF announced: ipv4 + Route refresh + Graceful restart + 4-octet AS numbers + Enhanced refresh + Long-lived graceful restart + Neighbor capabilities + Multiprotocol + AF announced: ipv4 + Route refresh + Graceful restart + 4-octet AS numbers + Enhanced refresh + Long-lived graceful restart + Session: external AS4 + Source address: 10.0.12.1 + Hold timer: /240 + Keepalive timer: /80 + Send hold timer: /480 + Channel ipv4 + State: UP + Table: master4 + Preference: 100 + Input filter: ACCEPT + Output filter: export_static + Routes: 0 imported, 2 exported, 0 preferred + Route change stats: received rejected filtered ignored accepted + Import updates: + Import withdraws: + Export updates: + Export withdraws: + BGP Next hop: 10.0.12.1 + +ebgp_dyn BGP --- start Passive + BGP state: Passive + Neighbor range: 10.0.13.0/24 + Neighbor AS: 65003 + Local AS: 65001 + Channel ipv4 + State: DOWN + Table: master4 + Preference: 100 + Input filter: ACCEPT + Output filter: export_static + diff --git a/netlab/cf-ebgp-gshut/data-v2.20/proto-03-restart-m1 b/netlab/cf-ebgp-gshut/data-v2.20/proto-03-restart-m1 new file mode 100644 index 0000000..d344b59 --- /dev/null +++ b/netlab/cf-ebgp-gshut/data-v2.20/proto-03-restart-m1 @@ -0,0 +1,72 @@ +BIRD ready. +Name Proto Table State Since Info +device1 Device --- up + +static4 Static master4 up + Channel ipv4 + State: UP + Table: master4 + Preference: 200 + Input filter: ACCEPT + Output filter: REJECT + Routes: 2 imported, 0 exported, 2 preferred + Route change stats: received rejected filtered ignored accepted + Import updates: + Import withdraws: + Export updates: + Export withdraws: + +ebgp_m2 BGP --- up Established + BGP state: Established + Neighbor address: 10.0.12.2 + Neighbor AS: 65002 + Local AS: 65001 + Graceful shutdown active + Neighbor ID: 10.2.1.1 + Local capabilities + Multiprotocol + AF announced: ipv4 + Route refresh + Graceful restart + 4-octet AS numbers + Enhanced refresh + Long-lived graceful restart + Neighbor capabilities + Multiprotocol + AF announced: ipv4 + Route refresh + Graceful restart + 4-octet AS numbers + Enhanced refresh + Long-lived graceful restart + Session: external AS4 + Source address: 10.0.12.1 + Hold timer: /90 + Keepalive timer: /30 + Send hold timer: /180 + Channel ipv4 + State: UP + Table: master4 + Preference: 100 + Input filter: ACCEPT + Output filter: export_static + Routes: 0 imported, 2 exported, 0 preferred + Route change stats: received rejected filtered ignored accepted + Import updates: + Import withdraws: + Export updates: + Export withdraws: + BGP Next hop: 10.0.12.1 + +ebgp_dyn BGP --- start Passive + BGP state: Passive + Neighbor range: 10.0.13.0/24 + Neighbor AS: 65003 + Local AS: 65001 + Channel ipv4 + State: DOWN + Table: master4 + Preference: 100 + Input filter: ACCEPT + Output filter: export_static + diff --git a/netlab/cf-ebgp-gshut/data-v2.20/proto-04-dynamic-m1 b/netlab/cf-ebgp-gshut/data-v2.20/proto-04-dynamic-m1 new file mode 100644 index 0000000..d9b57d2 --- /dev/null +++ b/netlab/cf-ebgp-gshut/data-v2.20/proto-04-dynamic-m1 @@ -0,0 +1,115 @@ +BIRD ready. +Name Proto Table State Since Info +device1 Device --- up + +static4 Static master4 up + Channel ipv4 + State: UP + Table: master4 + Preference: 200 + Input filter: ACCEPT + Output filter: REJECT + Routes: 2 imported, 0 exported, 2 preferred + Route change stats: received rejected filtered ignored accepted + Import updates: + Import withdraws: + Export updates: + Export withdraws: + +ebgp_m2 BGP --- up Established + BGP state: Established + Neighbor address: 10.0.12.2 + Neighbor AS: 65002 + Local AS: 65001 + Graceful shutdown active + Neighbor ID: 10.2.1.1 + Local capabilities + Multiprotocol + AF announced: ipv4 + Route refresh + Graceful restart + 4-octet AS numbers + Enhanced refresh + Long-lived graceful restart + Neighbor capabilities + Multiprotocol + AF announced: ipv4 + Route refresh + Graceful restart + 4-octet AS numbers + Enhanced refresh + Long-lived graceful restart + Session: external AS4 + Source address: 10.0.12.1 + Hold timer: /90 + Keepalive timer: /30 + Send hold timer: /180 + Channel ipv4 + State: UP + Table: master4 + Preference: 100 + Input filter: ACCEPT + Output filter: export_static + Routes: 0 imported, 2 exported, 0 preferred + Route change stats: received rejected filtered ignored accepted + Import updates: + Import withdraws: + Export updates: + Export withdraws: + BGP Next hop: 10.0.12.1 + +ebgp_dyn BGP --- start Passive + BGP state: Passive + Neighbor range: 10.0.13.0/24 + Neighbor AS: 65003 + Local AS: 65001 + Graceful shutdown active + Channel ipv4 + State: DOWN + Table: master4 + Preference: 100 + Input filter: ACCEPT + Output filter: export_static + +ebgp_m31 BGP --- up Established + BGP state: Established + Neighbor address: 10.0.13.2 + Neighbor AS: 65003 + Local AS: 65001 + Graceful shutdown active + Neighbor ID: 10.3.1.1 + Local capabilities + Multiprotocol + AF announced: ipv4 + Route refresh + Graceful restart + 4-octet AS numbers + Enhanced refresh + Long-lived graceful restart + Neighbor capabilities + Multiprotocol + AF announced: ipv4 + Route refresh + Graceful restart + 4-octet AS numbers + Enhanced refresh + Long-lived graceful restart + Session: external AS4 + Source address: 10.0.13.1 + Hold timer: /240 + Keepalive timer: /80 + Send hold timer: /480 + Channel ipv4 + State: UP + Table: master4 + Preference: 100 + Input filter: ACCEPT + Output filter: export_static + Routes: 0 imported, 2 exported, 0 preferred + Route change stats: received rejected filtered ignored accepted + Import updates: + Import withdraws: + Export updates: + Export withdraws: + BGP Next hop: 10.0.13.1 + diff --git a/netlab/cf-ebgp-gshut/data-v2.20/proto-05-off-m1 b/netlab/cf-ebgp-gshut/data-v2.20/proto-05-off-m1 new file mode 100644 index 0000000..681d8cd --- /dev/null +++ b/netlab/cf-ebgp-gshut/data-v2.20/proto-05-off-m1 @@ -0,0 +1,112 @@ +BIRD ready. +Name Proto Table State Since Info +device1 Device --- up + +static4 Static master4 up + Channel ipv4 + State: UP + Table: master4 + Preference: 200 + Input filter: ACCEPT + Output filter: REJECT + Routes: 2 imported, 0 exported, 2 preferred + Route change stats: received rejected filtered ignored accepted + Import updates: + Import withdraws: + Export updates: + Export withdraws: + +ebgp_m2 BGP --- up Established + BGP state: Established + Neighbor address: 10.0.12.2 + Neighbor AS: 65002 + Local AS: 65001 + Neighbor ID: 10.2.1.1 + Local capabilities + Multiprotocol + AF announced: ipv4 + Route refresh + Graceful restart + 4-octet AS numbers + Enhanced refresh + Long-lived graceful restart + Neighbor capabilities + Multiprotocol + AF announced: ipv4 + Route refresh + Graceful restart + 4-octet AS numbers + Enhanced refresh + Long-lived graceful restart + Session: external AS4 + Source address: 10.0.12.1 + Hold timer: /90 + Keepalive timer: /30 + Send hold timer: /180 + Channel ipv4 + State: UP + Table: master4 + Preference: 100 + Input filter: ACCEPT + Output filter: export_static + Routes: 0 imported, 2 exported, 0 preferred + Route change stats: received rejected filtered ignored accepted + Import updates: + Import withdraws: + Export updates: + Export withdraws: + BGP Next hop: 10.0.12.1 + +ebgp_dyn BGP --- start Passive + BGP state: Passive + Neighbor range: 10.0.13.0/24 + Neighbor AS: 65003 + Local AS: 65001 + Channel ipv4 + State: DOWN + Table: master4 + Preference: 100 + Input filter: ACCEPT + Output filter: export_static + +ebgp_m31 BGP --- up Established + BGP state: Established + Neighbor address: 10.0.13.2 + Neighbor AS: 65003 + Local AS: 65001 + Neighbor ID: 10.3.1.1 + Local capabilities + Multiprotocol + AF announced: ipv4 + Route refresh + Graceful restart + 4-octet AS numbers + Enhanced refresh + Long-lived graceful restart + Neighbor capabilities + Multiprotocol + AF announced: ipv4 + Route refresh + Graceful restart + 4-octet AS numbers + Enhanced refresh + Long-lived graceful restart + Session: external AS4 + Source address: 10.0.13.1 + Hold timer: /240 + Keepalive timer: /80 + Send hold timer: /480 + Channel ipv4 + State: UP + Table: master4 + Preference: 100 + Input filter: ACCEPT + Output filter: export_static + Routes: 0 imported, 2 exported, 0 preferred + Route change stats: received rejected filtered ignored accepted + Import updates: + Import withdraws: + Export updates: + Export withdraws: + BGP Next hop: 10.0.13.1 + diff --git a/netlab/cf-ebgp-gshut/test-cf-ebgp-gshut.py b/netlab/cf-ebgp-gshut/test-cf-ebgp-gshut.py new file mode 100644 index 0000000..cc8c5ce --- /dev/null +++ b/netlab/cf-ebgp-gshut/test-cf-ebgp-gshut.py @@ -0,0 +1,133 @@ +import pytest + +import tests.kernel as tk +import tests.config as cf + + +LIMIT = 30 +PEERS = ("m2", "m3") +LOG_OPT = [ + " ebgp_m1: Received: Other configuration change", +] + +## 1: Initial state, no community on the peers + +@pytest.mark.skipif(cf.save == False, reason="mode: save") +def test_01_wait(): + """Wait until the time (limit) runs out""" + tk.wait(LIMIT) + + +@pytest.mark.parametrize("exp_devs", PEERS) +def test_01_bird_routes_ipv4(exp_devs: str): + """IPv4: get the content of BIRD tables and check it""" + tk.test_bird_routes("master4-01-initial", exp_devs, "master4") + + +def test_01_protocols_m1(): + """BGP: get the content of proto all message and check it""" + tk.test_protocols(key="proto-01-initial", dev="m1", opts="all") + + +## 2: Graceful shutdown of the static session, m2 sees the community + +def test_02_gshut_m2(): + tk.gshut_bird_protocol("m1", "ebgp_m2") + + +@pytest.mark.skipif(cf.save == False, reason="mode: save") +def test_02_wait(): + """Wait until the time (limit) runs out""" + tk.wait(5) + + +@pytest.mark.parametrize("exp_devs", PEERS) +def test_02_bird_routes_ipv4(exp_devs: str): + """IPv4: get the content of BIRD tables and check it""" + tk.test_bird_routes("master4-02-gshut", exp_devs, "master4") + + +def test_02_protocols_m1(): + """BGP: get the content of proto all message and check it""" + tk.test_protocols(key="proto-02-gshut", dev="m1", opts="all") + + +## 3: Reconfiguration that restarts the session keeps the state + +def test_03_reconfigure_restart(): + """Reconfigure m1 with a changed hold time, which restarts ebgp_m2""" + tk.run_configure("m1", "bird_restart.conf") + + +@pytest.mark.skipif(cf.save == False, reason="mode: save") +def test_03_wait(): + """Wait until the time (limit) runs out""" + tk.wait(LIMIT) + + +@pytest.mark.parametrize("exp_devs", PEERS) +def test_03_bird_routes_ipv4(exp_devs: str): + """IPv4: get the content of BIRD tables and check it""" + tk.test_bird_routes("master4-03-restart", exp_devs, "master4") + + +def test_03_protocols_m1(): + """BGP: get the content of proto all message and check it""" + tk.test_protocols(key="proto-03-restart", dev="m1", opts="all") + + +## 4: A session spawned by a drained dynamic listener inherits the state + +def test_04_gshut_listener(): + tk.gshut_bird_protocol("m1", "ebgp_dyn") + + +def test_04_connect_m3(): + """Enable the session on m3 for the first time, so m1 spawns a dynamic instance""" + tk.enable_bird_protocol("m3", "ebgp_m1") + + +@pytest.mark.skipif(cf.save == False, reason="mode: save") +def test_04_wait(): + """Wait until the time (limit) runs out""" + tk.wait(LIMIT) + + +@pytest.mark.parametrize("exp_devs", PEERS) +def test_04_bird_routes_ipv4(exp_devs: str): + """IPv4: get the content of BIRD tables and check it""" + tk.test_bird_routes("master4-04-dynamic", exp_devs, "master4") + + +def test_04_protocols_m1(): + """BGP: get the content of proto all message and check it""" + tk.test_protocols(key="proto-04-dynamic", dev="m1", opts="all") + + +## 5: Graceful shutdown off, communities gone + +def test_05_gshut_off(): + tk.gshut_bird_protocol("m1", "all", off=True) + + +@pytest.mark.skipif(cf.save == False, reason="mode: save") +def test_05_wait(): + """Wait until the time (limit) runs out""" + tk.wait(5) + + +@pytest.mark.parametrize("exp_devs", PEERS) +def test_05_bird_routes_ipv4(exp_devs: str): + """IPv4: get the content of BIRD tables and check it""" + tk.test_bird_routes("master4-05-off", exp_devs, "master4") + + +def test_05_protocols_m1(): + """BGP: get the content of proto all message and check it""" + tk.test_protocols(key="proto-05-off", dev="m1", opts="all") + + +@pytest.mark.parametrize("exp_devs", ("m1", "m2", "m3")) +def test_logging(exp_devs: str): + """Check the log files. There should only DBG, INFO and TRACE messages""" + tk.test_logs(exp_devs, LOG_OPT, []) diff --git a/netlab/tests/kernel.py b/netlab/tests/kernel.py index 725c27e..847cafa 100644 --- a/netlab/tests/kernel.py +++ b/netlab/tests/kernel.py @@ -395,6 +395,10 @@ def enable_bird_protocol(dev: str, proto: str) -> None: os.system(f"cd {dev} && ./birdc -l enable {proto}") +def gshut_bird_protocol(dev: str, proto: str, off: bool = False) -> None: + os.system(f"cd {dev} && ./birdc -l gshut {'off ' if off else ''}{proto}") + + def reload_bird_protocol(dev: str, proto: str, what: str, must_fail: bool=False) -> None: command = f"cd {dev} && ./birdc -l reload {what} '{proto}'" captured_stdout = process_command(command) -- 2.43.0