AP MLD: Handle link_id in EAPOL TX status handler
Add link ID support into EAPOL TX status handler so that the events can be routed to the appropriate link BSSs. Check each BSS's other partner link BSS STA list as well in hostapd_find_by_sta() to support this. Signed-off-by: Sriram R <quic_srirrama@quicinc.com> Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
This commit is contained in:
parent
636530bc26
commit
eea52c4b51
1 changed files with 46 additions and 26 deletions
|
@ -1980,16 +1980,43 @@ static int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr)
|
||||||
|
|
||||||
|
|
||||||
static struct hostapd_data * hostapd_find_by_sta(struct hostapd_iface *iface,
|
static struct hostapd_data * hostapd_find_by_sta(struct hostapd_iface *iface,
|
||||||
const u8 *src, bool rsn)
|
const u8 *src, bool rsn,
|
||||||
|
struct sta_info **sta_ret)
|
||||||
{
|
{
|
||||||
|
struct hostapd_data *hapd;
|
||||||
struct sta_info *sta;
|
struct sta_info *sta;
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
|
|
||||||
|
if (sta_ret)
|
||||||
|
*sta_ret = NULL;
|
||||||
|
|
||||||
for (j = 0; j < iface->num_bss; j++) {
|
for (j = 0; j < iface->num_bss; j++) {
|
||||||
sta = ap_get_sta(iface->bss[j], src);
|
hapd = iface->bss[j];
|
||||||
|
sta = ap_get_sta(hapd, src);
|
||||||
if (sta && (sta->flags & WLAN_STA_ASSOC) &&
|
if (sta && (sta->flags & WLAN_STA_ASSOC) &&
|
||||||
(!rsn || sta->wpa_sm))
|
(!rsn || sta->wpa_sm)) {
|
||||||
return iface->bss[j];
|
if (sta_ret)
|
||||||
|
*sta_ret = sta;
|
||||||
|
return hapd;
|
||||||
|
}
|
||||||
|
#ifdef CONFIG_IEEE80211BE
|
||||||
|
if (hapd->conf->mld_ap) {
|
||||||
|
struct hostapd_data *p_hapd;
|
||||||
|
|
||||||
|
for_each_mld_link(p_hapd, hapd) {
|
||||||
|
if (p_hapd == hapd)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sta = ap_get_sta(p_hapd, src);
|
||||||
|
if (sta && (sta->flags & WLAN_STA_ASSOC) &&
|
||||||
|
(!rsn || sta->wpa_sm)) {
|
||||||
|
if (sta_ret)
|
||||||
|
*sta_ret = sta;
|
||||||
|
return p_hapd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_IEEE80211BE */
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2011,7 +2038,7 @@ static bool search_mld_sta(struct hostapd_data **p_hapd, const u8 *src)
|
||||||
if (!hostapd_is_ml_partner(h_hapd, hapd))
|
if (!hostapd_is_ml_partner(h_hapd, hapd))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
h_hapd = hostapd_find_by_sta(h, src, false);
|
h_hapd = hostapd_find_by_sta(h, src, false, NULL);
|
||||||
if (h_hapd) {
|
if (h_hapd) {
|
||||||
struct sta_info *sta = ap_get_sta(h_hapd, src);
|
struct sta_info *sta = ap_get_sta(h_hapd, src);
|
||||||
|
|
||||||
|
@ -2040,24 +2067,25 @@ static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src,
|
||||||
struct hostapd_data *h_hapd;
|
struct hostapd_data *h_hapd;
|
||||||
|
|
||||||
hapd = switch_link_hapd(hapd, link_id);
|
hapd = switch_link_hapd(hapd, link_id);
|
||||||
h_hapd = hostapd_find_by_sta(hapd->iface, src, true);
|
h_hapd = hostapd_find_by_sta(hapd->iface, src, true, NULL);
|
||||||
if (!h_hapd)
|
if (!h_hapd)
|
||||||
h_hapd = hostapd_find_by_sta(orig_hapd->iface, src,
|
h_hapd = hostapd_find_by_sta(orig_hapd->iface, src,
|
||||||
true);
|
true, NULL);
|
||||||
if (!h_hapd)
|
if (!h_hapd)
|
||||||
h_hapd = hostapd_find_by_sta(hapd->iface, src, false);
|
h_hapd = hostapd_find_by_sta(hapd->iface, src, false,
|
||||||
|
NULL);
|
||||||
if (!h_hapd)
|
if (!h_hapd)
|
||||||
h_hapd = hostapd_find_by_sta(orig_hapd->iface, src,
|
h_hapd = hostapd_find_by_sta(orig_hapd->iface, src,
|
||||||
false);
|
false, NULL);
|
||||||
if (h_hapd)
|
if (h_hapd)
|
||||||
hapd = h_hapd;
|
hapd = h_hapd;
|
||||||
} else if (hapd->conf->mld_ap) {
|
} else if (hapd->conf->mld_ap) {
|
||||||
search_mld_sta(&hapd, src);
|
search_mld_sta(&hapd, src);
|
||||||
} else {
|
} else {
|
||||||
hapd = hostapd_find_by_sta(hapd->iface, src, false);
|
hapd = hostapd_find_by_sta(hapd->iface, src, false, NULL);
|
||||||
}
|
}
|
||||||
#else /* CONFIG_IEEE80211BE */
|
#else /* CONFIG_IEEE80211BE */
|
||||||
hapd = hostapd_find_by_sta(hapd->iface, src, false);
|
hapd = hostapd_find_by_sta(hapd->iface, src, false, NULL);
|
||||||
#endif /* CONFIG_IEEE80211BE */
|
#endif /* CONFIG_IEEE80211BE */
|
||||||
|
|
||||||
if (!hapd) {
|
if (!hapd) {
|
||||||
|
@ -2386,23 +2414,15 @@ err:
|
||||||
|
|
||||||
#ifdef NEED_AP_MLME
|
#ifdef NEED_AP_MLME
|
||||||
static void hostapd_eapol_tx_status(struct hostapd_data *hapd, const u8 *dst,
|
static void hostapd_eapol_tx_status(struct hostapd_data *hapd, const u8 *dst,
|
||||||
const u8 *data, size_t len, int ack)
|
const u8 *data, size_t len, int ack,
|
||||||
|
int link_id)
|
||||||
{
|
{
|
||||||
struct sta_info *sta;
|
struct sta_info *sta;
|
||||||
struct hostapd_iface *iface = hapd->iface;
|
|
||||||
|
|
||||||
sta = ap_get_sta(hapd, dst);
|
hapd = switch_link_hapd(hapd, link_id);
|
||||||
if (!sta && iface->num_bss > 1) {
|
hapd = hostapd_find_by_sta(hapd->iface, dst, false, &sta);
|
||||||
size_t j;
|
|
||||||
|
|
||||||
for (j = 0; j < iface->num_bss; j++) {
|
if (!sta) {
|
||||||
hapd = iface->bss[j];
|
|
||||||
sta = ap_get_sta(hapd, dst);
|
|
||||||
if (sta)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!sta || !(sta->flags & WLAN_STA_ASSOC)) {
|
|
||||||
wpa_printf(MSG_DEBUG, "Ignore TX status for Data frame to STA "
|
wpa_printf(MSG_DEBUG, "Ignore TX status for Data frame to STA "
|
||||||
MACSTR " that is not currently associated",
|
MACSTR " that is not currently associated",
|
||||||
MAC2STR(dst));
|
MAC2STR(dst));
|
||||||
|
@ -2492,11 +2512,11 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EVENT_EAPOL_TX_STATUS:
|
case EVENT_EAPOL_TX_STATUS:
|
||||||
hapd = switch_link_hapd(hapd, data->eapol_tx_status.link_id);
|
|
||||||
hostapd_eapol_tx_status(hapd, data->eapol_tx_status.dst,
|
hostapd_eapol_tx_status(hapd, data->eapol_tx_status.dst,
|
||||||
data->eapol_tx_status.data,
|
data->eapol_tx_status.data,
|
||||||
data->eapol_tx_status.data_len,
|
data->eapol_tx_status.data_len,
|
||||||
data->eapol_tx_status.ack);
|
data->eapol_tx_status.ack,
|
||||||
|
data->eapol_tx_status.link_id);
|
||||||
break;
|
break;
|
||||||
case EVENT_DRIVER_CLIENT_POLL_OK:
|
case EVENT_DRIVER_CLIENT_POLL_OK:
|
||||||
hostapd_client_poll_ok(hapd, data->client_poll.addr);
|
hostapd_client_poll_ok(hapd, data->client_poll.addr);
|
||||||
|
|
Loading…
Reference in a new issue