Fill the current opclass in (Re)AssocRequest depending on HT/VHT IEs

The previous implementation was assuming a fixed 20 MHz channel
bandwidth when determining which operating class value to indicate as
the Current Operating Class in the Supported Operating Classes element.
This is not accurate for many HT/VHT cases.

Fix this by determining the current operating class (i.e., the operating
class used for the requested association) based on the HT/VHT operation
elements from scan results.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
Ananya Barat 2020-03-10 12:07:33 +05:30 committed by Jouni Malinen
parent d9a7b71a78
commit 2b9713d616
5 changed files with 31 additions and 10 deletions

View File

@ -14,6 +14,7 @@
#include "utils/common.h"
#include "common/ieee802_11_common.h"
#include "wpa_supplicant_i.h"
#include "bss.h"
static enum chan_allowed allow_channel(struct hostapd_hw_modes *mode,
@ -356,9 +357,25 @@ static int wpas_op_class_supported(struct wpa_supplicant *wpa_s,
}
static int wpas_sta_secondary_channel_offset(struct wpa_bss *bss, u8 *current,
u8 *channel)
{
u8 *ies, phy_type;
size_t ies_len;
if (!bss)
return -1;
ies = (u8 *) (bss + 1);
ies_len = bss->ie_len ? bss->ie_len : bss->beacon_ie_len;
return wpas_get_op_chan_phy(bss->freq, ies, ies_len, current,
channel, &phy_type);
}
size_t wpas_supp_op_class_ie(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid,
int freq, u8 *pos, size_t len)
struct wpa_bss *bss, u8 *pos, size_t len)
{
struct wpabuf *buf;
u8 op, current, chan;
@ -366,11 +383,13 @@ size_t wpas_supp_op_class_ie(struct wpa_supplicant *wpa_s,
size_t res;
/*
* Assume 20 MHz channel for now.
* TODO: Use the secondary channel and VHT channel width that will be
* used after association.
* Determine the current operating class correct mode based on
* advertised BSS capabilities, if available. Fall back to a less
* accurate guess based on frequency if the needed IEs are not available
* or used.
*/
if (ieee80211_freq_to_channel_ext(freq, 0, CHANWIDTH_USE_HT,
if (wpas_sta_secondary_channel_offset(bss, &current, &chan) < 0 &&
ieee80211_freq_to_channel_ext(bss->freq, 0, CHANWIDTH_USE_HT,
&current, &chan) == NUM_HOSTAPD_MODES)
return 0;

View File

@ -695,8 +695,8 @@ static int * wpas_beacon_request_freqs(struct wpa_supplicant *wpa_s,
}
static int wpas_get_op_chan_phy(int freq, const u8 *ies, size_t ies_len,
u8 *op_class, u8 *chan, u8 *phy_type)
int wpas_get_op_chan_phy(int freq, const u8 *ies, size_t ies_len,
u8 *op_class, u8 *chan, u8 *phy_type)
{
const u8 *ie;
int sec_chan = 0, vht = 0;

View File

@ -578,7 +578,7 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
sme_auth_handle_rrm(wpa_s, bss);
wpa_s->sme.assoc_req_ie_len += wpas_supp_op_class_ie(
wpa_s, ssid, bss->freq,
wpa_s, ssid, bss,
wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
sizeof(wpa_s->sme.assoc_req_ie) - wpa_s->sme.assoc_req_ie_len);

View File

@ -2890,7 +2890,7 @@ static u8 * wpas_populate_assoc_ies(
#endif /* CONFIG_P2P */
if (bss) {
wpa_ie_len += wpas_supp_op_class_ie(wpa_s, ssid, bss->freq,
wpa_ie_len += wpas_supp_op_class_ie(wpa_s, ssid, bss,
wpa_ie + wpa_ie_len,
max_wpa_ie_len -
wpa_ie_len);

View File

@ -1394,6 +1394,8 @@ int wpas_update_random_addr(struct wpa_supplicant *wpa_s, int style);
int wpas_update_random_addr_disassoc(struct wpa_supplicant *wpa_s);
void add_freq(int *freqs, int *num_freqs, int freq);
int wpas_get_op_chan_phy(int freq, const u8 *ies, size_t ies_len,
u8 *op_class, u8 *chan, u8 *phy_type);
void wpas_rrm_reset(struct wpa_supplicant *wpa_s);
void wpas_rrm_process_neighbor_rep(struct wpa_supplicant *wpa_s,
const u8 *report, size_t report_len);
@ -1453,7 +1455,7 @@ enum chan_allowed verify_channel(struct hostapd_hw_modes *mode, u8 op_class,
u8 channel, u8 bw);
size_t wpas_supp_op_class_ie(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid,
int freq, u8 *pos, size_t len);
struct wpa_bss *bss, u8 *pos, size_t len);
int * wpas_supp_op_classes(struct wpa_supplicant *wpa_s);
int wpas_enable_mac_addr_randomization(struct wpa_supplicant *wpa_s,