AP MLD: Process link info when handling new STA event with driver SME

When association is handled in hostapd, a non-AP MLD's info is stored in
all valid links. This should be the same when SME is offloaded to the
driver.

Also skip some operations that are already done by the driver
when SME is offloaded.

Signed-off-by: Chenming Huang <quic_chenhuan@quicinc.com>
This commit is contained in:
Chenming Huang 2023-11-21 11:42:29 +05:30 committed by Jouni Malinen
parent 6a91e3608f
commit 03e89de47b
3 changed files with 63 additions and 33 deletions

View file

@ -856,6 +856,16 @@ skip_wpa_check:
} }
#endif /* CONFIG_IEEE80211R_AP || CONFIG_FILS */ #endif /* CONFIG_IEEE80211R_AP || CONFIG_FILS */
#ifdef CONFIG_IEEE80211BE
if (hostapd_process_assoc_ml_info(hapd, sta, req_ies, req_ies_len,
!!reassoc, WLAN_STATUS_SUCCESS,
true)) {
status = WLAN_STATUS_UNSPECIFIED_FAILURE;
reason = WLAN_REASON_UNSPECIFIED;
goto fail;
}
#endif /* CONFIG_IEEE80211BE */
new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0; new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC; sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
sta->flags &= ~WLAN_STA_WNM_SLEEP_MODE; sta->flags &= ~WLAN_STA_WNM_SLEEP_MODE;

View file

@ -4381,11 +4381,11 @@ out:
} }
static void ieee80211_ml_process_link(struct hostapd_data *hapd, static int ieee80211_ml_process_link(struct hostapd_data *hapd,
struct sta_info *origin_sta, struct sta_info *origin_sta,
struct mld_link_info *link, struct mld_link_info *link,
const u8 *ies, size_t ies_len, const u8 *ies, size_t ies_len,
bool reassoc) bool reassoc, bool offload)
{ {
struct ieee802_11_elems elems; struct ieee802_11_elems elems;
struct wpabuf *mlbuf = NULL; struct wpabuf *mlbuf = NULL;
@ -4448,20 +4448,22 @@ static void ieee80211_ml_process_link(struct hostapd_data *hapd,
li->resp_sta_profile_len = 0; li->resp_sta_profile_len = 0;
} }
/* if (!offload) {
* Get the AID from the station on which the association was performed, /*
* and mark it as used. * Get the AID from the station on which the association was
*/ * performed, and mark it as used.
sta->aid = origin_sta->aid; */
if (sta->aid == 0) { sta->aid = origin_sta->aid;
wpa_printf(MSG_DEBUG, "MLD: link: No AID assigned"); if (sta->aid == 0) {
status = WLAN_STATUS_UNSPECIFIED_FAILURE; wpa_printf(MSG_DEBUG, "MLD: link: No AID assigned");
goto out; status = WLAN_STATUS_UNSPECIFIED_FAILURE;
goto out;
}
hapd->sta_aid[(sta->aid - 1) / 32] |= BIT((sta->aid - 1) % 32);
sta->listen_interval = origin_sta->listen_interval;
if (update_ht_state(hapd, sta) > 0)
ieee802_11_update_beacons(hapd->iface);
} }
hapd->sta_aid[(sta->aid - 1) / 32] |= BIT((sta->aid - 1) % 32);
sta->listen_interval = origin_sta->listen_interval;
if (update_ht_state(hapd, sta) > 0)
ieee802_11_update_beacons(hapd->iface);
/* RSN Authenticator should always be the one on the original station */ /* RSN Authenticator should always be the one on the original station */
wpa_auth_sta_deinit(sta->wpa_sm); wpa_auth_sta_deinit(sta->wpa_sm);
@ -4487,17 +4489,23 @@ static void ieee80211_ml_process_link(struct hostapd_data *hapd,
/* TODO: What other processing is required? */ /* TODO: What other processing is required? */
if (add_associated_sta(hapd, sta, reassoc)) if (!offload && add_associated_sta(hapd, sta, reassoc))
status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
out: out:
wpabuf_free(mlbuf); wpabuf_free(mlbuf);
link->status = status; link->status = status;
wpa_printf(MSG_DEBUG, "MLD: link: status=%u", status); if (!offload)
if (sta && status != WLAN_STATUS_SUCCESS) ieee80211_ml_build_assoc_resp(hapd, link);
ap_free_sta(hapd, sta);
ieee80211_ml_build_assoc_resp(hapd, link); wpa_printf(MSG_DEBUG, "MLD: link: status=%u", status);
if (status != WLAN_STATUS_SUCCESS) {
if (sta)
ap_free_sta(hapd, sta);
return -1;
}
return 0;
} }
@ -4516,16 +4524,17 @@ bool hostapd_is_mld_ap(struct hostapd_data *hapd)
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
static void hostapd_process_assoc_ml_info(struct hostapd_data *hapd, int hostapd_process_assoc_ml_info(struct hostapd_data *hapd,
struct sta_info *sta, struct sta_info *sta,
const u8 *ies, size_t ies_len, const u8 *ies, size_t ies_len,
bool reassoc, int tx_link_status) bool reassoc, int tx_link_status,
bool offload)
{ {
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
unsigned int i, j; unsigned int i, j;
if (!hostapd_is_mld_ap(hapd)) if (!hostapd_is_mld_ap(hapd))
return; return 0;
/* /*
* This is not really needed, but make the interaction with the RSN * This is not really needed, but make the interaction with the RSN
@ -4561,17 +4570,23 @@ static void hostapd_process_assoc_ml_info(struct hostapd_data *hapd,
"MLD: No link match for link_id=%u", i); "MLD: No link match for link_id=%u", i);
link->status = WLAN_STATUS_UNSPECIFIED_FAILURE; link->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
ieee80211_ml_build_assoc_resp(hapd, link); if (!offload)
ieee80211_ml_build_assoc_resp(hapd, link);
} else if (tx_link_status != WLAN_STATUS_SUCCESS) { } else if (tx_link_status != WLAN_STATUS_SUCCESS) {
/* TX link rejected the connection */ /* TX link rejected the connection */
link->status = WLAN_STATUS_DENIED_TX_LINK_NOT_ACCEPTED; link->status = WLAN_STATUS_DENIED_TX_LINK_NOT_ACCEPTED;
ieee80211_ml_build_assoc_resp(hapd, link); if (!offload)
ieee80211_ml_build_assoc_resp(hapd, link);
} else { } else {
ieee80211_ml_process_link(iface->bss[0], sta, link, if (ieee80211_ml_process_link(iface->bss[0], sta, link,
ies, ies_len, reassoc); ies, ies_len, reassoc,
offload))
return -1;
} }
} }
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
return 0;
} }
@ -5588,7 +5603,7 @@ static void handle_assoc(struct hostapd_data *hapd,
*/ */
if (sta) if (sta)
hostapd_process_assoc_ml_info(hapd, sta, pos, left, reassoc, hostapd_process_assoc_ml_info(hapd, sta, pos, left, reassoc,
resp); resp, false);
if (resp == WLAN_STATUS_SUCCESS && sta && if (resp == WLAN_STATUS_SUCCESS && sta &&
add_associated_sta(hapd, sta, reassoc)) add_associated_sta(hapd, sta, reassoc))

View file

@ -258,5 +258,10 @@ const char * sae_get_password(struct hostapd_data *hapd,
struct sta_info * hostapd_ml_get_assoc_sta(struct hostapd_data *hapd, struct sta_info * hostapd_ml_get_assoc_sta(struct hostapd_data *hapd,
struct sta_info *sta, struct sta_info *sta,
struct hostapd_data **assoc_hapd); struct hostapd_data **assoc_hapd);
int hostapd_process_assoc_ml_info(struct hostapd_data *hapd,
struct sta_info *sta,
const u8 *ies, size_t ies_len,
bool reassoc, int tx_link_status,
bool offload);
#endif /* IEEE802_11_H */ #endif /* IEEE802_11_H */