Merge tag '6.9-rc5-cifs-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6
[sfrench/cifs-2.6.git] / tools / testing / selftests / net / test_bridge_neigh_suppress.sh
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 #
4 # This test is for checking bridge neighbor suppression functionality. The
5 # topology consists of two bridges (VTEPs) connected using VXLAN. A single
6 # host is connected to each bridge over multiple VLANs. The test checks that
7 # ARP/NS messages from the first host are suppressed on the VXLAN port when
8 # should.
9 #
10 # +-----------------------+              +------------------------+
11 # | h1                    |              | h2                     |
12 # |                       |              |                        |
13 # | + eth0.10             |              | + eth0.10              |
14 # | | 192.0.2.1/28        |              | | 192.0.2.2/28         |
15 # | | 2001:db8:1::1/64    |              | | 2001:db8:1::2/64     |
16 # | |                     |              | |                      |
17 # | |  + eth0.20          |              | |  + eth0.20           |
18 # | \  | 192.0.2.17/28    |              | \  | 192.0.2.18/28     |
19 # |  \ | 2001:db8:2::1/64 |              |  \ | 2001:db8:2::2/64  |
20 # |   \|                  |              |   \|                   |
21 # |    + eth0             |              |    + eth0              |
22 # +----|------------------+              +----|-------------------+
23 #      |                                      |
24 #      |                                      |
25 # +----|-------------------------------+ +----|-------------------------------+
26 # |    + swp1                   + vx0  | |    + swp1                   + vx0  |
27 # |    |                        |      | |    |                        |      |
28 # |    |           br0          |      | |    |                        |      |
29 # |    +------------+-----------+      | |    +------------+-----------+      |
30 # |                 |                  | |                 |                  |
31 # |                 |                  | |                 |                  |
32 # |             +---+---+              | |             +---+---+              |
33 # |             |       |              | |             |       |              |
34 # |             |       |              | |             |       |              |
35 # |             +       +              | |             +       +              |
36 # |          br0.10  br0.20            | |          br0.10  br0.20            |
37 # |                                    | |                                    |
38 # |                 192.0.2.33         | |                 192.0.2.34         |
39 # |                 + lo               | |                 + lo               |
40 # |                                    | |                                    |
41 # |                                    | |                                    |
42 # |                   192.0.2.49/28    | |    192.0.2.50/28                   |
43 # |                           veth0 +-------+ veth0                           |
44 # |                                    | |                                    |
45 # | sw1                                | | sw2                                |
46 # +------------------------------------+ +------------------------------------+
47
48 source lib.sh
49 ret=0
50
51 # All tests in this script. Can be overridden with -t option.
52 TESTS="
53         neigh_suppress_arp
54         neigh_suppress_ns
55         neigh_vlan_suppress_arp
56         neigh_vlan_suppress_ns
57 "
58 VERBOSE=0
59 PAUSE_ON_FAIL=no
60 PAUSE=no
61
62 ################################################################################
63 # Utilities
64
65 log_test()
66 {
67         local rc=$1
68         local expected=$2
69         local msg="$3"
70
71         if [ ${rc} -eq ${expected} ]; then
72                 printf "TEST: %-60s  [ OK ]\n" "${msg}"
73                 nsuccess=$((nsuccess+1))
74         else
75                 ret=1
76                 nfail=$((nfail+1))
77                 printf "TEST: %-60s  [FAIL]\n" "${msg}"
78                 if [ "$VERBOSE" = "1" ]; then
79                         echo "    rc=$rc, expected $expected"
80                 fi
81
82                 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
83                 echo
84                         echo "hit enter to continue, 'q' to quit"
85                         read a
86                         [ "$a" = "q" ] && exit 1
87                 fi
88         fi
89
90         if [ "${PAUSE}" = "yes" ]; then
91                 echo
92                 echo "hit enter to continue, 'q' to quit"
93                 read a
94                 [ "$a" = "q" ] && exit 1
95         fi
96
97         [ "$VERBOSE" = "1" ] && echo
98 }
99
100 run_cmd()
101 {
102         local cmd="$1"
103         local out
104         local stderr="2>/dev/null"
105
106         if [ "$VERBOSE" = "1" ]; then
107                 printf "COMMAND: $cmd\n"
108                 stderr=
109         fi
110
111         out=$(eval $cmd $stderr)
112         rc=$?
113         if [ "$VERBOSE" = "1" -a -n "$out" ]; then
114                 echo "    $out"
115         fi
116
117         return $rc
118 }
119
120 tc_check_packets()
121 {
122         local ns=$1; shift
123         local id=$1; shift
124         local handle=$1; shift
125         local count=$1; shift
126         local pkts
127
128         sleep 0.1
129         pkts=$(tc -n $ns -j -s filter show $id \
130                 | jq ".[] | select(.options.handle == $handle) | \
131                 .options.actions[0].stats.packets")
132         [[ $pkts == $count ]]
133 }
134
135 ################################################################################
136 # Setup
137
138 setup_topo_ns()
139 {
140         local ns=$1; shift
141
142         ip netns exec $ns sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1
143         ip netns exec $ns sysctl -qw net.ipv6.conf.default.ignore_routes_with_linkdown=1
144         ip netns exec $ns sysctl -qw net.ipv6.conf.all.accept_dad=0
145         ip netns exec $ns sysctl -qw net.ipv6.conf.default.accept_dad=0
146 }
147
148 setup_topo()
149 {
150         local ns
151
152         setup_ns h1 h2 sw1 sw2
153         for ns in $h1 $h2 $sw1 $sw2; do
154                 setup_topo_ns $ns
155         done
156
157         ip link add name veth0 type veth peer name veth1
158         ip link set dev veth0 netns $h1 name eth0
159         ip link set dev veth1 netns $sw1 name swp1
160
161         ip link add name veth0 type veth peer name veth1
162         ip link set dev veth0 netns $sw1 name veth0
163         ip link set dev veth1 netns $sw2 name veth0
164
165         ip link add name veth0 type veth peer name veth1
166         ip link set dev veth0 netns $h2 name eth0
167         ip link set dev veth1 netns $sw2 name swp1
168 }
169
170 setup_host_common()
171 {
172         local ns=$1; shift
173         local v4addr1=$1; shift
174         local v4addr2=$1; shift
175         local v6addr1=$1; shift
176         local v6addr2=$1; shift
177
178         ip -n $ns link set dev eth0 up
179         ip -n $ns link add link eth0 name eth0.10 up type vlan id 10
180         ip -n $ns link add link eth0 name eth0.20 up type vlan id 20
181
182         ip -n $ns address add $v4addr1 dev eth0.10
183         ip -n $ns address add $v4addr2 dev eth0.20
184         ip -n $ns address add $v6addr1 dev eth0.10
185         ip -n $ns address add $v6addr2 dev eth0.20
186 }
187
188 setup_h1()
189 {
190         local ns=$h1
191         local v4addr1=192.0.2.1/28
192         local v4addr2=192.0.2.17/28
193         local v6addr1=2001:db8:1::1/64
194         local v6addr2=2001:db8:2::1/64
195
196         setup_host_common $ns $v4addr1 $v4addr2 $v6addr1 $v6addr2
197 }
198
199 setup_h2()
200 {
201         local ns=$h2
202         local v4addr1=192.0.2.2/28
203         local v4addr2=192.0.2.18/28
204         local v6addr1=2001:db8:1::2/64
205         local v6addr2=2001:db8:2::2/64
206
207         setup_host_common $ns $v4addr1 $v4addr2 $v6addr1 $v6addr2
208 }
209
210 setup_sw_common()
211 {
212         local ns=$1; shift
213         local local_addr=$1; shift
214         local remote_addr=$1; shift
215         local veth_addr=$1; shift
216         local gw_addr=$1; shift
217
218         ip -n $ns address add $local_addr/32 dev lo
219
220         ip -n $ns link set dev veth0 up
221         ip -n $ns address add $veth_addr/28 dev veth0
222         ip -n $ns route add default via $gw_addr
223
224         ip -n $ns link add name br0 up type bridge vlan_filtering 1 \
225                 vlan_default_pvid 0 mcast_snooping 0
226
227         ip -n $ns link add link br0 name br0.10 up type vlan id 10
228         bridge -n $ns vlan add vid 10 dev br0 self
229
230         ip -n $ns link add link br0 name br0.20 up type vlan id 20
231         bridge -n $ns vlan add vid 20 dev br0 self
232
233         ip -n $ns link set dev swp1 up master br0
234         bridge -n $ns vlan add vid 10 dev swp1
235         bridge -n $ns vlan add vid 20 dev swp1
236
237         ip -n $ns link add name vx0 up master br0 type vxlan \
238                 local $local_addr dstport 4789 nolearning external
239         bridge -n $ns fdb add 00:00:00:00:00:00 dev vx0 self static \
240                 dst $remote_addr src_vni 10010
241         bridge -n $ns fdb add 00:00:00:00:00:00 dev vx0 self static \
242                 dst $remote_addr src_vni 10020
243         bridge -n $ns link set dev vx0 vlan_tunnel on learning off
244
245         bridge -n $ns vlan add vid 10 dev vx0
246         bridge -n $ns vlan add vid 10 dev vx0 tunnel_info id 10010
247
248         bridge -n $ns vlan add vid 20 dev vx0
249         bridge -n $ns vlan add vid 20 dev vx0 tunnel_info id 10020
250 }
251
252 setup_sw1()
253 {
254         local ns=$sw1
255         local local_addr=192.0.2.33
256         local remote_addr=192.0.2.34
257         local veth_addr=192.0.2.49
258         local gw_addr=192.0.2.50
259
260         setup_sw_common $ns $local_addr $remote_addr $veth_addr $gw_addr
261 }
262
263 setup_sw2()
264 {
265         local ns=$sw2
266         local local_addr=192.0.2.34
267         local remote_addr=192.0.2.33
268         local veth_addr=192.0.2.50
269         local gw_addr=192.0.2.49
270
271         setup_sw_common $ns $local_addr $remote_addr $veth_addr $gw_addr
272 }
273
274 setup()
275 {
276         set -e
277
278         setup_topo
279         setup_h1
280         setup_h2
281         setup_sw1
282         setup_sw2
283
284         sleep 5
285
286         set +e
287 }
288
289 cleanup()
290 {
291         cleanup_ns $h1 $h2 $sw1 $sw2
292 }
293
294 ################################################################################
295 # Tests
296
297 neigh_suppress_arp_common()
298 {
299         local vid=$1; shift
300         local sip=$1; shift
301         local tip=$1; shift
302         local h2_mac
303
304         echo
305         echo "Per-port ARP suppression - VLAN $vid"
306         echo "----------------------------------"
307
308         run_cmd "tc -n $sw1 qdisc replace dev vx0 clsact"
309         run_cmd "tc -n $sw1 filter replace dev vx0 egress pref 1 handle 101 proto 0x0806 flower indev swp1 arp_tip $tip arp_sip $sip arp_op request action pass"
310
311         # Initial state - check that ARP requests are not suppressed and that
312         # ARP replies are received.
313         run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip -I eth0.$vid $tip"
314         log_test $? 0 "arping"
315         tc_check_packets $sw1 "dev vx0 egress" 101 1
316         log_test $? 0 "ARP suppression"
317
318         # Enable neighbor suppression and check that nothing changes compared
319         # to the initial state.
320         run_cmd "bridge -n $sw1 link set dev vx0 neigh_suppress on"
321         run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_suppress on\""
322         log_test $? 0 "\"neigh_suppress\" is on"
323
324         run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip -I eth0.$vid $tip"
325         log_test $? 0 "arping"
326         tc_check_packets $sw1 "dev vx0 egress" 101 2
327         log_test $? 0 "ARP suppression"
328
329         # Install an FDB entry for the remote host and check that nothing
330         # changes compared to the initial state.
331         h2_mac=$(ip -n $h2 -j -p link show eth0.$vid | jq -r '.[]["address"]')
332         run_cmd "bridge -n $sw1 fdb replace $h2_mac dev vx0 master static vlan $vid"
333         log_test $? 0 "FDB entry installation"
334
335         run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip -I eth0.$vid $tip"
336         log_test $? 0 "arping"
337         tc_check_packets $sw1 "dev vx0 egress" 101 3
338         log_test $? 0 "ARP suppression"
339
340         # Install a neighbor on the matching SVI interface and check that ARP
341         # requests are suppressed.
342         run_cmd "ip -n $sw1 neigh replace $tip lladdr $h2_mac nud permanent dev br0.$vid"
343         log_test $? 0 "Neighbor entry installation"
344
345         run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip -I eth0.$vid $tip"
346         log_test $? 0 "arping"
347         tc_check_packets $sw1 "dev vx0 egress" 101 3
348         log_test $? 0 "ARP suppression"
349
350         # Take the second host down and check that ARP requests are suppressed
351         # and that ARP replies are received.
352         run_cmd "ip -n $h2 link set dev eth0.$vid down"
353         log_test $? 0 "H2 down"
354
355         run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip -I eth0.$vid $tip"
356         log_test $? 0 "arping"
357         tc_check_packets $sw1 "dev vx0 egress" 101 3
358         log_test $? 0 "ARP suppression"
359
360         run_cmd "ip -n $h2 link set dev eth0.$vid up"
361         log_test $? 0 "H2 up"
362
363         # Disable neighbor suppression and check that ARP requests are no
364         # longer suppressed.
365         run_cmd "bridge -n $sw1 link set dev vx0 neigh_suppress off"
366         run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_suppress off\""
367         log_test $? 0 "\"neigh_suppress\" is off"
368
369         run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip -I eth0.$vid $tip"
370         log_test $? 0 "arping"
371         tc_check_packets $sw1 "dev vx0 egress" 101 4
372         log_test $? 0 "ARP suppression"
373
374         # Take the second host down and check that ARP requests are not
375         # suppressed and that ARP replies are not received.
376         run_cmd "ip -n $h2 link set dev eth0.$vid down"
377         log_test $? 0 "H2 down"
378
379         run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip -I eth0.$vid $tip"
380         log_test $? 1 "arping"
381         tc_check_packets $sw1 "dev vx0 egress" 101 5
382         log_test $? 0 "ARP suppression"
383 }
384
385 neigh_suppress_arp()
386 {
387         local vid=10
388         local sip=192.0.2.1
389         local tip=192.0.2.2
390
391         neigh_suppress_arp_common $vid $sip $tip
392
393         vid=20
394         sip=192.0.2.17
395         tip=192.0.2.18
396         neigh_suppress_arp_common $vid $sip $tip
397 }
398
399 neigh_suppress_ns_common()
400 {
401         local vid=$1; shift
402         local saddr=$1; shift
403         local daddr=$1; shift
404         local maddr=$1; shift
405         local h2_mac
406
407         echo
408         echo "Per-port NS suppression - VLAN $vid"
409         echo "---------------------------------"
410
411         run_cmd "tc -n $sw1 qdisc replace dev vx0 clsact"
412         run_cmd "tc -n $sw1 filter replace dev vx0 egress pref 1 handle 101 proto ipv6 flower indev swp1 ip_proto icmpv6 dst_ip $maddr src_ip $saddr type 135 code 0 action pass"
413
414         # Initial state - check that NS messages are not suppressed and that ND
415         # messages are received.
416         run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr -w 5000 $daddr eth0.$vid"
417         log_test $? 0 "ndisc6"
418         tc_check_packets $sw1 "dev vx0 egress" 101 1
419         log_test $? 0 "NS suppression"
420
421         # Enable neighbor suppression and check that nothing changes compared
422         # to the initial state.
423         run_cmd "bridge -n $sw1 link set dev vx0 neigh_suppress on"
424         run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_suppress on\""
425         log_test $? 0 "\"neigh_suppress\" is on"
426
427         run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr -w 5000 $daddr eth0.$vid"
428         log_test $? 0 "ndisc6"
429         tc_check_packets $sw1 "dev vx0 egress" 101 2
430         log_test $? 0 "NS suppression"
431
432         # Install an FDB entry for the remote host and check that nothing
433         # changes compared to the initial state.
434         h2_mac=$(ip -n $h2 -j -p link show eth0.$vid | jq -r '.[]["address"]')
435         run_cmd "bridge -n $sw1 fdb replace $h2_mac dev vx0 master static vlan $vid"
436         log_test $? 0 "FDB entry installation"
437
438         run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr -w 5000 $daddr eth0.$vid"
439         log_test $? 0 "ndisc6"
440         tc_check_packets $sw1 "dev vx0 egress" 101 3
441         log_test $? 0 "NS suppression"
442
443         # Install a neighbor on the matching SVI interface and check that NS
444         # messages are suppressed.
445         run_cmd "ip -n $sw1 neigh replace $daddr lladdr $h2_mac nud permanent dev br0.$vid"
446         log_test $? 0 "Neighbor entry installation"
447
448         run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr -w 5000 $daddr eth0.$vid"
449         log_test $? 0 "ndisc6"
450         tc_check_packets $sw1 "dev vx0 egress" 101 3
451         log_test $? 0 "NS suppression"
452
453         # Take the second host down and check that NS messages are suppressed
454         # and that ND messages are received.
455         run_cmd "ip -n $h2 link set dev eth0.$vid down"
456         log_test $? 0 "H2 down"
457
458         run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr -w 5000 $daddr eth0.$vid"
459         log_test $? 0 "ndisc6"
460         tc_check_packets $sw1 "dev vx0 egress" 101 3
461         log_test $? 0 "NS suppression"
462
463         run_cmd "ip -n $h2 link set dev eth0.$vid up"
464         log_test $? 0 "H2 up"
465
466         # Disable neighbor suppression and check that NS messages are no longer
467         # suppressed.
468         run_cmd "bridge -n $sw1 link set dev vx0 neigh_suppress off"
469         run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_suppress off\""
470         log_test $? 0 "\"neigh_suppress\" is off"
471
472         run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr -w 5000 $daddr eth0.$vid"
473         log_test $? 0 "ndisc6"
474         tc_check_packets $sw1 "dev vx0 egress" 101 4
475         log_test $? 0 "NS suppression"
476
477         # Take the second host down and check that NS messages are not
478         # suppressed and that ND messages are not received.
479         run_cmd "ip -n $h2 link set dev eth0.$vid down"
480         log_test $? 0 "H2 down"
481
482         run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr -w 5000 $daddr eth0.$vid"
483         log_test $? 2 "ndisc6"
484         tc_check_packets $sw1 "dev vx0 egress" 101 5
485         log_test $? 0 "NS suppression"
486 }
487
488 neigh_suppress_ns()
489 {
490         local vid=10
491         local saddr=2001:db8:1::1
492         local daddr=2001:db8:1::2
493         local maddr=ff02::1:ff00:2
494
495         neigh_suppress_ns_common $vid $saddr $daddr $maddr
496
497         vid=20
498         saddr=2001:db8:2::1
499         daddr=2001:db8:2::2
500         maddr=ff02::1:ff00:2
501
502         neigh_suppress_ns_common $vid $saddr $daddr $maddr
503 }
504
505 neigh_vlan_suppress_arp()
506 {
507         local vid1=10
508         local vid2=20
509         local sip1=192.0.2.1
510         local sip2=192.0.2.17
511         local tip1=192.0.2.2
512         local tip2=192.0.2.18
513         local h2_mac1
514         local h2_mac2
515
516         echo
517         echo "Per-{Port, VLAN} ARP suppression"
518         echo "--------------------------------"
519
520         run_cmd "tc -n $sw1 qdisc replace dev vx0 clsact"
521         run_cmd "tc -n $sw1 filter replace dev vx0 egress pref 1 handle 101 proto 0x0806 flower indev swp1 arp_tip $tip1 arp_sip $sip1 arp_op request action pass"
522         run_cmd "tc -n $sw1 filter replace dev vx0 egress pref 1 handle 102 proto 0x0806 flower indev swp1 arp_tip $tip2 arp_sip $sip2 arp_op request action pass"
523
524         h2_mac1=$(ip -n $h2 -j -p link show eth0.$vid1 | jq -r '.[]["address"]')
525         h2_mac2=$(ip -n $h2 -j -p link show eth0.$vid2 | jq -r '.[]["address"]')
526         run_cmd "bridge -n $sw1 fdb replace $h2_mac1 dev vx0 master static vlan $vid1"
527         run_cmd "bridge -n $sw1 fdb replace $h2_mac2 dev vx0 master static vlan $vid2"
528         run_cmd "ip -n $sw1 neigh replace $tip1 lladdr $h2_mac1 nud permanent dev br0.$vid1"
529         run_cmd "ip -n $sw1 neigh replace $tip2 lladdr $h2_mac2 nud permanent dev br0.$vid2"
530
531         # Enable per-{Port, VLAN} neighbor suppression and check that ARP
532         # requests are not suppressed and that ARP replies are received.
533         run_cmd "bridge -n $sw1 link set dev vx0 neigh_vlan_suppress on"
534         run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_vlan_suppress on\""
535         log_test $? 0 "\"neigh_vlan_suppress\" is on"
536
537         run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip1 -I eth0.$vid1 $tip1"
538         log_test $? 0 "arping (VLAN $vid1)"
539         run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip2 -I eth0.$vid2 $tip2"
540         log_test $? 0 "arping (VLAN $vid2)"
541
542         tc_check_packets $sw1 "dev vx0 egress" 101 1
543         log_test $? 0 "ARP suppression (VLAN $vid1)"
544         tc_check_packets $sw1 "dev vx0 egress" 102 1
545         log_test $? 0 "ARP suppression (VLAN $vid2)"
546
547         # Enable neighbor suppression on VLAN 10 and check that only on this
548         # VLAN ARP requests are suppressed.
549         run_cmd "bridge -n $sw1 vlan set vid $vid1 dev vx0 neigh_suppress on"
550         run_cmd "bridge -n $sw1 -d vlan show dev vx0 vid $vid1 | grep \"neigh_suppress on\""
551         log_test $? 0 "\"neigh_suppress\" is on (VLAN $vid1)"
552         run_cmd "bridge -n $sw1 -d vlan show dev vx0 vid $vid2 | grep \"neigh_suppress off\""
553         log_test $? 0 "\"neigh_suppress\" is off (VLAN $vid2)"
554
555         run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip1 -I eth0.$vid1 $tip1"
556         log_test $? 0 "arping (VLAN $vid1)"
557         run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip2 -I eth0.$vid2 $tip2"
558         log_test $? 0 "arping (VLAN $vid2)"
559
560         tc_check_packets $sw1 "dev vx0 egress" 101 1
561         log_test $? 0 "ARP suppression (VLAN $vid1)"
562         tc_check_packets $sw1 "dev vx0 egress" 102 2
563         log_test $? 0 "ARP suppression (VLAN $vid2)"
564
565         # Enable neighbor suppression on the port and check that it has no
566         # effect compared to previous state.
567         run_cmd "bridge -n $sw1 link set dev vx0 neigh_suppress on"
568         run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_suppress on\""
569         log_test $? 0 "\"neigh_suppress\" is on"
570
571         run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip1 -I eth0.$vid1 $tip1"
572         log_test $? 0 "arping (VLAN $vid1)"
573         run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip2 -I eth0.$vid2 $tip2"
574         log_test $? 0 "arping (VLAN $vid2)"
575
576         tc_check_packets $sw1 "dev vx0 egress" 101 1
577         log_test $? 0 "ARP suppression (VLAN $vid1)"
578         tc_check_packets $sw1 "dev vx0 egress" 102 3
579         log_test $? 0 "ARP suppression (VLAN $vid2)"
580
581         # Disable neighbor suppression on the port and check that it has no
582         # effect compared to previous state.
583         run_cmd "bridge -n $sw1 link set dev vx0 neigh_suppress off"
584         run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_suppress off\""
585         log_test $? 0 "\"neigh_suppress\" is off"
586
587         run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip1 -I eth0.$vid1 $tip1"
588         log_test $? 0 "arping (VLAN $vid1)"
589         run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip2 -I eth0.$vid2 $tip2"
590         log_test $? 0 "arping (VLAN $vid2)"
591
592         tc_check_packets $sw1 "dev vx0 egress" 101 1
593         log_test $? 0 "ARP suppression (VLAN $vid1)"
594         tc_check_packets $sw1 "dev vx0 egress" 102 4
595         log_test $? 0 "ARP suppression (VLAN $vid2)"
596
597         # Disable neighbor suppression on VLAN 10 and check that ARP requests
598         # are no longer suppressed on this VLAN.
599         run_cmd "bridge -n $sw1 vlan set vid $vid1 dev vx0 neigh_suppress off"
600         run_cmd "bridge -n $sw1 -d vlan show dev vx0 vid $vid1 | grep \"neigh_suppress off\""
601         log_test $? 0 "\"neigh_suppress\" is off (VLAN $vid1)"
602
603         run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip1 -I eth0.$vid1 $tip1"
604         log_test $? 0 "arping (VLAN $vid1)"
605         run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip2 -I eth0.$vid2 $tip2"
606         log_test $? 0 "arping (VLAN $vid2)"
607
608         tc_check_packets $sw1 "dev vx0 egress" 101 2
609         log_test $? 0 "ARP suppression (VLAN $vid1)"
610         tc_check_packets $sw1 "dev vx0 egress" 102 5
611         log_test $? 0 "ARP suppression (VLAN $vid2)"
612
613         # Disable per-{Port, VLAN} neighbor suppression, enable neighbor
614         # suppression on the port and check that on both VLANs ARP requests are
615         # suppressed.
616         run_cmd "bridge -n $sw1 link set dev vx0 neigh_vlan_suppress off"
617         run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_vlan_suppress off\""
618         log_test $? 0 "\"neigh_vlan_suppress\" is off"
619
620         run_cmd "bridge -n $sw1 link set dev vx0 neigh_suppress on"
621         run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_suppress on\""
622         log_test $? 0 "\"neigh_suppress\" is on"
623
624         run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip1 -I eth0.$vid1 $tip1"
625         log_test $? 0 "arping (VLAN $vid1)"
626         run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip2 -I eth0.$vid2 $tip2"
627         log_test $? 0 "arping (VLAN $vid2)"
628
629         tc_check_packets $sw1 "dev vx0 egress" 101 2
630         log_test $? 0 "ARP suppression (VLAN $vid1)"
631         tc_check_packets $sw1 "dev vx0 egress" 102 5
632         log_test $? 0 "ARP suppression (VLAN $vid2)"
633 }
634
635 neigh_vlan_suppress_ns()
636 {
637         local vid1=10
638         local vid2=20
639         local saddr1=2001:db8:1::1
640         local saddr2=2001:db8:2::1
641         local daddr1=2001:db8:1::2
642         local daddr2=2001:db8:2::2
643         local maddr=ff02::1:ff00:2
644         local h2_mac1
645         local h2_mac2
646
647         echo
648         echo "Per-{Port, VLAN} NS suppression"
649         echo "-------------------------------"
650
651         run_cmd "tc -n $sw1 qdisc replace dev vx0 clsact"
652         run_cmd "tc -n $sw1 filter replace dev vx0 egress pref 1 handle 101 proto ipv6 flower indev swp1 ip_proto icmpv6 dst_ip $maddr src_ip $saddr1 type 135 code 0 action pass"
653         run_cmd "tc -n $sw1 filter replace dev vx0 egress pref 1 handle 102 proto ipv6 flower indev swp1 ip_proto icmpv6 dst_ip $maddr src_ip $saddr2 type 135 code 0 action pass"
654
655         h2_mac1=$(ip -n $h2 -j -p link show eth0.$vid1 | jq -r '.[]["address"]')
656         h2_mac2=$(ip -n $h2 -j -p link show eth0.$vid2 | jq -r '.[]["address"]')
657         run_cmd "bridge -n $sw1 fdb replace $h2_mac1 dev vx0 master static vlan $vid1"
658         run_cmd "bridge -n $sw1 fdb replace $h2_mac2 dev vx0 master static vlan $vid2"
659         run_cmd "ip -n $sw1 neigh replace $daddr1 lladdr $h2_mac1 nud permanent dev br0.$vid1"
660         run_cmd "ip -n $sw1 neigh replace $daddr2 lladdr $h2_mac2 nud permanent dev br0.$vid2"
661
662         # Enable per-{Port, VLAN} neighbor suppression and check that NS
663         # messages are not suppressed and that ND messages are received.
664         run_cmd "bridge -n $sw1 link set dev vx0 neigh_vlan_suppress on"
665         run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_vlan_suppress on\""
666         log_test $? 0 "\"neigh_vlan_suppress\" is on"
667
668         run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr1 -w 5000 $daddr1 eth0.$vid1"
669         log_test $? 0 "ndisc6 (VLAN $vid1)"
670         run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr2 -w 5000 $daddr2 eth0.$vid2"
671         log_test $? 0 "ndisc6 (VLAN $vid2)"
672
673         tc_check_packets $sw1 "dev vx0 egress" 101 1
674         log_test $? 0 "NS suppression (VLAN $vid1)"
675         tc_check_packets $sw1 "dev vx0 egress" 102 1
676         log_test $? 0 "NS suppression (VLAN $vid2)"
677
678         # Enable neighbor suppression on VLAN 10 and check that only on this
679         # VLAN NS messages are suppressed.
680         run_cmd "bridge -n $sw1 vlan set vid $vid1 dev vx0 neigh_suppress on"
681         run_cmd "bridge -n $sw1 -d vlan show dev vx0 vid $vid1 | grep \"neigh_suppress on\""
682         log_test $? 0 "\"neigh_suppress\" is on (VLAN $vid1)"
683         run_cmd "bridge -n $sw1 -d vlan show dev vx0 vid $vid2 | grep \"neigh_suppress off\""
684         log_test $? 0 "\"neigh_suppress\" is off (VLAN $vid2)"
685
686         run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr1 -w 5000 $daddr1 eth0.$vid1"
687         log_test $? 0 "ndisc6 (VLAN $vid1)"
688         run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr2 -w 5000 $daddr2 eth0.$vid2"
689         log_test $? 0 "ndisc6 (VLAN $vid2)"
690
691         tc_check_packets $sw1 "dev vx0 egress" 101 1
692         log_test $? 0 "NS suppression (VLAN $vid1)"
693         tc_check_packets $sw1 "dev vx0 egress" 102 2
694         log_test $? 0 "NS suppression (VLAN $vid2)"
695
696         # Enable neighbor suppression on the port and check that it has no
697         # effect compared to previous state.
698         run_cmd "bridge -n $sw1 link set dev vx0 neigh_suppress on"
699         run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_suppress on\""
700         log_test $? 0 "\"neigh_suppress\" is on"
701
702         run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr1 -w 5000 $daddr1 eth0.$vid1"
703         log_test $? 0 "ndisc6 (VLAN $vid1)"
704         run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr2 -w 5000 $daddr2 eth0.$vid2"
705         log_test $? 0 "ndisc6 (VLAN $vid2)"
706
707         tc_check_packets $sw1 "dev vx0 egress" 101 1
708         log_test $? 0 "NS suppression (VLAN $vid1)"
709         tc_check_packets $sw1 "dev vx0 egress" 102 3
710         log_test $? 0 "NS suppression (VLAN $vid2)"
711
712         # Disable neighbor suppression on the port and check that it has no
713         # effect compared to previous state.
714         run_cmd "bridge -n $sw1 link set dev vx0 neigh_suppress off"
715         run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_suppress off\""
716         log_test $? 0 "\"neigh_suppress\" is off"
717
718         run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr1 -w 5000 $daddr1 eth0.$vid1"
719         log_test $? 0 "ndisc6 (VLAN $vid1)"
720         run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr2 -w 5000 $daddr2 eth0.$vid2"
721         log_test $? 0 "ndisc6 (VLAN $vid2)"
722
723         tc_check_packets $sw1 "dev vx0 egress" 101 1
724         log_test $? 0 "NS suppression (VLAN $vid1)"
725         tc_check_packets $sw1 "dev vx0 egress" 102 4
726         log_test $? 0 "NS suppression (VLAN $vid2)"
727
728         # Disable neighbor suppression on VLAN 10 and check that NS messages
729         # are no longer suppressed on this VLAN.
730         run_cmd "bridge -n $sw1 vlan set vid $vid1 dev vx0 neigh_suppress off"
731         run_cmd "bridge -n $sw1 -d vlan show dev vx0 vid $vid1 | grep \"neigh_suppress off\""
732         log_test $? 0 "\"neigh_suppress\" is off (VLAN $vid1)"
733
734         run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr1 -w 5000 $daddr1 eth0.$vid1"
735         log_test $? 0 "ndisc6 (VLAN $vid1)"
736         run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr2 -w 5000 $daddr2 eth0.$vid2"
737         log_test $? 0 "ndisc6 (VLAN $vid2)"
738
739         tc_check_packets $sw1 "dev vx0 egress" 101 2
740         log_test $? 0 "NS suppression (VLAN $vid1)"
741         tc_check_packets $sw1 "dev vx0 egress" 102 5
742         log_test $? 0 "NS suppression (VLAN $vid2)"
743
744         # Disable per-{Port, VLAN} neighbor suppression, enable neighbor
745         # suppression on the port and check that on both VLANs NS messages are
746         # suppressed.
747         run_cmd "bridge -n $sw1 link set dev vx0 neigh_vlan_suppress off"
748         run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_vlan_suppress off\""
749         log_test $? 0 "\"neigh_vlan_suppress\" is off"
750
751         run_cmd "bridge -n $sw1 link set dev vx0 neigh_suppress on"
752         run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_suppress on\""
753         log_test $? 0 "\"neigh_suppress\" is on"
754
755         run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr1 -w 5000 $daddr1 eth0.$vid1"
756         log_test $? 0 "ndisc6 (VLAN $vid1)"
757         run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr2 -w 5000 $daddr2 eth0.$vid2"
758         log_test $? 0 "ndisc6 (VLAN $vid2)"
759
760         tc_check_packets $sw1 "dev vx0 egress" 101 2
761         log_test $? 0 "NS suppression (VLAN $vid1)"
762         tc_check_packets $sw1 "dev vx0 egress" 102 5
763         log_test $? 0 "NS suppression (VLAN $vid2)"
764 }
765
766 ################################################################################
767 # Usage
768
769 usage()
770 {
771         cat <<EOF
772 usage: ${0##*/} OPTS
773
774         -t <test>   Test(s) to run (default: all)
775                     (options: $TESTS)
776         -p          Pause on fail
777         -P          Pause after each test before cleanup
778         -v          Verbose mode (show commands and output)
779 EOF
780 }
781
782 ################################################################################
783 # Main
784
785 trap cleanup EXIT
786
787 while getopts ":t:pPvh" opt; do
788         case $opt in
789                 t) TESTS=$OPTARG;;
790                 p) PAUSE_ON_FAIL=yes;;
791                 P) PAUSE=yes;;
792                 v) VERBOSE=$(($VERBOSE + 1));;
793                 h) usage; exit 0;;
794                 *) usage; exit 1;;
795         esac
796 done
797
798 # Make sure we don't pause twice.
799 [ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no
800
801 if [ "$(id -u)" -ne 0 ];then
802         echo "SKIP: Need root privileges"
803         exit $ksft_skip;
804 fi
805
806 if [ ! -x "$(command -v ip)" ]; then
807         echo "SKIP: Could not run test without ip tool"
808         exit $ksft_skip
809 fi
810
811 if [ ! -x "$(command -v bridge)" ]; then
812         echo "SKIP: Could not run test without bridge tool"
813         exit $ksft_skip
814 fi
815
816 if [ ! -x "$(command -v tc)" ]; then
817         echo "SKIP: Could not run test without tc tool"
818         exit $ksft_skip
819 fi
820
821 if [ ! -x "$(command -v arping)" ]; then
822         echo "SKIP: Could not run test without arping tool"
823         exit $ksft_skip
824 fi
825
826 if [ ! -x "$(command -v ndisc6)" ]; then
827         echo "SKIP: Could not run test without ndisc6 tool"
828         exit $ksft_skip
829 fi
830
831 if [ ! -x "$(command -v jq)" ]; then
832         echo "SKIP: Could not run test without jq tool"
833         exit $ksft_skip
834 fi
835
836 bridge link help 2>&1 | grep -q "neigh_vlan_suppress"
837 if [ $? -ne 0 ]; then
838    echo "SKIP: iproute2 bridge too old, missing per-VLAN neighbor suppression support"
839    exit $ksft_skip
840 fi
841
842 # Start clean.
843 cleanup
844
845 for t in $TESTS
846 do
847         setup; $t; cleanup;
848 done
849
850 if [ "$TESTS" != "none" ]; then
851         printf "\nTests passed: %3d\n" ${nsuccess}
852         printf "Tests failed: %3d\n"   ${nfail}
853 fi
854
855 exit $ret