Samples Index¶
All samples live under
bpf-samples/src/main/java/me/bechberger/ebpf/samples/.
Samples marked Y in the reference-quality column below are ≤ ~80 lines,
cover a single concept, and are suitable as starting points or --8<-- doc
includes.
Selection guide¶
| I want to… | Start with |
|---|---|
| Observe syscalls | HelloWorld |
| Drop / pass packets at the driver | XDPDropEveryThirdPacket |
| Log network events (XDP + TC) | PacketLogger |
| Filter by IP address | demo/BlockHTTP |
| Block egress by cgroup | CGroupBlockHTTPEgress |
| Use a hash map | HashMapSample |
| Stream events to userspace | RingSample |
| Attach to multiple kernel functions | KProbeMultiCounter |
| Intercept / redirect file opens | demo/ForbiddenFile |
| Deny access via LSM | demo/ForbiddenFile2 |
| Profile CPU with stack traces | CPUProfiler |
| Write a kernel-side scheduler | sched/MinimalScheduler |
| Write a userspace scheduler | sched/RustlandFifoSample |
| Register a TCP congestion algorithm | HelloCubicSample |
Reference-quality samples¶
| Sample | Hook | What it demonstrates | Blog post |
|---|---|---|---|
| HelloWorld | SystemCallHooks (openat2) | Minimal hello-world tracepoint logging filename on openat2 | |
| LogOpenAt2Calls | SystemCallHooks (openat2) | Reads openat2 args with bpf_probe_read_kernel and getCurrentComm | |
| SyscallCounter | raw_tracepoint (sys_enter) | Counts all syscalls over 5 s using a global variable | |
| SyscallProgramDemo | SEC("syscall") / BPF_PROG_TEST_RUN | Invokes a BPF_PROG_TEST_RUN syscall program to add two integers | |
| HashMapSample | SystemCallHooks (openat2) | Counts openat2 calls per process name using BPFHashMap | |
| RingSample | SystemCallHooks (openat2) | Streams filename+pid events to userspace via BPFRingBuffer | |
| HelloArrayOfMaps | raw_tracepoint (sys_enter) | ARRAY_OF_MAPS with per-slot syscall count inner hash maps | |
| PerCpuInnerMapSample | raw_tracepoint (sys_enter) | HASH_OF_MAPS keyed by CPU id for contention-free syscall counting | |
| PacketCountByLength | XDPHook | Counts XDP packets by length using XDPContext ergonomic API | |
| XDPDropEveryThirdPacket | XDPHook | Drops every third incoming packet with a BPFFunction helper | |
| TCDropEveryThirdOutgoingPacket | TCHook | Drops ~1/3 of outgoing packets using TC egress with Park-Miller RNG | |
| TCFirewall | TCHook, BasePacketParser | Blocks ingress traffic on ports specified at runtime via BPFHashMap | |
| CGroupBlockHTTPEgress | CGroupHook | Blocks all cgroup egress HTTP traffic | |
| LSMDemo | @LSM (file_open, bpf, socket_create) | Observes three LSM hooks and counts events with global variables | |
| KProbeMultiCounter | @KProbeMulti | Attaches one program to 20 syscall entries using kprobe.multi | |
| TailCallDemo | XDPHook, BPFProgArray | XDP tail calls with manual BPFProgArray slot registration | |
| HelloCubicSample | struct_ops (TcpCongestionControl) | Minimal TCP congestion control algorithm registered as struct_ops | |
| FeatureProbeSample | none (pure Java) | Prints kernel version and feature-probe table using Features API | |
| TimerDemo | XDPHook, @BPFTimer | Self-rearming 1-second BPF timer armed on first incoming XDP packet | |
| demo/HelloWorld | SystemCallHooks (openat2) | Minimal hello-world openat2 tracepoint (tutorial version) | |
| demo/Sample | SystemCallHooks (openat2) | Prints filename argument on every openat2 call | |
| demo/MapSample | SystemCallHooks (openat2) | Counts opens per process with BPFHashMap storing name+count struct | |
| demo/RingSample | SystemCallHooks (openat2) | Logs filenames to ring buffer via BPFRingBuffer | |
| demo/GlobalVariableSample | SystemCallHooks (openat2) | Counts openat2 calls using a single GlobalVariable counter | |
| demo/BlockHTTP | XDPHook | Drops incoming packets on HTTP port using BasePacketParser helper | |
| demo/ForbiddenFile | SystemCallHooks (openat2) | Redirects /tmp/forbidden opens to empty path via bpf_probe_write_user | |
| demo/ForbiddenFile2 | @LSM (file_open) | Denies opens of /tmp/forbidden with EACCES using @LSM annotation | |
| demo/XDPDropEveryThirdPacket | XDPHook | Drops every third packet with a BPFFunction helper and GlobalVariable | |
| sched/MinimalScheduler | sched_ext (SchedulerBase) | Absolute-minimum FIFO sched_ext scheduler using SchedulerBase | |
| sched/FCFSScheduler | sched_ext (SchedulerBase) | First-come-first-served scheduler with no preemption (slice=-1) | |
| sched/RunnableScheduler | sched_ext (SchedulerBase) | FIFO scheduler demonstrating runnable() callback and extra_flags | |
| sched/PrevCpuScheduler | sched_ext (Scheduler) | Cache-warmth scheduler preferring task's previous CPU | |
| sched/PerCpuSchedulerSample | sched_ext (PerCpuSchedulerBase) | Minimal PerCpuSchedulerBase demo with per-CPU and shared fallback DSQs | |
| sched/TaskStorageScheduler | sched_ext (SchedulerBase), BPFTaskStorage | FIFO scheduler tracking per-task wakeup counts with BPFTaskStorage | |
| sched/RustlandFifoSample | UserspaceScheduler | Minimal FIFO userspace scheduler baseline | |
| HttpUtil | none (pure Java utility) | URL query-string parser used by FirewallSpring controller |
All samples¶
Tracepoint / syscall¶
| Sample | Purpose |
|---|---|
| HelloWorld | Minimal openat2 tracepoint; prints filename |
| LogOpenAt2Calls | Reads openat2 args; logs comm and filename |
| SyscallCounter | Counts all syscalls over 5 s |
| SyscallProgramDemo | Invokes a BPF_PROG_TEST_RUN syscall program |
| HashMapSample | Counts openat2 calls per process name with BPFHashMap |
| RingSample | Streams filename+pid events via BPFRingBuffer |
| HelloArrayOfMaps | ARRAY_OF_MAPS with per-slot inner hash maps |
| PerCpuInnerMapSample | HASH_OF_MAPS for contention-free per-CPU syscall counting |
| demo/HelloWorld | Minimal openat2 tracepoint (tutorial version) |
| demo/Sample | Prints filename on every openat2 call |
| demo/MapSample | Counts opens per process with BPFHashMap |
| demo/RingSample | Logs filenames to ring buffer |
| demo/GlobalVariableSample | Counts openat2 calls using GlobalVariable |
| demo/ForbiddenFile | Redirects /tmp/forbidden via bpf_probe_write_user |
XDP¶
| Sample | Purpose |
|---|---|
| PacketLogger | Logs incoming packets (XDP) and outgoing (TC) to ring buffer |
| PacketCountByLength | Counts packets by length using XDPContext API |
| XDPDropEveryThirdPacket | Drops every third incoming packet |
| XDPPacketFilter | Blocks packets from specified IPs (legacy C-string version) |
| XDPPacketFilter2 | Blocks packets from specified IPs (compiler-plugin version) |
| Firewall | Full firewall with per-IP rules, LRU log, and ring-buffer events |
| FirewallSpring | Spring Boot REST front-end managing the Firewall BPF program |
| HelloTailCall | 3-stage XDP tail-call chain via @BPFTailCallTable |
| TailCallDemo | XDP tail calls with manual BPFProgArray slot registration |
| TimerDemo | Self-rearming 1-second BPF timer on first XDP packet |
| demo/BlockHTTP | Drops incoming packets on HTTP port |
| demo/XDPDropEveryThirdPacket | Drops every third packet with BPFFunction and GlobalVariable |
TC / CGroup¶
| Sample | Purpose |
|---|---|
| TCDropEveryThirdOutgoingPacket | Drops ~1/3 of outgoing packets via TC egress with Park-Miller RNG |
| TCFirewall | Blocks ingress traffic on ports specified at runtime |
| CGroupBlockHTTPEgress | Blocks all cgroup egress HTTP traffic |
kprobe / uprobe¶
| Sample | Purpose |
|---|---|
| KProbeMultiCounter | Attaches one program to 20 syscall entries using kprobe.multi |
| JvmGcPauseTracer | Traces JVM GC pauses via uprobes on libjvm.so |
| sched/LockHolderBoostUprobes | Uprobe companion for LockHolderBoostScheduler |
LSM¶
| Sample | Purpose |
|---|---|
| LSMDemo | Observes file_open, bpf, socket_create hooks; counts events |
| demo/ForbiddenFile2 | Denies opens of /tmp/forbidden with EACCES |
struct_ops¶
| Sample | Purpose |
|---|---|
| HelloCubicSample | Minimal TCP congestion control algorithm as struct_ops |
sched_ext (kernel-side)¶
| Sample | Purpose |
|---|---|
| sched/MinimalScheduler | Absolute-minimum FIFO scheduler (SchedulerBase) |
| sched/FCFSScheduler | First-come-first-served, no preemption |
| sched/SimpleScheduler | scx_simple port with FIFO and weighted vtime modes |
| sched/VTimeScheduler | Weighted virtual-time fair scheduler |
| sched/PriorityScheduler | 5-queue weight-based priority scheduler (scx_qmap port) |
| sched/LotteryScheduler | Lottery scheduler with random time-slice dispatch bias |
| sched/BoostedScheduler | Priority-boost for shared-cache-hot tasks |
| sched/ChaosScheduler | Concurrency-fuzzing chaos scheduler for stress-testing |
| sched/CPU0Scheduler | Pins all tasks to CPU 0 |
| sched/CentralScheduler | Central-CPU dispatcher with shared global DSQ |
| sched/DeadlineScheduler | Earliest-Deadline-First with per-task virtual deadlines |
| sched/FlowScheduler | Budget-driven starvation-free tier scheduler (scx_flow port) |
| sched/NestScheduler | CPU-nesting topology-aware scheduler |
| sched/RunnableScheduler | FIFO demonstrating runnable() callback |
| sched/PrevCpuScheduler | Cache-warmth scheduler preferring previous CPU |
| sched/PerCpuSchedulerSample | Minimal PerCpuSchedulerBase demo |
| sched/TaskStorageScheduler | FIFO with per-task wakeup counts via BPFTaskStorage |
| sched/SMTPairScheduler | SMT-pair topology-aware scheduler |
| sched/LockHolderBoostScheduler | Priority-inheritance scheduler using shared BPF maps |
| SampleScheduler | Full scx_simple port with vtime and FIFO modes plus stats |
Userspace scheduler¶
| Sample | Purpose |
|---|---|
| sched/RustlandFifoSample | Minimal FIFO userspace scheduler baseline |
| sched/WeightedRRSample | Weighted round-robin with per-pid debt tracking |
| sched/LotterySample | Lottery scheduler with weight-proportional CPU placement |
Diagnostics / utilities¶
| Sample | Purpose |
|---|---|
| CPUProfiler | CPU profiler using perf-event sampling and stack-trace symbolisation |
| StackSymbolizer | Translates raw instruction pointers to symbols via kallsyms and ELF |
| FeatureProbeSample | Prints kernel version and feature-probe table |
| HttpUtil | URL query-string parser used by FirewallSpring |