Skip to content

CNI API

aether.cni.v1 — The gRPC contract between the CNI plugin and the node agent: what the plugin reports about a pod when the container runtime calls ADD, and what it withdraws at DEL.

Generated from the schema

Rendered by protoc from api/aether/cni/v1/ when this site was built, so it cannot drift from the compiled schema — there is no committed copy of this page. Field constraints are carried as buf.validate options and are not shown here; read the .proto for those.

api/aether/cni/v1/cni.proto

CNIPod

Field Type Label Description
name string
namespace string
network_namespace string
container_id string
ips string repeated
labels CNIPod.LabelsEntry repeated
annotations CNIPod.AnnotationsEntry repeated
pid google.protobuf.UInt32Value
service_account string
terminating bool terminating is set by the agent when the Kubernetes pod's deletionTimestamp appears (deletion requested, before SIGTERM reaches the app). A terminating pod's endpoint is deregistered immediately so new requests stop routing to it while in-flight ones drain through the grace period; the liveness loop must never re-register it. Local xDS resources stay until the CNI DEL performs final teardown.
uid string uid is the Kubernetes pod UID, fetched from the API server on CNI ADD and persisted so listener regeneration from storage can resolve the pod's UDS socket path (<uds-csi-root>/<uid>/<file>, proposals 034/039) without the API server. Empty on records written before the field existed.
uds_csi_volume string uds_csi_volume is the name of the pod's inline csi: {driver: csi.aether.io} volume, the only carrier for a UDS-delivered socket since proposal 039 Phase 2. Recorded by the agent on CNI ADD from the pod spec and persisted so storage replay resolves the socket without the API server. Empty when the pod declares no such volume, and ALSO when it declares more than one (one mesh socket volume per pod: the agent trusts neither; see uds_csi_volumes).
volumes string repeated volumes lists the name of every volume the pod declares, whatever its source. It lets the agent tell a UDS request naming a volume the pod mounts with another carrier (an emptyDir left over from before 039 Phase 2: reason "not_csi") from one naming a volume the pod does not declare at all (reason "volume_not_declared").
uds_csi_volumes uint32 uds_csi_volumes counts the pod's csi.aether.io volumes, so a pod declaring more than one (uds_csi_volume then empty) is reported as "multiple_csi_volumes" rather than misattributed. Zero on records written before the field existed.

CNIPod.AnnotationsEntry

Field Type Label Description
key string
value string

CNIPod.LabelsEntry

Field Type Label Description
key string
value string

api/aether/cni/v1/service.proto

AddPodRequest

Field Type Label Description
pod CNIPod
plugin_timings PluginTimings

AddPodResponse

Field Type Label Description
result AddPodResponse.Result

PluginTimings

PluginTimings are the CNI plugin's own timings for one invocation. The plugin exports no telemetry of its own (issue #1166: the OTel SDK cost every pod ADD/DEL a collector round trip, and 2 s whenever the collector was unreachable), so it forwards them to the agent, whose RPC span records them as attributes. Optional throughout: a plugin that predates them sends none, and the agent then records nothing extra for that call.

Field Type Label Description
started google.protobuf.Timestamp started is when the plugin process entered main().
pre_call google.protobuf.Duration pre_call is started -> this RPC was sent: netconf parsing, the container PID lookup (a CRI call when the netns path carries no PID) and the netns pin. Work the agent's own span cannot see.

RemovePodRequest

Field Type Label Description
name string
namespace string
container_id string
plugin_timings PluginTimings

RemovePodResponse

Field Type Label Description
result RemovePodResponse.Result

ReportAddResultRequest

Field Type Label Description
name string
namespace string
container_id string
plugin_timings PluginTimings
readiness_probe google.protobuf.Duration readiness_probe is how long the in-netns probe of the pod's outbound capture listener took. Unset when the probe is disabled (readiness_probe_disabled in the netconf).
readiness_probe_error string readiness_probe_error is the probe's failure; empty = it confirmed serving.
capture_divert google.protobuf.Duration capture_divert is how long installing the transparent-capture divert (nftables table + policy routing) in the pod's netns took.
capture_divert_error string capture_divert_error is the install failure; empty = installed. Non-empty means the pod is running UNCAPTURED: the mesh does nothing for it.
total google.protobuf.Duration total is the plugin's started -> this report was sent: the whole ADD as the plugin saw it, short of printing the result to the runtime.

ReportAddResultResponse

AddPodResponse.Result

Name Number Description
RESULT_UNSPECIFIED 0
RESULT_SUCCESS 1
RESULT_ERROR 2
RESULT_IGNORED 3 RESULT_IGNORED: the pod is not mesh-managed (aether.io/managed != "true", a system namespace, or no IPs) — the agent stored no config and the CNI plugin must install NO capture/redirect (the label is only visible to the agent, which fetches it from the API; the CNI cannot see labels via CRI).

RemovePodResponse.Result

Name Number Description
RESULT_UNSPECIFIED 0
RESULT_SUCCESS 1
RESULT_ERROR 2
RESULT_IGNORED 3 RESULT_IGNORED: the pod is not mesh-managed (aether.io/managed != "true", a system namespace, or no IPs) — the agent stored no config and the CNI plugin must install NO capture/redirect (the label is only visible to the agent, which fetches it from the API; the CNI cannot see labels via CRI).

CNIService

Method Name Request Type Response Type Description
AddPod AddPodRequest AddPodResponse
RemovePod RemovePodRequest RemovePodResponse
ReportAddResult ReportAddResultRequest ReportAddResultResponse ReportAddResult carries what the plugin did AFTER AddPod answered: the data-plane readiness probe and the transparent-capture divert (nftables) install. Best-effort: the plugin never fails an ADD on it, and an agent that predates it answers UNIMPLEMENTED, which the plugin ignores. The agent records it as span attributes, the aether.cni.operations{operation="capture_divert"} counter, and a WARN when the divert failed (the pod runs UNCAPTURED). Issue #1166.