]>
Commit | Line | Data |
---|---|---|
b0449478 | 1 | #!/usr/bin/env python |
acddc0ed | 2 | # SPDX-License-Identifier: ISC |
b0449478 DS |
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 | # | |
b0449478 DS |
8 | |
9 | """ | |
17be83bf | 10 | Following tests are covered to test BGP Graceful Restart functionality. |
b0449478 DS |
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 | |
d94ee272 | 71 | 23. Transition from Peer-level disable to Global inherit helper |
b0449478 DS |
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: | |
d63c7094 | 150 | pytest.skip("Kernel requirements are not met, kernel version should be >=4.16") |
b0449478 DS |
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 | |
d60a3f0e | 166 | # to start daemons and then start routers |
b0449478 DS |
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 BGP_GR_TC_50_p1(request): | |
246 | """ | |
247 | Test Objective : Transition from Peer-level helper to Global inherit helper | |
248 | Global Mode : None | |
249 | PerPeer Mode : Helper | |
250 | GR Mode effective : GR Helper | |
251 | ||
252 | """ | |
253 | ||
254 | tgen = get_topogen() | |
255 | tc_name = request.node.name | |
256 | write_test_header(tc_name) | |
257 | ||
258 | # Check router status | |
259 | check_router_status(tgen) | |
260 | ||
261 | # Don't run this test if we have any failure. | |
262 | if tgen.routers_have_failure(): | |
263 | pytest.skip(tgen.errors) | |
264 | ||
265 | # Creating configuration from JSON | |
266 | reset_config_on_routers(tgen) | |
267 | ||
268 | step( | |
269 | "Configure R1 as GR helper node at per Peer-level for R2" | |
270 | " and configure R2 as global restarting node." | |
271 | ) | |
272 | ||
273 | input_dict = { | |
274 | "r1": { | |
275 | "bgp": { | |
276 | "address_family": { | |
277 | "ipv4": { | |
278 | "unicast": { | |
279 | "neighbor": { | |
280 | "r2": { | |
281 | "dest_link": { | |
282 | "r1-link1": {"graceful-restart-helper": True} | |
283 | } | |
284 | } | |
285 | } | |
286 | } | |
287 | }, | |
288 | "ipv6": { | |
289 | "unicast": { | |
290 | "neighbor": { | |
291 | "r2": { | |
292 | "dest_link": { | |
293 | "r1-link1": {"graceful-restart-helper": True} | |
294 | } | |
295 | } | |
296 | } | |
297 | } | |
298 | }, | |
299 | } | |
300 | } | |
301 | }, | |
302 | "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}}, | |
303 | } | |
304 | ||
305 | configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2") | |
306 | ||
307 | step("Verify on R2 that R1 advertises GR capabilities as a helper node") | |
308 | ||
309 | for addr_type in ADDR_TYPES: | |
310 | result = verify_graceful_restart( | |
311 | tgen, topo, addr_type, input_dict, dut="r1", peer="r2" | |
312 | ) | |
313 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
314 | tc_name, result | |
315 | ) | |
316 | ||
317 | for addr_type in ADDR_TYPES: | |
318 | protocol = "bgp" | |
319 | next_hop = next_hop_per_address_family( | |
320 | tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1 | |
321 | ) | |
322 | input_topo = {"r1": topo["routers"]["r1"]} | |
323 | result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol) | |
324 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
325 | tc_name, result | |
326 | ) | |
327 | ||
328 | for addr_type in ADDR_TYPES: | |
329 | next_hop = next_hop_per_address_family( | |
330 | tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2 | |
331 | ) | |
332 | input_topo = {"r2": topo["routers"]["r2"]} | |
333 | result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop) | |
334 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
335 | tc_name, result | |
336 | ) | |
337 | ||
338 | result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol) | |
339 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
340 | tc_name, result | |
341 | ) | |
342 | ||
343 | step("Kill BGP on R2") | |
344 | ||
345 | kill_router_daemons(tgen, "r2", ["bgpd"]) | |
346 | ||
347 | step( | |
348 | "Verify that R2 keeps the stale entries in FIB & R1 keeps stale entries in RIB & FIB" | |
349 | ) | |
350 | ||
351 | for addr_type in ADDR_TYPES: | |
352 | protocol = "bgp" | |
353 | next_hop = next_hop_per_address_family( | |
354 | tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1 | |
355 | ) | |
356 | input_topo = {"r1": topo["routers"]["r1"]} | |
357 | result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol) | |
358 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
359 | tc_name, result | |
360 | ) | |
361 | ||
362 | for addr_type in ADDR_TYPES: | |
363 | next_hop = next_hop_per_address_family( | |
364 | tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2 | |
365 | ) | |
366 | input_topo = {"r2": topo["routers"]["r2"]} | |
367 | result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop) | |
368 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
369 | tc_name, result | |
370 | ) | |
371 | ||
372 | result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol) | |
373 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
374 | tc_name, result | |
375 | ) | |
376 | ||
377 | step("Bring up BGP on R2 and remove Peer-level GR config from R1 ") | |
378 | ||
379 | start_router_daemons(tgen, "r2", ["bgpd"]) | |
380 | ||
381 | input_dict = { | |
382 | "r1": { | |
383 | "bgp": { | |
384 | "address_family": { | |
385 | "ipv4": { | |
386 | "unicast": { | |
387 | "neighbor": { | |
388 | "r2": { | |
389 | "dest_link": { | |
390 | "r1-link1": {"graceful-restart-helper": False} | |
391 | } | |
392 | } | |
393 | } | |
394 | } | |
395 | }, | |
396 | "ipv6": { | |
397 | "unicast": { | |
398 | "neighbor": { | |
399 | "r2": { | |
400 | "dest_link": { | |
401 | "r1-link1": {"graceful-restart-helper": False} | |
402 | } | |
403 | } | |
404 | } | |
405 | } | |
406 | }, | |
407 | } | |
408 | } | |
409 | } | |
410 | } | |
411 | ||
412 | result = create_router_bgp(tgen, topo, input_dict) | |
413 | assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) | |
414 | ||
415 | for addr_type in ADDR_TYPES: | |
416 | neighbor = topo["routers"]["r2"]["links"]["r1-link1"][addr_type].split("/")[0] | |
417 | clear_bgp(tgen, addr_type, "r1", neighbor=neighbor) | |
418 | ||
419 | result = verify_bgp_convergence_from_running_config(tgen) | |
420 | assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) | |
421 | ||
422 | step("Verify on R2 that R1 still advertises GR capabilities as a helper node") | |
423 | ||
424 | input_dict = { | |
425 | "r1": {"bgp": {"graceful-restart": {"graceful-restart-helper": True}}}, | |
426 | "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}}, | |
427 | } | |
428 | ||
429 | for addr_type in ADDR_TYPES: | |
430 | result = verify_graceful_restart( | |
431 | tgen, topo, addr_type, input_dict, dut="r1", peer="r2" | |
432 | ) | |
433 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
434 | tc_name, result | |
435 | ) | |
436 | ||
437 | for addr_type in ADDR_TYPES: | |
438 | protocol = "bgp" | |
439 | next_hop = next_hop_per_address_family( | |
440 | tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1 | |
441 | ) | |
442 | input_topo = {"r1": topo["routers"]["r1"]} | |
443 | result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol) | |
444 | assert ( | |
445 | result is True | |
446 | ), "Testcase {} : Failed \n Routes are still present \n Error {}".format( | |
447 | tc_name, result | |
448 | ) | |
449 | ||
450 | for addr_type in ADDR_TYPES: | |
451 | next_hop = next_hop_per_address_family( | |
452 | tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2 | |
453 | ) | |
454 | input_topo = {"r2": topo["routers"]["r2"]} | |
455 | result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop) | |
456 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
457 | tc_name, result | |
458 | ) | |
459 | ||
460 | result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol) | |
461 | assert ( | |
462 | result is True | |
463 | ), "Testcase {} : Failed \n Routes are still present \n Error {}".format( | |
464 | tc_name, result | |
465 | ) | |
466 | ||
467 | step("Kill BGP on R2") | |
468 | ||
469 | kill_router_daemons(tgen, "r2", ["bgpd"]) | |
470 | ||
471 | step( | |
472 | "Verify that R2 keeps the stale entries in FIB & R1 keeps stale entries in RIB & FIB" | |
473 | ) | |
474 | ||
475 | for addr_type in ADDR_TYPES: | |
476 | protocol = "bgp" | |
477 | next_hop = next_hop_per_address_family( | |
478 | tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1 | |
479 | ) | |
480 | input_topo = {"r1": topo["routers"]["r1"]} | |
481 | result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol) | |
482 | assert ( | |
483 | result is True | |
484 | ), "Testcase {} : Failed \n Routes are still present \n Error {}".format( | |
485 | tc_name, result | |
486 | ) | |
487 | ||
488 | for addr_type in ADDR_TYPES: | |
489 | next_hop = next_hop_per_address_family( | |
490 | tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2 | |
491 | ) | |
492 | input_topo = {"r2": topo["routers"]["r2"]} | |
493 | result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop) | |
494 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
495 | tc_name, result | |
496 | ) | |
497 | ||
498 | result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol) | |
499 | assert ( | |
500 | result is True | |
501 | ), "Testcase {} : Failed \n Routes are still present \n Error {}".format( | |
502 | tc_name, result | |
503 | ) | |
504 | ||
505 | step("Start BGP on R2") | |
506 | ||
507 | start_router_daemons(tgen, "r2", ["bgpd"]) | |
508 | ||
509 | write_test_footer(tc_name) | |
510 | ||
511 | ||
512 | def test_BGP_GR_TC_51_p1(request): | |
513 | """ | |
514 | Test Objective : Transition from Peer-level restarting to Global inherit helper | |
515 | Global Mode : None | |
516 | PerPeer Mode : GR Restart | |
517 | GR Mode effective : GR Restart | |
518 | ||
519 | """ | |
520 | ||
521 | tgen = get_topogen() | |
522 | tc_name = request.node.name | |
523 | write_test_header(tc_name) | |
524 | ||
525 | # Check router status | |
526 | check_router_status(tgen) | |
527 | ||
528 | # Don't run this test if we have any failure. | |
529 | if tgen.routers_have_failure(): | |
530 | pytest.skip(tgen.errors) | |
531 | ||
532 | # Creating configuration from JSON | |
533 | reset_config_on_routers(tgen) | |
534 | ||
535 | step("Configure R1 as GR restarting node at per Peer-level for R2") | |
536 | ||
537 | input_dict = { | |
538 | "r1": { | |
539 | "bgp": { | |
540 | "address_family": { | |
541 | "ipv4": { | |
542 | "unicast": { | |
543 | "neighbor": { | |
544 | "r2": { | |
545 | "dest_link": { | |
546 | "r1-link1": {"graceful-restart": True} | |
547 | } | |
548 | } | |
549 | } | |
550 | } | |
551 | }, | |
552 | "ipv6": { | |
553 | "unicast": { | |
554 | "neighbor": { | |
555 | "r2": { | |
556 | "dest_link": { | |
557 | "r1-link1": {"graceful-restart": True} | |
558 | } | |
559 | } | |
560 | } | |
561 | } | |
562 | }, | |
563 | } | |
564 | } | |
565 | }, | |
566 | "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}}, | |
567 | } | |
568 | ||
569 | configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2") | |
570 | step("Verify on R2 that R1 advertises GR capabilities as a restarting node") | |
571 | ||
572 | for addr_type in ADDR_TYPES: | |
573 | result = verify_graceful_restart( | |
574 | tgen, topo, addr_type, input_dict, dut="r1", peer="r2" | |
575 | ) | |
576 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
577 | tc_name, result | |
578 | ) | |
579 | ||
580 | for addr_type in ADDR_TYPES: | |
581 | protocol = "bgp" | |
582 | next_hop = next_hop_per_address_family( | |
583 | tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2 | |
584 | ) | |
585 | input_topo = {"r2": topo["routers"]["r2"]} | |
586 | result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol) | |
587 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
588 | tc_name, result | |
589 | ) | |
590 | ||
591 | for addr_type in ADDR_TYPES: | |
592 | next_hop = next_hop_per_address_family( | |
593 | tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1 | |
594 | ) | |
595 | input_topo = {"r1": topo["routers"]["r1"]} | |
596 | result = verify_bgp_rib(tgen, addr_type, "r2", input_topo, next_hop) | |
597 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
598 | tc_name, result | |
599 | ) | |
600 | ||
601 | result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol) | |
602 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
603 | tc_name, result | |
604 | ) | |
605 | ||
606 | step("Kill BGP on R1") | |
607 | ||
608 | kill_router_daemons(tgen, "r1", ["bgpd"]) | |
609 | ||
610 | step( | |
611 | "Verify that R1 keeps the stale entries in FIB & R2 keeps stale entries in RIB & FIB" | |
612 | ) | |
613 | ||
614 | for addr_type in ADDR_TYPES: | |
615 | protocol = "bgp" | |
616 | next_hop = next_hop_per_address_family( | |
617 | tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2 | |
618 | ) | |
619 | input_topo = {"r2": topo["routers"]["r2"]} | |
620 | result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol) | |
621 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
622 | tc_name, result | |
623 | ) | |
624 | ||
625 | for addr_type in ADDR_TYPES: | |
626 | next_hop = next_hop_per_address_family( | |
627 | tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1 | |
628 | ) | |
629 | input_topo = {"r1": topo["routers"]["r1"]} | |
630 | result = verify_bgp_rib(tgen, addr_type, "r2", input_topo, next_hop) | |
631 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
632 | tc_name, result | |
633 | ) | |
634 | ||
635 | result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol) | |
636 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
637 | tc_name, result | |
638 | ) | |
639 | ||
640 | step("Bring up BGP on R1 and remove Peer-level GR config") | |
641 | ||
642 | start_router_daemons(tgen, "r1", ["bgpd"]) | |
643 | ||
644 | input_dict = { | |
645 | "r1": { | |
646 | "bgp": { | |
647 | "address_family": { | |
648 | "ipv4": { | |
649 | "unicast": { | |
650 | "neighbor": { | |
651 | "r2": { | |
652 | "dest_link": { | |
653 | "r1-link1": {"graceful-restart": False} | |
654 | } | |
655 | } | |
656 | } | |
657 | } | |
658 | }, | |
659 | "ipv6": { | |
660 | "unicast": { | |
661 | "neighbor": { | |
662 | "r2": { | |
663 | "dest_link": { | |
664 | "r1-link1": {"graceful-restart": False} | |
665 | } | |
666 | } | |
667 | } | |
668 | } | |
669 | }, | |
670 | } | |
671 | } | |
672 | } | |
673 | } | |
674 | ||
675 | result = create_router_bgp(tgen, topo, input_dict) | |
676 | assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) | |
677 | ||
678 | for addr_type in ADDR_TYPES: | |
679 | neighbor = topo["routers"]["r2"]["links"]["r1-link1"][addr_type].split("/")[0] | |
680 | clear_bgp(tgen, addr_type, "r1", neighbor=neighbor) | |
681 | ||
682 | result = verify_bgp_convergence_from_running_config(tgen) | |
683 | assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) | |
684 | ||
685 | step("Verify on R2 that R1 advertises GR capabilities as a helper node") | |
686 | ||
687 | input_dict = { | |
688 | "r1": {"bgp": {"graceful-restart": {"graceful-restart-helper": True}}}, | |
689 | "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}}, | |
690 | } | |
691 | ||
692 | for addr_type in ADDR_TYPES: | |
693 | result = verify_graceful_restart( | |
694 | tgen, topo, addr_type, input_dict, dut="r1", peer="r2" | |
695 | ) | |
696 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
697 | tc_name, result | |
698 | ) | |
699 | ||
700 | for addr_type in ADDR_TYPES: | |
701 | protocol = "bgp" | |
702 | next_hop = next_hop_per_address_family( | |
703 | tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1 | |
704 | ) | |
705 | input_topo = {"r1": topo["routers"]["r1"]} | |
706 | result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol) | |
707 | assert ( | |
708 | result is True | |
709 | ), "Testcase {} : Failed \n Routes are still present \n Error {}".format( | |
710 | tc_name, result | |
711 | ) | |
712 | ||
713 | for addr_type in ADDR_TYPES: | |
714 | next_hop = next_hop_per_address_family( | |
715 | tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2 | |
716 | ) | |
717 | input_topo = {"r2": topo["routers"]["r2"]} | |
718 | result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop) | |
719 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
720 | tc_name, result | |
721 | ) | |
722 | ||
723 | result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol) | |
724 | assert ( | |
725 | result is True | |
726 | ), "Testcase {} : Failed \n Routes are still present \n Error {}".format( | |
727 | tc_name, result | |
728 | ) | |
729 | ||
730 | step("Kill BGPd on R2") | |
731 | ||
732 | kill_router_daemons(tgen, "r2", ["bgpd"]) | |
733 | ||
734 | step( | |
735 | "Verify that R2 keeps the stale entries in FIB & R1 keeps stale entries in RIB & FIB" | |
736 | ) | |
737 | ||
738 | for addr_type in ADDR_TYPES: | |
739 | protocol = "bgp" | |
740 | next_hop = next_hop_per_address_family( | |
741 | tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1 | |
742 | ) | |
743 | input_topo = {"r1": topo["routers"]["r1"]} | |
744 | result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol) | |
745 | assert ( | |
746 | result is True | |
747 | ), "Testcase {} : Failed \n Routes are still present \n Error {}".format( | |
748 | tc_name, result | |
749 | ) | |
750 | ||
751 | for addr_type in ADDR_TYPES: | |
752 | next_hop = next_hop_per_address_family( | |
753 | tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2 | |
754 | ) | |
755 | input_topo = {"r2": topo["routers"]["r2"]} | |
756 | result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop) | |
757 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
758 | tc_name, result | |
759 | ) | |
760 | ||
761 | result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol) | |
762 | assert ( | |
763 | result is True | |
764 | ), "Testcase {} : Failed \n Routes are still present \n Error {}".format( | |
765 | tc_name, result | |
766 | ) | |
767 | ||
768 | step("Start BGP on R2") | |
769 | ||
770 | start_router_daemons(tgen, "r2", ["bgpd"]) | |
771 | ||
772 | write_test_footer(tc_name) | |
773 | ||
774 | ||
775 | def test_BGP_GR_TC_53_p1(request): | |
776 | """ | |
777 | Test Objective : Default GR functional mode is Helper. | |
778 | Global Mode : None | |
779 | PerPeer Mode : None | |
780 | GR Mode effective : GR Helper | |
781 | ||
782 | """ | |
783 | ||
784 | tgen = get_topogen() | |
785 | tc_name = request.node.name | |
786 | write_test_header(tc_name) | |
787 | ||
788 | # Check router status | |
789 | check_router_status(tgen) | |
790 | ||
791 | # Don't run this test if we have any failure. | |
792 | if tgen.routers_have_failure(): | |
793 | pytest.skip(tgen.errors) | |
794 | ||
795 | # Creating configuration from JSON | |
796 | reset_config_on_routers(tgen) | |
797 | ||
798 | step("configure R2 as global restarting node") | |
799 | ||
800 | input_dict = {"r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}}} | |
801 | ||
802 | configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2") | |
803 | ||
804 | step( | |
805 | "Verify on R2 that R1 advertises GR capabilities as a helper node based on inherit" | |
806 | ) | |
807 | ||
808 | input_dict = { | |
809 | "r1": {"bgp": {"graceful-restart": {"graceful-restart-helper": True}}}, | |
810 | "r2": {"bgp": {"graceful-restart": {"graceful-restart": True}}}, | |
811 | } | |
812 | ||
813 | for addr_type in ADDR_TYPES: | |
814 | result = verify_graceful_restart( | |
815 | tgen, topo, addr_type, input_dict, dut="r1", peer="r2" | |
816 | ) | |
817 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
818 | tc_name, result | |
819 | ) | |
820 | ||
821 | for addr_type in ADDR_TYPES: | |
822 | protocol = "bgp" | |
823 | next_hop = next_hop_per_address_family( | |
824 | tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1 | |
825 | ) | |
826 | input_topo = {"r1": topo["routers"]["r1"]} | |
827 | result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol) | |
828 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
829 | tc_name, result | |
830 | ) | |
831 | ||
832 | for addr_type in ADDR_TYPES: | |
833 | next_hop = next_hop_per_address_family( | |
834 | tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2 | |
835 | ) | |
836 | input_topo = {"r2": topo["routers"]["r2"]} | |
837 | result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop) | |
838 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
839 | tc_name, result | |
840 | ) | |
841 | ||
842 | result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol) | |
843 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
844 | tc_name, result | |
845 | ) | |
846 | ||
847 | step("Kill BGPd on R2") | |
848 | ||
849 | kill_router_daemons(tgen, "r2", ["bgpd"]) | |
850 | ||
851 | step( | |
852 | "Verify that R2 keeps the stale entries in FIB & R1 keeps stale entries in RIB & FIB" | |
853 | ) | |
854 | ||
855 | for addr_type in ADDR_TYPES: | |
856 | protocol = "bgp" | |
857 | next_hop = next_hop_per_address_family( | |
858 | tgen, "r2", "r1", addr_type, NEXT_HOP_IP_1 | |
859 | ) | |
860 | input_topo = {"r1": topo["routers"]["r1"]} | |
861 | result = verify_rib(tgen, addr_type, "r2", input_topo, next_hop, protocol) | |
862 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
863 | tc_name, result | |
864 | ) | |
865 | ||
866 | for addr_type in ADDR_TYPES: | |
867 | next_hop = next_hop_per_address_family( | |
868 | tgen, "r1", "r2", addr_type, NEXT_HOP_IP_2 | |
869 | ) | |
870 | input_topo = {"r2": topo["routers"]["r2"]} | |
871 | result = verify_bgp_rib(tgen, addr_type, "r1", input_topo, next_hop) | |
872 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
873 | tc_name, result | |
874 | ) | |
875 | ||
876 | result = verify_rib(tgen, addr_type, "r1", input_topo, next_hop, protocol) | |
877 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
878 | tc_name, result | |
879 | ) | |
880 | ||
881 | step("Start BGP on R2") | |
882 | ||
883 | start_router_daemons(tgen, "r2", ["bgpd"]) | |
884 | ||
885 | write_test_footer(tc_name) | |
886 | ||
887 | ||
888 | def test_BGP_GR_TC_4_p0(request): | |
889 | """ | |
890 | Test Objective : Verify that the restarting node sets "R" bit while sending the | |
891 | BGP open messages after the node restart, only if GR is enabled. | |
892 | """ | |
893 | ||
894 | tgen = get_topogen() | |
895 | tc_name = request.node.name | |
896 | write_test_header(tc_name) | |
897 | ||
898 | # Check router status | |
899 | check_router_status(tgen) | |
900 | ||
901 | # Don't run this test if we have any failure. | |
902 | if tgen.routers_have_failure(): | |
903 | pytest.skip(tgen.errors) | |
904 | ||
905 | # Creating configuration from JSON | |
906 | reset_config_on_routers(tgen) | |
907 | ||
908 | logger.info( | |
909 | "[Phase 1] : Test Setup" " [Restart Mode]R1-----R2[Helper Mode] initialized " | |
910 | ) | |
911 | ||
912 | # Configure graceful-restart | |
913 | input_dict = { | |
914 | "r1": { | |
915 | "bgp": { | |
916 | "address_family": { | |
917 | "ipv4": { | |
918 | "unicast": { | |
919 | "neighbor": { | |
920 | "r2": { | |
921 | "dest_link": { | |
922 | "r1-link1": {"graceful-restart": True} | |
923 | } | |
924 | } | |
925 | } | |
926 | } | |
927 | }, | |
928 | "ipv6": { | |
929 | "unicast": { | |
930 | "neighbor": { | |
931 | "r2": { | |
932 | "dest_link": { | |
933 | "r1-link1": {"graceful-restart": True} | |
934 | } | |
935 | } | |
936 | } | |
937 | } | |
938 | }, | |
939 | } | |
940 | } | |
941 | }, | |
942 | "r2": { | |
943 | "bgp": { | |
944 | "address_family": { | |
945 | "ipv4": { | |
946 | "unicast": { | |
947 | "neighbor": { | |
948 | "r1": { | |
949 | "dest_link": { | |
950 | "r2-link1": {"graceful-restart-helper": True} | |
951 | } | |
952 | } | |
953 | } | |
954 | } | |
955 | }, | |
956 | "ipv6": { | |
957 | "unicast": { | |
958 | "neighbor": { | |
959 | "r1": { | |
960 | "dest_link": { | |
961 | "r2-link1": {"graceful-restart-helper": True} | |
962 | } | |
963 | } | |
964 | } | |
965 | } | |
966 | }, | |
967 | } | |
968 | } | |
969 | }, | |
970 | } | |
971 | ||
972 | configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2") | |
973 | ||
974 | for addr_type in ADDR_TYPES: | |
975 | result = verify_graceful_restart( | |
976 | tgen, topo, addr_type, input_dict, dut="r1", peer="r2" | |
977 | ) | |
978 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
979 | tc_name, result | |
980 | ) | |
981 | ||
982 | # Verifying BGP RIB routes | |
983 | dut = "r1" | |
984 | peer = "r2" | |
985 | next_hop = next_hop_per_address_family( | |
986 | tgen, dut, peer, addr_type, NEXT_HOP_IP_2 | |
987 | ) | |
988 | input_topo = {key: topo["routers"][key] for key in ["r2"]} | |
989 | result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop) | |
990 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
991 | tc_name, result | |
992 | ) | |
993 | ||
994 | # Verifying RIB routes | |
995 | protocol = "bgp" | |
996 | result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol) | |
997 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
998 | tc_name, result | |
999 | ) | |
1000 | ||
1001 | logger.info("[Phase 2] : R2 goes for reload ") | |
1002 | ||
1003 | kill_router_daemons(tgen, "r2", ["bgpd"]) | |
1004 | ||
1005 | logger.info( | |
1006 | "[Phase 3] : R2 is still down, restart time {} sec." | |
1007 | "So time verify the routes are present in BGP RIB and ZEBRA ".format( | |
1008 | GR_RESTART_TIMER | |
1009 | ) | |
1010 | ) | |
1011 | ||
1012 | for addr_type in ADDR_TYPES: | |
1013 | # Verifying BGP RIB routes | |
1014 | next_hop = next_hop_per_address_family( | |
1015 | tgen, dut, peer, addr_type, NEXT_HOP_IP_2 | |
1016 | ) | |
1017 | input_topo = {key: topo["routers"][key] for key in ["r2"]} | |
1018 | result = verify_bgp_rib( | |
1019 | tgen, addr_type, dut, input_topo, next_hop, expected=False | |
1020 | ) | |
1021 | assert result is not True, ( | |
1022 | "Testcase {} : Failed \n " | |
d63c7094 KK |
1023 | "Expected: Routes should not be present in {} BGP RIB \n " |
1024 | "Found: {}".format(tc_name, dut, result) | |
b0449478 | 1025 | ) |
b0449478 DS |
1026 | |
1027 | # Verifying RIB routes | |
1028 | result = verify_rib( | |
1029 | tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False | |
1030 | ) | |
1031 | assert result is not True, ( | |
1032 | "Testcase {} : Failed \n " | |
d63c7094 KK |
1033 | "Expected: Routes should not be present in {} FIB \n " |
1034 | "Found: {}".format(tc_name, dut, result) | |
b0449478 | 1035 | ) |
b0449478 DS |
1036 | |
1037 | logger.info("[Phase 5] : R2 is about to come up now ") | |
1038 | start_router_daemons(tgen, "r2", ["bgpd"]) | |
1039 | ||
1040 | logger.info("[Phase 4] : R2 is UP now, so time to collect GR stats ") | |
1041 | ||
1042 | for addr_type in ADDR_TYPES: | |
1043 | result = verify_graceful_restart( | |
1044 | tgen, topo, addr_type, input_dict, dut="r1", peer="r2" | |
1045 | ) | |
1046 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
1047 | tc_name, result | |
1048 | ) | |
1049 | ||
1050 | result = verify_r_bit(tgen, topo, addr_type, input_dict, dut="r1", peer="r2") | |
1051 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
1052 | tc_name, result | |
1053 | ) | |
1054 | ||
1055 | # Verifying BGP RIB routes | |
1056 | next_hop = next_hop_per_address_family( | |
1057 | tgen, dut, peer, addr_type, NEXT_HOP_IP_2 | |
1058 | ) | |
1059 | input_topo = {key: topo["routers"][key] for key in ["r2"]} | |
1060 | result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop) | |
1061 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
1062 | tc_name, result | |
1063 | ) | |
1064 | ||
1065 | # Verifying RIB routes | |
1066 | result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol) | |
1067 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
1068 | tc_name, result | |
1069 | ) | |
1070 | ||
1071 | write_test_footer(tc_name) | |
1072 | ||
1073 | ||
1074 | def test_BGP_GR_TC_5_1_2_p1(request): | |
1075 | """ | |
1076 | Test Objective : Verify if restarting node resets R bit in BGP open message | |
1077 | during normal BGP session flaps as well, even when GR restarting mode is enabled. | |
1078 | Here link flap happen due to interface UP/DOWN. | |
1079 | ||
1080 | """ | |
1081 | tgen = get_topogen() | |
1082 | tc_name = request.node.name | |
1083 | write_test_header(tc_name) | |
1084 | ||
1085 | # Check router status | |
1086 | check_router_status(tgen) | |
1087 | ||
1088 | # Don't run this test if we have any failure. | |
1089 | if tgen.routers_have_failure(): | |
1090 | pytest.skip(tgen.errors) | |
1091 | ||
1092 | # Creating configuration from JSON | |
1093 | reset_config_on_routers(tgen) | |
1094 | ||
1095 | logger.info( | |
1096 | "[Phase 1] : Test Setup" " [Restart Mode]R1-----R2[Restart Mode] initialized " | |
1097 | ) | |
1098 | ||
1099 | # Configure graceful-restart | |
1100 | input_dict = { | |
1101 | "r1": { | |
1102 | "bgp": { | |
1103 | "address_family": { | |
1104 | "ipv4": { | |
1105 | "unicast": { | |
1106 | "neighbor": { | |
1107 | "r2": { | |
1108 | "dest_link": { | |
1109 | "r1-link1": {"graceful-restart": True} | |
1110 | } | |
1111 | } | |
1112 | } | |
1113 | } | |
1114 | }, | |
1115 | "ipv6": { | |
1116 | "unicast": { | |
1117 | "neighbor": { | |
1118 | "r2": { | |
1119 | "dest_link": { | |
1120 | "r1-link1": {"graceful-restart": True} | |
1121 | } | |
1122 | } | |
1123 | } | |
1124 | } | |
1125 | }, | |
1126 | } | |
1127 | } | |
1128 | }, | |
1129 | "r2": { | |
1130 | "bgp": { | |
1131 | "address_family": { | |
1132 | "ipv4": { | |
1133 | "unicast": { | |
1134 | "neighbor": { | |
1135 | "r1": { | |
1136 | "dest_link": { | |
1137 | "r2-link1": {"graceful-restart": True} | |
1138 | } | |
1139 | } | |
1140 | } | |
1141 | } | |
1142 | }, | |
1143 | "ipv6": { | |
1144 | "unicast": { | |
1145 | "neighbor": { | |
1146 | "r1": { | |
1147 | "dest_link": { | |
1148 | "r2-link1": {"graceful-restart": True} | |
1149 | } | |
1150 | } | |
1151 | } | |
1152 | } | |
1153 | }, | |
1154 | } | |
1155 | } | |
1156 | }, | |
1157 | } | |
1158 | ||
1159 | configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2") | |
1160 | ||
1161 | for addr_type in ADDR_TYPES: | |
1162 | result = verify_graceful_restart( | |
1163 | tgen, topo, addr_type, input_dict, dut="r1", peer="r2" | |
1164 | ) | |
1165 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
1166 | tc_name, result | |
1167 | ) | |
1168 | ||
1169 | # Verifying BGP RIB routes | |
1170 | dut = "r1" | |
1171 | peer = "r2" | |
1172 | next_hop = next_hop_per_address_family( | |
1173 | tgen, dut, peer, addr_type, NEXT_HOP_IP_2 | |
1174 | ) | |
1175 | input_topo = {key: topo["routers"][key] for key in ["r2"]} | |
1176 | result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop) | |
1177 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
1178 | tc_name, result | |
1179 | ) | |
1180 | ||
1181 | # Verifying RIB routes | |
1182 | protocol = "bgp" | |
1183 | result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol) | |
1184 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
1185 | tc_name, result | |
1186 | ) | |
1187 | ||
1188 | logger.info("[Phase 2] : Now flap the link running the BGP session ") | |
1189 | # Shutdown interface | |
1190 | intf = "r2-r1-eth0" | |
1191 | shutdown_bringup_interface(tgen, "r2", intf) | |
1192 | ||
1193 | # Bring up Interface | |
1194 | shutdown_bringup_interface(tgen, "r2", intf, ifaceaction=True) | |
1195 | ||
1196 | for addr_type in ADDR_TYPES: | |
1197 | result = verify_graceful_restart( | |
1198 | tgen, topo, addr_type, input_dict, dut="r1", peer="r2" | |
1199 | ) | |
1200 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
1201 | tc_name, result | |
1202 | ) | |
1203 | ||
1204 | result = verify_r_bit(tgen, topo, addr_type, input_dict, dut="r1", peer="r2") | |
1205 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
1206 | tc_name, result | |
1207 | ) | |
1208 | ||
1209 | logger.info("[Phase 2] : Restart BGPd on router R2. ") | |
1210 | kill_router_daemons(tgen, "r2", ["bgpd"]) | |
1211 | ||
1212 | start_router_daemons(tgen, "r2", ["bgpd"]) | |
1213 | ||
1214 | logger.info("[Phase 4] : R2 is UP now, so time to collect GR stats ") | |
1215 | ||
1216 | for addr_type in ADDR_TYPES: | |
1217 | result = verify_graceful_restart( | |
1218 | tgen, topo, addr_type, input_dict, dut="r1", peer="r2" | |
1219 | ) | |
1220 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
1221 | tc_name, result | |
1222 | ) | |
1223 | ||
1224 | result = verify_r_bit(tgen, topo, addr_type, input_dict, dut="r1", peer="r2") | |
1225 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
1226 | tc_name, result | |
1227 | ) | |
1228 | ||
1229 | # Verifying BGP RIB routes | |
1230 | next_hop = next_hop_per_address_family( | |
1231 | tgen, dut, peer, addr_type, NEXT_HOP_IP_2 | |
1232 | ) | |
1233 | input_topo = {key: topo["routers"][key] for key in ["r2"]} | |
1234 | result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop) | |
1235 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
1236 | tc_name, result | |
1237 | ) | |
1238 | ||
1239 | # Verifying RIB routes | |
1240 | result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol) | |
1241 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
1242 | tc_name, result | |
1243 | ) | |
1244 | ||
1245 | write_test_footer(tc_name) | |
1246 | ||
1247 | ||
1248 | def test_BGP_GR_TC_6_1_2_p1(request): | |
1249 | """ | |
1250 | Test Objective : Verify if restarting node resets R bit in BGP | |
1251 | open message during normal BGP session flaps when GR is disabled. | |
1252 | """ | |
1253 | ||
1254 | tgen = get_topogen() | |
1255 | tc_name = request.node.name | |
1256 | write_test_header(tc_name) | |
1257 | ||
1258 | # Check router status | |
1259 | check_router_status(tgen) | |
1260 | ||
1261 | # Don't run this test if we have any failure. | |
1262 | if tgen.routers_have_failure(): | |
1263 | pytest.skip(tgen.errors) | |
1264 | ||
1265 | # Creating configuration from JSON | |
1266 | reset_config_on_routers(tgen) | |
1267 | ||
1268 | logger.info( | |
1269 | "[Phase 1] : Test Setup" "[Restart Mode]R1-----R2[Helper Mode] initialized " | |
1270 | ) | |
1271 | ||
1272 | # Configure graceful-restart | |
1273 | input_dict = { | |
1274 | "r1": { | |
1275 | "bgp": { | |
1276 | "address_family": { | |
1277 | "ipv4": { | |
1278 | "unicast": { | |
1279 | "neighbor": { | |
1280 | "r2": { | |
1281 | "dest_link": { | |
1282 | "r1-link1": {"graceful-restart": True} | |
1283 | } | |
1284 | } | |
1285 | } | |
1286 | } | |
1287 | }, | |
1288 | "ipv6": { | |
1289 | "unicast": { | |
1290 | "neighbor": { | |
1291 | "r2": { | |
1292 | "dest_link": { | |
1293 | "r1-link1": {"graceful-restart": True} | |
1294 | } | |
1295 | } | |
1296 | } | |
1297 | } | |
1298 | }, | |
1299 | } | |
1300 | } | |
1301 | }, | |
1302 | "r2": { | |
1303 | "bgp": { | |
1304 | "address_family": { | |
1305 | "ipv4": { | |
1306 | "unicast": { | |
1307 | "neighbor": { | |
1308 | "r1": { | |
1309 | "dest_link": { | |
1310 | "r2-link1": {"graceful-restart-helper": True} | |
1311 | } | |
1312 | } | |
1313 | } | |
1314 | } | |
1315 | }, | |
1316 | "ipv6": { | |
1317 | "unicast": { | |
1318 | "neighbor": { | |
1319 | "r1": { | |
1320 | "dest_link": { | |
1321 | "r2-link1": {"graceful-restart-helper": True} | |
1322 | } | |
1323 | } | |
1324 | } | |
1325 | } | |
1326 | }, | |
1327 | } | |
1328 | } | |
1329 | }, | |
1330 | } | |
1331 | ||
1332 | configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2") | |
1333 | ||
1334 | for addr_type in ADDR_TYPES: | |
1335 | result = verify_graceful_restart( | |
1336 | tgen, topo, addr_type, input_dict, dut="r1", peer="r2" | |
1337 | ) | |
1338 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
1339 | tc_name, result | |
1340 | ) | |
1341 | ||
1342 | # Verifying BGP RIB routes | |
1343 | dut = "r1" | |
1344 | peer = "r2" | |
1345 | next_hop = next_hop_per_address_family( | |
1346 | tgen, dut, peer, addr_type, NEXT_HOP_IP_2 | |
1347 | ) | |
1348 | input_topo = {key: topo["routers"][key] for key in ["r2"]} | |
1349 | result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop) | |
1350 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
1351 | tc_name, result | |
1352 | ) | |
1353 | ||
1354 | # Verifying RIB routes | |
1355 | protocol = "bgp" | |
1356 | result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol) | |
1357 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
1358 | tc_name, result | |
1359 | ) | |
1360 | ||
1361 | logger.info("[Phase 1] : Changing mode" "[Disable Mode]R1-----R2[Helper Mode]") | |
1362 | ||
1363 | # Configure graceful-restart | |
1364 | input_dict = { | |
1365 | "r1": { | |
1366 | "bgp": { | |
1367 | "address_family": { | |
1368 | "ipv4": { | |
1369 | "unicast": { | |
1370 | "neighbor": { | |
1371 | "r2": { | |
1372 | "dest_link": { | |
1373 | "r1-link1": {"graceful-restart-disable": True} | |
1374 | } | |
1375 | } | |
1376 | } | |
1377 | } | |
1378 | }, | |
1379 | "ipv6": { | |
1380 | "unicast": { | |
1381 | "neighbor": { | |
1382 | "r2": { | |
1383 | "dest_link": { | |
1384 | "r1-link1": {"graceful-restart-disable": True} | |
1385 | } | |
1386 | } | |
1387 | } | |
1388 | } | |
1389 | }, | |
1390 | } | |
1391 | } | |
1392 | } | |
1393 | } | |
1394 | ||
1395 | result = create_router_bgp(tgen, topo, input_dict) | |
1396 | assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) | |
1397 | ||
1398 | for addr_type in ADDR_TYPES: | |
1399 | neighbor = topo["routers"]["r2"]["links"]["r1-link1"][addr_type].split("/")[0] | |
1400 | clear_bgp(tgen, addr_type, "r1", neighbor=neighbor) | |
1401 | ||
1402 | result = verify_bgp_convergence_from_running_config(tgen) | |
1403 | assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) | |
1404 | ||
1405 | # Verify GR stats | |
1406 | input_dict = { | |
1407 | "r2": { | |
1408 | "bgp": { | |
1409 | "address_family": { | |
1410 | "ipv4": { | |
1411 | "unicast": { | |
1412 | "neighbor": { | |
1413 | "r1": { | |
1414 | "dest_link": { | |
1415 | "r2-link1": {"graceful-restart-helper": True} | |
1416 | } | |
1417 | } | |
1418 | } | |
1419 | } | |
1420 | }, | |
1421 | "ipv6": { | |
1422 | "unicast": { | |
1423 | "neighbor": { | |
1424 | "r1": { | |
1425 | "dest_link": { | |
1426 | "r2-link1": {"graceful-restart-helper": True} | |
1427 | } | |
1428 | } | |
1429 | } | |
1430 | } | |
1431 | }, | |
1432 | } | |
1433 | } | |
1434 | }, | |
1435 | "r1": { | |
1436 | "bgp": { | |
1437 | "address_family": { | |
1438 | "ipv4": { | |
1439 | "unicast": { | |
1440 | "neighbor": { | |
1441 | "r2": { | |
1442 | "dest_link": { | |
1443 | "r1-link1": {"graceful-restart-disable": True} | |
1444 | } | |
1445 | } | |
1446 | } | |
1447 | } | |
1448 | }, | |
1449 | "ipv6": { | |
1450 | "unicast": { | |
1451 | "neighbor": { | |
1452 | "r2": { | |
1453 | "dest_link": { | |
1454 | "r1-link1": {"graceful-restart-disable": True} | |
1455 | } | |
1456 | } | |
1457 | } | |
1458 | } | |
1459 | }, | |
1460 | } | |
1461 | } | |
1462 | }, | |
1463 | } | |
1464 | ||
1465 | # here the verify_graceful_restart fro the neighbor would be | |
1466 | # "NotReceived" as the latest GR config is not yet applied. | |
1467 | for addr_type in ADDR_TYPES: | |
1468 | result = verify_graceful_restart( | |
1469 | tgen, topo, addr_type, input_dict, dut="r1", peer="r2" | |
1470 | ) | |
1471 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
1472 | tc_name, result | |
1473 | ) | |
1474 | ||
1475 | logger.info("[Phase 2] : Now flap the link running the BGP session ") | |
1476 | # Shutdown interface | |
1477 | intf = "r2-r1-eth0" | |
1478 | shutdown_bringup_interface(tgen, "r2", intf) | |
1479 | ||
1480 | # Bring up Interface | |
1481 | shutdown_bringup_interface(tgen, "r2", intf, ifaceaction=True) | |
1482 | ||
1483 | for addr_type in ADDR_TYPES: | |
1484 | result = verify_graceful_restart( | |
1485 | tgen, topo, addr_type, input_dict, dut="r1", peer="r2" | |
1486 | ) | |
1487 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
1488 | tc_name, result | |
1489 | ) | |
1490 | ||
1491 | result = verify_r_bit( | |
1492 | tgen, topo, addr_type, input_dict, dut="r2", peer="r1", expected=False | |
1493 | ) | |
d63c7094 KK |
1494 | assert result is not True, ( |
1495 | "Testcase {} : Failed \n " | |
1496 | "Expected: R-bit should not be set to True in r2\n" | |
1497 | "Found: {}".format(tc_name, result) | |
b0449478 DS |
1498 | ) |
1499 | ||
1500 | logger.info("Restart BGPd on R2 ") | |
1501 | kill_router_daemons(tgen, "r2", ["bgpd"]) | |
1502 | ||
1503 | start_router_daemons(tgen, "r2", ["bgpd"]) | |
1504 | ||
1505 | for addr_type in ADDR_TYPES: | |
1506 | result = verify_graceful_restart( | |
1507 | tgen, topo, addr_type, input_dict, dut="r1", peer="r2" | |
1508 | ) | |
1509 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
1510 | tc_name, result | |
1511 | ) | |
1512 | ||
1513 | result = verify_r_bit( | |
1514 | tgen, topo, addr_type, input_dict, dut="r2", peer="r1", expected=False | |
1515 | ) | |
d63c7094 KK |
1516 | assert result is not True, ( |
1517 | "Testcase {} : Failed \n " | |
1518 | "Expected: R-bit should not be set to True in r2\n" | |
1519 | "Found: {}".format(tc_name, result) | |
b0449478 DS |
1520 | ) |
1521 | ||
1522 | write_test_footer(tc_name) | |
1523 | ||
1524 | ||
1525 | if __name__ == "__main__": | |
1526 | args = ["-s"] + sys.argv[1:] | |
1527 | sys.exit(pytest.main(args)) |