全球最实用的IT互联网信息网站!

AI人工智能P2P分享&下载搜索网页发布信息网站地图

当前位置:诺佳网 > 电子/半导体 > 嵌入式技术 >

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

时间:2023-07-30 16:48

人气:

作者:admin

标签: 内存 

导读:2、非线性区域 在1、中,可以看到每张sk_buff的图: 在end指针紧挨着一个非线性区域 ; 在struct sk_buff中没有指向skb_shared_info结构的指针,利用end指针,,可以用 skb_shinfo宏 来访问: #de...

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中关于长度的两个字段
  1. len字段:无分片的报文,数据报文的大小
  2. 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的分析、实操等将在以后的文章中梳理。

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信