使用libbpf创建含自定义结构体的BPF_MAP_TYPE_ARRAY失败求助
问题解决:BPF数组映射使用自定义结构体键值失败
根因分析
BPF_MAP_TYPE_ARRAY 类型的映射必须使用 __u32 类型作为键,因为数组的键本质是数组的索引(从0开始的无符号32位整数)。你尝试用自定义结构体 network_tuple 作为数组键,这违反了内核对数组映射的要求,导致创建映射时返回 Invalid argument(-22) 错误。
解决方案
如果你需要根据网络元组(network_tuple)存储连接详情,应该使用 BPF_MAP_TYPE_HASH 类型的映射——哈希映射支持自定义结构体作为键(只要结构体大小固定且内存对齐正确)。
修正后的BPF代码如下:
struct network_tuple { __u32 saddr; __u32 daddr; __u16 sport; __u16 dport; __u8 l4_proto; }; struct syn_event { __u64 time_ns; __u32 tcp_seq; struct network_tuple flow_key; }; #define MAX_ENTRIES_FLOW 1024 // 根据实际需求调整哈希表最大条目数 struct { __uint(type, BPF_MAP_TYPE_HASH); __type(key, struct network_tuple); __type(value, struct syn_event); __uint(max_entries, MAX_ENTRIES_FLOW); } flow_table SEC(".maps");
补充说明
- 数组映射(
BPF_MAP_TYPE_ARRAY)适合预先知道固定数量条目的场景,比如用索引快速访问固定位置的数据;而哈希映射(BPF_MAP_TYPE_HASH)适合动态存储键值对,尤其是当键是复杂结构体时。 - 你的第二个示例(使用
__u32键值的数组映射)能正常工作,正是因为它符合数组映射对键类型的要求。
内容的提问来源于stack exchange,提问作者hundredmiles
相关产品推荐
相关产品推荐

