Extended Berkeley Packet Filters (eBPF) have transformed the Linux kernel into a programmable, sandboxed execution environment. Modern observability agents, network load balancers (such as Cilium and Katran), and security enforcement frameworks (such as Tetragon and Falco) inject eBPF bytecode directly into kernel tracepoints, kprobes, and network socket layers. However, when troubleshooting system performance degradation, kernel memory overhead, or rogue network filters, administrators require visibility into exactly which programs and data maps are active in the kernel. The upstream bpftool utility provides the authoritative administrative command-line interface for auditing, dumping, and debugging live eBPF kernel state.
Architecture of eBPF Programs, Maps, and Links
The Linux kernel manages eBPF components through distinct object types:
- eBPF Programs: Sandboxed bytecode verified by the kernel verifier and compiled into native machine instructions via the in-kernel Just-In-Time (JIT) compiler. Common program types include
kprobe,tracepoint,xdp(eXpress Data Path), andcgroup/skb. - eBPF Maps: Generic key-value storage structures resident in kernel memory. Maps allow bidirectional communication and state sharing between user-space daemons and kernel-space eBPF programs. Common map types include
hash,array,lpm_trie, andringbuf. - eBPF Links (bpf_link): Kernel abstractions that pin an eBPF program to an attachment target (such as a network interface or cgroup). When the link object is closed or its file descriptor released, the program automatically detaches unless pinned to the BPF virtual filesystem (
/sys/fs/bpf).
Installing bpftool on Modern Linux Distributions
The bpftool binary is distributed alongside the Linux kernel source tree. Install the toolchain via your distribution’s package manager:
# On Debian, Ubuntu, and derivatives
sudo apt update && sudo apt install -y linux-tools-common linux-tools-generic linux-tools-$(uname -r)
# On Fedora, CentOS Stream, and Rocky Linux
sudo dnf install -y bpftool
# On Arch Linux
sudo pacman -Sy bpf
Verify installation and kernel compatibility by running sudo bpftool version.
Auditing Loaded eBPF Programs
To view all active eBPF programs currently resident in the kernel across all processes, run:
# List all loaded eBPF programs
sudo bpftool prog show
# Query eBPF programs formatted as structured JSON for automation
sudo bpftool prog show --json --pretty
The output presents critical metadata for each active program:
342: sched_cls name egress_filter tag 7a42bc981df9831a gpl
loaded_at 2026-11-07T10:14:22+0000 uid 0
xlated 424B jited 268B memlock 4096B map_ids 112,114
btf_id 84
Key indicators include:
- Program ID (342): The unique runtime identifier assigned by the kernel.
- Type (sched_cls): The attachment class (traffic control classifier).
- xlated / jited: The size of the translated bytecode and the JIT-compiled native assembly in kernel memory.
- map_ids (112, 114): The IDs of the kernel storage maps referenced by this program.
Dumping JIT-Compiled Assembly and Bytecode
To inspect the verified instructions of a loaded program without access to source code:
# Dump the human-readable translated bytecode instructions for program ID 342
sudo bpftool prog dump xlated id 342
# Dump the native CPU assembly instructions emitted by the JIT compiler
sudo bpftool prog dump jited id 342
If the program was compiled with BTF (BPF Type Format) debug information, bpftool interleaves the original C source lines directly within the disassembled instructions.
Inspecting eBPF Maps and Dumping Memory Contents
To audit kernel memory structures created by eBPF applications:
# List all active BPF maps in kernel memory
sudo bpftool map show
# Show detailed metadata for a specific map by ID
sudo bpftool map show id 112
# Dump all key-value entries stored in map 112
sudo bpftool map dump id 112
Dumping map entries enables administrators to view real-time connection tracking records, rate-limiting counters, and telemetry metrics stored directly inside kernel hash tables.
Tracking Pinned Objects in the BPF Virtual Filesystem
Modern service mesh daemons persist eBPF state across process restarts by pinning programs and maps to /sys/fs/bpf:
# Inspect pinned BPF objects across the filesystem
sudo bpftool prog show pinned /sys/fs/bpf/cilium_net_filter 2>/dev/null || ls -la /sys/fs/bpf/
# Pin an active program to the filesystem manually
sudo bpftool prog pin id 342 /sys/fs/bpf/my_custom_filter
Profiling eBPF Execution Performance and CPU Overhead
The Linux kernel can measure the exact CPU time consumed by individual eBPF programs. Enable performance profiling to identify expensive handlers:
# Enable runtime kernel statistics for BPF programs
sudo sysctl -w kernel.bpf_stats_enabled=1
# View program runtime and invocation frequency
sudo bpftool prog show
# Once diagnostics are complete, disable stats to eliminate instrumentation overhead
sudo sysctl -w kernel.bpf_stats_enabled=0
The run_time_ns and run_cnt fields illustrate how many nanoseconds the CPU spent inside the eBPF hook and how many packets or events triggered the program.