为什么load_half在bpf_helpers中有定义,但在filter.c中却没有出现?
Why load_half is defined in bpf_helpers but it doesn't appear in filter.c?
如果我在 tools/testing/selftests/bpf/bpf_helpers.h
中理解 "well" 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 助手,所以在内核中 grep 查找它的原型时你不会看到它。
前缀 sk_filter
用于附加到套接字的 eBPF 过滤器,其方式与使用传统 cBPF 的方式类似,用于过滤传入数据包。虽然可能会造成混淆,但您可以看到内核文件 net/core/filter.c
中的 sock_filter_is_valid_access
用于 cg_sock_verifier_ops
,它在 include/uapi/linux/bpf.h
中关联到程序类型 BPF_PROG_TYPE_CGROUP_SOCK_ADDR
。所以它指的是在cgroups中使用的程序正确help (containerised) applications to bind and connect它们的套接字。
如果我在 tools/testing/selftests/bpf/bpf_helpers.h
中理解 "well" 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 助手,所以在内核中 grep 查找它的原型时你不会看到它。前缀
sk_filter
用于附加到套接字的 eBPF 过滤器,其方式与使用传统 cBPF 的方式类似,用于过滤传入数据包。虽然可能会造成混淆,但您可以看到内核文件net/core/filter.c
中的sock_filter_is_valid_access
用于cg_sock_verifier_ops
,它在include/uapi/linux/bpf.h
中关联到程序类型BPF_PROG_TYPE_CGROUP_SOCK_ADDR
。所以它指的是在cgroups中使用的程序正确help (containerised) applications to bind and connect它们的套接字。