brintos

brintos / linux-shallow public Read only

0
0
Text · 21.3 KiB · a603f7b Raw
805 lines · bash
1#!/bin/bash2# SPDX-License-Identifier: GPL-2.03 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) HW34# =============================================================================35# |                                                               |  (likely) SW36# |    + 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 VXPORT68 69: ${ALL_TESTS:="70	ping_ipv471	ping_ipv672	test_flood73	test_unicast74	test_ttl75	test_tos76	test_ecn_encap77	test_ecn_decap78	reapply_config79	ping_ipv480	ping_ipv681	test_flood82	test_unicast83"}84 85NUM_NETIFS=686source lib.sh87source tc_common.sh88 89h1_create()90{91	simple_if_init $h1 192.0.2.1/28 2001:db8:1::1/6492	tc qdisc add dev $h1 clsact93}94 95h1_destroy()96{97	tc qdisc del dev $h1 clsact98	simple_if_fini $h1 192.0.2.1/28 2001:db8:1::1/6499}100 101h2_create()102{103	simple_if_init $h2 192.0.2.2/28 2001:db8:1::2/64104	tc qdisc add dev $h2 clsact105}106 107h2_destroy()108{109	tc qdisc del dev $h2 clsact110	simple_if_fini $h2 192.0.2.2/28 2001:db8:1::2/64111}112 113rp1_set_addr()114{115	ip address add dev $rp1 2001:db8:3::1/64116 117	ip route add 2001:db8:4::0/64 nexthop via 2001:db8:3::2118	ip route add 2001:db8:5::0/64 nexthop via 2001:db8:3::2119}120 121rp1_unset_addr()122{123	ip route del 2001:db8:5::0/64 nexthop via 2001:db8:3::2124	ip route del 2001:db8:4::0/64 nexthop via 2001:db8:3::2125 126	ip address del dev $rp1 2001:db8:3::1/64127}128 129switch_create()130{131	ip link add name br1 type bridge vlan_filtering 0 mcast_snooping 0132	# Make sure the bridge uses the MAC address of the local port and not133	# that of the VxLAN's device.134	ip link set dev br1 address $(mac_get $swp1)135	ip link set dev br1 up136 137	ip link set dev $rp1 up138	rp1_set_addr139	tc qdisc add dev $rp1 clsact140 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 100144	ip link set dev vx1 up145 146	ip link set dev vx1 master br1147	ip link set dev $swp1 master br1148	ip link set dev $swp1 up149	tc qdisc add dev $swp1 clsact150 151	ip link set dev $swp2 master br1152	ip link set dev $swp2 up153 154	bridge fdb append dev vx1 00:00:00:00:00:00 dst 2001:db8:4::1 self155	bridge fdb append dev vx1 00:00:00:00:00:00 dst 2001:db8:5::1 self156}157 158switch_destroy()159{160	bridge fdb del dev vx1 00:00:00:00:00:00 dst 2001:db8:5::1 self161	bridge fdb del dev vx1 00:00:00:00:00:00 dst 2001:db8:4::1 self162 163	ip link set dev $swp2 down164	ip link set dev $swp2 nomaster165 166	tc qdisc del dev $swp1 clsact167	ip link set dev $swp1 down168	ip link set dev $swp1 nomaster169 170	ip link set dev vx1 nomaster171	ip link set dev vx1 down172	ip link del dev vx1173 174	tc qdisc del dev $rp1 clsact175	rp1_unset_addr176	ip link set dev $rp1 down177 178	ip link set dev br1 down179	ip link del dev br1180}181 182vrp2_create()183{184	simple_if_init $rp2 2001:db8:3::2/64185	__simple_if_init v1 v$rp2 2001:db8:4::2/64186	__simple_if_init v3 v$rp2 2001:db8:5::2/64187	tc qdisc add dev v1 clsact188}189 190vrp2_destroy()191{192	tc qdisc del dev v1 clsact193	__simple_if_fini v3 2001:db8:5::2/64194	__simple_if_fini v1 2001:db8:4::2/64195	simple_if_fini $rp2 2001:db8:3::2/64196}197 198ns_init_common()199{200	local in_if=$1; shift201	local in_addr=$1; shift202	local other_in_addr=$1; shift203	local nh_addr=$1; shift204	local host_addr_ipv4=$1; shift205	local host_addr_ipv6=$1; shift206 207	ip link set dev $in_if up208	ip address add dev $in_if $in_addr/64209	tc qdisc add dev $in_if clsact210 211	ip link add name br2 type bridge vlan_filtering 0212	ip link set dev br2 up213 214	ip link add name w1 type veth peer name w2215 216	ip link set dev w1 master br2217	ip link set dev w1 up218 219	ip link add name vx2 type vxlan id 1000 local $in_addr \220		dstport "$VXPORT" udp6zerocsumrx221	ip link set dev vx2 up222	bridge fdb append dev vx2 00:00:00:00:00:00 dst 2001:db8:3::1 self223	bridge fdb append dev vx2 00:00:00:00:00:00 dst $other_in_addr self224 225	ip link set dev vx2 master br2226	tc qdisc add dev vx2 clsact227 228	simple_if_init w2 $host_addr_ipv4/28 $host_addr_ipv6/64229 230	ip route add 2001:db8:3::0/64 nexthop via $nh_addr231	ip route add $other_in_addr/128 nexthop via $nh_addr232}233export -f ns_init_common234 235ns1_create()236{237	ip netns add ns1238	ip link set dev v2 netns ns1239	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::3242}243 244ns1_destroy()245{246	ip netns exec ns1 ip link set dev v2 netns 1247	ip netns del ns1248}249 250ns2_create()251{252	ip netns add ns2253	ip link set dev v4 netns ns2254	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::4257}258 259ns2_destroy()260{261	ip netns exec ns2 ip link set dev v4 netns 1262	ip netns del ns2263}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_prepare277	forwarding_enable278 279	h1_create280	h2_create281	switch_create282 283	ip link add name v1 type veth peer name v2284	ip link add name v3 type veth peer name v4285	vrp2_create286	ns1_create287	ns2_create288 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_cleanup297 298	ns2_destroy299	ns1_destroy300	vrp2_destroy301	ip link del dev v3302	ip link del dev v1303 304	switch_destroy305	h2_destroy306	h1_destroy307 308	forwarding_restore309	vrf_cleanup310}311 312# For the first round of tests, vx1 is the first device to get313# attached to the bridge, and at that point the local IP is already314# configured. Try the other scenario of attaching the devices to a an315# 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 self321	bridge fdb del dev vx1 00:00:00:00:00:00 dst 2001:db8:4::1 self322	ip link set dev vx1 nomaster323	rp1_unset_addr324	sleep 5325 326	ip link set dev vx1 master br1327	bridge fdb append dev vx1 00:00:00:00:00:00 dst 2001:db8:4::1 self328	bridge fdb append dev vx1 00:00:00:00:00:00 dst 2001:db8:5::1 self329	sleep 1330	rp1_set_addr331	sleep 5332}333 334__ping_ipv4()335{336	local vxlan_local_ip=$1; shift337	local vxlan_remote_ip=$1; shift338	local src_ip=$1; shift339	local dst_ip=$1; shift340	local dev=$1; shift341	local info=$1; shift342 343	RET=0344 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 pass348	# Match ICMP-reply packets after decapsulation, so source IP is349	# destination IP of the ping and destination IP is source IP of the350	# 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 pass354 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=20 ping_do $dev $dst_ip358	check_err $? "Ping failed"359 360	tc_check_at_least_x_packets "dev $rp1 egress" 101 10 100361	check_err $? "Encapsulated packets did not go through router"362 363	tc_check_at_least_x_packets "dev $swp1 egress" 101 10 100364	check_err $? "Decapsulated packets did not go through switch"365 366	log_test "ping: $info"367 368	tc filter del dev $swp1 egress369	tc filter del dev $rp1 egress370}371 372ping_ipv4()373{374	RET=0375 376	local local_sw_ip=2001:db8:3::1377	local remote_ns1_ip=2001:db8:4::1378	local remote_ns2_ip=2001:db8:5::1379	local h1_ip=192.0.2.1380	local w2_ns1_ip=192.0.2.3381	local w2_ns2_ip=192.0.2.4382 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; shift394	local vxlan_remote_ip=$1; shift395	local src_ip=$1; shift396	local dst_ip=$1; shift397	local dev=$1; shift398	local info=$1; shift399 400	RET=0401 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 pass405	# Match ICMP-reply packets after decapsulation, so source IP is406	# destination IP of the ping and destination IP is source IP of the407	# 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 pass410 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=20 ping6_do $dev $dst_ip414	check_err $? "Ping failed"415 416	tc_check_at_least_x_packets "dev $rp1 egress" 101 100417	check_err $? "Encapsulated packets did not go through router"418 419	tc_check_at_least_x_packets "dev $swp1 egress" 101 100420	check_err $? "Decapsulated packets did not go through switch"421 422	log_test "ping6: $info"423 424	tc filter del dev $swp1 egress425	tc filter del dev $rp1 egress426}427 428ping_ipv6()429{430	RET=0431 432	local local_sw_ip=2001:db8:3::1433	local remote_ns1_ip=2001:db8:4::1434	local remote_ns2_ip=2001:db8:5::1435	local h1_ip=2001:db8:1::1436	local w2_ns1_ip=2001:db8:1::3437	local w2_ns2_ip=2001:db8:1::4438 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} $1450}451 452__flood_counter_add_del()453{454	local add_del=$1; shift455	local dst_ip=$1; shift456	local dev=$1; shift457	local ns=$1; shift458 459	# Putting the ICMP capture both to HW and to SW will end up460	# double-counting the packets that are trapped to slow path, such as for461	# 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, because463	# those are dropped due to MAC address mismatch; and skip_sw is a no-go464	# 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 pass474}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; shift489	local ns=$1; shift490 491	$(maybe_in_ns $ns) tc_rule_stats_get $dev 100 ingress492}493 494flood_fetch_stats()495{496	local counters=("${@}")497	local counter498 499	for counter in "${counters[@]}"; do500		flood_fetch_stat $counter501	done502}503 504vxlan_flood_test()505{506	local mac=$1; shift507	local dst=$1; shift508	local -a expects=("${@}")509 510	local -a counters=($h2 "vx2 ns1" "vx2 ns2")511	local counter512	local key513 514	for counter in "${counters[@]}"; do515		flood_counter_install $dst $counter516	done517 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 -q520	sleep 1521	local -a t1s=($(flood_fetch_stats "${counters[@]}"))522 523	for key in ${!t0s[@]}; do524		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	done530 531	for counter in "${counters[@]}"; do532		flood_counter_uninstall $dst $counter533	done534}535 536__test_flood()537{538	local mac=$1; shift539	local dst=$1; shift540	local what=$1; shift541 542	RET=0543 544	vxlan_flood_test $mac $dst 10 10 10545 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; shift557	local mac=$1; shift558	local dev=$1; shift559	local dst=$1; shift560 561	bridge fdb $add_del dev $dev $mac self static permanent \562		${dst:+dst} $dst 2>/dev/null563	bridge fdb $add_del dev $dev $mac master static 2>/dev/null564}565 566__test_unicast()567{568	local mac=$1; shift569	local dst=$1; shift570	local hit_idx=$1; shift571	local what=$1; shift572 573	RET=0574 575	local -a expects=(0 0 0)576	expects[$hit_idx]=10577 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 target589 590	for target in "${targets[@]}"; do591		vxlan_fdb_add_del add $target592	done593 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[@]}"; do599		vxlan_fdb_add_del del $target600	done601}602 603vxlan_ping_test()604{605	local ping_dev=$1; shift606	local ping_dip=$1; shift607	local ping_args=$1; shift608	local capture_dev=$1; shift609	local capture_dir=$1; shift610	local capture_pref=$1; shift611	local expect=$1; shift612 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 + 5))620	check_err $? "$capture_dev: Expected to capture $expect packets, got $delta."621}622 623test_ttl()624{625	RET=0626 627	tc filter add dev v1 egress pref 77 protocol ipv6 \628		flower ip_ttl 99 action pass629	vxlan_ping_test $h1 2001:db8:1::3 "" v1 egress 77 10630	tc filter del dev v1 egress pref 77 protocol ipv6631 632	log_test "VXLAN: envelope TTL"633}634 635test_tos()636{637	RET=0638 639	tc filter add dev v1 egress pref 77 protocol ipv6 \640		flower ip_tos 0x14 action pass641	vxlan_ping_test $h1 2001:db8:1::3 "-Q 0x14" v1 egress 77 10642	vxlan_ping_test $h1 2001:db8:1::3 "-Q 0x18" v1 egress 77 0643	tc filter del dev v1 egress pref 77 protocol ipv6644 645	log_test "VXLAN: envelope TOS inheritance"646}647 648__test_ecn_encap()649{650	local q=$1; shift651	local tos=$1; shift652 653	RET=0654 655	tc filter add dev v1 egress pref 77 protocol ipv6 \656		flower ip_tos $tos ip_proto udp dst_port $VXPORT action pass657	sleep 1658	vxlan_ping_test $h1 2001:db8:1::3 "-Q $q" v1 egress 77 10659	tc filter del dev v1 egress pref 77 protocol ipv6660 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 0x00668	__test_ecn_encap 0x01 0x01669	__test_ecn_encap 0x02 0x02670	__test_ecn_encap 0x03 0x02671}672 673vxlan_encapped_ping_do()674{675	local count=$1; shift676	local dev=$1; shift677	local next_hop_mac=$1; shift678	local dest_ip=$1; shift679	local dest_mac=$1; shift680	local inner_tos=$1; shift681	local outer_tos=$1; shift682	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 flags689		    )"00:00:00:"$(                : VXLAN reserved690		    )"00:03:e8:"$(                : VXLAN VNI691		    )"00:"$(                      : VXLAN reserved692		    )"$dest_mac:"$(               : ETH daddr693		    )"$(mac_get w2):"$(           : ETH saddr694		    )"86:dd:"$(                   : ETH type695		    )"6"$(			  : IP version696		    )"$inner_tos"$(               : Traffic class697		    )"0:00:00:"$(                 : Flow label698		    )"00:08:"$(                   : Payload length699		    )"3a:"$(                      : Next header700		    )"04:"$(                      : Hop limit701		    )"$saddr:"$(		  : IP saddr702		    )"$daddr:"$(		  : IP daddr703		    )"80:"$(			  : ICMPv6.type704		    )"00:"$(			  : ICMPv6.code705		    )"00:"$(			  : ICMPv6.checksum706		    )707}708export -f vxlan_encapped_ping_do709 710vxlan_encapped_ping_test()711{712	local ping_dev=$1; shift713	local nh_dev=$1; shift714	local ping_dip=$1; shift715	local inner_tos=$1; shift716	local outer_tos=$1; shift717	local stat_get=$1; shift718	local expect=$1; shift719 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_tos726	sleep 1727	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_test735 736__test_ecn_decap()737{738	local orig_inner_tos=$1; shift739	local orig_outer_tos=$1; shift740	local decapped_tos=$1; shift741 742	RET=0743 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 drop747	sleep 1748	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" 10751	tc filter del dev $h1 ingress pref 77752 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=03760 761	RET=0762 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" 10766 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 0x00774	__test_ecn_decap "0:0" 01 0x00775	__test_ecn_decap "0:0" 02 0x00776	# 00 03 is tested in test_ecn_decap_error()777	__test_ecn_decap "0:1" 00 0x01778	__test_ecn_decap "0:1" 01 0x01779	__test_ecn_decap "0:1" 02 0x01780	__test_ecn_decap "0:1" 03 0x03781	__test_ecn_decap "0:2" 00 0x02782	__test_ecn_decap "0:2" 01 0x01783	__test_ecn_decap "0:2" 02 0x02784	__test_ecn_decap "0:2" 03 0x03785	__test_ecn_decap "0:3" 00 0x03786	__test_ecn_decap "0:3" 01 0x03787	__test_ecn_decap "0:3" 02 0x03788	__test_ecn_decap "0:3" 03 0x03789	test_ecn_decap_error790}791 792test_all()793{794	log_info "Running tests with UDP port $VXPORT"795	tests_run796}797 798trap cleanup EXIT799 800setup_prepare801setup_wait802test_all803 804exit $EXIT_STATUS805