selftests: forwarding: Fix ping failure due to short timeout
[sfrench/cifs-2.6.git] / tools / testing / selftests / net / forwarding / vxlan_bridge_1q_ipv6.sh
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3
4 # +-----------------------+                          +------------------------+
5 # | H1 (vrf)              |                          | H2 (vrf)               |
6 # | + $h1.10              |                          | + $h2.10               |
7 # | | 192.0.2.1/28        |                          | | 192.0.2.2/28         |
8 # | | 2001:db8:1::1/64    |                          | | 2001:db8:1::2/64     |
9 # | |                     |                          | |                      |
10 # | |  + $h1.20           |                          | |  + $h2.20            |
11 # | \  | 198.51.100.1/24  |                          | \  | 198.51.100.2/24   |
12 # |  \ | 2001:db8:2::1/64 |                          |  \ | 2001:db8:2::2/64  |
13 # |   \|                  |                          |   \|                   |
14 # |    + $h1              |                          |    + $h2               |
15 # +----|------------------+                          +----|-------------------+
16 #      |                                                  |
17 # +----|--------------------------------------------------|-------------------+
18 # | SW |                                                  |                   |
19 # | +--|--------------------------------------------------|-----------------+ |
20 # | |  + $swp1                   BR1 (802.1q)             + $swp2           | |
21 # | |     vid 10                                             vid 10         | |
22 # | |     vid 20                                             vid 20         | |
23 # | |                                                                       | |
24 # | |  + vx10 (vxlan)                        + vx20 (vxlan)                 | |
25 # | |    local:                                local:                       | |
26 # | |    2001:db8:3::1                         2001:db8:3::1                | |
27 # | |    remote:                               remote:                      | |
28 # | |    2001:db8:4::1 2001:db8:5::1           2001:db8:4::1 2001:db8:5::1  | |
29 # | |    id 1000 dstport $VXPORT               id 2000 dstport $VXPORT      | |
30 # | |    vid 10 pvid untagged                  vid 20 pvid untagged         | |
31 # | +-----------------------------------------------------------------------+ |
32 # |                                                                           |
33 # |  2001:db8:4::0/64 via 2001:db8:3::2                                       |
34 # |  2001:db8:5::0/64 via 2001:db8:3::2                                       |
35 # |                                                                           |
36 # |    + $rp1                                                                 |
37 # |    | 2001:db8:3::1/64                                                     |
38 # +----|----------------------------------------------------------------------+
39 #      |
40 # +----|----------------------------------------------------------+
41 # |    |                                             VRP2 (vrf)   |
42 # |    + $rp2                                                     |
43 # |      2001:db8:3::2/64                                         |
44 # |                                                               |  (maybe) HW
45 # =============================================================================
46 # |                                                               |  (likely) SW
47 # |    + v1 (veth)                             + v3 (veth)        |
48 # |    | 2001:db8:4::2/64                      | 2001:db8:5::2/64 |
49 # +----|---------------------------------------|------------------+
50 #      |                                       |
51 # +----|--------------------------------+ +----|-------------------------------+
52 # |    + v2 (veth)        NS1 (netns)   | |    + v4 (veth)        NS2 (netns)  |
53 # |      2001:db8:4::1/64               | |      2001:db8:5::1/64              |
54 # |                                     | |                                    |
55 # | 2001:db8:3::0/64 via 2001:db8:4::2  | | 2001:db8:3::0/64 via 2001:db8:5::2 |
56 # | 2001:db8:5::1/128 via 2001:db8:4::2 | | 2001:db8:4::1/128 via              |
57 # |                                     | |         2001:db8:5::2              |
58 # |                                     | |                                    |
59 # | +-------------------------------+   | | +-------------------------------+  |
60 # | |                  BR2 (802.1q) |   | | |                  BR2 (802.1q) |  |
61 # | |  + vx10 (vxlan)               |   | | |  + vx10 (vxlan)               |  |
62 # | |    local 2001:db8:4::1        |   | | |    local 2001:db8:5::1        |  |
63 # | |    remote 2001:db8:3::1       |   | | |    remote 2001:db8:3::1       |  |
64 # | |    remote 2001:db8:5::1       |   | | |    remote 2001:db8:4::1       |  |
65 # | |    id 1000 dstport $VXPORT    |   | | |    id 1000 dstport $VXPORT    |  |
66 # | |    vid 10 pvid untagged       |   | | |    vid 10 pvid untagged       |  |
67 # | |                               |   | | |                               |  |
68 # | |  + vx20 (vxlan)               |   | | |  + vx20 (vxlan)               |  |
69 # | |    local 2001:db8:4::1        |   | | |    local 2001:db8:5::1        |  |
70 # | |    remote 2001:db8:3::1       |   | | |    remote 2001:db8:3::1       |  |
71 # | |    remote 2001:db8:5::1       |   | | |    remote 2001:db8:4::1       |  |
72 # | |    id 2000 dstport $VXPORT    |   | | |    id 2000 dstport $VXPORT    |  |
73 # | |    vid 20 pvid untagged       |   | | |    vid 20 pvid untagged       |  |
74 # | |                               |   | | |                               |  |
75 # | |  + w1 (veth)                  |   | | |  + w1 (veth)                  |  |
76 # | |  | vid 10                     |   | | |  | vid 10                     |  |
77 # | |  | vid 20                     |   | | |  | vid 20                     |  |
78 # | +--|----------------------------+   | | +--|----------------------------+  |
79 # |    |                                | |    |                               |
80 # | +--|----------------------------+   | | +--|----------------------------+  |
81 # | |  + w2 (veth)        VW2 (vrf) |   | | |  + w2 (veth)        VW2 (vrf) |  |
82 # | |  |\                           |   | | |  |\                           |  |
83 # | |  | + w2.10                    |   | | |  | + w2.10                    |  |
84 # | |  |   192.0.2.3/28             |   | | |  |   192.0.2.4/28             |  |
85 # | |  |   2001:db8:1::3/64         |   | | |  |   2001:db8:1::4/64         |  |
86 # | |  |                            |   | | |  |                            |  |
87 # | |  + w2.20                      |   | | |  + w2.20                      |  |
88 # | |    198.51.100.3/24            |   | | |    198.51.100.4/24            |  |
89 # | |    2001:db8:2::3/64           |   | | |    2001:db8:2::4/64           |  |
90 # | +-------------------------------+   | | +-------------------------------+  |
91 # +-------------------------------------+ +------------------------------------+
92
93 : ${VXPORT:=4789}
94 export VXPORT
95
96 : ${ALL_TESTS:="
97         ping_ipv4
98         ping_ipv6
99         test_flood
100         test_unicast
101         reapply_config
102         ping_ipv4
103         ping_ipv6
104         test_flood
105         test_unicast
106         test_pvid
107         ping_ipv4
108         ping_ipv6
109         test_flood
110         test_pvid
111 "}
112
113 NUM_NETIFS=6
114 source lib.sh
115 source tc_common.sh
116
117 h1_create()
118 {
119         simple_if_init $h1
120         tc qdisc add dev $h1 clsact
121         vlan_create $h1 10 v$h1 192.0.2.1/28 2001:db8:1::1/64
122         vlan_create $h1 20 v$h1 198.51.100.1/24 2001:db8:2::1/64
123 }
124
125 h1_destroy()
126 {
127         vlan_destroy $h1 20
128         vlan_destroy $h1 10
129         tc qdisc del dev $h1 clsact
130         simple_if_fini $h1
131 }
132
133 h2_create()
134 {
135         simple_if_init $h2
136         tc qdisc add dev $h2 clsact
137         vlan_create $h2 10 v$h2 192.0.2.2/28 2001:db8:1::2/64
138         vlan_create $h2 20 v$h2 198.51.100.2/24 2001:db8:2::2/64
139 }
140
141 h2_destroy()
142 {
143         vlan_destroy $h2 20
144         vlan_destroy $h2 10
145         tc qdisc del dev $h2 clsact
146         simple_if_fini $h2
147 }
148
149 rp1_set_addr()
150 {
151         ip address add dev $rp1 2001:db8:3::1/64
152
153         ip route add 2001:db8:4::0/64 nexthop via 2001:db8:3::2
154         ip route add 2001:db8:5::0/64 nexthop via 2001:db8:3::2
155 }
156
157 rp1_unset_addr()
158 {
159         ip route del 2001:db8:5::0/64 nexthop via 2001:db8:3::2
160         ip route del 2001:db8:4::0/64 nexthop via 2001:db8:3::2
161
162         ip address del dev $rp1 2001:db8:3::1/64
163 }
164
165 switch_create()
166 {
167         ip link add name br1 type bridge vlan_filtering 1 vlan_default_pvid 0 \
168                 mcast_snooping 0
169         # Make sure the bridge uses the MAC address of the local port and not
170         # that of the VxLAN's device.
171         ip link set dev br1 address $(mac_get $swp1)
172         ip link set dev br1 up
173
174         ip link set dev $rp1 up
175         rp1_set_addr
176         tc qdisc add dev $rp1 clsact
177
178         ip link add name vx10 type vxlan id 1000 local 2001:db8:3::1 \
179                 dstport "$VXPORT" nolearning udp6zerocsumrx udp6zerocsumtx \
180                 tos inherit ttl 100
181         ip link set dev vx10 up
182
183         ip link set dev vx10 master br1
184         bridge vlan add vid 10 dev vx10 pvid untagged
185
186         ip link add name vx20 type vxlan id 2000 local 2001:db8:3::1 \
187                 dstport "$VXPORT" nolearning udp6zerocsumrx udp6zerocsumtx \
188                 tos inherit ttl 100
189         ip link set dev vx20 up
190
191         ip link set dev vx20 master br1
192         bridge vlan add vid 20 dev vx20 pvid untagged
193
194         ip link set dev $swp1 master br1
195         ip link set dev $swp1 up
196         tc qdisc add dev $swp1 clsact
197         bridge vlan add vid 10 dev $swp1
198         bridge vlan add vid 20 dev $swp1
199
200         ip link set dev $swp2 master br1
201         ip link set dev $swp2 up
202         bridge vlan add vid 10 dev $swp2
203         bridge vlan add vid 20 dev $swp2
204
205         bridge fdb append dev vx10 00:00:00:00:00:00 dst 2001:db8:4::1 self
206         bridge fdb append dev vx10 00:00:00:00:00:00 dst 2001:db8:5::1 self
207
208         bridge fdb append dev vx20 00:00:00:00:00:00 dst 2001:db8:4::1 self
209         bridge fdb append dev vx20 00:00:00:00:00:00 dst 2001:db8:5::1 self
210 }
211
212 switch_destroy()
213 {
214         bridge fdb del dev vx20 00:00:00:00:00:00 dst 2001:db8:5::1 self
215         bridge fdb del dev vx20 00:00:00:00:00:00 dst 2001:db8:4::1 self
216
217         bridge fdb del dev vx10 00:00:00:00:00:00 dst 2001:db8:5::1 self
218         bridge fdb del dev vx10 00:00:00:00:00:00 dst 2001:db8:4::1 self
219
220         bridge vlan del vid 20 dev $swp2
221         bridge vlan del vid 10 dev $swp2
222         ip link set dev $swp2 down
223         ip link set dev $swp2 nomaster
224
225         bridge vlan del vid 20 dev $swp1
226         bridge vlan del vid 10 dev $swp1
227         tc qdisc del dev $swp1 clsact
228         ip link set dev $swp1 down
229         ip link set dev $swp1 nomaster
230
231         bridge vlan del vid 20 dev vx20
232         ip link set dev vx20 nomaster
233
234         ip link set dev vx20 down
235         ip link del dev vx20
236
237         bridge vlan del vid 10 dev vx10
238         ip link set dev vx10 nomaster
239
240         ip link set dev vx10 down
241         ip link del dev vx10
242
243         tc qdisc del dev $rp1 clsact
244         rp1_unset_addr
245         ip link set dev $rp1 down
246
247         ip link set dev br1 down
248         ip link del dev br1
249 }
250
251 vrp2_create()
252 {
253         simple_if_init $rp2 2001:db8:3::2/64
254         __simple_if_init v1 v$rp2 2001:db8:4::2/64
255         __simple_if_init v3 v$rp2 2001:db8:5::2/64
256         tc qdisc add dev v1 clsact
257 }
258
259 vrp2_destroy()
260 {
261         tc qdisc del dev v1 clsact
262         __simple_if_fini v3 2001:db8:5::2/64
263         __simple_if_fini v1 2001:db8:4::2/64
264         simple_if_fini $rp2 2001:db8:3::2/64
265 }
266
267 ns_init_common()
268 {
269         local in_if=$1; shift
270         local in_addr=$1; shift
271         local other_in_addr=$1; shift
272         local nh_addr=$1; shift
273         local host_addr1_ipv4=$1; shift
274         local host_addr1_ipv6=$1; shift
275         local host_addr2_ipv4=$1; shift
276         local host_addr2_ipv6=$1; shift
277
278         ip link set dev $in_if up
279         ip address add dev $in_if $in_addr/64
280         tc qdisc add dev $in_if clsact
281
282         ip link add name br2 type bridge vlan_filtering 1 vlan_default_pvid 0
283         ip link set dev br2 up
284
285         ip link add name w1 type veth peer name w2
286
287         ip link set dev w1 master br2
288         ip link set dev w1 up
289
290         bridge vlan add vid 10 dev w1
291         bridge vlan add vid 20 dev w1
292
293         ip link add name vx10 type vxlan id 1000 local $in_addr \
294                 dstport "$VXPORT" udp6zerocsumrx
295         ip link set dev vx10 up
296         bridge fdb append dev vx10 00:00:00:00:00:00 dst 2001:db8:3::1 self
297         bridge fdb append dev vx10 00:00:00:00:00:00 dst $other_in_addr self
298
299         ip link set dev vx10 master br2
300         tc qdisc add dev vx10 clsact
301
302         bridge vlan add vid 10 dev vx10 pvid untagged
303
304         ip link add name vx20 type vxlan id 2000 local $in_addr \
305                 dstport "$VXPORT" udp6zerocsumrx
306         ip link set dev vx20 up
307         bridge fdb append dev vx20 00:00:00:00:00:00 dst 2001:db8:3::1 self
308         bridge fdb append dev vx20 00:00:00:00:00:00 dst $other_in_addr self
309
310         ip link set dev vx20 master br2
311         tc qdisc add dev vx20 clsact
312
313         bridge vlan add vid 20 dev vx20 pvid untagged
314
315         simple_if_init w2
316         vlan_create w2 10 vw2 $host_addr1_ipv4/28 $host_addr1_ipv6/64
317         vlan_create w2 20 vw2 $host_addr2_ipv4/24 $host_addr2_ipv6/64
318
319         ip route add 2001:db8:3::0/64 nexthop via $nh_addr
320         ip route add $other_in_addr/128 nexthop via $nh_addr
321 }
322 export -f ns_init_common
323
324 ns1_create()
325 {
326         ip netns add ns1
327         ip link set dev v2 netns ns1
328         in_ns ns1 \
329               ns_init_common v2 2001:db8:4::1 2001:db8:5::1 2001:db8:4::2 \
330               192.0.2.3 2001:db8:1::3 198.51.100.3 2001:db8:2::3
331 }
332
333 ns1_destroy()
334 {
335         ip netns exec ns1 ip link set dev v2 netns 1
336         ip netns del ns1
337 }
338
339 ns2_create()
340 {
341         ip netns add ns2
342         ip link set dev v4 netns ns2
343         in_ns ns2 \
344               ns_init_common v4 2001:db8:5::1 2001:db8:4::1 2001:db8:5::2 \
345               192.0.2.4 2001:db8:1::4 198.51.100.4 2001:db8:2::4
346 }
347
348 ns2_destroy()
349 {
350         ip netns exec ns2 ip link set dev v4 netns 1
351         ip netns del ns2
352 }
353
354 setup_prepare()
355 {
356         h1=${NETIFS[p1]}
357         swp1=${NETIFS[p2]}
358
359         swp2=${NETIFS[p3]}
360         h2=${NETIFS[p4]}
361
362         rp1=${NETIFS[p5]}
363         rp2=${NETIFS[p6]}
364
365         vrf_prepare
366         forwarding_enable
367
368         h1_create
369         h2_create
370         switch_create
371
372         ip link add name v1 type veth peer name v2
373         ip link add name v3 type veth peer name v4
374         vrp2_create
375         ns1_create
376         ns2_create
377
378         r1_mac=$(in_ns ns1 mac_get w2)
379         r2_mac=$(in_ns ns2 mac_get w2)
380         h2_mac=$(mac_get $h2)
381 }
382
383 cleanup()
384 {
385         pre_cleanup
386
387         ns2_destroy
388         ns1_destroy
389         vrp2_destroy
390         ip link del dev v3
391         ip link del dev v1
392
393         switch_destroy
394         h2_destroy
395         h1_destroy
396
397         forwarding_restore
398         vrf_cleanup
399 }
400
401 # For the first round of tests, vx10 and vx20 were the first devices to get
402 # attached to the bridge, and at that point the local IP is already
403 # configured. Try the other scenario of attaching these devices to a bridge
404 # that already has local ports members, and only then assign the local IP.
405 reapply_config()
406 {
407         log_info "Reapplying configuration"
408
409         bridge fdb del dev vx20 00:00:00:00:00:00 dst 2001:db8:5::1 self
410         bridge fdb del dev vx20 00:00:00:00:00:00 dst 2001:db8:4::1 self
411
412         bridge fdb del dev vx10 00:00:00:00:00:00 dst 2001:db8:5::1 self
413         bridge fdb del dev vx10 00:00:00:00:00:00 dst 2001:db8:4::1 self
414
415         ip link set dev vx20 nomaster
416         ip link set dev vx10 nomaster
417
418         rp1_unset_addr
419         sleep 5
420
421         ip link set dev vx10 master br1
422         bridge vlan add vid 10 dev vx10 pvid untagged
423
424         ip link set dev vx20 master br1
425         bridge vlan add vid 20 dev vx20 pvid untagged
426
427         bridge fdb append dev vx10 00:00:00:00:00:00 dst 2001:db8:4::1 self
428         bridge fdb append dev vx10 00:00:00:00:00:00 dst 2001:db8:5::1 self
429
430         bridge fdb append dev vx20 00:00:00:00:00:00 dst 2001:db8:4::1 self
431         bridge fdb append dev vx20 00:00:00:00:00:00 dst 2001:db8:5::1 self
432
433         rp1_set_addr
434         sleep 5
435 }
436
437 __ping_ipv4()
438 {
439         local vxlan_local_ip=$1; shift
440         local vxlan_remote_ip=$1; shift
441         local src_ip=$1; shift
442         local dst_ip=$1; shift
443         local dev=$1; shift
444         local info=$1; shift
445
446         RET=0
447
448         tc filter add dev $rp1 egress protocol ipv6 pref 1 handle 101 \
449                 flower ip_proto udp src_ip $vxlan_local_ip \
450                 dst_ip $vxlan_remote_ip dst_port $VXPORT $TC_FLAG action pass
451         # Match ICMP-reply packets after decapsulation, so source IP is
452         # destination IP of the ping and destination IP is source IP of the
453         # ping.
454         tc filter add dev $swp1 egress protocol 802.1q pref 1 handle 101 \
455                 flower vlan_ethtype ipv4 src_ip $dst_ip dst_ip $src_ip \
456                 $TC_FLAG action pass
457
458         # Send 100 packets and verify that at least 100 packets hit the rule,
459         # to overcome ARP noise.
460         PING_COUNT=100 PING_TIMEOUT=20 ping_do $dev $dst_ip
461         check_err $? "Ping failed"
462
463         tc_check_at_least_x_packets "dev $rp1 egress" 101 10 100
464         check_err $? "Encapsulated packets did not go through router"
465
466         tc_check_at_least_x_packets "dev $swp1 egress" 101 10 100
467         check_err $? "Decapsulated packets did not go through switch"
468
469         log_test "ping: $info"
470
471         tc filter del dev $swp1 egress
472         tc filter del dev $rp1 egress
473 }
474
475 ping_ipv4()
476 {
477         RET=0
478
479         local local_sw_ip=2001:db8:3::1
480         local remote_ns1_ip=2001:db8:4::1
481         local remote_ns2_ip=2001:db8:5::1
482         local h1_10_ip=192.0.2.1
483         local h1_20_ip=198.51.100.1
484         local w2_10_ns1_ip=192.0.2.3
485         local w2_10_ns2_ip=192.0.2.4
486         local w2_20_ns1_ip=198.51.100.3
487         local w2_20_ns2_ip=198.51.100.4
488
489         ping_test $h1.10 192.0.2.2 ": local->local vid 10"
490         ping_test $h1.20 198.51.100.2 ": local->local vid 20"
491
492         __ping_ipv4 $local_sw_ip $remote_ns1_ip $h1_10_ip $w2_10_ns1_ip $h1.10 \
493                 "local->remote 1 vid 10"
494         __ping_ipv4 $local_sw_ip $remote_ns2_ip $h1_10_ip $w2_10_ns2_ip $h1.10 \
495                 "local->remote 2 vid 10"
496         __ping_ipv4 $local_sw_ip $remote_ns1_ip $h1_20_ip $w2_20_ns1_ip $h1.20 \
497                 "local->remote 1 vid 20"
498         __ping_ipv4 $local_sw_ip $remote_ns2_ip $h1_20_ip $w2_20_ns2_ip $h1.20 \
499                 "local->remote 2 vid 20"
500 }
501
502 __ping_ipv6()
503 {
504         local vxlan_local_ip=$1; shift
505         local vxlan_remote_ip=$1; shift
506         local src_ip=$1; shift
507         local dst_ip=$1; shift
508         local dev=$1; shift
509         local info=$1; shift
510
511         RET=0
512
513         tc filter add dev $rp1 egress protocol ipv6 pref 1 handle 101 \
514                 flower ip_proto udp src_ip $vxlan_local_ip \
515                 dst_ip $vxlan_remote_ip dst_port $VXPORT $TC_FLAG action pass
516         # Match ICMP-reply packets after decapsulation, so source IP is
517         # destination IP of the ping and destination IP is source IP of the
518         # ping.
519         tc filter add dev $swp1 egress protocol 802.1q pref 1 handle 101 \
520                 flower vlan_ethtype ipv6 src_ip $dst_ip dst_ip $src_ip \
521                 $TC_FLAG action pass
522
523         # Send 100 packets and verify that at least 100 packets hit the rule,
524         # to overcome neighbor discovery noise.
525         PING_COUNT=100 PING_TIMEOUT=20 ping6_do $dev $dst_ip
526         check_err $? "Ping failed"
527
528         tc_check_at_least_x_packets "dev $rp1 egress" 101 100
529         check_err $? "Encapsulated packets did not go through router"
530
531         tc_check_at_least_x_packets "dev $swp1 egress" 101 100
532         check_err $? "Decapsulated packets did not go through switch"
533
534         log_test "ping6: $info"
535
536         tc filter del dev $swp1 egress
537         tc filter del dev $rp1 egress
538 }
539
540 ping_ipv6()
541 {
542         RET=0
543
544         local local_sw_ip=2001:db8:3::1
545         local remote_ns1_ip=2001:db8:4::1
546         local remote_ns2_ip=2001:db8:5::1
547         local h1_10_ip=2001:db8:1::1
548         local h1_20_ip=2001:db8:2::1
549         local w2_10_ns1_ip=2001:db8:1::3
550         local w2_10_ns2_ip=2001:db8:1::4
551         local w2_20_ns1_ip=2001:db8:2::3
552         local w2_20_ns2_ip=2001:db8:2::4
553
554         ping6_test $h1.10 2001:db8:1::2 ": local->local vid 10"
555         ping6_test $h1.20 2001:db8:2::2 ": local->local vid 20"
556
557         __ping_ipv6 $local_sw_ip $remote_ns1_ip $h1_10_ip $w2_10_ns1_ip $h1.10 \
558                 "local->remote 1 vid 10"
559         __ping_ipv6 $local_sw_ip $remote_ns2_ip $h1_10_ip $w2_10_ns2_ip $h1.10 \
560                 "local->remote 2 vid 10"
561         __ping_ipv6 $local_sw_ip $remote_ns1_ip $h1_20_ip $w2_20_ns1_ip $h1.20 \
562                 "local->remote 1 vid 20"
563         __ping_ipv6 $local_sw_ip $remote_ns2_ip $h1_20_ip $w2_20_ns2_ip $h1.20 \
564                 "local->remote 2 vid 20"
565 }
566
567 maybe_in_ns()
568 {
569         echo ${1:+in_ns} $1
570 }
571
572 __flood_counter_add_del()
573 {
574         local add_del=$1; shift
575         local dst_ip=$1; shift
576         local dev=$1; shift
577         local ns=$1; shift
578
579         # Putting the ICMP capture both to HW and to SW will end up
580         # double-counting the packets that are trapped to slow path, such as for
581         # the unicast test. Adding either skip_hw or skip_sw fixes this problem,
582         # but with skip_hw, the flooded packets are not counted at all, because
583         # those are dropped due to MAC address mismatch; and skip_sw is a no-go
584         # for veth-based topologies.
585         #
586         # So try to install with skip_sw and fall back to skip_sw if that fails.
587
588         $(maybe_in_ns $ns) tc filter $add_del dev "$dev" ingress \
589            proto ipv6 pref 100 flower dst_ip $dst_ip ip_proto \
590            icmpv6 skip_sw action pass 2>/dev/null || \
591         $(maybe_in_ns $ns) tc filter $add_del dev "$dev" ingress \
592            proto ipv6 pref 100 flower dst_ip $dst_ip ip_proto \
593            icmpv6 skip_hw action pass
594 }
595
596 flood_counter_install()
597 {
598         __flood_counter_add_del add "$@"
599 }
600
601 flood_counter_uninstall()
602 {
603         __flood_counter_add_del del "$@"
604 }
605
606 flood_fetch_stat()
607 {
608         local dev=$1; shift
609         local ns=$1; shift
610
611         $(maybe_in_ns $ns) tc_rule_stats_get $dev 100 ingress
612 }
613
614 flood_fetch_stats()
615 {
616         local counters=("${@}")
617         local counter
618
619         for counter in "${counters[@]}"; do
620                 flood_fetch_stat $counter
621         done
622 }
623
624 vxlan_flood_test()
625 {
626         local mac=$1; shift
627         local dst=$1; shift
628         local vid=$1; shift
629         local -a expects=("${@}")
630
631         local -a counters=($h2 "vx10 ns1" "vx20 ns1" "vx10 ns2" "vx20 ns2")
632         local counter
633         local key
634
635         # Packets reach the local host tagged whereas they reach the VxLAN
636         # devices untagged. In order to be able to use the same filter for
637         # all counters, make sure the packets also reach the local host
638         # untagged
639         bridge vlan add vid $vid dev $swp2 untagged
640         for counter in "${counters[@]}"; do
641                 flood_counter_install $dst $counter
642         done
643
644         local -a t0s=($(flood_fetch_stats "${counters[@]}"))
645         $MZ -6 $h1 -Q $vid -c 10 -d 100msec -p 64 -b $mac -B $dst -t icmp6 type=128 -q
646         sleep 1
647         local -a t1s=($(flood_fetch_stats "${counters[@]}"))
648
649         for key in ${!t0s[@]}; do
650                 local delta=$((t1s[$key] - t0s[$key]))
651                 local expect=${expects[$key]}
652
653                 ((expect == delta))
654                 check_err $? "${counters[$key]}: Expected to capture $expect packets, got $delta."
655         done
656
657         for counter in "${counters[@]}"; do
658                 flood_counter_uninstall $dst $counter
659         done
660         bridge vlan add vid $vid dev $swp2
661 }
662
663 __test_flood()
664 {
665         local mac=$1; shift
666         local dst=$1; shift
667         local vid=$1; shift
668         local what=$1; shift
669         local -a expects=("${@}")
670
671         RET=0
672
673         vxlan_flood_test $mac $dst $vid "${expects[@]}"
674
675         log_test "VXLAN: $what"
676 }
677
678 test_flood()
679 {
680         __test_flood de:ad:be:ef:13:37 2001:db8:1::100 10 "flood vlan 10" \
681                 10 10 0 10 0
682         __test_flood ca:fe:be:ef:13:37 2001:db8:2::100 20 "flood vlan 20" \
683                 10 0 10 0 10
684 }
685
686 vxlan_fdb_add_del()
687 {
688         local add_del=$1; shift
689         local vid=$1; shift
690         local mac=$1; shift
691         local dev=$1; shift
692         local dst=$1; shift
693
694         bridge fdb $add_del dev $dev $mac self static permanent \
695                 ${dst:+dst} $dst 2>/dev/null
696         bridge fdb $add_del dev $dev $mac master static vlan $vid 2>/dev/null
697 }
698
699 __test_unicast()
700 {
701         local mac=$1; shift
702         local dst=$1; shift
703         local hit_idx=$1; shift
704         local vid=$1; shift
705         local what=$1; shift
706
707         RET=0
708
709         local -a expects=(0 0 0 0 0)
710         expects[$hit_idx]=10
711
712         vxlan_flood_test $mac $dst $vid "${expects[@]}"
713
714         log_test "VXLAN: $what"
715 }
716
717 test_unicast()
718 {
719         local -a targets=("$h2_mac $h2"
720                           "$r1_mac vx10 2001:db8:4::1"
721                           "$r2_mac vx10 2001:db8:5::1")
722         local target
723
724         log_info "unicast vlan 10"
725
726         for target in "${targets[@]}"; do
727                 vxlan_fdb_add_del add 10 $target
728         done
729
730         __test_unicast $h2_mac 2001:db8:1::2 0 10 "local MAC unicast"
731         __test_unicast $r1_mac 2001:db8:1::3 1 10 "remote MAC 1 unicast"
732         __test_unicast $r2_mac 2001:db8:1::4 3 10 "remote MAC 2 unicast"
733
734         for target in "${targets[@]}"; do
735                 vxlan_fdb_add_del del 10 $target
736         done
737
738         log_info "unicast vlan 20"
739
740         targets=("$h2_mac $h2" "$r1_mac vx20 2001:db8:4::1" \
741                  "$r2_mac vx20 2001:db8:5::1")
742
743         for target in "${targets[@]}"; do
744                 vxlan_fdb_add_del add 20 $target
745         done
746
747         __test_unicast $h2_mac 2001:db8:2::2 0 20 "local MAC unicast"
748         __test_unicast $r1_mac 2001:db8:2::3 2 20 "remote MAC 1 unicast"
749         __test_unicast $r2_mac 2001:db8:2::4 4 20 "remote MAC 2 unicast"
750
751         for target in "${targets[@]}"; do
752                 vxlan_fdb_add_del del 20 $target
753         done
754 }
755
756 test_pvid()
757 {
758         local -a expects=(0 0 0 0 0)
759         local mac=de:ad:be:ef:13:37
760         local dst=2001:db8:1::100
761         local vid=10
762
763         # Check that flooding works
764         RET=0
765
766         expects[0]=10; expects[1]=10; expects[3]=10
767         vxlan_flood_test $mac $dst $vid "${expects[@]}"
768
769         log_test "VXLAN: flood before pvid off"
770
771         # Toggle PVID off and test that flood to remote hosts does not work
772         RET=0
773
774         bridge vlan add vid 10 dev vx10
775
776         expects[0]=10; expects[1]=0; expects[3]=0
777         vxlan_flood_test $mac $dst $vid "${expects[@]}"
778
779         log_test "VXLAN: flood after pvid off"
780
781         # Toggle PVID on and test that flood to remote hosts does work
782         RET=0
783
784         bridge vlan add vid 10 dev vx10 pvid untagged
785
786         expects[0]=10; expects[1]=10; expects[3]=10
787         vxlan_flood_test $mac $dst $vid "${expects[@]}"
788
789         log_test "VXLAN: flood after pvid on"
790
791         # Add a new VLAN and test that it does not affect flooding
792         RET=0
793
794         bridge vlan add vid 30 dev vx10
795
796         expects[0]=10; expects[1]=10; expects[3]=10
797         vxlan_flood_test $mac $dst $vid "${expects[@]}"
798
799         bridge vlan del vid 30 dev vx10
800
801         log_test "VXLAN: flood after vlan add"
802
803         # Remove currently mapped VLAN and test that flood to remote hosts does
804         # not work
805         RET=0
806
807         bridge vlan del vid 10 dev vx10
808
809         expects[0]=10; expects[1]=0; expects[3]=0
810         vxlan_flood_test $mac $dst $vid "${expects[@]}"
811
812         log_test "VXLAN: flood after vlan delete"
813
814         # Re-add the VLAN and test that flood to remote hosts does work
815         RET=0
816
817         bridge vlan add vid 10 dev vx10 pvid untagged
818
819         expects[0]=10; expects[1]=10; expects[3]=10
820         vxlan_flood_test $mac $dst $vid "${expects[@]}"
821
822         log_test "VXLAN: flood after vlan re-add"
823 }
824
825 test_all()
826 {
827         log_info "Running tests with UDP port $VXPORT"
828         tests_run
829 }
830
831 trap cleanup EXIT
832
833 setup_prepare
834 setup_wait
835 test_all
836
837 exit $EXIT_STATUS