You have SSH'd into a Linux host you did not set up and want to know which eBPF programs are loaded and what they are attached to. Which bpftool subcommands answer that, and what do their outputs tell you?
answer
- one command lists, another locates
- prog show does not name the hook
- links, net, cgroup, perf
- map_ids ties program to data
- -j when you script it
basics
~20 sStart with bpftool prog show for loaded programs and bpftool map show for their maps. Attachment points come from bpftool link show, bpftool net show for interface hooks and bpftool cgroup tree for cgroup hooks, because prog show alone does not say where a program is attached.
solid answer
~50 s`bpftool prog show` lists every loaded program with its id, program type, name, load time, owning uid, `xlated` and `jited` sizes, `memlock` bytes and the `map_ids` it uses — on a suitably privileged kernel it also prints the pids holding it. `bpftool map show` gives the corresponding maps with type, key and value sizes, `max_entries` and `memlock`, and `bpftool map dump id N` prints their contents. What `prog show` deliberately does not tell you is the attach point, so you follow up with `bpftool link show` for link-based attachments, `bpftool net show` for interface hooks, `bpftool cgroup tree` for cgroup ones and `bpftool perf show` for perf-event attachments held by processes. `bpftool prog dump xlated id N` shows the post-verifier instructions when you need to know what a program actually does. Add `-j` or `-p` for JSON when you are scripting.
code
bash · 6 linesbpftool prog show
bpftool map show
bpftool link show
bpftool net show
bpftool prog dump xlated id 6
bpftool map dump id 4go deeper
Know that bpftool prog show and bpftool map show are how you see what eBPF is doing on a host, and that both need root.
Read the output field by field — id, type, name, loaded_at, xlated, memlock, map_ids — and know that finding the attach point takes a second command such as bpftool link show or bpftool net show.
Turn the output into a conclusion on an unfamiliar box: attribute programs to an owner, account for the kernel memory their maps hold, inspect what a program does with dump xlated, and decide whether removing it is safe.
Set the expectation that eBPF on the fleet is inventoried and attributable — agents that pin under a known path, a naming convention, and a policy for what happens when an unattributed program appears on a production host.
## bpftool is the ground truth bpftool ships with the kernel source (under `tools/bpf/bpftool`) and is packaged by every distribution. It is the only general-purpose way to see BPF state on a box, because loaded programs belong to no process by name and leave no trace in `ps`. Everything below needs root or `CAP_BPF`/`CAP_SYS_ADMIN` depending on kernel version. ## What is loaded ```bash bpftool prog show ``` A typical entry looks like: ``` 6: tracepoint name handle_exec tag 6deef7357e7b4530 gpl loaded_at 2026-08-19T10:12:04+0000 uid 0 xlated 528B jited 397B memlock 4096B map_ids 4,5 btf_id 12 ``` Read it as: the **id** is bpftool's handle for later commands; the **type** (`tracepoint`, `kprobe`, `xdp`, `cgroup_skb`, …) tells you what class of hook it is written for; **name** comes from the C function; **loaded_at** and **uid** are your first forensic clues about who put it there and when; **xlated**/**jited** are instruction-stream sizes; **memlock** is the kernel memory charged for it; **map_ids** links it to its maps; **btf_id** shows it carries type information, which is what makes a readable dump possible. ```bash bpftool map show ``` gives `id: type name`, `key`/`value` sizes, `max_entries` and `memlock`. `memlock` across all maps is the number to watch when you suspect BPF is holding meaningful kernel memory; a large hash map with a big `max_entries` allocates up front. ## Where it is attached — the part `prog show` omits This is the detail that separates someone who has used bpftool from someone who has read about it. A program's *existence* and its *attachment* are separate facts, so you need more commands: - `bpftool link show` — modern attachments are `bpf_link` objects and this lists them with the link type, the program id and, for many types, the attach target. If a program has a link, this is the fastest answer. - `bpftool net show` — programs attached to network interfaces, per device. - `bpftool cgroup tree` — walks the cgroup hierarchy and prints programs attached to each cgroup, which is where systemd-managed and container-runtime filters live. - `bpftool perf show` — perf-event attachments (older kprobe/uprobe/tracepoint style) held open by processes, printed with the owning pid. If a program appears in `prog show` but in none of these, it is loaded and idle — most likely held alive by a pin under `/sys/fs/bpf`. `ls -R /sys/fs/bpf` plus `bpftool prog show pinned <path>` closes that loop. ## Looking inside ```bash bpftool prog dump xlated id 6 bpftool map dump id 4 ``` `dump xlated` prints the instruction stream *after* the verifier has processed it, with source line and function annotations when BTF is present — enough to tell whether a program is counting events or rewriting packets. `dump jited` shows the native code instead. `bpftool map dump` prints live key/value pairs, which is often the actual data the tool was collecting. ## Practical habits - Add `-p` (pretty JSON) or `-j` when feeding output to `jq`; the plain format is not stable enough to parse. - `bpftool feature probe` reports what the running kernel supports — useful when a colleague's tool refuses to load and you want to know whether the kernel or the tool is at fault. - `bpftool prog tracelog` streams what programs write with `bpf_trace_printk`, saving you from opening the trace pipe yourself. - Programs with `uid 0`, a recent `loaded_at` and no visible attachment on a host you did not configure deserve attention: eBPF is a legitimate tool for security agents and CNI plugins, and equally a place attackers hide. Identify the owner before you remove anything, because detaching a security agent's program is its own incident.
- `bpftool prog show` lists a program but you cannot find any process that owns it. What are the possibilities?Either something else holds a reference or the owning process is simply not reported. Check `/sys/fs/bpf` for a pin, `bpftool link show` for a pinned or kernel-held link, and `bpftool net show` / `bpftool cgroup tree` for attachments the kernel owns. The pid column also depends on kernel support and privilege, so its absence is not proof that no process holds an fd.
- How do you tell from bpftool output how much kernel memory BPF is costing on a host?Sum the `memlock` figures from `bpftool map show` and `bpftool prog show`. Maps dominate, because a hash or array map allocates for `max_entries` up front rather than growing on demand, so one oversized map can account for most of it. Program `memlock` is small by comparison — it is the instruction stream, not data.
- Why is `bpftool prog dump xlated` more readable on some programs than others?Because readability comes from BTF. A program loaded with BTF (`btf_id` present in `prog show`) can be annotated with function names, source line numbers and type information; without it you get raw instructions. That in turn depends on the program having been compiled with `-g` and the loader having passed the BTF to the kernel.
saying these in an interview costs you the question
- Expecting `bpftool prog show` to name the attach point
- Thinking loaded eBPF programs appear in ps output
- Parsing bpftool's plain text output in scripts instead of JSON
- Assuming every attachment is a bpf_link
- Removing an unknown program before identifying its owner