]>
git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/bgp_evpn_overlay_index_gateway/test_bgp_evpn_overlay_index_gateway.py
3 # Copyright (c) 2020 by VMware, Inc. ("VMware")
4 # Used Copyright (c) 2018 by Network Device Education Foundation, Inc. ("NetDEF")
7 # Permission to use, copy, modify, and/or distribute this software
8 # for any purpose with or without fee is hereby granted, provided
9 # that the above copyright notice and this permission notice appear
12 # THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
13 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
15 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
16 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
17 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
18 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
23 test_bgp_evpn_overlay_index_gateway.py: Test EVPN gateway IP overlay index functionality
24 Following functionality is covered:
26 +--------+ BGP +--------+ BGP +--------+ +--------+
27 SN1 | | IPv4/v6 | | EVPN | | | |
28 ======+ Host1 +---------+ PE1 +------+ PE2 +------+ Host2 +
30 +--------+ +--------+ +--------+ +--------+
32 Host1 is connected to PE1 and host2 is connected to PE2
33 Host1 and PE1 have IPv4/v6 BGP sessions.
34 PE1 and PE2 gave EVPN session.
35 Host1 advertises IPv4/v6 prefixes to PE1.
36 PE1 advertises these prefixes to PE2 as EVPN type-5 routes.
37 Gateway IP for these EVPN type-5 routes is host1 IP.
38 Host1 MAC/IP is advertised by PE1 as EVPN type-2 route
40 Following testcases are covered:
42 Check BGP and zebra states for above topology at PE1 and PE2.
45 Stop advertising prefixes from host1. It should withdraw type-5 routes. Check states at PE1 and PE2
46 Advertise the prefixes again. Check states.
49 Shut down VxLAN interface at PE1. This should withdraw type-2 routes. Check states at PE1 and PE2.
50 Enable VxLAN interface again. Check states.
56 from functools
import partial
61 #Current Working Directory
62 CWD
= os
.path
.dirname(os
.path
.realpath(__file__
))
63 sys
.path
.append(os
.path
.join(CWD
, "../"))
65 # pylint: disable=C0413
66 # Import topogen and topotest helpers
67 from lib
import topotest
68 from lib
.topogen
import Topogen
, TopoRouter
, get_topogen
69 from lib
.topolog
import logger
70 from lib
.common_config
import (
74 generate_support_bundle
,
77 # Required to instantiate the topology builder class.
78 from lib
.micronet_compat
import Topo
80 pytestmark
= [pytest
.mark
.bgpd
]
85 HOSTS
= ['host1', 'host2']
86 PE_SUFFIX
= {'PE1': '1', 'PE2': '2'}
87 HOST_SUFFIX
= {'host1': '1', 'host2': '2'}
88 TRIGGERS
= ["base", "no_rt5", "no_rt2"]
92 # This function only purpose is to define allocation and relationship
93 # between routers and add links.
101 krel
= platform
.release()
102 logger
.info('Kernel version ' + krel
)
105 tgen
.add_link(tgen
.gears
['PE1'], tgen
.gears
['PE2'], 'PE1-eth0', 'PE2-eth0')
106 tgen
.add_link(tgen
.gears
['PE1'], tgen
.gears
['host1'], 'PE1-eth1', 'host1-eth0')
107 tgen
.add_link(tgen
.gears
['PE2'], tgen
.gears
['host2'], 'PE2-eth1', 'host2-eth0')
110 def setup_module(mod
):
111 "Sets up the pytest environment"
113 testsuite_run_time
= time
.asctime(time
.localtime(time
.time()))
114 logger
.info("Testsuite start time: {}".format(testsuite_run_time
))
115 logger
.info("=" * 40)
117 logger
.info("Running setup_module to create topology")
119 # This function initiates the topology build with Topogen...
120 tgen
= Topogen(build_topo
, mod
.__name
__)
121 # ... and here it calls Mininet initialization functions.
123 kernelv
= platform
.release()
124 if topotest
.version_cmp(kernelv
, "4.15") < 0:
125 logger
.info("For EVPN, kernel version should be minimum 4.15. Kernel present {}".format(kernelv
))
128 if topotest
.version_cmp(kernelv
, '4.15') == 0:
130 logger
.info('setting net.ipv4.tcp_l3mdev_accept={}'.format(l3mdev_accept
))
134 # Starting topology, create tmp files which are loaded to routers
135 # to start deamons and then start routers
136 tgen
.start_topology()
138 # Configure MAC address for hosts as these MACs are advertised with EVPN type-2 routes
139 for name
in tgen
.gears
:
140 if name
not in HOSTS
:
142 host
= tgen
.net
[name
]
144 host_mac
= "1a:2b:3c:4d:5e:6{}".format(HOST_SUFFIX
[name
])
145 host
.cmd_raises("ip link set dev {}-eth0 down".format(name
))
146 host
.cmd_raises("ip link set dev {0}-eth0 address {1}".format(name
, host_mac
))
147 host
.cmd_raises("ip link set dev {}-eth0 up".format(name
))
149 # Configure PE VxLAN and Bridge interfaces
150 for name
in tgen
.gears
:
155 vtep_ip
= "10.100.0.{}".format(PE_SUFFIX
[name
])
156 bridge_ip
= "50.0.1.{}/24".format(PE_SUFFIX
[name
])
157 bridge_ipv6
= "50:0:1::{}/48".format(PE_SUFFIX
[name
])
159 pe
.cmd_raises("ip link add vrf-blue type vrf table 10")
160 pe
.cmd_raises("ip link set dev vrf-blue up")
162 "ip link add vxlan100 type vxlan id 100 dstport 4789 local {}".format(
166 pe
.cmd_raises("ip link add name br100 type bridge stp_state 0")
167 pe
.cmd_raises("ip link set dev vxlan100 master br100")
168 pe
.cmd_raises("ip link set dev {}-eth1 master br100".format(name
))
169 pe
.cmd_raises("ip addr add {} dev br100".format(bridge_ip
))
170 pe
.cmd_raises("ip link set up dev br100")
171 pe
.cmd_raises("ip link set up dev vxlan100")
172 pe
.cmd_raises("ip link set up dev {}-eth1".format(name
))
173 pe
.cmd_raises("ip link set dev br100 master vrf-blue")
174 pe
.cmd_raises("ip -6 addr add {} dev br100".format(bridge_ipv6
))
177 "ip link add vxlan1000 type vxlan id 1000 dstport 4789 local {}".format(
181 pe
.cmd_raises("ip link add name br1000 type bridge stp_state 0")
182 pe
.cmd_raises("ip link set dev vxlan1000 master br100")
183 pe
.cmd_raises("ip link set up dev br1000")
184 pe
.cmd_raises("ip link set up dev vxlan1000")
185 pe
.cmd_raises("ip link set dev br1000 master vrf-blue")
187 pe
.cmd_raises("sysctl -w net.ipv4.ip_forward=1")
188 pe
.cmd_raises("sysctl -w net.ipv6.conf.all.forwarding=1")
189 pe
.cmd_raises("sysctl -w net.ipv4.udp_l3mdev_accept={}".format(l3mdev_accept
))
190 pe
.cmd_raises("sysctl -w net.ipv4.tcp_l3mdev_accept={}".format(l3mdev_accept
))
192 # For all registred routers, load the zebra configuration file
193 for (name
, router
) in tgen
.routers().items():
195 TopoRouter
.RD_ZEBRA
, os
.path
.join(CWD
, "{}/zebra.conf".format(name
))
198 TopoRouter
.RD_BGP
, os
.path
.join(CWD
, "{}/bgpd.conf".format(name
))
201 # After loading the configurations, this function loads configured daemons.
204 logger
.info("Running setup_module() done")
207 def teardown_module(mod
):
208 """Teardown the pytest environment"""
210 logger
.info("Running teardown_module to delete topology")
214 # Stop toplogy and Remove tmp files
218 "Testsuite end time: {}".format(time
.asctime(time
.localtime(time
.time())))
220 logger
.info("=" * 40)
223 def evpn_gateway_ip_show_op_check(trigger
=" "):
225 This function checks CLI O/P for commands mentioned in show_commands for a given trigger
226 :param trigger: Should be a trigger present in TRIGGERS
227 :return: Returns a tuple (result: None for success, retmsg: Log message to be printed on failure)
231 if trigger
not in TRIGGERS
:
232 return "Unexpected trigger", "Unexpected trigger {}".format(trigger
)
234 show_commands
= {'bgp_vni_routes': 'show bgp l2vpn evpn route vni 100 json',
235 'bgp_vrf_ipv4' : 'show bgp vrf vrf-blue ipv4 json',
236 'bgp_vrf_ipv6' : 'show bgp vrf vrf-blue ipv6 json',
237 'zebra_vrf_ipv4': 'show ip route vrf vrf-blue json',
238 'zebra_vrf_ipv6': 'show ipv6 route vrf vrf-blue json'}
240 for (name
, pe
) in tgen
.gears
.items():
244 for (cmd_key
, command
) in show_commands
.items():
245 expected_op_file
= "{0}/{1}/{2}_{3}.json".format(CWD
, name
, cmd_key
, trigger
)
246 expected_op
= json
.loads(open(expected_op_file
).read())
248 test_func
= partial(topotest
.router_json_cmp
, pe
, command
, expected_op
)
249 ret
, result
= topotest
.run_and_expect(test_func
, None, count
=30, wait
=1)
250 assertmsg
= '"{0}" JSON output mismatch for {1}'.format(name
, command
)
251 if result
is not None:
252 return result
, assertmsg
257 def test_evpn_gateway_ip_basic_topo(request
):
259 Tets EVPN overlay index gateway IP functionality. VErify show O/Ps on PE1 and PE2
263 tc_name
= request
.node
.name
264 write_test_header(tc_name
)
266 kernelv
= platform
.release()
267 if topotest
.version_cmp(kernelv
, "4.15") < 0:
268 logger
.info("For EVPN, kernel version should be minimum 4.15")
269 write_test_footer(tc_name
)
272 if tgen
.routers_have_failure():
273 pytest
.skip(tgen
.errors
)
275 step("Check O/Ps for EVPN gateway IP overlay Index functionality at PE1 and PE2")
277 result
, assertmsg
= evpn_gateway_ip_show_op_check("base")
279 if result
is not None:
280 generate_support_bundle()
281 assert result
is None, assertmsg
283 write_test_footer(tc_name
)
286 def test_evpn_gateway_ip_flap_rt5(request
):
288 Withdraw EVPN type-5 routes and check O/Ps at PE1 and PE2
291 tc_name
= request
.node
.name
292 write_test_header(tc_name
)
294 kernelv
= platform
.release()
295 if topotest
.version_cmp(kernelv
, "4.15") < 0:
296 logger
.info("For EVPN, kernel version should be minimum 4.15")
297 write_test_footer(tc_name
)
300 if tgen
.routers_have_failure():
301 pytest
.skip(tgen
.errors
)
303 h1
= tgen
.gears
['host1']
305 step("Withdraw type-5 routes")
307 h1
.run('vtysh -c "config t" \
308 -c "router bgp 111" \
309 -c "address-family ipv4" \
310 -c "no network 100.0.0.21/32"')
311 h1
.run('vtysh -c "config t" \
312 -c "router bgp 111" \
313 -c "address-family ipv6" \
314 -c "no network 100::21/128"')
316 result
, assertmsg
= evpn_gateway_ip_show_op_check("no_rt5")
317 if result
is not None:
318 generate_support_bundle()
319 assert result
is None, assertmsg
321 step("Advertise type-5 routes again")
323 h1
.run('vtysh -c "config t" \
324 -c "router bgp 111" \
325 -c "address-family ipv4" \
326 -c "network 100.0.0.21/32"')
327 h1
.run('vtysh -c "config t" \
328 -c "router bgp 111" \
329 -c "address-family ipv6" \
330 -c "network 100::21/128"')
332 result
, assertmsg
= evpn_gateway_ip_show_op_check("base")
333 if result
is not None:
334 generate_support_bundle()
336 assert result
is None, assertmsg
338 write_test_footer(tc_name
)
341 def test_evpn_gateway_ip_flap_rt2(request
):
343 Withdraw EVPN type-2 routes and check O/Ps at PE1 and PE2
346 tc_name
= request
.node
.name
347 write_test_header(tc_name
)
349 kernelv
= platform
.release()
350 if topotest
.version_cmp(kernelv
, "4.15") < 0:
351 logger
.info("For EVPN, kernel version should be minimum 4.15")
352 write_test_footer(tc_name
)
355 if tgen
.routers_have_failure():
356 pytest
.skip(tgen
.errors
)
359 step("Shut down VxLAN interface at PE1 which results in withdraw of type-2 routes")
361 pe1
= tgen
.net
["PE1"]
363 pe1
.cmd_raises("ip link set dev vxlan100 down")
365 result
, assertmsg
= evpn_gateway_ip_show_op_check("no_rt2")
366 if result
is not None:
367 generate_support_bundle()
368 assert result
is None, assertmsg
370 step("Bring up VxLAN interface at PE1 and advertise type-2 routes again")
372 pe1
.cmd_raises("ip link set dev vxlan100 up")
374 result
, assertmsg
= evpn_gateway_ip_show_op_check("base")
375 if result
is not None:
376 generate_support_bundle()
377 assert result
is None, assertmsg
379 write_test_footer(tc_name
)
382 def test_memory_leak():
383 """Run the memory leak test and report results"""
385 if not tgen
.is_memleak_enabled():
386 pytest
.skip("Memory leak test/report is disabled")
388 tgen
.report_memory_leaks()
390 if __name__
== "__main__":
391 args
= ["-s"] + sys
.argv
[1:]
392 sys
.exit(pytest
.main(args
))