Skip to content

eBPF and XDP: Ultra-Fast Packet Processing and DDoS Protection in Linux

Modern Linux networking is no longer limited to iptables, nftables, or traditional firewalls. With eBPF and XDP, we can inspect, filter, and drop packets before they even enter the kernel networking stack.

This allows us to build:

  • High-performance firewalls
  • DDoS mitigation
  • IP blocking at line rate
  • Packet statistics and monitoring
  • Load balancers and custom network logic

All of this without kernel modules and without touching the kernel source code.

In this article, we’ll cover:

  • What eBPF is
  • What XDP is and why it’s insanely fast
  • How packets normally flow vs XDP path
  • Writing a simple XDP program to block IP addresses
  • Using XDP as a DDoS protection layer

What is eBPF?

eBPF (extended Berkeley Packet Filter) is a virtual machine inside the Linux kernel.

You can load small programs into the kernel safely, and they can:

  • Inspect packets
  • Collect metrics
  • Modify behavior
  • Make decisions at runtime

eBPF programs are:

  • Verified by the kernel (safe, no crashes)
  • JIT compiled (very fast)
  • Attached to hooks (network, tracepoints, syscalls, etc.)

What is XDP?

XDP (eXpress Data Path) is a hook in the earliest point of the Linux network stack — inside the network driver.

That means packets are processed:

Before iptables
Before conntrack
Before the kernel networking stack
Before Kubernetes, Docker, anything

Normal packet path

NIC  Driver  Kernel Stack  Netfilter  Userspace

With XDP

NIC  XDP  (DROP or PASS)

This is why XDP can handle millions of packets per second per core.

XDP Actions

An XDP program returns one of these:

ActionMeaning
XDP_PASSLet packet continue
XDP_DROPDrop packet immediately
XDP_TXSend packet back out
XDP_REDIRECTSend to another interface/CPU

For firewall/DDoS protection, we mostly use:

XDP_DROP

Example 1 – Block traffic by IP using XDP

To compile, load, and attach XDP programs (and use the tools we’ve been using) on Linux, you need these packages.

Debian / Ubuntu

sudo apt-get update

sudo apt-get install -y \
  clang \
  llvm \
  libbpf-dev \
  make \
  linux-headers-$(uname -r)

We’ll write a minimal XDP program that drops packets from a specific IP.

xdp_block_ip.c

#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <bpf/bpf_helpers.h>

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

    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;

    struct iphdr *ip = data + sizeof(struct ethhdr);
    if ((void *)(ip + 1) > data_end)
        return XDP_PASS;

    // Block this IP: 1.2.3.4
    if (ip->saddr == __constant_htonl(0x01020304))
        return XDP_DROP;

    return XDP_PASS;
}

char _license[] SEC("license") = "GPL";

Compile the program

clang -O2 -target bpf -c xdp_block_ip.c -o xdp_block_ip.o

Attach to interface

ip link set dev eth0 xdp obj xdp_block_ip.o sec xdp

Check:

ip -details link show eth0

Now all packets from 1.2.3.4 are dropped before reaching iptables.

Why this is much faster than iptables?

iptables works after:

  • Packet allocation
  • Conntrack
  • Routing decision
  • Kernel networking stack

XDP drops packets at driver level – almost zero CPU cost.

Example 2 – Dynamic IP Block List with BPF Map

Hardcoding IPs is useless for real life. Instead, we use a BPF map.

xdp_ddos_protect.c

#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <bpf/bpf_helpers.h>

struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 1024);
    __type(key, __u32);
    __type(value, __u8);
} blocked_ips SEC(".maps");

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

    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;

    struct iphdr *ip = data + sizeof(struct ethhdr);
    if ((void *)(ip + 1) > data_end)
        return XDP_PASS;

    __u8 *blocked = bpf_map_lookup_elem(&blocked_ips, &ip->saddr);
    if (blocked)
        return XDP_DROP;

    return XDP_PASS;
}

char _license[] SEC("license") = "GPL";

Load program

ip link set dev eth0 xdp obj xdp_ddos_protect.o sec xdp

Add IPs to block list dynamically

Find map id:

bpftool map list

Add IP:

bpftool map update id <MAP_ID> key 0x01020304 value 0x1

Now you can block IPs in real time without reloading the program.

Using XDP for DDoS protection

With XDP you can implement:

1. SYN flood protection

Drop excessive SYN packets per IP.

2. Rate limiting per IP

Use a map to count packets and drop if threshold exceeded.

3. Drop malformed packets

Check headers and drop garbage traffic.

4. Block entire subnets

Mask IP and drop ranges.

5. Early packet validation

Drop non-TCP/UDP/ICMP traffic instantly.

This is exactly how Cloudflare, Facebook, and Cilium protect their infrastructure.

Example logic for simple rate limiting (concept)

  • Map: IP → packet counter
  • If counter > threshold in short time → XDP_DROP

This stops:

  • UDP floods
  • SYN floods
  • Bot traffic

Before kernel even sees it.

Performance

Typical numbers on modern NIC:

MethodPackets/sec/core
iptables~200k
nftables~400k
XDP5–20 million

That’s why XDP is used in production at hyperscale.

Where XDP shines in Kubernetes

  • Protect Kubernetes nodes from DDoS
  • Protect Ingress/LoadBalancer
  • Replace iptables rules with eBPF logic
  • Used internally by Cilium CNI

Detach XDP

ip link set dev eth0 xdp off

Conclusion

eBPF + XDP turns Linux into a high-performance programmable firewall.

You can:

  • Block IPs at line rate
  • Mitigate DDoS
  • Inspect traffic without performance loss
  • Build advanced networking logic safely

And all of this runs inside the kernel with no kernel modules.

If you work with Kubernetes, high-traffic APIs, or public services – learning XDP is a game changer.

Next step ideas

  • XDP rate limiter implementation
  • XDP + Prometheus metrics
  • XDP load balancer
  • How Cilium uses XDP internally
Published inLinuxMonitoringScriptSecurity