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# +-----------------------+ +------------------------+
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}
94export 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
113NUM_NETIFS=6
114source lib.sh
115source tc_common.sh
116
117h1_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
125h1_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
133h2_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
141h2_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
149rp1_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
157rp1_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
165switch_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
212switch_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
251vrp2_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
259vrp2_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
267ns_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}
322export -f ns_init_common
323
324ns1_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
333ns1_destroy()
334{
335 ip netns exec ns1 ip link set dev v2 netns 1
336 ip netns del ns1
337}
338
339ns2_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
348ns2_destroy()
349{
350 ip netns exec ns2 ip link set dev v4 netns 1
351 ip netns del ns2
352}
353
354setup_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
383cleanup()
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.
405reapply_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
475ping_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
540ping_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
567maybe_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
596flood_counter_install()
597{
598 __flood_counter_add_del add "$@"
599}
600
601flood_counter_uninstall()
602{
603 __flood_counter_add_del del "$@"
604}
605
606flood_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
614flood_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
624vxlan_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
678test_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
686vxlan_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
717test_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
756test_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
825test_all()
826{
827 log_info "Running tests with UDP port $VXPORT"
828 tests_run
829}
830
831trap cleanup EXIT
832
833setup_prepare
834setup_wait
835test_all
836
837exit $EXIT_STATUS