Visitar URL original
btf, linker: resolve kfuncs by essential name when exact match fails by Ananttyagi07 · Pull Request #2098 · cilium/ebpf · GitHub
Skip to content

btf, linker: resolve kfuncs by essential name when exact match fails - #2098

Draft
Ananttyagi07 wants to merge 1 commit into
cilium:mainfrom
Ananttyagi07:kfunc-suffix-resolution
Draft

Ananttyagi07 wants to merge 1 commit into
cilium:mainfrom
Ananttyagi07:kfunc-suffix-resolution

Conversation

@Ananttyagi07

Copy link
Copy Markdown

Summary

Fixes #2057. When a kfunc call can't be resolved by its exact name in
the kernel's BTF, retry using the name with its ___ flavour suffix
stripped (its "essential name"), matching the same "ignored suffix
rule" already used for CO-RE relocations.

This lets a BPF program declare multiple ___-suffixed variants of a
kfunc whose signature has changed across kernel versions (e.g.
foo___old, foo) and have the variant matching the running kernel
resolve automatically, instead of only ever resolving kfuncs with an
exact name match.

What was already there vs. what this adds

While tracing this, I found the signature-compatibility half of the
issue ("ensure its function signature is the same") is already
implemented: fixupKfuncs in linker.go calls
btf.CheckTypeCompatibility on whatever target is resolved, before
using it. So the only missing piece was the name resolution itself,
which was doing an exact match only (findTargetInKernel →
Spec.TypeByName, no suffix handling).

This adds btf.EssentialName, an exported wrapper around the
existing internal newEssentialName/essentialNameLen CO-RE logic
(so the suffix-stripping rule itself isn't duplicated), and uses it
as a fallback in fixupKfuncs specifically — not in
findTargetInKernel itself, since that helper is shared with program
attach-target and struct_ops lookups, where fuzzy suffix matching
would be an unwanted, silent behavior change.

Testing

  • go build ./..., go vet ./..., gofmt -l all clean.
  • Added TestEssentialNameExported for the new exported wrapper. The
    suffix-stripping logic itself already has thorough edge-case
    coverage via the existing TestEssentialName.
  • Could not exercise the fixupKfuncs retry path end-to-end: that
    requires loading a program against real kernel BTF containing a
    kfunc with multiple versioned signatures, and this dev environment
    has neither CAP_BPF nor such a kfunc available to test against.
    Marking as draft for that reason — happy to add an integration test
    if a maintainer can point me at a suitable existing kfunc/kernel
    fixture, or if there's a preferred way to fake this in the test
    suite.

Generative AI disclosure

Per the Cilium Generative AI policy: I used Claude (Anthropic) while
preparing this submission. It helped trace where kfunc resolution
actually happens in the codebase, confirmed the signature-compatibility
check already existed, and helped scope the fix to avoid changing
shared lookup behavior used by other callers. I reviewed and
understood the resulting design and code before submitting, and I'm
happy to discuss any part of it further during review.

🤖 Generated with Claude Code

Adds btf.EssentialName, an exported wrapper around the existing
CO-RE "ignored suffix rule" logic, and uses it in fixupKfuncs as a
fallback: if a kfunc's exact name isn't found in the kernel, retry
with the ___ flavour suffix stripped.

This lets a BPF program declare multiple ___-suffixed variants of a
kfunc that has changed signature across kernel versions (e.g.
"foo___old" and "foo") and have the correct one resolve automatically
against whatever kernel it runs on, per cilium#2057. The existing
btf.CheckTypeCompatibility call in fixupKfuncs already runs
unconditionally after resolution, so it continues to guard against
silently binding to an unrelated kfunc that happens to share the
essential name.

Scoped the fallback to fixupKfuncs specifically rather than changing
findTargetInKernel itself, since that helper is also used for program
attach-target and struct_ops lookups, where fuzzy suffix matching
would be an unwanted, silent change in behavior.

Testing:
- go build ./..., go vet ./..., gofmt -l all clean.
- Added TestEssentialNameExported for the new exported wrapper; the
  underlying suffix-stripping logic already has thorough coverage in
  TestEssentialName.
- Could not exercise the fixupKfuncs retry path itself end-to-end:
  it requires loading a program against real kernel BTF, and this
  dev environment has neither CAP_BPF nor a way to fabricate a kfunc
  with multiple kernel-version signatures to test against.

Generative AI disclosure: per the Cilium Generative AI policy, I used
Claude (Anthropic) while preparing this change. It helped trace where
kfunc name resolution actually happens (fixupKfuncs in linker.go,
distinct from the typed-ksym-var path in the same file), confirmed
that the signature-compatibility half of this issue was already
implemented via btf.CheckTypeCompatibility, and helped scope the fix
to the kfunc call site rather than the shared findTargetInKernel
helper. I reviewed and understood the resulting design and code
before submitting.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Anant Tyagi <tyagianant65@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unable to resolve kfuncs with "suffixes"

2 participants