Lion Cipher Lab
Drop a packet flood in the kernel with XDP/eBPF (before it ever reaches your app)
- Cyber / Security Engineer
- Advanced
- ~75 min
- Free · no account required
Why it matters
When a volumetric flood hits a Linux box, the expensive part is not the decision to drop a packet — it is everything the kernel does BEFORE it can decide. On the normal path the driver receives the frame, the kernel allocates an sk_buff (the heap structure that represents a packet as it travels up the stack), and the packet climbs through the networking layers until a netfilter hook (where iptables/nftables live) finally runs your DROP rule. Under a real flood you pay that setup cost millions of times a second, and the CPU saturates long before your rules are the bottleneck. XDP (eXpress Data…
What you'll learn
- where XDP sits in the Linux receive path (driver hook, BEFORE sk_buff allocation) and why that beats iptables/nftables for volumetric drop
- writing a minimal XDP program in C from scratch: parsing Ethernet -> IPv4 -> UDP by hand with explicit bounds checks
- compiling BPF bytecode with clang -target bpf and loading it in generic (SKB) mode with `ip link set ... xdpgeneric` — the no-hardware path
- confirming attachment with `ip link show` and `bpftool` and reading which mode (generic/native/offload) you actually got
- generating a UDP flood and MEASURING packets-per-second dropped and CPU load before vs after the filter
- adding a BPF map (per-CPU array) so userspace can read live drop counts and update policy without reloading the program
- the eBPF VERIFIER: what it enforces (bounded loops, provable in-bounds memory), triggering a rejection on purpose, and reading its log
- the judgment of XDP vs nftables vs a scrubbing service, when NOT to use XDP, generic vs native mode, and CO-RE for portability
Steps in this lab
- Where a packet dies matters: the receive path
- eBPF and the verifier: why kernel code you wrote is safe to run
- Build the range: a veth pair, no hardware needed
- Write the XDP filter in C, from scratch
- Compile to BPF bytecode and load in generic mode
- Prove it drops: flood the port and read the counters
- Measure it: pps and CPU, XDP vs the stack
- Add a BPF map: live drop counts, no reload
- Meet the verifier: break it on purpose
- The judgment: XDP vs nftables vs a scrubber, and doing it right