Summary previous we analyzed a virtual hardware network driver sample. From here we see some of the interfaces of the network devices. In fact, the function of network device driver and block device driver is similar, both sending and receiving packets (data request).
Of course they are actually very different.
1. Introduction
First, the block device has a device node under the/dev folder. Network devices do not have access to such devices.
Regular file interfaces such as Read,write do not make sense under network devices.
The biggest difference is that the block device responds only to the data request from the kernel, while the network device driver asynchronously receives packets from the outside. To put it simply. Block device drivers are required to transmit data while network devices are actively requesting data transfer. Network device drivers also need to support the setting of address, change the number of transfer parameters and so on. So the network device-driven API needs to provide these interfaces.
This article is a simple comb for the network-driven sample of virtual hardware above.
(1) Network equipment Registration
头文件:<linux/netdevice.h>struct net_device 网络设备结构体struct net_device *alloc_netdev (intconstcharvoid (*setup)(struct net_device *));int register_netdev(struct net_device *device); 注冊网络设备void unregitster_netdev(struct net_device *device); 注销网络设备
(2) Open and close
After the driver is loaded into the kernel, the kernel calls the probe function to probe it. When a network interface is capable of transmitting a packet, the kernel must first open it and set the address to it. The kernel opens and closes the network interface that is triggered by the ifconfig command.
(*open)(struct net_device*)(*stop)(struct net_device*); 关闭网络设备void netif_start_queue(struct net_device*); 启动网络传输队列void netif_stop_queue(struct net_device*); 关闭网络传输队列
(3) Transmission of network data
The most critical data for a network interface is the sending and receiving of network data.
头文件:<linux/skbuff.h> 定义了网络驱动中传输的基本单元。struct sk_buffstruct netdeviceops 网络设备驱动须要实现的接口函数netdev_tx_t (*ndo_start_xmit) (structstruct net_device *dev); 传输网络数据包的函数void (*ndo_tx_timeout) (struct net_device *dev); 传输超时函数
(4) Reception of network data
Receiving network data is more complex than sending data. Because you need to assign a sk_buff in an atomic context and hand it over to the upper layer.
Packet reception is implemented in two ways: Interrupt driver and polling. Most drivers are interrupt-driven. There are some high-throughput drivers that use polling methods.
structintlength); 原子上下文中分配skbprintk_ratelimit() 限制printk的输出频率,在中断对应函数中降低输出
To achieve a high-throughput network drive, the best way to reduce network congestion is to use NAPI, which is explained later
(5) Interrupt handling
The hardware can interrupt the CPU to send two kinds of events: the arrival of the new packet and the sending of the packet has been completed.
Infer and Process packet events
Assume that the send queue is temporarily stopped elsewhere. You should start it again in the interrupt function.
(6) NAPI
A high-throughput network interface assumes that each packet is handled with interrupts, which can put a huge burden on the system. You should use a polling-based NAPI at this time. This will reduce the burden on the system and reduce the time of blockage.
Only a handful of devices implement NAPI, which is more complex to implement than interrupts. And there are some other conditions.
In the interrupt handler function, the further interrupt processing is forbidden first, then the polling function is dispatched, and multiple data sending requests are processed continuously after entering the polling function.
int (*poll*devint*budget); 网络驱动轮询函数int*dev); 准备调用轮询函数int (*poll*devint*budget); 轮询函数
Linux LAN Driver Learning (ii) (Network Driver Interface Summary)