Linux eBPF Program Types & Attach Points
The Linux kernel does not treat all eBPF programs identically. Every eBPF program must declare a specific Program Type (enum bpf_prog_type) in its ELF section header (e.g., SEC("xdp") or SEC("kprobe/sys_execve")).
The program type determines three fundamental characteristics:
- Attach Point: Where in the kernel execution path the program hooks (network driver, system call entry, security check).
- Context Argument: The specific data structure pointer passed to the program's main function (
struct xdp_md *,struct pt_regs *,struct __sk_buff *). - Allowed Helper Functions: The specific subset of kernel BPF helper functions the verifier allows the program to call (e.g. packet editing helpers are allowed in XDP, but forbidden in tracing kprobes).
[ Incoming Network Packet ]
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ 1. XDP (eXpress Data Path) │
│ Executes inside network driver before sk_buff allocation │
│ Actions: XDP_DROP (DDoS mitigation), XDP_TX, XDP_PASS │
└─────────────────────────────────┬────────────────────────────────┘
│ XDP_PASS
▼
┌──────────────────────────────────────────────────────────────────┐
│ 2. TC (Traffic Control - Ingress) │
│ Executes on allocated sk_buff; supports ingress & egress │
└─────────────────────────────────┬────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ 3. Kernel Subsystems: Kprobes, Tracepoints, BPF LSM │
│ Monitors syscalls, kernel internal functions, and security │
└──────────────────────────────────────────────────────────────────┘
Primary eBPF Program Types
1. XDP: eXpress Data Path (BPF_PROG_TYPE_XDP)
XDP delivers the highest networking performance in Linux. It executes at the earliest possible point in the network subsystem—directly inside the network interface card (NIC) driver before the kernel allocates a struct sk_buff (socket buffer) or performs memory copies:
- Section Name:
SEC("xdp") - Context:
struct xdp_md *ctx(raw memory pointersdataanddata_end) - Return Codes:
XDP_DROP: Silently drops packet instantly (ideal for multi-million PPS line-rate DDoS defense).XDP_PASS: Hands packet upward to the standard Linux TCP/IP stack.XDP_TX: Bounces packet back out the same network interface it arrived on.XDP_REDIRECT: Forwards packet to another network interface or into user space via AF_XDP.
2. TC: Traffic Control (BPF_PROG_TYPE_SCHED_CLS)
While XDP operates only on packet ingress, BPF programs attached to the Traffic Control (qdisc) subsystem handle both ingress and egress traffic:
- Section Name:
SEC("tc")orSEC("classifier") - Context:
struct __sk_buff *skb - Capabilities: Can modify packet headers, alter checksums, perform NAT, and redirect packets across network namespaces without passing through intermediate bridges (the foundation of Cilium networking).
3. Kprobes and Kretprobes (BPF_PROG_TYPE_KPROBE)
Dynamic tracing probes attached to arbitrary kernel functions:
kprobe: Fires when entering a kernel function (inspects arguments in CPU registers).kretprobe: Fires when a kernel function returns (inspects return value and execution duration).- Trade-off: Extremely flexible (can trace any non-inlined kernel symbol), but unstable across kernel versions because internal kernel function signatures can change.
4. Tracepoints (BPF_PROG_TYPE_TRACEPOINT)
Static, permanent instrumentation points defined by Linux kernel developers:
- Section Name:
SEC("tracepoint/syscalls/sys_enter_openat") - Advantage over Kprobes: Guaranteed ABI stability. Tracepoint names and argument structures are stable across Linux kernel releases, making them the standard choice for production system monitoring.
5. BPF LSM (BPF_PROG_TYPE_LSM)
Introduced in Linux 5.7, BPF LSM allows developers to attach eBPF programs directly to Linux Security Module (LSM) hooks (like file_open, bprm_check_security, socket_connect):
- Section Name:
SEC("lsm/file_open") - Power: Unlike read-only tracing programs, a BPF LSM program can return negative error codes (such as
-EPERM) to block security violations in real time.
Comprehensive Comparison Matrix
| Program Type | ELF Section Macro | Context Type | Typical Execution Speed | Can Block/Drop? |
|---|---|---|---|---|
| XDP | SEC("xdp") |
struct xdp_md * |
~10–24M packets/sec | Yes (XDP_DROP) |
| TC | SEC("tc") |
struct __sk_buff * |
~2–5M packets/sec | Yes (TC_ACT_SHOT) |
| Tracepoint | SEC("tracepoint/...") |
Static trace struct | Nanoseconds per event | No (Observer only) |
| Kprobe | SEC("kprobe/...") |
struct pt_regs * |
Tens of nanoseconds | No (Observer only) |
| BPF LSM | SEC("lsm/...") |
Specific hook args | Direct syscall overhead | Yes (Returns -EPERM) |
| Socket Filter | SEC("socket") |
struct __sk_buff * |
Layer 4 overhead | Yes (Truncate/Drop) |
Frequently Asked Questions (FAQ)
What is the primary difference between XDP and TC eBPF programs?
XDP runs directly in the network driver before sk_buff allocation for maximum throughput on ingress only, while TC runs after sk_buff allocation and can inspect and modify both ingress and egress packets. For raw packet dropping (DDoS defense), XDP is significantly faster; for complex container routing and egress shaping, TC is required.
Can an eBPF kprobe or tracepoint program prevent a system call from running?
No. Kprobes and tracepoints are strictly passive observability tools; their return values cannot abort or block the calling process. To block unauthorized operations in real time, you must use seccomp (for filtering system call numbers and arguments) or BPF LSM (for enforcing kernel security policies).
What is the advantage of Tracepoints over Kprobes in eBPF?
Tracepoints have stable, guaranteed ABIs across kernel upgrades, whereas Kprobes attach to internal kernel function names and registers that can change or disappear between Linux releases. Production observability agents (like Datadog, Falco, and BCC) prefer tracepoints whenever available to ensure backward compatibility.
Related Topics
- eBPF Overview: Fundamentals of BPF objects, loading, and skeletons.
- The eBPF Verifier: How the kernel validates bytecode safety before execution.
- eBPF Maps: State sharing and ring buffer communication.
- Linux Security Modules (LSM): Architecture of LSM hooks and security enforcement.
