Re: [PATCH net-next v10 2/4] net: Introduce generic failover module
On Mon, May 07, 2018 at 03:39:19PM -0700, Randy Dunlap wrote: > Hi, > > On 05/07/2018 03:10 PM, Sridhar Samudrala wrote: > > > > Signed-off-by: Sridhar Samudrala > > --- > > MAINTAINERS|7 + > > include/linux/netdevice.h | 16 + > > include/net/net_failover.h | 52 +++ > > net/Kconfig| 10 + > > net/core/Makefile |1 + > > net/core/net_failover.c| 1044 > > > > 6 files changed, 1130 insertions(+) > > create mode 100644 include/net/net_failover.h > > create mode 100644 net/core/net_failover.c > > > > diff --git a/net/Kconfig b/net/Kconfig > > index b62089fb1332..0540856676de 100644 > > --- a/net/Kconfig > > +++ b/net/Kconfig > > @@ -429,6 +429,16 @@ config MAY_USE_DEVLINK > > config PAGE_POOL > > bool > > > > +config NET_FAILOVER > > + tristate "Failover interface" > > + default m > > Need some justification for default m (as opposed to n). Or one can just leave the default line out. ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH net-next v10 2/4] net: Introduce generic failover module
On Mon, May 07, 2018 at 05:24:27PM -0700, Samudrala, Sridhar wrote: > > > On 5/7/2018 4:53 PM, Stephen Hemminger wrote: > > On Mon, 7 May 2018 15:10:44 -0700 > > Sridhar Samudrala wrote: > > > > > +static struct net_device *net_failover_get_bymac(u8 *mac, > > > + struct net_failover_ops **ops) > > > +{ > > > + struct net_device *failover_dev; > > > + struct net_failover *failover; > > > + > > > + spin_lock(&net_failover_lock); > > > + list_for_each_entry(failover, &net_failover_list, list) { > > > + failover_dev = rtnl_dereference(failover->failover_dev); > > > + if (ether_addr_equal(failover_dev->perm_addr, mac)) { > > > + *ops = rtnl_dereference(failover->ops); > > > + spin_unlock(&net_failover_lock); > > > + return failover_dev; > > > + } > > > + } > > > + spin_unlock(&net_failover_lock); > > > + return NULL; > > > +} > > This is broken if non-ethernet devices such as Infiniband are present. > > There is check to make sure that a slave and failover devices are of the same > type in > net_failover_slave_register() > > failover_dev = net_failover_get_bymac(slave_dev->perm_addr, &nfo_ops); > if (!failover_dev) > goto done; > > if (failover_dev->type != slave_dev->type) > goto done; > > Do you think this is not good enough? I had an explicit check for > ARPHRD_ETHER in > earlier patchsets, but removed it based on Jiri's comment. Right but how is ether_addr_equal supposed to work if types are identical but not ethernet? This can also benefit from a comment referring to the check in net_failover_slave_register. -- MST ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH net-next v10 2/4] net: Introduce generic failover module
On 5/7/2018 3:39 PM, Randy Dunlap wrote: Hi, On 05/07/2018 03:10 PM, Sridhar Samudrala wrote: Signed-off-by: Sridhar Samudrala --- MAINTAINERS|7 + include/linux/netdevice.h | 16 + include/net/net_failover.h | 52 +++ net/Kconfig| 10 + net/core/Makefile |1 + net/core/net_failover.c| 1044 6 files changed, 1130 insertions(+) create mode 100644 include/net/net_failover.h create mode 100644 net/core/net_failover.c diff --git a/net/Kconfig b/net/Kconfig index b62089fb1332..0540856676de 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -429,6 +429,16 @@ config MAY_USE_DEVLINK config PAGE_POOL bool +config NET_FAILOVER + tristate "Failover interface" + default m Need some justification for default m (as opposed to n). default n should be fine. It will get selected automatically when virtio_net or netvsc are enabled. will fix in the next revision. ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH net-next v10 2/4] net: Introduce generic failover module
On 5/7/2018 4:46 PM, Stephen Hemminger wrote: On Mon, 7 May 2018 15:10:44 -0700 Sridhar Samudrala wrote: This provides a generic interface for paravirtual drivers to listen for netdev register/unregister/link change events from pci ethernet devices with the same MAC and takeover their datapath. The notifier and event handling code is based on the existing netvsc implementation. It exposes 2 sets of interfaces to the paravirtual drivers. 1. For paravirtual drivers like virtio_net that use 3 netdev model, the the failover module provides interfaces to create/destroy additional master netdev and all the slave events are managed internally. net_failover_create() net_failover_destroy() A failover netdev is created that acts a master device and controls 2 slave devices. The original virtio_net netdev is registered as 'standby' netdev and a passthru/vf device with the same MAC gets registered as 'primary' netdev. Both 'standby' and 'failover' netdevs are associated with the same 'pci' device. The user accesses the network interface via 'failover' netdev. The 'failover' netdev chooses 'primary' netdev as default for transmits when it is available with link up and running. 2. For existing netvsc driver that uses 2 netdev model, no master netdev is created. The paravirtual driver registers each instance of netvsc as a 'failover' netdev along with a set of ops to manage the slave events. There is no 'standby' netdev in this model. A passthru/vf device with the same MAC gets registered as 'primary' netdev. net_failover_register() net_failover_unregister() Signed-off-by: Sridhar Samudrala You are conflating the net_failover device (3 device model) with the generic network failover infrastructure into one file. There should be two seperate files net/core/failover.c and drivers/net/failover.c which splits the work into two parts (and acts a check for the api). OK. I started splitting net_failover.c into 2 files. net/core/failover.c (CONFIG_FAILOVER) - implements the generic failover infrastructure that exports failover_register(), failover_unregister() and failover_slave_unregister() as the API that will be used by netvsc and the net_failover drivers(3 netdev model) drivers/net/net_failover.c (CONFIG_NET_FAILOVER) - implements the net_failover netdev as the upper dev for the 3-netdev model and exports net_failover_create() and net_failover_destroy() as the API that is used by virtio_net. HYPERV_NET and NET_FAILOVER selects FAILOVER VIRTIO_NET selects NET_FAILOVER Does this look good? Any better suggestion for the prefix to be used for generic network failover api rather than 'failover'? ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH net-next v10 2/4] net: Introduce generic failover module
Hi Sridhar, I love your patch! Perhaps something to improve: [auto build test WARNING on net-next/master] url: https://github.com/0day-ci/linux/commits/Sridhar-Samudrala/Enable-virtio_net-to-act-as-a-standby-for-a-passthru-device/20180508-123531 reproduce: # apt-get install sparse make ARCH=x86_64 allmodconfig make C=1 CF=-D__CHECK_ENDIAN__ sparse warnings: (new ones prefixed by >>) >> net/core/net_failover.c:868:16: sparse: Using plain integer as NULL pointer net/core/net_failover.c:115:12: sparse: context imbalance in 'net_failover_select_queue' - wrong count at exit vim +868 net/core/net_failover.c 828 829 /** 830 * net_failover_register - Register a failover instance 831 * 832 * @dev: failover or standby netdev 833 * @ops: failover ops 834 * 835 * Paravirtual drivers supporting 3-netdev model call this routine indirectly 836 * via net_failover_create(). It passes failover netdev and ops will be NULL 837 * as the slave events are handled internally. 838 * Paravirtual drivers supporting 2-netdev model call this routine by passing 839 * standby netdev and ops that are called to handle slave register/unregister/ 840 * link change events. 841 * 842 * Return: pointer to failover instance 843 */ 844 struct net_failover *net_failover_register(struct net_device *dev, 845 struct net_failover_ops *ops) 846 { 847 struct net_failover *failover; 848 849 failover = kzalloc(sizeof(*failover), GFP_KERNEL); 850 if (!failover) 851 return ERR_PTR(-ENOMEM); 852 853 rcu_assign_pointer(failover->ops, ops); 854 dev_hold(dev); 855 dev->priv_flags |= IFF_FAILOVER; 856 rcu_assign_pointer(failover->failover_dev, dev); 857 858 spin_lock(&net_failover_lock); 859 list_add_tail(&failover->list, &net_failover_list); 860 spin_unlock(&net_failover_lock); 861 862 netdev_info(dev, "failover master:%s registered\n", dev->name); 863 864 net_failover_existing_slave_register(dev); 865 866 return failover; 867 > 868 return 0; 869 } 870 EXPORT_SYMBOL_GPL(net_failover_register); 871 --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH net-next v10 2/4] net: Introduce generic failover module
On 5/7/2018 4:53 PM, Stephen Hemminger wrote: On Mon, 7 May 2018 15:10:44 -0700 Sridhar Samudrala wrote: +static struct net_device *net_failover_get_bymac(u8 *mac, +struct net_failover_ops **ops) +{ + struct net_device *failover_dev; + struct net_failover *failover; + + spin_lock(&net_failover_lock); + list_for_each_entry(failover, &net_failover_list, list) { + failover_dev = rtnl_dereference(failover->failover_dev); + if (ether_addr_equal(failover_dev->perm_addr, mac)) { + *ops = rtnl_dereference(failover->ops); + spin_unlock(&net_failover_lock); + return failover_dev; + } + } + spin_unlock(&net_failover_lock); + return NULL; +} This is broken if non-ethernet devices such as Infiniband are present. There is check to make sure that a slave and failover devices are of the same type in net_failover_slave_register() failover_dev = net_failover_get_bymac(slave_dev->perm_addr, &nfo_ops); if (!failover_dev) goto done; if (failover_dev->type != slave_dev->type) goto done; Do you think this is not good enough? I had an explicit check for ARPHRD_ETHER in earlier patchsets, but removed it based on Jiri's comment. ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH net-next v10 2/4] net: Introduce generic failover module
On 5/7/2018 4:59 PM, Stephen Hemminger wrote: On Mon, 7 May 2018 15:10:44 -0700 Sridhar Samudrala wrote: + if (netif_running(failover_dev)) { + err = dev_open(slave_dev); + if (err && (err != -EBUSY)) { + netdev_err(failover_dev, "Opening slave %s failed err:%d\n", + slave_dev->name, err); + goto err_dev_open; + } + } + + netif_addr_lock_bh(failover_dev); + dev_uc_sync_multiple(slave_dev, failover_dev); + dev_uc_sync_multiple(slave_dev, failover_dev); + netif_addr_unlock_bh(failover_dev); + The order of these is backwards, you want to sync addresses before bringing up. Also, doing it this way does not allow udev/systemd the chance to rename VF devices. During my testing, i noticed that dev_open() may fail with EBUSY in certain scenarios, If so, the opening of the slave is handled after the rename via the NETDEV_CHANGENAME event handler. The complexity of this whole failover mechanism does not make life easier, more reliable, or safer for netvsc. I though that was the whole reason for having common code. netvsc doesn't go through this code. if (nfo_ops && nfo_ops->slave_register) return nfo_ops->slave_register(slave_dev, failover_dev); So there is no change in event handling for netvsc 2-netdev model. ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH net-next v10 2/4] net: Introduce generic failover module
On Mon, 7 May 2018 15:10:44 -0700 Sridhar Samudrala wrote: > + if (netif_running(failover_dev)) { > + err = dev_open(slave_dev); > + if (err && (err != -EBUSY)) { > + netdev_err(failover_dev, "Opening slave %s failed > err:%d\n", > +slave_dev->name, err); > + goto err_dev_open; > + } > + } > + > + netif_addr_lock_bh(failover_dev); > + dev_uc_sync_multiple(slave_dev, failover_dev); > + dev_uc_sync_multiple(slave_dev, failover_dev); > + netif_addr_unlock_bh(failover_dev); > + The order of these is backwards, you want to sync addresses before bringing up. Also, doing it this way does not allow udev/systemd the chance to rename VF devices. The complexity of this whole failover mechanism does not make life easier, more reliable, or safer for netvsc. I though that was the whole reason for having common code. ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH net-next v10 2/4] net: Introduce generic failover module
On Mon, 7 May 2018 15:10:44 -0700 Sridhar Samudrala wrote: > +static struct net_device *net_failover_get_bymac(u8 *mac, > + struct net_failover_ops **ops) > +{ > + struct net_device *failover_dev; > + struct net_failover *failover; > + > + spin_lock(&net_failover_lock); > + list_for_each_entry(failover, &net_failover_list, list) { > + failover_dev = rtnl_dereference(failover->failover_dev); > + if (ether_addr_equal(failover_dev->perm_addr, mac)) { > + *ops = rtnl_dereference(failover->ops); > + spin_unlock(&net_failover_lock); > + return failover_dev; > + } > + } > + spin_unlock(&net_failover_lock); > + return NULL; > +} This is broken if non-ethernet devices such as Infiniband are present. ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH net-next v10 2/4] net: Introduce generic failover module
On Mon, 7 May 2018 15:10:44 -0700 Sridhar Samudrala wrote: > This provides a generic interface for paravirtual drivers to listen > for netdev register/unregister/link change events from pci ethernet > devices with the same MAC and takeover their datapath. The notifier and > event handling code is based on the existing netvsc implementation. > > It exposes 2 sets of interfaces to the paravirtual drivers. > 1. For paravirtual drivers like virtio_net that use 3 netdev model, the >the failover module provides interfaces to create/destroy additional >master netdev and all the slave events are managed internally. > net_failover_create() > net_failover_destroy() >A failover netdev is created that acts a master device and controls 2 >slave devices. The original virtio_net netdev is registered as 'standby' >netdev and a passthru/vf device with the same MAC gets registered as >'primary' netdev. Both 'standby' and 'failover' netdevs are associated >with the same 'pci' device. The user accesses the network interface via >'failover' netdev. The 'failover' netdev chooses 'primary' netdev as >default for transmits when it is available with link up and running. > 2. For existing netvsc driver that uses 2 netdev model, no master netdev >is created. The paravirtual driver registers each instance of netvsc >as a 'failover' netdev along with a set of ops to manage the slave >events. There is no 'standby' netdev in this model. A passthru/vf device >with the same MAC gets registered as 'primary' netdev. > net_failover_register() > net_failover_unregister() > > Signed-off-by: Sridhar Samudrala You are conflating the net_failover device (3 device model) with the generic network failover infrastructure into one file. There should be two seperate files net/core/failover.c and drivers/net/failover.c which splits the work into two parts (and acts a check for the api). ___ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Re: [PATCH net-next v10 2/4] net: Introduce generic failover module
Hi, On 05/07/2018 03:10 PM, Sridhar Samudrala wrote: > > Signed-off-by: Sridhar Samudrala > --- > MAINTAINERS|7 + > include/linux/netdevice.h | 16 + > include/net/net_failover.h | 52 +++ > net/Kconfig| 10 + > net/core/Makefile |1 + > net/core/net_failover.c| 1044 > > 6 files changed, 1130 insertions(+) > create mode 100644 include/net/net_failover.h > create mode 100644 net/core/net_failover.c > diff --git a/net/Kconfig b/net/Kconfig > index b62089fb1332..0540856676de 100644 > --- a/net/Kconfig > +++ b/net/Kconfig > @@ -429,6 +429,16 @@ config MAY_USE_DEVLINK > config PAGE_POOL > bool > > +config NET_FAILOVER > + tristate "Failover interface" > + default m Need some justification for default m (as opposed to n). > + help > + This provides a generic interface for paravirtual drivers to listen > + for netdev register/unregister/link change events from pci ethernet PCI > + devices with the same MAC and takeover their datapath. This also > + enables live migration of a VM with direct attached VF by failing > + over to the paravirtual datapath when the VF is unplugged. > + > endif # if NET > > # Used by archs to tell that they support BPF JIT compiler plus which > flavour. > diff --git a/net/core/net_failover.c b/net/core/net_failover.c > new file mode 100644 > index ..8d60e74e3034 > --- /dev/null > +++ b/net/core/net_failover.c > @@ -0,0 +1,1044 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* Copyright (c) 2018, Intel Corporation. */ > + > +/* A common module to handle registrations and notifications for paravirtual > + * drivers to enable accelerated datapath and support VF live migration. > + * > + * The notifier and event handling code is based on netvsc driver and > failover > + * netdev management routines are based on bond/team driver. > + * > + */ > +/** > + * net_failover_create - Create and register a failover instance > + * > + * @dev: standby netdev * @standby_dev: standby netdev > + * > + * Creates a failover netdev and registers a failover instance for a standby > + * netdev. Used by paravirtual drivers that use 3-netdev model. > + * The failover netdev acts as a master device and controls 2 slave devices - > + * the original standby netdev and a VF netdev with the same MAC gets > + * registered as primary netdev. > + * > + * Return: pointer to failover instance > + */ > +struct net_failover *net_failover_create(struct net_device *standby_dev) > +{ > + struct device *dev = standby_dev->dev.parent; > + struct net_device *failover_dev; > + struct net_failover *failover; > + int err; > + > + /* Alloc at least 2 queues, for now we are going with 16 assuming > + * that VF devices being enslaved won't have too many queues. > + */ > + failover_dev = alloc_etherdev_mq(sizeof(struct net_failover_info), 16); > + if (!failover_dev) { > + dev_err(dev, "Unable to allocate failover_netdev!\n"); > + return ERR_PTR(-ENOMEM); > + } > + > + dev_net_set(failover_dev, dev_net(standby_dev)); > + SET_NETDEV_DEV(failover_dev, dev); > + > + failover_dev->netdev_ops = &failover_dev_ops; > + failover_dev->ethtool_ops = &failover_ethtool_ops; > + > + /* Initialize the device options */ > + failover_dev->priv_flags |= IFF_UNICAST_FLT | IFF_NO_QUEUE; > + failover_dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | > +IFF_TX_SKB_SHARING); > + > + /* don't acquire failover netdev's netif_tx_lock when transmitting */ > + failover_dev->features |= NETIF_F_LLTX; > + > + /* Don't allow failover devices to change network namespaces. */ > + failover_dev->features |= NETIF_F_NETNS_LOCAL; > + > + failover_dev->hw_features = FAILOVER_VLAN_FEATURES | > + NETIF_F_HW_VLAN_CTAG_TX | > + NETIF_F_HW_VLAN_CTAG_RX | > + NETIF_F_HW_VLAN_CTAG_FILTER; > + > + failover_dev->hw_features |= NETIF_F_GSO_ENCAP_ALL; > + failover_dev->features |= failover_dev->hw_features; > + > + memcpy(failover_dev->dev_addr, standby_dev->dev_addr, > +failover_dev->addr_len); > + > + failover_dev->min_mtu = standby_dev->min_mtu; > + failover_dev->max_mtu = standby_dev->max_mtu; > + > + err = register_netdev(failover_dev); > + if (err) { > + dev_err(dev, "Unable to register failover_dev!\n"); > + goto err_register_netdev; > + } > + > + netif_carrier_off(failover_dev); > + > + failover = net_failover_register(failover_dev, NULL); > + if (IS_ERR(failover)) > + goto err_failover_register; > + > + return failover; > + > +err_failover_register: > + unregister_netdev(failover_de
[PATCH net-next v10 2/4] net: Introduce generic failover module
This provides a generic interface for paravirtual drivers to listen for netdev register/unregister/link change events from pci ethernet devices with the same MAC and takeover their datapath. The notifier and event handling code is based on the existing netvsc implementation. It exposes 2 sets of interfaces to the paravirtual drivers. 1. For paravirtual drivers like virtio_net that use 3 netdev model, the the failover module provides interfaces to create/destroy additional master netdev and all the slave events are managed internally. net_failover_create() net_failover_destroy() A failover netdev is created that acts a master device and controls 2 slave devices. The original virtio_net netdev is registered as 'standby' netdev and a passthru/vf device with the same MAC gets registered as 'primary' netdev. Both 'standby' and 'failover' netdevs are associated with the same 'pci' device. The user accesses the network interface via 'failover' netdev. The 'failover' netdev chooses 'primary' netdev as default for transmits when it is available with link up and running. 2. For existing netvsc driver that uses 2 netdev model, no master netdev is created. The paravirtual driver registers each instance of netvsc as a 'failover' netdev along with a set of ops to manage the slave events. There is no 'standby' netdev in this model. A passthru/vf device with the same MAC gets registered as 'primary' netdev. net_failover_register() net_failover_unregister() Signed-off-by: Sridhar Samudrala --- MAINTAINERS|7 + include/linux/netdevice.h | 16 + include/net/net_failover.h | 52 +++ net/Kconfig| 10 + net/core/Makefile |1 + net/core/net_failover.c| 1044 6 files changed, 1130 insertions(+) create mode 100644 include/net/net_failover.h create mode 100644 net/core/net_failover.c diff --git a/MAINTAINERS b/MAINTAINERS index ebe0b9ed7805..83cbd99d8efa 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9638,6 +9638,13 @@ S: Maintained F: Documentation/hwmon/nct6775 F: drivers/hwmon/nct6775.c +NET_FAILOVER MODULE +M: Sridhar Samudrala +L: net...@vger.kernel.org +S: Supported +F: net/core/net_failover.c +F: include/net/net_failover.h + NETEFFECT IWARP RNIC DRIVER (IW_NES) M: Faisal Latif L: linux-r...@vger.kernel.org diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 46dcb5f7522f..4fff9b5d079e 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1421,6 +1421,8 @@ struct net_device_ops { * entity (i.e. the master device for bridged veth) * @IFF_MACSEC: device is a MACsec device * @IFF_NO_RX_HANDLER: device doesn't support the rx_handler hook + * @IFF_FAILOVER: device is a failover master device + * @IFF_FAILOVER_SLAVE: device is lower dev of a failover master device */ enum netdev_priv_flags { IFF_802_1Q_VLAN = 1<<0, @@ -1450,6 +1452,8 @@ enum netdev_priv_flags { IFF_PHONY_HEADROOM = 1<<24, IFF_MACSEC = 1<<25, IFF_NO_RX_HANDLER = 1<<26, + IFF_FAILOVER= 1<<27, + IFF_FAILOVER_SLAVE = 1<<28, }; #define IFF_802_1Q_VLANIFF_802_1Q_VLAN @@ -1478,6 +1482,8 @@ enum netdev_priv_flags { #define IFF_RXFH_CONFIGUREDIFF_RXFH_CONFIGURED #define IFF_MACSEC IFF_MACSEC #define IFF_NO_RX_HANDLER IFF_NO_RX_HANDLER +#define IFF_FAILOVER IFF_FAILOVER +#define IFF_FAILOVER_SLAVE IFF_FAILOVER_SLAVE /** * struct net_device - The DEVICE structure. @@ -4320,6 +4326,16 @@ static inline bool netif_is_rxfh_configured(const struct net_device *dev) return dev->priv_flags & IFF_RXFH_CONFIGURED; } +static inline bool netif_is_failover(const struct net_device *dev) +{ + return dev->priv_flags & IFF_FAILOVER; +} + +static inline bool netif_is_failover_slave(const struct net_device *dev) +{ + return dev->priv_flags & IFF_FAILOVER_SLAVE; +} + /* This device needs to keep skb dst for qdisc enqueue or ndo_start_xmit() */ static inline void netif_keep_dst(struct net_device *dev) { diff --git a/include/net/net_failover.h b/include/net/net_failover.h new file mode 100644 index ..221c2aff7531 --- /dev/null +++ b/include/net/net_failover.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2018, Intel Corporation. */ + +#ifndef _NET_FAILOVER_H +#define _NET_FAILOVER_H + +#include + +struct net_failover_ops { + int (*slave_register)(struct net_device *slave_dev, + struct net_device *failover_dev); + int (*slave_unregister)(struct net_device *slave_dev, + struct net_device *failover_dev); + int (*sl