]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
MLO: Store MLO link information in RSN Authentication
authorAndrei Otcheretianski <andrei.otcheretianski@intel.com>
Mon, 22 May 2023 19:33:59 +0000 (22:33 +0300)
committerJouni Malinen <j@w1.fi>
Wed, 14 Jun 2023 08:34:07 +0000 (11:34 +0300)
Make the MLO related information available for the RSN Authenticator
state machine to be able to perform steps needed on an AP MLD. The
actual use of this information will be in the following commits.

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

index c51742b58f8e3f2e74366974b14f5f05fc199ac6..8fb40dcbe7fa2706259ce144f856033f4098ca23 100644 (file)
@@ -3970,15 +3970,34 @@ static int __check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
 
                wpa_ie -= 2;
                wpa_ie_len += 2;
-               if (sta->wpa_sm == NULL)
+
+               if (!sta->wpa_sm) {
+#ifdef CONFIG_IEEE80211BE
+                       struct mld_info *info = &sta->mld_info;
+#endif /* CONFIG_IEEE80211BE */
+
                        sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
                                                        sta->addr,
                                                        p2p_dev_addr);
-               if (sta->wpa_sm == NULL) {
-                       wpa_printf(MSG_WARNING, "Failed to initialize WPA "
-                                  "state machine");
-                       return WLAN_STATUS_UNSPECIFIED_FAILURE;
+
+                       if (!sta->wpa_sm) {
+                               wpa_printf(MSG_WARNING,
+                                          "Failed to initialize RSN state machine");
+                               return WLAN_STATUS_UNSPECIFIED_FAILURE;
+                       }
+
+#ifdef CONFIG_IEEE80211BE
+                       if (info->mld_sta) {
+                               wpa_printf(MSG_DEBUG,
+                                          "MLD: Set ML info in RSN Authenticator");
+                               wpa_auth_set_ml_info(sta->wpa_sm,
+                                                    hapd->mld_addr,
+                                                    sta->mld_assoc_link_id,
+                                                    info);
+                       }
+#endif /* CONFIG_IEEE80211BE */
                }
+
                wpa_auth_set_auth_alg(sta->wpa_sm, sta->auth_alg);
                res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
                                          hapd->iface->freq,
index 12b49704b90a887bd9ce60590aa1eecf15122d98..a9c23b809b4a4c84c2a667db18325256dba63345 100644 (file)
@@ -29,6 +29,7 @@
 #include "drivers/driver.h"
 #include "ap_config.h"
 #include "ieee802_11.h"
+#include "sta_info.h"
 #include "wpa_auth.h"
 #include "pmksa_cache_auth.h"
 #include "wpa_auth_i.h"
@@ -695,6 +696,9 @@ wpa_auth_sta_init(struct wpa_authenticator *wpa_auth, const u8 *addr,
        sm->wpa_auth = wpa_auth;
        sm->group = wpa_auth->group;
        wpa_group_get(sm->wpa_auth, sm->group);
+#ifdef CONFIG_IEEE80211BE
+       sm->mld_assoc_link_id = -1;
+#endif /* CONFIG_IEEE80211BE */
 
        return sm;
 }
@@ -3590,6 +3594,31 @@ static u8 * replace_ie(const char *name, const u8 *old_buf, size_t *len, u8 eid,
 #endif /* CONFIG_TESTING_OPTIONS */
 
 
+#ifdef CONFIG_IEEE80211BE
+
+void wpa_auth_ml_get_rsn_info(struct wpa_authenticator *a,
+                             struct wpa_auth_ml_link_rsn_info *info)
+{
+       info->rsn_ies = a->wpa_ie;
+       info->rsn_ies_len = a->wpa_ie_len;
+
+       wpa_printf(MSG_DEBUG, "RSN: MLD: link_id=%u, rsn_ies_len=%zu",
+                  info->link_id, info->rsn_ies_len);
+}
+
+
+static void wpa_auth_get_ml_rsn_info(struct wpa_authenticator *wpa_auth,
+                                    struct wpa_auth_ml_rsn_info *info)
+{
+       if (!wpa_auth->cb->get_ml_rsn_info)
+               return;
+
+       wpa_auth->cb->get_ml_rsn_info(wpa_auth->cb_ctx, info);
+}
+
+#endif /* CONFIG_IEEE80211BE */
+
+
 SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
 {
        u8 rsc[WPA_KEY_RSC_LEN], *_rsc, *gtk, *kde = NULL, *pos, stub_gtk[32];
@@ -6026,3 +6055,81 @@ void wpa_auth_sta_radius_psk_resp(struct wpa_state_machine *sm, bool success)
 
        eloop_register_timeout(0, 0, wpa_sm_call_step, sm, NULL);
 }
+
+
+void wpa_auth_set_ml_info(struct wpa_state_machine *sm, const u8 *mld_addr,
+                         u8 mld_assoc_link_id, struct mld_info *info)
+{
+#ifdef CONFIG_IEEE80211BE
+       struct wpa_auth_ml_rsn_info ml_rsn_info;
+       unsigned int link_id, i;
+
+       if (!info)
+               return;
+
+       os_memset(sm->mld_links, 0, sizeof(sm->mld_links));
+
+       wpa_auth_logger(sm->wpa_auth, wpa_auth_get_spa(sm), LOGGER_DEBUG,
+                       "MLD: Initialization");
+
+       os_memcpy(sm->own_mld_addr, mld_addr, ETH_ALEN);
+       os_memcpy(sm->peer_mld_addr, info->common_info.mld_addr, ETH_ALEN);
+
+       sm->mld_assoc_link_id = mld_assoc_link_id;
+
+       os_memset(&ml_rsn_info, 0, sizeof(ml_rsn_info));
+
+       for (i = 0, link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
+               struct mld_link_info *link = &info->links[link_id];
+               struct mld_link *sm_link = &sm->mld_links[link_id];
+
+               sm_link->valid = link->valid;
+               if (!link->valid)
+                       continue;
+
+               os_memcpy(sm_link->peer_addr, link->peer_addr, ETH_ALEN);
+               os_memcpy(sm_link->own_addr, link->local_addr, ETH_ALEN);
+
+               wpa_printf(MSG_DEBUG,
+                          "WPA_AUTH: MLD: id=%u, addr=" MACSTR " peer=" MACSTR,
+                          link_id,
+                          MAC2STR(sm_link->own_addr),
+                          MAC2STR(sm_link->peer_addr));
+
+               if (link_id != mld_assoc_link_id)
+                       sm->n_mld_affiliated_links++;
+
+               ml_rsn_info.links[i++].link_id = link_id;
+       }
+
+       ml_rsn_info.n_mld_links = i;
+
+       wpa_auth_get_ml_rsn_info(sm->wpa_auth, &ml_rsn_info);
+
+       for (i = 0; i < ml_rsn_info.n_mld_links; i++) {
+               struct mld_link *sm_link;
+               const u8 *rsn_ies;
+               u8 rsn_ies_len;
+
+               sm_link = &sm->mld_links[ml_rsn_info.links[i].link_id];
+               rsn_ies = ml_rsn_info.links[i].rsn_ies;
+               rsn_ies_len = ml_rsn_info.links[i].rsn_ies_len;
+
+               /* This should not really happen */
+               if (!rsn_ies || rsn_ies_len < 2 || rsn_ies[0] != WLAN_EID_RSN ||
+                   rsn_ies[1] + 2 > rsn_ies_len) {
+                       wpa_printf(MSG_INFO, "WPA_AUTH: MLD: Invalid RSNE");
+                       continue;
+               }
+
+               sm_link->rsne = rsn_ies;
+               sm_link->rsne_len = rsn_ies[1] + 2;
+
+               if (rsn_ies[1] + 2UL + 2UL < rsn_ies_len &&
+                   rsn_ies[rsn_ies[1] + 2] == WLAN_EID_RSNX) {
+                       sm_link->rsnxe = rsn_ies + 2 + rsn_ies[1];
+                       sm_link->rsnxe_len = sm_link->rsnxe[1] + 2;
+               }
+       }
+#endif /* CONFIG_IEEE80211BE */
+}
index eed016accb4a88267f9e8784d367eef61936e5e2..311d91f7f2ba9c49a38516f023ede5a4a6f99d01 100644 (file)
@@ -15,6 +15,7 @@
 #include "common/ieee802_11_defs.h"
 
 struct vlan_description;
+struct mld_info;
 
 #define MAX_OWN_IE_OVERRIDE 256
 
@@ -288,6 +289,16 @@ typedef enum {
        WPA_EAPOL_keyDone, WPA_EAPOL_inc_EapolFramesTx
 } wpa_eapol_variable;
 
+struct wpa_auth_ml_rsn_info {
+       unsigned int n_mld_links;
+
+       struct wpa_auth_ml_link_rsn_info {
+               unsigned int link_id;
+               const u8 *rsn_ies;
+               size_t rsn_ies_len;
+       } links[MAX_NUM_MLD_LINKS];
+};
+
 struct wpa_auth_callbacks {
        void (*logger)(void *ctx, const u8 *addr, logger_level level,
                       const char *txt);
@@ -355,6 +366,9 @@ struct wpa_auth_callbacks {
        int (*set_ltf_keyseed)(void *ctx, const u8 *addr, const u8 *ltf_keyseed,
                               size_t ltf_keyseed_len);
 #endif /* CONFIG_PASN */
+#ifdef CONFIG_IEEE80211BE
+       int (*get_ml_rsn_info)(void *ctx, struct wpa_auth_ml_rsn_info *info);
+#endif /* CONFIG_IEEE80211BE */
 };
 
 struct wpa_authenticator * wpa_init(const u8 *addr,
@@ -593,4 +607,9 @@ void wpa_auth_set_ocv_override_freq(struct wpa_authenticator *wpa_auth,
 
 void wpa_auth_sta_radius_psk_resp(struct wpa_state_machine *sm, bool success);
 
+void wpa_auth_set_ml_info(struct wpa_state_machine *sm, const u8 *mld_addr,
+                         u8 mld_assoc_link_id, struct mld_info *info);
+void wpa_auth_ml_get_rsn_info(struct wpa_authenticator *a,
+                             struct wpa_auth_ml_link_rsn_info *info);
+
 #endif /* WPA_AUTH_H */
index 14ac4e785c2bf0a139965ed5a63c5224b2ae9308..41c029973bd80bc52c46dfda8ee4dab42cb5de8e 100644 (file)
@@ -1496,6 +1496,50 @@ static int hostapd_set_ltf_keyseed(void *ctx, const u8 *peer_addr,
 #endif /* CONFIG_PASN */
 
 
+#ifdef CONFIG_IEEE80211BE
+static int hostapd_wpa_auth_get_ml_rsn_info(void *ctx,
+                                           struct wpa_auth_ml_rsn_info *info)
+{
+       struct hostapd_data *hapd = ctx;
+       unsigned int i, j;
+
+       wpa_printf(MSG_DEBUG, "WPA_AUTH: MLD: Get RSN info CB: n_mld_links=%u",
+                  info->n_mld_links);
+
+       if (!hapd->conf->mld_ap || !hapd->iface || !hapd->iface->interfaces)
+               return -1;
+
+       for (i = 0; i < info->n_mld_links; i++) {
+               unsigned int link_id = info->links[i].link_id;
+
+               wpa_printf(MSG_DEBUG,
+                          "WPA_AUTH: MLD: Get link RSN CB: link_id=%u",
+                          link_id);
+
+               for (j = 0; j < hapd->iface->interfaces->count; j++) {
+                       struct hostapd_iface *iface =
+                               hapd->iface->interfaces->iface[j];
+
+                       if (!iface->bss[0]->conf->mld_ap ||
+                           hapd->conf->mld_id != iface->bss[0]->conf->mld_id ||
+                           link_id != iface->bss[0]->mld_link_id)
+                               continue;
+
+                       wpa_auth_ml_get_rsn_info(iface->bss[0]->wpa_auth,
+                                                &info->links[i]);
+                       break;
+               }
+
+               if (j == hapd->iface->interfaces->count)
+                       wpa_printf(MSG_DEBUG,
+                                  "WPA_AUTH: MLD: link=%u not found", link_id);
+       }
+
+       return 0;
+}
+#endif /* CONFIG_IEEE80211BE */
+
+
 int hostapd_setup_wpa(struct hostapd_data *hapd)
 {
        struct wpa_auth_config _conf;
@@ -1545,6 +1589,9 @@ int hostapd_setup_wpa(struct hostapd_data *hapd)
 #ifdef CONFIG_PASN
                .set_ltf_keyseed = hostapd_set_ltf_keyseed,
 #endif /* CONFIG_PASN */
+#ifdef CONFIG_IEEE80211BE
+               .get_ml_rsn_info = hostapd_wpa_auth_get_ml_rsn_info,
+#endif /* CONFIG_IEEE80211BE */
        };
        const u8 *wpa_ie;
        size_t wpa_ie_len;
index d401550c7a8d7f1d08f992de58c6a6520eb9d378..74ae5ad2e361649dd683768311cc0f4dc307caa1 100644 (file)
@@ -172,6 +172,24 @@ struct wpa_state_machine {
        void *eapol_status_cb_ctx1;
        void *eapol_status_cb_ctx2;
 #endif /* CONFIG_TESTING_OPTIONS */
+
+#ifdef CONFIG_IEEE80211BE
+       u8 own_mld_addr[ETH_ALEN];
+       u8 peer_mld_addr[ETH_ALEN];
+       s8 mld_assoc_link_id;
+       u8 n_mld_affiliated_links;
+
+       struct mld_link {
+               bool valid;
+               u8 peer_addr[ETH_ALEN];
+               u8 own_addr[ETH_ALEN];
+
+               const u8 *rsne;
+               size_t rsne_len;
+               const u8 *rsnxe;
+               size_t rsnxe_len;
+       } mld_links[MAX_NUM_MLD_LINKS];
+#endif /* CONFIG_IEEE80211BE */
 };