在wlan驱动中,数据读取写入是通过sk_buff这个结构体,而sk_buff结构主要作用是包含接收的缓冲数据,和它的包头信息。

如下是sk_buff的主要结构成员:

  1. struct sk_buff {
  2. ...
  3. unsigned char *head;
  4. unsigned char *data;
  5. unsigned char *tail;
  6. unsigned char *end;
  7. ...
  8. };

当然,sk_buff还包含一些链表的东西,在此处并不做解析。在以上结构体中:

  • head:报文缓冲区的头;
  • data:数据的头指针;
  • tail:数据的尾指针;
  • end :报文缓冲区的尾部。

如图所示,

分别有三个空间:head room、packet data、tail room。其中packet data是数据所在区包括数据的包头,head room是数据头部增长的预留空间、tail room是尾部增加的空间。预留头部使用skb_reserve(skb, header_len);函数,尾部增加使用skb_put(),头部增长使用skb_push()

以下图是调用分配空间函数,即初始化函数alloc_skb(len, GFP_KERNEL)的样子:

可以看到,headdatatail都指向了缓冲区的起始,而end指向结束。这个SKB的数据长度为0,不包含任何数据。

接着调用了skb_reserve(skb, header_len)预留了头部数据,如图所示:

3.4.4  数据预留和对齐

数据预留和对齐主要由skb_reserve()、skb_put()、skb_push()以及skb_pull()这几个函数来完成。

1.skb_reserve()

skb_reserve()在数据缓存区头部预留一定的空间,通常被用来在数据缓存区中插入协议首部或者在某个边界上对齐。它并没有把数据移出或移入数据缓存区,而只是简单地更新了数据缓存区的两个指针-分别指向负载起始和结尾的data和tail指针,图3-15 展示了调用skb_reserve()前后这两个指针的变化。

请注意:skb_reserve()只能用于空的SKB,通常会在分配SKB之后就调用该函数,此时data和tail指针还一同指向数据区的起始位置,如图3-15a所示。例如,某个以太网设备驱动的接收函数,在分配SKB之后,向数据缓存区填充数据之前,会有这样的一条语句skb_reserve(skb, 2),这是因为以太网头长度为14B,再加上2B就正好16字节边界对齐,所以大多数以太网设备都会在数据包之前保留2B。

当SKB在协议栈中向下传递时,每一层协议都把skb->data指针向上移动,然后复制本层首部,同时更新skb->len。这些操作都使用图3-15 中所示的函数完成。

图3-15  在接收过程中使用skb_reserve()
a) 空的SKB  b) 头部预留2个字节  c) 复制以太网帧到SKB

2.skb_push()

skb_push()在数据缓存区的前头加入一块数据,与skb_reserve()类似,也并没有真正向数据缓存区中添加数据,而只是移动数据缓存区的头指针data和尾指针tail。数据由其他函数复制到数据缓存区中。

函数执行步骤如下:

1)当TCP发送数据时,会根据一些条件,如TCP最大分段长度MSS、是否支持聚合分散I/O等,分配一个SKB。

2)TCP需在数据缓存区的头部预留足够的空间,用来填充各层首部。MAX_TCP_HEADER是各层首部长度的总和,它考虑了最坏的情况:由于TCP层不知道将要用哪个接口发送包,它为每一层预留了最大的首部长度,甚至还考虑了出现多个IP首部的可能性,因为在内核编译支持IP over IP的情况下,会遇到多个IP首部。

3)把TCP负载复制到数据缓存区。需要注意的是,图3-16 只是一个例子,TCP负载可能会被组织成其他形式,例如分片,在后续章节中将会看到一个分片的数据缓存区是什么样的。

图3-16  TCP层向链路层传递时数据的填充过程
a) 空的SKB  b) 在SKB的头部预留足够的空间  c) 复制TCP数据  
d) 添加TCP首部  e) 添加IP首部  f) 添加以太网帧首部

4)TCP层添加TCP首部。

5)SKB传递到IP层,IP层为数据包添加IP首部。

6)SKB传递到链路层,链路层为数据包添加链路层首部。

3.skb_put()

skb_put()修改指向数据区末尾的指针tail,使之往下移len字节,即使数据区向下扩大len字节,并更新数据区长度len。调用skb_put()前后,SKB结构变化如图3-17所示。

图3-17  skb_put()示意
a) 调用前  b) 调用后

4.skb_pull()

skb_pull()通过将data指针往下移动,在数据区首部忽略len字节长度的数据,通常用于接收到数据包后在各层间由下往上传递时,上层忽略下层的首部。调用skb_pull()前后,SKB结构变化如图3-18所示。

图3-18  skb_pull()示意
a) 调用前  b) 调用后

以上为整合内容 原文链接:http://simpleyyt.github.io/linux/2014/04/16/sk_buff_analysis/  和 http://book.51cto.com/art/201206/345043.htm

sk_buff结构和函数分析相关推荐

  1. linux skb 结构和相关操作函数分析

    sk_buff是Linux网络中最核心的结构体,它用来管理和控制接收或发送数据包的信息.各层协议都依赖于sk_buff而存在.内核中sk_buff结构体在各层协议之间传输不是用拷贝sk_buff结构体 ...

  2. Linux内核--网络协议栈深入分析(二)--sk_buff的操作函数

    本文分析基于Linux Kernel 3.2.1 原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7972647 更多请查看网络栈分析 ...

  3. 【原创】【专栏】《Linux设备驱动程序》--- LDD3源码目录结构和源码分析经典链接

    http://blog.csdn.net/geng823/article/details/37567557 [原创][专栏]<Linux设备驱动程序>--- LDD3源码目录结构和源码分析 ...

  4. 【Linux 内核 内存管理】虚拟地址空间布局架构 ③ ( 内存描述符 mm_struct 结构体成员分析 | mmap | mm_rb | task_size | pgd | mm_users )

    文章目录 一.mm_struct 结构体成员分析 1.mmap 成员 2.mm_rb 成员 3.get_unmapped_area 函数指针 4.task_size 成员 5.pgd 成员 6.mm_ ...

  5. Windows事件等待学习笔记(三)—— WaitForSingleObject函数分析

    Windows事件等待学习笔记(三)-- WaitForSingleObject函数分析 要点回顾 WaitForSingleObject NtWaitForSingleObject KeWaitFo ...

  6. 网络协议栈深入分析(二)--sk_buff的操作函数

    1.alloc_skb()函数 该函数的作用是在上层协议要发送数据包的时候或网络设备准备接收数据包的时候会调用alloc_skb()函数分配sk_buff结构体,需要释放时调用kfree_skb()函 ...

  7. ucos任务调度函数 OSSched()函数分析 ,任务切换函数

    OS_Sched()分析 在uc/os中总是运行优先级最高的就绪任务,确定哪个任务优先级最高,该由哪个优先级人物运行了,这一工作是由任务调度器完成的,(而具体的任务切换,是任务调度器在调用其他函数来完 ...

  8. CorelDraw插件开发-文字功能-文本分列-创建文本-函数分析-Cdr插件开发教程(二)

    文章目录 1.函数-sub_2381FDE0-进程资源锁 2.大致分析了一下函数结构 3.动态调试 4.上一级函数分析 5.VBA宏功能 6.总结 逆向代码的学习需要耐心,往往高手的代码会用到你想不到 ...

  9. struct sk_buff结构体详解

    struct sk_buff是linux网络系统中的核心结构体,linux网络中的所有数据包的封装以及解封装都是在这个结构体的基础上进行. 1 2 3 4 5 6 7 8 9 10 11 12 13 ...

最新文章

  1. 二、python基础(列表、元组、字符串、集合、字典、文件操作,函数基本语法及特性)...
  2. 入门SAP PP的学习流程
  3. 解决执行 df -h 卡住,yum和rpm都无法安装软件问题
  4. hive启动时出现javax.jdo.JDODataStoreException: Error executing SQL query
  5. ffmpeg开发指南(使用 libavformat 和 libavcodec)
  6. android genymotion模拟器怎么使用以及和google提供的模拟器性能对比
  7. 设计一个Enum Class
  8. 买车,给点建议和意见
  9. MySQL数据监控案例_zabbix 监控多实例mysql
  10. jquery api的整体解读
  11. java数据结构 mobi_数据结构:Java语言描述(第2版) pdf epub mobi txt 下载
  12. oppo r11s鸿蒙固件,OPPO R11s官方出厂rom系统刷机包下载_卡刷升级包降级回退包
  13. 云计算 | 浅议云计算发展趋势
  14. Linux·触摸屏驱动实例
  15. tftp刷路由器 linux,路由器TFTP配置的四个步骤
  16. Firebox比较常用的插件
  17. 申报绿色工厂对企业有什么好处
  18. nrf52 iic使用
  19. 少年碎碎念:《追飞机的人》
  20. 阻燃电缆ZR,ZA,ZB,ZC分别是什么意思,有什么区别

热门文章

  1. 科研、科技成果的常见形式和分类有哪些?
  2. 兰海说成长|让孩子端正态度,你也许用错了方法
  3. 斑马,跑在互联网上的汽车
  4. SOEM(Simle Open EtherCAT Master)1.3.1
  5. 实验二 人机交互接口实验
  6. android切换账号登录界面,华为游戏切换安卓账号登陆界面
  7. Visio 画流程图
  8. GripSeal格雷希尔快速密封连接器 管内径密封测试工具 内涨式充堵头
  9. 李世民是千古明君还是卑污小人?
  10. 2021年煤炭生产经营单位(安全生产管理人员)考试资料及考试技巧