diff mbox series

[wireless,4/8] wifi: mac80211: mlme: re-parse if AP mode is less than client

Message ID 20240418105220.d1f25d92cfe7.Ia21eff6cdcae2f5aca13cf8e742a986af5e70f89@changeid (mailing list archive)
State Accepted
Delegated to: Johannes Berg
Headers show
Series [wireless,1/8] wifi: mac80211: fix idle calculation with multi-link | expand

Commit Message

Johannes Berg April 18, 2024, 8:52 a.m. UTC
From: Johannes Berg <johannes.berg@intel.com>

If the AP mode ends up being determined less than the client mode,
there may be different reasons for this, e.g. AP misconfiguration.
If this happens in a way that causes e.g. EHT to be rejected, the
elements need to be re-parsed since we'll connect as HE, but not
reparsing means that we'll still think it's OK to use multi-link,
so we can connect in a non-sensical configuration of advertising
only HE on a secondary link. This normally won't happen for the
assoc link because that reuses the mode from authentication, and
if that's not EHT, multi-link association is rejected.

Fix this inconsistency by parsing the elements again if the mode
was different from the first parsing attempt. Print the message a
bit later to avoid printing "determined AP ... to be HE" twice in
cases where ieee80211_determine_ap_chan() returned a lesser mode,
rather than the regulatory downgrades below changing it.

Fixes: 310c8387c638 ("wifi: mac80211: clean up connection process")
Reviewed-by: Miriam Rachel Korenblit <miriam.rachel.korenblit@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/mac80211/mlme.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 6fa3752b740e..502c34d52fbe 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -632,15 +632,21 @@  ieee80211_determine_chan_mode(struct ieee80211_sub_if_data *sdata,
 	ap_mode = ieee80211_determine_ap_chan(sdata, channel, bss->vht_cap_info,
 					      elems, false, conn, &ap_chandef);
 
-	mlme_link_id_dbg(sdata, link_id, "determined AP %pM to be %s\n",
-			 cbss->bssid, ieee80211_conn_mode_str(ap_mode));
-
 	/* this should be impossible since parsing depends on our mode */
 	if (WARN_ON(ap_mode > conn->mode)) {
 		ret = -EINVAL;
 		goto free;
 	}
 
+	if (conn->mode != ap_mode) {
+		conn->mode = ap_mode;
+		kfree(elems);
+		goto again;
+	}
+
+	mlme_link_id_dbg(sdata, link_id, "determined AP %pM to be %s\n",
+			 cbss->bssid, ieee80211_conn_mode_str(ap_mode));
+
 	sband = sdata->local->hw.wiphy->bands[channel->band];
 
 	switch (channel->band) {
@@ -691,7 +697,6 @@  ieee80211_determine_chan_mode(struct ieee80211_sub_if_data *sdata,
 		break;
 	}
 
-	conn->mode = ap_mode;
 	chanreq->oper = ap_chandef;
 
 	/* wider-bandwidth OFDMA is only done in EHT */