From: Amit Cohen <hidden> Date: 2021-12-21 14:50:15
mlxsw driver lately added support for VxLAN with IPv6 underlay.
This set adds the relevant tests for IPv6, most of them are same to
IPv4 tests with the required changes.
Patch set overview:
Patch #1 relaxes requirements for offloading TC filters that
match on 802.1q fields. The following selftests make use of these
newly-relaxed filters.
Patch #2 adds preparation as part of selftests API, which will be used
later.
Patches #3-#4 add tests for VxLAN with bridge aware and unaware.
Patche #5 cleans unused function.
Patches #6-#7 add tests for VxLAN symmetric and asymmetric.
Patch #8 adds test for Q-in-VNI.
Amit Cohen (8):
mlxsw: spectrum_flower: Make vlan_id limitation more specific
selftests: lib.sh: Add PING_COUNT to allow sending configurable amount
of packets
selftests: forwarding: Add VxLAN tests with a VLAN-unaware bridge for
IPv6
selftests: forwarding: Add VxLAN tests with a VLAN-aware bridge for
IPv6
selftests: forwarding: vxlan_bridge_1q: Remove unused function
selftests: forwarding: Add a test for VxLAN asymmetric routing with
IPv6
selftests: forwarding: Add a test for VxLAN symmetric routing with
IPv6
selftests: forwarding: Add Q-in-VNI test for IPv6
.../ethernet/mellanox/mlxsw/spectrum_flower.c | 3 +-
tools/testing/selftests/net/forwarding/lib.sh | 7 +-
.../selftests/net/forwarding/q_in_vni_ipv6.sh | 347 ++++++++
.../net/forwarding/vxlan_asymmetric_ipv6.sh | 504 +++++++++++
.../net/forwarding/vxlan_bridge_1d_ipv6.sh | 804 +++++++++++++++++
.../vxlan_bridge_1d_port_8472_ipv6.sh | 11 +
.../net/forwarding/vxlan_bridge_1q.sh | 20 -
.../net/forwarding/vxlan_bridge_1q_ipv6.sh | 837 ++++++++++++++++++
.../vxlan_bridge_1q_port_8472_ipv6.sh | 11 +
.../net/forwarding/vxlan_symmetric_ipv6.sh | 563 ++++++++++++
10 files changed, 3084 insertions(+), 23 deletions(-)
create mode 100755 tools/testing/selftests/net/forwarding/q_in_vni_ipv6.sh
create mode 100755 tools/testing/selftests/net/forwarding/vxlan_asymmetric_ipv6.sh
create mode 100755 tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh
create mode 100755 tools/testing/selftests/net/forwarding/vxlan_bridge_1d_port_8472_ipv6.sh
create mode 100755 tools/testing/selftests/net/forwarding/vxlan_bridge_1q_ipv6.sh
create mode 100755 tools/testing/selftests/net/forwarding/vxlan_bridge_1q_port_8472_ipv6.sh
create mode 100755 tools/testing/selftests/net/forwarding/vxlan_symmetric_ipv6.sh
--
2.31.1
From: Amit Cohen <hidden> Date: 2021-12-21 14:50:15
Spectrum ASICs do not support matching of VLAN ID at egress.
Currently, mlxsw driver forbids matching of all VLAN related fields at
egress, which is too strict check.
For example, the following filter is not supported by the driver:
$ tc filter add dev swpX egress protocol 802.1q pref 1 handle 101 flower
vlan_ethtype ipv4 src_ip .. dst_ip .. skip_sw action pass
Error: mlxsw_spectrum: vlan_id key is not supported on egress.
We have an error talking to the kernel
The filter above does not match on VLAN ID, but is bounced anyway.
Make the check more specific, forbid only matching of 'vlan_id' at egress.
Signed-off-by: Amit Cohen <redacted>
Reviewed-by: Petr Machata <petrm@nvidia.com>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
@@ -508,7 +508,8 @@ static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp,structflow_match_vlanmatch;flow_rule_match_vlan(rule,&match);-if(mlxsw_sp_flow_block_is_egress_bound(block)){+if(mlxsw_sp_flow_block_is_egress_bound(block)&&+match.mask->vlan_id){NL_SET_ERR_MSG_MOD(f->common.extack,"vlan_id key is not supported on egress");return-EOPNOTSUPP;}
From: Amit Cohen <hidden> Date: 2021-12-21 14:50:17
Currently `ping_do()` and `ping6_do()` send 10 packets.
There are cases that it is not possible to catch only the interesting
packets using tc rule, so then, it is possible to send many packets and
verify that at least this amount of packets hit the rule.
Add `PING_COUNT` variable, which is set to 10 by default, to allow tests
sending more than 10 packets using the existing ping API.
Signed-off-by: Amit Cohen <redacted>
Reviewed-by: Petr Machata <petrm@nvidia.com>
---
tools/testing/selftests/net/forwarding/lib.sh | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
From: Amit Cohen <hidden> Date: 2021-12-21 14:50:20
Add tests similar to vxlan_bridge_1d.sh and vxlan_bridge_1d_port_8472.sh.
The tests set up a topology with three VxLAN endpoints: one
"local", possibly offloaded, and two "remote", formed using veth pairs
and likely purely software bridges. The "local" endpoint is connected to
host systems by a VLAN-unaware bridge.
Since VxLAN tunnels must be unique per namespace, each of the "remote"
endpoints is in its own namespace. H3 forms the bridge between the three
domains.
Send IPv4 packets and IPv6 packets with IPv6 underlay.
Use `TC_FLAG`, which is defined in `forwarding.config` file, for TC
checks. `TC_FLAG` allows testing that on HW datapath, the traffic
actually goes through HW.
Signed-off-by: Amit Cohen <redacted>
Reviewed-by: Petr Machata <petrm@nvidia.com>
---
.../net/forwarding/vxlan_bridge_1d_ipv6.sh | 804 ++++++++++++++++++
.../vxlan_bridge_1d_port_8472_ipv6.sh | 11 +
2 files changed, 815 insertions(+)
create mode 100755 tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh
create mode 100755 tools/testing/selftests/net/forwarding/vxlan_bridge_1d_port_8472_ipv6.sh
@@ -0,0 +1,804 @@+#!/bin/bash+# SPDX-License-Identifier: GPL-2.0++# +-----------------------+ +------------------------++# | H1 (vrf) | | H2 (vrf) |+# | + $h1 | | + $h2 |+# | | 192.0.2.1/28 | | | 192.0.2.2/28 |+# | | 2001:db8:1::1/64 | | | 2001:db8:1::2/64 |+# +----|------------------+ +----|-------------------++# | |+# +----|--------------------------------------------------|-------------------++# | SW | | |+# | +--|--------------------------------------------------|-----------------+ |+# | | + $swp1 BR1 (802.1d) + $swp2 | |+# | | | |+# | | + vx1 (vxlan) | |+# | | local 2001:db8:3::1 | |+# | | remote 2001:db8:4::1 2001:db8:5::1 | |+# | | id 1000 dstport $VXPORT | |+# | +-----------------------------------------------------------------------+ |+# | |+# | 2001:db8:4::0/64 via 2001:db8:3::2 |+# | 2001:db8:5::0/64 via 2001:db8:3::2 |+# | |+# | + $rp1 |+# | | 2001:db8:3::1/64 |+# +----|----------------------------------------------------------------------++# |+# +----|----------------------------------------------------------++# | | VRP2 (vrf) |+# | + $rp2 |+# | 2001:db8:3::2/64 |+# | | (maybe) HW+# =============================================================================+# | | (likely) SW+# | + v1 (veth) + v3 (veth) |+# | | 2001:db8:4::2/64 | 2001:db8:5::2/64 |+# +----|---------------------------------------|------------------++# | |+# +----|--------------------------------+ +----|-------------------------------++# | + v2 (veth) NS1 (netns) | | + v4 (veth) NS2 (netns) |+# | 2001:db8:4::1/64 | | 2001:db8:5::1/64 |+# | | | |+# | 2001:db8:3::0/64 via 2001:db8:4::2 | | 2001:db8:3::0/64 via 2001:db8:5::2 |+# | 2001:db8:5::1/128 via 2001:db8:4::2 | | 2001:db8:4::1/128 via |+# | | | 2001:db8:5::2 |+# | | | |+# | +-------------------------------+ | | +-------------------------------+ |+# | | BR2 (802.1d) | | | | BR2 (802.1d) | |+# | | + vx2 (vxlan) | | | | + vx2 (vxlan) | |+# | | local 2001:db8:4::1 | | | | local 2001:db8:5::1 | |+# | | remote 2001:db8:3::1 | | | | remote 2001:db8:3::1 | |+# | | remote 2001:db8:5::1 | | | | remote 2001:db8:4::1 | |+# | | id 1000 dstport $VXPORT | | | | id 1000 dstport $VXPORT | |+# | | | | | | | |+# | | + w1 (veth) | | | | + w1 (veth) | |+# | +--|----------------------------+ | | +--|----------------------------+ |+# | | | | | |+# | +--|----------------------------+ | | +--|----------------------------+ |+# | | + w2 (veth) VW2 (vrf) | | | | + w2 (veth) VW2 (vrf) | |+# | | 192.0.2.3/28 | | | | 192.0.2.4/28 | |+# | | 2001:db8:1::3/64 | | | | 2001:db8:1::4/64 | |+# | +-------------------------------+ | | +-------------------------------+ |+# +-------------------------------------+ +------------------------------------+++:${VXPORT:=4789}+exportVXPORT++:${ALL_TESTS:="+ping_ipv4+ping_ipv6+test_flood+test_unicast+test_ttl+test_tos+test_ecn_encap+test_ecn_decap+reapply_config+ping_ipv4+ping_ipv6+test_flood+test_unicast+"}++NUM_NETIFS=6+sourcelib.sh+sourcetc_common.sh++h1_create()+{+simple_if_init$h1192.0.2.1/282001:db8:1::1/64+tcqdiscadddev$h1clsact+}++h1_destroy()+{+tcqdiscdeldev$h1clsact+simple_if_fini$h1192.0.2.1/282001:db8:1::1/64+}++h2_create()+{+simple_if_init$h2192.0.2.2/282001:db8:1::2/64+tcqdiscadddev$h2clsact+}++h2_destroy()+{+tcqdiscdeldev$h2clsact+simple_if_fini$h2192.0.2.2/282001:db8:1::2/64+}++rp1_set_addr()+{+ipaddressadddev$rp12001:db8:3::1/64++iprouteadd2001:db8:4::0/64nexthopvia2001:db8:3::2+iprouteadd2001:db8:5::0/64nexthopvia2001:db8:3::2+}++rp1_unset_addr()+{+iproutedel2001:db8:5::0/64nexthopvia2001:db8:3::2+iproutedel2001:db8:4::0/64nexthopvia2001:db8:3::2++ipaddressdeldev$rp12001:db8:3::1/64+}++switch_create()+{+iplinkaddnamebr1typebridgevlan_filtering0mcast_snooping0+# Make sure the bridge uses the MAC address of the local port and not+# that of the VxLAN's device.+iplinksetdevbr1address$(mac_get$swp1)+iplinksetdevbr1up++iplinksetdev$rp1up+rp1_set_addr+tcqdiscadddev$rp1clsact++iplinkaddnamevx1typevxlanid1000local2001:db8:3::1\+dstport"$VXPORT"nolearningudp6zerocsumrxudp6zerocsumtx\+tosinheritttl100+iplinksetdevvx1up++iplinksetdevvx1masterbr1+iplinksetdev$swp1masterbr1+iplinksetdev$swp1up+tcqdiscadddev$swp1clsact++iplinksetdev$swp2masterbr1+iplinksetdev$swp2up++bridgefdbappenddevvx100:00:00:00:00:00dst2001:db8:4::1self+bridgefdbappenddevvx100:00:00:00:00:00dst2001:db8:5::1self+}++switch_destroy()+{+bridgefdbdeldevvx100:00:00:00:00:00dst2001:db8:5::1self+bridgefdbdeldevvx100:00:00:00:00:00dst2001:db8:4::1self++iplinksetdev$swp2down+iplinksetdev$swp2nomaster++tcqdiscdeldev$swp1clsact+iplinksetdev$swp1down+iplinksetdev$swp1nomaster++iplinksetdevvx1nomaster+iplinksetdevvx1down+iplinkdeldevvx1++tcqdiscdeldev$rp1clsact+rp1_unset_addr+iplinksetdev$rp1down++iplinksetdevbr1down+iplinkdeldevbr1+}++vrp2_create()+{+simple_if_init$rp22001:db8:3::2/64+__simple_if_initv1v$rp22001:db8:4::2/64+__simple_if_initv3v$rp22001:db8:5::2/64+tcqdiscadddevv1clsact+}++vrp2_destroy()+{+tcqdiscdeldevv1clsact+__simple_if_finiv32001:db8:5::2/64+__simple_if_finiv12001:db8:4::2/64+simple_if_fini$rp22001:db8:3::2/64+}++ns_init_common()+{+localin_if=$1;shift+localin_addr=$1;shift+localother_in_addr=$1;shift+localnh_addr=$1;shift+localhost_addr_ipv4=$1;shift+localhost_addr_ipv6=$1;shift++iplinksetdev$in_ifup+ipaddressadddev$in_if$in_addr/64+tcqdiscadddev$in_ifclsact++iplinkaddnamebr2typebridgevlan_filtering0+iplinksetdevbr2up++iplinkaddnamew1typevethpeernamew2++iplinksetdevw1masterbr2+iplinksetdevw1up++iplinkaddnamevx2typevxlanid1000local$in_addr\+dstport"$VXPORT"udp6zerocsumrx+iplinksetdevvx2up+bridgefdbappenddevvx200:00:00:00:00:00dst2001:db8:3::1self+bridgefdbappenddevvx200:00:00:00:00:00dst$other_in_addrself++iplinksetdevvx2masterbr2+tcqdiscadddevvx2clsact++simple_if_initw2$host_addr_ipv4/28$host_addr_ipv6/64++iprouteadd2001:db8:3::0/64nexthopvia$nh_addr+iprouteadd$other_in_addr/128nexthopvia$nh_addr+}+export-fns_init_common++ns1_create()+{+ipnetnsaddns1+iplinksetdevv2netnsns1+in_nsns1\+ns_init_commonv22001:db8:4::12001:db8:5::12001:db8:4::2\+192.0.2.32001:db8:1::3+}++ns1_destroy()+{+ipnetnsexecns1iplinksetdevv2netns1+ipnetnsdelns1+}++ns2_create()+{+ipnetnsaddns2+iplinksetdevv4netnsns2+in_nsns2\+ns_init_commonv42001:db8:5::12001:db8:4::12001:db8:5::2\+192.0.2.42001:db8:1::4+}++ns2_destroy()+{+ipnetnsexecns2iplinksetdevv4netns1+ipnetnsdelns2+}++setup_prepare()+{+h1=${NETIFS[p1]}+swp1=${NETIFS[p2]}++swp2=${NETIFS[p3]}+h2=${NETIFS[p4]}++rp1=${NETIFS[p5]}+rp2=${NETIFS[p6]}++vrf_prepare+forwarding_enable++h1_create+h2_create+switch_create++iplinkaddnamev1typevethpeernamev2+iplinkaddnamev3typevethpeernamev4+vrp2_create+ns1_create+ns2_create++r1_mac=$(in_nsns1mac_getw2)+r2_mac=$(in_nsns2mac_getw2)+h2_mac=$(mac_get$h2)+}++cleanup()+{+pre_cleanup++ns2_destroy+ns1_destroy+vrp2_destroy+iplinkdeldevv3+iplinkdeldevv1++switch_destroy+h2_destroy+h1_destroy++forwarding_restore+vrf_cleanup+}++# For the first round of tests, vx1 is the first device to get+# attached to the bridge, and at that point the local IP is already+# configured. Try the other scenario of attaching the devices to a an+# already-offloaded bridge, and only then assign the local IP.+reapply_config()+{+log_info"Reapplying configuration"++bridgefdbdeldevvx100:00:00:00:00:00dst2001:db8:5::1self+bridgefdbdeldevvx100:00:00:00:00:00dst2001:db8:4::1self+iplinksetdevvx1nomaster+rp1_unset_addr+sleep5++iplinksetdevvx1masterbr1+bridgefdbappenddevvx100:00:00:00:00:00dst2001:db8:4::1self+bridgefdbappenddevvx100:00:00:00:00:00dst2001:db8:5::1self+sleep1+rp1_set_addr+sleep5+}++__ping_ipv4()+{+localvxlan_local_ip=$1;shift+localvxlan_remote_ip=$1;shift+localsrc_ip=$1;shift+localdst_ip=$1;shift+localdev=$1;shift+localinfo=$1;shift++RET=0++tcfilteradddev$rp1egressprotocolipv6pref1handle101\+flowerip_protoudpsrc_ip$vxlan_local_ip\+dst_ip$vxlan_remote_ipdst_port$VXPORT$TC_FLAGactionpass+# Match ICMP-reply packets after decapsulation, so source IP is+# destination IP of the ping and destination IP is source IP of the+# ping.+tcfilteradddev$swp1egressprotocolippref1handle101\+flowersrc_ip$dst_ipdst_ip$src_ip\+$TC_FLAGactionpass++# Send 100 packets and verify that at least 100 packets hit the rule,+# to overcome ARP noise.+PING_COUNT=100PING_TIMEOUT=11ping_do$dev$dst_ip+check_err$?"Ping failed"++tc_check_at_least_x_packets"dev $rp1 egress"10110100+check_err$?"Encapsulated packets did not go through router"++tc_check_at_least_x_packets"dev $swp1 egress"10110100+check_err$?"Decapsulated packets did not go through switch"++log_test"ping: $info"++tcfilterdeldev$swp1egress+tcfilterdeldev$rp1egress+}++ping_ipv4()+{+RET=0++locallocal_sw_ip=2001:db8:3::1+localremote_ns1_ip=2001:db8:4::1+localremote_ns2_ip=2001:db8:5::1+localh1_ip=192.0.2.1+localw2_ns1_ip=192.0.2.3+localw2_ns2_ip=192.0.2.4++ping_test$h1192.0.2.2": local->local"++__ping_ipv4$local_sw_ip$remote_ns1_ip$h1_ip$w2_ns1_ip$h1\+"local->remote 1"+__ping_ipv4$local_sw_ip$remote_ns2_ip$h1_ip$w2_ns2_ip$h1\+"local->remote 2"+}++__ping_ipv6()+{+localvxlan_local_ip=$1;shift+localvxlan_remote_ip=$1;shift+localsrc_ip=$1;shift+localdst_ip=$1;shift+localdev=$1;shift+localinfo=$1;shift++RET=0++tcfilteradddev$rp1egressprotocolipv6pref1handle101\+flowerip_protoudpsrc_ip$vxlan_local_ip\+dst_ip$vxlan_remote_ipdst_port$VXPORT$TC_FLAGactionpass+# Match ICMP-reply packets after decapsulation, so source IP is+# destination IP of the ping and destination IP is source IP of the+# ping.+tcfilteradddev$swp1egressprotocolipv6pref1handle101\+flowersrc_ip$dst_ipdst_ip$src_ip$TC_FLAGactionpass++# Send 100 packets and verify that at least 100 packets hit the rule,+# to overcome neighbor discovery noise.+PING_COUNT=100PING_TIMEOUT=11ping6_do$dev$dst_ip+check_err$?"Ping failed"++tc_check_at_least_x_packets"dev $rp1 egress"101100+check_err$?"Encapsulated packets did not go through router"++tc_check_at_least_x_packets"dev $swp1 egress"101100+check_err$?"Decapsulated packets did not go through switch"++log_test"ping6: $info"++tcfilterdeldev$swp1egress+tcfilterdeldev$rp1egress+}++ping_ipv6()+{+RET=0++locallocal_sw_ip=2001:db8:3::1+localremote_ns1_ip=2001:db8:4::1+localremote_ns2_ip=2001:db8:5::1+localh1_ip=2001:db8:1::1+localw2_ns1_ip=2001:db8:1::3+localw2_ns2_ip=2001:db8:1::4++ping6_test$h12001:db8:1::2": local->local"++__ping_ipv6$local_sw_ip$remote_ns1_ip$h1_ip$w2_ns1_ip$h1\+"local->remote 1"+__ping_ipv6$local_sw_ip$remote_ns2_ip$h1_ip$w2_ns2_ip$h1\+"local->remote 2"+}++maybe_in_ns()+{+echo${1:+in_ns}$1+}++__flood_counter_add_del()+{+localadd_del=$1;shift+localdst_ip=$1;shift+localdev=$1;shift+localns=$1;shift++# Putting the ICMP capture both to HW and to SW will end up+# double-counting the packets that are trapped to slow path, such as for+# the unicast test. Adding either skip_hw or skip_sw fixes this problem,+# but with skip_hw, the flooded packets are not counted at all, because+# those are dropped due to MAC address mismatch; and skip_sw is a no-go+# for veth-based topologies.+#+# So try to install with skip_sw and fall back to skip_sw if that fails.++$(maybe_in_ns$ns)tcfilter$add_deldev"$dev"ingress\+protoipv6pref100flowerdst_ip$dst_ipip_proto\+icmpv6skip_swactionpass2>/dev/null||\+$(maybe_in_ns$ns)tcfilter$add_deldev"$dev"ingress\+protoipv6pref100flowerdst_ip$dst_ipip_proto\+icmpv6skip_hwactionpass+}++flood_counter_install()+{+__flood_counter_add_deladd"$@"+}++flood_counter_uninstall()+{+__flood_counter_add_deldel"$@"+}++flood_fetch_stat()+{+localdev=$1;shift+localns=$1;shift++$(maybe_in_ns$ns)tc_rule_stats_get$dev100ingress+}++flood_fetch_stats()+{+localcounters=("${@}")+localcounter++forcounterin"${counters[@]}";do+flood_fetch_stat$counter+done+}++vxlan_flood_test()+{+localmac=$1;shift+localdst=$1;shift+local-aexpects=("${@}")++local-acounters=($h2"vx2 ns1""vx2 ns2")+localcounter+localkey++forcounterin"${counters[@]}";do+flood_counter_install$dst$counter+done++local-at0s=($(flood_fetch_stats"${counters[@]}"))+$MZ-6$h1-c10-d100msec-p64-b$mac-B$dst-ticmp6type=128-q+sleep1+local-at1s=($(flood_fetch_stats"${counters[@]}"))++forkeyin${!t0s[@]};do+localdelta=$((t1s[$key]-t0s[$key]))+localexpect=${expects[$key]}++((expect==delta))+check_err$?"${counters[$key]}: Expected to capture $expect packets, got $delta."+done++forcounterin"${counters[@]}";do+flood_counter_uninstall$dst$counter+done+}++__test_flood()+{+localmac=$1;shift+localdst=$1;shift+localwhat=$1;shift++RET=0++vxlan_flood_test$mac$dst101010++log_test"VXLAN: $what"+}++test_flood()+{+__test_floodde:ad:be:ef:13:372001:db8:1::100"flood"+}++vxlan_fdb_add_del()+{+localadd_del=$1;shift+localmac=$1;shift+localdev=$1;shift+localdst=$1;shift++bridgefdb$add_deldev$dev$macselfstaticpermanent\+${dst:+dst}$dst2>/dev/null+bridgefdb$add_deldev$dev$macmasterstatic2>/dev/null+}++__test_unicast()+{+localmac=$1;shift+localdst=$1;shift+localhit_idx=$1;shift+localwhat=$1;shift++RET=0++local-aexpects=(000)+expects[$hit_idx]=10++vxlan_flood_test$mac$dst"${expects[@]}"++log_test"VXLAN: $what"+}++test_unicast()+{+local-atargets=("$h2_mac$h2"+"$r1_mac vx1 2001:db8:4::1"+"$r2_mac vx1 2001:db8:5::1")+localtarget++fortargetin"${targets[@]}";do+vxlan_fdb_add_deladd$target+done++__test_unicast$h2_mac2001:db8:1::20"local MAC unicast"+__test_unicast$r1_mac2001:db8:1::31"remote MAC 1 unicast"+__test_unicast$r2_mac2001:db8:1::42"remote MAC 2 unicast"++fortargetin"${targets[@]}";do+vxlan_fdb_add_deldel$target+done+}++vxlan_ping_test()+{+localping_dev=$1;shift+localping_dip=$1;shift+localping_args=$1;shift+localcapture_dev=$1;shift+localcapture_dir=$1;shift+localcapture_pref=$1;shift+localexpect=$1;shift++localt0=$(tc_rule_stats_get$capture_dev$capture_pref$capture_dir)+ping6_do$ping_dev$ping_dip"$ping_args"+localt1=$(tc_rule_stats_get$capture_dev$capture_pref$capture_dir)+localdelta=$((t1-t0))++# Tolerate a couple stray extra packets.+((expect<=delta&&delta<=expect+2))+check_err$?"$capture_dev: Expected to capture $expect packets, got $delta."+}++test_ttl()+{+RET=0++tcfilteradddevv1egresspref77protocolipv6\+flowerip_ttl99actionpass+vxlan_ping_test$h12001:db8:1::3""v1egress7710+tcfilterdeldevv1egresspref77protocolipv6++log_test"VXLAN: envelope TTL"+}++test_tos()+{+RET=0++tcfilteradddevv1egresspref77protocolipv6\+flowerip_tos0x14actionpass+vxlan_ping_test$h12001:db8:1::3"-Q 0x14"v1egress7710+vxlan_ping_test$h12001:db8:1::3"-Q 0x18"v1egress770+tcfilterdeldevv1egresspref77protocolipv6++log_test"VXLAN: envelope TOS inheritance"+}++__test_ecn_encap()+{+localq=$1;shift+localtos=$1;shift++RET=0++tcfilteradddevv1egresspref77protocolipv6\+flowerip_tos$tosactionpass+sleep1+vxlan_ping_test$h12001:db8:1::3"-Q $q"v1egress7710+tcfilterdeldevv1egresspref77protocolipv6++log_test"VXLAN: ECN encap: $q->$tos"+}++test_ecn_encap()+{+# In accordance with INET_ECN_encapsulate()+__test_ecn_encap0x000x00+__test_ecn_encap0x010x01+__test_ecn_encap0x020x02+__test_ecn_encap0x030x02+}++vxlan_encapped_ping_do()+{+localcount=$1;shift+localdev=$1;shift+localnext_hop_mac=$1;shift+localdest_ip=$1;shift+localdest_mac=$1;shift+localinner_tos=$1;shift+localouter_tos=$1;shift+localsaddr="20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:03"+localdaddr="20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:01"++$MZ-6$dev-c$count-d100msec-q\+-b$next_hop_mac-B$dest_ip\+-tudptos=$outer_tos,sp=23456,dp=$VXPORT,p=$(:+)"08:"$(:VXLANflags+)"00:00:00:"$(:VXLANreserved+)"00:03:e8:"$(:VXLANVNI+)"00:"$(:VXLANreserved+)"$dest_mac:"$(:ETHdaddr+)"$(mac_getw2):"$(:ETHsaddr+)"86:dd:"$(:ETHtype+)"6"$(:IPversion+)"$inner_tos"$(:Trafficclass+)"0:00:00:"$(:Flowlabel+)"00:08:"$(:Payloadlength+)"3a:"$(:Nextheader+)"04:"$(:Hoplimit+)"$saddr:"$(:IPsaddr+)"$daddr:"$(:IPdaddr+)"80:"$(:ICMPv6.type+)"00:"$(:ICMPv6.code+)"00:"$(:ICMPv6.checksum+)+}+export-fvxlan_encapped_ping_do++vxlan_encapped_ping_test()+{+localping_dev=$1;shift+localnh_dev=$1;shift+localping_dip=$1;shift+localinner_tos=$1;shift+localouter_tos=$1;shift+localstat_get=$1;shift+localexpect=$1;shift++localt0=$($stat_get)++in_nsns1\+vxlan_encapped_ping_do10$ping_dev$(mac_get$nh_dev)\+$ping_dip$(mac_get$h1)\+$inner_tos$outer_tos+sleep1+localt1=$($stat_get)+localdelta=$((t1-t0))++# Tolerate a couple stray extra packets.+((expect<=delta&&delta<=expect+2))+check_err$?"Expected to capture $expect packets, got $delta."+}+export-fvxlan_encapped_ping_test++__test_ecn_decap()+{+localorig_inner_tos=$1;shift+localorig_outer_tos=$1;shift+localdecapped_tos=$1;shift++RET=0++tcfilteradddev$h1ingresspref77protocolipv6\+flowersrc_ip2001:db8:1::3dst_ip2001:db8:1::1\+ip_tos$decapped_tosactiondrop+sleep1+vxlan_encapped_ping_testv2v12001:db8:3::1\+$orig_inner_tos$orig_outer_tos\+"tc_rule_stats_get $h1 77 ingress"10+tcfilterdeldev$h1ingresspref77++log_test"VXLAN: ECN decap: $orig_outer_tos/$orig_inner_tos->$decapped_tos"+}++test_ecn_decap_error()+{+localorig_inner_tos="0:0"+localorig_outer_tos=03++RET=0++vxlan_encapped_ping_testv2v12001:db8:3::1\+$orig_inner_tos$orig_outer_tos\+"link_stats_rx_errors_get vx1"10++log_test"VXLAN: ECN decap: $orig_outer_tos/$orig_inner_tos->error"+}++test_ecn_decap()+{+# In accordance with INET_ECN_decapsulate()+__test_ecn_decap"0:0"000x00+__test_ecn_decap"0:0"010x00+__test_ecn_decap"0:0"020x00+# 00 03 is tested in test_ecn_decap_error()+__test_ecn_decap"0:1"000x01+__test_ecn_decap"0:1"010x01+__test_ecn_decap"0:1"020x01+__test_ecn_decap"0:1"030x03+__test_ecn_decap"0:2"000x02+__test_ecn_decap"0:2"010x01+__test_ecn_decap"0:2"020x02+__test_ecn_decap"0:2"030x03+__test_ecn_decap"0:3"000x03+__test_ecn_decap"0:3"010x03+__test_ecn_decap"0:3"020x03+__test_ecn_decap"0:3"030x03+test_ecn_decap_error+}++test_all()+{+log_info"Running tests with UDP port $VXPORT"+tests_run+}++trapcleanupEXIT++setup_prepare+setup_wait+test_all++exit$EXIT_STATUS
@@ -0,0 +1,11 @@+#!/bin/bash+# SPDX-License-Identifier: GPL-2.0++# A wrapper to run VXLAN tests with an unusual port number.++VXPORT=8472+ALL_TESTS="+ping_ipv4+ping_ipv6+"+sourcevxlan_bridge_1d_ipv6.sh
From: Amit Cohen <hidden> Date: 2021-12-21 14:51:35
The tests are very similar to their VLAN-unaware counterpart
(vxlan_bridge_1d_ipv6.sh and vxlan_bridge_1d_port_8472_ipv6.sh),
but instead of using multiple VLAN-unaware bridges, a single VLAN-aware
bridge is used with multiple VLANs.
Signed-off-by: Amit Cohen <redacted>
Reviewed-by: Petr Machata <petrm@nvidia.com>
---
.../net/forwarding/vxlan_bridge_1q_ipv6.sh | 837 ++++++++++++++++++
.../vxlan_bridge_1q_port_8472_ipv6.sh | 11 +
2 files changed, 848 insertions(+)
create mode 100755 tools/testing/selftests/net/forwarding/vxlan_bridge_1q_ipv6.sh
create mode 100755 tools/testing/selftests/net/forwarding/vxlan_bridge_1q_port_8472_ipv6.sh
@@ -0,0 +1,837 @@+#!/bin/bash+# SPDX-License-Identifier: GPL-2.0++# +-----------------------+ +------------------------++# | H1 (vrf) | | H2 (vrf) |+# | + $h1.10 | | + $h2.10 |+# | | 192.0.2.1/28 | | | 192.0.2.2/28 |+# | | 2001:db8:1::1/64 | | | 2001:db8:1::2/64 |+# | | | | | |+# | | + $h1.20 | | | + $h2.20 |+# | \ | 198.51.100.1/24 | | \ | 198.51.100.2/24 |+# | \ | 2001:db8:2::1/64 | | \ | 2001:db8:2::2/64 |+# | \| | | \| |+# | + $h1 | | + $h2 |+# +----|------------------+ +----|-------------------++# | |+# +----|--------------------------------------------------|-------------------++# | SW | | |+# | +--|--------------------------------------------------|-----------------+ |+# | | + $swp1 BR1 (802.1q) + $swp2 | |+# | | vid 10 vid 10 | |+# | | vid 20 vid 20 | |+# | | | |+# | | + vx10 (vxlan) + vx20 (vxlan) | |+# | | local: local: | |+# | | 2001:db8:3::1 2001:db8:3::1 | |+# | | remote: remote: | |+# | | 2001:db8:4::1 2001:db8:5::1 2001:db8:4::1 2001:db8:5::1 | |+# | | id 1000 dstport $VXPORT id 2000 dstport $VXPORT | |+# | | vid 10 pvid untagged vid 20 pvid untagged | |+# | +-----------------------------------------------------------------------+ |+# | |+# | 2001:db8:4::0/64 via 2001:db8:3::2 |+# | 2001:db8:5::0/64 via 2001:db8:3::2 |+# | |+# | + $rp1 |+# | | 2001:db8:3::1/64 |+# +----|----------------------------------------------------------------------++# |+# +----|----------------------------------------------------------++# | | VRP2 (vrf) |+# | + $rp2 |+# | 2001:db8:3::2/64 |+# | | (maybe) HW+# =============================================================================+# | | (likely) SW+# | + v1 (veth) + v3 (veth) |+# | | 2001:db8:4::2/64 | 2001:db8:5::2/64 |+# +----|---------------------------------------|------------------++# | |+# +----|--------------------------------+ +----|-------------------------------++# | + v2 (veth) NS1 (netns) | | + v4 (veth) NS2 (netns) |+# | 2001:db8:4::1/64 | | 2001:db8:5::1/64 |+# | | | |+# | 2001:db8:3::0/64 via 2001:db8:4::2 | | 2001:db8:3::0/64 via 2001:db8:5::2 |+# | 2001:db8:5::1/128 via 2001:db8:4::2 | | 2001:db8:4::1/128 via |+# | | | 2001:db8:5::2 |+# | | | |+# | +-------------------------------+ | | +-------------------------------+ |+# | | BR2 (802.1q) | | | | BR2 (802.1q) | |+# | | + vx10 (vxlan) | | | | + vx10 (vxlan) | |+# | | local 2001:db8:4::1 | | | | local 2001:db8:5::1 | |+# | | remote 2001:db8:3::1 | | | | remote 2001:db8:3::1 | |+# | | remote 2001:db8:5::1 | | | | remote 2001:db8:4::1 | |+# | | id 1000 dstport $VXPORT | | | | id 1000 dstport $VXPORT | |+# | | vid 10 pvid untagged | | | | vid 10 pvid untagged | |+# | | | | | | | |+# | | + vx20 (vxlan) | | | | + vx20 (vxlan) | |+# | | local 2001:db8:4::1 | | | | local 2001:db8:5::1 | |+# | | remote 2001:db8:3::1 | | | | remote 2001:db8:3::1 | |+# | | remote 2001:db8:5::1 | | | | remote 2001:db8:4::1 | |+# | | id 2000 dstport $VXPORT | | | | id 2000 dstport $VXPORT | |+# | | vid 20 pvid untagged | | | | vid 20 pvid untagged | |+# | | | | | | | |+# | | + w1 (veth) | | | | + w1 (veth) | |+# | | | vid 10 | | | | | vid 10 | |+# | | | vid 20 | | | | | vid 20 | |+# | +--|----------------------------+ | | +--|----------------------------+ |+# | | | | | |+# | +--|----------------------------+ | | +--|----------------------------+ |+# | | + w2 (veth) VW2 (vrf) | | | | + w2 (veth) VW2 (vrf) | |+# | | |\ | | | | |\ | |+# | | | + w2.10 | | | | | + w2.10 | |+# | | | 192.0.2.3/28 | | | | | 192.0.2.4/28 | |+# | | | 2001:db8:1::3/64 | | | | | 2001:db8:1::4/64 | |+# | | | | | | | | | |+# | | + w2.20 | | | | + w2.20 | |+# | | 198.51.100.3/24 | | | | 198.51.100.4/24 | |+# | | 2001:db8:2::3/64 | | | | 2001:db8:2::4/64 | |+# | +-------------------------------+ | | +-------------------------------+ |+# +-------------------------------------+ +------------------------------------+++:${VXPORT:=4789}+exportVXPORT++:${ALL_TESTS:="+ping_ipv4+ping_ipv6+test_flood+test_unicast+reapply_config+ping_ipv4+ping_ipv6+test_flood+test_unicast+test_pvid+ping_ipv4+ping_ipv6+test_flood+test_pvid+"}++NUM_NETIFS=6+sourcelib.sh+sourcetc_common.sh++h1_create()+{+simple_if_init$h1+tcqdiscadddev$h1clsact+vlan_create$h110v$h1192.0.2.1/282001:db8:1::1/64+vlan_create$h120v$h1198.51.100.1/242001:db8:2::1/64+}++h1_destroy()+{+vlan_destroy$h120+vlan_destroy$h110+tcqdiscdeldev$h1clsact+simple_if_fini$h1+}++h2_create()+{+simple_if_init$h2+tcqdiscadddev$h2clsact+vlan_create$h210v$h2192.0.2.2/282001:db8:1::2/64+vlan_create$h220v$h2198.51.100.2/242001:db8:2::2/64+}++h2_destroy()+{+vlan_destroy$h220+vlan_destroy$h210+tcqdiscdeldev$h2clsact+simple_if_fini$h2+}++rp1_set_addr()+{+ipaddressadddev$rp12001:db8:3::1/64++iprouteadd2001:db8:4::0/64nexthopvia2001:db8:3::2+iprouteadd2001:db8:5::0/64nexthopvia2001:db8:3::2+}++rp1_unset_addr()+{+iproutedel2001:db8:5::0/64nexthopvia2001:db8:3::2+iproutedel2001:db8:4::0/64nexthopvia2001:db8:3::2++ipaddressdeldev$rp12001:db8:3::1/64+}++switch_create()+{+iplinkaddnamebr1typebridgevlan_filtering1vlan_default_pvid0\+mcast_snooping0+# Make sure the bridge uses the MAC address of the local port and not+# that of the VxLAN's device.+iplinksetdevbr1address$(mac_get$swp1)+iplinksetdevbr1up++iplinksetdev$rp1up+rp1_set_addr+tcqdiscadddev$rp1clsact++iplinkaddnamevx10typevxlanid1000local2001:db8:3::1\+dstport"$VXPORT"nolearningudp6zerocsumrxudp6zerocsumtx\+tosinheritttl100+iplinksetdevvx10up++iplinksetdevvx10masterbr1+bridgevlanaddvid10devvx10pviduntagged++iplinkaddnamevx20typevxlanid2000local2001:db8:3::1\+dstport"$VXPORT"nolearningudp6zerocsumrxudp6zerocsumtx\+tosinheritttl100+iplinksetdevvx20up++iplinksetdevvx20masterbr1+bridgevlanaddvid20devvx20pviduntagged++iplinksetdev$swp1masterbr1+iplinksetdev$swp1up+tcqdiscadddev$swp1clsact+bridgevlanaddvid10dev$swp1+bridgevlanaddvid20dev$swp1++iplinksetdev$swp2masterbr1+iplinksetdev$swp2up+bridgevlanaddvid10dev$swp2+bridgevlanaddvid20dev$swp2++bridgefdbappenddevvx1000:00:00:00:00:00dst2001:db8:4::1self+bridgefdbappenddevvx1000:00:00:00:00:00dst2001:db8:5::1self++bridgefdbappenddevvx2000:00:00:00:00:00dst2001:db8:4::1self+bridgefdbappenddevvx2000:00:00:00:00:00dst2001:db8:5::1self+}++switch_destroy()+{+bridgefdbdeldevvx2000:00:00:00:00:00dst2001:db8:5::1self+bridgefdbdeldevvx2000:00:00:00:00:00dst2001:db8:4::1self++bridgefdbdeldevvx1000:00:00:00:00:00dst2001:db8:5::1self+bridgefdbdeldevvx1000:00:00:00:00:00dst2001:db8:4::1self++bridgevlandelvid20dev$swp2+bridgevlandelvid10dev$swp2+iplinksetdev$swp2down+iplinksetdev$swp2nomaster++bridgevlandelvid20dev$swp1+bridgevlandelvid10dev$swp1+tcqdiscdeldev$swp1clsact+iplinksetdev$swp1down+iplinksetdev$swp1nomaster++bridgevlandelvid20devvx20+iplinksetdevvx20nomaster++iplinksetdevvx20down+iplinkdeldevvx20++bridgevlandelvid10devvx10+iplinksetdevvx10nomaster++iplinksetdevvx10down+iplinkdeldevvx10++tcqdiscdeldev$rp1clsact+rp1_unset_addr+iplinksetdev$rp1down++iplinksetdevbr1down+iplinkdeldevbr1+}++vrp2_create()+{+simple_if_init$rp22001:db8:3::2/64+__simple_if_initv1v$rp22001:db8:4::2/64+__simple_if_initv3v$rp22001:db8:5::2/64+tcqdiscadddevv1clsact+}++vrp2_destroy()+{+tcqdiscdeldevv1clsact+__simple_if_finiv32001:db8:5::2/64+__simple_if_finiv12001:db8:4::2/64+simple_if_fini$rp22001:db8:3::2/64+}++ns_init_common()+{+localin_if=$1;shift+localin_addr=$1;shift+localother_in_addr=$1;shift+localnh_addr=$1;shift+localhost_addr1_ipv4=$1;shift+localhost_addr1_ipv6=$1;shift+localhost_addr2_ipv4=$1;shift+localhost_addr2_ipv6=$1;shift++iplinksetdev$in_ifup+ipaddressadddev$in_if$in_addr/64+tcqdiscadddev$in_ifclsact++iplinkaddnamebr2typebridgevlan_filtering1vlan_default_pvid0+iplinksetdevbr2up++iplinkaddnamew1typevethpeernamew2++iplinksetdevw1masterbr2+iplinksetdevw1up++bridgevlanaddvid10devw1+bridgevlanaddvid20devw1++iplinkaddnamevx10typevxlanid1000local$in_addr\+dstport"$VXPORT"udp6zerocsumrx+iplinksetdevvx10up+bridgefdbappenddevvx1000:00:00:00:00:00dst2001:db8:3::1self+bridgefdbappenddevvx1000:00:00:00:00:00dst$other_in_addrself++iplinksetdevvx10masterbr2+tcqdiscadddevvx10clsact++bridgevlanaddvid10devvx10pviduntagged++iplinkaddnamevx20typevxlanid2000local$in_addr\+dstport"$VXPORT"udp6zerocsumrx+iplinksetdevvx20up+bridgefdbappenddevvx2000:00:00:00:00:00dst2001:db8:3::1self+bridgefdbappenddevvx2000:00:00:00:00:00dst$other_in_addrself++iplinksetdevvx20masterbr2+tcqdiscadddevvx20clsact++bridgevlanaddvid20devvx20pviduntagged++simple_if_initw2+vlan_createw210vw2$host_addr1_ipv4/28$host_addr1_ipv6/64+vlan_createw220vw2$host_addr2_ipv4/24$host_addr2_ipv6/64++iprouteadd2001:db8:3::0/64nexthopvia$nh_addr+iprouteadd$other_in_addr/128nexthopvia$nh_addr+}+export-fns_init_common++ns1_create()+{+ipnetnsaddns1+iplinksetdevv2netnsns1+in_nsns1\+ns_init_commonv22001:db8:4::12001:db8:5::12001:db8:4::2\+192.0.2.32001:db8:1::3198.51.100.32001:db8:2::3+}++ns1_destroy()+{+ipnetnsexecns1iplinksetdevv2netns1+ipnetnsdelns1+}++ns2_create()+{+ipnetnsaddns2+iplinksetdevv4netnsns2+in_nsns2\+ns_init_commonv42001:db8:5::12001:db8:4::12001:db8:5::2\+192.0.2.42001:db8:1::4198.51.100.42001:db8:2::4+}++ns2_destroy()+{+ipnetnsexecns2iplinksetdevv4netns1+ipnetnsdelns2+}++setup_prepare()+{+h1=${NETIFS[p1]}+swp1=${NETIFS[p2]}++swp2=${NETIFS[p3]}+h2=${NETIFS[p4]}++rp1=${NETIFS[p5]}+rp2=${NETIFS[p6]}++vrf_prepare+forwarding_enable++h1_create+h2_create+switch_create++iplinkaddnamev1typevethpeernamev2+iplinkaddnamev3typevethpeernamev4+vrp2_create+ns1_create+ns2_create++r1_mac=$(in_nsns1mac_getw2)+r2_mac=$(in_nsns2mac_getw2)+h2_mac=$(mac_get$h2)+}++cleanup()+{+pre_cleanup++ns2_destroy+ns1_destroy+vrp2_destroy+iplinkdeldevv3+iplinkdeldevv1++switch_destroy+h2_destroy+h1_destroy++forwarding_restore+vrf_cleanup+}++# For the first round of tests, vx10 and vx20 were the first devices to get+# attached to the bridge, and at that point the local IP is already+# configured. Try the other scenario of attaching these devices to a bridge+# that already has local ports members, and only then assign the local IP.+reapply_config()+{+log_info"Reapplying configuration"++bridgefdbdeldevvx2000:00:00:00:00:00dst2001:db8:5::1self+bridgefdbdeldevvx2000:00:00:00:00:00dst2001:db8:4::1self++bridgefdbdeldevvx1000:00:00:00:00:00dst2001:db8:5::1self+bridgefdbdeldevvx1000:00:00:00:00:00dst2001:db8:4::1self++iplinksetdevvx20nomaster+iplinksetdevvx10nomaster++rp1_unset_addr+sleep5++iplinksetdevvx10masterbr1+bridgevlanaddvid10devvx10pviduntagged++iplinksetdevvx20masterbr1+bridgevlanaddvid20devvx20pviduntagged++bridgefdbappenddevvx1000:00:00:00:00:00dst2001:db8:4::1self+bridgefdbappenddevvx1000:00:00:00:00:00dst2001:db8:5::1self++bridgefdbappenddevvx2000:00:00:00:00:00dst2001:db8:4::1self+bridgefdbappenddevvx2000:00:00:00:00:00dst2001:db8:5::1self++rp1_set_addr+sleep5+}++__ping_ipv4()+{+localvxlan_local_ip=$1;shift+localvxlan_remote_ip=$1;shift+localsrc_ip=$1;shift+localdst_ip=$1;shift+localdev=$1;shift+localinfo=$1;shift++RET=0++tcfilteradddev$rp1egressprotocolipv6pref1handle101\+flowerip_protoudpsrc_ip$vxlan_local_ip\+dst_ip$vxlan_remote_ipdst_port$VXPORT$TC_FLAGactionpass+# Match ICMP-reply packets after decapsulation, so source IP is+# destination IP of the ping and destination IP is source IP of the+# ping.+tcfilteradddev$swp1egressprotocol802.1qpref1handle101\+flowervlan_ethtypeipv4src_ip$dst_ipdst_ip$src_ip\+$TC_FLAGactionpass++# Send 100 packets and verify that at least 100 packets hit the rule,+# to overcome ARP noise.+PING_COUNT=100PING_TIMEOUT=11ping_do$dev$dst_ip+check_err$?"Ping failed"++tc_check_at_least_x_packets"dev $rp1 egress"10110100+check_err$?"Encapsulated packets did not go through router"++tc_check_at_least_x_packets"dev $swp1 egress"10110100+check_err$?"Decapsulated packets did not go through switch"++log_test"ping: $info"++tcfilterdeldev$swp1egress+tcfilterdeldev$rp1egress+}++ping_ipv4()+{+RET=0++locallocal_sw_ip=2001:db8:3::1+localremote_ns1_ip=2001:db8:4::1+localremote_ns2_ip=2001:db8:5::1+localh1_10_ip=192.0.2.1+localh1_20_ip=198.51.100.1+localw2_10_ns1_ip=192.0.2.3+localw2_10_ns2_ip=192.0.2.4+localw2_20_ns1_ip=198.51.100.3+localw2_20_ns2_ip=198.51.100.4++ping_test$h1.10192.0.2.2": local->local vid 10"+ping_test$h1.20198.51.100.2": local->local vid 20"++__ping_ipv4$local_sw_ip$remote_ns1_ip$h1_10_ip$w2_10_ns1_ip$h1.10\+"local->remote 1 vid 10"+__ping_ipv4$local_sw_ip$remote_ns2_ip$h1_10_ip$w2_10_ns2_ip$h1.10\+"local->remote 2 vid 10"+__ping_ipv4$local_sw_ip$remote_ns1_ip$h1_20_ip$w2_20_ns1_ip$h1.20\+"local->remote 1 vid 20"+__ping_ipv4$local_sw_ip$remote_ns2_ip$h1_20_ip$w2_20_ns2_ip$h1.20\+"local->remote 2 vid 20"+}++__ping_ipv6()+{+localvxlan_local_ip=$1;shift+localvxlan_remote_ip=$1;shift+localsrc_ip=$1;shift+localdst_ip=$1;shift+localdev=$1;shift+localinfo=$1;shift++RET=0++tcfilteradddev$rp1egressprotocolipv6pref1handle101\+flowerip_protoudpsrc_ip$vxlan_local_ip\+dst_ip$vxlan_remote_ipdst_port$VXPORT$TC_FLAGactionpass+# Match ICMP-reply packets after decapsulation, so source IP is+# destination IP of the ping and destination IP is source IP of the+# ping.+tcfilteradddev$swp1egressprotocol802.1qpref1handle101\+flowervlan_ethtypeipv6src_ip$dst_ipdst_ip$src_ip\+$TC_FLAGactionpass++# Send 100 packets and verify that at least 100 packets hit the rule,+# to overcome neighbor discovery noise.+PING_COUNT=100PING_TIMEOUT=11ping6_do$dev$dst_ip+check_err$?"Ping failed"++tc_check_at_least_x_packets"dev $rp1 egress"101100+check_err$?"Encapsulated packets did not go through router"++tc_check_at_least_x_packets"dev $swp1 egress"101100+check_err$?"Decapsulated packets did not go through switch"++log_test"ping6: $info"++tcfilterdeldev$swp1egress+tcfilterdeldev$rp1egress+}++ping_ipv6()+{+RET=0++locallocal_sw_ip=2001:db8:3::1+localremote_ns1_ip=2001:db8:4::1+localremote_ns2_ip=2001:db8:5::1+localh1_10_ip=2001:db8:1::1+localh1_20_ip=2001:db8:2::1+localw2_10_ns1_ip=2001:db8:1::3+localw2_10_ns2_ip=2001:db8:1::4+localw2_20_ns1_ip=2001:db8:2::3+localw2_20_ns2_ip=2001:db8:2::4++ping6_test$h1.102001:db8:1::2": local->local vid 10"+ping6_test$h1.202001:db8:2::2": local->local vid 20"++__ping_ipv6$local_sw_ip$remote_ns1_ip$h1_10_ip$w2_10_ns1_ip$h1.10\+"local->remote 1 vid 10"+__ping_ipv6$local_sw_ip$remote_ns2_ip$h1_10_ip$w2_10_ns2_ip$h1.10\+"local->remote 2 vid 10"+__ping_ipv6$local_sw_ip$remote_ns1_ip$h1_20_ip$w2_20_ns1_ip$h1.20\+"local->remote 1 vid 20"+__ping_ipv6$local_sw_ip$remote_ns2_ip$h1_20_ip$w2_20_ns2_ip$h1.20\+"local->remote 2 vid 20"+}++maybe_in_ns()+{+echo${1:+in_ns}$1+}++__flood_counter_add_del()+{+localadd_del=$1;shift+localdst_ip=$1;shift+localdev=$1;shift+localns=$1;shift++# Putting the ICMP capture both to HW and to SW will end up+# double-counting the packets that are trapped to slow path, such as for+# the unicast test. Adding either skip_hw or skip_sw fixes this problem,+# but with skip_hw, the flooded packets are not counted at all, because+# those are dropped due to MAC address mismatch; and skip_sw is a no-go+# for veth-based topologies.+#+# So try to install with skip_sw and fall back to skip_sw if that fails.++$(maybe_in_ns$ns)tcfilter$add_deldev"$dev"ingress\+protoipv6pref100flowerdst_ip$dst_ipip_proto\+icmpv6skip_swactionpass2>/dev/null||\+$(maybe_in_ns$ns)tcfilter$add_deldev"$dev"ingress\+protoipv6pref100flowerdst_ip$dst_ipip_proto\+icmpv6skip_hwactionpass+}++flood_counter_install()+{+__flood_counter_add_deladd"$@"+}++flood_counter_uninstall()+{+__flood_counter_add_deldel"$@"+}++flood_fetch_stat()+{+localdev=$1;shift+localns=$1;shift++$(maybe_in_ns$ns)tc_rule_stats_get$dev100ingress+}++flood_fetch_stats()+{+localcounters=("${@}")+localcounter++forcounterin"${counters[@]}";do+flood_fetch_stat$counter+done+}++vxlan_flood_test()+{+localmac=$1;shift+localdst=$1;shift+localvid=$1;shift+local-aexpects=("${@}")++local-acounters=($h2"vx10 ns1""vx20 ns1""vx10 ns2""vx20 ns2")+localcounter+localkey++# Packets reach the local host tagged whereas they reach the VxLAN+# devices untagged. In order to be able to use the same filter for+# all counters, make sure the packets also reach the local host+# untagged+bridgevlanaddvid$viddev$swp2untagged+forcounterin"${counters[@]}";do+flood_counter_install$dst$counter+done++local-at0s=($(flood_fetch_stats"${counters[@]}"))+$MZ-6$h1-Q$vid-c10-d100msec-p64-b$mac-B$dst-ticmp6type=128-q+sleep1+local-at1s=($(flood_fetch_stats"${counters[@]}"))++forkeyin${!t0s[@]};do+localdelta=$((t1s[$key]-t0s[$key]))+localexpect=${expects[$key]}++((expect==delta))+check_err$?"${counters[$key]}: Expected to capture $expect packets, got $delta."+done++forcounterin"${counters[@]}";do+flood_counter_uninstall$dst$counter+done+bridgevlanaddvid$viddev$swp2+}++__test_flood()+{+localmac=$1;shift+localdst=$1;shift+localvid=$1;shift+localwhat=$1;shift+local-aexpects=("${@}")++RET=0++vxlan_flood_test$mac$dst$vid"${expects[@]}"++log_test"VXLAN: $what"+}++test_flood()+{+__test_floodde:ad:be:ef:13:372001:db8:1::10010"flood vlan 10"\+10100100+__test_floodca:fe:be:ef:13:372001:db8:2::10020"flood vlan 20"\+10010010+}++vxlan_fdb_add_del()+{+localadd_del=$1;shift+localvid=$1;shift+localmac=$1;shift+localdev=$1;shift+localdst=$1;shift++bridgefdb$add_deldev$dev$macselfstaticpermanent\+${dst:+dst}$dst2>/dev/null+bridgefdb$add_deldev$dev$macmasterstaticvlan$vid2>/dev/null+}++__test_unicast()+{+localmac=$1;shift+localdst=$1;shift+localhit_idx=$1;shift+localvid=$1;shift+localwhat=$1;shift++RET=0++local-aexpects=(00000)+expects[$hit_idx]=10++vxlan_flood_test$mac$dst$vid"${expects[@]}"++log_test"VXLAN: $what"+}++test_unicast()+{+local-atargets=("$h2_mac$h2"+"$r1_mac vx10 2001:db8:4::1"+"$r2_mac vx10 2001:db8:5::1")+localtarget++log_info"unicast vlan 10"++fortargetin"${targets[@]}";do+vxlan_fdb_add_deladd10$target+done++__test_unicast$h2_mac2001:db8:1::2010"local MAC unicast"+__test_unicast$r1_mac2001:db8:1::3110"remote MAC 1 unicast"+__test_unicast$r2_mac2001:db8:1::4310"remote MAC 2 unicast"++fortargetin"${targets[@]}";do+vxlan_fdb_add_deldel10$target+done++log_info"unicast vlan 20"++targets=("$h2_mac$h2""$r1_mac vx20 2001:db8:4::1"\+"$r2_mac vx20 2001:db8:5::1")++fortargetin"${targets[@]}";do+vxlan_fdb_add_deladd20$target+done++__test_unicast$h2_mac2001:db8:2::2020"local MAC unicast"+__test_unicast$r1_mac2001:db8:2::3220"remote MAC 1 unicast"+__test_unicast$r2_mac2001:db8:2::4420"remote MAC 2 unicast"++fortargetin"${targets[@]}";do+vxlan_fdb_add_deldel20$target+done+}++test_pvid()+{+local-aexpects=(00000)+localmac=de:ad:be:ef:13:37+localdst=2001:db8:1::100+localvid=10++# Check that flooding works+RET=0++expects[0]=10;expects[1]=10;expects[3]=10+vxlan_flood_test$mac$dst$vid"${expects[@]}"++log_test"VXLAN: flood before pvid off"++# Toggle PVID off and test that flood to remote hosts does not work+RET=0++bridgevlanaddvid10devvx10++expects[0]=10;expects[1]=0;expects[3]=0+vxlan_flood_test$mac$dst$vid"${expects[@]}"++log_test"VXLAN: flood after pvid off"++# Toggle PVID on and test that flood to remote hosts does work+RET=0++bridgevlanaddvid10devvx10pviduntagged++expects[0]=10;expects[1]=10;expects[3]=10+vxlan_flood_test$mac$dst$vid"${expects[@]}"++log_test"VXLAN: flood after pvid on"++# Add a new VLAN and test that it does not affect flooding+RET=0++bridgevlanaddvid30devvx10++expects[0]=10;expects[1]=10;expects[3]=10+vxlan_flood_test$mac$dst$vid"${expects[@]}"++bridgevlandelvid30devvx10++log_test"VXLAN: flood after vlan add"++# Remove currently mapped VLAN and test that flood to remote hosts does+# not work+RET=0++bridgevlandelvid10devvx10++expects[0]=10;expects[1]=0;expects[3]=0+vxlan_flood_test$mac$dst$vid"${expects[@]}"++log_test"VXLAN: flood after vlan delete"++# Re-add the VLAN and test that flood to remote hosts does work+RET=0++bridgevlanaddvid10devvx10pviduntagged++expects[0]=10;expects[1]=10;expects[3]=10+vxlan_flood_test$mac$dst$vid"${expects[@]}"++log_test"VXLAN: flood after vlan re-add"+}++test_all()+{+log_info"Running tests with UDP port $VXPORT"+tests_run+}++trapcleanupEXIT++setup_prepare+setup_wait+test_all++exit$EXIT_STATUS
@@ -0,0 +1,11 @@+#!/bin/bash+# SPDX-License-Identifier: GPL-2.0++# A wrapper to run VXLAN tests with an unusual port number.++VXPORT=8472+ALL_TESTS="+ping_ipv4+ping_ipv6+"+sourcevxlan_bridge_1q_ipv6.sh
From: Amit Cohen <hidden> Date: 2021-12-21 14:51:38
Remove `vxlan_ping_test()` which is not used and probably was copied
mistakenly from vxlan_bridge_1d.sh.
This was found while adding an equivalent test for IPv6.
Signed-off-by: Amit Cohen <redacted>
Reviewed-by: Petr Machata <petrm@nvidia.com>
---
.../net/forwarding/vxlan_bridge_1q.sh | 20 -------------------
1 file changed, 20 deletions(-)
From: Amit Cohen <hidden> Date: 2021-12-21 14:51:40
In asymmetric routing the ingress VTEP routes the packet into the
correct VxLAN tunnel, whereas the egress VTEP only bridges the packet to
the correct host. Therefore, packets in different directions use
different VNIs - the target VNI.
Add a test which is similar to the existing IPv4 test to check IPv6.
The test uses a simple topology with two VTEPs and two VNIs and verifies
that ping passes between hosts (local / remote) in the same VLAN (VNI)
and in different VLANs belonging to the same tenant (VRF).
While the test does not check VM mobility, it does configure an anycast
gateway using a macvlan device on both VTEPs.
Signed-off-by: Amit Cohen <redacted>
Reviewed-by: Petr Machata <petrm@nvidia.com>
---
.../net/forwarding/vxlan_asymmetric_ipv6.sh | 504 ++++++++++++++++++
1 file changed, 504 insertions(+)
create mode 100755 tools/testing/selftests/net/forwarding/vxlan_asymmetric_ipv6.sh
From: Amit Cohen <hidden> Date: 2021-12-21 14:51:43
In a similar fashion to the asymmetric test, add a test for symmetric
routing. In symmetric routing both the ingress and egress VTEPs perform
routing in the overlay network into / from the VxLAN tunnel. Packets in
different directions use the same VNI - the L3 VNI.
Different tenants (VRFs) use different L3 VNIs.
Add a test which is similar to the existing IPv4 test to check IPv6.
Signed-off-by: Amit Cohen <redacted>
Reviewed-by: Petr Machata <petrm@nvidia.com>
---
.../net/forwarding/vxlan_symmetric_ipv6.sh | 563 ++++++++++++++++++
1 file changed, 563 insertions(+)
create mode 100755 tools/testing/selftests/net/forwarding/vxlan_symmetric_ipv6.sh
From: Amit Cohen <hidden> Date: 2021-12-21 14:53:06
Add test to check Q-in-VNI traffic with IPv6 underlay and overlay.
The test is similar to the existing IPv4 test.
Signed-off-by: Amit Cohen <redacted>
Reviewed-by: Petr Machata <petrm@nvidia.com>
---
.../selftests/net/forwarding/q_in_vni_ipv6.sh | 347 ++++++++++++++++++
1 file changed, 347 insertions(+)
create mode 100755 tools/testing/selftests/net/forwarding/q_in_vni_ipv6.sh
Hello:
This series was applied to netdev/net-next.git (master)
by Jakub Kicinski [off-list ref]:
On Tue, 21 Dec 2021 16:49:41 +0200 you wrote:
mlxsw driver lately added support for VxLAN with IPv6 underlay.
This set adds the relevant tests for IPv6, most of them are same to
IPv4 tests with the required changes.
Patch set overview:
Patch #1 relaxes requirements for offloading TC filters that
match on 802.1q fields. The following selftests make use of these
newly-relaxed filters.
Patch #2 adds preparation as part of selftests API, which will be used
later.
Patches #3-#4 add tests for VxLAN with bridge aware and unaware.
Patche #5 cleans unused function.
Patches #6-#7 add tests for VxLAN symmetric and asymmetric.
Patch #8 adds test for Q-in-VNI.
[...]