含BPF_MAP_TYPE_ARRAY_OF_MAPS的XDP程序加载失败求助
eBPF XDP程序加载失败问题排查
我编写了如下eBPF XDP程序,但加载时失败:
#include <linux/bpf.h> #include <bpf/bpf_helpers.h> #include <bpf/bpf_endian.h> #include <linux/if_ether.h> #include <linux/ip.h> #include <linux/udp.h> #include <linux/tcp.h> #include <linux/in.h> #include <linux/time.h> #define MAX_CPUs 32 struct flow_key { __u32 src_ip; __u16 src_port; }; struct flow_entry { __u64 timestamp_ns; __u32 dst_ip; __u16 dst_port; __u16 src_port; }; struct { __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, 512000); __type(key, struct flow_key); __type(value, struct flow_entry); } flows SEC(".maps"); struct { __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS); __uint(max_entries, MAX_CPUs + 1); __type(key, __u32); __array(values, struct flows); } per_cpu_flows SEC(".maps"); SEC("xdp") int udp_router(struct xdp_md *ctx) { return XDP_PASS; } char _license[] SEC("license") = "GPL";
加载时出现如下错误:
libbpf: map 'per_cpu_flows': map-in-map inner def is of unexpected kind fwd.
我参考了多个示例,未发现代码差异,请问问题出在哪里?
问题原因及解决方法
错误本质:
BPF_MAP_TYPE_ARRAY_OF_MAPS的定义方式错误。直接引用外部已定义的struct flows作为内部映射类型时,libbpf无法正确识别内部映射的完整定义,从而抛出"unexpected kind fwd"错误。修正方案:需要在数组嵌套映射的定义中,直接内嵌内部映射的完整定义,而非引用外部结构体。修改
per_cpu_flows的定义如下:
struct { __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS); __uint(max_entries, MAX_CPUs + 1); __type(key, __u32); __array(values, struct { __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, 512000); __type(key, struct flow_key); __type(value, struct flow_entry); }); } per_cpu_flows SEC(".maps");
- 复用定义优化:如果需要复用内部映射的定义逻辑,可以通过宏来避免代码重复:
#define FLOW_MAP_DEF \ __uint(type, BPF_MAP_TYPE_HASH); \ __uint(max_entries, 512000); \ __type(key, struct flow_key); \ __type(value, struct flow_entry) // 单独的哈希映射(若需保留) struct { FLOW_MAP_DEF; } flows SEC(".maps"); // 数组嵌套映射 struct { __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS); __uint(max_entries, MAX_CPUs + 1); __type(key, __u32); __array(values, struct { FLOW_MAP_DEF; }); } per_cpu_flows SEC(".maps");
修改后,libbpf就能正确解析内部映射的类型,程序加载即可正常完成。
内容的提问来源于stack exchange,提问作者eof
相关产品推荐
相关产品推荐

