]>
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 mininet
.topo
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
, host
) in tgen
.gears
.items():
146 if name
not in HOSTS
:
149 host_mac
= "1a:2b:3c:4d:5e:6{}".format(HOST_SUFFIX
[name
])
150 host
.run("ip link set dev {}-eth0 down").format(name
)
151 host
.run("ip link set dev {0}-eth0 address {1}".format(name
, host_mac
))
152 host
.run("ip link set dev {}-eth0 up").format(name
)
154 # Configure PE VxLAN and Bridge interfaces
155 for (name
, pe
) in tgen
.gears
.items():
158 vtep_ip
= "10.100.0.{}".format(PE_SUFFIX
[name
])
159 bridge_ip
= "50.0.1.{}/24".format(PE_SUFFIX
[name
])
160 bridge_ipv6
= "50:0:1::{}/48".format(PE_SUFFIX
[name
])
162 pe
.run("ip link add vrf-blue type vrf table 10")
163 pe
.run("ip link set dev vrf-blue up")
164 pe
.run("ip link add vxlan100 type vxlan id 100 dstport 4789 local {}".format(vtep_ip
))
165 pe
.run("ip link add name br100 type bridge stp_state 0")
166 pe
.run("ip link set dev vxlan100 master br100")
167 pe
.run("ip link set dev {}-eth1 master br100".format(name
))
168 pe
.run("ip addr add {} dev br100".format(bridge_ip
))
169 pe
.run("ip link set up dev br100")
170 pe
.run("ip link set up dev vxlan100")
171 pe
.run("ip link set up dev {}-eth1".format(name
))
172 pe
.run("ip link set dev br100 master vrf-blue")
173 pe
.run("ip -6 addr add {} dev br100".format(bridge_ipv6
))
175 pe
.run("ip link add vxlan1000 type vxlan id 1000 dstport 4789 local {}".format(vtep_ip
))
176 pe
.run("ip link add name br1000 type bridge stp_state 0")
177 pe
.run("ip link set dev vxlan1000 master br100")
178 pe
.run("ip link set up dev br1000")
179 pe
.run("ip link set up dev vxlan1000")
180 pe
.run("ip link set dev br1000 master vrf-blue")
182 pe
.run("sysctl -w net.ipv4.ip_forward=1")
183 pe
.run("sysctl -w net.ipv6.conf.all.forwarding=1")
184 pe
.run("sysctl -w net.ipv4.udp_l3mdev_accept={}".format(l3mdev_accept
))
185 pe
.run("sysctl -w net.ipv4.tcp_l3mdev_accept={}".format(l3mdev_accept
))
187 # For all registred routers, load the zebra configuration file
188 for (name
, router
) in tgen
.routers().items():
190 TopoRouter
.RD_ZEBRA
, os
.path
.join(CWD
, "{}/zebra.conf".format(name
))
193 TopoRouter
.RD_BGP
, os
.path
.join(CWD
, "{}/bgpd.conf".format(name
))
196 # After loading the configurations, this function loads configured daemons.
199 logger
.info("Running setup_module() done")
202 def teardown_module(mod
):
203 """Teardown the pytest environment"""
205 logger
.info("Running teardown_module to delete topology")
209 # Stop toplogy and Remove tmp files
213 "Testsuite end time: {}".format(time
.asctime(time
.localtime(time
.time())))
215 logger
.info("=" * 40)
218 def evpn_gateway_ip_show_op_check(trigger
=" "):
220 This function checks CLI O/P for commands mentioned in show_commands for a given trigger
221 :param trigger: Should be a trigger present in TRIGGERS
222 :return: Returns a tuple (result: None for success, retmsg: Log message to be printed on failure)
226 if trigger
not in TRIGGERS
:
227 return "Unexpected trigger", "Unexpected trigger {}".format(trigger
)
229 show_commands
= {'bgp_vni_routes': 'show bgp l2vpn evpn route vni 100 json',
230 'bgp_vrf_ipv4' : 'show bgp vrf vrf-blue ipv4 json',
231 'bgp_vrf_ipv6' : 'show bgp vrf vrf-blue ipv6 json',
232 'zebra_vrf_ipv4': 'show ip route vrf vrf-blue json',
233 'zebra_vrf_ipv6': 'show ipv6 route vrf vrf-blue json'}
235 for (name
, pe
) in tgen
.gears
.items():
239 for (cmd_key
, command
) in show_commands
.items():
240 expected_op_file
= "{0}/{1}/{2}_{3}.json".format(CWD
, name
, cmd_key
, trigger
)
241 expected_op
= json
.loads(open(expected_op_file
).read())
243 test_func
= partial(topotest
.router_json_cmp
, pe
, command
, expected_op
)
244 ret
, result
= topotest
.run_and_expect(test_func
, None, count
=30, wait
=1)
245 assertmsg
= '"{0}" JSON output mismatch for {1}'.format(name
, command
)
246 if result
is not None:
247 return result
, assertmsg
252 def test_evpn_gateway_ip_basic_topo(request
):
254 Tets EVPN overlay index gateway IP functionality. VErify show O/Ps on PE1 and PE2
258 tc_name
= request
.node
.name
259 write_test_header(tc_name
)
261 kernelv
= platform
.release()
262 if topotest
.version_cmp(kernelv
, "4.15") < 0:
263 logger
.info("For EVPN, kernel version should be minimum 4.15")
264 write_test_footer(tc_name
)
267 if tgen
.routers_have_failure():
268 pytest
.skip(tgen
.errors
)
270 step("Check O/Ps for EVPN gateway IP overlay Index functionality at PE1 and PE2")
272 result
, assertmsg
= evpn_gateway_ip_show_op_check("base")
274 if result
is not None:
275 generate_support_bundle()
276 assert result
is None, assertmsg
278 write_test_footer(tc_name
)
281 def test_evpn_gateway_ip_flap_rt5(request
):
283 Withdraw EVPN type-5 routes and check O/Ps at PE1 and PE2
286 tc_name
= request
.node
.name
287 write_test_header(tc_name
)
289 kernelv
= platform
.release()
290 if topotest
.version_cmp(kernelv
, "4.15") < 0:
291 logger
.info("For EVPN, kernel version should be minimum 4.15")
292 write_test_footer(tc_name
)
295 if tgen
.routers_have_failure():
296 pytest
.skip(tgen
.errors
)
298 h1
= tgen
.gears
['host1']
300 step("Withdraw type-5 routes")
302 h1
.run('vtysh -c "config t" \
303 -c "router bgp 111" \
304 -c "address-family ipv4" \
305 -c "no network 100.0.0.21/32"')
306 h1
.run('vtysh -c "config t" \
307 -c "router bgp 111" \
308 -c "address-family ipv6" \
309 -c "no network 100::21/128"')
311 result
, assertmsg
= evpn_gateway_ip_show_op_check("no_rt5")
312 if result
is not None:
313 generate_support_bundle()
314 assert result
is None, assertmsg
316 step("Advertise type-5 routes again")
318 h1
.run('vtysh -c "config t" \
319 -c "router bgp 111" \
320 -c "address-family ipv4" \
321 -c "network 100.0.0.21/32"')
322 h1
.run('vtysh -c "config t" \
323 -c "router bgp 111" \
324 -c "address-family ipv6" \
325 -c "network 100::21/128"')
327 result
, assertmsg
= evpn_gateway_ip_show_op_check("base")
328 if result
is not None:
329 generate_support_bundle()
331 assert result
is None, assertmsg
333 write_test_footer(tc_name
)
336 def test_evpn_gateway_ip_flap_rt2(request
):
338 Withdraw EVPN type-2 routes and check O/Ps at PE1 and PE2
341 tc_name
= request
.node
.name
342 write_test_header(tc_name
)
344 kernelv
= platform
.release()
345 if topotest
.version_cmp(kernelv
, "4.15") < 0:
346 logger
.info("For EVPN, kernel version should be minimum 4.15")
347 write_test_footer(tc_name
)
350 if tgen
.routers_have_failure():
351 pytest
.skip(tgen
.errors
)
354 step("Shut down VxLAN interface at PE1 which results in withdraw of type-2 routes")
356 pe1
= tgen
.gears
['PE1']
358 pe1
.run('ip link set dev vxlan100 down')
360 result
, assertmsg
= evpn_gateway_ip_show_op_check("no_rt2")
361 if result
is not None:
362 generate_support_bundle()
363 assert result
is None, assertmsg
365 step("Bring up VxLAN interface at PE1 and advertise type-2 routes again")
367 pe1
.run('ip link set dev vxlan100 up')
369 result
, assertmsg
= evpn_gateway_ip_show_op_check("base")
370 if result
is not None:
371 generate_support_bundle()
372 assert result
is None, assertmsg
374 write_test_footer(tc_name
)
377 def test_memory_leak():
378 """Run the memory leak test and report results"""
380 if not tgen
.is_memleak_enabled():
381 pytest
.skip("Memory leak test/report is disabled")
383 tgen
.report_memory_leaks()
385 if __name__
== "__main__":
386 args
= ["-s"] + sys
.argv
[1:]
387 sys
.exit(pytest
.main(args
))