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:
184 'EVPN tests will not run (have kernel "{}", '
185 "but it requires >= 4.19)".format(platform
.release())
187 pytest
.skip(error_msg
)
189 global BGP_CONVERGENCE
191 ADDR_TYPES
= check_address_types()
193 BGP_CONVERGENCE
= verify_bgp_convergence(tgen
, topo
)
194 assert BGP_CONVERGENCE
is True, "setup_module :Failed \n Error: {}".format(
198 logger
.info("Pre-requisite config for testsuite")
199 prerequisite_config_for_test_suite(tgen
)
201 logger
.info("Running setup_module() done")
204 def teardown_module():
205 """Teardown the pytest environment"""
207 logger
.info("Running teardown_module to delete topology")
211 # Stop toplogy and Remove tmp files
215 "Testsuite end time: {}".format(time
.asctime(time
.localtime(time
.time())))
217 logger
.info("=" * 40)
220 #####################################################
224 #####################################################
227 def prerequisite_config_for_test_suite(tgen
):
229 API to do prerequisite config for testsuite
233 * `tgen`: topogen object
236 step("Configure vxlan, bridge interface")
237 for dut
in ["e1", "d1", "d2"]:
238 step("[DUT: ]Configure vxlan")
243 "vxlan_name": VXLAN
["vxlan_name"],
244 "vxlan_id": VXLAN
["vxlan_id"],
245 "dstport": VXLAN
["dstport"],
246 "local_addr": VXLAN
["local_addr"][dut
],
247 "learning": VXLAN
["learning"],
253 result
= configure_vxlan(tgen
, vxlan_input
)
254 assert result
is True, "Testcase {} on {} :Failed \n Error: {}".format(
258 step("Configure bridge interface")
263 "brctl_name": BRCTL
["brctl_name"],
264 "addvxlan": BRCTL
["addvxlan"],
271 result
= configure_brctl(tgen
, topo
, brctl_input
)
272 assert result
is True, "Testcase {} on {} :Failed \n Error: {}".format(
276 step("Configure default routes")
277 add_default_routes(tgen
)
280 def add_default_routes(tgen
):
282 API to do prerequisite config for testsuite
286 * `tgen`: topogen object
289 step("Add default routes..")
295 "network": "{}/32".format(VXLAN
["local_addr"]["d1"]),
296 "next_hop": topo
["routers"]["d1"]["links"]["e1-link1"][
301 "network": "{}/32".format(VXLAN
["local_addr"]["d2"]),
302 "next_hop": topo
["routers"]["d2"]["links"]["e1-link1"][
311 "network": "{}/32".format(VXLAN
["local_addr"]["e1"]),
312 "next_hop": topo
["routers"]["e1"]["links"]["d1-link1"][
317 "network": "{}/32".format(VXLAN
["local_addr"]["d2"]),
318 "next_hop": topo
["routers"]["e1"]["links"]["d1-link1"][
327 "network": "{}/32".format(VXLAN
["local_addr"]["d1"]),
328 "next_hop": topo
["routers"]["e1"]["links"]["d2-link1"][
333 "network": "{}/32".format(VXLAN
["local_addr"]["e1"]),
334 "next_hop": topo
["routers"]["e1"]["links"]["d2-link1"][
342 result
= create_static_routes(tgen
, default_routes
)
343 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
346 def test_RD_verification_manual_and_auto_p0(request
):
348 RD verification (manual/auto).
352 tc_name
= request
.node
.name
353 write_test_header(tc_name
)
354 check_router_status(tgen
)
355 reset_config_on_routers(tgen
)
356 add_default_routes(tgen
)
358 if tgen
.routers_have_failure():
359 pytest
.skip(tgen
.errors
)
362 "Advertise prefixes from VNF routers R1 and R2 in associated "
363 "VRFs for both address-family."
366 "Advertise vrf RED's routes in EVPN address family from Edge-1 router"
367 ", without manual configuration of RD."
370 for addr_type
in ADDR_TYPES
:
375 "network": NETWORK1_1
[addr_type
],
376 "next_hop": NEXT_HOP_IP
[addr_type
],
384 "network": NETWORK2_1
[addr_type
],
385 "next_hop": NEXT_HOP_IP
[addr_type
],
389 "network": NETWORK3_1
[addr_type
],
390 "next_hop": NEXT_HOP_IP
[addr_type
],
397 result
= create_static_routes(tgen
, input_dict_1
)
398 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
402 step("Verify on DCG-1 and DCG-2:")
403 step("EVPN route for 10.1.1.1/32 has auto-assigned RD value.")
405 for dut
in ["d1", "d2"]:
406 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
407 result
= verify_attributes_for_evpn_routes(
408 tgen
, topo
, dut
, input_routes
, rd
="auto", rd_peer
="e1"
410 assert result
is True, "Testcase {} on {} :Failed \n Error: {}".format(
415 "Configure RD for vrf RED manually as 50.50.50.50:50 and "
416 "advertise vrf RED's routes in EVPN address family from "
426 "address_family": {"l2vpn": {"evpn": {"rd": "50.50.50.50:50"}}},
432 result
= create_router_bgp(tgen
, topo
, input_dict_rd
)
433 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
435 step("EVPN route for vrf RED has RD value as 50.50.50.50:50")
436 for dut
in ["d1", "d2"]:
437 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
438 result
= verify_attributes_for_evpn_routes(
439 tgen
, topo
, dut
, input_routes
, rd
="50.50.50.50:50"
441 assert result
is True, "Testcase {} on {} :Failed \n Error: {}".format(
446 "Configure RD for vrf RED manually as 100.100.100.100:100 and "
447 "advertise vrf RED's routes in EVPN address family from Edge-1 "
457 "l2vpn": {"evpn": {"rd": "100.100.100.100:100"}}
464 result
= create_router_bgp(tgen
, topo
, input_dict_rd
)
465 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
468 "EVPN route for vrf RED is overridden with RD value as " "100.100.100.100:100."
471 for dut
in ["d1", "d2"]:
472 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
473 result
= verify_attributes_for_evpn_routes(
474 tgen
, topo
, dut
, input_routes
, rd
="100.100.100.100:100"
476 assert result
is True, "Testcase {} on {} :Failed \n Error: {}".format(
481 "Configure RD for vrf BLUE manually same as vrf RED "
482 "(100.100.100.100:100) and advertise vrf RED and BLUE's routes "
483 "in EVPN address family from Edge-1 router."
493 "l2vpn": {"evpn": {"rd": "100.100.100.100:100"}}
500 result
= create_router_bgp(tgen
, topo
, input_dict_rd
)
501 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
504 "Delete manually configured RD and advertise vrf RED's routes "
505 "in EVPN address family from Edge-1 router."
515 "l2vpn": {"evpn": {"no rd": "100.100.100.100:100"}}
522 result
= create_router_bgp(tgen
, topo
, input_dict_rd
)
523 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
526 "Configure same RD value for vrf GREEN, as auto generated RD "
527 "value for vrf RED on Edge-1 router."
536 "address_family": {"l2vpn": {"evpn": {"rd": "10.0.0.33:1"}}},
542 result
= create_router_bgp(tgen
, topo
, input_dict_rd
)
543 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
545 step("Delete auto configured RD value from vrf RED in EVPN " "address family.")
553 "address_family": {"l2vpn": {"evpn": {"no rd": "10.0.0.33:1"}}},
559 result
= create_router_bgp(tgen
, topo
, input_dict_rd
)
560 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
562 step("Configure RD value as 100.100.100:100")
570 "address_family": {"l2vpn": {"evpn": {"rd": "100.100.100:100"}}},
576 result
= create_router_bgp(tgen
, topo
, input_dict_rd
)
577 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
579 write_test_footer(tc_name
)
582 def test_RT_verification_manual_p0(request
):
584 RT verification(manual)
588 tc_name
= request
.node
.name
589 write_test_header(tc_name
)
590 check_router_status(tgen
)
591 reset_config_on_routers(tgen
)
592 add_default_routes(tgen
)
594 if tgen
.routers_have_failure():
595 pytest
.skip(tgen
.errors
)
598 "Advertise prefixes from VNF routers R1 and R2 in associated "
599 "VRFs for both address-family."
601 step("Advertise VRF routes as in EVPN address family from Edge-1 " "router.")
603 for addr_type
in ADDR_TYPES
:
608 "network": NETWORK1_1
[addr_type
],
609 "next_hop": NEXT_HOP_IP
[addr_type
],
617 "network": NETWORK2_1
[addr_type
],
618 "next_hop": NEXT_HOP_IP
[addr_type
],
622 "network": NETWORK3_1
[addr_type
],
623 "next_hop": NEXT_HOP_IP
[addr_type
],
630 result
= create_static_routes(tgen
, input_dict_1
)
631 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
636 "Configure RT for vrf RED manually as export 100:100 "
637 "and advertise vrf RED's routes in EVPN address family"
638 " from Edge-1 router."
649 "unicast": {"neighbor": {"r1": {"dest_link": {"e1": {}}}}}
652 "unicast": {"neighbor": {"r1": {"dest_link": {"e1": {}}}}}
655 "evpn": {"route-target": {"export": [{"value": "100:100"}]}}
663 result
= create_router_bgp(tgen
, topo
, input_dict_rt
)
664 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
667 "Verify on dcg-1 and dcg-2, EVPN route for 10.1.1.1/32"
668 " and 10::1/128 have RT value as 100:100."
671 for dut
in ["d1", "d2"]:
672 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
673 result
= verify_attributes_for_evpn_routes(
674 tgen
, topo
, dut
, input_routes
, rt
="100:100"
676 assert result
is True, "Testcase {} on {} :Failed \n Error: {}".format(
681 "Configure RT for vrf RED manually as export 500:500 and"
682 " advertise vrf RED's routes in EVPN address family from"
694 "evpn": {"route-target": {"export": [{"value": "500:500"}]}}
702 result
= create_router_bgp(tgen
, topo
, input_dict_rt
)
703 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
706 "Verify on dcg-1 and dcg-2, EVPN route for 10.1.1.1/32"
707 " and 10::1/128 have RT value as 500:500."
710 for dut
in ["d1", "d2"]:
711 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
712 result
= verify_attributes_for_evpn_routes(
713 tgen
, topo
, dut
, input_routes
, rt
=["100:100", "500:500"]
715 assert result
is True, "Testcase {} on {} :Failed \n Error: {}".format(
720 "Import RT value 100:100 and 500:500 in vrf BLUE manually on"
721 " peer router DCG-1 and DCG-2."
735 {"value": "100:100"},
736 {"value": "500:500"},
755 {"value": "100:100"},
756 {"value": "500:500"},
767 result
= create_router_bgp(tgen
, topo
, input_dict_rt
)
768 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
771 "EVPN route for 10.1.1.1/32 and 10::1 should be installed "
772 "in vrf BLUE on DCG-1 and DCG-2 and further advertised to "
776 for addr_type
in ADDR_TYPES
:
779 "static_routes": [{"network": [NETWORK1_1
[addr_type
]], "vrf": "BLUE"}]
782 result
= verify_rib(tgen
, addr_type
, "d1", input_routes
)
783 assert result
is True, "Testcase {} :Failed \n Error {}".format(tc_name
, result
)
785 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
)
786 assert result
is True, "Testcase {} :Failed \n Error {}".format(tc_name
, result
)
789 "Delete import RT value 500:500 in vrf BLUE manually on "
790 "peer router DCG-1 and DCG-2."
803 "import": [{"value": "500:500", "delete": True}]
820 "import": [{"value": "500:500", "delete": True}]
830 result
= create_router_bgp(tgen
, topo
, input_dict_rt
)
831 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
833 for dut
in ["d1", "d2"]:
834 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
835 result
= verify_attributes_for_evpn_routes(
836 tgen
, topo
, dut
, input_routes
, rt
=["100:100", "500:500"]
838 assert result
is True, "Testcase {} on {} :Failed \n Error: {}".format(
842 step("Delete RT export value 100:100 for vrf RED on Edge-1")
854 "export": [{"value": "100:100", "delete": True}]
864 result
= create_router_bgp(tgen
, topo
, input_dict_rt
)
865 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
868 "EVPN route for 10.1.1.1/32 and 10::1 should be withdrawn "
869 "from vrf BLUE on DCG-1,DCG-2 and VNF router."
872 for addr_type
in ADDR_TYPES
:
875 "static_routes": [{"network": [NETWORK1_1
[addr_type
]], "vrf": "BLUE"}]
878 result
= verify_rib(tgen
, addr_type
, "d1", input_routes
, expected
=False)
879 assert result
is not True, (
880 "Testcase {} :Failed \n Expected Behavior: Routes are still "
881 "present \n Error: {}".format(tc_name
, result
)
883 logger
.info("Expected Behavior: {}".format(result
))
885 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
, expected
=False)
886 assert result
is not True, (
887 "Testcase {} :Failed \n Expected Behavior: Routes are still "
888 "present \n Error: {}".format(tc_name
, result
)
890 logger
.info("Expected Behavior: {}".format(result
))
893 "Configure RT value as 100:100000010000010000101010 to check "
894 "the boundary value."
908 {"value": "100:100000010000010000101010"}
919 result
= create_router_bgp(tgen
, topo
, input_dict_rt
)
920 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
923 "CLI error: RT value: 100:100000010000010000101010 should not " "be configured"
927 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
928 result
= verify_attributes_for_evpn_routes(
929 tgen
, topo
, dut
, input_routes
, rt
="100:100000010000010000101010", expected
=False
931 assert result
is not True, (
932 "Testcase {} :Failed \n Expected Behavior: RT value of out"
933 " of boundary \n Error: {}".format(tc_name
, result
)
935 logger
.info("Expected Behavior: {}".format(result
))
937 write_test_footer(tc_name
)
940 def test_active_standby_evpn_implementation_p1(request
):
942 In an active/standby EVPN implementation, if active DCG goes down,
943 secondary takes over.
947 tc_name
= request
.node
.name
948 write_test_header(tc_name
)
949 check_router_status(tgen
)
950 reset_config_on_routers(tgen
)
951 add_default_routes(tgen
)
953 if tgen
.routers_have_failure():
954 pytest
.skip(tgen
.errors
)
957 "Taken care in base config: Configure BGP neighborship for both "
958 "address families(IPv4 & IPv6) between DCG-1/DCG-2 and VFN routers"
963 "BGP neighborships come up within defined VRFs. Please use below "
964 "command: sh bgp vrf all summary"
967 result
= verify_bgp_convergence(tgen
, topo
, "d1")
968 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
970 result
= verify_bgp_convergence(tgen
, topo
, "d2")
971 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
974 "Advertise prefixes from VNF routers R3 and R4 in associated "
975 "VRFs for both address-families."
978 for addr_type
in ADDR_TYPES
:
983 "network": NETWORK1_2
[addr_type
],
984 "next_hop": NEXT_HOP_IP
[addr_type
],
992 "network": NETWORK1_3
[addr_type
],
993 "next_hop": NEXT_HOP_IP
[addr_type
],
997 "network": NETWORK1_4
[addr_type
],
998 "next_hop": NEXT_HOP_IP
[addr_type
],
1005 result
= create_static_routes(tgen
, input_dict_1
)
1006 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1011 "Redistribute static in (IPv4 and IPv6) address-family "
1012 "on Edge-1 for all VRFs."
1016 for dut
in ["r3", "r4"]:
1017 temp
= {dut
: {"bgp": []}}
1018 input_dict_2
.update(temp
)
1024 VRFS
= ["BLUE", "GREEN"]
1027 for vrf
, as_num
in zip(VRFS
, AS_NUM
):
1028 temp
[dut
]["bgp"].append(
1034 "unicast": {"redistribute": [{"redist_type": "static"}]}
1037 "unicast": {"redistribute": [{"redist_type": "static"}]}
1043 result
= create_router_bgp(tgen
, topo
, input_dict_2
)
1044 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1046 step("Prefixes are received in respective VRFs on DCG-1/DCG-2.")
1048 for addr_type
in ADDR_TYPES
:
1053 "network": NETWORK1_2
[addr_type
],
1054 "next_hop": NEXT_HOP_IP
[addr_type
],
1062 "network": NETWORK1_3
[addr_type
],
1063 "next_hop": NEXT_HOP_IP
[addr_type
],
1067 "network": NETWORK1_4
[addr_type
],
1068 "next_hop": NEXT_HOP_IP
[addr_type
],
1075 result
= verify_rib(tgen
, addr_type
, "d1", input_routes
)
1076 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1080 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
)
1081 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1086 "Taken care in base config: Advertise VRF routes in EVPN "
1087 "address-family from DCG-1 and DCG-2 router."
1090 step("Verify on Edge-1 that EVPN routes are installed via next-hop " "as DCG-2.")
1092 for addr_type
in ADDR_TYPES
:
1097 "network": NETWORK1_2
[addr_type
],
1098 "next_hop": NEXT_HOP_IP
[addr_type
],
1106 "network": NETWORK1_3
[addr_type
],
1107 "next_hop": NEXT_HOP_IP
[addr_type
],
1111 "network": NETWORK1_4
[addr_type
],
1112 "next_hop": NEXT_HOP_IP
[addr_type
],
1119 if addr_type
== "ipv4":
1120 result
= verify_rib(
1121 tgen
, addr_type
, "e1", input_routes
, next_hop
=BRIDGE_INTF2
1123 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1127 result
= verify_rib(tgen
, addr_type
, "e1", input_routes
)
1128 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1133 "Configure 'next-hop self' on DCG-1 for peer Edge-1 in EVPN " "address-family."
1146 "ipv4": {"d1-link1": {"next_hop_self": True}}
1157 result
= create_router_bgp(tgen
, topo
, input_dict_3
)
1158 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1161 "Creating route-map so ipv6 glpbal ip wpuld be preferred " "as next-hop"
1165 "Verify on Edge-1 that EVPN routes are now preferred via "
1166 "next-hop as DCG-1(iBGP) due to shortest AS-Path."
1169 for addr_type
in ADDR_TYPES
:
1171 logger
.info("Verifying only ipv4 routes")
1172 if addr_type
!= "ipv4":
1179 "network": NETWORK1_2
[addr_type
],
1180 "next_hop": NEXT_HOP_IP
[addr_type
],
1188 "network": NETWORK1_3
[addr_type
],
1189 "next_hop": NEXT_HOP_IP
[addr_type
],
1193 "network": NETWORK1_4
[addr_type
],
1194 "next_hop": NEXT_HOP_IP
[addr_type
],
1201 next_hop
= topo
["routers"]["d1"]["links"]["e1-link1"]["ipv4"].split("/")[0]
1203 result
= verify_rib(tgen
, addr_type
, "e1", input_routes
, next_hop
=next_hop
)
1204 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1208 write_test_footer(tc_name
)
1211 def test_evpn_routes_from_VNFs_p1(request
):
1213 EVPN routes are advertised/withdrawn, based on VNFs
1214 advertising/withdrawing IP prefixes.
1217 tgen
= get_topogen()
1218 tc_name
= request
.node
.name
1219 write_test_header(tc_name
)
1220 check_router_status(tgen
)
1221 reset_config_on_routers(tgen
)
1222 add_default_routes(tgen
)
1224 if tgen
.routers_have_failure():
1225 pytest
.skip(tgen
.errors
)
1228 "Advertise prefixes from VNF routers R1 and R2 in associated "
1229 "VRFs for both address-family."
1232 for addr_type
in ADDR_TYPES
:
1237 "network": NETWORK1_1
[addr_type
],
1238 "next_hop": NEXT_HOP_IP
[addr_type
],
1246 "network": NETWORK2_1
[addr_type
],
1247 "next_hop": NEXT_HOP_IP
[addr_type
],
1251 "network": NETWORK3_1
[addr_type
],
1252 "next_hop": NEXT_HOP_IP
[addr_type
],
1259 result
= create_static_routes(tgen
, input_dict_1
)
1260 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1265 "Taken care in base config: Advertise VNFs'(R1 and R2) "
1266 "originated routes in EVPN address-family from Edge-1 to "
1267 "DCG-1 and DCG-2 routers."
1270 "Taken care in base config: Advertise IPv4 and IPv6 routes "
1271 "from default vrf in EVPN address-family from Edge-1."
1275 "Verify on DCG-2 that VNF routes are received in respective "
1276 "VRFs along with auto derived RD/RT values 'show bgp l2vpn evpn'"
1278 for dut
in ["d1", "d2"]:
1279 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1280 result
= verify_evpn_routes(tgen
, topo
, dut
, input_routes
)
1281 assert result
is True, "Testcase {} on {} :Failed \n Error: {}".format(
1282 tc_name
, dut
, result
1285 input_routes
= {key
: topo
["routers"][key
] for key
in ["r2"]}
1286 result
= verify_evpn_routes(tgen
, topo
, dut
, input_routes
)
1287 assert result
is True, "Testcase {} on {} :Failed \n Error: {}".format(
1288 tc_name
, dut
, result
1292 "Verify on R3 and R4 that DCG-2 further advertises all EVPN "
1293 "routes to corresponding VRFs."
1295 for addr_type
in ADDR_TYPES
:
1296 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1297 result
= verify_rib(tgen
, addr_type
, "r3", input_routes
)
1298 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1302 for addr_type
in ADDR_TYPES
:
1303 input_routes
= {key
: topo
["routers"][key
] for key
in ["r2"]}
1304 result
= verify_rib(tgen
, addr_type
, "r4", input_routes
)
1305 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1310 "Verify that DCG-2 receives EVPN routes associated to default "
1311 "VRF and install in default IP routing table as well."
1313 for addr_type
in ADDR_TYPES
:
1314 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1315 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
, expected
=False)
1316 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1320 for addr_type
in ADDR_TYPES
:
1321 input_routes
= {key
: topo
["routers"][key
] for key
in ["r2"]}
1322 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
, expected
=False)
1323 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1327 step("Withdraw the IP prefixes from VFN(R1).")
1330 static_routes
= topo
["routers"][dut
]["static_routes"]
1331 for static_route
in static_routes
:
1332 static_route
["delete"] = True
1333 temp
= {dut
: {"static_routes": [static_route
]}}
1334 input_dict_2
.update(temp
)
1336 result
= create_static_routes(tgen
, input_dict_2
)
1337 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1342 "Verify that DCG-2 removes EVPN routes corresponding to vrf RED and "
1343 "send an withdraw to VNF(R3) as well."
1345 for addr_type
in ADDR_TYPES
:
1346 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1347 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
, expected
=False)
1348 assert result
is not True, "Testcase {} :Failed \n "
1349 "Routes are still present: {}".format(tc_name
, result
)
1350 logger
.info("Expected Behavior: {}".format(result
))
1352 for addr_type
in ADDR_TYPES
:
1353 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1354 result
= verify_rib(tgen
, addr_type
, "r3", input_routes
, expected
=False)
1355 assert result
is not True, "Testcase {} :Failed \n "
1356 "Routes are still present: {}".format(tc_name
, result
)
1357 logger
.info("Expected Behavior: {}".format(result
))
1359 step("Re-advertise IP prefixes from VFN(R1).")
1361 "Advertise prefixes from VNF routers R1 and R2 in associated "
1362 "VRFs for both address-family."
1365 for addr_type
in ADDR_TYPES
:
1370 "network": NETWORK1_1
[addr_type
],
1371 "next_hop": NEXT_HOP_IP
[addr_type
],
1379 "network": NETWORK2_1
[addr_type
],
1380 "next_hop": NEXT_HOP_IP
[addr_type
],
1384 "network": NETWORK3_1
[addr_type
],
1385 "next_hop": NEXT_HOP_IP
[addr_type
],
1392 result
= create_static_routes(tgen
, input_dict_1
)
1393 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1398 "Verify that DCG-2 receives EVPN routes corresponding to vrf RED "
1399 "again and send an update to VNF(R3) as well."
1401 for addr_type
in ADDR_TYPES
:
1402 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1403 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
)
1404 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1408 for addr_type
in ADDR_TYPES
:
1409 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1410 result
= verify_rib(tgen
, addr_type
, "r3", input_routes
)
1411 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1415 step("Delete vrf BLUE from router Edge-1")
1416 input_dict_3
= {"e1": {"vrfs": [{"name": "BLUE", "id": "2", "delete": True}]}}
1418 result
= create_vrf_cfg(tgen
, input_dict_3
)
1419 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1422 "Verify that DCG-2 removes EVPN routes corresponding to "
1423 "vrf BLUE and send an withdraw to VNF(R4) as well."
1425 for addr_type
in ADDR_TYPES
:
1427 "r2": {"static_routes": [{"network": NETWORK2_1
[addr_type
], "vrf": "BLUE"}]}
1430 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
, expected
=False)
1431 assert result
is not True, "Testcase {} :Failed \n "
1432 "Routes are still present: {}".format(tc_name
, result
)
1433 logger
.info("Expected Behavior: {}".format(result
))
1435 result
= verify_rib(tgen
, addr_type
, "r4", input_routes
, expected
=False)
1436 assert result
is not True, "Testcase {} :Failed \n "
1437 "Routes are still present: {}".format(tc_name
, result
)
1438 logger
.info("Expected Behavior: {}".format(result
))
1440 step("Add vrf BLUE on router Edge-1 again.")
1441 interface
= topo
["routers"]["e1"]["links"]["r2-link1"]["interface"]
1446 "interface": interface
,
1452 "vrfs": [{"name": "BLUE", "id": "2"}],
1455 result
= create_vrf_cfg(tgen
, input_dict_3
)
1456 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1459 "After deleting VRFs ipv6 addresses wil be deleted "
1460 "from kernel Adding back ipv6 addresses"
1466 for c_link
, c_data
in topo
["routers"][dut
]["links"].items():
1468 if c_data
["vrf"] != vrf
:
1471 intf_name
= c_data
["interface"]
1472 intf_ipv6
= c_data
["ipv6"]
1474 create_interface_in_kernel(
1475 tgen
, dut
, intf_name
, intf_ipv6
, vrf
, create
=False
1478 logger
.info("Wait for 60 sec.")
1482 "Verify that DCG-2 receives EVPN routes corresponding to "
1483 "vrf BLUE again and send an update to VNF(R4) as well."
1485 for addr_type
in ADDR_TYPES
:
1487 "r2": {"static_routes": [{"network": NETWORK2_1
[addr_type
], "vrf": "BLUE"}]}
1490 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
)
1491 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1495 result
= verify_rib(tgen
, addr_type
, "r4", input_routes
)
1496 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1500 step("Withdraw IPv6 address-family in EVPN advertisements for " "VRF GREEN")
1511 "advertise": {addr_type
: {"unicast": {"delete": True}}}
1520 result
= create_router_bgp(tgen
, topo
, input_dict_4
)
1521 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1524 "Verify that EVPN routes (IPv6)associated with vrf GREEN are "
1525 "withdrawn from DCG-2 and VNF R4."
1528 "r2": {"static_routes": [{"network": NETWORK3_1
[addr_type
], "vrf": "GREEN"}]}
1531 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
, expected
=False)
1532 assert result
is not True, "Testcase {} :Failed \n "
1533 "Routes are still present: {}".format(tc_name
, result
)
1534 logger
.info("Expected Behavior: {}".format(result
))
1536 result
= verify_rib(tgen
, addr_type
, "r4", input_routes
, expected
=False)
1537 assert result
is not True, "Testcase {} :Failed \n "
1538 "Routes are still present: {}".format(tc_name
, result
)
1539 logger
.info("Expected Behavior: {}".format(result
))
1541 step("Advertise IPv6 address-family in EVPN advertisements " "for VRF GREEN.")
1550 "l2vpn": {"evpn": {"advertise": {addr_type
: {"unicast": {}}}}}
1557 result
= create_router_bgp(tgen
, topo
, input_dict_4
)
1558 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1560 for addr_type
in ADDR_TYPES
:
1563 "static_routes": [{"network": NETWORK3_1
[addr_type
], "vrf": "GREEN"}]
1567 result
= verify_rib(tgen
, addr_type
, "d2", input_routes
)
1568 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1572 result
= verify_rib(tgen
, addr_type
, "r4", input_routes
)
1573 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1577 write_test_footer(tc_name
)
1580 @pytest.mark
.parametrize(
1581 "attribute", [{"route-type": "prefix"}, {"vni": VNI_1
}, {"rt": "300:300"}]
1583 def test_route_map_operations_for_evpn_address_family_p1(request
, attribute
):
1585 Route-map operations for EVPN address family.
1588 tgen
= get_topogen()
1589 tc_name
= request
.node
.name
1590 write_test_header(tc_name
)
1591 check_router_status(tgen
)
1592 reset_config_on_routers(tgen
)
1593 add_default_routes(tgen
)
1596 "Advertise prefixes from VNF routers R1 and R2 in associated "
1597 "VRFs for both address-family."
1600 for addr_type
in ADDR_TYPES
:
1605 "network": NETWORK1_1
[addr_type
],
1606 "next_hop": NEXT_HOP_IP
[addr_type
],
1614 "network": NETWORK2_1
[addr_type
],
1615 "next_hop": NEXT_HOP_IP
[addr_type
],
1619 "network": NETWORK3_1
[addr_type
],
1620 "next_hop": NEXT_HOP_IP
[addr_type
],
1627 result
= create_static_routes(tgen
, input_dict_1
)
1628 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1632 if tgen
.routers_have_failure():
1633 pytest
.skip(tgen
.errors
)
1636 "Advertise VRF routes in EVPN address family from Edge-1 router."
1637 " Configure a route-map on e1 to filter EVPN routes based on"
1638 " below keywords: route-type: prefix"
1641 for key
, value
in attribute
.items():
1643 logger
.info("Creating extcommunity using raw_config")
1647 "bgp extcommunity-list standard ECOMM300 permit {} {}".format(
1653 result
= apply_raw_config(tgen
, raw_config
)
1654 assert result
is True, "Testcase {} : Failed Error: {}".format(
1661 "rmap_route_type": [
1662 {"action": "permit", "set": {"extcommunity": {key
: value
}}}
1668 "rmap_route_type": [
1669 {"action": "permit", "match": {"extcommunity": "ECOMM300"}}
1679 "rmap_route_type": [
1680 {"action": "permit", "match": {"evpn": {key
: value
}}}
1686 "rmap_route_type": [
1687 {"action": "permit", "match": {"evpn": {key
: value
}}}
1692 result
= create_route_maps(tgen
, input_dict_1
)
1693 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1711 "name": "rmap_route_type",
1738 "name": "rmap_route_type",
1754 result
= create_router_bgp(tgen
, topo
, input_dict_2
)
1755 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1758 "Verify on router DCG-2 that EVPN routes corresponding to all "
1759 "VRFs are received. As all EVPN routes are type-5 only."
1762 input_routes
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1763 result
= verify_evpn_routes(tgen
, topo
, "d2", input_routes
)
1764 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1766 input_routes
= {key
: topo
["routers"][key
] for key
in ["r2"]}
1767 result
= verify_evpn_routes(tgen
, topo
, "d2", input_routes
)
1768 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1770 write_test_footer(tc_name
)
1773 @pytest.mark
.parametrize("attribute", ["locPrf", "weight", "path"])
1774 def test_bgp_attributes_for_evpn_address_family_p1(request
, attribute
):
1776 BGP attributes for EVPN address-family.
1779 tgen
= get_topogen()
1780 tc_name
= request
.node
.name
1781 write_test_header(tc_name
)
1782 check_router_status(tgen
)
1783 reset_config_on_routers(tgen
)
1784 add_default_routes(tgen
)
1786 if tgen
.routers_have_failure():
1787 pytest
.skip(tgen
.errors
)
1790 "Advertise prefixes from VNF routers R1 and R2 in associated "
1791 "VRFs for both address-family."
1794 for addr_type
in ADDR_TYPES
:
1799 "network": NETWORK1_1
[addr_type
],
1800 "next_hop": NEXT_HOP_IP
[addr_type
],
1808 "network": NETWORK2_1
[addr_type
],
1809 "next_hop": NEXT_HOP_IP
[addr_type
],
1813 "network": NETWORK3_1
[addr_type
],
1814 "next_hop": NEXT_HOP_IP
[addr_type
],
1821 result
= create_static_routes(tgen
, input_dict_1
)
1822 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1826 topo_local
= deepcopy(topo
)
1828 logger
.info("Modifying topology b/w e1 and d1 from iBGP to eBGP")
1829 step("Delete BGP config for vrf RED.")
1831 if attribute
== "locPrf":
1835 {"name": "RED", "no_vni": VNI_1
},
1836 {"name": "BLUE", "no_vni": VNI_2
},
1837 {"name": "GREEN", "no_vni": VNI_3
},
1841 result
= create_vrf_cfg(tgen
, topo
, input_dict
=input_dict_vni
)
1842 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1848 temp
= {dut
: {"bgp": []}}
1849 input_dict_2
.update(temp
)
1851 INDEX
= [0, 1, 2, 3]
1852 VRFS
= ["RED", "BLUE", "GREEN", None]
1853 AS_NUM
= [100, 100, 100, 100]
1855 for index
, vrf
, as_num
in zip(INDEX
, VRFS
, AS_NUM
):
1856 topo_local
["routers"][dut
]["bgp"][index
]["local_as"] = 200
1858 temp
[dut
]["bgp"].append(
1859 {"local_as": as_num
, "vrf": vrf
, "delete": True}
1862 temp
[dut
]["bgp"].append({"local_as": as_num
, "delete": True})
1864 result
= create_router_bgp(tgen
, topo
, input_dict_2
)
1865 assert result
is True, "Testcase {} on d1 :Failed \n Error: {}".format(
1869 result
= create_router_bgp(tgen
, topo_local
["routers"])
1870 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1874 step("Advertise VRF routes in EVPN address-family from DCG-1 " "and DCG-2 routers.")
1876 for addr_type
in ADDR_TYPES
:
1881 "network": NETWORK1_2
[addr_type
],
1882 "next_hop": NEXT_HOP_IP
[addr_type
],
1890 "network": NETWORK1_3
[addr_type
],
1891 "next_hop": NEXT_HOP_IP
[addr_type
],
1895 "network": NETWORK1_4
[addr_type
],
1896 "next_hop": NEXT_HOP_IP
[addr_type
],
1903 result
= create_static_routes(tgen
, input_dict_1
)
1904 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
1909 "Redistribute static in (IPv4 and IPv6) address-family "
1910 "on Edge-1 for all VRFs."
1914 for dut
in ["r3", "r4"]:
1915 temp
= {dut
: {"bgp": []}}
1916 input_dict_2
.update(temp
)
1922 VRFS
= ["BLUE", "GREEN"]
1925 for vrf
, as_num
in zip(VRFS
, AS_NUM
):
1926 temp
[dut
]["bgp"].append(
1932 "unicast": {"redistribute": [{"redist_type": "static"}]}
1935 "unicast": {"redistribute": [{"redist_type": "static"}]}
1941 result
= create_router_bgp(tgen
, topo
, input_dict_2
)
1942 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
1945 "Verify on router Edge-1 that EVPN routes corresponding to "
1946 "all VRFs are received from both routers DCG-1 and DCG-2"
1949 for addr_type
in ADDR_TYPES
:
1954 "network": NETWORK1_2
[addr_type
],
1955 "next_hop": NEXT_HOP_IP
[addr_type
],
1963 "network": NETWORK1_3
[addr_type
],
1964 "next_hop": NEXT_HOP_IP
[addr_type
],
1968 "network": NETWORK1_4
[addr_type
],
1969 "next_hop": NEXT_HOP_IP
[addr_type
],
1976 result
= verify_rib(tgen
, addr_type
, "e1", input_routes
)
1977 assert result
is True, "Testcase {} :Failed \n Error: {}".format(
1982 "Configure a route-map on Edge-1 to modify below BGP attributes "
1983 "for EVPN address-family:"
1986 if attribute
== "path":
1990 "rmap_d1".format(addr_type
): [
1995 "as_num": "123 231 321",
1996 "as_action": "prepend",
2001 "rmap_d2".format(addr_type
): [
2005 attribute
: {"as_num": "121", "as_action": "prepend"}
2016 "rmap_d1".format(addr_type
): [
2017 {"action": "permit", "set": {attribute
: 120}}
2019 "rmap_d2".format(addr_type
): [
2020 {"action": "permit", "set": {attribute
: 150}}
2025 result
= create_route_maps(tgen
, input_dict_1
)
2026 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
2070 result
= create_router_bgp(tgen
, topo
, input_dict_2
)
2071 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
2074 "Verify on router Edge-1 that EVPN routes are preferred via"
2075 " DCG-1 or DCG-2 based on best path selection criteria "
2076 "(according to the configured BGP attribute values in route-map)."
2079 for addr_type
in ADDR_TYPES
:
2084 "network": NETWORK1_2
[addr_type
],
2085 "next_hop": NEXT_HOP_IP
[addr_type
],
2093 "network": NETWORK1_3
[addr_type
],
2094 "next_hop": NEXT_HOP_IP
[addr_type
],
2098 "network": NETWORK1_4
[addr_type
],
2099 "next_hop": NEXT_HOP_IP
[addr_type
],
2106 result
= verify_best_path_as_per_bgp_attribute(
2107 tgen
, addr_type
, "e1", input_routes
, attribute
2109 assert result
is True, "Testcase {} : Failed \n Error: {}".format(
2113 write_test_footer(tc_name
)
2116 if __name__
== "__main__":
2117 args
= ["-s"] + sys
.argv
[1:]
2118 sys
.exit(pytest
.main(args
))