首页 > 解决方案 > AF-XDP:小数据包有问题吗?

问题描述

在 AF-XDP 套接字框架 (+ libbpf) 中是否存在关于数据包大小的已知(或可能未知)错误?

我的应用程序遇到奇怪的数据包丢失:

bpf_printk我在我的 XDP-Kernelprogram 中添加了一条语句:

const int len = bpf_ntohs(iph->tot_len);
if(len < 400) {
    bpf_printk("FOUND PACKET LEN < 400: %d.\n", len);
}

永远不会通过 观察到此输出sudo cat /sys/kernel/debug/tracing/trace_pipe。所以我的内核过滤器甚至没有收到这些小的 RTP 标记数据包——难怪我在用户空间中没有收到它们。

ethtool -S <if>给我看这个号码:rx_256_to_511_bytes_phy。这个数字的增长速度与标记数据包应该进来的速度相似(大约 30/s)。所以这意味着我的 NIC 确实收到了数据包,但我的 XDP 程序没有 - 为什么?

知道什么可能是这个问题的原因吗?

标签: linuxsocketsnetworkingxdp-bpf

解决方案


首先,bpf_printk()并不总是对我有用。您可能想看看这个片段(内核空间代码):

// Nicer way to call bpf_trace_printk()
#define bpf_custom_printk(fmt, ...)                     \
        ({                                              \
            char ____fmt[] = fmt;                       \
            bpf_trace_printk(____fmt, sizeof(____fmt),  \
                    ##__VA_ARGS__);                     \
        })

// print:
bpf_custom_printk("This year is %d\n", 2020);
// output: sudo cat /sys/kernel/debug/tracing/trace_pipe

第二:可能是数据包进入了其他网卡队列。您可能想使用xdp-tutorial中的 vanilla 代码,并从上面的代码片段添加内核跟踪以打印数据包的大小,然后编译并运行示例程序,例如-q 1队列号 1。

一种获取数据包大小的方法:

void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
size_t size_pkt = data - data_end;
bpf_custom_printk("Packet size %d\n", size_pkt);

推荐阅读