From nobody Tue Apr 7 15:26:13 2026 Received: from mail-pl1-f177.google.com (mail-pl1-f177.google.com [209.85.214.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E1374377540 for ; Thu, 26 Feb 2026 11:43:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772106201; cv=none; b=GfeXzTOVCZzrvS5dRA9vIfnDt4QbDRcUprI/IhmrMZzT5VjMr8vl6tqcrKZp+NyZusSpPBbfvkht5MKRB9pOj+eNEOoPVks3TFHlyPRvB/0MY9m2svbKH62PlxO2nh3LbLH+KpUY08+3CV3yb2N3BZU5GhbJdrbs3zIsODeXtuQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772106201; c=relaxed/simple; bh=GzjQ1QrmncB3M8ZZh2gze1EuHsDImbS4oU69hNkTzxU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WejnHCQ/TzoSoJWDis9lBwgJDnfv1VN9qCxiBAkzLGknW7YCLPInjRUAlpqIDBInDPcHoXXeParM2HkUy+uAnzeLWATq3Vo9PnweD+xBdHHcQnwOUkCDGlfwiMGTtk4VbuqY554Uh9pwl620Ez4dGMruGd7vnxrw/fCZl1ffvnI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=N7kXG/zL; arc=none smtp.client-ip=209.85.214.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="N7kXG/zL" Received: by mail-pl1-f177.google.com with SMTP id d9443c01a7336-2adcede372cso2983125ad.0 for ; Thu, 26 Feb 2026 03:43:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772106199; x=1772710999; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=4ciG01gWGaVHVP/mcZG8G3rAKieiLmIPuwLg8daH8Bc=; b=N7kXG/zLaNi1ZAQ7AJAqUJQxOVdwfK0I8LmmvNRfdxaEIybICnPjxHdN5HcT3A02HY oM2iVro0BLsp/WKWiGiwM4iOEHntbmvEGHUFbwmlFY8BEsrB30DEidmWOn3LuYlnJVkw dMMAXEnMRDu3grtp3+HJ8O9Id/ZIiofDu+2e3m4s4MISTCpR749peJb6VZrn+IQ40I5v qkQp5ZIJVmEMyHPmAKGMWmHrcw080Ylfc4t+BIL3Cyt81zaz6cUP3M8gRLQtXUP8AyDs 7tC1XCUOUkd8sSfe+6juDnhdA8f5XEH+uDljxFyWg41bp6xMMQpkxJceoU6rx5XpMKa4 zVIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772106199; x=1772710999; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=4ciG01gWGaVHVP/mcZG8G3rAKieiLmIPuwLg8daH8Bc=; b=aGwmpYuW7Yv4oqk/1jMmYy1KKCLGrsM7KBxuUOOTXUYDEkwuBXrHiOrxug10N8BkyC pov0Ysafh7T/p5M7kpXAwGslCDA1rIZDk41RP4Ftq0AGCrNvcn/3YYUgPmhvNdjvv6c6 fnm1/F/FkqsHLcmw/qydbfmN1e97ui2wX9JipGhVOEemS645H3881bIENgILDhBZ6VAf isFnx8I863Fc/mXZLmwh+yx2alh9g4EjPSM2lMHQbUUinoXFtpFP4Dy5AUUFpO5PMTDv h+dPhiHl4glQte8LVmXG8kfpY6dCd2RX8B1oJ5iUim7HX3Ec70Yi/ifUzyHLf+0pG/vM sApA== X-Forwarded-Encrypted: i=1; AJvYcCVgRwIXD2AIAhxr1PphsOmwXFBaA3PzuFViTRACYM35MLiymhPvp302tftxj9hpXZvjRV8uiHlhnfnU/Sc=@vger.kernel.org X-Gm-Message-State: AOJu0Yyb4SyicR/+lzXP99QcKw4pJZ6hIhF7WOe0s24RIGqNMI+bKsPn tryEKknBXcp/gNfin+x06f5obFr8P/AmByMHuUGjioSh31N3WR59+btF X-Gm-Gg: ATEYQzwmYxDU4AJXNmQ1TCnv4Az1JicZpvTyjYruPUQNxhMWPGac9M1uoBLK5tbi7Rs tSO+Xbng+/8fuZDMqGh2pjrRmU1Xy94FGdg7S2qMBdGb2SLff9dCnoIwmBLer3hfzSRIw9GT/zM 8yQXdm1fIte/xLuzRwuBBUW5Cgcz+s9QFzW6H2/KwqMULv5CSE0/k1Yk64QCUhAzQ+cc+wiW1Wv 8715fuadEGoqiQbk1gSucBnKZBv95RE3EGRQOo47VURefPeTTTWkfkhGDFqao6WezQwBXUV1uJI ThowC+xShRpjVVf1UboTzWQ/lL8eQS9DSWDEtZF2ehE207CFVsfr3WwgkHovsYGJ+GK4B3EX+KU 45CGTLLBZh1ql1LGqu55FjLt1/UJSNFaEyGI5yGgcCH0Kxh0fQglvmBIJYT2qY6J9HjMQcZmqUa rRV1aerZlpHKdga8naCn8LnnHglQc= X-Received: by 2002:a17:903:32d2:b0:2aa:f2f3:bcb0 with SMTP id d9443c01a7336-2ae036e631amr24181285ad.47.1772106199007; Thu, 26 Feb 2026 03:43:19 -0800 (PST) Received: from fedora ([209.132.188.88]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2adfb5dbac7sm34131545ad.37.2026.02.26.03.43.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 Feb 2026 03:43:18 -0800 (PST) From: Hangbin Liu To: netdev@vger.kernel.org Cc: Jay Vosburgh , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Sridhar Samudrala , Jiri Pirko , Simon Horman , Nikolay Aleksandrov , Ido Schimmel , Stanislav Fomichev , Kuniyuki Iwashima , Samiullah Khawaja , Ahmed Zaki , Alexander Lobakin , linux-kernel@vger.kernel.org, bridge@lists.linux.dev, Hangbin Liu Subject: [RFC PATCH net-next 1/3] net: add ndo_update_offloads Date: Thu, 26 Feb 2026 11:42:06 +0000 Message-ID: <20260226114208.27774-2-liuhangbin@gmail.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260226114208.27774-1-liuhangbin@gmail.com> References: <20260226114208.27774-1-liuhangbin@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a new ndo_update_offloads callback to net_device_ops that allows devices to compute and update their offload features during feature updates. This callback enabling master devices to recompute their features based on current slave device configuration. This is particularly useful for bonding, bridging, team, and failover devices that need to aggregate features from their lower devices. The callback is optional and only implemented by devices that need dynamic offload feature computation. Signed-off-by: Hangbin Liu --- include/linux/netdevice.h | 7 +++++++ net/core/dev.c | 3 +++ 2 files changed, 10 insertions(+) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index d4e6e00bb90a..1169091ccb9a 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1281,6 +1281,12 @@ struct netdev_net_notifier { * constraints, and returns the resulting flags. Must not modify * the device state. * + * void (*ndo_update_offloads)(struct net_device *dev); + * Called during feature update to allow device to compute and update + * offload features (like vlan_features, hw_enc_features) based on + * current lower device configuration. Typically used by master + * devices to aggregate features from slave devices. + * * int (*ndo_set_features)(struct net_device *dev, netdev_features_t featu= res); * Called to update device configuration to new features. Passed * feature set might be less than what was returned by ndo_fix_features()). @@ -1558,6 +1564,7 @@ struct net_device_ops { struct sock *sk); netdev_features_t (*ndo_fix_features)(struct net_device *dev, netdev_features_t features); + void (*ndo_update_offloads)(struct net_device *dev); int (*ndo_set_features)(struct net_device *dev, netdev_features_t features); int (*ndo_neigh_construct)(struct net_device *dev, diff --git a/net/core/dev.c b/net/core/dev.c index 096b3ff13f6b..d05837c0713a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -10982,6 +10982,9 @@ int __netdev_update_features(struct net_device *dev) ASSERT_RTNL(); netdev_ops_assert_locked(dev); =20 + if (dev->netdev_ops->ndo_update_offloads) + dev->netdev_ops->ndo_update_offloads(dev); + features =3D netdev_get_wanted_features(dev); =20 if (dev->netdev_ops->ndo_fix_features) --=20 2.50.1 From nobody Tue Apr 7 15:26:13 2026 Received: from mail-pl1-f176.google.com (mail-pl1-f176.google.com [209.85.214.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 35BED37649A for ; Thu, 26 Feb 2026 11:43:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772106208; cv=none; b=fHPrNwMGd8oriooXXjBoSCNNEWMKl+b+DcB/UKl1QDSs0AReS5v9IYpsNERZgksf8I/PTZDyeSnqf4iQPzEcqmRYlzzBMvjA2QUbTX5cFeIwrgglxRye7Hxnl/QmDhCFt8c9su/3PXaEiTPwdFnsak8eDOTYTxw4dOnhGVwilPc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772106208; c=relaxed/simple; bh=QE7+shqhYrIkkr0DVQn90AztuymZ6yT+ozQWHEu81W4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bf3zST5PTC5fDs/rumTDcVTBZIcvNxJgsDMXNdsI3U5uyjhV1FPlLWkRBuKtU3C8xATK1bKSySxmHRNBv1Xu9nHsJCEixA4jch9Bnuy5W/G9onNroSxS6xWDTKHIhbngGAEUIMbzNCczC0tyxzztyJ/uUzysnuYFp3IiMPCgumE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=WiR3Z1F0; arc=none smtp.client-ip=209.85.214.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="WiR3Z1F0" Received: by mail-pl1-f176.google.com with SMTP id d9443c01a7336-2aaed195901so3576165ad.0 for ; Thu, 26 Feb 2026 03:43:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772106206; x=1772711006; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=K8tCHRpr4wzppgYjorSC40fFUhqaMIZWAyWgimJgq3o=; b=WiR3Z1F0IV9Y2mvK+eYp/fD73mu9BjjmLY8R039NeQOqwvKuR/5qsenve69DxXMwDw cro0QsnhBXcELBM1MAPsehsoP+nWHnDBhvryavmidxy158Rj2/sb5aF2yROXhqSO0ML8 ih03o1gJK9a1WobvNR8Red3mbLDqE2VT+XtF23exNyzU01VDBCaTJJ7GRaXlpK3mqm5B /FDqTnQUofodlCt5v/Qdj8oL+p8krtA3z7+0o7pVkTMBPZhVYaBtF7eEMcH2PwHZe/3/ DvNmjpleD5XHDjXsqgoAmm7o2EfpItMeWcsO/pIavJT+k/ZOyz0w53s6yIgvVAQPVp+7 diaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772106206; x=1772711006; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=K8tCHRpr4wzppgYjorSC40fFUhqaMIZWAyWgimJgq3o=; b=Y6Eas3uE+XYAB7GtMpf6bU8wOxPnyDFPl8wcajeA74au7z2VThK5XHo6mg1c6Fl3nK 3EpLcPbvGecshFcJrCDT1zP0jlV0J0v4dA78a8slVAfZfGGOTAy4Q+/snVvmqw54cQEk 2hG+6IPmvoLeAGCzB9CNSQGX4xqjVoFuQ7RR0GIjxytrBmviChPA98+eIyMzj8af2cCj Wu/t0sr68VHGjBXnT7hpgtz9/Dd+zSGoOd1Gil6K+jQYHOploKQYmpnTrQkwCfQA76jf NBe97QOpzonjExL+QW9Hf94JOIWaLLR9RBd24ypSsNih6lH/E2CURrYoBmQ3Qf6jOq4p PLHg== X-Forwarded-Encrypted: i=1; AJvYcCXszMtaSVYOcTeOughIWZHvq25gEgR3kZ3YCyMcrDlvEjrQRRX6mCxMApJnsMPhLnk4jq1uNG2a1JApgyU=@vger.kernel.org X-Gm-Message-State: AOJu0YxqWA0EZhxZPS0R0Yi7xkz31bEOVUPMCIme9skVgL42ixdpO0E7 jyG5tE0XvN7APVrZ4zggvirqZNH0X/ydQFD7Tq7wz2xy+TU9n/aUVNr1 X-Gm-Gg: ATEYQzwLUrV/XgLA8v3siicFzxY8pa319l6Um/fq4HyMoR69HlPtHrESaBgEJAwTWyG WHxaJzLFR7hr4lSR05XSZdLfrbCeL/JI4TKT+S+6F1JSNbZSmvKbz6pVb1OUNjpKVETvx6YTR2y tjdrlRuZOdR5Og+k/9PdBuJOHep6LiZDf7tkAda+30bVO2JnMKvAwAfDeMS5MFi8y2HYSJSLNQs N16sRgixCm5Gacdv/KV2bb4NBM9GPohr4smn9R4iLD7jzcKZQppq0QxKf+9f1ImSSynrNZroE9l ctMOZ3RMd4SGk+t0KlWDKd7rQgD1CXnY0YBJQZuJyn0BoK6msF32ML3x6fkRHK02xmP5h7L++IP nY2sBhBd6ynARKZ2rvTrrG8fid/T0iPtXVLOK3nr+8s7IgPZ0svd9aioLppxSnUERpjftVMVaDh LfJhOp8H6QT3c2jjU8Wtx5KVoT5uo= X-Received: by 2002:a17:902:ce84:b0:2ad:ba04:40cd with SMTP id d9443c01a7336-2adba0442abmr77452645ad.22.1772106206343; Thu, 26 Feb 2026 03:43:26 -0800 (PST) Received: from fedora ([209.132.188.88]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2adfb5dbac7sm34131545ad.37.2026.02.26.03.43.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 Feb 2026 03:43:26 -0800 (PST) From: Hangbin Liu To: netdev@vger.kernel.org Cc: Jay Vosburgh , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Sridhar Samudrala , Jiri Pirko , Simon Horman , Nikolay Aleksandrov , Ido Schimmel , Stanislav Fomichev , Kuniyuki Iwashima , Samiullah Khawaja , Ahmed Zaki , Alexander Lobakin , linux-kernel@vger.kernel.org, bridge@lists.linux.dev, Hangbin Liu Subject: [RFC PATCH net-next 2/3] net: use ndo_update_offloads for bonding/bridge/team Date: Thu, 26 Feb 2026 11:42:07 +0000 Message-ID: <20260226114208.27774-3-liuhangbin@gmail.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260226114208.27774-1-liuhangbin@gmail.com> References: <20260226114208.27774-1-liuhangbin@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Convert bonding, bridge, and team drivers to use the new ndo_update_offloads callback instead of manually calling netdev_compute_master_upper_features() during port add/remove operations. This change centralizes the feature computation flow: Before: - netdev_compute_master_upper_features() - compute offload features - netdev_change_features() - __netdev_update_features() - update other features After: - netdev_master_upper_dev_link() - __netdev_upper_dev_link() - netdev_change_features() - __netdev_update_features() - ndo_update_offloads() - netdev_compute_master_upper_features() - update other features This ensures offload features are computed automatically when upper/lower device links change, removing the need for manual feature computation calls in the driver code. The netdev_change_features() call in team_uninit() is also removed since it calls team_port_del() for each port, which now triggers feature updates automatically. Signed-off-by: Hangbin Liu --- drivers/net/bonding/bond_main.c | 10 +++++++--- drivers/net/team/team_core.c | 11 +++++++---- net/bridge/br_device.c | 6 ++++++ net/bridge/br_if.c | 4 ---- net/core/dev.c | 8 ++++++-- 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_mai= n.c index 55a960da42b5..dc524f595e28 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1504,6 +1504,11 @@ static netdev_features_t bond_fix_features(struct ne= t_device *dev, return features; } =20 +static void bond_update_offloads(struct net_device *dev) +{ + netdev_compute_master_upper_features(dev, true); +} + static void bond_setup_by_slave(struct net_device *bond_dev, struct net_device *slave_dev) { @@ -2224,7 +2229,6 @@ int bond_enslave(struct net_device *bond_dev, struct = net_device *slave_dev, } =20 bond->slave_cnt++; - netdev_compute_master_upper_features(bond->dev, true); bond_set_carrier(bond); =20 /* Needs to be called before bond_select_active_slave(), which will @@ -2479,7 +2483,6 @@ static int __bond_release_one(struct net_device *bond= _dev, call_netdevice_notifiers(NETDEV_RELEASE, bond->dev); } =20 - netdev_compute_master_upper_features(bond->dev, true); if (!(bond_dev->features & NETIF_F_VLAN_CHALLENGED) && (old_features & NETIF_F_VLAN_CHALLENGED)) slave_info(bond_dev, slave_dev, "last VLAN challenged slave left bond - = VLAN blocking is removed\n"); @@ -3971,7 +3974,7 @@ static int bond_slave_netdev_event(unsigned long even= t, case NETDEV_FEAT_CHANGE: if (!bond->notifier_ctx) { bond->notifier_ctx =3D true; - netdev_compute_master_upper_features(bond->dev, true); + netdev_change_features(bond->dev); bond->notifier_ctx =3D false; } break; @@ -5895,6 +5898,7 @@ static const struct net_device_ops bond_netdev_ops = =3D { .ndo_add_slave =3D bond_enslave, .ndo_del_slave =3D bond_release, .ndo_fix_features =3D bond_fix_features, + .ndo_update_offloads =3D bond_update_offloads, .ndo_features_check =3D passthru_features_check, .ndo_get_xmit_slave =3D bond_xmit_get_slave, .ndo_sk_get_lower_dev =3D bond_sk_get_lower_dev, diff --git a/drivers/net/team/team_core.c b/drivers/net/team/team_core.c index c08a5c1bd6e4..fa62965b61de 100644 --- a/drivers/net/team/team_core.c +++ b/drivers/net/team/team_core.c @@ -1249,7 +1249,6 @@ static int team_port_add(struct team *team, struct ne= t_device *port_dev, port->index =3D -1; list_add_tail_rcu(&port->list, &team->port_list); team_port_enable(team, port); - netdev_compute_master_upper_features(team->dev, true); __team_port_change_port_added(port, !!netif_oper_up(port_dev)); __team_options_change_check(team); =20 @@ -1333,7 +1332,6 @@ static int team_port_del(struct team *team, struct ne= t_device *port_dev) dev_set_mtu(port_dev, port->orig.mtu); kfree_rcu(port, rcu); netdev_info(dev, "Port device %s removed\n", portname); - netdev_compute_master_upper_features(team->dev, true); =20 return 0; } @@ -1641,7 +1639,6 @@ static void team_uninit(struct net_device *dev) team_mcast_rejoin_fini(team); team_notify_peers_fini(team); team_queue_override_fini(team); - netdev_change_features(dev); } =20 static void team_destructor(struct net_device *dev) @@ -1959,6 +1956,11 @@ static netdev_features_t team_fix_features(struct ne= t_device *dev, return features; } =20 +static void team_update_offloads(struct net_device *dev) +{ + netdev_compute_master_upper_features(dev, true); +} + static int team_change_carrier(struct net_device *dev, bool new_carrier) { struct team *team =3D netdev_priv(dev); @@ -1994,6 +1996,7 @@ static const struct net_device_ops team_netdev_ops = =3D { .ndo_add_slave =3D team_add_slave, .ndo_del_slave =3D team_del_slave, .ndo_fix_features =3D team_fix_features, + .ndo_update_offloads =3D team_update_offloads, .ndo_change_carrier =3D team_change_carrier, .ndo_features_check =3D passthru_features_check, }; @@ -2931,7 +2934,7 @@ static int team_device_event(struct notifier_block *u= nused, case NETDEV_FEAT_CHANGE: if (!port->team->notifier_ctx) { port->team->notifier_ctx =3D true; - netdev_compute_master_upper_features(port->team->dev, true); + netdev_change_features(port->team->dev); port->team->notifier_ctx =3D false; } break; diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index a818fdc22da9..3f2e8f5249fb 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -289,6 +289,11 @@ static netdev_features_t br_fix_features(struct net_de= vice *dev, return br_features_recompute(br, features); } =20 +static void br_update_offloads(struct net_device *dev) +{ + netdev_compute_master_upper_features(dev, false); +} + #ifdef CONFIG_NET_POLL_CONTROLLER static void br_poll_controller(struct net_device *br_dev) { @@ -456,6 +461,7 @@ static const struct net_device_ops br_netdev_ops =3D { .ndo_add_slave =3D br_add_slave, .ndo_del_slave =3D br_del_slave, .ndo_fix_features =3D br_fix_features, + .ndo_update_offloads =3D br_update_offloads, .ndo_fdb_add =3D br_fdb_add, .ndo_fdb_del =3D br_fdb_delete, .ndo_fdb_del_bulk =3D br_fdb_delete_bulk, diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 4c67a32745f6..7806436340ef 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -680,8 +680,6 @@ int br_add_if(struct net_bridge *br, struct net_device = *dev, =20 br_mtu_auto_adjust(br); =20 - netdev_compute_master_upper_features(br->dev, false); - kobject_uevent(&p->kobj, KOBJ_ADD); =20 return 0; @@ -734,8 +732,6 @@ int br_del_if(struct net_bridge *br, struct net_device = *dev) if (changed_addr) call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev); =20 - netdev_compute_master_upper_features(br->dev, false); - return 0; } =20 diff --git a/net/core/dev.c b/net/core/dev.c index d05837c0713a..7043ee022980 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -8893,6 +8893,9 @@ static int __netdev_upper_dev_link(struct net_device = *dev, __netdev_walk_all_upper_dev(upper_dev, __netdev_update_lower_level, priv); =20 + /* re-compute all features after adding link */ + netdev_change_features(upper_dev); + return 0; =20 rollback: @@ -8985,6 +8988,9 @@ static void __netdev_upper_dev_unlink(struct net_devi= ce *dev, __netdev_update_lower_level(upper_dev, priv); __netdev_walk_all_upper_dev(upper_dev, __netdev_update_lower_level, priv); + + /* re-compute all features after removing link */ + netdev_change_features(upper_dev); } =20 /** @@ -12851,8 +12857,6 @@ void netdev_compute_master_upper_features(struct ne= t_device *dev, bool update_he =20 netif_set_tso_max_segs(dev, tso_max_segs); netif_set_tso_max_size(dev, tso_max_size); - - netdev_change_features(dev); } EXPORT_SYMBOL(netdev_compute_master_upper_features); =20 --=20 2.50.1 From nobody Tue Apr 7 15:26:13 2026 Received: from mail-pl1-f172.google.com (mail-pl1-f172.google.com [209.85.214.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2DB0937B3FE for ; Thu, 26 Feb 2026 11:43:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772106215; cv=none; b=MNsOIwd8HsqzDFojFymublZxE7C7gZewovlg6sutOXDw9C7fT+sEs0VQkyV5aPSWawQzarQ02rMwBWEghZ1KQ6ihHeCxvTCGslZis1aTv0u8U6m7/IXE4IK/TiWZwdq9+rmO2AxBqFOhHFjFwjNLMuwFFBp1LnMPnT+NfIql3o0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772106215; c=relaxed/simple; bh=W8/P9pOZ2TaGtqC+2IqlgV4WZxsB2rdjDd83Ft34dw4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Z9/OCWC5qUuFMr3F/Ff9YP9BU2mDXUgGo2ax5yNOm+qW7GaYU4CUTMtvh01HtOvg9adqgKl4w5LKpYfPnjUvVhY87egNDZrGde/JQeG/yZ9/wutZnHrOHbxVucj91b/RIeYBXAsoa/USdrn8Pq9O2ktnfSk7RI4E6Tm73FlEHeQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=ERy1PxuB; arc=none smtp.client-ip=209.85.214.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ERy1PxuB" Received: by mail-pl1-f172.google.com with SMTP id d9443c01a7336-2a871daa98fso5739475ad.1 for ; Thu, 26 Feb 2026 03:43:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772106213; x=1772711013; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=PbhS0NvKYgSA4IUttJNgnpP91LFlge369iIxmO7B660=; b=ERy1PxuBzHujcE1H+s+0KuXiE01OUdcIDWsRStKHS7fjsmiGejgn0LtD7JWVlS8xe0 jM5FwmnimPE+AQG1gOPPqx9uZoGEADLI9ww2DYFUJLX2bNracRCBjr03iqm3a8iAIYNU yTETcdfxXLctMH5wn/77vfQYGgUYiPqoiI+iDbH6qa9ROJ6755NOXHJRugP3X3BPbYl1 K271h7Lq5XaWmIHTEy9+aTr+9Fewnitp8wrPy2WfyrqUWR6/T8n9ab7XrR5zNMZ98nrb uncN3fcEk7dEvhBkmLSNhi2c/JzrwegcCwMo8eN4KXN7cm4VuUN4JE5oDU3cZK8FCRUI SO/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772106213; x=1772711013; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=PbhS0NvKYgSA4IUttJNgnpP91LFlge369iIxmO7B660=; b=Le+mqixvHn7c80pVcvwguGQZFxovuTuv9qROeOwjZ3ongKXScZbwVaJy2PaGCfNSxR 0T1bB75qkPD/iI4LkMrctJm4p5ggL0rVe4G+UKY4hJhYIGGiIJo5BmXBTScrhywVM9yE qezO841i8NMZeb4bZHBw8dgj+dar5gN//qZ3/pi1tXqtHpg8PygAbVYUfQnrSldk3EUz txkdN1UM0cJlyEzt4N2dTn57FnPuQ9kNbzvJkfCGRiMgnXMIeidNVOFMzLt2v89WaLgv rbPoIKn9FjplqXYlI9iFzeirI7kj5HnTezGyir1qUVyEICzMNSnLdTjK8ubMgF44MinZ 0Ijw== X-Forwarded-Encrypted: i=1; AJvYcCXCv2hCCm1/S3uO/cmp4sv+2qpMk9FK8Lr+72l+GfMACZIho+uKW6q+GLYbPdqKsLC6UDi5z9gFLvX9NS0=@vger.kernel.org X-Gm-Message-State: AOJu0Yxk8NPgRKH0EEgSdsixPBRrIlQeW5+vEOzRW/Ml/RrAFXSAg8rZ PRLTg5nScpXqVmYJh+F0PPAngXAuVgBFqUeewFj5MxxoIGnOc2TfQU29 X-Gm-Gg: ATEYQzxuDFwWI/37KDt9QrgTEbA0xRFkPrqFoLhuGV2kDOOvaBGOK87eWVLmucwDfng Ie6xAwnudNtRXxdgZNgX1vR4eKmJ5lE0XARnm6PgE7i75N/MJ0m5wdH3H6k6tIm3RUALn9R1peq tBfTaKXfWUzn0JXey2j5HaXyNdmZcEDwbsAxdk8flMMjwiONpkM2jPYY+ERQkBE8NM9yDEWCo3G ZeetPjhXOiSW1iAMruSA4ksyLUlfhODYLrmIoXYadRIrajGfNzQ5BaCXAHpi1uGX80u3Sy7zUL1 lkYtwrjs00Pf/UkVHRwxhtiSp/GB3DoENtqgirwBMTdm3UKv8Co1zxFpTuiQzIXc7Qs6tY/LXVD 8RBBmyUOSEpihzia9podHuAdo1ZclpIcciIcCr72MBDjhhXwQV8z+vMEDlde2UPR8FeD0yiczhj GRVWaZSap1exIrSsaj/uo0IfVVnwY= X-Received: by 2002:a17:902:f68c:b0:2ad:ae4f:3468 with SMTP id d9443c01a7336-2ade9a4fd5cmr39424435ad.38.1772106213588; Thu, 26 Feb 2026 03:43:33 -0800 (PST) Received: from fedora ([209.132.188.88]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2adfb5dbac7sm34131545ad.37.2026.02.26.03.43.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 Feb 2026 03:43:33 -0800 (PST) From: Hangbin Liu To: netdev@vger.kernel.org Cc: Jay Vosburgh , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Sridhar Samudrala , Jiri Pirko , Simon Horman , Nikolay Aleksandrov , Ido Schimmel , Stanislav Fomichev , Kuniyuki Iwashima , Samiullah Khawaja , Ahmed Zaki , Alexander Lobakin , linux-kernel@vger.kernel.org, bridge@lists.linux.dev, Hangbin Liu Subject: [RFC PATCH net-next 3/3] failover: use .ndo_update_offloads for failover Date: Thu, 26 Feb 2026 11:42:08 +0000 Message-ID: <20260226114208.27774-4-liuhangbin@gmail.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260226114208.27774-1-liuhangbin@gmail.com> References: <20260226114208.27774-1-liuhangbin@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Convert net_failover to use the new ndo_update_offloads callback instead of manually calling netdev_compute_master_upper_features() during slave registration/unregistration. This simplifies the failover code significantly by removing the custom feature computation logic and relying on the centralized feature update mechanism. The callback is automatically invoked during feature updates when upper/lower device links change. Signed-off-by: Hangbin Liu --- drivers/net/net_failover.c | 64 ++++---------------------------------- include/net/net_failover.h | 7 ----- 2 files changed, 6 insertions(+), 65 deletions(-) diff --git a/drivers/net/net_failover.c b/drivers/net/net_failover.c index d0361aaf25ef..527175f554a6 100644 --- a/drivers/net/net_failover.c +++ b/drivers/net/net_failover.c @@ -300,6 +300,11 @@ static int net_failover_vlan_rx_kill_vid(struct net_de= vice *dev, __be16 proto, return 0; } =20 +static void failover_update_offloads(struct net_device *dev) +{ + netdev_compute_master_upper_features(dev, true); +} + static const struct net_device_ops failover_dev_ops =3D { .ndo_open =3D net_failover_open, .ndo_stop =3D net_failover_close, @@ -312,6 +317,7 @@ static const struct net_device_ops failover_dev_ops =3D= { .ndo_vlan_rx_kill_vid =3D net_failover_vlan_rx_kill_vid, .ndo_validate_addr =3D eth_validate_addr, .ndo_features_check =3D passthru_features_check, + .ndo_update_offloads =3D failover_update_offloads, }; =20 #define FAILOVER_NAME "net_failover" @@ -373,61 +379,6 @@ static rx_handler_result_t net_failover_handle_frame(s= truct sk_buff **pskb) return RX_HANDLER_ANOTHER; } =20 -static void net_failover_compute_features(struct net_device *dev) -{ - netdev_features_t vlan_features =3D FAILOVER_VLAN_FEATURES & - NETIF_F_ALL_FOR_ALL; - netdev_features_t enc_features =3D FAILOVER_ENC_FEATURES; - unsigned short max_hard_header_len =3D ETH_HLEN; - unsigned int dst_release_flag =3D IFF_XMIT_DST_RELEASE | - IFF_XMIT_DST_RELEASE_PERM; - struct net_failover_info *nfo_info =3D netdev_priv(dev); - struct net_device *primary_dev, *standby_dev; - - primary_dev =3D rcu_dereference(nfo_info->primary_dev); - if (primary_dev) { - vlan_features =3D - netdev_increment_features(vlan_features, - primary_dev->vlan_features, - FAILOVER_VLAN_FEATURES); - enc_features =3D - netdev_increment_features(enc_features, - primary_dev->hw_enc_features, - FAILOVER_ENC_FEATURES); - - dst_release_flag &=3D primary_dev->priv_flags; - if (primary_dev->hard_header_len > max_hard_header_len) - max_hard_header_len =3D primary_dev->hard_header_len; - } - - standby_dev =3D rcu_dereference(nfo_info->standby_dev); - if (standby_dev) { - vlan_features =3D - netdev_increment_features(vlan_features, - standby_dev->vlan_features, - FAILOVER_VLAN_FEATURES); - enc_features =3D - netdev_increment_features(enc_features, - standby_dev->hw_enc_features, - FAILOVER_ENC_FEATURES); - - dst_release_flag &=3D standby_dev->priv_flags; - if (standby_dev->hard_header_len > max_hard_header_len) - max_hard_header_len =3D standby_dev->hard_header_len; - } - - dev->vlan_features =3D vlan_features; - dev->hw_enc_features =3D enc_features | NETIF_F_GSO_ENCAP_ALL; - dev->hard_header_len =3D max_hard_header_len; - - dev->priv_flags &=3D ~IFF_XMIT_DST_RELEASE; - if (dst_release_flag =3D=3D (IFF_XMIT_DST_RELEASE | - IFF_XMIT_DST_RELEASE_PERM)) - dev->priv_flags |=3D IFF_XMIT_DST_RELEASE; - - netdev_change_features(dev); -} - static void net_failover_lower_state_changed(struct net_device *slave_dev, struct net_device *primary_dev, struct net_device *standby_dev) @@ -550,7 +501,6 @@ static int net_failover_slave_register(struct net_devic= e *slave_dev, } =20 net_failover_lower_state_changed(slave_dev, primary_dev, standby_dev); - net_failover_compute_features(failover_dev); =20 call_netdevice_notifiers(NETDEV_JOIN, slave_dev); =20 @@ -621,8 +571,6 @@ static int net_failover_slave_unregister(struct net_dev= ice *slave_dev, =20 dev_put(slave_dev); =20 - net_failover_compute_features(failover_dev); - netdev_info(failover_dev, "failover %s slave:%s unregistered\n", slave_is_standby ? "standby" : "primary", slave_dev->name); =20 diff --git a/include/net/net_failover.h b/include/net/net_failover.h index b12a1c469d1c..f0f038d113a0 100644 --- a/include/net/net_failover.h +++ b/include/net/net_failover.h @@ -30,11 +30,4 @@ struct net_failover_info { struct failover *net_failover_create(struct net_device *standby_dev); void net_failover_destroy(struct failover *failover); =20 -#define FAILOVER_VLAN_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \ - NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \ - NETIF_F_HIGHDMA | NETIF_F_LRO) - -#define FAILOVER_ENC_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \ - NETIF_F_RXCSUM | NETIF_F_ALL_TSO) - #endif /* _NET_FAILOVER_H */ --=20 2.50.1