Proper configuration of 802.11k and 802.11v

My understanding is that it is unnecessary. I am basing it on the fact that ubus call usteer remote_info happily returns all of my APs/SSIDs. Further, for each of the results, the output includes "rrm_nr" which lists the BSSID, SSID, and Neighbor Report value.

Also, based on this, https://github.com/openwrt/usteer#functions, I am [perhaps naively] assuming "Synchronization of Neighbor Reports between multiple APs" is fulfilling the role that static-neighbor-report would otherwise play.

If anyone knows that static-neighbor-report is actually needed with Usteer, I'll be glad to be corrected on that for the sake of science. :slight_smile:

1 Like

Sure is! That's the purpose of the enabled event log types (list event_log_types ...) in my config. Running logread -f will allow you to see a lot of what Usteer is doing.

2 Likes

Making some more interesting discoveries on this topic. Any iPhone users who also happen to be somewhat Wireshark savvy--could you help test something with me?

I just ran a wireless sniffer capture from my MacBook. If you're not familiar, this is a built-in Mac tool that does a low-level (i.e. raw) capture from your wireless card. It gets all the 802.11 packets you don't typically see in a Wireshark capture on a Mac. Here's the process: https://osxdaily.com/2015/04/23/sniff-packet-capture-packet-trace-mac-os-x-wireless-diagnostics/

When analyzing the sniffer capture in Wireshark (again, post-capture), I found two of my iPhones (an iPhone 11 and an iPhone 12 Pro Max) are not indicating support for neighbor reports in their RM capabilities when sending an association request to the AP. Supposedly these iPhones support 802.11k, but the association request says otherwise.

Example:

When the AP sends the association response back, it indicates it supports neighbor report (hooray for 802.11k), but also states AP channel report capability is disabled:

Because the iPhones state they don't have neighbor report enabled, they never send a Neighbor Report Request, thus the AP does not send a Neighbor Report Response back.

Not sure what to make of all this yet, but wanted to float the info out there to the smarter brains who might have some thoughts about it.

For anyone willing to test this with me, the following display filter in Wireshark should show the packets we're interested in here:

Display Filter:
wlan.fc.type_subtype==0x0 || wlan.fc.type_subtype==0x1 || wlan.fixed.action_code==4 || wlan.fixed.action_code==5

Key:
wlan.fc.type_subtype==0x0 = Association Request
wlan.fc.type_subtype==0x1 = Association Response
wlan.fixed.action_code==4 = Neighbor Report Request
wlan.fixed.action_code==5 = Neighbor Report Response

2 Likes

With this usteer configuration, I believe I fixed my roaming "issues". I see no more 4 way handshake and Viber do not disconnect while walking around my apartment. I need to test it with MS Teams. I needed just to comment the min snr -70, as when I am smoking on the terrace I got disconnected from the AP.
Thanks. Will continue testing

Glad to hear a positive report back on the config, though I'm a little confused by your mention of no more 4-way handshakes. That's not necessarily a good thing, TBH. But maybe I misunderstood what you were saying.

Would you mind elaborating on that point some more?

As far as I understood it from other topics like https://forum.openwrt.org/t/any-way-to-monitor-if-802-11r-is-working/73504/2?u=underworld with "k" roaming you should not have again 4 way handshakes, as the clients are already authenticated and you should see something like this auth_alg=ft. And in fact now I do not see 4 way mesages and roaming seems to work.
Regards

Ah, yes! So in an ideal configuration, you would be seeing much more of this in your logs:

WPA: FT authentication already completed - do not start 4-way handshake

And just for the sake of not leading anyone astray on this thread, that is a feature/function of 802.11r, not specifically 802.11k/v. Though obviously when configured properly, they all play together for a great end-user experience. :slight_smile:

2 Likes

Yep but I never saw : WPA: FT authentication already completed - do not start 4-way handshake, in my 4-5 years of experiments. I am glad however that I do not see anymore 4-way handshake messages.

Continuing this discovery... I confirmed that without Usteer or Dawn, beacon frames from the AP do not have Link Measurement enabled. This screen capture is what the beacon looks like when Usteer or Dawn are enabled (I tested with each enabled independently):

And the beacon without either Usteer or Dawn:

1 Like

Any thoughts on this:

In yet another interesting twist, I found an older iPhone 7 which is running iOS 15.7.3. It actually sends a Neighbor Report Request:

However, the AP does not reply with a Neighbor Report Response.

I have a single Android device (not by choice) in my house and it properly exchanges Neighbor Report Requests and Neighbor Report Responses with my APs.

Is this an iOS issue? Does Apple not use NRRs anymore?

In relation to my previous post, I have submitted a bug report with Apple to make them aware of what I am seeing. Not going to hold my breath on getting actionable responses back, but they may surprise me.

3 Likes

Here is a question, mindful that both DAWN and Usteer have various snags. Perhaps @patrakov, @account4538 or @eR2022 can offer some insight.

Would you expect enabling 802.11k and 802.11v without doing anything else to cause harm? If so why? And what minimum extra step(s) should be undertaken to make things work well with having enabled 802.11k and/or 802.11v? For example, above there was mention of static-neighbor-report.

No harm in enabling any of these options by themselves.

Here is a DAWN config that works for me with WPA2 - but note that this is just a test setup, and I don't really need the second AP. The test clients are two Linux laptops with Intel AX200 and AX210 cards, and Samsung Galaxy A02 phone. I know that there are lots of options that should better be removed.

And note: this has been tested on the 2.4 GHz only, as band steering inevitably adds latency spikes while in the gray area. I could not get 802.11r to work reliably - sometimes it does roam with FT, sometimes it does a full 4-way handshake.

/etc/config/wireless fragment on Linksys E8450
config wifi-device 'radio0'
	option type 'mac80211'
	option path 'platform/18000000.wmac'
	option band '2g'
	option country 'PH'
	option htmode 'HT40'
	option channel '13'
	option noscan '1'
	option local_pwr_constraint '0'
	option cell_density '1'
	option txpower '20'
	option log_level '1'

config wifi-iface 'wifinet5'
	option device 'radio0'
	option mode 'ap'
	option ssid 'Backbone'
	option encryption 'psk2+ccmp'
	option wds '1'
	option key 'PASSWORD'
	option ieee80211w '2'
	option wpa_disable_eapol_key_retries '1'
	option network 'lan'
	option ieee80211r '1'
	option mobility_domain 'af15'
	option ft_psk_generate_local '0'
	option bss_transition '1'
	option wnm_sleep_mode '1'
	option time_advertisement '2'
	option time_zone 'GMT0'
	option ieee80211k '1'
	option ft_over_ds '0'
	option reassociation_deadline '20000'
/etc/config/wireless fragment on Netgear WAX202 (used as a repeater)
config wifi-device 'radio0'
	option type 'mac80211'
	option path '1e140000.pcie/pci0000:00/0000:00:01.0/0000:02:00.0'
	option band '2g'
	option country 'PH'
	option noscan '1'
	option htmode 'HT40'
	option channel '13'
	option cell_density '1'
	option txpower '20'
	option log_level '1'

config wifi-iface 'wifinet1'
	option device 'radio0'
	option mode 'sta'
	option ssid 'Backbone'
	option bssid 'EA:9F:80:D4:9E:C5'
	option key 'PASSWORD'
	option wds '1'
	option encryption 'psk2+ccmp'
	option ieee80211w '2'
	option network 'lan'

config wifi-iface 'wifinet2'
	option device 'radio0'
	option mode 'ap'
	option ssid 'Backbone'
	option encryption 'psk2+ccmp'
	option wds '1'
	option key 'PASSWORD'
	option ieee80211r '1'
	option mobility_domain 'af15'
	option ft_psk_generate_local '1'
	option ieee80211w '2'
	option wpa_disable_eapol_key_retries '1'
	option network 'lan'
	option bss_transition '1'
	option wnm_sleep_mode '1'
	option time_advertisement '2'
	option time_zone 'GMT0'
	option ieee80211k '1'
	option ft_over_ds '0'
	option reassociation_deadline '20000'
/etc/config/dawn, identical on both devices
config local
	option loglevel '1'

config network
	option broadcast_ip '192.168.10.255'
	option broadcast_port '1025'
	option tcp_port '1026'
	option network_option '2'
	option shared_key 'PASSWORDpassword'
	option iv 'PASSWORDpassword'
	option use_symm_enc '1'
	option collision_domain '-1'
	option bandwidth '-1'

config hostapd
	option hostapd_dir '/var/run/hostapd'

config times
	option con_timeout '60'
	option update_client '10'
	option remove_client '15'
	option remove_probe '30'
	option remove_ap '460'
	option update_hostapd '10'
	option update_tcp_con '10'
	option update_chan_util '5'
	option update_beacon_reports '20'

config metric 'global'
	option min_probe_count '2'
	option bandwidth_threshold '0'
	option kicking_threshold '10'
	option min_number_to_kick '3'
	option use_station_count '0'
	option max_station_diff '1'
	option eval_probe_req '0'
	option eval_auth_req '0'
	option eval_assoc_req '0'
	option deny_auth_reason '1'
	option deny_assoc_reason '17'
	option chan_util_avg_period '3'
	option duration '150'
	option set_hostapd_nr '2'
	option rrm_mode 'apt'
	option kicking '1'

config metric '802_11g'
	option initial_score '70'
	option ht_support '0'
	option vht_support '0'
	option rssi '0'
	option low_rssi_val '-80'
	option low_rssi '-15'
	option chan_util '0'
	option max_chan_util '0'
	option rssi_weight '1'
	option no_ht_support '0'
	option no_vht_support '0'
	option rssi_val '-60'
	option chan_util_val '140'
	option max_chan_util_val '170'
	option rssi_center '-50'

config metric '802_11a'
	option initial_score '100'
	option ht_support '0'
	option vht_support '0'
	option rssi '0'
	option low_rssi_val '-80'
	option low_rssi '-15'
	option chan_util '0'
	option max_chan_util '-15'
	option no_ht_support '0'
	option no_vht_support '0'
	option rssi_val '-60'
	option chan_util_val '140'
	option max_chan_util_val '170'
	option rssi_weight '1'
	option rssi_center '-70'

The key for reliable kicking was to enable active probing.

1 Like

Thanks for posting that config!

How do you test? I found the android phone app Ubiquiti WiFiman app helpful because it shows you transitions in real-time with continuously plotting graph of signal strength. I haven't figured out a good alternative for Apple iPhones or iPads. Or perhaps with DAWN you can look in the DAWN logs.

The motivation behind my question was just that it seems nice to be able to be able to keep things simple. I think that was perhaps @account4538's approach.

I also test using that, but also note that it produces some false reports about roaming. I.e. it draws an arrow without the word "Disconnected", while in the hostapd log on the AP there is clearly a 4-way handshake.

Screenshot falsely indicating a successful roam but also a huge latency spike:

Hostapd log on the target AP, clearly indicating that FT did not work this time:

Wed Mar  8 09:00:28 2023 daemon.debug hostapd: wlan0-1: STA c8:51:42:23:d4:0c IEEE 802.11: authentication OK (open system)
Wed Mar  8 09:00:28 2023 daemon.debug hostapd: wlan0-1: STA c8:51:42:23:d4:0c MLME: MLME-AUTHENTICATE.indication(c8:51:42:23:d4:0c, OPEN_SYSTEM)
Wed Mar  8 09:00:28 2023 daemon.debug hostapd: wlan0-1: STA c8:51:42:23:d4:0c MLME: MLME-DELETEKEYS.request(c8:51:42:23:d4:0c)
Wed Mar  8 09:00:28 2023 daemon.info hostapd: wlan0-1: STA c8:51:42:23:d4:0c IEEE 802.11: authenticated
Wed Mar  8 09:00:28 2023 daemon.debug hostapd: wlan0-1: STA c8:51:42:23:d4:0c IEEE 802.11: association OK (aid 1)
Wed Mar  8 09:00:28 2023 daemon.info hostapd: wlan0-1: STA c8:51:42:23:d4:0c IEEE 802.11: associated (aid 1)
Wed Mar  8 09:00:28 2023 daemon.debug hostapd: wlan0-1: STA c8:51:42:23:d4:0c MLME: MLME-ASSOCIATE.indication(c8:51:42:23:d4:0c)
Wed Mar  8 09:00:28 2023 daemon.debug hostapd: wlan0-1: STA c8:51:42:23:d4:0c MLME: MLME-DELETEKEYS.request(c8:51:42:23:d4:0c)
Wed Mar  8 09:00:28 2023 daemon.debug hostapd: wlan0-1: STA c8:51:42:23:d4:0c IEEE 802.11: binding station to interface 'wlan0-1'
Wed Mar  8 09:00:28 2023 daemon.debug hostapd: wlan0-1: STA c8:51:42:23:d4:0c WPA: event 1 notification
Wed Mar  8 09:00:28 2023 daemon.debug hostapd: wlan0-1: STA c8:51:42:23:d4:0c WPA: start authentication
Wed Mar  8 09:00:28 2023 daemon.debug hostapd: wlan0-1: STA c8:51:42:23:d4:0c IEEE 802.1X: unauthorizing port
Wed Mar  8 09:00:28 2023 daemon.debug hostapd: wlan0-1: STA c8:51:42:23:d4:0c WPA: sending 1/4 msg of 4-Way Handshake
Wed Mar  8 09:00:28 2023 daemon.debug hostapd: wlan0-1: STA c8:51:42:23:d4:0c WPA: received EAPOL-Key frame (2/4 Pairwise)
Wed Mar  8 09:00:28 2023 daemon.debug hostapd: wlan0-1: STA c8:51:42:23:d4:0c WPA: sending 3/4 msg of 4-Way Handshake
Wed Mar  8 09:00:28 2023 daemon.debug hostapd: wlan0-1: STA c8:51:42:23:d4:0c WPA: received EAPOL-Key frame (4/4 Pairwise)
Wed Mar  8 09:00:28 2023 daemon.notice hostapd: wlan0-1: AP-STA-CONNECTED c8:51:42:23:d4:0c
Wed Mar  8 09:00:28 2023 daemon.debug hostapd: wlan0-1: STA c8:51:42:23:d4:0c IEEE 802.1X: authorizing port
Wed Mar  8 09:00:28 2023 daemon.info hostapd: wlan0-1: STA c8:51:42:23:d4:0c RADIUS: starting accounting session D6904079BFEF1D64
Wed Mar  8 09:00:28 2023 daemon.info hostapd: wlan0-1: STA c8:51:42:23:d4:0c WPA: pairwise key handshake completed (RSN)
Wed Mar  8 09:00:28 2023 daemon.notice hostapd: EAPOL-4WAY-HS-COMPLETED c8:51:42:23:d4:0c
Wed Mar  8 09:00:38 2023 daemon.notice hostapd: wlan0-1: BEACON-REQ-TX-STATUS c8:51:42:23:d4:0c 32 ack=1
Wed Mar  8 09:00:54 2023 daemon.notice hostapd: wlan0-1: BEACON-REQ-TX-STATUS c8:51:42:23:d4:0c 33 ack=1
Wed Mar  8 09:00:58 2023 daemon.notice hostapd: wlan0-1: BEACON-REQ-TX-STATUS c8:51:42:23:d4:0c 34 ack=1
Wed Mar  8 09:01:00 2023 cron.err crond[1769]: USER root pid 25360 cmd scp root@192.168.10.1:/tmp/dhcp.leases /tmp/dhcp.leases.new && mv /tmp/dhcp.leases.new /tmp/dhcp.leases
Wed Mar  8 09:01:14 2023 daemon.notice hostapd: wlan0-1: BEACON-REQ-TX-STATUS c8:51:42:23:d4:0c 35 ack=1
1 Like

You can test if 802.11k neighbor report is working by checking to see if the neighbor list is populated:

ubus call hostapd.wlan1 rrm_nr_list (or wlan0, wlan1-1, etc...)

I only use the neighbor report and 802.11r fast transition and both Apple and Android phones FT without issue and I don't have any devices that cannot connect.

I'm using WPA2-PSK, no 802.11w frame protection, KRACK countermeasures off, reassociation deadline 65535, FT over the air, generate PMK locally, and Time interval for rekeying GTK=0

1 Like

Thanks. Couple more questions.

Do you use static-neighbor-report to make that work? If not how do you populate the list? And might static-neighbor-report not be a good idea in your case?

Why not? What's your thinking behind this?

How I'm doing it is I'm populating the list in startup and as a cronjob. static-neighbor-report and other scripts do the same thing for you.

After populating the list, it will remain until a reboot or change in settings where hostapd has to restart. So I just do a check every 5 mins to make sure the list is still populated which is what those scripts do, but you can do it with a one line command.

To get the info from an AP:
ubus call hostapd.wlan1 rrm_nr_get_own (or wlan0, wlan1-1, etc...)

Just put this info into it's neighboring AP - example:

ubus call hostapd.wlan1 rrm_nr_set '{"list": [["e3:44:52:13:c4:96","ssid_name","e3445213c496ef097000110d070603000f00"]]}'

In startup at least for my AP I need a sleep 4 first so hostapd is setup and radios are on.

As for cron, all you need is:

*/5 * * * * [[ "`ubus call hostapd.wlan1 rrm_nr_list`" == *","* ]] ||

before the command above.

Just for me it's just easier for the simplicity and management vs a script or package that is just a one line command.

As for 802.11v I just don't need it as my mobile devices roam fine without issue. I have also read that it can cause issues with 802.11r fast transition which was my main focus. If you have to force disconnect a device then you loose the fast transition and the device has to scan again and then completely re-authenticate to an AP and do the 4-way handshake. This breaks your connection and ruins the experience for the user especially if it's something like wifi calling, video chat, streaming video, etc. that they are on.

1 Like

@_FailSafe how about in this fine thread instead?