]>
Commit | Line | Data |
---|---|---|
b0449478 DS |
1 | #!/usr/bin/env python |
2 | # | |
3 | # Copyright (c) 2019 by VMware, Inc. ("VMware") | |
4 | # Used Copyright (c) 2018 by Network Device Education Foundation, Inc. ("NetDEF") | |
5 | # in this file. | |
6 | # | |
7 | # Permission to use, copy, modify, and/or distribute this software | |
8 | # for any purpose with or without fee is hereby granted, provided | |
9 | # that the above copyright notice and this permission notice appear | |
10 | # in all copies. | |
11 | # | |
12 | # THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES | |
13 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
14 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR | |
15 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY | |
16 | # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
17 | # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | |
18 | # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |
19 | # OF THIS SOFTWARE. | |
20 | # | |
21 | ||
22 | """ | |
23 | Following tests are covered to test BGP Graceful Restart functionality. | |
24 | Basic Common Test steps for all the test case below : | |
25 | - Create topology (setup module) | |
26 | Creating 7 routers topology | |
27 | - Bring up topology | |
28 | - Verify for bgp to converge | |
29 | - Configure BGP Graceful Restart on both the routers. | |
30 | ||
31 | TC_1_2: | |
32 | Verify that EOR message is sent out only after initial convergence | |
33 | Verify whether EOR message is received from all the peers after restart | |
34 | TC_3: | |
35 | Verify the selection deferral timer functionality when EOR is not sent | |
36 | by the helper router | |
37 | TC_11: | |
38 | Verify that selection-deferral timer sets the maximum time to | |
39 | avoid deadlock during which the best-path | |
40 | TC_10: | |
41 | Test Objective : Test GR scenarios on helper router by enabling | |
42 | Graceful Restart for multiple address families. | |
43 | TC_15: | |
44 | Test Objective : Test GR scenarios by enabling Graceful Restart | |
45 | for multiple address families.. | |
46 | TC_16: | |
47 | Test Objective : Verify BGP-GR feature when restarting node | |
48 | is a transit router for it's iBGP peers. | |
49 | TC_18: | |
50 | Test Objective : Verify that GR helper router deletes stale routes | |
51 | received from restarting node, if GR capability is not present in | |
52 | TC_19: | |
53 | Test Objective : Verify that GR routers keeps all the routes | |
54 | received from restarting node if both the routers are | |
55 | TC_26: | |
56 | Test Objective : Test GR scenarios on helper router by enabling | |
57 | Graceful Restart for multiple address families. | |
58 | TC_28: | |
59 | Test Objective : Verify if helper node goes down before restarting | |
60 | node comes up online, helper node sets the R-bit to avoid dead-lock | |
61 | TC_29: | |
62 | Test Objective : Change timers on the fly, and | |
63 | verify if it takes immediate effect. | |
64 | TC_33: | |
65 | Test Objective : Helper router receives same prefixes from two | |
66 | different routers (GR-restarting and GR-disabled). Keeps the | |
67 | TC_34_1: | |
68 | Test Objective : Restarting node doesn't preserve forwarding | |
69 | state, helper router should not keep the stale entries. | |
70 | TC_34_2: | |
71 | Test Objective : Restarting node doesn't preserve the forwarding | |
72 | state verify the behaviour on helper node, if it still keeps the | |
73 | TC_32: | |
74 | Test Objective : Restarting node is connected to multiple helper | |
75 | nodes, one of them doesn't send EOR to restarting router. Verify | |
76 | TC_37: | |
77 | Test Objective : Verify if helper node restarts before sending the | |
78 | EOR message, restarting node doesn't wait until stale path timer | |
79 | TC_30: | |
80 | Test Objective : Restarting node removes stale routes from Zebra | |
81 | after receiving an EOR from helper router. | |
82 | ||
83 | """ | |
84 | ||
85 | import os | |
86 | import sys | |
87 | import time | |
88 | import pytest | |
89 | from time import sleep | |
90 | ||
91 | # Save the Current Working Directory to find configuration files. | |
92 | CWD = os.path.dirname(os.path.realpath(__file__)) | |
93 | sys.path.append(os.path.join("../")) | |
94 | sys.path.append(os.path.join("../lib/")) | |
95 | ||
96 | # pylint: disable=C0413 | |
97 | # Import topogen and topotest helpers | |
98 | from lib.topogen import Topogen, get_topogen | |
99 | from lib.topolog import logger | |
100 | ||
101 | # Required to instantiate the topology builder class. | |
102 | ||
103 | # Import topoJson from lib, to create topology and initial configuration | |
104 | from lib.topojson import build_config_from_json | |
105 | from lib.bgp import ( | |
106 | clear_bgp, | |
107 | verify_bgp_rib, | |
108 | verify_graceful_restart, | |
109 | create_router_bgp, | |
110 | verify_r_bit, | |
111 | verify_eor, | |
112 | verify_f_bit, | |
113 | verify_bgp_convergence, | |
114 | verify_gr_address_family, | |
115 | modify_bgp_config_when_bgpd_down, | |
116 | verify_graceful_restart_timers, | |
117 | verify_bgp_convergence_from_running_config, | |
118 | ) | |
119 | ||
120 | from lib.common_config import ( | |
121 | write_test_header, | |
122 | reset_config_on_routers, | |
123 | start_topology, | |
124 | kill_router_daemons, | |
125 | start_router_daemons, | |
126 | verify_rib, | |
127 | check_address_types, | |
128 | write_test_footer, | |
129 | check_router_status, | |
130 | step, | |
131 | get_frr_ipv6_linklocal, | |
132 | required_linux_kernel_version, | |
133 | ) | |
134 | ||
135 | pytestmark = [pytest.mark.bgpd] | |
136 | ||
137 | ||
138 | # Global variables | |
139 | BGP_CONVERGENCE = False | |
140 | GR_RESTART_TIMER = 5 | |
141 | GR_SELECT_DEFER_TIMER = 5 | |
142 | GR_STALEPATH_TIMER = 5 | |
143 | PREFERRED_NEXT_HOP = "link_local" | |
144 | NEXT_HOP_4 = ["192.168.1.1", "192.168.4.2"] | |
145 | NEXT_HOP_6 = ["fd00:0:0:1::1", "fd00:0:0:4::2"] | |
146 | ||
147 | ||
148 | def setup_module(mod): | |
149 | """ | |
150 | Sets up the pytest environment | |
151 | ||
152 | * `mod`: module name | |
153 | """ | |
154 | ||
155 | # Required linux kernel version for this suite to run. | |
156 | result = required_linux_kernel_version("4.16") | |
157 | if result is not True: | |
158 | pytest.skip("Kernel requirements are not met") | |
159 | ||
160 | global ADDR_TYPES | |
161 | ||
162 | testsuite_run_time = time.asctime(time.localtime(time.time())) | |
163 | logger.info("Testsuite start time: {}".format(testsuite_run_time)) | |
164 | logger.info("=" * 40) | |
165 | ||
166 | logger.info("Running setup_module to create topology") | |
167 | ||
168 | # This function initiates the topology build with Topogen... | |
169 | json_file = "{}/bgp_gr_topojson_topo2.json".format(CWD) | |
170 | tgen = Topogen(json_file, mod.__name__) | |
171 | global topo | |
172 | topo = tgen.json_topo | |
173 | # ... and here it calls Mininet initialization functions. | |
174 | ||
175 | # Starting topology, create tmp files which are loaded to routers | |
176 | # to start deamons and then start routers | |
177 | start_topology(tgen) | |
178 | ||
179 | # Creating configuration from JSON | |
180 | build_config_from_json(tgen, topo) | |
181 | ||
182 | # Api call verify whether BGP is converged | |
183 | ADDR_TYPES = check_address_types() | |
184 | ||
185 | for addr_type in ADDR_TYPES: | |
186 | BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo) | |
187 | assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error:" " {}".format( | |
188 | BGP_CONVERGENCE | |
189 | ) | |
190 | ||
191 | logger.info("Running setup_module() done") | |
192 | ||
193 | ||
194 | def teardown_module(mod): | |
195 | """ | |
196 | Teardown the pytest environment | |
197 | ||
198 | * `mod`: module name | |
199 | """ | |
200 | ||
201 | logger.info("Running teardown_module to delete topology") | |
202 | ||
203 | tgen = get_topogen() | |
204 | ||
205 | # Stop toplogy and Remove tmp files | |
206 | tgen.stop_topology() | |
207 | ||
208 | logger.info( | |
209 | "Testsuite end time: {}".format(time.asctime(time.localtime(time.time()))) | |
210 | ) | |
211 | logger.info("=" * 40) | |
212 | ||
213 | ||
214 | def configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut, peer): | |
215 | """ | |
216 | This function groups the repetitive function calls into one function. | |
217 | """ | |
218 | ||
219 | logger.info("configure_gr_followed_by_clear: dut %s peer %s", dut, peer) | |
220 | ||
221 | result = create_router_bgp(tgen, topo, input_dict) | |
222 | assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) | |
223 | ||
224 | for addr_type in ADDR_TYPES: | |
225 | neighbor = topo["routers"][peer]["links"][dut][addr_type].split("/")[0] | |
226 | clear_bgp(tgen, addr_type, dut, neighbor=neighbor) | |
227 | ||
228 | for addr_type in ADDR_TYPES: | |
229 | neighbor = topo["routers"][dut]["links"][peer][addr_type].split("/")[0] | |
230 | clear_bgp(tgen, addr_type, peer, neighbor=neighbor) | |
231 | ||
232 | result = verify_bgp_convergence_from_running_config(tgen) | |
233 | assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) | |
234 | ||
235 | return True | |
236 | ||
237 | ||
238 | def next_hop_per_address_family(tgen, dut, peer, addr_type, next_hop_dict): | |
239 | """ | |
240 | This function returns link_local or global next_hop per address-family | |
241 | """ | |
242 | ||
243 | intferface = topo["routers"][peer]["links"]["{}-link1".format(dut)]["interface"] | |
244 | if addr_type == "ipv6" and "link_local" in PREFERRED_NEXT_HOP: | |
245 | next_hop = get_frr_ipv6_linklocal(tgen, peer, intf=intferface) | |
246 | else: | |
247 | next_hop = next_hop_dict[addr_type] | |
248 | ||
249 | return next_hop | |
250 | ||
251 | ||
252 | def test_BGP_GR_chaos_34_1_p1(request): | |
253 | """ | |
254 | Test Objective : Restarting node doesn't preserve forwarding | |
255 | state, helper router should not keep the stale entries. | |
256 | """ | |
257 | ||
258 | tgen = get_topogen() | |
259 | tc_name = request.node.name | |
260 | write_test_header(tc_name) | |
261 | ||
262 | # Check router status | |
263 | check_router_status(tgen) | |
264 | ||
265 | # Don't run this test if we have any failure. | |
266 | if tgen.routers_have_failure(): | |
267 | pytest.skip(tgen.errors) | |
268 | ||
269 | # Creating configuration from JSON | |
270 | reset_config_on_routers(tgen) | |
271 | ||
272 | logger.info( | |
273 | " Test Case : test_BGP_GR_chaos_31 " | |
274 | "BGP GR " | |
275 | "[Restart Mode]R1---R3[Helper Mode]" | |
276 | ) | |
277 | ||
278 | # Configure graceful-restart | |
279 | input_dict = { | |
280 | "r1": { | |
281 | "bgp": { | |
282 | "graceful-restart": { | |
283 | "preserve-fw-state": True, | |
284 | "timer": {"restart-time": GR_RESTART_TIMER}, | |
285 | }, | |
286 | "address_family": { | |
287 | "ipv4": { | |
288 | "unicast": { | |
289 | "neighbor": { | |
290 | "r3": {"dest_link": {"r1": {"graceful-restart": True}}} | |
291 | } | |
292 | } | |
293 | }, | |
294 | "ipv6": { | |
295 | "unicast": { | |
296 | "neighbor": { | |
297 | "r3": {"dest_link": {"r1": {"graceful-restart": True}}} | |
298 | } | |
299 | } | |
300 | }, | |
301 | }, | |
302 | } | |
303 | }, | |
304 | "r3": { | |
305 | "bgp": { | |
306 | "address_family": { | |
307 | "ipv4": { | |
308 | "unicast": { | |
309 | "neighbor": { | |
310 | "r1": { | |
311 | "dest_link": { | |
312 | "r3": {"graceful-restart-helper": True} | |
313 | } | |
314 | } | |
315 | } | |
316 | } | |
317 | }, | |
318 | "ipv6": { | |
319 | "unicast": { | |
320 | "neighbor": { | |
321 | "r1": { | |
322 | "dest_link": { | |
323 | "r3": {"graceful-restart-helper": True} | |
324 | } | |
325 | } | |
326 | } | |
327 | } | |
328 | }, | |
329 | } | |
330 | } | |
331 | }, | |
332 | } | |
333 | ||
334 | configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3") | |
335 | ||
336 | for addr_type in ADDR_TYPES: | |
337 | result = verify_graceful_restart( | |
338 | tgen, topo, addr_type, input_dict, dut="r1", peer="r3" | |
339 | ) | |
340 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
341 | tc_name, result | |
342 | ) | |
343 | ||
344 | # Verifying BGP RIB routes after starting BGPd daemon | |
345 | dut = "r3" | |
346 | input_dict_1 = {key: topo["routers"][key] for key in ["r1"]} | |
347 | result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1) | |
348 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
349 | tc_name, result | |
350 | ) | |
351 | ||
352 | # Verifying RIB routes | |
353 | result = verify_rib(tgen, addr_type, dut, input_dict_1) | |
354 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
355 | tc_name, result | |
356 | ) | |
357 | ||
358 | logger.info( | |
359 | "[Step 1] : Remove the preserve-fw-state command" | |
360 | " from restarting node R1's config" | |
361 | ) | |
362 | ||
363 | # Configure graceful-restart to set f-bit as False | |
364 | input_dict_2 = {"r1": {"bgp": {"graceful-restart": {"preserve-fw-state": False}}}} | |
365 | ||
366 | result = create_router_bgp(tgen, topo, input_dict_2) | |
367 | assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) | |
368 | ||
369 | logger.info("[Step 2] : Reset the session between R1 and R3..") | |
370 | ||
371 | # Reset sessions | |
372 | for addr_type in ADDR_TYPES: | |
373 | clear_bgp(tgen, addr_type, "r1") | |
374 | ||
375 | result = verify_bgp_convergence_from_running_config(tgen, topo) | |
376 | assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) | |
377 | ||
378 | for addr_type in ADDR_TYPES: | |
379 | # Verify f-bit after starting BGPd daemon | |
380 | result = verify_f_bit( | |
381 | tgen, topo, addr_type, input_dict_2, "r3", "r1", expected=False | |
382 | ) | |
383 | assert ( | |
384 | result is not True | |
385 | ), "Testcase {} : Failed \n " "r3: F-bit is set to True\n Error: {}".format( | |
386 | tc_name, result | |
387 | ) | |
388 | logger.info(" Expected behavior: {}".format(result)) | |
389 | ||
390 | logger.info("[Step 3] : Kill BGPd daemon on R1..") | |
391 | ||
392 | # Kill BGPd daemon on R1 | |
393 | kill_router_daemons(tgen, "r1", ["bgpd"]) | |
394 | ||
395 | # Waiting for GR_RESTART_TIMER | |
396 | logger.info("Waiting for {} sec..".format(GR_RESTART_TIMER)) | |
397 | sleep(GR_RESTART_TIMER) | |
398 | ||
399 | for addr_type in ADDR_TYPES: | |
400 | # Verifying BGP RIB routes | |
401 | input_dict = {key: topo["routers"][key] for key in ["r1"]} | |
402 | result = verify_bgp_rib(tgen, addr_type, dut, input_dict, expected=False) | |
403 | assert result is not True, ( | |
404 | "Testcase {} : Failed \n " | |
405 | "r3: routes are still present in BGP RIB\n Error: {}".format( | |
406 | tc_name, result | |
407 | ) | |
408 | ) | |
409 | logger.info(" Expected behavior: {}".format(result)) | |
410 | ||
411 | # Verifying RIB routes | |
412 | result = verify_rib(tgen, addr_type, dut, input_dict, expected=False) | |
413 | assert result is not True, ( | |
414 | "Testcase {} : Failed \n " | |
415 | "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name, result) | |
416 | ) | |
417 | logger.info(" Expected behavior: {}".format(result)) | |
418 | ||
419 | # Start BGPd daemon on R1 | |
420 | start_router_daemons(tgen, "r1", ["bgpd"]) | |
421 | ||
422 | write_test_footer(tc_name) | |
423 | ||
424 | ||
425 | def test_BGP_GR_chaos_32_p1(request): | |
426 | """ | |
427 | Test Objective : Restarting node is connected to multiple helper | |
428 | nodes, one of them doesn't send EOR to restarting router. Verify | |
429 | that only after SDT restarting node send EOR to all helper peers | |
430 | excluding the prefixes originated by faulty router. | |
431 | """ | |
432 | ||
433 | tgen = get_topogen() | |
434 | tc_name = request.node.name | |
435 | write_test_header(tc_name) | |
436 | ||
437 | # Check router status | |
438 | check_router_status(tgen) | |
439 | ||
440 | # Don't run this test if we have any failure. | |
441 | if tgen.routers_have_failure(): | |
442 | pytest.skip(tgen.errors) | |
443 | ||
444 | # Creating configuration from JSON | |
445 | reset_config_on_routers(tgen) | |
446 | ||
447 | logger.info( | |
448 | " Test Case : test_BGP_GR_chaos_32 " | |
449 | "BGP GR " | |
450 | "[Restart Mode]R1---R3&R5[Helper Mode]" | |
451 | ) | |
452 | ||
453 | logger.info( | |
454 | "[Step 1] : Change the mode on R1 be a restarting" " node on global level" | |
455 | ) | |
456 | ||
457 | # Configure graceful-restart | |
458 | input_dict = { | |
459 | "r1": { | |
460 | "bgp": { | |
461 | "graceful-restart": {"graceful-restart": True}, | |
462 | "address_family": { | |
463 | "ipv4": { | |
464 | "unicast": { | |
465 | "neighbor": { | |
466 | "r3": {"dest_link": {"r1": {"next_hop_self": True}}}, | |
467 | "r5": {"dest_link": {"r1": {"graceful-restart": True}}}, | |
468 | } | |
469 | } | |
470 | }, | |
471 | "ipv6": { | |
472 | "unicast": { | |
473 | "neighbor": { | |
474 | "r3": {"dest_link": {"r1": {"next_hop_self": True}}}, | |
475 | "r5": {"dest_link": {"r1": {"graceful-restart": True}}}, | |
476 | } | |
477 | } | |
478 | }, | |
479 | }, | |
480 | } | |
481 | }, | |
482 | "r5": { | |
483 | "bgp": { | |
484 | "address_family": { | |
485 | "ipv4": { | |
486 | "unicast": { | |
487 | "neighbor": { | |
488 | "r1": { | |
489 | "dest_link": { | |
490 | "r5": {"graceful-restart-helper": True} | |
491 | } | |
492 | } | |
493 | } | |
494 | } | |
495 | }, | |
496 | "ipv6": { | |
497 | "unicast": { | |
498 | "neighbor": { | |
499 | "r1": { | |
500 | "dest_link": { | |
501 | "r5": {"graceful-restart-helper": True} | |
502 | } | |
503 | } | |
504 | } | |
505 | } | |
506 | }, | |
507 | } | |
508 | } | |
509 | }, | |
510 | } | |
511 | ||
512 | configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r5") | |
513 | ||
514 | for addr_type in ADDR_TYPES: | |
515 | result = verify_graceful_restart( | |
516 | tgen, topo, addr_type, input_dict, dut="r1", peer="r5" | |
517 | ) | |
518 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
519 | tc_name, result | |
520 | ) | |
521 | ||
522 | # Verifying BGP RIB routes after starting BGPd daemon | |
523 | dut = "r3" | |
524 | input_dict_1 = {key: topo["routers"][key] for key in ["r5"]} | |
525 | result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1) | |
526 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
527 | tc_name, result | |
528 | ) | |
529 | ||
530 | # Verifying RIB routes | |
531 | result = verify_rib(tgen, addr_type, dut, input_dict_1) | |
532 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
533 | tc_name, result | |
534 | ) | |
535 | ||
536 | logger.info("[Step 2] : Kill BGPd daemon on R1..") | |
537 | # Kill BGPd daemon on R1 | |
538 | kill_router_daemons(tgen, "r1", ["bgpd"]) | |
539 | ||
540 | logger.info("[Step 3] : Withdraw all the advertised prefixes from R5") | |
541 | ||
542 | # Api call to delete advertised networks | |
543 | network = {"ipv4": "105.0.20.1/32", "ipv6": "5::1/128"} | |
544 | for addr_type in ADDR_TYPES: | |
545 | input_dict_2 = { | |
546 | "r5": { | |
547 | "bgp": { | |
548 | "address_family": { | |
549 | addr_type: { | |
550 | "unicast": { | |
551 | "advertise_networks": [ | |
552 | { | |
553 | "network": network[addr_type], | |
554 | "no_of_network": 5, | |
555 | "delete": True, | |
556 | } | |
557 | ] | |
558 | } | |
559 | } | |
560 | } | |
561 | } | |
562 | } | |
563 | } | |
564 | ||
565 | result = create_router_bgp(tgen, topo, input_dict_2) | |
566 | assert result is True, "Testcase {} : Failed \n Error: {}".format( | |
567 | tc_name, result | |
568 | ) | |
569 | ||
570 | logger.info( | |
571 | "[Step 4] : Stop the helper router R5 from sending EOR" " message using CLI" | |
572 | ) | |
573 | ||
574 | # Modify graceful-restart config to prevent sending EOR | |
575 | input_dict_3 = {"r5": {"bgp": {"graceful-restart": {"disable-eor": True}}}} | |
576 | ||
577 | result = create_router_bgp(tgen, topo, input_dict_3) | |
578 | assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) | |
579 | ||
580 | logger.info("[Step 5] : Bring up the BGPd daemon on R1..") | |
581 | ||
582 | # Start BGPd daemon on R1 | |
583 | start_router_daemons(tgen, "r1", ["bgpd"]) | |
584 | ||
585 | for addr_type in ADDR_TYPES: | |
586 | # Verify EOR is disabled | |
587 | result = verify_eor( | |
588 | tgen, topo, addr_type, input_dict_3, dut="r5", peer="r1", expected=False | |
589 | ) | |
590 | assert ( | |
591 | result is not True | |
592 | ), "Testcase {} : Failed \n " "r5: EOR is set to TRUE\n Error: {}".format( | |
593 | tc_name, result | |
594 | ) | |
595 | logger.info(" Expected behavior: {}".format(result)) | |
596 | ||
597 | # Verifying BGP RIB routes after starting BGPd daemon | |
598 | input_dict_1 = {key: topo["routers"][key] for key in ["r5"]} | |
599 | result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1, expected=False) | |
600 | assert result is not True, ( | |
601 | "Testcase {} : Failed \n " | |
602 | "r3: routes are still present in BGP RIB\n Error: {}".format( | |
603 | tc_name, result | |
604 | ) | |
605 | ) | |
606 | logger.info(" Expected behavior: {}".format(result)) | |
607 | ||
608 | # Verifying RIB routes | |
609 | result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False) | |
610 | assert result is not True, ( | |
611 | "Testcase {} : Failed \n " | |
612 | "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name, result) | |
613 | ) | |
614 | logger.info(" Expected behavior: {}".format(result)) | |
615 | ||
616 | write_test_footer(tc_name) | |
617 | ||
618 | ||
619 | def test_BGP_GR_chaos_37_p1(request): | |
620 | """ | |
621 | Test Objective : Verify if helper node restarts before sending the | |
622 | EOR message, restarting node doesn't wait until stale path timer | |
623 | expiry to do the best path selection and sends an EOR | |
624 | """ | |
625 | ||
626 | tgen = get_topogen() | |
627 | tc_name = request.node.name | |
628 | write_test_header(tc_name) | |
629 | ||
630 | # Check router status | |
631 | check_router_status(tgen) | |
632 | ||
633 | # Don't run this test if we have any failure. | |
634 | if tgen.routers_have_failure(): | |
635 | pytest.skip(tgen.errors) | |
636 | ||
637 | # Creating configuration from JSON | |
638 | reset_config_on_routers(tgen) | |
639 | ||
640 | logger.info( | |
641 | " Test Case : test_BGP_GR_chaos_37 " | |
642 | "BGP GR " | |
643 | "[Restart Mode]R1---R3[Helper Mode]" | |
644 | ) | |
645 | ||
646 | logger.info( | |
647 | "[Step 1] : Configure restarting router R3 to prevent " "sending an EOR.." | |
648 | ) | |
649 | ||
650 | logger.info("[Step 2] : Reset the session between R3 and R1..") | |
651 | ||
652 | # Configure graceful-restart | |
653 | input_dict = { | |
654 | "r1": { | |
655 | "bgp": { | |
656 | "address_family": { | |
657 | "ipv4": { | |
658 | "unicast": { | |
659 | "neighbor": { | |
660 | "r3": {"dest_link": {"r1": {"graceful-restart": True}}} | |
661 | } | |
662 | } | |
663 | }, | |
664 | "ipv6": { | |
665 | "unicast": { | |
666 | "neighbor": { | |
667 | "r3": {"dest_link": {"r1": {"graceful-restart": True}}} | |
668 | } | |
669 | } | |
670 | }, | |
671 | } | |
672 | } | |
673 | }, | |
674 | "r3": { | |
675 | "bgp": { | |
676 | "graceful-restart": {"disable-eor": True}, | |
677 | "address_family": { | |
678 | "ipv4": { | |
679 | "unicast": { | |
680 | "neighbor": { | |
681 | "r1": { | |
682 | "dest_link": { | |
683 | "r3": {"graceful-restart-helper": True} | |
684 | } | |
685 | } | |
686 | } | |
687 | } | |
688 | }, | |
689 | "ipv6": { | |
690 | "unicast": { | |
691 | "neighbor": { | |
692 | "r1": { | |
693 | "dest_link": { | |
694 | "r3": {"graceful-restart-helper": True} | |
695 | } | |
696 | } | |
697 | } | |
698 | } | |
699 | }, | |
700 | }, | |
701 | } | |
702 | }, | |
703 | } | |
704 | ||
705 | configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3") | |
706 | ||
707 | for addr_type in ADDR_TYPES: | |
708 | result = verify_graceful_restart( | |
709 | tgen, topo, addr_type, input_dict, dut="r1", peer="r3" | |
710 | ) | |
711 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
712 | tc_name, result | |
713 | ) | |
714 | ||
715 | # Verify EOR is disabled | |
716 | result = verify_eor( | |
717 | tgen, topo, addr_type, input_dict, dut="r3", peer="r1", expected=False | |
718 | ) | |
719 | assert ( | |
720 | result is not True | |
721 | ), "Testcase {} : Failed \n " "r3: EOR is set to True\n Error: {}".format( | |
722 | tc_name, result | |
723 | ) | |
724 | logger.info(" Expected behavior: {}".format(result)) | |
725 | ||
726 | # Verifying BGP RIB routes after starting BGPd daemon | |
727 | dut = "r1" | |
728 | input_dict_1 = {key: topo["routers"][key] for key in ["r3"]} | |
729 | result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1) | |
730 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
731 | tc_name, result | |
732 | ) | |
733 | ||
734 | # Verifying RIB routes | |
735 | result = verify_rib(tgen, addr_type, dut, input_dict_1) | |
736 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
737 | tc_name, result | |
738 | ) | |
739 | ||
740 | logger.info("[Step 3] : Kill BGPd daemon on R1..") | |
741 | ||
742 | # Kill BGPd daemon on R1 | |
743 | kill_router_daemons(tgen, "r1", ["bgpd"]) | |
744 | ||
745 | logger.info("[Step 4] : Start BGPd daemon on R1..") | |
746 | ||
747 | # Start BGPd daemon on R1 | |
748 | start_router_daemons(tgen, "r1", ["bgpd"]) | |
749 | ||
750 | logger.info("[Step 5] : Kill BGPd daemon on R3..") | |
751 | ||
752 | # Kill BGPd daemon on R3 | |
753 | kill_router_daemons(tgen, "r3", ["bgpd"]) | |
754 | ||
755 | # Modify graceful-restart config to prevent sending EOR | |
756 | input_dict_2 = {"r3": {"bgp": {"graceful-restart": {"disable-eor": True}}}} | |
757 | ||
758 | result = modify_bgp_config_when_bgpd_down(tgen, topo, input_dict_2) | |
759 | assert result is True, "Testcase {} : Failed \n Error {}".format(tc_name, result) | |
760 | ||
761 | logger.info("[Step 6] : Start BGPd daemon on R3..") | |
762 | ||
763 | # Start BGPd daemon on R3 | |
764 | start_router_daemons(tgen, "r3", ["bgpd"]) | |
765 | ||
766 | for addr_type in ADDR_TYPES: | |
767 | # Verify r_bit | |
768 | result = verify_r_bit(tgen, topo, addr_type, input_dict, dut="r1", peer="r3") | |
769 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
770 | tc_name, result | |
771 | ) | |
772 | ||
773 | # Verifying RIB routes | |
774 | input_dict_1 = {key: topo["routers"][key] for key in ["r3"]} | |
775 | result = verify_rib(tgen, addr_type, dut, input_dict_1) | |
776 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
777 | tc_name, result | |
778 | ) | |
779 | ||
780 | # Verify EOR is send from R1 to R3 | |
781 | input_dict_3 = {"r1": {"bgp": {"graceful-restart": {"disable-eor": True}}}} | |
782 | ||
783 | result = verify_eor( | |
784 | tgen, topo, addr_type, input_dict_3, dut="r1", peer="r3", expected=False | |
785 | ) | |
786 | assert ( | |
787 | result is not True | |
788 | ), "Testcase {} : Failed \n " "r1: EOR is set to True\n Error: {}".format( | |
789 | tc_name, result | |
790 | ) | |
791 | ||
792 | write_test_footer(tc_name) | |
793 | ||
794 | ||
795 | def test_BGP_GR_chaos_30_p1(request): | |
796 | """ | |
797 | Test Objective : Restarting node removes stale routes from Zebra | |
798 | after receiving an EOR from helper router. | |
799 | """ | |
800 | ||
801 | tgen = get_topogen() | |
802 | tc_name = request.node.name | |
803 | write_test_header(tc_name) | |
804 | ||
805 | # Check router status | |
806 | check_router_status(tgen) | |
807 | ||
808 | # Don't run this test if we have any failure. | |
809 | if tgen.routers_have_failure(): | |
810 | pytest.skip(tgen.errors) | |
811 | ||
812 | # Creating configuration from JSON | |
813 | reset_config_on_routers(tgen) | |
814 | ||
815 | logger.info( | |
816 | " Test Case : test_BGP_GR_chaos_30 " | |
817 | "BGP GR [Helper Mode]R3-----R1[Restart Mode] " | |
818 | ) | |
819 | ||
820 | # Configure graceful-restart and timers | |
821 | input_dict = { | |
822 | "r1": { | |
823 | "bgp": { | |
824 | "graceful-restart": {"preserve-fw-state": True}, | |
825 | "address_family": { | |
826 | "ipv4": { | |
827 | "unicast": { | |
828 | "neighbor": { | |
829 | "r3": {"dest_link": {"r1": {"graceful-restart": True}}} | |
830 | } | |
831 | } | |
832 | }, | |
833 | "ipv6": { | |
834 | "unicast": { | |
835 | "neighbor": { | |
836 | "r3": {"dest_link": {"r1": {"graceful-restart": True}}} | |
837 | } | |
838 | } | |
839 | }, | |
840 | }, | |
841 | } | |
842 | }, | |
843 | "r3": { | |
844 | "bgp": { | |
845 | "address_family": { | |
846 | "ipv4": { | |
847 | "unicast": { | |
848 | "neighbor": { | |
849 | "r1": { | |
850 | "dest_link": { | |
851 | "r3": {"graceful-restart-helper": True} | |
852 | } | |
853 | } | |
854 | } | |
855 | } | |
856 | }, | |
857 | "ipv6": { | |
858 | "unicast": { | |
859 | "neighbor": { | |
860 | "r1": { | |
861 | "dest_link": { | |
862 | "r3": {"graceful-restart-helper": True} | |
863 | } | |
864 | } | |
865 | } | |
866 | } | |
867 | }, | |
868 | } | |
869 | } | |
870 | }, | |
871 | } | |
872 | ||
873 | configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3") | |
874 | ||
875 | for addr_type in ADDR_TYPES: | |
876 | result = verify_graceful_restart( | |
877 | tgen, topo, addr_type, input_dict, dut="r1", peer="r3" | |
878 | ) | |
879 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
880 | tc_name, result | |
881 | ) | |
882 | ||
883 | for addr_type in ADDR_TYPES: | |
884 | # Verifying BGP RIB routes before shutting down BGPd daemon | |
885 | dut = "r1" | |
886 | input_dict = {key: topo["routers"][key] for key in ["r3"]} | |
887 | result = verify_bgp_rib(tgen, addr_type, dut, input_dict) | |
888 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
889 | tc_name, result | |
890 | ) | |
891 | ||
892 | # Verifying RIB routes before shutting down BGPd daemon | |
893 | result = verify_rib(tgen, addr_type, dut, input_dict) | |
894 | assert result is True, "Testcase {} : Failed \n Error {}".format( | |
895 | tc_name, result | |
896 | ) | |
897 | ||
898 | logger.info("[Step 2] : Kill BGPd daemon on R1..") | |
899 | ||
900 | # Kill BGPd daemon on R1 | |
901 | kill_router_daemons(tgen, "r1", ["bgpd"]) | |
902 | ||
903 | logger.info("[Step 3] : Withdraw advertised prefixes from R3...") | |
904 | ||
905 | # Api call to delete advertised networks | |
906 | network = {"ipv4": "103.0.20.1/32", "ipv6": "3::1/128"} | |
907 | for addr_type in ADDR_TYPES: | |
908 | input_dict = { | |
909 | "r3": { | |
910 | "bgp": { | |
911 | "address_family": { | |
912 | addr_type: { | |
913 | "unicast": { | |
914 | "advertise_networks": [ | |
915 | { | |
916 | "network": network[addr_type], | |
917 | "no_of_network": 5, | |
918 | "delete": True, | |
919 | } | |
920 | ] | |
921 | } | |
922 | } | |
923 | } | |
924 | } | |
925 | } | |
926 | } | |
927 | ||
928 | result = create_router_bgp(tgen, topo, input_dict) | |
929 | assert result is True, "Testcase {} : Failed \n Error: {}".format( | |
930 | tc_name, result | |
931 | ) | |
932 | ||
933 | logger.info("[Step 4] : Start BGPd daemon on R1..") | |
934 | ||
935 | # Start BGPd daemon on R1 | |
936 | start_router_daemons(tgen, "r1", ["bgpd"]) | |
937 | ||
938 | for addr_type in ADDR_TYPES: | |
939 | # Verifying BGP RIB routes before shutting down BGPd daemon | |
940 | input_dict = {key: topo["routers"][key] for key in ["r3"]} | |
941 | result = verify_bgp_rib(tgen, addr_type, dut, input_dict, expected=False) | |
942 | assert result is not True, ( | |
943 | "Testcase {} : Failed \n " | |
944 | "r1: routes are still present in BGP RIB\n Error: {}".format( | |
945 | tc_name, result | |
946 | ) | |
947 | ) | |
948 | logger.info(" Expected behavior: {}".format(result)) | |
949 | ||
950 | # Verifying RIB routes before shutting down BGPd daemon | |
951 | result = verify_rib(tgen, addr_type, dut, input_dict, expected=False) | |
952 | assert result is not True, ( | |
953 | "Testcase {} : Failed \n " | |
954 | "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result) | |
955 | ) | |
956 | logger.info(" Expected behavior: {}".format(result)) | |
957 | ||
958 | write_test_footer(tc_name) | |
959 | ||
960 | ||
961 | def test_BGP_GR_15_p2(request): | |
962 | """ | |
963 | Test Objective : Test GR scenarios by enabling Graceful Restart | |
964 | for multiple address families.. | |
965 | """ | |
966 | ||
967 | tgen = get_topogen() | |
968 | tc_name = request.node.name | |
969 | write_test_header(tc_name) | |
970 | ||
971 | # Check router status | |
972 | check_router_status(tgen) | |
973 | ||
974 | # Don't run this test if we have any failure. | |
975 | if tgen.routers_have_failure(): | |
976 | pytest.skip(tgen.errors) | |
977 | ||
978 | # Creating configuration from JSON | |
979 | reset_config_on_routers(tgen) | |
980 | ||
981 | # Configure graceful-restart | |
982 | input_dict = { | |
983 | "r1": { | |
984 | "bgp": { | |
985 | "address_family": { | |
986 | "ipv4": { | |
987 | "unicast": { | |
988 | "neighbor": { | |
989 | "r6": {"dest_link": {"r1": {"graceful-restart": True}}} | |
990 | } | |
991 | } | |
992 | }, | |
993 | "ipv6": { | |
994 | "unicast": { | |
995 | "neighbor": { | |
996 | "r6": {"dest_link": {"r1": {"graceful-restart": True}}} | |
997 | } | |
998 | } | |
999 | }, | |
1000 | } | |
1001 | } | |
1002 | }, | |
1003 | "r6": { | |
1004 | "bgp": { | |
1005 | "address_family": { | |
1006 | "ipv4": { | |
1007 | "unicast": { | |
1008 | "neighbor": { | |
1009 | "r1": { | |
1010 | "dest_link": { | |
1011 | "r6": {"graceful-restart-helper": True} | |
1012 | } | |
1013 | } | |
1014 | } | |
1015 | } | |
1016 | }, | |
1017 | "ipv6": { | |
1018 | "unicast": { | |
1019 | "neighbor": { | |
1020 | "r1": { | |
1021 | "dest_link": { | |
1022 | "r6": {"graceful-restart-helper": True} | |
1023 | } | |
1024 | } | |
1025 | } | |
1026 | } | |
1027 | }, | |
1028 | } | |
1029 | } | |
1030 | }, | |
1031 | } | |
1032 | ||
1033 | configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r6") | |
1034 | ||
1035 | for addr_type in ADDR_TYPES: | |
1036 | result = verify_graceful_restart( | |
1037 | tgen, topo, addr_type, input_dict, dut="r1", peer="r6" | |
1038 | ) | |
1039 | assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) | |
1040 | ||
1041 | logger.info( | |
1042 | "[Step 2] : Test Setup " | |
1043 | "[Helper Mode]R6-----R1[Restart Mode]" | |
1044 | "--------R2[Helper Mode] Initilized" | |
1045 | ) | |
1046 | ||
1047 | # Configure graceful-restart | |
1048 | input_dict = { | |
1049 | "r1": { | |
1050 | "bgp": { | |
1051 | "address_family": { | |
1052 | "ipv4": { | |
1053 | "unicast": { | |
1054 | "neighbor": { | |
1055 | "r2": {"dest_link": {"r1": {"graceful-restart": True}}} | |
1056 | } | |
1057 | } | |
1058 | }, | |
1059 | "ipv6": { | |
1060 | "unicast": { | |
1061 | "neighbor": { | |
1062 | "r2": {"dest_link": {"r1": {"graceful-restart": True}}} | |
1063 | } | |
1064 | } | |
1065 | }, | |
1066 | } | |
1067 | } | |
1068 | }, | |
1069 | "r2": { | |
1070 | "bgp": { | |
1071 | "address_family": { | |
1072 | "ipv4": { | |
1073 | "unicast": { | |
1074 | "neighbor": { | |
1075 | "r1": { | |
1076 | "dest_link": { | |
1077 | "r2": {"graceful-restart-helper": True} | |
1078 | } | |
1079 | } | |
1080 | } | |
1081 | } | |
1082 | }, | |
1083 | "ipv6": { | |
1084 | "unicast": { | |
1085 | "neighbor": { | |
1086 | "r1": { | |
1087 | "dest_link": { | |
1088 | "r2": {"graceful-restart-helper": True} | |
1089 | } | |
1090 | } | |
1091 | } | |
1092 | } | |
1093 | }, | |
1094 | } | |
1095 | } | |
1096 | }, | |
1097 | } | |
1098 | ||
1099 | configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2") | |
1100 | ||
1101 | for addr_type in ADDR_TYPES: | |
1102 | result = verify_graceful_restart( | |
1103 | tgen, topo, addr_type, input_dict, dut="r1", peer="r2" | |
1104 | ) | |
1105 | assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) | |
1106 | ||
1107 | # Verifying BGP RIB routes | |
1108 | dut = "r6" | |
1109 | input_dict_1 = {key: topo["routers"][key] for key in ["r1"]} | |
1110 | result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1) | |
1111 | assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) | |
1112 | ||
1113 | # Verifying RIB routes before shutting down BGPd daemon | |
1114 | result = verify_rib(tgen, addr_type, dut, input_dict_1) | |
1115 | assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) | |
1116 | ||
1117 | # Verifying BGP RIB routes | |
1118 | dut = "r6" | |
1119 | input_dict_2 = {key: topo["routers"][key] for key in ["r2"]} | |
1120 | result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2) | |
1121 | assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) | |
1122 | ||
1123 | # Verifying RIB routes before shutting down BGPd daemon | |
1124 | result = verify_rib(tgen, addr_type, dut, input_dict_2) | |
1125 | assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) | |
1126 | ||
1127 | # Kill BGPd daemon on R1 | |
1128 | kill_router_daemons(tgen, "r1", ["bgpd"]) | |
1129 | ||
1130 | for addr_type in ADDR_TYPES: | |
1131 | # Verifying BGP RIB routes | |
1132 | dut = "r6" | |
1133 | input_dict_1 = {key: topo["routers"][key] for key in ["r1"]} | |
1134 | result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1) | |
1135 | assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) | |
1136 | ||
1137 | # Verifying RIB routes before shutting down BGPd daemon | |
1138 | result = verify_rib(tgen, addr_type, dut, input_dict_1) | |
1139 | assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) | |
1140 | ||
1141 | # Verifying BGP RIB routes | |
1142 | dut = "r6" | |
1143 | input_dict_2 = {key: topo["routers"][key] for key in ["r2"]} | |
1144 | result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2) | |
1145 | assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) | |
1146 | ||
1147 | # Verifying RIB routes before shutting down BGPd daemon | |
1148 | result = verify_rib(tgen, addr_type, dut, input_dict_2) | |
1149 | assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) | |
1150 | ||
1151 | # Start BGPd daemon on R1 | |
1152 | start_router_daemons(tgen, "r1", ["bgpd"]) | |
1153 | ||
1154 | for addr_type in ADDR_TYPES: | |
1155 | result = verify_bgp_convergence(tgen, topo) | |
1156 | assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) | |
1157 | ||
1158 | # Verifying BGP RIB routes | |
1159 | dut = "r6" | |
1160 | input_dict_1 = {key: topo["routers"][key] for key in ["r1"]} | |
1161 | result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1) | |
1162 | assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) | |
1163 | ||
1164 | # Verifying RIB routes before shutting down BGPd daemon | |
1165 | result = verify_rib(tgen, addr_type, dut, input_dict_1) | |
1166 | assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) | |
1167 | ||
1168 | # Verifying BGP RIB routes | |
1169 | dut = "r6" | |
1170 | input_dict_2 = {key: topo["routers"][key] for key in ["r2"]} | |
1171 | result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2) | |
1172 | assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) | |
1173 | ||
1174 | # Verifying RIB routes before shutting down BGPd daemon | |
1175 | result = verify_rib(tgen, addr_type, dut, input_dict_2) | |
1176 | assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) | |
1177 | ||
1178 | write_test_footer(tc_name) | |
1179 | ||
1180 | ||
1181 | def BGP_GR_TC_7_p1(request): | |
1182 | """ | |
1183 | Verify that BGP restarting node deletes all the routes received from peer | |
1184 | if BGP Graceful capability is not present in BGP Open message from the | |
1185 | peer | |
1186 | """ | |
1187 | ||
1188 | tgen = get_topogen() | |
1189 | tc_name = request.node.name | |
1190 | write_test_header(tc_name) | |
1191 | ||
1192 | # Check router status | |
1193 | check_router_status(tgen) | |
1194 | ||
1195 | # Don't run this test if we have any failure. | |
1196 | if tgen.routers_have_failure(): | |
1197 | pytest.skip(tgen.errors) | |
1198 | ||
1199 | # Creating configuration from JSON | |
1200 | reset_config_on_routers(tgen) | |
1201 | ||
1202 | logger.info( | |
1203 | " Verify route download to RIB: BGP_GR_TC_7 >> " | |
1204 | "BGP GR [Helper Mode]R3-----R1[Restart Mode] " | |
1205 | ) | |
1206 | ||
1207 | # Configure graceful-restart | |
1208 | input_dict = { | |
1209 | "r3": { | |
1210 | "bgp": { | |
1211 | "address_family": { | |
1212 | "ipv4": { | |
1213 | "unicast": { | |
1214 | "neighbor": { | |
1215 | "r1": { | |
1216 | "dest_link": { | |
1217 | "r3": {"graceful-restart-helper": True} | |
1218 | } | |
1219 | } | |
1220 | } | |
1221 | } | |
1222 | }, | |
1223 | "ipv6": { | |
1224 | "unicast": { | |
1225 | "neighbor": { | |
1226 | "r1": { | |
1227 | "dest_link": { | |
1228 | "r3": {"graceful-restart-helper": True} | |
1229 | } | |
1230 | } | |
1231 | } | |
1232 | } | |
1233 | }, | |
1234 | } | |
1235 | } | |
1236 | }, | |
1237 | "r1": { | |
1238 | "bgp": { | |
1239 | "graceful-restart": { | |
1240 | "graceful-restart": True, | |
1241 | "preserve-fw-state": True, | |
1242 | }, | |
1243 | "address_family": { | |
1244 | "ipv4": { | |
1245 | "unicast": { | |
1246 | "neighbor": { | |
1247 | "r3": {"dest_link": {"r1": {"graceful-restart": True}}} | |
1248 | } | |
1249 | } | |
1250 | }, | |
1251 | "ipv6": { | |
1252 | "unicast": { | |
1253 | "neighbor": { | |
1254 | "r3": {"dest_link": {"r1": {"graceful-restart": True}}} | |
1255 | } | |
1256 | } | |
1257 | }, | |
1258 | }, | |
1259 | } | |
1260 | }, | |
1261 | } | |
1262 | ||
1263 | configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r3") | |
1264 | ||
1265 | for addr_type in ADDR_TYPES: | |
1266 | result = verify_graceful_restart( | |
1267 | tgen, topo, addr_type, input_dict, dut="r1", peer="r3" | |
1268 | ) | |
1269 | assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) | |
1270 | ||
1271 | # Verifying BGP RIB routes received from router R1 | |
1272 | dut = "r1" | |
1273 | input_dict_1 = {key: topo["routers"][key] for key in ["r3"]} | |
1274 | result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1) | |
1275 | assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) | |
1276 | ||
1277 | # Verifying RIB routes | |
1278 | result = verify_rib(tgen, addr_type, dut, input_dict_1) | |
1279 | assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) | |
1280 | ||
1281 | logger.info("R1 goes for reload") | |
1282 | kill_router_daemons(tgen, "r1", ["bgpd"]) | |
1283 | ||
1284 | # Change the configuration on router R1 | |
1285 | input_dict_2 = { | |
1286 | "r3": { | |
1287 | "bgp": { | |
1288 | "address_family": { | |
1289 | "ipv4": { | |
1290 | "unicast": { | |
1291 | "neighbor": { | |
1292 | "r1": { | |
1293 | "dest_link": { | |
1294 | "r3": {"graceful-restart-disable": True} | |
1295 | } | |
1296 | } | |
1297 | } | |
1298 | } | |
1299 | }, | |
1300 | "ipv6": { | |
1301 | "unicast": { | |
1302 | "neighbor": { | |
1303 | "r1": { | |
1304 | "dest_link": { | |
1305 | "r3": {"graceful-restart-disable": True} | |
1306 | } | |
1307 | } | |
1308 | } | |
1309 | } | |
1310 | }, | |
1311 | } | |
1312 | } | |
1313 | } | |
1314 | } | |
1315 | ||
1316 | result = create_router_bgp(tgen, topo, input_dict_2) | |
1317 | assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) | |
1318 | ||
1319 | # Change the configuration on R1 | |
1320 | network = {"ipv4": "103.0.20.1/32", "ipv6": "3::1/128"} | |
1321 | for addr_type in ADDR_TYPES: | |
1322 | input_dict_2 = { | |
1323 | "r3": { | |
1324 | "bgp": { | |
1325 | "address_family": { | |
1326 | addr_type: { | |
1327 | "unicast": { | |
1328 | "advertise_networks": [ | |
1329 | { | |
1330 | "network": network[addr_type], | |
1331 | "no_of_network": 5, | |
1332 | "delete": True, | |
1333 | } | |
1334 | ] | |
1335 | } | |
1336 | } | |
1337 | } | |
1338 | } | |
1339 | } | |
1340 | } | |
1341 | ||
1342 | result = create_router_bgp(tgen, topo, input_dict_2) | |
1343 | assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) | |
1344 | ||
1345 | logger.info("R1 is about to come up now") | |
1346 | start_router_daemons(tgen, "r1", ["bgpd"]) | |
1347 | logger.info("R1 is UP Now") | |
1348 | ||
1349 | # Wait for RIB stale timeout | |
1350 | logger.info("Verify routes are not present" "in restart router") | |
1351 | ||
1352 | for addr_type in ADDR_TYPES: | |
1353 | # Verifying RIB routes | |
1354 | dut = "r1" | |
1355 | input_dict_1 = {key: topo["routers"][key] for key in ["r3"]} | |
1356 | result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False) | |
1357 | assert result is not True, ( | |
1358 | "Testcase {} : Failed \n " | |
1359 | "r1: routes are still present in ZEBRA\n Error: {}".format(tc_name, result) | |
1360 | ) | |
1361 | ||
1362 | write_test_footer(tc_name) | |
1363 | ||
1364 | ||
1365 | if __name__ == "__main__": | |
1366 | args = ["-s"] + sys.argv[1:] | |
1367 | sys.exit(pytest.main(args)) |