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.
11 """RFC5549 Automation."""
16 from copy
import deepcopy
18 # Save the Current Working Directory to find configuration files.
19 CWD
= os
.path
.dirname(os
.path
.realpath(__file__
))
20 sys
.path
.append(os
.path
.join(CWD
, "../"))
21 sys
.path
.append(os
.path
.join(CWD
, "../../"))
23 # pylint: disable=C0413
24 # Import topogen and topotest helpers
25 from lib
.topogen
import Topogen
, get_topogen
27 from lib
.common_config
import (
30 get_frr_ipv6_linklocal
,
35 reset_config_on_routers
,
38 from lib
.topolog
import logger
40 verify_bgp_convergence
,
44 from lib
.topojson
import build_config_from_json
47 pytestmark
= [pytest
.mark
.bgpd
, pytest
.mark
.staticd
]
61 "ipv6": ["1::1/128", "1::2/128", "1::3/128", "1::4/128", "1::5/128"],
63 MASK
= {"ipv4": "32", "ipv6": "128"}
65 "ipv4": ["10.0.0.1", "10.0.1.1", "10.0.2.1", "10.0.3.1", "10.0.4.1"],
66 "ipv6": ["Null0", "Null0", "Null0", "Null0", "Null0"],
69 NETWORK_CMD_IP
= "1.0.1.17/32"
70 ADDR_TYPES
= check_address_types()
72 Please view in a fixed-width font such as Courier.
81 +----+ 5links +----+ 8links +--+-+ +----+
82 |R0 +----------+ R1 +------------+ R2 | ipv6 nbr |R3 |
83 | +----------+ +------------+ +-------------+ |
84 +----+ +----+ ipv6 nbr +----+ +----+
88 1. Verify Ipv4 route next hop is changed when advertised using
89 next hop -self command
90 2. Verify IPv4 route advertised to peer when IPv6 BGP session established
92 3. Verify IPv4 routes received with IPv6 nexthop are getting advertised
93 to another IBGP peer without changing the nexthop
94 4. Verify IPv4 routes advertised with correct nexthop when nexthop
95 unchange is configure on EBGP peers
99 def setup_module(mod
):
100 """Set up the pytest environment."""
103 testsuite_run_time
= time
.asctime(time
.localtime(time
.time()))
104 logger
.info("Testsuite start time: {}".format(testsuite_run_time
))
105 logger
.info("=" * 40)
107 logger
.info("Running setup_module to create topology")
109 # This function initiates the topology build with Topogen...
110 json_file
= "{}/rfc5549_ebgp_ibgp_nbr.json".format(CWD
)
111 tgen
= Topogen(json_file
, mod
.__name
__)
113 topo
= tgen
.json_topo
115 # Starting topology, create tmp files which are loaded to routers
116 # to start daemons and then start routers
119 # Creating configuration from JSON
120 build_config_from_json(tgen
, topo
)
121 # Don't run this test if we have any failure.
122 if tgen
.routers_have_failure():
123 pytest
.skip(tgen
.errors
)
125 BGP_CONVERGENCE
= verify_bgp_convergence(tgen
, topo
)
126 assert BGP_CONVERGENCE
is True, "setup_module :Failed \n Error:" " {}".format(
129 logger
.info("Running setup_module() done")
132 def teardown_module():
134 Teardown the pytest environment.
138 logger
.info("Running teardown_module to delete topology")
142 # Stop toplogy and Remove tmp files
146 def get_llip(onrouter
, intf
):
148 API to get the link local ipv6 address of a particular interface
152 * `fromnode`: Source node
153 * `tonode` : interface for which link local ip needs to be returned.
157 result = get_llip('r1', 'r2-link0')
161 1) link local ipv6 address from the interface.
162 2) errormsg - when link local ip not found.
165 intf
= topo
["routers"][onrouter
]["links"][intf
]["interface"]
166 llip
= get_frr_ipv6_linklocal(tgen
, onrouter
, intf
)
168 logger
.info("llip ipv6 address to be set as NH is %s", llip
)
173 def get_glipv6(onrouter
, intf
):
175 API to get the global ipv6 address of a particular interface
179 * `onrouter`: Source node
180 * `intf` : interface for which link local ip needs to be returned.
184 result = get_glipv6('r1', 'r2-link0')
188 1) global ipv6 address from the interface.
189 2) errormsg - when link local ip not found.
191 glipv6
= (topo
["routers"][onrouter
]["links"][intf
]["ipv6"]).split("/")[0]
193 logger
.info("Global ipv6 address to be set as NH is %s", glipv6
)
198 # ##################################
199 # Test cases start here.
200 # ##################################
201 def test_ibgp_to_ibgp_p1(request
):
204 Test Capability extended nexthop.
206 Verify IPv4 routes received with IPv6 nexthop are getting advertised to
207 another IBGP peer without changing the nexthop
209 tc_name
= request
.node
.name
210 write_test_header(tc_name
)
212 # Don't run this test if we have any failure.
213 if tgen
.routers_have_failure():
214 pytest
.skip(tgen
.errors
)
215 reset_config_on_routers(tgen
)
217 topo23
= deepcopy(topo
)
218 build_config_from_json(tgen
, topo23
, save_bkup
=False)
220 step("Configure IPv6 EBGP session between R1 and R2 with " "global IPv6 address")
221 step("Configure IPv6 IBGP session betn R2 & R3 using IPv6 global address")
222 step("Enable capability extended-nexthop on both the IPv6 BGP peers")
223 step("Activate same IPv6 nbr from IPv4 unicast family")
224 step("Enable cap ext nh on r1 and r2 and activate in ipv4 addr family")
225 step("Verify bgp convergence as ipv6 nbr is enabled on ipv4 addr family.")
227 # verify bgp convergence as ipv6 nbr is enabled on ipv4 addr family.
228 bgp_convergence
= verify_bgp_convergence(tgen
, topo23
)
229 assert bgp_convergence
is True, "Testcase :Failed \n Error:" " {}".format(
233 step(" Configure 5 IPv4 static" " routes on R1, Nexthop as different links of R0")
234 for rte
in range(0, NO_OF_RTES
):
235 # Create Static routes
240 "network": NETWORK
["ipv4"][rte
],
242 "next_hop": NEXT_HOP
["ipv4"][rte
],
247 result
= create_static_routes(tgen
, input_dict
)
248 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
253 "Advertise static routes from IPv4 unicast family and IPv6 "
254 "unicast family respectively from R1 using red static cmd "
255 "Advertise loopback from IPv4 unicast family using network command "
259 configure_bgp_on_r1
= {
265 "redistribute": [{"redist_type": "static"}],
266 "advertise_networks": [
267 {"network": NETWORK_CMD_IP
, "no_of_network": 1}
275 result
= create_router_bgp(tgen
, topo23
, configure_bgp_on_r1
)
276 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
278 "IPv4 routes advertised using static and network command are "
279 " received on R2 BGP and routing table , "
280 "verify using show ip bgp, show ip route for IPv4 routes ."
283 gllip
= get_llip("r1", "r2-link0")
284 assert gllip
is not None, "Testcase {} : Failed \n Error: {}".format(
290 # verify the routes with nh as ext_nh
291 verify_nh_for_static_rtes
= {
295 "network": NETWORK
["ipv4"][0],
296 "no_of_ip": NO_OF_RTES
,
302 bgp_rib
= verify_bgp_rib(
303 tgen
, "ipv4", dut
, verify_nh_for_static_rtes
, next_hop
=gllip
305 assert bgp_rib
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, bgp_rib
)
307 tgen
, "ipv4", dut
, verify_nh_for_static_rtes
, next_hop
=gllip
, protocol
=protocol
309 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
311 configure_bgp_on_r2
= {
322 "capability": "extended-nexthop",
333 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r2
)
334 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
336 configure_bgp_on_r3
= {
347 "capability": "extended-nexthop",
358 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r3
)
359 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
362 "IPv4 routes installed on R3 with global address without "
363 "changing the nexthop ( nexthop should IPv6 link local which is"
366 gipv6
= get_glipv6("r1", "r2-link0")
368 verify_nh_for_static_rtes
= {
372 "network": NETWORK
["ipv4"][0],
373 "no_of_ip": NO_OF_RTES
,
379 bgp_rib
= verify_bgp_rib(
380 tgen
, "ipv4", dut
, verify_nh_for_static_rtes
, next_hop
=gipv6
382 assert bgp_rib
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, bgp_rib
)
383 write_test_footer(tc_name
)
386 def test_ext_nh_cap_red_static_network_ibgp_peer_p1(request
):
389 Test Extended capability next hop, with ibgp peer.
391 Verify IPv4 routes advertise using "redistribute static" and
392 "network command" are received on EBGP peer with IPv6 nexthop
394 tc_name
= request
.node
.name
395 write_test_header(tc_name
)
397 # Don't run this test if we have any failure.
398 if tgen
.routers_have_failure():
399 pytest
.skip(tgen
.errors
)
400 reset_config_on_routers(tgen
)
402 " Configure IPv6 EBGP session between R1 & R2 with global IPv6 address"
403 " Enable capability extended-nexthop on the nbr from both the routers"
404 " Activate same IPv6 nbr from IPv4 unicast family"
406 configure_bgp_on_r2
= {
409 "default_ipv4_unicast": "False",
417 "capability": "extended-nexthop",
419 "next_hop_self": True,
431 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r2
)
432 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
434 configure_bgp_on_r3
= {
444 "capability": "extended-nexthop",
456 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r3
)
457 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
458 for rte
in range(0, NO_OF_RTES
):
459 # Create Static routes
464 "network": NETWORK
["ipv4"][rte
],
466 "next_hop": NEXT_HOP
["ipv4"][rte
],
471 result
= create_static_routes(tgen
, input_dict
)
472 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
476 configure_bgp_on_r1
= {
479 "default_ipv4_unicast": "False",
483 "redistribute": [{"redist_type": "static"}],
484 "advertise_networks": [
485 {"network": NETWORK_CMD_IP
, "no_of_network": 1}
493 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r1
)
494 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
496 gllip
= get_llip("r1", "r2-link0")
497 assert gllip
is not None, "Testcase {} : Failed \n Error: {}".format(
503 verify_nh_for_static_rtes
= {
507 "network": NETWORK
["ipv4"][0],
508 "no_of_ip": NO_OF_RTES
,
515 tgen
, "ipv4", dut
, verify_nh_for_static_rtes
, next_hop
=gllip
, protocol
=protocol
517 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
519 verify_nh_for_nw_cmd_rtes
= {
523 "network": NETWORK_CMD_IP
,
532 tgen
, "ipv4", dut
, verify_nh_for_nw_cmd_rtes
, next_hop
=gllip
, protocol
=protocol
534 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
536 gllip
= get_glipv6("r2", "r3")
537 assert gllip
is not None, "Testcase {} : Failed \n Error: {}".format(
543 # verify the routes with nh as ext_nh
544 verify_nh_for_static_rtes
= {
548 "network": NETWORK
["ipv4"][0],
549 "no_of_ip": NO_OF_RTES
,
556 tgen
, "ipv4", dut
, verify_nh_for_static_rtes
, next_hop
=gllip
, protocol
=protocol
558 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
559 verify_nh_for_nw_cmd_rtes
= {
563 "network": NETWORK_CMD_IP
,
570 bgp_rib
= verify_bgp_rib(
571 tgen
, "ipv4", dut
, verify_nh_for_nw_cmd_rtes
, next_hop
=gllip
573 assert bgp_rib
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, bgp_rib
)
575 tgen
, "ipv4", dut
, verify_nh_for_nw_cmd_rtes
, next_hop
=gllip
, protocol
=protocol
577 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
579 write_test_footer(tc_name
)
582 def test_bgp_peer_group_p1(request
):
584 Test extended capability next hop with peer groups.
586 Verify IPv4 routes received with IPv6 nexthop are getting advertised to
587 another IBGP peer without changing the nexthop
589 tc_name
= request
.node
.name
590 write_test_header(tc_name
)
592 # Don't run this test if we have any failure.
593 if tgen
.routers_have_failure():
594 pytest
.skip(tgen
.errors
)
595 reset_config_on_routers(tgen
)
597 topo1
= deepcopy(topo
)
598 step("Configure IPv6 EBGP session between R1 and R2 with " "global IPv6 address")
599 step("Configure IPv6 IBGP session betn R2 & R3 using IPv6 global address")
600 step("Enable capability extended-nexthop on both the IPv6 BGP peers")
601 step("Activate same IPv6 nbr from IPv4 unicast family")
602 step("Enable cap ext nh on r1 and r2 and activate in ipv4 addr family")
603 configure_bgp_on_r1
= {
606 "default_ipv4_unicast": "False",
608 "rfc5549": {"capability": "extended-nexthop", "remote-as": "200"}
613 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r1
)
614 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
615 configure_bgp_on_r1
= {
626 "capability": "extended-nexthop",
627 "peer-group": "rfc5549",
638 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r1
)
639 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
640 configure_bgp_on_r2
= {
643 "default_ipv4_unicast": "False",
645 "rfc5549": {"capability": "extended-nexthop", "remote-as": "100"}
650 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r2
)
651 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
652 configure_bgp_on_r2
= {
662 "capability": "extended-nexthop",
664 "peer-group": "rfc5549",
668 "r3": {"dest_link": {"r2": {}}},
676 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r2
)
677 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
679 configure_bgp_on_r3
= {
683 "ipv4": {"unicast": {"neighbor": {"r2": {"dest_link": {"r3": {}}}}}}
688 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r3
)
689 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
691 step("Verify bgp convergence as ipv6 nbr is enabled on ipv4 addr family.")
692 bgp_convergence
= verify_bgp_convergence(tgen
, topo
)
693 assert bgp_convergence
is True, "Testcase :Failed \n Error:" " {}".format(
697 step(" Configure 2 IPv4 static" " routes on R1, Nexthop as different links of R0")
698 for rte
in range(0, NO_OF_RTES
):
699 # Create Static routes
704 "network": NETWORK
["ipv4"][rte
],
706 "next_hop": NEXT_HOP
["ipv4"][rte
],
711 result
= create_static_routes(tgen
, input_dict
)
712 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
717 "Advertise static routes from IPv4 unicast family and IPv6 "
718 "unicast family respectively from R1 using red static cmd "
719 "Advertise loopback from IPv4 unicast family using network command "
723 configure_bgp_on_r1
= {
729 "redistribute": [{"redist_type": "static"}],
730 "advertise_networks": [
731 {"network": NETWORK_CMD_IP
, "no_of_network": 1}
739 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r1
)
740 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
742 "IPv4 routes advertised using static and network command are "
743 " received on R2 BGP and routing table , "
744 "verify using show ip bgp, show ip route for IPv4 routes ."
747 gllip
= get_llip("r1", "r2-link0")
748 assert gllip
is not None, "Testcase {} : Failed \n Error: {}".format(
754 verify_nh_for_static_rtes
= {
758 "network": NETWORK
["ipv4"][0],
759 "no_of_ip": NO_OF_RTES
,
765 bgp_rib
= verify_bgp_rib(
766 tgen
, "ipv4", dut
, verify_nh_for_static_rtes
, next_hop
=gllip
768 assert bgp_rib
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, bgp_rib
)
770 tgen
, "ipv4", dut
, verify_nh_for_static_rtes
, next_hop
=gllip
, protocol
=protocol
772 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
774 step("Enable cap ext nh on r1 and r2 and activate in ipv4 addr family")
775 configure_bgp_on_r1
= {
778 "default_ipv4_unicast": "False",
780 "rfc5549": {"capability": "extended-nexthop", "remote-as": "200"}
785 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r1
)
786 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
787 configure_bgp_on_r1
= {
798 "capability": "extended-nexthop",
799 "peer-group": "rfc5549",
810 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r1
)
811 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
812 configure_bgp_on_r2
= {
815 "default_ipv4_unicast": "False",
817 "rfc5549": {"capability": "extended-nexthop", "remote-as": "100"}
822 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r2
)
823 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
824 configure_bgp_on_r2
= {
834 "capability": "extended-nexthop",
836 "peer-group": "rfc5549",
840 "r3": {"dest_link": {"r2": {}}},
848 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r2
)
849 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
851 configure_bgp_on_r3
= {
855 "ipv4": {"unicast": {"neighbor": {"r2": {"dest_link": {"r3": {}}}}}}
860 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r3
)
861 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
863 step("Verify bgp convergence as ipv6 nbr is enabled on ipv4 addr family.")
864 bgp_convergence
= verify_bgp_convergence(tgen
, topo
)
865 assert bgp_convergence
is True, "Testcase :Failed \n Error:" " {}".format(
869 step(" Configure 2 IPv4 static" " routes on R1, Nexthop as different links of R0")
870 for rte
in range(0, NO_OF_RTES
):
875 "network": NETWORK
["ipv4"][rte
],
877 "next_hop": NEXT_HOP
["ipv4"][rte
],
882 result
= create_static_routes(tgen
, input_dict
)
883 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
888 "Advertise static routes from IPv4 unicast family and IPv6 "
889 "unicast family respectively from R1 using red static cmd "
890 "Advertise loopback from IPv4 unicast family using network command "
894 configure_bgp_on_r1
= {
900 "redistribute": [{"redist_type": "static"}],
901 "advertise_networks": [
902 {"network": NETWORK_CMD_IP
, "no_of_network": 1}
910 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r1
)
911 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
913 "IPv4 routes advertised using static and network command are "
914 " received on R2 BGP and routing table , "
915 "verify using show ip bgp, show ip route for IPv4 routes ."
918 gllip
= get_llip("r1", "r2-link0")
919 assert gllip
is not None, "Testcase {} : Failed \n Error: {}".format(
925 verify_nh_for_static_rtes
= {
929 "network": NETWORK
["ipv4"][0],
930 "no_of_ip": NO_OF_RTES
,
936 bgp_rib
= verify_bgp_rib(
937 tgen
, "ipv4", dut
, verify_nh_for_static_rtes
, next_hop
=gllip
939 assert bgp_rib
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, bgp_rib
)
941 tgen
, "ipv4", dut
, verify_nh_for_static_rtes
, next_hop
=gllip
, protocol
=protocol
943 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
945 write_test_footer(tc_name
)
948 if __name__
== "__main__":
949 args
= ["-s"] + sys
.argv
[1:]
950 sys
.exit(pytest
.main(args
))