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

XDPTC
Contextxdp_buffsk_buff
Hook pointDriver levelAfter L2
SpeedFastestSlower
DirectionIngress onlyIngress + Egress
ActionsXDP_DROP, XDP_PASS, XDP_TX, XDP_REDIRECT, XDP_ABORTEDTC_ACT_OK, TC_ACT_SHOT, TC_ACT_STOLEN, TC_ACT_REDIRECT
ModesNative, Offloaded, Genericcls_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/bpf filesystem, BPF_OBJ_PIN/BPF_OBJ_GET
  • Tail Calls: Program chaining, BPF_MAP_TYPE_PROG_ARRAY
  • BPF to BPF Calls: Function calls, always_inline vs 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.

AspectXDPTC (cls_bpf)
Hook pointNIC driver, before SKB allocationAfter SKB is created, in the qdisc layer
DirectionIngress onlyBoth ingress and egress
PerformanceFastest possible; runs before the kernel network stackSlower; SKB overhead is already paid
Use case fitDDoS drop, DNS filtering, L4 LB forwardingEgress shaping, container networking, policy after routing
SKB accessNo SKB; works with raw xdp_mdFull SKB with metadata, mark, priority
When you need itWhenever you want to filter or redirect at line rateWhen 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_DROP is the fastest path.
  • DNS filtering inspects inbound UDP queries, all ingress, no egress hook needed.
  • L4 load balancing forwards packets with bpf_redirect before 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.