commit d46be19220fa2b0c740315e9d65e87ceabc19883
parent 9427b1657ea91c724eb631761002facaa7a1e6c5
Author: finwo <finwo@pm.me>
Date: Thu, 17 Sep 2026 22:38:03 +0200
Add basic ifupdown functionality to unosd
Diffstat:
6 files changed, 92 insertions(+), 12 deletions(-)
diff --git a/mk/rootfs.sh b/mk/rootfs.sh
@@ -47,7 +47,7 @@ apk_ns "${APK}" --root "${ROOTFS}" --initdb \
echo "==> UNOS system (fully trusted from here on)"
apk_ns "${APK}" --root "${ROOTFS}" \
--cache-dir "${CACHE}" --repository "${REPO}" \
- add base-files glibc busybox unos-firstboot tinyssh libmnl zlib openssl iproute2 apk-tools linux-longterm grub popt efivar efibootmgr
+ add base-files glibc busybox unos-firstboot tinyssh libmnl zlib openssl iproute2 apk-tools linux-longterm grub popt efivar efibootmgr unosd
# Deterministic loader cache: package post-installs refresh it during the
# transaction, but assembly must not depend on script-execution order.
diff --git a/packages/base-files/files/network/interfaces b/packages/base-files/files/network/interfaces
@@ -0,0 +1,7 @@
+# UNOS network interfaces
+# Cumulus style: `iface <name>` preferred, `inet` is optional.
+# See ifupdown2 docs for hooks: pre-up/post-up etc.
+auto lo
+iface lo
+ address 127.0.0.1/8
+ address ::1/128
diff --git a/packages/base-files/files/network/ports b/packages/base-files/files/network/ports
@@ -0,0 +1,53 @@
+# UNOS switch port configuration
+#
+# Read from /etc/network/ports, or if that file is absent, from every
+# /etc/network/ports.d/*.cnf drop-in.
+#
+# SCOPE
+#
+# This file covers physical-layer properties of switch ports only. Anything
+# the Linux kernel already models on a netdev belongs in
+# /etc/network/interfaces.d/ and is applied by ifup:
+#
+# addresses, gateway, netmask, metric ... iface <name> inet static
+# mtu .................................. mtu <bytes>
+# mac address .......................... hwaddress <addr>
+# admin state .......................... auto / allow-hotplug / ifdown
+# vlans ................................ iface swp1.100
+#
+# unosd learns all of that from netlink and mirrors it into the ASIC, so
+# configuring it here as well would create two sources of truth for one value.
+# Directives belonging to ifupdown are rejected rather than ignored.
+#
+# DIRECTIVES
+#
+# speed <mbit> port speed in Mbit/s
+# fec off|auto|rs|baser forward error correction
+# autoneg on|off
+# breakout <profile> e.g. 4x25g -- splits one cage into several
+# ports. Structural: it decides which netdevs
+# exist at all, so it is applied before ifup runs.
+#
+# On generic x86_64 there is no ASIC and none of these apply; the kernel
+# backend ignores them and Linux does the forwarding.
+
+port swp1
+ speed 25000
+ fec rs
+ autoneg off
+
+port swp2
+ speed 25000
+ fec rs
+ autoneg off
+
+# 100G uplink
+port swp49
+ speed 100000
+ fec rs
+
+# 100G cage split into 4x25G -- yields swp50s0..swp50s3
+port swp50
+ breakout 4x25g
+ speed 25000
+ fec rs
diff --git a/packages/base-files/template b/packages/base-files/template
@@ -1,7 +1,7 @@
# Template file for 'base-files'
pkgname=base-files
version=0.1.0
-revision=4
+revision=5
short_desc="UNOS filesystem skeleton - passwd, profile, nsswitch, fstab"
maintainer="finwo <finwo@pm.me>"
license="GPL-2.0-only"
@@ -27,6 +27,10 @@ do_install() {
vinstall ${FILESDIR}/os-release 644 etc
vinstall ${FILESDIR}/inittab 644 etc
vinstall ${FILESDIR}/rcS 755 etc/init.d rcS
+ vinstall ${FILESDIR}/network/ports 644 etc/network ports
+ vinstall ${FILESDIR}/network/interfaces 644 etc/network interfaces
+ install -d "${DESTDIR}/etc/network/ports.d"
+ install -d "${DESTDIR}/etc/network/interfaces.d"
install -d -m700 "${DESTDIR}/root"
install -d "${DESTDIR}/etc/ld.so.conf.d"
# standard mount points (fstab references /run and /tmp; init mounts the
diff --git a/packages/busybox/template b/packages/busybox/template
@@ -1,7 +1,7 @@
# Template file for 'busybox'
pkgname=busybox
version=1.36.1
-revision=6
+revision=7
short_desc="Swiss Army knife of embedded Linux utilities"
maintainer="finwo <finwo@pm.me>"
license="GPL-2.0-only"
@@ -26,16 +26,18 @@ depends=
# otherwise; six symbols gate them in bbunzip.c, all six go; kernel
# initramfs xz stays independent via CONFIG_RD_XZ),
# udhcpd (dnsmasq covers the server side), httpd/inetd (tcpsvd is our
-# super-server).
+# super-server), IFUP (unosd owns /etc/network/interfaces via unosc, busybox
+# ifupdown would conflict and its `iface <name>` parser is for old
+# `iface <name> inet static` only -- cumulus `iface <name>` fails there).
# Untouched (defconfig default) until their design lands: SYSLOGD/KLOGD.
# No checked-in .config on purpose: defconfig + CFG_* is the source of truth
# (this kconfig has no savedefconfig anyway); the assertions below enforce it.
CFG_ON="INIT HALT POWEROFF REBOOT GETTY LOGIN MOUNT UMOUNT SWITCH_ROOT ASH ASH_JOB_CONTROL RUNSV RUNSVDIR SV SVLOGD CHPST SETUIDGID TCPSVD UDHCPC"
-CFG_OFF="IP FEATURE_IP_ADDRESS FEATURE_IP_LINK FEATURE_IP_ROUTE FEATURE_IP_RULE FEATURE_IP_TUNNEL TC LDCONFIG UNLZMA LZCAT LZMA UNXZ XZCAT XZ UDHCPD HTTPD INETD"
+CFG_OFF="IP FEATURE_IP_ADDRESS FEATURE_IP_LINK FEATURE_IP_ROUTE FEATURE_IP_RULE FEATURE_IP_TUNNEL TC LDCONFIG UNLZMA LZCAT LZMA UNXZ XZCAT XZ UDHCPD HTTPD INETD IFUP IFDOWN"
# applet names as `busybox --list` prints them
REQUIRE="init halt poweroff reboot getty login mount umount switch_root ash runsv runsvdir sv svlogd chpst setuidgid tcpsvd udhcpc"
-FORBID="ip tc ldconfig unlzma lzcat lzma unxz xzcat xz udhcpd httpd inetd"
+FORBID="ip tc ldconfig unlzma lzcat lzma unxz xzcat xz udhcpd httpd inetd ifup ifdown"
set_config() {
# $1 = symbol, $2 = y|n
diff --git a/packages/unosd/template b/packages/unosd/template
@@ -1,19 +1,33 @@
# Template file for 'unosd'
pkgname=unosd
version=0.1.0
-revision=1
+revision=3
short_desc="UNOS control plane daemon - kernel netlink mirror into the dataplane"
maintainer="finwo <finwo@pm.me>"
license="GPL-2.0-only"
homepage="https://unos.finwo.dev"
-depends="busybox"
+depends="busybox iproute2"
+
+do_build() {
+ # Build unosd via its own Makefile (assembles build/<target> and runs dep)
+ make -C "${UNOS_MKDIR}/../src/unosd" -j"$(nproc)"
+ [ -x "${UNOS_MKDIR}/../src/unosd/build/linux-glibc-amd64/unosd" ] || die "unosd binary missing after build"
+ # Build unosc (thin IPC client) directly -- not via the unosd Makefile's wildcard
+ # which would incorrectly link it into unosd
+ cc -Wall -Wextra -O2 -o "${UNOS_MKDIR}/../src/unosd/build/linux-glibc-amd64/unosc" \
+ "${UNOS_MKDIR}/../src/unosd/src/cli/unosc.c"
+ [ -x "${UNOS_MKDIR}/../src/unosd/build/linux-glibc-amd64/unosc" ] || die "unosc binary missing"
+}
do_install() {
- # TODO(phase0): wire the src/unosd build into CI so the binary lands here.
- # The service contract (run/check/log) is fixed now; the build recipe
- # follows with the package pipeline.
- # vinstall ${WRKSRC}/unosd 755 usr/bin unosd
+ vinstall "${UNOS_MKDIR}/../src/unosd/build/linux-glibc-amd64/unosd" 755 usr/bin unosd
+ vinstall "${UNOS_MKDIR}/../src/unosd/build/linux-glibc-amd64/unosc" 755 usr/bin unosc
+ # ifup/ifdown/ifquery/ifreload as symlinks to unosc (argv[0] dispatch)
+ for link in ifup ifdown ifquery ifreload; do
+ ln -sfn unosc "${DESTDIR}/usr/bin/${link}"
+ done
vinstall ${FILESDIR}/unosd-run 755 etc/sv/unosd run
vinstall ${FILESDIR}/unosd-check 755 etc/sv/unosd check
vinstall ${FILESDIR}/unosd-log-run 755 etc/sv/unosd/log run
+ install -d "${DESTDIR}/var/log/unosd"
}