diff --git a/hostapd/config_file.c b/hostapd/config_file.c index f4cd26308..4b9d09783 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -1090,17 +1090,18 @@ static int hostapd_config_check_bss(struct hostapd_bss_config *bss, #ifdef CONFIG_IEEE80211N if (conf->ieee80211n && bss->ssid.security_policy == SECURITY_STATIC_WEP) { + bss->disable_11n = 1; wpa_printf(MSG_ERROR, "HT (IEEE 802.11n) with WEP is not " - "allowed"); - return -1; + "allowed, disabling HT capabilities"); } if (conf->ieee80211n && bss->wpa && !(bss->wpa_pairwise & WPA_CIPHER_CCMP) && !(bss->rsn_pairwise & WPA_CIPHER_CCMP)) { + bss->disable_11n = 1; wpa_printf(MSG_ERROR, "HT (IEEE 802.11n) with WPA/WPA2 " - "requires CCMP to be enabled"); - return -1; + "requires CCMP to be enabled, disabling HT " + "capabilities"); } #endif /* CONFIG_IEEE80211N */ diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 8761ad25b..cdc676af2 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -328,6 +328,7 @@ struct hostapd_bss_config { #define TDLS_PROHIBIT BIT(0) #define TDLS_PROHIBIT_CHAN_SWITCH BIT(1) int tdls; + int disable_11n; }; diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 06fc701eb..45180ccb2 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -675,7 +675,7 @@ static u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta, if (resp != WLAN_STATUS_SUCCESS) return resp; #ifdef CONFIG_IEEE80211N - resp = copy_sta_ht_capab(sta, elems.ht_capabilities, + resp = copy_sta_ht_capab(hapd, sta, elems.ht_capabilities, elems.ht_capabilities_len); if (resp != WLAN_STATUS_SUCCESS) return resp; diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h index b1f009cda..157198c82 100644 --- a/src/ap/ieee802_11.h +++ b/src/ap/ieee802_11.h @@ -57,8 +57,8 @@ void ieee802_11_send_sa_query_req(struct hostapd_data *hapd, void hostapd_get_ht_capab(struct hostapd_data *hapd, struct ieee80211_ht_capabilities *ht_cap, struct ieee80211_ht_capabilities *neg_ht_cap); -u16 copy_sta_ht_capab(struct sta_info *sta, const u8 *ht_capab, - size_t ht_capab_len); +u16 copy_sta_ht_capab(struct hostapd_data *hapd, struct sta_info *sta, + const u8 *ht_capab, size_t ht_capab_len); void update_ht_state(struct hostapd_data *hapd, struct sta_info *sta); void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr, const u8 *buf, size_t len, int ack); diff --git a/src/ap/ieee802_11_ht.c b/src/ap/ieee802_11_ht.c index 7541b8381..acb85fec0 100644 --- a/src/ap/ieee802_11_ht.c +++ b/src/ap/ieee802_11_ht.c @@ -30,7 +30,8 @@ u8 * hostapd_eid_ht_capabilities(struct hostapd_data *hapd, u8 *eid) struct ieee80211_ht_capabilities *cap; u8 *pos = eid; - if (!hapd->iconf->ieee80211n || !hapd->iface->current_mode) + if (!hapd->iconf->ieee80211n || !hapd->iface->current_mode || + hapd->conf->disable_11n) return eid; *pos++ = WLAN_EID_HT_CAP; @@ -58,7 +59,7 @@ u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid) struct ieee80211_ht_operation *oper; u8 *pos = eid; - if (!hapd->iconf->ieee80211n) + if (!hapd->iconf->ieee80211n || hapd->conf->disable_11n) return eid; *pos++ = WLAN_EID_HT_OPERATION; @@ -160,11 +161,13 @@ int hostapd_ht_operation_update(struct hostapd_iface *iface) } -u16 copy_sta_ht_capab(struct sta_info *sta, const u8 *ht_capab, - size_t ht_capab_len) +u16 copy_sta_ht_capab(struct hostapd_data *hapd, struct sta_info *sta, + const u8 *ht_capab, size_t ht_capab_len) { + /* Disable HT caps for STAs associated to no-HT BSSes. */ if (!ht_capab || - ht_capab_len < sizeof(struct ieee80211_ht_capabilities)) { + ht_capab_len < sizeof(struct ieee80211_ht_capabilities) || + hapd->conf->disable_11n) { sta->flags &= ~WLAN_STA_HT; os_free(sta->ht_capabilities); sta->ht_capabilities = NULL;