Linux eBPF Datapath Architecture: XDP vs tc (Traffic Control) Packet Processing Mechanics
A systems engineering comparison of Linux eBPF networking hooks, contrasting early driver-level XDP processing with sk_buff metadata handling in tc (traffic control) ingress and egress filters.
Written by: TrendSpike Engineering Desk | Published: October 11, 2026 | Subsystem: Linux Kernel Networking (eBPF)
High-throughput Linux networking systems—including edge proxies, load balancers, and Kubernetes networking platforms—can use eBPF (extended Berkeley Packet Filter) to inspect and process packets in the kernel. Two important attachment points are XDP (eXpress Data Path) and tc (Traffic Control). Both can run eBPF programs, but they operate at different stages of packet processing and expose different contexts and capabilities.
The practical choice depends on the workload, required metadata, traffic direction, network driver support, and measured performance. XDP is often a strong choice for early packet filtering and redirection, while tc is useful for policies that need the socket-buffer context, ingress and egress processing, or integration with Linux traffic-control facilities.
1. Where XDP and tc Fit in the Network Datapath
The most important distinction is when the program runs in the packet's processing path.
- XDP in native driver mode: The XDP program normally runs on received packets in the network driver's receive path, before the usual
struct sk_buff(skb) is created. The BPF program receives astruct xdp_mdcontext. The kernel uses internal structures such asstruct xdp_buffto represent the packet at this stage. - XDP in generic mode: Generic XDP can run when native driver support is unavailable, but it operates later in the receive path, after an skb has been allocated. Consequently, it does not provide the same early-processing advantage as native XDP.
- tc ingress: A tc BPF program generally runs after the incoming packet has an skb representation. It receives a
struct __sk_buffcontext that exposes verifier-approved packet and metadata fields and supports applicable BPF helpers. - tc egress: tc can also process outgoing packets. This makes it useful for egress policy, classification, and traffic-control tasks that a standard XDP receive hook does not directly provide.
Native XDP can avoid the cost of creating an skb for packets it drops or redirects early. However, actual throughput and CPU savings depend on the driver, packet size, workload, configuration, and chosen actions. Generic XDP and tc should not be assumed to have identical performance characteristics to native XDP.
2. Packet Context and Metadata: XDP vs. tc
The contexts exposed to each BPF program influence which packet information and operations are available.
- XDP packet access: An XDP program typically uses the
dataanddata_endfields ofstruct xdp_mdto inspect packet bytes safely. It can parse supported packet headers and use XDP helpers to drop, transmit, or redirect packets. The internalxdp_buffis a kernel data structure, not the ordinary context type passed to a standard XDP BPF program. - tc packet access: A tc BPF program receives a
struct __sk_buffcontext. Depending on the program type, kernel version, and available helpers, it can access or modify supported skb fields, inspect packet data, use packet marks, and perform actions such as redirecting traffic. - Metadata is not universally available: Information such as hardware receive timestamps, receive hashes, VLAN information, or connection-tracking state is not automatically available in every program. Access depends on the relevant helper, kernel support, driver capabilities, configuration, and hook location.
- XDP-to-tc metadata sharing: An XDP program can reserve space in the packet's metadata area and write application-defined information there. A later tc BPF program can read that metadata when the packet follows a compatible path, such as XDP passing it into the normal stack. The two programs must agree on the metadata format, and the required driver and kernel support must be present.
Therefore, tc often offers a richer skb-based networking context, while native XDP offers an earlier opportunity to act on received packets. Neither hook should be described as having every possible piece of packet metadata in every environment.
3. Packet Direction and Action Models
The two systems use different return-code conventions.
XDP actions
XDP_DROP: Drops the received packet without passing it into the normal network stack.XDP_PASS: Allows the packet to continue into the normal networking path, where an skb is created as needed.XDP_TX: Requests transmission of the packet back through the same network interface.XDP_REDIRECT: Requests redirection through a supported target, such as a device map, CPU map, or AF_XDP socket map. The precise path and capabilities depend on the target and device support.XDP_ABORTED: Indicates an exceptional or error path. It is not a normal forwarding verdict.
The standard XDP hook discussed here is primarily for received packets. XDP_TX and XDP_REDIRECT can send packets toward a transmission path, but that does not make the standard XDP receive hook a general replacement for tc egress processing.
tc BPF actions
TC_ACT_OK: Allows processing to continue according to the applicable tc hook and configuration.TC_ACT_SHOT: Drops the packet.TC_ACT_REDIRECT: Requests redirection to a supported destination.TC_ACT_RECLASSIFY: Requests that the packet be classified again through the applicable traffic-control path.
These tc return codes are used in the direct-action BPF classifier model. The exact behavior depends on how the BPF filter is attached and configured. XDP action codes and tc action codes are not interchangeable.
4. Production Use Cases
Production systems can use XDP and tc together rather than treating them as mutually exclusive choices.
- Early packet filtering and DDoS mitigation: Native XDP can drop unwanted traffic before skb allocation, helping reduce host processing costs for traffic that can be identified at that stage. Rate limiting and attack mitigation require appropriate policy and state management. TCP SYN cookies are a separate kernel mechanism and should not be described as automatically provided by an XDP program.
- Layer 4 load balancing: XDP can parse packet headers and use supported redirect or transmit actions to implement high-performance forwarding. Meta's Katran is a well-known example of an XDP-based Layer 4 load balancer. Encapsulation, routing decisions, and transmission behavior depend on the implementation.
- Kubernetes networking: eBPF-based networking systems, including Cilium, use kernel hooks to implement networking and security functions. The exact mix of XDP, tc, and other hooks varies with the feature, configuration, and software version.
- Egress policy and traffic control: tc is useful when policies need outgoing-packet processing, skb-based information, classification, or integration with Linux queuing disciplines. A BPF classifier can participate in a traffic-control configuration, but bandwidth shaping and fair queuing depend on the relevant qdiscs and configuration—not on the BPF program alone.
5. Performance: What to Measure
There is no universal performance number that applies to every XDP or tc deployment. A meaningful comparison should use the same hardware, kernel, packet mix, traffic rate, and policy logic wherever possible.
Useful measurements include:
- Packets per second and throughput under representative packet sizes.
- CPU utilization and per-packet processing cost.
- Packet drops, redirect failures, and other error counters.
- Latency under normal load and during traffic bursts.
- Driver support and whether XDP is running in native or generic mode.
- The overhead of parsing, map lookups, state tracking, and redirect targets.
For early filtering of received traffic, native XDP is often worth benchmarking first. For policies that require egress processing or richer skb context, tc may be the more suitable starting point. Measure the actual deployment rather than assuming that one hook is always faster.
Conclusion
XDP and tc solve related but different problems in Linux networking. Native XDP can act early on received packets and avoid skb allocation for packets that are dropped or redirected. tc provides ingress and egress attachment points and a packet context suited to many classification, policy, and traffic-control tasks.
The right design depends on the required packet direction, available metadata, driver and kernel support, and operational needs. In high-throughput systems, the strongest architecture may use XDP for early decisions and tc for later processing, with explicit metadata handling where necessary.
Sources and Official References
- Linux Kernel Documentation: BPF
- Linux Kernel Documentation: AF_XDP
- Linux Kernel Documentation: BPF Redirect
- Linux Kernel Documentation: XDP RX Metadata
- XDP Project: XDP Tutorial and Examples
- Linux Manual: tc-bpf(8)
- Cilium: eBPF-based Networking and Security
- Katran: XDP-based Layer 4 Load Balancer
Disclaimer: This article is for technical and educational purposes. Kernel behavior, supported helpers, driver capabilities, and performance vary by Linux version and deployment. Verify support and benchmark representative workloads before using these techniques in production.
TrendSpike Editorial Team
Staff Research & Technical AnalysisIndependent research covering distributed cloud systems, modern enterprise software engineering, and macro-financial policy. Our technical and financial analyses reference primary documentation, official regulatory filings, and benchmark architectures.