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

时间:2018-01-15 15:27:35

标签: c++ network-programming packet dpdk

我尝试使用mbuf和mempool库修改某些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);
}

此函数从循环中调用,该循环解析数据包流并在每次迭代时传递数据包 size 。由于会有很多电话,我怎样才能使我的代码内存更高效更好?有什么提示吗?

1 个答案:

答案 0 :(得分:0)

代码存在一些问题。

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字节本身。所以我们必须使用它返回的指针实际进行复制,即

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

以下是rte_pktmbuf_append()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);

性能

我们可以在数据复制期间考虑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是否小于数据包长度可能也是必需的,除非在代码中先前进行过此类检查。