4 # Copyright (c) 2021 by VMware, Inc. ("VMware")
5 # Used Copyright (c) 2018 by Network Device Education Foundation, Inc.
6 # ("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
24 """RFC5549 Automation."""
29 from copy
import deepcopy
31 # Save the Current Working Directory to find configuration files.
32 CWD
= os
.path
.dirname(os
.path
.realpath(__file__
))
33 sys
.path
.append(os
.path
.join(CWD
, "../"))
34 sys
.path
.append(os
.path
.join(CWD
, "../../"))
36 # pylint: disable=C0413
37 # Import topogen and topotest helpers
38 from lib
.topogen
import Topogen
, get_topogen
40 from lib
.common_config
import (
43 get_frr_ipv6_linklocal
,
48 reset_config_on_routers
,
51 from lib
.topolog
import logger
53 verify_bgp_convergence
,
57 from lib
.topojson
import build_config_from_json
71 "ipv6": ["1::1/128", "1::2/128", "1::3/128", "1::4/128", "1::5/128"],
73 MASK
= {"ipv4": "32", "ipv6": "128"}
75 "ipv4": ["10.0.0.1", "10.0.1.1", "10.0.2.1", "10.0.3.1", "10.0.4.1"],
76 "ipv6": ["Null0", "Null0", "Null0", "Null0", "Null0"],
79 NETWORK_CMD_IP
= "1.0.1.17/32"
80 ADDR_TYPES
= check_address_types()
82 Please view in a fixed-width font such as Courier.
91 +----+ 5links +----+ 8links +--+-+ +----+
92 |R0 +----------+ R1 +------------+ R2 | ipv6 nbr |R3 |
93 | +----------+ +------------+ +-------------+ |
94 +----+ +----+ ipv6 nbr +----+ +----+
98 1. Verify Ipv4 route next hop is changed when advertised using
99 next hop -self command
100 2. Verify IPv4 route advertised to peer when IPv6 BGP session established
102 3. Verify IPv4 routes received with IPv6 nexthop are getting advertised
103 to another IBGP peer without changing the nexthop
104 4. Verify IPv4 routes advertised with correct nexthop when nexthop
105 unchange is configure on EBGP peers
109 def setup_module(mod
):
110 """Set up the pytest environment."""
113 testsuite_run_time
= time
.asctime(time
.localtime(time
.time()))
114 logger
.info("Testsuite start time: {}".format(testsuite_run_time
))
115 logger
.info("=" * 40)
117 logger
.info("Running setup_module to create topology")
119 # This function initiates the topology build with Topogen...
120 json_file
= "{}/rfc5549_ebgp_ibgp_nbr.json".format(CWD
)
121 tgen
= Topogen(json_file
, mod
.__name
__)
123 topo
= tgen
.json_topo
125 # Starting topology, create tmp files which are loaded to routers
126 # to start deamons and then start routers
129 # Creating configuration from JSON
130 build_config_from_json(tgen
, topo
)
131 # Don't run this test if we have any failure.
132 if tgen
.routers_have_failure():
133 pytest
.skip(tgen
.errors
)
135 BGP_CONVERGENCE
= verify_bgp_convergence(tgen
, topo
)
136 assert BGP_CONVERGENCE
is True, "setup_module :Failed \n Error:" " {}".format(
139 logger
.info("Running setup_module() done")
142 def teardown_module():
144 Teardown the pytest environment.
148 logger
.info("Running teardown_module to delete topology")
152 # Stop toplogy and Remove tmp files
156 def get_llip(onrouter
, intf
):
158 API to get the link local ipv6 address of a perticular interface
162 * `fromnode`: Source node
163 * `tonode` : interface for which link local ip needs to be returned.
167 result = get_llip('r1', 'r2-link0')
171 1) link local ipv6 address from the interface.
172 2) errormsg - when link local ip not found.
175 intf
= topo
["routers"][onrouter
]["links"][intf
]["interface"]
176 llip
= get_frr_ipv6_linklocal(tgen
, onrouter
, intf
)
178 logger
.info("llip ipv6 address to be set as NH is %s", llip
)
183 def get_glipv6(onrouter
, intf
):
185 API to get the global ipv6 address of a perticular interface
189 * `onrouter`: Source node
190 * `intf` : interface for which link local ip needs to be returned.
194 result = get_glipv6('r1', 'r2-link0')
198 1) global ipv6 address from the interface.
199 2) errormsg - when link local ip not found.
201 glipv6
= (topo
["routers"][onrouter
]["links"][intf
]["ipv6"]).split("/")[0]
203 logger
.info("Global ipv6 address to be set as NH is %s", glipv6
)
208 # ##################################
209 # Test cases start here.
210 # ##################################
211 def test_ibgp_to_ibgp_p1(request
):
214 Test Capability extended nexthop.
216 Verify IPv4 routes received with IPv6 nexthop are getting advertised to
217 another IBGP peer without changing the nexthop
219 tc_name
= request
.node
.name
220 write_test_header(tc_name
)
222 # Don't run this test if we have any failure.
223 if tgen
.routers_have_failure():
224 pytest
.skip(tgen
.errors
)
225 reset_config_on_routers(tgen
)
227 topo23
= deepcopy(topo
)
228 build_config_from_json(tgen
, topo23
, save_bkup
=False)
230 step("Configure IPv6 EBGP session between R1 and R2 with " "global IPv6 address")
231 step("Configure IPv6 IBGP session betn R2 & R3 using IPv6 global address")
232 step("Enable capability extended-nexthop on both the IPv6 BGP peers")
233 step("Activate same IPv6 nbr from IPv4 unicast family")
234 step("Enable cap ext nh on r1 and r2 and activate in ipv4 addr family")
235 step("Verify bgp convergence as ipv6 nbr is enabled on ipv4 addr family.")
237 # verify bgp convergence as ipv6 nbr is enabled on ipv4 addr family.
238 bgp_convergence
= verify_bgp_convergence(tgen
, topo23
)
239 assert bgp_convergence
is True, "Testcase :Failed \n Error:" " {}".format(
243 step(" Configure 5 IPv4 static" " routes on R1, Nexthop as different links of R0")
244 for rte
in range(0, NO_OF_RTES
):
245 # Create Static routes
250 "network": NETWORK
["ipv4"][rte
],
252 "next_hop": NEXT_HOP
["ipv4"][rte
],
257 result
= create_static_routes(tgen
, input_dict
)
258 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
263 "Advertise static routes from IPv4 unicast family and IPv6 "
264 "unicast family respectively from R1 using red static cmd "
265 "Advertise loopback from IPv4 unicast family using network command "
269 configure_bgp_on_r1
= {
275 "redistribute": [{"redist_type": "static"}],
276 "advertise_networks": [
277 {"network": NETWORK_CMD_IP
, "no_of_network": 1}
285 result
= create_router_bgp(tgen
, topo23
, configure_bgp_on_r1
)
286 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
288 "IPv4 routes advertised using static and network command are "
289 " received on R2 BGP and routing table , "
290 "verify using show ip bgp, show ip route for IPv4 routes ."
293 gllip
= get_llip("r1", "r2-link0")
294 assert gllip
is not None, "Testcase {} : Failed \n Error: {}".format(
300 # verify the routes with nh as ext_nh
301 verify_nh_for_static_rtes
= {
305 "network": NETWORK
["ipv4"][0],
306 "no_of_ip": NO_OF_RTES
,
312 bgp_rib
= verify_bgp_rib(
313 tgen
, "ipv4", dut
, verify_nh_for_static_rtes
, next_hop
=gllip
315 assert bgp_rib
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, bgp_rib
)
317 tgen
, "ipv4", dut
, verify_nh_for_static_rtes
, next_hop
=gllip
, protocol
=protocol
319 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
321 configure_bgp_on_r2
= {
332 "capability": "extended-nexthop",
343 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r2
)
344 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
346 configure_bgp_on_r3
= {
357 "capability": "extended-nexthop",
368 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r3
)
369 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
372 "IPv4 routes installed on R3 with global address without "
373 "changing the nexthop ( nexthop should IPv6 link local which is"
376 gipv6
= get_glipv6("r1", "r2-link0")
378 verify_nh_for_static_rtes
= {
382 "network": NETWORK
["ipv4"][0],
383 "no_of_ip": NO_OF_RTES
,
389 bgp_rib
= verify_bgp_rib(
390 tgen
, "ipv4", dut
, verify_nh_for_static_rtes
, next_hop
=gipv6
392 assert bgp_rib
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, bgp_rib
)
393 write_test_footer(tc_name
)
396 def test_ext_nh_cap_red_static_network_ibgp_peer_p1(request
):
399 Test Extended capability next hop, with ibgp peer.
401 Verify IPv4 routes advertise using "redistribute static" and
402 "network command" are received on EBGP peer with IPv6 nexthop
404 tc_name
= request
.node
.name
405 write_test_header(tc_name
)
407 # Don't run this test if we have any failure.
408 if tgen
.routers_have_failure():
409 pytest
.skip(tgen
.errors
)
410 reset_config_on_routers(tgen
)
412 " Configure IPv6 EBGP session between R1 & R2 with global IPv6 address"
413 " Enable capability extended-nexthop on the nbr from both the routers"
414 " Activate same IPv6 nbr from IPv4 unicast family"
416 configure_bgp_on_r2
= {
419 "default_ipv4_unicast": "False",
427 "capability": "extended-nexthop",
429 "next_hop_self": True,
441 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r2
)
442 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
444 configure_bgp_on_r3
= {
454 "capability": "extended-nexthop",
466 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r3
)
467 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
468 for rte
in range(0, NO_OF_RTES
):
469 # Create Static routes
474 "network": NETWORK
["ipv4"][rte
],
476 "next_hop": NEXT_HOP
["ipv4"][rte
],
481 result
= create_static_routes(tgen
, input_dict
)
482 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
486 configure_bgp_on_r1
= {
489 "default_ipv4_unicast": "False",
493 "redistribute": [{"redist_type": "static"}],
494 "advertise_networks": [
495 {"network": NETWORK_CMD_IP
, "no_of_network": 1}
503 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r1
)
504 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
506 gllip
= get_llip("r1", "r2-link0")
507 assert gllip
is not None, "Testcase {} : Failed \n Error: {}".format(
513 verify_nh_for_static_rtes
= {
517 "network": NETWORK
["ipv4"][0],
518 "no_of_ip": NO_OF_RTES
,
525 tgen
, "ipv4", dut
, verify_nh_for_static_rtes
, next_hop
=gllip
, protocol
=protocol
527 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
529 verify_nh_for_nw_cmd_rtes
= {
533 "network": NETWORK_CMD_IP
,
542 tgen
, "ipv4", dut
, verify_nh_for_nw_cmd_rtes
, next_hop
=gllip
, protocol
=protocol
544 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
546 gllip
= get_glipv6("r2", "r3")
547 assert gllip
is not None, "Testcase {} : Failed \n Error: {}".format(
553 # verify the routes with nh as ext_nh
554 verify_nh_for_static_rtes
= {
558 "network": NETWORK
["ipv4"][0],
559 "no_of_ip": NO_OF_RTES
,
566 tgen
, "ipv4", dut
, verify_nh_for_static_rtes
, next_hop
=gllip
, protocol
=protocol
568 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
569 verify_nh_for_nw_cmd_rtes
= {
573 "network": NETWORK_CMD_IP
,
580 bgp_rib
= verify_bgp_rib(
581 tgen
, "ipv4", dut
, verify_nh_for_nw_cmd_rtes
, next_hop
=gllip
583 assert bgp_rib
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, bgp_rib
)
585 tgen
, "ipv4", dut
, verify_nh_for_nw_cmd_rtes
, next_hop
=gllip
, protocol
=protocol
587 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
589 write_test_footer(tc_name
)
592 def test_bgp_peer_group_p1(request
):
594 Test extended capability next hop with peer groups.
596 Verify IPv4 routes received with IPv6 nexthop are getting advertised to
597 another IBGP peer without changing the nexthop
599 tc_name
= request
.node
.name
600 write_test_header(tc_name
)
602 # Don't run this test if we have any failure.
603 if tgen
.routers_have_failure():
604 pytest
.skip(tgen
.errors
)
605 reset_config_on_routers(tgen
)
607 topo1
= deepcopy(topo
)
608 step("Configure IPv6 EBGP session between R1 and R2 with " "global IPv6 address")
609 step("Configure IPv6 IBGP session betn R2 & R3 using IPv6 global address")
610 step("Enable capability extended-nexthop on both the IPv6 BGP peers")
611 step("Activate same IPv6 nbr from IPv4 unicast family")
612 step("Enable cap ext nh on r1 and r2 and activate in ipv4 addr family")
613 configure_bgp_on_r1
= {
616 "default_ipv4_unicast": "False",
618 "rfc5549": {"capability": "extended-nexthop", "remote-as": "200"}
623 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r1
)
624 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
625 configure_bgp_on_r1
= {
636 "capability": "extended-nexthop",
637 "peer-group": "rfc5549",
648 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r1
)
649 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
650 configure_bgp_on_r2
= {
653 "default_ipv4_unicast": "False",
655 "rfc5549": {"capability": "extended-nexthop", "remote-as": "100"}
660 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r2
)
661 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
662 configure_bgp_on_r2
= {
672 "capability": "extended-nexthop",
674 "peer-group": "rfc5549",
678 "r3": {"dest_link": {"r2": {}}},
686 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r2
)
687 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
689 configure_bgp_on_r3
= {
693 "ipv4": {"unicast": {"neighbor": {"r2": {"dest_link": {"r3": {}}}}}}
698 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r3
)
699 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
701 step("Verify bgp convergence as ipv6 nbr is enabled on ipv4 addr family.")
702 bgp_convergence
= verify_bgp_convergence(tgen
, topo
)
703 assert bgp_convergence
is True, "Testcase :Failed \n Error:" " {}".format(
707 step(" Configure 2 IPv4 static" " routes on R1, Nexthop as different links of R0")
708 for rte
in range(0, NO_OF_RTES
):
709 # Create Static routes
714 "network": NETWORK
["ipv4"][rte
],
716 "next_hop": NEXT_HOP
["ipv4"][rte
],
721 result
= create_static_routes(tgen
, input_dict
)
722 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
727 "Advertise static routes from IPv4 unicast family and IPv6 "
728 "unicast family respectively from R1 using red static cmd "
729 "Advertise loopback from IPv4 unicast family using network command "
733 configure_bgp_on_r1
= {
739 "redistribute": [{"redist_type": "static"}],
740 "advertise_networks": [
741 {"network": NETWORK_CMD_IP
, "no_of_network": 1}
749 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r1
)
750 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
752 "IPv4 routes advertised using static and network command are "
753 " received on R2 BGP and routing table , "
754 "verify using show ip bgp, show ip route for IPv4 routes ."
757 gllip
= get_llip("r1", "r2-link0")
758 assert gllip
is not None, "Testcase {} : Failed \n Error: {}".format(
764 verify_nh_for_static_rtes
= {
768 "network": NETWORK
["ipv4"][0],
769 "no_of_ip": NO_OF_RTES
,
775 bgp_rib
= verify_bgp_rib(
776 tgen
, "ipv4", dut
, verify_nh_for_static_rtes
, next_hop
=gllip
778 assert bgp_rib
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, bgp_rib
)
780 tgen
, "ipv4", dut
, verify_nh_for_static_rtes
, next_hop
=gllip
, protocol
=protocol
782 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
784 step("Enable cap ext nh on r1 and r2 and activate in ipv4 addr family")
785 configure_bgp_on_r1
= {
788 "default_ipv4_unicast": "False",
790 "rfc5549": {"capability": "extended-nexthop", "remote-as": "200"}
795 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r1
)
796 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
797 configure_bgp_on_r1
= {
808 "capability": "extended-nexthop",
809 "peer-group": "rfc5549",
820 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r1
)
821 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
822 configure_bgp_on_r2
= {
825 "default_ipv4_unicast": "False",
827 "rfc5549": {"capability": "extended-nexthop", "remote-as": "100"}
832 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r2
)
833 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
834 configure_bgp_on_r2
= {
844 "capability": "extended-nexthop",
846 "peer-group": "rfc5549",
850 "r3": {"dest_link": {"r2": {}}},
858 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r2
)
859 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
861 configure_bgp_on_r3
= {
865 "ipv4": {"unicast": {"neighbor": {"r2": {"dest_link": {"r3": {}}}}}}
870 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r3
)
871 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
873 step("Verify bgp convergence as ipv6 nbr is enabled on ipv4 addr family.")
874 bgp_convergence
= verify_bgp_convergence(tgen
, topo
)
875 assert bgp_convergence
is True, "Testcase :Failed \n Error:" " {}".format(
879 step(" Configure 2 IPv4 static" " routes on R1, Nexthop as different links of R0")
880 for rte
in range(0, NO_OF_RTES
):
885 "network": NETWORK
["ipv4"][rte
],
887 "next_hop": NEXT_HOP
["ipv4"][rte
],
892 result
= create_static_routes(tgen
, input_dict
)
893 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
898 "Advertise static routes from IPv4 unicast family and IPv6 "
899 "unicast family respectively from R1 using red static cmd "
900 "Advertise loopback from IPv4 unicast family using network command "
904 configure_bgp_on_r1
= {
910 "redistribute": [{"redist_type": "static"}],
911 "advertise_networks": [
912 {"network": NETWORK_CMD_IP
, "no_of_network": 1}
920 result
= create_router_bgp(tgen
, topo
, configure_bgp_on_r1
)
921 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
923 "IPv4 routes advertised using static and network command are "
924 " received on R2 BGP and routing table , "
925 "verify using show ip bgp, show ip route for IPv4 routes ."
928 gllip
= get_llip("r1", "r2-link0")
929 assert gllip
is not None, "Testcase {} : Failed \n Error: {}".format(
935 verify_nh_for_static_rtes
= {
939 "network": NETWORK
["ipv4"][0],
940 "no_of_ip": NO_OF_RTES
,
946 bgp_rib
= verify_bgp_rib(
947 tgen
, "ipv4", dut
, verify_nh_for_static_rtes
, next_hop
=gllip
949 assert bgp_rib
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, bgp_rib
)
951 tgen
, "ipv4", dut
, verify_nh_for_static_rtes
, next_hop
=gllip
, protocol
=protocol
953 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
955 write_test_footer(tc_name
)
958 if __name__
== "__main__":
959 args
= ["-s"] + sys
.argv
[1:]
960 sys
.exit(pytest
.main(args
))