Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3#
4# This test is for checking bridge backup port and backup nexthop ID
5# functionality. The topology consists of two bridge (VTEPs) connected using
6# VXLAN. The test checks that when the switch port (swp1) is down, traffic is
7# redirected to the VXLAN port (vx0). When a backup nexthop ID is configured,
8# the test checks that traffic is redirected with the correct nexthop
9# information.
10#
11# +------------------------------------+ +------------------------------------+
12# | + swp1 + vx0 | | + swp1 + vx0 |
13# | | | | | | | |
14# | | br0 | | | | | |
15# | +------------+-----------+ | | +------------+-----------+ |
16# | | | | | |
17# | | | | | |
18# | + | | + |
19# | br0 | | br0 |
20# | + | | + |
21# | | | | | |
22# | | | | | |
23# | + | | + |
24# | br0.10 | | br0.10 |
25# | 192.0.2.65/28 | | 192.0.2.66/28 |
26# | | | |
27# | | | |
28# | 192.0.2.33 | | 192.0.2.34 |
29# | + lo | | + lo |
30# | | | |
31# | | | |
32# | 192.0.2.49/28 | | 192.0.2.50/28 |
33# | veth0 +-------+ veth0 |
34# | | | |
35# | sw1 | | sw2 |
36# +------------------------------------+ +------------------------------------+
37
38source lib.sh
39ret=0
40
41# All tests in this script. Can be overridden with -t option.
42TESTS="
43 backup_port
44 backup_nhid
45 backup_nhid_invalid
46 backup_nhid_ping
47 backup_nhid_torture
48"
49VERBOSE=0
50PAUSE_ON_FAIL=no
51PAUSE=no
52PING_TIMEOUT=5
53
54################################################################################
55# Utilities
56
57log_test()
58{
59 local rc=$1
60 local expected=$2
61 local msg="$3"
62
63 if [ ${rc} -eq ${expected} ]; then
64 printf "TEST: %-60s [ OK ]\n" "${msg}"
65 nsuccess=$((nsuccess+1))
66 else
67 ret=1
68 nfail=$((nfail+1))
69 printf "TEST: %-60s [FAIL]\n" "${msg}"
70 if [ "$VERBOSE" = "1" ]; then
71 echo " rc=$rc, expected $expected"
72 fi
73
74 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
75 echo
76 echo "hit enter to continue, 'q' to quit"
77 read a
78 [ "$a" = "q" ] && exit 1
79 fi
80 fi
81
82 if [ "${PAUSE}" = "yes" ]; then
83 echo
84 echo "hit enter to continue, 'q' to quit"
85 read a
86 [ "$a" = "q" ] && exit 1
87 fi
88
89 [ "$VERBOSE" = "1" ] && echo
90}
91
92run_cmd()
93{
94 local cmd="$1"
95 local out
96 local stderr="2>/dev/null"
97
98 if [ "$VERBOSE" = "1" ]; then
99 printf "COMMAND: $cmd\n"
100 stderr=
101 fi
102
103 out=$(eval $cmd $stderr)
104 rc=$?
105 if [ "$VERBOSE" = "1" -a -n "$out" ]; then
106 echo " $out"
107 fi
108
109 return $rc
110}
111
112tc_check_packets()
113{
114 local ns=$1; shift
115 local id=$1; shift
116 local handle=$1; shift
117 local count=$1; shift
118 local pkts
119
120 sleep 0.1
121 pkts=$(tc -n $ns -j -s filter show $id \
122 | jq ".[] | select(.options.handle == $handle) | \
123 .options.actions[0].stats.packets")
124 [[ $pkts == $count ]]
125}
126
127bridge_link_check()
128{
129 local ns=$1; shift
130 local dev=$1; shift
131 local state=$1; shift
132
133 bridge -n $ns -d -j link show dev $dev | \
134 jq -e ".[][\"state\"] == \"$state\"" &> /dev/null
135}
136
137################################################################################
138# Setup
139
140setup_topo_ns()
141{
142 local ns=$1; shift
143
144 ip netns exec $ns sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1
145 ip netns exec $ns sysctl -qw net.ipv6.conf.default.ignore_routes_with_linkdown=1
146 ip netns exec $ns sysctl -qw net.ipv6.conf.all.accept_dad=0
147 ip netns exec $ns sysctl -qw net.ipv6.conf.default.accept_dad=0
148}
149
150setup_topo()
151{
152 local ns
153
154 setup_ns sw1 sw2
155 for ns in $sw1 $sw2; do
156 setup_topo_ns $ns
157 done
158
159 ip link add name veth0 type veth peer name veth1
160 ip link set dev veth0 netns $sw1 name veth0
161 ip link set dev veth1 netns $sw2 name veth0
162}
163
164setup_sw_common()
165{
166 local ns=$1; shift
167 local local_addr=$1; shift
168 local remote_addr=$1; shift
169 local veth_addr=$1; shift
170 local gw_addr=$1; shift
171 local br_addr=$1; shift
172
173 ip -n $ns address add $local_addr/32 dev lo
174
175 ip -n $ns link set dev veth0 up
176 ip -n $ns address add $veth_addr/28 dev veth0
177 ip -n $ns route add default via $gw_addr
178
179 ip -n $ns link add name br0 up type bridge vlan_filtering 1 \
180 vlan_default_pvid 0 mcast_snooping 0
181
182 ip -n $ns link add link br0 name br0.10 up type vlan id 10
183 bridge -n $ns vlan add vid 10 dev br0 self
184 ip -n $ns address add $br_addr/28 dev br0.10
185
186 ip -n $ns link add name swp1 up type dummy
187 ip -n $ns link set dev swp1 master br0
188 bridge -n $ns vlan add vid 10 dev swp1 untagged
189
190 ip -n $ns link add name vx0 up master br0 type vxlan \
191 local $local_addr dstport 4789 nolearning external
192 bridge -n $ns link set dev vx0 vlan_tunnel on learning off
193
194 bridge -n $ns vlan add vid 10 dev vx0
195 bridge -n $ns vlan add vid 10 dev vx0 tunnel_info id 10010
196}
197
198setup_sw1()
199{
200 local ns=$sw1
201 local local_addr=192.0.2.33
202 local remote_addr=192.0.2.34
203 local veth_addr=192.0.2.49
204 local gw_addr=192.0.2.50
205 local br_addr=192.0.2.65
206
207 setup_sw_common $ns $local_addr $remote_addr $veth_addr $gw_addr \
208 $br_addr
209}
210
211setup_sw2()
212{
213 local ns=$sw2
214 local local_addr=192.0.2.34
215 local remote_addr=192.0.2.33
216 local veth_addr=192.0.2.50
217 local gw_addr=192.0.2.49
218 local br_addr=192.0.2.66
219
220 setup_sw_common $ns $local_addr $remote_addr $veth_addr $gw_addr \
221 $br_addr
222}
223
224setup()
225{
226 set -e
227
228 setup_topo
229 setup_sw1
230 setup_sw2
231
232 sleep 5
233
234 set +e
235}
236
237cleanup()
238{
239 cleanup_ns $sw1 $sw2
240}
241
242################################################################################
243# Tests
244
245backup_port()
246{
247 local dmac=00:11:22:33:44:55
248 local smac=00:aa:bb:cc:dd:ee
249
250 echo
251 echo "Backup port"
252 echo "-----------"
253
254 run_cmd "tc -n $sw1 qdisc replace dev swp1 clsact"
255 run_cmd "tc -n $sw1 filter replace dev swp1 egress pref 1 handle 101 proto ip flower src_mac $smac dst_mac $dmac action pass"
256
257 run_cmd "tc -n $sw1 qdisc replace dev vx0 clsact"
258 run_cmd "tc -n $sw1 filter replace dev vx0 egress pref 1 handle 101 proto ip flower src_mac $smac dst_mac $dmac action pass"
259
260 run_cmd "bridge -n $sw1 fdb replace $dmac dev swp1 master static vlan 10"
261
262 # Initial state - check that packets are forwarded out of swp1 when it
263 # has a carrier and not forwarded out of any port when it does not have
264 # a carrier.
265 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1"
266 tc_check_packets $sw1 "dev swp1 egress" 101 1
267 log_test $? 0 "Forwarding out of swp1"
268 tc_check_packets $sw1 "dev vx0 egress" 101 0
269 log_test $? 0 "No forwarding out of vx0"
270
271 run_cmd "ip -n $sw1 link set dev swp1 carrier off"
272 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 disabled
273 log_test $? 0 "swp1 carrier off"
274
275 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1"
276 tc_check_packets $sw1 "dev swp1 egress" 101 1
277 log_test $? 0 "No forwarding out of swp1"
278 tc_check_packets $sw1 "dev vx0 egress" 101 0
279 log_test $? 0 "No forwarding out of vx0"
280
281 run_cmd "ip -n $sw1 link set dev swp1 carrier on"
282 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 forwarding
283 log_test $? 0 "swp1 carrier on"
284
285 # Configure vx0 as the backup port of swp1 and check that packets are
286 # forwarded out of swp1 when it has a carrier and out of vx0 when swp1
287 # does not have a carrier.
288 run_cmd "bridge -n $sw1 link set dev swp1 backup_port vx0"
289 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_port vx0\""
290 log_test $? 0 "vx0 configured as backup port of swp1"
291
292 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1"
293 tc_check_packets $sw1 "dev swp1 egress" 101 2
294 log_test $? 0 "Forwarding out of swp1"
295 tc_check_packets $sw1 "dev vx0 egress" 101 0
296 log_test $? 0 "No forwarding out of vx0"
297
298 run_cmd "ip -n $sw1 link set dev swp1 carrier off"
299 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 disabled
300 log_test $? 0 "swp1 carrier off"
301
302 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1"
303 tc_check_packets $sw1 "dev swp1 egress" 101 2
304 log_test $? 0 "No forwarding out of swp1"
305 tc_check_packets $sw1 "dev vx0 egress" 101 1
306 log_test $? 0 "Forwarding out of vx0"
307
308 run_cmd "ip -n $sw1 link set dev swp1 carrier on"
309 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 forwarding
310 log_test $? 0 "swp1 carrier on"
311
312 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1"
313 tc_check_packets $sw1 "dev swp1 egress" 101 3
314 log_test $? 0 "Forwarding out of swp1"
315 tc_check_packets $sw1 "dev vx0 egress" 101 1
316 log_test $? 0 "No forwarding out of vx0"
317
318 # Check that packets are forwarded out of vx0 when swp1 is
319 # administratively down and out of swp1 when it is administratively up
320 # again.
321 run_cmd "ip -n $sw1 link set dev swp1 down"
322 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 disabled
323 log_test $? 0 "swp1 administratively down"
324
325 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1"
326 tc_check_packets $sw1 "dev swp1 egress" 101 3
327 log_test $? 0 "No forwarding out of swp1"
328 tc_check_packets $sw1 "dev vx0 egress" 101 2
329 log_test $? 0 "Forwarding out of vx0"
330
331 run_cmd "ip -n $sw1 link set dev swp1 up"
332 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 forwarding
333 log_test $? 0 "swp1 administratively up"
334
335 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1"
336 tc_check_packets $sw1 "dev swp1 egress" 101 4
337 log_test $? 0 "Forwarding out of swp1"
338 tc_check_packets $sw1 "dev vx0 egress" 101 2
339 log_test $? 0 "No forwarding out of vx0"
340
341 # Remove vx0 as the backup port of swp1 and check that packets are no
342 # longer forwarded out of vx0 when swp1 does not have a carrier.
343 run_cmd "bridge -n $sw1 link set dev swp1 nobackup_port"
344 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_port vx0\""
345 log_test $? 1 "vx0 not configured as backup port of swp1"
346
347 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1"
348 tc_check_packets $sw1 "dev swp1 egress" 101 5
349 log_test $? 0 "Forwarding out of swp1"
350 tc_check_packets $sw1 "dev vx0 egress" 101 2
351 log_test $? 0 "No forwarding out of vx0"
352
353 run_cmd "ip -n $sw1 link set dev swp1 carrier off"
354 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 disabled
355 log_test $? 0 "swp1 carrier off"
356
357 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1"
358 tc_check_packets $sw1 "dev swp1 egress" 101 5
359 log_test $? 0 "No forwarding out of swp1"
360 tc_check_packets $sw1 "dev vx0 egress" 101 2
361 log_test $? 0 "No forwarding out of vx0"
362}
363
364backup_nhid()
365{
366 local dmac=00:11:22:33:44:55
367 local smac=00:aa:bb:cc:dd:ee
368
369 echo
370 echo "Backup nexthop ID"
371 echo "-----------------"
372
373 run_cmd "tc -n $sw1 qdisc replace dev swp1 clsact"
374 run_cmd "tc -n $sw1 filter replace dev swp1 egress pref 1 handle 101 proto ip flower src_mac $smac dst_mac $dmac action pass"
375
376 run_cmd "tc -n $sw1 qdisc replace dev vx0 clsact"
377 run_cmd "tc -n $sw1 filter replace dev vx0 egress pref 1 handle 101 proto ip flower src_mac $smac dst_mac $dmac action pass"
378
379 run_cmd "ip -n $sw1 nexthop replace id 1 via 192.0.2.34 fdb"
380 run_cmd "ip -n $sw1 nexthop replace id 2 via 192.0.2.34 fdb"
381 run_cmd "ip -n $sw1 nexthop replace id 10 group 1/2 fdb"
382
383 run_cmd "bridge -n $sw1 fdb replace $dmac dev swp1 master static vlan 10"
384 run_cmd "bridge -n $sw1 fdb replace $dmac dev vx0 self static dst 192.0.2.36 src_vni 10010"
385
386 run_cmd "ip -n $sw2 address replace 192.0.2.36/32 dev lo"
387
388 # The first filter matches on packets forwarded using the backup
389 # nexthop ID and the second filter matches on packets forwarded using a
390 # regular VXLAN FDB entry.
391 run_cmd "tc -n $sw2 qdisc replace dev vx0 clsact"
392 run_cmd "tc -n $sw2 filter replace dev vx0 ingress pref 1 handle 101 proto ip flower src_mac $smac dst_mac $dmac enc_key_id 10010 enc_dst_ip 192.0.2.34 action pass"
393 run_cmd "tc -n $sw2 filter replace dev vx0 ingress pref 1 handle 102 proto ip flower src_mac $smac dst_mac $dmac enc_key_id 10010 enc_dst_ip 192.0.2.36 action pass"
394
395 # Configure vx0 as the backup port of swp1 and check that packets are
396 # forwarded out of swp1 when it has a carrier and out of vx0 when swp1
397 # does not have a carrier. When packets are forwarded out of vx0, check
398 # that they are forwarded by the VXLAN FDB entry.
399 run_cmd "bridge -n $sw1 link set dev swp1 backup_port vx0"
400 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_port vx0\""
401 log_test $? 0 "vx0 configured as backup port of swp1"
402
403 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1"
404 tc_check_packets $sw1 "dev swp1 egress" 101 1
405 log_test $? 0 "Forwarding out of swp1"
406 tc_check_packets $sw1 "dev vx0 egress" 101 0
407 log_test $? 0 "No forwarding out of vx0"
408
409 run_cmd "ip -n $sw1 link set dev swp1 carrier off"
410 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 disabled
411 log_test $? 0 "swp1 carrier off"
412
413 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1"
414 tc_check_packets $sw1 "dev swp1 egress" 101 1
415 log_test $? 0 "No forwarding out of swp1"
416 tc_check_packets $sw1 "dev vx0 egress" 101 1
417 log_test $? 0 "Forwarding out of vx0"
418 tc_check_packets $sw2 "dev vx0 ingress" 101 0
419 log_test $? 0 "No forwarding using backup nexthop ID"
420 tc_check_packets $sw2 "dev vx0 ingress" 102 1
421 log_test $? 0 "Forwarding using VXLAN FDB entry"
422
423 run_cmd "ip -n $sw1 link set dev swp1 carrier on"
424 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 forwarding
425 log_test $? 0 "swp1 carrier on"
426
427 # Configure nexthop ID 10 as the backup nexthop ID of swp1 and check
428 # that when packets are forwarded out of vx0, they are forwarded using
429 # the backup nexthop ID.
430 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 10"
431 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_nhid 10\""
432 log_test $? 0 "nexthop ID 10 configured as backup nexthop ID of swp1"
433
434 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1"
435 tc_check_packets $sw1 "dev swp1 egress" 101 2
436 log_test $? 0 "Forwarding out of swp1"
437 tc_check_packets $sw1 "dev vx0 egress" 101 1
438 log_test $? 0 "No forwarding out of vx0"
439
440 run_cmd "ip -n $sw1 link set dev swp1 carrier off"
441 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 disabled
442 log_test $? 0 "swp1 carrier off"
443
444 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1"
445 tc_check_packets $sw1 "dev swp1 egress" 101 2
446 log_test $? 0 "No forwarding out of swp1"
447 tc_check_packets $sw1 "dev vx0 egress" 101 2
448 log_test $? 0 "Forwarding out of vx0"
449 tc_check_packets $sw2 "dev vx0 ingress" 101 1
450 log_test $? 0 "Forwarding using backup nexthop ID"
451 tc_check_packets $sw2 "dev vx0 ingress" 102 1
452 log_test $? 0 "No forwarding using VXLAN FDB entry"
453
454 run_cmd "ip -n $sw1 link set dev swp1 carrier on"
455 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 forwarding
456 log_test $? 0 "swp1 carrier on"
457
458 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1"
459 tc_check_packets $sw1 "dev swp1 egress" 101 3
460 log_test $? 0 "Forwarding out of swp1"
461 tc_check_packets $sw1 "dev vx0 egress" 101 2
462 log_test $? 0 "No forwarding out of vx0"
463 tc_check_packets $sw2 "dev vx0 ingress" 101 1
464 log_test $? 0 "No forwarding using backup nexthop ID"
465 tc_check_packets $sw2 "dev vx0 ingress" 102 1
466 log_test $? 0 "No forwarding using VXLAN FDB entry"
467
468 # Reset the backup nexthop ID to 0 and check that packets are no longer
469 # forwarded using the backup nexthop ID when swp1 does not have a
470 # carrier and are instead forwarded by the VXLAN FDB.
471 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 0"
472 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_nhid\""
473 log_test $? 1 "No backup nexthop ID configured for swp1"
474
475 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1"
476 tc_check_packets $sw1 "dev swp1 egress" 101 4
477 log_test $? 0 "Forwarding out of swp1"
478 tc_check_packets $sw1 "dev vx0 egress" 101 2
479 log_test $? 0 "No forwarding out of vx0"
480 tc_check_packets $sw2 "dev vx0 ingress" 101 1
481 log_test $? 0 "No forwarding using backup nexthop ID"
482 tc_check_packets $sw2 "dev vx0 ingress" 102 1
483 log_test $? 0 "No forwarding using VXLAN FDB entry"
484
485 run_cmd "ip -n $sw1 link set dev swp1 carrier off"
486 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 disabled
487 log_test $? 0 "swp1 carrier off"
488
489 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1"
490 tc_check_packets $sw1 "dev swp1 egress" 101 4
491 log_test $? 0 "No forwarding out of swp1"
492 tc_check_packets $sw1 "dev vx0 egress" 101 3
493 log_test $? 0 "Forwarding out of vx0"
494 tc_check_packets $sw2 "dev vx0 ingress" 101 1
495 log_test $? 0 "No forwarding using backup nexthop ID"
496 tc_check_packets $sw2 "dev vx0 ingress" 102 2
497 log_test $? 0 "Forwarding using VXLAN FDB entry"
498}
499
500backup_nhid_invalid()
501{
502 local dmac=00:11:22:33:44:55
503 local smac=00:aa:bb:cc:dd:ee
504 local tx_drop
505
506 echo
507 echo "Backup nexthop ID - invalid IDs"
508 echo "-------------------------------"
509
510 # Check that when traffic is redirected with an invalid nexthop ID, it
511 # is forwarded out of the VXLAN port, but dropped by the VXLAN driver
512 # and does not crash the host.
513
514 run_cmd "tc -n $sw1 qdisc replace dev swp1 clsact"
515 run_cmd "tc -n $sw1 filter replace dev swp1 egress pref 1 handle 101 proto ip flower src_mac $smac dst_mac $dmac action pass"
516
517 run_cmd "tc -n $sw1 qdisc replace dev vx0 clsact"
518 run_cmd "tc -n $sw1 filter replace dev vx0 egress pref 1 handle 101 proto ip flower src_mac $smac dst_mac $dmac action pass"
519 # Drop all other Tx traffic to avoid changes to Tx drop counter.
520 run_cmd "tc -n $sw1 filter replace dev vx0 egress pref 2 handle 102 proto all matchall action drop"
521
522 tx_drop=$(ip -n $sw1 -s -j link show dev vx0 | jq '.[]["stats64"]["tx"]["dropped"]')
523
524 run_cmd "ip -n $sw1 nexthop replace id 1 via 192.0.2.34 fdb"
525 run_cmd "ip -n $sw1 nexthop replace id 2 via 192.0.2.34 fdb"
526 run_cmd "ip -n $sw1 nexthop replace id 10 group 1/2 fdb"
527
528 run_cmd "bridge -n $sw1 fdb replace $dmac dev swp1 master static vlan 10"
529
530 run_cmd "tc -n $sw2 qdisc replace dev vx0 clsact"
531 run_cmd "tc -n $sw2 filter replace dev vx0 ingress pref 1 handle 101 proto ip flower src_mac $smac dst_mac $dmac enc_key_id 10010 enc_dst_ip 192.0.2.34 action pass"
532
533 # First, check that redirection works.
534 run_cmd "bridge -n $sw1 link set dev swp1 backup_port vx0"
535 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_port vx0\""
536 log_test $? 0 "vx0 configured as backup port of swp1"
537
538 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 10"
539 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_nhid 10\""
540 log_test $? 0 "Valid nexthop as backup nexthop"
541
542 run_cmd "ip -n $sw1 link set dev swp1 carrier off"
543 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 disabled
544 log_test $? 0 "swp1 carrier off"
545
546 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1"
547 tc_check_packets $sw1 "dev swp1 egress" 101 0
548 log_test $? 0 "No forwarding out of swp1"
549 tc_check_packets $sw1 "dev vx0 egress" 101 1
550 log_test $? 0 "Forwarding out of vx0"
551 tc_check_packets $sw2 "dev vx0 ingress" 101 1
552 log_test $? 0 "Forwarding using backup nexthop ID"
553 run_cmd "ip -n $sw1 -s -j link show dev vx0 | jq -e '.[][\"stats64\"][\"tx\"][\"dropped\"] == $tx_drop'"
554 log_test $? 0 "No Tx drop increase"
555
556 # Use a non-existent nexthop ID.
557 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 20"
558 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_nhid 20\""
559 log_test $? 0 "Non-existent nexthop as backup nexthop"
560
561 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1"
562 tc_check_packets $sw1 "dev swp1 egress" 101 0
563 log_test $? 0 "No forwarding out of swp1"
564 tc_check_packets $sw1 "dev vx0 egress" 101 2
565 log_test $? 0 "Forwarding out of vx0"
566 tc_check_packets $sw2 "dev vx0 ingress" 101 1
567 log_test $? 0 "No forwarding using backup nexthop ID"
568 run_cmd "ip -n $sw1 -s -j link show dev vx0 | jq -e '.[][\"stats64\"][\"tx\"][\"dropped\"] == $((tx_drop + 1))'"
569 log_test $? 0 "Tx drop increased"
570
571 # Use a blckhole nexthop.
572 run_cmd "ip -n $sw1 nexthop replace id 30 blackhole"
573 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 30"
574 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_nhid 30\""
575 log_test $? 0 "Blackhole nexthop as backup nexthop"
576
577 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1"
578 tc_check_packets $sw1 "dev swp1 egress" 101 0
579 log_test $? 0 "No forwarding out of swp1"
580 tc_check_packets $sw1 "dev vx0 egress" 101 3
581 log_test $? 0 "Forwarding out of vx0"
582 tc_check_packets $sw2 "dev vx0 ingress" 101 1
583 log_test $? 0 "No forwarding using backup nexthop ID"
584 run_cmd "ip -n $sw1 -s -j link show dev vx0 | jq -e '.[][\"stats64\"][\"tx\"][\"dropped\"] == $((tx_drop + 2))'"
585 log_test $? 0 "Tx drop increased"
586
587 # Non-group FDB nexthop.
588 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 1"
589 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_nhid 1\""
590 log_test $? 0 "Non-group FDB nexthop as backup nexthop"
591
592 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1"
593 tc_check_packets $sw1 "dev swp1 egress" 101 0
594 log_test $? 0 "No forwarding out of swp1"
595 tc_check_packets $sw1 "dev vx0 egress" 101 4
596 log_test $? 0 "Forwarding out of vx0"
597 tc_check_packets $sw2 "dev vx0 ingress" 101 1
598 log_test $? 0 "No forwarding using backup nexthop ID"
599 run_cmd "ip -n $sw1 -s -j link show dev vx0 | jq -e '.[][\"stats64\"][\"tx\"][\"dropped\"] == $((tx_drop + 3))'"
600 log_test $? 0 "Tx drop increased"
601
602 # IPv6 address family nexthop.
603 run_cmd "ip -n $sw1 nexthop replace id 100 via 2001:db8:100::1 fdb"
604 run_cmd "ip -n $sw1 nexthop replace id 200 via 2001:db8:100::1 fdb"
605 run_cmd "ip -n $sw1 nexthop replace id 300 group 100/200 fdb"
606 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 300"
607 run_cmd "bridge -n $sw1 -d link show dev swp1 | grep \"backup_nhid 300\""
608 log_test $? 0 "IPv6 address family nexthop as backup nexthop"
609
610 run_cmd "ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 1"
611 tc_check_packets $sw1 "dev swp1 egress" 101 0
612 log_test $? 0 "No forwarding out of swp1"
613 tc_check_packets $sw1 "dev vx0 egress" 101 5
614 log_test $? 0 "Forwarding out of vx0"
615 tc_check_packets $sw2 "dev vx0 ingress" 101 1
616 log_test $? 0 "No forwarding using backup nexthop ID"
617 run_cmd "ip -n $sw1 -s -j link show dev vx0 | jq -e '.[][\"stats64\"][\"tx\"][\"dropped\"] == $((tx_drop + 4))'"
618 log_test $? 0 "Tx drop increased"
619}
620
621backup_nhid_ping()
622{
623 local sw1_mac
624 local sw2_mac
625
626 echo
627 echo "Backup nexthop ID - ping"
628 echo "------------------------"
629
630 # Test bidirectional traffic when traffic is redirected in both VTEPs.
631 sw1_mac=$(ip -n $sw1 -j -p link show br0.10 | jq -r '.[]["address"]')
632 sw2_mac=$(ip -n $sw2 -j -p link show br0.10 | jq -r '.[]["address"]')
633
634 run_cmd "bridge -n $sw1 fdb replace $sw2_mac dev swp1 master static vlan 10"
635 run_cmd "bridge -n $sw2 fdb replace $sw1_mac dev swp1 master static vlan 10"
636
637 run_cmd "ip -n $sw1 neigh replace 192.0.2.66 lladdr $sw2_mac nud perm dev br0.10"
638 run_cmd "ip -n $sw2 neigh replace 192.0.2.65 lladdr $sw1_mac nud perm dev br0.10"
639
640 run_cmd "ip -n $sw1 nexthop replace id 1 via 192.0.2.34 fdb"
641 run_cmd "ip -n $sw2 nexthop replace id 1 via 192.0.2.33 fdb"
642 run_cmd "ip -n $sw1 nexthop replace id 10 group 1 fdb"
643 run_cmd "ip -n $sw2 nexthop replace id 10 group 1 fdb"
644
645 run_cmd "bridge -n $sw1 link set dev swp1 backup_port vx0"
646 run_cmd "bridge -n $sw2 link set dev swp1 backup_port vx0"
647 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 10"
648 run_cmd "bridge -n $sw2 link set dev swp1 backup_nhid 10"
649
650 run_cmd "ip -n $sw1 link set dev swp1 carrier off"
651 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw1 swp1 disabled
652 run_cmd "ip -n $sw2 link set dev swp1 carrier off"
653 busywait $BUSYWAIT_TIMEOUT bridge_link_check $sw2 swp1 disabled
654
655 run_cmd "ip netns exec $sw1 ping -i 0.1 -c 10 -w $PING_TIMEOUT 192.0.2.66"
656 log_test $? 0 "Ping with backup nexthop ID"
657
658 # Reset the backup nexthop ID to 0 and check that ping fails.
659 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 0"
660 run_cmd "bridge -n $sw2 link set dev swp1 backup_nhid 0"
661
662 run_cmd "ip netns exec $sw1 ping -i 0.1 -c 10 -w $PING_TIMEOUT 192.0.2.66"
663 log_test $? 1 "Ping after disabling backup nexthop ID"
664}
665
666backup_nhid_add_del_loop()
667{
668 while true; do
669 ip -n $sw1 nexthop del id 10
670 ip -n $sw1 nexthop replace id 10 group 1/2 fdb
671 done >/dev/null 2>&1
672}
673
674backup_nhid_torture()
675{
676 local dmac=00:11:22:33:44:55
677 local smac=00:aa:bb:cc:dd:ee
678 local pid1
679 local pid2
680 local pid3
681
682 echo
683 echo "Backup nexthop ID - torture test"
684 echo "--------------------------------"
685
686 # Continuously send traffic through the backup nexthop while adding and
687 # deleting the group. The test is considered successful if nothing
688 # crashed.
689
690 run_cmd "ip -n $sw1 nexthop replace id 1 via 192.0.2.34 fdb"
691 run_cmd "ip -n $sw1 nexthop replace id 2 via 192.0.2.34 fdb"
692 run_cmd "ip -n $sw1 nexthop replace id 10 group 1/2 fdb"
693
694 run_cmd "bridge -n $sw1 fdb replace $dmac dev swp1 master static vlan 10"
695
696 run_cmd "bridge -n $sw1 link set dev swp1 backup_port vx0"
697 run_cmd "bridge -n $sw1 link set dev swp1 backup_nhid 10"
698 run_cmd "ip -n $sw1 link set dev swp1 carrier off"
699
700 backup_nhid_add_del_loop &
701 pid1=$!
702 ip netns exec $sw1 mausezahn br0.10 -a $smac -b $dmac -A 198.51.100.1 -B 198.51.100.2 -t ip -p 100 -q -c 0 &
703 pid2=$!
704
705 sleep 30
706 kill -9 $pid1 $pid2
707 wait $pid1 $pid2 2>/dev/null
708
709 log_test 0 0 "Torture test"
710}
711
712################################################################################
713# Usage
714
715usage()
716{
717 cat <<EOF
718usage: ${0##*/} OPTS
719
720 -t <test> Test(s) to run (default: all)
721 (options: $TESTS)
722 -p Pause on fail
723 -P Pause after each test before cleanup
724 -v Verbose mode (show commands and output)
725 -w Timeout for ping
726EOF
727}
728
729################################################################################
730# Main
731
732trap cleanup EXIT
733
734while getopts ":t:pPvhw:" opt; do
735 case $opt in
736 t) TESTS=$OPTARG;;
737 p) PAUSE_ON_FAIL=yes;;
738 P) PAUSE=yes;;
739 v) VERBOSE=$(($VERBOSE + 1));;
740 w) PING_TIMEOUT=$OPTARG;;
741 h) usage; exit 0;;
742 *) usage; exit 1;;
743 esac
744done
745
746# Make sure we don't pause twice.
747[ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no
748
749if [ "$(id -u)" -ne 0 ];then
750 echo "SKIP: Need root privileges"
751 exit $ksft_skip;
752fi
753
754if [ ! -x "$(command -v ip)" ]; then
755 echo "SKIP: Could not run test without ip tool"
756 exit $ksft_skip
757fi
758
759if [ ! -x "$(command -v bridge)" ]; then
760 echo "SKIP: Could not run test without bridge tool"
761 exit $ksft_skip
762fi
763
764if [ ! -x "$(command -v tc)" ]; then
765 echo "SKIP: Could not run test without tc tool"
766 exit $ksft_skip
767fi
768
769if [ ! -x "$(command -v mausezahn)" ]; then
770 echo "SKIP: Could not run test without mausezahn tool"
771 exit $ksft_skip
772fi
773
774if [ ! -x "$(command -v jq)" ]; then
775 echo "SKIP: Could not run test without jq tool"
776 exit $ksft_skip
777fi
778
779bridge link help 2>&1 | grep -q "backup_nhid"
780if [ $? -ne 0 ]; then
781 echo "SKIP: iproute2 bridge too old, missing backup nexthop ID support"
782 exit $ksft_skip
783fi
784
785# Start clean.
786cleanup
787
788for t in $TESTS
789do
790 setup; $t; cleanup;
791done
792
793if [ "$TESTS" != "none" ]; then
794 printf "\nTests passed: %3d\n" ${nsuccess}
795 printf "Tests failed: %3d\n" ${nfail}
796fi
797
798exit $ret