]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WNM: Group rekeying skipping with BSS max idle period management
authorJouni Malinen <quic_jouni@quicinc.com>
Wed, 29 May 2024 09:57:08 +0000 (12:57 +0300)
committerJouni Malinen <j@w1.fi>
Wed, 29 May 2024 09:57:08 +0000 (12:57 +0300)
Allow hostapd to be configured to not disconnect a STA if the STA fails
to reply to a group key handshake when BSS max idle period management is
used. This might be needed for some STAs that use aggressive power
saving (e.g., battery powered IoT devices).

This is disabled by default since this can delayed group rekeying
slightly and also to maintain the previous behavior. The more relaxed
operation can be enabled with the new configuration parameter
no_disconnect_on_group_keyerror=1.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
hostapd/config_file.c
hostapd/hostapd.conf
src/ap/ap_config.h
src/ap/wpa_auth.c
src/ap/wpa_auth.h
src/ap/wpa_auth_glue.c

index 5999f40dd8c377426bb2360e8b5da41b72964285..5c091fcd22dd446cac6fa7a3008aac4004a40757 100644 (file)
@@ -2558,6 +2558,16 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                        return 1;
                }
                bss->bss_max_idle = val;
+       } else if (os_strcmp(buf, "no_disconnect_on_group_keyerror") == 0) {
+               int val = atoi(pos);
+
+               if (val < 0 || val > 1) {
+                       wpa_printf(MSG_ERROR,
+                                  "Line %d: Invalid no_disconnect_on_group_keyerror",
+                                  line);
+                       return 1;
+               }
+               bss->no_disconnect_on_group_keyerror = val;
        } else if (os_strcmp(buf, "config_id") == 0) {
                os_free(bss->config_id);
                bss->config_id = os_strdup(pos);
index c6d279c2f36dcf7a0e80a7c99fb71fa94931d134..be92db7a3c8bb09e17539df7f62713bcd21425b4 100644 (file)
@@ -529,6 +529,13 @@ wmm_ac_vo_acm=0
 # 2 = enabled requiring protected frames (advertise and manage BSS max idle
 #     period and require STAs to use protected keep-alive frames)
 #bss_max_idle=1
+#
+# Allow STA to skip group key handshake without getting disconnection when
+# BSS max idle period management is enabled.
+# 0 = disconnect STA if it does not reply to group key handshake (default)
+# 1 = do not disconnect STA if it does not reply to group key handshake and
+#     if BSS max idle period management is enabled
+#no_disconnect_on_group_keyerror=0
 
 # Disassociate stations based on excessive transmission failures or other
 # indications of connection loss. This depends on the driver capabilities and
index 7fd638ea135255a177e120442430fd42d80b6145..8daea416d0b555c64fd1fd170042720ca877e376 100644 (file)
@@ -466,6 +466,7 @@ struct hostapd_bss_config {
 
        int ap_max_inactivity;
        int bss_max_idle;
+       bool no_disconnect_on_group_keyerror;
        int ignore_broadcast_ssid;
        int no_probe_resp_if_max_sta;
 
index 8304c6047b1c7823690b5df548c559336dfb2397..08260c4b32efbe3c2655887834e6ddf59e534510 100644 (file)
@@ -5308,6 +5308,14 @@ SM_STATE(WPA_PTK_GROUP, KEYERROR)
        SM_ENTRY_MA(WPA_PTK_GROUP, KEYERROR, wpa_ptk_group);
        if (sm->GUpdateStationKeys)
                wpa_gkeydone_sta(sm);
+       if (sm->wpa_auth->conf.no_disconnect_on_group_keyerror &&
+           sm->wpa == WPA_VERSION_WPA2) {
+               wpa_auth_vlogger(sm->wpa_auth, wpa_auth_get_spa(sm),
+                                LOGGER_DEBUG,
+                                "group key handshake failed after %u tries - allow STA to remain connected",
+                                sm->wpa_auth->conf.wpa_group_update_count);
+               return;
+       }
        sm->Disconnect = true;
        sm->disconnect_reason = WLAN_REASON_GROUP_KEY_UPDATE_TIMEOUT;
        wpa_auth_vlogger(sm->wpa_auth, wpa_auth_get_spa(sm), LOGGER_INFO,
index ed0442c189e239760dcd7199814a23fa578cff84..89bc5e7f2d62a6b1421bd871981a72ddd984e207 100644 (file)
@@ -281,6 +281,8 @@ struct wpa_auth_config {
 
        bool radius_psk;
 
+       bool no_disconnect_on_group_keyerror;
+
        /* Pointer to Multi-BSSID transmitted BSS authenticator instance.
         * Set only in nontransmitted BSSs, i.e., is NULL for transmitted BSS
         * and in BSSs that are not part of a Multi-BSSID set. */
index bbfb5b42f656a6fe1316e303028b229158003c52..9f84510046132bc70df46320b4742d76ccc6733d 100644 (file)
@@ -224,6 +224,9 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
 #endif /* CONFIG_PASN */
 
        wconf->radius_psk = conf->wpa_psk_radius == PSK_RADIUS_DURING_4WAY_HS;
+       wconf->no_disconnect_on_group_keyerror =
+               conf->bss_max_idle && conf->ap_max_inactivity &&
+               conf->no_disconnect_on_group_keyerror;
 }