802.11r Fast Transition how to understand that FT works?

This is really helpful thank you!

I have been using WPA2-PSK. Is WPA3-SAE any faster in terms of transition or just the same?

With iPhones and ipads connectivity seems OK, and fast transitions seem to get reported in the logs OK, but after some time (maybe 2 days?) my wife complains she has to manually disconnect and reconnect WiFi. I never see this issue with android devices / Windows laptop.

I have not even tried to measure any difference between them.

If you wish to try WPA3-SAE on your own, I'll give you some clues. The minimum config you need is to enable 802.11r, and make sure to DISABLE Generate PMK locally (ft_psk_generate_local). This option is currently not working with WPA3.

OpenWRT will provide default values for the keys and identifiers, so there's no need to set them: nas_identifier is taken from the BSSID; mobility_domain will be the first 4 hex digits of the md5sum of the SSID; FT key is the md5sum of mobility_domain/radius_scret, and then used to set r0kh and r1hk with wildcard MACs and NAS identifiers. Beware that up to OpenWrt 21.02.xx, in case of PSK/SAE, the input is limited to 4 bytes (radius_secret will be empty), so it is safer to set your own key, but it will work without it nonetheless. From 22.03 onward, a 128-bit key will be generated from the mobility_domain & psk, and hostpad will then transform it into a 256-bit key.
Also, the transition will occur with any AP that uses that same key (nas_id and MAC will not be checked), which is not such a bit deal. If you wish to set your key with the wildcard MAC/nas_id, then use
ff:ff:ff:ff:ff:ff,*,Use-Your-Own-256bit-hex-key-here for r0kh (128-bit keys are
00:00:00:00:00:00,00:00:00:00:00:00,Repeat-Your-256bit-hex-key-here for r1kh

Support for 128-bit keys was maintained in hostapd for backward compatibility.

You may check /var/run/hostapd-phy* just to be sure everything is right:

mobility_domain=0123 # must be the same for all APs & interfaces
ft_psk_generate_local=0 # it will not work with WPA3 or EAP if not 0
nas_identifier=e89fxxxxxxd1 # this should be unique for every interface, default is the bssid
r0kh=ff:ff:ff:ff:ff:ff * 00112233445566778899aabbccddeeff # If using wildcard MAC/nas_id, this should be the same across all APs & interfaces within the same mobility domain
r1kh=00:00:00:00:00:00 00:00:00:00:00:00 00112233445566778899aabbccddeeff # then this key should match the one in r0hk above
wpa_key_mgmt=SAE FT-SAE # It should have FT-SAE, FT-PSK or FT-EAP

Since this appears to be relevant 4 years after I wrote it, I edited the post in Feb/2024 to fix the example by using commas to separate keys from MACs, to point out the keys should be 256 bits long, and to update the status of default key-generation after OpenWrt 22.03.

TLDR: starting with OpenWrt 22.03, when not using WPA3, all you need to do to make FT work is to enable 802.11r from LuCI (option ieee80211r '1' in /etc/config/wireless). With WPA3, including mixed mode, you must disable "Generate PMK locally" in LuCI (option ft_psk_generate_local '0' in /etc/config/wireless).
With current snapshots, the Generate PMK locally option will be automatically disabled when using WPA3, and will not even show up in LuCI.

4 Likes

@cotequeiroz: Does this imply that 802.11r won't work without a controller (i.e. the common home scenario of at least two independent access points with no RADIUS, DAWN or other controlling server infrastructure)? If so, is this just a temporary restriction or is there something unsolvable in the way that WPA3 SAE works?

It works without a controller. It's just that you need to configure your key for r0kh and r1kh like in the example, and both APs must be reachable from the LAN network, I think. I have no idea why it does not work with WPA3 SAE--if it is something in the standard that keeps it from working as before, or if it needs something from someone's to do list. I haven't looked at this.

BTW, I've been running with WPA3-SAE and 802.11r here since I wrote my last post, and haven't got any complains about Apple devices not connected. They have been running just fine.

1 Like

cotequeiroz, am I reading your post correctly?

You have encryption set to SAE and 802.11r is fast roaming correctly?

I would like to get that working as well...

Basically, assuming you're running 21.02 or master and configuring from luci, you just need to turn 802.11r on and disable 'Generate PMK locally'. Leave the r0kh and r1kh empty.

OpenWrt will generate a key for you. Test it with just that to see if it works. The caveat is that it will only use the mobility domain to do so, meaning it will only generate 65536 possible keys, vs 3.403E+38 if you set your own. If you don't set your own mobility domain, then anyone can use the same recipe to compute the key from your SSID, which is not good. I have sent a patch to append the PSK, which should be safe, but it has not been accepted yet.

Then a recommended next step is to setup your own 128-bit key to use for r0kh and r1kh. Running this will generate a random one for you:

dd if=/dev/random bs=16 count=1 2>/dev/null | md5sum | awk '{print $1}'
05ad9451dcaa84f746311694186c29e7

Using 05ad9451dcaa84f746311694186c29e7 as an example, then set:

  • r0kh to: ff:ff:ff:ff:ff:ff * 05ad9451dcaa84f746311694186c29e7
  • r1kh to: 00:00:00:00:00:00 00:00:00:00:00:00 05ad9451dcaa84f746311694186c29e7

This exact setup--the key has to be the same--should be used across all your wireless interfaces in all APs doing 802.11r for the same SSID (technically, it's the same mobility domain).

6 Likes

Anyone got problems with Apple devices sometimes not playing well with FT (my wife keeps complaining that she has to disable and re-enable WiFi now and then - perhaps after a long period of inactivity, but I am not sure)? I think this is only Apple because I don't see the issue on my android devices.

Is there a solution?

I used to have the exact same problem, then out of the blue--or most likely, a config change that I don't remember--they were gone.

I have 5 iPhones (X, XR, 11) regularly in my network of 6 Linksys E8450 running master from dec/2021 (7e89421a7c). I turned 802.11r on January 7, and have been running smoothly ever since.
I use WPA3/SAE, and have 802.11{w,r,k,v} on. DAWN fills up neighbor reports (don't know if that helps with FT). Perhaps ft_psk_generate_local 0 may make a difference. Here's my full config:

config wifi-iface 'Xxx_radio1'
        option device 'radio1'
        option network 'lan'
        option mode 'ap'
        option ssid 'Xxx'
        option encryption 'sae'
        option key '***'
        option ieee80211w '2'
        option ieee80211r '1'
        option ft_psk_generate_local '0'
        option ft_over_ds '0'
        option ieee80211k '1'
        option bss_transition '1'
        option ieee80211v '1'
        option disassoc_low_ack '0'

I don't have r0kh or r1kh set because I'm running my patch to compute them from psk. You may want to set them manually.

I also run a legacy SSID with WPA2-PSK, but I don't think I have Apple devices connected to it regularly. It has ft_psk_generate_local '1', and ieee80211w '1', but I can't say if it works or not.

Thanks for the tips!

Its interesting and frustrating how few of my devices support fast roaming...

My pixel3a will fast roam with PSK2 but not SAE. When I am using SAE the pixel3a locks onto an AP and will not let go until the signal is gone.

Windows 10 does not support 80211r on PSK networks.

My family has various iphones, and I tested one and I think 80211r was working, I need to test it further.

My chromebook will not connect to an SAE network.

My macbook pro m1 from 2020 seems to use 80211r with SAE fine.

So I seem to have it working for apple devices at least.

Here is what I have:

config wifi-iface 'default_radio1'
        option device 'radio1'
        option network 'lan'
        option mode 'ap'
        option ssid 'XXXX'
        option encryption 'psk2'
        option key 'XXXX'
        option wds '1'
        option ieee80211r '1'
        option ft_psk_generate_local '1'
        option reassociation_deadline '20000'
        option ft_over_ds '0'

@netprince yes my Pixel 3a (what a great device) is very happy with FT on PSK2. Works perfectly all the time. And I have confirmed multiple times FT's throughout the house between 3x RT3200's. I have not tried SAE. It sounds like that is going to break my Pixel 3a or older devices. So stuck between rock and hard place?

I think my wife has an iPhone 13 and that seems to not be working with my PSK2 setup. When I say not working I need to qualify this. When I test it, it works fine. I see the fast transitions as I walk around the house and have confirmed with the right level of logging:

The problem is that now and then the iPhone needs to be manually reconnected. It's hard to reproduce.

@hnyman suggested some ideas to get the iPhones to work here:

Could it be something related to inactivity polling:

Certainly I think the issue relates to use following a lengthy period of inactivity. My wife picks up phone from charge and observes no WiFi, and has to manually disable and re-enable.

Had the same issues with my iphone xr and these settings (on all ap’s) resolved the issues:

option reassociation_deadline '20000'
option max_inactivity '15'

Read here:

This is my config:

config wifi-iface 'wifinet0'
	option device 'radio0'
	option ssid 'xxx'
	option encryption 'psk2'
	option key ''
	option network 'lan'
	option mode 'ap'
	option ieee80211r '1'
	option ft_over_ds '0'
	option ft_psk_generate_local '1'
	option mobility_domain '1111'
	option reassociation_deadline '20000'
	option max_inactivity '15'

1 Like

Thanks. I missed this. What does it do and why 15?

1 Like

i was experementing with dawn and it really works great till client get deauntificated due inactivity (when clent moved from one point to another in 5 -300 secounds ususly it gets deautificated), hostapd does it
so i wonder if you can figure out the parametr that makes deauntification time longer like 30 minuts in my opinion would be grate

Well actually i just needed a quick solution for my issue and I didn’t really question why it was working :sweat_smile:.
This is the default value written in the doc:

max_inactivity integer no 300
Station inactivity limit in seconds: If a station does not send anything in ap_max_inactivity seconds, an empty data frame is sent to it in order to verify whether it is still in range. If this frame is not ACKed, the station will be disassociated and then deauthenticated.

Found here:

This was the best explanation I could find:

Going A->B works perfectly, but since the client is never deauth/disassociated from A after the transition, going back to A before max_inactivity kicks in on AP A means the client will not reassociate to A, because A expects the old key and Client uses a new one I suppose (and it's still registered in the kernel, you can observe the infamous "Could not set STA to kernel driver" error until the client decides to re-do the entire handshake properly).
Lowering max_inactivity to 15 seconds allowed me to mostly work around this issue.

So, if I understand correct, with a lower max_inactivity the client get’s deauthed sooner and I guess this helps if you move from A -> B and back to A in a short amount of time.

1 Like

Hmm thanks yes. I did read that but find it curious. Does that also apply for FT over air? Since the author writes about FT over DS. It seems mysterious to me. Shouldn't a device deauthenticate as part of transitioning from A to B? Feels like something is broken and this is a band aid.

@hnyman would you be able to shed any light on this?

if u use somthing like DAWN for 802.11 k v tecnology and this parametr is what i think it will be good
also why u trying to set up 802.11r? 802.11k and 802.11v also important tecnologys , and help devices to make switchuing disicion faster and DAWN actually use these 2 tecnology

@Hudra since setting max_inactivity to '15' I have had no more complaints from my wife. This may mean that the iPhone problems have been resolved.

2 Likes

That’s good to hear. Happy wife, happy life :grin:

I hope it stays this way because a few days after writing you I got some occasional disconnects again. Most of the time I wasn’t even moving from one ap to the other. Just lying on the couch and watching YouTube on my phone. I didn’t have to reconnect manually and after approx. a minute I was always back online. No issues with other devices only with my iPhone xr.
I think there maybe was a bug because I tried every possible wifi setting (that made sense)– I even tried DAWN but noting really made a difference. When I upgraded to the latest snapshot a few days ago my issues seemed to disappear. So in the last 4 days I only had 1 disconnect of this kind. Fingers crossed

2 Likes

I tried this settings too, but xiaomi Mi 9se sometimes keeps freezing wifi-connection connection from time to time.
Fast Roaming works well (only with WPA2, WPA3 cause 4-way re-association) but phone gets in trouble, especially when moving from an AP area to the next while in doze mode.

Here's an extract from phone's log. Anyone spotting something useful?

03-11 18:37:22.875  3282  3282 I MiuiDozeScreenBrightnessController: unregister sensor listener
03-11 18:37:22.875  3282  3282 I MiuiDozeScreenBrightnessController: unregister non ui sensor listener
03-11 18:37:22.875  3282  3282 V DreamService[DozeService]: finish(): mFinished=true
03-11 18:37:22.875  3282  3282 V DreamService[DozeService]: finish(): mFinished=true
03-11 18:37:22.875  3282  3282 V DreamService[DozeService]: onDestroy()
03-11 18:37:22.875  3282  3282 V DreamService[DozeService]: finish(): mFinished=true
03-11 18:37:22.876   841   918 I sensors-hal: activate:147, xiaomi.sensor.aod/37 en=0
03-11 18:37:22.878   841   918 I sensors-hal: activate:158, xiaomi.sensor.aod/37 en=0 completed
03-11 18:37:22.880   841   918 I sensors-hal: activate:147, xiaomi.sensor.nonui/15 en=0
03-11 18:37:22.881   841   918 I sensors-hal: activate:158, xiaomi.sensor.nonui/15 en=0 completed
03-11 18:37:22.882  1488  2294 I chatty  : uid=1000(system) ConnectivitySer expire 64 lines
03-11 18:37:22.883  1290  1290 E wificond: Skip scan ssid for single scan: {}
03-11 18:37:22.883  1290  1290 E wificond: scan() freq: {}
03-11 18:37:22.883  1290  1290 E wificond: scan() ssid: 
03-11 18:37:22.883  1290  1290 E wificond: scan() type: 0, random_mac: 0
03-11 18:37:22.883  2746  3730 D QCNEJ/WlanStaInfoRelay: Received action: android.net.wifi.RSSI_CHANGED
03-11 18:37:22.884 13468 13528 D QCNEJ/WlanStaInfoRelay: Received action: android.net.wifi.RSSI_CHANGED
03-11 18:37:22.885  2771  3079 D MainServiceImplHandler: : handleMessage msg.what = 7
03-11 18:37:22.885  2771  3079 D MainServiceImplHandler: : EVENT_ON_NR_ICON_TYPE
03-11 18:37:22.885  2771  3079 D MainServiceImpl: onNrIconType: Responding back for transaction = null
.....
03-11 18:37:23.079  2771  2771 D DynamicSarService: PhoneStateListener.onDataActivity: direction=3
03-11 18:37:23.079  2771  2771 D DynamicSarService: modem state change, messageType: 128 state: 3
03-11 18:37:23.079  2771  2771 D DynamicSarService: PhoneStateListener.onDataActivity: direction=3
03-11 18:37:23.079  2771  2771 D DynamicSarService: modem state change, messageType: 128 state: 3
......
03-11 18:37:23.608  2771  2771 D DynamicSarService: onSensorChanged distance = 1
03-11 18:37:23.608  2771  2771 D WifiSarController: onStateChanged: type = 3, value = 1
03-11 18:37:23.608  2771  2771 D WifiSarController: setSARLimit: 2
03-11 18:37:23.609 15058 15058 I wpa_supplicant: nl80211: Set SAR mode: enable=2 spec=0 sar_version=1
03-11 18:37:23.619  3204 27671 I chatty  : uid=1002(bluetooth) Binder:3204_7 expire 5 lines
03-11 18:37:23.626  2386 16467 I chatty  : uid=1002(bluetooth) Binder:2386_10 expire 16 lines
03-11 18:37:23.630   816  3085 I chatty  : uid=1002 bluetooth@1.0-s expire 186 lines
....
03-11 18:37:24.459  2605  2605 E DnsResolver: resNetworkResult:android.system.ErrnoException: resNetworkResult failed: ETIMEDOUT (Connection timed out)
03-11 18:37:24.460  2605  2605 E DnsResolver: resNetworkResult:android.system.ErrnoException: resNetworkResult failed: ETIMEDOUT (Connection timed out)
.....
03-11 18:37:26.626  2605 15070 W IpClient.wlan0: [IpReachabilityMonitor] WARN ALERT neighbor went from: NeighborEvent{@175539593,RTM_NEWNEIGH,if=30,192.168.1.1,NUD_PROBE,[cc:2d:21:e8:03:10]} to: NeighborEvent{@175545987,RTM_NEWNEIGH,if=30,192.168.1.1,NUD_FAILED,[null]}
03-11 18:37:26.623  1327  1327 W /system/vendor/bin/ipacm: type=1400 audit(0.0:277824): avc: denied { write } for comm=6E65746C696E6B20736F636B6574 name="ipacm_log_file" dev="tmpfs" ino=29625 scontext=u:r:ipacm:s0 tcontext=u:object_r:ipacm_socket:s0 tclass=sock_file permissive=0
03-11 18:37:26.627  2605 15070 W IpReachabilityMonitor: FAILURE: LOST_PROVISIONING, NeighborEvent{@175545987,RTM_NEWNEIGH,if=30,192.168.1.1,NUD_FAILED,[null]}
03-11 18:37:26.623  1327  1327 W /system/vendor/bin/ipacm: type=1400 audit(0.0:277825): avc: denied { write } for comm=6E65746C696E6B20736F636B6574 name="ipacm_log_file" dev="tmpfs" ino=29625 scontext=u:r:ipacm:s0 tcontext=u:object_r:ipacm_socket:s0 tclass=sock_file permissive=0
03-11 18:37:26.623  1327  1327 W /system/vendor/bin/ipacm: type=1400 audit(0.0:277826): avc: denied { write } for comm=6E65746C696E6B20736F636B6574 name="ipacm_log_file" dev="tmpfs" ino=29625 scontext=u:r:ipacm:s0 tcontext=u:object_r:ipacm_socket:s0 tclass=sock_file permissive=0
03-11 18:37:26.623  1327  1327 W ipacm   : type=1400 audit(0.0:277827): avc: denied { write } for name="ipacm_log_file" dev="tmpfs" ino=29625 scontext=u:r:ipacm:s0 tcontext=u:object_r:ipacm_socket:s0 tclass=sock_file permissive=0
03-11 18:37:26.623  1327  1327 W ipacm   : type=1400 audit(0.0:277828): avc: denied { write } for name="ipacm_log_file" dev="tmpfs" ino=29625 scontext=u:r:ipacm:s0 tcontext=u:object_r:ipacm_socket:s0 tclass=sock_file permissive=0
03-11 18:37:26.632   855   855 E android.hardware.wifi@1.0-service: Error deleting file: Permission denied
03-11 18:37:26.632   855   855 I chatty  : uid=1010 wifi@1.0-servic identical 12 lines
03-11 18:37:26.632   855   855 E android.hardware.wifi@1.0-service: Error deleting file: Permission denied
03-11 18:37:26.632   855   855 E android.hardware.wifi@1.0-service: Error occurred while deleting old tombstone files
03-11 18:37:26.632   855   855 E android.hardware.wifi@1.0-service: Error writing files to flash

No, but this sounds pretty grave to me (especially the second line below):

03-11 18:37:26.632   855   855 E android.hardware.wifi@1.0-service: Error deleting file: Permission denied
03-11 18:37:26.632   855   855 E android.hardware.wifi@1.0-service: Error occurred while deleting old tombstone files
03-11 18:37:26.632   855   855 E android.hardware.wifi@1.0-service: Error writing files to flash

In case helpful, these are the settings that resulted in no further comments from my wife - happy wife giving a happy life and all:

config wifi-iface 'default_radio0'
        option device 'radio0'
        option network 'lan'
        option mode 'ap'
        option ssid 'XXXX'
        option encryption 'psk2'
        option key 'XXXX'
        option ieee80211r '1'
        option ft_psk_generate_local '1'
        option reassociation_deadline '20000'
        option ft_over_ds '0'
        option max_inactivity '15'

config wifi-iface 'default_radio1'
        option device 'radio1'
        option network 'lan'
        option mode 'ap'
        option ssid 'XXXX'
        option encryption 'psk2'
        option key 'XXXX'
        option wds '1'
        option ieee80211r '1'
        option ft_psk_generate_local '1'
        option reassociation_deadline '20000'
        option ft_over_ds '0'
        option max_inactivity '15'