[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260206030123.5430-1-linus.luessing@c0d3.blue>
Date: Fri, 6 Feb 2026 03:52:06 +0100
From: Linus Lüssing <linus.luessing@...3.blue>
To: bridge@...ts.linux.dev
Cc: netdev@...r.kernel.org,
linux-kernel@...r.kernel.org,
Nikolay Aleksandrov <razor@...ckwall.org>,
Ido Schimmel <idosch@...dia.com>,
Andrew Lunn <andrew+netdev@...n.ch>,
Simon Horman <horms@...nel.org>,
Paolo Abeni <pabeni@...hat.com>,
Jakub Kicinski <kuba@...nel.org>,
Eric Dumazet <edumazet@...gle.com>,
"David S . Miller" <davem@...emloft.net>,
Kuniyuki Iwashima <kuniyu@...gle.com>,
Stanislav Fomichev <sdf@...ichev.me>,
Xiao Liang <shaw.leon@...il.com>
Subject: [PATCH net-next v2 00/14] net: bridge: reduce multicast checks in fast path
This patchset introduces new state variables to combine and reduce the
number of checks we would otherwise perform on every multicast packet
in fast/data path. Instead of checking if our querier is enabled or
if another querier timer is pending, plus if the initial query
grace period has elapsed, plus for IPv6 and for our own querier if we
have an IPv6 address yet - and all this for every multicast packet -
we can now simply check one boolean state variable per protocol family
combining all this, the new ip{4,6}_active. Or MCAST_ACTIVE_V4 /
MCAST_ACTIVE_V6 to netlink/userspace.
The second reason for introducing these new, internal multicast active
variables is to later propagate a safety mechanism which was introduced
in b00589af3b04 ("bridge: disable snooping if there is no querier") to
switchdev/DSA, too. That is to notify switchdev/DSA if multicast
snooping can safely be applied without potential packet loss.
An example usage/integration of this with the modified Realtek rtl83xx
switch driver can be found in a draft pull-request at the OpenWrt
project: https://github.com/openwrt/openwrt/pull/18780
This was tested at least on an ZyXEL GS1900-24HP v1 switch.
iproute2 patch:
https://patchwork.kernel.org/project/netdevbpf/patch/20260206023704.4839-1-linus.luessing@c0d3.blue/
Regards, Linus
---
# Changelog v2
Summary of notable changes:
With the newly added selftests things are moved around a bit,
to be able to early on verify every commit that the general
and netlink ABI behaviour did not change.
The locking for br_multicast_open() and br_multicast_stop()
is now more symmetric.
The newly added tests revealed that in the previous pull-request
the checks were insufficient/incorrect when using VLANs, this
got fixed.
An inactive assertion / kernel splat was fixed.
* all: rebased to current net-next/main (a90f6dcefca6)
* [PATCH net-next v2 1/14] net: bridge: mcast: export ip{4,6}_active state to netlink
* removed the ip{4,6}_active state variables for now,
using/mimicking the current checks used in fast-path
to define the intended result for the netlink/userspace ABI
* br_vlan_global_opts_fill(): removing "const" from
"struct net_bridge_vlan *v_opts" (for now), to allow
dereferencing it
br->multicast_ctx.ip{4,6}_active to start with,
* [PATCH net-next v2 2/14] net: bridge: mcast: track active state, adding tests
* NEW: test that the new netlink interface has the intended results
* [PATCH net-next v2 3/14] net: bridge: mcast: avoid sleeping on bridge-down
* NEW: to be able
* [PATCH net-next v2 4/14] net: bridge: mcast: track active state, IGMP/MLD querier appearance
* adding br_multicast_notify_active() with a simple br_info()
to start with to track the evolving ip{4,6}_active behaviour
* br_ip{4,6}_multicast_query_delay_expired(): don't enable
ip{4,6}_active if we are about to get disabled by
adding/checking br_multicast_stopping()
* adding protocol specific ...delay_timer.function resets
in (new) br_multicast_reset_timer_cbs(), instead of
changing timer_setup()s in br_multicast_ctx_init()
* [PATCH net-next v2 5/14] net: bridge: mcast: track active state, foreign IGMP/MLD querier disappearance
* unchanged
* [PATCH net-next v2 6/14] net: bridge: mcast: track active state, IPv6 address availability
* unchanged
* [PATCH net-next v2 7/14] net: bridge: mcast: track active state, own MLD querier disappearance
* unchanged
* [PATCH net-next v2 8/14] net: bridge: mcast: track active state, if snooping is enabled
* renamed title: "... mcast: active state ..."
-> "... mcast: track activestate ..."
* adding VLAN aware check for BROPT_MCAST_VLAN_SNOOPING_ENABLED
* removing misplaced, second br_multicast_update_active(brmctx)
in br_multicast_toggle_one_vlan()
* [PATCH net-next v2 9/14] net: bridge: mcast: track active state, VLAN snooping
* NEW
* [PATCH net-next v2 10/14] net: bridge: mcast: track active state, bridge up/down
* adding mcast-spin-lock around br_multicast_open() in br_dev_open()a
* adding mcast-spin-lock around br_multicast_update_active()
in __br_multicast_stop()
* removing (now already locked) mcast-spin-lock addition
in br_multicast_toggle_one_vlan()
* removing (now already locked) mcast-spin-lock addition
in br_multicast_toggle_vlan_snooping()
* [PATCH net-next v2 11/14] net: bridge: mcast: track active state, prepare for outside lock reads
* NEW
* [PATCH net-next v2 12/14] net: bridge: mcast: use combined active state in netlink
* NEW (partially from: "net: bridge: mcast: export ip{4,6}_active state to netlink")
* [PATCH net-next v2 13/14] net: bridge: mcast: use combined active state in fast/data path
* using READ_ONCE() on ip{4,6}_active states
* [PATCH net-next v2 14/14] net: bridge: mcast: add inactive state assertions
* with the moved lock, bail out early if we are about to
get disabled (via br_multicast_stopping()) and just entered
br_ip{4,6}_multicast_querier_expired()
* removed br_multicast_assert_inactive() in
br_multicast_toggle_one_vlan(), as it can toggle to enabled
# Changelog (v1)
Changelog to / follow-up of: [PATCH net-next 0/5] net: bridge: propagate safe mcast snooping to switchdev + DSA
-> https://lkml.org/lkml/2025/5/22/1413
* removed the switchdev/DSA changes for now
* splitting "[PATCH net-next 1/5] net: bridge: mcast: explicitly track active state"
into:
* net: bridge: mcast: track active state, IGMP/MLD querier appearance
* net: bridge: mcast: track active state, foreign IGMP/MLD querier disappearance
* net: bridge: mcast: track active state, IPv6 address availability
* net: bridge: mcast: track active state, own MLD querier disappearance
* net: bridge: mcast: use combined active state in fast/data path
* net: bridge: mcast: track active state, bridge up/down
* rebased to current net-next/main:
* from_timer() -> timer_container_of()
* net: bridge: mcast: export ip{4,6}_active state to netlink:
* changing NLA_U8 to NLA_REJECT to make it read-only
* moved br_multicast_update_active() call from br_ip{4,6}_multicast_query_expired()
(own querier timer callback) to br_ip{4,6}_multicast_querier_expired()
(other querier timer callback)
* even though both should have worked as br_multicast_querier_expired()
would call br_multicast_start_querier()->...->br_multicast_query_expired(),
even if the own querier is disabled, but let's use the more direct way
* simplified br_multicast_update_active():
* no return value for now, don't track if the active state has changed,
these aren't necessary (yet)
* removed __br_multicast_update_active() variant as was used to force
an inactive state in __br_multicast_stop(), instead using an
netif_running(brmctx->br->dev) check in br_multicast_update_active()
* replaced br_ip{4,6}_multicast_check_active() with simpler
br_ip{4,6}_multicast_update_active() and
br_ip{4,6}_multicast_querier_exists()
* fixing build errors with CONFIG_IPV6 unset
* simplified br_multicast_toggle_enabled()
* no return value for now
* fixes "old used uninitialized" issue
* removed const from __br_multicast_querier_exists()'s "bool is_ipv6"
* replaced "struct ethhdr *eth" in br_multicast_{snooping,querier}_active()
with direct ethernet protocol integer attributes
* added a few comments in br_multicast_update_active() calling functions
Linus Lüssing (14):
net: bridge: mcast: export ip{4,6}_active state to netlink
net: bridge: mcast: track active state, adding tests
net: bridge: mcast: avoid sleeping on bridge-down
net: bridge: mcast: track active state, IGMP/MLD querier appearance
net: bridge: mcast: track active state, foreign IGMP/MLD querier
disappearance
net: bridge: mcast: track active state, IPv6 address availability
net: bridge: mcast: track active state, own MLD querier disappearance
net: bridge: mcast: track active state, if snooping is enabled
net: bridge: mcast: track active state, VLAN snooping
net: bridge: mcast: track active state, bridge up/down
net: bridge: mcast: track active state, prepare for outside lock reads
net: bridge: mcast: use combined active state in netlink
net: bridge: mcast: use combined active state in fast/data path
net: bridge: mcast: add inactive state assertions
include/uapi/linux/if_bridge.h | 2 +
include/uapi/linux/if_link.h | 14 +
net/bridge/br_device.c | 6 +-
net/bridge/br_input.c | 2 +-
net/bridge/br_multicast.c | 351 +++++++--
net/bridge/br_netlink.c | 10 +-
net/bridge/br_private.h | 45 +-
net/bridge/br_vlan.c | 5 +
net/bridge/br_vlan_options.c | 10 +-
net/core/rtnetlink.c | 2 +-
.../net/forwarding/bridge_mdb_active.sh | 682 ++++++++++++++++++
11 files changed, 1048 insertions(+), 81 deletions(-)
create mode 100755 tools/testing/selftests/net/forwarding/bridge_mdb_active.sh
--
2.51.0
Powered by blists - more mailing lists