小默

struct sk_buff

/home/green/src/list.c
alloc_skb
kfree_skb
skb_put
skb_trim


#############
/home/green/src/list.c
#############
alloc_skb
kfree_skb
skb_put  // used data后部扩展
skb_push // used data前部扩展
skb_pull // used data前部截断
skb_trim // used data后部截断
skb_reserve // data+分片后移,只允许对空缓存使用

skb_queue_head_init  // 初始化struct sk_buff_head
skb_queue_head  // list头部添加一个packet
skb_queue_tail  // list尾部添加一个packet
skb_dequeue      // 移去list头部第一个packet(返回移除的packet指针,内存没有收回?)
skb_dequeue_tail // 移去list尾部第一个packet  
skb_queue_purge  // 清空list中的节点
skb_append      // 在list的给定packet后append一个packet
skb_insert      // 在list的给定packet前insert一个packet



#############
alloc_skb
#############
<linux-2.6.36/net/core/skbuff.c>

__alloc_skb()分析:

申请struct skb_buff skb空间, 必须从CACHE中申请(skbuff_fclone_cache或skbuff_head_cache).
申请数据区内存, 使用kmalloc. 数据区包括字节对齐后的size和struct skb_shared_info.
填充skb结构.
填充分片信息struct skb_shared_info shinfo.
如果头部skb_buff是从skbuff_fclone_cache中申请的,do something... //TODO

********

__alloc_skb()完成时,内存状态:

skb           struct sk_buff     <-| skb->truesize
              --------------       |
data          size                 |
skb->data                          |
skb->head                          |
              -------------      <-|
              struct skb_shared_info

tail 和 end是偏移量
skb->tail = skb->data - skb->head = 0
skb->end = skb->tail + skb->size

********

head,data是指针,tail,end是偏移量。

<linux-2.6.36/include/linux/skbuff.h>
#ifdef NET_SKBUFF_DATA_USES_OFFSET
typedef unsigned int sk_buff_data_t;
#else
typedef unsigned char *sk_buff_data_t;
#endif

struct sk_buff {
    /* These elements must be at the end, see alloc_skb() for details.  */
    sk_buff_data_t      tail;
    sk_buff_data_t      end;
    unsigned char       *head,
    *data;

    unsigned int        truesize;
    atomic_t        users;
};

*********
skb,shinfo的引用计数都是原子类型atomic_t.
volatile只读内存,不读寄存器. 


#############
kfree_skb
#############
内存屏障

软件可通过读写屏障强制内存访问次序.所有在设置读写屏障之前发起的内存访问,必须先于在设置屏障之后发起的内存访问之前完成,确保内存访问按程序的顺序完成.

smp_mb()    适用于多处理器的内存屏障。
smp_rmb()   适用于多处理器的读内存屏障。

http://blogold.chinaunix.net/u3/93713/showart_2061476.html


#############
skb_put
#############
BUG() BUGON()

BUG()和BUG_ON()被用来提供断言,当被调用时会引发oops,导致栈的回溯和错误信息的打印.
大部分体系结构把BUG()定义成某种非法操作.
断言某种情况不该发生:
if(bad_thing):
    BUG();
或者更好的形式:
BUG_ON(bad_thing);

******
frag_list

如果传输层将数据包分片了,就会把这些数据包放到skb的frag_list链表中.

******
skb_put 在尾部扩展used data area.常被用于给数据块添加协议尾部.
其实就修改了tail偏移量和len值,别的什么都没做.
设了俩断言:
数据包不能有分片;
扩展数据区不能超出skb->end.


#############
skb_trim
#############
struct sk_buff

truesize = skb + data
len = data + 分片
data+len = 分片

posted on 2011-03-24 18:07 小默 阅读(907) 评论(0)  编辑 收藏 引用 所属分类: Linux


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

统计

留言簿(13)

随笔分类(287)

随笔档案(289)

漏洞

搜索

积分与排名

最新评论

阅读排行榜