Your app needs eBPF, and nobody can tell you whether this kernel actually has it, so ask with bpftool feature. It reports what the running kernel or a network device supports, saves the answer as JSON if you want it, and tells a real probe apart from a list of names. Allow about ten minutes for one host. Everything here inspects state: no program is loaded, no device is changed and no kernel configuration is touched.
First find out which executable your shell will run. The package on this machine is linux-tools-common 6.8.0-139.139. On Ubuntu, /usr/sbin/bpftool may only be a selector that wants a kernel-specific tools package. A warning about a missing binary means the tool is unavailable. It does not mean eBPF is absent.
$ command -v bpftool
/usr/sbin/bpftool
$ dpkg-query -W -f='${Package} ${Version}\n' linux-tools-common
linux-tools-common 6.8.0-139.139
$ bpftool --version
bpftool vX.Y
libbpf vX.Y
sudo. The probes themselves do not normally need it.Checkpoint: continue only when bpftool --version reports a usable binary, or record that this host cannot perform the next steps yet.
With no target, feature probe examines the running kernel. Writing kernel makes the target explicit. The report covers the bpf() system call, JIT settings, program types, helper availability and more. The text changes with the kernel, libbpf and bpftool build, so treat it as a capability report and not a stable interface.
$ bpftool feature probe kernel
For a quick, non-invasive check, leave off full. By default bpftool skips the probes for bpf_probe_write_user() and bpf_trace_printk(), because those probes print warnings to the kernel log. That keeps a routine inspection quiet, but it also means the report is not the result of every available probe.
Run the complete set only when you can accept those log messages:
$ bpftool feature probe kernel full
Warning: full is not destructive, but it is deliberately noisier. If a clean kernel log matters on a production host, use the default probe and note that the two warning-producing helper probes were skipped. A missing line in that report is not proof that a helper is unusable.
Privilege changes what feature detection can see. A run without CAP_SYS_ADMIN sees a smaller subset than a privileged run. To test what an ordinary service account can use, say so explicitly:
$ bpftool feature probe kernel unprivileged
Checkpoint: keep both reports if you are debugging a deployment. A difference between kernel and kernel unprivileged is evidence about permissions, not necessarily about different kernels.
Kernel support and network-device support are separate questions. Replace DEVICE with an existing interface name, such as eth0 or ens3. Find the name without changing anything:
$ ip -brief link
lo UNKNOWN 127.0.0.1/8 ::1/128
DEVICE UP ...
The interface names shown are host-specific. Probe one by passing the name after dev:
$ bpftool feature probe dev DEVICE
DEVICE with the literal interface name, not the word in the example.For scripts or a before-and-after comparison, ask for JSON. The option goes before feature in the global command syntax:
$ bpftool -j feature probe kernel > kernel-features.json
$ test -s kernel-features.json && echo 'JSON report written'
JSON report written
Use -p when you want JSON that is easier for a person to read:
$ bpftool -p feature probe kernel
Do not parse the human-readable default output with a script. Keep the captured file as evidence alongside the kernel release, bpftool version and command line.
Warning: redirection creates or truncates the destination before the command runs. Choose a new filename, or use a temporary file, if an earlier report matters. To discard a report you no longer need, remove only that named file after checking its path. The probe has no undo step because it changes no persistent state.
If a build wants compile-time-style feature names, ask for the macro form instead of converting the normal report yourself. This mode is available without JSON:
$ bpftool feature probe kernel macros > bpf-features.h
$ sed -n '1,12p' bpf-features.h
The output is a subset of the probe results as #define lines, suitable for a C header. It cannot be combined with -j, so pick JSON or macros. Add a prefix when the names could collide with another header:
$ bpftool feature probe kernel macros prefix MYPROJECT_ > bpf-features.h
Tip: read a generated header before you commit it. It describes the host that produced it and may change after a kernel, libbpf or bpftool update. One host's header is not proof that every deployment supports the same features.
list_builtins does not probe the kernel or a device. It lists the items this bpftool build knows about, supplied by libbpf or the BPF UAPI headers. Use it to enumerate program, map, attach or link types, or helper names:
$ bpftool feature list_builtins prog_types
$ bpftool feature list_builtins map_types
$ bpftool feature list_builtins helpers
A name printed here means bpftool knew it at compile time. It does not mean the running kernel accepts it. Follow an inventory command with feature probe when you need host capability, and note which question each result answers.
unprivileged when testing an ordinary user's view.list_builtins inventory.