About the skb_header_pointer Function

Source: Internet
Author: User
For the skb_header_pointer function, Copyleft in this document is owned by yfydz. You can freely copy and repost the function using GPL. ensure the integrity of the document during reprinting. It is strictly prohibited for any commercial purposes.
MSN: yfydz_no1@hotmail.com
Source: http://yfydz.cublog. cn1. preface in kernel 2.6.17, the parameters for obtaining the protocol headers in sk_buff are no longer directly reading the pointers of each protocol header defined in the SKB package, but obtained using the skb_header_pointer () function, why is this change interesting. The following kernel code version is 2.6.17.11. 2. skb_header_pointer function this function is simple and defined as follows:/* include/Linux/skbuff. H */static inline void * skb_header_pointer (const struct sk_buff * SKB, int offset,
Int Len, void * buffer)
{
Int hlen = skb_headlen (SKB); If (hlen-Offset> = Len)
Return SKB-> Data + offset; If (skb_copy_bits (SKB, offset, buffer, Len) <0)
Return NULL; return buffer;
} The parameters are:
SKB: pointer of the data packet struct sk_buff
Offset: the offset relative to the starting data header (such as the IP header)
Len: Data Length
Buffer: buffer. The size is not smaller than Len. skb_headlen () is defined as:/* include/Linux/skbuff. H */static inline unsigned int skb_headlen (const struct sk_buff * SKB)
{
Return SKB-> len-SKB-> data_len;
} SKB-> Len indicates the packet length. In IPv4, it indicates the total length of a complete IP packet. However, the data is not necessarily on the current Memory Page; SKB-> data_len indicates the Data Length on other pages, so SKB-> len-SKB-> data_len indicates the data size on the current page. If the value of SKB-> data_len is not 0, it indicates that the data of the IP packet belongs to different pages, and the data packet becomes non-linear.
Skb_is_nonlinear () is determined by this parameter. Generally, the SKB package that has just been reorganized belongs to this type. More details about the data pointers of sk_buff
For details, refer:
Http://vger.kernel.org /~ The skb_header_pointer () function like davem/skb_data.html is easy to understand. First, judge whether all the data to be processed is in the current page. If yes, the system returns data that can be processed directly and returns the Data Pointer, otherwise, use the skb_copy_bits () function for copying. This function is also a complicated processing function:/* Net/CORE/skbuff. C * // * copy some data bits from SKB to kernel buffer. */INT skb_copy_bits (const struct sk_buff * SKB, int offset, void * To, int Len)
{
Int I, copy;
Int start = skb_headlen (SKB); If (Offset> (INT) SKB-> len-len)
Goto fault;/* Copy header .*/
If (copy = start-offset)> 0 ){
// Copy the part on the current page
If (copy> Len)
Copy = Len;
Memcpy (to, SKB-> Data + offset, copy );
If (LEN-= copy) = 0)
Return 0;
Offset + = copy;
To + = copy;
} // Copy other parts of this SKB
For (I = 0; I <skb_shinfo (SKB)-> nr_frags; I ++ ){
Int end; bug_trap (start <= offset + Len); End = start + skb_shinfo (SKB)-> frags [I]. size;
If (copy = end-offset)> 0 ){
U8 * vaddr; If (copy> Len)
Copy = Len; vaddr = kmap_skb_frag (& skb_shinfo (SKB)-> frags [I]);
Memcpy (,
Vaddr + skb_shinfo (SKB)-> frags [I]. page_offset +
Offset-start, copy );
Kunmap_skb_frag (vaddr); If (LEN-= copy) = 0)
Return 0;
Offset + = copy;
To + = copy;
}
Start = end;
} // Copy the data part of another shard SKB
If (skb_shinfo (SKB)-> frag_list ){
Struct sk_buff * List = skb_shinfo (SKB)-> frag_list; For (; List = List-> next ){
Int end; bug_trap (start <= offset + Len); End = start + list-> Len;
If (copy = end-offset)> 0 ){
If (copy> Len)
Copy = Len;
If (skb_copy_bits (list, offset-start,
To, copy ))
Goto fault;
If (LEN-= copy) = 0)
Return 0;
Offset + = copy;
To + = copy;
}
Start = end;
}
}
If (! Len)
Return 0; fault:
Return-efault;
} 3. the difference from 2.4 is that 2.4 does not have this function, because 2.4 of Netfilter first reassembles the shard package, and then performs the SKB linearity check to normalize the non-linear SKB package, therefore, when the valid SKB package enters the subsequent hook point operation, the actual SKB-> data_len is all 0 and can be operated directly. The fragment reorganization function of Netfilter is ip_ct_gather_frags (). After the fragment reorganization is completed in 2.4, the system returns the result directly after the reorganization in 2.6.17, without linear operation, therefore, you must check whether the data to be processed is on the Memory Page. 4. conclusion because the SKB data packet is not linear after the fragment reorganization operation in 2.6.17, the data may exist in different memory pages, and data operations cannot be performed directly if the data is not on the same page, data needs to be copied to a separate buffer before processing. I don't know why I want to improve efficiency? Is it because there are very few fragmented packages on the network, most of the time it is a complete package, but how much efficiency will be reduced by checking in advance? Is it necessary to re-split the package when it is sent out later?

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.