hostapd: Add ability to disable HT/VHT/HE per BSS

Add the ability to disable HT/VHT/HE for specific BSS from hostapd.conf.

- Add disable_11ax boolean to hostapd_bss_config.
- Change disable_11n and disable_11ac to bool in hostapd_bss_config.
- Add configuration option to set these disable_11* parameters
  (which were previously used only automatically based on incompatible
  security parameters to disable HT/VHT).

Signed-off-by: Shay Bar <shay.bar@celeno.com>
This commit is contained in:
Shay Bar 2020-06-30 17:23:46 +03:00 committed by Jouni Malinen
parent 89ad24379d
commit eee0d242bb
9 changed files with 37 additions and 18 deletions

View File

@ -4569,6 +4569,12 @@ static int hostapd_config_fill(struct hostapd_config *conf,
} }
bss->mka_psk_set |= MKA_PSK_SET_CKN; bss->mka_psk_set |= MKA_PSK_SET_CKN;
#endif /* CONFIG_MACSEC */ #endif /* CONFIG_MACSEC */
} else if (os_strcmp(buf, "disable_11n") == 0) {
bss->disable_11n = !!atoi(pos);
} else if (os_strcmp(buf, "disable_11ac") == 0) {
bss->disable_11ac = !!atoi(pos);
} else if (os_strcmp(buf, "disable_11ax") == 0) {
bss->disable_11ax = !!atoi(pos);
} else { } else {
wpa_printf(MSG_ERROR, wpa_printf(MSG_ERROR,
"Line %d: unknown configuration item '%s'", "Line %d: unknown configuration item '%s'",

View File

@ -580,6 +580,9 @@ wmm_ac_vo_acm=0
# Note: hw_mode=g (2.4 GHz) and hw_mode=a (5 GHz) is used to specify the band. # Note: hw_mode=g (2.4 GHz) and hw_mode=a (5 GHz) is used to specify the band.
#ieee80211n=1 #ieee80211n=1
# disable_11n: Boolean (0/1) to disable HT for a specific BSS
#disable_11n=0
# ht_capab: HT capabilities (list of flags) # ht_capab: HT capabilities (list of flags)
# LDPC coding capability: [LDPC] = supported # LDPC coding capability: [LDPC] = supported
# Supported channel width set: [HT40-] = both 20 MHz and 40 MHz with secondary # Supported channel width set: [HT40-] = both 20 MHz and 40 MHz with secondary
@ -632,6 +635,9 @@ wmm_ac_vo_acm=0
# Note: hw_mode=a is used to specify that 5 GHz band is used with VHT. # Note: hw_mode=a is used to specify that 5 GHz band is used with VHT.
#ieee80211ac=1 #ieee80211ac=1
# disable_11ac: Boolean (0/1) to disable VHT for a specific BSS
#disable_11ac=0
# vht_capab: VHT capabilities (list of flags) # vht_capab: VHT capabilities (list of flags)
# #
# vht_max_mpdu_len: [MAX-MPDU-7991] [MAX-MPDU-11454] # vht_max_mpdu_len: [MAX-MPDU-7991] [MAX-MPDU-11454]
@ -786,6 +792,9 @@ wmm_ac_vo_acm=0
# 1 = enabled # 1 = enabled
#ieee80211ax=1 #ieee80211ax=1
# disable_11ax: Boolean (0/1) to disable HE for a specific BSS
#disable_11ax=0
#he_su_beamformer: HE single user beamformer support #he_su_beamformer: HE single user beamformer support
# 0 = not supported (default) # 0 = not supported (default)
# 1 = supported # 1 = supported

View File

@ -1229,7 +1229,7 @@ static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
if (full_config && conf->ieee80211n && if (full_config && conf->ieee80211n &&
conf->hw_mode == HOSTAPD_MODE_IEEE80211B) { conf->hw_mode == HOSTAPD_MODE_IEEE80211B) {
bss->disable_11n = 1; bss->disable_11n = true;
wpa_printf(MSG_ERROR, "HT (IEEE 802.11n) in 11b mode is not " wpa_printf(MSG_ERROR, "HT (IEEE 802.11n) in 11b mode is not "
"allowed, disabling HT capabilities"); "allowed, disabling HT capabilities");
} }
@ -1237,7 +1237,7 @@ static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
#ifdef CONFIG_WEP #ifdef CONFIG_WEP
if (full_config && conf->ieee80211n && if (full_config && conf->ieee80211n &&
bss->ssid.security_policy == SECURITY_STATIC_WEP) { bss->ssid.security_policy == SECURITY_STATIC_WEP) {
bss->disable_11n = 1; bss->disable_11n = true;
wpa_printf(MSG_ERROR, "HT (IEEE 802.11n) with WEP is not " wpa_printf(MSG_ERROR, "HT (IEEE 802.11n) with WEP is not "
"allowed, disabling HT capabilities"); "allowed, disabling HT capabilities");
} }
@ -1248,7 +1248,7 @@ static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
!(bss->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP | !(bss->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP |
WPA_CIPHER_CCMP_256 | WPA_CIPHER_GCMP_256))) WPA_CIPHER_CCMP_256 | WPA_CIPHER_GCMP_256)))
{ {
bss->disable_11n = 1; bss->disable_11n = true;
wpa_printf(MSG_ERROR, "HT (IEEE 802.11n) with WPA/WPA2 " wpa_printf(MSG_ERROR, "HT (IEEE 802.11n) with WPA/WPA2 "
"requires CCMP/GCMP to be enabled, disabling HT " "requires CCMP/GCMP to be enabled, disabling HT "
"capabilities"); "capabilities");
@ -1258,7 +1258,7 @@ static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
#ifdef CONFIG_WEP #ifdef CONFIG_WEP
if (full_config && conf->ieee80211ac && if (full_config && conf->ieee80211ac &&
bss->ssid.security_policy == SECURITY_STATIC_WEP) { bss->ssid.security_policy == SECURITY_STATIC_WEP) {
bss->disable_11ac = 1; bss->disable_11ac = true;
wpa_printf(MSG_ERROR, wpa_printf(MSG_ERROR,
"VHT (IEEE 802.11ac) with WEP is not allowed, disabling VHT capabilities"); "VHT (IEEE 802.11ac) with WEP is not allowed, disabling VHT capabilities");
} }
@ -1269,7 +1269,7 @@ static int hostapd_config_check_bss(struct hostapd_bss_config *bss,
!(bss->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP | !(bss->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP |
WPA_CIPHER_CCMP_256 | WPA_CIPHER_GCMP_256))) WPA_CIPHER_CCMP_256 | WPA_CIPHER_GCMP_256)))
{ {
bss->disable_11ac = 1; bss->disable_11ac = true;
wpa_printf(MSG_ERROR, wpa_printf(MSG_ERROR,
"VHT (IEEE 802.11ac) with WPA/WPA2 requires CCMP/GCMP to be enabled, disabling VHT capabilities"); "VHT (IEEE 802.11ac) with WPA/WPA2 requires CCMP/GCMP to be enabled, disabling VHT capabilities");
} }

View File

@ -531,8 +531,9 @@ struct hostapd_bss_config {
#define TDLS_PROHIBIT BIT(0) #define TDLS_PROHIBIT BIT(0)
#define TDLS_PROHIBIT_CHAN_SWITCH BIT(1) #define TDLS_PROHIBIT_CHAN_SWITCH BIT(1)
int tdls; int tdls;
int disable_11n; bool disable_11n;
int disable_11ac; bool disable_11ac;
bool disable_11ax;
/* IEEE 802.11v */ /* IEEE 802.11v */
int time_advertisement; int time_advertisement;

View File

@ -458,7 +458,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
} }
#ifdef CONFIG_IEEE80211AX #ifdef CONFIG_IEEE80211AX
if (hapd->iconf->ieee80211ax) { if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
buflen += 3 + sizeof(struct ieee80211_he_capabilities) + buflen += 3 + sizeof(struct ieee80211_he_capabilities) +
3 + sizeof(struct ieee80211_he_operation) + 3 + sizeof(struct ieee80211_he_operation) +
3 + sizeof(struct ieee80211_he_mu_edca_parameter_set) + 3 + sizeof(struct ieee80211_he_mu_edca_parameter_set) +
@ -564,14 +564,14 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
#endif /* CONFIG_IEEE80211AC */ #endif /* CONFIG_IEEE80211AC */
if ((hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) || if ((hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) ||
hapd->iconf->ieee80211ax) (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax))
pos = hostapd_eid_wb_chsw_wrapper(hapd, pos); pos = hostapd_eid_wb_chsw_wrapper(hapd, pos);
pos = hostapd_eid_fils_indic(hapd, pos, 0); pos = hostapd_eid_fils_indic(hapd, pos, 0);
pos = hostapd_get_rsnxe(hapd, pos, epos - pos); pos = hostapd_get_rsnxe(hapd, pos, epos - pos);
#ifdef CONFIG_IEEE80211AX #ifdef CONFIG_IEEE80211AX
if (hapd->iconf->ieee80211ax) { if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
pos = hostapd_eid_he_capab(hapd, pos, IEEE80211_MODE_AP); pos = hostapd_eid_he_capab(hapd, pos, IEEE80211_MODE_AP);
pos = hostapd_eid_he_operation(hapd, pos); pos = hostapd_eid_he_operation(hapd, pos);
pos = hostapd_eid_spatial_reuse(hapd, pos); pos = hostapd_eid_spatial_reuse(hapd, pos);
@ -1163,7 +1163,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
#endif /* CONFIG_IEEE80211AC */ #endif /* CONFIG_IEEE80211AC */
#ifdef CONFIG_IEEE80211AX #ifdef CONFIG_IEEE80211AX
if (hapd->iconf->ieee80211ax) { if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
tail_len += 3 + sizeof(struct ieee80211_he_capabilities) + tail_len += 3 + sizeof(struct ieee80211_he_capabilities) +
3 + sizeof(struct ieee80211_he_operation) + 3 + sizeof(struct ieee80211_he_operation) +
3 + sizeof(struct ieee80211_he_mu_edca_parameter_set) + 3 + sizeof(struct ieee80211_he_mu_edca_parameter_set) +
@ -1288,14 +1288,14 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
#endif /* CONFIG_IEEE80211AC */ #endif /* CONFIG_IEEE80211AC */
if ((hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) || if ((hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) ||
hapd->iconf->ieee80211ax) (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax))
tailpos = hostapd_eid_wb_chsw_wrapper(hapd, tailpos); tailpos = hostapd_eid_wb_chsw_wrapper(hapd, tailpos);
tailpos = hostapd_eid_fils_indic(hapd, tailpos, 0); tailpos = hostapd_eid_fils_indic(hapd, tailpos, 0);
tailpos = hostapd_get_rsnxe(hapd, tailpos, tailend - tailpos); tailpos = hostapd_get_rsnxe(hapd, tailpos, tailend - tailpos);
#ifdef CONFIG_IEEE80211AX #ifdef CONFIG_IEEE80211AX
if (hapd->iconf->ieee80211ax) { if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
tailpos = hostapd_eid_he_capab(hapd, tailpos, tailpos = hostapd_eid_he_capab(hapd, tailpos,
IEEE80211_MODE_AP); IEEE80211_MODE_AP);
tailpos = hostapd_eid_he_operation(hapd, tailpos); tailpos = hostapd_eid_he_operation(hapd, tailpos);

View File

@ -748,7 +748,8 @@ int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf,
iface->conf->ieee80211n && !hapd->conf->disable_11n, iface->conf->ieee80211n && !hapd->conf->disable_11n,
iface->conf->ieee80211ac && iface->conf->ieee80211ac &&
!hapd->conf->disable_11ac, !hapd->conf->disable_11ac,
iface->conf->ieee80211ax, iface->conf->ieee80211ax &&
!hapd->conf->disable_11ax,
iface->conf->beacon_int, iface->conf->beacon_int,
hapd->conf->dtim_period); hapd->conf->dtim_period);
if (os_snprintf_error(buflen - len, ret)) if (os_snprintf_error(buflen - len, ret))
@ -756,7 +757,7 @@ int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf,
len += ret; len += ret;
#ifdef CONFIG_IEEE80211AX #ifdef CONFIG_IEEE80211AX
if (iface->conf->ieee80211ax) { if (iface->conf->ieee80211ax && !hapd->conf->disable_11ax) {
ret = os_snprintf(buf + len, buflen - len, ret = os_snprintf(buf + len, buflen - len,
"he_oper_chwidth=%d\n" "he_oper_chwidth=%d\n"
"he_oper_centr_freq_seg0_idx=%d\n" "he_oper_centr_freq_seg0_idx=%d\n"

View File

@ -3254,7 +3254,7 @@ static int check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
} }
#endif /* CONFIG_IEEE80211AC */ #endif /* CONFIG_IEEE80211AC */
#ifdef CONFIG_IEEE80211AX #ifdef CONFIG_IEEE80211AX
if (hapd->iconf->ieee80211ax) { if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
resp = copy_sta_he_capab(hapd, sta, IEEE80211_MODE_AP, resp = copy_sta_he_capab(hapd, sta, IEEE80211_MODE_AP,
elems.he_capabilities, elems.he_capabilities,
elems.he_capabilities_len); elems.he_capabilities_len);
@ -3870,7 +3870,7 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
#endif /* CONFIG_IEEE80211AC */ #endif /* CONFIG_IEEE80211AC */
#ifdef CONFIG_IEEE80211AX #ifdef CONFIG_IEEE80211AX
if (hapd->iconf->ieee80211ax) { if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
p = hostapd_eid_he_capab(hapd, p, IEEE80211_MODE_AP); p = hostapd_eid_he_capab(hapd, p, IEEE80211_MODE_AP);
p = hostapd_eid_he_operation(hapd, p); p = hostapd_eid_he_operation(hapd, p);
p = hostapd_eid_spatial_reuse(hapd, p); p = hostapd_eid_spatial_reuse(hapd, p);

View File

@ -419,6 +419,7 @@ u16 copy_sta_he_capab(struct hostapd_data *hapd, struct sta_info *sta,
size_t he_capab_len) size_t he_capab_len)
{ {
if (!he_capab || !hapd->iconf->ieee80211ax || if (!he_capab || !hapd->iconf->ieee80211ax ||
hapd->conf->disable_11ax ||
!check_valid_he_mcs(hapd, he_capab, opmode) || !check_valid_he_mcs(hapd, he_capab, opmode) ||
ieee80211_invalid_he_cap_size(he_capab, he_capab_len) || ieee80211_invalid_he_cap_size(he_capab, he_capab_len) ||
he_capab_len > sizeof(struct ieee80211_he_capabilities)) { he_capab_len > sizeof(struct ieee80211_he_capabilities)) {
@ -448,6 +449,7 @@ u16 copy_sta_he_6ghz_capab(struct hostapd_data *hapd, struct sta_info *sta,
const u8 *he_6ghz_capab) const u8 *he_6ghz_capab)
{ {
if (!he_6ghz_capab || !hapd->iconf->ieee80211ax || if (!he_6ghz_capab || !hapd->iconf->ieee80211ax ||
hapd->conf->disable_11ax ||
!is_6ghz_op_class(hapd->iconf->op_class)) { !is_6ghz_op_class(hapd->iconf->op_class)) {
sta->flags &= ~WLAN_STA_6GHZ; sta->flags &= ~WLAN_STA_6GHZ;
os_free(sta->he_6ghz_capab); os_free(sta->he_6ghz_capab);

View File

@ -220,7 +220,7 @@ void hostapd_neighbor_set_own_report(struct hostapd_data *hapd)
u16 capab = hostapd_own_capab_info(hapd); u16 capab = hostapd_own_capab_info(hapd);
int ht = hapd->iconf->ieee80211n && !hapd->conf->disable_11n; int ht = hapd->iconf->ieee80211n && !hapd->conf->disable_11n;
int vht = hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac; int vht = hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac;
int he = hapd->iconf->ieee80211ax; int he = hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax;
struct wpa_ssid_value ssid; struct wpa_ssid_value ssid;
u8 channel, op_class; u8 channel, op_class;
u8 center_freq1_idx = 0, center_freq2_idx = 0; u8 center_freq1_idx = 0, center_freq2_idx = 0;