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