首页 > 解决方案 > bpf_prog_test_run() 导致意外的数据包数据

问题描述


我尝试为 XDP BPF 程序执行测试运行。BPF 程序使用bpf_xdp_adjust_meta()助手来调整元数据。

我试过了:

  1. 跑步bpf_prog_test_run()
  2. 跑步bpf_prog_test_run_xattr()

1.bpf_prog_test_run()
(第一次尝试我的bpf程序的调试信息告诉我调整data_meta字段失败。)现在它可以调整data_meta,但是该iph.ihl字段显然没有设置为5。

2.bpf_prog_test_xattr()
这总是返回-1,所以有些事情失败了。

编码

包:

struct ipv4_packet pkt_v4 = {
    .eth.h_proto = __bpf_constant_htons(ETH_P_IP),
    .iph.ihl = 5,
    .iph.daddr = __bpf_constant_htonl(33554442),
    .iph.saddr = __bpf_constant_htonl(50331658),
    .iph.protocol = IPPROTO_TCP,
    .iph.tot_len = __bpf_constant_htons(MAGIC_BYTES),
    .tcp.urg_ptr = 123,
    .tcp.doff = 5,
};

测试属性:

__u32 size, retval, duration;
char data_out[128];
struct xdp_md ctx_in, ctx_out;
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,
};

测试执行:
bpf_prog_test_run(main_prog_fd, 1, &pkt_v4, sizeof(pkt_v4), &data_out, &size, &retval, &duration) ->iph.ihl字段为 0。

bpf_prog_test_run_xattr(&test_attr)-> 返回 -1。

笔记

该程序已成功连接到真实网络接口的挂钩点并按预期运行。我只是用上面的代码替换了将程序附加到挂钩点的代码进行测试。

标签: linux-kernelbpfebpfxdp-bpf

解决方案


struct ipv4_packet pkt_v4不是packed。_

当我用它替换__packed__attribute__ ((__packed__))时。

有关没有打包会发生什么的信息,请参见例如这个问题
基本上,编译器会添加填充字节,这会导致数据包中的字段位于与预期不同的位置。


推荐阅读