Unable to resolve kfuncs with "suffixes"
In the world of BTF we have the "ignored suffix rule", which means that when you define a type like void my_special_kfunc___old(), then we should attempt to match this to the void my_special_kfunc() kernel type, so ignoring the ___.... suffix.
This feature exists to allow programs to write CO-RE logic for cases where types have changed over time. For example:
void my_special_kfunc___old() __ksym __weak;
void my_special_kfunc(int new_param) __ksym __weak;
void some_func(int some_param) {
if (bpf_ksym_exists(my_special_kfunc))
return my_special_kfunc(some_param);
if (bpf_ksym_exists(my_special_kfunc___old))
return my_special_kfunc___old()
// No version of the kfunc available, cannot run.
bpf_throw();
}For each symbol we search the kernel for a type with the same name without its suffix (its essential name) and then ensure that its function signature is the same.
That way we will fixup my_special_kfunc___old on older kernels and my_special_kfunc on newer kernels. The bpf_ksym_exists guards ensure the function call is unreachable during program verification if a given symbol was not resolved.
This is an increasingly more common pattern now that kernel developers deprecate and modify kfuncs more often. Such as with the sched_ext kfuncs https://elixir.bootlin.com/linux/v7.1.3/source/tools/sched_ext/include/scx/compat.bpf.h.
Currently cilium/ebpf can only resolve kfuncs if their name matches exactly, but we never resolve kfuncs if they have suffixes.
Source: cilium/ebpf