]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/bgp_distance_change/test_bgp_admin_dist.py
doc: Add `show ipv6 rpf X:X::X:X` command to docs
[mirror_frr.git] / tests / topotests / bgp_distance_change / test_bgp_admin_dist.py
1 #!/usr/bin/env python
2
3 #
4 # Copyright (c) 2022 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 import sys
24 import time
25 import pytest
26 import inspect
27 import os
28
29
30 """Following tests are covered to test bgp admin distance functionality.
31 TC_1:
32 Verify bgp admin distance functionality when static route is
33 configured same as ebgp learnt route
34
35 TC_2:
36 Verify ebgp admin distance functionality with ECMP.
37
38 TC_3:
39 Verify ibgp admin distance functionality when static route is
40 configured same as bgp learnt route.
41 TC_4:
42 Verify ibgp admin distance functionality with ECMP.
43
44 TC_7: Chaos - Verify bgp admin distance functionality with chaos.
45 """
46
47 #################################
48 # TOPOLOGY
49 #################################
50 """
51
52 +-------+
53 +--------- | R2 |
54 | +-------+
55 |iBGP |
56 +-------+ |
57 | R1 | |iBGP
58 +-------+ |
59 | |
60 | iBGP +-------+ eBGP +-------+
61 +---------- | R3 |----------| R4 |
62 +-------+ +-------+
63 |
64 |eBGP
65 |
66 +-------+
67 | R5 |
68 +-------+
69
70
71 """
72
73 # Save the Current Working Directory to find configuration files.
74 CWD = os.path.dirname(os.path.realpath(__file__))
75 sys.path.append(os.path.join(CWD, "../"))
76 sys.path.append(os.path.join(CWD, "../lib/"))
77
78 # pylint: disable=C0413
79 # Import topogen and topotest helpers
80 from lib.topogen import Topogen, get_topogen
81
82 # Required to instantiate the topology builder class.
83 from lib.common_config import (
84 start_topology,
85 write_test_header,
86 step,
87 write_test_footer,
88 create_static_routes,
89 verify_rib,
90 create_route_maps,
91 create_prefix_lists,
92 check_address_types,
93 reset_config_on_routers,
94 check_router_status,
95 stop_router,
96 kill_router_daemons,
97 start_router_daemons,
98 start_router,
99 get_frr_ipv6_linklocal,
100 verify_fib_routes,
101 )
102 from lib.topolog import logger
103 from lib.bgp import (
104 verify_bgp_convergence,
105 create_router_bgp,
106 verify_best_path_as_per_admin_distance,
107 clear_bgp,
108 )
109
110 # pylint: disable=C0413
111 # Import topogen and topotest helpers
112 from lib.topogen import Topogen, get_topogen
113 from lib.topojson import build_config_from_json
114 from lib.topolog import logger
115
116 # Global variables
117 topo = None
118 bgp_convergence = False
119 pytestmark = [pytest.mark.bgpd, pytest.mark.staticd]
120
121 NETWORK = {
122 "ipv4": [
123 "192.168.20.1/32",
124 "192.168.20.2/32",
125 "192.168.21.1/32",
126 "192.168.21.2/32",
127 "192.168.22.1/32",
128 "192.168.22.2/32",
129 ],
130 "ipv6": [
131 "fc07:50::1/128",
132 "fc07:50::2/128",
133 "fc07:150::1/128",
134 "fc07:150::2/128",
135 "fc07:1::1/128",
136 "fc07:1::2/128",
137 ],
138 }
139
140 ADDR_TYPES = check_address_types()
141
142
143 def setup_module(mod):
144 """
145 Sets up the pytest environment
146
147 * `mod`: module name
148 """
149
150 global topo
151
152 testsuite_run_time = time.asctime(time.localtime(time.time()))
153 logger.info("Testsuite start time: {}".format(testsuite_run_time))
154 logger.info("=" * 40)
155
156 logger.info("Running setup_module to create topology")
157
158 # This function initiates the topology build with Topogen...
159 json_file = "{}/bgp_admin_dist.json".format(CWD)
160 tgen = Topogen(json_file, mod.__name__)
161 global topo
162 topo = tgen.json_topo
163
164 # Starting topology, create tmp files which are loaded to routers
165 # to start deamons and then start routers
166 start_topology(tgen)
167
168 # Creating configuration from JSON
169 build_config_from_json(tgen, topo)
170
171 # Checking BGP convergence
172 global bgp_convergence
173 global ADDR_TYPES
174
175 # Don't run this test if we have any failure.
176 if tgen.routers_have_failure():
177 pytest.skip(tgen.errors)
178
179 # Api call verify whether BGP is converged
180 bgp_convergence = verify_bgp_convergence(tgen, topo)
181 assert bgp_convergence is True, "setup_module :Failed \n Error:" " {}".format(
182 bgp_convergence
183 )
184 logger.info("Running setup_module() done")
185
186
187 def teardown_module(mod):
188 """teardown_module.
189
190 Teardown the pytest environment.
191 * `mod`: module name
192 """
193 logger.info("Running teardown_module to delete topology")
194 tgen = get_topogen()
195
196 # Stop toplogy and Remove tmp files
197 tgen.stop_topology()
198
199 logger.info(
200 "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
201 )
202 logger.info("=" * 40)
203
204
205 #####################################################
206 # Tests starting
207 #####################################################
208 def test_bgp_admin_distance_ebgp_ecmp_p0():
209 """
210 TC: 2
211 Verify ebgp admin distance functionality with ECMP.
212 """
213 tgen = get_topogen()
214 global bgp_convergence
215
216 if bgp_convergence is not True:
217 pytest.skip("skipping test case because of BGP Convergence failure at setup")
218
219 # test case name
220 tc_name = inspect.stack()[0][3]
221 write_test_header(tc_name)
222 if tgen.routers_have_failure():
223 check_router_status(tgen)
224
225 step("Configure base config as per the topology")
226 reset_config_on_routers(tgen)
227
228 step("Configure static route in R4 and R5, redistribute in bgp")
229
230 for addr_type in ADDR_TYPES:
231
232 input_dict = {
233 "r4": {
234 "static_routes": [{"network": NETWORK[addr_type], "next_hop": "Null0"}]
235 }
236 }
237
238 result = create_static_routes(tgen, input_dict)
239 assert result is True, "Testcase {} : Failed \n Error: {}".format(
240 tc_name, result
241 )
242
243 for addr_type in ADDR_TYPES:
244
245 input_dict = {
246 "r5": {
247 "static_routes": [{"network": NETWORK[addr_type], "next_hop": "Null0"}]
248 }
249 }
250
251 result = create_static_routes(tgen, input_dict)
252 assert result is True, "Testcase {} : Failed \n Error: {}".format(
253 tc_name, result
254 )
255
256 step("Verify that route is learnt in DUT via ebgp")
257
258 # Verifying RIB routes
259 protocol = "bgp"
260 input_dict = topo["routers"]
261 dut = "r3"
262 nhop = {"ipv4": [], "ipv6": []}
263 nhop["ipv4"].append(topo["routers"]["r4"]["links"]["r3"]["ipv4"].split("/")[0])
264 nhop["ipv4"].append(topo["routers"]["r5"]["links"]["r3"]["ipv4"].split("/")[0])
265 nhop["ipv6"].append(get_frr_ipv6_linklocal(tgen, "r4", "r3-r4-eth1"))
266 nhop["ipv6"].append(get_frr_ipv6_linklocal(tgen, "r5", "r1-r3-eth1"))
267
268 for addr_type in ADDR_TYPES:
269 input_dict = {
270 "r3": {
271 "static_routes": [
272 {"network": NETWORK[addr_type][0], "next_hop": "Null0"}
273 ]
274 }
275 }
276 result4 = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
277 assert result4 is True, "Testcase {} : Failed \n Error: {}".format(
278 tc_name, result4
279 )
280
281 step("Configure the static route in R3 (Dut).")
282
283 for addr_type in ADDR_TYPES:
284
285 input_dict = {
286 "r3": {
287 "static_routes": [
288 {"network": NETWORK[addr_type][0], "next_hop": "Null0"}
289 ]
290 }
291 }
292
293 result = create_static_routes(tgen, input_dict)
294 assert result is True, "Testcase {} : Failed \n Error: {}".format(
295 tc_name, result
296 )
297
298 step("Verify that static route is selected as best route in zebra.")
299
300 # Verifying RIB routes
301 protocol = "static"
302 dut = "r3"
303
304 for addr_type in ADDR_TYPES:
305 input_dict = {
306 "r3": {
307 "static_routes": [
308 {"network": NETWORK[addr_type][0], "next_hop": "Null0"}
309 ]
310 }
311 }
312
313 result4 = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
314 assert result4 is True, "Testcase {} : Failed \n Error: {}".format(
315 tc_name, result4
316 )
317
318 step(" Configure the admin distance of 254 to static route in R3.")
319
320 for addr_type in ADDR_TYPES:
321
322 input_dict = {
323 "r3": {
324 "static_routes": [
325 {
326 "network": NETWORK[addr_type][0],
327 "next_hop": "Null0",
328 "admin_distance": 254,
329 }
330 ]
331 }
332 }
333
334 result = create_static_routes(tgen, input_dict)
335 assert result is True, "Testcase {} : Failed \n Error: {}".format(
336 tc_name, result
337 )
338
339 step("Verify that bgp routes are selected as best routes in zebra.")
340 protocol = "bgp"
341 dut = "r3"
342
343 for addr_type in ADDR_TYPES:
344 input_dict = {
345 "r3": {
346 "static_routes": [
347 {"network": NETWORK[addr_type][0], "next_hop": "Null0"}
348 ]
349 }
350 }
351 result4 = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
352 assert result4 is True, "Testcase {} : Failed \n Error: {}".format(
353 tc_name, result4
354 )
355
356 input_dict_1 = {
357 "r3": {
358 "bgp": {
359 "local_as": 100,
360 "address_family": {
361 "ipv4": {
362 "unicast": {
363 "distance": {"ebgp": 254, "ibgp": 254, "local": 254}
364 }
365 },
366 "ipv6": {
367 "unicast": {
368 "distance": {"ebgp": 254, "ibgp": 254, "local": 254}
369 }
370 },
371 },
372 }
373 }
374 }
375
376 result = create_router_bgp(tgen, topo, input_dict_1)
377 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
378
379 step("Verify that bgp routes are selected as best routes in zebra.")
380 # Verifying RIB routes
381 protocol = "bgp"
382 dut = "r3"
383
384 for addr_type in ADDR_TYPES:
385 input_dict = {
386 "r3": {
387 "static_routes": [
388 {"network": NETWORK[addr_type][0], "next_hop": "Null0"}
389 ]
390 }
391 }
392 result4 = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
393 assert result4 is True, "Testcase {} : Failed \n Error: {}".format(
394 tc_name, result4
395 )
396
397 step("Configure bgp admin distance 10 with CLI in dut.")
398 input_dict_1 = {
399 "r3": {
400 "bgp": {
401 "local_as": 100,
402 "address_family": {
403 "ipv4": {
404 "unicast": {"distance": {"ebgp": 10, "ibgp": 254, "local": 254}}
405 },
406 "ipv6": {
407 "unicast": {"distance": {"ebgp": 10, "ibgp": 254, "local": 254}}
408 },
409 },
410 }
411 }
412 }
413
414 result = create_router_bgp(tgen, topo, input_dict_1)
415 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
416
417 step("Verify ebgp routes have admin distance of 10 in dut.")
418
419 protocol = "bgp"
420 input_dict = topo["routers"]
421 dut = "r3"
422
423 for addr_type in ADDR_TYPES:
424 input_dict = {
425 "r3": {
426 "static_routes": [
427 {"network": NETWORK[addr_type][0], "next_hop": "Null0"}
428 ]
429 }
430 }
431 result4 = verify_rib(
432 tgen, addr_type, dut, input_dict, protocol=protocol, admin_distance=10
433 )
434 assert result4 is True, "Testcase {} : Failed \n Error: {}".format(
435 tc_name, result4
436 )
437
438 step(
439 "Configure route map with weight as 200 and apply to one of the "
440 "neighbor (R4 neighbor)."
441 )
442
443 # Create Prefix list
444 input_dict_2 = {
445 "r3": {
446 "prefix_lists": {
447 "ipv4": {
448 "pf_ls_1": [
449 {
450 "seqid": 10,
451 "network": NETWORK["ipv4"][0],
452 "le": "32",
453 "action": "permit",
454 }
455 ]
456 },
457 "ipv6": {
458 "pf_ls_1_ipv6": [
459 {
460 "seqid": 100,
461 "network": NETWORK["ipv6"][0],
462 "le": "128",
463 "action": "permit",
464 }
465 ]
466 },
467 }
468 }
469 }
470 result = create_prefix_lists(tgen, input_dict_2)
471 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
472
473 # Create route map
474 input_dict_3 = {
475 "r3": {
476 "route_maps": {
477 "RMAP_WEIGHT": [
478 {
479 "action": "permit",
480 "match": {"ipv4": {"prefix_lists": "pf_ls_1"}},
481 "set": {"weight": 200},
482 },
483 {
484 "action": "permit",
485 "match": {"ipv6": {"prefix_lists": "pf_ls_1_ipv6"}},
486 "set": {"weight": 200},
487 },
488 ]
489 }
490 }
491 }
492 result = create_route_maps(tgen, input_dict_3)
493 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
494
495 # Configure neighbor for route map
496 input_dict_4 = {
497 "r3": {
498 "bgp": {
499 "address_family": {
500 "ipv4": {
501 "unicast": {
502 "neighbor": {
503 "r4": {
504 "dest_link": {
505 "r3": {
506 "route_maps": [
507 {
508 "name": "RMAP_WEIGHT",
509 "direction": "in",
510 }
511 ]
512 }
513 }
514 }
515 }
516 }
517 },
518 "ipv6": {
519 "unicast": {
520 "neighbor": {
521 "r4": {
522 "dest_link": {
523 "r3": {
524 "route_maps": [
525 {
526 "name": "RMAP_WEIGHT",
527 "direction": "in",
528 }
529 ]
530 }
531 }
532 }
533 }
534 }
535 },
536 }
537 }
538 }
539 }
540 result = create_router_bgp(tgen, topo, input_dict_4)
541 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
542
543 step("Verify that bgp route is selected as best on by zebra in r3.")
544
545 protocol = "bgp"
546 dut = "r3"
547
548 for addr_type in ADDR_TYPES:
549 input_dict = {
550 "r3": {
551 "static_routes": [
552 {"network": NETWORK[addr_type][0], "next_hop": "Null0"}
553 ]
554 }
555 }
556 result4 = verify_rib(
557 tgen, addr_type, dut, input_dict, protocol=protocol, admin_distance=10
558 )
559 assert result4 is True, "Testcase {} : Failed \n Error: {}".format(
560 tc_name, result4
561 )
562
563 step("Static route should not be selected as best route.")
564 protocol = "static"
565 dut = "r3"
566
567 for addr_type in ADDR_TYPES:
568 input_dict = {
569 "r3": {
570 "static_routes": [
571 {"network": NETWORK[addr_type][0], "next_hop": "Null0"}
572 ]
573 }
574 }
575 result4 = verify_fib_routes(
576 tgen, addr_type, dut, input_dict, protocol=protocol, expected=False
577 )
578 assert (
579 result4 is not True
580 ), "Testcase {} : Failed. Wrong route is selected as best route.\n Error: {}".format(
581 tc_name, result4
582 )
583
584 step("Reconfigure the static route without admin distance")
585
586 for addr_type in ADDR_TYPES:
587
588 input_dict = {
589 "r3": {
590 "static_routes": [
591 {
592 "network": NETWORK[addr_type][0],
593 "next_hop": "Null0",
594 "admin_distance": 254,
595 "delete": True,
596 }
597 ]
598 }
599 }
600
601 result = create_static_routes(tgen, input_dict)
602 assert result is True, "Testcase {} : Failed \n Error: {}".format(
603 tc_name, result
604 )
605
606 for addr_type in ADDR_TYPES:
607 input_dict = {
608 "r3": {
609 "static_routes": [
610 {"network": NETWORK[addr_type][0], "next_hop": "Null0"}
611 ]
612 }
613 }
614
615 result = create_static_routes(tgen, input_dict)
616 assert result is True, "Testcase {} : Failed \n Error: {}".format(
617 tc_name, result
618 )
619
620 step("Verify that static route is installed as best route.")
621 protocol = "static"
622 dut = "r3"
623
624 for addr_type in ADDR_TYPES:
625 input_dict = {
626 "r3": {
627 "static_routes": [
628 {"network": NETWORK[addr_type][0], "next_hop": "Null0"}
629 ]
630 }
631 }
632 result4 = verify_rib(
633 tgen, addr_type, dut, input_dict, protocol=protocol, fib=True
634 )
635 assert result4 is True, "Testcase {} : Failed \n Error: {}".format(
636 tc_name, result4
637 )
638
639 step("Unconfigure the static route in R3.")
640
641 for addr_type in ADDR_TYPES:
642 input_dict = {
643 "r3": {
644 "static_routes": [
645 {
646 "network": NETWORK[addr_type][0],
647 "next_hop": "Null0",
648 "delete": True,
649 }
650 ]
651 }
652 }
653
654 result = create_static_routes(tgen, input_dict)
655 assert result is True, "Testcase {} : Failed \n Error: {}".format(
656 tc_name, result
657 )
658
659 step("Verify that bgp route is selected as best on by zebra in r3.")
660
661 protocol = "bgp"
662 dut = "r3"
663
664 for addr_type in ADDR_TYPES:
665 input_dict = {
666 "r3": {
667 "static_routes": [
668 {"network": NETWORK[addr_type][0], "next_hop": "Null0"}
669 ]
670 }
671 }
672 result4 = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
673 assert result4 is True, "Testcase {} : Failed \n Error: {}".format(
674 tc_name, result4
675 )
676
677 step("Un configure the route map on R3.")
678
679 # Configure neighbor for route map
680 input_dict_4 = {
681 "r3": {
682 "bgp": {
683 "address_family": {
684 "ipv4": {
685 "unicast": {
686 "neighbor": {
687 "r4": {
688 "dest_link": {
689 "r3": {
690 "route_maps": [
691 {
692 "name": "RMAP_WEIGHT",
693 "direction": "in",
694 "delete": True,
695 }
696 ]
697 }
698 }
699 }
700 }
701 }
702 },
703 "ipv6": {
704 "unicast": {
705 "neighbor": {
706 "r4": {
707 "dest_link": {
708 "r3": {
709 "route_maps": [
710 {
711 "name": "RMAP_WEIGHT",
712 "direction": "in",
713 "delete": True,
714 }
715 ]
716 }
717 }
718 }
719 }
720 }
721 },
722 }
723 }
724 }
725 }
726 result = create_router_bgp(tgen, topo, input_dict_4)
727 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
728
729 step("verify bgp routes installed in zebra.")
730
731 # Verifying RIB routes
732 protocol = "bgp"
733 input_dict = topo["routers"]
734 dut = "r3"
735 for addr_type in ADDR_TYPES:
736 input_dict = {
737 "r3": {
738 "static_routes": [
739 {"network": NETWORK[addr_type][0], "next_hop": "Null0"}
740 ]
741 }
742 }
743 result4 = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
744 assert result4 is True, "Testcase {} : Failed \n Error: {}".format(
745 tc_name, result4
746 )
747
748 write_test_footer(tc_name)
749
750
751 def test_bgp_admin_distance_ibgp_p0():
752 """
753 TC: 3
754 Verify bgp admin distance functionality when static route is
755 configured same as ibgp learnt route
756 """
757 tgen = get_topogen()
758 global bgp_convergence
759
760 if bgp_convergence is not True:
761 pytest.skip("skipping test case because of BGP Convergence failure at setup")
762
763 # test case name
764 tc_name = inspect.stack()[0][3]
765 write_test_header(tc_name)
766 if tgen.routers_have_failure():
767 check_router_status(tgen)
768
769 step("Configure base config as per the topology")
770 reset_config_on_routers(tgen)
771
772 step("Configure bgp admin distance 200 with CLI in dut.")
773
774 input_dict_1 = {
775 "r3": {
776 "bgp": {
777 "local_as": 100,
778 "address_family": {
779 "ipv4": {
780 "unicast": {
781 "distance": {"ebgp": 200, "ibgp": 200, "local": 200}
782 }
783 },
784 "ipv6": {
785 "unicast": {
786 "distance": {"ebgp": 200, "ibgp": 200, "local": 200}
787 }
788 },
789 },
790 }
791 }
792 }
793
794 result = create_router_bgp(tgen, topo, input_dict_1)
795 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
796
797 step("Verify bgp routes have admin distance of 200 in dut.")
798 # Verifying best path
799 dut = "r3"
800 attribute = "admin_distance"
801
802 input_dict = {
803 "ipv4": {
804 "r3": {
805 "static_routes": [
806 {
807 "network": "192.168.22.1/32",
808 "admin_distance": 200,
809 },
810 {
811 "network": "192.168.22.2/32",
812 "admin_distance": 200,
813 },
814 ]
815 }
816 },
817 "ipv6": {
818 "r3": {
819 "static_routes": [
820 {
821 "network": "fc07:1::1/128",
822 "admin_distance": 200,
823 },
824 {
825 "network": "fc07:1::2/128",
826 "admin_distance": 200,
827 },
828 ]
829 }
830 },
831 }
832
833 for addr_type in ADDR_TYPES:
834 result = verify_best_path_as_per_admin_distance(
835 tgen, addr_type, dut, input_dict[addr_type], attribute
836 )
837 assert result is True, "Testcase {} : Failed \n Error: {}".format(
838 tc_name, result
839 )
840
841 step("Modify the admin distance value to 150.")
842
843 input_dict_1 = {
844 "r3": {
845 "bgp": {
846 "local_as": 100,
847 "address_family": {
848 "ipv4": {
849 "unicast": {
850 "distance": {"ebgp": 150, "ibgp": 150, "local": 150}
851 }
852 },
853 "ipv6": {
854 "unicast": {
855 "distance": {"ebgp": 150, "ibgp": 150, "local": 150}
856 }
857 },
858 },
859 }
860 }
861 }
862
863 result = create_router_bgp(tgen, topo, input_dict_1)
864 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
865
866 step("Verify bgp routes have admin distance of 150 in dut.")
867 # Verifying best path
868 dut = "r3"
869 attribute = "admin_distance"
870
871 input_dict = {
872 "ipv4": {
873 "r3": {
874 "static_routes": [
875 {
876 "network": "192.168.22.1/32",
877 "admin_distance": 150,
878 },
879 {
880 "network": "192.168.22.2/32",
881 "admin_distance": 150,
882 },
883 ]
884 }
885 },
886 "ipv6": {
887 "r3": {
888 "static_routes": [
889 {
890 "network": "fc07:1::1/128",
891 "admin_distance": 150,
892 },
893 {
894 "network": "fc07:1::2/128",
895 "admin_distance": 150,
896 },
897 ]
898 }
899 },
900 }
901
902 for addr_type in ADDR_TYPES:
903 result = verify_best_path_as_per_admin_distance(
904 tgen, addr_type, dut, input_dict[addr_type], attribute
905 )
906 assert result is True, "Testcase {} : Failed \n Error: {}".format(
907 tc_name, result
908 )
909
910 step("Un configure the admin distance value on DUT")
911
912 input_dict_1 = {
913 "r3": {
914 "bgp": {
915 "local_as": 100,
916 "address_family": {
917 "ipv4": {
918 "unicast": {
919 "distance": {
920 "ebgp": 150,
921 "ibgp": 150,
922 "local": 150,
923 "delete": True,
924 }
925 }
926 },
927 "ipv6": {
928 "unicast": {
929 "distance": {
930 "ebgp": 150,
931 "ibgp": 150,
932 "local": 150,
933 "delete": True,
934 }
935 }
936 },
937 },
938 }
939 }
940 }
941
942 result = create_router_bgp(tgen, topo, input_dict_1)
943 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
944
945 step("Verify bgp routes have default admin distance in dut.")
946 # Verifying best path
947 dut = "r3"
948 attribute = "admin_distance"
949
950 input_dict = {
951 "ipv4": {
952 "r3": {
953 "static_routes": [
954 {
955 "network": "192.168.22.1/32",
956 "admin_distance": 20,
957 },
958 {
959 "network": "192.168.22.2/32",
960 "admin_distance": 20,
961 },
962 ]
963 }
964 },
965 "ipv6": {
966 "r3": {
967 "static_routes": [
968 {
969 "network": "fc07:1::1/128",
970 "admin_distance": 20,
971 },
972 {
973 "network": "fc07:1::2/128",
974 "admin_distance": 20,
975 },
976 ]
977 }
978 },
979 }
980
981 for addr_type in ADDR_TYPES:
982 result = verify_best_path_as_per_admin_distance(
983 tgen, addr_type, dut, input_dict[addr_type], attribute
984 )
985 assert result is True, "Testcase {} : Failed \n Error: {}".format(
986 tc_name, result
987 )
988
989 step(
990 "Learn the same route via ebgp and ibgp peer. Configure admin "
991 "distance of 200 in DUT for both ebgp and ibgp peer. "
992 )
993
994 step("Verify that ebgp route is preferred over ibgp.")
995
996 # Verifying RIB routes
997 protocol = "bgp"
998 input_dict = topo["routers"]
999
1000 for addr_type in ADDR_TYPES:
1001 result4 = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
1002 assert result4 is True, "Testcase {} : Failed \n Error: {}".format(
1003 tc_name, result4
1004 )
1005
1006 step("Configure static route Without any admin distance")
1007
1008 for addr_type in ADDR_TYPES:
1009
1010 input_dict = {
1011 "r3": {
1012 "static_routes": [{"network": NETWORK[addr_type], "next_hop": "Null0"}]
1013 }
1014 }
1015
1016 result = create_static_routes(tgen, input_dict)
1017 assert result is True, "Testcase {} : Failed \n Error: {}".format(
1018 tc_name, result
1019 )
1020
1021 step("Verify that zebra selects static route.")
1022 protocol = "static"
1023
1024 for addr_type in ADDR_TYPES:
1025
1026 input_dict = {
1027 "r3": {
1028 "static_routes": [{"network": NETWORK[addr_type], "next_hop": "Null0"}]
1029 }
1030 }
1031
1032 result4 = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
1033 assert result4 is True, "Testcase {} : Failed \n Error: {}".format(
1034 tc_name, result4
1035 )
1036
1037 step("Configure static route with admin distance of 253")
1038 for addr_type in ADDR_TYPES:
1039
1040 input_dict = {
1041 "r3": {
1042 "static_routes": [
1043 {
1044 "network": NETWORK[addr_type],
1045 "next_hop": "Null0",
1046 "admin_distance": 253,
1047 }
1048 ]
1049 }
1050 }
1051
1052 result = create_static_routes(tgen, input_dict)
1053 assert result is True, "Testcase {} : Failed \n Error: {}".format(
1054 tc_name, result
1055 )
1056
1057 step("Verify that zebra selects bgp route.")
1058 protocol = "bgp"
1059
1060 for addr_type in ADDR_TYPES:
1061 result4 = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
1062 assert result4 is True, "Testcase {} : Failed \n Error: {}".format(
1063 tc_name, result4
1064 )
1065
1066 step("Configure admin distance of 254 in bgp for route.")
1067
1068 input_dict_1 = {
1069 "r3": {
1070 "bgp": {
1071 "local_as": 100,
1072 "address_family": {
1073 "ipv4": {
1074 "unicast": {
1075 "distance": {"ebgp": 254, "ibgp": 254, "local": 254}
1076 }
1077 },
1078 "ipv6": {
1079 "unicast": {
1080 "distance": {"ebgp": 254, "ibgp": 254, "local": 254}
1081 }
1082 },
1083 },
1084 }
1085 }
1086 }
1087
1088 result = create_router_bgp(tgen, topo, input_dict_1)
1089 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
1090
1091 step("Verify that zebra selects static route.")
1092 protocol = "static"
1093
1094 for addr_type in ADDR_TYPES:
1095 result4 = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
1096 assert result4 is True, "Testcase {} : Failed \n Error: {}".format(
1097 tc_name, result4
1098 )
1099
1100 step("Delete the static route.")
1101 for addr_type in ADDR_TYPES:
1102
1103 input_dict = {
1104 "r3": {
1105 "static_routes": [
1106 {
1107 "network": NETWORK[addr_type],
1108 "next_hop": "Null0",
1109 "admin_distance": 253,
1110 "delete": True,
1111 }
1112 ]
1113 }
1114 }
1115
1116 result = create_static_routes(tgen, input_dict)
1117 assert result is True, "Testcase {} : Failed \n Error: {}".format(
1118 tc_name, result
1119 )
1120
1121 step("Verify that zebra selects bgp route.")
1122 protocol = "bgp"
1123
1124 for addr_type in ADDR_TYPES:
1125 result4 = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
1126 assert result4 is True, "Testcase {} : Failed \n Error: {}".format(
1127 tc_name, result4
1128 )
1129
1130 write_test_footer(tc_name)
1131
1132
1133 def test_bgp_admin_distance_chaos_p2():
1134 """
1135 TC: 7
1136 Chaos - Verify bgp admin distance functionality with chaos.
1137 """
1138 tgen = get_topogen()
1139 global bgp_convergence
1140
1141 if bgp_convergence is not True:
1142 pytest.skip("skipping test case because of BGP Convergence failure at setup")
1143
1144 # test case name
1145 tc_name = inspect.stack()[0][3]
1146 write_test_header(tc_name)
1147 if tgen.routers_have_failure():
1148 check_router_status(tgen)
1149
1150 step("Configure base config as per the topology")
1151 reset_config_on_routers(tgen)
1152
1153 step("Configure bgp admin distance 200 with CLI in dut.")
1154
1155 input_dict_1 = {
1156 "r3": {
1157 "bgp": {
1158 "local_as": 100,
1159 "address_family": {
1160 "ipv4": {
1161 "unicast": {
1162 "distance": {"ebgp": 200, "ibgp": 200, "local": 200}
1163 }
1164 },
1165 "ipv6": {
1166 "unicast": {
1167 "distance": {"ebgp": 200, "ibgp": 200, "local": 200}
1168 }
1169 },
1170 },
1171 }
1172 }
1173 }
1174
1175 result = create_router_bgp(tgen, topo, input_dict_1)
1176 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
1177
1178 step("Verify bgp routes have admin distance of 200 in dut.")
1179 # Verifying best path
1180 dut = "r3"
1181 attribute = "admin_distance"
1182
1183 input_dict = {
1184 "ipv4": {
1185 "r3": {
1186 "static_routes": [
1187 {
1188 "network": NETWORK["ipv4"][0],
1189 "admin_distance": 200,
1190 },
1191 {
1192 "network": NETWORK["ipv4"][1],
1193 "admin_distance": 200,
1194 },
1195 ]
1196 }
1197 },
1198 "ipv6": {
1199 "r3": {
1200 "static_routes": [
1201 {
1202 "network": NETWORK["ipv6"][0],
1203 "admin_distance": 200,
1204 },
1205 {
1206 "network": NETWORK["ipv6"][1],
1207 "admin_distance": 200,
1208 },
1209 ]
1210 }
1211 },
1212 }
1213
1214 for addr_type in ADDR_TYPES:
1215 result = verify_best_path_as_per_admin_distance(
1216 tgen, addr_type, dut, input_dict[addr_type], attribute
1217 )
1218 assert result is True, "Testcase {} : Failed \n Error: {}".format(
1219 tc_name, result
1220 )
1221
1222 step("Restart frr on R3")
1223 stop_router(tgen, "r3")
1224 start_router(tgen, "r3")
1225
1226 bgp_convergence = verify_bgp_convergence(tgen, topo)
1227 assert bgp_convergence is True, "Testcase {} : Failed \n Error: {}".format(
1228 tc_name, bgp_convergence
1229 )
1230
1231 step("Verify ebgp and ibgp routes have admin distance of 200 in dut.")
1232 for addr_type in ADDR_TYPES:
1233 result = verify_best_path_as_per_admin_distance(
1234 tgen, addr_type, dut, input_dict[addr_type], attribute
1235 )
1236 assert result is True, "Testcase {} : Failed \n Error: {}".format(
1237 tc_name, result
1238 )
1239
1240 step("Restart bgpd process on R3")
1241 kill_router_daemons(tgen, "r3", ["bgpd"])
1242 start_router_daemons(tgen, "r3", ["bgpd"])
1243
1244 bgp_convergence = verify_bgp_convergence(tgen, topo)
1245 assert bgp_convergence is True, "Testcase {} : Failed \n Error: {}".format(
1246 tc_name, bgp_convergence
1247 )
1248
1249 step("Verify ebgp and ibgp routes have admin distance of 200 in dut.")
1250 for addr_type in ADDR_TYPES:
1251 result = verify_best_path_as_per_admin_distance(
1252 tgen, addr_type, dut, input_dict[addr_type], attribute
1253 )
1254 assert result is True, "Testcase {} : Failed \n Error: {}".format(
1255 tc_name, result
1256 )
1257
1258 step("Clear BGP")
1259 for rtr in topo["routers"]:
1260 clear_bgp(tgen, "ipv4", rtr)
1261 clear_bgp(tgen, "ipv6", rtr)
1262
1263 bgp_convergence = verify_bgp_convergence(tgen, topo)
1264 assert bgp_convergence is True, "Testcase {} : Failed \n Error: {}".format(
1265 tc_name, bgp_convergence
1266 )
1267
1268 step("Verify that zebra selects bgp route.")
1269 protocol = "bgp"
1270
1271 for addr_type in ADDR_TYPES:
1272 result4 = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
1273 assert result4 is True, "Testcase {} : Failed \n Error: {}".format(
1274 tc_name, result4
1275 )
1276
1277 write_test_footer(tc_name)
1278
1279
1280 if __name__ == "__main__":
1281 args = ["-s"] + sys.argv[1:]
1282 sys.exit(pytest.main(args))