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);
}
这个函数是从一个循环调用的,该循环解析数据包流并在每次迭代时传递 packet 和 size。由于会有很多调用,我怎样才能使我的代码内存更高效、更好?有什么建议吗?
代码几乎没有问题。
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
是否小于数据包长度,除非在代码前面进行了此类检查。
我正在尝试使用 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);
}
这个函数是从一个循环调用的,该循环解析数据包流并在每次迭代时传递 packet 和 size。由于会有很多调用,我怎样才能使我的代码内存更高效、更好?有什么建议吗?
代码几乎没有问题。
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
是否小于数据包长度,除非在代码前面进行了此类检查。