Allow MLO disabled connection to legacy open/WPA2-Personal-only AP MLDs

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 7d8b96dcfd ("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>
This commit is contained in:
Veerendranath Jakkam 2023-03-23 19:03:01 +05:30 committed by Jouni Malinen
parent b9c3b57a99
commit 8bc84fceeb
2 changed files with 34 additions and 13 deletions

View file

@ -622,8 +622,7 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
#ifdef CONFIG_WEP #ifdef CONFIG_WEP
int wep_ok; int wep_ok;
#endif /* CONFIG_WEP */ #endif /* CONFIG_WEP */
bool is_6ghz_bss_or_mld = is_6ghz_freq(bss->freq) || bool is_6ghz_bss = is_6ghz_freq(bss->freq);
!is_zero_ether_addr(bss->mld_addr);
ret = wpas_wps_ssid_bss_match(wpa_s, ssid, bss); ret = wpas_wps_ssid_bss_match(wpa_s, ssid, bss);
if (ret >= 0) if (ret >= 0)
@ -638,10 +637,10 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
#endif /* CONFIG_WEP */ #endif /* CONFIG_WEP */
rsn_ie = wpa_bss_get_ie(bss, WLAN_EID_RSN); 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) if (debug_print)
wpa_dbg(wpa_s, MSG_DEBUG, wpa_dbg(wpa_s, MSG_DEBUG,
" skip - 6 GHz/MLD BSS without RSNE"); " skip - 6 GHz BSS without RSNE");
return 0; return 0;
} }
@ -659,8 +658,8 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
if (!ie.has_group) if (!ie.has_group)
ie.group_cipher = wpa_default_rsn_cipher(bss->freq); ie.group_cipher = wpa_default_rsn_cipher(bss->freq);
if (is_6ghz_bss_or_mld) { if (is_6ghz_bss || !is_zero_ether_addr(bss->mld_addr)) {
/* WEP and TKIP are not allowed on 6 GHz */ /* WEP and TKIP are not allowed on 6 GHz/MLD */
ie.pairwise_cipher &= ~(WPA_CIPHER_WEP40 | ie.pairwise_cipher &= ~(WPA_CIPHER_WEP40 |
WPA_CIPHER_WEP104 | WPA_CIPHER_WEP104 |
WPA_CIPHER_TKIP); WPA_CIPHER_TKIP);
@ -710,12 +709,12 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
break; break;
} }
if (is_6ghz_bss_or_mld) { if (is_6ghz_bss) {
/* MFPC must be supported on 6 GHz */ /* MFPC must be supported on 6 GHz */
if (!(ie.capabilities & WPA_CAPABILITY_MFPC)) { if (!(ie.capabilities & WPA_CAPABILITY_MFPC)) {
if (debug_print) if (debug_print)
wpa_dbg(wpa_s, MSG_DEBUG, wpa_dbg(wpa_s, MSG_DEBUG,
" skip RSNE - 6 GHz/MLD without MFPC"); " skip RSNE - 6 GHz without MFPC");
break; break;
} }
@ -755,10 +754,10 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
return 1; return 1;
} }
if (is_6ghz_bss_or_mld) { if (is_6ghz_bss) {
if (debug_print) if (debug_print)
wpa_dbg(wpa_s, MSG_DEBUG, wpa_dbg(wpa_s, MSG_DEBUG,
" skip - 6 GHz/MLD BSS without matching RSNE"); " skip - 6 GHz BSS without matching RSNE");
return 0; return 0;
} }

View 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; 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; u8 ml_ie_len, rnr_ie_len;
const struct ieee80211_eht_ml *eht_ml; const struct ieee80211_eht_ml *eht_ml;
const struct eht_ml_basic_common_info *ml_basic_common_info; 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; 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); ml_ie_len = wpabuf_len(mlbuf);
/* control + common info len + MLD address + MLD link information */ /* 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.ssid_len = bss->ssid_len;
params.p2p = ssid->p2p_group; 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"); wpa_printf(MSG_DEBUG, "MLD: In authentication");
params.mld = true; params.mld = true;
params.mld_link_id = wpa_s->mlo_assoc_link_id; params.mld_link_id = wpa_s->mlo_assoc_link_id;