]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
AP: Do not prune station when adding a link station
authorIlan Peer <ilan.peer@intel.com>
Mon, 22 May 2023 19:33:51 +0000 (22:33 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 12 Jun 2023 13:26:56 +0000 (16:26 +0300)
As otherwise the original station would be pruned.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
src/ap/hostapd.c
src/ap/hostapd.h
src/ap/sta_info.c
src/ap/utils.c

index 0f6574f5d5b87af9628087088809959af86346ba..a8ba207de9362ddef9b5c7a113ae597b42633e31 100644 (file)
@@ -3534,6 +3534,12 @@ void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
                return;
        }
 
+#ifdef CONFIG_IEEE80211BE
+       if (hapd->conf->mld_ap && sta->mld_info.mld_sta &&
+           sta->mld_assoc_link_id != hapd->mld_link_id)
+               return;
+#endif /* CONFIG_IEEE80211BE */
+
        ap_sta_clear_disconnect_timeouts(hapd, sta);
        sta->post_csa_sa_query = 0;
 
index d721d15b5ac32732ab5d9a16080ada55ab11805b..6e0ce3dea697a3da911d6377a3ceff096179992a 100644 (file)
@@ -723,7 +723,8 @@ int hostapd_register_probereq_cb(struct hostapd_data *hapd,
                                           const u8 *ie, size_t ie_len,
                                           int ssi_signal),
                                 void *ctx);
-void hostapd_prune_associations(struct hostapd_data *hapd, const u8 *addr);
+void hostapd_prune_associations(struct hostapd_data *hapd, const u8 *addr,
+                               int mld_assoc_link_id);
 
 /* drv_callbacks.c (TODO: move to somewhere else?) */
 void hostapd_notify_assoc_fils_finish(struct hostapd_data *hapd,
index 01d73cf1494c6935a6ce081895bd40c72a62244e..cf527e63984203664a520af22c7ddf922da873c5 100644 (file)
@@ -1299,7 +1299,19 @@ void ap_sta_set_authorized(struct hostapd_data *hapd, struct sta_info *sta,
                return;
 
        if (authorized) {
-               hostapd_prune_associations(hapd, sta->addr);
+               int mld_assoc_link_id = -1;
+
+#ifdef CONFIG_IEEE80211BE
+               if (hapd->conf->mld_ap && sta->mld_info.mld_sta) {
+                       if (sta->mld_assoc_link_id == hapd->mld_link_id)
+                               mld_assoc_link_id = sta->mld_assoc_link_id;
+                       else
+                               mld_assoc_link_id = -2;
+               }
+#endif /* CONFIG_IEEE80211BE */
+               if (mld_assoc_link_id != -2)
+                       hostapd_prune_associations(hapd, sta->addr,
+                                                  mld_assoc_link_id);
                sta->flags |= WLAN_STA_AUTHORIZED;
        } else {
                sta->flags &= ~WLAN_STA_AUTHORIZED;
index bedad6eb02f7bfda2b421ad4591e0edd6438b09a..e93e53171cda47731016e7ecb72273ddf15ecee0 100644 (file)
@@ -43,6 +43,7 @@ int hostapd_register_probereq_cb(struct hostapd_data *hapd,
 struct prune_data {
        struct hostapd_data *hapd;
        const u8 *addr;
+       int mld_assoc_link_id;
 };
 
 static int prune_associations(struct hostapd_iface *iface, void *ctx)
@@ -72,6 +73,12 @@ static int prune_associations(struct hostapd_iface *iface, void *ctx)
                if (!osta)
                        continue;
 
+#ifdef CONFIG_IEEE80211BE
+               if (data->mld_assoc_link_id >= 0 &&
+                   osta->mld_assoc_link_id == data->mld_assoc_link_id)
+                       continue;
+#endif /* CONFIG_IEEE80211BE */
+
                wpa_printf(MSG_INFO, "%s: Prune association for " MACSTR,
                           ohapd->conf->iface, MAC2STR(osta->addr));
                ap_sta_disassociate(ohapd, osta, WLAN_REASON_UNSPECIFIED);
@@ -84,15 +91,20 @@ static int prune_associations(struct hostapd_iface *iface, void *ctx)
  * hostapd_prune_associations - Remove extraneous associations
  * @hapd: Pointer to BSS data for the most recent association
  * @addr: Associated STA address
+ * @mld_assoc_link_id: MLD link id used for association or -1 for non MLO
  *
  * This function looks through all radios and BSS's for previous
  * (stale) associations of STA. If any are found they are removed.
  */
-void hostapd_prune_associations(struct hostapd_data *hapd, const u8 *addr)
+void hostapd_prune_associations(struct hostapd_data *hapd, const u8 *addr,
+                               int mld_assoc_link_id)
 {
        struct prune_data data;
+
        data.hapd = hapd;
        data.addr = addr;
+       data.mld_assoc_link_id = mld_assoc_link_id;
+
        if (hapd->iface->interfaces &&
            hapd->iface->interfaces->for_each_interface)
                hapd->iface->interfaces->for_each_interface(