]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Add support to configure URNM_MFPR and URNM_MFPR_X20 (STA)
authorKhanjan Desai <khanjan@qti.qualcomm.com>
Mon, 9 Jun 2025 09:54:13 +0000 (15:24 +0530)
committerJouni Malinen <j@w1.fi>
Wed, 24 Sep 2025 10:08:32 +0000 (13:08 +0300)
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 <khanjan@qti.qualcomm.com>
src/rsn_supp/wpa.c
src/rsn_supp/wpa.h
src/rsn_supp/wpa_i.h
src/rsn_supp/wpa_ie.c
wpa_supplicant/ctrl_iface.c
wpa_supplicant/pasn_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index f5319c606f0b7fda472d898eda09d0221f7cb4e7..e82421047fc24ae242c27ca462fab9bfd55d3522 100644 (file)
@@ -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;
index 0c360bdeae6cb452d2a7f0d0b91c90c2cb17969d..a33f3679c95942ceb7dd73cfcdea23082bfef2a1 100644 (file)
@@ -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 {
index 93152687c2937d1e2976f76068dfb856df624c37..4f75e3cd7c187ea5178488b053fd81869860cb1c 100644 (file)
@@ -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;
 
index d27bcf905da5b03ac3bbc749c803e18dc8788e00..d00196743ef153955e801fb510e94881fafdb049 100644 (file)
@@ -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)
index 229595d36cb65b008242e28f7c621c79104ff291..ebcc5d7ee4d2864703d0ecaadc1994a63593a20b 100644 (file)
@@ -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);
index 0158aadf1b68f7e2dbb21e7bc850ac5e2434b8a9..fb15d084917f1a613bba3306a04386ded6714b90 100644 (file)
@@ -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);
index 2f77413d5798a71bfea20574e277e2b43b69cbd8..e7675a4abe0a354789e1a8902b33aa570f347b6c 100644 (file)
@@ -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 */