AP MLD: Reduce struct mld_link_info size
Replace the fixed length maximum buffer size for STA profile with dynamically allocated buffers for active links. This reduces struct mld_link_info size by almost 16 kB and drops the per-STA information in struct sta_info to a more reasonable size to avoid the almost 10x increase from MLO support. In addition, free the resp_sta_profile buffers as soon as the ML element has bee generated for (Re)Association Response frame since those buffers are not needed after that. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
b91572b308
commit
512b925240
5 changed files with 78 additions and 33 deletions
|
@ -617,6 +617,19 @@ struct probe_resp_params {
|
|||
#endif /* CONFIG_IEEE80211AX */
|
||||
};
|
||||
|
||||
|
||||
static void hostapd_free_probe_resp_params(struct probe_resp_params *params)
|
||||
{
|
||||
#ifdef CONFIG_IEEE80211BE
|
||||
if (!params)
|
||||
return;
|
||||
ap_sta_free_sta_profile(params->mld_info);
|
||||
os_free(params->mld_info);
|
||||
params->mld_info = NULL;
|
||||
#endif /* CONFIG_IEEE80211BE */
|
||||
}
|
||||
|
||||
|
||||
static size_t hostapd_probe_resp_elems_len(struct hostapd_data *hapd,
|
||||
struct probe_resp_params *params)
|
||||
{
|
||||
|
@ -955,6 +968,7 @@ static void hostapd_fill_probe_resp_ml_params(struct hostapd_data *hapd,
|
|||
size_t buflen;
|
||||
u8 mld_link_id = link->mld_link_id;
|
||||
u8 *epos;
|
||||
u8 buf[EHT_ML_MAX_STA_PROF_LEN];
|
||||
|
||||
/*
|
||||
* Set mld_ap iff the ML probe request explicitly
|
||||
|
@ -984,7 +998,7 @@ static void hostapd_fill_probe_resp_ml_params(struct hostapd_data *hapd,
|
|||
buflen = MAX_PROBERESP_LEN;
|
||||
buflen += hostapd_probe_resp_elems_len(link, &sta_info_params);
|
||||
|
||||
if (buflen > sizeof(link_info->resp_sta_profile)) {
|
||||
if (buflen > EHT_ML_MAX_STA_PROF_LEN) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"MLD: Not including link %d in ML probe response (%zu bytes is too long)",
|
||||
mld_link_id, buflen);
|
||||
|
@ -996,18 +1010,21 @@ static void hostapd_fill_probe_resp_ml_params(struct hostapd_data *hapd,
|
|||
* various other things.
|
||||
*/
|
||||
link_info->valid = true;
|
||||
epos = link_info->resp_sta_profile;
|
||||
epos = buf;
|
||||
|
||||
/* Capabilities is the only fixed parameter */
|
||||
WPA_PUT_LE16(link_info->resp_sta_profile,
|
||||
hostapd_own_capab_info(hapd));
|
||||
WPA_PUT_LE16(epos, hostapd_own_capab_info(hapd));
|
||||
epos += 2;
|
||||
|
||||
epos = hostapd_probe_resp_fill_elems(
|
||||
link, &sta_info_params,
|
||||
link_info->resp_sta_profile + 2,
|
||||
sizeof(link_info->resp_sta_profile) - 2);
|
||||
link_info->resp_sta_profile_len =
|
||||
epos - link_info->resp_sta_profile;
|
||||
link, &sta_info_params, epos,
|
||||
EHT_ML_MAX_STA_PROF_LEN - 2);
|
||||
link_info->resp_sta_profile_len = epos - buf;
|
||||
os_free(link_info->resp_sta_profile);
|
||||
link_info->resp_sta_profile = os_memdup(
|
||||
buf, link_info->resp_sta_profile_len);
|
||||
if (!link_info->resp_sta_profile)
|
||||
link_info->resp_sta_profile_len = 0;
|
||||
os_memcpy(link_info->local_addr, link->own_addr, ETH_ALEN);
|
||||
|
||||
wpa_printf(MSG_DEBUG,
|
||||
|
@ -1026,7 +1043,7 @@ static void hostapd_fill_probe_resp_ml_params(struct hostapd_data *hapd,
|
|||
return;
|
||||
|
||||
fail:
|
||||
os_free(params->mld_info);
|
||||
hostapd_free_probe_resp_params(params);
|
||||
params->mld_ap = NULL;
|
||||
params->mld_info = NULL;
|
||||
}
|
||||
|
@ -1584,7 +1601,7 @@ void handle_probe_req(struct hostapd_data *hapd,
|
|||
|
||||
hostapd_gen_probe_resp(hapd, ¶ms);
|
||||
|
||||
os_free(params.mld_info);
|
||||
hostapd_free_probe_resp_params(¶ms);
|
||||
|
||||
if (!params.resp)
|
||||
return;
|
||||
|
|
|
@ -3078,6 +3078,7 @@ static void handle_auth(struct hostapd_data *hapd,
|
|||
|
||||
#ifdef CONFIG_IEEE80211BE
|
||||
if (auth_transaction == 1) {
|
||||
ap_sta_free_sta_profile(&sta->mld_info);
|
||||
os_memset(&sta->mld_info, 0, sizeof(sta->mld_info));
|
||||
|
||||
if (mld_sta) {
|
||||
|
@ -4319,22 +4320,23 @@ static int check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
|
|||
|
||||
#ifdef CONFIG_IEEE80211BE
|
||||
|
||||
static size_t ieee80211_ml_build_assoc_resp(struct hostapd_data *hapd,
|
||||
u16 status_code,
|
||||
u8 *buf, size_t buflen)
|
||||
static void ieee80211_ml_build_assoc_resp(struct hostapd_data *hapd,
|
||||
struct mld_link_info *link)
|
||||
{
|
||||
u8 buf[EHT_ML_MAX_STA_PROF_LEN];
|
||||
u8 *p = buf;
|
||||
size_t buflen = sizeof(buf);
|
||||
|
||||
/* Capability Info */
|
||||
WPA_PUT_LE16(p, hostapd_own_capab_info(hapd));
|
||||
p += 2;
|
||||
|
||||
/* Status Code */
|
||||
WPA_PUT_LE16(p, status_code);
|
||||
WPA_PUT_LE16(p, link->status);
|
||||
p += 2;
|
||||
|
||||
if (status_code != WLAN_STATUS_SUCCESS)
|
||||
return p - buf;
|
||||
if (link->status != WLAN_STATUS_SUCCESS)
|
||||
goto out;
|
||||
|
||||
/* AID is not included */
|
||||
p = hostapd_eid_supp_rates(hapd, p);
|
||||
|
@ -4372,7 +4374,10 @@ static size_t ieee80211_ml_build_assoc_resp(struct hostapd_data *hapd,
|
|||
p += wpabuf_len(hapd->conf->assocresp_elements);
|
||||
}
|
||||
|
||||
return p - buf;
|
||||
out:
|
||||
os_free(link->resp_sta_profile);
|
||||
link->resp_sta_profile = os_memdup(buf, p - buf);
|
||||
link->resp_sta_profile_len = link->resp_sta_profile ? p - buf : 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -4386,6 +4391,7 @@ static void ieee80211_ml_process_link(struct hostapd_data *hapd,
|
|||
struct wpabuf *mlbuf = NULL;
|
||||
struct sta_info *sta = NULL;
|
||||
u16 status = WLAN_STATUS_SUCCESS;
|
||||
int i;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "MLD: link: link_id=%u, peer=" MACSTR,
|
||||
hapd->mld_link_id, MAC2STR(link->peer_addr));
|
||||
|
@ -4435,6 +4441,12 @@ static void ieee80211_ml_process_link(struct hostapd_data *hapd,
|
|||
sta->mld_assoc_link_id = origin_sta->mld_assoc_link_id;
|
||||
|
||||
os_memcpy(&sta->mld_info, &origin_sta->mld_info, sizeof(sta->mld_info));
|
||||
for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
|
||||
struct mld_link_info *li = &sta->mld_info.links[i];
|
||||
|
||||
li->resp_sta_profile = NULL;
|
||||
li->resp_sta_profile_len = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the AID from the station on which the association was performed,
|
||||
|
@ -4485,10 +4497,7 @@ out:
|
|||
if (sta && status != WLAN_STATUS_SUCCESS)
|
||||
ap_free_sta(hapd, sta);
|
||||
|
||||
link->resp_sta_profile_len =
|
||||
ieee80211_ml_build_assoc_resp(hapd, link->status,
|
||||
link->resp_sta_profile,
|
||||
sizeof(link->resp_sta_profile));
|
||||
ieee80211_ml_build_assoc_resp(hapd, link);
|
||||
}
|
||||
|
||||
|
||||
|
@ -4552,19 +4561,11 @@ static void hostapd_process_assoc_ml_info(struct hostapd_data *hapd,
|
|||
"MLD: No link match for link_id=%u", i);
|
||||
|
||||
link->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||
link->resp_sta_profile_len =
|
||||
ieee80211_ml_build_assoc_resp(
|
||||
hapd, link->status,
|
||||
link->resp_sta_profile,
|
||||
sizeof(link->resp_sta_profile));
|
||||
ieee80211_ml_build_assoc_resp(hapd, link);
|
||||
} else if (tx_link_status != WLAN_STATUS_SUCCESS) {
|
||||
/* TX link rejected the connection */
|
||||
link->status = WLAN_STATUS_DENIED_TX_LINK_NOT_ACCEPTED;
|
||||
link->resp_sta_profile_len =
|
||||
ieee80211_ml_build_assoc_resp(
|
||||
hapd, link->status,
|
||||
link->resp_sta_profile,
|
||||
sizeof(link->resp_sta_profile));
|
||||
ieee80211_ml_build_assoc_resp(hapd, link);
|
||||
} else {
|
||||
ieee80211_ml_process_link(iface->bss[0], sta, link,
|
||||
ies, ies_len, reassoc);
|
||||
|
|
|
@ -583,6 +583,9 @@ static u8 * hostapd_eid_eht_basic_ml_common(struct hostapd_data *hapd,
|
|||
/* BSS Parameters Change Count */
|
||||
wpabuf_put_u8(buf, hapd->eht_mld_bss_param_change);
|
||||
|
||||
if (!link->resp_sta_profile)
|
||||
continue;
|
||||
|
||||
/* Fragment the sub element if needed */
|
||||
if (total_len <= 255) {
|
||||
wpabuf_put_data(buf, link->resp_sta_profile,
|
||||
|
@ -784,6 +787,7 @@ u8 * hostapd_eid_eht_ml_assoc(struct hostapd_data *hapd, struct sta_info *info,
|
|||
|
||||
eid = hostapd_eid_eht_basic_ml_common(hapd, eid, &info->mld_info,
|
||||
false);
|
||||
ap_sta_free_sta_profile(&info->mld_info);
|
||||
return hostapd_eid_eht_reconf_ml(hapd, eid);
|
||||
}
|
||||
|
||||
|
|
|
@ -350,6 +350,7 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
|
|||
#ifdef CONFIG_INTERWORKING
|
||||
if (sta->gas_dialog) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < GAS_DIALOG_MAX; i++)
|
||||
gas_serv_dialog_clear(&sta->gas_dialog[i]);
|
||||
os_free(sta->gas_dialog);
|
||||
|
@ -420,6 +421,10 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
|
|||
|
||||
os_free(sta->ifname_wds);
|
||||
|
||||
#ifdef CONFIG_IEEE80211BE
|
||||
ap_sta_free_sta_profile(&sta->mld_info);
|
||||
#endif /* CONFIG_IEEE80211BE */
|
||||
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
os_free(sta->sae_postponed_commit);
|
||||
forced_memzero(sta->last_tk, WPA_TK_MAX_LEN);
|
||||
|
@ -1791,3 +1796,19 @@ int ap_sta_re_add(struct hostapd_data *hapd, struct sta_info *sta)
|
|||
sta->added_unassoc = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_IEEE80211BE
|
||||
void ap_sta_free_sta_profile(struct mld_info *info)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
|
||||
os_free(info->links[i].resp_sta_profile);
|
||||
info->links[i].resp_sta_profile = NULL;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_IEEE80211BE */
|
||||
|
|
|
@ -93,7 +93,7 @@ struct mld_info {
|
|||
|
||||
u16 status;
|
||||
size_t resp_sta_profile_len;
|
||||
u8 resp_sta_profile[EHT_ML_MAX_STA_PROF_LEN];
|
||||
u8 *resp_sta_profile;
|
||||
|
||||
const u8 *rsne, *rsnxe;
|
||||
} links[MAX_NUM_MLD_LINKS];
|
||||
|
@ -438,4 +438,6 @@ static inline void ap_sta_set_mld(struct sta_info *sta, bool mld)
|
|||
#endif /* CONFIG_IEEE80211BE */
|
||||
}
|
||||
|
||||
void ap_sta_free_sta_profile(struct mld_info *info);
|
||||
|
||||
#endif /* STA_INFO_H */
|
||||
|
|
Loading…
Reference in a new issue