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
,
81 create_interface_in_kernel
84 from lib
.topolog
import logger
86 verify_bgp_convergence
,
89 verify_best_path_as_per_bgp_attribute
,
90 verify_attributes_for_evpn_routes
,
93 from lib
.topojson
import build_topo_from_json
, build_config_from_json
95 # Reading the data from JSON File for topology creation
96 jsonFile
= "{}/evpn_type5_topo1.json".format(CWD
)
98 with
open(jsonFile
, "r") as topoJson
:
99 topo
= json
.load(topoJson
)
101 assert False, "Could not read file {}".format(jsonFile
)
104 NETWORK1_1
= {"ipv4": "10.1.1.1/32", "ipv6": "10::1/128"}
105 NETWORK1_2
= {"ipv4": "40.1.1.1/32", "ipv6": "40::1/128"}
106 NETWORK1_3
= {"ipv4": "40.1.1.2/32", "ipv6": "40::2/128"}
107 NETWORK1_4
= {"ipv4": "40.1.1.3/32", "ipv6": "40::3/128"}
108 NETWORK2_1
= {"ipv4": "20.1.1.1/32", "ipv6": "20::1/128"}
109 NETWORK3_1
= {"ipv4": "30.1.1.1/32", "ipv6": "30::1/128"}
110 NETWORK4_1
= {"ipv4": "100.1.1.1/32 ", "ipv6": "100::100/128"}
111 NEXT_HOP_IP
= {"ipv4": "Null0", "ipv6": "Null0"}
115 MAC_1
= "00:80:48:ba:d1:00"
116 MAC_2
= "00:80:48:ba:d1:01"
117 MAC_3
= "00:80:48:ba:d1:02"
121 VXLAN_1
= "vxlan75100"
122 VXLAN_2
= "vxlan75200"
123 VXLAN_3
= "vxlan75300"
124 BRIDGE_INTF1
= "120.0.0.1"
125 BRIDGE_INTF2
= "120.0.0.2"
126 BRIDGE_INTF3
= "120.0.0.3"
129 "vxlan_name": [VXLAN_1
, VXLAN_2
, VXLAN_3
],
130 "vxlan_id": [75100, 75200, 75300],
132 "local_addr": {"e1": BRIDGE_INTF1
, "d1": BRIDGE_INTF2
, "d2": BRIDGE_INTF3
},
136 "brctl_name": [BRCTL_1
, BRCTL_2
, BRCTL_3
],
137 "addvxlan": [VXLAN_1
, VXLAN_2
, VXLAN_3
],
138 "vrf": ["RED", "BLUE", "GREEN"],
143 class CreateTopo(Topo
):
145 Test BasicTopo - topology 1
147 * `Topo`: Topology object
150 def build(self
, *_args
, **_opts
):
152 tgen
= get_topogen(self
)
154 # Building topology from json file
155 build_topo_from_json(tgen
, topo
)
158 def setup_module(mod
):
160 Sets up the pytest environment
166 testsuite_run_time
= time
.asctime(time
.localtime(time
.time()))
167 logger
.info("Testsuite start time: {}".format(testsuite_run_time
))
168 logger
.info("=" * 40)
170 logger
.info("Running setup_module to create topology")
172 # This function initiates the topology build with Topogen...
173 tgen
= Topogen(CreateTopo
, mod
.__name
__)
174 # ... and here it calls Mininet initialization functions.
176 # Starting topology, create tmp files which are loaded to routers
177 # to start deamons and then start routers
180 # Creating configuration from JSON
181 build_config_from_json(tgen
, topo
)
183 if version_cmp(platform
.release(), '4.19') < 0:
184 error_msg
= ('EVPN tests will not run (have kernel "{}", '
185 'but it requires >= 4.19)'.format(platform
.release()))
186 pytest
.skip(error_msg
)
188 global BGP_CONVERGENCE
190 ADDR_TYPES
= check_address_types()
192 BGP_CONVERGENCE
= verify_bgp_convergence(tgen
, topo
)
193 assert BGP_CONVERGENCE
is True, "setup_module :Failed \n Error: {}".format(
197 logger
.info("Pre-requisite config for testsuite")
198 prerequisite_config_for_test_suite(tgen
)
200 logger
.info("Running setup_module() done")
203 def teardown_module():
204 """Teardown the pytest environment"""
206 logger
.info("Running teardown_module to delete topology")
210 # Stop toplogy and Remove tmp files
214 "Testsuite end time: {}".format(time
.asctime(time
.localtime(time
.time())))
216 logger
.info("=" * 40)
219 #####################################################
223 #####################################################
226 def prerequisite_config_for_test_suite(tgen
):
228 API to do prerequisite config for testsuite
232 * `tgen`: topogen object
235 step("Configure vxlan, bridge interface")
236 for dut
in ["e1", "d1", "d2"]:
237 step("[DUT: ]Configure vxlan")
242 "vxlan_name": VXLAN
["vxlan_name"],
243 "vxlan_id": VXLAN
["vxlan_id"],
244 "dstport": VXLAN
["dstport"],
245 "local_addr": VXLAN
["local_addr"][dut
],
246 "learning": VXLAN
["learning"],
252 result
= configure_vxlan(tgen
, vxlan_input
)
253 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
257 step("Configure bridge interface")
262 "brctl_name": BRCTL
["brctl_name"],
263 "addvxlan": BRCTL
["addvxlan"],
270 result
= configure_brctl(tgen
, topo
, brctl_input
)
271 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
275 step("Configure default routes")
276 add_default_routes(tgen
)
279 def add_default_routes(tgen
):
281 API to do prerequisite config for testsuite
285 * `tgen`: topogen object
288 step("Add default routes..")
294 "network": "{}/32".format(VXLAN
["local_addr"]["d1"]),
295 "next_hop": topo
["routers"]["d1"]["links"]["e1-link1"][
300 "network": "{}/32".format(VXLAN
["local_addr"]["d2"]),
301 "next_hop": topo
["routers"]["d2"]["links"]["e1-link1"][
310 "network": "{}/32".format(VXLAN
["local_addr"]["e1"]),
311 "next_hop": topo
["routers"]["e1"]["links"]["d1-link1"][
316 "network": "{}/32".format(VXLAN
["local_addr"]["d2"]),
317 "next_hop": topo
["routers"]["e1"]["links"]["d1-link1"][
326 "network": "{}/32".format(VXLAN
["local_addr"]["d1"]),
327 "next_hop": topo
["routers"]["e1"]["links"]["d2-link1"][
332 "network": "{}/32".format(VXLAN
["local_addr"]["e1"]),
333 "next_hop": topo
["routers"]["e1"]["links"]["d2-link1"][
341 result
= create_static_routes(tgen
, default_routes
)
342 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
345 def test_RD_verification_manual_and_auto_p0(request
):
347 RD verification (manual/auto).
351 tc_name
= request
.node
.name
352 write_test_header(tc_name
)
353 check_router_status(tgen
)
354 reset_config_on_routers(tgen
)
355 add_default_routes(tgen
)
357 if tgen
.routers_have_failure():
358 pytest
.skip(tgen
.errors
)
361 "Advertise prefixes from VNF routers R1 and R2 in associated "
362 "VRFs for both address-family."
365 "Advertise vrf RED's routes in EVPN address family from Edge-1 router"
366 ", without manual configuration of RD."
369 for addr_type
in ADDR_TYPES
:
374 "network": NETWORK1_1
[addr_type
],
375 "next_hop": NEXT_HOP_IP
[addr_type
],
383 "network": NETWORK2_1
[addr_type
],
384 "next_hop": NEXT_HOP_IP
[addr_type
],
388 "network": NETWORK3_1
[addr_type
],
389 "next_hop": NEXT_HOP_IP
[addr_type
],
396 result
= create_static_routes(tgen
, input_dict_1
)
397 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
401 step("Verify on DCG-1 and DCG-2:")
402 step("EVPN route for 10.1.1.1/32 has auto-assigned RD value.")
404 for dut
in ["d1", "d2"]:
405 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
406 result
= verify_attributes_for_evpn_routes(
407 tgen
, topo
, dut
, input_routes
, rd
="auto", rd_peer
="e1"
409 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
414 "Configure RD for vrf RED manually as 50.50.50.50:50 and "
415 "advertise vrf RED's routes in EVPN address family from "
425 "address_family": {"l2vpn": {"evpn": {"rd": "50.50.50.50:50"}}},
431 result
= create_router_bgp(tgen
, topo
, input_dict_rd
)
432 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
434 step("EVPN route for vrf RED has RD value as 50.50.50.50:50")
435 for dut
in ["d1", "d2"]:
436 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
437 result
= verify_attributes_for_evpn_routes(
438 tgen
, topo
, dut
, input_routes
, rd
="50.50.50.50:50"
440 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
445 "Configure RD for vrf RED manually as 100.100.100.100:100 and "
446 "advertise vrf RED's routes in EVPN address family from Edge-1 "
456 "l2vpn": {"evpn": {"rd": "100.100.100.100:100"}}
463 result
= create_router_bgp(tgen
, topo
, input_dict_rd
)
464 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
467 "EVPN route for vrf RED is overridden with RD value as " "100.100.100.100:100."
470 for dut
in ["d1", "d2"]:
471 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
472 result
= verify_attributes_for_evpn_routes(
473 tgen
, topo
, dut
, input_routes
, rd
="100.100.100.100:100"
475 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
480 "Configure RD for vrf BLUE manually same as vrf RED "
481 "(100.100.100.100:100) and advertise vrf RED and BLUE's routes "
482 "in EVPN address family from Edge-1 router."
492 "l2vpn": {"evpn": {"rd": "100.100.100.100:100"}}
499 result
= create_router_bgp(tgen
, topo
, input_dict_rd
)
500 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
503 "Delete manually configured RD and advertise vrf RED's routes "
504 "in EVPN address family from Edge-1 router."
514 "l2vpn": {"evpn": {"no rd": "100.100.100.100:100"}}
521 result
= create_router_bgp(tgen
, topo
, input_dict_rd
)
522 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
525 "Configure same RD value for vrf GREEN, as auto generated RD "
526 "value for vrf RED on Edge-1 router."
535 "address_family": {"l2vpn": {"evpn": {"rd": "10.0.0.33:1"}}},
541 result
= create_router_bgp(tgen
, topo
, input_dict_rd
)
542 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
544 step("Delete auto configured RD value from vrf RED in EVPN " "address family.")
552 "address_family": {"l2vpn": {"evpn": {"no rd": "10.0.0.33:1"}}},
558 result
= create_router_bgp(tgen
, topo
, input_dict_rd
)
559 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
561 step("Configure RD value as 100.100.100:100")
569 "address_family": {"l2vpn": {"evpn": {"rd": "100.100.100:100"}}},
575 result
= create_router_bgp(tgen
, topo
, input_dict_rd
)
576 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
578 write_test_footer(tc_name
)
581 def test_RT_verification_manual_p0(request
):
583 RT verification(manual)
587 tc_name
= request
.node
.name
588 write_test_header(tc_name
)
589 check_router_status(tgen
)
590 reset_config_on_routers(tgen
)
591 add_default_routes(tgen
)
593 if tgen
.routers_have_failure():
594 pytest
.skip(tgen
.errors
)
597 "Advertise prefixes from VNF routers R1 and R2 in associated "
598 "VRFs for both address-family."
600 step("Advertise VRF routes as in EVPN address family from Edge-1 " "router.")
602 for addr_type
in ADDR_TYPES
:
607 "network": NETWORK1_1
[addr_type
],
608 "next_hop": NEXT_HOP_IP
[addr_type
],
616 "network": NETWORK2_1
[addr_type
],
617 "next_hop": NEXT_HOP_IP
[addr_type
],
621 "network": NETWORK3_1
[addr_type
],
622 "next_hop": NEXT_HOP_IP
[addr_type
],
629 result
= create_static_routes(tgen
, input_dict_1
)
630 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
635 "Configure RT for vrf RED manually as export 100:100 "
636 "and advertise vrf RED's routes in EVPN address family"
637 " from Edge-1 router."
648 "unicast": {"neighbor": {"r1": {"dest_link": {"e1": {}}}}}
651 "unicast": {"neighbor": {"r1": {"dest_link": {"e1": {}}}}}
654 "evpn": {"route-target": {"export": [{"value": "100:100"}]}}
662 result
= create_router_bgp(tgen
, topo
, input_dict_rt
)
663 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
666 "Verify on dcg-1 and dcg-2, EVPN route for 10.1.1.1/32"
667 " and 10::1/128 have RT value as 100:100."
670 for dut
in ["d1", "d2"]:
671 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
672 result
= verify_attributes_for_evpn_routes(
673 tgen
, topo
, dut
, input_routes
, rt
="100:100"
675 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
680 "Configure RT for vrf RED manually as export 500:500 and"
681 " advertise vrf RED's routes in EVPN address family from"
693 "evpn": {"route-target": {"export": [{"value": "500:500"}]}}
701 result
= create_router_bgp(tgen
, topo
, input_dict_rt
)
702 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
705 "Verify on dcg-1 and dcg-2, EVPN route for 10.1.1.1/32"
706 " and 10::1/128 have RT value as 500:500."
709 for dut
in ["d1", "d2"]:
710 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
711 result
= verify_attributes_for_evpn_routes(
712 tgen
, topo
, dut
, input_routes
, rt
=["100:100", "500:500"]
714 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
719 "Import RT value 100:100 and 500:500 in vrf BLUE manually on"
720 " peer router DCG-1 and DCG-2."
734 {"value": "100:100"},
735 {"value": "500:500"},
754 {"value": "100:100"},
755 {"value": "500:500"},
766 result
= create_router_bgp(tgen
, topo
, input_dict_rt
)
767 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
770 "EVPN route for 10.1.1.1/32 and 10::1 should be installed "
771 "in vrf BLUE on DCG-1 and DCG-2 and further advertised to "
775 for addr_type
in ADDR_TYPES
:
778 "static_routes": [{"network": [NETWORK1_1
[addr_type
]], "vrf": "BLUE"}]
781 result
= verify_rib(tgen
, addr_type
, "d1", input_routes
)
782 assert result
is True, "Testcase {} :Failed \n Error {}".format(tc_name
, result
)
784 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
)
785 assert result
is True, "Testcase {} :Failed \n Error {}".format(tc_name
, result
)
788 "Delete import RT value 500:500 in vrf BLUE manually on "
789 "peer router DCG-1 and DCG-2."
802 "import": [{"value": "500:500", "delete": True}]
819 "import": [{"value": "500:500", "delete": True}]
829 result
= create_router_bgp(tgen
, topo
, input_dict_rt
)
830 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
832 for dut
in ["d1", "d2"]:
833 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
834 result
= verify_attributes_for_evpn_routes(
835 tgen
, topo
, dut
, input_routes
, rt
=["100:100", "500:500"]
837 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
841 step("Delete RT export value 100:100 for vrf RED on Edge-1")
853 "export": [{"value": "100:100", "delete": True}]
863 result
= create_router_bgp(tgen
, topo
, input_dict_rt
)
864 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
867 "EVPN route for 10.1.1.1/32 and 10::1 should be withdrawn "
868 "from vrf BLUE on DCG-1,DCG-2 and VNF router."
871 for addr_type
in ADDR_TYPES
:
874 "static_routes": [{"network": [NETWORK1_1
[addr_type
]], "vrf": "BLUE"}]
877 result
= verify_rib(tgen
, addr_type
, "d1", input_routes
, expected
=False)
878 assert result
is not True, (
879 "Testcase {} :Failed \n Expected Behavior: Routes are still "
880 "present \n Error: {}".format(tc_name
, result
)
882 logger
.info("Expected Behavior: {}".format(result
))
884 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
, expected
=False)
885 assert result
is not True, (
886 "Testcase {} :Failed \n Expected Behavior: Routes are still "
887 "present \n Error: {}".format(tc_name
, result
)
889 logger
.info("Expected Behavior: {}".format(result
))
892 "Configure RT value as 100:100000010000010000101010 to check "
893 "the boundary value."
907 {"value": "100:100000010000010000101010"}
918 result
= create_router_bgp(tgen
, topo
, input_dict_rt
)
919 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
922 "CLI error: RT value: 100:100000010000010000101010 should not " "be configured"
926 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
927 result
= verify_attributes_for_evpn_routes(
928 tgen
, topo
, dut
, input_routes
, rt
="100:100000010000010000101010", expected
=False
930 assert result
is not True, (
931 "Testcase {} :Failed \n Expected Behavior: RT value of out"
932 " of boundary \n Error: {}".format(tc_name
, result
)
934 logger
.info("Expected Behavior: {}".format(result
))
936 write_test_footer(tc_name
)
939 def test_active_standby_evpn_implementation_p1(request
):
941 In an active/standby EVPN implementation, if active DCG goes down,
942 secondary takes over.
946 tc_name
= request
.node
.name
947 write_test_header(tc_name
)
948 check_router_status(tgen
)
949 reset_config_on_routers(tgen
)
950 add_default_routes(tgen
)
952 if tgen
.routers_have_failure():
953 pytest
.skip(tgen
.errors
)
956 "Taken care in base config: Configure BGP neighborship for both "
957 "address families(IPv4 & IPv6) between DCG-1/DCG-2 and VFN routers"
962 "BGP neighborships come up within defined VRFs. Please use below "
963 "command: sh bgp vrf all summary"
966 result
= verify_bgp_convergence(tgen
, topo
, "d1")
967 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
969 result
= verify_bgp_convergence(tgen
, topo
, "d2")
970 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
973 "Advertise prefixes from VNF routers R3 and R4 in associated "
974 "VRFs for both address-families."
977 for addr_type
in ADDR_TYPES
:
982 "network": NETWORK1_2
[addr_type
],
983 "next_hop": NEXT_HOP_IP
[addr_type
],
991 "network": NETWORK1_3
[addr_type
],
992 "next_hop": NEXT_HOP_IP
[addr_type
],
996 "network": NETWORK1_4
[addr_type
],
997 "next_hop": NEXT_HOP_IP
[addr_type
],
1004 result
= create_static_routes(tgen
, input_dict_1
)
1005 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1010 "Redistribute static in (IPv4 and IPv6) address-family "
1011 "on Edge-1 for all VRFs."
1015 for dut
in ["r3", "r4"]:
1016 temp
= {dut
: {"bgp": []}}
1017 input_dict_2
.update(temp
)
1023 VRFS
= ["BLUE", "GREEN"]
1026 for vrf
, as_num
in zip(VRFS
, AS_NUM
):
1027 temp
[dut
]["bgp"].append(
1033 "unicast": {"redistribute": [{"redist_type": "static"}]}
1036 "unicast": {"redistribute": [{"redist_type": "static"}]}
1042 result
= create_router_bgp(tgen
, topo
, input_dict_2
)
1043 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1045 step("Prefixes are received in respective VRFs on DCG-1/DCG-2.")
1047 for addr_type
in ADDR_TYPES
:
1052 "network": NETWORK1_2
[addr_type
],
1053 "next_hop": NEXT_HOP_IP
[addr_type
],
1061 "network": NETWORK1_3
[addr_type
],
1062 "next_hop": NEXT_HOP_IP
[addr_type
],
1066 "network": NETWORK1_4
[addr_type
],
1067 "next_hop": NEXT_HOP_IP
[addr_type
],
1074 result
= verify_rib(tgen
, addr_type
, "d1", input_routes
)
1075 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1079 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
)
1080 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1085 "Taken care in base config: Advertise VRF routes in EVPN "
1086 "address-family from DCG-1 and DCG-2 router."
1089 step("Verify on Edge-1 that EVPN routes are installed via next-hop " "as DCG-2.")
1091 for addr_type
in ADDR_TYPES
:
1096 "network": NETWORK1_2
[addr_type
],
1097 "next_hop": NEXT_HOP_IP
[addr_type
],
1105 "network": NETWORK1_3
[addr_type
],
1106 "next_hop": NEXT_HOP_IP
[addr_type
],
1110 "network": NETWORK1_4
[addr_type
],
1111 "next_hop": NEXT_HOP_IP
[addr_type
],
1118 if addr_type
== "ipv4":
1119 result
= verify_rib(
1120 tgen
, addr_type
, "e1", input_routes
, next_hop
=BRIDGE_INTF2
1122 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1126 result
= verify_rib(tgen
, addr_type
, "e1", input_routes
)
1127 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1132 "Configure 'next-hop self' on DCG-1 for peer Edge-1 in EVPN " "address-family."
1145 "ipv4": {"d1-link1": {"next_hop_self": True}}
1156 result
= create_router_bgp(tgen
, topo
, input_dict_3
)
1157 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1160 "Creating route-map so ipv6 glpbal ip wpuld be preferred " "as next-hop"
1164 "Verify on Edge-1 that EVPN routes are now preferred via "
1165 "next-hop as DCG-1(iBGP) due to shortest AS-Path."
1168 for addr_type
in ADDR_TYPES
:
1170 logger
.info("Verifying only ipv4 routes")
1171 if addr_type
!= "ipv4":
1178 "network": NETWORK1_2
[addr_type
],
1179 "next_hop": NEXT_HOP_IP
[addr_type
],
1187 "network": NETWORK1_3
[addr_type
],
1188 "next_hop": NEXT_HOP_IP
[addr_type
],
1192 "network": NETWORK1_4
[addr_type
],
1193 "next_hop": NEXT_HOP_IP
[addr_type
],
1200 next_hop
= topo
["routers"]["d1"]["links"]["e1-link1"]["ipv4"].split("/")[0]
1202 result
= verify_rib(tgen
, addr_type
, "e1", input_routes
, next_hop
=next_hop
)
1203 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1207 write_test_footer(tc_name
)
1210 def test_evpn_routes_from_VNFs_p1(request
):
1212 EVPN routes are advertised/withdrawn, based on VNFs
1213 advertising/withdrawing IP prefixes.
1216 tgen
= get_topogen()
1217 tc_name
= request
.node
.name
1218 write_test_header(tc_name
)
1219 check_router_status(tgen
)
1220 reset_config_on_routers(tgen
)
1221 add_default_routes(tgen
)
1223 if tgen
.routers_have_failure():
1224 pytest
.skip(tgen
.errors
)
1227 "Advertise prefixes from VNF routers R1 and R2 in associated "
1228 "VRFs for both address-family."
1231 for addr_type
in ADDR_TYPES
:
1236 "network": NETWORK1_1
[addr_type
],
1237 "next_hop": NEXT_HOP_IP
[addr_type
],
1245 "network": NETWORK2_1
[addr_type
],
1246 "next_hop": NEXT_HOP_IP
[addr_type
],
1250 "network": NETWORK3_1
[addr_type
],
1251 "next_hop": NEXT_HOP_IP
[addr_type
],
1258 result
= create_static_routes(tgen
, input_dict_1
)
1259 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1264 "Taken care in base config: Advertise VNFs'(R1 and R2) "
1265 "originated routes in EVPN address-family from Edge-1 to "
1266 "DCG-1 and DCG-2 routers."
1269 "Taken care in base config: Advertise IPv4 and IPv6 routes "
1270 "from default vrf in EVPN address-family from Edge-1."
1274 "Verify on DCG-2 that VNF routes are received in respective "
1275 "VRFs along with auto derived RD/RT values 'show bgp l2vpn evpn'"
1277 for dut
in ["d1", "d2"]:
1278 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1279 result
= verify_evpn_routes(tgen
, topo
, dut
, input_routes
)
1280 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1284 input_routes
= {key
: topo
["routers"][key
] for key
in ["r2"]}
1285 result
= verify_evpn_routes(tgen
, topo
, dut
, input_routes
)
1286 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1291 "Verify on R3 and R4 that DCG-2 further advertises all EVPN "
1292 "routes to corresponding VRFs."
1294 for addr_type
in ADDR_TYPES
:
1295 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1296 result
= verify_rib(tgen
, addr_type
, "r3", input_routes
)
1297 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1301 for addr_type
in ADDR_TYPES
:
1302 input_routes
= {key
: topo
["routers"][key
] for key
in ["r2"]}
1303 result
= verify_rib(tgen
, addr_type
, "r4", input_routes
)
1304 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1309 "Verify that DCG-2 receives EVPN routes associated to default "
1310 "VRF and install in default IP routing table as well."
1312 for addr_type
in ADDR_TYPES
:
1313 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1314 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
, expected
=False)
1315 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1319 for addr_type
in ADDR_TYPES
:
1320 input_routes
= {key
: topo
["routers"][key
] for key
in ["r2"]}
1321 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
, expected
=False)
1322 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1326 step("Withdraw the IP prefixes from VFN(R1).")
1329 static_routes
= topo
["routers"][dut
]["static_routes"]
1330 for static_route
in static_routes
:
1331 static_route
["delete"] = True
1332 temp
= {dut
: {"static_routes": [static_route
]}}
1333 input_dict_2
.update(temp
)
1335 result
= create_static_routes(tgen
, input_dict_2
)
1336 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1341 "Verify that DCG-2 removes EVPN routes corresponding to vrf RED and "
1342 "send an withdraw to VNF(R3) as well."
1344 for addr_type
in ADDR_TYPES
:
1345 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1346 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
, expected
=False)
1347 assert result
is not True, "Testcase {} :Failed \n "
1348 "Routes are still present: {}".format(tc_name
, result
)
1349 logger
.info("Expected Behavior: {}".format(result
))
1351 for addr_type
in ADDR_TYPES
:
1352 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1353 result
= verify_rib(tgen
, addr_type
, "r3", input_routes
, expected
=False)
1354 assert result
is not True, "Testcase {} :Failed \n "
1355 "Routes are still present: {}".format(tc_name
, result
)
1356 logger
.info("Expected Behavior: {}".format(result
))
1358 step("Re-advertise IP prefixes from VFN(R1).")
1360 "Advertise prefixes from VNF routers R1 and R2 in associated "
1361 "VRFs for both address-family."
1364 for addr_type
in ADDR_TYPES
:
1369 "network": NETWORK1_1
[addr_type
],
1370 "next_hop": NEXT_HOP_IP
[addr_type
],
1378 "network": NETWORK2_1
[addr_type
],
1379 "next_hop": NEXT_HOP_IP
[addr_type
],
1383 "network": NETWORK3_1
[addr_type
],
1384 "next_hop": NEXT_HOP_IP
[addr_type
],
1391 result
= create_static_routes(tgen
, input_dict_1
)
1392 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1397 "Verify that DCG-2 receives EVPN routes corresponding to vrf RED "
1398 "again and send an update to VNF(R3) as well."
1400 for addr_type
in ADDR_TYPES
:
1401 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1402 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
)
1403 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1407 for addr_type
in ADDR_TYPES
:
1408 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1409 result
= verify_rib(tgen
, addr_type
, "r3", input_routes
)
1410 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1414 step("Delete vrf BLUE from router Edge-1")
1415 input_dict_3
= {"e1": {"vrfs": [{"name": "BLUE", "id": "2", "delete": True}]}}
1417 result
= create_vrf_cfg(tgen
, input_dict_3
)
1418 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1421 "Verify that DCG-2 removes EVPN routes corresponding to "
1422 "vrf BLUE and send an withdraw to VNF(R4) as well."
1424 for addr_type
in ADDR_TYPES
:
1426 "r2": {"static_routes": [{"network": NETWORK2_1
[addr_type
], "vrf": "BLUE"}]}
1429 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
, expected
=False)
1430 assert result
is not True, "Testcase {} :Failed \n "
1431 "Routes are still present: {}".format(tc_name
, result
)
1432 logger
.info("Expected Behavior: {}".format(result
))
1434 result
= verify_rib(tgen
, addr_type
, "r4", input_routes
, expected
=False)
1435 assert result
is not True, "Testcase {} :Failed \n "
1436 "Routes are still present: {}".format(tc_name
, result
)
1437 logger
.info("Expected Behavior: {}".format(result
))
1439 step("Add vrf BLUE on router Edge-1 again.")
1440 interface
= topo
["routers"]["e1"]["links"]["r2-link1"]["interface"]
1445 "interface": interface
,
1451 "vrfs": [{"name": "BLUE", "id": "2"}],
1454 result
= create_vrf_cfg(tgen
, input_dict_3
)
1455 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1458 "After deleting VRFs ipv6 addresses wil be deleted "
1459 "from kernel Adding back ipv6 addresses"
1465 for c_link
, c_data
in topo
["routers"][dut
]["links"].items():
1467 if c_data
["vrf"] != vrf
:
1470 intf_name
= c_data
["interface"]
1471 intf_ipv6
= c_data
["ipv6"]
1473 create_interface_in_kernel(
1474 tgen
, dut
, intf_name
, intf_ipv6
, vrf
, create
=False
1477 logger
.info("Wait for 60 sec.")
1481 "Verify that DCG-2 receives EVPN routes corresponding to "
1482 "vrf BLUE again and send an update to VNF(R4) as well."
1484 for addr_type
in ADDR_TYPES
:
1486 "r2": {"static_routes": [{"network": NETWORK2_1
[addr_type
], "vrf": "BLUE"}]}
1489 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
)
1490 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1494 result
= verify_rib(tgen
, addr_type
, "r4", input_routes
)
1495 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1499 step("Withdraw IPv6 address-family in EVPN advertisements for " "VRF GREEN")
1510 "advertise": {addr_type
: {"unicast": {"delete": True}}}
1519 result
= create_router_bgp(tgen
, topo
, input_dict_4
)
1520 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1523 "Verify that EVPN routes (IPv6)associated with vrf GREEN are "
1524 "withdrawn from DCG-2 and VNF R4."
1527 "r2": {"static_routes": [{"network": NETWORK3_1
[addr_type
], "vrf": "GREEN"}]}
1530 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
, expected
=False)
1531 assert result
is not True, "Testcase {} :Failed \n "
1532 "Routes are still present: {}".format(tc_name
, result
)
1533 logger
.info("Expected Behavior: {}".format(result
))
1535 result
= verify_rib(tgen
, addr_type
, "r4", input_routes
, expected
=False)
1536 assert result
is not True, "Testcase {} :Failed \n "
1537 "Routes are still present: {}".format(tc_name
, result
)
1538 logger
.info("Expected Behavior: {}".format(result
))
1540 step("Advertise IPv6 address-family in EVPN advertisements " "for VRF GREEN.")
1549 "l2vpn": {"evpn": {"advertise": {addr_type
: {"unicast": {}}}}}
1556 result
= create_router_bgp(tgen
, topo
, input_dict_4
)
1557 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1559 for addr_type
in ADDR_TYPES
:
1562 "static_routes": [{"network": NETWORK3_1
[addr_type
], "vrf": "GREEN"}]
1566 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
)
1567 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1571 result
= verify_rib(tgen
, addr_type
, "r4", input_routes
)
1572 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1576 write_test_footer(tc_name
)
1579 @pytest.mark
.parametrize(
1580 "attribute", [{"route-type": "prefix"}, {"vni": VNI_1
}, {"rt": "300:300"}]
1582 def test_route_map_operations_for_evpn_address_family_p1(request
, attribute
):
1584 Route-map operations for EVPN address family.
1587 tgen
= get_topogen()
1588 tc_name
= request
.node
.name
1589 write_test_header(tc_name
)
1590 check_router_status(tgen
)
1591 reset_config_on_routers(tgen
)
1592 add_default_routes(tgen
)
1595 "Advertise prefixes from VNF routers R1 and R2 in associated "
1596 "VRFs for both address-family."
1599 for addr_type
in ADDR_TYPES
:
1604 "network": NETWORK1_1
[addr_type
],
1605 "next_hop": NEXT_HOP_IP
[addr_type
],
1613 "network": NETWORK2_1
[addr_type
],
1614 "next_hop": NEXT_HOP_IP
[addr_type
],
1618 "network": NETWORK3_1
[addr_type
],
1619 "next_hop": NEXT_HOP_IP
[addr_type
],
1626 result
= create_static_routes(tgen
, input_dict_1
)
1627 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1631 if tgen
.routers_have_failure():
1632 pytest
.skip(tgen
.errors
)
1635 "Advertise VRF routes in EVPN address family from Edge-1 router."
1636 " Configure a route-map on e1 to filter EVPN routes based on"
1637 " below keywords: route-type: prefix"
1640 for key
, value
in attribute
.items():
1642 logger
.info("Creating extcommunity using raw_config")
1646 "bgp extcommunity-list standard ECOMM300 permit {} {}".format(
1652 result
= apply_raw_config(tgen
, raw_config
)
1653 assert result
is True, "Testcase {} : Failed Error: {}".format(
1660 "rmap_route_type": [
1661 {"action": "permit", "set": {"extcommunity": {key
: value
}}}
1667 "rmap_route_type": [
1668 {"action": "permit", "match": {"extcommunity": "ECOMM300"}}
1678 "rmap_route_type": [
1679 {"action": "permit", "match": {"evpn": {key
: value
}}}
1685 "rmap_route_type": [
1686 {"action": "permit", "match": {"evpn": {key
: value
}}}
1691 result
= create_route_maps(tgen
, input_dict_1
)
1692 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1710 "name": "rmap_route_type",
1737 "name": "rmap_route_type",
1753 result
= create_router_bgp(tgen
, topo
, input_dict_2
)
1754 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1757 "Verify on router DCG-2 that EVPN routes corresponding to all "
1758 "VRFs are received. As all EVPN routes are type-5 only."
1761 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1762 result
= verify_evpn_routes(tgen
, topo
, "d2", input_routes
)
1763 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1765 input_routes
= {key
: topo
["routers"][key
] for key
in ["r2"]}
1766 result
= verify_evpn_routes(tgen
, topo
, "d2", input_routes
)
1767 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1769 write_test_footer(tc_name
)
1772 @pytest.mark
.parametrize("attribute", ["locPrf", "weight", "path"])
1773 def test_bgp_attributes_for_evpn_address_family_p1(request
, attribute
):
1775 BGP attributes for EVPN address-family.
1778 tgen
= get_topogen()
1779 tc_name
= request
.node
.name
1780 write_test_header(tc_name
)
1781 check_router_status(tgen
)
1782 reset_config_on_routers(tgen
)
1783 add_default_routes(tgen
)
1785 if tgen
.routers_have_failure():
1786 pytest
.skip(tgen
.errors
)
1789 "Advertise prefixes from VNF routers R1 and R2 in associated "
1790 "VRFs for both address-family."
1793 for addr_type
in ADDR_TYPES
:
1798 "network": NETWORK1_1
[addr_type
],
1799 "next_hop": NEXT_HOP_IP
[addr_type
],
1807 "network": NETWORK2_1
[addr_type
],
1808 "next_hop": NEXT_HOP_IP
[addr_type
],
1812 "network": NETWORK3_1
[addr_type
],
1813 "next_hop": NEXT_HOP_IP
[addr_type
],
1820 result
= create_static_routes(tgen
, input_dict_1
)
1821 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1825 topo_local
= deepcopy(topo
)
1827 logger
.info("Modifying topology b/w e1 and d1 from iBGP to eBGP")
1828 step("Delete BGP config for vrf RED.")
1830 if attribute
== "locPrf":
1834 {"name": "RED", "no_vni": VNI_1
},
1835 {"name": "BLUE", "no_vni": VNI_2
},
1836 {"name": "GREEN", "no_vni": VNI_3
},
1840 result
= create_vrf_cfg(tgen
, topo
, input_dict
=input_dict_vni
)
1841 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1847 temp
= {dut
: {"bgp": []}}
1848 input_dict_2
.update(temp
)
1850 INDEX
= [0, 1, 2, 3]
1851 VRFS
= ["RED", "BLUE", "GREEN", None]
1852 AS_NUM
= [100, 100, 100, 100]
1854 for index
, vrf
, as_num
in zip(INDEX
, VRFS
, AS_NUM
):
1855 topo_local
["routers"][dut
]["bgp"][index
]["local_as"] = 200
1857 temp
[dut
]["bgp"].append(
1858 {"local_as": as_num
, "vrf": vrf
, "delete": True}
1861 temp
[dut
]["bgp"].append({"local_as": as_num
, "delete": True})
1863 result
= create_router_bgp(tgen
, topo
, input_dict_2
)
1864 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1868 result
= create_router_bgp(tgen
, topo_local
["routers"])
1869 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1873 step("Advertise VRF routes in EVPN address-family from DCG-1 " "and DCG-2 routers.")
1875 for addr_type
in ADDR_TYPES
:
1880 "network": NETWORK1_2
[addr_type
],
1881 "next_hop": NEXT_HOP_IP
[addr_type
],
1889 "network": NETWORK1_3
[addr_type
],
1890 "next_hop": NEXT_HOP_IP
[addr_type
],
1894 "network": NETWORK1_4
[addr_type
],
1895 "next_hop": NEXT_HOP_IP
[addr_type
],
1902 result
= create_static_routes(tgen
, input_dict_1
)
1903 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1908 "Redistribute static in (IPv4 and IPv6) address-family "
1909 "on Edge-1 for all VRFs."
1913 for dut
in ["r3", "r4"]:
1914 temp
= {dut
: {"bgp": []}}
1915 input_dict_2
.update(temp
)
1921 VRFS
= ["BLUE", "GREEN"]
1924 for vrf
, as_num
in zip(VRFS
, AS_NUM
):
1925 temp
[dut
]["bgp"].append(
1931 "unicast": {"redistribute": [{"redist_type": "static"}]}
1934 "unicast": {"redistribute": [{"redist_type": "static"}]}
1940 result
= create_router_bgp(tgen
, topo
, input_dict_2
)
1941 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1944 "Verify on router Edge-1 that EVPN routes corresponding to "
1945 "all VRFs are received from both routers DCG-1 and DCG-2"
1948 for addr_type
in ADDR_TYPES
:
1953 "network": NETWORK1_2
[addr_type
],
1954 "next_hop": NEXT_HOP_IP
[addr_type
],
1962 "network": NETWORK1_3
[addr_type
],
1963 "next_hop": NEXT_HOP_IP
[addr_type
],
1967 "network": NETWORK1_4
[addr_type
],
1968 "next_hop": NEXT_HOP_IP
[addr_type
],
1975 result
= verify_rib(tgen
, addr_type
, "e1", input_routes
)
1976 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1981 "Configure a route-map on Edge-1 to modify below BGP attributes "
1982 "for EVPN address-family:"
1985 if attribute
== "path":
1989 "rmap_d1".format(addr_type
): [
1994 "as_num": "123 231 321",
1995 "as_action": "prepend",
2000 "rmap_d2".format(addr_type
): [
2004 attribute
: {"as_num": "121", "as_action": "prepend"}
2015 "rmap_d1".format(addr_type
): [
2016 {"action": "permit", "set": {attribute
: 120}}
2018 "rmap_d2".format(addr_type
): [
2019 {"action": "permit", "set": {attribute
: 150}}
2024 result
= create_route_maps(tgen
, input_dict_1
)
2025 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
2069 result
= create_router_bgp(tgen
, topo
, input_dict_2
)
2070 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
2073 "Verify on router Edge-1 that EVPN routes are preferred via"
2074 " DCG-1 or DCG-2 based on best path selection criteria "
2075 "(according to the configured BGP attribute values in route-map)."
2078 for addr_type
in ADDR_TYPES
:
2083 "network": NETWORK1_2
[addr_type
],
2084 "next_hop": NEXT_HOP_IP
[addr_type
],
2092 "network": NETWORK1_3
[addr_type
],
2093 "next_hop": NEXT_HOP_IP
[addr_type
],
2097 "network": NETWORK1_4
[addr_type
],
2098 "next_hop": NEXT_HOP_IP
[addr_type
],
2105 result
= verify_best_path_as_per_bgp_attribute(
2106 tgen
, addr_type
, "e1", input_routes
, attribute
2108 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
2112 write_test_footer(tc_name
)
2115 if __name__
== "__main__":
2116 args
= ["-s"] + sys
.argv
[1:]
2117 sys
.exit(pytest
.main(args
))