Skip to main content
AF_XDP (Address Family XDP) is a Linux kernel-bypass networking technology that Firedancer uses for high-performance packet processing. This page details the low-level implementation.

What is AF_XDP?

AF_XDP is a Linux API providing kernel-bypass networking through shared memory ring buffers accessible from userspace. Key characteristics:
  • Redirects packets from/to shared memory buffers
  • Hardware-agnostic (unlike DPDK)
  • Can share NIC with Linux networking stack
  • Allows deployment in existing, heterogeneous networks
  • Shared memory region called “UMEM”

XDP (eXpress Data Path)

XDP is a framework for installing hooks (eBPF programs) at an early stage of packet processing:
  • Runs before tc and netfilter
  • eBPF is JIT-compiled bytecode
  • Some hardware/driver combinations offload eBPF to NICs
  • Not to be confused with Solana BPF (sBPF)

Packet Flow Architecture

RX Block Diagram

In XDP_FLAGS_DRV_MODE mode:
  1. NIC receives packet via hardware
  2. Driver passes packet to XDP facility
  3. XDP eBPF program inspects packet:
    • XDP_PASS: Continue to Linux stack (sk_buff, ip_rcv, tc, netfilter)
    • XDP_REDIRECT: Copy to XSK UMEM, allocate RX queue entry
  4. fd_aio backend provides async I/O interface
The XDP_FLAGS_SKB_MODE fallback uses sk_buff-based memory management (still skips most of the generic path) but is more widely available.

TX Block Diagram

  1. fd_aio: Userspace delivers packets to XSK/UMEM buffers
  2. Kernel: Forwards packets to NIC driver
  3. Driver: NIC transmits packets
The application is responsible for maintaining a routing table to resolve layer-3 destination addresses to NICs and layer-2 addresses. Netfilter (iptables, nftables) is not available in the XDP path.

Memory Management

UMEM Overview

The UMEM (Universal Memory) area:
  • Allocated from userspace (recommended: huge pages via fd_util shmem/wksp APIs)
  • Divided into equally sized frames
  • Each frame owned by either userspace or kernel at any time
  • All frames initially owned by userspace

Ring Buffers

Ownership changes and packet events are transmitted via four rings allocated by the kernel (mmap’d to userspace):
The FILL-RX and TX-COMPLETION pairs form two independent cycles. The kernel never moves frames between pairs.

XDP Ring Structure

Ring Descriptor

The kernel-provided descriptor ring memory layout is unstable. Field offsets must be queried using getsockopt(SOL_XDP, XDP_MMAP_OFFSETS) on each join.

Ring Operations

Rings are synchronized via incrementing sequence numbers that wrap at 2^64.
Optimization:
  • Caches producer/consumer sequence numbers
  • Only refreshes from shared memory when potentially empty/full
  • Reduces expensive memory fence operations

XSK Socket Structure

XSK Parameters

Important Flags

XDP_FLAGS_DRV_MODE:
  • Driver mode (fast path)
  • XDP support in NIC driver before sk_buff allocation
  • Best performance
  • Hardware/driver dependent
XDP_FLAGS_SKB_MODE:
  • Socket buffer mode (fallback)
  • Uses Linux sk_buff for memory management
  • Works everywhere
  • Slower than driver mode
XDP_ZEROCOPY:
  • Enables zero-copy I/O
  • UMEM directly accessible to NIC via DMA
  • Requires driver mode
  • Eliminates software packet copies

Zero-Copy I/O

With XDP_FLAGS_DRV_MODE and XDP_ZEROCOPY:
  1. PCIe device initiates DMA write to DRAM
  2. Device driver signals new packet arrival
  3. Kernel XDP passes pointer through to net tile
  4. Net tile identifies recipient app tile
  5. Net tile passes pointer via mcache to app tile
  6. App tile reads packet data directly from UMEM
No software copies from NIC to application!
Firedancer did not initially have zero-copy RX. Changing to zero-copy required less than 500 lines of code changed at the net tile. No changes to app tile code were required. This demonstrates the power of the Tango message queue design.

IOMMU Protection

The UMEM region is shared with hardware: Access permissions:
  • Firedancer app tiles: read-only
  • Firedancer net tiles: read-write
  • Linux kernel: read-write
  • PCIe network devices: read-write (via IOMMU)
The IOMMU (I/O Memory Management Unit):
  • Provides memory protection for DMA
  • Prevents NIC from accessing arbitrary memory
  • Allows zero-copy while maintaining security

Supported Drivers

Well-tested drivers for Firedancer:
AF_XDP works with any Ethernet interface, but driver quality varies:
  • Driver mode support varies by driver
  • Zero-copy support varies by driver
  • Performance characteristics differ
Results may vary across drivers. Popular, well-tested drivers generally have better XDP support and fewer bugs.
Firedancer’s AF_XDP stack integrates with Linux networking via netlink:

Configuration Sources

Interface table: Network interface information Route tables: IPv4 routes from local and main tables Neighbor tables: ARP entries for XDP-enabled Ethernet interfaces

Netbase Shared Memory

The netlink tile maintains a read-only cache (“netbase” workspace) containing:
  • Interface configurations
  • Routing information
  • Neighbor (ARP) entries
Net tiles have read-only access to this shared memory.

ARP Handling

Neighbor discovery (ARP on IPv4):
  1. App tile needs to send to IP address
  2. Net tile checks neighbor table for MAC address
  3. If not found, net tile notifies netlink tile
  4. Netlink tile requests neighbor solicitation via netlink
  5. Kernel broadcasts ARP request
  6. ARP response received, kernel updates neighbor table
  7. Netlink tile updates netbase shared memory
  8. Net tile can now send packet
The netlink tile deduplicates neighbor solicitation requests to prevent flooding from line-rate traffic.

Security Considerations

Required Capabilities

AF_XDP requires:
  • CAP_SYS_ADMIN - System administration
  • CAP_NET_RAW - Raw network access
This is why Firedancer requires root permissions on Linux.

Isolation

The netlink tile isolates itself from untrusted inputs:
  • Separate process with own sandbox
  • Only net tiles can communicate with it
  • Net tiles have read-only access to netbase
  • Malicious netlink tile can compromise net tiles, but not vice versa

XDP Program

Firedancer installs an XDP program on the interface that:
  • Redirects Firedancer traffic to AF_XDP sockets
  • Passes other traffic to Linux stack (XDP_PASS)
  • Unloaded when Firedancer exits
Other applications on the system continue working normally.

Limitations

Monitoring

Packets received and sent via AF_XDP will not appear under standard network monitoring tools like tcpdump.
Use Firedancer’s built-in packet capture facilities instead.

Interface Sharing

  • Firedancer cannot share an interface with other AF_XDP apps
  • May cause performance impact to other apps using Linux networking on shared interfaces
  • Only one external network interface supported (plus loopback)

IPv6

Firedancer does not support IPv6:
  • Practically all Solana traffic uses IPv4 (as of Feb 2025)
  • IPv6 would be more expensive (lower MTU, mandatory UDP checksums, longer addresses)
  • Adding IPv6 support would be straightforward if needed

Performance Characteristics

Target Performance

  • RX throughput: ~20 million packets per second
  • Kernel wake-ups: ~20,000 times per second
  • Busy polling: Net tile never sleeps

Optimizations

Preferred busy polling: Reduces latency by polling more aggressively Zero-copy I/O: Eliminates software copies via DMA Batching: RX and TX processed in batches Cache optimization: Critical structures aligned to cache lines

Future Improvements

  • SO_PREFERRED_BUSY_POLL not yet used
  • IRQ affinity not yet configured
  • NIC interrupts not yet disabled
  • Could reduce RX mcache scaling from O(n*m) to O(max(n,m))
  • tx_free ring probably obsolete (could move COMPLETION→TX directly)