Re: [PATCH bpf-next] libbpf: skip compat check for session kfuncs
From: Andrii Nakryiko
Date: Mon Feb 23 2026 - 14:12:33 EST
On Sun, Feb 22, 2026 at 6:16 AM Menglong Dong <menglong.dong@xxxxxxxxx> wrote:
>
> On 2026/2/12 01:20, Andrii Nakryiko wrote:
> > On Wed, Feb 11, 2026 at 4:57 AM Menglong Dong <menglong8.dong@xxxxxxxxx> wrote:
> > >
> > > The function prototype of bpf_session_{cookie,is_return} is changed in
> > > the commit 8fe4dc4f6456 ("bpf: change prototype of
> > > bpf_session_{cookie,is_return}"), which is not friendly to the old kernel,
> > > as the libbpf will fail on the compatible checking.
> > >
> > > Therefore, let's skip the checking of bpf_session_{cookie,is_return} in
> > > libbpf, and just let the kernel do the checking.
> > >
> > > Signed-off-by: Menglong Dong <dongml2@xxxxxxxxxxxxxxx>
> > > ---
> > > tools/lib/bpf/libbpf.c | 31 ++++++++++++++++++++-----------
> > > 1 file changed, 20 insertions(+), 11 deletions(-)
> > >
> >
> > This is not the way. Use bpf_ksym_exists() check and have custom
> > legacy bpf_session_cookie___legacy() definition with old prototype.
> > You can then detect whether
> > bpf_ksym_exists(bpf_session_cookie___legacy) is true and use the
> > legacy version, otherwise use the current version.
>
> Great! I found that there are already similar usages in kernel.
> I did some tests, and it works well. Thanks!
>
> BTW, do you think that if we need do some wrapper for bpf_session_{cookie,is_return}
> like this in case that someone else don't know the compatible problem?
>
> extern bool bpf_session_is_return___legacy(void) __weak __ksym;
> extern __u64 *bpf_session_cookie___legacy(void) __weak __ksym;
>
>
> #define bpf_session_is_return(ctx) \
> (bpf_ksym_exists(bpf_session_is_return___legacy) ? bpf_session_is_return___legacy() : \
> bpf_session_is_return(ctx))
> #define bpf_session_cookie(ctx) \
> (bpf_ksym_exists(bpf_session_cookie___legacy) ? bpf_session_cookie___legacy() : \
> bpf_session_cookie(ctx))
>
I'd like to avoid carrying this in libbpf forever, tbh. One reason we
decided to break bpf_session_xxx() helpers is because almost no one is
using them in any serious capacity, so I'm thinking it's fine to just
have this workaround live in your code base as an early session
adopter.
> Thanks!
> Menglong Dong
>
> >
> > pw-bot: cr
> >
> >
> > > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> > > index 0c8bf0b5cce4..71bdd1c1ac39 100644
> > > --- a/tools/lib/bpf/libbpf.c
> > > +++ b/tools/lib/bpf/libbpf.c
> > > @@ -8557,6 +8557,12 @@ static int find_ksym_btf_id(struct bpf_object *obj, const char *ksym_name,
> > > return id;
> > > }
> > >
> > > +static bool kfunc_skip_compat_check(const char *name)
> > > +{
> > > + return name && (strcmp(name, "bpf_session_cookie") == 0 ||
> > > + strcmp(name, "bpf_session_is_return") == 0);
> > > +}
> > > +
> > > static int bpf_object__resolve_ksym_var_btf_id(struct bpf_object *obj,
> > > struct extern_desc *ext)
> > > {
> > > @@ -8617,12 +8623,13 @@ static int bpf_object__resolve_ksym_func_btf_id(struct bpf_object *obj,
> > > struct module_btf *mod_btf = NULL;
> > > const struct btf_type *kern_func;
> > > struct btf *kern_btf = NULL;
> > > + const char *kfunc_name;
> > > int ret;
> > >
> > > local_func_proto_id = ext->ksym.type_id;
> > >
> > > - kfunc_id = find_ksym_btf_id(obj, ext->essent_name ?: ext->name, BTF_KIND_FUNC, &kern_btf,
> > > - &mod_btf);
> > > + kfunc_name = ext->essent_name ?: ext->name;
> > > + kfunc_id = find_ksym_btf_id(obj, kfunc_name, BTF_KIND_FUNC, &kern_btf, &mod_btf);
> > > if (kfunc_id < 0) {
> > > if (kfunc_id == -ESRCH && ext->is_weak)
> > > return 0;
> > > @@ -8634,16 +8641,18 @@ static int bpf_object__resolve_ksym_func_btf_id(struct bpf_object *obj,
> > > kern_func = btf__type_by_id(kern_btf, kfunc_id);
> > > kfunc_proto_id = kern_func->type;
> > >
> > > - ret = bpf_core_types_are_compat(obj->btf, local_func_proto_id,
> > > - kern_btf, kfunc_proto_id);
> > > - if (ret <= 0) {
> > > - if (ext->is_weak)
> > > - return 0;
> > > + if (!kfunc_skip_compat_check(kfunc_name)) {
> > > + ret = bpf_core_types_are_compat(obj->btf, local_func_proto_id,
> > > + kern_btf, kfunc_proto_id);
> > > + if (ret <= 0) {
> > > + if (ext->is_weak)
> > > + return 0;
> > >
> > > - pr_warn("extern (func ksym) '%s': func_proto [%d] incompatible with %s [%d]\n",
> > > - ext->name, local_func_proto_id,
> > > - mod_btf ? mod_btf->name : "vmlinux", kfunc_proto_id);
> > > - return -EINVAL;
> > > + pr_warn("extern (func ksym) '%s': func_proto [%d] incompatible with %s [%d]\n",
> > > + ext->name, local_func_proto_id,
> > > + mod_btf ? mod_btf->name : "vmlinux", kfunc_proto_id);
> > > + return -EINVAL;
> > > + }
> > > }
> > >
> > > /* set index for module BTF fd in fd_array, if unset */
> > > --
> > > 2.53.0
> > >
> >
> >
>
>
>
>