netdev: network device operations infrastructure
This patch changes the network device internal API to move adminstrative operations out of the network device structure and into a separate structure. This patch involves some hackery to maintain compatablity between the new and old model, so all 300+ drivers don't have to be changed at once. For drivers that aren't converted yet, the netdevice_ops virt function list still resides in the net_device structure. For old protocols, the new net_device_ops are copied out to the old net_device pointers. After the transistion is completed the nag message can be changed to an WARN_ON, and the compatiablity code can be made configurable. Some function pointers aren't moved: * destructor can't be in net_device_ops because it may need to be referenced after the module is unloaded. * neighbor setup is manipulated in a couple of places that need special consideration * hard_start_xmit is in the fast path for transmit. Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
6b41e7dd90
commit
d314774cf2
@ -451,6 +451,131 @@ struct netdev_queue {
|
||||
struct Qdisc *qdisc_sleeping;
|
||||
} ____cacheline_aligned_in_smp;
|
||||
|
||||
|
||||
/*
|
||||
* This structure defines the management hooks for network devices.
|
||||
* The following hooks can bed defined and are optonal (can be null)
|
||||
* unless otherwise noted.
|
||||
*
|
||||
* int (*ndo_init)(struct net_device *dev);
|
||||
* This function is called once when network device is registered.
|
||||
* The network device can use this to any late stage initializaton
|
||||
* or semantic validattion. It can fail with an error code which will
|
||||
* be propogated back to register_netdev
|
||||
*
|
||||
* void (*ndo_uninit)(struct net_device *dev);
|
||||
* This function is called when device is unregistered or when registration
|
||||
* fails. It is not called if init fails.
|
||||
*
|
||||
* int (*ndo_open)(struct net_device *dev);
|
||||
* This function is called when network device transistions to the up
|
||||
* state.
|
||||
*
|
||||
* int (*ndo_stop)(struct net_device *dev);
|
||||
* This function is called when network device transistions to the down
|
||||
* state.
|
||||
*
|
||||
* void (*ndo_change_rx_flags)(struct net_device *dev, int flags);
|
||||
* This function is called to allow device receiver to make
|
||||
* changes to configuration when multicast or promiscious is enabled.
|
||||
*
|
||||
* void (*ndo_set_rx_mode)(struct net_device *dev);
|
||||
* This function is called device changes address list filtering.
|
||||
*
|
||||
* void (*ndo_set_multicast_list)(struct net_device *dev);
|
||||
* This function is called when the multicast address list changes.
|
||||
*
|
||||
* int (*ndo_set_mac_address)(struct net_device *dev, void *addr);
|
||||
* This function is called when the Media Access Control address
|
||||
* needs to be changed. If not this interface is not defined, the
|
||||
* mac address can not be changed.
|
||||
*
|
||||
* int (*ndo_validate_addr)(struct net_device *dev);
|
||||
* Test if Media Access Control address is valid for the device.
|
||||
*
|
||||
* int (*ndo_do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd);
|
||||
* Called when a user request an ioctl which can't be handled by
|
||||
* the generic interface code. If not defined ioctl's return
|
||||
* not supported error code.
|
||||
*
|
||||
* int (*ndo_set_config)(struct net_device *dev, struct ifmap *map);
|
||||
* Used to set network devices bus interface parameters. This interface
|
||||
* is retained for legacy reason, new devices should use the bus
|
||||
* interface (PCI) for low level management.
|
||||
*
|
||||
* int (*ndo_change_mtu)(struct net_device *dev, int new_mtu);
|
||||
* Called when a user wants to change the Maximum Transfer Unit
|
||||
* of a device. If not defined, any request to change MTU will
|
||||
* will return an error.
|
||||
*
|
||||
* void (*ndo_tx_timeout) (struct net_device *dev);
|
||||
* Callback uses when the transmitter has not made any progress
|
||||
* for dev->watchdog ticks.
|
||||
*
|
||||
* struct net_device_stats* (*get_stats)(struct net_device *dev);
|
||||
* Called when a user wants to get the network device usage
|
||||
* statistics. If not defined, the counters in dev->stats will
|
||||
* be used.
|
||||
*
|
||||
* void (*ndo_vlan_rx_register)(struct net_device *dev, struct vlan_group *grp);
|
||||
* If device support VLAN receive accleration
|
||||
* (ie. dev->features & NETIF_F_HW_VLAN_RX), then this function is called
|
||||
* when vlan groups for the device changes. Note: grp is NULL
|
||||
* if no vlan's groups are being used.
|
||||
*
|
||||
* void (*ndo_vlan_rx_add_vid)(struct net_device *dev, unsigned short vid);
|
||||
* If device support VLAN filtering (dev->features & NETIF_F_HW_VLAN_FILTER)
|
||||
* this function is called when a VLAN id is registered.
|
||||
*
|
||||
* void (*ndo_vlan_rx_kill_vid)(struct net_device *dev, unsigned short vid);
|
||||
* If device support VLAN filtering (dev->features & NETIF_F_HW_VLAN_FILTER)
|
||||
* this function is called when a VLAN id is unregistered.
|
||||
*
|
||||
* void (*ndo_poll_controller)(struct net_device *dev);
|
||||
*/
|
||||
struct net_device_ops {
|
||||
int (*ndo_init)(struct net_device *dev);
|
||||
void (*ndo_uninit)(struct net_device *dev);
|
||||
int (*ndo_open)(struct net_device *dev);
|
||||
int (*ndo_stop)(struct net_device *dev);
|
||||
#define HAVE_CHANGE_RX_FLAGS
|
||||
void (*ndo_change_rx_flags)(struct net_device *dev,
|
||||
int flags);
|
||||
#define HAVE_SET_RX_MODE
|
||||
void (*ndo_set_rx_mode)(struct net_device *dev);
|
||||
#define HAVE_MULTICAST
|
||||
void (*ndo_set_multicast_list)(struct net_device *dev);
|
||||
#define HAVE_SET_MAC_ADDR
|
||||
int (*ndo_set_mac_address)(struct net_device *dev,
|
||||
void *addr);
|
||||
#define HAVE_VALIDATE_ADDR
|
||||
int (*ndo_validate_addr)(struct net_device *dev);
|
||||
#define HAVE_PRIVATE_IOCTL
|
||||
int (*ndo_do_ioctl)(struct net_device *dev,
|
||||
struct ifreq *ifr, int cmd);
|
||||
#define HAVE_SET_CONFIG
|
||||
int (*ndo_set_config)(struct net_device *dev,
|
||||
struct ifmap *map);
|
||||
#define HAVE_CHANGE_MTU
|
||||
int (*ndo_change_mtu)(struct net_device *dev, int new_mtu);
|
||||
|
||||
#define HAVE_TX_TIMEOUT
|
||||
void (*ndo_tx_timeout) (struct net_device *dev);
|
||||
|
||||
struct net_device_stats* (*ndo_get_stats)(struct net_device *dev);
|
||||
|
||||
void (*ndo_vlan_rx_register)(struct net_device *dev,
|
||||
struct vlan_group *grp);
|
||||
void (*ndo_vlan_rx_add_vid)(struct net_device *dev,
|
||||
unsigned short vid);
|
||||
void (*ndo_vlan_rx_kill_vid)(struct net_device *dev,
|
||||
unsigned short vid);
|
||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
#define HAVE_NETDEV_POLL
|
||||
void (*ndo_poll_controller)(struct net_device *dev);
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* The DEVICE structure.
|
||||
* Actually, this whole structure is a big mistake. It mixes I/O
|
||||
@ -498,11 +623,6 @@ struct net_device
|
||||
#ifdef CONFIG_NETPOLL
|
||||
struct list_head napi_list;
|
||||
#endif
|
||||
|
||||
/* The device initialization function. Called only once. */
|
||||
int (*init)(struct net_device *dev);
|
||||
|
||||
/* ------- Fields preinitialized in Space.c finish here ------- */
|
||||
|
||||
/* Net device features */
|
||||
unsigned long features;
|
||||
@ -546,15 +666,13 @@ struct net_device
|
||||
* for all in netdev_increment_features.
|
||||
*/
|
||||
#define NETIF_F_ONE_FOR_ALL (NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ROBUST | \
|
||||
NETIF_F_SG | NETIF_F_HIGHDMA | \
|
||||
NETIF_F_SG | NETIF_F_HIGHDMA | \
|
||||
NETIF_F_FRAGLIST)
|
||||
|
||||
/* Interface index. Unique device identifier */
|
||||
int ifindex;
|
||||
int iflink;
|
||||
|
||||
|
||||
struct net_device_stats* (*get_stats)(struct net_device *dev);
|
||||
struct net_device_stats stats;
|
||||
|
||||
#ifdef CONFIG_WIRELESS_EXT
|
||||
@ -564,18 +682,13 @@ struct net_device
|
||||
/* Instance data managed by the core of Wireless Extensions. */
|
||||
struct iw_public_data * wireless_data;
|
||||
#endif
|
||||
/* Management operations */
|
||||
const struct net_device_ops *netdev_ops;
|
||||
const struct ethtool_ops *ethtool_ops;
|
||||
|
||||
/* Hardware header description */
|
||||
const struct header_ops *header_ops;
|
||||
|
||||
/*
|
||||
* This marks the end of the "visible" part of the structure. All
|
||||
* fields hereafter are internal to the system, and may change at
|
||||
* will (read: may be cleaned up at will).
|
||||
*/
|
||||
|
||||
|
||||
unsigned int flags; /* interface flags (a la BSD) */
|
||||
unsigned short gflags;
|
||||
unsigned short priv_flags; /* Like 'flags' but invisible to userspace. */
|
||||
@ -634,7 +747,7 @@ struct net_device
|
||||
unsigned long last_rx; /* Time of last Rx */
|
||||
/* Interface address info used in eth_type_trans() */
|
||||
unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address, (before bcast
|
||||
because most packets are unicast) */
|
||||
because most packets are unicast) */
|
||||
|
||||
unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */
|
||||
|
||||
@ -648,6 +761,10 @@ struct net_device
|
||||
/* Number of TX queues currently active in device */
|
||||
unsigned int real_num_tx_queues;
|
||||
|
||||
/* Map buffer to appropriate transmit queue */
|
||||
u16 (*select_queue)(struct net_device *dev,
|
||||
struct sk_buff *skb);
|
||||
|
||||
unsigned long tx_queue_len; /* Max frames per queue allowed */
|
||||
spinlock_t tx_global_lock;
|
||||
/*
|
||||
@ -662,9 +779,6 @@ struct net_device
|
||||
int watchdog_timeo; /* used by dev_watchdog() */
|
||||
struct timer_list watchdog_timer;
|
||||
|
||||
/*
|
||||
* refcnt is a very hot point, so align it on SMP
|
||||
*/
|
||||
/* Number of references to this device */
|
||||
atomic_t refcnt ____cacheline_aligned_in_smp;
|
||||
|
||||
@ -683,56 +797,14 @@ struct net_device
|
||||
NETREG_RELEASED, /* called free_netdev */
|
||||
} reg_state;
|
||||
|
||||
/* Called after device is detached from network. */
|
||||
void (*uninit)(struct net_device *dev);
|
||||
/* Called after last user reference disappears. */
|
||||
void (*destructor)(struct net_device *dev);
|
||||
/* Called from unregister, can be used to call free_netdev */
|
||||
void (*destructor)(struct net_device *dev);
|
||||
|
||||
/* Pointers to interface service routines. */
|
||||
int (*open)(struct net_device *dev);
|
||||
int (*stop)(struct net_device *dev);
|
||||
#define HAVE_NETDEV_POLL
|
||||
#define HAVE_CHANGE_RX_FLAGS
|
||||
void (*change_rx_flags)(struct net_device *dev,
|
||||
int flags);
|
||||
#define HAVE_SET_RX_MODE
|
||||
void (*set_rx_mode)(struct net_device *dev);
|
||||
#define HAVE_MULTICAST
|
||||
void (*set_multicast_list)(struct net_device *dev);
|
||||
#define HAVE_SET_MAC_ADDR
|
||||
int (*set_mac_address)(struct net_device *dev,
|
||||
void *addr);
|
||||
#define HAVE_VALIDATE_ADDR
|
||||
int (*validate_addr)(struct net_device *dev);
|
||||
#define HAVE_PRIVATE_IOCTL
|
||||
int (*do_ioctl)(struct net_device *dev,
|
||||
struct ifreq *ifr, int cmd);
|
||||
#define HAVE_SET_CONFIG
|
||||
int (*set_config)(struct net_device *dev,
|
||||
struct ifmap *map);
|
||||
#define HAVE_CHANGE_MTU
|
||||
int (*change_mtu)(struct net_device *dev, int new_mtu);
|
||||
int (*neigh_setup)(struct net_device *dev, struct neigh_parms *);
|
||||
|
||||
#define HAVE_TX_TIMEOUT
|
||||
void (*tx_timeout) (struct net_device *dev);
|
||||
|
||||
void (*vlan_rx_register)(struct net_device *dev,
|
||||
struct vlan_group *grp);
|
||||
void (*vlan_rx_add_vid)(struct net_device *dev,
|
||||
unsigned short vid);
|
||||
void (*vlan_rx_kill_vid)(struct net_device *dev,
|
||||
unsigned short vid);
|
||||
|
||||
int (*neigh_setup)(struct net_device *dev, struct neigh_parms *);
|
||||
#ifdef CONFIG_NETPOLL
|
||||
struct netpoll_info *npinfo;
|
||||
#endif
|
||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
void (*poll_controller)(struct net_device *dev);
|
||||
#endif
|
||||
|
||||
u16 (*select_queue)(struct net_device *dev,
|
||||
struct sk_buff *skb);
|
||||
|
||||
#ifdef CONFIG_NET_NS
|
||||
/* Network namespace this network device is inside */
|
||||
@ -763,6 +835,38 @@ struct net_device
|
||||
/* for setting kernel sock attribute on TCP connection setup */
|
||||
#define GSO_MAX_SIZE 65536
|
||||
unsigned int gso_max_size;
|
||||
|
||||
#ifdef CONFIG_COMPAT_NET_DEV_OPS
|
||||
struct {
|
||||
int (*init)(struct net_device *dev);
|
||||
void (*uninit)(struct net_device *dev);
|
||||
int (*open)(struct net_device *dev);
|
||||
int (*stop)(struct net_device *dev);
|
||||
void (*change_rx_flags)(struct net_device *dev,
|
||||
int flags);
|
||||
void (*set_rx_mode)(struct net_device *dev);
|
||||
void (*set_multicast_list)(struct net_device *dev);
|
||||
int (*set_mac_address)(struct net_device *dev,
|
||||
void *addr);
|
||||
int (*validate_addr)(struct net_device *dev);
|
||||
int (*do_ioctl)(struct net_device *dev,
|
||||
struct ifreq *ifr, int cmd);
|
||||
int (*set_config)(struct net_device *dev,
|
||||
struct ifmap *map);
|
||||
int (*change_mtu)(struct net_device *dev, int new_mtu);
|
||||
void (*tx_timeout) (struct net_device *dev);
|
||||
struct net_device_stats* (*get_stats)(struct net_device *dev);
|
||||
void (*vlan_rx_register)(struct net_device *dev,
|
||||
struct vlan_group *grp);
|
||||
void (*vlan_rx_add_vid)(struct net_device *dev,
|
||||
unsigned short vid);
|
||||
void (*vlan_rx_kill_vid)(struct net_device *dev,
|
||||
unsigned short vid);
|
||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
void (*poll_controller)(struct net_device *dev);
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
};
|
||||
#define to_net_dev(d) container_of(d, struct net_device, dev)
|
||||
|
||||
|
Reference in New Issue
Block a user