Open-Source Wikis

/

Cilium

/

Systems

/

Datapath

cilium/cilium

Datapath

Active contributors: borkmann, julianwiedmann, jrfastab, ti-mo, joestringer

Purpose

The Cilium datapath is the set of eBPF programs running in the Linux kernel that handle every packet entering or leaving a node. It implements identity-based policy enforcement, service load balancing, NAT, conntrack, encryption, encapsulation, bandwidth shaping, and observability — all without leaving the kernel for the L3/L4 fast path.

The userspace half of the datapath, under pkg/datapath/, owns the lifecycle: compile the C sources with clang, attach the resulting BPF objects to interfaces, populate the BPF maps that drive policy decisions, and reconcile changes when the cluster state moves.

Directory layout

bpf/
├── bpf_lxc.c          # per-pod TC ingress/egress program
├── bpf_host.c         # per-host TC + cilium_host program
├── bpf_overlay.c      # VXLAN/Geneve overlay program
├── bpf_xdp.c          # XDP fast-path for north-south LB
├── bpf_sock.c         # connect-time socket LB (cgroup/sockops)
├── bpf_sock_term.c    # connection termination tracking
├── bpf_wireguard.c    # WireGuard offload helpers
├── bpf_alignchecker.c # struct layout audit
├── bpf_probes.c       # kernel feature probes
├── lib/               # shared inline helpers (encap, policy, ct, lb, nat, ...)
├── include/bpf/       # macros and types
├── tests/             # BPF unit tests
├── complexity-tests/  # verifier complexity stress tests
└── tools/             # tooling

pkg/datapath/
├── cells.go             # Hive cells for the datapath
├── orchestrator/        # decides what to load where
├── loader/              # compiles + attaches BPF programs
├── linux/               # Linux-specific routing, neigh, ipsec
├── tunnel/              # VXLAN / Geneve / encryption interface mgmt
├── iptables/            # iptables/nftables rules for fallback paths
├── connector/           # veth + ipvlan setup for endpoints
├── neighbor/            # ARP/NDP cache management
├── ipcache/             # ipcache map programmer
├── maps/                # high-level map glue
├── xdp/                 # XDP attach helpers
├── prefilter/           # XDP prefilter program (DDoS)
├── sockets/             # socket-level helpers
├── tables/              # statedb tables (devices, routes, ...)
├── plugins/             # ipam, kube-router, mixer connectors
├── l2responder/         # L2 ARP responder for service IPs
├── agentliveness/       # liveness probes piped through datapath
├── alignchecker/        # struct alignment runtime check
├── config/              # node_config / ep_config rendering
├── gneigh/              # gratuitous ARP
├── link/                # netlink link operations
├── node/                # per-node IP and identity tracking
└── vtep/                # VXLAN VTEP integration

Key abstractions

Type File Role
Loader pkg/datapath/loader/loader.go Compiles and attaches BPF programs to interfaces.
Orchestrator pkg/datapath/orchestrator/ Decides which programs go on which interfaces and triggers reloads.
BPF maps pkg/maps/<map>/ Typed Go wrappers around each BPF map (ct, nat, lb, ipcache, policy, ...).
node_config.h generated by agent Per-host compile-time constants (node IP, MTU, encryption key id, ...).
ep_config.h generated by agent Per-endpoint compile-time constants (identity, security policy id).

Packet path summary

graph TD
    Pkt[Packet at NIC]
    XDP[bpf_xdp.c<br/>XDP attach]
    Host[bpf_host.c<br/>TC ingress on physical iface]
    Veth[bpf_lxc.c<br/>TC on pod veth]
    Pol[policy map check]
    LB[lb maps lookup]
    CT[ct map lookup]
    Encap[bpf_overlay.c<br/>VXLAN/Geneve encap]
    Out[Wire / Pod]

    Pkt --> XDP
    XDP -->|XDP_PASS| Host
    Host --> CT
    CT --> Pol
    Pol -->|allow| LB
    LB --> Encap
    Encap --> Out
    Host --> Veth
    Veth --> Pol
    Veth --> Out

The exact sequence depends on direction (ingress vs egress), routing mode (overlay vs native), encryption (none vs WireGuard vs IPSec), and whether the packet hits the L7 redirect. The high-level invariant: every packet that enters the node touches at least one Cilium BPF program, identity is resolved via the ipcache, and policy is enforced before the packet is routed or delivered.

Compile and load

The agent compiles BPF programs at runtime by:

  1. Rendering node_config.h and ep_config.h from current state (pkg/datapath/config/).
  2. Invoking clang via pkg/datapath/loader/ (compile.go) on the C sources in bpf/.
  3. Loading the resulting ELF objects with the cilium/ebpf library (vendored under vendor/github.com/cilium/ebpf/).
  4. Attaching to TC, XDP, cgroup, or sockops attach points as appropriate.
  5. Pinning maps to bpffs so they survive agent restarts.

pkg/datapath/orchestrator/ decides which programs go on which interfaces — for example, bpf_lxc.c is loaded on each pod's veth, bpf_host.c is loaded on the host-side interfaces, bpf_xdp.c is loaded on the chosen physical NIC if XDP is enabled.

Map updates without restart

Most state changes in Cilium update BPF maps in place — the dataplane keeps running, no programs are reloaded. Examples:

  • New identity learned: the ipcache map gets a new entry.
  • New policy rule applied: the per-endpoint policy map gets new key/value pairs.
  • New service backend: the lb map's backend slots are updated.

Programs are only recompiled when the layout changes — for example, when an endpoint's identity changes or when a new feature flag toggles inline behaviour.

Integration points

  • Endpoint manager (pkg/endpoint/) calls into the loader on every regenerate.
  • Policy (pkg/policy/) writes the policy map for each endpoint.
  • IP cache (pkg/ipcache/) writes the global ipcache map consumed by every program.
  • Service (pkg/loadbalancer/) writes the lb maps.
  • Hubble (pkg/hubble/) reads the monitor ring buffer that BPF programs emit events into.

Entry points for modification

  • New BPF helpers: add to bpf/lib/<area>.h, include in the relevant bpf_*.c, exercise via tests in bpf/tests/.
  • New maps: define under pkg/maps/<name>/, expose to the dataplane via macros in bpf/include/bpf/, programme it from a Go cell.
  • New attach points: extend pkg/datapath/orchestrator/ and pkg/datapath/loader/.
  • For verifier complexity issues, check bpf/complexity-tests/ first; that suite catches the regressions CI cares about.

Key source files

File Purpose
bpf/bpf_lxc.c Per-pod TC program.
bpf/bpf_host.c Per-host TC program.
bpf/bpf_overlay.c VXLAN/Geneve overlay.
bpf/bpf_xdp.c XDP north-south LB and DDoS.
bpf/bpf_sock.c Socket LB at connect().
bpf/lib/policy.h Policy map lookup macros.
bpf/lib/lb.h LB lookup macros.
pkg/datapath/loader/loader.go Compile + attach orchestration.
pkg/datapath/orchestrator/orchestrator.go Decide what to load.
pkg/datapath/cells.go Datapath Hive cells.

See packages/bpf-maps.md for the map abstraction and features/load-balancing.md for the service path.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Datapath – Cilium wiki | Factory