2 # SPDX-License-Identifier: ISC
5 # Copyright (c) 2020 by VMware, Inc. ("VMware")
6 # Used Copyright (c) 2018 by Network Device Education Foundation,
7 # Inc. ("NetDEF") in this file.
10 -Verify static route ECMP functionality with 8 next hop
12 -Verify static route functionality with 8 next hop different AD value
14 -Verify static route with tag option
16 -Verify BGP did not install the static route when it receive route
28 # Save the Current Working Directory to find configuration files.
29 CWD
= os
.path
.dirname(os
.path
.realpath(__file__
))
30 sys
.path
.append(os
.path
.join(CWD
, "../"))
31 sys
.path
.append(os
.path
.join(CWD
, "../lib/"))
32 # pylint: disable=C0413
33 # Import topogen and topotest helpers
34 from lib
.topogen
import Topogen
, get_topogen
35 from lib
.topotest
import version_cmp
37 from lib
.common_config
import (
41 reset_config_on_routers
,
46 shutdown_bringup_interface
,
50 from lib
.topolog
import logger
51 from lib
.bgp
import verify_bgp_convergence
, create_router_bgp
, verify_bgp_rib
52 from lib
.topojson
import build_config_from_json
54 pytestmark
= [pytest
.mark
.bgpd
, pytest
.mark
.staticd
]
57 BGP_CONVERGENCE
= False
58 ADDR_TYPES
= check_address_types()
81 PREFIX1
= {"ipv4": "110.0.20.1/32", "ipv6": "20::1/128"}
82 NETWORK2
= {"ipv4": ["11.0.20.1/32"], "ipv6": ["2::1/128"]}
86 def setup_module(mod
):
89 Set up the pytest environment.
93 testsuite_run_time
= time
.asctime(time
.localtime(time
.time()))
94 logger
.info("Testsuite start time: {}".format(testsuite_run_time
))
97 logger
.info("Running setup_module to create topology")
99 # This function initiates the topology build with Topogen...
100 json_file
= "{}/static_routes_topo3_ibgp.json".format(CWD
)
101 tgen
= Topogen(json_file
, mod
.__name
__)
103 topo
= tgen
.json_topo
104 # ... and here it calls Mininet initialization functions.
106 # Starting topology, create tmp files which are loaded to routers
107 # to start daemons and then start routers
110 # Creating configuration from JSON
111 build_config_from_json(tgen
, topo
)
113 if version_cmp(platform
.release(), "4.19") < 0:
115 'These tests will not run. (have kernel "{}", '
116 "requires kernel >= 4.19)".format(platform
.release())
118 pytest
.skip(error_msg
)
120 # Checking BGP convergence
121 global BGP_CONVERGENCE
124 # Don't run this test if we have any failure.
125 if tgen
.routers_have_failure():
126 pytest
.skip(tgen
.errors
)
127 # Api call verify whether BGP is converged
128 BGP_CONVERGENCE
= verify_bgp_convergence(tgen
, topo
)
129 assert BGP_CONVERGENCE
is True, "setup_module :Failed \n Error: {}".format(
133 logger
.info("Running setup_module() done")
136 def teardown_module(mod
):
138 Teardown the pytest environment
143 logger
.info("Running teardown_module to delete topology")
147 # Stop toplogy and Remove tmp files
151 "Testsuite end time: {}".format(time
.asctime(time
.localtime(time
.time())))
153 logger
.info("=" * 40)
159 "ipv4": topo
["routers"]["r1"]["links"]["r2-link0"]["ipv4"].split("/")[0],
160 "ipv6": topo
["routers"]["r1"]["links"]["r2-link0"]["ipv6"].split("/")[0],
163 "ipv4": topo
["routers"]["r1"]["links"]["r2-link1"]["ipv4"].split("/")[0],
164 "ipv6": topo
["routers"]["r1"]["links"]["r2-link1"]["ipv6"].split("/")[0],
167 "ipv4": topo
["routers"]["r1"]["links"]["r2-link2"]["ipv4"].split("/")[0],
168 "ipv6": topo
["routers"]["r1"]["links"]["r2-link2"]["ipv6"].split("/")[0],
171 "ipv4": topo
["routers"]["r1"]["links"]["r2-link3"]["ipv4"].split("/")[0],
172 "ipv6": topo
["routers"]["r1"]["links"]["r2-link3"]["ipv6"].split("/")[0],
175 "ipv4": topo
["routers"]["r1"]["links"]["r2-link4"]["ipv4"].split("/")[0],
176 "ipv6": topo
["routers"]["r1"]["links"]["r2-link4"]["ipv6"].split("/")[0],
179 "ipv4": topo
["routers"]["r1"]["links"]["r2-link5"]["ipv4"].split("/")[0],
180 "ipv6": topo
["routers"]["r1"]["links"]["r2-link5"]["ipv6"].split("/")[0],
183 "ipv4": topo
["routers"]["r1"]["links"]["r2-link6"]["ipv4"].split("/")[0],
184 "ipv6": topo
["routers"]["r1"]["links"]["r2-link6"]["ipv6"].split("/")[0],
187 "ipv4": topo
["routers"]["r1"]["links"]["r2-link7"]["ipv4"].split("/")[0],
188 "ipv6": topo
["routers"]["r1"]["links"]["r2-link7"]["ipv6"].split("/")[0],
194 #####################################################
198 #####################################################
201 def test_staticroute_with_ecmp_p0_tc3_ibgp(request
):
203 Verify static route ECMP functionality with 8 next hop'
206 tc_name
= request
.node
.name
207 write_test_header(tc_name
)
210 # Don't run this test if we have any failure.
211 if tgen
.routers_have_failure():
212 pytest
.skip(tgen
.errors
)
214 reset_config_on_routers(tgen
)
215 NEXT_HOP_IP
= populate_nh()
217 step("Configure 8 interfaces / links between R1 and R2,")
219 "Configure IPv4 static route in R2 with 8 next hop"
220 "N1(21.1.1.2), N2(22.1.1.2), N3(23.1.1.2), N4(24.1.1.2),"
221 "N5(25.1.1.2), N6(26.1.1.2), N7(27.1.1.2),N8(28.1.1.2), Static"
222 "route next-hop present on R1"
225 step("Configure IBGP IPv4 peering between R2 and R3 router.")
227 for addr_type
in ADDR_TYPES
:
228 # Enable static routes
229 for nhp
in range(1, 9):
234 "network": PREFIX1
[addr_type
],
235 "next_hop": NEXT_HOP_IP
["nh" + str(nhp
)][addr_type
],
240 logger
.info("Configure static routes")
241 result
= create_static_routes(tgen
, input_dict_4
)
242 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
245 logger
.info("Verifying %s routes on r2", addr_type
)
247 NEXT_HOP_IP
["nh1"][addr_type
],
248 NEXT_HOP_IP
["nh2"][addr_type
],
249 NEXT_HOP_IP
["nh3"][addr_type
],
250 NEXT_HOP_IP
["nh4"][addr_type
],
251 NEXT_HOP_IP
["nh5"][addr_type
],
252 NEXT_HOP_IP
["nh6"][addr_type
],
253 NEXT_HOP_IP
["nh7"][addr_type
],
254 NEXT_HOP_IP
["nh8"][addr_type
],
260 tgen
, addr_type
, dut
, input_dict_4
, next_hop
=nh
, protocol
=protocol
264 ), "Testcase {} : Failed \nError: Routes are" " missing in RIB".format(tc_name
)
265 step("Configure redistribute static in BGP on R2 router")
266 for addr_type
in ADDR_TYPES
:
272 "unicast": {"redistribute": [{"redist_type": "static"}]}
278 result
= create_router_bgp(tgen
, topo
, input_dict_2
)
279 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
284 "Remove the static route configured with nexthop N1 to N8, one"
285 "by one from running config"
287 for addr_type
in ADDR_TYPES
:
288 # delete static routes
289 for nhp
in range(1, 9):
294 "network": PREFIX1
[addr_type
],
295 "next_hop": NEXT_HOP_IP
["nh" + str(nhp
)][addr_type
],
302 logger
.info("Configure static routes")
303 result
= create_static_routes(tgen
, input_dict_4
)
304 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
319 ), "Testcase {} : Failed \nError: Routes are" " still present in RIB".format(
323 step("Configure the static route with nexthop N1 to N8, one by" "one")
325 for addr_type
in ADDR_TYPES
:
327 for nhp
in range(1, 9):
332 "network": PREFIX1
[addr_type
],
333 "next_hop": NEXT_HOP_IP
["nh" + str(nhp
)][addr_type
],
339 logger
.info("Configure static routes")
340 result
= create_static_routes(tgen
, input_dict_4
)
341 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
346 tgen
, addr_type
, dut
, input_dict_4
, next_hop
=nh
, protocol
=protocol
350 ), "Testcase {} : Failed \nError: Routes are" " missing in RIB".format(tc_name
)
352 step("Random shut of the nexthop interfaces")
353 randnum
= random
.randint(0, 7)
354 for addr_type
in ADDR_TYPES
:
355 intf
= topo
["routers"]["r2"]["links"]["r1-link" + str(randnum
)]["interface"]
356 shutdown_bringup_interface(tgen
, dut
, intf
, False)
357 nhip
= NEXT_HOP_IP
["nh" + str(randnum
+ 1)][addr_type
]
362 "network": PREFIX1
[addr_type
],
363 "next_hop": NEXT_HOP_IP
["nh" + str(randnum
+ 1)][addr_type
],
379 ), "Testcase {} : Failed \n" "Error: Routes are still present in RIB".format(
383 step("Random no shut of the nexthop interfaces")
384 for addr_type
in ADDR_TYPES
:
385 intf
= topo
["routers"]["r2"]["links"]["r1-link" + str(randnum
)]["interface"]
386 shutdown_bringup_interface(tgen
, dut
, intf
, True)
387 nhip
= NEXT_HOP_IP
["nh" + str(randnum
+ 1)][addr_type
]
389 tgen
, addr_type
, dut
, input_dict_5
, next_hop
=nhip
, protocol
=protocol
393 ), "Testcase {} : Failed \n" "Error: Routes are missing in RIB".format(tc_name
)
395 step("Reload the FRR router")
396 # stop/start -> restart FRR router and verify
397 stop_router(tgen
, "r2")
398 start_router(tgen
, "r2")
401 tgen
, addr_type
, dut
, input_dict_4
, next_hop
=nh
, protocol
=protocol
405 ), "Testcase {} : Failed \nError: Routes are" " missing in RIB".format(tc_name
)
407 write_test_footer(tc_name
)
410 def test_staticroute_with_ecmp_with_diff_AD_p0_tc4_ibgp(request
):
412 Verify static route ECMP functionality with 8 next hop
415 tc_name
= request
.node
.name
416 write_test_header(tc_name
)
419 # Don't run this test if we have any failure.
420 if tgen
.routers_have_failure():
421 pytest
.skip(tgen
.errors
)
423 reset_config_on_routers(tgen
)
425 step("Configure 8 interfaces / links between R1 and R2,")
426 step("Configure IBGP IPv4 peering between R2 and R3 router.")
427 NEXT_HOP_IP
= populate_nh()
429 for addr_type
in ADDR_TYPES
:
430 nh_all
[addr_type
] = []
431 for nhp
in range(1, 9):
432 nh_all
[addr_type
].append(NEXT_HOP_IP
["nh" + str(nhp
)][addr_type
])
434 "Configure IPv4 static route in R2 with 8 next hop"
435 "N1(21.1.1.2) AD 10, N2(22.1.1.2) AD 20, N3(23.1.1.2) AD 30,"
436 "N4(24.1.1.2) AD 40, N5(25.1.1.2) AD 50, N6(26.1.1.2) AD 60,"
437 "N7(27.1.1.2) AD 70, N8(28.1.1.2) AD 80, Static route next-hop"
440 for addr_type
in ADDR_TYPES
:
441 for nhp
in range(1, 9):
446 "network": PREFIX1
[addr_type
],
447 "next_hop": NEXT_HOP_IP
["nh" + str(nhp
)][addr_type
],
448 "admin_distance": 10 * nhp
,
453 logger
.info("Configure static routes")
454 result
= create_static_routes(tgen
, input_dict_4
)
455 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
458 logger
.info("Verifying %s routes on r2", addr_type
)
461 "On R2, static route installed in RIB using "
462 "show ip route with 8 next hop, lowest AD nexthop is active"
464 step("On R2, static route with lowest AD nexthop installed in FIB")
469 "network": PREFIX1
[addr_type
],
470 "next_hop": NEXT_HOP_IP
["nh1"][addr_type
],
471 "admin_distance": 10,
478 nh
= NEXT_HOP_IP
["nh1"][addr_type
]
480 tgen
, addr_type
, dut
, input_dict_4
, next_hop
=nh
, protocol
=protocol
, fib
=True
482 assert result
is True, (
483 "Testcase {} : Failed \nError: Route with "
484 " lowest AD is missing in RIB".format(tc_name
)
488 for nhp
in range(2, 9):
489 nh
.append(NEXT_HOP_IP
["nh" + str(nhp
)][addr_type
])
500 assert result
is not True, (
501 "Testcase {} : Failed \nError: Routes "
502 " with high AD are active in RIB".format(tc_name
)
505 step("Configure redistribute static in BGP on R2 router")
506 for addr_type
in ADDR_TYPES
:
512 "unicast": {"redistribute": [{"redist_type": "static"}]}
519 logger
.info("Configuring redistribute static")
520 result
= create_router_bgp(tgen
, topo
, input_dict_2
)
521 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
526 "After configuring them, route is always active with lowest AD"
527 "value and all the nexthop populated in RIB and FIB again "
533 "network": PREFIX1
[addr_type
],
534 "next_hop": NEXT_HOP_IP
["nh1"][addr_type
],
535 "admin_distance": 10,
542 nh
= NEXT_HOP_IP
["nh1"][addr_type
]
544 tgen
, addr_type
, dut
, input_dict_4
, next_hop
=nh
, protocol
=protocol
, fib
=True
546 assert result
is True, (
547 "Testcase {} : Failed \nError: Route with "
548 " lowest AD is missing in RIB".format(tc_name
)
552 "Remove the static route configured with nexthop N1 to N8, one"
553 "by one from running config"
556 for addr_type
in ADDR_TYPES
:
557 # delete static routes
558 for nhp
in range(1, 9):
563 "network": PREFIX1
[addr_type
],
564 "next_hop": NEXT_HOP_IP
["nh" + str(nhp
)][addr_type
],
565 "admin_distance": 10 * nhp
,
572 logger
.info("Configure static routes")
573 result
= create_static_routes(tgen
, input_dict_4
)
574 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
579 "After removing the static route with N1 to N8 one by one, "
580 "route become active with next preferred nexthop and nexthop which "
581 "got removed is not shown in RIB and FIB"
588 next_hop
=nh_all
[addr_type
],
594 ), "Testcase {} : Failed \nError: Routes are" " still present in RIB".format(
598 step("Configure the static route with nexthop N1 to N8, one by" "one")
599 for addr_type
in ADDR_TYPES
:
601 for nhp
in range(1, 9):
606 "network": PREFIX1
[addr_type
],
607 "next_hop": NEXT_HOP_IP
["nh" + str(nhp
)][addr_type
],
608 "admin_distance": 10 * nhp
,
613 logger
.info("Configure static routes")
614 result
= create_static_routes(tgen
, input_dict_4
)
615 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
619 step("On R2, static route with lowest AD nexthop installed in FIB")
624 "network": PREFIX1
[addr_type
],
625 "next_hop": NEXT_HOP_IP
["nh1"][addr_type
],
626 "admin_distance": 10,
633 nh
= NEXT_HOP_IP
["nh1"][addr_type
]
635 tgen
, addr_type
, dut
, input_dict_4
, next_hop
=nh
, protocol
=protocol
, fib
=True
637 assert result
is True, (
638 "Testcase {} : Failed \nError: Route with "
639 " lowest AD is missing in RIB".format(tc_name
)
643 for nhp
in range(2, 9):
644 nh
.append(NEXT_HOP_IP
["nh" + str(nhp
)][addr_type
])
655 assert result
is not True, (
656 "Testcase {} : Failed \nError: Routes "
657 " with high AD are active in RIB".format(tc_name
)
660 step("Random shut of the nexthop interfaces")
661 randnum
= random
.randint(0, 7)
662 for addr_type
in ADDR_TYPES
:
663 intf
= topo
["routers"]["r2"]["links"]["r1-link" + str(randnum
)]["interface"]
664 shutdown_bringup_interface(tgen
, dut
, intf
, False)
665 nhip
= NEXT_HOP_IP
["nh" + str(randnum
+ 1)][addr_type
]
670 "network": PREFIX1
[addr_type
],
671 "next_hop": NEXT_HOP_IP
["nh" + str(randnum
+ 1)][addr_type
],
687 ), "Testcase {} : Failed \n" "Error: Routes are still present in RIB".format(
691 step("Random no shut of the nexthop interfaces")
692 for addr_type
in ADDR_TYPES
:
693 intf
= topo
["routers"]["r2"]["links"]["r1-link" + str(randnum
)]["interface"]
694 shutdown_bringup_interface(tgen
, dut
, intf
, True)
695 nhip
= NEXT_HOP_IP
["nh" + str(randnum
+ 1)][addr_type
]
697 tgen
, addr_type
, dut
, input_dict_5
, next_hop
=nhip
, protocol
=protocol
701 ), "Testcase {} : Failed \n" "Error: Routes are missing in RIB".format(tc_name
)
703 step("Reload the FRR router")
704 # stop/start -> restart FRR router and verify
705 stop_router(tgen
, "r2")
706 start_router(tgen
, "r2")
709 "After reload of FRR router, static route installed "
710 "in RIB and FIB properly ."
712 for addr_type
in ADDR_TYPES
:
717 "network": PREFIX1
[addr_type
],
718 "next_hop": NEXT_HOP_IP
["nh1"][addr_type
],
719 "admin_distance": 10,
726 nh
= NEXT_HOP_IP
["nh1"][addr_type
]
728 tgen
, addr_type
, dut
, input_dict_4
, next_hop
=nh
, protocol
=protocol
, fib
=True
730 assert result
is True, (
731 "Testcase {} : Failed \nError: Route with "
732 " lowest AD is missing in RIB".format(tc_name
)
736 for nhp
in range(2, 9):
737 nh
.append(NEXT_HOP_IP
["nh" + str(nhp
)][addr_type
])
748 assert result
is not True, (
749 "Testcase {} : Failed \nError: Routes "
750 " with high AD are active in RIB".format(tc_name
)
753 step("Remove the redistribute static knob")
755 for addr_type
in ADDR_TYPES
:
763 {"redist_type": "static", "delete": True}
772 logger
.info("Remove redistribute static")
773 result
= create_router_bgp(tgen
, topo
, input_dict_2
)
774 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
777 step("verify that routes are deleted from R3 routing table")
789 assert result
is not True, (
790 "Testcase {} : Failed \nError: Routes are"
791 " still present in RIB of R3".format(tc_name
)
794 write_test_footer(tc_name
)
797 def test_bgp_local_nexthop_p1_tc14_ibgp(request
):
799 Verify BGP did not install the static route when it receive route
803 tc_name
= request
.node
.name
804 write_test_header(tc_name
)
807 step("Configure BGP IPv4 session between R2 and R3")
808 step("Configure IPv4 static route on R2")
809 reset_config_on_routers(tgen
)
811 for addr_type
in ADDR_TYPES
:
812 # Enable static routes
817 "network": NETWORK
[addr_type
],
818 "next_hop": topo
["routers"]["r3"]["links"]["r2-link0"][
826 logger
.info("Configure static routes")
827 result
= create_static_routes(tgen
, input_dict_4
)
828 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
832 step("Configure redistribute static in the BGP")
839 "unicast": {"redistribute": [{"redist_type": "static"}]}
845 result
= create_router_bgp(tgen
, topo
, input_dict_2
)
846 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
850 step("Verify R2 BGP table has IPv4 route")
852 result
= verify_rib(tgen
, addr_type
, dut
, input_dict_4
)
855 ), "Testcase {} : Failed \nError: Routes is" " missing in RIB of R2".format(
859 step(" Verify route did not install in the R3 BGP table, RIB/FIB")
861 result
= verify_bgp_rib(tgen
, addr_type
, dut
, input_dict_4
, expected
=False)
862 assert result
is not True, (
863 "Testcase {} : Failed \nError: Routes is"
864 " still present in BGP RIB of R2".format(tc_name
)
867 result
= verify_rib(tgen
, addr_type
, dut
, input_dict_4
, expected
=False)
868 assert result
is not True, (
869 "Testcase {} : Failed \nError: Routes is"
870 " still present in RIB of R2".format(tc_name
)
873 write_test_footer(tc_name
)
876 if __name__
== "__main__":
877 args
= ["-s"] + sys
.argv
[1:]
878 sys
.exit(pytest
.main(args
))