eBPF verifier的func_info是什么?XDP加载报错数量不匹配如何解决
报错根因分析
你遇到的错误核心是XDP程序没有指定正确的ELF段名:
- 你的XDP入口函数现在被编译到了默认的
.text段,libbpf无法根据段名识别这是XDP类型的eBPF程序,首先抛出了段名识别失败的错误。 - 第二个
func_info数量和子程序数量不匹配是连锁错误:因为libbpf没有识别到正确的程序类型,加载时解析ELF的func_info(函数元信息)和子程序统计逻辑异常,两个计数对不上触发了verifier报错。
func_info_cnt和subprog_cnt的赋值逻辑
attr->func_info_cnt:由用户态libbpf在加载eBPF程序前,解析ELF文件中的.BTF.func_info段统计得到,值等于当前加载的程序段中包含的所有函数(入口函数+所有辅助函数)的总数量。env->subprog_cnt:内核eBPF加载模块在进入verifier前,解析传入的eBPF字节码,统计字节码中包含的所有子程序(包括入口函数)的数量得到。
正常情况两个值必须完全相等,否则verifier会直接拒绝加载。
eBPF verifier中func_info的作用
func_info是BTF提供的函数级元信息,verifier依赖它完成这些校验逻辑:
- 校验每个函数的参数数量、参数类型、返回值类型是否符合eBPF编程规范
- 校验函数调用时的参数传递是否符合类型要求,避免类型不匹配的访问
- 识别递归调用(eBPF禁止递归),校验函数调用栈深度是否超过内核限制(默认最大1024字节)
- 辅助边界校验逻辑,比如指针类型参数的访问范围校验
解决方法
你只需要给XDP入口函数加上正确的段标记即可:
- 在XDP入口函数定义前加上
SEC("xdp")注解,示例代码如下:
#include <bpf/bpf_helpers.h> SEC("xdp") int xdp_handler(struct xdp_md *ctx) { // 你的XDP处理逻辑 return XDP_PASS; } // 你的6个辅助函数不需要加SEC注解,正常定义即可 static void helper_func1(...) { // 辅助函数逻辑 } char _license[] SEC("license") = "GPL";
- 重新编译eBPF程序后再次加载,libbpf会自动识别
xdp段名,正确统计func_info和子程序数量,报错就会消失。
内容的提问来源于stack exchange,提问作者walid barakat
相关产品推荐
相关产品推荐

