XDP Packet Processing
Program Types, Deep Dive and Debugging
BPF program types, deep dive, and debugging techniques.
BPF Program Types (XDP vs tc)
Source: Cilium BPF Program Types
| XDP | TC | |
|---|---|---|
| Context | xdp_buff | sk_buff |
| Hook point | Driver level | After L2 |
| Speed | Fastest | Slower |
| Direction | Ingress only | Ingress + Egress |
| Actions | XDP_DROP, XDP_PASS, XDP_TX, XDP_REDIRECT, XDP_ABORTED | TC_ACT_OK, TC_ACT_SHOT, TC_ACT_STOLEN, TC_ACT_REDIRECT |
| Modes | Native, Offloaded, Generic | cls_bpf direct-action |
For DDoS Engine: XDP native mode (fastest drop) For DNS Filter: tc egress hook (container policy enforcement)
Inspect in xdp-tutorial: advanced01-xdp-tc-interact - XDP and TC interaction, metadata passing.
Reading: Cilium Network Concepts - XDP and tc integration.
BPF Deep Dive
Source: Cilium BPF Architecture
Read this document after completing the XDP section:
- Instruction Set: 11 registers (r0-r10), 512-byte stack, calling convention
- Helper Functions:
bpf_map_lookup_elem,bpf_xdp_adjust_head, etc. - Maps: All map types (HASH, ARRAY, LPM_TRIE, PROG_ARRAY, etc.)
- Object Pinning:
/sys/fs/bpffilesystem,BPF_OBJ_PIN/BPF_OBJ_GET - Tail Calls: Program chaining,
BPF_MAP_TYPE_PROG_ARRAY - BPF to BPF Calls: Function calls,
always_inlinevs normal - JIT: x86_64, arm64 JIT compiler
- Hardening: JIT constant blinding,
bpf_jit_harden - Offloads: Offload to NIC (Netronome nfp)
- BPF sysctls:
bpf_jit_enable,bpf_jit_harden,unprivileged_bpf_disabled- important: these are the first settings to check when starting with BPF
Debugging and Testing
Source: Cilium BPF Debug & Test
bpftool - inspect loaded programs and maps
# List all loaded BPF programs
$ bpftool prog list
6: xdp name xdp_filter tag 3b185187f1855c4c
loaded_at 2024-01-15T10:30:00+0000 uid 0
xlated 296B jited 184B memlock 4096B
# Dump a map's contents
$ bpftool map dump id 42
key: 0a 00 01 01 value: 00 00 00 05
key: c0 a8 00 01 value: 00 00 00 12
# Show program stats (requires kernel.bpf_stats_enabled=1)
$ bpftool prog profile id 6 duration 5
run_cnt run_time_ns
154231 892041
bpf_printk - debug output from BPF programs
SEC("xdp")
int xdp_debug(struct xdp_md *ctx) {
void *data = (void *)(long)ctx->data;
void *data_end = (void *)(long)ctx->data_end;
struct ethhdr *eth = data;
if (data + sizeof(*eth) > data_end)
return XDP_PASS;
bpf_printk("pkt proto=%x len=%d",
bpf_ntohs(eth->h_proto),
data_end - data);
return XDP_PASS;
}
Read the output:
$ cat /sys/kernel/debug/tracing/trace_pipe
<idle>-0 [001] ..s1 1234.567890: bpf_trace_printk: pkt proto=800 len=74
llvm-objdump - inspect BPF bytecode
$ llvm-objdump -S xdp_prog.o
Disassembly of section xdp:
0000000000000000 <xdp_filter>:
0: r6 = r1 ; save ctx
1: r2 = *(u32 *)(r6 + 0) ; data
2: r3 = *(u32 *)(r6 + 4) ; data_end
3: r4 = r2 + 14 ; data + sizeof(ethhdr)
4: if r4 > r3 goto +8 ; bounds check
When to use: When you hit verifier errors, encounter performance issues, or need to understand program behavior.
Is TC Hook Needed?
Short answer: No. For the DDoS engine, DNS filter, and L4 load balancer projects in this roadmap, XDP is sufficient. You do not need to learn TC (Traffic Control) BPF hooks.
| Aspect | XDP | TC (cls_bpf) |
|---|---|---|
| Hook point | NIC driver, before SKB allocation | After SKB is created, in the qdisc layer |
| Direction | Ingress only | Both ingress and egress |
| Performance | Fastest possible; runs before the kernel network stack | Slower; SKB overhead is already paid |
| Use case fit | DDoS drop, DNS filtering, L4 LB forwarding | Egress shaping, container networking, policy after routing |
| SKB access | No SKB; works with raw xdp_md | Full SKB with metadata, mark, priority |
| When you need it | Whenever you want to filter or redirect at line rate | When you need egress hooks or SKB-level features (e.g., skb->mark) |
Why XDP is enough for this roadmap:
- DDoS mitigation needs fast ingress drop. XDP’s
XDP_DROPis the fastest path. - DNS filtering inspects inbound UDP queries, all ingress, no egress hook needed.
- L4 load balancing forwards packets with
bpf_redirectbefore the kernel allocates an SKB, which is the whole performance advantage. - TC becomes relevant when you need egress policies (e.g., Cilium’s container networking) or need to read SKB metadata. That is outside the scope of this roadmap.
If you later work on container networking or need egress filtering, revisit TC at that point. For now, focus entirely on XDP.