]> git.proxmox.com Git - mirror_frr.git/blame - tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py
tests: Actually loop if ping fails
[mirror_frr.git] / tests / topotests / bgp_srv6l3vpn_to_bgp_vrf3 / test_bgp_srv6l3vpn_to_bgp_vrf3.py
CommitLineData
3a94d672 1#!/usr/bin/env python
acddc0ed 2# SPDX-License-Identifier: ISC
3a94d672
CS
3
4# Copyright (c) 2022, University of Rome Tor Vergata
5# Authored by Carmine Scarpitta <carmine.scarpitta@uniroma2.it>
6#
3a94d672
CS
7
8import os
9import re
10import sys
11import json
12import functools
13import pytest
14
15CWD = os.path.dirname(os.path.realpath(__file__))
16sys.path.append(os.path.join(CWD, "../"))
17
18# pylint: disable=C0413
19# Import topogen and topotest helpers
20from lib import topotest
21from lib.topogen import Topogen, TopoRouter, get_topogen
22from lib.topolog import logger
23from lib.common_config import required_linux_kernel_version
24
25pytestmark = [pytest.mark.bgpd]
26
27
28def 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
47def 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))
625fe20b
RS
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 )
3a94d672
CS
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
83def teardown_module(mod):
84 tgen = get_topogen()
85 tgen.stop_topology()
86
87
88def 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
96def 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)
22c10bbd
DS
101 if match not in output:
102 return "ping fail"
3a94d672 103
625fe20b 104 match = ", {} packet loss".format("0%" if expect_connected else "100%")
3a94d672
CS
105 logger.info("[+] check {} {} {}".format(name, dest_addr, match))
106 tgen = get_topogen()
107 func = functools.partial(_check, name, dest_addr, match)
108 success, result = topotest.run_and_expect(func, None, count=10, wait=0.5)
109 assert result is None, "Failed"
110
111
112def check_ping6(name, dest_addr, expect_connected):
113 def _check(name, dest_addr, match):
114 tgen = get_topogen()
115 output = tgen.gears[name].run("ping6 {} -c 1 -w 1".format(dest_addr))
116 logger.info(output)
117 if match not in output:
118 return "ping fail"
119
120 match = "{} packet loss".format("0%" if expect_connected else "100%")
121 logger.info("[+] check {} {} {}".format(name, dest_addr, match))
122 tgen = get_topogen()
123 func = functools.partial(_check, name, dest_addr, match)
124 success, result = topotest.run_and_expect(func, None, count=10, wait=1)
125 assert result is None, "Failed"
126
127
128def check_rib(name, cmd, expected_file):
129 def _check(name, dest_addr, match):
130 logger.info("polling")
131 tgen = get_topogen()
132 router = tgen.gears[name]
133 output = json.loads(router.vtysh_cmd(cmd))
134 expected = open_json_file("{}/{}".format(CWD, expected_file))
135 return topotest.json_cmp(output, expected)
136
625fe20b 137 logger.info('[+] check {} "{}" {}'.format(name, cmd, expected_file))
3a94d672
CS
138 tgen = get_topogen()
139 func = functools.partial(_check, name, cmd, expected_file)
140 success, result = topotest.run_and_expect(func, None, count=10, wait=0.5)
141 assert result is None, "Failed"
142
143
144def test_rib():
145 check_rib("r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib.json")
146 check_rib("r2", "show bgp ipv4 vpn json", "r2/vpnv4_rib.json")
147 check_rib("r1", "show ip route vrf vrf10 json", "r1/vrf10v4_rib.json")
148 check_rib("r1", "show ip route vrf vrf20 json", "r1/vrf20v4_rib.json")
149 check_rib("r2", "show ip route vrf vrf10 json", "r2/vrf10v4_rib.json")
150 check_rib("r2", "show ip route vrf vrf20 json", "r2/vrf20v4_rib.json")
151 check_rib("ce1", "show ip route json", "ce1/ip_rib.json")
152 check_rib("ce2", "show ip route json", "ce2/ip_rib.json")
153 check_rib("ce3", "show ip route json", "ce3/ip_rib.json")
154 check_rib("ce4", "show ip route json", "ce4/ip_rib.json")
155 check_rib("ce5", "show ip route json", "ce5/ip_rib.json")
156 check_rib("ce6", "show ip route json", "ce6/ip_rib.json")
157
158 check_rib("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib.json")
159 check_rib("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib.json")
160 check_rib("r1", "show ipv6 route vrf vrf10 json", "r1/vrf10v6_rib.json")
161 check_rib("r1", "show ipv6 route vrf vrf20 json", "r1/vrf20v6_rib.json")
162 check_rib("r2", "show ipv6 route vrf vrf10 json", "r2/vrf10v6_rib.json")
163 check_rib("r2", "show ipv6 route vrf vrf20 json", "r2/vrf20v6_rib.json")
164 check_rib("ce1", "show ipv6 route json", "ce1/ipv6_rib.json")
165 check_rib("ce2", "show ipv6 route json", "ce2/ipv6_rib.json")
166 check_rib("ce3", "show ipv6 route json", "ce3/ipv6_rib.json")
167 check_rib("ce4", "show ipv6 route json", "ce4/ipv6_rib.json")
168 check_rib("ce5", "show ipv6 route json", "ce5/ipv6_rib.json")
169 check_rib("ce6", "show ipv6 route json", "ce6/ipv6_rib.json")
170
171
172def test_ping():
173 check_ping4("ce1", "192.168.2.2", True)
174 check_ping4("ce1", "192.168.3.2", True)
175 check_ping4("ce1", "192.168.4.2", False)
176 check_ping4("ce1", "192.168.5.2", False)
177 check_ping4("ce1", "192.168.6.2", False)
178 check_ping4("ce4", "192.168.1.2", False)
179 check_ping4("ce4", "192.168.2.2", False)
180 check_ping4("ce4", "192.168.3.2", False)
181 check_ping4("ce4", "192.168.5.2", True)
182 check_ping4("ce4", "192.168.6.2", True)
183
184 check_ping6("ce1", "2001:2::2", True)
185 check_ping6("ce1", "2001:3::2", True)
186 check_ping6("ce1", "2001:4::2", False)
187 check_ping6("ce1", "2001:5::2", False)
188 check_ping6("ce1", "2001:6::2", False)
189 check_ping6("ce4", "2001:1::2", False)
190 check_ping6("ce4", "2001:2::2", False)
191 check_ping6("ce4", "2001:3::2", False)
192 check_ping6("ce4", "2001:5::2", True)
193 check_ping6("ce4", "2001:6::2", True)
194
195
b3c5e11c
CS
196def test_bgp_sid_vpn_export_disable():
197 check_ping4("ce1", "192.168.2.2", True)
198 check_ping6("ce1", "2001:2::2", True)
199 get_topogen().gears["r1"].vtysh_cmd(
200 """
201 configure terminal
202 router bgp 1 vrf vrf10
203 segment-routing srv6
204 no sid vpn per-vrf export
205 """
206 )
625fe20b
RS
207 check_rib(
208 "r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib_sid_vpn_export_disabled.json"
209 )
210 check_rib(
211 "r2", "show bgp ipv4 vpn json", "r2/vpnv4_rib_sid_vpn_export_disabled.json"
212 )
213 check_rib(
214 "r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib_sid_vpn_export_disabled.json"
215 )
216 check_rib(
217 "r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib_sid_vpn_export_disabled.json"
218 )
b3c5e11c
CS
219 check_ping4("ce1", "192.168.2.2", False)
220 check_ping6("ce1", "2001:2::2", False)
221
222
223def test_bgp_sid_vpn_export_reenable():
224 check_ping4("ce1", "192.168.2.2", False)
225 check_ping6("ce1", "2001:2::2", False)
226 get_topogen().gears["r1"].vtysh_cmd(
227 """
228 configure terminal
229 router bgp 1 vrf vrf10
230 segment-routing srv6
231 sid vpn per-vrf export auto
232 """
233 )
625fe20b
RS
234 check_rib(
235 "r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib_sid_vpn_export_reenabled.json"
236 )
237 check_rib(
238 "r2", "show bgp ipv4 vpn json", "r2/vpnv4_rib_sid_vpn_export_reenabled.json"
239 )
240 check_rib(
241 "r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib_sid_vpn_export_reenabled.json"
242 )
243 check_rib(
244 "r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib_sid_vpn_export_reenabled.json"
245 )
b3c5e11c
CS
246 check_ping4("ce1", "192.168.2.2", True)
247 check_ping6("ce1", "2001:2::2", True)
248
249
3a94d672
CS
250def test_locator_delete():
251 check_ping4("ce1", "192.168.2.2", True)
252 check_ping6("ce1", "2001:2::2", True)
253 get_topogen().gears["r1"].vtysh_cmd(
254 """
255 configure terminal
256 segment-routing
257 srv6
258 locators
259 no locator loc1
260 """
261 )
262 check_rib("r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib_locator_deleted.json")
263 check_rib("r2", "show bgp ipv4 vpn json", "r2/vpnv4_rib_locator_deleted.json")
264 check_rib("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib_locator_deleted.json")
265 check_rib("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib_locator_deleted.json")
266 check_ping4("ce1", "192.168.2.2", False)
267 check_ping6("ce1", "2001:2::2", False)
268
269
270def test_locator_recreate():
271 check_ping4("ce1", "192.168.2.2", False)
272 check_ping6("ce1", "2001:2::2", False)
273 get_topogen().gears["r1"].vtysh_cmd(
274 """
275 configure terminal
276 segment-routing
277 srv6
278 locators
279 locator loc1
280 prefix 2001:db8:1:1::/64
281 """
282 )
283 check_rib("r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib_locator_recreated.json")
284 check_rib("r2", "show bgp ipv4 vpn json", "r2/vpnv4_rib_locator_recreated.json")
285 check_rib("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib_locator_recreated.json")
286 check_rib("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib_locator_recreated.json")
287 check_ping4("ce1", "192.168.2.2", True)
288 check_ping6("ce1", "2001:2::2", True)
289
290
291def test_bgp_locator_unset():
292 check_ping4("ce1", "192.168.2.2", True)
293 check_ping6("ce1", "2001:2::2", True)
294 get_topogen().gears["r1"].vtysh_cmd(
295 """
296 configure terminal
297 router bgp 1
298 segment-routing srv6
299 no locator loc1
300 """
301 )
302 check_rib("r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib_locator_deleted.json")
303 check_rib("r2", "show bgp ipv4 vpn json", "r2/vpnv4_rib_locator_deleted.json")
304 check_rib("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib_locator_deleted.json")
305 check_rib("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib_locator_deleted.json")
306 check_ping4("ce1", "192.168.2.2", False)
307 check_ping6("ce1", "2001:2::2", False)
308
309
310def test_bgp_locator_reset():
311 check_ping4("ce1", "192.168.2.2", False)
312 check_ping6("ce1", "2001:2::2", False)
313 get_topogen().gears["r1"].vtysh_cmd(
314 """
315 configure terminal
316 router bgp 1
317 segment-routing srv6
318 locator loc1
319 """
320 )
321 check_rib("r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib_locator_recreated.json")
322 check_rib("r2", "show bgp ipv4 vpn json", "r2/vpnv4_rib_locator_recreated.json")
323 check_rib("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib_locator_recreated.json")
324 check_rib("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib_locator_recreated.json")
325 check_ping4("ce1", "192.168.2.2", True)
326 check_ping6("ce1", "2001:2::2", True)
327
328
329def test_bgp_srv6_unset():
330 check_ping4("ce1", "192.168.2.2", True)
331 check_ping6("ce1", "2001:2::2", True)
332 get_topogen().gears["r1"].vtysh_cmd(
333 """
334 configure terminal
335 router bgp 1
336 no segment-routing srv6
337 """
338 )
339 check_rib("r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib_locator_deleted.json")
340 check_rib("r2", "show bgp ipv4 vpn json", "r2/vpnv4_rib_locator_deleted.json")
341 check_rib("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib_locator_deleted.json")
342 check_rib("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib_locator_deleted.json")
343 check_ping4("ce1", "192.168.2.2", False)
344 check_ping6("ce1", "2001:2::2", False)
345
346
347def test_bgp_srv6_reset():
348 check_ping4("ce1", "192.168.2.2", False)
349 check_ping6("ce1", "2001:2::2", False)
350 get_topogen().gears["r1"].vtysh_cmd(
351 """
352 configure terminal
353 router bgp 1
354 segment-routing srv6
355 locator loc1
356 """
357 )
358 check_rib("r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib_locator_recreated.json")
359 check_rib("r2", "show bgp ipv4 vpn json", "r2/vpnv4_rib_locator_recreated.json")
360 check_rib("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib_locator_recreated.json")
361 check_rib("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib_locator_recreated.json")
362 check_ping4("ce1", "192.168.2.2", True)
363 check_ping6("ce1", "2001:2::2", True)
364
365
366if __name__ == "__main__":
367 args = ["-s"] + sys.argv[1:]
368 sys.exit(pytest.main(args))