From nobody Mon Apr 6 10:31:54 2026 Received: from CY3PR05CU001.outbound.protection.outlook.com (mail-westcentralusazon11013053.outbound.protection.outlook.com [40.93.201.53]) (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 B3FFF391E51; Mon, 30 Mar 2026 02:21:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.201.53 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774837276; cv=fail; b=EwwDUcI343Rbjl15HsWpBjACCv434WFsuow4wIMgOhTHs5yPV1xPs+t6Lr1CyOvt4rJRF+DiZJzEdzecs8iJRMoxtAbcNVGpXx6nPAceln0S3nhtw1BeShyde05F0CLMIvGIdIXRHlR8HxIi+zc4Auqrje52L6USE7RRd2uPErE= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774837276; c=relaxed/simple; bh=F6pPaU0pHFkjHKkHIqBn2YUnBYqSOgsKdfd+SShI3yk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=meP8Y2SIIuuiWANabppqjiVTScm4/uDzErPpnPrt9CYPojLmHCIAOM/q1+60uGHyRmnp9Kj6BVTg4vFyqJOEDyBtMpaDOMbCQ1rVS+DKtpB5Oe5faYVrSNhg/rR82hZC+1TnJ8YTv94YEdJpFnXstFTZc90Vgo8usJKeCDk7iV8= 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=e1NZoWtB; arc=fail smtp.client-ip=40.93.201.53 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="e1NZoWtB" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=oHN06+w3aRPl6NX0kGsOwH9PM4O6EFT1pNfnh8attM/Ui6BupPG28iN6Xlqfch1yJeUTOw/eO9tisQKXCkFGJN1utjj/ylLxl8PxzW7l9vHX1on4kxRBM7rp/oajDuRCnnICWfVLi5nUg+dKCDpT9ZK1OO4iA0Bs3tHDZ6Sv7LTH5XTV2g+JWkhIyWBb0YcglN+4Kp8EwTJ+ddogjU7QAgI4/7ck3zCEfZbsG7fuqpBizVmIoxtlmkTg0HV6zVmFuermrlArpXLbDgXGTtNfkYpapq3k5bw7fY9mjZ3l7CoiuPlOINWGKratCu+Qh2PBoXUK6RtOWlUcqXQVzr/wKQ== 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=XYtY8I8O/4EkS37y2GSGl/LGyImh999RZqLafmap+7k=; b=NnIWiIaCJUamENaQ83egTGa0avk4kyqohK7yKdvM7xRxPRaPH3o51Wwm48P6bkXq8ITDfHhLJmR0iP9F+En74DpjJh/6m2O2SGApoJYgsyXJYOO83tTC7ow/y6D128OlBU6P62bQIUqwg9vKWimu08zqiybZWnEmX5M9RMmZX1mOFGbxIfI10l65BmNVNCknuanngwnLpgn0/W573QvQh7kMA0Ev0qHidIYWkLv+gMT7RePAIuaC0vY3GW2d4SuFBio3/egjq9w1T9jwrO0zOTD3WMQO2j9xqf9VolXZQSynuEzqrV8EvsieK6nz0p4azGrEdbKsBhrOCgP25ukNjA== 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=XYtY8I8O/4EkS37y2GSGl/LGyImh999RZqLafmap+7k=; b=e1NZoWtBLuntkg25lsLUNwDwEptIH8UsH1ljCqGfy38HF30fkUVWoAWQ9+0aAXN6RKbXkVDxjXDaBqr+Cv0pWJVQiqHDUmsg7zHM9Ge3oG1otrGY1uanL2REQ16rp0Ges01f4JVJo7IdhhKSuHMWWQ/lKw3J0w6G/+zukWYBjJXJr2+6VcyvKLItPinz5R/R/q7Dapg/Bzu7adxxZtMK7G9OWpPZTkkAl+OFonTFEOd7/lM1m/22bsvSqZR4zZBU9FjqT310/U8rluQoIBq9mRLHbanKRUZnK02TUygjgKMsXSulUh0GUhiV+j3/JU0c5QQHvB1VsUIQtQjSm+9Kfw== 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 CY3PR12MB9680.namprd12.prod.outlook.com (2603:10b6:930:100::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9769.15; Mon, 30 Mar 2026 02:21:11 +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; Mon, 30 Mar 2026 02:21:11 +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 v3 1/3] net: bridge: add stp_mode attribute for STP mode selection Date: Sun, 29 Mar 2026 19:21:05 -0700 Message-ID: <20260330022107.670566-2-aroulin@nvidia.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260330022107.670566-1-aroulin@nvidia.com> References: <20260330022107.670566-1-aroulin@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BYAPR07CA0039.namprd07.prod.outlook.com (2603:10b6:a03:60::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_|CY3PR12MB9680:EE_ X-MS-Office365-Filtering-Correlation-Id: 231c99cc-0b03-447c-2eed-08de8e03025a X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|7416014|1800799024|366016|56012099003|22082099003|18092099006|18002099003; X-Microsoft-Antispam-Message-Info: ZRRKMXoUWVdAd3p4C09dymRDtW8eJLDrKi+dIcstifSwdMPMBDvkub/EjRSqtWYfZhB4KGlYZjFmOSlOdoV0XhxtFoP7X1abKuuvhIkL3tNPJD1IdOEd1jHe6r+exO1aXEsqLExwn2yzyOIN4b84b1kVj7ROfS8QpRJPJad7mWJh/XXSEchRFwTkCX/s3gYJF+4uoiVuMkN9bnBNULfBluhFfBA1Qrfrj8ePnl01d47or4a/6abt5CLGpJ7sElMvuMQ2SNfqy/nkLsSecfew4pCMIsQmNki09zadM+tiCcwHTpG4RSAfNYJow4tf4GcNVJRb/TepbECf4fVYeVT701ryNWRuOmRqNNhoQuKn3d6vPZGY94lCAW8FbHNaHbRIlo6dcSz1PHO8b1TdCqbxFeuqXxESyBYURHlah3ZAjinRA/6B6HdDsYoNupMyvI7FCxZlPuXuPIdj/kCIH12XNsmNTeKxkZ3CRYRD+rEEMAPCTqB/SIKDMIImgpDavQzaqdMvaN564QDJahKYsHmRn77HPdXhpHW6SSCWLRTr5vMn0EuE/0AhGk/qPmSShwFUBpwmdAt4cvwyItQ9q1ud0u+UyZc8K8y3dk8CFxRSwavAaA1mEwgVSS+i7ecTmlSTnOBtiaXEcXhPwY+8Es8FNUO9VMy2YJEI0ifWkfqMxEzaNM+rMBT49PyAcaqfjcLgq7X7kbU0icJIc/4hG3mzoobENepmDga23uJTxRQBKII= 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)(376014)(7416014)(1800799024)(366016)(56012099003)(22082099003)(18092099006)(18002099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?EV1SyohJp7gWOtVaoeprbrPYXajFVhr1Xr/AEfvJ7IakFsgxxwDT9oRXpFj4?= =?us-ascii?Q?ulEAb8s5oVUdN7sfUwcTi0BKzMuz4R/rOdObn6UaFc1fBGJEO1Dx4xWA7Svj?= =?us-ascii?Q?KNVmnWvPLSc2zM/GC5si7a/tAe1QA8ys8h6scpKI54LiMj6D+GDFfXb9huLy?= =?us-ascii?Q?lPBeUt1QRP0jXJ9Y94shk7DEvAzW7fbGnFzK7uwLYRq9PQ3d6BMS+OZMlqXi?= =?us-ascii?Q?ia10mTF26A+5n+X8GlhfefUp3LTiEn2XRmpuaq4I6d70bC3BniBeu4mkvUAK?= =?us-ascii?Q?FYUS22iwCsyWXWqo2o704gY5hjUA3NtX6zstEvCzXoVp9YIJJ4asytiBoQMX?= =?us-ascii?Q?+UgdjN5Y/iWbxTFZp5XtdjJO+15B8H77pdart0AQxqiyYcmPMYh+OIs0XI0J?= =?us-ascii?Q?VDZ6puruQ/+DwVTfJcfxcOg+Elpr6sWMcvTJO8lQ1i8yRzs52FxAo1huaJ2A?= =?us-ascii?Q?ZLOhZgT1MlPmPjk3VtEo9E3+iIW4Xh1411Z8v49XejgIfe16Hs7ulvF1cfZW?= =?us-ascii?Q?Uo9UQAkJo1pd4ZvIdts7eUI1H0wMg0MgWi9TGsb84TbjBoqjDtiXvaDCcFlK?= =?us-ascii?Q?ZTPKumDj+zjxfn+LIdyTOI9c9P40MepqBpxOFCojIatEYUuLpe8c1yoUI9A5?= =?us-ascii?Q?FBKD2YVvcYGH6TfOJu/UiaP+v+ue5t2kuAGFDjhBMM+Fit+3bxLvPAaUkzOq?= =?us-ascii?Q?VWgPD0NOEsCBsdiOnjx5fdjnl5n6qOQAFClckVc4GmGES1gwQcCIPuMe0bIn?= =?us-ascii?Q?DsRIqcwdy8lYt0ak7eEEiQVjDM9vk2GqDezCuyr4Eei+/Q2atIYOG4ETbPOB?= =?us-ascii?Q?yqOHgySb/N9+LpnIKPBikQBxe1AJJ5j+ms4Kuy7WKYsLUEk05h/4QDReg1kU?= =?us-ascii?Q?gq/HI7lkCkE/brP8Ug6zd4PKAAAMbZsKfHuaOi55uXgqgUAsO56+hVaQs3Tm?= =?us-ascii?Q?1ucidd+HFuQDZOvrWUGPmt0ETe0UtsI1CVmQ3/xVc62MhCoHa8nhMjxNihtR?= =?us-ascii?Q?NtK90Q4Qg6B2PWvM/SZHwSxkio47AbKEM/H2Aj+f3r0JMN5CnBXr3Azl1xz6?= =?us-ascii?Q?HeOen6QZRZPnrFS6wSfF9WdgvMl8DfGOr7LxjKDRuB/DEKV2odu/5a/sYG2h?= =?us-ascii?Q?kx0Ly4XMHDyyrfRwEO65TcgLLs2plooj6d3d3301JgFzRaD36oQ+y+WijMJK?= =?us-ascii?Q?kFYUJ1mCmSL0irvyAmaR5hNT+xI+kAAsYemBBDqI5TMMmg30oWI3dRbZLZnI?= =?us-ascii?Q?c5EvByl7kNA5t454xF9RpS69TPZq8f6NV6sRF1YhVbFAxJXqCI/7qNW3+Z9Q?= =?us-ascii?Q?1IPbWDSj7XR9RxESLM72PsCVITXJoLXFZXGvqXUlAfRm41rsADGsZiPaMmM4?= =?us-ascii?Q?LE3212iM0v+fCK+ZjHeuremCyN4PuHXSurLipE5ZNsQJsv7MtnXxHflI42JM?= =?us-ascii?Q?rSrUL7+ONTTCUJ9Kv2NMNOK8/m+xRYKHd5wgkW45FUvjr8h9j34Tal45iwR5?= =?us-ascii?Q?FqrqI3Y02Tptfrag8ygSEutX+D8afhVjkmCAe2K21EPL4goKlfinBYKG5MVV?= =?us-ascii?Q?XbqmAyAdE5+RjgMF+UPoFbxenMGai3GrDczGYMrabFCDmrWML6mBPG8Eji/t?= =?us-ascii?Q?au2iTQ2QntWOH+Uyh96911mCnXlPlsQX3XmF7ptEp18z/F/5MML+2yd5hyS5?= =?us-ascii?Q?emndwMS3Td6JUie4TeD60xefkHM3o6zQ6T1ftP0Ey4StQXzqrnDXjgpIJIJn?= =?us-ascii?Q?D4ZiLtc0bw=3D=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 231c99cc-0b03-447c-2eed-08de8e03025a X-MS-Exchange-CrossTenant-AuthSource: DS7PR12MB8202.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Mar 2026 02:21:10.9987 (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: YH4az0gCpDTsjnKeCz6P1nrI0ez6uqYF25gb0VR8u70wh7KxONdAYraqBKM1gBDE0DFZKcdIJPoKhjdgsiAXmQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY3PR12MB9680 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. v3: * Name enum br_stp_mode for YNL codegen. * Add enum-name to rt-link.yaml spec. 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 | 18 ++++++++++- net/bridge/br_private.h | 1 + net/bridge/br_stp_if.c | 17 ++++++----- 6 files changed, 80 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..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 Mon Apr 6 10:31:54 2026 Received: from CY3PR05CU001.outbound.protection.outlook.com (mail-westcentralusazon11013053.outbound.protection.outlook.com [40.93.201.53]) (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 63543391E44; Mon, 30 Mar 2026 02:21:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.201.53 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774837277; cv=fail; b=uDn4ZgYOfPnrGC1UABAugKOtq6BSM5QkBlqd/Kt/XmfIY86jKhZDuMFqpqUlOoW+8nRFgSaLwf1UIgWF9XTe+RXLeTshrYr+ZEyBdu6hiBgm5nB5q8HqonXQVbDYV2hyGhDzsELxPeYGX7/bhBv2O48F/JvE7zY1SDRASWJzP/s= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774837277; c=relaxed/simple; bh=QYBJzJH65YB8tQo0SMmdHNgsWXD7WG7GicaFpOLQCjY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=RGPZmkv7CSb1GAqJfWCEWcgE9bcQtQceEQhh68udreGSIQM/a+U1qC3u6olgiIe5MiBmFe87chRaF8hlRoBe02xEciH3s1bcc4De8LW3UIi52RCE+re4X++UbzK2EFoFaO18pp16/o6GHOAnRruI6x7tDUGPyruTe2G+rMQOlGI= 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=t9egv9jD; arc=fail smtp.client-ip=40.93.201.53 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="t9egv9jD" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=Phdv1ARULRfIl9MdRe3yD36OWvgvPUfLgixKQYYtjpZIHP4ezRvgdK4ajVbdtuYC6q/DTtmjjV28Att9/fCvG0ULQeO34ETJdqIMGz2jdyXbjbYr6aY/e+ZP+Buyi9TMxGY9OPMrQiXd2yC3VU8WVKgrYELdSAehjKbaXVUCjGRQJe8lQ+H04IXYJWw1710iLVfpHH/uiLMu8CeiwUyzSnAVDy19Yr/LzVgQsjcg2k1RkRk5b5M6NeA7hm6agN18kE1QVKm8qWFZgnoYrLYqKY+cIMhbjYQ6UiFQBKQ9q9hDuIgutYSq6k9dwmfU1pFNTWHb/a9/5sUB3QLIOa+6FQ== 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=ZIlirYWelZ3ToxTSJw9eEooFFDAtK6yCStXZtBn3T7lGwFFe+sD122EaK46z31TMKZ1R/312JsSJYtat6JEARV303meljiVOWzaDzNpm6+W9KjWQ17thmfFiJwg8aN4RjW1kOQuiB1LlyCDRgMmGK2Cztf/sgLNp88MO2/zTu5F88ksmO8YFgppC7jYsnON44zS9m139lmdZz4QRMJBy30Sn/0GtmahngSBzZMiSRY4TWRxyLUc02LcZMAlsEdmFzJv+Ma8YxFfALYMfDO7mVCM5fUZ+/68HjU3+Sn5Zi1GAQ/j4vmkOijOyCi6Me4ZrWTlEN7hbgacQEurlk6oueQ== 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=t9egv9jDhobp+xSPll65NUOykXLbcKgEgUqjClPnqR8OvnO2aiUs7VYwA3UKHQM4Zc28eRN77EvAwnPEICdmLniA1EsLndOHW+FQZYl1rksUHSb9NRG2iTUhskpSPIMIkUxwr5Helc+4ubMmCfNvMnubPwUX/jLwipjXEG4hPFhSqI610G6f0bgLg/QTIqvgkP1yw/b4+lhJbsJUwhXvokg6qnlTXpQsdvzKiuWMS0fwQHCJ54M1MysY6x7uxjAM1lkF5rY+bRy/B8UDzoZrzCWPs3zUtiEb9BfdNcAcKVXt3hlLjDhlgyw7jXiszyNpPRMCC1oSQNg1/zRqg13vKA== 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 CY3PR12MB9680.namprd12.prod.outlook.com (2603:10b6:930:100::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9769.15; Mon, 30 Mar 2026 02:21:12 +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; Mon, 30 Mar 2026 02:21:12 +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 v3 2/3] docs: net: bridge: document stp_mode attribute Date: Sun, 29 Mar 2026 19:21:06 -0700 Message-ID: <20260330022107.670566-3-aroulin@nvidia.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260330022107.670566-1-aroulin@nvidia.com> References: <20260330022107.670566-1-aroulin@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BYAPR07CA0070.namprd07.prod.outlook.com (2603:10b6:a03:60::47) 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_|CY3PR12MB9680:EE_ X-MS-Office365-Filtering-Correlation-Id: cf8ca8fa-67e0-4ac1-9be8-08de8e03035f X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|7416014|1800799024|366016|56012099003|22082099003|18002099003; X-Microsoft-Antispam-Message-Info: GszSB0XDsw0cQIvoBIMShlT1kLzpLIt+yRTYIHVjcPLrySoZpwL7DQxRGydwUDALoSpXK26fSqC78tvuAO6OXgf084k/ft2SOCpiVtdkMWJf/MyBn5csZ7jpfUxztMmF65bcOr/EzuQMy3Y2VwdYMXzX2KVep+zULTne/XggX/KCIC5WH8McqNN1cggymqKQSIqLu/Cqh5I21SXFliVTEw8EJSCEL//ROz5Fuo0vf+hFEcfpw7t1OP/IGboZsTL2FM+BoKWtpuLy0WybROj883bLHheSBRyED/HW8NF8AgIL556GwdkS2SIopfA0JU+cppmyIs3O1W1jL53xzWz4IhsbRfSkaK7c+NMrTLg9Exz1cH5oxUgy5qHi7GGl82zbXLK8nt/1W0ShEtFUc2YO886K7/Tt+xRd4SChw9h2aBjagLI3ITYBsaAGUjNvA2lzxNzEQaamJH+oeHGjnSdkucgFmGfBpskqce10g22dy7FjDTFMfO0BPYMKruEcWxsX2/mPlnXbl5A6E0pC+WPKuzABLYIHKtVuc/9QN72pz8ivGWlM+GoMAqy8z5l5I+S23qpcsT7v6apNwgLHewISTf23kU4xZzxtCNu25Muhq/5gg72x9YMXNlNvhrCKqcnLdMFzg+rDkbFYVOAsluOtfWR0l+q/odZK7InU1We3m6gvaMDTzHMBpM0IfAU8F4GHaVGv7Zg35t1BM5KnXHjIhZ4Njt4TtjPD5GwYfIo0WME= 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)(376014)(7416014)(1800799024)(366016)(56012099003)(22082099003)(18002099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?F3hLwheW95N2gmjxxocrVYRr3f1rpIE5mim1YLKtxJKl7D6I97C2UN1t2ywl?= =?us-ascii?Q?qGAyoQv/P9S54vb3JQjilqPBYws9YCl1hCycn+d9SoT2aOha5vk0USlVIHjo?= =?us-ascii?Q?43Y91PKN/avwMqlkV/CieC3cDDX5csr9OTP6N7ZwtEjBf8nmWm+IVDiA6w/h?= =?us-ascii?Q?3uNEdTEOztpZTvdKD20WIXBJ399vHhU1Ox80Gdjb3hutXmwImoAvIfzUCXe+?= =?us-ascii?Q?FOLaIlvGMSZaTcmP9VnvJSu5CX2i/WqwI8UWWSuykVESLF5M5TZ4vIAI4PFv?= =?us-ascii?Q?0XcasR8HCKYEkt6mfqtsCLAASuWk8TL+tv8nGQahFF0ARH9SYZGVOWllGtl5?= =?us-ascii?Q?mGPYzM3MRK+Ai8wunlRQA6wTJox4tC96VZ88rkyOncq/F5l4KSc4jRajFg1W?= =?us-ascii?Q?1aig1LLfCod2RQNzgV/VPJKLhQ723oMjGe/5vpudBBcw7bmFdacMUrwpEJp3?= =?us-ascii?Q?WBga9wX731+bnm56PH5+Qp4FlhS91yYjqQjTXPV411obJRgTGdpBsMSrnd9o?= =?us-ascii?Q?c9kUQpunsqlAkiZASwvF+CXvDOXPyUSdthuHQhl2TxABgbK/KQYmESOXmuSN?= =?us-ascii?Q?osbMpg2AX4ajkNDAeoL925Bk/UIlA7PogN0zenM/sCvaoGj7bXizCrd+4XRP?= =?us-ascii?Q?BgU7DUy/zlyRkJbBBahz61f1qpWV1h7lj8p5NoKKErcs/7Hx1/aweZh2UHxq?= =?us-ascii?Q?BM1qNa1hmcBsNMe3cqR1Rm+0HpWzrWMR06A1DBPBUTGNE52mvXC5tMB5H+ES?= =?us-ascii?Q?0Fk8Vb0lAx87Gjh/AhE9LlXAqpobL6fT0IM8RWZbEgWAxkQHhDz7YRPzjHJZ?= =?us-ascii?Q?QQaUBo14aXaH/5APthedMWjZP60qpDUcNOPHd2200A416YeARRJbL3bwICJc?= =?us-ascii?Q?sy2GM3cw7TlcUrZVRtdDdtb6TLZCFoGlvjbEmUxNe4N2LsKSxbFpjhMZcv+l?= =?us-ascii?Q?7pRtXAqRF3DASCGtIcqk/Osw+IHJREARM5bdxq5n7ifDPuNh4Xfba8BZT1bp?= =?us-ascii?Q?A5cUBEVFFSLCEZrc0nOLH2/meN7JA93BiIyNxj/8XhbaULaIDVgPMHbuUIWj?= =?us-ascii?Q?l7NZAbfS541/lbxZDN+lpt3R+kLMH0nAzlZ7Pp6+zHIBUNGy3vBe1DuZGUSd?= =?us-ascii?Q?sg00FikiD4+nMwqXe4aPrKYzct53AdlqWuZFXNVpkggRyng01W7hEh/weH6K?= =?us-ascii?Q?/Ygkld4FndomL6JkJ9HOvnjgeObqRBIyXf8fKm/MWinCU4GKt8Z5WGeueMkV?= =?us-ascii?Q?VkxBLlEFNEAZavULyQcxwkGbyp6+EzM2PMPpY+9FfdCvOUfUpjpahPuKKf5e?= =?us-ascii?Q?ZV6Ik5i0Qzj/q0tdND4p7Z5FyWqkIOOymYkzPuk+U/5aUvJATFajNoAxasR6?= =?us-ascii?Q?m9TpqqubQKk2qZyn78XmiLrIW/UBh/pyFzGA5tehhpf/5VWvG5Qxl2EdGoDC?= =?us-ascii?Q?0Pjmxpy3CwKXg3hzU4I62+HU+AfitsY6YuWnIiqyB03nC86mW6zH6oJM3TjZ?= =?us-ascii?Q?6ZJ5npQT6FPKfBw79lPa8g/eJPaisahi+Pmkz9nBBj/XV6AXS3WnkilwhZ6z?= =?us-ascii?Q?J2FftV/BVMbYQE3FOO86OrX/IgwYFLl+Xj15670jT6PNLqYxrw+Qd3JnKJrn?= =?us-ascii?Q?hDWsd6cXZIf66LlS9gliikTh5Ij3OfoBf8RAYUTIOWoERILL+bUjfWIlEXXS?= =?us-ascii?Q?scZJf3cHlnvMw9aIP3m7DXdkJzF9kxNZoZOmuqqyfoyR4Yl9C3AWZfvhpblu?= =?us-ascii?Q?ccqZwfFyXA=3D=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: cf8ca8fa-67e0-4ac1-9be8-08de8e03035f X-MS-Exchange-CrossTenant-AuthSource: DS7PR12MB8202.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Mar 2026 02:21:12.6750 (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: VKg+X/M7Y/tkkH8yyVo6qEbV/zIj3qJdl5ynJQQPUxaIQxDCLEj8fasWVRTG0DXk4/CwqAbJEw4GWdNhbr6KOw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY3PR12MB9680 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 Mon Apr 6 10:31:54 2026 Received: from CY3PR05CU001.outbound.protection.outlook.com (mail-westcentralusazon11013053.outbound.protection.outlook.com [40.93.201.53]) (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 8A960391E40; Mon, 30 Mar 2026 02:21:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.201.53 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774837280; cv=fail; b=mDGV86EsW0YWWBgCoiOqjNkL1OV3RJShAOk6YELC6ajM83S5cE1sszDFwrgPvi/zl0Bhn3EvTGpV4g1DRCfzkF/AA6cDVskW6eaqQaM01BNwpf1Yumf63F8iALGvRltIsxt15TsfLkxobBpeWA0zZOv3qTs+28GGIosAEw6WqqE= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774837280; c=relaxed/simple; bh=5jCkHkfSjmkcxCScj0qC0OeI0UhHSFU2V935Ptpi2hE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=Jt8/eDzzOvgL/3mUHnIuiaGKDx8gY35MDvTvqpLcnLZIayGDTM9GxaXWE2elF8EWCZ06X9nGiLh5TvgVrgKSU6iyfD/1l/aD3rdMKKS08HM1jfaHVzyGqWbTRcyHL9sI20c6MDfX7VTPkP1efUVK+uRZLD6uwvCEtYMZvtgVWDk= 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=E7ubfA8g; arc=fail smtp.client-ip=40.93.201.53 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="E7ubfA8g" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=tUeoJHYt7Jq1A3FE7B9RSxkX4QNoTPocyy7x/84qX47Pr7AV9w43LYrfmkmWOIM3OPKpkCl+iRhIz/6/LWVg153v26skjA3SBtqfzHOoHg4tAVU3AuPV1CK6FVP12+4nNNuFGTS44TNoNMCQZAZ5zhINQ0iV6JEoK0eVQLtcLcAjIekaKUHNAl0c7IcgwiJQ5zAmWa97GMv4WMWWqc3I+TqUQtpeNOMG6kVocUYrsUYGnmD0c7WW8U0SIk9/CHfbVJsPfSOveqZCaxGSxNByEOoGleZSQ6fwWRHS7E2pUKvs/5adJVCi1yI8pxN+tqgrIjfVjitaOQ3JavHW3TGW8Q== 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=UliWCYJRUMR9BRXf11AHaTihcV0fXRLYJekfYILdXGK2i9znV9wl0YSfAOsS2iF0y3TM1HVvWMiD/TGVNJXRQekc/3V2O19AYvqtJkBSPeldfj3hax3meu1bXgoZW/WnL81uCNDuC9NP9X7PRutXaKQQa8IyA+XjMQi4w4s7ul9EosVFP2TtK/rhg5SCw248xnyfJHPG6q1xLToU302kf2mtCGp4Ne9d6Er8/WqKguYz0mPku6TtX8F6OmRX4WWu5lMoArxNynFgXnG3oxbBIcuoNEcqo5nF+0QfbJK5g9Okdt9wtEDB5S/S8UpzQxebJNtsVPEjWeFmWWAltfYh3w== 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=E7ubfA8glxQ1k2HiULFm4x+65hyqTjLD5rftMNQ0YbVlPfLaEh+MCqgjEmMZZRs3ZvvKfWcYUJvhQMTCX4s6FE8cxM9cJOAKedwofLHPF1pOP8NMTj9+WgePuj+hREbPv8OoxIwVNispQjdOcxslYKlosqtLgC1qTJ8ikKtopCEiB+URkD1d61NfO3Du50k80pMljJRrr3RgvP9xRWZOuNhnfRCDD/AMaJkF4WB1xUyVux8Byfk33C359oVeAwudjqk7XeSgkb3fTwQyP1co8A+nHjpeneFusXhBoyuM6b1NJHczOnHKd/JkIAwzUnNSF/eUWL2k4La+I2LD0Z+gVw== 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 CY3PR12MB9680.namprd12.prod.outlook.com (2603:10b6:930:100::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9769.15; Mon, 30 Mar 2026 02:21:14 +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; Mon, 30 Mar 2026 02:21:14 +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 v3 3/3] selftests: net: add bridge STP mode selection test Date: Sun, 29 Mar 2026 19:21:07 -0700 Message-ID: <20260330022107.670566-4-aroulin@nvidia.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260330022107.670566-1-aroulin@nvidia.com> References: <20260330022107.670566-1-aroulin@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BYAPR11CA0091.namprd11.prod.outlook.com (2603:10b6:a03:f4::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_|CY3PR12MB9680:EE_ X-MS-Office365-Filtering-Correlation-Id: d9530516-f6a6-4d14-2a93-08de8e030438 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|7416014|1800799024|366016|56012099003|22082099003|18092099006|18002099003; X-Microsoft-Antispam-Message-Info: PzssI01CwPE2Etg6xoppH8JOvczb4iti+8lJsLSZQaUbAfVYxJVtxjQXSeF6P/wXpDXXzHj36k+NFUWyhUati3xacFdTl9bFKsq0L6e03JmnQ0gbga1/nTpbS4gAb4NFg28s1/vdR2nAko3D6U3+6iFVAiRa1ODzfp7GtYYazzA3GQC1/dzDmYN4ig+wfnx2Hv5RGFeaqedrvI/jIVmN1tYQ4xn0nDCbdOiDwao4ccHmrh6PDTZ605abBZnp9kKkeO0cb1JFKLA8YzMMysa4QfcTkhBPEVi0/7mYoVQGzc9yKM4jYdmKuaCUbpiZsAD1125qDLhYx+/2TU7/9KGndFFTmpu9XaOBl/BnDqKdRJCNLwlDzpmYth3tlUoQ08c4qQZ2eBOkplti+UPslWbitH6lBrT5O5rLq+nXeCKcxvEd258QcnFpD9+ME3bTsFW1Re8WxZUnMN1ZYBzxJuiSqVw8zBWpgLHLzk8nz1TJrlXP4a3RAtYDYaC2cApsW1XHP+MwpNb49yjUw+BHy4x0gyYFNCLxQ+tYvk3M8FJDS1hYyYsPlnuh/YAW6L5hT+dwK3zvq6gRfaWjp8IEblsH7Vua/2551bv6wbVje54Pwyh4UIJ5sm1mujmtT0Bq285TQeI2oXFwyMHymMsKh2AL398M8vpNU2hsNNyHO4Z3x29xH5xZmZ7CE7PHXaH5LArGuV1I8hl+F4rv8dkOZ555rhlLb5hGEyIjmGfR+5P508k= 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)(376014)(7416014)(1800799024)(366016)(56012099003)(22082099003)(18092099006)(18002099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?IUWpEzoO21Q3cdBlTTXGjGEl8AkeeCKoIuaEVv6a9CMCKsYMnLfJhZCQL+Hs?= =?us-ascii?Q?/SGSC4EJ+8iO/dMvBQrOlVGop2yeHJJntVBpSMVsEc7Daq33f5H1H+nGoIsR?= =?us-ascii?Q?qq5jQ9JuXlgwPWPJa09vd21lHSy1n5cS81UGV3Vse7BpD/NV2c+dGLxB4npm?= =?us-ascii?Q?8RwB2KMThej4DFb2k7FtgRpVc13KbULKLGZf+dBOCIDZkataYnpWP3M5wzQ2?= =?us-ascii?Q?5zPT87+LvNjhmOs8TAzCYFG6S/qpvE6Xez21AFi+4cGkWLXINssCnfO3UPtB?= =?us-ascii?Q?t4xW7M4wNdQFhRLssHqgEUbUd8X/PAXkVsw+9mKXiqAD8o+jX1qJnTqoDiWA?= =?us-ascii?Q?jJfePY4W9yprG4dfoGXuAP5nWhVKUzdKxKHRWTfiwBSZIHmVfxv5pWNkY8Gw?= =?us-ascii?Q?e2M8WQXueUvpZRasczqMffph3vjr3BFlPIfUwWaTXH5ttRX5SnXQflk8l62k?= =?us-ascii?Q?heSX2Y1IL0/TV4vu+4L9kByWU3I+Ya0XvvQOz5EyhvKxsXxLpgqvUewim/g3?= =?us-ascii?Q?cBBsXFnSIx6bOlr8RPhZfXpC0oSGsSUACEP32bNz62xMuXXeDBzUTtCsEgUw?= =?us-ascii?Q?oYoOIEndbny6w8AmtekpoW6OiHiEkO86rmNVSWrF3DPBTmO5S5KwEAj4d1j/?= =?us-ascii?Q?pHhDNRmvfNZcio3Rtjb7h/a0ih0bTxtAN4P62WrknprGcxxRq8fKyFTyCapl?= =?us-ascii?Q?YcUPqmrp683Ioiktu3OWcwiXji5eGeeYkshO9SA8x1X1sNh3ONOvFQbnqevt?= =?us-ascii?Q?kMCRWggnVNk7hPyrsPbR3YJMbWZP1Tbq6G5LzEMWYXpCL+zxM9L9Hl1T1ctq?= =?us-ascii?Q?I/H1/0lQoyifinpn93drsL3HMyaBvZ9CgJH7HkuE3DAs6CjcjV70oqwNaCle?= =?us-ascii?Q?NhjAW/eUIi+zVJAlM6z1Wp25PzMo/fWUnJLeVafZRqWiR2+S7RshaHwxBdjF?= =?us-ascii?Q?z9FTI2lSNPPo7Nt8YogLAmCsVdf3bX8v3q+j2owrl7w0850E06GP6DDBOT6M?= =?us-ascii?Q?Kr/X3R/6z78JYmtiTopZu/h7XYhMtLHqj3sTogdgMgXYcyZQiPjCSYWZ/lJa?= =?us-ascii?Q?cwxhSXAj8lUM5wCFZ6SN2rGtDHczYI0eTPIDh2YoD0yUq3xI9OFzMLdh42RT?= =?us-ascii?Q?tcIFBDCZGZOLz2u70hnqmauLO5Ond8V/H4fknJspw48PhGorRNgQy/Ax/8w1?= =?us-ascii?Q?kOHUBDNV2p4hu1zb4YtneQt3VTIziArNB6+3hwy2awaH6rP9tELWfaazYYXQ?= =?us-ascii?Q?laf+eQWh1LSmlLST1DGtWArU9+9G51HPgKze/Fa0t2/xug/voRsbWtOKDI9j?= =?us-ascii?Q?rikAKV/baRDu2N+qq0d6CkHEMPR42IFoRon7k6Dq5CbAtNascVx70Z2UWRXM?= =?us-ascii?Q?X0XrediiHQFKBYZkwmT2NFjlQ1H8X3i7ETLdjqknKROc/9o3NZKJcvPOW57r?= =?us-ascii?Q?GB1uiFCpE7vKx2Aoor8YrF3o/I4n9NhcveUBP4/N68gog7vLMCM5wkzN4Amx?= =?us-ascii?Q?V7Q418RX/y0Y4RHn8BSVKe3r8RWOyVBDFJ1FO2GwR2wWmr3WUdkd73lJgkO1?= =?us-ascii?Q?crLgmekgLJGc1vCKAEwonez9khpl30fMj7nLXEVZVSuZzSyL7YELZ6WTbxou?= =?us-ascii?Q?7H3+swmOYhwCn9rZG+kvLHWYVxXAJH8LyAFF7Kfq87d/9WN+wIocgwBQSM6u?= =?us-ascii?Q?my/muHi/o0Crdzp0hE+GhDRyRVynAdVZZbcrs4skzfKv8fEca166kgE8oXDR?= =?us-ascii?Q?0j55+dEXxw=3D=3D?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: d9530516-f6a6-4d14-2a93-08de8e030438 X-MS-Exchange-CrossTenant-AuthSource: DS7PR12MB8202.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Mar 2026 02:21:14.1190 (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: laPaWE3MDEn2cZi4p9L1+5nGypAicV+EAulN/KSTLTxySYLVEriWqApEiPK1kOjHASC39CjlxfVbaCpw3EnPlA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY3PR12MB9680 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