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