cilium/cilium
Patterns and conventions
This page documents the recurring patterns a contributor should expect when reading or writing Cilium Go code.
Hive cells everywhere
New agent functionality is added by writing a cell.Cell:
var Cell = cell.Module(
"feature-foo",
"Implements feature foo",
cell.Provide(newFooManager),
cell.Invoke(registerFooHooks),
cell.Config(defaultConfig),
)cell.Provide— supply types other cells canInfrom. Constructors return(T, error)or(T, hive.Lifecycle)etc.cell.Invoke— run side-effecting initialisation that depends on already-provided types.cell.Config— register a struct that maps to CLI flags viaoption.Flag*tags.cell.Module— group related cells with a stable name, used byhive print-objectsand the metric labels.
Lifecycle hooks (OnStart / OnStop) are registered through cell.Lifecycle so that the agent can stop cleanly. Avoid global state — every dependency should flow through the cell graph.
See pkg/hive/ and the dozens of cell.go files under pkg/ for examples.
Configuration
Configuration originates from CLI flags / Helm values / ConfigMap and is mapped into typed Config structs:
- Cell-local config: a struct with
Flags(flags *pflag.FlagSet)registered throughcell.Config. - Global agent config:
pkg/option/config.goholds the historicalDaemonConfigplus itsRegisterOptionsmethod. New options should go into a cell-local config when possible, falling back toDaemonConfigonly when truly cross-cutting.
Helm values are defined in install/kubernetes/cilium/values.yaml and rendered into a ConfigMap, then mapped onto the agent flags.
Logging
- Use
log/slogviapkg/logging/. Each subsystem keeps its own logger in a package-levellogvariable initialised fromlogging.DefaultSlogLogger.With(logfields.LogSubsys, "<name>"). - Field constants live in
pkg/logging/logfields/. Reuse them rather than hardcoding strings (logfields.EndpointID,logfields.IPAddr,logfields.Identity, ...). - Log levels:
slog.LevelDebugfor verbose internal flows,Infofor one-shot events that an operator should see,Warnfor recoverable problems,Erroronly for failures that are visible to users.
Error handling
- Wrap errors with
fmt.Errorf("…: %w", err)so callers canerrors.Is/As. - Reserve sentinel errors for cases callers must distinguish (
errors.New("…"), exported asErrFoo). - For control-plane reconciliation, return the error and let the upper layer (controller, hive lifecycle, statedb reconciler) retry; do not block in the inner loop.
Concurrency
- Prefer statedb tables (
vendor/.../statedb,pkg/datapath/tables/, etc.) over ad-hoc maps protected by mutexes for shared state. - Where a mutex is required, use
pkg/lock/(lock.Mutex,lock.RWMutex) for context-aware deadlock checking under-tags lockdebug. - Long-running goroutines must take a
context.Contextfrom the cell lifecycle so they can be cancelled on shutdown. - Use
pkg/controller/for periodic reconciliation loops that need backoff and metrics.
REST API conventions
The agent's REST API is defined in OpenAPI at api/v1/openapi.yaml and generated into api/v1/server/ and api/v1/client/ via make generate-api. The handlers live in daemon/cmd/ and are wired via Hive cells.
The Hubble gRPC API is defined in .proto files under api/v1/observer/, api/v1/relay/, and api/v1/peer/.
CRDs
Cilium CRDs live in pkg/k8s/apis/cilium.io/v2/ (and v2alpha1 for alpha). After modifying a Go type, run:
make generate-k8s-apiThis regenerates deepcopy methods, OpenAPI schemas, the YAML CRD manifests under pkg/k8s/apis/cilium.io/client/crds/, and the docs table in Documentation/crdlist.rst.
File naming
One package per directory; the package name matches the directory name.
Tests sit next to source:
foo.go+foo_test.go.Build tags:
//go:build linux,//go:build privileged, etc. Cilium runs on Linux only; non-Linux files are stub implementations that satisfy the compiler.License header on every source file:
// SPDX-License-Identifier: Apache-2.0 // Copyright Authors of Ciliumenforced by
make checkpatchand CI.
BPF C conventions
- Programs live in
bpf/bpf_*.c; helpers live inbpf/lib/*.h. - All map declarations go through
BPF_MAP_*macros inbpf/include/bpf/. - Programs include
node_config.h(host-specific) andep_config.h(endpoint-specific) generated by the agent at compile time. - Tail-calls are dispatched through indices defined in
bpf/include/bpf/section.h. - Verifier complexity is a constant battle: prefer small inline functions, bounded loops, and
__always_inlineto keep the verifier happy.
Style summary
- Run
gofmt,goimports, andgolangci-lint. - Keep PRs focused — split large changes into a series of commits, each independently reviewable.
- Add tests for new behaviour; if you can't, explain why in the PR.
- Keep the public surface (
pkg/exported identifiers) stable across patch releases.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.