Import wpa_supplicant/hostapd commit b4f7506ff

This commit is contained in:
Cy Schubert 2021-07-21 14:14:05 -07:00
parent 40c7ff83e7
commit 2f6c3ea960
36 changed files with 669 additions and 144 deletions

View File

@ -1228,7 +1228,9 @@ int hostapd_is_dfs_required(struct hostapd_iface *iface)
{
int n_chans, n_chans1, start_chan_idx, start_chan_idx1, res;
if (!iface->conf->ieee80211h || !iface->current_mode ||
if ((!(iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) &&
!iface->conf->ieee80211h) ||
!iface->current_mode ||
iface->current_mode->mode != HOSTAPD_MODE_IEEE80211A)
return 0;
@ -1279,6 +1281,8 @@ int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
*/
int hostapd_handle_dfs_offload(struct hostapd_iface *iface)
{
int dfs_res;
wpa_printf(MSG_DEBUG, "%s: iface->cac_started: %d",
__func__, iface->cac_started);
@ -1294,10 +1298,11 @@ int hostapd_handle_dfs_offload(struct hostapd_iface *iface)
return 1;
}
if (ieee80211_is_dfs(iface->freq, iface->hw_features,
iface->num_hw_features)) {
wpa_printf(MSG_DEBUG, "%s: freq %d MHz requires DFS",
__func__, iface->freq);
dfs_res = hostapd_is_dfs_required(iface);
if (dfs_res > 0) {
wpa_printf(MSG_DEBUG,
"%s: freq %d MHz requires DFS for %d chans",
__func__, iface->freq, dfs_res);
return 0;
}

View File

@ -3943,8 +3943,10 @@ static void handle_auth(struct hostapd_data *hapd,
fail:
reply_res = send_auth_reply(hapd, sta, mgmt->sa, mgmt->bssid, auth_alg,
auth_transaction + 1, resp, resp_ies,
resp_ies_len, "handle-auth");
auth_alg == WLAN_AUTH_SAE ?
auth_transaction : auth_transaction + 1,
resp, resp_ies, resp_ies_len,
"handle-auth");
if (sta && sta->added_unassoc && (resp != WLAN_STATUS_SUCCESS ||
reply_res != WLAN_STATUS_SUCCESS)) {

View File

@ -1553,7 +1553,8 @@ int hostapd_setup_wpa(struct hostapd_data *hapd)
return -1;
}
hapd->ptksa = ptksa_cache_init();
if (!hapd->ptksa)
hapd->ptksa = ptksa_cache_init();
if (!hapd->ptksa) {
wpa_printf(MSG_ERROR, "Failed to allocate PTKSA cache");
return -1;

View File

@ -1172,6 +1172,8 @@ int hostapd_init_wps(struct hostapd_data *hapd,
wps->auth_types |= WPS_AUTH_WPA2PSK;
if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X)
wps->auth_types |= WPS_AUTH_WPA2;
if (conf->wpa_key_mgmt & WPA_KEY_MGMT_SAE)
wps->auth_types |= WPS_AUTH_WPA2PSK;
if (conf->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP |
WPA_CIPHER_CCMP_256 |
@ -1328,6 +1330,11 @@ int hostapd_init_wps(struct hostapd_data *hapd,
hostapd_register_probereq_cb(hapd, hostapd_wps_probe_req_rx, hapd);
#ifdef CONFIG_P2P
if ((hapd->conf->p2p & P2P_ENABLED) &&
is_6ghz_op_class(hapd->iconf->op_class))
wps->use_passphrase = true;
#endif /* CONFIG_P2P */
hapd->wps = wps;
bin_clear_free(multi_ap_netw_key, 2 * PMK_LEN);

View File

@ -1894,7 +1894,7 @@ const struct oper_class_map global_op_class[] = {
*/
{ HOSTAPD_MODE_IEEE80211A, 128, 36, 177, 4, BW80, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 129, 36, 177, 4, BW160, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 131, 1, 233, 4, BW20, NO_P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 131, 1, 233, 4, BW20, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 132, 1, 233, 8, BW40, NO_P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 133, 1, 233, 16, BW80, NO_P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 134, 1, 233, 32, BW160, NO_P2P_SUPP },

View File

@ -1657,6 +1657,7 @@ enum p2p_attr_id {
#define P2P_DEV_CAPAB_INFRA_MANAGED BIT(3)
#define P2P_DEV_CAPAB_DEVICE_LIMIT BIT(4)
#define P2P_DEV_CAPAB_INVITATION_PROCEDURE BIT(5)
#define P2P_DEV_CAPAB_6GHZ_BAND_CAPABLE BIT(6)
/* P2P Capability - Group Capability bitmap */
#define P2P_GROUP_CAPAB_GROUP_OWNER BIT(0)

View File

@ -1730,11 +1730,22 @@ enum qca_vendor_attr_tsf_cmd {
* @QCA_TSF_CAPTURE: Initiate TSF Capture
* @QCA_TSF_GET: Get TSF capture value
* @QCA_TSF_SYNC_GET: Initiate TSF capture and return with captured value
* @QCA_TSF_AUTO_REPORT_ENABLE: Used in STA mode only. Once set, the target
* will automatically send TSF report to the host. To query
* QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY, this operation needs to be
* initiated first.
* @QCA_TSF_AUTO_REPORT_DISABLE: Used in STA mode only. Once set, the target
* will not automatically send TSF report to the host. If
* QCA_TSF_AUTO_REPORT_ENABLE is initiated and
* QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY is not queried anymore, this
* operation needs to be initiated.
*/
enum qca_tsf_cmd {
QCA_TSF_CAPTURE,
QCA_TSF_GET,
QCA_TSF_SYNC_GET,
QCA_TSF_AUTO_REPORT_ENABLE,
QCA_TSF_AUTO_REPORT_DISABLE,
};
/**
@ -3867,6 +3878,10 @@ enum qca_wlan_vendor_attr_ll_stats_results {
* QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO.
*/
QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_RX_TIME = 85,
/* u8 value representing the channel load percentage. Possible values
* are 0-100.
*/
QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_LOAD_PERCENTAGE = 86,
/* keep last */
QCA_WLAN_VENDOR_ATTR_LL_STATS_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX =
@ -8120,6 +8135,29 @@ enum qca_wlan_vendor_attr_wifi_test_config {
*/
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_KEEP_ALIVE_FRAME_TYPE = 53,
/* 8-bit unsigned value to configure the driver to use scan request
* BSSID value in Probe Request frame RA(A1) during the scan. The
* driver saves this configuration and applies this setting to all user
* space scan requests until the setting is cleared. If this
* configuration is set, the driver uses the BSSID value from the scan
* request to set the RA(A1) in the Probe Request frames during the
* scan.
*
* 0 - Default behavior uses the broadcast RA in Probe Request frames.
* 1 - Uses the scan request BSSID in RA in Probe Request frames.
* This attribute is used for testing purposes.
*/
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_USE_BSSID_IN_PROBE_REQ_RA = 54,
/* 8-bit unsigned value to configure the driver to enable/disable the
* BSS max idle period support.
*
* 0 - Disable the BSS max idle support.
* 1 - Enable the BSS max idle support.
* This attribute is used for testing purposes.
*/
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD_ENABLE = 55,
/* keep last */
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX =
@ -10369,6 +10407,11 @@ enum qca_vendor_wlan_sta_guard_interval {
* failed roam invoke. Different roam invoke failure reason codes
* are specified in enum qca_vendor_roam_invoke_fail_reasons. This can be
* queried either in connected state or disconnected state.
*
* @QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY: u32, used in STA mode only.
* This represents the average congestion duration of uplink frames in MAC
* queue in unit of ms. This can be queried either in connected state or
* disconnected state.
*/
enum qca_wlan_vendor_attr_get_sta_info {
QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_INVALID = 0,
@ -10421,6 +10464,7 @@ enum qca_wlan_vendor_attr_get_sta_info {
QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_TRIGGER_REASON = 47,
QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_FAIL_REASON = 48,
QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_ROAM_INVOKE_FAIL_REASON = 49,
QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_UPLINK_DELAY = 50,
/* keep last */
QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_AFTER_LAST,

View File

@ -645,6 +645,12 @@ struct wpa_driver_scan_params {
*/
unsigned int oce_scan:1;
/**
* p2p_include_6ghz - Include 6 GHz channels for P2P full scan
*
*/
unsigned int p2p_include_6ghz:1;
/*
* NOTE: Whenever adding new parameters here, please make sure
* wpa_scan_clone_params() and wpa_scan_free_params() get updated with

View File

@ -1329,7 +1329,7 @@ static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted,
struct nlattr *nl;
int rem;
struct scan_info *info;
#define MAX_REPORT_FREQS 50
#define MAX_REPORT_FREQS 100
int freqs[MAX_REPORT_FREQS];
int num_freqs = 0;
@ -1361,7 +1361,7 @@ static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted,
}
}
if (tb[NL80211_ATTR_SCAN_FREQUENCIES]) {
char msg[300], *pos, *end;
char msg[500], *pos, *end;
int res;
pos = msg;
@ -2273,7 +2273,7 @@ static void send_vendor_scan_event(struct wpa_driver_nl80211_data *drv,
}
if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES]) {
char msg[300], *pos, *end;
char msg[500], *pos, *end;
int res;
pos = msg;

View File

@ -132,9 +132,11 @@ static void * eap_wsc_init(struct eap_sm *sm)
cfg.peer_addr = sm->peer_addr;
#ifdef CONFIG_P2P
if (sm->assoc_p2p_ie) {
wpa_printf(MSG_DEBUG, "EAP-WSC: Prefer PSK format for P2P "
"client");
cfg.use_psk_key = 1;
if (!sm->cfg->wps->use_passphrase) {
wpa_printf(MSG_DEBUG,
"EAP-WSC: Prefer PSK format for non-6 GHz P2P client");
cfg.use_psk_key = 1;
}
cfg.p2p_dev_addr = p2p_get_go_dev_addr(sm->assoc_p2p_ie);
}
#endif /* CONFIG_P2P */

View File

@ -1035,7 +1035,7 @@ static void p2p_search(struct p2p_data *p2p)
res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, type, freq,
p2p->num_req_dev_types, p2p->req_dev_types,
p2p->find_dev_id, pw_id);
p2p->find_dev_id, pw_id, p2p->include_6ghz);
if (res < 0) {
p2p_dbg(p2p, "Scan request schedule failed");
p2p_continue_find(p2p);
@ -1159,7 +1159,7 @@ int p2p_find(struct p2p_data *p2p, unsigned int timeout,
enum p2p_discovery_type type,
unsigned int num_req_dev_types, const u8 *req_dev_types,
const u8 *dev_id, unsigned int search_delay,
u8 seek_count, const char **seek, int freq)
u8 seek_count, const char **seek, int freq, bool include_6ghz)
{
int res;
struct os_reltime start;
@ -1184,7 +1184,7 @@ int p2p_find(struct p2p_data *p2p, unsigned int timeout,
p2p->find_dev_id = p2p->find_dev_id_buf;
} else
p2p->find_dev_id = NULL;
p2p->include_6ghz = p2p_wfd_enabled(p2p) && include_6ghz;
if (seek_count == 0 || !seek) {
/* Not an ASP search */
p2p->p2ps_seek = 0;
@ -1260,7 +1260,8 @@ int p2p_find(struct p2p_data *p2p, unsigned int timeout,
P2P_SCAN_SPECIFIC, freq,
p2p->num_req_dev_types,
p2p->req_dev_types, dev_id,
DEV_PW_DEFAULT);
DEV_PW_DEFAULT,
p2p->include_6ghz);
break;
}
/* fall through */
@ -1268,13 +1269,13 @@ int p2p_find(struct p2p_data *p2p, unsigned int timeout,
res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_FULL, 0,
p2p->num_req_dev_types,
p2p->req_dev_types, dev_id,
DEV_PW_DEFAULT);
DEV_PW_DEFAULT, p2p->include_6ghz);
break;
case P2P_FIND_ONLY_SOCIAL:
res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_SOCIAL, 0,
p2p->num_req_dev_types,
p2p->req_dev_types, dev_id,
DEV_PW_DEFAULT);
DEV_PW_DEFAULT, p2p->include_6ghz);
break;
default:
return -1;
@ -1396,8 +1397,8 @@ static int p2p_prepare_channel_pref(struct p2p_data *p2p,
p2p->channels.reg_class[0].reg_class = p2p->op_reg_class;
p2p->channels.reg_class[0].channel[0] = p2p->op_channel;
} else {
os_memcpy(&p2p->channels, &p2p->cfg->channels,
sizeof(struct p2p_channels));
p2p_copy_channels(&p2p->channels, &p2p->cfg->channels,
p2p->allow_6ghz);
}
return 0;
@ -1411,6 +1412,7 @@ static void p2p_prepare_channel_best(struct p2p_data *p2p)
const int op_classes_ht40[] = { 126, 127, 116, 117, 0 };
const int op_classes_vht[] = { 128, 0 };
const int op_classes_edmg[] = { 181, 182, 183, 0 };
const int op_classes_6ghz[] = { 131, 0 };
p2p_dbg(p2p, "Prepare channel best");
@ -1447,6 +1449,12 @@ static void p2p_prepare_channel_best(struct p2p_data *p2p)
0) {
p2p_dbg(p2p, "Select possible EDMG channel (op_class %u channel %u) as operating channel preference",
p2p->op_reg_class, p2p->op_channel);
} else if (p2p->allow_6ghz &&
(p2p_channel_select(&p2p->cfg->channels, op_classes_6ghz,
&p2p->op_reg_class, &p2p->op_channel) ==
0)) {
p2p_dbg(p2p, "Select possible 6 GHz channel (op_class %u channel %u) as operating channel preference",
p2p->op_reg_class, p2p->op_channel);
} else if (p2p_channel_select(&p2p->cfg->channels, op_classes_vht,
&p2p->op_reg_class, &p2p->op_channel) ==
0) {
@ -1484,8 +1492,7 @@ static void p2p_prepare_channel_best(struct p2p_data *p2p)
p2p->op_channel, p2p->op_reg_class);
}
os_memcpy(&p2p->channels, &p2p->cfg->channels,
sizeof(struct p2p_channels));
p2p_copy_channels(&p2p->channels, &p2p->cfg->channels, p2p->allow_6ghz);
}
@ -1568,9 +1575,10 @@ int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr,
p2p_dbg(p2p, "Request to start group negotiation - peer=" MACSTR
" GO Intent=%d Intended Interface Address=" MACSTR
" wps_method=%d persistent_group=%d pd_before_go_neg=%d "
"oob_pw_id=%u",
"oob_pw_id=%u allow_6ghz=%d",
MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr),
wps_method, persistent_group, pd_before_go_neg, oob_pw_id);
wps_method, persistent_group, pd_before_go_neg, oob_pw_id,
p2p->allow_6ghz);
dev = p2p_get_device(p2p, peer_addr);
if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) {
@ -1668,9 +1676,9 @@ int p2p_authorize(struct p2p_data *p2p, const u8 *peer_addr,
p2p_dbg(p2p, "Request to authorize group negotiation - peer=" MACSTR
" GO Intent=%d Intended Interface Address=" MACSTR
" wps_method=%d persistent_group=%d oob_pw_id=%u",
" wps_method=%d persistent_group=%d oob_pw_id=%u allow_6ghz=%d",
MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr),
wps_method, persistent_group, oob_pw_id);
wps_method, persistent_group, oob_pw_id, p2p->allow_6ghz);
dev = p2p_get_device(p2p, peer_addr);
if (dev == NULL) {
@ -5575,3 +5583,69 @@ struct wpabuf * p2p_build_probe_resp_template(struct p2p_data *p2p,
return buf;
}
bool p2p_is_peer_6ghz_capab(struct p2p_data *p2p, const u8 *addr)
{
struct p2p_device *dev;
dev = p2p_get_device(p2p, addr);
if (!dev)
return false;
return !!(dev->info.dev_capab & P2P_DEV_CAPAB_6GHZ_BAND_CAPABLE);
}
void p2p_set_6ghz_dev_capab(struct p2p_data *p2p, bool allow_6ghz)
{
p2p->p2p_6ghz_capable = allow_6ghz;
p2p->allow_6ghz = allow_6ghz;
p2p_dbg(p2p, "Set 6 GHz capability to %d", allow_6ghz);
if (allow_6ghz)
p2p->dev_capab |= P2P_DEV_CAPAB_6GHZ_BAND_CAPABLE;
else
p2p->dev_capab &= ~P2P_DEV_CAPAB_6GHZ_BAND_CAPABLE;
}
bool is_p2p_6ghz_capable(struct p2p_data *p2p)
{
return p2p->p2p_6ghz_capable;
}
bool p2p_wfd_enabled(struct p2p_data *p2p)
{
#ifdef CONFIG_WIFI_DISPLAY
return p2p->wfd_ie_probe_req != NULL;
#else /* CONFIG_WIFI_DISPLAY */
return false;
#endif /* CONFIG_WIFI_DISPLAY */
}
bool p2p_peer_wfd_enabled(struct p2p_data *p2p, const u8 *peer_addr)
{
#ifdef CONFIG_WIFI_DISPLAY
struct p2p_device *dev;
dev = p2p_get_device(p2p, peer_addr);
return dev && dev->info.wfd_subelems != NULL;
#else /* CONFIG_WIFI_DISPLAY */
return false;
#endif /* CONFIG_WIFI_DISPLAY */
}
bool is_p2p_allow_6ghz(struct p2p_data *p2p)
{
return p2p->allow_6ghz;
}
void set_p2p_allow_6ghz(struct p2p_data *p2p, bool value)
{
p2p->allow_6ghz = value;
}

View File

@ -612,6 +612,7 @@ struct p2p_config {
* @req_dev_types: Array containing requested device types
* @dev_id: Device ID to search for or %NULL to find all devices
* @pw_id: Device Password ID
* @include_6ghz: Include 6 GHz channels in P2P scan
* Returns: 0 on success, -1 on failure
*
* This callback function is used to request a P2P scan or search
@ -635,7 +636,8 @@ struct p2p_config {
*/
int (*p2p_scan)(void *ctx, enum p2p_scan_type type, int freq,
unsigned int num_req_dev_types,
const u8 *req_dev_types, const u8 *dev_id, u16 pw_id);
const u8 *req_dev_types, const u8 *dev_id, u16 pw_id,
bool include_6ghz);
/**
* send_probe_resp - Transmit a Probe Response frame
@ -1243,13 +1245,15 @@ enum p2p_discovery_type {
* P2P_FIND_START_WITH_FULL behavior. 0 = Use normal full scan.
* If p2p_find is already in progress, this parameter is ignored and full
* scan will be executed.
* @include_6ghz: Include 6 GHz channels in P2P find
* Returns: 0 on success, -1 on failure
*/
int p2p_find(struct p2p_data *p2p, unsigned int timeout,
enum p2p_discovery_type type,
unsigned int num_req_dev_types, const u8 *req_dev_types,
const u8 *dev_id, unsigned int search_delay,
u8 seek_count, const char **seek_string, int freq);
u8 seek_count, const char **seek_string, int freq,
bool include_6ghz);
/**
* p2p_notify_scan_trigger_status - Indicate scan trigger status
@ -2411,4 +2415,13 @@ int p2p_group_get_common_freqs(struct p2p_group *group, int *common_freqs,
struct wpabuf * p2p_build_probe_resp_template(struct p2p_data *p2p,
unsigned int freq);
void p2p_set_6ghz_dev_capab(struct p2p_data *p2p, bool allow_6ghz);
bool is_p2p_6ghz_capable(struct p2p_data *p2p);
bool p2p_is_peer_6ghz_capab(struct p2p_data *p2p, const u8 *addr);
bool p2p_peer_wfd_enabled(struct p2p_data *p2p, const u8 *peer_addr);
bool p2p_wfd_enabled(struct p2p_data *p2p);
bool is_p2p_allow_6ghz(struct p2p_data *p2p);
void set_p2p_allow_6ghz(struct p2p_data *p2p, bool value);
int p2p_remove_6ghz_channels(unsigned int *pref_freq_list, int size);
#endif /* P2P_H */

View File

@ -548,6 +548,9 @@ struct p2p_data {
/* Override option for preferred operating channel in GO Negotiation */
u8 override_pref_op_class;
u8 override_pref_channel;
bool p2p_6ghz_capable;
bool include_6ghz;
bool allow_6ghz;
};
/**
@ -698,6 +701,8 @@ int p2p_channel_random_social(struct p2p_channels *chans, u8 *op_class,
u8 *op_channel,
struct wpa_freq_range_list *avoid_list,
struct wpa_freq_range_list *disallow_list);
void p2p_copy_channels(struct p2p_channels *dst, const struct p2p_channels *src,
bool allow_6ghz);
/* p2p_parse.c */
void p2p_copy_filter_devname(char *dst, size_t dst_len,

View File

@ -653,8 +653,9 @@ int p2p_invite(struct p2p_data *p2p, const u8 *peer, enum p2p_invite_role role,
struct p2p_device *dev;
p2p_dbg(p2p, "Request to invite peer " MACSTR " role=%d persistent=%d "
"force_freq=%u",
MAC2STR(peer), role, persistent_group, force_freq);
"force_freq=%u allow_6ghz=%d",
MAC2STR(peer), role, persistent_group, force_freq,
p2p->allow_6ghz);
if (bssid)
p2p_dbg(p2p, "Invitation for BSSID " MACSTR, MAC2STR(bssid));
if (go_dev_addr) {

View File

@ -496,3 +496,42 @@ int p2p_channels_to_freqs(const struct p2p_channels *channels, int *freq_list,
return idx;
}
void p2p_copy_channels(struct p2p_channels *dst,
const struct p2p_channels *src, bool allow_6ghz)
{
size_t i, j;
if (allow_6ghz) {
os_memcpy(dst, src, sizeof(struct p2p_channels));
return;
}
for (i = 0, j = 0; i < P2P_MAX_REG_CLASSES; i++) {
if (is_6ghz_op_class(src->reg_class[i].reg_class))
continue;
os_memcpy(&dst->reg_class[j], &src->reg_class[i],
sizeof(struct p2p_reg_class));
j++;
}
dst->reg_classes = j;
}
int p2p_remove_6ghz_channels(unsigned int *pref_freq_list, int size)
{
int i;
for (i = 0; i < size; i++) {
if (is_6ghz_freq(pref_freq_list[i])) {
wpa_printf(MSG_DEBUG, "P2P: Remove 6 GHz channel %d",
pref_freq_list[i]);
size--;
os_memmove(&pref_freq_list[i], &pref_freq_list[i + 1],
(size - i) * sizeof(pref_freq_list[0]));
i--;
}
}
return i;
}

View File

@ -212,7 +212,8 @@ pmksa_cache_add_entry(struct rsn_pmksa_cache *pmksa,
"that was based on the old PMK");
if (!pos->opportunistic)
pmksa_cache_flush(pmksa, entry->network_ctx,
pos->pmk, pos->pmk_len);
pos->pmk, pos->pmk_len,
false);
pmksa_cache_free_entry(pmksa, pos, PMKSA_REPLACE);
break;
}
@ -282,9 +283,11 @@ pmksa_cache_add_entry(struct rsn_pmksa_cache *pmksa,
* @network_ctx: Network configuration context or %NULL to flush all entries
* @pmk: PMK to match for or %NULL to match all PMKs
* @pmk_len: PMK length
* @external_only: Flush only PMKSA cache entries configured by external
* applications
*/
void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa, void *network_ctx,
const u8 *pmk, size_t pmk_len)
const u8 *pmk, size_t pmk_len, bool external_only)
{
struct rsn_pmksa_cache_entry *entry, *prev = NULL, *tmp;
int removed = 0;
@ -295,7 +298,8 @@ void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa, void *network_ctx,
network_ctx == NULL) &&
(pmk == NULL ||
(pmk_len == entry->pmk_len &&
os_memcmp(pmk, entry->pmk, pmk_len) == 0))) {
os_memcmp(pmk, entry->pmk, pmk_len) == 0)) &&
(!external_only || entry->external)) {
wpa_printf(MSG_DEBUG, "RSN: Flush PMKSA cache entry "
"for " MACSTR, MAC2STR(entry->aa));
if (prev)

View File

@ -43,6 +43,7 @@ struct rsn_pmksa_cache_entry {
*/
void *network_ctx;
int opportunistic;
bool external;
};
struct rsn_pmksa_cache;
@ -84,7 +85,7 @@ struct rsn_pmksa_cache_entry *
pmksa_cache_get_opportunistic(struct rsn_pmksa_cache *pmksa,
void *network_ctx, const u8 *aa, int akmp);
void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa, void *network_ctx,
const u8 *pmk, size_t pmk_len);
const u8 *pmk, size_t pmk_len, bool external_only);
#else /* IEEE8021X_EAPOL */
@ -157,7 +158,8 @@ static inline int pmksa_cache_set_current(struct wpa_sm *sm, const u8 *pmkid,
static inline void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa,
void *network_ctx,
const u8 *pmk, size_t pmk_len)
const u8 *pmk, size_t pmk_len,
bool external_only)
{
}

View File

@ -2345,6 +2345,16 @@ void wpa_sm_aborted_cached(struct wpa_sm *sm)
}
void wpa_sm_aborted_external_cached(struct wpa_sm *sm)
{
if (sm && sm->cur_pmksa && sm->cur_pmksa->external) {
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
"RSN: Cancelling external PMKSA caching attempt");
sm->cur_pmksa = NULL;
}
}
static void wpa_eapol_key_dump(struct wpa_sm *sm,
const struct wpa_eapol_key *key,
unsigned int key_data_len,
@ -3865,7 +3875,13 @@ void wpa_sm_update_replay_ctr(struct wpa_sm *sm, const u8 *replay_ctr)
void wpa_sm_pmksa_cache_flush(struct wpa_sm *sm, void *network_ctx)
{
pmksa_cache_flush(sm->pmksa, network_ctx, NULL, 0);
pmksa_cache_flush(sm->pmksa, network_ctx, NULL, 0, false);
}
void wpa_sm_external_pmksa_cache_flush(struct wpa_sm *sm, void *network_ctx)
{
pmksa_cache_flush(sm->pmksa, network_ctx, NULL, 0, true);
}

View File

@ -180,6 +180,7 @@ int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len,
struct wpa_ie_data *data);
void wpa_sm_aborted_cached(struct wpa_sm *sm);
void wpa_sm_aborted_external_cached(struct wpa_sm *sm);
int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
const u8 *buf, size_t len);
int wpa_sm_parse_own_wpa_ie(struct wpa_sm *sm, struct wpa_ie_data *data);
@ -205,6 +206,7 @@ int wpa_sm_has_ptk_installed(struct wpa_sm *sm);
void wpa_sm_update_replay_ctr(struct wpa_sm *sm, const u8 *replay_ctr);
void wpa_sm_pmksa_cache_flush(struct wpa_sm *sm, void *network_ctx);
void wpa_sm_external_pmksa_cache_flush(struct wpa_sm *sm, void *network_ctx);
int wpa_sm_get_p2p_ip_addr(struct wpa_sm *sm, u8 *buf);
@ -353,6 +355,10 @@ static inline void wpa_sm_aborted_cached(struct wpa_sm *sm)
{
}
static inline void wpa_sm_aborted_external_cached(struct wpa_sm *sm)
{
}
static inline int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
const u8 *buf, size_t len)
{
@ -392,6 +398,11 @@ static inline void wpa_sm_update_replay_ctr(struct wpa_sm *sm,
{
}
static inline void wpa_sm_external_pmksa_cache_flush(struct wpa_sm *sm,
void *network_ctx)
{
}
static inline void wpa_sm_pmksa_cache_flush(struct wpa_sm *sm,
void *network_ctx)
{

View File

@ -841,6 +841,10 @@ struct wps_context {
struct wpabuf *ap_nfc_dh_pubkey;
struct wpabuf *ap_nfc_dh_privkey;
struct wpabuf *ap_nfc_dev_pw;
/* Whether to send WPA2-PSK passphrase as a passphrase instead of PSK
* for WPA3-Personal transition mode needs. */
bool use_passphrase;
};
struct wps_registrar *

View File

@ -1753,8 +1753,10 @@ int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
wpa_snprintf_hex(hex, sizeof(hex), wps->wps->psk, PMK_LEN);
os_memcpy(wps->cred.key, hex, PMK_LEN * 2);
wps->cred.key_len = PMK_LEN * 2;
} else if (!wps->wps->registrar->force_per_enrollee_psk &&
wps->wps->network_key) {
} else if ((!wps->wps->registrar->force_per_enrollee_psk ||
wps->wps->use_passphrase) && wps->wps->network_key) {
wpa_printf(MSG_DEBUG,
"WPS: Use passphrase format for Network key");
os_memcpy(wps->cred.key, wps->wps->network_key,
wps->wps->network_key_len);
wps->cred.key_len = wps->wps->network_key_len;

View File

@ -100,6 +100,11 @@ def test_multi_ap_fronthaul_on_ap(dev, apdev):
if "CTRL-EVENT-DISCONNECTED" not in ev:
raise Exception("Unexpected connection result")
def remove_apdev(dev, ifname):
hglobal = hostapd.HostapdGlobal()
hglobal.remove(ifname)
dev.cmd_execute(['iw', ifname, 'del'])
def run_multi_ap_wps(dev, apdev, params, params_backhaul=None, add_apdev=False,
run_csa=False, allow_csa_fail=False):
"""Helper for running Multi-AP WPS tests
@ -219,10 +224,10 @@ def run_multi_ap_wps(dev, apdev, params, params_backhaul=None, add_apdev=False,
raise Exception("Received disconnection event instead of channel switch event")
if add_apdev:
dev[0].cmd_execute(['iw', wpas_apdev['ifname'], 'del'])
remove_apdev(dev[0], wpas_apdev['ifname'])
except:
if wpas_apdev:
dev[0].cmd_execute(['iw', wpas_apdev['ifname'], 'del'])
remove_apdev(dev[0], wpas_apdev['ifname'])
raise
return hapd

View File

@ -680,6 +680,8 @@ def test_pasn_ft_eap_sha384(dev, apdev):
def test_pasn_sta_mic_error(dev, apdev):
"""PASN authentication with WPA2/CCMP AP with corrupted MIC on station"""
check_pasn_capab(dev[0])
params = pasn_ap_params("PASN", "CCMP", "19")
hapd = hostapd.add_ap(apdev[0], params)
@ -697,6 +699,8 @@ def test_pasn_sta_mic_error(dev, apdev):
def test_pasn_ap_mic_error(dev, apdev):
"""PASN authentication with WPA2/CCMP AP with corrupted MIC on AP"""
check_pasn_capab(dev[0])
params = pasn_ap_params("PASN", "CCMP", "19")
hapd0 = hostapd.add_ap(apdev[0], params)

View File

@ -2775,3 +2775,19 @@ def test_sae_ocv_pmk_failure(dev, apdev):
raise Exception("hostapd did not report correct PMK after disconnection")
if pmk_w2 != pmk_w:
raise Exception("wpa_supplicant did not report correct PMK after disconnection")
def test_sae_reject(dev, apdev):
"""SAE and AP rejecting connection"""
check_sae_capab(dev[0])
params = hostapd.wpa2_params(ssid="test-sae",
passphrase="12345678")
params['wpa_key_mgmt'] = 'SAE'
params['max_num_sta'] = '0'
hapd = hostapd.add_ap(apdev[0], params)
dev[0].set("sae_groups", "")
id = dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
scan_freq="2412", wait_connect=False)
if not dev[0].wait_event(["CTRL-EVENT-AUTH-REJECT"], timeout=10):
raise Exception("Authentication rejection not reported")
dev[0].request("REMOVE_NETWORK all")
dev[0].dump_monitor()

View File

@ -109,13 +109,15 @@ static void wpas_conf_ap_vht(struct wpa_supplicant *wpa_s,
switch (hostapd_get_oper_chwidth(conf)) {
case CHANWIDTH_80MHZ:
case CHANWIDTH_80P80MHZ:
center_chan = wpas_p2p_get_vht80_center(wpa_s, mode, channel);
center_chan = wpas_p2p_get_vht80_center(wpa_s, mode, channel,
conf->op_class);
wpa_printf(MSG_DEBUG,
"VHT center channel %u for 80 or 80+80 MHz bandwidth",
center_chan);
break;
case CHANWIDTH_160MHZ:
center_chan = wpas_p2p_get_vht160_center(wpa_s, mode, channel);
center_chan = wpas_p2p_get_vht160_center(wpa_s, mode, channel,
conf->op_class);
wpa_printf(MSG_DEBUG,
"VHT center channel %u for 160 MHz bandwidth",
center_chan);
@ -127,15 +129,25 @@ static void wpas_conf_ap_vht(struct wpa_supplicant *wpa_s,
* not supported.
*/
hostapd_set_oper_chwidth(conf, CHANWIDTH_160MHZ);
center_chan = wpas_p2p_get_vht160_center(wpa_s, mode, channel);
ieee80211_freq_to_channel_ext(ssid->frequency, 0,
conf->vht_oper_chwidth,
&conf->op_class,
&conf->channel);
center_chan = wpas_p2p_get_vht160_center(wpa_s, mode, channel,
conf->op_class);
if (center_chan && is_chanwidth160_supported(mode, conf)) {
wpa_printf(MSG_DEBUG,
"VHT center channel %u for auto-selected 160 MHz bandwidth",
center_chan);
} else {
hostapd_set_oper_chwidth(conf, CHANWIDTH_80MHZ);
ieee80211_freq_to_channel_ext(ssid->frequency, 0,
conf->vht_oper_chwidth,
&conf->op_class,
&conf->channel);
center_chan = wpas_p2p_get_vht80_center(wpa_s, mode,
channel);
channel,
conf->op_class);
wpa_printf(MSG_DEBUG,
"VHT center channel %u for auto-selected 80 MHz bandwidth",
center_chan);
@ -183,9 +195,15 @@ int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid,
struct hostapd_config *conf)
{
conf->hw_mode = ieee80211_freq_to_chan(ssid->frequency,
&conf->channel);
conf->hw_mode = ieee80211_freq_to_channel_ext(ssid->frequency, 0,
ssid->max_oper_chwidth,
&conf->op_class,
&conf->channel);
/* ssid->max_oper_chwidth is not valid in all cases, so fall back to the
* less specific mechanism, if needed, at least for now */
if (conf->hw_mode == NUM_HOSTAPD_MODES)
conf->hw_mode = ieee80211_freq_to_chan(ssid->frequency,
&conf->channel);
if (conf->hw_mode == NUM_HOSTAPD_MODES) {
wpa_printf(MSG_ERROR, "Unsupported AP mode frequency: %d MHz",
ssid->frequency);
@ -874,6 +892,8 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
params.wpa_proto = ssid->proto;
if (ssid->key_mgmt & WPA_KEY_MGMT_PSK)
wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
else if (ssid->key_mgmt & WPA_KEY_MGMT_SAE)
wpa_s->key_mgmt = WPA_KEY_MGMT_SAE;
else
wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
params.key_mgmt_suite = wpa_s->key_mgmt;

View File

@ -5723,12 +5723,16 @@ static int p2p_ctrl_find(struct wpa_supplicant *wpa_s, char *cmd)
const char *_seek[P2P_MAX_QUERY_HASH + 1], **seek = NULL;
u8 seek_count = 0;
int freq = 0;
bool include_6ghz = false;
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
wpa_dbg(wpa_s, MSG_INFO,
"Reject P2P_FIND since interface is disabled");
return -1;
}
if (os_strstr(cmd, " include_6ghz"))
include_6ghz = true;
if (os_strstr(cmd, "type=social"))
type = P2P_FIND_ONLY_SOCIAL;
else if (os_strstr(cmd, "type=progressive"))
@ -5788,7 +5792,8 @@ static int p2p_ctrl_find(struct wpa_supplicant *wpa_s, char *cmd)
}
return wpas_p2p_find(wpa_s, timeout, type, _dev_type != NULL, _dev_type,
_dev_id, search_delay, seek_count, seek, freq);
_dev_id, search_delay, seek_count, seek, freq,
include_6ghz);
}
@ -6041,6 +6046,7 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
u8 _group_ssid[SSID_MAX_LEN], *group_ssid = NULL;
size_t group_ssid_len = 0;
int he;
bool allow_6ghz;
if (!wpa_s->global->p2p_init_wpa_s)
return -1;
@ -6078,6 +6084,7 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
}
}
join = os_strstr(pos, " join") != NULL;
allow_6ghz = os_strstr(pos, " allow_6ghz") != NULL;
auth = os_strstr(pos, " auth") != NULL;
automatic = os_strstr(pos, " auto") != NULL;
pd = os_strstr(pos, " provdisc") != NULL;
@ -6157,7 +6164,7 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
persistent_group, automatic, join,
auth, go_intent, freq, freq2, persistent_id,
pd, ht40, vht, max_oper_chwidth, he, edmg,
group_ssid, group_ssid_len);
group_ssid, group_ssid_len, allow_6ghz);
if (new_pin == -2) {
os_memcpy(buf, "FAIL-CHANNEL-UNAVAILABLE\n", 25);
return 25;
@ -6714,6 +6721,7 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd)
int freq = 0, pref_freq = 0;
int ht40, vht, he, max_oper_chwidth, chwidth = 0, freq2 = 0;
int edmg;
bool allow_6ghz;
id = atoi(cmd);
pos = os_strstr(cmd, " peer=");
@ -6765,8 +6773,11 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd)
if (max_oper_chwidth < 0)
return -1;
allow_6ghz = os_strstr(cmd, " allow_6ghz") != NULL;
return wpas_p2p_invite(wpa_s, _peer, ssid, NULL, freq, freq2, ht40, vht,
max_oper_chwidth, pref_freq, he, edmg);
max_oper_chwidth, pref_freq, he, edmg,
allow_6ghz);
}
@ -6774,6 +6785,7 @@ static int p2p_ctrl_invite_group(struct wpa_supplicant *wpa_s, char *cmd)
{
char *pos;
u8 peer[ETH_ALEN], go_dev_addr[ETH_ALEN], *go_dev = NULL;
bool allow_6ghz;
pos = os_strstr(cmd, " peer=");
if (!pos)
@ -6786,6 +6798,8 @@ static int p2p_ctrl_invite_group(struct wpa_supplicant *wpa_s, char *cmd)
return -1;
}
allow_6ghz = os_strstr(pos, " allow_6ghz") != NULL;
pos = os_strstr(pos, " go_dev_addr=");
if (pos) {
pos += 13;
@ -6797,7 +6811,7 @@ static int p2p_ctrl_invite_group(struct wpa_supplicant *wpa_s, char *cmd)
go_dev = go_dev_addr;
}
return wpas_p2p_invite_group(wpa_s, cmd, peer, go_dev);
return wpas_p2p_invite_group(wpa_s, cmd, peer, go_dev, allow_6ghz);
}
@ -6815,7 +6829,7 @@ static int p2p_ctrl_invite(struct wpa_supplicant *wpa_s, char *cmd)
static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
int id, int freq, int vht_center_freq2,
int ht40, int vht, int vht_chwidth,
int he, int edmg)
int he, int edmg, bool allow_6ghz)
{
struct wpa_ssid *ssid;
@ -6830,13 +6844,14 @@ static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq,
vht_center_freq2, 0, ht40, vht,
vht_chwidth, he, edmg,
NULL, 0, 0);
NULL, 0, 0, allow_6ghz);
}
static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
{
int freq = 0, persistent = 0, group_id = -1;
bool allow_6ghz = false;
int vht = wpa_s->conf->p2p_go_vht;
int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
int he = wpa_s->conf->p2p_go_he;
@ -6869,6 +6884,8 @@ static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
edmg = 1;
} else if (os_strcmp(token, "persistent") == 0) {
persistent = 1;
} else if (os_strcmp(token, "allow_6ghz") == 0) {
allow_6ghz = true;
} else {
wpa_printf(MSG_DEBUG,
"CTRL: Invalid P2P_GROUP_ADD parameter: '%s'",
@ -6905,10 +6922,10 @@ static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
return p2p_ctrl_group_add_persistent(wpa_s, group_id,
freq, freq2, ht40, vht,
max_oper_chwidth, he,
edmg);
edmg, allow_6ghz);
return wpas_p2p_group_add(wpa_s, persistent, freq, freq2, ht40, vht,
max_oper_chwidth, he, edmg);
max_oper_chwidth, he, edmg, allow_6ghz);
}
@ -10606,6 +10623,8 @@ static int wpas_ctrl_iface_pmksa_add(struct wpa_supplicant *wpa_s,
entry->network_ctx = ssid;
entry->external = true;
wpa_sm_pmksa_cache_add_entry(wpa_s->wpa, entry);
entry = NULL;
ret = 0;

View File

@ -175,7 +175,7 @@ DBusMessage * wpas_dbus_handler_p2p_find(DBusMessage *message,
}
if (wpas_p2p_find(wpa_s, timeout, type, num_req_dev_types,
req_dev_types, NULL, 0, 0, NULL, freq))
req_dev_types, NULL, 0, 0, NULL, freq, false))
reply = wpas_dbus_error_unknown_error(
message, "Could not start P2P find");
@ -425,14 +425,15 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message,
goto inv_args;
if (wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0, 0, 0,
0, 0, 0, 0, NULL, 0, 0)) {
0, 0, 0, 0, NULL, 0, 0,
false)) {
reply = wpas_dbus_error_unknown_error(
message,
"Failed to reinvoke a persistent group");
goto out;
}
} else if (wpas_p2p_group_add(wpa_s, persistent_group, freq, 0, 0, 0,
0, 0, 0))
0, 0, 0, false))
goto inv_args;
out:
@ -653,7 +654,7 @@ DBusMessage * wpas_dbus_handler_p2p_connect(DBusMessage *message,
new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method,
persistent_group, 0, join, authorize_only,
go_intent, freq, 0, -1, 0, 0, 0, 0, 0, 0,
NULL, 0);
NULL, 0, false);
if (new_pin >= 0) {
char npin[9];
@ -810,7 +811,7 @@ DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message,
goto err;
if (wpas_p2p_invite(wpa_s, peer_addr, ssid, NULL, 0, 0, 0, 0, 0,
0, 0, 0) < 0) {
0, 0, 0, false) < 0) {
reply = wpas_dbus_error_unknown_error(
message,
"Failed to reinvoke a persistent group");
@ -821,7 +822,7 @@ DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message,
* No group ID means propose to a peer to join my active group
*/
if (wpas_p2p_invite_group(wpa_s, wpa_s->ifname,
peer_addr, NULL)) {
peer_addr, NULL, false)) {
reply = wpas_dbus_error_unknown_error(
message, "Failed to join to an active group");
goto out;

View File

@ -4621,6 +4621,7 @@ static void wpas_event_assoc_reject(struct wpa_supplicant *wpa_s,
#ifdef CONFIG_FILS
/* Update ERP next sequence number */
if (wpa_s->auth_alg == WPA_AUTH_ALG_FILS) {
fils_pmksa_cache_flush(wpa_s);
eapol_sm_update_erp_next_seq_num(
wpa_s->eapol,
data->assoc_reject.fils_erp_next_seq_num);

View File

@ -347,9 +347,9 @@ static void wpas_p2p_trigger_scan_cb(struct wpa_radio_work *work, int deinit)
params->only_new_results = 1;
}
if (wpa_s->conf->p2p_6ghz_disable && !params->freqs) {
if (!params->p2p_include_6ghz && !params->freqs) {
wpa_printf(MSG_DEBUG,
"P2P: 6 GHz disabled - update the scan frequency list");
"P2P: Exclude 6 GHz channels - update the scan frequency list");
wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G, params,
0);
wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211A, params,
@ -394,7 +394,8 @@ static int wpas_p2p_search_social_channel(struct wpa_supplicant *wpa_s,
static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
unsigned int num_req_dev_types,
const u8 *req_dev_types, const u8 *dev_id, u16 pw_id)
const u8 *req_dev_types, const u8 *dev_id, u16 pw_id,
bool include_6ghz)
{
struct wpa_supplicant *wpa_s = ctx;
struct wpa_driver_scan_params *params = NULL;
@ -432,7 +433,8 @@ static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,
num_req_dev_types, req_dev_types);
if (wps_ie == NULL)
goto fail;
if (!wpa_s->conf->p2p_6ghz_disable)
params->p2p_include_6ghz = include_6ghz;
switch (type) {
case P2P_SCAN_SOCIAL:
params->freqs = os_calloc(ARRAY_SIZE(social_channels_freq) + 1,
@ -2063,6 +2065,14 @@ static void wpas_start_wps_go(struct wpa_supplicant *wpa_s,
}
ssid->auth_alg = WPA_AUTH_ALG_OPEN;
ssid->key_mgmt = WPA_KEY_MGMT_PSK;
if (is_6ghz_freq(ssid->frequency) &&
is_p2p_6ghz_capable(wpa_s->global->p2p)) {
ssid->auth_alg |= WPA_AUTH_ALG_SAE;
ssid->key_mgmt = WPA_KEY_MGMT_SAE;
wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Use SAE auth_alg and key_mgmt");
} else {
p2p_set_6ghz_dev_capab(wpa_s->global->p2p, false);
}
ssid->proto = WPA_PROTO_RSN;
ssid->pairwise_cipher = WPA_CIPHER_CCMP;
ssid->group_cipher = WPA_CIPHER_CCMP;
@ -3234,7 +3244,7 @@ static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid,
wpa_s->conf->p2p_go_he,
wpa_s->conf->p2p_go_edmg, NULL,
go ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0,
1);
1, is_p2p_allow_6ghz(wpa_s->global->p2p));
} else if (bssid) {
wpa_s->user_initiated_pd = 0;
wpa_msg_global(wpa_s, MSG_INFO,
@ -3463,7 +3473,8 @@ static void wpas_invitation_result(void *ctx, int status, const u8 *bssid,
channels,
ssid->mode == WPAS_MODE_P2P_GO ?
P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
0, 1);
0, 1,
is_p2p_allow_6ghz(wpa_s->global->p2p));
}
@ -3545,19 +3556,19 @@ static int wpas_p2p_default_channels(struct wpa_supplicant *wpa_s,
}
static int has_channel(struct wpa_global *global,
struct hostapd_hw_modes *mode, u8 chan, int *flags)
static enum chan_allowed has_channel(struct wpa_global *global,
struct hostapd_hw_modes *mode, u8 op_class,
u8 chan, int *flags)
{
int i;
unsigned int freq;
freq = (mode->mode == HOSTAPD_MODE_IEEE80211A ? 5000 : 2407) +
chan * 5;
freq = ieee80211_chan_to_freq(NULL, op_class, chan);
if (wpas_p2p_disallowed_freq(global, freq))
return NOT_ALLOWED;
for (i = 0; i < mode->num_channels; i++) {
if (mode->channels[i].chan == chan) {
if ((unsigned int) mode->channels[i].freq == freq) {
if (flags)
*flags = mode->channels[i].flag;
if (mode->channels[i].flag &
@ -3576,15 +3587,15 @@ static int has_channel(struct wpa_global *global,
static int wpas_p2p_get_center_80mhz(struct wpa_supplicant *wpa_s,
struct hostapd_hw_modes *mode,
u8 channel)
u8 channel, const u8 *center_channels,
size_t num_chan)
{
u8 center_channels[] = { 42, 58, 106, 122, 138, 155, 171 };
size_t i;
if (mode->mode != HOSTAPD_MODE_IEEE80211A)
return 0;
for (i = 0; i < ARRAY_SIZE(center_channels); i++)
for (i = 0; i < num_chan; i++)
/*
* In 80 MHz, the bandwidth "spans" 12 channels (e.g., 36-48),
* so the center channel is 6 channels away from the start/end.
@ -3597,25 +3608,43 @@ static int wpas_p2p_get_center_80mhz(struct wpa_supplicant *wpa_s,
}
static const u8 center_channels_5ghz_80mhz[] = { 42, 58, 106, 122, 138,
155, 171 };
static const u8 center_channels_6ghz_80mhz[] = { 7, 23, 39, 55, 71, 87, 103,
119, 135, 151, 167, 183, 199,
215 };
static enum chan_allowed wpas_p2p_verify_80mhz(struct wpa_supplicant *wpa_s,
struct hostapd_hw_modes *mode,
u8 channel, u8 bw)
u8 op_class, u8 channel, u8 bw)
{
u8 center_chan;
int i, flags;
enum chan_allowed res, ret = ALLOWED;
const u8 *chans;
size_t num_chans;
bool is_6ghz = is_6ghz_op_class(op_class);
center_chan = wpas_p2p_get_center_80mhz(wpa_s, mode, channel);
if (is_6ghz) {
chans = center_channels_6ghz_80mhz;
num_chans = ARRAY_SIZE(center_channels_6ghz_80mhz);
} else {
chans = center_channels_5ghz_80mhz;
num_chans = ARRAY_SIZE(center_channels_5ghz_80mhz);
}
center_chan = wpas_p2p_get_center_80mhz(wpa_s, mode, channel,
chans, num_chans);
if (!center_chan)
return NOT_ALLOWED;
if (center_chan >= 58 && center_chan <= 138)
if (!is_6ghz && center_chan >= 58 && center_chan <= 138)
return NOT_ALLOWED; /* Do not allow DFS channels for P2P */
/* check all the channels are available */
for (i = 0; i < 4; i++) {
int adj_chan = center_chan - 6 + i * 4;
res = has_channel(wpa_s->global, mode, adj_chan, &flags);
res = has_channel(wpa_s->global, mode, op_class, adj_chan,
&flags);
if (res == NOT_ALLOWED)
return NOT_ALLOWED;
if (res == NO_IR)
@ -3637,15 +3666,15 @@ static enum chan_allowed wpas_p2p_verify_80mhz(struct wpa_supplicant *wpa_s,
static int wpas_p2p_get_center_160mhz(struct wpa_supplicant *wpa_s,
struct hostapd_hw_modes *mode,
u8 channel)
u8 channel, const u8 *center_channels,
size_t num_chan)
{
u8 center_channels[] = { 50, 114, 163 };
unsigned int i;
if (mode->mode != HOSTAPD_MODE_IEEE80211A)
return 0;
for (i = 0; i < ARRAY_SIZE(center_channels); i++)
for (i = 0; i < num_chan; i++)
/*
* In 160 MHz, the bandwidth "spans" 28 channels (e.g., 36-64),
* so the center channel is 14 channels away from the start/end.
@ -3658,15 +3687,29 @@ static int wpas_p2p_get_center_160mhz(struct wpa_supplicant *wpa_s,
}
static const u8 center_channels_5ghz_160mhz[] = { 50, 114, 163 };
static const u8 center_channels_6ghz_160mhz[] = { 15, 47, 79, 111, 143, 175,
207 };
static enum chan_allowed wpas_p2p_verify_160mhz(struct wpa_supplicant *wpa_s,
struct hostapd_hw_modes *mode,
u8 channel, u8 bw)
u8 op_class, u8 channel, u8 bw)
{
u8 center_chan;
int i, flags;
enum chan_allowed res, ret = ALLOWED;
const u8 *chans;
size_t num_chans;
center_chan = wpas_p2p_get_center_160mhz(wpa_s, mode, channel);
if (is_6ghz_op_class(op_class)) {
chans = center_channels_6ghz_160mhz;
num_chans = ARRAY_SIZE(center_channels_6ghz_160mhz);
} else {
chans = center_channels_5ghz_160mhz;
num_chans = ARRAY_SIZE(center_channels_5ghz_160mhz);
}
center_chan = wpas_p2p_get_center_160mhz(wpa_s, mode, channel,
chans, num_chans);
if (!center_chan)
return NOT_ALLOWED;
/* VHT 160 MHz uses DFS channels in most countries. */
@ -3675,7 +3718,8 @@ static enum chan_allowed wpas_p2p_verify_160mhz(struct wpa_supplicant *wpa_s,
for (i = 0; i < 8; i++) {
int adj_chan = center_chan - 14 + i * 4;
res = has_channel(wpa_s->global, mode, adj_chan, &flags);
res = has_channel(wpa_s->global, mode, op_class, adj_chan,
&flags);
if (res == NOT_ALLOWED)
return NOT_ALLOWED;
@ -3720,24 +3764,28 @@ static enum chan_allowed wpas_p2p_verify_edmg(struct wpa_supplicant *wpa_s,
static enum chan_allowed wpas_p2p_verify_channel(struct wpa_supplicant *wpa_s,
struct hostapd_hw_modes *mode,
u8 channel, u8 bw)
u8 op_class, u8 channel, u8 bw)
{
int flag = 0;
enum chan_allowed res, res2;
res2 = res = has_channel(wpa_s->global, mode, channel, &flag);
res2 = res = has_channel(wpa_s->global, mode, op_class, channel, &flag);
if (bw == BW40MINUS) {
if (!(flag & HOSTAPD_CHAN_HT40MINUS))
return NOT_ALLOWED;
res2 = has_channel(wpa_s->global, mode, channel - 4, NULL);
res2 = has_channel(wpa_s->global, mode, op_class, channel - 4,
NULL);
} else if (bw == BW40PLUS) {
if (!(flag & HOSTAPD_CHAN_HT40PLUS))
return NOT_ALLOWED;
res2 = has_channel(wpa_s->global, mode, channel + 4, NULL);
res2 = has_channel(wpa_s->global, mode, op_class, channel + 4,
NULL);
} else if (bw == BW80) {
res2 = wpas_p2p_verify_80mhz(wpa_s, mode, channel, bw);
res2 = wpas_p2p_verify_80mhz(wpa_s, mode, op_class, channel,
bw);
} else if (bw == BW160) {
res2 = wpas_p2p_verify_160mhz(wpa_s, mode, channel, bw);
res2 = wpas_p2p_verify_160mhz(wpa_s, mode, op_class, channel,
bw);
} else if (bw == BW4320 || bw == BW6480 || bw == BW8640) {
return wpas_p2p_verify_edmg(wpa_s, mode, channel);
}
@ -3791,7 +3839,8 @@ static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
ch < 149 && ch + o->inc > 149)
ch = 149;
res = wpas_p2p_verify_channel(wpa_s, mode, ch, o->bw);
res = wpas_p2p_verify_channel(wpa_s, mode, o->op_class,
ch, o->bw);
if (res == ALLOWED) {
if (reg == NULL) {
if (cla == P2P_MAX_REG_CLASSES)
@ -3861,7 +3910,8 @@ int wpas_p2p_get_ht40_mode(struct wpa_supplicant *wpa_s,
(o->bw != BW40PLUS && o->bw != BW40MINUS) ||
ch != channel)
continue;
ret = wpas_p2p_verify_channel(wpa_s, mode, ch, o->bw);
ret = wpas_p2p_verify_channel(wpa_s, mode, o->op_class,
ch, o->bw);
if (ret == ALLOWED)
return (o->bw == BW40MINUS) ? -1 : 1;
}
@ -3871,21 +3921,45 @@ int wpas_p2p_get_ht40_mode(struct wpa_supplicant *wpa_s,
int wpas_p2p_get_vht80_center(struct wpa_supplicant *wpa_s,
struct hostapd_hw_modes *mode, u8 channel)
struct hostapd_hw_modes *mode, u8 channel,
u8 op_class)
{
if (!wpas_p2p_verify_channel(wpa_s, mode, channel, BW80))
const u8 *chans;
size_t num_chans;
if (!wpas_p2p_verify_channel(wpa_s, mode, op_class, channel, BW80))
return 0;
return wpas_p2p_get_center_80mhz(wpa_s, mode, channel);
if (is_6ghz_op_class(op_class)) {
chans = center_channels_6ghz_80mhz;
num_chans = ARRAY_SIZE(center_channels_6ghz_80mhz);
} else {
chans = center_channels_5ghz_80mhz;
num_chans = ARRAY_SIZE(center_channels_5ghz_80mhz);
}
return wpas_p2p_get_center_80mhz(wpa_s, mode, channel,
chans, num_chans);
}
int wpas_p2p_get_vht160_center(struct wpa_supplicant *wpa_s,
struct hostapd_hw_modes *mode, u8 channel)
struct hostapd_hw_modes *mode, u8 channel,
u8 op_class)
{
if (!wpas_p2p_verify_channel(wpa_s, mode, channel, BW160))
const u8 *chans;
size_t num_chans;
if (!wpas_p2p_verify_channel(wpa_s, mode, op_class, channel, BW160))
return 0;
return wpas_p2p_get_center_160mhz(wpa_s, mode, channel);
if (is_6ghz_op_class(op_class)) {
chans = center_channels_6ghz_160mhz;
num_chans = ARRAY_SIZE(center_channels_6ghz_160mhz);
} else {
chans = center_channels_5ghz_160mhz;
num_chans = ARRAY_SIZE(center_channels_5ghz_160mhz);
}
return wpas_p2p_get_center_160mhz(wpa_s, mode, channel,
chans, num_chans);
}
@ -4425,10 +4499,10 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev,
persistent_go->mode ==
WPAS_MODE_P2P_GO ?
P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
0, 0);
0, 0, false);
} else if (response_done) {
wpas_p2p_group_add(wpa_s, 1, freq,
0, 0, 0, 0, 0, 0);
0, 0, 0, 0, 0, 0, false);
}
if (passwd_id == DEV_PW_P2PS_DEFAULT) {
@ -4547,9 +4621,11 @@ static int wpas_prov_disc_resp_cb(void *ctx)
wpa_s, persistent_go, 0, 0, 0, 0, 0, 0, 0, 0, 0,
NULL,
persistent_go->mode == WPAS_MODE_P2P_GO ?
P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0, 0);
P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0, 0,
is_p2p_allow_6ghz(wpa_s->global->p2p));
} else {
wpas_p2p_group_add(wpa_s, 1, freq, 0, 0, 0, 0, 0, 0);
wpas_p2p_group_add(wpa_s, 1, freq, 0, 0, 0, 0, 0, 0,
is_p2p_allow_6ghz(wpa_s->global->p2p));
}
return 1;
@ -5157,7 +5233,8 @@ static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s,
wpa_s->p2p_go_max_oper_chwidth,
wpa_s->p2p_go_he,
wpa_s->p2p_go_edmg,
NULL, 0);
NULL, 0,
is_p2p_allow_6ghz(wpa_s->global->p2p));
return;
}
@ -5355,7 +5432,8 @@ static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq,
if (freq > 0) {
freqs[0] = freq;
params.freqs = freqs;
} else if (wpa_s->conf->p2p_6ghz_disable) {
} else if (wpa_s->conf->p2p_6ghz_disable ||
!is_p2p_allow_6ghz(wpa_s->global->p2p)) {
wpa_printf(MSG_DEBUG,
"P2P: 6 GHz disabled - update the scan frequency list");
wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G, &params,
@ -5392,7 +5470,7 @@ static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq,
* the new scan results become available.
*/
ret = wpa_drv_scan(wpa_s, &params);
if (wpa_s->conf->p2p_6ghz_disable && params.freqs != freqs)
if (params.freqs != freqs)
os_free(params.freqs);
if (!ret) {
os_get_reltime(&wpa_s->scan_trigger_time);
@ -5622,6 +5700,10 @@ static int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq,
res = wpa_drv_get_pref_freq_list(wpa_s, iface_type,
&max_pref_freq,
pref_freq_list);
if (!is_p2p_allow_6ghz(wpa_s->global->p2p))
max_pref_freq = p2p_remove_6ghz_channels(pref_freq_list,
max_pref_freq);
if (!res && max_pref_freq > 0) {
*num_pref_freq = max_pref_freq;
i = 0;
@ -5681,6 +5763,40 @@ static int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq,
}
static bool is_p2p_6ghz_supported(struct wpa_supplicant *wpa_s,
const u8 *peer_addr)
{
if (wpa_s->conf->p2p_6ghz_disable ||
!get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
HOSTAPD_MODE_IEEE80211A, true))
return false;
if (!p2p_wfd_enabled(wpa_s->global->p2p))
return false;
if (peer_addr && !p2p_peer_wfd_enabled(wpa_s->global->p2p, peer_addr))
return false;
return true;
}
static int wpas_p2p_check_6ghz(struct wpa_supplicant *wpa_s,
const u8 *peer_addr, bool allow_6ghz, int freq)
{
if (allow_6ghz && is_p2p_6ghz_supported(wpa_s, peer_addr)) {
wpa_printf(MSG_DEBUG,
"P2P: Allow connection on 6 GHz channels");
p2p_set_6ghz_dev_capab(wpa_s->global->p2p, true);
} else {
if (is_6ghz_freq(freq))
return -2;
p2p_set_6ghz_dev_capab(wpa_s->global->p2p, false);
}
return 0;
}
/**
* wpas_p2p_connect - Request P2P Group Formation to be started
* @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
@ -5705,6 +5821,7 @@ static int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq,
* (CHANWIDTH_*).
* @group_ssid: Specific Group SSID for join or %NULL if not set
* @group_ssid_len: Length of @group_ssid in octets
* @allow_6ghz: Allow P2P connection on 6 GHz channels
* Returns: 0 or new PIN (if pin was %NULL) on success, -1 on unspecified
* failure, -2 on failure due to channel not currently available,
* -3 if forced channel is not supported
@ -5715,7 +5832,8 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
int go_intent, int freq, unsigned int vht_center_freq2,
int persistent_id, int pd, int ht40, int vht,
unsigned int vht_chwidth, int he, int edmg,
const u8 *group_ssid, size_t group_ssid_len)
const u8 *group_ssid, size_t group_ssid_len,
bool allow_6ghz)
{
int force_freq = 0, pref_freq = 0;
int ret = 0, res;
@ -5734,7 +5852,7 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
return -1;
}
if (is_6ghz_freq(freq) && wpa_s->conf->p2p_6ghz_disable)
if (wpas_p2p_check_6ghz(wpa_s, peer_addr, allow_6ghz, freq))
return -2;
os_free(wpa_s->global->add_psk);
@ -6012,6 +6130,9 @@ static int wpas_p2p_select_go_freq(struct wpa_supplicant *wpa_s, int freq)
res = wpa_drv_get_pref_freq_list(wpa_s, WPA_IF_P2P_GO,
&size, pref_freq_list);
if (!is_p2p_allow_6ghz(wpa_s->global->p2p))
size = p2p_remove_6ghz_channels(pref_freq_list, size);
if (!res && size > 0) {
i = 0;
while (i < size &&
@ -6439,14 +6560,16 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
enum hostapd_hw_mode mode;
struct hostapd_hw_modes *hwmode;
u8 chan;
u8 op_class;
cand = wpa_s->p2p_group_common_freqs[i];
op_class = is_6ghz_freq(cand) ? 133 : 128;
mode = ieee80211_freq_to_chan(cand, &chan);
hwmode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
mode, is_6ghz_freq(cand));
if (!hwmode ||
wpas_p2p_verify_channel(wpa_s, hwmode, chan,
BW80) != ALLOWED)
wpas_p2p_verify_channel(wpa_s, hwmode, op_class,
chan, BW80) != ALLOWED)
continue;
if (wpas_p2p_supported_freq_go(wpa_s, channels, cand)) {
params->freq = cand;
@ -6465,20 +6588,44 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
for (i = 0; i < wpa_s->p2p_group_common_freqs_num; i++) {
enum hostapd_hw_mode mode;
struct hostapd_hw_modes *hwmode;
u8 chan;
u8 chan, op_class;
bool is_6ghz, supported = false;
is_6ghz = is_6ghz_freq(cand);
cand = wpa_s->p2p_group_common_freqs[i];
mode = ieee80211_freq_to_chan(cand, &chan);
hwmode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
mode, is_6ghz_freq(cand));
mode, is_6ghz);
if (!wpas_same_band(wpa_s->current_ssid->frequency,
cand) ||
!hwmode ||
(wpas_p2p_verify_channel(wpa_s, hwmode, chan,
BW40MINUS) != ALLOWED &&
wpas_p2p_verify_channel(wpa_s, hwmode, chan,
BW40PLUS) != ALLOWED))
!hwmode)
continue;
if (is_6ghz &&
wpas_p2p_verify_channel(wpa_s, hwmode, 132, chan,
BW40) == ALLOWED)
supported = true;
if (!is_6ghz &&
ieee80211_freq_to_channel_ext(
cand, -1, CHANWIDTH_USE_HT, &op_class,
&chan) != NUM_HOSTAPD_MODES &&
wpas_p2p_verify_channel(
wpa_s, hwmode, op_class, chan,
BW40MINUS) == ALLOWED)
supported = true;
if (!supported && !is_6ghz &&
ieee80211_freq_to_channel_ext(
cand, 1, CHANWIDTH_USE_HT, &op_class,
&chan) != NUM_HOSTAPD_MODES &&
wpas_p2p_verify_channel(
wpa_s, hwmode, op_class, chan,
BW40PLUS) == ALLOWED)
supported = true;
if (!supported)
continue;
if (wpas_p2p_supported_freq_go(wpa_s, channels, cand)) {
params->freq = cand;
wpa_printf(MSG_DEBUG,
@ -6599,6 +6746,7 @@ wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated,
* @vht: Start GO with VHT support
* @vht_chwidth: channel bandwidth for GO operating with VHT support
* @edmg: Start GO with EDMG support
* @allow_6ghz: Allow P2P group creation on a 6 GHz channel
* Returns: 0 on success, -1 on failure
*
* This function creates a new P2P group with the local end as the Group Owner,
@ -6606,12 +6754,15 @@ wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated,
*/
int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
int freq, int vht_center_freq2, int ht40, int vht,
int max_oper_chwidth, int he, int edmg)
int max_oper_chwidth, int he, int edmg,
bool allow_6ghz)
{
struct p2p_go_neg_results params;
if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
return -1;
if (wpas_p2p_check_6ghz(wpa_s, NULL, allow_6ghz, freq))
return -1;
os_free(wpa_s->global->add_psk);
wpa_s->global->add_psk = NULL;
@ -6710,7 +6861,8 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
int vht, int max_oper_chwidth, int he,
int edmg,
const struct p2p_channels *channels,
int connection_timeout, int force_scan)
int connection_timeout, int force_scan,
bool allow_6ghz)
{
struct p2p_go_neg_results params;
int go = 0, freq;
@ -7102,7 +7254,8 @@ int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,
enum p2p_discovery_type type,
unsigned int num_req_dev_types, const u8 *req_dev_types,
const u8 *dev_id, unsigned int search_delay,
u8 seek_cnt, const char **seek_string, int freq)
u8 seek_cnt, const char **seek_string, int freq,
bool include_6ghz)
{
wpas_p2p_clear_pending_action_tx(wpa_s);
wpa_s->global->p2p_long_listen = 0;
@ -7121,7 +7274,8 @@ int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,
return p2p_find(wpa_s->global->p2p, timeout, type,
num_req_dev_types, req_dev_types, dev_id,
search_delay, seek_cnt, seek_string, freq);
search_delay, seek_cnt, seek_string, freq,
include_6ghz);
}
@ -7337,7 +7491,7 @@ int wpas_p2p_reject(struct wpa_supplicant *wpa_s, const u8 *addr)
int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq,
int vht_center_freq2, int ht40, int vht, int max_chwidth,
int pref_freq, int he, int edmg)
int pref_freq, int he, int edmg, bool allow_6ghz)
{
enum p2p_invite_role role;
u8 *bssid = NULL;
@ -7346,6 +7500,9 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
int no_pref_freq_given = pref_freq == 0;
unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS], size;
if (wpas_p2p_check_6ghz(wpa_s, NULL, allow_6ghz, freq))
return -1;
wpa_s->global->p2p_invite_group = NULL;
if (peer_addr)
os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN);
@ -7420,7 +7577,8 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
/* Invite to join an active group */
int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname,
const u8 *peer_addr, const u8 *go_dev_addr)
const u8 *peer_addr, const u8 *go_dev_addr,
bool allow_6ghz)
{
struct wpa_global *global = wpa_s->global;
enum p2p_invite_role role;
@ -7483,6 +7641,8 @@ int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname,
if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
return -1;
if (wpas_p2p_check_6ghz(wpa_s, peer_addr, allow_6ghz, freq))
return -1;
size = P2P_MAX_PREF_CHANNELS;
res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,
@ -8385,7 +8545,7 @@ static int wpas_p2p_fallback_to_go_neg(struct wpa_supplicant *wpa_s,
wpa_s->p2p_go_max_oper_chwidth,
wpa_s->p2p_go_he,
wpa_s->p2p_go_edmg,
NULL, 0);
NULL, 0, is_p2p_allow_6ghz(wpa_s->global->p2p));
return ret;
}
@ -8923,7 +9083,7 @@ static int wpas_p2p_nfc_join_group(struct wpa_supplicant *wpa_s,
-1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth,
wpa_s->p2p_go_he, wpa_s->p2p_go_edmg,
params->go_ssid_len ? params->go_ssid : NULL,
params->go_ssid_len);
params->go_ssid_len, false);
}
@ -9002,7 +9162,7 @@ static int wpas_p2p_nfc_init_go_neg(struct wpa_supplicant *wpa_s,
forced_freq, wpa_s->p2p_go_vht_center_freq2,
-1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth,
wpa_s->p2p_go_he, wpa_s->p2p_go_edmg,
NULL, 0);
NULL, 0, false);
}
@ -9019,7 +9179,7 @@ static int wpas_p2p_nfc_resp_go_neg(struct wpa_supplicant *wpa_s,
forced_freq, wpa_s->p2p_go_vht_center_freq2,
-1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth,
wpa_s->p2p_go_he, wpa_s->p2p_go_edmg,
NULL, 0);
NULL, 0, false);
if (res)
return res;

View File

@ -38,19 +38,21 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
int go_intent, int freq, unsigned int vht_center_freq2,
int persistent_id, int pd, int ht40, int vht,
unsigned int vht_chwidth, int he, int edmg,
const u8 *group_ssid, size_t group_ssid_len);
const u8 *group_ssid, size_t group_ssid_len,
bool allow_6ghz);
int wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s,
int freq, struct wpa_ssid *ssid);
int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
int freq, int vht_center_freq2, int ht40, int vht,
int max_oper_chwidth, int he, int edmg);
int max_oper_chwidth, int he, int edmg, bool allow_6ghz);
int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid, int addr_allocated,
int force_freq, int neg_freq,
int vht_center_freq2, int ht40, int vht,
int max_oper_chwidth, int he, int edmg,
const struct p2p_channels *channels,
int connection_timeout, int force_scan);
int connection_timeout, int force_scan,
bool allow_6ghz);
struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid);
enum wpas_p2p_prov_disc_use {
@ -73,7 +75,8 @@ int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,
enum p2p_discovery_type type,
unsigned int num_req_dev_types, const u8 *req_dev_types,
const u8 *dev_id, unsigned int search_delay,
u8 seek_cnt, const char **seek_string, int freq);
u8 seek_cnt, const char **seek_string, int freq,
bool include_6ghz);
void wpas_p2p_stop_find(struct wpa_supplicant *wpa_s);
int wpas_p2p_listen(struct wpa_supplicant *wpa_s, unsigned int timeout);
int wpas_p2p_listen_start(struct wpa_supplicant *wpa_s, unsigned int timeout);
@ -117,9 +120,10 @@ int wpas_p2p_reject(struct wpa_supplicant *wpa_s, const u8 *addr);
int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq,
int vht_center_freq2, int ht40, int vht, int max_chwidth,
int pref_freq, int he, int edmg);
int pref_freq, int he, int edmg, bool allow_6ghz);
int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname,
const u8 *peer_addr, const u8 *go_dev_addr);
const u8 *peer_addr, const u8 *go_dev_addr,
bool allow_6ghz);
int wpas_p2p_presence_req(struct wpa_supplicant *wpa_s, u32 duration1,
u32 interval1, u32 duration2, u32 interval2);
int wpas_p2p_ext_listen(struct wpa_supplicant *wpa_s, unsigned int period,
@ -145,9 +149,11 @@ int wpas_p2p_scan_no_go_seen(struct wpa_supplicant *wpa_s);
int wpas_p2p_get_ht40_mode(struct wpa_supplicant *wpa_s,
struct hostapd_hw_modes *mode, u8 channel);
int wpas_p2p_get_vht80_center(struct wpa_supplicant *wpa_s,
struct hostapd_hw_modes *mode, u8 channel);
struct hostapd_hw_modes *mode, u8 channel,
u8 op_class);
int wpas_p2p_get_vht160_center(struct wpa_supplicant *wpa_s,
struct hostapd_hw_modes *mode, u8 channel);
struct hostapd_hw_modes *mode, u8 channel,
u8 op_class);
unsigned int wpas_p2p_search_delay(struct wpa_supplicant *wpa_s);
void wpas_p2p_new_psk_cb(struct wpa_supplicant *wpa_s, const u8 *mac_addr,
const u8 *p2p_dev_addr,

View File

@ -2850,6 +2850,7 @@ wpa_scan_clone_params(const struct wpa_driver_scan_params *src)
params->relative_rssi = src->relative_rssi;
params->relative_adjust_band = src->relative_adjust_band;
params->relative_adjust_rssi = src->relative_adjust_rssi;
params->p2p_include_6ghz = src->p2p_include_6ghz;
return params;
failed:

View File

@ -1340,8 +1340,15 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
if (status_code != WLAN_STATUS_SUCCESS &&
status_code != WLAN_STATUS_SAE_HASH_TO_ELEMENT &&
status_code != WLAN_STATUS_SAE_PK)
status_code != WLAN_STATUS_SAE_PK) {
const u8 *bssid = sa ? sa : wpa_s->pending_bssid;
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_AUTH_REJECT MACSTR
" auth_type=%u auth_transaction=%u status_code=%u",
MAC2STR(bssid), WLAN_AUTH_SAE,
auth_transaction, status_code);
return -1;
}
if (auth_transaction == 1) {
u16 res;
@ -1542,7 +1549,7 @@ void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data)
int res;
res = sme_sae_auth(wpa_s, data->auth.auth_transaction,
data->auth.status_code, data->auth.ies,
data->auth.ies_len, 0, NULL);
data->auth.ies_len, 0, data->auth.peer);
if (res < 0) {
wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);

View File

@ -1343,11 +1343,11 @@ static int wnm_fetch_scan_results(struct wpa_supplicant *wpa_s)
continue;
bss = wpa_s->current_bss;
ssid_ie = wpa_scan_get_ie(res, WLAN_EID_SSID);
if (bss && ssid_ie &&
if (bss && ssid_ie && ssid_ie[1] &&
(bss->ssid_len != ssid_ie[1] ||
os_memcmp(bss->ssid, ssid_ie + 2,
bss->ssid_len) != 0))
continue;
continue; /* Skip entries for other ESSs */
/* Potential candidate found */
found = 1;

View File

@ -7537,6 +7537,46 @@ void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
#ifdef CONFIG_FILS
void fils_pmksa_cache_flush(struct wpa_supplicant *wpa_s)
{
struct wpa_ssid *ssid = wpa_s->current_ssid;
const u8 *realm, *username, *rrk;
size_t realm_len, username_len, rrk_len;
u16 next_seq_num;
/* Clear the PMKSA cache entry if FILS authentication was rejected.
* Check for ERP keys existing to limit when this can be done since
* the rejection response is not protected and such triggers should
* really not allow internal state to be modified unless required to
* avoid significant issues in functionality. In addition, drop
* externally configure PMKSA entries even without ERP keys since it
* is possible for an external component to add PMKSA entries for FILS
* authentication without restoring previously generated ERP keys.
*
* In this case, this is needed to allow recovery from cases where the
* AP or authentication server has dropped PMKSAs and ERP keys. */
if (!ssid || !ssid->eap.erp || !wpa_key_mgmt_fils(ssid->key_mgmt))
return;
if (eapol_sm_get_erp_info(wpa_s->eapol, &ssid->eap,
&username, &username_len,
&realm, &realm_len, &next_seq_num,
&rrk, &rrk_len) != 0 ||
!realm) {
wpa_dbg(wpa_s, MSG_DEBUG,
"FILS: Drop external PMKSA cache entry");
wpa_sm_aborted_external_cached(wpa_s->wpa);
wpa_sm_external_pmksa_cache_flush(wpa_s->wpa, ssid);
return;
}
wpa_dbg(wpa_s, MSG_DEBUG, "FILS: Drop PMKSA cache entry");
wpa_sm_aborted_cached(wpa_s->wpa);
wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
}
void fils_connection_failure(struct wpa_supplicant *wpa_s)
{
struct wpa_ssid *ssid = wpa_s->current_ssid;

View File

@ -1501,6 +1501,7 @@ void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s);
void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s);
void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid);
void fils_connection_failure(struct wpa_supplicant *wpa_s);
void fils_pmksa_cache_flush(struct wpa_supplicant *wpa_s);
int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s);
int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s);
void wpas_auth_failed(struct wpa_supplicant *wpa_s, char *reason);

View File

@ -372,6 +372,7 @@ static int wpa_supplicant_wps_cred(void *ctx,
#ifdef CONFIG_WPS_REG_DISABLE_OPEN
int registrar = 0;
#endif /* CONFIG_WPS_REG_DISABLE_OPEN */
bool add_sae;
if ((wpa_s->conf->wps_cred_processing == 1 ||
wpa_s->conf->wps_cred_processing == 2) && cred->cred_attr) {
@ -534,8 +535,12 @@ static int wpa_supplicant_wps_cred(void *ctx,
case WPS_AUTH_WPA2PSK:
ssid->auth_alg = WPA_AUTH_ALG_OPEN;
ssid->key_mgmt = WPA_KEY_MGMT_PSK;
if (wpa_s->conf->wps_cred_add_sae &&
cred->key_len != 2 * PMK_LEN) {
add_sae = wpa_s->conf->wps_cred_add_sae;
#ifdef CONFIG_P2P
if (ssid->p2p_group && is_p2p_6ghz_capable(wpa_s->global->p2p))
add_sae = true;
#endif /* CONFIG_P2P */
if (add_sae && cred->key_len != 2 * PMK_LEN) {
ssid->auth_alg = 0;
ssid->key_mgmt |= WPA_KEY_MGMT_SAE;
ssid->ieee80211w = MGMT_FRAME_PROTECTION_OPTIONAL;