Test per-port flood control flags of unknown BUM traffic by injecting bc/uc/mc on one bridge port and verifying it being forwarded to both the bridge itself and another regular bridge port. Signed-off-by: Joachim Wiberg <troglobit@xxxxxxxxx> --- .../testing/selftests/net/forwarding/Makefile | 3 +- .../selftests/net/forwarding/bridge_flood.sh | 170 ++++++++++++++++++ 2 files changed, 172 insertions(+), 1 deletion(-) create mode 100755 tools/testing/selftests/net/forwarding/bridge_flood.sh diff --git a/tools/testing/selftests/net/forwarding/Makefile b/tools/testing/selftests/net/forwarding/Makefile index ae80c2aef577..873fa61d1ee1 100644 --- a/tools/testing/selftests/net/forwarding/Makefile +++ b/tools/testing/selftests/net/forwarding/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0+ OR MIT -TEST_PROGS = bridge_igmp.sh \ +TEST_PROGS = bridge_flood.sh \ + bridge_igmp.sh \ bridge_locked_port.sh \ bridge_mdb.sh \ bridge_port_isolation.sh \ diff --git a/tools/testing/selftests/net/forwarding/bridge_flood.sh b/tools/testing/selftests/net/forwarding/bridge_flood.sh new file mode 100755 index 000000000000..1966c960d705 --- /dev/null +++ b/tools/testing/selftests/net/forwarding/bridge_flood.sh @@ -0,0 +1,170 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Verify per-port flood control flags of unknown BUM traffic. +# +# br0 +# / \ +# h1 h2 +# +# We inject bc/uc/mc on h1, toggle the three flood flags for +# both br0 and h2, then verify that traffic is flooded as per +# the flags, and nowhere else. +# +#set -x + +ALL_TESTS="br_flood_unknown_bc_test br_flood_unknown_uc_test br_flood_unknown_mc_test" +NUM_NETIFS=4 + +SRC_MAC="00:de:ad:be:ef:00" +GRP_IP4="225.1.2.3" +GRP_MAC="01:00:01:c0:ff:ee" +GRP_IP6="ff02::42" + +BC_PKT="ff:ff:ff:ff:ff:ff $SRC_MAC 00:04 48:45:4c:4f" +UC_PKT="02:00:01:c0:ff:ee $SRC_MAC 00:04 48:45:4c:4f" +MC_PKT="01:00:5e:01:02:03 $SRC_MAC 08:00 45:00 00:20 c2:10 00:00 ff 11 12:b2 01:02:03:04 e1:01:02:03 04:d2 10:e1 00:0c 6e:84 48:45:4c:4f" + +# Disable promisc to ensure we only receive flooded frames +export TCPDUMP_EXTRA_FLAGS="-pl" + +source lib.sh + +h1=${NETIFS[p1]} +h2=${NETIFS[p3]} +swp1=${NETIFS[p2]} +swp2=${NETIFS[p4]} + +# +# Port mappings and flood flag pattern to set/detect +# +declare -A ports=([br0]=br0 [$swp1]=$h1 [$swp2]=$h2) +declare -A flag1=([$swp1]=off [$swp2]=off [br0]=off) +declare -A flag2=([$swp1]=off [$swp2]=on [br0]=off) +declare -A flag3=([$swp1]=off [$swp2]=on [br0]=on ) +declare -A flag4=([$swp1]=off [$swp2]=off [br0]=on ) + +switch_create() +{ + ip link add dev br0 type bridge + + for port in ${!ports[@]}; do + [ "$port" != "br0" ] && ip link set dev $port master br0 + ip link set dev $port up + done +} + +switch_destroy() +{ + for port in ${!ports[@]}; do + ip link set dev $port down + done + ip link del dev br0 +} + +setup_prepare() +{ + vrf_prepare + + let i=1 + for iface in ${ports[@]}; do + [ "$iface" = "br0" ] && continue + simple_if_init $iface 192.0.2.$i/24 2001:db8:1::$i/64 + let i=$((i + 1)) + done + + switch_create +} + +cleanup() +{ + pre_cleanup + switch_destroy + + let i=1 + for iface in ${ports[@]}; do + [ "$iface" = "br0" ] && continue + simple_if_fini $iface 192.0.2.$i/24 2001:db8:1::$i/64 + let i=$((i + 1)) + done + + vrf_cleanup +} + +do_flood_unknown() +{ + local type=$1 + local pass=$2 + local flag=$3 + local pkt=$4 + local -n flags=$5 + + RET=0 + for port in ${!ports[@]}; do + if [ "$port" = "br0" ]; then + self="self" + else + self="" + fi + bridge link set dev $port $flag ${flags[$port]} $self + check_err $? "Failed setting $port $flag ${flags[$port]}" + done + + for iface in ${ports[@]}; do + tcpdump_start $iface + done + + $MZ -q $h1 "$pkt" + sleep 1 + + for iface in ${ports[@]}; do + tcpdump_stop $iface + done + + for port in ${!ports[@]}; do + iface=${ports[$port]} + +# echo "Dumping PCAP from $iface, expecting ${flags[$port]}:" +# tcpdump_show $iface + tcpdump_show $iface |grep -q "$SRC_MAC" + rc=$? + + check_err_fail "${flags[$port]} = on" $? "failed flooding from $h1 to port $port" + check_err_fail "${flags[$port]} = off" $? "flooding from $h1 to port $port" + done + + log_test "flood unknown $type pass $pass/4" +} + +br_flood_unknown_bc_test() +{ + do_flood_unknown BC 1 bcast_flood "$BC_PKT" flag1 + do_flood_unknown BC 2 bcast_flood "$BC_PKT" flag2 + do_flood_unknown BC 3 bcast_flood "$BC_PKT" flag3 + do_flood_unknown BC 4 bcast_flood "$BC_PKT" flag4 +} + +br_flood_unknown_uc_test() +{ + do_flood_unknown UC 1 flood "$UC_PKT" flag1 + do_flood_unknown UC 2 flood "$UC_PKT" flag2 + do_flood_unknown UC 3 flood "$UC_PKT" flag3 + do_flood_unknown UC 4 flood "$UC_PKT" flag4 +} + +br_flood_unknown_mc_test() +{ + do_flood_unknown MC 1 mcast_flood "$MC_PKT" flag1 + do_flood_unknown MC 2 mcast_flood "$MC_PKT" flag2 + do_flood_unknown MC 3 mcast_flood "$MC_PKT" flag3 + do_flood_unknown MC 4 mcast_flood "$MC_PKT" flag4 +} + +trap cleanup EXIT + +setup_prepare +setup_wait + +tests_run + +exit $EXIT_STATUS -- 2.25.1