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.goKey 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- Watch —
pkg/k8s/watchers/cnp.go+policy.gopush rules into the repository. - SelectorCache — every selector is compiled to a bitmap of matching identities. Identity additions/removals update the cache, which triggers downstream regeneration.
- Distillery — for each
(identity, traffic-direction)produce the merged set of L4 / L7 entries. - Endpoint — bind the SelectorPolicy to the endpoint and write the policy map. Endpoint goroutines coalesce rapid updates.
- Hubble correlation —
pkg/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 throughRepository -> Distillery. - New L4 semantic (e.g., a new protocol): extend
pkg/policy/l4.goand 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.