Message ID | 1738965337-23085-1-git-send-email-longli@linuxonhyperv.com (mailing list archive) |
---|---|
State | Rejected |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [net-next,v3] hv_netvsc: Set device flags for properly indicating bonding in Hyper-V | expand |
On Fri, 7 Feb 2025 13:55:37 -0800 longli@linuxonhyperv.com wrote: > On Hyper-V platforms, a slave VF netdev always bonds to Netvsc and remains > as Netvsc's only active slave as long as the slave device is present. This > behavior is the same as a bonded device, but it's not user-configurable. > > Some kernel APIs (e.g those in "include/linux/netdevice.h") check for > IFF_MASTER, IFF_SLAVE and IFF_BONDING for determing if those are used in > a master/slave bonded setup. Netvsc's bonding setup with its slave device > falls into this category. Again, this is way too much of a hack. You're trying to make netif_is_bond_master() return true for your franken-interfaces with minimal effort.
On Tue, 11 Feb 2025 16:20:26 -0800 Jakub Kicinski <kuba@kernel.org> wrote: > On Fri, 7 Feb 2025 13:55:37 -0800 longli@linuxonhyperv.com wrote: > > On Hyper-V platforms, a slave VF netdev always bonds to Netvsc and remains > > as Netvsc's only active slave as long as the slave device is present. This > > behavior is the same as a bonded device, but it's not user-configurable. > > > > Some kernel APIs (e.g those in "include/linux/netdevice.h") check for > > IFF_MASTER, IFF_SLAVE and IFF_BONDING for determing if those are used in > > a master/slave bonded setup. Netvsc's bonding setup with its slave device > > falls into this category. > > Again, this is way too much of a hack. You're trying to make > netif_is_bond_master() return true for your franken-interfaces > with minimal effort. Agree but disagree as to reasoning. The way bonding is handled in the kernel internal API's is ad-hoc. Really a better solution is needed. The real problem is in any code (other than the bonding driver itself) looking at IFF_BONDING is broken. All that code won't work if used over team or failover devices (luckily no one ever seems to use them).
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index d6c4abfc3a28..035869b02fde 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -2204,6 +2204,10 @@ static int netvsc_vf_join(struct net_device *vf_netdev, goto rx_handler_failed; } + vf_netdev->kernel_bond = 1; + ndev->kernel_bond = 1; + ndev->flags |= IFF_MASTER; + ret = netdev_master_upper_dev_link(vf_netdev, ndev, NULL, NULL, NULL); if (ret != 0) { @@ -2484,6 +2488,13 @@ static int netvsc_unregister_vf(struct net_device *vf_netdev) reinit_completion(&net_device_ctx->vf_add); netdev_rx_handler_unregister(vf_netdev); + + /* Unlink the slave device and clear flag */ + vf_netdev->kernel_bond = 0; + ndev->kernel_bond = 0; + vf_netdev->flags &= ~IFF_SLAVE; + ndev->flags &= ~IFF_MASTER; + netdev_upper_dev_unlink(vf_netdev, ndev); RCU_INIT_POINTER(net_device_ctx->vf_netdev, NULL); dev_put(vf_netdev); diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index ecc686409161..5befb0e23585 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1997,6 +1997,8 @@ enum netdev_reg_state { * @change_proto_down: device supports setting carrier via IFLA_PROTO_DOWN * @netns_local: interface can't change network namespaces * @fcoe_mtu: device supports maximum FCoE MTU, 2158 bytes + * @kernel_bond: device is auto bonded to another device without user + * configuration * * @net_notifier_list: List of per-net netdev notifier block * that follow this device when it is moved @@ -2402,6 +2404,7 @@ struct net_device { unsigned long change_proto_down:1; unsigned long netns_local:1; unsigned long fcoe_mtu:1; + unsigned long kernel_bond:1; struct list_head net_notifier_list; @@ -5150,12 +5153,14 @@ static inline bool netif_is_macvlan_port(const struct net_device *dev) static inline bool netif_is_bond_master(const struct net_device *dev) { - return dev->flags & IFF_MASTER && dev->priv_flags & IFF_BONDING; + return dev->flags & IFF_MASTER && + (dev->priv_flags & IFF_BONDING || dev->kernel_bond); } static inline bool netif_is_bond_slave(const struct net_device *dev) { - return dev->flags & IFF_SLAVE && dev->priv_flags & IFF_BONDING; + return dev->flags & IFF_SLAVE && + (dev->priv_flags & IFF_BONDING || dev->kernel_bond); } static inline bool netif_supports_nofcs(struct net_device *dev)