wpa_supplicant: Support VHT capability overrides

Add support for VHT capability overrides to allow testing connections
with a subset of the VHT capabilities that are actually supported by
the device. The only thing that isn't currently supported (by mac80211
and this code) is the RX/TX highest rate field.

Signed-hostap: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg 2013-03-10 18:04:39 +02:00 committed by Jouni Malinen
parent eae3a584f5
commit e9ee8dc394
11 changed files with 195 additions and 0 deletions

View file

@ -568,6 +568,19 @@ struct wpa_driver_associate_params {
*/ */
const u8 *htcaps; /* struct ieee80211_ht_capabilities * */ const u8 *htcaps; /* struct ieee80211_ht_capabilities * */
const u8 *htcaps_mask; /* struct ieee80211_ht_capabilities * */ const u8 *htcaps_mask; /* struct ieee80211_ht_capabilities * */
#ifdef CONFIG_VHT_OVERRIDES
/**
* disable_vht - Disable VHT for this connection
*/
int disable_vht;
/**
* VHT capability overrides.
*/
const struct ieee80211_vht_capabilities *vhtcaps;
const struct ieee80211_vht_capabilities *vhtcaps_mask;
#endif /* CONFIG_VHT_OVERRIDES */
}; };
enum hide_ssid { enum hide_ssid {

View file

@ -7175,6 +7175,20 @@ skip_auth_type:
params->htcaps_mask); params->htcaps_mask);
} }
#ifdef CONFIG_VHT_OVERRIDES
if (params->disable_vht) {
wpa_printf(MSG_DEBUG, " * VHT disabled");
NLA_PUT_FLAG(msg, NL80211_ATTR_DISABLE_VHT);
}
if (params->vhtcaps && params->vhtcaps_mask) {
int sz = sizeof(struct ieee80211_vht_capabilities);
NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY, sz, params->vhtcaps);
NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY_MASK, sz,
params->vhtcaps_mask);
}
#endif /* CONFIG_VHT_OVERRIDES */
ret = nl80211_set_conn_keys(params, msg); ret = nl80211_set_conn_keys(params, msg);
if (ret) if (ret)
goto nla_put_failure; goto nla_put_failure;
@ -7361,6 +7375,20 @@ static int wpa_driver_nl80211_associate(
params->htcaps_mask); params->htcaps_mask);
} }
#ifdef CONFIG_VHT_OVERRIDES
if (params->disable_vht) {
wpa_printf(MSG_DEBUG, " * VHT disabled");
NLA_PUT_FLAG(msg, NL80211_ATTR_DISABLE_VHT);
}
if (params->vhtcaps && params->vhtcaps_mask) {
int sz = sizeof(struct ieee80211_vht_capabilities);
NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY, sz, params->vhtcaps);
NLA_PUT(msg, NL80211_ATTR_VHT_CAPABILITY_MASK, sz,
params->vhtcaps_mask);
}
#endif /* CONFIG_VHT_OVERRIDES */
if (params->p2p) if (params->p2p)
wpa_printf(MSG_DEBUG, " * P2P group"); wpa_printf(MSG_DEBUG, " * P2P group");

View file

@ -126,6 +126,10 @@ ifdef CONFIG_HT_OVERRIDES
CFLAGS += -DCONFIG_HT_OVERRIDES CFLAGS += -DCONFIG_HT_OVERRIDES
endif endif
ifdef CONFIG_VHT_OVERRIDES
CFLAGS += -DCONFIG_VHT_OVERRIDES
endif
ifndef CONFIG_BACKEND ifndef CONFIG_BACKEND
CONFIG_BACKEND=file CONFIG_BACKEND=file
endif endif

View file

@ -224,6 +224,9 @@ CONFIG_SMARTCARD=y
# Support HT overrides (disable HT/HT40, mask MCS rates, etc.) # Support HT overrides (disable HT/HT40, mask MCS rates, etc.)
#CONFIG_HT_OVERRIDES=y #CONFIG_HT_OVERRIDES=y
# Support VHT overrides (disable VHT, mask MCS rates, etc.)
#CONFIG_VHT_OVERRIDES=y
# Development testing # Development testing
#CONFIG_EAPOL_TEST=y #CONFIG_EAPOL_TEST=y

View file

@ -1550,6 +1550,27 @@ static const struct parse_data ssid_fields[] = {
{ INT_RANGE(ampdu_density, -1, 7) }, { INT_RANGE(ampdu_density, -1, 7) },
{ STR(ht_mcs) }, { STR(ht_mcs) },
#endif /* CONFIG_HT_OVERRIDES */ #endif /* CONFIG_HT_OVERRIDES */
#ifdef CONFIG_VHT_OVERRIDES
{ INT_RANGE(disable_vht, 0, 1) },
{ INT(vht_capa) },
{ INT(vht_capa_mask) },
{ INT_RANGE(vht_rx_mcs_nss_1, -1, 3) },
{ INT_RANGE(vht_rx_mcs_nss_2, -1, 3) },
{ INT_RANGE(vht_rx_mcs_nss_3, -1, 3) },
{ INT_RANGE(vht_rx_mcs_nss_4, -1, 3) },
{ INT_RANGE(vht_rx_mcs_nss_5, -1, 3) },
{ INT_RANGE(vht_rx_mcs_nss_6, -1, 3) },
{ INT_RANGE(vht_rx_mcs_nss_7, -1, 3) },
{ INT_RANGE(vht_rx_mcs_nss_8, -1, 3) },
{ INT_RANGE(vht_tx_mcs_nss_1, -1, 3) },
{ INT_RANGE(vht_tx_mcs_nss_2, -1, 3) },
{ INT_RANGE(vht_tx_mcs_nss_3, -1, 3) },
{ INT_RANGE(vht_tx_mcs_nss_4, -1, 3) },
{ INT_RANGE(vht_tx_mcs_nss_5, -1, 3) },
{ INT_RANGE(vht_tx_mcs_nss_6, -1, 3) },
{ INT_RANGE(vht_tx_mcs_nss_7, -1, 3) },
{ INT_RANGE(vht_tx_mcs_nss_8, -1, 3) },
#endif /* CONFIG_VHT_OVERRIDES */
{ INT(ap_max_inactivity) }, { INT(ap_max_inactivity) },
{ INT(dtim_period) }, { INT(dtim_period) },
{ INT(beacon_int) }, { INT(beacon_int) },
@ -1953,6 +1974,24 @@ void wpa_config_set_network_defaults(struct wpa_ssid *ssid)
ssid->ampdu_factor = DEFAULT_AMPDU_FACTOR; ssid->ampdu_factor = DEFAULT_AMPDU_FACTOR;
ssid->ampdu_density = DEFAULT_AMPDU_DENSITY; ssid->ampdu_density = DEFAULT_AMPDU_DENSITY;
#endif /* CONFIG_HT_OVERRIDES */ #endif /* CONFIG_HT_OVERRIDES */
#ifdef CONFIG_VHT_OVERRIDES
ssid->vht_rx_mcs_nss_1 = -1;
ssid->vht_rx_mcs_nss_2 = -1;
ssid->vht_rx_mcs_nss_3 = -1;
ssid->vht_rx_mcs_nss_4 = -1;
ssid->vht_rx_mcs_nss_5 = -1;
ssid->vht_rx_mcs_nss_6 = -1;
ssid->vht_rx_mcs_nss_7 = -1;
ssid->vht_rx_mcs_nss_8 = -1;
ssid->vht_tx_mcs_nss_1 = -1;
ssid->vht_tx_mcs_nss_2 = -1;
ssid->vht_tx_mcs_nss_3 = -1;
ssid->vht_tx_mcs_nss_4 = -1;
ssid->vht_tx_mcs_nss_5 = -1;
ssid->vht_tx_mcs_nss_6 = -1;
ssid->vht_tx_mcs_nss_7 = -1;
ssid->vht_tx_mcs_nss_8 = -1;
#endif /* CONFIG_VHT_OVERRIDES */
ssid->proactive_key_caching = -1; ssid->proactive_key_caching = -1;
#ifdef CONFIG_IEEE80211W #ifdef CONFIG_IEEE80211W
ssid->ieee80211w = MGMT_FRAME_PROTECTION_DEFAULT; ssid->ieee80211w = MGMT_FRAME_PROTECTION_DEFAULT;

View file

@ -534,6 +534,35 @@ struct wpa_ssid {
char *ht_mcs; char *ht_mcs;
#endif /* CONFIG_HT_OVERRIDES */ #endif /* CONFIG_HT_OVERRIDES */
#ifdef CONFIG_VHT_OVERRIDES
/**
* disable_vht - Disable VHT (IEEE 802.11ac) for this network
*
* By default, use it if it is available, but this can be configured
* to 1 to have it disabled.
*/
int disable_vht;
/**
* vht_capa - VHT capabilities to use
*/
unsigned int vht_capa;
/**
* vht_capa_mask - mask for VHT capabilities
*/
unsigned int vht_capa_mask;
int vht_rx_mcs_nss_1, vht_rx_mcs_nss_2,
vht_rx_mcs_nss_3, vht_rx_mcs_nss_4,
vht_rx_mcs_nss_5, vht_rx_mcs_nss_6,
vht_rx_mcs_nss_7, vht_rx_mcs_nss_8;
int vht_tx_mcs_nss_1, vht_tx_mcs_nss_2,
vht_tx_mcs_nss_3, vht_tx_mcs_nss_4,
vht_tx_mcs_nss_5, vht_tx_mcs_nss_6,
vht_tx_mcs_nss_7, vht_tx_mcs_nss_8;
#endif /* CONFIG_VHT_OVERRIDES */
/** /**
* ap_max_inactivity - Timeout in seconds to detect STA's inactivity * ap_max_inactivity - Timeout in seconds to detect STA's inactivity
* *

View file

@ -225,6 +225,9 @@ CONFIG_SMARTCARD=y
# Support HT overrides (disable HT/HT40, mask MCS rates, etc.) # Support HT overrides (disable HT/HT40, mask MCS rates, etc.)
#CONFIG_HT_OVERRIDES=y #CONFIG_HT_OVERRIDES=y
# Support VHT overrides (disable VHT, mask MCS rates, etc.)
#CONFIG_VHT_OVERRIDES=y
# Development testing # Development testing
#CONFIG_EAPOL_TEST=y #CONFIG_EAPOL_TEST=y

View file

@ -632,6 +632,10 @@ void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
struct ieee80211_ht_capabilities htcaps; struct ieee80211_ht_capabilities htcaps;
struct ieee80211_ht_capabilities htcaps_mask; struct ieee80211_ht_capabilities htcaps_mask;
#endif /* CONFIG_HT_OVERRIDES */ #endif /* CONFIG_HT_OVERRIDES */
#ifdef CONFIG_VHT_OVERRIDES
struct ieee80211_vht_capabilities vhtcaps;
struct ieee80211_vht_capabilities vhtcaps_mask;
#endif /* CONFIG_VHT_OVERRIDES */
os_memset(&params, 0, sizeof(params)); os_memset(&params, 0, sizeof(params));
params.bssid = bssid; params.bssid = bssid;
@ -653,6 +657,13 @@ void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
params.htcaps_mask = (u8 *) &htcaps_mask; params.htcaps_mask = (u8 *) &htcaps_mask;
wpa_supplicant_apply_ht_overrides(wpa_s, wpa_s->current_ssid, &params); wpa_supplicant_apply_ht_overrides(wpa_s, wpa_s->current_ssid, &params);
#endif /* CONFIG_HT_OVERRIDES */ #endif /* CONFIG_HT_OVERRIDES */
#ifdef CONFIG_VHT_OVERRIDES
os_memset(&vhtcaps, 0, sizeof(vhtcaps));
os_memset(&vhtcaps_mask, 0, sizeof(vhtcaps_mask));
params.vhtcaps = &vhtcaps;
params.vhtcaps_mask = &vhtcaps_mask;
wpa_supplicant_apply_vht_overrides(wpa_s, wpa_s->current_ssid, &params);
#endif /* CONFIG_VHT_OVERRIDES */
#ifdef CONFIG_IEEE80211R #ifdef CONFIG_IEEE80211R
if (auth_type == WLAN_AUTH_FT && wpa_s->sme.ft_ies) { if (auth_type == WLAN_AUTH_FT && wpa_s->sme.ft_ies) {
params.wpa_ie = wpa_s->sme.ft_ies; params.wpa_ie = wpa_s->sme.ft_ies;

View file

@ -2625,6 +2625,54 @@ void wpa_supplicant_apply_ht_overrides(
#endif /* CONFIG_HT_OVERRIDES */ #endif /* CONFIG_HT_OVERRIDES */
#ifdef CONFIG_VHT_OVERRIDES
void wpa_supplicant_apply_vht_overrides(
struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
struct wpa_driver_associate_params *params)
{
struct ieee80211_vht_capabilities *vhtcaps;
struct ieee80211_vht_capabilities *vhtcaps_mask;
if (!ssid)
return;
params->disable_vht = ssid->disable_vht;
vhtcaps = (void *) params->vhtcaps;
vhtcaps_mask = (void *) params->vhtcaps_mask;
if (!vhtcaps || !vhtcaps_mask)
return;
vhtcaps->vht_capabilities_info = ssid->vht_capa;
vhtcaps_mask->vht_capabilities_info = ssid->vht_capa_mask;
#define OVERRIDE_MCS(i) \
if (ssid->vht_tx_mcs_nss_ ##i >= 0) { \
vhtcaps_mask->vht_supported_mcs_set.tx_map |= \
3 << 2 * (i - 1); \
vhtcaps->vht_supported_mcs_set.tx_map |= \
ssid->vht_tx_mcs_nss_ ##i << 2 * (i - 1); \
} \
if (ssid->vht_rx_mcs_nss_ ##i >= 0) { \
vhtcaps_mask->vht_supported_mcs_set.rx_map |= \
3 << 2 * (i - 1); \
vhtcaps->vht_supported_mcs_set.rx_map |= \
ssid->vht_rx_mcs_nss_ ##i << 2 * (i - 1); \
}
OVERRIDE_MCS(1);
OVERRIDE_MCS(2);
OVERRIDE_MCS(3);
OVERRIDE_MCS(4);
OVERRIDE_MCS(5);
OVERRIDE_MCS(6);
OVERRIDE_MCS(7);
OVERRIDE_MCS(8);
}
#endif /* CONFIG_VHT_OVERRIDES */
static int pcsc_reader_init(struct wpa_supplicant *wpa_s) static int pcsc_reader_init(struct wpa_supplicant *wpa_s)
{ {
#ifdef PCSC_FUNCS #ifdef PCSC_FUNCS

View file

@ -869,6 +869,20 @@ fast_reauth=1
# -1 = Do not make any changes. # -1 = Do not make any changes.
# 0-3 = Set AMPDU density (aka factor) to specified value. # 0-3 = Set AMPDU density (aka factor) to specified value.
# disable_vht: Whether VHT should be disabled.
# 0 = VHT enabled (if AP supports it)
# 1 = VHT disabled
#
# vht_capa: VHT capabilities to set in the override
# vht_capa_mask: mask of VHT capabilities
#
# vht_rx_mcs_nss_1/2/3/4/5/6/7/8: override the MCS set for RX NSS 1-8
# vht_tx_mcs_nss_1/2/3/4/5/6/7/8: override the MCS set for TX NSS 1-8
# 0: MCS 0-7
# 1: MCS 0-8
# 2: MCS 0-9
# 3: not supported
# Example blocks: # Example blocks:
# Simple case: WPA-PSK, PSK as an ASCII passphrase, allow all valid ciphers # Simple case: WPA-PSK, PSK as an ASCII passphrase, allow all valid ciphers

View file

@ -681,6 +681,9 @@ struct wpa_supplicant {
void wpa_supplicant_apply_ht_overrides( void wpa_supplicant_apply_ht_overrides(
struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
struct wpa_driver_associate_params *params); struct wpa_driver_associate_params *params);
void wpa_supplicant_apply_vht_overrides(
struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
struct wpa_driver_associate_params *params);
int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);