3 Packet (Mbuf) Library

news/2025/4/2 9:04:05/文章来源:https://www.cnblogs.com/Tohomson/p/18802779

Packet(MBuf)库概述:

这个库提供了分配和释放缓冲区(mbuf)的能力,DPDK 应用可以使用这些缓冲区来存储各种类型的数据,比如:

  • 网络数据包(最常见)
  • 控制信息(control data)
  • 事件(events)
  • 或其他需要临时存储的数据

这些 mbuf 缓冲区的底层是通过 Mempool 管理的,即使用 Memory Pool Library 来进行对象池化分配。

rte_mbuf 是什么?

rte_mbuf 是 DPDK 中用来表示一个 消息缓冲区(Message Buffer) 的结构体。

最常用于:承载一个网络数据包(packet)或其中的一部分(比如一帧、一段 TCP payload)

结构设计特点:

  • rte_mbuf 的结构体设计目标是:尽可能小、尽可能 cache 友好
  • 它被划分为两个 cache line,常用字段尽量放在第一个 cache line
  • 这样可以减少 CPU 访问开销,提高包处理性能

主要字段包括:

  • 指向真正数据的指针 data
  • 数据长度 data_len
  • 数据偏移 data_off
  • 指向原始 mempool 的指针 pool
  • 一些 metadata(如端口号、RSS hash、标志位)
rte_mbuf
+-----------------------------+   ← 第一 cache line(常用)
| buf_addr                    |
| data_off                   |
| data_len                   |
| pkt_len                    |
| next                       |
| port, ol_flags, hash       |
+-----------------------------+   ← 第二 cache line(不常访问)
| vlan info, timestamp, etc  |
| user metadata              |
+-----------------------------+

通俗总结:

内容
mbuf 是什么? DPDK 中的基本数据包单元,既可以是网络包,也可以是任意数据
谁来分配 mbuf? Mempool(对象池)负责分配、缓存、回收 mbuf
为什么结构要小? 减少 CPU 缓存 miss,提升包处理效率
能不能自定义? rte_mbuf 支持用户元数据区,可挂自定义字段

数据包缓冲区设计:

在设计用于存储数据包数据(包括协议头部)的结构时,DPDK 考虑了两种方案:

方法一:将元数据和数据区合并在一个内存块中

也就是:先是 rte_mbuf 结构体 → 紧接着是一段固定大小的数据区,都位于同一个内存块中。

这种方式的好处是:

  • 只需要一次分配 / 一次释放操作
  • 结构紧凑、访问高效、减少内存碎片
  • DPDK 选择了这种方式

方法二:将元数据和数据区分开存储

  • 一块内存保存 rte_mbuf 元数据
  • 另一块内存保存真正的数据包内容

这种方法虽然更灵活(元信息和数据可以独立分配),但会带来额外复杂性:

  • 两次分配和释放
  • 缓存命中率低
  • 管理复杂,不利于性能优化

DPDK 采用了第一种设计方案(合并结构)

在这种结构中,rte_mbuf 中包含:

  • 消息类型(message type)
  • 数据长度(data_len、pkt_len)
  • 数据起始偏移(data_off)
  • next 指针(用于多个 mbuf 链接成一个长包)
缓冲区链(Buffer Chaining)

有些大型数据包(如 jumbo frame)单个 mbuf 放不下,这时:

会使用多个 rte_mbuf,通过它们的 next 字段组成链表(mbuf chain)

每个 mbuf 承载数据包的一部分。

[mbuf1] --> [mbuf2] --> [mbuf3] ...

这种方式称为 scatter-gather 模式,在处理大包或硬件分段时非常重要。

数据偏移说明(RTE_PKTMBUF_HEADROOM)

每个新分配的 rte_mbuf 的数据区不是从 buffer 开头开始,而是:

data_start = buf_addr + RTE_PKTMBUF_HEADROOM

这个 预留空间(headroom) 用于:

  • 在数据包前插入额外头部(如封装、tunneling)
  • 保证数据对齐(cache aligned)
  • 避免每次移动数据造成性能开销

默认 headroom 是 128 字节(可配置)

../_images/mbuf1.svg

../_images/mbuf2.svg

3.6 元信息(Meta Information)

DPDK 中的网络驱动在接收(RX)或发送(TX)数据包时,会把一些辅助信息存入 mbuf,以便后续快速处理或 offload 给硬件。

示例信息包括:

元信息 说明
VLAN 标签信息 用于 VLAN 识别与打标
RSS hash 值 用于多核负载均衡
校验和状态标志(checksum offload) 表明硬件是否已经完成 L3/L4 校验

数据包来源端口 mb->port

该数据包链表的段数 nb_segs(mbuf 链)

如果是链式 mbuf,只有链首的 mbuf 保存这些元信息(包括 csum、RSS、port 等)

RX 方向(接收)

比如:

  • IEEE1588 时间戳
  • VLAN tag
  • L3 校验和状态

都由网卡写入 mbuf 对应字段 → 上层代码无需重复解析,提高效率。

TX 方向(发送)

你也可以主动设置 mbuf 的标志位,告诉驱动让硬件去计算某些字段(offload),比如:

标志位 含义
RTE_MBUF_F_TX_IP_CKSUM 要求硬件计算 IPv4 校验和
RTE_MBUF_F_TX_TCP_CKSUM 要求硬件计算 TCP 校验和
RTE_MBUF_F_TX_UDP_CKSUM 要求硬件计算 UDP 校验和
RTE_MBUF_F_TX_TCP_SEG 要求硬件做 TCP 分段(TSO)
RTE_MBUF_F_TX_OUTER_IP_CKSUM 要求硬件计算外层 IPv4 封装的校验和(VXLAN 场景)

VXLAN 封装 TCP 包的 Offload 配置示例:

下面这些例子展示如何设置 mbuf->ol_flagsmbuf->l2_len, l3_len, outer_l2_len 等字段来控制 offload 行为

动态字段与标志位(Dynamic Fields and Flags)

由于 rte_mbuf 的结构大小是有限的(只有两个 cache line),但现实中协议场景非常多,无法为所有协议预留字段,因此 DPDK 提供了一种机制:动态扩展空间

动态字段(Dynamic Field):

  • 是 mbuf 结构中一个注册的 命名字段区域
  • 你可以使用 rte_mbuf_dynfield_register() 来分配
  • 用于保存一些自定义的信息,如:
    • Q-in-Q metadata
    • PTP 时间戳
    • 模块扩展标记

动态标志位(Dynamic Flag):

  • ol_flags 字段中的 某一位
  • 你可以用 rte_mbuf_dynflag_register() 注册一个新的功能标志
  • 之后可以在 ol_flags 中设置或检查这个 flag

限制:

  • 一旦注册后,动态字段/标志不能取消注册
  • 每次注册都要求你指定大小、对齐方式(最小 1 字节)
  • 多个库/模块可以独立使用,不冲突

通俗总结

说明
mbuf 支持哪些元信息? VLAN、hash、校验和状态、端口号、段数
硬件可以帮你做什么? 计算 IP/TCP/UDP 校验和、TSO 分段、VXLAN 封装校验等
你需要设置什么? ol_flags + l2_len / l3_len / outer_l2_len
动态扩展怎么办? rte_mbuf_dynfield_register() / dynflag_register() 添加自定义字段和标志

rte_mbuf 是高性能、硬件友好、可扩展的数据结构,既能记录丰富的协议信息,也支持灵活 offload 配置,且可通过动态字段实现模块间扩展与解耦。

直接与间接缓冲区(Direct and Indirect Buffers)

什么是 直接缓冲区(Direct Buffer)

  • 一个 独立完整rte_mbuf,其 buf_addr 和数据完全属于它自己。
  • 正常分配的 rte_mbuf 都是 Direct 的。
什么是 间接缓冲区(Indirect Buffer)
  • 表面上是个 rte_mbuf,但它的数据指针(buf_addrdata_off指向另一个 Direct mbuf 的数据区域
  • 自己不持有数据,只是引用别人的数据。

间接缓冲区非常适合以下场景:

场景 问题 使用间接缓冲区的优势
数据包复制 多个模块需要访问同一份数据 零拷贝复用数据,节省内存
数据包分片(如 GSO) 一个包分成多个段 每个间接 mbuf 指向 Direct 的不同片段
转发分支 同一个包要发给多个目的地 创建多个 indirect clone,无需拷贝
//创建间接缓冲区
rte_pktmbuf_attach(indirect_mbuf, direct_mbuf);
//解除引用
rte_pktmbuf_detach(indirect_mbuf);
//推荐使用
struct rte_mbuf *clone = rte_pktmbuf_clone(original, clone_pool);

注意事项:

限制 说明
不能 attach 到另一个 indirect buffer 会自动 attach 到其 direct buffer(跳过中间层)
要 attach 的 direct buffer refcnt 必须为 1 表示它是“尚未被引用”的
不能重复 attach 你必须先 detach 再 attach

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/908755.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

3.31 计算机实践-数字逻辑电路

带使能端的D触发器 之前学的门控D锁存器加了一个时钟周期CLK(使得只有时钟发生转换的时候才能写入数据)再加一个使能端(使得只有EN=1的时候才能正确写入,否则就把当前的输出结果再输入给D端,保持触发器当前输出)4位行波加法计数器 T触发器(使得每一个时钟周期之后就会有…

2025年天梯赛补题记录——九宫格

九宫格输入样例: 3 5 1 9 2 8 3 4 6 7 7 2 8 9 6 4 3 5 1 3 4 6 5 7 1 9 2 8 8 9 2 1 4 5 7 3 6 4 7 3 6 2 8 1 9 5 6 5 1 7 3 9 2 8 4 9 3 4 8 1 6 5 7 2 1 6 7 3 5 2 8 4 9 2 8 5 4 9 7 6 1 3 8 2 5 4 9 7 1 3 6 7 9 6 5 1 3 8 2 4 3 4 1 6 8 2 7 9 5 6 8 4 2 7 1 3 5 9 9 1…

【Python编程】Python 参数传递的强制规则你必须掌握

场景 外卖点单时,本来想在“备注”里写“不要辣”,结果不小心输错位置,填在了“地址”栏。骑手到了,给你打电话:“请问您是在‘不要辣小区’门口等我吗?”是不是听起来有点好笑? 生活里,错误填写表单位置尚且令人哭笑不得;而在代码世界里,如果参数用错了位置,后果往…

基于FPGA的2ASK+帧同步系统verilog开发,包含testbench,高斯信道,误码统计,可设置SNR

1.算法仿真效果 vivado2019.2仿真结果如下(完整代码运行后无水印):设置SNR=8db设置SNR=20db整体波形效果:仿真操作步骤可参考程序配套的操作视频。2.算法涉及理论知识概要 2.1 2ASK调制解调2ASK调制解调是一种数字调制解调技术,它是基于ASK调制的一种数字调制方式。ASK调制…

15.文件和流

本章目标Java中的文件 流 字节流 字符流本章内容 一、Java中的文件 1、文件的介绍 Java中文件操作主要通过File类来实现,File类关心的是磁盘上存储的文件File类并不是只代表文件 可以表示特定文件的名称,这里的名称就是路径 可以是某个目录。2、路径的表示方式: 因为在Java中…

16.对象流

本章目标对象流 递归(掌握)本章内容 一、对象流如果想在JVM停止后,把这些对象保存到磁盘或者通过网络传输到另一远程机器,怎么办呢?1、什么是对象流 所谓对象流也就是将对象的内容进行流化,能够输入输出对象的流称为对象流。可以对流化后的对象进行读写操作,也可将流化后…

可视化图解算法: 二叉树的中序遍历

对于二叉树的相关算法,我们总结了一套【可视化+图解】方法,依据此方法来解决相关问题,算法变得易于理解,写出来的代码可读性高也不容易出错。1. 题目 描述 给定一个二叉树的根节点root,返回它的中序遍历结果。 数据范围:树上节点数满足 0≤n≤1000,树上每个节点的值满足…

CH58x/CH59x不同类型广播使用

前言:在日常使用的时候我们用到的广播基本就是普通从机广播,在有特殊使用场景的时候我们可能会用到定向广播和拓展广播。本次对使用对定向广播和拓展广播。 一:定向广播 定向广播类型是为了尽可能快的连接,俗称回连包,这种报文包含两个地址:广播者的地址和发起者的地址。…

k 近邻算法

什么是 k 近邻? k 近邻(K-NearestNeighbor,简称 KNN)算法应该是机器学习中最简单的一个算法了,不过它虽然简单,但也有很多优点,比如:思想极度简单; 使用的数学知识很少(近乎为 0) 对于一些特定的数据集有非常好的效果; 可以解释机器学习算法使用过程中的很多细节问…

个性化配色方案

配置配色方案在app主页点击存储选择内部在根目录下找到 config 目录, 如果没有的话就创建进入 config 目录, 找到 ColorScheme 目录, 如果没有就创建进入 ColorScheme 目录, 可以创建 light.json 和 dark.json 两个文件, 一个用于在亮色模式下显示的配色方案, 一个用于暗色模式…

编辑器插件

开发编辑器插件步骤如下:在 build.gradle.kts 文件中添加 m8test sdk 依赖 , 为了减小插件apk大小, 如果是 M8Test Version Catalog 中存在的依赖库请使用 compileOnly 来依赖项目import com.m8test.util.VersionUtilsplugins {alias(m8test.plugins.android.application)alias…