On this page

eBPF Program Types

Coverage: All BPF_PROG_TYPE → Attach Points → Context → Available Helpers → Use Cases → Kernel Implementation Details

Program Type Overview

Each program type defines: where to attach, the context parameter type, and the whitelist of available helper functions.

TypeAttach PointContextPurpose
XDPNetwork driver NAPI pollxdp_mdDDoS/Load Balancing (earliest touchpoint)
SCHED_CLSTC ingress/egress__sk_buffFirewall/Cilium
SCHED_ACTTC action__sk_buffPacket modification/Redirection
KPROBEkprobe (function entry)pt_regsObservability
TRACEPOINTtracepointtracepoint-specific structEvent tracing
PERF_EVENTperf_event_openbpf_perf_event_dataPerformance sampling
CGROUP_SKBcgroup egress/ingress__sk_buffContainer network policies
CGROUP_SOCKsocket create/releasebpf_sockSocket option control
SOCK_OPSsocket operations (TCP states)bpf_sock_opsTCP tuning/BBR policies
SK_MSGsocket messagesk_msg_mdSocket redirection
LSMLSM hooksbpf_lsm_ctxSecurity policies
SK_LOOKUPsocket lookupbpf_sk_lookupSocket binding override
SYSCALLsyscallbpf_syscall_ctxSyscall filtering
STRUCT_OPSKernel function pointer replacementOperation-specific structReplace congestion control, etc.

Deep Dive into Key Program Types

XDP (eXpress Data Path)

// drivers/net/ various drivers → XDP hook → BPF program
// Earliest processing point: Inside NAPI poll, before sk_buff allocation
// Context: struct xdp_md { data, data_end, data_meta }

// Return values:
enum xdp_action {
    XDP_DROP,       // Drop (fastest!)
    XDP_PASS,       // Pass, hand over to the protocol stack
    XDP_TX,         // Send back from the same NIC (hairpin)
    XDP_REDIRECT,   // Redirect to another NIC/CPU
};

// Why it's fast:
//   - Runs before sk_buff allocation → zero allocation overhead
//   - Executed inline within the driver → no function call overhead (in some drivers)
//   - DROP only requires: BPF_JMP XDP_DROP → driver releases DMA buffer → done

// Loading:
ip link set dev eth0 xdp obj xdp_drop.o sec xdp
bpftool net attach xdpdrv id <prog_id> dev eth0

kprobe / kretprobe

// Dynamically probe any kernel function (unstable API!)
// kprobe: Function entry → R0..R5 = function arguments
// kretprobe: Function return → R0 = return value

// Limitations:
//   - Function signatures may change between versions → CO-RE does not fully cover (requires BTF)
//   - Kernel may inline functions → kprobe cannot attach
//   - Blacklist: Some functions cannot be probed (lock, NMI, ...)
//     → /sys/kernel/debug/kprobes/blacklist

// User-space probing (uprobe):
//   Attach to the entry/return of user-space functions
//   → Suitable for debugging, not for production (high overhead)

Tracepoint

// Pre-defined stable probe points in the kernel → does not depend on function signatures
// Directory structure: /sys/kernel/debug/tracing/events/
// Each tracepoint has a specific context struct (known via BTF)

// Example: sched_switch
//   context: prev_pid, prev_comm, next_pid, next_comm, ...

// Advantages:
//   - Stable API (more reliable than kprobe)
//   - Full BTF coverage
//   - Lower overhead than kprobe (one less function call)

// Disadvantages:
//   - Only pre-defined points in the kernel → less flexible than kprobe

CGROUP_SKB (Container Network Policies)

Attach Point: cgroup v2 egress/ingress
  → Socket traffic for all tasks under this cgroup passes through
  → Container egress: Attach point is on cgroup net_cls

Cilium's core: Uses CGROUP_SKB to implement:
  - L3/L4 policies between containers (no tunnels, no iptables)
  - Based on identity rather than IP
  - 10x faster than iptables (hash lookup vs. linear chain)

LSM BPF (5.7+)

// security/ + BPF
// BPF programs implement LSM hooks → customize security policies without modifying kernel code

// bpf(BPF_PROG_LOAD, BPF_PROG_TYPE_LSM, ...)
// → Attach to LSM hook: bpf(BPF_RAW_TRACEPOINT_OPEN, lsm/file_open)

// Use cases:
//   - Custom audit policies
//   - Android: Device-level security policies
//   - Container security (more flexible than seccomp)

Helper Availability Matrix

// Not all helpers are available for all program types
// Rules are determined at kernel compile time: include/uapi/linux/bpf.h

// Example: bpf_skb_load_bytes() is only available for SKB types
//     bpf_xdp_adjust_head() is only available for XDP
//     bpf_get_current_pid_tgid() is available for all tracing types

// Tool: bpftool feature probe to check which helpers are supported on the current kernel

References

  • Source Code: include/uapi/linux/bpf.h (all type definitions), kernel/bpf/syscall.c (loading path), net/core/filter.c (network-related helpers)
  • Kernel Documentation: Documentation/bpf/libbpf/
  • Cilium BPF Documentation: docs.cilium.io (the best documentation for BPF networking practices)

Keywords: BPF_PROG_TYPE, XDP, kprobe, tracepoint, CGROUP_SKB, LSM BPF, helper whitelist