* [PATCH iproute2-next] iplink: bridge: add stp_mode support
@ 2026-05-18 16:36 Andy Roulin
2026-05-18 22:10 ` Stephen Hemminger
0 siblings, 1 reply; 2+ messages in thread
From: Andy Roulin @ 2026-05-18 16:36 UTC (permalink / raw)
To: netdev
Cc: stephen, dsahern, bridge, razor, nikolay, idosch, petrm,
danieller, Andy Roulin
Add support for the IFLA_BR_STP_MODE bridge attribute that allows
userspace to explicitly select the STP mode:
- auto (0): default, try /sbin/bridge-stp helper in init_net
- user (1): directly enable userspace STP without the helper,
works in any network namespace
- kernel (2): directly enable kernel STP without the helper
Both string ("auto", "user", "kernel") and numeric values are accepted
when setting the attribute. Display uses string names for known values
with numeric fallback for future extensions.
Example usage:
ip link set br0 type bridge stp_mode user
ip link set br0 type bridge stp_state 1
Link: https://lore.kernel.org/netdev/20260405205224.3163000-1-aroulin@nvidia.com/
Assisted-by: Claude:claude-opus-4-7
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Andy Roulin <aroulin@nvidia.com>
---
ip/iplink_bridge.c | 30 ++++++++++++++++++++++++++++++
man/man8/ip-link.8.in | 32 ++++++++++++++++++++++++++++++++
2 files changed, 62 insertions(+)
diff --git a/ip/iplink_bridge.c b/ip/iplink_bridge.c
index df3264c3..d15221b2 100644
--- a/ip/iplink_bridge.c
+++ b/ip/iplink_bridge.c
@@ -31,6 +31,7 @@ static void print_explain(FILE *f)
" [ max_age MAX_AGE ]\n"
" [ ageing_time AGEING_TIME ]\n"
" [ stp_state STP_STATE ]\n"
+ " [ stp_mode STP_MODE ]\n"
" [ mst_enabled MST_ENABLED ]\n"
" [ priority PRIORITY ]\n"
" [ group_fwd_mask MASK ]\n"
@@ -67,6 +68,7 @@ static void print_explain(FILE *f)
" [ mdb_offload_fail_notification MDB_OFFLOAD_FAIL_NOTIFICATION ]\n"
"\n"
"Where: VLAN_PROTOCOL := { 802.1Q | 802.1ad }\n"
+ " STP_MODE := { auto | user | kernel }\n"
);
}
@@ -120,6 +122,20 @@ static int bridge_parse_opt(struct link_util *lu, int argc, char **argv,
invarg("invalid stp_state", *argv);
addattr32(n, 1024, IFLA_BR_STP_STATE, val);
+ } else if (strcmp(*argv, "stp_mode") == 0) {
+ __u32 stp_mode;
+
+ NEXT_ARG();
+ if (strcmp(*argv, "auto") == 0)
+ stp_mode = BR_STP_MODE_AUTO;
+ else if (strcmp(*argv, "user") == 0)
+ stp_mode = BR_STP_MODE_USER;
+ else if (strcmp(*argv, "kernel") == 0)
+ stp_mode = BR_STP_MODE_KERNEL;
+ else if (get_u32(&stp_mode, *argv, 0))
+ invarg("invalid stp_mode", *argv);
+
+ addattr32(n, 1024, IFLA_BR_STP_MODE, stp_mode);
} else if (matches(*argv, "priority") == 0) {
__u16 prio;
@@ -512,6 +528,20 @@ static void bridge_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
"stp_state %u ",
rta_getattr_u32(tb[IFLA_BR_STP_STATE]));
+ if (tb[IFLA_BR_STP_MODE]) {
+ static const char *stp_modes[] = {
+ "auto", "user", "kernel"
+ };
+ __u32 mode = rta_getattr_u32(tb[IFLA_BR_STP_MODE]);
+
+ if (mode < ARRAY_SIZE(stp_modes))
+ print_string(PRINT_ANY, "stp_mode",
+ "stp_mode %s ", stp_modes[mode]);
+ else
+ print_uint(PRINT_ANY, "stp_mode",
+ "stp_mode %u ", mode);
+ }
+
if (tb[IFLA_BR_PRIORITY])
print_uint(PRINT_ANY,
"priority",
diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
index ef45fe08..802dd739 100644
--- a/man/man8/ip-link.8.in
+++ b/man/man8/ip-link.8.in
@@ -1719,6 +1719,8 @@ the following additional arguments are supported:
] [
.BI stp_state " STP_STATE "
] [
+.BI stp_mode " STP_MODE "
+] [
.BI mst_enabled " MST_ENABLED "
] [
.BI priority " PRIORITY "
@@ -1828,6 +1830,36 @@ or off
.RI ( STP_STATE " == 0). "
for this bridge.
+.BI stp_mode " STP_MODE "
+- set the STP mode for this bridge. This controls how the bridge
+selects between userspace and kernel STP when STP is enabled via
+.BR stp_state .
+.I STP_MODE
+can be one of:
+.in +8
+.sp
+.B auto
+(default) - invoke the
+.B /sbin/bridge-stp
+helper to hand the bridge to a userspace STP daemon. Only attempted in
+the initial network namespace; in other namespaces this falls back to
+kernel STP.
+
+.B user
+- directly enable userspace STP without invoking the helper. Works in
+any network namespace. The caller is responsible for registering the
+bridge with the userspace STP daemon.
+
+.B kernel
+- directly enable kernel STP without invoking the helper.
+.in -8
+
+Can only be changed while STP is disabled. Both
+.B stp_mode
+and
+.B stp_state
+can be set in a single command.
+
.BI mst_enabled " MST_ENABLED "
- turn multiple spanning tree (MST) support on
.RI ( MST_ENABLED " > 0) "
--
2.43.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH iproute2-next] iplink: bridge: add stp_mode support
2026-05-18 16:36 [PATCH iproute2-next] iplink: bridge: add stp_mode support Andy Roulin
@ 2026-05-18 22:10 ` Stephen Hemminger
0 siblings, 0 replies; 2+ messages in thread
From: Stephen Hemminger @ 2026-05-18 22:10 UTC (permalink / raw)
To: Andy Roulin
Cc: netdev, dsahern, bridge, razor, nikolay, idosch, petrm, danieller
On Mon, 18 May 2026 09:36:47 -0700
Andy Roulin <aroulin@nvidia.com> wrote:
> + } else if (strcmp(*argv, "stp_mode") == 0) {
> + __u32 stp_mode;
> +
> + NEXT_ARG();
> + if (strcmp(*argv, "auto") == 0)
> + stp_mode = BR_STP_MODE_AUTO;
> + else if (strcmp(*argv, "user") == 0)
> + stp_mode = BR_STP_MODE_USER;
> + else if (strcmp(*argv, "kernel") == 0)
> + stp_mode = BR_STP_MODE_KERNEL;
> + else if (get_u32(&stp_mode, *argv, 0))
> + invarg("invalid stp_mode", *argv);
> +
> + addattr32(n, 1024, IFLA_BR_STP_MODE, stp_mode);
Not your fault but yet another case where matches() was bad idea
because if you pass "stp" it matches only stp_state.
Really should fix all of iproute2 to use a table approach and
not allow conflicting matches, but that is a lot of work,
and will break peoples scripts.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-05-18 22:10 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-18 16:36 [PATCH iproute2-next] iplink: bridge: add stp_mode support Andy Roulin
2026-05-18 22:10 ` Stephen Hemminger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox