diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 92293dc88..46b7a4781 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -918,6 +918,7 @@ struct hostapd_bss_config { u8 rnr; char *config_id; + bool xrates_supported; }; /** diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 20073a6c2..a0f865a7b 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -91,6 +91,29 @@ int hostapd_for_each_interface(struct hapd_interfaces *interfaces, } +struct hostapd_data * hostapd_mbssid_get_tx_bss(struct hostapd_data *hapd) +{ + if (hapd->iconf->mbssid) + return hapd->iface->bss[0]; + + return hapd; +} + + +int hostapd_mbssid_get_bss_index(struct hostapd_data *hapd) +{ + if (hapd->iconf->mbssid) { + size_t i; + + for (i = 1; i < hapd->iface->num_bss; i++) + if (hapd->iface->bss[i] == hapd) + return i; + } + + return 0; +} + + void hostapd_reconfig_encryption(struct hostapd_data *hapd) { if (hapd->wpa_auth) diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index e945a211e..ed2ff4587 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -749,5 +749,7 @@ void fst_hostapd_fill_iface_obj(struct hostapd_data *hapd, #endif /* CONFIG_FST */ int hostapd_set_acl(struct hostapd_data *hapd); +struct hostapd_data * hostapd_mbssid_get_tx_bss(struct hostapd_data *hapd); +int hostapd_mbssid_get_bss_index(struct hostapd_data *hapd); #endif /* HOSTAPD_H */ diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 5ed91b4f3..756f3af9b 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -162,6 +162,7 @@ u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid) int i, num, count; int h2e_required; + hapd->conf->xrates_supported = false; if (hapd->iface->current_rates == NULL) return eid; @@ -211,6 +212,7 @@ u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid) *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY; } + hapd->conf->xrates_supported = true; return pos; } @@ -6726,12 +6728,14 @@ u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type) static size_t hostapd_eid_mbssid_elem_len(struct hostapd_data *hapd, u32 frame_type, size_t *bss_index) { + struct hostapd_data *tx_bss = hostapd_mbssid_get_tx_bss(hapd); size_t len = 3, i; for (i = *bss_index; i < hapd->iface->num_bss; i++) { struct hostapd_data *bss = hapd->iface->bss[i]; - const u8 *auth, *rsn, *rsnx; + const u8 *auth, *rsn = NULL, *rsnx = NULL; size_t nontx_profile_len, auth_len; + u8 ie_count = 0; if (!bss || !bss->conf || !bss->started) continue; @@ -6759,6 +6763,16 @@ static size_t hostapd_eid_mbssid_elem_len(struct hostapd_data *hapd, if (rsnx) nontx_profile_len += 2 + rsnx[1]; } + if (!rsn && hostapd_wpa_ie(tx_bss, WLAN_EID_RSN)) + ie_count++; + if (!rsnx && hostapd_wpa_ie(tx_bss, WLAN_EID_RSNX)) + ie_count++; + if (bss->conf->xrates_supported) + nontx_profile_len += 8; + else if (hapd->conf->xrates_supported) + ie_count++; + if (ie_count) + nontx_profile_len += 4 + ie_count; if (len + nontx_profile_len > 255) break; @@ -6805,6 +6819,7 @@ static u8 * hostapd_eid_mbssid_elem(struct hostapd_data *hapd, u8 *eid, u8 *end, u32 frame_type, u8 max_bssid_indicator, size_t *bss_index, u8 elem_count) { + struct hostapd_data *tx_bss = hostapd_mbssid_get_tx_bss(hapd); size_t i; u8 *eid_len_offset, *max_bssid_indicator_offset; @@ -6816,7 +6831,8 @@ static u8 * hostapd_eid_mbssid_elem(struct hostapd_data *hapd, u8 *eid, u8 *end, struct hostapd_data *bss = hapd->iface->bss[i]; struct hostapd_bss_config *conf; u8 *eid_len_pos, *nontx_bss_start = eid; - const u8 *auth, *rsn, *rsnx; + const u8 *auth, *rsn = NULL, *rsnx = NULL; + u8 ie_count = 0, non_inherit_ie[3]; size_t auth_len = 0; u16 capab_info; @@ -6868,6 +6884,21 @@ static u8 * hostapd_eid_mbssid_elem(struct hostapd_data *hapd, u8 *eid, u8 *end, eid += 2 + rsnx[1]; } } + if (!rsn && hostapd_wpa_ie(tx_bss, WLAN_EID_RSN)) + non_inherit_ie[ie_count++] = WLAN_EID_RSN; + if (!rsnx && hostapd_wpa_ie(tx_bss, WLAN_EID_RSNX)) + non_inherit_ie[ie_count++] = WLAN_EID_RSNX; + if (hapd->conf->xrates_supported && + !bss->conf->xrates_supported) + non_inherit_ie[ie_count++] = WLAN_EID_EXT_SUPP_RATES; + if (ie_count) { + *eid++ = WLAN_EID_EXTENSION; + *eid++ = 2 + ie_count; + *eid++ = WLAN_EID_EXT_NON_INHERITANCE; + *eid++ = ie_count; + os_memcpy(eid, non_inherit_ie, ie_count); + eid += ie_count; + } *eid_len_pos = (eid - eid_len_pos) - 1; diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index 023bbc332..ed0051e7b 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -481,6 +481,7 @@ #define WLAN_EID_EXT_SPATIAL_REUSE 39 #define WLAN_EID_EXT_COLOR_CHANGE_ANNOUNCEMENT 42 #define WLAN_EID_EXT_OCV_OCI 54 +#define WLAN_EID_EXT_NON_INHERITANCE 56 #define WLAN_EID_EXT_SHORT_SSID_LIST 58 #define WLAN_EID_EXT_HE_6GHZ_BAND_CAP 59 #define WLAN_EID_EXT_EDMG_CAPABILITIES 61