From nobody Mon Apr 6 11:51:44 2026 Received: from BN8PR05CU002.outbound.protection.outlook.com (mail-eastus2azon11011056.outbound.protection.outlook.com [52.101.57.56]) (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 4046C382F1F; Sun, 5 Apr 2026 20:52:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.57.56 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775422353; cv=fail; b=fd6AmgL13TSTaO09FC1mMQtOrVlTfumSWIB93CBwM7PHAUoWwoPhuuq2sslGeBpcNbEOHC5WjudQxhrJFjOQ4/jdBEpjBbSDz9eqXmuCpJlahBWCSuLY4oq5w3DKEqLYNYlnE4cuvmHbtnPhxa8dotkXcSBvh70KsmgmahQR25o= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775422353; c=relaxed/simple; bh=Fee1vMZvAuGQ+EfNLsUV4Ei4fYleIw/O+Z8Lu6riMLk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=O9siIxnJ7oiLB/TyJffrAKUvm6Dq7/x39uLWa4XTJr8MVIV65TDJxCHkCJq3Bpr0bRNs4VMqM+34SitvmNN+2gFmjB0GgiLOWK8LjGZ+e828RAo2qzxman8cYim8HPAYLwvja5b2n8LzhK6AsVLpnNYv1V8oKaRnK7GAxM8+lyE= 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=mn3Pf5f7; arc=fail smtp.client-ip=52.101.57.56 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="mn3Pf5f7" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=nyHSrO5M3ogJ/N8tk+HVpwXw2h7vEdye7A1wSn73SVmUDO9/VvLWMkF1Y5W/9v+stbFrmfhIU+2h2/9xlVW3bDXuEwY5rl/OodpYtBVHLT3gMwqzcKsurB9BAEIIUgsktpoiBCU9MJaxPdKkuMBe2wJWRyb1UcRXMPh7UOSSt1OBxEvaLbkD0GXxoyRrTBkFd8YXU65gFpT2QAlkAhEhOzRDQXoPT/sP9T41LF0k0s3U7fgK5bqO+f0r9tqd+AQlhm9VRfpfMawNZWjEDSBt/F9S7flwIS1G6vPS/9rr3uAhwpdr3XQk8c7tJtCN1mibiMvJmMpnv3MCAZR2k/H/+A== 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=k0BRg1fv40I035l3aZzAKgIRnWsr3oWjMBhhxfomsr8=; b=PBBdWC+rtdJOKGv9TRr1iacZGlmKAGMCQy+mIc27VM47epZ9ZJDIjrTHs4MznLqhS9ZER5FJqvm0lTwuPqGtBkxL20sxdJCVpNb9/sZfm3NyAvx5HTjg+OjuPsgXcY/ssVB7HejAiUrydgYPRCkx4po5odeiQ/Vp7jjlH7E8dpqFj8R0XI0BI5RnMovCnQfy3DQ9EEK0uR4qVMsjv3mK9Ac+m3ApD4Ylu3rSXaeE+q8nFLwPxDMEedBJszdgeQyxHOoDjJI0EJM/wGUFoYfK5AMdvLIG8r6yH0SI3YprFPK19jxtQ5sSoL9Wtr32w6wBZZx2VOf1QAqMBmjlgotcqA== 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=k0BRg1fv40I035l3aZzAKgIRnWsr3oWjMBhhxfomsr8=; b=mn3Pf5f7fhtZAWfX/piSuCiWiiCanypzPmqNCpGEHULnlQhGAIUqKCg/ScJBE4cx0FFE1pJbHoFNIV8CPTKh6WU4gkWR1gQFOFhatbh8LrXAuoBU4rYiXO7EjNR3PqjQ4IV4ooFnqbwD10sNxQS14aDTSlK0u2B98gX8faz6QwFl0tmIKUtqj+tSEYYwI4L/KZj+16eTr/N9JDTRTktl59dJuw3hwM8y/sb77N19ZCv4Vk5IO3vQ+Xtzo86mkPLMOXAiGI3vlhoSUutALlJicbR4qDZiSaVC7cXpql8npUrdJencdntysBpXcZ6h13rHfCv561GIQlEcHBFv/Rjgug== 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 SJ2PR12MB8807.namprd12.prod.outlook.com (2603:10b6:a03:4d0::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9769.17; Sun, 5 Apr 2026 20:52:27 +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.020; Sun, 5 Apr 2026 20:52:27 +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 , Nikolay Aleksandrov Subject: [PATCH net-next v4 1/3] net: bridge: add stp_mode attribute for STP mode selection Date: Sun, 5 Apr 2026 13:52:22 -0700 Message-ID: <20260405205224.3163000-2-aroulin@nvidia.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260405205224.3163000-1-aroulin@nvidia.com> References: <20260405205224.3163000-1-aroulin@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BYAPR08CA0043.namprd08.prod.outlook.com (2603:10b6:a03:117::20) 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_|SJ2PR12MB8807:EE_ X-MS-Office365-Filtering-Correlation-Id: 010714e4-4ad5-476c-1abc-08de93553f5a X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|366016|1800799024|376014|7416014|22082099003|56012099003|18092099006|18002099003; X-Microsoft-Antispam-Message-Info: B7HhRPN8qQVNeiFvkRsSUsbnVZoLWl8P0a3fQPoz+pTKe67qeQlTOIYwB/G1Tlzo1bBfW1TQtzwu8l779uMLSJtUtrLcp7Z/CtmW2CCME2dtm9Vh5Gf5Qc8UDX2MDZmSKjFXpS9JY8RSS8IYBroylhmpbYE0mqvZRsaW2vbt8m6EHs0PdPBu9IYEeaOBCOOpHJJsLZ43sPrE8Ah/Ye4hmldz9cJCOHPVuqnNSYQDHbJUOXZpExOP2bFiOHosmX/+xIsoDQGxXcHwf8GCAENVgmMkIN8AbA+Xf+YniqnUTrOG0OyI+vVww2Im5ve4/4tWwFarolJxr07x4IGVouDZKUlj4hzKpKIoVrpbGvm8+UkAbVRf48UJozW5LXv2P4Gx9JOgrpONbG3QoMUdIQTBDp4eY5EC072OhyUjwUlMi0TO9qYmagKz/t+3OjYh49gcnTxUHLDkJytdET9Q88NtM5r7bbCPyZ+74FX0WjzcahU9Nu7+u+8xp2t7qFb8Adjb06UBcJylTo1btbUIzZLSX4jgyXRFXHOy2Uor8S+5oepflj4B7ez8iDMp/AUZbQ7dVVJaVODsm0nLUA8eWSUs4MRg7CjTugQ+2lmfnuMO1O+2cgI8yxmg2p7rAUrlH6T23p1lNC7r2dhnwccrmaJuR1Lxtw3AdnvEzBel3CrA80a4idiNPucIuL6aogNNnXcp969R3XfvvwplIYacdfvEXOAzrp5Nugnw1yRQe1nVez8= 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)(366016)(1800799024)(376014)(7416014)(22082099003)(56012099003)(18092099006)(18002099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?SBohUg7C5KqCv2YFMRewJVlTY2DEz160sdJRDstpYEsWRA+gqsAl9Ad0/UGG?= =?us-ascii?Q?ZjbHuKnVcra8ACc07G9xxxuhvcsroVnCaGLXQx2zbR8OPgbXJgqKTmAFesLr?= =?us-ascii?Q?K3FLgsxUew9/VjZpGg9WDrNjP664bCDuU3fNhi+vG63fxr+tHGiwpwSVh2/S?= =?us-ascii?Q?21g6L0LYaQjHQClKJoX6OSwV0uzHC6KLF+gdECLzcVTzm7tOHun66UZDxU+G?= =?us-ascii?Q?6gbmT0dzCoP0qkONxaqR+K4nEiZQbH1OadId/wk0kMccob2ss/c1tQLMl2f5?= =?us-ascii?Q?8k6EwArnJkSjlA4eamKeF2B98cBYgxnHW2D1AN6zbKTO3r9H2upXiuDmcWsg?= =?us-ascii?Q?OyHwtfjn3FODQ8PPgZf/ohU2qDkE0mXFBdC8fwluRUoC0aXXN15j4ce3sUnn?= =?us-ascii?Q?mfazVUwWew1xQR9N5bU+hhV6871OJtrndPn62X0NXgzg80OLYBQhuieJ7uXm?= =?us-ascii?Q?8zgyi+aHswFmrie29N8XDhVxCLnnChwaPpQL665K1XNf9vFuUIyutWSQ0AIr?= =?us-ascii?Q?ziihy0nIxuWaeWHT/+KI5+5/IxRgWN8V3xrmZCAShK2s/Vizw9bVXS0O+6j4?= =?us-ascii?Q?+ir7M6CVk0eSpkA+kaL7kqbd0p6qSvG+CZEmYDw+pHWGq3VNm03CmZraW4Cy?= =?us-ascii?Q?DFdiN/wezP7XqdEDp0YKC/xrMTfmHk00syrF/o4ztb+7KYwljXFF4jegcgJ0?= =?us-ascii?Q?/wqvVzOE+pU1VwMYFCd90xjvKiyLpflw2dkU6Hm8YX/nHvOjPGCdBDSZ/KPR?= =?us-ascii?Q?67AI1doS9b/rS25km3xlrFxkSi/eWuTITd5Q2YQdWPVIe66LHW+zSdzIDMxi?= =?us-ascii?Q?Y94F5pHQmCqVBJo4osZEqK/zMiyHYWZMeR6kY4rJlM26RekYiQeBapwt+7bR?= =?us-ascii?Q?cfjuK+9XrYfTrAW16im62gxAdu2RgM5JIQh6VL/GmxpXNxjZMpYwXrlyBCrU?= =?us-ascii?Q?uzlmgO1J+C+NRL/vjymeAh8Q/V9ywOJNQZZ4YklXOKtnOKQBBW165oHXGXKB?= =?us-ascii?Q?Mo1D/YOaZ81l8wlygozZfeLDolvL0C4Ul7qKJhqd62PXeshf7aoNj5gd79qC?= =?us-ascii?Q?8phRLhCK98PRniKilEjRN/lLmwavBJV6JSP6QigHoa63wxewe9ShZQ7bM9l+?= =?us-ascii?Q?aZpTEHBxMv6erblZIsWIP3b+2Cj4cKOMKjvq3Ic7E6VN52SkEY7blkJD1V/q?= =?us-ascii?Q?MB0JHq7CQgYYhkSg+6W4Sq39Va6Mdys42TzVNsWGcaxV1uW08rKNZT09cJKO?= =?us-ascii?Q?5lajy1sibExl0sOZPNrYWmL3k7062nJPrFH8UKSU42W7lEFbsj5tMdsQkXRn?= =?us-ascii?Q?yL8qL9eGdDv9z/Z0l/AWOGWEHd/uphl6zSUr537SaFm4DjQb5yURvMmEoDws?= =?us-ascii?Q?rb+Ynah6jSHwOWk1g25N7uJA+qwrWqeDvWKa4VLrBaBhgukMxH2CAkqk0W68?= =?us-ascii?Q?b14FCy9IzcfHu6IuYQwzaDtSOVduIUz0Yh3KeINRIkTOryip8QghYRjjAtJD?= =?us-ascii?Q?WGVNOrdxREsIakYeMLim3RG9S6clsbQm/obKC9Pl1RAEFJeVQbLu3kX+y3jV?= =?us-ascii?Q?ihl/ovDqNcreNLdFI1cejTBAosM7ph9DMu0JykUoXseRrPmrhEwlPA/hDhT2?= =?us-ascii?Q?ciwJ0wGJArQtLgYJ4aYI1dYil7FK9DvfuisVK8Q9Hr5SKU1yBe+CXj1JCRmz?= =?us-ascii?Q?MvdiaW/Cakw9DouHpygibZPzH6Nnmzz2Zv7g79E6N5bHMfhr2zBZ9s3mynql?= =?us-ascii?Q?/W0S4Gl5Ew=3D=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 010714e4-4ad5-476c-1abc-08de93553f5a X-MS-Exchange-CrossTenant-AuthSource: DS7PR12MB8202.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Apr 2026 20:52:27.8350 (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: S6hgpmYPgptso/d0g8aNCR8sQF39LFRJ6EycfHly0gSOoON7Ji3cvt/AvGqinKjM3ORG1VxZF9tj6kjm1mQpmw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ2PR12MB8807 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. The mode can also be changed in the same message that disables STP. The stp_mode struct field is u8 since all possible values fit, while NLA_U32 is used for the netlink attribute since it occupies the same space in the netlink message as NLA_U8. A new stp_helper_active boolean tracks whether the /sbin/bridge-stp helper was invoked during br_stp_start(), so that br_stp_stop() only calls the helper for stop when it was called for start. This avoids calling the helper asymmetrically when stp_mode changes between start and stop. Suggested-by: Ido Schimmel Assisted-by: Claude:claude-opus-4-6 Reviewed-by: Ido Schimmel Acked-by: Nikolay Aleksandrov 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. v3: * Name enum br_stp_mode for YNL codegen. * Add enum-name to rt-link.yaml spec. v4: * Use u8 for stp_mode struct field. * Add stp_helper_active bool to track whether the usermode helper was invoked during start. * Allow mode change when STP is being disabled in the same netlink message. Documentation/netlink/specs/rt-link.yaml | 12 ++++++++ include/uapi/linux/if_link.h | 39 ++++++++++++++++++++++++ net/bridge/br_device.c | 1 + net/bridge/br_netlink.c | 24 ++++++++++++++- net/bridge/br_private.h | 2 ++ net/bridge/br_stp_if.c | 19 +++++++----- 6 files changed, 89 insertions(+), 8 deletions(-) diff --git a/Documentation/netlink/specs/rt-link.yaml b/Documentation/netli= nk/specs/rt-link.yaml index df4b56beb8187..495836a569e8f 100644 --- a/Documentation/netlink/specs/rt-link.yaml +++ b/Documentation/netlink/specs/rt-link.yaml @@ -833,6 +833,14 @@ definitions: entries: - p2p - mp + - + name: br-stp-mode + type: enum + enum-name: br-stp-mode + entries: + - auto + - user + - kernel =20 attribute-sets: - @@ -1543,6 +1551,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..f159be39a6e78 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 { + 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..6fd5386a1d646 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,23 @@ 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 (mode !=3D br->stp_mode) { + bool stp_off =3D br->stp_enabled =3D=3D BR_NO_STP || + (data[IFLA_BR_STP_STATE] && + !nla_get_u32(data[IFLA_BR_STP_STATE])); + + if (!stp_off) { + 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 +1654,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 +1707,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..361a9b84451ec 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -523,6 +523,8 @@ struct net_bridge { unsigned char topology_change; unsigned char topology_change_detected; u16 root_port; + u8 stp_mode; + bool stp_helper_active; 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..28c1d3f7e22f6 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,8 +164,9 @@ 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->stp_helper_active =3D !err; br_debug(br, "userspace STP started\n"); } else { br->stp_enabled =3D BR_KERNEL_STP; @@ -180,12 +183,14 @@ 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_helper_active) { + int err =3D br_stp_call_user(br, "stop"); + + if (err) + br_err(br, "failed to stop userspace STP (%d)\n", err); + br->stp_helper_active =3D false; + } =20 /* To start timers on any ports left in blocking */ spin_lock_bh(&br->lock); --=20 2.43.0 From nobody Mon Apr 6 11:51:44 2026 Received: from BN8PR05CU002.outbound.protection.outlook.com (mail-eastus2azon11011056.outbound.protection.outlook.com [52.101.57.56]) (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 013B4383C9D; Sun, 5 Apr 2026 20:52:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.57.56 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775422355; cv=fail; b=VqsyjN504z3dHiUsGrzTLn5/xpCrA4NQPUkOBLUrSyM7RWVKR1e/a0tZiNLmPDo5+B42PeuSez/UCjdJ0/CPKUzsABUmtcDhLzG6YI7yl9C0FCEK9MxBhu00PGIk6ug96fIG4TP5+1xgNVL7Ev/nam1sv7P5bxzvLDgwNoDXky4= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775422355; c=relaxed/simple; bh=7Yt3e+diZQtSb1cDXt8ELj2SohIVkhnYuFZyJk4Tr7s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=s2ptCzXi5ZK2D78J9ASqGalllh9+kjZh4ffpkyq2a5e9Vf9/d9cvRd1h15s+038caKYxMCHSdR3fE383J6ySC+fyPy1R83R5cyr78/dEAq0QGTtMzS6LEZbtXAvxruwNDLJAhomzsTl9QePNb6u8Dt5KbfE0/0HHth2BpDdqSR8= 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=a0wOhF3T; arc=fail smtp.client-ip=52.101.57.56 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="a0wOhF3T" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=VRqXLFODLH9hDYK7Ejo0hIrAvp4mrZ3m3TTX4/q2FbYsMdB5tBX8fR7hOxt9MGGD7WckcW5iZmEDeOXwiX+lFeRwKkJHlPUoAwKkkFqIVl/ZJmj+heGuvJIfAOG7FgzfYyvEmHQ7QhlCU6Lp/TVXPVvDiEkdmkmhy7EOX56NVaHpzR8Qh5pQODDqzHNPYRU94fVyYutnbZoCAG60qPZlOTLwQ69IeLYcYeiagVDUhilf2f5mqsSVoEMnkGWLv9Th+sp1xKENmdrfJ8Vm/uYaLNogaCPd9YBSUYzbDhoL40hktCy3dlLS7A1bY8ZAOE0iB50jvc5EG9cjQFZaYkQGqg== 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=ZCzhZrB7vOl2KlscA9l2DPFieR/udLdl29V/diTqWsU=; b=otoexlz+KUzgNNXv15GleGTQNfCFWmKjXccMv8U+BHnEv7HAkIIfj9zzlTbVhwql4RWHW6zGraYfC1aXSY+Npsqra0Awm2YZtXgKzr3rv+ngkX2REQNFf+M54ogBUh31EBqJt5wQd2paI4ch+gbAKXIaOsy+1cuIJpDbpfz6On/hUCwIMBRGYBOr6CpNypX9ayZ1VXIFCDLyVRGrfruurH9/f22geIaKn8SUlpugR9meWMGt2nCk7E1m6JZaTH8VraM91yf8kvwdrCDW1G3297yR9w2EituDh59kRurRoDkT8R+MrAyhCOyTM2Xk76mMMk5nrbDh2Z4lCkIbV02O7Q== 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=ZCzhZrB7vOl2KlscA9l2DPFieR/udLdl29V/diTqWsU=; b=a0wOhF3Tr4XH6vP4WhmBQvKa6poGy+9afr3V0XA9kdgEesBBmaj7YLrXLXrCxOENZbBODwGHyzDITjnBU8d+tD97rbrYP66dRrrygOycP7wFqByNkJgwjH21Q1JMaupLp+etBzxUI4yKn7cxiqirsg5hbaxD5Tr7tH8MZpcJiUg+oygUq8CBzOOysQNVUE3IpQ6Eb4hqRc8wnf4i/qiV98+++AXfgXUly1k1eIWZ8GPVVf7V2TFVRRZqcrk77xD+mLryhBvo4guIkI3PdxsrfQRYZRA579gY/k+nZAc6Qv2HMbpvqXO1Ve7k0WcUkoNuKv1e2MHdG//dmIOoC90nDQ== 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 SJ2PR12MB8807.namprd12.prod.outlook.com (2603:10b6:a03:4d0::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9769.17; Sun, 5 Apr 2026 20:52:29 +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.020; Sun, 5 Apr 2026 20:52:29 +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 , Nikolay Aleksandrov Subject: [PATCH net-next v4 2/3] docs: net: bridge: document stp_mode attribute Date: Sun, 5 Apr 2026 13:52:23 -0700 Message-ID: <20260405205224.3163000-3-aroulin@nvidia.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260405205224.3163000-1-aroulin@nvidia.com> References: <20260405205224.3163000-1-aroulin@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BY3PR03CA0019.namprd03.prod.outlook.com (2603:10b6:a03:39a::24) 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_|SJ2PR12MB8807:EE_ X-MS-Office365-Filtering-Correlation-Id: 66cd0917-0c2f-4875-7513-08de93554036 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|366016|1800799024|376014|7416014|22082099003|56012099003|18002099003; X-Microsoft-Antispam-Message-Info: G1UUUkMhVyqebqBgrMCLZ2bcSfu6QcU4Oap3Ek2xnVLUOQQCjj0V/IK2e5awIjOo1s5wipkJbXMjTON4xBQ6CSra8GTL/D0nl0SDtaJylzngRvjNGMN30Wrj+NyrvtMqvh0iAqt5vjwJkrevcFe0gOYqF3cmhSZfetdw0DAM3n8/5QwlJOM5iOIYTfMFVqPMPiA6XHNgFIacS4t44qgiezYKNveiqvSELhukFGCtmNO32fFI35qt0rnYsWF5JtPueWsRlr0S1IY2AkcuCxJoy7oEJKXBvNzW8QLCiGYEPcOWoJd1mLvD84kbafJG685xbXLQod4ygDHDkwSBLF1dpUYMvkwVg27u7rzzPHJFkYIB8Jm4BXRhKRESAMEYYJW0sJF9NAWzSC5LViQkMs/6876yq59H36lJgPaI1ScgPcIu11hBvl6L9JtVurjsvxbCiNal5R7+MSbN7gZvNbabKK7y1nHfVdPrpPlpDT6oVXrPgRkr0FfjstsPYnfpUCqEWO/f6AJDeWRwrw81n+e86hWTRGW4YS77LoLriH+lsSlWOIvRhHt58xiVYteT47SyxWZ8Q7uGveYlt8H2TmdqLJxic9TOGDdNYaunjMDK8/BHQfYiV3jLxEbRiMdtPg9auWhZL0KHDg6C5YfziRnEVH+JGebpml4cSmwi+L2vTG72T8++iTJCPlrl3UUGaFj5088JZnH9Gp48WyyuWAp1MrHbaf5tc/Nrjy5NjCbpZY0= 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)(366016)(1800799024)(376014)(7416014)(22082099003)(56012099003)(18002099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?GgTSIJV4rZ8S0Q80mTsu70FaCHC5QXOUjS3jqlPa+i11FfEtd+hQHAplx6P6?= =?us-ascii?Q?WWXgV5TTjhBN3q/vLbDb48fMFRYXtyh23zztb2B1Toud4rPJqt/bg+V9GV6j?= =?us-ascii?Q?05HmDeDGoskgjR0wG5sEjZXbytJh2rKleiRwnrp3i/k6Yfuu0sH+xPLHZwQ4?= =?us-ascii?Q?eJihGjtoshnKajKhjsCx0fH9iqyDSJPAl55k5pvYyafx4sNu7VbAoaJB0O/4?= =?us-ascii?Q?9Qwh8iVrxIhve9eEDXQwuNAMwHzMYK8R6aMH0rFTaIEFe8PlH+R6LtfHtGDT?= =?us-ascii?Q?PRPCV5SG5LmEfwxrPVyqjpvcV7cGQ2+D09/il0kO71ME6/h/0KNZWl4i+0yZ?= =?us-ascii?Q?RksgxQAxbyGL3N4tnkPd6psrfTymNY/XkDYgLpsb6NscOnoLVIvLcMgCVL0i?= =?us-ascii?Q?U7W8O8nkkjmELG3Nb7j0y0VCKnhkjbFbndY6XGgU3pGr/fBulfDBPQgQgR4y?= =?us-ascii?Q?I/lOo5bX2o9a/RFUm7DQ25y093zlsMZ//nchB3Fw7C2F2ZUp627jjr1j7LD0?= =?us-ascii?Q?fOlF3I03to/ATXNSQIJTkzO/9dfJfw2qBnR90QbuCpPGQ/9naaWF2L6Fmv1f?= =?us-ascii?Q?XYQUPHJjx7MPnhBbrNDhMezq6NhS9iWgQpFS+nKNwnfNaziA3YE+AOYEOshK?= =?us-ascii?Q?HbxvAiB4ISIIQuWWf5ij0g32Vgem1zzJ+Tj5MrGK76SQtoregPHAEzGOX3QC?= =?us-ascii?Q?ZM74qP0gWcMfsutgCw6R4a22pKRvE9Y5s74ydgVCJkNva+SShwjHc7cIvs6L?= =?us-ascii?Q?HCgCVffJ/U2Mug7wvN5W2cVUJ8pZt1Gpi5KyOynBvvsqgeSPXrkGtz45dozc?= =?us-ascii?Q?RSX51dSxpBWw2jLqKR5NRQMj5ZV/m2MQfCUWd+tYqdgYgRT4lNRIQIKlJVxo?= =?us-ascii?Q?eCV+rlrpYP9CzinN10A9K2QwlYfKz1gZ5d8BrU8INI2vz2ka6jXqvF4Blge/?= =?us-ascii?Q?ubki8xrf42fwsbPEVnxcVyTFPJnc/dmkriP9aaaBQoMKR+LjGad+41/yBHxH?= =?us-ascii?Q?vd2jndWk/BDibCaKxPv1bh0Mx7YqhDvpo41j4iGscT5n81VfPYIAl4swjZxn?= =?us-ascii?Q?X6f0E1aNgt32eVtuOGGit9qFDreUVdasnvIUQ7oyd95kR5s//DZwzpq9X3nV?= =?us-ascii?Q?BGHwzi4Jzjei1uaYM+6lFl2yXFk769BwT7XUAJlQlUy1YP1v9D7mpW/7s085?= =?us-ascii?Q?mmwItD5G7aiSLlMrDL6HFRMlNT9k6obreS+zeNZwdSk/VAX3ESmZrQZ4eQj7?= =?us-ascii?Q?8f9VuYerCS+kJhf0awmK+Hm9w+X9I8dP9RwBc//eCy1wRMlF6J0mqPX31bn9?= =?us-ascii?Q?Pt+mfMhuxlWdwmK8PDHnFN3sEu74HqX1LxdIgelaKd54zUBRJB3nFX54tzNk?= =?us-ascii?Q?/vh3uLg7/T+ghOxOgNu57lNTRx8mQB+ce9BWG2GwEOb67gy9N29UM+NI0myA?= =?us-ascii?Q?N9Fn15lbZ2ofKjzr5DtFjXvHNxQ53aFEpbdmRAOwNFjf7mSRjD7N5GvUG3IT?= =?us-ascii?Q?KZaHLvfcFUq89mWQva3acjjNvvaoVOVoQbbTEvh6+OGGtRdQg9x7Hoe+3HLY?= =?us-ascii?Q?3bzPM3br8XtQiGAPhMaUBO3Ka5Sr09/paDbZJIMRX2woDYflSWe2gxpxNQip?= =?us-ascii?Q?Z2tviLdVt1HLQvNdY5zX95A3lmXA2eRQHNIExfi4mfT9MytMDVG0Bm4UPCbA?= =?us-ascii?Q?H4BOid/osAOSdjG7rk5BZsJB56DnB1x8FSFEQU72rxlQUW4kgzFtLCf4MXca?= =?us-ascii?Q?m5aXax9p+A=3D=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 66cd0917-0c2f-4875-7513-08de93554036 X-MS-Exchange-CrossTenant-AuthSource: DS7PR12MB8202.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Apr 2026 20:52:29.2855 (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: 3d/vDLPeMFkRYbU+YIQj9J21YBB65y+xTFjjFxMKJXFHTAmIYy4lKrdy0an950Hq9S+2AO+pqK4R/8au/b40AQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ2PR12MB8807 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. Reviewed-by: Ido Schimmel Acked-by: Nikolay Aleksandrov 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 Mon Apr 6 11:51:44 2026 Received: from BN8PR05CU002.outbound.protection.outlook.com (mail-eastus2azon11011056.outbound.protection.outlook.com [52.101.57.56]) (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 803FE3845A0; Sun, 5 Apr 2026 20:52:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.57.56 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775422357; cv=fail; b=A6GLLu/yYfuKWCcnTP44Wuq6bdEr4QWUdJ/VGXOgQ95Uj4TITrNRy0w1NCMlPyuj3LhqhntHAOmlUxD5UyfKxQKuRjE3No62bU4zuZk0GuGbHs3Nk2EC5pIokpErb0HwY9GeMnrz4q7jIqGgDvIn88rf51GFg0c8oA/PwFlUUJY= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775422357; c=relaxed/simple; bh=kiJF8N6yjTIobo7AxhdlIaE6hj4pTFW5SynC4Im0fP0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=MDlnFoCOoiiQQARZIIR6MYPk28OF4CpLeegNdX2tL/1owej9ra7m8DJUVTanCkUfGflyjQK0werVtIZgUzCml0U2nz5WMg/0GLTuw1gpWM4R81C8YRb7blbPREaYCf5lwFfMLCeBfVgv3OIcIabP976EoEq0KpWqHFLiEhYT22g= 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=rywx+aKR; arc=fail smtp.client-ip=52.101.57.56 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="rywx+aKR" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=isesC3gAOJ2A5VM5J8KPLSx84LH+aPUzk5DyZc8RBcqRStHPYsebGqUokcdwRxW5bV8zKL8qKoQTCoLToRSsr8xhhTNHylIZrudzz50A7FoUjB58b0pr5X3XCbg06m+2i6UMhdQMJNWwykh7p38+tOkDDRp4USPIaH+zZYM/gnnvTLmPen3mGzbDvWbZTl+SROpAsae+5S7fy1/CmMifD7Np/wb6rX1EkLxY+XBn3jXuWPz5oWzGr2wIed7GcdkPCyEWOYI1Bip9vHgUCuqwtfZ6KO5ThMKKUhZodpDyn8IrDSVrbYQuwydHL0E48rQnJT0+Jn57ZyZZsgSzenlslg== 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=4Hwtjala+FQOUrzVLlofKalszfgiPzfB7hvaCAlvc9k=; b=OR4yFb8rlCaEQEicbfAz+SiN6GFVMJ58Ycg+I5mLlyUfb0yOuhFAFp00DvMb1SiDD6z1i2THyqibS6/w/skrZEKawbeVHdB7L6dxShow2cNhRjsx5JRfXoAmviUpqhCYQBA/hC+FMWjsNWAwj2B7p8d3yTRv/d8dYfTc29zE8YEKIfRRkQTTBtl3kf9Zw05ysqjf4l+VSeWTK09Im7NeKqfkKa/uONfhe0hZ83g8deOPut5LlwPuX+OycPK1zG8Qy5qY6Q8OmjsncV81Q64dLuPF5XqznwSdRI1cIlG9dufcsgzey7zS3aAAnxfnh2LbQF8mr87lhNW6Ja2o7P+1QA== 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=4Hwtjala+FQOUrzVLlofKalszfgiPzfB7hvaCAlvc9k=; b=rywx+aKRaAKvLpxfC2LBGW/z6hzsjkEsqkUDuCx6xKpPxPaIWzORV24DWNRBq6d+fAVT8aVSz+yXHBtcDvsDC+nPX6Dww3mnjzPQaIoZxj49DI5T1cTXeVuCz9ZnGGzeIteM+/99xGJ6sLEmazsSVbF+J32DVO/CbFudTxrultje1ErycQoRjEpbTe6qyFYk30Q2qRoIhiaR6AMIaJMaZSpS5/shQcjFQjU2kLrc7IT59hvxfg5qoTKMt5MsfsC6CHTl1/o3qNTZpdzcYUMoPTf+F4QgauKAW+DiAcSIETMBfBThLxWvbQ3lFhMsKoLH3RmAoAECX4xK5YfB3rEQTQ== 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 SJ2PR12MB8807.namprd12.prod.outlook.com (2603:10b6:a03:4d0::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9769.17; Sun, 5 Apr 2026 20:52:31 +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.020; Sun, 5 Apr 2026 20:52:31 +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 , Nikolay Aleksandrov Subject: [PATCH net-next v4 3/3] selftests: net: add bridge STP mode selection test Date: Sun, 5 Apr 2026 13:52:24 -0700 Message-ID: <20260405205224.3163000-4-aroulin@nvidia.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260405205224.3163000-1-aroulin@nvidia.com> References: <20260405205224.3163000-1-aroulin@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BY3PR03CA0029.namprd03.prod.outlook.com (2603:10b6:a03:39a::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_|SJ2PR12MB8807:EE_ X-MS-Office365-Filtering-Correlation-Id: 36b49b09-1714-42f3-a09e-08de93554149 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|366016|1800799024|376014|7416014|22082099003|56012099003|18092099006|18002099003; X-Microsoft-Antispam-Message-Info: oJdsEGmDaYAdSWXd8yrOBMxtvwmRY4moBPgrRVD0a3tatAK43AZWINuudhz7D0eFg62rNs2O0NXVcpcjXtJMJtxlc5wThUpWyhV+Rxqq/zhHYF8rTBCtq/KgYjuD193Khr6EVs2T06idjENPL4u5DlveHpIRS/qeV0n2ij5uIiROXBoYey98diEZYL8/oUkrqYVUyOv6ZhmerOqt9RS/2R9x4csphUJtyX1/o2NqIYJhGqP6FWBvbkxYnj3ru0ZHs1ZSliRMHi19KxPZUJ6TNlMsclv3znvEZ/viFiJ8592shzTANS0OVE4kr75daeJXu7uuPSh/5KtWZQNGqgQw99wOQdImSZocdtw+9ihZW3A1qDDpzoXN7qbPa1zvqLUWhcpRBaNHaXSKJAJWJeNU7P0OeiVWLfA6CG2dwdPd8v7/uQjYLKZlCTj/O4NT7sMZ4jq7f2KeOW3nLu5ml0EhAlu4T0toSy+Sy8yBalirObTjS9Nf4t/pE2rHR9bwLddTkryLtURlLzYSlZclP4+j8oJZynfodfzNNhXzzNFxXjVFTPisEtEahuQFuQyiAh+uLIFMRq6CyRCDu/CGFhGCYw8PKWNtfo0yi5KyX066PP0GsDHQQ0iUZy8djL1sKlROSXkXdbs4UpYmrQQHENzRg+MUR7bhRoswj6cA6lgl1yK46JylMXFS+Xdyz1YOKtUjMM+8Kw9z1fZ4IFlUM/TJoLkIbNfQARW4dstrARO37WI= 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)(366016)(1800799024)(376014)(7416014)(22082099003)(56012099003)(18092099006)(18002099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?+363U8wlQ+liQp1tEBuCe8VCZbIhWu1vJMDhjH/uRwJVh3s2kvcJ8eMjGBR2?= =?us-ascii?Q?nMOEQvoKi+pmdVhaHwUfTYVQ45XHMaA5jcC/hBf7SgnQT5WC6iNj7SBb9cfv?= =?us-ascii?Q?VKqTOUgu+Q4BlxxRzwtur8Kv4BZoJRaQozzcXC/SY7HB3kp/4IXtlF9JG1eX?= =?us-ascii?Q?olRv97n8KhCrLBf64xIMhW2hu9GnYjxOFPTT3UoSugt6SmOWIPNzqgI0AHia?= =?us-ascii?Q?RsuejZoH8BY0UPcSPRPYeOFkOEGXxFWkvPFrNDfG1nrlINiEBt8AXcG5Z1nK?= =?us-ascii?Q?Jf3cR4bc89L5/3RrvyE4bz83o1yx2YME4LlpdVFFUvNqXrTT7+RCCJi8YrLn?= =?us-ascii?Q?Ep5VyJICEBeYAjaIe2TXcH6cysGCl9xzWvppfll0x99pAvJARO2SoGoIMYCL?= =?us-ascii?Q?rmza01UITybjBKg0Xg6r11RLlBmW4B36UC0exWqD1FekhSc0Tg6qP6ScNqgq?= =?us-ascii?Q?NN2zSjEHnl0SDrABzdRPOVWDHQ0pgjhuu4CE2fw1x81u1HB02xSTP1ZjIUrM?= =?us-ascii?Q?sqT5H+LqcVo/RwdOtYmsF4Y1vGe+pNN9Oewv+kvEfq09WMIcSlbOqcAtJYF7?= =?us-ascii?Q?WYpyJFCpTz5Fr9mqgysYH0c8FeE9gKLefzyt0HoSiriWVhuoBdhu+ScDSt3+?= =?us-ascii?Q?HOsdSKH2Mi/vsGolwY0uijbiqwEGZA42lGZQdhfVpuBZQZIpFwc7BOzH+8z6?= =?us-ascii?Q?E+v51ah7rnPDodAXgcMmj6x0dmt4dHYodYlcCbfexc6vEaApaFUKXYaW5UoE?= =?us-ascii?Q?C5J9tbPJZi+FdtoX2NWLYWL6+CBj9p9V2GEnvm2vZeZdPjtDyU5Yp9t8FAab?= =?us-ascii?Q?g1Pc++q7ug/IiVUXfG7x7dX97KMwE2HPpaJ+VqXOv6P7AX64cbQfh6BSy9Tm?= =?us-ascii?Q?PRa113hBg4fiioFJGnv7c/FPup2hND+eWzlRziHAZfDoUvIyIzA3JJ6E+LKE?= =?us-ascii?Q?M7QVrChowKVJ0ext2F74fbiZyNPUknxwpUndY3J7hGDkz7ueJh1DxGMAs+OW?= =?us-ascii?Q?WtSGOZtEvnNIC1ZAi6Mn4Xk+QmCyzA45iaxXSyhO4dilTs6PgWGybRtxNRJs?= =?us-ascii?Q?wbMvwHflNIW3tfaMP2Y90KxOW+NW2y2yhMM5P/HDROSEBuVR6DRFMzuBRQuA?= =?us-ascii?Q?fQNACvrg6FmLHOfNqHZVoJVf5R7ATxVQgG9rwW1BeMOuxStXWsWOZofh1yMV?= =?us-ascii?Q?OSrewn47DQIwbn34jKf3SpjmIVccq+XQQxJhrfsiGaHXUr3+nuLuXMZD1bQd?= =?us-ascii?Q?PDDQiG86BhcEo6wok57ytMuPfw3l7On71q3dC3zlbzgmKfGfTn/8QES4JtBi?= =?us-ascii?Q?tJpdZ83IvCUfowhMY4vqIDtdLP/JCTCR7h3mEvvrdMOix9vY4nuQ4VR/vQdY?= =?us-ascii?Q?wo2SXW9BRgKHraP/3esWZez5kitNSV09lUK7Ym/Y64QBUBYwudta11BF3VSQ?= =?us-ascii?Q?kXjjP148rKLxN+HxAqx0Ytq2mEwZ5uYxSNfC8o8AATzq49+68Loh/IMOfQaQ?= =?us-ascii?Q?PtRmPKgB5ZGwQA3BfWhMEYiEd4/cVkOQliWKSSHGgS77J+lD8MrleiJ/aKfv?= =?us-ascii?Q?c216+kizhF5rs4Cb2Ph4Ydu6Yg7CDy9ESC5Eov/+TDbHomnADLN9uhwd5ENu?= =?us-ascii?Q?yPB4oBdVozQDqjorelxIF/VHipXhbZQQxXbkwFUEO2kv5TnWeYGd2uhnADDq?= =?us-ascii?Q?Mqj/DtFRHJ/2g67ySqqZsAe6jm+MlwaUGR+rN/vpsOuvVBzHTvBlgiYYxZc/?= =?us-ascii?Q?k6IV0m3zfQ=3D=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 36b49b09-1714-42f3-a09e-08de93554149 X-MS-Exchange-CrossTenant-AuthSource: DS7PR12MB8202.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Apr 2026 20:52:31.0950 (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: AvDMhVejqHyI5BMExq0Ej683JUyEoDgzJ6o1NjnfTmqpOO5/+YMt8Tzj95E4ed8FfNMIvx35cbqF/rGlwn5M6g== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ2PR12MB8807 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 Reviewed-by: Ido Schimmel Acked-by: Nikolay Aleksandrov Signed-off-by: Andy Roulin Suggested-by: Ido Schimmel --- Notes: v2: * Fix shellcheck CI: add SC2329 suppression. * Add idempotent stp_mode test. v4: * Add disable+mode-change simultaneous test. tools/testing/selftests/net/Makefile | 1 + .../testing/selftests/net/bridge_stp_mode.sh | 288 ++++++++++++++++++ 2 files changed, 289 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..0c81fd029d794 --- /dev/null +++ b/tools/testing/selftests/net/bridge_stp_mode.sh @@ -0,0 +1,288 @@ +#!/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" + + # Changing mode while disabling STP in the same message should succeed. + ip -n "$NS1" link set dev br-test type bridge stp_mode auto stp_state 0 + check_err $? "Mode change with simultaneous STP disable should succeed" + + check_stp_mode br-test auto "mode changed after disable+change" + check_stp_state br-test 0 "stp_state after disable+change" + + log_test "idempotent and simultaneous mode change while STP 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