DPDK:修改捕获数据包的最有效方法 headers

DPDK: Most efficient way to modify captured packet's headers

我正在尝试使用 mbuf 和 mempool 库修改 headers 一些 GTP 数据包,特别是我想删除所有的 ETH、IP、UDP、GTP 层和 获取数据包有效载荷的(深)副本

这是应该完成工作的代码片段:

void (const unsigned char* packet, size_t size)
{
    auto outer_header_len = sizeof(ether_header) + sizeof(ip) + sizeof(udphdr) + sizeof(gtp); //length to cut
    uint8_t byte_size = static_cast<uint8_t>(size);
    struct rte_mempool* mbuf_pool;

    struct rte_mbuf *mbuf_pkt = rte_pktmbuf_alloc(mbuf_pool);
    mbuf_pkt->data_len = byte_size;
    mbuf_pkt->pkt_len = byte_size;

    rte_pktmbuf_append(mbuf_pkt, packet[byte_size]);    
    auto payload = rte_pktmbuf_adj(mbuf_pkt, outer_header_len);
}

这个函数是从一个循环调用的,该循环解析数据包流并在每次迭代时传递 packetsize。由于会有很多调用,我怎样才能使我的代码内存更高效、更好?有什么建议吗?

代码几乎没有问题。

byte_size

uint8_t byte_size = static_cast<uint8_t>(size); 我不确定这是否正确,因为它基本上将所有数据包限制为 256 字节,但情况可能并非总是如此。所以我只是删除了这一行,因为 size 本身非常好。

rte_pktmbuf_append()

rte_pktmbuf_append(mbuf_pkt, packet[byte_size]); 这个函数增加了 mbuf_pkt 的长度,但不改变 mbuf 字节本身。所以我们必须使用指针 it returns 来实际进行复制,即

ptr = rte_pktmbuf_append(mbuf_pkt, size);
if (ptr != NULL)
    rte_memcpy(ptr, packet + outer_header_len, size -outer_header_len);

这里还有 rte_pktmbuf_append() and rte_memcpy() 文档的链接。

其他 Mbuf 长度操作

由于rte_pktmbuf_append()增加了数据包的长度,以下几行是多余的:

mbuf_pkt->data_len = byte_size;
mbuf_pkt->pkt_len = byte_size;
auto payload = rte_pktmbuf_adj(mbuf_pkt, outer_header_len);

性能

我们可以在没有外部 header 的情况下复制数据,方法是在数据复制期间考虑 outer_header_len,如前例所示:

ptr = rte_pktmbuf_append(mbuf_pkt, size);
if (ptr != NULL)
    rte_memcpy(ptr, packet + outer_header_len, size -outer_header_len);

可能还需要检查 outer_header_len 是否小于数据包长度,除非在代码前面进行了此类检查。