From f3fa24d9bd04ed37674f896213d037ecca463507 Mon Sep 17 00:00:00 2001 From: Aloka Dixit Date: Fri, 23 Oct 2020 14:52:24 -0700 Subject: [PATCH] hostapd: Fixes in EMA beacon transmission offload (1) CSA failure: Fixed by initiating CSA for all BSSes on a radio. Each VAP has an assigned channel context in mac80211. Initiating CSA on only one transmitted VAP results in unequal number of assigned and reserved contexts. (2) This change adds non-inheritance element only if transmitted VAP is secure but non-transmitted is open, and calculates the length of multiple BSSID element accordingly. Signed-off-by: Aloka Dixit --- hostapd/ctrl_iface.c | 3 --- src/ap/beacon.c | 9 +++------ src/ap/ieee802_11.c | 19 +++++++++++++------ src/ap/ieee802_11_shared.c | 28 +++++++++++++++++++++++----- 4 files changed, 39 insertions(+), 20 deletions(-) Index: hostapd-2021-02-20/hostapd/ctrl_iface.c =================================================================== --- hostapd-2021-02-20.orig/hostapd/ctrl_iface.c +++ hostapd-2021-02-20/hostapd/ctrl_iface.c @@ -2759,9 +2759,6 @@ static int hostapd_ctrl_iface_chan_switc * submitting multi-BSS CSA requests? */ return ret; } - - if (iface->bss[i]->iconf->multiple_bssid) - break; } return 0; Index: hostapd-2021-02-20/src/ap/beacon.c =================================================================== --- hostapd-2021-02-20.orig/src/ap/beacon.c +++ hostapd-2021-02-20/src/ap/beacon.c @@ -434,7 +434,7 @@ static u8 * hostapd_gen_probe_resp(struc { struct hostapd_data *hidden = NULL; struct ieee80211_mgmt *resp; - u8 *pos, *epos, *csa_pos, *ext_cap_pos; + u8 *pos, *epos, *csa_pos; size_t buflen; if (hapd->iconf->multiple_bssid && @@ -566,10 +566,7 @@ static u8 * hostapd_gen_probe_resp(struc pos = hostapd_eid_ht_capabilities(hapd, pos); pos = hostapd_eid_ht_operation(hapd, pos); - ext_cap_pos = pos; pos = hostapd_eid_ext_capab(hapd, pos); - if ((pos - ext_cap_pos >= 13) && (ext_cap_pos[12] & 0x08)) - ext_cap_pos[12] |= 0x01; pos = hostapd_eid_time_adv(hapd, pos); pos = hostapd_eid_time_zone(hapd, pos); @@ -1834,9 +1831,9 @@ int ieee802_11_build_ap_params(struct ho MULTIPLE_BSSID_IE_MAX, hapd->iconf->ema_beacon); params->multiple_bssid_ie_len = end - params->multiple_bssid_ies; - if ((params->multiple_bssid_ie_count <= 1) && + if ((params->multiple_bssid_ie_count > 1) && (ext_cap_len >= 13) && (ext_cap_pos[12] & 0x08)) - ext_cap_pos[12] |= 0x01; + ext_cap_pos[12] &= ~0x01; /* Clear bit 80 */ params->dtim_period = hapd->conf->dtim_period; } Index: hostapd-2021-02-20/src/ap/ieee802_11.c =================================================================== --- hostapd-2021-02-20.orig/src/ap/ieee802_11.c +++ hostapd-2021-02-20/src/ap/ieee802_11.c @@ -167,6 +167,7 @@ u8 * hostapd_eid_ext_supp_rates(struct h int i, num, count; int h2e_required; + hapd->conf->xrates_supported = 0; if (hapd->iface->current_rates == NULL) return eid; @@ -216,6 +217,7 @@ u8 * hostapd_eid_ext_supp_rates(struct h *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY; } + hapd->conf->xrates_supported = 1; return pos; } @@ -7081,6 +7083,13 @@ static int hostapd_eid_multiple_bssid_ch if (wpa_auth_get_wpa_ie(bss->wpa_auth, &ies_len)) nontx_profile_len += ies_len; + else if (wpa_auth_get_wpa_ie(hapd->wpa_auth, &ies_len)) + nontx_profile_len += 8; /* Non-inheritance element */ + + if (bss->conf->xrates_supported) + nontx_profile_len += 8; /*ext supp rates*/ + else if (hapd->conf->xrates_supported) + nontx_profile_len += 3; /* Non-inheritance element for xrates */ if (len + nontx_profile_len > 255) { goto multiple_bssid_too_big; @@ -7117,7 +7126,8 @@ static u8 * hostapd_eid_multiple_bssid_c struct hostapd_data *bss; struct hostapd_bss_config *conf; u8 *size_offset, *num_offset; - int i; + int i, ie_count = 0; + u8 non_inherit_ie[3] = {0}; *eid++ = WLAN_EID_MULTIPLE_BSSID; size_offset = eid++; @@ -7126,8 +7136,9 @@ static u8 * hostapd_eid_multiple_bssid_c for (i = *count; i < hapd->iface->num_bss; i++) { bss = hapd->iface->bss[i]; conf = bss->conf; - u8 *bss_size_offset, *index_size_offset, *pos = eid, *rsn; + u8 *bss_size_offset, *index_size_offset, *pos = eid; u16 capab_info; + ie_count = 0; *eid++ = WLAN_EID_SUBELEMENT_NONTRANSMITTED_BSSID_PROFILE; bss_size_offset = eid++; @@ -7161,17 +7172,38 @@ static u8 * hostapd_eid_multiple_bssid_c } *index_size_offset = (eid - index_size_offset) - 1; - rsn = hostapd_get_rsne(bss, eid, end - eid); - if (rsn == eid) { - /* add RSN non-inheritance IE */ + eid = hostapd_get_rsne(bss, eid, end - eid); + eid = hostapd_get_rsnxe(bss, eid, end - eid); + eid = hostapd_eid_ext_supp_rates(bss, eid); + + /* Add non inheritance ie for capabalities that + * are not inherited by non tx vap from tx vap + */ + + if (hostapd_wpa_ie(hapd, WLAN_EID_RSN) && + !hostapd_wpa_ie(bss, WLAN_EID_RSN)) { + non_inherit_ie[ie_count] = WLAN_EID_RSN; + ie_count++; + } + + if (hapd->conf->xrates_supported && + !bss->conf->xrates_supported) { + non_inherit_ie[ie_count] = WLAN_EID_EXT_SUPP_RATES; + ie_count++; + } + if (hostapd_wpa_ie(hapd, WLAN_EID_RSNX) && + !hostapd_wpa_ie(bss, WLAN_EID_RSNX)) { + non_inherit_ie[ie_count] = WLAN_EID_RSNX; + ie_count++; + } + + if (ie_count) { *eid++ = WLAN_EID_EXTENSION; - *eid++ = 3; + *eid++ = 2 + ie_count; *eid++ = WLAN_EID_EXT_NON_INHERITANCE; - *eid++ = 1; - *eid++ = WLAN_EID_RSN; - } else { - eid = rsn; - eid = hostapd_get_rsnxe(bss, eid, end - eid); + *eid++ = ie_count; + os_memcpy(eid, non_inherit_ie, ie_count); + eid += ie_count; } *bss_size_offset = (eid - bss_size_offset) - 1; Index: hostapd-2021-02-20/src/ap/ieee802_11_shared.c =================================================================== --- hostapd-2021-02-20.orig/src/ap/ieee802_11_shared.c +++ hostapd-2021-02-20/src/ap/ieee802_11_shared.c @@ -427,9 +427,13 @@ static void hostapd_ext_capab_byte(struc * Identifiers Used Exclusively */ } #endif /* CONFIG_SAE */ - /* Bit 83 - EMA AP Support */ - if (hapd->iconf->ema_beacon) - *pos |= 0x08; + if (hapd->iconf->multiple_bssid) { + /* Bit 80 - Complete list of non-transmitted profiles */ + *pos |= 0x01; + /* Bit 83 - EMA AP Support */ + if (hapd->iconf->ema_beacon) + *pos |= 0x08; + } if (hapd->conf->beacon_prot && (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_BEACON_PROTECTION)) @@ -447,6 +451,16 @@ static void hostapd_ext_capab_byte(struc } +void hostapd_eid_ext_capab_multiple_bssid(struct hostapd_data *hapd, u8 *eid, + u8 len) +{ + if (!hapd->iconf->ema_beacon && (len >= 11)) + eid[10] &= 0xF7; + if (!hapd->iconf->multiple_bssid && (len >= 3)) + eid[2] &= 0xBF; +} + + u8 * hostapd_eid_ext_capab(struct hostapd_data *hapd, u8 *eid) { u8 *pos = eid; @@ -459,7 +473,8 @@ u8 * hostapd_eid_ext_capab(struct hostap (hapd->conf->time_advertisement == 2 || hapd->conf->interworking)) len = 4; if (len < 3 && - (hapd->conf->wnm_sleep_mode || hapd->conf->bss_transition)) + (hapd->conf->wnm_sleep_mode || hapd->conf->bss_transition || + hapd->iconf->multiple_bssid)) len = 3; if (len < 1 && (hapd->iconf->obss_interval || @@ -501,7 +516,7 @@ u8 * hostapd_eid_ext_capab(struct hostap hostapd_sae_pw_id_in_use(hapd->conf)) len = 11; #endif /* CONFIG_SAE */ - if (len < 11 && (hapd->conf->beacon_prot || hapd->iconf->ema_beacon) && + if (len < 11 && (hapd->conf->beacon_prot || hapd->iconf->multiple_bssid) && (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_BEACON_PROTECTION)) len = 11; #ifdef CONFIG_SAE_PK @@ -526,6 +541,8 @@ u8 * hostapd_eid_ext_capab(struct hostap } } + hostapd_eid_ext_capab_multiple_bssid(hapd, eid + 2, len); + while (len > 0 && eid[1 + len] == 0) { len--; eid[1] = len; Index: hostapd-2021-02-20/src/ap/ap_config.h =================================================================== --- hostapd-2021-02-20.orig/src/ap/ap_config.h +++ hostapd-2021-02-20/src/ap/ap_config.h @@ -534,6 +534,7 @@ struct hostapd_bss_config { bool disable_11n; bool disable_11ac; bool disable_11ax; + bool xrates_supported; /* IEEE 802.11v */ int time_advertisement;