[PATCH v2] AP MLD: Replace own stale link STA on a retried association

John Macias dencity7 at gmail.com
Wed Oct 21 22:35:22 PDT 2026


When a non-AP MLD retries its (Re)Association Request, for example
because the earlier Association Response accepting a partner link was
never delivered, ieee80211_ml_process_link() finds the link STA that the
previous attempt created on the partner link. It then rejects that link
with "MLD: link: Station already exists" and the non-AP MLD ends up
associated on fewer links than it requested.

If the existing entry is this MLD's own link STA (same association link
and the same wpa_sm as the origin STA), free it and set up the link
again. ap_free_sta() on such a link STA only removes the driver link
STA and releases the link auth reference; it does not deinit the shared
state machine. Any other existing STA is still rejected.

Seen on a GL.iNet GL-BE3600 (ath12k, 2.4 GHz + 5 GHz AP MLD) where the
first two-link Association Response was not acknowledged: without this
change the retry was accepted on one link only; with it, hostapd
accepts both links again on the retry. (In that setup the retried
two-link response was not acknowledged either; that part is a
driver/firmware issue and is reported separately.)

Assisted-by: LLM
Signed-off-by: John Macias <dencity7 at gmail.com>
---
v2: add missing Signed-off-by; no code changes.

 src/ap/ieee802_11.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index ecaf977..e80b7ea 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -7780,6 +7780,23 @@ int ieee80211_ml_process_link(struct hostapd_data *hapd,
 	}
 
 	sta = ap_get_sta(hapd, origin_sta->addr);
+	if (sta && ap_sta_is_mld(hapd, sta) &&
+	    hostapd_sta_is_link_sta(hapd, sta) &&
+	    sta->mld_assoc_link_id == origin_sta->mld_assoc_link_id &&
+	    sta->wpa_sm && sta->wpa_sm == origin_sta->wpa_sm) {
+		/*
+		 * A retried association from the same non-AP MLD finds the
+		 * link station that the previous attempt created on this link
+		 * (for example when the earlier Association Response was not
+		 * delivered). It shares the association link's state machine,
+		 * so drop only this link station and set it up again instead
+		 * of rejecting the link.
+		 */
+		wpa_printf(MSG_INFO,
+			   "MLD: link: Replacing link station from a previous association attempt");
+		ap_free_sta(hapd, sta);
+		sta = NULL;
+	}
 	if (sta || TEST_FAIL()) {
 		wpa_printf(MSG_INFO, "MLD: link: Station already exists");
 		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
-- 
2.47.3




More information about the Hostap mailing list