如何克隆数据包并更改 DPDK 中的以太网、IP 和 UDP header 字段?

How to clone a packet and change Ethernet, IP, and UDP header fields in DPDK?

我正在尝试克隆数据包并更改克隆数据包中的各种第 2/3/4 层 header 字段。

根据 DPDK 存储库和互联网上给出的示例,几乎所有示例都使用了 rte_pktmbuf_prepend()。在前置所需的 header 之后,那些新添加的 header 将被更改以反映各个字段的更新值。据我了解,rte_pktmbuf_clone() 将克隆所有段,为什么我们不能更改克隆中的 header 字段数据包以及为什么我们需要在克隆数据包后添加 headers?

此外,在 ipv4_multicast(DPDK 示例应用程序)中,首先使用 rte_pktmbuf_adj() 删除 header,然后新的 header 被添加到数据包中。 因此,在某些示例中,首先删除 header,然后添加新的 header,而在其他一些示例中,添加新的 header。为什么我们需要这样做?

谢谢。

相关链接:

http://dpdk.org/ml/archives/dev/2014-March/001589.html

http://dpdk.org/ml/archives/dev/2014-March/001583.html

http://dpdk.readthedocs.io/en/v17.08/sample_app_ug/ipv4_multicast.html

在 DPDK 中(与许多其他库一样),mbufs 背后的想法是拆分数据(即内部带有 IP 数据包的以太网帧)和元数据(即链中缓冲区的数量、指向下一个缓冲区的指针、标志、总长度等)。

给定 mbuf 的 rte_pktmbuf_clone() 分配另一个元数据。此元数据附加到原始 mbuf 数据,即原始和克隆的 mbuf 在克隆后共享相同的数据,但有两个单独的元数据。这在 Programer's Guide.

中有更详细的描述

现在回答你的问题。

why can't we change the header fields in the cloned packets and why do we need to prepend the headers after cloning the packet?

事实上,我们可以更改克隆数据包中的数据包 headers,但是由于(在克隆之后)两个 mbuf 共享相同的缓冲区数据,更改一个 mbuf 的数据将更改另一个 mbuf 中的数据,因为 mbuf数据已共享。

一些示例的目标是将同一个 mbuf 同时发送到 N 个目的地。最简单的解决方案是:

  1. 分配 N 个新的 mbuf。
  2. 复制原始数据N份。
  3. 为 N 个目的地更改数据包 headers N 次。
  4. 将这些 mbuf 发送到 N 个不同的接口。

不幸的是,制作N份数据只是为了改变开头的几个字节并不是最有效的解决方案。所以我们克隆数据包,即:

  1. 分配 N 个新的 mbufs 元数据(即比以前少得多)。
  2. 将N个mbufs附加到原始数据(即没有数据副本)。

现在,由于所有 N 个 mbuf 共享相同的数据,我们不能为 N 个不同的目的地更改数据包 headers。因此,我们只为数据包 headers 分配另一个 mbuf,即:

  1. 为数据包headers分配N个mbufs。
  2. 为 N 个目的地填充数据包 headers N 次。
  3. 将 N headers 添加到 N 个克隆的 mbuf。
  4. 将这些 mbuf 发送到 N 个不同的接口。

所以,这个过程比以前更复杂,但可能会表现出更好的性能,因为我们从不复制数据包数据,在某些情况下可能高达 ~65K。

So, in some examples, headers are removed first and then new headers are added and in some other examples, the new headers are added. Why do we need to do this?

这取决于是否只需要更改数据包 headers 并将其发送出去,或者我们需要使用 N 个不同的数据包 headers 制作 N 个副本,如上所述。总的来说,DPDK 非常注重性能,因此我们可以理所当然地认为所有这些复杂情况都是有原因的...