Linux network devices are different from character devices and block devices, and no files correspond to network devices. The application operates the network device through the socket.
The network device driver belongs to the data link layer, communicates with the IP/ARP protocol, and directly operates the physical layer chip (NIC Chip). The three-layer protocol sends data through DEV_QUEUE_XMIT (), receives data through NETIF_RX (), and network device drivers send data through the Hard_startx_xmit () operation of the physical network card, receiving packets by means of interrupts. The core of the network drive is the struct net_device, which abstracts the ever-changing network card.
A Important Data structures
1.struct Net_device, Include/linux/netdevice.h
Important members are as follows:
>> Global Information
Char Name[ifnamesiz]; NIC device name, global variable
>> Hardware Information
unsigned long mem_end; /* Shared mem End */
unsigned long mem_start; /* Shared mem start */
Starting and ending addresses for shared memory
unsigned long base_addr; /* device I/O address */network device I/O base Address
unsigned int IRQ; /* Device IRQ Number */device use interrupt
unsigned char if_port; /* selectable AUI, TP,.. */
Which port is used by a multiport device, and this field is for multiport devices only. This field can be used if the device supports both IF_PORT_10BASE2 (coaxial cable) and If_port_10baset (twisted pair).
unsigned char DMA; /* DMA Channel */
>> Interface Information
unsigned int flags; /* Interface flags (a la BSD) */
Network interface flags, starting with iff_ (Interface flag), some flags are managed by the kernel, and others are set at interface initialization to illustrate the capabilities and features of the device interface. The interface flags include IFF_UP (when the device activates and can send packets, kernel settings), Iff_automedia (device section switches between multiple mediums), Iff_broadcast (allow broadcast), Iff_debug (debug mode, A detailed program that can be used to control PRINTK calls), Iff_loopback (loopback), Iff_multicast (allow multicast), Iff_noarp (interfaces cannot perform ARP), and Iff_pointtopoint (interfaces connected to point-to-point links), and so on.
unsigned int MTU; /* Interface MTU value */
unsigned short type; /* Interface Hardware type */
unsigned short hard_header_len; /* Hardware HDR length */
The hardware head length of the network device, in the initialization function of the Ethernet device, the member is assigned a value of Eth_hlen, which is 14.
/* Interface address info used in Eth_type_trans () */
unsigned char *dev_addr; /* HW address, (before bcast because most packets is unicast) */
Device hardware address, the driver may provide an interface to set the MAC address, which causes the MAC address set to be saved to that member.
>> Device Operation function
/* Management Operations */
const struct NET_DEVICE_OPS *netdev_ops;
const struct ETHTOOL_OPS *ethtool_ops;
The Ethtool_ops member function corresponds to the various command options of the user space Ethtool tool, Ethtool provides network card and network card driver management capability, and provides Linux network developers with the ability to set up, view, and debug network card hardware, drivers, and networking protocol stacks.
/* Hardware Header Description */
const struct HEADER_OPS *header_ops;
Corresponding to the hardware head operation, the main finish is to create the hardware head and analyze the hardware head from the given Sk_buff and other operations.
>> Auxiliary Members
/*
* Trans_start Here's expensive for high speed devices on SMP,
* Please use Netdev_queue->trans_start instead.
*/
unsigned long trans_start; /* Time (in jiffies) of the last Tx */
unsigned long last_rx; /* Time of last Rx
* This should not being set in
* drivers, unless really needed,
* Because network stack (bonding)
* Use it if/when necessary, to
* Avoid dirtying this cache line.
*/
Trans_start records the timestamp at which the last packet began to be sent, last_rx the timestamp when the packet was last received, both of which are recorded jiffies, and the driver should maintain the two members.
2.struct Net_device_ops, Include/linux/netdevice.h
Int (*ndo_open) (struct net_device *dev);
Open the network interface device to get the I/O address, IRQ, DMA channel, etc. required by the device. The Stop () function is the function of stopping the network interface device.
netdev_tx_t (*ndo_start_xmit) (struct sk_buff *skb, struct net_device *dev);
Initiating the sending of a packet
void (*ndo_tx_timeout) (struct net_device *dev);
When a packet is sent out, the function takes steps such as restarting the packet sending process or restarting the hardware to restore the network device to its normal state.
struct net_device_stats* (*ndo_get_stats) (struct net_device *dev);
Returns the status information of the network device, and the NET_DEVICE_STATS structure maintains detailed network device traffic statistics.
Int (*ndo_do_ioctl) (struct net_device *dev, struct ifreq *ifr, int cmd);
Device-Specific IO control
Int (*ndo_set_config) (struct net_device *dev, struct ifmap *map);
The configuration interface can also be used to change the IO address and interrupts of the device.
Int (*ndo_set_mac_address) (struct net_device *dev, void *addr);
Set the MAC address of the device
3.more
Two Sk_buff operation
struct Sk_buff defined in include/linux/skbuff.h
/** struct Sk_buff-socket buffer* @next: Next buffer in list* @prev: Previous buffer in list* @tstamp: time we arrived* @sk: Socket We are owned by* @dev: Device We arrived On/are leaving by* @cb: Control buffer. Free to use by every layer. Put private VARs here* @_skb_refdst:destination entry (with Norefcount bit) * @sp: The security path, used for xfrm* @len: Length of actual data* @data_len: Data length* @mac_len: Length of link layer header* @hdr_len: writable header length of Cloned skb* @csum: Checksum (must include Start/offset pair) * @csum_start: Offset from skb->head where checksumming sh Ould start* @csum_offset: Offset from Csum_start where checksum should is stored* @priority: Packet queueing priority* @lo Cal_df:allow local fragmentation* @cloned: Head May is cloned (check refcnt to being sure) * @ip_summed: Driver Fed us an IP checksum* @nohdr: Payload reference only, must not modify header* @nfctinfo: Relationship of this SKB to the connection* @ Pkt_type:packet class*@fclone: Skbuff clone status* @ipvs_property: Skbuff is owned by ipvs* @peeked: This packet have been seen already, so stat S has been* done for it, and don ' t them again* @nf_trace: NetFilter packet trace flag* @protocol: Packet protocol from DRI ver* @destructor: Destruct function* @nfct: Associated connection, if any* @nfct_reasm: NetFilter conntrack re-assembly PO inter* @nf_bridge: Saved data about a bridged frame-see br_netfilter.c* @skb_iif: IfIndex of device we arrived on* @tc_i Ndex:traffic control index* @tc_verd: Traffic control verdict* @rxhash: The packet hash computed on receive* @queue_mappi Ng:queue mapping for Multiqueue devices* @ndisc_nodetype: router type [from link layer] * @ooo_okay: Allow the mapping of A socket to a queue to being changed* @l4_rxhash: Indicate Rxhash is a canonical 4-tuple hash over transport ports.* @dma_coo Kie:a Cookie to one of several possible DMA operations* do by SKB DMA functions* @secmark: Security marking* @mark: Gen Eric Packet mark* @dropcOunt:total number of Sk_receive_queue overflows* @vlan_tci: VLAN tag control information* @transport_header: Transport LA Yer header* @network_header: Network layer header* @mac_header: Link layer header* @tail: tail pointer* @end: End pointer* @head: Head of buffer* @data: Data head pointer* @truesize: Buffer size* @users: User count-see {datagram,tcp}.c*/structSk_buff {/*these must be first.*/structSk_buff *Next;structSk_buff *prev;/*These elements must is at the end and see ALLOC_SKB () for details.*/sk_buff_data_t tail;sk_buff_data_t end;unsignedChar*head, *data;unsignedinttruesize;atomic_t users;};
Head and end point to the head and tail of the buffer, while data and tail point to the head and tail of the actual data. Each layer fills the protocol header between head and data, or adds new protocol data between tail and end.
>> distribution
Static inline struct Sk_buff *alloc_skb (unsigned int size, gfp_t priority);
extern struct Sk_buff *dev_alloc_skb (unsigned int length);
The size of the ALLOC_SKB () is aligned with the l1_cache_bytes byte (for ARM 32), and the parameter priority is the memory allocation precedence. DEV_ALLOC_SKB () allocates the SKB with the gfp_atomic priority, because the function is often called in a device-driven receive interrupt.
>> Release
void Kfree_skb (struct sk_buff *skb);
void Consume_skb (struct sk_buff *skb);
#define DEV_KFREE_SKB (a) consume_skb (a)
void Dev_kfree_skb_irq (struct sk_buff *skb);
void Dev_kfree_skb_any (struct sk_buff *skb);
The KFREE_SKB () function is used internally in the Linux kernel, and in network device drivers it is preferable to release the socket buffer with DEV_KFREE_SKB (), DEV_KFREE_SKB_IRQ (), and Dev_kfree_skb_any (). where DEV_KFREE_SKB () is used for non-interrupt contexts, DEV_KFREE_SKB_IRQ () is used for interrupt contexts, and dev_kfree_skb_any () can be used in both interrupt and non-disruptive contexts.
>> Change
unsigned char *skb_put (struct sk_buff *skb, unsigned int len);
Static inline unsigned char *__skb_put (struct sk_buff *skb, unsigned int len)
{
unsigned char *tmp = Skb_tail_pointer (SKB);
Skb_linear_assert (SKB);
Skb->tail + = Len;
Skb->len + = Len;
return TMP;
}
It causes the skb->tail to move after Len and Skb->len increases the Len size.
unsigned char *skb_push (struct sk_buff *skb, unsigned int len);
Static inline unsigned char *__skb_push (struct sk_buff *skb, unsigned int len) {
Skb->data-= Len;
Skb->len + = Len;
Return skb->data;
}
It causes Skb->data to move forward Len, while Skb->len increases Len.
extern unsigned char *skb_pull (struct sk_buff *skb, unsigned int len);
Static inline unsigned char *__skb_pull (struct sk_buff *skb, unsigned int len)
{
Skb->len-= Len;
Bug_on (Skb->len < Skb->data_len);
return skb->data + = Len;
}
It removes the data at the beginning of the buffer.
static inline void Skb_reserve (struct sk_buff *skb, int len)
{
Skb->data + = Len;
Skb->tail + = Len;
}
For an empty buffer, call the following function to adjust the head of the buffer. Move Skb->data and skb->tail back to Len at the same time.
>> Example
SKB = ALLOC_SKB (Len+headspace, Gfp_kernel);
Skb_reserve (SKB, headspace);
Skb_put (SKB, Len);
Memcpy_fromfs (skb->data, data, Len);
Pass_to_m_protocol (SKB);
The above code first allocates a completely new sk_buff, then calls Skb_reserve () frees up the head space, then calls Skb_put () frees up the data space, then copies the data in, finally passes the Sk_buff to the protocol stack.
Three Important Operation functions
1.NAPI
Typically, network device drivers receive packets in an interrupted manner, while Poll_controller () uses pure polling, and the other is the NAPI (New API), whose data receive process is "receive interrupt coming Turn off receive interrupts--poll to receive all packets until receive interrupts----open receive interrupts---the kernel provides the following functions:
/**
* Netif_napi_add-initialize a NAPI context
* @dev: Network device
* @napi: Napi Context
* @poll: Polling function
* @weight: Default weight
*
* NETIF_NAPI_ADD () must is used to initialize a NAPI context prior to calling
* *any* of the other Napi related func tions.
*/
void Netif_napi_add (struct net_device *dev, struct napi_struct *napi,
Int (*poll) (struct napi_struct *, int ), int weight);
/**
* Netif_napi_del-remove a NAPI context
* @napi: Napi context
*
* Netif_napi_del () removes a NAPI context from the network device NAPI list
*/
void Netif_napi_del (struct napi_struct *napi);
static inline void napi_enable (struct napi_struct *n);
static inline void napi_disable (struct napi_struct *n);
static inline int napi_schedule_prep (struct napi_struct *n);
Used to check if Napi can be dispatched
static inline void Napi_schedule (struct napi_struct *n);
To schedule polling instances to run
extern void Napi_complete (struct napi_struct *n);
Called when NAPI processing is complete
2. Upper Operation function
Net/core/dev.c
int dev_queue_xmit (struct sk_buff *skb);
int Netif_rx (struct sk_buff *skb);
3.more
Four Network Driver
1. Registration cancellation
extern int Register_netdev (struct net_device *dev);
extern void Unregister_netdev (struct net_device *dev);
The generation of Net_device and the assignment of members do not have to be done manually by the engineer, and can be populated with the following macros:
extern struct Net_device *alloc_netdev_mqs (int sizeof_priv, const char *name, void (*setup) (struct Net_device *),
unsigned int txqs, unsigned int rxqs);
The first parameter is the device private member size, the second parameter is the device name, the third parameter is the setup () function pointer for Net_device, and the fourth to fifth parameter is the number of send and receive sub-queues to allocate. The setup () function accepts a parameter that is also a net_device pointer that is used to preset the value of the Net_device member.
#define ALLOC_NETDEV (Sizeof_priv, name, Setup) \
Alloc_netdev_mqs (Sizeof_priv, Name, Setup, 1, 1)
#define ALLOC_NETDEV_MQ (Sizeof_priv, name, Setup, count) \
Alloc_netdev_mqs (Sizeof_priv, name, Setup, Count, Count)
void Free_netdev (struct net_device *dev); Release Net_device
2. Initialization of network devices
3. Opening and releasing of network devices
4. Data transmission Process
5. Data reception Process
6. Network Connection Status
7. Parameter settings and statistics
Five More
Reference:
1. Linux device Driver Development--Song Baohua
Linux Network device drivers