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

以下为四个函数的源码分析;

  1. /**
  2. * skb_put - add data to a buffer
  3. * @skb: buffer to use
  4. * @len: amount of data to add
  5. *
  6. * This function extends the used data area of the buffer. If this would
  7. * exceed the total buffer size the kernel will panic. A pointer to the
  8. * first byte of the extra data is returned.
  9. */
  10. /*
  11. 向skb尾部添加数据
  12. */
  13. unsigned char *skb_put(struct sk_buff *skb, unsigned int len)
  14. {
  15. /* 获取当前skb->tail */
  16. unsigned char *tmp = skb_tail_pointer(skb);
  17.  
  18. /* 要求skb数据区必须为线性 */
  19. SKB_LINEAR_ASSERT(skb);
  20.  
  21. /* skb尾部增加len字节 */
  22. skb->tail += len;
  23. /* skb数据总长度增加len字节 */
  24. skb->len += len;
  25.  
  26. /* 如果增加之后的tail > end ,则panic */
  27. if (unlikely(skb->tail > skb->end))
  28. skb_over_panic(skb, len, __builtin_return_address());
  29.  
  30. //返回添加数据的第一个字节位置
  31. return tmp;
  32. }
  1. /**
  2. * skb_push - add data to the start of a buffer
  3. * @skb: buffer to use
  4. * @len: amount of data to add
  5. *
  6. * This function extends the used data area of the buffer at the buffer
  7. * start. If this would exceed the total buffer headroom the kernel will
  8. * panic. A pointer to the first byte of the extra data is returned.
  9. */
  10. /*
  11. 向skb数据区头部添加数据
  12. */
  13. unsigned char *skb_push(struct sk_buff *skb, unsigned int len)
  14. {
  15. /* 数据区data指针前移len字节 */
  16. skb->data -= len;
  17. /* 数据总长度增加len字节 */
  18. skb->len += len;
  19.  
  20. /* 添加数据长度溢出过header ,panic*/
  21. if (unlikely(skb->data<skb->head))
  22. skb_under_panic(skb, len, __builtin_return_address());
  23.  
  24. /* 返回新的data指针 */
  25. return skb->data;
  26. }
  1. /**
  2. * skb_pull - remove data from the start of a buffer
  3. * @skb: buffer to use
  4. * @len: amount of data to remove
  5. *
  6. * This function removes data from the start of a buffer, returning
  7. * the memory to the headroom. A pointer to the next data in the buffer
  8. * is returned. Once the data has been pulled future pushes will overwrite
  9. * the old data.
  10. */
  11. /*
  12. 从数据区头部移除数据
  13. */
  14. unsigned char *skb_pull(struct sk_buff *skb, unsigned int len)
  15. {
  16. return skb_pull_inline(skb, len);
  17. }
  1. /* 根据移除数据长度判断函数调用 */
  2. static inline unsigned char *skb_pull_inline(struct sk_buff *skb, unsigned int len)
  3. {
  4. /*
  5. 移除长度> skb数据总长度,返回NULL
  6. 否则,继续调用_skb_pull函数
  7. */
  8. return unlikely(len > skb->len) ? NULL : __skb_pull(skb, len);
  9. }
  1. /* 从skb数据区头部移除数据 */
  2. static inline unsigned char *__skb_pull(struct sk_buff *skb, unsigned int len)
  3. {
  4. /* 数据总长度减去len字节 */
  5. skb->len -= len;
  6. /* 数据总长度是否有异常 */
  7. BUG_ON(skb->len < skb->data_len);
  8.  
  9. /*
  10. data指针移动len字节
  11. 返回移除之后新的data指针
  12. */
  13. return skb->data += len;
  14. }
  1. /*
  2. 保留头部空间,只能对空的skb使用
  3. */
  4. static inline void skb_reserve(struct sk_buff *skb, int len)
  5. {
  6. /* 数据区data指针增加len字节*/
  7. skb->data += len;
  8. /* 数据区tail指针增加len字节 */
  9. skb->tail += len;
  10. }

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. Gradle sync failed: Failed to find Build Tools revision 26.0.2的解决办法

    说明在android studio中没有 build tools 的26.0.2的版本,你确认一下,是否是这样: 点击==>android studio的菜单栏中Tools==>andro ...

  2. js 关键字 in 判断 一个属性或方法是否属于一个对象

    判断对象是否为数组/对象的元素/属性: 格式:(变量 in 对象)......注意,,, 当“对象”为数组时,“变量”指的是数组的“索引”: 当“对象”为对象是,“变量”指的是对象的“属性”. 判断 ...

  3. WPF 分页控件的实现 -用户控件

    效果图:

  4. RT-thread 设备驱动组件之IIC总线设备

    本文主要介绍RT-thread中IIC总线设备驱动,涉及到的主要文件有:驱动框架文件(i2c_core.c,i2c_dev.c,i2c-bit-ops.c,i2c_dev.h,i2c.h):底层硬件驱 ...

  5. SP263 PERIOD - Period

    题目描述 For each prefix of a given string S with N characters (each character has an ASCII code between ...

  6. 详细图解jQuery对象,以及如何扩展jQuery插件

    详细图解jQuery对象,以及如何扩展jQuery插件 早几年学习前端,大家都非常热衷于研究jQuery源码.我还记得当初从jQuery源码中学到一星半点应用技巧的时候常会有一种发自内心的惊叹,“原来 ...

  7. iphone手机与PC蓝牙出现感叹号且无法修复解决方案

    解决方案如下: 1.需要下载Windows Mobile 6.5 的驱动 drvupdate-amd64.exe ,下载需要正版验证,手动安装驱动,具体步骤Google 2. 如果在BlueTooth ...

  8. [洛谷P3261][JLOI2015]城池攻占

    题目大意:有$n$个点的树,第$i$个节点有一个权值$h_i$,$m$个骑士,第$i$个骑士攻击力为$v_i$,一个骑士可以把从它开始的连续的父亲中比它小的节点攻破,攻破一个节点可以把攻击力加或乘一个 ...

  9. [CQOI2009]跳舞 网络流

    题面:[CQOI2009]跳舞 题解: 首先最大时间不好求,而且数据范围很小,所以我们可以先二分一个最大时间,然后就只需要判断是否可行即可. 因此我们每二分一个mid,对于每个女生,连s ---> ...

  10. BZOJ3172 [Tjoi2013]单词 【AC自动机】

    3172: [Tjoi2013]单词 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 4293  Solved: 2083 [Submit][Stat ...