Article title: Linux network packet receiving and sending overview. Linux is a technology channel of the IT lab in China. Includes basic categories such as desktop applications, Linux system management, kernel research, embedded systems, and open source.
For Linux kernels, network packets are received by network devices. The device driver reads packets from network devices and transmits the packets to the network protocol stack in the kernel through the network interface functions provided by the kernel. Packets are processed by the protocol stack, forwarded, discarded, or transmitted to a process.
The opposite is the sending of network packets. a process sends data to the network protocol stack through a system call, or the network protocol stack sends packets by itself, the protocol stack then schedules the driver by calling the network interface function, so that it sends packets to the network device and sends them out.
This article discusses the network interface layer, which is the bond between the network device driver and the network protocol stack. See netif in red.
500) this. width = 500; "border = 0>
Message receipt
Network packets are received from network devices. After receiving a packet, the network device notifies the CPU through interruption. The NIC driver needs to register the processing function for the interrupt event (see linux interrupt handling analysis) to process received packets.
In the interrupt processing function, the network driver can process packets in two ways (the old method and the new method). let's first introduce the old-fashioned processing method. In this way, the interrupt handler mainly completes the following tasks:
Allocate a skb structure (this structure is used to save a packet ). Operate the device and copy the data received by the device to the buffer corresponding to the skb structure. Set the protocol type skb-> protocol of skb, which indicates the upper-layer protocol of the network protocol stack (we will see below ). Then call the network interface function netif_rx provided by the kernel;
Netif_rx (skb );
After the netif_rx function initializes the additional information such as the timestamp of the skb, it puts the skb structure into the input_pkt_queue queue of the softdate_net structure of the current CPU. Netif_rx judges the congestion status of the device based on the length of the queue (if the queue is too long, the message is received too quickly, so that the upper layer cannot process it ). If the device is congested, the received packets may be discarded directly.
If everything is normal, netif_rx will call the network interface function netif_rx_schedule to trigger further processing of received packets;
Netif_rx_schedule (dev );
Netif_rx uses the embedded backlog_dev in the softdate_net structure as dev to call netif_rx_schedule. The latter adds it to the poll_list queue in the softdate_net structure (if this dev is not in the queue ), to make it wait for scheduling.
Compared with the old-fashioned processing method, the new processing method (called NAPI) only calls the netif_rx_schedule function with the dev structure of the corresponding device as the parameter in the interrupt processing function.
Finally, the netif_rx_schedule function will trigger the NET_RX_SOFTIRQ soft interrupt, so the corresponding soft interrupt handler net_rx_action will be called;
Net_rx_action ();
Call the dev-> poll method for all dev in the poll_list queue of the softdate_net structure corresponding to the current CPU. This method is implemented by the driver corresponding to dev and is used to receive and process packets (except for backlog_dev mentioned above ).
Net_rx_action has a certain limit for each running, and it is not necessary to finish all the reports. Net_rx_action returns after a certain number of packets are processed or the processing process exceeds a certain period of time. A NET_RX_SOFTIRQ soft interrupt is triggered before the result is returned, and the task continues to be scheduled when the next interruption arrives.
The above process (from ULNI ):
500) this. width = 500; "border = 0>
The softdate_net structure mentioned above is a structure used for packet sending and receiving scheduling. the kernel maintains this structure for each CPU. Three members are used in the message receiving process:
1. poll_list: The dev queue of the network device. The device receives the message and needs to be processed;
2. input_pkt_queue, the queue of the skb packet structure, stores the received packets that need to be processed;
3. backlog_dev: a virtual network device dev structure;
The last two members are specially set to support older processing methods. In this mode, the received skb is put into the input_pkt_queue queue, and then the backlog_dev is added to the poll_list. Finally, the natural backlog_dev-> poll function will process the skb in the input_pkt_queue queue. Backlog_dev-> poll is the process_backlog function;
Process_backlog (backlog_dev, budget );
Since net_rx_action has a quota each time it runs, it will also pass the remaining quota value when calling dev-> poll, that is, budget.
Process_backlog traverses the skb in the input_pkt_queue queue and calls the netif_receive_skb function to process it.
The process_backlog function has two endings: one is the quota to or time to directly return; the other is to finish processing all skb in the input_pkt_queue queue. in this case, you need to delete backlog_dev from the poll_list.
The new NAPI processing method is similar to the old one. In its corresponding dev-> poll function, you need to allocate a skb structure, read packets from the device, call netif_receive_skb, and let the upper layer of the network protocol stack process packets.
[1] [2] Next page