]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Allow MLO disabled connection to legacy open/WPA2-Personal-only AP MLDs
authorVeerendranath Jakkam <quic_vjakkam@quicinc.com>
Thu, 23 Mar 2023 13:33:01 +0000 (19:03 +0530)
committerJouni Malinen <j@w1.fi>
Tue, 25 Apr 2023 14:04:44 +0000 (17:04 +0300)
wpa_supplicant was skipping MLD APs from network selection when the AP
advertise legacy open, WPA2-Personal-only (PSK without SAE), or PMF
disabled. However, there are already some early Wi-Fi 7 APs in the
market which advertise legacy open, WPA2-Personal-only, or PMF disabled
even though these combinations are unlikely to be allowed for Wi-Fi 7 in
the end.

To avoid connectivity issues with such APs, allow stations to connect
with MLO disabled when an AP MLD is detected to advertise legacy open,
WPA2-Personal-only (PSK without SAE), or PMF disabled.

This reverts commit 7d8b96dcfdbb ("wpa_supplicant: Apply same
restrictions for MLD as for 6 GHz BSS") except WEP and TKIP checks,
i.e., AP MLDs which advertise only WEP or TKIP are still skipped from
network selection.

For the SME-in-wpa_supplicant case, skip configuring MLD parameters to
the driver if the STA can connect only in legacy open,
WPA2-Personal-only, or PMF disabled mode. For the SME-in-driver case, it
is the driver's responsibility to initiate connection with MLO disabled
with such APs.

Signed-off-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
wpa_supplicant/events.c
wpa_supplicant/sme.c

index a05dd26a2861cc7bede969467838840180505eb9..2184ea09357297afbe02d2ff4985259affd93450 100644 (file)
@@ -622,8 +622,7 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
 #ifdef CONFIG_WEP
        int wep_ok;
 #endif /* CONFIG_WEP */
-       bool is_6ghz_bss_or_mld = is_6ghz_freq(bss->freq) ||
-               !is_zero_ether_addr(bss->mld_addr);
+       bool is_6ghz_bss = is_6ghz_freq(bss->freq);
 
        ret = wpas_wps_ssid_bss_match(wpa_s, ssid, bss);
        if (ret >= 0)
@@ -638,10 +637,10 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
 #endif /* CONFIG_WEP */
 
        rsn_ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
-       if (is_6ghz_bss_or_mld && !rsn_ie) {
+       if (is_6ghz_bss && !rsn_ie) {
                if (debug_print)
                        wpa_dbg(wpa_s, MSG_DEBUG,
-                               "   skip - 6 GHz/MLD BSS without RSNE");
+                               "   skip - 6 GHz BSS without RSNE");
                return 0;
        }
 
@@ -659,8 +658,8 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
                if (!ie.has_group)
                        ie.group_cipher = wpa_default_rsn_cipher(bss->freq);
 
-               if (is_6ghz_bss_or_mld) {
-                       /* WEP and TKIP are not allowed on 6 GHz */
+               if (is_6ghz_bss || !is_zero_ether_addr(bss->mld_addr)) {
+                       /* WEP and TKIP are not allowed on 6 GHz/MLD */
                        ie.pairwise_cipher &= ~(WPA_CIPHER_WEP40 |
                                                WPA_CIPHER_WEP104 |
                                                WPA_CIPHER_TKIP);
@@ -710,12 +709,12 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
                        break;
                }
 
-               if (is_6ghz_bss_or_mld) {
+               if (is_6ghz_bss) {
                        /* MFPC must be supported on 6 GHz */
                        if (!(ie.capabilities & WPA_CAPABILITY_MFPC)) {
                                if (debug_print)
                                        wpa_dbg(wpa_s, MSG_DEBUG,
-                                               "   skip RSNE - 6 GHz/MLD without MFPC");
+                                               "   skip RSNE - 6 GHz without MFPC");
                                break;
                        }
 
@@ -755,10 +754,10 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
                return 1;
        }
 
-       if (is_6ghz_bss_or_mld) {
+       if (is_6ghz_bss) {
                if (debug_print)
                        wpa_dbg(wpa_s, MSG_DEBUG,
-                               "   skip - 6 GHz/MLD BSS without matching RSNE");
+                               "   skip - 6 GHz BSS without matching RSNE");
                return 0;
        }
 
index 29e0b3b4dce9bf5aca3b9dd1dbdaf25d197a16d6..51bc44246e3a14afc43c8517dc7a232a5ac8a785 100644 (file)
@@ -378,10 +378,12 @@ static void sme_auth_handle_rrm(struct wpa_supplicant *wpa_s,
 }
 
 
-static bool wpas_ml_element(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
+static bool wpas_ml_element(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
+                           struct wpa_ssid *ssid)
 {
        struct wpabuf *mlbuf;
-       const u8 *rnr_ie, *pos;
+       const u8 *rnr_ie, *pos, *rsn_ie;
+       struct wpa_ie_data ie;
        u8 ml_ie_len, rnr_ie_len;
        const struct ieee80211_eht_ml *eht_ml;
        const struct eht_ml_basic_common_info *ml_basic_common_info;
@@ -402,6 +404,26 @@ static bool wpas_ml_element(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
                return false;
        }
 
+       rsn_ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+       if (!rsn_ie || wpa_parse_wpa_ie(rsn_ie, 2 + rsn_ie[1], &ie)) {
+               wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No RSN element");
+               goto out;
+       }
+
+       if (!(ie.capabilities & WPA_CAPABILITY_MFPC) ||
+           wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION) {
+               wpa_dbg(wpa_s, MSG_DEBUG,
+                       "MLD: No management frame protection");
+               goto out;
+       }
+
+       ie.key_mgmt &= ~(WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_PSK |
+                        WPA_KEY_MGMT_PSK_SHA256);
+       if (!(ie.key_mgmt & ssid->key_mgmt)) {
+               wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No valid key management");
+               goto out;
+       }
+
        ml_ie_len = wpabuf_len(mlbuf);
 
        /* control + common info len + MLD address + MLD link information */
@@ -604,7 +626,7 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
        params.ssid_len = bss->ssid_len;
        params.p2p = ssid->p2p_group;
 
-       if (wpas_ml_element(wpa_s, bss)) {
+       if (wpas_ml_element(wpa_s, bss, ssid)) {
                wpa_printf(MSG_DEBUG, "MLD: In authentication");
                params.mld = true;
                params.mld_link_id = wpa_s->mlo_assoc_link_id;