yggnode is an ultra-lightweight, memory-optimized, fully static downstream distribution of Yggdrasil-ng engineered specifically for resource-constrained embedded Linux routers, IoT gateways, and low-power devices (MIPS, ARM, x86).
Most consumer routers and embedded edge devices operate with very limited memory pools (typically 32 MB to 64 MB of RAM and MIPS 24KEc/74Kc or Cortex-A7 processors).
- The Problem with Standard Builds: The reference Go implementation of Yggdrasil consumes between 18 MB and 40 MB RSS, frequently triggering Linux Out-Of-Memory (
oom-killer) invocations on 64 MB routers sharing RAM with Wi-Fi drivers and firewall tables. - The 32-bit Architecture Block: Upstream Yggdrasil-ng introduced 64-bit atomics (
AtomicU64) for MTU synchronization, causing immediate build and link failures on 32-bit MIPS architectures lacking native 64-bit atomic instructions. - The Solution:
yggnodesolves these problems by fixing 32-bit atomic operations, aggressively stripping unused transport layers, compiling statically against musl libc, and applying link-time optimizations. Under real network load,yggnodeoperates stably at ~2.5 MB RSS with a fully static binary footprint of ~3.4 MB.
The compilation uses --no-default-features --features tun,ctl. The following features are intentionally removed:
| Excluded Feature | Rationale |
|---|---|
quic (QUIC Transport) |
Memory & binary bloat. QUIC requires substantial buffer allocations, timer queues, and complex state machines. For an edge router connecting to standard public peers, QUIC adds unnecessary overhead without performance gain. |
ws (WebSockets) |
Web layer redundancy. WebSocket transport is aimed at browser environments and restrictive corporate firewalls. Router-to-router and router-to-peer links utilize direct TCP or TLS. |
ckr (Crypto Key Routing) |
RAM conservation. Dynamic cryptographic key routing extensions add routing state tables that consume valuable memory on routers with <= 64 MB RAM. Standard Ironwood spanning tree routing is sufficient. |
systemd (systemd integration) |
Platform mismatch. Embedded router operating systems (OpenWrt, Padavan, ASUSWRT, Keenetic, DD-WRT) utilize procd, sysvinit, busybox init, or rc.unslung, never systemd. |
Retained Core Features:
tun: Direct interaction with the Linux kernel L3 TUN driver (/dev/net/tun), creatingygg0with full MTU configuration and kernel routing.ctl: Local control socket protocol for diagnostics and status inspection via command-line utilities (yggdrasil getPeers,yggdrasil getSelf).
- File:
crates/yggdrasil/src/ipv6rwc.rs - Issue: Upstream committed MTU tracking using
AtomicU64. On 32-bit MIPS architectures (mipsel-unknown-linux-musl,mips-unknown-linux-musl), 64-bit atomics are unavailable without software emulation libraries. - Fix: Switched
AtomicU64toAtomicU32. Because IPv6 overlay MTU is mathematically bounded and clamped between 1280 and 65535 bytes, a 32-bit unsigned integer is completely sufficient, eliminating the need for missing 64-bit atomic instructions.
All release binaries are compiled against static musl libc using GCC 16.x cross-toolchains with LTO (opt-level = "z"), -Zbuild-std=std,panic_abort -Zbuild-std-features=optimize_for_size, and section stripping (sstrip). Binaries have zero dynamic dependencies and execute identically on uClibc, musl, or glibc host firmwares.
Each build passes a complete validation cycle: compilation under musl with LTO, extreme ELF section stripping via sstrip, binary execution verification in QEMU (--version), and packaging into distribution ZIP archives with md5 checksums.
| Architecture | Target Triple | Target Hardware / Devices |
|---|---|---|
| mips-ath79-bigendian | mips-unknown-linux-musl |
Qualcomm Atheros AR9xxx / QCA95xx (OpenWrt ath79, soft-float) |
| mipsel-ramips-littleendian | mipsel-unknown-linux-musl |
MediaTek MT7620 / MT7621 / MT7628 (OpenWrt / Padavan / Keenetic ramips, soft-float) |
| armv7-cortexa7-hardfloat | armv7-unknown-linux-musleabihf |
Cortex-A7 / A9, Raspberry Pi 2 / Zero 2W, Orange Pi (hard-float) |
| arm64-aarch64 | aarch64-unknown-linux-musl |
Cortex-A53 / A72, Raspberry Pi 3 / 4 / 5, modern ARM routers |
| x86_64-generic | x86_64-unknown-linux-musl |
64-bit Intel / AMD x86 servers, PC, VM, and VPS |
| i686-x86-32bit | i686-unknown-linux-musl |
32-bit x86 legacy hardware and thin clients |
To guarantee carrier-grade stability on edge routers running unattended for months, yggnode enforces rigorous verification at compile-time and runtime:
-
Memory Safety & Safe Rust Guarantees:
- 100% Safe Rust Core: Memory management is strictly enforced by the Rust compiler ownership, borrowing, and lifetime mechanics without raw pointer manipulation in routing logic.
- Architectural Immunity: Completely immune to memory-corruption vulnerabilities: zero buffer overflows, zero use-after-free, zero double-free, and complete absence of null-pointer dereferencing.
-
Static Analysis & Linting Audit:
- Audited continuously using
cargo clippy --no-default-features --features tun,ctl -p yggdrasil. - Static validation ensures optimal memory access patterns, absence of unintended heap bloat, and verified lock-free state transitions.
- Audited continuously using
-
Automated Test Suite (180+ Unit, Integration & Protocol Tests):
- Passed 100% of test cases (0 failures) covering:
- Cryptography & Signatures: Ed25519 identity key generation, Ed25519-to-Curve25519 conversions, Salsa20 cipher roundtrips, and cryptographic box sealing.
- Routing Algebra & Address Space: IPv6
200::/7cryptographically generated node address calculations,300::/64routed subnet derivations, and Bloom filter encoding/merging. - Stateful In-Kernel Firewall: TCP state tracking (SYN validation, unsolicited inbound packet rejection), ICMPv6 echo handling, fragment dropping, and session garbage collection.
- MTU Clamping (IPv6RWC): Strict mathematical clamping between 1280 and 65535 bytes, preventing packet truncation or fragmentation over lower MTU carriers.
- Config Normalization: Lossless TOML parser preserving user comments, unknown keys, and custom directives across automated config rewrites.
- Passed 100% of test cases (0 failures) covering:
-
Cross-Architecture Runtime Emulation (QEMU):
- Every compiled release artifact (
mips,mipsel,armv7,aarch64,x86_64,i686) undergoes automatic execution verification viaqemu-user-staticwithin GitHub Actions CI before distribution. - Verifies instruction-set compatibility (MIPS32r2, ARM EABI, soft-float ABI) and validates ELF program headers after extreme
sstripoptimization, guaranteeing zeroSIGILL(Illegal Instruction) orExec format errorfaults.
- Every compiled release artifact (
-
Zero-Leak Memory Stabilization on Routers:
- Production deployments on MIPS/MIPSEL routers (Padavan, OpenWrt) demonstrate permanent resident memory stabilization at 2.5 – 3.5 MB VmRSS under active multi-peer peering.
- Ironwood routing trees and peer state tables enforce bounded capacities, preventing heap runaway or memory fragmentation during prolonged 24/7 uptime.
To discover low-latency public peers, you can use the peers_updater utility.
However, when configuring peers on embedded routers, you must follow strict transport rules:
Supported Scheme:
tcp://ONLY: Pure Layer 4 TCP is fully supported and recommended. It establishes immediately, produces negligible CPU overhead, and maintains rock-solid stability.
Unsupported Schemes on Embedded MIPS:
- DO NOT use
tls://: On 32-bit MIPS / MIPSEL processors (MediaTek MT7620/MT7621/MT7628, Qualcomm Atheros AR9xxx), therustlslibrary crashes with a Segmentation fault (signal 11, exit code 139) during TLS handshake state machine initialization and certificate processing. Attempting to connect to atls://peer will immediately kill the daemon process. - DO NOT use
ws://: WebSocket transport is compiled out (--no-default-features) to eliminate heavy HTTP/WebSocket parsing engines and extra memory allocations. - DO NOT use
quic://: QUIC transport is compiled out to eliminate large UDP packet buffer pools, timer state machines, and crypto overhead that trigger out-of-memory crashes on routers with <= 64 MB of RAM.
Summary for peers_updater:
When running ./peers_updater -p, filter and select only lines starting with tcp://. If a node lists both tls://example.com:4443 and tcp://example.com:4442, always configure the tcp:// endpoint.
- Upstream Project: Revertron/Yggdrasil-ng
- Upstream Author: Mikhail f. Revertron and the Yggdrasil Network Contributors
- Base Commit Fork Point:
59e8973d4ed3888ba021785b0808e68c7874449f - License: Mozilla Public License 2.0 (MPL-2.0)
This project is provided free of charge on an "as is" and "as available" basis, without warranties of any kind, whether express, implied, or statutory. The authors and maintainers do not assume any legal responsibility, liability, or obligations for network disruption, data loss, hardware damage, or other consequences arising from using this software. You run it entirely at your own risk.