WNM: Group rekeying skipping with BSS max idle period management

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>
This commit is contained in:
Jouni Malinen 2024-05-29 12:57:08 +03:00 committed by Jouni Malinen
parent 846b1d618c
commit 6cd0231112
6 changed files with 31 additions and 0 deletions

View 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);

View 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

View 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;

View 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,

View 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. */

View 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;
}