]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / tests / topotests / bgp_multi_vrf_topo2 / test_bgp_multi_vrf_topo2.py
1 #!/usr/bin/env python
2 # SPDX-License-Identifier: ISC
3
4 #
5 # Copyright (c) 2020 by VMware, Inc. ("VMware")
6 # Used Copyright (c) 2018 by Network Device Education Foundation,
7 # Inc. ("NetDEF") in this file.
8 #
9
10 """
11 Following tests are covered to test BGP Multi-VRF:
12
13 CHAOS_1:
14 Do a shut and no shut on connecting interface of DUT,
15 to see if all vrf instances clear their respective BGP tables
16 during the interface down and restores when interface brought
17 kCHAOS_3:
18 VRF leaking - next-hop interface is flapping.
19 CHAOS_5:
20 VRF - VLANs - Routing Table ID - combination testcase
21 on DUT.
22 CHAOS_9:
23 Verify that all vrf instances fall back
24 to backup path, if primary link goes down.
25 CHAOS_6:
26 Restart BGPd daemon on DUT to check if all the
27 routes in respective vrfs are reinstalled..
28 CHAOS_2:
29 Delete a VRF instance from DUT and check if the routes get
30 deleted from subsequent neighbour routers and appears again once VRF
31 is re-added.
32 CHAOS_4:
33 Verify that VRF names are locally significant
34 to a router, and end to end connectivity depends on unique
35 virtual circuits (using VLANs or separate physical interfaces).
36 CHAOS_8:
37 Restart all FRR services (reboot DUT) to check if all
38 the routes in respective vrfs are reinstalled.
39 """
40
41 import os
42 import sys
43 import time
44 import pytest
45 from copy import deepcopy
46 from time import sleep
47
48
49 # Save the Current Working Directory to find configuration files.
50 CWD = os.path.dirname(os.path.realpath(__file__))
51 sys.path.append(os.path.join(CWD, "../"))
52 sys.path.append(os.path.join(CWD, "../lib/"))
53
54 # Required to instantiate the topology builder class.
55
56 # pylint: disable=C0413
57 # Import topogen and topotest helpers
58 from lib.topogen import Topogen, get_topogen
59 from lib.topotest import iproute2_is_vrf_capable
60 from lib.common_config import (
61 step,
62 verify_rib,
63 start_topology,
64 write_test_header,
65 check_address_types,
66 write_test_footer,
67 reset_config_on_routers,
68 create_route_maps,
69 shutdown_bringup_interface,
70 start_router_daemons,
71 create_static_routes,
72 create_vrf_cfg,
73 create_interfaces_cfg,
74 create_interface_in_kernel,
75 get_frr_ipv6_linklocal,
76 check_router_status,
77 apply_raw_config,
78 required_linux_kernel_version,
79 kill_router_daemons,
80 start_router_daemons,
81 stop_router,
82 start_router,
83 )
84
85 from lib.topolog import logger
86 from lib.bgp import clear_bgp, verify_bgp_rib, create_router_bgp, verify_bgp_convergence
87 from lib.topojson import build_config_from_json
88
89
90 pytestmark = [pytest.mark.bgpd, pytest.mark.staticd]
91
92
93 # Global variables
94 NETWORK1_1 = {"ipv4": "1.1.1.1/32", "ipv6": "1::1/128"}
95 NETWORK1_2 = {"ipv4": "1.1.1.2/32", "ipv6": "1::2/128"}
96 NETWORK2_1 = {"ipv4": "2.1.1.1/32", "ipv6": "2::1/128"}
97 NETWORK2_2 = {"ipv4": "2.1.1.2/32", "ipv6": "2::2/128"}
98 NETWORK3_1 = {"ipv4": "3.1.1.1/32", "ipv6": "3::1/128"}
99 NETWORK3_2 = {"ipv4": "3.1.1.2/32", "ipv6": "3::2/128"}
100 NETWORK4_1 = {"ipv4": "4.1.1.1/32", "ipv6": "4::1/128"}
101 NETWORK4_2 = {"ipv4": "4.1.1.2/32", "ipv6": "4::2/128"}
102 NETWORK9_1 = {"ipv4": "100.1.0.1/30", "ipv6": "100::1/126"}
103 NETWORK9_2 = {"ipv4": "100.1.0.2/30", "ipv6": "100::2/126"}
104
105 NEXT_HOP_IP = {"ipv4": "Null0", "ipv6": "Null0"}
106
107 LOOPBACK_2 = {
108 "ipv4": "20.20.20.20/32",
109 "ipv6": "20::20:20/128",
110 }
111
112 MAX_PATHS = 2
113 KEEPALIVETIMER = 1
114 HOLDDOWNTIMER = 3
115 PREFERRED_NEXT_HOP = "link_local"
116
117
118 def setup_module(mod):
119 """
120 Sets up the pytest environment
121
122 * `mod`: module name
123 """
124 # Required linux kernel version for this suite to run.
125 result = required_linux_kernel_version("4.14")
126 if result is not True:
127 pytest.skip("Kernel requirements are not met")
128
129 # iproute2 needs to support VRFs for this suite to run.
130 if not iproute2_is_vrf_capable():
131 pytest.skip("Installed iproute2 version does not support VRFs")
132
133 testsuite_run_time = time.asctime(time.localtime(time.time()))
134 logger.info("Testsuite start time: {}".format(testsuite_run_time))
135 logger.info("=" * 40)
136
137 logger.info("Running setup_module to create topology")
138
139 # This function initiates the topology build with Topogen...
140 json_file = "{}/bgp_multi_vrf_topo2.json".format(CWD)
141 tgen = Topogen(json_file, mod.__name__)
142 global topo
143 topo = tgen.json_topo
144 # ... and here it calls Mininet initialization functions.
145
146 # Starting topology, create tmp files which are loaded to routers
147 # to start daemons and then start routers
148 start_topology(tgen)
149
150 # Creating configuration from JSON
151 build_config_from_json(tgen, topo)
152
153 global BGP_CONVERGENCE
154 global ADDR_TYPES
155 ADDR_TYPES = check_address_types()
156
157 BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
158 assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error: {}".format(
159 BGP_CONVERGENCE
160 )
161
162 logger.info("Running setup_module() done")
163
164
165 def teardown_module():
166 """Teardown the pytest environment"""
167
168 logger.info("Running teardown_module to delete topology")
169
170 tgen = get_topogen()
171
172 # Stop toplogy and Remove tmp files
173 tgen.stop_topology()
174
175 logger.info(
176 "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
177 )
178 logger.info("=" * 40)
179
180
181 #####################################################
182 #
183 # Testcases
184 #
185 #####################################################
186
187
188 def test_vrf_with_multiple_links_p1(request):
189 """
190 CHAOS_9:
191 Verify that all vrf instances fall back
192 to backup path, if primary link goes down.
193 """
194
195 tgen = get_topogen()
196 tc_name = request.node.name
197 write_test_header(tc_name)
198
199 if tgen.routers_have_failure():
200 check_router_status(tgen)
201
202 step(
203 "Configure BGP neighborships(IPv4+IPv6) between R1 and R4 "
204 "using exact same link IPs for all 4 VRFs."
205 )
206
207 topo_modify = deepcopy(topo)
208 build_config_from_json(tgen, topo_modify)
209
210 interfaces = ["link1", "link2", "link3", "link4"]
211 for interface in interfaces:
212 topo_modify["routers"]["r1"]["links"]["r4-{}".format(interface)][
213 "delete"
214 ] = True
215 topo_modify["routers"]["r4"]["links"]["r1-{}".format(interface)][
216 "delete"
217 ] = True
218
219 step("Build interface config from json")
220 create_interfaces_cfg(tgen, topo_modify["routers"])
221
222 interfaces = ["link1", "link2", "link3", "link4"]
223 for interface in interfaces:
224 del topo_modify["routers"]["r1"]["links"]["r4-{}".format(interface)]["delete"]
225 del topo_modify["routers"]["r4"]["links"]["r1-{}".format(interface)]["delete"]
226
227 r1_config = []
228 r4_config = []
229 for addr_type in ADDR_TYPES:
230 interfaces = ["link1", "link2", "link3", "link4"]
231 for interface in interfaces:
232 intf_name_r1 = topo_modify["routers"]["r1"]["links"][
233 "r4-{}".format(interface)
234 ]["interface"]
235 topo_modify["routers"]["r1"]["links"]["r4-{}".format(interface)][
236 addr_type
237 ] = NETWORK9_1[addr_type]
238
239 intf_name_r4 = topo_modify["routers"]["r4"]["links"][
240 "r1-{}".format(interface)
241 ]["interface"]
242 topo_modify["routers"]["r4"]["links"]["r1-{}".format(interface)][
243 addr_type
244 ] = NETWORK9_2[addr_type]
245
246 r1_config.append("interface {}".format(intf_name_r1))
247 r4_config.append("interface {}".format(intf_name_r4))
248 if addr_type == "ipv4":
249 r1_config.append("no ip address {}".format(NETWORK9_1[addr_type]))
250 r4_config.append("no ip address {}".format(NETWORK9_2[addr_type]))
251 else:
252 r1_config.append("no ipv6 address {}".format(NETWORK9_1[addr_type]))
253 r4_config.append("no ipv6 address {}".format(NETWORK9_2[addr_type]))
254
255 step("Build interface config from json")
256 create_interfaces_cfg(tgen, topo_modify["routers"])
257
258 step("Create bgp config")
259 result = create_router_bgp(tgen, topo_modify["routers"])
260 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
261
262 step("Verify BGP convergence")
263
264 result = verify_bgp_convergence(tgen, topo_modify)
265 assert result is True, "Testcase {} : Failed \n Error {}".format(tc_name, result)
266
267 step(
268 "Advertise below prefixes in BGP using static redistribution"
269 " for both vrfs (RED_A and BLUE_A) on router R2.."
270 )
271
272 for addr_type in ADDR_TYPES:
273 input_dict_1 = {
274 "r1": {
275 "static_routes": [
276 {
277 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
278 "next_hop": NEXT_HOP_IP[addr_type],
279 "vrf": "RED_A",
280 },
281 {
282 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
283 "next_hop": NEXT_HOP_IP[addr_type],
284 "vrf": "BLUE_A",
285 },
286 {
287 "network": [NETWORK3_1[addr_type]] + [NETWORK3_2[addr_type]],
288 "next_hop": NEXT_HOP_IP[addr_type],
289 "vrf": "RED_B",
290 },
291 {
292 "network": [NETWORK4_1[addr_type]] + [NETWORK4_2[addr_type]],
293 "next_hop": NEXT_HOP_IP[addr_type],
294 "vrf": "BLUE_B",
295 },
296 ]
297 }
298 }
299 result = create_static_routes(tgen, input_dict_1)
300 assert result is True, "Testcase {} : Failed \n Error: {}".format(
301 tc_name, result
302 )
303
304 step("Redistribute static..")
305
306 input_dict_3 = {}
307 for dut in ["r1"]:
308 temp = {dut: {"bgp": []}}
309 input_dict_3.update(temp)
310
311 VRFS = ["RED_A", "RED_B", "BLUE_A", "BLUE_B"]
312 AS_NUM = [100, 100, 100, 100]
313
314 for vrf, as_num in zip(VRFS, AS_NUM):
315 temp[dut]["bgp"].append(
316 {
317 "local_as": as_num,
318 "vrf": vrf,
319 "address_family": {
320 "ipv4": {
321 "unicast": {"redistribute": [{"redist_type": "static"}]}
322 },
323 "ipv6": {
324 "unicast": {"redistribute": [{"redist_type": "static"}]}
325 },
326 },
327 }
328 )
329
330 result = create_router_bgp(tgen, topo_modify, input_dict_3)
331 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
332
333 step("Verify routes are installed with same nexthop in different" " VRFs")
334 result = verify_bgp_convergence(tgen, topo_modify)
335 assert result is True, "Testcase {} : Failed \n Error {}".format(tc_name, result)
336
337 for addr_type in ADDR_TYPES:
338 dut = "r4"
339 _input_dict = {
340 "r1": {
341 "static_routes": [
342 {
343 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
344 "next_hop": NEXT_HOP_IP[addr_type],
345 "vrf": "RED_A",
346 }
347 ]
348 }
349 }
350
351 R1_NEXTHOP = topo_modify["routers"]["r1"]["links"]["r4-link1"][addr_type].split(
352 "/"
353 )[0]
354
355 result = verify_rib(tgen, addr_type, dut, _input_dict, next_hop=R1_NEXTHOP)
356 assert result is True, "Testcase {} : Failed \n Error {}".format(
357 tc_name, result
358 )
359
360 _input_dict = {
361 "r1": {
362 "static_routes": [
363 {
364 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
365 "next_hop": NEXT_HOP_IP[addr_type],
366 "vrf": "BLUE_A",
367 }
368 ]
369 }
370 }
371
372 R1_NEXTHOP = topo_modify["routers"]["r1"]["links"]["r4-link1"][addr_type].split(
373 "/"
374 )[0]
375
376 result = verify_rib(tgen, addr_type, dut, _input_dict, next_hop=R1_NEXTHOP)
377 assert result is True, "Testcase {} : Failed \n Error {}".format(
378 tc_name, result
379 )
380
381 _input_dict = {
382 "r1": {
383 "static_routes": [
384 {
385 "network": [NETWORK3_1[addr_type]] + [NETWORK3_2[addr_type]],
386 "next_hop": NEXT_HOP_IP[addr_type],
387 "vrf": "RED_B",
388 }
389 ]
390 }
391 }
392
393 R1_NEXTHOP = topo_modify["routers"]["r1"]["links"]["r4-link1"][addr_type].split(
394 "/"
395 )[0]
396
397 result = verify_rib(tgen, addr_type, dut, _input_dict, next_hop=R1_NEXTHOP)
398 assert result is True, "Testcase {} : Failed \n Error {}".format(
399 tc_name, result
400 )
401
402 _input_dict = {
403 "r1": {
404 "static_routes": [
405 {
406 "network": [NETWORK4_1[addr_type]] + [NETWORK4_2[addr_type]],
407 "next_hop": NEXT_HOP_IP[addr_type],
408 "vrf": "BLUE_B",
409 }
410 ]
411 }
412 }
413
414 R1_NEXTHOP = topo_modify["routers"]["r1"]["links"]["r4-link1"][addr_type].split(
415 "/"
416 )[0]
417
418 result = verify_rib(tgen, addr_type, dut, _input_dict, next_hop=R1_NEXTHOP)
419 assert result is True, "Testcase {} : Failed \n Error {}".format(
420 tc_name, result
421 )
422
423 step(
424 "Configure a route-map on R3 to prepend as-path and apply"
425 " for neighbour router R2 in both vrfs, in inbound direction."
426 )
427
428 input_dict_4 = {
429 "r3": {
430 "route_maps": {
431 "ASP": [
432 {
433 "action": "permit",
434 "set": {"path": {"as_num": 123, "as_action": "prepend"}},
435 }
436 ]
437 }
438 }
439 }
440 result = create_route_maps(tgen, input_dict_4)
441 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
442
443 step("Apply route-map to neighbours")
444 step(
445 "Configure ECMP on router R3 using 'max-path' command for both"
446 " VRFs RED_A and BLUE_A."
447 )
448
449 input_dict_5 = {
450 "r3": {
451 "bgp": [
452 {
453 "local_as": "200",
454 "vrf": "RED_A",
455 "address_family": {
456 "ipv4": {
457 "unicast": {
458 "neighbor": {
459 "r2": {
460 "dest_link": {
461 "r3-link1": {
462 "route_maps": [
463 {"name": "ASP", "direction": "in"}
464 ]
465 }
466 }
467 }
468 }
469 }
470 },
471 "ipv6": {
472 "unicast": {
473 "neighbor": {
474 "r2": {
475 "dest_link": {
476 "r3-link1": {
477 "route_maps": [
478 {"name": "ASP", "direction": "in"}
479 ]
480 }
481 }
482 },
483 "r4": {
484 "dest_link": {
485 "r3-link1": {
486 "route_maps": [
487 {
488 "name": "rmap_global",
489 "direction": "in",
490 }
491 ]
492 }
493 }
494 },
495 }
496 }
497 },
498 },
499 },
500 {
501 "local_as": "200",
502 "vrf": "RED_B",
503 "address_family": {
504 "ipv4": {
505 "unicast": {
506 "neighbor": {
507 "r2": {
508 "dest_link": {
509 "r3-link2": {
510 "route_maps": [
511 {"name": "ASP", "direction": "in"}
512 ]
513 }
514 }
515 }
516 }
517 }
518 },
519 "ipv6": {
520 "unicast": {
521 "neighbor": {
522 "r2": {
523 "dest_link": {
524 "r3-link2": {
525 "route_maps": [
526 {"name": "ASP", "direction": "in"}
527 ]
528 }
529 }
530 }
531 }
532 }
533 },
534 },
535 },
536 {
537 "local_as": "200",
538 "vrf": "BLUE_A",
539 "address_family": {
540 "ipv4": {
541 "unicast": {
542 "neighbor": {
543 "r2": {
544 "dest_link": {
545 "r3-link3": {
546 "route_maps": [
547 {"name": "ASP", "direction": "in"}
548 ]
549 }
550 }
551 }
552 }
553 }
554 },
555 "ipv6": {
556 "unicast": {
557 "neighbor": {
558 "r2": {
559 "dest_link": {
560 "r3-link3": {
561 "route_maps": [
562 {"name": "ASP", "direction": "in"}
563 ]
564 }
565 }
566 },
567 "r4": {
568 "dest_link": {
569 "r3-link3": {
570 "route_maps": [
571 {
572 "name": "rmap_global",
573 "direction": "in",
574 }
575 ]
576 }
577 }
578 },
579 }
580 }
581 },
582 },
583 },
584 {
585 "local_as": "200",
586 "vrf": "BLUE_B",
587 "address_family": {
588 "ipv4": {
589 "unicast": {
590 "neighbor": {
591 "r2": {
592 "dest_link": {
593 "r3-link4": {
594 "route_maps": [
595 {"name": "ASP", "direction": "in"}
596 ]
597 }
598 }
599 }
600 }
601 }
602 },
603 "ipv6": {
604 "unicast": {
605 "neighbor": {
606 "r2": {
607 "dest_link": {
608 "r3-link4": {
609 "route_maps": [
610 {"name": "ASP", "direction": "in"}
611 ]
612 }
613 }
614 }
615 }
616 }
617 },
618 },
619 },
620 ]
621 }
622 }
623
624 result = create_router_bgp(tgen, topo_modify, input_dict_5)
625 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
626
627 result = verify_bgp_convergence(tgen, topo_modify)
628 assert result is True, "Testcase {} : Failed \n Error {}".format(tc_name, result)
629
630 for addr_type in ADDR_TYPES:
631 dut = "r3"
632 peer = "r2"
633 input_dict = {
634 "r2": {
635 "static_routes": [
636 {
637 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
638 "vrf": "RED_A",
639 }
640 ]
641 }
642 }
643
644 intf = topo_modify["routers"][peer]["links"]["r3-link1"]["interface"]
645 if addr_type == "ipv6" and "link_local" in PREFERRED_NEXT_HOP:
646 R2_NEXTHOP = get_frr_ipv6_linklocal(tgen, peer, intf=intf, vrf="RED_A")
647 else:
648 R2_NEXTHOP = topo_modify["routers"]["r2"]["links"]["r3-link1"][
649 addr_type
650 ].split("/")[0]
651
652 result = verify_rib(tgen, addr_type, dut, input_dict, next_hop=R2_NEXTHOP)
653 assert result is True, "Testcase {} : Failed \n Error {}".format(
654 tc_name, result
655 )
656
657 input_dict = {
658 "r2": {
659 "static_routes": [
660 {
661 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
662 "vrf": "BLUE_A",
663 }
664 ]
665 }
666 }
667
668 intf = topo["routers"][peer]["links"]["r3-link3"]["interface"]
669 if addr_type == "ipv6" and "link_local" in PREFERRED_NEXT_HOP:
670 R2_NEXTHOP = get_frr_ipv6_linklocal(tgen, peer, intf=intf, vrf="BLUE_A")
671 else:
672 R2_NEXTHOP = topo_modify["routers"]["r2"]["links"]["r3-link3"][
673 addr_type
674 ].split("/")[0]
675
676 result = verify_rib(tgen, addr_type, dut, input_dict, next_hop=R2_NEXTHOP)
677 assert result is True, "Testcase {} : Failed \n Error {}".format(
678 tc_name, result
679 )
680
681 step(
682 "Configure ECMP on router R3 using max-path command for"
683 " both VRFs RED_A and BLUE_A."
684 )
685
686 input_dict_7 = {
687 "r3": {
688 "bgp": [
689 {
690 "local_as": "200",
691 "vrf": "RED_A",
692 "address_family": {
693 "ipv4": {
694 "unicast": {
695 "maximum_paths": {
696 "ebgp": MAX_PATHS,
697 }
698 }
699 },
700 "ipv6": {
701 "unicast": {
702 "maximum_paths": {
703 "ebgp": MAX_PATHS,
704 }
705 }
706 },
707 },
708 },
709 {
710 "local_as": "200",
711 "vrf": "BLUE_A",
712 "address_family": {
713 "ipv4": {
714 "unicast": {
715 "maximum_paths": {
716 "ebgp": MAX_PATHS,
717 }
718 }
719 },
720 "ipv6": {
721 "unicast": {
722 "maximum_paths": {
723 "ebgp": MAX_PATHS,
724 }
725 }
726 },
727 },
728 },
729 ]
730 }
731 }
732
733 result = create_router_bgp(tgen, topo_modify, input_dict_7)
734 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
735
736 step("R3 should install prefixes from both next-hops (R2 and R4)")
737 result = verify_bgp_convergence(tgen, topo_modify)
738 assert result is True, "Testcase {} : Failed \n Error {}".format(tc_name, result)
739
740 for addr_type in ADDR_TYPES:
741 dut = "r3"
742 peer = "r2"
743 input_dict = {
744 "r2": {
745 "static_routes": [
746 {
747 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
748 "vrf": "RED_A",
749 }
750 ]
751 }
752 }
753
754 intf = topo_modify["routers"][peer]["links"]["r3-link1"]["interface"]
755 if addr_type == "ipv6" and "link_local" in PREFERRED_NEXT_HOP:
756 R2_NEXTHOP = get_frr_ipv6_linklocal(tgen, peer, intf=intf, vrf="RED_A")
757 else:
758 R2_NEXTHOP = topo_modify["routers"]["r2"]["links"]["r3-link1"][
759 addr_type
760 ].split("/")[0]
761
762 result = verify_rib(tgen, addr_type, dut, input_dict, next_hop=R2_NEXTHOP)
763 assert result is True, "Testcase {} : Failed \n Error {}".format(
764 tc_name, result
765 )
766
767 input_dict = {
768 "r2": {
769 "static_routes": [
770 {
771 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
772 "vrf": "BLUE_A",
773 }
774 ]
775 }
776 }
777
778 intf = topo_modify["routers"][peer]["links"]["r3-link3"]["interface"]
779 if addr_type == "ipv6" and "link_local" in PREFERRED_NEXT_HOP:
780 R2_NEXTHOP = get_frr_ipv6_linklocal(tgen, peer, intf=intf, vrf="BLUE_A")
781 else:
782 R2_NEXTHOP = topo_modify["routers"]["r2"]["links"]["r3-link3"][
783 addr_type
784 ].split("/")[0]
785
786 result = verify_rib(tgen, addr_type, dut, input_dict, next_hop=R2_NEXTHOP)
787 assert result is True, "Testcase {} : Failed \n Error {}".format(
788 tc_name, result
789 )
790
791 step("Shutdown interface between R2 and R3 for vrfs RED_A and " "BLUE_A.")
792
793 intf1 = topo_modify["routers"]["r2"]["links"]["r3-link1"]["interface"]
794 intf2 = topo_modify["routers"]["r2"]["links"]["r3-link3"]["interface"]
795
796 interfaces = [intf1, intf2]
797 for intf in interfaces:
798 shutdown_bringup_interface(tgen, "r2", intf, False)
799
800 for addr_type in ADDR_TYPES:
801 dut = "r3"
802 peer = "r4"
803 input_dict = {
804 "r2": {
805 "static_routes": [
806 {
807 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
808 "vrf": "RED_A",
809 }
810 ]
811 }
812 }
813
814 R4_NEXTHOP = topo_modify["routers"]["r4"]["links"]["r3-link1"][addr_type].split(
815 "/"
816 )[0]
817
818 result = verify_rib(tgen, addr_type, dut, input_dict, next_hop=R4_NEXTHOP)
819 assert result is True, "Testcase {} : Failed \n Error {}".format(
820 tc_name, result
821 )
822
823 input_dict = {
824 "r2": {
825 "static_routes": [
826 {
827 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
828 "vrf": "BLUE_A",
829 }
830 ]
831 }
832 }
833
834 R4_NEXTHOP = topo_modify["routers"]["r4"]["links"]["r3-link3"][addr_type].split(
835 "/"
836 )[0]
837
838 result = verify_rib(tgen, addr_type, dut, input_dict, next_hop=R4_NEXTHOP)
839 assert result is True, "Testcase {} : Failed \n Error {}".format(
840 tc_name, result
841 )
842
843 step("Unshut the interfaces between R2 and R3 for vrfs RED_A and BLUE_A.")
844
845 for intf in interfaces:
846 shutdown_bringup_interface(tgen, "r2", intf, True)
847
848 for addr_type in ADDR_TYPES:
849 dut = "r3"
850 peer = "r2"
851 input_dict = {
852 "r2": {
853 "static_routes": [
854 {
855 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
856 "vrf": "RED_A",
857 }
858 ]
859 }
860 }
861
862 R4_NEXTHOP = topo_modify["routers"]["r4"]["links"]["r3-link1"][addr_type].split(
863 "/"
864 )[0]
865
866 result = verify_rib(tgen, addr_type, dut, input_dict, next_hop=R4_NEXTHOP)
867 assert result is True, "Testcase {} : Failed \n Error {}".format(
868 tc_name, result
869 )
870
871 input_dict = {
872 "r2": {
873 "static_routes": [
874 {
875 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
876 "vrf": "BLUE_A",
877 }
878 ]
879 }
880 }
881
882 R4_NEXTHOP = topo_modify["routers"]["r4"]["links"]["r3-link3"][addr_type].split(
883 "/"
884 )[0]
885
886 result = verify_rib(tgen, addr_type, dut, input_dict, next_hop=R4_NEXTHOP)
887 assert result is True, "Testcase {} : Failed \n Error {}".format(
888 tc_name, result
889 )
890
891 step("Remove route-map from R3 for vrfs RED_A and BLUE_A.")
892
893 input_dict_6 = {
894 "r3": {
895 "bgp": [
896 {
897 "local_as": "200",
898 "vrf": "RED_A",
899 "address_family": {
900 "ipv4": {
901 "unicast": {
902 "neighbor": {
903 "r2": {
904 "dest_link": {
905 "r3-link1": {
906 "route_maps": [
907 {
908 "name": "ASP_ipv4",
909 "direction": "in",
910 "delete": True,
911 }
912 ]
913 }
914 }
915 }
916 }
917 }
918 },
919 "ipv6": {
920 "unicast": {
921 "neighbor": {
922 "r2": {
923 "dest_link": {
924 "r3-link1": {
925 "route_maps": [
926 {
927 "name": "ASP_ipv6",
928 "direction": "in",
929 "delete": True,
930 },
931 {
932 "name": "rmap_global",
933 "direction": "in",
934 },
935 ]
936 }
937 }
938 }
939 }
940 }
941 },
942 },
943 },
944 {
945 "local_as": "200",
946 "vrf": "BLUE_A",
947 "address_family": {
948 "ipv4": {
949 "unicast": {
950 "neighbor": {
951 "r2": {
952 "dest_link": {
953 "r3-link3": {
954 "route_maps": [
955 {
956 "name": "ASP_ipv4",
957 "direction": "in",
958 "delete": True,
959 }
960 ]
961 }
962 }
963 }
964 }
965 }
966 },
967 "ipv6": {
968 "unicast": {
969 "neighbor": {
970 "r2": {
971 "dest_link": {
972 "r3-link3": {
973 "route_maps": [
974 {
975 "name": "ASP_ipv6",
976 "direction": "in",
977 "delete": True,
978 },
979 {
980 "name": "rmap_global",
981 "direction": "in",
982 },
983 ]
984 }
985 }
986 }
987 }
988 }
989 },
990 },
991 },
992 ]
993 }
994 }
995
996 result = create_router_bgp(tgen, topo_modify, input_dict_6)
997 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
998
999 result = verify_bgp_convergence(tgen, topo_modify)
1000 assert result is True, "Testcase {} : Failed \n Error {}".format(tc_name, result)
1001
1002 for addr_type in ADDR_TYPES:
1003 dut = "r3"
1004 input_dict = {
1005 "r2": {
1006 "static_routes": [
1007 {
1008 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
1009 "vrf": "RED_A",
1010 }
1011 ]
1012 }
1013 }
1014
1015 R2_NEXTHOP = topo_modify["routers"]["r2"]["links"]["r3-link1"][addr_type].split(
1016 "/"
1017 )[0]
1018
1019 result = verify_rib(tgen, addr_type, dut, input_dict, next_hop=R2_NEXTHOP)
1020 assert result is True, "Testcase {} : Failed \n Error {}".format(
1021 tc_name, result
1022 )
1023
1024 input_dict = {
1025 "r2": {
1026 "static_routes": [
1027 {
1028 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
1029 "vrf": "BLUE_A",
1030 }
1031 ]
1032 }
1033 }
1034
1035 R2_NEXTHOP = topo_modify["routers"]["r2"]["links"]["r3-link3"][addr_type].split(
1036 "/"
1037 )[0]
1038
1039 result = verify_rib(tgen, addr_type, dut, input_dict, next_hop=R2_NEXTHOP)
1040 assert result is True, "Testcase {} : Failed \n Error {}".format(
1041 tc_name, result
1042 )
1043
1044 step("Shutdown links between between R2 and R3 for vrfs RED_A and" " BLUE_A.")
1045
1046 for intf in interfaces:
1047 shutdown_bringup_interface(tgen, "r2", intf, False)
1048
1049 for addr_type in ADDR_TYPES:
1050 dut = "r3"
1051 input_dict = {
1052 "r2": {
1053 "static_routes": [
1054 {
1055 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
1056 "vrf": "RED_A",
1057 }
1058 ]
1059 }
1060 }
1061
1062 R4_NEXTHOP = topo_modify["routers"]["r4"]["links"]["r3-link1"][addr_type].split(
1063 "/"
1064 )[0]
1065
1066 result = verify_rib(tgen, addr_type, dut, input_dict, next_hop=R4_NEXTHOP)
1067 assert result is True, "Testcase {} : Failed \n Error {}".format(
1068 tc_name, result
1069 )
1070
1071 input_dict = {
1072 "r2": {
1073 "static_routes": [
1074 {
1075 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
1076 "vrf": "BLUE_A",
1077 }
1078 ]
1079 }
1080 }
1081
1082 R4_NEXTHOP = topo_modify["routers"]["r4"]["links"]["r3-link3"][addr_type].split(
1083 "/"
1084 )[0]
1085
1086 result = verify_rib(tgen, addr_type, dut, input_dict, next_hop=R4_NEXTHOP)
1087 assert result is True, "Testcase {} : Failed \n Error {}".format(
1088 tc_name, result
1089 )
1090
1091 step("Bringup links between between R2 and R3 for vrfs RED_A and" " BLUE_A.")
1092
1093 for intf in interfaces:
1094 shutdown_bringup_interface(tgen, "r2", intf, True)
1095
1096 step("Deleting manualy assigned ip address from router r1 and r4 interfaces")
1097 raw_config = {"r1": {"raw_config": r1_config}, "r4": {"raw_config": r4_config}}
1098 result = apply_raw_config(tgen, raw_config)
1099 assert result is True, "Testcase {} : Failed Error: {}".format(tc_name, result)
1100
1101 write_test_footer(tc_name)
1102
1103
1104 def test_shut_noshut_p1(request):
1105 """
1106 CHAOS_1:
1107 Do a shut and no shut on connecting interface of DUT,
1108 to see if all vrf instances clear their respective BGP tables
1109 during the interface down and restores when interface brought
1110 back up again.
1111 """
1112
1113 tgen = get_topogen()
1114 tc_name = request.node.name
1115 write_test_header(tc_name)
1116 reset_config_on_routers(tgen)
1117
1118 if tgen.routers_have_failure():
1119 check_router_status(tgen)
1120
1121 step("Build interface config from json")
1122 create_interfaces_cfg(tgen, topo["routers"])
1123
1124 if tgen.routers_have_failure():
1125 pytest.skip(tgen.errors)
1126
1127 step(
1128 "Advertise unique prefixes in BGP using static redistribution"
1129 " for both vrfs (RED_A and RED_B) on router RED_1."
1130 )
1131
1132 for addr_type in ADDR_TYPES:
1133 input_dict_1 = {
1134 "red1": {
1135 "static_routes": [
1136 {
1137 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
1138 "next_hop": NEXT_HOP_IP[addr_type],
1139 "vrf": "RED_A",
1140 },
1141 {
1142 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
1143 "next_hop": NEXT_HOP_IP[addr_type],
1144 "vrf": "RED_B",
1145 },
1146 ]
1147 }
1148 }
1149 result = create_static_routes(tgen, input_dict_1)
1150 assert result is True, "Testcase {} : Failed \n Error: {}".format(
1151 tc_name, result
1152 )
1153
1154 step(
1155 "Advertise unique prefixes in BGP using static redistribution"
1156 " for both vrfs (BLUE_A and BLUE_B) on router BLUE_1."
1157 )
1158
1159 for addr_type in ADDR_TYPES:
1160 input_dict_2 = {
1161 "blue1": {
1162 "static_routes": [
1163 {
1164 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
1165 "next_hop": NEXT_HOP_IP[addr_type],
1166 "vrf": "BLUE_A",
1167 },
1168 {
1169 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
1170 "next_hop": NEXT_HOP_IP[addr_type],
1171 "vrf": "BLUE_B",
1172 },
1173 ]
1174 }
1175 }
1176 result = create_static_routes(tgen, input_dict_2)
1177 assert result is True, "Testcase {} : Failed \n Error: {}".format(
1178 tc_name, result
1179 )
1180
1181 step("Redistribute static..")
1182
1183 input_dict_3 = {}
1184 for dut in ["red1", "blue1"]:
1185 temp = {dut: {"bgp": []}}
1186 input_dict_3.update(temp)
1187
1188 if "red" in dut:
1189 VRFS = ["RED_A", "RED_B"]
1190 AS_NUM = [500, 500]
1191 elif "blue" in dut:
1192 VRFS = ["BLUE_A", "BLUE_B"]
1193 AS_NUM = [800, 800]
1194
1195 for vrf, as_num in zip(VRFS, AS_NUM):
1196 temp[dut]["bgp"].append(
1197 {
1198 "local_as": as_num,
1199 "vrf": vrf,
1200 "address_family": {
1201 "ipv4": {
1202 "unicast": {"redistribute": [{"redist_type": "static"}]}
1203 },
1204 "ipv6": {
1205 "unicast": {"redistribute": [{"redist_type": "static"}]}
1206 },
1207 },
1208 }
1209 )
1210
1211 result = create_router_bgp(tgen, topo, input_dict_3)
1212 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
1213
1214 step("Api call to modify BGP timers")
1215
1216 input_dict_4 = {
1217 "r1": {
1218 "bgp": [
1219 {
1220 "local_as": "100",
1221 "vrf": "RED_A",
1222 "address_family": {
1223 "ipv4": {
1224 "unicast": {
1225 "neighbor": {
1226 "r2": {
1227 "dest_link": {
1228 "r1-link1": {
1229 "keepalivetimer": KEEPALIVETIMER,
1230 "holddowntimer": HOLDDOWNTIMER,
1231 }
1232 }
1233 }
1234 }
1235 }
1236 },
1237 "ipv6": {
1238 "unicast": {
1239 "neighbor": {
1240 "r2": {
1241 "dest_link": {
1242 "r1-link1": {
1243 "keepalivetimer": KEEPALIVETIMER,
1244 "holddowntimer": HOLDDOWNTIMER,
1245 }
1246 }
1247 }
1248 }
1249 }
1250 },
1251 },
1252 },
1253 {
1254 "local_as": "100",
1255 "vrf": "RED_B",
1256 "address_family": {
1257 "ipv4": {
1258 "unicast": {
1259 "neighbor": {
1260 "r2": {
1261 "dest_link": {
1262 "r1-link2": {
1263 "keepalivetimer": KEEPALIVETIMER,
1264 "holddowntimer": HOLDDOWNTIMER,
1265 }
1266 }
1267 }
1268 }
1269 }
1270 },
1271 "ipv6": {
1272 "unicast": {
1273 "neighbor": {
1274 "r2": {
1275 "dest_link": {
1276 "r1-link2": {
1277 "keepalivetimer": KEEPALIVETIMER,
1278 "holddowntimer": HOLDDOWNTIMER,
1279 }
1280 }
1281 }
1282 }
1283 }
1284 },
1285 },
1286 },
1287 {
1288 "local_as": "100",
1289 "vrf": "BLUE_A",
1290 "address_family": {
1291 "ipv4": {
1292 "unicast": {
1293 "neighbor": {
1294 "r2": {
1295 "dest_link": {
1296 "r1-link3": {
1297 "keepalivetimer": KEEPALIVETIMER,
1298 "holddowntimer": HOLDDOWNTIMER,
1299 }
1300 }
1301 }
1302 }
1303 }
1304 },
1305 "ipv6": {
1306 "unicast": {
1307 "neighbor": {
1308 "r2": {
1309 "dest_link": {
1310 "r1-link3": {
1311 "keepalivetimer": KEEPALIVETIMER,
1312 "holddowntimer": HOLDDOWNTIMER,
1313 }
1314 }
1315 }
1316 }
1317 }
1318 },
1319 },
1320 },
1321 {
1322 "local_as": "100",
1323 "vrf": "BLUE_B",
1324 "address_family": {
1325 "ipv4": {
1326 "unicast": {
1327 "neighbor": {
1328 "r2": {
1329 "dest_link": {
1330 "r1-link4": {
1331 "keepalivetimer": KEEPALIVETIMER,
1332 "holddowntimer": HOLDDOWNTIMER,
1333 }
1334 }
1335 }
1336 }
1337 }
1338 },
1339 "ipv6": {
1340 "unicast": {
1341 "neighbor": {
1342 "r2": {
1343 "dest_link": {
1344 "r1-link4": {
1345 "keepalivetimer": KEEPALIVETIMER,
1346 "holddowntimer": HOLDDOWNTIMER,
1347 }
1348 }
1349 }
1350 }
1351 }
1352 },
1353 },
1354 },
1355 ]
1356 },
1357 "r2": {
1358 "bgp": [
1359 {
1360 "local_as": "100",
1361 "vrf": "RED_A",
1362 "address_family": {
1363 "ipv4": {
1364 "unicast": {
1365 "neighbor": {
1366 "r1": {
1367 "dest_link": {
1368 "r2-link1": {
1369 "keepalivetimer": KEEPALIVETIMER,
1370 "holddowntimer": HOLDDOWNTIMER,
1371 }
1372 }
1373 }
1374 }
1375 }
1376 },
1377 "ipv6": {
1378 "unicast": {
1379 "neighbor": {
1380 "r1": {
1381 "dest_link": {
1382 "r2-link1": {
1383 "keepalivetimer": KEEPALIVETIMER,
1384 "holddowntimer": HOLDDOWNTIMER,
1385 }
1386 }
1387 }
1388 }
1389 }
1390 },
1391 },
1392 },
1393 {
1394 "local_as": "100",
1395 "vrf": "RED_B",
1396 "address_family": {
1397 "ipv4": {
1398 "unicast": {
1399 "neighbor": {
1400 "r1": {
1401 "dest_link": {
1402 "r2-link2": {
1403 "keepalivetimer": KEEPALIVETIMER,
1404 "holddowntimer": HOLDDOWNTIMER,
1405 }
1406 }
1407 }
1408 }
1409 }
1410 },
1411 "ipv6": {
1412 "unicast": {
1413 "neighbor": {
1414 "r1": {
1415 "dest_link": {
1416 "r2-link2": {
1417 "keepalivetimer": KEEPALIVETIMER,
1418 "holddowntimer": HOLDDOWNTIMER,
1419 }
1420 }
1421 }
1422 }
1423 }
1424 },
1425 },
1426 },
1427 {
1428 "local_as": "100",
1429 "vrf": "BLUE_A",
1430 "address_family": {
1431 "ipv4": {
1432 "unicast": {
1433 "neighbor": {
1434 "r1": {
1435 "dest_link": {
1436 "r2-link3": {
1437 "keepalivetimer": KEEPALIVETIMER,
1438 "holddowntimer": HOLDDOWNTIMER,
1439 }
1440 }
1441 }
1442 }
1443 }
1444 },
1445 "ipv6": {
1446 "unicast": {
1447 "neighbor": {
1448 "r1": {
1449 "dest_link": {
1450 "r2-link3": {
1451 "keepalivetimer": KEEPALIVETIMER,
1452 "holddowntimer": HOLDDOWNTIMER,
1453 }
1454 }
1455 }
1456 }
1457 }
1458 },
1459 },
1460 },
1461 {
1462 "local_as": "100",
1463 "vrf": "BLUE_B",
1464 "address_family": {
1465 "ipv4": {
1466 "unicast": {
1467 "neighbor": {
1468 "r1": {
1469 "dest_link": {
1470 "r2-link4": {
1471 "keepalivetimer": KEEPALIVETIMER,
1472 "holddowntimer": HOLDDOWNTIMER,
1473 }
1474 }
1475 }
1476 }
1477 }
1478 },
1479 "ipv6": {
1480 "unicast": {
1481 "neighbor": {
1482 "r1": {
1483 "dest_link": {
1484 "r2-link4": {
1485 "keepalivetimer": KEEPALIVETIMER,
1486 "holddowntimer": HOLDDOWNTIMER,
1487 }
1488 }
1489 }
1490 }
1491 }
1492 },
1493 },
1494 },
1495 ]
1496 },
1497 }
1498
1499 result = create_router_bgp(tgen, topo, input_dict_4)
1500 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
1501
1502 for addr_type in ADDR_TYPES:
1503 clear_bgp(tgen, addr_type, "r1", vrf=["RED_A", "RED_B", "BLUE_A", "BLUE_B"])
1504
1505 clear_bgp(tgen, addr_type, "r2", vrf=["RED_A", "RED_B", "BLUE_A", "BLUE_B"])
1506
1507 step("Shut down connecting interface between R1<<>>R2 on R1.")
1508 step("Repeat step-3 and step-4 10 times.")
1509
1510 for count in range(1, 2):
1511 step("Iteration {}".format(count))
1512 step("Shut down connecting interface between R1<<>>R2 on R1.")
1513
1514 intf1 = topo["routers"]["r1"]["links"]["r2-link1"]["interface"]
1515 intf2 = topo["routers"]["r1"]["links"]["r2-link2"]["interface"]
1516 intf3 = topo["routers"]["r1"]["links"]["r2-link3"]["interface"]
1517 intf4 = topo["routers"]["r1"]["links"]["r2-link4"]["interface"]
1518
1519 interfaces = [intf1, intf2, intf3, intf4]
1520 for intf in interfaces:
1521 shutdown_bringup_interface(tgen, "r1", intf, False)
1522
1523 step(
1524 "On R2, all BGP peering in respective vrf instances go down"
1525 " when the interface is shut"
1526 )
1527
1528 step("Sleeping for {}+1 sec..".format(HOLDDOWNTIMER))
1529 sleep(HOLDDOWNTIMER + 1)
1530
1531 result = verify_bgp_convergence(tgen, topo, expected=False)
1532 assert (
1533 result is not True
1534 ), "Testcase {} : Failed \nExpected Behaviour: BGP will not be converged \nError {}".format(
1535 tc_name, result
1536 )
1537
1538 for addr_type in ADDR_TYPES:
1539 dut = "r2"
1540 input_dict_1 = {
1541 "red1": {
1542 "static_routes": [
1543 {
1544 "network": [NETWORK1_1[addr_type]]
1545 + [NETWORK1_2[addr_type]],
1546 "next_hop": NEXT_HOP_IP[addr_type],
1547 "vrf": "RED_A",
1548 },
1549 {
1550 "network": [NETWORK2_1[addr_type]]
1551 + [NETWORK2_2[addr_type]],
1552 "next_hop": NEXT_HOP_IP[addr_type],
1553 "vrf": "RED_B",
1554 },
1555 ]
1556 }
1557 }
1558
1559 input_dict_2 = {
1560 "blue1": {
1561 "static_routes": [
1562 {
1563 "network": [NETWORK1_1[addr_type]]
1564 + [NETWORK1_2[addr_type]],
1565 "next_hop": NEXT_HOP_IP[addr_type],
1566 "vrf": "BLUE_A",
1567 },
1568 {
1569 "network": [NETWORK2_1[addr_type]]
1570 + [NETWORK2_2[addr_type]],
1571 "next_hop": NEXT_HOP_IP[addr_type],
1572 "vrf": "BLUE_B",
1573 },
1574 ]
1575 }
1576 }
1577
1578 result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False)
1579 assert (
1580 result is not True
1581 ), "Testcase {} : Failed \nExpected Behaviour: Routes are flushed out \nError {}".format(
1582 tc_name, result
1583 )
1584
1585 result = verify_rib(tgen, addr_type, dut, input_dict_2, expected=False)
1586 assert (
1587 result is not True
1588 ), "Testcase {} : Failed \nExpected Behaviour: Routes are flushed out \nError {}".format(
1589 tc_name, result
1590 )
1591
1592 step("Bring up connecting interface between R1<<>>R2 on R1.")
1593 for intf in interfaces:
1594 shutdown_bringup_interface(tgen, "r1", intf, True)
1595
1596 step(
1597 "R2 restores BGP peering and routing tables in all vrf "
1598 "instances when interface brought back up again"
1599 )
1600
1601 result = verify_bgp_convergence(tgen, topo)
1602 assert result is True, "Testcase {} : Failed \n Error {}".format(
1603 tc_name, result
1604 )
1605
1606 for addr_type in ADDR_TYPES:
1607 dut = "r2"
1608 input_dict_1 = {
1609 "red1": {
1610 "static_routes": [
1611 {
1612 "network": [NETWORK1_1[addr_type]]
1613 + [NETWORK1_2[addr_type]],
1614 "next_hop": NEXT_HOP_IP[addr_type],
1615 "vrf": "RED_A",
1616 },
1617 {
1618 "network": [NETWORK2_1[addr_type]]
1619 + [NETWORK2_2[addr_type]],
1620 "next_hop": NEXT_HOP_IP[addr_type],
1621 "vrf": "RED_B",
1622 },
1623 ]
1624 }
1625 }
1626
1627 input_dict_2 = {
1628 "blue1": {
1629 "static_routes": [
1630 {
1631 "network": [NETWORK1_1[addr_type]]
1632 + [NETWORK1_2[addr_type]],
1633 "next_hop": NEXT_HOP_IP[addr_type],
1634 "vrf": "BLUE_A",
1635 },
1636 {
1637 "network": [NETWORK2_1[addr_type]]
1638 + [NETWORK2_2[addr_type]],
1639 "next_hop": NEXT_HOP_IP[addr_type],
1640 "vrf": "BLUE_B",
1641 },
1642 ]
1643 }
1644 }
1645
1646 result = verify_rib(tgen, addr_type, dut, input_dict_1)
1647 assert result is True, "Testcase {} : Failed \n Error {}".format(
1648 tc_name, result
1649 )
1650
1651 result = verify_rib(tgen, addr_type, dut, input_dict_2)
1652 assert result is True, "Testcase {} : Failed \n Error {}".format(
1653 tc_name, result
1654 )
1655
1656 write_test_footer(tc_name)
1657
1658
1659 def test_vrf_vlan_routing_table_p1(request):
1660 """
1661 CHAOS_5:
1662 VRF - VLANs - Routing Table ID - combination testcase
1663 on DUT.
1664 """
1665
1666 tgen = get_topogen()
1667 tc_name = request.node.name
1668 write_test_header(tc_name)
1669 reset_config_on_routers(tgen)
1670
1671 if tgen.routers_have_failure():
1672 check_router_status(tgen)
1673
1674 step(
1675 "Advertise unique prefixes(IPv4+IPv6) in BGP using"
1676 " network command for vrf RED_A on router R2"
1677 )
1678
1679 for addr_type in ADDR_TYPES:
1680 input_dict_1 = {
1681 "r2": {
1682 "static_routes": [
1683 {
1684 "network": NETWORK1_1[addr_type],
1685 "next_hop": NEXT_HOP_IP[addr_type],
1686 "vrf": "RED_A",
1687 }
1688 ]
1689 }
1690 }
1691 result = create_static_routes(tgen, input_dict_1)
1692 assert result is True, "Testcase {} : Failed \n Error: {}".format(
1693 tc_name, result
1694 )
1695
1696 step("Redistribute static..")
1697
1698 input_dict_3 = {
1699 "r2": {
1700 "bgp": [
1701 {
1702 "local_as": "100",
1703 "vrf": "RED_A",
1704 "address_family": {
1705 "ipv4": {
1706 "unicast": {"redistribute": [{"redist_type": "static"}]}
1707 },
1708 "ipv6": {
1709 "unicast": {"redistribute": [{"redist_type": "static"}]}
1710 },
1711 },
1712 }
1713 ]
1714 }
1715 }
1716
1717 result = create_router_bgp(tgen, topo, input_dict_3)
1718 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
1719
1720 step(
1721 "Verify that static routes(IPv4+IPv6) is overridden and doesn't"
1722 " have duplicate entries within VRF RED_A on router RED-1"
1723 )
1724
1725 result = verify_bgp_convergence(tgen, topo)
1726 assert result is True, "Testcase {} : Failed \n Error {}".format(tc_name, result)
1727
1728 for addr_type in ADDR_TYPES:
1729 dut = "r3"
1730 input_dict_1 = {
1731 "r2": {
1732 "static_routes": [
1733 {
1734 "network": NETWORK1_1[addr_type],
1735 "next_hop": NEXT_HOP_IP[addr_type],
1736 "vrf": "RED_A",
1737 }
1738 ]
1739 }
1740 }
1741
1742 result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
1743 assert result is True, "Testcase {} : Failed \n Error {}".format(
1744 tc_name, result
1745 )
1746
1747 step("Api call to modify BGP timers")
1748
1749 input_dict_4 = {
1750 "r3": {
1751 "bgp": [
1752 {
1753 "local_as": "200",
1754 "vrf": "RED_A",
1755 "address_family": {
1756 "ipv4": {
1757 "unicast": {
1758 "neighbor": {
1759 "r2": {
1760 "dest_link": {
1761 "r3-link1": {
1762 "keepalivetimer": KEEPALIVETIMER,
1763 "holddowntimer": HOLDDOWNTIMER,
1764 }
1765 }
1766 }
1767 }
1768 }
1769 },
1770 "ipv6": {
1771 "unicast": {
1772 "neighbor": {
1773 "r2": {
1774 "dest_link": {
1775 "r3-link1": {
1776 "keepalivetimer": KEEPALIVETIMER,
1777 "holddowntimer": HOLDDOWNTIMER,
1778 }
1779 }
1780 }
1781 }
1782 }
1783 },
1784 },
1785 }
1786 ]
1787 }
1788 }
1789
1790 result = create_router_bgp(tgen, topo, input_dict_4)
1791 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
1792
1793 for addr_type in ADDR_TYPES:
1794 clear_bgp(tgen, addr_type, "r3", vrf=["RED_A"])
1795
1796 step("Repeat for 5 times.")
1797
1798 for count in range(1, 2):
1799 step("Iteration {}..".format(count))
1800 step("Delete a specific VRF instance(RED_A) from router R3")
1801
1802 input_dict = {"r3": {"vrfs": [{"name": "RED_A", "id": "1", "delete": True}]}}
1803
1804 result = create_vrf_cfg(tgen, input_dict)
1805 assert result is True, "Testcase {} : Failed \n Error {}".format(
1806 tc_name, result
1807 )
1808
1809 step("Sleeping for {}+1 sec..".format(HOLDDOWNTIMER))
1810 sleep(HOLDDOWNTIMER + 1)
1811
1812 for addr_type in ADDR_TYPES:
1813 dut = "r3"
1814 input_dict_1 = {
1815 "r2": {
1816 "static_routes": [
1817 {
1818 "network": NETWORK1_1[addr_type],
1819 "next_hop": NEXT_HOP_IP[addr_type],
1820 "vrf": "RED_A",
1821 }
1822 ]
1823 }
1824 }
1825
1826 result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1, expected=False)
1827 assert (
1828 result is not True
1829 ), "Testcase {} : Failed \n Expected Behaviour: Routes are cleaned \n Error {}".format(
1830 tc_name, result
1831 )
1832
1833 step("Add/reconfigure the same VRF instance again")
1834
1835 result = create_vrf_cfg(tgen, {"r3": topo["routers"]["r3"]})
1836 assert result is True, "Testcase {} : Failed \n Error {}".format(
1837 tc_name, result
1838 )
1839
1840 step(
1841 "After deleting VRFs ipv6 addresses will be deleted from kernel "
1842 " Adding back ipv6 addresses"
1843 )
1844
1845 dut = "r3"
1846 vrf = "RED_A"
1847
1848 for c_link, c_data in topo["routers"][dut]["links"].items():
1849 if c_data["vrf"] != vrf:
1850 continue
1851
1852 intf_name = c_data["interface"]
1853 intf_ipv6 = c_data["ipv6"]
1854
1855 create_interface_in_kernel(
1856 tgen, dut, intf_name, intf_ipv6, vrf, create=False
1857 )
1858
1859 step("Sleeping for {}+1 sec..".format(HOLDDOWNTIMER))
1860 sleep(HOLDDOWNTIMER + 1)
1861
1862 for addr_type in ADDR_TYPES:
1863 dut = "r3"
1864 input_dict_1 = {
1865 "r2": {
1866 "static_routes": [
1867 {
1868 "network": NETWORK1_1[addr_type],
1869 "next_hop": NEXT_HOP_IP[addr_type],
1870 "vrf": "RED_A",
1871 }
1872 ]
1873 }
1874 }
1875
1876 result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
1877 assert result is True, "Testcase {} : Failed \n Error {}".format(
1878 tc_name, result
1879 )
1880
1881 write_test_footer(tc_name)
1882
1883
1884 def test_vrf_route_leaking_next_hop_interface_flapping_p1(request):
1885 """
1886 CHAOS_3:
1887 VRF leaking - next-hop interface is flapping.
1888 """
1889
1890 tgen = get_topogen()
1891 tc_name = request.node.name
1892 write_test_header(tc_name)
1893 reset_config_on_routers(tgen)
1894
1895 if tgen.routers_have_failure():
1896 check_router_status(tgen)
1897
1898 step("Create loopback interface")
1899
1900 for addr_type in ADDR_TYPES:
1901 create_interface_in_kernel(
1902 tgen,
1903 "red1",
1904 "loopback2",
1905 LOOPBACK_2[addr_type],
1906 "RED_B",
1907 )
1908
1909 intf_red1_r11 = topo["routers"]["red1"]["links"]["r1-link2"]["interface"]
1910 for addr_type in ADDR_TYPES:
1911 input_dict_1 = {
1912 "red1": {
1913 "static_routes": [
1914 {
1915 "network": LOOPBACK_2[addr_type],
1916 "interface": intf_red1_r11,
1917 "nexthop_vrf": "RED_B",
1918 "vrf": "RED_A",
1919 }
1920 ]
1921 }
1922 }
1923 result = create_static_routes(tgen, input_dict_1)
1924 assert result is True, "Testcase {} : Failed \n Error: {}".format(
1925 tc_name, result
1926 )
1927
1928 step("Redistribute static..")
1929
1930 input_dict_3 = {
1931 "red1": {
1932 "bgp": [
1933 {
1934 "local_as": "500",
1935 "vrf": "RED_A",
1936 "address_family": {
1937 "ipv4": {
1938 "unicast": {"redistribute": [{"redist_type": "static"}]}
1939 },
1940 "ipv6": {
1941 "unicast": {"redistribute": [{"redist_type": "static"}]}
1942 },
1943 },
1944 }
1945 ]
1946 }
1947 }
1948
1949 result = create_router_bgp(tgen, topo, input_dict_3)
1950 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
1951
1952 result = verify_bgp_convergence(tgen, topo)
1953 assert result is True, "Testcase {} : Failed \n Error {}".format(tc_name, result)
1954
1955 step("VRF RED_A should install a route for vrf RED_B's " "loopback ip.")
1956 for addr_type in ADDR_TYPES:
1957 dut = "red1"
1958 input_dict_1 = {
1959 "red1": {
1960 "static_routes": [
1961 {
1962 "network": LOOPBACK_2[addr_type],
1963 "interface": intf_red1_r11,
1964 "nexthop_vrf": "RED_B",
1965 "vrf": "RED_A",
1966 }
1967 ]
1968 }
1969 }
1970
1971 result = verify_rib(tgen, addr_type, dut, input_dict_1, protocol="static")
1972 assert result is True, "Testcase {} : Failed \n Error {}".format(
1973 tc_name, result
1974 )
1975
1976 step("Repeat step-2 to 4 at least 5 times")
1977
1978 for count in range(1, 2):
1979 intf1 = topo["routers"]["red1"]["links"]["r1-link2"]["interface"]
1980
1981 step(
1982 "Iteration {}: Shutdown interface {} on router"
1983 "RED_1.".format(count, intf1)
1984 )
1985 shutdown_bringup_interface(tgen, "red1", intf1, False)
1986
1987 step("Verify that RED_A removes static route from routing " "table.")
1988
1989 for addr_type in ADDR_TYPES:
1990 dut = "red1"
1991 input_dict_1 = {
1992 "red1": {
1993 "static_routes": [
1994 {
1995 "network": LOOPBACK_2[addr_type],
1996 "interface": intf_red1_r11,
1997 "nexthop_vrf": "RED_B",
1998 "vrf": "RED_A",
1999 }
2000 ]
2001 }
2002 }
2003
2004 result = verify_rib(
2005 tgen, addr_type, dut, input_dict_1, protocol="static", expected=False
2006 )
2007 assert result is not True, (
2008 "Testcase {} : Failed \n Expected Behaviour: Routes are"
2009 " not present Error {}".format(tc_name, result)
2010 )
2011
2012 step("Bring up interface {} on router RED_1 again.".format(intf1))
2013 shutdown_bringup_interface(tgen, "red1", intf1, True)
2014
2015 step(
2016 "Verify that RED_A reinstalls static route pointing to "
2017 "RED_B's IP in routing table again"
2018 )
2019
2020 for addr_type in ADDR_TYPES:
2021 dut = "red1"
2022 input_dict_1 = {
2023 "red1": {
2024 "static_routes": [
2025 {
2026 "network": LOOPBACK_2[addr_type],
2027 "interface": intf_red1_r11,
2028 "nexthop_vrf": "RED_B",
2029 "vrf": "RED_A",
2030 }
2031 ]
2032 }
2033 }
2034
2035 result = verify_rib(tgen, addr_type, dut, input_dict_1, protocol="static")
2036 assert result is True, "Testcase {} : Failed \n Error {}".format(
2037 tc_name, result
2038 )
2039
2040 write_test_footer(tc_name)
2041
2042
2043 def test_restart_bgpd_daemon_p1(request):
2044 """
2045 CHAOS_6:
2046 Restart BGPd daemon on DUT to check if all the
2047 routes in respective vrfs are reinstalled..
2048 """
2049
2050 tgen = get_topogen()
2051 tc_name = request.node.name
2052 write_test_header(tc_name)
2053
2054 if tgen.routers_have_failure():
2055 check_router_status(tgen)
2056
2057 reset_config_on_routers(tgen)
2058
2059 step(
2060 "Advertise unique BGP prefixes(IPv4+IPv6) from RED_1"
2061 " in vrf instances(RED_A and RED_B)."
2062 )
2063
2064 for addr_type in ADDR_TYPES:
2065 input_dict_1 = {
2066 "red1": {
2067 "static_routes": [
2068 {
2069 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
2070 "next_hop": NEXT_HOP_IP[addr_type],
2071 "vrf": "RED_A",
2072 },
2073 {
2074 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
2075 "next_hop": NEXT_HOP_IP[addr_type],
2076 "vrf": "RED_B",
2077 },
2078 ]
2079 }
2080 }
2081 result = create_static_routes(tgen, input_dict_1)
2082 assert result is True, "Testcase {} : Failed \n Error: {}".format(
2083 tc_name, result
2084 )
2085
2086 step(
2087 "Advertise unique BGP prefixes(IPv4+IPv6) from BLUE_1 in"
2088 " vrf instances(BLUE_A and BLUE_B)."
2089 )
2090
2091 for addr_type in ADDR_TYPES:
2092 input_dict_2 = {
2093 "blue1": {
2094 "static_routes": [
2095 {
2096 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
2097 "next_hop": NEXT_HOP_IP[addr_type],
2098 "vrf": "BLUE_A",
2099 },
2100 {
2101 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
2102 "next_hop": NEXT_HOP_IP[addr_type],
2103 "vrf": "BLUE_B",
2104 },
2105 ]
2106 }
2107 }
2108 result = create_static_routes(tgen, input_dict_2)
2109 assert result is True, "Testcase {} : Failed \n Error: {}".format(
2110 tc_name, result
2111 )
2112
2113 step("Redistribute static..")
2114
2115 input_dict_3 = {}
2116 for dut in ["red1", "blue1"]:
2117 temp = {dut: {"bgp": []}}
2118 input_dict_3.update(temp)
2119
2120 if "red" in dut:
2121 VRFS = ["RED_A", "RED_B"]
2122 AS_NUM = [500, 500]
2123 elif "blue" in dut:
2124 VRFS = ["BLUE_A", "BLUE_B"]
2125 AS_NUM = [800, 800]
2126
2127 for vrf, as_num in zip(VRFS, AS_NUM):
2128 temp[dut]["bgp"].append(
2129 {
2130 "local_as": as_num,
2131 "vrf": vrf,
2132 "address_family": {
2133 "ipv4": {
2134 "unicast": {"redistribute": [{"redist_type": "static"}]}
2135 },
2136 "ipv6": {
2137 "unicast": {"redistribute": [{"redist_type": "static"}]}
2138 },
2139 },
2140 }
2141 )
2142
2143 result = create_router_bgp(tgen, topo, input_dict_3)
2144 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
2145
2146 result = verify_bgp_convergence(tgen, topo)
2147 assert result is True, "Testcase {} :Failed\n Error {}".format(tc_name, result)
2148
2149 step("Kill BGPd daemon on R1.")
2150 kill_router_daemons(tgen, "r1", ["bgpd"])
2151
2152 for addr_type in ADDR_TYPES:
2153 dut = "r2"
2154 input_dict_1 = {
2155 "red1": {
2156 "static_routes": [
2157 {
2158 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
2159 "next_hop": NEXT_HOP_IP[addr_type],
2160 "vrf": "RED_A",
2161 },
2162 {
2163 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
2164 "next_hop": NEXT_HOP_IP[addr_type],
2165 "vrf": "RED_B",
2166 },
2167 ]
2168 }
2169 }
2170
2171 input_dict_2 = {
2172 "blue1": {
2173 "static_routes": [
2174 {
2175 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
2176 "next_hop": NEXT_HOP_IP[addr_type],
2177 "vrf": "BLUE_A",
2178 },
2179 {
2180 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
2181 "next_hop": NEXT_HOP_IP[addr_type],
2182 "vrf": "BLUE_B",
2183 },
2184 ]
2185 }
2186 }
2187
2188 result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False)
2189 assert result is not True, (
2190 "Testcase {} : Failed \n "
2191 "Routes are still present in VRF RED_A and RED_B \n Error: {}".format(
2192 tc_name, result
2193 )
2194 )
2195
2196 result = verify_rib(tgen, addr_type, dut, input_dict_2, expected=False)
2197 assert result is not True, (
2198 "Testcase {} : Failed \n "
2199 "Routes are still present in VRF BLUE_A and BLUE_B \n Error: {}".format(
2200 tc_name, result
2201 )
2202 )
2203
2204 step("Bring up BGPd daemon on R1.")
2205 start_router_daemons(tgen, "r1", ["bgpd"])
2206
2207 result = verify_bgp_convergence(tgen, topo)
2208 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
2209
2210 for addr_type in ADDR_TYPES:
2211 dut = "r2"
2212 input_dict_1 = {
2213 "red1": {
2214 "static_routes": [
2215 {
2216 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
2217 "next_hop": NEXT_HOP_IP[addr_type],
2218 "vrf": "RED_A",
2219 },
2220 {
2221 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
2222 "next_hop": NEXT_HOP_IP[addr_type],
2223 "vrf": "RED_B",
2224 },
2225 ]
2226 }
2227 }
2228
2229 input_dict_2 = {
2230 "blue1": {
2231 "static_routes": [
2232 {
2233 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
2234 "next_hop": NEXT_HOP_IP[addr_type],
2235 "vrf": "BLUE_A",
2236 },
2237 {
2238 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
2239 "next_hop": NEXT_HOP_IP[addr_type],
2240 "vrf": "BLUE_B",
2241 },
2242 ]
2243 }
2244 }
2245
2246 result = verify_rib(tgen, addr_type, dut, input_dict_1)
2247 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
2248
2249 result = verify_rib(tgen, addr_type, dut, input_dict_2)
2250 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
2251
2252 write_test_footer(tc_name)
2253
2254
2255 def test_delete_and_re_add_vrf_p1(request):
2256 """
2257 CHAOS_2:
2258 Delete a VRF instance from DUT and check if the routes get
2259 deleted from subsequent neighbour routers and appears again once VRF
2260 is re-added.
2261 """
2262
2263 tgen = get_topogen()
2264 tc_name = request.node.name
2265 write_test_header(tc_name)
2266 reset_config_on_routers(tgen)
2267
2268 if tgen.routers_have_failure():
2269 pytest.skip(tgen.errors)
2270
2271 step(
2272 "Advertise unique prefixes in BGP using static redistribution"
2273 "for both vrfs (RED_A and RED_B) on router RED_1"
2274 )
2275
2276 for addr_type in ADDR_TYPES:
2277 input_dict_1 = {
2278 "red1": {
2279 "static_routes": [
2280 {
2281 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
2282 "next_hop": NEXT_HOP_IP[addr_type],
2283 "vrf": "RED_A",
2284 },
2285 {
2286 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
2287 "next_hop": NEXT_HOP_IP[addr_type],
2288 "vrf": "RED_B",
2289 },
2290 ]
2291 }
2292 }
2293 result = create_static_routes(tgen, input_dict_1)
2294 assert result is True, "Testcase {} : Failed \n Error: {}".format(
2295 tc_name, result
2296 )
2297
2298 step(
2299 "Advertise unique prefixes in BGP using static redistribution"
2300 " for both vrfs (BLUE_A and BLUE_B) on router BLUE_1."
2301 )
2302
2303 for addr_type in ADDR_TYPES:
2304 input_dict_2 = {
2305 "blue1": {
2306 "static_routes": [
2307 {
2308 "network": [NETWORK3_1[addr_type]] + [NETWORK3_2[addr_type]],
2309 "next_hop": NEXT_HOP_IP[addr_type],
2310 "vrf": "BLUE_A",
2311 },
2312 {
2313 "network": [NETWORK4_1[addr_type]] + [NETWORK4_2[addr_type]],
2314 "next_hop": NEXT_HOP_IP[addr_type],
2315 "vrf": "BLUE_B",
2316 },
2317 ]
2318 }
2319 }
2320 result = create_static_routes(tgen, input_dict_2)
2321 assert result is True, "Testcase {} : Failed \n Error: {}".format(
2322 tc_name, result
2323 )
2324
2325 step("Redistribute static for vrfs RED_A and RED_B and BLUE_A and BLUE_B")
2326
2327 input_dict_3 = {}
2328 for dut in ["red1", "blue1"]:
2329 temp = {dut: {"bgp": []}}
2330 input_dict_3.update(temp)
2331
2332 if "red" in dut:
2333 VRFS = ["RED_A", "RED_B"]
2334 AS_NUM = [500, 500]
2335 elif "blue" in dut:
2336 VRFS = ["BLUE_A", "BLUE_B"]
2337 AS_NUM = [800, 800]
2338
2339 for vrf, as_num in zip(VRFS, AS_NUM):
2340 temp[dut]["bgp"].append(
2341 {
2342 "local_as": as_num,
2343 "vrf": vrf,
2344 "address_family": {
2345 "ipv4": {
2346 "unicast": {"redistribute": [{"redist_type": "static"}]}
2347 },
2348 "ipv6": {
2349 "unicast": {"redistribute": [{"redist_type": "static"}]}
2350 },
2351 },
2352 }
2353 )
2354
2355 result = create_router_bgp(tgen, topo, input_dict_3)
2356 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
2357
2358 step("Verifying RIB and FIB before deleting VRFs")
2359 result = verify_bgp_convergence(tgen, topo)
2360 assert result is True, "Testcase {} : Failed \n Error {}".format(tc_name, result)
2361
2362 for addr_type in ADDR_TYPES:
2363 dut = "r2"
2364 input_dict_1 = {
2365 "red1": {
2366 "static_routes": [
2367 {
2368 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
2369 "next_hop": NEXT_HOP_IP[addr_type],
2370 "vrf": "RED_A",
2371 },
2372 {
2373 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
2374 "next_hop": NEXT_HOP_IP[addr_type],
2375 "vrf": "RED_B",
2376 },
2377 ]
2378 }
2379 }
2380
2381 result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
2382 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
2383
2384 result = verify_rib(tgen, addr_type, dut, input_dict_1)
2385 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
2386
2387 for addr_type in ADDR_TYPES:
2388 dut = "r2"
2389 input_dict_2 = {
2390 "blue1": {
2391 "static_routes": [
2392 {
2393 "network": [NETWORK3_1[addr_type]] + [NETWORK3_2[addr_type]],
2394 "next_hop": NEXT_HOP_IP[addr_type],
2395 "vrf": "BLUE_A",
2396 },
2397 {
2398 "network": [NETWORK4_1[addr_type]] + [NETWORK4_2[addr_type]],
2399 "next_hop": NEXT_HOP_IP[addr_type],
2400 "vrf": "BLUE_B",
2401 },
2402 ]
2403 }
2404 }
2405
2406 result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
2407 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
2408
2409 result = verify_rib(tgen, addr_type, dut, input_dict_2)
2410 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
2411
2412 step("Api call to modify BGP timers")
2413
2414 input_dict_4 = {
2415 "r1": {
2416 "bgp": [
2417 {
2418 "local_as": "100",
2419 "vrf": "RED_A",
2420 "address_family": {
2421 "ipv4": {
2422 "unicast": {
2423 "neighbor": {
2424 "r2": {
2425 "dest_link": {
2426 "r1-link1": {
2427 "keepalivetimer": KEEPALIVETIMER,
2428 "holddowntimer": HOLDDOWNTIMER,
2429 }
2430 }
2431 }
2432 }
2433 }
2434 },
2435 "ipv6": {
2436 "unicast": {
2437 "neighbor": {
2438 "r2": {
2439 "dest_link": {
2440 "r1-link1": {
2441 "keepalivetimer": KEEPALIVETIMER,
2442 "holddowntimer": HOLDDOWNTIMER,
2443 }
2444 }
2445 }
2446 }
2447 }
2448 },
2449 },
2450 },
2451 {
2452 "local_as": "100",
2453 "vrf": "RED_B",
2454 "address_family": {
2455 "ipv4": {
2456 "unicast": {
2457 "neighbor": {
2458 "r2": {
2459 "dest_link": {
2460 "r1-link2": {
2461 "keepalivetimer": KEEPALIVETIMER,
2462 "holddowntimer": HOLDDOWNTIMER,
2463 }
2464 }
2465 }
2466 }
2467 }
2468 },
2469 "ipv6": {
2470 "unicast": {
2471 "neighbor": {
2472 "r2": {
2473 "dest_link": {
2474 "r1-link2": {
2475 "keepalivetimer": KEEPALIVETIMER,
2476 "holddowntimer": HOLDDOWNTIMER,
2477 }
2478 }
2479 }
2480 }
2481 }
2482 },
2483 },
2484 },
2485 {
2486 "local_as": "100",
2487 "vrf": "BLUE_A",
2488 "address_family": {
2489 "ipv4": {
2490 "unicast": {
2491 "neighbor": {
2492 "r2": {
2493 "dest_link": {
2494 "r1-link3": {
2495 "keepalivetimer": KEEPALIVETIMER,
2496 "holddowntimer": HOLDDOWNTIMER,
2497 }
2498 }
2499 }
2500 }
2501 }
2502 },
2503 "ipv6": {
2504 "unicast": {
2505 "neighbor": {
2506 "r2": {
2507 "dest_link": {
2508 "r1-link3": {
2509 "keepalivetimer": KEEPALIVETIMER,
2510 "holddowntimer": HOLDDOWNTIMER,
2511 }
2512 }
2513 }
2514 }
2515 }
2516 },
2517 },
2518 },
2519 {
2520 "local_as": "100",
2521 "vrf": "BLUE_B",
2522 "address_family": {
2523 "ipv4": {
2524 "unicast": {
2525 "neighbor": {
2526 "r2": {
2527 "dest_link": {
2528 "r1-link4": {
2529 "keepalivetimer": KEEPALIVETIMER,
2530 "holddowntimer": HOLDDOWNTIMER,
2531 }
2532 }
2533 }
2534 }
2535 }
2536 },
2537 "ipv6": {
2538 "unicast": {
2539 "neighbor": {
2540 "r2": {
2541 "dest_link": {
2542 "r1-link4": {
2543 "keepalivetimer": KEEPALIVETIMER,
2544 "holddowntimer": HOLDDOWNTIMER,
2545 }
2546 }
2547 }
2548 }
2549 }
2550 },
2551 },
2552 },
2553 ]
2554 }
2555 }
2556
2557 result = create_router_bgp(tgen, topo, input_dict_4)
2558 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
2559
2560 for addr_type in ADDR_TYPES:
2561 clear_bgp(tgen, addr_type, "r1", vrf=["RED_A", "RED_B", "BLUE_A", "BLUE_B"])
2562
2563 step("Delete vrfs RED_A and BLUE_A from R1.")
2564
2565 input_dict = {
2566 "r1": {
2567 "vrfs": [
2568 {"name": "RED_A", "id": "1", "delete": True},
2569 {"name": "BLUE_A", "id": "3", "delete": True},
2570 ]
2571 }
2572 }
2573
2574 result = create_vrf_cfg(tgen, input_dict)
2575 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
2576
2577 step(
2578 "R2 must not receive the prefixes(in respective vrfs)"
2579 "originated from RED_1 and BLUE_1."
2580 )
2581
2582 step("Wait for {}+1 sec..".format(HOLDDOWNTIMER))
2583 sleep(HOLDDOWNTIMER + 1)
2584
2585 for addr_type in ADDR_TYPES:
2586 dut = "r2"
2587 input_dict_2 = {
2588 "red1": {
2589 "static_routes": [
2590 {
2591 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
2592 "next_hop": NEXT_HOP_IP[addr_type],
2593 "vrf": "RED_A",
2594 }
2595 ]
2596 },
2597 "blue1": {
2598 "static_routes": [
2599 {
2600 "network": [NETWORK3_1[addr_type]] + [NETWORK3_2[addr_type]],
2601 "next_hop": NEXT_HOP_IP[addr_type],
2602 "vrf": "BLUE_A",
2603 }
2604 ]
2605 },
2606 }
2607
2608 result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2, expected=False)
2609 assert result is not True, (
2610 "Testcase {} :Failed \n Expected Behaviour:"
2611 " Routes are not present \n Error {}".format(tc_name, result)
2612 )
2613
2614 result = verify_rib(tgen, addr_type, dut, input_dict_2, expected=False)
2615 assert result is not True, (
2616 "Testcase {} :Failed \n Expected Behaviour:"
2617 " Routes are not present \n Error {}".format(tc_name, result)
2618 )
2619
2620 step("Add vrfs again RED_A and BLUE_A on R1.")
2621
2622 result = create_vrf_cfg(tgen, {"r1": topo["routers"]["r1"]})
2623 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
2624
2625 create_interfaces_cfg(tgen, {"r1": topo["routers"]["r1"]})
2626 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
2627
2628 step(
2629 "After deleting VRFs ipv6 addresses will be deleted from kernel "
2630 " Adding back ipv6 addresses"
2631 )
2632
2633 dut = "r1"
2634 vrfs = ["RED_A", "BLUE_A"]
2635
2636 for vrf in vrfs:
2637 for c_link, c_data in topo["routers"][dut]["links"].items():
2638 if c_data["vrf"] != vrf:
2639 continue
2640
2641 intf_name = c_data["interface"]
2642 intf_ipv6 = c_data["ipv6"]
2643
2644 create_interface_in_kernel(
2645 tgen, dut, intf_name, intf_ipv6, vrf, create=False
2646 )
2647
2648 step(
2649 "R2 should now receive the prefixes(in respective vrfs)"
2650 "again. Check the debugging logs as well. For verification"
2651 " use same commands as mention in step-3."
2652 )
2653
2654 for addr_type in ADDR_TYPES:
2655 dut = "r2"
2656 input_dict_2 = {
2657 "red1": {
2658 "static_routes": [
2659 {
2660 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
2661 "next_hop": NEXT_HOP_IP[addr_type],
2662 "vrf": "RED_A",
2663 }
2664 ]
2665 }
2666 }
2667
2668 result = verify_bgp_convergence(tgen, topo)
2669 assert result is True, "Testcase {}: Failed\n Error {}".format(tc_name, result)
2670
2671 result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
2672 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
2673
2674 result = verify_rib(tgen, addr_type, dut, input_dict_2)
2675 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
2676
2677 for addr_type in ADDR_TYPES:
2678 dut = "r2"
2679 input_dict_2 = {
2680 "blue1": {
2681 "static_routes": [
2682 {
2683 "network": [NETWORK3_1[addr_type]] + [NETWORK3_2[addr_type]],
2684 "next_hop": NEXT_HOP_IP[addr_type],
2685 "vrf": "BLUE_A",
2686 }
2687 ]
2688 }
2689 }
2690
2691 result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
2692 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
2693
2694 result = verify_rib(tgen, addr_type, dut, input_dict_2)
2695 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
2696
2697 write_test_footer(tc_name)
2698
2699
2700 def test_vrf_name_significance_p1(request):
2701 """
2702 CHAOS_4:
2703 Verify that VRF names are locally significant
2704 to a router, and end to end connectivity depends on unique
2705 virtual circuits (using VLANs or separate physical interfaces).
2706 """
2707
2708 tgen = get_topogen()
2709 tc_name = request.node.name
2710 write_test_header(tc_name)
2711 reset_config_on_routers(tgen)
2712
2713 if tgen.routers_have_failure():
2714 check_router_status(tgen)
2715
2716 step(
2717 "Advertise unique prefixes in BGP using static redistribution"
2718 "for both vrfs (RED_A and RED_B) on router RED_1"
2719 )
2720
2721 for addr_type in ADDR_TYPES:
2722 input_dict_1 = {
2723 "red1": {
2724 "static_routes": [
2725 {
2726 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
2727 "next_hop": NEXT_HOP_IP[addr_type],
2728 "vrf": "RED_A",
2729 },
2730 {
2731 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
2732 "next_hop": NEXT_HOP_IP[addr_type],
2733 "vrf": "RED_B",
2734 },
2735 ]
2736 }
2737 }
2738 result = create_static_routes(tgen, input_dict_1)
2739 assert result is True, "Testcase {} : Failed \n Error: {}".format(
2740 tc_name, result
2741 )
2742
2743 step(
2744 "Advertise unique prefixes in BGP using static redistribution"
2745 " for both vrfs (BLUE_A and BLUE_B) on router BLUE_1."
2746 )
2747
2748 for addr_type in ADDR_TYPES:
2749 input_dict_2 = {
2750 "blue1": {
2751 "static_routes": [
2752 {
2753 "network": [NETWORK3_1[addr_type]] + [NETWORK3_2[addr_type]],
2754 "next_hop": NEXT_HOP_IP[addr_type],
2755 "vrf": "BLUE_A",
2756 },
2757 {
2758 "network": [NETWORK4_1[addr_type]] + [NETWORK4_2[addr_type]],
2759 "next_hop": NEXT_HOP_IP[addr_type],
2760 "vrf": "BLUE_B",
2761 },
2762 ]
2763 }
2764 }
2765 result = create_static_routes(tgen, input_dict_2)
2766 assert result is True, "Testcase {} : Failed \n Error: {}".format(
2767 tc_name, result
2768 )
2769
2770 step("Redistribute static for vrfs RED_A and RED_B and BLUE_A and BLUE_B")
2771
2772 input_dict_3 = {}
2773 for dut in ["red1", "blue1"]:
2774 temp = {dut: {"bgp": []}}
2775 input_dict_3.update(temp)
2776
2777 if "red" in dut:
2778 VRFS = ["RED_A", "RED_B"]
2779 AS_NUM = [500, 500]
2780 elif "blue" in dut:
2781 VRFS = ["BLUE_A", "BLUE_B"]
2782 AS_NUM = [800, 800]
2783
2784 for vrf, as_num in zip(VRFS, AS_NUM):
2785 temp[dut]["bgp"].append(
2786 {
2787 "local_as": as_num,
2788 "vrf": vrf,
2789 "address_family": {
2790 "ipv4": {
2791 "unicast": {"redistribute": [{"redist_type": "static"}]}
2792 },
2793 "ipv6": {
2794 "unicast": {"redistribute": [{"redist_type": "static"}]}
2795 },
2796 },
2797 }
2798 )
2799
2800 result = create_router_bgp(tgen, topo, input_dict_3)
2801 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
2802
2803 step("Configure allowas-in on red2 and blue2")
2804
2805 input_dict_4 = {
2806 "red2": {
2807 "bgp": [
2808 {
2809 "local_as": "500",
2810 "vrf": "RED_A",
2811 "address_family": {
2812 "ipv4": {
2813 "unicast": {
2814 "neighbor": {
2815 "r3": {
2816 "dest_link": {
2817 "red2-link1": {
2818 "allowas-in": {"number_occurences": 2}
2819 }
2820 }
2821 }
2822 }
2823 }
2824 },
2825 "ipv6": {
2826 "unicast": {
2827 "neighbor": {
2828 "r3": {
2829 "dest_link": {
2830 "red2-link1": {
2831 "allowas-in": {"number_occurences": 2}
2832 }
2833 }
2834 }
2835 }
2836 }
2837 },
2838 },
2839 },
2840 {
2841 "local_as": "500",
2842 "vrf": "RED_B",
2843 "address_family": {
2844 "ipv4": {
2845 "unicast": {
2846 "neighbor": {
2847 "r3": {
2848 "dest_link": {
2849 "red2-link2": {
2850 "allowas-in": {"number_occurences": 2}
2851 }
2852 }
2853 }
2854 }
2855 }
2856 },
2857 "ipv6": {
2858 "unicast": {
2859 "neighbor": {
2860 "r3": {
2861 "dest_link": {
2862 "red2-link2": {
2863 "allowas-in": {"number_occurences": 2}
2864 }
2865 }
2866 }
2867 }
2868 }
2869 },
2870 },
2871 },
2872 ]
2873 },
2874 "blue2": {
2875 "bgp": [
2876 {
2877 "local_as": "800",
2878 "vrf": "BLUE_A",
2879 "address_family": {
2880 "ipv4": {
2881 "unicast": {
2882 "neighbor": {
2883 "r3": {
2884 "dest_link": {
2885 "blue2-link1": {
2886 "allowas-in": {"number_occurences": 2}
2887 }
2888 }
2889 }
2890 }
2891 }
2892 },
2893 "ipv6": {
2894 "unicast": {
2895 "neighbor": {
2896 "r3": {
2897 "dest_link": {
2898 "blue2-link1": {
2899 "allowas-in": {"number_occurences": 2}
2900 }
2901 }
2902 }
2903 }
2904 }
2905 },
2906 },
2907 },
2908 {
2909 "local_as": "800",
2910 "vrf": "BLUE_B",
2911 "address_family": {
2912 "ipv4": {
2913 "unicast": {
2914 "neighbor": {
2915 "r3": {
2916 "dest_link": {
2917 "blue2-link2": {
2918 "allowas-in": {"number_occurences": 2}
2919 }
2920 }
2921 }
2922 }
2923 }
2924 },
2925 "ipv6": {
2926 "unicast": {
2927 "neighbor": {
2928 "r3": {
2929 "dest_link": {
2930 "blue2-link2": {
2931 "allowas-in": {"number_occurences": 2}
2932 }
2933 }
2934 }
2935 }
2936 }
2937 },
2938 },
2939 },
2940 ]
2941 },
2942 }
2943
2944 result = create_router_bgp(tgen, topo, input_dict_4)
2945 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
2946
2947 step("Verifying RIB and FIB before deleting VRFs")
2948
2949 for addr_type in ADDR_TYPES:
2950 dut = "red2"
2951 input_dict_1 = {
2952 "red1": {
2953 "static_routes": [
2954 {
2955 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
2956 "next_hop": NEXT_HOP_IP[addr_type],
2957 "vrf": "RED_A",
2958 }
2959 ]
2960 }
2961 }
2962 input_dict_2 = {
2963 "red1": {
2964 "static_routes": [
2965 {
2966 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
2967 "next_hop": NEXT_HOP_IP[addr_type],
2968 "vrf": "RED_B",
2969 }
2970 ]
2971 }
2972 }
2973
2974 result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
2975 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
2976
2977 result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
2978 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
2979
2980 result = verify_rib(tgen, addr_type, dut, input_dict_1)
2981 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
2982
2983 result = verify_rib(tgen, addr_type, dut, input_dict_2)
2984 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
2985
2986 for addr_type in ADDR_TYPES:
2987 dut = "blue2"
2988 input_dict_3 = {
2989 "blue1": {
2990 "static_routes": [
2991 {
2992 "network": [NETWORK3_1[addr_type]] + [NETWORK3_2[addr_type]],
2993 "next_hop": NEXT_HOP_IP[addr_type],
2994 "vrf": "BLUE_A",
2995 }
2996 ]
2997 }
2998 }
2999
3000 input_dict_4 = {
3001 "blue1": {
3002 "static_routes": [
3003 {
3004 "network": [NETWORK4_1[addr_type]] + [NETWORK4_2[addr_type]],
3005 "next_hop": NEXT_HOP_IP[addr_type],
3006 "vrf": "BLUE_B",
3007 }
3008 ]
3009 }
3010 }
3011
3012 result = verify_bgp_rib(tgen, addr_type, dut, input_dict_3)
3013 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
3014
3015 result = verify_bgp_rib(tgen, addr_type, dut, input_dict_4)
3016 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
3017
3018 result = verify_rib(tgen, addr_type, dut, input_dict_3)
3019 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
3020
3021 result = verify_rib(tgen, addr_type, dut, input_dict_4)
3022 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
3023
3024 step("Api call to modify BGP timers")
3025
3026 input_dict_4 = {
3027 "r3": {
3028 "bgp": [
3029 {
3030 "local_as": "200",
3031 "vrf": "RED_A",
3032 "address_family": {
3033 "ipv4": {
3034 "unicast": {
3035 "neighbor": {
3036 "red2": {
3037 "dest_link": {
3038 "r3-link1": {
3039 "keepalivetimer": KEEPALIVETIMER,
3040 "holddowntimer": HOLDDOWNTIMER,
3041 }
3042 }
3043 }
3044 }
3045 }
3046 },
3047 "ipv6": {
3048 "unicast": {
3049 "neighbor": {
3050 "red2": {
3051 "dest_link": {
3052 "r3-link1": {
3053 "keepalivetimer": KEEPALIVETIMER,
3054 "holddowntimer": HOLDDOWNTIMER,
3055 }
3056 }
3057 }
3058 }
3059 }
3060 },
3061 },
3062 },
3063 {
3064 "local_as": "200",
3065 "vrf": "RED_B",
3066 "address_family": {
3067 "ipv4": {
3068 "unicast": {
3069 "neighbor": {
3070 "red2": {
3071 "dest_link": {
3072 "r3-link2": {
3073 "keepalivetimer": KEEPALIVETIMER,
3074 "holddowntimer": HOLDDOWNTIMER,
3075 }
3076 }
3077 }
3078 }
3079 }
3080 },
3081 "ipv6": {
3082 "unicast": {
3083 "neighbor": {
3084 "red2": {
3085 "dest_link": {
3086 "r3-link2": {
3087 "keepalivetimer": KEEPALIVETIMER,
3088 "holddowntimer": HOLDDOWNTIMER,
3089 }
3090 }
3091 }
3092 }
3093 }
3094 },
3095 },
3096 },
3097 {
3098 "local_as": "200",
3099 "vrf": "BLUE_A",
3100 "address_family": {
3101 "ipv4": {
3102 "unicast": {
3103 "neighbor": {
3104 "blue2": {
3105 "dest_link": {
3106 "r3-link1": {
3107 "keepalivetimer": KEEPALIVETIMER,
3108 "holddowntimer": HOLDDOWNTIMER,
3109 }
3110 }
3111 }
3112 }
3113 }
3114 },
3115 "ipv6": {
3116 "unicast": {
3117 "neighbor": {
3118 "blue2": {
3119 "dest_link": {
3120 "r3-link1": {
3121 "keepalivetimer": KEEPALIVETIMER,
3122 "holddowntimer": HOLDDOWNTIMER,
3123 }
3124 }
3125 }
3126 }
3127 }
3128 },
3129 },
3130 },
3131 {
3132 "local_as": "200",
3133 "vrf": "BLUE_B",
3134 "address_family": {
3135 "ipv4": {
3136 "unicast": {
3137 "neighbor": {
3138 "blue2": {
3139 "dest_link": {
3140 "r3-link2": {
3141 "keepalivetimer": KEEPALIVETIMER,
3142 "holddowntimer": HOLDDOWNTIMER,
3143 }
3144 }
3145 }
3146 }
3147 }
3148 },
3149 "ipv6": {
3150 "unicast": {
3151 "neighbor": {
3152 "blue2": {
3153 "dest_link": {
3154 "r3-link2": {
3155 "keepalivetimer": KEEPALIVETIMER,
3156 "holddowntimer": HOLDDOWNTIMER,
3157 }
3158 }
3159 }
3160 }
3161 }
3162 },
3163 },
3164 },
3165 ]
3166 },
3167 "red2": {
3168 "bgp": [
3169 {
3170 "local_as": "500",
3171 "vrf": "RED_A",
3172 "address_family": {
3173 "ipv4": {
3174 "unicast": {
3175 "neighbor": {
3176 "r3": {
3177 "dest_link": {
3178 "red2-link1": {
3179 "keepalivetimer": KEEPALIVETIMER,
3180 "holddowntimer": HOLDDOWNTIMER,
3181 }
3182 }
3183 }
3184 }
3185 }
3186 },
3187 "ipv6": {
3188 "unicast": {
3189 "neighbor": {
3190 "r3": {
3191 "dest_link": {
3192 "red2-link1": {
3193 "keepalivetimer": KEEPALIVETIMER,
3194 "holddowntimer": HOLDDOWNTIMER,
3195 }
3196 }
3197 }
3198 }
3199 }
3200 },
3201 },
3202 },
3203 {
3204 "local_as": "500",
3205 "vrf": "RED_B",
3206 "address_family": {
3207 "ipv4": {
3208 "unicast": {
3209 "neighbor": {
3210 "r3": {
3211 "dest_link": {
3212 "red2-link2": {
3213 "keepalivetimer": KEEPALIVETIMER,
3214 "holddowntimer": HOLDDOWNTIMER,
3215 }
3216 }
3217 }
3218 }
3219 }
3220 },
3221 "ipv6": {
3222 "unicast": {
3223 "neighbor": {
3224 "r3": {
3225 "dest_link": {
3226 "red2-link2": {
3227 "keepalivetimer": KEEPALIVETIMER,
3228 "holddowntimer": HOLDDOWNTIMER,
3229 }
3230 }
3231 }
3232 }
3233 }
3234 },
3235 },
3236 },
3237 ]
3238 },
3239 "blue2": {
3240 "bgp": [
3241 {
3242 "local_as": "800",
3243 "vrf": "BLUE_A",
3244 "address_family": {
3245 "ipv4": {
3246 "unicast": {
3247 "neighbor": {
3248 "r3": {
3249 "dest_link": {
3250 "blue2-link1": {
3251 "keepalivetimer": KEEPALIVETIMER,
3252 "holddowntimer": HOLDDOWNTIMER,
3253 }
3254 }
3255 }
3256 }
3257 }
3258 },
3259 "ipv6": {
3260 "unicast": {
3261 "neighbor": {
3262 "r3": {
3263 "dest_link": {
3264 "blue2-link1": {
3265 "keepalivetimer": KEEPALIVETIMER,
3266 "holddowntimer": HOLDDOWNTIMER,
3267 }
3268 }
3269 }
3270 }
3271 }
3272 },
3273 },
3274 },
3275 {
3276 "local_as": "800",
3277 "vrf": "BLUE_B",
3278 "address_family": {
3279 "ipv4": {
3280 "unicast": {
3281 "neighbor": {
3282 "r3": {
3283 "dest_link": {
3284 "blue2-link2": {
3285 "keepalivetimer": KEEPALIVETIMER,
3286 "holddowntimer": HOLDDOWNTIMER,
3287 }
3288 }
3289 }
3290 }
3291 }
3292 },
3293 "ipv6": {
3294 "unicast": {
3295 "neighbor": {
3296 "r3": {
3297 "dest_link": {
3298 "blue2-link2": {
3299 "keepalivetimer": KEEPALIVETIMER,
3300 "holddowntimer": HOLDDOWNTIMER,
3301 }
3302 }
3303 }
3304 }
3305 }
3306 },
3307 },
3308 },
3309 ]
3310 },
3311 }
3312
3313 result = create_router_bgp(tgen, topo, input_dict_4)
3314 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
3315
3316 for addr_type in ADDR_TYPES:
3317 clear_bgp(tgen, addr_type, "r3", vrf=["RED_A", "RED_B", "BLUE_A", "BLUE_B"])
3318
3319 clear_bgp(tgen, addr_type, "red2", vrf=["RED_A", "RED_B"])
3320
3321 clear_bgp(tgen, addr_type, "blue2", vrf=["BLUE_A", "BLUE_B"])
3322
3323 step("Delete vrfs RED_A and BLUE_A from R3")
3324
3325 input_dict = {
3326 "r3": {
3327 "vrfs": [
3328 {"name": "RED_A", "id": "1", "delete": True},
3329 {"name": "BLUE_A", "id": "3", "delete": True},
3330 ]
3331 }
3332 }
3333
3334 result = create_vrf_cfg(tgen, input_dict)
3335 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
3336
3337 step("Waiting for {}+1..".format(HOLDDOWNTIMER))
3338 sleep(HOLDDOWNTIMER + 1)
3339
3340 step("Verify RIB and FIB after deleting VRFs")
3341
3342 for addr_type in ADDR_TYPES:
3343 dut = "red2"
3344 input_dict_1 = {
3345 "red1": {
3346 "static_routes": [
3347 {
3348 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
3349 "next_hop": NEXT_HOP_IP[addr_type],
3350 "vrf": "RED_A",
3351 }
3352 ]
3353 }
3354 }
3355
3356 result = verify_rib(tgen, addr_type, dut, input_dict_1, expected=False)
3357 assert (
3358 result is not True
3359 ), "Testcase {} :Failed \n Expected Behaviour: Routes are not present \n Error {}".format(
3360 tc_name, result
3361 )
3362
3363 result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1, expected=False)
3364 assert (
3365 result is not True
3366 ), "Testcase {} :Failed \n Expected Behaviour: Routes are not present \n Error {}".format(
3367 tc_name, result
3368 )
3369
3370 for addr_type in ADDR_TYPES:
3371 dut = "blue2"
3372 input_dict_2 = {
3373 "blue1": {
3374 "static_routes": [
3375 {
3376 "network": [NETWORK3_1[addr_type]] + [NETWORK3_2[addr_type]],
3377 "next_hop": NEXT_HOP_IP[addr_type],
3378 "vrf": "BLUE_A",
3379 }
3380 ]
3381 }
3382 }
3383
3384 result = verify_rib(tgen, addr_type, dut, input_dict_2, expected=False)
3385 assert (
3386 result is not True
3387 ), "Testcase {} :Failed \n Expected Behaviour: Routes are not present \n Error {}".format(
3388 tc_name, result
3389 )
3390
3391 result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2, expected=False)
3392 assert (
3393 result is not True
3394 ), "Testcase {} :Failed \n Expected Behaviour: Routes are not present \n Error {}".format(
3395 tc_name, result
3396 )
3397
3398 step("Create 2 new VRFs PINK_A and GREY_A IN R3")
3399
3400 topo_modify = deepcopy(topo)
3401 topo_modify["routers"]["r3"]["vrfs"][0]["name"] = "PINK_A"
3402 topo_modify["routers"]["r3"]["vrfs"][0]["id"] = "1"
3403 topo_modify["routers"]["r3"]["vrfs"][2]["name"] = "GREY_A"
3404 topo_modify["routers"]["r3"]["vrfs"][2]["id"] = "3"
3405
3406 topo_modify["routers"]["r3"]["links"]["red2-link1"]["vrf"] = "PINK_A"
3407 topo_modify["routers"]["r3"]["links"]["blue2-link1"]["vrf"] = "GREY_A"
3408
3409 topo_modify["routers"]["r3"]["links"]["r2-link1"]["vrf"] = "PINK_A"
3410 topo_modify["routers"]["r3"]["links"]["r2-link3"]["vrf"] = "GREY_A"
3411
3412 topo_modify["routers"]["r3"]["links"]["r4-link1"]["vrf"] = "PINK_A"
3413 topo_modify["routers"]["r3"]["links"]["r4-link3"]["vrf"] = "GREY_A"
3414
3415 topo_modify["routers"]["r3"]["bgp"][0]["vrf"] = "PINK_A"
3416 topo_modify["routers"]["r3"]["bgp"][2]["vrf"] = "GREY_A"
3417
3418 result = create_vrf_cfg(tgen, {"r3": topo_modify["routers"]["r3"]})
3419 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
3420
3421 create_interfaces_cfg(tgen, {"r3": topo_modify["routers"]["r3"]})
3422 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
3423
3424 result = create_router_bgp(tgen, topo_modify["routers"])
3425 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
3426
3427 step("Api call to modify BGP timers")
3428
3429 input_dict_4 = {
3430 "r3": {
3431 "bgp": [
3432 {
3433 "local_as": "200",
3434 "vrf": "PINK_A",
3435 "address_family": {
3436 "ipv4": {
3437 "unicast": {
3438 "neighbor": {
3439 "red2": {
3440 "dest_link": {
3441 "r3-link1": {
3442 "keepalivetimer": KEEPALIVETIMER,
3443 "holddowntimer": HOLDDOWNTIMER,
3444 }
3445 }
3446 }
3447 }
3448 }
3449 },
3450 "ipv6": {
3451 "unicast": {
3452 "neighbor": {
3453 "red2": {
3454 "dest_link": {
3455 "r3-link1": {
3456 "keepalivetimer": KEEPALIVETIMER,
3457 "holddowntimer": HOLDDOWNTIMER,
3458 }
3459 }
3460 }
3461 }
3462 }
3463 },
3464 },
3465 },
3466 {
3467 "local_as": "200",
3468 "vrf": "RED_B",
3469 "address_family": {
3470 "ipv4": {
3471 "unicast": {
3472 "neighbor": {
3473 "red2": {
3474 "dest_link": {
3475 "r3-link2": {
3476 "keepalivetimer": KEEPALIVETIMER,
3477 "holddowntimer": HOLDDOWNTIMER,
3478 }
3479 }
3480 }
3481 }
3482 }
3483 },
3484 "ipv6": {
3485 "unicast": {
3486 "neighbor": {
3487 "red2": {
3488 "dest_link": {
3489 "r3-link2": {
3490 "keepalivetimer": KEEPALIVETIMER,
3491 "holddowntimer": HOLDDOWNTIMER,
3492 }
3493 }
3494 }
3495 }
3496 }
3497 },
3498 },
3499 },
3500 {
3501 "local_as": "200",
3502 "vrf": "GREY_A",
3503 "address_family": {
3504 "ipv4": {
3505 "unicast": {
3506 "neighbor": {
3507 "blue2": {
3508 "dest_link": {
3509 "r3-link1": {
3510 "keepalivetimer": KEEPALIVETIMER,
3511 "holddowntimer": HOLDDOWNTIMER,
3512 }
3513 }
3514 }
3515 }
3516 }
3517 },
3518 "ipv6": {
3519 "unicast": {
3520 "neighbor": {
3521 "blue2": {
3522 "dest_link": {
3523 "r3-link1": {
3524 "keepalivetimer": KEEPALIVETIMER,
3525 "holddowntimer": HOLDDOWNTIMER,
3526 }
3527 }
3528 }
3529 }
3530 }
3531 },
3532 },
3533 },
3534 {
3535 "local_as": "200",
3536 "vrf": "BLUE_B",
3537 "address_family": {
3538 "ipv4": {
3539 "unicast": {
3540 "neighbor": {
3541 "blue2": {
3542 "dest_link": {
3543 "r3-link2": {
3544 "keepalivetimer": KEEPALIVETIMER,
3545 "holddowntimer": HOLDDOWNTIMER,
3546 }
3547 }
3548 }
3549 }
3550 }
3551 },
3552 "ipv6": {
3553 "unicast": {
3554 "neighbor": {
3555 "blue2": {
3556 "dest_link": {
3557 "r3-link2": {
3558 "keepalivetimer": KEEPALIVETIMER,
3559 "holddowntimer": HOLDDOWNTIMER,
3560 }
3561 }
3562 }
3563 }
3564 }
3565 },
3566 },
3567 },
3568 ]
3569 }
3570 }
3571
3572 result = create_router_bgp(tgen, topo_modify, input_dict_4)
3573 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
3574
3575 for addr_type in ADDR_TYPES:
3576 clear_bgp(tgen, addr_type, "r3", vrf=["PINK_A", "RED_B", "GREY_A", "BLUE_B"])
3577
3578 step(
3579 "After deleting VRFs ipv6 addresses will be deleted from kernel "
3580 " Adding back ipv6 addresses"
3581 )
3582
3583 dut = "r3"
3584 vrfs = ["GREY_A", "PINK_A"]
3585
3586 for vrf in vrfs:
3587 for c_link, c_data in topo_modify["routers"][dut]["links"].items():
3588 if c_data["vrf"] != vrf:
3589 continue
3590
3591 intf_name = c_data["interface"]
3592 intf_ipv6 = c_data["ipv6"]
3593
3594 create_interface_in_kernel(
3595 tgen, dut, intf_name, intf_ipv6, vrf, create=False
3596 )
3597
3598 step("Waiting for {}+1 sec..".format(HOLDDOWNTIMER))
3599 sleep(HOLDDOWNTIMER + 1)
3600
3601 step(
3602 "Advertised prefixes should appear again in respective VRF"
3603 " table on routers RED_2 and BLUE_2. Verify fib and rib entries"
3604 )
3605
3606 for addr_type in ADDR_TYPES:
3607 dut = "red2"
3608 input_dict_1 = {
3609 "red1": {
3610 "static_routes": [
3611 {
3612 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
3613 "next_hop": NEXT_HOP_IP[addr_type],
3614 "vrf": "RED_A",
3615 }
3616 ]
3617 }
3618 }
3619
3620 input_dict_2 = {
3621 "red1": {
3622 "static_routes": [
3623 {
3624 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
3625 "next_hop": NEXT_HOP_IP[addr_type],
3626 "vrf": "RED_B",
3627 }
3628 ]
3629 }
3630 }
3631
3632 result = verify_bgp_rib(tgen, addr_type, dut, input_dict_1)
3633 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
3634
3635 result = verify_bgp_rib(tgen, addr_type, dut, input_dict_2)
3636 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
3637
3638 result = verify_rib(tgen, addr_type, dut, input_dict_1)
3639 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
3640
3641 result = verify_rib(tgen, addr_type, dut, input_dict_2)
3642 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
3643
3644 for addr_type in ADDR_TYPES:
3645 dut = "blue2"
3646 input_dict_3 = {
3647 "blue1": {
3648 "static_routes": [
3649 {
3650 "network": [NETWORK3_1[addr_type]] + [NETWORK3_2[addr_type]],
3651 "next_hop": NEXT_HOP_IP[addr_type],
3652 "vrf": "BLUE_A",
3653 }
3654 ]
3655 }
3656 }
3657
3658 input_dict_4 = {
3659 "blue1": {
3660 "static_routes": [
3661 {
3662 "network": [NETWORK4_1[addr_type]] + [NETWORK4_2[addr_type]],
3663 "next_hop": NEXT_HOP_IP[addr_type],
3664 "vrf": "BLUE_B",
3665 }
3666 ]
3667 }
3668 }
3669
3670 result = verify_bgp_rib(tgen, addr_type, dut, input_dict_3)
3671 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
3672
3673 result = verify_bgp_rib(tgen, addr_type, dut, input_dict_4)
3674 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
3675
3676 result = verify_rib(tgen, addr_type, dut, input_dict_3)
3677 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
3678
3679 result = verify_rib(tgen, addr_type, dut, input_dict_4)
3680 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
3681
3682 write_test_footer(tc_name)
3683
3684
3685 def test_restart_frr_services_p1(request):
3686 """
3687 CHAOS_8:
3688 Restart all FRR services (reboot DUT) to check if all
3689 the routes in respective vrfs are reinstalled.
3690 """
3691
3692 tgen = get_topogen()
3693 tc_name = request.node.name
3694 write_test_header(tc_name)
3695 reset_config_on_routers(tgen)
3696
3697 if tgen.routers_have_failure():
3698 check_router_status(tgen)
3699
3700 step(
3701 "Advertise unique BGP prefixes(IPv4+IPv6) from RED_1"
3702 " in vrf instances(RED_A and RED_B)."
3703 )
3704
3705 for addr_type in ADDR_TYPES:
3706 input_dict_1 = {
3707 "red1": {
3708 "static_routes": [
3709 {
3710 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
3711 "next_hop": NEXT_HOP_IP[addr_type],
3712 "vrf": "RED_A",
3713 },
3714 {
3715 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
3716 "next_hop": NEXT_HOP_IP[addr_type],
3717 "vrf": "RED_B",
3718 },
3719 ]
3720 }
3721 }
3722 result = create_static_routes(tgen, input_dict_1)
3723 assert result is True, "Testcase {} : Failed \n Error: {}".format(
3724 tc_name, result
3725 )
3726
3727 step(
3728 "Advertise unique BGP prefixes(IPv4+IPv6) from BLUE_1 in"
3729 " vrf instances(BLUE_A and BLUE_B)."
3730 )
3731
3732 for addr_type in ADDR_TYPES:
3733 input_dict_2 = {
3734 "blue1": {
3735 "static_routes": [
3736 {
3737 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
3738 "next_hop": NEXT_HOP_IP[addr_type],
3739 "vrf": "BLUE_A",
3740 },
3741 {
3742 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
3743 "next_hop": NEXT_HOP_IP[addr_type],
3744 "vrf": "BLUE_B",
3745 },
3746 ]
3747 }
3748 }
3749 result = create_static_routes(tgen, input_dict_2)
3750 assert result is True, "Testcase {} : Failed \n Error: {}".format(
3751 tc_name, result
3752 )
3753
3754 step("Redistribute static..")
3755
3756 input_dict_3 = {}
3757 for dut in ["red1", "blue1"]:
3758 temp = {dut: {"bgp": []}}
3759 input_dict_3.update(temp)
3760
3761 if "red" in dut:
3762 VRFS = ["RED_A", "RED_B"]
3763 AS_NUM = [500, 500]
3764 elif "blue" in dut:
3765 VRFS = ["BLUE_A", "BLUE_B"]
3766 AS_NUM = [800, 800]
3767
3768 for vrf, as_num in zip(VRFS, AS_NUM):
3769 temp[dut]["bgp"].append(
3770 {
3771 "local_as": as_num,
3772 "vrf": vrf,
3773 "address_family": {
3774 "ipv4": {
3775 "unicast": {"redistribute": [{"redist_type": "static"}]}
3776 },
3777 "ipv6": {
3778 "unicast": {"redistribute": [{"redist_type": "static"}]}
3779 },
3780 },
3781 }
3782 )
3783
3784 result = create_router_bgp(tgen, topo, input_dict_3)
3785 assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
3786
3787 step("Restart frr on R1")
3788 stop_router(tgen, "r1")
3789 start_router(tgen, "r1")
3790
3791 for addr_type in ADDR_TYPES:
3792 dut = "r2"
3793
3794 input_dict_1 = {
3795 "red1": {
3796 "static_routes": [
3797 {
3798 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
3799 "next_hop": NEXT_HOP_IP[addr_type],
3800 "vrf": "RED_A",
3801 },
3802 {
3803 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
3804 "next_hop": NEXT_HOP_IP[addr_type],
3805 "vrf": "RED_B",
3806 },
3807 ]
3808 }
3809 }
3810
3811 input_dict_2 = {
3812 "blue1": {
3813 "static_routes": [
3814 {
3815 "network": [NETWORK1_1[addr_type]] + [NETWORK1_2[addr_type]],
3816 "next_hop": NEXT_HOP_IP[addr_type],
3817 "vrf": "BLUE_A",
3818 },
3819 {
3820 "network": [NETWORK2_1[addr_type]] + [NETWORK2_2[addr_type]],
3821 "next_hop": NEXT_HOP_IP[addr_type],
3822 "vrf": "BLUE_B",
3823 },
3824 ]
3825 }
3826 }
3827
3828 result = verify_rib(tgen, addr_type, dut, input_dict_1)
3829 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
3830
3831 result = verify_rib(tgen, addr_type, dut, input_dict_2)
3832 assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result)
3833
3834 write_test_footer(tc_name)
3835
3836
3837 if __name__ == "__main__":
3838 args = ["-s"] + sys.argv[1:]
3839 sys.exit(pytest.main(args))