Chinaunix首页 | 论坛 | 博客
  • 博客访问: 834357
  • 博文数量: 97
  • 博客积分: 3042
  • 博客等级: 中校
  • 技术积分: 1610
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-21 11:48
文章存档

2015年(1)

2014年(3)

2013年(4)

2012年(43)

2011年(44)

2010年(2)

分类: LINUX

2012-09-03 20:48:50

sk_buff  功能函数应用
    sk_buff是那些linux内核处理网络分组的缓存。上层协议模块需要发送数据包或者网络设备接收数据包时,都要调用alloc_skb分配套接字缓冲区,不许要时调用kfree_skb释放占用的套接字缓冲区。

skb支持的功能函数
主要描述一下sk_buff层最重要的一些功能函数。分配、释放、复制、克隆、扩展等功能函数。

分配:
struct sk_buff *alloc_skb(unsigned int len,int priority)
struct sk_buff *dev_alloc_skb(unsigned int len)
分配一个缓冲区。
alloc_skb分配一个缓冲区并初始化skb->data和skb->tail到skb->head。
dev_alloc_skb函数是以GFP_ATOMIC优先级调用alloc_skb,并保存skb->head和skb->data之间16个字节的一个快捷方式。这个数据空间可以用来"推(push)"硬件包头。
(这 两个函数的定义位于net/core/skbuff.c文件内。通过这alloc_skb()申请的内存空间有两个,一个是存放实际报文数据的内存空间, 通过kmalloc()函数申请;一个是sk_buff数据结构的内存空间,通过 kmem_cache_alloc()函数申请。dev_alloc_skb()的功能与alloc_skb()类似,它只被驱动程序的中断所调用,与 alloc_skb()比较只是申请的内存空间长度多了16个字节。)
例如:
 skb = alloc_skb(len, GFP_ATOMIC);//见注释
 kfree_skb(skb);

释放:
void kfree_skb(struct sk_buff *skb)
释放一个缓冲区。kfree_skb被内核内部使用。

struct sk_buff *skb_get(struct sk_buff *skb)
skb使用计数加一,返回一个指向skb的指针,获取数据。

克隆:
struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask)
这个函数克隆一个skb。两份拷贝共享分组数据,但分别拥有自己的sk_buff结构。新拷贝不属于任何socket,参考计数为1。

复制:
struct sk_buff *skb_copy(const struct sk_buff *skb, int gfp_mask)
产生一个实实在在的skb拷贝,包含分组数据。但你想要修改分组数据时,需要这么做。新拷贝的参考计数为1。

struct skb_copy_expand(const struct sk_buff *skb, int new_headroom, int new_tailroom, int gfp_mask)
产生一个skb拷贝,包含分组数据。另外,新skb还拥有一个/new_headroom/字节大
小的头空间,和一个/new_tailroom/字节大小的尾空间。

其它:
unsigned char *skb_put(struct sk_buff *sbk, int len)
扩展skb的数据域。如果总长度超出了skb的尺寸大小,内核将陷入慌乱。此函数将返回一个指向新数据第一个字节的指针。
(skb_put()向后扩大数据区空间,tailroom空间减少,skb->data指针不变,skb->tail指针下移)

unsigned char *skb_push(struct sk_buff *skb, int len)
扩展skb的数据域。
(skb_push()向前扩大数据区空间,headroom空间减少,skb->tail指针不变,skb->data指针上移)

unsigned char *skb_pull(struct sk_buff *skb, int len)
将数据从缓存起始处移除,回收头空间字节。返回一个指向缓存中下一个数据的指针。
(skb_pull()缩小数据区空间,headroom空间增大,skb->data指针下移,skb->tail指针不变。)


注释:
 通过kmalloc()函数申请
 kmalloc()
       1. 以字节为单位进行分配,在
       2. void *kmalloc(size_t size, int flags) 分配的内存物理地址上连续,虚拟地址上自然连续
       3. gfp_mask标志:什么时候使用哪种标志?如下:

              ----------------------------------------------------------------------------------------------

              情形                                                        相应标志

              ----------------------------------------------------------------------------------------------

              进程上下文,可以睡眠                     GFP_KERNEL

              进程上下文,不可以睡眠                  GFP_ATOMIC

              中断处理程序                                 GFP_ATOMIC

              软中断                                          GFP_ATOMIC

              Tasklet                                         GFP_ATOMIC

              用于DMA的内存,可以睡眠              GFP_DMA | GFP_KERNEL

              用于DMA的内存,不可以睡眠           GFP_DMA | GFP_ATOMIC

              ----------------------------------------------------------------------------------------------

       4. void kfree(const void *ptr)

              释放由kmalloc()分配出来的内存块
阅读(1476) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~