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:
parent
eae3a584f5
commit
e9ee8dc394
11 changed files with 195 additions and 0 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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");
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
*
|
*
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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(¶ms, 0, sizeof(params));
|
os_memset(¶ms, 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, ¶ms);
|
wpa_supplicant_apply_ht_overrides(wpa_s, wpa_s->current_ssid, ¶ms);
|
||||||
#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, ¶ms);
|
||||||
|
#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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue