flowsdn is a Rust networking stack for stormcos, implementing a CNI plugin and an eBPF endpoint datapath. Its broader goal is Cilium-compatible networking, services, policy and observability. That full stack is not implemented yet.
As of 2026-11-10 (source through d50a453), the executable pair is
flowsdn-agent and flowsdn-cni. The agent provides persisted endpoint
ownership, IPv4/IPv6 host-scope allocation and a bounded HTTP API over a Unix
socket. The primary veth CNI supports ADD, CHECK, DEL, STATUS and VERSION,
including queued offline deletion, and the same executable is the loopback
plugin. With bpf-pin-root configured, pinned endpoint maps and TCX links
preserve forwarding across agent downtime; restoration checks interface ownership.
- The BPF objects are embedded. The agent carries
local-delivery(and, in Kubernetes mode,socket-lb) built from its own commit and loads them whenbpf-objectis not configured.bpf-objects.lockrecords their hashes;test/build.shrebuilds them and refuses a stale embedded copy. - Two egress modes.
egress: fib(default) FIB-redirects non-local traffic in BPF for native routing.egress: stackhands every frame from an endpoint to the host stack (routing, netfilter), same-node pod-to-pod included, and adds a host/32//128route per endpoint address. The stormcos edition usesstack. - Node CNI installation.
flowsdn-cni installcopies the plugin into the host's/opt/cni/bin(flowsdn-cni,flowsdn, andloopbackif absent) and atomically writes/etc/cni/net.d/00-flowsdn.conflist. - Kubernetes mode (agent
kubernetescargo feature, GNU build with Fedora OpenSSL; the build the golden carries). Node and cluster Pod watches;autopools from the Node's pod CIDR (or10.<last IPv4 byte>.0.0/16); direct routes<podCIDR> via <nodeIP>to every other node with conflict checks and pruning; forwarding sysctls;GET /v1/ip,/v1/node/routes,/v1/service. - Services without kube-proxy (
kubernetes.service-lb, default on, #292). Service + EndpointSlice watches program thesocket-lbcgroup programs (connect/sendmsg/recvmsg/getpeername, IPv4/IPv6/IPv4-mapped, TCP/UDP): ClusterIPs, externalIPs, LoadBalancer ingress IPs and NodePorts for clients on the node, withinternalTrafficPolicy/externalTrafficPolicy: Localand ClientIP session affinity. - NodePort/LB/externalIP from outside the cluster (
kubernetes.node-port, default on).nodeport_ingress/nodeport_egresson the uplink's TCX hooks DNAT to this node's backends or, forexternalTrafficPolicy: Cluster, SNAT and FIB-redirect to other nodes' backends; IPv4 and IPv6. New flows pick a backend at random or by Maglev (kubernetes.lb-algorithm, or theservice.flowsdn.io/lb-algorithmannotation).kubernetes.lb-mode: snat|dsr|hybrid(defaultsnat; DSR by IP option, per Serviceservice.flowsdn.io/forwarding-mode) andkubernetes.nat46x64(default off) are verified by kernel test runs only, not on a cluster. - Several uplinks (#408,
kubernetes.uplinks, defaultactive-active): every port on the node's subnet that has carrier carries traffic, as per-flow ECMP routes to other nodes with source rules pinning each address to its port. A port that loses carrier has its address held as a /32 by a live port, with a gratuitous ARP, until carrier returns.GET /v1/uplinksreports each port's link, speed, FEC, bytes and the join/leave history. Unit-tested; not yet run on a two-port node. - Host firewall (
kubernetes.host-firewall: audit|enforce, default off,auditin the stormcos Kubernetes-mode config; ADR-0022): FlowsdnClusterwideNetworkPolicy host rules (nodeSelector) filter traffic to the node on its uplinks in eBPF, with audit mode and verdict counters (GET /v1/policy/verdicts). The Pod rules of FlowsdnNetworkPolicy and FlowsdnClusterwideNetworkPolicy (kubernetes.flowsdn-policy, default off) use the same endpoint policy maps. - Kubernetes NetworkPolicy in the datapath (
kubernetes.network-policy, default on; ADR-0021) and UDP socket termination when a Service backend leaves (netlinkSOCK_DESTROY). - Kubernetes Events and pod tagging. Events on Pods and the Node
(
EndpointCreated,IPAllocationFailed,PodCIDRSelected, …) and theflowsdn.io/pod-networksannotation on local Pods, with flowsdn's entry in the Multusk8s.v1.cni.cncf.io/network-statusbeside it (#298, #328, #371). - stormcos edition manifests.
deploy/stormcos/manifests-kubernetes/(RBAC, ConfigMap, DaemonSet, the 22 CRDs) is what the edition ships;manifests/is the older single-node, static-pool set without Service handling.
Privileged fixtures in the test container's medium suite have exercised
same-node IPv4/IPv6 delivery, native routing between router namespaces, the
socket LB, the IPv4 and IPv6 NodePort/SNAT programs, UDP socket termination
and the policy programs, on a stormcos 7.2 kernel (pvetest2), and the node
probe found kube-dns and the kubernetes Service programmed on a flowsdn node.
Those fixtures are not acceptance of a two-node Kubernetes network:
two-node acceptance (#291) and live NetworkPolicy acceptance on a cluster
(#292) are still open.
The Kubernetes-mode agent also allocates cluster identities for its Pods (FlowsdnIdentity objects, #291). Not implemented in the agent: L7, FQDN and ICMP policy rules, host egress policy, flowsdn's own masquerade, DSR by IPIP or Geneve and DSR ICMP errors, NAT46/64 to local backends or in the socket LB, TCP socket termination, CRD controllers, an operator process and the Hubble observer/relay. Libraries also implement configuration resolution, identity and map layouts, a Kubernetes NetworkPolicy importer and policy simulator, Maglev tables, BGP codecs/session state, encryption and egress plans, proxy ACK handling, flow filtering and cloud request plans. A library or passing unit test does not imply the feature runs in the agent. See the current implementation assessment.
The package version and latest published foundation prerelease remain 0.14.0. Current main contains unreleased runtime work beyond that prerelease. A stormcos golden's pinned source revision identifies what a node actually runs; the package version alone does not distinguish these unreleased commits.
flowsdn-agent --config PATHreads a standalone JSON configuration.--help/-hand--version/-Vexit successfully without starting the agent.- The agent's HTTP API uses the configured mode-0600 Unix socket; the optional
http-listenadds a read-only listener on a loopback port (403 for anything that changes state), for the stormcos console; non-loopback addresses are refused. There is no Hubble service on 4244, metrics listener or relay. GET /v1/healthzreports API availability after restore and deletion replay; it does not mean the pod network or policy controllers are ready./v1/health/modulesreports unavailable controllers as degraded.- Endpoint list/detail, IPAM summaries, allocation, CNI publication/deletion
and the Kubernetes-mode
/v1/ip,/v1/node/routesand/v1/serviceviews (20 routes,api::ROUTES, incl./v1/identity,/v1/policy/verdictsand/v1/cni/timing) are documented in the agent API. This is a subset of the reference REST shape, not complete Cilium CLI/API compatibility. - The runtime configuration reference lists every standalone key, required value, default and CNI override. The separate 539-key configuration library is a compatibility catalogue, not the executable's accepted CLI or active feature set.
flowsdn ships 22 custom resources in flowsdn.io/v1alpha1 (CRD reference,
#325): Flowsdn* kinds, fs* short names and the flowsdn category, with the
reference schemas (validation, status subresources, printer columns) projected
from vendored Cilium v1.20.1 CRDs. The manifests are generated into
deploy/stormcos/manifests-kubernetes/crds/, with examples and offline
accept/reject validation for every kind. No controller reads or writes them
yet: the daemon does not register or reconcile CRDs, and flowsdn must not adopt
or garbage-collect existing cilium.io objects.
Compatibility concerns data shape (CNI result, agent API, BPF map layouts),
not names: nothing flowsdn ships carries the reference project's name. The CNI
type is flowsdn-cni, the socket /var/run/flowsdn/flowsdn.sock, the BPF maps
flowsdn_*, and tools/check-no-cilium.sh checks the shipped files on every
build (ADR-0020). Moving a
cluster from Cilium is a one-time conversion (migration).
See the resource identity decision
for CRD ownership boundaries.
flowsdn ships as the flowsdn golden in the stormcos flowsdn edition: the
Kubernetes-mode agent (/flowsdn-agent, GNU build with its Fedora glibc/OpenSSL
runtime and the BPF objects embedded, stormcos#171), the static musl CNI
(/opt/cni/bin/flowsdn) and nft for the node's masquerade. Nodes clone it
copy-on-write and mount it at /pallets/flowsdn. The latest golden,
golden-flowsdn-de1d63ada483, was staged from 1254993 (DSR, Maglev, host
firewall, flowsdn policy kinds, NAT46/64; those features are off by default and
kernel-test-run only). Later fixes (#396 CNI ADD timing, #397 start log, #402
host firewall audit config, #404 state-lock wait) are staged separately. A source push
alone does not update nodes: the revision must be staged into a new golden and
composed into a stormcos release.
On a node, the edition's DaemonSet runs image: flowsdn. The stormcos kubelet
(stormpump runtime) roots a container named …/flowsdn on the flowsdn golden,
so nothing is pulled. Its init container runs /opt/cni/bin/flowsdn install to
put the plugin and conflist on the host; the agent runs privileged in the host
network namespace with /var/run/flowsdn and /var/lib/flowsdn from the host.
The edition runs no kube-proxy: Services go through the agent's socket LB and
uplink NodePort programs (kubernetes.service-lb, kubernetes.node-port,
#292), for every pod and host process. The node provides forwarding and the
masquerade for off-node egress. The edition uses the Kubernetes-mode manifests
(deploy/stormcos/manifests-kubernetes/): pod CIDRs from the Node, direct
routes to the other nodes' pods (#291) and Service load balancing (#292). The
older static manifests/ set has no Service handling. Applying the manifests
is stormcos's side (stormcos#261).
See the deployment contract.
Outside stormcos, a standalone install is a Helm chart
(install/kubernetes/flowsdn, docs)
with an agent image (images/agent) and release archives
(deploy/release/build.sh: static agent and CNI per architecture plus
SHA256SUMS); none of it is in the golden, and none is published yet (#294).
The authority for the golden lifecycle is
stormcos's golden documentation.
Dependency versions and Git revisions in Cargo.lock remain build inputs; a
sibling dependency's new commit is not selected automatically.
There is no operator or relay binary to deploy. Storage/PVC provisioning belongs
to stormcos's built-in stormblock driver, not to flowsdn.
- Services (#292): socket-LB ClusterIPs, then externalIPs, LoadBalancer IPs and
NodePorts for in-cluster clients, traffic policies and ClientIP affinity;
uplink NodePort programs with node-local backends, SNAT to other nodes'
backends (IPv4) and IPv6. The socket LB attaches on the 7.2 kernel since
cda5799(noBPF_F_ALLOW_MULTI). - Policy library (#292): Kubernetes NetworkPolicy importer and lowering to the policy simulator, with evaluate-versus-compiled-map agreement tests. Not wired into the agent.
- Agent: Kubernetes Events, stable route list and an
agenthealthz member (#298);flowsdn.io/pod-networksand Multusnetwork-status(#371) annotations and pod/container fields on/v1/endpointand/v1/ip(#328); read-only loopbackhttp-listen(#297). - CRDs: 22
flowsdn.io/v1alpha1kinds generated from vendored schemas, with printer columns and offline validation (CRD reference, #325). - Release scope: the stormcos golden, plus standalone archives and a Helm chart kept out of it, flowsdn names only (ADR-0019, chart, #294);
bpf-objects.lock(#245). - No reference-project names in anything shipped, checked on every build by
tools/check-no-cilium.sh; BPF maps renamedflowsdn_*(ADR-0020, migration, #330). - Tests: the
short/medium/longtest container ran on hardware (#303, #256skb-ctx-matrix);perfandperf-scalesuites compare flowsdn with Cilium (#321, not run yet).
Remaining acceptance is tracked by four milestones:
working Kubernetes pod networking (#291), services/policy (#292), advanced
networking/observability (#293), and compatibility/release hardening (#294).
The console plugin (stormconsole#83) and sc net (stormcos#318) are built by
their own projects on flowsdn's API, events and CRD columns.
Use Linux and the Rust toolchain pinned in rust-toolchain.toml:
cargo xtask check
cargo test --workspace --all-features --release --locked
cargo xtask deny
cargo xtask chart-check # Helm chart checks (needs helm)
cargo xtask cloud-scan # scan tests/cloud fixtures for unscrubbed data (#391)check runs formatting, Clippy, tests and compile checks for x86-64/arm64 Linux
musl for non-TLS dependency closures, including feature-gated fixtures.
TLS consumers use native GNU checks and require Fedora OpenSSL; target
sysroots and runtime checks are needed for cross-architecture TLS validation. deny requires cargo-deny. Build output
uses standard Cargo configuration. Privileged runtime fixtures have additional
requirements documented in flowsdn-bpftest;
cross-compilation alone does not prove runtime support.
On test machines, stormcentral runs the test container (/test short|medium|long) against the commit's own agent, CNI and BPF objects, and
/test perf|perf-scale (flowsdn-perf) on the cluster's own network.
Maintainer builds and tests run with sc-build after a commit is pushed; it
fetches that revision into a disposable build directory. GitHub Actions is
disabled and no GitHub workflow builds, tests or publishes this project.
flowsdn goldens use stormcentral component stage flowsdn; stormcentral records
the golden and files the release request. See build and publication
for the actual commands and the distinction from ordinary Cargo development.
For a short overview, see the presentation (a Marp deck).
Start with the documentation guide, current runtime/API and
deployment references. docs/spec/ defines intended contracts;
docs/inventory/ describes Cilium v1.20.1 (7d68cfb394); historical decisions,
workcycles and release records are not lists of enabled features. Test corpora
are data until a working adapter executes them. Project tools and harnesses are
Rust; fixture data uses txtar, JSON, YAML and TOML.
Apache License 2.0. See LICENSE, NOTICE and the licensing and clean-room rules.
The Kubernetes client links Fedora system OpenSSL
(ADR-0016); building it needs
openssl-devel and pkgconf-pkg-config. The default agent build and the CNI
do not link it and stay static musl (the release archives). The
Kubernetes-mode agent is a GNU build; the golden carries its Fedora runtime
(stormcos#171).