如果我理解"很好"tools/testing/selftests/bpf/bpf_helpers.h
bpf heleprs 原型就被定义出来了。
如果我现在想哪些帮助程序可用于特定程序类型,我需要在结果中搜索'func_proto(enum bpf_func_id func_id' kernel/ net/ drivers/
例如,要检查套接字过滤器程序可以调用的帮助程序,我可以阅读以下定义
static const struct bpf_func_proto *
sock_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
switch (func_id) {
/* inet and inet6 sockets are created in a process
* context so there is always a valid uid/gid
*/
case BPF_FUNC_get_current_uid_gid:
return &bpf_get_current_uid_gid_proto;
case BPF_FUNC_get_local_storage:
return &bpf_get_local_storage_proto;
default:
return bpf_base_func_proto(func_id);
}
}
问题:
1(我看不到load_half
,但我仍然可以从我的套接字过滤器程序中调用它。为什么?2(socket_filter
和sk_filter
之间的区别是什么?
load_half()
不是BPF 帮助程序。您提到的文件
bpf_helpers.h
确实声明了 BPF 帮助程序函数的原型,但它也包含其他有用的定义,例如SEC()
或bpf_printk()
宏。特别是,它宣布load_half()
,并附有以下评论:/* llvm builtin functions that eBPF C program may use to * emit BPF_LD_ABS and BPF_LD_IND instructions */ [...] unsigned long long load_half(void *skb, unsigned long long off) asm("llvm.bpf.load.half");
正如你所读到的,
load_half()
是一个内置的LLVM,一个由clang/LLVM支持的程序集原语,为了方便起见,它被包装为load_half()
。而且因为它不是 BPF 助手,所以在内核中查找其原型时不会看到它。前缀
sk_filter
用于连接到套接字的 eBPF 过滤器,其方式类似于对旧版 cBPF 执行的操作,以过滤传入数据包。虽然可能会令人困惑,但您可以看到内核文件net/core/filter.c
中的sock_filter_is_valid_access
用于cg_sock_verifier_ops
,这在程序类型BPF_PROG_TYPE_CGROUP_SOCK_ADDR
include/uapi/linux/bpf.h
相关联。因此,它指的是 cgroups 中使用的程序,以帮助(容器化(应用程序正确绑定和连接其套接字。