Lets talk about usteer

I already made this simple test (forcing disassociation_imminent flag and disassociation_timer) in usteer code several weeks ago.
It made usteer working with my Redmi Note 8 Pro that was previously just ignoring transition_request.


I also did this months ago and reported my findings here

1 Like

Not exactly. My latest tests show more info:

  • The problem is that some phones, like my pixel 4, need to have the neighbors list in the bss transition command. If not it is ignored. Not need to modify the disassociation_imminent, it must be false to not break fast transition.
  • Others devices, ignore the bss transition command. For this devices, if they ignore the command, the disassociation_imminent must be true and this makes the AP to force disconnect the device.

So I suggest to fill the optional neighbors list of the command always, and if the device does not disconnect after X tries, then make the disassociation_imminent true.


I tried to create an account to contribute something in https://openwrt.org/docs/guide-user/network/wifi/usteer but cannot login via github. Do you know what I can do?

For new users it would be good to add "802.11r" to Setting up usteer with OpenWrt 21.02.x

1 Like

In my case (OnePlus 9 Pro, Android 13)
The disassociation_timer: 0 is working fine.
The disassociation_imminent is the issue.

When it's false, it will roam only when neighbor AP is available nearby.
When it's true, it will roam (kick) no matter what.

Hope usteer's developers will fix those bugs asap, in my opinion, usteer has very good potential

1 Like

You need to ask for the account first here: Applying for OpenWrt wiki account


I think I have finally usteer working. I only wanted it to do AP steering when the signal of the new AP is higher, so I added the:

# Minimum signal strength difference until AP steering policy is active
option signal_diff_threshold 10

but it seemed not to be working. After looking at the code, I added this too:

# Minimum signal-to-noise ratio or signal level (dBm) before attempting to trigger
# client scans for roaming
option roam_scan_snr -55

Seems to have done the magic and it works. Now roams with my two APs without problem. Is that needed? Other parameters that can be interesting for a simple roaming between APs depending on the signal, nothing more?


Worth putting this type of note on the wiki, even just as broad user tips. Can all be cleaned up one day if more/better advice comes along

The reason that works is because following that path, the client will eventually just get kicked (deauthed by the ap).

But that is not related to the actual band steering functionality of usteer, which is supposed to steer the client to another BSSID in the 5 GHz band through neighbor reporting.


Very nice. Is this option realy needed?
Needs it to be higher than "0"? I thought "0" is already the best.

# Minimum signal strength difference until AP steering policy is active
option signal_diff_threshold 10

Seeing the code, it seems than yes. With 0 is ignored, and has no sense to change from AP with the same signal. A value of 1 is ok if you want: https://github.com/openwrt/usteer/blob/7d2b17c91baf67419c0ce63dc6c65a7659ab6a5c/policy.c#L51-L52

I'm not sure about this. When the client is deauthed it gets totally disconnected and needs to connect again. But in my case it works with fast roaming, moving from one to the other AP without loosing connection.
For curiosity, the latest code is at openwrt repo: https://github.com/openwrt/usteer the other one that you use, from blogic, is a little outdated :wink:

I know and that's why I was telling you in case you can't comprehend the code.

I'm also aware of that but I was too lazy to again look for the location. The second link in my previous post is to the openwrt git repo with the up to date code of usteer.

This part of code has changed a lot between versions. I think it is entering by here:

that is a roaming petition to the client, as you can see because the disassociation_imminent parameter is false that is what forces to disconnect the client.

To disconnect the clients it uses del_client ubus commands, that is what is used in all the other cases (that are not AP roaming or band roaming) to disconnect the node.

I have logs that show the fast roaming between APs,

If someone more can confirm that the roam_scan_snr is needed for signal_diff_threshold I can add it to the wiki without problem.

Hey everyone,
I'm not a native english speaker, so I will try my best to explain and share...

I adjusted the config file for about 3 days really intensively with trials and errors, and I made it working perfectly well !

It's not totally "roaming".. it's actually kick the client when signal is above -55 dbi , and the signal differences is =>5 between AP's .

I'm using the roaming mechanism, with only 1 try (option roam_scan_tries 1), and immediately kick.

In my case, it's roaming perfectly well (SSH etc.. stay connected), seamless enough for me, altough i'm not using 802.11r , only 802.11 k&v .

Hope you'll find it useful
Feel free to share your thoughts :slight_smile:

config usteer
	# The network interface for inter-AP communication
	option 'network' 'lan'

	# Log messages to syslog (0/1)
	option 'syslog' '1'

	# Disable network communication (0/1)
	option local_mode '0'

	# Use IPv6 for remote exchange
	option 'ipv6' '0'

	# Minimum level of logged messages
	# 0 = fatal
	# 1 = info
	# 2 = verbose
	# 3 = some debug messages
	# 4 = network packet information
	# 5 = all debug messages
	option 'debug_level' '2'

	# Maximum number of neighbor reports set for a node
	#option max_neighbor_reports 8

	# Maximum amount of time (ms) a station may be blocked due to policy decisions
	#option sta_block_timeout 0

	# Maximum amount of time (ms) a local unconnected station is tracked
	#option local_sta_timeout 100

	# Maximum amount of time (ms) a measurement report is stored
	option measurement_report_timeout 1000

	# Local station information update interval (ms)
	#option local_sta_update 1000

	# Maximum number of consecutive times a station may be blocked by policy
	option max_retry_band 0

	# Maximum idle time of a station entry (ms) to be considered for policy decisions
	#option seen_policy_timeout 0

	# Minimum number of stations delta between APs before load balancing policy is active
	#option load_balancing_threshold 0

	# Minimum number of stations delta between bands before band steering policy is active
	option band_steering_threshold 0

	# Interval (ms) between sending state updates to other APs
	option remote_update_interval 1000

	# Number of remote update intervals after which a remote-node is deleted
	#option remote_node_timeout 10

	# Allow rejecting assoc requests for steering purposes (0/1)
	#option assoc_steering 0

	# Allow ignoring probe requests for steering purposes (0/1)
	#option probe_steering 0

	# Minimum signal-to-noise ratio or signal level (dBm) to allow connections
	#option min_connect_snr 0

	# Minimum signal-to-noise ratio or signal level (dBm) to remain connected
	#option min_snr 0

	# Timeout after which a station with snr < min_snr will be kicked
	#option min_snr_kick_delay 5000

	# Timeout (ms) for which a client will not be steered after rejecting a BSS-transition-request
	#option steer_reject_timeout 0

	# Timeout (in ms) after which a association following a disassociation is not seen
	# as a roam
	#option roam_process_timeout 5000

	# Minimum signal-to-noise ratio or signal level (dBm) before attempting to trigger
	# client scans for roaming
	#option roam_scan_snr 0
	option roam_scan_snr -55

	# Maximum number of client roaming scan trigger attempts
	option roam_scan_tries 1

	# Retry scanning when roam_scan_tries is exceeded after this timeout (in ms)
	# In case this option is set to 0, the client is kicked instead
	#option roam_scan_timeout 0

	# Minimum time (ms) between client roaming scan trigger attempts
	#option roam_scan_interval 10000
	option roam_scan_interval 0

	# Minimum signal-to-noise ratio or signal level (dBm) before attempting to trigger
	# forced client roaming
	#option roam_trigger_snr 0

	# Minimum time (ms) between client roaming trigger attempts
	#option roam_trigger_interval 60000
	option roam_trigger_interval 0

	# Timeout (ms) for client roam requests. usteer will kick the client after this times out.
	option roam_kick_delay 100

	# Minimum signal strength difference until AP steering policy is active
	option signal_diff_threshold 5

	# Initial delay (ms) before responding to probe requests (to allow other APs to see packets as well)
	#option initial_connect_delay 0

	# Enable kicking client on excessive channel load (0/1)
	#option load_kick_enabled 0

	# Minimum channel load (%) before kicking clients
	option load_kick_threshold 0

	# Minimum amount of time (ms) that channel load is above threshold before starting to kick clients
	#option load_kick_delay 10000

	# Minimum number of connected clients before kicking based on channel load
	#option load_kick_min_clients 10

	# Reason code on client kick based on channel load (default: WLAN_REASON_DISASSOC_AP_BUSY)
	#option load_kick_reason_code 5

	# Attempting to steer clients to a higher frequency-band every n ms.
	# A value of 0 disabled band-steering.
	option band_steering_interval 0

	# Minimal SNR or absolute signal a device has to maintain over band_steering_interval to be
	# steered to a higher frequency band
	#option band_steering_min_snr -60

	# Interval (ms) the device is sent a link-measurement request to help assess
	# the bi-directional link quality. Setting the interval to 0 disables link-measurements.
	option link_measurement_interval 0

	# Script to run after bringing up a node
	#option node_up_script ''

	# Message types to include in log
	# Available types:
	# - probe_req_accept
	# - probe_req_deny
	# - auth_req_accept
	# - auth_req_deny
	# - assoc_req_accept
	# - assoc_req_deny
	# - load_kick_trigger
	# - load_kick_reset
	# - load_kick_min_clients
	# - load_kick_no_client
	# - load_kick_client
	# - signal_kick
	#list event_log_types ''

	# List of SSIDs to enable steering on
	list ssid_list 'wifi_2.4g'
	list ssid_list 'wifi_5g'

1 Like

I have a odd issue where a 5ghz steered client flips over 2.4ghz in the middle of a transfer/stream periodically. I have the updated usteer config share by @McGiverGim.

My config was for steering between two 5GHz APs. For steering between 2.4 and 5 bands, there are more parameters but I don't have tried it.

usteer is sending beacon requests in a wrong way, that's why it's not working properly for me.
I always receive beacon responds in this format:

hostapd: wlan1: BEACON-RESP-RX xx:xx:xx:xx:xx:xx xx 04 0000000000000000000000008000000000000000000000000000

When sending beacon request manually with mode: 0 ,It's receiving the correct beacon respond :

ubus call hostapd.wlan1 rrm_beacon_req '{"addr":"xx:xx:xx:xx:xx:xx", "op_class":0, "channel":1, "duration":1, "mode":0, "bssid":"xx:xx:xx:xx:xx:xx"}'

DAWN have the option to set beacon mode, usteer does'nt .
it's a pity, I think usteer have very good potential, but this beacon responds makes roaming to not work at all .

Is this something you know how to fix with usteer? If so, could you somehow submit a PR for it?

I dont know how to do that,

This is the problematic line:

Looks like someone else opened an issue for this? https://github.com/blocktrron/usteer/issues/4