]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-2.py
Merge pull request #12248 from pguibert6WIND/bgpasdot
[mirror_frr.git] / tests / topotests / bgp_gr_functionality_topo1 / test_bgp_gr_functionality_topo1-2.py
1 #!/usr/bin/env python
2 # SPDX-License-Identifier: ISC
3 #
4 # Copyright (c) 2019 by VMware, Inc. ("VMware")
5 # Used Copyright (c) 2018 by Network Device Education Foundation, Inc. ("NetDEF")
6 # in this file.
7 #
8
9 """
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
14 - Bring up topology
15 - Verify for bgp to converge
16 - Configure BGP Garceful Restart on both the routers.
17
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
35 GR restarting node.
36 11. Verify that GR helper routers delete all the routes
37 received from a node if both the routers are configured as GR
38 helper node.
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
50 Disable to Helper.
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
69 PerPeer Mode : None
70 GR Mode effective : GR Restart
71 23. Transition from Peer-level disable to Global inherit helper
72 Global Mode : None
73 PerPeer Mode : GR Disable
74 GR Mode effective : GR Disable
75
76 These tests have been broken up into 4 sub python scripts because
77 the totality of this run was fairly significant.
78 """
79
80 import os
81 import sys
82 import time
83 import pytest
84
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/"))
89
90 # pylint: disable=C0413
91 # Import topogen and topotest helpers
92 from lib.topogen import Topogen, get_topogen
93 from lib.topolog import logger
94
95 # Required to instantiate the topology builder class.
96
97 # Import topoJson from lib, to create topology and initial configuration
98 from lib.topojson import build_config_from_json
99 from lib.bgp import (
100 clear_bgp,
101 verify_bgp_rib,
102 verify_graceful_restart,
103 create_router_bgp,
104 verify_r_bit,
105 verify_f_bit,
106 verify_bgp_convergence,
107 verify_bgp_convergence_from_running_config,
108 )
109
110 from lib.common_config import (
111 write_test_header,
112 reset_config_on_routers,
113 start_topology,
114 kill_router_daemons,
115 start_router_daemons,
116 verify_rib,
117 check_address_types,
118 write_test_footer,
119 check_router_status,
120 shutdown_bringup_interface,
121 step,
122 get_frr_ipv6_linklocal,
123 required_linux_kernel_version,
124 )
125
126 pytestmark = [pytest.mark.bgpd]
127
128
129 # Global variables
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"
136
137
138 def setup_module(mod):
139 """
140 Sets up the pytest environment
141
142 * `mod`: module name
143 """
144
145 global ADDR_TYPES
146
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")
151
152 testsuite_run_time = time.asctime(time.localtime(time.time()))
153 logger.info("Testsuite start time: {}".format(testsuite_run_time))
154 logger.info("=" * 40)
155
156 logger.info("Running setup_module to create topology")
157
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__)
161 global topo
162 topo = tgen.json_topo
163 # ... and here it calls Mininet initialization functions.
164
165 # Starting topology, create tmp files which are loaded to routers
166 # to start daemons and then start routers
167 start_topology(tgen)
168
169 # Creating configuration from JSON
170 build_config_from_json(tgen, topo)
171
172 # Don't run this test if we have any failure.
173 if tgen.routers_have_failure():
174 pytest.skip(tgen.errors)
175
176 # Api call verify whether BGP is converged
177 ADDR_TYPES = check_address_types()
178
179 BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
180 assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error:" " {}".format(
181 BGP_CONVERGENCE
182 )
183
184 logger.info("Running setup_module() done")
185
186
187 def teardown_module(mod):
188 """
189 Teardown the pytest environment
190
191 * `mod`: module name
192 """
193
194 logger.info("Running teardown_module to delete topology")
195
196 tgen = get_topogen()
197
198 # Stop toplogy and Remove tmp files
199 tgen.stop_topology()
200
201 logger.info(
202 "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
203 )
204 logger.info("=" * 40)
205
206
207 def configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut, peer):
208 """
209 This function groups the repetitive function calls into one function.
210 """
211
212 result = create_router_bgp(tgen, topo, input_dict)
213 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
214
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)
218
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)
222
223 result = verify_bgp_convergence_from_running_config(tgen)
224 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
225
226 return True
227
228
229 def next_hop_per_address_family(
230 tgen, dut, peer, addr_type, next_hop_dict, preferred_next_hop=PREFERRED_NEXT_HOP
231 ):
232 """
233 This function returns link_local or global next_hop per address-family
234 """
235
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)
239 else:
240 next_hop = next_hop_dict[addr_type]
241
242 return next_hop
243
244
245 def test_BGP_GR_TC_8_p1(request):
246 """
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.
249 """
250
251 tgen = get_topogen()
252 tc_name = request.node.name
253 write_test_header(tc_name)
254
255 # Check router status
256 check_router_status(tgen)
257
258 # Don't run this test if we have any failure.
259 if tgen.routers_have_failure():
260 pytest.skip(tgen.errors)
261
262 # Creating configuration from JSON
263 reset_config_on_routers(tgen)
264
265 logger.info(
266 "[Phase 1] : Test Setup" " [Restart Mode]R1-----R2[Restart Mode] initialized "
267 )
268
269 # Configure graceful-restart
270 input_dict = {
271 "r1": {
272 "bgp": {
273 "graceful-restart": {"preserve-fw-state": True},
274 "address_family": {
275 "ipv4": {
276 "unicast": {
277 "neighbor": {
278 "r2": {
279 "dest_link": {
280 "r1-link1": {"graceful-restart": True}
281 }
282 }
283 }
284 }
285 },
286 "ipv6": {
287 "unicast": {
288 "neighbor": {
289 "r2": {
290 "dest_link": {
291 "r1-link1": {"graceful-restart": True}
292 }
293 }
294 }
295 }
296 },
297 },
298 }
299 },
300 "r2": {
301 "bgp": {
302 "address_family": {
303 "ipv4": {
304 "unicast": {
305 "neighbor": {
306 "r1": {
307 "dest_link": {
308 "r2-link1": {"graceful-restart": True}
309 }
310 }
311 }
312 }
313 },
314 "ipv6": {
315 "unicast": {
316 "neighbor": {
317 "r1": {
318 "dest_link": {
319 "r2-link1": {"graceful-restart": True}
320 }
321 }
322 }
323 }
324 },
325 }
326 }
327 },
328 }
329
330 configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
331
332 for addr_type in ADDR_TYPES:
333 result = verify_graceful_restart(
334 tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
335 )
336 assert result is True, "Testcase {} : Failed \n Error {}".format(
337 tc_name, result
338 )
339
340 # Verifying BGP RIB routes
341 dut = "r1"
342 peer = "r2"
343 next_hop = next_hop_per_address_family(
344 tgen, dut, peer, addr_type, NEXT_HOP_IP_2
345 )
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(
349 tc_name, result
350 )
351
352 # Verifying RIB routes
353 protocol = "bgp"
354 result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
355 assert result is True, "Testcase {} : Failed \n Error {}".format(
356 tc_name, result
357 )
358
359 logger.info("[Phase 2] : R1 goes for reload ")
360
361 kill_router_daemons(tgen, "r1", ["bgpd"])
362
363 logger.info("[Phase 3] : R1 is about to come up now ")
364 start_router_daemons(tgen, "r1", ["bgpd"])
365
366 logger.info("[Phase 4] : R2 is UP now, so time to collect GR stats ")
367
368 for addr_type in ADDR_TYPES:
369 result = verify_graceful_restart(
370 tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
371 )
372 assert result is True, "Testcase {} : Failed \n Error {}".format(
373 tc_name, result
374 )
375
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(
378 tc_name, result
379 )
380
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(
383 tc_name, result
384 )
385
386 write_test_footer(tc_name)
387
388
389 if __name__ == "__main__":
390 args = ["-s"] + sys.argv[1:]
391 sys.exit(pytest.main(args))