mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-21 11:22:50 +00:00
Some checks failed
Build OpenWrt/uCentral images / build (cig_wf186h) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cig_wf186w) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cig_wf188n) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cig_wf189) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cig_wf196) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cybertan_eww631-a1) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cybertan_eww631-b1) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap101) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap102) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap104) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap105) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap111) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap112) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_oap101) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_oap101-6e) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_oap101e) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_oap101e-6e) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4x) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4x_2) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4x_3) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4x_w) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4xe) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4xi) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4xi_w) (push) Has been cancelled
Build OpenWrt/uCentral images / build (indio_um-305ax) (push) Has been cancelled
Build OpenWrt/uCentral images / build (sercomm_ap72tip) (push) Has been cancelled
Build OpenWrt/uCentral images / build (sonicfi_rap630c-311g) (push) Has been cancelled
Build OpenWrt/uCentral images / build (sonicfi_rap630w-211g) (push) Has been cancelled
Build OpenWrt/uCentral images / build (sonicfi_rap630w-311g) (push) Has been cancelled
Build OpenWrt/uCentral images / build (udaya_a6-id2) (push) Has been cancelled
Build OpenWrt/uCentral images / build (udaya_a6-od2) (push) Has been cancelled
Build OpenWrt/uCentral images / build (wallys_dr5018) (push) Has been cancelled
Build OpenWrt/uCentral images / build (wallys_dr6018) (push) Has been cancelled
Build OpenWrt/uCentral images / build (wallys_dr6018-v4) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_ax820) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_ax840) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_fap640) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_fap650) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_fap655) (push) Has been cancelled
Build OpenWrt/uCentral images / trigger-testing (push) Has been cancelled
Build OpenWrt/uCentral images / create-x64_vm-ami (push) Has been cancelled
Signed-off-by: John Crispin <john@phrozen.org>
522 lines
15 KiB
Diff
522 lines
15 KiB
Diff
From 4c901173a6a0886f83dc62541f0cced19da36f0e Mon Sep 17 00:00:00 2001
|
|
From: Yuvarani V <quic_yuvarani@quicinc.com>
|
|
Date: Thu, 28 Dec 2023 13:23:28 +0530
|
|
Subject: [PATCH] hostapd: add FT over DS support
|
|
|
|
- Source AP's associated STA's ML address will be shared in FT action frame
|
|
instead of the STA's link address as per D3.0 spec.
|
|
|
|
- Target AP's Hostapd will maintain a separate list with the STA's ML address
|
|
until it receive the assoc request from the station.
|
|
|
|
- On receiving assoc frame, Target AP will replace the ML address with
|
|
STA's Link address and completes the connectivity.
|
|
|
|
Signed-off-by: Karthik M <quic_karm@quicinc.com>
|
|
Signed-off-by: Yuvarani V <quic_yuvarani@quicinc.com>
|
|
---
|
|
src/ap/ap_drv_ops.c | 4 +-
|
|
src/ap/ap_drv_ops.h | 2 +-
|
|
src/ap/hostapd.c | 1 +
|
|
src/ap/hostapd.h | 12 +++++
|
|
src/ap/ieee802_11.c | 119 +++++++++++++++++++++++++++++++++++++++++
|
|
src/ap/ieee802_11.h | 2 +
|
|
src/ap/sta_info.c | 21 ++++++++
|
|
src/ap/sta_info.h | 3 ++
|
|
src/ap/wpa_auth.c | 6 +++
|
|
src/ap/wpa_auth.h | 4 +-
|
|
src/ap/wpa_auth_ft.c | 33 ++++++++++--
|
|
src/ap/wpa_auth_glue.c | 81 +++++++++++++++++++++++++++-
|
|
src/drivers/driver.h | 2 +-
|
|
13 files changed, 280 insertions(+), 10 deletions(-)
|
|
|
|
--- a/src/ap/ap_drv_ops.c
|
|
+++ b/src/ap/ap_drv_ops.c
|
|
@@ -372,11 +372,11 @@ int hostapd_set_wds_sta(struct hostapd_d
|
|
|
|
|
|
int hostapd_add_sta_node(struct hostapd_data *hapd, const u8 *addr,
|
|
- u16 auth_alg)
|
|
+ u16 auth_alg, bool is_ml)
|
|
{
|
|
if (hapd->driver == NULL || hapd->driver->add_sta_node == NULL)
|
|
return -EOPNOTSUPP;
|
|
- return hapd->driver->add_sta_node(hapd->drv_priv, addr, auth_alg);
|
|
+ return hapd->driver->add_sta_node(hapd->drv_priv, addr, auth_alg, is_ml);
|
|
}
|
|
|
|
static int hostapd_get_scs_final_value(struct sta_info *sta,
|
|
--- a/src/ap/ap_drv_ops.h
|
|
+++ b/src/ap/ap_drv_ops.h
|
|
@@ -125,7 +125,7 @@ hostapd_drv_send_action_cancel_wait(stru
|
|
hapd->driver->send_action_cancel_wait(hapd->drv_priv);
|
|
}
|
|
int hostapd_add_sta_node(struct hostapd_data *hapd, const u8 *addr,
|
|
- u16 auth_alg);
|
|
+ u16 auth_alg, bool is_ml);
|
|
int hostapd_sta_auth(struct hostapd_data *hapd, const u8 *addr,
|
|
u16 seq, u16 status, const u8 *ie, size_t len);
|
|
int hostapd_sta_assoc(struct hostapd_data *hapd, const u8 *addr,
|
|
--- a/src/ap/hostapd.c
|
|
+++ b/src/ap/hostapd.c
|
|
@@ -3073,6 +3073,7 @@ static void hostapd_bss_setup_multi_link
|
|
interfaces->mld = all_mld;
|
|
interfaces->mld[interfaces->mld_count] = mld;
|
|
interfaces->mld_count++;
|
|
+ dl_list_init(&hapd->mld->ft_ds_ml_stas);
|
|
|
|
return;
|
|
fail:
|
|
--- a/src/ap/hostapd.h
|
|
+++ b/src/ap/hostapd.h
|
|
@@ -553,6 +553,17 @@ struct hostapd_sta_info {
|
|
};
|
|
|
|
#ifdef CONFIG_IEEE80211BE
|
|
+
|
|
+/**
|
|
+ * struct hostapd_ft_over_ds_ml_sta_entry - ft over ds ml sta structure
|
|
+ */
|
|
+struct hostapd_ft_over_ds_ml_sta_entry {
|
|
+ struct dl_list list;
|
|
+ u8 mld_mac[ETH_ALEN];
|
|
+ struct wpa_state_machine *wpa_sm;
|
|
+ struct wpa_authenticator *wpa_auth;
|
|
+};
|
|
+
|
|
/**
|
|
* struct hostapd_mld - hostapd per-mld data structure
|
|
*/
|
|
@@ -564,6 +575,7 @@ struct hostapd_mld {
|
|
|
|
struct hostapd_data *fbss;
|
|
struct dl_list links; /* List HEAD of all affiliated links */
|
|
+ struct dl_list ft_ds_ml_stas;
|
|
};
|
|
#endif /* CONFIG_IEEE80211BE */
|
|
|
|
--- a/src/ap/ieee802_11.c
|
|
+++ b/src/ap/ieee802_11.c
|
|
@@ -60,6 +60,7 @@
|
|
#ifdef CONFIG_IEEE80211BE
|
|
#include "scs.h"
|
|
#endif
|
|
+#include "wpa_auth_i.h"
|
|
|
|
#ifdef CONFIG_FILS
|
|
static struct wpabuf *
|
|
@@ -3069,6 +3070,17 @@ static void handle_auth(struct hostapd_d
|
|
return;
|
|
}
|
|
#endif /* CONFIG_SAE */
|
|
+ {
|
|
+ struct hostapd_ft_over_ds_ml_sta_entry *entry;
|
|
+
|
|
+ entry = ap_get_ft_ds_ml_sta(hapd, sa);
|
|
+ if (entry) {
|
|
+ wpa_printf(MSG_ERROR,
|
|
+ "handle_auth: Auth frame received with SA = FT-OVER-DS list MLD mac "MACSTR"\n",
|
|
+ MAC2STR(sa));
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
|
|
sta = ap_get_sta(hapd, sa);
|
|
if (sta) {
|
|
@@ -3307,6 +3319,23 @@ static void handle_auth(struct hostapd_d
|
|
}
|
|
|
|
|
|
+void hostap_ft_ds_ml_sta_timeout(void *eloop_ctx, void *timeout_ctx)
|
|
+{
|
|
+ struct hostapd_ft_over_ds_ml_sta_entry *entry = eloop_ctx;
|
|
+
|
|
+ if (!entry)
|
|
+ return;
|
|
+
|
|
+ wpa_printf(MSG_DEBUG, "%s: removing "MACSTR"\n", __func__,
|
|
+ MAC2STR(entry->mld_mac));
|
|
+ if (entry->wpa_sm)
|
|
+ wpa_auth_sta_deinit(entry->wpa_sm);
|
|
+
|
|
+ dl_list_del(&entry->list);
|
|
+ os_free(entry);
|
|
+}
|
|
+
|
|
+
|
|
static u8 hostapd_max_bssid_indicator(struct hostapd_data *hapd)
|
|
{
|
|
size_t num_bss_nontx;
|
|
@@ -5284,6 +5313,93 @@ void fils_hlp_timeout(void *eloop_ctx, v
|
|
#endif /* CONFIG_FILS */
|
|
|
|
|
|
+static const u8 *
|
|
+hostapd_mlie_to_get_mld_addr_from_assoc(struct hostapd_data *hapd,
|
|
+ const struct ieee80211_mgmt *mgmt,
|
|
+ size_t len, int reassoc)
|
|
+{
|
|
+ struct ieee802_11_elems elems;
|
|
+ const u8 *pos;
|
|
+ int assoc_ies_len;
|
|
+
|
|
+ if (!hapd->mld->mld_addr)
|
|
+ return NULL;
|
|
+
|
|
+ pos = reassoc ? mgmt->u.reassoc_req.variable : mgmt->u.assoc_req.variable;
|
|
+ if (!pos)
|
|
+ return NULL;
|
|
+
|
|
+ if (reassoc) {
|
|
+ len -= offsetof(struct ieee80211_mgmt, u.reassoc_req.variable);
|
|
+ assoc_ies_len = (int)len - (pos - mgmt->u.reassoc_req.variable);
|
|
+ } else {
|
|
+ len -= offsetof(struct ieee80211_mgmt, u.assoc_req.variable);
|
|
+ assoc_ies_len = (int)len - (pos - mgmt->u.assoc_req.variable);
|
|
+ }
|
|
+
|
|
+ if (ieee802_11_parse_elems(pos, assoc_ies_len,
|
|
+ &elems, 0) == ParseFailed) {
|
|
+ wpa_printf(MSG_DEBUG,
|
|
+ "MLD: Failed parsing Authentication frame");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ if (!elems.basic_mle || !elems.basic_mle_len)
|
|
+ return NULL;
|
|
+
|
|
+ return get_basic_mle_mld_addr(elems.basic_mle, elems.basic_mle_len);
|
|
+}
|
|
+
|
|
+
|
|
+static struct sta_info *
|
|
+get_sta_from_ft_ds_list(struct hostapd_data *hapd,
|
|
+ const struct ieee80211_mgmt *mgmt,
|
|
+ size_t len, int reassoc)
|
|
+{
|
|
+ struct hostapd_ft_over_ds_ml_sta_entry *entry;
|
|
+ const u8 *sta_mld;
|
|
+ struct wpa_state_machine *wpa_sm;
|
|
+ struct sta_info *sta;
|
|
+
|
|
+ if (!hapd->mld)
|
|
+ return NULL;
|
|
+
|
|
+ sta_mld = hostapd_mlie_to_get_mld_addr_from_assoc(hapd, mgmt, len, reassoc);
|
|
+ entry = ap_get_ft_ds_ml_sta(hapd, sta_mld);
|
|
+ if (!entry)
|
|
+ return NULL;
|
|
+
|
|
+ wpa_sm = entry->wpa_sm;
|
|
+ eloop_cancel_timeout(hostap_ft_ds_ml_sta_timeout, entry, NULL);
|
|
+ dl_list_del(&entry->list);
|
|
+ os_free(entry);
|
|
+
|
|
+ if (wpa_sm) {
|
|
+ wpa_auth_sta_addr_change(wpa_sm, mgmt->sa);
|
|
+ if (!wpa_sm->group)
|
|
+ wpa_sm->group = hapd->wpa_auth->group;
|
|
+ } else {
|
|
+ wpa_printf(MSG_DEBUG, "%s : Temp reject the station as it is a existing entry",
|
|
+ __func__);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ sta = ap_sta_add(hapd, mgmt->sa);
|
|
+ if (!sta) {
|
|
+ if (wpa_sm)
|
|
+ wpa_auth_sta_deinit(wpa_sm);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ sta->auth_alg = WLAN_AUTH_FT;
|
|
+ sta->ft_over_ds = true;
|
|
+ sta->wpa_sm = wpa_sm;
|
|
+ //sta->ft_over_ds_saquery_status = sa_query_status;
|
|
+
|
|
+ return sta;
|
|
+}
|
|
+
|
|
+
|
|
static void handle_assoc(struct hostapd_data *hapd,
|
|
const struct ieee80211_mgmt *mgmt, size_t len,
|
|
int reassoc, int rssi)
|
|
@@ -5357,6 +5473,11 @@ static void handle_assoc(struct hostapd_
|
|
|
|
sta = ap_get_sta(hapd, mgmt->sa);
|
|
#ifdef CONFIG_IEEE80211R_AP
|
|
+ if (!sta) {
|
|
+ wpa_printf(MSG_DEBUG,
|
|
+ "FT over DS: Check for STA entry with ML address");
|
|
+ sta = get_sta_from_ft_ds_list(hapd, mgmt, len, reassoc);
|
|
+ }
|
|
if (sta && sta->auth_alg == WLAN_AUTH_FT &&
|
|
(sta->flags & WLAN_STA_AUTH) == 0) {
|
|
wpa_printf(MSG_DEBUG, "FT: Allow STA " MACSTR " to associate "
|
|
--- a/src/ap/ieee802_11.h
|
|
+++ b/src/ap/ieee802_11.h
|
|
@@ -170,6 +170,8 @@ static inline void sae_clear_retransmit_
|
|
}
|
|
#endif /* CONFIG_SAE */
|
|
|
|
+void hostap_ft_ds_ml_sta_timeout(void *eloop_ctx, void *timeout_ctx);
|
|
+
|
|
u8 * hostapd_eid_rm_enabled_capab(struct hostapd_data *hapd,
|
|
u8 *eid, size_t len);
|
|
|
|
--- a/src/ap/sta_info.c
|
|
+++ b/src/ap/sta_info.c
|
|
@@ -69,6 +69,26 @@ int ap_for_each_sta(struct hostapd_data
|
|
}
|
|
|
|
|
|
+struct hostapd_ft_over_ds_ml_sta_entry *ap_get_ft_ds_ml_sta(struct hostapd_data *hapd,
|
|
+ const u8 *sta)
|
|
+{
|
|
+ struct hostapd_ft_over_ds_ml_sta_entry *item;
|
|
+
|
|
+ if (!hapd->mld) {
|
|
+ wpa_printf(MSG_ERROR, "NULL Pointer %s:%d\n",
|
|
+ __func__, __LINE__);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ dl_list_for_each(item, &hapd->mld->ft_ds_ml_stas,
|
|
+ struct hostapd_ft_over_ds_ml_sta_entry, list) {
|
|
+ if (os_memcmp(item->mld_mac, sta, ETH_ALEN) == 0)
|
|
+ return item;
|
|
+ }
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+
|
|
struct sta_info * ap_get_sta(struct hostapd_data *hapd, const u8 *sta)
|
|
{
|
|
struct sta_info *s;
|
|
--- a/src/ap/sta_info.h
|
|
+++ b/src/ap/sta_info.h
|
|
@@ -119,6 +119,7 @@ struct sta_info {
|
|
u8 supported_rates[WLAN_SUPP_RATES_MAX];
|
|
int supported_rates_len;
|
|
u8 qosinfo; /* Valid when WLAN_STA_WMM is set */
|
|
+ int ft_over_ds_saquery_status;
|
|
|
|
#ifdef CONFIG_MESH
|
|
enum mesh_plink_state plink_state;
|
|
@@ -394,6 +395,8 @@ int ap_for_each_sta(struct hostapd_data
|
|
int (*cb)(struct hostapd_data *hapd, struct sta_info *sta,
|
|
void *ctx),
|
|
void *ctx);
|
|
+struct hostapd_ft_over_ds_ml_sta_entry *ap_get_ft_ds_ml_sta(struct hostapd_data *hapd,
|
|
+ const u8 *sta_mld);
|
|
struct sta_info * ap_get_sta(struct hostapd_data *hapd, const u8 *sta);
|
|
struct sta_info * ap_get_sta_p2p(struct hostapd_data *hapd, const u8 *addr);
|
|
void ap_sta_hash_add(struct hostapd_data *hapd, struct sta_info *sta);
|
|
--- a/src/ap/wpa_auth.c
|
|
+++ b/src/ap/wpa_auth.c
|
|
@@ -825,6 +825,12 @@ int wpa_reconfig(struct wpa_authenticato
|
|
}
|
|
|
|
|
|
+void wpa_auth_sta_addr_change(struct wpa_state_machine *wpa_sm, const u8 *addr)
|
|
+{
|
|
+ os_memcpy(wpa_sm->addr, addr, sizeof(wpa_sm->addr));
|
|
+}
|
|
+
|
|
+
|
|
struct wpa_state_machine *
|
|
wpa_auth_sta_init(struct wpa_authenticator *wpa_auth, const u8 *addr,
|
|
const u8 *p2p_dev_addr)
|
|
--- a/src/ap/wpa_auth.h
|
|
+++ b/src/ap/wpa_auth.h
|
|
@@ -365,7 +365,8 @@ struct wpa_auth_callbacks {
|
|
const u8 *anonce,
|
|
const u8 *eapol, size_t eapol_len);
|
|
#ifdef CONFIG_IEEE80211R_AP
|
|
- struct wpa_state_machine * (*add_sta)(void *ctx, const u8 *sta_addr);
|
|
+ struct wpa_state_machine * (*add_sta)(void *ctx, const u8 *sta_addr,
|
|
+ bool is_ml);
|
|
int (*add_sta_ft)(void *ctx, const u8 *sta_addr);
|
|
int (*set_vlan)(void *ctx, const u8 *sta_addr,
|
|
struct vlan_description *vlan);
|
|
@@ -435,6 +436,7 @@ int wpa_auth_uses_ocv(struct wpa_state_m
|
|
struct wpa_state_machine *
|
|
wpa_auth_sta_init(struct wpa_authenticator *wpa_auth, const u8 *addr,
|
|
const u8 *p2p_dev_addr);
|
|
+void wpa_auth_sta_addr_change(struct wpa_state_machine *wpa_sm, const u8 *addr);
|
|
int wpa_auth_sta_associated(struct wpa_authenticator *wpa_auth,
|
|
struct wpa_state_machine *sm);
|
|
void wpa_auth_sta_no_wpa(struct wpa_state_machine *sm);
|
|
--- a/src/ap/wpa_auth_ft.c
|
|
+++ b/src/ap/wpa_auth_ft.c
|
|
@@ -674,11 +674,12 @@ static const u8 * wpa_ft_get_psk(struct
|
|
|
|
|
|
static struct wpa_state_machine *
|
|
-wpa_ft_add_sta(struct wpa_authenticator *wpa_auth, const u8 *sta_addr)
|
|
+wpa_ft_add_sta(struct wpa_authenticator *wpa_auth, const u8 *sta_addr,
|
|
+ bool is_ml)
|
|
{
|
|
if (wpa_auth->cb->add_sta == NULL)
|
|
return NULL;
|
|
- return wpa_auth->cb->add_sta(wpa_auth->cb_ctx, sta_addr);
|
|
+ return wpa_auth->cb->add_sta(wpa_auth->cb_ctx, sta_addr, is_ml);
|
|
}
|
|
|
|
|
|
@@ -4209,8 +4210,39 @@ static int wpa_ft_rrb_rx_request(struct
|
|
u8 *resp_ies;
|
|
size_t resp_ies_len;
|
|
int res;
|
|
+ bool is_ml = false;
|
|
+ struct ieee802_11_elems elems;
|
|
+ const u8 *mld_mac;
|
|
|
|
- sm = wpa_ft_add_sta(wpa_auth, sta_addr);
|
|
+ if (ieee802_11_parse_elems(body, len, &elems, 1) == ParseFailed) {
|
|
+ wpa_printf(MSG_DEBUG,
|
|
+ "ERROR!! %s parse_elems failure for " MACSTR,
|
|
+ __func__,
|
|
+ MAC2STR(sta_addr));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (elems.basic_mle) {
|
|
+ mld_mac = get_basic_mle_mld_addr(elems.basic_mle, elems.basic_mle_len);
|
|
+ if (!mld_mac) {
|
|
+ wpa_printf(MSG_ERROR,
|
|
+ "ERROR!! %s MLD Mac extraction from ML-IE failure\n",
|
|
+ __func__);
|
|
+ } else if (os_memcmp(mld_mac, sta_addr, ETH_ALEN) != 0) {
|
|
+ wpa_printf(MSG_ERROR,
|
|
+ "ERROR!! %s MIMSATCH between sta_addr in FT-REQUEST fixed field and in the ML-IE "MACSTR" "MACSTR"\n",
|
|
+ __func__, MAC2STR(mld_mac), MAC2STR(sta_addr));
|
|
+ return -1;
|
|
+ }
|
|
+ wpa_printf(MSG_MSGDUMP,
|
|
+ "FT over DS: Received STA "MACSTR" "MACSTR"\n",
|
|
+ MAC2STR(mld_mac), MAC2STR(sta_addr));
|
|
+ is_ml = true;
|
|
+ } else {
|
|
+ is_ml = false;
|
|
+ }
|
|
+
|
|
+ sm = wpa_ft_add_sta(wpa_auth, sta_addr, is_ml);
|
|
if (sm == NULL) {
|
|
wpa_printf(MSG_DEBUG, "FT: Failed to add new STA based on "
|
|
"RRB Request");
|
|
--- a/src/ap/wpa_auth_glue.c
|
|
+++ b/src/ap/wpa_auth_glue.c
|
|
@@ -1130,7 +1130,80 @@ static int hostapd_wpa_auth_send_ft_acti
|
|
|
|
|
|
static struct wpa_state_machine *
|
|
-hostapd_wpa_auth_add_sta(void *ctx, const u8 *sta_addr)
|
|
+hostapd_wpa_auth_add_sta_ml(struct hostapd_data *hapd, const u8 *sta_mld)
|
|
+{
|
|
+ struct sta_info *sta_ml_obj;
|
|
+ bool new_allocation = false;
|
|
+ bool ft_ds_list_found = false;
|
|
+ struct hostapd_ft_over_ds_ml_sta_entry *entry;
|
|
+ struct wpa_state_machine *wpa_sm = NULL;
|
|
+
|
|
+ if (!hapd->mld) {
|
|
+ wpa_printf(MSG_ERROR, "%s hapd is not MLO\n", __func__);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ entry = ap_get_ft_ds_ml_sta(hapd, sta_mld);
|
|
+ if (!entry) {
|
|
+ entry = os_zalloc(sizeof(*entry));
|
|
+ if (entry == NULL) {
|
|
+ wpa_printf(MSG_ERROR,
|
|
+ "%s: failed to allocate ft_ds_ml_entry\n",
|
|
+ __func__);
|
|
+ return NULL;
|
|
+ }
|
|
+ new_allocation = true;
|
|
+ os_memcpy(entry->mld_mac, sta_mld, 6);
|
|
+ entry->wpa_auth = hapd->wpa_auth;
|
|
+ } else {
|
|
+ ft_ds_list_found = true;
|
|
+ }
|
|
+
|
|
+ sta_ml_obj = ap_get_sta(hapd, sta_mld);
|
|
+ if (sta_ml_obj)
|
|
+ wpa_sm = sta_ml_obj->wpa_sm;
|
|
+
|
|
+ if (!wpa_sm) {
|
|
+ /*
|
|
+ * entry->wpa_sm is marked only if wpa-sm is newly
|
|
+ * allocated during the FT-Over-DS entry addition here.
|
|
+ * Otherwise entry-wpa_sm remains as NULL
|
|
+ *
|
|
+ * On receiving assoc-request if a sta_info node has to be
|
|
+ * created entry->wpa_sm should be available to attach to that
|
|
+ * sta_info.
|
|
+ */
|
|
+ entry->wpa_sm =
|
|
+ wpa_auth_sta_init(hapd->wpa_auth, sta_mld, NULL);
|
|
+ wpa_sm = entry->wpa_sm;
|
|
+ }
|
|
+
|
|
+ if (wpa_sm == NULL) {
|
|
+ wpa_printf(MSG_ERROR, "%s: wpa_sm NULL\n", __func__);
|
|
+ if (new_allocation)
|
|
+ os_free(entry);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ if (ft_ds_list_found)
|
|
+ /*
|
|
+ * Cancel the existing timer
|
|
+ */
|
|
+ eloop_cancel_timeout(hostap_ft_ds_ml_sta_timeout, sta_ml_obj, NULL);
|
|
+ else
|
|
+ dl_list_add(&hapd->mld->ft_ds_ml_stas, &entry->list);
|
|
+
|
|
+ /*
|
|
+ * Expect FT-Assoc at least 5 seconds after receiving FT-Request,
|
|
+ * otherwise remove from list
|
|
+ */
|
|
+ eloop_register_timeout(5, 0, hostap_ft_ds_ml_sta_timeout, sta_ml_obj, NULL);
|
|
+ return wpa_sm;
|
|
+}
|
|
+
|
|
+
|
|
+static struct wpa_state_machine *
|
|
+hostapd_wpa_auth_add_sta(void *ctx, const u8 *sta_addr, bool is_ml)
|
|
{
|
|
struct hostapd_data *hapd = ctx;
|
|
struct sta_info *sta;
|
|
@@ -1139,7 +1212,7 @@ hostapd_wpa_auth_add_sta(void *ctx, cons
|
|
wpa_printf(MSG_DEBUG, "Add station entry for " MACSTR
|
|
" based on WPA authenticator callback",
|
|
MAC2STR(sta_addr));
|
|
- ret = hostapd_add_sta_node(hapd, sta_addr, WLAN_AUTH_FT);
|
|
+ ret = hostapd_add_sta_node(hapd, sta_addr, WLAN_AUTH_FT, is_ml);
|
|
|
|
/*
|
|
* The expected return values from hostapd_add_sta_node() are
|
|
@@ -1150,6 +1223,9 @@ hostapd_wpa_auth_add_sta(void *ctx, cons
|
|
if (ret < 0 && ret != -EOPNOTSUPP)
|
|
return NULL;
|
|
|
|
+ if (is_ml)
|
|
+ return hostapd_wpa_auth_add_sta_ml(hapd, sta_addr);
|
|
+
|
|
sta = ap_sta_add(hapd, sta_addr);
|
|
if (sta == NULL)
|
|
return NULL;
|
|
--- a/src/drivers/driver.h
|
|
+++ b/src/drivers/driver.h
|
|
@@ -4503,7 +4503,7 @@ struct wpa_driver_ops {
|
|
* This function adds the station node in the driver, when
|
|
* the station gets added by FT-over-DS.
|
|
*/
|
|
- int (*add_sta_node)(void *priv, const u8 *addr, u16 auth_alg);
|
|
+ int (*add_sta_node)(void *priv, const u8 *addr, u16 auth_alg, bool is_ml);
|
|
|
|
/**
|
|
* sched_scan - Request the driver to initiate scheduled scan
|