802.11r works great for me with either FT over the air or DS but I had to switch to WPA2 as some Android devices have problems with WPA3 and become sticky unlike Apple devices which work perfectly.
Yes, it is. And everything else I mentioned too. Previously, this automagic did not exist, and the Internet is full of instructions telling you how to fill out all this bunch of fields.
Yes, this issue still exists and cannot be fixed without replacing this devices
Either you have WPA3 or FT.
Yeah, that mobility domain automatics was implemented just 8 years ago, in 2018.
Iāve encountered the same issue. After various tests, I found that smartphones shipped with Android 11 or earlierāespecially those based on platforms like the Snapdragon 865āhave problems with WPA3 roaming.
Because of this, I configured usteer to forcibly disconnect clients when the signal drops below a specified threshold. However, this setting is a double-edged sword. In situations where there is no alternative AP to roam to (for example, when moving back toward the edge of coverage), the aggressive kick-out behavior can cause the smartphone to interpret the situation as AP congestion.
In my environment, devices from the generation that originally shipped with Android 12 or laterāsuch as those based on the Snapdragon 888 or Snapdragon 7 Gen 1āare able to roam over WPA3 without any issues.
I hope this information is helpful.
EDIT:
This is not an issue with OpenWrt, but rather behavior related to Android itself (or the chipset and hardware used in that particular generation). I have confirmed that the same problem also occurs with Aruba. In the case of Aruba, I had to configure a more aggressive disconnect policy via ClientMatch in the Virtual Controller settings to handle sticky Android smartphones.
Hello @Immortal_gamer_2561,
have a look at version 15 of the script.
Regards
I was looking at this on 25.12-SNAPSHOT and regardless of whether Iām running wpad-mbedtls or wpad-basic-mbedtls, I donāt see any associated clients, which I know to be false since ubus -v call hostapd.phy2-ap0 get_clients clearly sees them. Is there something else Iām missing?
Have you noticed any issues with the 25.12 release? My clients stopped jumping from AP to AP. Here's an example log from the AP the client should jump to:
Log
[Feb 25, 2026, 5:09:42 PM GMT+2] daemon.notice: hostapd: phy1-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: did not acknowledge authentication response
[Feb 25, 2026, 5:09:42 PM GMT+2] daemon.notice: hostapd: phy1-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: did not acknowledge authentication response
[Feb 25, 2026, 5:09:52 PM GMT+2] daemon.info: hostapd: phy1-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: deauthenticated due to inactivity (timer DEAUTH/REMOVE)
[Feb 25, 2026, 5:10:43 PM GMT+2] daemon.notice: hostapd: phy1-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: did not acknowledge authentication response
[Feb 25, 2026, 5:10:53 PM GMT+2] daemon.info: hostapd: phy1-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: deauthenticated due to inactivity (timer DEAUTH/REMOVE)
[Feb 25, 2026, 5:11:05 PM GMT+2] daemon.notice: hostapd: phy1-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: did not acknowledge authentication response
[Feb 25, 2026, 5:11:15 PM GMT+2] daemon.info: hostapd: phy1-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: deauthenticated due to inactivity (timer DEAUTH/REMOVE)
[Feb 25, 2026, 5:12:20 PM GMT+2] daemon.notice: hostapd: phy1-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: did not acknowledge authentication response
[Feb 25, 2026, 5:12:21 PM GMT+2] daemon.notice: hostapd: phy0-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: did not acknowledge authentication response
[Feb 25, 2026, 5:12:21 PM GMT+2] daemon.notice: hostapd: phy1-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: did not acknowledge authentication response
[Feb 25, 2026, 5:12:21 PM GMT+2] daemon.notice: hostapd: phy0-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: did not acknowledge authentication response
[Feb 25, 2026, 5:12:30 PM GMT+2] daemon.info: hostapd: phy1-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: deauthenticated due to inactivity (timer DEAUTH/REMOVE)
[Feb 25, 2026, 5:12:31 PM GMT+2] daemon.info: hostapd: phy0-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: deauthenticated due to inactivity (timer DEAUTH/REMOVE)
[Feb 25, 2026, 5:14:48 PM GMT+2] daemon.notice: hostapd: phy1-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: did not acknowledge authentication response
[Feb 25, 2026, 5:14:58 PM GMT+2] daemon.info: hostapd: phy1-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: deauthenticated due to inactivity (timer DEAUTH/REMOVE)
[Feb 25, 2026, 5:18:08 PM GMT+2] daemon.notice: hostapd: phy1-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: did not acknowledge authentication response
[Feb 25, 2026, 5:18:18 PM GMT+2] daemon.info: hostapd: phy1-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: deauthenticated due to inactivity (timer DEAUTH/REMOVE)
[Feb 25, 2026, 5:19:52 PM GMT+2] daemon.notice: hostapd: phy1-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: did not acknowledge authentication response
[Feb 25, 2026, 5:20:02 PM GMT+2] daemon.info: hostapd: phy1-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: deauthenticated due to inactivity (timer DEAUTH/REMOVE)
[Feb 25, 2026, 5:20:20 PM GMT+2] daemon.notice: hostapd: phy1-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: did not acknowledge authentication response
[Feb 25, 2026, 5:20:30 PM GMT+2] daemon.info: hostapd: phy1-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: deauthenticated due to inactivity (timer DEAUTH/REMOVE)
[Feb 25, 2026, 5:21:28 PM GMT+2] daemon.notice: hostapd: phy1-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: did not acknowledge authentication response
[Feb 25, 2026, 5:21:38 PM GMT+2] daemon.info: hostapd: phy1-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: deauthenticated due to inactivity (timer DEAUTH/REMOVE)
[Feb 25, 2026, 5:21:51 PM GMT+2] daemon.info: hostapd: phy1-ap0: STA f4:ce:xx:xx:xx:xx IEEE 802.11: associated (aid 1)
[Feb 25, 2026, 5:22:04 PM GMT+2] daemon.notice: hostapd: phy1-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: did not acknowledge authentication response
[Feb 25, 2026, 5:22:04 PM GMT+2] daemon.notice: hostapd: phy1-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: did not acknowledge authentication response
[Feb 25, 2026, 5:22:14 PM GMT+2] daemon.info: hostapd: phy1-ap0: STA 46:02:xx:xx:xx:xx IEEE 802.11: deauthenticated due to inactivity (timer DEAUTH/REMOVE)
On release 24.10 with the same config everything is ok.
AP1 - mt7986
AP2 - mt7981
I'm on 25.12 since -rc1, no difference with 24.10.
AP - mt7986
Dump AP - mt7621
Probably, I've found root cause.
25.12.0-rc5 (option encryption 'sae'):
24.10.5 (option encryption 'sae'):
Just need to figure out how to switch off additional SAE capabilities in 25.12.0-rc5.
In my case OCV prevented Roaming due to different channel-bandwidths/capabilities.
I used a command like this to track one client roaming across several APs (in my case with the ips 192.68.2.70 - 192.168.2.75). Helped a lot.
for i in 70 71 72 73 74 75; do
(ssh -y -T root@192.168.2.$i "logread -f | awk '/xx:xx:xx:xx:xx:xx/ {print; fflush()}'" < /dev/null | sed "s/^/$(printf "\033[0;33m[AP-.$i]\033[0m ") /") &
done
What is the tool name that you used to check the params?
I described a quick hack in the issue - https://github.com/openwrt/openwrt/issues/22200
I just made a PR for luci-app-usteer to show the AKM and cipher in the tooltip PR 8367
@Double-G May I suggest adding a local MAC lookup in /etc/ethers?
EDIT:
...
# --- Identification ---
u_ip="" u_name="" e_name=""
if [ -f /etc/ethers ]; then
e_name=$(grep -m 1 "$assoc" /etc/ethers | cut -f 2)
fi
if [ -f /tmp/dhcp.leases ]; then
lease_line=$(grep -m 1 -i "$assoc" /tmp/dhcp.leases)
[ -n "$lease_line" ] && { u_ip=$(echo "$lease_line" | awk '{print $3}'); u_name=$(echo "$lease_line" | awk '{print $4}'); }
fi
if [ -z "$u_ip" ]; then
cfg_sec=$(uci -q show dhcp | grep -i "$assoc" | cut -d'.' -f2)
if [ -n "$cfg_sec" ]; then
u_ip=$(uci -q get "dhcp.$cfg_sec.ip"); u_name=$(uci -q get "dhcp.$cfg_sec.name")
fi
fi
if [ "$LOCAL_ONLY" = false ] && [ -z "$u_ip" ]; then
u_ip=$(ip neigh show | grep -m 1 -i "$assoc" | awk '{print $1}')
if [ -n "$u_ip" ]; then
u_name=$(nslookup "$u_ip" 2>/dev/null | grep "name =" | cut -d'=' -f2 | xargs | cut -d'.' -f1)
fi
fi
display_name="${u_name:-${e_name:-?}} ($u_ip)"
[ -z "$u_ip" ] && display_name="${e_name:-$assoc}"
...
EDIT2: another suggestion would be ciphers supported (by AP, not per client)
ubus call hostapd bss_info '{"iface": "phy1-ap0"}' | jsonfilter -e '@["wpa_pairwise"]'
ubus call hostapd bss_info '{"iface": "phy1-ap0"}' | jsonfilter -e '@["wpa_key_mgmt"]'

