From 5144ba29e5687818afcfacaadb0c31575a8315e6 Mon Sep 17 00:00:00 2001 From: Pradeep Kumar Chitrapu Date: Fri, 19 Jun 2020 14:46:54 -0700 Subject: [PATCH] hostapd: fix enable 40/80mhz bandwidth in 6Ghz Currently higher bandwidths are being rejected by hostapd for 6ghz channels due to invalid sanity check. So fix that. Also, currently 6GHz AP is setting unicast destination address for probe response which need to be set to broadcast address according to spec IEEE P802.11ax/D6.1. So fix that. Make management frame protection required as default for 6Ghz band. Signed-off-by: Pradeep Kumar Chitrapu --- src/common/hw_features_common.c | 2 +- src/common/ieee802_11_common.c | 16 ++++++++-------- src/drivers/driver_nl80211.c | 3 ++- wpa_supplicant/op_classes.c | 8 ++++---- 4 files changed, 15 insertions(+), 14 deletions(-) --- a/src/common/hw_features_common.c +++ b/src/common/hw_features_common.c @@ -415,7 +415,7 @@ int hostapd_set_freq_params(struct hosta return -1; } - if (center_idx_to_bw_6ghz(channel) != 0) { + if (center_idx_to_bw_6ghz(channel) < 0) { wpa_printf(MSG_ERROR, "Invalid control channel for 6 GHz band"); return -1; --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -10654,7 +10654,8 @@ static int add_acs_ch_list(struct nl_msg * compatibility. */ if (!(freq >= 2412 && freq <= 2484) && - !(freq >= 5180 && freq <= 5900)) + !(freq >= 5180 && freq <= 5900) && + !(freq >= 5945 && freq <= 7115)) continue; hw_mode = ieee80211_freq_to_chan(freq, &ch_list[num_channels]); if (hw_mode != NUM_HOSTAPD_MODES) --- a/wpa_supplicant/op_classes.c +++ b/wpa_supplicant/op_classes.c @@ -242,7 +242,7 @@ static int wpas_op_class_supported(struc if (f == 0) break; /* end of list */ - if (f > 4000 && f < 6000) + if (f > 4000 && f < 7115) freq5 = 1; else if (f > 2400 && f < 2500) freq2 = 1; @@ -253,7 +253,7 @@ static int wpas_op_class_supported(struc freq2 = freq5 = 1; } - if (op_class->op_class >= 115 && op_class->op_class <= 130 && !freq5) + if (op_class->op_class >= 115 && op_class->op_class <= 136 && !freq5) return 0; if (op_class->op_class >= 81 && op_class->op_class <= 84 && !freq2) return 0; --- a/src/ap/acs.c +++ b/src/ap/acs.c @@ -372,40 +372,44 @@ acs_survey_chan_interference_factor(stru } -static int acs_usable_ht40_chan(const struct hostapd_channel_data *chan) +static int acs_usable_bw40_chan(const struct hostapd_channel_data *chan) { - const int allowed[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, - 157, 184, 192 }; + const int allowed[] = { 5180, 5220, 5260, 5300, 5500, 5540, 5580, 5620, 5660, 5745, + 5785, 5955, 5995, 6035, 6075, 6115, 6155, 6195, 6235, 6275, + 6315, 6355, 6395, 6435, 6475, 6515, 6555, 6595, 6635, 6675, + 6715, 6755, 6795, 6835, 6875, 6915, 6955, 6995, 7035, 7075 }; unsigned int i; for (i = 0; i < ARRAY_SIZE(allowed); i++) - if (chan->chan == allowed[i]) + if (chan->freq == allowed[i]) return 1; return 0; } -static int acs_usable_vht80_chan(const struct hostapd_channel_data *chan) +static int acs_usable_bw80_chan(const struct hostapd_channel_data *chan) { - const int allowed[] = { 36, 52, 100, 116, 132, 149 }; + const int allowed[] = { 5180, 5260, 5550, 5580, 5660, 5680, 5955, 6035, 6115, + 6195, 6275, 6355, 6435, 6515, 6595, 6675, 6755, 6835, + 6915, 6995 }; unsigned int i; for (i = 0; i < ARRAY_SIZE(allowed); i++) - if (chan->chan == allowed[i]) + if (chan->freq == allowed[i]) return 1; return 0; } -static int acs_usable_vht160_chan(const struct hostapd_channel_data *chan) +static int acs_usable_bw160_chan(const struct hostapd_channel_data *chan) { - const int allowed[] = { 36, 100 }; + const int allowed[] = { 5180, 5500, 5955, 6115, 6275, 6435, 6595, 6755, 6915 }; unsigned int i; for (i = 0; i < ARRAY_SIZE(allowed); i++) - if (chan->chan == allowed[i]) + if (chan->freq == allowed[i]) return 1; return 0; @@ -678,10 +682,11 @@ acs_find_ideal_chan_mode(struct hostapd_ /* HT40 on 5 GHz has a limited set of primary channels as per * 11n Annex J */ if (mode->mode == HOSTAPD_MODE_IEEE80211A && - iface->conf->ieee80211n && - iface->conf->secondary_channel && - !acs_usable_ht40_chan(chan)) { - wpa_printf(MSG_DEBUG, "ACS: Channel %d: not allowed as primary channel for HT40", + ((iface->conf->ieee80211n && + iface->conf->secondary_channel) || + is_6ghz_freq(chan->freq)) && + !acs_usable_bw40_chan(chan)) { + wpa_printf(MSG_DEBUG, "ACS: Channel %d: not allowed as primary channel for 40MHz bandwidth", chan->chan); continue; } @@ -690,18 +695,18 @@ acs_find_ideal_chan_mode(struct hostapd_ (iface->conf->ieee80211ac || iface->conf->ieee80211ax)) { if (hostapd_get_oper_chwidth(iface->conf) == CHANWIDTH_80MHZ && - !acs_usable_vht80_chan(chan)) { + !acs_usable_bw80_chan(chan)) { wpa_printf(MSG_DEBUG, - "ACS: Channel %d: not allowed as primary channel for VHT80", + "ACS: Channel %d: not allowed as primary channel for 80MHz bandwidth", chan->chan); continue; } if (hostapd_get_oper_chwidth(iface->conf) == CHANWIDTH_160MHZ && - !acs_usable_vht160_chan(chan)) { + !acs_usable_bw160_chan(chan)) { wpa_printf(MSG_DEBUG, - "ACS: Channel %d: not allowed as primary channel for VHT160", + "ACS: Channel %d: not allowed as primary channel for 160MHz bandwidth", chan->chan); continue; } @@ -832,16 +837,20 @@ acs_find_ideal_chan(struct hostapd_iface u32 bw; struct hostapd_hw_modes *mode; - /* TODO: HT40- support */ + if (is_6ghz_op_class(iface->conf->op_class)) { + bw = op_class_to_bandwidth(iface->conf->op_class); + n_chans = bw/20; + goto bw_selected; + } + /* TODO: HT40- support */ if (iface->conf->ieee80211n && iface->conf->secondary_channel == -1) { wpa_printf(MSG_ERROR, "ACS: HT40- is not supported yet. Please try HT40+"); return NULL; } - if (iface->conf->ieee80211n && - iface->conf->secondary_channel) + if (iface->conf->ieee80211n && iface->conf->secondary_channel) n_chans = 2; if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) { @@ -857,6 +866,7 @@ acs_find_ideal_chan(struct hostapd_iface bw = num_chan_to_bw(n_chans); +bw_selected: /* TODO: VHT/HE80+80. Update acs_adjust_center_freq() too. */ wpa_printf(MSG_DEBUG, --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -1689,6 +1689,10 @@ static int setup_interface2(struct hosta ch_width = op_class_to_ch_width(iface->conf->op_class); hostapd_set_oper_chwidth(iface->conf, ch_width); + if (!iface->conf->secondary_channel && + op_class_to_bandwidth(iface->conf->op_class) >= 40) + iface->conf->secondary_channel = + (((iface->conf->channel - 1) / 4 ) % 2) ? -1 : 1 ; } ret = hostapd_select_hw_mode(iface); diff --git a/src/ap/beacon.c b/src/ap/beacon.c index 668d9094e28d..ff17b2f00e85 100644 --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -486,8 +486,10 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, resp->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_PROBE_RESP); - if (req) + os_memset(resp->da, 0xff, ETH_ALEN); + if (req && !is_6ghz_op_class(hapd->iconf->op_class)) os_memcpy(resp->da, req->sa, ETH_ALEN); + os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN); os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN); diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c index c1630d09a254..56f40edc0fdc 100644 --- a/wpa_supplicant/mesh.c +++ b/wpa_supplicant/mesh.c @@ -512,6 +512,8 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s, params->flags |= WPA_DRIVER_MESH_FLAG_SAE_AUTH; params->flags |= WPA_DRIVER_MESH_FLAG_AMPE; wpa_s->conf->user_mpm = 1; + if (is_6ghz_freq(ssid->frequency)) + ssid->ieee80211w = MGMT_FRAME_PROTECTION_REQUIRED; } if (wpa_s->conf->user_mpm) {