2 # SPDX-License-Identifier: ISC
5 # Copyright (c) 2021 by VMware, Inc. ("VMware")
6 # Used Copyright (c) 2018 by Network Device Education Foundation, Inc.
7 # ("NetDEF") in this file.
12 Following tests are covered to test ecmp functionality on BGP GSHUT.
13 1. Verify graceful-shutdown functionality with iBGP peers
14 2. Verify graceful-shutdown functionality after
15 deleting/re-adding route-map with iBGP peers
23 # Save the Current Working Directory to find configuration files.
24 CWD
= os
.path
.dirname(os
.path
.realpath(__file__
))
25 sys
.path
.append(os
.path
.join(CWD
, "../"))
26 sys
.path
.append(os
.path
.join(CWD
, "../../"))
28 # pylint: disable=C0413
29 # Import topogen and topotest helpers
30 from lib
.topogen
import Topogen
, get_topogen
32 from lib
.common_config
import (
38 reset_config_on_routers
,
40 get_frr_ipv6_linklocal
,
42 create_bgp_community_lists
,
43 required_linux_kernel_version
,
45 from lib
.topolog
import logger
47 verify_bgp_convergence
,
50 verify_bgp_attributes
,
52 from lib
.topojson
import build_config_from_json
54 pytestmark
= [pytest
.mark
.bgpd
, pytest
.mark
.staticd
]
58 NETWORK
= {"ipv4": "100.0.10.1/32", "ipv6": "1::1/128"}
59 NEXT_HOP_IP_1
= {"ipv4": "10.0.3.1", "ipv6": "fd00:0:0:3::1"}
60 NEXT_HOP_IP_2
= {"ipv4": "10.0.4.1", "ipv6": "fd00:0:0:2::1"}
61 PREFERRED_NEXT_HOP
= "link_local"
62 BGP_CONVERGENCE
= False
65 def setup_module(mod
):
67 Sets up the pytest environment
74 # Required linux kernel version for this suite to run.
75 result
= required_linux_kernel_version("4.16")
76 if result
is not True:
77 pytest
.skip("Kernel requirements are not met, kernel version should be >=4.16")
79 testsuite_run_time
= time
.asctime(time
.localtime(time
.time()))
80 logger
.info("Testsuite start time: {}".format(testsuite_run_time
))
83 logger
.info("Running setup_module to create topology")
85 # This function initiates the topology build with Topogen...
86 json_file
= "{}/ibgp_gshut_topo1.json".format(CWD
)
87 tgen
= Topogen(json_file
, mod
.__name
__)
90 # ... and here it calls Mininet initialization functions.
92 # Starting topology, create tmp files which are loaded to routers
93 # to start daemons and then start routers
96 # Creating configuration from JSON
97 build_config_from_json(tgen
, topo
)
99 # Don't run this test if we have any failure.
100 if tgen
.routers_have_failure():
101 pytest
.skip(tgen
.errors
)
103 # Api call verify whether BGP is converged
104 ADDR_TYPES
= check_address_types()
106 BGP_CONVERGENCE
= verify_bgp_convergence(tgen
, topo
)
107 assert BGP_CONVERGENCE
is True, "setup_module :Failed \n Error:" " {}".format(
111 logger
.info("Running setup_module() done")
114 def teardown_module():
116 Teardown the pytest environment.
121 logger
.info("Running teardown_module to delete topology")
125 # Stop toplogy and Remove tmp files
129 ###########################
131 ###########################
134 def next_hop_per_address_family(
135 tgen
, dut
, peer
, addr_type
, next_hop_dict
, preferred_next_hop
=PREFERRED_NEXT_HOP
138 This function returns link_local or global next_hop per address-family
141 intferface
= topo
["routers"][peer
]["links"]["{}".format(dut
)]["interface"]
142 if addr_type
== "ipv6" and "link_local" in preferred_next_hop
:
143 next_hop
= get_frr_ipv6_linklocal(tgen
, peer
, intf
=intferface
)
145 next_hop
= next_hop_dict
[addr_type
]
150 ###########################
152 ###########################
155 def test_verify_graceful_shutdown_functionality_with_iBGP_peers_p0(request
):
157 Verify graceful-shutdown functionality with iBGP peers
160 tc_name
= request
.node
.name
161 write_test_header(tc_name
)
163 reset_config_on_routers(tgen
)
165 step("Done in base config: Configure base config as per the topology")
166 step("Base config should be up, verify using BGP convergence")
167 result
= verify_bgp_convergence(tgen
, topo
)
168 assert result
is True, "Test case {} : Failed \n Error: {}".format(tc_name
, result
)
170 step("Done in base config: Advertise prefixes from R1")
171 step("Verify BGP routes are received at R4 with best path from R3 to R1")
173 for addr_type
in ADDR_TYPES
:
175 next_hop1
= next_hop_per_address_family(
176 tgen
, "r4", "r2", addr_type
, NEXT_HOP_IP_1
178 next_hop2
= next_hop_per_address_family(
179 tgen
, "r4", "r3", addr_type
, NEXT_HOP_IP_2
182 input_topo
= {key
: topo
["routers"][key
] for key
in ["r1"]}
183 result
= verify_bgp_rib(
184 tgen
, addr_type
, dut
, input_topo
, next_hop
=[next_hop1
, next_hop2
]
186 assert result
is True, "Test case {} : Failed \n Error: {}".format(
191 tgen
, addr_type
, dut
, input_topo
, next_hop
=[next_hop1
, next_hop2
]
193 assert result
is True, "Test case {} : Failed \n Error: {}".format(
197 step("On R1 configure:")
198 step("Create standard bgp community-list to permit graceful-shutdown:")
201 "bgp_community_lists": [
203 "community_type": "standard",
206 "value": "graceful-shutdown",
212 result
= create_bgp_community_lists(tgen
, input_dict_1
)
213 assert result
is True, "Test case {} : Failed \n Error: {}".format(tc_name
, result
)
215 step("Create route-map to set community GSHUT in OUT direction")
224 "set": {"community": {"num": "graceful-shutdown"}},
231 result
= create_route_maps(tgen
, input_dict_2
)
232 assert result
is True, "Test case {} : Failed \n Error: {}".format(tc_name
, result
)
279 result
= create_router_bgp(tgen
, topo
, input_dict_3
)
280 assert result
is True, "Test case {} : Failed \n Error: {}".format(tc_name
, result
)
283 "FRR is setting local-pref to 0 by-default on receiver GSHUT community, "
284 "below step is not needed, but keeping for reference"
287 "On R3, apply route-map IN direction to match GSHUT community "
288 "and set local-preference to 0."
292 "Verify BGP convergence on R4 and ensure all the neighbours state "
296 result
= verify_bgp_convergence(tgen
, topo
)
297 assert result
is True, "Test case {} : Failed \n Error: {}".format(tc_name
, result
)
299 step("Verify BGP routes on R4:")
300 step("local pref for routes coming from R1 is set to 0.")
302 for addr_type
in ADDR_TYPES
:
306 "GSHUT-OUT": [{"set": {"locPrf": 0}}],
311 static_routes
= [NETWORK
[addr_type
]]
312 result
= verify_bgp_attributes(
313 tgen
, addr_type
, dut
, static_routes
, "GSHUT-OUT", rmap_dict
315 assert result
is True, "Test case {} : Failed \n Error: {}".format(
319 step("Ensure that best path is selected from R4 to R3.")
321 for addr_type
in ADDR_TYPES
:
323 next_hop1
= next_hop_per_address_family(
324 tgen
, "r4", "r2", addr_type
, NEXT_HOP_IP_1
326 next_hop2
= next_hop_per_address_family(
327 tgen
, "r4", "r3", addr_type
, NEXT_HOP_IP_2
330 input_topo
= {key
: topo
["routers"][key
] for key
in ["r1"]}
331 result
= verify_bgp_rib(
332 tgen
, addr_type
, dut
, input_topo
, next_hop
=[next_hop1
, next_hop2
]
334 assert result
is True, "Test case {} : Failed \n Error: {}".format(
338 result
= verify_rib(tgen
, addr_type
, dut
, input_topo
, next_hop
=next_hop1
)
339 assert result
is True, "Test case {} : Failed \n Error: {}".format(
343 write_test_footer(tc_name
)
346 def test_verify_deleting_re_adding_route_map_with_iBGP_peers_p0(request
):
348 Verify graceful-shutdown functionality after deleting/re-adding route-map
352 tc_name
= request
.node
.name
353 write_test_header(tc_name
)
355 reset_config_on_routers(tgen
)
357 step("Done in base config: Configure base config as per the topology")
358 step("Base config should be up, verify using BGP convergence")
359 result
= verify_bgp_convergence(tgen
, topo
)
360 assert result
is True, "Test case {} : Failed \n Error: {}".format(tc_name
, result
)
362 step("Done in base config: Advertise prefixes from R1")
363 step("Verify BGP routes are received at R4 with best path from R3 to R1")
365 for addr_type
in ADDR_TYPES
:
367 next_hop1
= next_hop_per_address_family(
368 tgen
, "r4", "r2", addr_type
, NEXT_HOP_IP_1
370 next_hop2
= next_hop_per_address_family(
371 tgen
, "r4", "r3", addr_type
, NEXT_HOP_IP_2
374 input_topo
= {key
: topo
["routers"][key
] for key
in ["r1"]}
375 result
= verify_bgp_rib(
376 tgen
, addr_type
, dut
, input_topo
, next_hop
=[next_hop1
, next_hop2
]
378 assert result
is True, "Test case {} : Failed \n Error: {}".format(
383 tgen
, addr_type
, dut
, input_topo
, next_hop
=[next_hop1
, next_hop2
]
385 assert result
is True, "Test case {} : Failed \n Error: {}".format(
389 step("On R1 configure:")
390 step("Create standard bgp community-list to permit graceful-shutdown:")
393 "bgp_community_lists": [
395 "community_type": "standard",
398 "value": "graceful-shutdown",
404 result
= create_bgp_community_lists(tgen
, input_dict_1
)
405 assert result
is True, "Test case {} : Failed \n Error: {}".format(tc_name
, result
)
407 step("Create route-map to set community GSHUT in OUT direction")
416 "set": {"community": {"num": "graceful-shutdown"}},
423 result
= create_route_maps(tgen
, input_dict_2
)
424 assert result
is True, "Test case {} : Failed \n Error: {}".format(tc_name
, result
)
471 result
= create_router_bgp(tgen
, topo
, input_dict_3
)
472 assert result
is True, "Test case {} : Failed \n Error: {}".format(tc_name
, result
)
475 "FRR is setting local-pref to 0 by-default on receiver GSHUT community, "
476 "below step is not needed, but keeping for reference"
479 "On R3, apply route-map IN direction to match GSHUT community "
480 "and set local-preference to 0."
484 "Verify BGP convergence on R4 and ensure all the neighbours state "
488 result
= verify_bgp_convergence(tgen
, topo
)
489 assert result
is True, "Test case {} : Failed \n Error: {}".format(tc_name
, result
)
491 step("Verify BGP routes on R4:")
492 step("local pref for routes coming from R1 is set to 0.")
494 for addr_type
in ADDR_TYPES
:
498 "GSHUT-OUT": [{"set": {"locPrf": 0}}],
503 static_routes
= [NETWORK
[addr_type
]]
504 result
= verify_bgp_attributes(
505 tgen
, addr_type
, dut
, static_routes
, "GSHUT-OUT", rmap_dict
507 assert result
is True, "Test case {} : Failed \n Error: {}".format(
511 step("Ensure that best path is selected from R4 to R3.")
513 for addr_type
in ADDR_TYPES
:
515 next_hop1
= next_hop_per_address_family(
516 tgen
, "r4", "r2", addr_type
, NEXT_HOP_IP_1
518 next_hop2
= next_hop_per_address_family(
519 tgen
, "r4", "r3", addr_type
, NEXT_HOP_IP_2
522 input_topo
= {key
: topo
["routers"][key
] for key
in ["r1"]}
523 result
= verify_bgp_rib(
524 tgen
, addr_type
, dut
, input_topo
, next_hop
=[next_hop1
, next_hop2
]
526 assert result
is True, "Test case {} : Failed \n Error: {}".format(
530 result
= verify_rib(tgen
, addr_type
, dut
, input_topo
, next_hop
=next_hop1
)
531 assert result
is True, "Test case {} : Failed \n Error: {}".format(
535 step("Delete route-map from R1")
544 "community": {"num": "graceful-shutdown", "delete": True}
552 result
= create_route_maps(tgen
, del_rmap_dict
)
553 assert result
is True, "Test case {} : Failed \n Error: {}".format(tc_name
, result
)
556 "Verify BGP convergence on R3 and ensure that all neighbor state "
559 result
= verify_bgp_convergence(tgen
, topo
)
560 assert result
is True, "Test case {} : Failed \n Error: {}".format(tc_name
, result
)
562 step("Verify BGP routes on R4:")
563 step("Ensure that best path is selected from R1->R3")
565 for addr_type
in ADDR_TYPES
:
567 next_hop1
= next_hop_per_address_family(
568 tgen
, "r4", "r2", addr_type
, NEXT_HOP_IP_1
570 next_hop2
= next_hop_per_address_family(
571 tgen
, "r4", "r3", addr_type
, NEXT_HOP_IP_2
574 input_topo
= {key
: topo
["routers"][key
] for key
in ["r1"]}
575 result
= verify_bgp_rib(tgen
, addr_type
, dut
, input_topo
, next_hop
=[next_hop1
])
576 assert result
is True, "Test case {} : Failed \n Error: {}".format(
580 result
= verify_rib(tgen
, addr_type
, dut
, input_topo
, next_hop
=[next_hop1
])
581 assert result
is True, "Test case {} : Failed \n Error: {}".format(
585 step("Re-add route-map in R1")
586 result
= create_route_maps(tgen
, input_dict_2
)
587 assert result
is True, "Test case {} : Failed \n Error: {}".format(tc_name
, result
)
590 "Verify BGP convergence on R3 and ensure all the neighbours state "
594 result
= verify_bgp_convergence(tgen
, topo
)
595 assert result
is True, "Test case {} : Failed \n Error: {}".format(tc_name
, result
)
597 step("Verify BGP routes on R4:")
598 step("local pref for routes coming from R1 is set to 0.")
600 for addr_type
in ADDR_TYPES
:
601 rmap_dict
= {"r1": {"route_maps": {"GSHUT-OUT": [{"set": {"locPrf": 0}}]}}}
603 static_routes
= [NETWORK
[addr_type
]]
604 result
= verify_bgp_attributes(
605 tgen
, addr_type
, dut
, static_routes
, "GSHUT-OUT", rmap_dict
607 assert result
is True, "Test case {} : Failed \n Error: {}".format(
611 step("Ensure that best path is selected from R4 to R3.")
613 for addr_type
in ADDR_TYPES
:
615 next_hop1
= next_hop_per_address_family(
616 tgen
, "r4", "r2", addr_type
, NEXT_HOP_IP_1
618 next_hop2
= next_hop_per_address_family(
619 tgen
, "r4", "r3", addr_type
, NEXT_HOP_IP_2
622 input_topo
= {key
: topo
["routers"][key
] for key
in ["r1"]}
623 result
= verify_bgp_rib(
624 tgen
, addr_type
, dut
, input_topo
, next_hop
=[next_hop1
, next_hop2
]
626 assert result
is True, "Test case {} : Failed \n Error: {}".format(
630 result
= verify_rib(tgen
, addr_type
, dut
, input_topo
, next_hop
=next_hop1
)
631 assert result
is True, "Test case {} : Failed \n Error: {}".format(
635 write_test_footer(tc_name
)
638 if __name__
== "__main__":
639 args
= ["-s"] + sys
.argv
[1:]
640 sys
.exit(pytest
.main(args
))