]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/bgp_distance_change/test_bgp_admin_dist_vrf.py
Merge pull request #12816 from gpnaveen/stc_rte_err_msg
[mirror_frr.git] / tests / topotests / bgp_distance_change / test_bgp_admin_dist_vrf.py
1 #!/usr/bin/env python
2 # SPDX-License-Identifier: ISC
3
4 #
5 # Copyright (c) 2022 by VMware, Inc. ("VMware")
6 # Used Copyright (c) 2018 by Network Device Education Foundation,
7 # Inc. ("NetDEF") in this file.
8 #
9
10 import sys
11 import time
12 import pytest
13 import inspect
14 import os
15
16 """Following tests are covered to test bgp admin distance functionality.
17 TC_5:
18 Verify bgp admin distance functionality when static route is configured
19 same as bgp learnt route in user vrf.
20
21 TC_6: Verify bgp admin distance functionality with ECMP in user vrf.
22
23 TC_7:
24 Verify bgp admin distance functionality when routes are
25 imported between VRFs.
26 """
27
28 #################################
29 # TOPOLOGY
30 #################################
31 """
32
33 +-------+
34 +--------- | R2 |
35 | +-------+
36 |iBGP |
37 +-------+ |
38 | R1 | |iBGP
39 +-------+ |
40 | |
41 | iBGP +-------+ eBGP +-------+
42 +---------- | R3 |----------| R4 |
43 +-------+ +-------+
44 |
45 |eBGP
46 |
47 +-------+
48 | R5 |
49 +-------+
50
51
52 """
53
54 # Save the Current Working Directory to find configuration files.
55 CWD = os.path.dirname(os.path.realpath(__file__))
56 sys.path.append(os.path.join(CWD, "../"))
57 sys.path.append(os.path.join(CWD, "../lib/"))
58
59 # pylint: disable=C0413
60 # Import topogen and topotest helpers
61 from lib.topogen import Topogen, get_topogen
62
63 # Required to instantiate the topology builder class.
64 from lib.common_config import (
65 start_topology,
66 write_test_header,
67 step,
68 write_test_footer,
69 create_static_routes,
70 verify_rib,
71 check_address_types,
72 reset_config_on_routers,
73 check_router_status,
74 )
75 from lib.topolog import logger
76 from lib.bgp import (
77 verify_bgp_convergence,
78 create_router_bgp,
79 verify_best_path_as_per_admin_distance,
80 )
81
82 # pylint: disable=C0413
83 # Import topogen and topotest helpers
84 from lib.topogen import Topogen, get_topogen
85 from lib.topojson import build_config_from_json
86 from lib.topolog import logger
87
88 # Global variables
89 topo = None
90 bgp_convergence = False
91 pytestmark = [pytest.mark.bgpd, pytest.mark.staticd]
92
93 NETWORK = {
94 "ipv4": [
95 "192.168.20.1/32",
96 "192.168.20.2/32",
97 "192.168.21.1/32",
98 "192.168.21.2/32",
99 "192.168.22.1/32",
100 "192.168.22.2/32",
101 ],
102 "ipv6": [
103 "fc07:50::1/128",
104 "fc07:50::2/128",
105 "fc07:150::1/128",
106 "fc07:150::2/128",
107 "fc07:1::1/128",
108 "fc07:1::2/128",
109 ],
110 }
111 ADDR_TYPES = check_address_types()
112
113
114 def setup_module(mod):
115 """
116 Sets up the pytest environment
117
118 * `mod`: module name
119 """
120
121 global topo
122
123 testsuite_run_time = time.asctime(time.localtime(time.time()))
124 logger.info("Testsuite start time: {}".format(testsuite_run_time))
125 logger.info("=" * 40)
126
127 logger.info("Running setup_module to create topology")
128
129 # This function initiates the topology build with Topogen...
130 json_file = "{}/bgp_admin_dist_vrf.json".format(CWD)
131 tgen = Topogen(json_file, mod.__name__)
132 global topo
133 topo = tgen.json_topo
134
135 # Starting topology, create tmp files which are loaded to routers
136 # to start deamons and then start routers
137 start_topology(tgen)
138
139 # Creating configuration from JSON
140 build_config_from_json(tgen, topo)
141
142 # Checking BGP convergence
143 global bgp_convergence
144 global ADDR_TYPES
145
146 # Don't run this test if we have any failure.
147 if tgen.routers_have_failure():
148 pytest.skip(tgen.errors)
149
150 # Api call verify whether BGP is converged
151 bgp_convergence = verify_bgp_convergence(tgen, topo)
152 assert bgp_convergence is True, "setup_module :Failed \n Error:" " {}".format(
153 bgp_convergence
154 )
155 logger.info("Running setup_module() done")
156
157
158 def teardown_module(mod):
159 """teardown_module.
160
161 Teardown the pytest environment.
162 * `mod`: module name
163 """
164 logger.info("Running teardown_module to delete topology")
165 tgen = get_topogen()
166
167 # Stop toplogy and Remove tmp files
168 tgen.stop_topology()
169
170 logger.info(
171 "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
172 )
173 logger.info("=" * 40)
174
175
176 #####################################################
177 # Tests starting
178 #####################################################
179
180
181 def test_bgp_admin_distance_ebgp_vrf_p0():
182 """
183 TC: 5
184 Verify bgp admin distance functionality when static route is
185 configured same as ebgp learnt route
186 """
187 tgen = get_topogen()
188 global bgp_convergence
189
190 if bgp_convergence is not True:
191 pytest.skip("skipping test case because of BGP Convergence failure at setup")
192
193 # test case name
194 tc_name = inspect.stack()[0][3]
195 write_test_header(tc_name)
196 if tgen.routers_have_failure():
197 check_router_status(tgen)
198
199 step("Configure base config as per the topology")
200 reset_config_on_routers(tgen)
201
202 step("Configure bgp admin distance 200 with CLI in dut.")
203
204 input_dict_1 = {
205 "r3": {
206 "bgp": [
207 {
208 "vrf": "RED",
209 "local_as": 100,
210 "address_family": {
211 "ipv4": {
212 "unicast": {
213 "distance": {"ebgp": 200, "ibgp": 200, "local": 200}
214 }
215 },
216 "ipv6": {
217 "unicast": {
218 "distance": {"ebgp": 200, "ibgp": 200, "local": 200}
219 }
220 },
221 },
222 }
223 ]
224 }
225 }
226
227 result = create_router_bgp(tgen, topo, input_dict_1)
228 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
229
230 step("Verify bgp routes have admin distance of 200 in dut.")
231 # Verifying best path
232 dut = "r3"
233 attribute = "admin_distance"
234
235 input_dict = {
236 "ipv4": {
237 "r3": {
238 "static_routes": [
239 {
240 "network": NETWORK["ipv4"][0],
241 "admin_distance": 200,
242 "vrf": "RED",
243 },
244 {
245 "network": NETWORK["ipv4"][1],
246 "admin_distance": 200,
247 "vrf": "RED",
248 },
249 ]
250 }
251 },
252 "ipv6": {
253 "r3": {
254 "static_routes": [
255 {
256 "network": NETWORK["ipv6"][0],
257 "admin_distance": 200,
258 "vrf": "RED",
259 },
260 {
261 "network": NETWORK["ipv6"][1],
262 "admin_distance": 200,
263 "vrf": "RED",
264 },
265 ]
266 }
267 },
268 }
269
270 for addr_type in ADDR_TYPES:
271 result = verify_best_path_as_per_admin_distance(
272 tgen, addr_type, dut, input_dict[addr_type], attribute, vrf="RED"
273 )
274 assert result is True, "Testcase {} : Failed \n Error: {}".format(
275 tc_name, result
276 )
277
278 step("Modify the admin distance value to 150.")
279
280 input_dict_1 = {
281 "r3": {
282 "bgp": [
283 {
284 "local_as": 100,
285 "address_family": {
286 "ipv4": {
287 "unicast": {
288 "distance": {"ebgp": 150, "ibgp": 150, "local": 150}
289 }
290 },
291 "ipv6": {
292 "unicast": {
293 "distance": {"ebgp": 150, "ibgp": 150, "local": 150}
294 }
295 },
296 },
297 }
298 ]
299 }
300 }
301
302 result = create_router_bgp(tgen, topo, input_dict_1)
303 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
304
305 step("Verify bgp routes have admin distance of 150 in dut.")
306 # Verifying best path
307 dut = "r3"
308 attribute = "admin_distance"
309
310 input_dict = {
311 "ipv4": {
312 "r3": {
313 "static_routes": [
314 {
315 "network": NETWORK["ipv4"][0],
316 "admin_distance": 150,
317 "vrf": "RED",
318 },
319 {
320 "network": NETWORK["ipv4"][1],
321 "admin_distance": 150,
322 "vrf": "RED",
323 },
324 ]
325 }
326 },
327 "ipv6": {
328 "r3": {
329 "static_routes": [
330 {
331 "network": NETWORK["ipv6"][0],
332 "admin_distance": 150,
333 "vrf": "RED",
334 },
335 {
336 "network": NETWORK["ipv6"][1],
337 "admin_distance": 150,
338 "vrf": "RED",
339 },
340 ]
341 }
342 },
343 }
344
345 for addr_type in ADDR_TYPES:
346 result = verify_best_path_as_per_admin_distance(
347 tgen, addr_type, dut, input_dict[addr_type], attribute, vrf="RED"
348 )
349 assert result is True, "Testcase {} : Failed \n Error: {}".format(
350 tc_name, result
351 )
352
353 step("Un configure the admin distance value on DUT")
354
355 input_dict_1 = {
356 "r3": {
357 "bgp": [
358 {
359 "local_as": 100,
360 "address_family": {
361 "ipv4": {
362 "unicast": {
363 "distance": {
364 "ebgp": 150,
365 "ibgp": 150,
366 "local": 150,
367 "delete": True,
368 }
369 }
370 },
371 "ipv6": {
372 "unicast": {
373 "distance": {
374 "ebgp": 150,
375 "ibgp": 150,
376 "local": 150,
377 "delete": True,
378 }
379 }
380 },
381 },
382 }
383 ]
384 }
385 }
386
387 result = create_router_bgp(tgen, topo, input_dict_1)
388 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
389
390 step("Verify bgp routes have default admin distance in dut.")
391 # Verifying best path
392 dut = "r3"
393 attribute = "admin_distance"
394
395 input_dict = {
396 "ipv4": {
397 "r3": {
398 "static_routes": [
399 {"network": NETWORK["ipv4"][0], "admin_distance": 20, "vrf": "RED"},
400 {"network": NETWORK["ipv4"][1], "admin_distance": 20, "vrf": "RED"},
401 ]
402 }
403 },
404 "ipv6": {
405 "r3": {
406 "static_routes": [
407 {"network": NETWORK["ipv6"][0], "admin_distance": 20, "vrf": "RED"},
408 {"network": NETWORK["ipv6"][1], "admin_distance": 20, "vrf": "RED"},
409 ]
410 }
411 },
412 }
413
414 for addr_type in ADDR_TYPES:
415 result = verify_best_path_as_per_admin_distance(
416 tgen, addr_type, dut, input_dict[addr_type], attribute, vrf="RED"
417 )
418 assert result is True, "Testcase {} : Failed \n Error: {}".format(
419 tc_name, result
420 )
421
422 step("Configure static route Without any admin distance")
423
424 for addr_type in ADDR_TYPES:
425 # Create Static routes
426 input_dict = {
427 "r3": {
428 "static_routes": [
429 {"network": NETWORK[addr_type], "next_hop": "Null0", "vrf": "RED"}
430 ]
431 }
432 }
433
434 result = create_static_routes(tgen, input_dict)
435 assert result is True, "Testcase {} : Failed \n Error: {}".format(
436 tc_name, result
437 )
438
439 step("Verify that zebra selects static route.")
440 protocol = "static"
441 # dual stack changes
442 for addr_type in ADDR_TYPES:
443 input_dict = {
444 "r3": {
445 "static_routes": [
446 {"network": NETWORK[addr_type], "next_hop": "Null0", "vrf": "RED"}
447 ]
448 }
449 }
450 result4 = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
451 assert result4 is True, "Testcase {} : Failed \n Error: {}".format(
452 tc_name, result4
453 )
454
455 step("Configure static route with admin distance of 253")
456 for addr_type in ADDR_TYPES:
457 # Create Static routes
458 input_dict = {
459 "r3": {
460 "static_routes": [
461 {
462 "network": NETWORK[addr_type],
463 "next_hop": "Null0",
464 "admin_distance": 253,
465 "vrf": "RED",
466 }
467 ]
468 }
469 }
470
471 result = create_static_routes(tgen, input_dict)
472 assert result is True, "Testcase {} : Failed \n Error: {}".format(
473 tc_name, result
474 )
475
476 step("Verify that zebra selects bgp route.")
477 protocol = "bgp"
478
479 for addr_type in ADDR_TYPES:
480 input_dict = {
481 "r3": {
482 "static_routes": [
483 {
484 "network": NETWORK[addr_type],
485 "next_hop": "Null0",
486 "admin_distance": 253,
487 "vrf": "RED",
488 }
489 ]
490 }
491 }
492 result4 = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
493 assert result4 is True, "Testcase {} : Failed \n Error: {}".format(
494 tc_name, result4
495 )
496
497 step("Configure admin distance of 254 in bgp for route .")
498
499 input_dict_1 = {
500 "r3": {
501 "bgp": [
502 {
503 "local_as": 100,
504 "address_family": {
505 "ipv4": {
506 "unicast": {
507 "distance": {"ebgp": 254, "ibgp": 254, "local": 254}
508 }
509 },
510 "ipv6": {
511 "unicast": {
512 "distance": {"ebgp": 254, "ibgp": 254, "local": 254}
513 }
514 },
515 },
516 }
517 ]
518 }
519 }
520
521 result = create_router_bgp(tgen, topo, input_dict_1)
522 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
523
524 step("Verify that zebra selects static route.")
525 protocol = "static"
526 # dual stack changes
527 for addr_type in ADDR_TYPES:
528 input_dict = {
529 "r3": {
530 "static_routes": [
531 {
532 "network": NETWORK[addr_type],
533 "next_hop": "Null0",
534 "admin_distance": 253,
535 "vrf": "RED",
536 }
537 ]
538 }
539 }
540
541 result4 = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
542 assert result4 is True, "Testcase {} : Failed \n Error: {}".format(
543 tc_name, result4
544 )
545
546 step("Configure admin distance of 255 in bgp for route in vrf red")
547
548 input_dict_1 = {
549 "r3": {
550 "bgp": [
551 {
552 "local_as": 100,
553 "address_family": {
554 "ipv4": {
555 "unicast": {
556 "distance": {"ebgp": 255, "ibgp": 255, "local": 255}
557 }
558 },
559 "ipv6": {
560 "unicast": {
561 "distance": {"ebgp": 255, "ibgp": 255, "local": 255}
562 }
563 },
564 },
565 }
566 ]
567 }
568 }
569
570 result = create_router_bgp(tgen, topo, input_dict_1)
571 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
572
573 step("Verify that zebra selects static route.")
574 protocol = "static"
575 # dual stack changes
576 for addr_type in ADDR_TYPES:
577 input_dict = {
578 "r3": {
579 "static_routes": [
580 {
581 "network": NETWORK[addr_type],
582 "next_hop": "Null0",
583 "admin_distance": 253,
584 "vrf": "RED",
585 }
586 ]
587 }
588 }
589
590 result4 = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
591 assert result4 is True, "Testcase {} : Failed \n Error: {}".format(
592 tc_name, result4
593 )
594
595 step("Delete the static route.")
596 for addr_type in ADDR_TYPES:
597 # Create Static routes
598 input_dict = {
599 "r3": {
600 "static_routes": [
601 {
602 "network": NETWORK[addr_type],
603 "next_hop": "Null0",
604 "admin_distance": 253,
605 "delete": True,
606 "vrf": "RED",
607 }
608 ]
609 }
610 }
611
612 result = create_static_routes(tgen, input_dict)
613 assert result is True, "Testcase {} : Failed \n Error: {}".format(
614 tc_name, result
615 )
616
617 step("Verify that zebra selects bgp route.")
618 protocol = "bgp"
619 # dual stack changes
620 for addr_type in ADDR_TYPES:
621 result4 = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
622 assert result4 is True, "Testcase {} : Failed \n Error: {}".format(
623 tc_name, result4
624 )
625
626 write_test_footer(tc_name)
627
628
629 def test_bgp_admin_distance_ebgp_with_imported_rtes_vrf_p0():
630 """
631 TC: 5
632 Verify bgp admin distance functionality when static route is configured
633 same as bgp learnt route in user vrf.
634 """
635 tgen = get_topogen()
636 global bgp_convergence
637
638 if bgp_convergence is not True:
639 pytest.skip("skipping test case because of BGP Convergence failure at setup")
640
641 # test case name
642 tc_name = inspect.stack()[0][3]
643 write_test_header(tc_name)
644 if tgen.routers_have_failure():
645 check_router_status(tgen)
646
647 step("Configure base config as per the topology")
648 reset_config_on_routers(tgen)
649 step("Configure bgp admin distance 200 with CLI in dut.")
650 step(" Import route from vrf to default vrf")
651 input_dict_1 = {
652 "r3": {
653 "bgp": [
654 {
655 "vrf": "RED",
656 "local_as": 100,
657 "address_family": {
658 "ipv4": {
659 "unicast": {
660 "distance": {"ebgp": 200, "ibgp": 200, "local": 200}
661 }
662 },
663 "ipv6": {
664 "unicast": {
665 "distance": {"ebgp": 200, "ibgp": 200, "local": 200}
666 }
667 },
668 },
669 },
670 {
671 "local_as": 100,
672 "address_family": {
673 "ipv4": {
674 "unicast": {
675 "distance": {"ebgp": 200, "ibgp": 200, "local": 200},
676 "import": {"vrf": "RED"},
677 }
678 },
679 "ipv6": {
680 "unicast": {
681 "distance": {"ebgp": 200, "ibgp": 200, "local": 200},
682 "import": {
683 "vrf": "RED",
684 },
685 }
686 },
687 },
688 },
689 ]
690 }
691 }
692
693 result = create_router_bgp(tgen, topo, input_dict_1)
694 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
695
696 step("Verify bgp routes have admin distance of 200 in dut.")
697 # Verifying best path
698 dut = "r3"
699 attribute = "admin_distance"
700
701 input_dict = {
702 "ipv4": {
703 "r3": {
704 "static_routes": [
705 {
706 "network": NETWORK["ipv4"][0],
707 "admin_distance": 200,
708 "vrf": "RED",
709 },
710 {
711 "network": NETWORK["ipv4"][1],
712 "admin_distance": 200,
713 "vrf": "RED",
714 },
715 ]
716 }
717 },
718 "ipv6": {
719 "r3": {
720 "static_routes": [
721 {
722 "network": NETWORK["ipv6"][0],
723 "admin_distance": 200,
724 "vrf": "RED",
725 },
726 {
727 "network": NETWORK["ipv6"][1],
728 "admin_distance": 200,
729 "vrf": "RED",
730 },
731 ]
732 }
733 },
734 }
735
736 for addr_type in ADDR_TYPES:
737 result = verify_best_path_as_per_admin_distance(
738 tgen, addr_type, dut, input_dict[addr_type], attribute, vrf="RED"
739 )
740 assert result is True, "Testcase {} : Failed \n Error: {}".format(
741 tc_name, result
742 )
743
744 step(
745 "Verify that routes are getting imported without any issues and "
746 "routes are calculated and installed in rib."
747 )
748
749 input_dict = {
750 "ipv4": {
751 "r3": {
752 "static_routes": [
753 {
754 "network": NETWORK["ipv4"][0],
755 "admin_distance": 200,
756 },
757 {
758 "network": NETWORK["ipv4"][1],
759 "admin_distance": 200,
760 },
761 ]
762 }
763 },
764 "ipv6": {
765 "r3": {
766 "static_routes": [
767 {
768 "network": NETWORK["ipv6"][0],
769 "admin_distance": 200,
770 },
771 {
772 "network": NETWORK["ipv6"][1],
773 "admin_distance": 200,
774 },
775 ]
776 }
777 },
778 }
779
780 step("Verify that zebra selects bgp route.")
781 protocol = "bgp"
782 # dual stack changes
783 for addr_type in ADDR_TYPES:
784 result4 = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
785 assert result4 is True, "Testcase {} : Failed \n Error: {}".format(
786 tc_name, result4
787 )
788
789 step(" Un configure import route vrf red inside default vrf.")
790 input_dict_1 = {
791 "r3": {
792 "bgp": [
793 {
794 "vrf": "RED",
795 "local_as": 100,
796 "address_family": {
797 "ipv4": {
798 "unicast": {
799 "distance": {"ebgp": 200, "ibgp": 200, "local": 200}
800 }
801 },
802 "ipv6": {
803 "unicast": {
804 "distance": {"ebgp": 200, "ibgp": 200, "local": 200}
805 }
806 },
807 },
808 },
809 {
810 "local_as": 100,
811 "address_family": {
812 "ipv4": {
813 "unicast": {
814 "distance": {"ebgp": 200, "ibgp": 200, "local": 200},
815 "import": {"vrf": "RED", "delete": True},
816 }
817 },
818 "ipv6": {
819 "unicast": {
820 "distance": {"ebgp": 200, "ibgp": 200, "local": 200},
821 "import": {"vrf": "RED", "delete": True},
822 }
823 },
824 },
825 },
826 ]
827 }
828 }
829
830 result = create_router_bgp(tgen, topo, input_dict_1)
831 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
832
833 input_dict = {
834 "ipv4": {
835 "r3": {
836 "static_routes": [
837 {
838 "network": NETWORK["ipv4"][0],
839 "admin_distance": 200,
840 },
841 {
842 "network": NETWORK["ipv4"][1],
843 "admin_distance": 200,
844 },
845 ]
846 }
847 },
848 "ipv6": {
849 "r3": {
850 "static_routes": [
851 {
852 "network": NETWORK["ipv6"][0],
853 "admin_distance": 200,
854 },
855 {
856 "network": NETWORK["ipv6"][1],
857 "admin_distance": 200,
858 },
859 ]
860 }
861 },
862 }
863
864 step("Verify that route withdrawal happens properly.")
865 protocol = "bgp"
866 # dual stack changes
867 for addr_type in ADDR_TYPES:
868 result4 = verify_rib(
869 tgen,
870 addr_type,
871 dut,
872 input_dict[addr_type],
873 protocol=protocol,
874 expected=False,
875 )
876 assert (
877 result4 is not True
878 ), "Testcase {} : Failed \n Route is not withdrawn. Error: {}".format(
879 tc_name, result4
880 )
881
882 write_test_footer(tc_name)
883
884
885 if __name__ == "__main__":
886 args = ["-s"] + sys.argv[1:]
887 sys.exit(pytest.main(args))