XDP Packet Processing

XDP Fundamentals and Packet Parsing

XDP (eXpress Data Path) - packet processing at the driver level, before entering the kernel stack. The fastest eBPF hook point.

XDP Fundamentals and Packet Parsing

Lab: eBPF XDP Fundamentals

What you will learn in this lab:

  • XDP modes: Generic (test), Native (production), Offload (NIC)
  • XDP actions:
    • XDP_PASS - forward the packet to the kernel stack
    • XDP_DROP - drop the packet (fastest)
    • XDP_TX - send the packet back out the same interface
    • XDP_REDIRECT - redirect to another interface
    • XDP_ABORTED - error, drop the packet + trace
  • struct xdp_md context (data, data_end, data_meta)
  • Ethernet header parsing (struct ethhdr)
  • IPv4/IPv6 header parsing
  • TCP/UDP header parsing
  • ICMP parsing
  • Byte order: bpf_ntohs(), bpf_htons()

Packet Parsing Pattern

SEC("xdp")
int xdp_parser(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;

    if (eth->h_proto == bpf_htons(ETH_P_IP)) {
        struct iphdr *ip = data + sizeof(*eth);
        if ((void *)(ip + 1) > data_end)
            return XDP_PASS;
        // IPv4 packet processing...
    }
    return XDP_PASS;
}

Full parse chain: Ethernet → IP → TCP/UDP

Extending the basic pattern above into a complete L3/L4 parser:

SEC("xdp")
int xdp_full_parse(struct xdp_md *ctx) {
    void *data = (void *)(long)ctx->data;
    void *data_end = (void *)(long)ctx->data_end;

    // L2: Ethernet
    struct ethhdr *eth = data;
    if (data + sizeof(*eth) > data_end)
        return XDP_PASS;

    if (eth->h_proto != bpf_htons(ETH_P_IP))
        return XDP_PASS;  // not IPv4, skip

    // L3: IPv4
    struct iphdr *ip = data + sizeof(*eth);
    if ((void *)(ip + 1) > data_end)
        return XDP_PASS;

    // L4: TCP or UDP
    void *l4 = (void *)ip + (ip->ihl * 4);  // IP header can be variable length

    if (ip->protocol == IPPROTO_TCP) {
        struct tcphdr *tcp = l4;
        if ((void *)(tcp + 1) > data_end)
            return XDP_PASS;
        // tcp->dest has the destination port (network byte order)
        if (tcp->dest == bpf_htons(80))
            return XDP_DROP;  // drop HTTP traffic
    } else if (ip->protocol == IPPROTO_UDP) {
        struct udphdr *udp = l4;
        if ((void *)(udp + 1) > data_end)
            return XDP_PASS;
        // udp->dest has the destination port
        if (udp->dest == bpf_htons(53))
            return XDP_DROP;  // drop DNS traffic
    }

    return XDP_PASS;
}

Notice the pattern: every pointer dereference requires a bounds check against data_end. The verifier enforces this. Skip any check and your program will not load.

xdp-tutorial: packet01-parsing/ - do it yourself!

How to work through xdp-tutorial:

  1. Read README.org first (understand the assignments)
  2. Read xdp_prog_kern.c, inspect parsing_helpers.h
  3. Do the assignments yourself
  4. If you get stuck, check the packet-solutions/ folder

Prerequisite reading: XDP Paper (~15 pages)

Inspect in xdp-tutorial: setup_dependencies.org - dependencies (clang, llvm, libelf, kernel headers, bpftool, libxdp, libbpf).


xdp-tutorial Directory Guide

The xdp-tutorial repository is organized into progressive folders. Use this table to know which folder to study and when.

FolderWhat It TeachesWhen to Use
basic01-xdp-passMinimal XDP program that passes all packetsStart here; first XDP program
basic02-prog-by-nameLoading and attaching XDP programs by section nameRight after basic01
basic03-map-counterUsing BPF maps to count packetsWhen learning maps (Chapter 2+)
basic04-pinning-mapsPinning maps to the BPF filesystem for persistenceAfter basic03, before multi-program setups
packet01-parsingParsing Ethernet, IP, and TCP/UDP headers safelyCore skill; study before building any filter
packet02-rewritingRewriting packet headers (MAC, IP)Needed for load balancer and NAT projects
packet03-redirectingRedirecting packets between interfaces with bpf_redirectLoad balancer and forwarding use cases
tracing01-xdp-simpleTracing XDP events with bpf_printkDebugging any XDP program
tracing02-xdp-perf-eventPerf event output from XDP programsWhen you need structured event output
advanced01-xdp-load-balancerFull XDP load balancer exampleAfter completing packet01-03; compare with your own LB
advanced03-AF_XDPAF_XDP socket for user-space packet processingOptional; only if you need user-space fast path