diff mbox series

[RESEND] wpasupplicant: Only advertise MSCS and SCS in association request if supported by bss

Message ID GV0P278MB0830B588A174DDBAEBD2CEE39F659@GV0P278MB0830.CHEP278.PROD.OUTLOOK.COM
State Accepted
Headers show
Series [RESEND] wpasupplicant: Only advertise MSCS and SCS in association request if supported by bss | expand

Commit Message

Sebastian Priebe April 26, 2023, 1:22 p.m. UTC
Since version 2.10 the extended capabilities MSCS and SCS are advertised in the association request.
This causes the association request to be rejected by several access points. Issue was observed with:
- D-Link DIR600
- Tp-Link AC1900
- Synology MR2200ac
To avoid this issue the extended capabilities MSCS and SCS shall only be added if the bss also supports
them.

Note: The extended capabilities are only included in the association request if the bss also sent it's
extended capabilities (see wpas_populate_assoc_ies). This workaround exists since version 2.1.

Signed-off-by: Sebastian Priebe <sebastian.priebe@konplan.com>
---
---
Sebastian Priebe

Comments

Jouni Malinen Nov. 3, 2023, 1:18 p.m. UTC | #1
On Wed, Apr 26, 2023 at 01:22:02PM +0000, Sebastian Priebe wrote:
> Since version 2.10 the extended capabilities MSCS and SCS are advertised in the association request.
> This causes the association request to be rejected by several access points. Issue was observed with:
> - D-Link DIR600
> - Tp-Link AC1900
> - Synology MR2200ac
> To avoid this issue the extended capabilities MSCS and SCS shall only be added if the bss also supports
> them.
> 
> Note: The extended capabilities are only included in the association request if the bss also sent it's
> extended capabilities (see wpas_populate_assoc_ies). This workaround exists since version 2.1.

Thanks, applied.
diff mbox series

Patch

diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index c3984a40c..aad049640 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -615,7 +615,7 @@  void wpa_supplicant_set_default_scan_ies(struct wpa_supplicant *wpa_s)
 	wpa_drv_get_ext_capa(wpa_s, type);
 
 	ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
-					     sizeof(ext_capab));
+					     sizeof(ext_capab), NULL);
 	if (ext_capab_len > 0 &&
 	    wpabuf_resize(&default_ies, ext_capab_len) == 0)
 		wpabuf_put_data(default_ies, ext_capab, ext_capab_len);
@@ -667,7 +667,7 @@  static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s)
 		wpa_drv_get_ext_capa(wpa_s, WPA_IF_STATION);
 
 	ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
-					     sizeof(ext_capab));
+					     sizeof(ext_capab), NULL);
 	if (ext_capab_len > 0 &&
 	    wpabuf_resize(&extra_ie, ext_capab_len) == 0)
 		wpabuf_put_data(extra_ie, ext_capab, ext_capab_len);
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index 51bc44246..ef62ab9df 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -912,7 +912,7 @@  static void sme_send_authentication(struct wpa_supplicant *wpa_s,
 		wpa_drv_get_ext_capa(wpa_s, WPA_IF_STATION);
 
 	ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
-					     sizeof(ext_capab));
+					     sizeof(ext_capab), bss);
 	if (ext_capab_len > 0) {
 		u8 *pos = wpa_s->sme.assoc_req_ie;
 		if (wpa_s->sme.assoc_req_ie_len > 0 && pos[0] == WLAN_EID_RSN)
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 651c0ce9e..ce9d6f742 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -2077,7 +2077,8 @@  int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
 }
 
 
-static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
+static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos,
+			  int idx, struct wpa_bss *bss)
 {
 	bool scs = true, mscs = true;
 
@@ -2128,6 +2129,8 @@  static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
 		if (wpa_s->disable_scs_support)
 			scs = false;
 #endif /* CONFIG_TESTING_OPTIONS */
+		if (bss && !wpa_bss_ext_capab(bss, WLAN_EXT_CAPAB_SCS))
+			scs = false;
 		if (scs)
 			*pos |= 0x40; /* Bit 54 - SCS */
 		break;
@@ -2150,6 +2153,8 @@  static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
 		if (wpa_s->disable_mscs_support)
 			mscs = false;
 #endif /* CONFIG_TESTING_OPTIONS */
+		if (bss && !wpa_bss_ext_capab(bss, WLAN_EXT_CAPAB_MSCS))
+			mscs = false;
 		if (mscs)
 			*pos |= 0x20; /* Bit 85 - Mirrored SCS */
 		break;
@@ -2157,7 +2162,8 @@  static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
 }
 
 
-int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf, size_t buflen)
+int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf,
+			  size_t buflen, struct wpa_bss *bss)
 {
 	u8 *pos = buf;
 	u8 len = 11, i;
@@ -2173,7 +2179,7 @@  int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf, size_t buflen)
 	*pos++ = WLAN_EID_EXT_CAPAB;
 	*pos++ = len;
 	for (i = 0; i < len; i++, pos++) {
-		wpas_ext_capab_byte(wpa_s, pos, i);
+		wpas_ext_capab_byte(wpa_s, pos, i, bss);
 
 		if (i < wpa_s->extended_capa_len) {
 			*pos &= ~wpa_s->extended_capa_mask[i];
@@ -3469,7 +3475,7 @@  static u8 * wpas_populate_assoc_ies(
 		u8 ext_capab[18];
 		int ext_capab_len;
 		ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
-						     sizeof(ext_capab));
+						     sizeof(ext_capab), bss);
 		if (ext_capab_len > 0 &&
 		    wpa_ie_len + ext_capab_len <= max_wpa_ie_len) {
 			u8 *pos = wpa_ie;
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index d5b3dab67..60b17ee3d 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1649,7 +1649,8 @@  int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
 		    size_t ssid_len);
 void wpas_request_connection(struct wpa_supplicant *wpa_s);
 void wpas_request_disconnection(struct wpa_supplicant *wpa_s);
-int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf, size_t buflen);
+int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf,
+			    size_t buflen, struct wpa_bss *bss);
 int wpas_update_random_addr(struct wpa_supplicant *wpa_s, int style,
 			    struct wpa_ssid *ssid);
 int wpas_update_random_addr_disassoc(struct wpa_supplicant *wpa_s);