2 # SPDX-License-Identifier: ISC
4 # Copyright (c) 2019 by VMware, Inc. ("VMware")
5 # Used Copyright (c) 2018 by Network Device Education Foundation, Inc. ("NetDEF")
10 Following tests are covered to test BGP Graceful Restart functionality.
11 Basic Common Test steps for all the test case below :
12 - Create topology (setup module)
13 Creating 2 routers topology, r1, r2 in IBGP
15 - Verify for bgp to converge
16 - Configure BGP Garceful Restart on both the routers.
18 1. Transition from Peer-level helper to Global Restarting
19 2. Transition from Peer-level helper to Global inherit helper
20 3. Transition from Peer-level restarting to Global inherit helper
21 4. Default GR functional mode is Helper.
22 5. Verify that the restarting node sets "R" bit while sending the
23 BGP open messages after the node restart, only if GR is enabled.
24 6. Verify if restarting node resets R bit in BGP open message
25 during normal BGP session flaps as well, even when GR restarting
26 mode is enabled. Here link flap happen due to interface UP/DOWN.
27 7. Verify if restarting node resets R bit in BGP
28 open message during normal BGP session flaps when GR is disabled.
29 8. Verify that restarting nodes set "F" bit while sending
30 the BGP open messages after it restarts, only when BGP GR is enabled.
31 9. Verify that only GR helper routers keep the stale
32 route entries, not any GR disabled router.
33 10. Verify that GR helper routers keeps all the routes received
34 from restarting node if both the routers are configured as
36 11. Verify that GR helper routers delete all the routes
37 received from a node if both the routers are configured as GR
39 12. After BGP neighborship is established and GR capability is exchanged,
40 transition restarting router to disabled state and vice versa.
41 13. After BGP neighborship is established and GR capability is exchanged,
42 transition restarting router to disabled state and vice versa.
43 14. Verify that restarting nodes reset "F" bit while sending
44 the BGP open messages after it's restarts, when BGP GR is **NOT** enabled.
45 15. Verify that only GR helper routers keep the stale
46 route entries, not any GR disabled router.
47 16. Transition from Global Restarting to Disable and then Global
48 Disable to Restarting.
49 17. Transition from Global Helper to Disable and then Global
51 18. Transition from Global Restart to Helper and then Global
52 Helper to Restart, Global Mode : GR Restarting
53 PerPeer Mode : GR Helper
54 GR Mode effective : GR Helper
55 19. Transition from Peer-level helper to Global Restarting,
56 Global Mode : GR Restarting
57 PerPeer Mode : GR Restarting
58 GR Mode effective : GR Restarting
59 20. Transition from Peer-level restart to Global Restart
60 Global Mode : GR Restarting
61 PerPeer Mode : GR Restarting
62 GR Mode effective : GR Restarting
63 21. Transition from Peer-level disabled to Global Restart
64 Global Mode : GR Restarting
65 PerPeer Mode : GR Disabled
66 GR Mode effective : GR Disabled
67 22. Peer-level inherit from Global Restarting
68 Global Mode : GR Restart
70 GR Mode effective : GR Restart
71 23. Transition from Peer-level disable to Global inherit helper
73 PerPeer Mode : GR Disable
74 GR Mode effective : GR Disable
76 These tests have been broken up into 4 sub python scripts because
77 the totality of this run was fairly significant.
85 # Save the Current Working Directory to find configuration files.
86 CWD
= os
.path
.dirname(os
.path
.realpath(__file__
))
87 sys
.path
.append(os
.path
.join("../"))
88 sys
.path
.append(os
.path
.join("../lib/"))
90 # pylint: disable=C0413
91 # Import topogen and topotest helpers
92 from lib
.topogen
import Topogen
, get_topogen
93 from lib
.topolog
import logger
95 # Required to instantiate the topology builder class.
97 # Import topoJson from lib, to create topology and initial configuration
98 from lib
.topojson
import build_config_from_json
102 verify_graceful_restart
,
106 verify_bgp_convergence
,
107 verify_bgp_convergence_from_running_config
,
110 from lib
.common_config
import (
112 reset_config_on_routers
,
115 start_router_daemons
,
120 shutdown_bringup_interface
,
122 get_frr_ipv6_linklocal
,
123 required_linux_kernel_version
,
126 pytestmark
= [pytest
.mark
.bgpd
]
130 NEXT_HOP_IP
= {"ipv4": "192.168.1.10", "ipv6": "fd00:0:0:1::10"}
131 NEXT_HOP_IP_1
= {"ipv4": "192.168.0.1", "ipv6": "fd00::1"}
132 NEXT_HOP_IP_2
= {"ipv4": "192.168.0.2", "ipv6": "fd00::2"}
133 BGP_CONVERGENCE
= False
134 GR_RESTART_TIMER
= 20
135 PREFERRED_NEXT_HOP
= "link_local"
138 def setup_module(mod
):
140 Sets up the pytest environment
147 # Required linux kernel version for this suite to run.
148 result
= required_linux_kernel_version("4.16")
149 if result
is not True:
150 pytest
.skip("Kernel requirements are not met, kernel version should be >=4.16")
152 testsuite_run_time
= time
.asctime(time
.localtime(time
.time()))
153 logger
.info("Testsuite start time: {}".format(testsuite_run_time
))
154 logger
.info("=" * 40)
156 logger
.info("Running setup_module to create topology")
158 # This function initiates the topology build with Topogen...
159 json_file
= "{}/bgp_gr_topojson_topo1.json".format(CWD
)
160 tgen
= Topogen(json_file
, mod
.__name
__)
162 topo
= tgen
.json_topo
163 # ... and here it calls Mininet initialization functions.
165 # Starting topology, create tmp files which are loaded to routers
166 # to start daemons and then start routers
169 # Creating configuration from JSON
170 build_config_from_json(tgen
, topo
)
172 # Don't run this test if we have any failure.
173 if tgen
.routers_have_failure():
174 pytest
.skip(tgen
.errors
)
176 # Api call verify whether BGP is converged
177 ADDR_TYPES
= check_address_types()
179 BGP_CONVERGENCE
= verify_bgp_convergence(tgen
, topo
)
180 assert BGP_CONVERGENCE
is True, "setup_module : Failed \n Error:" " {}".format(
184 logger
.info("Running setup_module() done")
187 def teardown_module(mod
):
189 Teardown the pytest environment
194 logger
.info("Running teardown_module to delete topology")
198 # Stop toplogy and Remove tmp files
202 "Testsuite end time: {}".format(time
.asctime(time
.localtime(time
.time())))
204 logger
.info("=" * 40)
207 def configure_gr_followed_by_clear(tgen
, topo
, input_dict
, tc_name
, dut
, peer
):
209 This function groups the repetitive function calls into one function.
212 result
= create_router_bgp(tgen
, topo
, input_dict
)
213 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
215 for addr_type
in ADDR_TYPES
:
216 neighbor
= topo
["routers"][peer
]["links"]["r1-link1"][addr_type
].split("/")[0]
217 clear_bgp(tgen
, addr_type
, dut
, neighbor
=neighbor
)
219 for addr_type
in ADDR_TYPES
:
220 neighbor
= topo
["routers"][dut
]["links"]["r2-link1"][addr_type
].split("/")[0]
221 clear_bgp(tgen
, addr_type
, peer
, neighbor
=neighbor
)
223 result
= verify_bgp_convergence_from_running_config(tgen
)
224 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
229 def next_hop_per_address_family(
230 tgen
, dut
, peer
, addr_type
, next_hop_dict
, preferred_next_hop
=PREFERRED_NEXT_HOP
233 This function returns link_local or global next_hop per address-family
236 intferface
= topo
["routers"][peer
]["links"]["{}-link1".format(dut
)]["interface"]
237 if addr_type
== "ipv6" and "link_local" in preferred_next_hop
:
238 next_hop
= get_frr_ipv6_linklocal(tgen
, peer
, intf
=intferface
)
240 next_hop
= next_hop_dict
[addr_type
]
245 def test_BGP_GR_TC_8_p1(request
):
247 Test Objective : Verify that restarting nodes set "F" bit while sending
248 the BGP open messages after it restarts, only when BGP GR is enabled.
252 tc_name
= request
.node
.name
253 write_test_header(tc_name
)
255 # Check router status
256 check_router_status(tgen
)
258 # Don't run this test if we have any failure.
259 if tgen
.routers_have_failure():
260 pytest
.skip(tgen
.errors
)
262 # Creating configuration from JSON
263 reset_config_on_routers(tgen
)
266 "[Phase 1] : Test Setup" " [Restart Mode]R1-----R2[Restart Mode] initialized "
269 # Configure graceful-restart
273 "graceful-restart": {"preserve-fw-state": True},
280 "r1-link1": {"graceful-restart": True}
291 "r1-link1": {"graceful-restart": True}
308 "r2-link1": {"graceful-restart": True}
319 "r2-link1": {"graceful-restart": True}
330 configure_gr_followed_by_clear(tgen
, topo
, input_dict
, tc_name
, dut
="r1", peer
="r2")
332 for addr_type
in ADDR_TYPES
:
333 result
= verify_graceful_restart(
334 tgen
, topo
, addr_type
, input_dict
, dut
="r1", peer
="r2"
336 assert result
is True, "Testcase {} : Failed \n Error {}".format(
340 # Verifying BGP RIB routes
343 next_hop
= next_hop_per_address_family(
344 tgen
, dut
, peer
, addr_type
, NEXT_HOP_IP_2
346 input_topo
= {key
: topo
["routers"][key
] for key
in ["r2"]}
347 result
= verify_bgp_rib(tgen
, addr_type
, dut
, input_topo
, next_hop
)
348 assert result
is True, "Testcase {} : Failed \n Error {}".format(
352 # Verifying RIB routes
354 result
= verify_rib(tgen
, addr_type
, dut
, input_topo
, next_hop
, protocol
)
355 assert result
is True, "Testcase {} : Failed \n Error {}".format(
359 logger
.info("[Phase 2] : R1 goes for reload ")
361 kill_router_daemons(tgen
, "r1", ["bgpd"])
363 logger
.info("[Phase 3] : R1 is about to come up now ")
364 start_router_daemons(tgen
, "r1", ["bgpd"])
366 logger
.info("[Phase 4] : R2 is UP now, so time to collect GR stats ")
368 for addr_type
in ADDR_TYPES
:
369 result
= verify_graceful_restart(
370 tgen
, topo
, addr_type
, input_dict
, dut
="r1", peer
="r2"
372 assert result
is True, "Testcase {} : Failed \n Error {}".format(
376 result
= verify_r_bit(tgen
, topo
, addr_type
, input_dict
, dut
="r2", peer
="r1")
377 assert result
is True, "Testcase {} : Failed \n Error {}".format(
381 result
= verify_f_bit(tgen
, topo
, addr_type
, input_dict
, dut
="r2", peer
="r1")
382 assert result
is True, "Testcase {} : Failed \n Error {}".format(
386 write_test_footer(tc_name
)
389 if __name__
== "__main__":
390 args
= ["-s"] + sys
.argv
[1:]
391 sys
.exit(pytest
.main(args
))