调用bpf_prog_test_run测试XDP BPF程序出现报文数据异常问题排查
问题排查与修复方案
1. bpf_prog_test_run_xattr 返回-1执行失败
根因:
- 核心错误:
bpf_prog_test_run_attr结构体中data_size_in字段赋值错误,你填写的sizeof(&pkt_v4)取的是指针的大小(64位系统为8字节、32位为4字节),远小于实际struct ipv4_packet的长度,内核校验输入报文不合法直接返回错误。 - 次要错误:传入的
ctx_in是未初始化的空结构体,内核测试框架无法识别报文的内存边界,导致参数校验失败。
修复方法:
// 修复data_size_in赋值 struct bpf_prog_test_run_attr test_attr = { .prog_fd = prog_fd, .repeat = 100, .data_in = &pkt_v4, .data_size_in = sizeof(pkt_v4), // 改为结构体本身长度,而非指针长度 .data_out = &data_out, .data_size_out = sizeof(data_out), .ctx_in = &ctx_in, .ctx_size_in = sizeof(ctx_in), .ctx_out = &ctx_out, .ctx_size_out = sizeof(ctx_out), .retval = &retval, .duration = &duration, }; // 初始化xdp_md上下文字段 memset(&ctx_in, 0, sizeof(ctx_in)); ctx_in.data = (unsigned long long)&pkt_v4; ctx_in.data_end = (unsigned long long)&pkt_v4 + sizeof(pkt_v4); // 初始状态下meta和data指向同一位置,预留足够空间给adjust_meta操作 ctx_in.data_meta = ctx_in.data;
2. bpf_prog_test_run 执行后iph.ihl值为0
根因:
调用bpf_xdp_adjust_meta后,内核会将预留的meta空间放在实际报文数据之前,输出到data_out缓冲区的内容为 [meta预留空间] + [原始报文数据] 的完整结构。你直接将data_out起始地址强转为struct ipv4_packet读取的是未初始化的meta空间内容,默认值为0,因此读到的ihl值不符合预期。
修复方法:
读取输出报文时,先跳过meta预留空间的长度,再强转为报文结构体:
// meta长度为data指针减去data_meta指针的差值 int meta_len = ctx_out.data - ctx_out.data_meta; struct ipv4_packet *out_pkt = (struct ipv4_packet *)(data_out + meta_len); // 此时读取out_pkt->iph.ihl即可得到预期值
补充排查建议
执行系统调用失败后可以打印errno的值,可快速定位错误类型:
- EINVAL:参数非法,检查各字段长度、指针是否合法
- ENOENT:传入的prog_fd无效
- ENOMEM:输出缓冲区长度不足,需要加大
data_out的大小
内容的提问来源于stack exchange,提问作者n1kb3rt
相关产品推荐
相关产品推荐

