fix(gateway): reject LAN interfaces without carrier

A gateway with the selected Ethernet cable unplugged can still open an
AF_PACKET socket and join the relay room. That makes clients see a connected LAN
gateway even though DHCP and LAN discovery cannot make the physical round trip.

Check the selected Linux interface's sysfs carrier file before creating the raw
socket. If sysfs reports carrier 0, fail before the gateway joins the relay.
Missing or unrecognized carrier files remain allowed so this does not reject
interfaces where the kernel cannot expose link state in that form. README and
TESTING now document the preflight and the operator fix.

Test Plan:
All cargo commands used these environment variables:
RUSTUP_HOME=/tmp/softlan-vpn-rustup
CARGO_HOME=/tmp/softlan-vpn-cargo

- cargo test -p lanparty-gateway \
  packet::tests::detects_disconnected_interfaces_from_sysfs_carrier
- cargo test -p lanparty-gateway
- cargo fmt --check
- cargo test --workspace
- cargo clippy --workspace --all-targets -- -D warnings
- git diff --check

Refs: PLAN.md wired Ethernet gateway requirement
This commit is contained in:
2026-05-22 04:48:12 +02:00
parent ac03bf1616
commit 217469edf0
3 changed files with 75 additions and 7 deletions
+7 -5
View File
@@ -173,16 +173,18 @@ cargo run -p lanparty-gateway -- \
The gateway first opens the wired LAN interface as an AF_PACKET socket with
promiscuous packet membership, then connects to the relay as `role = gateway`
and completes the control-stream hello/welcome handshake. That startup order
keeps an invalid or wireless interface from briefly advertising a gateway that
cannot bridge. Once both sides are ready, it bridges Ethernet frames between the
relay and wired LAN until shutdown. It captures whole LAN frames up to the
keeps an invalid, wireless, or unplugged interface from briefly advertising a
gateway that cannot bridge. Once both sides are ready, it bridges Ethernet
frames between the relay and wired LAN until shutdown. It captures whole LAN
frames up to the
overlay payload-length ceiling before deciding whether they fit the tunnel. It
never fragments Ethernet frames; LAN frames whose encoded datagrams exceed the
negotiated QUIC budget are counted, dropped, and logged instead of stopping the
bridge.
`--relay` accepts a DNS name or socket address; bare hosts default to UDP/443.
The gateway rejects Linux interfaces that sysfs identifies as Wi-Fi; managed
wireless NICs are not supported for the physical LAN bridge.
The gateway rejects Linux interfaces that sysfs identifies as Wi-Fi, and rejects
wired interfaces whose sysfs carrier state reports no link; managed wireless
NICs are not supported for the physical LAN bridge.
It tracks remote-client source MACs seen from relay traffic and periodically
emits small CAM refresh frames so the physical switch keeps those MACs
associated with the gateway port. Gateway