project/usteer.git
2 years agolocal-node: handle BSS transition queries
David Bauer [Mon, 20 Dec 2021 14:40:54 +0000 (15:40 +0100)]
local-node: handle BSS transition queries

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>
2 years agopolicy: don't track roam_scan_done
David Bauer [Wed, 22 Dec 2021 21:28:49 +0000 (22:28 +0100)]
policy: don't track roam_scan_done

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>
2 years agopolicy: fix incurrect handling of scan-requests with disabled timeout
David Bauer [Sun, 23 Jan 2022 16:27:09 +0000 (17:27 +0100)]
policy: fix incurrect handling of scan-requests with disabled timeout

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>
2 years agopolicy: add roam-scan timeout
David Bauer [Tue, 21 Dec 2021 14:30:14 +0000 (15:30 +0100)]
policy: add roam-scan timeout

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>
2 years agopolicy: don't select better candidate with bad signal
David Bauer [Tue, 21 Dec 2021 13:09:15 +0000 (14:09 +0100)]
policy: don't select better candidate with bad signal

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>
2 years agopolicy: export snr_to_signal to other source files
David Bauer [Mon, 20 Dec 2021 21:32:00 +0000 (22:32 +0100)]
policy: export snr_to_signal to other source files

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>
2 years agoubus: only request beacon-report for current SSID
David Bauer [Fri, 31 Dec 2021 20:46:14 +0000 (21:46 +0100)]
ubus: only request beacon-report for current SSID

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>
2 years agoconfig: make remote_node_timeout configurable
David Bauer [Sat, 1 Jan 2022 17:00:45 +0000 (18:00 +0100)]
config: make remote_node_timeout configurable

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>
2 years agopolicy: only select candidates with better load
David Bauer [Tue, 21 Dec 2021 12:24:14 +0000 (13:24 +0100)]
policy: only select candidates with better load

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>
2 years agosta: uniform disconnect state handling
David Bauer [Sun, 28 Nov 2021 22:20:48 +0000 (23:20 +0100)]
sta: uniform disconnect state handling

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>
2 years agosta: remove duplicate code
David Bauer [Sat, 11 Dec 2021 11:48:10 +0000 (12:48 +0100)]
sta: remove duplicate code

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>
2 years agopolicy: remove redundant candidate evaluation
David Bauer [Sat, 25 Dec 2021 16:36:39 +0000 (17:36 +0100)]
policy: remove redundant candidate evaluation

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>
2 years agopolicy: fix not selecting better candidate on request
David Bauer [Sat, 25 Dec 2021 16:25:38 +0000 (17:25 +0100)]
policy: fix not selecting better candidate on request

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>
2 years agoubus: skip current node for transition candidate list
David Bauer [Thu, 9 Dec 2021 22:13:39 +0000 (23:13 +0100)]
ubus: skip current node for transition candidate list

Don't add the node the client is forced to leave as a potential
transition candidate.

Signed-off-by: David Bauer <mail@david-bauer.net>
2 years agonode: move roam-events to dedicated struct
David Bauer [Fri, 26 Nov 2021 00:36:43 +0000 (01:36 +0100)]
node: move roam-events to dedicated struct

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>
2 years agonode: skip neighbors exceeding assoc-limit
David Bauer [Sun, 31 Oct 2021 09:59:31 +0000 (10:59 +0100)]
node: skip neighbors exceeding assoc-limit

When creating the list of neighbor reports, skip nodes which can't
handle additional STAs.

Signed-off-by: David Bauer <mail@david-bauer.net>
2 years agoubus: set scan duration to roam scan interval
David Bauer [Mon, 18 Oct 2021 11:30:18 +0000 (13:30 +0200)]
ubus: set scan duration to roam scan interval

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>
2 years agopolicy: only select nodes with better signal when roaming
David Bauer [Fri, 15 Oct 2021 13:46:06 +0000 (15:46 +0200)]
policy: only select nodes with better signal when roaming

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>
2 years agoubus: don't request measurement from unsupported STAs
David Bauer [Mon, 25 Oct 2021 19:49:05 +0000 (21:49 +0200)]
ubus: don't request measurement from unsupported STAs

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>
2 years agolocal-node: update STA RRM capabilites
David Bauer [Mon, 25 Oct 2021 13:09:52 +0000 (15:09 +0200)]
local-node: update STA RRM capabilites

Save the RRM capabilities of STAs when updating clients from hostapd.

This is required to determine which measurement modes a STA supports.

Signed-off-by: David Bauer <mail@david-bauer.net>
2 years agonode: determine roamability when selecting neighbors
David Bauer [Wed, 29 Sep 2021 17:17:11 +0000 (19:17 +0200)]
node: determine roamability when selecting neighbors

Currently, the neighbor report list is sorted based on the total amount
of roam actions to and from the specific foreign nodes.

This does not take into account that nodes might not be created at the
same time. When a popular neighbor node reboots, it's roam actions are
reset and it's ranking might not recover for a long amount of time
depending on how long the local node is already running.

Change this shotcoming to take into account the timestamp at which a
node was created. This way, the ranking depends on the amount of roam
actions relative to the nodes uptime / seen-time.

Signed-off-by: David Bauer <mail@david-bauer.net>
2 years agonode: save created time for node
David Bauer [Wed, 29 Sep 2021 17:05:44 +0000 (19:05 +0200)]
node: save created time for node

Save the timestamp of the node creation. This is required to optimize
the selection of most-roamed to neighbors relative to their creation
time.

Signed-off-by: David Bauer <mail@david-bauer.net>
2 years agoubus: prioritize neighbor reports on bss transition
David Bauer [Fri, 1 Oct 2021 09:13:04 +0000 (11:13 +0200)]
ubus: prioritize neighbor reports on bss transition

Apply the same logic for selecting the most relevant neighbors also when
sending transition requests to STAs.

Signed-off-by: David Bauer <mail@david-bauer.net>
2 years agolocal-node: prioritize neighbor candidates
David Bauer [Tue, 28 Sep 2021 22:42:37 +0000 (00:42 +0200)]
local-node: prioritize neighbor candidates

Prioritize neighbor candidates installed to hostapd. Add a new config
option to set a limit for neighbor reports installed to hostapd. This is
due to the fact, most devices will only evaluate a certain amount of
neighbor reports. Furthermore, the number of neighbor reports possible
is limited by the maximum frame size.

Signed-off-by: David Bauer <mail@david-bauer.net>
2 years agonode: keep track of roam-sources and roam-destinations
David Bauer [Mon, 27 Sep 2021 19:48:58 +0000 (21:48 +0200)]
node: keep track of roam-sources and roam-destinations

Keep track of STA journeys between multiple nodes. When a new STA is
reported from a foreign node, check whether this STA was previously
associated with a local node.

Vice versa, check upon association whether or not the STA was previously
associated with a foreign node.

Keep track of these roaming transactions using two new (local) fields of
the node struct.

Signed-off-by: David Bauer <mail@david-bauer.net>
2 years agosta-info: add last_connected field
David Bauer [Mon, 27 Sep 2021 18:56:41 +0000 (20:56 +0200)]
sta-info: add last_connected field

Add a last_connected field to the sta_info struct. This field can be
used to determine, if and when a client was last connected to a given
node. This way, other nodes can determine where a client roamed to or
from.

Signed-off-by: David Bauer <mail@david-bauer.net>
3 years agoremote: always re-schedule update timeout
David Bauer [Sat, 23 Oct 2021 22:40:55 +0000 (00:40 +0200)]
remote: always re-schedule update timeout

This commit fixes updates not triggering due to a race-condition in
usteer.

When usteer does not yet have local-nodes when loading config, the
scheduled remote-update is not re-scheduled, leading to usteer only
exchanging node-messages on STA-events, leading to expiring remotes on
other remote nodes in low-event scenarios.

Signed-off-by: David Bauer <mail@david-bauer.net>
3 years agoremote: fix compilation with glibc
David Bauer [Fri, 29 Oct 2021 23:13:34 +0000 (01:13 +0200)]
remote: fix compilation with glibc

Fixes builds for the arc target.

Signed-off-by: David Bauer <mail@david-bauer.net>
3 years agosta: schedule sta_info timeout on creation
David Bauer [Mon, 25 Oct 2021 12:52:59 +0000 (14:52 +0200)]
sta: schedule sta_info timeout on creation

The codes looks to have a race-condition, where disconnected sta_infos
are created without scheduling a timeout.

As sta_infos are not connected by default, schedule the timeout upon
sta_info creation.

Fixes spurious spamming of "Refuse to add an already expired station
entry" on remote nodes.

Signed-off-by: David Bauer <mail@david-bauer.net>
3 years agoubus: fix channel for active probing
David Bauer [Mon, 18 Oct 2021 11:25:52 +0000 (13:25 +0200)]
ubus: fix channel for active probing

The IEEE802.11-2016 specification says:

[...] a Channel Number field value of 255 indicates a request
to make iterative measurements for all supported channels in the
current operating class listed in the latest AP Channel Report
received from the serving AP.

The problem with this is, no AP Channel report is sent to the STA with
the measurement request.

To scan the whole Operating class, a channel number of 0 is desired:

[...] Channel Number field value of 0 indicates a request to make
iterative measurements for all supported channels in the operating
class [...]

Signed-off-by: David Bauer <mail@david-bauer.net>
3 years agoubus: introduce enum for beacon measurement mode
David Bauer [Mon, 18 Oct 2021 11:21:39 +0000 (13:21 +0200)]
ubus: introduce enum for beacon measurement mode

This improves code readability.

Signed-off-by: David Bauer <mail@david-bauer.net>
3 years agopolicy: use correct reference signal
David Bauer [Fri, 15 Oct 2021 21:24:30 +0000 (23:24 +0200)]
policy: use correct reference signal

Signed-off-by: David Bauer <mail@david-bauer.net>
3 years agopolicy: avoid creating kick loop for client
David Bauer [Sun, 3 Oct 2021 13:53:25 +0000 (15:53 +0200)]
policy: avoid creating kick loop for client

When checking whether a client is allowed to associate to a node, the
lower ceiling for kicking clients was not taken into account when
assoc-steering is disabled.

The problem behind this is, that a configured lower barrier for
disassociating clients (kicking) would kick the client immediatly after
association. In the worst scenario the client immediatly associates
again to the station and ends up in a kick loop.

Don't allow associating when a min_snr is configured and the client
signal is below this value.

Signed-off-by: David Bauer <mail@david-bauer.net>
3 years agosta: add sta_connection_state enum
David Bauer [Mon, 27 Sep 2021 17:35:55 +0000 (19:35 +0200)]
sta: add sta_connection_state enum

Make the connection state of a sta-info more readable by introducing an
enum for the STA connection state.

Also switch come comparison cases to use the explicit enum values to
make the code more readable.

Signed-off-by: David Bauer <mail@david-bauer.net>
3 years agoremote: include node BSSID into messages
David Bauer [Tue, 21 Sep 2021 14:41:23 +0000 (16:41 +0200)]
remote: include node BSSID into messages

Add the node BSSID to messages exchanged between usteer hosts. This way,
a foreign node can determine the node reported by a STA using beacon
reports.

Signed-off-by: David Bauer <mail@david-bauer.net>
3 years agousteer: add BSSID to node struct
David Bauer [Tue, 21 Sep 2021 14:02:16 +0000 (16:02 +0200)]
usteer: add BSSID to node struct

Add the node BSSID to the usteer_node struct. This will be helpful in
the future when evaluating beacon reports from STAs.

Signed-off-by: David Bauer <mail@david-bauer.net>
3 years agoremote: fix memory leak on host removal
David Bauer [Sun, 5 Sep 2021 16:05:49 +0000 (18:05 +0200)]
remote: fix memory leak on host removal

The host address is allocated on the heap, hence it has to be freed when
freeing the containing struct.

Signed-off-by: David Bauer <mail@david-bauer.net>
3 years agoremote: fix incorrect use of strcmp result
David Bauer [Sun, 5 Sep 2021 16:03:21 +0000 (18:03 +0200)]
remote: fix incorrect use of strcmp result

When checking if the hostaddresses match up, the result returned from
strcmp was incorrectly evaluated. strcmp returns 0 in case both strings
match.

Signed-off-by: David Bauer <mail@david-bauer.net>
3 years agogitignore: add .patch files
David Bauer [Tue, 7 Sep 2021 18:55:51 +0000 (20:55 +0200)]
gitignore: add .patch files

Signed-off-by: David Bauer <mail@david-bauer.net>
3 years agogitignore: add vscode directory
David Bauer [Sun, 5 Sep 2021 00:44:32 +0000 (02:44 +0200)]
gitignore: add vscode directory

Signed-off-by: David Bauer <mail@david-bauer.net>
3 years agocontrib: add libpcap build dependency
David Bauer [Sun, 15 Nov 2020 20:48:32 +0000 (21:48 +0100)]
contrib: add libpcap build dependency

Add a build dependency for libpcap, as it is required for the monitor
utility but not usteer itself. Use a build-dependency, as the monitor
utility executable is not packaged.

Signed-off-by: David Bauer <mail@david-bauer.net>
3 years agolocal-node: don't read pointer after clear
David Bauer [Tue, 21 Sep 2021 16:51:57 +0000 (18:51 +0200)]
local-node: don't read pointer after clear

The name pointer provided by ubus get's cleared after the first call to
ubus_register_subscriber in usteer_get_node. The leads to an incorrect
ifindex returned by if_nametoindex due to the 0 characters long string.

Work around this issue by reusing the interface name already stored in
the local node struct.

Fixes querying the wrong interface with netlink, resulting in incorrect
SSIDs used for the nodes.

Signed-off-by: David Bauer <mail@david-bauer.net>
3 years agousteer: add support for IPv6 remote exchange
Jan Braun [Sun, 5 Sep 2021 00:43:59 +0000 (02:43 +0200)]
usteer: add support for IPv6 remote exchange

This adds optional support for message exchange using IPv6 multicast
messaging. This has the ability for routers and switches between nodes
to route traffic between usteer nodes multicast-aware.

By default, IPv4 is used. IPv6 can be enabled by configuring the ipv6
option to 1.

Signed-off-by: Jan Braun <keksgesicht23@gmail.com>
[squash commits - adapt usock usage]
Signed-off-by: David Bauer <mail@david-bauer.net>
3 years agoremote: use port macro for destination port
David Bauer [Wed, 8 Sep 2021 07:53:26 +0000 (09:53 +0200)]
remote: use port macro for destination port

Signed-off-by: David Bauer <mail@david-bauer.net>
3 years agomain: add a command line option for dumping remote node data
Felix Fietkau [Wed, 7 Jul 2021 09:37:50 +0000 (11:37 +0200)]
main: add a command line option for dumping remote node data

Run for a given number of seconds and dump all found remote hosts/nodes as
JSON data

Signed-off-by: Felix Fietkau <nbd@nbd.name>
3 years agoconfig: reduce remote node timeout to 10 update intervals
Felix Fietkau [Tue, 6 Jul 2021 17:50:02 +0000 (19:50 +0200)]
config: reduce remote node timeout to 10 update intervals

Even when there are network issues, we shouldn't keep stale data
around for so long

Signed-off-by: Felix Fietkau <nbd@nbd.name>
3 years agoadd support for defining global host info
Felix Fietkau [Tue, 6 Jul 2021 17:44:01 +0000 (19:44 +0200)]
add support for defining global host info

Change the '*' in the node info update cmd to refer to host info instead

Signed-off-by: Felix Fietkau <nbd@nbd.name>
3 years agoubus: add support for getting a list of remote hosts
Felix Fietkau [Tue, 6 Jul 2021 17:23:59 +0000 (19:23 +0200)]
ubus: add support for getting a list of remote hosts

Signed-off-by: Felix Fietkau <nbd@nbd.name>
3 years agoremote: track remote hosts as a separate data structure
Felix Fietkau [Tue, 6 Jul 2021 17:14:36 +0000 (19:14 +0200)]
remote: track remote hosts as a separate data structure

Will be used to track host info

Signed-off-by: Felix Fietkau <nbd@nbd.name>
3 years agorename script_data to node_info
Felix Fietkau [Tue, 6 Jul 2021 12:29:24 +0000 (14:29 +0200)]
rename script_data to node_info

It's a more descriptive name, and we will have host_info later as well

Signed-off-by: Felix Fietkau <nbd@nbd.name>
3 years agorename a few functions in preparation for renaming script_data to node_info
Felix Fietkau [Tue, 6 Jul 2021 12:28:28 +0000 (14:28 +0200)]
rename a few functions in preparation for renaming script_data to node_info

Signed-off-by: Felix Fietkau <nbd@nbd.name>
3 years agoubus: add api for modifying node script data
Felix Fietkau [Tue, 6 Jul 2021 08:29:20 +0000 (10:29 +0200)]
ubus: add api for modifying node script data

This is replicated across nodes

Signed-off-by: Felix Fietkau <nbd@nbd.name>
3 years agoubus: display script data when dumping node info
Felix Fietkau [Mon, 5 Jul 2021 13:51:10 +0000 (15:51 +0200)]
ubus: display script data when dumping node info

Signed-off-by: Felix Fietkau <nbd@nbd.name>
3 years agoconfig: check for empty ssid list
Felix Fietkau [Tue, 6 Jul 2021 09:00:35 +0000 (11:00 +0200)]
config: check for empty ssid list

Without this check, an empty ssid list array results in a config with no nodes

Signed-off-by: Felix Fietkau <nbd@nbd.name>
3 years agoopenwrt: add missing config handling for event log types
Felix Fietkau [Thu, 13 May 2021 14:10:33 +0000 (16:10 +0200)]
openwrt: add missing config handling for event log types

Signed-off-by: Felix Fietkau <nbd@nbd.name>
3 years agomake list of steering-enabled SSIDs configurable
Felix Fietkau [Thu, 13 May 2021 14:06:16 +0000 (16:06 +0200)]
make list of steering-enabled SSIDs configurable

Signed-off-by: Felix Fietkau <nbd@nbd.name>
3 years agoopenwrt: add documentation for uci options in the config file
Felix Fietkau [Wed, 12 May 2021 11:33:14 +0000 (13:33 +0200)]
openwrt: add documentation for uci options in the config file

Signed-off-by: Felix Fietkau <nbd@nbd.name>
3 years agorework log handling
Felix Fietkau [Fri, 16 Apr 2021 12:15:15 +0000 (14:15 +0200)]
rework log handling

- make logging events more structured
- add fine grained control over log events
- make it possible to receive more detailed events via ubus

Signed-off-by: Felix Fietkau <nbd@nbd.name>
3 years agoopenwrt: fix path to daemon in init script
Felix Fietkau [Fri, 16 Apr 2021 12:29:12 +0000 (14:29 +0200)]
openwrt: fix path to daemon in init script

Signed-off-by: Felix Fietkau <nbd@nbd.name>
3 years agopolicy: always accept assoc requests by default
Felix Fietkau [Mon, 12 Apr 2021 10:14:05 +0000 (12:14 +0200)]
policy: always accept assoc requests by default

Only steer using probe responses to avoid connection issues

Signed-off-by: Felix Fietkau <nbd@nbd.name>
3 years agopolicy: always accept auth requests
Felix Fietkau [Mon, 12 Apr 2021 10:10:17 +0000 (12:10 +0200)]
policy: always accept auth requests

Signed-off-by: Felix Fietkau <nbd@nbd.name>
4 years agoMerge pull request #1 from thuehn/patch-1
John Crispin [Thu, 19 Nov 2020 20:37:44 +0000 (21:37 +0100)]
Merge pull request #1 from thuehn/patch-1

[fix] binary file name should be usteerd

4 years ago[fix] binary file name should be usteerd
Dr.-Ing. Thomas Hühn [Thu, 19 Nov 2020 15:46:12 +0000 (16:46 +0100)]
[fix] binary file name should be usteerd

the binary file name to be copied while install it in the OpenWrt package should be usteerd not usteer

4 years agousteer: Initial import
Felix Fietkau [Wed, 21 Mar 2018 15:40:05 +0000 (16:40 +0100)]
usteer: Initial import

Signed-off-by: Felix Fietkau <nbd@nbd.name>