public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH net-next 0/3] net: add ndo_update_offloads for offload computation
@ 2026-02-26 11:42 Hangbin Liu
  2026-02-26 11:42 ` [RFC PATCH net-next 1/3] net: add ndo_update_offloads Hangbin Liu
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Hangbin Liu @ 2026-02-26 11:42 UTC (permalink / raw)
  To: netdev
  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, bridge, Hangbin Liu

Currently, master devices (bonding, bridge, team) manually call
netdev_compute_master_upper_features() scattered throughout their port
add/remove operations. This approach requires each driver to remember
to update features at the right times and leads to code duplication.

The series adds a new ndo_update_offloads callback that is automatically
invoked during feature updates when upper/lower device relationships change.
This centralizes the feature computation flow and removes the burden
from individual drivers.

Changes:
1. Patch 1: Add ndo_update_offloads callback to net_device_ops and invoke
   it from __netdev_update_features()
2. Patch 2: Convert bonding, bridge, and team drivers to use the new
   callback, removing manual feature computation calls
3. Patch 3: Convert net_failover driver, significantly simplifying its
   feature management code

*Discuss*:
1. Should we set ndo_update_offloads after ndo_set_features? Or maybe just
   call netdev_compute_master_upper_features() in ndo_set_features?
2. Do we need to compute the offload feature for hsr?


Hangbin Liu (3):
  net: add ndo_update_offloads
  net: use ndo_update_offloads for bonding/bridge/team
  failover: use .ndo_update_offloads for failover

 drivers/net/bonding/bond_main.c | 10 ++++--
 drivers/net/net_failover.c      | 64 ++++-----------------------------
 drivers/net/team/team_core.c    | 11 +++---
 include/linux/netdevice.h       |  7 ++++
 include/net/net_failover.h      |  7 ----
 net/bridge/br_device.c          |  6 ++++
 net/bridge/br_if.c              |  4 ---
 net/core/dev.c                  | 11 ++++--
 8 files changed, 42 insertions(+), 78 deletions(-)

-- 
2.50.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [RFC PATCH net-next 1/3] net: add ndo_update_offloads
  2026-02-26 11:42 [RFC PATCH net-next 0/3] net: add ndo_update_offloads for offload computation Hangbin Liu
@ 2026-02-26 11:42 ` Hangbin Liu
  2026-02-26 11:42 ` [RFC PATCH net-next 2/3] net: use ndo_update_offloads for bonding/bridge/team Hangbin Liu
  2026-02-26 11:42 ` [RFC PATCH net-next 3/3] failover: use .ndo_update_offloads for failover Hangbin Liu
  2 siblings, 0 replies; 6+ messages in thread
From: Hangbin Liu @ 2026-02-26 11:42 UTC (permalink / raw)
  To: netdev
  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, bridge, Hangbin Liu

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 <liuhangbin@gmail.com>
---
 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 features);
  *	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);
 
+	if (dev->netdev_ops->ndo_update_offloads)
+		dev->netdev_ops->ndo_update_offloads(dev);
+
 	features = netdev_get_wanted_features(dev);
 
 	if (dev->netdev_ops->ndo_fix_features)
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC PATCH net-next 2/3] net: use ndo_update_offloads for bonding/bridge/team
  2026-02-26 11:42 [RFC PATCH net-next 0/3] net: add ndo_update_offloads for offload computation Hangbin Liu
  2026-02-26 11:42 ` [RFC PATCH net-next 1/3] net: add ndo_update_offloads Hangbin Liu
@ 2026-02-26 11:42 ` Hangbin Liu
  2026-02-27  7:53   ` Hangbin Liu
  2026-02-26 11:42 ` [RFC PATCH net-next 3/3] failover: use .ndo_update_offloads for failover Hangbin Liu
  2 siblings, 1 reply; 6+ messages in thread
From: Hangbin Liu @ 2026-02-26 11:42 UTC (permalink / raw)
  To: netdev
  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, bridge, Hangbin Liu

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 <liuhangbin@gmail.com>
---
 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_main.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 net_device *dev,
 	return features;
 }
 
+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,
 	}
 
 	bond->slave_cnt++;
-	netdev_compute_master_upper_features(bond->dev, true);
 	bond_set_carrier(bond);
 
 	/* 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);
 	}
 
-	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 event,
 	case NETDEV_FEAT_CHANGE:
 		if (!bond->notifier_ctx) {
 			bond->notifier_ctx = true;
-			netdev_compute_master_upper_features(bond->dev, true);
+			netdev_change_features(bond->dev);
 			bond->notifier_ctx = false;
 		}
 		break;
@@ -5895,6 +5898,7 @@ static const struct net_device_ops bond_netdev_ops = {
 	.ndo_add_slave		= bond_enslave,
 	.ndo_del_slave		= bond_release,
 	.ndo_fix_features	= bond_fix_features,
+	.ndo_update_offloads	= bond_update_offloads,
 	.ndo_features_check	= passthru_features_check,
 	.ndo_get_xmit_slave	= bond_xmit_get_slave,
 	.ndo_sk_get_lower_dev	= 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 net_device *port_dev,
 	port->index = -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);
 
@@ -1333,7 +1332,6 @@ static int team_port_del(struct team *team, struct net_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);
 
 	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);
 }
 
 static void team_destructor(struct net_device *dev)
@@ -1959,6 +1956,11 @@ static netdev_features_t team_fix_features(struct net_device *dev,
 	return features;
 }
 
+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 = netdev_priv(dev);
@@ -1994,6 +1996,7 @@ static const struct net_device_ops team_netdev_ops = {
 	.ndo_add_slave		= team_add_slave,
 	.ndo_del_slave		= team_del_slave,
 	.ndo_fix_features	= team_fix_features,
+	.ndo_update_offloads	= team_update_offloads,
 	.ndo_change_carrier     = team_change_carrier,
 	.ndo_features_check	= passthru_features_check,
 };
@@ -2931,7 +2934,7 @@ static int team_device_event(struct notifier_block *unused,
 	case NETDEV_FEAT_CHANGE:
 		if (!port->team->notifier_ctx) {
 			port->team->notifier_ctx = true;
-			netdev_compute_master_upper_features(port->team->dev, true);
+			netdev_change_features(port->team->dev);
 			port->team->notifier_ctx = 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_device *dev,
 	return br_features_recompute(br, features);
 }
 
+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 = {
 	.ndo_add_slave		 = br_add_slave,
 	.ndo_del_slave		 = br_del_slave,
 	.ndo_fix_features        = br_fix_features,
+	.ndo_update_offloads	 = br_update_offloads,
 	.ndo_fdb_add		 = br_fdb_add,
 	.ndo_fdb_del		 = br_fdb_delete,
 	.ndo_fdb_del_bulk	 = 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,
 
 	br_mtu_auto_adjust(br);
 
-	netdev_compute_master_upper_features(br->dev, false);
-
 	kobject_uevent(&p->kobj, KOBJ_ADD);
 
 	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);
 
-	netdev_compute_master_upper_features(br->dev, false);
-
 	return 0;
 }
 
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);
 
+	/* re-compute all features after adding link */
+	netdev_change_features(upper_dev);
+
 	return 0;
 
 rollback:
@@ -8985,6 +8988,9 @@ static void __netdev_upper_dev_unlink(struct net_device *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);
 }
 
 /**
@@ -12851,8 +12857,6 @@ void netdev_compute_master_upper_features(struct net_device *dev, bool update_he
 
 	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);
 
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC PATCH net-next 3/3] failover: use .ndo_update_offloads for failover
  2026-02-26 11:42 [RFC PATCH net-next 0/3] net: add ndo_update_offloads for offload computation Hangbin Liu
  2026-02-26 11:42 ` [RFC PATCH net-next 1/3] net: add ndo_update_offloads Hangbin Liu
  2026-02-26 11:42 ` [RFC PATCH net-next 2/3] net: use ndo_update_offloads for bonding/bridge/team Hangbin Liu
@ 2026-02-26 11:42 ` Hangbin Liu
  2026-02-26 12:48   ` Hangbin Liu
  2 siblings, 1 reply; 6+ messages in thread
From: Hangbin Liu @ 2026-02-26 11:42 UTC (permalink / raw)
  To: netdev
  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, bridge, Hangbin Liu

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 <liuhangbin@gmail.com>
---
 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_device *dev, __be16 proto,
 	return 0;
 }
 
+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 = {
 	.ndo_open		= net_failover_open,
 	.ndo_stop		= net_failover_close,
@@ -312,6 +317,7 @@ static const struct net_device_ops failover_dev_ops = {
 	.ndo_vlan_rx_kill_vid	= net_failover_vlan_rx_kill_vid,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_features_check	= passthru_features_check,
+	.ndo_update_offloads    = failover_update_offloads,
 };
 
 #define FAILOVER_NAME "net_failover"
@@ -373,61 +379,6 @@ static rx_handler_result_t net_failover_handle_frame(struct sk_buff **pskb)
 	return RX_HANDLER_ANOTHER;
 }
 
-static void net_failover_compute_features(struct net_device *dev)
-{
-	netdev_features_t vlan_features = FAILOVER_VLAN_FEATURES &
-					  NETIF_F_ALL_FOR_ALL;
-	netdev_features_t enc_features  = FAILOVER_ENC_FEATURES;
-	unsigned short max_hard_header_len = ETH_HLEN;
-	unsigned int dst_release_flag = IFF_XMIT_DST_RELEASE |
-					IFF_XMIT_DST_RELEASE_PERM;
-	struct net_failover_info *nfo_info = netdev_priv(dev);
-	struct net_device *primary_dev, *standby_dev;
-
-	primary_dev = rcu_dereference(nfo_info->primary_dev);
-	if (primary_dev) {
-		vlan_features =
-			netdev_increment_features(vlan_features,
-						  primary_dev->vlan_features,
-						  FAILOVER_VLAN_FEATURES);
-		enc_features =
-			netdev_increment_features(enc_features,
-						  primary_dev->hw_enc_features,
-						  FAILOVER_ENC_FEATURES);
-
-		dst_release_flag &= primary_dev->priv_flags;
-		if (primary_dev->hard_header_len > max_hard_header_len)
-			max_hard_header_len = primary_dev->hard_header_len;
-	}
-
-	standby_dev = rcu_dereference(nfo_info->standby_dev);
-	if (standby_dev) {
-		vlan_features =
-			netdev_increment_features(vlan_features,
-						  standby_dev->vlan_features,
-						  FAILOVER_VLAN_FEATURES);
-		enc_features =
-			netdev_increment_features(enc_features,
-						  standby_dev->hw_enc_features,
-						  FAILOVER_ENC_FEATURES);
-
-		dst_release_flag &= standby_dev->priv_flags;
-		if (standby_dev->hard_header_len > max_hard_header_len)
-			max_hard_header_len = standby_dev->hard_header_len;
-	}
-
-	dev->vlan_features = vlan_features;
-	dev->hw_enc_features = enc_features | NETIF_F_GSO_ENCAP_ALL;
-	dev->hard_header_len = max_hard_header_len;
-
-	dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
-	if (dst_release_flag == (IFF_XMIT_DST_RELEASE |
-				 IFF_XMIT_DST_RELEASE_PERM))
-		dev->priv_flags |= 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_device *slave_dev,
 	}
 
 	net_failover_lower_state_changed(slave_dev, primary_dev, standby_dev);
-	net_failover_compute_features(failover_dev);
 
 	call_netdevice_notifiers(NETDEV_JOIN, slave_dev);
 
@@ -621,8 +571,6 @@ static int net_failover_slave_unregister(struct net_device *slave_dev,
 
 	dev_put(slave_dev);
 
-	net_failover_compute_features(failover_dev);
-
 	netdev_info(failover_dev, "failover %s slave:%s unregistered\n",
 		    slave_is_standby ? "standby" : "primary", slave_dev->name);
 
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);
 
-#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 */
-- 
2.50.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [RFC PATCH net-next 3/3] failover: use .ndo_update_offloads for failover
  2026-02-26 11:42 ` [RFC PATCH net-next 3/3] failover: use .ndo_update_offloads for failover Hangbin Liu
@ 2026-02-26 12:48   ` Hangbin Liu
  0 siblings, 0 replies; 6+ messages in thread
From: Hangbin Liu @ 2026-02-26 12:48 UTC (permalink / raw)
  To: netdev
  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, bridge

On Thu, Feb 26, 2026 at 11:42:08AM +0000, Hangbin Liu wrote:
> 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);
>  
> -#define FAILOVER_VLAN_FEATURES	(NETIF_F_HW_CSUM | NETIF_F_SG | \
> -				 NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \
> -				 NETIF_F_HIGHDMA | NETIF_F_LRO)
> -

Oh, forgot to fix this. Maybe we can use MASTER_UPPER_DEV_VLAN_FEATURES to
replace it?

drivers/net/net_failover.c: In function ‘net_failover_create’:
drivers/net/net_failover.c:687:37: error: ‘FAILOVER_VLAN_FEATURES’ undeclared (first use in this function)
  687 |         failover_dev->hw_features = FAILOVER_VLAN_FEATURES |
      |                                     ^~~~~~~~~~~~~~~~~~~~~~


Thanks
Hangbin

> -#define FAILOVER_ENC_FEATURES	(NETIF_F_HW_CSUM | NETIF_F_SG | \
> -				 NETIF_F_RXCSUM | NETIF_F_ALL_TSO)
> -
>  #endif /* _NET_FAILOVER_H */
> -- 
> 2.50.1
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC PATCH net-next 2/3] net: use ndo_update_offloads for bonding/bridge/team
  2026-02-26 11:42 ` [RFC PATCH net-next 2/3] net: use ndo_update_offloads for bonding/bridge/team Hangbin Liu
@ 2026-02-27  7:53   ` Hangbin Liu
  0 siblings, 0 replies; 6+ messages in thread
From: Hangbin Liu @ 2026-02-27  7:53 UTC (permalink / raw)
  To: netdev
  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,
	Alexander Lobakin, linux-kernel, bridge

On Thu, Feb 26, 2026 at 11:42:07AM +0000, Hangbin Liu wrote:
> 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 <liuhangbin@gmail.com>
> ---
>  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/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);
>  
> +	/* re-compute all features after adding link */
> +	netdev_change_features(upper_dev);
> +
>  	return 0;

Another benefit for this change is, after calling netdev_change_features() here,
the later netdev_sync_lower_features() will disable LRO automatically.
So we don't need to call dev_disable_lro() manually in
bonding/bridge/team/VLAN. I will add this patch in next version.

Hangbin

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-02-27  7:53 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-26 11:42 [RFC PATCH net-next 0/3] net: add ndo_update_offloads for offload computation Hangbin Liu
2026-02-26 11:42 ` [RFC PATCH net-next 1/3] net: add ndo_update_offloads Hangbin Liu
2026-02-26 11:42 ` [RFC PATCH net-next 2/3] net: use ndo_update_offloads for bonding/bridge/team Hangbin Liu
2026-02-27  7:53   ` Hangbin Liu
2026-02-26 11:42 ` [RFC PATCH net-next 3/3] failover: use .ndo_update_offloads for failover Hangbin Liu
2026-02-26 12:48   ` Hangbin Liu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox