Mesh & routing

A control plane with no controller.

Every node floods what it knows, computes routes over the shared picture, and relays for its peers. When a node joins, moves or dies, the topology refloods and every surviving node recomputes independently, within whatever detection costs — ≈1.25 s at default probe settings.

Field-proven on the 8-node fleetOpt-in per feature
Flooding

LSAs to every established peer

Each advertisement carries the originator, a sequence number, per-neighbor links (cost = best alive RTT, aliveness, per-link RSSI), served prefixes, a human node_name — and optionally WGS-84 position with velocity, which is what the prediction layer consumes.

Hygiene

Aging, refresh, tombstones

Entries age out at 100 s, refresh every 30 s (re-stamping position), and departed nodes leave tombstones (~300 s) so a stale advertisement can’t resurrect them. Full-database exchange on session establish; event-driven, debounced re-floods on link changes.

Positions

Three sources, auto-prioritised

Static config, live GPS fixes over the telemetry socket, or an operator typing coordinates into the dashboard’s topology tab — park a relay van, enter its position, and every peer’s map updates within an advertisement tick.

Paging

A membership update that fits one datagram

The roster travels in pages, and a page fits a single UDP datagram by construction: node ids ride as base64 (not 32-number JSON arrays), the public key left the wire entirely (identity is the key), the deprecated config block rides only on full-sync rounds, and the sealed envelope carries a 48-byte binary prefix instead of base64-in-JSON. [mesh] max_gossip_bytes defaults to 1330 — sealed, that stays under a 1500-MTU path — so losing a datagram costs one page, never the roster; the members that did not fit lead the next document to the same target. Measured to fit a 250 kbit tactical bearer.

SPF

Shortest path over measured costs

Dijkstra over the LSDB — measured-cost or hop-count mode — with dynamic peer learning behind relays and a TTL’d relay header capping paths at 8 hops. When the direct edge dies, traffic threads through whoever survives.

Hop honesty

Relays are trusted members of your fleet

Each leg is protected by its own Noise session: a relay decrypts the fragment from the previous hop, reassembles, makes the forwarding decision, and re-encrypts toward the next hop. That is per-hop protection by trusted nodes — not end-to-end blindness — and it is different from hosted traversal relays, which forward opaque envelopes they cannot open. the three trust boundaries ↗

Multipath

Next-hop diversity, deduplicated arrival

routing.path_redundancy = K computes the top-K next hops and fans every fragment across all of them — at the origin and at each transit hop — with receive-side dedup. Because candidates are separated by first hop, not by full node-disjointness, two paths can still meet further downstream; what you are guaranteed is that they leave on different neighbours. Nothing switches over, so there is no failover gap to lose packets in. Off by default (K = 1); K = 2 doubles the backbone bill. The 2× figure comes from a scripted demo scenario, not the measurement estate. Simulation

Pinned paths

Operator-pinned static routes

Named hop lists with stable path IDs and auto-failover deliberately disabled — a static FIB for rehearsed operations where predictability beats adaptivity.

The mesh control plane

Push a config. Watch it spread. Cut the wire and push again.

Membership is a CRDT with authenticated join and liveness heartbeats; configuration travels as Ed25519-signed epochs over encrypted gossip. Any node can author; every node verifies, applies through the commit-confirmed lifecycle, and gossips its status back.

Eight nodes, no controller — push from anywhereSimulation
v1config epoch
8 / 8nodes converged
time to converge
nonecontrollers involved
The real machinery behind this picture: signed epochs with a section whitelist (identity, peers and auth can never be pushed remotely — a security boundary), rollback protection, per-node commit-confirmed apply with a deadman revert, and status gossip so the author watches the fleet converge. All of it on operations, proven end-to-end in the epoch suite.
Why no controller

Nothing to stand up. Nothing to capture. Nothing to lose.

The mesh needs no orchestrator because its three jobs are already distributed:

Membership

A conflict-free replicated registry with Lamport clocks, authenticated join via a shared mesh secret, heartbeats and expiry. Anti-entropy syncs with a genuinely random peer every few seconds, so no member can be starved of updates.

Confidential gossip

Since gossip v2, every mesh body crosses the wire as ChaCha20-Poly1305 ciphertext under a key derived from the mesh secret, with per-opcode domain separation and replay damping — an eavesdropper on any underlay no longer gets a free map of the fleet. (A compatibility flag exists for mixed fleets mid-upgrade.)

Authority

Knowing the mesh secret means you may see the mesh; only an Ed25519 author key means you may change it — and even an author cannot rewrite a node’s identity or peer set remotely. Partition-tolerant by construction: both sides keep operating and reconcile on reconnection.

The swarm fabric

The fleet doesn’t use the network. It is the network.

Give every airframe a node and the formation becomes its own transport fabric: spatial diversity (routes thread around losses) and spectral diversity (edges on different bands fail differently) — with reconvergence on the event rather than on a timer, doing the flying-formation bookkeeping.

Six airframes, two bands — take away an airframe, or take away a whole bandSimulation
Destroy an airframe
Degrade a band
6 / 6airframes flying
5hops on the path
9 Mbpspath bottleneck
0SPF recomputations
What you're watching: a simulation routing with Dijkstra SPF on measured cost, where every edge belongs to exactly one band — 5.8 GHz between neighbouring airframes (solid, short reach, fat), 2.4 GHz across the formation (dashed, long reach, thin). Destroying an airframe removes one node; degrading a band removes every edge on it at once, which is why the two losses look different on the stage and are recovered separately. Both ends hold an edge on each band, so no single band failure can strand either of them. What was demonstrated for real: at HEMUS 2026, an 8-node mixed fleet — laptops, field relays, an airborne node — carried MAVLink C2, H.265 video and gimbal control through physical link kills and induced degradation. Controlled link-degradation trials; no live RF jamming. The full rig is on evidence; the operator-depth patterns are in the playbooks.
Use 802.11s

As a link, it’s excellent

A radio segment that self-forms at Layer 2 is a perfectly good Atlas underlay — the standing fleet bonds one alongside five other link types. Atlas treats the whole mesh segment as one measured path.

Never both

One multi-hop layer per set of radios

Two routing layers fighting over the same RF is the one bad configuration: HWMP path changes race Atlas’s dead-detection, the L2 mesh advertises capacity it can’t deliver over N hops, RSSI is first-hop-only, and broadcast amplifies. Rule: if Atlas is doing the relaying, the radio layer underneath must not — and vice versa.

Research

Bonding-only segments

A proposed forwarding = "bonding-only" link attribute would keep a mesh-underlay link fully in the bond between its endpoints while making it structurally impossible to use as a transit hop — the recommended tactical layout, enforced by the config instead of by discipline. roadmap ↗

Where the two layers meet

Every hop of the path is itself a bond.

Bonding and meshing compose: the mesh decides which nodes carry the traffic, and between each pair of them the bond decides over what. That gives a path two independent ways to survive — and two failure modes that look identical on a topology map until you draw the hops honestly.

One path, four hops, six radio links — break either layerSimulation
Kill a relay
Cut one link of a hop
4hops on the path
6 / 6links carrying
52 Mbpspath bottleneck
0SPF recomputations
What you're watching: a simulation routing on hop-count cost, so a hop costs the same whether it rides one link or two — which is exactly why cutting half a bond never moves the route, and why the SPF counter stays put while the capacity number falls. Both behaviours are real: a bond is formed between two adjacent nodes, so a relayed path is a chain of bonds, each leg with its own Noise session and its own scheduler. Exhaust every link of a hop and the mesh takes over again.
Request an evaluation

Your fleet is the infrastructure.

Every node a relay, every relay measured, every route recomputed the moment the topology moves — with nothing in the middle to capture or lose.