Skip to content

Wifi wds - #1680

Draft
mattiaswal wants to merge 35 commits into
mainfrom
wifi-wds
Draft

mattiaswal wants to merge 35 commits into
mainfrom
wifi-wds

Conversation

@mattiaswal

@mattiaswal mattiaswal commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

So many fixes on this branch, this is more like wifi-next branch, fixing, extending features that already exist takes more place than the actual wds specific fixes.

Fixes #1679

Description

Checklist

Tick relevant boxes, this PR is-a or has-a:

  • Bugfix
    • Regression tests
    • ChangeLog updates (for next release)
  • Feature
    • YANG model change => revision updated?
    • Regression tests added?
    • ChangeLog updates (for next release)
    • Documentation added?
  • Test changes
    • Checked in changed Readme.adoc (make test-spec)
    • Added new test to group Readme.adoc and yaml file
  • Code style update (formatting, renaming)
  • Refactoring (please detail in commit messages)
  • Build related changes
  • Documentation content changes
    • ChangeLog updated (for major changes)
  • Other (please describe):

@mattiaswal
mattiaswal force-pushed the wifi-wds branch 13 times, most recently from 4b92792 to a3cc9f2 Compare October 8, 2026 20:23
Signed-off-by: Mattias Walström <lazzer@gmail.com>
Signed-off-by: Mattias Walström <lazzer@gmail.com>
The rootfs image loaded at 0x4A000000 covered the WiFi firmware and WED
regions at 0x4fc00000, so the kernel could not reserve them.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
hostapd only creates the socket for the BSS with a ctrl_interface line,
so hostapd_cli could not reach the secondary SSIDs on a radio.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
Adds wds_sta_ifname=<mac> <ifname>, so a 4-address station can be bound
to a port that already exists and is bridged by someone else.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
A wds-link interface is a bridge port of a local access point for one
remote 4-address station, created as an AP_VLAN up front and bound by
hostapd via wds_sta_ifname.  A station with wds enabled may be a bridge
port.  Also judge hostapd config by the APs left in config on commit,
since the changed interface on a radio need not be an AP anymore.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
AP_VLAN ports never leave operstate UNKNOWN, so oper-status is now
derived from the UP and LOWER_UP flags for such interfaces.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
Signed-off-by: Mattias Walström <lazzer@gmail.com>
The virtual medium now only acknowledges unicast frames to peers heard
within the last minute, so a vanished station is detected by the AP's
inactivity probing like on real RF.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
Signed-off-by: Mattias Walström <lazzer@gmail.com>
A full-size data frame with 802.11 headers and encryption exceeds the
1500 byte carrier MTU, and the send error took the whole relay down.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
hostapd adopts a re-added netdev of a name it still holds and turns it
back into an AP, which broke a station created right after an AP of the
same name was removed.  Run hostapd with a global control socket and
tell it to drop the interface first.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
Adding station settings to a scan-only interface, or changing them, only
rewrote the wpa_supplicant config; nothing told the daemon.  Reload it on
config changes and start it over when the netdev is recreated.

Fix #1679

Signed-off-by: Mattias Walström <lazzer@gmail.com>
The survey container under the radio only ever held the operating
channel once the radio was connected or serving clients, the kernel has
no data for channels it never visits, and every hardware GET paid for an
iw call per radio to learn that.  Replace it with a channel-survey
action that scans all channels first.  Going off channel pauses traffic
for a few seconds, so this is something an operator asks for.

The scan is triggered and then waited for over iw event, the combined
iw scan spins on its netlink socket for minutes on the test kernel.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
Calls the channel-survey action on the radio component and feeds the
channel map renderer, which until now had no command at all.  The rpc
tool gains -j to print an RPC output tree as JSON, the value printer
cannot render a list.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
The always-on survey card showed a single bar on a busy radio.  Replace
it with a Scan channels button per radio that runs the channel-survey
action and draws the result.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
Signed-off-by: Mattias Walström <lazzer@gmail.com>
Runs the channel-survey action on a station associated to an AP and on
the AP itself.  Both transports get a call_action_output helper that
returns the action output as a dict, lists included.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
The kernel ignores a country code the wireless regulatory database has
no rules for, so 69 of the ISO codes validated fine and then left the
radios in the world domain without a word.  Keep the 181 countries the
database knows plus '00', say what the world domain means, and drop the
CAPWAP references that never applied.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
The regulatory domain is one setting in the kernel, yet the model asked
for a country code per radio, and it only ever reached the kernel once a
radio had an interface, through hostapd or wpa_supplicant.  A radio
without one sat in the world domain, with no 6 GHz and a listen-only
5 GHz band, which is exactly when a channel survey is wanted.

Replace the per-radio leaf with hardware/wifi/country-code, default
"00", and apply the domain from confd on every change.  Access points
and mesh points require a real country.  Bump confd to 1.11 and migrate
existing configurations: the first radio naming a country wins, radios
left at "00" set nothing.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
The country moves from each radio's form to a WiFi card on the hardware
page.  The interface editor and the wizard still offer it next to the
radio fields, so a first radio can be set up in one go, but write it to
the shared leaf.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
A WPA3-only access point requires it, and on 6 GHz every access point
does.  wpa_supplicant silently skipped those networks as candidates, so
the station saw them in the scan but never tried to associate.  Set it
as capable rather than required, WPA2 networks without it still work.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
wpa_supplicant labels every RSN network WPA2, so an SAE-only network
showed up as WPA2-Personal.  Classify by key management instead.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
The chart is capped at 220 px in the radio card, too small to read on
a radio with many channels.  A click opens a copy in a dialog sized to
the window, closed with the button, the backdrop or Escape.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
A module file cut short, left by a restart in the middle of a download,
made goyang dereference nil at every start.  Write cached files through a
temporary name, turn a parser panic into an error, drop a cache that
fails to load so the next refresh fetches it again, and prune files the
device no longer lists so two revisions of a module never load together.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
hostapd binds to WiFi netdevs.  With the hardware handler first, a
commit that recreates an access point netdev, e.g. for a new MAC
address, restarted hostapd before the interface pipeline rebuilt the
netdev.  hostapd bound to the one about to be deleted and kept reporting
the access point enabled while the new netdev sat idle.  Run the
interfaces first, then the hardware.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
The exchange is sent on the bridge the BSS is a port of.  On a VLAN
filtering bridge a frame from the bridge device lands in the bridge's
own untagged VLAN, if any, not in the access points' VLAN, and naming
another interface as the bridge makes hostapd move the BSS into it.
Add a per-BSS ft_iface option for the interface to use instead.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
Fast transition to an access point on another device failed for WPA3
clients with status 53, invalid PMKID: their PMK comes from the SAE
handshake, so the target cannot regenerate it from the passphrase like
ft_psk_generate_local does for WPA2.  Give every access point of the
SSID wildcard R0KH/R1KH entries with a key derived from the mobility
domain and the passphrase, so the target fetches the PMK-R1 from the
access point the client came from, and tell hostapd about the bridge
so that exchange reaches the other devices.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
A client with a good signal has no reason to roam, so when its access
point goes away it only notices once the beacons stop, and then scans
for a new network.  Run hostapd through a wrapper that, when stopped,
sends every station an 802.11v BSS transition request with
disassociation imminent and waits for them to leave, so clients that
support it roam while the radio is still up.  Give finit ten seconds
before SIGKILL to make room for that.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
Withholding probe responses only sways a client that is choosing a
network, a client already connected on 2.4 GHz stays there.  Ask such
clients to move with an 802.11v request naming the higher-band twin,
from a steering loop the hostapd wrapper runs per pair, as long as the
twin is up and the client's 2.4 GHz signal makes the move worthwhile; a
client that shrugs off a couple of requests is left alone for an hour.
Refusing authentication on 2.4 GHz for clients the twin has seen was
tried and dropped: it locks a client out when the twin cannot take it.
Keep the seen-on list to one minute.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
A client asked to move needs to know where to, wpa_supplicant ignores a
transition request without candidates, and a node does not know the
other nodes' access points.  Every 30 seconds a node announces its
access points in one frame per network they are bridged to, the network
the 802.11r key exchange uses, and listens for the other nodes' frames.
What it hears goes to hostapd as 802.11k neighbors of every access
point with the same SSID, and into the handover request.  No radio
leaves its channel for it.

Anything on that network can send such a frame, so each line is tagged
with the 802.11r key of its SSID and checked before use.  The frame
starts with a version; a node drops frames of another version and logs
it once per sender, so bump the version when the format changes.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
Signed-off-by: Mattias Walström <lazzer@gmail.com>
Signed-off-by: Mattias Walström <lazzer@gmail.com>
With WED on, the built-in radio of a BPI-R3 or W6m stalled its WPDMA RX
ring after a few thousand frames: clients associated and nothing else
arrived.  The radio is bound to band 1 and never set up ring 0, which
the WED drives alike.  Give it an empty ring 0.  Also pull in the WDS
with WED support, the WED v2 reserve buffer and the wcid publish order
from upstream.

Signed-off-by: Mattias Walström <lazzer@gmail.com>
Applies to every MT7986 board built from this BSP: BPI-R3, BPI-R3 Mini
and the Acer Connect Vero W6m.

Signed-off-by: Mattias Walström <lazzer@gmail.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WiFi station settings added to a scan-only interface do not take effect until reboot

1 participant