Compare commits

..

2 commits

Author SHA1 Message Date
Raito Bezarius
5c72ebc915 ubus: support readiness notifications
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
2024-09-07 18:07:48 +02:00
Felix Fietkau
05396ebd93 hostapd: initial prototype of an ubus binding
Supports listing, removing and banning clients, and hooking into
probe/assoc/auth requests via object subscribe.

Co-authored-by: David Bauer <mail@david-bauer.net>
Co-authored-by: Ryan Lahfa <ryan@dgnum.eu>
2024-09-07 15:54:43 +02:00
145 changed files with 3894 additions and 8869 deletions

3
.gitignore vendored
View file

@ -6,6 +6,3 @@ wpaspy/build
**/parallel-vm.log **/parallel-vm.log
tags tags
build/ build/
# clangd commands and cache
compile_commands.json
.cache

View file

@ -883,11 +883,6 @@ fi.w1.wpa_supplicant1.CreateInterface.
<p>The most recent roam success or failure.</p> <p>The most recent roam success or failure.</p>
</li> </li>
<li>
<h3>ScanInProgress6GHz - b - (read)</h3>
<p>Whether a 6GHz scan is currently in progress.</p>
</li>
<li> <li>
<h3>SessionLength - u - (read)</h3> <h3>SessionLength - u - (read)</h3>
<p>The most recent BSS session length in milliseconds.</p> <p>The most recent BSS session length in milliseconds.</p>

View file

@ -1,54 +0,0 @@
#!/usr/bin/env python3
# compile_commands.json generator
# Copyright (C) 2024 Intel Corporation
#
# This software may be distributed under the terms of the BSD license.
# See README for more details.
import os
import sys
import glob
import json
import argparse
parser = argparse.ArgumentParser(description='Read each of the build directories that are given and generate '
'a compile_commands.json file. If a source file is found multiple times, '
'then the compile flags from the last build directory will be used.')
parser.add_argument('-o', '--output', default='compile_commands.json', type=str,
help="Output file to generate")
parser.add_argument('builddirs', nargs='+', type=str, metavar="builddir",
help='Build directories to search')
args = parser.parse_args()
files = {}
for builddir in args.builddirs:
for cmd_file in glob.glob('**/*.o.cmd', root_dir=builddir, recursive=True):
with open(os.path.join(builddir, cmd_file), encoding='ascii') as f:
base_dir, cmd = f.readline().split(':', 1)
src_file = cmd.rsplit(maxsplit=1)[1]
src_file = os.path.abspath(os.path.join(base_dir, src_file))
files[src_file] = {
'command': cmd.strip(),
'directory': base_dir,
'file': src_file,
}
flist = json.dumps(sorted(list(files.values()), key=lambda k: k['file']), indent=2, sort_keys=True)
try:
# Avoid writing the file if it did not change, first read original
with open(args.output, 'rt', encoding='UTF-8') as f:
orig = []
while data := f.read():
orig.append(data)
orig = ''.join(orig)
except OSError:
orig = ''
# And only write if something changed
if orig != flist:
with open(args.output, 'wt', encoding='UTF-8') as f:
f.write(flist)

View file

@ -166,6 +166,12 @@ OBJS += ../src/common/hw_features_common.o
OBJS += ../src/eapol_auth/eapol_auth_sm.o OBJS += ../src/eapol_auth/eapol_auth_sm.o
ifdef CONFIG_UBUS
CFLAGS += -DUBUS_SUPPORT
OBJS += ../src/utils/uloop.o
OBJS += ../src/ap/ubus.o
LIBS += -lubox -lubus
endif
ifdef CONFIG_CODE_COVERAGE ifdef CONFIG_CODE_COVERAGE
CFLAGS += -O0 -fprofile-arcs -ftest-coverage -U_FORTIFY_SOURCE CFLAGS += -O0 -fprofile-arcs -ftest-coverage -U_FORTIFY_SOURCE

View file

@ -2436,31 +2436,6 @@ static int get_u16(const char *pos, int line, u16 *ret_val)
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
#ifdef CONFIG_TESTING_OPTIONS
static bool get_hexstream(const char *val, struct wpabuf **var,
const char *name, int line)
{
struct wpabuf *tmp;
size_t len = os_strlen(val) / 2;
tmp = wpabuf_alloc(len);
if (!tmp)
return false;
if (hexstr2bin(val, wpabuf_put(tmp, len), len)) {
wpabuf_free(tmp);
wpa_printf(MSG_ERROR, "Line %d: Invalid %s '%s'",
line, name, val);
return false;
}
wpabuf_free(*var);
*var = tmp;
return true;
}
#endif /* CONFIG_TESTING_OPTIONS */
static int hostapd_config_fill(struct hostapd_config *conf, static int hostapd_config_fill(struct hostapd_config *conf,
struct hostapd_bss_config *bss, struct hostapd_bss_config *bss,
const char *buf, char *pos, int line) const char *buf, char *pos, int line)
@ -3181,16 +3156,6 @@ static int hostapd_config_fill(struct hostapd_config *conf,
bss->wpa_key_mgmt = hostapd_config_parse_key_mgmt(line, pos); bss->wpa_key_mgmt = hostapd_config_parse_key_mgmt(line, pos);
if (bss->wpa_key_mgmt == -1) if (bss->wpa_key_mgmt == -1)
return 1; return 1;
} else if (os_strcmp(buf, "rsn_override_key_mgmt") == 0) {
bss->rsn_override_key_mgmt =
hostapd_config_parse_key_mgmt(line, pos);
if (bss->rsn_override_key_mgmt == -1)
return 1;
} else if (os_strcmp(buf, "rsn_override_key_mgmt_2") == 0) {
bss->rsn_override_key_mgmt_2 =
hostapd_config_parse_key_mgmt(line, pos);
if (bss->rsn_override_key_mgmt_2 == -1)
return 1;
} else if (os_strcmp(buf, "wpa_psk_radius") == 0) { } else if (os_strcmp(buf, "wpa_psk_radius") == 0) {
bss->wpa_psk_radius = atoi(pos); bss->wpa_psk_radius = atoi(pos);
if (bss->wpa_psk_radius != PSK_RADIUS_IGNORED && if (bss->wpa_psk_radius != PSK_RADIUS_IGNORED &&
@ -3222,32 +3187,6 @@ static int hostapd_config_fill(struct hostapd_config *conf,
line, pos); line, pos);
return 1; return 1;
} }
} else if (os_strcmp(buf, "rsn_override_pairwise") == 0) {
bss->rsn_override_pairwise =
hostapd_config_parse_cipher(line, pos);
if (bss->rsn_override_pairwise == -1 ||
bss->rsn_override_pairwise == 0)
return 1;
if (bss->rsn_override_pairwise &
(WPA_CIPHER_NONE | WPA_CIPHER_WEP40 | WPA_CIPHER_WEP104)) {
wpa_printf(MSG_ERROR,
"Line %d: unsupported pairwise cipher suite '%s'",
line, pos);
return 1;
}
} else if (os_strcmp(buf, "rsn_override_pairwise_2") == 0) {
bss->rsn_override_pairwise_2 =
hostapd_config_parse_cipher(line, pos);
if (bss->rsn_override_pairwise_2 == -1 ||
bss->rsn_override_pairwise_2 == 0)
return 1;
if (bss->rsn_override_pairwise_2 &
(WPA_CIPHER_NONE | WPA_CIPHER_WEP40 | WPA_CIPHER_WEP104)) {
wpa_printf(MSG_ERROR,
"Line %d: unsupported pairwise cipher suite '%s'",
line, pos);
return 1;
}
} else if (os_strcmp(buf, "group_cipher") == 0) { } else if (os_strcmp(buf, "group_cipher") == 0) {
bss->group_cipher = hostapd_config_parse_cipher(line, pos); bss->group_cipher = hostapd_config_parse_cipher(line, pos);
if (bss->group_cipher == -1 || bss->group_cipher == 0) if (bss->group_cipher == -1 || bss->group_cipher == 0)
@ -3269,8 +3208,6 @@ static int hostapd_config_fill(struct hostapd_config *conf,
os_free(bss->rsn_preauth_interfaces); os_free(bss->rsn_preauth_interfaces);
bss->rsn_preauth_interfaces = os_strdup(pos); bss->rsn_preauth_interfaces = os_strdup(pos);
#endif /* CONFIG_RSN_PREAUTH */ #endif /* CONFIG_RSN_PREAUTH */
} else if (os_strcmp(buf, "rsn_override_omit_rsnxe") == 0) {
bss->rsn_override_omit_rsnxe = atoi(pos);
} else if (os_strcmp(buf, "peerkey") == 0) { } else if (os_strcmp(buf, "peerkey") == 0) {
wpa_printf(MSG_INFO, wpa_printf(MSG_INFO,
"Line %d: Obsolete peerkey parameter ignored", line); "Line %d: Obsolete peerkey parameter ignored", line);
@ -3705,10 +3642,6 @@ static int hostapd_config_fill(struct hostapd_config *conf,
conf->use_driver_iface_addr = atoi(pos); conf->use_driver_iface_addr = atoi(pos);
} else if (os_strcmp(buf, "ieee80211w") == 0) { } else if (os_strcmp(buf, "ieee80211w") == 0) {
bss->ieee80211w = atoi(pos); bss->ieee80211w = atoi(pos);
} else if (os_strcmp(buf, "rsn_override_mfp") == 0) {
bss->rsn_override_mfp = atoi(pos);
} else if (os_strcmp(buf, "rsn_override_mfp_2") == 0) {
bss->rsn_override_mfp_2 = atoi(pos);
} else if (os_strcmp(buf, "group_mgmt_cipher") == 0) { } else if (os_strcmp(buf, "group_mgmt_cipher") == 0) {
if (os_strcmp(pos, "AES-128-CMAC") == 0) { if (os_strcmp(pos, "AES-128-CMAC") == 0) {
bss->group_mgmt_cipher = WPA_CIPHER_AES_128_CMAC; bss->group_mgmt_cipher = WPA_CIPHER_AES_128_CMAC;
@ -4529,29 +4462,23 @@ static int hostapd_config_fill(struct hostapd_config *conf,
bss->radio_measurements[0] |= bss->radio_measurements[0] |=
WLAN_RRM_CAPS_NEIGHBOR_REPORT; WLAN_RRM_CAPS_NEIGHBOR_REPORT;
} else if (os_strcmp(buf, "own_ie_override") == 0) { } else if (os_strcmp(buf, "own_ie_override") == 0) {
if (!get_hexstream(pos, &bss->own_ie_override, struct wpabuf *tmp;
"own_ie_override", line)) size_t len = os_strlen(pos) / 2;
tmp = wpabuf_alloc(len);
if (!tmp)
return 1; return 1;
} else if (os_strcmp(buf, "rsne_override") == 0) {
if (!get_hexstream(pos, &bss->rsne_override, if (hexstr2bin(pos, wpabuf_put(tmp, len), len)) {
"rsne_override", line)) wpabuf_free(tmp);
return 1; wpa_printf(MSG_ERROR,
} else if (os_strcmp(buf, "rsnoe_override") == 0) { "Line %d: Invalid own_ie_override '%s'",
if (!get_hexstream(pos, &bss->rsnoe_override, line, pos);
"rsnoe_override", line))
return 1;
} else if (os_strcmp(buf, "rsno2e_override") == 0) {
if (!get_hexstream(pos, &bss->rsno2e_override,
"rsno2e_override", line))
return 1;
} else if (os_strcmp(buf, "rsnxe_override") == 0) {
if (!get_hexstream(pos, &bss->rsnxe_override,
"rsnxe_override", line))
return 1;
} else if (os_strcmp(buf, "rsnxoe_override") == 0) {
if (!get_hexstream(pos, &bss->rsnxoe_override,
"rsnxoe_override", line))
return 1; return 1;
}
wpabuf_free(bss->own_ie_override);
bss->own_ie_override = tmp;
} else if (os_strcmp(buf, "sae_reflection_attack") == 0) { } else if (os_strcmp(buf, "sae_reflection_attack") == 0) {
bss->sae_reflection_attack = atoi(pos); bss->sae_reflection_attack = atoi(pos);
} else if (os_strcmp(buf, "sae_commit_status") == 0) { } else if (os_strcmp(buf, "sae_commit_status") == 0) {
@ -4613,8 +4540,6 @@ static int hostapd_config_fill(struct hostapd_config *conf,
return 1; return 1;
} else if (os_strcmp(buf, "eapol_m3_no_encrypt") == 0) { } else if (os_strcmp(buf, "eapol_m3_no_encrypt") == 0) {
bss->eapol_m3_no_encrypt = atoi(pos); bss->eapol_m3_no_encrypt = atoi(pos);
} else if (os_strcmp(buf, "eapol_key_reserved_random") == 0) {
bss->eapol_key_reserved_random = atoi(pos);
} else if (os_strcmp(buf, "test_assoc_comeback_type") == 0) { } else if (os_strcmp(buf, "test_assoc_comeback_type") == 0) {
bss->test_assoc_comeback_type = atoi(pos); bss->test_assoc_comeback_type = atoi(pos);
} else if (os_strcmp(buf, "presp_elements") == 0) { } else if (os_strcmp(buf, "presp_elements") == 0) {

View file

@ -2454,31 +2454,6 @@ static int hostapd_ctrl_register_frame(struct hostapd_data *hapd,
#ifdef NEED_AP_MLME #ifdef NEED_AP_MLME
static bool
hostapd_ctrl_is_freq_in_cmode(struct hostapd_hw_modes *mode,
struct hostapd_multi_hw_info *current_hw_info,
int freq)
{
struct hostapd_channel_data *chan;
int i;
for (i = 0; i < mode->num_channels; i++) {
chan = &mode->channels[i];
if (chan->flag & HOSTAPD_CHAN_DISABLED)
continue;
if (!chan_in_current_hw_info(current_hw_info, chan))
continue;
if (chan->freq == freq)
return true;
}
return false;
}
static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params, static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params,
u16 punct_bitmap) u16 punct_bitmap)
{ {
@ -2693,15 +2668,6 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
settings.link_id = iface->bss[0]->mld_link_id; settings.link_id = iface->bss[0]->mld_link_id;
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
if (iface->num_hw_features > 1 &&
!hostapd_ctrl_is_freq_in_cmode(iface->current_mode,
iface->current_hw_info,
settings.freq_params.freq)) {
wpa_printf(MSG_INFO,
"chanswitch: Invalid frequency settings provided for multi band phy");
return -1;
}
ret = hostapd_ctrl_check_freq_params(&settings.freq_params, ret = hostapd_ctrl_check_freq_params(&settings.freq_params,
settings.punct_bitmap); settings.punct_bitmap);
if (ret) { if (ret) {
@ -2769,12 +2735,6 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
return 0; return 0;
} }
if (iface->cac_started) {
wpa_printf(MSG_DEBUG,
"CAC is in progress - switching channel without CSA");
return hostapd_force_channel_switch(iface, settings);
}
for (i = 0; i < iface->num_bss; i++) { for (i = 0; i < iface->num_bss; i++) {
/* Save CHAN_SWITCH VHT, HE, and EHT config */ /* Save CHAN_SWITCH VHT, HE, and EHT config */
@ -3745,7 +3705,6 @@ static int hostapd_ctrl_nan_publish(struct hostapd_data *hapd, char *cmd,
struct wpabuf *ssi = NULL; struct wpabuf *ssi = NULL;
int ret = -1; int ret = -1;
enum nan_service_protocol_type srv_proto_type = 0; enum nan_service_protocol_type srv_proto_type = 0;
bool p2p = false;
os_memset(&params, 0, sizeof(params)); os_memset(&params, 0, sizeof(params));
/* USD shall use both solicited and unsolicited transmissions */ /* USD shall use both solicited and unsolicited transmissions */
@ -3779,11 +3738,6 @@ static int hostapd_ctrl_nan_publish(struct hostapd_data *hapd, char *cmd,
continue; continue;
} }
if (os_strcmp(token, "p2p=1") == 0) {
p2p = true;
continue;
}
if (os_strcmp(token, "solicited=0") == 0) { if (os_strcmp(token, "solicited=0") == 0) {
params.solicited = false; params.solicited = false;
continue; continue;
@ -3805,7 +3759,7 @@ static int hostapd_ctrl_nan_publish(struct hostapd_data *hapd, char *cmd,
} }
publish_id = hostapd_nan_usd_publish(hapd, service_name, srv_proto_type, publish_id = hostapd_nan_usd_publish(hapd, service_name, srv_proto_type,
ssi, &params, p2p); ssi, &params);
if (publish_id > 0) if (publish_id > 0)
ret = os_snprintf(buf, buflen, "%d", publish_id); ret = os_snprintf(buf, buflen, "%d", publish_id);
fail: fail:
@ -3888,7 +3842,6 @@ static int hostapd_ctrl_nan_subscribe(struct hostapd_data *hapd, char *cmd,
struct wpabuf *ssi = NULL; struct wpabuf *ssi = NULL;
int ret = -1; int ret = -1;
enum nan_service_protocol_type srv_proto_type = 0; enum nan_service_protocol_type srv_proto_type = 0;
bool p2p = false;
os_memset(&params, 0, sizeof(params)); os_memset(&params, 0, sizeof(params));
@ -3922,11 +3875,6 @@ static int hostapd_ctrl_nan_subscribe(struct hostapd_data *hapd, char *cmd,
continue; continue;
} }
if (os_strcmp(token, "p2p=1") == 0) {
p2p = true;
continue;
}
wpa_printf(MSG_INFO, wpa_printf(MSG_INFO,
"CTRL: Invalid NAN_SUBSCRIBE parameter: %s", "CTRL: Invalid NAN_SUBSCRIBE parameter: %s",
token); token);
@ -3935,7 +3883,7 @@ static int hostapd_ctrl_nan_subscribe(struct hostapd_data *hapd, char *cmd,
subscribe_id = hostapd_nan_usd_subscribe(hapd, service_name, subscribe_id = hostapd_nan_usd_subscribe(hapd, service_name,
srv_proto_type, ssi, srv_proto_type, ssi,
&params, p2p); &params);
if (subscribe_id > 0) if (subscribe_id > 0)
ret = os_snprintf(buf, buflen, "%d", subscribe_id); ret = os_snprintf(buf, buflen, "%d", subscribe_id);
fail: fail:
@ -4734,360 +4682,23 @@ done:
} }
#ifdef CONFIG_IEEE80211BE
#ifndef CONFIG_CTRL_IFACE_UDP
static int hostapd_mld_ctrl_iface_receive_process(struct hostapd_mld *mld,
char *buf, char *reply,
size_t reply_size,
struct sockaddr_storage *from,
socklen_t fromlen)
{
struct hostapd_data *link_hapd, *link_itr;
int reply_len = -1, link_id = -1;
char *cmd;
bool found = false;
os_memcpy(reply, "OK\n", 3);
reply_len = 3;
cmd = buf;
/* Check whether the link ID is provided in the command */
if (os_strncmp(cmd, "LINKID ", 7) == 0) {
cmd += 7;
link_id = atoi(cmd);
if (link_id < 0 || link_id >= 15) {
os_memcpy(reply, "INVALID LINK ID\n", 16);
reply_len = 16;
goto out;
}
cmd = os_strchr(cmd, ' ');
if (!cmd)
goto out;
cmd++;
}
if (link_id >= 0) {
link_hapd = mld->fbss;
if (!link_hapd) {
os_memcpy(reply, "NO LINKS ACTIVE\n", 16);
reply_len = 16;
goto out;
}
for_each_mld_link(link_itr, link_hapd) {
if (link_itr->mld_link_id == link_id) {
found = true;
break;
}
}
if (!found)
goto out;
link_hapd = link_itr;
} else {
link_hapd = mld->fbss;
}
if (os_strcmp(cmd, "PING") == 0) {
os_memcpy(reply, "PONG\n", 5);
reply_len = 5;
} else if (os_strcmp(cmd, "ATTACH") == 0) {
if (ctrl_iface_attach(&mld->ctrl_dst, from, fromlen, NULL))
reply_len = -1;
} else if (os_strncmp(cmd, "ATTACH ", 7) == 0) {
if (ctrl_iface_attach(&mld->ctrl_dst, from, fromlen, cmd + 7))
reply_len = -1;
} else if (os_strcmp(cmd, "DETACH") == 0) {
if (ctrl_iface_detach(&mld->ctrl_dst, from, fromlen))
reply_len = -1;
} else {
if (link_id == -1)
wpa_printf(MSG_DEBUG,
"Link ID not provided, using the first link BSS (if available)");
if (!link_hapd)
reply_len = -1;
else
reply_len =
hostapd_ctrl_iface_receive_process(
link_hapd, cmd, reply, reply_size,
from, fromlen);
}
out:
if (reply_len < 0) {
os_memcpy(reply, "FAIL\n", 5);
reply_len = 5;
}
return reply_len;
}
static void hostapd_mld_ctrl_iface_receive(int sock, void *eloop_ctx,
void *sock_ctx)
{
struct hostapd_mld *mld = eloop_ctx;
char buf[4096];
int res;
struct sockaddr_storage from;
socklen_t fromlen = sizeof(from);
char *reply, *pos = buf;
const size_t reply_size = 4096;
int reply_len;
int level = MSG_DEBUG;
res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
(struct sockaddr *) &from, &fromlen);
if (res < 0) {
wpa_printf(MSG_ERROR, "recvfrom(mld ctrl_iface): %s",
strerror(errno));
return;
}
buf[res] = '\0';
reply = os_malloc(reply_size);
if (!reply) {
if (sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from,
fromlen) < 0) {
wpa_printf(MSG_DEBUG, "MLD CTRL: sendto failed: %s",
strerror(errno));
}
return;
}
if (os_strcmp(pos, "PING") == 0)
level = MSG_EXCESSIVE;
wpa_hexdump_ascii(level, "RX MLD ctrl_iface", pos, res);
reply_len = hostapd_mld_ctrl_iface_receive_process(mld, pos,
reply, reply_size,
&from, fromlen);
if (sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from,
fromlen) < 0) {
wpa_printf(MSG_DEBUG, "MLD CTRL: sendto failed: %s",
strerror(errno));
}
os_free(reply);
}
static char * hostapd_mld_ctrl_iface_path(struct hostapd_mld *mld)
{
size_t len;
char *buf;
int ret;
if (!mld->ctrl_interface)
return NULL;
len = os_strlen(mld->ctrl_interface) + os_strlen(mld->name) + 2;
buf = os_malloc(len);
if (!buf)
return NULL;
ret = os_snprintf(buf, len, "%s/%s", mld->ctrl_interface, mld->name);
if (os_snprintf_error(len, ret)) {
os_free(buf);
return NULL;
}
return buf;
}
#endif /* !CONFIG_CTRL_IFACE_UDP */
int hostapd_mld_ctrl_iface_init(struct hostapd_mld *mld)
{
#ifndef CONFIG_CTRL_IFACE_UDP
struct sockaddr_un addr;
int s = -1;
char *fname = NULL;
if (!mld)
return -1;
if (mld->ctrl_sock > -1) {
wpa_printf(MSG_DEBUG, "MLD %s ctrl_iface already exists!",
mld->name);
return 0;
}
dl_list_init(&mld->ctrl_dst);
if (!mld->ctrl_interface)
return 0;
if (mkdir(mld->ctrl_interface, S_IRWXU | S_IRWXG) < 0) {
if (errno == EEXIST) {
wpa_printf(MSG_DEBUG,
"Using existing control interface directory.");
} else {
wpa_printf(MSG_ERROR, "mkdir[ctrl_interface]: %s",
strerror(errno));
goto fail;
}
}
if (os_strlen(mld->ctrl_interface) + 1 + os_strlen(mld->name) >=
sizeof(addr.sun_path))
goto fail;
s = socket(PF_UNIX, SOCK_DGRAM, 0);
if (s < 0) {
wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno));
goto fail;
}
os_memset(&addr, 0, sizeof(addr));
#ifdef __FreeBSD__
addr.sun_len = sizeof(addr);
#endif /* __FreeBSD__ */
addr.sun_family = AF_UNIX;
fname = hostapd_mld_ctrl_iface_path(mld);
if (!fname)
goto fail;
os_strlcpy(addr.sun_path, fname, sizeof(addr.sun_path));
wpa_printf(MSG_DEBUG, "Setting up MLD %s ctrl_iface", mld->name);
if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
wpa_printf(MSG_DEBUG, "ctrl_iface bind(PF_UNIX) failed: %s",
strerror(errno));
if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not allow connections - assuming it was left over from forced program termination");
if (unlink(fname) < 0) {
wpa_printf(MSG_ERROR,
"Could not unlink existing ctrl_iface socket '%s': %s",
fname, strerror(errno));
goto fail;
}
if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) <
0) {
wpa_printf(MSG_ERROR,
"hostapd-ctrl-iface: bind(PF_UNIX): %s",
strerror(errno));
goto fail;
}
wpa_printf(MSG_DEBUG,
"Successfully replaced leftover ctrl_iface socket '%s'",
fname);
} else {
wpa_printf(MSG_INFO,
"ctrl_iface exists and seems to be in use - cannot override it");
wpa_printf(MSG_INFO,
"Delete '%s' manually if it is not used anymore", fname);
os_free(fname);
fname = NULL;
goto fail;
}
}
if (chmod(fname, S_IRWXU | S_IRWXG) < 0) {
wpa_printf(MSG_ERROR, "chmod[ctrl_interface/ifname]: %s",
strerror(errno));
goto fail;
}
os_free(fname);
mld->ctrl_sock = s;
if (eloop_register_read_sock(s, hostapd_mld_ctrl_iface_receive, mld,
NULL) < 0)
return -1;
return 0;
fail:
if (s >= 0)
close(s);
if (fname) {
unlink(fname);
os_free(fname);
}
return -1;
#endif /* !CONFIG_CTRL_IFACE_UDP */
return 0;
}
void hostapd_mld_ctrl_iface_deinit(struct hostapd_mld *mld)
{
#ifndef CONFIG_CTRL_IFACE_UDP
struct wpa_ctrl_dst *dst, *prev;
if (mld->ctrl_sock > -1) {
char *fname;
eloop_unregister_read_sock(mld->ctrl_sock);
close(mld->ctrl_sock);
mld->ctrl_sock = -1;
fname = hostapd_mld_ctrl_iface_path(mld);
if (fname) {
unlink(fname);
os_free(fname);
}
if (mld->ctrl_interface &&
rmdir(mld->ctrl_interface) < 0) {
if (errno == ENOTEMPTY) {
wpa_printf(MSG_DEBUG,
"MLD control interface directory not empty - leaving it behind");
} else {
wpa_printf(MSG_ERROR,
"rmdir[ctrl_interface=%s]: %s",
mld->ctrl_interface,
strerror(errno));
}
}
}
dl_list_for_each_safe(dst, prev, &mld->ctrl_dst, struct wpa_ctrl_dst,
list)
os_free(dst);
#endif /* !CONFIG_CTRL_IFACE_UDP */
os_free(mld->ctrl_interface);
}
#endif /* CONFIG_IEEE80211BE */
#ifndef CONFIG_CTRL_IFACE_UDP #ifndef CONFIG_CTRL_IFACE_UDP
static char * hostapd_ctrl_iface_path(struct hostapd_data *hapd) static char * hostapd_ctrl_iface_path(struct hostapd_data *hapd)
{ {
char *buf; char *buf;
size_t len; size_t len;
const char *ctrl_sock_iface;
#ifdef CONFIG_IEEE80211BE
ctrl_sock_iface = hapd->ctrl_sock_iface;
#else /* CONFIG_IEEE80211BE */
ctrl_sock_iface = hapd->conf->iface;
#endif /* CONFIG_IEEE80211BE */
if (hapd->conf->ctrl_interface == NULL) if (hapd->conf->ctrl_interface == NULL)
return NULL; return NULL;
len = os_strlen(hapd->conf->ctrl_interface) + len = os_strlen(hapd->conf->ctrl_interface) +
os_strlen(ctrl_sock_iface) + 2; os_strlen(hapd->conf->iface) + 2;
buf = os_malloc(len); buf = os_malloc(len);
if (buf == NULL) if (buf == NULL)
return NULL; return NULL;
os_snprintf(buf, len, "%s/%s", os_snprintf(buf, len, "%s/%s",
hapd->conf->ctrl_interface, ctrl_sock_iface); hapd->conf->ctrl_interface, hapd->conf->iface);
buf[len - 1] = '\0'; buf[len - 1] = '\0';
return buf; return buf;
} }
@ -5203,7 +4814,6 @@ fail:
struct sockaddr_un addr; struct sockaddr_un addr;
int s = -1; int s = -1;
char *fname = NULL; char *fname = NULL;
size_t iflen;
if (hapd->ctrl_sock > -1) { if (hapd->ctrl_sock > -1) {
wpa_printf(MSG_DEBUG, "ctrl_iface already exists!"); wpa_printf(MSG_DEBUG, "ctrl_iface already exists!");
@ -5258,13 +4868,8 @@ fail:
} }
#endif /* ANDROID */ #endif /* ANDROID */
#ifdef CONFIG_IEEE80211BE
iflen = os_strlen(hapd->ctrl_sock_iface);
#else /* CONFIG_IEEE80211BE */
iflen = os_strlen(hapd->conf->iface);
#endif /* CONFIG_IEEE80211BE */
if (os_strlen(hapd->conf->ctrl_interface) + 1 + if (os_strlen(hapd->conf->ctrl_interface) + 1 +
iflen >= sizeof(addr.sun_path)) os_strlen(hapd->conf->iface) >= sizeof(addr.sun_path))
goto fail; goto fail;
s = socket(PF_UNIX, SOCK_DGRAM, 0); s = socket(PF_UNIX, SOCK_DGRAM, 0);

View file

@ -14,8 +14,6 @@ int hostapd_ctrl_iface_init(struct hostapd_data *hapd);
void hostapd_ctrl_iface_deinit(struct hostapd_data *hapd); void hostapd_ctrl_iface_deinit(struct hostapd_data *hapd);
int hostapd_global_ctrl_iface_init(struct hapd_interfaces *interface); int hostapd_global_ctrl_iface_init(struct hapd_interfaces *interface);
void hostapd_global_ctrl_iface_deinit(struct hapd_interfaces *interface); void hostapd_global_ctrl_iface_deinit(struct hapd_interfaces *interface);
int hostapd_mld_ctrl_iface_init(struct hostapd_mld *mld);
void hostapd_mld_ctrl_iface_deinit(struct hostapd_mld *mld);
#else /* CONFIG_NO_CTRL_IFACE */ #else /* CONFIG_NO_CTRL_IFACE */
static inline int hostapd_ctrl_iface_init(struct hostapd_data *hapd) static inline int hostapd_ctrl_iface_init(struct hostapd_data *hapd)
{ {

View file

@ -2298,67 +2298,6 @@ own_ip_addr=127.0.0.1
# #
#ssid_protection=0 #ssid_protection=0
# RSNE/RSNXE override
#
# These parameters can be used to configure RSN parameters for STAs that support
# the override elements. The RSN parameters for STAs that do not support these
# mechanisms are configured in the referenced configuration parameters. The AP
# allows STAs to use either of the configured sets for negotiating RSN
# parameters.
#
# The main purpose of this mechanism is to make the AP look like it is using an
# older security mechanism (e.g., WPA2-Personal) to older STAs while allowing
# new stations use newer security mechanisms (e.g., WPA3-Personal) based on the
# override values. This might be needed to work around issues with deployed
# STAs that do not implement RSNE extensibility correctly and may fail to
# connect when the AP is using a transition mode like WPA3-Personal transition
# mode.
#
# Key management; see wpa_key_mgmt for RSNE configuration
#rsn_override_key_mgmt=<accepted key management algorithms>
#
# Pairwise cipher suites; see rsn_pairwise for RSNE configuration
#rsn_override_pairwise=<accepted cipher suites)
#
# Management frame protection (MFP/PMF); see ieee80211w for RSNE configuration
# 0 = disabled
# 1 = optional
# 2 = required
#rsn_override_mfp=<0/1/2>
#
# Second set of similar parameters. These are required to be used for
# Wi-Fi 7 (EHT/MLO) associations with RSN overriding and can optionally be used
# in cases that do not use Wi-Fi 7.
#rsn_override_key_mgmt_2
#rsn_override_pairwise_2
#rsn_override_mfp_2
#
# The RSNXE is normally included if any of the extended RSN capabilities is
# enabled/supported. When using RSN overriding, a separate RSNXOE is included
# and it may be more interoperable to omit the RSNXE completely. This
# configuration parameter can be used to do that.
# 0 = Include the RSNXE if any extended RSN capability is enabled/supported
# (default).
# 1 = Do not include the RSNXE.
#rsn_override_omit_rsnxe=0
#
# Example configuration for WPA2-Personal/PMF-optional in RSNE and
# WPA3-Personal/PMF-required/MLO in override elements
#wpa_key_mgmt=WPA-PSK
#rsn_pairwise=CCMP
#ieee80211w=1
#rsn_override_key_mgmt=SAE
#rsn_override_pairwise=GCMP-256
#rsn_override_mfp=2
#rsn_override_key_mgmt_2=SAE-EXT-KEY
#rsn_override_pairwise_2=GCMP-256
#rsn_override_mfp_2=2
#beacon_prot=1
#sae_groups=19 20
#sae_require_mfp=1
#sae_pwe=2
##### IEEE 802.11r configuration ############################################## ##### IEEE 802.11r configuration ##############################################
# Mobility Domain identifier (dot11FTMobilityDomainID, MDID) # Mobility Domain identifier (dot11FTMobilityDomainID, MDID)

View file

@ -54,11 +54,7 @@ static void usage(void)
fprintf(stderr, "%s\n", hostapd_cli_version); fprintf(stderr, "%s\n", hostapd_cli_version);
fprintf(stderr, fprintf(stderr,
"\n" "\n"
"usage: hostapd_cli [-p<path>] [-i<ifname>] " "usage: hostapd_cli [-p<path>] [-i<ifname>] [-hvBr] "
#ifdef CONFIG_IEEE80211BE
"[-l<link_id>] "
#endif /* CONFIG_IEEE80211BE */
"[-hvBr] "
"[-a<path>] \\\n" "[-a<path>] \\\n"
" [-P<pid file>] [-G<ping interval>] [command..]\n" " [-P<pid file>] [-G<ping interval>] [command..]\n"
"\n" "\n"
@ -78,11 +74,7 @@ static void usage(void)
" -B run a daemon in the background\n" " -B run a daemon in the background\n"
" -i<ifname> Interface to listen on (default: first " " -i<ifname> Interface to listen on (default: first "
"interface found in the\n" "interface found in the\n"
" socket path)\n" " socket path)\n\n");
#ifdef CONFIG_IEEE80211BE
" -l<link_id> Link ID of the interface in case of Multi-Link Operation\n"
#endif /* CONFIG_IEEE80211BE */
"\n");
print_help(stderr, NULL); print_help(stderr, NULL);
} }
@ -2220,15 +2212,12 @@ int main(int argc, char *argv[])
int c; int c;
int daemonize = 0; int daemonize = 0;
int reconnect = 0; int reconnect = 0;
#ifdef CONFIG_IEEE80211BE
int link_id = -1;
#endif /* CONFIG_IEEE80211BE */
if (os_program_init()) if (os_program_init())
return -1; return -1;
for (;;) { for (;;) {
c = getopt(argc, argv, "a:BhG:i:l:p:P:rs:v"); c = getopt(argc, argv, "a:BhG:i:p:P:rs:v");
if (c < 0) if (c < 0)
break; break;
switch (c) { switch (c) {
@ -2263,11 +2252,6 @@ int main(int argc, char *argv[])
case 's': case 's':
client_socket_dir = optarg; client_socket_dir = optarg;
break; break;
#ifdef CONFIG_IEEE80211BE
case 'l':
link_id = atoi(optarg);
break;
#endif /* CONFIG_IEEE80211BE */
default: default:
usage(); usage();
return -1; return -1;
@ -2301,24 +2285,6 @@ int main(int argc, char *argv[])
closedir(dir); closedir(dir);
} }
} }
#ifdef CONFIG_IEEE80211BE
if (link_id >= 0 && ctrl_ifname) {
int ret;
char buf[300];
ret = os_snprintf(buf, sizeof(buf), "%s_%s%d",
ctrl_ifname, WPA_CTRL_IFACE_LINK_NAME,
link_id);
if (os_snprintf_error(sizeof(buf), ret))
return -1;
os_free(ctrl_ifname);
ctrl_ifname = os_strdup(buf);
link_id = -1;
}
#endif /* CONFIG_IEEE80211BE */
hostapd_cli_reconnect(ctrl_ifname); hostapd_cli_reconnect(ctrl_ifname);
if (ctrl_conn) { if (ctrl_conn) {
if (warning_displayed) if (warning_displayed)

View file

@ -191,6 +191,7 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
os_memcpy(hapd->own_addr, b, ETH_ALEN); os_memcpy(hapd->own_addr, b, ETH_ALEN);
} }
hostapd_mld_add_link(hapd);
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"Setup of non first link (%d) BSS of MLD %s", "Setup of non first link (%d) BSS of MLD %s",
hapd->mld_link_id, hapd->conf->iface); hapd->mld_link_id, hapd->conf->iface);
@ -277,6 +278,7 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
else else
os_memcpy(hapd->own_addr, b, ETH_ALEN); os_memcpy(hapd->own_addr, b, ETH_ALEN);
hostapd_mld_add_link(hapd);
wpa_printf(MSG_DEBUG, "Setup of first link (%d) BSS of MLD %s", wpa_printf(MSG_DEBUG, "Setup of first link (%d) BSS of MLD %s",
hapd->mld_link_id, hapd->conf->iface); hapd->mld_link_id, hapd->conf->iface);
} }
@ -336,14 +338,8 @@ setup_mld:
hapd->mld_link_id, MAC2STR(hapd->mld->mld_addr), hapd->mld_link_id, MAC2STR(hapd->mld->mld_addr),
MAC2STR(hapd->own_addr)); MAC2STR(hapd->own_addr));
if (hostapd_drv_link_add(hapd, hapd->mld_link_id, hostapd_drv_link_add(hapd, hapd->mld_link_id,
hapd->own_addr)) { hapd->own_addr);
wpa_printf(MSG_ERROR,
"MLD: Failed to add link %d in MLD %s",
hapd->mld_link_id, hapd->conf->iface);
return -1;
}
hostapd_mld_add_link(hapd);
} }
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
@ -752,7 +748,6 @@ static void hostapd_global_cleanup_mld(struct hapd_interfaces *interfaces)
if (!interfaces->mld[i]) if (!interfaces->mld[i])
continue; continue;
interfaces->mld_ctrl_iface_deinit(interfaces->mld[i]);
os_free(interfaces->mld[i]); os_free(interfaces->mld[i]);
interfaces->mld[i] = NULL; interfaces->mld[i] = NULL;
} }
@ -798,10 +793,6 @@ int main(int argc, char *argv[])
interfaces.global_iface_path = NULL; interfaces.global_iface_path = NULL;
interfaces.global_iface_name = NULL; interfaces.global_iface_name = NULL;
interfaces.global_ctrl_sock = -1; interfaces.global_ctrl_sock = -1;
#ifdef CONFIG_IEEE80211BE
interfaces.mld_ctrl_iface_init = hostapd_mld_ctrl_iface_init;
interfaces.mld_ctrl_iface_deinit = hostapd_mld_ctrl_iface_deinit;
#endif /* CONFIG_IEEE80211BE */
dl_list_init(&interfaces.global_ctrl_dst); dl_list_init(&interfaces.global_ctrl_dst);
#ifdef CONFIG_ETH_P_OUI #ifdef CONFIG_ETH_P_OUI
dl_list_init(&interfaces.eth_p_oui); dl_list_init(&interfaces.eth_p_oui);

View file

@ -112,8 +112,14 @@ static void set_sta_weights(struct hostapd_data *hapd, unsigned int weight)
{ {
struct sta_info *sta; struct sta_info *sta;
for (sta = hapd->sta_list; sta; sta = sta->next) for (sta = hapd->sta_list; sta; sta = sta->next) {
sta_set_airtime_weight(hapd, sta, weight); unsigned int sta_weight = weight;
if (sta->dyn_airtime_weight)
sta_weight = (weight * sta->dyn_airtime_weight) / 256;
sta_set_airtime_weight(hapd, sta, sta_weight);
}
} }
@ -244,6 +250,9 @@ int airtime_policy_new_sta(struct hostapd_data *hapd, struct sta_info *sta)
unsigned int weight; unsigned int weight;
if (hapd->iconf->airtime_mode == AIRTIME_MODE_STATIC) { if (hapd->iconf->airtime_mode == AIRTIME_MODE_STATIC) {
if (sta->dyn_airtime_weight)
weight = sta->dyn_airtime_weight;
else
weight = get_weight_for_sta(hapd, sta->addr); weight = get_weight_for_sta(hapd, sta->addr);
if (weight) if (weight)
return sta_set_airtime_weight(hapd, sta, weight); return sta_set_airtime_weight(hapd, sta, weight);

View file

@ -491,33 +491,20 @@ int hostapd_setup_sae_pt(struct hostapd_bss_config *conf)
#ifdef CONFIG_SAE #ifdef CONFIG_SAE
struct hostapd_ssid *ssid = &conf->ssid; struct hostapd_ssid *ssid = &conf->ssid;
struct sae_password_entry *pw; struct sae_password_entry *pw;
int *groups = conf->sae_groups;
int default_groups[] = { 19, 0, 0 };
if ((conf->sae_pwe == SAE_PWE_HUNT_AND_PECK && if ((conf->sae_pwe == SAE_PWE_HUNT_AND_PECK &&
!hostapd_sae_pw_id_in_use(conf) && !hostapd_sae_pw_id_in_use(conf) &&
!wpa_key_mgmt_sae_ext_key(conf->wpa_key_mgmt | !wpa_key_mgmt_sae_ext_key(conf->wpa_key_mgmt) &&
conf->rsn_override_key_mgmt |
conf->rsn_override_key_mgmt_2) &&
!hostapd_sae_pk_in_use(conf)) || !hostapd_sae_pk_in_use(conf)) ||
conf->sae_pwe == SAE_PWE_FORCE_HUNT_AND_PECK || conf->sae_pwe == SAE_PWE_FORCE_HUNT_AND_PECK ||
!wpa_key_mgmt_sae(conf->wpa_key_mgmt | !wpa_key_mgmt_sae(conf->wpa_key_mgmt))
conf->rsn_override_key_mgmt |
conf->rsn_override_key_mgmt_2))
return 0; /* PT not needed */ return 0; /* PT not needed */
if (!groups) {
groups = default_groups;
if (wpa_key_mgmt_sae_ext_key(conf->wpa_key_mgmt |
conf->rsn_override_key_mgmt |
conf->rsn_override_key_mgmt_2))
default_groups[1] = 20;
}
sae_deinit_pt(ssid->pt); sae_deinit_pt(ssid->pt);
ssid->pt = NULL; ssid->pt = NULL;
if (ssid->wpa_passphrase) { if (ssid->wpa_passphrase) {
ssid->pt = sae_derive_pt(groups, ssid->ssid, ssid->ssid_len, ssid->pt = sae_derive_pt(conf->sae_groups, ssid->ssid,
ssid->ssid_len,
(const u8 *) ssid->wpa_passphrase, (const u8 *) ssid->wpa_passphrase,
os_strlen(ssid->wpa_passphrase), os_strlen(ssid->wpa_passphrase),
NULL); NULL);
@ -527,7 +514,8 @@ int hostapd_setup_sae_pt(struct hostapd_bss_config *conf)
for (pw = conf->sae_passwords; pw; pw = pw->next) { for (pw = conf->sae_passwords; pw; pw = pw->next) {
sae_deinit_pt(pw->pt); sae_deinit_pt(pw->pt);
pw->pt = sae_derive_pt(groups, ssid->ssid, ssid->ssid_len, pw->pt = sae_derive_pt(conf->sae_groups, ssid->ssid,
ssid->ssid_len,
(const u8 *) pw->password, (const u8 *) pw->password,
os_strlen(pw->password), os_strlen(pw->password),
pw->identifier); pw->identifier);
@ -972,11 +960,6 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf)
#ifdef CONFIG_TESTING_OPTIONS #ifdef CONFIG_TESTING_OPTIONS
wpabuf_free(conf->own_ie_override); wpabuf_free(conf->own_ie_override);
wpabuf_free(conf->rsne_override);
wpabuf_free(conf->rsnoe_override);
wpabuf_free(conf->rsno2e_override);
wpabuf_free(conf->rsnxe_override);
wpabuf_free(conf->rsnxoe_override);
wpabuf_free(conf->sae_commit_override); wpabuf_free(conf->sae_commit_override);
wpabuf_free(conf->rsne_override_eapol); wpabuf_free(conf->rsne_override_eapol);
wpabuf_free(conf->rsnxe_override_eapol); wpabuf_free(conf->rsnxe_override_eapol);

View file

@ -358,11 +358,7 @@ struct hostapd_bss_config {
int wpa; /* bitfield of WPA_PROTO_WPA, WPA_PROTO_RSN */ int wpa; /* bitfield of WPA_PROTO_WPA, WPA_PROTO_RSN */
int extended_key_id; int extended_key_id;
int wpa_key_mgmt; int wpa_key_mgmt;
int rsn_override_key_mgmt;
int rsn_override_key_mgmt_2;
enum mfp_options ieee80211w; enum mfp_options ieee80211w;
enum mfp_options rsn_override_mfp;
enum mfp_options rsn_override_mfp_2;
int group_mgmt_cipher; int group_mgmt_cipher;
int beacon_prot; int beacon_prot;
/* dot11AssociationSAQueryMaximumTimeout (in TUs) */ /* dot11AssociationSAQueryMaximumTimeout (in TUs) */
@ -391,13 +387,9 @@ struct hostapd_bss_config {
u32 wpa_pairwise_update_count; u32 wpa_pairwise_update_count;
int wpa_disable_eapol_key_retries; int wpa_disable_eapol_key_retries;
int rsn_pairwise; int rsn_pairwise;
int rsn_override_pairwise;
int rsn_override_pairwise_2;
int rsn_preauth; int rsn_preauth;
char *rsn_preauth_interfaces; char *rsn_preauth_interfaces;
int rsn_override_omit_rsnxe;
#ifdef CONFIG_IEEE80211R_AP #ifdef CONFIG_IEEE80211R_AP
/* IEEE 802.11r - Fast BSS Transition */ /* IEEE 802.11r - Fast BSS Transition */
u8 mobility_domain[MOBILITY_DOMAIN_ID_LEN]; u8 mobility_domain[MOBILITY_DOMAIN_ID_LEN];
@ -696,11 +688,6 @@ struct hostapd_bss_config {
u8 bss_load_test[5]; u8 bss_load_test[5];
u8 bss_load_test_set; u8 bss_load_test_set;
struct wpabuf *own_ie_override; struct wpabuf *own_ie_override;
struct wpabuf *rsne_override;
struct wpabuf *rsnoe_override;
struct wpabuf *rsno2e_override;
struct wpabuf *rsnxe_override;
struct wpabuf *rsnxoe_override;
int sae_reflection_attack; int sae_reflection_attack;
int sae_commit_status; int sae_commit_status;
int sae_pk_omit; int sae_pk_omit;
@ -725,7 +712,6 @@ struct hostapd_bss_config {
struct wpabuf *eapol_m1_elements; struct wpabuf *eapol_m1_elements;
struct wpabuf *eapol_m3_elements; struct wpabuf *eapol_m3_elements;
bool eapol_m3_no_encrypt; bool eapol_m3_no_encrypt;
bool eapol_key_reserved_random;
int test_assoc_comeback_type; int test_assoc_comeback_type;
struct wpabuf *presp_elements; struct wpabuf *presp_elements;

View file

@ -1250,14 +1250,3 @@ int hostapd_drv_set_secure_ranging_ctx(struct hostapd_data *hapd,
return hapd->driver->set_secure_ranging_ctx(hapd->drv_priv, &params); return hapd->driver->set_secure_ranging_ctx(hapd->drv_priv, &params);
} }
#endif /* CONFIG_PASN */ #endif /* CONFIG_PASN */
struct hostapd_multi_hw_info *
hostapd_get_multi_hw_info(struct hostapd_data *hapd,
unsigned int *num_multi_hws)
{
if (!hapd->driver || !hapd->driver->get_multi_hw_info)
return NULL;
return hapd->driver->get_multi_hw_info(hapd->drv_priv, num_multi_hws);
}

View file

@ -478,8 +478,4 @@ static inline int hostapd_drv_link_sta_remove(struct hostapd_data *hapd,
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
struct hostapd_multi_hw_info *
hostapd_get_multi_hw_info(struct hostapd_data *hapd,
unsigned int *num_multi_hws);
#endif /* AP_DRV_OPS */ #endif /* AP_DRV_OPS */

View file

@ -403,81 +403,6 @@ static u8 * hostapd_get_osen_ie(struct hostapd_data *hapd, u8 *pos, size_t len)
} }
static u8 * hostapd_get_rsne_override(struct hostapd_data *hapd, u8 *pos,
size_t len)
{
const u8 *ie;
ie = hostapd_vendor_wpa_ie(hapd, RSNE_OVERRIDE_IE_VENDOR_TYPE);
if (!ie || 2U + ie[1] > len)
return pos;
os_memcpy(pos, ie, 2 + ie[1]);
return pos + 2 + ie[1];
}
static u8 * hostapd_get_rsne_override_2(struct hostapd_data *hapd, u8 *pos,
size_t len)
{
const u8 *ie;
ie = hostapd_vendor_wpa_ie(hapd, RSNE_OVERRIDE_2_IE_VENDOR_TYPE);
if (!ie || 2U + ie[1] > len)
return pos;
os_memcpy(pos, ie, 2 + ie[1]);
return pos + 2 + ie[1];
}
static u8 * hostapd_get_rsnxe_override(struct hostapd_data *hapd, u8 *pos,
size_t len)
{
const u8 *ie;
ie = hostapd_vendor_wpa_ie(hapd, RSNXE_OVERRIDE_IE_VENDOR_TYPE);
if (!ie || 2U + ie[1] > len)
return pos;
os_memcpy(pos, ie, 2 + ie[1]);
return pos + 2 + ie[1];
}
static size_t hostapd_get_rsne_override_len(struct hostapd_data *hapd)
{
const u8 *ie;
ie = hostapd_vendor_wpa_ie(hapd, RSNE_OVERRIDE_IE_VENDOR_TYPE);
if (!ie)
return 0;
return 2 + ie[1];
}
static size_t hostapd_get_rsne_override_2_len(struct hostapd_data *hapd)
{
const u8 *ie;
ie = hostapd_vendor_wpa_ie(hapd, RSNE_OVERRIDE_2_IE_VENDOR_TYPE);
if (!ie)
return 0;
return 2 + ie[1];
}
static size_t hostapd_get_rsnxe_override_len(struct hostapd_data *hapd)
{
const u8 *ie;
ie = hostapd_vendor_wpa_ie(hapd, RSNXE_OVERRIDE_IE_VENDOR_TYPE);
if (!ie)
return 0;
return 2 + ie[1];
}
static u8 * hostapd_eid_csa(struct hostapd_data *hapd, u8 *eid) static u8 * hostapd_eid_csa(struct hostapd_data *hapd, u8 *eid)
{ {
#ifdef CONFIG_TESTING_OPTIONS #ifdef CONFIG_TESTING_OPTIONS
@ -514,35 +439,6 @@ static u8 * hostapd_eid_ecsa(struct hostapd_data *hapd, u8 *eid)
} }
static u8 * hostapd_eid_max_cs_time(struct hostapd_data *hapd, u8 *eid)
{
#ifdef CONFIG_IEEE80211BE
u32 switch_time;
/* Add Max Channel Switch Time element only if this AP is affiliated
* with an AP MLD and channel switch is in process. */
if (!hapd->conf->mld_ap || !hapd->cs_freq_params.channel)
return eid;
/* Switch time is basically time between CSA count 1 and CSA count
* 0 (1 beacon interval) + time for interface restart + time to
* send a Beacon frame in the new channel (1 beacon interval).
*
* TODO: Use dynamic interface restart time. For now, assume 1 sec.
*/
switch_time = USEC_TO_TU(1000 * 1000) + 2 * hapd->iconf->beacon_int;
*eid++ = WLAN_EID_EXTENSION;
*eid++ = 4;
*eid++ = WLAN_EID_EXT_MAX_CHANNEL_SWITCH_TIME;
WPA_PUT_LE24(eid, switch_time);
eid += 3;
#endif /* CONFIG_IEEE80211BE */
return eid;
}
static u8 * hostapd_eid_supported_op_classes(struct hostapd_data *hapd, u8 *eid) static u8 * hostapd_eid_supported_op_classes(struct hostapd_data *hapd, u8 *eid)
{ {
u8 op_class, channel; u8 op_class, channel;
@ -705,6 +601,7 @@ struct probe_resp_params {
bool is_p2p; bool is_p2p;
/* Generated IEs will be included inside an ML element */ /* Generated IEs will be included inside an ML element */
bool is_ml_sta_info;
struct hostapd_data *mld_ap; struct hostapd_data *mld_ap;
struct mld_info *mld_info; struct mld_info *mld_info;
@ -726,7 +623,7 @@ static void hostapd_free_probe_resp_params(struct probe_resp_params *params)
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
if (!params) if (!params)
return; return;
ap_sta_free_sta_profile(params->mld_info);
os_free(params->mld_info); os_free(params->mld_info);
params->mld_info = NULL; params->mld_info = NULL;
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
@ -765,21 +662,17 @@ static size_t hostapd_probe_resp_elems_len(struct hostapd_data *hapd,
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) { if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
struct hostapd_data *ml_elem_ap =
params->mld_ap ? params->mld_ap : hapd;
buflen += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP); buflen += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP);
buflen += 3 + sizeof(struct ieee80211_eht_operation); buflen += 3 + sizeof(struct ieee80211_eht_operation);
if (hapd->iconf->punct_bitmap) if (hapd->iconf->punct_bitmap)
buflen += EHT_OPER_DISABLED_SUBCHAN_BITMAP_SIZE; buflen += EHT_OPER_DISABLED_SUBCHAN_BITMAP_SIZE;
if (ml_elem_ap->conf->mld_ap) { if (!params->is_ml_sta_info && hapd->conf->mld_ap) {
struct hostapd_data *ml_elem_ap =
params->mld_ap ? params->mld_ap : hapd;
buflen += hostapd_eid_eht_ml_beacon_len( buflen += hostapd_eid_eht_ml_beacon_len(
ml_elem_ap, params->mld_info, !!params->mld_ap); ml_elem_ap, params->mld_info, !!params->mld_ap);
/* For Max Channel Switch Time element during channel
* switch */
buflen += 6;
} }
} }
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
@ -787,13 +680,12 @@ static size_t hostapd_probe_resp_elems_len(struct hostapd_data *hapd,
buflen += hostapd_eid_mbssid_len(hapd, WLAN_FC_STYPE_PROBE_RESP, NULL, buflen += hostapd_eid_mbssid_len(hapd, WLAN_FC_STYPE_PROBE_RESP, NULL,
params->known_bss, params->known_bss,
params->known_bss_len, NULL); params->known_bss_len, NULL);
buflen += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP, true); if (!params->is_ml_sta_info)
buflen += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP,
true);
buflen += hostapd_mbo_ie_len(hapd); buflen += hostapd_mbo_ie_len(hapd);
buflen += hostapd_eid_owe_trans_len(hapd); buflen += hostapd_eid_owe_trans_len(hapd);
buflen += hostapd_eid_dpp_cc_len(hapd); buflen += hostapd_eid_dpp_cc_len(hapd);
buflen += hostapd_get_rsne_override_len(hapd);
buflen += hostapd_get_rsne_override_2_len(hapd);
buflen += hostapd_get_rsnxe_override_len(hapd);
return buflen; return buflen;
} }
@ -808,11 +700,13 @@ static u8 * hostapd_probe_resp_fill_elems(struct hostapd_data *hapd,
epos = pos + len; epos = pos + len;
if (!params->is_ml_sta_info) {
*pos++ = WLAN_EID_SSID; *pos++ = WLAN_EID_SSID;
*pos++ = hapd->conf->ssid.ssid_len; *pos++ = hapd->conf->ssid.ssid_len;
os_memcpy(pos, hapd->conf->ssid.ssid, os_memcpy(pos, hapd->conf->ssid.ssid,
hapd->conf->ssid.ssid_len); hapd->conf->ssid.ssid_len);
pos += hapd->conf->ssid.ssid_len; pos += hapd->conf->ssid.ssid_len;
}
/* Supported rates */ /* Supported rates */
pos = hostapd_eid_supp_rates(hapd, pos); pos = hostapd_eid_supp_rates(hapd, pos);
@ -825,13 +719,18 @@ static u8 * hostapd_probe_resp_fill_elems(struct hostapd_data *hapd,
/* Power Constraint element */ /* Power Constraint element */
pos = hostapd_eid_pwr_constraint(hapd, pos); pos = hostapd_eid_pwr_constraint(hapd, pos);
/* CSA element */ /*
* CSA IE
* TODO: This should be included inside the ML sta profile
*/
if (!params->is_ml_sta_info) {
csa_pos = hostapd_eid_csa(hapd, pos); csa_pos = hostapd_eid_csa(hapd, pos);
if (csa_pos != pos) if (csa_pos != pos)
params->csa_pos = csa_pos - 1; params->csa_pos = csa_pos - 1;
else else
params->csa_pos = NULL; params->csa_pos = NULL;
pos = csa_pos; pos = csa_pos;
}
/* ERP Information element */ /* ERP Information element */
pos = hostapd_eid_erp_info(hapd, pos); pos = hostapd_eid_erp_info(hapd, pos);
@ -847,13 +746,18 @@ static u8 * hostapd_probe_resp_fill_elems(struct hostapd_data *hapd,
pos = hostapd_eid_rm_enabled_capab(hapd, pos, epos - pos); pos = hostapd_eid_rm_enabled_capab(hapd, pos, epos - pos);
pos = hostapd_get_mde(hapd, pos, epos - pos); pos = hostapd_get_mde(hapd, pos, epos - pos);
/* eCSA element */ /*
* eCSA IE
* TODO: This should be included inside the ML sta profile
*/
if (!params->is_ml_sta_info) {
csa_pos = hostapd_eid_ecsa(hapd, pos); csa_pos = hostapd_eid_ecsa(hapd, pos);
if (csa_pos != pos) if (csa_pos != pos)
params->ecsa_pos = csa_pos - 1; params->ecsa_pos = csa_pos - 1;
else else
params->ecsa_pos = NULL; params->ecsa_pos = NULL;
pos = csa_pos; pos = csa_pos;
}
pos = hostapd_eid_supported_op_classes(hapd, pos); pos = hostapd_eid_supported_op_classes(hapd, pos);
pos = hostapd_eid_ht_capabilities(hapd, pos); pos = hostapd_eid_ht_capabilities(hapd, pos);
@ -895,14 +799,12 @@ static u8 * hostapd_probe_resp_fill_elems(struct hostapd_data *hapd,
pos = hostapd_eid_txpower_envelope(hapd, pos); pos = hostapd_eid_txpower_envelope(hapd, pos);
#endif /* CONFIG_IEEE80211AX */ #endif /* CONFIG_IEEE80211AX */
pos = hostapd_eid_chsw_wrapper(hapd, pos); pos = hostapd_eid_wb_chsw_wrapper(hapd, pos);
pos = hostapd_eid_rnr(hapd, pos, WLAN_FC_STYPE_PROBE_RESP, true); if (!params->is_ml_sta_info)
pos = hostapd_eid_rnr(hapd, pos, WLAN_FC_STYPE_PROBE_RESP,
true);
pos = hostapd_eid_fils_indic(hapd, pos, 0); pos = hostapd_eid_fils_indic(hapd, pos, 0);
/* Max Channel Switch Time element */
pos = hostapd_eid_max_cs_time(hapd, pos);
pos = hostapd_get_rsnxe(hapd, pos, epos - pos); pos = hostapd_get_rsnxe(hapd, pos, epos - pos);
#ifdef CONFIG_IEEE80211AX #ifdef CONFIG_IEEE80211AX
@ -983,10 +885,6 @@ static u8 * hostapd_probe_resp_fill_elems(struct hostapd_data *hapd,
pos = hostapd_eid_owe_trans(hapd, pos, epos - pos); pos = hostapd_eid_owe_trans(hapd, pos, epos - pos);
pos = hostapd_eid_dpp_cc(hapd, pos, epos - pos); pos = hostapd_eid_dpp_cc(hapd, pos, epos - pos);
pos = hostapd_get_rsne_override(hapd, pos, epos - pos);
pos = hostapd_get_rsne_override_2(hapd, pos, epos - pos);
pos = hostapd_get_rsnxe_override(hapd, pos, epos - pos);
if (hapd->conf->vendor_elements) { if (hapd->conf->vendor_elements) {
os_memcpy(pos, wpabuf_head(hapd->conf->vendor_elements), os_memcpy(pos, wpabuf_head(hapd->conf->vendor_elements),
wpabuf_len(hapd->conf->vendor_elements)); wpabuf_len(hapd->conf->vendor_elements));
@ -1059,6 +957,7 @@ static void hostapd_fill_probe_resp_ml_params(struct hostapd_data *hapd,
const struct ieee80211_mgmt *mgmt, const struct ieee80211_mgmt *mgmt,
int mld_id, u16 links) int mld_id, u16 links)
{ {
struct probe_resp_params sta_info_params;
struct hostapd_data *link; struct hostapd_data *link;
params->mld_ap = NULL; params->mld_ap = NULL;
@ -1072,7 +971,10 @@ static void hostapd_fill_probe_resp_ml_params(struct hostapd_data *hapd,
for_each_mld_link(link, hapd) { for_each_mld_link(link, hapd) {
struct mld_link_info *link_info; struct mld_link_info *link_info;
size_t buflen;
u8 mld_link_id = link->mld_link_id; u8 mld_link_id = link->mld_link_id;
u8 *epos;
u8 buf[EHT_ML_MAX_STA_PROF_LEN];
/* /*
* Set mld_ap iff the ML probe request explicitly * Set mld_ap iff the ML probe request explicitly
@ -1092,12 +994,49 @@ static void hostapd_fill_probe_resp_ml_params(struct hostapd_data *hapd,
continue; continue;
link_info = &params->mld_info->links[mld_link_id]; link_info = &params->mld_info->links[mld_link_id];
os_memcpy(link_info, &hapd->partner_links[mld_link_id],
sizeof(hapd->partner_links[mld_link_id])); sta_info_params.req = params->req;
sta_info_params.is_p2p = false;
sta_info_params.is_ml_sta_info = true;
sta_info_params.mld_ap = NULL;
sta_info_params.mld_info = NULL;
buflen = MAX_PROBERESP_LEN;
buflen += hostapd_probe_resp_elems_len(link, &sta_info_params);
if (buflen > EHT_ML_MAX_STA_PROF_LEN) {
wpa_printf(MSG_DEBUG,
"MLD: Not including link %d in ML probe response (%zu bytes is too long)",
mld_link_id, buflen);
goto fail;
}
/*
* NOTE: This does not properly handle inheritance and
* various other things.
*/
link_info->valid = true;
epos = buf;
/* Capabilities is the only fixed parameter */
WPA_PUT_LE16(epos, hostapd_own_capab_info(hapd));
epos += 2;
epos = hostapd_probe_resp_fill_elems(
link, &sta_info_params, epos,
EHT_ML_MAX_STA_PROF_LEN - 2);
link_info->resp_sta_profile_len = epos - buf;
os_free(link_info->resp_sta_profile);
link_info->resp_sta_profile = os_memdup(
buf, link_info->resp_sta_profile_len);
if (!link_info->resp_sta_profile)
link_info->resp_sta_profile_len = 0;
os_memcpy(link_info->local_addr, link->own_addr, ETH_ALEN);
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"MLD: ML probe response includes link STA info for %d: %u bytes", "MLD: ML probe response includes link sta info for %d: %u bytes (estimate %zu)",
mld_link_id, link_info->resp_sta_profile_len); mld_link_id, link_info->resp_sta_profile_len,
buflen);
} }
if (mld_id != -1 && !params->mld_ap) { if (mld_id != -1 && !params->mld_ap) {
@ -1418,6 +1357,12 @@ void handle_probe_req(struct hostapd_data *hapd,
int mld_id; int mld_id;
u16 links; u16 links;
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
struct hostapd_ubus_request req = {
.type = HOSTAPD_UBUS_PROBE_REQ,
.mgmt_frame = mgmt,
.ssi_signal = ssi_signal,
.elems = &elems,
};
if (hapd->iconf->rssi_ignore_probe_request && ssi_signal && if (hapd->iconf->rssi_ignore_probe_request && ssi_signal &&
ssi_signal < hapd->iconf->rssi_ignore_probe_request) ssi_signal < hapd->iconf->rssi_ignore_probe_request)
@ -1604,6 +1549,12 @@ void handle_probe_req(struct hostapd_data *hapd,
} }
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */
if (hostapd_ubus_handle_event(hapd, &req)) {
wpa_printf(MSG_DEBUG, "Probe request for " MACSTR " rejected by ubus handler.\n",
MAC2STR(mgmt->sa));
return;
}
/* TODO: verify that supp_rates contains at least one matching rate /* TODO: verify that supp_rates contains at least one matching rate
* with AP configuration */ * with AP configuration */
@ -1664,6 +1615,7 @@ void handle_probe_req(struct hostapd_data *hapd,
params.is_p2p = !!elems.p2p; params.is_p2p = !!elems.p2p;
params.known_bss = elems.mbssid_known_bss; params.known_bss = elems.mbssid_known_bss;
params.known_bss_len = elems.mbssid_known_bss_len; params.known_bss_len = elems.mbssid_known_bss_len;
params.is_ml_sta_info = false;
hostapd_gen_probe_resp(hapd, &params); hostapd_gen_probe_resp(hapd, &params);
@ -1744,6 +1696,7 @@ static u8 * hostapd_probe_resp_offloads(struct hostapd_data *hapd,
params.is_p2p = false; params.is_p2p = false;
params.known_bss = NULL; params.known_bss = NULL;
params.known_bss_len = 0; params.known_bss_len = 0;
params.is_ml_sta_info = false;
params.mld_ap = NULL; params.mld_ap = NULL;
params.mld_info = NULL; params.mld_info = NULL;
@ -1787,6 +1740,7 @@ u8 * hostapd_unsol_bcast_probe_resp(struct hostapd_data *hapd,
probe_params.is_p2p = false; probe_params.is_p2p = false;
probe_params.known_bss = NULL; probe_params.known_bss = NULL;
probe_params.known_bss_len = 0; probe_params.known_bss_len = 0;
probe_params.is_ml_sta_info = false;
probe_params.mld_ap = NULL; probe_params.mld_ap = NULL;
probe_params.mld_info = NULL; probe_params.mld_info = NULL;
@ -2164,7 +2118,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
#ifdef NEED_AP_MLME #ifdef NEED_AP_MLME
#define BEACON_HEAD_BUF_SIZE 256 #define BEACON_HEAD_BUF_SIZE 256
#define BEACON_TAIL_BUF_SIZE 1500 #define BEACON_TAIL_BUF_SIZE 512
head = os_zalloc(BEACON_HEAD_BUF_SIZE); head = os_zalloc(BEACON_HEAD_BUF_SIZE);
tail_len = BEACON_TAIL_BUF_SIZE; tail_len = BEACON_TAIL_BUF_SIZE;
#ifdef CONFIG_WPS #ifdef CONFIG_WPS
@ -2203,13 +2157,8 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
* long based on the common info and number of per * long based on the common info and number of per
* station profiles. For now use 256. * station profiles. For now use 256.
*/ */
if (hapd->conf->mld_ap) { if (hapd->conf->mld_ap)
tail_len += 256; tail_len += 256;
/* for Max Channel Switch Time element during channel
* switch */
tail_len += 6;
}
} }
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
@ -2220,9 +2169,6 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
tail_len += hostapd_mbo_ie_len(hapd); tail_len += hostapd_mbo_ie_len(hapd);
tail_len += hostapd_eid_owe_trans_len(hapd); tail_len += hostapd_eid_owe_trans_len(hapd);
tail_len += hostapd_eid_dpp_cc_len(hapd); tail_len += hostapd_eid_dpp_cc_len(hapd);
tail_len += hostapd_get_rsne_override_len(hapd);
tail_len += hostapd_get_rsne_override_2_len(hapd);
tail_len += hostapd_get_rsnxe_override_len(hapd);
tailpos = tail = os_malloc(tail_len); tailpos = tail = os_malloc(tail_len);
if (head == NULL || tail == NULL) { if (head == NULL || tail == NULL) {
@ -2353,14 +2299,10 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
tailpos = hostapd_eid_txpower_envelope(hapd, tailpos); tailpos = hostapd_eid_txpower_envelope(hapd, tailpos);
#endif /* CONFIG_IEEE80211AX */ #endif /* CONFIG_IEEE80211AX */
tailpos = hostapd_eid_chsw_wrapper(hapd, tailpos); tailpos = hostapd_eid_wb_chsw_wrapper(hapd, tailpos);
tailpos = hostapd_eid_rnr(hapd, tailpos, WLAN_FC_STYPE_BEACON, true); tailpos = hostapd_eid_rnr(hapd, tailpos, WLAN_FC_STYPE_BEACON, true);
tailpos = hostapd_eid_fils_indic(hapd, tailpos, 0); tailpos = hostapd_eid_fils_indic(hapd, tailpos, 0);
/* Max Channel Switch Time element */
tailpos = hostapd_eid_max_cs_time(hapd, tailpos);
tailpos = hostapd_get_rsnxe(hapd, tailpos, tailend - tailpos); tailpos = hostapd_get_rsnxe(hapd, tailpos, tailend - tailpos);
tailpos = hostapd_eid_mbssid_config(hapd, tailpos, tailpos = hostapd_eid_mbssid_config(hapd, tailpos,
params->mbssid_elem_count); params->mbssid_elem_count);
@ -2438,13 +2380,6 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
tail + tail_len - tailpos); tail + tail_len - tailpos);
tailpos = hostapd_eid_dpp_cc(hapd, tailpos, tail + tail_len - tailpos); tailpos = hostapd_eid_dpp_cc(hapd, tailpos, tail + tail_len - tailpos);
tailpos = hostapd_get_rsne_override(hapd, tailpos,
tail + tail_len - tailpos);
tailpos = hostapd_get_rsne_override_2(hapd, tailpos,
tail + tail_len - tailpos);
tailpos = hostapd_get_rsnxe_override(hapd, tailpos,
tail + tail_len - tailpos);
if (hapd->conf->vendor_elements) { if (hapd->conf->vendor_elements) {
os_memcpy(tailpos, wpabuf_head(hapd->conf->vendor_elements), os_memcpy(tailpos, wpabuf_head(hapd->conf->vendor_elements),
wpabuf_len(hapd->conf->vendor_elements)); wpabuf_len(hapd->conf->vendor_elements));
@ -2477,9 +2412,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
/* If SAE offload is enabled, provide password to lower layer for /* If SAE offload is enabled, provide password to lower layer for
* SAE authentication and PMK generation. * SAE authentication and PMK generation.
*/ */
if (wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt | if (wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) &&
hapd->conf->rsn_override_key_mgmt |
hapd->conf->rsn_override_key_mgmt_2) &&
(hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SAE_OFFLOAD_AP)) { (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SAE_OFFLOAD_AP)) {
if (hostapd_sae_pk_in_use(hapd->conf)) { if (hostapd_sae_pk_in_use(hapd->conf)) {
wpa_printf(MSG_ERROR, wpa_printf(MSG_ERROR,
@ -2524,9 +2457,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
else if (hapd->conf->wpa & WPA_PROTO_WPA) else if (hapd->conf->wpa & WPA_PROTO_WPA)
params->pairwise_ciphers = hapd->conf->wpa_pairwise; params->pairwise_ciphers = hapd->conf->wpa_pairwise;
params->group_cipher = hapd->conf->wpa_group; params->group_cipher = hapd->conf->wpa_group;
params->key_mgmt_suites = hapd->conf->wpa_key_mgmt | params->key_mgmt_suites = hapd->conf->wpa_key_mgmt;
hapd->conf->rsn_override_key_mgmt |
hapd->conf->rsn_override_key_mgmt_2;
params->auth_algs = hapd->conf->auth_algs; params->auth_algs = hapd->conf->auth_algs;
params->wpa_version = hapd->conf->wpa; params->wpa_version = hapd->conf->wpa;
params->privacy = hapd->conf->wpa; params->privacy = hapd->conf->wpa;
@ -2760,438 +2691,12 @@ void ieee802_11_set_beacon_per_bss_only(struct hostapd_data *hapd)
} }
#ifdef CONFIG_IEEE80211BE
static int hostapd_get_probe_resp_tmpl(struct hostapd_data *hapd,
struct probe_resp_params *params,
bool is_ml_sta_info)
{
os_memset(params, 0, sizeof(*params));
hostapd_gen_probe_resp(hapd, params);
if (!params->resp)
return -1;
/* The caller takes care of freeing params->resp. */
return 0;
}
static bool is_restricted_eid_in_sta_profile(u8 eid, bool tx_vap)
{
switch (eid) {
case WLAN_EID_TIM:
case WLAN_EID_BSS_MAX_IDLE_PERIOD:
case WLAN_EID_MULTIPLE_BSSID:
case WLAN_EID_REDUCED_NEIGHBOR_REPORT:
case WLAN_EID_NEIGHBOR_REPORT:
return true;
case WLAN_EID_SSID:
/* SSID is not restricted for non-transmitted BSSID */
return tx_vap;
default:
return false;
}
}
static bool is_restricted_ext_eid_in_sta_profile(u8 ext_id)
{
switch (ext_id) {
case WLAN_EID_EXT_MULTI_LINK:
return true;
default:
return false;
}
}
/* Create the link STA profiles based on inheritance from the reporting
* profile.
*
* NOTE: The same function is used for length calculation as well as filling
* data in the given buffer. This avoids risk of not updating the length
* function but filling function or vice versa.
*/
static size_t hostapd_add_sta_profile(struct ieee80211_mgmt *link_fdata,
size_t link_data_len,
struct ieee80211_mgmt *own_fdata,
size_t own_data_len,
u8 *sta_profile, bool tx_vap)
{
const struct element *link_elem;
size_t sta_profile_len = 0;
const u8 *link_elem_data;
u8 link_ele_len;
u8 *link_data;
const struct element *own_elem;
u8 link_eid, own_eid, own_ele_len;
const u8 *own_elem_data;
u8 *own_data;
bool is_ext;
bool ie_found;
u8 non_inherit_ele_ext_list[256] = { 0 };
u8 non_inherit_ele_ext_list_len = 0;
u8 non_inherit_ele_list[256] = { 0 };
u8 non_inherit_ele_list_len = 0;
u8 num_link_elem_vendor_ies = 0, num_own_elem_vendor_ies = 0;
bool add_vendor_ies = false, is_identical_vendor_ies = true;
/* The bitmap of parsed EIDs. There are 256 EIDs and ext EIDs, so 32
* bytes to store the bitmaps. */
u8 parsed_eid_bmap[32] = { 0 }, parsed_ext_eid_bmap[32] = { 0 };
/* extra len used in the logic includes the element id and len */
u8 extra_len = 2;
/* Include len for capab info */
sta_profile_len += sizeof(le16);
if (sta_profile) {
os_memcpy(sta_profile, &link_fdata->u.probe_resp.capab_info,
sizeof(le16));
sta_profile += sizeof(le16);
}
own_data = own_fdata->u.probe_resp.variable;
link_data = link_fdata->u.probe_resp.variable;
/* The below logic takes the reporting BSS data and reported BSS data
* and performs intersection to build the STA profile of the reported
* BSS. Certain elements are not added to the STA profile as
* recommended in standard. Matching element information in the
* reporting BSS profile are ignored in the STA profile. Remaining
* elements pertaining to the STA profile are appended at the end. */
for_each_element(own_elem, own_data, own_data_len) {
is_ext = false;
ie_found = false;
/* Pick one of own elements and get its EID and length */
own_elem_data = own_elem->data;
own_ele_len = own_elem->datalen;
if (own_elem->id == WLAN_EID_EXTENSION) {
is_ext = true;
own_eid = *(own_elem_data);
if (is_restricted_ext_eid_in_sta_profile(own_eid))
continue;
} else {
own_eid = own_elem->id;
if (is_restricted_eid_in_sta_profile(own_eid, tx_vap))
continue;
}
for_each_element(link_elem, link_data, link_data_len) {
/* If the element type mismatches, do not consider
* this link element for comparison. */
if ((link_elem->id == WLAN_EID_EXTENSION &&
!is_ext) ||
(is_ext && link_elem->id != WLAN_EID_EXTENSION))
continue;
/* Comparison can be done so get the link element and
* its EID and length. */
link_elem_data = link_elem->data;
link_ele_len = link_elem->datalen;
if (link_elem->id == WLAN_EID_EXTENSION)
link_eid = *(link_elem_data);
else
link_eid = link_elem->id;
/* Ignore if EID does not match */
if (own_eid != link_eid)
continue;
ie_found = true;
/* Ignore if the contents is identical. */
if (own_ele_len == link_ele_len &&
os_memcmp(own_elem->data, link_elem->data,
own_ele_len) == 0) {
if (own_eid == WLAN_EID_VENDOR_SPECIFIC) {
is_identical_vendor_ies = true;
num_own_elem_vendor_ies++;
}
continue;
}
/* No need to include this non-matching Vendor Specific
* element explicitly at this point. */
if (own_eid == WLAN_EID_VENDOR_SPECIFIC) {
is_identical_vendor_ies = false;
continue;
}
/* This element is present in the reported profile
* as well as present in the reporting profile.
* However, there is a mismatch in the contents and
* hence, include this in the per STA profile. */
sta_profile_len += link_ele_len + extra_len;
if (sta_profile) {
os_memcpy(sta_profile,
link_elem->data - extra_len,
link_ele_len + extra_len);
sta_profile += link_ele_len + extra_len;
}
/* Update the parsed EIDs bitmap */
if (is_ext)
parsed_ext_eid_bmap[own_eid / 8] |=
BIT(own_eid % 8);
else
parsed_eid_bmap[own_eid / 8] |=
BIT(own_eid % 8);
break;
}
/* We found at least one Vendor Specific element in reporting
* link which is not same (or present) in the reported link. We
* need to include all Vendor Specific elements from the
* reported link. */
if (!is_identical_vendor_ies)
add_vendor_ies = true;
/* This is a unique element in the reporting profile which is
* not present in the reported profile. Update the
* non-inheritance list. */
if (!ie_found) {
u8 idx;
if (is_ext) {
idx = non_inherit_ele_ext_list_len++;
non_inherit_ele_ext_list[idx] = own_eid;
} else {
idx = non_inherit_ele_list_len++;
non_inherit_ele_list[idx] = own_eid;
}
}
}
/* Parse the remaining elements in the reported profile */
for_each_element(link_elem, link_data, link_data_len) {
link_elem_data = link_elem->data;
link_ele_len = link_elem->datalen;
/* No need to check this Vendor Specific element at this point.
* Just take the count and continue. */
if (link_elem->id == WLAN_EID_VENDOR_SPECIFIC) {
num_link_elem_vendor_ies++;
continue;
}
if (link_elem->id == WLAN_EID_EXTENSION) {
link_eid = *(link_elem_data);
if ((parsed_ext_eid_bmap[link_eid / 8] &
BIT(link_eid % 8)) ||
is_restricted_ext_eid_in_sta_profile(link_eid))
continue;
} else {
link_eid = link_elem->id;
if ((parsed_eid_bmap[link_eid / 8] &
BIT(link_eid % 8)) ||
is_restricted_eid_in_sta_profile(link_eid, tx_vap))
continue;
}
sta_profile_len += link_ele_len + extra_len;
if (sta_profile) {
os_memcpy(sta_profile, link_elem_data - extra_len,
link_ele_len + extra_len);
sta_profile += link_ele_len + extra_len;
}
}
/* Handle Vendor Specific elements
* Add all the Vendor Specific elements of the reported link if
* a. There is at least one non-matching Vendor Specific element, or
* b. The number of Vendor Specific elements in reporting and reported
* link is not same. */
if (add_vendor_ies ||
num_own_elem_vendor_ies != num_link_elem_vendor_ies) {
for_each_element(link_elem, link_data, link_data_len) {
link_elem_data = link_elem->data;
link_ele_len = link_elem->datalen;
if (link_elem->id != WLAN_EID_VENDOR_SPECIFIC)
continue;
sta_profile_len += link_ele_len + extra_len;
if (sta_profile) {
os_memcpy(sta_profile,
link_elem_data - extra_len,
link_ele_len + extra_len);
sta_profile += link_ele_len + extra_len;
}
}
}
/* Handle non-inheritance
* Non-Inheritance element:
* Element ID Ext: 1 octet
* Length: 1 octet
* Ext tag number: 1 octet
* Length of Elements ID list: 1 octet
* Elements ID list: variable
* Length of Elements ID Extension list: 1 octet
* Elements ID extensions list: variable
*/
if (non_inherit_ele_list_len || non_inherit_ele_ext_list_len)
sta_profile_len += 3 + 2 + non_inherit_ele_list_len +
non_inherit_ele_ext_list_len;
if (sta_profile &&
(non_inherit_ele_list_len || non_inherit_ele_ext_list_len)) {
*sta_profile++ = WLAN_EID_EXTENSION;
*sta_profile++ = non_inherit_ele_list_len +
non_inherit_ele_ext_list_len + 3;
*sta_profile++ = WLAN_EID_EXT_NON_INHERITANCE;
*sta_profile++ = non_inherit_ele_list_len;
os_memcpy(sta_profile, non_inherit_ele_list,
non_inherit_ele_list_len);
sta_profile += non_inherit_ele_list_len;
*sta_profile++ = non_inherit_ele_ext_list_len;
os_memcpy(sta_profile, non_inherit_ele_ext_list,
non_inherit_ele_ext_list_len);
sta_profile += non_inherit_ele_ext_list_len;
}
return sta_profile_len;
}
static u8 * hostapd_gen_sta_profile(struct ieee80211_mgmt *link_data,
size_t link_data_len,
struct ieee80211_mgmt *own_data,
size_t own_data_len,
size_t *sta_profile_len, bool tx_vap)
{
u8 *sta_profile;
/* Get the length first */
*sta_profile_len = hostapd_add_sta_profile(link_data, link_data_len,
own_data, own_data_len,
NULL, tx_vap);
if (!(*sta_profile_len) || *sta_profile_len > EHT_ML_MAX_STA_PROF_LEN)
return NULL;
sta_profile = os_zalloc(*sta_profile_len);
if (!sta_profile)
return NULL;
/* Now fill in the data */
hostapd_add_sta_profile(link_data, link_data_len, own_data,
own_data_len, sta_profile, tx_vap);
/* The caller takes care of freeing the returned sta_profile */
return sta_profile;
}
static void hostapd_gen_per_sta_profiles(struct hostapd_data *hapd)
{
bool tx_vap = hapd == hostapd_mbssid_get_tx_bss(hapd);
size_t link_data_len, sta_profile_len;
size_t own_data_len;
struct probe_resp_params link_params;
struct probe_resp_params own_params;
struct ieee80211_mgmt *link_data;
struct ieee80211_mgmt *own_data;
struct mld_link_info *link_info;
struct hostapd_data *link_bss;
u8 link_id, *sta_profile;
if (!hapd->conf->mld_ap)
return;
wpa_printf(MSG_DEBUG, "MLD: Generating per STA profiles for MLD %s",
hapd->conf->iface);
wpa_printf(MSG_DEBUG, "MLD: Reporting link %d", hapd->mld_link_id);
/* Generate a Probe Response template for self */
if (hostapd_get_probe_resp_tmpl(hapd, &own_params, false)) {
wpa_printf(MSG_ERROR,
"MLD: Error in building per STA profiles");
return;
}
own_data = own_params.resp;
own_data_len = own_params.resp_len;
/* Consider the length of the variable fields */
own_data_len -= offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
for_each_mld_link(link_bss, hapd) {
if (link_bss == hapd || !link_bss->started)
continue;
link_id = link_bss->mld_link_id;
if (link_id > MAX_NUM_MLD_LINKS)
continue;
sta_profile = NULL;
sta_profile_len = 0;
/* Generate a Probe Response frame template for partner link */
if (hostapd_get_probe_resp_tmpl(link_bss, &link_params, true)) {
wpa_printf(MSG_ERROR,
"MLD: Could not get link STA probe response template for link %d",
link_id);
continue;
}
link_data = link_params.resp;
link_data_len = link_params.resp_len;
/* Consider length of the variable fields */
link_data_len -= offsetof(struct ieee80211_mgmt,
u.probe_resp.variable);
sta_profile = hostapd_gen_sta_profile(link_data, link_data_len,
own_data, own_data_len,
&sta_profile_len, tx_vap);
if (!sta_profile) {
wpa_printf(MSG_ERROR,
"MLD: Could not generate link STA profile for link %d",
link_id);
continue;
}
link_info = &hapd->partner_links[link_id];
link_info->valid = true;
os_free(link_info->resp_sta_profile);
link_info->resp_sta_profile_len = sta_profile_len;
link_info->resp_sta_profile = os_memdup(sta_profile,
sta_profile_len);
if (!link_info->resp_sta_profile)
link_info->resp_sta_profile_len = 0;
os_memcpy(link_info->local_addr, link_bss->own_addr, ETH_ALEN);
wpa_printf(MSG_DEBUG,
"MLD: Reported link STA info for %d: %u bytes",
link_id, link_info->resp_sta_profile_len);
os_free(sta_profile);
os_free(link_params.resp);
}
os_free(own_params.resp);
}
#endif /* CONFIG_IEEE80211BE */
int ieee802_11_set_beacon(struct hostapd_data *hapd) int ieee802_11_set_beacon(struct hostapd_data *hapd)
{ {
struct hostapd_iface *iface = hapd->iface; struct hostapd_iface *iface = hapd->iface;
int ret; int ret;
size_t i, j; size_t i, j;
bool is_6g, hapd_mld = false; bool is_6g, hapd_mld = false;
#ifdef CONFIG_IEEE80211BE
struct hostapd_data *link_bss;
#endif /* CONFIG_IEEE80211BE */
ret = __ieee802_11_set_beacon(hapd); ret = __ieee802_11_set_beacon(hapd);
if (ret != 0) if (ret != 0)
@ -3232,15 +2737,6 @@ int ieee802_11_set_beacon(struct hostapd_data *hapd)
} }
} }
#ifdef CONFIG_IEEE80211BE
if (!hapd_mld)
return 0;
/* Generate per STA profiles for each affiliated APs */
for_each_mld_link(link_bss, hapd)
hostapd_gen_per_sta_profiles(link_bss);
#endif /* CONFIG_IEEE80211BE */
return 0; return 0;
} }

View file

@ -661,18 +661,15 @@ int hostapd_ctrl_iface_deauthenticate(struct hostapd_data *hapd,
} }
#endif /* CONFIG_P2P_MANAGER */ #endif /* CONFIG_P2P_MANAGER */
sta = ap_get_sta(hapd, addr); if (os_strstr(txtaddr, " tx=0"))
if (os_strstr(txtaddr, " tx=0")) {
hostapd_drv_sta_remove(hapd, addr); hostapd_drv_sta_remove(hapd, addr);
if (sta) else
ap_free_sta(hapd, sta);
} else {
hostapd_drv_sta_deauth(hapd, addr, reason); hostapd_drv_sta_deauth(hapd, addr, reason);
sta = ap_get_sta(hapd, addr);
if (sta) if (sta)
ap_sta_deauthenticate(hapd, sta, reason); ap_sta_deauthenticate(hapd, sta, reason);
else if (addr[0] == 0xff) else if (addr[0] == 0xff)
hostapd_free_stas(hapd); hostapd_free_stas(hapd);
}
return 0; return 0;
} }
@ -726,18 +723,15 @@ int hostapd_ctrl_iface_disassociate(struct hostapd_data *hapd,
} }
#endif /* CONFIG_P2P_MANAGER */ #endif /* CONFIG_P2P_MANAGER */
sta = ap_get_sta(hapd, addr); if (os_strstr(txtaddr, " tx=0"))
if (os_strstr(txtaddr, " tx=0")) {
hostapd_drv_sta_remove(hapd, addr); hostapd_drv_sta_remove(hapd, addr);
if (sta) else
ap_free_sta(hapd, sta);
} else {
hostapd_drv_sta_disassoc(hapd, addr, reason); hostapd_drv_sta_disassoc(hapd, addr, reason);
sta = ap_get_sta(hapd, addr);
if (sta) if (sta)
ap_sta_disassociate(hapd, sta, reason); ap_sta_disassociate(hapd, sta, reason);
else if (addr[0] == 0xff) else if (addr[0] == 0xff)
hostapd_free_stas(hapd); hostapd_free_stas(hapd);
}
return 0; return 0;
} }
@ -1143,9 +1137,8 @@ int hostapd_parse_csa_settings(const char *pos,
SET_CSA_SETTING_EXT(punct_bitmap); SET_CSA_SETTING_EXT(punct_bitmap);
settings->freq_params.ht_enabled = !!os_strstr(pos, " ht"); settings->freq_params.ht_enabled = !!os_strstr(pos, " ht");
settings->freq_params.vht_enabled = !!os_strstr(pos, " vht"); settings->freq_params.vht_enabled = !!os_strstr(pos, " vht");
settings->freq_params.he_enabled = !!os_strstr(pos, " he");
settings->freq_params.eht_enabled = !!os_strstr(pos, " eht"); settings->freq_params.eht_enabled = !!os_strstr(pos, " eht");
settings->freq_params.he_enabled = !!os_strstr(pos, " he") ||
settings->freq_params.eht_enabled;
settings->block_tx = !!os_strstr(pos, " blocktx"); settings->block_tx = !!os_strstr(pos, " blocktx");
#undef SET_CSA_SETTING #undef SET_CSA_SETTING
#undef SET_CSA_SETTING_EXT #undef SET_CSA_SETTING_EXT

View file

@ -253,13 +253,6 @@ static int dfs_find_channel(struct hostapd_iface *iface,
for (i = 0; i < mode->num_channels; i++) { for (i = 0; i < mode->num_channels; i++) {
chan = &mode->channels[i]; chan = &mode->channels[i];
if (!chan_in_current_hw_info(iface->current_hw_info, chan)) {
wpa_printf(MSG_DEBUG,
"DFS: channel %d (%d) is not under current hardware index",
chan->freq, chan->chan);
continue;
}
/* Skip HT40/VHT incompatible channels */ /* Skip HT40/VHT incompatible channels */
if (iface->conf->ieee80211n && if (iface->conf->ieee80211n &&
iface->conf->secondary_channel && iface->conf->secondary_channel &&
@ -1225,6 +1218,8 @@ int hostapd_dfs_pre_cac_expired(struct hostapd_iface *iface, int freq,
"freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d", "freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d",
freq, ht_enabled, chan_offset, chan_width, cf1, cf2); freq, ht_enabled, chan_offset, chan_width, cf1, cf2);
hostapd_ubus_notify_radar_detected(iface, freq, chan_width, cf1, cf2);
/* Proceed only if DFS is not offloaded to the driver */ /* Proceed only if DFS is not offloaded to the driver */
if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)
return 0; return 0;

View file

@ -73,8 +73,6 @@ void hostapd_notify_assoc_fils_finish(struct hostapd_data *hapd,
p = hostapd_eid_assoc_fils_session(sta->wpa_sm, p, p = hostapd_eid_assoc_fils_session(sta->wpa_sm, p,
elems.fils_session, elems.fils_session,
sta->fils_hlp_resp); sta->fils_hlp_resp);
if (!p)
return;
reply_res = hostapd_sta_assoc(hapd, sta->addr, reply_res = hostapd_sta_assoc(hapd, sta->addr,
sta->fils_pending_assoc_is_reassoc, sta->fils_pending_assoc_is_reassoc,
@ -250,52 +248,6 @@ out:
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
#if defined(HOSTAPD) || defined(CONFIG_IEEE80211BE)
static struct hostapd_data * hostapd_find_by_sta(struct hostapd_iface *iface,
const u8 *src, bool rsn,
struct sta_info **sta_ret)
{
struct hostapd_data *hapd;
struct sta_info *sta;
unsigned int j;
if (sta_ret)
*sta_ret = NULL;
for (j = 0; j < iface->num_bss; j++) {
hapd = iface->bss[j];
sta = ap_get_sta(hapd, src);
if (sta && (sta->flags & WLAN_STA_ASSOC) &&
(!rsn || sta->wpa_sm)) {
if (sta_ret)
*sta_ret = sta;
return hapd;
}
#ifdef CONFIG_IEEE80211BE
if (hapd->conf->mld_ap) {
struct hostapd_data *p_hapd;
for_each_mld_link(p_hapd, hapd) {
if (p_hapd == hapd)
continue;
sta = ap_get_sta(p_hapd, src);
if (sta && (sta->flags & WLAN_STA_ASSOC) &&
(!rsn || sta->wpa_sm)) {
if (sta_ret)
*sta_ret = sta;
return p_hapd;
}
}
}
#endif /* CONFIG_IEEE80211BE */
}
return NULL;
}
#endif /* HOSTAPD || CONFIG_IEEE80211BE */
int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
const u8 *req_ies, size_t req_ies_len, const u8 *req_ies, size_t req_ies_len,
const u8 *resp_ies, size_t resp_ies_len, const u8 *resp_ies, size_t resp_ies_len,
@ -316,6 +268,10 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
struct hostapd_iface *iface = hapd->iface; struct hostapd_iface *iface = hapd->iface;
#endif /* CONFIG_OWE */ #endif /* CONFIG_OWE */
bool updated = false; bool updated = false;
struct hostapd_ubus_request req = {
.type = HOSTAPD_UBUS_ASSOC_REQ,
.addr = addr,
};
if (addr == NULL) { if (addr == NULL) {
/* /*
@ -460,6 +416,12 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
goto fail; goto fail;
} }
if (hostapd_ubus_handle_event(hapd, &req)) {
wpa_printf(MSG_DEBUG, "Station " MACSTR " assoc rejected by ubus handler.\n",
MAC2STR(req.addr));
goto fail;
}
#ifdef CONFIG_P2P #ifdef CONFIG_P2P
if (elems.p2p) { if (elems.p2p) {
wpabuf_free(sta->p2p_ie); wpabuf_free(sta->p2p_ie);
@ -561,8 +523,6 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
"Failed to initialize WPA state machine"); "Failed to initialize WPA state machine");
return -1; return -1;
} }
wpa_auth_set_rsn_selection(sta->wpa_sm, elems.rsn_selection,
elems.rsn_selection_len);
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
if (ap_sta_is_mld(hapd, sta)) { if (ap_sta_is_mld(hapd, sta)) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
@ -823,9 +783,6 @@ skip_wpa_check:
p = hostapd_eid_assoc_fils_session(sta->wpa_sm, p, p = hostapd_eid_assoc_fils_session(sta->wpa_sm, p,
elems.fils_session, elems.fils_session,
sta->fils_hlp_resp); sta->fils_hlp_resp);
if (!p)
goto fail;
wpa_hexdump(MSG_DEBUG, "FILS Assoc Resp BUF (IEs)", wpa_hexdump(MSG_DEBUG, "FILS Assoc Resp BUF (IEs)",
buf, p - buf); buf, p - buf);
} }
@ -1090,20 +1047,6 @@ legacy:
void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr) void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr)
{ {
struct sta_info *sta = ap_get_sta(hapd, addr); struct sta_info *sta = ap_get_sta(hapd, addr);
#ifdef CONFIG_IEEE80211BE
struct hostapd_data *orig_hapd = hapd;
if (!sta && hapd->conf->mld_ap) {
hapd = hostapd_find_by_sta(hapd->iface, addr, true, &sta);
if (!hapd) {
wpa_printf(MSG_DEBUG,
"No partner link BSS found for STA " MACSTR
" - fallback to received context",
MAC2STR(addr));
hapd = orig_hapd;
}
}
#endif /* CONFIG_IEEE80211BE */
if (!sta || !hapd->conf->disassoc_low_ack || sta->agreed_to_steer) if (!sta || !hapd->conf->disassoc_low_ack || sta->agreed_to_steer)
return; return;
@ -2046,6 +1989,50 @@ static int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr)
} }
static struct hostapd_data * hostapd_find_by_sta(struct hostapd_iface *iface,
const u8 *src, bool rsn,
struct sta_info **sta_ret)
{
struct hostapd_data *hapd;
struct sta_info *sta;
unsigned int j;
if (sta_ret)
*sta_ret = NULL;
for (j = 0; j < iface->num_bss; j++) {
hapd = iface->bss[j];
sta = ap_get_sta(hapd, src);
if (sta && (sta->flags & WLAN_STA_ASSOC) &&
(!rsn || sta->wpa_sm)) {
if (sta_ret)
*sta_ret = sta;
return hapd;
}
#ifdef CONFIG_IEEE80211BE
if (hapd->conf->mld_ap) {
struct hostapd_data *p_hapd;
for_each_mld_link(p_hapd, hapd) {
if (p_hapd == hapd)
continue;
sta = ap_get_sta(p_hapd, src);
if (sta && (sta->flags & WLAN_STA_ASSOC) &&
(!rsn || sta->wpa_sm)) {
if (sta_ret)
*sta_ret = sta;
return p_hapd;
}
}
}
#endif /* CONFIG_IEEE80211BE */
}
return NULL;
}
static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src, static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src,
const u8 *data, size_t data_len, const u8 *data, size_t data_len,
enum frame_encryption encrypted, enum frame_encryption encrypted,
@ -2432,88 +2419,6 @@ static void hostapd_event_color_change(struct hostapd_data *hapd, bool success)
#endif /* CONFIG_IEEE80211AX */ #endif /* CONFIG_IEEE80211AX */
static void hostapd_iface_enable(struct hostapd_data *hapd)
{
wpa_msg(hapd->msg_ctx, MSG_INFO, INTERFACE_ENABLED);
if (hapd->disabled && hapd->started) {
hapd->disabled = 0;
/*
* Try to re-enable interface if the driver stopped it
* when the interface got disabled.
*/
if (hapd->wpa_auth)
wpa_auth_reconfig_group_keys(hapd->wpa_auth);
else
hostapd_reconfig_encryption(hapd);
hapd->reenable_beacon = 1;
ieee802_11_set_beacon(hapd);
#ifdef NEED_AP_MLME
} else if (hapd->disabled && hapd->iface->cac_started) {
wpa_printf(MSG_DEBUG, "DFS: restarting pending CAC");
hostapd_handle_dfs(hapd->iface);
#endif /* NEED_AP_MLME */
}
}
static void hostapd_iface_disable(struct hostapd_data *hapd)
{
hostapd_free_stas(hapd);
wpa_msg(hapd->msg_ctx, MSG_INFO, INTERFACE_DISABLED);
hapd->disabled = 1;
}
#ifdef CONFIG_IEEE80211BE
static void hostapd_mld_iface_enable(struct hostapd_data *hapd)
{
struct hostapd_data *first_link, *link_bss;
first_link = hostapd_mld_is_first_bss(hapd) ? hapd :
hostapd_mld_get_first_bss(hapd);
/* Links have been removed. Re-add all links and enable them, but
* enable the first link BSS before doing that. */
if (hostapd_drv_link_add(first_link, first_link->mld_link_id,
first_link->own_addr)) {
wpa_printf(MSG_ERROR, "MLD: Failed to re-add link %d in MLD %s",
first_link->mld_link_id, first_link->conf->iface);
return;
}
hostapd_iface_enable(first_link);
/* Add other affiliated links */
for_each_mld_link(link_bss, first_link) {
if (link_bss == first_link)
continue;
if (hostapd_drv_link_add(link_bss, link_bss->mld_link_id,
link_bss->own_addr)) {
wpa_printf(MSG_ERROR,
"MLD: Failed to re-add link %d in MLD %s",
link_bss->mld_link_id,
link_bss->conf->iface);
continue;
}
hostapd_iface_enable(link_bss);
}
}
static void hostapd_mld_iface_disable(struct hostapd_data *hapd)
{
struct hostapd_data *link_bss;
for_each_mld_link(link_bss, hapd)
hostapd_iface_disable(link_bss);
}
#endif /* CONFIG_IEEE80211BE */
void wpa_supplicant_event(void *ctx, enum wpa_event_type event, void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
union wpa_event_data *data) union wpa_event_data *data)
{ {
@ -2791,22 +2696,30 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
break; break;
#endif /* NEED_AP_MLME */ #endif /* NEED_AP_MLME */
case EVENT_INTERFACE_ENABLED: case EVENT_INTERFACE_ENABLED:
#ifdef CONFIG_IEEE80211BE wpa_msg(hapd->msg_ctx, MSG_INFO, INTERFACE_ENABLED);
if (hapd->conf->mld_ap) { if (hapd->disabled && hapd->started) {
hostapd_mld_iface_enable(hapd); hapd->disabled = 0;
break; /*
* Try to re-enable interface if the driver stopped it
* when the interface got disabled.
*/
if (hapd->wpa_auth)
wpa_auth_reconfig_group_keys(hapd->wpa_auth);
else
hostapd_reconfig_encryption(hapd);
hapd->reenable_beacon = 1;
ieee802_11_set_beacon(hapd);
#ifdef NEED_AP_MLME
} else if (hapd->disabled && hapd->iface->cac_started) {
wpa_printf(MSG_DEBUG, "DFS: restarting pending CAC");
hostapd_handle_dfs(hapd->iface);
#endif /* NEED_AP_MLME */
} }
#endif /* CONFIG_IEEE80211BE */
hostapd_iface_enable(hapd);
break; break;
case EVENT_INTERFACE_DISABLED: case EVENT_INTERFACE_DISABLED:
#ifdef CONFIG_IEEE80211BE hostapd_free_stas(hapd);
if (hapd->conf->mld_ap) { wpa_msg(hapd->msg_ctx, MSG_INFO, INTERFACE_DISABLED);
hostapd_mld_iface_disable(hapd); hapd->disabled = 1;
break;
}
#endif /* CONFIG_IEEE80211BE */
hostapd_iface_disable(hapd);
break; break;
#ifdef CONFIG_ACS #ifdef CONFIG_ACS
case EVENT_ACS_CHANNEL_SELECTED: case EVENT_ACS_CHANNEL_SELECTED:
@ -2859,13 +2772,6 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
hostapd_event_color_change(hapd, true); hostapd_event_color_change(hapd, true);
break; break;
#endif /* CONFIG_IEEE80211AX */ #endif /* CONFIG_IEEE80211AX */
#ifdef CONFIG_IEEE80211BE
case EVENT_MLD_INTERFACE_FREED:
wpa_printf(MSG_DEBUG, "MLD: Interface %s freed",
hapd->conf->iface);
hostapd_mld_interface_freed(hapd);
break;
#endif /* CONFIG_IEEE80211BE */
default: default:
wpa_printf(MSG_DEBUG, "Unknown event %d", event); wpa_printf(MSG_DEBUG, "Unknown event %d", event);
break; break;

View file

@ -400,6 +400,8 @@ static int hostapd_broadcast_wep_set(struct hostapd_data *hapd)
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
#ifdef CONFIG_TESTING_OPTIONS #ifdef CONFIG_TESTING_OPTIONS
#define TU_TO_USEC(_val) ((_val) * 1024)
static void hostapd_link_remove_timeout_handler(void *eloop_data, static void hostapd_link_remove_timeout_handler(void *eloop_data,
void *user_ctx) void *user_ctx)
{ {
@ -438,8 +440,6 @@ int hostapd_link_remove(struct hostapd_data *hapd, u32 count)
hapd->eht_mld_link_removal_count = count; hapd->eht_mld_link_removal_count = count;
hapd->eht_mld_bss_param_change++; hapd->eht_mld_bss_param_change++;
if (hapd->eht_mld_bss_param_change == 255)
hapd->eht_mld_bss_param_change = 0;
eloop_register_timeout(0, TU_TO_USEC(hapd->iconf->beacon_int), eloop_register_timeout(0, TU_TO_USEC(hapd->iconf->beacon_int),
hostapd_link_remove_timeout_handler, hostapd_link_remove_timeout_handler,
@ -475,6 +475,7 @@ void hostapd_free_hapd_data(struct hostapd_data *hapd)
hapd->beacon_set_done = 0; hapd->beacon_set_done = 0;
wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface);
hostapd_ubus_free_bss(hapd);
accounting_deinit(hapd); accounting_deinit(hapd);
hostapd_deinit_wpa(hapd); hostapd_deinit_wpa(hapd);
vlan_deinit(hapd); vlan_deinit(hapd);
@ -620,19 +621,9 @@ void hostapd_free_hapd_data(struct hostapd_data *hapd)
static void hostapd_bss_link_deinit(struct hostapd_data *hapd) static void hostapd_bss_link_deinit(struct hostapd_data *hapd)
{ {
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
int i;
if (!hapd->conf || !hapd->conf->mld_ap) if (!hapd->conf || !hapd->conf->mld_ap)
return; return;
/* Free per STA profiles */
for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
os_free(hapd->partner_links[i].resp_sta_profile);
os_memset(&hapd->partner_links[i], 0,
sizeof(hapd->partner_links[i]));
}
/* Put all freeing logic above this */
if (!hapd->mld->num_links) if (!hapd->mld->num_links)
return; return;
@ -712,9 +703,6 @@ void hostapd_cleanup_iface_partial(struct hostapd_iface *iface)
ap_list_deinit(iface); ap_list_deinit(iface);
sta_track_deinit(iface); sta_track_deinit(iface);
airtime_policy_update_deinit(iface); airtime_policy_update_deinit(iface);
hostapd_free_multi_hw_info(iface->multi_hw_info);
iface->multi_hw_info = NULL;
iface->current_hw_info = NULL;
} }
@ -1316,6 +1304,8 @@ static int hostapd_start_beacon(struct hostapd_data *hapd,
if (hapd->driver && hapd->driver->set_operstate) if (hapd->driver && hapd->driver->set_operstate)
hapd->driver->set_operstate(hapd->drv_priv, 1); hapd->driver->set_operstate(hapd->drv_priv, 1);
hostapd_ubus_add_bss(hapd);
return 0; return 0;
} }
@ -1453,6 +1443,7 @@ static int hostapd_setup_bss(struct hostapd_data *hapd, int first,
if (h_hapd) { if (h_hapd) {
hapd->drv_priv = h_hapd->drv_priv; hapd->drv_priv = h_hapd->drv_priv;
hapd->interface_added = h_hapd->interface_added; hapd->interface_added = h_hapd->interface_added;
hostapd_mld_add_link(hapd);
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"Setup of non first link (%d) BSS of MLD %s", "Setup of non first link (%d) BSS of MLD %s",
hapd->mld_link_id, hapd->conf->iface); hapd->mld_link_id, hapd->conf->iface);
@ -1483,6 +1474,7 @@ static int hostapd_setup_bss(struct hostapd_data *hapd, int first,
hapd->mld_link_id, hapd->conf->iface); hapd->mld_link_id, hapd->conf->iface);
os_memcpy(hapd->mld->mld_addr, hapd->own_addr, os_memcpy(hapd->mld->mld_addr, hapd->own_addr,
ETH_ALEN); ETH_ALEN);
hostapd_mld_add_link(hapd);
} }
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
} }
@ -1497,14 +1489,9 @@ setup_mld:
MAC2STR(hapd->own_addr)); MAC2STR(hapd->own_addr));
if (hostapd_drv_link_add(hapd, hapd->mld_link_id, if (hostapd_drv_link_add(hapd, hapd->mld_link_id,
hapd->own_addr)) { hapd->own_addr))
wpa_printf(MSG_ERROR,
"MLD: Failed to add link %d in MLD %s",
hapd->mld_link_id, hapd->conf->iface);
return -1; return -1;
} }
hostapd_mld_add_link(hapd);
}
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
if (conf->wmm_enabled < 0) if (conf->wmm_enabled < 0)
@ -1824,36 +1811,12 @@ int hostapd_set_acl(struct hostapd_data *hapd)
} }
static int hostapd_set_ctrl_sock_iface(struct hostapd_data *hapd)
{
#ifdef CONFIG_IEEE80211BE
int ret;
if (hapd->conf->mld_ap) {
ret = os_snprintf(hapd->ctrl_sock_iface,
sizeof(hapd->ctrl_sock_iface), "%s_%s%d",
hapd->conf->iface, WPA_CTRL_IFACE_LINK_NAME,
hapd->mld_link_id);
if (os_snprintf_error(sizeof(hapd->ctrl_sock_iface), ret))
return -1;
} else {
os_strlcpy(hapd->ctrl_sock_iface, hapd->conf->iface,
sizeof(hapd->ctrl_sock_iface));
}
#endif /* CONFIG_IEEE80211BE */
return 0;
}
static int start_ctrl_iface_bss(struct hostapd_data *hapd) static int start_ctrl_iface_bss(struct hostapd_data *hapd)
{ {
if (!hapd->iface->interfaces || if (!hapd->iface->interfaces ||
!hapd->iface->interfaces->ctrl_iface_init) !hapd->iface->interfaces->ctrl_iface_init)
return 0; return 0;
if (hostapd_set_ctrl_sock_iface(hapd))
return -1;
if (hapd->iface->interfaces->ctrl_iface_init(hapd)) { if (hapd->iface->interfaces->ctrl_iface_init(hapd)) {
wpa_printf(MSG_ERROR, wpa_printf(MSG_ERROR,
"Failed to setup control interface for %s", "Failed to setup control interface for %s",
@ -1874,10 +1837,6 @@ static int start_ctrl_iface(struct hostapd_iface *iface)
for (i = 0; i < iface->num_bss; i++) { for (i = 0; i < iface->num_bss; i++) {
struct hostapd_data *hapd = iface->bss[i]; struct hostapd_data *hapd = iface->bss[i];
if (hostapd_set_ctrl_sock_iface(hapd))
return -1;
if (iface->interfaces->ctrl_iface_init(hapd)) { if (iface->interfaces->ctrl_iface_init(hapd)) {
wpa_printf(MSG_ERROR, wpa_printf(MSG_ERROR,
"Failed to setup control interface for %s", "Failed to setup control interface for %s",
@ -2525,6 +2484,7 @@ static int hostapd_setup_interface_complete_sync(struct hostapd_iface *iface,
if (err) if (err)
goto fail; goto fail;
hostapd_ubus_add_iface(iface);
wpa_printf(MSG_DEBUG, "Completing interface initialization"); wpa_printf(MSG_DEBUG, "Completing interface initialization");
if (iface->freq) { if (iface->freq) {
#ifdef NEED_AP_MLME #ifdef NEED_AP_MLME
@ -2536,12 +2496,6 @@ static int hostapd_setup_interface_complete_sync(struct hostapd_iface *iface,
hostapd_hw_mode_txt(iface->conf->hw_mode), hostapd_hw_mode_txt(iface->conf->hw_mode),
iface->conf->channel, iface->freq); iface->conf->channel, iface->freq);
if (hostapd_set_current_hw_info(iface, iface->freq)) {
wpa_printf(MSG_ERROR,
"Failed to set current hardware info");
goto fail;
}
#ifdef NEED_AP_MLME #ifdef NEED_AP_MLME
/* Handle DFS only if it is not offloaded to the driver */ /* Handle DFS only if it is not offloaded to the driver */
if (!(iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)) { if (!(iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)) {
@ -2722,6 +2676,8 @@ dfs_offload:
#endif /* CONFIG_FST */ #endif /* CONFIG_FST */
hostapd_set_state(iface, HAPD_IFACE_ENABLED); hostapd_set_state(iface, HAPD_IFACE_ENABLED);
// TODO: log everything in `hostapd_set_state` directly
hostapd_ubus_notify_readiness(hapd);
hostapd_owe_update_trans(iface); hostapd_owe_update_trans(iface);
airtime_policy_update_init(iface); airtime_policy_update_init(iface);
wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_ENABLED); wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_ENABLED);
@ -2750,6 +2706,7 @@ dfs_offload:
fail: fail:
wpa_printf(MSG_ERROR, "Interface initialization failed"); wpa_printf(MSG_ERROR, "Interface initialization failed");
hostapd_ubus_free_iface(iface);
if (iface->is_no_ir) { if (iface->is_no_ir) {
hostapd_set_state(iface, HAPD_IFACE_NO_IR); hostapd_set_state(iface, HAPD_IFACE_NO_IR);
@ -3115,17 +3072,9 @@ static void hostapd_bss_setup_multi_link(struct hostapd_data *hapd,
os_strlcpy(mld->name, conf->iface, sizeof(conf->iface)); os_strlcpy(mld->name, conf->iface, sizeof(conf->iface));
dl_list_init(&mld->links); dl_list_init(&mld->links);
mld->ctrl_sock = -1;
if (hapd->conf->ctrl_interface)
mld->ctrl_interface = os_strdup(hapd->conf->ctrl_interface);
wpa_printf(MSG_DEBUG, "AP MLD %s created", mld->name); wpa_printf(MSG_DEBUG, "AP MLD %s created", mld->name);
/* Initialize MLD control interfaces early to allow external monitoring
* of link setup operations. */
if (interfaces->mld_ctrl_iface_init(mld))
goto fail;
hapd->mld = mld; hapd->mld = mld;
hostapd_mld_ref_inc(mld); hostapd_mld_ref_inc(mld);
hostapd_bss_alloc_link_id(hapd); hostapd_bss_alloc_link_id(hapd);
@ -3185,8 +3134,6 @@ static void hostapd_cleanup_unused_mlds(struct hapd_interfaces *interfaces)
if (!remove && !forced_remove) if (!remove && !forced_remove)
continue; continue;
interfaces->mld_ctrl_iface_deinit(mld);
wpa_printf(MSG_DEBUG, "AP MLD %s: Freed%s", mld->name, wpa_printf(MSG_DEBUG, "AP MLD %s: Freed%s", mld->name,
forced_remove ? " (forced)" : ""); forced_remove ? " (forced)" : "");
os_free(mld); os_free(mld);
@ -3447,10 +3394,8 @@ static void hostapd_cleanup_driver(const struct wpa_driver_ops *driver,
driver->hapd_deinit(drv_priv); driver->hapd_deinit(drv_priv);
} else if (hostapd_mld_is_first_bss(iface->bss[0]) && } else if (hostapd_mld_is_first_bss(iface->bss[0]) &&
driver->is_drv_shared && driver->is_drv_shared &&
!driver->is_drv_shared(drv_priv, !driver->is_drv_shared(drv_priv, iface->bss[0])) {
iface->bss[0]->mld_link_id)) {
driver->hapd_deinit(drv_priv); driver->hapd_deinit(drv_priv);
hostapd_mld_interface_freed(iface->bss[0]);
} else if (hostapd_if_link_remove(iface->bss[0], } else if (hostapd_if_link_remove(iface->bss[0],
WPA_IF_AP_BSS, WPA_IF_AP_BSS,
iface->bss[0]->conf->iface, iface->bss[0]->conf->iface,
@ -3478,6 +3423,7 @@ void hostapd_interface_deinit_free(struct hostapd_iface *iface)
(unsigned int) iface->conf->num_bss); (unsigned int) iface->conf->num_bss);
driver = iface->bss[0]->driver; driver = iface->bss[0]->driver;
drv_priv = iface->bss[0]->drv_priv; drv_priv = iface->bss[0]->drv_priv;
hostapd_ubus_free_iface(iface);
hostapd_interface_deinit(iface); hostapd_interface_deinit(iface);
wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
__func__, driver, drv_priv); __func__, driver, drv_priv);
@ -4563,42 +4509,6 @@ int hostapd_switch_channel(struct hostapd_data *hapd,
} }
int hostapd_force_channel_switch(struct hostapd_iface *iface,
struct csa_settings settings)
{
int ret = 0;
if (!settings.freq_params.channel) {
/* Check if the new channel is supported */
settings.freq_params.channel = hostapd_hw_get_channel(
iface->bss[0], settings.freq_params.freq);
if (!settings.freq_params.channel)
return -1;
}
ret = hostapd_disable_iface(iface);
if (ret) {
wpa_printf(MSG_DEBUG, "Failed to disable the interface");
return ret;
}
hostapd_chan_switch_config(iface->bss[0], &settings.freq_params);
ret = hostapd_change_config_freq(iface->bss[0], iface->conf,
&settings.freq_params, NULL);
if (ret) {
wpa_printf(MSG_DEBUG,
"Failed to set the new channel in config");
return ret;
}
ret = hostapd_enable_iface(iface);
if (ret)
wpa_printf(MSG_DEBUG, "Failed to enable the interface");
return ret;
}
void void
hostapd_switch_channel_fallback(struct hostapd_iface *iface, hostapd_switch_channel_fallback(struct hostapd_iface *iface,
const struct hostapd_freq_params *freq_params) const struct hostapd_freq_params *freq_params)
@ -5030,18 +4940,6 @@ struct hostapd_data * hostapd_mld_get_first_bss(struct hostapd_data *hapd)
return mld->fbss; return mld->fbss;
} }
void hostapd_mld_interface_freed(struct hostapd_data *hapd)
{
struct hostapd_data *link_bss = NULL;
if (!hapd || !hapd->conf->mld_ap)
return;
for_each_mld_link(link_bss, hapd)
link_bss->drv_priv = NULL;
}
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */

View file

@ -18,6 +18,7 @@
#include "utils/list.h" #include "utils/list.h"
#include "ap_config.h" #include "ap_config.h"
#include "drivers/driver.h" #include "drivers/driver.h"
#include "ubus.h"
#define OCE_STA_CFON_ENABLED(hapd) \ #define OCE_STA_CFON_ENABLED(hapd) \
((hapd->conf->oce & OCE_STA_CFON) && \ ((hapd->conf->oce & OCE_STA_CFON) && \
@ -97,8 +98,6 @@ struct hapd_interfaces {
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
struct hostapd_mld **mld; struct hostapd_mld **mld;
size_t mld_count; size_t mld_count;
int (*mld_ctrl_iface_init)(struct hostapd_mld *mld);
void (*mld_ctrl_iface_deinit)(struct hostapd_mld *mld);
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
}; };
@ -169,21 +168,23 @@ struct hostapd_sae_commit_queue {
u8 msg[]; u8 msg[];
}; };
struct mld_link_info { /**
u8 valid:1; * struct hostapd_liminix_stats - Liminix custom STA/AP statistics
u8 nstr_bitmap_len:2; * Inspired from the OpenWRT patch of David Bauer.
u8 local_addr[ETH_ALEN]; */
u8 peer_addr[ETH_ALEN]; struct hostapd_liminix_stats {
struct {
u64 neighbor_report_tx;
} rrm;
u8 nstr_bitmap[2]; struct {
u64 bss_transition_query_rx;
u16 capability; u64 bss_transition_request_tx;
u64 bss_transition_response_rx;
u16 status; } wnm;
u16 resp_sta_profile_len;
u8 *resp_sta_profile;
}; };
/** /**
* struct hostapd_data - hostapd per-BSS data structure * struct hostapd_data - hostapd per-BSS data structure
*/ */
@ -191,6 +192,7 @@ struct hostapd_data {
struct hostapd_iface *iface; struct hostapd_iface *iface;
struct hostapd_config *iconf; struct hostapd_config *iconf;
struct hostapd_bss_config *conf; struct hostapd_bss_config *conf;
struct hostapd_ubus_bss ubus;
int interface_added; /* virtual interface added for this BSS */ int interface_added; /* virtual interface added for this BSS */
unsigned int started:1; unsigned int started:1;
unsigned int disabled:1; unsigned int disabled:1;
@ -198,6 +200,9 @@ struct hostapd_data {
u8 own_addr[ETH_ALEN]; u8 own_addr[ETH_ALEN];
/* Liminix specific statistics */
struct hostapd_liminix_stats liminix_stats;
int num_sta; /* number of entries in sta_list */ int num_sta; /* number of entries in sta_list */
struct sta_info *sta_list; /* STA info list head */ struct sta_info *sta_list; /* STA info list head */
#define STA_HASH_SIZE 256 #define STA_HASH_SIZE 256
@ -493,14 +498,6 @@ struct hostapd_data {
struct hostapd_mld *mld; struct hostapd_mld *mld;
struct dl_list link; struct dl_list link;
u8 mld_link_id; u8 mld_link_id;
/* Cached partner info for ML probe response */
struct mld_link_info partner_links[MAX_NUM_MLD_LINKS];
/* 5 characters for "_link", up to 2 characters for <link ID>, so in
* total, additional 7 characters required. */
char ctrl_sock_iface[IFNAMSIZ + 7 + 1];
#ifdef CONFIG_TESTING_OPTIONS #ifdef CONFIG_TESTING_OPTIONS
u8 eht_mld_link_removal_count; u8 eht_mld_link_removal_count;
#endif /* CONFIG_TESTING_OPTIONS */ #endif /* CONFIG_TESTING_OPTIONS */
@ -543,10 +540,6 @@ struct hostapd_mld {
struct hostapd_data *fbss; struct hostapd_data *fbss;
struct dl_list links; /* List head of all affiliated links */ struct dl_list links; /* List head of all affiliated links */
int ctrl_sock;
struct dl_list ctrl_dst;
char *ctrl_interface; /* Directory for UNIX domain sockets */
}; };
#define HOSTAPD_MLD_MAX_REF_COUNT 0xFF #define HOSTAPD_MLD_MAX_REF_COUNT 0xFF
@ -740,10 +733,6 @@ struct hostapd_iface {
bool is_no_ir; bool is_no_ir;
bool is_ch_switch_dfs; /* Channel switch from ACS to DFS */ bool is_ch_switch_dfs; /* Channel switch from ACS to DFS */
struct hostapd_multi_hw_info *multi_hw_info;
unsigned int num_multi_hws;
struct hostapd_multi_hw_info *current_hw_info;
}; };
/* hostapd.c */ /* hostapd.c */
@ -758,6 +747,7 @@ hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface,
struct hostapd_bss_config *bss); struct hostapd_bss_config *bss);
int hostapd_setup_interface(struct hostapd_iface *iface); int hostapd_setup_interface(struct hostapd_iface *iface);
int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err); int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err);
void hostapd_set_own_neighbor_report(struct hostapd_data *hapd);
void hostapd_interface_deinit(struct hostapd_iface *iface); void hostapd_interface_deinit(struct hostapd_iface *iface);
void hostapd_interface_free(struct hostapd_iface *iface); void hostapd_interface_free(struct hostapd_iface *iface);
struct hostapd_iface * hostapd_alloc_iface(void); struct hostapd_iface * hostapd_alloc_iface(void);
@ -786,8 +776,6 @@ void hostapd_chan_switch_config(struct hostapd_data *hapd,
struct hostapd_freq_params *freq_params); struct hostapd_freq_params *freq_params);
int hostapd_switch_channel(struct hostapd_data *hapd, int hostapd_switch_channel(struct hostapd_data *hapd,
struct csa_settings *settings); struct csa_settings *settings);
int hostapd_force_channel_switch(struct hostapd_iface *iface,
struct csa_settings settings);
void void
hostapd_switch_channel_fallback(struct hostapd_iface *iface, hostapd_switch_channel_fallback(struct hostapd_iface *iface,
const struct hostapd_freq_params *freq_params); const struct hostapd_freq_params *freq_params);
@ -866,7 +854,6 @@ int hostapd_fill_cca_settings(struct hostapd_data *hapd,
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
bool hostapd_mld_is_first_bss(struct hostapd_data *hapd); bool hostapd_mld_is_first_bss(struct hostapd_data *hapd);
void hostapd_mld_interface_freed(struct hostapd_data *hapd);
#define for_each_mld_link(partner, self) \ #define for_each_mld_link(partner, self) \
dl_list_for_each(partner, &self->mld->links, struct hostapd_data, link) dl_list_for_each(partner, &self->mld->links, struct hostapd_data, link)

View file

@ -76,15 +76,12 @@ int hostapd_get_hw_features(struct hostapd_iface *iface)
{ {
struct hostapd_data *hapd = iface->bss[0]; struct hostapd_data *hapd = iface->bss[0];
int i, j; int i, j;
unsigned int k;
u16 num_modes, flags; u16 num_modes, flags;
struct hostapd_hw_modes *modes; struct hostapd_hw_modes *modes;
u8 dfs_domain; u8 dfs_domain;
enum hostapd_hw_mode mode = HOSTAPD_MODE_IEEE80211ANY; enum hostapd_hw_mode mode = HOSTAPD_MODE_IEEE80211ANY;
bool is_6ghz = false; bool is_6ghz = false;
bool orig_mode_valid = false; bool orig_mode_valid = false;
struct hostapd_multi_hw_info *multi_hw_info;
unsigned int num_multi_hws;
if (hostapd_drv_none(hapd)) if (hostapd_drv_none(hapd))
return -1; return -1;
@ -171,25 +168,6 @@ int hostapd_get_hw_features(struct hostapd_iface *iface)
__func__); __func__);
} }
multi_hw_info = hostapd_get_multi_hw_info(hapd, &num_multi_hws);
if (!multi_hw_info)
return 0;
hostapd_free_multi_hw_info(iface->multi_hw_info);
iface->multi_hw_info = multi_hw_info;
iface->num_multi_hws = num_multi_hws;
wpa_printf(MSG_DEBUG, "Multiple underlying hardwares info:");
for (k = 0; k < num_multi_hws; k++) {
struct hostapd_multi_hw_info *hw_info = &multi_hw_info[k];
wpa_printf(MSG_DEBUG,
" %d. hw_idx=%u, frequency range: %d-%d MHz",
k + 1, hw_info->hw_idx, hw_info->start_freq,
hw_info->end_freq);
}
return 0; return 0;
} }
@ -1413,34 +1391,3 @@ int hostapd_hw_skip_mode(struct hostapd_iface *iface,
} }
return 0; return 0;
} }
void hostapd_free_multi_hw_info(struct hostapd_multi_hw_info *multi_hw_info)
{
os_free(multi_hw_info);
}
int hostapd_set_current_hw_info(struct hostapd_iface *iface, int oper_freq)
{
struct hostapd_multi_hw_info *hw_info;
unsigned int i;
if (!iface->num_multi_hws)
return 0;
for (i = 0; i < iface->num_multi_hws; i++) {
hw_info = &iface->multi_hw_info[i];
if (hw_info->start_freq <= oper_freq &&
hw_info->end_freq >= oper_freq) {
iface->current_hw_info = hw_info;
wpa_printf(MSG_DEBUG,
"Mode: Selected underlying hardware: hw_idx=%u",
iface->current_hw_info->hw_idx);
return 0;
}
}
return -1;
}

View file

@ -30,8 +30,6 @@ void hostapd_stop_setup_timers(struct hostapd_iface *iface);
int hostapd_hw_skip_mode(struct hostapd_iface *iface, int hostapd_hw_skip_mode(struct hostapd_iface *iface,
struct hostapd_hw_modes *mode); struct hostapd_hw_modes *mode);
int hostapd_determine_mode(struct hostapd_iface *iface); int hostapd_determine_mode(struct hostapd_iface *iface);
void hostapd_free_multi_hw_info(struct hostapd_multi_hw_info *multi_hw_info);
int hostapd_set_current_hw_info(struct hostapd_iface *iface, int oper_freq);
#else /* NEED_AP_MLME */ #else /* NEED_AP_MLME */
static inline void static inline void
hostapd_free_hw_features(struct hostapd_hw_modes *hw_features, hostapd_free_hw_features(struct hostapd_hw_modes *hw_features,
@ -105,16 +103,6 @@ static inline int hostapd_determine_mode(struct hostapd_iface *iface)
return 0; return 0;
} }
static inline
void hostapd_free_multi_hw_info(struct hostapd_multi_hw_info *multi_hw_info)
{
}
static inline int hostapd_set_current_hw_info(struct hostapd_iface *iface,
u32 oper_freq)
{
return 0;
}
#endif /* NEED_AP_MLME */ #endif /* NEED_AP_MLME */
#endif /* HW_FEATURES_H */ #endif /* HW_FEATURES_H */

View file

@ -1173,23 +1173,16 @@ static int sae_sm_step(struct hostapd_data *hapd, struct sta_info *sta,
static void sae_pick_next_group(struct hostapd_data *hapd, struct sta_info *sta) static void sae_pick_next_group(struct hostapd_data *hapd, struct sta_info *sta)
{ {
struct sae_data *sae = sta->sae; struct sae_data *sae = sta->sae;
struct hostapd_bss_config *conf = hapd->conf; int i, *groups = hapd->conf->sae_groups;
int i, *groups = conf->sae_groups; int default_groups[] = { 19, 0 };
int default_groups[] = { 19, 0, 0 };
if (sae->state != SAE_COMMITTED) if (sae->state != SAE_COMMITTED)
return; return;
wpa_printf(MSG_DEBUG, "SAE: Previously selected group: %d", sae->group); wpa_printf(MSG_DEBUG, "SAE: Previously selected group: %d", sae->group);
if (!groups) { if (!groups)
groups = default_groups; groups = default_groups;
if (wpa_key_mgmt_sae_ext_key(conf->wpa_key_mgmt |
conf->rsn_override_key_mgmt |
conf->rsn_override_key_mgmt_2))
default_groups[1] = 20;
}
for (i = 0; groups[i] > 0; i++) { for (i = 0; groups[i] > 0; i++) {
if (sae->group == groups[i]) if (sae->group == groups[i])
break; break;
@ -1254,18 +1247,12 @@ static int sae_status_success(struct hostapd_data *hapd, u16 status_code)
static int sae_is_group_enabled(struct hostapd_data *hapd, int group) static int sae_is_group_enabled(struct hostapd_data *hapd, int group)
{ {
struct hostapd_bss_config *conf = hapd->conf; int *groups = hapd->conf->sae_groups;
int *groups = conf->sae_groups; int default_groups[] = { 19, 0 };
int default_groups[] = { 19, 0, 0 };
int i; int i;
if (!groups) { if (!groups)
groups = default_groups; groups = default_groups;
if (wpa_key_mgmt_sae_ext_key(conf->wpa_key_mgmt |
conf->rsn_override_key_mgmt |
conf->rsn_override_key_mgmt_2))
default_groups[1] = 20;
}
for (i = 0; groups[i] > 0; i++) { for (i = 0; groups[i] > 0; i++) {
if (groups[i] == group) if (groups[i] == group)
@ -1322,20 +1309,14 @@ static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
{ {
int resp = WLAN_STATUS_SUCCESS; int resp = WLAN_STATUS_SUCCESS;
struct wpabuf *data = NULL; struct wpabuf *data = NULL;
struct hostapd_bss_config *conf = hapd->conf; int *groups = hapd->conf->sae_groups;
int *groups = conf->sae_groups; int default_groups[] = { 19, 0 };
int default_groups[] = { 19, 0, 0 };
const u8 *pos, *end; const u8 *pos, *end;
int sta_removed = 0; int sta_removed = 0;
bool success_status; bool success_status;
if (!groups) { if (!groups)
groups = default_groups; groups = default_groups;
if (wpa_key_mgmt_sae_ext_key(conf->wpa_key_mgmt |
conf->rsn_override_key_mgmt |
conf->rsn_override_key_mgmt_2))
default_groups[1] = 20;
}
#ifdef CONFIG_TESTING_OPTIONS #ifdef CONFIG_TESTING_OPTIONS
if (hapd->conf->sae_reflection_attack && auth_transaction == 1) { if (hapd->conf->sae_reflection_attack && auth_transaction == 1) {
@ -1628,12 +1609,12 @@ reply:
!data && end - pos >= 2) !data && end - pos >= 2)
data = wpabuf_alloc_copy(pos, 2); data = wpabuf_alloc_copy(pos, 2);
sae_sme_send_external_auth_status(hapd, sta, resp);
send_auth_reply(hapd, sta, sta->addr, send_auth_reply(hapd, sta, sta->addr,
WLAN_AUTH_SAE, WLAN_AUTH_SAE,
auth_transaction, resp, auth_transaction, resp,
data ? wpabuf_head(data) : (u8 *) "", data ? wpabuf_head(data) : (u8 *) "",
data ? wpabuf_len(data) : 0, "auth-sae"); data ? wpabuf_len(data) : 0, "auth-sae");
sae_sme_send_external_auth_status(hapd, sta, resp);
if (sta->sae && sta->sae->tmp && sta->sae->tmp->pw_id && if (sta->sae && sta->sae->tmp && sta->sae->tmp->pw_id &&
resp == WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER && resp == WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER &&
auth_transaction == 1) { auth_transaction == 1) {
@ -1954,8 +1935,6 @@ void handle_auth_fils(struct hostapd_data *hapd, struct sta_info *sta,
goto fail; goto fail;
} }
wpa_auth_set_rsn_selection(sta->wpa_sm, elems.rsn_selection,
elems.rsn_selection_len);
res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
hapd->iface->freq, hapd->iface->freq,
elems.rsn_ie - 2, elems.rsn_ie_len + 2, elems.rsn_ie - 2, elems.rsn_ie_len + 2,
@ -2850,7 +2829,7 @@ static void handle_auth_pasn(struct hostapd_data *hapd, struct sta_info *sta,
hapd_pasn_update_params(hapd, sta, mgmt, len); hapd_pasn_update_params(hapd, sta, mgmt, len);
if (handle_auth_pasn_1(sta->pasn, hapd->own_addr, if (handle_auth_pasn_1(sta->pasn, hapd->own_addr,
sta->addr, mgmt, len, false) < 0) sta->addr, mgmt, len) < 0)
ap_free_sta(hapd, sta); ap_free_sta(hapd, sta);
} else if (trans_seq == 3) { } else if (trans_seq == 3) {
if (!sta->pasn) { if (!sta->pasn) {
@ -2895,7 +2874,7 @@ static void handle_auth(struct hostapd_data *hapd,
u16 auth_alg, auth_transaction, status_code; u16 auth_alg, auth_transaction, status_code;
u16 resp = WLAN_STATUS_SUCCESS; u16 resp = WLAN_STATUS_SUCCESS;
struct sta_info *sta = NULL; struct sta_info *sta = NULL;
int res, reply_res; int res, reply_res, ubus_resp;
u16 fc; u16 fc;
const u8 *challenge = NULL; const u8 *challenge = NULL;
u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN]; u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
@ -2907,6 +2886,12 @@ static void handle_auth(struct hostapd_data *hapd,
bool mld_sta = false; bool mld_sta = false;
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
struct hostapd_ubus_request req = {
.type = HOSTAPD_UBUS_AUTH_REQ,
.mgmt_frame = mgmt,
.ssi_signal = rssi,
};
if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) { if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)", wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
(unsigned long) len); (unsigned long) len);
@ -2982,10 +2967,7 @@ static void handle_auth(struct hostapd_data *hapd,
auth_alg == WLAN_AUTH_FT) || auth_alg == WLAN_AUTH_FT) ||
#endif /* CONFIG_IEEE80211R_AP */ #endif /* CONFIG_IEEE80211R_AP */
#ifdef CONFIG_SAE #ifdef CONFIG_SAE
(hapd->conf->wpa && (hapd->conf->wpa && wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) &&
wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt |
hapd->conf->rsn_override_key_mgmt |
hapd->conf->rsn_override_key_mgmt_2) &&
auth_alg == WLAN_AUTH_SAE) || auth_alg == WLAN_AUTH_SAE) ||
#endif /* CONFIG_SAE */ #endif /* CONFIG_SAE */
#ifdef CONFIG_FILS #ifdef CONFIG_FILS
@ -3026,6 +3008,14 @@ static void handle_auth(struct hostapd_data *hapd,
goto fail; goto fail;
} }
ubus_resp = hostapd_ubus_handle_event(hapd, &req);
if (ubus_resp) {
wpa_printf(MSG_DEBUG, "Station " MACSTR " rejected by ubus handler.\n",
MAC2STR(mgmt->sa));
resp = ubus_resp > 0 ? (u16) ubus_resp : WLAN_STATUS_UNSPECIFIED_FAILURE;
goto fail;
}
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
if (mld_sta && if (mld_sta &&
(ether_addr_equal(sa, hapd->own_addr) || (ether_addr_equal(sa, hapd->own_addr) ||
@ -4152,8 +4142,6 @@ static int __check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
wpa_auth_set_auth_alg(sta->wpa_sm, sta->auth_alg); wpa_auth_set_auth_alg(sta->wpa_sm, sta->auth_alg);
wpa_auth_set_rsn_selection(sta->wpa_sm, elems->rsn_selection,
elems->rsn_selection_len);
res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
hapd->iface->freq, hapd->iface->freq,
wpa_ie, wpa_ie_len, wpa_ie, wpa_ie_len,
@ -5014,8 +5002,7 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
#endif /* CONFIG_IEEE80211AX */ #endif /* CONFIG_IEEE80211AX */
p = hostapd_eid_ext_capab(hapd, p, false); p = hostapd_eid_ext_capab(hapd, p, false);
p = hostapd_eid_bss_max_idle_period(hapd, p, p = hostapd_eid_bss_max_idle_period(hapd, p, sta->max_idle_period);
sta ? sta->max_idle_period : 0);
if (sta && sta->qos_map_enabled) if (sta && sta->qos_map_enabled)
p = hostapd_eid_qos_map_set(hapd, p); p = hostapd_eid_qos_map_set(hapd, p);
@ -5357,7 +5344,7 @@ static void handle_assoc(struct hostapd_data *hapd,
int resp = WLAN_STATUS_SUCCESS; int resp = WLAN_STATUS_SUCCESS;
u16 reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE; u16 reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE;
const u8 *pos; const u8 *pos;
int left, i; int left, i, ubus_resp;
struct sta_info *sta; struct sta_info *sta;
u8 *tmp = NULL; u8 *tmp = NULL;
#ifdef CONFIG_FILS #ifdef CONFIG_FILS
@ -5600,6 +5587,12 @@ static void handle_assoc(struct hostapd_data *hapd,
} }
#endif /* CONFIG_FILS */ #endif /* CONFIG_FILS */
struct hostapd_ubus_request req = {
.type = HOSTAPD_UBUS_ASSOC_REQ,
.mgmt_frame = mgmt,
.ssi_signal = rssi,
};
/* followed by SSID and Supported rates; and HT capabilities if 802.11n /* followed by SSID and Supported rates; and HT capabilities if 802.11n
* is used */ * is used */
resp = check_assoc_ies(hapd, sta, pos, left, reassoc); resp = check_assoc_ies(hapd, sta, pos, left, reassoc);
@ -5701,6 +5694,14 @@ static void handle_assoc(struct hostapd_data *hapd,
if (set_beacon) if (set_beacon)
ieee802_11_update_beacons(hapd->iface); ieee802_11_update_beacons(hapd->iface);
ubus_resp = hostapd_ubus_handle_event(hapd, &req);
if (ubus_resp) {
wpa_printf(MSG_DEBUG, "Station " MACSTR " assoc rejected by ubus handler.\n",
MAC2STR(mgmt->sa));
resp = ubus_resp > 0 ? (u16) ubus_resp : WLAN_STATUS_UNSPECIFIED_FAILURE;
goto fail;
}
fail: fail:
/* /*
@ -5930,6 +5931,7 @@ static void handle_disassoc(struct hostapd_data *hapd,
(unsigned long) len); (unsigned long) len);
return; return;
} }
hostapd_ubus_notify(hapd, "disassoc", mgmt->sa);
sta = ap_get_sta(hapd, mgmt->sa); sta = ap_get_sta(hapd, mgmt->sa);
if (!sta) { if (!sta) {
@ -5958,6 +5960,8 @@ static void handle_deauth(struct hostapd_data *hapd,
return; return;
} }
hostapd_ubus_notify(hapd, "deauth", mgmt->sa);
/* Clear the PTKSA cache entries for PASN */ /* Clear the PTKSA cache entries for PASN */
ptksa_cache_flush(hapd->ptksa, mgmt->sa, WPA_CIPHER_NONE); ptksa_cache_flush(hapd->ptksa, mgmt->sa, WPA_CIPHER_NONE);
@ -7247,11 +7251,16 @@ u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid)
} }
/* Wide Bandwidth Channel Switch subelement */ u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid)
static u8 * hostapd_eid_wb_channel_switch(struct hostapd_data *hapd, u8 *eid,
u8 chan1, u8 chan2)
{ {
u8 bw; u8 bw, chan1 = 0, chan2 = 0;
int freq1;
if (!hapd->cs_freq_params.channel ||
(!hapd->cs_freq_params.vht_enabled &&
!hapd->cs_freq_params.he_enabled &&
!hapd->cs_freq_params.eht_enabled))
return eid;
/* bandwidth: 0: 40, 1: 80, 160, 80+80, 4: 320 as per /* bandwidth: 0: 40, 1: 80, 160, 80+80, 4: 320 as per
* IEEE P802.11-REVme/D4.0, 9.4.2.159 and Table 9-314. */ * IEEE P802.11-REVme/D4.0, 9.4.2.159 and Table 9-314. */
@ -7273,6 +7282,20 @@ static u8 * hostapd_eid_wb_channel_switch(struct hostapd_data *hapd, u8 *eid,
return eid; return eid;
} }
freq1 = hapd->cs_freq_params.center_freq1 ?
hapd->cs_freq_params.center_freq1 :
hapd->cs_freq_params.freq;
if (ieee80211_freq_to_chan(freq1, &chan1) !=
HOSTAPD_MODE_IEEE80211A)
return eid;
if (hapd->cs_freq_params.center_freq2 &&
ieee80211_freq_to_chan(hapd->cs_freq_params.center_freq2,
&chan2) != HOSTAPD_MODE_IEEE80211A)
return eid;
*eid++ = WLAN_EID_CHANNEL_SWITCH_WRAPPER;
*eid++ = 5; /* Length of Channel Switch Wrapper */
*eid++ = WLAN_EID_WIDE_BW_CHSWITCH; *eid++ = WLAN_EID_WIDE_BW_CHSWITCH;
*eid++ = 3; /* Length of Wide Bandwidth Channel Switch element */ *eid++ = 3; /* Length of Wide Bandwidth Channel Switch element */
*eid++ = bw; /* New Channel Width */ *eid++ = bw; /* New Channel Width */
@ -7298,118 +7321,6 @@ static u8 * hostapd_eid_wb_channel_switch(struct hostapd_data *hapd, u8 *eid,
} }
#ifdef CONFIG_IEEE80211BE
/* Bandwidth Indication element that is also used as the Bandwidth Indication
* For Channel Switch subelement within a Channel Switch Wrapper element. */
static u8 * hostapd_eid_bw_indication(struct hostapd_data *hapd, u8 *eid,
u8 chan1, u8 chan2)
{
u16 punct_bitmap = hostapd_get_punct_bitmap(hapd);
struct ieee80211_bw_ind_element *bw_ind_elem;
size_t elen = 3;
if (hapd->cs_freq_params.bandwidth <= 160 && !punct_bitmap)
return eid;
if (punct_bitmap)
elen += EHT_OPER_DISABLED_SUBCHAN_BITMAP_SIZE;
*eid++ = WLAN_EID_EXTENSION;
*eid++ = 1 + elen;
*eid++ = WLAN_EID_EXT_BANDWIDTH_INDICATION;
bw_ind_elem = (struct ieee80211_bw_ind_element *) eid;
os_memset(bw_ind_elem, 0, sizeof(struct ieee80211_bw_ind_element));
switch (hapd->cs_freq_params.bandwidth) {
case 320:
bw_ind_elem->bw_ind_info.control |= BW_IND_CHANNEL_WIDTH_320MHZ;
chan2 = chan1;
if (hapd->cs_freq_params.channel < chan1)
chan1 -= 16;
else
chan1 += 16;
break;
case 160:
bw_ind_elem->bw_ind_info.control |= BW_IND_CHANNEL_WIDTH_160MHZ;
chan2 = chan1;
if (hapd->cs_freq_params.channel < chan1)
chan1 -= 8;
else
chan1 += 8;
break;
case 80:
bw_ind_elem->bw_ind_info.control |= BW_IND_CHANNEL_WIDTH_80MHZ;
break;
case 40:
if (hapd->cs_freq_params.sec_channel_offset == 1)
bw_ind_elem->bw_ind_info.control |=
BW_IND_CHANNEL_WIDTH_40MHZ;
else
bw_ind_elem->bw_ind_info.control |=
BW_IND_CHANNEL_WIDTH_20MHZ;
break;
default:
bw_ind_elem->bw_ind_info.control |= BW_IND_CHANNEL_WIDTH_20MHZ;
break;
}
bw_ind_elem->bw_ind_info.ccfs0 = chan1;
bw_ind_elem->bw_ind_info.ccfs1 = chan2;
if (punct_bitmap) {
bw_ind_elem->bw_ind_params |=
BW_IND_PARAMETER_DISABLED_SUBCHAN_BITMAP_PRESENT;
bw_ind_elem->bw_ind_info.disabled_chan_bitmap =
host_to_le16(punct_bitmap);
}
return eid + elen;
}
#endif /* CONFIG_IEEE80211BE */
u8 * hostapd_eid_chsw_wrapper(struct hostapd_data *hapd, u8 *eid)
{
u8 chan1 = 0, chan2 = 0;
u8 *eid_len_offset;
int freq1;
if (!hapd->cs_freq_params.channel ||
(!hapd->cs_freq_params.vht_enabled &&
!hapd->cs_freq_params.he_enabled &&
!hapd->cs_freq_params.eht_enabled))
return eid;
freq1 = hapd->cs_freq_params.center_freq1 ?
hapd->cs_freq_params.center_freq1 :
hapd->cs_freq_params.freq;
if (ieee80211_freq_to_chan(freq1, &chan1) !=
HOSTAPD_MODE_IEEE80211A)
return eid;
if (hapd->cs_freq_params.center_freq2 &&
ieee80211_freq_to_chan(hapd->cs_freq_params.center_freq2,
&chan2) != HOSTAPD_MODE_IEEE80211A)
return eid;
*eid++ = WLAN_EID_CHANNEL_SWITCH_WRAPPER;
eid_len_offset = eid++; /* Length of Channel Switch Wrapper element */
eid = hostapd_eid_wb_channel_switch(hapd, eid, chan1, chan2);
#ifdef CONFIG_IEEE80211BE
if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
/* Bandwidth Indication For Channel Switch subelement */
eid = hostapd_eid_bw_indication(hapd, eid, chan1, chan2);
}
#endif /* CONFIG_IEEE80211BE */
*eid_len_offset = (eid - eid_len_offset) - 1;
return eid;
}
static size_t hostapd_eid_nr_db_len(struct hostapd_data *hapd, static size_t hostapd_eid_nr_db_len(struct hostapd_data *hapd,
size_t *current_len) size_t *current_len)
{ {

View file

@ -63,7 +63,7 @@ u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid);
u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid, u32 nsts); u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid, u32 nsts);
u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid); u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid);
u8 * hostapd_eid_vendor_vht(struct hostapd_data *hapd, u8 *eid); u8 * hostapd_eid_vendor_vht(struct hostapd_data *hapd, u8 *eid);
u8 * hostapd_eid_chsw_wrapper(struct hostapd_data *hapd, u8 *eid); u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid);
u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid); u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid);
u8 * hostapd_eid_he_capab(struct hostapd_data *hapd, u8 *eid, u8 * hostapd_eid_he_capab(struct hostapd_data *hapd, u8 *eid,
enum ieee80211_op_mode opmode); enum ieee80211_op_mode opmode);

View file

@ -871,8 +871,6 @@ sae_commit_skip_fixed_fields(const struct ieee80211_mgmt *mgmt, size_t len,
wpa_printf(MSG_DEBUG, "EHT: SAE scalar length is %zu", prime_len); wpa_printf(MSG_DEBUG, "EHT: SAE scalar length is %zu", prime_len);
if (len - 2 < prime_len * (ec ? 3 : 2))
goto truncated;
/* scalar */ /* scalar */
pos += prime_len; pos += prime_len;
@ -884,7 +882,6 @@ sae_commit_skip_fixed_fields(const struct ieee80211_mgmt *mgmt, size_t len,
} }
if (pos - mgmt->u.auth.variable > (int) len) { if (pos - mgmt->u.auth.variable > (int) len) {
truncated:
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"EHT: Too short SAE commit Authentication frame"); "EHT: Too short SAE commit Authentication frame");
return NULL; return NULL;
@ -908,37 +905,15 @@ sae_confirm_skip_fixed_fields(struct hostapd_data *hapd,
return pos; return pos;
/* send confirm integer */ /* send confirm integer */
if (len < 2)
goto truncated;
pos += 2; pos += 2;
/* /*
* At this stage we should already have an MLD station and actually SA * At this stage we should already have an MLD station and actually SA
* will be replaced with the MLD MAC address by the driver. However, * will be replaced with the MLD MAC address by the driver.
* there is at least a theoretical race condition in a case where the
* peer sends the SAE confirm message quickly enough for the driver
* translation mechanism to not be available to update the SAE confirm
* message addresses. Work around that by searching for the STA entry
* using the link address of the non-AP MLD if no match is found based
* on the MLD MAC address.
*/ */
sta = ap_get_sta(hapd, mgmt->sa); sta = ap_get_sta(hapd, mgmt->sa);
if (!sta) { if (!sta) {
wpa_printf(MSG_DEBUG, "SAE: No MLD STA for SAE confirm"); wpa_printf(MSG_DEBUG, "SAE: No MLD STA for SAE confirm");
for (sta = hapd->sta_list; sta; sta = sta->next) {
int link_id = hapd->mld_link_id;
if (!sta->mld_info.mld_sta ||
sta->mld_info.links[link_id].valid ||
!ether_addr_equal(
mgmt->sa,
sta->mld_info.links[link_id].peer_addr))
continue;
wpa_printf(MSG_DEBUG,
"SAE: Found MLD STA for SAE confirm based on link address");
break;
}
if (!sta)
return NULL; return NULL;
} }
@ -954,12 +929,9 @@ sae_confirm_skip_fixed_fields(struct hostapd_data *hapd,
wpa_printf(MSG_DEBUG, "SAE: confirm: kck_len=%zu", wpa_printf(MSG_DEBUG, "SAE: confirm: kck_len=%zu",
sta->sae->tmp->kck_len); sta->sae->tmp->kck_len);
if (len - 2 < sta->sae->tmp->kck_len)
goto truncated;
pos += sta->sae->tmp->kck_len; pos += sta->sae->tmp->kck_len;
if (pos - mgmt->u.auth.variable > (int) len) { if (pos - mgmt->u.auth.variable > (int) len) {
truncated:
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"EHT: Too short SAE confirm Authentication frame"); "EHT: Too short SAE confirm Authentication frame");
return NULL; return NULL;

View file

@ -79,51 +79,6 @@ u8 * hostapd_eid_ht_capabilities(struct hostapd_data *hapd, u8 *eid)
} }
static void set_ht_param(struct hostapd_data *hapd,
struct ieee80211_ht_operation *oper)
{
int secondary_channel = hapd->iconf->secondary_channel;
#ifdef CONFIG_IEEE80211BE
enum oper_chan_width chwidth = hostapd_get_oper_chwidth(hapd->iconf);
u16 bw = 0, punct_bitmap = hostapd_get_punct_bitmap(hapd);
u8 offset, chan_bit_pos;
switch (chwidth) {
case CONF_OPER_CHWIDTH_80MHZ:
bw = 80;
offset = 6;
break;
case CONF_OPER_CHWIDTH_160MHZ:
bw = 160;
offset = 14;
break;
case CONF_OPER_CHWIDTH_320MHZ:
bw = 320;
offset = 30;
break;
default:
goto no_update;
}
chan_bit_pos = (hapd->iconf->channel -
hostapd_get_oper_centr_freq_seg0_idx(hapd->iconf) +
offset) / 4;
/* Check if secondary channel is punctured */
if (bw >= 80 && punct_bitmap && secondary_channel &&
(punct_bitmap & BIT(chan_bit_pos + secondary_channel)))
return; /* Do not indicate punctured secondary channel for HT */
no_update:
#endif /* CONFIG_IEEE80211BE */
if (secondary_channel == 1)
oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE |
HT_INFO_HT_PARAM_STA_CHNL_WIDTH;
if (secondary_channel == -1)
oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW |
HT_INFO_HT_PARAM_STA_CHNL_WIDTH;
}
u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid) u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid)
{ {
struct ieee80211_ht_operation *oper; struct ieee80211_ht_operation *oper;
@ -141,7 +96,12 @@ u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid)
oper->primary_chan = hapd->iconf->channel; oper->primary_chan = hapd->iconf->channel;
oper->operation_mode = host_to_le16(hapd->iface->ht_op_mode); oper->operation_mode = host_to_le16(hapd->iface->ht_op_mode);
set_ht_param(hapd, oper); if (hapd->iconf->secondary_channel == 1)
oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE |
HT_INFO_HT_PARAM_STA_CHNL_WIDTH;
if (hapd->iconf->secondary_channel == -1)
oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW |
HT_INFO_HT_PARAM_STA_CHNL_WIDTH;
pos += sizeof(*oper); pos += sizeof(*oper);

View file

@ -158,7 +158,7 @@ int hostapd_nan_usd_init(struct hostapd_data *hapd)
cb.subscribe_terminated = hostapd_nan_de_subscribe_terminated; cb.subscribe_terminated = hostapd_nan_de_subscribe_terminated;
cb.receive = hostapd_nan_de_receive; cb.receive = hostapd_nan_de_receive;
hapd->nan_de = nan_de_init(hapd->own_addr, false, true, &cb); hapd->nan_de = nan_de_init(hapd->own_addr, true, &cb);
if (!hapd->nan_de) if (!hapd->nan_de)
return -1; return -1;
return 0; return 0;
@ -192,7 +192,7 @@ void hostapd_nan_usd_flush(struct hostapd_data *hapd)
int hostapd_nan_usd_publish(struct hostapd_data *hapd, const char *service_name, int hostapd_nan_usd_publish(struct hostapd_data *hapd, const char *service_name,
enum nan_service_protocol_type srv_proto_type, enum nan_service_protocol_type srv_proto_type,
const struct wpabuf *ssi, const struct wpabuf *ssi,
struct nan_publish_params *params, bool p2p) struct nan_publish_params *params)
{ {
int publish_id; int publish_id;
struct wpabuf *elems = NULL; struct wpabuf *elems = NULL;
@ -201,7 +201,7 @@ int hostapd_nan_usd_publish(struct hostapd_data *hapd, const char *service_name,
return -1; return -1;
publish_id = nan_de_publish(hapd->nan_de, service_name, srv_proto_type, publish_id = nan_de_publish(hapd->nan_de, service_name, srv_proto_type,
ssi, elems, params, p2p); ssi, elems, params);
wpabuf_free(elems); wpabuf_free(elems);
return publish_id; return publish_id;
} }
@ -231,7 +231,7 @@ int hostapd_nan_usd_subscribe(struct hostapd_data *hapd,
const char *service_name, const char *service_name,
enum nan_service_protocol_type srv_proto_type, enum nan_service_protocol_type srv_proto_type,
const struct wpabuf *ssi, const struct wpabuf *ssi,
struct nan_subscribe_params *params, bool p2p) struct nan_subscribe_params *params)
{ {
int subscribe_id; int subscribe_id;
struct wpabuf *elems = NULL; struct wpabuf *elems = NULL;
@ -240,7 +240,7 @@ int hostapd_nan_usd_subscribe(struct hostapd_data *hapd,
return -1; return -1;
subscribe_id = nan_de_subscribe(hapd->nan_de, service_name, subscribe_id = nan_de_subscribe(hapd->nan_de, service_name,
srv_proto_type, ssi, elems, params, p2p); srv_proto_type, ssi, elems, params);
wpabuf_free(elems); wpabuf_free(elems);
return subscribe_id; return subscribe_id;
} }

View file

@ -21,7 +21,7 @@ void hostapd_nan_usd_flush(struct hostapd_data *hapd);
int hostapd_nan_usd_publish(struct hostapd_data *hapd, const char *service_name, int hostapd_nan_usd_publish(struct hostapd_data *hapd, const char *service_name,
enum nan_service_protocol_type srv_proto_type, enum nan_service_protocol_type srv_proto_type,
const struct wpabuf *ssi, const struct wpabuf *ssi,
struct nan_publish_params *params, bool p2p); struct nan_publish_params *params);
void hostapd_nan_usd_cancel_publish(struct hostapd_data *hapd, int publish_id); void hostapd_nan_usd_cancel_publish(struct hostapd_data *hapd, int publish_id);
int hostapd_nan_usd_update_publish(struct hostapd_data *hapd, int publish_id, int hostapd_nan_usd_update_publish(struct hostapd_data *hapd, int publish_id,
const struct wpabuf *ssi); const struct wpabuf *ssi);
@ -29,7 +29,7 @@ int hostapd_nan_usd_subscribe(struct hostapd_data *hapd,
const char *service_name, const char *service_name,
enum nan_service_protocol_type srv_proto_type, enum nan_service_protocol_type srv_proto_type,
const struct wpabuf *ssi, const struct wpabuf *ssi,
struct nan_subscribe_params *params, bool p2p); struct nan_subscribe_params *params);
void hostapd_nan_usd_cancel_subscribe(struct hostapd_data *hapd, void hostapd_nan_usd_cancel_subscribe(struct hostapd_data *hapd,
int subscribe_id); int subscribe_id);
int hostapd_nan_usd_transmit(struct hostapd_data *hapd, int handle, int hostapd_nan_usd_transmit(struct hostapd_data *hapd, int handle,

View file

@ -89,6 +89,9 @@ static void hostapd_handle_beacon_report(struct hostapd_data *hapd,
return; return;
wpa_msg(hapd->msg_ctx, MSG_INFO, BEACON_RESP_RX MACSTR " %u %02x %s", wpa_msg(hapd->msg_ctx, MSG_INFO, BEACON_RESP_RX MACSTR " %u %02x %s",
MAC2STR(addr), token, rep_mode, report); MAC2STR(addr), token, rep_mode, report);
if (len < sizeof(struct rrm_measurement_beacon_report))
return;
hostapd_ubus_notify_beacon_report(hapd, addr, token, rep_mode, (struct rrm_measurement_beacon_report*) pos, len);
} }
@ -269,6 +272,7 @@ static void hostapd_send_nei_report_resp(struct hostapd_data *hapd,
} }
} }
hapd->liminix_stats.rrm.neighbor_report_tx++;
hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr, hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr,
wpabuf_head(buf), wpabuf_len(buf)); wpabuf_head(buf), wpabuf_len(buf));
wpabuf_free(buf); wpabuf_free(buf);
@ -404,6 +408,7 @@ void hostapd_handle_radio_measurement(struct hostapd_data *hapd,
hostapd_handle_nei_report_req(hapd, buf, len); hostapd_handle_nei_report_req(hapd, buf, len);
break; break;
case WLAN_RRM_LINK_MEASUREMENT_REPORT: case WLAN_RRM_LINK_MEASUREMENT_REPORT:
hostapd_ubus_handle_link_measurement(hapd, buf, len);
hostapd_handle_link_mesr_report(hapd, buf, len); hostapd_handle_link_mesr_report(hapd, buf, len);
break; break;
default: default:

View file

@ -542,6 +542,7 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_INFO, "deauthenticated due to " HOSTAPD_LEVEL_INFO, "deauthenticated due to "
"local deauth request"); "local deauth request");
hostapd_ubus_notify(hapd, "local-deauth", sta->addr);
ap_free_sta(hapd, sta); ap_free_sta(hapd, sta);
return; return;
} }
@ -699,6 +700,7 @@ skip_poll:
mlme_deauthenticate_indication( mlme_deauthenticate_indication(
hapd, sta, hapd, sta,
WLAN_REASON_PREV_AUTH_NOT_VALID); WLAN_REASON_PREV_AUTH_NOT_VALID);
hostapd_ubus_notify(hapd, "inactive-deauth", sta->addr);
ap_free_sta(hapd, sta); ap_free_sta(hapd, sta);
break; break;
} }
@ -1524,15 +1526,28 @@ void ap_sta_set_authorized_event(struct hostapd_data *hapd,
os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(sta->addr)); os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(sta->addr));
if (authorized) { if (authorized) {
static const char * const auth_algs[] = {
[WLAN_AUTH_OPEN] = "open",
[WLAN_AUTH_SHARED_KEY] = "shared",
[WLAN_AUTH_FT] = "ft",
[WLAN_AUTH_SAE] = "sae",
[WLAN_AUTH_FILS_SK] = "fils-sk",
[WLAN_AUTH_FILS_SK_PFS] = "fils-sk-pfs",
[WLAN_AUTH_FILS_PK] = "fils-pk",
[WLAN_AUTH_PASN] = "pasn",
};
const char *auth_alg = NULL;
const u8 *dpp_pkhash; const u8 *dpp_pkhash;
const char *keyid; const char *keyid;
char dpp_pkhash_buf[100]; char dpp_pkhash_buf[100];
char keyid_buf[100]; char keyid_buf[100];
char ip_addr[100]; char ip_addr[100];
char alg_buf[100];
dpp_pkhash_buf[0] = '\0'; dpp_pkhash_buf[0] = '\0';
keyid_buf[0] = '\0'; keyid_buf[0] = '\0';
ip_addr[0] = '\0'; ip_addr[0] = '\0';
alg_buf[0] = '\0';
#ifdef CONFIG_P2P #ifdef CONFIG_P2P
if (wpa_auth_get_ip_addr(sta->wpa_sm, ip_addr_buf) == 0) { if (wpa_auth_get_ip_addr(sta->wpa_sm, ip_addr_buf) == 0) {
os_snprintf(ip_addr, sizeof(ip_addr), os_snprintf(ip_addr, sizeof(ip_addr),
@ -1543,6 +1558,13 @@ void ap_sta_set_authorized_event(struct hostapd_data *hapd,
} }
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */
if (sta->auth_alg < ARRAY_SIZE(auth_algs))
auth_alg = auth_algs[sta->auth_alg];
if (auth_alg)
os_snprintf(alg_buf, sizeof(alg_buf),
" auth_alg=%s", auth_alg);
keyid = ap_sta_wpa_get_keyid(hapd, sta); keyid = ap_sta_wpa_get_keyid(hapd, sta);
if (keyid) { if (keyid) {
os_snprintf(keyid_buf, sizeof(keyid_buf), os_snprintf(keyid_buf, sizeof(keyid_buf),
@ -1561,17 +1583,19 @@ void ap_sta_set_authorized_event(struct hostapd_data *hapd,
dpp_pkhash, SHA256_MAC_LEN); dpp_pkhash, SHA256_MAC_LEN);
} }
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s", hostapd_ubus_notify_authorized(hapd, sta, auth_alg);
buf, ip_addr, keyid_buf, dpp_pkhash_buf); wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s%s",
buf, ip_addr, keyid_buf, dpp_pkhash_buf, alg_buf);
if (hapd->msg_ctx_parent && if (hapd->msg_ctx_parent &&
hapd->msg_ctx_parent != hapd->msg_ctx) hapd->msg_ctx_parent != hapd->msg_ctx)
wpa_msg_no_global(hapd->msg_ctx_parent, MSG_INFO, wpa_msg_no_global(hapd->msg_ctx_parent, MSG_INFO,
AP_STA_CONNECTED "%s%s%s%s", AP_STA_CONNECTED "%s%s%s%s%s",
buf, ip_addr, keyid_buf, buf, ip_addr, keyid_buf,
dpp_pkhash_buf); dpp_pkhash_buf, alg_buf);
} else { } else {
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf); wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf);
hostapd_ubus_notify(hapd, "disassoc", sta->addr);
if (hapd->msg_ctx_parent && if (hapd->msg_ctx_parent &&
hapd->msg_ctx_parent != hapd->msg_ctx) hapd->msg_ctx_parent != hapd->msg_ctx)

View file

@ -81,7 +81,20 @@ struct mld_info {
u16 mld_capa; u16 mld_capa;
} common_info; } common_info;
struct mld_link_info links[MAX_NUM_MLD_LINKS]; struct mld_link_info {
u8 valid:1;
u8 nstr_bitmap_len:2;
u8 local_addr[ETH_ALEN];
u8 peer_addr[ETH_ALEN];
u8 nstr_bitmap[2];
u16 capability;
u16 status;
u16 resp_sta_profile_len;
u8 *resp_sta_profile;
} links[MAX_NUM_MLD_LINKS];
}; };
struct sta_info { struct sta_info {
@ -308,6 +321,7 @@ struct sta_info {
#endif /* CONFIG_TESTING_OPTIONS */ #endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_AIRTIME_POLICY #ifdef CONFIG_AIRTIME_POLICY
unsigned int airtime_weight; unsigned int airtime_weight;
unsigned int dyn_airtime_weight;
struct os_reltime backlogged_until; struct os_reltime backlogged_until;
#endif /* CONFIG_AIRTIME_POLICY */ #endif /* CONFIG_AIRTIME_POLICY */

2010
src/ap/ubus.c Normal file

File diff suppressed because it is too large Load diff

162
src/ap/ubus.h Normal file
View file

@ -0,0 +1,162 @@
/*
* hostapd / ubus support
* Copyright (c) 2013, Felix Fietkau <nbd@nbd.name>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#ifndef __HOSTAPD_UBUS_H
#define __HOSTAPD_UBUS_H
#include "sta_info.h"
enum hostapd_ubus_event_type {
HOSTAPD_UBUS_PROBE_REQ,
HOSTAPD_UBUS_AUTH_REQ,
HOSTAPD_UBUS_ASSOC_REQ,
HOSTAPD_UBUS_TYPE_MAX
};
struct hostapd_ubus_request {
enum hostapd_ubus_event_type type;
const struct ieee80211_mgmt *mgmt_frame;
const struct ieee802_11_elems *elems;
int ssi_signal; /* dBm */
const u8 *addr;
};
struct hostapd_iface;
struct hostapd_data;
struct hapd_interfaces;
struct rrm_measurement_beacon_report;
struct sta_info;
#ifdef UBUS_SUPPORT
#include <libubox/avl.h>
#include <libubus.h>
struct hostapd_ubus_bss {
struct ubus_object obj;
struct avl_tree banned;
int notify_response;
};
void hostapd_ubus_add_iface(struct hostapd_iface *iface);
void hostapd_ubus_free_iface(struct hostapd_iface *iface);
void hostapd_ubus_add_bss(struct hostapd_data *hapd);
void hostapd_ubus_free_bss(struct hostapd_data *hapd);
void hostapd_ubus_add_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan);
void hostapd_ubus_remove_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan);
int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req);
void hostapd_ubus_handle_link_measurement(struct hostapd_data *hapd, const u8 *data, size_t len);
void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *mac);
void hostapd_ubus_notify_beacon_report(struct hostapd_data *hapd,
const u8 *addr, u8 token, u8 rep_mode,
struct rrm_measurement_beacon_report *rep,
size_t len);
void hostapd_ubus_notify_radar_detected(struct hostapd_iface *iface, int frequency,
int chan_width, int cf1, int cf2);
void hostapd_ubus_notify_bss_transition_response(
struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 status_code,
u8 bss_termination_delay, const u8 *target_bssid,
const u8 *candidate_list, u16 candidate_list_len);
void hostapd_ubus_add(struct hapd_interfaces *interfaces);
void hostapd_ubus_free(struct hapd_interfaces *interfaces);
int hostapd_ubus_notify_bss_transition_query(
struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 reason,
const u8 *candidate_list, u16 candidate_list_len);
void hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta,
const char *auth_alg);
void hostapd_ubus_notify_readiness(struct hostapd_data *hapd);
#else
struct hostapd_ubus_bss {};
static inline void hostapd_ubus_add_iface(struct hostapd_iface *iface)
{
}
static inline void hostapd_ubus_free_iface(struct hostapd_iface *iface)
{
}
static inline void hostapd_ubus_add_bss(struct hostapd_data *hapd)
{
}
static inline void hostapd_ubus_free_bss(struct hostapd_data *hapd)
{
}
static inline void hostapd_ubus_add_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan)
{
}
static inline void hostapd_ubus_remove_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vlan)
{
}
static inline int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req)
{
return 0;
}
static inline void hostapd_ubus_handle_link_measurement(struct hostapd_data *hapd, const u8 *data, size_t len)
{
}
static inline void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *mac)
{
}
static inline void hostapd_ubus_notify_readiness(struct hostapd_data *hapd)
{
}
static inline void hostapd_ubus_notify_beacon_report(struct hostapd_data *hapd,
const u8 *addr, u8 token,
u8 rep_mode,
struct rrm_measurement_beacon_report *rep,
size_t len)
{
}
static inline void hostapd_ubus_notify_radar_detected(struct hostapd_iface *iface, int frequency,
int chan_width, int cf1, int cf2)
{
}
static inline void hostapd_ubus_notify_bss_transition_response(
struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 status_code,
u8 bss_termination_delay, const u8 *target_bssid,
const u8 *candidate_list, u16 candidate_list_len)
{
}
static inline void hostapd_ubus_add(struct hapd_interfaces *interfaces)
{
}
static inline void hostapd_ubus_free(struct hapd_interfaces *interfaces)
{
}
static inline int hostapd_ubus_notify_bss_transition_query(
struct hostapd_data *hapd, const u8 *addr, u8 dialog_token, u8 reason,
const u8 *candidate_list, u16 candidate_list_len)
{
return 0;
}
static inline void
hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta,
const char *auth_alg)
{
}
#endif
#endif

View file

@ -22,6 +22,7 @@
static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan, static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan,
int existsok) int existsok)
{ {
bool vlan_exists = iface_exists(vlan->ifname);
int ret; int ret;
#ifdef CONFIG_WEP #ifdef CONFIG_WEP
int i; int i;
@ -36,7 +37,7 @@ static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan,
} }
#endif /* CONFIG_WEP */ #endif /* CONFIG_WEP */
if (!iface_exists(vlan->ifname)) if (!vlan_exists)
ret = hostapd_vlan_if_add(hapd, vlan->ifname); ret = hostapd_vlan_if_add(hapd, vlan->ifname);
else if (!existsok) else if (!existsok)
return -1; return -1;
@ -51,6 +52,9 @@ static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan,
if (hapd->wpa_auth) if (hapd->wpa_auth)
ret = wpa_auth_ensure_group(hapd->wpa_auth, vlan->vlan_id); ret = wpa_auth_ensure_group(hapd->wpa_auth, vlan->vlan_id);
if (!ret && !vlan_exists)
hostapd_ubus_add_vlan(hapd, vlan);
if (ret == 0) if (ret == 0)
return ret; return ret;
@ -77,6 +81,8 @@ int vlan_if_remove(struct hostapd_data *hapd, struct hostapd_vlan *vlan)
"WPA deinitialization for VLAN %d failed (%d)", "WPA deinitialization for VLAN %d failed (%d)",
vlan->vlan_id, ret); vlan->vlan_id, ret);
hostapd_ubus_remove_vlan(hapd, vlan);
return hostapd_vlan_if_remove(hapd, vlan->ifname); return hostapd_vlan_if_remove(hapd, vlan->ifname);
} }

View file

@ -410,6 +410,7 @@ static int ieee802_11_send_bss_trans_mgmt_request(struct hostapd_data *hapd,
mgmt->u.action.u.bss_tm_req.validity_interval = 1; mgmt->u.action.u.bss_tm_req.validity_interval = 1;
pos = mgmt->u.action.u.bss_tm_req.variable; pos = mgmt->u.action.u.bss_tm_req.variable;
hapd->liminix_stats.wnm.bss_transition_request_tx++;
wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to " wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request to "
MACSTR " dialog_token=%u req_mode=0x%x disassoc_timer=%u " MACSTR " dialog_token=%u req_mode=0x%x disassoc_timer=%u "
"validity_interval=%u", "validity_interval=%u",
@ -478,6 +479,7 @@ static void ieee802_11_rx_bss_trans_mgmt_query(struct hostapd_data *hapd,
MAC2STR(addr), reason, hex ? " neighbor=" : "", hex); MAC2STR(addr), reason, hex ? " neighbor=" : "", hex);
os_free(hex); os_free(hex);
if (!hostapd_ubus_notify_bss_transition_query(hapd, addr, dialog_token, reason, pos, end - pos))
ieee802_11_send_bss_trans_mgmt_request(hapd, addr, dialog_token); ieee802_11_send_bss_trans_mgmt_request(hapd, addr, dialog_token);
} }
@ -500,7 +502,7 @@ static void ieee802_11_rx_bss_trans_mgmt_resp(struct hostapd_data *hapd,
size_t len) size_t len)
{ {
u8 dialog_token, status_code, bss_termination_delay; u8 dialog_token, status_code, bss_termination_delay;
const u8 *pos, *end; const u8 *pos, *end, *target_bssid = NULL;
int enabled = hapd->conf->bss_transition; int enabled = hapd->conf->bss_transition;
struct sta_info *sta; struct sta_info *sta;
@ -547,6 +549,7 @@ static void ieee802_11_rx_bss_trans_mgmt_resp(struct hostapd_data *hapd,
wpa_printf(MSG_DEBUG, "WNM: not enough room for Target BSSID field"); wpa_printf(MSG_DEBUG, "WNM: not enough room for Target BSSID field");
return; return;
} }
target_bssid = pos;
sta->agreed_to_steer = 1; sta->agreed_to_steer = 1;
eloop_cancel_timeout(ap_sta_reset_steer_flag_timer, hapd, sta); eloop_cancel_timeout(ap_sta_reset_steer_flag_timer, hapd, sta);
eloop_register_timeout(2, 0, ap_sta_reset_steer_flag_timer, eloop_register_timeout(2, 0, ap_sta_reset_steer_flag_timer,
@ -566,6 +569,10 @@ static void ieee802_11_rx_bss_trans_mgmt_resp(struct hostapd_data *hapd,
MAC2STR(addr), status_code, bss_termination_delay); MAC2STR(addr), status_code, bss_termination_delay);
} }
hostapd_ubus_notify_bss_transition_response(hapd, sta->addr, dialog_token,
status_code, bss_termination_delay,
target_bssid, pos, end - pos);
wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries", wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries",
pos, end - pos); pos, end - pos);
} }
@ -814,10 +821,12 @@ int ieee802_11_rx_wnm_action_ap(struct hostapd_data *hapd,
plen); plen);
return 0; return 0;
case WNM_BSS_TRANS_MGMT_QUERY: case WNM_BSS_TRANS_MGMT_QUERY:
hapd->liminix_stats.wnm.bss_transition_query_rx++;
ieee802_11_rx_bss_trans_mgmt_query(hapd, mgmt->sa, payload, ieee802_11_rx_bss_trans_mgmt_query(hapd, mgmt->sa, payload,
plen); plen);
return 0; return 0;
case WNM_BSS_TRANS_MGMT_RESP: case WNM_BSS_TRANS_MGMT_RESP:
hapd->liminix_stats.wnm.bss_transition_response_rx++;
ieee802_11_rx_bss_trans_mgmt_resp(hapd, mgmt->sa, payload, ieee802_11_rx_bss_trans_mgmt_resp(hapd, mgmt->sa, payload,
plen); plen);
return 0; return 0;
@ -865,6 +874,7 @@ int wnm_send_disassoc_imminent(struct hostapd_data *hapd,
pos = mgmt->u.action.u.bss_tm_req.variable; pos = mgmt->u.action.u.bss_tm_req.variable;
hapd->liminix_stats.wnm.bss_transition_request_tx++;
wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request frame to indicate imminent disassociation (disassoc_timer=%d) to " wpa_printf(MSG_DEBUG, "WNM: Send BSS Transition Management Request frame to indicate imminent disassociation (disassoc_timer=%d) to "
MACSTR, disassoc_timer, MAC2STR(sta->addr)); MACSTR, disassoc_timer, MAC2STR(sta->addr));
if (hostapd_drv_send_mlme(hapd, buf, pos - buf, 0, NULL, 0, 0) < 0) { if (hostapd_drv_send_mlme(hapd, buf, pos - buf, 0, NULL, 0, 0) < 0) {
@ -947,6 +957,7 @@ int wnm_send_ess_disassoc_imminent(struct hostapd_data *hapd,
return -1; return -1;
} }
hapd->liminix_stats.wnm.bss_transition_request_tx++;
if (disassoc_timer) { if (disassoc_timer) {
/* send disassociation frame after time-out */ /* send disassociation frame after time-out */
set_disassoc_timer(hapd, sta, disassoc_timer); set_disassoc_timer(hapd, sta, disassoc_timer);
@ -1028,6 +1039,7 @@ int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta,
} }
os_free(buf); os_free(buf);
hapd->liminix_stats.wnm.bss_transition_request_tx++;
if (disassoc_timer) { if (disassoc_timer) {
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
if (ap_sta_is_mld(hapd, sta)) { if (ap_sta_is_mld(hapd, sta)) {

View file

@ -112,7 +112,10 @@ static void wpa_gkeydone_sta(struct wpa_state_machine *sm)
int link_id; int link_id;
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
sm->group->GKeyDoneStations--; if (!sm->wpa_auth)
return;
sm->wpa_auth->group->GKeyDoneStations--;
sm->GUpdateStationKeys = false; sm->GUpdateStationKeys = false;
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
@ -1043,7 +1046,6 @@ static void wpa_free_sta_sm(struct wpa_state_machine *sm)
os_free(sm->last_rx_eapol_key); os_free(sm->last_rx_eapol_key);
os_free(sm->wpa_ie); os_free(sm->wpa_ie);
os_free(sm->rsnxe); os_free(sm->rsnxe);
os_free(sm->rsn_selection);
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
for_each_sm_auth(sm, link_id) { for_each_sm_auth(sm, link_id) {
wpa_group_put(sm->mld_links[link_id].wpa_auth, wpa_group_put(sm->mld_links[link_id].wpa_auth,
@ -1884,7 +1886,6 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
sm->EAPOLKeyReceived = true; sm->EAPOLKeyReceived = true;
sm->EAPOLKeyPairwise = !!(key_info & WPA_KEY_INFO_KEY_TYPE); sm->EAPOLKeyPairwise = !!(key_info & WPA_KEY_INFO_KEY_TYPE);
sm->EAPOLKeyRequest = !!(key_info & WPA_KEY_INFO_REQUEST); sm->EAPOLKeyRequest = !!(key_info & WPA_KEY_INFO_REQUEST);
if (msg == PAIRWISE_2)
os_memcpy(sm->SNonce, key->key_nonce, WPA_NONCE_LEN); os_memcpy(sm->SNonce, key->key_nonce, WPA_NONCE_LEN);
wpa_sm_step(sm); wpa_sm_step(sm);
@ -2063,11 +2064,6 @@ void __wpa_send_eapol(struct wpa_authenticator *wpa_auth,
if (key_rsc) if (key_rsc)
os_memcpy(key->key_rsc, key_rsc, WPA_KEY_RSC_LEN); os_memcpy(key->key_rsc, key_rsc, WPA_KEY_RSC_LEN);
#ifdef CONFIG_TESTING_OPTIONS
if (conf->eapol_key_reserved_random)
random_get_bytes(key->key_id, sizeof(key->key_id));
#endif /* CONFIG_TESTING_OPTIONS */
if (kde && !encr) { if (kde && !encr) {
os_memcpy(key_data, kde, kde_len); os_memcpy(key_data, kde, kde_len);
WPA_PUT_BE16(key_mic + mic_len, kde_len); WPA_PUT_BE16(key_mic + mic_len, kde_len);
@ -3918,34 +3914,6 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
goto out; goto out;
} }
#endif /* CONFIG_IEEE80211R_AP */ #endif /* CONFIG_IEEE80211R_AP */
/* Verify RSN Selection element for RSN overriding */
if ((wpa_auth->conf.rsn_override_key_mgmt ||
wpa_auth->conf.rsn_override_key_mgmt_2) &&
((rsn_is_snonce_cookie(sm->SNonce) && !kde.rsn_selection) ||
(!rsn_is_snonce_cookie(sm->SNonce) && kde.rsn_selection) ||
(sm->rsn_selection && !kde.rsn_selection) ||
(!sm->rsn_selection && kde.rsn_selection) ||
(sm->rsn_selection && kde.rsn_selection &&
(sm->rsn_selection_len != kde.rsn_selection_len ||
os_memcmp(sm->rsn_selection, kde.rsn_selection,
sm->rsn_selection_len) != 0)))) {
wpa_auth_logger(wpa_auth, wpa_auth_get_spa(sm), LOGGER_INFO,
"RSN Selection element from (Re)AssocReq did not match the one in EAPOL-Key msg 2/4");
wpa_printf(MSG_DEBUG,
"SNonce cookie for RSN overriding %sused",
rsn_is_snonce_cookie(sm->SNonce) ? "" : "not ");
wpa_hexdump(MSG_DEBUG, "RSN Selection in AssocReq",
sm->rsn_selection, sm->rsn_selection_len);
wpa_hexdump(MSG_DEBUG, "RSN Selection in EAPOL-Key msg 2/4",
kde.rsn_selection, kde.rsn_selection_len);
/* MLME-DEAUTHENTICATE.request */
wpa_sta_disconnect(wpa_auth, sm->addr,
WLAN_REASON_PREV_AUTH_NOT_VALID);
goto out;
}
#ifdef CONFIG_P2P #ifdef CONFIG_P2P
if (kde.ip_addr_req && kde.ip_addr_req[0] && if (kde.ip_addr_req && kde.ip_addr_req[0] &&
wpa_auth->ip_pool && WPA_GET_BE32(sm->ip_addr) == 0) { wpa_auth->ip_pool && WPA_GET_BE32(sm->ip_addr) == 0) {
@ -4209,8 +4177,7 @@ static u8 * replace_ie(const char *name, const u8 *old_buf, size_t *len, u8 eid,
void wpa_auth_ml_get_key_info(struct wpa_authenticator *a, void wpa_auth_ml_get_key_info(struct wpa_authenticator *a,
struct wpa_auth_ml_link_key_info *info, struct wpa_auth_ml_link_key_info *info,
bool mgmt_frame_prot, bool beacon_prot, bool mgmt_frame_prot, bool beacon_prot)
bool rekey)
{ {
struct wpa_group *gsm = a->group; struct wpa_group *gsm = a->group;
u8 rsc[WPA_KEY_RSC_LEN]; u8 rsc[WPA_KEY_RSC_LEN];
@ -4223,7 +4190,7 @@ void wpa_auth_ml_get_key_info(struct wpa_authenticator *a,
info->gtk = gsm->GTK[gsm->GN - 1]; info->gtk = gsm->GTK[gsm->GN - 1];
info->gtk_len = gsm->GTK_len; info->gtk_len = gsm->GTK_len;
if (rekey || wpa_auth_get_seqnum(a, NULL, gsm->GN, rsc) < 0) if (wpa_auth_get_seqnum(a, NULL, gsm->GN, rsc) < 0)
os_memset(info->pn, 0, sizeof(info->pn)); os_memset(info->pn, 0, sizeof(info->pn));
else else
os_memcpy(info->pn, rsc, sizeof(info->pn)); os_memcpy(info->pn, rsc, sizeof(info->pn));
@ -4235,7 +4202,7 @@ void wpa_auth_ml_get_key_info(struct wpa_authenticator *a,
info->igtk = gsm->IGTK[gsm->GN_igtk - 4]; info->igtk = gsm->IGTK[gsm->GN_igtk - 4];
info->igtk_len = wpa_cipher_key_len(a->conf.group_mgmt_cipher); info->igtk_len = wpa_cipher_key_len(a->conf.group_mgmt_cipher);
if (rekey || wpa_auth_get_seqnum(a, NULL, gsm->GN_igtk, rsc) < 0) if (wpa_auth_get_seqnum(a, NULL, gsm->GN_igtk, rsc) < 0)
os_memset(info->ipn, 0, sizeof(info->ipn)); os_memset(info->ipn, 0, sizeof(info->ipn));
else else
os_memcpy(info->ipn, rsc, sizeof(info->ipn)); os_memcpy(info->ipn, rsc, sizeof(info->ipn));
@ -4251,7 +4218,7 @@ void wpa_auth_ml_get_key_info(struct wpa_authenticator *a,
info->bigtkidx = gsm->GN_bigtk; info->bigtkidx = gsm->GN_bigtk;
info->bigtk = gsm->BIGTK[gsm->GN_bigtk - 6]; info->bigtk = gsm->BIGTK[gsm->GN_bigtk - 6];
if (rekey || wpa_auth_get_seqnum(a, NULL, gsm->GN_bigtk, rsc) < 0) if (wpa_auth_get_seqnum(a, NULL, gsm->GN_bigtk, rsc) < 0)
os_memset(info->bipn, 0, sizeof(info->bipn)); os_memset(info->bipn, 0, sizeof(info->bipn));
else else
os_memcpy(info->bipn, rsc, sizeof(info->bipn)); os_memcpy(info->bipn, rsc, sizeof(info->bipn));
@ -4259,13 +4226,12 @@ void wpa_auth_ml_get_key_info(struct wpa_authenticator *a,
static void wpa_auth_get_ml_key_info(struct wpa_authenticator *wpa_auth, static void wpa_auth_get_ml_key_info(struct wpa_authenticator *wpa_auth,
struct wpa_auth_ml_key_info *info, struct wpa_auth_ml_key_info *info)
bool rekey)
{ {
if (!wpa_auth->cb->get_ml_key_info) if (!wpa_auth->cb->get_ml_key_info)
return; return;
wpa_auth->cb->get_ml_key_info(wpa_auth->cb_ctx, info, rekey); wpa_auth->cb->get_ml_key_info(wpa_auth->cb_ctx, info);
} }
@ -4322,7 +4288,6 @@ static u8 * wpa_auth_ml_group_kdes(struct wpa_state_machine *sm, u8 *pos)
struct wpa_auth_ml_key_info ml_key_info; struct wpa_auth_ml_key_info ml_key_info;
unsigned int i, link_id; unsigned int i, link_id;
u8 *start = pos; u8 *start = pos;
bool rekey = sm->wpa_ptk_group_state == WPA_PTK_GROUP_REKEYNEGOTIATING;
/* First fetch the key information from all the authenticators */ /* First fetch the key information from all the authenticators */
os_memset(&ml_key_info, 0, sizeof(ml_key_info)); os_memset(&ml_key_info, 0, sizeof(ml_key_info));
@ -4342,7 +4307,7 @@ static u8 * wpa_auth_ml_group_kdes(struct wpa_state_machine *sm, u8 *pos)
ml_key_info.links[i++].link_id = link_id; ml_key_info.links[i++].link_id = link_id;
} }
wpa_auth_get_ml_key_info(sm->wpa_auth, &ml_key_info, rekey); wpa_auth_get_ml_key_info(sm->wpa_auth, &ml_key_info);
/* Add MLO GTK KDEs */ /* Add MLO GTK KDEs */
for (i = 0, link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) { for (i = 0, link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
@ -4481,7 +4446,7 @@ static size_t wpa_auth_ml_kdes_len(struct wpa_state_machine *sm)
/* For the MAC Address KDE */ /* For the MAC Address KDE */
kde_len = 2 + RSN_SELECTOR_LEN + ETH_ALEN; kde_len = 2 + RSN_SELECTOR_LEN + ETH_ALEN;
/* MLO Link KDE and RSN Override Link KDE for each link */ /* MLO Link KDE for each link */
for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) { for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
struct wpa_authenticator *wpa_auth; struct wpa_authenticator *wpa_auth;
const u8 *ie; const u8 *ie;
@ -4490,39 +4455,15 @@ static size_t wpa_auth_ml_kdes_len(struct wpa_state_machine *sm)
if (!wpa_auth) if (!wpa_auth)
continue; continue;
/* MLO Link KDE */
kde_len += 2 + RSN_SELECTOR_LEN + 1 + ETH_ALEN; kde_len += 2 + RSN_SELECTOR_LEN + 1 + ETH_ALEN;
ie = get_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len, ie = get_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len,
WLAN_EID_RSN); WLAN_EID_RSN);
if (ie) if (ie)
kde_len += 2 + ie[1]; kde_len += 2 + ie[1];
ie = get_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len, ie = get_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len,
WLAN_EID_RSNX); WLAN_EID_RSNX);
if (ie) if (ie)
kde_len += 2 + ie[1]; kde_len += 2 + ie[1];
if (!rsn_is_snonce_cookie(sm->SNonce))
continue;
/* RSN Override Link KDE */
kde_len += 2 + RSN_SELECTOR_LEN + 1;
ie = get_vendor_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len,
RSNE_OVERRIDE_IE_VENDOR_TYPE);
if (ie)
kde_len += 2 + ie[1];
ie = get_vendor_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len,
RSNE_OVERRIDE_2_IE_VENDOR_TYPE);
if (ie)
kde_len += 2 + ie[1];
ie = get_vendor_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len,
RSNXE_OVERRIDE_IE_VENDOR_TYPE);
if (ie)
kde_len += 2 + ie[1];
} }
kde_len += wpa_auth_ml_group_kdes_len(sm); kde_len += wpa_auth_ml_group_kdes_len(sm);
@ -4547,9 +4488,8 @@ static u8 * wpa_auth_ml_kdes(struct wpa_state_machine *sm, u8 *pos)
for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) { for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
struct wpa_authenticator *wpa_auth; struct wpa_authenticator *wpa_auth;
const u8 *rsne, *rsnxe, *rsnoe, *rsno2e, *rsnxoe; const u8 *rsne, *rsnxe;
size_t rsne_len, rsnxe_len, rsnoe_len, rsno2e_len, rsnxoe_len; size_t rsne_len, rsnxe_len;
size_t kde_len;
wpa_auth = wpa_get_link_auth(sm->wpa_auth, link_id); wpa_auth = wpa_get_link_auth(sm->wpa_auth, link_id);
if (!wpa_auth) if (!wpa_auth)
@ -4568,7 +4508,6 @@ static u8 * wpa_auth_ml_kdes(struct wpa_state_machine *sm, u8 *pos)
RSN_SELECTOR_LEN + 1 + ETH_ALEN + RSN_SELECTOR_LEN + 1 + ETH_ALEN +
rsne_len + rsnxe_len); rsne_len + rsnxe_len);
/* MLO Link KDE */
*pos++ = WLAN_EID_VENDOR_SPECIFIC; *pos++ = WLAN_EID_VENDOR_SPECIFIC;
*pos++ = RSN_SELECTOR_LEN + 1 + ETH_ALEN + *pos++ = RSN_SELECTOR_LEN + 1 + ETH_ALEN +
rsne_len + rsnxe_len; rsne_len + rsnxe_len;
@ -4596,63 +4535,9 @@ static u8 * wpa_auth_ml_kdes(struct wpa_state_machine *sm, u8 *pos)
os_memcpy(pos, rsnxe, rsnxe_len); os_memcpy(pos, rsnxe, rsnxe_len);
pos += rsnxe_len; pos += rsnxe_len;
} }
if (!rsn_is_snonce_cookie(sm->SNonce))
continue;
rsnoe = get_vendor_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len,
RSNE_OVERRIDE_IE_VENDOR_TYPE);
rsnoe_len = rsnoe ? 2 + rsnoe[1] : 0;
rsno2e = get_vendor_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len,
RSNE_OVERRIDE_2_IE_VENDOR_TYPE);
rsno2e_len = rsno2e ? 2 + rsno2e[1] : 0;
rsnxoe = get_vendor_ie(wpa_auth->wpa_ie, wpa_auth->wpa_ie_len,
RSNXE_OVERRIDE_IE_VENDOR_TYPE);
rsnxoe_len = rsnxoe ? 2 + rsnxoe[1] : 0;
wpa_printf(MSG_DEBUG,
"RSN: RSN Override Link KDE: link=%u, len=%zu",
link_id, RSN_SELECTOR_LEN + rsnoe_len + rsno2e_len +
rsnxoe_len);
/* RSN Override Link KDE */
*pos++ = WLAN_EID_VENDOR_SPECIFIC;
kde_len = RSN_SELECTOR_LEN + 1 + rsnoe_len + rsno2e_len +
rsnxoe_len;
if (kde_len > 255) {
wpa_printf(MSG_ERROR,
"RSN: RSNOE/RSNO2E/RSNXOE too long (KDE length %zu) to fit in RSN Override Link KDE for link %u",
kde_len, link_id);
return NULL;
}
*pos++ = kde_len;
RSN_SELECTOR_PUT(pos, WFA_KEY_DATA_RSN_OVERRIDE_LINK);
pos += RSN_SELECTOR_LEN;
*pos++ = link_id;
if (rsnoe_len) {
os_memcpy(pos, rsnoe, rsnoe_len);
pos += rsnoe_len;
} }
if (rsno2e_len) { wpa_printf(MSG_DEBUG, "RSN: MLO Link KDE len = %ld", pos - start);
os_memcpy(pos, rsno2e, rsno2e_len);
pos += rsno2e_len;
}
if (rsnxoe_len) {
os_memcpy(pos, rsnxoe, rsnxoe_len);
pos += rsnxoe_len;
}
}
wpa_printf(MSG_DEBUG,
"RSN: MLO Link KDEs and RSN Override Link KDEs len = %ld",
pos - start);
pos = wpa_auth_ml_group_kdes(sm, pos); pos = wpa_auth_ml_group_kdes(sm, pos);
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
@ -4667,7 +4552,7 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
struct wpa_group *gsm = sm->group; struct wpa_group *gsm = sm->group;
u8 *wpa_ie; u8 *wpa_ie;
int secure, gtkidx, encr = 0; int secure, gtkidx, encr = 0;
u8 *wpa_ie_buf = NULL, *wpa_ie_buf2 = NULL, *wpa_ie_buf3 = NULL; u8 *wpa_ie_buf = NULL, *wpa_ie_buf2 = NULL;
u8 hdr[2]; u8 hdr[2];
struct wpa_auth_config *conf = &sm->wpa_auth->conf; struct wpa_auth_config *conf = &sm->wpa_auth->conf;
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
@ -4708,39 +4593,6 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
wpa_ie = wpa_ie + wpa_ie[1] + 2; wpa_ie = wpa_ie + wpa_ie[1] + 2;
wpa_ie_len = wpa_ie[1] + 2; wpa_ie_len = wpa_ie[1] + 2;
} }
if ((conf->rsn_override_key_mgmt || conf->rsn_override_key_mgmt_2) &&
!rsn_is_snonce_cookie(sm->SNonce)) {
u8 *ie;
size_t ie_len;
u32 ids[] = {
RSNE_OVERRIDE_IE_VENDOR_TYPE,
RSNE_OVERRIDE_2_IE_VENDOR_TYPE,
RSNXE_OVERRIDE_IE_VENDOR_TYPE,
0
};
int i;
wpa_printf(MSG_DEBUG,
"RSN: Remove RSNE/RSNXE override elements");
wpa_hexdump(MSG_DEBUG, "EAPOL-Key msg 3/4 IEs before edits",
wpa_ie, wpa_ie_len);
wpa_ie_buf3 = os_memdup(wpa_ie, wpa_ie_len);
if (!wpa_ie_buf3)
goto done;
wpa_ie = wpa_ie_buf3;
for (i = 0; ids[i]; i++) {
ie = (u8 *) get_vendor_ie(wpa_ie, wpa_ie_len, ids[i]);
if (ie) {
ie_len = 2 + ie[1];
os_memmove(ie, ie + ie_len,
wpa_ie_len - (ie + ie_len - wpa_ie));
wpa_ie_len -= ie_len;
}
}
wpa_hexdump(MSG_DEBUG, "EAPOL-Key msg 3/4 IEs after edits",
wpa_ie, wpa_ie_len);
}
#ifdef CONFIG_TESTING_OPTIONS #ifdef CONFIG_TESTING_OPTIONS
if (conf->rsne_override_eapol_set) { if (conf->rsne_override_eapol_set) {
wpa_ie_buf2 = replace_ie( wpa_ie_buf2 = replace_ie(
@ -4980,10 +4832,6 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
#endif /* CONFIG_DPP2 */ #endif /* CONFIG_DPP2 */
pos = wpa_auth_ml_kdes(sm, pos); pos = wpa_auth_ml_kdes(sm, pos);
if (!pos) {
wpa_printf(MSG_ERROR, "RSN: Failed to add MLO KDEs");
goto done;
}
if (sm->ssid_protection) { if (sm->ssid_protection) {
*pos++ = WLAN_EID_SSID; *pos++ = WLAN_EID_SSID;
@ -5014,7 +4862,6 @@ done:
bin_clear_free(kde, kde_len); bin_clear_free(kde, kde_len);
os_free(wpa_ie_buf); os_free(wpa_ie_buf);
os_free(wpa_ie_buf2); os_free(wpa_ie_buf2);
os_free(wpa_ie_buf3);
} }
@ -5628,38 +5475,11 @@ static void wpa_group_gtk_init(struct wpa_authenticator *wpa_auth,
static int wpa_group_update_sta(struct wpa_state_machine *sm, void *ctx) static int wpa_group_update_sta(struct wpa_state_machine *sm, void *ctx)
{ {
struct wpa_authenticator *wpa_auth = sm->wpa_auth; if (ctx != NULL && ctx != sm->group)
struct wpa_group *group = sm->group;
#ifdef CONFIG_IEEE80211BE
int link_id;
for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
if (!sm->mld_links[link_id].valid)
continue;
if (sm->mld_links[link_id].wpa_auth &&
sm->mld_links[link_id].wpa_auth->group == ctx) {
group = sm->mld_links[link_id].wpa_auth->group;
wpa_auth = sm->mld_links[link_id].wpa_auth;
break;
}
}
#endif /* CONFIG_IEEE80211BE */
if (ctx && ctx != group)
return 0; return 0;
#ifdef CONFIG_IEEE80211BE
/* For ML STA, run rekey on the association link and send G1 with keys
* for all links. This is based on assumption that MLD level
* Authenticator updates group keys on all affiliated links in one shot
* and not independently or concurrently for separate links. */
if (sm->mld_assoc_link_id >= 0 &&
sm->mld_assoc_link_id != wpa_auth->link_id)
return 0;
#endif /* CONFIG_IEEE80211BE */
if (sm->wpa_ptk_state != WPA_PTK_PTKINITDONE) { if (sm->wpa_ptk_state != WPA_PTK_PTKINITDONE) {
wpa_auth_logger(wpa_auth, wpa_auth_get_spa(sm), wpa_auth_logger(sm->wpa_auth, wpa_auth_get_spa(sm),
LOGGER_DEBUG, LOGGER_DEBUG,
"Not in PTKINITDONE; skip Group Key update"); "Not in PTKINITDONE; skip Group Key update");
sm->GUpdateStationKeys = false; sm->GUpdateStationKeys = false;
@ -5671,7 +5491,7 @@ static int wpa_group_update_sta(struct wpa_state_machine *sm, void *ctx)
* Since we clear the GKeyDoneStations before the loop, the * Since we clear the GKeyDoneStations before the loop, the
* station needs to be counted here anyway. * station needs to be counted here anyway.
*/ */
wpa_auth_logger(wpa_auth, wpa_auth_get_spa(sm), wpa_auth_logger(sm->wpa_auth, wpa_auth_get_spa(sm),
LOGGER_DEBUG, LOGGER_DEBUG,
"GUpdateStationKeys was already set when marking station for GTK rekeying"); "GUpdateStationKeys was already set when marking station for GTK rekeying");
} }
@ -5681,11 +5501,6 @@ static int wpa_group_update_sta(struct wpa_state_machine *sm, void *ctx)
return 0; return 0;
sm->group->GKeyDoneStations++; sm->group->GKeyDoneStations++;
#ifdef CONFIG_IEEE80211BE
for_each_sm_auth(sm, link_id)
sm->mld_links[link_id].wpa_auth->group->GKeyDoneStations++;
#endif /* CONFIG_IEEE80211BE */
sm->GUpdateStationKeys = true; sm->GUpdateStationKeys = true;
wpa_sm_step(sm); wpa_sm_step(sm);
@ -6998,30 +6813,6 @@ void wpa_auth_set_auth_alg(struct wpa_state_machine *sm, u16 auth_alg)
} }
void wpa_auth_set_rsn_selection(struct wpa_state_machine *sm, const u8 *ie,
size_t len)
{
if (!sm)
return;
os_free(sm->rsn_selection);
sm->rsn_selection = NULL;
sm->rsn_selection_len = 0;
sm->rsn_override = false;
sm->rsn_override_2 = false;
if (ie) {
if (len >= 1) {
if (ie[0] == RSN_SELECTION_RSNE_OVERRIDE)
sm->rsn_override = true;
else if (ie[0] == RSN_SELECTION_RSNE_OVERRIDE_2)
sm->rsn_override_2 = true;
}
sm->rsn_selection = os_memdup(ie, len);
if (sm->rsn_selection)
sm->rsn_selection_len = len;
}
}
#ifdef CONFIG_DPP2 #ifdef CONFIG_DPP2
void wpa_auth_set_dpp_z(struct wpa_state_machine *sm, const struct wpabuf *z) void wpa_auth_set_dpp_z(struct wpa_state_machine *sm, const struct wpabuf *z)
{ {

View file

@ -17,7 +17,7 @@
struct vlan_description; struct vlan_description;
struct mld_info; struct mld_info;
#define MAX_OWN_IE_OVERRIDE 257 #define MAX_OWN_IE_OVERRIDE 256
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma pack(push, 1) #pragma pack(push, 1)
@ -173,8 +173,6 @@ struct wpa_auth_config {
int wpa; int wpa;
int extended_key_id; int extended_key_id;
int wpa_key_mgmt; int wpa_key_mgmt;
int rsn_override_key_mgmt;
int rsn_override_key_mgmt_2;
int wpa_pairwise; int wpa_pairwise;
int wpa_group; int wpa_group;
int wpa_group_rekey; int wpa_group_rekey;
@ -186,8 +184,6 @@ struct wpa_auth_config {
u32 wpa_pairwise_update_count; u32 wpa_pairwise_update_count;
int wpa_disable_eapol_key_retries; int wpa_disable_eapol_key_retries;
int rsn_pairwise; int rsn_pairwise;
int rsn_override_pairwise;
int rsn_override_pairwise_2;
int rsn_preauth; int rsn_preauth;
int eapol_version; int eapol_version;
int wmm_enabled; int wmm_enabled;
@ -196,8 +192,6 @@ struct wpa_auth_config {
int okc; int okc;
int tx_status; int tx_status;
enum mfp_options ieee80211w; enum mfp_options ieee80211w;
enum mfp_options rsn_override_mfp;
enum mfp_options rsn_override_mfp_2;
int beacon_prot; int beacon_prot;
int group_mgmt_cipher; int group_mgmt_cipher;
int sae_require_mfp; int sae_require_mfp;
@ -230,21 +224,6 @@ struct wpa_auth_config {
double corrupt_gtk_rekey_mic_probability; double corrupt_gtk_rekey_mic_probability;
u8 own_ie_override[MAX_OWN_IE_OVERRIDE]; u8 own_ie_override[MAX_OWN_IE_OVERRIDE];
size_t own_ie_override_len; size_t own_ie_override_len;
bool rsne_override_set;
u8 rsne_override[MAX_OWN_IE_OVERRIDE];
size_t rsne_override_len;
bool rsnoe_override_set;
u8 rsnoe_override[MAX_OWN_IE_OVERRIDE];
size_t rsnoe_override_len;
bool rsno2e_override_set;
u8 rsno2e_override[MAX_OWN_IE_OVERRIDE];
size_t rsno2e_override_len;
bool rsnxe_override_set;
u8 rsnxe_override[MAX_OWN_IE_OVERRIDE];
size_t rsnxe_override_len;
bool rsnxoe_override_set;
u8 rsnxoe_override[MAX_OWN_IE_OVERRIDE];
size_t rsnxoe_override_len;
u8 rsne_override_eapol[MAX_OWN_IE_OVERRIDE]; u8 rsne_override_eapol[MAX_OWN_IE_OVERRIDE];
size_t rsne_override_eapol_len; size_t rsne_override_eapol_len;
u8 rsnxe_override_eapol[MAX_OWN_IE_OVERRIDE]; u8 rsnxe_override_eapol[MAX_OWN_IE_OVERRIDE];
@ -266,7 +245,6 @@ struct wpa_auth_config {
struct wpabuf *eapol_m1_elements; struct wpabuf *eapol_m1_elements;
struct wpabuf *eapol_m3_elements; struct wpabuf *eapol_m3_elements;
bool eapol_m3_no_encrypt; bool eapol_m3_no_encrypt;
bool eapol_key_reserved_random;
#endif /* CONFIG_TESTING_OPTIONS */ #endif /* CONFIG_TESTING_OPTIONS */
unsigned int oci_freq_override_eapol_m3; unsigned int oci_freq_override_eapol_m3;
unsigned int oci_freq_override_eapol_g1; unsigned int oci_freq_override_eapol_g1;
@ -317,8 +295,6 @@ struct wpa_auth_config {
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
bool ssid_protection; bool ssid_protection;
int rsn_override_omit_rsnxe;
}; };
typedef enum { typedef enum {
@ -424,8 +400,7 @@ struct wpa_auth_callbacks {
size_t ltf_keyseed_len); size_t ltf_keyseed_len);
#endif /* CONFIG_PASN */ #endif /* CONFIG_PASN */
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
int (*get_ml_key_info)(void *ctx, struct wpa_auth_ml_key_info *info, int (*get_ml_key_info)(void *ctx, struct wpa_auth_ml_key_info *info);
bool rekey);
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
int (*get_drv_flags)(void *ctx, u64 *drv_flags, u64 *drv_flags2); int (*get_drv_flags)(void *ctx, u64 *drv_flags, u64 *drv_flags2);
}; };
@ -630,8 +605,6 @@ u8 * wpa_auth_write_assoc_resp_fils(struct wpa_state_machine *sm,
bool wpa_auth_write_fd_rsn_info(struct wpa_authenticator *wpa_auth, bool wpa_auth_write_fd_rsn_info(struct wpa_authenticator *wpa_auth,
u8 *fd_rsn_info); u8 *fd_rsn_info);
void wpa_auth_set_auth_alg(struct wpa_state_machine *sm, u16 auth_alg); void wpa_auth_set_auth_alg(struct wpa_state_machine *sm, u16 auth_alg);
void wpa_auth_set_rsn_selection(struct wpa_state_machine *sm, const u8 *ie,
size_t len);
void wpa_auth_set_dpp_z(struct wpa_state_machine *sm, const struct wpabuf *z); void wpa_auth_set_dpp_z(struct wpa_state_machine *sm, const struct wpabuf *z);
void wpa_auth_set_ssid_protection(struct wpa_state_machine *sm, bool val); void wpa_auth_set_ssid_protection(struct wpa_state_machine *sm, bool val);
void wpa_auth_set_transition_disable(struct wpa_authenticator *wpa_auth, void wpa_auth_set_transition_disable(struct wpa_authenticator *wpa_auth,
@ -671,8 +644,7 @@ void wpa_auth_set_ml_info(struct wpa_state_machine *sm,
u8 mld_assoc_link_id, struct mld_info *info); u8 mld_assoc_link_id, struct mld_info *info);
void wpa_auth_ml_get_key_info(struct wpa_authenticator *a, void wpa_auth_ml_get_key_info(struct wpa_authenticator *a,
struct wpa_auth_ml_link_key_info *info, struct wpa_auth_ml_link_key_info *info,
bool mgmt_frame_prot, bool beacon_prot, bool mgmt_frame_prot, bool beacon_prot);
bool rekey);
void wpa_release_link_auth_ref(struct wpa_state_machine *sm, void wpa_release_link_auth_ref(struct wpa_state_machine *sm,
int release_link_id); int release_link_id);

View file

@ -45,8 +45,6 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
wconf->wpa = conf->wpa; wconf->wpa = conf->wpa;
wconf->extended_key_id = conf->extended_key_id; wconf->extended_key_id = conf->extended_key_id;
wconf->wpa_key_mgmt = conf->wpa_key_mgmt; wconf->wpa_key_mgmt = conf->wpa_key_mgmt;
wconf->rsn_override_key_mgmt = conf->rsn_override_key_mgmt;
wconf->rsn_override_key_mgmt_2 = conf->rsn_override_key_mgmt_2;
wconf->wpa_pairwise = conf->wpa_pairwise; wconf->wpa_pairwise = conf->wpa_pairwise;
wconf->wpa_group = conf->wpa_group; wconf->wpa_group = conf->wpa_group;
wconf->wpa_group_rekey = conf->wpa_group_rekey; wconf->wpa_group_rekey = conf->wpa_group_rekey;
@ -58,8 +56,6 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
conf->wpa_disable_eapol_key_retries; conf->wpa_disable_eapol_key_retries;
wconf->wpa_pairwise_update_count = conf->wpa_pairwise_update_count; wconf->wpa_pairwise_update_count = conf->wpa_pairwise_update_count;
wconf->rsn_pairwise = conf->rsn_pairwise; wconf->rsn_pairwise = conf->rsn_pairwise;
wconf->rsn_override_pairwise = conf->rsn_override_pairwise;
wconf->rsn_override_pairwise_2 = conf->rsn_override_pairwise_2;
wconf->rsn_preauth = conf->rsn_preauth; wconf->rsn_preauth = conf->rsn_preauth;
wconf->eapol_version = conf->eapol_version; wconf->eapol_version = conf->eapol_version;
#ifdef CONFIG_MACSEC #ifdef CONFIG_MACSEC
@ -74,8 +70,6 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
#endif /* CONFIG_OCV */ #endif /* CONFIG_OCV */
wconf->okc = conf->okc; wconf->okc = conf->okc;
wconf->ieee80211w = conf->ieee80211w; wconf->ieee80211w = conf->ieee80211w;
wconf->rsn_override_mfp = conf->rsn_override_mfp;
wconf->rsn_override_mfp_2 = conf->rsn_override_mfp_2;
wconf->beacon_prot = conf->beacon_prot; wconf->beacon_prot = conf->beacon_prot;
wconf->group_mgmt_cipher = conf->group_mgmt_cipher; wconf->group_mgmt_cipher = conf->group_mgmt_cipher;
wconf->sae_require_mfp = conf->sae_require_mfp; wconf->sae_require_mfp = conf->sae_require_mfp;
@ -132,46 +126,6 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
wpabuf_head(conf->own_ie_override), wpabuf_head(conf->own_ie_override),
wconf->own_ie_override_len); wconf->own_ie_override_len);
} }
if (conf->rsne_override &&
wpabuf_len(conf->rsne_override) <= MAX_OWN_IE_OVERRIDE) {
wconf->rsne_override_len = wpabuf_len(conf->rsne_override);
os_memcpy(wconf->rsne_override,
wpabuf_head(conf->rsne_override),
wconf->rsne_override_len);
wconf->rsne_override_set = true;
}
if (conf->rsnoe_override &&
wpabuf_len(conf->rsnoe_override) <= MAX_OWN_IE_OVERRIDE) {
wconf->rsnoe_override_len = wpabuf_len(conf->rsnoe_override);
os_memcpy(wconf->rsnoe_override,
wpabuf_head(conf->rsnoe_override),
wconf->rsnoe_override_len);
wconf->rsnoe_override_set = true;
}
if (conf->rsno2e_override &&
wpabuf_len(conf->rsno2e_override) <= MAX_OWN_IE_OVERRIDE) {
wconf->rsno2e_override_len = wpabuf_len(conf->rsno2e_override);
os_memcpy(wconf->rsno2e_override,
wpabuf_head(conf->rsno2e_override),
wconf->rsno2e_override_len);
wconf->rsno2e_override_set = true;
}
if (conf->rsnxe_override &&
wpabuf_len(conf->rsnxe_override) <= MAX_OWN_IE_OVERRIDE) {
wconf->rsnxe_override_len = wpabuf_len(conf->rsnxe_override);
os_memcpy(wconf->rsnxe_override,
wpabuf_head(conf->rsnxe_override),
wconf->rsnxe_override_len);
wconf->rsnxe_override_set = true;
}
if (conf->rsnxoe_override &&
wpabuf_len(conf->rsnxoe_override) <= MAX_OWN_IE_OVERRIDE) {
wconf->rsnxoe_override_len = wpabuf_len(conf->rsnxoe_override);
os_memcpy(wconf->rsnxoe_override,
wpabuf_head(conf->rsnxoe_override),
wconf->rsnxoe_override_len);
wconf->rsnxoe_override_set = true;
}
if (conf->rsne_override_eapol && if (conf->rsne_override_eapol &&
wpabuf_len(conf->rsne_override_eapol) <= MAX_OWN_IE_OVERRIDE) { wpabuf_len(conf->rsne_override_eapol) <= MAX_OWN_IE_OVERRIDE) {
wconf->rsne_override_eapol_set = 1; wconf->rsne_override_eapol_set = 1;
@ -236,7 +190,6 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
if (conf->eapol_m3_elements) if (conf->eapol_m3_elements)
wconf->eapol_m3_elements = wpabuf_dup(conf->eapol_m3_elements); wconf->eapol_m3_elements = wpabuf_dup(conf->eapol_m3_elements);
wconf->eapol_m3_no_encrypt = conf->eapol_m3_no_encrypt; wconf->eapol_m3_no_encrypt = conf->eapol_m3_no_encrypt;
wconf->eapol_key_reserved_random = conf->eapol_key_reserved_random;
#endif /* CONFIG_TESTING_OPTIONS */ #endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_P2P #ifdef CONFIG_P2P
os_memcpy(wconf->ip_addr_go, conf->ip_addr_go, 4); os_memcpy(wconf->ip_addr_go, conf->ip_addr_go, 4);
@ -275,8 +228,6 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
wconf->no_disconnect_on_group_keyerror = wconf->no_disconnect_on_group_keyerror =
conf->bss_max_idle && conf->ap_max_inactivity && conf->bss_max_idle && conf->ap_max_inactivity &&
conf->no_disconnect_on_group_keyerror; conf->no_disconnect_on_group_keyerror;
wconf->rsn_override_omit_rsnxe = conf->rsn_override_omit_rsnxe;
} }
@ -328,6 +279,7 @@ static void hostapd_wpa_auth_psk_failure_report(void *ctx, const u8 *addr)
struct hostapd_data *hapd = ctx; struct hostapd_data *hapd = ctx;
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POSSIBLE_PSK_MISMATCH MACSTR, wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POSSIBLE_PSK_MISMATCH MACSTR,
MAC2STR(addr)); MAC2STR(addr));
hostapd_ubus_notify(hapd, "key-mismatch", addr);
} }
@ -1587,8 +1539,7 @@ static int hostapd_set_ltf_keyseed(void *ctx, const u8 *peer_addr,
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
static int hostapd_wpa_auth_get_ml_key_info(void *ctx, static int hostapd_wpa_auth_get_ml_key_info(void *ctx,
struct wpa_auth_ml_key_info *info, struct wpa_auth_ml_key_info *info)
bool rekey)
{ {
struct hostapd_data *hapd = ctx; struct hostapd_data *hapd = ctx;
unsigned int i; unsigned int i;
@ -1612,8 +1563,7 @@ static int hostapd_wpa_auth_get_ml_key_info(void *ctx,
wpa_auth_ml_get_key_info(hapd->wpa_auth, wpa_auth_ml_get_key_info(hapd->wpa_auth,
&info->links[i], &info->links[i],
info->mgmt_frame_prot, info->mgmt_frame_prot,
info->beacon_prot, info->beacon_prot);
rekey);
continue; continue;
} }
@ -1624,8 +1574,7 @@ static int hostapd_wpa_auth_get_ml_key_info(void *ctx,
wpa_auth_ml_get_key_info(bss->wpa_auth, wpa_auth_ml_get_key_info(bss->wpa_auth,
&info->links[i], &info->links[i],
info->mgmt_frame_prot, info->mgmt_frame_prot,
info->beacon_prot, info->beacon_prot);
rekey);
link_bss_found = true; link_bss_found = true;
break; break;
} }

View file

@ -111,8 +111,6 @@ struct wpa_state_machine {
size_t wpa_ie_len; size_t wpa_ie_len;
u8 *rsnxe; u8 *rsnxe;
size_t rsnxe_len; size_t rsnxe_len;
u8 *rsn_selection;
size_t rsn_selection_len;
enum { enum {
WPA_VERSION_NO_WPA = 0 /* WPA not used */, WPA_VERSION_NO_WPA = 0 /* WPA not used */,
@ -126,9 +124,6 @@ struct wpa_state_machine {
u32 dot11RSNAStatsTKIPLocalMICFailures; u32 dot11RSNAStatsTKIPLocalMICFailures;
u32 dot11RSNAStatsTKIPRemoteMICFailures; u32 dot11RSNAStatsTKIPRemoteMICFailures;
bool rsn_override;
bool rsn_override_2;
#ifdef CONFIG_IEEE80211R_AP #ifdef CONFIG_IEEE80211R_AP
u8 xxkey[PMK_LEN_MAX]; /* PSK or the second 256 bits of MSK, or the u8 xxkey[PMK_LEN_MAX]; /* PSK or the second 256 bits of MSK, or the
* first 384 bits of MSK */ * first 384 bits of MSK */

View file

@ -89,8 +89,7 @@ static int wpa_write_wpa_ie(struct wpa_auth_config *conf, u8 *buf, size_t len)
} }
static u16 wpa_own_rsn_capab(struct wpa_auth_config *conf, static u16 wpa_own_rsn_capab(struct wpa_auth_config *conf)
enum mfp_options mfp)
{ {
u16 capab = 0; u16 capab = 0;
@ -100,9 +99,9 @@ static u16 wpa_own_rsn_capab(struct wpa_auth_config *conf,
/* 4 PTKSA replay counters when using WMM */ /* 4 PTKSA replay counters when using WMM */
capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2); capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2);
} }
if (mfp != NO_MGMT_FRAME_PROTECTION) { if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
capab |= WPA_CAPABILITY_MFPC; capab |= WPA_CAPABILITY_MFPC;
if (mfp == MGMT_FRAME_PROTECTION_REQUIRED) if (conf->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED)
capab |= WPA_CAPABILITY_MFPR; capab |= WPA_CAPABILITY_MFPR;
} }
#ifdef CONFIG_OCV #ifdef CONFIG_OCV
@ -120,19 +119,24 @@ static u16 wpa_own_rsn_capab(struct wpa_auth_config *conf,
} }
static u8 * rsne_write_data(u8 *buf, size_t len, u8 *pos, int group, int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,
int pairwise, int key_mgmt, u16 rsn_capab, const u8 *pmkid)
const u8 *pmkid, enum mfp_options mfp,
int group_mgmt_cipher)
{ {
struct rsn_ie_hdr *hdr;
int num_suites, res; int num_suites, res;
u8 *count; u8 *pos, *count;
u32 suite; u32 suite;
suite = wpa_cipher_to_suite(WPA_PROTO_RSN, group); hdr = (struct rsn_ie_hdr *) buf;
hdr->elem_id = WLAN_EID_RSN;
WPA_PUT_LE16(hdr->version, RSN_VERSION);
pos = (u8 *) (hdr + 1);
suite = wpa_cipher_to_suite(WPA_PROTO_RSN, conf->wpa_group);
if (suite == 0) { if (suite == 0) {
wpa_printf(MSG_DEBUG, "Invalid group cipher (%d).", group); wpa_printf(MSG_DEBUG, "Invalid group cipher (%d).",
return NULL; conf->wpa_group);
return -1;
} }
RSN_SELECTOR_PUT(pos, suite); RSN_SELECTOR_PUT(pos, suite);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
@ -149,7 +153,7 @@ static u8 * rsne_write_data(u8 *buf, size_t len, u8 *pos, int group,
} }
#endif /* CONFIG_RSN_TESTING */ #endif /* CONFIG_RSN_TESTING */
res = rsn_cipher_put_suites(pos, pairwise); res = rsn_cipher_put_suites(pos, conf->rsn_pairwise);
num_suites += res; num_suites += res;
pos += res * RSN_SELECTOR_LEN; pos += res * RSN_SELECTOR_LEN;
@ -163,8 +167,8 @@ static u8 * rsne_write_data(u8 *buf, size_t len, u8 *pos, int group,
if (num_suites == 0) { if (num_suites == 0) {
wpa_printf(MSG_DEBUG, "Invalid pairwise cipher (%d).", wpa_printf(MSG_DEBUG, "Invalid pairwise cipher (%d).",
pairwise); conf->rsn_pairwise);
return NULL; return -1;
} }
WPA_PUT_LE16(count, num_suites); WPA_PUT_LE16(count, num_suites);
@ -180,102 +184,102 @@ static u8 * rsne_write_data(u8 *buf, size_t len, u8 *pos, int group,
} }
#endif /* CONFIG_RSN_TESTING */ #endif /* CONFIG_RSN_TESTING */
if (key_mgmt & WPA_KEY_MGMT_IEEE8021X) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X); RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
num_suites++; num_suites++;
} }
if (key_mgmt & WPA_KEY_MGMT_PSK) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X); RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
num_suites++; num_suites++;
} }
#ifdef CONFIG_IEEE80211R_AP #ifdef CONFIG_IEEE80211R_AP
if (key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X); RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
num_suites++; num_suites++;
} }
#ifdef CONFIG_SHA384 #ifdef CONFIG_SHA384
if (key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X_SHA384) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X_SHA384) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X_SHA384); RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X_SHA384);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
num_suites++; num_suites++;
} }
#endif /* CONFIG_SHA384 */ #endif /* CONFIG_SHA384 */
if (key_mgmt & WPA_KEY_MGMT_FT_PSK) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_PSK) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_PSK); RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_PSK);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
num_suites++; num_suites++;
} }
#endif /* CONFIG_IEEE80211R_AP */ #endif /* CONFIG_IEEE80211R_AP */
#ifdef CONFIG_SHA384 #ifdef CONFIG_SHA384
if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA384) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA384) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SHA384); RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SHA384);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
num_suites++; num_suites++;
} }
#endif /* CONFIG_SHA384 */ #endif /* CONFIG_SHA384 */
if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SHA256); RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SHA256);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
num_suites++; num_suites++;
} }
if (key_mgmt & WPA_KEY_MGMT_PSK_SHA256) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK_SHA256) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_SHA256); RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_SHA256);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
num_suites++; num_suites++;
} }
#ifdef CONFIG_SAE #ifdef CONFIG_SAE
if (key_mgmt & WPA_KEY_MGMT_SAE) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_SAE) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE); RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
num_suites++; num_suites++;
} }
if (key_mgmt & WPA_KEY_MGMT_SAE_EXT_KEY) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_SAE_EXT_KEY) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE_EXT_KEY); RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_SAE_EXT_KEY);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
num_suites++; num_suites++;
} }
if (key_mgmt & WPA_KEY_MGMT_FT_SAE) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_SAE) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE); RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
num_suites++; num_suites++;
} }
if (key_mgmt & WPA_KEY_MGMT_FT_SAE_EXT_KEY) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_SAE_EXT_KEY) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE_EXT_KEY); RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_SAE_EXT_KEY);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
num_suites++; num_suites++;
} }
#endif /* CONFIG_SAE */ #endif /* CONFIG_SAE */
if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B); RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
num_suites++; num_suites++;
} }
if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192); RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
num_suites++; num_suites++;
} }
#ifdef CONFIG_FILS #ifdef CONFIG_FILS
if (key_mgmt & WPA_KEY_MGMT_FILS_SHA256) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FILS_SHA256) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA256); RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA256);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
num_suites++; num_suites++;
} }
if (key_mgmt & WPA_KEY_MGMT_FILS_SHA384) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FILS_SHA384) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA384); RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FILS_SHA384);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
num_suites++; num_suites++;
} }
#ifdef CONFIG_IEEE80211R_AP #ifdef CONFIG_IEEE80211R_AP
if (key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA256) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA256) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_FILS_SHA256); RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_FILS_SHA256);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
num_suites++; num_suites++;
} }
if (key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA384) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_FILS_SHA384) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_FILS_SHA384); RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_FILS_SHA384);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
num_suites++; num_suites++;
@ -283,28 +287,28 @@ static u8 * rsne_write_data(u8 *buf, size_t len, u8 *pos, int group,
#endif /* CONFIG_IEEE80211R_AP */ #endif /* CONFIG_IEEE80211R_AP */
#endif /* CONFIG_FILS */ #endif /* CONFIG_FILS */
#ifdef CONFIG_OWE #ifdef CONFIG_OWE
if (key_mgmt & WPA_KEY_MGMT_OWE) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_OWE); RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_OWE);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
num_suites++; num_suites++;
} }
#endif /* CONFIG_OWE */ #endif /* CONFIG_OWE */
#ifdef CONFIG_DPP #ifdef CONFIG_DPP
if (key_mgmt & WPA_KEY_MGMT_DPP) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_DPP); RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_DPP);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
num_suites++; num_suites++;
} }
#endif /* CONFIG_DPP */ #endif /* CONFIG_DPP */
#ifdef CONFIG_HS20 #ifdef CONFIG_HS20
if (key_mgmt & WPA_KEY_MGMT_OSEN) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_OSEN) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_OSEN); RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_OSEN);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
num_suites++; num_suites++;
} }
#endif /* CONFIG_HS20 */ #endif /* CONFIG_HS20 */
#ifdef CONFIG_PASN #ifdef CONFIG_PASN
if (key_mgmt & WPA_KEY_MGMT_PASN) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PASN) {
RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PASN); RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PASN);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
num_suites++; num_suites++;
@ -321,18 +325,18 @@ static u8 * rsne_write_data(u8 *buf, size_t len, u8 *pos, int group,
if (num_suites == 0) { if (num_suites == 0) {
wpa_printf(MSG_DEBUG, "Invalid key management type (%d).", wpa_printf(MSG_DEBUG, "Invalid key management type (%d).",
key_mgmt); conf->wpa_key_mgmt);
return NULL; return -1;
} }
WPA_PUT_LE16(count, num_suites); WPA_PUT_LE16(count, num_suites);
/* RSN Capabilities */ /* RSN Capabilities */
WPA_PUT_LE16(pos, rsn_capab); WPA_PUT_LE16(pos, wpa_own_rsn_capab(conf));
pos += 2; pos += 2;
if (pmkid) { if (pmkid) {
if (2 + PMKID_LEN > buf + len - pos) if (2 + PMKID_LEN > buf + len - pos)
return NULL; return -1;
/* PMKID Count */ /* PMKID Count */
WPA_PUT_LE16(pos, 1); WPA_PUT_LE16(pos, 1);
pos += 2; pos += 2;
@ -340,19 +344,18 @@ static u8 * rsne_write_data(u8 *buf, size_t len, u8 *pos, int group,
pos += PMKID_LEN; pos += PMKID_LEN;
} }
if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION &&
if (mfp != NO_MGMT_FRAME_PROTECTION && conf->group_mgmt_cipher != WPA_CIPHER_AES_128_CMAC) {
group_mgmt_cipher != WPA_CIPHER_AES_128_CMAC) {
if (2 + 4 > buf + len - pos) if (2 + 4 > buf + len - pos)
return NULL; return -1;
if (!pmkid) { if (pmkid == NULL) {
/* PMKID Count */ /* PMKID Count */
WPA_PUT_LE16(pos, 0); WPA_PUT_LE16(pos, 0);
pos += 2; pos += 2;
} }
/* Management Group Cipher Suite */ /* Management Group Cipher Suite */
switch (group_mgmt_cipher) { switch (conf->group_mgmt_cipher) {
case WPA_CIPHER_AES_128_CMAC: case WPA_CIPHER_AES_128_CMAC:
RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC); RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
break; break;
@ -368,8 +371,8 @@ static u8 * rsne_write_data(u8 *buf, size_t len, u8 *pos, int group,
default: default:
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"Invalid group management cipher (0x%x)", "Invalid group management cipher (0x%x)",
group_mgmt_cipher); conf->group_mgmt_cipher);
return NULL; return -1;
} }
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
} }
@ -381,12 +384,12 @@ static u8 * rsne_write_data(u8 *buf, size_t len, u8 *pos, int group,
* the element. * the element.
*/ */
int pmkid_count_set = pmkid != NULL; int pmkid_count_set = pmkid != NULL;
if (mfp != NO_MGMT_FRAME_PROTECTION) if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION)
pmkid_count_set = 1; pmkid_count_set = 1;
/* PMKID Count */ /* PMKID Count */
WPA_PUT_LE16(pos, 0); WPA_PUT_LE16(pos, 0);
pos += 2; pos += 2;
if (mfp == NO_MGMT_FRAME_PROTECTION) { if (conf->ieee80211w == NO_MGMT_FRAME_PROTECTION) {
/* Management Group Cipher Suite */ /* Management Group Cipher Suite */
RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC); RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC);
pos += RSN_SELECTOR_LEN; pos += RSN_SELECTOR_LEN;
@ -396,27 +399,6 @@ static u8 * rsne_write_data(u8 *buf, size_t len, u8 *pos, int group,
pos += 17; pos += 17;
} }
#endif /* CONFIG_RSN_TESTING */ #endif /* CONFIG_RSN_TESTING */
return pos;
}
int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,
const u8 *pmkid)
{
struct rsn_ie_hdr *hdr;
u8 *pos;
hdr = (struct rsn_ie_hdr *) buf;
hdr->elem_id = WLAN_EID_RSN;
WPA_PUT_LE16(hdr->version, RSN_VERSION);
pos = (u8 *) (hdr + 1);
pos = rsne_write_data(buf, len, pos, conf->wpa_group,
conf->rsn_pairwise, conf->wpa_key_mgmt,
wpa_own_rsn_capab(conf, conf->ieee80211w), pmkid,
conf->ieee80211w, conf->group_mgmt_cipher);
if (!pos)
return -1;
hdr->len = (pos - buf) - 2; hdr->len = (pos - buf) - 2;
@ -424,74 +406,16 @@ int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len,
} }
static int wpa_write_rsne_override(struct wpa_auth_config *conf, u8 *buf, int wpa_write_rsnxe(struct wpa_auth_config *conf, u8 *buf, size_t len)
size_t len)
{ {
u8 *pos, *len_pos; u8 *pos = buf;
u32 capab = 0, tmp;
size_t flen;
pos = buf; if (wpa_key_mgmt_sae(conf->wpa_key_mgmt) &&
*pos++ = WLAN_EID_VENDOR_SPECIFIC;
len_pos = pos++;
WPA_PUT_BE32(pos, RSNE_OVERRIDE_IE_VENDOR_TYPE);
pos += 4;
WPA_PUT_LE16(pos, RSN_VERSION);
pos += 2;
pos = rsne_write_data(buf, len, pos, conf->wpa_group,
conf->rsn_override_pairwise,
conf->rsn_override_key_mgmt,
wpa_own_rsn_capab(conf, conf->rsn_override_mfp),
NULL, conf->rsn_override_mfp,
conf->group_mgmt_cipher);
if (!pos)
return -1;
*len_pos = (pos - buf) - 2;
return pos - buf;
}
static int wpa_write_rsne_override_2(struct wpa_auth_config *conf, u8 *buf,
size_t len)
{
u8 *pos, *len_pos;
pos = buf;
*pos++ = WLAN_EID_VENDOR_SPECIFIC;
len_pos = pos++;
WPA_PUT_BE32(pos, RSNE_OVERRIDE_2_IE_VENDOR_TYPE);
pos += 4;
WPA_PUT_LE16(pos, RSN_VERSION);
pos += 2;
pos = rsne_write_data(buf, len, pos, conf->wpa_group,
conf->rsn_override_pairwise_2,
conf->rsn_override_key_mgmt_2,
wpa_own_rsn_capab(conf, conf->rsn_override_mfp_2),
NULL, conf->rsn_override_mfp_2,
conf->group_mgmt_cipher);
if (!pos)
return -1;
*len_pos = (pos - buf) - 2;
return pos - buf;
}
static u32 rsnxe_capab(struct wpa_auth_config *conf, int key_mgmt)
{
u32 capab = 0;
if (wpa_key_mgmt_sae(key_mgmt) &&
(conf->sae_pwe == SAE_PWE_HASH_TO_ELEMENT || (conf->sae_pwe == SAE_PWE_HASH_TO_ELEMENT ||
conf->sae_pwe == SAE_PWE_BOTH || conf->sae_pk || conf->sae_pwe == SAE_PWE_BOTH || conf->sae_pk ||
wpa_key_mgmt_sae_ext_key(key_mgmt))) { wpa_key_mgmt_sae_ext_key(conf->wpa_key_mgmt))) {
capab |= BIT(WLAN_RSNX_CAPAB_SAE_H2E); capab |= BIT(WLAN_RSNX_CAPAB_SAE_H2E);
#ifdef CONFIG_SAE_PK #ifdef CONFIG_SAE_PK
if (conf->sae_pk) if (conf->sae_pk)
@ -508,18 +432,6 @@ static u32 rsnxe_capab(struct wpa_auth_config *conf, int key_mgmt)
if (conf->ssid_protection) if (conf->ssid_protection)
capab |= BIT(WLAN_RSNX_CAPAB_SSID_PROTECTION); capab |= BIT(WLAN_RSNX_CAPAB_SSID_PROTECTION);
return capab;
}
int wpa_write_rsnxe(struct wpa_auth_config *conf, u8 *buf, size_t len)
{
u8 *pos = buf;
u32 capab = 0, tmp;
size_t flen;
capab = rsnxe_capab(conf, conf->wpa_key_mgmt);
if (!capab) if (!capab)
return 0; /* no supported extended RSN capabilities */ return 0; /* no supported extended RSN capabilities */
tmp = capab; tmp = capab;
@ -543,42 +455,6 @@ int wpa_write_rsnxe(struct wpa_auth_config *conf, u8 *buf, size_t len)
} }
static int wpa_write_rsnxe_override(struct wpa_auth_config *conf, u8 *buf,
size_t len)
{
u8 *pos = buf;
u32 capab, tmp;
size_t flen;
capab = rsnxe_capab(conf, conf->rsn_override_key_mgmt |
conf->rsn_override_key_mgmt_2);
if (!capab)
return 0; /* no supported extended RSN capabilities */
tmp = capab;
flen = 0;
while (tmp) {
flen++;
tmp >>= 8;
}
if (len < 2 + flen)
return -1;
capab |= flen - 1; /* bit 0-3 = Field length (n - 1) */
*pos++ = WLAN_EID_VENDOR_SPECIFIC;
*pos++ = 4 + flen;
WPA_PUT_BE32(pos, RSNXE_OVERRIDE_IE_VENDOR_TYPE);
pos += 4;
while (capab) {
*pos++ = capab & 0xff;
capab >>= 8;
}
return pos - buf;
}
static u8 * wpa_write_osen(struct wpa_auth_config *conf, u8 *eid) static u8 * wpa_write_osen(struct wpa_auth_config *conf, u8 *eid)
{ {
u8 *len; u8 *len;
@ -632,7 +508,7 @@ static u8 * wpa_write_osen(struct wpa_auth_config *conf, u8 *eid)
int wpa_auth_gen_wpa_ie(struct wpa_authenticator *wpa_auth) int wpa_auth_gen_wpa_ie(struct wpa_authenticator *wpa_auth)
{ {
u8 *pos, buf[1500]; u8 *pos, buf[128];
int res; int res;
#ifdef CONFIG_TESTING_OPTIONS #ifdef CONFIG_TESTING_OPTIONS
@ -658,54 +534,17 @@ int wpa_auth_gen_wpa_ie(struct wpa_authenticator *wpa_auth)
pos = wpa_write_osen(&wpa_auth->conf, pos); pos = wpa_write_osen(&wpa_auth->conf, pos);
} }
if (wpa_auth->conf.wpa & WPA_PROTO_RSN) { if (wpa_auth->conf.wpa & WPA_PROTO_RSN) {
#ifdef CONFIG_TESTING_OPTIONS
if (wpa_auth->conf.rsne_override_set) {
wpa_hexdump(MSG_DEBUG,
"RSN: Forced own RSNE for testing",
wpa_auth->conf.rsne_override,
wpa_auth->conf.rsne_override_len);
if (sizeof(buf) - (pos - buf) <
wpa_auth->conf.rsne_override_len)
return -1;
os_memcpy(pos, wpa_auth->conf.rsne_override,
wpa_auth->conf.rsne_override_len);
pos += wpa_auth->conf.rsne_override_len;
goto rsnxe;
}
#endif /* CONFIG_TESTING_OPTIONS */
res = wpa_write_rsn_ie(&wpa_auth->conf, res = wpa_write_rsn_ie(&wpa_auth->conf,
pos, buf + sizeof(buf) - pos, NULL); pos, buf + sizeof(buf) - pos, NULL);
if (res < 0) if (res < 0)
return res; return res;
pos += res; pos += res;
#ifdef CONFIG_TESTING_OPTIONS
rsnxe:
if (wpa_auth->conf.rsnxe_override_set) {
wpa_hexdump(MSG_DEBUG,
"RSN: Forced own RSNXE for testing",
wpa_auth->conf.rsnxe_override,
wpa_auth->conf.rsnxe_override_len);
if (sizeof(buf) - (pos - buf) <
wpa_auth->conf.rsnxe_override_len)
return -1;
os_memcpy(pos, wpa_auth->conf.rsnxe_override,
wpa_auth->conf.rsnxe_override_len);
pos += wpa_auth->conf.rsnxe_override_len;
goto fte;
}
#endif /* CONFIG_TESTING_OPTIONS */
if (wpa_auth->conf.rsn_override_omit_rsnxe)
res = 0;
else
res = wpa_write_rsnxe(&wpa_auth->conf, pos, res = wpa_write_rsnxe(&wpa_auth->conf, pos,
buf + sizeof(buf) - pos); buf + sizeof(buf) - pos);
if (res < 0) if (res < 0)
return res; return res;
pos += res; pos += res;
} }
#ifdef CONFIG_TESTING_OPTIONS
fte:
#endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_IEEE80211R_AP #ifdef CONFIG_IEEE80211R_AP
if (wpa_key_mgmt_ft(wpa_auth->conf.wpa_key_mgmt)) { if (wpa_key_mgmt_ft(wpa_auth->conf.wpa_key_mgmt)) {
res = wpa_write_mdie(&wpa_auth->conf, pos, res = wpa_write_mdie(&wpa_auth->conf, pos,
@ -722,87 +561,7 @@ fte:
return res; return res;
pos += res; pos += res;
} }
if ((wpa_auth->conf.wpa & WPA_PROTO_RSN) &&
wpa_auth->conf.rsn_override_key_mgmt) {
#ifdef CONFIG_TESTING_OPTIONS
if (wpa_auth->conf.rsnoe_override_set) {
wpa_hexdump(MSG_DEBUG,
"RSN: Forced own RSNOE for testing",
wpa_auth->conf.rsnoe_override,
wpa_auth->conf.rsnoe_override_len);
if (sizeof(buf) - (pos - buf) <
wpa_auth->conf.rsnoe_override_len)
return -1;
os_memcpy(pos, wpa_auth->conf.rsnoe_override,
wpa_auth->conf.rsnoe_override_len);
pos += wpa_auth->conf.rsnoe_override_len;
goto rsno2e;
}
#endif /* CONFIG_TESTING_OPTIONS */
res = wpa_write_rsne_override(&wpa_auth->conf,
pos, buf + sizeof(buf) - pos);
if (res < 0)
return res;
pos += res;
}
#ifdef CONFIG_TESTING_OPTIONS
rsno2e:
#endif /* CONFIG_TESTING_OPTIONS */
if ((wpa_auth->conf.wpa & WPA_PROTO_RSN) &&
wpa_auth->conf.rsn_override_key_mgmt_2) {
#ifdef CONFIG_TESTING_OPTIONS
if (wpa_auth->conf.rsno2e_override_set) {
wpa_hexdump(MSG_DEBUG,
"RSN: Forced own RSNO2E for testing",
wpa_auth->conf.rsno2e_override,
wpa_auth->conf.rsno2e_override_len);
if (sizeof(buf) - (pos - buf) <
wpa_auth->conf.rsno2e_override_len)
return -1;
os_memcpy(pos, wpa_auth->conf.rsno2e_override,
wpa_auth->conf.rsno2e_override_len);
pos += wpa_auth->conf.rsno2e_override_len;
goto rsnxoe;
}
#endif /* CONFIG_TESTING_OPTIONS */
res = wpa_write_rsne_override_2(&wpa_auth->conf, pos,
buf + sizeof(buf) - pos);
if (res < 0)
return res;
pos += res;
}
#ifdef CONFIG_TESTING_OPTIONS
rsnxoe:
#endif /* CONFIG_TESTING_OPTIONS */
if ((wpa_auth->conf.wpa & WPA_PROTO_RSN) &&
(wpa_auth->conf.rsn_override_key_mgmt ||
wpa_auth->conf.rsn_override_key_mgmt_2)) {
#ifdef CONFIG_TESTING_OPTIONS
if (wpa_auth->conf.rsnxoe_override_set) {
wpa_hexdump(MSG_DEBUG,
"RSN: Forced own RSNXOE for testing",
wpa_auth->conf.rsnxoe_override,
wpa_auth->conf.rsnxoe_override_len);
if (sizeof(buf) - (pos - buf) <
wpa_auth->conf.rsnxoe_override_len)
return -1;
os_memcpy(pos, wpa_auth->conf.rsnxoe_override,
wpa_auth->conf.rsnxoe_override_len);
pos += wpa_auth->conf.rsnxoe_override_len;
goto done;
}
#endif /* CONFIG_TESTING_OPTIONS */
res = wpa_write_rsnxe_override(&wpa_auth->conf, pos,
buf + sizeof(buf) - pos);
if (res < 0)
return res;
pos += res;
}
#ifdef CONFIG_TESTING_OPTIONS
done:
#endif /* CONFIG_TESTING_OPTIONS */
wpa_hexdump(MSG_DEBUG, "RSN: Own IEs", buf, pos - buf);
os_free(wpa_auth->wpa_ie); os_free(wpa_auth->wpa_ie);
wpa_auth->wpa_ie = os_malloc(pos - buf); wpa_auth->wpa_ie = os_malloc(pos - buf);
if (wpa_auth->wpa_ie == NULL) if (wpa_auth->wpa_ie == NULL)
@ -1014,12 +773,6 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
return WPA_INVALID_GROUP; return WPA_INVALID_GROUP;
} }
if (sm->rsn_override_2)
key_mgmt = data.key_mgmt &
wpa_auth->conf.rsn_override_key_mgmt_2;
else if (sm->rsn_override)
key_mgmt = data.key_mgmt & wpa_auth->conf.rsn_override_key_mgmt;
else
key_mgmt = data.key_mgmt & wpa_auth->conf.wpa_key_mgmt; key_mgmt = data.key_mgmt & wpa_auth->conf.wpa_key_mgmt;
if (!key_mgmt) { if (!key_mgmt) {
wpa_printf(MSG_DEBUG, "Invalid WPA key mgmt (0x%x) from " wpa_printf(MSG_DEBUG, "Invalid WPA key mgmt (0x%x) from "
@ -1089,13 +842,7 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
else else
sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK; sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
if (version == WPA_PROTO_RSN && sm->rsn_override_2) if (version == WPA_PROTO_RSN)
ciphers = data.pairwise_cipher &
wpa_auth->conf.rsn_override_pairwise_2;
else if (version == WPA_PROTO_RSN && sm->rsn_override)
ciphers = data.pairwise_cipher &
wpa_auth->conf.rsn_override_pairwise;
else if (version == WPA_PROTO_RSN)
ciphers = data.pairwise_cipher & wpa_auth->conf.rsn_pairwise; ciphers = data.pairwise_cipher & wpa_auth->conf.rsn_pairwise;
else else
ciphers = data.pairwise_cipher & wpa_auth->conf.wpa_pairwise; ciphers = data.pairwise_cipher & wpa_auth->conf.wpa_pairwise;
@ -1482,7 +1229,7 @@ bool wpa_auth_write_fd_rsn_info(struct wpa_authenticator *wpa_auth,
return false; return false;
/* RSN Capability (B0..B15) */ /* RSN Capability (B0..B15) */
WPA_PUT_LE16(pos, wpa_own_rsn_capab(conf, conf->ieee80211w)); WPA_PUT_LE16(pos, wpa_own_rsn_capab(conf));
pos += 2; pos += 2;
/* Group Data Cipher Suite Selector (B16..B21) */ /* Group Data Cipher Suite Selector (B16..B21) */

View file

@ -83,16 +83,13 @@ _make_dirs:
@mkdir -p $(sort $(_DIRS)) @mkdir -p $(sort $(_DIRS))
$(BUILDDIR)/$(PROJ)/src/%.o: $(ROOTDIR)src/%.c $(CONFIG_FILE) | _make_dirs $(BUILDDIR)/$(PROJ)/src/%.o: $(ROOTDIR)src/%.c $(CONFIG_FILE) | _make_dirs
@echo $(CURDIR): '$(CC) -c -o $@ $(CFLAGS) $<' >$@.cmd
$(Q)$(CC) -c -o $@ $(CFLAGS) $< $(Q)$(CC) -c -o $@ $(CFLAGS) $<
@$(E) " CC " $< @$(E) " CC " $<
$(BUILDDIR)/$(PROJ)/%.o: %.c $(CONFIG_FILE) | _make_dirs $(BUILDDIR)/$(PROJ)/%.o: %.c $(CONFIG_FILE) | _make_dirs
@echo $(CURDIR): '$(CC) -c -o $@ $(CFLAGS) $<' >$@.cmd
$(Q)$(CC) -c -o $@ $(CFLAGS) $< $(Q)$(CC) -c -o $@ $(CFLAGS) $<
@$(E) " CC " $< @$(E) " CC " $<
# for the fuzzing tests # for the fuzzing tests
$(BUILDDIR)/$(PROJ)/wpa_supplicant/%.o: $(ROOTDIR)wpa_supplicant/%.c $(CONFIG_FILE) | _make_dirs $(BUILDDIR)/$(PROJ)/wpa_supplicant/%.o: $(ROOTDIR)wpa_supplicant/%.c $(CONFIG_FILE) | _make_dirs
@echo $(CURDIR): '$(CC) -c -o $@ $(CFLAGS) $<' >$@.cmd
$(Q)$(CC) -c -o $@ $(CFLAGS) $< $(Q)$(CC) -c -o $@ $(CFLAGS) $<
@$(E) " CC " $< @$(E) " CC " $<

View file

@ -532,9 +532,4 @@ enum sae_pwe {
SAE_PWE_NOT_SET = 4, SAE_PWE_NOT_SET = 4,
}; };
#define USEC_80211_TU 1024
#define USEC_TO_TU(m) ((m) / USEC_80211_TU)
#define TU_TO_USEC(m) ((m) * USEC_80211_TU)
#endif /* DEFS_H */ #endif /* DEFS_H */

View file

@ -1035,10 +1035,6 @@ struct wpabuf * dpp_build_conf_req_helper(struct dpp_authentication *auth,
json_value_sep(json); json_value_sep(json);
json_add_string(json, "pkcs10", csr); json_add_string(json, "pkcs10", csr);
} }
#ifdef CONFIG_DPP3
json_value_sep(json);
json_add_int(json, "capabilities", DPP_ENROLLEE_CAPAB_SAE_PW_ID);
#endif /* CONFIG_DPP3 */
if (extra_name && extra_value && extra_name[0] && extra_value[0]) { if (extra_name && extra_value && extra_name[0] && extra_value[0]) {
json_value_sep(json); json_value_sep(json);
wpabuf_printf(json, "\"%s\":%s", extra_name, extra_value); wpabuf_printf(json, "\"%s\":%s", extra_name, extra_value);
@ -1143,18 +1139,8 @@ int dpp_configuration_valid(const struct dpp_configuration *conf)
return 0; return 0;
if (dpp_akm_psk(conf->akm) && !conf->passphrase && !conf->psk_set) if (dpp_akm_psk(conf->akm) && !conf->passphrase && !conf->psk_set)
return 0; return 0;
if (dpp_akm_psk(conf->akm) && conf->passphrase) {
size_t len = os_strlen(conf->passphrase);
if (len > 63 || len < 8)
return 0;
}
if (dpp_akm_sae(conf->akm) && !conf->passphrase) if (dpp_akm_sae(conf->akm) && !conf->passphrase)
return 0; return 0;
#ifdef CONFIG_DPP3
if (conf->idpass && (!conf->passphrase || !dpp_akm_sae(conf->akm)))
return 0;
#endif /* CONFIG_DPP3 */
return 1; return 1;
} }
@ -1164,9 +1150,6 @@ void dpp_configuration_free(struct dpp_configuration *conf)
if (!conf) if (!conf)
return; return;
str_clear_free(conf->passphrase); str_clear_free(conf->passphrase);
#ifdef CONFIG_DPP3
os_free(conf->idpass);
#endif /* CONFIG_DPP3 */
os_free(conf->group_id); os_free(conf->group_id);
os_free(conf->csrattrs); os_free(conf->csrattrs);
os_free(conf->extra_name); os_free(conf->extra_name);
@ -1245,28 +1228,14 @@ static int dpp_configuration_parse_helper(struct dpp_authentication *auth,
end = os_strchr(pos, ' '); end = os_strchr(pos, ' ');
pass_len = end ? (size_t) (end - pos) : os_strlen(pos); pass_len = end ? (size_t) (end - pos) : os_strlen(pos);
pass_len /= 2; pass_len /= 2;
if (pass_len > 63 || pass_len < 8)
goto fail;
conf->passphrase = os_zalloc(pass_len + 1); conf->passphrase = os_zalloc(pass_len + 1);
if (!conf->passphrase || if (!conf->passphrase ||
hexstr2bin(pos, (u8 *) conf->passphrase, pass_len) < 0) hexstr2bin(pos, (u8 *) conf->passphrase, pass_len) < 0)
goto fail; goto fail;
} }
#ifdef CONFIG_DPP3
pos = os_strstr(cmd, " idpass=");
if (pos) {
size_t idpass_len;
pos += 8;
end = os_strchr(pos, ' ');
idpass_len = end ? (size_t) (end - pos) : os_strlen(pos);
idpass_len /= 2;
conf->idpass = os_zalloc(idpass_len + 1);
if (!conf->idpass ||
hexstr2bin(pos, (u8 *) conf->idpass, idpass_len) < 0)
goto fail;
}
#endif /* CONFIG_DPP3 */
pos = os_strstr(cmd, " psk="); pos = os_strstr(cmd, " psk=");
if (pos) { if (pos) {
pos += 5; pos += 5;
@ -1626,13 +1595,6 @@ static void dpp_build_legacy_cred_params(struct wpabuf *buf,
if (conf->passphrase && os_strlen(conf->passphrase) < 64) { if (conf->passphrase && os_strlen(conf->passphrase) < 64) {
json_add_string_escape(buf, "pass", conf->passphrase, json_add_string_escape(buf, "pass", conf->passphrase,
os_strlen(conf->passphrase)); os_strlen(conf->passphrase));
#ifdef CONFIG_DPP3
if (conf->idpass) {
json_value_sep(buf);
json_add_string_escape(buf, "idpass", conf->idpass,
os_strlen(conf->idpass));
}
#endif /* CONFIG_DPP3 */
} else if (conf->psk_set) { } else if (conf->psk_set) {
char psk[2 * sizeof(conf->psk) + 1]; char psk[2 * sizeof(conf->psk) + 1];
@ -1955,16 +1917,6 @@ dpp_build_conf_obj_legacy(struct dpp_authentication *auth,
const char *akm_str; const char *akm_str;
size_t len = 1000; size_t len = 1000;
#ifdef CONFIG_DPP3
if (conf->idpass &&
!(auth->enrollee_capabilities & DPP_ENROLLEE_CAPAB_SAE_PW_ID)) {
wpa_printf(MSG_DEBUG,
"DPP: Enrollee does not support SAE Password Identifier - cannot generate config object");
return NULL;
}
#endif /* CONFIG_DPP3 */
if (conf->extra_name && conf->extra_value) if (conf->extra_name && conf->extra_value)
len += 10 + os_strlen(conf->extra_name) + len += 10 + os_strlen(conf->extra_name) +
os_strlen(conf->extra_value); os_strlen(conf->extra_value);
@ -2583,18 +2535,6 @@ dpp_conf_req_rx(struct dpp_authentication *auth, const u8 *attr_start,
cont: cont:
#endif /* CONFIG_DPP2 */ #endif /* CONFIG_DPP2 */
#ifdef CONFIG_DPP3
token = json_get_member(root, "capabilities");
if (token && token->type == JSON_NUMBER) {
wpa_printf(MSG_DEBUG, "DPP: capabilities = 0x%x",
token->number);
wpa_msg(auth->msg_ctx, MSG_INFO,
DPP_EVENT_ENROLLEE_CAPABILITY "%d",
token->number);
auth->enrollee_capabilities = token->number;
}
#endif /* CONFIG_DPP3 */
resp = dpp_build_conf_resp(auth, e_nonce, e_nonce_len, netrole, resp = dpp_build_conf_resp(auth, e_nonce, e_nonce_len, netrole,
cert_req); cert_req);
@ -2618,25 +2558,13 @@ static int dpp_parse_cred_legacy(struct dpp_config_obj *conf,
if (pass && pass->type == JSON_STRING) { if (pass && pass->type == JSON_STRING) {
size_t len = os_strlen(pass->string); size_t len = os_strlen(pass->string);
#ifdef CONFIG_DPP3
struct json_token *saepi = json_get_member(cred, "idpass");
#endif /* CONFIG_DPP3 */
wpa_hexdump_ascii_key(MSG_DEBUG, "DPP: Legacy passphrase", wpa_hexdump_ascii_key(MSG_DEBUG, "DPP: Legacy passphrase",
pass->string, len); pass->string, len);
if (dpp_akm_psk(conf->akm) && (len < 8 || len > 63)) { if (len < 8 || len > 63)
wpa_printf(MSG_DEBUG,
"DPP: Unexpected pass length %zu for a config object that includes PSK",
len);
return -1; return -1;
}
os_strlcpy(conf->passphrase, pass->string, os_strlcpy(conf->passphrase, pass->string,
sizeof(conf->passphrase)); sizeof(conf->passphrase));
#ifdef CONFIG_DPP3
if (saepi && saepi->type == JSON_STRING)
os_strlcpy(conf->password_id, saepi->string,
sizeof(conf->password_id));
#endif /* CONFIG_DPP3 */
} else if (psk_hex && psk_hex->type == JSON_STRING) { } else if (psk_hex && psk_hex->type == JSON_STRING) {
if (dpp_akm_sae(conf->akm) && !dpp_akm_psk(conf->akm)) { if (dpp_akm_sae(conf->akm) && !dpp_akm_psk(conf->akm)) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,

View file

@ -134,9 +134,6 @@ enum dpp_connector_key {
#define DPP_MAX_SHARED_SECRET_LEN 66 #define DPP_MAX_SHARED_SECRET_LEN 66
#define DPP_CP_LEN 64 #define DPP_CP_LEN 64
/* DPP Configuration Request - Enrollee Capabilities */
#define DPP_ENROLLEE_CAPAB_SAE_PW_ID BIT(0)
struct dpp_curve_params { struct dpp_curve_params {
const char *name; const char *name;
size_t hash_len; size_t hash_len;
@ -263,7 +260,6 @@ struct dpp_configuration {
/* For legacy configuration */ /* For legacy configuration */
char *passphrase; char *passphrase;
char *idpass;
u8 psk[32]; u8 psk[32];
int psk_set; int psk_set;
@ -360,9 +356,6 @@ struct dpp_authentication {
u8 ssid_len; u8 ssid_len;
int ssid_charset; int ssid_charset;
char passphrase[64]; char passphrase[64];
#ifdef CONFIG_DPP3
char password_id[64];
#endif /* CONFIG_DPP3 */
u8 psk[PMK_LEN]; u8 psk[PMK_LEN];
int psk_set; int psk_set;
enum dpp_akm akm; enum dpp_akm akm;
@ -400,7 +393,6 @@ struct dpp_authentication {
char *e_name; char *e_name;
char *e_mud_url; char *e_mud_url;
int *e_band_support; int *e_band_support;
unsigned int enrollee_capabilities;
#ifdef CONFIG_TESTING_OPTIONS #ifdef CONFIG_TESTING_OPTIONS
char *config_obj_override; char *config_obj_override;
char *discovery_override; char *discovery_override;

View file

@ -1033,18 +1033,3 @@ bool is_punct_bitmap_valid(u16 bw, u16 pri_ch_bit_pos, u16 punct_bitmap)
return false; return false;
} }
bool chan_in_current_hw_info(struct hostapd_multi_hw_info *current_hw_info,
struct hostapd_channel_data *chan)
{
/* Assuming that if current_hw_info is not set full
* iface->current_mode->channels[] can be used to scan for channels,
* hence we return true.
*/
if (!current_hw_info)
return true;
return current_hw_info->start_freq <= chan->freq &&
current_hw_info->end_freq >= chan->freq;
}

View file

@ -58,7 +58,5 @@ int chan_bw_allowed(const struct hostapd_channel_data *chan, u32 bw,
int ht40_plus, int pri); int ht40_plus, int pri);
int chan_pri_allowed(const struct hostapd_channel_data *chan); int chan_pri_allowed(const struct hostapd_channel_data *chan);
bool is_punct_bitmap_valid(u16 bw, u16 pri_ch_bit_pos, u16 punct_bitmap); bool is_punct_bitmap_valid(u16 bw, u16 pri_ch_bit_pos, u16 punct_bitmap);
bool chan_in_current_hw_info(struct hostapd_multi_hw_info *current_hw_info,
struct hostapd_channel_data *chan);
#endif /* HW_FEATURES_COMMON_H */ #endif /* HW_FEATURES_COMMON_H */

View file

@ -140,28 +140,6 @@ static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen,
elems->sae_pk = pos + 4; elems->sae_pk = pos + 4;
elems->sae_pk_len = elen - 4; elems->sae_pk_len = elen - 4;
break; break;
case WFA_RSNE_OVERRIDE_OUI_TYPE:
elems->rsne_override = pos;
elems->rsne_override_len = elen;
break;
case WFA_RSNE_OVERRIDE_2_OUI_TYPE:
elems->rsne_override_2 = pos;
elems->rsne_override_2_len = elen;
break;
case WFA_RSN_SELECTION_OUI_TYPE:
if (elen < 4 + 1) {
wpa_printf(MSG_DEBUG,
"Too short RSN Selection element ignored");
return -1;
}
elems->rsn_selection = pos + 4;
elems->rsn_selection_len = elen - 4;
break;
case P2P2_OUI_TYPE:
/* Wi-Fi Alliance - P2P2 IE */
elems->p2p2_ie = pos;
elems->p2p2_ie_len = elen;
break;
default: default:
wpa_printf(MSG_MSGDUMP, "Unknown WFA " wpa_printf(MSG_MSGDUMP, "Unknown WFA "
"information element ignored " "information element ignored "
@ -3145,12 +3123,8 @@ bool ieee802_11_rsnx_capab_len(const u8 *rsnxe, size_t rsnxe_len,
bool ieee802_11_rsnx_capab(const u8 *rsnxe, unsigned int capab) bool ieee802_11_rsnx_capab(const u8 *rsnxe, unsigned int capab)
{ {
if (!rsnxe) return ieee802_11_rsnx_capab_len(rsnxe ? rsnxe + 2 : NULL,
return false; rsnxe ? rsnxe[1] : 0, capab);
if (rsnxe[0] == WLAN_EID_VENDOR_SPECIFIC && rsnxe[1] >= 4 + 1)
return ieee802_11_rsnx_capab_len(rsnxe + 2 + 4, rsnxe[1] - 4,
capab);
return ieee802_11_rsnx_capab_len(rsnxe + 2, rsnxe[1], capab);
} }

View file

@ -65,7 +65,6 @@ struct ieee802_11_elems {
const u8 *vendor_ht_cap; const u8 *vendor_ht_cap;
const u8 *vendor_vht; const u8 *vendor_vht;
const u8 *p2p; const u8 *p2p;
const u8 *p2p2_ie;
const u8 *wfd; const u8 *wfd;
const u8 *link_id; const u8 *link_id;
const u8 *interworking; const u8 *interworking;
@ -117,9 +116,6 @@ struct ieee802_11_elems {
const u8 *prior_access_mle; const u8 *prior_access_mle;
const u8 *mbssid_known_bss; const u8 *mbssid_known_bss;
const u8 *mbssid; const u8 *mbssid;
const u8 *rsne_override;
const u8 *rsne_override_2;
const u8 *rsn_selection;
u8 ssid_len; u8 ssid_len;
u8 supp_rates_len; u8 supp_rates_len;
@ -140,7 +136,6 @@ struct ieee802_11_elems {
u8 vendor_ht_cap_len; u8 vendor_ht_cap_len;
u8 vendor_vht_len; u8 vendor_vht_len;
u8 p2p_len; u8 p2p_len;
u8 p2p2_ie_len;
u8 wfd_len; u8 wfd_len;
u8 interworking_len; u8 interworking_len;
u8 qos_map_set_len; u8 qos_map_set_len;
@ -184,9 +179,6 @@ struct ieee802_11_elems {
size_t prior_access_mle_len; size_t prior_access_mle_len;
u8 mbssid_known_bss_len; u8 mbssid_known_bss_len;
u8 mbssid_len; u8 mbssid_len;
size_t rsne_override_len;
size_t rsne_override_2_len;
size_t rsn_selection_len;
struct mb_ies_info mb_ies; struct mb_ies_info mb_ies;

View file

@ -504,7 +504,6 @@
#define WLAN_EID_EXT_HE_MU_EDCA_PARAMS 38 #define WLAN_EID_EXT_HE_MU_EDCA_PARAMS 38
#define WLAN_EID_EXT_SPATIAL_REUSE 39 #define WLAN_EID_EXT_SPATIAL_REUSE 39
#define WLAN_EID_EXT_COLOR_CHANGE_ANNOUNCEMENT 42 #define WLAN_EID_EXT_COLOR_CHANGE_ANNOUNCEMENT 42
#define WLAN_EID_EXT_MAX_CHANNEL_SWITCH_TIME 52
#define WLAN_EID_EXT_OCV_OCI 54 #define WLAN_EID_EXT_OCV_OCI 54
#define WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION 55 #define WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION 55
#define WLAN_EID_EXT_NON_INHERITANCE 56 #define WLAN_EID_EXT_NON_INHERITANCE 56
@ -525,7 +524,6 @@
#define WLAN_EID_EXT_MULTI_LINK_TRAFFIC_INDICATION 110 #define WLAN_EID_EXT_MULTI_LINK_TRAFFIC_INDICATION 110
#define WLAN_EID_EXT_QOS_CHARACTERISTICS 113 #define WLAN_EID_EXT_QOS_CHARACTERISTICS 113
#define WLAN_EID_EXT_AKM_SUITE_SELECTOR 114 #define WLAN_EID_EXT_AKM_SUITE_SELECTOR 114
#define WLAN_EID_EXT_BANDWIDTH_INDICATION 135
/* Extended Capabilities field */ /* Extended Capabilities field */
#define WLAN_EXT_CAPAB_20_40_COEX 0 #define WLAN_EXT_CAPAB_20_40_COEX 0
@ -1427,7 +1425,6 @@ struct ieee80211_ampe_ie {
#define WPS_IE_VENDOR_TYPE 0x0050f204 #define WPS_IE_VENDOR_TYPE 0x0050f204
#define OUI_WFA 0x506f9a #define OUI_WFA 0x506f9a
#define P2P_IE_VENDOR_TYPE 0x506f9a09 #define P2P_IE_VENDOR_TYPE 0x506f9a09
#define P2P2_IE_VENDOR_TYPE 0x506f9a28
#define WFD_IE_VENDOR_TYPE 0x506f9a0a #define WFD_IE_VENDOR_TYPE 0x506f9a0a
#define WFD_OUI_TYPE 10 #define WFD_OUI_TYPE 10
#define HS20_IE_VENDOR_TYPE 0x506f9a10 #define HS20_IE_VENDOR_TYPE 0x506f9a10
@ -1449,14 +1446,6 @@ struct ieee80211_ampe_ie {
#define QM_IE_OUI_TYPE 0x22 #define QM_IE_OUI_TYPE 0x22
#define WFA_CAPA_IE_VENDOR_TYPE 0x506f9a23 #define WFA_CAPA_IE_VENDOR_TYPE 0x506f9a23
#define WFA_CAPA_OUI_TYPE 0x23 #define WFA_CAPA_OUI_TYPE 0x23
#define WFA_RSNE_OVERRIDE_OUI_TYPE 0x29
#define WFA_RSNE_OVERRIDE_2_OUI_TYPE 0x2a
#define WFA_RSNXE_OVERRIDE_OUI_TYPE 0x2b
#define WFA_RSN_SELECTION_OUI_TYPE 0x2c
#define RSNE_OVERRIDE_IE_VENDOR_TYPE 0x506f9a29
#define RSNE_OVERRIDE_2_IE_VENDOR_TYPE 0x506f9a2a
#define RSNXE_OVERRIDE_IE_VENDOR_TYPE 0x506f9a2b
#define RSN_SELECTION_IE_VENDOR_TYPE 0x506f9a2c
#define MULTI_AP_SUB_ELEM_TYPE 0x06 #define MULTI_AP_SUB_ELEM_TYPE 0x06
#define MULTI_AP_PROFILE_SUB_ELEM_TYPE 0x07 #define MULTI_AP_PROFILE_SUB_ELEM_TYPE 0x07
@ -1721,7 +1710,6 @@ enum mbo_transition_reject_reason {
/* Wi-Fi Direct (P2P) */ /* Wi-Fi Direct (P2P) */
#define P2P_OUI_TYPE 9 #define P2P_OUI_TYPE 9
#define P2P2_OUI_TYPE 0x28
enum p2p_attr_id { enum p2p_attr_id {
P2P_ATTR_STATUS = 0, P2P_ATTR_STATUS = 0,
@ -1752,13 +1740,6 @@ enum p2p_attr_id {
P2P_ATTR_SESSION_ID = 26, P2P_ATTR_SESSION_ID = 26,
P2P_ATTR_FEATURE_CAPABILITY = 27, P2P_ATTR_FEATURE_CAPABILITY = 27,
P2P_ATTR_PERSISTENT_GROUP = 28, P2P_ATTR_PERSISTENT_GROUP = 28,
P2P_ATTR_CAPABILITY_EXTENSION = 29,
P2P_ATTR_WLAN_AP_INFORMATION = 30,
P2P_ATTR_DEVICE_IDENTITY_KEY = 31,
P2P_ATTR_DEVICE_IDENTITY_RESOLUTION = 32,
P2P_ATTR_PAIRING_AND_BOOTSTRAPPING = 33,
P2P_ATTR_PASSWORD = 34,
P2P_ATTR_ACTION_FRAME_WRAPPER = 35,
P2P_ATTR_VENDOR_SPECIFIC = 221 P2P_ATTR_VENDOR_SPECIFIC = 221
}; };
@ -1783,31 +1764,6 @@ enum p2p_attr_id {
#define P2P_GROUP_CAPAB_GROUP_FORMATION BIT(6) #define P2P_GROUP_CAPAB_GROUP_FORMATION BIT(6)
#define P2P_GROUP_CAPAB_IP_ADDR_ALLOCATION BIT(7) #define P2P_GROUP_CAPAB_IP_ADDR_ALLOCATION BIT(7)
/* P2P Capability Extension attribute - Capability info */
#define P2P_PCEA_LEN_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3))
#define P2P_PCEA_6GHZ BIT(4)
#define P2P_PCEA_REG_INFO BIT(5)
#define P2P_PCEA_DFS_OWNER BIT(6)
#define P2P_PCEA_CLI_REQ_CS BIT(7)
#define P2P_PCEA_PAIRING_CAPABLE BIT(8)
#define P2P_PCEA_PAIRING_SETUP_ENABLED BIT(9)
#define P2P_PCEA_PMK_CACHING BIT(10)
#define P2P_PCEA_PASN_TYPE BIT(11)
#define P2P_PCEA_TWT_POWER_MGMT BIT(12)
/* P2P Pairing Bootstrapping Method attribute - Bootstrapping Method */
#define P2P_PBMA_OPPORTUNISTIC BIT(0)
#define P2P_PBMA_PIN_CODE_DISPLAY BIT(1)
#define P2P_PBMA_PASSPHRASE_DISPLAY BIT(2)
#define P2P_PBMA_QR_DISPLAY BIT(3)
#define P2P_PBMA_NFC_TAG BIT(4)
#define P2P_PBMA_PIN_CODE_KEYPAD BIT(5)
#define P2P_PBMA_PASSPHRASE_KEYPAD BIT(6)
#define P2P_PBMA_QR_SCAN BIT(7)
#define P2P_PBMA_NFC_READER BIT(8)
#define P2P_PBMA_SERVICE_MANAGED BIT(14)
#define P2P_PBMA_HANDSHAKE_SKIP BIT(15)
/* P2PS Coordination Protocol Transport Bitmap */ /* P2PS Coordination Protocol Transport Bitmap */
#define P2PS_FEATURE_CAPAB_UDP_TRANSPORT BIT(0) #define P2PS_FEATURE_CAPAB_UDP_TRANSPORT BIT(0)
#define P2PS_FEATURE_CAPAB_MAC_TRANSPORT BIT(1) #define P2PS_FEATURE_CAPAB_MAC_TRANSPORT BIT(1)
@ -1839,7 +1795,6 @@ enum p2p_status_code {
P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD = 10, P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD = 10,
P2P_SC_FAIL_REJECTED_BY_USER = 11, P2P_SC_FAIL_REJECTED_BY_USER = 11,
P2P_SC_SUCCESS_DEFERRED = 12, P2P_SC_SUCCESS_DEFERRED = 12,
P2P_SC_COMEBACK = 13,
}; };
enum p2p_role_indication { enum p2p_role_indication {
@ -2908,33 +2863,6 @@ enum ieee80211_eht_ml_sub_elem {
EHT_ML_SUB_ELEM_FRAGMENT = 254, EHT_ML_SUB_ELEM_FRAGMENT = 254,
}; };
/* IEEE P802.11be/D7.0, 9.4.2.329 (Bandwidth Indication element) defines the
* Bandwidth Indication Information field to have the same definition as the
* EHT Operation Information field in the EHT Operation element.
*/
struct ieee80211_bw_ind_info {
u8 control; /* B0..B2: Channel Width */
u8 ccfs0;
u8 ccfs1;
le16 disabled_chan_bitmap; /* 0 or 2 octets */
} STRUCT_PACKED;
/* Control subfield: Channel Width subfield; see Table 9-417e (Channel width,
* CCFS0, and CCFS1 subfields) in IEEE P802.11be/D7.0. */
#define BW_IND_CHANNEL_WIDTH_20MHZ EHT_OPER_CHANNEL_WIDTH_20MHZ
#define BW_IND_CHANNEL_WIDTH_40MHZ EHT_OPER_CHANNEL_WIDTH_40MHZ
#define BW_IND_CHANNEL_WIDTH_80MHZ EHT_OPER_CHANNEL_WIDTH_80MHZ
#define BW_IND_CHANNEL_WIDTH_160MHZ EHT_OPER_CHANNEL_WIDTH_160MHZ
#define BW_IND_CHANNEL_WIDTH_320MHZ EHT_OPER_CHANNEL_WIDTH_320MHZ
/* IEEE P802.11be/D7.0, 9.4.2.329 (Bandwidth Indication element) */
struct ieee80211_bw_ind_element {
u8 bw_ind_params; /* Bandwidth Indication Parameters */
struct ieee80211_bw_ind_info bw_ind_info; /* 3 or 5 octets */
} STRUCT_PACKED;
#define BW_IND_PARAMETER_DISABLED_SUBCHAN_BITMAP_PRESENT BIT(1)
/* IEEE P802.11ay/D4.0, 9.4.2.251 - EDMG Operation element */ /* IEEE P802.11ay/D4.0, 9.4.2.251 - EDMG Operation element */
#define EDMG_BSS_OPERATING_CHANNELS_OFFSET 6 #define EDMG_BSS_OPERATING_CHANNELS_OFFSET 6
#define EDMG_OPERATING_CHANNEL_WIDTH_OFFSET 7 #define EDMG_OPERATING_CHANNEL_WIDTH_OFFSET 7

View file

@ -58,12 +58,10 @@ struct nan_de_service {
struct os_reltime next_publish_state; struct os_reltime next_publish_state;
struct os_reltime next_publish_chan; struct os_reltime next_publish_chan;
unsigned int next_publish_duration; unsigned int next_publish_duration;
bool is_p2p;
}; };
struct nan_de { struct nan_de {
u8 nmi[ETH_ALEN]; u8 nmi[ETH_ALEN];
bool offload;
bool ap; bool ap;
struct nan_callbacks cb; struct nan_callbacks cb;
@ -79,7 +77,7 @@ struct nan_de {
}; };
struct nan_de * nan_de_init(const u8 *nmi, bool offload, bool ap, struct nan_de * nan_de_init(const u8 *nmi, bool ap,
const struct nan_callbacks *cb) const struct nan_callbacks *cb)
{ {
struct nan_de *de; struct nan_de *de;
@ -89,7 +87,6 @@ struct nan_de * nan_de_init(const u8 *nmi, bool offload, bool ap,
return NULL; return NULL;
os_memcpy(de->nmi, nmi, ETH_ALEN); os_memcpy(de->nmi, nmi, ETH_ALEN);
de->offload = offload;
de->ap = ap; de->ap = ap;
os_memcpy(&de->cb, cb, sizeof(*cb)); os_memcpy(&de->cb, cb, sizeof(*cb));
@ -593,7 +590,7 @@ static void nan_de_timer(void *eloop_ctx, void *timeout_ctx)
if (srv_next >= 0 && (next == -1 || srv_next < next)) if (srv_next >= 0 && (next == -1 || srv_next < next))
next = srv_next; next = srv_next;
if (srv_next == 0 && !started && !de->offload && if (srv_next == 0 && !started &&
de->listen_freq == 0 && de->ext_listen_freq == 0 && de->listen_freq == 0 && de->ext_listen_freq == 0 &&
de->tx_wait_end_freq == 0 && de->tx_wait_end_freq == 0 &&
nan_de_next_multicast(de, srv, &now) == 0) { nan_de_next_multicast(de, srv, &now) == 0) {
@ -601,7 +598,7 @@ static void nan_de_timer(void *eloop_ctx, void *timeout_ctx)
nan_de_tx_multicast(de, srv, 0); nan_de_tx_multicast(de, srv, 0);
} }
if (!started && !de->offload && de->cb.listen && if (!started && de->cb.listen &&
de->listen_freq == 0 && de->ext_listen_freq == 0 && de->listen_freq == 0 && de->ext_listen_freq == 0 &&
de->tx_wait_end_freq == 0 && de->tx_wait_end_freq == 0 &&
((srv->type == NAN_DE_PUBLISH && ((srv->type == NAN_DE_PUBLISH &&
@ -777,34 +774,6 @@ static void nan_de_get_sdea(const u8 *buf, size_t len, u8 instance_id,
} }
static void nan_de_process_elem_container(struct nan_de *de, const u8 *buf,
size_t len, const u8 *peer_addr,
unsigned int freq, bool p2p)
{
const u8 *elem;
u16 elem_len;
elem = nan_de_get_attr(buf, len, NAN_ATTR_ELEM_CONTAINER, 0);
if (!elem)
return;
elem++;
elem_len = WPA_GET_LE16(elem);
elem += 2;
/* Skip the attribute if there is not enough froom for an element. */
if (elem_len < 1 + 2)
return;
/* Skip Map ID */
elem++;
elem_len--;
if (p2p && de->cb.process_p2p_usd_elems)
de->cb.process_p2p_usd_elems(de->cb.ctx, elem, elem_len,
peer_addr, freq);
}
static void nan_de_rx_publish(struct nan_de *de, struct nan_de_service *srv, static void nan_de_rx_publish(struct nan_de *de, struct nan_de_service *srv,
const u8 *peer_addr, u8 instance_id, const u8 *peer_addr, u8 instance_id,
u8 req_instance_id, u16 sdea_control, u8 req_instance_id, u16 sdea_control,
@ -818,13 +787,13 @@ static void nan_de_rx_publish(struct nan_de *de, struct nan_de_service *srv,
nan_de_run_timer(de); nan_de_run_timer(de);
} }
if (!de->offload && srv->subscribe.active && req_instance_id == 0) { if (srv->subscribe.active && req_instance_id == 0) {
/* Active subscriber replies with a Subscribe message if it /* Active subscriber replies with a Subscribe message if it
* received a matching unsolicited Publish message. */ * received a matching unsolicited Publish message. */
nan_de_tx_multicast(de, srv, instance_id); nan_de_tx_multicast(de, srv, instance_id);
} }
if (!de->offload && !srv->subscribe.active && req_instance_id == 0) { if (!srv->subscribe.active && req_instance_id == 0) {
/* Passive subscriber replies with a Follow-up message without /* Passive subscriber replies with a Follow-up message without
* Service Specific Info field if it received a matching * Service Specific Info field if it received a matching
* unsolicited Publish message. */ * unsolicited Publish message. */
@ -904,9 +873,6 @@ static void nan_de_rx_subscribe(struct nan_de *de, struct nan_de_service *srv,
return; return;
} }
if (de->offload)
goto offload;
/* Reply with a solicited Publish message */ /* Reply with a solicited Publish message */
/* Service Descriptor attribute */ /* Service Descriptor attribute */
sda_len = NAN_SERVICE_ID_LEN + 1 + 1 + 1; sda_len = NAN_SERVICE_ID_LEN + 1 + 1 + 1;
@ -973,7 +939,6 @@ static void nan_de_rx_subscribe(struct nan_de *de, struct nan_de_service *srv,
nan_de_pause_state(srv, peer_addr, instance_id); nan_de_pause_state(srv, peer_addr, instance_id);
offload:
if (!srv->publish.disable_events && de->cb.replied) if (!srv->publish.disable_events && de->cb.replied)
de->cb.replied(de->cb.ctx, srv->id, peer_addr, instance_id, de->cb.replied(de->cb.ctx, srv->id, peer_addr, instance_id,
srv_proto_type, ssi, ssi_len); srv_proto_type, ssi, ssi_len);
@ -1129,8 +1094,6 @@ static void nan_de_rx_sda(struct nan_de *de, const u8 *peer_addr,
wpa_hexdump(MSG_MSGDUMP, "NAN: ssi", wpa_hexdump(MSG_MSGDUMP, "NAN: ssi",
ssi, ssi_len); ssi, ssi_len);
} }
nan_de_process_elem_container(de, buf, len, peer_addr,
freq, srv->is_p2p);
} }
switch (type) { switch (type) {
@ -1233,23 +1196,10 @@ static int nan_de_derive_service_id(struct nan_de_service *srv)
} }
const u8 * nan_de_get_service_id(struct nan_de *de, int id)
{
struct nan_de_service *srv;
if (id < 1 || id > NAN_DE_MAX_SERVICE)
return NULL;
srv = de->service[id - 1];
if (!srv)
return NULL;
return srv->service_id;
}
int nan_de_publish(struct nan_de *de, const char *service_name, int nan_de_publish(struct nan_de *de, const char *service_name,
enum nan_service_protocol_type srv_proto_type, enum nan_service_protocol_type srv_proto_type,
const struct wpabuf *ssi, const struct wpabuf *elems, const struct wpabuf *ssi, const struct wpabuf *elems,
struct nan_publish_params *params, bool p2p) struct nan_publish_params *params)
{ {
int publish_id; int publish_id;
struct nan_de_service *srv; struct nan_de_service *srv;
@ -1311,7 +1261,6 @@ int nan_de_publish(struct nan_de *de, const char *service_name,
wpa_printf(MSG_DEBUG, "NAN: Assigned new publish handle %d for %s", wpa_printf(MSG_DEBUG, "NAN: Assigned new publish handle %d for %s",
publish_id, service_name); publish_id, service_name);
srv->id = publish_id; srv->id = publish_id;
srv->is_p2p = p2p;
nan_de_add_srv(de, srv); nan_de_add_srv(de, srv);
nan_de_run_timer(de); nan_de_run_timer(de);
return publish_id; return publish_id;
@ -1363,7 +1312,7 @@ int nan_de_update_publish(struct nan_de *de, int publish_id,
int nan_de_subscribe(struct nan_de *de, const char *service_name, int nan_de_subscribe(struct nan_de *de, const char *service_name,
enum nan_service_protocol_type srv_proto_type, enum nan_service_protocol_type srv_proto_type,
const struct wpabuf *ssi, const struct wpabuf *elems, const struct wpabuf *ssi, const struct wpabuf *elems,
struct nan_subscribe_params *params, bool p2p) struct nan_subscribe_params *params)
{ {
int subscribe_id; int subscribe_id;
struct nan_de_service *srv; struct nan_de_service *srv;
@ -1388,17 +1337,6 @@ int nan_de_subscribe(struct nan_de *de, const char *service_name,
if (nan_de_derive_service_id(srv) < 0) if (nan_de_derive_service_id(srv) < 0)
goto fail; goto fail;
os_memcpy(&srv->subscribe, params, sizeof(*params)); os_memcpy(&srv->subscribe, params, sizeof(*params));
if (params->freq_list) {
size_t len;
len = (int_array_len(params->freq_list) + 1) * sizeof(int);
srv->freq_list = os_memdup(params->freq_list, len);
if (!srv->freq_list)
goto fail;
}
srv->subscribe.freq_list = NULL;
srv->srv_proto_type = srv_proto_type; srv->srv_proto_type = srv_proto_type;
if (ssi) { if (ssi) {
srv->ssi = wpabuf_dup(ssi); srv->ssi = wpabuf_dup(ssi);
@ -1414,7 +1352,6 @@ int nan_de_subscribe(struct nan_de *de, const char *service_name,
wpa_printf(MSG_DEBUG, "NAN: Assigned new subscribe handle %d for %s", wpa_printf(MSG_DEBUG, "NAN: Assigned new subscribe handle %d for %s",
subscribe_id, service_name); subscribe_id, service_name);
srv->id = subscribe_id; srv->id = subscribe_id;
srv->is_p2p = p2p;
nan_de_add_srv(de, srv); nan_de_add_srv(de, srv);
nan_de_run_timer(de); nan_de_run_timer(de);
return subscribe_id; return subscribe_id;

View file

@ -53,13 +53,9 @@ struct nan_callbacks {
void (*receive)(void *ctx, int id, int peer_instance_id, void (*receive)(void *ctx, int id, int peer_instance_id,
const u8 *ssi, size_t ssi_len, const u8 *ssi, size_t ssi_len,
const u8 *peer_addr); const u8 *peer_addr);
void (*process_p2p_usd_elems)(void *ctx, const u8 *buf,
u16 buf_len, const u8 *peer_addr,
unsigned int freq);
}; };
struct nan_de * nan_de_init(const u8 *nmi, bool offload, bool ap, struct nan_de * nan_de_init(const u8 *nmi, bool ap,
const struct nan_callbacks *cb); const struct nan_callbacks *cb);
void nan_de_flush(struct nan_de *de); void nan_de_flush(struct nan_de *de);
void nan_de_deinit(struct nan_de *de); void nan_de_deinit(struct nan_de *de);
@ -72,7 +68,6 @@ void nan_de_tx_wait_ended(struct nan_de *de);
void nan_de_rx_sdf(struct nan_de *de, const u8 *peer_addr, unsigned int freq, void nan_de_rx_sdf(struct nan_de *de, const u8 *peer_addr, unsigned int freq,
const u8 *buf, size_t len); const u8 *buf, size_t len);
const u8 * nan_de_get_service_id(struct nan_de *de, int id);
struct nan_publish_params { struct nan_publish_params {
/* configuration_parameters */ /* configuration_parameters */
@ -110,7 +105,7 @@ struct nan_publish_params {
int nan_de_publish(struct nan_de *de, const char *service_name, int nan_de_publish(struct nan_de *de, const char *service_name,
enum nan_service_protocol_type srv_proto_type, enum nan_service_protocol_type srv_proto_type,
const struct wpabuf *ssi, const struct wpabuf *elems, const struct wpabuf *ssi, const struct wpabuf *elems,
struct nan_publish_params *params, bool p2p); struct nan_publish_params *params);
void nan_de_cancel_publish(struct nan_de *de, int publish_id); void nan_de_cancel_publish(struct nan_de *de, int publish_id);
@ -129,9 +124,6 @@ struct nan_subscribe_params {
/* Selected frequency */ /* Selected frequency */
unsigned int freq; unsigned int freq;
/* Multi-channel frequencies (publishChannelList) */
const int *freq_list;
/* Query period in ms; 0 = use default */ /* Query period in ms; 0 = use default */
unsigned int query_period; unsigned int query_period;
}; };
@ -140,7 +132,7 @@ struct nan_subscribe_params {
int nan_de_subscribe(struct nan_de *de, const char *service_name, int nan_de_subscribe(struct nan_de *de, const char *service_name,
enum nan_service_protocol_type srv_proto_type, enum nan_service_protocol_type srv_proto_type,
const struct wpabuf *ssi, const struct wpabuf *elems, const struct wpabuf *ssi, const struct wpabuf *elems,
struct nan_subscribe_params *params, bool p2p); struct nan_subscribe_params *params);
void nan_de_cancel_subscribe(struct nan_de *de, int subscribe_id); void nan_de_cancel_subscribe(struct nan_de *de, int subscribe_id);

View file

@ -230,8 +230,7 @@ enum qca_radiotap_vendor_ids {
* *
* @QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES: Command to get the features * @QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES: Command to get the features
* supported by the driver. enum qca_wlan_vendor_features defines * supported by the driver. enum qca_wlan_vendor_features defines
* the possible features that are encoded in * the possible features.
* QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS.
* *
* @QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED: Event used by driver, * @QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED: Event used by driver,
* which supports DFS offloading, to indicate a channel availability check * which supports DFS offloading, to indicate a channel availability check
@ -1133,39 +1132,6 @@ enum qca_radiotap_vendor_ids {
* Uses the attributes defined in * Uses the attributes defined in
* enum qca_wlan_vendor_attr_tdls_disc_rsp_ext. * enum qca_wlan_vendor_attr_tdls_disc_rsp_ext.
* *
* @QCA_NL80211_VENDOR_SUBCMD_AUDIO_TRANSPORT_SWITCH: This vendor subcommand is
* used to configure and indicate the audio transport switch in both
* command and event paths. This is used when two or more audio transports
* (e.g., WLAN and Bluetooth) are available between peers.
*
* If the driver needs to perform operations like scan, connection,
* roaming, RoC, etc. and AP concurrency policy is set to either
* QCA_WLAN_CONCURRENT_AP_POLICY_GAMING_AUDIO or
* QCA_WLAN_CONCURRENT_AP_POLICY_LOSSLESS_AUDIO_STREAMING, the driver sends
* audio transport switch event to userspace. Userspace application upon
* receiving the event, can try to switch to the requested audio transport.
* The userspace uses this command to send the status of transport
* switching (either confirm or reject) to the driver using this
* subcommand. The driver continues with the pending operation either upon
* receiving the command from userspace or after waiting for a timeout from
* sending the event to userspace. The driver can request userspace to
* switch to WLAN upon availability of WLAN audio transport once after the
* concurrent operations are completed.
*
* Userspace can also request audio transport switch from non-WLAN to WLAN
* using this subcommand to the driver. The driver can accept or reject
* depending on other concurrent operations in progress. The driver returns
* success if it can allow audio transport when it receives the command or
* appropriate kernel error code otherwise. Userspace indicates the audio
* transport switch from WLAN to non-WLAN using this subcommand and the
* driver can do other concurrent operations without needing to send any
* event to userspace. This subcommand is used by userspace only when the
* driver advertises support for
* QCA_WLAN_VENDOR_FEATURE_ENHANCED_AUDIO_EXPERIENCE_OVER_WLAN.
*
* The attributes used with this command are defined in enum
* qca_wlan_vendor_attr_audio_transport_switch.
*
* @QCA_NL80211_VENDOR_SUBCMD_TX_LATENCY: This vendor subcommand is used to * @QCA_NL80211_VENDOR_SUBCMD_TX_LATENCY: This vendor subcommand is used to
* configure, retrieve, and report per-link transmit latency statistics. * configure, retrieve, and report per-link transmit latency statistics.
* *
@ -1261,35 +1227,6 @@ enum qca_radiotap_vendor_ids {
* collection of these statistics has been enabled by the command * collection of these statistics has been enabled by the command
* @QCA_NL80211_VENDOR_SUBCMD_ASYNC_STATS_POLICY. The attributes for this * @QCA_NL80211_VENDOR_SUBCMD_ASYNC_STATS_POLICY. The attributes for this
* event are defined in enum qca_wlan_vendor_attr_flow_stats. * event are defined in enum qca_wlan_vendor_attr_flow_stats.
*
* @QCA_NL80211_VENDOR_SUBCMD_USD: Vendor subcommand to implement unsynchronized
* service discovery (USD). Based on the type of the USD subcommand the USD
* operation to publish, subscribe, update publish, cancel publish, or
* cancel subscribe is triggered.
*
* When used as an event, the driver notifies the status of an USD command.
*
* The attributes used with this command are defined in
* enum qca_wlan_vendor_attr_usd.
*
* @QCA_NL80211_VENDOR_SUBCMD_CONNECT_EXT: This is an extension to
* %NL80211_CMD_CONNECT command. Userspace can use this to indicate
* additional information to be considered for the subsequent
* (re)association request attempts with %NL80211_CMD_CONNECT. The
* additional information sent with this command is applicable for the
* entire duration of the connection established with %NL80211_CMD_CONNECT,
* including the roams triggered by the driver internally due to other
* vendor interfaces, driver internal logic, and BTM requests from the
* connected AP.
*
* @QCA_NL80211_VENDOR_SUBCMD_SET_P2P_MODE: Vendor subcommand to configure
* Wi-Fi Direct mode. This command sets the configuration through
* the attributes defined in the enum qca_wlan_vendor_attr_set_p2p_mode.
* It is applicable for P2P Group Owner only. This command is used before
* starting the GO.
*
* The attributes used with this command are defined in
* enum qca_wlan_vendor_attr_connect_ext.
*/ */
enum qca_nl80211_vendor_subcmds { enum qca_nl80211_vendor_subcmds {
QCA_NL80211_VENDOR_SUBCMD_UNSPEC = 0, QCA_NL80211_VENDOR_SUBCMD_UNSPEC = 0,
@ -1505,7 +1442,7 @@ enum qca_nl80211_vendor_subcmds {
QCA_NL80211_VENDOR_SUBCMD_TID_TO_LINK_MAP = 229, QCA_NL80211_VENDOR_SUBCMD_TID_TO_LINK_MAP = 229,
QCA_NL80211_VENDOR_SUBCMD_LINK_RECONFIG = 230, QCA_NL80211_VENDOR_SUBCMD_LINK_RECONFIG = 230,
QCA_NL80211_VENDOR_SUBCMD_TDLS_DISC_RSP_EXT = 231, QCA_NL80211_VENDOR_SUBCMD_TDLS_DISC_RSP_EXT = 231,
QCA_NL80211_VENDOR_SUBCMD_AUDIO_TRANSPORT_SWITCH = 232, /* 232 - reserved for QCA */
QCA_NL80211_VENDOR_SUBCMD_TX_LATENCY = 233, QCA_NL80211_VENDOR_SUBCMD_TX_LATENCY = 233,
/* 234 - reserved for QCA */ /* 234 - reserved for QCA */
QCA_NL80211_VENDOR_SUBCMD_SDWF_PHY_OPS = 235, QCA_NL80211_VENDOR_SUBCMD_SDWF_PHY_OPS = 235,
@ -1522,9 +1459,6 @@ enum qca_nl80211_vendor_subcmds {
QCA_NL80211_VENDOR_SUBCMD_FLOW_CLASSIFY_RESULT = 246, QCA_NL80211_VENDOR_SUBCMD_FLOW_CLASSIFY_RESULT = 246,
QCA_NL80211_VENDOR_SUBCMD_ASYNC_STATS_POLICY = 247, QCA_NL80211_VENDOR_SUBCMD_ASYNC_STATS_POLICY = 247,
QCA_NL80211_VENDOR_SUBCMD_CLASSIFIED_FLOW_REPORT = 248, QCA_NL80211_VENDOR_SUBCMD_CLASSIFIED_FLOW_REPORT = 248,
QCA_NL80211_VENDOR_SUBCMD_USD = 249,
QCA_NL80211_VENDOR_SUBCMD_CONNECT_EXT = 250,
QCA_NL80211_VENDOR_SUBCMD_SET_P2P_MODE = 251,
}; };
/* Compatibility defines for previously used subcmd names. /* Compatibility defines for previously used subcmd names.
@ -1551,11 +1485,7 @@ enum qca_wlan_vendor_attr {
*/ */
QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY = 5, QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY = 5,
QCA_WLAN_VENDOR_ATTR_MAC_ADDR = 6, QCA_WLAN_VENDOR_ATTR_MAC_ADDR = 6,
/* Feature flags contained in a byte array. The feature flags are /* used by QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES */
* identified by their bit index (see &enum qca_wlan_vendor_features)
* with the first byte being the least significant one and the last one
* being the most significant one. Used by
* QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES. */
QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS = 7, QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS = 7,
QCA_WLAN_VENDOR_ATTR_TEST = 8, QCA_WLAN_VENDOR_ATTR_TEST = 8,
/* used by QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES */ /* used by QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES */
@ -2250,15 +2180,6 @@ enum qca_wlan_vendor_acs_hw_mode {
* that the device supports enhanced audio experience over WLAN feature. * that the device supports enhanced audio experience over WLAN feature.
* @QCA_WLAN_VENDOR_FEATURE_HT_VHT_TWT_RESPONDER: Flag indicates that the device * @QCA_WLAN_VENDOR_FEATURE_HT_VHT_TWT_RESPONDER: Flag indicates that the device
* in AP mode supports TWT responder mode in HT and VHT modes. * in AP mode supports TWT responder mode in HT and VHT modes.
*
* @QCA_WLAN_VENDOR_FEATURE_RSN_OVERRIDE_STA: Flag indicates that the device
* supports RSNE/RSNXE overriding in STA mode. Supplicant should enable
* RSN overriding elements use only when the driver indicates this feature
* flag. For BSS selection offload to the driver case, the driver shall
* strip/modify the RSN Selection element indicated in connect request
* elements or add that element if none was provided based on the BSS
* selected by the driver.
*
* @NUM_QCA_WLAN_VENDOR_FEATURES: Number of assigned feature bits * @NUM_QCA_WLAN_VENDOR_FEATURES: Number of assigned feature bits
*/ */
enum qca_wlan_vendor_features { enum qca_wlan_vendor_features {
@ -2287,7 +2208,6 @@ enum qca_wlan_vendor_features {
QCA_WLAN_VENDOR_FEATURE_AP_ALLOWED_FREQ_LIST = 22, QCA_WLAN_VENDOR_FEATURE_AP_ALLOWED_FREQ_LIST = 22,
QCA_WLAN_VENDOR_FEATURE_ENHANCED_AUDIO_EXPERIENCE_OVER_WLAN = 23, QCA_WLAN_VENDOR_FEATURE_ENHANCED_AUDIO_EXPERIENCE_OVER_WLAN = 23,
QCA_WLAN_VENDOR_FEATURE_HT_VHT_TWT_RESPONDER = 24, QCA_WLAN_VENDOR_FEATURE_HT_VHT_TWT_RESPONDER = 24,
QCA_WLAN_VENDOR_FEATURE_RSN_OVERRIDE_STA = 25,
NUM_QCA_WLAN_VENDOR_FEATURES /* keep last */ NUM_QCA_WLAN_VENDOR_FEATURES /* keep last */
}; };
@ -2707,9 +2627,6 @@ enum qca_wlan_vendor_scan_priority {
* when AP is operating as MLD to specify which link is requesting the * when AP is operating as MLD to specify which link is requesting the
* scan or which link the scan result is for. No need of this attribute * scan or which link the scan result is for. No need of this attribute
* in other cases. * in other cases.
* @QCA_WLAN_VENDOR_ATTR_SCAN_SKIP_CHANNEL_RECENCY_PERIOD: Optional (u32). Skip
* scanning channels which are scanned recently within configured time
* (in ms).
*/ */
enum qca_wlan_vendor_attr_scan { enum qca_wlan_vendor_attr_scan {
QCA_WLAN_VENDOR_ATTR_SCAN_INVALID_PARAM = 0, QCA_WLAN_VENDOR_ATTR_SCAN_INVALID_PARAM = 0,
@ -2728,7 +2645,6 @@ enum qca_wlan_vendor_attr_scan {
QCA_WLAN_VENDOR_ATTR_SCAN_PRIORITY = 13, QCA_WLAN_VENDOR_ATTR_SCAN_PRIORITY = 13,
QCA_WLAN_VENDOR_ATTR_SCAN_PAD = 14, QCA_WLAN_VENDOR_ATTR_SCAN_PAD = 14,
QCA_WLAN_VENDOR_ATTR_SCAN_LINK_ID = 15, QCA_WLAN_VENDOR_ATTR_SCAN_LINK_ID = 15,
QCA_WLAN_VENDOR_ATTR_SCAN_SKIP_CHANNEL_RECENCY_PERIOD = 16,
QCA_WLAN_VENDOR_ATTR_SCAN_AFTER_LAST, QCA_WLAN_VENDOR_ATTR_SCAN_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_SCAN_MAX = QCA_WLAN_VENDOR_ATTR_SCAN_MAX =
QCA_WLAN_VENDOR_ATTR_SCAN_AFTER_LAST - 1 QCA_WLAN_VENDOR_ATTR_SCAN_AFTER_LAST - 1
@ -3730,17 +3646,6 @@ enum qca_wlan_vendor_attr_config {
*/ */
QCA_WLAN_VENDOR_ATTR_CONFIG_FOLLOW_AP_PREFERENCE_FOR_CNDS_SELECT = 121, QCA_WLAN_VENDOR_ATTR_CONFIG_FOLLOW_AP_PREFERENCE_FOR_CNDS_SELECT = 121,
/* 16-bit unsigned value to configure P2P GO beacon interval in TUs.
* This attribute is used to update the P2P GO beacon interval
* dynamically.
*
* Updating the beacon interval while the GO continues operating the BSS
* will likely interoperability issues and is not recommended to be
* used. All the values should be multiples of the minimum used value to
* minimize risk of issues.
*/
QCA_WLAN_VENDOR_ATTR_CONFIG_P2P_GO_BEACON_INTERVAL = 122,
/* keep last */ /* keep last */
QCA_WLAN_VENDOR_ATTR_CONFIG_AFTER_LAST, QCA_WLAN_VENDOR_ATTR_CONFIG_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_CONFIG_MAX = QCA_WLAN_VENDOR_ATTR_CONFIG_MAX =
@ -7512,10 +7417,6 @@ enum qca_wlan_vendor_attr_external_acs_event {
* for External ACS * for External ACS
*/ */
QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_AFC_CAPABILITY = 15, QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_AFC_CAPABILITY = 15,
/* Link ID attibute (u8) is used to identify a specific link affiliated
* to an AP MLD.
*/
QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_LINK_ID = 16,
/* keep last */ /* keep last */
QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_LAST, QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_LAST,
@ -10457,14 +10358,6 @@ enum qca_wlan_vendor_attr_wifi_test_config {
*/ */
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_EHT_SCS_TRAFFIC_SUPPORT = 73, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_EHT_SCS_TRAFFIC_SUPPORT = 73,
/* 8-bit unsigned value to disable or not disable the channel switch
* initiation in P2P GO mode.
* 0 - Not-disable, 1 - Disable
*
* This attribute is used for testing purposes.
*/
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISABLE_CHAN_SWITCH_INITIATION = 74,
/* keep last */ /* keep last */
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_AFTER_LAST, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX =
@ -12518,12 +12411,6 @@ enum qca_wlan_vendor_attr_add_sta_node_params {
*/ */
QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_IS_ML = 3, QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_IS_ML = 3,
/*
* This is u8 attribute used to identify a specific link affiliated
* to an AP MLD.
*/
QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_LINK_ID = 4,
/* keep last */ /* keep last */
QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_PARAM_AFTER_LAST, QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_PARAM_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_PARAM_MAX = QCA_WLAN_VENDOR_ATTR_ADD_STA_NODE_PARAM_MAX =
@ -17962,318 +17849,4 @@ enum qca_wlan_intf_offload_type {
QCA_WLAN_INTF_OFFLOAD_TYPE_PPE_DS = 3, QCA_WLAN_INTF_OFFLOAD_TYPE_PPE_DS = 3,
}; };
/**
* enum qca_wlan_vendor_attr_usd_op_type: Attribute values for
* %QCA_WLAN_VENDOR_ATTR_USD_OP_TYPE to the vendor subcmd
* %QCA_NL80211_VENDOR_SUBCMD_USD. This is a mandatory u8 attribute which
* represents the USD command type.
*
* @QCA_WLAN_VENDOR_USD_OP_TYPE_FLUSH: Indicates USD tear down of all active
* publish and subscribe sessions.
*
* @QCA_WLAN_VENDOR_USD_OP_TYPE_PUBLISH: Indicates USD solicited publish
* operation that enables to offer a service for other devices based on
* given parameters.
*
* @QCA_WLAN_VENDOR_USD_OP_TYPE_SUBSCRIBE: Indicates USD active subscribe
* operation that requests for a given service with given parameters from
* other devices that offer the service.
*
* @QCA_WLAN_VENDOR_USD_OP_TYPE_UPDATE_PUBLISH: Indicates update of an instance
* of the publish function of given publish id.
*
* @QCA_WLAN_VENDOR_USD_OP_TYPE_CANCEL_PUBLISH: Indicates cancellation of an
* instance of the publish function.
*
* @QCA_WLAN_VENDOR_USD_OP_TYPE_CANCEL_SUBSCRIBE: Indicates cancellation of an
* instance of the subscribe function.
*/
enum qca_wlan_vendor_attr_an_usd_op_type {
QCA_WLAN_VENDOR_USD_OP_TYPE_FLUSH = 0,
QCA_WLAN_VENDOR_USD_OP_TYPE_PUBLISH = 1,
QCA_WLAN_VENDOR_USD_OP_TYPE_SUBSCRIBE = 2,
QCA_WLAN_VENDOR_USD_OP_TYPE_UPDATE_PUBLISH = 3,
QCA_WLAN_VENDOR_USD_OP_TYPE_CANCEL_PUBLISH = 4,
QCA_WLAN_VENDOR_USD_OP_TYPE_CANCEL_SUBSCRIBE = 5,
};
/**
* enum qca_wlan_vendor_attr_usd_service_protocol_type: Attribute values for
* %QCA_WLAN_VENDOR_ATTR_USD_SERVICE_PROTOCOL_TYPE to the vendor subcmd
* %QCA_NL80211_VENDOR_SUBCMD_USD. This is a u8 attribute which represents the
* USD service protocol type for service specific information.
*
* @QCA_WLAN_VENDOR_USD_SERVICE_PROTOCOL_TYPE_BONJOUR: Indicates SSI info is
* of type Bonjour
* @QCA_WLAN_VENDOR_USD_SERVICE_PROTOCOL_TYPE_GENERIC: Indicates SSI info is
* of type generic
* @QCA_WLAN_VENDOR_USD_SERVICE_PROTOCOL_TYPE_CSA_MATTER: Indicates SSI info
* is of type CSA/Matter
*/
enum qca_wlan_vendor_attr_usd_service_protocol_type {
QCA_WLAN_VENDOR_USD_SERVICE_PROTOCOL_TYPE_BONJOUR = 1,
QCA_WLAN_VENDOR_USD_SERVICE_PROTOCOL_TYPE_GENERIC = 2,
QCA_WLAN_VENDOR_USD_SERVICE_PROTOCOL_TYPE_CSA_MATTER = 3,
};
/**
* enum qca_wlan_vendor_attr_usd_chan_config - Attributes used inside nested
* attribute %QCA_WLAN_VENDOR_ATTR_USD_CHAN_CONFIG.
*
* @QCA_WLAN_VENDOR_ATTR_USD_CHAN_CONFIG_DEFAULT_FREQ: Required
* u32 attribute containing the default channel frequency (MHz).
*
* @QCA_WLAN_VENDOR_ATTR_USD_CHAN_CONFIG_FREQ_LIST: Optional array of channel
* frequencies in MHz (u32) to publish or subscribe.
*/
enum qca_wlan_vendor_attr_usd_chan_config {
QCA_WLAN_VENDOR_ATTR_USD_CHAN_CONFIG_INVALID = 0,
QCA_WLAN_VENDOR_ATTR_USD_CHAN_CONFIG_DEFAULT_FREQ = 1,
QCA_WLAN_VENDOR_ATTR_USD_CHAN_CONFIG_FREQ_LIST = 2,
QCA_WLAN_VENDOR_ATTR_USD_CHAN_CONFIG_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_USD_CHAN_CONFIG_MAX =
QCA_WLAN_VENDOR_ATTR_USD_CHAN_CONFIG_AFTER_LAST - 1,
};
/**
* enum qca_wlan_vendor_attr_usd_status
*
* @QCA_WLAN_VENDOR_ATTR_USD_STATUS_SUCCESS: USD request success status.
* @QCA_WLAN_VENDOR_ATTR_USD_STATUS_FAILED: USD request failed status.
*/
enum qca_wlan_vendor_attr_usd_status {
QCA_WLAN_VENDOR_ATTR_USD_STATUS_SUCCESS,
QCA_WLAN_VENDOR_ATTR_USD_STATUS_FAILED,
};
/* enum qca_wlan_vendor_attr_usd: Attributes used by vendor command
* %QCA_NL80211_VENDOR_SUBCMD_USD.
*
* @QCA_WLAN_VENDOR_ATTR_USD_SRC_ADDR: 6-byte source MAC address
* Mandatory attribute used with type
* %QCA_WLAN_VENDOR_USD_OP_TYPE_PUBLISH and
* %QCA_WLAN_VENDOR_USD_OP_TYPE_SUBSCRIBE.
*
* @QCA_WLAN_VENDOR_ATTR_USD_OP_TYPE: Required u8 attribute.
* It indicates the type of the USD command. It uses values defined in enum
* qca_wlan_vendor_attr_usd_op_type.
*
* @QCA_WLAN_VENDOR_ATTR_USD_INSTANCE_ID: Required u8 attribute.
* It contains the publisher/subscribe id that is specific to the
* publish/subscribe instance.
*
* @QCA_WLAN_VENDOR_ATTR_USD_SERVICE_ID: Required 6-byte attribute.
* It contains the service id that is specific to the service being
* published/subscribed.
*
* @QCA_WLAN_VENDOR_ATTR_USD_SERVICE_PROTOCOL_TYPE: u8 attribute that indicates
* the service protocol type of service specific info. It uses values
* defined in enum qca_wlan_vendor_attr_usd_service_protocol_type. It is
* applicable when %QCA_WLAN_VENDOR_ATTR_USD_SSI is present.
*
* @QCA_WLAN_VENDOR_ATTR_USD_SSI: u8 array containing service specific
* information that has to be conveyed in publish/subscribe message.
* Optional attribute used with type
* %QCA_WLAN_VENDOR_USD_OP_TYPE_PUBLISH,
* %QCA_WLAN_VENDOR_USD_OP_TYPE_SUBSCRIBE, and
* %QCA_WLAN_VENDOR_USD_OP_TYPE_UPDATE_PUBLISH.
*
* @QCA_WLAN_VENDOR_ATTR_USD_CHAN_CONFIG: Nested attribute containing USD
* channel configuration parameters.
* Required for type %QCA_WLAN_VENDOR_USD_OP_TYPE_PUBLISH and
* %QCA_WLAN_VENDOR_USD_OP_TYPE_SUBSCRIBE.
* See enum qca_wlan_vendor_attr_usd_chan_config for nested attributes.
*
* @QCA_WLAN_VENDOR_ATTR_USD_ELEMENT_CONTAINER: u8 array containing a USD
* element container buffer that has to be conveyed in publish/subscribe
* message.
* Required for type %QCA_WLAN_VENDOR_USD_OP_TYPE_PUBLISH and
* %QCA_WLAN_VENDOR_USD_OP_TYPE_SUBSCRIBE.
*
* @QCA_WLAN_VENDOR_ATTR_USD_TTL: u16 attribute. Indicates the timeout
* for each request in seconds. Timeout value 0 represents single time
* operation.
*
* @QCA_WLAN_VENDOR_ATTR_USD_STATUS: u8 attribute. Status received in event
* indicating whether the underlying driver/firmware has started the USD
* operation as indicated by attributes
* %QCA_WLAN_VENDOR_ATTR_USD_OP_TYPE and
* %QCA_WLAN_VENDOR_ATTR_USD_INSTANCE_ID.
* enum qca_wlan_vendor_attr_usd_status indicates status values.
*/
enum qca_wlan_vendor_attr_usd {
QCA_WLAN_VENDOR_ATTR_USD_INVALID = 0,
QCA_WLAN_VENDOR_ATTR_USD_SRC_ADDR = 1,
QCA_WLAN_VENDOR_ATTR_USD_OP_TYPE = 2,
QCA_WLAN_VENDOR_ATTR_USD_INSTANCE_ID = 3,
QCA_WLAN_VENDOR_ATTR_USD_SERVICE_ID = 4,
QCA_WLAN_VENDOR_ATTR_USD_SERVICE_PROTOCOL_TYPE = 5,
QCA_WLAN_VENDOR_ATTR_USD_SSI = 6,
QCA_WLAN_VENDOR_ATTR_USD_CHAN_CONFIG = 7,
QCA_WLAN_VENDOR_ATTR_USD_ELEMENT_CONTAINER = 8,
QCA_WLAN_VENDOR_ATTR_USD_TTL = 9,
QCA_WLAN_VENDOR_ATTR_USD_STATUS = 10,
QCA_WLAN_VENDOR_ATTR_USD_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_USD_MAX =
QCA_WLAN_VENDOR_ATTR_USD_AFTER_LAST - 1,
};
/**
* enum qca_wlan_audio_transport_switch_type - Represents the possible transport
* switch types.
*
* @QCA_WLAN_AUDIO_TRANSPORT_SWITCH_TYPE_NON_WLAN: Request to route audio data
* via non-WLAN transport (e.g., Bluetooth).
*
* @QCA_WLAN_AUDIO_TRANSPORT_SWITCH_TYPE_WLAN: Request to route audio data via
* WLAN transport.
*/
enum qca_wlan_audio_transport_switch_type {
QCA_WLAN_AUDIO_TRANSPORT_SWITCH_TYPE_NON_WLAN = 0,
QCA_WLAN_AUDIO_TRANSPORT_SWITCH_TYPE_WLAN = 1,
};
/**
* enum qca_wlan_audio_transport_switch_status - Represents the status of audio
* transport switch request.
*
* @QCA_WLAN_AUDIO_TRANSPORT_SWITCH_STATUS_REJECTED: Request to switch transport
* has been rejected. For example, when transport switch is requested from WLAN
* to non-WLAN transport, user space modules and peers would evaluate the switch
* request and may not be ready for switch and hence switch to non-WLAN
* transport gets rejected.
*
* @QCA_WLAN_AUDIO_TRANSPORT_SWITCH_STATUS_COMPLETED: Request to switch
* transport has been completed. This is sent only in the command path. For
* example, when the driver had requested for audio transport switch and
* userspace modules as well as peers are ready for the switch, userspace module
* switches the transport and sends the subcommand with status completed to the
* driver.
*/
enum qca_wlan_audio_transport_switch_status {
QCA_WLAN_AUDIO_TRANSPORT_SWITCH_STATUS_REJECTED = 0,
QCA_WLAN_AUDIO_TRANSPORT_SWITCH_STATUS_COMPLETED = 1,
};
/**
* enum qca_wlan_audio_transport_switch_reason - Represents the reason of audio
* transport switch request.
*
* @QCA_WLAN_AUDIO_TRANSPORT_SWITCH_REASON_TERMINATING: Requester transport is
* terminating. After this indication, requester module may not be available to
* process further request on its transport. For example, to handle a high
* priority concurrent interface, WLAN transport needs to terminate and hence
* indicates switch to a non-WLAN transport with reason terminating. User space
* modules switch to non-WLAN immediately without waiting for further
* confirmation.
*/
enum qca_wlan_audio_transport_switch_reason {
QCA_WLAN_AUDIO_TRANSPORT_SWITCH_REASON_TERMINATING = 0,
};
/**
* enum qca_wlan_vendor_attr_audio_transport_switch - Attributes used by
* %QCA_NL80211_VENDOR_SUBCMD_AUDIO_TRANSPORT_SWITCH vendor command.
*
* @QCA_WLAN_VENDOR_ATTR_AUDIO_TRANSPORT_SWITCH_TYPE: u8 attribute. Indicates
* the transport switch type from one of the values in enum
* qca_wlan_audio_transport_switch_type. This is mandatory attribute in both
* command and event path. This attribute is included in both requests and
* responses.
*
* @QCA_WLAN_VENDOR_ATTR_AUDIO_TRANSPORT_SWITCH_STATUS: u8 attribute. Indicates
* the transport switch status from one of the values in enum
* qca_wlan_audio_transport_switch_status. This is optional attribute and used
* in both command and event path. This attribute must not be included in
* requests.
*
* @QCA_WLAN_VENDOR_ATTR_AUDIO_TRANSPORT_SWITCH_REASON: u8 attribute. Indicates
* the transport switch reason from one of the values in enum
* qca_wlan_audio_transport_switch_reason. This is optional attribute and used
* in both command and event path.
*/
enum qca_wlan_vendor_attr_audio_transport_switch {
QCA_WLAN_VENDOR_ATTR_AUDIO_TRANSPORT_SWITCH_INVALID = 0,
QCA_WLAN_VENDOR_ATTR_AUDIO_TRANSPORT_SWITCH_TYPE = 1,
QCA_WLAN_VENDOR_ATTR_AUDIO_TRANSPORT_SWITCH_STATUS = 2,
QCA_WLAN_VENDOR_ATTR_AUDIO_TRANSPORT_SWITCH_REASON = 3,
/* keep last */
QCA_WLAN_VENDOR_ATTR_AUDIO_TRANSPORT_SWITCH_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_AUDIO_TRANSPORT_SWITCH_MAX =
QCA_WLAN_VENDOR_ATTR_AUDIO_TRANSPORT_SWITCH_AFTER_LAST - 1,
};
/**
* enum qca_wlan_connect_ext_features - Feature flags for
* %QCA_WLAN_VENDOR_ATTR_CONNECT_EXT_FEATURES
*
* @QCA_CONNECT_EXT_FEATURE_RSNO: Flag attribute. This indicates supplicant
* support for RSN overriding. The driver shall enable RSN overriding in the
* (re)association attempts only if this flag is indicated. This functionality
* is available only when the driver indicates support for
* @QCA_WLAN_VENDOR_FEATURE_RSN_OVERRIDE_STA.
*
* @NUM_QCA_WLAN_VENDOR_FEATURES: Number of assigned feature bits.
*/
enum qca_wlan_connect_ext_features {
QCA_CONNECT_EXT_FEATURE_RSNO = 0,
NUM_QCA_CONNECT_EXT_FEATURES /* keep last */
};
/* enum qca_wlan_vendor_attr_connect_ext: Attributes used by vendor command
* %QCA_NL80211_VENDOR_SUBCMD_CONNECT_EXT.
*
* @QCA_WLAN_VENDOR_ATTR_CONNECT_EXT_FEATURES: Feature flags contained in a byte
* array. The feature flags are identified by their bit index (see &enum
* qca_wlan_connect_ext_features) with the first byte being the least
* significant one and the last one being the most significant one.
*/
enum qca_wlan_vendor_attr_connect_ext {
QCA_WLAN_VENDOR_ATTR_CONNECT_EXT_INVALID = 0,
QCA_WLAN_VENDOR_ATTR_CONNECT_EXT_FEATURES = 1,
QCA_WLAN_VENDOR_ATTR_CONNECT_EXT_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_CONNECT_EXT_MAX =
QCA_WLAN_VENDOR_ATTR_CONNECT_EXT_AFTER_LAST - 1,
};
/**
* enum qca_wlan_vendor_p2p_mode - Defines the values used with
* %QCA_WLAN_VENDOR_ATTR_SET_P2P_MODE_CONFIG.
*
* @QCA_P2P_MODE_WFD_R1: Wi-Fi Direct R1 only.
* @QCA_P2P_MODE_WFD_R2: Wi-Fi Direct R2 only.
* @QCA_P2P_MODE_WFD_PCC: P2P Connection Compatibility Mode which supports both
* Wi-Fi Direct R1 and R2.
*/
enum qca_wlan_vendor_p2p_mode {
QCA_P2P_MODE_WFD_R1 = 0,
QCA_P2P_MODE_WFD_R2 = 1,
QCA_P2P_MODE_WFD_PCC = 2,
};
/* enum qca_wlan_vendor_attr_set_p2p_mode: Attributes used by vendor command
* %QCA_NL80211_VENDOR_SUBCMD_SET_P2P_MODE.
*
* @QCA_WLAN_VENDOR_ATTR_SET_P2P_MODE_CONFIG: u8 attribute. Sets the P2P device
* mode. The values used are defined in enum qca_wlan_vendor_p2p_mode.
* This configuration is valid until the interface is brought up next time after
* this configuration and the driver shall use this configuration only when the
* interface is brought up in NL80211_IFTYPE_P2P_GO mode.
* When this parameter has not been set, the interface is brought up with
* Wi-Fi Direct R1 only configuration by default.
*/
enum qca_wlan_vendor_attr_set_p2p_mode {
QCA_WLAN_VENDOR_ATTR_SET_P2P_MODE_INVALID = 0,
QCA_WLAN_VENDOR_ATTR_SET_P2P_MODE_CONFIG = 1,
QCA_WLAN_VENDOR_ATTR_SET_P2P_MODE_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_SET_P2P_MODE_MAX =
QCA_WLAN_VENDOR_ATTR_SET_P2P_MODE_AFTER_LAST - 1,
};
#endif /* QCA_VENDOR_H */ #endif /* QCA_VENDOR_H */

View file

@ -9,6 +9,6 @@
#define GIT_VERSION_STR_POSTFIX "" #define GIT_VERSION_STR_POSTFIX ""
#endif /* GIT_VERSION_STR_POSTFIX */ #endif /* GIT_VERSION_STR_POSTFIX */
#define VERSION_STR "2.12-devel" VERSION_STR_POSTFIX GIT_VERSION_STR_POSTFIX #define VERSION_STR "2.11" VERSION_STR_POSTFIX GIT_VERSION_STR_POSTFIX
#endif /* VERSION_H */ #endif /* VERSION_H */

View file

@ -1890,14 +1890,6 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
data->has_group = 1; data->has_group = 1;
data->key_mgmt = WPA_KEY_MGMT_OSEN; data->key_mgmt = WPA_KEY_MGMT_OSEN;
data->proto = WPA_PROTO_OSEN; data->proto = WPA_PROTO_OSEN;
} else if (rsn_ie_len >= 2 + 4 + 2 && rsn_ie[1] >= 4 + 2 &&
rsn_ie[1] == rsn_ie_len - 2 &&
(WPA_GET_BE32(&rsn_ie[2]) == RSNE_OVERRIDE_IE_VENDOR_TYPE ||
WPA_GET_BE32(&rsn_ie[2]) ==
RSNE_OVERRIDE_2_IE_VENDOR_TYPE) &&
WPA_GET_LE16(&rsn_ie[2 + 4]) == RSN_VERSION) {
pos = rsn_ie + 2 + 4 + 2;
left = rsn_ie_len - 2 - 4 - 2;
} else { } else {
const struct rsn_ie_hdr *hdr; const struct rsn_ie_hdr *hdr;
@ -3448,7 +3440,7 @@ static int wpa_parse_generic(const u8 *pos, struct wpa_eapol_ie_parse *ie)
const u8 *p; const u8 *p;
size_t left; size_t left;
u8 link_id; u8 link_id;
char title[100]; char title[50];
int ret; int ret;
if (len == 0) if (len == 0)
@ -3629,57 +3621,6 @@ static int wpa_parse_generic(const u8 *pos, struct wpa_eapol_ie_parse *ie)
return 0; return 0;
} }
if (left >= 1 && selector == WFA_KEY_DATA_RSN_OVERRIDE_LINK) {
link_id = p[0];
if (link_id >= MAX_NUM_MLD_LINKS)
return 2;
ie->rsn_override_link[link_id] = p;
ie->rsn_override_link_len[link_id] = left;
ret = os_snprintf(title, sizeof(title),
"RSN: Link ID %u - RSN Override Link KDE in EAPOL-Key",
link_id);
if (!os_snprintf_error(sizeof(title), ret))
wpa_hexdump(MSG_DEBUG, title, pos, dlen);
return 0;
}
if (selector == RSNE_OVERRIDE_IE_VENDOR_TYPE) {
ie->rsne_override = pos;
ie->rsne_override_len = dlen;
wpa_hexdump(MSG_DEBUG,
"RSN: RSNE Override element in EAPOL-Key",
ie->rsne_override, ie->rsne_override_len);
return 0;
}
if (selector == RSNE_OVERRIDE_2_IE_VENDOR_TYPE) {
ie->rsne_override_2 = pos;
ie->rsne_override_2_len = dlen;
wpa_hexdump(MSG_DEBUG,
"RSN: RSNE Override 2 element in EAPOL-Key",
ie->rsne_override_2, ie->rsne_override_2_len);
return 0;
}
if (selector == RSNXE_OVERRIDE_IE_VENDOR_TYPE) {
ie->rsnxe_override = pos;
ie->rsnxe_override_len = dlen;
wpa_hexdump(MSG_DEBUG,
"RSN: RSNXE Override element in EAPOL-Key",
ie->rsnxe_override, ie->rsnxe_override_len);
return 0;
}
if (selector == RSN_SELECTION_IE_VENDOR_TYPE) {
ie->rsn_selection = p;
ie->rsn_selection_len = left;
wpa_hexdump(MSG_DEBUG,
"RSN: RSN Selection element in EAPOL-Key",
ie->rsn_selection, ie->rsn_selection_len);
return 0;
}
return 2; return 2;
} }
@ -4319,24 +4260,3 @@ int wpa_pasn_add_extra_ies(struct wpabuf *buf, const u8 *extra_ies, size_t len)
} }
#endif /* CONFIG_PASN */ #endif /* CONFIG_PASN */
void rsn_set_snonce_cookie(u8 *snonce)
{
u8 *pos;
pos = snonce + WPA_NONCE_LEN - 6;
WPA_PUT_BE24(pos, OUI_WFA);
pos += 3;
WPA_PUT_BE24(pos, 0x000029);
}
bool rsn_is_snonce_cookie(const u8 *snonce)
{
const u8 *pos;
pos = snonce + WPA_NONCE_LEN - 6;
return WPA_GET_BE24(pos) == OUI_WFA &&
WPA_GET_BE24(pos + 3) == 0x000029;
}

View file

@ -144,7 +144,6 @@ WPA_CIPHER_BIP_CMAC_256)
#define WFA_KEY_DATA_IP_ADDR_ALLOC RSN_SELECTOR(0x50, 0x6f, 0x9a, 5) #define WFA_KEY_DATA_IP_ADDR_ALLOC RSN_SELECTOR(0x50, 0x6f, 0x9a, 5)
#define WFA_KEY_DATA_TRANSITION_DISABLE RSN_SELECTOR(0x50, 0x6f, 0x9a, 0x20) #define WFA_KEY_DATA_TRANSITION_DISABLE RSN_SELECTOR(0x50, 0x6f, 0x9a, 0x20)
#define WFA_KEY_DATA_DPP RSN_SELECTOR(0x50, 0x6f, 0x9a, 0x21) #define WFA_KEY_DATA_DPP RSN_SELECTOR(0x50, 0x6f, 0x9a, 0x21)
#define WFA_KEY_DATA_RSN_OVERRIDE_LINK RSN_SELECTOR(0x50, 0x6f, 0x9a, 0x2d)
#define WPA_OUI_TYPE RSN_SELECTOR(0x00, 0x50, 0xf2, 1) #define WPA_OUI_TYPE RSN_SELECTOR(0x00, 0x50, 0xf2, 1)
@ -644,14 +643,6 @@ struct wpa_pasn_params_data {
#define WPA_PASN_PUBKEY_COMPRESSED_1 0x03 #define WPA_PASN_PUBKEY_COMPRESSED_1 0x03
#define WPA_PASN_PUBKEY_UNCOMPRESSED 0x04 #define WPA_PASN_PUBKEY_UNCOMPRESSED 0x04
/* WPA3 specification - RSN Selection element */
enum rsn_selection_variant {
RSN_SELECTION_RSNE = 0,
RSN_SELECTION_RSNE_OVERRIDE = 1,
RSN_SELECTION_RSNE_OVERRIDE_2 = 2,
};
int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse, int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse,
int key_mgmt, bool reassoc_resp); int key_mgmt, bool reassoc_resp);
void wpa_ft_parse_ies_free(struct wpa_ft_ies *parse); void wpa_ft_parse_ies_free(struct wpa_ft_ies *parse);
@ -713,14 +704,6 @@ struct wpa_eapol_ie_parse {
u16 aid; u16 aid;
const u8 *wmm; const u8 *wmm;
size_t wmm_len; size_t wmm_len;
const u8 *rsn_selection;
size_t rsn_selection_len;
const u8 *rsne_override;
size_t rsne_override_len;
const u8 *rsne_override_2;
size_t rsne_override_2_len;
const u8 *rsnxe_override;
size_t rsnxe_override_len;
u16 valid_mlo_gtks; /* bitmap of valid link GTK KDEs */ u16 valid_mlo_gtks; /* bitmap of valid link GTK KDEs */
const u8 *mlo_gtk[MAX_NUM_MLD_LINKS]; const u8 *mlo_gtk[MAX_NUM_MLD_LINKS];
size_t mlo_gtk_len[MAX_NUM_MLD_LINKS]; size_t mlo_gtk_len[MAX_NUM_MLD_LINKS];
@ -733,8 +716,6 @@ struct wpa_eapol_ie_parse {
u16 valid_mlo_links; /* bitmap of valid MLO link KDEs */ u16 valid_mlo_links; /* bitmap of valid MLO link KDEs */
const u8 *mlo_link[MAX_NUM_MLD_LINKS]; const u8 *mlo_link[MAX_NUM_MLD_LINKS];
size_t mlo_link_len[MAX_NUM_MLD_LINKS]; size_t mlo_link_len[MAX_NUM_MLD_LINKS];
const u8 *rsn_override_link[MAX_NUM_MLD_LINKS];
size_t rsn_override_link_len[MAX_NUM_MLD_LINKS];
}; };
int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie); int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie);
@ -806,7 +787,4 @@ int wpa_pasn_parse_parameter_ie(const u8 *data, u8 len, bool from_ap,
void wpa_pasn_add_rsnxe(struct wpabuf *buf, u16 capab); void wpa_pasn_add_rsnxe(struct wpabuf *buf, u16 capab);
int wpa_pasn_add_extra_ies(struct wpabuf *buf, const u8 *extra_ies, size_t len); int wpa_pasn_add_extra_ies(struct wpabuf *buf, const u8 *extra_ies, size_t len);
void rsn_set_snonce_cookie(u8 *snonce);
bool rsn_is_snonce_cookie(const u8 *snonce);
#endif /* WPA_COMMON_H */ #endif /* WPA_COMMON_H */

View file

@ -13,8 +13,6 @@
extern "C" { extern "C" {
#endif #endif
#define WPA_CTRL_IFACE_LINK_NAME "link"
/* wpa_supplicant control interface - fixed message prefixes */ /* wpa_supplicant control interface - fixed message prefixes */
/** Interactive request for identity/password/pin */ /** Interactive request for identity/password/pin */
@ -206,7 +204,6 @@ extern "C" {
#define DPP_EVENT_CONFOBJ_SSID "DPP-CONFOBJ-SSID " #define DPP_EVENT_CONFOBJ_SSID "DPP-CONFOBJ-SSID "
#define DPP_EVENT_CONFOBJ_SSID_CHARSET "DPP-CONFOBJ-SSID-CHARSET " #define DPP_EVENT_CONFOBJ_SSID_CHARSET "DPP-CONFOBJ-SSID-CHARSET "
#define DPP_EVENT_CONFOBJ_PASS "DPP-CONFOBJ-PASS " #define DPP_EVENT_CONFOBJ_PASS "DPP-CONFOBJ-PASS "
#define DPP_EVENT_CONFOBJ_IDPASS "DPP-CONFOBJ-IDPASS "
#define DPP_EVENT_CONFOBJ_PSK "DPP-CONFOBJ-PSK " #define DPP_EVENT_CONFOBJ_PSK "DPP-CONFOBJ-PSK "
#define DPP_EVENT_CONNECTOR "DPP-CONNECTOR " #define DPP_EVENT_CONNECTOR "DPP-CONNECTOR "
#define DPP_EVENT_C_SIGN_KEY "DPP-C-SIGN-KEY " #define DPP_EVENT_C_SIGN_KEY "DPP-C-SIGN-KEY "
@ -228,7 +225,6 @@ extern "C" {
#define DPP_EVENT_CHIRP_STOPPED "DPP-CHIRP-STOPPED " #define DPP_EVENT_CHIRP_STOPPED "DPP-CHIRP-STOPPED "
#define DPP_EVENT_MUD_URL "DPP-MUD-URL " #define DPP_EVENT_MUD_URL "DPP-MUD-URL "
#define DPP_EVENT_BAND_SUPPORT "DPP-BAND-SUPPORT " #define DPP_EVENT_BAND_SUPPORT "DPP-BAND-SUPPORT "
#define DPP_EVENT_ENROLLEE_CAPABILITY "DPP-ENROLLEE-CAPABILITY "
#define DPP_EVENT_CSR "DPP-CSR " #define DPP_EVENT_CSR "DPP-CSR "
#define DPP_EVENT_CHIRP_RX "DPP-CHIRP-RX " #define DPP_EVENT_CHIRP_RX "DPP-CHIRP-RX "
#define DPP_EVENT_CONF_NEEDED "DPP-CONF-NEEDED " #define DPP_EVENT_CONF_NEEDED "DPP-CONF-NEEDED "

View file

@ -27,10 +27,6 @@
#endif /* CONFIG_MACSEC */ #endif /* CONFIG_MACSEC */
#include "utils/list.h" #include "utils/list.h"
struct nan_subscribe_params;
struct nan_publish_params;
enum nan_service_protocol_type;
#define HOSTAPD_CHAN_DISABLED 0x00000001 #define HOSTAPD_CHAN_DISABLED 0x00000001
#define HOSTAPD_CHAN_NO_IR 0x00000002 #define HOSTAPD_CHAN_NO_IR 0x00000002
#define HOSTAPD_CHAN_RADAR 0x00000008 #define HOSTAPD_CHAN_RADAR 0x00000008
@ -321,27 +317,6 @@ struct hostapd_hw_modes {
}; };
/**
* struct hostapd_multi_hw_info: Supported multiple underlying hardware info
*/
struct hostapd_multi_hw_info {
/**
* hw_idx - Hardware index
*/
u8 hw_idx;
/**
* start_freq - Frequency range start in MHz
*/
int start_freq;
/**
* end_freq - Frequency range end in MHz
*/
int end_freq;
};
#define IEEE80211_CAP_ESS 0x0001 #define IEEE80211_CAP_ESS 0x0001
#define IEEE80211_CAP_IBSS 0x0002 #define IEEE80211_CAP_IBSS 0x0002
#define IEEE80211_CAP_PRIVACY 0x0010 #define IEEE80211_CAP_PRIVACY 0x0010
@ -1388,12 +1363,6 @@ struct wpa_driver_associate_params {
* mld_params - MLD association parameters * mld_params - MLD association parameters
*/ */
struct wpa_driver_mld_params mld_params; struct wpa_driver_mld_params mld_params;
/**
* rsn_overriding - wpa_supplicant RSN overriding support
*/
bool rsn_overriding;
}; };
enum hide_ssid { enum hide_ssid {
@ -2361,10 +2330,6 @@ struct wpa_driver_capa {
#define WPA_DRIVER_FLAGS2_SAE_OFFLOAD_AP 0x0000000000100000ULL #define WPA_DRIVER_FLAGS2_SAE_OFFLOAD_AP 0x0000000000100000ULL
/** Driver supports TWT responder in HT and VHT modes */ /** Driver supports TWT responder in HT and VHT modes */
#define WPA_DRIVER_FLAGS2_HT_VHT_TWT_RESPONDER 0x0000000000200000ULL #define WPA_DRIVER_FLAGS2_HT_VHT_TWT_RESPONDER 0x0000000000200000ULL
/** Driver supports RSN override elements */
#define WPA_DRIVER_FLAGS2_RSN_OVERRIDE_STA 0x0000000000400000ULL
/** Driver supports NAN offload */
#define WPA_DRIVER_FLAGS2_NAN_OFFLOAD 0x0000000000800000ULL
u64 flags2; u64 flags2;
#define FULL_AP_CLIENT_STATE_SUPP(drv_flags) \ #define FULL_AP_CLIENT_STATE_SUPP(drv_flags) \
@ -5229,19 +5194,15 @@ struct wpa_driver_ops {
/** /**
* is_drv_shared - Check whether the driver interface is shared * is_drv_shared - Check whether the driver interface is shared
* @priv: Private driver interface data from init() * @priv: Private driver interface data from init()
* @link_id: Link ID to match * @bss_ctx: BSS context for %WPA_IF_AP_BSS interfaces
* Returns: true if it is being used or else false.
* *
* Checks whether the driver interface is being used by other partner * Checks whether the driver interface is being used by other partner
* BSS(s) or not. This is used to decide whether the driver interface * BSS(s) or not. This is used to decide whether the driver interface
* needs to be deinitilized when one interface is getting deinitialized. * needs to be deinitilized when one interface is getting deinitialized.
* *
* NOTE: @link_id will be used only when there is only one BSS * Returns: true if it is being used or else false.
* present and if that single link is active. In that case, the
* link ID is matched with the active link_id to decide whether the
* driver interface is being used by other partner BSS(s).
*/ */
bool (*is_drv_shared)(void *priv, int link_id); bool (*is_drv_shared)(void *priv, void *bss_ctx);
/** /**
* link_sta_remove - Remove a link STA from an MLD STA * link_sta_remove - Remove a link STA from an MLD STA
@ -5252,94 +5213,11 @@ struct wpa_driver_ops {
*/ */
int (*link_sta_remove)(void *priv, u8 link_id, const u8 *addr); int (*link_sta_remove)(void *priv, u8 link_id, const u8 *addr);
/**
* nan_flush - Flush all NAN offload services
* @priv: Private driver interface data
* Returns: 0 on success, negative value on failure
*/
int (*nan_flush)(void *priv);
/**
* nan_publish - NAN offload for Publish()
* @priv: Private driver interface data
* @src: Source P2P device addr
* @publish_id: Publish instance to add
* @service_name: Service name
* @service_id: Service ID (6 octet value derived from service name)
* @srv_proto_type: Service protocol type
* @ssi: Service specific information or %NULL
* @elems: Information elements for Element Container attribute or %NULL
* @params: Configuration parameters
* Returns: 0 on success, negative value on failure
*/
int (*nan_publish)(void *priv, const u8 *src, int publish_id,
const char *service_name, const u8 *service_id,
enum nan_service_protocol_type srv_proto_type,
const struct wpabuf *ssi, const struct wpabuf *elems,
struct nan_publish_params *params);
/**
* nan_cancel_publish - NAN offload for CancelPublish()
* @priv: Private driver interface data
* @publish_id: Publish instance to cancel
* Returns: 0 on success, negative value on failure
*/
int (*nan_cancel_publish)(void *priv, int publish_id);
/**
* nan_update_publish - NAN offload for UpdatePublish()
* @priv: Private driver interface data
* @ssi: Service specific information or %NULL
* Returns: 0 on success, negative value on failure
*/
int (*nan_update_publish)(void *priv, int publish_id,
const struct wpabuf *ssi);
/**
* nan_subscribe - NAN offload for Subscribe()
* @priv: Private driver interface data
* @src: Source P2P device addr
* @subscribe_id: Subscribe instance to add
* @service_name: Service name
* @service_id: Service ID (6 octet value derived from service name)
* @srv_proto_type: Service protocol type
* @ssi: Service specific information or %NULL
* @elems: Information elements for Element Container attribute or %NULL
* @params: Configuration parameters
* Returns: 0 on success, negative value on failure
*/
int (*nan_subscribe)(void *priv, const u8 *src, int subscribe_id,
const char *service_name, const u8 *service_id,
enum nan_service_protocol_type srv_proto_type,
const struct wpabuf *ssi,
const struct wpabuf *elems,
struct nan_subscribe_params *params);
/**
* nan_cancel_subscribe - NAN offload for CancelSubscribe()
* @priv: Private driver interface data
* @subscribe_id: Subscribe instance to cancel
* Returns: 0 on success, negative value on failure
*/
int (*nan_cancel_subscribe)(void *priv, int subscribe_id);
#ifdef CONFIG_TESTING_OPTIONS #ifdef CONFIG_TESTING_OPTIONS
int (*register_frame)(void *priv, u16 type, int (*register_frame)(void *priv, u16 type,
const u8 *match, size_t match_len, const u8 *match, size_t match_len,
bool multicast); bool multicast);
#endif /* CONFIG_TESTING_OPTIONS */ #endif /* CONFIG_TESTING_OPTIONS */
/**
* get_multi_hw_info - Get multiple underlying hardware information
* (hardware IDx and supported frequency range)
* @priv: Private driver interface data
* @num_multi_hws: Variable for returning the number of returned
* hardware info data
* Returns: Pointer to allocated multiple hardware data on success
* or %NULL on failure. Caller is responsible for freeing this.
*/
struct hostapd_multi_hw_info *
(*get_multi_hw_info)(void *priv, unsigned int *num_multi_hws);
}; };
/** /**
@ -5967,11 +5845,6 @@ enum wpa_event_type {
* EVENT_LINK_RECONFIG - Notification that AP links removed * EVENT_LINK_RECONFIG - Notification that AP links removed
*/ */
EVENT_LINK_RECONFIG, EVENT_LINK_RECONFIG,
/**
* EVENT_MLD_INTERFACE_FREED - Notification of AP MLD interface removal
*/
EVENT_MLD_INTERFACE_FREED,
}; };

View file

@ -100,7 +100,6 @@ const char * event_to_string(enum wpa_event_type event)
E2S(LINK_CH_SWITCH_STARTED); E2S(LINK_CH_SWITCH_STARTED);
E2S(TID_LINK_MAP); E2S(TID_LINK_MAP);
E2S(LINK_RECONFIG); E2S(LINK_RECONFIG);
E2S(MLD_INTERFACE_FREED);
} }
return "UNKNOWN"; return "UNKNOWN";

View file

@ -19,7 +19,6 @@
#include <netlink/route/link.h> #include <netlink/route/link.h>
#include <netlink/route/link/macsec.h> #include <netlink/route/link/macsec.h>
#include <linux/if_macsec.h> #include <linux/if_macsec.h>
#include <linux/version.h>
#include <inttypes.h> #include <inttypes.h>
#include "utils/common.h" #include "utils/common.h"
@ -33,8 +32,7 @@
#define UNUSED_SCI 0xffffffffffffffff #define UNUSED_SCI 0xffffffffffffffff
#if (LIBNL_VER_NUM >= LIBNL_VER(3, 6) && \ #if LIBNL_VER_NUM >= LIBNL_VER(3, 6)
LINUX_VERSION_CODE >= KERNEL_VERSION(5, 7, 0))
#define LIBNL_HAS_OFFLOAD #define LIBNL_HAS_OFFLOAD
#endif #endif

View file

@ -3083,7 +3083,7 @@ static int wpa_driver_nl80211_del_beacon(struct i802_bss *bss,
struct wpa_driver_nl80211_data *drv = bss->drv; struct wpa_driver_nl80211_data *drv = bss->drv;
struct i802_link *link = nl80211_get_link(bss, link_id); struct i802_link *link = nl80211_get_link(bss, link_id);
if (!link || !link->beacon_set) if (!link->beacon_set)
return 0; return 0;
wpa_printf(MSG_DEBUG, "nl80211: Remove beacon (ifindex=%d)", wpa_printf(MSG_DEBUG, "nl80211: Remove beacon (ifindex=%d)",
@ -3151,6 +3151,9 @@ static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
bss->ifname, bss->brname, strerror(errno)); bss->ifname, bss->brname, strerror(errno));
} }
if (drv->rtnl_sk)
nl_socket_free(drv->rtnl_sk);
if (bss->added_bridge) { if (bss->added_bridge) {
if (linux_set_iface_flags(drv->global->ioctl_sock, bss->brname, if (linux_set_iface_flags(drv->global->ioctl_sock, bss->brname,
0) < 0) 0) < 0)
@ -3170,9 +3173,6 @@ static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
nl80211_remove_links(bss); nl80211_remove_links(bss);
} }
if (drv->rtnl_sk)
nl_socket_free(drv->rtnl_sk);
if (drv->eapol_sock >= 0) { if (drv->eapol_sock >= 0) {
eloop_unregister_read_sock(drv->eapol_sock); eloop_unregister_read_sock(drv->eapol_sock);
close(drv->eapol_sock); close(drv->eapol_sock);
@ -3189,7 +3189,7 @@ static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
eloop_cancel_timeout(wpa_driver_nl80211_send_rfkill, drv, drv->ctx); eloop_cancel_timeout(wpa_driver_nl80211_send_rfkill, drv, drv->ctx);
rfkill_deinit(drv->rfkill); rfkill_deinit(drv->rfkill);
eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, bss->ctx); eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
if (!drv->start_iface_up) if (!drv->start_iface_up)
(void) i802_set_iface_flags(bss, 0); (void) i802_set_iface_flags(bss, 0);
@ -4207,22 +4207,6 @@ struct i802_link * nl80211_get_link(struct i802_bss *bss, s8 link_id)
} }
u8 nl80211_get_link_id_from_link(struct i802_bss *bss, struct i802_link *link)
{
u8 link_id;
if (link == bss->flink)
return 0;
for_each_link(bss->valid_links, link_id) {
if (&bss->links[link_id] == link)
return link_id;
}
return 0;
}
static void nl80211_link_set_freq(struct i802_bss *bss, s8 link_id, int freq) static void nl80211_link_set_freq(struct i802_bss *bss, s8 link_id, int freq)
{ {
struct i802_link *link = nl80211_get_link(bss, link_id); struct i802_link *link = nl80211_get_link(bss, link_id);
@ -5881,15 +5865,13 @@ fail:
} }
static void rtnl_neigh_delete_fdb_entry(struct i802_bss *bss, const u8 *addr, static void rtnl_neigh_delete_fdb_entry(struct i802_bss *bss, const u8 *addr)
bool is_bridge)
{ {
struct wpa_driver_nl80211_data *drv = bss->drv; struct wpa_driver_nl80211_data *drv = bss->drv;
struct ndmsg nhdr = { struct ndmsg nhdr = {
.ndm_state = NUD_PERMANENT, .ndm_state = NUD_PERMANENT,
.ndm_ifindex = is_bridge ? bss->br_ifindex : bss->ifindex, .ndm_ifindex = bss->ifindex,
.ndm_family = AF_BRIDGE, .ndm_family = AF_BRIDGE,
.ndm_type = is_bridge ? NTF_SELF : 0,
}; };
struct nl_msg *msg; struct nl_msg *msg;
int err; int err;
@ -5906,61 +5888,11 @@ static void rtnl_neigh_delete_fdb_entry(struct i802_bss *bss, const u8 *addr,
err = nl_wait_for_ack(drv->rtnl_sk); err = nl_wait_for_ack(drv->rtnl_sk);
if (err < 0) { if (err < 0) {
wpa_printf(MSG_DEBUG, "nl80211: bridge FDB entry delete for " wpa_printf(MSG_DEBUG, "nl80211: bridge FDB entry delete for "
MACSTR " ifindex=%d ifname %s failed: %s", MACSTR " ifindex=%d failed: %s", MAC2STR(addr),
MAC2STR(addr), bss->ifindex, nl_geterror(err));
is_bridge ? bss->br_ifindex : bss->ifindex,
is_bridge ? bss->brname : bss->ifname,
nl_geterror(err));
} else { } else {
wpa_printf(MSG_DEBUG, "nl80211: deleted bridge FDB entry " wpa_printf(MSG_DEBUG, "nl80211: deleted bridge FDB entry for "
MACSTR " from %s", MACSTR, MAC2STR(addr));
MAC2STR(addr),
is_bridge ? bss->brname : bss->ifname);
}
errout:
nlmsg_free(msg);
}
static void rtnl_neigh_add_fdb_entry(struct i802_bss *bss, const u8 *addr,
bool is_bridge)
{
struct wpa_driver_nl80211_data *drv = bss->drv;
struct ndmsg nhdr = {
.ndm_state = NUD_PERMANENT,
.ndm_ifindex = is_bridge ? bss->br_ifindex : bss->ifindex,
.ndm_family = AF_BRIDGE,
/* TODO: remove this check if this flag needs to be used,
* for other interfaces type.
*/
.ndm_flags = is_bridge ? NTF_SELF : 0,
};
struct nl_msg *msg;
int err;
msg = nlmsg_alloc_simple(RTM_NEWNEIGH, NLM_F_CREATE);
if (!msg)
return;
if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0 ||
nla_put(msg, NDA_LLADDR, ETH_ALEN, (void *) addr) ||
nl_send_auto_complete(drv->rtnl_sk, msg) < 0)
goto errout;
err = nl_wait_for_ack(drv->rtnl_sk);
if (err < 0) {
wpa_printf(MSG_DEBUG, "nl80211: bridge FDB entry addition for "
MACSTR " ifindex=%d ifname %s failed: %s",
MAC2STR(addr),
is_bridge ? bss->br_ifindex : bss->ifindex,
is_bridge ? bss->brname : bss->ifname,
nl_geterror(err));
} else {
wpa_printf(MSG_DEBUG, "nl80211: added bridge FDB entry " MACSTR
" to %s",
MAC2STR(addr),
is_bridge ? bss->brname : bss->ifname);
} }
errout: errout:
@ -5995,7 +5927,7 @@ static int wpa_driver_nl80211_sta_remove(struct i802_bss *bss, const u8 *addr,
bss->ifname, MAC2STR(addr), ret, strerror(-ret)); bss->ifname, MAC2STR(addr), ret, strerror(-ret));
if (drv->rtnl_sk) if (drv->rtnl_sk)
rtnl_neigh_delete_fdb_entry(bss, addr, false); rtnl_neigh_delete_fdb_entry(bss, addr);
if (ret == -ENOENT) if (ret == -ENOENT)
return 0; return 0;
@ -7134,60 +7066,6 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
} }
#ifdef CONFIG_DRIVER_NL80211_QCA
static void connect_ext_feature_set(u8 *features,
enum qca_wlan_connect_ext_features idx)
{
u8 *idx_byte = &features[idx / 8];
*idx_byte |= BIT(idx % 8);
}
#endif /* CONFIG_DRIVER_NL80211_QCA */
static int nl80211_connect_ext(struct wpa_driver_nl80211_data *drv,
struct wpa_driver_associate_params *params)
{
#ifdef CONFIG_DRIVER_NL80211_QCA
struct nl_msg *msg;
struct nlattr *attr;
u8 features[(NUM_QCA_CONNECT_EXT_FEATURES + 7) / 8] = {};
if (!drv->connect_ext_vendor_cmd_avail)
return -1;
wpa_printf(MSG_DEBUG, "nl80211: Connect_ext (ifindex=%d)",
drv->ifindex);
if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
QCA_NL80211_VENDOR_SUBCMD_CONNECT_EXT))
goto fail;
attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
if (!attr)
goto fail;
if (params->rsn_overriding) {
wpa_printf(MSG_DEBUG, "- RSN overriding");
connect_ext_feature_set(features, QCA_CONNECT_EXT_FEATURE_RSNO);
}
if (nla_put(msg, QCA_WLAN_VENDOR_ATTR_CONNECT_EXT_FEATURES,
sizeof(features), features))
goto fail;
nla_nest_end(msg, attr);
return send_and_recv_cmd(drv, msg);
fail:
nlmsg_free(msg);
#endif /* CONFIG_DRIVER_NL80211_QCA */
return -1;
}
static int wpa_driver_nl80211_try_connect( static int wpa_driver_nl80211_try_connect(
struct wpa_driver_nl80211_data *drv, struct wpa_driver_nl80211_data *drv,
struct wpa_driver_associate_params *params, struct wpa_driver_associate_params *params,
@ -7209,7 +7087,6 @@ static int wpa_driver_nl80211_try_connect(
} }
#endif /* CONFIG_DRIVER_NL80211_QCA */ #endif /* CONFIG_DRIVER_NL80211_QCA */
nl80211_connect_ext(drv, params);
wpa_printf(MSG_DEBUG, "nl80211: Connect (ifindex=%d)", drv->ifindex); wpa_printf(MSG_DEBUG, "nl80211: Connect (ifindex=%d)", drv->ifindex);
msg = nl80211_drv_msg(drv, 0, NL80211_CMD_CONNECT); msg = nl80211_drv_msg(drv, 0, NL80211_CMD_CONNECT);
if (!msg) if (!msg)
@ -8543,7 +8420,6 @@ static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val,
struct wpa_driver_nl80211_data *drv = bss->drv; struct wpa_driver_nl80211_data *drv = bss->drv;
char name[IFNAMSIZ + 1]; char name[IFNAMSIZ + 1];
union wpa_event_data event; union wpa_event_data event;
bool add_br = false;
int ret; int ret;
ret = os_snprintf(name, sizeof(name), "%s.sta%d", bss->ifname, aid); ret = os_snprintf(name, sizeof(name), "%s.sta%d", bss->ifname, aid);
@ -8565,9 +8441,10 @@ static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val,
bss->addr, 1, NULL, NULL, 0) < bss->addr, 1, NULL, NULL, 0) <
0) 0)
return -1; return -1;
if (bridge_ifname &&
if (bridge_ifname) linux_br_add_if(drv->global->ioctl_sock,
add_br = true; bridge_ifname, name) < 0)
return -1;
os_memset(&event, 0, sizeof(event)); os_memset(&event, 0, sizeof(event));
event.wds_sta_interface.sta_addr = addr; event.wds_sta_interface.sta_addr = addr;
@ -8581,12 +8458,6 @@ static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val,
wpa_printf(MSG_ERROR, "nl80211: Failed to set WDS STA " wpa_printf(MSG_ERROR, "nl80211: Failed to set WDS STA "
"interface %s up", name); "interface %s up", name);
} }
if (add_br &&
linux_br_add_if(drv->global->ioctl_sock,
bridge_ifname, name) < 0)
return -1;
return i802_set_sta_vlan(priv, addr, name, 0, return i802_set_sta_vlan(priv, addr, name, 0,
NL80211_DRV_LINK_ID_NA); NL80211_DRV_LINK_ID_NA);
} else { } else {
@ -9571,14 +9442,13 @@ fail:
} }
int nl80211_remove_link(struct i802_bss *bss, int link_id) static int nl80211_remove_link(struct i802_bss *bss, int link_id)
{ {
struct wpa_driver_nl80211_data *drv = bss->drv; struct wpa_driver_nl80211_data *drv = bss->drv;
struct i802_link *link; struct i802_link *link;
struct nl_msg *msg; struct nl_msg *msg;
size_t i; size_t i;
int ret; int ret;
u8 link_addr[ETH_ALEN];
wpa_printf(MSG_DEBUG, "nl80211: Remove link (ifindex=%d link_id=%u)", wpa_printf(MSG_DEBUG, "nl80211: Remove link (ifindex=%d link_id=%u)",
bss->ifindex, link_id); bss->ifindex, link_id);
@ -9593,7 +9463,6 @@ int nl80211_remove_link(struct i802_bss *bss, int link_id)
wpa_driver_nl80211_del_beacon(bss, link_id); wpa_driver_nl80211_del_beacon(bss, link_id);
os_memcpy(link_addr, link->addr, ETH_ALEN);
/* First remove the link locally */ /* First remove the link locally */
bss->valid_links &= ~BIT(link_id); bss->valid_links &= ~BIT(link_id);
os_memset(link->addr, 0, ETH_ALEN); os_memset(link->addr, 0, ETH_ALEN);
@ -9631,9 +9500,6 @@ int nl80211_remove_link(struct i802_bss *bss, int link_id)
"nl80211: remove link (%d) failed. ret=%d (%s)", "nl80211: remove link (%d) failed. ret=%d (%s)",
link_id, ret, strerror(-ret)); link_id, ret, strerror(-ret));
if (drv->rtnl_sk)
rtnl_neigh_delete_fdb_entry(bss, link_addr, true);
return ret; return ret;
} }
@ -10033,9 +9899,6 @@ static int nl80211_set_param(void *priv, const char *param)
WPA_DRIVER_FLAGS2_SEC_LTF_AP; WPA_DRIVER_FLAGS2_SEC_LTF_AP;
} }
if (os_strstr(param, "rsn_override_in_driver=1"))
drv->capa.flags2 |= WPA_DRIVER_FLAGS2_RSN_OVERRIDE_STA;
return 0; return 0;
} }
@ -10386,8 +10249,6 @@ static int wpa_driver_nl80211_get_survey(void *priv, unsigned int freq)
int err; int err;
union wpa_event_data data; union wpa_event_data data;
struct survey_results *survey_results; struct survey_results *survey_results;
void *ctx = (bss->scan_link && bss->scan_link->ctx) ?
bss->scan_link->ctx : bss->ctx;
os_memset(&data, 0, sizeof(data)); os_memset(&data, 0, sizeof(data));
survey_results = &data.survey_results; survey_results = &data.survey_results;
@ -10410,7 +10271,7 @@ static int wpa_driver_nl80211_get_survey(void *priv, unsigned int freq)
if (err) if (err)
wpa_printf(MSG_ERROR, "nl80211: Failed to process survey data"); wpa_printf(MSG_ERROR, "nl80211: Failed to process survey data");
else else
wpa_supplicant_event(ctx, EVENT_SURVEY, &data); wpa_supplicant_event(drv->ctx, EVENT_SURVEY, &data);
clean_survey_results(survey_results); clean_survey_results(survey_results);
return err; return err;
@ -10883,7 +10744,6 @@ static int driver_nl80211_link_remove(void *priv, enum wpa_driver_if_type type,
{ {
struct i802_bss *bss = priv; struct i802_bss *bss = priv;
struct wpa_driver_nl80211_data *drv = bss->drv; struct wpa_driver_nl80211_data *drv = bss->drv;
int ret;
if (type != WPA_IF_AP_BSS || if (type != WPA_IF_AP_BSS ||
!nl80211_link_valid(bss->valid_links, link_id)) !nl80211_link_valid(bss->valid_links, link_id))
@ -10903,25 +10763,18 @@ static int driver_nl80211_link_remove(void *priv, enum wpa_driver_if_type type,
if (!bss->valid_links) { if (!bss->valid_links) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"nl80211: No more links remaining, so remove interface"); "nl80211: No more links remaining, so remove interface");
ret = wpa_driver_nl80211_if_remove(bss, type, ifname); return wpa_driver_nl80211_if_remove(bss, type, ifname);
if (ret)
return ret;
/* Notify that the MLD interface is removed */
wpa_supplicant_event(bss->ctx, EVENT_MLD_INTERFACE_FREED, NULL);
} }
return 0; return 0;
} }
static bool nl80211_is_drv_shared(void *priv, int link_id) static bool nl80211_is_drv_shared(void *priv, void *bss_ctx)
{ {
struct i802_bss *bss = priv; struct i802_bss *bss = priv;
struct wpa_driver_nl80211_data *drv = bss->drv; struct wpa_driver_nl80211_data *drv = bss->drv;
unsigned int num_bss = 0, num_links = 0; unsigned int num_bss = 0;
bool self = false;
u8 i;
/* If any other BSS exist, someone else is using this since at this /* If any other BSS exist, someone else is using this since at this
* time, we would have removed all BSSs created by this driver and only * time, we would have removed all BSSs created by this driver and only
@ -10936,23 +10789,13 @@ static bool nl80211_is_drv_shared(void *priv, int link_id)
/* This is the only BSS present */ /* This is the only BSS present */
bss = priv; bss = priv;
for_each_link(bss->valid_links, i) { /* If only one/no link is there no one is sharing */
num_links++; if (bss->valid_links <= 1)
if (i == link_id)
self = true;
}
/* More than one links means some one is still sharing */
if (num_links > 1)
return true;
/* Even if only one link is there, it should match the given
* link ID to assert that no one else is sharing. */
if (num_links == 1 && self)
return false; return false;
/* No links are active means no one is sharing */ /* More than one link means someone is still using. To check if
if (num_links == 0) * only 1 bit is set, power of 2 condition can be checked. */
if (!(bss->valid_links & (bss->valid_links - 1)))
return false; return false;
return true; return true;
@ -14075,10 +13918,6 @@ static int nl80211_link_add(void *priv, u8 link_id, const u8 *addr,
wpa_printf(MSG_DEBUG, "nl80211: MLD: valid_links=0x%04x on %s", wpa_printf(MSG_DEBUG, "nl80211: MLD: valid_links=0x%04x on %s",
bss->valid_links, bss->ifname); bss->valid_links, bss->ifname);
if (drv->rtnl_sk)
rtnl_neigh_add_fdb_entry(bss, addr, true);
return 0; return 0;
} }
@ -14158,15 +13997,6 @@ static int testing_nl80211_radio_disable(void *priv, int disabled)
#endif /* CONFIG_TESTING_OPTIONS */ #endif /* CONFIG_TESTING_OPTIONS */
static struct hostapd_multi_hw_info *
wpa_driver_get_multi_hw_info(void *priv, unsigned int *num_multi_hws)
{
struct i802_bss *bss = priv;
return nl80211_get_multi_hw_info(bss, num_multi_hws);
}
const struct wpa_driver_ops wpa_driver_nl80211_ops = { const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.name = "nl80211", .name = "nl80211",
.desc = "Linux nl80211/cfg80211", .desc = "Linux nl80211/cfg80211",
@ -14325,5 +14155,4 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.register_frame = testing_nl80211_register_frame, .register_frame = testing_nl80211_register_frame,
.radio_disable = testing_nl80211_radio_disable, .radio_disable = testing_nl80211_radio_disable,
#endif /* CONFIG_TESTING_OPTIONS */ #endif /* CONFIG_TESTING_OPTIONS */
.get_multi_hw_info = wpa_driver_get_multi_hw_info,
}; };

View file

@ -67,7 +67,7 @@ struct i802_bss {
u16 valid_links; u16 valid_links;
struct i802_link links[MAX_NUM_MLD_LINKS]; struct i802_link links[MAX_NUM_MLD_LINKS];
struct i802_link *flink, *scan_link; struct i802_link *flink;
int ifindex; int ifindex;
int br_ifindex; int br_ifindex;
@ -200,7 +200,6 @@ struct wpa_driver_nl80211_data {
unsigned int secure_ranging_ctx_vendor_cmd_avail:1; unsigned int secure_ranging_ctx_vendor_cmd_avail:1;
unsigned int puncturing:1; unsigned int puncturing:1;
unsigned int qca_ap_allowed_freqs:1; unsigned int qca_ap_allowed_freqs:1;
unsigned int connect_ext_vendor_cmd_avail:1;
u32 ignore_next_local_disconnect; u32 ignore_next_local_disconnect;
u32 ignore_next_local_deauth; u32 ignore_next_local_deauth;
@ -353,8 +352,6 @@ const char * nl80211_iftype_str(enum nl80211_iftype mode);
void nl80211_restore_ap_mode(struct i802_bss *bss); void nl80211_restore_ap_mode(struct i802_bss *bss);
struct i802_link * nl80211_get_link(struct i802_bss *bss, s8 link_id); struct i802_link * nl80211_get_link(struct i802_bss *bss, s8 link_id);
u8 nl80211_get_link_id_from_link(struct i802_bss *bss, struct i802_link *link);
int nl80211_remove_link(struct i802_bss *bss, int link_id);
static inline bool nl80211_link_valid(u16 links, s8 link_id) static inline bool nl80211_link_valid(u16 links, s8 link_id)
{ {
@ -412,7 +409,5 @@ int wpa_driver_nl80211_abort_scan(void *priv, u64 scan_cookie);
int wpa_driver_nl80211_vendor_scan(struct i802_bss *bss, int wpa_driver_nl80211_vendor_scan(struct i802_bss *bss,
struct wpa_driver_scan_params *params); struct wpa_driver_scan_params *params);
int nl80211_set_default_scan_ies(void *priv, const u8 *ies, size_t ies_len); int nl80211_set_default_scan_ies(void *priv, const u8 *ies, size_t ies_len);
struct hostapd_multi_hw_info *
nl80211_get_multi_hw_info(struct i802_bss *bss, unsigned int *num_multi_hws);
#endif /* DRIVER_NL80211_H */ #endif /* DRIVER_NL80211_H */

View file

@ -1120,9 +1120,6 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
case QCA_NL80211_VENDOR_SUBCMD_SECURE_RANGING_CONTEXT: case QCA_NL80211_VENDOR_SUBCMD_SECURE_RANGING_CONTEXT:
drv->secure_ranging_ctx_vendor_cmd_avail = 1; drv->secure_ranging_ctx_vendor_cmd_avail = 1;
break; break;
case QCA_NL80211_VENDOR_SUBCMD_CONNECT_EXT:
drv->connect_ext_vendor_cmd_avail = 1;
break;
#endif /* CONFIG_DRIVER_NL80211_QCA */ #endif /* CONFIG_DRIVER_NL80211_QCA */
} }
#ifdef CONFIG_DRIVER_NL80211_BRCM #ifdef CONFIG_DRIVER_NL80211_BRCM
@ -1446,12 +1443,6 @@ static void qca_nl80211_get_features(struct wpa_driver_nl80211_data *drv)
drv->qca_ap_allowed_freqs = 1; drv->qca_ap_allowed_freqs = 1;
if (check_feature(QCA_WLAN_VENDOR_FEATURE_HT_VHT_TWT_RESPONDER, &info)) if (check_feature(QCA_WLAN_VENDOR_FEATURE_HT_VHT_TWT_RESPONDER, &info))
drv->capa.flags2 |= WPA_DRIVER_FLAGS2_HT_VHT_TWT_RESPONDER; drv->capa.flags2 |= WPA_DRIVER_FLAGS2_HT_VHT_TWT_RESPONDER;
if (check_feature(QCA_WLAN_VENDOR_FEATURE_RSN_OVERRIDE_STA, &info)) {
wpa_printf(MSG_DEBUG,
"The driver supports RSN overriding in STA mode");
drv->capa.flags2 |= WPA_DRIVER_FLAGS2_RSN_OVERRIDE_STA;
}
os_free(info.flags); os_free(info.flags);
} }
@ -1479,7 +1470,6 @@ int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK | WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK | WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK |
WPA_DRIVER_CAPA_KEY_MGMT_PSK_SHA256 |
WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B | WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B |
WPA_DRIVER_CAPA_KEY_MGMT_OWE | WPA_DRIVER_CAPA_KEY_MGMT_OWE |
WPA_DRIVER_CAPA_KEY_MGMT_DPP; WPA_DRIVER_CAPA_KEY_MGMT_DPP;
@ -1495,7 +1485,6 @@ int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384 | WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384 |
WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA256 | WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA256 |
WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA384 | WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA384 |
WPA_DRIVER_CAPA_KEY_MGMT_SAE_EXT_KEY |
WPA_DRIVER_CAPA_KEY_MGMT_SAE; WPA_DRIVER_CAPA_KEY_MGMT_SAE;
else if (drv->capa.flags & WPA_DRIVER_FLAGS_FILS_SK_OFFLOAD) else if (drv->capa.flags & WPA_DRIVER_FLAGS_FILS_SK_OFFLOAD)
drv->capa.key_mgmt |= drv->capa.key_mgmt |=
@ -2739,133 +2728,3 @@ nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags,
return NULL; return NULL;
} }
static int phy_multi_hw_info_parse(struct hostapd_multi_hw_info *hw_info,
struct nlattr *radio_attr)
{
struct nlattr *tb_freq[NL80211_WIPHY_RADIO_FREQ_ATTR_MAX + 1];
int start_freq, end_freq;
switch (nla_type(radio_attr)) {
case NL80211_WIPHY_RADIO_ATTR_INDEX:
hw_info->hw_idx = nla_get_u32(radio_attr);
return NL_OK;
case NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE:
nla_parse_nested(tb_freq, NL80211_WIPHY_RADIO_FREQ_ATTR_MAX,
radio_attr, NULL);
if (!tb_freq[NL80211_WIPHY_RADIO_FREQ_ATTR_START] ||
!tb_freq[NL80211_WIPHY_RADIO_FREQ_ATTR_END])
return NL_STOP;
start_freq = nla_get_u32(
tb_freq[NL80211_WIPHY_RADIO_FREQ_ATTR_START]);
end_freq = nla_get_u32(
tb_freq[NL80211_WIPHY_RADIO_FREQ_ATTR_END]);
/* Convert to MHz and store */
hw_info->start_freq = start_freq / 1000;
hw_info->end_freq = end_freq / 1000;
return NL_OK;
default:
return NL_OK;
}
}
struct phy_multi_hw_info_arg {
bool failed;
unsigned int *num_multi_hws;
struct hostapd_multi_hw_info *multi_hws;
};
static int phy_multi_hw_info_handler(struct nl_msg *msg, void *arg)
{
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
struct phy_multi_hw_info_arg *multi_hw_info = arg;
struct hostapd_multi_hw_info *multi_hws, hw_info;
struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
struct nlattr *nl_hw, *radio_attr;
int rem_hw, rem_radio_prop, res;
nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);
if (!tb_msg[NL80211_ATTR_WIPHY_RADIOS])
return NL_SKIP;
*multi_hw_info->num_multi_hws = 0;
nla_for_each_nested(nl_hw, tb_msg[NL80211_ATTR_WIPHY_RADIOS], rem_hw) {
os_memset(&hw_info, 0, sizeof(hw_info));
nla_for_each_nested(radio_attr, nl_hw, rem_radio_prop) {
res = phy_multi_hw_info_parse(&hw_info, radio_attr);
if (res != NL_OK)
goto out;
}
if (hw_info.start_freq == 0 || hw_info.end_freq == 0)
goto out;
multi_hws = os_realloc_array(multi_hw_info->multi_hws,
*multi_hw_info->num_multi_hws + 1,
sizeof(*multi_hws));
if (!multi_hws)
goto out;
multi_hw_info->multi_hws = multi_hws;
os_memcpy(&multi_hws[*(multi_hw_info->num_multi_hws)],
&hw_info, sizeof(struct hostapd_multi_hw_info));
*(multi_hw_info->num_multi_hws) += 1;
}
return NL_OK;
out:
multi_hw_info->failed = true;
return NL_STOP;
}
struct hostapd_multi_hw_info *
nl80211_get_multi_hw_info(struct i802_bss *bss, unsigned int *num_multi_hws)
{
u32 feat;
struct wpa_driver_nl80211_data *drv = bss->drv;
int nl_flags = 0;
struct nl_msg *msg;
struct phy_multi_hw_info_arg result = {
.failed = false,
.num_multi_hws = num_multi_hws,
.multi_hws = NULL,
};
*num_multi_hws = 0;
if (!drv->has_capability || !(drv->capa.flags2 & WPA_DRIVER_FLAGS2_MLO))
return NULL;
feat = get_nl80211_protocol_features(drv);
if (feat & NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP)
nl_flags = NLM_F_DUMP;
if (!(msg = nl80211_cmd_msg(bss, nl_flags, NL80211_CMD_GET_WIPHY)) ||
nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP)) {
nlmsg_free(msg);
return NULL;
}
if (send_and_recv_resp(drv, msg, phy_multi_hw_info_handler,
&result) == 0) {
if (result.failed) {
os_free(result.multi_hws);
*num_multi_hws = 0;
return NULL;
}
return result.multi_hws;
}
return NULL;
}

View file

@ -186,7 +186,6 @@ static const char * nl80211_command_to_string(enum nl80211_commands cmd)
C2S(NL80211_CMD_REMOVE_LINK_STA) C2S(NL80211_CMD_REMOVE_LINK_STA)
C2S(NL80211_CMD_SET_HW_TIMESTAMP) C2S(NL80211_CMD_SET_HW_TIMESTAMP)
C2S(NL80211_CMD_LINKS_REMOVED) C2S(NL80211_CMD_LINKS_REMOVED)
C2S(NL80211_CMD_SET_TID_TO_LINK_MAPPING)
C2S(__NL80211_CMD_AFTER_LAST) C2S(__NL80211_CMD_AFTER_LAST)
} }
#undef C2S #undef C2S
@ -1205,6 +1204,9 @@ static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
int chan_offset = 0; int chan_offset = 0;
int ifidx; int ifidx;
wpa_printf(MSG_DEBUG, "nl80211: Channel switch%s event",
finished ? "" : " started");
if (!freq) if (!freq)
return; return;
@ -1216,9 +1218,6 @@ static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
return; return;
} }
wpa_printf(MSG_DEBUG, "nl80211: Channel switch%s event for %s",
finished ? "" : " started", bss->ifname);
if (type) { if (type) {
enum nl80211_channel_type ch_type = nla_get_u32(type); enum nl80211_channel_type ch_type = nla_get_u32(type);
@ -1261,13 +1260,10 @@ static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
if (cf2) if (cf2)
data.ch_switch.cf2 = nla_get_u32(cf2); data.ch_switch.cf2 = nla_get_u32(cf2);
if (link) { if (link)
data.ch_switch.link_id = nla_get_u8(link); data.ch_switch.link_id = nla_get_u8(link);
wpa_printf(MSG_DEBUG, "nl80211: Link ID: %d", else
data.ch_switch.link_id);
} else {
data.ch_switch.link_id = NL80211_DRV_LINK_ID_NA; data.ch_switch.link_id = NL80211_DRV_LINK_ID_NA;
}
if (finished) { if (finished) {
if (data.ch_switch.link_id != NL80211_DRV_LINK_ID_NA) { if (data.ch_switch.link_id != NL80211_DRV_LINK_ID_NA) {
@ -1304,14 +1300,6 @@ static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
return; return;
} }
if (link && is_ap_interface(drv->nlmode) &&
!nl80211_link_valid(bss->valid_links, data.ch_switch.link_id)) {
wpa_printf(MSG_WARNING,
"nl80211: Unknown link ID (%d) for channel switch (%s), ignoring",
data.ch_switch.link_id, bss->ifname);
return;
}
drv->assoc_freq = data.ch_switch.freq; drv->assoc_freq = data.ch_switch.freq;
wpa_supplicant_event(bss->ctx, finished ? wpa_supplicant_event(bss->ctx, finished ?
@ -1977,10 +1965,9 @@ static void mlme_event_dh_event(struct wpa_driver_nl80211_data *drv,
} }
static void send_scan_event(struct i802_bss *bss, int aborted, static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted,
struct nlattr *tb[], int external_scan) struct nlattr *tb[], int external_scan)
{ {
struct wpa_driver_nl80211_data *drv = bss->drv;
union wpa_event_data event; union wpa_event_data event;
struct nlattr *nl; struct nlattr *nl;
int rem; int rem;
@ -1988,8 +1975,6 @@ static void send_scan_event(struct i802_bss *bss, int aborted,
#define MAX_REPORT_FREQS 110 #define MAX_REPORT_FREQS 110
int freqs[MAX_REPORT_FREQS]; int freqs[MAX_REPORT_FREQS];
int num_freqs = 0; int num_freqs = 0;
struct i802_link *mld_link;
void *ctx = bss->ctx;
if (!external_scan && drv->scan_for_auth) { if (!external_scan && drv->scan_for_auth) {
drv->scan_for_auth = 0; drv->scan_for_auth = 0;
@ -2053,30 +2038,13 @@ static void send_scan_event(struct i802_bss *bss, int aborted,
ETH_ALEN); ETH_ALEN);
} }
/* Need to pass to the correct link ctx during AP MLD operation */ wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, &event);
if (is_ap_interface(drv->nlmode)) {
mld_link = bss->scan_link;
if (!mld_link) {
wpa_printf(MSG_DEBUG,
"nl80211: Scan event on unknown link");
} else if (mld_link->ctx) {
u8 link_id = nl80211_get_link_id_from_link(bss,
mld_link);
wpa_printf(MSG_DEBUG,
"nl80211: Scan event for link_id %d",
link_id);
ctx = mld_link->ctx;
}
}
wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, &event);
} }
static void nl80211_cqm_event(struct i802_bss *bss, struct nlattr *tb[]) static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
struct nlattr *tb[])
{ {
struct wpa_driver_nl80211_data *drv = bss->drv;
static struct nla_policy cqm_policy[NL80211_ATTR_CQM_MAX + 1] = { static struct nla_policy cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
[NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 }, [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 },
[NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U8 }, [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U8 },
@ -2111,7 +2079,7 @@ static void nl80211_cqm_event(struct i802_bss *bss, struct nlattr *tb[])
wpa_printf(MSG_DEBUG, "nl80211: Packet loss event for " MACSTR wpa_printf(MSG_DEBUG, "nl80211: Packet loss event for " MACSTR
" (num_packets %u)", " (num_packets %u)",
MAC2STR(ed.low_ack.addr), ed.low_ack.num_packets); MAC2STR(ed.low_ack.addr), ed.low_ack.num_packets);
wpa_supplicant_event(bss->ctx, EVENT_STATION_LOW_ACK, &ed); wpa_supplicant_event(drv->ctx, EVENT_STATION_LOW_ACK, &ed);
return; return;
} }
@ -2443,33 +2411,10 @@ static void nl80211_tdls_oper_event(struct wpa_driver_nl80211_data *drv,
} }
static void nl80211_stop_ap(struct i802_bss *bss, struct nlattr **tb) static void nl80211_stop_ap(struct wpa_driver_nl80211_data *drv,
struct nlattr **tb)
{ {
struct i802_link *mld_link = NULL; wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_UNAVAILABLE, NULL);
void *ctx = bss->ctx;
int link_id = -1;
if (tb[NL80211_ATTR_MLO_LINK_ID]) {
link_id = nla_get_u8(tb[NL80211_ATTR_MLO_LINK_ID]);
if (!nl80211_link_valid(bss->valid_links, link_id)) {
wpa_printf(MSG_DEBUG,
"nl80211: Ignoring STOP_AP event for invalid link ID %d (valid: 0x%04x)",
link_id, bss->valid_links);
return;
}
mld_link = nl80211_get_link(bss, link_id);
wpa_printf(MSG_DEBUG,
"nl80211: STOP_AP event on link %d", link_id);
ctx = mld_link->ctx;
/* The driver would have already deleted the link and this call
* will return an error. Ignore that since nl80211_remove_link()
* is called here only to update the bss->links[] state. */
nl80211_remove_link(bss, link_id);
}
wpa_supplicant_event(ctx, EVENT_INTERFACE_UNAVAILABLE, NULL);
} }
@ -3110,7 +3055,7 @@ static void qca_nl80211_scan_done_event(struct wpa_driver_nl80211_data *drv,
drv->scan_state = SCAN_ABORTED; drv->scan_state = SCAN_ABORTED;
eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
drv->first_bss->ctx); drv->ctx);
drv->vendor_scan_cookie = 0; drv->vendor_scan_cookie = 0;
drv->last_scan_cmd = 0; drv->last_scan_cmd = 0;
} }
@ -3949,7 +3894,7 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
switch (cmd) { switch (cmd) {
case NL80211_CMD_TRIGGER_SCAN: case NL80211_CMD_TRIGGER_SCAN:
wpa_dbg(bss->ctx, MSG_DEBUG, "nl80211: Scan trigger"); wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan trigger");
drv->scan_state = SCAN_STARTED; drv->scan_state = SCAN_STARTED;
if (drv->scan_for_auth) { if (drv->scan_for_auth) {
/* /*
@ -3961,40 +3906,40 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
wpa_printf(MSG_DEBUG, "nl80211: Do not indicate scan-start event due to internal scan_for_auth"); wpa_printf(MSG_DEBUG, "nl80211: Do not indicate scan-start event due to internal scan_for_auth");
break; break;
} }
wpa_supplicant_event(bss->ctx, EVENT_SCAN_STARTED, NULL); wpa_supplicant_event(drv->ctx, EVENT_SCAN_STARTED, NULL);
break; break;
case NL80211_CMD_START_SCHED_SCAN: case NL80211_CMD_START_SCHED_SCAN:
wpa_dbg(bss->ctx, MSG_DEBUG, "nl80211: Sched scan started"); wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan started");
drv->scan_state = SCHED_SCAN_STARTED; drv->scan_state = SCHED_SCAN_STARTED;
break; break;
case NL80211_CMD_SCHED_SCAN_STOPPED: case NL80211_CMD_SCHED_SCAN_STOPPED:
wpa_dbg(bss->ctx, MSG_DEBUG, "nl80211: Sched scan stopped"); wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan stopped");
drv->scan_state = SCHED_SCAN_STOPPED; drv->scan_state = SCHED_SCAN_STOPPED;
wpa_supplicant_event(bss->ctx, EVENT_SCHED_SCAN_STOPPED, NULL); wpa_supplicant_event(drv->ctx, EVENT_SCHED_SCAN_STOPPED, NULL);
break; break;
case NL80211_CMD_NEW_SCAN_RESULTS: case NL80211_CMD_NEW_SCAN_RESULTS:
wpa_dbg(bss->ctx, MSG_DEBUG, wpa_dbg(drv->ctx, MSG_DEBUG,
"nl80211: New scan results available"); "nl80211: New scan results available");
if (drv->last_scan_cmd != NL80211_CMD_VENDOR) if (drv->last_scan_cmd != NL80211_CMD_VENDOR)
drv->scan_state = SCAN_COMPLETED; drv->scan_state = SCAN_COMPLETED;
drv->scan_complete_events = 1; drv->scan_complete_events = 1;
if (drv->last_scan_cmd == NL80211_CMD_TRIGGER_SCAN) { if (drv->last_scan_cmd == NL80211_CMD_TRIGGER_SCAN) {
eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout,
drv, bss->ctx); drv, drv->ctx);
drv->last_scan_cmd = 0; drv->last_scan_cmd = 0;
} else { } else {
external_scan_event = 1; external_scan_event = 1;
} }
send_scan_event(bss, 0, tb, external_scan_event); send_scan_event(drv, 0, tb, external_scan_event);
break; break;
case NL80211_CMD_SCHED_SCAN_RESULTS: case NL80211_CMD_SCHED_SCAN_RESULTS:
wpa_dbg(bss->ctx, MSG_DEBUG, wpa_dbg(drv->ctx, MSG_DEBUG,
"nl80211: New sched scan results available"); "nl80211: New sched scan results available");
drv->scan_state = SCHED_SCAN_RESULTS; drv->scan_state = SCHED_SCAN_RESULTS;
send_scan_event(bss, 0, tb, 0); send_scan_event(drv, 0, tb, 0);
break; break;
case NL80211_CMD_SCAN_ABORTED: case NL80211_CMD_SCAN_ABORTED:
wpa_dbg(bss->ctx, MSG_DEBUG, "nl80211: Scan aborted"); wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan aborted");
if (drv->last_scan_cmd != NL80211_CMD_VENDOR) if (drv->last_scan_cmd != NL80211_CMD_VENDOR)
drv->scan_state = SCAN_ABORTED; drv->scan_state = SCAN_ABORTED;
if (drv->last_scan_cmd == NL80211_CMD_TRIGGER_SCAN) { if (drv->last_scan_cmd == NL80211_CMD_TRIGGER_SCAN) {
@ -4003,12 +3948,12 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
* order not to make wpa_supplicant stop its scanning. * order not to make wpa_supplicant stop its scanning.
*/ */
eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout,
drv, bss->ctx); drv, drv->ctx);
drv->last_scan_cmd = 0; drv->last_scan_cmd = 0;
} else { } else {
external_scan_event = 1; external_scan_event = 1;
} }
send_scan_event(bss, 1, tb, external_scan_event); send_scan_event(drv, 1, tb, external_scan_event);
break; break;
case NL80211_CMD_AUTHENTICATE: case NL80211_CMD_AUTHENTICATE:
case NL80211_CMD_ASSOCIATE: case NL80211_CMD_ASSOCIATE:
@ -4086,7 +4031,7 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
mlme_event_remain_on_channel(drv, 1, tb); mlme_event_remain_on_channel(drv, 1, tb);
break; break;
case NL80211_CMD_NOTIFY_CQM: case NL80211_CMD_NOTIFY_CQM:
nl80211_cqm_event(bss, tb); nl80211_cqm_event(drv, tb);
break; break;
case NL80211_CMD_REG_CHANGE: case NL80211_CMD_REG_CHANGE:
case NL80211_CMD_WIPHY_REG_CHANGE: case NL80211_CMD_WIPHY_REG_CHANGE:
@ -4123,7 +4068,7 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
nl80211_radar_event(drv, tb); nl80211_radar_event(drv, tb);
break; break;
case NL80211_CMD_STOP_AP: case NL80211_CMD_STOP_AP:
nl80211_stop_ap(bss, tb); nl80211_stop_ap(drv, tb);
break; break;
case NL80211_CMD_VENDOR: case NL80211_CMD_VENDOR:
nl80211_vendor_event(drv, tb); nl80211_vendor_event(drv, tb);
@ -4257,16 +4202,7 @@ int process_global_event(struct nl_msg *msg, void *arg)
wdev_id == bss->wdev_id)) { wdev_id == bss->wdev_id)) {
processed = true; processed = true;
do_process_drv_event(bss, gnlh->cmd, tb); do_process_drv_event(bss, gnlh->cmd, tb);
/* There are two types of events that may need if (!wiphy_idx_set)
* to be delivered to multiple interfaces:
* 1. Events for a wiphy, as it can have
* multiple interfaces.
* 2. "Global" events, like
* NL80211_CMD_REG_CHANGE.
*
* Terminate early only if the event is directed
* to a specific interface or wdev. */
if (ifidx != -1 || wdev_id_set)
return NL_SKIP; return NL_SKIP;
/* The driver instance could have been removed, /* The driver instance could have been removed,
* e.g., due to NL80211_CMD_RADAR_DETECT event, * e.g., due to NL80211_CMD_RADAR_DETECT event,

View file

@ -153,7 +153,6 @@ fail:
void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx) void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx)
{ {
struct wpa_driver_nl80211_data *drv = eloop_ctx; struct wpa_driver_nl80211_data *drv = eloop_ctx;
struct i802_bss *bss;
wpa_printf(MSG_DEBUG, "nl80211: Scan timeout - try to abort it"); wpa_printf(MSG_DEBUG, "nl80211: Scan timeout - try to abort it");
#ifdef CONFIG_DRIVER_NL80211_QCA #ifdef CONFIG_DRIVER_NL80211_QCA
@ -161,27 +160,14 @@ void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx)
nl80211_abort_vendor_scan(drv, drv->vendor_scan_cookie) == 0) nl80211_abort_vendor_scan(drv, drv->vendor_scan_cookie) == 0)
return; return;
#endif /* CONFIG_DRIVER_NL80211_QCA */ #endif /* CONFIG_DRIVER_NL80211_QCA */
for (bss = drv->first_bss; bss; bss = bss->next) {
if (bss->scan_link)
break;
}
if (!bss) {
wpa_printf(MSG_DEBUG, "nl80211: Failed to find scan BSS");
return;
}
if (!drv->vendor_scan_cookie && if (!drv->vendor_scan_cookie &&
nl80211_abort_scan(bss) == 0) { nl80211_abort_scan(drv->first_bss) == 0)
bss->scan_link = NULL;
return; return;
}
wpa_printf(MSG_DEBUG, "nl80211: Failed to abort scan"); wpa_printf(MSG_DEBUG, "nl80211: Failed to abort scan");
if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED) if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED)
nl80211_restore_ap_mode(bss); nl80211_restore_ap_mode(drv->first_bss);
wpa_printf(MSG_DEBUG, "nl80211: Try to get scan results"); wpa_printf(MSG_DEBUG, "nl80211: Try to get scan results");
wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL); wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
@ -361,7 +347,7 @@ int wpa_driver_nl80211_scan(struct i802_bss *bss,
int ret = -1, timeout; int ret = -1, timeout;
struct nl_msg *msg = NULL; struct nl_msg *msg = NULL;
wpa_dbg(bss->ctx, MSG_DEBUG, "nl80211: scan request"); wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: scan request");
drv->scan_for_auth = 0; drv->scan_for_auth = 0;
if (TEST_FAIL()) if (TEST_FAIL())
@ -416,40 +402,6 @@ int wpa_driver_nl80211_scan(struct i802_bss *bss,
wpa_printf(MSG_DEBUG, "nl80211: Scan trigger failed: ret=%d " wpa_printf(MSG_DEBUG, "nl80211: Scan trigger failed: ret=%d "
"(%s)", ret, strerror(-ret)); "(%s)", ret, strerror(-ret));
if (drv->hostapd && is_ap_interface(drv->nlmode)) { if (drv->hostapd && is_ap_interface(drv->nlmode)) {
#ifdef CONFIG_IEEE80211BE
/* For multi link BSS, retry scan if any other links
* are busy scanning. */
if (ret == -EBUSY &&
nl80211_link_valid(bss->valid_links,
params->link_id)) {
struct i802_bss *link_bss;
u8 link_id;
wpa_printf(MSG_DEBUG,
"nl80211: Scan trigger on multi link BSS failed (requested link=%d on interface %s)",
params->link_id, bss->ifname);
for (link_bss = drv->first_bss; link_bss;
link_bss = link_bss->next) {
if (link_bss->scan_link)
break;
}
if (!link_bss) {
wpa_printf(MSG_DEBUG,
"nl80211: BSS information already running scan not available");
goto fail;
}
link_id = nl80211_get_link_id_from_link(
link_bss, link_bss->scan_link);
wpa_printf(MSG_DEBUG,
"nl80211: Scan already running on interface %s link %d",
link_bss->ifname, link_id);
goto fail;
}
#endif /* CONFIG_IEEE80211BE */
/* /*
* mac80211 does not allow scan requests in AP mode, so * mac80211 does not allow scan requests in AP mode, so
* try to do this in station mode. * try to do this in station mode.
@ -483,20 +435,11 @@ int wpa_driver_nl80211_scan(struct i802_bss *bss,
} }
wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d " wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d "
"seconds", ret, timeout); "seconds", ret, timeout);
eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, bss->ctx); eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
eloop_register_timeout(timeout, 0, wpa_driver_nl80211_scan_timeout, eloop_register_timeout(timeout, 0, wpa_driver_nl80211_scan_timeout,
drv, bss->ctx); drv, drv->ctx);
drv->last_scan_cmd = NL80211_CMD_TRIGGER_SCAN; drv->last_scan_cmd = NL80211_CMD_TRIGGER_SCAN;
bss->scan_link = bss->flink;
if (is_ap_interface(drv->nlmode) &&
nl80211_link_valid(bss->valid_links, params->link_id)) {
wpa_dbg(bss->ctx, MSG_DEBUG,
"nl80211: Scan requested for link %d",
params->link_id);
bss->scan_link = nl80211_get_link(bss, params->link_id);
}
fail: fail:
nlmsg_free(msg); nlmsg_free(msg);
return ret; return ret;
@ -1351,9 +1294,9 @@ int wpa_driver_nl80211_vendor_scan(struct i802_bss *bss,
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"nl80211: Vendor scan requested (ret=%d) - scan timeout 30 seconds, scan cookie:0x%llx", "nl80211: Vendor scan requested (ret=%d) - scan timeout 30 seconds, scan cookie:0x%llx",
ret, (long long unsigned int) cookie); ret, (long long unsigned int) cookie);
eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, bss->ctx); eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
eloop_register_timeout(30, 0, wpa_driver_nl80211_scan_timeout, eloop_register_timeout(30, 0, wpa_driver_nl80211_scan_timeout,
drv, bss->ctx); drv, drv->ctx);
drv->last_scan_cmd = NL80211_CMD_VENDOR; drv->last_scan_cmd = NL80211_CMD_VENDOR;
fail: fail:

View file

@ -11,7 +11,7 @@
* Copyright 2008 Jouni Malinen <jouni.malinen@atheros.com> * Copyright 2008 Jouni Malinen <jouni.malinen@atheros.com>
* Copyright 2008 Colin McCabe <colin@cozybit.com> * Copyright 2008 Colin McCabe <colin@cozybit.com>
* Copyright 2015-2017 Intel Deutschland GmbH * Copyright 2015-2017 Intel Deutschland GmbH
* Copyright (C) 2018-2024 Intel Corporation * Copyright (C) 2018-2023 Intel Corporation
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -72,7 +72,7 @@
* For drivers supporting TDLS with external setup (WIPHY_FLAG_SUPPORTS_TDLS * For drivers supporting TDLS with external setup (WIPHY_FLAG_SUPPORTS_TDLS
* and WIPHY_FLAG_TDLS_EXTERNAL_SETUP), the station lifetime is as follows: * and WIPHY_FLAG_TDLS_EXTERNAL_SETUP), the station lifetime is as follows:
* - a setup station entry is added, not yet authorized, without any rate * - a setup station entry is added, not yet authorized, without any rate
* or capability information; this just exists to avoid race conditions * or capability information, this just exists to avoid race conditions
* - when the TDLS setup is done, a single NL80211_CMD_SET_STATION is valid * - when the TDLS setup is done, a single NL80211_CMD_SET_STATION is valid
* to add rate and capability information to the station and at the same * to add rate and capability information to the station and at the same
* time mark it authorized. * time mark it authorized.
@ -87,7 +87,7 @@
* DOC: Frame transmission/registration support * DOC: Frame transmission/registration support
* *
* Frame transmission and registration support exists to allow userspace * Frame transmission and registration support exists to allow userspace
* management entities such as wpa_supplicant to react to management frames * management entities such as wpa_supplicant react to management frames
* that are not being handled by the kernel. This includes, for example, * that are not being handled by the kernel. This includes, for example,
* certain classes of action frames that cannot be handled in the kernel * certain classes of action frames that cannot be handled in the kernel
* for various reasons. * for various reasons.
@ -113,7 +113,7 @@
* *
* Frame transmission allows userspace to send for example the required * Frame transmission allows userspace to send for example the required
* responses to action frames. It is subject to some sanity checking, * responses to action frames. It is subject to some sanity checking,
* but many frames can be transmitted. When a frame is transmitted, its * but many frames can be transmitted. When a frame was transmitted, its
* status is indicated to the sending socket. * status is indicated to the sending socket.
* *
* For more technical details, see the corresponding command descriptions * For more technical details, see the corresponding command descriptions
@ -123,7 +123,7 @@
/** /**
* DOC: Virtual interface / concurrency capabilities * DOC: Virtual interface / concurrency capabilities
* *
* Some devices are able to operate with virtual MACs; they can have * Some devices are able to operate with virtual MACs, they can have
* more than one virtual interface. The capability handling for this * more than one virtual interface. The capability handling for this
* is a bit complex though, as there may be a number of restrictions * is a bit complex though, as there may be a number of restrictions
* on the types of concurrency that are supported. * on the types of concurrency that are supported.
@ -135,7 +135,7 @@
* Once concurrency is desired, more attributes must be observed: * Once concurrency is desired, more attributes must be observed:
* To start with, since some interface types are purely managed in * To start with, since some interface types are purely managed in
* software, like the AP-VLAN type in mac80211 for example, there's * software, like the AP-VLAN type in mac80211 for example, there's
* an additional list of these; they can be added at any time and * an additional list of these, they can be added at any time and
* are only restricted by some semantic restrictions (e.g. AP-VLAN * are only restricted by some semantic restrictions (e.g. AP-VLAN
* cannot be added without a corresponding AP interface). This list * cannot be added without a corresponding AP interface). This list
* is exported in the %NL80211_ATTR_SOFTWARE_IFTYPES attribute. * is exported in the %NL80211_ATTR_SOFTWARE_IFTYPES attribute.
@ -164,7 +164,7 @@
* Packet coalesce feature helps to reduce number of received interrupts * Packet coalesce feature helps to reduce number of received interrupts
* to host by buffering these packets in firmware/hardware for some * to host by buffering these packets in firmware/hardware for some
* predefined time. Received interrupt will be generated when one of the * predefined time. Received interrupt will be generated when one of the
* following events occurs. * following events occur.
* a) Expiration of hardware timer whose expiration time is set to maximum * a) Expiration of hardware timer whose expiration time is set to maximum
* coalescing delay of matching coalesce rule. * coalescing delay of matching coalesce rule.
* b) Coalescing buffer in hardware reaches its limit. * b) Coalescing buffer in hardware reaches its limit.
@ -174,7 +174,7 @@
* rule. * rule.
* a) Maximum coalescing delay * a) Maximum coalescing delay
* b) List of packet patterns which needs to be matched * b) List of packet patterns which needs to be matched
* c) Condition for coalescence: pattern 'match' or 'no match' * c) Condition for coalescence. pattern 'match' or 'no match'
* Multiple such rules can be created. * Multiple such rules can be created.
*/ */
@ -213,7 +213,7 @@
/** /**
* DOC: FILS shared key authentication offload * DOC: FILS shared key authentication offload
* *
* FILS shared key authentication offload can be advertised by drivers by * FILS shared key authentication offload can be advertized by drivers by
* setting @NL80211_EXT_FEATURE_FILS_SK_OFFLOAD flag. The drivers that support * setting @NL80211_EXT_FEATURE_FILS_SK_OFFLOAD flag. The drivers that support
* FILS shared key authentication offload should be able to construct the * FILS shared key authentication offload should be able to construct the
* authentication and association frames for FILS shared key authentication and * authentication and association frames for FILS shared key authentication and
@ -239,7 +239,7 @@
* The PMKSA can be maintained in userspace persistently so that it can be used * The PMKSA can be maintained in userspace persistently so that it can be used
* later after reboots or wifi turn off/on also. * later after reboots or wifi turn off/on also.
* *
* %NL80211_ATTR_FILS_CACHE_ID is the cache identifier advertised by a FILS * %NL80211_ATTR_FILS_CACHE_ID is the cache identifier advertized by a FILS
* capable AP supporting PMK caching. It specifies the scope within which the * capable AP supporting PMK caching. It specifies the scope within which the
* PMKSAs are cached in an ESS. %NL80211_CMD_SET_PMKSA and * PMKSAs are cached in an ESS. %NL80211_CMD_SET_PMKSA and
* %NL80211_CMD_DEL_PMKSA are enhanced to allow support for PMKSA caching based * %NL80211_CMD_DEL_PMKSA are enhanced to allow support for PMKSA caching based
@ -290,12 +290,12 @@
* If the configuration needs to be applied for specific peer then the MAC * If the configuration needs to be applied for specific peer then the MAC
* address of the peer needs to be passed in %NL80211_ATTR_MAC, otherwise the * address of the peer needs to be passed in %NL80211_ATTR_MAC, otherwise the
* configuration will be applied for all the connected peers in the vif except * configuration will be applied for all the connected peers in the vif except
* any peers that have peer-specific configuration for the TID by default; if * any peers that have peer specific configuration for the TID by default; if
* the %NL80211_TID_CONFIG_ATTR_OVERRIDE flag is set, peer-specific values * the %NL80211_TID_CONFIG_ATTR_OVERRIDE flag is set, peer specific values
* will be overwritten. * will be overwritten.
* *
* All this configuration is valid only for STA's current connection, * All this configuration is valid only for STA's current connection
* i.e., the configuration will be reset to default when the STA connects back * i.e. the configuration will be reset to default when the STA connects back
* after disconnection/roaming, and this configuration will be cleared when * after disconnection/roaming, and this configuration will be cleared when
* the interface goes down. * the interface goes down.
*/ */
@ -413,8 +413,8 @@
* are like for %NL80211_CMD_SET_BEACON, and additionally parameters that * are like for %NL80211_CMD_SET_BEACON, and additionally parameters that
* do not change are used, these include %NL80211_ATTR_BEACON_INTERVAL, * do not change are used, these include %NL80211_ATTR_BEACON_INTERVAL,
* %NL80211_ATTR_DTIM_PERIOD, %NL80211_ATTR_SSID, * %NL80211_ATTR_DTIM_PERIOD, %NL80211_ATTR_SSID,
* %NL80211_ATTR_HIDDEN_SSID, %NL80211_ATTR_CIPHER_SUITES_PAIRWISE, * %NL80211_ATTR_HIDDEN_SSID, %NL80211_ATTR_CIPHERS_PAIRWISE,
* %NL80211_ATTR_CIPHER_SUITE_GROUP, %NL80211_ATTR_WPA_VERSIONS, * %NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS,
* %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY, * %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY,
* %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_INACTIVITY_TIMEOUT, * %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_INACTIVITY_TIMEOUT,
* %NL80211_ATTR_ACL_POLICY and %NL80211_ATTR_MAC_ADDRS. * %NL80211_ATTR_ACL_POLICY and %NL80211_ATTR_MAC_ADDRS.
@ -438,8 +438,7 @@
* %NL80211_ATTR_REASON_CODE can optionally be used to specify which type * %NL80211_ATTR_REASON_CODE can optionally be used to specify which type
* of disconnection indication should be sent to the station * of disconnection indication should be sent to the station
* (Deauthentication or Disassociation frame and reason code for that * (Deauthentication or Disassociation frame and reason code for that
* frame). %NL80211_ATTR_MLO_LINK_ID can be used optionally to remove * frame).
* stations connected and using at least that link as one of its links.
* *
* @NL80211_CMD_GET_MPATH: Get mesh path attributes for mesh path to * @NL80211_CMD_GET_MPATH: Get mesh path attributes for mesh path to
* destination %NL80211_ATTR_MAC on the interface identified by * destination %NL80211_ATTR_MAC on the interface identified by
@ -451,6 +450,11 @@
* %NL80211_ATTR_MAC via %NL80211_ATTR_MPATH_NEXT_HOP. * %NL80211_ATTR_MAC via %NL80211_ATTR_MPATH_NEXT_HOP.
* @NL80211_CMD_DEL_MPATH: Delete a mesh path to the destination given by * @NL80211_CMD_DEL_MPATH: Delete a mesh path to the destination given by
* %NL80211_ATTR_MAC. * %NL80211_ATTR_MAC.
* @NL80211_CMD_NEW_PATH: Add a mesh path with given attributes to the
* interface identified by %NL80211_ATTR_IFINDEX.
* @NL80211_CMD_DEL_PATH: Remove a mesh path identified by %NL80211_ATTR_MAC
* or, if no MAC address given, all mesh paths, on the interface identified
* by %NL80211_ATTR_IFINDEX.
* @NL80211_CMD_SET_BSS: Set BSS attributes for BSS identified by * @NL80211_CMD_SET_BSS: Set BSS attributes for BSS identified by
* %NL80211_ATTR_IFINDEX. * %NL80211_ATTR_IFINDEX.
* *
@ -517,7 +521,7 @@
* %NL80211_ATTR_SCHED_SCAN_PLANS. If %NL80211_ATTR_SCHED_SCAN_PLANS is * %NL80211_ATTR_SCHED_SCAN_PLANS. If %NL80211_ATTR_SCHED_SCAN_PLANS is
* not specified and only %NL80211_ATTR_SCHED_SCAN_INTERVAL is specified, * not specified and only %NL80211_ATTR_SCHED_SCAN_INTERVAL is specified,
* scheduled scan will run in an infinite loop with the specified interval. * scheduled scan will run in an infinite loop with the specified interval.
* These attributes are mutually exclusive, * These attributes are mutually exculsive,
* i.e. NL80211_ATTR_SCHED_SCAN_INTERVAL must not be passed if * i.e. NL80211_ATTR_SCHED_SCAN_INTERVAL must not be passed if
* NL80211_ATTR_SCHED_SCAN_PLANS is defined. * NL80211_ATTR_SCHED_SCAN_PLANS is defined.
* If for some reason scheduled scan is aborted by the driver, all scan * If for some reason scheduled scan is aborted by the driver, all scan
@ -548,7 +552,7 @@
* %NL80211_CMD_STOP_SCHED_SCAN command is received or when the interface * %NL80211_CMD_STOP_SCHED_SCAN command is received or when the interface
* is brought down while a scheduled scan was running. * is brought down while a scheduled scan was running.
* *
* @NL80211_CMD_GET_SURVEY: get survey results, e.g. channel occupation * @NL80211_CMD_GET_SURVEY: get survey resuls, e.g. channel occupation
* or noise level * or noise level
* @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to * @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to
* NL80211_CMD_GET_SURVEY and on the "scan" multicast group) * NL80211_CMD_GET_SURVEY and on the "scan" multicast group)
@ -559,13 +563,12 @@
* using %NL80211_ATTR_SSID, %NL80211_ATTR_FILS_CACHE_ID, * using %NL80211_ATTR_SSID, %NL80211_ATTR_FILS_CACHE_ID,
* %NL80211_ATTR_PMKID, and %NL80211_ATTR_PMK in case of FILS * %NL80211_ATTR_PMKID, and %NL80211_ATTR_PMK in case of FILS
* authentication where %NL80211_ATTR_FILS_CACHE_ID is the identifier * authentication where %NL80211_ATTR_FILS_CACHE_ID is the identifier
* advertised by a FILS capable AP identifying the scope of PMKSA in an * advertized by a FILS capable AP identifying the scope of PMKSA in an
* ESS. * ESS.
* @NL80211_CMD_DEL_PMKSA: Delete a PMKSA cache entry, using %NL80211_ATTR_MAC * @NL80211_CMD_DEL_PMKSA: Delete a PMKSA cache entry, using %NL80211_ATTR_MAC
* (for the BSSID) and %NL80211_ATTR_PMKID or using %NL80211_ATTR_SSID, * (for the BSSID) and %NL80211_ATTR_PMKID or using %NL80211_ATTR_SSID,
* %NL80211_ATTR_FILS_CACHE_ID, and %NL80211_ATTR_PMKID in case of FILS * %NL80211_ATTR_FILS_CACHE_ID, and %NL80211_ATTR_PMKID in case of FILS
* authentication. Additionally in case of SAE offload and OWE offloads * authentication.
* PMKSA entry can be deleted using %NL80211_ATTR_SSID.
* @NL80211_CMD_FLUSH_PMKSA: Flush all PMKSA cache entries. * @NL80211_CMD_FLUSH_PMKSA: Flush all PMKSA cache entries.
* *
* @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain * @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain
@ -604,7 +607,7 @@
* BSSID in case of station mode). %NL80211_ATTR_SSID is used to specify * BSSID in case of station mode). %NL80211_ATTR_SSID is used to specify
* the SSID (mainly for association, but is included in authentication * the SSID (mainly for association, but is included in authentication
* request, too, to help BSS selection. %NL80211_ATTR_WIPHY_FREQ + * request, too, to help BSS selection. %NL80211_ATTR_WIPHY_FREQ +
* %NL80211_ATTR_WIPHY_FREQ_OFFSET is used to specify the frequency of the * %NL80211_ATTR_WIPHY_FREQ_OFFSET is used to specify the frequence of the
* channel in MHz. %NL80211_ATTR_AUTH_TYPE is used to specify the * channel in MHz. %NL80211_ATTR_AUTH_TYPE is used to specify the
* authentication type. %NL80211_ATTR_IE is used to define IEs * authentication type. %NL80211_ATTR_IE is used to define IEs
* (VendorSpecificInfo, but also including RSN IE and FT IEs) to be added * (VendorSpecificInfo, but also including RSN IE and FT IEs) to be added
@ -813,7 +816,7 @@
* reached. * reached.
* @NL80211_CMD_SET_CHANNEL: Set the channel (using %NL80211_ATTR_WIPHY_FREQ * @NL80211_CMD_SET_CHANNEL: Set the channel (using %NL80211_ATTR_WIPHY_FREQ
* and the attributes determining channel width) the given interface * and the attributes determining channel width) the given interface
* (identified by %NL80211_ATTR_IFINDEX) shall operate on. * (identifed by %NL80211_ATTR_IFINDEX) shall operate on.
* In case multiple channels are supported by the device, the mechanism * In case multiple channels are supported by the device, the mechanism
* with which it switches channels is implementation-defined. * with which it switches channels is implementation-defined.
* When a monitor interface is given, it can only switch channel while * When a monitor interface is given, it can only switch channel while
@ -885,7 +888,7 @@
* inform userspace of the new replay counter. * inform userspace of the new replay counter.
* *
* @NL80211_CMD_PMKSA_CANDIDATE: This is used as an event to inform userspace * @NL80211_CMD_PMKSA_CANDIDATE: This is used as an event to inform userspace
* of PMKSA caching candidates. * of PMKSA caching dandidates.
* *
* @NL80211_CMD_TDLS_OPER: Perform a high-level TDLS command (e.g. link setup). * @NL80211_CMD_TDLS_OPER: Perform a high-level TDLS command (e.g. link setup).
* In addition, this can be used as an event to request userspace to take * In addition, this can be used as an event to request userspace to take
@ -921,7 +924,7 @@
* *
* @NL80211_CMD_PROBE_CLIENT: Probe an associated station on an AP interface * @NL80211_CMD_PROBE_CLIENT: Probe an associated station on an AP interface
* by sending a null data frame to it and reporting when the frame is * by sending a null data frame to it and reporting when the frame is
* acknowledged. This is used to allow timing out inactive clients. Uses * acknowleged. This is used to allow timing out inactive clients. Uses
* %NL80211_ATTR_IFINDEX and %NL80211_ATTR_MAC. The command returns a * %NL80211_ATTR_IFINDEX and %NL80211_ATTR_MAC. The command returns a
* direct reply with an %NL80211_ATTR_COOKIE that is later used to match * direct reply with an %NL80211_ATTR_COOKIE that is later used to match
* up the event with the request. The event includes the same data and * up the event with the request. The event includes the same data and
@ -1115,7 +1118,7 @@
* current configuration is not changed. If it is present but * current configuration is not changed. If it is present but
* set to zero, the configuration is changed to don't-care * set to zero, the configuration is changed to don't-care
* (i.e. the device can decide what to do). * (i.e. the device can decide what to do).
* @NL80211_CMD_NAN_MATCH: Notification sent when a match is reported. * @NL80211_CMD_NAN_FUNC_MATCH: Notification sent when a match is reported.
* This will contain a %NL80211_ATTR_NAN_MATCH nested attribute and * This will contain a %NL80211_ATTR_NAN_MATCH nested attribute and
* %NL80211_ATTR_COOKIE. * %NL80211_ATTR_COOKIE.
* *
@ -1132,15 +1135,11 @@
* @NL80211_CMD_DEL_PMK: For offloaded 4-Way handshake, delete the previously * @NL80211_CMD_DEL_PMK: For offloaded 4-Way handshake, delete the previously
* configured PMK for the authenticator address identified by * configured PMK for the authenticator address identified by
* %NL80211_ATTR_MAC. * %NL80211_ATTR_MAC.
* @NL80211_CMD_PORT_AUTHORIZED: An event that indicates port is authorized and * @NL80211_CMD_PORT_AUTHORIZED: An event that indicates an 802.1X FT roam was
* open for regular data traffic. For STA/P2P-client, this event is sent * completed successfully. Drivers that support 4 way handshake offload
* with AP MAC address and for AP/P2P-GO, the event carries the STA/P2P- * should send this event after indicating 802.1X FT assocation with
* client MAC address. * %NL80211_CMD_ROAM. If the 4 way handshake failed %NL80211_CMD_DISCONNECT
* Drivers that support 4 way handshake offload should send this event for * should be indicated instead.
* STA/P2P-client after successful 4-way HS or after 802.1X FT following
* NL80211_CMD_CONNECT or NL80211_CMD_ROAM. Drivers using AP/P2P-GO 4-way
* handshake offload should send this event on successful completion of
* 4-way handshake with the peer (STA/P2P-client).
* @NL80211_CMD_CONTROL_PORT_FRAME: Control Port (e.g. PAE) frame TX request * @NL80211_CMD_CONTROL_PORT_FRAME: Control Port (e.g. PAE) frame TX request
* and RX notification. This command is used both as a request to transmit * and RX notification. This command is used both as a request to transmit
* a control port frame and as a notification that a control port frame * a control port frame and as a notification that a control port frame
@ -1324,11 +1323,6 @@
* Multi-Link reconfiguration. %NL80211_ATTR_MLO_LINKS is used to provide * Multi-Link reconfiguration. %NL80211_ATTR_MLO_LINKS is used to provide
* information about the removed STA MLD setup links. * information about the removed STA MLD setup links.
* *
* @NL80211_CMD_SET_TID_TO_LINK_MAPPING: Set the TID to Link Mapping for a
* non-AP MLD station. The %NL80211_ATTR_MLO_TTLM_DLINK and
* %NL80211_ATTR_MLO_TTLM_ULINK attributes are used to specify the
* TID to Link mapping for downlink/uplink traffic.
*
* @NL80211_CMD_MAX: highest used command number * @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use * @__NL80211_CMD_AFTER_LAST: internal use
*/ */
@ -1584,8 +1578,6 @@ enum nl80211_commands {
NL80211_CMD_LINKS_REMOVED, NL80211_CMD_LINKS_REMOVED,
NL80211_CMD_SET_TID_TO_LINK_MAPPING,
/* add new commands above here */ /* add new commands above here */
/* used to define NL80211_CMD_MAX below */ /* used to define NL80211_CMD_MAX below */
@ -1843,7 +1835,7 @@ enum nl80211_commands {
* using %CMD_CONTROL_PORT_FRAME. If control port routing over NL80211 is * using %CMD_CONTROL_PORT_FRAME. If control port routing over NL80211 is
* to be used then userspace must also use the %NL80211_ATTR_SOCKET_OWNER * to be used then userspace must also use the %NL80211_ATTR_SOCKET_OWNER
* flag. When used with %NL80211_ATTR_CONTROL_PORT_NO_PREAUTH, pre-auth * flag. When used with %NL80211_ATTR_CONTROL_PORT_NO_PREAUTH, pre-auth
* frames are not forwarded over the control port. * frames are not forwared over the control port.
* *
* @NL80211_ATTR_TESTDATA: Testmode data blob, passed through to the driver. * @NL80211_ATTR_TESTDATA: Testmode data blob, passed through to the driver.
* We recommend using nested, driver-specific attributes within this. * We recommend using nested, driver-specific attributes within this.
@ -1857,6 +1849,12 @@ enum nl80211_commands {
* that protected APs should be used. This is also used with NEW_BEACON to * that protected APs should be used. This is also used with NEW_BEACON to
* indicate that the BSS is to use protection. * indicate that the BSS is to use protection.
* *
* @NL80211_ATTR_CIPHERS_PAIRWISE: Used with CONNECT, ASSOCIATE, and NEW_BEACON
* to indicate which unicast key ciphers will be used with the connection
* (an array of u32).
* @NL80211_ATTR_CIPHER_GROUP: Used with CONNECT, ASSOCIATE, and NEW_BEACON to
* indicate which group key cipher will be used with the connection (a
* u32).
* @NL80211_ATTR_WPA_VERSIONS: Used with CONNECT, ASSOCIATE, and NEW_BEACON to * @NL80211_ATTR_WPA_VERSIONS: Used with CONNECT, ASSOCIATE, and NEW_BEACON to
* indicate which WPA version(s) the AP we want to associate with is using * indicate which WPA version(s) the AP we want to associate with is using
* (a u32 with flags from &enum nl80211_wpa_versions). * (a u32 with flags from &enum nl80211_wpa_versions).
@ -1887,7 +1885,6 @@ enum nl80211_commands {
* with %NL80211_KEY_* sub-attributes * with %NL80211_KEY_* sub-attributes
* *
* @NL80211_ATTR_PID: Process ID of a network namespace. * @NL80211_ATTR_PID: Process ID of a network namespace.
* @NL80211_ATTR_NETNS_FD: File descriptor of a network namespace.
* *
* @NL80211_ATTR_GENERATION: Used to indicate consistent snapshots for * @NL80211_ATTR_GENERATION: Used to indicate consistent snapshots for
* dumps. This number increases whenever the object list being * dumps. This number increases whenever the object list being
@ -1942,7 +1939,6 @@ enum nl80211_commands {
* *
* @NL80211_ATTR_ACK: Flag attribute indicating that the frame was * @NL80211_ATTR_ACK: Flag attribute indicating that the frame was
* acknowledged by the recipient. * acknowledged by the recipient.
* @NL80211_ATTR_ACK_SIGNAL: Station's ack signal strength (s32)
* *
* @NL80211_ATTR_PS_STATE: powersave state, using &enum nl80211_ps_state values. * @NL80211_ATTR_PS_STATE: powersave state, using &enum nl80211_ps_state values.
* *
@ -1976,10 +1972,10 @@ enum nl80211_commands {
* bit. Depending on which antennas are selected in the bitmap, 802.11n * bit. Depending on which antennas are selected in the bitmap, 802.11n
* drivers can derive which chainmasks to use (if all antennas belonging to * drivers can derive which chainmasks to use (if all antennas belonging to
* a particular chain are disabled this chain should be disabled) and if * a particular chain are disabled this chain should be disabled) and if
* a chain has diversity antennas whether diversity should be used or not. * a chain has diversity antennas wether diversity should be used or not.
* HT capabilities (STBC, TX Beamforming, Antenna selection) can be * HT capabilities (STBC, TX Beamforming, Antenna selection) can be
* derived from the available chains after applying the antenna mask. * derived from the available chains after applying the antenna mask.
* Non-802.11n drivers can derive whether to use diversity or not. * Non-802.11n drivers can derive wether to use diversity or not.
* Drivers may reject configurations or RX/TX mask combinations they cannot * Drivers may reject configurations or RX/TX mask combinations they cannot
* support by returning -EINVAL. * support by returning -EINVAL.
* *
@ -2052,10 +2048,6 @@ enum nl80211_commands {
* @NL80211_ATTR_INTERFACE_COMBINATIONS: Nested attribute listing the supported * @NL80211_ATTR_INTERFACE_COMBINATIONS: Nested attribute listing the supported
* interface combinations. In each nested item, it contains attributes * interface combinations. In each nested item, it contains attributes
* defined in &enum nl80211_if_combination_attrs. * defined in &enum nl80211_if_combination_attrs.
* If the wiphy uses multiple radios (@NL80211_ATTR_WIPHY_RADIOS is set),
* this attribute contains the interface combinations of the first radio.
* See @NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS for the global wiphy
* combinations for the sum of all radios.
* @NL80211_ATTR_SOFTWARE_IFTYPES: Nested attribute (just like * @NL80211_ATTR_SOFTWARE_IFTYPES: Nested attribute (just like
* %NL80211_ATTR_SUPPORTED_IFTYPES) containing the interface types that * %NL80211_ATTR_SUPPORTED_IFTYPES) containing the interface types that
* are managed in software: interfaces of these types aren't subject to * are managed in software: interfaces of these types aren't subject to
@ -2144,9 +2136,6 @@ enum nl80211_commands {
* @NL80211_ATTR_DISABLE_HE: Force HE capable interfaces to disable * @NL80211_ATTR_DISABLE_HE: Force HE capable interfaces to disable
* this feature during association. This is a flag attribute. * this feature during association. This is a flag attribute.
* Currently only supported in mac80211 drivers. * Currently only supported in mac80211 drivers.
* @NL80211_ATTR_DISABLE_EHT: Force EHT capable interfaces to disable
* this feature during association. This is a flag attribute.
* Currently only supported in mac80211 drivers.
* @NL80211_ATTR_HT_CAPABILITY_MASK: Specify which bits of the * @NL80211_ATTR_HT_CAPABILITY_MASK: Specify which bits of the
* ATTR_HT_CAPABILITY to which attention should be paid. * ATTR_HT_CAPABILITY to which attention should be paid.
* Currently, only mac80211 NICs support this feature. * Currently, only mac80211 NICs support this feature.
@ -2156,12 +2145,6 @@ enum nl80211_commands {
* All values are treated as suggestions and may be ignored * All values are treated as suggestions and may be ignored
* by the driver as required. The actual values may be seen in * by the driver as required. The actual values may be seen in
* the station debugfs ht_caps file. * the station debugfs ht_caps file.
* @NL80211_ATTR_VHT_CAPABILITY_MASK: Specify which bits of the
* ATTR_VHT_CAPABILITY to which attention should be paid.
* Currently, only mac80211 NICs support this feature.
* All values are treated as suggestions and may be ignored
* by the driver as required. The actual values may be seen in
* the station debugfs vht_caps file.
* *
* @NL80211_ATTR_DFS_REGION: region for regulatory rules which this country * @NL80211_ATTR_DFS_REGION: region for regulatory rules which this country
* abides to when initiating radiation on DFS channels. A country maps * abides to when initiating radiation on DFS channels. A country maps
@ -2420,7 +2403,7 @@ enum nl80211_commands {
* scheduled scan is started. Or the delay before a WoWLAN * scheduled scan is started. Or the delay before a WoWLAN
* net-detect scan is started, counting from the moment the * net-detect scan is started, counting from the moment the
* system is suspended. This value is a u32, in seconds. * system is suspended. This value is a u32, in seconds.
*
* @NL80211_ATTR_REG_INDOOR: flag attribute, if set indicates that the device * @NL80211_ATTR_REG_INDOOR: flag attribute, if set indicates that the device
* is operating in an indoor environment. * is operating in an indoor environment.
* *
@ -2562,7 +2545,7 @@ enum nl80211_commands {
* from successful FILS authentication and is used with * from successful FILS authentication and is used with
* %NL80211_CMD_CONNECT. * %NL80211_CMD_CONNECT.
* *
* @NL80211_ATTR_FILS_CACHE_ID: A 2-octet identifier advertised by a FILS AP * @NL80211_ATTR_FILS_CACHE_ID: A 2-octet identifier advertized by a FILS AP
* identifying the scope of PMKSAs. This is used with * identifying the scope of PMKSAs. This is used with
* @NL80211_CMD_SET_PMKSA and @NL80211_CMD_DEL_PMKSA. * @NL80211_CMD_SET_PMKSA and @NL80211_CMD_DEL_PMKSA.
* *
@ -2843,31 +2826,6 @@ enum nl80211_commands {
* @NL80211_ATTR_MLO_LINK_DISABLED: Flag attribute indicating that the link is * @NL80211_ATTR_MLO_LINK_DISABLED: Flag attribute indicating that the link is
* disabled. * disabled.
* *
* @NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA: Include BSS usage data, i.e.
* include BSSes that can only be used in restricted scenarios and/or
* cannot be used at all.
*
* @NL80211_ATTR_MLO_TTLM_DLINK: Binary attribute specifying the downlink TID to
* link mapping. The length is 8 * sizeof(u16). For each TID the link
* mapping is as defined in section 9.4.2.314 (TID-To-Link Mapping element)
* in Draft P802.11be_D4.0.
* @NL80211_ATTR_MLO_TTLM_ULINK: Binary attribute specifying the uplink TID to
* link mapping. The length is 8 * sizeof(u16). For each TID the link
* mapping is as defined in section 9.4.2.314 (TID-To-Link Mapping element)
* in Draft P802.11be_D4.0.
*
* @NL80211_ATTR_ASSOC_SPP_AMSDU: flag attribute used with
* %NL80211_CMD_ASSOCIATE indicating the SPP A-MSDUs
* are used on this connection
*
* @NL80211_ATTR_WIPHY_RADIOS: Nested attribute describing physical radios
* belonging to this wiphy. See &enum nl80211_wiphy_radio_attrs.
*
* @NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS: Nested attribute listing the
* supported interface combinations for all radios combined. In each
* nested item, it contains attributes defined in
* &enum nl80211_if_combination_attrs.
*
* @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined * @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use * @__NL80211_ATTR_AFTER_LAST: internal use
@ -3406,16 +3364,6 @@ enum nl80211_attrs {
NL80211_ATTR_MLO_LINK_DISABLED, NL80211_ATTR_MLO_LINK_DISABLED,
NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA,
NL80211_ATTR_MLO_TTLM_DLINK,
NL80211_ATTR_MLO_TTLM_ULINK,
NL80211_ATTR_ASSOC_SPP_AMSDU,
NL80211_ATTR_WIPHY_RADIOS,
NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS,
/* add attributes here, update the policy in nl80211.c */ /* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST, __NL80211_ATTR_AFTER_LAST,
@ -3556,7 +3504,6 @@ enum nl80211_iftype {
* @NL80211_STA_FLAG_ASSOCIATED: station is associated; used with drivers * @NL80211_STA_FLAG_ASSOCIATED: station is associated; used with drivers
* that support %NL80211_FEATURE_FULL_AP_CLIENT_STATE to transition a * that support %NL80211_FEATURE_FULL_AP_CLIENT_STATE to transition a
* previously added station into associated state * previously added station into associated state
* @NL80211_STA_FLAG_SPP_AMSDU: station supports SPP A-MSDUs
* @NL80211_STA_FLAG_MAX: highest station flag number currently defined * @NL80211_STA_FLAG_MAX: highest station flag number currently defined
* @__NL80211_STA_FLAG_AFTER_LAST: internal use * @__NL80211_STA_FLAG_AFTER_LAST: internal use
*/ */
@ -3569,7 +3516,6 @@ enum nl80211_sta_flags {
NL80211_STA_FLAG_AUTHENTICATED, NL80211_STA_FLAG_AUTHENTICATED,
NL80211_STA_FLAG_TDLS_PEER, NL80211_STA_FLAG_TDLS_PEER,
NL80211_STA_FLAG_ASSOCIATED, NL80211_STA_FLAG_ASSOCIATED,
NL80211_STA_FLAG_SPP_AMSDU,
/* keep last */ /* keep last */
__NL80211_STA_FLAG_AFTER_LAST, __NL80211_STA_FLAG_AFTER_LAST,
@ -3580,7 +3526,7 @@ enum nl80211_sta_flags {
* enum nl80211_sta_p2p_ps_status - station support of P2P PS * enum nl80211_sta_p2p_ps_status - station support of P2P PS
* *
* @NL80211_P2P_PS_UNSUPPORTED: station doesn't support P2P PS mechanism * @NL80211_P2P_PS_UNSUPPORTED: station doesn't support P2P PS mechanism
* @NL80211_P2P_PS_SUPPORTED: station supports P2P PS mechanism * @@NL80211_P2P_PS_SUPPORTED: station supports P2P PS mechanism
* @NUM_NL80211_P2P_PS_STATUS: number of values * @NUM_NL80211_P2P_PS_STATUS: number of values
*/ */
enum nl80211_sta_p2p_ps_status { enum nl80211_sta_p2p_ps_status {
@ -3618,9 +3564,9 @@ enum nl80211_he_gi {
/** /**
* enum nl80211_he_ltf - HE long training field * enum nl80211_he_ltf - HE long training field
* @NL80211_RATE_INFO_HE_1XLTF: 3.2 usec * @NL80211_RATE_INFO_HE_1xLTF: 3.2 usec
* @NL80211_RATE_INFO_HE_2XLTF: 6.4 usec * @NL80211_RATE_INFO_HE_2xLTF: 6.4 usec
* @NL80211_RATE_INFO_HE_4XLTF: 12.8 usec * @NL80211_RATE_INFO_HE_4xLTF: 12.8 usec
*/ */
enum nl80211_he_ltf { enum nl80211_he_ltf {
NL80211_RATE_INFO_HE_1XLTF, NL80211_RATE_INFO_HE_1XLTF,
@ -3735,7 +3681,7 @@ enum nl80211_eht_ru_alloc {
* @NL80211_RATE_INFO_HE_GI: HE guard interval identifier * @NL80211_RATE_INFO_HE_GI: HE guard interval identifier
* (u8, see &enum nl80211_he_gi) * (u8, see &enum nl80211_he_gi)
* @NL80211_RATE_INFO_HE_DCM: HE DCM value (u8, 0/1) * @NL80211_RATE_INFO_HE_DCM: HE DCM value (u8, 0/1)
* @NL80211_RATE_INFO_HE_RU_ALLOC: HE RU allocation, if not present then * @NL80211_RATE_INFO_RU_ALLOC: HE RU allocation, if not present then
* non-OFDMA was used (u8, see &enum nl80211_he_ru_alloc) * non-OFDMA was used (u8, see &enum nl80211_he_ru_alloc)
* @NL80211_RATE_INFO_320_MHZ_WIDTH: 320 MHz bitrate * @NL80211_RATE_INFO_320_MHZ_WIDTH: 320 MHz bitrate
* @NL80211_RATE_INFO_EHT_MCS: EHT MCS index (u8, 0-15) * @NL80211_RATE_INFO_EHT_MCS: EHT MCS index (u8, 0-15)
@ -3867,8 +3813,8 @@ enum nl80211_sta_bss_param {
* Contains a nested array of signal strength attributes (u8, dBm) * Contains a nested array of signal strength attributes (u8, dBm)
* @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average * @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average
* Same format as NL80211_STA_INFO_CHAIN_SIGNAL. * Same format as NL80211_STA_INFO_CHAIN_SIGNAL.
* @NL80211_STA_INFO_EXPECTED_THROUGHPUT: expected throughput considering also * @NL80211_STA_EXPECTED_THROUGHPUT: expected throughput considering also the
* the 802.11 header (u32, kbps) * 802.11 header (u32, kbps)
* @NL80211_STA_INFO_RX_DROP_MISC: RX packets dropped for unspecified reasons * @NL80211_STA_INFO_RX_DROP_MISC: RX packets dropped for unspecified reasons
* (u64) * (u64)
* @NL80211_STA_INFO_BEACON_RX: number of beacons received from this peer (u64) * @NL80211_STA_INFO_BEACON_RX: number of beacons received from this peer (u64)
@ -4194,7 +4140,7 @@ enum nl80211_band_attr {
* @NL80211_WMMR_CW_MAX: Maximum contention window slot. * @NL80211_WMMR_CW_MAX: Maximum contention window slot.
* @NL80211_WMMR_AIFSN: Arbitration Inter Frame Space. * @NL80211_WMMR_AIFSN: Arbitration Inter Frame Space.
* @NL80211_WMMR_TXOP: Maximum allowed tx operation time. * @NL80211_WMMR_TXOP: Maximum allowed tx operation time.
* @NL80211_WMMR_MAX: highest possible wmm rule. * @nl80211_WMMR_MAX: highest possible wmm rule.
* @__NL80211_WMMR_LAST: Internal use. * @__NL80211_WMMR_LAST: Internal use.
*/ */
enum nl80211_wmm_rule { enum nl80211_wmm_rule {
@ -4218,14 +4164,13 @@ enum nl80211_wmm_rule {
* @NL80211_FREQUENCY_ATTR_NO_IR: no mechanisms that initiate radiation * @NL80211_FREQUENCY_ATTR_NO_IR: no mechanisms that initiate radiation
* are permitted on this channel, this includes sending probe * are permitted on this channel, this includes sending probe
* requests, or modes of operation that require beaconing. * requests, or modes of operation that require beaconing.
* @__NL80211_FREQUENCY_ATTR_NO_IBSS: obsolete, same as _NO_IR
* @NL80211_FREQUENCY_ATTR_RADAR: Radar detection is mandatory * @NL80211_FREQUENCY_ATTR_RADAR: Radar detection is mandatory
* on this channel in current regulatory domain. * on this channel in current regulatory domain.
* @NL80211_FREQUENCY_ATTR_MAX_TX_POWER: Maximum transmission power in mBm * @NL80211_FREQUENCY_ATTR_MAX_TX_POWER: Maximum transmission power in mBm
* (100 * dBm). * (100 * dBm).
* @NL80211_FREQUENCY_ATTR_DFS_STATE: current state for DFS * @NL80211_FREQUENCY_ATTR_DFS_STATE: current state for DFS
* (enum nl80211_dfs_state) * (enum nl80211_dfs_state)
* @NL80211_FREQUENCY_ATTR_DFS_TIME: time in milliseconds for how long * @NL80211_FREQUENCY_ATTR_DFS_TIME: time in miliseconds for how long
* this channel is in this DFS state. * this channel is in this DFS state.
* @NL80211_FREQUENCY_ATTR_NO_HT40_MINUS: HT40- isn't possible with this * @NL80211_FREQUENCY_ATTR_NO_HT40_MINUS: HT40- isn't possible with this
* channel as the control channel * channel as the control channel
@ -4281,19 +4226,6 @@ enum nl80211_wmm_rule {
* in current regulatory domain. * in current regulatory domain.
* @NL80211_FREQUENCY_ATTR_PSD: Power spectral density (in dBm) that * @NL80211_FREQUENCY_ATTR_PSD: Power spectral density (in dBm) that
* is allowed on this channel in current regulatory domain. * is allowed on this channel in current regulatory domain.
* @NL80211_FREQUENCY_ATTR_DFS_CONCURRENT: Operation on this channel is
* allowed for peer-to-peer or adhoc communication under the control
* of a DFS master which operates on the same channel (FCC-594280 D01
* Section B.3). Should be used together with %NL80211_RRF_DFS only.
* @NL80211_FREQUENCY_ATTR_NO_6GHZ_VLP_CLIENT: Client connection to VLP AP
* not allowed using this channel
* @NL80211_FREQUENCY_ATTR_NO_6GHZ_AFC_CLIENT: Client connection to AFC AP
* not allowed using this channel
* @NL80211_FREQUENCY_ATTR_CAN_MONITOR: This channel can be used in monitor
* mode despite other (regulatory) restrictions, even if the channel is
* otherwise completely disabled.
* @NL80211_FREQUENCY_ATTR_ALLOW_6GHZ_VLP_AP: This channel can be used for a
* very low power (VLP) AP, despite being NO_IR.
* @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number
* currently defined * currently defined
* @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use
@ -4333,11 +4265,6 @@ enum nl80211_frequency_attr {
NL80211_FREQUENCY_ATTR_NO_320MHZ, NL80211_FREQUENCY_ATTR_NO_320MHZ,
NL80211_FREQUENCY_ATTR_NO_EHT, NL80211_FREQUENCY_ATTR_NO_EHT,
NL80211_FREQUENCY_ATTR_PSD, NL80211_FREQUENCY_ATTR_PSD,
NL80211_FREQUENCY_ATTR_DFS_CONCURRENT,
NL80211_FREQUENCY_ATTR_NO_6GHZ_VLP_CLIENT,
NL80211_FREQUENCY_ATTR_NO_6GHZ_AFC_CLIENT,
NL80211_FREQUENCY_ATTR_CAN_MONITOR,
NL80211_FREQUENCY_ATTR_ALLOW_6GHZ_VLP_AP,
/* keep last */ /* keep last */
__NL80211_FREQUENCY_ATTR_AFTER_LAST, __NL80211_FREQUENCY_ATTR_AFTER_LAST,
@ -4350,10 +4277,6 @@ enum nl80211_frequency_attr {
#define NL80211_FREQUENCY_ATTR_NO_IR NL80211_FREQUENCY_ATTR_NO_IR #define NL80211_FREQUENCY_ATTR_NO_IR NL80211_FREQUENCY_ATTR_NO_IR
#define NL80211_FREQUENCY_ATTR_GO_CONCURRENT \ #define NL80211_FREQUENCY_ATTR_GO_CONCURRENT \
NL80211_FREQUENCY_ATTR_IR_CONCURRENT NL80211_FREQUENCY_ATTR_IR_CONCURRENT
#define NL80211_FREQUENCY_ATTR_NO_UHB_VLP_CLIENT \
NL80211_FREQUENCY_ATTR_NO_6GHZ_VLP_CLIENT
#define NL80211_FREQUENCY_ATTR_NO_UHB_AFC_CLIENT \
NL80211_FREQUENCY_ATTR_NO_6GHZ_AFC_CLIENT
/** /**
* enum nl80211_bitrate_attr - bitrate attributes * enum nl80211_bitrate_attr - bitrate attributes
@ -4376,7 +4299,7 @@ enum nl80211_bitrate_attr {
}; };
/** /**
* enum nl80211_reg_initiator - Indicates the initiator of a reg domain request * enum nl80211_initiator - Indicates the initiator of a reg domain request
* @NL80211_REGDOM_SET_BY_CORE: Core queried CRDA for a dynamic world * @NL80211_REGDOM_SET_BY_CORE: Core queried CRDA for a dynamic world
* regulatory domain. * regulatory domain.
* @NL80211_REGDOM_SET_BY_USER: User asked the wireless core to set the * @NL80211_REGDOM_SET_BY_USER: User asked the wireless core to set the
@ -4491,7 +4414,14 @@ enum nl80211_reg_rule_attr {
* value as specified by &struct nl80211_bss_select_rssi_adjust. * value as specified by &struct nl80211_bss_select_rssi_adjust.
* @NL80211_SCHED_SCAN_MATCH_ATTR_BSSID: BSSID to be used for matching * @NL80211_SCHED_SCAN_MATCH_ATTR_BSSID: BSSID to be used for matching
* (this cannot be used together with SSID). * (this cannot be used together with SSID).
* @NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI: Obsolete * @NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI: Nested attribute that carries the
* band specific minimum rssi thresholds for the bands defined in
* enum nl80211_band. The minimum rssi threshold value(s32) specific to a
* band shall be encapsulated in attribute with type value equals to one
* of the NL80211_BAND_* defined in enum nl80211_band. For example, the
* minimum rssi threshold value for 2.4GHZ band shall be encapsulated
* within an attribute of type NL80211_BAND_2GHZ. And one or more of such
* attributes will be nested within this attribute.
* @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter * @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter
* attribute number currently defined * attribute number currently defined
* @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use * @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use
@ -4504,7 +4434,7 @@ enum nl80211_sched_scan_match_attr {
NL80211_SCHED_SCAN_MATCH_ATTR_RELATIVE_RSSI, NL80211_SCHED_SCAN_MATCH_ATTR_RELATIVE_RSSI,
NL80211_SCHED_SCAN_MATCH_ATTR_RSSI_ADJUST, NL80211_SCHED_SCAN_MATCH_ATTR_RSSI_ADJUST,
NL80211_SCHED_SCAN_MATCH_ATTR_BSSID, NL80211_SCHED_SCAN_MATCH_ATTR_BSSID,
NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI, /* obsolete */ NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI,
/* keep last */ /* keep last */
__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST, __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST,
@ -4528,7 +4458,6 @@ enum nl80211_sched_scan_match_attr {
* @NL80211_RRF_NO_IR: no mechanisms that initiate radiation are allowed, * @NL80211_RRF_NO_IR: no mechanisms that initiate radiation are allowed,
* this includes probe requests or modes of operation that require * this includes probe requests or modes of operation that require
* beaconing. * beaconing.
* @__NL80211_RRF_NO_IBSS: obsolete, same as NO_IR
* @NL80211_RRF_AUTO_BW: maximum available bandwidth should be calculated * @NL80211_RRF_AUTO_BW: maximum available bandwidth should be calculated
* base on contiguous rules and wider channels will be allowed to cross * base on contiguous rules and wider channels will be allowed to cross
* multiple contiguous/overlapping frequency ranges. * multiple contiguous/overlapping frequency ranges.
@ -4541,14 +4470,6 @@ enum nl80211_sched_scan_match_attr {
* @NL80211_RRF_NO_320MHZ: 320MHz operation not allowed * @NL80211_RRF_NO_320MHZ: 320MHz operation not allowed
* @NL80211_RRF_NO_EHT: EHT operation not allowed * @NL80211_RRF_NO_EHT: EHT operation not allowed
* @NL80211_RRF_PSD: Ruleset has power spectral density value * @NL80211_RRF_PSD: Ruleset has power spectral density value
* @NL80211_RRF_DFS_CONCURRENT: Operation on this channel is allowed for
* peer-to-peer or adhoc communication under the control of a DFS master
* which operates on the same channel (FCC-594280 D01 Section B.3).
* Should be used together with %NL80211_RRF_DFS only.
* @NL80211_RRF_NO_6GHZ_VLP_CLIENT: Client connection to VLP AP not allowed
* @NL80211_RRF_NO_6GHZ_AFC_CLIENT: Client connection to AFC AP not allowed
* @NL80211_RRF_ALLOW_6GHZ_VLP_AP: Very low power (VLP) AP can be permitted
* despite NO_IR configuration.
*/ */
enum nl80211_reg_rule_flags { enum nl80211_reg_rule_flags {
NL80211_RRF_NO_OFDM = 1<<0, NL80211_RRF_NO_OFDM = 1<<0,
@ -4570,10 +4491,6 @@ enum nl80211_reg_rule_flags {
NL80211_RRF_NO_320MHZ = 1<<18, NL80211_RRF_NO_320MHZ = 1<<18,
NL80211_RRF_NO_EHT = 1<<19, NL80211_RRF_NO_EHT = 1<<19,
NL80211_RRF_PSD = 1<<20, NL80211_RRF_PSD = 1<<20,
NL80211_RRF_DFS_CONCURRENT = 1<<21,
NL80211_RRF_NO_6GHZ_VLP_CLIENT = 1<<22,
NL80211_RRF_NO_6GHZ_AFC_CLIENT = 1<<23,
NL80211_RRF_ALLOW_6GHZ_VLP_AP = 1<<24,
}; };
#define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR #define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR
@ -4582,8 +4499,6 @@ enum nl80211_reg_rule_flags {
#define NL80211_RRF_NO_HT40 (NL80211_RRF_NO_HT40MINUS |\ #define NL80211_RRF_NO_HT40 (NL80211_RRF_NO_HT40MINUS |\
NL80211_RRF_NO_HT40PLUS) NL80211_RRF_NO_HT40PLUS)
#define NL80211_RRF_GO_CONCURRENT NL80211_RRF_IR_CONCURRENT #define NL80211_RRF_GO_CONCURRENT NL80211_RRF_IR_CONCURRENT
#define NL80211_RRF_NO_UHB_VLP_CLIENT NL80211_RRF_NO_6GHZ_VLP_CLIENT
#define NL80211_RRF_NO_UHB_AFC_CLIENT NL80211_RRF_NO_6GHZ_AFC_CLIENT
/* For backport compatibility with older userspace */ /* For backport compatibility with older userspace */
#define NL80211_RRF_NO_IR_ALL (NL80211_RRF_NO_IR | __NL80211_RRF_NO_IBSS) #define NL80211_RRF_NO_IR_ALL (NL80211_RRF_NO_IR | __NL80211_RRF_NO_IBSS)
@ -4730,8 +4645,8 @@ enum nl80211_mntr_flags {
* alternate between Active and Doze states, but may not wake up * alternate between Active and Doze states, but may not wake up
* for neighbor's beacons. * for neighbor's beacons.
* *
* @__NL80211_MESH_POWER_AFTER_LAST: internal use * @__NL80211_MESH_POWER_AFTER_LAST - internal use
* @NL80211_MESH_POWER_MAX: highest possible power save level * @NL80211_MESH_POWER_MAX - highest possible power save level
*/ */
enum nl80211_mesh_power_mode { enum nl80211_mesh_power_mode {
@ -5112,36 +5027,6 @@ enum nl80211_bss_scan_width {
NL80211_BSS_CHAN_WIDTH_2, NL80211_BSS_CHAN_WIDTH_2,
}; };
/**
* enum nl80211_bss_use_for - bitmap indicating possible BSS use
* @NL80211_BSS_USE_FOR_NORMAL: Use this BSS for normal "connection",
* including IBSS/MBSS depending on the type.
* @NL80211_BSS_USE_FOR_MLD_LINK: This BSS can be used as a link in an
* MLO connection. Note that for an MLO connection, all links including
* the assoc link must have this flag set, and the assoc link must
* additionally have %NL80211_BSS_USE_FOR_NORMAL set.
*/
enum nl80211_bss_use_for {
NL80211_BSS_USE_FOR_NORMAL = 1 << 0,
NL80211_BSS_USE_FOR_MLD_LINK = 1 << 1,
};
/**
* enum nl80211_bss_cannot_use_reasons - reason(s) connection to a
* BSS isn't possible
* @NL80211_BSS_CANNOT_USE_NSTR_NONPRIMARY: NSTR nonprimary links aren't
* supported by the device, and this BSS entry represents one.
* @NL80211_BSS_CANNOT_USE_6GHZ_PWR_MISMATCH: STA is not supporting
* the AP power type (SP, VLP, AP) that the AP uses.
*/
enum nl80211_bss_cannot_use_reasons {
NL80211_BSS_CANNOT_USE_NSTR_NONPRIMARY = 1 << 0,
NL80211_BSS_CANNOT_USE_6GHZ_PWR_MISMATCH = 1 << 1,
};
#define NL80211_BSS_CANNOT_USE_UHB_PWR_MISMATCH \
NL80211_BSS_CANNOT_USE_6GHZ_PWR_MISMATCH
/** /**
* enum nl80211_bss - netlink attributes for a BSS * enum nl80211_bss - netlink attributes for a BSS
* *
@ -5194,14 +5079,6 @@ enum nl80211_bss_cannot_use_reasons {
* @NL80211_BSS_FREQUENCY_OFFSET: frequency offset in KHz * @NL80211_BSS_FREQUENCY_OFFSET: frequency offset in KHz
* @NL80211_BSS_MLO_LINK_ID: MLO link ID of the BSS (u8). * @NL80211_BSS_MLO_LINK_ID: MLO link ID of the BSS (u8).
* @NL80211_BSS_MLD_ADDR: MLD address of this BSS if connected to it. * @NL80211_BSS_MLD_ADDR: MLD address of this BSS if connected to it.
* @NL80211_BSS_USE_FOR: u32 bitmap attribute indicating what the BSS can be
* used for, see &enum nl80211_bss_use_for.
* @NL80211_BSS_CANNOT_USE_REASONS: Indicates the reason that this BSS cannot
* be used for all or some of the possible uses by the device reporting it,
* even though its presence was detected.
* This is a u64 attribute containing a bitmap of values from
* &enum nl80211_cannot_use_reasons, note that the attribute may be missing
* if no reasons are specified.
* @__NL80211_BSS_AFTER_LAST: internal * @__NL80211_BSS_AFTER_LAST: internal
* @NL80211_BSS_MAX: highest BSS attribute * @NL80211_BSS_MAX: highest BSS attribute
*/ */
@ -5229,8 +5106,6 @@ enum nl80211_bss {
NL80211_BSS_FREQUENCY_OFFSET, NL80211_BSS_FREQUENCY_OFFSET,
NL80211_BSS_MLO_LINK_ID, NL80211_BSS_MLO_LINK_ID,
NL80211_BSS_MLD_ADDR, NL80211_BSS_MLD_ADDR,
NL80211_BSS_USE_FOR,
NL80211_BSS_CANNOT_USE_REASONS,
/* keep last */ /* keep last */
__NL80211_BSS_AFTER_LAST, __NL80211_BSS_AFTER_LAST,
@ -5579,7 +5454,7 @@ enum nl80211_tx_rate_setting {
* (%NL80211_TID_CONFIG_ATTR_TIDS, %NL80211_TID_CONFIG_ATTR_OVERRIDE). * (%NL80211_TID_CONFIG_ATTR_TIDS, %NL80211_TID_CONFIG_ATTR_OVERRIDE).
* @NL80211_TID_CONFIG_ATTR_PEER_SUPP: same as the previous per-vif one, but * @NL80211_TID_CONFIG_ATTR_PEER_SUPP: same as the previous per-vif one, but
* per peer instead. * per peer instead.
* @NL80211_TID_CONFIG_ATTR_OVERRIDE: flag attribute, if set indicates * @NL80211_TID_CONFIG_ATTR_OVERRIDE: flag attribue, if set indicates
* that the new configuration overrides all previous peer * that the new configuration overrides all previous peer
* configurations, otherwise previous peer specific configurations * configurations, otherwise previous peer specific configurations
* should be left untouched. * should be left untouched.
@ -5751,7 +5626,7 @@ struct nl80211_pattern_support {
* "TCP connection wakeup" for more details. This is a nested attribute * "TCP connection wakeup" for more details. This is a nested attribute
* containing the exact information for establishing and keeping alive * containing the exact information for establishing and keeping alive
* the TCP connection. * the TCP connection.
* @NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH: For wakeup reporting only, the * @NL80211_WOWLAN_TRIG_TCP_WAKEUP_MATCH: For wakeup reporting only, the
* wakeup packet was received on the TCP connection * wakeup packet was received on the TCP connection
* @NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST: For wakeup reporting only, the * @NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST: For wakeup reporting only, the
* TCP connection was lost or failed to be established * TCP connection was lost or failed to be established
@ -5780,8 +5655,6 @@ struct nl80211_pattern_support {
* %NL80211_ATTR_SCAN_FREQUENCIES contains more than one * %NL80211_ATTR_SCAN_FREQUENCIES contains more than one
* frequency, it means that the match occurred in more than one * frequency, it means that the match occurred in more than one
* channel. * channel.
* @NL80211_WOWLAN_TRIG_UNPROTECTED_DEAUTH_DISASSOC: For wakeup reporting only.
* Wake up happened due to unprotected deauth or disassoc frame in MFP.
* @NUM_NL80211_WOWLAN_TRIG: number of wake on wireless triggers * @NUM_NL80211_WOWLAN_TRIG: number of wake on wireless triggers
* @MAX_NL80211_WOWLAN_TRIG: highest wowlan trigger attribute number * @MAX_NL80211_WOWLAN_TRIG: highest wowlan trigger attribute number
* *
@ -5809,7 +5682,6 @@ enum nl80211_wowlan_triggers {
NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS, NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS,
NL80211_WOWLAN_TRIG_NET_DETECT, NL80211_WOWLAN_TRIG_NET_DETECT,
NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS, NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS,
NL80211_WOWLAN_TRIG_UNPROTECTED_DEAUTH_DISASSOC,
/* keep last */ /* keep last */
NUM_NL80211_WOWLAN_TRIG, NUM_NL80211_WOWLAN_TRIG,
@ -5965,7 +5837,7 @@ enum nl80211_attr_coalesce_rule {
/** /**
* enum nl80211_coalesce_condition - coalesce rule conditions * enum nl80211_coalesce_condition - coalesce rule conditions
* @NL80211_COALESCE_CONDITION_MATCH: coalesce Rx packets when patterns * @NL80211_COALESCE_CONDITION_MATCH: coalaesce Rx packets when patterns
* in a rule are matched. * in a rule are matched.
* @NL80211_COALESCE_CONDITION_NO_MATCH: coalesce Rx packets when patterns * @NL80211_COALESCE_CONDITION_NO_MATCH: coalesce Rx packets when patterns
* in a rule are not matched. * in a rule are not matched.
@ -6064,7 +5936,7 @@ enum nl80211_if_combination_attrs {
* enum nl80211_plink_state - state of a mesh peer link finite state machine * enum nl80211_plink_state - state of a mesh peer link finite state machine
* *
* @NL80211_PLINK_LISTEN: initial state, considered the implicit * @NL80211_PLINK_LISTEN: initial state, considered the implicit
* state of non-existent mesh peer links * state of non existent mesh peer links
* @NL80211_PLINK_OPN_SNT: mesh plink open frame has been sent to * @NL80211_PLINK_OPN_SNT: mesh plink open frame has been sent to
* this mesh peer * this mesh peer
* @NL80211_PLINK_OPN_RCVD: mesh plink open frame has been received * @NL80211_PLINK_OPN_RCVD: mesh plink open frame has been received
@ -6100,7 +5972,7 @@ enum nl80211_plink_state {
* @NL80211_PLINK_ACTION_BLOCK: block traffic from this mesh peer * @NL80211_PLINK_ACTION_BLOCK: block traffic from this mesh peer
* @NUM_NL80211_PLINK_ACTIONS: number of possible actions * @NUM_NL80211_PLINK_ACTIONS: number of possible actions
*/ */
enum nl80211_plink_action { enum plink_actions {
NL80211_PLINK_ACTION_NO_ACTION, NL80211_PLINK_ACTION_NO_ACTION,
NL80211_PLINK_ACTION_OPEN, NL80211_PLINK_ACTION_OPEN,
NL80211_PLINK_ACTION_BLOCK, NL80211_PLINK_ACTION_BLOCK,
@ -6357,7 +6229,7 @@ enum nl80211_feature_flags {
* request to use RRM (see %NL80211_ATTR_USE_RRM) with * request to use RRM (see %NL80211_ATTR_USE_RRM) with
* %NL80211_CMD_ASSOCIATE and %NL80211_CMD_CONNECT requests, which will set * %NL80211_CMD_ASSOCIATE and %NL80211_CMD_CONNECT requests, which will set
* the ASSOC_REQ_USE_RRM flag in the association request even if * the ASSOC_REQ_USE_RRM flag in the association request even if
* NL80211_FEATURE_QUIET is not advertised. * NL80211_FEATURE_QUIET is not advertized.
* @NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER: This device supports MU-MIMO air * @NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER: This device supports MU-MIMO air
* sniffer which means that it can be configured to hear packets from * sniffer which means that it can be configured to hear packets from
* certain groups which can be configured by the * certain groups which can be configured by the
@ -6369,15 +6241,13 @@ enum nl80211_feature_flags {
* the BSS that the interface that requested the scan is connected to * the BSS that the interface that requested the scan is connected to
* (if available). * (if available).
* @NL80211_EXT_FEATURE_BSS_PARENT_TSF: Per BSS, this driver reports the * @NL80211_EXT_FEATURE_BSS_PARENT_TSF: Per BSS, this driver reports the
* time the last beacon/probe was received. For a non-MLO connection, the * time the last beacon/probe was received. The time is the TSF of the
* time is the TSF of the BSS that the interface that requested the scan is * BSS that the interface that requested the scan is connected to
* connected to (if available). For an MLO connection, the time is the TSF * (if available).
* of the BSS corresponding with link ID specified in the scan request (if
* specified).
* @NL80211_EXT_FEATURE_SET_SCAN_DWELL: This driver supports configuration of * @NL80211_EXT_FEATURE_SET_SCAN_DWELL: This driver supports configuration of
* channel dwell time. * channel dwell time.
* @NL80211_EXT_FEATURE_BEACON_RATE_LEGACY: Driver supports beacon rate * @NL80211_EXT_FEATURE_BEACON_RATE_LEGACY: Driver supports beacon rate
* configuration (AP/mesh), supporting a legacy (non-HT/VHT) rate. * configuration (AP/mesh), supporting a legacy (non HT/VHT) rate.
* @NL80211_EXT_FEATURE_BEACON_RATE_HT: Driver supports beacon rate * @NL80211_EXT_FEATURE_BEACON_RATE_HT: Driver supports beacon rate
* configuration (AP/mesh) with HT rates. * configuration (AP/mesh) with HT rates.
* @NL80211_EXT_FEATURE_BEACON_RATE_VHT: Driver supports beacon rate * @NL80211_EXT_FEATURE_BEACON_RATE_VHT: Driver supports beacon rate
@ -6427,7 +6297,6 @@ enum nl80211_feature_flags {
* receiving control port frames over nl80211 instead of the netdevice. * receiving control port frames over nl80211 instead of the netdevice.
* @NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT: This driver/device supports * @NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT: This driver/device supports
* (average) ACK signal strength reporting. * (average) ACK signal strength reporting.
* @NL80211_EXT_FEATURE_DATA_ACK_SIGNAL_SUPPORT: Backward-compatible ID
* @NL80211_EXT_FEATURE_TXQS: Driver supports FQ-CoDel-enabled intermediate * @NL80211_EXT_FEATURE_TXQS: Driver supports FQ-CoDel-enabled intermediate
* TXQs. * TXQs.
* @NL80211_EXT_FEATURE_SCAN_RANDOM_SN: Driver/device supports randomizing the * @NL80211_EXT_FEATURE_SCAN_RANDOM_SN: Driver/device supports randomizing the
@ -6452,7 +6321,8 @@ enum nl80211_feature_flags {
* @NL80211_EXT_FEATURE_AP_PMKSA_CACHING: Driver/device supports PMKSA caching * @NL80211_EXT_FEATURE_AP_PMKSA_CACHING: Driver/device supports PMKSA caching
* (set/del PMKSA operations) in AP mode. * (set/del PMKSA operations) in AP mode.
* *
* @NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD: Obsolete * @NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD: Driver supports
* filtering of sched scan results using band specific RSSI thresholds.
* *
* @NL80211_EXT_FEATURE_STA_TX_PWR: This driver supports controlling tx power * @NL80211_EXT_FEATURE_STA_TX_PWR: This driver supports controlling tx power
* to a station. * to a station.
@ -6556,16 +6426,6 @@ enum nl80211_feature_flags {
* @NL80211_EXT_FEATURE_OWE_OFFLOAD_AP: Driver/Device wants to do OWE DH IE * @NL80211_EXT_FEATURE_OWE_OFFLOAD_AP: Driver/Device wants to do OWE DH IE
* handling in AP mode. * handling in AP mode.
* *
* @NL80211_EXT_FEATURE_DFS_CONCURRENT: The device supports peer-to-peer or
* ad hoc operation on DFS channels under the control of a concurrent
* DFS master on the same channel as described in FCC-594280 D01
* (Section B.3). This, for example, allows P2P GO and P2P clients to
* operate on DFS channels as long as there's a concurrent BSS connection.
*
* @NL80211_EXT_FEATURE_SPP_AMSDU_SUPPORT: The driver has support for SPP
* (signaling and payload protected) A-MSDUs and this shall be advertised
* in the RSNXE.
*
* @NUM_NL80211_EXT_FEATURES: number of extended features. * @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index. * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
*/ */
@ -6607,7 +6467,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER, NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER,
NL80211_EXT_FEATURE_AIRTIME_FAIRNESS, NL80211_EXT_FEATURE_AIRTIME_FAIRNESS,
NL80211_EXT_FEATURE_AP_PMKSA_CACHING, NL80211_EXT_FEATURE_AP_PMKSA_CACHING,
NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD, /* obsolete */ NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD,
NL80211_EXT_FEATURE_EXT_KEY_ID, NL80211_EXT_FEATURE_EXT_KEY_ID,
NL80211_EXT_FEATURE_STA_TX_PWR, NL80211_EXT_FEATURE_STA_TX_PWR,
NL80211_EXT_FEATURE_SAE_OFFLOAD, NL80211_EXT_FEATURE_SAE_OFFLOAD,
@ -6639,8 +6499,6 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA, NL80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA,
NL80211_EXT_FEATURE_OWE_OFFLOAD, NL80211_EXT_FEATURE_OWE_OFFLOAD,
NL80211_EXT_FEATURE_OWE_OFFLOAD_AP, NL80211_EXT_FEATURE_OWE_OFFLOAD_AP,
NL80211_EXT_FEATURE_DFS_CONCURRENT,
NL80211_EXT_FEATURE_SPP_AMSDU_SUPPORT,
/* add new features before the definition below */ /* add new features before the definition below */
NUM_NL80211_EXT_FEATURES, NUM_NL80211_EXT_FEATURES,
@ -6725,7 +6583,7 @@ enum nl80211_timeout_reason {
* request parameters IE in the probe request * request parameters IE in the probe request
* @NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP: accept broadcast probe responses * @NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP: accept broadcast probe responses
* @NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE: send probe request frames at * @NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE: send probe request frames at
* rate of at least 5.5M. In case non-OCE AP is discovered in the channel, * rate of at least 5.5M. In case non OCE AP is discovered in the channel,
* only the first probe req in the channel will be sent in high rate. * only the first probe req in the channel will be sent in high rate.
* @NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION: allow probe request * @NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION: allow probe request
* tx deferral (dot11FILSProbeDelay shall be set to 15ms) * tx deferral (dot11FILSProbeDelay shall be set to 15ms)
@ -6761,7 +6619,7 @@ enum nl80211_timeout_reason {
* received on the 2.4/5 GHz channels to actively scan only the 6GHz * received on the 2.4/5 GHz channels to actively scan only the 6GHz
* channels on which APs are expected to be found. Note that when not set, * channels on which APs are expected to be found. Note that when not set,
* the scan logic would scan all 6GHz channels, but since transmission of * the scan logic would scan all 6GHz channels, but since transmission of
* probe requests on non-PSC channels is limited, it is highly likely that * probe requests on non PSC channels is limited, it is highly likely that
* these channels would passively be scanned. Also note that when the flag * these channels would passively be scanned. Also note that when the flag
* is set, in addition to the colocated APs, PSC channels would also be * is set, in addition to the colocated APs, PSC channels would also be
* scanned if the user space has asked for it. * scanned if the user space has asked for it.
@ -6811,8 +6669,6 @@ enum nl80211_acl_policy {
* @NL80211_SMPS_STATIC: static SMPS (use a single antenna) * @NL80211_SMPS_STATIC: static SMPS (use a single antenna)
* @NL80211_SMPS_DYNAMIC: dynamic smps (start with a single antenna and * @NL80211_SMPS_DYNAMIC: dynamic smps (start with a single antenna and
* turn on other antennas after CTS/RTS). * turn on other antennas after CTS/RTS).
* @__NL80211_SMPS_AFTER_LAST: internal
* @NL80211_SMPS_MAX: highest used enumeration
*/ */
enum nl80211_smps_mode { enum nl80211_smps_mode {
NL80211_SMPS_OFF, NL80211_SMPS_OFF,
@ -7034,8 +6890,6 @@ enum nl80211_bss_select_attr {
* @NL80211_NAN_FUNC_PUBLISH: function is publish * @NL80211_NAN_FUNC_PUBLISH: function is publish
* @NL80211_NAN_FUNC_SUBSCRIBE: function is subscribe * @NL80211_NAN_FUNC_SUBSCRIBE: function is subscribe
* @NL80211_NAN_FUNC_FOLLOW_UP: function is follow-up * @NL80211_NAN_FUNC_FOLLOW_UP: function is follow-up
* @__NL80211_NAN_FUNC_TYPE_AFTER_LAST: internal use
* @NL80211_NAN_FUNC_MAX_TYPE: internal use
*/ */
enum nl80211_nan_function_type { enum nl80211_nan_function_type {
NL80211_NAN_FUNC_PUBLISH, NL80211_NAN_FUNC_PUBLISH,
@ -7097,7 +6951,7 @@ enum nl80211_nan_func_term_reason {
* The instance ID for the follow up Service Discovery Frame. This is u8. * The instance ID for the follow up Service Discovery Frame. This is u8.
* @NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID: relevant if the function's type * @NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID: relevant if the function's type
* is follow up. This is a u8. * is follow up. This is a u8.
* The requester instance ID for the follow up Service Discovery Frame. * The requestor instance ID for the follow up Service Discovery Frame.
* @NL80211_NAN_FUNC_FOLLOW_UP_DEST: the MAC address of the recipient of the * @NL80211_NAN_FUNC_FOLLOW_UP_DEST: the MAC address of the recipient of the
* follow up Service Discovery Frame. This is a binary attribute. * follow up Service Discovery Frame. This is a binary attribute.
* @NL80211_NAN_FUNC_CLOSE_RANGE: is this function limited for devices in a * @NL80211_NAN_FUNC_CLOSE_RANGE: is this function limited for devices in a
@ -7196,7 +7050,7 @@ enum nl80211_nan_match_attributes {
}; };
/** /**
* enum nl80211_external_auth_action - Action to perform with external * nl80211_external_auth_action - Action to perform with external
* authentication request. Used by NL80211_ATTR_EXTERNAL_AUTH_ACTION. * authentication request. Used by NL80211_ATTR_EXTERNAL_AUTH_ACTION.
* @NL80211_EXTERNAL_AUTH_START: Start the authentication. * @NL80211_EXTERNAL_AUTH_START: Start the authentication.
* @NL80211_EXTERNAL_AUTH_ABORT: Abort the ongoing authentication. * @NL80211_EXTERNAL_AUTH_ABORT: Abort the ongoing authentication.
@ -7214,7 +7068,7 @@ enum nl80211_external_auth_action {
* @NL80211_FTM_RESP_ATTR_LCI: The content of Measurement Report Element * @NL80211_FTM_RESP_ATTR_LCI: The content of Measurement Report Element
* (9.4.2.22 in 802.11-2016) with type 8 - LCI (9.4.2.22.10), * (9.4.2.22 in 802.11-2016) with type 8 - LCI (9.4.2.22.10),
* i.e. starting with the measurement token * i.e. starting with the measurement token
* @NL80211_FTM_RESP_ATTR_CIVICLOC: The content of Measurement Report Element * @NL80211_FTM_RESP_ATTR_CIVIC: The content of Measurement Report Element
* (9.4.2.22 in 802.11-2016) with type 11 - Civic (Section 9.4.2.22.13), * (9.4.2.22 in 802.11-2016) with type 11 - Civic (Section 9.4.2.22.13),
* i.e. starting with the measurement token * i.e. starting with the measurement token
* @__NL80211_FTM_RESP_ATTR_LAST: Internal * @__NL80211_FTM_RESP_ATTR_LAST: Internal
@ -7487,7 +7341,7 @@ enum nl80211_peer_measurement_attrs {
* @NL80211_PMSR_FTM_CAPA_ATTR_TRIGGER_BASED: flag attribute indicating if * @NL80211_PMSR_FTM_CAPA_ATTR_TRIGGER_BASED: flag attribute indicating if
* trigger based ranging measurement is supported * trigger based ranging measurement is supported
* @NL80211_PMSR_FTM_CAPA_ATTR_NON_TRIGGER_BASED: flag attribute indicating * @NL80211_PMSR_FTM_CAPA_ATTR_NON_TRIGGER_BASED: flag attribute indicating
* if non-trigger-based ranging measurement is supported * if non trigger based ranging measurement is supported
* *
* @NUM_NL80211_PMSR_FTM_CAPA_ATTR: internal * @NUM_NL80211_PMSR_FTM_CAPA_ATTR: internal
* @NL80211_PMSR_FTM_CAPA_ATTR_MAX: highest attribute number * @NL80211_PMSR_FTM_CAPA_ATTR_MAX: highest attribute number
@ -7541,7 +7395,7 @@ enum nl80211_peer_measurement_ftm_capa {
* if neither %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED nor * if neither %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED nor
* %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set, EDCA based * %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set, EDCA based
* ranging will be used. * ranging will be used.
* @NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED: request non-trigger-based * @NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED: request non trigger based
* ranging measurement (flag) * ranging measurement (flag)
* This attribute and %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED are * This attribute and %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED are
* mutually exclusive. * mutually exclusive.
@ -7619,7 +7473,7 @@ enum nl80211_peer_measurement_ftm_failure_reasons {
* @NL80211_PMSR_FTM_RESP_ATTR_NUM_FTMR_ATTEMPTS: number of FTM Request frames * @NL80211_PMSR_FTM_RESP_ATTR_NUM_FTMR_ATTEMPTS: number of FTM Request frames
* transmitted (u32, optional) * transmitted (u32, optional)
* @NL80211_PMSR_FTM_RESP_ATTR_NUM_FTMR_SUCCESSES: number of FTM Request frames * @NL80211_PMSR_FTM_RESP_ATTR_NUM_FTMR_SUCCESSES: number of FTM Request frames
* that were acknowledged (u32, optional) * that were acknowleged (u32, optional)
* @NL80211_PMSR_FTM_RESP_ATTR_BUSY_RETRY_TIME: retry time received from the * @NL80211_PMSR_FTM_RESP_ATTR_BUSY_RETRY_TIME: retry time received from the
* busy peer (u32, seconds) * busy peer (u32, seconds)
* @NL80211_PMSR_FTM_RESP_ATTR_NUM_BURSTS_EXP: actual number of bursts exponent * @NL80211_PMSR_FTM_RESP_ATTR_NUM_BURSTS_EXP: actual number of bursts exponent
@ -7857,7 +7711,6 @@ enum nl80211_sae_pwe_mechanism {
* *
* @NL80211_SAR_TYPE_POWER: power limitation specified in 0.25dBm unit * @NL80211_SAR_TYPE_POWER: power limitation specified in 0.25dBm unit
* *
* @NUM_NL80211_SAR_TYPE: internal
*/ */
enum nl80211_sar_type { enum nl80211_sar_type {
NL80211_SAR_TYPE_POWER, NL80211_SAR_TYPE_POWER,
@ -7871,8 +7724,6 @@ enum nl80211_sar_type {
/** /**
* enum nl80211_sar_attrs - Attributes for SAR spec * enum nl80211_sar_attrs - Attributes for SAR spec
* *
* @__NL80211_SAR_ATTR_INVALID: Invalid
*
* @NL80211_SAR_ATTR_TYPE: the SAR type as defined in &enum nl80211_sar_type. * @NL80211_SAR_ATTR_TYPE: the SAR type as defined in &enum nl80211_sar_type.
* *
* @NL80211_SAR_ATTR_SPECS: Nested array of SAR power * @NL80211_SAR_ATTR_SPECS: Nested array of SAR power
@ -7904,8 +7755,6 @@ enum nl80211_sar_attrs {
/** /**
* enum nl80211_sar_specs_attrs - Attributes for SAR power limit specs * enum nl80211_sar_specs_attrs - Attributes for SAR power limit specs
* *
* @__NL80211_SAR_ATTR_SPECS_INVALID: Invalid
*
* @NL80211_SAR_ATTR_SPECS_POWER: Required (s32)value to specify the actual * @NL80211_SAR_ATTR_SPECS_POWER: Required (s32)value to specify the actual
* power limit value in units of 0.25 dBm if type is * power limit value in units of 0.25 dBm if type is
* NL80211_SAR_TYPE_POWER. (i.e., a value of 44 represents 11 dBm). * NL80211_SAR_TYPE_POWER. (i.e., a value of 44 represents 11 dBm).
@ -8020,54 +7869,4 @@ enum nl80211_ap_settings_flags {
NL80211_AP_SETTINGS_SA_QUERY_OFFLOAD_SUPPORT = 1 << 1, NL80211_AP_SETTINGS_SA_QUERY_OFFLOAD_SUPPORT = 1 << 1,
}; };
/**
* enum nl80211_wiphy_radio_attrs - wiphy radio attributes
*
* @__NL80211_WIPHY_RADIO_ATTR_INVALID: Invalid
*
* @NL80211_WIPHY_RADIO_ATTR_INDEX: Index of this radio (u32)
* @NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE: Frequency range supported by this
* radio. Attribute may be present multiple times.
* @NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION: Supported interface
* combination for this radio. Attribute may be present multiple times
* and contains attributes defined in &enum nl80211_if_combination_attrs.
*
* @__NL80211_WIPHY_RADIO_ATTR_LAST: Internal
* @NL80211_WIPHY_RADIO_ATTR_MAX: Highest attribute
*/
enum nl80211_wiphy_radio_attrs {
__NL80211_WIPHY_RADIO_ATTR_INVALID,
NL80211_WIPHY_RADIO_ATTR_INDEX,
NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE,
NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION,
/* keep last */
__NL80211_WIPHY_RADIO_ATTR_LAST,
NL80211_WIPHY_RADIO_ATTR_MAX = __NL80211_WIPHY_RADIO_ATTR_LAST - 1,
};
/**
* enum nl80211_wiphy_radio_freq_range - wiphy radio frequency range
*
* @__NL80211_WIPHY_RADIO_FREQ_ATTR_INVALID: Invalid
*
* @NL80211_WIPHY_RADIO_FREQ_ATTR_START: Frequency range start (u32).
* The unit is kHz.
* @NL80211_WIPHY_RADIO_FREQ_ATTR_END: Frequency range end (u32).
* The unit is kHz.
*
* @__NL80211_WIPHY_RADIO_FREQ_ATTR_LAST: Internal
* @NL80211_WIPHY_RADIO_FREQ_ATTR_MAX: Highest attribute
*/
enum nl80211_wiphy_radio_freq_range {
__NL80211_WIPHY_RADIO_FREQ_ATTR_INVALID,
NL80211_WIPHY_RADIO_FREQ_ATTR_START,
NL80211_WIPHY_RADIO_FREQ_ATTR_END,
__NL80211_WIPHY_RADIO_FREQ_ATTR_LAST,
NL80211_WIPHY_RADIO_FREQ_ATTR_MAX = __NL80211_WIPHY_RADIO_FREQ_ATTR_LAST - 1,
};
#endif /* __LINUX_NL80211_H */ #endif /* __LINUX_NL80211_H */

View file

@ -18,6 +18,11 @@
#include "fst/fst_ctrl_defs.h" #include "fst/fst_ctrl_defs.h"
#endif /* CONFIG_FST_TEST */ #endif /* CONFIG_FST_TEST */
#define US_80211_TU 1024
#define US_TO_TU(m) ((m) * / US_80211_TU)
#define TU_TO_US(m) ((m) * US_80211_TU)
#define FST_LLT_SWITCH_IMMEDIATELY 0 #define FST_LLT_SWITCH_IMMEDIATELY 0
#define fst_printf_session(s, level, format, ...) \ #define fst_printf_session(s, level, format, ...) \
@ -177,8 +182,7 @@ static void fst_session_timeout_handler(void *eloop_data, void *user_ctx)
static void fst_session_stt_arm(struct fst_session *s) static void fst_session_stt_arm(struct fst_session *s)
{ {
/* Action frames sometimes get delayed. Use relaxed timeout (2*) */ /* Action frames sometimes get delayed. Use relaxed timeout (2*) */
eloop_register_timeout(0, eloop_register_timeout(0, 2 * TU_TO_US(FST_DEFAULT_SESSION_TIMEOUT_TU),
2 * TU_TO_USEC(FST_DEFAULT_SESSION_TIMEOUT_TU),
fst_session_timeout_handler, NULL, s); fst_session_timeout_handler, NULL, s);
s->stt_armed = true; s->stt_armed = true;
} }

View file

@ -954,7 +954,6 @@ static void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev)
dev->info.wps_vendor_ext[i] = NULL; dev->info.wps_vendor_ext[i] = NULL;
} }
os_free(dev->bootstrap_params);
wpabuf_free(dev->info.wfd_subelems); wpabuf_free(dev->info.wfd_subelems);
wpabuf_free(dev->info.vendor_elems); wpabuf_free(dev->info.vendor_elems);
wpabuf_free(dev->go_neg_conf); wpabuf_free(dev->go_neg_conf);
@ -1600,8 +1599,7 @@ int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr,
int go_intent, const u8 *own_interface_addr, int go_intent, const u8 *own_interface_addr,
unsigned int force_freq, int persistent_group, unsigned int force_freq, int persistent_group,
const u8 *force_ssid, size_t force_ssid_len, const u8 *force_ssid, size_t force_ssid_len,
int pd_before_go_neg, unsigned int pref_freq, u16 oob_pw_id, int pd_before_go_neg, unsigned int pref_freq, u16 oob_pw_id)
bool p2p2, u16 bootstrap, const char *password)
{ {
struct p2p_device *dev; struct p2p_device *dev;
@ -1685,10 +1683,6 @@ int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr,
dev->wps_method = wps_method; dev->wps_method = wps_method;
dev->oob_pw_id = oob_pw_id; dev->oob_pw_id = oob_pw_id;
dev->p2p2 = p2p2;
dev->req_bootstrap_method = bootstrap;
if (password && os_strlen(password) < sizeof(dev->password))
os_strlcpy(dev->password, password, sizeof(dev->password));
dev->status = P2P_SC_SUCCESS; dev->status = P2P_SC_SUCCESS;
if (p2p->p2p_scan_running) { if (p2p->p2p_scan_running) {
@ -1707,8 +1701,7 @@ int p2p_authorize(struct p2p_data *p2p, const u8 *peer_addr,
int go_intent, const u8 *own_interface_addr, int go_intent, const u8 *own_interface_addr,
unsigned int force_freq, int persistent_group, unsigned int force_freq, int persistent_group,
const u8 *force_ssid, size_t force_ssid_len, const u8 *force_ssid, size_t force_ssid_len,
unsigned int pref_freq, u16 oob_pw_id, u16 bootstrap, unsigned int pref_freq, u16 oob_pw_id)
const char *password)
{ {
struct p2p_device *dev; struct p2p_device *dev;
@ -1742,10 +1735,6 @@ int p2p_authorize(struct p2p_data *p2p, const u8 *peer_addr,
dev->flags &= ~P2P_DEV_USER_REJECTED; dev->flags &= ~P2P_DEV_USER_REJECTED;
dev->go_neg_req_sent = 0; dev->go_neg_req_sent = 0;
dev->go_state = UNKNOWN_GO; dev->go_state = UNKNOWN_GO;
dev->req_bootstrap_method = bootstrap;
if (password && os_strlen(password) < sizeof(dev->password))
os_strlcpy(dev->password, password, sizeof(dev->password));
p2p_set_dev_persistent(dev, persistent_group); p2p_set_dev_persistent(dev, persistent_group);
p2p->go_intent = go_intent; p2p->go_intent = go_intent;
os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN); os_memcpy(p2p->intended_addr, own_interface_addr, ETH_ALEN);
@ -1935,10 +1924,10 @@ static void p2p_rx_p2p_action(struct p2p_data *p2p, const u8 *sa,
p2p_process_invitation_resp(p2p, sa, data + 1, len - 1); p2p_process_invitation_resp(p2p, sa, data + 1, len - 1);
break; break;
case P2P_PROV_DISC_REQ: case P2P_PROV_DISC_REQ:
p2p_handle_prov_disc_req(p2p, sa, data + 1, len - 1, rx_freq); p2p_process_prov_disc_req(p2p, sa, data + 1, len - 1, rx_freq);
break; break;
case P2P_PROV_DISC_RESP: case P2P_PROV_DISC_RESP:
p2p_handle_prov_disc_resp(p2p, sa, data + 1, len - 1, rx_freq); p2p_process_prov_disc_resp(p2p, sa, data + 1, len - 1);
break; break;
case P2P_DEV_DISC_REQ: case P2P_DEV_DISC_REQ:
p2p_process_dev_disc_req(p2p, sa, data + 1, len - 1, rx_freq); p2p_process_dev_disc_req(p2p, sa, data + 1, len - 1, rx_freq);
@ -2979,44 +2968,6 @@ bool is_p2p_6ghz_disabled(struct p2p_data *p2p)
} }
static void p2p_pairing_info_deinit(struct p2p_data *p2p)
{
os_free(p2p->pairing_info);
}
static int p2p_pairing_info_init(struct p2p_data *p2p)
{
struct p2p_pairing_info *pairing_info;
if (p2p->cfg->pairing_config.dik_len > DEVICE_IDENTITY_KEY_MAX_LEN)
return -1;
pairing_info = os_zalloc(sizeof(struct p2p_pairing_info));
if (!pairing_info)
return -1;
pairing_info->enable_pairing_setup =
p2p->cfg->pairing_config.enable_pairing_setup;
pairing_info->enable_pairing_cache =
p2p->cfg->pairing_config.enable_pairing_cache;
pairing_info->supported_bootstrap =
p2p->cfg->pairing_config.bootstrap_methods;
pairing_info->dev_ik.cipher_version =
p2p->cfg->pairing_config.dik_cipher;
pairing_info->dev_ik.dik_len = p2p->cfg->pairing_config.dik_len;
os_memcpy(pairing_info->dev_ik.dik_data,
p2p->cfg->pairing_config.dik_data,
p2p->cfg->pairing_config.dik_len);
p2p_pairing_info_deinit(p2p);
p2p->pairing_info = pairing_info;
return 0;
}
struct p2p_data * p2p_init(const struct p2p_config *cfg) struct p2p_data * p2p_init(const struct p2p_config *cfg)
{ {
struct p2p_data *p2p; struct p2p_data *p2p;
@ -3072,10 +3023,6 @@ struct p2p_data * p2p_init(const struct p2p_config *cfg)
p2p->go_timeout = 100; p2p->go_timeout = 100;
p2p->client_timeout = 20; p2p->client_timeout = 20;
p2p->num_p2p_sd_queries = 0; p2p->num_p2p_sd_queries = 0;
/* Default comeback after one second */
if (!p2p->cfg->comeback_after)
p2p->cfg->comeback_after = 977; /* TUs */
p2p_pairing_info_init(p2p);
p2p_dbg(p2p, "initialized"); p2p_dbg(p2p, "initialized");
p2p_channels_dump(p2p, "channels", &p2p->cfg->channels); p2p_channels_dump(p2p, "channels", &p2p->cfg->channels);
@ -3119,7 +3066,6 @@ void p2p_deinit(struct p2p_data *p2p)
p2p_remove_wps_vendor_extensions(p2p); p2p_remove_wps_vendor_extensions(p2p);
os_free(p2p->no_go_freq.range); os_free(p2p->no_go_freq.range);
p2p_service_flush_asp(p2p); p2p_service_flush_asp(p2p);
p2p_pairing_info_deinit(p2p);
os_free(p2p); os_free(p2p);
} }
@ -3453,7 +3399,7 @@ static void p2p_retry_pd(struct p2p_data *p2p)
if (!ether_addr_equal(p2p->pending_pd_devaddr, if (!ether_addr_equal(p2p->pending_pd_devaddr,
dev->info.p2p_device_addr)) dev->info.p2p_device_addr))
continue; continue;
if (!dev->req_config_methods && !dev->req_bootstrap_method) if (!dev->req_config_methods)
continue; continue;
p2p_dbg(p2p, "Send pending Provision Discovery Request to " p2p_dbg(p2p, "Send pending Provision Discovery Request to "
@ -5742,184 +5688,3 @@ void set_p2p_allow_6ghz(struct p2p_data *p2p, bool value)
{ {
p2p->allow_6ghz = value; p2p->allow_6ghz = value;
} }
static int p2p_derive_nonce_tag(struct p2p_data *p2p)
{
u8 dira_nonce[DEVICE_IDENTITY_NONCE_LEN];
u8 dira_tag[DEVICE_MAX_HASH_LEN];
u8 data[DIR_STR_LEN + DEVICE_IDENTITY_NONCE_LEN + ETH_ALEN];
struct p2p_id_key *dev_ik;
dev_ik = &p2p->pairing_info->dev_ik;
if (dev_ik->cipher_version != DIRA_CIPHER_VERSION_128) {
wpa_printf(MSG_INFO,
"P2P: Unsupported DIRA Cipher version = %d",
dev_ik->cipher_version);
return -1;
}
if (dev_ik->dik_len != DEVICE_IDENTITY_KEY_LEN) {
wpa_printf(MSG_INFO, "P2P: Invalid DIK length = %zu",
dev_ik->dik_len);
return -1;
}
os_memset(data, 0, sizeof(data));
if (os_get_random(dira_nonce, DEVICE_IDENTITY_NONCE_LEN) < 0) {
wpa_printf(MSG_ERROR, "P2P: Failed to generate DIRA nonce");
return -1;
}
/* Tag = Truncate-64(HMAC-SHA-256(DevIK,
* "DIR" || P2P Device Address || Nonce))
*/
os_memcpy(data, "DIR", DIR_STR_LEN);
os_memcpy(&data[DIR_STR_LEN], p2p->cfg->dev_addr, ETH_ALEN);
os_memcpy(&data[DIR_STR_LEN + ETH_ALEN], dira_nonce,
DEVICE_IDENTITY_NONCE_LEN);
if (hmac_sha256(dev_ik->dik_data, dev_ik->dik_len, data, sizeof(data),
dira_tag) < 0) {
wpa_printf(MSG_ERROR, "P2P: Could not derive DIRA tag");
return -1;
}
dev_ik->dira_nonce_len = DEVICE_IDENTITY_NONCE_LEN;
os_memcpy(dev_ik->dira_nonce, dira_nonce, DEVICE_IDENTITY_NONCE_LEN);
dev_ik->dira_tag_len = DEVICE_IDENTITY_TAG_LEN;
os_memcpy(dev_ik->dira_tag, dira_tag, DEVICE_IDENTITY_TAG_LEN);
wpa_hexdump_key(MSG_DEBUG, "P2P: DIK", dev_ik->dik_data,
dev_ik->dik_len);
wpa_hexdump_key(MSG_DEBUG, "P2P: DIRA-NONCE", dev_ik->dira_nonce,
dev_ik->dira_nonce_len);
wpa_hexdump_key(MSG_DEBUG, "P2P: DIRA-TAG", dev_ik->dira_tag,
dev_ik->dira_tag_len);
return 0;
}
struct wpabuf * p2p_usd_elems(struct p2p_data *p2p)
{
struct wpabuf *buf;
u8 *len;
u8 group_capab;
buf = wpabuf_alloc(1000);
if (!buf)
return NULL;
len = p2p_buf_add_ie_hdr(buf);
/* P2P Capability attribute */
group_capab = 0;
if (p2p->num_groups) {
group_capab |= P2P_GROUP_CAPAB_GROUP_OWNER;
if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) &&
(p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED) &&
p2p->cross_connect)
group_capab |= P2P_GROUP_CAPAB_CROSS_CONN;
}
if (p2p->cfg->p2p_intra_bss)
group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST;
p2p_buf_add_capability(buf, p2p->dev_capab &
~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
group_capab);
/* P2P Device Info attribute */
p2p_buf_add_device_info(buf, p2p, NULL);
p2p_buf_update_ie_hdr(buf, len);
len = p2p_buf_add_p2p2_ie_hdr(buf);
/* P2P Capability Extension attribute */
p2p_buf_add_pcea(buf, p2p);
/* P2P Pairing Bootstrapping Method attribute */
p2p_buf_add_pbma(buf, p2p->cfg->pairing_config.bootstrap_methods, NULL,
0, 0);
/* P2P Device Identity Resolution attribute */
if (p2p->pairing_info &&
p2p->cfg->pairing_config.pairing_capable &&
p2p->cfg->pairing_config.enable_pairing_cache &&
p2p->cfg->pairing_config.enable_pairing_verification &&
p2p_derive_nonce_tag(p2p) == 0)
p2p_buf_add_dira(buf, p2p);
p2p_buf_update_ie_hdr(buf, len);
return buf;
}
void p2p_process_usd_elems(struct p2p_data *p2p, const u8 *ies, u16 ies_len,
const u8 *peer_addr, unsigned int freq)
{
struct p2p_device *dev;
struct p2p_message msg;
const u8 *p2p_dev_addr;
os_memset(&msg, 0, sizeof(msg));
if (p2p_parse_ies(ies, ies_len, &msg)) {
p2p_dbg(p2p, "Failed to parse P2P IE for a device entry");
p2p_parse_free(&msg);
return;
}
if (msg.p2p_device_addr)
p2p_dev_addr = msg.p2p_device_addr;
else
p2p_dev_addr = peer_addr;
dev = p2p_create_device(p2p, p2p_dev_addr);
if (!dev) {
p2p_parse_free(&msg);
p2p_dbg(p2p, "Failed to add a peer P2P Device");
return;
}
dev->p2p2 = true;
/* Reset info from old IEs */
dev->info.reg_info = 0;
os_memset(&dev->info.pairing_config, 0,
sizeof(struct p2p_pairing_config));
os_get_reltime(&dev->last_seen);
dev->listen_freq = freq;
dev->oper_freq = freq;
if (msg.capability) {
/*
* P2P Client Discoverability bit is reserved in all frames
* that use this function, so do not change its value here.
*/
dev->info.dev_capab &= P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;
dev->info.dev_capab |= msg.capability[0] &
~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY;
dev->info.group_capab = msg.capability[1];
}
if (msg.pcea_info && msg.pcea_info_len >= 2)
p2p_process_pcea(p2p, &msg, dev);
if (msg.pbma_info && msg.pbma_info_len == 2)
dev->info.pairing_config.bootstrap_methods =
WPA_GET_LE16(msg.pbma_info);
if (!ether_addr_equal(peer_addr, p2p_dev_addr))
os_memcpy(dev->interface_addr, peer_addr, ETH_ALEN);
p2p_dbg(p2p, "Updated device entry based on USD frame: " MACSTR
" dev_capab=0x%x group_capab=0x%x listen_freq=%d",
MAC2STR(dev->info.p2p_device_addr), dev->info.dev_capab,
dev->info.group_capab, dev->listen_freq);
p2p->cfg->dev_found(p2p->cfg->cb_ctx, dev->info.p2p_device_addr,
&dev->info, !(dev->flags & P2P_DEV_REPORTED_ONCE));
p2p_parse_free(&msg);
}

View file

@ -12,16 +12,6 @@
#include "common/ieee802_11_defs.h" #include "common/ieee802_11_defs.h"
#include "wps/wps.h" #include "wps/wps.h"
#define DEVICE_IDENTITY_KEY_MAX_LEN 64
#define DEVICE_IDENTITY_KEY_LEN 16
#define DEVICE_IDENTITY_TAG_LEN 8
#define DEVICE_IDENTITY_NONCE_LEN 8
#define DEVICE_MAX_HASH_LEN 32
#define DIR_STR_LEN 3
/* DIRA Cipher versions */
#define DIRA_CIPHER_VERSION_128 0
struct weighted_pcl; struct weighted_pcl;
/* P2P ASP Setup Capability */ /* P2P ASP Setup Capability */
@ -330,50 +320,6 @@ enum p2p_scan_type {
#define P2P_MAX_WPS_VENDOR_EXT 10 #define P2P_MAX_WPS_VENDOR_EXT 10
/**
* struct p2p_pairing_config - P2P pairing configuration
*/
struct p2p_pairing_config {
/**
* Pairing capable
*/
bool pairing_capable;
/**
* Enable P2P pairing setup
*/
bool enable_pairing_setup;
/**
* Enable pairing cache to allow verification
*/
bool enable_pairing_cache;
/**
* Enable P2P pairing verification with cached NIK/NPK
*/
bool enable_pairing_verification;
/**
* P2P bootstrapping methods supported
*/
u16 bootstrap_methods;
/**
* Bitmap of supported PASN types
*/
u8 pasn_type;
/* Cipher version type */
int dik_cipher;
/* Buffer to hold the DevIK */
u8 dik_data[DEVICE_IDENTITY_KEY_MAX_LEN];
/* Length of DevIK in octets */
size_t dik_len;
};
/** /**
* struct p2p_peer_info - P2P peer information * struct p2p_peer_info - P2P peer information
*/ */
@ -465,21 +411,6 @@ struct p2p_peer_info {
* p2ps_instance - P2PS Application Service Info * p2ps_instance - P2PS Application Service Info
*/ */
struct wpabuf *p2ps_instance; struct wpabuf *p2ps_instance;
/**
* pcea_cap_info - Capability info in PCEA
*/
u16 pcea_cap_info;
/**
* The regulatory info encoding for operation in 6 GHz band
*/
u8 reg_info;
/**
* p2p_pairing_config - P2P pairing configuration
*/
struct p2p_pairing_config pairing_config;
}; };
enum p2p_prov_disc_status { enum p2p_prov_disc_status {
@ -658,33 +589,6 @@ struct p2p_config {
*/ */
unsigned int passphrase_len; unsigned int passphrase_len;
/**
* p2p_pairing_config - P2P pairing configuration
*/
struct p2p_pairing_config pairing_config;
/**
* reg_info - Regulatory info encoding for operation in 6 GHz band
*/
u8 reg_info;
/**
* dfs_owner - Enable P2P GO to act as DFS Owner
*/
bool dfs_owner;
/**
* twt_power_mgmt - Enable TWT based power management for P2P
*/
bool twt_power_mgmt;
/**
* comeback_after - Bootstrap request unauthorized for peer
*
* Ask to come back after this many TUs.
*/
u16 comeback_after;
/** /**
* cb_ctx - Context to use with callback functions * cb_ctx - Context to use with callback functions
*/ */
@ -1232,19 +1136,6 @@ struct p2p_config {
int (*get_pref_freq_list)(void *ctx, int go, int (*get_pref_freq_list)(void *ctx, int go,
unsigned int *len, unsigned int *len,
struct weighted_pcl *freq_list); struct weighted_pcl *freq_list);
/**
* register_bootstrap_comeback - Register timeout to initiate bootstrap
* comeback request
* @ctx: Callback context from cb_ctx
* @addr: P2P Device Address to which comeback request is to be sent
* @comeback_after: Time in TUs after which comeback request is sent
*
* This function can be used to send comeback request after given
* timeout.
*/
void (*register_bootstrap_comeback)(void *ctx, const u8 *addr,
u16 comeback_after);
}; };
@ -1428,10 +1319,6 @@ void p2p_stop_listen(struct p2p_data *p2p);
* formation * formation
* @pref_freq: Preferred operating frequency in MHz or 0 (this is only used if * @pref_freq: Preferred operating frequency in MHz or 0 (this is only used if
* force_freq == 0) * force_freq == 0)
* @oob_pw_id: OOB password identifier
* @p2p2: Device supports P2P2 features
* @bootstrap: Bootstrapping method requested for P2P2 provision discovery
* @password: P2P2 pairing password or %NULL for opportunistic method
* Returns: 0 on success, -1 on failure * Returns: 0 on success, -1 on failure
*/ */
int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr, int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr,
@ -1439,8 +1326,7 @@ int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr,
int go_intent, const u8 *own_interface_addr, int go_intent, const u8 *own_interface_addr,
unsigned int force_freq, int persistent_group, unsigned int force_freq, int persistent_group,
const u8 *force_ssid, size_t force_ssid_len, const u8 *force_ssid, size_t force_ssid_len,
int pd_before_go_neg, unsigned int pref_freq, u16 oob_pw_id, int pd_before_go_neg, unsigned int pref_freq, u16 oob_pw_id);
bool p2p2, u16 bootstrap, const char *password);
/** /**
* p2p_authorize - Authorize P2P group formation (GO negotiation) * p2p_authorize - Authorize P2P group formation (GO negotiation)
@ -1458,9 +1344,6 @@ int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr,
* @force_ssid_len: Length of $force_ssid buffer * @force_ssid_len: Length of $force_ssid buffer
* @pref_freq: Preferred operating frequency in MHz or 0 (this is only used if * @pref_freq: Preferred operating frequency in MHz or 0 (this is only used if
* force_freq == 0) * force_freq == 0)
* @oob_pw_id: OOB password identifier
* @bootstrap: Bootstrapping method requested for P2P2 provision discovery
* @password: P2P2 pairing password or %NULL for opportunistic method
* Returns: 0 on success, -1 on failure * Returns: 0 on success, -1 on failure
* *
* This is like p2p_connect(), but the actual group negotiation is not * This is like p2p_connect(), but the actual group negotiation is not
@ -1471,8 +1354,7 @@ int p2p_authorize(struct p2p_data *p2p, const u8 *peer_addr,
int go_intent, const u8 *own_interface_addr, int go_intent, const u8 *own_interface_addr,
unsigned int force_freq, int persistent_group, unsigned int force_freq, int persistent_group,
const u8 *force_ssid, size_t force_ssid_len, const u8 *force_ssid, size_t force_ssid_len,
unsigned int pref_freq, u16 oob_pw_id, u16 bootstrap, unsigned int pref_freq, u16 oob_pw_id);
const char *password);
/** /**
* p2p_reject - Reject peer device (explicitly block connection attempts) * p2p_reject - Reject peer device (explicitly block connection attempts)
@ -2547,8 +2429,5 @@ bool is_p2p_allow_6ghz(struct p2p_data *p2p);
void set_p2p_allow_6ghz(struct p2p_data *p2p, bool value); void set_p2p_allow_6ghz(struct p2p_data *p2p, bool value);
int p2p_remove_6ghz_channels(struct weighted_pcl *pref_freq_list, int size); int p2p_remove_6ghz_channels(struct weighted_pcl *pref_freq_list, int size);
int p2p_channel_to_freq(int op_class, int channel); int p2p_channel_to_freq(int op_class, int channel);
struct wpabuf * p2p_usd_elems(struct p2p_data *p2p);
void p2p_process_usd_elems(struct p2p_data *p2p, const u8 *ies, u16 ies_len,
const u8 *peer_addr, unsigned int freq);
#endif /* P2P_H */ #endif /* P2P_H */

View file

@ -55,24 +55,11 @@ u8 * p2p_buf_add_ie_hdr(struct wpabuf *buf)
void p2p_buf_update_ie_hdr(struct wpabuf *buf, u8 *len) void p2p_buf_update_ie_hdr(struct wpabuf *buf, u8 *len)
{ {
/* Update P2P/P2P2 IE Length */ /* Update P2P IE Length */
*len = (u8 *) wpabuf_put(buf, 0) - len - 1; *len = (u8 *) wpabuf_put(buf, 0) - len - 1;
} }
u8 * p2p_buf_add_p2p2_ie_hdr(struct wpabuf *buf)
{
u8 *len;
/* P2P2 IE header */
wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
len = wpabuf_put(buf, 1); /* IE length to be filled */
wpabuf_put_be32(buf, P2P2_IE_VENDOR_TYPE);
wpa_printf(MSG_DEBUG, "P2P: * P2P2 IE header");
return len;
}
void p2p_buf_add_capability(struct wpabuf *buf, u8 dev_capab, u8 group_capab) void p2p_buf_add_capability(struct wpabuf *buf, u8 dev_capab, u8 group_capab)
{ {
/* P2P Capability */ /* P2P Capability */
@ -722,111 +709,6 @@ void p2p_buf_add_persistent_group_info(struct wpabuf *buf, const u8 *dev_addr,
} }
void p2p_buf_add_pcea(struct wpabuf *buf, struct p2p_data *p2p)
{
u8 *len;
u16 capability_info = 0;
/* P2P Capability Extension */
wpabuf_put_u8(buf, P2P_ATTR_CAPABILITY_EXTENSION);
/* Length to be filled */
len = wpabuf_put(buf, 2);
if (!p2p->cfg->p2p_6ghz_disable)
capability_info |= P2P_PCEA_6GHZ;
if (p2p->cfg->reg_info)
capability_info |= P2P_PCEA_REG_INFO;
if (p2p->cfg->dfs_owner)
capability_info |= P2P_PCEA_DFS_OWNER;
if (p2p->cfg->pairing_config.pairing_capable)
capability_info |= P2P_PCEA_PAIRING_CAPABLE;
if (p2p->cfg->pairing_config.enable_pairing_setup)
capability_info |= P2P_PCEA_PAIRING_SETUP_ENABLED;
if (p2p->cfg->pairing_config.enable_pairing_cache)
capability_info |= P2P_PCEA_PMK_CACHING;
if (p2p->cfg->pairing_config.pasn_type)
capability_info |= P2P_PCEA_PASN_TYPE;
if (p2p->cfg->twt_power_mgmt)
capability_info |= P2P_PCEA_TWT_POWER_MGMT;
/* Field length is (n-1), n in octets */
capability_info |= (2 - 1) & P2P_PCEA_LEN_MASK;
wpabuf_put_le16(buf, capability_info);
if (capability_info & P2P_PCEA_REG_INFO)
wpabuf_put_u8(buf, p2p->cfg->reg_info);
if (capability_info & P2P_PCEA_PASN_TYPE)
wpabuf_put_u8(buf, p2p->cfg->pairing_config.pasn_type);
/* Update attribute length */
WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2);
wpa_printf(MSG_DEBUG, "P2P: * Capability Extension info=0x%x",
capability_info);
}
void p2p_buf_add_pbma(struct wpabuf *buf, u16 bootstrap, const u8 *cookie,
size_t cookie_len, int comeback_after)
{
u8 *len;
/* P2P Pairing and Bootstrapping methods */
wpabuf_put_u8(buf, P2P_ATTR_PAIRING_AND_BOOTSTRAPPING);
/* Length to be filled */
len = wpabuf_put(buf, 2);
if (cookie && cookie_len) {
if (comeback_after)
wpabuf_put_le16(buf, comeback_after);
wpabuf_put_u8(buf, cookie_len);
wpabuf_put_data(buf, cookie, cookie_len);
}
wpabuf_put_le16(buf, bootstrap);
/* Update attribute length */
WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2);
wpa_printf(MSG_DEBUG, "P2P: * Bootstrapping method=0x%x",
bootstrap);
}
void p2p_buf_add_dira(struct wpabuf *buf, struct p2p_data *p2p)
{
u8 *len;
struct p2p_id_key *dev_ik;
if (!p2p->cfg->pairing_config.pairing_capable ||
!p2p->cfg->pairing_config.enable_pairing_cache ||
!p2p->cfg->pairing_config.enable_pairing_verification)
return;
dev_ik = &p2p->pairing_info->dev_ik;
/* P2P DIRA */
wpabuf_put_u8(buf, P2P_ATTR_DEVICE_IDENTITY_RESOLUTION);
/* Length to be filled */
len = wpabuf_put(buf, 2);
wpabuf_put_u8(buf, dev_ik->cipher_version);
wpabuf_put_data(buf, dev_ik->dira_nonce, dev_ik->dira_nonce_len);
wpabuf_put_data(buf, dev_ik->dira_tag, dev_ik->dira_tag_len);
/* Update attribute length */
WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2);
wpa_printf(MSG_DEBUG, "P2P: * DIRA");
}
static int p2p_add_wps_string(struct wpabuf *buf, enum wps_attribute attr, static int p2p_add_wps_string(struct wpabuf *buf, enum wps_attribute attr,
const char *val) const char *val)
{ {

View file

@ -244,8 +244,6 @@ int p2p_connect_send(struct p2p_data *p2p, struct p2p_device *dev)
config_method = WPS_CONFIG_PUSHBUTTON; config_method = WPS_CONFIG_PUSHBUTTON;
else if (dev->wps_method == WPS_P2PS) else if (dev->wps_method == WPS_P2PS)
config_method = WPS_CONFIG_P2PS; config_method = WPS_CONFIG_P2PS;
else if (dev->p2p2 && dev->req_bootstrap_method)
config_method = WPS_NOT_READY;
else else
return -1; return -1;
return p2p_prov_disc_req(p2p, dev->info.p2p_device_addr, return p2p_prov_disc_req(p2p, dev->info.p2p_device_addr,

View file

@ -36,26 +36,6 @@ enum p2p_go_state {
REMOTE_GO REMOTE_GO
}; };
/**
* struct bootstrap_params - P2P Device bootstrap request parameters
*/
struct p2p_bootstrap_params {
/* Bootstrap method */
u16 bootstrap_method;
/* Status code */
enum p2p_status_code status;
/* Cookie for comeback */
u8 cookie[50];
/* Cookie length */
size_t cookie_len;
/* Comeback time in TUs after which receiver is requested to retry */
int comeback_after;
};
/** /**
* struct p2p_device - P2P Device data (internal to P2P module) * struct p2p_device - P2P Device data (internal to P2P module)
*/ */
@ -170,18 +150,6 @@ struct p2p_device {
int sd_pending_bcast_queries; int sd_pending_bcast_queries;
bool support_6ghz; bool support_6ghz;
/* Supports P2P2 */
bool p2p2;
/* Requested bootstrap method */
u16 req_bootstrap_method;
/* Bootstrap parameters received from peer */
struct p2p_bootstrap_params *bootstrap_params;
/* Password for P2P2 GO negotiation */
char password[100];
}; };
struct p2p_sd_query { struct p2p_sd_query {
@ -192,39 +160,6 @@ struct p2p_sd_query {
struct wpabuf *tlvs; struct wpabuf *tlvs;
}; };
/* P2P Device Identity Key parameters */
struct p2p_id_key {
/* AKMP used for DevIK derviation */
int akmp;
/* Cipher version type */
int cipher_version;
/* Buffer to hold the DevIK */
u8 dik_data[DEVICE_IDENTITY_KEY_MAX_LEN];
/* Length of DevIK */
size_t dik_len;
/* Nonce used in DIRA attribute */
u8 dira_nonce[DEVICE_IDENTITY_NONCE_LEN];
/* Length of nonce */
size_t dira_nonce_len;
/* Tag computed for nonce using NIK */
u8 dira_tag[DEVICE_IDENTITY_TAG_LEN];
/* Length of tag in octets */
size_t dira_tag_len;
};
struct p2p_pairing_info {
/* P2P device own address */
u8 own_addr[ETH_ALEN];
/* device capability to enable pairing setup */
bool enable_pairing_setup;
/* device capability to enable pairing cache */
bool enable_pairing_cache;
/* device supported bootstrapping */
u16 supported_bootstrap;
/* P2P Device Identity Key info */
struct p2p_id_key dev_ik;
};
/** /**
* struct p2p_data - P2P module data (internal to P2P module) * struct p2p_data - P2P module data (internal to P2P module)
*/ */
@ -619,8 +554,6 @@ struct p2p_data {
bool p2p_6ghz_capable; bool p2p_6ghz_capable;
bool include_6ghz; bool include_6ghz;
bool allow_6ghz; bool allow_6ghz;
struct p2p_pairing_info *pairing_info;
}; };
/** /**
@ -628,7 +561,6 @@ struct p2p_data {
*/ */
struct p2p_message { struct p2p_message {
struct wpabuf *p2p_attributes; struct wpabuf *p2p_attributes;
struct wpabuf *p2p2_attributes;
struct wpabuf *wps_attributes; struct wpabuf *wps_attributes;
struct wpabuf *wfd_subelems; struct wpabuf *wfd_subelems;
@ -727,12 +659,6 @@ struct p2p_message {
const u8 *pref_freq_list; const u8 *pref_freq_list;
size_t pref_freq_list_len; size_t pref_freq_list_len;
const u8 *pcea_info;
size_t pcea_info_len;
const u8 *pbma_info;
size_t pbma_info_len;
}; };
@ -822,7 +748,6 @@ void p2p_buf_add_action_hdr(struct wpabuf *buf, u8 subtype, u8 dialog_token);
void p2p_buf_add_public_action_hdr(struct wpabuf *buf, u8 subtype, void p2p_buf_add_public_action_hdr(struct wpabuf *buf, u8 subtype,
u8 dialog_token); u8 dialog_token);
u8 * p2p_buf_add_ie_hdr(struct wpabuf *buf); u8 * p2p_buf_add_ie_hdr(struct wpabuf *buf);
u8 * p2p_buf_add_p2p2_ie_hdr(struct wpabuf *buf);
void p2p_buf_add_status(struct wpabuf *buf, u8 status); void p2p_buf_add_status(struct wpabuf *buf, u8 status);
void p2p_buf_add_device_info(struct wpabuf *buf, struct p2p_data *p2p, void p2p_buf_add_device_info(struct wpabuf *buf, struct p2p_data *p2p,
struct p2p_device *peer); struct p2p_device *peer);
@ -863,10 +788,6 @@ void p2p_buf_add_feature_capability(struct wpabuf *buf, u16 len,
const u8 *mask); const u8 *mask);
void p2p_buf_add_persistent_group_info(struct wpabuf *buf, const u8 *dev_addr, void p2p_buf_add_persistent_group_info(struct wpabuf *buf, const u8 *dev_addr,
const u8 *ssid, size_t ssid_len); const u8 *ssid, size_t ssid_len);
void p2p_buf_add_pcea(struct wpabuf *buf, struct p2p_data *p2p);
void p2p_buf_add_pbma(struct wpabuf *buf, u16 bootstrap, const u8 *cookie,
size_t cookie_len, int comeback_after);
void p2p_buf_add_dira(struct wpabuf *buf, struct p2p_data *p2p);
int p2p_build_wps_ie(struct p2p_data *p2p, struct wpabuf *buf, int pw_id, int p2p_build_wps_ie(struct p2p_data *p2p, struct wpabuf *buf, int pw_id,
int all_attr); int all_attr);
void p2p_buf_add_pref_channel_list(struct wpabuf *buf, void p2p_buf_add_pref_channel_list(struct wpabuf *buf,
@ -905,16 +826,14 @@ void p2p_check_pref_chan(struct p2p_data *p2p, int go,
struct p2p_device *dev, struct p2p_message *msg); struct p2p_device *dev, struct p2p_message *msg);
/* p2p_pd.c */ /* p2p_pd.c */
void p2p_handle_prov_disc_req(struct p2p_data *p2p, const u8 *sa, void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
const u8 *data, size_t len, int rx_freq);
void p2p_handle_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
const u8 *data, size_t len, int rx_freq); const u8 *data, size_t len, int rx_freq);
void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
const u8 *data, size_t len);
int p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev, int p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev,
int join, int force_freq); int join, int force_freq);
void p2p_reset_pending_pd(struct p2p_data *p2p); void p2p_reset_pending_pd(struct p2p_data *p2p);
void p2ps_prov_free(struct p2p_data *p2p); void p2ps_prov_free(struct p2p_data *p2p);
void p2p_process_pcea(struct p2p_data *p2p, struct p2p_message *msg,
struct p2p_device *dev);
/* p2p_invitation.c */ /* p2p_invitation.c */
void p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa, void p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa,

View file

@ -417,26 +417,6 @@ static int p2p_parse_attribute(u8 id, const u8 *data, u16 len,
msg->persistent_ssid_len)); msg->persistent_ssid_len));
break; break;
} }
case P2P_ATTR_CAPABILITY_EXTENSION:
if (len < 2) {
wpa_printf(MSG_DEBUG, "P2P: Too short PCEA (length %d)",
len);
return -1;
}
msg->pcea_info = data;
msg->pcea_info_len = len;
wpa_printf(MSG_DEBUG, "P2P: * PCEA (length=%u)", len);
break;
case P2P_ATTR_PAIRING_AND_BOOTSTRAPPING:
if (len < 1) {
wpa_printf(MSG_DEBUG, "P2P: Too short PBMA (length %d)",
len);
return -1;
}
msg->pbma_info = data;
msg->pbma_info_len = len;
wpa_printf(MSG_DEBUG, "P2P: * PBMA (length=%u)", len);
break;
default: default:
wpa_printf(MSG_DEBUG, "P2P: Skipped unknown attribute %d " wpa_printf(MSG_DEBUG, "P2P: Skipped unknown attribute %d "
"(length %d)", id, len); "(length %d)", id, len);
@ -593,18 +573,6 @@ int p2p_parse_ies(const u8 *data, size_t len, struct p2p_message *msg)
return -1; return -1;
} }
msg->p2p2_attributes = ieee802_11_vendor_ie_concat(data, len,
P2P2_IE_VENDOR_TYPE);
if (msg->p2p2_attributes &&
p2p_parse_p2p_ie(msg->p2p2_attributes, msg)) {
wpa_printf(MSG_DEBUG, "P2P: Failed to parse P2P2 IE data");
if (msg->p2p2_attributes)
wpa_hexdump_buf(MSG_MSGDUMP, "P2P: P2P2 IE data",
msg->p2p2_attributes);
p2p_parse_free(msg);
return -1;
}
#ifdef CONFIG_WIFI_DISPLAY #ifdef CONFIG_WIFI_DISPLAY
if (elems.wfd) { if (elems.wfd) {
msg->wfd_subelems = ieee802_11_vendor_ie_concat( msg->wfd_subelems = ieee802_11_vendor_ie_concat(
@ -679,8 +647,6 @@ void p2p_parse_free(struct p2p_message *msg)
{ {
wpabuf_free(msg->p2p_attributes); wpabuf_free(msg->p2p_attributes);
msg->p2p_attributes = NULL; msg->p2p_attributes = NULL;
wpabuf_free(msg->p2p2_attributes);
msg->p2p2_attributes = NULL;
wpabuf_free(msg->wps_attributes); wpabuf_free(msg->wps_attributes);
msg->wps_attributes = NULL; msg->wps_attributes = NULL;
#ifdef CONFIG_WIFI_DISPLAY #ifdef CONFIG_WIFI_DISPLAY

File diff suppressed because it is too large Load diff

View file

@ -192,14 +192,6 @@ int pasn_set_extra_ies(struct pasn_data *pasn, const u8 *extra_ies,
} }
void pasn_set_noauth(struct pasn_data *pasn, bool noauth)
{
if (!pasn)
return;
pasn->noauth = noauth;
}
int pasn_get_akmp(struct pasn_data *pasn) int pasn_get_akmp(struct pasn_data *pasn)
{ {
if (!pasn) if (!pasn)

View file

@ -174,8 +174,7 @@ int wpa_pasn_auth_tx_status(struct pasn_data *pasn,
/* Responder */ /* Responder */
int handle_auth_pasn_1(struct pasn_data *pasn, int handle_auth_pasn_1(struct pasn_data *pasn,
const u8 *own_addr, const u8 *peer_addr, const u8 *own_addr, const u8 *peer_addr,
const struct ieee80211_mgmt *mgmt, size_t len, const struct ieee80211_mgmt *mgmt, size_t len);
bool reject);
int handle_auth_pasn_3(struct pasn_data *pasn, const u8 *own_addr, int handle_auth_pasn_3(struct pasn_data *pasn, const u8 *own_addr,
const u8 *peer_addr, const u8 *peer_addr,
const struct ieee80211_mgmt *mgmt, size_t len); const struct ieee80211_mgmt *mgmt, size_t len);
@ -208,7 +207,6 @@ void pasn_set_responder_pmksa(struct pasn_data *pasn,
int pasn_set_pt(struct pasn_data *pasn, struct sae_pt *pt); int pasn_set_pt(struct pasn_data *pasn, struct sae_pt *pt);
/* Responder */ /* Responder */
void pasn_set_noauth(struct pasn_data *pasn, bool noauth);
void pasn_set_password(struct pasn_data *pasn, const char *password); void pasn_set_password(struct pasn_data *pasn, const char *password);
void pasn_set_wpa_key_mgmt(struct pasn_data *pasn, int key_mgmt); void pasn_set_wpa_key_mgmt(struct pasn_data *pasn, int key_mgmt);
void pasn_set_rsn_pairwise(struct pasn_data *pasn, int rsn_pairwise); void pasn_set_rsn_pairwise(struct pasn_data *pasn, int rsn_pairwise);

View file

@ -597,8 +597,7 @@ fail:
int handle_auth_pasn_1(struct pasn_data *pasn, int handle_auth_pasn_1(struct pasn_data *pasn,
const u8 *own_addr, const u8 *peer_addr, const u8 *own_addr, const u8 *peer_addr,
const struct ieee80211_mgmt *mgmt, size_t len, const struct ieee80211_mgmt *mgmt, size_t len)
bool reject)
{ {
struct ieee802_11_elems elems; struct ieee802_11_elems elems;
struct wpa_ie_data rsn_data; struct wpa_ie_data rsn_data;
@ -617,12 +616,6 @@ int handle_auth_pasn_1(struct pasn_data *pasn,
if (!groups) if (!groups)
groups = default_groups; groups = default_groups;
if (reject) {
wpa_printf(MSG_DEBUG, "PASN: Received Rejection");
status = WLAN_STATUS_UNSPECIFIED_FAILURE;
goto send_resp;
}
if (ieee802_11_parse_elems(mgmt->u.auth.variable, if (ieee802_11_parse_elems(mgmt->u.auth.variable,
len - offsetof(struct ieee80211_mgmt, len - offsetof(struct ieee80211_mgmt,
u.auth.variable), u.auth.variable),

View file

@ -531,7 +531,7 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
size_t mic_len, hdrlen, rlen, extra_len = 0; size_t mic_len, hdrlen, rlen, extra_len = 0;
struct wpa_eapol_key *reply; struct wpa_eapol_key *reply;
u8 *rbuf, *key_mic; u8 *rbuf, *key_mic;
u8 *rsn_ie_buf = NULL, *buf2 = NULL; u8 *rsn_ie_buf = NULL;
u16 key_info; u16 key_info;
#ifdef CONFIG_TESTING_OPTIONS #ifdef CONFIG_TESTING_OPTIONS
size_t pad_len = 0; size_t pad_len = 0;
@ -581,37 +581,6 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
} }
#endif /* CONFIG_IEEE80211R */ #endif /* CONFIG_IEEE80211R */
if (sm->rsn_override != RSN_OVERRIDE_NOT_USED) {
u8 *pos;
buf2 = os_malloc(wpa_ie_len + 2 + 4 + 1);
if (!buf2) {
os_free(rsn_ie_buf);
return -1;
}
os_memcpy(buf2, wpa_ie, wpa_ie_len);
pos = buf2 + wpa_ie_len;
*pos++ = WLAN_EID_VENDOR_SPECIFIC;
*pos++ = 4 + 1;
WPA_PUT_BE32(pos, RSN_SELECTION_IE_VENDOR_TYPE);
pos += 4;
if (sm->rsn_override == RSN_OVERRIDE_RSNE) {
*pos++ = RSN_SELECTION_RSNE;
} else if (sm->rsn_override == RSN_OVERRIDE_RSNE_OVERRIDE) {
*pos++ = RSN_SELECTION_RSNE_OVERRIDE;
} else if (sm->rsn_override == RSN_OVERRIDE_RSNE_OVERRIDE_2) {
*pos++ = RSN_SELECTION_RSNE_OVERRIDE_2;
} else {
os_free(rsn_ie_buf);
os_free(buf2);
return -1;
}
wpa_ie = buf2;
wpa_ie_len += 2 + 4 + 1;
}
wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len); wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len);
#ifdef CONFIG_TESTING_OPTIONS #ifdef CONFIG_TESTING_OPTIONS
@ -632,7 +601,6 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
&rlen, (void *) &reply); &rlen, (void *) &reply);
if (rbuf == NULL) { if (rbuf == NULL) {
os_free(rsn_ie_buf); os_free(rsn_ie_buf);
os_free(buf2);
return -1; return -1;
} }
@ -665,7 +633,6 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
WPA_PUT_BE16(key_mic + mic_len, wpa_ie_len + extra_len); WPA_PUT_BE16(key_mic + mic_len, wpa_ie_len + extra_len);
os_memcpy(key_mic + mic_len + 2, wpa_ie, wpa_ie_len); /* Key Data */ os_memcpy(key_mic + mic_len + 2, wpa_ie, wpa_ie_len); /* Key Data */
os_free(rsn_ie_buf); os_free(rsn_ie_buf);
os_free(buf2);
#ifdef CONFIG_TESTING_OPTIONS #ifdef CONFIG_TESTING_OPTIONS
if (sm->test_eapol_m2_elems) { if (sm->test_eapol_m2_elems) {
os_memcpy(key_mic + mic_len + 2 + wpa_ie_len, os_memcpy(key_mic + mic_len + 2 + wpa_ie_len,
@ -1023,8 +990,6 @@ static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
"WPA: Failed to get random data for SNonce"); "WPA: Failed to get random data for SNonce");
goto failed; goto failed;
} }
if (wpa_sm_rsn_overriding_supported(sm))
rsn_set_snonce_cookie(sm->snonce);
sm->renew_snonce = 0; sm->renew_snonce = 0;
wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce", wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce",
sm->snonce, WPA_NONCE_LEN); sm->snonce, WPA_NONCE_LEN);
@ -2228,68 +2193,6 @@ static int wpa_supplicant_validate_ie(struct wpa_sm *sm,
return -1; return -1;
} }
if (sm->proto == WPA_PROTO_RSN && wpa_sm_rsn_overriding_supported(sm)) {
if ((sm->ap_rsne_override && !ie->rsne_override) ||
(!sm->ap_rsne_override && ie->rsne_override) ||
(sm->ap_rsne_override && ie->rsne_override &&
(sm->ap_rsne_override_len != ie->rsne_override_len ||
os_memcmp(sm->ap_rsne_override, ie->rsne_override,
sm->ap_rsne_override_len) != 0))) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"RSN: RSNE Override element mismatch between Beacon/ProbeResp and EAPOL-Key msg 3/4");
wpa_hexdump(MSG_INFO,
"RSNE Override element in Beacon/ProbeResp",
sm->ap_rsne_override,
sm->ap_rsne_override_len);
wpa_hexdump(MSG_INFO,
"RSNE Override element in EAPOL-Key msg 3/4",
ie->rsne_override, ie->rsne_override_len);
wpa_sm_deauthenticate(sm,
WLAN_REASON_IE_IN_4WAY_DIFFERS);
return -1;
}
if ((sm->ap_rsne_override_2 && !ie->rsne_override_2) ||
(!sm->ap_rsne_override_2 && ie->rsne_override_2) ||
(sm->ap_rsne_override_2 && ie->rsne_override_2 &&
(sm->ap_rsne_override_2_len != ie->rsne_override_2_len ||
os_memcmp(sm->ap_rsne_override_2, ie->rsne_override_2,
sm->ap_rsne_override_2_len) != 0))) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"RSN: RSNE Override 2 element mismatch between Beacon/ProbeResp and EAPOL-Key msg 3/4");
wpa_hexdump(MSG_INFO,
"RSNE Override 2 element in Beacon/ProbeResp",
sm->ap_rsne_override_2,
sm->ap_rsne_override_2_len);
wpa_hexdump(MSG_INFO,
"RSNE Override 2 element in EAPOL-Key msg 3/4",
ie->rsne_override_2, ie->rsne_override_2_len);
wpa_sm_deauthenticate(sm,
WLAN_REASON_IE_IN_4WAY_DIFFERS);
return -1;
}
if ((sm->ap_rsnxe_override && !ie->rsnxe_override) ||
(!sm->ap_rsnxe_override && ie->rsnxe_override) ||
(sm->ap_rsnxe_override && ie->rsnxe_override &&
(sm->ap_rsnxe_override_len != ie->rsnxe_override_len ||
os_memcmp(sm->ap_rsnxe_override, ie->rsnxe_override,
sm->ap_rsnxe_override_len) != 0))) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"RSN: RSNXE Override element mismatch between Beacon/ProbeResp and EAPOL-Key msg 3/4");
wpa_hexdump(MSG_INFO,
"RSNXE Override element in Beacon/ProbeResp",
sm->ap_rsnxe_override,
sm->ap_rsnxe_override_len);
wpa_hexdump(MSG_INFO,
"RSNXE Override element in EAPOL-Key msg 3/4",
ie->rsnxe_override, ie->rsnxe_override_len);
wpa_sm_deauthenticate(sm,
WLAN_REASON_IE_IN_4WAY_DIFFERS);
return -1;
}
}
#ifdef CONFIG_IEEE80211R #ifdef CONFIG_IEEE80211R
if (wpa_key_mgmt_ft(sm->key_mgmt) && if (wpa_key_mgmt_ft(sm->key_mgmt) &&
wpa_supplicant_validate_ie_ft(sm, src_addr, ie) < 0) wpa_supplicant_validate_ie_ft(sm, src_addr, ie) < 0)
@ -2436,14 +2339,10 @@ int wpa_supplicant_send_4_of_4(struct wpa_sm *sm, const unsigned char *dst,
static int wpa_supplicant_validate_link_kde(struct wpa_sm *sm, u8 link_id, static int wpa_supplicant_validate_link_kde(struct wpa_sm *sm, u8 link_id,
const u8 *link_kde, const u8 *link_kde,
size_t link_kde_len, size_t link_kde_len)
const u8 *rsn_override_link_kde,
size_t rsn_override_link_kde_len)
{ {
size_t rsne_len = 0, rsnxe_len = 0, rsnoe_len = 0, rsno2e_len = 0, size_t rsne_len = 0, rsnxe_len = 0;
rsnxoe_len = 0; const u8 *rsne = NULL, *rsnxe = NULL;
const u8 *rsne = NULL, *rsnxe = NULL, *rsnoe = NULL, *rsno2e = NULL,
*rsnxoe = NULL;
if (!link_kde || if (!link_kde ||
link_kde_len < RSN_MLO_LINK_KDE_LINK_MAC_INDEX + ETH_ALEN) { link_kde_len < RSN_MLO_LINK_KDE_LINK_MAC_INDEX + ETH_ALEN) {
@ -2504,14 +2403,14 @@ static int wpa_supplicant_validate_link_kde(struct wpa_sm *sm, u8 link_id,
sm->mlo.links[link_id].ap_rsne_len, sm->mlo.links[link_id].ap_rsne_len,
rsne, rsne_len)) { rsne, rsne_len)) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO, wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"RSN MLO: RSNE in 3/4 msg does not match with IE in Beacon/ProbeResp for link ID %u", "RSN MLO: IE in 3/4 msg does not match with IE in Beacon/ProbeResp for link ID %u",
link_id); link_id);
wpa_hexdump(MSG_INFO, "RSNE in Beacon/ProbeResp", wpa_hexdump(MSG_INFO, "RSNE in Beacon/ProbeResp",
sm->mlo.links[link_id].ap_rsne, sm->mlo.links[link_id].ap_rsne,
sm->mlo.links[link_id].ap_rsne_len); sm->mlo.links[link_id].ap_rsne_len);
wpa_hexdump(MSG_INFO, "RSNE in EAPOL-Key msg 3/4", wpa_hexdump(MSG_INFO, "RSNE in EAPOL-Key msg 3/4",
rsne, rsne_len); rsne, rsne_len);
goto fail; return -1;
} }
if ((sm->mlo.links[link_id].ap_rsnxe && !rsnxe) || if ((sm->mlo.links[link_id].ap_rsnxe && !rsnxe) ||
@ -2528,91 +2427,13 @@ static int wpa_supplicant_validate_link_kde(struct wpa_sm *sm, u8 link_id,
sm->mlo.links[link_id].ap_rsnxe_len); sm->mlo.links[link_id].ap_rsnxe_len);
wpa_hexdump(MSG_INFO, "RSNXE in EAPOL-Key msg 3/4", wpa_hexdump(MSG_INFO, "RSNXE in EAPOL-Key msg 3/4",
rsnxe, rsnxe_len); rsnxe, rsnxe_len);
goto fail;
}
if (!wpa_sm_rsn_overriding_supported(sm))
return 0;
if (rsn_override_link_kde) {
rsnoe = get_vendor_ie(rsn_override_link_kde + 1,
rsn_override_link_kde_len - 1,
RSNE_OVERRIDE_IE_VENDOR_TYPE);
if (rsnoe)
rsnoe_len = 2 + rsnoe[1];
rsno2e = get_vendor_ie(rsn_override_link_kde + 1,
rsn_override_link_kde_len - 1,
RSNE_OVERRIDE_2_IE_VENDOR_TYPE);
if (rsno2e)
rsno2e_len = 2 + rsno2e[1];
rsnxoe = get_vendor_ie(rsn_override_link_kde + 1,
rsn_override_link_kde_len - 1,
RSNXE_OVERRIDE_IE_VENDOR_TYPE);
if (rsnxoe)
rsnxoe_len = 2 + rsnxoe[1];
}
if ((sm->mlo.links[link_id].ap_rsnoe && !rsnoe) ||
(!sm->mlo.links[link_id].ap_rsnoe && rsnoe) ||
(sm->mlo.links[link_id].ap_rsnoe && rsnoe &&
wpa_compare_rsn_ie(wpa_key_mgmt_ft(sm->key_mgmt),
sm->mlo.links[link_id].ap_rsnoe,
sm->mlo.links[link_id].ap_rsnoe_len,
rsnoe, rsnoe_len))) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"RSN MLO: RSNOE in 3/4 msg does not match with IE in Beacon/ProbeResp for link ID %u",
link_id);
wpa_hexdump(MSG_INFO, "RSNOE in Beacon/ProbeResp",
sm->mlo.links[link_id].ap_rsnoe,
sm->mlo.links[link_id].ap_rsnoe_len);
wpa_hexdump(MSG_INFO, "RSNOE in EAPOL-Key msg 3/4",
rsnoe, rsnoe_len);
goto fail;
}
if ((sm->mlo.links[link_id].ap_rsno2e && !rsno2e) ||
(!sm->mlo.links[link_id].ap_rsno2e && rsno2e) ||
(sm->mlo.links[link_id].ap_rsno2e && rsno2e &&
wpa_compare_rsn_ie(wpa_key_mgmt_ft(sm->key_mgmt),
sm->mlo.links[link_id].ap_rsno2e,
sm->mlo.links[link_id].ap_rsno2e_len,
rsno2e, rsno2e_len))) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"RSN MLO: RSNO2E in 3/4 msg does not match with IE in Beacon/ProbeResp for link ID %u",
link_id);
wpa_hexdump(MSG_INFO, "RSNO2E in Beacon/ProbeResp",
sm->mlo.links[link_id].ap_rsno2e,
sm->mlo.links[link_id].ap_rsno2e_len);
wpa_hexdump(MSG_INFO, "RSNOE in EAPOL-Key msg 3/4",
rsno2e, rsno2e_len);
goto fail;
}
if ((sm->mlo.links[link_id].ap_rsnxoe && !rsnxoe) ||
(!sm->mlo.links[link_id].ap_rsnxoe && rsnxoe) ||
(sm->mlo.links[link_id].ap_rsnxoe && rsnxoe &&
(sm->mlo.links[link_id].ap_rsnxoe_len != rsnxoe_len ||
os_memcmp(sm->mlo.links[link_id].ap_rsnxoe, rsnxoe,
sm->mlo.links[link_id].ap_rsnxoe_len) != 0))) {
wpa_msg(sm->ctx->msg_ctx, MSG_INFO,
"RSN MLO: RSNXOE mismatch between Beacon/ProbeResp and EAPOL-Key msg 3/4 for link ID %u",
link_id);
wpa_hexdump(MSG_INFO, "RSNXOE in Beacon/ProbeResp",
sm->mlo.links[link_id].ap_rsnxoe,
sm->mlo.links[link_id].ap_rsnxoe_len);
wpa_hexdump(MSG_INFO, "RSNXOE in EAPOL-Key msg 3/4",
rsnxoe, rsnxoe_len);
goto fail;
}
return 0;
fail:
wpa_sm_deauthenticate(sm, WLAN_REASON_IE_IN_4WAY_DIFFERS); wpa_sm_deauthenticate(sm, WLAN_REASON_IE_IN_4WAY_DIFFERS);
return -1; return -1;
} }
return 0;
}
static int wpa_validate_mlo_ieee80211w_kdes(struct wpa_sm *sm, static int wpa_validate_mlo_ieee80211w_kdes(struct wpa_sm *sm,
u8 link_id, u8 link_id,
@ -2778,10 +2599,8 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
if (!(sm->mlo.req_links & BIT(i))) if (!(sm->mlo.req_links & BIT(i)))
continue; continue;
if (wpa_supplicant_validate_link_kde( if (wpa_supplicant_validate_link_kde(sm, i, ie.mlo_link[i],
sm, i, ie.mlo_link[i], ie.mlo_link_len[i], ie.mlo_link_len[i]) < 0)
ie.rsn_override_link[i],
ie.rsn_override_link_len[i]) < 0)
goto failed; goto failed;
if (!(sm->mlo.valid_links & BIT(i))) if (!(sm->mlo.valid_links & BIT(i)))
@ -4354,15 +4173,9 @@ void wpa_sm_deinit(struct wpa_sm *sm)
os_free(sm->ap_wpa_ie); os_free(sm->ap_wpa_ie);
os_free(sm->ap_rsn_ie); os_free(sm->ap_rsn_ie);
os_free(sm->ap_rsnxe); os_free(sm->ap_rsnxe);
os_free(sm->ap_rsne_override);
os_free(sm->ap_rsne_override_2);
os_free(sm->ap_rsnxe_override);
for (i = 0; i < MAX_NUM_MLD_LINKS; i++) { for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
os_free(sm->mlo.links[i].ap_rsne); os_free(sm->mlo.links[i].ap_rsne);
os_free(sm->mlo.links[i].ap_rsnxe); os_free(sm->mlo.links[i].ap_rsnxe);
os_free(sm->mlo.links[i].ap_rsnoe);
os_free(sm->mlo.links[i].ap_rsno2e);
os_free(sm->mlo.links[i].ap_rsnxoe);
} }
wpa_sm_drop_sa(sm); wpa_sm_drop_sa(sm);
os_free(sm->ctx); os_free(sm->ctx);
@ -4765,69 +4578,6 @@ int wpa_sm_set_mlo_params(struct wpa_sm *sm, const struct wpa_sm_mlo *mlo)
} }
sm->mlo.links[i].ap_rsnxe_len = len; sm->mlo.links[i].ap_rsnxe_len = len;
} }
ie = mlo->links[i].ap_rsnoe;
len = mlo->links[i].ap_rsnoe_len;
os_free(sm->mlo.links[i].ap_rsnoe);
if (!ie || len == 0) {
if (sm->mlo.links[i].ap_rsnoe)
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
"RSN: Clearing MLO link[%u] AP RSNOE",
i);
sm->mlo.links[i].ap_rsnoe = NULL;
sm->mlo.links[i].ap_rsnoe_len = 0;
} else {
wpa_hexdump_link(MSG_DEBUG, i, "RSN: Set AP RSNOE",
ie, len);
sm->mlo.links[i].ap_rsnoe = os_memdup(ie, len);
if (!sm->mlo.links[i].ap_rsnoe) {
sm->mlo.links[i].ap_rsnoe_len = 0;
return -1;
}
sm->mlo.links[i].ap_rsnoe_len = len;
}
ie = mlo->links[i].ap_rsno2e;
len = mlo->links[i].ap_rsno2e_len;
os_free(sm->mlo.links[i].ap_rsno2e);
if (!ie || len == 0) {
if (sm->mlo.links[i].ap_rsno2e)
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
"RSN: Clearing MLO link[%u] AP RSNO2E",
i);
sm->mlo.links[i].ap_rsno2e = NULL;
sm->mlo.links[i].ap_rsno2e_len = 0;
} else {
wpa_hexdump_link(MSG_DEBUG, i, "RSN: Set AP RSNO2E",
ie, len);
sm->mlo.links[i].ap_rsno2e = os_memdup(ie, len);
if (!sm->mlo.links[i].ap_rsno2e) {
sm->mlo.links[i].ap_rsno2e_len = 0;
return -1;
}
sm->mlo.links[i].ap_rsno2e_len = len;
}
ie = mlo->links[i].ap_rsnxoe;
len = mlo->links[i].ap_rsnxoe_len;
os_free(sm->mlo.links[i].ap_rsnxoe);
if (!ie || len == 0) {
if (sm->mlo.links[i].ap_rsnxoe)
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
"RSN: Clearing MLO link[%u] AP RSNXOE",
i);
sm->mlo.links[i].ap_rsnxoe = NULL;
sm->mlo.links[i].ap_rsnxoe_len = 0;
} else {
wpa_hexdump_link(MSG_DEBUG, i, "RSN: Set AP RSNXOE",
ie, len);
sm->mlo.links[i].ap_rsnxoe = os_memdup(ie, len);
if (!sm->mlo.links[i].ap_rsnxoe) {
sm->mlo.links[i].ap_rsnxoe_len = 0;
return -1;
}
sm->mlo.links[i].ap_rsnxoe_len = len;
}
} }
return 0; return 0;
@ -4987,12 +4737,6 @@ int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
case WPA_PARAM_SSID_PROTECTION: case WPA_PARAM_SSID_PROTECTION:
sm->ssid_protection = value; sm->ssid_protection = value;
break; break;
case WPA_PARAM_RSN_OVERRIDE:
sm->rsn_override = value;
break;
case WPA_PARAM_RSN_OVERRIDE_SUPPORT:
sm->rsn_override_support = value;
break;
default: default:
break; break;
} }
@ -5001,23 +4745,6 @@ int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
} }
static const u8 * wpa_sm_get_ap_rsne(struct wpa_sm *sm, size_t *len)
{
if (sm->rsn_override == RSN_OVERRIDE_RSNE_OVERRIDE) {
*len = sm->ap_rsne_override_len;
return sm->ap_rsne_override;
}
if (sm->rsn_override == RSN_OVERRIDE_RSNE_OVERRIDE_2) {
*len = sm->ap_rsne_override_2_len;
return sm->ap_rsne_override_2;
}
*len = sm->ap_rsn_ie_len;
return sm->ap_rsn_ie;
}
/** /**
* wpa_sm_get_status - Get WPA state machine * wpa_sm_get_status - Get WPA state machine
* @sm: Pointer to WPA state machine data from wpa_sm_init() * @sm: Pointer to WPA state machine data from wpa_sm_init()
@ -5035,10 +4762,6 @@ int wpa_sm_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
{ {
char *pos = buf, *end = buf + buflen; char *pos = buf, *end = buf + buflen;
int ret; int ret;
const u8 *rsne;
size_t rsne_len;
rsne = wpa_sm_get_ap_rsne(sm, &rsne_len);
ret = os_snprintf(pos, end - pos, ret = os_snprintf(pos, end - pos,
"pairwise_cipher=%s\n" "pairwise_cipher=%s\n"
@ -5060,10 +4783,10 @@ int wpa_sm_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
} }
#endif /* CONFIG_DPP2 */ #endif /* CONFIG_DPP2 */
if (sm->mfp != NO_MGMT_FRAME_PROTECTION && rsne) { if (sm->mfp != NO_MGMT_FRAME_PROTECTION && sm->ap_rsn_ie) {
struct wpa_ie_data rsn; struct wpa_ie_data rsn;
if (wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &rsn)
if (wpa_parse_wpa_ie_rsn(rsne, rsne_len, &rsn) >= 0 && >= 0 &&
rsn.capabilities & (WPA_CAPABILITY_MFPR | rsn.capabilities & (WPA_CAPABILITY_MFPR |
WPA_CAPABILITY_MFPC)) { WPA_CAPABILITY_MFPC)) {
ret = os_snprintf(pos, end - pos, "pmf=%d\n" ret = os_snprintf(pos, end - pos, "pmf=%d\n"
@ -5085,15 +4808,11 @@ int wpa_sm_get_status(struct wpa_sm *sm, char *buf, size_t buflen,
int wpa_sm_pmf_enabled(struct wpa_sm *sm) int wpa_sm_pmf_enabled(struct wpa_sm *sm)
{ {
struct wpa_ie_data rsn; struct wpa_ie_data rsn;
const u8 *rsne;
size_t rsne_len;
rsne = wpa_sm_get_ap_rsne(sm, &rsne_len); if (sm->mfp == NO_MGMT_FRAME_PROTECTION || !sm->ap_rsn_ie)
if (sm->mfp == NO_MGMT_FRAME_PROTECTION || !rsne)
return 0; return 0;
if (wpa_parse_wpa_ie_rsn(rsne, rsne_len, &rsn) >= 0 && if (wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len, &rsn) >= 0 &&
rsn.capabilities & (WPA_CAPABILITY_MFPR | WPA_CAPABILITY_MFPC)) rsn.capabilities & (WPA_CAPABILITY_MFPR | WPA_CAPABILITY_MFPC))
return 1; return 1;
@ -5101,17 +4820,6 @@ int wpa_sm_pmf_enabled(struct wpa_sm *sm)
} }
bool wpa_sm_rsn_overriding_supported(struct wpa_sm *sm)
{
const u8 *rsne;
size_t rsne_len;
rsne = wpa_sm_get_ap_rsne(sm, &rsne_len);
return sm->rsn_override_support && rsne;
}
int wpa_sm_ext_key_id(struct wpa_sm *sm) int wpa_sm_ext_key_id(struct wpa_sm *sm)
{ {
return sm ? sm->ext_key_id : 0; return sm ? sm->ext_key_id : 0;
@ -5127,14 +4835,12 @@ int wpa_sm_ext_key_id_active(struct wpa_sm *sm)
int wpa_sm_ocv_enabled(struct wpa_sm *sm) int wpa_sm_ocv_enabled(struct wpa_sm *sm)
{ {
struct wpa_ie_data rsn; struct wpa_ie_data rsn;
const u8 *rsne;
size_t rsne_len;
rsne = wpa_sm_get_ap_rsne(sm, &rsne_len); if (!sm->ocv || !sm->ap_rsn_ie)
if (!sm->ocv || !rsne)
return 0; return 0;
return wpa_parse_wpa_ie_rsn(rsne, rsne_len, &rsn) >= 0 && return wpa_parse_wpa_ie_rsn(sm->ap_rsn_ie, sm->ap_rsn_ie_len,
&rsn) >= 0 &&
(rsn.capabilities & WPA_CAPABILITY_OCVC); (rsn.capabilities & WPA_CAPABILITY_OCVC);
} }
@ -5415,81 +5121,6 @@ int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len)
} }
int wpa_sm_set_ap_rsne_override(struct wpa_sm *sm, const u8 *ie, size_t len)
{
if (!sm)
return -1;
os_free(sm->ap_rsne_override);
if (!ie || len == 0) {
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
"RSN: Clearing AP RSNE Override element");
sm->ap_rsne_override = NULL;
sm->ap_rsne_override_len = 0;
} else {
wpa_hexdump(MSG_DEBUG, "RSN: Set AP RSNE Override element",
ie, len);
sm->ap_rsne_override = os_memdup(ie, len);
if (!sm->ap_rsne_override)
return -1;
sm->ap_rsne_override_len = len;
}
return 0;
}
int wpa_sm_set_ap_rsne_override_2(struct wpa_sm *sm, const u8 *ie, size_t len)
{
if (!sm)
return -1;
os_free(sm->ap_rsne_override_2);
if (!ie || len == 0) {
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
"RSN: Clearing AP RSNE Override 2 element");
sm->ap_rsne_override_2 = NULL;
sm->ap_rsne_override_2_len = 0;
} else {
wpa_hexdump(MSG_DEBUG, "RSN: Set AP RSNE Override 2 element",
ie, len);
sm->ap_rsne_override_2 = os_memdup(ie, len);
if (!sm->ap_rsne_override_2)
return -1;
sm->ap_rsne_override_2_len = len;
}
return 0;
}
int wpa_sm_set_ap_rsnxe_override(struct wpa_sm *sm, const u8 *ie, size_t len)
{
if (!sm)
return -1;
os_free(sm->ap_rsnxe_override);
if (!ie || len == 0) {
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
"RSN: Clearing AP RSNXE Override element");
sm->ap_rsnxe_override = NULL;
sm->ap_rsnxe_override_len = 0;
} else {
wpa_hexdump(MSG_DEBUG, "RSN: Set AP RSNXE Override element",
ie, len);
sm->ap_rsnxe_override = os_memdup(ie, len);
if (!sm->ap_rsnxe_override)
return -1;
sm->ap_rsnxe_override_len = len;
}
return 0;
}
/** /**
* wpa_sm_parse_own_wpa_ie - Parse own WPA/RSN IE * wpa_sm_parse_own_wpa_ie - Parse own WPA/RSN IE
* @sm: Pointer to WPA state machine data from wpa_sm_init() * @sm: Pointer to WPA state machine data from wpa_sm_init()

View file

@ -137,15 +137,6 @@ enum wpa_sm_conf_params {
WPA_PARAM_ENCRYPT_EAPOL_M4, WPA_PARAM_ENCRYPT_EAPOL_M4,
WPA_PARAM_FT_PREPEND_PMKID, WPA_PARAM_FT_PREPEND_PMKID,
WPA_PARAM_SSID_PROTECTION, WPA_PARAM_SSID_PROTECTION,
WPA_PARAM_RSN_OVERRIDE,
WPA_PARAM_RSN_OVERRIDE_SUPPORT,
};
enum wpa_rsn_override {
RSN_OVERRIDE_NOT_USED,
RSN_OVERRIDE_RSNE,
RSN_OVERRIDE_RSNE_OVERRIDE,
RSN_OVERRIDE_RSNE_OVERRIDE_2,
}; };
struct rsn_supp_config { struct rsn_supp_config {
@ -169,9 +160,8 @@ struct rsn_supp_config {
struct wpa_sm_link { struct wpa_sm_link {
u8 addr[ETH_ALEN]; u8 addr[ETH_ALEN];
u8 bssid[ETH_ALEN]; u8 bssid[ETH_ALEN];
u8 *ap_rsne, *ap_rsnxe, *ap_rsnoe, *ap_rsno2e, *ap_rsnxoe; u8 *ap_rsne, *ap_rsnxe;
size_t ap_rsne_len, ap_rsnxe_len, ap_rsnoe_len, ap_rsno2e_len, size_t ap_rsne_len, ap_rsnxe_len;
ap_rsnxoe_len;;
struct wpa_gtk gtk; struct wpa_gtk gtk;
struct wpa_gtk gtk_wnm_sleep; struct wpa_gtk gtk_wnm_sleep;
struct wpa_igtk igtk; struct wpa_igtk igtk;
@ -214,9 +204,6 @@ int wpa_sm_set_assoc_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len);
int wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len); int wpa_sm_set_ap_wpa_ie(struct wpa_sm *sm, const u8 *ie, size_t len);
int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len); int wpa_sm_set_ap_rsn_ie(struct wpa_sm *sm, const u8 *ie, size_t len);
int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len); int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, const u8 *ie, size_t len);
int wpa_sm_set_ap_rsne_override(struct wpa_sm *sm, const u8 *ie, size_t len);
int wpa_sm_set_ap_rsne_override_2(struct wpa_sm *sm, const u8 *ie, size_t len);
int wpa_sm_set_ap_rsnxe_override(struct wpa_sm *sm, const u8 *ie, size_t len);
int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen); int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen);
int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param, int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
@ -361,24 +348,6 @@ static inline int wpa_sm_set_ap_rsnxe(struct wpa_sm *sm, const u8 *ie,
return -1; return -1;
} }
static inline int wpa_sm_set_ap_rsne_override(struct wpa_sm *sm, const u8 *ie,
size_t len)
{
return -1;
}
static inline int wpa_sm_set_ap_rsne_override_2(struct wpa_sm *sm, const u8 *ie,
size_t len)
{
return -1;
}
static inline int wpa_sm_set_ap_rsnxe_override(struct wpa_sm *sm, const u8 *ie,
size_t len)
{
return -1;
}
static inline int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen) static inline int wpa_sm_get_mib(struct wpa_sm *sm, char *buf, size_t buflen)
{ {
return 0; return 0;

View file

@ -120,9 +120,6 @@ struct wpa_sm {
size_t assoc_rsnxe_len; size_t assoc_rsnxe_len;
u8 *ap_wpa_ie, *ap_rsn_ie, *ap_rsnxe; u8 *ap_wpa_ie, *ap_rsn_ie, *ap_rsnxe;
size_t ap_wpa_ie_len, ap_rsn_ie_len, ap_rsnxe_len; size_t ap_wpa_ie_len, ap_rsn_ie_len, ap_rsnxe_len;
u8 *ap_rsne_override, *ap_rsne_override_2, *ap_rsnxe_override;
size_t ap_rsne_override_len, ap_rsne_override_2_len,
ap_rsnxe_override_len;
#ifdef CONFIG_TDLS #ifdef CONFIG_TDLS
struct wpa_tdls_peer *tdls; struct wpa_tdls_peer *tdls;
@ -232,9 +229,6 @@ struct wpa_sm {
bool wmm_enabled; bool wmm_enabled;
bool driver_bss_selection; bool driver_bss_selection;
bool ft_prepend_pmkid; bool ft_prepend_pmkid;
bool rsn_override_support;
enum wpa_rsn_override rsn_override;
}; };
@ -548,6 +542,5 @@ int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr,
void wpa_tdls_assoc(struct wpa_sm *sm); void wpa_tdls_assoc(struct wpa_sm *sm);
void wpa_tdls_disassoc(struct wpa_sm *sm); void wpa_tdls_disassoc(struct wpa_sm *sm);
bool wpa_sm_rsn_overriding_supported(struct wpa_sm *sm);
#endif /* WPA_I_H */ #endif /* WPA_I_H */

View file

@ -33,14 +33,7 @@ int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len,
if (wpa_ie_len >= 6 && wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC && if (wpa_ie_len >= 6 && wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC &&
wpa_ie[1] >= 4 && WPA_GET_BE32(&wpa_ie[2]) == OSEN_IE_VENDOR_TYPE) wpa_ie[1] >= 4 && WPA_GET_BE32(&wpa_ie[2]) == OSEN_IE_VENDOR_TYPE)
return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data); return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data);
if (wpa_ie_len >= 6 && wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC && else
wpa_ie[1] >= 4 &&
WPA_GET_BE32(&wpa_ie[2]) == RSNE_OVERRIDE_IE_VENDOR_TYPE)
return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data);
if (wpa_ie_len >= 6 && wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC &&
wpa_ie[1] >= 4 &&
WPA_GET_BE32(&wpa_ie[2]) == RSNE_OVERRIDE_2_IE_VENDOR_TYPE)
return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data);
return wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, data); return wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, data);
} }

View file

@ -77,6 +77,9 @@ struct eloop_sock_table {
struct eloop_data { struct eloop_data {
int max_sock; int max_sock;
eloop_timeout_poll_handler timeout_poll_cb;
eloop_poll_handler poll_cb;
size_t count; /* sum of all table counts */ size_t count; /* sum of all table counts */
#ifdef CONFIG_ELOOP_POLL #ifdef CONFIG_ELOOP_POLL
size_t max_pollfd_map; /* number of pollfds_map currently allocated */ size_t max_pollfd_map; /* number of pollfds_map currently allocated */
@ -1121,6 +1124,12 @@ void eloop_run(void)
os_reltime_sub(&timeout->time, &now, &tv); os_reltime_sub(&timeout->time, &now, &tv);
else else
tv.sec = tv.usec = 0; tv.sec = tv.usec = 0;
}
if (eloop.timeout_poll_cb && eloop.timeout_poll_cb(&tv, !!timeout))
timeout = (void *)1;
if (timeout) {
#if defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL) #if defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL)
timeout_ms = tv.sec * 1000 + tv.usec / 1000; timeout_ms = tv.sec * 1000 + tv.usec / 1000;
#endif /* defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL) */ #endif /* defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL) */
@ -1190,7 +1199,8 @@ void eloop_run(void)
eloop.exceptions.changed = 0; eloop.exceptions.changed = 0;
eloop_process_pending_signals(); eloop_process_pending_signals();
if (eloop.poll_cb)
eloop.poll_cb();
/* check if some registered timeouts have occurred */ /* check if some registered timeouts have occurred */
timeout = dl_list_first(&eloop.timeout, struct eloop_timeout, timeout = dl_list_first(&eloop.timeout, struct eloop_timeout,
@ -1252,6 +1262,14 @@ out:
return; return;
} }
int eloop_register_cb(eloop_poll_handler poll_cb,
eloop_timeout_poll_handler timeout_cb)
{
eloop.poll_cb = poll_cb;
eloop.timeout_poll_cb = timeout_cb;
return 0;
}
void eloop_terminate(void) void eloop_terminate(void)
{ {

View file

@ -65,6 +65,9 @@ typedef void (*eloop_timeout_handler)(void *eloop_ctx, void *user_ctx);
*/ */
typedef void (*eloop_signal_handler)(int sig, void *signal_ctx); typedef void (*eloop_signal_handler)(int sig, void *signal_ctx);
typedef bool (*eloop_timeout_poll_handler)(struct os_reltime *tv, bool tv_set);
typedef void (*eloop_poll_handler)(void);
/** /**
* eloop_init() - Initialize global event loop data * eloop_init() - Initialize global event loop data
* Returns: 0 on success, -1 on failure * Returns: 0 on success, -1 on failure
@ -73,6 +76,9 @@ typedef void (*eloop_signal_handler)(int sig, void *signal_ctx);
*/ */
int eloop_init(void); int eloop_init(void);
int eloop_register_cb(eloop_poll_handler poll_cb,
eloop_timeout_poll_handler timeout_cb);
/** /**
* eloop_register_read_sock - Register handler for read events * eloop_register_read_sock - Register handler for read events
* @sock: File descriptor number for the socket * @sock: File descriptor number for the socket
@ -320,6 +326,8 @@ int eloop_register_signal_reconfig(eloop_signal_handler handler,
*/ */
int eloop_sock_requeue(void); int eloop_sock_requeue(void);
void eloop_add_uloop(void);
/** /**
* eloop_run - Start the event loop * eloop_run - Start the event loop
* *

64
src/utils/uloop.c Normal file
View file

@ -0,0 +1,64 @@
#include <libubox/uloop.h>
#include "includes.h"
#include "common.h"
#include "eloop.h"
static void eloop_uloop_event_cb(int sock, void *eloop_ctx, void *sock_ctx)
{
}
static void eloop_uloop_fd_cb(struct uloop_fd *fd, unsigned int events)
{
unsigned int changed = events ^ fd->flags;
if (changed & ULOOP_READ) {
if (events & ULOOP_READ)
eloop_register_sock(fd->fd, EVENT_TYPE_READ, eloop_uloop_event_cb, fd, fd);
else
eloop_unregister_sock(fd->fd, EVENT_TYPE_READ);
}
if (changed & ULOOP_WRITE) {
if (events & ULOOP_WRITE)
eloop_register_sock(fd->fd, EVENT_TYPE_WRITE, eloop_uloop_event_cb, fd, fd);
else
eloop_unregister_sock(fd->fd, EVENT_TYPE_WRITE);
}
}
static bool uloop_timeout_poll_handler(struct os_reltime *tv, bool tv_set)
{
struct os_reltime tv_uloop;
int timeout_ms = uloop_get_next_timeout();
if (timeout_ms < 0)
return false;
tv_uloop.sec = timeout_ms / 1000;
tv_uloop.usec = (timeout_ms % 1000) * 1000;
if (!tv_set || os_reltime_before(&tv_uloop, tv)) {
*tv = tv_uloop;
return true;
}
return false;
}
static void uloop_poll_handler(void)
{
uloop_run_timeout(0);
}
void eloop_add_uloop(void)
{
static bool init_done = false;
if (!init_done) {
uloop_init();
uloop_fd_set_cb = eloop_uloop_fd_cb;
init_done = true;
}
eloop_register_cb(uloop_poll_handler, uloop_timeout_poll_handler);
}

View file

@ -15,7 +15,6 @@ import wpaspy
import remotehost import remotehost
import utils import utils
import subprocess import subprocess
from remotectrl import RemoteCtrl
logger = logging.getLogger() logger = logging.getLogger()
hapd_ctrl = '/var/run/hostapd' hapd_ctrl = '/var/run/hostapd'
@ -29,18 +28,12 @@ class HostapdGlobal:
try: try:
hostname = apdev['hostname'] hostname = apdev['hostname']
port = apdev['port'] port = apdev['port']
if 'remote_cli' in apdev:
remote_cli = apdev['remote_cli']
else:
remote_cli = False
except: except:
hostname = None hostname = None
port = 8878 port = 8878
remote_cli = False
self.host = remotehost.Host(hostname) self.host = remotehost.Host(hostname)
self.hostname = hostname self.hostname = hostname
self.port = port self.port = port
self.remote_cli = remote_cli
if hostname is None: if hostname is None:
global_ctrl = hapd_global global_ctrl = hapd_global
if global_ctrl_override: if global_ctrl_override:
@ -48,14 +41,6 @@ class HostapdGlobal:
self.ctrl = wpaspy.Ctrl(global_ctrl) self.ctrl = wpaspy.Ctrl(global_ctrl)
self.mon = wpaspy.Ctrl(global_ctrl) self.mon = wpaspy.Ctrl(global_ctrl)
self.dbg = "" self.dbg = ""
else:
if remote_cli:
global_ctrl = hapd_global
if global_ctrl_override:
global_ctrl = global_ctrl_override
self.ctrl = RemoteCtrl(global_ctrl, port, hostname=hostname)
self.mon = RemoteCtrl(global_ctrl, port, hostname=hostname)
self.dbg = hostname + "/global"
else: else:
self.ctrl = wpaspy.Ctrl(hostname, port) self.ctrl = wpaspy.Ctrl(hostname, port)
self.mon = wpaspy.Ctrl(hostname, port) self.mon = wpaspy.Ctrl(hostname, port)
@ -134,9 +119,6 @@ class HostapdGlobal:
if self.hostname is None: if self.hostname is None:
return None return None
if self.remote_cli:
return None
res = self.request("INTERFACES ctrl") res = self.request("INTERFACES ctrl")
lines = res.splitlines() lines = res.splitlines()
found = False found = False
@ -165,23 +147,14 @@ class HostapdGlobal:
class Hostapd: class Hostapd:
def __init__(self, ifname, bssidx=0, hostname=None, ctrl=hapd_ctrl, def __init__(self, ifname, bssidx=0, hostname=None, ctrl=hapd_ctrl,
port=8877, remote_cli=False, link=None): port=8877):
self.hostname = hostname self.hostname = hostname
self.host = remotehost.Host(hostname, ifname) self.host = remotehost.Host(hostname, ifname)
self.ifname = ifname self.ifname = ifname
self.remote_cli = remote_cli
if hostname is None: if hostname is None:
if link is not None:
ifname = ifname + "_link" + str(link)
self.ctrl = wpaspy.Ctrl(os.path.join(ctrl, ifname)) self.ctrl = wpaspy.Ctrl(os.path.join(ctrl, ifname))
self.mon = wpaspy.Ctrl(os.path.join(ctrl, ifname)) self.mon = wpaspy.Ctrl(os.path.join(ctrl, ifname))
self.dbg = ifname self.dbg = ifname
else:
if remote_cli:
self.ctrl = RemoteCtrl(ctrl, port, hostname=hostname,
ifname=ifname)
self.mon = RemoteCtrl(ctrl, port, hostname=hostname,
ifname=ifname)
else: else:
self.ctrl = wpaspy.Ctrl(hostname, port) self.ctrl = wpaspy.Ctrl(hostname, port)
self.mon = wpaspy.Ctrl(hostname, port) self.mon = wpaspy.Ctrl(hostname, port)
@ -665,31 +638,22 @@ def add_ap(apdev, params, wait_enabled=True, no_enable=False, timeout=30,
try: try:
hostname = apdev['hostname'] hostname = apdev['hostname']
port = apdev['port'] port = apdev['port']
if 'remote_cli' in apdev: logger.info("Starting AP " + hostname + "/" + port + " " + ifname)
remote_cli = apdev['remote_cli']
else:
remote_cli = False
if 'global_ctrl_override' in apdev:
global_ctrl_override = apdev['global_ctrl_override']
logger.info("Starting AP " + hostname + "/" + port + " " + ifname + " remote_cli " + str(remote_cli))
except: except:
logger.info("Starting AP " + ifname) logger.info("Starting AP " + ifname)
hostname = None hostname = None
port = 8878 port = 8878
remote_cli = False
else: else:
ifname = apdev ifname = apdev
logger.info("Starting AP " + ifname + " (old add_ap argument type)") logger.info("Starting AP " + ifname + " (old add_ap argument type)")
hostname = None hostname = None
port = 8878 port = 8878
remote_cli = False
hapd_global = HostapdGlobal(apdev, hapd_global = HostapdGlobal(apdev,
global_ctrl_override=global_ctrl_override) global_ctrl_override=global_ctrl_override)
hapd_global.remove(ifname) hapd_global.remove(ifname)
hapd_global.add(ifname, driver=driver) hapd_global.add(ifname, driver=driver)
port = hapd_global.get_ctrl_iface_port(ifname) port = hapd_global.get_ctrl_iface_port(ifname)
hapd = Hostapd(ifname, hostname=hostname, port=port, hapd = Hostapd(ifname, hostname=hostname, port=port)
remote_cli=remote_cli)
if not hapd.ping(): if not hapd.ping():
raise Exception("Could not ping hostapd") raise Exception("Could not ping hostapd")
hapd.set_defaults(set_channel=set_channel) hapd.set_defaults(set_channel=set_channel)
@ -724,22 +688,17 @@ def add_bss(apdev, ifname, confname, ignore_error=False):
try: try:
hostname = apdev['hostname'] hostname = apdev['hostname']
port = apdev['port'] port = apdev['port']
if 'remote_cli' in apdev: logger.info("Starting BSS " + hostname + "/" + port + " phy=" + phy + " ifname=" + ifname)
remote_cli = apdev['remote_cli']
else:
remote_cli = False
logger.info("Starting BSS " + hostname + "/" + port + " phy=" + phy + " ifname=" + ifname + " remote_cli=" + str(remote_cli))
except: except:
logger.info("Starting BSS phy=" + phy + " ifname=" + ifname) logger.info("Starting BSS phy=" + phy + " ifname=" + ifname)
hostname = None hostname = None
port = 8878 port = 8878
remote_cli = False
hapd_global = HostapdGlobal(apdev) hapd_global = HostapdGlobal(apdev)
confname = cfg_file(apdev, confname, ifname) confname = cfg_file(apdev, confname, ifname)
hapd_global.send_file(confname, confname) hapd_global.send_file(confname, confname)
hapd_global.add_bss(phy, confname, ignore_error) hapd_global.add_bss(phy, confname, ignore_error)
port = hapd_global.get_ctrl_iface_port(ifname) port = hapd_global.get_ctrl_iface_port(ifname)
hapd = Hostapd(ifname, hostname=hostname, port=port, remote_cli=remote_cli) hapd = Hostapd(ifname, hostname=hostname, port=port)
if not hapd.ping(): if not hapd.ping():
raise Exception("Could not ping hostapd") raise Exception("Could not ping hostapd")
return hapd return hapd
@ -749,27 +708,22 @@ def add_iface(apdev, confname):
try: try:
hostname = apdev['hostname'] hostname = apdev['hostname']
port = apdev['port'] port = apdev['port']
if 'remote_cli' in apdev: logger.info("Starting interface " + hostname + "/" + port + " " + ifname)
remote_cli = apdev['remote_cli']
else:
remote_cli = False
logger.info("Starting interface " + hostname + "/" + port + " " + ifname + "remote_cli=" + str(remote_cli))
except: except:
logger.info("Starting interface " + ifname) logger.info("Starting interface " + ifname)
hostname = None hostname = None
port = 8878 port = 8878
remote_cli = False
hapd_global = HostapdGlobal(apdev) hapd_global = HostapdGlobal(apdev)
confname = cfg_file(apdev, confname, ifname) confname = cfg_file(apdev, confname, ifname)
hapd_global.send_file(confname, confname) hapd_global.send_file(confname, confname)
hapd_global.add_iface(ifname, confname) hapd_global.add_iface(ifname, confname)
port = hapd_global.get_ctrl_iface_port(ifname) port = hapd_global.get_ctrl_iface_port(ifname)
hapd = Hostapd(ifname, hostname=hostname, port=port, remote_cli=remote_cli) hapd = Hostapd(ifname, hostname=hostname, port=port)
if not hapd.ping(): if not hapd.ping():
raise Exception("Could not ping hostapd") raise Exception("Could not ping hostapd")
return hapd return hapd
def add_mld_link(apdev, link_id, params): def add_mld_link(apdev, params):
if isinstance(apdev, dict): if isinstance(apdev, dict):
ifname = apdev['ifname'] ifname = apdev['ifname']
try: try:
@ -795,8 +749,7 @@ def add_mld_link(apdev, link_id, params):
if str(e) == "Could not add hostapd link": if str(e) == "Could not add hostapd link":
raise utils.HwsimSkip("No MLO support in hostapd") raise utils.HwsimSkip("No MLO support in hostapd")
port = hapd_global.get_ctrl_iface_port(ifname) port = hapd_global.get_ctrl_iface_port(ifname)
hapd = Hostapd(ifname, hostname=hostname, ctrl=ctrl_iface, port=port, hapd = Hostapd(ifname, hostname=hostname, ctrl=ctrl_iface, port=port)
link=link_id)
if not hapd.ping(): if not hapd.ping():
raise Exception("Could not ping hostapd") raise Exception("Could not ping hostapd")
return hapd return hapd
@ -1070,6 +1023,9 @@ def cfg_mld_link_file(ifname, params):
fd, fname = tempfile.mkstemp(dir='/tmp', prefix=conf + '-') fd, fname = tempfile.mkstemp(dir='/tmp', prefix=conf + '-')
f = os.fdopen(fd, 'w') f = os.fdopen(fd, 'w')
if idx != 0:
ctrl_iface="/var/run/hostapd_%d" % idx
f.write("ctrl_interface=%s\n" % ctrl_iface) f.write("ctrl_interface=%s\n" % ctrl_iface)
f.write("driver=nl80211\n") f.write("driver=nl80211\n")
f.write("ieee80211n=1\n") f.write("ieee80211n=1\n")

View file

@ -1,36 +0,0 @@
# Python class for controlling Multi Link Device
# Copyright (c) 2024, Jouni Malinen <j@w1.fi>
#
# This software may be distributed under the terms of the BSD license.
# See README for more details.
import os
import logging
import wpaspy
logger = logging.getLogger()
hapd_ctrl = '/var/run/hostapd'
class MultiLinkDevice:
def __init__(self, ifname, ctrl=hapd_ctrl, port=8877):
self.ifname = ifname
self.ctrl = wpaspy.Ctrl(os.path.join(ctrl, ifname))
self.dbg = ifname
def close_ctrl(self):
self.ctrl.close()
self.ctrl = None
def request(self, cmd):
logger.debug(self.dbg + ": MLD CTRL: " + cmd)
return self.ctrl.request(cmd)
def ping(self):
return "PONG" in self.request("PING")
def get_mld_obj(ifname, ctrl=hapd_ctrl, port=8877):
mld = MultiLinkDevice(ifname, ctrl, port)
if not mld.ping():
raise Exception("Could not ping MLD %s" % ifname)
return mld

View file

@ -1,92 +0,0 @@
#!/usr/bin/python
#
# wpa_supplicant/hostapd control interface using Python
# Copyright (c) 2024, Jouni Malinen <j@w1.fi>
#
# This software may be distributed under the terms of the BSD license.
# See README for more details.
from wpaspy import Ctrl
import remotehost
class RemoteCtrl(Ctrl):
def __init__(self, path, port=9877, hostname=None, ifname=None):
self.started = False
self.attached = False
self.path = path
self.port = port
self.ifname = ifname
self.hostname = hostname
self.proc = None
self.host = remotehost.Host(hostname)
self.started = True
def __del__(self):
self.close()
def close(self):
if self.attached:
try:
self.detach()
except Exception as e:
# Need to ignore this allow the socket to be closed
self.attached = False
pass
if self.host and self.started:
self.started = False
def request(self, cmd, timeout=10):
if self.host:
cmd = '\'' + cmd + '\''
if self.ifname:
_cmd = ['wpa_cli', '-p', self.path, '-i', self.ifname, "raw " + cmd]
else:
_cmd = ['wpa_cli', '-g', self.path, "raw " + cmd]
status, buf = self.host.execute(_cmd)
return buf
def attach(self):
if self.attached:
return
if self.host:
if self.ifname:
_cmd = [ "wpa_cli", "-p", self.path, "-i", self.ifname ]
else:
_cmd = [ "wpa_cli", '-g', self.path]
self.proc = self.host.proc_run(_cmd)
self.attached = True
def detach(self):
if not self.attached:
return
if self.hostname and self.proc:
self.request("DETACH")
self.request("QUIT")
self.host.proc_stop(self.proc)
self.attached = False
self.proc = None
def terminate(self):
if self.attached:
try:
self.detach()
except Exception as e:
# Need to ignore this to allow the socket to be closed
self.attached = False
self.request("TERMINATE")
self.close()
def pending(self, timeout=0):
if self.host and self.proc:
return self.host.proc_pending(self.proc, timeout=timeout)
return False
def recv(self):
if self.host and self.proc:
res = self.host.proc_read(self.proc)
return res
return ""

View file

@ -83,10 +83,7 @@ class Host():
if self.host is None: if self.host is None:
return self.local_execute(command) return self.local_execute(command)
if self.user:
cmd = ["ssh", self.user + "@" + self.host, ' '.join(command)] cmd = ["ssh", self.user + "@" + self.host, ' '.join(command)]
else:
cmd = ["ssh", self.host, ' '.join(command)]
_cmd = self.name + " execute: " + ' '.join(cmd) _cmd = self.name + " execute: " + ' '.join(cmd)
logger.debug(_cmd) logger.debug(_cmd)
err = tempfile.TemporaryFile() err = tempfile.TemporaryFile()
@ -117,10 +114,7 @@ class Host():
if self.host is None: if self.host is None:
cmd = _command cmd = _command
else: else:
if self.user:
cmd = ["ssh", self.user + "@" + self.host, ' '.join(_command)] cmd = ["ssh", self.user + "@" + self.host, ' '.join(_command)]
else:
cmd = ["ssh", self.host, ' '.join(_command)]
_cmd = self.name + " thread_run: " + ' '.join(cmd) _cmd = self.name + " thread_run: " + ' '.join(cmd)
logger.debug(_cmd) logger.debug(_cmd)
t = threading.Thread(target=execute_thread, name=filename, args=(cmd, res)) t = threading.Thread(target=execute_thread, name=filename, args=(cmd, res))
@ -180,10 +174,7 @@ class Host():
_command = [filename] + command _command = [filename] + command
if self.host: if self.host:
if self.user:
cmd = ["ssh", self.user + "@" + self.host, ' '.join(_command)] cmd = ["ssh", self.user + "@" + self.host, ' '.join(_command)]
else:
cmd = ["ssh", self.host, ' '.join(_command)]
else: else:
cmd = _command cmd = _command
@ -270,18 +261,12 @@ class Host():
def get_logs(self, local_log_dir=None): def get_logs(self, local_log_dir=None):
for log in self.logs: for log in self.logs:
if local_log_dir: if local_log_dir:
if self.user:
self.local_execute(["scp", self.user + "@[" + self.host + "]:" + log, local_log_dir]) self.local_execute(["scp", self.user + "@[" + self.host + "]:" + log, local_log_dir])
else:
self.local_execute(["scp", "[" + self.host + "]:" + log, local_log_dir])
self.execute(["rm", log]) self.execute(["rm", log])
del self.logs[:] del self.logs[:]
def send_file(self, src, dst): def send_file(self, src, dst):
if self.host is None: if self.host is None:
return return
if self.user:
self.local_execute(["scp", src, self.local_execute(["scp", src,
self.user + "@[" + self.host + "]:" + dst]) self.user + "@[" + self.host + "]:" + dst])
else:
self.local_execute(["scp", src, "[" + self.host + "]:" + dst])

View file

@ -374,12 +374,12 @@ def test_ap_ft_vlan(dev, apdev):
params = ft_params1(ssid=ssid, passphrase=passphrase) params = ft_params1(ssid=ssid, passphrase=passphrase)
params['dynamic_vlan'] = "1" params['dynamic_vlan'] = "1"
params['accept_mac_file'] = filename params['accept_mac_file'] = filename
hapd0 = hostapd.add_ap(apdev[0], params) hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
params = ft_params2(ssid=ssid, passphrase=passphrase) params = ft_params2(ssid=ssid, passphrase=passphrase)
params['dynamic_vlan'] = "1" params['dynamic_vlan'] = "1"
params['accept_mac_file'] = filename params['accept_mac_file'] = filename
hapd1 = hostapd.add_ap(apdev[1], params) hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, conndev="brvlan1") run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, conndev="brvlan1")
if "[WPA2-FT/PSK-CCMP]" not in dev[0].request("SCAN_RESULTS"): if "[WPA2-FT/PSK-CCMP]" not in dev[0].request("SCAN_RESULTS"):
@ -413,13 +413,13 @@ def test_ap_ft_vlan_disconnected(dev, apdev):
params['dynamic_vlan'] = "1" params['dynamic_vlan'] = "1"
params['accept_mac_file'] = filename params['accept_mac_file'] = filename
params['ft_psk_generate_local'] = "1" params['ft_psk_generate_local'] = "1"
hapd0 = hostapd.add_ap(apdev[0], params) hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
params = ft_params2a(ssid=ssid, passphrase=passphrase) params = ft_params2a(ssid=ssid, passphrase=passphrase)
params['dynamic_vlan'] = "1" params['dynamic_vlan'] = "1"
params['accept_mac_file'] = filename params['accept_mac_file'] = filename
params['ft_psk_generate_local'] = "1" params['ft_psk_generate_local'] = "1"
hapd1 = hostapd.add_ap(apdev[1], params) hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, conndev="brvlan1") run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, conndev="brvlan1")
if "[WPA2-FT/PSK-CCMP]" not in dev[0].request("SCAN_RESULTS"): if "[WPA2-FT/PSK-CCMP]" not in dev[0].request("SCAN_RESULTS"):
@ -437,11 +437,11 @@ def test_ap_ft_vlan_2(dev, apdev):
params = ft_params1(ssid=ssid, passphrase=passphrase) params = ft_params1(ssid=ssid, passphrase=passphrase)
params['dynamic_vlan'] = "1" params['dynamic_vlan'] = "1"
params['accept_mac_file'] = filename params['accept_mac_file'] = filename
hapd0 = hostapd.add_ap(apdev[0], params) hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
params = ft_params2(ssid=ssid, passphrase=passphrase) params = ft_params2(ssid=ssid, passphrase=passphrase)
params['dynamic_vlan'] = "1" params['dynamic_vlan'] = "1"
hapd1 = hostapd.add_ap(apdev[1], params) hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, conndev="brvlan1", run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, conndev="brvlan1",
force_initial_conn_to_first_ap=True) force_initial_conn_to_first_ap=True)
@ -520,12 +520,12 @@ def test_ap_ft_many_vlan(dev, apdev):
params = ft_params1(ssid=ssid, passphrase=passphrase) params = ft_params1(ssid=ssid, passphrase=passphrase)
params['dynamic_vlan'] = "1" params['dynamic_vlan'] = "1"
params['accept_mac_file'] = filename params['accept_mac_file'] = filename
hapd0 = hostapd.add_ap(apdev[0], params) hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
params = ft_params2(ssid=ssid, passphrase=passphrase) params = ft_params2(ssid=ssid, passphrase=passphrase)
params['dynamic_vlan'] = "1" params['dynamic_vlan'] = "1"
params['accept_mac_file'] = filename params['accept_mac_file'] = filename
hapd1 = hostapd.add_ap(apdev[1], params) hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, roams=50, run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, roams=50,
conndev="brvlan1") conndev="brvlan1")
@ -862,11 +862,11 @@ def test_ap_ft_vlan_over_ds(dev, apdev):
params = ft_params1(ssid=ssid, passphrase=passphrase) params = ft_params1(ssid=ssid, passphrase=passphrase)
params['dynamic_vlan'] = "1" params['dynamic_vlan'] = "1"
params['accept_mac_file'] = filename params['accept_mac_file'] = filename
hapd0 = hostapd.add_ap(apdev[0], params) hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
params = ft_params2(ssid=ssid, passphrase=passphrase) params = ft_params2(ssid=ssid, passphrase=passphrase)
params['dynamic_vlan'] = "1" params['dynamic_vlan'] = "1"
params['accept_mac_file'] = filename params['accept_mac_file'] = filename
hapd1 = hostapd.add_ap(apdev[1], params) hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
dev[0].flush_scan_cache() dev[0].flush_scan_cache()
run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True, run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
@ -900,11 +900,11 @@ def test_ap_ft_vlan_over_ds_many(dev, apdev):
params = ft_params1(ssid=ssid, passphrase=passphrase) params = ft_params1(ssid=ssid, passphrase=passphrase)
params['dynamic_vlan'] = "1" params['dynamic_vlan'] = "1"
params['accept_mac_file'] = filename params['accept_mac_file'] = filename
hapd0 = hostapd.add_ap(apdev[0], params) hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
params = ft_params2(ssid=ssid, passphrase=passphrase) params = ft_params2(ssid=ssid, passphrase=passphrase)
params['dynamic_vlan'] = "1" params['dynamic_vlan'] = "1"
params['accept_mac_file'] = filename params['accept_mac_file'] = filename
hapd1 = hostapd.add_ap(apdev[1], params) hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
dev[0].flush_scan_cache() dev[0].flush_scan_cache()
run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True, run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,
@ -1115,12 +1115,12 @@ def test_ap_ft_over_ds_pull_vlan(dev, apdev):
params["pmk_r1_push"] = "0" params["pmk_r1_push"] = "0"
params['dynamic_vlan'] = "1" params['dynamic_vlan'] = "1"
params['accept_mac_file'] = filename params['accept_mac_file'] = filename
hapd0 = hostapd.add_ap(apdev[0], params) hapd0 = hostapd.add_ap(apdev[0]['ifname'], params)
params = ft_params2(ssid=ssid, passphrase=passphrase) params = ft_params2(ssid=ssid, passphrase=passphrase)
params["pmk_r1_push"] = "0" params["pmk_r1_push"] = "0"
params['dynamic_vlan'] = "1" params['dynamic_vlan'] = "1"
params['accept_mac_file'] = filename params['accept_mac_file'] = filename
hapd1 = hostapd.add_ap(apdev[1], params) hapd1 = hostapd.add_ap(apdev[1]['ifname'], params)
dev[0].flush_scan_cache() dev[0].flush_scan_cache()
run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True, run_roams(dev[0], apdev, hapd0, hapd1, ssid, passphrase, over_ds=True,

View file

@ -131,7 +131,7 @@ def test_ap_open_assoc_timeout(dev, apdev):
def test_ap_open_auth_drop_sta(dev, apdev): def test_ap_open_auth_drop_sta(dev, apdev):
"""AP dropping station after successful authentication""" """AP dropping station after successful authentication"""
hapd = hostapd.add_ap(apdev[0], {"ssid": "open"}) hapd = hostapd.add_ap(apdev[0]['ifname'], {"ssid": "open"})
dev[0].scan(freq="2412") dev[0].scan(freq="2412")
hapd.set("ext_mgmt_frame_handling", "1") hapd.set("ext_mgmt_frame_handling", "1")
dev[0].connect("open", key_mgmt="NONE", scan_freq="2412", dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",

View file

@ -3759,21 +3759,6 @@ def test_rsn_eapol_m3_extra(dev, apdev):
dev[0].connect(ssid, psk=passphrase, scan_freq="2412") dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
def test_rsn_eapol_m3_extra_long(dev, apdev):
"""Long extra KDE in EAPOL-Key msg 3/4"""
ssid = "test-rsn"
passphrase = 'qwertyuiop'
params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
# Add a reserved KDEs into EAPOL-Key msg 3/4
val = 'dd0507c0d19311'
val += 'ddff69b847070102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafb'
val += 'dd085ba59d7911223344'
val += 'dd0a000face4112233445566'
params['eapol_m3_elements'] = val
hapd = hostapd.add_ap(apdev[0], params)
dev[0].connect(ssid, psk=passphrase, scan_freq="2412")
def test_rsn_eapol_m3_no_encrypt(dev, apdev): def test_rsn_eapol_m3_no_encrypt(dev, apdev):
"""EAPOL-Key msg 3/4 Key Data field not encrypted""" """EAPOL-Key msg 3/4 Key Data field not encrypted"""
ssid = "test-rsn" ssid = "test-rsn"

View file

@ -800,21 +800,17 @@ def test_ap_vlan_psk(dev, apdev, params):
if vlan_id != i + 1: if vlan_id != i + 1:
raise Exception("Unexpected vlan_id %d for dev[%d]" % (vlan_id, i)) raise Exception("Unexpected vlan_id %d for dev[%d]" % (vlan_id, i))
def start_ap_vlan_sae(apdev): def test_ap_vlan_sae(dev, apdev, params):
"""AP VLAN based on SAE Password Identifier"""
for i in range(3):
check_sae_capab(dev[i])
params = hostapd.wpa2_params(ssid="test-sae-vlan") params = hostapd.wpa2_params(ssid="test-sae-vlan")
params['wpa_key_mgmt'] = 'SAE' params['wpa_key_mgmt'] = 'SAE'
params['sae_password'] = ['pw1|vlanid=1|id=id1', params['sae_password'] = ['pw1|vlanid=1|id=id1',
'pw2|mac=ff:ff:ff:ff:ff:ff|vlanid=2|id=id2', 'pw2|mac=ff:ff:ff:ff:ff:ff|vlanid=2|id=id2',
'pw3|vlanid=3|id=id3'] 'pw3|vlanid=3|id=id3']
params['dynamic_vlan'] = "1" params['dynamic_vlan'] = "1"
params['wpa_group_rekey'] = '10' hapd = hostapd.add_ap(apdev[0], params)
return hostapd.add_ap(apdev, params)
def test_ap_vlan_sae(dev, apdev, params):
"""AP VLAN based on SAE Password Identifier"""
for i in range(3):
check_sae_capab(dev[i])
hapd = start_ap_vlan_sae(apdev[0])
for i in range(3): for i in range(3):
dev[i].request("SET sae_groups ") dev[i].request("SET sae_groups ")
@ -834,42 +830,3 @@ def test_ap_vlan_sae(dev, apdev, params):
vlan_id = int(sta["vlan_id"]) vlan_id = int(sta["vlan_id"])
if vlan_id != i + 1: if vlan_id != i + 1:
raise Exception("Unexpected vlan_id %d for dev[%d]" % (vlan_id, i)) raise Exception("Unexpected vlan_id %d for dev[%d]" % (vlan_id, i))
ev = dev[i].wait_event(["RSN: Group rekeying completed"], timeout=11)
if ev is None:
raise Exception("GTK rekey timed out")
time.sleep(1)
hwsim_utils.test_connectivity_iface(dev[0], hapd, "brvlan1")
hwsim_utils.test_connectivity_iface(dev[1], hapd, "brvlan2")
hwsim_utils.test_connectivity_iface(dev[2], hapd, "brvlan3")
def test_ap_vlan_sae_group_rekey(dev, apdev, params):
"""AP VLAN and group rekeying"""
check_sae_capab(dev[0])
hapd = start_ap_vlan_sae(apdev[0])
dev[0].set("sae_groups", "")
dev[0].connect("test-sae-vlan", sae_password="pw1",
sae_password_id="id1",
key_mgmt="SAE", scan_freq="2412")
hapd.wait_sta()
hwsim_utils.test_connectivity_iface(dev[0], hapd, "brvlan1")
hapd.set("ext_eapol_frame_io", "1")
ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
if ev is None:
raise Exception("Timeout on EAPOL-TX from hostapd")
time.sleep(0.1)
hwsim_utils.test_connectivity_iface(dev[0], hapd, "brvlan1")
hapd.set("ext_eapol_frame_io", "0")
ev = dev[0].wait_event(["RSN: Group rekeying completed"], timeout=11)
if ev is None:
raise Exception("GTK rekey timed out")
time.sleep(1)
hwsim_utils.test_connectivity_iface(dev[0], hapd, "brvlan1")

View file

@ -2314,23 +2314,6 @@ def test_dpp_auto_connect_legacy_sae_2(dev, apdev):
finally: finally:
dev[0].set("dpp_config_processing", "0", allow_fail=True) dev[0].set("dpp_config_processing", "0", allow_fail=True)
def test_dpp_auto_connect_legacy_sae_3(dev, apdev):
"""DPP and auto connect (legacy SAE with short password)"""
try:
run_dpp_auto_connect_legacy(dev, apdev, conf='sta-sae', sae_only=True,
password="1234567")
finally:
dev[0].set("dpp_config_processing", "0", allow_fail=True)
def test_dpp_auto_connect_legacy_sae_pw_id(dev, apdev):
"""DPP and auto connect (legacy SAE with password identifier)"""
check_dpp_capab(dev[0], min_ver=3)
try:
run_dpp_auto_connect_legacy(dev, apdev, conf='sta-sae', sae_only=True,
password_id="id")
finally:
dev[0].set("dpp_config_processing", "0", allow_fail=True)
def test_dpp_auto_connect_legacy_psk_sae_1(dev, apdev): def test_dpp_auto_connect_legacy_psk_sae_1(dev, apdev):
"""DPP and auto connect (legacy PSK+SAE)""" """DPP and auto connect (legacy PSK+SAE)"""
try: try:
@ -2356,22 +2339,16 @@ def test_dpp_auto_connect_legacy_psk_sae_3(dev, apdev):
def run_dpp_auto_connect_legacy(dev, apdev, conf='sta-psk', def run_dpp_auto_connect_legacy(dev, apdev, conf='sta-psk',
ssid_charset=None, ssid_charset=None,
psk_sae=False, sae_only=False, psk_sae=False, sae_only=False):
password="secret passphrase",
password_id=None):
check_dpp_capab(dev[0]) check_dpp_capab(dev[0])
check_dpp_capab(dev[1]) check_dpp_capab(dev[1])
if sae_only and password_id:
params = hostapd.wpa3_params(ssid="dpp-legacy",
password=password + '|id=' + password_id)
elif sae_only:
params = hostapd.wpa3_params(ssid="dpp-legacy",
password=password)
else:
params = hostapd.wpa2_params(ssid="dpp-legacy", params = hostapd.wpa2_params(ssid="dpp-legacy",
passphrase=password) passphrase="secret passphrase")
if psk_sae: if sae_only:
params['wpa_key_mgmt'] = 'SAE'
params['ieee80211w'] = '2'
elif psk_sae:
params['wpa_key_mgmt'] = 'WPA-PSK SAE' params['wpa_key_mgmt'] = 'WPA-PSK SAE'
params['ieee80211w'] = '1' params['ieee80211w'] = '1'
params['sae_require_mfp'] = '1' params['sae_require_mfp'] = '1'
@ -2386,7 +2363,7 @@ def run_dpp_auto_connect_legacy(dev, apdev, conf='sta-psk',
dev[0].dpp_listen(2412) dev[0].dpp_listen(2412)
dev[1].dpp_auth_init(uri=uri0, conf=conf, ssid="dpp-legacy", dev[1].dpp_auth_init(uri=uri0, conf=conf, ssid="dpp-legacy",
ssid_charset=ssid_charset, ssid_charset=ssid_charset,
passphrase=password, password_id=password_id) passphrase="secret passphrase")
wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0]) wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0])
if ssid_charset: if ssid_charset:
ev = dev[0].wait_event(["DPP-CONFOBJ-SSID-CHARSET"], timeout=1) ev = dev[0].wait_event(["DPP-CONFOBJ-SSID-CHARSET"], timeout=1)

View file

@ -13,7 +13,6 @@ from hwsim import HWSimRadio
import hwsim_utils import hwsim_utils
from wpasupplicant import WpaSupplicant from wpasupplicant import WpaSupplicant
import re import re
import mld
from tshark import run_tshark from tshark import run_tshark
from test_gas import hs20_ap_params from test_gas import hs20_ap_params
from test_dpp import check_dpp_capab, wait_auth_success from test_dpp import check_dpp_capab, wait_auth_success
@ -105,9 +104,8 @@ def eht_verify_status(wpas, hapd, freq, bw, is_ht=False, is_vht=False,
time.sleep(0.1) time.sleep(0.1)
_eht_verify_links(wpas, valid_links, active_links) _eht_verify_links(wpas, valid_links, active_links)
def traffic_test(wpas, hapd, success=True, ifname2=None): def traffic_test(wpas, hapd, success=True):
hwsim_utils.test_connectivity(wpas, hapd, success_expected=success, hwsim_utils.test_connectivity(wpas, hapd, success_expected=success)
ifname2=ifname2)
def test_eht_open(dev, apdev): def test_eht_open(dev, apdev):
"""EHT AP with open mode configuration""" """EHT AP with open mode configuration"""
@ -240,8 +238,8 @@ def test_eht_sae_mlo_tm(dev, apdev):
dev[0].set("sae_pwe", "0") dev[0].set("sae_pwe", "0")
dev[1].set("sae_groups", "") dev[1].set("sae_groups", "")
def eht_mld_enable_ap(iface, link_id, params): def eht_mld_enable_ap(iface, params):
hapd = hostapd.add_mld_link(iface, link_id, params) hapd = hostapd.add_mld_link(iface, params)
hapd.enable() hapd.enable()
ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=1) ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=1)
@ -253,7 +251,7 @@ def eht_mld_enable_ap(iface, link_id, params):
return hapd return hapd
def eht_mld_ap_wpa2_params(ssid, passphrase=None, key_mgmt="WPA-PSK-SHA256", def eht_mld_ap_wpa2_params(ssid, passphrase=None, key_mgmt="WPA-PSK-SHA256",
mfp="2", pwe=None, beacon_prot="1", bridge=False): mfp="2", pwe=None, beacon_prot="1"):
params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase, params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase,
wpa_key_mgmt=key_mgmt, ieee80211w=mfp) wpa_key_mgmt=key_mgmt, ieee80211w=mfp)
params['ieee80211n'] = '1' params['ieee80211n'] = '1'
@ -263,8 +261,6 @@ def eht_mld_ap_wpa2_params(ssid, passphrase=None, key_mgmt="WPA-PSK-SHA256",
params['hw_mode'] = 'g' params['hw_mode'] = 'g'
params['group_mgmt_cipher'] = "AES-128-CMAC" params['group_mgmt_cipher'] = "AES-128-CMAC"
params['beacon_prot'] = beacon_prot params['beacon_prot'] = beacon_prot
if bridge:
params['bridge'] = 'ap-br0'
if pwe is not None: if pwe is not None:
params['sae_pwe'] = pwe params['sae_pwe'] = pwe
@ -311,8 +307,8 @@ def test_eht_mld_discovery(dev, apdev):
"hw_mode": "g", "hw_mode": "g",
"channel": "2"} "channel": "2"}
hapd0 = eht_mld_enable_ap(hapd_iface, 0, link0_params) hapd0 = eht_mld_enable_ap(hapd_iface, link0_params)
hapd1 = eht_mld_enable_ap(hapd_iface, 1, link1_params) hapd1 = eht_mld_enable_ap(hapd_iface, link1_params)
# Only scan link 0 # Only scan link 0
res = wpas.request("SCAN freq=2412") res = wpas.request("SCAN freq=2412")
@ -392,13 +388,13 @@ def _eht_mld_owe_two_links(dev, apdev, second_link_disabled=False,
ssid = "mld_ap_owe_two_link" ssid = "mld_ap_owe_two_link"
params = eht_mld_ap_wpa2_params(ssid, key_mgmt="OWE", mfp="2") params = eht_mld_ap_wpa2_params(ssid, key_mgmt="OWE", mfp="2")
hapd0 = eht_mld_enable_ap(hapd0_iface, 0, params) hapd0 = eht_mld_enable_ap(hapd0_iface, params)
params['channel'] = '6' params['channel'] = '6'
if second_link_disabled: if second_link_disabled:
params['mld_indicate_disabled'] = '1' params['mld_indicate_disabled'] = '1'
hapd1 = eht_mld_enable_ap(hapd0_iface, 1, params) hapd1 = eht_mld_enable_ap(hapd0_iface, params)
# Check legacy client connection # Check legacy client connection
dev[0].connect(ssid, scan_freq="2437", key_mgmt="OWE", ieee80211w="2") dev[0].connect(ssid, scan_freq="2437", key_mgmt="OWE", ieee80211w="2")
@ -450,7 +446,7 @@ def test_eht_mld_sae_single_link(dev, apdev):
params = eht_mld_ap_wpa2_params(ssid, passphrase, key_mgmt="SAE", params = eht_mld_ap_wpa2_params(ssid, passphrase, key_mgmt="SAE",
mfp="2", pwe='2') mfp="2", pwe='2')
hapd0 = eht_mld_enable_ap(hapd_iface, 0, params) hapd0 = eht_mld_enable_ap(hapd_iface, params)
wpas.set("sae_pwe", "1") wpas.set("sae_pwe", "1")
wpas.connect(ssid, sae_password=passphrase, scan_freq="2412", wpas.connect(ssid, sae_password=passphrase, scan_freq="2412",
@ -462,7 +458,7 @@ def test_eht_mld_sae_single_link(dev, apdev):
traffic_test(wpas, hapd0) traffic_test(wpas, hapd0)
def run_eht_mld_sae_two_links(dev, apdev, beacon_prot="1", def run_eht_mld_sae_two_links(dev, apdev, beacon_prot="1",
disable_enable=False, bridge=False): disable_enable=False):
with HWSimRadio(use_mlo=True) as (hapd_radio, hapd_iface), \ with HWSimRadio(use_mlo=True) as (hapd_radio, hapd_iface), \
HWSimRadio(use_mlo=True) as (wpas_radio, wpas_iface): HWSimRadio(use_mlo=True) as (wpas_radio, wpas_iface):
@ -473,18 +469,13 @@ def run_eht_mld_sae_two_links(dev, apdev, beacon_prot="1",
ssid = "mld_ap_sae_two_link" ssid = "mld_ap_sae_two_link"
params = eht_mld_ap_wpa2_params(ssid, passphrase, params = eht_mld_ap_wpa2_params(ssid, passphrase,
key_mgmt="SAE", mfp="2", pwe='1', key_mgmt="SAE", mfp="2", pwe='1',
beacon_prot=beacon_prot, beacon_prot=beacon_prot)
bridge=bridge)
hapd0 = eht_mld_enable_ap(hapd_iface, 0, params) hapd0 = eht_mld_enable_ap(hapd_iface, params)
params['channel'] = '6' params['channel'] = '6'
hapd1 = eht_mld_enable_ap(hapd_iface, 1, params) hapd1 = eht_mld_enable_ap(hapd_iface, params)
if bridge:
hapd0.cmd_execute(['brctl', 'setfd', 'ap-br0', '0'])
hapd0.cmd_execute(['ip', 'link', 'set', 'dev', 'ap-br0', 'up'])
wpas.set("sae_pwe", "1") wpas.set("sae_pwe", "1")
@ -503,8 +494,8 @@ def run_eht_mld_sae_two_links(dev, apdev, beacon_prot="1",
if wpas.get_status_field('sae_group') != '19': if wpas.get_status_field('sae_group') != '19':
raise Exception("Expected SAE group not used") raise Exception("Expected SAE group not used")
traffic_test(wpas, hapd0, ifname2='ap-br0' if bridge else None) traffic_test(wpas, hapd0)
traffic_test(wpas, hapd1, ifname2='ap-br0' if bridge else None) traffic_test(wpas, hapd1)
if disable_enable: if disable_enable:
if "OK" not in hapd0.request("DISABLE_MLD"): if "OK" not in hapd0.request("DISABLE_MLD"):
@ -543,8 +534,8 @@ def run_eht_mld_sae_two_links(dev, apdev, beacon_prot="1",
wpas.wait_connected() wpas.wait_connected()
hapd0.wait_sta() hapd0.wait_sta()
hapd1.wait_sta() hapd1.wait_sta()
traffic_test(wpas, hapd0, ifname2='ap-br0' if bridge else None) traffic_test(wpas, hapd0)
traffic_test(wpas, hapd1, ifname2='ap-br0' if bridge else None) traffic_test(wpas, hapd1)
def test_eht_mld_sae_two_links(dev, apdev): def test_eht_mld_sae_two_links(dev, apdev):
"""EHT MLD AP with MLD client SAE H2E connection using two links""" """EHT MLD AP with MLD client SAE H2E connection using two links"""
@ -558,10 +549,6 @@ def test_eht_mld_sae_two_links_disable_enable(dev, apdev):
"""AP MLD with two links and disabling/enabling full AP MLD""" """AP MLD with two links and disabling/enabling full AP MLD"""
run_eht_mld_sae_two_links(dev, apdev, disable_enable=True) run_eht_mld_sae_two_links(dev, apdev, disable_enable=True)
def test_eht_mld_sae_two_links_bridge(dev, apdev):
"""AP MLD with two links in a bridge"""
run_eht_mld_sae_two_links(dev, apdev, bridge=True)
def test_eht_mld_sae_ext_one_link(dev, apdev): def test_eht_mld_sae_ext_one_link(dev, apdev):
"""EHT MLD AP with MLD client SAE-EXT H2E connection using single link""" """EHT MLD AP with MLD client SAE-EXT H2E connection using single link"""
with HWSimRadio(use_mlo=True) as (hapd_radio, hapd_iface), \ with HWSimRadio(use_mlo=True) as (hapd_radio, hapd_iface), \
@ -574,7 +561,7 @@ def test_eht_mld_sae_ext_one_link(dev, apdev):
ssid = "mld_ap_sae_ext_single_link" ssid = "mld_ap_sae_ext_single_link"
params = eht_mld_ap_wpa2_params(ssid, passphrase, key_mgmt="SAE-EXT-KEY") params = eht_mld_ap_wpa2_params(ssid, passphrase, key_mgmt="SAE-EXT-KEY")
hapd0 = eht_mld_enable_ap(hapd_iface, 0, params) hapd0 = eht_mld_enable_ap(hapd_iface, params)
wpas.connect(ssid, sae_password=passphrase, scan_freq="2412", wpas.connect(ssid, sae_password=passphrase, scan_freq="2412",
key_mgmt="SAE-EXT-KEY", ieee80211w="2") key_mgmt="SAE-EXT-KEY", ieee80211w="2")
@ -597,11 +584,11 @@ def test_eht_mld_sae_ext_two_links(dev, apdev):
params = eht_mld_ap_wpa2_params(ssid, passphrase, params = eht_mld_ap_wpa2_params(ssid, passphrase,
key_mgmt="SAE-EXT-KEY") key_mgmt="SAE-EXT-KEY")
hapd0 = eht_mld_enable_ap(hapd_iface, 0, params) hapd0 = eht_mld_enable_ap(hapd_iface, params)
params['channel'] = '6' params['channel'] = '6'
hapd1 = eht_mld_enable_ap(hapd_iface, 1, params) hapd1 = eht_mld_enable_ap(hapd_iface, params)
wpas.connect(ssid, sae_password=passphrase, scan_freq="2412 2437", wpas.connect(ssid, sae_password=passphrase, scan_freq="2412 2437",
key_mgmt="SAE-EXT-KEY", ieee80211w="2") key_mgmt="SAE-EXT-KEY", ieee80211w="2")
@ -620,11 +607,11 @@ def test_eht_mld_sae_legacy_client(dev, apdev):
params = eht_mld_ap_wpa2_params(ssid, passphrase, params = eht_mld_ap_wpa2_params(ssid, passphrase,
key_mgmt="SAE", mfp="2", pwe='1') key_mgmt="SAE", mfp="2", pwe='1')
hapd0 = eht_mld_enable_ap(hapd_iface, 0, params) hapd0 = eht_mld_enable_ap(hapd_iface, params)
params['channel'] = '6' params['channel'] = '6'
hapd1 = eht_mld_enable_ap(hapd_iface, 1, params) hapd1 = eht_mld_enable_ap(hapd_iface, params)
try: try:
dev[0].set("sae_groups", "") dev[0].set("sae_groups", "")
@ -660,11 +647,11 @@ def test_eht_mld_sae_transition(dev, apdev):
key_mgmt="SAE-EXT-KEY SAE WPA-PSK WPA-PSK-SHA256", key_mgmt="SAE-EXT-KEY SAE WPA-PSK WPA-PSK-SHA256",
mfp="1") mfp="1")
hapd0 = eht_mld_enable_ap(hapd_iface, 0, params) hapd0 = eht_mld_enable_ap(hapd_iface, params)
params['channel'] = '6' params['channel'] = '6'
hapd1 = eht_mld_enable_ap(hapd_iface, 1, params) hapd1 = eht_mld_enable_ap(hapd_iface, params)
wpas.connect(ssid, sae_password=passphrase, scan_freq="2412 2437", wpas.connect(ssid, sae_password=passphrase, scan_freq="2412 2437",
key_mgmt="SAE-EXT-KEY", ieee80211w="2") key_mgmt="SAE-EXT-KEY", ieee80211w="2")
@ -696,11 +683,11 @@ def test_eht_mld_ptk_rekey(dev, apdev):
mfp="1") mfp="1")
params['wpa_ptk_rekey'] = '5' params['wpa_ptk_rekey'] = '5'
hapd0 = eht_mld_enable_ap(hapd_iface, 0, params) hapd0 = eht_mld_enable_ap(hapd_iface, params)
params['channel'] = '6' params['channel'] = '6'
hapd1 = eht_mld_enable_ap(hapd_iface, 1, params) hapd1 = eht_mld_enable_ap(hapd_iface, params)
wpas.connect(ssid, sae_password=passphrase, scan_freq="2412 2437", wpas.connect(ssid, sae_password=passphrase, scan_freq="2412 2437",
key_mgmt="SAE-EXT-KEY", ieee80211w="2") key_mgmt="SAE-EXT-KEY", ieee80211w="2")
@ -736,11 +723,11 @@ def test_eht_mld_gtk_rekey(dev, apdev):
mfp="1") mfp="1")
params['wpa_group_rekey'] = '5' params['wpa_group_rekey'] = '5'
hapd0 = eht_mld_enable_ap(hapd_iface, 0, params) hapd0 = eht_mld_enable_ap(hapd_iface, params)
params['channel'] = '6' params['channel'] = '6'
hapd1 = eht_mld_enable_ap(hapd_iface, 1, params) hapd1 = eht_mld_enable_ap(hapd_iface, params)
wpas.connect(ssid, sae_password=passphrase, scan_freq="2412 2437", wpas.connect(ssid, sae_password=passphrase, scan_freq="2412 2437",
key_mgmt="SAE-EXT-KEY", ieee80211w="2") key_mgmt="SAE-EXT-KEY", ieee80211w="2")
@ -758,9 +745,10 @@ def test_eht_mld_gtk_rekey(dev, apdev):
if "CTRL-EVENT-DISCONNECTED" in ev: if "CTRL-EVENT-DISCONNECTED" in ev:
raise Exception("Disconnect instead of rekey") raise Exception("Disconnect instead of rekey")
time.sleep(0.1) #TODO: Uncomment these ones GTK rekeying works for MLO
traffic_test(wpas, hapd0) #time.sleep(0.1)
traffic_test(wpas, hapd1) #traffic_test(wpas, hapd0)
#traffic_test(wpas, hapd1)
def test_eht_ml_probe_req(dev, apdev): def test_eht_ml_probe_req(dev, apdev):
"""AP MLD with two links and non-AP MLD sending ML Probe Request""" """AP MLD with two links and non-AP MLD sending ML Probe Request"""
@ -775,11 +763,11 @@ def test_eht_ml_probe_req(dev, apdev):
params = eht_mld_ap_wpa2_params(ssid, passphrase, params = eht_mld_ap_wpa2_params(ssid, passphrase,
key_mgmt="SAE-EXT-KEY") key_mgmt="SAE-EXT-KEY")
hapd0 = eht_mld_enable_ap(hapd_iface, 0, params) hapd0 = eht_mld_enable_ap(hapd_iface, params)
params['channel'] = '6' params['channel'] = '6'
hapd1 = eht_mld_enable_ap(hapd_iface, 1, params) hapd1 = eht_mld_enable_ap(hapd_iface, params)
bssid = hapd0.own_addr() bssid = hapd0.own_addr()
wpas.scan_for_bss(bssid, freq=2412) wpas.scan_for_bss(bssid, freq=2412)
@ -816,11 +804,11 @@ def test_eht_mld_connect_probes(dev, apdev, params):
key_mgmt="SAE", pwe='2') key_mgmt="SAE", pwe='2')
link_params['channel'] = '1' link_params['channel'] = '1'
link_params['bssid'] = '00:11:22:33:44:01' link_params['bssid'] = '00:11:22:33:44:01'
hapd0 = eht_mld_enable_ap(hapd_iface, 0, link_params) hapd0 = eht_mld_enable_ap(hapd_iface, link_params)
link_params['channel'] = '6' link_params['channel'] = '6'
link_params['bssid'] = '00:11:22:33:44:02' link_params['bssid'] = '00:11:22:33:44:02'
hapd1 = eht_mld_enable_ap(hapd_iface, 1, link_params) hapd1 = eht_mld_enable_ap(hapd_iface, link_params)
wpas.set("sae_pwe", "1") wpas.set("sae_pwe", "1")
wpas.connect(ssid, sae_password= passphrase, ieee80211w="2", wpas.connect(ssid, sae_password= passphrase, ieee80211w="2",
@ -861,11 +849,11 @@ def test_eht_tx_link_rejected_connect_other(dev, apdev, params):
key_mgmt="SAE", pwe='2') key_mgmt="SAE", pwe='2')
link_params['channel'] = '1' link_params['channel'] = '1'
link_params['bssid'] = '00:11:22:33:44:01' link_params['bssid'] = '00:11:22:33:44:01'
hapd0 = eht_mld_enable_ap(hapd_iface, 0, link_params) hapd0 = eht_mld_enable_ap(hapd_iface, link_params)
link_params['channel'] = '6' link_params['channel'] = '6'
link_params['bssid'] = '00:11:22:33:44:02' link_params['bssid'] = '00:11:22:33:44:02'
hapd1 = eht_mld_enable_ap(hapd_iface, 1, link_params) hapd1 = eht_mld_enable_ap(hapd_iface, link_params)
wpas.set("sae_pwe", "1") wpas.set("sae_pwe", "1")
with fail_test(hapd0, 1, "hostapd_get_aid"): with fail_test(hapd0, 1, "hostapd_get_aid"):
@ -891,11 +879,11 @@ def test_eht_all_links_rejected(dev, apdev, params):
key_mgmt="SAE", pwe='2') key_mgmt="SAE", pwe='2')
link_params['channel'] = '1' link_params['channel'] = '1'
link_params['bssid'] = '00:11:22:33:44:01' link_params['bssid'] = '00:11:22:33:44:01'
hapd0 = eht_mld_enable_ap(hapd_iface, 0, link_params) hapd0 = eht_mld_enable_ap(hapd_iface, link_params)
link_params['channel'] = '6' link_params['channel'] = '6'
link_params['bssid'] = '00:11:22:33:44:02' link_params['bssid'] = '00:11:22:33:44:02'
hapd1 = eht_mld_enable_ap(hapd_iface, 1, link_params) hapd1 = eht_mld_enable_ap(hapd_iface, link_params)
wpas.set("mld_connect_bssid_pref", "00:11:22:33:44:01") wpas.set("mld_connect_bssid_pref", "00:11:22:33:44:01")
wpas.set("sae_pwe", "1") wpas.set("sae_pwe", "1")
@ -934,11 +922,11 @@ def test_eht_connect_invalid_link(dev, apdev, params):
key_mgmt="SAE", pwe='2') key_mgmt="SAE", pwe='2')
link_params['channel'] = '1' link_params['channel'] = '1'
link_params['bssid'] = '00:11:22:33:44:01' link_params['bssid'] = '00:11:22:33:44:01'
hapd0 = eht_mld_enable_ap(hapd_iface, 0, link_params) hapd0 = eht_mld_enable_ap(hapd_iface, link_params)
link_params['channel'] = '6' link_params['channel'] = '6'
link_params['bssid'] = '00:11:22:33:44:02' link_params['bssid'] = '00:11:22:33:44:02'
hapd1 = eht_mld_enable_ap(hapd_iface, 1, link_params) hapd1 = eht_mld_enable_ap(hapd_iface, link_params)
# We scan for both APs, then try to connect to link 0, but only the # We scan for both APs, then try to connect to link 0, but only the
# second attempt will work if mac80211 rejects the second link. # second attempt will work if mac80211 rejects the second link.
@ -969,10 +957,10 @@ def test_eht_mld_link_removal(dev, apdev):
ssid = "mld_ap_owe_two_link" ssid = "mld_ap_owe_two_link"
params = eht_mld_ap_wpa2_params(ssid, key_mgmt="OWE", mfp="2") params = eht_mld_ap_wpa2_params(ssid, key_mgmt="OWE", mfp="2")
hapd0 = eht_mld_enable_ap(hapd0_iface, 0, params) hapd0 = eht_mld_enable_ap(hapd0_iface, params)
params['channel'] = '6' params['channel'] = '6'
hapd1 = eht_mld_enable_ap(hapd0_iface, 1, params) hapd1 = eht_mld_enable_ap(hapd0_iface, params)
wpas.connect(ssid, scan_freq="2412 2437", key_mgmt="OWE", wpas.connect(ssid, scan_freq="2412 2437", key_mgmt="OWE",
ieee80211w="2") ieee80211w="2")
@ -1022,11 +1010,11 @@ def test_eht_mld_bss_trans_mgmt_link_removal_imminent(dev, apdev):
params["bss_transition"] = "1" params["bss_transition"] = "1"
params["mbo"] = "1" params["mbo"] = "1"
hapd0 = eht_mld_enable_ap(hapd0_iface, 0, params) hapd0 = eht_mld_enable_ap(hapd0_iface, params)
params['channel'] = '6' params['channel'] = '6'
hapd1 = eht_mld_enable_ap(hapd0_iface, 1, params) hapd1 = eht_mld_enable_ap(hapd0_iface, params)
wpas.connect(ssid, scan_freq="2412 2437", key_mgmt="OWE", wpas.connect(ssid, scan_freq="2412 2437", key_mgmt="OWE",
ieee80211w="2") ieee80211w="2")
@ -1074,11 +1062,11 @@ def test_eht_ap_mld_proto(dev, apdev):
ssid = "mld_ap_owe_two_link" ssid = "mld_ap_owe_two_link"
params = eht_mld_ap_wpa2_params(ssid, key_mgmt="OWE", mfp="2") params = eht_mld_ap_wpa2_params(ssid, key_mgmt="OWE", mfp="2")
hapd0 = eht_mld_enable_ap(hapd0_iface, 0, params) hapd0 = eht_mld_enable_ap(hapd0_iface, params)
params['channel'] = '6' params['channel'] = '6'
hapd1 = eht_mld_enable_ap(hapd0_iface, 1, params) hapd1 = eht_mld_enable_ap(hapd0_iface, params)
ap_mld_addr = hapd0.get_status_field("mld_addr[0]").replace(':', '') ap_mld_addr = hapd0.get_status_field("mld_addr[0]").replace(':', '')
bssid0 = hapd0.own_addr().replace(':', '') bssid0 = hapd0.own_addr().replace(':', '')
@ -1363,7 +1351,6 @@ def _test_eht_6ghz(dev, apdev, channel, op_class, ccfs1):
raise Exception("STATUS did not indicate ieee80211be=1") raise Exception("STATUS did not indicate ieee80211be=1")
dev[0].set("sae_pwe", "1") dev[0].set("sae_pwe", "1")
dev[0].set("sae_groups", "")
freq = 5950 + channel * 5 freq = 5950 + channel * 5
bw = _6ghz_op_class_to_bw(op_class) bw = _6ghz_op_class_to_bw(op_class)
@ -1462,11 +1449,11 @@ def test_eht_mld_gas(dev, apdev):
params['venue_group'] = "7" params['venue_group'] = "7"
params['venue_type'] = "1" params['venue_type'] = "1"
params['venue_name'] = "eng:Example venue" params['venue_name'] = "eng:Example venue"
hapd0 = eht_mld_enable_ap(hapd0_iface, 0, params) hapd0 = eht_mld_enable_ap(hapd0_iface, params)
bssid0 = hapd0.own_addr() bssid0 = hapd0.own_addr()
params['channel'] = '6' params['channel'] = '6'
hapd1 = eht_mld_enable_ap(hapd0_iface, 1, params) hapd1 = eht_mld_enable_ap(hapd0_iface, params)
bssid1 = hapd1.own_addr() bssid1 = hapd1.own_addr()
wpas.scan_for_bss(bssid0, freq="2412") wpas.scan_for_bss(bssid0, freq="2412")
@ -1498,10 +1485,10 @@ def test_eht_mld_dpp_responder_while_assoc(dev, apdev):
ssid = "owe_two_link" ssid = "owe_two_link"
params = eht_mld_ap_wpa2_params(ssid, key_mgmt="OWE", mfp="2") params = eht_mld_ap_wpa2_params(ssid, key_mgmt="OWE", mfp="2")
hapd0 = eht_mld_enable_ap(hapd0_iface, 0, params) hapd0 = eht_mld_enable_ap(hapd0_iface, params)
params['channel'] = '6' params['channel'] = '6'
hapd1 = eht_mld_enable_ap(hapd0_iface, 1, params) hapd1 = eht_mld_enable_ap(hapd0_iface, params)
wpas.connect(ssid, scan_freq="2412 2437", key_mgmt="OWE", wpas.connect(ssid, scan_freq="2412 2437", key_mgmt="OWE",
ieee80211w="2") ieee80211w="2")
@ -1526,10 +1513,10 @@ def _eht_mld_disconnect(dev, apdev, disassoc=True):
ssid = "mld_ap_owe_two_link" ssid = "mld_ap_owe_two_link"
params = eht_mld_ap_wpa2_params(ssid, key_mgmt="OWE", mfp="2") params = eht_mld_ap_wpa2_params(ssid, key_mgmt="OWE", mfp="2")
hapd0 = eht_mld_enable_ap(hapd0_iface, 0, params) hapd0 = eht_mld_enable_ap(hapd0_iface, params)
params['channel'] = '6' params['channel'] = '6'
hapd1 = eht_mld_enable_ap(hapd0_iface, 1, params) hapd1 = eht_mld_enable_ap(hapd0_iface, params)
wpas.connect(ssid, scan_freq="2412 2437", key_mgmt="OWE", wpas.connect(ssid, scan_freq="2412 2437", key_mgmt="OWE",
ieee80211w="2") ieee80211w="2")
@ -1584,7 +1571,7 @@ def test_eht_mld_non_pref_chan(dev, apdev):
params["bss_transition"] = "1" params["bss_transition"] = "1"
params["mbo"] = "1" params["mbo"] = "1"
hapd0 = eht_mld_enable_ap(hapd0_iface, 0, params) hapd0 = eht_mld_enable_ap(hapd0_iface, params)
if "OK" not in wpas.request("SET non_pref_chan 81:7:200:1 81:9:100:2"): if "OK" not in wpas.request("SET non_pref_chan 81:7:200:1 81:9:100:2"):
raise Exception("Failed to set non-preferred channel list") raise Exception("Failed to set non-preferred channel list")
@ -1672,7 +1659,7 @@ def test_eht_mld_rrm_beacon_req(dev, apdev):
params["mbo"] = "1" params["mbo"] = "1"
params["rrm_beacon_report"] = "1" params["rrm_beacon_report"] = "1"
hapd0 = eht_mld_enable_ap(hapd0_iface, 0, params) hapd0 = eht_mld_enable_ap(hapd0_iface, params)
wpas.connect(ssid, scan_freq="2412", key_mgmt="OWE", ieee80211w="2", wpas.connect(ssid, scan_freq="2412", key_mgmt="OWE", ieee80211w="2",
owe_only="1") owe_only="1")
@ -1686,7 +1673,7 @@ def test_eht_mld_rrm_beacon_req(dev, apdev):
other_ssid = "other" other_ssid = "other"
params = eht_mld_ap_wpa2_params(other_ssid, key_mgmt="OWE", mfp="2") params = eht_mld_ap_wpa2_params(other_ssid, key_mgmt="OWE", mfp="2")
params["channel"] = '6' params["channel"] = '6'
hapd1 = eht_mld_enable_ap(hapd1_iface, 0, params) hapd1 = eht_mld_enable_ap(hapd1_iface, params)
# Issue a beacon request for the second AP # Issue a beacon request for the second AP
addr = wpas.own_addr() addr = wpas.own_addr()
@ -1725,7 +1712,7 @@ def test_eht_mld_legacy_stas(dev, apdev):
mfp="2", pwe='2') mfp="2", pwe='2')
params['rsn_pairwise'] = "CCMP GCMP-256" params['rsn_pairwise'] = "CCMP GCMP-256"
params['sae_groups'] = "19 20" params['sae_groups'] = "19 20"
hapd0 = eht_mld_enable_ap(hapd_iface, 0, params) hapd0 = eht_mld_enable_ap(hapd_iface, params)
for i in range(3): for i in range(3):
dev[i].set("sae_groups", "") dev[i].set("sae_groups", "")
@ -1764,7 +1751,7 @@ def test_eht_mld_and_mlds(dev, apdev):
mfp="2", pwe='2') mfp="2", pwe='2')
params['rsn_pairwise'] = "CCMP GCMP-256" params['rsn_pairwise'] = "CCMP GCMP-256"
params['sae_groups'] = "19 20" params['sae_groups'] = "19 20"
hapd0 = eht_mld_enable_ap(hapd_iface, 0, params) hapd0 = eht_mld_enable_ap(hapd_iface, params)
wpas.set("sae_pwe", "1") wpas.set("sae_pwe", "1")
wpas.connect(ssid, sae_password=password, scan_freq="2412", wpas.connect(ssid, sae_password=password, scan_freq="2412",
@ -1829,10 +1816,10 @@ def test_eht_mlo_csa(dev, apdev):
params = eht_mld_ap_wpa2_params(ssid, passphrase, params = eht_mld_ap_wpa2_params(ssid, passphrase,
key_mgmt="SAE", mfp="2", pwe='1') key_mgmt="SAE", mfp="2", pwe='1')
hapd0 = eht_mld_enable_ap(hapd_iface, 0, params) hapd0 = eht_mld_enable_ap(hapd_iface, params)
params['channel'] = '6' params['channel'] = '6'
hapd1 = eht_mld_enable_ap(hapd_iface, 1, params) hapd1 = eht_mld_enable_ap(hapd_iface, params)
wpas.set("sae_pwe", "1") wpas.set("sae_pwe", "1")
wpas.connect(ssid, sae_password=passphrase, scan_freq="2412 2437", wpas.connect(ssid, sae_password=passphrase, scan_freq="2412 2437",
@ -1850,21 +1837,6 @@ def test_eht_mlo_csa(dev, apdev):
logger.info("Test traffic after 1st link CSA completes") logger.info("Test traffic after 1st link CSA completes")
traffic_test(wpas, hapd0) traffic_test(wpas, hapd0)
logger.info("Perform CSA on 2nd link")
mlo_perform_csa(hapd1, "CHAN_SWITCH 5 2412 ht he eht blocktx",
2412, wpas)
logger.info("Test traffic after 2nd link CSA completes")
traffic_test(wpas, hapd1)
logger.info("Perform CSA on 2nd link and bring it back to original channel")
mlo_perform_csa(hapd1, "CHAN_SWITCH 5 2437 ht he eht blocktx",
2437, wpas)
logger.info("Test traffic again after 2nd link CSA completes")
traffic_test(wpas, hapd1)
logger.info("Perform CSA on 1st link and bring it back to original channel") logger.info("Perform CSA on 1st link and bring it back to original channel")
mlo_perform_csa(hapd0, "CHAN_SWITCH 5 2412 ht he eht blocktx", mlo_perform_csa(hapd0, "CHAN_SWITCH 5 2412 ht he eht blocktx",
2412, wpas) 2412, wpas)
@ -1872,6 +1844,8 @@ def test_eht_mlo_csa(dev, apdev):
logger.info("Test traffic again after 1st link CSA completes") logger.info("Test traffic again after 1st link CSA completes")
traffic_test(wpas, hapd0) traffic_test(wpas, hapd0)
#TODO: CSA on non-first link
def create_base_conf_file(iface, channel, prefix='hostapd-', hw_mode='g', def create_base_conf_file(iface, channel, prefix='hostapd-', hw_mode='g',
op_class=None): op_class=None):
# Create configuration file and add phy characteristics # Create configuration file and add phy characteristics
@ -1929,7 +1903,7 @@ def get_config(iface, count, ssid, passphrase, channel, bssid_regex,
params['sae_pwe'] = "2" params['sae_pwe'] = "2"
params['group_mgmt_cipher'] = "AES-128-CMAC" params['group_mgmt_cipher'] = "AES-128-CMAC"
params['beacon_prot'] = "1" params['beacon_prot'] = "1"
params["ctrl_interface"] = "/var/run/hostapd/" params["ctrl_interface"] = "/var/run/hostapd/chan_" + str(channel)
params["bssid"] = bssid_regex % (i + 1) params["bssid"] = bssid_regex % (i + 1)
if rnr: if rnr:
@ -1937,7 +1911,7 @@ def get_config(iface, count, ssid, passphrase, channel, bssid_regex,
append_bss_conf_to_file(f, ifname, params, first=(i == 0)) append_bss_conf_to_file(f, ifname, params, first=(i == 0))
hapds.append([ifname, i]) hapds.append([ifname, params["ctrl_interface"], i])
f.close() f.close()
@ -1982,15 +1956,15 @@ def get_mld_devs(hapd_iface, count, prefix, rnr=False):
start_ap(prefix, fname1 + " " + fname2) start_ap(prefix, fname1 + " " + fname2)
hapd_mld1_link0 = hostapd.Hostapd(ifname=hapds1[0][0], bssidx=hapds1[0][1], hapd_mld1_link0 = hostapd.Hostapd(ifname=hapds1[0][0], ctrl=hapds1[0][1],
link=0) bssidx=hapds1[0][2])
hapd_mld1_link1 = hostapd.Hostapd(ifname=hapds2[0][0], bssidx=hapds2[0][1], hapd_mld1_link1 = hostapd.Hostapd(ifname=hapds2[0][0], ctrl=hapds2[0][1],
link=1) bssidx=hapds2[0][2])
hapd_mld2_link0 = hostapd.Hostapd(ifname=hapds1[1][0], bssidx=hapds1[1][1], hapd_mld2_link0 = hostapd.Hostapd(ifname=hapds1[1][0], ctrl=hapds1[1][1],
link=0) bssidx=hapds1[1][2])
hapd_mld2_link1 = hostapd.Hostapd(ifname=hapds2[1][0], bssidx=hapds2[1][1], hapd_mld2_link1 = hostapd.Hostapd(ifname=hapds2[1][0], ctrl=hapds2[1][1],
link=1) bssidx=hapds2[1][2])
if not hapd_mld1_link0.ping(): if not hapd_mld1_link0.ping():
raise Exception("Could not ping hostapd") raise Exception("Could not ping hostapd")
@ -2170,12 +2144,12 @@ def test_eht_mlo_color_change(dev, apdev):
key_mgmt="SAE", mfp="2", pwe='1') key_mgmt="SAE", mfp="2", pwe='1')
params['he_bss_color'] = '42' params['he_bss_color'] = '42'
hapd0 = eht_mld_enable_ap(hapd_iface, 0, params) hapd0 = eht_mld_enable_ap(hapd_iface, params)
params['channel'] = '6' params['channel'] = '6'
params['he_bss_color'] = '24' params['he_bss_color'] = '24'
hapd1 = eht_mld_enable_ap(hapd_iface, 1, params) hapd1 = eht_mld_enable_ap(hapd_iface, params)
logger.info("Perform CCA on 1st link") logger.info("Perform CCA on 1st link")
if "OK" not in hapd0.request("COLOR_CHANGE 10"): if "OK" not in hapd0.request("COLOR_CHANGE 10"):
@ -2216,36 +2190,3 @@ def test_eht_mlo_color_change(dev, apdev):
hapd0.dump_monitor() hapd0.dump_monitor()
hapd1.dump_monitor() hapd1.dump_monitor()
def test_eht_mld_control_socket_connectivity(dev, apdev):
"""AP MLD control socket connectivity"""
with HWSimRadio(use_mlo=True) as (hapd_radio, hapd_iface), \
HWSimRadio(use_mlo=True) as (wpas_radio, wpas_iface):
ssid = "mld_ap"
link0_params = {"ssid": ssid,
"hw_mode": "g",
"channel": "1"}
link1_params = {"ssid": ssid,
"hw_mode": "g",
"channel": "2"}
hapd0 = eht_mld_enable_ap(hapd_iface, 0, link0_params)
hapd1 = eht_mld_enable_ap(hapd_iface, 1, link1_params)
mld_dev = mld.get_mld_obj(hapd_iface)
# Check status of each link
res = str(mld_dev.request("LINKID 0 STATUS"))
logger.info("LINK 0 STATUS:\n" + res)
if "state" not in res:
raise Exception("Failed to get link 0 status via MLD socket")
if 'link_id=0' not in res.splitlines():
raise Exception("link_id=0 not reported for link 0")
res = mld_dev.request("LINKID 1 STATUS")
logger.info("LINK 1 STATUS:\n" + res)
if "state" not in res:
raise Exception("Failed to get link 1 status via MLD socket")
if 'link_id=1' not in res.splitlines():
raise Exception("link_id=0 not reported for link 1")

View file

@ -36,7 +36,7 @@ def test_fils_sk_full_auth(dev, apdev, params):
params['erp_domain'] = 'example.com' params['erp_domain'] = 'example.com'
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
params['wpa_group_rekey'] = '1' params['wpa_group_rekey'] = '1'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].flush_scan_cache() dev[0].flush_scan_cache()
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
@ -86,7 +86,7 @@ def test_fils_sk_sha384_full_auth(dev, apdev, params):
params['erp_domain'] = 'example.com' params['erp_domain'] = 'example.com'
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
params['wpa_group_rekey'] = '1' params['wpa_group_rekey'] = '1'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].flush_scan_cache() dev[0].flush_scan_cache()
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
@ -134,7 +134,7 @@ def test_fils_sk_pmksa_caching(dev, apdev, params):
params['auth_server_port'] = "18128" params['auth_server_port'] = "18128"
params['erp_domain'] = 'example.com' params['erp_domain'] = 'example.com'
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -202,7 +202,7 @@ def test_fils_sk_pmksa_caching_ocv(dev, apdev, params):
params['ieee80211w'] = '1' params['ieee80211w'] = '1'
params['ocv'] = '1' params['ocv'] = '1'
try: try:
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
except Exception as e: except Exception as e:
if "Failed to set hostapd parameter ocv" in str(e): if "Failed to set hostapd parameter ocv" in str(e):
raise HwsimSkip("OCV not supported") raise HwsimSkip("OCV not supported")
@ -279,7 +279,7 @@ def test_fils_sk_pmksa_caching_and_cache_id(dev, apdev):
params["eap_fast_a_id_info"] = "test server" params["eap_fast_a_id_info"] = "test server"
params["eap_server_erp"] = "1" params["eap_server_erp"] = "1"
params["erp_domain"] = "example.com" params["erp_domain"] = "example.com"
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -305,7 +305,7 @@ def test_fils_sk_pmksa_caching_and_cache_id(dev, apdev):
params['erp_domain'] = 'example.com' params['erp_domain'] = 'example.com'
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
params['fils_cache_id'] = "abcd" params['fils_cache_id'] = "abcd"
hapd2 = hostapd.add_ap(apdev[1], params) hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
dev[0].scan_for_bss(bssid2, freq=2412) dev[0].scan_for_bss(bssid2, freq=2412)
@ -348,7 +348,7 @@ def test_fils_sk_pmksa_caching_ctrl_ext(dev, apdev, params):
params['erp_domain'] = 'example.com' params['erp_domain'] = 'example.com'
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
params['fils_cache_id'] = "ffee" params['fils_cache_id'] = "ffee"
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -386,7 +386,7 @@ def test_fils_sk_pmksa_caching_ctrl_ext(dev, apdev, params):
params['erp_domain'] = 'example.com' params['erp_domain'] = 'example.com'
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
params['fils_cache_id'] = "ffee" params['fils_cache_id'] = "ffee"
hapd2 = hostapd.add_ap(apdev[1], params) hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
dev[0].scan_for_bss(bssid2, freq=2412) dev[0].scan_for_bss(bssid2, freq=2412)
dev[0].set_network(id, "bssid", bssid2) dev[0].set_network(id, "bssid", bssid2)
@ -417,7 +417,7 @@ def run_fils_sk_erp(dev, apdev, key_mgmt, params):
params['erp_domain'] = 'example.com' params['erp_domain'] = 'example.com'
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
params['disable_pmksa_caching'] = '1' params['disable_pmksa_caching'] = '1'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -458,7 +458,7 @@ def test_fils_sk_erp_followed_by_pmksa_caching(dev, apdev, params):
params['auth_server_port'] = "18128" params['auth_server_port'] = "18128"
params['erp_domain'] = 'example.com' params['erp_domain'] = 'example.com'
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -533,7 +533,7 @@ def test_fils_sk_erp_another_ssid(dev, apdev, params):
params['erp_domain'] = 'example.com' params['erp_domain'] = 'example.com'
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
params['disable_pmksa_caching'] = '1' params['disable_pmksa_caching'] = '1'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -557,7 +557,7 @@ def test_fils_sk_erp_another_ssid(dev, apdev, params):
params['erp_domain'] = 'example.com' params['erp_domain'] = 'example.com'
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
params['disable_pmksa_caching'] = '1' params['disable_pmksa_caching'] = '1'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].dump_monitor() dev[0].dump_monitor()
@ -600,7 +600,7 @@ def test_fils_sk_multiple_realms(dev, apdev, params):
params['fils_realm'] = fils_realms params['fils_realm'] = fils_realms
params['fils_cache_id'] = "1234" params['fils_cache_id'] = "1234"
params['hessid'] = bssid params['hessid'] = bssid
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].flush_scan_cache() dev[0].flush_scan_cache()
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
@ -785,7 +785,7 @@ def run_fils_sk_hlp(dev, apdev, rapid_commit_server, params):
params['fils_hlp_wait_time'] = '10000' params['fils_hlp_wait_time'] = '10000'
if not rapid_commit_server: if not rapid_commit_server:
params['dhcp_rapid_commit_proxy'] = '1' params['dhcp_rapid_commit_proxy'] = '1'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -890,7 +890,7 @@ def test_fils_sk_hlp_timeout(dev, apdev, params):
bssid = apdev[0]['bssid'] bssid = apdev[0]['bssid']
params = fils_hlp_config(fils_hlp_wait_time=30) params = fils_hlp_config(fils_hlp_wait_time=30)
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -937,7 +937,7 @@ def test_fils_sk_hlp_oom(dev, apdev, params):
bssid = apdev[0]['bssid'] bssid = apdev[0]['bssid']
params = fils_hlp_config(fils_hlp_wait_time=500) params = fils_hlp_config(fils_hlp_wait_time=500)
params['dhcp_rapid_commit_proxy'] = '1' params['dhcp_rapid_commit_proxy'] = '1'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -1037,7 +1037,7 @@ def test_fils_sk_hlp_req_parsing(dev, apdev, params):
bssid = apdev[0]['bssid'] bssid = apdev[0]['bssid']
params = fils_hlp_config(fils_hlp_wait_time=30) params = fils_hlp_config(fils_hlp_wait_time=30)
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -1212,7 +1212,7 @@ def test_fils_sk_hlp_dhcp_parsing(dev, apdev, params):
bssid = apdev[0]['bssid'] bssid = apdev[0]['bssid']
params = fils_hlp_config(fils_hlp_wait_time=30) params = fils_hlp_config(fils_hlp_wait_time=30)
params['dhcp_rapid_commit_proxy'] = '1' params['dhcp_rapid_commit_proxy'] = '1'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -1374,7 +1374,7 @@ def test_fils_sk_erp_and_reauth(dev, apdev, params):
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
params['disable_pmksa_caching'] = '1' params['disable_pmksa_caching'] = '1'
params['broadcast_deauth'] = '0' params['broadcast_deauth'] = '0'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -1413,7 +1413,7 @@ def test_fils_sk_erp_sim(dev, apdev, params):
params['auth_server_port'] = "18128" params['auth_server_port'] = "18128"
params['fils_realm'] = realm params['fils_realm'] = realm
params['disable_pmksa_caching'] = '1' params['disable_pmksa_caching'] = '1'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -1499,7 +1499,7 @@ def run_fils_sk_pfs(dev, apdev, group, params):
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
params['disable_pmksa_caching'] = '1' params['disable_pmksa_caching'] = '1'
params['fils_dh_group'] = group params['fils_dh_group'] = group
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -1542,7 +1542,7 @@ def test_fils_sk_pfs_group_mismatch(dev, apdev, params):
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
params['disable_pmksa_caching'] = '1' params['disable_pmksa_caching'] = '1'
params['fils_dh_group'] = "20" params['fils_dh_group'] = "20"
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -1577,7 +1577,7 @@ def test_fils_sk_pfs_pmksa_caching(dev, apdev, params):
params['erp_domain'] = 'example.com' params['erp_domain'] = 'example.com'
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
params['fils_dh_group'] = "19" params['fils_dh_group'] = "19"
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -1694,7 +1694,7 @@ def test_fils_sk_auth_mismatch(dev, apdev, params):
params['erp_domain'] = 'example.com' params['erp_domain'] = 'example.com'
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
params['disable_pmksa_caching'] = '1' params['disable_pmksa_caching'] = '1'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -1741,7 +1741,7 @@ def setup_fils_rekey(dev, apdev, params, wpa_ptk_rekey=0, wpa_group_rekey=0,
params['disable_pmksa_caching'] = '1' params['disable_pmksa_caching'] = '1'
if ext_key_id: if ext_key_id:
params['extended_key_id'] = '1' params['extended_key_id'] = '1'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -1823,7 +1823,7 @@ def test_fils_and_ft(dev, apdev, params):
params['erp_domain'] = 'example.com' params['erp_domain'] = 'example.com'
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
params['disable_pmksa_caching'] = '1' params['disable_pmksa_caching'] = '1'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -1856,7 +1856,7 @@ def test_fils_and_ft(dev, apdev, params):
params['r0kh'] = ["02:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f"] params['r0kh'] = ["02:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f"]
params['r1kh'] = "02:00:00:00:04:00 00:01:02:03:04:06 200102030405060708090a0b0c0d0e0f" params['r1kh'] = "02:00:00:00:04:00 00:01:02:03:04:06 200102030405060708090a0b0c0d0e0f"
params['ieee80211w'] = "1" params['ieee80211w'] = "1"
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].dump_monitor() dev[0].dump_monitor()
@ -1893,7 +1893,7 @@ def test_fils_and_ft(dev, apdev, params):
params['r1_key_holder'] = "000102030406" params['r1_key_holder'] = "000102030406"
params['r0kh'] = ["02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f"] params['r0kh'] = ["02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f"]
params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0e0f" params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0e0f"
hapd2 = hostapd.add_ap(apdev[1], params) hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412", force_scan=True) dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412", force_scan=True)
# FIX: Cannot use FT-over-DS without the FTE MIC issue addressed # FIX: Cannot use FT-over-DS without the FTE MIC issue addressed
@ -1984,7 +1984,7 @@ def run_fils_and_ft_setup(dev, apdev, params, key_mgmt):
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
params['disable_pmksa_caching'] = '1' params['disable_pmksa_caching'] = '1'
params['ieee80211w'] = "2" params['ieee80211w'] = "2"
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -2021,7 +2021,7 @@ def run_fils_and_ft_setup(dev, apdev, params, key_mgmt):
"02:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f"] "02:00:00:00:04:00 nas2.w1.fi 300102030405060708090a0b0c0d0e0f"]
params['r1kh'] = "02:00:00:00:04:00 00:01:02:03:04:06 200102030405060708090a0b0c0d0e0f" params['r1kh'] = "02:00:00:00:04:00 00:01:02:03:04:06 200102030405060708090a0b0c0d0e0f"
params['ieee80211w'] = "2" params['ieee80211w'] = "2"
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].dump_monitor() dev[0].dump_monitor()
@ -2052,7 +2052,7 @@ def run_fils_and_ft_setup(dev, apdev, params, key_mgmt):
params['r0kh'] = ["02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f", params['r0kh'] = ["02:00:00:00:03:00 nas1.w1.fi 200102030405060708090a0b0c0d0e0f",
"02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f"] "02:00:00:00:04:00 nas2.w1.fi 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f"]
params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0e0f" params['r1kh'] = "02:00:00:00:03:00 00:01:02:03:04:05 300102030405060708090a0b0c0d0e0f"
hapd2 = hostapd.add_ap(apdev[1], params) hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
return hapd, hapd2 return hapd, hapd2
@ -2070,7 +2070,7 @@ def test_fils_assoc_replay(dev, apdev, params):
params['auth_server_port'] = "18128" params['auth_server_port'] = "18128"
params['erp_domain'] = 'example.com' params['erp_domain'] = 'example.com'
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -2163,7 +2163,7 @@ def test_fils_sk_erp_server_flush(dev, apdev, params):
params['erp_domain'] = 'example.com' params['erp_domain'] = 'example.com'
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
params['disable_pmksa_caching'] = '1' params['disable_pmksa_caching'] = '1'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -2260,7 +2260,7 @@ def run_fils_sk_erp_radius_ext(dev, apdev, params):
params['erp_domain'] = 'erp.example.com' params['erp_domain'] = 'erp.example.com'
params['fils_realm'] = 'erp.example.com' params['fils_realm'] = 'erp.example.com'
params['disable_pmksa_caching'] = '1' params['disable_pmksa_caching'] = '1'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -2313,7 +2313,7 @@ def run_fils_sk_erp_radius_roam(dev, apdev):
params['erp_domain'] = 'example.com' params['erp_domain'] = 'example.com'
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
params['disable_pmksa_caching'] = '1' params['disable_pmksa_caching'] = '1'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -2329,7 +2329,7 @@ def run_fils_sk_erp_radius_roam(dev, apdev):
params['erp_domain'] = 'example.com' params['erp_domain'] = 'example.com'
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
params['disable_pmksa_caching'] = '1' params['disable_pmksa_caching'] = '1'
hapd2 = hostapd.add_ap(apdev[1], params) hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
dev[0].scan_for_bss(bssid2, freq=2412) dev[0].scan_for_bss(bssid2, freq=2412)
@ -2362,7 +2362,7 @@ def test_fils_sk_erp_roam_diff_akm(dev, apdev, params):
params['auth_server_port'] = "18128" params['auth_server_port'] = "18128"
params['erp_domain'] = 'example.com' params['erp_domain'] = 'example.com'
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -2389,7 +2389,7 @@ def test_fils_sk_erp_roam_diff_akm(dev, apdev, params):
params['auth_server_port'] = "18128" params['auth_server_port'] = "18128"
params['erp_domain'] = 'example.com' params['erp_domain'] = 'example.com'
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
hapd2 = hostapd.add_ap(apdev[1], params) hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
dev[0].scan_for_bss(bssid2, freq=2412) dev[0].scan_for_bss(bssid2, freq=2412)
@ -2452,7 +2452,7 @@ def test_fils_discovery_frame(dev, apdev, params):
params['wpa_group_rekey'] = '1' params['wpa_group_rekey'] = '1'
params['fils_discovery_min_interval'] = '20' params['fils_discovery_min_interval'] = '20'
params['fils_discovery_max_interval'] = '20' params['fils_discovery_max_interval'] = '20'
hapd = hostapd.add_ap(apdev[0], params, no_enable=True) hapd = hostapd.add_ap(apdev[0]['ifname'], params, no_enable=True)
if "OK" not in hapd.request("ENABLE"): if "OK" not in hapd.request("ENABLE"):
raise HwsimSkip("FILS Discovery frame transmission not supported") raise HwsimSkip("FILS Discovery frame transmission not supported")
@ -2493,7 +2493,7 @@ def run_fils_offload_to_driver(dev, apdev, params):
params['erp_domain'] = 'example.com' params['erp_domain'] = 'example.com'
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
params['disable_pmksa_caching'] = '1' params['disable_pmksa_caching'] = '1'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev.request("ERP_FLUSH") dev.request("ERP_FLUSH")
id = dev.connect("fils", key_mgmt="FILS-SHA256", id = dev.connect("fils", key_mgmt="FILS-SHA256",
@ -2535,7 +2535,7 @@ def test_fils_sk_okc(dev, apdev, params):
params['auth_server_port'] = "18128" params['auth_server_port'] = "18128"
params['erp_domain'] = 'example.com' params['erp_domain'] = 'example.com'
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].request("ERP_FLUSH") dev[0].request("ERP_FLUSH")
@ -2584,7 +2584,7 @@ def test_fils_sk_ptk_rekey_request(dev, apdev, params):
params['erp_send_reauth_start'] = '1' params['erp_send_reauth_start'] = '1'
params['erp_domain'] = 'example.com' params['erp_domain'] = 'example.com'
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].flush_scan_cache() dev[0].flush_scan_cache()
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)

View file

@ -1,16 +0,0 @@
# hostapd error paths
# Copyright (c) 2024, Jouni Malinen <j@w1.fi>
#
# This software may be distributed under the terms of the BSD license.
# See README for more details.
import hostapd
from utils import *
def test_hostapd_error_drv_init(dev, apdev):
"""hostapd error path on driver interface initialization failure"""
hapd = hostapd.add_ap(apdev[0], {"ssid": "ctrl"})
with fail_test(hapd, 1, "nl80211_setup_ap"):
hapd1 = hostapd.add_ap(apdev[1], {"ssid": "open"}, no_enable=True)
if "FAIL" not in hapd1.request("ENABLE"):
raise Exception("ENABLE succeeded unexpectedly")

View file

@ -428,11 +428,8 @@ def _test_wifi_display_parsing(dev):
dev[1].p2p_connect_group(dev[0].p2p_dev_addr(), pin, timeout=60, dev[1].p2p_connect_group(dev[0].p2p_dev_addr(), pin, timeout=60,
social=True, freq=2412) social=True, freq=2412)
bssid = dev[0].get_group_status_field('bssid') bssid = dev[0].get_group_status_field('bssid')
dev[2].flush_scan_cache()
dev[2].scan_for_bss(bssid, freq=2412, force_scan=True) dev[2].scan_for_bss(bssid, freq=2412, force_scan=True)
bss = dev[2].get_bss(bssid) bss = dev[2].get_bss(bssid)
if 'wfd_subelems' not in bss:
raise Exception("Missing WFD elements in scan results")
if bss['wfd_subelems'] != "000006" + wfd_devinfo: if bss['wfd_subelems'] != "000006" + wfd_devinfo:
raise Exception("Unexpected WFD elements in scan results: " + bss['wfd_subelems']) raise Exception("Unexpected WFD elements in scan results: " + bss['wfd_subelems'])

View file

@ -569,7 +569,7 @@ def pasn_fils_setup(wpas, apdev, params, key_mgmt):
params['erp_domain'] = 'example.com' params['erp_domain'] = 'example.com'
params['fils_realm'] = 'example.com' params['fils_realm'] = 'example.com'
params['disable_pmksa_caching'] = '1' params['disable_pmksa_caching'] = '1'
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
id = wpas.connect("fils", key_mgmt=key_mgmt, id = wpas.connect("fils", key_mgmt=key_mgmt,
eap="PSK", identity="psk.user@example.com", eap="PSK", identity="psk.user@example.com",

View file

@ -64,9 +64,9 @@ def check_nr_results(dev, bssids=None, lci=False, civic=False):
def test_rrm_neighbor_db(dev, apdev): def test_rrm_neighbor_db(dev, apdev):
"""hostapd ctrl_iface SET_NEIGHBOR""" """hostapd ctrl_iface SET_NEIGHBOR"""
params = {"ssid": "test", "rrm_neighbor_report": "1"} params = {"ssid": "test", "rrm_neighbor_report": "1"}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
params = {"ssid": "test2", "rrm_neighbor_report": "1"} params = {"ssid": "test2", "rrm_neighbor_report": "1"}
hapd2 = hostapd.add_ap(apdev[1], params) hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
res = hapd.request("SHOW_NEIGHBOR") res = hapd.request("SHOW_NEIGHBOR")
if len(res.splitlines()) != 1: if len(res.splitlines()) != 1:
@ -215,7 +215,7 @@ def test_rrm_neighbor_db(dev, apdev):
def test_rrm_neighbor_db_failures(dev, apdev): def test_rrm_neighbor_db_failures(dev, apdev):
"""hostapd ctrl_iface SET_NEIGHBOR failures""" """hostapd ctrl_iface SET_NEIGHBOR failures"""
params = {"ssid": "test", "rrm_neighbor_report": "1"} params = {"ssid": "test", "rrm_neighbor_report": "1"}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
cmd = "SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\" nr=" + nr + " lci=" + lci + " civic=" + civic cmd = "SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\" nr=" + nr + " lci=" + lci + " civic=" + civic
tests = [(1, "hostapd_neighbor_add"), tests = [(1, "hostapd_neighbor_add"),
(1, "wpabuf_dup;hostapd_neighbor_set"), (1, "wpabuf_dup;hostapd_neighbor_set"),
@ -229,7 +229,7 @@ def test_rrm_neighbor_db_failures(dev, apdev):
def test_rrm_neighbor_db_disabled(dev, apdev): def test_rrm_neighbor_db_disabled(dev, apdev):
"""hostapd ctrl_iface SHOW_NEIGHBOR while neighbor report disabled""" """hostapd ctrl_iface SHOW_NEIGHBOR while neighbor report disabled"""
params = {"ssid": "test"} params = {"ssid": "test"}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
if "FAIL" not in hapd.request("SHOW_NEIGHBOR"): if "FAIL" not in hapd.request("SHOW_NEIGHBOR"):
raise Exception("SHOW_NEIGHBOR accepted") raise Exception("SHOW_NEIGHBOR accepted")
@ -242,9 +242,9 @@ def test_rrm_neighbor_rep_req(dev, apdev):
nr3 = "dd112233445500000000510107" nr3 = "dd112233445500000000510107"
params = {"ssid": "test", "rnr": "1"} params = {"ssid": "test", "rnr": "1"}
hostapd.add_ap(apdev[0], params) hostapd.add_ap(apdev[0]['ifname'], params)
params = {"ssid": "test2", "rrm_neighbor_report": "1", "rnr": "1"} params = {"ssid": "test2", "rrm_neighbor_report": "1", "rnr": "1"}
hapd = hostapd.add_ap(apdev[1], params) hapd = hostapd.add_ap(apdev[1]['ifname'], params)
bssid1 = apdev[1]['bssid'] bssid1 = apdev[1]['bssid']
@ -351,7 +351,7 @@ def test_rrm_neighbor_rep_oom(dev, apdev):
nr3 = "dd112233445500000000510107" nr3 = "dd112233445500000000510107"
params = {"ssid": "test", "rrm_neighbor_report": "1"} params = {"ssid": "test", "rrm_neighbor_report": "1"}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].connect("test", key_mgmt="NONE", scan_freq="2412") dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
@ -367,7 +367,7 @@ def test_rrm_lci_req(dev, apdev):
check_rrm_support(dev[0]) check_rrm_support(dev[0])
params = {"ssid": "rrm", "rrm_neighbor_report": "1"} params = {"ssid": "rrm", "rrm_neighbor_report": "1"}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
# station not specified # station not specified
if "FAIL" not in hapd.request("REQ_LCI "): if "FAIL" not in hapd.request("REQ_LCI "):
@ -400,7 +400,7 @@ def test_rrm_lci_req_timeout(dev, apdev):
check_rrm_support(dev[0]) check_rrm_support(dev[0])
params = {"ssid": "rrm", "rrm_neighbor_report": "1"} params = {"ssid": "rrm", "rrm_neighbor_report": "1"}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].request("SET LCI " + lci) dev[0].request("SET LCI " + lci)
dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412") dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
@ -431,7 +431,7 @@ def test_rrm_lci_req_oom(dev, apdev):
check_rrm_support(dev[0]) check_rrm_support(dev[0])
params = {"ssid": "rrm", "rrm_neighbor_report": "1"} params = {"ssid": "rrm", "rrm_neighbor_report": "1"}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].request("SET LCI " + lci) dev[0].request("SET LCI " + lci)
dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412") dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
@ -454,7 +454,7 @@ def test_rrm_lci_req_ap_oom(dev, apdev):
check_rrm_support(dev[0]) check_rrm_support(dev[0])
params = {"ssid": "rrm", "rrm_neighbor_report": "1"} params = {"ssid": "rrm", "rrm_neighbor_report": "1"}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].request("SET LCI " + lci) dev[0].request("SET LCI " + lci)
dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412") dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
@ -472,7 +472,7 @@ def test_rrm_lci_req_get_reltime_failure(dev, apdev):
check_rrm_support(dev[0]) check_rrm_support(dev[0])
params = {"ssid": "rrm", "rrm_neighbor_report": "1"} params = {"ssid": "rrm", "rrm_neighbor_report": "1"}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].request("SET LCI " + lci) dev[0].request("SET LCI " + lci)
dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412") dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
@ -488,7 +488,7 @@ def test_rrm_neighbor_rep_req_from_conf(dev, apdev):
params = {"ssid": "test2", "rrm_neighbor_report": "1", params = {"ssid": "test2", "rrm_neighbor_report": "1",
"stationary_ap": "1", "lci": lci, "civic": civic} "stationary_ap": "1", "lci": lci, "civic": civic}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
bssid = apdev[0]['bssid'] bssid = apdev[0]['bssid']
@ -504,7 +504,7 @@ def test_rrm_neighbor_rep_req_timeout(dev, apdev):
params = {"ssid": "test2", "rrm_neighbor_report": "1", params = {"ssid": "test2", "rrm_neighbor_report": "1",
"stationary_ap": "1", "lci": lci, "civic": civic} "stationary_ap": "1", "lci": lci, "civic": civic}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].connect("test2", key_mgmt="NONE", scan_freq="2412") dev[0].connect("test2", key_mgmt="NONE", scan_freq="2412")
@ -523,7 +523,7 @@ def test_rrm_neighbor_rep_req_oom(dev, apdev):
params = {"ssid": "test2", "rrm_neighbor_report": "1", params = {"ssid": "test2", "rrm_neighbor_report": "1",
"stationary_ap": "1", "lci": lci, "civic": civic} "stationary_ap": "1", "lci": lci, "civic": civic}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].connect("test2", key_mgmt="NONE", scan_freq="2412") dev[0].connect("test2", key_mgmt="NONE", scan_freq="2412")
@ -548,7 +548,7 @@ def test_rrm_neighbor_rep_req_disconnect(dev, apdev):
params = {"ssid": "test2", "rrm_neighbor_report": "1", params = {"ssid": "test2", "rrm_neighbor_report": "1",
"stationary_ap": "1", "lci": lci, "civic": civic} "stationary_ap": "1", "lci": lci, "civic": civic}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
if "FAIL" not in dev[0].request("NEIGHBOR_REP_REQUEST"): if "FAIL" not in dev[0].request("NEIGHBOR_REP_REQUEST"):
raise Exception("Request accepted while disconnected") raise Exception("Request accepted while disconnected")
@ -570,7 +570,7 @@ def test_rrm_neighbor_rep_req_not_supported(dev, apdev):
check_rrm_support(dev[0]) check_rrm_support(dev[0])
params = {"ssid": "test2", "rrm_beacon_report": "1"} params = {"ssid": "test2", "rrm_beacon_report": "1"}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].connect("test2", key_mgmt="NONE", scan_freq="2412") dev[0].connect("test2", key_mgmt="NONE", scan_freq="2412")
@ -583,7 +583,7 @@ def test_rrm_neighbor_rep_req_busy(dev, apdev):
params = {"ssid": "test2", "rrm_neighbor_report": "1", params = {"ssid": "test2", "rrm_neighbor_report": "1",
"stationary_ap": "1", "lci": lci, "civic": civic} "stationary_ap": "1", "lci": lci, "civic": civic}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
dev[0].connect("test2", key_mgmt="NONE", scan_freq="2412") dev[0].connect("test2", key_mgmt="NONE", scan_freq="2412")
@ -608,7 +608,7 @@ def test_rrm_ftm_range_req(dev, apdev):
def run_rrm_ftm_range_req(dev, apdev): def run_rrm_ftm_range_req(dev, apdev):
params = {"ssid": "rrm", "rrm_neighbor_report": "1"} params = {"ssid": "rrm", "rrm_neighbor_report": "1"}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
bssid = hapd.own_addr() bssid = hapd.own_addr()
# station not specified # station not specified
@ -694,7 +694,7 @@ def test_rrm_ftm_range_req_timeout(dev, apdev):
def run_rrm_ftm_range_req_timeout(dev, apdev): def run_rrm_ftm_range_req_timeout(dev, apdev):
params = {"ssid": "rrm", "rrm_neighbor_report": "1"} params = {"ssid": "rrm", "rrm_neighbor_report": "1"}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
bssid = hapd.own_addr() bssid = hapd.own_addr()
# Override RM capabilities to include FTM range report # Override RM capabilities to include FTM range report
@ -734,7 +734,7 @@ def test_rrm_ftm_range_req_failure(dev, apdev):
def run_rrm_ftm_range_req_failure(dev, apdev): def run_rrm_ftm_range_req_failure(dev, apdev):
params = {"ssid": "rrm", "rrm_neighbor_report": "1"} params = {"ssid": "rrm", "rrm_neighbor_report": "1"}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
bssid = hapd.own_addr() bssid = hapd.own_addr()
# Override RM capabilities to include FTM range report # Override RM capabilities to include FTM range report
@ -764,7 +764,7 @@ def _test_rrm_ftm_capa_indication(dev, apdev):
params = {"ssid": "ftm", params = {"ssid": "ftm",
"ftm_responder": "1", "ftm_responder": "1",
"ftm_initiator": "1",} "ftm_initiator": "1",}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
if "OK" not in dev[0].request("SET ftm_initiator 1"): if "OK" not in dev[0].request("SET ftm_initiator 1"):
raise Exception("could not set ftm_initiator") raise Exception("could not set ftm_initiator")
@ -1564,7 +1564,7 @@ def test_rrm_beacon_req_active_many(dev, apdev):
params = {"ssid": "rrm", "rrm_beacon_report": "1"} params = {"ssid": "rrm", "rrm_beacon_report": "1"}
params['vendor_elements'] = "dd50" + 80*'aa' params['vendor_elements'] = "dd50" + 80*'aa'
hapd = hostapd.add_ap(apdev[1], params) hapd = hostapd.add_ap(apdev[1]['ifname'], params)
dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412") dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
addr = dev[0].own_addr() addr = dev[0].own_addr()
@ -2058,7 +2058,7 @@ def test_rrm_beacon_req_ap_errors(dev, apdev):
def run_rrm_beacon_req_ap_errors(dev, apdev): def run_rrm_beacon_req_ap_errors(dev, apdev):
params = {"ssid": "rrm", "rrm_beacon_report": "1"} params = {"ssid": "rrm", "rrm_beacon_report": "1"}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
bssid = hapd.own_addr() bssid = hapd.own_addr()
dev[0].scan_for_bss(bssid, freq=2412) dev[0].scan_for_bss(bssid, freq=2412)
dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412") dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
@ -2106,7 +2106,7 @@ def run_rrm_beacon_req_ap_errors(dev, apdev):
def test_rrm_req_reject_oom(dev, apdev): def test_rrm_req_reject_oom(dev, apdev):
"""Radio measurement request - OOM while rejecting a request""" """Radio measurement request - OOM while rejecting a request"""
params = {"ssid": "rrm", "rrm_beacon_report": "1"} params = {"ssid": "rrm", "rrm_beacon_report": "1"}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
bssid = hapd.own_addr() bssid = hapd.own_addr()
dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412") dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
@ -2129,7 +2129,7 @@ def test_rrm_req_reject_oom(dev, apdev):
def test_rrm_req_when_rrm_not_used(dev, apdev): def test_rrm_req_when_rrm_not_used(dev, apdev):
"""Radio/link measurement request for non-RRM association""" """Radio/link measurement request for non-RRM association"""
params = {"ssid": "rrm"} params = {"ssid": "rrm"}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
bssid = hapd.own_addr() bssid = hapd.own_addr()
dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412") dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
@ -2268,7 +2268,7 @@ def test_rrm_link_measurement(dev, apdev):
"""Radio measurement request - link measurement""" """Radio measurement request - link measurement"""
check_tx_power_support(dev[0]) check_tx_power_support(dev[0])
params = {"ssid": "rrm", "rrm_beacon_report": "1"} params = {"ssid": "rrm", "rrm_beacon_report": "1"}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
bssid = hapd.own_addr() bssid = hapd.own_addr()
dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412") dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
@ -2289,7 +2289,7 @@ def test_rrm_link_measurement_oom(dev, apdev):
"""Radio measurement request - link measurement OOM""" """Radio measurement request - link measurement OOM"""
check_tx_power_support(dev[0]) check_tx_power_support(dev[0])
params = {"ssid": "rrm", "rrm_beacon_report": "1"} params = {"ssid": "rrm", "rrm_beacon_report": "1"}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
bssid = hapd.own_addr() bssid = hapd.own_addr()
dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412") dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
@ -2319,7 +2319,7 @@ def test_rrm_rep_parse_proto(dev, apdev):
check_rrm_support(dev[0]) check_rrm_support(dev[0])
params = {"ssid": "rrm", "rrm_neighbor_report": "1"} params = {"ssid": "rrm", "rrm_neighbor_report": "1"}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
bssid = hapd.own_addr() bssid = hapd.own_addr()
dev[0].request("SET LCI " + lci) dev[0].request("SET LCI " + lci)
@ -2354,7 +2354,7 @@ def test_rrm_unexpected(dev, apdev):
check_rrm_support(dev[0]) check_rrm_support(dev[0])
params = {"ssid": "rrm", "rrm_neighbor_report": "0"} params = {"ssid": "rrm", "rrm_neighbor_report": "0"}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
bssid = hapd.own_addr() bssid = hapd.own_addr()
dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412") dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
@ -2381,7 +2381,7 @@ def check_beacon_req(hapd, addr, idx):
def test_rrm_reassociation(dev, apdev): def test_rrm_reassociation(dev, apdev):
"""Radio measurement request - reassociation""" """Radio measurement request - reassociation"""
params = {"ssid": "rrm", "rrm_beacon_report": "1"} params = {"ssid": "rrm", "rrm_beacon_report": "1"}
hapd = hostapd.add_ap(apdev[0], params) hapd = hostapd.add_ap(apdev[0]['ifname'], params)
bssid = hapd.own_addr() bssid = hapd.own_addr()
addr = dev[0].own_addr() addr = dev[0].own_addr()
@ -2395,7 +2395,7 @@ def test_rrm_reassociation(dev, apdev):
hapd.wait_sta() hapd.wait_sta()
check_beacon_req(hapd, addr, 1) check_beacon_req(hapd, addr, 1)
hapd2 = hostapd.add_ap(apdev[1], params) hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
bssid2 = hapd2.own_addr() bssid2 = hapd2.own_addr()
dev[0].scan_for_bss(bssid2, freq=2412, force_scan=True) dev[0].scan_for_bss(bssid2, freq=2412, force_scan=True)
dev[0].roam(bssid2) dev[0].roam(bssid2)

View file

@ -1,437 +0,0 @@
# Test cases for RSNE/RSNXE overriding
# Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc.
#
# This software may be distributed under the terms of the BSD license.
# See README for more details.
import hostapd
from utils import *
from hwsim import HWSimRadio
from wpasupplicant import WpaSupplicant
from test_eht import eht_mld_enable_ap, eht_verify_status, eht_verify_wifi_version, traffic_test
def test_rsn_override(dev, apdev):
"""RSNE=WPA2-Personal/PMF-optional override=WPA3-Personal/PMF-required (with MLO parameters)"""
check_sae_capab(dev[0])
ssid = "test-rsn-override"
params = hostapd.wpa2_params(ssid=ssid,
passphrase="12345678",
ieee80211w='1')
params['rsn_override_key_mgmt'] = 'SAE SAE-EXT-KEY'
params['rsn_override_pairwise'] = 'CCMP GCMP-256'
params['rsn_override_mfp'] = '2'
params['beacon_prot'] = '1'
params['sae_groups'] = '19 20'
params['sae_require_mfp'] = '1'
params['sae_pwe'] = '2'
hapd = hostapd.add_ap(apdev[0], params)
bssid = hapd.own_addr()
try:
dev[0].set("rsn_overriding", "1")
dev[0].scan_for_bss(bssid, freq=2412)
bss = dev[0].get_bss(bssid)
flags = bss['flags']
if "PSK" in flags:
raise Exception("Unexpected BSS flags: " + flags)
if "-SAE+SAE-EXT-KEY-" not in flags:
raise Exception("Unexpected BSS flags: " + flags)
if "-GCMP-256+CCMP" not in flags:
raise Exception("Unexpected BSS flags: " + flags)
dev[0].set("sae_pwe", "2")
dev[0].set("sae_groups", "")
dev[0].connect(ssid, sae_password="12345678", key_mgmt="SAE",
ieee80211w="2", scan_freq="2412")
finally:
dev[0].set("sae_pwe", "0")
dev[0].set("rsn_overriding", "0")
def test_rsn_override2(dev, apdev):
"""RSNE=WPA2-Personal/PMF-disabled override=WPA3-Personal/PMF-required (with MLO parameters)"""
check_sae_capab(dev[0])
ssid = "test-rsn-override"
params = hostapd.wpa2_params(ssid=ssid,
passphrase="12345678",
ieee80211w='0')
params['rsn_override_key_mgmt'] = 'SAE SAE-EXT-KEY'
params['rsn_override_pairwise'] = 'CCMP GCMP-256'
params['rsn_override_mfp'] = '2'
params['beacon_prot'] = '1'
params['sae_groups'] = '19 20'
params['sae_require_mfp'] = '1'
params['sae_pwe'] = '2'
hapd = hostapd.add_ap(apdev[0], params)
bssid = hapd.own_addr()
try:
dev[0].set("rsn_overriding", "1")
dev[0].scan_for_bss(bssid, freq=2412)
bss = dev[0].get_bss(bssid)
flags = bss['flags']
if "PSK" in flags:
raise Exception("Unexpected BSS flags: " + flags)
if "-SAE+SAE-EXT-KEY-" not in flags:
raise Exception("Unexpected BSS flags: " + flags)
if "-GCMP-256+CCMP" not in flags:
raise Exception("Unexpected BSS flags: " + flags)
dev[0].set("sae_pwe", "2")
dev[0].set("sae_groups", "")
dev[0].connect(ssid, sae_password="12345678", key_mgmt="SAE",
ieee80211w="2", scan_freq="2412")
finally:
dev[0].set("sae_pwe", "0")
dev[0].set("rsn_overriding", "0")
def test_rsn_override_no_pairwise(dev, apdev):
"""RSN overriding and no pairwise cipher match in RSNEO"""
check_sae_capab(dev[0])
ssid = "test-rsn-override"
params = hostapd.wpa2_params(ssid=ssid,
passphrase="12345678",
ieee80211w='1')
params['rsn_override_key_mgmt'] = 'SAE SAE-EXT-KEY'
params['rsn_override_pairwise'] = 'GCMP-256'
params['rsn_override_mfp'] = '2'
params['beacon_prot'] = '1'
params['sae_groups'] = '19 20'
params['sae_require_mfp'] = '1'
hapd = hostapd.add_ap(apdev[0], params)
bssid = hapd.own_addr()
try:
dev[0].set("rsn_overriding", "1")
dev[0].scan_for_bss(bssid, freq=2412)
dev[0].set("sae_groups", "")
dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK SAE",
pairwise="CCMP", ieee80211w="1", scan_freq="2412")
finally:
dev[0].set("sae_pwe", "0")
dev[0].set("rsn_overriding", "0")
def test_rsn_override_mld(dev, apdev):
"""AP MLD and RSNE=WPA2-Personal/PMF-disabled override=WPA3-Personal/PMF-required"""
run_rsn_override_mld(dev, apdev, False)
def test_rsn_override_mld_mixed(dev, apdev):
"""AP MLD and RSNE=WPA2-Personal/PMF-disabled override=WPA3-Personal/PMF-required on one link"""
run_rsn_override_mld(dev, apdev, True)
def test_rsn_override_mld_only_sta(dev, apdev):
"""AP MLD and RSN overriding only on STA"""
run_rsn_override_mld(dev, apdev, False, only_sta=True)
def test_rsn_override_mld_too_long_elems(dev, apdev):
"""AP MLD and RSN overriding with too long elements"""
run_rsn_override_mld(dev, apdev, False, too_long_elems=True)
def run_rsn_override_mld(dev, apdev, mixed, only_sta=False,
too_long_elems=False):
with HWSimRadio(use_mlo=True) as (hapd_radio, hapd_iface), \
HWSimRadio(use_mlo=True) as (wpas_radio, wpas_iface):
wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
wpas.interface_add(wpas_iface)
passphrase = 'qwertyuiop'
ssid = "AP MLD RSN override"
params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
params['ieee80211n'] = '1'
params['ieee80211ax'] = '1'
params['ieee80211be'] = '1'
params['channel'] = '1'
params['hw_mode'] = 'g'
params['beacon_prot'] = '1'
params['sae_groups'] = '19 20'
params['sae_require_mfp'] = '1'
params['sae_pwe'] = '2'
if only_sta:
params['wpa_key_mgmt'] = 'SAE SAE-EXT-KEY'
params['rsn_pairwise'] = 'CCMP GCMP-256'
params['ieee80211w'] = '2'
elif not mixed:
params['rsn_override_key_mgmt'] = 'SAE'
params['rsn_override_key_mgmt_2'] = 'SAE-EXT-KEY'
params['rsn_override_pairwise'] = 'CCMP'
params['rsn_override_pairwise_2'] = 'GCMP-256'
params['rsn_override_mfp'] = '1'
params['rsn_override_mfp_2'] = '2'
params1 = dict(params)
if mixed:
params['wpa_key_mgmt'] = 'SAE SAE-EXT-KEY'
params['rsn_pairwise'] = 'CCMP GCMP-256'
params['ieee80211w'] = '2'
params['rsn_override_key_mgmt_2'] = 'SAE SAE-EXT-KEY'
params['rsn_override_pairwise_2'] = 'CCMP GCMP-256'
params['rsn_override_mfp_2'] = '2'
params1['rsn_override_key_mgmt_2'] = 'SAE SAE-EXT-KEY'
params1['rsn_override_pairwise_2'] = 'CCMP GCMP-256'
params1['rsn_override_mfp_2'] = '2'
hapd0 = eht_mld_enable_ap(hapd_iface, 0, params)
params1['channel'] = '6'
if too_long_elems:
params1['rsnoe_override'] = 'ddff506f9a29' + 251*'cc'
hapd1 = eht_mld_enable_ap(hapd_iface, 1, params1)
wpas.set("sae_pwe", "1")
wpas.set("rsn_overriding", "1")
wpas.connect(ssid, sae_password=passphrase, scan_freq="2412 2437",
key_mgmt="SAE-EXT-KEY", ieee80211w="2", beacon_prot="1",
pairwise="GCMP-256 CCMP", wait_connect=not too_long_elems)
if too_long_elems:
ev = wpas.wait_event(['Associated with'], timeout=10)
if ev is None:
raise Exception("Association not reported")
ev = wpas.wait_event(['EAPOL-RX'], timeout=1)
if ev is None:
raise Exception("EAPOL-Key M1 not reported")
ev = wpas.wait_event(['EAPOL-RX', 'CTRL-EVENT-DISCONNECTED'],
timeout=20)
if ev is None:
raise Exception("Disconnection not reported")
# The AP is expected to fail to send M3 due to RSNOE/RSNO2E/RSNXOE
# being too long to fit into the RSN Override Link KDE.
if 'EAPOL-RX' in ev:
raise Exception("Unexpected EAPOL-Key M3 reported")
return
eht_verify_status(wpas, hapd0, 2412, 20, is_ht=True, mld=True,
valid_links=3, active_links=3)
eht_verify_wifi_version(wpas)
traffic_test(wpas, hapd0)
traffic_test(wpas, hapd1)
if only_sta:
return
dev[0].set("rsn_overriding", "0")
dev[0].connect(ssid, psk=passphrase, key_mgmt="WPA-PSK",
scan_freq="2412 2437")
status = wpas.get_status()
logger.debug("wpas STATUS:\n" + str(status))
if status['key_mgmt'] != 'SAE-EXT-KEY' or \
'pmf' not in status or \
status['pmf'] != '2' or \
status['pairwise_cipher'] != 'GCMP-256':
raise Exception("Unexpected result for new STA")
status = dev[0].get_status()
logger.debug("dev[0] STATUS:\n" + str(status))
if status['key_mgmt'] != 'WPA2-PSK' or \
status['pairwise_cipher'] != 'CCMP':
raise Exception("Unexpected result for legacy STA")
def test_rsn_override_connect_cmd(dev, apdev):
"""RSNE=WPA2-Personal/PMF-optional override=WPA3-Personal/PMF-required using cfg80211 connect command"""
wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
wpas.interface_add("wlan5", drv_params="force_connect_cmd=1 rsn_override_in_driver=1")
check_sae_capab(wpas)
ssid = "test-rsn-override"
params = hostapd.wpa2_params(ssid=ssid,
passphrase="12345678",
ieee80211w='1')
params['rsn_override_key_mgmt'] = 'WPA-PSK-SHA256'
params['rsn_override_pairwise'] = 'CCMP GCMP-256'
params['rsn_override_mfp'] = '2'
params['beacon_prot'] = '1'
hapd = hostapd.add_ap(apdev[0], params)
wpas.set("rsn_overriding", "1")
wpas.connect(ssid, psk="12345678", key_mgmt="WPA-PSK-SHA256",
ieee80211w="2", scan_freq="2412")
def test_rsn_override_omit_rsnxe(dev, apdev):
"""RSN overriding with RSNXE explicitly omitted"""
check_sae_capab(dev[0])
ssid = "test-rsn-override"
params = hostapd.wpa2_params(ssid=ssid,
passphrase="12345678",
ieee80211w='1')
params['rsn_override_key_mgmt'] = 'SAE SAE-EXT-KEY'
params['rsn_override_pairwise'] = 'CCMP GCMP-256'
params['rsn_override_mfp'] = '2'
params['beacon_prot'] = '1'
params['sae_groups'] = '19 20'
params['sae_require_mfp'] = '1'
params['sae_pwe'] = '2'
params['ssid_protection'] = '1'
params['rsn_override_omit_rsnxe'] = '1'
hapd = hostapd.add_ap(apdev[0], params)
bssid = hapd.own_addr()
try:
dev[0].set("rsn_overriding", "1")
dev[0].scan_for_bss(bssid, freq=2412)
dev[0].set("sae_pwe", "2")
dev[0].set("sae_groups", "")
dev[0].connect(ssid, sae_password="12345678", key_mgmt="SAE",
ieee80211w="2", ssid_protection="1",
scan_freq="2412")
finally:
dev[0].set("sae_pwe", "0")
dev[0].set("rsn_overriding", "0")
def test_rsn_override_replace_ies(dev, apdev):
"""RSN overriding and replaced AP IEs"""
check_sae_capab(dev[0])
ssid = "test-rsn-override"
params = hostapd.wpa2_params(ssid=ssid,
passphrase="12345678",
ieee80211w='1')
params['rsn_override_key_mgmt'] = 'SAE'
params['rsn_override_key_mgmt_2'] = 'SAE-EXT-KEY'
params['rsn_override_pairwise'] = 'CCMP'
params['rsn_override_pairwise_2'] = 'GCMP-256'
params['rsn_override_mfp'] = '1'
params['rsn_override_mfp_2'] = '2'
params['beacon_prot'] = '1'
params['sae_groups'] = '19 20'
params['sae_require_mfp'] = '1'
params['sae_pwe'] = '2'
params['ssid_protection'] = '1'
params['rsne_override'] = '30180100000fac040100000fac040200000facff000fac020c00'
params['rsnxe_override'] = 'f40320eeee'
params['rsnoe_override'] = 'dd1c506f9a290100000fac040100000fac040200000facff000fac088c00'
params['rsno2e_override'] = 'dd1c506f9a2a0100000fac040100000fac090200000facff000fac18cc00'
params['rsnxoe_override'] = 'dd07506f9a2b20bbbb'
hapd = hostapd.add_ap(apdev[0], params)
bssid = hapd.own_addr()
try:
dev[0].set("rsn_overriding", "1")
dev[0].scan_for_bss(bssid, freq=2412)
dev[0].set("sae_pwe", "2")
dev[0].set("sae_groups", "")
dev[0].connect(ssid, sae_password="12345678", key_mgmt="SAE",
ieee80211w="2", ssid_protection="1",
scan_freq="2412")
finally:
dev[0].set("sae_pwe", "0")
dev[0].set("rsn_overriding", "0")
def test_rsn_override_rsnxe_extensibility(dev, apdev):
"""RSN overriding and RSNXE extensibility"""
check_sae_capab(dev[0])
ssid = "test-rsn-override"
params = hostapd.wpa2_params(ssid=ssid,
passphrase="12345678",
ieee80211w='1')
params['rsn_override_key_mgmt'] = 'SAE SAE-EXT-KEY'
params['rsn_override_pairwise'] = 'CCMP GCMP-256'
params['rsn_override_mfp'] = '2'
params['beacon_prot'] = '1'
params['sae_groups'] = '19 20'
params['sae_require_mfp'] = '1'
params['sae_pwe'] = '2'
params['rsnxe_override'] = 'f4182f0000ffffffffffffffffffffffffffeeeeeeeeeeeeeeee'
params['rsnxoe_override'] = 'dd1c506f9a2b2f0000ffffffffffffffffffffffffffeeeeeeeeeeeeeeee'
hapd = hostapd.add_ap(apdev[0], params)
bssid = hapd.own_addr()
try:
dev[0].set("rsn_overriding", "1")
dev[0].scan_for_bss(bssid, freq=2412)
dev[0].set("sae_pwe", "2")
dev[0].set("sae_groups", "")
dev[0].connect(ssid, sae_password="12345678", key_mgmt="SAE",
ieee80211w="2", ssid_protection="1",
scan_freq="2412")
finally:
dev[0].set("sae_pwe", "0")
dev[0].set("rsn_overriding", "0")
def test_rsn_override_sta_only(dev, apdev):
"""RSN overriding enabled only on the STA"""
check_sae_capab(dev[0])
params = hostapd.wpa2_params(ssid="test-sae",
passphrase="12345678")
params['wpa_key_mgmt'] = 'SAE'
hapd = hostapd.add_ap(apdev[0], params)
dev[0].set("sae_groups", "")
try:
dev[0].set("rsn_overriding", "1")
dev[0].connect("test-sae", psk="12345678", key_mgmt="SAE",
scan_freq="2412")
finally:
dev[0].set("rsn_overriding", "0")
def test_rsn_override_compatibility_mode(dev, apdev):
"""RSN overriding and WPA3-Personal Compatibility Mode"""
check_sae_capab(dev[0])
ssid = "test-rsn-override"
params = hostapd.wpa2_params(ssid=ssid,
passphrase="12345678")
params['rsn_override_key_mgmt'] = 'SAE'
params['rsn_override_key_mgmt_2'] = 'SAE-EXT-KEY'
params['rsn_override_pairwise'] = 'CCMP'
params['rsn_override_pairwise_2'] = 'GCMP-256'
params['rsn_override_mfp'] = '2'
params['rsn_override_mfp_2'] = '2'
params['beacon_prot'] = '1'
params['sae_groups'] = '19 20'
params['sae_require_mfp'] = '1'
params['sae_pwe'] = '2'
hapd = hostapd.add_ap(apdev[0], params)
bssid = hapd.own_addr()
try:
logger.info("RSN overriding capable STA using RSNO2E")
dev[0].set("rsn_overriding", "1")
dev[0].scan_for_bss(bssid, freq=2412)
dev[0].set("sae_pwe", "2")
dev[0].set("sae_groups", "")
dev[0].connect(ssid, sae_password="12345678",
pairwise="GCMP-256", key_mgmt="SAE-EXT-KEY",
ieee80211w="2", scan_freq="2412")
hapd.wait_sta()
dev[0].request("REMOVE_NETWORK all")
dev[0].wait_disconnected()
hapd.wait_sta_disconnect()
logger.info("RSN overriding capable STA using RSNOE")
dev[0].set("sae_pwe", "0")
dev[0].connect(ssid, sae_password="12345678",
pairwise="CCMP", key_mgmt="SAE",
ieee80211w="2", scan_freq="2412")
hapd.wait_sta()
dev[0].request("REMOVE_NETWORK all")
dev[0].wait_disconnected()
hapd.wait_sta_disconnect()
logger.info("RSN overriding capable STA using RSNE")
dev[0].connect(ssid, psk="12345678",
pairwise="CCMP", key_mgmt="WPA-PSK",
ieee80211w="0", scan_freq="2412")
hapd.wait_sta()
dev[0].request("REMOVE_NETWORK all")
dev[0].wait_disconnected()
hapd.wait_sta_disconnect()
logger.info("RSN overriding uncapable STA using RSNE")
dev[0].set("rsn_overriding", "0")
dev[0].connect(ssid, psk="12345678",
pairwise="CCMP", key_mgmt="WPA-PSK",
ieee80211w="0", scan_freq="2412")
hapd.wait_sta()
dev[0].request("REMOVE_NETWORK all")
dev[0].wait_disconnected()
hapd.wait_sta_disconnect()
finally:
dev[0].set("sae_pwe", "0")
dev[0].set("rsn_overriding", "0")

Some files were not shown because too many files have changed in this diff Show more