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