net: introduce IFF_NO_RX_HANDLER
Some network devices - notably ipvlan slave - are not compatible with any kind of rx_handler. Currently the hook can be installed but any configuration (bridge, bond, macsec, ...) is nonfunctional. This change allocates a priv_flag bit to mark such devices and explicitly forbid installing a rx_handler if such bit is set. The new bit is used by ipvlan slave device. Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
d185efc1da
commit
f5426250a6
@ -604,6 +604,8 @@ int ipvlan_link_new(struct net *src_net, struct net_device *dev,
|
|||||||
*/
|
*/
|
||||||
memcpy(dev->dev_addr, phy_dev->dev_addr, ETH_ALEN);
|
memcpy(dev->dev_addr, phy_dev->dev_addr, ETH_ALEN);
|
||||||
|
|
||||||
|
dev->priv_flags |= IFF_NO_RX_HANDLER;
|
||||||
|
|
||||||
err = register_netdevice(dev);
|
err = register_netdevice(dev);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
@ -1397,6 +1397,7 @@ struct net_device_ops {
|
|||||||
* @IFF_PHONY_HEADROOM: the headroom value is controlled by an external
|
* @IFF_PHONY_HEADROOM: the headroom value is controlled by an external
|
||||||
* entity (i.e. the master device for bridged veth)
|
* entity (i.e. the master device for bridged veth)
|
||||||
* @IFF_MACSEC: device is a MACsec device
|
* @IFF_MACSEC: device is a MACsec device
|
||||||
|
* @IFF_NO_RX_HANDLER: device doesn't support the rx_handler hook
|
||||||
*/
|
*/
|
||||||
enum netdev_priv_flags {
|
enum netdev_priv_flags {
|
||||||
IFF_802_1Q_VLAN = 1<<0,
|
IFF_802_1Q_VLAN = 1<<0,
|
||||||
@ -1425,6 +1426,7 @@ enum netdev_priv_flags {
|
|||||||
IFF_RXFH_CONFIGURED = 1<<23,
|
IFF_RXFH_CONFIGURED = 1<<23,
|
||||||
IFF_PHONY_HEADROOM = 1<<24,
|
IFF_PHONY_HEADROOM = 1<<24,
|
||||||
IFF_MACSEC = 1<<25,
|
IFF_MACSEC = 1<<25,
|
||||||
|
IFF_NO_RX_HANDLER = 1<<26,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IFF_802_1Q_VLAN IFF_802_1Q_VLAN
|
#define IFF_802_1Q_VLAN IFF_802_1Q_VLAN
|
||||||
@ -1452,6 +1454,7 @@ enum netdev_priv_flags {
|
|||||||
#define IFF_TEAM IFF_TEAM
|
#define IFF_TEAM IFF_TEAM
|
||||||
#define IFF_RXFH_CONFIGURED IFF_RXFH_CONFIGURED
|
#define IFF_RXFH_CONFIGURED IFF_RXFH_CONFIGURED
|
||||||
#define IFF_MACSEC IFF_MACSEC
|
#define IFF_MACSEC IFF_MACSEC
|
||||||
|
#define IFF_NO_RX_HANDLER IFF_NO_RX_HANDLER
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct net_device - The DEVICE structure.
|
* struct net_device - The DEVICE structure.
|
||||||
|
@ -4351,6 +4351,9 @@ int netdev_rx_handler_register(struct net_device *dev,
|
|||||||
if (netdev_is_rx_handler_busy(dev))
|
if (netdev_is_rx_handler_busy(dev))
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
|
if (dev->priv_flags & IFF_NO_RX_HANDLER)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
/* Note: rx_handler_data must be set before rx_handler */
|
/* Note: rx_handler_data must be set before rx_handler */
|
||||||
rcu_assign_pointer(dev->rx_handler_data, rx_handler_data);
|
rcu_assign_pointer(dev->rx_handler_data, rx_handler_data);
|
||||||
rcu_assign_pointer(dev->rx_handler, rx_handler);
|
rcu_assign_pointer(dev->rx_handler, rx_handler);
|
||||||
|
Loading…
Reference in New Issue
Block a user