XDP DATA PLANE

XDP is a hook in the NIC driver. Here is what we built on it.

XDP runs an eBPF program inside the network driver, before Linux allocates a socket buffer. That is the whole idea. What matters is what you can make it do once it is there — and whether it still holds up with PPPoE termination, carrier-grade NAT, hierarchical QoS and ACLs all switched on at once.

Ours does 50 Mpps per box with every one of those enabled. That is 33.6 Gbps at 64-byte frames, the hardest test there is.

50 Mpps

Full feature set

Engine ceiling per box

33.6 Gbps

At 64-byte frames

The hardest test there is

~975 ns

Full-CGNAT path

Measured per-packet cost

Commodity x86

No appliance

Servers you already buy

What XDP actually is

XDP — eXpress Data Path — is a hook in the Linux kernel that runs an eBPF program in the network driver’s receive path, before the kernel allocates an sk_buff for the packet. Allocating and initialising that structure is most of what the kernel spends on a packet it is going to drop or forward unchanged, so the saving is not marginal.

The program returns one of four verdicts, and the driver acts on it immediately:

  • XDP_DROP — free the buffer and return. Nothing is allocated, nothing is queued. This is why XDP is the natural place for anti-spoof filtering and DDoS mitigation.
  • XDP_PASS — hand the packet on to the normal network stack.
  • XDP_TX — send it back out the interface it arrived on, after whatever the program rewrote.
  • XDP_REDIRECT — send it to another interface, a CPU map, or an AF_XDP socket.

There are three places the program can run. Native mode is inside the driver, which is where the performance is. Generic mode runs after sk_buff allocation — useful for testing, not for a data plane. Offloaded mode runs on the NIC itself, on the few cards that support it.

Everything an XDP program does passes the eBPF verifier before it is allowed to load: bounded loops, no unchecked pointer arithmetic, no unbounded execution. A forwarding program that would fault does not load in the first place. That property is the reason a data plane can be replaced on a running box.

Why in-kernel, and not kernel bypass

DPDK is the obvious alternative and it is a serious piece of engineering. The reason we did not build on it comes down to five structural consequences of taking the port out of the kernel.

01

No core is dedicated

A poll-mode driver spins a core whether or not there are packets. Processor cost is fixed at the worst case. In-kernel, cost tracks offered load — an idle gateway at 04:00 is an idle gateway.

02

Nothing is reserved before start

No hugepage pool to size and lock away before the data plane will run. Packet memory is ordinary kernel memory, which means the box is still a box you can run other things on.

03

The port never leaves the kernel

The interface stays a normal interface. ip, tcpdump, ethtool and your monitoring keep working on it, because nothing bound it away from the kernel.

04

One routing table, not two

A userspace data plane needs its own FIB and its own view of the network, kept in step with the kernel’s. Two tables that must agree is a class of bug that simply does not exist here.

05

Replace the program, keep the sessions

The forwarding program can be swapped on a running data plane. That is what makes shipping a security fix in days instead of at the next line-card refresh a normal operation rather than a maintenance window.

The long version, with the kernel-bypass camp’s own published measurements: XDP vs DPDK — the benchmark everyone quotes has no subscribers in it.

What runs in the one data plane

Not six products chained together. One XDP program, one pass over the packet.

PPPoE and IPoE termination

Subscriber sessions with RADIUS AAA, CoA and QinQ, with every CPU core carrying its share rather than one core owning the control path. vBNG / BRAS

Carrier-grade NAT

Port-block allocation per subscriber, NAT44 with conntrack sized to real sessions, and logging that maps a public IP:port back to a customer. XDP CGNAT

Hierarchical QoS

The plan rate delivered per subscriber, with AQM and L4S underneath so a full line still feels fast. Low latency

ACLs and anti-spoof

Filtering at the subscriber port, in the driver, before the kernel has spent anything on the packet. Edge security

IPv6 transition

Dual-stack, DS-Lite, NAT64 and a stateless MAP-T / MAP-E border relay in the same fast path. NAT64 brief

BGP border routing

Border routing on the same box that terminates subscribers — no separate edge router to licence. Border router brief

Packet rate is the number. Everything else is arithmetic.

Most BNG datasheets quote a headline Gbps and leave out the frame size, which makes the figure unfalsifiable and useless to anyone specifying hardware. The engine ceiling is a packet rate. Bandwidth follows from it and from frame size.

Frame sizeWire bitsAt 50 Mpps
64 B67233.6 Gbps
256 B2,208110.4 Gbps
IMIX ~340 B2,880144.0 Gbps
1500 B12,160608 Gbps — port-capped

One measured constant and visible arithmetic: wire_bits = (frame_bytes + 20) × 8, then Gbps = pps × wire_bits ÷ 1e9. Check it yourself.

Port capacity is not throughput. A box with 400G of ports fitted — two dual-port E810s — does not forward 400 Gbps of 64-byte frames. That would be 595 Mpps, which no x86 software data plane does. Anyone quoting the port number as a forwarding number is quoting the wrong number.

When the network card is the problem

Running in the driver means the driver is yours to fix. When a card misbehaves at line rate, the fix goes into the driver rather than into a support ticket that ends with a firmware release note six months out. Kernel 6.18.2 to 6.18.3 took five days on our fleet. Security fixes ship as software, because there is no line card to refresh.

That is the part of an XDP data plane nobody puts on a datasheet, and it is the part that decides whether the thing survives contact with real hardware.

The briefs behind this page

Bring your own traffic profile.

Tell us subscriber count and busy-hour throughput and we will size it against your numbers, not ours. A proof of concept runs on your own x86 against your own traffic.

Need Solution?

Contact us if you need a solution.