]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/bgp_evpn_overlay_index_gateway/test_bgp_evpn_overlay_index_gateway.py
tests: Disable test which fails under micronet
[mirror_frr.git] / tests / topotests / bgp_evpn_overlay_index_gateway / test_bgp_evpn_overlay_index_gateway.py
1 #!/usr/bin/env python
2 #
3 # Copyright (c) 2020 by VMware, Inc. ("VMware")
4 # Used Copyright (c) 2018 by Network Device Education Foundation, Inc. ("NetDEF")
5 # in this file.
6 #
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
10 # in all copies.
11 #
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
19 # OF THIS SOFTWARE.
20 #
21
22 """
23 test_bgp_evpn_overlay_index_gateway.py: Test EVPN gateway IP overlay index functionality
24 Following functionality is covered:
25
26 +--------+ BGP +--------+ BGP +--------+ +--------+
27 SN1 | | IPv4/v6 | | EVPN | | | |
28 ======+ Host1 +---------+ PE1 +------+ PE2 +------+ Host2 +
29 | | | | | | | |
30 +--------+ +--------+ +--------+ +--------+
31
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
39
40 Following testcases are covered:
41 TC_1:
42 Check BGP and zebra states for above topology at PE1 and PE2.
43
44 TC_2:
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.
47
48 TC_3:
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.
51 """
52
53 import os
54 import sys
55 import json
56 from functools import partial
57 import pytest
58 import time
59 import platform
60
61 #Current Working Directory
62 CWD = os.path.dirname(os.path.realpath(__file__))
63 sys.path.append(os.path.join(CWD, "../"))
64
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 (
71 step,
72 write_test_header,
73 write_test_footer,
74 generate_support_bundle,
75 )
76
77 # Required to instantiate the topology builder class.
78 from lib.micronet_compat import Topo
79
80 pytestmark = [pytest.mark.bgpd]
81
82
83 #Global variables
84 PES = ['PE1', 'PE2']
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"]
89
90
91 def build_topo(tgen):
92 # This function only purpose is to define allocation and relationship
93 # between routers and add links.
94
95 # Create routers
96 for pe in PES:
97 tgen.add_router(pe)
98 for host in HOSTS:
99 tgen.add_router(host)
100
101 krel = platform.release()
102 logger.info('Kernel version ' + krel)
103
104 #Add links
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')
108
109
110 def setup_module(mod):
111 "Sets up the pytest environment"
112
113 testsuite_run_time = time.asctime(time.localtime(time.time()))
114 logger.info("Testsuite start time: {}".format(testsuite_run_time))
115 logger.info("=" * 40)
116
117 logger.info("Running setup_module to create topology")
118
119 # This function initiates the topology build with Topogen...
120 tgen = Topogen(build_topo, mod.__name__)
121 # ... and here it calls Mininet initialization functions.
122
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))
126 return
127
128 if topotest.version_cmp(kernelv, '4.15') == 0:
129 l3mdev_accept = 1
130 logger.info('setting net.ipv4.tcp_l3mdev_accept={}'.format(l3mdev_accept))
131 else:
132 l3mdev_accept = 0
133
134 # Starting topology, create tmp files which are loaded to routers
135 # to start deamons and then start routers
136 tgen.start_topology()
137
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:
141 continue
142 host = tgen.net[name]
143
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))
148
149 # Configure PE VxLAN and Bridge interfaces
150 for name in tgen.gears:
151 if name not in PES:
152 continue
153 pe = tgen.net[name]
154
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])
158
159 pe.cmd_raises("ip link add vrf-blue type vrf table 10")
160 pe.cmd_raises("ip link set dev vrf-blue up")
161 pe.cmd_raises(
162 "ip link add vxlan100 type vxlan id 100 dstport 4789 local {}".format(
163 vtep_ip
164 )
165 )
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))
175
176 pe.cmd_raises(
177 "ip link add vxlan1000 type vxlan id 1000 dstport 4789 local {}".format(
178 vtep_ip
179 )
180 )
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")
186
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))
191
192 # For all registred routers, load the zebra configuration file
193 for (name, router) in tgen.routers().items():
194 router.load_config(
195 TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(name))
196 )
197 router.load_config(
198 TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(name))
199 )
200
201 # After loading the configurations, this function loads configured daemons.
202 tgen.start_router()
203
204 logger.info("Running setup_module() done")
205
206 time.sleep(10)
207
208
209 def teardown_module(mod):
210 """Teardown the pytest environment"""
211
212 logger.info("Running teardown_module to delete topology")
213
214 tgen = get_topogen()
215
216 # Stop toplogy and Remove tmp files
217 tgen.stop_topology()
218
219 logger.info(
220 "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
221 )
222 logger.info("=" * 40)
223
224
225 def evpn_gateway_ip_show_op_check(trigger=" "):
226 """
227 This function checks CLI O/P for commands mentioned in show_commands for a given trigger
228 :param trigger: Should be a trigger present in TRIGGERS
229 :return: Returns a tuple (result: None for success, retmsg: Log message to be printed on failure)
230 """
231 tgen = get_topogen()
232
233 if trigger not in TRIGGERS:
234 return "Unexpected trigger", "Unexpected trigger {}".format(trigger)
235
236 show_commands = {'bgp_vni_routes': 'show bgp l2vpn evpn route vni 100 json',
237 'bgp_vrf_ipv4' : 'show bgp vrf vrf-blue ipv4 json',
238 'bgp_vrf_ipv6' : 'show bgp vrf vrf-blue ipv6 json',
239 'zebra_vrf_ipv4': 'show ip route vrf vrf-blue json',
240 'zebra_vrf_ipv6': 'show ipv6 route vrf vrf-blue json'}
241
242 for (name, pe) in tgen.gears.items():
243 if name not in PES:
244 continue
245
246 for (cmd_key, command) in show_commands.items():
247 expected_op_file = "{0}/{1}/{2}_{3}.json".format(CWD, name, cmd_key, trigger)
248 expected_op = json.loads(open(expected_op_file).read())
249
250 test_func = partial(topotest.router_json_cmp, pe, command, expected_op)
251 ret, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
252 assertmsg = '"{0}" JSON output mismatch for {1}'.format(name, command)
253 if result is not None:
254 return result, assertmsg
255
256 return None, "Pass"
257
258
259 def test_evpn_gateway_ip_basic_topo(request):
260 """
261 Tets EVPN overlay index gateway IP functionality. VErify show O/Ps on PE1 and PE2
262 """
263
264 tgen = get_topogen()
265 tc_name = request.node.name
266 write_test_header(tc_name)
267
268 # Temporarily Disabled
269 tgen.set_error("%s: Failing under new micronet framework, please debug and re-enable", tc_name)
270
271 kernelv = platform.release()
272 if topotest.version_cmp(kernelv, "4.15") < 0:
273 logger.info("For EVPN, kernel version should be minimum 4.15")
274 write_test_footer(tc_name)
275 return
276
277 if tgen.routers_have_failure():
278 pytest.skip(tgen.errors)
279
280 step("Check O/Ps for EVPN gateway IP overlay Index functionality at PE1 and PE2")
281
282 result, assertmsg = evpn_gateway_ip_show_op_check("base")
283
284 if result is not None:
285 generate_support_bundle()
286 assert result is None, assertmsg
287
288 write_test_footer(tc_name)
289
290
291 def test_evpn_gateway_ip_flap_rt5(request):
292 """
293 Withdraw EVPN type-5 routes and check O/Ps at PE1 and PE2
294 """
295 tgen = get_topogen()
296 tc_name = request.node.name
297 write_test_header(tc_name)
298
299 kernelv = platform.release()
300 if topotest.version_cmp(kernelv, "4.15") < 0:
301 logger.info("For EVPN, kernel version should be minimum 4.15")
302 write_test_footer(tc_name)
303 return
304
305 if tgen.routers_have_failure():
306 pytest.skip(tgen.errors)
307
308 h1 = tgen.gears['host1']
309
310 step("Withdraw type-5 routes")
311
312 h1.run('vtysh -c "config t" \
313 -c "router bgp 111" \
314 -c "address-family ipv4" \
315 -c "no network 100.0.0.21/32"')
316 h1.run('vtysh -c "config t" \
317 -c "router bgp 111" \
318 -c "address-family ipv6" \
319 -c "no network 100::21/128"')
320
321 result, assertmsg = evpn_gateway_ip_show_op_check("no_rt5")
322 if result is not None:
323 generate_support_bundle()
324 assert result is None, assertmsg
325
326 step("Advertise type-5 routes again")
327
328 h1.run('vtysh -c "config t" \
329 -c "router bgp 111" \
330 -c "address-family ipv4" \
331 -c "network 100.0.0.21/32"')
332 h1.run('vtysh -c "config t" \
333 -c "router bgp 111" \
334 -c "address-family ipv6" \
335 -c "network 100::21/128"')
336
337 result, assertmsg = evpn_gateway_ip_show_op_check("base")
338 if result is not None:
339 generate_support_bundle()
340
341 assert result is None, assertmsg
342
343 write_test_footer(tc_name)
344
345
346 def test_evpn_gateway_ip_flap_rt2(request):
347 """
348 Withdraw EVPN type-2 routes and check O/Ps at PE1 and PE2
349 """
350 tgen = get_topogen()
351 tc_name = request.node.name
352 write_test_header(tc_name)
353
354 kernelv = platform.release()
355 if topotest.version_cmp(kernelv, "4.15") < 0:
356 logger.info("For EVPN, kernel version should be minimum 4.15")
357 write_test_footer(tc_name)
358 return
359
360 if tgen.routers_have_failure():
361 pytest.skip(tgen.errors)
362
363
364 step("Shut down VxLAN interface at PE1 which results in withdraw of type-2 routes")
365
366 pe1 = tgen.net["PE1"]
367
368 pe1.cmd_raises("ip link set dev vxlan100 down")
369
370 result, assertmsg = evpn_gateway_ip_show_op_check("no_rt2")
371 if result is not None:
372 generate_support_bundle()
373 assert result is None, assertmsg
374
375 step("Bring up VxLAN interface at PE1 and advertise type-2 routes again")
376
377 pe1.cmd_raises("ip link set dev vxlan100 up")
378
379 result, assertmsg = evpn_gateway_ip_show_op_check("base")
380 if result is not None:
381 generate_support_bundle()
382 assert result is None, assertmsg
383
384 write_test_footer(tc_name)
385
386
387 def test_memory_leak():
388 """Run the memory leak test and report results"""
389 tgen = get_topogen()
390 if not tgen.is_memleak_enabled():
391 pytest.skip("Memory leak test/report is disabled")
392
393 tgen.report_memory_leaks()
394
395 if __name__ == "__main__":
396 args = ["-s"] + sys.argv[1:]
397 sys.exit(pytest.main(args))