4 # Copyright (c) 2020 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
24 Following tests are covered to test EVPN-Type5 functionality:
26 1. RD verification (manual/auto).
27 2. RT verification(manual)
28 3. In an active/standby EVPN implementation, if active DCG goes down,
30 4. EVPN routes are advertised/withdrawn, based on VNFs
31 advertising/withdrawing IP prefixes.
32 5. Route-map operations for EVPN address family.
33 6. BGP attributes for EVPN address-family.
43 from copy
import deepcopy
44 from time
import sleep
47 # Save the Current Working Directory to find configuration files.
48 CWD
= os
.path
.dirname(os
.path
.realpath(__file__
))
49 sys
.path
.append(os
.path
.join(CWD
, "../"))
50 sys
.path
.append(os
.path
.join(CWD
, "../lib/"))
52 # Required to instantiate the topology builder class.
54 # pylint: disable=C0413
55 # Import topogen and topotest helpers
56 from lib
.topotest
import version_cmp
57 from lib
.topogen
import Topogen
, get_topogen
58 from mininet
.topo
import Topo
60 from lib
.common_config
import (
65 reset_config_on_routers
,
80 create_interface_in_kernel
83 from lib
.topolog
import logger
85 verify_bgp_convergence
,
88 verify_best_path_as_per_bgp_attribute
,
89 verify_attributes_for_evpn_routes
,
92 from lib
.topojson
import build_topo_from_json
, build_config_from_json
94 # Reading the data from JSON File for topology creation
95 jsonFile
= "{}/evpn_type5_topo1.json".format(CWD
)
97 with
open(jsonFile
, "r") as topoJson
:
98 topo
= json
.load(topoJson
)
100 assert False, "Could not read file {}".format(jsonFile
)
103 NETWORK1_1
= {"ipv4": "10.1.1.1/32", "ipv6": "10::1/128"}
104 NETWORK1_2
= {"ipv4": "40.1.1.1/32", "ipv6": "40::1/128"}
105 NETWORK1_3
= {"ipv4": "40.1.1.2/32", "ipv6": "40::2/128"}
106 NETWORK1_4
= {"ipv4": "40.1.1.3/32", "ipv6": "40::3/128"}
107 NETWORK2_1
= {"ipv4": "20.1.1.1/32", "ipv6": "20::1/128"}
108 NETWORK3_1
= {"ipv4": "30.1.1.1/32", "ipv6": "30::1/128"}
109 NETWORK4_1
= {"ipv4": "100.1.1.1/32 ", "ipv6": "100::100/128"}
110 NEXT_HOP_IP
= {"ipv4": "Null0", "ipv6": "Null0"}
114 MAC_1
= "00:80:48:ba:d1:00"
115 MAC_2
= "00:80:48:ba:d1:01"
116 MAC_3
= "00:80:48:ba:d1:02"
120 VXLAN_1
= "vxlan75100"
121 VXLAN_2
= "vxlan75200"
122 VXLAN_3
= "vxlan75300"
123 BRIDGE_INTF1
= "120.0.0.1"
124 BRIDGE_INTF2
= "120.0.0.2"
125 BRIDGE_INTF3
= "120.0.0.3"
128 "vxlan_name": [VXLAN_1
, VXLAN_2
, VXLAN_3
],
129 "vxlan_id": [75100, 75200, 75300],
131 "local_addr": {"e1": BRIDGE_INTF1
, "d1": BRIDGE_INTF2
, "d2": BRIDGE_INTF3
},
135 "brctl_name": [BRCTL_1
, BRCTL_2
, BRCTL_3
],
136 "addvxlan": [VXLAN_1
, VXLAN_2
, VXLAN_3
],
137 "vrf": ["RED", "BLUE", "GREEN"],
142 class CreateTopo(Topo
):
144 Test BasicTopo - topology 1
146 * `Topo`: Topology object
149 def build(self
, *_args
, **_opts
):
151 tgen
= get_topogen(self
)
153 # Building topology from json file
154 build_topo_from_json(tgen
, topo
)
157 def setup_module(mod
):
159 Sets up the pytest environment
165 testsuite_run_time
= time
.asctime(time
.localtime(time
.time()))
166 logger
.info("Testsuite start time: {}".format(testsuite_run_time
))
167 logger
.info("=" * 40)
169 logger
.info("Running setup_module to create topology")
171 # This function initiates the topology build with Topogen...
172 tgen
= Topogen(CreateTopo
, mod
.__name
__)
173 # ... and here it calls Mininet initialization functions.
175 # Starting topology, create tmp files which are loaded to routers
176 # to start deamons and then start routers
179 # Creating configuration from JSON
180 build_config_from_json(tgen
, topo
)
182 if version_cmp(platform
.release(), '4.19') < 0:
183 error_msg
= ('EVPN tests will not run (have kernel "{}", '
184 'but it requires >= 4.19)'.format(platform
.release()))
185 pytest
.skip(error_msg
)
187 global BGP_CONVERGENCE
189 ADDR_TYPES
= check_address_types()
191 BGP_CONVERGENCE
= verify_bgp_convergence(tgen
, topo
)
192 assert BGP_CONVERGENCE
is True, "setup_module :Failed \n Error: {}".format(
196 logger
.info("Pre-requisite config for testsuite")
197 prerequisite_config_for_test_suite(tgen
)
199 logger
.info("Running setup_module() done")
202 def teardown_module():
203 """Teardown the pytest environment"""
205 logger
.info("Running teardown_module to delete topology")
209 # Stop toplogy and Remove tmp files
213 "Testsuite end time: {}".format(time
.asctime(time
.localtime(time
.time())))
215 logger
.info("=" * 40)
218 #####################################################
222 #####################################################
225 def prerequisite_config_for_test_suite(tgen
):
227 API to do prerequisite config for testsuite
231 * `tgen`: topogen object
234 step("Configure vxlan, bridge interface")
235 for dut
in ["e1", "d1", "d2"]:
236 step("[DUT: ]Configure vxlan")
241 "vxlan_name": VXLAN
["vxlan_name"],
242 "vxlan_id": VXLAN
["vxlan_id"],
243 "dstport": VXLAN
["dstport"],
244 "local_addr": VXLAN
["local_addr"][dut
],
245 "learning": VXLAN
["learning"],
251 result
= configure_vxlan(tgen
, vxlan_input
)
252 assert result
is True, "Testcase {} on {} :Failed \n Error: {}".format(
256 step("Configure bridge interface")
261 "brctl_name": BRCTL
["brctl_name"],
262 "addvxlan": BRCTL
["addvxlan"],
269 result
= configure_brctl(tgen
, topo
, brctl_input
)
270 assert result
is True, "Testcase {} on {} :Failed \n Error: {}".format(
274 step("Configure default routes")
275 add_default_routes(tgen
)
278 def add_default_routes(tgen
):
280 API to do prerequisite config for testsuite
284 * `tgen`: topogen object
287 step("Add default routes..")
293 "network": "{}/32".format(VXLAN
["local_addr"]["d1"]),
294 "next_hop": topo
["routers"]["d1"]["links"]["e1-link1"][
299 "network": "{}/32".format(VXLAN
["local_addr"]["d2"]),
300 "next_hop": topo
["routers"]["d2"]["links"]["e1-link1"][
309 "network": "{}/32".format(VXLAN
["local_addr"]["e1"]),
310 "next_hop": topo
["routers"]["e1"]["links"]["d1-link1"][
315 "network": "{}/32".format(VXLAN
["local_addr"]["d2"]),
316 "next_hop": topo
["routers"]["e1"]["links"]["d1-link1"][
325 "network": "{}/32".format(VXLAN
["local_addr"]["d1"]),
326 "next_hop": topo
["routers"]["e1"]["links"]["d2-link1"][
331 "network": "{}/32".format(VXLAN
["local_addr"]["e1"]),
332 "next_hop": topo
["routers"]["e1"]["links"]["d2-link1"][
340 result
= create_static_routes(tgen
, default_routes
)
341 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
344 def test_RD_verification_manual_and_auto_p0(request
):
346 RD verification (manual/auto).
350 tc_name
= request
.node
.name
351 write_test_header(tc_name
)
352 check_router_status(tgen
)
353 reset_config_on_routers(tgen
)
354 add_default_routes(tgen
)
356 if tgen
.routers_have_failure():
357 pytest
.skip(tgen
.errors
)
360 "Advertise prefixes from VNF routers R1 and R2 in associated "
361 "VRFs for both address-family."
364 "Advertise vrf RED's routes in EVPN address family from Edge-1 router"
365 ", without manual configuration of RD."
368 for addr_type
in ADDR_TYPES
:
373 "network": NETWORK1_1
[addr_type
],
374 "next_hop": NEXT_HOP_IP
[addr_type
],
382 "network": NETWORK2_1
[addr_type
],
383 "next_hop": NEXT_HOP_IP
[addr_type
],
387 "network": NETWORK3_1
[addr_type
],
388 "next_hop": NEXT_HOP_IP
[addr_type
],
395 result
= create_static_routes(tgen
, input_dict_1
)
396 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
400 step("Verify on DCG-1 and DCG-2:")
401 step("EVPN route for 10.1.1.1/32 has auto-assigned RD value.")
403 for dut
in ["d1", "d2"]:
404 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
405 result
= verify_attributes_for_evpn_routes(
406 tgen
, topo
, dut
, input_routes
, rd
="auto", rd_peer
="e1"
408 assert result
is True, "Testcase {} on {} :Failed \n Error: {}".format(
413 "Configure RD for vrf RED manually as 50.50.50.50:50 and "
414 "advertise vrf RED's routes in EVPN address family from "
424 "address_family": {"l2vpn": {"evpn": {"rd": "50.50.50.50:50"}}},
430 result
= create_router_bgp(tgen
, topo
, input_dict_rd
)
431 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
433 step("EVPN route for vrf RED has RD value as 50.50.50.50:50")
434 for dut
in ["d1", "d2"]:
435 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
436 result
= verify_attributes_for_evpn_routes(
437 tgen
, topo
, dut
, input_routes
, rd
="50.50.50.50:50"
439 assert result
is True, "Testcase {} on {} :Failed \n Error: {}".format(
444 "Configure RD for vrf RED manually as 100.100.100.100:100 and "
445 "advertise vrf RED's routes in EVPN address family from Edge-1 "
455 "l2vpn": {"evpn": {"rd": "100.100.100.100:100"}}
462 result
= create_router_bgp(tgen
, topo
, input_dict_rd
)
463 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
466 "EVPN route for vrf RED is overridden with RD value as " "100.100.100.100:100."
469 for dut
in ["d1", "d2"]:
470 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
471 result
= verify_attributes_for_evpn_routes(
472 tgen
, topo
, dut
, input_routes
, rd
="100.100.100.100:100"
474 assert result
is True, "Testcase {} on {} :Failed \n Error: {}".format(
479 "Configure RD for vrf BLUE manually same as vrf RED "
480 "(100.100.100.100:100) and advertise vrf RED and BLUE's routes "
481 "in EVPN address family from Edge-1 router."
491 "l2vpn": {"evpn": {"rd": "100.100.100.100:100"}}
498 result
= create_router_bgp(tgen
, topo
, input_dict_rd
)
499 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
502 "Delete manually configured RD and advertise vrf RED's routes "
503 "in EVPN address family from Edge-1 router."
513 "l2vpn": {"evpn": {"no rd": "100.100.100.100:100"}}
520 result
= create_router_bgp(tgen
, topo
, input_dict_rd
)
521 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
524 "Configure same RD value for vrf GREEN, as auto generated RD "
525 "value for vrf RED on Edge-1 router."
534 "address_family": {"l2vpn": {"evpn": {"rd": "10.0.0.33:1"}}},
540 result
= create_router_bgp(tgen
, topo
, input_dict_rd
)
541 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
543 step("Delete auto configured RD value from vrf RED in EVPN " "address family.")
551 "address_family": {"l2vpn": {"evpn": {"no rd": "10.0.0.33:1"}}},
557 result
= create_router_bgp(tgen
, topo
, input_dict_rd
)
558 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
560 step("Configure RD value as 100.100.100:100")
568 "address_family": {"l2vpn": {"evpn": {"rd": "100.100.100:100"}}},
574 result
= create_router_bgp(tgen
, topo
, input_dict_rd
)
575 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
577 write_test_footer(tc_name
)
580 def test_RT_verification_manual_p0(request
):
582 RT verification(manual)
586 tc_name
= request
.node
.name
587 write_test_header(tc_name
)
588 check_router_status(tgen
)
589 reset_config_on_routers(tgen
)
590 add_default_routes(tgen
)
592 if tgen
.routers_have_failure():
593 pytest
.skip(tgen
.errors
)
596 "Advertise prefixes from VNF routers R1 and R2 in associated "
597 "VRFs for both address-family."
599 step("Advertise VRF routes as in EVPN address family from Edge-1 " "router.")
601 for addr_type
in ADDR_TYPES
:
606 "network": NETWORK1_1
[addr_type
],
607 "next_hop": NEXT_HOP_IP
[addr_type
],
615 "network": NETWORK2_1
[addr_type
],
616 "next_hop": NEXT_HOP_IP
[addr_type
],
620 "network": NETWORK3_1
[addr_type
],
621 "next_hop": NEXT_HOP_IP
[addr_type
],
628 result
= create_static_routes(tgen
, input_dict_1
)
629 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
634 "Configure RT for vrf RED manually as export 100:100 "
635 "and advertise vrf RED's routes in EVPN address family"
636 " from Edge-1 router."
647 "unicast": {"neighbor": {"r1": {"dest_link": {"e1": {}}}}}
650 "unicast": {"neighbor": {"r1": {"dest_link": {"e1": {}}}}}
653 "evpn": {"route-target": {"export": [{"value": "100:100"}]}}
661 result
= create_router_bgp(tgen
, topo
, input_dict_rt
)
662 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
665 "Verify on dcg-1 and dcg-2, EVPN route for 10.1.1.1/32"
666 " and 10::1/128 have RT value as 100:100."
669 for dut
in ["d1", "d2"]:
670 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
671 result
= verify_attributes_for_evpn_routes(
672 tgen
, topo
, dut
, input_routes
, rt
="100:100"
674 assert result
is True, "Testcase {} on {} :Failed \n Error: {}".format(
679 "Configure RT for vrf RED manually as export 500:500 and"
680 " advertise vrf RED's routes in EVPN address family from"
692 "evpn": {"route-target": {"export": [{"value": "500:500"}]}}
700 result
= create_router_bgp(tgen
, topo
, input_dict_rt
)
701 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
704 "Verify on dcg-1 and dcg-2, EVPN route for 10.1.1.1/32"
705 " and 10::1/128 have RT value as 500:500."
708 for dut
in ["d1", "d2"]:
709 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
710 result
= verify_attributes_for_evpn_routes(
711 tgen
, topo
, dut
, input_routes
, rt
=["100:100", "500:500"]
713 assert result
is True, "Testcase {} on {} :Failed \n Error: {}".format(
718 "Import RT value 100:100 and 500:500 in vrf BLUE manually on"
719 " peer router DCG-1 and DCG-2."
733 {"value": "100:100"},
734 {"value": "500:500"},
753 {"value": "100:100"},
754 {"value": "500:500"},
765 result
= create_router_bgp(tgen
, topo
, input_dict_rt
)
766 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
769 "EVPN route for 10.1.1.1/32 and 10::1 should be installed "
770 "in vrf BLUE on DCG-1 and DCG-2 and further advertised to "
774 for addr_type
in ADDR_TYPES
:
777 "static_routes": [{"network": [NETWORK1_1
[addr_type
]], "vrf": "BLUE"}]
780 result
= verify_rib(tgen
, addr_type
, "d1", input_routes
)
781 assert result
is True, "Testcase {} :Failed \n Error {}".format(tc_name
, result
)
783 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
)
784 assert result
is True, "Testcase {} :Failed \n Error {}".format(tc_name
, result
)
787 "Delete import RT value 500:500 in vrf BLUE manually on "
788 "peer router DCG-1 and DCG-2."
801 "import": [{"value": "500:500", "delete": True}]
818 "import": [{"value": "500:500", "delete": True}]
828 result
= create_router_bgp(tgen
, topo
, input_dict_rt
)
829 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
831 for dut
in ["d1", "d2"]:
832 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
833 result
= verify_attributes_for_evpn_routes(
834 tgen
, topo
, dut
, input_routes
, rt
=["100:100", "500:500"]
836 assert result
is True, "Testcase {} on {} :Failed \n Error: {}".format(
840 step("Delete RT export value 100:100 for vrf RED on Edge-1")
852 "export": [{"value": "100:100", "delete": True}]
862 result
= create_router_bgp(tgen
, topo
, input_dict_rt
)
863 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
866 "EVPN route for 10.1.1.1/32 and 10::1 should be withdrawn "
867 "from vrf BLUE on DCG-1,DCG-2 and VNF router."
870 for addr_type
in ADDR_TYPES
:
873 "static_routes": [{"network": [NETWORK1_1
[addr_type
]], "vrf": "BLUE"}]
876 result
= verify_rib(tgen
, addr_type
, "d1", input_routes
, expected
=False)
877 assert result
is not True, (
878 "Testcase {} :Failed \n Expected Behavior: Routes are still "
879 "present \n Error: {}".format(tc_name
, result
)
881 logger
.info("Expected Behavior: {}".format(result
))
883 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
, expected
=False)
884 assert result
is not True, (
885 "Testcase {} :Failed \n Expected Behavior: Routes are still "
886 "present \n Error: {}".format(tc_name
, result
)
888 logger
.info("Expected Behavior: {}".format(result
))
891 "Configure RT value as 100:100000010000010000101010 to check "
892 "the boundary value."
906 {"value": "100:100000010000010000101010"}
917 result
= create_router_bgp(tgen
, topo
, input_dict_rt
)
918 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
921 "CLI error: RT value: 100:100000010000010000101010 should not " "be configured"
925 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
926 result
= verify_attributes_for_evpn_routes(
927 tgen
, topo
, dut
, input_routes
, rt
="100:100000010000010000101010", expected
=False
929 assert result
is not True, (
930 "Testcase {} :Failed \n Expected Behavior: RT value of out"
931 " of boundary \n Error: {}".format(tc_name
, result
)
933 logger
.info("Expected Behavior: {}".format(result
))
935 write_test_footer(tc_name
)
938 def test_active_standby_evpn_implementation_p1(request
):
940 In an active/standby EVPN implementation, if active DCG goes down,
941 secondary takes over.
945 tc_name
= request
.node
.name
946 write_test_header(tc_name
)
947 check_router_status(tgen
)
948 reset_config_on_routers(tgen
)
949 add_default_routes(tgen
)
951 if tgen
.routers_have_failure():
952 pytest
.skip(tgen
.errors
)
955 "Taken care in base config: Configure BGP neighborship for both "
956 "address families(IPv4 & IPv6) between DCG-1/DCG-2 and VFN routers"
961 "BGP neighborships come up within defined VRFs. Please use below "
962 "command: sh bgp vrf all summary"
965 result
= verify_bgp_convergence(tgen
, topo
, "d1")
966 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
968 result
= verify_bgp_convergence(tgen
, topo
, "d2")
969 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
972 "Advertise prefixes from VNF routers R3 and R4 in associated "
973 "VRFs for both address-families."
976 for addr_type
in ADDR_TYPES
:
981 "network": NETWORK1_2
[addr_type
],
982 "next_hop": NEXT_HOP_IP
[addr_type
],
990 "network": NETWORK1_3
[addr_type
],
991 "next_hop": NEXT_HOP_IP
[addr_type
],
995 "network": NETWORK1_4
[addr_type
],
996 "next_hop": NEXT_HOP_IP
[addr_type
],
1003 result
= create_static_routes(tgen
, input_dict_1
)
1004 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1009 "Redistribute static in (IPv4 and IPv6) address-family "
1010 "on Edge-1 for all VRFs."
1014 for dut
in ["r3", "r4"]:
1015 temp
= {dut
: {"bgp": []}}
1016 input_dict_2
.update(temp
)
1022 VRFS
= ["BLUE", "GREEN"]
1025 for vrf
, as_num
in zip(VRFS
, AS_NUM
):
1026 temp
[dut
]["bgp"].append(
1032 "unicast": {"redistribute": [{"redist_type": "static"}]}
1035 "unicast": {"redistribute": [{"redist_type": "static"}]}
1041 result
= create_router_bgp(tgen
, topo
, input_dict_2
)
1042 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1044 step("Prefixes are received in respective VRFs on DCG-1/DCG-2.")
1046 for addr_type
in ADDR_TYPES
:
1051 "network": NETWORK1_2
[addr_type
],
1052 "next_hop": NEXT_HOP_IP
[addr_type
],
1060 "network": NETWORK1_3
[addr_type
],
1061 "next_hop": NEXT_HOP_IP
[addr_type
],
1065 "network": NETWORK1_4
[addr_type
],
1066 "next_hop": NEXT_HOP_IP
[addr_type
],
1073 result
= verify_rib(tgen
, addr_type
, "d1", input_routes
)
1074 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1078 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
)
1079 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1084 "Taken care in base config: Advertise VRF routes in EVPN "
1085 "address-family from DCG-1 and DCG-2 router."
1088 step("Verify on Edge-1 that EVPN routes are installed via next-hop " "as DCG-2.")
1090 for addr_type
in ADDR_TYPES
:
1095 "network": NETWORK1_2
[addr_type
],
1096 "next_hop": NEXT_HOP_IP
[addr_type
],
1104 "network": NETWORK1_3
[addr_type
],
1105 "next_hop": NEXT_HOP_IP
[addr_type
],
1109 "network": NETWORK1_4
[addr_type
],
1110 "next_hop": NEXT_HOP_IP
[addr_type
],
1117 if addr_type
== "ipv4":
1118 result
= verify_rib(
1119 tgen
, addr_type
, "e1", input_routes
, next_hop
=BRIDGE_INTF2
1121 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1125 result
= verify_rib(tgen
, addr_type
, "e1", input_routes
)
1126 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1131 "Configure 'next-hop self' on DCG-1 for peer Edge-1 in EVPN " "address-family."
1144 "ipv4": {"d1-link1": {"next_hop_self": True}}
1155 result
= create_router_bgp(tgen
, topo
, input_dict_3
)
1156 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1159 "Creating route-map so ipv6 glpbal ip wpuld be preferred " "as next-hop"
1163 "Verify on Edge-1 that EVPN routes are now preferred via "
1164 "next-hop as DCG-1(iBGP) due to shortest AS-Path."
1167 for addr_type
in ADDR_TYPES
:
1169 logger
.info("Verifying only ipv4 routes")
1170 if addr_type
!= "ipv4":
1177 "network": NETWORK1_2
[addr_type
],
1178 "next_hop": NEXT_HOP_IP
[addr_type
],
1186 "network": NETWORK1_3
[addr_type
],
1187 "next_hop": NEXT_HOP_IP
[addr_type
],
1191 "network": NETWORK1_4
[addr_type
],
1192 "next_hop": NEXT_HOP_IP
[addr_type
],
1199 next_hop
= topo
["routers"]["d1"]["links"]["e1-link1"]["ipv4"].split("/")[0]
1201 result
= verify_rib(tgen
, addr_type
, "e1", input_routes
, next_hop
=next_hop
)
1202 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1206 write_test_footer(tc_name
)
1209 def test_evpn_routes_from_VNFs_p1(request
):
1211 EVPN routes are advertised/withdrawn, based on VNFs
1212 advertising/withdrawing IP prefixes.
1215 tgen
= get_topogen()
1216 tc_name
= request
.node
.name
1217 write_test_header(tc_name
)
1218 check_router_status(tgen
)
1219 reset_config_on_routers(tgen
)
1220 add_default_routes(tgen
)
1222 if tgen
.routers_have_failure():
1223 pytest
.skip(tgen
.errors
)
1226 "Advertise prefixes from VNF routers R1 and R2 in associated "
1227 "VRFs for both address-family."
1230 for addr_type
in ADDR_TYPES
:
1235 "network": NETWORK1_1
[addr_type
],
1236 "next_hop": NEXT_HOP_IP
[addr_type
],
1244 "network": NETWORK2_1
[addr_type
],
1245 "next_hop": NEXT_HOP_IP
[addr_type
],
1249 "network": NETWORK3_1
[addr_type
],
1250 "next_hop": NEXT_HOP_IP
[addr_type
],
1257 result
= create_static_routes(tgen
, input_dict_1
)
1258 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1263 "Taken care in base config: Advertise VNFs'(R1 and R2) "
1264 "originated routes in EVPN address-family from Edge-1 to "
1265 "DCG-1 and DCG-2 routers."
1268 "Taken care in base config: Advertise IPv4 and IPv6 routes "
1269 "from default vrf in EVPN address-family from Edge-1."
1273 "Verify on DCG-2 that VNF routes are received in respective "
1274 "VRFs along with auto derived RD/RT values 'show bgp l2vpn evpn'"
1276 for dut
in ["d1", "d2"]:
1277 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1278 result
= verify_evpn_routes(tgen
, topo
, dut
, input_routes
)
1279 assert result
is True, "Testcase {} on {} :Failed \n Error: {}".format(
1280 tc_name
, dut
, result
1283 input_routes
= {key
: topo
["routers"][key
] for key
in ["r2"]}
1284 result
= verify_evpn_routes(tgen
, topo
, dut
, input_routes
)
1285 assert result
is True, "Testcase {} on {} :Failed \n Error: {}".format(
1286 tc_name
, dut
, result
1290 "Verify on R3 and R4 that DCG-2 further advertises all EVPN "
1291 "routes to corresponding VRFs."
1293 for addr_type
in ADDR_TYPES
:
1294 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1295 result
= verify_rib(tgen
, addr_type
, "r3", input_routes
)
1296 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1300 for addr_type
in ADDR_TYPES
:
1301 input_routes
= {key
: topo
["routers"][key
] for key
in ["r2"]}
1302 result
= verify_rib(tgen
, addr_type
, "r4", input_routes
)
1303 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1308 "Verify that DCG-2 receives EVPN routes associated to default "
1309 "VRF and install in default IP routing table as well."
1311 for addr_type
in ADDR_TYPES
:
1312 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1313 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
, expected
=False)
1314 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1318 for addr_type
in ADDR_TYPES
:
1319 input_routes
= {key
: topo
["routers"][key
] for key
in ["r2"]}
1320 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
, expected
=False)
1321 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1325 step("Withdraw the IP prefixes from VFN(R1).")
1328 static_routes
= topo
["routers"][dut
]["static_routes"]
1329 for static_route
in static_routes
:
1330 static_route
["delete"] = True
1331 temp
= {dut
: {"static_routes": [static_route
]}}
1332 input_dict_2
.update(temp
)
1334 result
= create_static_routes(tgen
, input_dict_2
)
1335 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1340 "Verify that DCG-2 removes EVPN routes corresponding to vrf RED and "
1341 "send an withdraw to VNF(R3) as well."
1343 for addr_type
in ADDR_TYPES
:
1344 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1345 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
, expected
=False)
1346 assert result
is not True, "Testcase {} :Failed \n "
1347 "Routes are still present: {}".format(tc_name
, result
)
1348 logger
.info("Expected Behavior: {}".format(result
))
1350 for addr_type
in ADDR_TYPES
:
1351 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1352 result
= verify_rib(tgen
, addr_type
, "r3", input_routes
, expected
=False)
1353 assert result
is not True, "Testcase {} :Failed \n "
1354 "Routes are still present: {}".format(tc_name
, result
)
1355 logger
.info("Expected Behavior: {}".format(result
))
1357 step("Re-advertise IP prefixes from VFN(R1).")
1359 "Advertise prefixes from VNF routers R1 and R2 in associated "
1360 "VRFs for both address-family."
1363 for addr_type
in ADDR_TYPES
:
1368 "network": NETWORK1_1
[addr_type
],
1369 "next_hop": NEXT_HOP_IP
[addr_type
],
1377 "network": NETWORK2_1
[addr_type
],
1378 "next_hop": NEXT_HOP_IP
[addr_type
],
1382 "network": NETWORK3_1
[addr_type
],
1383 "next_hop": NEXT_HOP_IP
[addr_type
],
1390 result
= create_static_routes(tgen
, input_dict_1
)
1391 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1396 "Verify that DCG-2 receives EVPN routes corresponding to vrf RED "
1397 "again and send an update to VNF(R3) as well."
1399 for addr_type
in ADDR_TYPES
:
1400 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1401 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
)
1402 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1406 for addr_type
in ADDR_TYPES
:
1407 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1408 result
= verify_rib(tgen
, addr_type
, "r3", input_routes
)
1409 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1413 step("Delete vrf BLUE from router Edge-1")
1414 input_dict_3
= {"e1": {"vrfs": [{"name": "BLUE", "id": "2", "delete": True}]}}
1416 result
= create_vrf_cfg(tgen
, input_dict_3
)
1417 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1420 "Verify that DCG-2 removes EVPN routes corresponding to "
1421 "vrf BLUE and send an withdraw to VNF(R4) as well."
1423 for addr_type
in ADDR_TYPES
:
1425 "r2": {"static_routes": [{"network": NETWORK2_1
[addr_type
], "vrf": "BLUE"}]}
1428 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
, expected
=False)
1429 assert result
is not True, "Testcase {} :Failed \n "
1430 "Routes are still present: {}".format(tc_name
, result
)
1431 logger
.info("Expected Behavior: {}".format(result
))
1433 result
= verify_rib(tgen
, addr_type
, "r4", input_routes
, expected
=False)
1434 assert result
is not True, "Testcase {} :Failed \n "
1435 "Routes are still present: {}".format(tc_name
, result
)
1436 logger
.info("Expected Behavior: {}".format(result
))
1438 step("Add vrf BLUE on router Edge-1 again.")
1439 interface
= topo
["routers"]["e1"]["links"]["r2-link1"]["interface"]
1444 "interface": interface
,
1450 "vrfs": [{"name": "BLUE", "id": "2"}],
1453 result
= create_vrf_cfg(tgen
, input_dict_3
)
1454 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1457 "After deleting VRFs ipv6 addresses wil be deleted "
1458 "from kernel Adding back ipv6 addresses"
1464 for c_link
, c_data
in topo
["routers"][dut
]["links"].items():
1466 if c_data
["vrf"] != vrf
:
1469 intf_name
= c_data
["interface"]
1470 intf_ipv6
= c_data
["ipv6"]
1472 create_interface_in_kernel(
1473 tgen
, dut
, intf_name
, intf_ipv6
, vrf
, create
=False
1476 logger
.info("Wait for 60 sec.")
1480 "Verify that DCG-2 receives EVPN routes corresponding to "
1481 "vrf BLUE again and send an update to VNF(R4) as well."
1483 for addr_type
in ADDR_TYPES
:
1485 "r2": {"static_routes": [{"network": NETWORK2_1
[addr_type
], "vrf": "BLUE"}]}
1488 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
)
1489 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1493 result
= verify_rib(tgen
, addr_type
, "r4", input_routes
)
1494 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1498 step("Withdraw IPv6 address-family in EVPN advertisements for " "VRF GREEN")
1509 "advertise": {addr_type
: {"unicast": {"delete": True}}}
1518 result
= create_router_bgp(tgen
, topo
, input_dict_4
)
1519 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1522 "Verify that EVPN routes (IPv6)associated with vrf GREEN are "
1523 "withdrawn from DCG-2 and VNF R4."
1526 "r2": {"static_routes": [{"network": NETWORK3_1
[addr_type
], "vrf": "GREEN"}]}
1529 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
, expected
=False)
1530 assert result
is not True, "Testcase {} :Failed \n "
1531 "Routes are still present: {}".format(tc_name
, result
)
1532 logger
.info("Expected Behavior: {}".format(result
))
1534 result
= verify_rib(tgen
, addr_type
, "r4", input_routes
, expected
=False)
1535 assert result
is not True, "Testcase {} :Failed \n "
1536 "Routes are still present: {}".format(tc_name
, result
)
1537 logger
.info("Expected Behavior: {}".format(result
))
1539 step("Advertise IPv6 address-family in EVPN advertisements " "for VRF GREEN.")
1548 "l2vpn": {"evpn": {"advertise": {addr_type
: {"unicast": {}}}}}
1555 result
= create_router_bgp(tgen
, topo
, input_dict_4
)
1556 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1558 for addr_type
in ADDR_TYPES
:
1561 "static_routes": [{"network": NETWORK3_1
[addr_type
], "vrf": "GREEN"}]
1565 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
)
1566 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1570 result
= verify_rib(tgen
, addr_type
, "r4", input_routes
)
1571 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1575 write_test_footer(tc_name
)
1578 @pytest.mark
.parametrize(
1579 "attribute", [{"route-type": "prefix"}, {"vni": VNI_1
}, {"rt": "300:300"}]
1581 def test_route_map_operations_for_evpn_address_family_p1(request
, attribute
):
1583 Route-map operations for EVPN address family.
1586 tgen
= get_topogen()
1587 tc_name
= request
.node
.name
1588 write_test_header(tc_name
)
1589 check_router_status(tgen
)
1590 reset_config_on_routers(tgen
)
1591 add_default_routes(tgen
)
1594 "Advertise prefixes from VNF routers R1 and R2 in associated "
1595 "VRFs for both address-family."
1598 for addr_type
in ADDR_TYPES
:
1603 "network": NETWORK1_1
[addr_type
],
1604 "next_hop": NEXT_HOP_IP
[addr_type
],
1612 "network": NETWORK2_1
[addr_type
],
1613 "next_hop": NEXT_HOP_IP
[addr_type
],
1617 "network": NETWORK3_1
[addr_type
],
1618 "next_hop": NEXT_HOP_IP
[addr_type
],
1625 result
= create_static_routes(tgen
, input_dict_1
)
1626 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1630 if tgen
.routers_have_failure():
1631 pytest
.skip(tgen
.errors
)
1634 "Advertise VRF routes in EVPN address family from Edge-1 router."
1635 " Configure a route-map on e1 to filter EVPN routes based on"
1636 " below keywords: route-type: prefix"
1639 for key
, value
in attribute
.items():
1641 logger
.info("Creating extcommunity using raw_config")
1645 "bgp extcommunity-list standard ECOMM300 permit {} {}".format(
1651 result
= apply_raw_config(tgen
, raw_config
)
1652 assert result
is True, "Testcase {} : Failed Error: {}".format(
1659 "rmap_route_type": [
1660 {"action": "permit", "set": {"extcommunity": {key
: value
}}}
1666 "rmap_route_type": [
1667 {"action": "permit", "match": {"extcommunity": "ECOMM300"}}
1677 "rmap_route_type": [
1678 {"action": "permit", "match": {"evpn": {key
: value
}}}
1684 "rmap_route_type": [
1685 {"action": "permit", "match": {"evpn": {key
: value
}}}
1690 result
= create_route_maps(tgen
, input_dict_1
)
1691 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1709 "name": "rmap_route_type",
1736 "name": "rmap_route_type",
1752 result
= create_router_bgp(tgen
, topo
, input_dict_2
)
1753 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1756 "Verify on router DCG-2 that EVPN routes corresponding to all "
1757 "VRFs are received. As all EVPN routes are type-5 only."
1760 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1761 result
= verify_evpn_routes(tgen
, topo
, "d2", input_routes
)
1762 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1764 input_routes
= {key
: topo
["routers"][key
] for key
in ["r2"]}
1765 result
= verify_evpn_routes(tgen
, topo
, "d2", input_routes
)
1766 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1768 write_test_footer(tc_name
)
1771 @pytest.mark
.parametrize("attribute", ["locPrf", "weight", "path"])
1772 def test_bgp_attributes_for_evpn_address_family_p1(request
, attribute
):
1774 BGP attributes for EVPN address-family.
1777 tgen
= get_topogen()
1778 tc_name
= request
.node
.name
1779 write_test_header(tc_name
)
1780 check_router_status(tgen
)
1781 reset_config_on_routers(tgen
)
1782 add_default_routes(tgen
)
1784 if tgen
.routers_have_failure():
1785 pytest
.skip(tgen
.errors
)
1788 "Advertise prefixes from VNF routers R1 and R2 in associated "
1789 "VRFs for both address-family."
1792 for addr_type
in ADDR_TYPES
:
1797 "network": NETWORK1_1
[addr_type
],
1798 "next_hop": NEXT_HOP_IP
[addr_type
],
1806 "network": NETWORK2_1
[addr_type
],
1807 "next_hop": NEXT_HOP_IP
[addr_type
],
1811 "network": NETWORK3_1
[addr_type
],
1812 "next_hop": NEXT_HOP_IP
[addr_type
],
1819 result
= create_static_routes(tgen
, input_dict_1
)
1820 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1824 topo_local
= deepcopy(topo
)
1826 logger
.info("Modifying topology b/w e1 and d1 from iBGP to eBGP")
1827 step("Delete BGP config for vrf RED.")
1829 if attribute
== "locPrf":
1833 {"name": "RED", "no_vni": VNI_1
},
1834 {"name": "BLUE", "no_vni": VNI_2
},
1835 {"name": "GREEN", "no_vni": VNI_3
},
1839 result
= create_vrf_cfg(tgen
, topo
, input_dict
=input_dict_vni
)
1840 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1846 temp
= {dut
: {"bgp": []}}
1847 input_dict_2
.update(temp
)
1849 INDEX
= [0, 1, 2, 3]
1850 VRFS
= ["RED", "BLUE", "GREEN", None]
1851 AS_NUM
= [100, 100, 100, 100]
1853 for index
, vrf
, as_num
in zip(INDEX
, VRFS
, AS_NUM
):
1854 topo_local
["routers"][dut
]["bgp"][index
]["local_as"] = 200
1856 temp
[dut
]["bgp"].append(
1857 {"local_as": as_num
, "vrf": vrf
, "delete": True}
1860 temp
[dut
]["bgp"].append({"local_as": as_num
, "delete": True})
1862 result
= create_router_bgp(tgen
, topo
, input_dict_2
)
1863 assert result
is True, "Testcase {} on d1 :Failed \n Error: {}".format(
1867 result
= create_router_bgp(tgen
, topo_local
["routers"])
1868 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1872 step("Advertise VRF routes in EVPN address-family from DCG-1 " "and DCG-2 routers.")
1874 for addr_type
in ADDR_TYPES
:
1879 "network": NETWORK1_2
[addr_type
],
1880 "next_hop": NEXT_HOP_IP
[addr_type
],
1888 "network": NETWORK1_3
[addr_type
],
1889 "next_hop": NEXT_HOP_IP
[addr_type
],
1893 "network": NETWORK1_4
[addr_type
],
1894 "next_hop": NEXT_HOP_IP
[addr_type
],
1901 result
= create_static_routes(tgen
, input_dict_1
)
1902 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1907 "Redistribute static in (IPv4 and IPv6) address-family "
1908 "on Edge-1 for all VRFs."
1912 for dut
in ["r3", "r4"]:
1913 temp
= {dut
: {"bgp": []}}
1914 input_dict_2
.update(temp
)
1920 VRFS
= ["BLUE", "GREEN"]
1923 for vrf
, as_num
in zip(VRFS
, AS_NUM
):
1924 temp
[dut
]["bgp"].append(
1930 "unicast": {"redistribute": [{"redist_type": "static"}]}
1933 "unicast": {"redistribute": [{"redist_type": "static"}]}
1939 result
= create_router_bgp(tgen
, topo
, input_dict_2
)
1940 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1943 "Verify on router Edge-1 that EVPN routes corresponding to "
1944 "all VRFs are received from both routers DCG-1 and DCG-2"
1947 for addr_type
in ADDR_TYPES
:
1952 "network": NETWORK1_2
[addr_type
],
1953 "next_hop": NEXT_HOP_IP
[addr_type
],
1961 "network": NETWORK1_3
[addr_type
],
1962 "next_hop": NEXT_HOP_IP
[addr_type
],
1966 "network": NETWORK1_4
[addr_type
],
1967 "next_hop": NEXT_HOP_IP
[addr_type
],
1974 result
= verify_rib(tgen
, addr_type
, "e1", input_routes
)
1975 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1980 "Configure a route-map on Edge-1 to modify below BGP attributes "
1981 "for EVPN address-family:"
1984 if attribute
== "path":
1988 "rmap_d1".format(addr_type
): [
1993 "as_num": "123 231 321",
1994 "as_action": "prepend",
1999 "rmap_d2".format(addr_type
): [
2003 attribute
: {"as_num": "121", "as_action": "prepend"}
2014 "rmap_d1".format(addr_type
): [
2015 {"action": "permit", "set": {attribute
: 120}}
2017 "rmap_d2".format(addr_type
): [
2018 {"action": "permit", "set": {attribute
: 150}}
2023 result
= create_route_maps(tgen
, input_dict_1
)
2024 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
2068 result
= create_router_bgp(tgen
, topo
, input_dict_2
)
2069 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
2072 "Verify on router Edge-1 that EVPN routes are preferred via"
2073 " DCG-1 or DCG-2 based on best path selection criteria "
2074 "(according to the configured BGP attribute values in route-map)."
2077 for addr_type
in ADDR_TYPES
:
2082 "network": NETWORK1_2
[addr_type
],
2083 "next_hop": NEXT_HOP_IP
[addr_type
],
2091 "network": NETWORK1_3
[addr_type
],
2092 "next_hop": NEXT_HOP_IP
[addr_type
],
2096 "network": NETWORK1_4
[addr_type
],
2097 "next_hop": NEXT_HOP_IP
[addr_type
],
2104 result
= verify_best_path_as_per_bgp_attribute(
2105 tgen
, addr_type
, "e1", input_routes
, attribute
2107 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
2111 write_test_footer(tc_name
)
2114 if __name__
== "__main__":
2115 args
= ["-s"] + sys
.argv
[1:]
2116 sys
.exit(pytest
.main(args
))