diff mbox series

wifi: mac80211: Skip association timeout update after comeback rejection

Message ID 20231219174814.2581575-1-j@w1.fi
State New
Headers show
Series wifi: mac80211: Skip association timeout update after comeback rejection | expand

Commit Message

Jouni Malinen Dec. 19, 2023, 5:48 p.m. UTC
From: Jouni Malinen <quic_jouni@quicinc.com>

It is possible for the TX status report for the (Re)Association Request
frame to be delayed long enough for the AP's (Re)Association Response
frame to be received and processed before it. If that were to happen for
a case where the AP rejects the association with indication to come back
later, the association timeout and retry state should not be modified
anymore with the TX status information that would be processed after
this. Updating the association timeout in such a reverse order of events
could result in shortening the timeouts for the association comeback
mechanism and that could result in the association failing.

Track whether we have already processed association rejection with
comeback time and if so, skip the timeout and retry update on any
following TX status report.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
---
 net/mac80211/ieee80211_i.h |  1 +
 net/mac80211/mlme.c        | 11 +++++++++++
 2 files changed, 12 insertions(+)
diff mbox series

Patch

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index cd483787f795..32b7d3f6b4b4 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -439,6 +439,7 @@  struct ieee80211_mgd_assoc_data {
 	bool need_beacon;
 	bool synced;
 	bool timeout_started;
+	bool comeback; /* whether the AP has requested association comeback */
 	bool s1g;
 
 	unsigned int assoc_link_id;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index a693ca2cf8cd..0c7ce022d2ed 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -5381,6 +5381,7 @@  static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
 			   assoc_data->ap_addr, tu, ms);
 		assoc_data->timeout = jiffies + msecs_to_jiffies(ms);
 		assoc_data->timeout_started = true;
+		assoc_data->comeback = true;
 		if (ms > IEEE80211_ASSOC_TIMEOUT)
 			run_again(sdata, assoc_data->timeout);
 		goto notify_driver;
@@ -6718,8 +6719,18 @@  void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
 			}
 			ifmgd->auth_data->timeout_started = true;
 		} else if (ifmgd->assoc_data &&
+			   !ifmgd->assoc_data->comeback &&
 			   (ieee80211_is_assoc_req(fc) ||
 			    ieee80211_is_reassoc_req(fc))) {
+			/*
+			 * Update association timeout based on the TX status
+			 * for the (Re)Association Request frame. Skip this if
+			 * we have already processed a (Re)Association Response
+			 * frame that indicated need for association comeback
+			 * at a specific time in the future. This could happen
+			 * if the TX status information is delayed enough for
+			 * the response to be received and processed first.
+			 */
 			if (status_acked) {
 				ifmgd->assoc_data->timeout =
 					jiffies + IEEE80211_ASSOC_TIMEOUT_SHORT;