Skip to content

eBPF, XDP & DPDK: Advanced Kernel Networking

Chapter 27: eBPF, XDP & DPDK: Advanced Kernel Networking

Section titled “Chapter 27: eBPF, XDP & DPDK: Advanced Kernel Networking”
  • Understand XDP (eXpress Data Path) and its use cases
  • Know how DPDK enables kernel-bypass networking
  • Write basic XDP programs for packet filtering
  • Understand when to use XDP vs DPDK vs standard networking

eBPF is a revolutionary technology that lets you run custom mini-programs deep inside the Linux kernel, safely and instantly. XDP uses eBPF to inspect and block network packets at lightning speed, before the main operating system even sees them.

27.1 The Kernel Network Path Performance Problem

Section titled “27.1 The Kernel Network Path Performance Problem”
Normal Linux Packet Processing
────────────────────────────────
Packet → NIC DMA → Ring Buffer → Hard IRQ → NAPI Poll (softirq)
→ sk_buff allocation → netfilter → IP routing
→ TCP stack → Socket buffer → Application
Overhead per packet:
• Memory allocations (sk_buff)
• Multiple data copies
• Lock contention at various layers
• Context switches
Maximum theoretical: ~2-5 Mpps per core (10GbE line rate = 14.88 Mpps)
Actual with kernel stack: 1-2 Mpps per core
→ At 10GbE speeds with small packets, kernel can't keep up!
Solutions:
────────────
XDP: Process packets at driver level (before sk_buff allocation)
DPDK: Bypass kernel entirely, poll from user space
io_uring: Async I/O without context switches (network in future)

XDP is an eBPF hook at the earliest point in the network receive path — right at the NIC driver, before the kernel allocates an sk_buff.

XDP Position in Network Stack
───────────────────────────────
NIC Driver
│ DMA (hardware copies packet to memory)
┌──────────────────────────────────┐
│ XDP Hook │ ← Process packet HERE
│ │ (before sk_buff!)
│ XDP_DROP: Drop (fastest) │
│ XDP_PASS: Pass to kernel stack │
│ XDP_TX: Send back on same NIC │
│ XDP_REDIRECT: Send to other NIC │
│ or to AF_XDP socket │
└──────────────────────────────────┘
│ (if XDP_PASS)
sk_buff allocation
Normal kernel network stack
XDP Performance:
• DDoS drop: 26+ Mpps per core (10x faster than iptables!)
• Load balancing: 14+ Mpps
• Uses eBPF → safe, JIT-compiled
// xdp_drop_udp.c — Drop all UDP packets at line rate
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <bpf/bpf_helpers.h>
SEC("xdp")
int xdp_drop_udp(struct xdp_md *ctx) {
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
// Parse Ethernet header
struct ethhdr *eth = data;
if ((void *)(eth + 1) > data_end)
return XDP_PASS;
if (eth->h_proto != __constant_htons(ETH_P_IP))
return XDP_PASS;
// Parse IP header
struct iphdr *ip = (void *)(eth + 1);
if ((void *)(ip + 1) > data_end)
return XDP_PASS;
// Drop UDP packets
if (ip->protocol == IPPROTO_UDP)
return XDP_DROP;
return XDP_PASS;
}
char _license[] SEC("license") = "GPL";
Terminal window
# Compile and load XDP program
clang -O2 -target bpf -c xdp_drop_udp.c -o xdp_drop_udp.o
# Attach to interface (native mode = fastest, uses driver XDP support)
ip link set dev eth0 xdp obj xdp_drop_udp.o sec xdp
# Check it's loaded
ip link show eth0 | grep xdp
# Remove XDP program
ip link set dev eth0 xdp off
# Monitor XDP stats
bpftool prog show
bpftool map show
XDP Production Use Cases
─────────────────────────
DDoS Mitigation (Cloudflare, Facebook):
→ Drop malformed/flood packets at 26Mpps before touching kernel
→ XDP_DROP for packets matching attack signatures
→ Much faster than iptables which allocates sk_buff first
Layer 4 Load Balancing (Facebook Katran, Cilium):
→ XDP_TX: Rewrite packet headers and redirect to backend
→ No connection state required (pure math on packet)
→ 10x better performance than kernel LB
Network Monitoring (sampling):
→ XDP_REDIRECT to AF_XDP socket (zero-copy to user space)
→ Sample 1 in N packets for flow analysis
Kubernetes Service Load Balancing (Cilium):
→ Replace kube-proxy with eBPF/XDP
→ 3-4x reduction in CPU usage for service routing

AF_XDP allows XDP programs to redirect packets directly to a user-space ring buffer (UMEM) without kernel sk_buff allocation.

AF_XDP Architecture
─────────────────────
NIC DMA → UMEM (shared memory, no copy!)
XDP program → XDP_REDIRECT → AF_XDP socket
User-space app reads from UMEM ring
(zero kernel→user copy!)
Performance: ~10-15 Mpps to user space
vs normal socket: ~1-3 Mpps

DPDK (Data Plane Development Kit) bypasses the Linux kernel entirely for maximum network throughput.

DPDK Architecture
──────────────────
Normal Linux:
NIC → Kernel → Kernel buffers → User space (copies!)
DPDK:
NIC → DPDK PMD (poll mode driver) → User space (direct!)
(No interrupts — busy polling)
(No kernel — zero copies)
(Huge pages — no TLB pressure)
Performance:
DPDK: 100+ Mpps per core (for small packets)
Normal: 1-2 Mpps per core
Trade-offs:
✓ Maximum performance (trading systems, telecom, NFV)
✗ Burns an entire CPU core doing busy-polling
✗ Complex programming model
✗ No kernel network stack (must re-implement TCP/IP if needed)
✗ NIC not usable by OS simultaneously
Use Cases:
• Telecom / 5G packet processing
• High-frequency trading (latency < 1μs)
• Network appliances (firewalls, IDS)
• Virtual network functions (VNF)

Choosing the Right Approach
────────────────────────────
┌─────────────────────┬──────────┬──────────┬──────────┐
│ Feature │ Standard │ XDP │ DPDK │
├─────────────────────┼──────────┼──────────┼──────────┤
│ Max PPS per core │ 2 Mpps │ 26 Mpps │ 100 Mpps │
│ Latency │ ~50μs │ ~10μs │ <1μs │
│ Programming model │ Sockets │ eBPF C │ DPDK API │
│ Kernel stack │ Yes │ Optional │ No │
│ Safety (verification│ N/A │ eBPF VM │ None │
│ CPU dedicated │ No │ No │ Yes │
│ Deployment │ Easy │ Medium │ Hard │
└─────────────────────┴──────────┴──────────┴──────────┘
Decision Guide:
─────────────────
< 1Mpps and need standard socket API → Standard Linux
Need fast packet filtering/DDoS protection → XDP
Need very fast packet switching/LB → XDP
Need <1μs latency or >10Mpps to user space → DPDK
Kubernetes networking → eBPF/Cilium (uses XDP)

Q1: What is XDP and how does it achieve 26 Mpps packet processing?

Answer: XDP (eXpress Data Path) hooks an eBPF program into the NIC driver at the earliest possible point — before the kernel allocates an sk_buff structure for the packet. This is the key optimization: sk_buff allocation is expensive (memory allocation, cache misses). By dropping, forwarding, or redirecting the packet before sk_buff is allocated, XDP avoids the bulk of Linux network stack overhead. The eBPF program is JIT-compiled to native CPU code by the kernel. At 26 Mpps, XDP processes packets faster than iptables (which requires sk_buff to exist). Real-world use: Cloudflare uses XDP to mitigate DDoS at line rate (10GbE = 14.88 Mpps of 64-byte packets).

Q2: When would you use DPDK vs XDP?

Answer: Use XDP when: you need fast packet filtering/dropping (DDoS), layer 4 load balancing, or network monitoring — and you want to keep using the Linux kernel network stack for other traffic. XDP runs in the kernel (safe, verified eBPF), is easy to deploy, and can coexist with normal networking. Use DPDK when: you need absolute maximum performance (< 1μs latency, 100+ Mpps), and you’re building a network appliance, telecom application, or high-frequency trading system that can dedicate entire CPU cores to network processing. DPDK bypasses the kernel entirely, which gives maximum performance but requires dedicating cores and building your own packet processing pipeline.


TechnologyHook PointMax PerfUse Case
iptablesAfter sk_buff~1 MppsGeneral firewall
XDPBefore sk_buff26 MppsDDoS, LB, monitoring
AF_XDPAfter XDP15 MppsUser-space packet processing
DPDKNo kernel100 MppsTelecom, HFT, NFV

Chapter 1 (Linux Architecture), Chapter 11 (Network Tuning).


Advantages: Safely extends kernel functionality without reboots, insane packet processing speed. Disadvantages: Requires writing C code, verifier is strict and will reject complex loops.


  • Trying to write complex stateful logic in XDP — XDP is for fast, simple packet processing; complex logic should be handled higher in the stack.
  • Ignoring the verifier — eBPF programs must be provably safe; loops must be bounded.
  • Using generic XDP (SKB mode) and expecting bare-metal performance — it runs after SKB allocation, losing much of the XDP speed advantage.

SymptomCauseDiagnosisFix
eBPF program fails to loadVerifier rejected the programRead the verifier log outputFix bounded loops, out-of-bounds accesses, or invalid memory reads
XDP program drops all packetsLogic error returning XDP_DROPAdd bpf_printk statements and read /sys/kernel/debug/tracing/trace_pipeReview packet parsing logic; ensure XDP_PASS is returned for legitimate traffic

Objective: Run a basic eBPF trace.

Terminal window
# 1. Install bcc-tools or bpftrace
# sudo apt install bpfcc-tools bpftrace
# 2. Trace execution of new processes
sudo execsnoop-bpfcc
# or: sudo bpftrace -e 'tracepoint:syscalls:sys_enter_execve { printf("%s\n", str(args->filename)); }'
# 3. Trace slow block I/O
sudo biosnoop-bpfcc

  1. Use bpftrace to count the number of system calls made by a specific process ID over 10 seconds.
  2. Review the source code of the tcpconnect BCC tool to understand how it hooks into the kernel’s TCP stack.

  • eBPF allows running sandboxed programs in the kernel without changing kernel source code.
  • XDP (eXpress Data Path) hooks into the network stack at the lowest level, before SKB allocation, enabling high-performance packet dropping or forwarding.
  • The verifier ensures eBPF programs cannot crash the kernel or access unauthorized memory.
  • BCC and bpftrace are standard frontends for using eBPF tools.

  • BPF Performance Tools by Brendan Gregg
  • eBPF.io documentation


Last Updated: July 2026