]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/bgp_path_attributes_topo1/test_bgp_path_attributes.py
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / tests / topotests / bgp_path_attributes_topo1 / test_bgp_path_attributes.py
1 #!/usr/bin/env python
2 # SPDX-License-Identifier: ISC
3
4 #
5 # Modified work Copyright (c) 2019 by VMware, Inc. ("VMware")
6 # Original work Copyright (c) 2018 by Network Device Education
7 # Foundation, Inc. ("NetDEF")
8 #
9
10 """
11 Following tests are covered to test AS-Path functionality:
12
13 Setup module:
14 - Create topology (setup module)
15 - Bring up topology
16 - Verify BGP convergence
17
18 Test cases:
19 1. Test next_hop attribute and verify best path is installed as per
20 reachable next_hop
21 2. Test aspath attribute and verify best path is installed as per
22 shortest AS-Path
23 3. Test localpref attribute and verify best path is installed as per
24 shortest local-preference
25 4. Test weight attribute and and verify best path is installed as per
26 highest weight
27 5. Test origin attribute and verify best path is installed as per
28 IGP>EGP>INCOMPLETE rule
29 6. Test med attribute and verify best path is installed as per lowest
30 med value
31 7. Test admin distance and verify best path is installed as per lowest
32 admin distance
33
34 Teardown module:
35 - Bring down the topology
36 - stop routers
37
38 """
39
40 import os
41 import sys
42 import time
43 import pytest
44
45 # Save the Current Working Directory to find configuration files.
46 CWD = os.path.dirname(os.path.realpath(__file__))
47 sys.path.append(os.path.join(CWD, "../"))
48
49 # pylint: disable=C0413
50 # Import topogen and topotest helpers
51 from lib.topogen import Topogen, get_topogen
52
53 # Required to instantiate the topology builder class.
54 from lib.common_config import (
55 start_topology,
56 write_test_header,
57 write_test_footer,
58 reset_config_on_routers,
59 verify_rib,
60 create_static_routes,
61 create_prefix_lists,
62 create_route_maps,
63 check_address_types,
64 )
65 from lib.topolog import logger
66 from lib.bgp import (
67 verify_bgp_convergence,
68 create_router_bgp,
69 verify_best_path_as_per_bgp_attribute,
70 verify_best_path_as_per_admin_distance,
71 )
72 from lib.topojson import build_config_from_json
73
74
75 pytestmark = [pytest.mark.bgpd, pytest.mark.staticd]
76
77
78 # Address read from env variables
79 ADDR_TYPES = check_address_types()
80
81 ####
82 def setup_module(mod):
83 """
84 Sets up the pytest environment
85
86 * `mod`: module name
87 """
88
89 global ADDR_TYPES
90
91 testsuite_run_time = time.asctime(time.localtime(time.time()))
92 logger.info("Testsuite start time: %s", testsuite_run_time)
93 logger.info("=" * 40)
94
95 logger.info("Running setup_module to create topology")
96
97 # This function initiates the topology build with Topogen...
98 json_file = "{}/bgp_path_attributes.json".format(CWD)
99 tgen = Topogen(json_file, mod.__name__)
100 global topo
101 topo = tgen.json_topo
102 # ... and here it calls Mininet initialization functions.
103
104 # Starting topology, create tmp files which are loaded to routers
105 # to start daemons and then start routers
106 start_topology(tgen)
107
108 # Creating configuration from JSON
109 build_config_from_json(tgen, topo)
110
111 # Don't run this test if we have any failure.
112 if tgen.routers_have_failure():
113 pytest.skip(tgen.errors)
114
115 # Checking BGP convergence
116 result = verify_bgp_convergence(tgen, topo)
117 assert result is True, "setup_module :Failed \n Error:" " {}".format(result)
118
119 logger.info("Running setup_module() done")
120
121
122 def teardown_module():
123 """
124 Teardown the pytest environment
125 """
126
127 logger.info("Running teardown_module to delete topology")
128
129 tgen = get_topogen()
130
131 # Stop toplogy and Remove tmp files
132 tgen.stop_topology()
133
134 logger.info("Testsuite end time: %s", time.asctime(time.localtime(time.time())))
135 logger.info("=" * 40)
136
137
138 #####################################################
139 ##
140 ## Testcases
141 ##
142 #####################################################
143
144
145 def test_next_hop_attribute(request):
146 """
147 Verifying route are not getting installed in, as next_hop is
148 unreachable, Making next hop reachable using next_hop_self
149 command and verifying routes are installed.
150 """
151
152 tgen = get_topogen()
153
154 # Don't run this test if we have any failure.
155 if tgen.routers_have_failure():
156 pytest.skip(tgen.errors)
157
158 # test case name
159 tc_name = request.node.name
160 write_test_header(tc_name)
161
162 # Creating configuration from JSON
163 reset_config_on_routers(tgen)
164
165 # Api call to advertise networks
166 input_dict = {
167 "r7": {
168 "bgp": {
169 "address_family": {
170 "ipv4": {
171 "unicast": {
172 "advertise_networks": [
173 {"network": "200.50.2.0/32"},
174 {"network": "200.60.2.0/32"},
175 ]
176 }
177 },
178 "ipv6": {
179 "unicast": {
180 "advertise_networks": [
181 {"network": "200:50:2::/128"},
182 {"network": "200:60:2::/128"},
183 ]
184 }
185 },
186 }
187 }
188 }
189 }
190 result = create_router_bgp(tgen, topo, input_dict)
191 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
192
193 # Verifying RIB routes
194 dut = "r1"
195 protocol = "bgp"
196 # Verification should fail as nexthop-self is not enabled
197 for addr_type in ADDR_TYPES:
198 result = verify_rib(
199 tgen, addr_type, dut, input_dict, protocol=protocol, expected=False
200 )
201 assert (
202 result is not True
203 ), "Testcase {} : Failed \n Error: " "{} routes are not present in RIB".format(
204 addr_type, tc_name
205 )
206
207 # Configure next-hop-self to bgp neighbor
208 input_dict_1 = {
209 "r2": {
210 "bgp": {
211 "address_family": {
212 "ipv4": {
213 "unicast": {
214 "neighbor": {
215 "r1": {"dest_link": {"r2": {"next_hop_self": True}}}
216 }
217 }
218 },
219 "ipv6": {
220 "unicast": {
221 "neighbor": {
222 "r1": {"dest_link": {"r2": {"next_hop_self": True}}}
223 }
224 }
225 },
226 }
227 }
228 },
229 "r3": {
230 "bgp": {
231 "address_family": {
232 "ipv4": {
233 "unicast": {
234 "neighbor": {
235 "r1": {"dest_link": {"r3": {"next_hop_self": True}}}
236 }
237 }
238 },
239 "ipv6": {
240 "unicast": {
241 "neighbor": {
242 "r1": {"dest_link": {"r3": {"next_hop_self": True}}}
243 }
244 }
245 },
246 }
247 }
248 },
249 }
250
251 result = create_router_bgp(tgen, topo, input_dict_1)
252 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
253
254 # Verifying RIB routes
255 dut = "r1"
256 protocol = "bgp"
257 for addr_type in ADDR_TYPES:
258 result = verify_rib(tgen, addr_type, dut, input_dict, protocol=protocol)
259 assert result is True, "Testcase {} : Failed \n Error: {}".format(
260 tc_name, result
261 )
262
263 write_test_footer(tc_name)
264
265
266 def test_aspath_attribute(request):
267 "Verifying AS_PATH attribute functionality"
268
269 tgen = get_topogen()
270
271 # Don't run this test if we have any failure.
272 if tgen.routers_have_failure():
273 pytest.skip(tgen.errors)
274
275 # test case name
276 tc_name = request.node.name
277 write_test_header(tc_name)
278
279 # Creating configuration from JSON
280 reset_config_on_routers(tgen)
281
282 # Api call to advertise networks
283 input_dict = {
284 "r7": {
285 "bgp": {
286 "address_family": {
287 "ipv4": {
288 "unicast": {
289 "advertise_networks": [
290 {"network": "200.50.2.0/32"},
291 {"network": "200.60.2.0/32"},
292 ]
293 }
294 },
295 "ipv6": {
296 "unicast": {
297 "advertise_networks": [
298 {"network": "200:50:2::/128"},
299 {"network": "200:60:2::/128"},
300 ]
301 }
302 },
303 }
304 }
305 },
306 "r2": {
307 "bgp": {
308 "address_family": {
309 "ipv4": {
310 "unicast": {
311 "neighbor": {
312 "r1": {"dest_link": {"r2": {"next_hop_self": True}}}
313 }
314 }
315 },
316 "ipv6": {
317 "unicast": {
318 "neighbor": {
319 "r1": {"dest_link": {"r2": {"next_hop_self": True}}}
320 }
321 }
322 },
323 }
324 }
325 },
326 "r3": {
327 "bgp": {
328 "address_family": {
329 "ipv4": {
330 "unicast": {
331 "neighbor": {
332 "r1": {"dest_link": {"r3": {"next_hop_self": True}}}
333 }
334 }
335 },
336 "ipv6": {
337 "unicast": {
338 "neighbor": {
339 "r1": {"dest_link": {"r3": {"next_hop_self": True}}}
340 }
341 }
342 },
343 }
344 }
345 },
346 }
347 result = create_router_bgp(tgen, topo, input_dict)
348 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
349
350 # Verifying best path
351 dut = "r1"
352 attribute = "path"
353 for addr_type in ADDR_TYPES:
354 result = verify_best_path_as_per_bgp_attribute(
355 tgen, addr_type, dut, {"r7": input_dict["r7"]}, attribute
356 )
357 assert result is True, "Testcase {} : Failed \n Error: {}".format(
358 tc_name, result
359 )
360
361 # Modify AS-Path and verify best path is changed
362 # Create Prefix list
363
364 input_dict_2 = {
365 "r3": {
366 "prefix_lists": {
367 "ipv4": {
368 "pf_ls_1_ipv4": [
369 {
370 "seqid": 10,
371 "network": "200.0.0.0/8",
372 "le": "32",
373 "action": "permit",
374 }
375 ]
376 },
377 "ipv6": {
378 "pf_ls_1_ipv6": [
379 {
380 "seqid": 10,
381 "network": "200::/8",
382 "le": "128",
383 "action": "permit",
384 }
385 ]
386 },
387 }
388 }
389 }
390 result = create_prefix_lists(tgen, input_dict_2)
391 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
392
393 # Create route map
394 input_dict_3 = {
395 "r3": {
396 "route_maps": {
397 "RMAP_AS_PATH": [
398 {
399 "action": "permit",
400 "match": {"ipv4": {"prefix_lists": "pf_ls_1_ipv4"}},
401 "set": {"path": {"as_num": "111 222", "as_action": "prepend"}},
402 },
403 {
404 "action": "permit",
405 "match": {"ipv6": {"prefix_lists": "pf_ls_1_ipv6"}},
406 "set": {"path": {"as_num": "111 222", "as_action": "prepend"}},
407 },
408 ]
409 }
410 }
411 }
412 result = create_route_maps(tgen, input_dict_3)
413 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
414
415 # Configure neighbor for route map
416 input_dict_4 = {
417 "r3": {
418 "bgp": {
419 "address_family": {
420 "ipv4": {
421 "unicast": {
422 "neighbor": {
423 "r5": {
424 "dest_link": {
425 "r3": {
426 "route_maps": [
427 {
428 "name": "RMAP_AS_PATH",
429 "direction": "in",
430 }
431 ]
432 }
433 }
434 }
435 }
436 }
437 },
438 "ipv6": {
439 "unicast": {
440 "neighbor": {
441 "r5": {
442 "dest_link": {
443 "r3": {
444 "route_maps": [
445 {
446 "name": "RMAP_AS_PATH",
447 "direction": "in",
448 }
449 ]
450 }
451 }
452 }
453 }
454 }
455 },
456 }
457 }
458 }
459 }
460 result = create_router_bgp(tgen, topo, input_dict_4)
461 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
462
463 # Verifying best path
464 dut = "r1"
465 attribute = "path"
466 for addr_type in ADDR_TYPES:
467 result = verify_best_path_as_per_bgp_attribute(
468 tgen, addr_type, dut, {"r7": input_dict["r7"]}, attribute
469 )
470 assert result is True, "Testcase {} : Failed \n Error: {}".format(
471 tc_name, result
472 )
473
474 write_test_footer(tc_name)
475
476
477 def test_localpref_attribute(request):
478 "Verifying LOCAL PREFERENCE attribute functionality"
479
480 tgen = get_topogen()
481
482 # Don't run this test if we have any failure.
483 if tgen.routers_have_failure():
484 pytest.skip(tgen.errors)
485
486 # test case name
487 tc_name = request.node.name
488 write_test_header(tc_name)
489
490 # Creating configuration from JSON
491 reset_config_on_routers(tgen)
492
493 # Api call to advertise networks
494 input_dict = {
495 "r7": {
496 "bgp": {
497 "address_family": {
498 "ipv4": {
499 "unicast": {
500 "advertise_networks": [
501 {"network": "200.50.2.0/32"},
502 {"network": "200.60.2.0/32"},
503 ]
504 }
505 },
506 "ipv6": {
507 "unicast": {
508 "advertise_networks": [
509 {"network": "200:50:2::/128"},
510 {"network": "200:60:2::/128"},
511 ]
512 }
513 },
514 }
515 }
516 },
517 "r2": {
518 "bgp": {
519 "address_family": {
520 "ipv4": {
521 "unicast": {
522 "neighbor": {
523 "r1": {"dest_link": {"r2": {"next_hop_self": True}}}
524 }
525 }
526 },
527 "ipv6": {
528 "unicast": {
529 "neighbor": {
530 "r1": {"dest_link": {"r2": {"next_hop_self": True}}}
531 }
532 }
533 },
534 }
535 }
536 },
537 "r3": {
538 "bgp": {
539 "address_family": {
540 "ipv4": {
541 "unicast": {
542 "neighbor": {
543 "r1": {"dest_link": {"r3": {"next_hop_self": True}}}
544 }
545 }
546 },
547 "ipv6": {
548 "unicast": {
549 "neighbor": {
550 "r1": {"dest_link": {"r3": {"next_hop_self": True}}}
551 }
552 }
553 },
554 }
555 }
556 },
557 }
558
559 result = create_router_bgp(tgen, topo, input_dict)
560 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
561
562 # Create Prefix list
563 input_dict_2 = {
564 "r2": {
565 "prefix_lists": {
566 "ipv4": {
567 "pf_ls_1_ipv4": [
568 {
569 "seqid": 10,
570 "network": "200.0.0.0/8",
571 "le": "32",
572 "action": "permit",
573 }
574 ]
575 },
576 "ipv6": {
577 "pf_ls_1_ipv6": [
578 {
579 "seqid": 10,
580 "network": "200::/8",
581 "le": "128",
582 "action": "permit",
583 }
584 ]
585 },
586 }
587 }
588 }
589 result = create_prefix_lists(tgen, input_dict_2)
590 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
591
592 # Create route map
593 input_dict_3 = {
594 "r2": {
595 "route_maps": {
596 "RMAP_LOCAL_PREF": [
597 {
598 "action": "permit",
599 "seq_id": "10",
600 "match": {"ipv4": {"prefix_lists": "pf_ls_1_ipv4"}},
601 "set": {"locPrf": 1111},
602 },
603 {
604 "action": "permit",
605 "seq_id": "20",
606 "match": {"ipv6": {"prefix_lists": "pf_ls_1_ipv6"}},
607 "set": {"locPrf": 1111},
608 },
609 ]
610 }
611 }
612 }
613 result = create_route_maps(tgen, input_dict_3)
614 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
615
616 # Configure neighbor for route map
617 input_dict_4 = {
618 "r2": {
619 "bgp": {
620 "address_family": {
621 "ipv4": {
622 "unicast": {
623 "neighbor": {
624 "r4": {
625 "dest_link": {
626 "r2-link1": {
627 "route_maps": [
628 {
629 "name": "RMAP_LOCAL_PREF",
630 "direction": "in",
631 }
632 ]
633 }
634 }
635 }
636 }
637 }
638 },
639 "ipv6": {
640 "unicast": {
641 "neighbor": {
642 "r4": {
643 "dest_link": {
644 "r2-link1": {
645 "route_maps": [
646 {
647 "name": "RMAP_LOCAL_PREF",
648 "direction": "in",
649 }
650 ]
651 }
652 }
653 }
654 }
655 }
656 },
657 }
658 }
659 }
660 }
661 result = create_router_bgp(tgen, topo, input_dict_4)
662 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
663
664 # Verifying best path
665 dut = "r1"
666 attribute = "locPrf"
667 for addr_type in ADDR_TYPES:
668 result = verify_best_path_as_per_bgp_attribute(
669 tgen, addr_type, dut, {"r7": input_dict["r7"]}, attribute
670 )
671 assert result is True, "Testcase {} : Failed \n Error: {}".format(
672 tc_name, result
673 )
674
675 # Modify route map
676 input_dict_3 = {
677 "r2": {
678 "route_maps": {
679 "RMAP_LOCAL_PREF": [
680 {
681 "action": "permit",
682 "seq_id": "10",
683 "match": {"ipv4": {"prefix_lists": "pf_ls_1_ipv4"}},
684 "set": {"locPrf": 50},
685 },
686 {
687 "action": "permit",
688 "seq_id": "20",
689 "match": {"ipv6": {"prefix_lists": "pf_ls_1_ipv6"}},
690 "set": {"locPrf": 50},
691 },
692 ]
693 }
694 }
695 }
696 result = create_route_maps(tgen, input_dict_3)
697 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
698
699 # Verifying best path
700 dut = "r1"
701 attribute = "locPrf"
702 for addr_type in ADDR_TYPES:
703 result = verify_best_path_as_per_bgp_attribute(
704 tgen, addr_type, dut, {"r7": input_dict["r7"]}, attribute
705 )
706 assert result is True, "Testcase {} : Failed \n Error: {}".format(
707 tc_name, result
708 )
709
710 write_test_footer(tc_name)
711
712
713 def test_weight_attribute(request):
714 """
715 Test configure/modify weight attribute and
716 verify best path is installed as per highest weight
717 """
718
719 tgen = get_topogen()
720
721 # Don't run this test if we have any failure.
722 if tgen.routers_have_failure():
723 pytest.skip(tgen.errors)
724
725 # test case name
726 tc_name = request.node.name
727 write_test_header(tc_name)
728
729 # Creating configuration from JSON
730 reset_config_on_routers(tgen)
731
732 # Api call to advertise networks
733 input_dict = {
734 "r7": {
735 "bgp": {
736 "address_family": {
737 "ipv4": {
738 "unicast": {
739 "advertise_networks": [
740 {"network": "200.50.2.0/32"},
741 {"network": "200.60.2.0/32"},
742 ]
743 }
744 },
745 "ipv6": {
746 "unicast": {
747 "advertise_networks": [
748 {"network": "200:50:2::/128"},
749 {"network": "200:60:2::/128"},
750 ]
751 }
752 },
753 }
754 }
755 },
756 "r2": {
757 "bgp": {
758 "address_family": {
759 "ipv4": {
760 "unicast": {
761 "neighbor": {
762 "r1": {"dest_link": {"r2": {"next_hop_self": True}}}
763 }
764 }
765 },
766 "ipv6": {
767 "unicast": {
768 "neighbor": {
769 "r1": {"dest_link": {"r2": {"next_hop_self": True}}}
770 }
771 }
772 },
773 }
774 }
775 },
776 "r3": {
777 "bgp": {
778 "address_family": {
779 "ipv4": {
780 "unicast": {
781 "neighbor": {
782 "r1": {"dest_link": {"r3": {"next_hop_self": True}}}
783 }
784 }
785 },
786 "ipv6": {
787 "unicast": {
788 "neighbor": {
789 "r1": {"dest_link": {"r3": {"next_hop_self": True}}}
790 }
791 }
792 },
793 }
794 }
795 },
796 }
797 result = create_router_bgp(tgen, topo, input_dict)
798 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
799
800 # Create Prefix list
801 input_dict_2 = {
802 "r1": {
803 "prefix_lists": {
804 "ipv4": {
805 "pf_ls_1_ipv4": [
806 {
807 "seqid": 10,
808 "network": "200.0.0.0/8",
809 "le": "32",
810 "action": "permit",
811 }
812 ]
813 },
814 "ipv6": {
815 "pf_ls_1_ipv6": [
816 {
817 "seqid": 10,
818 "network": "200::/8",
819 "le": "128",
820 "action": "permit",
821 }
822 ]
823 },
824 }
825 }
826 }
827 result = create_prefix_lists(tgen, input_dict_2)
828 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
829
830 # Create route map
831 input_dict_3 = {
832 "r1": {
833 "route_maps": {
834 "RMAP_WEIGHT": [
835 {
836 "action": "permit",
837 "seq_id": "5",
838 "match": {"ipv4": {"prefix_lists": "pf_ls_1_ipv4"}},
839 "set": {"weight": 500},
840 },
841 {
842 "action": "permit",
843 "seq_id": "10",
844 "match": {"ipv6": {"prefix_lists": "pf_ls_1_ipv6"}},
845 "set": {"weight": 500},
846 },
847 ]
848 }
849 }
850 }
851 result = create_route_maps(tgen, input_dict_3)
852 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
853
854 # Configure neighbor for route map
855 input_dict_4 = {
856 "r1": {
857 "bgp": {
858 "address_family": {
859 "ipv4": {
860 "unicast": {
861 "neighbor": {
862 "r2": {
863 "dest_link": {
864 "r1": {
865 "route_maps": [
866 {
867 "name": "RMAP_WEIGHT",
868 "direction": "in",
869 }
870 ]
871 }
872 }
873 }
874 }
875 }
876 },
877 "ipv6": {
878 "unicast": {
879 "neighbor": {
880 "r2": {
881 "dest_link": {
882 "r1": {
883 "route_maps": [
884 {
885 "name": "RMAP_WEIGHT",
886 "direction": "in",
887 }
888 ]
889 }
890 }
891 }
892 }
893 }
894 },
895 }
896 }
897 }
898 }
899 result = create_router_bgp(tgen, topo, input_dict_4)
900 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
901
902 # Verifying best path
903 dut = "r1"
904 attribute = "weight"
905 for addr_type in ADDR_TYPES:
906 result = verify_best_path_as_per_bgp_attribute(
907 tgen, addr_type, dut, {"r7": input_dict["r7"]}, attribute
908 )
909 assert result is True, "Testcase {} : Failed \n Error: {}".format(
910 tc_name, result
911 )
912
913 # Modify route map
914 input_dict_3 = {
915 "r1": {
916 "route_maps": {
917 "RMAP_WEIGHT": [
918 {
919 "action": "permit",
920 "seq_id": "5",
921 "match": {"ipv4": {"prefix_lists": "pf_ls_1_ipv4"}},
922 "set": {"weight": 1000},
923 },
924 {
925 "action": "permit",
926 "seq_id": "10",
927 "match": {"ipv6": {"prefix_lists": "pf_ls_1_ipv6"}},
928 "set": {"weight": 1000},
929 },
930 ]
931 }
932 }
933 }
934 result = create_route_maps(tgen, input_dict_3)
935 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
936
937 # Verifying best path
938 dut = "r1"
939 attribute = "weight"
940 for addr_type in ADDR_TYPES:
941 result = verify_best_path_as_per_bgp_attribute(
942 tgen, addr_type, dut, {"r7": input_dict["r7"]}, attribute
943 )
944 assert result is True, "Testcase {} : Failed \n Error: {}".format(
945 tc_name, result
946 )
947
948 write_test_footer(tc_name)
949
950
951 def test_origin_attribute(request):
952 """
953 Test origin attribute and verify best path is
954 installed as per IGP>EGP>INCOMPLETE rule
955 """
956
957 tgen = get_topogen()
958
959 # Don't run this test if we have any failure.
960 if tgen.routers_have_failure():
961 pytest.skip(tgen.errors)
962
963 # test case name
964 tc_name = request.node.name
965 write_test_header(tc_name)
966
967 # Creating configuration from JSON
968 reset_config_on_routers(tgen)
969
970 # Api call to advertise networks
971 input_dict = {
972 "r4": {
973 "bgp": {
974 "address_family": {
975 "ipv4": {
976 "unicast": {
977 "advertise_networks": [
978 {"network": "200.50.2.0/32"},
979 {"network": "200.60.2.0/32"},
980 ]
981 }
982 },
983 "ipv6": {
984 "unicast": {
985 "advertise_networks": [
986 {"network": "200:50:2::/128"},
987 {"network": "200:60:2::/128"},
988 ]
989 }
990 },
991 }
992 }
993 },
994 "r2": {
995 "bgp": {
996 "address_family": {
997 "ipv4": {
998 "unicast": {
999 "neighbor": {
1000 "r1": {"dest_link": {"r2": {"next_hop_self": True}}}
1001 }
1002 }
1003 },
1004 "ipv6": {
1005 "unicast": {
1006 "neighbor": {
1007 "r1": {"dest_link": {"r2": {"next_hop_self": True}}}
1008 }
1009 }
1010 },
1011 }
1012 }
1013 },
1014 "r3": {
1015 "bgp": {
1016 "address_family": {
1017 "ipv4": {
1018 "unicast": {
1019 "neighbor": {
1020 "r1": {"dest_link": {"r3": {"next_hop_self": True}}}
1021 }
1022 }
1023 },
1024 "ipv6": {
1025 "unicast": {
1026 "neighbor": {
1027 "r1": {"dest_link": {"r3": {"next_hop_self": True}}}
1028 }
1029 }
1030 },
1031 }
1032 }
1033 },
1034 "r5": {
1035 "bgp": {
1036 "address_family": {
1037 "ipv4": {
1038 "unicast": {
1039 "redistribute": [
1040 {"redist_type": "static"},
1041 {"redist_type": "connected"},
1042 ]
1043 }
1044 },
1045 "ipv6": {
1046 "unicast": {
1047 "redistribute": [
1048 {"redist_type": "static"},
1049 {"redist_type": "connected"},
1050 ]
1051 }
1052 },
1053 }
1054 }
1055 },
1056 }
1057 result = create_router_bgp(tgen, topo, input_dict)
1058 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
1059
1060 # Api call to create static routes
1061 input_dict_3 = {
1062 "r5": {
1063 "static_routes": [
1064 {"network": "200.50.2.0/32", "next_hop": "Null0"},
1065 {"network": "200.60.2.0/32", "next_hop": "Null0"},
1066 {"network": "200:50:2::/128", "next_hop": "Null0"},
1067 {"network": "200:60:2::/128", "next_hop": "Null0"},
1068 ]
1069 }
1070 }
1071 result = create_static_routes(tgen, input_dict_3)
1072 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
1073
1074 # Verifying best path
1075 dut = "r1"
1076 attribute = "origin"
1077 for addr_type in ADDR_TYPES:
1078 result = verify_best_path_as_per_bgp_attribute(
1079 tgen, addr_type, dut, {"r4": input_dict["r4"]}, attribute
1080 )
1081 assert result is True, "Testcase {} : Failed \n Error: {}".format(
1082 tc_name, result
1083 )
1084
1085 write_test_footer(tc_name)
1086
1087
1088 def test_med_attribute(request):
1089 """
1090 Test configure/modify MED attribute and verify best path
1091 is installed as per lowest med value
1092 """
1093
1094 tgen = get_topogen()
1095
1096 # Don't run this test if we have any failure.
1097 if tgen.routers_have_failure():
1098 pytest.skip(tgen.errors)
1099
1100 # test case name
1101 tc_name = request.node.name
1102 write_test_header(tc_name)
1103
1104 # Creating configuration from JSON
1105 reset_config_on_routers(tgen)
1106
1107 # Api call to advertise networks
1108 input_dict = {
1109 "r4": {
1110 "bgp": {
1111 "address_family": {
1112 "ipv4": {
1113 "unicast": {
1114 "advertise_networks": [
1115 {"network": "200.50.2.0/32"},
1116 {"network": "200.60.2.0/32"},
1117 ]
1118 }
1119 },
1120 "ipv6": {
1121 "unicast": {
1122 "advertise_networks": [
1123 {"network": "200:50:2::/128"},
1124 {"network": "200:60:2::/128"},
1125 ]
1126 }
1127 },
1128 }
1129 }
1130 },
1131 "r5": {
1132 "bgp": {
1133 "address_family": {
1134 "ipv4": {
1135 "unicast": {
1136 "advertise_networks": [
1137 {"network": "200.50.2.0/32"},
1138 {"network": "200.60.2.0/32"},
1139 ]
1140 }
1141 },
1142 "ipv6": {
1143 "unicast": {
1144 "advertise_networks": [
1145 {"network": "200:50:2::/128"},
1146 {"network": "200:60:2::/128"},
1147 ]
1148 }
1149 },
1150 }
1151 }
1152 },
1153 }
1154
1155 result = create_router_bgp(tgen, topo, input_dict)
1156 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
1157
1158 # Create Prefix list
1159 input_dict_2 = {
1160 "r2": {
1161 "prefix_lists": {
1162 "ipv4": {
1163 "pf_ls_r2_ipv4": [
1164 {
1165 "seqid": 10,
1166 "network": "200.0.0.0/8",
1167 "le": "32",
1168 "action": "permit",
1169 }
1170 ]
1171 },
1172 "ipv6": {
1173 "pf_ls_r2_ipv6": [
1174 {
1175 "seqid": 20,
1176 "network": "200::/8",
1177 "le": "128",
1178 "action": "permit",
1179 }
1180 ]
1181 },
1182 }
1183 },
1184 "r3": {
1185 "prefix_lists": {
1186 "ipv4": {
1187 "pf_ls_r3_ipv4": [
1188 {
1189 "seqid": 10,
1190 "network": "200.0.0.0/8",
1191 "le": "32",
1192 "action": "permit",
1193 }
1194 ]
1195 },
1196 "ipv6": {
1197 "pf_ls_r3_ipv6": [
1198 {
1199 "seqid": 20,
1200 "network": "200::/8",
1201 "le": "128",
1202 "action": "permit",
1203 }
1204 ]
1205 },
1206 }
1207 },
1208 }
1209 result = create_prefix_lists(tgen, input_dict_2)
1210 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
1211
1212 # Create route map
1213 input_dict_3 = {
1214 "r2": {
1215 "route_maps": {
1216 "RMAP_MED_R2": [
1217 {
1218 "action": "permit",
1219 "seq_id": "10",
1220 "match": {"ipv4": {"prefix_lists": "pf_ls_r2_ipv4"}},
1221 "set": {"metric": 100},
1222 },
1223 {
1224 "action": "permit",
1225 "seq_id": "20",
1226 "match": {"ipv6": {"prefix_lists": "pf_ls_r2_ipv6"}},
1227 "set": {"metric": 100},
1228 },
1229 ]
1230 }
1231 },
1232 "r3": {
1233 "route_maps": {
1234 "RMAP_MED_R3": [
1235 {
1236 "action": "permit",
1237 "seq_id": "10",
1238 "match": {"ipv4": {"prefix_lists": "pf_ls_r3_ipv4"}},
1239 "set": {"metric": 10},
1240 },
1241 {
1242 "action": "permit",
1243 "seq_id": "20",
1244 "match": {"ipv6": {"prefix_lists": "pf_ls_r3_ipv6"}},
1245 "set": {"metric": 10},
1246 },
1247 ]
1248 }
1249 },
1250 }
1251 result = create_route_maps(tgen, input_dict_3)
1252 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
1253
1254 # Configure neighbor for route map
1255 input_dict_4 = {
1256 "r2": {
1257 "bgp": {
1258 "address_family": {
1259 "ipv4": {
1260 "unicast": {
1261 "neighbor": {
1262 "r4": {
1263 "dest_link": {
1264 "r2-link1": {
1265 "route_maps": [
1266 {
1267 "name": "RMAP_MED_R2",
1268 "direction": "in",
1269 }
1270 ]
1271 }
1272 }
1273 },
1274 "r1": {"dest_link": {"r2": {"next_hop_self": True}}},
1275 }
1276 }
1277 },
1278 "ipv6": {
1279 "unicast": {
1280 "neighbor": {
1281 "r4": {
1282 "dest_link": {
1283 "r2-link1": {
1284 "route_maps": [
1285 {
1286 "name": "RMAP_MED_R2",
1287 "direction": "in",
1288 }
1289 ]
1290 }
1291 }
1292 },
1293 "r1": {"dest_link": {"r2": {"next_hop_self": True}}},
1294 }
1295 }
1296 },
1297 }
1298 }
1299 },
1300 "r3": {
1301 "bgp": {
1302 "address_family": {
1303 "ipv4": {
1304 "unicast": {
1305 "neighbor": {
1306 "r1": {"dest_link": {"r3": {"next_hop_self": True}}},
1307 "r5": {
1308 "dest_link": {
1309 "r3": {
1310 "route_maps": [
1311 {
1312 "name": "RMAP_MED_R3",
1313 "direction": "in",
1314 }
1315 ]
1316 }
1317 }
1318 },
1319 }
1320 }
1321 },
1322 "ipv6": {
1323 "unicast": {
1324 "neighbor": {
1325 "r1": {"dest_link": {"r3": {"next_hop_self": True}}},
1326 "r5": {
1327 "dest_link": {
1328 "r3": {
1329 "route_maps": [
1330 {
1331 "name": "RMAP_MED_R3",
1332 "direction": "in",
1333 }
1334 ]
1335 }
1336 }
1337 },
1338 }
1339 }
1340 },
1341 }
1342 }
1343 },
1344 }
1345
1346 result = create_router_bgp(tgen, topo, input_dict_4)
1347 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
1348
1349 # Verifying best path
1350 dut = "r1"
1351 attribute = "metric"
1352 for addr_type in ADDR_TYPES:
1353 result = verify_best_path_as_per_bgp_attribute(
1354 tgen, addr_type, dut, input_dict, attribute
1355 )
1356 assert result is True, "Testcase {} : Failed \n Error: {}".format(
1357 tc_name, result
1358 )
1359
1360 # Modify route-map to set med value
1361 input_dict_3 = {
1362 "r3": {
1363 "route_maps": {
1364 "RMAP_MED_R3": [
1365 {
1366 "action": "permit",
1367 "seq_id": "10",
1368 "match": {"ipv4": {"prefix_lists": "pf_ls_r3_ipv4"}},
1369 "set": {"metric": 200},
1370 },
1371 {
1372 "action": "permit",
1373 "seq_id": "20",
1374 "match": {"ipv6": {"prefix_lists": "pf_ls_r3_ipv6"}},
1375 "set": {"metric": 200},
1376 },
1377 ]
1378 }
1379 }
1380 }
1381
1382 result = create_route_maps(tgen, input_dict_3)
1383 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
1384
1385 # Verifying best path
1386 dut = "r1"
1387 attribute = "metric"
1388 for addr_type in ADDR_TYPES:
1389 result = verify_best_path_as_per_bgp_attribute(
1390 tgen, addr_type, dut, input_dict, attribute
1391 )
1392 assert result is True, "Testcase {} : Failed \n Error: {}".format(
1393 tc_name, result
1394 )
1395
1396 write_test_footer(tc_name)
1397
1398 # Uncomment next line for debugging
1399 # tgen.mininet_cli()
1400
1401
1402 def test_admin_distance(request):
1403 "Verifying admin distance functionality"
1404
1405 tgen = get_topogen()
1406
1407 # Don't run this test if we have any failure.
1408 if tgen.routers_have_failure():
1409 pytest.skip(tgen.errors)
1410
1411 # test case name
1412 tc_name = request.node.name
1413 write_test_header(tc_name)
1414
1415 # Creating configuration from JSON
1416 reset_config_on_routers(tgen)
1417
1418 # Api call to create static routes
1419 input_dict = {
1420 "r2": {
1421 "static_routes": [
1422 {
1423 "network": "200.50.2.0/32",
1424 "admin_distance": 80,
1425 "next_hop": "10.0.0.14",
1426 },
1427 {
1428 "network": "200.50.2.0/32",
1429 "admin_distance": 60,
1430 "next_hop": "10.0.0.18",
1431 },
1432 {
1433 "network": "200:50:2::/128",
1434 "admin_distance": 80,
1435 "next_hop": "fd00::1",
1436 },
1437 {
1438 "network": "200:50:2::/128",
1439 "admin_distance": 60,
1440 "next_hop": "fd00::1",
1441 },
1442 ]
1443 }
1444 }
1445 result = create_static_routes(tgen, input_dict)
1446 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
1447
1448 # Api call to redistribute static routes
1449 input_dict_2 = {
1450 "r2": {
1451 "bgp": {
1452 "address_family": {
1453 "ipv4": {
1454 "unicast": {
1455 "redistribute": [
1456 {"redist_type": "static"},
1457 {"redist_type": "connected"},
1458 ]
1459 }
1460 },
1461 "ipv6": {
1462 "unicast": {
1463 "redistribute": [
1464 {"redist_type": "static"},
1465 {"redist_type": "connected"},
1466 ]
1467 }
1468 },
1469 }
1470 }
1471 }
1472 }
1473 result = create_router_bgp(tgen, input_dict_2)
1474 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
1475
1476 # Verifying best path
1477 dut = "r1"
1478 attribute = "admin_distance"
1479
1480 input_dict = {
1481 "ipv4": {
1482 "r2": {
1483 "static_routes": [
1484 {
1485 "network": "200.50.2.0/32",
1486 "admin_distance": 80,
1487 "next_hop": "10.0.0.14",
1488 },
1489 {
1490 "network": "200.50.2.0/32",
1491 "admin_distance": 60,
1492 "next_hop": "10.0.0.18",
1493 },
1494 ]
1495 }
1496 },
1497 "ipv6": {
1498 "r2": {
1499 "static_routes": [
1500 {
1501 "network": "200:50:2::/128",
1502 "admin_distance": 80,
1503 "next_hop": "fd00::1",
1504 },
1505 {
1506 "network": "200:50:2::/128",
1507 "admin_distance": 60,
1508 "next_hop": "fd00::1",
1509 },
1510 ]
1511 }
1512 },
1513 }
1514
1515 for addr_type in ADDR_TYPES:
1516 result = verify_best_path_as_per_admin_distance(
1517 tgen, addr_type, dut, input_dict[addr_type], attribute
1518 )
1519 assert result is True, "Testcase {} : Failed \n Error: {}".format(
1520 tc_name, result
1521 )
1522
1523 write_test_footer(tc_name)
1524
1525
1526 if __name__ == "__main__":
1527 args = ["-s"] + sys.argv[1:]
1528 sys.exit(pytest.main(args))