SKb_についてheader_pointer関数
4419 ワード
本文書のCopylityはすべてyfydzに帰属します.GPLを使って発表します.自由にコピー、転載できます.転載する時は文書の完全性を維持してください.商業用途に使用することは厳禁です.
msn:[email protected]
ソース:http://yfydz.cublog.cn
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.★
!