mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 00:53:34 +02:00
selftests: forwarding: Add test for BR_BOOLOPT_FDB_LOCAL_VLAN_0
Add a selftest to check the operation of this newly-introduced bridge option. Signed-off-by: Petr Machata <petrm@nvidia.com> Acked-by: Nikolay Aleksandrov <razor@blackwall.org> Link: https://patch.msgid.link/62294f96884ab5d341648eef21243fa099a2dee5.1757004393.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
fa57032941
commit
dbd9134792
|
|
@ -5,6 +5,7 @@ TEST_PROGS = \
|
|||
bridge_fdb_learning_limit.sh \
|
||||
bridge_igmp.sh \
|
||||
bridge_locked_port.sh \
|
||||
bridge_fdb_local_vlan_0.sh \
|
||||
bridge_mdb.sh \
|
||||
bridge_mdb_host.sh \
|
||||
bridge_mdb_max.sh \
|
||||
|
|
|
|||
374
tools/testing/selftests/net/forwarding/bridge_fdb_local_vlan_0.sh
Executable file
374
tools/testing/selftests/net/forwarding/bridge_fdb_local_vlan_0.sh
Executable file
|
|
@ -0,0 +1,374 @@
|
|||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
# +-----------------------+ +-----------------------+ +-----------------------+
|
||||
# | H1 (vrf) | | H2 (vrf) | | H3 (vrf) |
|
||||
# | + $h1 | | + $h2 | | + $h3 |
|
||||
# | | 192.0.2.1/28 | | | 192.0.2.2/28 | | | 192.0.2.18/28 |
|
||||
# | | 2001:db8:1::1/64 | | | 2001:db8:1::2/64 | | | 2001:db8:2::2/64 |
|
||||
# | | | | | | | | |
|
||||
# +----|------------------+ +----|------------------+ +----|------------------+
|
||||
# | | |
|
||||
# +----|-------------------------|-------------------------|------------------+
|
||||
# | +--|-------------------------|------------------+ | |
|
||||
# | | + $swp1 + $swp2 | + $swp3 |
|
||||
# | | | 192.0.2.17/28 |
|
||||
# | | BR1 (802.1q) | 2001:db8:2::1/64 |
|
||||
# | | 192.0.2.3/28 | |
|
||||
# | | 2001:db8:1::3/64 | |
|
||||
# | +-----------------------------------------------+ SW |
|
||||
# +---------------------------------------------------------------------------+
|
||||
#
|
||||
#shellcheck disable=SC2317 # SC doesn't see our uses of functions.
|
||||
#shellcheck disable=SC2034 # ... and global variables
|
||||
|
||||
ALL_TESTS="
|
||||
test_d_no_sharing
|
||||
test_d_sharing
|
||||
test_q_no_sharing
|
||||
test_q_sharing
|
||||
"
|
||||
|
||||
NUM_NETIFS=6
|
||||
source lib.sh
|
||||
|
||||
pMAC=00:11:22:33:44:55
|
||||
bMAC=00:11:22:33:44:66
|
||||
mMAC=00:11:22:33:44:77
|
||||
xMAC=00:11:22:33:44:88
|
||||
|
||||
host_create()
|
||||
{
|
||||
local h=$1; shift
|
||||
local ipv4=$1; shift
|
||||
local ipv6=$1; shift
|
||||
|
||||
simple_if_init "$h" "$ipv4" "$ipv6"
|
||||
defer simple_if_fini "$h" "$ipv4" "$ipv6"
|
||||
|
||||
ip_route_add vrf "v$h" 192.0.2.16/28 nexthop via 192.0.2.3
|
||||
ip_route_add vrf "v$h" 2001:db8:2::/64 nexthop via 2001:db8:1::3
|
||||
}
|
||||
|
||||
h3_create()
|
||||
{
|
||||
simple_if_init "$h3" 192.0.2.18/28 2001:db8:2::2/64
|
||||
defer simple_if_fini "$h3" 192.0.2.18/28 2001:db8:2::2/64
|
||||
|
||||
ip_route_add vrf "v$h3" 192.0.2.0/28 nexthop via 192.0.2.17
|
||||
ip_route_add vrf "v$h3" 2001:db8:1::/64 nexthop via 2001:db8:2::1
|
||||
|
||||
tc qdisc add dev "$h3" clsact
|
||||
defer tc qdisc del dev "$h3" clsact
|
||||
|
||||
tc filter add dev "$h3" ingress proto ip pref 104 \
|
||||
flower skip_hw ip_proto udp dst_port 4096 \
|
||||
action pass
|
||||
defer tc filter del dev "$h3" ingress proto ip pref 104
|
||||
|
||||
tc qdisc add dev "$h2" clsact
|
||||
defer tc qdisc del dev "$h2" clsact
|
||||
|
||||
tc filter add dev "$h2" ingress proto ip pref 104 \
|
||||
flower skip_hw ip_proto udp dst_port 4096 \
|
||||
action pass
|
||||
defer tc filter del dev "$h2" ingress proto ip pref 104
|
||||
}
|
||||
|
||||
switch_create()
|
||||
{
|
||||
ip_link_set_up "$swp1"
|
||||
|
||||
ip_link_set_up "$swp2"
|
||||
|
||||
ip_addr_add "$swp3" 192.0.2.17/28
|
||||
ip_addr_add "$swp3" 2001:db8:2::1/64
|
||||
ip_link_set_up "$swp3"
|
||||
}
|
||||
|
||||
setup_prepare()
|
||||
{
|
||||
h1=${NETIFS[p1]}
|
||||
swp1=${NETIFS[p2]}
|
||||
|
||||
swp2=${NETIFS[p3]}
|
||||
h2=${NETIFS[p4]}
|
||||
|
||||
swp3=${NETIFS[p5]}
|
||||
h3=${NETIFS[p6]}
|
||||
|
||||
vrf_prepare
|
||||
defer vrf_cleanup
|
||||
|
||||
forwarding_enable
|
||||
defer forwarding_restore
|
||||
|
||||
host_create "$h1" 192.0.2.1/28 2001:db8:1::1/64
|
||||
host_create "$h2" 192.0.2.2/28 2001:db8:1::2/64
|
||||
h3_create
|
||||
|
||||
switch_create
|
||||
}
|
||||
|
||||
adf_bridge_create()
|
||||
{
|
||||
local dev
|
||||
local mac
|
||||
|
||||
ip_link_add br up type bridge vlan_default_pvid 0 "$@"
|
||||
mac=$(mac_get br)
|
||||
ip_addr_add br 192.0.2.3/28
|
||||
ip_addr_add br 2001:db8:1::3/64
|
||||
|
||||
bridge_vlan_add dev br vid 1 pvid untagged self
|
||||
bridge_vlan_add dev br vid 2 self
|
||||
bridge_vlan_add dev br vid 3 self
|
||||
|
||||
for dev in "$swp1" "$swp2"; do
|
||||
ip_link_set_master "$dev" br
|
||||
bridge_vlan_add dev "$dev" vid 1 pvid untagged
|
||||
bridge_vlan_add dev "$dev" vid 2
|
||||
bridge_vlan_add dev "$dev" vid 3
|
||||
done
|
||||
|
||||
ip_link_set_addr br "$mac"
|
||||
}
|
||||
|
||||
check_fdb_local_vlan_0_support()
|
||||
{
|
||||
if ip_link_add XXbr up type bridge vlan_filtering 1 fdb_local_vlan_0 1 \
|
||||
&>/dev/null; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
log_test_skip "FDB sharing" \
|
||||
"iproute 2 or the kernel do not support fdb_local_vlan_0"
|
||||
}
|
||||
|
||||
check_mac_presence()
|
||||
{
|
||||
local should_fail=$1; shift
|
||||
local dev=$1; shift
|
||||
local vlan=$1; shift
|
||||
local mac
|
||||
|
||||
mac=$(mac_get "$dev")
|
||||
|
||||
if ((vlan == 0)); then
|
||||
vlan=null
|
||||
fi
|
||||
|
||||
bridge -j fdb show dev "$dev" |
|
||||
jq -e --arg mac "$mac" --argjson vlan "$vlan" \
|
||||
'.[] | select(.mac == $mac) | select(.vlan == $vlan)' > /dev/null
|
||||
check_err_fail "$should_fail" $? "FDB dev $dev vid $vlan addr $mac exists"
|
||||
}
|
||||
|
||||
do_sharing_test()
|
||||
{
|
||||
local should_fail=$1; shift
|
||||
local what=$1; shift
|
||||
local dev
|
||||
|
||||
RET=0
|
||||
|
||||
for dev in "$swp1" "$swp2" br; do
|
||||
check_mac_presence 0 "$dev" 0
|
||||
check_mac_presence "$should_fail" "$dev" 1
|
||||
check_mac_presence "$should_fail" "$dev" 2
|
||||
check_mac_presence "$should_fail" "$dev" 3
|
||||
done
|
||||
|
||||
log_test "$what"
|
||||
}
|
||||
|
||||
do_end_to_end_test()
|
||||
{
|
||||
local mac=$1; shift
|
||||
local what=$1; shift
|
||||
local probe_dev=${1-$h3}; shift
|
||||
local expect=${1-10}; shift
|
||||
|
||||
local t0
|
||||
local t1
|
||||
local dd
|
||||
|
||||
RET=0
|
||||
|
||||
# In mausezahn, use $dev MAC as the destination MAC. In the MAC sharing
|
||||
# context, that will cause an FDB miss on VLAN 1 and prompt a second
|
||||
# lookup in VLAN 0.
|
||||
|
||||
t0=$(tc_rule_stats_get "$probe_dev" 104 ingress)
|
||||
|
||||
$MZ "$h1" -c 10 -p 64 -a own -b "$mac" \
|
||||
-A 192.0.2.1 -B 192.0.2.18 -t udp "dp=4096,sp=2048" -q
|
||||
sleep 1
|
||||
|
||||
t1=$(tc_rule_stats_get "$probe_dev" 104 ingress)
|
||||
dd=$((t1 - t0))
|
||||
|
||||
((dd == expect))
|
||||
check_err $? "Expected $expect packets on $probe_dev got $dd"
|
||||
|
||||
log_test "$what"
|
||||
}
|
||||
|
||||
do_tests()
|
||||
{
|
||||
local should_fail=$1; shift
|
||||
local what=$1; shift
|
||||
local swp1_mac
|
||||
local br_mac
|
||||
|
||||
swp1_mac=$(mac_get "$swp1")
|
||||
br_mac=$(mac_get br)
|
||||
|
||||
do_sharing_test "$should_fail" "$what"
|
||||
do_end_to_end_test "$swp1_mac" "$what: end to end, $swp1 MAC"
|
||||
do_end_to_end_test "$br_mac" "$what: end to end, br MAC"
|
||||
}
|
||||
|
||||
bridge_standard()
|
||||
{
|
||||
local vlan_filtering=$1; shift
|
||||
|
||||
if ((vlan_filtering)); then
|
||||
echo 802.1q
|
||||
else
|
||||
echo 802.1d
|
||||
fi
|
||||
}
|
||||
|
||||
nonexistent_fdb_test()
|
||||
{
|
||||
local vlan_filtering=$1; shift
|
||||
local standard
|
||||
|
||||
standard=$(bridge_standard "$vlan_filtering")
|
||||
|
||||
# We expect flooding, so $h2 should get the traffic.
|
||||
do_end_to_end_test "$xMAC" "$standard: Nonexistent FDB" "$h2"
|
||||
}
|
||||
|
||||
misleading_fdb_test()
|
||||
{
|
||||
local vlan_filtering=$1; shift
|
||||
local standard
|
||||
|
||||
standard=$(bridge_standard "$vlan_filtering")
|
||||
|
||||
defer_scope_push
|
||||
# Add an FDB entry on VLAN 0. The lookup on VLAN-aware bridge
|
||||
# shouldn't pick this up even with fdb_local_vlan_0 enabled, so
|
||||
# the traffic should be flooded. This all holds on
|
||||
# vlan_filtering bridge, on non-vlan_filtering one the FDB entry
|
||||
# is expected to be found as usual, no flooding takes place.
|
||||
#
|
||||
# Adding only on VLAN 0 is a bit tricky, because bridge is
|
||||
# trying to be nice and interprets the request as if the FDB
|
||||
# should be added on each VLAN.
|
||||
|
||||
bridge fdb add "$mMAC" dev "$swp1" master
|
||||
bridge fdb del "$mMAC" dev "$swp1" vlan 1 master
|
||||
bridge fdb del "$mMAC" dev "$swp1" vlan 2 master
|
||||
bridge fdb del "$mMAC" dev "$swp1" vlan 3 master
|
||||
|
||||
local expect=$((vlan_filtering ? 10 : 0))
|
||||
do_end_to_end_test "$mMAC" \
|
||||
"$standard: Lookup of non-local MAC on VLAN 0" \
|
||||
"$h2" "$expect"
|
||||
defer_scope_pop
|
||||
}
|
||||
|
||||
change_mac()
|
||||
{
|
||||
local dev=$1; shift
|
||||
local mac=$1; shift
|
||||
local cur_mac
|
||||
|
||||
cur_mac=$(mac_get "$dev")
|
||||
|
||||
log_info "Change $dev MAC $cur_mac -> $mac"
|
||||
ip_link_set_addr "$dev" "$mac"
|
||||
defer log_info "Change $dev MAC back"
|
||||
}
|
||||
|
||||
do_test_no_sharing()
|
||||
{
|
||||
local vlan_filtering=$1; shift
|
||||
local standard
|
||||
|
||||
standard=$(bridge_standard "$vlan_filtering")
|
||||
|
||||
adf_bridge_create vlan_filtering "$vlan_filtering"
|
||||
setup_wait
|
||||
|
||||
do_tests 0 "$standard, no FDB sharing"
|
||||
|
||||
change_mac "$swp1" "$pMAC"
|
||||
change_mac br "$bMAC"
|
||||
|
||||
do_tests 0 "$standard, no FDB sharing after MAC change"
|
||||
|
||||
in_defer_scope check_fdb_local_vlan_0_support || return
|
||||
|
||||
log_info "Set fdb_local_vlan_0=1"
|
||||
ip link set dev br type bridge fdb_local_vlan_0 1
|
||||
|
||||
do_tests 1 "$standard, fdb sharing after toggle"
|
||||
}
|
||||
|
||||
do_test_sharing()
|
||||
{
|
||||
local vlan_filtering=$1; shift
|
||||
local standard
|
||||
|
||||
standard=$(bridge_standard "$vlan_filtering")
|
||||
|
||||
in_defer_scope check_fdb_local_vlan_0_support || return
|
||||
|
||||
adf_bridge_create vlan_filtering "$vlan_filtering" fdb_local_vlan_0 1
|
||||
setup_wait
|
||||
|
||||
do_tests 1 "$standard, FDB sharing"
|
||||
|
||||
nonexistent_fdb_test "$vlan_filtering"
|
||||
misleading_fdb_test "$vlan_filtering"
|
||||
|
||||
change_mac "$swp1" "$pMAC"
|
||||
change_mac br "$bMAC"
|
||||
|
||||
do_tests 1 "$standard, FDB sharing after MAC change"
|
||||
|
||||
log_info "Set fdb_local_vlan_0=0"
|
||||
ip link set dev br type bridge fdb_local_vlan_0 0
|
||||
|
||||
do_tests 0 "$standard, No FDB sharing after toggle"
|
||||
}
|
||||
|
||||
test_d_no_sharing()
|
||||
{
|
||||
do_test_no_sharing 0
|
||||
}
|
||||
|
||||
test_d_sharing()
|
||||
{
|
||||
do_test_sharing 0
|
||||
}
|
||||
|
||||
test_q_no_sharing()
|
||||
{
|
||||
do_test_no_sharing 1
|
||||
}
|
||||
|
||||
test_q_sharing()
|
||||
{
|
||||
do_test_sharing 1
|
||||
}
|
||||
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
setup_prepare
|
||||
tests_run
|
||||
Loading…
Reference in New Issue
Block a user