bpf_prog_test_run() 导致意外的数据包数据
bpf_prog_test_run() causes unexpected packet data
我尝试对 XDP BPF 程序执行测试 运行。 BPF 程序使用 bpf_xdp_adjust_meta()
助手来调整元数据。
我试过了:
- 到运行
bpf_prog_test_run()
- 到运行
bpf_prog_test_run_xattr()
1. bpf_prog_test_run()
(我第一次尝试我的 bpf 程序的调试消息告诉我调整 data_meta 字段失败。)现在它可以调整 data_meta,但是 iph.ihl
字段显然没有设置为 5 .
2。 bpf_prog_test_xattr()
这总是 returns -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)
-> returns -1.
备注
该程序已成功附加到真实网络接口的挂钩点,并且 运行 符合预期。我只是把将程序附加到挂钩点的代码替换成上面的代码进行测试。
struct ipv4_packet pkt_v4
不是 packed
。
当我用 __attribute__ ((__packed__))
替换 __packed
时,它起作用了。
有关不打包会发生什么的信息,请参见示例 this question。
基本上,编译器会添加 填充字节 ,这会导致数据包中的字段与预期的位置不同。
我尝试对 XDP BPF 程序执行测试 运行。 BPF 程序使用 bpf_xdp_adjust_meta()
助手来调整元数据。
我试过了:
- 到运行
bpf_prog_test_run()
- 到运行
bpf_prog_test_run_xattr()
1. bpf_prog_test_run()
(我第一次尝试我的 bpf 程序的调试消息告诉我调整 data_meta 字段失败。)现在它可以调整 data_meta,但是 iph.ihl
字段显然没有设置为 5 .
2。 bpf_prog_test_xattr()
这总是 returns -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)
-> returns -1.
备注
该程序已成功附加到真实网络接口的挂钩点,并且 运行 符合预期。我只是把将程序附加到挂钩点的代码替换成上面的代码进行测试。
struct ipv4_packet pkt_v4
不是 packed
。
当我用 __attribute__ ((__packed__))
替换 __packed
时,它起作用了。
有关不打包会发生什么的信息,请参见示例 this question。
基本上,编译器会添加 填充字节 ,这会导致数据包中的字段与预期的位置不同。