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的更多相关文章

  1. skb管理函数之skb_clone、pskb_copy、skb_copy

    skb_clone--只复制skb描述符本身,如果只修改skb描述符则使用该函数克隆: pskb_copy--复制skb描述符+线性数据区域(包括skb_shared_info),如果需要修改描述符以 ...

  2. skb管理函数之alloc_skb、dev_alloc_skb、kfree_skb、dev_kfree_skb、consume_skb

    alloc_skb--分配skb dev_alloc_skb--分配skb,通常被设备驱动用在中断上下文中,它是alloc_skb的封装函数,因为在中断处理函数中被调用,因此要求原子操作(GFP_AT ...

  3. μC/OS-Ⅲ系统的时间管理函数和定时器

    一.时间管理函数 μC/OS-Ⅲ系统提供一些列时间管理服务函数: 1.OSTimeDly():任务延时n个时钟节拍. 2.OSTimeDlyHMSM():任务延时指定的时间,采用“时:分:秒:毫秒”方 ...

  4. 内存管理运算符new delete与内存管理函数malloc free的区别——已经他们对对象创建的过程。

    (1)内存管理函数与内存管理运算符的区别 内存管理函数有内存分配函数,malloc calloc realloc 以及内存释放函数free. 内存管理运算符有new 和delete. 两种内存管理方式 ...

  5. functools:管理函数工具(部分)

    # -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' #functools:管理函数工具 #作用:处理其他函数的函数 #版 ...

  6. POSIX多线程——基本线程管理函数介绍

    POSIX基本的几个线程管理函数见下表: ------------------------------------------------------------------------------- ...

  7. [图形学] Chp9 三维几何变换--栈处理函数与矩阵管理函数的区别

    矩阵管理函数:glLoadIdentity()是把当前活动矩阵设置为单位矩阵. 栈处理函数:glPushMatrix()是将当前活动的变换矩阵复制一份,压入栈顶:glPopMatrix()是破坏当前活 ...

  8. C++内存管理-重载内存管理函数

    记录学习的点点滴滴,参考侯捷<<C++内存管理>> 我们先重载一下C++的几个内存管理函数 operator new, operator new[], operator del ...

  9. 【教训】null == '',改造ThinkSNS 系统里面的一个缓存管理函数S()后,留下一个大bug

    本来想简化 ThinkSNS 系统里面的一个缓存管理函数: <?php /** * 用来对应用缓存信息的读.写.删除 * $expire = null/0 表示永久缓存,否则为缓存有效期 */ ...

随机推荐

  1. asp.net MVC4 @Html.DropDownList的使用

    在MVC4中使用Razor语法,一使用就爱上他了, 一般项目都是有一些增删改查功能,表单下拉框是经常使用的,除了用原始的<select>外,还可以用@Html.DropDownList和@ ...

  2. 【bzoj2699】更新 dp

    题目描述 对于一个数列A[1..N],一种寻找最大值的方法是:依次枚举A[2]到A[N],如果A[i]比当前的A[1]值要大,那么就令A[1]=A[i],最后A[1]为所求最大值.假设所有数都在范围[ ...

  3. 【bzoj1705】[Usaco2007 Nov]Telephone Wire 架设电话线 dp

    题目描述 最近,Farmer John的奶牛们越来越不满于牛棚里一塌糊涂的电话服务 于是,她们要求FJ把那些老旧的电话线换成性能更好的新电话线. 新的电话线架设在已有的N(2 <= N < ...

  4. 转:Scipy入门

    Scipy入门 转:http://notes.yeshiwei.com/scipy/getting_started.html 本章节主要内容来自 Getting Started .翻译的其中一部分,并 ...

  5. [洛谷P4174][NOI2006]最大获利

    题目大意:同Petya and Graph,数据范围改成$n\leqslant5\times10^3,m\leqslant5\times10^4$ 题解:同上 卡点:无 C++ Code: #incl ...

  6. 洛谷 P1640 [SCOI2010]连续攻击游戏 解题报告

    P1640 [SCOI2010]连续攻击游戏 题目描述 lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当他使用某种装备 ...

  7. 洛谷 P3644 [APIO2015]八邻旁之桥 解题报告

    P3644 [APIO2015]八邻旁之桥 题目描述 一条东西走向的穆西河将巴邻旁市一分为二,分割成了区域\(A\)和区域\(B\). 每一块区域沿着河岸都建了恰好\(1000000001\)栋的建筑 ...

  8. HDOJ(HDU).2159 FATE (DP 带个数限制的完全背包)

    HDOJ(HDU).2159 FATE (DP 带个数限制的完全背包) 题意分析 与普通的完全背包大同小异,区别就在于多了一个个数限制,那么在普通的完全背包的基础上,增加一维,表示个数.同时for循环 ...

  9. Lua Go R HEXO Kotlin 简单介绍

    Lua Lua使用C编写而成的脚本语言.同为脚本语言的Python拥有庞大的类库工具包,定位于独立开发,Lua极度精简化,没有提供太多功能包,必须与C.C++等语言混合使用,目的是为了快速并动态的嵌入 ...

  10. spring 整合 redis 单机版

    增加spring配置文件: application-jedis.xml <?xml version="1.0" encoding="UTF-8"?> ...