From nobody Thu Apr 2 12:33:04 2026 Received: from BYAPR05CU005.outbound.protection.outlook.com (mail-westusazon11010014.outbound.protection.outlook.com [52.101.85.14]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8466524A044; Sun, 29 Mar 2026 02:59:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.85.14 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774753149; cv=fail; b=DI93i9KPZ+zQ+7N2qo/K5tl3SA6OgZEp+jxOx7M9sruw9YlpbCL6uqWNJT4oFo0XJ/pT4pzC5CAJYZ89GxW8NG1hdnTWJ+QSQx4NzBXkyo7dmY94Gw7c8O/74quFThpSjGjXBHVoVZOHeB44c7E9SlxYUNCy1Av14rBI6B94beI= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774753149; c=relaxed/simple; bh=tp+xedz4Yx0ORCT9Mgzs5gB5SojEALe+6+Drl3SfIHs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=pbVmrseAGifWDZGICjgIepUyOp+ZhIQs2hf5EP4I+BsOfnXiPmC7W6aXFniiH/+FyNcfwQDRyrTkzv3EfcE1hwvHlT4/uyamJzbrfXQZbM3i9TsgyXW3tlLWIFRY+4cNJt7lQ1EWtm8O1MafOP/zpIoEwxB+ZADFTShkVVcOm9U= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com; spf=fail smtp.mailfrom=nvidia.com; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b=bzqfhuOK; arc=fail smtp.client-ip=52.101.85.14 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=nvidia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b="bzqfhuOK" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=hJ3nPO3uJW36IbIXAmNFRof6aihUWjSYgmw1FykfQ6OF2dMA6NGbpLNCB291f4yUOLVm4DtQpnQ+BQTfAX/OkIUksalZt2Q3ity0bIEDa59OAjgVA1jfecGqctlfWqqhft41D2g1PCB0QUJSN9yzjxgMZXg8MFyW0BjFJbC0QQqJYgHRm7HVdodqm5APHb9fNmEw1s+RlTXtJBNX037WG3nArR73pdBBz9Lwgy2NO+nd3A8W1rKvIL/05ZOfJoIcPN3tq1tCpCfp5U+o8qSoj2nkXGAjLsww0de8cNffSo9NwYQfW8i643H5/1kiRu4ZjezeaMDqhiitAxfTVzNBNg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=udzHLhr11JgpFqc/3kGdZwU1RXx5f/CRkHsE1F7vdwM=; b=fq2HASAm86eYbBqBP8IL0TKE6fVMT1rqXmU5V58Ec3IfwARihmDk3je9JE2474uje7AlYfzamcZyPUGHD0Ckvi1oRw6r/kXRRD3DdQiBfQESjF9uLvS38p5JuIswSPxlJxv1bvAxRMuhQty93LAtloNMdd0kGMGAxQaHuwgKUWQj5A4aZgG741uMYhUDM0gXH0uEmip+ebYYIIubrzXuvvsDQtcnNI4zCvRjMc4HUy+fPnn8EDdklsvP09Fe89sct1vEZRo9W0cVHdTWZAs2Nta6kIVsFvQajKSlC+wwSfANGConQB189HwvUztwkY0+/8C0r97PPWYr/sTaQ3GsHA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=udzHLhr11JgpFqc/3kGdZwU1RXx5f/CRkHsE1F7vdwM=; b=bzqfhuOKiLHWG+suTYkFUEmZfwBGz/sDJoxVOcb+qgtjVu+eydozjVjyQ+2U2bXOosVlZ+BjBkWAKkmgNK4P/QliAyLKXhEZxIzMutzbsS9X1OayuAr/tziZwF2juQ97ryyvUIX64ZpzFOBWFQrZ3q0JESrbJHwcw3cMP/im7rIeUw+d69r+mjuC6tHpFvINA0rCdPx48sGeyii/tDzFRonF2FnelDzhQ+5EBN8W5zYCJQccfC6t8AvbnK0Q7+6b1Dh2M2fFQqBQJeK0AvOfn26gSfYPoKx3Gk0+k7wyWKhk9czCwg9OxvADCV4onW9myL+ZERKP1rvfzmZ5gjV6qQ== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; Received: from DS7PR12MB8202.namprd12.prod.outlook.com (2603:10b6:8:e1::13) by DS2PR12MB9752.namprd12.prod.outlook.com (2603:10b6:8:270::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9769.14; Sun, 29 Mar 2026 02:59:01 +0000 Received: from DS7PR12MB8202.namprd12.prod.outlook.com ([fe80::38fd:4146:aea:639e]) by DS7PR12MB8202.namprd12.prod.outlook.com ([fe80::38fd:4146:aea:639e%6]) with mapi id 15.20.9769.014; Sun, 29 Mar 2026 02:59:01 +0000 From: Andy Roulin To: netdev@vger.kernel.org Cc: bridge@lists.linux.dev, Nikolay Aleksandrov , Ido Schimmel , Andrew Lunn , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Jonathan Corbet , Shuah Khan , Petr Machata , Donald Hunter , Jonas Gorski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Andy Roulin Subject: [PATCH net-next v2 1/3] net: bridge: add stp_mode attribute for STP mode selection Date: Sat, 28 Mar 2026 19:58:56 -0700 Message-ID: <20260329025858.330620-2-aroulin@nvidia.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260329025858.330620-1-aroulin@nvidia.com> References: <20260329025858.330620-1-aroulin@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: SJ0PR05CA0209.namprd05.prod.outlook.com (2603:10b6:a03:330::34) To DS7PR12MB8202.namprd12.prod.outlook.com (2603:10b6:8:e1::13) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DS7PR12MB8202:EE_|DS2PR12MB9752:EE_ X-MS-Office365-Filtering-Correlation-Id: d009dc45-dea9-4678-aee9-08de8d3f2139 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|7416014|376014|366016|18002099003|18092099006|56012099003|22082099003; X-Microsoft-Antispam-Message-Info: h2622Df8ZkskotuAv2Mf9K3voEtraSD+IppxoP9WwFR5EjYZ/PiD4Ips6PZ4sBzMUF38nHJOJtYvgynb/+kqzGn09uxgk1G0hgWKV0Y/B2ppAOyYuDbHYeLNngVkOnJIh2tuzqsGvQYeeXbEu79rR8WV7BPcdRE6FgmVYrwifBypoztNxKM4BNecWuujoJTjzTvr4Ab5Bw1rWS79L17+zvW6ci4URjITsFZv438o6DnPNEpDjZ4A+n2fxe2Amg74exJadHSiMxrZAUTfh9GNgptXjpXl/GRrSvpFyqep54XonhHCb8kIPndPe7tIPdFa693NAwuxAqzzpo8GWHabvvKSTzQ4fxNZAw1DN0Yq4TFrm6ns4rJqbDbQOFKiplrAehdbWyOiLSrQdBCM2+qAMo2E6qN+m6vRllK5T/jfDqk7VrF8ykESatS5b+fYo+7S9bNU2CBnMpqnAg02tvTc3zca9iehwVV5BmzRzoym4+vMfKF/ySXIfdVVFEhtbmnFmFGOd7rfzfoC2AcIVbuLf3JabnC0DYDN2nw2sQMRUTvfNQD0V92FitAbIFt5nc1E9JoDHjjReYHq7CZrnQ4dBbegIfsBdD7oqnCTEjAEISzchfl4RNxS9kZYn/LpNUWr7c3+HYQF6bEdfb0tUYxOoX+vrnDN56xIsvTLl3DwhX17XDAw1HVs2zhc4aevrjf/hlpEjSDeyvpNje9kCWYk8Nl0EfvQAzIJuOTADyPSauc= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DS7PR12MB8202.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(1800799024)(7416014)(376014)(366016)(18002099003)(18092099006)(56012099003)(22082099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?pmAVzYjv4aqwkio1Upp6OYrlNeXBGzZuImzK7qcZ7YIxt9iCiq60e/w1K/+u?= =?us-ascii?Q?GgEvH8UeazCLopc9Xm35RHgHb8aNr6jWweT3uiNP4UPcLxUhfQ8bDNaTa5nC?= =?us-ascii?Q?5N08gwi0FwCc+4Rc2ILA73cyQN3GWKs26gm3e/xzuyDGnZrROH4pdkiHCJQz?= =?us-ascii?Q?B4isBVsSLcas9pyCzuNvKI5UmP9Ms4jPNdoW0VG1QkJRY6zGO0Zfizl2v/Ue?= =?us-ascii?Q?9vSekZ84Bz5/cpBGj9OvmTc7mMqoqViw0ba8OAB+lIoki0oBxCBYpUY9+rON?= =?us-ascii?Q?o4A4lElByilqsT6ayWIfvGhAM4RIIQMvUQ6klHABFJlYPdixfdb9ybY4HvG0?= =?us-ascii?Q?9Fcl3UuKBVABK9RM6lO57HAa9JKFmr0vLv5fuQUP8+ogEk4dmPDZEgTpuVLI?= =?us-ascii?Q?nnlS2VXdRpGK6y50teg3rfonIwrXEAXfHKuUJjK+lMv2MUmqc6sq9lKMcFKr?= =?us-ascii?Q?Wzk/IUineKLA4UaFwT6m0ZZWJBfT70bt6EsgZVuZnLSbkujY6WruBlEVs0Tj?= =?us-ascii?Q?KJrZJuzjYIpvGWN+oEDJxPXnglkvmN1ZnrUY35HgwByvuM4mVxx6YaaGNQir?= =?us-ascii?Q?UKZcjjxilPGRJlenMLrdFk29j6YDAtaBf15hzHk5JbcgVdihTopv9s7IQox8?= =?us-ascii?Q?KyWn1JtpPAW3GVtQ6/b9uAnnTot6OqXO2sWzQNg+ANg2KSLHJ1M5X/YYh8zi?= =?us-ascii?Q?0zhbXCRGLD96CXbF1DVSAEdiZsh6rmX8AkyFBrdDwT3tRdbVjbD147/saMH3?= =?us-ascii?Q?dAWY0Ns+VK/kHpCnyMCvnW6JmkTjQDaHF9m5+uxqNbYScLaLM15KtL9jWfrw?= =?us-ascii?Q?42K8/Bf6JbvyISK1HrmbI5LWQTd50p/aL4Q1Vbvr/HQLi8qLpvnYE7iypLQM?= =?us-ascii?Q?F72lLWtBl3ks4Do0ySn7z/cw1Mp9fm7/EukF6/+c0goo/mOPRsQhjMvOfMda?= =?us-ascii?Q?VOpYGsqwm3UTNQvqtk+TwpEXY3n26enmhr3+7I18m5fYKoT4eVHGyhXg3FIW?= =?us-ascii?Q?CEDbgarhcrQG/JIkhL6Fj+yqWu+EjoHtK5xilWO43R8gOkXCOGlzqBChwtiE?= =?us-ascii?Q?i2405VBP20qLi8fZntRrRsxYqt5/wDRD1AigAvAvozY0pVgXgF76MGTAi196?= =?us-ascii?Q?1ffFzuX1idgl0wvfsmVtm0h3jEJDgZMhUslmkEITRTSfnhl6Su4CkQs5Mkwh?= =?us-ascii?Q?YC2IxoV9DeOJ7VjDpx8mHJ3zTr9kuGyN0Cx72vbqqcJEKWiBg1VokYzWDoed?= =?us-ascii?Q?QJp4Ma5LBuIuKJUo2g/hpOpis537+9C732bHixC2owIMSS6p4ANUU8IBecI9?= =?us-ascii?Q?kOg3yuSQVBugYKyHXY2UOGYwiJWMSMYmrQV4yXxVriWmQl2PjojFsTh2poFB?= =?us-ascii?Q?tPe2bJ5t4KhViHDBrw6ZnxxsrnDYEplxk49AKJ1QjNfFB5/Qus4KHC5eJABS?= =?us-ascii?Q?qSVVB7HcYL3bYe6AIDR5i4StdhWJOAzwYr7VsszmK2HPmXnqZ35RuVYz7XpC?= =?us-ascii?Q?htoB4AAQkqIVpjn2LF1FT/qAjljKRDFbfgodTRmQ12mRIPpKvvTiqBivRdnW?= =?us-ascii?Q?D1JlysWBpev6Zu/Kwe5R5zVFlDwzb5bZQbFgN8DxBe7WBFFnn8hWo2DLimBK?= =?us-ascii?Q?v54uFqiBsk+iNRs96Zw23gNm4CUJ/MLdbBdgmDM8/b68EbIjt+iu251QULPu?= =?us-ascii?Q?hOxF3Rf/xmnEobylIJwo4B/zBHrwCxgIIdHhU+iMyiZHRRdMS0gWXf8PBJiC?= =?us-ascii?Q?X9PHTUL7EA=3D=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: d009dc45-dea9-4678-aee9-08de8d3f2139 X-MS-Exchange-CrossTenant-AuthSource: DS7PR12MB8202.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Mar 2026 02:59:01.4393 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 0frpmGUBoO+kLrSx8vQ94GnwKBRR/d2SkwEgjpEtYelRArNDr+vYalSMoKj5N+wovNKSjlkfgHyqkVFHRGTROg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS2PR12MB9752 Content-Type: text/plain; charset="utf-8" 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. Userspace is responsible for ensuring an STP daemon manages the bridge. 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, or set to the same value (-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/565B7F7D.80208@nod.at/ and providing a cleaner alternative to extending the helper into namespaces. Suggested-by: Ido Schimmel Assisted-by: Claude:claude-opus-4-6 Signed-off-by: Andy Roulin --- Notes: v2: * Add rt-link.yaml netlink spec update. * Allow idempotent stp_mode set while STP is active. * Move stp_mode next to root_port to fill a struct hole. * Rephrase BR_STP_MODE_USER doc. Documentation/netlink/specs/rt-link.yaml | 11 +++++++ include/uapi/linux/if_link.h | 39 ++++++++++++++++++++++++ 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 ++++++----- 6 files changed, 79 insertions(+), 8 deletions(-) diff --git a/Documentation/netlink/specs/rt-link.yaml b/Documentation/netli= nk/specs/rt-link.yaml index df4b56beb8187..15fb3b1cd51da 100644 --- a/Documentation/netlink/specs/rt-link.yaml +++ b/Documentation/netlink/specs/rt-link.yaml @@ -833,6 +833,13 @@ definitions: entries: - p2p - mp + - + name: br-stp-mode + type: enum + entries: + - auto + - user + - kernel =20 attribute-sets: - @@ -1543,6 +1550,10 @@ attribute-sets: - name: fdb-max-learned type: u32 + - + name: stp-mode + type: u32 + enum: br-stp-mode - name: linkinfo-brport-attrs name-prefix: ifla-brport- diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index 83a96c56b8cad..58727fbf81e56 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -744,6 +744,11 @@ enum in6_addr_gen_mode { * @IFLA_BR_FDB_MAX_LEARNED * Set the number of max dynamically learned FDB entries for the current * bridge. + * + * @IFLA_BR_STP_MODE + * Set the STP mode for the bridge, which controls how the bridge + * selects between userspace and kernel STP. The valid values are + * documented below in the ``BR_STP_MODE_*`` constants. */ enum { IFLA_BR_UNSPEC, @@ -796,11 +801,45 @@ enum { IFLA_BR_MCAST_QUERIER_STATE, IFLA_BR_FDB_N_LEARNED, IFLA_BR_FDB_MAX_LEARNED, + IFLA_BR_STP_MODE, __IFLA_BR_MAX, }; =20 #define IFLA_BR_MAX (__IFLA_BR_MAX - 1) =20 +/** + * DOC: Bridge STP mode values + * + * @BR_STP_MODE_AUTO + * Default. The kernel invokes the ``/sbin/bridge-stp`` helper to hand + * the bridge to a userspace STP daemon (e.g. mstpd). Only attempted in + * the initial network namespace; in other namespaces this falls back to + * kernel STP. + * + * @BR_STP_MODE_USER + * Directly enable userspace STP (``BR_USER_STP``) without invoking the + * ``/sbin/bridge-stp`` helper. Works in any network namespace. + * Userspace is responsible for ensuring an STP daemon manages the + * bridge. + * + * @BR_STP_MODE_KERNEL + * Directly enable kernel STP (``BR_KERNEL_STP``) without invoking the + * helper. + * + * The mode controls how the bridge selects between userspace and kernel + * STP when STP is enabled via ``IFLA_BR_STP_STATE``. It can only be + * changed while STP is disabled (``IFLA_BR_STP_STATE`` =3D=3D 0), returns + * ``-EBUSY`` otherwise. The default value is ``BR_STP_MODE_AUTO``. + */ +enum { + BR_STP_MODE_AUTO, + BR_STP_MODE_USER, + BR_STP_MODE_KERNEL, + __BR_STP_MODE_MAX +}; + +#define BR_STP_MODE_MAX (__BR_STP_MODE_MAX - 1) + struct ifla_bridge_id { __u8 prio[2]; __u8 addr[6]; /* ETH_ALEN */ diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index f7502e62dd357..a35ceae0a6f2c 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -518,6 +518,7 @@ void br_dev_setup(struct net_device *dev) ether_addr_copy(br->group_addr, eth_stp_addr); =20 br->stp_enabled =3D BR_NO_STP; + br->stp_mode =3D BR_STP_MODE_AUTO; br->group_fwd_mask =3D BR_GROUPFWD_DEFAULT; br->group_fwd_mask_required =3D BR_GROUPFWD_DEFAULT; =20 diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 0264730938f4b..f5b462a040b92 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -1270,6 +1270,9 @@ static const struct nla_policy br_policy[IFLA_BR_MAX = + 1] =3D { NLA_POLICY_EXACT_LEN(sizeof(struct br_boolopt_multi)), [IFLA_BR_FDB_N_LEARNED] =3D { .type =3D NLA_REJECT }, [IFLA_BR_FDB_MAX_LEARNED] =3D { .type =3D NLA_U32 }, + [IFLA_BR_STP_MODE] =3D NLA_POLICY_RANGE(NLA_U32, + BR_STP_MODE_AUTO, + BR_STP_MODE_MAX), }; =20 static int br_changelink(struct net_device *brdev, struct nlattr *tb[], @@ -1306,6 +1309,17 @@ static int br_changelink(struct net_device *brdev, s= truct nlattr *tb[], return err; } =20 + if (data[IFLA_BR_STP_MODE]) { + u32 mode =3D nla_get_u32(data[IFLA_BR_STP_MODE]); + + if (br->stp_enabled !=3D BR_NO_STP && mode !=3D br->stp_mode) { + NL_SET_ERR_MSG_MOD(extack, + "Can't change STP mode while STP is enabled"); + return -EBUSY; + } + br->stp_mode =3D mode; + } + if (data[IFLA_BR_STP_STATE]) { u32 stp_enabled =3D nla_get_u32(data[IFLA_BR_STP_STATE]); =20 @@ -1634,6 +1648,7 @@ static size_t br_get_size(const struct net_device *br= dev) nla_total_size(sizeof(u8)) + /* IFLA_BR_NF_CALL_ARPTABLES */ #endif nla_total_size(sizeof(struct br_boolopt_multi)) + /* IFLA_BR_MULTI= _BOOLOPT */ + nla_total_size(sizeof(u32)) + /* IFLA_BR_STP_MODE */ 0; } =20 @@ -1686,7 +1701,8 @@ static int br_fill_info(struct sk_buff *skb, const st= ruct net_device *brdev) nla_put(skb, IFLA_BR_MULTI_BOOLOPT, sizeof(bm), &bm) || nla_put_u32(skb, IFLA_BR_FDB_N_LEARNED, atomic_read(&br->fdb_n_learned)) || - nla_put_u32(skb, IFLA_BR_FDB_MAX_LEARNED, br->fdb_max_learned)) + nla_put_u32(skb, IFLA_BR_FDB_MAX_LEARNED, br->fdb_max_learned) || + nla_put_u32(skb, IFLA_BR_STP_MODE, br->stp_mode)) return -EMSGSIZE; =20 #ifdef CONFIG_BRIDGE_VLAN_FILTERING diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 6dbca845e625d..03e9f20181175 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -523,6 +523,7 @@ struct net_bridge { unsigned char topology_change; unsigned char topology_change_detected; u16 root_port; + u32 stp_mode; unsigned long max_age; unsigned long hello_time; unsigned long forward_delay; diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index cc4b27ff1b088..fa2271c5d84fe 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c @@ -149,7 +149,9 @@ static void br_stp_start(struct net_bridge *br) { int err =3D -ENOENT; =20 - if (net_eq(dev_net(br->dev), &init_net)) + /* AUTO mode: try bridge-stp helper in init_net only */ + if (br->stp_mode =3D=3D BR_STP_MODE_AUTO && + net_eq(dev_net(br->dev), &init_net)) err =3D br_stp_call_user(br, "start"); =20 if (err && err !=3D -ENOENT) @@ -162,7 +164,7 @@ static void br_stp_start(struct net_bridge *br) else if (br->bridge_forward_delay > BR_MAX_FORWARD_DELAY) __br_set_forward_delay(br, BR_MAX_FORWARD_DELAY); =20 - if (!err) { + if (br->stp_mode =3D=3D BR_STP_MODE_USER || !err) { br->stp_enabled =3D BR_USER_STP; br_debug(br, "userspace STP started\n"); } else { @@ -180,12 +182,13 @@ static void br_stp_start(struct net_bridge *br) =20 static void br_stp_stop(struct net_bridge *br) { - int err; - if (br->stp_enabled =3D=3D BR_USER_STP) { - err =3D br_stp_call_user(br, "stop"); - if (err) - br_err(br, "failed to stop userspace STP (%d)\n", err); + if (br->stp_mode =3D=3D BR_STP_MODE_AUTO) { + int err =3D br_stp_call_user(br, "stop"); + + if (err) + br_err(br, "failed to stop userspace STP (%d)\n", err); + } =20 /* To start timers on any ports left in blocking */ spin_lock_bh(&br->lock); --=20 2.43.0 From nobody Thu Apr 2 12:33:04 2026 Received: from BYAPR05CU005.outbound.protection.outlook.com (mail-westusazon11010014.outbound.protection.outlook.com [52.101.85.14]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 80495261B8A; Sun, 29 Mar 2026 02:59:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.85.14 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774753151; cv=fail; b=rGNpmhAyNk3qPf6QUQgEr3TRRUEFjMocjFh/GpF3AzQANzJetAd691Rb9YGE60QAjY0Xf93ddArQ8hGH9TkOF/sJCCnMeyp9rsT4uI+8HqUDxFcjauW1aYeN4ZS4oDVZ6rl27N2ye/d8HoLWmdNpW/5Vkm/Z+99iOQzPKyvj3PU= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774753151; c=relaxed/simple; bh=QYBJzJH65YB8tQo0SMmdHNgsWXD7WG7GicaFpOLQCjY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=BetPqmOTDZ+6kOwpS41sHN6fjYjdbJE9QEz4GI5GOEive8SDKZxkeNE7nkkNMQRsekxTVb6SJACStQrxYZhVJrfy4cn0Pa0n75E71mQiVDS0dvZYD6+/vdFkkNgDfrqGD5X8rnnh0tBzjaxZqsuR1DxlVMzAZs/r/zNHJiduVFc= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com; spf=fail smtp.mailfrom=nvidia.com; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b=PMhy8NHY; arc=fail smtp.client-ip=52.101.85.14 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=nvidia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b="PMhy8NHY" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=g0m7ivcSLwaPHRVNskbVtLFGbBW6D0ytOywlhBLvllTdw3H5ppzBTK+j2IqmDgFkHUxmHpkjdjxHo9b9masXII5isVR2mxdmYHQO0nO7FaNCTXohtdccstWwp+FYknOgmfATsHR5YasRIt7uRm/38cZmu1GHypho0hmmd4Q+o31XleGZsNdmRuXD/RHOolitfGTN5GJ4QCrrAo7ZpDIVvW3xKwtcuCgE6D2rx5/hC9cNUtsZyn9P+XUIZSUGBapNp8HCGHSMZzwWsat3Fb4c9yxN4r9lfMTVKCKG8rsWVHj2/P4WFi1loVT2Q1C/oxN3vL3EWqY9Pd0JXwxW3LAnMQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=iD8PZjXiC2vGg6dm1rUMnBsWJWEIsOc5KZEgfWkMl2o=; b=LHOltTWIT3VAK9bStjyHZJoV2wSOw/Q2ynSNVMxgTzLxMSq6q3eR6L/ttcwU09ShT7R1pfb1Rvuk0ZCMwLfgeQZHZgh61t4JYGpVAnD7YUCxXr1YmKQVMgQo1TYYvsin5r48E0EWU+imhUpr4wPSXkaCCJtX7DPBRH+cFHmwdHen6v3fMDFiSS99NrES8uxTyj1TlcN6fC7KOP5cGSCxjVTO3mwZFGtscZs9eZNOTP3Enr2qNmodoF3NgKderJjCe0BpnB984y37jQZyLRJJc2d7Rdocz9XsfX7tc2Ry7v6eKnFtcxcoJ+8Q+82GkVZSDoj19J1MqvrUMlPZ6YhTjg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=iD8PZjXiC2vGg6dm1rUMnBsWJWEIsOc5KZEgfWkMl2o=; b=PMhy8NHYP4464n3684Lwkt1LVrH1FHizGpxtS9HQ2ctaStOKCMNd1HX5dsYYZ/PoARtfP9VugXo/OO34xF6vE7XjTAP7PbMvUCXyIf6RLY1XfjUE6POIEezC47P3uiyjxUXw8dGmVrWLNdp0RFvbcaCX6XPUum9K2gB5v+H5weE3vGSreHCNXOTx/C7AaOr9uoNkLK06jvt/FhvGE8nliN5YXdxhYO7+IuD0hWtzrH0oFudgxzz6B9Fj9Ie4vDrBNpuCDUuY/KZ4bwR3mCnSa1D8f47ci1Y/6IEuAV+FicLnCDkGmM+mBBNwHYQU+FaaXG2Z22Pq+U1METtSSYs7wA== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; Received: from DS7PR12MB8202.namprd12.prod.outlook.com (2603:10b6:8:e1::13) by DS2PR12MB9752.namprd12.prod.outlook.com (2603:10b6:8:270::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9769.14; Sun, 29 Mar 2026 02:59:03 +0000 Received: from DS7PR12MB8202.namprd12.prod.outlook.com ([fe80::38fd:4146:aea:639e]) by DS7PR12MB8202.namprd12.prod.outlook.com ([fe80::38fd:4146:aea:639e%6]) with mapi id 15.20.9769.014; Sun, 29 Mar 2026 02:59:03 +0000 From: Andy Roulin To: netdev@vger.kernel.org Cc: bridge@lists.linux.dev, Nikolay Aleksandrov , Ido Schimmel , Andrew Lunn , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Jonathan Corbet , Shuah Khan , Petr Machata , Donald Hunter , Jonas Gorski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Andy Roulin Subject: [PATCH net-next v2 2/3] docs: net: bridge: document stp_mode attribute Date: Sat, 28 Mar 2026 19:58:57 -0700 Message-ID: <20260329025858.330620-3-aroulin@nvidia.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260329025858.330620-1-aroulin@nvidia.com> References: <20260329025858.330620-1-aroulin@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BY5PR03CA0006.namprd03.prod.outlook.com (2603:10b6:a03:1e0::16) To DS7PR12MB8202.namprd12.prod.outlook.com (2603:10b6:8:e1::13) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DS7PR12MB8202:EE_|DS2PR12MB9752:EE_ X-MS-Office365-Filtering-Correlation-Id: a7b91e3d-7877-42fe-762d-08de8d3f226d X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|7416014|376014|366016|18002099003|56012099003|22082099003; X-Microsoft-Antispam-Message-Info: YdskAeT9OP+TOdNDe7NMUqoU6Pjgno1Jv3659PRI+nTplED8R3S7PWlNdc7xPrcIcnEXltPs8FX7XW0S3sjzil0OOdg4rMtux2z5oJl558h8r+VCSxuZtgvW6KECdMMFRCoc71t2xtM8XIJyKqK74bMt2yKsrgzB+VxV8WilZhCtc0J4EUKH/hMtHMsYr6Nl8T5jEU2g/XwBQ9FzSjT2m1HZ/aoAemNcdsKkiA6IqvUP7jgnLCg4GddYEt9RnsT2wofEtsRxDQr2VrwhA2wxnivhPMrFHkltd1GpxrakBI9Cjctt9KCRqQYPpBcol8VRUfRFKuGr8N/qwhwD88GcEAG6TMixn4VO9mZ4AtzHMUiCedLhgegpEeV3cr/pD7oGVqR9NCJaSPufSu6ACee7hWGWwHAtBuWm03354hF3GdOptwyYqLoeONUs4KjkpI4nF1NdID9N0wC753iHRxIKOFuZrzl60ZCTMA09GWaIiwE9/Xde29DqXjoPMY7kL4NURj3PsNM9yYNoYJVe1ysv17ooZtpdmu1Iesz+sLtzcqfjNTJoL/sYStAb1CrmBeW6l/A0cmSVfEJy0G8a/2xlx+O1FFzfiVwQFoDqT4n9GmmZ2M4iuJrvBPOqy/y+tDjnnFZljsApw27PwwCqhd+f7KYerfaSG6pxOZME2nx+YfRiNb2pmI/UtQhy1tek8ndkGUJKd+giuT1P8e+iFWeU5MbN9/FKb1rZ5cVu/S45LCw= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DS7PR12MB8202.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(1800799024)(7416014)(376014)(366016)(18002099003)(56012099003)(22082099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?ufhVRxkK3xAW4liJB3aYD0tH0vJie8UkNWfu0Bxn6IdYBdCcmBQl8ynk8zyB?= =?us-ascii?Q?kHJLOnFUL/BVGnGrZUPz995pxiTM45WswE+Xh7YtKjBnnWzzLX0C0URSqCC0?= =?us-ascii?Q?J7rYOB1fg88st123x1LuYfr7E4X5N+KmP0qRhhhNn1XNjqTxkpMXkEFI/HFb?= =?us-ascii?Q?3cxQ4dg/H9WxtlkUSty3bY0vf5RrDPw+U1LQIGq1hnYIX1lJIHa5+qMWQtCn?= =?us-ascii?Q?aEZ0ZsXrBQL/GigcP0IP071mK5pkKkEnUYsTJBuaqAGDKBS495t/Jt1mlZrf?= =?us-ascii?Q?mTq+OZ2Fgj3YuTlfHYBnaqxVe+VBR7Ocisl55KAIw344Qvzvl3pOCXEjRZhx?= =?us-ascii?Q?bX8WrpNEnjV/z9bZFsN87Zz8KPpqdP93lcCsryxkMovFGFi9sYuwkxkrnMDT?= =?us-ascii?Q?n+U/Yxei9n6YK5+Faw6EhaFHEl4J8/TnbIEq2TjsEo68L7vKWmOAK2CkQ0XG?= =?us-ascii?Q?v1rTkWe2+8ElG5wNEYUsU4bKFLKn1dbdw4L0uQYTMtcF/9gJ6JN0OY2vIm/D?= =?us-ascii?Q?bIh+dtSpH/Sm2nrcNa3v7fAtVQB9lOEPWzS09sxfpsUU6McYgr9jMzMUkz5p?= =?us-ascii?Q?Js5ZOmEthVeUCuJ5ZIMI3PtWDOgSelkGDlf/VtsM/0uBebRxNN/3j0w6uvF+?= =?us-ascii?Q?tTfwoVaW4Y5T18uZH8u7/IMIjtMjYNMsscNLnIg7Vf51eWpNSlwj0DmZUK0j?= =?us-ascii?Q?YjDiQeB0wadVhjpxVXi8DU80m3moOUQOQ5nj9P1Ak+3raYVt0XGf7kLCYRHm?= =?us-ascii?Q?WFOdyE6KZgzjB5/8w/hqIhJTSup3P+8il049lTLFsrcDgQSPedO58sqEwcFF?= =?us-ascii?Q?1YCdN1tBhhnMq7+vefcyz67d5HELANzOiVKfAsoBkS+GfmVWTDRYBGZ7q1+s?= =?us-ascii?Q?sJjpAZZXjDtLArRIWUGEABY3VWwClYrkx+T+iMBsjiNcamHBhFtoH37rkzZz?= =?us-ascii?Q?uNPiaTaWwgSztsFcVDCkIBuh91vVFWTXS2dR0tsEpGrIt9MmFE9wQVlteZ/X?= =?us-ascii?Q?gnbSWup+89vMMWCX3BQwuapSV1vCSSONa0dvDFSVgSXJfCQnJ5t60YN8iNbc?= =?us-ascii?Q?Gf78EqnDCnxxiRDr+bB+r1zdpFDeb9n29314J6Kncb+5g3OgjZq4uNDekJ2b?= =?us-ascii?Q?f2ZvI+HzDF0Owgl4+2uWJU7HF8v4FCnJGwIPUVzLos48zUy7WfYGF3pawhn9?= =?us-ascii?Q?B4PpVgm/lxcFi0V6gkQdAYRyU5aNqhkocUvxlwvO4p26bG3SgO9bLKzU18BB?= =?us-ascii?Q?JQhU/vfsrg9SqEPjRvmcV0oYaRZdk6eNrhcamMtSHsEZB+FGLmwUSPL/9MR2?= =?us-ascii?Q?DxoTNi+OZ8OkMDdzNW6P40c6Q/f118pgRqctQCOfnsXmhv2NBZeIvm7tLhNR?= =?us-ascii?Q?SYyL4al/eqKEdgZa61UVjvuXVlDuneozYAzAEWfFjlchEQl+T8wR2G7uyaq+?= =?us-ascii?Q?OXboHZJVYg8HuCAW5PTGB2H4Wn6lMw1rO47C4cBal5OGLVDNalht+qO6s7Id?= =?us-ascii?Q?UOdkSUj9nNQZc+1jGuSAPctWLxZK4mq8CB8obLCJ+nqzqhmNZCGyEj4CyA+U?= =?us-ascii?Q?O+6xGGoC/LAGhqoxif3wffG9ATlxybebIyh/tFKH/RIPB77Vw+FtyYWe+DLa?= =?us-ascii?Q?AK50AWFr5jgK4W22QIc03itlDLU40R0i+cSHHomf4tiYKrESoGf9IA+ei/x4?= =?us-ascii?Q?OqAYwOWIRefDMW0pSao0Yv6d5hSY/rkME3bpf5pTPyeb8YYO2S1HRy/1b3E9?= =?us-ascii?Q?8DwSYGB0/A=3D=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: a7b91e3d-7877-42fe-762d-08de8d3f226d X-MS-Exchange-CrossTenant-AuthSource: DS7PR12MB8202.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Mar 2026 02:59:03.4766 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: x9rx2utqRMzPjbWDTWfxkyAYaHBU5SXqYOVv+u+oX2P3TDeY5TibTcytMBEnaRb61WFSV4dmc2slZYg4ddyaBQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS2PR12MB9752 Content-Type: text/plain; charset="utf-8" Add documentation for the IFLA_BR_STP_MODE bridge attribute in the "User space STP helper" section of the bridge documentation. Reference the BR_STP_MODE_* values via kernel-doc and describe the use case for network namespace environments. Signed-off-by: Andy Roulin Suggested-by: Ido Schimmel --- Documentation/networking/bridge.rst | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Documentation/networking/bridge.rst b/Documentation/networking= /bridge.rst index ef8b73e157b26..c1e6ea52c9e59 100644 --- a/Documentation/networking/bridge.rst +++ b/Documentation/networking/bridge.rst @@ -148,6 +148,28 @@ called by the kernel when STP is enabled/disabled on a= bridge stp_state <0|1>``). The kernel enables user_stp mode if that command retu= rns 0, or enables kernel_stp mode if that command returns any other value. =20 +STP mode selection +------------------ + +The ``IFLA_BR_STP_MODE`` bridge attribute allows explicit control over how +STP operates when enabled, bypassing the ``/sbin/bridge-stp`` helper +entirely for the ``user`` and ``kernel`` modes. + +.. kernel-doc:: include/uapi/linux/if_link.h + :doc: Bridge STP mode values + +The default mode is ``BR_STP_MODE_AUTO``, which preserves the traditional +behavior of invoking the ``/sbin/bridge-stp`` helper. The ``user`` and +``kernel`` modes are particularly useful in network namespace environments +where the helper mechanism is not available, as ``call_usermodehelper()`` +is restricted to the initial network namespace. + +Example:: + + ip link set dev br0 type bridge stp_mode user stp_state 1 + +The mode can only be changed while STP is disabled. + VLAN =3D=3D=3D=3D =20 --=20 2.43.0 From nobody Thu Apr 2 12:33:04 2026 Received: from BYAPR05CU005.outbound.protection.outlook.com (mail-westusazon11010014.outbound.protection.outlook.com [52.101.85.14]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7587926B973; Sun, 29 Mar 2026 02:59:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.85.14 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774753153; cv=fail; b=tvUPE5jDLA2trP0zivnme7s4vRCnnfFazgUEG3L4OJ3E7bQDyFchjiOyDFiupl3u8ha+RJrHf6QxkKNgDCLHXSGz0+noVk9pJEq+mJcdDh6HJLhUDCRuF+rsav69LBtjIRUbZIM02kLzG39VwUnvVwxlI8dmgqR3dGIw5JVaNAI= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774753153; c=relaxed/simple; bh=5jCkHkfSjmkcxCScj0qC0OeI0UhHSFU2V935Ptpi2hE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=iiecU/ofS6EuGx6zzqeiGU11BUEJ8yBhAi3Auwd8cd7NAZltdN3uuvw+eri1wKJGVHQeb5+Nfo4RrLvWYYNcROf4M3bpltQ7yKRIFfL6HF9dndnWkiKOUj8JQKNz4kYVFy7Q3FF+ieKL5oX0piApVO0DSbNiNxWsqy9xgpVcbgI= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com; spf=fail smtp.mailfrom=nvidia.com; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b=ri6zEgks; arc=fail smtp.client-ip=52.101.85.14 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=nvidia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b="ri6zEgks" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=E06khBxXDzcYpSIGEUaiqWhZX+edq+EGzexaal1SL0je5m7nSjHwoIMRZMemfht8rwDBezO0+f36PJRCttVOJm+RnymcNsI4bud/+Urye/ogl6p60T5OoU/AvGkBIkhEiY2s3QYKzhHnediX6RzgbadxzCwsnYEFT0MgnBdQ190UCUhcHSM66O3hvf0kIuvh3QmHd85cqRFh2nTIn5NJRfBY0vcRkJ8lKD5KuWEJ3AnlSTYHxgKSw/4bzv3ICV2BGDAd1/WWBjA2xqdMr6RUEksdbzxPNIGJiS+naqeZ6bSDYhh+IChjoCebXZcY1KXsFb3StpdP0hpo+j+E/LVs4w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=pWhkJlaLx+gijcnZVU3Eudd72WmH6c0h+KLOfObRjtE=; b=KM9AlOO/BCuGWeiPm81w7NqnsXRUgDDGzuXRsnTXt7fLC/PdbyKZbVnTZ7Q/JmE8Seltm7ibB2euUAO14BZstLz0bVDG9zeqyOvqDJFtn96vTkY/Ka1xFKjVoTUMd3PPO00OJPC12BSULP9o9CbAZTlllLH2AUGUjyK3FG1elYZGxZR+h/dyORlBT7UaQHptUxZMFsRw/t4OiVaXifUutGsFb9vN5Q/7E3AMGVwqReQ/woAKD/ww3GgzMpLh8OhHbshDlxEAGQXIQcByk/AYVGHotTctFWYB68wAkISS8JOUZ6tGzA8+J9tHgVzPQbd0axElKnwYHaqalKQpL1tx6Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=pWhkJlaLx+gijcnZVU3Eudd72WmH6c0h+KLOfObRjtE=; b=ri6zEgksC0k9Oeiu7ANbg7aKLjKhM6Y8NjauL2oneYS6H0OkUfQdvGkd/QMwvge0l3eqkKxOULlVWwcnWX6L/UIJqeZh6xxcYeKS7FddnemG0VFFJNiuSQ5G/2fPEBE9fSKq/hlFAlqKWzUa5HZm+iaQCHMFDvyD7VDgAoAw83X8KOrgJWifSVgctQ3kjJvDJS8PKSHN2Icwy2+DyOfg4tpghQs2WMOzXSFJu0qjdjzZM5lsiTi15JxCF69a7Qdw+Fa0INTyaBLyjMkVS1PJF/zxIbc288y723JQFOk4MQXbvBVhySBDBxmTOmBPhDDmkGl/h6mpZgsAjqlDx5zRnw== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; Received: from DS7PR12MB8202.namprd12.prod.outlook.com (2603:10b6:8:e1::13) by DS2PR12MB9752.namprd12.prod.outlook.com (2603:10b6:8:270::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9769.14; Sun, 29 Mar 2026 02:59:05 +0000 Received: from DS7PR12MB8202.namprd12.prod.outlook.com ([fe80::38fd:4146:aea:639e]) by DS7PR12MB8202.namprd12.prod.outlook.com ([fe80::38fd:4146:aea:639e%6]) with mapi id 15.20.9769.014; Sun, 29 Mar 2026 02:59:05 +0000 From: Andy Roulin To: netdev@vger.kernel.org Cc: bridge@lists.linux.dev, Nikolay Aleksandrov , Ido Schimmel , Andrew Lunn , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Jonathan Corbet , Shuah Khan , Petr Machata , Donald Hunter , Jonas Gorski , linux-doc@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Andy Roulin Subject: [PATCH net-next v2 3/3] selftests: net: add bridge STP mode selection test Date: Sat, 28 Mar 2026 19:58:58 -0700 Message-ID: <20260329025858.330620-4-aroulin@nvidia.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260329025858.330620-1-aroulin@nvidia.com> References: <20260329025858.330620-1-aroulin@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BY3PR04CA0027.namprd04.prod.outlook.com (2603:10b6:a03:217::32) To DS7PR12MB8202.namprd12.prod.outlook.com (2603:10b6:8:e1::13) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DS7PR12MB8202:EE_|DS2PR12MB9752:EE_ X-MS-Office365-Filtering-Correlation-Id: 855946a0-f7af-478a-f13f-08de8d3f2370 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|7416014|376014|366016|18002099003|18092099006|56012099003|22082099003; X-Microsoft-Antispam-Message-Info: kbTTAGlN4+15OAqe7wWwZGIQAA/+7rn7PfaDbY8xFyABbGOp9XKd1sO0mDrp8f1i03ANqMbZX3VphtZMk+9KOAisXaJhsiJmTPNHQ9b31Sw9lJr0F+mFU0O9dXQeM/f7sowOYAc1lfD0dzFMSB8MKzbXz2BNSvhkLnFYLbINlNd3k4EIV7fBf8MpSD9NM2220uvnwpKG8KPxkVukMHLRfaA0uh++42Xbrid07YdJtLRzbFELspM138KycafrhisYK874PGgzKGQpZRS2krPClR7UsD3QRFnupDuDCn6HC4V/bUprduedZlujTuo6oLA2XndMdN5zTADWOakWa6gYAVcLyy0bq2iX9GDlN6umfyWtcdtU8m6rRDL698JEthOgR5blZUJQ7ifbmrfuSw/uEvYwZfPEI3czIzySpm5nMp+Gmo458CXX/E5/Hn0dJD93Cx0kT832yI5ji4nISYDafFt57qhraTNLvBCNYfmeddqxiw80ZZJaJv54Fh0Jx9x22OpwDntx1PqPRVrKuWKjnXPrrtlouLEwTB0Rm2GQalCbc5sUVAH1ADBIhjz9zAlrq8uMYHZAYBaqZfRnjoLbarG0AqJkqPJAxP8BEKX8S/K7E+I36CsYFM3TwCaa0IO0Hok+EYFk4Qz9VJ5kCV3GIx7fn5Zl4GIFCaz2q8pYMD5MNllRg3ozDeEuEcVl40HmIJs6liJsf+B0dPcI02sGGqOR04RWJHnymhaMx3SgUDI= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DS7PR12MB8202.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(1800799024)(7416014)(376014)(366016)(18002099003)(18092099006)(56012099003)(22082099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?BIpkVkz53UuJ/OZCkGYiO/AbtQfR1B4YDc18F5R3x5PTkgHKSQQna5bDcfhl?= =?us-ascii?Q?dtRney3XR7CADP46D2et3x2/PllJ++Ju56UooP1yhafWgKjt1lxoUDQ8yjRt?= =?us-ascii?Q?VYSmlinI1OgXKwdnNedQSD2KzWSf7NBtkXRAri2alEJjaMXCNE+IYO2TPpcb?= =?us-ascii?Q?KYJsHKNfGVpHM5z9DZ2E1k2BoXCzK//Jb3vzLZIXFNjftXee4vRUUa+alSr4?= =?us-ascii?Q?Z0it79QCPOcutoNMR2hbCr1oKIkP8CwO/2DBuROMBiJrX25Ny8YMQD1FNhuZ?= =?us-ascii?Q?YM2xBE+GEVF3h4Zs1IyRK40jbjq6ict5sgIkq83ys5+/m1t93s1Zi1LmmspX?= =?us-ascii?Q?8Tqwfs1D0NGuc2Zj/ECSAYbjo39Jb0mGQZo3OcxdOl3AX6fhNqQdz/6gG9BN?= =?us-ascii?Q?xy0/cLkbcg9ksQ+heuHyMrYGHo6qryZ584csiKJJPHkFgYy2Zuc9jBC82a4P?= =?us-ascii?Q?Qad0YVb9L7DkOnLprqv/9AD84TqsmpDE55Vev53av1agZvelaqFPSJ/p7+xU?= =?us-ascii?Q?8AhH4yE/3v0g8b+Wn4sq/iBbnAeItOvS0TMO+bMHnYezMKSd387FaEvUJ3kT?= =?us-ascii?Q?q19QcRgqg6RTc7puI1ElRl+Tsb2mEn4DB05tDwzVGabIZFzKBW95F9SDgK2b?= =?us-ascii?Q?GkWpemlrPcLu2SqyK6drGJ0lxlS29q8bdOHpAwIBaaxaitm7sZlQ/pppiUEH?= =?us-ascii?Q?zn9oJrNtKDkGdPKz9ghGg8CB7qLOhGsGpC2sHRwaJzImRWYKcLyVcoZq+NaX?= =?us-ascii?Q?GQxbBb9h9o7g4iOZFwtvsWK673Vx7eJ7IuYXvOr5jynTriimWcCBSBsiTE3R?= =?us-ascii?Q?bR2+4oKs4wBUf7iMi8mXgekc/3XeLGjJyFWWYJ0yUODb5sPADev2VGI/dRQl?= =?us-ascii?Q?6Q+K11IBuPtITJw99zN908DrhlHWNXKKQUPmYtx0v6T4mmpW0uCjKg4yKWUv?= =?us-ascii?Q?i0IduUBR31smH6ZL8Q2Xt9YkT2O2CBfWASslivSi/+OPtvdUpd2bPbX+gPZY?= =?us-ascii?Q?XemV8XwxF6B4qGjEh3yOgY5e2hvN9zFa6bNrKJb0VS14CFJvlmmDkWXJGVqq?= =?us-ascii?Q?0GTLtuWrjd42c5cevZ9fnfR8V1ThVSgXQbHNNBje2FaFRAQzEPT6ng700iGb?= =?us-ascii?Q?XFIFPi6MJ4E5wx+xkGSuubIIKF0N77Hb8WIPx5f1n8Ho1J0LhHzm4yxkSKGg?= =?us-ascii?Q?W1fWXqwduvMNbgo4pVZAU2txX3txIYmRthfcvo1qxLBAkahGtginwj8jbNL0?= =?us-ascii?Q?WDkuUYPgrLJ/ib+tXKK3MBt6tLq13JE9he1kYL3rokki4bp8PWdtIvSeXyKr?= =?us-ascii?Q?oXydp0LAbqsMrv9JdmpZXyZe7ChN/YJ8Bto3ncnozmg8yWnh8Nxu6O0qUXSk?= =?us-ascii?Q?jAq6M0lIYs9IyEpBIE6OUF6RJjdSjNmMP843nk3Emr/5u0LSw7d/4lDJcE5m?= =?us-ascii?Q?/sBhlru3XVBrYMbcQeFgkclxuyfR6Lx0ebkvMg0MuuDAULV4xRz8n6xtQYQa?= =?us-ascii?Q?+F0BZO1YKhoXD9D3wkWbs4Y85zm16DGSQSLLmjDU0eScEiaa9D7JG+rie0WO?= =?us-ascii?Q?YaGjpD+IWwmDlqzeor3jIaBxyPl2fj/NzFvrBxssCmq0Zd3zcy22l882/FPK?= =?us-ascii?Q?TXM91aAeNvQZfPWV0JDe2PV5P+Oyy2XmQTe6DBot9HhPR6yilZbHk76GxlIh?= =?us-ascii?Q?Z0Xgfa73dHWCJKtBn9f5RvikobaXBX1N3a2qWT+zBhLafabZbRYje5V5KTIC?= =?us-ascii?Q?eFvd2ni2jg=3D=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 855946a0-f7af-478a-f13f-08de8d3f2370 X-MS-Exchange-CrossTenant-AuthSource: DS7PR12MB8202.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Mar 2026 02:59:05.1648 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: A0RSsq9/AN1p8avZ5axJn06BOX50vBbPGwP6tUPPy/NfP2nNldWnXxZrrjo4e9Ghh1CdKKkWn873bcg4POaMQA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS2PR12MB9752 Content-Type: text/plain; charset="utf-8" Add a selftest for the IFLA_BR_STP_MODE bridge attribute that verifies: 1. stp_mode defaults to auto on new bridges 2. stp_mode can be toggled between user, kernel, and auto 3. Changing stp_mode while STP is active is rejected with -EBUSY 4. Re-setting the same stp_mode while STP is active succeeds 5. stp_mode user in a network namespace yields userspace STP (stp_state=3D2) 6. stp_mode kernel forces kernel STP (stp_state=3D1) 7. stp_mode auto in a netns preserves traditional fallback to kernel STP 8. stp_mode and stp_state can be set atomically in a single message 9. stp_mode persists across STP disable/enable cycles Test 5 is the key use case: it demonstrates that userspace STP can now be enabled in non-init network namespaces by setting stp_mode to user before enabling STP. Test 8 verifies the atomic usage pattern where both attributes are set in a single netlink message, which is supported because br_changelink() processes IFLA_BR_STP_MODE before IFLA_BR_STP_STATE. The test gracefully skips if the installed iproute2 does not support the stp_mode attribute. Assisted-by: Claude:claude-opus-4-6 Signed-off-by: Andy Roulin Suggested-by: Ido Schimmel --- Notes: v2: * Fix shellcheck CI: add SC2329 suppression. * Add idempotent stp_mode test. tools/testing/selftests/net/Makefile | 1 + .../testing/selftests/net/bridge_stp_mode.sh | 281 ++++++++++++++++++ 2 files changed, 282 insertions(+) create mode 100755 tools/testing/selftests/net/bridge_stp_mode.sh diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests= /net/Makefile index 6bced3ed798b0..053c7b83c76dd 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -15,6 +15,7 @@ TEST_PROGS :=3D \ big_tcp.sh \ bind_bhash.sh \ bpf_offload.py \ + bridge_stp_mode.sh \ bridge_vlan_dump.sh \ broadcast_ether_dst.sh \ broadcast_pmtu.sh \ diff --git a/tools/testing/selftests/net/bridge_stp_mode.sh b/tools/testing= /selftests/net/bridge_stp_mode.sh new file mode 100755 index 0000000000000..5737a10f002f0 --- /dev/null +++ b/tools/testing/selftests/net/bridge_stp_mode.sh @@ -0,0 +1,281 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# shellcheck disable=3DSC2034,SC2154,SC2317,SC2329 +# +# Test for bridge STP mode selection (IFLA_BR_STP_MODE). +# +# Verifies that: +# - stp_mode defaults to auto on new bridges +# - stp_mode can be toggled between user, kernel, and auto +# - stp_mode change is rejected while STP is active (-EBUSY) +# - stp_mode user in a netns yields userspace STP (stp_state=3D2) +# - stp_mode kernel forces kernel STP (stp_state=3D1) +# - stp_mode auto preserves traditional fallback to kernel STP +# - stp_mode and stp_state can be set atomically in one message +# - stp_mode persists across STP disable/enable cycles + +source lib.sh + +require_command jq + +ALL_TESTS=3D" + test_default_auto + test_set_modes + test_reject_change_while_stp_active + test_idempotent_mode_while_stp_active + test_user_mode_in_netns + test_kernel_mode + test_auto_mode + test_atomic_mode_and_state + test_mode_persistence +" + +bridge_info_get() +{ + ip -n "$NS1" -d -j link show "$1" | \ + jq -r ".[0].linkinfo.info_data.$2" +} + +check_stp_mode() +{ + local br=3D$1; shift + local expected=3D$1; shift + local msg=3D$1; shift + local val + + val=3D$(bridge_info_get "$br" stp_mode) + [ "$val" =3D "$expected" ] + check_err $? "$msg: expected $expected, got $val" +} + +check_stp_state() +{ + local br=3D$1; shift + local expected=3D$1; shift + local msg=3D$1; shift + local val + + val=3D$(bridge_info_get "$br" stp_state) + [ "$val" =3D "$expected" ] + check_err $? "$msg: expected $expected, got $val" +} + +# Create a bridge in NS1, bring it up, and defer its deletion. +bridge_create() +{ + ip -n "$NS1" link add "$1" type bridge + ip -n "$NS1" link set "$1" up + defer ip -n "$NS1" link del "$1" +} + +setup_prepare() +{ + setup_ns NS1 +} + +cleanup() +{ + defer_scopes_cleanup + cleanup_all_ns +} + +# Check that stp_mode defaults to auto when creating a bridge. +test_default_auto() +{ + RET=3D0 + + ip -n "$NS1" link add br-test type bridge + defer ip -n "$NS1" link del br-test + + check_stp_mode br-test auto "stp_mode default" + + log_test "stp_mode defaults to auto" +} + +# Test setting stp_mode to user, kernel, and back to auto. +test_set_modes() +{ + RET=3D0 + + ip -n "$NS1" link add br-test type bridge + defer ip -n "$NS1" link del br-test + + ip -n "$NS1" link set dev br-test type bridge stp_mode user + check_err $? "Failed to set stp_mode to user" + check_stp_mode br-test user "after set user" + + ip -n "$NS1" link set dev br-test type bridge stp_mode kernel + check_err $? "Failed to set stp_mode to kernel" + check_stp_mode br-test kernel "after set kernel" + + ip -n "$NS1" link set dev br-test type bridge stp_mode auto + check_err $? "Failed to set stp_mode to auto" + check_stp_mode br-test auto "after set auto" + + log_test "stp_mode set user/kernel/auto" +} + +# Verify that stp_mode cannot be changed while STP is active. +test_reject_change_while_stp_active() +{ + RET=3D0 + + bridge_create br-test + + ip -n "$NS1" link set dev br-test type bridge stp_mode kernel + check_err $? "Failed to set stp_mode to kernel" + + ip -n "$NS1" link set dev br-test type bridge stp_state 1 + check_err $? "Failed to enable STP" + + # Changing stp_mode while STP is active should fail. + ip -n "$NS1" link set dev br-test type bridge stp_mode auto 2>/dev/null + check_fail $? "Changing stp_mode should fail while STP is active" + + check_stp_mode br-test kernel "mode unchanged after rejected change" + + # Disable STP, then change should succeed. + ip -n "$NS1" link set dev br-test type bridge stp_state 0 + check_err $? "Failed to disable STP" + + ip -n "$NS1" link set dev br-test type bridge stp_mode auto + check_err $? "Changing stp_mode should succeed after STP is disabled" + + log_test "reject stp_mode change while STP is active" +} + +# Verify that re-setting the same stp_mode while STP is active succeeds. +test_idempotent_mode_while_stp_active() +{ + RET=3D0 + + bridge_create br-test + + ip -n "$NS1" link set dev br-test type bridge stp_mode user stp_state 1 + check_err $? "Failed to enable STP with user mode" + + # Re-setting the same mode while STP is active should succeed. + ip -n "$NS1" link set dev br-test type bridge stp_mode user + check_err $? "Idempotent stp_mode set should succeed while STP is active" + + check_stp_state br-test 2 "stp_state after idempotent set" + + log_test "idempotent stp_mode set while STP is active" +} + +# Test that stp_mode user in a non-init netns yields userspace STP +# (stp_state =3D=3D 2). This is the key use case: userspace STP without +# needing /sbin/bridge-stp or being in init_net. +test_user_mode_in_netns() +{ + RET=3D0 + + bridge_create br-test + + ip -n "$NS1" link set dev br-test type bridge stp_mode user + check_err $? "Failed to set stp_mode to user" + + ip -n "$NS1" link set dev br-test type bridge stp_state 1 + check_err $? "Failed to enable STP" + + check_stp_state br-test 2 "stp_state with user mode" + + log_test "stp_mode user in netns yields userspace STP" +} + +# Test that stp_mode kernel forces kernel STP (stp_state =3D=3D 1) +# regardless of whether /sbin/bridge-stp exists. +test_kernel_mode() +{ + RET=3D0 + + bridge_create br-test + + ip -n "$NS1" link set dev br-test type bridge stp_mode kernel + check_err $? "Failed to set stp_mode to kernel" + + ip -n "$NS1" link set dev br-test type bridge stp_state 1 + check_err $? "Failed to enable STP" + + check_stp_state br-test 1 "stp_state with kernel mode" + + log_test "stp_mode kernel forces kernel STP" +} + +# Test that stp_mode auto preserves traditional behavior: in a netns +# (non-init_net), bridge-stp is not called and STP falls back to +# kernel mode (stp_state =3D=3D 1). +test_auto_mode() +{ + RET=3D0 + + bridge_create br-test + + # Auto mode is the default; enable STP in a netns. + ip -n "$NS1" link set dev br-test type bridge stp_state 1 + check_err $? "Failed to enable STP" + + # In a netns with auto mode, bridge-stp is skipped (init_net only), + # so STP should fall back to kernel mode (stp_state =3D=3D 1). + check_stp_state br-test 1 "stp_state with auto mode in netns" + + log_test "stp_mode auto preserves traditional behavior" +} + +# Test that stp_mode and stp_state can be set in a single netlink +# message. This is the intended atomic usage pattern. +test_atomic_mode_and_state() +{ + RET=3D0 + + bridge_create br-test + + # Set both stp_mode and stp_state in one command. + ip -n "$NS1" link set dev br-test type bridge stp_mode user stp_state 1 + check_err $? "Failed to set stp_mode user and stp_state 1 atomically" + + check_stp_state br-test 2 "stp_state after atomic set" + + log_test "atomic stp_mode user + stp_state 1 in single message" +} + +# Test that stp_mode persists across STP disable/enable cycles. +test_mode_persistence() +{ + RET=3D0 + + bridge_create br-test + + # Set user mode and enable STP. + ip -n "$NS1" link set dev br-test type bridge stp_mode user + ip -n "$NS1" link set dev br-test type bridge stp_state 1 + check_err $? "Failed to enable STP with user mode" + + # Disable STP. + ip -n "$NS1" link set dev br-test type bridge stp_state 0 + check_err $? "Failed to disable STP" + + # Verify mode is still user. + check_stp_mode br-test user "stp_mode after STP disable" + + # Re-enable STP -- should use user mode again. + ip -n "$NS1" link set dev br-test type bridge stp_state 1 + check_err $? "Failed to re-enable STP" + + check_stp_state br-test 2 "stp_state after re-enable" + + log_test "stp_mode persists across STP disable/enable cycles" +} + +# Check iproute2 support before setting up resources. +if ! ip link add type bridge help 2>&1 | grep -q "stp_mode"; then + echo "SKIP: iproute2 too old, missing stp_mode support" + exit "$ksft_skip" +fi + +trap cleanup EXIT + +setup_prepare +tests_run + +exit "$EXIT_STATUS" --=20 2.43.0