]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / tests / topotests / bgp_srv6l3vpn_to_bgp_vrf3 / test_bgp_srv6l3vpn_to_bgp_vrf3.py
1 #!/usr/bin/env python
2 # SPDX-License-Identifier: ISC
3
4 # Copyright (c) 2022, University of Rome Tor Vergata
5 # Authored by Carmine Scarpitta <carmine.scarpitta@uniroma2.it>
6 #
7
8 import os
9 import re
10 import sys
11 import json
12 import functools
13 import pytest
14
15 CWD = os.path.dirname(os.path.realpath(__file__))
16 sys.path.append(os.path.join(CWD, "../"))
17
18 # pylint: disable=C0413
19 # Import topogen and topotest helpers
20 from lib import topotest
21 from lib.topogen import Topogen, TopoRouter, get_topogen
22 from lib.topolog import logger
23 from lib.common_config import required_linux_kernel_version
24
25 pytestmark = [pytest.mark.bgpd]
26
27
28 def build_topo(tgen):
29 tgen.add_router("r1")
30 tgen.add_router("r2")
31 tgen.add_router("ce1")
32 tgen.add_router("ce2")
33 tgen.add_router("ce3")
34 tgen.add_router("ce4")
35 tgen.add_router("ce5")
36 tgen.add_router("ce6")
37
38 tgen.add_link(tgen.gears["r1"], tgen.gears["r2"], "eth0", "eth0")
39 tgen.add_link(tgen.gears["ce1"], tgen.gears["r1"], "eth0", "eth1")
40 tgen.add_link(tgen.gears["ce2"], tgen.gears["r2"], "eth0", "eth1")
41 tgen.add_link(tgen.gears["ce3"], tgen.gears["r1"], "eth0", "eth2")
42 tgen.add_link(tgen.gears["ce4"], tgen.gears["r2"], "eth0", "eth2")
43 tgen.add_link(tgen.gears["ce5"], tgen.gears["r1"], "eth0", "eth3")
44 tgen.add_link(tgen.gears["ce6"], tgen.gears["r2"], "eth0", "eth3")
45
46
47 def setup_module(mod):
48 result = required_linux_kernel_version("5.14")
49 if result is not True:
50 pytest.skip("Kernel requirements are not met")
51
52 tgen = Topogen(build_topo, mod.__name__)
53 tgen.start_topology()
54 for rname, router in tgen.routers().items():
55 router.run("/bin/bash {}/{}/setup.sh".format(CWD, rname))
56 router.load_config(
57 TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
58 )
59 router.load_config(
60 TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
61 )
62
63 tgen.gears["r1"].run("sysctl net.vrf.strict_mode=1")
64 tgen.gears["r1"].run("ip link add vrf10 type vrf table 10")
65 tgen.gears["r1"].run("ip link set vrf10 up")
66 tgen.gears["r1"].run("ip link add vrf20 type vrf table 20")
67 tgen.gears["r1"].run("ip link set vrf20 up")
68 tgen.gears["r1"].run("ip link set eth1 master vrf10")
69 tgen.gears["r1"].run("ip link set eth2 master vrf10")
70 tgen.gears["r1"].run("ip link set eth3 master vrf20")
71
72 tgen.gears["r2"].run("sysctl net.vrf.strict_mode=1")
73 tgen.gears["r2"].run("ip link add vrf10 type vrf table 10")
74 tgen.gears["r2"].run("ip link set vrf10 up")
75 tgen.gears["r2"].run("ip link add vrf20 type vrf table 20")
76 tgen.gears["r2"].run("ip link set vrf20 up")
77 tgen.gears["r2"].run("ip link set eth1 master vrf10")
78 tgen.gears["r2"].run("ip link set eth2 master vrf20")
79 tgen.gears["r2"].run("ip link set eth3 master vrf20")
80 tgen.start_router()
81
82
83 def teardown_module(mod):
84 tgen = get_topogen()
85 tgen.stop_topology()
86
87
88 def open_json_file(filename):
89 try:
90 with open(filename, "r") as f:
91 return json.load(f)
92 except IOError:
93 assert False, "Could not read file {}".format(filename)
94
95
96 def check_ping4(name, dest_addr, expect_connected):
97 def _check(name, dest_addr, match):
98 tgen = get_topogen()
99 output = tgen.gears[name].run("ping {} -c 1 -w 1".format(dest_addr))
100 logger.info(output)
101 assert match in output, "ping fail"
102
103 match = ", {} packet loss".format("0%" if expect_connected else "100%")
104 logger.info("[+] check {} {} {}".format(name, dest_addr, match))
105 tgen = get_topogen()
106 func = functools.partial(_check, name, dest_addr, match)
107 success, result = topotest.run_and_expect(func, None, count=10, wait=0.5)
108 assert result is None, "Failed"
109
110
111 def check_ping6(name, dest_addr, expect_connected):
112 def _check(name, dest_addr, match):
113 tgen = get_topogen()
114 output = tgen.gears[name].run("ping6 {} -c 1 -w 1".format(dest_addr))
115 logger.info(output)
116 if match not in output:
117 return "ping fail"
118
119 match = "{} packet loss".format("0%" if expect_connected else "100%")
120 logger.info("[+] check {} {} {}".format(name, dest_addr, match))
121 tgen = get_topogen()
122 func = functools.partial(_check, name, dest_addr, match)
123 success, result = topotest.run_and_expect(func, None, count=10, wait=1)
124 assert result is None, "Failed"
125
126
127 def check_rib(name, cmd, expected_file):
128 def _check(name, dest_addr, match):
129 logger.info("polling")
130 tgen = get_topogen()
131 router = tgen.gears[name]
132 output = json.loads(router.vtysh_cmd(cmd))
133 expected = open_json_file("{}/{}".format(CWD, expected_file))
134 return topotest.json_cmp(output, expected)
135
136 logger.info('[+] check {} "{}" {}'.format(name, cmd, expected_file))
137 tgen = get_topogen()
138 func = functools.partial(_check, name, cmd, expected_file)
139 success, result = topotest.run_and_expect(func, None, count=10, wait=0.5)
140 assert result is None, "Failed"
141
142
143 def test_rib():
144 check_rib("r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib.json")
145 check_rib("r2", "show bgp ipv4 vpn json", "r2/vpnv4_rib.json")
146 check_rib("r1", "show ip route vrf vrf10 json", "r1/vrf10v4_rib.json")
147 check_rib("r1", "show ip route vrf vrf20 json", "r1/vrf20v4_rib.json")
148 check_rib("r2", "show ip route vrf vrf10 json", "r2/vrf10v4_rib.json")
149 check_rib("r2", "show ip route vrf vrf20 json", "r2/vrf20v4_rib.json")
150 check_rib("ce1", "show ip route json", "ce1/ip_rib.json")
151 check_rib("ce2", "show ip route json", "ce2/ip_rib.json")
152 check_rib("ce3", "show ip route json", "ce3/ip_rib.json")
153 check_rib("ce4", "show ip route json", "ce4/ip_rib.json")
154 check_rib("ce5", "show ip route json", "ce5/ip_rib.json")
155 check_rib("ce6", "show ip route json", "ce6/ip_rib.json")
156
157 check_rib("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib.json")
158 check_rib("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib.json")
159 check_rib("r1", "show ipv6 route vrf vrf10 json", "r1/vrf10v6_rib.json")
160 check_rib("r1", "show ipv6 route vrf vrf20 json", "r1/vrf20v6_rib.json")
161 check_rib("r2", "show ipv6 route vrf vrf10 json", "r2/vrf10v6_rib.json")
162 check_rib("r2", "show ipv6 route vrf vrf20 json", "r2/vrf20v6_rib.json")
163 check_rib("ce1", "show ipv6 route json", "ce1/ipv6_rib.json")
164 check_rib("ce2", "show ipv6 route json", "ce2/ipv6_rib.json")
165 check_rib("ce3", "show ipv6 route json", "ce3/ipv6_rib.json")
166 check_rib("ce4", "show ipv6 route json", "ce4/ipv6_rib.json")
167 check_rib("ce5", "show ipv6 route json", "ce5/ipv6_rib.json")
168 check_rib("ce6", "show ipv6 route json", "ce6/ipv6_rib.json")
169
170
171 def test_ping():
172 check_ping4("ce1", "192.168.2.2", True)
173 check_ping4("ce1", "192.168.3.2", True)
174 check_ping4("ce1", "192.168.4.2", False)
175 check_ping4("ce1", "192.168.5.2", False)
176 check_ping4("ce1", "192.168.6.2", False)
177 check_ping4("ce4", "192.168.1.2", False)
178 check_ping4("ce4", "192.168.2.2", False)
179 check_ping4("ce4", "192.168.3.2", False)
180 check_ping4("ce4", "192.168.5.2", True)
181 check_ping4("ce4", "192.168.6.2", True)
182
183 check_ping6("ce1", "2001:2::2", True)
184 check_ping6("ce1", "2001:3::2", True)
185 check_ping6("ce1", "2001:4::2", False)
186 check_ping6("ce1", "2001:5::2", False)
187 check_ping6("ce1", "2001:6::2", False)
188 check_ping6("ce4", "2001:1::2", False)
189 check_ping6("ce4", "2001:2::2", False)
190 check_ping6("ce4", "2001:3::2", False)
191 check_ping6("ce4", "2001:5::2", True)
192 check_ping6("ce4", "2001:6::2", True)
193
194
195 def test_bgp_sid_vpn_export_disable():
196 check_ping4("ce1", "192.168.2.2", True)
197 check_ping6("ce1", "2001:2::2", True)
198 get_topogen().gears["r1"].vtysh_cmd(
199 """
200 configure terminal
201 router bgp 1 vrf vrf10
202 segment-routing srv6
203 no sid vpn per-vrf export
204 """
205 )
206 check_rib(
207 "r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib_sid_vpn_export_disabled.json"
208 )
209 check_rib(
210 "r2", "show bgp ipv4 vpn json", "r2/vpnv4_rib_sid_vpn_export_disabled.json"
211 )
212 check_rib(
213 "r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib_sid_vpn_export_disabled.json"
214 )
215 check_rib(
216 "r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib_sid_vpn_export_disabled.json"
217 )
218 check_ping4("ce1", "192.168.2.2", False)
219 check_ping6("ce1", "2001:2::2", False)
220
221
222 def test_bgp_sid_vpn_export_reenable():
223 check_ping4("ce1", "192.168.2.2", False)
224 check_ping6("ce1", "2001:2::2", False)
225 get_topogen().gears["r1"].vtysh_cmd(
226 """
227 configure terminal
228 router bgp 1 vrf vrf10
229 segment-routing srv6
230 sid vpn per-vrf export auto
231 """
232 )
233 check_rib(
234 "r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib_sid_vpn_export_reenabled.json"
235 )
236 check_rib(
237 "r2", "show bgp ipv4 vpn json", "r2/vpnv4_rib_sid_vpn_export_reenabled.json"
238 )
239 check_rib(
240 "r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib_sid_vpn_export_reenabled.json"
241 )
242 check_rib(
243 "r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib_sid_vpn_export_reenabled.json"
244 )
245 check_ping4("ce1", "192.168.2.2", True)
246 check_ping6("ce1", "2001:2::2", True)
247
248
249 def test_locator_delete():
250 check_ping4("ce1", "192.168.2.2", True)
251 check_ping6("ce1", "2001:2::2", True)
252 get_topogen().gears["r1"].vtysh_cmd(
253 """
254 configure terminal
255 segment-routing
256 srv6
257 locators
258 no locator loc1
259 """
260 )
261 check_rib("r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib_locator_deleted.json")
262 check_rib("r2", "show bgp ipv4 vpn json", "r2/vpnv4_rib_locator_deleted.json")
263 check_rib("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib_locator_deleted.json")
264 check_rib("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib_locator_deleted.json")
265 check_ping4("ce1", "192.168.2.2", False)
266 check_ping6("ce1", "2001:2::2", False)
267
268
269 def test_locator_recreate():
270 check_ping4("ce1", "192.168.2.2", False)
271 check_ping6("ce1", "2001:2::2", False)
272 get_topogen().gears["r1"].vtysh_cmd(
273 """
274 configure terminal
275 segment-routing
276 srv6
277 locators
278 locator loc1
279 prefix 2001:db8:1:1::/64
280 """
281 )
282 check_rib("r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib_locator_recreated.json")
283 check_rib("r2", "show bgp ipv4 vpn json", "r2/vpnv4_rib_locator_recreated.json")
284 check_rib("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib_locator_recreated.json")
285 check_rib("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib_locator_recreated.json")
286 check_ping4("ce1", "192.168.2.2", True)
287 check_ping6("ce1", "2001:2::2", True)
288
289
290 def test_bgp_locator_unset():
291 check_ping4("ce1", "192.168.2.2", True)
292 check_ping6("ce1", "2001:2::2", True)
293 get_topogen().gears["r1"].vtysh_cmd(
294 """
295 configure terminal
296 router bgp 1
297 segment-routing srv6
298 no locator loc1
299 """
300 )
301 check_rib("r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib_locator_deleted.json")
302 check_rib("r2", "show bgp ipv4 vpn json", "r2/vpnv4_rib_locator_deleted.json")
303 check_rib("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib_locator_deleted.json")
304 check_rib("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib_locator_deleted.json")
305 check_ping4("ce1", "192.168.2.2", False)
306 check_ping6("ce1", "2001:2::2", False)
307
308
309 def test_bgp_locator_reset():
310 check_ping4("ce1", "192.168.2.2", False)
311 check_ping6("ce1", "2001:2::2", False)
312 get_topogen().gears["r1"].vtysh_cmd(
313 """
314 configure terminal
315 router bgp 1
316 segment-routing srv6
317 locator loc1
318 """
319 )
320 check_rib("r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib_locator_recreated.json")
321 check_rib("r2", "show bgp ipv4 vpn json", "r2/vpnv4_rib_locator_recreated.json")
322 check_rib("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib_locator_recreated.json")
323 check_rib("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib_locator_recreated.json")
324 check_ping4("ce1", "192.168.2.2", True)
325 check_ping6("ce1", "2001:2::2", True)
326
327
328 def test_bgp_srv6_unset():
329 check_ping4("ce1", "192.168.2.2", True)
330 check_ping6("ce1", "2001:2::2", True)
331 get_topogen().gears["r1"].vtysh_cmd(
332 """
333 configure terminal
334 router bgp 1
335 no segment-routing srv6
336 """
337 )
338 check_rib("r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib_locator_deleted.json")
339 check_rib("r2", "show bgp ipv4 vpn json", "r2/vpnv4_rib_locator_deleted.json")
340 check_rib("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib_locator_deleted.json")
341 check_rib("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib_locator_deleted.json")
342 check_ping4("ce1", "192.168.2.2", False)
343 check_ping6("ce1", "2001:2::2", False)
344
345
346 def test_bgp_srv6_reset():
347 check_ping4("ce1", "192.168.2.2", False)
348 check_ping6("ce1", "2001:2::2", False)
349 get_topogen().gears["r1"].vtysh_cmd(
350 """
351 configure terminal
352 router bgp 1
353 segment-routing srv6
354 locator loc1
355 """
356 )
357 check_rib("r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib_locator_recreated.json")
358 check_rib("r2", "show bgp ipv4 vpn json", "r2/vpnv4_rib_locator_recreated.json")
359 check_rib("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib_locator_recreated.json")
360 check_rib("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib_locator_recreated.json")
361 check_ping4("ce1", "192.168.2.2", True)
362 check_ping6("ce1", "2001:2::2", True)
363
364
365 if __name__ == "__main__":
366 args = ["-s"] + sys.argv[1:]
367 sys.exit(pytest.main(args))