[PATCH 4/6] AP: Support deauthenticate/disassociate with MLD
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Mon Dec 25 09:43:01 PST 2023
From: Ilan Peer <ilan.peer at intel.com>
When requested to deauthenticate/disassociate a station
also handle the corresponding MLD stations.
Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
src/ap/sta_info.c | 106 ++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 102 insertions(+), 4 deletions(-)
diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c
index 31fc0cc242..db2e8ca26c 100644
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -875,8 +875,8 @@ static void ap_sta_disconnect_common(struct hostapd_data *hapd,
}
-void ap_sta_disassociate(struct hostapd_data *hapd, struct sta_info *sta,
- u16 reason)
+static void ap_sta_handle_disassociate(struct hostapd_data *hapd,
+ struct sta_info *sta, u16 reason)
{
wpa_printf(MSG_DEBUG, "%s: disassociate STA " MACSTR,
hapd->conf->iface, MAC2STR(sta->addr));
@@ -915,8 +915,8 @@ static void ap_sta_deauth_cb_timeout(void *eloop_ctx, void *timeout_ctx)
}
-void ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta,
- u16 reason)
+static void ap_sta_handle_deauthenticate(struct hostapd_data *hapd,
+ struct sta_info *sta, u16 reason)
{
if (hapd->iface->current_mode &&
hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211AD) {
@@ -943,6 +943,104 @@ void ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta,
}
+static bool ap_sta_ml_disconnect(struct hostapd_data *hapd,
+ struct sta_info *sta, u16 reason,
+ bool disassoc)
+{
+#ifdef CONFIG_IEEE80211BE
+ struct hostapd_data *assoc_hapd, *tmp_hapd;
+ struct sta_info *assoc_sta;
+ u8 i, link_id;
+
+ if (!hostapd_is_mld_ap(hapd))
+ return false;
+
+ /*
+ * Get the station on which the association was performed, as it holds
+ * the information about all the other links
+ */
+ assoc_sta = hostapd_ml_get_assoc_sta(hapd, sta, &assoc_hapd);
+ if (!assoc_sta)
+ return false;
+
+ for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
+ for (i = 0; i < assoc_hapd->iface->interfaces->count; i++) {
+ struct sta_info *tmp_sta;
+
+ if (!assoc_sta->mld_info.links[link_id].valid)
+ continue;
+
+ tmp_hapd =
+ assoc_hapd->iface->interfaces->iface[i]->bss[0];
+
+ if (!tmp_hapd->conf->mld_ap ||
+ assoc_hapd->conf->mld_id != tmp_hapd->conf->mld_id)
+ continue;
+
+ for (tmp_sta = tmp_hapd->sta_list; tmp_sta;
+ tmp_sta = tmp_sta->next) {
+ /*
+ * handle the station on which the association
+ * was done only after all other link station
+ * are removed. Since there is a only a single
+ * station per hapd with the same association
+ * link simply break;
+ */
+ if (tmp_sta == assoc_sta)
+ break;
+
+ if (tmp_sta->mld_assoc_link_id !=
+ assoc_sta->mld_assoc_link_id ||
+ tmp_sta->aid != assoc_sta->aid)
+ continue;
+
+ if (disassoc)
+ ap_sta_handle_disassociate(tmp_hapd,
+ tmp_sta,
+ reason);
+ else
+ ap_sta_handle_deauthenticate(tmp_hapd,
+ tmp_sta,
+ reason);
+
+ break;
+ }
+ }
+ }
+
+ /* disconnect the station on which the association was performed */
+ if (disassoc)
+ ap_sta_handle_disassociate(assoc_hapd, assoc_sta, reason);
+ else
+ ap_sta_handle_deauthenticate(assoc_hapd, assoc_sta, reason);
+
+ return true;
+#else
+ return false;
+#endif /* CONFIG_IEEE80211BE */
+}
+
+
+void ap_sta_disassociate(struct hostapd_data *hapd, struct sta_info *sta,
+ u16 reason)
+{
+ if (ap_sta_ml_disconnect(hapd, sta, reason, true))
+ return;
+
+ ap_sta_handle_disassociate(hapd, sta, reason);
+}
+
+
+void ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta,
+ u16 reason)
+{
+ if (ap_sta_ml_disconnect(hapd, sta, reason, false))
+ return;
+
+ ap_sta_handle_deauthenticate(hapd, sta, reason);
+}
+
+
#ifdef CONFIG_WPS
int ap_sta_wps_cancel(struct hostapd_data *hapd,
struct sta_info *sta, void *ctx)
--
2.43.0
More information about the Hostap
mailing list