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