sk_buff内存空间布局情况与相关操作(三)

2、非线性区域
在1、中,可以看到每张sk_buff的图: 在end指针紧挨着一个非线性区域 ;
在struct sk_buff中没有指向skb_shared_info结构的指针,利用end指针,,可以用skb_shinfo宏来访问:
#define skb_shinfo(skb) ((struct skb_shared_info *)(skb_end_pointer(skb)))其中skb_end_pointer函数如下,返回end指针
static inline unsigned char *skb_end_pointer(const struct sk_buff *skb){ return skb- >end;}具体地,struct skb_shared_info如下:
struct skb_shared_info { __u8 __unused; __u8 meta_len; //数组frags包含的元素个数 __u8 nr_frags; __u8 tx_flags; unsigned short gso_size; /* warning: this field is not always filled in (ufo)! */ unsigned short gso_segs; struct sk_buff *frag_list; struct skb_shared_hwtstamps hwtstamps; unsigned int gso_type; u32 tskey; /* * warning : all fields before dataref are cleared in __alloc_skb() */ //结构skb_shared_info 的引用计数器 atomic_t dataref; /* intermediate layers must ensure that destructor_arg * remains valid until skb destructor */ void * destructor_arg; /* must be last field, see pskb_expand_head() */ skb_frag_t frags[max_skb_frags];};其中skb_frag_t如下:
typedef struct skb_frag_struct skb_frag_t;struct skb_frag_struct { struct { //指向文件系统缓存页的指针 struct page *p; } page;#if (bits_per_long > 32) || (page_size >= 65536) //数据起始地址在文件系统缓存页中的偏移 __u32 page_offset; //数据在文件系统缓存页中使用的长度 __u32 size;#else __u16 page_offset; __u16 size;#endif};nr_frags,frags,frag_list与ip分片存储有关。
frag_list的用法:
用于在接收分组后链接多个分片,组成一个完整的ip数据报在udp数据报输出中,将待分片的skb链接到第一个skb中,然后在输出过程中能够快速的分片用于存放fraglist类型的聚合分散i/o数据包判断是否存在非线性缓冲区:
先说明struct sk_buff中关于长度的两个字段len字段:无分片的报文,数据报文的大小data_len字段:存在分散报文,data_len表示分片的部分大小如下所示,没有开启分片的报文len = x,data_len = 0:
如下所示在linux内核中,使用skb_is_nonlinear函数判断是否存在分片,即通过判断data_len的大小是否为0:
static inline bool skb_is_nonlinear(const struct sk_buff *skb){ return skb- >data_len;}在没有开启分片的报文中,数据包长度在struct sk_buff中为len字段的大小,即data到tail的长度,nf_frags为0,frag_list为null。普通聚合分散i/o的报文:
采用聚合分散i/o的报文, frag_list为 null,nf_frags不等于0 ,说明这不是一个普通的分片,而是聚合分散i/o的报文。
如下所示:
nr_frags为2,而frag_list为null,说明这不是普通的分片,而是聚合分散i/o分片,数量为2,这两个分片指向同一物理分页,各自在分页中的偏移和长度分别是0/s1和s1/s2。
fraglist类型的分散聚合i/o的报文:
采用fraglist类型的分散聚合i/o报文, ** frag_list不为null,nf_frags等于0 ,** 数据长度len为x+s1,data_len为s1,
以上从struct sk_buff的四大指针以及操作、非线性区域对套接字缓存(socket buffer)进行分析,更多sk_buff的分析、实操等将在以后的文章中梳理。

天马OLED显示屏助力小米手环8 Pro震撼发布
从四大领域着手,看清东芝电子布局!
忘记小米MIX全面屏的惊艳,三星s8全视双曲面屏初体验
6G已经发展到什么地步了?
如何聪明地防止电源正负极接反?
sk_buff内存空间布局情况与相关操作(三)
《数字孪生城市白皮书》
LLC谐振转换器在轻载条件下增益失真的注意事项
TSMC计划在印度建新晶圆厂:未来技术的重要布局?
基于区块链技术的标准链与雾联网系统平台介绍
AR初创公司Mojo Vision获5800万美元投资,谷歌的Gradient Ventures参投 ...
荣耀亮相IFA 2022 推出全场景操作系统MagicOS
斯柯达旗下首款插电混动车型有戏吗?
FAST:基于FPGA的SDN交换机开源项目(一)
物理服务器对ai发展的应用
MOVIFIT报直流电压过高电路框图分析
弹簧的类型及其性能与应用
环境空气质量监测系统助力城市智慧化监管
详解TLB的作用及工作原理
据DCS特性制定对应的运行维护方法