diff --git a/build/systemd/spinifex-vpcd.service b/build/systemd/spinifex-vpcd.service index 73f1b5cf7..083566a32 100644 --- a/build/systemd/spinifex-vpcd.service +++ b/build/systemd/spinifex-vpcd.service @@ -1,7 +1,7 @@ [Unit] Description=Spinifex VPC Daemon (OVN Networking) PartOf=spinifex.target -After=spinifex-nats.service spinifex-daemon.service +After=spinifex-nats.service spinifex-daemon.service systemd-networkd.service openvswitch-switch.service Wants=spinifex-nats.service [Service] diff --git a/scripts/reset-dev-env.sh b/scripts/reset-dev-env.sh index a09f8373c..c0b3adabe 100755 --- a/scripts/reset-dev-env.sh +++ b/scripts/reset-dev-env.sh @@ -107,6 +107,16 @@ if ip link show veth-wan-br >/dev/null 2>&1; then sudo ip link del veth-wan-br 2>/dev/null || true fi +# Remove veth persistence units (Fix 1, mulga-998.b). Without this, systemd-networkd +# recreates the veth on next reboot even after a full dev reset. +if [ -e /etc/systemd/network/15-spinifex-veth-wan.netdev ] || \ + [ -e /etc/systemd/network/15-spinifex-veth-wan.network ]; then + echo " Deleting veth persistence units" + sudo rm -f /etc/systemd/network/15-spinifex-veth-wan.netdev \ + /etc/systemd/network/15-spinifex-veth-wan.network + sudo networkctl reload 2>/dev/null || true +fi + # Remove macvlan interfaces created by setup-ovn.sh for iface in $(ip -o link show type macvlan 2>/dev/null | awk -F': ' '{print $2}' | grep '^spx-ext-'); do echo " Deleting macvlan: $iface" diff --git a/scripts/setup-ovn.sh b/scripts/setup-ovn.sh index b12fe39ed..a8f21c9ba 100755 --- a/scripts/setup-ovn.sh +++ b/scripts/setup-ovn.sh @@ -305,6 +305,19 @@ if [ -n "$WAN_BRIDGE" ]; then echo "" echo "Step 3b: Configuring WAN bridge ($WAN_BRIDGE) for public subnet uplink..." + # Rip down any stale veth persistence from a previous veth-mode install + # when switching to any non-veth mode. Idempotent — each command uses + # --if-exists / 2>/dev/null to tolerate absence. Without this, the + # veth pair re-materialises on reboot and fights the current mode's + # bridge plumbing (Fix 1, mulga-998.b, per D17). + if [ "$WAN_BRIDGE_MODE" != "veth" ]; then + sudo rm -f /etc/systemd/network/15-spinifex-veth-wan.netdev \ + /etc/systemd/network/15-spinifex-veth-wan.network + sudo networkctl reload 2>/dev/null || true + sudo ovs-vsctl --if-exists del-port "$WAN_BRIDGE" veth-wan-ovs + sudo ip link del veth-wan-br 2>/dev/null || true + fi + case "$WAN_BRIDGE_MODE" in existing) # Already an OVS bridge (from a previous run or explicit --wan-bridge). @@ -357,6 +370,31 @@ if [ -n "$WAN_BRIDGE" ]; then echo " $LINUX_BRIDGE (Linux) ↔ veth pair ↔ $WAN_BRIDGE (OVS)" echo " $LINUX_BRIDGE keeps its IP and routes — no interruption" + + # Persist the veth pair across reboot via systemd-networkd. Veths + # are kernel-only and vanish on reboot; without persistence vpcd + # starts with the OVS port pointing at a nonexistent peer and + # silently falls back to direct mode (Fix 1, mulga-998.b). + VETH_NETDEV="/etc/systemd/network/15-spinifex-veth-wan.netdev" + VETH_NETWORK="/etc/systemd/network/15-spinifex-veth-wan.network" + sudo tee "$VETH_NETDEV" >/dev/null </dev/null </dev/null || true + echo " wrote $VETH_NETDEV + $VETH_NETWORK (veth persists on reboot)" ;; direct)