Detailed description of sk_buff encapsulation and Network Packet encapsulation process

Source: Internet
Author: User

Detailed description of sk_buff encapsulation and Network Packet encapsulation process
It can be said that the sk_buff struct is the core of the Linux network protocol stack, and almost all operations are performed around the sk_buff struct, its importance is similar to that of BSD's mbuf (I have read "TCP/IP details Volume 2"). What is sk_buff?
1. Allocate a skb struct
It can be seen that the basic mode is "positioning/setting". The difference is that the application layer operations are generally completed on the socket interface. However, since this article describes general operations of skb, we will not distinguish this.
The alloc_skb interface completes two tasks: allocating the skb struct and the skb data packet buffer, and setting the initial value. The size parameter indicates the size of the Data Packet Buffer of skb, which includes the sum of all layers. If this function is successfully returned, it is equivalent to an empty data packet buffer with a size and skb metadata that operates the data packet buffer. As shown in:



2. The key to layer-by-layer encapsulation of the skb_reserve skb lies in the positioning of the write pointer, that is, where the layer starts to write. From the image of the Protocol-encapsulated pressure stack, this positioning should be in a regular order. Initial positioning is very important, and subsequent positioning is routine. The initial positioning is, of course, to the end of the application layer. From here, the protocol header is pushed layer by layer to the Data Packet Buffer of skb. The initial positioning diagram is as follows:


3. copy application layer data (skb_push/copy) after skb is allocated, You need to locate the Protocol "stack" in the "lowest position" of the data packet. This is the initial position, in this way, the data or protocol header of each layer can be pushed to the stack. This operation is completed by skb_reserve. The data on the application layer has been encapsulated on the socket, so the data packet buffer write pointer of skb is located at the beginning of the Application Data. At this time, the write pointer is located at the end of the application layer buffer, therefore, you need to use the skb_push operation to locate the write pointer at the beginning of the application layer, which means that the frame is pushed to the application layer stack.


After the application layer stack frame is pushed into the protocol stack, you can start at the write pointer position and write n Bytes of application layer data continuously. Generally, the data comes from the socket.


Next, you can happily set the transport layer header in the position returned by skb_push, UDP and TCP. It depends on your understanding of the transport layer. The header of the transport layer is set to write data at the position returned by skb_push. The write length is specified by the skb_push parameter, that is, n.


Next we can happily set the IP layer header in the position returned by skb_push. How to set it depends on your understanding of the IP layer. Because it only demonstrates how skb is encapsulated, there is no IP routing process that is very important to the IP layer.


So far, I have encapsulated a complete ethereum frame that can be sent directly through dev_queue_xmit. Along the way, you will find that the skb data packet buffer is gradually filled in the form of "push". Each layer is pushed to a stack frame through the skb_push interface, and the write pointer is returned, then write the stack frame length data starting from the write pointer according to the protocol logic of this layer.
Headroom or tailroom is required at this time. For example, to append data to the data packet, see:



In fact, the skb_put operation is to append data to the end of the data packet. As for how to use headroom, I will not mention it. In fact, it is skb_push. What is the use of headroom? The Front Guide code, which is encapsulated by X over Y.

The actual example is as follows: encapsulate an Ethernet frame and send it out:
Skb = alloc_skb (1500, GFP_ATOMIC); skb-> dev = dev; // routinely populate the skb metadata/* retain the skb Region */skb_reserve (skb, 2 + sizeof (struct ethhdr) + sizeof (struct iphdr) + sizeof (app_data);/* construct the data zone */p = skb_push (skb, sizeof (app_data )); memcpy (p, & app_data [0], sizeof (app_data); p = skb_push (skb, sizeof (struct udphdr); udphdr = (struct udphdr *) p; // fill in the udphdr field, for example, skb_reset_transport_header (skb);/* construct the IP header */p = skb_push (skb, sizeof (struct iphdr); iphdr = (struct iphdr *) p; // fill in the iphdr field, slightly skb_reset_network_header (skb);/* construct the Ethernet header */p = skb_push (skb, sizeof (struct ethhdr )); ethhdr = (struct ethhdr *) p; // fill in the ethhdr field, slightly skb_reset_mac_header (skb);/* launch */dev_queue_xmit (skb );

Skb_reset_mac_headerskb_reset_network_headerskb_reset_transport_headerThe call time is the time when skb_push returns. Once upon a time, I set the location of the protocol header in the following way:
/* Construct the IP header */p = skb_push (skb, sizeof (struct iphdr); iphdr = (struct iphdr *) p; // fill in the iphdr field, // skb_reset_network_header (skb); skb-> network_header = p;Is it wrong? At first glance, it was correct, but an error was reported:
Protocol 0008 is buggy, dev eth2
# If BITS_PER_LONG> 32 # define NET_SKBUFF_DATA_USES_OFFSET 1 # endif # ifdef extends unsigned int sk_buff_data_t; # elsetypedef unsigned char * sk_buff_data_t; # endifIn addition to space saving, the interface implementation for size-related operations is also more unified. This is the details, and these details are not the concern of people playing the network protocol stack, are they? This is completely at the system implementation level and has nothing to do with the business logic.
Alloc_skb:Allocate a skb;
Skb_reserver:The write pointer moves backward to a position p, which is determined as the end of the data packet. From the beginning, the write pointer starts to move forward from this position to encapsulate the data packet;
Skb_push:The write pointer moves forward n to update the length of the data packet. From the returned position, you can write n bytes of data-that is, the protocol that encapsulates n Bytes;
Skb_put:The write pointer moves to the end of the data packet and returns the tail pointer. You can write n bytes of data from this position and update the tail pointer and the length of the data packet;

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.