Files
harmony/data
Sylvain Tremblay 9eeede18b8
Some checks failed
Run Check Script / check (pull_request) Failing after 40s
feat(opnsense): pin physical NIC names to MAC addresses via vendored ethname
On multi-NIC FreeBSD/OPNsense boxes (Wize 5070 and similar), PCIe enumeration
order shuffles igc0/igc1/... across reboots. OPNsense binds wan/lan
assignments to interface names, so a shuffle silently re-points them at the
wrong physical ports and breaks firewall rules.

Validated fix from OPNsense forum #27023 (endorsed by franco): the upstream
`ethname` rc.d script (MIT, © Eric Borisch 2016–2019, frozen at v2.0.1) does
a two-stage rename in early boot — before `netif` — mapping MACs to fixed
interface names.

Vendor the 280-line script inline rather than `pkg install ethname`.
`pkg install` on a fresh ISO often fails because the firmware lags the live
pkg repo, and the firmware-upgrade reboot is precisely the boot we need to
defend against. Vendoring sidesteps the chicken-and-egg.

Adds:

  harmony/data/opnsense/ethname.sh        vendored upstream script (verbatim)
  harmony/data/opnsense/ethname.LICENSE   preserves MIT terms

  bootstrap.rs:
    ETHNAME_SCRIPT (const, include_str!)
    DEFAULT_PHYSICAL_DRIVER_PREFIXES (const)
    list_physical_nics_via_ssh / read_ethname_mac_set_via_ssh /
    install_ethname_via_ssh (pub SSH helpers)

  pin_nic_names module:
    pin_nic_names_step       — the shared one-shot logic
    OPNsensePinNicNamesScore — Score<OPNsenseBootstrapTopology> for
                               ad-hoc re-pinning / standalone use

OPNsenseBootstrapScore composes pin_nic_names_step internally as a mandatory
step between the web UI dance and API key mint — every firewall
bootstrapped through harmony gets pinned NIC names automatically, no caller
code change required. Idempotent: re-running on a firewall whose MAC set
already matches /etc/rc.conf.d/ethname is a NOOP.

The existence probe for the config file is wrapped in `sh -c '...'` because
OPNsense's root login shell is /bin/csh (tcsh); bare Bourne if/then/else
fails there. Simple `&&` chains (the pattern in the other SSH helpers) work
in both shells.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 10:49:59 -04:00
..