Ethernet Bridge development
 help / color / mirror / Atom feed
From: Ido Schimmel <idosch@nvidia.com>
To: netdev@vger.kernel.org, bridge@lists.linux.dev
Cc: davem@davemloft.net, kuba@kernel.org, pabeni@redhat.com,
	edumazet@kernel.org, razor@blackwall.org, horms@kernel.org,
	petrm@nvidia.com, yunlong_ma@buaa.edu.cn,
	Ido Schimmel <idosch@nvidia.com>
Subject: [PATCH net 2/2] selftests: forwarding: bridge_mdb_max: Add a test for rejected MDB entries
Date: Fri, 16 Oct 2026 13:14:07 +0300	[thread overview]
Message-ID: <20261016101407.2030133-3-idosch@nvidia.com> (raw)
In-Reply-To: <20261016101407.2030133-1-idosch@nvidia.com>

Add a test that checks that MDB entries that are rejected because the
port reached its maximum number of MDB entries (mcast_max_groups) do not
count towards the maximum number of MDB entries in the bridge
(mcast_hash_max).

The test lowers mcast_hash_max so that only three more entries can be
added. It then configures the port's maximum so that new (*, G) entries
are rejected and tries to add four of them. Next, it raises the maximum
by one so that a new (*, G) entry is accepted, but its (S, G) entry is
rejected, and tries this with four groups. Finally, it checks that
multicast snooping was not disabled because the bridge ran out of MDB
entries.

Like the other tests, the test is run for entries added both by the
control path (IGMP / MLD reports) and by the configuration path
(RTM_NEWMDB), and for both the port and port-VLAN maximums.

Without "bridge: mcast: Delete empty MDB entry when port group creation
fails", the new tests fail (other tests omitted):

 # ./bridge_mdb_max.sh
 INFO: 802.1d tests
 TEST: cfg4: port maxgroups: rejected entries do not exhaust MDB     [FAIL]
         Multicast snooping disabled by rejected MDB entries
 TEST: ctl4: port maxgroups: rejected entries do not exhaust MDB     [FAIL]
         Multicast snooping disabled by rejected MDB entries
 TEST: cfg6: port maxgroups: rejected entries do not exhaust MDB     [FAIL]
         Multicast snooping disabled by rejected MDB entries
 TEST: ctl6: port maxgroups: rejected entries do not exhaust MDB     [FAIL]
         Multicast snooping disabled by rejected MDB entries
 INFO: 802.1q tests
 TEST: cfg4: port maxgroups: rejected entries do not exhaust MDB     [FAIL]
         Multicast snooping disabled by rejected MDB entries
 TEST: ctl4: port maxgroups: rejected entries do not exhaust MDB     [FAIL]
         Multicast snooping disabled by rejected MDB entries
 TEST: cfg6: port maxgroups: rejected entries do not exhaust MDB     [FAIL]
         Multicast snooping disabled by rejected MDB entries
 TEST: ctl6: port maxgroups: rejected entries do not exhaust MDB     [FAIL]
         Multicast snooping disabled by rejected MDB entries
 INFO: 802.1q mcast_vlan_snooping 1 tests
 TEST: cfg4: port_vlan maxgroups: rejected entries do not exhaust MDB   [FAIL]
         Multicast snooping disabled by rejected MDB entries
 TEST: ctl4: port_vlan maxgroups: rejected entries do not exhaust MDB   [FAIL]
         Multicast snooping disabled by rejected MDB entries
 TEST: cfg6: port_vlan maxgroups: rejected entries do not exhaust MDB   [FAIL]
         Multicast snooping disabled by rejected MDB entries
 TEST: ctl6: port_vlan maxgroups: rejected entries do not exhaust MDB   [FAIL]
         Multicast snooping disabled by rejected MDB entries

Assisted-by: LLM
Acked-by: Nikolay Aleksandrov <nikolay@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
---
 .../net/forwarding/bridge_mdb_max.sh          | 138 ++++++++++++++++++
 1 file changed, 138 insertions(+)

diff --git a/tools/testing/selftests/net/forwarding/bridge_mdb_max.sh b/tools/testing/selftests/net/forwarding/bridge_mdb_max.sh
index 625162fd7e8b..4ebffe4588a2 100755
--- a/tools/testing/selftests/net/forwarding/bridge_mdb_max.sh
+++ b/tools/testing/selftests/net/forwarding/bridge_mdb_max.sh
@@ -399,6 +399,24 @@ bridge_port_vlan_maxgroups_set()
 	bridge vlan set $locus mcast_max_groups $max
 }
 
+bridge_mcast_snooping_get()
+{
+	ip -j -d link show dev br0 |
+	    jq '.[].linkinfo.info_data.mcast_snooping'
+}
+
+bridge_mcast_hash_max_get()
+{
+	ip -j -d link show dev br0 |
+	    jq '.[].linkinfo.info_data.mcast_hash_max'
+}
+
+bridge_mdb_entries_count()
+{
+	bridge -j mdb show dev br0 |
+	    jq '[.[].mdb[] | [.grp, .src, .vid]] | unique | length'
+}
+
 test_ngroups_reporting()
 {
 	local CFG=$1; shift
@@ -938,6 +956,114 @@ test_8021qvs_maxgroups_too_many_entries_ctl6()
 	test_maxgroups_too_many_entries ctl6 port_vlan "dev $swp1 vid 10"
 }
 
+test_maxgroups_hash_max()
+{
+	local CFG=$1; shift
+	local context=$1; shift
+	local locus=$1; shift
+
+	local hash_max n i
+
+	RET=0
+
+	hash_max=$(bridge_mcast_hash_max_get)
+
+	# Make sure the port has entries, so that max == n is not 0 (no limit).
+	${CFG}_entries_add "$locus" temp 2 120
+	check_err $? "$locus: Couldn't add MDB entries"
+	n=$(bridge_${context}_ngroups_get "$locus")
+
+	# Leave room for three more MDB entries.
+	ip link set dev br0 type bridge \
+		mcast_hash_max $(($(bridge_mdb_entries_count) + 3))
+	check_err $? "Couldn't set mcast_hash_max"
+
+	# Port at its maximum: (*, G) entries are rejected.
+	bridge_${context}_maxgroups_set "$locus" "$n"
+	check_err $? "$locus: Couldn't set maximum"
+	for i in $(seq 121 124); do
+		${CFG}_entries_add "$locus" temp 2 "$i" &> /dev/null
+	done
+
+	# One more slot: (*, G) is accepted, (S, G) is rejected.
+	bridge_${context}_maxgroups_set "$locus" $((n + 1))
+	check_err $? "$locus: Couldn't set maximum"
+	for i in $(seq 125 128); do
+		${CFG}_entries_add "$locus" temp 2 "$i" &> /dev/null
+	done
+
+	[[ $(bridge_mcast_snooping_get) == 1 ]]
+	check_err $? "Multicast snooping disabled by rejected MDB entries"
+
+	bridge mdb flush dev br0
+	ip link set dev br0 type bridge mcast_snooping 1
+	ip link set dev br0 type bridge mcast_hash_max "$hash_max"
+	bridge_${context}_maxgroups_set "$locus" 0
+	check_err $? "$locus: Couldn't set maximum to 0"
+
+	log_test "$CFG: $context maxgroups: rejected entries do not exhaust MDB"
+}
+
+test_8021d_maxgroups_hash_max_cfg4()
+{
+	test_maxgroups_hash_max cfg4 port "dev $swp1"
+}
+
+test_8021d_maxgroups_hash_max_ctl4()
+{
+	test_maxgroups_hash_max ctl4 port "dev $swp1"
+}
+
+test_8021d_maxgroups_hash_max_cfg6()
+{
+	test_maxgroups_hash_max cfg6 port "dev $swp1"
+}
+
+test_8021d_maxgroups_hash_max_ctl6()
+{
+	test_maxgroups_hash_max ctl6 port "dev $swp1"
+}
+
+test_8021q_maxgroups_hash_max_cfg4()
+{
+	test_maxgroups_hash_max cfg4 port "dev $swp1 vid 10"
+}
+
+test_8021q_maxgroups_hash_max_ctl4()
+{
+	test_maxgroups_hash_max ctl4 port "dev $swp1 vid 10"
+}
+
+test_8021q_maxgroups_hash_max_cfg6()
+{
+	test_maxgroups_hash_max cfg6 port "dev $swp1 vid 10"
+}
+
+test_8021q_maxgroups_hash_max_ctl6()
+{
+	test_maxgroups_hash_max ctl6 port "dev $swp1 vid 10"
+}
+
+test_8021qvs_maxgroups_hash_max_cfg4()
+{
+	test_maxgroups_hash_max cfg4 port_vlan "dev $swp1 vid 10"
+}
+
+test_8021qvs_maxgroups_hash_max_ctl4()
+{
+	test_maxgroups_hash_max ctl4 port_vlan "dev $swp1 vid 10"
+}
+
+test_8021qvs_maxgroups_hash_max_cfg6()
+{
+	test_maxgroups_hash_max cfg6 port_vlan "dev $swp1 vid 10"
+}
+
+test_8021qvs_maxgroups_hash_max_ctl6()
+{
+	test_maxgroups_hash_max ctl6 port_vlan "dev $swp1 vid 10"
+}
+
 test_maxgroups_too_many_cross_vlan()
 {
 	local CFG=$1; shift
@@ -1177,6 +1303,7 @@ test_8021d_maxgroups_cfg4()
 	test_8021d_maxgroups_zero_cfg4
 	test_8021d_maxgroups_too_low_cfg4
 	test_8021d_maxgroups_too_many_entries_cfg4
+	test_8021d_maxgroups_hash_max_cfg4
 }
 
 test_8021d_maxgroups_ctl4()
@@ -1184,6 +1311,7 @@ test_8021d_maxgroups_ctl4()
 	test_8021d_maxgroups_zero_ctl4
 	test_8021d_maxgroups_too_low_ctl4
 	test_8021d_maxgroups_too_many_entries_ctl4
+	test_8021d_maxgroups_hash_max_ctl4
 }
 
 test_8021d_maxgroups_cfg6()
@@ -1191,6 +1319,7 @@ test_8021d_maxgroups_cfg6()
 	test_8021d_maxgroups_zero_cfg6
 	test_8021d_maxgroups_too_low_cfg6
 	test_8021d_maxgroups_too_many_entries_cfg6
+	test_8021d_maxgroups_hash_max_cfg6
 }
 
 test_8021d_maxgroups_ctl6()
@@ -1198,6 +1327,7 @@ test_8021d_maxgroups_ctl6()
 	test_8021d_maxgroups_zero_ctl6
 	test_8021d_maxgroups_too_low_ctl6
 	test_8021d_maxgroups_too_many_entries_ctl6
+	test_8021d_maxgroups_hash_max_ctl6
 }
 
 test_8021q_maxgroups_cfg4()
@@ -1205,6 +1335,7 @@ test_8021q_maxgroups_cfg4()
 	test_8021q_maxgroups_zero_cfg4
 	test_8021q_maxgroups_too_low_cfg4
 	test_8021q_maxgroups_too_many_entries_cfg4
+	test_8021q_maxgroups_hash_max_cfg4
 }
 
 test_8021q_maxgroups_ctl4()
@@ -1212,6 +1343,7 @@ test_8021q_maxgroups_ctl4()
 	test_8021q_maxgroups_zero_ctl4
 	test_8021q_maxgroups_too_low_ctl4
 	test_8021q_maxgroups_too_many_entries_ctl4
+	test_8021q_maxgroups_hash_max_ctl4
 }
 
 test_8021q_maxgroups_cfg6()
@@ -1219,6 +1351,7 @@ test_8021q_maxgroups_cfg6()
 	test_8021q_maxgroups_zero_cfg6
 	test_8021q_maxgroups_too_low_cfg6
 	test_8021q_maxgroups_too_many_entries_cfg6
+	test_8021q_maxgroups_hash_max_cfg6
 }
 
 test_8021q_maxgroups_ctl6()
@@ -1226,6 +1359,7 @@ test_8021q_maxgroups_ctl6()
 	test_8021q_maxgroups_zero_ctl6
 	test_8021q_maxgroups_too_low_ctl6
 	test_8021q_maxgroups_too_many_entries_ctl6
+	test_8021q_maxgroups_hash_max_ctl6
 }
 
 test_8021qvs_maxgroups_cfg4()
@@ -1234,6 +1368,7 @@ test_8021qvs_maxgroups_cfg4()
 	test_8021qvs_maxgroups_zero_cross_vlan_cfg4
 	test_8021qvs_maxgroups_too_low_cfg4
 	test_8021qvs_maxgroups_too_many_entries_cfg4
+	test_8021qvs_maxgroups_hash_max_cfg4
 	test_8021qvs_maxgroups_too_many_cross_vlan_cfg4
 }
 
@@ -1243,6 +1378,7 @@ test_8021qvs_maxgroups_ctl4()
 	test_8021qvs_maxgroups_zero_cross_vlan_ctl4
 	test_8021qvs_maxgroups_too_low_ctl4
 	test_8021qvs_maxgroups_too_many_entries_ctl4
+	test_8021qvs_maxgroups_hash_max_ctl4
 	test_8021qvs_maxgroups_too_many_cross_vlan_ctl4
 }
 
@@ -1252,6 +1388,7 @@ test_8021qvs_maxgroups_cfg6()
 	test_8021qvs_maxgroups_zero_cross_vlan_cfg6
 	test_8021qvs_maxgroups_too_low_cfg6
 	test_8021qvs_maxgroups_too_many_entries_cfg6
+	test_8021qvs_maxgroups_hash_max_cfg6
 	test_8021qvs_maxgroups_too_many_cross_vlan_cfg6
 }
 
@@ -1261,6 +1398,7 @@ test_8021qvs_maxgroups_ctl6()
 	test_8021qvs_maxgroups_zero_cross_vlan_ctl6
 	test_8021qvs_maxgroups_too_low_ctl6
 	test_8021qvs_maxgroups_too_many_entries_ctl6
+	test_8021qvs_maxgroups_hash_max_ctl6
 	test_8021qvs_maxgroups_too_many_cross_vlan_ctl6
 }
 
-- 
2.56.0


  parent reply	other threads:[~2026-10-16 10:15 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-16 10:14 [PATCH net 0/2] bridge: mcast: Fix MDB exhaustion by rejected entries Ido Schimmel
2026-10-16 10:14 ` [PATCH net 1/2] bridge: mcast: Delete empty MDB entry when port group creation fails Ido Schimmel
2026-10-16 10:14 ` Ido Schimmel [this message]
2026-10-16 15:51 ` [PATCH net 0/2] bridge: mcast: Fix MDB exhaustion by rejected entries Gabriel Goller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261016101407.2030133-3-idosch@nvidia.com \
    --to=idosch@nvidia.com \
    --cc=bridge@lists.linux.dev \
    --cc=davem@davemloft.net \
    --cc=edumazet@kernel.org \
    --cc=horms@kernel.org \
    --cc=kuba@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=petrm@nvidia.com \
    --cc=razor@blackwall.org \
    --cc=yunlong_ma@buaa.edu.cn \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox