On Mon, Apr 11, 2022 at 03:38:31PM +0200, Joachim Wiberg wrote: > 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 I think the picture is slightly inaccurate. From it I understand that h1 and h2 are bridge ports, but they are stations attached to the real bridge ports, swp1 and swp2. Maybe it would be good to draw all interfaces. > +# > +# 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 stray debug line > + > +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" HELO to you too > +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" Exporting should be required only for sub-shells, doesn't apply when you source a script. > + > +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) Maybe you could populate the "ports" and the "flagN" arrays in the same order, i.e. bridge first for all? Also, to be honest, a generic name like "ports" is hard to digest, especially since you have another generic variable name "iface". Maybe "brports" and "station" is a little bit more specific? > +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 ) If it's not too much, maybe these could be called "flags_pass1", etc. Again, it was a bit hard to digest on first read. > + > +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 I find it slightly less confusing if "flag" and "flags" are next to each other in the parameter list, since they're related. > + > + 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 Do something about the commented lines. > + tcpdump_show $iface |grep -q "$SRC_MAC" Space between pipe and grep. > + rc=$? > + > + check_err_fail "${flags[$port]} = on" $? "failed flooding from $h1 to port $port" I think the "failed" word here is superfluous, since check_err_fail already says "$what succeeded, but should have failed". > + 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 >