From 4c17304aa250e906769ae3307005e1f3fabf5e8b Mon Sep 17 00:00:00 2001 From: CyberMind-FR Date: Tue, 28 Jul 2026 19:26:28 +0200 Subject: [PATCH] feat(wan): package secubox-wan-link-guard + netplan static fallback (backport live gk2 fix) (ref #913) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backports the live gk2 WAN link guard into source as a proper package (mirrors the secubox-frigate-diskguard skeleton): - sbin/secubox-wan-link-guard: mvpp2 eth2 pause-off (ethtool -A) + renegotiate (ethtool -r) + lan0 parasite route/addr cleanup + force default via eth2. NEVER ip link down/up (wedges the comphy). Tunable via /etc/default. - secubox-wan-link-guard.service + boot/30s .timer - 10-secubox-eth2-noflowctl.link: flow-control off at eth2 appearance (boot) - secubox-eth2-flowctl-off.service backstop (installed, left disabled; .link supersedes it, matching live) - postinst migrates the pre-dpkg hand-placed copies out of /etc/systemd + /usr/local/sbin so the packaged units win, then enables the timer. netplan (board/mochabin): add static fallback 192.168.1.200/24 on eth2 at route-metric 200 (higher than the DHCP route's 100) so the box is always reachable even without a lease — closes #913 task 1. Source-only; not applied live (avoids a remote WAN blip on the already-marginal link). Verified on gk2: install migrated the old units, timer enabled+active, guard ran clean (Result=success), WAN gateway stayed reachable throughout. Co-Authored-By: Gerald KERMA --- board/mochabin/netplan/00-secubox.yaml | 12 ++++ .../secubox-wan-link-guard/debian/changelog | 12 ++++ .../secubox-wan-link-guard/debian/control | 24 ++++++++ .../secubox-wan-link-guard/debian/postinst | 29 ++++++++++ packages/secubox-wan-link-guard/debian/rules | 24 ++++++++ .../debian/source/format | 1 + .../network/10-secubox-eth2-noflowctl.link | 12 ++++ .../sbin/secubox-wan-link-guard | 58 +++++++++++++++++++ .../systemd/secubox-eth2-flowctl-off.service | 13 +++++ .../systemd/secubox-wan-link-guard.service | 11 ++++ .../systemd/secubox-wan-link-guard.timer | 9 +++ 11 files changed, 205 insertions(+) create mode 100644 packages/secubox-wan-link-guard/debian/changelog create mode 100644 packages/secubox-wan-link-guard/debian/control create mode 100755 packages/secubox-wan-link-guard/debian/postinst create mode 100755 packages/secubox-wan-link-guard/debian/rules create mode 100644 packages/secubox-wan-link-guard/debian/source/format create mode 100644 packages/secubox-wan-link-guard/network/10-secubox-eth2-noflowctl.link create mode 100755 packages/secubox-wan-link-guard/sbin/secubox-wan-link-guard create mode 100644 packages/secubox-wan-link-guard/systemd/secubox-eth2-flowctl-off.service create mode 100644 packages/secubox-wan-link-guard/systemd/secubox-wan-link-guard.service create mode 100644 packages/secubox-wan-link-guard/systemd/secubox-wan-link-guard.timer diff --git a/board/mochabin/netplan/00-secubox.yaml b/board/mochabin/netplan/00-secubox.yaml index c9fe7a4c..b0b37904 100644 --- a/board/mochabin/netplan/00-secubox.yaml +++ b/board/mochabin/netplan/00-secubox.yaml @@ -15,6 +15,18 @@ network: dhcp4-overrides: use-routes: true route-metric: 100 + # Static fallback so the box is always reachable at 192.168.1.200 even + # when DHCP never leases (issue #913). Kept at a HIGHER route-metric than + # the DHCP route (100) so the lease wins whenever it exists; the static + # default only carries traffic when DHCP is down. This IP belongs on the + # WAN (eth2), never on lan0 — secubox-wan-link-guard strips any parasite + # copy that appears on lan0. + addresses: + - 192.168.1.200/24 + routes: + - to: default + via: 192.168.1.254 + metric: 200 lan0: {optional: true} lan1: {optional: true} lan2: {optional: true} diff --git a/packages/secubox-wan-link-guard/debian/changelog b/packages/secubox-wan-link-guard/debian/changelog new file mode 100644 index 00000000..d83665b9 --- /dev/null +++ b/packages/secubox-wan-link-guard/debian/changelog @@ -0,0 +1,12 @@ +secubox-wan-link-guard (1.0.0-1~bookworm1) bookworm; urgency=medium + + * Initial packaging: backport the live gk2 WAN link guard into source (#913). + Ships /usr/sbin/secubox-wan-link-guard (mvpp2 eth2 pause-off + renegotiate + + lan0 parasite route/addr cleanup, no `ip link down/up`), its .service + + boot/30s .timer, the 10-secubox-eth2-noflowctl.link (flow-control off at + eth2 appearance), and the secubox-eth2-flowctl-off backstop unit. + Tunable via /etc/default/secubox-wan-link-guard. postinst migrates the + pre-dpkg hand-placed copies out of /etc/systemd and /usr/local/sbin so the + packaged units are authoritative. + + -- Gerald KERMA Tue, 28 Jul 2026 19:30:00 +0200 diff --git a/packages/secubox-wan-link-guard/debian/control b/packages/secubox-wan-link-guard/debian/control new file mode 100644 index 00000000..f90276ca --- /dev/null +++ b/packages/secubox-wan-link-guard/debian/control @@ -0,0 +1,24 @@ +Source: secubox-wan-link-guard +Section: net +Priority: optional +Maintainer: Gerald KERMA +Build-Depends: debhelper-compat (= 13) +Standards-Version: 4.6.2 + +Package: secubox-wan-link-guard +Architecture: all +Depends: ${misc:Depends}, ethtool, iproute2, iputils-ping +Description: WAN mvpp2 marginal-link guard for SecuBox (MOCHAbin) + Board-specific watchdog for the MOCHAbin (Marvell Armada, mvpp2) WAN port, + which recurrently goes dead on gk2 through three stacked faults: the MAC TX + wedges under upstream flow-control PAUSE frames, gigabit auto-negotiation is + marginal through the intermediate hub, and a parasite default route/duplicate + host IP appears on lan0. + . + Ships a oneshot guard (ethtool pause-off + renegotiate + route/addr cleanup — + never `ip link down/up`, which wedges the comphy), a boot+30s timer, a + systemd .link that disables flow-control the moment eth2 appears, and a + flow-control backstop unit. Tunable via /etc/default/secubox-wan-link-guard. + . + MOCHAbin-only: on other boards eth2/lan0 do not match and the guard is a + no-op. See /usr/share/doc/secubox/FAQ-NETWORK-WAN-RECOVERY.md (ref #913). diff --git a/packages/secubox-wan-link-guard/debian/postinst b/packages/secubox-wan-link-guard/debian/postinst new file mode 100755 index 00000000..1e640cee --- /dev/null +++ b/packages/secubox-wan-link-guard/debian/postinst @@ -0,0 +1,29 @@ +#!/bin/bash +set -e +case "$1" in + configure) + # Migration: the guard was first deployed on gk2 by hand, OUTSIDE dpkg + # (units in /etc/systemd/system, script in /usr/local/sbin). Those shadow + # the packaged copies (/etc wins over /usr/lib for systemd; PATH picks + # /usr/local/sbin first) — remove them so the package is authoritative. + for u in secubox-wan-link-guard.service secubox-wan-link-guard.timer secubox-eth2-flowctl-off.service; do + if [ -e "/etc/systemd/system/$u" ]; then + systemctl disable "$u" >/dev/null 2>&1 || true + rm -f "/etc/systemd/system/$u" + fi + done + rm -f /etc/systemd/network/10-secubox-eth2-noflowctl.link + rm -f /usr/local/sbin/secubox-wan-link-guard + + systemctl daemon-reload || true + # The periodic guard: enable + start the timer (boot + every 30s). The + # oneshot guard.service is triggered BY the timer; the flowctl backstop + # stays disabled (the .link supersedes it, matching the live board). + systemctl enable --now secubox-wan-link-guard.timer >/dev/null 2>&1 || true + # Apply once now so the flow-control/route fix takes effect without waiting + # for the first timer tick or a reboot (idempotent, safe to re-run). + systemctl start secubox-wan-link-guard.service >/dev/null 2>&1 || true + ;; +esac +#DEBHELPER# +exit 0 diff --git a/packages/secubox-wan-link-guard/debian/rules b/packages/secubox-wan-link-guard/debian/rules new file mode 100755 index 00000000..1b1d2de3 --- /dev/null +++ b/packages/secubox-wan-link-guard/debian/rules @@ -0,0 +1,24 @@ +#!/usr/bin/make -f +%: + dh $@ + +override_dh_auto_install: + install -d debian/secubox-wan-link-guard/usr/sbin + install -m 755 sbin/secubox-wan-link-guard debian/secubox-wan-link-guard/usr/sbin/secubox-wan-link-guard + # systemd units — placed explicitly in usr/lib/systemd/system. Enable/start + # is handled below (timer) and by postinst; the oneshots are NOT started at + # install time (the guard mutates routing — let the timer/boot drive it). + install -d debian/secubox-wan-link-guard/usr/lib/systemd/system + install -m 644 systemd/secubox-wan-link-guard.service debian/secubox-wan-link-guard/usr/lib/systemd/system/ + install -m 644 systemd/secubox-wan-link-guard.timer debian/secubox-wan-link-guard/usr/lib/systemd/system/ + install -m 644 systemd/secubox-eth2-flowctl-off.service debian/secubox-wan-link-guard/usr/lib/systemd/system/ + # networkd .link (applied by udevd when eth2 appears) + install -d debian/secubox-wan-link-guard/usr/lib/systemd/network + install -m 644 network/10-secubox-eth2-noflowctl.link debian/secubox-wan-link-guard/usr/lib/systemd/network/ + +override_dh_installsystemd: + # Suppress dh's auto enable/start (it would run the oneshot guard at install + # and enable the flowctl backstop the live board keeps disabled). postinst + # does the precise enabling; #DEBHELPER# still emits daemon-reload + the + # stop-on-remove hooks for all shipped units. + dh_installsystemd --no-enable --no-start diff --git a/packages/secubox-wan-link-guard/debian/source/format b/packages/secubox-wan-link-guard/debian/source/format new file mode 100644 index 00000000..89ae9db8 --- /dev/null +++ b/packages/secubox-wan-link-guard/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/packages/secubox-wan-link-guard/network/10-secubox-eth2-noflowctl.link b/packages/secubox-wan-link-guard/network/10-secubox-eth2-noflowctl.link new file mode 100644 index 00000000..7b878ab6 --- /dev/null +++ b/packages/secubox-wan-link-guard/network/10-secubox-eth2-noflowctl.link @@ -0,0 +1,12 @@ +# SecuBox: the mvpp2 eth2 MAC TX wedges when the upstream (Freebox) floods +# flow-control PAUSE frames — good_octets_sent stays at 0 and all unicast dies. +# Confirmed fix 2026-07-28: disable flow-control pause at the .link level so it +# is applied by udevd the moment eth2 appears (covers boot-time DHCP, before the +# guard timer's first tick). See /usr/share/doc/secubox/FAQ-NETWORK-WAN-RECOVERY.md +[Match] +OriginalName=eth2 + +[Link] +AutoNegotiationFlowControl=no +RXFlowControl=no +TXFlowControl=no diff --git a/packages/secubox-wan-link-guard/sbin/secubox-wan-link-guard b/packages/secubox-wan-link-guard/sbin/secubox-wan-link-guard new file mode 100755 index 00000000..e81b0f46 --- /dev/null +++ b/packages/secubox-wan-link-guard/sbin/secubox-wan-link-guard @@ -0,0 +1,58 @@ +#!/bin/bash +# SPDX-License-Identifier: LicenseRef-CMSD-1.0 +# Copyright (c) 2026 CyberMind — Gérald Kerma +# Source-Disclosed License — All rights reserved except as expressly granted. +# See LICENCE-CMSD-1.0.md for terms. + +# SecuBox-Deb :: secubox-wan-link-guard +# MOCHAbin (Marvell Armada mvpp2) WAN marginal-link workaround. Three stacked +# problems on gk2 (see /usr/share/doc/secubox/FAQ-NETWORK-WAN-RECOVERY.md): +# (1) the mvpp2 MAC TX wedges when the upstream floods flow-control PAUSE +# frames -> disable pause (idempotent, non-disruptive); +# (2) gigabit auto-negotiation is marginal through the hub -> renegotiate +# (ethtool -r) until the gateway answers again; +# (3) a parasite default route / duplicate host IP appears on lan0 -> drop it +# and force the default via the WAN iface. +# +# NEVER `ip link set down/up` here: that wedges the comphy and needs a +# cold boot. Recovery uses ONLY ethtool -r / -A and route/addr fixes. +# +# set +e on purpose: every step is best-effort and idempotent; a failing step +# must never abort the recovery sequence. +set +e + +# Board defaults (gk2 / mochabin). Override in /etc/default/secubox-wan-link-guard. +IFACE=eth2 +GW=192.168.1.254 +FALLBACK_ADDR=192.168.1.200/24 +PARASITE_IFACE=lan0 +RENEGO_TRIES=6 +# shellcheck disable=SC1091 +[ -r /etc/default/secubox-wan-link-guard ] && . /etc/default/secubox-wan-link-guard + +# (1) flow-control pause off (idempotent, non disruptif) +ethtool -A "$IFACE" autoneg off rx off tx off 2>/dev/null + +# (3) tuer la route/IP parasite portée par $PARASITE_IFACE + forcer le default via $IFACE +ip route del default dev "$PARASITE_IFACE" 2>/dev/null +ip addr del "$FALLBACK_ADDR" dev "$PARASITE_IFACE" 2>/dev/null +ip route show default | grep -q "dev $IFACE" \ + || ip route replace default via "$GW" dev "$IFACE" 2>/dev/null + +# (2) si la gateway ne répond pas -> renégocier jusqu'à accroche +if ! ping -c1 -W2 "$GW" >/dev/null 2>&1; then + t=0 + while [ "$t" -lt "$RENEGO_TRIES" ]; do + t=$((t + 1)) + ethtool -r "$IFACE" 2>/dev/null + sleep 4 + ethtool -A "$IFACE" autoneg off rx off tx off 2>/dev/null + ip route replace default via "$GW" dev "$IFACE" 2>/dev/null + if ping -c1 -W2 "$GW" >/dev/null 2>&1; then + logger -t sbx-wan-guard "link recovered after $t renego" + break + fi + done +fi + +exit 0 diff --git a/packages/secubox-wan-link-guard/systemd/secubox-eth2-flowctl-off.service b/packages/secubox-wan-link-guard/systemd/secubox-eth2-flowctl-off.service new file mode 100644 index 00000000..f7459c50 --- /dev/null +++ b/packages/secubox-wan-link-guard/systemd/secubox-eth2-flowctl-off.service @@ -0,0 +1,13 @@ +[Unit] +Description=SecuBox: disable eth2 flow-control pause (mvpp2 MAC TX wedge workaround) +Documentation=file:///usr/share/doc/secubox/FAQ-NETWORK-WAN-RECOVERY.md +After=sys-subsystem-net-devices-eth2.device +Wants=sys-subsystem-net-devices-eth2.device + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/sbin/ethtool -A eth2 autoneg off rx off tx off + +[Install] +WantedBy=multi-user.target diff --git a/packages/secubox-wan-link-guard/systemd/secubox-wan-link-guard.service b/packages/secubox-wan-link-guard/systemd/secubox-wan-link-guard.service new file mode 100644 index 00000000..3ed5bc7b --- /dev/null +++ b/packages/secubox-wan-link-guard/systemd/secubox-wan-link-guard.service @@ -0,0 +1,11 @@ +[Unit] +Description=SecuBox WAN link guard (mvpp2 eth2: pause-off + renegotiate + route) +Documentation=file:///usr/share/doc/secubox/FAQ-NETWORK-WAN-RECOVERY.md +After=network.target + +[Service] +Type=oneshot +ExecStart=/usr/sbin/secubox-wan-link-guard + +[Install] +WantedBy=multi-user.target diff --git a/packages/secubox-wan-link-guard/systemd/secubox-wan-link-guard.timer b/packages/secubox-wan-link-guard/systemd/secubox-wan-link-guard.timer new file mode 100644 index 00000000..e32d17f7 --- /dev/null +++ b/packages/secubox-wan-link-guard/systemd/secubox-wan-link-guard.timer @@ -0,0 +1,9 @@ +[Unit] +Description=SecuBox WAN link guard — periodic check + +[Timer] +OnBootSec=20 +OnUnitActiveSec=30 + +[Install] +WantedBy=timers.target