#server-performance#dedicated-servers

XDP and eBPF for Linux Packet Processing

14 min read - May 27, 2026

hero section cover
Table of contents
  • XDP and eBPF for High-Performance Packet Processing
  • How eBPF and XDP Work Together
  • XDP vs iptables: Performance Benchmarks
  • DDoS Mitigation and Security
  • Tools, Deployment, and Hardware Requirements
  • Getting Started with XDP
Share

How XDP and eBPF process millions of packets per second at the NIC driver level. Benchmarks, DDoS use cases, toolchain setup, and hardware requirements.

XDP and eBPF for High-Performance Packet Processing

XDP (eXpress Data Path) and eBPF (extended Berkeley Packet Filter) let Linux process network packets before the kernel's normal networking stack gets involved. Instead of allocating memory structures for every incoming packet, XDP intercepts traffic right at the NIC driver, decides what to do with it, and either drops, forwards, or redirects it. The result is packet processing at millions of packets per second per core, with a fraction of the CPU overhead of traditional tools like iptables.


 

How eBPF and XDP Work Together

eBPF is a virtual machine inside the Linux kernel. It runs custom bytecode that's been verified for safety (no infinite loops, no unauthorized memory access) and then JIT-compiled to native CPU instructions. Programs are limited in scope. They can't call arbitrary kernel functions, only a set of predefined helpers for tasks like map lookups and packet redirection.

For state management, eBPF uses maps, which are key/value stores (hash tables, arrays, LPM tries) that persist across packet arrivals. Maps are readable and writable from userspace, so you can update blocklists or routing rules without reloading the program.

XDP is an eBPF hook point. It attaches to the NIC driver's receive path, before the kernel allocates an sk_buff structure (the 200-300 byte per-packet metadata object that the traditional networking stack depends on). Skipping that allocation is where the performance gain comes from.

XDP runs in three modes:

  • Native mode: runs inside the NIC driver. Best performance.
  • Offloaded mode: runs on the NIC's ASIC. Frees the CPU entirely.
  • Generic mode: runs after sk_buff allocation. Useful for testing on unsupported hardware, but no performance benefit.

After processing each packet, the XDP program returns a verdict:

VerdictAction
XDP_DROPDiscard the packet at the driver level
XDP_PASSForward to the normal networking stack
XDP_TXSend back out the same interface
XDP_REDIRECTRedirect to another NIC or AF_XDP userspace socket
XDP_ABORTEDDrop due to program error, log a trace event

XDP vs iptables: Performance Benchmarks

The numbers are stark. iptables handles roughly 200,000 packets per second per core. nftables improves that to around 400,000 pps. XDP in native mode processes 10 to 40 million pps per core on the same hardware.

The reason is simple: an XDP_DROP costs one bounds check and a return value. An iptables DROP requires sk_buff allocation, netfilter chain traversal, connection tracking lookup, the DROP action itself, and then deallocation. At 100 Gbps with 64-byte packets, a server faces 148 million packets per second, leaving about 100 nanoseconds per packet. At that scale, sk_buff allocation becomes the bottleneck.

The CPU savings are just as significant. Moving a blocklist from iptables to XDP in one benchmark reduced software interrupt CPU usage from 28% to 3% at 1 million pps. That freed-up headroom can run application processes, databases, or virtual machines on the same server.

DDoS Mitigation and Security

XDP's strongest hosting use case is DDoS mitigation. Because it operates at the driver level, malicious packets are dropped before they touch the kernel's networking stack. A single core running XDP can drop 26 million packets per second.

Cloudflare has used an XDP-based system called L4Drop for volumetric DDoS mitigation since at least 2018. The system processes and drops attack traffic in the XDP context, preventing it from reaching the application layer. Meta's Katran, an open-source XDP Layer 4 load balancer, handles traffic for Facebook and Instagram at over 10 million pps per core.

For dynamic filtering, eBPF maps like BPF_MAP_TYPE_LPM_TRIE let you manage IP blocklists covering individual IPs and CIDR subnets in a single lookup. Updates happen from userspace in real time, no program reload needed. During an active attack, you can push new signatures in milliseconds using bpftool:

bpftool map update id <MAP_ID> key <KEY_VALUE> value <VALUE>

For observability, eBPF collects per-application, per-IP, and per-flow metrics directly from the kernel data path. The xdp_md context provides telemetry like ingress_ifindex and rx_queue_index, so you can identify which interface or queue is under pressure. For long-term monitoring, tools like ebpf_exporter convert raw eBPF map data into Prometheus-compatible metrics for visualization in Grafana.

Tools, Deployment, and Hardware Requirements

The toolchain starts with Clang and LLVM for compiling restricted C into eBPF bytecode. From there, you need a loader library:

  • libbpf: the standard C library for production use. Supports CO-RE (Compile Once, Run Everywhere) for cross-kernel portability.
  • libxdp: XDP-specific, supports running multiple XDP programs on a single interface.
  • cilium/ebpf: a pure Go library for Go-based stacks.

For management, bpftool lets you inspect live programs and map contents. xdp-loader (from the xdp-tools suite) handles loading and unloading. BCC is useful for prototyping with Python/Lua front-ends, but libbpf with CO-RE is the better choice for production.

Enable the BPF JIT compiler before deploying:

sysctl -w net.core.bpf_jit_enable=1

For zero-downtime updates, use the XDP_FLAGS_REPLACE flag to atomically swap a running program. Pin maps to /sys/fs/bpf/ so they persist after the loader exits.

Hardware and Kernel Compatibility

XDP was introduced in kernel 4.8, but 5.x or later is recommended for the full feature set. Check your kernel with uname -r and verify the BPF filesystem exists at /sys/fs/bpf/.

Your NIC driver determines which XDP features are available:

DriverBasic XDPRedirectZero-copy (AF_XDP)
mlx5_coreYesYesYes
i40eYesYesYes
ixgbeYesYesYes
virtio_netYesYesNo
ena (Amazon)YesYesNo

Check your driver with ethtool -i <interface>. If native mode isn't supported, the system falls back to generic mode, which runs after sk_buff allocation and offers no performance benefit.

Disable GRO and LRO before attaching an XDP program, as they conflict:

ethtool -K <iface> gro off lro off

Standard XDP requires packets to fit in a single 4,096-byte memory page. On i40e and ice drivers, the x86 MTU limit is 3,046 bytes.

Getting Started with XDP

Start by assessing your environment. Run uname -r to confirm kernel 4.8+ (5.x preferred), and ethtool -i <interface> to check for native XDP driver support.

Begin with observability, not enforcement. Use eBPF maps to classify and count traffic so you have a baseline of normal activity. Once you understand your traffic patterns, move to enforcement: test with xdpgeneric mode first, then switch to xdpdrv (native) for production.

Keep in mind that XDP handles packet-level filtering, not raw bandwidth. For large-scale attacks at 100 Gbps, pair it with bare-metal infrastructure and BGP FlowSpec to manage upstream traffic before it reaches the server.

If you're running high-traffic workloads that need fast packet filtering, FDC's dedicated servers provide the bare-metal foundation to get the most out of XDP.

Blog

Featured this week

More articles
XDP and eBPF for Linux Packet Processing
#server-performance#dedicated-servers

XDP and eBPF for Linux Packet Processing

How XDP and eBPF process millions of packets per second at the NIC driver level. Benchmarks, DDoS use cases, toolchain setup, and hardware requirements.

14 min read - May 27, 2026

Why it's important to have a powerful and unmetered VPS

3 min read - May 9, 2025

More articles
background image

Have questions or need a custom solution?

icon

Flexible options

icon

Global reach

icon

Instant deployment

icon

Flexible options

icon

Global reach

icon

Instant deployment