cilium/cilium
Network policy
Active contributors: jrajahalme, christarazi, joestringer, aanm, gandro
Purpose
Cilium enforces network policy on every packet. Three policy formats are accepted simultaneously:
- Kubernetes
NetworkPolicy(built-in API). CiliumNetworkPolicy(CNP) — namespaced, richer than NetworkPolicy. Supports L7, FQDN, deny rules.CiliumClusterwideNetworkPolicy(CCNP) — cluster-scoped, otherwise identical to CNP.
The agent compiles all three into a single in-memory representation and produces per-endpoint policy maps that the dataplane consults on every packet.
Directory layout
pkg/policy/
├── api/ # the public CNP/CCNP/NetworkPolicy types and validators
├── repository.go # in-memory rule database
├── selectorcache.go # compiled selectors -> identity sets
├── distillery.go # compute SelectorPolicy per endpoint
├── l4.go # L4 entry construction
├── l7policy.go # L7 metadata propagation
├── policymap/ # writes the per-endpoint BPF policy map
├── correlation/ # correlation between policy + traffic
└── cells.go
pkg/policy/api/ # the policy schema (CRD types)
pkg/k8s/apis/cilium.io/v2/cnp_types.go # the CRD wrapper
pkg/proxy/ # L7 redirect runtime (Envoy / DNS)
pkg/fqdn/ # FQDN policy (DNS proxy + ipcache updates)
pkg/maps/policymap/ # the policy BPF mapPolicy model
A rule has three parts:
- Endpoint selector — which endpoints the rule applies to (label selector → set of identities).
- Ingress / egress lists — for each direction, a list of allow rules.
- Each rule carries L3 (
fromEndpoints,toEndpoints,fromCIDR,toCIDR,toFQDNs,fromEntities), L4 (toPorts), and optionally L7 (http,kafka,dns, custom).
Rules are additive: any rule that allows a flow makes it allowed. Deny rules (ingressDeny / egressDeny) override allow rules and are evaluated first.
Default mode is default-allow if no policy matches; once any policy applies to an endpoint, the endpoint becomes default-deny for that direction. Behaviour matches Kubernetes NetworkPolicy semantics.
Compilation pipeline
graph LR
CRD[CiliumNetworkPolicy CRD]
API[NetworkPolicy core API]
Repo[Policy Repository<br/>pkg/policy/repository.go]
SC[SelectorCache<br/>pkg/policy/selectorcache.go]
Distillery[Distillery<br/>pkg/policy/distillery.go]
SP[SelectorPolicy<br/>per identity]
EP[Endpoint<br/>pkg/endpoint]
PMap[policy map<br/>pkg/maps/policymap]
CRD --> Repo
API --> Repo
Repo --> SC
Repo --> Distillery
SC --> Distillery
Distillery --> SP
SP --> EP
EP --> PMapSteps:
- Watch — k8s watchers (
pkg/k8s/watchers/cnp.go,policy.go) push CRDs into the repository. - SelectorCache — every label selector is compiled into a set of identities; when identities change, dependents get notified.
- Distillery — for each
(identity, traffic-direction)combination, produce aSelectorPolicythat is the merged set of allowed L4 entries and L7 redirects. - Endpoint — per-endpoint goroutine consumes the SelectorPolicy and writes the per-endpoint policy map plus L7 redirects.
- Datapath —
bpf/lib/policy.hlooks up the policy map by(identity, port, proto, direction)on every packet.
L7 enforcement
When a rule includes an L7 stanza (HTTP method, gRPC method, Kafka topic, DNS pattern), the policy map entry is marked as redirect to the L7 proxy. The dataplane TPROXYs the connection to Envoy (or to the DNS proxy for DNS), which makes the L7 verdict and writes a structured access log that Hubble parses into a flow.
See systems/envoy-l7-proxy.md.
FQDN (toFQDNs)
toFQDNs: ["api.example.com"] lets policy reference DNS names. The DNS proxy (in-agent at pkg/fqdn/, or the optional out-of-process standalone-dns-proxy) intercepts DNS responses for the source pod and:
- Records the IP set associated with the FQDN.
- Adds those IPs to the ipcache with a synthetic identity.
- Emits a policy map entry that allows the source identity → that synthetic identity.
A garbage collector (pkg/fqdn/dnsproxy/) ages out IPs that no longer match a recent DNS response.
Deny rules
Deny rules are stored separately in the policy map and consulted first. They are useful for "always block" patterns and for compliance: e.g., deny all egress to a list of CIDRs even if other policies allow.
Testing
- Unit tests:
pkg/policy/*_test.gocovering distillery, selector cache, repository. - Compatibility tests:
pkg/policy/k8s/ensures Kubernetes NetworkPolicy semantics are matched. - Connectivity test:
cilium-cli connectivity testexercises a battery of scenarios across L3/L4/L7/FQDN/deny/CIDR.
Key source files
| File | Purpose |
|---|---|
pkg/policy/repository.go |
Rule database. |
pkg/policy/selectorcache.go |
Compiled selectors. |
pkg/policy/distillery.go |
Per-identity SelectorPolicy. |
pkg/policy/policymap/policymap.go |
BPF map. |
pkg/policy/api/rule.go |
Public rule type. |
pkg/fqdn/dnsproxy/proxy.go |
DNS proxy. |
pkg/proxy/envoyproxy.go |
Envoy redirect registration. |
bpf/lib/policy.h |
Dataplane lookup. |
See systems/identity-allocation.md for the identity model that policy is expressed against.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.