skb管理函数之skb_put、skb_push、skb_pull、skb_reserve
skb操作中的预留和对齐操作主要由skb_put、skb_push、skb_pull、skb_reserve完成;这几个函数的区别通过下面图(图片来自:深入理解linux网络技术内幕)可以清晰的区分;另外,需要注意的是skb_reserve只能操作空skb,即在分配了空间,尚未填充数据时调用;

以下为四个函数的源码分析;
/**
* skb_put - add data to a buffer
* @skb: buffer to use
* @len: amount of data to add
*
* This function extends the used data area of the buffer. If this would
* exceed the total buffer size the kernel will panic. A pointer to the
* first byte of the extra data is returned.
*/
/*
向skb尾部添加数据
*/
unsigned char *skb_put(struct sk_buff *skb, unsigned int len)
{
/* 获取当前skb->tail */
unsigned char *tmp = skb_tail_pointer(skb); /* 要求skb数据区必须为线性 */
SKB_LINEAR_ASSERT(skb); /* skb尾部增加len字节 */
skb->tail += len;
/* skb数据总长度增加len字节 */
skb->len += len; /* 如果增加之后的tail > end ,则panic */
if (unlikely(skb->tail > skb->end))
skb_over_panic(skb, len, __builtin_return_address()); //返回添加数据的第一个字节位置
return tmp;
}
/**
* skb_push - add data to the start of a buffer
* @skb: buffer to use
* @len: amount of data to add
*
* This function extends the used data area of the buffer at the buffer
* start. If this would exceed the total buffer headroom the kernel will
* panic. A pointer to the first byte of the extra data is returned.
*/
/*
向skb数据区头部添加数据
*/
unsigned char *skb_push(struct sk_buff *skb, unsigned int len)
{
/* 数据区data指针前移len字节 */
skb->data -= len;
/* 数据总长度增加len字节 */
skb->len += len; /* 添加数据长度溢出过header ,panic*/
if (unlikely(skb->data<skb->head))
skb_under_panic(skb, len, __builtin_return_address()); /* 返回新的data指针 */
return skb->data;
}
/**
* skb_pull - remove data from the start of a buffer
* @skb: buffer to use
* @len: amount of data to remove
*
* This function removes data from the start of a buffer, returning
* the memory to the headroom. A pointer to the next data in the buffer
* is returned. Once the data has been pulled future pushes will overwrite
* the old data.
*/
/*
从数据区头部移除数据
*/
unsigned char *skb_pull(struct sk_buff *skb, unsigned int len)
{
return skb_pull_inline(skb, len);
}
/* 根据移除数据长度判断函数调用 */
static inline unsigned char *skb_pull_inline(struct sk_buff *skb, unsigned int len)
{
/*
移除长度> skb数据总长度,返回NULL
否则,继续调用_skb_pull函数
*/
return unlikely(len > skb->len) ? NULL : __skb_pull(skb, len);
}
/* 从skb数据区头部移除数据 */
static inline unsigned char *__skb_pull(struct sk_buff *skb, unsigned int len)
{
/* 数据总长度减去len字节 */
skb->len -= len;
/* 数据总长度是否有异常 */
BUG_ON(skb->len < skb->data_len); /*
data指针移动len字节
返回移除之后新的data指针
*/
return skb->data += len;
}
/*
保留头部空间,只能对空的skb使用
*/
static inline void skb_reserve(struct sk_buff *skb, int len)
{
/* 数据区data指针增加len字节*/
skb->data += len;
/* 数据区tail指针增加len字节 */
skb->tail += len;
}
skb管理函数之skb_put、skb_push、skb_pull、skb_reserve的更多相关文章
- skb管理函数之skb_clone、pskb_copy、skb_copy
skb_clone--只复制skb描述符本身,如果只修改skb描述符则使用该函数克隆: pskb_copy--复制skb描述符+线性数据区域(包括skb_shared_info),如果需要修改描述符以 ...
- skb管理函数之alloc_skb、dev_alloc_skb、kfree_skb、dev_kfree_skb、consume_skb
alloc_skb--分配skb dev_alloc_skb--分配skb,通常被设备驱动用在中断上下文中,它是alloc_skb的封装函数,因为在中断处理函数中被调用,因此要求原子操作(GFP_AT ...
- μC/OS-Ⅲ系统的时间管理函数和定时器
一.时间管理函数 μC/OS-Ⅲ系统提供一些列时间管理服务函数: 1.OSTimeDly():任务延时n个时钟节拍. 2.OSTimeDlyHMSM():任务延时指定的时间,采用“时:分:秒:毫秒”方 ...
- 内存管理运算符new delete与内存管理函数malloc free的区别——已经他们对对象创建的过程。
(1)内存管理函数与内存管理运算符的区别 内存管理函数有内存分配函数,malloc calloc realloc 以及内存释放函数free. 内存管理运算符有new 和delete. 两种内存管理方式 ...
- functools:管理函数工具(部分)
# -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' #functools:管理函数工具 #作用:处理其他函数的函数 #版 ...
- POSIX多线程——基本线程管理函数介绍
POSIX基本的几个线程管理函数见下表: ------------------------------------------------------------------------------- ...
- [图形学] Chp9 三维几何变换--栈处理函数与矩阵管理函数的区别
矩阵管理函数:glLoadIdentity()是把当前活动矩阵设置为单位矩阵. 栈处理函数:glPushMatrix()是将当前活动的变换矩阵复制一份,压入栈顶:glPopMatrix()是破坏当前活 ...
- C++内存管理-重载内存管理函数
记录学习的点点滴滴,参考侯捷<<C++内存管理>> 我们先重载一下C++的几个内存管理函数 operator new, operator new[], operator del ...
- 【教训】null == '',改造ThinkSNS 系统里面的一个缓存管理函数S()后,留下一个大bug
本来想简化 ThinkSNS 系统里面的一个缓存管理函数: <?php /** * 用来对应用缓存信息的读.写.删除 * $expire = null/0 表示永久缓存,否则为缓存有效期 */ ...
随机推荐
- 学习 SQL 语句 - Select(9): 其他
//只要前五条记录 procedure TForm1.Button1Click(Sender: TObject); begin with ADODataSet1 do begin Clos ...
- 【其他】UTF-8带签名与不带签名
在 Visual Web Developer 另存为文件时,有编码选项,其中有: Unicode (UTF-8 with signature) - Codepage 65001 Unicode (UT ...
- SQL查询数据总结
SQL查询数据 完整语法 Select [select选项] 字段列表[字段别名]/* from 数据源 [where条件子句] [group by子句] [having子句] [order by子句 ...
- 2011 Multi-University Training Contest 8 - Host by HUST
Rank:56/147. 开场看B,是个线段树区间合并,花了2hour敲完代码...再花了30min查错..发现push_down有问题.改了就AC了. 然后发现A过了很多人.推了个公式,发现是个分段 ...
- 【hdu4734】F(x) 数位dp
题目描述 对于一个非负整数 $x=\overline{a_na_{n-1}...a_2a_1}$ ,设 $F(x)=a_n·2^{n-1}+a_{n-1}·2^{n-2}+...+a_2·2^1+ ...
- queue队列
1.作用:解耦,提高效率.队列就是一个容器,一个有顺序的容器. q.queue.Queue(maxsize=3): 生成一个队列的实例,并且最多存储3个元素 q.get(item,block=Ture ...
- [洛谷P4174][NOI2006]最大获利
题目大意:同Petya and Graph,数据范围改成$n\leqslant5\times10^3,m\leqslant5\times10^4$ 题解:同上 卡点:无 C++ Code: #incl ...
- pandas模块(数据分析)------Series
pandas是一个强大的Python数据分析的工具包. pandas是基于NumPy构建的. pandas的主要功能: 具备对其功能的数据结构DataFrame.Series 集成时间序列功能 提供丰 ...
- mybaties实体的 Mapper.xml文件中自定义sql时模糊查询的写法
<select id=selectByNameLike" parameterType="string" resultMap="BaseResultMap ...
- HDU 4303 树形DP
Hourai Jeweled Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 163840/163840 K (Java/Others) ...