mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-30 18:07:52 +00:00
391 lines
14 KiB
Diff
391 lines
14 KiB
Diff
From 8eac2331ffb149d6323c8d47fbe4da146a9324db Mon Sep 17 00:00:00 2001
|
|
From: Yuvarani V <quic_yuvarani@quicinc.com>
|
|
Date: Thu, 21 Mar 2024 02:38:07 +0530
|
|
Subject: [PATCH] hostapd: Add support for parsing ML Probe request
|
|
|
|
Currently, AP responds with all Per-STA Profile,
|
|
included in MLE for a ML Probe Request.
|
|
|
|
Add support to parse link_id from ML Probe Request
|
|
and include only STA requested APs in MLE in Probe
|
|
response.
|
|
|
|
Signed-off-by: Yuvarani V <quic_yuvarani@quicinc.com>
|
|
---
|
|
src/ap/beacon.c | 43 +++++++++++++++++++++-------------
|
|
src/ap/ieee802_11.c | 6 ++---
|
|
src/ap/ieee802_11.h | 6 +++--
|
|
src/ap/ieee802_11_eht.c | 15 ++++++++++--
|
|
src/ap/wpa_auth_glue.c | 4 ++--
|
|
src/common/ieee802_11_common.c | 43 +++++++++++++++++++++++++++++-----
|
|
src/common/ieee802_11_common.h | 3 ++-
|
|
src/common/ieee802_11_defs.h | 6 +++++
|
|
8 files changed, 94 insertions(+), 32 deletions(-)
|
|
|
|
--- a/src/ap/beacon.c
|
|
+++ b/src/ap/beacon.c
|
|
@@ -43,7 +43,7 @@ static u8 * hostapd_gen_probe_resp(struc
|
|
const struct ieee80211_mgmt *req,
|
|
int is_p2p, size_t *resp_len,
|
|
const u8 *known_bss, u8 known_bss_len,
|
|
- bool ml_probe);
|
|
+ bool ml_probe, struct multi_link_data *ml_data);
|
|
|
|
static u8 * hostapd_eid_bss_load(struct hostapd_data *hapd, u8 *eid, size_t len)
|
|
{
|
|
@@ -848,7 +848,7 @@ void hostapd_gen_per_sta_profiles(struct
|
|
|
|
own_data = (struct ieee80211_mgmt *)hostapd_gen_probe_resp(hapd, NULL, false,
|
|
&own_data_len,
|
|
- NULL, 0, false);
|
|
+ NULL, 0, false, NULL);
|
|
|
|
if (own_data == NULL) {
|
|
wpa_printf(MSG_ERROR, "Error building per sta profile");
|
|
@@ -871,7 +871,7 @@ void hostapd_gen_per_sta_profiles(struct
|
|
|
|
link_data = (struct ieee80211_mgmt *)hostapd_gen_probe_resp(link_bss, NULL, false,
|
|
&link_data_len,
|
|
- NULL, 0, false);
|
|
+ NULL, 0, false, NULL);
|
|
|
|
if (link_data == NULL) {
|
|
wpa_printf(MSG_ERROR, "Couldnt generate Link STA profile");
|
|
@@ -906,7 +906,7 @@ static u8 * hostapd_gen_probe_resp(struc
|
|
const struct ieee80211_mgmt *req,
|
|
int is_p2p, size_t *resp_len,
|
|
const u8 *known_bss, u8 known_bss_len,
|
|
- bool ml_probe)
|
|
+ bool ml_probe, struct multi_link_data *ml_data)
|
|
{
|
|
struct ieee80211_mgmt *resp;
|
|
u8 *pos, *epos, *csa_pos;
|
|
@@ -986,10 +986,18 @@ static u8 * hostapd_gen_probe_resp(struc
|
|
buflen += (6 + 2 + 4 +
|
|
sizeof(struct ieee80211_240mhz_vendor_oper));
|
|
|
|
- if (hapd_probed != hapd && hapd_probed->conf->mld_ap && ml_probe)
|
|
- buflen += hostapd_eid_eht_basic_ml_len(hapd_probed,
|
|
- hapd->partner_links, true,
|
|
- WLAN_FC_STYPE_PROBE_RESP);
|
|
+ if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
|
|
+ if (hapd->conf->mld_ap) {
|
|
+ if (hapd_probed == hapd && ml_probe)
|
|
+ buflen += hostapd_eid_eht_basic_ml_len(hapd,
|
|
+ hapd->partner_links, false, WLAN_FC_STYPE_PROBE_RESP, ml_data);
|
|
+ else
|
|
+ buflen += hostapd_eid_eht_basic_ml_len(hapd, NULL, false, WLAN_FC_STYPE_PROBE_RESP, NULL);
|
|
+ }
|
|
+ if (hapd_probed != hapd && hapd_probed->conf->mld_ap && ml_probe)
|
|
+ buflen += hostapd_eid_eht_basic_ml_len(hapd_probed,
|
|
+ hapd_probed->partner_links, true, WLAN_FC_STYPE_PROBE_RESP, ml_data);
|
|
+ }
|
|
}
|
|
|
|
#endif /* CONFIG_IEEE80211BE */
|
|
@@ -1166,10 +1174,10 @@ static u8 * hostapd_gen_probe_resp(struc
|
|
if (hapd_probed == hapd && ml_probe)
|
|
pos = hostapd_eid_eht_basic_ml(hapd, pos,
|
|
hapd->partner_links, false,
|
|
- WLAN_FC_STYPE_PROBE_RESP);
|
|
+ WLAN_FC_STYPE_PROBE_RESP, ml_data);
|
|
else
|
|
pos = hostapd_eid_eht_basic_ml(hapd, pos, NULL, false,
|
|
- WLAN_FC_STYPE_PROBE_RESP);
|
|
+ WLAN_FC_STYPE_PROBE_RESP, NULL);
|
|
}
|
|
pos = hostapd_eid_eht_capab(hapd, pos, IEEE80211_MODE_AP);
|
|
pos = hostapd_eid_eht_operation(hapd, pos, IEEE80211_MODE_AP);
|
|
@@ -1178,7 +1186,7 @@ static u8 * hostapd_gen_probe_resp(struc
|
|
if (hapd_probed != hapd && hapd_probed->conf->mld_ap && ml_probe)
|
|
pos = hostapd_eid_eht_basic_ml(hapd_probed, pos,
|
|
hapd_probed->partner_links, true,
|
|
- WLAN_FC_STYPE_PROBE_RESP);
|
|
+ WLAN_FC_STYPE_PROBE_RESP, ml_data);
|
|
}
|
|
|
|
#endif /* CONFIG_IEEE80211BE */
|
|
@@ -1460,7 +1468,9 @@ void handle_probe_req(struct hostapd_dat
|
|
bool ml_probe = false;
|
|
struct hostapd_data *hapd_probed = hapd;
|
|
struct wpabuf *mlbuf = NULL;
|
|
- u8 mld_id = 0;
|
|
+ struct multi_link_data ml_data;
|
|
+
|
|
+ os_memset(&ml_data, 0, sizeof(struct multi_link_data));
|
|
|
|
if (hapd->iconf->rssi_ignore_probe_request && ssi_signal &&
|
|
ssi_signal < hapd->iconf->rssi_ignore_probe_request)
|
|
@@ -1700,17 +1710,17 @@ void handle_probe_req(struct hostapd_dat
|
|
|
|
#ifdef CONFIG_IEEE80211BE
|
|
mlbuf = ieee802_11_defrag_mle(&elems, MULTI_LINK_CONTROL_TYPE_PROBE_REQ);
|
|
- if (hapd->conf->mld_ap && mlbuf && ieee802_11_parse_ml_probe_req(mlbuf, &mld_id)) {
|
|
+ if (hapd->conf->mld_ap && mlbuf && ieee802_11_parse_ml_probe_req(mlbuf, &ml_data)) {
|
|
ml_probe = true;
|
|
/* MLD ID Probing */
|
|
- if ((hapd == hostapd_mbssid_get_tx_bss(hapd)) && mld_id) {
|
|
- if (mld_id < hapd->iface->num_bss)
|
|
- hapd_probed = hapd->iface->bss[mld_id];
|
|
+ if ((hapd == hostapd_mbssid_get_tx_bss(hapd)) && ml_data.preq.mld_id) {
|
|
+ if (ml_data.preq.mld_id < hapd->iface->num_bss)
|
|
+ hapd_probed = hapd->iface->bss[ml_data.preq.mld_id];
|
|
else {
|
|
wpa_printf(MSG_INFO,
|
|
"Ignore Probe Request from " MACSTR
|
|
" since No Matched Non-tx vap found for BSSID Index %d",
|
|
- MAC2STR(mgmt->sa), mld_id);
|
|
+ MAC2STR(mgmt->sa), ml_data.preq.mld_id);
|
|
return;
|
|
}
|
|
}
|
|
@@ -1719,7 +1729,7 @@ void handle_probe_req(struct hostapd_dat
|
|
#endif
|
|
resp = hostapd_gen_probe_resp(hapd_probed, mgmt, elems.p2p != NULL,
|
|
&resp_len, elems.mbssid_known_bss,
|
|
- elems.mbssid_known_bss_len, ml_probe);
|
|
+ elems.mbssid_known_bss_len, ml_probe, &ml_data);
|
|
if (resp == NULL)
|
|
return;
|
|
|
|
@@ -1789,7 +1799,7 @@ static u8 * hostapd_probe_resp_offloads(
|
|
"this");
|
|
|
|
/* Generate a Probe Response template for the non-P2P case */
|
|
- return hostapd_gen_probe_resp(hapd, NULL, 0, resp_len, NULL, 0, false);
|
|
+ return hostapd_gen_probe_resp(hapd, NULL, 0, resp_len, NULL, 0, false, NULL);
|
|
}
|
|
|
|
#endif /* NEED_AP_MLME */
|
|
@@ -1820,7 +1830,7 @@ u8 *hostapd_unsol_bcast_probe_resp(struc
|
|
|
|
return hostapd_gen_probe_resp(hapd, NULL, 0,
|
|
&ubpr->unsol_bcast_probe_resp_tmpl_len,
|
|
- NULL, 0, false);
|
|
+ NULL, 0, false, NULL);
|
|
}
|
|
#endif /* CONFIG_IEEE80211AX */
|
|
|
|
@@ -2469,7 +2479,7 @@ int ieee802_11_build_ap_params(struct ho
|
|
if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
|
|
if (hapd->conf->mld_ap)
|
|
tailpos = hostapd_eid_eht_basic_ml(hapd, tailpos, NULL,
|
|
- false, WLAN_FC_STYPE_BEACON);
|
|
+ false, WLAN_FC_STYPE_BEACON, NULL);
|
|
tailpos = hostapd_eid_eht_capab(hapd, tailpos,
|
|
IEEE80211_MODE_AP);
|
|
startpos = tailpos;
|
|
--- a/src/ap/ieee802_11.c
|
|
+++ b/src/ap/ieee802_11.c
|
|
@@ -5128,7 +5128,7 @@ rsnxe_done:
|
|
if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
|
|
if (hapd->conf->mld_ap && sta->mld_info.mld_sta)
|
|
p = hostapd_eid_eht_basic_ml(hapd, p, sta->mld_info.links, false,
|
|
- WLAN_FC_STYPE_ASSOC_RESP);
|
|
+ WLAN_FC_STYPE_ASSOC_RESP, NULL);
|
|
p = hostapd_eid_eht_capab(hapd, p, IEEE80211_MODE_AP);
|
|
p = hostapd_eid_eht_operation(hapd, p, IEEE80211_MODE_AP);
|
|
p = hostapd_eid_vendor_240mhz(hapd, p, IEEE80211_MODE_AP);
|
|
@@ -8750,7 +8750,7 @@ static size_t hostapd_eid_mbssid_elem_le
|
|
/* For ML Probe resp, solicited hapd's MLE will be in the frame body */
|
|
if (bss->conf->mld_ap && (bss != hapd_probed || !ml_probe))
|
|
nontx_profile_len += hostapd_eid_eht_basic_ml_len(bss, NULL, true,
|
|
- frame_type);
|
|
+ frame_type, NULL);
|
|
#endif /* CONFIG_IEEE80211BE */
|
|
|
|
if (ie_count || ext_ie_count) {
|
|
@@ -8932,7 +8932,7 @@ static u8 * hostapd_eid_mbssid_elem(stru
|
|
#ifdef CONFIG_IEEE80211BE
|
|
/* For ML Probe resp, solicited hapd's MLE will be in the frame body */
|
|
if (bss->conf->mld_ap && (bss != hapd_probed || !ml_probe))
|
|
- eid = hostapd_eid_eht_basic_ml(bss, eid, NULL, true, frame_type);
|
|
+ eid = hostapd_eid_eht_basic_ml(bss, eid, NULL, true, frame_type, NULL);
|
|
#endif /* CONFIG_IEEE80211BE */
|
|
if (ie_count || ext_ie_count) {
|
|
*eid++ = WLAN_EID_EXTENSION;
|
|
--- a/src/ap/ieee802_11.h
|
|
+++ b/src/ap/ieee802_11.h
|
|
@@ -102,10 +102,12 @@ void hostapd_get_eht_capab(struct hostap
|
|
size_t len);
|
|
u8 * hostapd_eid_eht_basic_ml(struct hostapd_data *hapd, u8 *eid,
|
|
struct mld_link_info *link_info,
|
|
- bool include_mld_id, u32 type);
|
|
+ bool include_mld_id, u32 type,
|
|
+ struct multi_link_data *ml_data);
|
|
size_t hostapd_eid_eht_basic_ml_len(struct hostapd_data *hapd,
|
|
struct mld_link_info *info,
|
|
- bool include_mld_id, u32 type);
|
|
+ bool include_mld_id, u32 type,
|
|
+ struct multi_link_data *ml_data);
|
|
struct wpabuf * hostapd_ml_auth_resp(struct hostapd_data *hapd);
|
|
const u8 * hostapd_process_ml_auth(struct hostapd_data *hapd,
|
|
const struct ieee80211_mgmt *mgmt,
|
|
--- a/src/ap/ieee802_11_eht.c
|
|
+++ b/src/ap/ieee802_11_eht.c
|
|
@@ -601,7 +601,8 @@ void hostapd_get_eht_capab(struct hostap
|
|
*/
|
|
#define MLE_COMMON_INFO_LEN 13
|
|
u8 * hostapd_eid_eht_basic_ml(struct hostapd_data *hapd, u8 *eid,
|
|
- struct mld_link_info *info, bool include_mld_id, u32 type)
|
|
+ struct mld_link_info *info, bool include_mld_id, u32 type,
|
|
+ struct multi_link_data *ml_data)
|
|
{
|
|
struct wpabuf *buf;
|
|
u16 control, mld_cap;
|
|
@@ -707,6 +708,11 @@ u8 * hostapd_eid_eht_basic_ml(struct hos
|
|
struct mld_link_info *link = &info[link_id];
|
|
struct hostapd_data *link_bss;
|
|
|
|
+ if (ml_data) {
|
|
+ if (!(ml_data->preq.link_bmap & BIT(link_id)))
|
|
+ continue;
|
|
+ }
|
|
+
|
|
/*
|
|
* control (2) + station info length (1) + MAC address (6) +
|
|
* beacon interval (2) + TSF offset (8) + DTIM info (2) + BSS
|
|
@@ -850,7 +856,8 @@ out:
|
|
*/
|
|
size_t hostapd_eid_eht_basic_ml_len(struct hostapd_data *hapd,
|
|
struct mld_link_info *info,
|
|
- bool include_mld_id, u32 type)
|
|
+ bool include_mld_id, u32 type,
|
|
+ struct multi_link_data *ml_data)
|
|
{
|
|
int link_id;
|
|
size_t len, num_frags;
|
|
@@ -879,6 +886,10 @@ size_t hostapd_eid_eht_basic_ml_len(stru
|
|
struct mld_link_info *link = &info[link_id];
|
|
struct hostapd_data *link_bss;
|
|
|
|
+ if (ml_data) {
|
|
+ if (!(ml_data->preq.link_bmap & BIT(link_id)))
|
|
+ continue;
|
|
+ }
|
|
size_t sta_prof_len = MLE_STA_INFO_LENGTH + link->resp_sta_profile_len;
|
|
|
|
/* Add BSS Parameters Change Count in per STA for (Re)Assoc resp */
|
|
--- a/src/ap/wpa_auth_glue.c
|
|
+++ b/src/ap/wpa_auth_glue.c
|
|
@@ -1566,7 +1566,7 @@ static u8 *hostapd_wpa_ft_add_bmle(void
|
|
{
|
|
struct hostapd_data *hapd = ctx;
|
|
|
|
- return hostapd_eid_eht_basic_ml(hapd, bmle_ie, NULL, true, WLAN_FC_STYPE_AUTH);
|
|
+ return hostapd_eid_eht_basic_ml(hapd, bmle_ie, NULL, true, WLAN_FC_STYPE_AUTH, NULL);
|
|
}
|
|
|
|
|
|
@@ -1574,7 +1574,7 @@ static size_t hostapd_wpa_ft_add_bmle_le
|
|
{
|
|
struct hostapd_data *hapd = ctx;
|
|
|
|
- return hostapd_eid_eht_basic_ml_len(hapd, NULL, true, WLAN_FC_STYPE_AUTH);
|
|
+ return hostapd_eid_eht_basic_ml_len(hapd, NULL, true, WLAN_FC_STYPE_AUTH, NULL);
|
|
}
|
|
|
|
|
|
--- a/src/common/ieee802_11_common.c
|
|
+++ b/src/common/ieee802_11_common.c
|
|
@@ -1070,10 +1070,11 @@ void ieee802_11_elems_clear_ext_ids(stru
|
|
}
|
|
}
|
|
|
|
-bool ieee802_11_parse_ml_probe_req(struct wpabuf *mlbuf, u8 *mld_id)
|
|
+bool ieee802_11_parse_ml_probe_req(struct wpabuf *mlbuf, struct multi_link_data *ml_data)
|
|
{
|
|
const struct ieee80211_eht_ml *ml;
|
|
const u8 *pos;
|
|
+ const struct element *sub;
|
|
size_t len, cmn_info_len;
|
|
u16 ml_control;
|
|
|
|
@@ -1095,21 +1096,51 @@ bool ieee802_11_parse_ml_probe_req(struc
|
|
return false;
|
|
}
|
|
|
|
- cmn_info_len = pos;
|
|
pos += sizeof(ml->ml_control);
|
|
+ cmn_info_len = *pos;
|
|
if (ml_control & EHT_ML_PRES_BM_PROBE_REQ_AP_MLD_ID) {
|
|
if (cmn_info_len < 2) {
|
|
wpa_printf(MSG_DEBUG,
|
|
"MLD: ML probe req too short for MLD ID");
|
|
return false;
|
|
}
|
|
- if (mld_id != NULL)
|
|
- *mld_id = *(pos + 1);
|
|
+ ml_data->preq.mld_id = *(pos + 1);
|
|
}
|
|
- /* TODO parse the ML probe request and send response accordingly
|
|
- * Currently if ML probe request is sent, we support sending all
|
|
- * link's profile in the ML probe response
|
|
- */
|
|
+ pos += cmn_info_len;
|
|
+ len = len - cmn_info_len - sizeof(ml->ml_control);
|
|
+
|
|
+ /* Link Info not present, send response for all affiliated AP in this MLD */
|
|
+ if (!len) {
|
|
+ ml_data->preq.link_bmap = 0xffff;
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ /* Parse subelements */
|
|
+ for_each_element_id(sub, 0, pos, len) {
|
|
+ const struct ieee80211_eht_per_sta_profile *sta;
|
|
+ u16 sta_control;
|
|
+
|
|
+ if (sub->datalen <
|
|
+ sizeof(struct ieee80211_eht_per_sta_profile)) {
|
|
+ ml_data->preq.link_bmap = 0xffff;
|
|
+ wpa_printf(MSG_DEBUG,
|
|
+ "MLD: ML probe req %d too short for sta profile",
|
|
+ sub->datalen);
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ sta = (struct ieee80211_eht_per_sta_profile *) sub->data;
|
|
+
|
|
+ sta_control = le_to_host16(sta->sta_control);
|
|
+ ml_data->preq.link_bmap |= BIT(sta_control & EHT_PER_STA_CTRL_LINK_ID_MSK);
|
|
+ }
|
|
+
|
|
+ if (!for_each_element_completed(sub, pos, len)) {
|
|
+ wpa_printf(MSG_DEBUG,
|
|
+ "MLD: ML probe req sub-elements parsing error");
|
|
+ return false;
|
|
+ }
|
|
+
|
|
return true;
|
|
}
|
|
|
|
--- a/src/common/ieee802_11_common.h
|
|
+++ b/src/common/ieee802_11_common.h
|
|
@@ -228,7 +228,8 @@ void ieee802_11_elems_clear_ids(struct i
|
|
const u8 *ids, size_t num);
|
|
void ieee802_11_elems_clear_ext_ids(struct ieee802_11_elems *elems,
|
|
const u8 *ids, size_t num);
|
|
-bool ieee802_11_parse_ml_probe_req(struct wpabuf *mlbuf, u8 *mld_id);
|
|
+bool ieee802_11_parse_ml_probe_req(struct wpabuf *mlbuf,
|
|
+ struct multi_link_data *ml_data);
|
|
ParseRes ieee802_11_parse_link_assoc_req(const u8 *start, size_t len,
|
|
struct ieee802_11_elems *elems,
|
|
struct wpabuf *mlbuf,
|
|
--- a/src/common/ieee802_11_defs.h
|
|
+++ b/src/common/ieee802_11_defs.h
|
|
@@ -2786,6 +2786,13 @@ struct ieee80211_eht_ml {
|
|
u8 variable[];
|
|
} STRUCT_PACKED;
|
|
|
|
+struct multi_link_data {
|
|
+ struct multi_link_preq_info {
|
|
+ u8 mld_id;
|
|
+ u16 link_bmap;
|
|
+ } preq;
|
|
+};
|
|
+
|
|
/* Table 9-401c - Optional subelement IDs for Link Info field of the
|
|
* Multi-Link element */
|
|
enum ieee80211_eht_ml_sub_elem {
|