On 24/03/2026 20:49, Andy Roulin wrote:
The bridge-stp usermode helper is currently restricted to the initial
network namespace, preventing userspace STP daemons (e.g. mstpd) from
operating on bridges in other network namespaces. Since commit
ff62198553e4 ("bridge: Only call /sbin/bridge-stp for the initial
network namespace"), bridges in non-init namespaces silently fall back
to kernel STP with no way to use userspace STP.

Add a new bridge attribute IFLA_BR_STP_MODE that allows explicit
per-bridge control over STP mode selection:

   BR_STP_MODE_AUTO (default) - Existing behavior: invoke the
     /sbin/bridge-stp helper in init_net only; fall back to kernel STP
     if it fails or in non-init namespaces.

   BR_STP_MODE_USER - Directly enable userspace STP (BR_USER_STP)
     without invoking the helper. Works in any network namespace. The
     caller is responsible for registering the bridge with the STP
     daemon after enabling STP.

   BR_STP_MODE_KERNEL - Directly enable kernel STP (BR_KERNEL_STP)
     without invoking the helper.

The mode can only be changed while STP is disabled (-EBUSY otherwise).
IFLA_BR_STP_MODE is processed before IFLA_BR_STP_STATE in
br_changelink(), so both can be set atomically in a single netlink
message.

This eliminates the need for call_usermodehelper() in user/kernel
modes, addressing the security concerns discussed in the thread at
https://lore.kernel.org/netdev/[email protected]/ and providing
a cleaner alternative to extending the helper into namespaces.

Suggested-by: Ido Schimmel <[email protected]>
Reviewed-by: Ido Schimmel <[email protected]>
Assisted-by: Claude:claude-opus-4-6
Signed-off-by: Andy Roulin <[email protected]>
---
  include/uapi/linux/if_link.h | 40 ++++++++++++++++++++++++++++++++++++
  net/bridge/br_device.c       |  1 +
  net/bridge/br_netlink.c      | 18 +++++++++++++++-
  net/bridge/br_private.h      |  1 +
  net/bridge/br_stp_if.c       | 17 ++++++++-------
  5 files changed, 69 insertions(+), 8 deletions(-)

[snip]
  #ifdef CONFIG_BRIDGE_VLAN_FILTERING
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 6dbca845e625d..e4bb9c3f28726 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -540,6 +540,7 @@ struct net_bridge {
                BR_KERNEL_STP,          /* old STP in kernel */
                BR_USER_STP,            /* new RSTP in userspace */
        } stp_enabled;
+       u32                             stp_mode;
struct net_bridge_mcast multicast_ctx;
[snip]

Not critical but there's a 4 byte hole in the same cache line betwen root_port
and max_age, if you move stp_mode there we get:

/* size: 1728, cachelines: 27, members: 53 */
/* sum members: 1722, holes: 2, sum holes: 6 */

vs

/* size: 1736, cachelines: 28, members: 53 */
/* sum members: 1722, holes: 4, sum holes: 14 */




Reply via email to