1、先说一下sk_buff结构体

这个结构体是套接字的缓冲区,详细记录了一个数据包的组成,时间、网络设备、各层的首部及首部长度和数据的首尾指针。

下面是他的定义,挺长

[cpp] view plaincopy
  1. struct sk_buff {
  2. /* These two members must be first. */
  3. struct sk_buff      *next;
  4. struct sk_buff      *prev;
  5. ktime_t         tstamp;
  6. struct sock     *sk;
  7. struct net_device   *dev;
  8. /*
  9. * This is the control buffer. It is free to use for every
  10. * layer. Please put your private variables there. If you
  11. * want to keep them across layers you have to do a skb_clone()
  12. * first. This is owned by whoever has the skb queued ATM.
  13. */
  14. char            cb[48] __aligned(8);
  15. unsigned long       _skb_refdst;
  16. #ifdef CONFIG_XFRM
  17. struct  sec_path    *sp;
  18. #endif
  19. unsigned int        len,
  20. data_len;
  21. __u16           mac_len,
  22. hdr_len;
  23. union {
  24. __wsum      csum;
  25. struct {
  26. __u16   csum_start;
  27. __u16   csum_offset;
  28. };
  29. };
  30. __u32           priority;
  31. kmemcheck_bitfield_begin(flags1);
  32. __u8            local_df:1,
  33. cloned:1,
  34. ip_summed:2,
  35. nohdr:1,
  36. nfctinfo:3;
  37. __u8            pkt_type:3,
  38. fclone:2,
  39. ipvs_property:1,
  40. peeked:1,
  41. nf_trace:1;
  42. kmemcheck_bitfield_end(flags1);
  43. __be16          protocol;
  44. void            (*destructor)(struct sk_buff *skb);
  45. #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
  46. struct nf_conntrack *nfct;
  47. #endif
  48. #ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
  49. struct sk_buff      *nfct_reasm;
  50. #endif
  51. #ifdef CONFIG_BRIDGE_NETFILTER
  52. struct nf_bridge_info   *nf_bridge;
  53. #endif
  54. int         skb_iif;
  55. #ifdef CONFIG_NET_SCHED
  56. __u16           tc_index;   /* traffic control index */
  57. #ifdef CONFIG_NET_CLS_ACT
  58. __u16           tc_verd;    /* traffic control verdict */
  59. #endif
  60. #endif
  61. __u32           rxhash;
  62. __u16           queue_mapping;
  63. kmemcheck_bitfield_begin(flags2);
  64. #ifdef CONFIG_IPV6_NDISC_NODETYPE
  65. __u8            ndisc_nodetype:2;
  66. #endif
  67. __u8            ooo_okay:1;
  68. __u8            l4_rxhash:1;
  69. kmemcheck_bitfield_end(flags2);
  70. /* 0/13 bit hole */
  71. #ifdef CONFIG_NET_DMA
  72. dma_cookie_t        dma_cookie;
  73. #endif
  74. #ifdef CONFIG_NETWORK_SECMARK
  75. __u32           secmark;
  76. #endif
  77. union {
  78. __u32       mark;
  79. __u32       dropcount;
  80. };
  81. __u16           vlan_tci;
  82. sk_buff_data_t      transport_header;
  83. sk_buff_data_t      network_header;
  84. sk_buff_data_t      mac_header;
  85. /* These elements must be at the end, see alloc_skb() for details.  */
  86. sk_buff_data_t      tail;
  87. sk_buff_data_t      end;
  88. unsigned char       *head,
  89. *data;
  90. unsigned int        truesize;
  91. atomic_t        users;
  92. };

可以看到新版本内核中发生了很多变化,其中数据包的首部在早期版本是以union的形式定义的,例如mac_header的定义方式如下:

[cpp] view plaincopy
  1. union{
  2. struct ethhdr *ethernet;
  3. unsigned char *raw;
  4. }mac;

这里是以指针的形式给出的

[cpp] view plaincopy
  1. #ifdef NET_SKBUFF_DATA_USES_OFFSET
  2. typedef unsigned int sk_buff_data_t;
  3. #else
  4. typedef unsigned char *sk_buff_data_t;
  5. #endif

这里主要说明下后面几个后面的四个属性的含义head、data、tail、end

head是缓冲区的头指针,data是数据的起始地址,tail是数据的结束地址,end是缓冲区的结束地址。

char cb[48] __aligned(8);中的48个字节是控制字段,配合各层协议工作,为每层存储必要的控制信息。

2、sk_buff_head结构体

[cpp] view plaincopy
  1. struct sk_buff_head {
  2. /* These two members must be first. */
  3. struct sk_buff  *next;
  4. struct sk_buff  *prev;
  5. __u32       qlen;
  6. spinlock_t  lock;
  7. };

这个结构体比较简单,前面两个指针是用于和sk_buff结构串成双向链表,用于管理sk_buff双链表,qlen属性表示该链表中sk_buff的数目,lock是自旋锁。

3、skb_shared_info结构体

[cpp] view plaincopy
  1. struct skb_shared_info {
  2. unsigned short  nr_frags;
  3. unsigned short  gso_size;//尺寸
  4. /* Warning: this field is not always filled in (UFO)! */
  5. unsigned short  gso_segs;//顺序
  6. unsigned short  gso_type;
  7. __be32          ip6_frag_id;
  8. __u8        tx_flags;
  9. struct sk_buff  *frag_list;//分片的sk_buff列表
  10. struct skb_shared_hwtstamps hwtstamps;//硬件时间戳
  11. /*
  12. * Warning : all fields before dataref are cleared in __alloc_skb()
  13. */
  14. atomic_t    dataref;//使用计数
  15. /* Intermediate layers must ensure that destructor_arg
  16. * remains valid until skb destructor */
  17. void *      destructor_arg;
  18. /* must be last field, see pskb_expand_head() */
  19. skb_frag_t  frags[MAX_SKB_FRAGS];
  20. };

该类型用来管理数据包分片信息,通过宏可以表示与skb的关系

[cpp] view plaincopy
  1. #define skb_shinfo(SKB) ((struct skb_shared_info *)(skb_end_pointer(SKB)))
[cpp] view plaincopy
  1. #ifdef NET_SKBUFF_DATA_USES_OFFSET
  2. static inline unsigned char *skb_end_pointer(const struct sk_buff *skb)
  3. {
  4. return skb->head + skb->end;
  5. }
  6. #else
  7. static inline unsigned char *skb_end_pointer(const struct sk_buff *skb)
  8. {
  9. return skb->end;
  10. }
  11. #endif

可以看到如果用户没有自己使用偏移量,就是skb的end属性指针,也就是该信息存储在缓冲区之后。

下篇将看有关sk_buff的操作函数的实现。

网络协议栈深入分析(一)--与sk_buff有关的几个重要的数据结构相关推荐

  1. Linux内核--网络协议栈深入分析(一)--与sk_buff有关的几个重要的数据结构

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

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

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

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

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

  4. 网络协议栈深入分析(三)--BSD socket和传输层sock

    Linux内核中协议族有INET协议族,UNIX协议族等,我们还是以INET协议族为例. 下面是内核中的协议族声明: [cpp] view plaincopy /* Supported address ...

  5. 网络协议栈深入分析(四)--套接字内核初始化和创建过程

    1.系统初始化过程中会调用sock_init函数进行套接字的初始化,主要是进行缓存的初始化 [cpp] view plaincopy static int __init sock_init(void) ...

  6. 网络协议栈深入分析(五)--套接字的绑定、监听、连接和断开

    1.套接字的绑定 创建完套接字服务器端会在应用层使用bind函数进行套接字的绑定,这时会产生系统调用,sys_bind内核函数进行套接字. 系统调用函数的具体实现 [cpp] view plainco ...

  7. 深入浅出Linux内核网络协议栈|结构sk_buff|Iptables|Netfilter丨内核源码丨驱动开发丨内核开发丨C/C++Linux服务器开发

    深入浅出Linux内核网络协议栈 视频讲解如下,点击观看: 深入浅出Linux内核网络协议栈|结构sk C/C++Linux服务器开发高级架构师知识点精彩内容包括:C/C++,Linux,Nginx, ...

  8. linux 内核网络协议栈

    Linux网络协议栈之数据包处理过程  1前言 本来是想翻译<The journey of a packet through the linux 2.4 network stack>这篇文 ...

  9. linux内核网络协议栈--linux bridge(十九)

    1 . 前言 本文是参考附录上的资料整理而成,以帮助读者更好的理解kernel中brdige 模块代码. 2. 网桥的原理 2.1 桥接的概念 简单来说,桥接就是把一台机器上的若干个网络接口" ...

最新文章

  1. WinRM设置信任主机
  2. # cat /proc/umap/vi
  3. 自动驾驶中常用的四类机器学习算法
  4. 大一计算机课程ppt作业,大学生计算机基础作业PPT.ppt
  5. 搭建spring MVC项目
  6. Linux的段错误调试方法
  7. 小爱音箱mini系统故障怎么办_Win7系统连接小爱音箱mini的方法【图文】
  8. 【光波电子学】MATLAB仿真厄米特-高阶高斯光束以及绘制其光强分布图
  9. 大学计算机案例教程旧照片修复,「教你一招」使用自动软件修复老照片
  10. Amy Cuddy: Your body language shapes who you are
  11. 学生用计算机隐藏功能,学生计算器怎么去掉d
  12. 【软考-中级】系统集成项目管理工程师-【2信息系统集成和服务管理】
  13. 2018版 主流SDR设备横向比较
  14. 服务器图片显示小方块,高手帮忙了!!验证码跟着敲好之后 服务器打开一个小方块里面空的!在线等!!!...
  15. 手游测试员需要做什么?
  16. 操作系统实验报告(二)银行家算法
  17. 利用tldr工具再也不怕记不住Linux命令
  18. popupwindow 不抢夺焦点_不知道家里颜色怎么配?一起去翻画册吧!
  19. IPD-产品需求管理过程(2)
  20. cors实现请求跨域

热门文章

  1. linux根据进程的运行路径,停止进程
  2. 解决java无法切分字符串,.split()无效
  3. matplotlib在图像上方添加文字、标签
  4. pycharm 修改默认的注释风格(reStructuredText风格、Google风格、Numpy风格)
  5. 解决gensim报错AttributeError: type object ‘Word2Vec‘ has no attribute ‘load_word2vec_format‘
  6. Java中introduce方法_Java基础—继承
  7. 十六、在屏幕上显示时间
  8. shiro源码篇 - 疑问解答与系列总结,你值得拥有
  9. 使用cocopods安装Alamofire后各种报错
  10. HTML5为输入框添加语音输入功能