OWM Integrator Guide
General
This guide explains the key components that integrators need to understand when working with OWM (One Wifi Manager). It covers the three main subsystems: Confsync, Stats, and Steering.
- 1 General
- 2 Overview
- 3 1. Confsync
- 3.1 What is Confsync?
- 3.2 Architecture
- 3.3 How It Works
- 3.4 State Machine
- 3.5 Configuration Process
- 3.5.1 Step 1: Config Update
- 3.5.2 Step 2: Build Configuration
- 3.5.3 Step 3: Apply to Hardware
- 3.5.4 Step 4: Verify
- 3.6 Confsync Watchdog
- 3.7 Debugging
- 4 2. Stats
- 4.1 What is Stats?
- 4.2 Architecture
- 4.3 Statistics Types
- 4.3.1 1. Survey Statistics
- 4.3.2 2. Neighbor Statistics
- 4.3.3 3. Client Statistics
- 4.3.4 4. Device Statistics
- 4.4 Configuration (Wifi_Stats_Config)
- 4.4.1 OVSDB Table Fields
- 4.4.2 Key Fields
- 4.4.3 Example Configuration
- 4.5 Example: Creating a Statistics Module
- 4.6 Debugging Statistics
- 5 3. Steering
- 5.1 What is Steering?
- 5.2 Architecture
- 5.3 Steering Types
- 5.4 Steering Policies
- 5.4.1 Band Steering Policies
- 5.4.1.1 1. Pre-Association Policy
- 5.4.1.2 2. High Water Mark Policy
- 5.4.1.3 3. Low Water Mark Policy
- 5.4.2 Client Steering Policies
- 5.4.2.1 1. Force Kick Mode
- 5.4.2.2 2. Client Steering Mode
- 5.4.2.3 3. Idle Steering
- 5.4.2.4 4. Kick Type
- 5.4.1 Band Steering Policies
- 5.5 Steering Actions
- 5.5.1 1. ACL Block
- 5.5.2 2. BTM Request
- 5.5.3 3. Deauth
- 5.6 Steering Flow
- 5.7 Verifying Steering Configuration
- 5.7.1 Debug Output (SIGUSR1)
- 5.8 Testing & Debugging
- 6 Summary
Title: OWM Integrator Guide
Overview
This guide explains the key components that integrators need to understand when working with OWM (One Wifi Manager). It covers the three main subsystems: Confsync, Stats, and Steering.
1. Confsync
What is Confsync?
Confsync is the configuration synchronization engine that continuously ensures intended configuration (desired state) matches actual hardware state (current state) by detecting mismatches and applying necessary changes.
Architecture
┌────────────────────────────────────────┐
│ │
│ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ osw_conf │ │ osw_confsync │ │ osw_state │
│ (Intended │────▶│ (Sync │────▶│ (Actual │
│ Config) │ │ Engine) │ │ State) │
└──────────────┘ └──────────────┘ └──────────────┘
│
▼
┌──────────────┐
│ osw_mux │
│ (Driver │
│ Multiplexer) │
└──────────────┘
│
▼
HardwareHow It Works
Intended Config (osw_conf):
Supplemented from OVSDB tables (
Wifi_Radio_Config,Wifi_VIF_Config)Represents what the cloud/user wants
Updated when cloud sends new configuration
Actual State (osw_state):
Populated from driver/netlink events
Represents what hardware is actually doing
Updated automatically when hardware events occur
Sync Process:
Confsync observes changes in
osw_conforosw_stateCompares intended configuration vs actual state
Generates minimal command set to reconcile differences
Sends commands through
osw_muxto hardware driversVerifies hardware applied changes correctly
State Machine
Confsync uses a state machine to track the configuration process:
enum osw_confsync_state {
OSW_CONFSYNC_IDLE, // No configuration in progress
OSW_CONFSYNC_REQUESTING, // Preparing configuration
OSW_CONFSYNC_WAITING, // Waiting for hardware response
OSW_CONFSYNC_VERIFYING, // Verifying configuration was applied
};State Transitions:
IDLE → Changes detected in config or state
REQUESTING → Building configuration diff
WAITING → Commands sent to hardware
VERIFYING → Checking hardware applied changes
IDLE → Configuration matches state
Configuration Process
Step 1: Config Update
When OVSDB is updated:
// Cloud updates Wifi_Radio_Config
OVSDB UPDATE on Wifi_Radio_Config
↓
ow_ovsdb receives OVSDB update
↓
ow_conf translates configuration
↓
osw_conf updates internal structures
↓
osw_confsync detects change
↓
osw_confsync_set_state(OSW_CONFSYNC_REQUESTING)Step 2: Build Configuration
// Build target configuration
struct osw_drv_phy_config {
char *phy_name;
struct osw_hwaddr addr;
uint32_t tx_chainmask;
uint32_t rx_chainmask;
struct osw_channel channel;
// ... other fields
};
// Generate commands
for each phy:
compare target_config vs current_state
if different:
prepare command to applyStep 3: Apply to Hardware
// Send to hardware via nl80211 driver through osw_mux
osw_mux_request_phy_set_config(
phy_name,
&target_config
);Step 4: Verify
// State is updated automatically via netlink events
// osw_state reflects current hardware state
// Compare
if (config_matches_state) {
osw_confsync_set_state(OSW_CONFSYNC_IDLE);
} else {
// Retry or report error
}Confsync Watchdog
Confsync includes a watchdog that monitors configuration health and prevents configuration problems. The watchdog detects two types of issues:
Configuration happening too frequently - Device is constantly reconfiguring
Device can't configure - Device is unable to apply configuration successfully
Monitored Conditions:
Confsync not settled in 3 minutes
Spent >75% of last 5 minutes in UNSETTLED state
Actions:
When problems are detected, the watchdog takes the safest approach:
Logs error message
Sends Linux signal 6 (SIGABRT) to OWM process, which triggers OWM restart, clearing any stuck states and allowing fresh configuration attempt
Purpose:
The watchdog prevents the device from getting stuck in an unconfigured or constantly-reconfiguring state, ensuring configuration reliability and system stability. It also prevents the continuation of bogus states and other convoluted state combinations that could lead to unpredictable system behavior.
Scenarios of Watchdog Triggering:
The confsync watchdog will "bark" (trigger restart) in scenarios such as:
State reporting not implemented:
Driver fails to report current hardware state
Report function not implemented, returns wrong value, or memory not passed correctly
Result: Confsync can't verify if configuration was applied
Configuration request not implemented:
Driver missing configuration handlers
Configuration commands not implemented for certain features
Hardware can't configure - is it properly reported/value returned?
Result: Configuration requests are ignored, confsync keeps retrying
Broken comparison or returned value:
Incorrect state comparison logic in osw_confsync
Driver returns inconsistent or malformed state data
Mismatched data types or invalid values
Value incorrectly passes through abstraction layers
Configuration never matches state due to comparison bugs
Result: Perpetual UNSETTLED state
Real-World Example:
ACL Limit Exceeded on BCM Platform:
On the BCM platform, the ACL (Access Control List) limit is 64 entries. In one scenario:
Cloud configured 85 ACLs in OVSDB
All abstraction layers correctly passed 85 to the driver
However,
osw_plat_bcmonly read and configured the first 64 ACLs (hardware limit)The state reported 64 configured ACLs
Confsync compared: intended (85) ≠ actual (64)
Confsync couldn't settle and kept retrying to configure the remaining 21 ACLs
After repeated attempts, the confsync watchdog detected the perpetual UNSETTLED state
Watchdog restarted OWM to clear the stuck configuration
This demonstrates how hardware limitations can trigger the watchdog when the intended configuration exceeds platform capabilities and the mismatch isn't properly handled.
Debugging
Enable detailed logging:
Insert:
# Insert debug entry
ovsh i AW_Debug name:=OW log_severity:=Trace
# Monitor whole OW
logread -f | grep ow
# Monitor confsync
logread -f | grep confsync
# Monitor settled states
logread -f | grep settle2. Stats
What is Stats?
The Stats subsystem collects, processes, and reports wireless statistics including channel survey data, neighbor information, client metrics, and device performance. It uses an actor-based architecture where statistics are published to subscribers in a decoupled, asynchronous manner. Statistics may arrive at any point in time from various sources (driver, netlink, hardware counters).
Architecture
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Wifi_Stats_ │ │ow_stats_conf │ │ osw_stats │
│ Config │────▶│ (Config, │────▶│ (Publisher) │
│ (OVSDB) │ │ Subscriber) │ │ │
└──────────────┘ └──────────────┘ └──────────────┘
▲ │
│ ▼
┌──────────────┐ ┌────┴───────────┐
│ Driver │ │ Subscribers │
│ (Collector) │──────▶ (ow_stats_conf,│
└──────────────┘ │ ow_steer, │
│ dpp, etc.) │
└────────────────┘Statistics Types
1. Survey Statistics
Channel utilization information.
OVSDB Configuration (Wifi_Stats_Config):
stats_type : survey
survey_type : on-chan | off-chan | full
radio_type : 2.4G | 5G | 5GL | 5GU | 6G
sampling_interval : integer (seconds)
reporting_interval : integer (seconds)
channel_list : integer[] (1-233, max 64 channels)
survey_interval_ms : integer (milliseconds)2. Neighbor Statistics
Information about neighboring BSSs.
OVSDB Configuration (Wifi_Stats_Config):
stats_type : neighbor
radio_type : 2.4G | 5G | 5GL | 5GU | 6G
survey_type : on-chan | off-chan | full
sampling_interval : integer (seconds)
reporting_interval : integer (seconds)3. Client Statistics
Per-client performance metrics.
OVSDB Configuration (Wifi_Stats_Config):
stats_type : client
radio_type : 2.4G | 5G | 5GL | 5GU | 6G
sampling_interval : integer (seconds)
reporting_interval : integer (seconds)Collected Metrics:
Client association/disassociation events
Per-client counters from driver (TX/RX bytes, frames, retries, errors, rates)
SNR measurements
4. Device Statistics
Aggregate device metrics.
OVSDB Configuration (Wifi_Stats_Config):
stats_type : device
sampling_interval : integer (seconds)
reporting_interval : integer (seconds)Collected Metrics:
Temperature (gathered by OWM)
CPU usage, Memory usage, Uptime (handled by SM - Statistics Manager)
Configuration (Wifi_Stats_Config)
OVSDB Table Fields
_uuid : UUID (unique identifier)
_version : UUID (version identifier)
stats_type : neighbor | client | survey | device | radius_stats | latency | capacity | radio | essid | quality | rssi | steering | client_auth_fails
radio_type : 2.4G | 5G | 5GL | 5GU | 6G
survey_type : on-chan | off-chan | full | ["set",[]]
sampling_interval : integer (seconds, 0 = disabled)
reporting_interval : integer (seconds)
reporting_count : integer
survey_interval_ms : integer (milliseconds) | ["set",[]]
channel_list : ["set",[<channels>]] (e.g., ["set",[1,6,11]])
if_name : ["set",[<interfaces>]]
report_type : ["set",[]] | ["set",["raw","average","histogram","percentile","diff"]]
sample_policy : ["set",[]] | ["set",["separate","merge"]]
threshold : ["map",[]] | ["map",[["max_delay",<seconds>],["util",<percentage>]]]
latency_dscp : ["set",[]] | ["set",["do_not_report","report_per_dscp"]]
latency_kinds : ["set",[]] | ["set",["min","max","avg","last","num","perc"]]Key Fields
stats_type: Type of statistics to collectradio_type: Radio band (2.4G, 5G, 5GL, 5GU, 6G)survey_type: Scan method (on-chan, off-chan, full)sampling_interval: Collection frequency in seconds (0 = disabled)reporting_interval: Reporting frequency to cloud in secondschannel_list: Specific channels to monitor (e.g.,["set",[1,6,11]])survey_interval_ms: Time spent per channel in millisecondsthreshold: Conditions for withholding reports (e.g.,["map",[["max_delay",600],["util",10]]])
Example Configuration
# View current configuration
ovsh s Wifi_Stats_Config
# Example output shows multiple stat types configured per radio
# neighbor stats on 2.4G, 5GL, 5GU
# client stats on 2.4G, 5GL, 5GU
# survey stats on 2.4G (with channel_list)
# device stats (no radio_type)Example: Creating a Statistics Module
Here's how to create a new module that gathers specific statistics:
Step 1: Create the subscriber module
// my_stats_module.c
#include <osw_stats.h>
#include <log.h>
struct my_stats_module
{
struct osw_stats_subscriber *subscriber;
// Add your module-specific data here
};
// Callback when statistics arrive
static void
my_stats_cb(enum osw_stats_id id,
const struct osw_tlv *data,
const struct osw_tlv *last,
void *priv)
{
// Statistics arrive asynchronously at any time
// Only process client statistics
if (id != OSW_STATS_STA) return;
struct my_stats_module *module = priv;
// Get statistics definitions for parsing
const struct osw_stats_defs *stats_defs = osw_stats_defs_lookup(OSW_STATS_STA);
if (stats_defs == NULL) return;
// Parse TLV data
const struct osw_tlv_hdr *tb[OSW_STATS_STA_MAX__] = {0};
osw_tlv_parse(data->data, data->used, stats_defs->tpolicy, tb, OSW_STATS_STA_MAX__);
// Extract fields we're interested in
const struct osw_tlv_hdr *snr_db_t = tb[OSW_STATS_STA_SNR_DB];
const struct osw_tlv_hdr *sta_addr_t = tb[OSW_STATS_STA_MAC_ADDRESS];
if (snr_db_t == NULL) return;
if (sta_addr_t == NULL) return;
const uint32_t snr_db = osw_tlv_get_u32(snr_db_t);
struct osw_hwaddr sta_addr;
osw_tlv_get_hwaddr(&sta_addr, sta_addr_t);
LOGI("my_stats: client: " OSW_HWADDR_FMT " snr=%u",
OSW_HWADDR_ARG(&sta_addr),
snr_db);
}
// Initialize: allocate struct and fill in data
static void
my_stats_module_init(struct my_stats_module *module)
{
// Allocate subscriber
module->subscriber = osw_stats_subscriber_alloc();
// Configure subscriber
osw_stats_subscriber_set_report_fn(module->subscriber, my_stats_cb, module);
osw_stats_subscriber_set_report_seconds(module->subscriber, 10.0);
osw_stats_subscriber_set_sta(module->subscriber, true);
LOGI("my_stats: initialized");
}
// Attach: connect to the outside world
static void
my_stats_module_attach(struct my_stats_module *module)
{
// Register to receive statistics
osw_stats_register_subscriber(module->subscriber);
LOGI("my_stats: attached and subscribed");
}Step 2: Register the module
Use the OSW_MODULE macro with separate init and attach phases:
OSW_MODULE(my_stats_module)
{
static struct my_stats_module m;
my_stats_module_init(&m);
my_stats_module_attach(&m);
}Key Points:
Statistics use actor-based architecture with publisher-subscriber pattern
Stats arrive asynchronously at any point in time from various sources
Use TLV format for efficient, extensible data representation
Multiple subscribers can receive the same statistics independently
No need to poll - statistics are pushed to your module when available
Reference implementation: See
src/lib/osw/src/osw_sta_snr.cfor a complete real-world example
Debugging Statistics
# Enable OW debug logs
ovsh i AW_Debug name:=OW log_severity:=Debug
# Monitor statistics collection in logs
logread -f | grep "my_stats"
# View MQTT statistics reports
# Use OSRT to display MQTT Statistics3. Steering
What is Steering?
Steering manages client distribution across radios and bands to optimize wireless performance. It includes band steering (automatic distribution based on signal strength) and client steering (cloud-directed optimization for static devices).
Architecture
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│Band_Steering_ │ │Band_Steering_ │ │Wifi_VIF_ │
│Config │ │Clients │ │Neighbours │
│(OVSDB) │ │(OVSDB) │ │(OVSDB) │
└──────────────────┘ └──────────────────┘ └──────────────────┘
│ │ │
└─────────────────────┼──────────────────────┘
▼
┌─────────────────┐
│ ow_steer_bm │
│ (Band Manager) │
└─────────────────┘
│
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Policies │ │ Candidates │ │ Executors │
│ (Decisions) │ │ (Targets) │ │ (Actions) │
└──────────────┘ └──────────────┘ └──────────────┘
│ │ │
└──────────────┼──────────────┘
│
▼
┌─────────────────┐
│ osw_mux/btm │
│ (Hardware) │
└─────────────────┘Steering Types
OWM implements two distinct steering mechanisms:
Band Steering
Scope: Local on the device (AP/gateway), without cloud intervention
Target: Moving/mobile devices (not static clients)
Triggers:
SNR crossing events (RSSI XING): Client signal strength crosses HWM/LWM thresholds
VIF shutdown (
defer_vif_down): VIF is being disabled (10-second grace period allows steering clients to other VIFs before service interruption)
Methods:
Pre-association blocking (e.g., blocking 2.4GHz probe responses to force 5GHz association)
SNR threshold-based decisions (HWM/LWM/BOWM)
HWM (High Water Mark): Steer up to 5GHz when signal is strong
LWM (Low Water Mark): Steer down or away when signal degrades
BOWM (Bottom LWM): Force disconnect legacy (non-11v) clients on 2.4G when signal is critically low
Client Steering (Throughput Optimized Steering - TOS)
Scope: Cloud-triggered steering decisions
Target: Static devices (devices with little SNR variation)
Eligibility:
Stationary devices (e.g., Roku, MacBooks, Windows laptops)
Static classification determined nightly based on RSSI data over last 24 hours and majority of last 10 days
Only static devices are eligible unless they have a specific device profile
Methods:
802.11v BSS Transition Management (BTM)
Legacy deauth kicks
Idle Period Requirement:
Steering may be deferred during high traffic (video streaming, VoIP) to avoid user disruption
Device Profiles
When a client connects, the cloud identifies its device type (manufacturer, model) via MAC address and assigns a steering profile with customized thresholds and policies optimized for that device class. The profile is pushed to the AP via OVSDB.
Cloud Override Behavior:
Claimed pods in multi-AP topology: Cloud may override local settings (e.g., force
pref_5g:=always)Single-AP testing: Unclaim all pods to enable local HWM-based steering decisions
Steering Policies
Band Steering Policies
1. Pre-Association Policy
Blocks association to specific BSSs before connection (part of Band Steering).
Use Case: Prevent 2.4GHz connections for capable clients
Implementation: src/lib/ow/src/ow_steer_policy_pre_assoc.c
Key Fields:
pref_5g: Steering preference (always,never,hwm)pref_6g: 6GHz steering preference (always,never)pre_assoc_auth_block: Block pre-association auth requests (boolean)max_rejects: Maximum pre-association rejections (0 = unlimited)rejects_tmout_secs: Timeout to reset rejection counter (0 = no timeout)pref_5g_pre_assoc_block_timeout_msecs: Timeout for 5GHz blocking (milliseconds, default: 4000)reject_detection: Detection method (probe_all,probe_null,auth)preq_snr_thr: Probe request SNR threshold
Configuration:
# Always prefer 5GHz (block 2.4GHz probes)
ovsh i Band_Steering_Clients pref_5g:='always' pre_assoc_auth_block:=true mac:=AA:BB:CC:DD:EE:FF
# Use HWM-based logic
ovsh i Band_Steering_Clients pref_5g:='hwm' mac:=AA:BB:CC:DD:EE:FFNote: Use ovsh i (insert) over ovsh u (update). Insert verifies parameters and values during insertion, catching configuration errors early. Update only works on existing records
Verify:
ovsh s Band_Steering_Clients -w mac==AA:BB:CC:DD:EE:FF pref_5g pre_assoc_auth_block max_rejects2. High Water Mark Policy
Steers clients when SNR exceeds threshold (Band Steering).
Use Case: Distribute load across APs, steer capable clients from 2.4GHz to 5GHz when signal is strong
Implementation: src/lib/ow/src/ow_steer_bm_policy_hwm_2g.c
Key Fields:
hwm: High Water Mark SNR threshold in dB (default: 30)backoff_secs: Wait time before retrying steering (default: 120)kick_type: Mechanism for steering (btm_deauth,deauth,none)kick_debounce_period: Delay before kicking again in seconds (default: 60)steering_btm_params: BTM parameters (abridged, bss_term, btm_max_retries, btm_retry_interval, disassoc_imminent, pref, valid_interval)steering_kick_guard_time: Guard time before allowing kick (default: 10)steering_kick_backoff_time: Backoff time after kick failure (default: 1800)steer_during_backoff: Allow steering during backoff period (boolean)
Configuration:
# Standard band steering setup
ovsh i Band_Steering_Clients hwm:=35 lwm:=20 backoff_secs:=120 kick_type:=btm_deauth mac:=AA:BB:CC:DD:EE:FF
# Testing: Force upsteering to 5GHz
ovsh i Band_Steering_Clients hwm:=100 mac:=AA:BB:CC:DD:EE:FFVerify:
ovsh s Band_Steering_Clients -w mac==AA:BB:CC:DD:EE:FF hwm backoff_secs kick_type3. Low Water Mark Policy
Steers clients when signal quality drops below threshold (Band Steering).
Use Case: Move clients to better APs or bands when signal degrades
Implementation: src/lib/ow/src/ow_steer_policy_snr_xing.c
Key Fields:
lwm: Low Water Mark SNR threshold in dB (default: 10)bottom_lwm: Bottom LWM threshold for legacy clients (default: 5)sticky_kick_type: Kick mechanism for sticky steering (btm_deauth,deauth)sticky_btm_params: BTM parameters (abridged, bss_term, btm_max_retries, btm_retry_interval, disassoc_imminent, inc_neigh, pref, valid_interval)sticky_kick_debounce_period: Debounce period for sticky kicks (default: 60)sticky_kick_guard_time: Guard time for sticky kickssticky_kick_reason: Reason code for sticky kicks (default: 1)backoff_exp_base: Exponential backoff base multiplier (default: 3)
Configuration:
# Configure LWM steering
ovsh i Band_Steering_Clients lwm:=20 hwm:=35 bottom_lwm:=5 mac:=AA:BB:CC:DD:EE:FF
# Testing: Force downsteering to 2.4GHz
ovsh i Band_Steering_Clients lwm:=1 mac:=AA:BB:CC:DD:EE:FFVerify:
ovsh s Band_Steering_Clients -w mac==AA:BB:CC:DD:EE:FF lwm bottom_lwm hwm sticky_kick_type backoff_exp_baseClient Steering Policies
Cloud-triggered steering for static devices (Throughput Optimized Steering).
Use Case: Optimal AP selection for stationary devices (Roku, MacBooks, Windows laptops)
Implementation: src/lib/ow/src/ow_steer_policy_force_kick.c
1. Force Kick Mode
Controls proactive steering behavior.
Field: force_kick
Values:
speculative: Proactive steering based on predictiondirected: Cloud-directed steering to specific APnone: Disabled
2. Client Steering Mode
Controls when client steering is enabled.
Field: cs_mode
Values:
home: Enable steering in home networkaway: Enable steering in away networkoff: Disabled
3. Idle Steering
Controls whether to steer only idle clients.
Field: kick_upon_idle
Values:
true: Only steer when client is idle (< 200 PPDUs/min)false: Steer regardless of traffic
4. Kick Type
Selects steering mechanism.
Field: sc_kick_type
Values:
btm_deauth: Try BTM first, fall back to deauthdeauth: Use deauth directly
Additional Fields:
cs_state: Current steering state (read-only:steering,none,expired,failed)cs_params: Client steering parameterssc_btm_params: BTM parameters for client steeringsc_kick_debounce_period: Debounce period for client steering kickssc_kick_reason: Reason code for client steering kicksbtm_max_neighbors: Maximum neighbors in BTM request (default: 3)neighbor_list_filter_by_beacon_report: Filter neighbor list by beacon report (boolean, default: true)neighbor_list_filter_by_btm_status: Filter neighbor list by BTM status (boolean, default: true)
Configuration Examples:
# Enable directed client steering with idle check
ovsh i Band_Steering_Clients force_kick:='directed' cs_mode:='home' kick_upon_idle:=true sc_kick_type:='btm_deauth' mac:=AA:BB:CC:DD:EE:FF
# Disable client steering
ovsh i Band_Steering_Clients force_kick:='none' cs_mode:='off' mac:=AA:BB:CC:DD:EE:FFRequirements:
Device classified as static (low RSSI variation over 24h + majority of 10 days)
Device must be idle when
kick_upon_idle:=true(< 200 PPDUs/min over 3-minute window)Classification updated nightly by cloud
Verify:
ovsh s Band_Steering_Clients -w mac==AA:BB:CC:DD:EE:FF force_kick cs_mode cs_state kick_upon_idle sc_kick_typeSteering Actions
1. ACL Block
Block client via access control list.
2. BTM Request
Send BTM (802.11v) steering request.
3. Deauth
Force disassociation.
Steering Flow
For every client, the steering system maintains a list of candidate APs (alternative BSSs the client could connect to). Steering policies then edit this AP candidate list based on various criteria:
Candidate List Initialization:
System builds a list of potential target APs for each client
Consists of BSSs configured by Cloud in
Wifi_VIF_Neighbourand local APs fromWifi_VIF_State
Policy Evaluation:
Each active steering policy examines the candidate list sequentially
Policies filter out unsuitable candidates based on their criteria (SNR, load, capabilities)
Candidate Selection:
After all policies evaluate the list, the best remaining candidate is selected
Selection considers signal strength, band preference, and load balancing
If no suitable candidate exists, no steering action is taken
Action Execution:
Executor component performs the steering action using BTM, ACL, or deauth
Success/failure monitored and reported
Consequences and retry logic are executor-specific
Verifying Steering Configuration
Check all steering groups:
ovsh s Band_Steering_ConfigCheck all client policies:
ovsh s Band_Steering_ClientsCheck specific client configuration:
# View all steering settings for a client
ovsh s Band_Steering_Clients -w mac==AA:BB:CC:DD:EE:FF
# Check specific policy fields
ovsh s Band_Steering_Clients -w mac==AA:BB:CC:DD:EE:FF pref_5g hwm lwm force_kickCommon Policy Combinations:
Band Steering (local, moving devices):
ovsh i Band_Steering_Clients pref_5g:='hwm' hwm:=35 lwm:=20 mac:=AA:BB:CC:DD:EE:FFClient Steering (cloud, static devices):