SKb_についてheader_pointer関数


本文書のCopylityはすべてyfydzに帰属します.GPLを使って発表します.自由にコピー、転載できます.転載する時は文書の完全性を維持してください.商業用途に使用することは厳禁です.
msn:[email protected]
ソース:http://yfydz.cublog.cn
1.   

 2.6.17     sk_buff               skb             ,    skb_header_pointer()     ,              。

         2.6.17.11。

2. skb_header_pointer  

        ,    :
/* 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;
}
     :
skb:   struct sk_buff   
offset:       ( IP )    
len:    
buffer:   ,     len

  skb_headlen()   :

/* include/linux/skbuff.h */
static inline unsigned int skb_headlen(const struct sk_buff *skb)
{
 return skb->len - skb->data_len;
}
  skb->len      , IPv4       IP    ,                ;skb->data_len           ,  skb->len - skb->data_len           。

  skb->data_len  0,   IP          ,              ,   skb_is_nonlinear()         ,           skb      。      sk_buff              :
http://vger.kernel.org/~davem/skb_data.html

  skb_header_pointer()       ,                  ,   ,            ,        ,   skb_copy_bits()      ,                :

/* 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) {
//            
  if (copy > len)
   copy = len;
  memcpy(to, skb->data + offset, copy);
  if ((len -= copy) == 0)
   return 0;
  offset += copy;
  to     += copy;
 }
//    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(to,
          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;
 }
//       skb      
 if (skb_shinfo(skb)->frag_list) {
  struct sk_buff *list = skb_shinfo(skb)->frag_list;
  for (; list; 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.  2.4   

 2.4         ,  2.4 netfilter         ,    skb      ,    skb      ,    skb     hook      skb->data_len   0 ,      。
 
netfilter        ip_ct_gather_frags(), 2.4            , 2.6.17          ,         ,                            。

4.   

  2.6.17            skb       ,                 ,                      ,                     。
          ,      ?                 ,           ,                  ?                  ?

   : 2006-08-31,   : 2006-09-14 08:59,   3391 ,   2       
	  : ydwoo0722 	  :2006-09-13 21:13:51 IP  :221.219.29.★
	

                        ,          TCP   。



 TSO(tcp segment offload), sendfile 。       file   page cache     ,          SKB   ,       65535 - TCP    。   E1000,   MSS              。


	  : yfydz 	  :2006-09-14 08:59:55 IP  :218.247.216.★
	

  !