]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
selftests: forwarding: Add a test for FDB activity notification control
authorIdo Schimmel <idosch@nvidia.com>
Tue, 12 Aug 2025 07:18:10 +0000 (10:18 +0300)
committerJakub Kicinski <kuba@kernel.org>
Thu, 14 Aug 2025 00:09:54 +0000 (17:09 -0700)
Test various aspects of FDB activity notification control:

* Transitioning of an FDB entry from inactive to active state.

* Transitioning of an FDB entry from active to inactive state.

* Avoiding the resetting of an FDB entry's last activity time (i.e.,
  "updated" time) using the "norefresh" keyword.

Reviewed-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/20250812071810.312346-1-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
tools/testing/selftests/net/forwarding/Makefile
tools/testing/selftests/net/forwarding/bridge_activity_notify.sh [new file with mode: 0755]

index d7bb2e80e88c294e85232ca849ee2472341cfcb1..0a0d4c2a85f74198dc6dd5f668cf5bc7626f057f 100644 (file)
@@ -1,6 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0+ OR MIT
 
-TEST_PROGS = bridge_fdb_learning_limit.sh \
+TEST_PROGS = \
+       bridge_activity_notify.sh \
+       bridge_fdb_learning_limit.sh \
        bridge_igmp.sh \
        bridge_locked_port.sh \
        bridge_mdb.sh \
diff --git a/tools/testing/selftests/net/forwarding/bridge_activity_notify.sh b/tools/testing/selftests/net/forwarding/bridge_activity_notify.sh
new file mode 100755 (executable)
index 0000000..a20ef4b
--- /dev/null
@@ -0,0 +1,173 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+# +-----------------------+                          +------------------------+
+# | H1 (vrf)              |                          | H2 (vrf)               |
+# | 192.0.2.1/28          |                          | 192.0.2.2/28           |
+# |    + $h1              |                          |    + $h2               |
+# +----|------------------+                          +----|-------------------+
+#      |                                                  |
+# +----|--------------------------------------------------|-------------------+
+# | SW |                                                  |                   |
+# | +--|--------------------------------------------------|-----------------+ |
+# | |  + $swp1                   BR1 (802.1d)             + $swp2           | |
+# | |                                                                       | |
+# | +-----------------------------------------------------------------------+ |
+# +---------------------------------------------------------------------------+
+
+ALL_TESTS="
+       new_inactive_test
+       existing_active_test
+       norefresh_test
+"
+
+NUM_NETIFS=4
+source lib.sh
+
+h1_create()
+{
+       simple_if_init "$h1" 192.0.2.1/28
+       defer simple_if_fini "$h1" 192.0.2.1/28
+}
+
+h2_create()
+{
+       simple_if_init "$h2" 192.0.2.2/28
+       defer simple_if_fini "$h2" 192.0.2.2/28
+}
+
+switch_create()
+{
+       ip_link_add br1 type bridge vlan_filtering 0 mcast_snooping 0 \
+               ageing_time "$LOW_AGEING_TIME"
+       ip_link_set_up br1
+
+       ip_link_set_master "$swp1" br1
+       ip_link_set_up "$swp1"
+
+       ip_link_set_master "$swp2" br1
+       ip_link_set_up "$swp2"
+}
+
+setup_prepare()
+{
+       h1=${NETIFS[p1]}
+       swp1=${NETIFS[p2]}
+
+       swp2=${NETIFS[p3]}
+       h2=${NETIFS[p4]}
+
+       vrf_prepare
+       defer vrf_cleanup
+
+       h1_create
+       h2_create
+       switch_create
+}
+
+fdb_active_wait()
+{
+       local mac=$1; shift
+
+       bridge -d fdb get "$mac" br br1 | grep -q -v "inactive"
+}
+
+fdb_inactive_wait()
+{
+       local mac=$1; shift
+
+       bridge -d fdb get "$mac" br br1 | grep -q "inactive"
+}
+
+new_inactive_test()
+{
+       local mac="00:11:22:33:44:55"
+
+       # Add a new FDB entry as static and inactive and check that it
+       # becomes active upon traffic.
+       RET=0
+
+       bridge fdb add "$mac" dev "$swp1" master static activity_notify inactive
+       bridge -d fdb get "$mac" br br1 | grep -q "inactive"
+       check_err $? "FDB entry not present as \"inactive\" when should"
+
+       $MZ "$h1" -c 1 -p 64 -a "$mac" -b bcast -t ip -q
+
+       busywait "$BUSYWAIT_TIMEOUT" fdb_active_wait "$mac"
+       check_err $? "FDB entry present as \"inactive\" when should not"
+
+       log_test "Transition from inactive to active"
+
+       bridge fdb del "$mac" dev "$swp1" master
+}
+
+existing_active_test()
+{
+       local mac="00:11:22:33:44:55"
+       local ageing_time
+
+       # Enable activity notifications on an existing dynamic FDB entry and
+       # check that it becomes inactive after the ageing time passed.
+       RET=0
+
+       bridge fdb add "$mac" dev "$swp1" master dynamic
+       bridge fdb replace "$mac" dev "$swp1" master static activity_notify norefresh
+
+       bridge -d fdb get "$mac" br br1 | grep -q "activity_notify"
+       check_err $? "FDB entry not present as \"activity_notify\" when should"
+
+       bridge -d fdb get "$mac" br br1 | grep -q "inactive"
+       check_fail $? "FDB entry present as \"inactive\" when should not"
+
+       ageing_time=$(bridge_ageing_time_get br1)
+       slowwait $((ageing_time * 2)) fdb_inactive_wait "$mac"
+       check_err $? "FDB entry not present as \"inactive\" when should"
+
+       log_test "Transition from active to inactive"
+
+       bridge fdb del "$mac" dev "$swp1" master
+}
+
+norefresh_test()
+{
+       local mac="00:11:22:33:44:55"
+       local updated_time
+
+       # Check that the "updated" time is reset when replacing an FDB entry
+       # without the "norefresh" keyword and that it is not reset when
+       # replacing with the "norefresh" keyword.
+       RET=0
+
+       bridge fdb add "$mac" dev "$swp1" master static
+       sleep 1
+
+       bridge fdb replace "$mac" dev "$swp1" master static activity_notify
+       updated_time=$(bridge -d -s -j fdb get "$mac" br br1 | jq '.[]["updated"]')
+       if [[ $updated_time -ne 0 ]]; then
+               check_err 1 "\"updated\" time was not reset when should"
+       fi
+
+       sleep 1
+       bridge fdb replace "$mac" dev "$swp1" master static norefresh
+       updated_time=$(bridge -d -s -j fdb get "$mac" br br1 | jq '.[]["updated"]')
+       if [[ $updated_time -eq 0 ]]; then
+               check_err 1 "\"updated\" time was reset when should not"
+       fi
+
+       log_test "Resetting of \"updated\" time"
+
+       bridge fdb del "$mac" dev "$swp1" master
+}
+
+if ! bridge fdb help 2>&1 | grep -q "activity_notify"; then
+       echo "SKIP: iproute2 too old, missing bridge FDB activity notification control"
+       exit "$ksft_skip"
+fi
+
+trap cleanup EXIT
+
+setup_prepare
+setup_wait
+tests_run
+
+exit "$EXIT_STATUS"