DPDK基础组件一(mbuf、ring、pktmbuf_pool)

一、rte_mbuf

此部分转自:https://zhuanlan.zhihu.com/p/616314276

1.mbuf结构

mbuf是报文中的描素的结构体,是整个转发过程中最核心的数据结构之一。主要针对于mbuf的常用API与基本原理做一个简单的介绍。

  1. mbuf:报文内存存储结构,存储在mempool中
  2. mempool:使用环形缓冲区保存空闲对象
struct rte_mbuf {
	void *buf_addr; /**< Virtual address of segment buffer. */
	uint16_t data_off;
	uint32_t pkt_len; /**< Total pkt len: sum of all segments. */
	uint16_t data_len; /**< Amount of data in segment buffer. */
	uint16_t buf_len
	......
}

 rte_mbuf 结构通常承载网络数据包缓冲区,但它实际上可以是任何数据(控制数据、事件……)。 rte_mbuf 头结构保持尽可能小,目前只使用两个缓存行,最常用的字段位于两个缓存行中的第一个。原则上将基础性、频繁访问的数据放在第一个Cache Line字节,将功能性扩展的数据放在第二个Cache Line字节。

Mbuf报头包含包处理所需的所有数据,对于单个Mbuf存发不下的巨型帧(JumboFrame),Mbuf还有指向下一个Mbuf结构的指针来形成帧链表结构。所有应用都应该使用Mbuf结构来传输网络帧。

对于网络帧的封装和处理有两种方式:
1.将元数据嵌入单个内存缓冲区中,该结构后跟固定大小的数据包数据区域。
2.为元数据结构和数据包数据使用单独的内存缓冲区。

前者的好处是高效,它只需要一个指令来分配/释放数据包的整个内存,缺点是因为缓存长度固定而网络帧的大小不一,大部分帧只能填0(padding)的方式填满整个缓存,较为浪费内存空间。后者的优先相对灵活自由,数据帧的大小可以任意,同时对元数据和网络帧的缓存可以分开申请及释放,当然了缺点就是效率低。无法保证数据存储存在一个Cache Line中,可能造成Hit Miss。为了高效,DPDK选择了第一种方法。网络帧的元数据的一部分内容由DPDK网卡驱动写入。这些内容包含VLAN标签、RSS哈希值、网络帧入口端口号以及巨型帧所占的mbuf个数等等。对于巨型帧,网络帧元数据仅出现在第一个帧的Mbuf结构中,其他的帧该信息为空。

headroom: 保留区域headroom:一般用来存放用户自己针对于mbuf的一些描述信息,
一般保留给用户使用,可以通过修改mbuf头文件,来实现headroom的大小;
 data_off 的默认值就是mbuf的headroom的大小;默认就是128。
如果要定义超过这个范围的私有字段,请自行修改 RTE_PKTMBUF_HEADROOM
数据字段:data。 
data区域一般指的是地址区间在 buf_addr + data_off 到 buf_add + data_off + data_len 即,
data_len就是这段数据的长短,这个data_len一般都是通过mbuf的几个基本操作,
或者通过赋值来实现的。
tailroom: 一般指的是,data_len还未包含的东西。默认其实data_len是0。
所以说默认来说tailroom应该是占了很大的空间的;

 报文数据永远是存放在data中的

如上图,包含了一个Mbuf的基本组成,其中Mbuf头部大小为两个Cache Line,在Mbuf头部和实际的数据包之间还有一段控制头信息(headroom),用来存储和系统中其他实体交互的信息,比如控制信息、帧内容、事件等,headroom的长度由RTE_PKTMBUF_HEADROOM控制。

headroom的起始地址保存在Mbuf的buf_addr 指针中,数据帧的起始指针可以通过调用rte_pktmbuf_mtod获得。

 

数据帧的长度可通过调用rte_pktmbuf_pktlen(Mbuf)或者rte_pktmbuf_datalen(Mbuf)获得,但这只限于单帧Mbuf。巨型帧的单帧长度只由rte_pktmbuf_datalen(Mbuf)返回,而rte_pktmbuf_pktlen(Mbuf)用于访问巨型帧所有帧长度的总和,如图上所示。

除此之外Mbuf提供可操作的API有,具体的使用方法可以参考(mbuf/rte_mbuf.h)的注释内容和用法以及使用手册:

rte_pktmbuf_datalen:获得帧数据长度
rte_pktmbuf_mtod:获得指向数据的指针
rte_pktmbuf_prepend:在帧数据前插入一段内容

m->data_off = (uint16_t)(m->data_off - len);
m->data_len = (uint16_t)(m->data_len + len);
m->pkt_len  = (m->pkt_len + len);


rte_pktmbuf_append:在帧数据后插入一段内容

tail = (char *)m_last->buf_addr + m_last->data_off + m_last->data_len;
m_last->data_len = (uint16_t)(m_last->data_len + len);
m->pkt_len  = (m->pkt_len + len);


rte_pktmbuf_adj:在帧数据前删除一段内容

m->data_len = (uint16_t)(m->data_len - len);
m->data_off = (uint16_t)(m->data_off + len);
m->pkt_len  = (m->pkt_len - len);


rte_pktmbuf_trim:在帧数据后截掉一段内容

m_last->data_len = (uint16_t)(m_last->data_len - len);
m->pkt_len  = (m->pkt_len - 

相关推荐

  1. dpdk-ipsec-secgw 【dpdk20.11】

    2024-06-06 05:02:03       32 阅读
  2. DPDKdpdk测试发udp包

    2024-06-06 05:02:03       42 阅读
  3. dpdk】Getting Started Guide for Linux DPDK

    2024-06-06 05:02:03       32 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-06 05:02:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-06 05:02:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-06 05:02:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-06 05:02:03       18 阅读

热门阅读

  1. 文档智能开源软件

    2024-06-06 05:02:03       7 阅读
  2. 常用设计模式

    2024-06-06 05:02:03       7 阅读
  3. 层出不穷的大模型产品,你怎么选?【模板】

    2024-06-06 05:02:03       12 阅读
  4. HarmonyOs开发:关系型数据库封装之增删改查

    2024-06-06 05:02:03       8 阅读
  5. Vue基础(3)监听数据

    2024-06-06 05:02:03       8 阅读
  6. php fpdf使用记录

    2024-06-06 05:02:03       8 阅读
  7. 力扣1438.绝对差不超过限制的最长连续子数组

    2024-06-06 05:02:03       10 阅读
  8. 【面试题-011】如何设计一个三高系统

    2024-06-06 05:02:03       9 阅读
  9. 动态规划详细解释

    2024-06-06 05:02:03       9 阅读
  10. PHP编程入门:揭开Web开发的神秘面纱

    2024-06-06 05:02:03       8 阅读
  11. Android音频焦点

    2024-06-06 05:02:03       6 阅读
  12. go模拟经典面试题

    2024-06-06 05:02:03       9 阅读
  13. foreach、for in和for of之间区别?

    2024-06-06 05:02:03       9 阅读