0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

麦辣鸡腿堡 来源:技术简说 作者:董旭 2023-07-30 16:48 次阅读

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的分析、实操等将在以后的文章中梳理。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5068

    文章

    19008

    浏览量

    302995
  • Linux
    +关注

    关注

    87

    文章

    11219

    浏览量

    208879
  • 内存
    +关注

    关注

    8

    文章

    2996

    浏览量

    73870
收藏 人收藏

    评论

    相关推荐

    Linux sk_buff四大指针与相关操作

     在以上文章中,没有分析过Linux内核网络关键的数据结构-套接字数据缓存struct sk_buff,本文将第一次分享到sk_buff,但鉴于其在内核网络中一些复杂情况,本次只简单介绍sk_
    发表于 10-13 17:23 4533次阅读
    Linux <b class='flag-5'>sk_buff</b>四大指针与<b class='flag-5'>相关</b><b class='flag-5'>操作</b>

    使用rt_malloc申请内存空间失败,显示没有内存怎么解决?

    + net_server + crclib) 的情况下,还有2个堆栈空间2048的应用线程,使用rt_malloc申请内存空间失败,显示没有内存。经测试,只能申请1200bytes
    发表于 07-04 08:10

    Linux内存点滴 用户进程内存空间

    , Data+Stack size (kb)nFLT, Page Fault countnDRT, Dirty Pages count尽管有注释,但依然感觉有些晦涩,不知所指何意?进程内存空间正在运行的程序,叫进程。每个
    发表于 08-14 16:23

    嵌入式linux TCP/IP协议栈概述

    ;unsigned char *head,//缓存区的头指针*data;//有效数据头指针...};sk_buff相关操作函数
    发表于 12-07 10:05

    DM8127使用SWOSD_TI_alloc()分配内存空间怎么加大?

    DM8127使用SWOSD_TI_alloc()分配内存空间不够,请问在什么文件里怎样修改加大内存空间???
    发表于 04-16 10:56

    stm32 使用u*** host库占用内存空间很大!!!

    如何解决stm32 使用u*** host库占用内存空间很大的问题呢???
    发表于 01-22 16:44

    ARM32 Linux的内存布局

    看我们实际上内存布局是怎么样的?Linux内核在启动时,会打印出内核内存空间布局图,下面是ARM IMX6平台打印出来的内存空间布局图这部
    发表于 04-24 14:20

    RTThread的动态内存空间该如何去分配呢

    配的Heap_Size,而使用rt_malloc申请到的则是RTT分配的空间然后有以下几个问题1、如果是动态创建线程,那线程中的局部变量是位于RTT分配的动态内存空间中还是位于栈空间中?2、如果使用一些第
    发表于 08-31 14:34

    freertos怎么释放任务的内存空间

    freertos怎么释放任务的内存空间
    发表于 10-12 07:20

    Linux网络设备驱动程序

    当要发送数据包的时候,内核必须建立一个包含传输数据的sk_buff,然后将sk_buff交给下层,各层在sk_buff递交给下一层,各层在sk_buff中添加不同的协议贞头,直到交给网
    发表于 05-10 11:15 1813次阅读

    如何让你的手机省出内存空间

    大家都知道,手机使用久了就会变得很卡顿,除了手机本身“老化”之外,还有一个重要的原因就是内存堆积的太多了。事实上占用手机内存的无非就是照片、视频、微信等等,如果好好处理一下这几个方面的问题,相信你的手机一定能省出不少内存空间,下
    的头像 发表于 02-13 14:07 4195次阅读

    网卡的Ring Buffer详解

    DMA 将 NIC 接收的数据包逐个写入 sk_buff ,一个数据包可能占用多个 sk_buff , sk_buff 读写顺序遵循FIFO(先入先出)原则。
    的头像 发表于 03-17 14:25 1478次阅读

    网卡的Ring Buffer详解

    DMA 将 NIC 接收的数据包逐个写入 sk_buff ,一个数据包可能占用多个 sk_buff , sk_buff 读写顺序遵循FIFO(先入先出)原则。
    的头像 发表于 04-04 09:15 1110次阅读

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

    :报文数据,保存了实际网络中传输的数据,在内核协议栈起承上启下的作用,也有很多值得关注的sk_buff操作。 1、sk_buff四大指针与相关操作
    的头像 发表于 07-30 16:43 1161次阅读
    <b class='flag-5'>sk_buff</b><b class='flag-5'>内存空间布局</b><b class='flag-5'>情况</b>与<b class='flag-5'>相关</b><b class='flag-5'>操作</b>(一)

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

    操作tailroom中用户数据块区域:skb_put用于修改指向数据区末尾的指针tail: void *skb_put( struct sk_buff *skb, unsigned int len
    的头像 发表于 07-30 16:47 714次阅读
    <b class='flag-5'>sk_buff</b><b class='flag-5'>内存空间布局</b><b class='flag-5'>情况</b>与<b class='flag-5'>相关</b><b class='flag-5'>操作</b>(二)