Current version of software supports controller initiated mandate steering based on beacon measurement. For STA to be able to be steered its drivers must support 802.11k (RRM for beacon measurements) and 802.11v (this is usually implemented in MAC, needed for BTM steering).
The Multi-AP Controller supports STA steering as described in the EasyMesh standard.
## Usage & UCI Configuration
It allows loadable 'steer' plugins that can evaluate a STA's steering criteria.
These plugins come with their own private configuration, which the Controller does not need to know about.
In order to enable STA steering please set at least *enable_sta_steer* and *use_bcn_metrics* in mapcontroller file to **1** .
The Controller only pass certain EasyMesh messages to the 'steer' plugins, which they requested the Controller to provide.
There're also other UCI parameters that will be used for steering:
**/etc/config/mapcontroller**
After the 'steer' plugin decides that a STA should be steered, Controller sends a Client Steer Request EasyMesh message for the STA.
``` shell
...
config sta_steering
...
option steer_module 'rcpi'
# the name must match the /usr/lib/mapcontroller/<name>.so plugin file
option enabled '1'
# load this plugin if 1, skip loading otherwise
option enable_sta_steer '1'
# enable steering of (non-bsta) client stations
option enable_bsta_steer '0'
# enable steering of backhauls (experimental)
option use_bcn_metrics '1'
# use rcpi from beacon metrics to decide on best bssid to steer to
option use_usta_metrics '0'
# use ul_rcpi measured as an unassociated sta as additional trigger for steering (experimental)
option bandsteer '0'
# if 1 then steering from 5g/6g to 2.4g is alowed
option diffsnr '8'
# minimal RSSI diff (dest RSSI - src RSSI) for the BTM to kick in (default 8dB)
option rcpi_threshold_2g '70'
# global default rcpi threshold to trigger steering on 2GHZ band
option rcpi_threshold_5g '86'
# global default rcpi threshold to trigger steering on 5GHZ band
option rcpi_threshold_6g '86'
# global default rcpi threshold to trigger steering on 6GHZ band
option report_rcpi_threshold_2g '80'
# global default rcpi threshold to start reporing on 2GHZ band
option report_rcpi_threshold_5g '96'
# global default rcpi threshold to start reporing on 5GHZ band
option report_rcpi_threshold_6g '96'
# global default rcpi threshold to start reporing on 6GHZ band
option steer_retry_int '30'
# minimum interval (in seconds) from last steer attempt of given sta before next try allowed
option steer_int '180'
# minimum interval (in seconds) since last succesfull steer of given sta before next steer attempt allowed
option steer_disable_int '600'
# after 3 consecutive failed steer attempts sta will be blocked from steering for `steer_disable_int` (seconds)
...
```
Please note, that the steer_module must be present in the system, that is the map-controller is expecting to find rcpi plugin in /usr/lib/mapcontroller/rcpi.so. Otherwise it will not be able to load the steering decision plugin, and therefore the steering will be effectively disabled. More than one plugin can be present in system and in config file - each with own set of steering parameters, first one will be used for steering.
**/etc/config/mapcontroller**
# Prerequisite
``` shell
Although Controller initiates the Client Steer Request message, it cannot know when to issue the request.
...
For that, the 'steer' plugins evaluate the steering criteria and notify the Controller of the steer verdict.
config radio 'radio_44d4376af4cf'
option agent_id '46:d4:37:6a:f4:c0'
option macaddr '44:d4:37:6a:f4:cf'
option band '5'
option report_rcpi_threshold '96'
option rcpi_threshold '86'
...
```
This will be synchronized to mapagents in the mesh – radio sections in /etc/config/mapagent for each agent will be updated accordingly.
Examples of STA steer criteria can be -
Please note, that the rcpi_threshold & report_rcpi_threshold - if set - will override the global values set earlier in sta_steering section.
**/etc/config/mapagent**
1) Low signal
2) Low rate
3) High channel utilization
4) High error counters
``` shell
...
config wifi-radio
...
option util_threshold '0'
# radio utilization - if non-zero, then checked every 5 seconds
# it may cause sending of associated sta link metrics to the controller
# mandate steering may be trigerred by controller in handler of the above
...
option report_rcpi_threshold '96'
# going below threshold value will trigger sending of associated sta link metrics to the controller
# mandate steering may be trigerred by controller in handler of the above
...
option rcpi_threshold '86'
# steer once ul rcpi goes below this threshold, providing there's enough bcn metrics data available
...
option include_sta_metric '1'
# additional trigger point on top of the previous two
# notify controller on current link metrics (send link metrics) along the AP metrics response
# mandate steering may be trigerred by controller in handler of the above
...
```
In case the rcpi_threshold is not set explicitly in configuration file it will default to:
# Steer plugins
#define CONFIG_DEFAULT_RCPI_TH_6G 86
#define CONFIG_DEFAULT_RCPI_TH_5G 86
#define CONFIG_DEFAULT_RCPI_TH_2G 70
In case the report_rcpi_threshold is not set explicitly in configuration file it will default to:
On startup, Controller loads the 'steer' plugins from the path `/usr/lib/mapcontroller`.
**report_rcpi_threshold = rcpi_threshold + 10**
## Working functionality (automatic beacon metrcis based BTM steering)
See `src/README-STA-Steering.md` for more details about the steer plugins.
Controller initiated mandate steering is now working as follows:
Once the STA – AP rcpi goes below given value (report_rcpi_threshold), map-agent sends the Associated STA Link Metrics Response to the map-controller. This in turn will cause map-controller to send beacon metrics request for given STA on all operating classes/channels of nodes operating in the mesh and SSID value set to current network. After some time (depends on number of opclass/channel pairs) – the beacon metrics results will be parsed. Once there’s a better (diffsnr of at least 8dB is a default) BSS found for given STA, controller will try to to move STA to that BSS using BTM request.
## Configuration
Depending on the settings there'll be more or less frequent checks done by the controller. - Frequency of the checks depends on the frequency of the associated sta link metrics responses received from the nodes, which depends on the settings as explained earlier (util_threshold, report_rcpi_threshold, rcpi_threshold, include_sta_metric). Controller will check if RCPI goes below the reporting threshold. If so, then controller will request for beacon metrics and/or unassociated STA link metrics for given client. After some time it will then compare current RCPI of that given station with the values obtained in metrics and only try to (BTM) steer that station if there's a better candidate found. - The delta RCPI of at least 8 is required (difference in beacon metrics RCPI of source and target). Additionally the current uplink RCPI will be always compared with rcpi_threshold in the plugin, and steering will not take place if it's above that trigger.
**/etc/config/mapcontroller**
## Unassociated STA link metrics (experimental)
The config section config `sta_steering` is applicable for all STAs and all Agents in
Additionally one can try to use unassociated STA link metrics on top or instead of beacon metrics for getting of the (uplink) rcpi of given STA, for that one must set following in map-controller config
the Multi-AP network.
**/etc/config/mapcontroller**
Set `enable_sta_steer` to '1' to enable STA steering.
Setting the option to '0' disables Controller initiated STA steering.
``` shell
````
config sta_steering
config sta_steering
option use_usta_metrics '1'
option enable_sta_steer '1'
```
This will enable unassociated STA link metrics as an additional trigger for mandate steering.
````
The check is triggered on same occasion as for beacon metrics –upon drop of the signal strength below given threshold. In such case if there’s a BSS with better link towards steered STA found (in terms of better uplink RCPI - difference of at least 10) controller will send BTM steer request towards this STA.
## Steer exclusion lists
The following config options in the `sta_steering` section set the various steering related threshold values applicable to all STAs in the network.
Additionally there’re two steering disallowed lists maintained in the controller:
- steer_exclude (per node) – exclude STA from steering completely
````
- steer_exclude_btm (per node) – do not allow to steer of the STA using BTM steering (but association control based opportunity steering will be possible in the future – once implemented). To put the STA on either of two lists one must just add a list entry per node in controller UCI config as in example:
config sta_steering
option report_rcpi_threshold_2g '80'
option report_rcpi_threshold_5g '96'
option report_rcpi_threshold_6g '96'
option rcpi_threshold_2g '70'
option rcpi_threshold_5g '86'
option rcpi_threshold_6g '86'
option plugins_enabled '1'
option plugins_policy 'any'
list plugins 'rcpi'
list plugins 'rate'
````
User can override the steering config on a per-Agent or per-Radio basis.
STA steering config options applicable at per-Radio level -
````
config radio 'radio_44d4376af4cf'
option agent_id '46:d4:37:6a:f4:c0'
option macaddr '44:d4:37:6a:f4:cf'
option band '5'
option rcpi_threshold '86'
option report_rcpi_threshold '96'
````
STA steering config options applicable at per-Agent basis -
````
config node 'node_46d4376af4c0'
option agent_id '46:d4:37:6a:f4:c0'
list steer_exclude 'e0:d4:e8:79:c4:ee'
list steer_exclude 'e0:d4:e8:79:c4:11'
list steer_exclude_btm 'aa:bb:cc:dd:ee:ff'
````
## How it works
* Controller sets the associated STAs' metrics reporting policy.
* A Multi-AP Agent sends STA Link Metrics Response messages to the Controller either a) periodically or b) whenever a STA's uplink RCPI goes below a certain threshold value (config: *report_rcpi_threshold_\**).
* Controller notifies STAs' Link Metrics Response to the loaded steer plugins.
* The steer plugins may ask the Controller to trigger Beacon Metrics Request EasyMesh messages for the STA.
* Controller notifies the Beacon Metrics Response(s) for the STA to the steer plugins, if any received in response to it's above request(s).
* The steer plugins may ask the Controller to fetch Unassociated STA Link Metrics for the STA from the neighboring Agents.
* Again, Controller notifies the steer plugins of the Unassociated STA link metrics response(s) for the STA, if any received from the neighbor Agents.
* The steer plugins decide if the STA should be steered or not, based on the network condition and available STA metrics at that point.
* If the steer verdict is OK, then Controller issues a Client Steering Request EasyMesh message for the STA.
* As part of the steer verdict, the steer plugins also provide the target-AP to which the STA should be steered to.
* Upon receiving the Client Steering Request, the Multi-AP Agent is expected to send a 11v BTM Request to the STA.
* Upon receiving a 11v BTM Response from the STA, the Multi-AP Agent replies back to the Controller with a Client Steering BTM Report EasyMesh message containing the BTM steering status code.
* Controller updates the STA's state and steer metrics accordingly.
## Steer sxclusion lists
STA(s) can be excluded from Controller initiated steering by using either or both
the following config options -
**/etc/config/mapcontroller**
**/etc/config/mapcontroller**
``` shell
``` shell
config node 'node_46d4376af4c0'
config node 'node_46d4376af4c0'
option agent_id '46:d4:37:6a:f4:c0'
option agent_id '46:d4:37:6a:f4:c0'
list steer_exclude 'e0:d4:e8:79:c4:ee'
list steer_exclude 'e0:d4:e8:79:c4:ee'# exclude this STA from steering
list steer_exclude 'e0:d4:e8:79:c4:11'
list steer_exclude_btm 'e0:d4:e8:79:c4:11'# exclude this STA from 802.11v BTM based steering
list steer_exclude_btm 'aa:bb:cc:dd:ee:ff'
```
```
Removing STA MAC from the list will result in immediate allowing of the STA to be (BTM) steered again.
NOTE: The above options are applicable on a per-Agent basis.
## RCPI plugin
The plugin is used for separating steering decision algorithm from the steering code itself. Current example implementation is using diffsnr and rcpi_threshold values in order for the map-controller rcpi plugin to decide if there’s a better bssid found in per-STA measurements list.
The source for the default rcpi plugin can be found in map-controller source under plugins/steer/rcpi. If one wants to use their own decision algorithm they need to create new directory under plugins/steer/<pluginname> and update appropriate Makefiles.
## Steer intervals
## BandSteer
Following intervals and associated timers are used to avoid too frequent steering attempts of a specific STA.
**/etc/config/mapcontroller**
``` shell
config sta_steering
option steer_retry_int '30'
option steer_int '180'
option steer_disable_int '600'
```
The intervals are defined in seconds, and default to 30 seconds, 3 minutes and 30 minutes respectively.
- In case there was a unsuccesfull steer attempt during last `steer_retry_int`, next steer requests by mapcontroller will be blocked until it elapses.
- In case the sta has been succesfully steered during last `steer_int`, any steer attempt to another node (with better RCPI) will be ignored for that interval.
- Lastly if the sta continuosly refuses to be steered for 3 times in a row, it will be marked sticky, and no steer attempt will be made for next `steer_disable_int`.
## Band steer
There’s an additional option in sta_steering section of map-controller config
**(/etc/config/mapcontroller)**
**(/etc/config/mapcontroller)**
...
@@ -171,204 +125,18 @@ config sta_steering
...
@@ -171,204 +125,18 @@ config sta_steering
option bandsteer ‘1’
option bandsteer ‘1’
```
```
This option is also passed down to rcpi plugin. If set then rcpi plugin will allow for steering between bands (from 2.4 to 5 and from 5 to 2.4), basing its decision only on the difference in rssi. If not set then only steering across BSSs operating on current band will be allowed.
Controller pass this config option to let the steer plugins know if Bandsteering is allowed or not while deciding for the suitable target-APs.
## UBUS call inititated steering
## Command 'steer'
In order to steer the STA one can also use a map-controller UBUS API as follows
Controller provides a 'steer' command, which can be used to trigger STA steering explicitly.
This command bypass the STA steer plugins allowing the Controller to send a Client Steer Request EasyMesh message directly to an Agent.
See `map.controller` 'help' command to know about the different arguments that the 'steer' command can take.
The parameters are:
- agent - alid of the agent node of the source BSSID
- src_bssid - source BSSID to which the STA is currently connected
- sta - MAC address of the STA to be steered
- target_agent - the agent to which the sta is to be steered
- target_bssid - the target bssid to which the sta is to be steered
- abridged - abridged bit in Bssinfo of BTM Request
- disassoc_tmo - maps to Diassoc Immenent field and Disassoc Timer in TUs. When not set, Controller doesnot set the Disassoc Immenent field. Otherwise, it holds the Disassoc timer value in TUs
- mbo_reason - MBO Transition Reason Code to be sent if STA is Agile Multiband capable
## Other UBUS commands
Get independent (from the algorithm) beacon metrics:
- report_rcpi_threshold & rcpi_threshold are set separately per radio in controller config and can only be set after succesfull onboarding.
- hysteresis parameter is not implemented.
- There's no initial channel scan - independent channel scan must be executed on each node.
i.e. `ubus call wifi.radio.wl0 list_neighbor` must include target (to:) bss when run on src (from:) node
One shall set the
``` shell
config controller 'controller'
option initial_channel_scan ‘1’
```
in controller section of the controller config (/etc/config/mapcontroller) in order for the BTM steering to work robustly all the times.
Otherwise the neighbor_list on target interface may be empty, causing the BTM steering to that given BSSID to fail by ESL (“bssid not on neighbor list” type of error).
We’re currently working on removal of that check in ESL, so that neighbor_list can be empty on given interface (ubus call wifi.ap.wlX list_neighbor), as we already know the neighbors in map. We’ll then provide all the necessary neighbor data directly from the map daemons (bssid, channel, opclass, phy & bssid_info) – without depending on the channel scan functionality that would normally cause the neighbor list in wifi to be filled in.
- Only beacon metrics that were obtained after steering request sent are being used as steering data base. Others are marked 'stale'.
- One must set RCPI (report_rcpi_threshold & rcpi_threshold) using /etc/config/mapcontroller separately for each device & radio.
- One must remember to set up following configuration in controller, as it's not there by default:
``` shell
list steer_module 'rcpi'
```
- bandsteer check is not implemented in 6.5
## Source code guide
Function(s) from where the steering method of the steer plugin gets called & how the result/verdict is handled
If a stations RCPI drops beneath the configured `report_rcpi_threshold` of the respective radio,
then the agent is expected send 'Associated STA Link Metrics Response' to the Controller