Open-Source Wikis

/

Cilium

/

Packages

/

pkg/policy

cilium/cilium

pkg/policy

Active contributors: jrajahalme, christarazi, joestringer, gandro, aanm

Purpose

pkg/policy/ is the policy compilation pipeline of Cilium. It takes Kubernetes NetworkPolicy, CiliumNetworkPolicy, and CiliumClusterwideNetworkPolicy resources, plus the live identity catalog, and produces:

  • A per-identity SelectorPolicy (which L4 / L7 entries apply to flows from / to that identity).
  • The bytes that fill the per-endpoint policy BPF map.
  • The metadata Hubble uses to annotate flows with policy verdicts.

For the user-facing description of what policies can do, see features/network-policy.md. This page is about the implementation.

Directory layout

pkg/policy/
├── api/                      # the public CRD-facing schema (Rule, EndpointSelector, ...)
├── repository.go             # rule database
├── selectorcache.go          # compile selectors -> identity sets
├── distillery.go             # produce SelectorPolicy per identity
├── l4.go / l7policy.go       # L4 + L7 entry construction
├── policymap/                # write the per-endpoint policy BPF map
├── correlation/              # match flows to the rules that decided them
├── trafficdirection/         # constants for ingress/egress
├── trace.go                  # debug tracing of policy decisions
├── visibility.go             # L7 visibility-only policy
└── cells.go

Key abstractions

Type File Role
Repository pkg/policy/repository.go The in-memory database of all rules and the source of truth for the agent.
SelectorCache pkg/policy/selectorcache.go Compiles label selectors into identity sets and notifies subscribers when identities change.
Rule pkg/policy/api/rule.go A single CNP/CCNP/NetworkPolicy rule.
SelectorPolicy pkg/policy/distillery.go The output for one identity: ingress + egress L4/L7 entries.
EndpointPolicy pkg/policy/distillery.go A SelectorPolicy bound to a specific endpoint, ready to be flushed to BPF.
L4Filter pkg/policy/l4.go One (port, proto, peer-identities, L7 rules) entry.

Pipeline

graph LR
    Watch[k8s watchers]
    Repo[Repository]
    SC[SelectorCache]
    Distillery[Distillery]
    SP[SelectorPolicy per identity]
    EP[Endpoint]
    Map[policy BPF map]
    Hubble[Hubble correlation]

    Watch --> Repo
    Repo --> SC
    Repo --> Distillery
    SC --> Distillery
    Distillery --> SP
    SP --> EP
    EP --> Map
    SP --> Hubble
  1. Watchpkg/k8s/watchers/cnp.go + policy.go push rules into the repository.
  2. SelectorCache — every selector is compiled to a bitmap of matching identities. Identity additions/removals update the cache, which triggers downstream regeneration.
  3. Distillery — for each (identity, traffic-direction) produce the merged set of L4 / L7 entries.
  4. Endpoint — bind the SelectorPolicy to the endpoint and write the policy map. Endpoint goroutines coalesce rapid updates.
  5. Hubble correlationpkg/policy/correlation/ matches a runtime flow back to the rule(s) that allowed/denied it.

Selector cache details

The selector cache is the bottleneck for large-cluster policy work. Optimisations include:

  • Identity diffs: when a single identity changes, only the selectors that actually match are recomputed.
  • Reference counting: selectors that no policy uses are dropped to keep memory bounded.
  • Snapshot reads: Distillery and endpoint goroutines work against immutable snapshots to avoid lock contention.

L7 redirect plumbing

When a rule includes L7, the L4 entry is annotated with a "redirect to proxy port" marker. pkg/proxy/ then picks a per-endpoint port and wires Envoy via xDS (pkg/envoy/). The dataplane consults the redirect bit when looking up the policy map.

Deny rules

Deny rules are stored in a separate sub-tree of the policy map and consulted before allow rules. This keeps the dataplane fast path simple: deny → drop, allow miss → drop, allow hit → forward.

Testing

  • pkg/policy/*_test.go — table-driven tests for each compilation stage.
  • pkg/policy/k8s/*_test.go — Kubernetes NetworkPolicy compatibility.
  • Race tests in CI exercise concurrent identity churn vs policy recomputation.

Integration points

  • Repository consumes from K8s watchers and feeds Distillery.
  • Distillery consumes the SelectorCache and feeds endpoints.
  • Endpoint manager owns the per-endpoint regenerate cycle that flushes to BPF.
  • Hubble correlation consumes runtime flows + the live SelectorPolicy.

Entry points for modification

  • New rule field: extend pkg/policy/api/rule.go, run codegen if a CRD type changed, plumb the new field through Repository -> Distillery.
  • New L4 semantic (e.g., a new protocol): extend pkg/policy/l4.go and the BPF policy map encoding.
  • New L7 protocol: define a new redirector under pkg/proxy/ and wire Envoy filter config.

Key source files

File Purpose
pkg/policy/repository.go Rule database.
pkg/policy/selectorcache.go Selector compilation.
pkg/policy/distillery.go Per-identity policy.
pkg/policy/policymap/policymap.go BPF policy map.
pkg/policy/api/rule.go Public Rule type.
pkg/policy/correlation/correlation.go Flow ↔ rule matching for Hubble.

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

pkg/policy – Cilium wiki | Factory