From cdf384d7300a4f08307fd1c78609ebaa6a6b0d3e Mon Sep 17 00:00:00 2001 From: Arjen <18398758+Origami74@users.noreply.github.com> Date: Tue, 7 Jul 2026 15:10:04 +0200 Subject: [PATCH] docs(openwrt): document STA-on-same-radio channel capture; warn in fips-mesh-setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Field-found third silent-non-peering cause: a client (sta) interface must follow its upstream AP's channel, the whole radio follows the STA, and a mesh pinned to a different channel never joins — visible as 'type mesh point' with no channel line and an empty station dump. It also does not recover when the STA disconnects (wifi reload + fips restart needed), so a roaming uplink is fundamentally incompatible with a fixed-channel mesh on the same radio. Add to the guide's triage and constraints, and make fips-mesh-setup warn when the target radio carries a STA. --- docs/how-to/set-up-80211s-mesh-backhaul.md | 22 +++++++++++++++++-- .../openwrt-ipk/files/usr/bin/fips-mesh-setup | 15 +++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/docs/how-to/set-up-80211s-mesh-backhaul.md b/docs/how-to/set-up-80211s-mesh-backhaul.md index 44736f8..eb5038a 100644 --- a/docs/how-to/set-up-80211s-mesh-backhaul.md +++ b/docs/how-to/set-up-80211s-mesh-backhaul.md @@ -174,7 +174,16 @@ in this order: 1. **Channel mismatch** (the most common cause): compare `iw dev fips-mesh0 info` on both routers — mesh ID *and* channel must match exactly. -2. **Is the other router transmitting at all?** +2. **The mesh interface never joined** — `iw dev fips-meshX info` + shows `type mesh point` but **no channel line**, and `station dump` + is empty. Usual cause: a client (`sta`) interface on the same + radio. A STA must follow its upstream AP's channel, the whole + radio follows the STA, and a mesh pinned to a different channel + silently stays down. Check for a STA sharing the radio + (`iw dev`, look for `type managed` on the same phy), compare + `iw dev info | grep channel`, and re-pin the mesh + channel to match — on every backhaul router. +3. **Is the other router transmitting at all?** ```sh iw dev fips-mesh0 scan | grep -i -B4 "MESH ID" @@ -186,7 +195,7 @@ in this order: CAC wait, and confirm the country code is set (`uci get wireless.radio1.country`) — an unset regdomain can block channels entirely. -3. `logread | grep -iE "mesh|fips-mesh0"` on both sides. +4. `logread | grep -iE "mesh|fips-mesh0"` on both sides. Then the FIPS layer on top: @@ -217,3 +226,12 @@ sight. - **Radio links are lossy.** A neighbor at the edge of range will form an 802.11s peering yet deliver a fraction of its frames. Expect link-quality effects that don't exist on wired Ethernet. +- **A client (STA) uplink on the same radio owns the channel.** The + STA must follow whatever channel its upstream AP uses; every other + interface on that radio follows the STA. A mesh pinned to a + different channel silently never joins, and it does **not** recover + when the STA disconnects — a `wifi reload` (plus a fips restart) is + needed. A *roaming* uplink (travel-router / hotspot-chasing setups) + is fundamentally incompatible with a fixed-channel mesh on the same + radio: dedicate the mesh to the radio the STA never uses, and treat + any mesh sharing a STA radio as best-effort. diff --git a/packaging/openwrt-ipk/files/usr/bin/fips-mesh-setup b/packaging/openwrt-ipk/files/usr/bin/fips-mesh-setup index 3477c99..942c7c5 100755 --- a/packaging/openwrt-ipk/files/usr/bin/fips-mesh-setup +++ b/packaging/openwrt-ipk/files/usr/bin/fips-mesh-setup @@ -152,6 +152,21 @@ if [ -z "$CHANNEL" ] || [ "$CHANNEL" = "auto" ]; then echo " uci set wireless.$RADIO.channel='36' && uci commit wireless && wifi reload" >&2 fi +# A client (sta) interface on the same radio follows its upstream AP's +# channel and drags every other interface with it — a mesh pinned to a +# different channel silently never joins, and does not recover when the +# STA disconnects. +for s in $(uci show wireless 2>/dev/null | sed -n "s/^wireless\.\([^.]*\)\.mode='sta'$/\1/p"); do + if [ "$(uci -q get "wireless.$s.device")" = "$RADIO" ]; then + echo "Warning: $RADIO also carries client interface '$s' (mode 'sta')." >&2 + echo "The whole radio follows that STA's upstream channel — a mesh" >&2 + echo "pinned to a different channel stays down silently. Align the" >&2 + echo "mesh channel with the upstream AP, or put the mesh on a radio" >&2 + echo "without a STA (a roaming uplink is incompatible with a" >&2 + echo "fixed-channel mesh on the same radio)." >&2 + fi +done + # --------------------------------------------------------------------------- # Network: unmanaged interface so netifd brings the netdev up. No IP config — # the FIPS Ethernet transport speaks raw frames on it.