Only send the preferred candidate with a BSS transition request.
Otherwise, unsuitable candidates might be included in the neighbor-list
of a transition request.
Signed-off-by: David Bauer <mail@david-bauer.net>
Send link-measurement requests to every supporting local-sta in order to
acquire information to assess the link-quality bi-directional.
The link-measurement request is sent each configurable interval. It can
be disabled by configuring the interval to 0.
Signed-off-by: David Bauer <mail@david-bauer.net>
If the timeout is not reset here, it will expire based on its initial
creation regardless whether it was updated in the meantime.
Signed-off-by: David Bauer <mail@david-bauer.net>
Generalize measurement handling in a way that RCPi and RSNI are stored
regardless of the specific measurement type. This allows us to handle
link-measurement reports the same way as we already handle
beacon-reports.
Signed-off-by: David Bauer <mail@david-bauer.net>
Request hostap to enable the link-measurement capability in the BSS
beacons. Otherwise, STAs might reject link-measurement requests despite
being capable of performing such.
Signed-off-by: David Bauer <mail@david-bauer.net>
This adds a new band-steering component to usteer.
With band-steering enabled, usteer will attempt to move clients with a
consistently good SNR / signal from 2.4 GHz to the 5 GHz band.
In contrast to existing policies usteer tracks, band-steering is
non-invasive and will not lead to forceful connection termination.
Signed-off-by: David Bauer <mail@david-bauer.net>
Add a timeout in case a STA rejected a transition request. For this
configurable timeframe, usteer will refrain from steering the client
another time.
Signed-off-by: David Bauer <mail@david-bauer.net>
While usteer tries it's best to determine the availability of a better
node for a certain client, it might still attempt to direct the client
to a unsuitable AP.
Transition away from using BSS-Transition-Requests with the
disassoc-imminent bit set and instead unset this bit.
This way, the client can inform the AP it will not transition to a
different BSS but instead wishes to remain connected to the current AP.
usteer will still kick clients in case they either accepted the
BSS-transition-request and do not roam or ignore the request completely.
Signed-off-by: David Bauer <mail@david-bauer.net>
This prevents communication with other usteer nodes and allows it to be
used for purely local band steering / load balancing
Signed-off-by: Felix Fietkau <nbd@nbd.name>
BSS transition management as well as RRM capabilities have to be
considered not for the STA but per STA connection.
Most prominently, a STA might not support BSS-TM when connected without
PMF.
Signed-off-by: David Bauer <mail@david-bauer.net>
This causes segfaults on OpenWrt 21.02 which is missing the op-class
field.
Reported-by: John Crispin <john@phrozen.org>
Signed-off-by: David Bauer <mail@david-bauer.net>
Save the latest BSS-transition management response received from a STA.
This information can later be used to prevent kicking STAs when they
rejected a transition request.
Signed-off-by: David Bauer <mail@david-bauer.net>
Add a method to obtain local-host specific state data about usteers
internal logic for each connected STA.
Signed-off-by: David Bauer <mail@david-bauer.net>
Add logic for saving measurement-reports from STAs.
This commit does not yet save the measurement-reports received from
clients but adds the necessary code to do so. Currently the codes can
only handle beacon-reports, but link measurements can be added to it in
the future.
It also adds the new config-key measurement_report_timeout which
controls how long measurements are saved upon they are received by a
STA.
Signed-off-by: David Bauer <mail@david-bauer.net>
Add methods which returns a given node for a provided BSSID. This is
required to retrieve the node object from information available with
a neighbor report.
Signed-off-by: David Bauer <mail@david-bauer.net>
In order to send passive beacon-requests, channel and op-class of nodes
are required. Obtain this information per local-node from hostapd.
Signed-off-by: David Bauer <mail@david-bauer.net>
Currently the min_snr option will result in kicking clients the first
time their SNR dips below.
This might not be desirable, as drivers (notably ath10k) sometimes
report a much lower RSSI for a short timeframe after returning to
sensible values. Also, a device might be in the process of roaming just
to be kicked before.
Add the min_snr_kick_delay option. A client will be kicked after this
timeframe when it's SNR is below the min_snr threshold value over the
complete timeframe.
Signed-off-by: David Bauer <mail@david-bauer.net>
Make usteer handle incoming BSS-transition requests. Update with the
most active roaming neighbors like we already do for imminent
disassociations.
Create a new ubus method which calls hostapds bss_transition_request
method. This does not set the disassoc imminent bit, thus will not
automatically disassoc the requesting STA.
Signed-off-by: David Bauer <mail@david-bauer.net>
Don't determine a finished client scan based on whether the current node
has seen a beacon or not.
This works surprisingly bad on 5 GHz nodes, as clients may refuse to
perform active scanning on this frequency band. In case the clients does
refuse to scan the 5 GHz band but scans the 2.4 GHz band actively, we
might have a good indication about a better node on this band at least.
However, as the roam state-machine requires to have seen a probe request
from the client to direct him to a better node, thi process will not
continue, which either ends the node in being kicked due to exceeding
the number of max tries or the scan cooldown to kick in.
The solution to this is fairly simple: Don't track the roam_scan_done
state but instead just determine a better candidate after the scan
interval finished.
To ensure the indicated signal levels are as recent as 2 *
scan-interval, add a max_age parameter to find_better_candidate.
Signed-off-by: David Bauer <mail@david-bauer.net>
The logic guarding entering of the SCAN state of the roam state-machine
was incorrect in case the scan-timeout was not enabled.
Signed-off-by: David Bauer <mail@david-bauer.net>
Add an optional timeout when a better roaming candidate is not found
after the scan-retry limit. The roam state-machine will not retry
scanning before this timeout has expired.
If the timeout is set to 0, the client is kicked instead, which
resembles the behavior prior this commit.
This is added, as without this patch, if a forced disconnect
is not desired before roam_scan_trigger is exceeded the client will
repeatedly be asked to return active beacon-reports. For battery powered
clients this can result in a noticeable battery drain.
Signed-off-by: David Bauer <mail@david-bauer.net>
Don't select a node as a better candidate where a STA has insufficient
signal to. This is the case when the roam_trigger_snr is greater than
the projected signal of the client.
This stops clients from being selected to roam to a node where the
signal is not sufficient to maintain the connection. A selection might
otherwise happen e.g. due to better channel load on the remote node.
Signed-off-by: David Bauer <mail@david-bauer.net>
Export snr_to_signal to other source files. This will be necessary to
determine reported signal strengths from beacon-report throughout the
code base.
Signed-off-by: David Bauer <mail@david-bauer.net>
This reduces the return traffic from clients by only responding with
beacon reports for the current SSID.
Signed-off-by: David Bauer <mail@david-bauer.net>
The logic for customizing the remote_node_timeout config option was
missing. The default value of 10 could not be altered by a user.
Add the required logic and a short explanation of the config-option to
the default configuration.
Signed-off-by: David Bauer <mail@david-bauer.net>
When kicking clients due to high channel load, explicitly only select
new candidates in case their channel load is an improvement over the
current node.
Signed-off-by: David Bauer <mail@david-bauer.net>
Logic for handling STA transition to disconnected state is
present multiple times. Create a new method to remove
duplicate code.
Signed-off-by: David Bauer <mail@david-bauer.net>
Move the sta frequency-seen logic to usteer_sta_info_update.
This method is called on every occurence the seen frequency
is set now, thus removing the duplicate code.
Signed-off-by: David Bauer <mail@david-bauer.net>
It is not necessary to check if the candidate is not considered
reverse-better, as this is already done inside is_better_candidate for
all relevant criteria.
Signed-off-by: David Bauer <mail@david-bauer.net>
A unset bitmask leads to the candidate selection always return no
candidate, even if there is one.
To select a better candidate regardless of it's classification, provide
a bitmask containing all selection criteria.
Signed-off-by: David Bauer <mail@david-bauer.net>
Move the roam event counters to a dedicated struct.
Update the ubus output to represent this new organization.
Signed-off-by: David Bauer <mail@david-bauer.net>
Some clients seem to ignore scan requests with unreasonably high
measurement durations. This was observed with a Google Pixel 4A as well
as a Xiaomi Mi 10T.
Advertise a scan duration which closely matches the roam scan-interval.
This triggers scans more reliably with the aformentioned devices.
Signed-off-by: David Bauer <mail@david-bauer.net>
When determining a new node within the roam state machine, require the
destination node to have a better reported signal from the client.
Otherwise, the roam state machine might trigger a roam action for a
unsuitable destination node.
Signed-off-by: David Bauer <mail@david-bauer.net>
Don't request measurements from STAs which do not support the specific
measurement mode. Otherwise, hostapd complains in the syslog about
unsupported measurement modes.
Signed-off-by: David Bauer <mail@david-bauer.net>