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 表示永久缓存,否则为缓存有效期 */ ...
随机推荐
- Gradle sync failed: Failed to find Build Tools revision 26.0.2的解决办法
说明在android studio中没有 build tools 的26.0.2的版本,你确认一下,是否是这样: 点击==>android studio的菜单栏中Tools==>andro ...
- js 关键字 in 判断 一个属性或方法是否属于一个对象
判断对象是否为数组/对象的元素/属性: 格式:(变量 in 对象)......注意,,, 当“对象”为数组时,“变量”指的是数组的“索引”: 当“对象”为对象是,“变量”指的是对象的“属性”. 判断 ...
- WPF 分页控件的实现 -用户控件
效果图:
- RT-thread 设备驱动组件之IIC总线设备
本文主要介绍RT-thread中IIC总线设备驱动,涉及到的主要文件有:驱动框架文件(i2c_core.c,i2c_dev.c,i2c-bit-ops.c,i2c_dev.h,i2c.h):底层硬件驱 ...
- SP263 PERIOD - Period
题目描述 For each prefix of a given string S with N characters (each character has an ASCII code between ...
- 详细图解jQuery对象,以及如何扩展jQuery插件
详细图解jQuery对象,以及如何扩展jQuery插件 早几年学习前端,大家都非常热衷于研究jQuery源码.我还记得当初从jQuery源码中学到一星半点应用技巧的时候常会有一种发自内心的惊叹,“原来 ...
- iphone手机与PC蓝牙出现感叹号且无法修复解决方案
解决方案如下: 1.需要下载Windows Mobile 6.5 的驱动 drvupdate-amd64.exe ,下载需要正版验证,手动安装驱动,具体步骤Google 2. 如果在BlueTooth ...
- [洛谷P3261][JLOI2015]城池攻占
题目大意:有$n$个点的树,第$i$个节点有一个权值$h_i$,$m$个骑士,第$i$个骑士攻击力为$v_i$,一个骑士可以把从它开始的连续的父亲中比它小的节点攻破,攻破一个节点可以把攻击力加或乘一个 ...
- [CQOI2009]跳舞 网络流
题面:[CQOI2009]跳舞 题解: 首先最大时间不好求,而且数据范围很小,所以我们可以先二分一个最大时间,然后就只需要判断是否可行即可. 因此我们每二分一个mid,对于每个女生,连s ---> ...
- BZOJ3172 [Tjoi2013]单词 【AC自动机】
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 4293 Solved: 2083 [Submit][Stat ...