4 # Copyright (c) 2022 by VMware, Inc. ("VMware")
5 # Used Copyright (c) 2018 by Network Device Education Foundation,
6 # Inc. ("NetDEF") in this file.
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
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
30 """Following tests are covered to test bgp admin distance functionality.
32 Verify bgp admin distance functionality when static route is
33 configured same as ebgp learnt route
36 Verify ebgp admin distance functionality with ECMP.
39 Verify ibgp admin distance functionality when static route is
40 configured same as bgp learnt route.
42 Verify ibgp admin distance functionality with ECMP.
44 TC_7: Chaos - Verify bgp admin distance functionality with chaos.
47 #################################
49 #################################
60 | iBGP +-------+ eBGP +-------+
61 +---------- | R3 |----------| R4 |
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/"))
78 # pylint: disable=C0413
79 # Import topogen and topotest helpers
80 from lib
.topogen
import Topogen
, get_topogen
82 # Required to instantiate the topology builder class.
83 from lib
.common_config
import (
93 reset_config_on_routers
,
99 get_frr_ipv6_linklocal
,
102 from lib
.topolog
import logger
103 from lib
.bgp
import (
104 verify_bgp_convergence
,
106 verify_best_path_as_per_admin_distance
,
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
118 bgp_convergence
= False
119 pytestmark
= [pytest
.mark
.bgpd
, pytest
.mark
.staticd
]
140 ADDR_TYPES
= check_address_types()
143 def setup_module(mod
):
145 Sets up the pytest environment
152 testsuite_run_time
= time
.asctime(time
.localtime(time
.time()))
153 logger
.info("Testsuite start time: {}".format(testsuite_run_time
))
154 logger
.info("=" * 40)
156 logger
.info("Running setup_module to create topology")
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
__)
162 topo
= tgen
.json_topo
164 # Starting topology, create tmp files which are loaded to routers
165 # to start deamons and then start routers
168 # Creating configuration from JSON
169 build_config_from_json(tgen
, topo
)
171 # Checking BGP convergence
172 global bgp_convergence
175 # Don't run this test if we have any failure.
176 if tgen
.routers_have_failure():
177 pytest
.skip(tgen
.errors
)
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(
184 logger
.info("Running setup_module() done")
187 def teardown_module(mod
):
190 Teardown the pytest environment.
193 logger
.info("Running teardown_module to delete topology")
196 # Stop toplogy and Remove tmp files
200 "Testsuite end time: {}".format(time
.asctime(time
.localtime(time
.time())))
202 logger
.info("=" * 40)
205 #####################################################
207 #####################################################
208 def test_bgp_admin_distance_ebgp_ecmp_p0():
211 Verify ebgp admin distance functionality with ECMP.
214 global bgp_convergence
216 if bgp_convergence
is not True:
217 pytest
.skip("skipping test case because of BGP Convergence failure at setup")
220 tc_name
= inspect
.stack()[0][3]
221 write_test_header(tc_name
)
222 if tgen
.routers_have_failure():
223 check_router_status(tgen
)
225 step("Configure base config as per the topology")
226 reset_config_on_routers(tgen
)
228 step("Configure static route in R4 and R5, redistribute in bgp")
230 for addr_type
in ADDR_TYPES
:
234 "static_routes": [{"network": NETWORK
[addr_type
], "next_hop": "Null0"}]
238 result
= create_static_routes(tgen
, input_dict
)
239 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
243 for addr_type
in ADDR_TYPES
:
247 "static_routes": [{"network": NETWORK
[addr_type
], "next_hop": "Null0"}]
251 result
= create_static_routes(tgen
, input_dict
)
252 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
256 step("Verify that route is learnt in DUT via ebgp")
258 # Verifying RIB routes
260 input_dict
= topo
["routers"]
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"))
268 for addr_type
in ADDR_TYPES
:
272 {"network": NETWORK
[addr_type
][0], "next_hop": "Null0"}
276 result4
= verify_rib(tgen
, addr_type
, dut
, input_dict
, protocol
=protocol
)
277 assert result4
is True, "Testcase {} : Failed \n Error: {}".format(
281 step("Configure the static route in R3 (Dut).")
283 for addr_type
in ADDR_TYPES
:
288 {"network": NETWORK
[addr_type
][0], "next_hop": "Null0"}
293 result
= create_static_routes(tgen
, input_dict
)
294 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
298 step("Verify that static route is selected as best route in zebra.")
300 # Verifying RIB routes
304 for addr_type
in ADDR_TYPES
:
308 {"network": NETWORK
[addr_type
][0], "next_hop": "Null0"}
313 result4
= verify_rib(tgen
, addr_type
, dut
, input_dict
, protocol
=protocol
)
314 assert result4
is True, "Testcase {} : Failed \n Error: {}".format(
318 step(" Configure the admin distance of 254 to static route in R3.")
320 for addr_type
in ADDR_TYPES
:
326 "network": NETWORK
[addr_type
][0],
328 "admin_distance": 254,
334 result
= create_static_routes(tgen
, input_dict
)
335 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
339 step("Verify that bgp routes are selected as best routes in zebra.")
343 for addr_type
in ADDR_TYPES
:
347 {"network": NETWORK
[addr_type
][0], "next_hop": "Null0"}
351 result4
= verify_rib(tgen
, addr_type
, dut
, input_dict
, protocol
=protocol
)
352 assert result4
is True, "Testcase {} : Failed \n Error: {}".format(
363 "distance": {"ebgp": 254, "ibgp": 254, "local": 254}
368 "distance": {"ebgp": 254, "ibgp": 254, "local": 254}
376 result
= create_router_bgp(tgen
, topo
, input_dict_1
)
377 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
379 step("Verify that bgp routes are selected as best routes in zebra.")
380 # Verifying RIB routes
384 for addr_type
in ADDR_TYPES
:
388 {"network": NETWORK
[addr_type
][0], "next_hop": "Null0"}
392 result4
= verify_rib(tgen
, addr_type
, dut
, input_dict
, protocol
=protocol
)
393 assert result4
is True, "Testcase {} : Failed \n Error: {}".format(
397 step("Configure bgp admin distance 10 with CLI in dut.")
404 "unicast": {"distance": {"ebgp": 10, "ibgp": 254, "local": 254}}
407 "unicast": {"distance": {"ebgp": 10, "ibgp": 254, "local": 254}}
414 result
= create_router_bgp(tgen
, topo
, input_dict_1
)
415 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
417 step("Verify ebgp routes have admin distance of 10 in dut.")
420 input_dict
= topo
["routers"]
423 for addr_type
in ADDR_TYPES
:
427 {"network": NETWORK
[addr_type
][0], "next_hop": "Null0"}
431 result4
= verify_rib(
432 tgen
, addr_type
, dut
, input_dict
, protocol
=protocol
, admin_distance
=10
434 assert result4
is True, "Testcase {} : Failed \n Error: {}".format(
439 "Configure route map with weight as 200 and apply to one of the "
440 "neighbor (R4 neighbor)."
451 "network": NETWORK
["ipv4"][0],
461 "network": NETWORK
["ipv6"][0],
470 result
= create_prefix_lists(tgen
, input_dict_2
)
471 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
480 "match": {"ipv4": {"prefix_lists": "pf_ls_1"}},
481 "set": {"weight": 200},
485 "match": {"ipv6": {"prefix_lists": "pf_ls_1_ipv6"}},
486 "set": {"weight": 200},
492 result
= create_route_maps(tgen
, input_dict_3
)
493 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
495 # Configure neighbor for route map
508 "name": "RMAP_WEIGHT",
526 "name": "RMAP_WEIGHT",
540 result
= create_router_bgp(tgen
, topo
, input_dict_4
)
541 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
543 step("Verify that bgp route is selected as best on by zebra in r3.")
548 for addr_type
in ADDR_TYPES
:
552 {"network": NETWORK
[addr_type
][0], "next_hop": "Null0"}
556 result4
= verify_rib(
557 tgen
, addr_type
, dut
, input_dict
, protocol
=protocol
, admin_distance
=10
559 assert result4
is True, "Testcase {} : Failed \n Error: {}".format(
563 step("Static route should not be selected as best route.")
567 for addr_type
in ADDR_TYPES
:
571 {"network": NETWORK
[addr_type
][0], "next_hop": "Null0"}
575 result4
= verify_fib_routes(
576 tgen
, addr_type
, dut
, input_dict
, protocol
=protocol
, expected
=False
580 ), "Testcase {} : Failed. Wrong route is selected as best route.\n Error: {}".format(
584 step("Reconfigure the static route without admin distance")
586 for addr_type
in ADDR_TYPES
:
592 "network": NETWORK
[addr_type
][0],
594 "admin_distance": 254,
601 result
= create_static_routes(tgen
, input_dict
)
602 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
606 for addr_type
in ADDR_TYPES
:
610 {"network": NETWORK
[addr_type
][0], "next_hop": "Null0"}
615 result
= create_static_routes(tgen
, input_dict
)
616 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
620 step("Verify that static route is installed as best route.")
624 for addr_type
in ADDR_TYPES
:
628 {"network": NETWORK
[addr_type
][0], "next_hop": "Null0"}
632 result4
= verify_rib(
633 tgen
, addr_type
, dut
, input_dict
, protocol
=protocol
, fib
=True
635 assert result4
is True, "Testcase {} : Failed \n Error: {}".format(
639 step("Unconfigure the static route in R3.")
641 for addr_type
in ADDR_TYPES
:
646 "network": NETWORK
[addr_type
][0],
654 result
= create_static_routes(tgen
, input_dict
)
655 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
659 step("Verify that bgp route is selected as best on by zebra in r3.")
664 for addr_type
in ADDR_TYPES
:
668 {"network": NETWORK
[addr_type
][0], "next_hop": "Null0"}
672 result4
= verify_rib(tgen
, addr_type
, dut
, input_dict
, protocol
=protocol
)
673 assert result4
is True, "Testcase {} : Failed \n Error: {}".format(
677 step("Un configure the route map on R3.")
679 # Configure neighbor for route map
692 "name": "RMAP_WEIGHT",
711 "name": "RMAP_WEIGHT",
726 result
= create_router_bgp(tgen
, topo
, input_dict_4
)
727 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
729 step("verify bgp routes installed in zebra.")
731 # Verifying RIB routes
733 input_dict
= topo
["routers"]
735 for addr_type
in ADDR_TYPES
:
739 {"network": NETWORK
[addr_type
][0], "next_hop": "Null0"}
743 result4
= verify_rib(tgen
, addr_type
, dut
, input_dict
, protocol
=protocol
)
744 assert result4
is True, "Testcase {} : Failed \n Error: {}".format(
748 write_test_footer(tc_name
)
751 def test_bgp_admin_distance_ibgp_p0():
754 Verify bgp admin distance functionality when static route is
755 configured same as ibgp learnt route
758 global bgp_convergence
760 if bgp_convergence
is not True:
761 pytest
.skip("skipping test case because of BGP Convergence failure at setup")
764 tc_name
= inspect
.stack()[0][3]
765 write_test_header(tc_name
)
766 if tgen
.routers_have_failure():
767 check_router_status(tgen
)
769 step("Configure base config as per the topology")
770 reset_config_on_routers(tgen
)
772 step("Configure bgp admin distance 200 with CLI in dut.")
781 "distance": {"ebgp": 200, "ibgp": 200, "local": 200}
786 "distance": {"ebgp": 200, "ibgp": 200, "local": 200}
794 result
= create_router_bgp(tgen
, topo
, input_dict_1
)
795 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
797 step("Verify bgp routes have admin distance of 200 in dut.")
798 # Verifying best path
800 attribute
= "admin_distance"
807 "network": "192.168.22.1/32",
808 "admin_distance": 200,
811 "network": "192.168.22.2/32",
812 "admin_distance": 200,
821 "network": "fc07:1::1/128",
822 "admin_distance": 200,
825 "network": "fc07:1::2/128",
826 "admin_distance": 200,
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
837 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
841 step("Modify the admin distance value to 150.")
850 "distance": {"ebgp": 150, "ibgp": 150, "local": 150}
855 "distance": {"ebgp": 150, "ibgp": 150, "local": 150}
863 result
= create_router_bgp(tgen
, topo
, input_dict_1
)
864 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
866 step("Verify bgp routes have admin distance of 150 in dut.")
867 # Verifying best path
869 attribute
= "admin_distance"
876 "network": "192.168.22.1/32",
877 "admin_distance": 150,
880 "network": "192.168.22.2/32",
881 "admin_distance": 150,
890 "network": "fc07:1::1/128",
891 "admin_distance": 150,
894 "network": "fc07:1::2/128",
895 "admin_distance": 150,
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
906 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
910 step("Un configure the admin distance value on DUT")
942 result
= create_router_bgp(tgen
, topo
, input_dict_1
)
943 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
945 step("Verify bgp routes have default admin distance in dut.")
946 # Verifying best path
948 attribute
= "admin_distance"
955 "network": "192.168.22.1/32",
956 "admin_distance": 20,
959 "network": "192.168.22.2/32",
960 "admin_distance": 20,
969 "network": "fc07:1::1/128",
970 "admin_distance": 20,
973 "network": "fc07:1::2/128",
974 "admin_distance": 20,
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
985 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
990 "Learn the same route via ebgp and ibgp peer. Configure admin "
991 "distance of 200 in DUT for both ebgp and ibgp peer. "
994 step("Verify that ebgp route is preferred over ibgp.")
996 # Verifying RIB routes
998 input_dict
= topo
["routers"]
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(
1006 step("Configure static route Without any admin distance")
1008 for addr_type
in ADDR_TYPES
:
1012 "static_routes": [{"network": NETWORK
[addr_type
], "next_hop": "Null0"}]
1016 result
= create_static_routes(tgen
, input_dict
)
1017 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1021 step("Verify that zebra selects static route.")
1024 for addr_type
in ADDR_TYPES
:
1028 "static_routes": [{"network": NETWORK
[addr_type
], "next_hop": "Null0"}]
1032 result4
= verify_rib(tgen
, addr_type
, dut
, input_dict
, protocol
=protocol
)
1033 assert result4
is True, "Testcase {} : Failed \n Error: {}".format(
1037 step("Configure static route with admin distance of 253")
1038 for addr_type
in ADDR_TYPES
:
1044 "network": NETWORK
[addr_type
],
1045 "next_hop": "Null0",
1046 "admin_distance": 253,
1052 result
= create_static_routes(tgen
, input_dict
)
1053 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1057 step("Verify that zebra selects bgp route.")
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(
1066 step("Configure admin distance of 254 in bgp for route.")
1075 "distance": {"ebgp": 254, "ibgp": 254, "local": 254}
1080 "distance": {"ebgp": 254, "ibgp": 254, "local": 254}
1088 result
= create_router_bgp(tgen
, topo
, input_dict_1
)
1089 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
1091 step("Verify that zebra selects static route.")
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(
1100 step("Delete the static route.")
1101 for addr_type
in ADDR_TYPES
:
1107 "network": NETWORK
[addr_type
],
1108 "next_hop": "Null0",
1109 "admin_distance": 253,
1116 result
= create_static_routes(tgen
, input_dict
)
1117 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1121 step("Verify that zebra selects bgp route.")
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(
1130 write_test_footer(tc_name
)
1133 def test_bgp_admin_distance_chaos_p2():
1136 Chaos - Verify bgp admin distance functionality with chaos.
1138 tgen
= get_topogen()
1139 global bgp_convergence
1141 if bgp_convergence
is not True:
1142 pytest
.skip("skipping test case because of BGP Convergence failure at setup")
1145 tc_name
= inspect
.stack()[0][3]
1146 write_test_header(tc_name
)
1147 if tgen
.routers_have_failure():
1148 check_router_status(tgen
)
1150 step("Configure base config as per the topology")
1151 reset_config_on_routers(tgen
)
1153 step("Configure bgp admin distance 200 with CLI in dut.")
1162 "distance": {"ebgp": 200, "ibgp": 200, "local": 200}
1167 "distance": {"ebgp": 200, "ibgp": 200, "local": 200}
1175 result
= create_router_bgp(tgen
, topo
, input_dict_1
)
1176 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
1178 step("Verify bgp routes have admin distance of 200 in dut.")
1179 # Verifying best path
1181 attribute
= "admin_distance"
1188 "network": NETWORK
["ipv4"][0],
1189 "admin_distance": 200,
1192 "network": NETWORK
["ipv4"][1],
1193 "admin_distance": 200,
1202 "network": NETWORK
["ipv6"][0],
1203 "admin_distance": 200,
1206 "network": NETWORK
["ipv6"][1],
1207 "admin_distance": 200,
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
1218 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1222 step("Restart frr on R3")
1223 stop_router(tgen
, "r3")
1224 start_router(tgen
, "r3")
1226 bgp_convergence
= verify_bgp_convergence(tgen
, topo
)
1227 assert bgp_convergence
is True, "Testcase {} : Failed \n Error: {}".format(
1228 tc_name
, bgp_convergence
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
1236 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1240 step("Restart bgpd process on R3")
1241 kill_router_daemons(tgen
, "r3", ["bgpd"])
1242 start_router_daemons(tgen
, "r3", ["bgpd"])
1244 bgp_convergence
= verify_bgp_convergence(tgen
, topo
)
1245 assert bgp_convergence
is True, "Testcase {} : Failed \n Error: {}".format(
1246 tc_name
, bgp_convergence
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
1254 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1259 for rtr
in topo
["routers"]:
1260 clear_bgp(tgen
, "ipv4", rtr
)
1261 clear_bgp(tgen
, "ipv6", rtr
)
1263 bgp_convergence
= verify_bgp_convergence(tgen
, topo
)
1264 assert bgp_convergence
is True, "Testcase {} : Failed \n Error: {}".format(
1265 tc_name
, bgp_convergence
1268 step("Verify that zebra selects bgp route.")
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(
1277 write_test_footer(tc_name
)
1280 if __name__
== "__main__":
1281 args
= ["-s"] + sys
.argv
[1:]
1282 sys
.exit(pytest
.main(args
))