]>
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"]
91 class TemplateTopo(Topo
):
92 """Test topology builder"""
94 def build(self
, *_args
, **_opts
):
96 tgen
= get_topogen(self
)
98 # This function only purpose is to define allocation and relationship
99 # between routers and add links.
105 tgen
.add_router(host
)
107 krel
= platform
.release()
108 logger
.info('Kernel version ' + krel
)
111 tgen
.add_link(tgen
.gears
['PE1'], tgen
.gears
['PE2'], 'PE1-eth0', 'PE2-eth0')
112 tgen
.add_link(tgen
.gears
['PE1'], tgen
.gears
['host1'], 'PE1-eth1', 'host1-eth0')
113 tgen
.add_link(tgen
.gears
['PE2'], tgen
.gears
['host2'], 'PE2-eth1', 'host2-eth0')
116 def setup_module(mod
):
117 "Sets up the pytest environment"
119 testsuite_run_time
= time
.asctime(time
.localtime(time
.time()))
120 logger
.info("Testsuite start time: {}".format(testsuite_run_time
))
121 logger
.info("=" * 40)
123 logger
.info("Running setup_module to create topology")
125 # This function initiates the topology build with Topogen...
126 tgen
= Topogen(TemplateTopo
, mod
.__name
__)
127 # ... and here it calls Mininet initialization functions.
129 kernelv
= platform
.release()
130 if topotest
.version_cmp(kernelv
, "4.15") < 0:
131 logger
.info("For EVPN, kernel version should be minimum 4.15. Kernel present {}".format(kernelv
))
134 if topotest
.version_cmp(kernelv
, '4.15') == 0:
136 logger
.info('setting net.ipv4.tcp_l3mdev_accept={}'.format(l3mdev_accept
))
140 # Starting topology, create tmp files which are loaded to routers
141 # to start deamons and then start routers
142 tgen
.start_topology()
144 # Configure MAC address for hosts as these MACs are advertised with EVPN type-2 routes
145 for name
in tgen
.gears
:
146 if name
not in HOSTS
:
148 host
= tgen
.net
[name
]
150 host_mac
= "1a:2b:3c:4d:5e:6{}".format(HOST_SUFFIX
[name
])
151 host
.cmd_raises("ip link set dev {}-eth0 down".format(name
))
152 host
.cmd_raises("ip link set dev {0}-eth0 address {1}".format(name
, host_mac
))
153 host
.cmd_raises("ip link set dev {}-eth0 up".format(name
))
155 # Configure PE VxLAN and Bridge interfaces
156 for name
in tgen
.gears
:
161 vtep_ip
= "10.100.0.{}".format(PE_SUFFIX
[name
])
162 bridge_ip
= "50.0.1.{}/24".format(PE_SUFFIX
[name
])
163 bridge_ipv6
= "50:0:1::{}/48".format(PE_SUFFIX
[name
])
165 pe
.cmd_raises("ip link add vrf-blue type vrf table 10")
166 pe
.cmd_raises("ip link set dev vrf-blue up")
168 "ip link add vxlan100 type vxlan id 100 dstport 4789 local {}".format(
172 pe
.cmd_raises("ip link add name br100 type bridge stp_state 0")
173 pe
.cmd_raises("ip link set dev vxlan100 master br100")
174 pe
.cmd_raises("ip link set dev {}-eth1 master br100".format(name
))
175 pe
.cmd_raises("ip addr add {} dev br100".format(bridge_ip
))
176 pe
.cmd_raises("ip link set up dev br100")
177 pe
.cmd_raises("ip link set up dev vxlan100")
178 pe
.cmd_raises("ip link set up dev {}-eth1".format(name
))
179 pe
.cmd_raises("ip link set dev br100 master vrf-blue")
180 pe
.cmd_raises("ip -6 addr add {} dev br100".format(bridge_ipv6
))
183 "ip link add vxlan1000 type vxlan id 1000 dstport 4789 local {}".format(
187 pe
.cmd_raises("ip link add name br1000 type bridge stp_state 0")
188 pe
.cmd_raises("ip link set dev vxlan1000 master br100")
189 pe
.cmd_raises("ip link set up dev br1000")
190 pe
.cmd_raises("ip link set up dev vxlan1000")
191 pe
.cmd_raises("ip link set dev br1000 master vrf-blue")
193 pe
.cmd_raises("sysctl -w net.ipv4.ip_forward=1")
194 pe
.cmd_raises("sysctl -w net.ipv6.conf.all.forwarding=1")
195 pe
.cmd_raises("sysctl -w net.ipv4.udp_l3mdev_accept={}".format(l3mdev_accept
))
196 pe
.cmd_raises("sysctl -w net.ipv4.tcp_l3mdev_accept={}".format(l3mdev_accept
))
198 # For all registred routers, load the zebra configuration file
199 for (name
, router
) in tgen
.routers().items():
201 TopoRouter
.RD_ZEBRA
, os
.path
.join(CWD
, "{}/zebra.conf".format(name
))
204 TopoRouter
.RD_BGP
, os
.path
.join(CWD
, "{}/bgpd.conf".format(name
))
207 # After loading the configurations, this function loads configured daemons.
210 logger
.info("Running setup_module() done")
213 def teardown_module(mod
):
214 """Teardown the pytest environment"""
216 logger
.info("Running teardown_module to delete topology")
220 # Stop toplogy and Remove tmp files
224 "Testsuite end time: {}".format(time
.asctime(time
.localtime(time
.time())))
226 logger
.info("=" * 40)
229 def evpn_gateway_ip_show_op_check(trigger
=" "):
231 This function checks CLI O/P for commands mentioned in show_commands for a given trigger
232 :param trigger: Should be a trigger present in TRIGGERS
233 :return: Returns a tuple (result: None for success, retmsg: Log message to be printed on failure)
237 if trigger
not in TRIGGERS
:
238 return "Unexpected trigger", "Unexpected trigger {}".format(trigger
)
240 show_commands
= {'bgp_vni_routes': 'show bgp l2vpn evpn route vni 100 json',
241 'bgp_vrf_ipv4' : 'show bgp vrf vrf-blue ipv4 json',
242 'bgp_vrf_ipv6' : 'show bgp vrf vrf-blue ipv6 json',
243 'zebra_vrf_ipv4': 'show ip route vrf vrf-blue json',
244 'zebra_vrf_ipv6': 'show ipv6 route vrf vrf-blue json'}
246 for (name
, pe
) in tgen
.gears
.items():
250 for (cmd_key
, command
) in show_commands
.items():
251 expected_op_file
= "{0}/{1}/{2}_{3}.json".format(CWD
, name
, cmd_key
, trigger
)
252 expected_op
= json
.loads(open(expected_op_file
).read())
254 test_func
= partial(topotest
.router_json_cmp
, pe
, command
, expected_op
)
255 ret
, result
= topotest
.run_and_expect(test_func
, None, count
=30, wait
=1)
256 assertmsg
= '"{0}" JSON output mismatch for {1}'.format(name
, command
)
257 if result
is not None:
258 return result
, assertmsg
263 def test_evpn_gateway_ip_basic_topo(request
):
265 Tets EVPN overlay index gateway IP functionality. VErify show O/Ps on PE1 and PE2
269 tc_name
= request
.node
.name
270 write_test_header(tc_name
)
272 kernelv
= platform
.release()
273 if topotest
.version_cmp(kernelv
, "4.15") < 0:
274 logger
.info("For EVPN, kernel version should be minimum 4.15")
275 write_test_footer(tc_name
)
278 if tgen
.routers_have_failure():
279 pytest
.skip(tgen
.errors
)
281 step("Check O/Ps for EVPN gateway IP overlay Index functionality at PE1 and PE2")
283 result
, assertmsg
= evpn_gateway_ip_show_op_check("base")
285 if result
is not None:
286 generate_support_bundle()
287 assert result
is None, assertmsg
289 write_test_footer(tc_name
)
292 def test_evpn_gateway_ip_flap_rt5(request
):
294 Withdraw EVPN type-5 routes and check O/Ps at PE1 and PE2
297 tc_name
= request
.node
.name
298 write_test_header(tc_name
)
300 kernelv
= platform
.release()
301 if topotest
.version_cmp(kernelv
, "4.15") < 0:
302 logger
.info("For EVPN, kernel version should be minimum 4.15")
303 write_test_footer(tc_name
)
306 if tgen
.routers_have_failure():
307 pytest
.skip(tgen
.errors
)
309 h1
= tgen
.gears
['host1']
311 step("Withdraw type-5 routes")
313 h1
.run('vtysh -c "config t" \
314 -c "router bgp 111" \
315 -c "address-family ipv4" \
316 -c "no network 100.0.0.21/32"')
317 h1
.run('vtysh -c "config t" \
318 -c "router bgp 111" \
319 -c "address-family ipv6" \
320 -c "no network 100::21/128"')
322 result
, assertmsg
= evpn_gateway_ip_show_op_check("no_rt5")
323 if result
is not None:
324 generate_support_bundle()
325 assert result
is None, assertmsg
327 step("Advertise type-5 routes again")
329 h1
.run('vtysh -c "config t" \
330 -c "router bgp 111" \
331 -c "address-family ipv4" \
332 -c "network 100.0.0.21/32"')
333 h1
.run('vtysh -c "config t" \
334 -c "router bgp 111" \
335 -c "address-family ipv6" \
336 -c "network 100::21/128"')
338 result
, assertmsg
= evpn_gateway_ip_show_op_check("base")
339 if result
is not None:
340 generate_support_bundle()
342 assert result
is None, assertmsg
344 write_test_footer(tc_name
)
347 def test_evpn_gateway_ip_flap_rt2(request
):
349 Withdraw EVPN type-2 routes and check O/Ps at PE1 and PE2
352 tc_name
= request
.node
.name
353 write_test_header(tc_name
)
355 kernelv
= platform
.release()
356 if topotest
.version_cmp(kernelv
, "4.15") < 0:
357 logger
.info("For EVPN, kernel version should be minimum 4.15")
358 write_test_footer(tc_name
)
361 if tgen
.routers_have_failure():
362 pytest
.skip(tgen
.errors
)
365 step("Shut down VxLAN interface at PE1 which results in withdraw of type-2 routes")
367 pe1
= tgen
.net
["PE1"]
369 pe1
.cmd_raises("ip link set dev vxlan100 down")
371 result
, assertmsg
= evpn_gateway_ip_show_op_check("no_rt2")
372 if result
is not None:
373 generate_support_bundle()
374 assert result
is None, assertmsg
376 step("Bring up VxLAN interface at PE1 and advertise type-2 routes again")
378 pe1
.cmd_raises("ip link set dev vxlan100 up")
380 result
, assertmsg
= evpn_gateway_ip_show_op_check("base")
381 if result
is not None:
382 generate_support_bundle()
383 assert result
is None, assertmsg
385 write_test_footer(tc_name
)
388 def test_memory_leak():
389 """Run the memory leak test and report results"""
391 if not tgen
.is_memleak_enabled():
392 pytest
.skip("Memory leak test/report is disabled")
394 tgen
.report_memory_leaks()
396 if __name__
== "__main__":
397 args
= ["-s"] + sys
.argv
[1:]
398 sys
.exit(pytest
.main(args
))