[PATCH 37/50] WPA_AUTH: MLO: Store MLO link information
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Wed Feb 15 15:08:51 PST 2023
Signed-off-by: Ilan Peer <ilan.peer at intel.com>
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
src/ap/ieee802_11.c | 28 +++++++++--
src/ap/wpa_auth.c | 111 +++++++++++++++++++++++++++++++++++++++++
src/ap/wpa_auth.h | 44 ++++++++++++++++
src/ap/wpa_auth_glue.c | 46 +++++++++++++++++
src/ap/wpa_auth_i.h | 16 ++++++
5 files changed, 240 insertions(+), 5 deletions(-)
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 10af54b484..c302f01804 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -3929,15 +3929,33 @@ 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 WPA SM");
+ return WLAN_STATUS_UNSPECIFIED_FAILURE;
+ }
+
+#ifdef CONFIG_IEEE80211BE
+ if (info->mld_sta) {
+ wpa_printf(MSG_DEBUG, "MLD: used for WPA");
+
+ 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,
diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index a9227a4f15..a1e5d9bb52 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -33,6 +33,7 @@
#include "pmksa_cache_auth.h"
#include "wpa_auth_i.h"
#include "wpa_auth_ie.h"
+#include "sta_info.h"
static const u8 *wpa_auth_get_aa(struct wpa_state_machine *sm)
{
@@ -694,6 +695,7 @@ 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);
+ sm->mld_assoc_link_id = -1;
return sm;
}
@@ -787,6 +789,11 @@ static void wpa_free_sta_sm(struct wpa_state_machine *sm)
#ifdef CONFIG_DPP2
wpabuf_clear_free(sm->dpp_z);
#endif /* CONFIG_DPP2 */
+ os_memset(sm->own_mld_addr, 0, sizeof(sm->own_mld_addr));
+ os_memset(sm->peer_mld_addr, 0, sizeof(sm->peer_mld_addr));
+ sm->mld_assoc_link_id = -1;
+ os_memset(sm->mld_links, 0, sizeof(sm->mld_links));
+
bin_clear_free(sm, sizeof(*sm));
}
@@ -3587,6 +3594,29 @@ 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,
+ "WPA_AUTH: MLD: RSN info: link_id=%u, rsn_ies_len=%u",
+ 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)
{
@@ -6024,3 +6054,84 @@ 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;
+ u32 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++) {
+ u8 link_id = ml_rsn_info.links[i].link_id;
+ struct mld_link *sm_link = &sm->mld_links[link_id];
+ const u8 *rsn_ies;
+ u8 rsn_ies_len;
+
+ 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) {
+ wpa_printf(MSG_DEBUG,
+ "WPA_AUTH: MLD: Invalid RSN element");
+ 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 */
+}
diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h
index eed016accb..fbd9d84f8b 100644
--- a/src/ap/wpa_auth.h
+++ b/src/ap/wpa_auth.h
@@ -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,40 @@ typedef enum {
WPA_EAPOL_keyDone, WPA_EAPOL_inc_EapolFramesTx
} wpa_eapol_variable;
+struct wpa_auth_ml_rsn_info {
+ u8 n_mld_links;
+
+ struct wpa_auth_ml_link_rsn_info {
+ u8 link_id;
+ const u8 *rsn_ies;
+ u8 rsn_ies_len;
+ } links[MAX_NUM_MLD_LINKS];
+};
+
+struct wpa_auth_ml_key_info {
+ u8 n_mld_links;
+ bool mgmt_frame_prot;
+ bool beacon_prot;
+
+ struct wpa_auth_ml_link_key_info {
+ u8 link_id;
+
+ u8 gtkidx;
+ u8 gtk_len;
+ u8 pn[6];
+ const u8 *gtk;
+
+ u8 igtkidx;
+ u8 igtk_len;
+ const u8 *igtk;
+ u8 ipn[6];
+
+ u8 bigtkidx;
+ const u8 *bigtk;
+ u8 bipn[6];
+ } links[MAX_NUM_MLD_LINKS];
+};
+
struct wpa_auth_callbacks {
void (*logger)(void *ctx, const u8 *addr, logger_level level,
const char *txt);
@@ -355,6 +390,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 +631,10 @@ 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 */
diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c
index 9090ba7840..e15013c11b 100644
--- a/src/ap/wpa_auth_glue.c
+++ b/src/ap/wpa_auth_glue.c
@@ -1496,6 +1496,49 @@ 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;
+ u8 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++) {
+ u8 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]->conf->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)
{
@@ -1546,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;
diff --git a/src/ap/wpa_auth_i.h b/src/ap/wpa_auth_i.h
index f3cb9be31f..c3f1c19e9d 100644
--- a/src/ap/wpa_auth_i.h
+++ b/src/ap/wpa_auth_i.h
@@ -172,6 +172,22 @@ struct wpa_state_machine {
void *eapol_status_cb_ctx1;
void *eapol_status_cb_ctx2;
#endif /* CONFIG_TESTING_OPTIONS */
+
+ 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;
+ const u8 *rsnxe;
+ u8 rsne_len;
+ u8 rsnxe_len;
+ } mld_links[MAX_NUM_MLD_LINKS];
};
--
2.38.1
More information about the Hostap
mailing list