From: Khanjan Desai Date: Mon, 9 Jun 2025 09:54:13 +0000 (+0530) Subject: Add support to configure URNM_MFPR and URNM_MFPR_X20 (STA) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4f77f503286451916f58062dbe77af0b5d997464;p=thirdparty%2Fhostap.git Add support to configure URNM_MFPR and URNM_MFPR_X20 (STA) Add support for configuring Management Frame Protection flags via control interface commands, specifically targeting use cases defined in IEEE 802.11az. For drivers that set URNM_MFPR (Unassociated Range Negotiation and Measurement Management Frame Protection Required) to true and URNM_MFPR_X20 (20 MHz exemption for URNM_MFPR) to false in the RSNXE this change enables initializing the MFP configuration with relaxed constraints. The new behavior allows setting URNM_MFPR_X20 to true while keeping URNM_MFPR as false, facilitating unassociated ranging and measurement operations over 20 MHz channels without enforcing strict MFP requirements. This provides flexibility for devices operating in bandwidth-constrained environments or requiring adaptive protection policies during initial negotiation. Signed-off-by: Khanjan Desai --- diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index f5319c606..e82421047 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -5045,6 +5045,12 @@ int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param, sm->eapol_2_key_info_set_mask = value; break; #endif /* CONFIG_TESTING_OPTIONS */ + case WPA_PARAM_URNM_MFPR: + sm->prot_range_neg = value; + break; + case WPA_PARAM_URNM_MFPR_X20: + sm->prot_range_neg_x20 = value; + break; #ifdef CONFIG_DPP2 case WPA_PARAM_DPP_PFS: sm->dpp_pfs = value; diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h index 0c360bdea..a33f3679c 100644 --- a/src/rsn_supp/wpa.h +++ b/src/rsn_supp/wpa.h @@ -141,6 +141,8 @@ enum wpa_sm_conf_params { WPA_PARAM_RSN_OVERRIDE_SUPPORT, WPA_PARAM_EAPOL_2_KEY_INFO_SET_MASK, WPA_PARAM_SPP_AMSDU, + WPA_PARAM_URNM_MFPR, + WPA_PARAM_URNM_MFPR_X20, }; enum wpa_rsn_override { diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index 93152687c..4f75e3cd7 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -112,6 +112,7 @@ struct wpa_sm { unsigned int secure_ltf:1; unsigned int secure_rtt:1; unsigned int prot_range_neg:1; + unsigned int prot_range_neg_x20:1; unsigned int ssid_protection:1; unsigned int spp_amsdu:1; diff --git a/src/rsn_supp/wpa_ie.c b/src/rsn_supp/wpa_ie.c index d27bcf905..d00196743 100644 --- a/src/rsn_supp/wpa_ie.c +++ b/src/rsn_supp/wpa_ie.c @@ -320,6 +320,8 @@ int wpa_gen_rsnxe(struct wpa_sm *sm, u8 *rsnxe, size_t rsnxe_len) capab |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT); if (sm->prot_range_neg) capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR); + if (sm->prot_range_neg_x20) + capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR_X20); if (sm->ssid_protection) capab |= BIT(WLAN_RSNX_CAPAB_SSID_PROTECTION); if (sm->spp_amsdu) diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 229595d36..ebcc5d7ee 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -979,6 +979,12 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s, } else if (os_strcasecmp(cmd, "enable_dscp_policy_capa") == 0) { wpa_s->enable_dscp_policy_capa = !!atoi(value); #endif /* CONFIG_NO_ROBUST_AV */ +#ifdef CONFIG_PASN + } else if (os_strcasecmp(cmd, "urnm_mfpr") == 0) { + wpa_s->disable_urnm_mfpr = !atoi(value); + } else if (os_strcasecmp(cmd, "urnm_mfpr_x20") == 0) { + wpa_s->urnm_mfpr_x20 = !!atoi(value); +#endif /* CONFIG_PASN */ } else { value[-1] = '='; ret = wpa_config_process_global(wpa_s->conf, cmd, -1); diff --git a/wpa_supplicant/pasn_supplicant.c b/wpa_supplicant/pasn_supplicant.c index 0158aadf1..fb15d0849 100644 --- a/wpa_supplicant/pasn_supplicant.c +++ b/wpa_supplicant/pasn_supplicant.c @@ -687,8 +687,27 @@ static void wpas_pasn_auth_start_cb(struct wpa_radio_work *work, int deinit) capab |= BIT(WLAN_RSNX_CAPAB_SECURE_LTF); if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_RTT_STA) capab |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT); - if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_PROT_RANGE_NEG_STA) - capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR); + if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_PROT_RANGE_NEG_STA) { + /* + * URNM_MFPR_X20 is a subset of URNM_MFPR which excludes 20 MHz + * bandwidth from mandating protected Management frames. Set + * URNM_MFPR only when URNM_MFPR_X20 is not set. + */ + if (wpa_s->disable_urnm_mfpr) { + wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_URNM_MFPR, 0); + } else { + capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR); + wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_URNM_MFPR, 1); + } + if (wpa_s->urnm_mfpr_x20) { + capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR_X20); + wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_URNM_MFPR_X20, + 1); + } else { + wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_URNM_MFPR_X20, + 0); + } + } if ((wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SPP_AMSDU) && ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SPP_A_MSDU)) capab |= BIT(WLAN_RSNX_CAPAB_SPP_A_MSDU); diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 2f77413d5..e7675a4ab 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1596,6 +1596,8 @@ struct wpa_supplicant { struct wpa_radio_work *pasn_auth_work; unsigned int pasn_count; struct pasn_auth *pasn_params; + bool urnm_mfpr_x20; + bool disable_urnm_mfpr; #ifdef CONFIG_P2P struct wpa_radio_work *p2p_pasn_auth_work; #endif /* CONFIG_P2P */