]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
AP: MLO: Handle association callback
authorIlan Peer <ilan.peer@intel.com>
Mon, 22 May 2023 19:33:47 +0000 (22:33 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 12 Jun 2023 10:12:15 +0000 (13:12 +0300)
Handle association request callback in the context of MLO.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
src/ap/ieee802_11.c

index 5143bd5eed5c03c2d0476d7ef4ae9ed255a78249..9e2aad8a06e00bf9fa74280b2fa4582cf211f0b8 100644 (file)
@@ -6086,6 +6086,90 @@ static void hostapd_set_wds_encryption(struct hostapd_data *hapd,
 }
 
 
+#ifdef CONFIG_IEEE80211BE
+static void ieee80211_ml_link_sta_assoc_cb(struct hostapd_data *hapd,
+                                          struct sta_info *sta,
+                                          struct mld_link_info *link,
+                                          bool ok)
+{
+       if (!ok) {
+               hostapd_logger(hapd, link->peer_addr, HOSTAPD_MODULE_IEEE80211,
+                              HOSTAPD_LEVEL_DEBUG,
+                              "did not acknowledge association response");
+               sta->flags &= ~WLAN_STA_ASSOC_REQ_OK;
+
+               /* The STA is added only in case of SUCCESS */
+               if (link->status == WLAN_STATUS_SUCCESS)
+                       hostapd_drv_sta_remove(hapd, sta->addr);
+
+               return;
+       }
+
+       if (link->status != WLAN_STATUS_SUCCESS)
+               return;
+
+       sta->flags |= WLAN_STA_ASSOC;
+       sta->flags &= ~WLAN_STA_WNM_SLEEP_MODE;
+
+       if (!hapd->conf->ieee802_1x && !hapd->conf->wpa)
+               ap_sta_set_authorized(hapd, sta, 1);
+
+       hostapd_set_sta_flags(hapd, sta);
+
+       /*
+        * TODOs:
+        * - IEEE 802.1X port enablement is not needed as done on the station
+        *     doing the connection.
+        * - Not handling accounting
+        * - Need to handle VLAN configuration
+        */
+}
+#endif /* CONFIG_IEEE80211BE */
+
+
+static void hostapd_ml_handle_assoc_cb(struct hostapd_data *hapd,
+                                      struct sta_info *sta, bool ok)
+{
+#ifdef CONFIG_IEEE80211BE
+       unsigned int i, link_id;
+
+       if (!hostapd_is_mld_ap(hapd))
+               return;
+
+       for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
+               struct mld_link_info *link = &sta->mld_info.links[link_id];
+
+               if (!link->valid)
+                       continue;
+
+               for (i = 0; i < hapd->iface->interfaces->count; i++) {
+                       struct sta_info *tmp_sta;
+                       struct hostapd_data *tmp_hapd =
+                               hapd->iface->interfaces->iface[i]->bss[0];
+
+                       if (tmp_hapd->conf->mld_ap ||
+                           hapd->conf->mld_id != tmp_hapd->conf->mld_id)
+                               continue;
+
+                       for (tmp_sta = tmp_hapd->sta_list; tmp_sta;
+                            tmp_sta = tmp_sta->next) {
+                               if (tmp_sta == sta ||
+                                   tmp_sta->mld_assoc_link_id !=
+                                   sta->mld_assoc_link_id ||
+                                   tmp_sta->aid != sta->aid)
+                                       continue;
+
+                               ieee80211_ml_link_sta_assoc_cb(tmp_hapd,
+                                                              tmp_sta, link,
+                                                              ok);
+                               break;
+                       }
+               }
+       }
+#endif /* CONFIG_IEEE80211BE */
+}
+
+
 static void handle_assoc_cb(struct hostapd_data *hapd,
                            const struct ieee80211_mgmt *mgmt,
                            size_t len, int reassoc, int ok)
@@ -6101,6 +6185,17 @@ static void handle_assoc_cb(struct hostapd_data *hapd,
                return;
        }
 
+#ifdef CONFIG_IEEE80211BE
+       if (hapd->conf->mld_ap && sta->mld_info.mld_sta &&
+           hapd->mld_link_id != sta->mld_assoc_link_id) {
+               /* See ieee80211_ml_link_sta_assoc_cb() for the MLD case */
+               wpa_printf(MSG_DEBUG,
+                          "%s: MLD: ignore on link station (%d != %d)",
+                          __func__, hapd->mld_link_id, sta->mld_assoc_link_id);
+               return;
+       }
+#endif /* CONFIG_IEEE80211BE */
+
        if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_resp) :
                                      sizeof(mgmt->u.assoc_resp))) {
                wpa_printf(MSG_INFO,
@@ -6124,11 +6219,11 @@ static void handle_assoc_cb(struct hostapd_data *hapd,
                if (status == WLAN_STATUS_SUCCESS)
                        hostapd_drv_sta_remove(hapd, sta->addr);
 
-               return;
+               goto handle_ml;
        }
 
        if (status != WLAN_STATUS_SUCCESS)
-               return;
+               goto handle_ml;
 
        /* Stop previous accounting session, if one is started, and allocate
         * new session id for the new session. */
@@ -6170,11 +6265,11 @@ static void handle_assoc_cb(struct hostapd_data *hapd,
                 * interface selection is not going to change anymore.
                 */
                if (ap_sta_bind_vlan(hapd, sta) < 0)
-                       return;
+                       goto handle_ml;
        } else if (sta->vlan_id) {
                /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
                if (ap_sta_bind_vlan(hapd, sta) < 0)
-                       return;
+                       goto handle_ml;
        }
 
        hostapd_set_sta_flags(hapd, sta);
@@ -6242,6 +6337,9 @@ static void handle_assoc_cb(struct hostapd_data *hapd,
                os_free(sta->pending_eapol_rx);
                sta->pending_eapol_rx = NULL;
        }
+
+handle_ml:
+       hostapd_ml_handle_assoc_cb(hapd, sta, ok);
 }