Compare commits

..

No commits in common. "bde17063d5e8dea453fb29c53049a09922f6d876" and "87120a5b6e149976c94f06ee73ec3ead305439a9" have entirely different histories.

264 changed files with 6932 additions and 21310 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

2
README
View file

@ -1,7 +1,7 @@
wpa_supplicant and hostapd wpa_supplicant and hostapd
-------------------------- --------------------------
Copyright (c) 2002-2024, Jouni Malinen <j@w1.fi> and contributors Copyright (c) 2002-2022, Jouni Malinen <j@w1.fi> and contributors
All Rights Reserved. All Rights Reserved.
These programs are licensed under the BSD license (the one with These programs are licensed under the BSD license (the one with

View file

@ -583,24 +583,6 @@ fi.w1.wpa_supplicant1.CreateInterface.
<h3>InterworkingSelect ( ) --> nothing</h3> <h3>InterworkingSelect ( ) --> nothing</h3>
<p>Perform Interworking (Hotspot 2.0) network selection.</p> <p>Perform Interworking (Hotspot 2.0) network selection.</p>
</li> </li>
<li>
<h3>ANQPGet ( a{sv} : args) --> nothing</h3>
<p>Send an ANQP request.</p>
<h4>Arguments</h4>
<dl>
<dt>a{sv} : args</dt>
<dd>
<table>
<tr><th>Key</th><th>Value type</th><th>Description</th><th>Required</th>
<tr><td>addr</td><td>s</td><td>Address of the BSS</td><td>Yes</td>
<tr><td>freq</td><td>u</td><td>Frequency of the BSS</td><td>No</td>
<tr><td>ids</td><td>aq</td><td>List of ANQP information IDs to query</td><td>No</td>
<tr><td>hs20_ids</td><td>ay</td><td>List of Hotspot 2.0 ANQP information IDs to query</td><td>No</td>
<tr><td>mbo_ids</td><td>ay</td><td>List of MBO ANQP information IDs to query</td><td>No</td>
</table>
</dd>
</dl>
</li>
<li> <li>
<h3>EAPLogoff ( ) --> nothing</h3> <h3>EAPLogoff ( ) --> nothing</h3>
<p>IEEE 802.1X EAPOL state machine logoff.</p> <p>IEEE 802.1X EAPOL state machine logoff.</p>
@ -883,11 +865,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>
@ -1152,12 +1129,6 @@ fi.w1.wpa_supplicant1.CreateInterface.
<li> <li>
<h3>MACAddress - ay - (read)</h3> <h3>MACAddress - ay - (read)</h3>
<p>MAC address of the interface</p> <p>MAC address of the interface</p>
</li>
<li>
<h3>SignalChange - "a{sv}" - (read)</h3>
<p>Signal and quality properties of the interface</p>
</li>
</ul> </ul>
\subsection dbus_interface_signals Signals \subsection dbus_interface_signals Signals
@ -1374,17 +1345,6 @@ fi.w1.wpa_supplicant1.CreateInterface.
<dd>URL of the terms and conditions page.</dd> <dd>URL of the terms and conditions page.</dd>
</dl> </dl>
</li> </li>
<li>
<h3>ANQPQueryDone ( s : addr, s : result )</h3>
<p>Result of an ANQP query.</p>
<dl>
<dt>s : addr</dt>
<dd>Address of the BSS targeted by the query.</dd>
<dt>s : result</dt>
<dd>Determine if the request was successful. If so fields are available in BSS.</dd>
</dl>
</li>
</ul> </ul>
@ -2225,30 +2185,6 @@ scan results.
<h3>Age - u - (read)</h3> <h3>Age - u - (read)</h3>
<p>Number of seconds since the BSS was last seen.</p> <p>Number of seconds since the BSS was last seen.</p>
</li> </li>
<li>
<h3>ANQP - a{sv} - (read)</h3>
<p>ANQP information of the BSS. Empty dictionary indicates no ANQP field. Named dictionary entries are:</p>
<table>
<tr><td>CapabilityList</td><td>ay</td></tr>
<tr><td>VenueName</td><td>ay</td></tr>
<tr><td>NetworkAuthType</td><td>ay</td></tr>
<tr><td>RoamingConsortium</td><td>ay</td></tr>
<tr><td>IPAddrTypeAvailability</td><td>ay</td></tr>
<tr><td>NAIRealm</td><td>ay</td></tr>
<tr><td>3GPP</td><td>ay</td></tr>
<tr><td>DomainName</td><td>ay</td></tr>
<tr><td>FilsRealmInfo</td><td>ay</td></tr>
<tr><td>HS20CapabilityList</td><td>ay</td></tr>
<tr><td>HS20OperatorFriendlyName</td><td>ay</td></tr>
<tr><td>HS20WanMetrics</td><td>ay</td></tr>
<tr><td>HS20ConnectionCapability</td><td>ay</td></tr>
<tr><td>HS20OperatingClass</td><td>ay</td></tr>
<tr><td>HS20OSUProvidersList</td><td>ay</td></tr>
<tr><td>HS20OperatorIconMetadata</td><td>ay</td></tr>
<tr><td>HS20OSUProvidersNAIList</td><td>ay</td></tr>
</table>
<p>Unnamed ANQP elements have a generic entry name 'anqp[id]' where 'id' is the InfoID of the ANQP element as described in IEEE Std 802.11-2020, Table 9-331 (ANQP-element definitions).</p>
</li>
</ul> </ul>
\subsection dbus_bss_signals Signals \subsection dbus_bss_signals Signals

View file

@ -31,7 +31,7 @@ PROJECT_NAME = "wpa_supplicant / hostapd"
# This could be handy for archiving the generated documentation or # This could be handy for archiving the generated documentation or
# if some version control system is used. # if some version control system is used.
PROJECT_NUMBER = 2.11 PROJECT_NUMBER = 2.10
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put. # base path where the generated documentation will be put.

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

@ -154,7 +154,6 @@ OBJS += src/utils/crc32.c
OBJS += src/common/ieee802_11_common.c OBJS += src/common/ieee802_11_common.c
OBJS += src/common/wpa_common.c OBJS += src/common/wpa_common.c
OBJS += src/common/hw_features_common.c OBJS += src/common/hw_features_common.c
OBJS += src/common/ptksa_cache.c
OBJS += src/eapol_auth/eapol_auth_sm.c OBJS += src/eapol_auth/eapol_auth_sm.c
@ -595,6 +594,7 @@ NEED_HMAC_SHA256_KDF=y
NEED_HMAC_SHA384_KDF=y NEED_HMAC_SHA384_KDF=y
NEED_SHA256=y NEED_SHA256=y
NEED_SHA384=y NEED_SHA384=y
OBJS += src/common/ptksa_cache.c
endif endif
ifdef CONFIG_EAP_IKEV2 ifdef CONFIG_EAP_IKEV2
@ -647,11 +647,6 @@ ifdef CHAP
OBJS += src/eap_common/chap.c OBJS += src/eap_common/chap.c
endif endif
ifdef CONFIG_RADIUS_TLS
TLS_FUNCS=y
L_CFLAGS += -DCONFIG_RADIUS_TLS
endif
ifdef TLS_FUNCS ifdef TLS_FUNCS
NEED_DES=y NEED_DES=y
# Shared TLS functions (needed for EAP_TLS, EAP_PEAP, and EAP_TTLS) # Shared TLS functions (needed for EAP_TLS, EAP_PEAP, and EAP_TTLS)
@ -1051,7 +1046,6 @@ OBJS += src/ap/wmm.c
OBJS += src/ap/ap_list.c OBJS += src/ap/ap_list.c
OBJS += src/ap/comeback_token.c OBJS += src/ap/comeback_token.c
OBJS += src/pasn/pasn_responder.c OBJS += src/pasn/pasn_responder.c
OBJS += src/pasn/pasn_common.c
OBJS += src/ap/ieee802_11.c OBJS += src/ap/ieee802_11.c
OBJS += src/ap/hw_features.c OBJS += src/ap/hw_features.c
OBJS += src/ap/dfs.c OBJS += src/ap/dfs.c

View file

@ -1,42 +1,5 @@
ChangeLog for hostapd ChangeLog for hostapd
2024-07-20 - v2.11
* Wi-Fi Easy Connect
- add support for DPP release 3
- allow Configurator parameters to be provided during config exchange
* HE/IEEE 802.11ax/Wi-Fi 6
- various fixes
* EHT/IEEE 802.11be/Wi-Fi 7
- add preliminary support
* SAE: add support for fetching the password from a RADIUS server
* support OpenSSL 3.0 API changes
* support background radar detection and CAC with some additional
drivers
* support RADIUS ACL/PSK check during 4-way handshake (wpa_psk_radius=3)
* EAP-SIM/AKA: support IMSI privacy
* improve 4-way handshake operations
- use Secure=1 in message 3 during PTK rekeying
* OCV: do not check Frequency Segment 1 Channel Number for 160 MHz cases
to avoid interoperability issues
* support new SAE AKM suites with variable length keys
* support new AKM for 802.1X/EAP with SHA384
* extend PASN support for secure ranging
* FT: Use SHA256 to derive PMKID for AKM 00-0F-AC:3 (FT-EAP)
- this is based on additional details being added in the IEEE 802.11
standard
- the new implementation is not backwards compatible
* improved ACS to cover additional channel types/bandwidths
* extended Multiple BSSID support
* fix beacon protection with FT protocol (incorrect BIGTK was provided)
* support unsynchronized service discovery (USD)
* add preliminary support for RADIUS/TLS
* add support for explicit SSID protection in 4-way handshake
(a mitigation for CVE-2023-52424; disabled by default for now, can be
enabled with ssid_protection=1)
* fix SAE H2E rejected groups validation to avoid downgrade attacks
* use stricter validation for some RADIUS messages
* a large number of other fixes, cleanup, and extensions
2022-01-16 - v2.10 2022-01-16 - v2.10
* SAE changes * SAE changes
- improved protection against side channel attacks - improved protection against side channel attacks

View file

@ -84,7 +84,6 @@ OBJS += ../src/ap/beacon.o
OBJS += ../src/ap/bss_load.o OBJS += ../src/ap/bss_load.o
OBJS += ../src/ap/neighbor_db.o OBJS += ../src/ap/neighbor_db.o
OBJS += ../src/ap/rrm.o OBJS += ../src/ap/rrm.o
OBJS += ../src/common/ptksa_cache.o
OBJS_c = hostapd_cli.o OBJS_c = hostapd_cli.o
OBJS_c += ../src/common/wpa_ctrl.o OBJS_c += ../src/common/wpa_ctrl.o
@ -621,6 +620,7 @@ NEED_HMAC_SHA256_KDF=y
NEED_HMAC_SHA384_KDF=y NEED_HMAC_SHA384_KDF=y
NEED_SHA256=y NEED_SHA256=y
NEED_SHA384=y NEED_SHA384=y
OBJS += ../src/common/ptksa_cache.o
endif endif
ifdef CONFIG_EAP_IKEV2 ifdef CONFIG_EAP_IKEV2
@ -682,11 +682,6 @@ ifdef CHAP
OBJS += ../src/eap_common/chap.o OBJS += ../src/eap_common/chap.o
endif endif
ifdef CONFIG_RADIUS_TLS
TLS_FUNCS=y
CFLAGS += -DCONFIG_RADIUS_TLS
endif
ifdef TLS_FUNCS ifdef TLS_FUNCS
NEED_DES=y NEED_DES=y
# Shared TLS functions (needed for EAP_TLS, EAP_PEAP, and EAP_TTLS) # Shared TLS functions (needed for EAP_TLS, EAP_PEAP, and EAP_TTLS)
@ -1197,7 +1192,6 @@ OBJS += ../src/ap/wmm.o
OBJS += ../src/ap/ap_list.o OBJS += ../src/ap/ap_list.o
OBJS += ../src/ap/comeback_token.o OBJS += ../src/ap/comeback_token.o
OBJS += ../src/pasn/pasn_responder.o OBJS += ../src/pasn/pasn_responder.o
OBJS += ../src/pasn/pasn_common.o
OBJS += ../src/ap/ieee802_11.o OBJS += ../src/ap/ieee802_11.o
OBJS += ../src/ap/hw_features.o OBJS += ../src/ap/hw_features.o
OBJS += ../src/ap/dfs.o OBJS += ../src/ap/dfs.o

View file

@ -2,7 +2,7 @@ hostapd - user space IEEE 802.11 AP and IEEE 802.1X/WPA/WPA2/EAP
Authenticator and RADIUS authentication server Authenticator and RADIUS authentication server
================================================================ ================================================================
Copyright (c) 2002-2024, Jouni Malinen <j@w1.fi> and contributors Copyright (c) 2002-2022, Jouni Malinen <j@w1.fi> and contributors
All Rights Reserved. All Rights Reserved.
This program is licensed under the BSD license (the one with This program is licensed under the BSD license (the one with

View file

@ -121,9 +121,6 @@ CONFIG_PKCS12=y
# Build IPv6 support for RADIUS operations # Build IPv6 support for RADIUS operations
CONFIG_IPV6=y CONFIG_IPV6=y
# Include support fo RADIUS/TLS into the RADIUS client
#CONFIG_RADIUS_TLS=y
# IEEE Std 802.11r-2008 (Fast BSS Transition) # IEEE Std 802.11r-2008 (Fast BSS Transition)
#CONFIG_IEEE80211R=y #CONFIG_IEEE80211R=y

View file

@ -1678,8 +1678,6 @@ static int parse_anqp_elem(struct hostapd_bss_config *bss, char *buf, int line)
return 0; return 0;
} }
#endif /* CONFIG_INTERWORKING */
static int parse_qos_map_set(struct hostapd_bss_config *bss, static int parse_qos_map_set(struct hostapd_bss_config *bss,
char *buf, int line) char *buf, int line)
@ -1721,6 +1719,8 @@ static int parse_qos_map_set(struct hostapd_bss_config *bss,
return 0; return 0;
} }
#endif /* CONFIG_INTERWORKING */
#ifdef CONFIG_HS20 #ifdef CONFIG_HS20
static int hs20_parse_conn_capab(struct hostapd_bss_config *bss, char *buf, static int hs20_parse_conn_capab(struct hostapd_bss_config *bss, char *buf,
@ -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)
@ -2574,27 +2549,6 @@ static int hostapd_config_fill(struct hostapd_config *conf,
bss->ap_max_inactivity = atoi(pos); bss->ap_max_inactivity = atoi(pos);
} else if (os_strcmp(buf, "skip_inactivity_poll") == 0) { } else if (os_strcmp(buf, "skip_inactivity_poll") == 0) {
bss->skip_inactivity_poll = atoi(pos); bss->skip_inactivity_poll = atoi(pos);
} else if (os_strcmp(buf, "bss_max_idle") == 0) {
int val = atoi(pos);
if (val < 0 || val > 2) {
wpa_printf(MSG_ERROR,
"Line %d: Invalid bss_max_idle value", line);
return 1;
}
bss->bss_max_idle = val;
} else if (os_strcmp(buf, "max_acceptable_idle_period") == 0) {
bss->max_acceptable_idle_period = atoi(pos);
} else if (os_strcmp(buf, "no_disconnect_on_group_keyerror") == 0) {
int val = atoi(pos);
if (val < 0 || val > 1) {
wpa_printf(MSG_ERROR,
"Line %d: Invalid no_disconnect_on_group_keyerror",
line);
return 1;
}
bss->no_disconnect_on_group_keyerror = val;
} else if (os_strcmp(buf, "config_id") == 0) { } else if (os_strcmp(buf, "config_id") == 0) {
os_free(bss->config_id); os_free(bss->config_id);
bss->config_id = os_strdup(pos); bss->config_id = os_strdup(pos);
@ -2915,37 +2869,6 @@ static int hostapd_config_fill(struct hostapd_config *conf,
os_free(bss->radius->auth_server->shared_secret); os_free(bss->radius->auth_server->shared_secret);
bss->radius->auth_server->shared_secret = (u8 *) os_strdup(pos); bss->radius->auth_server->shared_secret = (u8 *) os_strdup(pos);
bss->radius->auth_server->shared_secret_len = len; bss->radius->auth_server->shared_secret_len = len;
} else if (bss->radius->auth_server &&
os_strcmp(buf, "auth_server_type") == 0) {
if (os_strcmp(pos, "UDP") == 0) {
bss->radius->auth_server->tls = false;
#ifdef CONFIG_RADIUS_TLS
} else if (os_strcmp(pos, "TLS") == 0) {
bss->radius->auth_server->tls = true;
#endif /* CONFIG_RADIUS_TLS */
} else {
wpa_printf(MSG_ERROR, "Line %d: unsupported RADIUS type '%s'",
line, pos);
return 1;
}
#ifdef CONFIG_RADIUS_TLS
} else if (bss->radius->auth_server &&
os_strcmp(buf, "auth_server_ca_cert") == 0) {
os_free(bss->radius->auth_server->ca_cert);
bss->radius->auth_server->ca_cert = os_strdup(pos);
} else if (bss->radius->auth_server &&
os_strcmp(buf, "auth_server_client_cert") == 0) {
os_free(bss->radius->auth_server->client_cert);
bss->radius->auth_server->client_cert = os_strdup(pos);
} else if (bss->radius->auth_server &&
os_strcmp(buf, "auth_server_private_key") == 0) {
os_free(bss->radius->auth_server->private_key);
bss->radius->auth_server->private_key = os_strdup(pos);
} else if (bss->radius->auth_server &&
os_strcmp(buf, "auth_server_private_key_passwd") == 0) {
os_free(bss->radius->auth_server->private_key_passwd);
bss->radius->auth_server->private_key_passwd = os_strdup(pos);
#endif /* CONFIG_RADIUS_TLS */
} else if (os_strcmp(buf, "acct_server_addr") == 0) { } else if (os_strcmp(buf, "acct_server_addr") == 0) {
if (hostapd_config_read_radius_addr( if (hostapd_config_read_radius_addr(
&bss->radius->acct_servers, &bss->radius->acct_servers,
@ -2980,42 +2903,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
os_free(bss->radius->acct_server->shared_secret); os_free(bss->radius->acct_server->shared_secret);
bss->radius->acct_server->shared_secret = (u8 *) os_strdup(pos); bss->radius->acct_server->shared_secret = (u8 *) os_strdup(pos);
bss->radius->acct_server->shared_secret_len = len; bss->radius->acct_server->shared_secret_len = len;
} else if (bss->radius->acct_server &&
os_strcmp(buf, "acct_server_type") == 0) {
if (os_strcmp(pos, "UDP") == 0) {
bss->radius->acct_server->tls = false;
#ifdef CONFIG_RADIUS_TLS
} else if (os_strcmp(pos, "TLS") == 0) {
bss->radius->acct_server->tls = true;
#endif /* CONFIG_RADIUS_TLS */
} else {
wpa_printf(MSG_ERROR, "Line %d: unsupported RADIUS type '%s'",
line, pos);
return 1;
}
#ifdef CONFIG_RADIUS_TLS
} else if (bss->radius->acct_server &&
os_strcmp(buf, "acct_server_ca_cert") == 0) {
os_free(bss->radius->acct_server->ca_cert);
bss->radius->acct_server->ca_cert = os_strdup(pos);
} else if (bss->radius->acct_server &&
os_strcmp(buf, "acct_server_client_cert") == 0) {
os_free(bss->radius->acct_server->client_cert);
bss->radius->acct_server->client_cert = os_strdup(pos);
} else if (bss->radius->acct_server &&
os_strcmp(buf, "acct_server_private_key") == 0) {
os_free(bss->radius->acct_server->private_key);
bss->radius->acct_server->private_key = os_strdup(pos);
} else if (bss->radius->acct_server &&
os_strcmp(buf, "acct_server_private_key_passwd") == 0) {
os_free(bss->radius->acct_server->private_key_passwd);
bss->radius->acct_server->private_key_passwd = os_strdup(pos);
#endif /* CONFIG_RADIUS_TLS */
} else if (os_strcmp(buf, "radius_retry_primary_interval") == 0) { } else if (os_strcmp(buf, "radius_retry_primary_interval") == 0) {
bss->radius->retry_primary_interval = atoi(pos); bss->radius->retry_primary_interval = atoi(pos);
} else if (os_strcmp(buf,
"radius_require_message_authenticator") == 0) {
bss->radius_require_message_authenticator = atoi(pos);
} else if (os_strcmp(buf, "radius_acct_interim_interval") == 0) { } else if (os_strcmp(buf, "radius_acct_interim_interval") == 0) {
bss->acct_interim_interval = atoi(pos); bss->acct_interim_interval = atoi(pos);
} else if (os_strcmp(buf, "radius_request_cui") == 0) { } else if (os_strcmp(buf, "radius_request_cui") == 0) {
@ -3181,16 +3070,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 +3101,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 +3122,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 +3556,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;
@ -3755,8 +3602,6 @@ static int hostapd_config_fill(struct hostapd_config *conf,
} }
} else if (os_strcmp(buf, "require_ht") == 0) { } else if (os_strcmp(buf, "require_ht") == 0) {
conf->require_ht = atoi(pos); conf->require_ht = atoi(pos);
} else if (os_strcmp(buf, "ht_vht_twt_responder") == 0) {
conf->ht_vht_twt_responder = atoi(pos);
} else if (os_strcmp(buf, "obss_interval") == 0) { } else if (os_strcmp(buf, "obss_interval") == 0) {
conf->obss_interval = atoi(pos); conf->obss_interval = atoi(pos);
#ifdef CONFIG_IEEE80211AC #ifdef CONFIG_IEEE80211AC
@ -4351,10 +4196,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
bss->gas_frag_limit = val; bss->gas_frag_limit = val;
} else if (os_strcmp(buf, "gas_comeback_delay") == 0) { } else if (os_strcmp(buf, "gas_comeback_delay") == 0) {
bss->gas_comeback_delay = atoi(pos); bss->gas_comeback_delay = atoi(pos);
#endif /* CONFIG_INTERWORKING */
} else if (os_strcmp(buf, "qos_map_set") == 0) { } else if (os_strcmp(buf, "qos_map_set") == 0) {
if (parse_qos_map_set(bss, pos, line) < 0) if (parse_qos_map_set(bss, pos, line) < 0)
return 1; return 1;
#endif /* CONFIG_INTERWORKING */
#ifdef CONFIG_RADIUS_TEST #ifdef CONFIG_RADIUS_TEST
} else if (os_strcmp(buf, "dump_msk_file") == 0) { } else if (os_strcmp(buf, "dump_msk_file") == 0) {
os_free(bss->dump_msk_file); os_free(bss->dump_msk_file);
@ -4529,29 +4374,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,13 +4452,8 @@ 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) {
if (parse_wpabuf_hex(line, buf, &bss->presp_elements, pos))
return 1;
#endif /* CONFIG_TESTING_OPTIONS */ #endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_SAE #ifdef CONFIG_SAE
} else if (os_strcmp(buf, "sae_password") == 0) { } else if (os_strcmp(buf, "sae_password") == 0) {
@ -4766,10 +4600,6 @@ static int hostapd_config_fill(struct hostapd_config *conf,
WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE | WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE |
WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE | WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE |
WLAN_RRM_CAPS_BEACON_REPORT_TABLE; WLAN_RRM_CAPS_BEACON_REPORT_TABLE;
} else if (os_strcmp(buf, "rrm_link_measurement_report") == 0) {
if (atoi(pos))
bss->radio_measurements[0] |=
WLAN_RRM_CAPS_LINK_MEASUREMENT;
} else if (os_strcmp(buf, "gas_address3") == 0) { } else if (os_strcmp(buf, "gas_address3") == 0) {
bss->gas_address3 = atoi(pos); bss->gas_address3 = atoi(pos);
} else if (os_strcmp(buf, "stationary_ap") == 0) { } else if (os_strcmp(buf, "stationary_ap") == 0) {
@ -4910,36 +4740,6 @@ static int hostapd_config_fill(struct hostapd_config *conf,
} }
bss->multi_ap = val; bss->multi_ap = val;
} else if (os_strcmp(buf, "multi_ap_profile") == 0) {
int val = atoi(pos);
if (val < MULTI_AP_PROFILE_1 || val > MULTI_AP_PROFILE_MAX) {
wpa_printf(MSG_ERROR,
"Line %d: Invalid multi_ap_profile '%s'",
line, buf);
return -1;
}
bss->multi_ap_profile = val;
} else if (os_strcmp(buf, "multi_ap_client_disallow") == 0) {
int val = atoi(pos);
if (val < 0 || val > 3) {
wpa_printf(MSG_ERROR,
"Line %d: Invalid multi_ap_client_allow '%s'",
line, buf);
return -1;
}
bss->multi_ap_client_disallow = val;
} else if (os_strcmp(buf, "multi_ap_vlanid") == 0) {
int val = atoi(pos);
if (val < 0 || val > MAX_VLAN_ID) {
wpa_printf(MSG_ERROR,
"Line %d: Invalid multi_ap_vlan_id '%s'",
line, buf);
return -1;
}
bss->multi_ap_vlanid = val;
} else if (os_strcmp(buf, "rssi_reject_assoc_rssi") == 0) { } else if (os_strcmp(buf, "rssi_reject_assoc_rssi") == 0) {
conf->rssi_reject_assoc_rssi = atoi(pos); conf->rssi_reject_assoc_rssi = atoi(pos);
} else if (os_strcmp(buf, "rssi_reject_assoc_timeout") == 0) { } else if (os_strcmp(buf, "rssi_reject_assoc_timeout") == 0) {
@ -5122,12 +4922,6 @@ static int hostapd_config_fill(struct hostapd_config *conf,
return 1; return 1;
} else if (os_strcmp(buf, "rnr") == 0) { } else if (os_strcmp(buf, "rnr") == 0) {
bss->rnr = atoi(pos); bss->rnr = atoi(pos);
} else if (os_strcmp(buf, "ssid_protection") == 0) {
int val = atoi(pos);
if (val < 0 || val > 1)
return 1;
bss->ssid_protection = val;
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
} else if (os_strcmp(buf, "ieee80211be") == 0) { } else if (os_strcmp(buf, "ieee80211be") == 0) {
conf->ieee80211be = atoi(pos); conf->ieee80211be = atoi(pos);
@ -5158,6 +4952,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
conf->punct_acs_threshold = val; conf->punct_acs_threshold = val;
} else if (os_strcmp(buf, "mld_ap") == 0) { } else if (os_strcmp(buf, "mld_ap") == 0) {
bss->mld_ap = !!atoi(pos); bss->mld_ap = !!atoi(pos);
} else if (os_strcmp(buf, "mld_id") == 0) {
bss->mld_id = atoi(pos);
} else if (os_strcmp(buf, "mld_addr") == 0) { } else if (os_strcmp(buf, "mld_addr") == 0) {
if (hwaddr_aton(pos, bss->mld_addr)) { if (hwaddr_aton(pos, bss->mld_addr)) {
wpa_printf(MSG_ERROR, "Line %d: Invalid mld_addr", wpa_printf(MSG_ERROR, "Line %d: Invalid mld_addr",

View file

@ -1309,8 +1309,6 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd)
hostapd_disassoc_deny_mac(hapd); hostapd_disassoc_deny_mac(hapd);
} else if (os_strcasecmp(cmd, "accept_mac_file") == 0) { } else if (os_strcasecmp(cmd, "accept_mac_file") == 0) {
hostapd_disassoc_accept_mac(hapd); hostapd_disassoc_accept_mac(hapd);
} else if (os_strcasecmp(cmd, "ssid") == 0) {
hostapd_neighbor_sync_own_report(hapd);
} else if (os_strncmp(cmd, "wme_ac_", 7) == 0 || } else if (os_strncmp(cmd, "wme_ac_", 7) == 0 ||
os_strncmp(cmd, "wmm_ac_", 7) == 0) { os_strncmp(cmd, "wmm_ac_", 7) == 0) {
hapd->parameter_set_count++; hapd->parameter_set_count++;
@ -1944,7 +1942,7 @@ static int hostapd_ctrl_iface_data_test_config(struct hostapd_data *hapd,
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
if (hapd->conf->mld_ap) if (hapd->conf->mld_ap)
addr = hapd->mld->mld_addr; addr = hapd->mld_addr;
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
hapd->l2_test = l2_packet_init(ifname, addr, hapd->l2_test = l2_packet_init(ifname, addr,
ETHERTYPE_IP, hostapd_data_test_rx, ETHERTYPE_IP, hostapd_data_test_rx,
@ -2454,31 +2452,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)
{ {
@ -2502,21 +2475,6 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params,
bw_idx[bw] != params->bandwidth) bw_idx[bw] != params->bandwidth)
return -1; return -1;
} }
} else { /* Non-6 GHz channel */
/* An EHT STA is also an HE STA as defined in
* IEEE P802.11be/D5.0, 4.3.16a. */
if (params->he_enabled || params->eht_enabled) {
params->he_enabled = 1;
/* An HE STA is also a VHT STA if operating in the 5 GHz
* band and an HE STA is also an HT STA in the 2.4 GHz
* band as defined in IEEE Std 802.11ax-2021, 4.3.15a.
* A VHT STA is an HT STA as defined in IEEE
* Std 802.11, 4.3.15. */
if (IS_5GHZ(params->freq))
params->vht_enabled = 1;
params->ht_enabled = 1;
}
} }
switch (params->bandwidth) { switch (params->bandwidth) {
@ -2680,8 +2638,6 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
unsigned int i; unsigned int i;
int bandwidth; int bandwidth;
u8 chan; u8 chan;
unsigned int num_err = 0;
int err = 0;
ret = hostapd_parse_csa_settings(pos, &settings); ret = hostapd_parse_csa_settings(pos, &settings);
if (ret) if (ret)
@ -2693,15 +2649,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) {
@ -2764,128 +2711,29 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
settings.freq_params.center_freq1); settings.freq_params.center_freq1);
/* Perform CAC and switch channel */ /* Perform CAC and switch channel */
iface->is_ch_switch_dfs = true;
hostapd_switch_channel_fallback(iface, &settings.freq_params); hostapd_switch_channel_fallback(iface, &settings.freq_params);
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 */
hostapd_chan_switch_config(iface->bss[i], hostapd_chan_switch_config(iface->bss[i],
&settings.freq_params); &settings.freq_params);
err = hostapd_switch_channel(iface->bss[i], &settings); ret = hostapd_switch_channel(iface->bss[i], &settings);
if (err) { if (ret) {
ret = err; /* FIX: What do we do if CSA fails in the middle of
num_err++; * submitting multi-BSS CSA requests? */
return ret;
} }
} }
return (iface->num_bss == num_err) ? ret : 0;
#else /* NEED_AP_MLME */
return -1;
#endif /* NEED_AP_MLME */
}
#ifdef CONFIG_IEEE80211AX
static int hostapd_ctrl_iface_color_change(struct hostapd_iface *iface,
const char *pos)
{
#ifdef NEED_AP_MLME
struct cca_settings settings;
struct hostapd_data *hapd = iface->bss[0];
int ret, color;
unsigned int i;
char *end;
os_memset(&settings, 0, sizeof(settings));
color = strtol(pos, &end, 10);
if (pos == end || color < 0 || color > 63) {
wpa_printf(MSG_ERROR, "color_change: Invalid color provided");
return -1;
}
/* Color value is expected to be [1-63]. If 0 comes, assumption is this
* is to disable the color. In this case no need to do CCA, just
* changing Beacon frames is sufficient. */
if (color == 0) {
if (iface->conf->he_op.he_bss_color_disabled) {
wpa_printf(MSG_ERROR,
"color_change: Color is already disabled");
return -1;
}
iface->conf->he_op.he_bss_color_disabled = 1;
for (i = 0; i < iface->num_bss; i++)
ieee802_11_set_beacon(iface->bss[i]);
return 0;
}
if (color == iface->conf->he_op.he_bss_color) {
if (!iface->conf->he_op.he_bss_color_disabled) {
wpa_printf(MSG_ERROR,
"color_change: Provided color is already set");
return -1;
}
iface->conf->he_op.he_bss_color_disabled = 0;
for (i = 0; i < iface->num_bss; i++)
ieee802_11_set_beacon(iface->bss[i]);
return 0;
}
if (hapd->cca_in_progress) {
wpa_printf(MSG_ERROR,
"color_change: CCA is already in progress");
return -1;
}
iface->conf->he_op.he_bss_color_disabled = 0;
for (i = 0; i < iface->num_bss; i++) {
struct hostapd_data *bss = iface->bss[i];
hostapd_cleanup_cca_params(bss);
bss->cca_color = color;
bss->cca_count = 10;
if (hostapd_fill_cca_settings(bss, &settings)) {
wpa_printf(MSG_DEBUG,
"color_change: Filling CCA settings failed for color: %d\n",
color);
hostapd_cleanup_cca_params(bss);
continue;
}
wpa_printf(MSG_DEBUG, "Setting user selected color: %d", color);
ret = hostapd_drv_switch_color(bss, &settings);
if (ret)
hostapd_cleanup_cca_params(bss);
free_beacon_data(&settings.beacon_cca);
free_beacon_data(&settings.beacon_after);
}
return 0; return 0;
#else /* NEED_AP_MLME */ #else /* NEED_AP_MLME */
return -1; return -1;
#endif /* NEED_AP_MLME */ #endif /* NEED_AP_MLME */
} }
#endif /* CONFIG_IEEE80211AX */
static u8 hostapd_maxnss(struct hostapd_data *hapd, struct sta_info *sta) static u8 hostapd_maxnss(struct hostapd_data *hapd, struct sta_info *sta)
@ -3355,26 +3203,6 @@ static int hostapd_ctrl_iface_req_beacon(struct hostapd_data *hapd,
} }
static int hostapd_ctrl_iface_req_link_measurement(struct hostapd_data *hapd,
const char *cmd, char *reply,
size_t reply_size)
{
u8 addr[ETH_ALEN];
int ret;
if (hwaddr_aton(cmd, addr)) {
wpa_printf(MSG_ERROR,
"CTRL: REQ_LINK_MEASUREMENT: Invalid MAC address");
return -1;
}
ret = hostapd_send_link_measurement_req(hapd, addr);
if (ret >= 0)
ret = os_snprintf(reply, reply_size, "%d", ret);
return ret;
}
static int hostapd_ctrl_iface_show_neighbor(struct hostapd_data *hapd, static int hostapd_ctrl_iface_show_neighbor(struct hostapd_data *hapd,
char *buf, size_t buflen) char *buf, size_t buflen)
{ {
@ -3645,8 +3473,10 @@ static int hostapd_ctrl_iface_enable_mld(struct hostapd_iface *iface)
for (i = 0; i < iface->interfaces->count; ++i) { for (i = 0; i < iface->interfaces->count; ++i) {
struct hostapd_iface *h_iface = iface->interfaces->iface[i]; struct hostapd_iface *h_iface = iface->interfaces->iface[i];
struct hostapd_data *h_hapd = h_iface->bss[0]; struct hostapd_data *h_hapd = h_iface->bss[0];
struct hostapd_bss_config *h_conf = h_hapd->conf;
if (!hostapd_is_ml_partner(h_hapd, iface->bss[0])) if (!h_conf->mld_ap ||
h_conf->mld_id != iface->bss[0]->conf->mld_id)
continue; continue;
if (hostapd_enable_iface(h_iface)) { if (hostapd_enable_iface(h_iface)) {
@ -3670,6 +3500,7 @@ static void hostapd_disable_iface_bss(struct hostapd_iface *iface)
static int hostapd_ctrl_iface_disable_mld(struct hostapd_iface *iface) static int hostapd_ctrl_iface_disable_mld(struct hostapd_iface *iface)
{ {
unsigned int i; unsigned int i;
struct hostapd_iface *first_iface = NULL;
if (!iface || !iface->bss[0]->conf->mld_ap) { if (!iface || !iface->bss[0]->conf->mld_ap) {
wpa_printf(MSG_ERROR, wpa_printf(MSG_ERROR,
@ -3683,19 +3514,32 @@ static int hostapd_ctrl_iface_disable_mld(struct hostapd_iface *iface)
for (i = 0; i < iface->interfaces->count; ++i) { for (i = 0; i < iface->interfaces->count; ++i) {
struct hostapd_iface *h_iface = iface->interfaces->iface[i]; struct hostapd_iface *h_iface = iface->interfaces->iface[i];
struct hostapd_data *h_hapd = h_iface->bss[0]; struct hostapd_data *h_hapd = h_iface->bss[0];
struct hostapd_bss_config *h_conf = h_hapd->conf;
if (!hostapd_is_ml_partner(h_hapd, iface->bss[0])) if (!h_conf->mld_ap ||
h_conf->mld_id != iface->bss[0]->conf->mld_id)
continue; continue;
if (!h_hapd->mld_first_bss) {
first_iface = h_iface;
continue;
}
hostapd_disable_iface_bss(iface); hostapd_disable_iface_bss(iface);
} }
if (first_iface)
hostapd_disable_iface_bss(first_iface);
/* Then, fully disable interfaces */ /* Then, fully disable interfaces */
for (i = 0; i < iface->interfaces->count; ++i) { for (i = 0; i < iface->interfaces->count; ++i) {
struct hostapd_iface *h_iface = iface->interfaces->iface[i]; struct hostapd_iface *h_iface = iface->interfaces->iface[i];
struct hostapd_data *h_hapd = h_iface->bss[0]; struct hostapd_data *h_hapd = h_iface->bss[0];
struct hostapd_bss_config *h_conf = h_hapd->conf;
if (!hostapd_is_ml_partner(h_hapd, iface->bss[0])) if (!h_conf->mld_ap ||
h_conf->mld_id != iface->bss[0]->conf->mld_id ||
!h_hapd->mld_first_bss)
continue; continue;
if (hostapd_disable_iface(h_iface)) { if (hostapd_disable_iface(h_iface)) {
@ -3704,6 +3548,11 @@ static int hostapd_ctrl_iface_disable_mld(struct hostapd_iface *iface)
} }
} }
if (first_iface && hostapd_disable_iface(first_iface)) {
wpa_printf(MSG_ERROR, "Disabling AP MLD failed");
return -1;
}
return 0; return 0;
} }
@ -3745,7 +3594,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 +3627,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 +3648,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 +3731,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 +3764,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 +3772,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:
@ -4314,11 +4151,6 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
} else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) { } else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) {
if (hostapd_ctrl_iface_chan_switch(hapd->iface, buf + 12)) if (hostapd_ctrl_iface_chan_switch(hapd->iface, buf + 12))
reply_len = -1; reply_len = -1;
#ifdef CONFIG_IEEE80211AX
} else if (os_strncmp(buf, "COLOR_CHANGE ", 13) == 0) {
if (hostapd_ctrl_iface_color_change(hapd->iface, buf + 13))
reply_len = -1;
#endif /* CONFIG_IEEE80211AX */
} else if (os_strncmp(buf, "NOTIFY_CW_CHANGE ", 17) == 0) { } else if (os_strncmp(buf, "NOTIFY_CW_CHANGE ", 17) == 0) {
if (hostapd_ctrl_iface_notify_cw_change(hapd, buf + 17)) if (hostapd_ctrl_iface_notify_cw_change(hapd, buf + 17))
reply_len = -1; reply_len = -1;
@ -4370,9 +4202,6 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
} else if (os_strncmp(buf, "REQ_BEACON ", 11) == 0) { } else if (os_strncmp(buf, "REQ_BEACON ", 11) == 0) {
reply_len = hostapd_ctrl_iface_req_beacon(hapd, buf + 11, reply_len = hostapd_ctrl_iface_req_beacon(hapd, buf + 11,
reply, reply_size); reply, reply_size);
} else if (os_strncmp(buf, "REQ_LINK_MEASUREMENT ", 21) == 0) {
reply_len = hostapd_ctrl_iface_req_link_measurement(
hapd, buf + 21, reply, reply_size);
} else if (os_strcmp(buf, "DRIVER_FLAGS") == 0) { } else if (os_strcmp(buf, "DRIVER_FLAGS") == 0) {
reply_len = hostapd_ctrl_driver_flags(hapd->iface, reply, reply_len = hostapd_ctrl_driver_flags(hapd->iface, reply,
reply_size); reply_size);
@ -4734,360 +4563,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 +4695,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 +4749,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);
@ -5872,7 +5358,7 @@ static void hostapd_global_ctrl_iface_receive(int sock, void *eloop_ctx,
reply_len = -1; reply_len = -1;
} else if (os_strncmp(buf, "INTERFACES", 10) == 0) { } else if (os_strncmp(buf, "INTERFACES", 10) == 0) {
reply_len = hostapd_global_ctrl_iface_interfaces( reply_len = hostapd_global_ctrl_iface_interfaces(
interfaces, buf + 10, reply, reply_size); interfaces, buf + 10, reply, sizeof(buffer));
} else if (os_strcmp(buf, "TERMINATE") == 0) { } else if (os_strcmp(buf, "TERMINATE") == 0) {
eloop_terminate(); eloop_terminate();
} else { } else {

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

@ -141,9 +141,6 @@ CONFIG_PKCS12=y
# Build IPv6 support for RADIUS operations # Build IPv6 support for RADIUS operations
CONFIG_IPV6=y CONFIG_IPV6=y
# Include support fo RADIUS/TLS into the RADIUS client
#CONFIG_RADIUS_TLS=y
# IEEE Std 802.11r-2008 (Fast BSS Transition) # IEEE Std 802.11r-2008 (Fast BSS Transition)
#CONFIG_IEEE80211R=y #CONFIG_IEEE80211R=y

View file

@ -522,25 +522,6 @@ wmm_ac_vo_acm=0
# even if they are still in range of the AP. This can be done by setting # even if they are still in range of the AP. This can be done by setting
# skip_inactivity_poll to 1 (default 0). # skip_inactivity_poll to 1 (default 0).
#skip_inactivity_poll=0 #skip_inactivity_poll=0
#
# BSS max idle period management
# 0 = disabled (do not advertise and manage BSS max idle period)
# 1 = enabled (advertise and manage BSS max idle period; default)
# 2 = enabled requiring protected frames (advertise and manage BSS max idle
# period and require STAs to use protected keep-alive frames)
#bss_max_idle=1
#
# Maximum acceptable BSS maximum idle period
# If this is set to a nonzero value, the AP allows STAs to request different
# maximum idle period values. This is in the units to 1000 TUs (1.024 s)
#max_acceptable_idle_period=600
#
# Allow STA to skip group key handshake without getting disconnection when
# BSS max idle period management is enabled.
# 0 = disconnect STA if it does not reply to group key handshake (default)
# 1 = do not disconnect STA if it does not reply to group key handshake and
# if BSS max idle period management is enabled
#no_disconnect_on_group_keyerror=0
# Disassociate stations based on excessive transmission failures or other # Disassociate stations based on excessive transmission failures or other
# indications of connection loss. This depends on the driver capabilities and # indications of connection loss. This depends on the driver capabilities and
@ -665,12 +646,6 @@ wmm_ac_vo_acm=0
# no co-existence issues with neighboring devices are found. # no co-existence issues with neighboring devices are found.
#obss_interval=0 #obss_interval=0
# ht_vht_twt_responder: Whether TWT responder is enabled in HT and VHT modes
# 0 = disable; Disable TWT responder support in HT and VHT modes (default).
# 1 = enable; Enable TWT responder support in HT and VHT modes if supported by
# the driver.
#ht_vht_twt_responder=0
##### IEEE 802.11ac related configuration ##################################### ##### IEEE 802.11ac related configuration #####################################
# ieee80211ac: Whether IEEE 802.11ac (VHT) is enabled # ieee80211ac: Whether IEEE 802.11ac (VHT) is enabled
@ -1096,6 +1071,9 @@ wmm_ac_vo_acm=0
# 1 = yes (MLO) # 1 = yes (MLO)
#mld_ap=0 #mld_ap=0
# MLD ID - Affiliated MLD ID
#mld_id=1
# AP MLD MAC address # AP MLD MAC address
# The configured address will be set as the interface hardware address and used # The configured address will be set as the interface hardware address and used
# as the AP MLD MAC address. If not set, the current interface hardware address # as the AP MLD MAC address. If not set, the current interface hardware address
@ -1603,16 +1581,6 @@ own_ip_addr=127.0.0.1
#acct_server_port=1813 #acct_server_port=1813
#acct_server_shared_secret=secret2 #acct_server_shared_secret=secret2
# RADIUS/TLS instead of RADIUS/UDP
#auth_server_addr=127.0.0.1
#auth_server_port=2083
#auth_server_type=TLS
#auth_server_shared_secret=radsec
#auth_server_ca_cert=<path to trusted CA certificate(s)>
#auth_server_client_cert=<path to client certificate>
#auth_server_private_key=<path to private key>
#auth_server_private_key_passwd=<password for decrypting private key>
# Retry interval for trying to return to the primary RADIUS server (in # Retry interval for trying to return to the primary RADIUS server (in
# seconds). RADIUS client code will automatically try to use the next server # seconds). RADIUS client code will automatically try to use the next server
# when the current server is not replying to requests. If this interval is set, # when the current server is not replying to requests. If this interval is set,
@ -1620,17 +1588,6 @@ own_ip_addr=127.0.0.1
# currently used secondary server is still working. # currently used secondary server is still working.
#radius_retry_primary_interval=600 #radius_retry_primary_interval=600
# Message-Authenticator attribute requirement for non-EAP cases
# hostapd requires Message-Authenticator attribute to be included in all cases
# where RADIUS is used for EAP authentication. This is also required for cases
# where RADIUS is used for MAC ACL (macaddr_acl=2) by default, but that case
# can be configured to not require this for compatibility with RADIUS servers
# that do not include the attribute. This is not recommended due to potential
# security concerns, but can be used as a temporary workaround in networks where
# the connection to the RADIUS server is secure.
# 0 = Do not require Message-Authenticator in MAC ACL response
# 1 = Require Message-Authenticator in all authentication cases (default)
#radius_require_message_authenticator=1
# Interim accounting update interval # Interim accounting update interval
# If this is set (larger than 0) and acct_server is configured, hostapd will # If this is set (larger than 0) and acct_server is configured, hostapd will
@ -2119,7 +2076,7 @@ own_ip_addr=127.0.0.1
# Maximum number of SAE synchronization errors (dot11RSNASAESync) # Maximum number of SAE synchronization errors (dot11RSNASAESync)
# The offending SAE peer will be disconnected if more than this many # The offending SAE peer will be disconnected if more than this many
# synchronization errors happen. # synchronization errors happen.
#sae_sync=3 #sae_sync=5
# Enabled SAE finite cyclic groups # Enabled SAE finite cyclic groups
# SAE implementation are required to support group 19 (ECC group defined over a # SAE implementation are required to support group 19 (ECC group defined over a
@ -2279,86 +2236,6 @@ own_ip_addr=127.0.0.1
# (default: 1 = activated) # (default: 1 = activated)
#pasn_noauth=1 #pasn_noauth=1
# SSID protection in 4-way handshake
# The IEEE 802.11i-2004 RSN design did not provide means for protecting the
# SSID in the general case. IEEE P802.11REVme/D6.0 added support for this in
# 4-way handshake. This capability allows a STA to confirm that the AP has the
# same understanding on which SSID is being used for an association in a
# protected manner in cases where both the AP and the STA has this capability.
# This can be used to mitigate CVE-2023-52424 (a.k.a. the SSID Confusion
# Attack).
#
# Ideally, this capability would be enabled by default on the AP, but since this
# is new functionality with limited testing, the default is to disable this for
# now and require explicitly configuration to enable. The default behavior is
# like to change once this capability has received more testing.
#
# 0 = SSID protection in 4-way handshake disabled (default)
# 1 = SSID protection in 4-way handshake enabled
#
#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)
@ -2678,23 +2555,6 @@ own_ip_addr=127.0.0.1
#multi_ap_backhaul_wpa_psk=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef #multi_ap_backhaul_wpa_psk=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
#multi_ap_backhaul_wpa_passphrase=secret passphrase #multi_ap_backhaul_wpa_passphrase=secret passphrase
# Multi-AP Profile
# Indicate the supported Multi-AP profile (default: 2)
# 1 = Supports Multi-AP profile 1 as defined in Wi-Fi EasyMesh specification
# 2 = Supports Multi-AP profile 2 as defined in Wi-Fi EasyMesh specification
#multi_ap_profile=2
# Multi-AP client disallow
# Used to disallow profile specific backhaul STA association
# Bitmap of the disallowed Profile-X profiles
# 1 = Profile-1 Backhaul STA association disallowed
# 2 = Profile-2 Backhaul STA association disallowed
#multi_ap_client_disallow=0
# Multi-AP VLAN ID
# A valid non-zero VLAN ID will be used to update Default IEEE 802.1Q Setting
#multi_ap_vlanid=0
# WPS UPnP interface # WPS UPnP interface
# If set, support for external Registrars is enabled. # If set, support for external Registrars is enabled.
#upnp_iface=br0 #upnp_iface=br0
@ -3228,9 +3088,6 @@ own_ip_addr=127.0.0.1
# Enable neighbor report via radio measurements # Enable neighbor report via radio measurements
#rrm_neighbor_report=1 #rrm_neighbor_report=1
# Enable link measurement report via radio measurements
#rrm_link_measurement_report=1
# Enable beacon report via radio measurements # Enable beacon report via radio measurements
#rrm_beacon_report=1 #rrm_beacon_report=1
@ -3332,13 +3189,6 @@ own_ip_addr=127.0.0.1
# attempt (wpa_pairwise_update_count). This will trigger a timeout on all # attempt (wpa_pairwise_update_count). This will trigger a timeout on all
# previous attempts and thus delays the frame. (testing only) # previous attempts and thus delays the frame. (testing only)
#delay_eapol_tx=0 #delay_eapol_tx=0
#
# Additional elements for Probe Response frames.
# This parameter can be used to add additional element(s) to the end of the
# Probe Response frames. The format for these element(s) is a hexdump of the
# raw information elements (id+len+payload for one or more elements).
# These elements are added after the 'vendor_elements'.
#presp_elements=
##### Multiple BSSID support ################################################## ##### Multiple BSSID support ##################################################
# #

View file

@ -21,7 +21,7 @@
static const char *const hostapd_cli_version = static const char *const hostapd_cli_version =
"hostapd_cli v" VERSION_STR "\n" "hostapd_cli v" VERSION_STR "\n"
"Copyright (c) 2004-2024, Jouni Malinen <j@w1.fi> and contributors"; "Copyright (c) 2004-2022, Jouni Malinen <j@w1.fi> and contributors";
static struct wpa_ctrl *ctrl_conn; static struct wpa_ctrl *ctrl_conn;
static int hostapd_cli_quit = 0; static int hostapd_cli_quit = 0;
@ -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);
} }
@ -1176,15 +1168,6 @@ static int hostapd_cli_cmd_fst(struct wpa_ctrl *ctrl, int argc, char *argv[])
#endif /* CONFIG_FST */ #endif /* CONFIG_FST */
#ifdef CONFIG_IEEE80211AX
static int hostapd_cli_cmd_color_change(struct wpa_ctrl *ctrl,
int argc, char *argv[])
{
return hostapd_cli_cmd(ctrl, "COLOR_CHANGE", 1, argc, argv);
}
#endif /* CONFIG_IEEE80211AX */
static int hostapd_cli_cmd_chan_switch(struct wpa_ctrl *ctrl, static int hostapd_cli_cmd_chan_switch(struct wpa_ctrl *ctrl,
int argc, char *argv[]) int argc, char *argv[])
{ {
@ -1287,13 +1270,6 @@ static int hostapd_cli_cmd_update_beacon(struct wpa_ctrl *ctrl, int argc,
} }
static int hostapd_cli_cmd_stop_ap(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
return wpa_ctrl_command(ctrl, "STOP_AP");
}
static int hostapd_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[]) static int hostapd_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[])
{ {
char cmd[256]; char cmd[256];
@ -1622,13 +1598,6 @@ static int hostapd_cli_cmd_req_beacon(struct wpa_ctrl *ctrl, int argc,
} }
static int hostapd_cli_cmd_req_link_measurement(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
return hostapd_cli_cmd(ctrl, "REQ_LINK_MEASUREMENT", 1, argc, argv);
}
static int hostapd_cli_cmd_reload_wpa_psk(struct wpa_ctrl *ctrl, int argc, static int hostapd_cli_cmd_reload_wpa_psk(struct wpa_ctrl *ctrl, int argc,
char *argv[]) char *argv[])
{ {
@ -1763,11 +1732,6 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
"<cs_count> <freq> [sec_channel_offset=] [center_freq1=]\n" "<cs_count> <freq> [sec_channel_offset=] [center_freq1=]\n"
" [center_freq2=] [bandwidth=] [blocktx] [ht|vht]\n" " [center_freq2=] [bandwidth=] [blocktx] [ht|vht]\n"
" = initiate channel switch announcement" }, " = initiate channel switch announcement" },
#ifdef CONFIG_IEEE80211AX
{ "color_change", hostapd_cli_cmd_color_change, NULL,
"<color> = initiate BSS color change to set the specified color\n"
"Value 0 will disable the color.\n"},
#endif /* CONFIG_IEEE80211AX */
{ "notify_cw_change", hostapd_cli_cmd_notify_cw_change, NULL, { "notify_cw_change", hostapd_cli_cmd_notify_cw_change, NULL,
"<channel_width> = 0 - 20 MHz, 1 - 40 MHz, 2 - 80 MHz, 3 - 160 MHz" }, "<channel_width> = 0 - 20 MHz, 1 - 40 MHz, 2 - 80 MHz, 3 - 160 MHz" },
{ "hs20_wnm_notif", hostapd_cli_cmd_hs20_wnm_notif, NULL, { "hs20_wnm_notif", hostapd_cli_cmd_hs20_wnm_notif, NULL,
@ -1795,8 +1759,6 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
"= disable AP MLD to which the interface is affiliated" }, "= disable AP MLD to which the interface is affiliated" },
{ "update_beacon", hostapd_cli_cmd_update_beacon, NULL, { "update_beacon", hostapd_cli_cmd_update_beacon, NULL,
"= update Beacon frame contents\n"}, "= update Beacon frame contents\n"},
{ "stop_ap", hostapd_cli_cmd_stop_ap, NULL,
"= stop AP\n"},
{ "erp_flush", hostapd_cli_cmd_erp_flush, NULL, { "erp_flush", hostapd_cli_cmd_erp_flush, NULL,
"= drop all ERP keys"}, "= drop all ERP keys"},
{ "log_level", hostapd_cli_cmd_log_level, NULL, { "log_level", hostapd_cli_cmd_log_level, NULL,
@ -1876,8 +1838,6 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
"<addr> = poll a STA to check connectivity with a QoS null frame" }, "<addr> = poll a STA to check connectivity with a QoS null frame" },
{ "req_beacon", hostapd_cli_cmd_req_beacon, NULL, { "req_beacon", hostapd_cli_cmd_req_beacon, NULL,
"<addr> [req_mode=] <measurement request hexdump> = send a Beacon report request to a station" }, "<addr> [req_mode=] <measurement request hexdump> = send a Beacon report request to a station" },
{ "req_link_measurement", hostapd_cli_cmd_req_link_measurement, NULL,
"<addr> = send a link measurement report request to a station"},
{ "reload_wpa_psk", hostapd_cli_cmd_reload_wpa_psk, NULL, { "reload_wpa_psk", hostapd_cli_cmd_reload_wpa_psk, NULL,
"= reload wpa_psk_file only" }, "= reload wpa_psk_file only" },
#ifdef CONFIG_IEEE80211R_AP #ifdef CONFIG_IEEE80211R_AP
@ -2220,15 +2180,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 +2220,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 +2253,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

@ -158,9 +158,6 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
struct hostapd_bss_config *conf = hapd->conf; struct hostapd_bss_config *conf = hapd->conf;
u8 *b = conf->bssid; u8 *b = conf->bssid;
struct wpa_driver_capa capa; struct wpa_driver_capa capa;
#ifdef CONFIG_IEEE80211BE
struct hostapd_data *h_hapd = NULL;
#endif /* CONFIG_IEEE80211BE */
if (hapd->driver == NULL || hapd->driver->hapd_init == NULL) { if (hapd->driver == NULL || hapd->driver->hapd_init == NULL) {
wpa_printf(MSG_ERROR, "No hostapd driver wrapper available"); wpa_printf(MSG_ERROR, "No hostapd driver wrapper available");
@ -168,12 +165,30 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
} }
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
if (conf->mld_ap) for (i = 0; conf->mld_ap && i < iface->interfaces->count; i++) {
h_hapd = hostapd_mld_get_first_bss(hapd); struct hostapd_iface *h = iface->interfaces->iface[i];
struct hostapd_data *h_hapd = h->bss[0];
struct hostapd_bss_config *hconf = h_hapd->conf;
if (h == iface) {
wpa_printf(MSG_DEBUG, "MLD: Skip own interface");
continue;
}
if (!hconf->mld_ap || hconf->mld_id != conf->mld_id) {
wpa_printf(MSG_DEBUG,
"MLD: Skip non matching mld_id");
continue;
}
wpa_printf(MSG_DEBUG, "MLD: Found matching MLD interface");
if (!h_hapd->drv_priv) {
wpa_printf(MSG_DEBUG,
"MLD: Matching MLD BSS not initialized yet");
continue;
}
if (h_hapd) {
hapd->drv_priv = h_hapd->drv_priv; hapd->drv_priv = h_hapd->drv_priv;
hapd->interface_added = h_hapd->interface_added;
/* /*
* All interfaces participating in the AP MLD would have * All interfaces participating in the AP MLD would have
@ -183,17 +198,20 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
* is not configured, and otherwise it would be the * is not configured, and otherwise it would be the
* configured BSSID. * configured BSSID.
*/ */
os_memcpy(hapd->mld_addr, h_hapd->mld_addr, ETH_ALEN);
if (is_zero_ether_addr(b)) { if (is_zero_ether_addr(b)) {
os_memcpy(hapd->own_addr, h_hapd->mld->mld_addr, os_memcpy(hapd->own_addr, h_hapd->mld_addr, ETH_ALEN);
ETH_ALEN);
random_mac_addr_keep_oui(hapd->own_addr); random_mac_addr_keep_oui(hapd->own_addr);
} else { } else {
os_memcpy(hapd->own_addr, b, ETH_ALEN); os_memcpy(hapd->own_addr, b, ETH_ALEN);
} }
wpa_printf(MSG_DEBUG, /*
"Setup of non first link (%d) BSS of MLD %s", * Mark the interface as a secondary interface, as this
hapd->mld_link_id, hapd->conf->iface); * is needed for the de-initialization flow
*/
hapd->mld_first_bss = h_hapd;
hapd->mld_link_id = hapd->mld_first_bss->mld_next_link_id++;
goto setup_mld; goto setup_mld;
} }
@ -270,15 +288,13 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
* configured, and otherwise it would be the configured BSSID. * configured, and otherwise it would be the configured BSSID.
*/ */
if (hapd->conf->mld_ap) { if (hapd->conf->mld_ap) {
os_memcpy(hapd->mld->mld_addr, hapd->own_addr, ETH_ALEN); os_memcpy(hapd->mld_addr, hapd->own_addr, ETH_ALEN);
hapd->mld_next_link_id = 0;
hapd->mld_link_id = hapd->mld_next_link_id++;
if (!b) if (!b)
random_mac_addr_keep_oui(hapd->own_addr); random_mac_addr_keep_oui(hapd->own_addr);
else else
os_memcpy(hapd->own_addr, b, ETH_ALEN); os_memcpy(hapd->own_addr, b, ETH_ALEN);
wpa_printf(MSG_DEBUG, "Setup of first link (%d) BSS of MLD %s",
hapd->mld_link_id, hapd->conf->iface);
} }
setup_mld: setup_mld:
@ -290,7 +306,6 @@ setup_mld:
iface->drv_flags = capa.flags; iface->drv_flags = capa.flags;
iface->drv_flags2 = capa.flags2; iface->drv_flags2 = capa.flags2;
iface->drv_rrm_flags = capa.rrm_flags;
iface->probe_resp_offloads = capa.probe_resp_offloads; iface->probe_resp_offloads = capa.probe_resp_offloads;
/* /*
* Use default extended capa values from per-radio information * Use default extended capa values from per-radio information
@ -333,17 +348,11 @@ setup_mld:
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"MLD: Set link_id=%u, mld_addr=" MACSTR "MLD: Set link_id=%u, mld_addr=" MACSTR
", own_addr=" MACSTR, ", own_addr=" MACSTR,
hapd->mld_link_id, MAC2STR(hapd->mld->mld_addr), hapd->mld_link_id, MAC2STR(hapd->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 */
@ -559,7 +568,7 @@ static void show_version(void)
"hostapd v%s\n" "hostapd v%s\n"
"User space daemon for IEEE 802.11 AP management,\n" "User space daemon for IEEE 802.11 AP management,\n"
"IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n" "IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n"
"Copyright (c) 2002-2024, Jouni Malinen <j@w1.fi> " "Copyright (c) 2002-2022, Jouni Malinen <j@w1.fi> "
"and contributors\n", "and contributors\n",
VERSION_STR); VERSION_STR);
} }
@ -740,30 +749,6 @@ static void hostapd_periodic(void *eloop_ctx, void *timeout_ctx)
} }
static void hostapd_global_cleanup_mld(struct hapd_interfaces *interfaces)
{
#ifdef CONFIG_IEEE80211BE
size_t i;
if (!interfaces || !interfaces->mld)
return;
for (i = 0; i < interfaces->mld_count; i++) {
if (!interfaces->mld[i])
continue;
interfaces->mld_ctrl_iface_deinit(interfaces->mld[i]);
os_free(interfaces->mld[i]);
interfaces->mld[i] = NULL;
}
os_free(interfaces->mld);
interfaces->mld = NULL;
interfaces->mld_count = 0;
#endif /* CONFIG_IEEE80211BE */
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct hapd_interfaces interfaces; struct hapd_interfaces interfaces;
@ -798,10 +783,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);
@ -1048,8 +1029,6 @@ int main(int argc, char *argv[])
interfaces.iface = NULL; interfaces.iface = NULL;
interfaces.count = 0; interfaces.count = 0;
hostapd_global_cleanup_mld(&interfaces);
#ifdef CONFIG_DPP #ifdef CONFIG_DPP
dpp_global_deinit(interfaces.dpp); dpp_global_deinit(interfaces.dpp);
#endif /* CONFIG_DPP */ #endif /* CONFIG_DPP */

View file

@ -12,7 +12,6 @@
#include "utils/common.h" #include "utils/common.h"
#include "utils/list.h" #include "utils/list.h"
#include "utils/eloop.h"
#include "common/ieee802_11_defs.h" #include "common/ieee802_11_defs.h"
#include "common/hw_features_common.h" #include "common/hw_features_common.h"
#include "common/wpa_ctrl.h" #include "common/wpa_ctrl.h"
@ -76,7 +75,7 @@
* *
* This corresponds to: * This corresponds to:
* --- * ---
* (busy time - tx time) / (active time - tx time) * 2^(chan_nf - band_min_nf) * (busy time - tx time) / (active time - tx time) * 2^(chan_nf + band_min_nf)
* --- * ---
* *
* The coefficient of 2 reflects the way power in "far-field" * The coefficient of 2 reflects the way power in "far-field"
@ -93,7 +92,7 @@
* calculated easily. * calculated easily.
* --- * ---
* (busy time - tx time) / (active time - tx time) * * (busy time - tx time) / (active time - tx time) *
* 2^(10^(chan_nf/10) - 10^(band_min_nf/10)) * 2^(10^(chan_nf/10) + 10^(band_min_nf/10))
* --- * ---
* *
* However to account for cases where busy/rx time is 0 (channel load is then * However to account for cases where busy/rx time is 0 (channel load is then
@ -101,7 +100,7 @@
* channel with lower noise floor is preferred. The equation becomes: * channel with lower noise floor is preferred. The equation becomes:
* --- * ---
* 10^(chan_nf/5) + (busy time - tx time) / (active time - tx time) * * 10^(chan_nf/5) + (busy time - tx time) / (active time - tx time) *
* 2^(10^(chan_nf/10) - 10^(band_min_nf/10)) * 2^(10^(chan_nf/10) + 10^(band_min_nf/10))
* --- * ---
* *
* All this "interference factor" is purely subjective and only time * All this "interference factor" is purely subjective and only time
@ -308,7 +307,6 @@ static const struct bw_item *bw_desc[] = {
static int acs_request_scan(struct hostapd_iface *iface); static int acs_request_scan(struct hostapd_iface *iface);
static int acs_survey_is_sufficient(struct freq_survey *survey); static int acs_survey_is_sufficient(struct freq_survey *survey);
static void acs_scan_retry(void *eloop_data, void *user_data);
static void acs_clean_chan_surveys(struct hostapd_channel_data *chan) static void acs_clean_chan_surveys(struct hostapd_channel_data *chan)
@ -354,8 +352,6 @@ void acs_cleanup(struct hostapd_iface *iface)
iface->chans_surveyed = 0; iface->chans_surveyed = 0;
iface->acs_num_completed_scans = 0; iface->acs_num_completed_scans = 0;
iface->acs_num_retries = 0;
eloop_cancel_timeout(acs_scan_retry, iface, NULL);
} }
@ -511,7 +507,7 @@ static int acs_survey_list_is_sufficient(struct hostapd_channel_data *chan)
} }
if (ret == -1) if (ret == -1)
ret = 0; /* no survey list entries */ ret = 1; /* no survey list entries */
if (!ret) { if (!ret) {
wpa_printf(MSG_INFO, wpa_printf(MSG_INFO,
@ -834,9 +830,6 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
int bw320_offset = 0, ideal_bw320_offset = 0; int bw320_offset = 0, ideal_bw320_offset = 0;
unsigned int k; unsigned int k;
int secondary_channel = 1, freq_offset; int secondary_channel = 1, freq_offset;
#ifdef CONFIG_IEEE80211BE
int index_primary = 0;
#endif /* CONFIG_IEEE80211BE */
if (is_24ghz_mode(mode->mode)) if (is_24ghz_mode(mode->mode))
secondary_channel = iface->conf->secondary_channel; secondary_channel = iface->conf->secondary_channel;
@ -976,9 +969,6 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
best->chan, chan->chan, best->chan, chan->chan,
chan->interference_factor, chan->interference_factor,
best->interference_factor); best->interference_factor);
#ifdef CONFIG_IEEE80211BE
index_primary = (chan->freq - best->freq) / 20;
#endif /* CONFIG_IEEE80211BE */
chan = best; chan = best;
} }
@ -1067,8 +1057,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
if (iface->conf->ieee80211be) if (iface->conf->ieee80211be)
acs_update_puncturing_bitmap(iface, mode, bw, acs_update_puncturing_bitmap(iface, mode, bw,
n_chans, chan, n_chans, chan,
factor, factor, 0);
index_primary);
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
} }
@ -1328,7 +1317,6 @@ static void acs_scan_complete(struct hostapd_iface *iface)
int err; int err;
iface->scan_cb = NULL; iface->scan_cb = NULL;
iface->acs_num_retries = 0;
wpa_printf(MSG_DEBUG, "ACS: Using survey based algorithm (acs_num_scans=%d)", wpa_printf(MSG_DEBUG, "ACS: Using survey based algorithm (acs_num_scans=%d)",
iface->conf->acs_num_scans); iface->conf->acs_num_scans);
@ -1341,7 +1329,7 @@ static void acs_scan_complete(struct hostapd_iface *iface)
if (++iface->acs_num_completed_scans < iface->conf->acs_num_scans) { if (++iface->acs_num_completed_scans < iface->conf->acs_num_scans) {
err = acs_request_scan(iface); err = acs_request_scan(iface);
if (err && err != -EBUSY) { if (err) {
wpa_printf(MSG_ERROR, "ACS: Failed to request scan"); wpa_printf(MSG_ERROR, "ACS: Failed to request scan");
goto fail; goto fail;
} }
@ -1394,7 +1382,7 @@ static int * acs_request_scan_add_freqs(struct hostapd_iface *iface,
static int acs_request_scan(struct hostapd_iface *iface) static int acs_request_scan(struct hostapd_iface *iface)
{ {
struct wpa_driver_scan_params params; struct wpa_driver_scan_params params;
int i, *freq, ret; int i, *freq;
int num_channels; int num_channels;
struct hostapd_hw_modes *mode; struct hostapd_hw_modes *mode;
@ -1427,62 +1415,24 @@ static int acs_request_scan(struct hostapd_iface *iface)
return -1; return -1;
} }
if (!iface->acs_num_retries) iface->scan_cb = acs_scan_complete;
wpa_printf(MSG_DEBUG, "ACS: Scanning %d / %d", wpa_printf(MSG_DEBUG, "ACS: Scanning %d / %d",
iface->acs_num_completed_scans + 1, iface->acs_num_completed_scans + 1,
iface->conf->acs_num_scans); iface->conf->acs_num_scans);
else
wpa_printf(MSG_DEBUG,
"ACS: Re-try scanning attempt %d (%d / %d)",
iface->acs_num_retries,
iface->acs_num_completed_scans + 1,
iface->conf->acs_num_scans);
ret = hostapd_driver_scan(iface->bss[0], &params); if (hostapd_driver_scan(iface->bss[0], &params) < 0) {
os_free(params.freqs);
if (ret == -EBUSY) {
iface->acs_num_retries++;
if (iface->acs_num_retries >= ACS_SCAN_RETRY_MAX_COUNT) {
wpa_printf(MSG_ERROR,
"ACS: Failed to request initial scan (all re-attempts failed)");
acs_fail(iface);
return -1;
}
wpa_printf(MSG_INFO,
"Failed to request acs scan ret=%d (%s) - try to scan after %d seconds",
ret, strerror(-ret), ACS_SCAN_RETRY_INTERVAL);
eloop_cancel_timeout(acs_scan_retry, iface, NULL);
eloop_register_timeout(ACS_SCAN_RETRY_INTERVAL, 0,
acs_scan_retry, iface, NULL);
return 0;
}
if (ret < 0) {
wpa_printf(MSG_ERROR, "ACS: Failed to request initial scan"); wpa_printf(MSG_ERROR, "ACS: Failed to request initial scan");
acs_cleanup(iface); acs_cleanup(iface);
os_free(params.freqs);
return -1; return -1;
} }
iface->scan_cb = acs_scan_complete; os_free(params.freqs);
return 0; return 0;
} }
static void acs_scan_retry(void *eloop_data, void *user_data)
{
struct hostapd_iface *iface = eloop_data;
if (acs_request_scan(iface)) {
wpa_printf(MSG_ERROR,
"ACS: Failed to request re-try of initial scan");
acs_fail(iface);
}
}
enum hostapd_chan_status acs_init(struct hostapd_iface *iface) enum hostapd_chan_status acs_init(struct hostapd_iface *iface)
{ {
int err; int err;

View file

@ -15,9 +15,6 @@
enum hostapd_chan_status acs_init(struct hostapd_iface *iface); enum hostapd_chan_status acs_init(struct hostapd_iface *iface);
void acs_cleanup(struct hostapd_iface *iface); void acs_cleanup(struct hostapd_iface *iface);
#define ACS_SCAN_RETRY_MAX_COUNT 15
#define ACS_SCAN_RETRY_INTERVAL 5
#else /* CONFIG_ACS */ #else /* CONFIG_ACS */
static inline enum hostapd_chan_status acs_init(struct hostapd_iface *iface) static inline enum hostapd_chan_status acs_init(struct hostapd_iface *iface)

View file

@ -92,7 +92,6 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
bss->eap_sim_id = 3; bss->eap_sim_id = 3;
bss->eap_sim_aka_fast_reauth_limit = 1000; bss->eap_sim_aka_fast_reauth_limit = 1000;
bss->ap_max_inactivity = AP_MAX_INACTIVITY; bss->ap_max_inactivity = AP_MAX_INACTIVITY;
bss->bss_max_idle = 1;
bss->eapol_version = EAPOL_VERSION; bss->eapol_version = EAPOL_VERSION;
bss->max_listen_interval = 65535; bss->max_listen_interval = 65535;
@ -122,10 +121,9 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
#endif /* CONFIG_IEEE80211R_AP */ #endif /* CONFIG_IEEE80211R_AP */
bss->radius_das_time_window = 300; bss->radius_das_time_window = 300;
bss->radius_require_message_authenticator = 1;
bss->anti_clogging_threshold = 5; bss->anti_clogging_threshold = 5;
bss->sae_sync = 3; bss->sae_sync = 5;
bss->gas_frag_limit = 1400; bss->gas_frag_limit = 1400;
@ -165,8 +163,6 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
/* Default to strict CRL checking. */ /* Default to strict CRL checking. */
bss->check_crl_strict = 1; bss->check_crl_strict = 1;
bss->multi_ap_profile = MULTI_AP_PROFILE_2;
#ifdef CONFIG_TESTING_OPTIONS #ifdef CONFIG_TESTING_OPTIONS
bss->sae_commit_status = -1; bss->sae_commit_status = -1;
bss->test_assoc_comeback_type = -1; bss->test_assoc_comeback_type = -1;
@ -491,33 +487,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 +510,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);
@ -571,10 +555,6 @@ static void hostapd_config_free_radius(struct hostapd_radius_server *servers,
for (i = 0; i < num_servers; i++) { for (i = 0; i < num_servers; i++) {
os_free(servers[i].shared_secret); os_free(servers[i].shared_secret);
os_free(servers[i].ca_cert);
os_free(servers[i].client_cert);
os_free(servers[i].private_key);
os_free(servers[i].private_key_passwd);
} }
os_free(servers); os_free(servers);
} }
@ -972,11 +952,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);
@ -986,7 +961,6 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf)
wpabuf_free(conf->igtk_rsc_override); wpabuf_free(conf->igtk_rsc_override);
wpabuf_free(conf->eapol_m1_elements); wpabuf_free(conf->eapol_m1_elements);
wpabuf_free(conf->eapol_m3_elements); wpabuf_free(conf->eapol_m3_elements);
wpabuf_free(conf->presp_elements);
#endif /* CONFIG_TESTING_OPTIONS */ #endif /* CONFIG_TESTING_OPTIONS */
os_free(conf->no_probe_resp_if_seen_on); os_free(conf->no_probe_resp_if_seen_on);

View file

@ -309,7 +309,6 @@ struct hostapd_bss_config {
struct hostapd_ip_addr own_ip_addr; struct hostapd_ip_addr own_ip_addr;
char *nas_identifier; char *nas_identifier;
struct hostapd_radius_servers *radius; struct hostapd_radius_servers *radius;
int radius_require_message_authenticator;
int acct_interim_interval; int acct_interim_interval;
int radius_request_cui; int radius_request_cui;
struct hostapd_radius_attr *radius_auth_req_attr; struct hostapd_radius_attr *radius_auth_req_attr;
@ -358,11 +357,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 +386,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];
@ -474,9 +465,6 @@ struct hostapd_bss_config {
*/ */
int ap_max_inactivity; int ap_max_inactivity;
int bss_max_idle;
int max_acceptable_idle_period;
bool no_disconnect_on_group_keyerror;
int ignore_broadcast_ssid; int ignore_broadcast_ssid;
int no_probe_resp_if_max_sta; int no_probe_resp_if_max_sta;
@ -696,11 +684,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,9 +708,7 @@ 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;
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
u16 eht_oper_puncturing_override; u16 eht_oper_puncturing_override;
@ -819,14 +800,6 @@ struct hostapd_bss_config {
#define BACKHAUL_BSS 1 #define BACKHAUL_BSS 1
#define FRONTHAUL_BSS 2 #define FRONTHAUL_BSS 2
int multi_ap; /* bitmap of BACKHAUL_BSS, FRONTHAUL_BSS */ int multi_ap; /* bitmap of BACKHAUL_BSS, FRONTHAUL_BSS */
int multi_ap_profile;
/* Multi-AP Profile-1 clients not allowed to connect */
#define PROFILE1_CLIENT_ASSOC_DISALLOW BIT(0)
/* Multi-AP Profile-2 clients not allowed to connect */
#define PROFILE2_CLIENT_ASSOC_DISALLOW BIT(1)
unsigned int multi_ap_client_disallow;
/* Primary VLAN ID to use in Multi-AP */
int multi_ap_vlanid;
#ifdef CONFIG_AIRTIME_POLICY #ifdef CONFIG_AIRTIME_POLICY
unsigned int airtime_weight; unsigned int airtime_weight;
@ -975,8 +948,6 @@ struct hostapd_bss_config {
char *config_id; char *config_id;
bool xrates_supported; bool xrates_supported;
bool ssid_protection;
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
/* The AP is part of an AP MLD */ /* The AP is part of an AP MLD */
u8 mld_ap; u8 mld_ap;
@ -1246,9 +1217,6 @@ struct hostapd_config {
MBSSID_ENABLED = 1, MBSSID_ENABLED = 1,
ENHANCED_MBSSID_ENABLED = 2, ENHANCED_MBSSID_ENABLED = 2,
} mbssid; } mbssid;
/* Whether to enable TWT responder in HT and VHT modes */
bool ht_vht_twt_responder;
}; };

View file

@ -208,9 +208,6 @@ int hostapd_build_ap_extra_ies(struct hostapd_data *hapd,
add_buf(&beacon, hapd->conf->vendor_elements); add_buf(&beacon, hapd->conf->vendor_elements);
add_buf(&proberesp, hapd->conf->vendor_elements); add_buf(&proberesp, hapd->conf->vendor_elements);
#ifdef CONFIG_TESTING_OPTIONS
add_buf(&proberesp, hapd->conf->presp_elements);
#endif /* CONFIG_TESTING_OPTIONS */
add_buf(&assocresp, hapd->conf->assocresp_elements); add_buf(&assocresp, hapd->conf->assocresp_elements);
*beacon_ret = beacon; *beacon_ret = beacon;
@ -268,7 +265,7 @@ int hostapd_set_ap_wps_ie(struct hostapd_data *hapd)
} }
bool hostapd_sta_is_link_sta(struct hostapd_data *hapd, static bool hostapd_sta_is_link_sta(struct hostapd_data *hapd,
struct sta_info *sta) struct sta_info *sta)
{ {
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
@ -575,33 +572,12 @@ int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
} }
#ifdef CONFIG_IEEE80211BE
int hostapd_if_link_remove(struct hostapd_data *hapd,
enum wpa_driver_if_type type,
const char *ifname, u8 link_id)
{
if (!hapd->driver || !hapd->drv_priv || !hapd->driver->link_remove)
return -1;
return hapd->driver->link_remove(hapd->drv_priv, type, ifname,
hapd->mld_link_id);
}
#endif /* CONFIG_IEEE80211BE */
int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type, int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
const char *ifname) const char *ifname)
{ {
if (hapd->driver == NULL || hapd->drv_priv == NULL || if (hapd->driver == NULL || hapd->drv_priv == NULL ||
hapd->driver->if_remove == NULL) hapd->driver->if_remove == NULL)
return -1; return -1;
#ifdef CONFIG_IEEE80211BE
if (hapd->conf->mld_ap)
return hostapd_if_link_remove(hapd, type, ifname,
hapd->mld_link_id);
#endif /* CONFIG_IEEE80211BE */
return hapd->driver->if_remove(hapd->drv_priv, type, ifname); return hapd->driver->if_remove(hapd->drv_priv, type, ifname);
} }
@ -627,17 +603,9 @@ int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
int hostapd_flush(struct hostapd_data *hapd) int hostapd_flush(struct hostapd_data *hapd)
{ {
int link_id = -1;
if (hapd->driver == NULL || hapd->driver->flush == NULL) if (hapd->driver == NULL || hapd->driver->flush == NULL)
return 0; return 0;
return hapd->driver->flush(hapd->drv_priv);
#ifdef CONFIG_IEEE80211BE
if (hapd->conf && hapd->conf->mld_ap)
link_id = hapd->mld_link_id;
#endif /* CONFIG_IEEE80211BE */
return hapd->driver->flush(hapd->drv_priv, link_id);
} }
@ -661,7 +629,7 @@ int hostapd_set_freq(struct hostapd_data *hapd, enum hostapd_hw_mode mode,
&cmode->he_capab[IEEE80211_MODE_AP] : NULL, &cmode->he_capab[IEEE80211_MODE_AP] : NULL,
cmode ? cmode ?
&cmode->eht_capab[IEEE80211_MODE_AP] : &cmode->eht_capab[IEEE80211_MODE_AP] :
NULL, hostapd_get_punct_bitmap(hapd))) NULL))
return -1; return -1;
if (hapd->driver == NULL) if (hapd->driver == NULL)
@ -790,8 +758,6 @@ int hostapd_driver_scan(struct hostapd_data *hapd,
struct wpa_scan_results * hostapd_driver_get_scan_results( struct wpa_scan_results * hostapd_driver_get_scan_results(
struct hostapd_data *hapd) struct hostapd_data *hapd)
{ {
if (hapd->driver && hapd->driver->get_scan_results)
return hapd->driver->get_scan_results(hapd->drv_priv, NULL);
if (hapd->driver && hapd->driver->get_scan_results2) if (hapd->driver && hapd->driver->get_scan_results2)
return hapd->driver->get_scan_results2(hapd->drv_priv); return hapd->driver->get_scan_results2(hapd->drv_priv);
return NULL; return NULL;
@ -874,7 +840,7 @@ int hostapd_drv_sta_deauth(struct hostapd_data *hapd,
link_id = hapd->mld_link_id; link_id = hapd->mld_link_id;
if (ap_sta_is_mld(hapd, sta)) if (ap_sta_is_mld(hapd, sta))
own_addr = hapd->mld->mld_addr; own_addr = hapd->mld_addr;
} }
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
@ -895,7 +861,7 @@ int hostapd_drv_sta_disassoc(struct hostapd_data *hapd,
struct sta_info *sta = ap_get_sta(hapd, addr); struct sta_info *sta = ap_get_sta(hapd, addr);
if (ap_sta_is_mld(hapd, sta)) if (ap_sta_is_mld(hapd, sta))
own_addr = hapd->mld->mld_addr; own_addr = hapd->mld_addr;
} }
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
@ -953,7 +919,7 @@ static int hapd_drv_send_action(struct hostapd_data *hapd, unsigned int freq,
sta = ap_get_sta(hapd, dst); sta = ap_get_sta(hapd, dst);
if (ap_sta_is_mld(hapd, sta)) { if (ap_sta_is_mld(hapd, sta)) {
own_addr = hapd->mld->mld_addr; own_addr = hapd->mld_addr;
bssid = own_addr; bssid = own_addr;
} }
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
@ -1011,8 +977,7 @@ int hostapd_start_dfs_cac(struct hostapd_iface *iface,
center_segment1, center_segment1,
cmode->vht_capab, cmode->vht_capab,
&cmode->he_capab[IEEE80211_MODE_AP], &cmode->he_capab[IEEE80211_MODE_AP],
&cmode->eht_capab[IEEE80211_MODE_AP], &cmode->eht_capab[IEEE80211_MODE_AP])) {
hostapd_get_punct_bitmap(hapd))) {
wpa_printf(MSG_ERROR, "Can't set freq params"); wpa_printf(MSG_ERROR, "Can't set freq params");
return -1; return -1;
} }
@ -1034,8 +999,7 @@ int hostapd_start_dfs_cac(struct hostapd_iface *iface,
int hostapd_drv_set_qos_map(struct hostapd_data *hapd, int hostapd_drv_set_qos_map(struct hostapd_data *hapd,
const u8 *qos_map_set, u8 qos_map_set_len) const u8 *qos_map_set, u8 qos_map_set_len)
{ {
if (!hapd->driver || !hapd->driver->set_qos_map || !hapd->drv_priv || if (!hapd->driver || !hapd->driver->set_qos_map || !hapd->drv_priv)
!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_QOS_MAPPING))
return 0; return 0;
return hapd->driver->set_qos_map(hapd->drv_priv, qos_map_set, return hapd->driver->set_qos_map(hapd->drv_priv, qos_map_set,
qos_map_set_len); qos_map_set_len);
@ -1250,14 +1214,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

@ -26,8 +26,6 @@ void hostapd_free_ap_extra_ies(struct hostapd_data *hapd, struct wpabuf *beacon,
struct wpabuf *assocresp); struct wpabuf *assocresp);
int hostapd_reset_ap_wps_ie(struct hostapd_data *hapd); int hostapd_reset_ap_wps_ie(struct hostapd_data *hapd);
int hostapd_set_ap_wps_ie(struct hostapd_data *hapd); int hostapd_set_ap_wps_ie(struct hostapd_data *hapd);
bool hostapd_sta_is_link_sta(struct hostapd_data *hapd,
struct sta_info *sta);
int hostapd_set_authorized(struct hostapd_data *hapd, int hostapd_set_authorized(struct hostapd_data *hapd,
struct sta_info *sta, int authorized); struct sta_info *sta, int authorized);
int hostapd_set_sta_flags(struct hostapd_data *hapd, struct sta_info *sta); int hostapd_set_sta_flags(struct hostapd_data *hapd, struct sta_info *sta);
@ -61,9 +59,6 @@ int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
const char *bridge, int use_existing); const char *bridge, int use_existing);
int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type, int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
const char *ifname); const char *ifname);
int hostapd_if_link_remove(struct hostapd_data *hapd,
enum wpa_driver_if_type type,
const char *ifname, u8 link_id);
int hostapd_set_ieee8021x(struct hostapd_data *hapd, int hostapd_set_ieee8021x(struct hostapd_data *hapd,
struct wpa_bss_params *params); struct wpa_bss_params *params);
int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd, int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
@ -393,15 +388,9 @@ static inline int hostapd_drv_vendor_cmd(struct hostapd_data *hapd,
static inline int hostapd_drv_stop_ap(struct hostapd_data *hapd) static inline int hostapd_drv_stop_ap(struct hostapd_data *hapd)
{ {
int link_id = -1;
if (!hapd->driver || !hapd->driver->stop_ap || !hapd->drv_priv) if (!hapd->driver || !hapd->driver->stop_ap || !hapd->drv_priv)
return 0; return 0;
#ifdef CONFIG_IEEE80211BE return hapd->driver->stop_ap(hapd->drv_priv);
if (hapd->conf->mld_ap)
link_id = hapd->mld_link_id;
#endif /* CONFIG_IEEE80211BE */
return hapd->driver->stop_ap(hapd->drv_priv, link_id);
} }
static inline int hostapd_drv_channel_info(struct hostapd_data *hapd, static inline int hostapd_drv_channel_info(struct hostapd_data *hapd,
@ -454,32 +443,15 @@ hostapd_drv_register_frame(struct hostapd_data *hapd, u16 type,
#endif /* CONFIG_TESTING_OPTIONS */ #endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
static inline int hostapd_drv_link_add(struct hostapd_data *hapd, static inline int hostapd_drv_link_add(struct hostapd_data *hapd,
u8 link_id, const u8 *addr) u8 link_id, const u8 *addr)
{ {
if (!hapd->driver || !hapd->drv_priv || !hapd->driver->link_add) if (!hapd->driver || !hapd->drv_priv || !hapd->driver->link_add)
return -1; return -1;
return hapd->driver->link_add(hapd->drv_priv, link_id, addr, hapd); return hapd->driver->link_add(hapd->drv_priv, link_id, addr);
} }
static inline int hostapd_drv_link_sta_remove(struct hostapd_data *hapd,
const u8 *addr)
{
if (!hapd->conf->mld_ap || !hapd->driver || !hapd->drv_priv ||
!hapd->driver->link_sta_remove)
return -1;
return hapd->driver->link_sta_remove(hapd->drv_priv, hapd->mld_link_id,
addr);
}
#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

@ -107,20 +107,13 @@ static int hostapd_setup_radius_srv(struct hostapd_data *hapd)
struct radius_server_conf srv; struct radius_server_conf srv;
struct hostapd_bss_config *conf = hapd->conf; struct hostapd_bss_config *conf = hapd->conf;
#ifdef CONFIG_IEEE80211BE if (hapd->mld_first_bss) {
if (!hostapd_mld_is_first_bss(hapd)) {
struct hostapd_data *first;
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"MLD: Using RADIUS server of the first BSS"); "MLD: Using RADIUS server of the first BSS");
first = hostapd_mld_get_first_bss(hapd); hapd->radius_srv = hapd->mld_first_bss->radius_srv;
if (!first)
return -1;
hapd->radius_srv = first->radius_srv;
return 0; return 0;
} }
#endif /* CONFIG_IEEE80211BE */
os_memset(&srv, 0, sizeof(srv)); os_memset(&srv, 0, sizeof(srv));
srv.client_file = conf->radius_server_clients; srv.client_file = conf->radius_server_clients;
@ -256,34 +249,18 @@ static struct eap_config * authsrv_eap_config(struct hostapd_data *hapd)
int authsrv_init(struct hostapd_data *hapd) int authsrv_init(struct hostapd_data *hapd)
{ {
#ifdef CONFIG_IEEE80211BE if (hapd->mld_first_bss) {
if (!hostapd_mld_is_first_bss(hapd)) {
struct hostapd_data *first;
first = hostapd_mld_get_first_bss(hapd);
if (!first)
return -1;
if (!first->eap_cfg) {
wpa_printf(MSG_DEBUG,
"MLD: First BSS auth_serv does not exist. Init on its behalf");
if (authsrv_init(first))
return -1;
}
wpa_printf(MSG_DEBUG, "MLD: Using auth_serv of the first BSS"); wpa_printf(MSG_DEBUG, "MLD: Using auth_serv of the first BSS");
#ifdef EAP_TLS_FUNCS #ifdef EAP_TLS_FUNCS
hapd->ssl_ctx = first->ssl_ctx; hapd->ssl_ctx = hapd->mld_first_bss->ssl_ctx;
#endif /* EAP_TLS_FUNCS */ #endif /* EAP_TLS_FUNCS */
hapd->eap_cfg = first->eap_cfg; hapd->eap_cfg = hapd->mld_first_bss->eap_cfg;
#ifdef EAP_SIM_DB #ifdef EAP_SIM_DB
hapd->eap_sim_db_priv = first->eap_sim_db_priv; hapd->eap_sim_db_priv = hapd->mld_first_bss->eap_sim_db_priv;
#endif /* EAP_SIM_DB */ #endif /* EAP_SIM_DB */
return 0; return 0;
} }
#endif /* CONFIG_IEEE80211BE */
#ifdef EAP_TLS_FUNCS #ifdef EAP_TLS_FUNCS
if (hapd->conf->eap_server && if (hapd->conf->eap_server &&
@ -399,8 +376,7 @@ int authsrv_init(struct hostapd_data *hapd)
void authsrv_deinit(struct hostapd_data *hapd) void authsrv_deinit(struct hostapd_data *hapd)
{ {
#ifdef CONFIG_IEEE80211BE if (hapd->mld_first_bss) {
if (!hostapd_mld_is_first_bss(hapd)) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"MLD: Deinit auth_serv of a non-first BSS"); "MLD: Deinit auth_serv of a non-first BSS");
@ -414,7 +390,6 @@ void authsrv_deinit(struct hostapd_data *hapd)
#endif /* EAP_TLS_FUNCS */ #endif /* EAP_TLS_FUNCS */
return; return;
} }
#endif /* CONFIG_IEEE80211BE */
#ifdef RADIUS_SERVER #ifdef RADIUS_SERVER
radius_server_deinit(hapd->radius_srv); radius_server_deinit(hapd->radius_srv);

File diff suppressed because it is too large Load diff

View file

@ -33,7 +33,4 @@ void sta_track_claim_taxonomy_info(struct hostapd_iface *iface, const u8 *addr,
const u8 * hostapd_wpa_ie(struct hostapd_data *hapd, u8 eid); const u8 * hostapd_wpa_ie(struct hostapd_data *hapd, u8 eid);
u8 * hostapd_unsol_bcast_probe_resp(struct hostapd_data *hapd,
struct unsol_bcast_probe_resp *ubpr);
#endif /* BEACON_H */ #endif /* BEACON_H */

View file

@ -277,14 +277,6 @@ static int hostapd_ctrl_iface_sta_mib(struct hostapd_data *hapd,
return len; return len;
len += ret; len += ret;
if (sta->max_idle_period) {
ret = os_snprintf(buf + len, buflen - len,
"max_idle_period=%d\n", sta->max_idle_period);
if (os_snprintf_error(buflen - len, ret))
return len;
len += ret;
}
res = ieee802_11_get_mib_sta(hapd, sta, buf + len, buflen - len); res = ieee802_11_get_mib_sta(hapd, sta, buf + len, buflen - len);
if (res >= 0) if (res >= 0)
len += res; len += res;
@ -356,15 +348,11 @@ static int hostapd_ctrl_iface_sta_mib(struct hostapd_data *hapd,
if (sta->supp_op_classes && if (sta->supp_op_classes &&
buflen - len > (unsigned) (17 + 2 * sta->supp_op_classes[0])) { buflen - len > (unsigned) (17 + 2 * sta->supp_op_classes[0])) {
res = os_snprintf(buf + len, buflen - len, "supp_op_classes="); len += os_snprintf(buf + len, buflen - len, "supp_op_classes=");
if (!os_snprintf_error(buflen - len, res))
len += res;
len += wpa_snprintf_hex(buf + len, buflen - len, len += wpa_snprintf_hex(buf + len, buflen - len,
sta->supp_op_classes + 1, sta->supp_op_classes + 1,
sta->supp_op_classes[0]); sta->supp_op_classes[0]);
res = os_snprintf(buf + len, buflen - len, "\n"); len += os_snprintf(buf + len, buflen - len, "\n");
if (!os_snprintf_error(buflen - len, res))
len += res;
} }
if (sta->power_capab) { if (sta->power_capab) {
@ -376,34 +364,6 @@ static int hostapd_ctrl_iface_sta_mib(struct hostapd_data *hapd,
len += ret; len += ret;
} }
#ifdef CONFIG_IEEE80211AX
if ((sta->flags & WLAN_STA_HE) && sta->he_capab) {
res = os_snprintf(buf + len, buflen - len, "he_capab=");
if (!os_snprintf_error(buflen - len, res))
len += res;
len += wpa_snprintf_hex(buf + len, buflen - len,
(const u8 *) sta->he_capab,
sta->he_capab_len);
res = os_snprintf(buf + len, buflen - len, "\n");
if (!os_snprintf_error(buflen - len, res))
len += res;
}
#endif /* CONFIG_IEEE80211AX */
#ifdef CONFIG_IEEE80211BE
if ((sta->flags & WLAN_STA_EHT) && sta->eht_capab) {
res = os_snprintf(buf + len, buflen - len, "eht_capab=");
if (!os_snprintf_error(buflen - len, res))
len += res;
len += wpa_snprintf_hex(buf + len, buflen - len,
(const u8 *) sta->eht_capab,
sta->eht_capab_len);
res = os_snprintf(buf + len, buflen - len, "\n");
if (!os_snprintf_error(buflen - len, res))
len += res;
}
#endif /* CONFIG_IEEE80211BE */
#ifdef CONFIG_IEEE80211AC #ifdef CONFIG_IEEE80211AC
if ((sta->flags & WLAN_STA_VHT) && sta->vht_capabilities) { if ((sta->flags & WLAN_STA_VHT) && sta->vht_capabilities) {
res = os_snprintf(buf + len, buflen - len, res = os_snprintf(buf + len, buflen - len,
@ -412,16 +372,6 @@ static int hostapd_ctrl_iface_sta_mib(struct hostapd_data *hapd,
vht_capabilities_info)); vht_capabilities_info));
if (!os_snprintf_error(buflen - len, res)) if (!os_snprintf_error(buflen - len, res))
len += res; len += res;
res = os_snprintf(buf + len, buflen - len, "vht_capab=");
if (!os_snprintf_error(buflen - len, res))
len += res;
len += wpa_snprintf_hex(buf + len, buflen - len,
(const u8 *) sta->vht_capabilities,
sizeof(*sta->vht_capabilities));
res = os_snprintf(buf + len, buflen - len, "\n");
if (!os_snprintf_error(buflen - len, res))
len += res;
} }
#endif /* CONFIG_IEEE80211AC */ #endif /* CONFIG_IEEE80211AC */
@ -436,15 +386,11 @@ static int hostapd_ctrl_iface_sta_mib(struct hostapd_data *hapd,
if (sta->ext_capability && if (sta->ext_capability &&
buflen - len > (unsigned) (11 + 2 * sta->ext_capability[0])) { buflen - len > (unsigned) (11 + 2 * sta->ext_capability[0])) {
res = os_snprintf(buf + len, buflen - len, "ext_capab="); len += os_snprintf(buf + len, buflen - len, "ext_capab=");
if (!os_snprintf_error(buflen - len, res))
len += res;
len += wpa_snprintf_hex(buf + len, buflen - len, len += wpa_snprintf_hex(buf + len, buflen - len,
sta->ext_capability + 1, sta->ext_capability + 1,
sta->ext_capability[0]); sta->ext_capability[0]);
res = os_snprintf(buf + len, buflen - len, "\n"); len += os_snprintf(buf + len, buflen - len, "\n");
if (!os_snprintf_error(buflen - len, res))
len += res;
} }
if (sta->flags & WLAN_STA_WDS && sta->ifname_wds) { if (sta->flags & WLAN_STA_WDS && sta->ifname_wds) {
@ -473,21 +419,6 @@ static int hostapd_ctrl_iface_sta_mib(struct hostapd_data *hapd,
len += ret; len += ret;
} }
#ifdef CONFIG_IEEE80211BE
if (sta->mld_info.mld_sta) {
for (i = 0; i < MAX_NUM_MLD_LINKS; ++i) {
if (!sta->mld_info.links[i].valid)
continue;
ret = os_snprintf(
buf + len, buflen - len,
"peer_addr[%d]=" MACSTR "\n",
i, MAC2STR(sta->mld_info.links[i].peer_addr));
if (!os_snprintf_error(buflen - len, ret))
len += ret;
}
}
#endif /* CONFIG_IEEE80211BE */
return len; return len;
} }
@ -661,18 +592,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 +654,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;
} }
@ -916,42 +841,6 @@ int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf,
return len; return len;
len += ret; len += ret;
} }
if (hapd->conf->mld_ap) {
struct hostapd_data *link_bss;
ret = os_snprintf(buf + len, buflen - len,
"num_links=%d\n",
hapd->mld->num_links);
if (os_snprintf_error(buflen - len, ret))
return len;
len += ret;
/* Self BSS */
ret = os_snprintf(buf + len, buflen - len,
"link_id=%d\n"
"link_addr=" MACSTR "\n",
hapd->mld_link_id,
MAC2STR(hapd->own_addr));
if (os_snprintf_error(buflen - len, ret))
return len;
len += ret;
/* Partner BSSs */
for_each_mld_link(link_bss, hapd) {
if (link_bss == hapd)
continue;
ret = os_snprintf(buf + len, buflen - len,
"partner_link[%d]=" MACSTR
"\n",
link_bss->mld_link_id,
MAC2STR(link_bss->own_addr));
if (os_snprintf_error(buflen - len, ret))
return len;
len += ret;
}
}
} }
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
@ -1077,8 +966,8 @@ int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf,
"mld_addr[%d]=" MACSTR "\n" "mld_addr[%d]=" MACSTR "\n"
"mld_id[%d]=%d\n" "mld_id[%d]=%d\n"
"mld_link_id[%d]=%d\n", "mld_link_id[%d]=%d\n",
(int) i, MAC2STR(bss->mld->mld_addr), (int) i, MAC2STR(bss->mld_addr),
(int) i, hostapd_get_mld_id(bss), (int) i, bss->conf->mld_id,
(int) i, bss->mld_link_id); (int) i, bss->mld_link_id);
if (os_snprintf_error(buflen - len, ret)) if (os_snprintf_error(buflen - len, ret))
return len; return len;
@ -1143,9 +1032,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

@ -14,7 +14,6 @@
#include "common/hw_features_common.h" #include "common/hw_features_common.h"
#include "common/wpa_ctrl.h" #include "common/wpa_ctrl.h"
#include "hostapd.h" #include "hostapd.h"
#include "beacon.h"
#include "ap_drv_ops.h" #include "ap_drv_ops.h"
#include "drivers/driver.h" #include "drivers/driver.h"
#include "dfs.h" #include "dfs.h"
@ -253,13 +252,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 &&
@ -980,7 +972,6 @@ static int hostapd_dfs_request_channel_switch(struct hostapd_iface *iface,
struct csa_settings csa_settings; struct csa_settings csa_settings;
u8 new_vht_oper_chwidth; u8 new_vht_oper_chwidth;
unsigned int i; unsigned int i;
unsigned int num_err = 0;
wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d", channel); wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d", channel);
wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NEW_CHANNEL wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NEW_CHANNEL
@ -1018,8 +1009,7 @@ static int hostapd_dfs_request_channel_switch(struct hostapd_iface *iface,
oper_centr_freq_seg1_idx, oper_centr_freq_seg1_idx,
cmode->vht_capab, cmode->vht_capab,
&cmode->he_capab[ieee80211_mode], &cmode->he_capab[ieee80211_mode],
&cmode->eht_capab[ieee80211_mode], &cmode->eht_capab[ieee80211_mode]);
hostapd_get_punct_bitmap(iface->bss[0]));
if (err) { if (err) {
wpa_printf(MSG_ERROR, wpa_printf(MSG_ERROR,
@ -1031,10 +1021,10 @@ static int hostapd_dfs_request_channel_switch(struct hostapd_iface *iface,
for (i = 0; i < iface->num_bss; i++) { for (i = 0; i < iface->num_bss; i++) {
err = hostapd_switch_channel(iface->bss[i], &csa_settings); err = hostapd_switch_channel(iface->bss[i], &csa_settings);
if (err) if (err)
num_err++; break;
} }
if (num_err == iface->num_bss) { if (err) {
wpa_printf(MSG_WARNING, wpa_printf(MSG_WARNING,
"DFS failed to schedule CSA (%d) - trying fallback", "DFS failed to schedule CSA (%d) - trying fallback",
err); err);
@ -1151,23 +1141,14 @@ int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq,
int cf1, int cf2) int cf1, int cf2)
{ {
wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_COMPLETED wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_COMPLETED
"success=%d freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d radar_detected=%d", "success=%d freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d",
success, freq, ht_enabled, chan_offset, chan_width, cf1, cf2, success, freq, ht_enabled, chan_offset, chan_width, cf1, cf2);
iface->radar_detected);
if (success) { if (success) {
/* Complete iface/ap configuration */ /* Complete iface/ap configuration */
if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) { if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) {
/* Complete AP configuration for the first bring up. If /* Complete AP configuration for the first bring up. */
* a radar was detected in this channel, interface setup if (iface->state != HAPD_IFACE_ENABLED)
* will be handled in
* 1. hostapd_event_ch_switch() if switching to a
* non-DFS channel
* 2. on next CAC complete event if switching to another
* DFS channel.
*/
if (iface->state != HAPD_IFACE_ENABLED &&
!iface->radar_detected)
hostapd_setup_interface_complete(iface, 0); hostapd_setup_interface_complete(iface, 0);
else else
iface->cac_started = 0; iface->cac_started = 0;
@ -1212,7 +1193,6 @@ int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq,
hostapd_dfs_update_background_chain(iface); hostapd_dfs_update_background_chain(iface);
} }
iface->radar_detected = false;
return 0; return 0;
} }
@ -1456,8 +1436,6 @@ int hostapd_dfs_radar_detected(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);
iface->radar_detected = true;
/* 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;
@ -1551,17 +1529,9 @@ int hostapd_dfs_start_cac(struct hostapd_iface *iface, int freq,
iface->radar_background.cac_started = 1; iface->radar_background.cac_started = 1;
} else { } else {
/* This is called when the driver indicates that an offloaded /* This is called when the driver indicates that an offloaded
* DFS has started CAC. radar_detected might be set for previous * DFS has started CAC. */
* DFS channel. Clear it for this new CAC process. */
hostapd_set_state(iface, HAPD_IFACE_DFS); hostapd_set_state(iface, HAPD_IFACE_DFS);
iface->cac_started = 1; iface->cac_started = 1;
/* Clear radar_detected in case it is for the previous
* frequency. Also remove disabled link's information in RNR
* element from other links. */
iface->radar_detected = false;
if (iface->interfaces && iface->interfaces->count > 1)
ieee802_11_set_beacons(iface);
} }
/* TODO: How to check CAC time for ETSI weather channels? */ /* TODO: How to check CAC time for ETSI weather channels? */
iface->dfs_cac_ms = 60000; iface->dfs_cac_ms = 60000;

View file

@ -3941,7 +3941,6 @@ int hostapd_dpp_push_button(struct hostapd_data *hapd, const char *cmd)
eloop_register_timeout(100, 0, hostapd_dpp_push_button_expire, eloop_register_timeout(100, 0, hostapd_dpp_push_button_expire,
hapd, NULL); hapd, NULL);
wpa_msg(hapd->msg_ctx, MSG_INFO, DPP_EVENT_PB_STATUS "started");
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,
@ -561,13 +513,11 @@ 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,
"MLD: Set ML info in RSN Authenticator"); "MLD: Set ML info in RSN Authenticator");
wpa_auth_set_ml_info(sta->wpa_sm, wpa_auth_set_ml_info(sta->wpa_sm, hapd->mld_addr,
sta->mld_assoc_link_id, sta->mld_assoc_link_id,
&sta->mld_info); &sta->mld_info);
} }
@ -578,7 +528,7 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
elems.rsnxe ? elems.rsnxe - 2 : NULL, elems.rsnxe ? elems.rsnxe - 2 : NULL,
elems.rsnxe ? elems.rsnxe_len + 2 : 0, elems.rsnxe ? elems.rsnxe_len + 2 : 0,
elems.mdie, elems.mdie_len, elems.mdie, elems.mdie_len,
elems.owe_dh, elems.owe_dh_len, NULL); elems.owe_dh, elems.owe_dh_len);
reason = WLAN_REASON_INVALID_IE; reason = WLAN_REASON_INVALID_IE;
status = WLAN_STATUS_INVALID_IE; status = WLAN_STATUS_INVALID_IE;
switch (res) { switch (res) {
@ -823,9 +773,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);
} }
@ -963,54 +910,6 @@ fail:
} }
static void hostapd_remove_sta(struct hostapd_data *hapd, struct sta_info *sta)
{
ap_sta_set_authorized(hapd, sta, 0);
sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
hostapd_set_sta_flags(hapd, sta);
wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
ap_free_sta(hapd, sta);
}
#ifdef CONFIG_IEEE80211BE
static void hostapd_notif_disassoc_mld(struct hostapd_data *assoc_hapd,
struct sta_info *sta,
const u8 *addr)
{
unsigned int link_id, i;
struct hostapd_data *tmp_hapd;
struct hapd_interfaces *interfaces = assoc_hapd->iface->interfaces;
/* Remove STA entry in non-assoc links */
for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
if (!sta->mld_info.links[link_id].valid)
continue;
for (i = 0; i < interfaces->count; i++) {
struct sta_info *tmp_sta;
tmp_hapd = interfaces->iface[i]->bss[0];
if (!tmp_hapd->conf->mld_ap ||
assoc_hapd == tmp_hapd ||
assoc_hapd->conf->mld_id != tmp_hapd->conf->mld_id)
continue;
tmp_sta = ap_get_sta(tmp_hapd, addr);
if (tmp_sta)
ap_free_sta(tmp_hapd, tmp_sta);
}
}
/* Remove STA in assoc link */
hostapd_remove_sta(assoc_hapd, sta);
}
#endif /* CONFIG_IEEE80211BE */
void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr) void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr)
{ {
struct sta_info *sta; struct sta_info *sta;
@ -1032,50 +931,6 @@ void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr)
HOSTAPD_LEVEL_INFO, "disassociated"); HOSTAPD_LEVEL_INFO, "disassociated");
sta = ap_get_sta(hapd, addr); sta = ap_get_sta(hapd, addr);
#ifdef CONFIG_IEEE80211BE
if (hostapd_is_mld_ap(hapd)) {
struct hostapd_data *assoc_hapd;
unsigned int i;
if (!sta) {
/* Find non-MLO cases from any of the affiliated AP
* links. */
for (i = 0; i < hapd->iface->interfaces->count; ++i) {
struct hostapd_iface *h =
hapd->iface->interfaces->iface[i];
struct hostapd_data *h_hapd = h->bss[0];
struct hostapd_bss_config *hconf = h_hapd->conf;
if (!hconf->mld_ap ||
hconf->mld_id != hapd->conf->mld_id)
continue;
sta = ap_get_sta(h_hapd, addr);
if (sta) {
if (!sta->mld_info.mld_sta) {
hapd = h_hapd;
goto legacy;
}
break;
}
}
} else if (!sta->mld_info.mld_sta) {
goto legacy;
}
if (!sta) {
wpa_printf(MSG_DEBUG,
"Disassociation notification for unknown STA "
MACSTR, MAC2STR(addr));
return;
}
sta = hostapd_ml_get_assoc_sta(hapd, sta, &assoc_hapd);
if (sta)
hostapd_notif_disassoc_mld(assoc_hapd, sta, addr);
return;
}
legacy:
#endif /* CONFIG_IEEE80211BE */
if (sta == NULL) { if (sta == NULL) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"Disassociation notification for unknown STA " "Disassociation notification for unknown STA "
@ -1083,27 +938,19 @@ legacy:
return; return;
} }
hostapd_remove_sta(hapd, sta); ap_sta_set_authorized(hapd, sta, 0);
sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
hostapd_set_sta_flags(hapd, sta);
wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
ap_free_sta(hapd, sta);
} }
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;
@ -1604,6 +1451,7 @@ int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da,
#ifdef CONFIG_IEEE80211R_AP #ifdef CONFIG_IEEE80211R_AP
static void hostapd_notify_auth_ft_finish(void *ctx, const u8 *dst, static void hostapd_notify_auth_ft_finish(void *ctx, const u8 *dst,
const u8 *bssid,
u16 auth_transaction, u16 status, u16 auth_transaction, u16 status,
const u8 *ies, size_t ies_len) const u8 *ies, size_t ies_len)
{ {
@ -1679,7 +1527,7 @@ static void hostapd_notif_auth(struct hostapd_data *hapd,
status = WLAN_STATUS_UNSPECIFIED_FAILURE; status = WLAN_STATUS_UNSPECIFIED_FAILURE;
goto fail; goto fail;
} }
wpa_ft_process_auth(sta->wpa_sm, wpa_ft_process_auth(sta->wpa_sm, rx_auth->bssid,
rx_auth->auth_transaction, rx_auth->ies, rx_auth->auth_transaction, rx_auth->ies,
rx_auth->ies_len, rx_auth->ies_len,
hostapd_notify_auth_ft_finish, hapd); hostapd_notify_auth_ft_finish, hapd);
@ -1815,38 +1663,10 @@ switch_link_hapd(struct hostapd_data *hapd, int link_id)
} }
static struct hostapd_data *
switch_link_scan(struct hostapd_data *hapd, u64 scan_cookie)
{
#ifdef CONFIG_IEEE80211BE
if (hapd->conf->mld_ap && scan_cookie != 0) {
unsigned int i;
for (i = 0; i < hapd->iface->interfaces->count; i++) {
struct hostapd_iface *h;
struct hostapd_data *h_hapd;
h = hapd->iface->interfaces->iface[i];
h_hapd = h->bss[0];
if (!hostapd_is_ml_partner(hapd, h_hapd))
continue;
if (h_hapd->scan_cookie == scan_cookie) {
h_hapd->scan_cookie = 0;
return h_hapd;
}
}
}
#endif /* CONFIG_IEEE80211BE */
return hapd;
}
#define HAPD_BROADCAST ((struct hostapd_data *) -1) #define HAPD_BROADCAST ((struct hostapd_data *) -1)
static struct hostapd_data * get_hapd_bssid(struct hostapd_iface *iface, static struct hostapd_data * get_hapd_bssid(struct hostapd_iface *iface,
const u8 *bssid, int link_id) const u8 *bssid)
{ {
size_t i; size_t i;
@ -1857,35 +1677,8 @@ static struct hostapd_data * get_hapd_bssid(struct hostapd_iface *iface,
return HAPD_BROADCAST; return HAPD_BROADCAST;
for (i = 0; i < iface->num_bss; i++) { for (i = 0; i < iface->num_bss; i++) {
struct hostapd_data *hapd; if (ether_addr_equal(bssid, iface->bss[i]->own_addr))
#ifdef CONFIG_IEEE80211BE return iface->bss[i];
struct hostapd_data *p_hapd;
#endif /* CONFIG_IEEE80211BE */
hapd = iface->bss[i];
if (ether_addr_equal(bssid, hapd->own_addr))
return hapd;
#ifdef CONFIG_IEEE80211BE
if (ether_addr_equal(bssid, hapd->own_addr) ||
(hapd->conf->mld_ap &&
ether_addr_equal(bssid, hapd->mld->mld_addr) &&
link_id == hapd->mld_link_id))
return hapd;
if (!hapd->conf->mld_ap)
continue;
for_each_mld_link(p_hapd, hapd) {
if (p_hapd == hapd)
continue;
if (ether_addr_equal(bssid, p_hapd->own_addr) ||
(ether_addr_equal(bssid, p_hapd->mld->mld_addr) &&
link_id == p_hapd->mld_link_id))
return p_hapd;
}
#endif /* CONFIG_IEEE80211BE */
} }
return NULL; return NULL;
@ -1896,7 +1689,7 @@ static void hostapd_rx_from_unknown_sta(struct hostapd_data *hapd,
const u8 *bssid, const u8 *addr, const u8 *bssid, const u8 *addr,
int wds) int wds)
{ {
hapd = get_hapd_bssid(hapd->iface, bssid, -1); hapd = get_hapd_bssid(hapd->iface, bssid);
if (hapd == NULL || hapd == HAPD_BROADCAST) if (hapd == NULL || hapd == HAPD_BROADCAST)
return; return;
@ -1911,9 +1704,8 @@ static int hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt)
const u8 *bssid; const u8 *bssid;
struct hostapd_frame_info fi; struct hostapd_frame_info fi;
int ret; int ret;
bool is_mld = false;
if (rx_mgmt->ctx)
hapd = rx_mgmt->ctx;
hapd = switch_link_hapd(hapd, rx_mgmt->link_id); hapd = switch_link_hapd(hapd, rx_mgmt->link_id);
iface = hapd->iface; iface = hapd->iface;
@ -1937,7 +1729,14 @@ static int hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt)
if (bssid == NULL) if (bssid == NULL)
return 0; return 0;
hapd = get_hapd_bssid(iface, bssid, rx_mgmt->link_id); #ifdef CONFIG_IEEE80211BE
if (hapd->conf->mld_ap &&
ether_addr_equal(hapd->mld_addr, bssid))
is_mld = true;
#endif /* CONFIG_IEEE80211BE */
if (!is_mld)
hapd = get_hapd_bssid(iface, bssid);
if (!hapd) { if (!hapd) {
u16 fc = le_to_host16(hdr->frame_control); u16 fc = le_to_host16(hdr->frame_control);
@ -1989,17 +1788,22 @@ static void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, const u8 *buf,
struct ieee80211_hdr *hdr; struct ieee80211_hdr *hdr;
struct hostapd_data *orig_hapd, *tmp_hapd; struct hostapd_data *orig_hapd, *tmp_hapd;
#ifdef CONFIG_IEEE80211BE
if (hapd->conf->mld_ap && link_id != -1) {
tmp_hapd = hostapd_mld_get_link_bss(hapd, link_id);
if (tmp_hapd)
hapd = tmp_hapd;
}
#endif /* CONFIG_IEEE80211BE */
orig_hapd = hapd; orig_hapd = hapd;
hdr = (struct ieee80211_hdr *) buf; hdr = (struct ieee80211_hdr *) buf;
hapd = switch_link_hapd(hapd, link_id); tmp_hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len));
tmp_hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len), link_id);
if (tmp_hapd) { if (tmp_hapd) {
hapd = tmp_hapd; hapd = tmp_hapd;
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
} else if (hapd->conf->mld_ap && } else if (hapd->conf->mld_ap &&
ether_addr_equal(hapd->mld->mld_addr, ether_addr_equal(hapd->mld_addr, get_hdr_bssid(hdr, len))) {
get_hdr_bssid(hdr, len))) {
/* AP MLD address match - use hapd pointer as-is */ /* AP MLD address match - use hapd pointer as-is */
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
} else { } else {
@ -2010,7 +1814,7 @@ static void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, const u8 *buf,
if (stype != WLAN_FC_STYPE_ACTION || len <= 25 || if (stype != WLAN_FC_STYPE_ACTION || len <= 25 ||
buf[24] != WLAN_ACTION_PUBLIC) buf[24] != WLAN_ACTION_PUBLIC)
return; return;
hapd = get_hapd_bssid(orig_hapd->iface, hdr->addr2, link_id); hapd = get_hapd_bssid(orig_hapd->iface, hdr->addr2);
if (!hapd || hapd == HAPD_BROADCAST) if (!hapd || hapd == HAPD_BROADCAST)
return; return;
/* /*
@ -2046,6 +1850,57 @@ 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;
unsigned int j;
for (j = 0; j < iface->num_bss; j++) {
sta = ap_get_sta(iface->bss[j], src);
if (sta && (sta->flags & WLAN_STA_ASSOC) &&
(!rsn || sta->wpa_sm))
return iface->bss[j];
}
return NULL;
}
#ifdef CONFIG_IEEE80211BE
static bool search_mld_sta(struct hostapd_data **p_hapd, const u8 *src)
{
struct hostapd_data *hapd = *p_hapd;
unsigned int i;
/* Search for STA on other MLO BSSs */
for (i = 0; i < hapd->iface->interfaces->count; i++) {
struct hostapd_iface *h =
hapd->iface->interfaces->iface[i];
struct hostapd_data *h_hapd = h->bss[0];
struct hostapd_bss_config *hconf = h_hapd->conf;
if (!hconf->mld_ap ||
hconf->mld_id != hapd->conf->mld_id)
continue;
h_hapd = hostapd_find_by_sta(h, src, false);
if (h_hapd) {
struct sta_info *sta = ap_get_sta(h_hapd, src);
if (sta && sta->mld_info.mld_sta &&
sta->mld_assoc_link_id != h_hapd->mld_link_id)
continue;
*p_hapd = h_hapd;
return true;
}
}
return false;
}
#endif /* CONFIG_IEEE80211BE */
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,
@ -2054,10 +1909,28 @@ static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src,
struct hostapd_data *orig_hapd = hapd; struct hostapd_data *orig_hapd = hapd;
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
if (link_id != -1) {
struct hostapd_data *h_hapd;
hapd = switch_link_hapd(hapd, link_id); hapd = switch_link_hapd(hapd, link_id);
hapd = hostapd_find_by_sta(hapd->iface, src, true, NULL); h_hapd = hostapd_find_by_sta(hapd->iface, src, true);
if (!h_hapd)
h_hapd = hostapd_find_by_sta(orig_hapd->iface, src,
true);
if (!h_hapd)
h_hapd = hostapd_find_by_sta(hapd->iface, src, false);
if (!h_hapd)
h_hapd = hostapd_find_by_sta(orig_hapd->iface, src,
false);
if (h_hapd)
hapd = h_hapd;
} else if (hapd->conf->mld_ap) {
search_mld_sta(&hapd, src);
} else {
hapd = hostapd_find_by_sta(hapd->iface, src, false);
}
#else /* CONFIG_IEEE80211BE */ #else /* CONFIG_IEEE80211BE */
hapd = hostapd_find_by_sta(hapd->iface, src, false, NULL); hapd = hostapd_find_by_sta(hapd->iface, src, false);
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
if (!hapd) { if (!hapd) {
@ -2384,136 +2257,6 @@ err:
#endif /* CONFIG_OWE */ #endif /* CONFIG_OWE */
#ifdef NEED_AP_MLME
static void hostapd_eapol_tx_status(struct hostapd_data *hapd, const u8 *dst,
const u8 *data, size_t len, int ack,
int link_id)
{
struct sta_info *sta;
hapd = switch_link_hapd(hapd, link_id);
hapd = hostapd_find_by_sta(hapd->iface, dst, false, &sta);
if (!sta) {
wpa_printf(MSG_DEBUG, "Ignore TX status for Data frame to STA "
MACSTR " that is not currently associated",
MAC2STR(dst));
return;
}
ieee802_1x_eapol_tx_status(hapd, sta, data, len, ack);
}
#endif /* NEED_AP_MLME */
#ifdef CONFIG_IEEE80211AX
static void hostapd_event_color_change(struct hostapd_data *hapd, bool success)
{
struct hostapd_data *bss;
size_t i;
for (i = 0; i < hapd->iface->num_bss; i++) {
bss = hapd->iface->bss[i];
if (bss->cca_color == 0)
continue;
if (success)
hapd->iface->conf->he_op.he_bss_color = bss->cca_color;
bss->cca_in_progress = 0;
if (ieee802_11_set_beacon(bss)) {
wpa_printf(MSG_ERROR, "Failed to remove BCCA element");
bss->cca_in_progress = 1;
} else {
hostapd_cleanup_cca_params(bss);
}
}
}
#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)
{ {
@ -2546,29 +2289,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
michael_mic_failure(hapd, data->michael_mic_failure.src, 1); michael_mic_failure(hapd, data->michael_mic_failure.src, 1);
break; break;
case EVENT_SCAN_RESULTS: case EVENT_SCAN_RESULTS:
#ifdef NEED_AP_MLME
if (data)
hapd = switch_link_scan(hapd,
data->scan_info.scan_cookie);
#endif /* NEED_AP_MLME */
if (hapd->iface->scan_cb) if (hapd->iface->scan_cb)
hapd->iface->scan_cb(hapd->iface); hapd->iface->scan_cb(hapd->iface);
#ifdef CONFIG_IEEE80211BE
if (!hapd->iface->scan_cb && hapd->conf->mld_ap) {
/* Other links may be waiting for HT scan result */
unsigned int i;
for (i = 0; i < hapd->iface->interfaces->count; i++) {
struct hostapd_iface *h =
hapd->iface->interfaces->iface[i];
struct hostapd_data *h_hapd = h->bss[0];
if (hostapd_is_ml_partner(hapd, h_hapd) &&
h_hapd->iface->scan_cb)
h_hapd->iface->scan_cb(h_hapd->iface);
}
}
#endif /* CONFIG_IEEE80211BE */
break; break;
case EVENT_WPS_BUTTON_PUSHED: case EVENT_WPS_BUTTON_PUSHED:
hostapd_wps_button_pushed(hapd, NULL); hostapd_wps_button_pushed(hapd, NULL);
@ -2592,11 +2314,11 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
} }
break; break;
case EVENT_EAPOL_TX_STATUS: case EVENT_EAPOL_TX_STATUS:
hapd = switch_link_hapd(hapd, data->eapol_tx_status.link_id);
hostapd_eapol_tx_status(hapd, data->eapol_tx_status.dst, hostapd_eapol_tx_status(hapd, data->eapol_tx_status.dst,
data->eapol_tx_status.data, data->eapol_tx_status.data,
data->eapol_tx_status.data_len, data->eapol_tx_status.data_len,
data->eapol_tx_status.ack, data->eapol_tx_status.ack);
data->eapol_tx_status.link_id);
break; break;
case EVENT_DRIVER_CLIENT_POLL_OK: case EVENT_DRIVER_CLIENT_POLL_OK:
hostapd_client_poll_ok(hapd, data->client_poll.addr); hostapd_client_poll_ok(hapd, data->client_poll.addr);
@ -2791,22 +2513,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:
@ -2831,41 +2561,28 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
/* The BSS color is shared amongst all BBSs on a specific phy. /* The BSS color is shared amongst all BBSs on a specific phy.
* Therefore we always start the color change on the primary * Therefore we always start the color change on the primary
* BSS. */ * BSS. */
hapd = switch_link_hapd(hapd,
data->bss_color_collision.link_id);
wpa_printf(MSG_DEBUG, "BSS color collision on %s", wpa_printf(MSG_DEBUG, "BSS color collision on %s",
hapd->conf->iface); hapd->conf->iface);
hostapd_switch_color(hapd->iface->bss[0], hostapd_switch_color(hapd->iface->bss[0],
data->bss_color_collision.bitmap); data->bss_color_collision.bitmap);
break; break;
case EVENT_CCA_STARTED_NOTIFY: case EVENT_CCA_STARTED_NOTIFY:
hapd = switch_link_hapd(hapd, wpa_printf(MSG_DEBUG, "CCA started on on %s",
data->bss_color_collision.link_id);
wpa_printf(MSG_DEBUG, "CCA started on %s",
hapd->conf->iface); hapd->conf->iface);
break; break;
case EVENT_CCA_ABORTED_NOTIFY: case EVENT_CCA_ABORTED_NOTIFY:
hapd = switch_link_hapd(hapd, wpa_printf(MSG_DEBUG, "CCA aborted on on %s",
data->bss_color_collision.link_id);
wpa_printf(MSG_DEBUG, "CCA aborted on %s",
hapd->conf->iface); hapd->conf->iface);
hostapd_event_color_change(hapd, false); hostapd_cleanup_cca_params(hapd);
break; break;
case EVENT_CCA_NOTIFY: case EVENT_CCA_NOTIFY:
hapd = switch_link_hapd(hapd, wpa_printf(MSG_DEBUG, "CCA finished on on %s",
data->bss_color_collision.link_id);
wpa_printf(MSG_DEBUG, "CCA finished on %s",
hapd->conf->iface); hapd->conf->iface);
hostapd_event_color_change(hapd, true); if (hapd->cca_color)
hapd->iface->conf->he_op.he_bss_color = hapd->cca_color;
hostapd_cleanup_cca_params(hapd);
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;

File diff suppressed because it is too large Load diff

View file

@ -44,7 +44,6 @@ struct mesh_conf;
#endif /* CONFIG_CTRL_IFACE_UDP */ #endif /* CONFIG_CTRL_IFACE_UDP */
struct hostapd_iface; struct hostapd_iface;
struct hostapd_mld;
struct hapd_interfaces { struct hapd_interfaces {
int (*reload_config)(struct hostapd_iface *iface); int (*reload_config)(struct hostapd_iface *iface);
@ -94,12 +93,6 @@ struct hapd_interfaces {
unsigned char ctrl_iface_cookie[CTRL_IFACE_COOKIE_LEN]; unsigned char ctrl_iface_cookie[CTRL_IFACE_COOKIE_LEN];
#endif /* CONFIG_CTRL_IFACE_UDP */ #endif /* CONFIG_CTRL_IFACE_UDP */
#ifdef CONFIG_IEEE80211BE
struct hostapd_mld **mld;
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 */
}; };
enum hostapd_chan_status { enum hostapd_chan_status {
@ -169,21 +162,6 @@ struct hostapd_sae_commit_queue {
u8 msg[]; u8 msg[];
}; };
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;
};
/** /**
* struct hostapd_data - hostapd per-BSS data structure * struct hostapd_data - hostapd per-BSS data structure
*/ */
@ -197,6 +175,12 @@ struct hostapd_data {
unsigned int reenable_beacon:1; unsigned int reenable_beacon:1;
u8 own_addr[ETH_ALEN]; u8 own_addr[ETH_ALEN];
u8 mld_addr[ETH_ALEN];
u8 mld_link_id;
/* Used for mld_link_id assignment - valid on the first MLD BSS only */
u8 mld_next_link_id;
struct hostapd_data *mld_first_bss;
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 */
@ -309,8 +293,7 @@ struct hostapd_data {
void *wps_event_cb_ctx; void *wps_event_cb_ctx;
void (*sta_authorized_cb)(void *ctx, const u8 *mac_addr, void (*sta_authorized_cb)(void *ctx, const u8 *mac_addr,
int authorized, const u8 *p2p_dev_addr, int authorized, const u8 *p2p_dev_addr);
const u8 *ip);
void *sta_authorized_cb_ctx; void *sta_authorized_cb_ctx;
void (*setup_complete_cb)(void *ctx); void (*setup_complete_cb)(void *ctx);
@ -422,10 +405,8 @@ struct hostapd_data {
u8 beacon_req_token; u8 beacon_req_token;
u8 lci_req_token; u8 lci_req_token;
u8 range_req_token; u8 range_req_token;
u8 link_measurement_req_token;
unsigned int lci_req_active:1; unsigned int lci_req_active:1;
unsigned int range_req_active:1; unsigned int range_req_active:1;
unsigned int link_mesr_req_active:1;
int dhcp_sock; /* UDP socket used with the DHCP server */ int dhcp_sock; /* UDP socket used with the DHCP server */
@ -490,17 +471,6 @@ struct hostapd_data {
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
u8 eht_mld_bss_param_change; u8 eht_mld_bss_param_change;
struct hostapd_mld *mld;
struct dl_list link;
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 */
@ -509,9 +479,6 @@ struct hostapd_data {
#ifdef CONFIG_NAN_USD #ifdef CONFIG_NAN_USD
struct nan_de *nan_de; struct nan_de *nan_de;
#endif /* CONFIG_NAN_USD */ #endif /* CONFIG_NAN_USD */
u64 scan_cookie; /* Scan instance identifier for the ongoing HT40 scan
*/
}; };
@ -525,33 +492,6 @@ struct hostapd_sta_info {
#endif /* CONFIG_TAXONOMY */ #endif /* CONFIG_TAXONOMY */
}; };
#ifdef CONFIG_IEEE80211BE
/**
* struct hostapd_mld - hostapd per-mld data structure
*/
struct hostapd_mld {
char name[IFNAMSIZ + 1];
u8 mld_addr[ETH_ALEN];
u8 next_link_id;
u8 num_links;
/* Number of hostapd_data (hapd) referencing this. num_links cannot be
* used since num_links can go to 0 even when a BSS is disabled and
* when it is re-enabled, the MLD should exist and hence it cannot be
* freed when num_links is 0.
*/
u8 refcount;
struct hostapd_data *fbss;
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
#endif /* CONFIG_IEEE80211BE */
/** /**
* struct hostapd_iface - hostapd per-interface data structure * struct hostapd_iface - hostapd per-interface data structure
*/ */
@ -608,7 +548,6 @@ struct hostapd_iface {
u64 drv_flags; u64 drv_flags;
u64 drv_flags2; u64 drv_flags2;
unsigned int drv_rrm_flags;
/* /*
* A bitmap of supported protocols for probe response offload. See * A bitmap of supported protocols for probe response offload. See
@ -634,8 +573,6 @@ struct hostapd_iface {
int *basic_rates; int *basic_rates;
int freq; int freq;
bool radar_detected;
/* Background radar configuration */ /* Background radar configuration */
struct { struct {
int channel; int channel;
@ -711,7 +648,6 @@ struct hostapd_iface {
#ifdef CONFIG_ACS #ifdef CONFIG_ACS
unsigned int acs_num_completed_scans; unsigned int acs_num_completed_scans;
unsigned int acs_num_retries;
#endif /* CONFIG_ACS */ #endif /* CONFIG_ACS */
void (*scan_cb)(struct hostapd_iface *iface); void (*scan_cb)(struct hostapd_iface *iface);
@ -738,12 +674,6 @@ struct hostapd_iface {
/* Configured freq of interface is NO_IR */ /* Configured freq of interface is NO_IR */
bool is_no_ir; bool is_no_ir;
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 */
@ -786,8 +716,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);
@ -852,37 +780,24 @@ int hostapd_mbssid_get_bss_index(struct hostapd_data *hapd);
struct hostapd_data * hostapd_mld_get_link_bss(struct hostapd_data *hapd, struct hostapd_data * hostapd_mld_get_link_bss(struct hostapd_data *hapd,
u8 link_id); u8 link_id);
int hostapd_link_remove(struct hostapd_data *hapd, u32 count); int hostapd_link_remove(struct hostapd_data *hapd, u32 count);
bool hostapd_is_ml_partner(struct hostapd_data *hapd1,
struct hostapd_data *hapd2);
u8 hostapd_get_mld_id(struct hostapd_data *hapd);
int hostapd_mld_add_link(struct hostapd_data *hapd);
int hostapd_mld_remove_link(struct hostapd_data *hapd);
struct hostapd_data * hostapd_mld_get_first_bss(struct hostapd_data *hapd);
void free_beacon_data(struct beacon_data *beacon);
int hostapd_fill_cca_settings(struct hostapd_data *hapd,
struct cca_settings *settings);
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
#define for_each_mld_link(_link, _bss_idx, _iface_idx, _ifaces, _mld_id) \
bool hostapd_mld_is_first_bss(struct hostapd_data *hapd); for (_iface_idx = 0; \
void hostapd_mld_interface_freed(struct hostapd_data *hapd); _iface_idx < (_ifaces)->count; \
_iface_idx++) \
#define for_each_mld_link(partner, self) \ for (_bss_idx = 0; \
dl_list_for_each(partner, &self->mld->links, struct hostapd_data, link) _bss_idx < \
(_ifaces)->iface[_iface_idx]->num_bss; \
_bss_idx++) \
for (_link = \
(_ifaces)->iface[_iface_idx]->bss[_bss_idx]; \
_link && _link->conf->mld_ap && \
_link->conf->mld_id == _mld_id; \
_link = NULL)
#else /* CONFIG_IEEE80211BE */ #else /* CONFIG_IEEE80211BE */
#define for_each_mld_link(_link, _bss_idx, _iface_idx, _ifaces, _mld_id) \
static inline bool hostapd_mld_is_first_bss(struct hostapd_data *hapd)
{
return true;
}
#define for_each_mld_link(partner, self) \
if (false) if (false)
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
u16 hostapd_get_punct_bitmap(struct hostapd_data *hapd);
#endif /* HOSTAPD_H */ #endif /* HOSTAPD_H */

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;
@ -110,7 +107,9 @@ int hostapd_get_hw_features(struct hostapd_iface *iface)
*/ */
orig_mode_valid = true; orig_mode_valid = true;
mode = iface->current_mode->mode; mode = iface->current_mode->mode;
is_6ghz = iface->current_mode->is_6ghz; is_6ghz = mode == HOSTAPD_MODE_IEEE80211A &&
iface->current_mode->num_channels > 0 &&
is_6ghz_freq(iface->current_mode->channels[0].freq);
iface->current_mode = NULL; iface->current_mode = NULL;
} }
hostapd_free_hw_features(iface->hw_features, iface->num_hw_features); hostapd_free_hw_features(iface->hw_features, iface->num_hw_features);
@ -171,25 +170,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;
} }
@ -528,12 +508,6 @@ static void ap_ht40_scan_retry(void *eloop_data, void *user_data)
else else
ieee80211n_scan_channels_5g(iface, &params); ieee80211n_scan_channels_5g(iface, &params);
params.link_id = -1;
#ifdef CONFIG_IEEE80211BE
if (iface->bss[0]->conf->mld_ap)
params.link_id = iface->bss[0]->mld_link_id;
#endif /* CONFIG_IEEE80211BE */
ret = hostapd_driver_scan(iface->bss[0], &params); ret = hostapd_driver_scan(iface->bss[0], &params);
iface->num_ht40_scan_tries++; iface->num_ht40_scan_tries++;
os_free(params.freqs); os_free(params.freqs);
@ -549,7 +523,6 @@ static void ap_ht40_scan_retry(void *eloop_data, void *user_data)
if (ret == 0) { if (ret == 0) {
iface->scan_cb = ieee80211n_check_scan; iface->scan_cb = ieee80211n_check_scan;
iface->bss[0]->scan_cookie = params.scan_cookie;
return; return;
} }
@ -585,11 +558,6 @@ static int ieee80211n_check_40mhz(struct hostapd_iface *iface)
else else
ieee80211n_scan_channels_5g(iface, &params); ieee80211n_scan_channels_5g(iface, &params);
params.link_id = -1;
#ifdef CONFIG_IEEE80211BE
if (iface->bss[0]->conf->mld_ap)
params.link_id = iface->bss[0]->mld_link_id;
#endif /* CONFIG_IEEE80211BE */
ret = hostapd_driver_scan(iface->bss[0], &params); ret = hostapd_driver_scan(iface->bss[0], &params);
os_free(params.freqs); os_free(params.freqs);
@ -611,7 +579,6 @@ static int ieee80211n_check_40mhz(struct hostapd_iface *iface)
} }
iface->scan_cb = ieee80211n_check_scan; iface->scan_cb = ieee80211n_check_scan;
iface->bss[0]->scan_cookie = params.scan_cookie;
return 1; return 1;
} }
@ -1103,7 +1070,9 @@ static bool skip_mode(struct hostapd_iface *iface,
return true; return true;
if (is_6ghz_op_class(iface->conf->op_class) && iface->freq == 0 && if (is_6ghz_op_class(iface->conf->op_class) && iface->freq == 0 &&
!mode->is_6ghz) (mode->mode != HOSTAPD_MODE_IEEE80211A ||
mode->num_channels == 0 ||
!is_6ghz_freq(mode->channels[0].freq)))
return true; return true;
return false; return false;
@ -1413,34 +1382,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 */

File diff suppressed because it is too large Load diff

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);
@ -129,10 +129,11 @@ u16 copy_sta_he_6ghz_capab(struct hostapd_data *hapd, struct sta_info *sta,
const u8 *he_6ghz_capab); const u8 *he_6ghz_capab);
int hostapd_get_he_twt_responder(struct hostapd_data *hapd, int hostapd_get_he_twt_responder(struct hostapd_data *hapd,
enum ieee80211_op_mode mode); enum ieee80211_op_mode mode);
bool hostapd_get_ht_vht_twt_responder(struct hostapd_data *hapd);
u8 * hostapd_eid_cca(struct hostapd_data *hapd, u8 *eid); u8 * hostapd_eid_cca(struct hostapd_data *hapd, u8 *eid);
void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr, void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr,
const u8 *buf, size_t len, int ack); const u8 *buf, size_t len, int ack);
void hostapd_eapol_tx_status(struct hostapd_data *hapd, const u8 *dst,
const u8 *data, size_t len, int ack);
void ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src, void ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src,
int wds); int wds);
u8 * hostapd_eid_assoc_comeback_time(struct hostapd_data *hapd, u8 * hostapd_eid_assoc_comeback_time(struct hostapd_data *hapd,
@ -147,8 +148,7 @@ u8 * hostapd_eid_time_adv(struct hostapd_data *hapd, u8 *eid);
u8 * hostapd_eid_time_zone(struct hostapd_data *hapd, u8 *eid); u8 * hostapd_eid_time_zone(struct hostapd_data *hapd, u8 *eid);
int hostapd_update_time_adv(struct hostapd_data *hapd); int hostapd_update_time_adv(struct hostapd_data *hapd);
void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr); void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr);
u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid, u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid);
u16 value);
int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta); int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta);
#ifdef CONFIG_SAE #ifdef CONFIG_SAE
@ -227,10 +227,8 @@ void auth_sae_process_commit(void *eloop_ctx, void *user_ctx);
u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len); u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len);
u16 check_ext_capab(struct hostapd_data *hapd, struct sta_info *sta, u16 check_ext_capab(struct hostapd_data *hapd, struct sta_info *sta,
const u8 *ext_capab_ie, size_t ext_capab_ie_len); const u8 *ext_capab_ie, size_t ext_capab_ie_len);
size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type, size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type);
bool include_mld_params); u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type);
u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type,
bool include_mld_params);
int ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta, int ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta,
int res, struct radius_sta *info); int res, struct radius_sta *info);
size_t hostapd_eid_eht_capab_len(struct hostapd_data *hapd, size_t hostapd_eid_eht_capab_len(struct hostapd_data *hapd,
@ -250,6 +248,8 @@ u8 * hostapd_eid_mbssid(struct hostapd_data *hapd, u8 *eid, u8 *end,
u8 **elem_offset, u8 **elem_offset,
const u8 *known_bss, size_t known_bss_len, u8 *rnr_eid, const u8 *known_bss, size_t known_bss_len, u8 *rnr_eid,
u8 *rnr_count, u8 **rnr_offset, size_t rnr_len); u8 *rnr_count, u8 **rnr_offset, size_t rnr_len);
void punct_update_legacy_bw(u16 bitmap, u8 pri_chan,
enum oper_chan_width *width, u8 *seg0, u8 *seg1);
bool hostapd_is_mld_ap(struct hostapd_data *hapd); bool hostapd_is_mld_ap(struct hostapd_data *hapd);
const char * sae_get_password(struct hostapd_data *hapd, const char * sae_get_password(struct hostapd_data *hapd,
struct sta_info *sta, const char *rx_id, struct sta_info *sta, const char *rx_id,

View file

@ -128,9 +128,6 @@ static int hostapd_radius_acl_query(struct hostapd_data *hapd, const u8 *addr,
goto fail; goto fail;
} }
if (!radius_msg_add_msg_auth(msg))
goto fail;
os_snprintf(buf, sizeof(buf), RADIUS_ADDR_FORMAT, MAC2STR(addr)); os_snprintf(buf, sizeof(buf), RADIUS_ADDR_FORMAT, MAC2STR(addr));
if (!radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, (u8 *) buf, if (!radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, (u8 *) buf,
os_strlen(buf))) { os_strlen(buf))) {
@ -508,9 +505,7 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
"Found matching Access-Request for RADIUS message (id=%d)", "Found matching Access-Request for RADIUS message (id=%d)",
query->radius_id); query->radius_id);
if (radius_msg_verify( if (radius_msg_verify(msg, shared_secret, shared_secret_len, req, 0)) {
msg, shared_secret, shared_secret_len, req,
hapd->conf->radius_require_message_authenticator)) {
wpa_printf(MSG_INFO, wpa_printf(MSG_INFO,
"Incoming RADIUS packet did not have correct authenticator - dropped"); "Incoming RADIUS packet did not have correct authenticator - dropped");
return RADIUS_RX_INVALID_AUTHENTICATOR; return RADIUS_RX_INVALID_AUTHENTICATOR;
@ -601,8 +596,7 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req,
if (query->radius_psk) { if (query->radius_psk) {
struct sta_info *sta; struct sta_info *sta;
bool success = cache->accepted == HOSTAPD_ACL_ACCEPT || bool success = cache->accepted == HOSTAPD_ACL_ACCEPT;
cache->accepted == HOSTAPD_ACL_ACCEPT_TIMEOUT;
sta = ap_get_sta(hapd, query->addr); sta = ap_get_sta(hapd, query->addr);
if (!sta || !sta->wpa_sm) { if (!sta || !sta->wpa_sm) {

View file

@ -206,11 +206,19 @@ u8 * hostapd_eid_eht_operation(struct hostapd_data *hapd, u8 *eid)
enum oper_chan_width chwidth; enum oper_chan_width chwidth;
size_t elen = 1 + 4; size_t elen = 1 + 4;
bool eht_oper_info_present; bool eht_oper_info_present;
u16 punct_bitmap = hostapd_get_punct_bitmap(hapd); u16 punct_bitmap = conf->punct_bitmap;
if (!hapd->iface->current_mode) if (!hapd->iface->current_mode)
return eid; return eid;
#ifdef CONFIG_TESTING_OPTIONS
if (!punct_bitmap && hapd->conf->eht_oper_puncturing_override) {
wpa_printf(MSG_DEBUG, "EHT: Puncturing mask override=0x%x",
hapd->conf->eht_oper_puncturing_override);
punct_bitmap = hapd->conf->eht_oper_puncturing_override;
}
#endif /* CONFIG_TESTING_OPTIONS */
if (is_6ghz_op_class(conf->op_class)) if (is_6ghz_op_class(conf->op_class))
chwidth = op_class_to_ch_width(conf->op_class); chwidth = op_class_to_ch_width(conf->op_class);
else else
@ -450,8 +458,6 @@ static u8 * hostapd_eid_eht_basic_ml_common(struct hostapd_data *hapd,
size_t len, slice_len; size_t len, slice_len;
u8 link_id; u8 link_id;
u8 common_info_len; u8 common_info_len;
u16 mld_cap;
u8 max_simul_links, active_links;
/* /*
* As the Multi-Link element can exceed the size of 255 bytes need to * As the Multi-Link element can exceed the size of 255 bytes need to
@ -489,7 +495,7 @@ static u8 * hostapd_eid_eht_basic_ml_common(struct hostapd_data *hapd,
wpabuf_put_u8(buf, common_info_len); wpabuf_put_u8(buf, common_info_len);
/* Own MLD MAC Address */ /* Own MLD MAC Address */
wpabuf_put_data(buf, hapd->mld->mld_addr, ETH_ALEN); wpabuf_put_data(buf, hapd->mld_addr, ETH_ALEN);
/* Own Link ID */ /* Own Link ID */
wpabuf_put_u8(buf, hapd->mld_link_id); wpabuf_put_u8(buf, hapd->mld_link_id);
@ -501,31 +507,14 @@ static u8 * hostapd_eid_eht_basic_ml_common(struct hostapd_data *hapd,
hapd->iface->mld_eml_capa); hapd->iface->mld_eml_capa);
wpabuf_put_le16(buf, hapd->iface->mld_eml_capa); wpabuf_put_le16(buf, hapd->iface->mld_eml_capa);
mld_cap = hapd->iface->mld_mld_capa;
max_simul_links = mld_cap & EHT_ML_MLD_CAPA_MAX_NUM_SIM_LINKS_MASK;
active_links = hapd->mld->num_links - 1;
if (active_links > max_simul_links) {
wpa_printf(MSG_ERROR,
"MLD: Error in max simultaneous links, advertised: 0x%x current: 0x%x",
max_simul_links, active_links);
active_links = max_simul_links;
}
mld_cap &= ~EHT_ML_MLD_CAPA_MAX_NUM_SIM_LINKS_MASK;
mld_cap |= active_links & EHT_ML_MLD_CAPA_MAX_NUM_SIM_LINKS_MASK;
/* TODO: Advertise T2LM based on driver support as well */
mld_cap &= ~EHT_ML_MLD_CAPA_TID_TO_LINK_MAP_NEG_SUPP_MSK;
wpa_printf(MSG_DEBUG, "MLD: MLD Capabilities and Operations=0x%x", wpa_printf(MSG_DEBUG, "MLD: MLD Capabilities and Operations=0x%x",
mld_cap); hapd->iface->mld_mld_capa);
wpabuf_put_le16(buf, mld_cap); wpabuf_put_le16(buf, hapd->iface->mld_mld_capa);
if (include_mld_id) { if (include_mld_id) {
wpa_printf(MSG_DEBUG, "MLD: AP MLD ID=0x%x", wpa_printf(MSG_DEBUG, "MLD: AP MLD ID=0x%x",
hostapd_get_mld_id(hapd)); hapd->conf->mld_id);
wpabuf_put_u8(buf, hostapd_get_mld_id(hapd)); wpabuf_put_u8(buf, hapd->conf->mld_id);
} }
if (!mld_info) if (!mld_info)
@ -589,8 +578,7 @@ static u8 * hostapd_eid_eht_basic_ml_common(struct hostapd_data *hapd,
wpabuf_put_le64(buf, 0); wpabuf_put_le64(buf, 0);
/* DTIM Info */ /* DTIM Info */
wpabuf_put_u8(buf, 0); /* DTIM Count */ wpabuf_put_le16(buf, link_bss->conf->dtim_period);
wpabuf_put_u8(buf, link_bss->conf->dtim_period);
/* BSS Parameters Change Count */ /* BSS Parameters Change Count */
wpabuf_put_u8(buf, hapd->eht_mld_bss_param_change); wpabuf_put_u8(buf, hapd->eht_mld_bss_param_change);
@ -824,7 +812,7 @@ struct wpabuf * hostapd_ml_auth_resp(struct hostapd_data *hapd)
wpabuf_put_u8(buf, WLAN_EID_EXT_MULTI_LINK); wpabuf_put_u8(buf, WLAN_EID_EXT_MULTI_LINK);
wpabuf_put_le16(buf, MULTI_LINK_CONTROL_TYPE_BASIC); wpabuf_put_le16(buf, MULTI_LINK_CONTROL_TYPE_BASIC);
wpabuf_put_u8(buf, ETH_ALEN + 1); wpabuf_put_u8(buf, ETH_ALEN + 1);
wpabuf_put_data(buf, hapd->mld->mld_addr, ETH_ALEN); wpabuf_put_data(buf, hapd->mld_addr, ETH_ALEN);
return buf; return buf;
} }
@ -871,8 +859,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 +870,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 +893,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 +917,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;
@ -1058,7 +1018,7 @@ const u8 * hostapd_process_ml_auth(struct hostapd_data *hapd,
static int hostapd_mld_validate_assoc_info(struct hostapd_data *hapd, static int hostapd_mld_validate_assoc_info(struct hostapd_data *hapd,
struct sta_info *sta) struct sta_info *sta)
{ {
u8 link_id; u8 i, link_id;
struct mld_info *info = &sta->mld_info; struct mld_info *info = &sta->mld_info;
if (!ap_sta_is_mld(hapd, sta)) { if (!ap_sta_is_mld(hapd, sta)) {
@ -1078,17 +1038,31 @@ static int hostapd_mld_validate_assoc_info(struct hostapd_data *hapd,
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 hostapd_data *other_hapd; struct hostapd_data *other_hapd;
if (!info->links[link_id].valid || link_id == hapd->mld_link_id) if (!info->links[link_id].valid)
continue; continue;
other_hapd = hostapd_mld_get_link_bss(hapd, link_id); for (i = 0; i < hapd->iface->interfaces->count; i++) {
if (!other_hapd) { other_hapd = hapd->iface->interfaces->iface[i]->bss[0];
if (hapd == other_hapd)
continue;
if (other_hapd->conf->mld_ap &&
other_hapd->conf->mld_id == hapd->conf->mld_id &&
link_id == other_hapd->mld_link_id)
break;
}
if (i == hapd->iface->interfaces->count &&
link_id != hapd->mld_link_id) {
wpa_printf(MSG_DEBUG, "MLD: Invalid link ID=%u", wpa_printf(MSG_DEBUG, "MLD: Invalid link ID=%u",
link_id); link_id);
return -1; return -1;
} }
os_memcpy(info->links[link_id].local_addr, other_hapd->own_addr, if (i < hapd->iface->interfaces->count)
os_memcpy(info->links[link_id].local_addr,
other_hapd->own_addr,
ETH_ALEN); ETH_ALEN);
} }

View file

@ -12,7 +12,6 @@
#include "utils/common.h" #include "utils/common.h"
#include "common/ieee802_11_defs.h" #include "common/ieee802_11_defs.h"
#include "common/ieee802_11_common.h" #include "common/ieee802_11_common.h"
#include "common/hw_features_common.h"
#include "hostapd.h" #include "hostapd.h"
#include "ap_config.h" #include "ap_config.h"
#include "beacon.h" #include "beacon.h"
@ -225,11 +224,10 @@ u8 * hostapd_eid_he_operation(struct hostapd_data *hapd, u8 *eid)
u8 seg0 = hapd->iconf->he_oper_centr_freq_seg0_idx; u8 seg0 = hapd->iconf->he_oper_centr_freq_seg0_idx;
u8 seg1 = hostapd_get_oper_centr_freq_seg1_idx(hapd->iconf); u8 seg1 = hostapd_get_oper_centr_freq_seg1_idx(hapd->iconf);
u8 control; u8 control;
#ifdef CONFIG_IEEE80211BE
u16 punct_bitmap = hostapd_get_punct_bitmap(hapd);
if (punct_bitmap) { #ifdef CONFIG_IEEE80211BE
punct_update_legacy_bw(punct_bitmap, if (hapd->iconf->punct_bitmap) {
punct_update_legacy_bw(hapd->iconf->punct_bitmap,
hapd->iconf->channel, hapd->iconf->channel,
&oper_chwidth, &seg0, &seg1); &oper_chwidth, &seg0, &seg1);
} }

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

@ -121,7 +121,7 @@ void ieee802_11_send_sa_query_req(struct hostapd_data *hapd,
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
if (ap_sta_is_mld(hapd, sta)) if (ap_sta_is_mld(hapd, sta))
own_addr = hapd->mld->mld_addr; own_addr = hapd->mld_addr;
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
@ -219,7 +219,7 @@ static void ieee802_11_send_sa_query_resp(struct hostapd_data *hapd,
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
if (ap_sta_is_mld(hapd, sta)) if (ap_sta_is_mld(hapd, sta))
own_addr = hapd->mld->mld_addr; own_addr = hapd->mld_addr;
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
resp->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, resp->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
@ -441,8 +441,6 @@ static void hostapd_ext_capab_byte(struct hostapd_data *hapd, u8 *pos, int idx,
if (hostapd_get_he_twt_responder(hapd, IEEE80211_MODE_AP)) if (hostapd_get_he_twt_responder(hapd, IEEE80211_MODE_AP))
*pos |= 0x40; /* Bit 78 - TWT responder */ *pos |= 0x40; /* Bit 78 - TWT responder */
#endif /* CONFIG_IEEE80211AX */ #endif /* CONFIG_IEEE80211AX */
if (hostapd_get_ht_vht_twt_responder(hapd))
*pos |= 0x40; /* Bit 78 - TWT responder */
break; break;
case 10: /* Bits 80-87 */ case 10: /* Bits 80-87 */
#ifdef CONFIG_SAE #ifdef CONFIG_SAE
@ -737,14 +735,12 @@ int hostapd_update_time_adv(struct hostapd_data *hapd)
} }
u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid, u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid)
u16 value)
{ {
u8 *pos = eid; u8 *pos = eid;
#ifdef CONFIG_WNM_AP #ifdef CONFIG_WNM_AP
if (hapd->conf->ap_max_inactivity > 0 && if (hapd->conf->ap_max_inactivity > 0) {
hapd->conf->bss_max_idle) {
unsigned int val; unsigned int val;
*pos++ = WLAN_EID_BSS_MAX_IDLE_PERIOD; *pos++ = WLAN_EID_BSS_MAX_IDLE_PERIOD;
*pos++ = 3; *pos++ = 3;
@ -757,13 +753,9 @@ u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid,
val = 1; val = 1;
if (val > 65535) if (val > 65535)
val = 65535; val = 65535;
if (value)
val = value;
WPA_PUT_LE16(pos, val); WPA_PUT_LE16(pos, val);
pos += 2; pos += 2;
/* Set the Protected Keep-Alive Required bit based on *pos++ = 0x00; /* TODO: Protected Keep-Alive Required */
* configuration */
*pos++ = hapd->conf->bss_max_idle == 2 ? BIT(0) : 0x00;
} }
#endif /* CONFIG_WNM_AP */ #endif /* CONFIG_WNM_AP */
@ -1097,7 +1089,7 @@ u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len)
{ {
u8 *pos = eid; u8 *pos = eid;
bool sae_pk = false; bool sae_pk = false;
u32 capab = 0, tmp; u16 capab = 0;
size_t flen; size_t flen;
if (!(hapd->conf->wpa & WPA_PROTO_RSN)) if (!(hapd->conf->wpa & WPA_PROTO_RSN))
@ -1126,28 +1118,18 @@ u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len)
capab |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT); capab |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT);
if (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_PROT_RANGE_NEG_AP) if (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_PROT_RANGE_NEG_AP)
capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR); capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR);
if (hapd->conf->ssid_protection)
capab |= BIT(WLAN_RSNX_CAPAB_SSID_PROTECTION);
if (!capab) flen = (capab & 0xff00) ? 2 : 1;
return eid; /* no supported extended RSN capabilities */ if (len < 2 + flen || !capab)
tmp = capab;
flen = 0;
while (tmp) {
flen++;
tmp >>= 8;
}
if (len < 2 + flen)
return eid; /* no supported extended RSN capabilities */ return eid; /* no supported extended RSN capabilities */
capab |= flen - 1; /* bit 0-3 = Field length (n - 1) */ capab |= flen - 1; /* bit 0-3 = Field length (n - 1) */
*pos++ = WLAN_EID_RSNX; *pos++ = WLAN_EID_RSNX;
*pos++ = flen; *pos++ = flen;
while (capab) { *pos++ = capab & 0x00ff;
*pos++ = capab & 0xff;
capab >>= 8; capab >>= 8;
} if (capab)
*pos++ = capab;
return pos; return pos;
} }
@ -1156,11 +1138,13 @@ u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len)
u16 check_ext_capab(struct hostapd_data *hapd, struct sta_info *sta, u16 check_ext_capab(struct hostapd_data *hapd, struct sta_info *sta,
const u8 *ext_capab_ie, size_t ext_capab_ie_len) const u8 *ext_capab_ie, size_t ext_capab_ie_len)
{ {
#ifdef CONFIG_INTERWORKING
/* check for QoS Map support */ /* check for QoS Map support */
if (ext_capab_ie_len >= 5) { if (ext_capab_ie_len >= 5) {
if (ext_capab_ie[4] & 0x01) if (ext_capab_ie[4] & 0x01)
sta->qos_map_enabled = 1; sta->qos_map_enabled = 1;
} }
#endif /* CONFIG_INTERWORKING */
if (ext_capab_ie_len > 0) { if (ext_capab_ie_len > 0) {
sta->ecsa_supported = !!(ext_capab_ie[0] & BIT(2)); sta->ecsa_supported = !!(ext_capab_ie[0] & BIT(2));
@ -1216,13 +1200,3 @@ struct sta_info * hostapd_ml_get_assoc_sta(struct hostapd_data *hapd,
return sta; return sta;
} }
bool hostapd_get_ht_vht_twt_responder(struct hostapd_data *hapd)
{
return hapd->iconf->ht_vht_twt_responder &&
((hapd->iconf->ieee80211n && !hapd->conf->disable_11n) ||
(hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac)) &&
(hapd->iface->drv_flags2 &
WPA_DRIVER_FLAGS2_HT_VHT_TWT_RESPONDER);
}

View file

@ -12,7 +12,6 @@
#include "utils/common.h" #include "utils/common.h"
#include "common/ieee802_11_defs.h" #include "common/ieee802_11_defs.h"
#include "common/hw_features_common.h"
#include "hostapd.h" #include "hostapd.h"
#include "ap_config.h" #include "ap_config.h"
#include "sta_info.h" #include "sta_info.h"
@ -80,9 +79,6 @@ u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid)
hostapd_get_oper_chwidth(hapd->iconf); hostapd_get_oper_chwidth(hapd->iconf);
u8 seg0 = hapd->iconf->vht_oper_centr_freq_seg0_idx; u8 seg0 = hapd->iconf->vht_oper_centr_freq_seg0_idx;
u8 seg1 = hapd->iconf->vht_oper_centr_freq_seg1_idx; u8 seg1 = hapd->iconf->vht_oper_centr_freq_seg1_idx;
#ifdef CONFIG_IEEE80211BE
u16 punct_bitmap = hostapd_get_punct_bitmap(hapd);
#endif /* CONFIG_IEEE80211BE */
if (is_6ghz_op_class(hapd->iconf->op_class)) if (is_6ghz_op_class(hapd->iconf->op_class))
return eid; return eid;
@ -94,8 +90,8 @@ u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid)
os_memset(oper, 0, sizeof(*oper)); os_memset(oper, 0, sizeof(*oper));
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
if (punct_bitmap) { if (hapd->iconf->punct_bitmap) {
punct_update_legacy_bw(punct_bitmap, punct_update_legacy_bw(hapd->iconf->punct_bitmap,
hapd->iconf->channel, hapd->iconf->channel,
&oper_chwidth, &seg0, &seg1); &oper_chwidth, &seg0, &seg1);
} }

View file

@ -172,7 +172,8 @@ static void ieee802_1x_ml_set_sta_authorized(struct hostapd_data *hapd,
struct hostapd_data *tmp_hapd = struct hostapd_data *tmp_hapd =
hapd->iface->interfaces->iface[i]->bss[0]; hapd->iface->interfaces->iface[i]->bss[0];
if (!hostapd_is_ml_partner(hapd, tmp_hapd)) if (!tmp_hapd->conf->mld_ap ||
hapd->conf->mld_id != tmp_hapd->conf->mld_id)
continue; continue;
for (tmp_sta = tmp_hapd->sta_list; tmp_sta; for (tmp_sta = tmp_hapd->sta_list; tmp_sta;
@ -767,9 +768,6 @@ void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd,
goto fail; goto fail;
} }
if (!radius_msg_add_msg_auth(msg))
goto fail;
if (sm->identity && if (sm->identity &&
!radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME, !radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME,
sm->identity, sm->identity_len)) { sm->identity, sm->identity_len)) {
@ -2042,7 +2040,16 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
} }
sta = sm->sta; sta = sm->sta;
if (radius_msg_verify(msg, shared_secret, shared_secret_len, req, 1)) { /* RFC 2869, Ch. 5.13: valid Message-Authenticator attribute MUST be
* present when packet contains an EAP-Message attribute */
if (hdr->code == RADIUS_CODE_ACCESS_REJECT &&
radius_msg_get_attr(msg, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, NULL,
0) < 0 &&
radius_msg_get_attr(msg, RADIUS_ATTR_EAP_MESSAGE, NULL, 0) < 0) {
wpa_printf(MSG_DEBUG,
"Allowing RADIUS Access-Reject without Message-Authenticator since it does not include EAP-Message");
} else if (radius_msg_verify(msg, shared_secret, shared_secret_len,
req, 1)) {
wpa_printf(MSG_INFO, wpa_printf(MSG_INFO,
"Incoming RADIUS packet did not have correct Message-Authenticator - dropped"); "Incoming RADIUS packet did not have correct Message-Authenticator - dropped");
return RADIUS_RX_INVALID_AUTHENTICATOR; return RADIUS_RX_INVALID_AUTHENTICATOR;
@ -2533,29 +2540,13 @@ int ieee802_1x_init(struct hostapd_data *hapd)
struct eapol_auth_config conf; struct eapol_auth_config conf;
struct eapol_auth_cb cb; struct eapol_auth_cb cb;
#ifdef CONFIG_IEEE80211BE if (hapd->mld_first_bss) {
if (!hostapd_mld_is_first_bss(hapd)) {
struct hostapd_data *first;
first = hostapd_mld_get_first_bss(hapd);
if (!first)
return -1;
if (!first->eapol_auth) {
wpa_printf(MSG_DEBUG,
"MLD: First BSS IEEE 802.1X state machine does not exist. Init on its behalf");
if (ieee802_1x_init(first))
return -1;
}
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"MLD: Using IEEE 802.1X state machine of the first BSS"); "MLD: Using IEEE 802.1X state machine of the first BSS");
hapd->eapol_auth = first->eapol_auth; hapd->eapol_auth = hapd->mld_first_bss->eapol_auth;
return 0; return 0;
} }
#endif /* CONFIG_IEEE80211BE */
dl_list_init(&hapd->erp_keys); dl_list_init(&hapd->erp_keys);
@ -2641,15 +2632,13 @@ void ieee802_1x_erp_flush(struct hostapd_data *hapd)
void ieee802_1x_deinit(struct hostapd_data *hapd) void ieee802_1x_deinit(struct hostapd_data *hapd)
{ {
#ifdef CONFIG_IEEE80211BE if (hapd->mld_first_bss) {
if (!hostapd_mld_is_first_bss(hapd)) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"MLD: Deinit IEEE 802.1X state machine of a non-first BSS"); "MLD: Deinit IEEE 802.1X state machine of a non-first BSS");
hapd->eapol_auth = NULL; hapd->eapol_auth = NULL;
return; return;
} }
#endif /* CONFIG_IEEE80211BE */
#ifdef CONFIG_WEP #ifdef CONFIG_WEP
eloop_cancel_timeout(ieee802_1x_rekey, hapd, NULL); eloop_cancel_timeout(ieee802_1x_rekey, hapd, NULL);

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

@ -61,7 +61,6 @@ void sta_ip6addr_del(struct hostapd_data *hapd, struct sta_info *sta)
dl_list_for_each_safe(ip6addr, prev, &sta->ip6addr, struct ip6addr, dl_list_for_each_safe(ip6addr, prev, &sta->ip6addr, struct ip6addr,
list) { list) {
hostapd_drv_br_delete_ip_neigh(hapd, 6, (u8 *) &ip6addr->addr); hostapd_drv_br_delete_ip_neigh(hapd, 6, (u8 *) &ip6addr->addr);
dl_list_del(&ip6addr->list);
os_free(ip6addr); os_free(ip6addr);
} }
} }

View file

@ -99,10 +99,7 @@ static void hostapd_neighbor_clear_entry(struct hostapd_neighbor_entry *nr)
nr->civic = NULL; nr->civic = NULL;
os_memset(nr->bssid, 0, sizeof(nr->bssid)); os_memset(nr->bssid, 0, sizeof(nr->bssid));
os_memset(&nr->ssid, 0, sizeof(nr->ssid)); os_memset(&nr->ssid, 0, sizeof(nr->ssid));
os_memset(&nr->lci_date, 0, sizeof(nr->lci_date));
nr->stationary = 0; nr->stationary = 0;
nr->short_ssid = 0;
nr->bss_parameters = 0;
} }
@ -168,14 +165,6 @@ fail:
} }
static void hostapd_neighbor_free(struct hostapd_neighbor_entry *nr)
{
hostapd_neighbor_clear_entry(nr);
dl_list_del(&nr->list);
os_free(nr);
}
int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid, int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid,
const struct wpa_ssid_value *ssid) const struct wpa_ssid_value *ssid)
{ {
@ -185,7 +174,9 @@ int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid,
if (!nr) if (!nr)
return -1; return -1;
hostapd_neighbor_free(nr); hostapd_neighbor_clear_entry(nr);
dl_list_del(&nr->list);
os_free(nr);
return 0; return 0;
} }
@ -197,7 +188,9 @@ void hostapd_free_neighbor_db(struct hostapd_data *hapd)
dl_list_for_each_safe(nr, prev, &hapd->nr_db, dl_list_for_each_safe(nr, prev, &hapd->nr_db,
struct hostapd_neighbor_entry, list) { struct hostapd_neighbor_entry, list) {
hostapd_neighbor_free(nr); hostapd_neighbor_clear_entry(nr);
dl_list_del(&nr->list);
os_free(nr);
} }
} }
@ -332,35 +325,3 @@ void hostapd_neighbor_set_own_report(struct hostapd_data *hapd)
wpabuf_free(nr); wpabuf_free(nr);
#endif /* NEED_AP_MLME */ #endif /* NEED_AP_MLME */
} }
static struct hostapd_neighbor_entry *
hostapd_neighbor_get_diff_short_ssid(struct hostapd_data *hapd, const u8 *bssid)
{
struct hostapd_neighbor_entry *nr;
dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
list) {
if (ether_addr_equal(bssid, nr->bssid) &&
nr->short_ssid != hapd->conf->ssid.short_ssid)
return nr;
}
return NULL;
}
int hostapd_neighbor_sync_own_report(struct hostapd_data *hapd)
{
struct hostapd_neighbor_entry *nr;
nr = hostapd_neighbor_get_diff_short_ssid(hapd, hapd->own_addr);
if (!nr)
return -1;
/* Clear old entry due to SSID change */
hostapd_neighbor_free(nr);
hostapd_neighbor_set_own_report(hapd);
return 0;
}

View file

@ -20,7 +20,6 @@ int hostapd_neighbor_set(struct hostapd_data *hapd, const u8 *bssid,
const struct wpabuf *civic, int stationary, const struct wpabuf *civic, int stationary,
u8 bss_parameters); u8 bss_parameters);
void hostapd_neighbor_set_own_report(struct hostapd_data *hapd); void hostapd_neighbor_set_own_report(struct hostapd_data *hapd);
int hostapd_neighbor_sync_own_report(struct hostapd_data *hapd);
int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid, int hostapd_neighbor_remove(struct hostapd_data *hapd, const u8 *bssid,
const struct wpa_ssid_value *ssid); const struct wpa_ssid_value *ssid);
void hostapd_free_neighbor_db(struct hostapd_data *hapd); void hostapd_free_neighbor_db(struct hostapd_data *hapd);

View file

@ -334,53 +334,6 @@ static void hostapd_handle_nei_report_req(struct hostapd_data *hapd,
} }
static void hostapd_link_mesr_rep_timeout_handler(void *eloop_data,
void *user_ctx)
{
struct hostapd_data *hapd = eloop_data;
wpa_printf(MSG_DEBUG,
"RRM: Link measurement request (token %u) timed out",
hapd->link_measurement_req_token);
hapd->link_mesr_req_active = 0;
}
static void hostapd_handle_link_mesr_report(struct hostapd_data *hapd,
const u8 *buf, size_t len)
{
const struct ieee80211_mgmt *mgmt = (const struct ieee80211_mgmt *) buf;
const struct rrm_link_measurement_report *report;
const u8 *pos, *end;
char report_msg[2 * 8 + 1];
end = buf + len;
pos = mgmt->u.action.u.rrm.variable;
report = (const struct rrm_link_measurement_report *) (pos - 1);
if (end - (const u8 *) report < (int) sizeof(*report))
return;
if (!hapd->link_mesr_req_active ||
(hapd->link_measurement_req_token != report->dialog_token)) {
wpa_printf(MSG_INFO,
"Unexpected Link measurement report, token %u",
report->dialog_token);
return;
}
hapd->link_mesr_req_active = 0;
eloop_cancel_timeout(hostapd_link_mesr_rep_timeout_handler, hapd, NULL);
report_msg[0] = '\0';
if (wpa_snprintf_hex(report_msg, sizeof(report_msg),
pos, end - pos) < 0)
return;
wpa_msg(hapd->msg_ctx, MSG_INFO, LINK_MSR_RESP_RX MACSTR " %u %s",
MAC2STR(mgmt->sa), report->dialog_token, report_msg);
}
void hostapd_handle_radio_measurement(struct hostapd_data *hapd, void hostapd_handle_radio_measurement(struct hostapd_data *hapd,
const u8 *buf, size_t len) const u8 *buf, size_t len)
{ {
@ -403,9 +356,6 @@ void hostapd_handle_radio_measurement(struct hostapd_data *hapd,
case WLAN_RRM_NEIGHBOR_REPORT_REQUEST: case WLAN_RRM_NEIGHBOR_REPORT_REQUEST:
hostapd_handle_nei_report_req(hapd, buf, len); hostapd_handle_nei_report_req(hapd, buf, len);
break; break;
case WLAN_RRM_LINK_MEASUREMENT_REPORT:
hostapd_handle_link_mesr_report(hapd, buf, len);
break;
default: default:
wpa_printf(MSG_DEBUG, "RRM action %u is not supported", wpa_printf(MSG_DEBUG, "RRM action %u is not supported",
mgmt->u.action.u.rrm.action); mgmt->u.action.u.rrm.action);
@ -613,7 +563,6 @@ void hostapd_clean_rrm(struct hostapd_data *hapd)
hapd->lci_req_active = 0; hapd->lci_req_active = 0;
eloop_cancel_timeout(hostapd_range_rep_timeout_handler, hapd, NULL); eloop_cancel_timeout(hostapd_range_rep_timeout_handler, hapd, NULL);
hapd->range_req_active = 0; hapd->range_req_active = 0;
eloop_cancel_timeout(hostapd_link_mesr_rep_timeout_handler, hapd, NULL);
} }
@ -723,73 +672,3 @@ void hostapd_rrm_beacon_req_tx_status(struct hostapd_data *hapd,
" %u ack=%d", MAC2STR(mgmt->da), " %u ack=%d", MAC2STR(mgmt->da),
mgmt->u.action.u.rrm.dialog_token, ok); mgmt->u.action.u.rrm.dialog_token, ok);
} }
int hostapd_send_link_measurement_req(struct hostapd_data *hapd, const u8 *addr)
{
struct wpabuf *buf;
struct sta_info *sta;
int ret;
wpa_printf(MSG_DEBUG, "Request Link Measurement: dest addr " MACSTR,
MAC2STR(addr));
if (!(hapd->iface->drv_rrm_flags &
WPA_DRIVER_FLAGS_TX_POWER_INSERTION)) {
wpa_printf(MSG_INFO,
"Request Link Measurement: the driver does not support TX power insertion");
return -1;
}
sta = ap_get_sta(hapd, addr);
if (!sta || !(sta->flags & WLAN_STA_AUTHORIZED)) {
wpa_printf(MSG_INFO,
"Request Link Measurement: specied STA is not connected");
return -1;
}
if (!(sta->rrm_enabled_capa[0] & WLAN_RRM_CAPS_LINK_MEASUREMENT)) {
wpa_printf(MSG_INFO,
"Request Link Measurement: destination STA does not support link measurement");
return -1;
}
if (hapd->link_mesr_req_active) {
wpa_printf(MSG_DEBUG,
"Request Link Measurement: request already in process - overriding");
hapd->link_mesr_req_active = 0;
eloop_cancel_timeout(hostapd_link_mesr_rep_timeout_handler,
hapd, NULL);
}
/* Action + Action type + token + Tx Power used + Max Tx Power = 5 */
buf = wpabuf_alloc(5);
if (!buf)
return -1;
hapd->link_measurement_req_token++;
if (!hapd->link_measurement_req_token)
hapd->link_measurement_req_token++;
wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT);
wpabuf_put_u8(buf, WLAN_RRM_LINK_MEASUREMENT_REQUEST);
wpabuf_put_u8(buf, hapd->link_measurement_req_token);
/* NOTE: The driver is expected to fill the Tx Power Used and Max Tx
* Power */
wpabuf_put_u8(buf, 0);
wpabuf_put_u8(buf, 0);
ret = hostapd_drv_send_action(hapd, hapd->iface->freq, 0, addr,
wpabuf_head(buf), wpabuf_len(buf));
wpabuf_free(buf);
if (ret < 0)
return ret;
hapd->link_mesr_req_active = 1;
eloop_register_timeout(HOSTAPD_RRM_REQUEST_TIMEOUT, 0,
hostapd_link_mesr_rep_timeout_handler, hapd,
NULL);
return hapd->link_measurement_req_token;
}

View file

@ -29,7 +29,5 @@ int hostapd_send_beacon_req(struct hostapd_data *hapd, const u8 *addr,
void hostapd_rrm_beacon_req_tx_status(struct hostapd_data *hapd, void hostapd_rrm_beacon_req_tx_status(struct hostapd_data *hapd,
const struct ieee80211_mgmt *mgmt, const struct ieee80211_mgmt *mgmt,
size_t len, int ok); size_t len, int ok);
int hostapd_send_link_measurement_req(struct hostapd_data *hapd,
const u8 *addr);
#endif /* RRM_H */ #endif /* RRM_H */

View file

@ -180,48 +180,13 @@ void ap_free_sta_pasn(struct hostapd_data *hapd, struct sta_info *sta)
sta->pasn->fils.erp_resp = NULL; sta->pasn->fils.erp_resp = NULL;
#endif /* CONFIG_FILS */ #endif /* CONFIG_FILS */
pasn_data_deinit(sta->pasn); bin_clear_free(sta->pasn, sizeof(*sta->pasn));
sta->pasn = NULL; sta->pasn = NULL;
} }
} }
#endif /* CONFIG_PASN */ #endif /* CONFIG_PASN */
static void __ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
{
#ifdef CONFIG_IEEE80211BE
if (hostapd_sta_is_link_sta(hapd, sta) &&
!hostapd_drv_link_sta_remove(hapd, sta->addr))
return;
#endif /* CONFIG_IEEE80211BE */
hostapd_drv_sta_remove(hapd, sta->addr);
}
#ifdef CONFIG_IEEE80211BE
static void clear_wpa_sm_for_each_partner_link(struct hostapd_data *hapd,
struct sta_info *psta)
{
struct sta_info *lsta;
struct hostapd_data *lhapd;
if (!ap_sta_is_mld(hapd, psta))
return;
for_each_mld_link(lhapd, hapd) {
if (lhapd == hapd)
continue;
lsta = ap_get_sta(lhapd, psta->addr);
if (lsta)
lsta->wpa_sm = NULL;
}
}
#endif /* CONFIG_IEEE80211BE */
void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta) void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
{ {
int set_beacon = 0; int set_beacon = 0;
@ -235,7 +200,6 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
if ((sta->flags & WLAN_STA_WDS) || if ((sta->flags & WLAN_STA_WDS) ||
(sta->flags & WLAN_STA_MULTI_AP && (sta->flags & WLAN_STA_MULTI_AP &&
(hapd->conf->multi_ap & BACKHAUL_BSS) && (hapd->conf->multi_ap & BACKHAUL_BSS) &&
hapd->conf->wds_sta &&
!(sta->flags & WLAN_STA_WPS))) !(sta->flags & WLAN_STA_WPS)))
hostapd_set_wds_sta(hapd, NULL, sta->addr, sta->aid, 0); hostapd_set_wds_sta(hapd, NULL, sta->addr, sta->aid, 0);
@ -245,7 +209,7 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
if (!hapd->iface->driver_ap_teardown && if (!hapd->iface->driver_ap_teardown &&
!(sta->flags & WLAN_STA_PREAUTH)) { !(sta->flags & WLAN_STA_PREAUTH)) {
__ap_free_sta(hapd, sta); hostapd_drv_sta_remove(hapd, sta->addr);
sta->added_unassoc = 0; sta->added_unassoc = 0;
} }
@ -340,17 +304,9 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
if (!ap_sta_is_mld(hapd, sta) || if (!ap_sta_is_mld(hapd, sta) ||
hapd->mld_link_id == sta->mld_assoc_link_id) { hapd->mld_link_id == sta->mld_assoc_link_id)
wpa_auth_sta_deinit(sta->wpa_sm); wpa_auth_sta_deinit(sta->wpa_sm);
/* Remove references from partner links. */ #else
clear_wpa_sm_for_each_partner_link(hapd, sta);
}
/* Release group references in case non-association link STA is removed
* before association link STA */
if (hostapd_sta_is_link_sta(hapd, sta))
wpa_release_link_auth_ref(sta->wpa_sm, hapd->mld_link_id);
#else /* CONFIG_IEEE80211BE */
wpa_auth_sta_deinit(sta->wpa_sm); wpa_auth_sta_deinit(sta->wpa_sm);
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
@ -498,27 +454,6 @@ void hostapd_free_stas(struct hostapd_data *hapd)
} }
#ifdef CONFIG_IEEE80211BE
void hostapd_free_link_stas(struct hostapd_data *hapd)
{
struct sta_info *sta, *prev;
sta = hapd->sta_list;
while (sta) {
prev = sta;
sta = sta->next;
if (!hostapd_sta_is_link_sta(hapd, prev))
continue;
wpa_printf(MSG_DEBUG, "Removing link station from MLD " MACSTR,
MAC2STR(prev->addr));
ap_free_sta(hapd, prev);
}
}
#endif /* CONFIG_IEEE80211BE */
/** /**
* ap_handle_timer - Per STA timer handler * ap_handle_timer - Per STA timer handler
* @eloop_ctx: struct hostapd_data * * @eloop_ctx: struct hostapd_data *
@ -533,7 +468,6 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
struct sta_info *sta = timeout_ctx; struct sta_info *sta = timeout_ctx;
unsigned long next_time = 0; unsigned long next_time = 0;
int reason; int reason;
int max_inactivity = hapd->conf->ap_max_inactivity;
wpa_printf(MSG_DEBUG, "%s: %s: " MACSTR " flags=0x%x timeout_next=%d", wpa_printf(MSG_DEBUG, "%s: %s: " MACSTR " flags=0x%x timeout_next=%d",
hapd->conf->iface, __func__, MAC2STR(sta->addr), sta->flags, hapd->conf->iface, __func__, MAC2STR(sta->addr), sta->flags,
@ -546,9 +480,6 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
return; return;
} }
if (sta->max_idle_period)
max_inactivity = (sta->max_idle_period * 1024 + 999) / 1000;
if ((sta->flags & WLAN_STA_ASSOC) && if ((sta->flags & WLAN_STA_ASSOC) &&
(sta->timeout_next == STA_NULLFUNC || (sta->timeout_next == STA_NULLFUNC ||
sta->timeout_next == STA_DISASSOC)) { sta->timeout_next == STA_DISASSOC)) {
@ -570,7 +501,7 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
* Anyway, try again after the next inactivity timeout, * Anyway, try again after the next inactivity timeout,
* but do not disconnect the station now. * but do not disconnect the station now.
*/ */
next_time = max_inactivity + fuzz; next_time = hapd->conf->ap_max_inactivity + fuzz;
} else if (inactive_sec == -ENOENT) { } else if (inactive_sec == -ENOENT) {
wpa_msg(hapd->msg_ctx, MSG_DEBUG, wpa_msg(hapd->msg_ctx, MSG_DEBUG,
"Station " MACSTR " has lost its driver entry", "Station " MACSTR " has lost its driver entry",
@ -579,19 +510,20 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
/* Avoid sending client probe on removed client */ /* Avoid sending client probe on removed client */
sta->timeout_next = STA_DISASSOC; sta->timeout_next = STA_DISASSOC;
goto skip_poll; goto skip_poll;
} else if (inactive_sec < max_inactivity) { } else if (inactive_sec < hapd->conf->ap_max_inactivity) {
/* station activity detected; reset timeout state */ /* station activity detected; reset timeout state */
wpa_msg(hapd->msg_ctx, MSG_DEBUG, wpa_msg(hapd->msg_ctx, MSG_DEBUG,
"Station " MACSTR " has been active %is ago", "Station " MACSTR " has been active %is ago",
MAC2STR(sta->addr), inactive_sec); MAC2STR(sta->addr), inactive_sec);
sta->timeout_next = STA_NULLFUNC; sta->timeout_next = STA_NULLFUNC;
next_time = max_inactivity + fuzz - inactive_sec; next_time = hapd->conf->ap_max_inactivity + fuzz -
inactive_sec;
} else { } else {
wpa_msg(hapd->msg_ctx, MSG_DEBUG, wpa_msg(hapd->msg_ctx, MSG_DEBUG,
"Station " MACSTR " has been " "Station " MACSTR " has been "
"inactive too long: %d sec, max allowed: %d", "inactive too long: %d sec, max allowed: %d",
MAC2STR(sta->addr), inactive_sec, MAC2STR(sta->addr), inactive_sec,
max_inactivity); hapd->conf->ap_max_inactivity);
if (hapd->conf->skip_inactivity_poll) if (hapd->conf->skip_inactivity_poll)
sta->timeout_next = STA_DISASSOC; sta->timeout_next = STA_DISASSOC;
@ -607,7 +539,7 @@ void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
/* data nullfunc frame poll did not produce TX errors; assume /* data nullfunc frame poll did not produce TX errors; assume
* station ACKed it */ * station ACKed it */
sta->timeout_next = STA_NULLFUNC; sta->timeout_next = STA_NULLFUNC;
next_time = max_inactivity; next_time = hapd->conf->ap_max_inactivity;
} }
skip_poll: skip_poll:
@ -795,7 +727,6 @@ struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr)
{ {
struct sta_info *sta; struct sta_info *sta;
int i; int i;
int max_inactivity = hapd->conf->ap_max_inactivity;
sta = ap_get_sta(hapd, addr); sta = ap_get_sta(hapd, addr);
if (sta) if (sta)
@ -829,15 +760,12 @@ struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr)
} }
sta->supported_rates_len = i; sta->supported_rates_len = i;
if (sta->max_idle_period)
max_inactivity = (sta->max_idle_period * 1024 + 999) / 1000;
if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_INACTIVITY_TIMER)) { if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_INACTIVITY_TIMER)) {
wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout " wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout "
"for " MACSTR " (%d seconds - ap_max_inactivity)", "for " MACSTR " (%d seconds - ap_max_inactivity)",
__func__, MAC2STR(addr), __func__, MAC2STR(addr),
max_inactivity); hapd->conf->ap_max_inactivity);
eloop_register_timeout(max_inactivity, 0, eloop_register_timeout(hapd->conf->ap_max_inactivity, 0,
ap_handle_timer, hapd, sta); ap_handle_timer, hapd, sta);
} }
@ -941,11 +869,9 @@ static void ap_sta_disconnect_common(struct hostapd_data *hapd,
ieee802_1x_free_station(hapd, sta); ieee802_1x_free_station(hapd, sta);
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
if (!hapd->conf->mld_ap || if (!hapd->conf->mld_ap ||
hapd->mld_link_id == sta->mld_assoc_link_id) { hapd->mld_link_id == sta->mld_assoc_link_id)
wpa_auth_sta_deinit(sta->wpa_sm); wpa_auth_sta_deinit(sta->wpa_sm);
clear_wpa_sm_for_each_partner_link(hapd, sta); #else
}
#else /* CONFIG_IEEE80211BE */
wpa_auth_sta_deinit(sta->wpa_sm); wpa_auth_sta_deinit(sta->wpa_sm);
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
@ -1044,15 +970,16 @@ static bool ap_sta_ml_disconnect(struct hostapd_data *hapd,
interfaces = assoc_hapd->iface->interfaces; interfaces = assoc_hapd->iface->interfaces;
for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) { for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
if (!assoc_sta->mld_info.links[link_id].valid)
continue;
for (i = 0; i < interfaces->count; i++) { for (i = 0; i < interfaces->count; i++) {
struct sta_info *tmp_sta; struct sta_info *tmp_sta;
if (!assoc_sta->mld_info.links[link_id].valid)
continue;
tmp_hapd = interfaces->iface[i]->bss[0]; tmp_hapd = interfaces->iface[i]->bss[0];
if (!hostapd_is_ml_partner(tmp_hapd, assoc_hapd)) if (!tmp_hapd->conf->mld_ap ||
assoc_hapd->conf->mld_id != tmp_hapd->conf->mld_id)
continue; continue;
for (tmp_sta = tmp_hapd->sta_list; tmp_sta; for (tmp_sta = tmp_hapd->sta_list; tmp_sta;
@ -1506,7 +1433,6 @@ void ap_sta_set_authorized_event(struct hostapd_data *hapd,
u8 addr[ETH_ALEN]; u8 addr[ETH_ALEN];
u8 ip_addr_buf[4]; u8 ip_addr_buf[4];
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */
const u8 *ip_ptr = NULL;
#ifdef CONFIG_P2P #ifdef CONFIG_P2P
if (hapd->p2p_group == NULL) { if (hapd->p2p_group == NULL) {
@ -1523,6 +1449,10 @@ void ap_sta_set_authorized_event(struct hostapd_data *hapd,
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */
os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(sta->addr)); os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(sta->addr));
if (hapd->sta_authorized_cb)
hapd->sta_authorized_cb(hapd->sta_authorized_cb_ctx,
sta->addr, authorized, dev_addr);
if (authorized) { if (authorized) {
const u8 *dpp_pkhash; const u8 *dpp_pkhash;
const char *keyid; const char *keyid;
@ -1539,7 +1469,6 @@ void ap_sta_set_authorized_event(struct hostapd_data *hapd,
" ip_addr=%u.%u.%u.%u", " ip_addr=%u.%u.%u.%u",
ip_addr_buf[0], ip_addr_buf[1], ip_addr_buf[0], ip_addr_buf[1],
ip_addr_buf[2], ip_addr_buf[3]); ip_addr_buf[2], ip_addr_buf[3]);
ip_ptr = ip_addr_buf;
} }
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */
@ -1579,11 +1508,6 @@ void ap_sta_set_authorized_event(struct hostapd_data *hapd,
AP_STA_DISCONNECTED "%s", buf); AP_STA_DISCONNECTED "%s", buf);
} }
if (hapd->sta_authorized_cb)
hapd->sta_authorized_cb(hapd->sta_authorized_cb_ctx,
sta->addr, authorized, dev_addr,
ip_ptr);
#ifdef CONFIG_FST #ifdef CONFIG_FST
if (hapd->iface->fst) { if (hapd->iface->fst) {
if (authorized) if (authorized)
@ -1801,8 +1725,10 @@ static void ap_sta_remove_link_sta(struct hostapd_data *hapd,
struct sta_info *sta) struct sta_info *sta)
{ {
struct hostapd_data *tmp_hapd; struct hostapd_data *tmp_hapd;
unsigned int i, j;
for_each_mld_link(tmp_hapd, hapd) { for_each_mld_link(tmp_hapd, i, j, hapd->iface->interfaces,
hapd->conf->mld_id) {
struct sta_info *tmp_sta; struct sta_info *tmp_sta;
if (hapd == tmp_hapd) if (hapd == tmp_hapd)

View file

@ -81,7 +81,22 @@ 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;
const u8 *rsne, *rsnxe;
} links[MAX_NUM_MLD_LINKS];
}; };
struct sta_info { struct sta_info {
@ -319,9 +334,6 @@ struct sta_info {
struct mld_info mld_info; struct mld_info mld_info;
u8 mld_assoc_link_id; u8 mld_assoc_link_id;
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
u16 max_idle_period; /* if nonzero, the granted BSS max idle period in
* units of 1000 TUs */
}; };
@ -428,6 +440,4 @@ static inline void ap_sta_set_mld(struct sta_info *sta, bool mld)
void ap_sta_free_sta_profile(struct mld_info *info); void ap_sta_free_sta_profile(struct mld_info *info);
void hostapd_free_link_stas(struct hostapd_data *hapd);
#endif /* STA_INFO_H */ #endif /* STA_INFO_H */

View file

@ -51,7 +51,7 @@ static const u8 * wnm_ap_get_own_addr(struct hostapd_data *hapd,
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
if (hapd->conf->mld_ap && (!sta || ap_sta_is_mld(hapd, sta))) if (hapd->conf->mld_ap && (!sta || ap_sta_is_mld(hapd, sta)))
own_addr = hapd->mld->mld_addr; own_addr = hapd->mld_addr;
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
return own_addr; return own_addr;

File diff suppressed because it is too large Load diff

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,17 +192,15 @@ 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;
#ifdef CONFIG_OCV #ifdef CONFIG_OCV
int ocv; /* Operating Channel Validation */ int ocv; /* Operating Channel Validation */
#endif /* CONFIG_OCV */ #endif /* CONFIG_OCV */
#ifdef CONFIG_IEEE80211R_AP
u8 ssid[SSID_MAX_LEN]; u8 ssid[SSID_MAX_LEN];
size_t ssid_len; size_t ssid_len;
#ifdef CONFIG_IEEE80211R_AP
u8 mobility_domain[MOBILITY_DOMAIN_ID_LEN]; u8 mobility_domain[MOBILITY_DOMAIN_ID_LEN];
u8 r0_key_holder[FT_R0KH_ID_MAX_LEN]; u8 r0_key_holder[FT_R0KH_ID_MAX_LEN];
size_t r0_key_holder_len; size_t r0_key_holder_len;
@ -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;
@ -303,22 +281,10 @@ struct wpa_auth_config {
bool radius_psk; bool radius_psk;
bool no_disconnect_on_group_keyerror;
/* Pointer to Multi-BSSID transmitted BSS authenticator instance. /* Pointer to Multi-BSSID transmitted BSS authenticator instance.
* Set only in nontransmitted BSSs, i.e., is NULL for transmitted BSS * Set only in nontransmitted BSSs, i.e., is NULL for transmitted BSS
* and in BSSs that are not part of a Multi-BSSID set. */ * and in BSSs that are not part of a Multi-BSSID set. */
struct wpa_authenticator *tx_bss_auth; struct wpa_authenticator *tx_bss_auth;
#ifdef CONFIG_IEEE80211BE
const u8 *mld_addr;
int link_id;
struct wpa_authenticator *first_link_auth;
#endif /* CONFIG_IEEE80211BE */
bool ssid_protection;
int rsn_override_omit_rsnxe;
}; };
typedef enum { typedef enum {
@ -331,6 +297,16 @@ typedef enum {
WPA_EAPOL_keyDone, WPA_EAPOL_inc_EapolFramesTx WPA_EAPOL_keyDone, WPA_EAPOL_inc_EapolFramesTx
} wpa_eapol_variable; } wpa_eapol_variable;
struct wpa_auth_ml_rsn_info {
unsigned int n_mld_links;
struct wpa_auth_ml_link_rsn_info {
unsigned int link_id;
const u8 *rsn_ies;
size_t rsn_ies_len;
} links[MAX_NUM_MLD_LINKS];
};
struct wpa_auth_ml_key_info { struct wpa_auth_ml_key_info {
unsigned int n_mld_links; unsigned int n_mld_links;
bool mgmt_frame_prot; bool mgmt_frame_prot;
@ -424,8 +400,8 @@ 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_rsn_info)(void *ctx, struct wpa_auth_ml_rsn_info *info);
bool rekey); int (*get_ml_key_info)(void *ctx, struct wpa_auth_ml_key_info *info);
#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);
}; };
@ -453,8 +429,7 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
const u8 *wpa_ie, size_t wpa_ie_len, const u8 *wpa_ie, size_t wpa_ie_len,
const u8 *rsnxe, size_t rsnxe_len, const u8 *rsnxe, size_t rsnxe_len,
const u8 *mdie, size_t mdie_len, const u8 *mdie, size_t mdie_len,
const u8 *owe_dh, size_t owe_dh_len, const u8 *owe_dh, size_t owe_dh_len);
struct wpa_state_machine *assoc_sm);
int wpa_validate_osen(struct wpa_authenticator *wpa_auth, int wpa_validate_osen(struct wpa_authenticator *wpa_auth,
struct wpa_state_machine *sm, struct wpa_state_machine *sm,
const u8 *osen_ie, size_t osen_ie_len); const u8 *osen_ie, size_t osen_ie_len);
@ -545,9 +520,9 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
size_t max_len, int auth_alg, size_t max_len, int auth_alg,
const u8 *req_ies, size_t req_ies_len, const u8 *req_ies, size_t req_ies_len,
int omit_rsnxe); int omit_rsnxe);
void wpa_ft_process_auth(struct wpa_state_machine *sm, void wpa_ft_process_auth(struct wpa_state_machine *sm, const u8 *bssid,
u16 auth_transaction, const u8 *ies, size_t ies_len, u16 auth_transaction, const u8 *ies, size_t ies_len,
void (*cb)(void *ctx, const u8 *dst, void (*cb)(void *ctx, const u8 *dst, const u8 *bssid,
u16 auth_transaction, u16 resp, u16 auth_transaction, u16 resp,
const u8 *ies, size_t ies_len), const u8 *ies, size_t ies_len),
void *ctx); void *ctx);
@ -630,10 +605,7 @@ 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_transition_disable(struct wpa_authenticator *wpa_auth, void wpa_auth_set_transition_disable(struct wpa_authenticator *wpa_auth,
u8 val); u8 val);
@ -667,20 +639,12 @@ void wpa_auth_set_ocv_override_freq(struct wpa_authenticator *wpa_auth,
void wpa_auth_sta_radius_psk_resp(struct wpa_state_machine *sm, bool success); void wpa_auth_sta_radius_psk_resp(struct wpa_state_machine *sm, bool success);
void wpa_auth_set_ml_info(struct wpa_state_machine *sm, void wpa_auth_set_ml_info(struct wpa_state_machine *sm, const u8 *mld_addr,
u8 mld_assoc_link_id, struct mld_info *info); u8 mld_assoc_link_id, struct mld_info *info);
void wpa_auth_ml_get_rsn_info(struct wpa_authenticator *a,
struct wpa_auth_ml_link_rsn_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,
int release_link_id);
#define for_each_sm_auth(sm, link_id) \
for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) \
if (sm->mld_links[link_id].valid && \
sm->mld_links[link_id].wpa_auth && \
sm->wpa_auth != sm->mld_links[link_id].wpa_auth)
#endif /* WPA_AUTH_H */ #endif /* WPA_AUTH_H */

View file

@ -3442,9 +3442,9 @@ out:
} }
void wpa_ft_process_auth(struct wpa_state_machine *sm, void wpa_ft_process_auth(struct wpa_state_machine *sm, const u8 *bssid,
u16 auth_transaction, const u8 *ies, size_t ies_len, u16 auth_transaction, const u8 *ies, size_t ies_len,
void (*cb)(void *ctx, const u8 *dst, void (*cb)(void *ctx, const u8 *dst, const u8 *bssid,
u16 auth_transaction, u16 status, u16 auth_transaction, u16 status,
const u8 *ies, size_t ies_len), const u8 *ies, size_t ies_len),
void *ctx) void *ctx)
@ -3462,8 +3462,7 @@ void wpa_ft_process_auth(struct wpa_state_machine *sm,
wpa_printf(MSG_DEBUG, "FT: Received authentication frame: STA=" MACSTR wpa_printf(MSG_DEBUG, "FT: Received authentication frame: STA=" MACSTR
" BSSID=" MACSTR " transaction=%d", " BSSID=" MACSTR " transaction=%d",
MAC2STR(sm->addr), MAC2STR(sm->wpa_auth->addr), MAC2STR(sm->addr), MAC2STR(bssid), auth_transaction);
auth_transaction);
sm->ft_pending_cb = cb; sm->ft_pending_cb = cb;
sm->ft_pending_cb_ctx = ctx; sm->ft_pending_cb_ctx = ctx;
sm->ft_pending_auth_transaction = auth_transaction; sm->ft_pending_auth_transaction = auth_transaction;
@ -3481,7 +3480,8 @@ void wpa_ft_process_auth(struct wpa_state_machine *sm,
MAC2STR(sm->addr), auth_transaction + 1, status, MAC2STR(sm->addr), auth_transaction + 1, status,
status2str(status)); status2str(status));
wpa_hexdump(MSG_DEBUG, "FT: Response IEs", resp_ies, resp_ies_len); wpa_hexdump(MSG_DEBUG, "FT: Response IEs", resp_ies, resp_ies_len);
cb(ctx, sm->addr, auth_transaction + 1, status, resp_ies, resp_ies_len); cb(ctx, sm->addr, bssid, auth_transaction + 1, status,
resp_ies, resp_ies_len);
os_free(resp_ies); os_free(resp_ies);
} }
@ -3810,7 +3810,7 @@ int wpa_ft_action_rx(struct wpa_state_machine *sm, const u8 *data, size_t len)
} }
static void wpa_ft_rrb_rx_request_cb(void *ctx, const u8 *dst, static void wpa_ft_rrb_rx_request_cb(void *ctx, const u8 *dst, const u8 *bssid,
u16 auth_transaction, u16 resp, u16 auth_transaction, u16 resp,
const u8 *ies, size_t ies_len) const u8 *ies, size_t ies_len)
{ {
@ -4339,7 +4339,7 @@ static void ft_finish_pull(struct wpa_state_machine *sm)
wpa_printf(MSG_DEBUG, "FT: Postponed auth callback result for " MACSTR wpa_printf(MSG_DEBUG, "FT: Postponed auth callback result for " MACSTR
" - status %u", MAC2STR(sm->addr), status); " - status %u", MAC2STR(sm->addr), status);
sm->ft_pending_cb(sm->ft_pending_cb_ctx, sm->addr, sm->ft_pending_cb(sm->ft_pending_cb_ctx, sm->addr, sm->wpa_auth->addr,
sm->ft_pending_auth_transaction + 1, status, sm->ft_pending_auth_transaction + 1, status,
resp_ies, resp_ies_len); resp_ies, resp_ies_len);
os_free(resp_ies); os_free(resp_ies);

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,17 +70,14 @@ 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;
wconf->ssid_protection = conf->ssid_protection; #ifdef CONFIG_IEEE80211R_AP
wconf->ssid_len = conf->ssid.ssid_len; wconf->ssid_len = conf->ssid.ssid_len;
if (wconf->ssid_len > SSID_MAX_LEN) if (wconf->ssid_len > SSID_MAX_LEN)
wconf->ssid_len = SSID_MAX_LEN; wconf->ssid_len = SSID_MAX_LEN;
os_memcpy(wconf->ssid, conf->ssid.ssid, wconf->ssid_len); os_memcpy(wconf->ssid, conf->ssid.ssid, wconf->ssid_len);
#ifdef CONFIG_IEEE80211R_AP
os_memcpy(wconf->mobility_domain, conf->mobility_domain, os_memcpy(wconf->mobility_domain, conf->mobility_domain,
MOBILITY_DOMAIN_ID_LEN); MOBILITY_DOMAIN_ID_LEN);
if (conf->nas_identifier && if (conf->nas_identifier &&
@ -132,46 +125,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 +189,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);
@ -272,11 +224,6 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
#endif /* CONFIG_PASN */ #endif /* CONFIG_PASN */
wconf->radius_psk = conf->wpa_psk_radius == PSK_RADIUS_DURING_4WAY_HS; wconf->radius_psk = conf->wpa_psk_radius == PSK_RADIUS_DURING_4WAY_HS;
wconf->no_disconnect_on_group_keyerror =
conf->bss_max_idle && conf->ap_max_inactivity &&
conf->no_disconnect_on_group_keyerror;
wconf->rsn_override_omit_rsnxe = conf->rsn_override_omit_rsnxe;
} }
@ -1586,12 +1533,54 @@ 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_rsn_info(void *ctx,
struct wpa_auth_ml_key_info *info, struct wpa_auth_ml_rsn_info *info)
bool rekey)
{ {
struct hostapd_data *hapd = ctx; struct hostapd_data *hapd = ctx;
unsigned int i; unsigned int i, j;
wpa_printf(MSG_DEBUG, "WPA_AUTH: MLD: Get RSN info CB: n_mld_links=%u",
info->n_mld_links);
if (!hapd->conf->mld_ap || !hapd->iface || !hapd->iface->interfaces)
return -1;
for (i = 0; i < info->n_mld_links; i++) {
unsigned int link_id = info->links[i].link_id;
wpa_printf(MSG_DEBUG,
"WPA_AUTH: MLD: Get link RSN CB: link_id=%u",
link_id);
for (j = 0; j < hapd->iface->interfaces->count; j++) {
struct hostapd_iface *iface =
hapd->iface->interfaces->iface[j];
if (!iface->bss[0]->conf->mld_ap ||
hapd->conf->mld_id != iface->bss[0]->conf->mld_id ||
link_id != iface->bss[0]->mld_link_id ||
!iface->bss[0]->wpa_auth)
continue;
wpa_auth_ml_get_rsn_info(iface->bss[0]->wpa_auth,
&info->links[i]);
break;
}
if (j == hapd->iface->interfaces->count)
wpa_printf(MSG_DEBUG,
"WPA_AUTH: MLD: link=%u not found", link_id);
}
return 0;
}
static int hostapd_wpa_auth_get_ml_key_info(void *ctx,
struct wpa_auth_ml_key_info *info)
{
struct hostapd_data *hapd = ctx;
unsigned int i, j;
wpa_printf(MSG_DEBUG, "WPA_AUTH: MLD: Get key info CB: n_mld_links=%u", wpa_printf(MSG_DEBUG, "WPA_AUTH: MLD: Get key info CB: n_mld_links=%u",
info->n_mld_links); info->n_mld_links);
@ -1600,37 +1589,30 @@ static int hostapd_wpa_auth_get_ml_key_info(void *ctx,
return -1; return -1;
for (i = 0; i < info->n_mld_links; i++) { for (i = 0; i < info->n_mld_links; i++) {
struct hostapd_data *bss;
u8 link_id = info->links[i].link_id; u8 link_id = info->links[i].link_id;
bool link_bss_found = false;
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"WPA_AUTH: MLD: Get link info CB: link_id=%u", "WPA_AUTH: MLD: Get link info CB: link_id=%u",
link_id); link_id);
if (hapd->mld_link_id == link_id) { for (j = 0; j < hapd->iface->interfaces->count; j++) {
wpa_auth_ml_get_key_info(hapd->wpa_auth, struct hostapd_iface *iface =
&info->links[i], hapd->iface->interfaces->iface[j];
info->mgmt_frame_prot,
info->beacon_prot,
rekey);
continue;
}
for_each_mld_link(bss, hapd) { if (!iface->bss[0]->conf->mld_ap ||
if (bss == hapd || bss->mld_link_id != link_id) hapd->conf->mld_id != iface->bss[0]->conf->mld_id ||
link_id != iface->bss[0]->mld_link_id ||
!iface->bss[0]->wpa_auth)
continue; continue;
wpa_auth_ml_get_key_info(bss->wpa_auth, wpa_auth_ml_get_key_info(iface->bss[0]->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;
break; break;
} }
if (!link_bss_found) if (j == hapd->iface->interfaces->count)
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"WPA_AUTH: MLD: link=%u not found", link_id); "WPA_AUTH: MLD: link=%u not found", link_id);
} }
@ -1706,6 +1688,7 @@ int hostapd_setup_wpa(struct hostapd_data *hapd)
.set_ltf_keyseed = hostapd_set_ltf_keyseed, .set_ltf_keyseed = hostapd_set_ltf_keyseed,
#endif /* CONFIG_PASN */ #endif /* CONFIG_PASN */
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
.get_ml_rsn_info = hostapd_wpa_auth_get_ml_rsn_info,
.get_ml_key_info = hostapd_wpa_auth_get_ml_key_info, .get_ml_key_info = hostapd_wpa_auth_get_ml_key_info,
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
.get_drv_flags = hostapd_wpa_auth_get_drv_flags, .get_drv_flags = hostapd_wpa_auth_get_drv_flags,
@ -1756,27 +1739,6 @@ int hostapd_setup_wpa(struct hostapd_data *hapd)
!!(hapd->iface->drv_flags2 & !!(hapd->iface->drv_flags2 &
WPA_DRIVER_FLAGS2_PROT_RANGE_NEG_AP); WPA_DRIVER_FLAGS2_PROT_RANGE_NEG_AP);
#ifdef CONFIG_IEEE80211BE
_conf.mld_addr = NULL;
_conf.link_id = -1;
_conf.first_link_auth = NULL;
if (hapd->conf->mld_ap) {
struct hostapd_data *lhapd;
_conf.mld_addr = hapd->mld->mld_addr;
_conf.link_id = hapd->mld_link_id;
for_each_mld_link(lhapd, hapd) {
if (lhapd == hapd)
continue;
if (lhapd->wpa_auth)
_conf.first_link_auth = lhapd->wpa_auth;
}
}
#endif /* CONFIG_IEEE80211BE */
hapd->wpa_auth = wpa_init(hapd->own_addr, &_conf, &cb, hapd); hapd->wpa_auth = wpa_init(hapd->own_addr, &_conf, &cb, hapd);
if (hapd->wpa_auth == NULL) { if (hapd->wpa_auth == NULL) {
wpa_printf(MSG_ERROR, "WPA initialization failed."); wpa_printf(MSG_ERROR, "WPA initialization failed.");

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 */
@ -141,7 +136,7 @@ struct wpa_state_machine {
size_t r0kh_id_len; size_t r0kh_id_len;
u8 *assoc_resp_ftie; u8 *assoc_resp_ftie;
void (*ft_pending_cb)(void *ctx, const u8 *dst, void (*ft_pending_cb)(void *ctx, const u8 *dst, const u8 *bssid,
u16 auth_transaction, u16 status, u16 auth_transaction, u16 status,
const u8 *ies, size_t ies_len); const u8 *ies, size_t ies_len);
void *ft_pending_cb_ctx; void *ft_pending_cb_ctx;
@ -177,6 +172,7 @@ struct wpa_state_machine {
#endif /* CONFIG_TESTING_OPTIONS */ #endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_IEEE80211BE #ifdef CONFIG_IEEE80211BE
u8 own_mld_addr[ETH_ALEN];
u8 peer_mld_addr[ETH_ALEN]; u8 peer_mld_addr[ETH_ALEN];
s8 mld_assoc_link_id; s8 mld_assoc_link_id;
u8 n_mld_affiliated_links; u8 n_mld_affiliated_links;
@ -184,12 +180,14 @@ struct wpa_state_machine {
struct mld_link { struct mld_link {
bool valid; bool valid;
u8 peer_addr[ETH_ALEN]; u8 peer_addr[ETH_ALEN];
u8 own_addr[ETH_ALEN];
struct wpa_authenticator *wpa_auth; const u8 *rsne;
size_t rsne_len;
const u8 *rsnxe;
size_t rsnxe_len;
} mld_links[MAX_NUM_MLD_LINKS]; } mld_links[MAX_NUM_MLD_LINKS];
#endif /* CONFIG_IEEE80211BE */ #endif /* CONFIG_IEEE80211BE */
bool ssid_protection;
}; };
@ -264,13 +262,6 @@ struct wpa_authenticator {
#ifdef CONFIG_P2P #ifdef CONFIG_P2P
struct bitfield *ip_pool; struct bitfield *ip_pool;
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */
#ifdef CONFIG_IEEE80211BE
bool is_ml;
u8 mld_addr[ETH_ALEN];
u8 link_id;
bool primary_auth;
#endif /* CONFIG_IEEE80211BE */
}; };

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;
u16 capab = 0;
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)
@ -505,75 +429,20 @@ static u32 rsnxe_capab(struct wpa_auth_config *conf, int key_mgmt)
capab |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT); capab |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT);
if (conf->prot_range_neg) if (conf->prot_range_neg)
capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR); capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR);
if (conf->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);
flen = (capab & 0xff00) ? 2 : 1;
if (!capab) if (!capab)
return 0; /* no supported extended RSN capabilities */ return 0; /* no supported extended RSN capabilities */
tmp = capab;
flen = 0;
while (tmp) {
flen++;
tmp >>= 8;
}
if (len < 2 + flen) if (len < 2 + flen)
return -1; return -1;
capab |= flen - 1; /* bit 0-3 = Field length (n - 1) */ capab |= flen - 1; /* bit 0-3 = Field length (n - 1) */
*pos++ = WLAN_EID_RSNX; *pos++ = WLAN_EID_RSNX;
*pos++ = flen; *pos++ = flen;
while (capab) { *pos++ = capab & 0x00ff;
*pos++ = capab & 0xff;
capab >>= 8; capab >>= 8;
} if (capab)
*pos++ = capab;
return pos - buf;
}
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; return pos - buf;
} }
@ -632,7 +501,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 +527,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 +554,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)
@ -856,8 +608,7 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
const u8 *wpa_ie, size_t wpa_ie_len, const u8 *wpa_ie, size_t wpa_ie_len,
const u8 *rsnxe, size_t rsnxe_len, const u8 *rsnxe, size_t rsnxe_len,
const u8 *mdie, size_t mdie_len, const u8 *mdie, size_t mdie_len,
const u8 *owe_dh, size_t owe_dh_len, const u8 *owe_dh, size_t owe_dh_len)
struct wpa_state_machine *assoc_sm)
{ {
struct wpa_auth_config *conf = &wpa_auth->conf; struct wpa_auth_config *conf = &wpa_auth->conf;
struct wpa_ie_data data; struct wpa_ie_data data;
@ -1014,12 +765,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 +834,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;
@ -1217,15 +956,6 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
else else
sm->wpa = WPA_VERSION_WPA; sm->wpa = WPA_VERSION_WPA;
if (assoc_sm) {
/* For ML association link STA cannot choose a different
* AKM or pairwise cipher from association STA */
if (sm->wpa_key_mgmt != assoc_sm->wpa_key_mgmt)
return WPA_INVALID_AKMP;
if (sm->pairwise != assoc_sm->pairwise)
return WPA_INVALID_PAIRWISE;
}
#if defined(CONFIG_IEEE80211R_AP) && defined(CONFIG_FILS) #if defined(CONFIG_IEEE80211R_AP) && defined(CONFIG_FILS)
if ((sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_FILS_SHA256 || if ((sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_FILS_SHA256 ||
sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_FILS_SHA384) && sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_FILS_SHA384) &&
@ -1482,7 +1212,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

@ -80,19 +80,16 @@ endif
_DIRS := $(BUILDDIR)/$(PROJ) _DIRS := $(BUILDDIR)/$(PROJ)
.PHONY: _make_dirs .PHONY: _make_dirs
_make_dirs: _make_dirs:
@mkdir -p $(sort $(_DIRS)) @mkdir -p $(_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

@ -381,75 +381,6 @@ int check_40mhz_2g4(struct hostapd_hw_modes *mode,
} }
static void punct_update_legacy_bw_80(u8 bitmap, u8 pri_chan, u8 *seg0)
{
u8 first_chan = *seg0 - 6, sec_chan;
switch (bitmap) {
case 0x6:
*seg0 = 0;
return;
case 0x8:
case 0x4:
case 0x2:
case 0x1:
case 0xC:
case 0x3:
if (pri_chan < *seg0)
*seg0 -= 4;
else
*seg0 += 4;
break;
}
if (pri_chan < *seg0)
sec_chan = pri_chan + 4;
else
sec_chan = pri_chan - 4;
if (bitmap & BIT((sec_chan - first_chan) / 4))
*seg0 = 0;
}
static void punct_update_legacy_bw_160(u8 bitmap, u8 pri,
enum oper_chan_width *width, u8 *seg0)
{
if (pri < *seg0) {
*seg0 -= 8;
if (bitmap & 0x0F) {
*width = 0;
punct_update_legacy_bw_80(bitmap & 0xF, pri, seg0);
}
} else {
*seg0 += 8;
if (bitmap & 0xF0) {
*width = 0;
punct_update_legacy_bw_80((bitmap & 0xF0) >> 4, pri,
seg0);
}
}
}
void punct_update_legacy_bw(u16 bitmap, u8 pri, enum oper_chan_width *width,
u8 *seg0, u8 *seg1)
{
if (*width == CONF_OPER_CHWIDTH_80MHZ && (bitmap & 0xF)) {
*width = CONF_OPER_CHWIDTH_USE_HT;
punct_update_legacy_bw_80(bitmap & 0xF, pri, seg0);
}
if (*width == CONF_OPER_CHWIDTH_160MHZ && (bitmap & 0xFF)) {
*width = CONF_OPER_CHWIDTH_80MHZ;
*seg1 = 0;
punct_update_legacy_bw_160(bitmap & 0xFF, pri, width, seg0);
}
/* TODO: 320 MHz */
}
int hostapd_set_freq_params(struct hostapd_freq_params *data, int hostapd_set_freq_params(struct hostapd_freq_params *data,
enum hostapd_hw_mode mode, enum hostapd_hw_mode mode,
int freq, int channel, int enable_edmg, int freq, int channel, int enable_edmg,
@ -460,12 +391,8 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data,
int center_segment0, int center_segment0,
int center_segment1, u32 vht_caps, int center_segment1, u32 vht_caps,
struct he_capabilities *he_cap, struct he_capabilities *he_cap,
struct eht_capabilities *eht_cap, struct eht_capabilities *eht_cap)
u16 punct_bitmap)
{ {
enum oper_chan_width oper_chwidth_legacy;
u8 seg0_legacy, seg1_legacy;
if (!he_cap || !he_cap->he_supported) if (!he_cap || !he_cap->he_supported)
he_enabled = 0; he_enabled = 0;
if (!eht_cap || !eht_cap->eht_supported) if (!eht_cap || !eht_cap->eht_supported)
@ -651,14 +578,6 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data,
break; break;
} }
oper_chwidth_legacy = oper_chwidth;
seg0_legacy = center_segment0;
seg1_legacy = center_segment1;
if (punct_bitmap)
punct_update_legacy_bw(punct_bitmap, channel,
&oper_chwidth_legacy,
&seg0_legacy, &seg1_legacy);
if (data->eht_enabled || data->he_enabled || if (data->eht_enabled || data->he_enabled ||
data->vht_enabled) switch (oper_chwidth) { data->vht_enabled) switch (oper_chwidth) {
case CONF_OPER_CHWIDTH_USE_HT: case CONF_OPER_CHWIDTH_USE_HT:
@ -683,8 +602,7 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data,
/* fall through */ /* fall through */
case CONF_OPER_CHWIDTH_80MHZ: case CONF_OPER_CHWIDTH_80MHZ:
data->bandwidth = 80; data->bandwidth = 80;
if (!sec_channel_offset && if (!sec_channel_offset) {
oper_chwidth_legacy != CONF_OPER_CHWIDTH_USE_HT) {
wpa_printf(MSG_ERROR, wpa_printf(MSG_ERROR,
"80/80+80 MHz: no second channel offset"); "80/80+80 MHz: no second channel offset");
return -1; return -1;
@ -742,8 +660,7 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data,
"160 MHz: center segment 1 should not be set"); "160 MHz: center segment 1 should not be set");
return -1; return -1;
} }
if (!sec_channel_offset && if (!sec_channel_offset) {
oper_chwidth_legacy != CONF_OPER_CHWIDTH_USE_HT) {
wpa_printf(MSG_ERROR, wpa_printf(MSG_ERROR,
"160 MHz: second channel offset not set"); "160 MHz: second channel offset not set");
return -1; return -1;
@ -1033,18 +950,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

@ -35,8 +35,6 @@ int check_40mhz_5g(struct wpa_scan_results *scan_res,
int check_40mhz_2g4(struct hostapd_hw_modes *mode, int check_40mhz_2g4(struct hostapd_hw_modes *mode,
struct wpa_scan_results *scan_res, int pri_chan, struct wpa_scan_results *scan_res, int pri_chan,
int sec_chan); int sec_chan);
void punct_update_legacy_bw(u16 bitmap, u8 pri_chan,
enum oper_chan_width *width, u8 *seg0, u8 *seg1);
int hostapd_set_freq_params(struct hostapd_freq_params *data, int hostapd_set_freq_params(struct hostapd_freq_params *data,
enum hostapd_hw_mode mode, enum hostapd_hw_mode mode,
int freq, int channel, int edmg, u8 edmg_channel, int freq, int channel, int edmg, u8 edmg_channel,
@ -47,8 +45,7 @@ int hostapd_set_freq_params(struct hostapd_freq_params *data,
int center_segment0, int center_segment0,
int center_segment1, u32 vht_caps, int center_segment1, u32 vht_caps,
struct he_capabilities *he_caps, struct he_capabilities *he_caps,
struct eht_capabilities *eht_cap, struct eht_capabilities *eht_cap);
u16 punct_bitmap);
void set_disable_ht40(struct ieee80211_ht_capabilities *htcaps, void set_disable_ht40(struct ieee80211_ht_capabilities *htcaps,
int disabled); int disabled);
int ieee80211ac_cap_check(u32 hw, u32 conf); int ieee80211ac_cap_check(u32 hw, u32 conf);
@ -58,7 +55,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 "
@ -629,12 +607,6 @@ static ParseRes __ieee802_11_parse_elems(const u8 *start, size_t len,
elems->rrm_enabled = pos; elems->rrm_enabled = pos;
elems->rrm_enabled_len = elen; elems->rrm_enabled_len = elen;
break; break;
case WLAN_EID_MULTIPLE_BSSID:
if (elen < 1)
break;
elems->mbssid = pos;
elems->mbssid_len = elen;
break;
case WLAN_EID_CAG_NUMBER: case WLAN_EID_CAG_NUMBER:
elems->cag_number = pos; elems->cag_number = pos;
elems->cag_number_len = elen; elems->cag_number_len = elen;
@ -1515,6 +1487,8 @@ ieee80211_freq_to_channel_ext(unsigned int freq, int sec_channel,
*op_class = 126; *op_class = 126;
else if (sec_channel == -1) else if (sec_channel == -1)
*op_class = 127; *op_class = 127;
else if (freq <= 5805)
*op_class = 124;
else else
*op_class = 125; *op_class = 125;
@ -2066,13 +2040,6 @@ int is_dfs_global_op_class(u8 op_class)
} }
bool is_80plus_op_class(u8 op_class)
{
/* Operating classes with "80+" behavior indication in Table E-4 */
return op_class == 130 || op_class == 135;
}
static int is_11b(u8 rate) static int is_11b(u8 rate)
{ {
return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16; return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16;
@ -2439,17 +2406,9 @@ const struct oper_class_map global_op_class[] = {
* channel center frequency index value, but it happens to be a 20 MHz * channel center frequency index value, but it happens to be a 20 MHz
* channel and the channel number in the channel set would match the * channel and the channel number in the channel set would match the
* value in for the frequency center. * value in for the frequency center.
*
* Operating class value pair 128 and 130 is used to describe a 80+80
* MHz channel on the 5 GHz band. 130 is identified with "80+", so this
* is encoded with two octets 130 and 128. Similarly, operating class
* value pair 133 and 135 is used to describe a 80+80 MHz channel on
* the 6 GHz band (135 being the one with "80+" indication). All other
* operating classes listed here are used as 1-octet values.
*/ */
{ HOSTAPD_MODE_IEEE80211A, 128, 36, 177, 4, BW80, P2P_SUPP }, { HOSTAPD_MODE_IEEE80211A, 128, 36, 177, 4, BW80, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 129, 36, 177, 4, BW160, P2P_SUPP }, { HOSTAPD_MODE_IEEE80211A, 129, 36, 177, 4, BW160, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 130, 36, 177, 4, BW80P80, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 131, 1, 233, 4, BW20, P2P_SUPP }, { HOSTAPD_MODE_IEEE80211A, 131, 1, 233, 4, BW20, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 132, 1, 233, 8, BW40, P2P_SUPP }, { HOSTAPD_MODE_IEEE80211A, 132, 1, 233, 8, BW40, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 133, 1, 233, 16, BW80, P2P_SUPP }, { HOSTAPD_MODE_IEEE80211A, 133, 1, 233, 16, BW80, P2P_SUPP },
@ -2457,9 +2416,6 @@ const struct oper_class_map global_op_class[] = {
{ HOSTAPD_MODE_IEEE80211A, 135, 1, 233, 16, BW80P80, NO_P2P_SUPP }, { HOSTAPD_MODE_IEEE80211A, 135, 1, 233, 16, BW80P80, NO_P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211A, 136, 2, 2, 4, BW20, NO_P2P_SUPP }, { HOSTAPD_MODE_IEEE80211A, 136, 2, 2, 4, BW20, NO_P2P_SUPP },
/* IEEE P802.11be/D5.0, Table E-4 (Global operating classes) */
{ HOSTAPD_MODE_IEEE80211A, 137, 31, 191, 32, BW320, NO_P2P_SUPP },
/* /*
* IEEE Std 802.11ad-2012 and P802.ay/D5.0 60 GHz operating classes. * IEEE Std 802.11ad-2012 and P802.ay/D5.0 60 GHz operating classes.
* Class 180 has the legacy channels 1-6. Classes 181-183 include * Class 180 has the legacy channels 1-6. Classes 181-183 include
@ -2470,6 +2426,11 @@ const struct oper_class_map global_op_class[] = {
{ HOSTAPD_MODE_IEEE80211AD, 182, 17, 20, 1, BW6480, P2P_SUPP }, { HOSTAPD_MODE_IEEE80211AD, 182, 17, 20, 1, BW6480, P2P_SUPP },
{ HOSTAPD_MODE_IEEE80211AD, 183, 25, 27, 1, BW8640, P2P_SUPP }, { HOSTAPD_MODE_IEEE80211AD, 183, 25, 27, 1, BW8640, P2P_SUPP },
/* Keep the operating class 130 as the last entry as a workaround for
* the OneHundredAndThirty Delimiter value used in the Supported
* Operating Classes element to indicate the end of the Operating
* Classes field. */
{ HOSTAPD_MODE_IEEE80211A, 130, 36, 177, 4, BW80P80, P2P_SUPP },
{ -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP } { -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP }
}; };
@ -2597,141 +2558,21 @@ size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len)
} }
u16 check_multi_ap_ie(const u8 *multi_ap_ie, size_t multi_ap_len, size_t add_multi_ap_ie(u8 *buf, size_t len, u8 value)
struct multi_ap_params *multi_ap)
{
const struct element *elem;
bool ext_present = false;
unsigned int vlan_id;
os_memset(multi_ap, 0, sizeof(*multi_ap));
/* Default profile is 1, when Multi-AP profile subelement is not
* present in the element. */
multi_ap->profile = 1;
for_each_element(elem, multi_ap_ie, multi_ap_len) {
u8 id = elem->id, elen = elem->datalen;
const u8 *pos = elem->data;
switch (id) {
case MULTI_AP_SUB_ELEM_TYPE:
if (elen >= 1) {
multi_ap->capability = *pos;
ext_present = true;
} else {
wpa_printf(MSG_DEBUG,
"Multi-AP invalid Multi-AP subelement");
return WLAN_STATUS_INVALID_IE;
}
break;
case MULTI_AP_PROFILE_SUB_ELEM_TYPE:
if (elen < 1) {
wpa_printf(MSG_DEBUG,
"Multi-AP IE invalid Multi-AP profile subelement");
return WLAN_STATUS_INVALID_IE;
}
multi_ap->profile = *pos;
if (multi_ap->profile > MULTI_AP_PROFILE_MAX) {
wpa_printf(MSG_DEBUG,
"Multi-AP IE with invalid profile 0x%02x",
multi_ap->profile);
return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
}
break;
case MULTI_AP_VLAN_SUB_ELEM_TYPE:
if (multi_ap->profile < MULTI_AP_PROFILE_2) {
wpa_printf(MSG_DEBUG,
"Multi-AP IE invalid profile to read VLAN IE");
return WLAN_STATUS_INVALID_IE;
}
if (elen < 2) {
wpa_printf(MSG_DEBUG,
"Multi-AP IE invalid Multi-AP VLAN subelement");
return WLAN_STATUS_INVALID_IE;
}
vlan_id = WPA_GET_LE16(pos);
if (vlan_id < 1 || vlan_id > 4094) {
wpa_printf(MSG_INFO,
"Multi-AP IE invalid Multi-AP VLAN ID %d",
vlan_id);
return WLAN_STATUS_INVALID_IE;
}
multi_ap->vlanid = vlan_id;
break;
default:
wpa_printf(MSG_DEBUG,
"Ignore unknown subelement %u in Multi-AP IE",
id);
break;
}
}
if (!for_each_element_completed(elem, multi_ap_ie, multi_ap_len)) {
wpa_printf(MSG_DEBUG, "Multi AP IE parse failed @%d",
(int) (multi_ap_ie + multi_ap_len -
(const u8 *) elem));
wpa_hexdump(MSG_MSGDUMP, "IEs", multi_ap_ie, multi_ap_len);
}
if (!ext_present) {
wpa_printf(MSG_DEBUG,
"Multi-AP element without Multi-AP Extension subelement");
return WLAN_STATUS_INVALID_IE;
}
return WLAN_STATUS_SUCCESS;
}
size_t add_multi_ap_ie(u8 *buf, size_t len,
const struct multi_ap_params *multi_ap)
{ {
u8 *pos = buf; u8 *pos = buf;
u8 *len_ptr;
if (len < 6) if (len < 9)
return 0; return 0;
*pos++ = WLAN_EID_VENDOR_SPECIFIC; *pos++ = WLAN_EID_VENDOR_SPECIFIC;
len_ptr = pos; /* Length field to be set at the end */ *pos++ = 7; /* len */
pos++;
WPA_PUT_BE24(pos, OUI_WFA); WPA_PUT_BE24(pos, OUI_WFA);
pos += 3; pos += 3;
*pos++ = MULTI_AP_OUI_TYPE; *pos++ = MULTI_AP_OUI_TYPE;
/* Multi-AP Extension subelement */
if (buf + len - pos < 3)
return 0;
*pos++ = MULTI_AP_SUB_ELEM_TYPE; *pos++ = MULTI_AP_SUB_ELEM_TYPE;
*pos++ = 1; /* len */ *pos++ = 1; /* len */
*pos++ = multi_ap->capability; *pos++ = value;
/* Add Multi-AP Profile subelement only for R2 or newer configuration */
if (multi_ap->profile >= MULTI_AP_PROFILE_2) {
if (buf + len - pos < 3)
return 0;
*pos++ = MULTI_AP_PROFILE_SUB_ELEM_TYPE;
*pos++ = 1;
*pos++ = multi_ap->profile;
}
/* Add Multi-AP Default 802.1Q Setting subelement only for backhaul BSS
*/
if (multi_ap->vlanid &&
multi_ap->profile >= MULTI_AP_PROFILE_2 &&
(multi_ap->capability & MULTI_AP_BACKHAUL_BSS)) {
if (buf + len - pos < 4)
return 0;
*pos++ = MULTI_AP_VLAN_SUB_ELEM_TYPE;
*pos++ = 2;
WPA_PUT_LE16(pos, multi_ap->vlanid);
pos += 2;
}
*len_ptr = pos - len_ptr - 1;
return pos - buf; return pos - buf;
} }
@ -2896,8 +2737,6 @@ int oper_class_bw_to_int(const struct oper_class_map *map)
case BW80P80: case BW80P80:
case BW160: case BW160:
return 160; return 160;
case BW320:
return 320;
case BW2160: case BW2160:
return 2160; return 2160;
default: default:
@ -3145,12 +2984,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

@ -30,12 +30,6 @@ struct mb_ies_info {
u8 nof_ies; u8 nof_ies;
}; };
struct multi_ap_params {
u8 capability;
u8 profile;
u16 vlanid;
};
/* Parsed Information Elements */ /* Parsed Information Elements */
struct ieee802_11_elems { struct ieee802_11_elems {
const u8 *ssid; const u8 *ssid;
@ -65,7 +59,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;
@ -116,10 +109,6 @@ struct ieee802_11_elems {
const u8 *tdls_mle; const u8 *tdls_mle;
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 *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 +129,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;
@ -183,10 +171,6 @@ struct ieee802_11_elems {
size_t tdls_mle_len; size_t tdls_mle_len;
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;
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;
@ -251,7 +235,6 @@ int ieee80211_chaninfo_to_channel(unsigned int freq, enum chan_width chanwidth,
int ieee80211_is_dfs(int freq, const struct hostapd_hw_modes *modes, int ieee80211_is_dfs(int freq, const struct hostapd_hw_modes *modes,
u16 num_modes); u16 num_modes);
int is_dfs_global_op_class(u8 op_class); int is_dfs_global_op_class(u8 op_class);
bool is_80plus_op_class(u8 op_class);
enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht); enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht);
int supp_rates_11b_only(struct ieee802_11_elems *elems); int supp_rates_11b_only(struct ieee802_11_elems *elems);
@ -270,7 +253,7 @@ struct oper_class_map {
u8 max_chan; u8 max_chan;
u8 inc; u8 inc;
enum { BW20, BW40PLUS, BW40MINUS, BW40, BW80, BW2160, BW160, BW80P80, enum { BW20, BW40PLUS, BW40MINUS, BW40, BW80, BW2160, BW160, BW80P80,
BW320, BW4320, BW6480, BW8640} bw; BW4320, BW6480, BW8640} bw;
enum { P2P_SUPP, NO_P2P_SUPP } p2p; enum { P2P_SUPP, NO_P2P_SUPP } p2p;
}; };
@ -283,10 +266,7 @@ const u8 * get_vendor_ie(const u8 *ies, size_t len, u32 vendor_type);
size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len); size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len);
u16 check_multi_ap_ie(const u8 *multi_ap_ie, size_t multi_ap_len, size_t add_multi_ap_ie(u8 *buf, size_t len, u8 value);
struct multi_ap_params *multi_ap);
size_t add_multi_ap_ie(u8 *buf, size_t len,
const struct multi_ap_params *multi_ap);
struct country_op_class { struct country_op_class {
u8 country_op_class; u8 country_op_class;

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
@ -618,7 +616,6 @@
#define WLAN_RSNX_CAPAB_SECURE_RTT 9 #define WLAN_RSNX_CAPAB_SECURE_RTT 9
#define WLAN_RSNX_CAPAB_URNM_MFPR_X20 10 #define WLAN_RSNX_CAPAB_URNM_MFPR_X20 10
#define WLAN_RSNX_CAPAB_URNM_MFPR 15 #define WLAN_RSNX_CAPAB_URNM_MFPR 15
#define WLAN_RSNX_CAPAB_SSID_PROTECTION 21
/* Multiple BSSID element subelements */ /* Multiple BSSID element subelements */
#define WLAN_MBSSID_SUBELEMENT_NONTRANSMITTED_BSSID_PROFILE 0 #define WLAN_MBSSID_SUBELEMENT_NONTRANSMITTED_BSSID_PROFILE 0
@ -1427,7 +1424,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,30 +1445,13 @@ 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_VLAN_SUB_ELEM_TYPE 0x08
#define MULTI_AP_PROFILE2_BACKHAUL_STA_DISALLOWED BIT(2)
#define MULTI_AP_PROFILE1_BACKHAUL_STA_DISALLOWED BIT(3)
#define MULTI_AP_TEAR_DOWN BIT(4) #define MULTI_AP_TEAR_DOWN BIT(4)
#define MULTI_AP_FRONTHAUL_BSS BIT(5) #define MULTI_AP_FRONTHAUL_BSS BIT(5)
#define MULTI_AP_BACKHAUL_BSS BIT(6) #define MULTI_AP_BACKHAUL_BSS BIT(6)
#define MULTI_AP_BACKHAUL_STA BIT(7) #define MULTI_AP_BACKHAUL_STA BIT(7)
#define MULTI_AP_PROFILE_1 1
#define MULTI_AP_PROFILE_2 2
#define MULTI_AP_PROFILE_MAX 6
#define WMM_OUI_TYPE 2 #define WMM_OUI_TYPE 2
#define WMM_OUI_SUBTYPE_INFORMATION_ELEMENT 0 #define WMM_OUI_SUBTYPE_INFORMATION_ELEMENT 0
#define WMM_OUI_SUBTYPE_PARAMETER_ELEMENT 1 #define WMM_OUI_SUBTYPE_PARAMETER_ELEMENT 1
@ -1721,7 +1700,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 +1730,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 +1754,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 +1785,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 +2853,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;
@ -1259,12 +1209,6 @@ int nan_de_publish(struct nan_de *de, const char *service_name,
return -1; return -1;
} }
if (!params->unsolicited && !params->solicited) {
wpa_printf(MSG_INFO,
"NAN: Publish() - both unsolicited and solicited disabled is invalid");
return -1;
}
publish_id = nan_de_get_handle(de); publish_id = nan_de_get_handle(de);
if (publish_id < 1) if (publish_id < 1)
return -1; return -1;
@ -1311,7 +1255,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 +1306,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 +1331,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 +1346,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

@ -19,8 +19,6 @@ struct ptksa_cache {
unsigned int n_ptksa; unsigned int n_ptksa;
}; };
#ifdef CONFIG_PTKSA_CACHE
static void ptksa_cache_set_expiration(struct ptksa_cache *ptksa); static void ptksa_cache_set_expiration(struct ptksa_cache *ptksa);
@ -344,44 +342,3 @@ struct ptksa_cache_entry * ptksa_cache_add(struct ptksa_cache *ptksa,
return entry; return entry;
} }
#else /* CONFIG_PTKSA_CACHE */
struct ptksa_cache * ptksa_cache_init(void)
{
return (struct ptksa_cache *) 1;
}
void ptksa_cache_deinit(struct ptksa_cache *ptksa)
{
}
struct ptksa_cache_entry *
ptksa_cache_get(struct ptksa_cache *ptksa, const u8 *addr, u32 cipher)
{
return NULL;
}
int ptksa_cache_list(struct ptksa_cache *ptksa, char *buf, size_t len)
{
return -1;
}
struct ptksa_cache_entry *
ptksa_cache_add(struct ptksa_cache *ptksa, const u8 *own_addr, const u8 *addr,
u32 cipher, u32 life_time, const struct wpa_ptk *ptk,
void (*cb)(struct ptksa_cache_entry *e), void *ctx, u32 akmp)
{
return NULL;
}
void ptksa_cache_flush(struct ptksa_cache *ptksa, const u8 *addr, u32 cipher)
{
}
#endif /* CONFIG_PTKSA_CACHE */

View file

@ -29,6 +29,7 @@ struct ptksa_cache_entry {
u32 akmp; u32 akmp;
}; };
#ifdef CONFIG_PTKSA_CACHE
struct ptksa_cache; struct ptksa_cache;
@ -47,4 +48,41 @@ struct ptksa_cache_entry * ptksa_cache_add(struct ptksa_cache *ptksa,
void *ctx, u32 akmp); void *ctx, u32 akmp);
void ptksa_cache_flush(struct ptksa_cache *ptksa, const u8 *addr, u32 cipher); void ptksa_cache_flush(struct ptksa_cache *ptksa, const u8 *addr, u32 cipher);
#else /* CONFIG_PTKSA_CACHE */
static inline struct ptksa_cache * ptksa_cache_init(void)
{
return (struct ptksa_cache *) 1;
}
static inline void ptksa_cache_deinit(struct ptksa_cache *ptksa)
{
}
static inline struct ptksa_cache_entry *
ptksa_cache_get(struct ptksa_cache *ptksa, const u8 *addr, u32 cipher)
{
return NULL;
}
static inline int ptksa_cache_list(struct ptksa_cache *ptksa,
char *buf, size_t len)
{
return -1;
}
static inline struct ptksa_cache_entry *
ptksa_cache_add(struct ptksa_cache *ptksa, const u8 *own_addr, const u8 *addr,
u32 cipher, u32 life_time, const struct wpa_ptk *ptk,
void (*cb)(struct ptksa_cache_entry *e), void *ctx, u32 akmp)
{
return NULL;
}
static inline void ptksa_cache_flush(struct ptksa_cache *ptksa,
const u8 *addr, u32 cipher)
{
}
#endif /* CONFIG_PTKSA_CACHE */
#endif /* PTKSA_CACHE_H */ #endif /* PTKSA_CACHE_H */

File diff suppressed because it is too large Load diff

View file

@ -2103,11 +2103,8 @@ static int sae_parse_rejected_groups(struct sae_data *sae,
wpa_hexdump(MSG_DEBUG, "SAE: Possible elements at the end of the frame", wpa_hexdump(MSG_DEBUG, "SAE: Possible elements at the end of the frame",
*pos, end - *pos); *pos, end - *pos);
if (!sae_is_rejected_groups_elem(*pos, end)) { if (!sae_is_rejected_groups_elem(*pos, end))
wpabuf_free(sae->tmp->peer_rejected_groups);
sae->tmp->peer_rejected_groups = NULL;
return WLAN_STATUS_SUCCESS; return WLAN_STATUS_SUCCESS;
}
epos = *pos; epos = *pos;
epos++; /* skip IE type */ epos++; /* skip IE type */
@ -2116,12 +2113,6 @@ static int sae_parse_rejected_groups(struct sae_data *sae,
return WLAN_STATUS_UNSPECIFIED_FAILURE; return WLAN_STATUS_UNSPECIFIED_FAILURE;
epos++; /* skip ext ID */ epos++; /* skip ext ID */
len--; len--;
if (len & 1) {
wpa_printf(MSG_DEBUG,
"SAE: Invalid length of the Rejected Groups element payload: %u",
len);
return WLAN_STATUS_UNSPECIFIED_FAILURE;
}
wpabuf_free(sae->tmp->peer_rejected_groups); wpabuf_free(sae->tmp->peer_rejected_groups);
sae->tmp->peer_rejected_groups = wpabuf_alloc(len); sae->tmp->peer_rejected_groups = wpabuf_alloc(len);
@ -2205,9 +2196,6 @@ u16 sae_parse_commit(struct sae_data *sae, const u8 *data, size_t len,
res = sae_parse_rejected_groups(sae, &pos, end); res = sae_parse_rejected_groups(sae, &pos, end);
if (res != WLAN_STATUS_SUCCESS) if (res != WLAN_STATUS_SUCCESS)
return res; return res;
} else {
wpabuf_free(sae->tmp->peer_rejected_groups);
sae->tmp->peer_rejected_groups = NULL;
} }
/* Optional Anti-Clogging Token Container element */ /* Optional Anti-Clogging Token Container element */

View file

@ -82,8 +82,6 @@ struct sae_temporary_data {
bool omit_pk_elem; bool omit_pk_elem;
#endif /* CONFIG_TESTING_OPTIONS */ #endif /* CONFIG_TESTING_OPTIONS */
#endif /* CONFIG_SAE_PK */ #endif /* CONFIG_SAE_PK */
struct os_reltime disabled_until;
}; };
struct sae_pt { struct sae_pt {

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-devel" VERSION_STR_POSTFIX GIT_VERSION_STR_POSTFIX
#endif /* VERSION_H */ #endif /* VERSION_H */

View file

@ -1031,6 +1031,9 @@ static int wpa_ft_parse_ftie(const u8 *ie, size_t ie_len,
const u8 *end, *pos; const u8 *end, *pos;
u8 link_id; u8 link_id;
parse->ftie = ie;
parse->ftie_len = ie_len;
pos = opt; pos = opt;
end = ie + ie_len; end = ie + ie_len;
wpa_hexdump(MSG_DEBUG, "FT: Parse FTE subelements", pos, end - pos); wpa_hexdump(MSG_DEBUG, "FT: Parse FTE subelements", pos, end - pos);
@ -1101,7 +1104,7 @@ static int wpa_ft_parse_ftie(const u8 *ie, size_t ie_len,
link_id = pos[2] & 0x0f; link_id = pos[2] & 0x0f;
wpa_printf(MSG_DEBUG, "FT: MLO GTK (Link ID %u)", wpa_printf(MSG_DEBUG, "FT: MLO GTK (Link ID %u)",
link_id); link_id);
if (link_id >= MAX_NUM_MLD_LINKS) if (link_id >= MAX_NUM_MLO_LINKS)
break; break;
parse->valid_mlo_gtks |= BIT(link_id); parse->valid_mlo_gtks |= BIT(link_id);
parse->mlo_gtk[link_id] = pos; parse->mlo_gtk[link_id] = pos;
@ -1116,7 +1119,7 @@ static int wpa_ft_parse_ftie(const u8 *ie, size_t ie_len,
link_id = pos[2 + 6] & 0x0f; link_id = pos[2 + 6] & 0x0f;
wpa_printf(MSG_DEBUG, "FT: MLO IGTK (Link ID %u)", wpa_printf(MSG_DEBUG, "FT: MLO IGTK (Link ID %u)",
link_id); link_id);
if (link_id >= MAX_NUM_MLD_LINKS) if (link_id >= MAX_NUM_MLO_LINKS)
break; break;
parse->valid_mlo_igtks |= BIT(link_id); parse->valid_mlo_igtks |= BIT(link_id);
parse->mlo_igtk[link_id] = pos; parse->mlo_igtk[link_id] = pos;
@ -1131,7 +1134,7 @@ static int wpa_ft_parse_ftie(const u8 *ie, size_t ie_len,
link_id = pos[2 + 6] & 0x0f; link_id = pos[2 + 6] & 0x0f;
wpa_printf(MSG_DEBUG, "FT: MLO BIGTK (Link ID %u)", wpa_printf(MSG_DEBUG, "FT: MLO BIGTK (Link ID %u)",
link_id); link_id);
if (link_id >= MAX_NUM_MLD_LINKS) if (link_id >= MAX_NUM_MLO_LINKS)
break; break;
parse->valid_mlo_bigtks |= BIT(link_id); parse->valid_mlo_bigtks |= BIT(link_id);
parse->mlo_bigtk[link_id] = pos; parse->mlo_bigtk[link_id] = pos;
@ -1336,11 +1339,6 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse,
} }
if (res < 0) if (res < 0)
goto fail; goto fail;
/* FTE might be fragmented. If it is, the separate Fragment
* elements are included in MIC calculation as full elements. */
parse->ftie = fte;
parse->ftie_len = fte_len;
} }
if (prot_ie_count == 0) if (prot_ie_count == 0)
@ -1355,7 +1353,7 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse,
/* TODO: This count should be done based on all _requested_, /* TODO: This count should be done based on all _requested_,
* not _accepted_ links. */ * not _accepted_ links. */
for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) { for (link_id = 0; link_id < MAX_NUM_MLO_LINKS; link_id++) {
if (parse->mlo_gtk[link_id]) { if (parse->mlo_gtk[link_id]) {
if (parse->rsn) if (parse->rsn)
prot_ie_count--; prot_ie_count--;
@ -1890,14 +1888,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 +3438,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)
@ -3561,7 +3551,7 @@ static int wpa_parse_generic(const u8 *pos, struct wpa_eapol_ie_parse *ie)
selector == RSN_KEY_DATA_MLO_GTK) { selector == RSN_KEY_DATA_MLO_GTK) {
link_id = (p[0] & RSN_MLO_GTK_KDE_PREFIX0_LINK_ID_MASK) >> link_id = (p[0] & RSN_MLO_GTK_KDE_PREFIX0_LINK_ID_MASK) >>
RSN_MLO_GTK_KDE_PREFIX0_LINK_ID_SHIFT; RSN_MLO_GTK_KDE_PREFIX0_LINK_ID_SHIFT;
if (link_id >= MAX_NUM_MLD_LINKS) if (link_id >= MAX_NUM_MLO_LINKS)
return 2; return 2;
ie->valid_mlo_gtks |= BIT(link_id); ie->valid_mlo_gtks |= BIT(link_id);
@ -3579,7 +3569,7 @@ static int wpa_parse_generic(const u8 *pos, struct wpa_eapol_ie_parse *ie)
selector == RSN_KEY_DATA_MLO_IGTK) { selector == RSN_KEY_DATA_MLO_IGTK) {
link_id = (p[8] & RSN_MLO_IGTK_KDE_PREFIX8_LINK_ID_MASK) >> link_id = (p[8] & RSN_MLO_IGTK_KDE_PREFIX8_LINK_ID_MASK) >>
RSN_MLO_IGTK_KDE_PREFIX8_LINK_ID_SHIFT; RSN_MLO_IGTK_KDE_PREFIX8_LINK_ID_SHIFT;
if (link_id >= MAX_NUM_MLD_LINKS) if (link_id >= MAX_NUM_MLO_LINKS)
return 2; return 2;
ie->valid_mlo_igtks |= BIT(link_id); ie->valid_mlo_igtks |= BIT(link_id);
@ -3597,7 +3587,7 @@ static int wpa_parse_generic(const u8 *pos, struct wpa_eapol_ie_parse *ie)
selector == RSN_KEY_DATA_MLO_BIGTK) { selector == RSN_KEY_DATA_MLO_BIGTK) {
link_id = (p[8] & RSN_MLO_BIGTK_KDE_PREFIX8_LINK_ID_MASK) >> link_id = (p[8] & RSN_MLO_BIGTK_KDE_PREFIX8_LINK_ID_MASK) >>
RSN_MLO_BIGTK_KDE_PREFIX8_LINK_ID_SHIFT; RSN_MLO_BIGTK_KDE_PREFIX8_LINK_ID_SHIFT;
if (link_id >= MAX_NUM_MLD_LINKS) if (link_id >= MAX_NUM_MLO_LINKS)
return 2; return 2;
ie->valid_mlo_bigtks |= BIT(link_id); ie->valid_mlo_bigtks |= BIT(link_id);
@ -3615,7 +3605,7 @@ static int wpa_parse_generic(const u8 *pos, struct wpa_eapol_ie_parse *ie)
selector == RSN_KEY_DATA_MLO_LINK) { selector == RSN_KEY_DATA_MLO_LINK) {
link_id = (p[0] & RSN_MLO_LINK_KDE_LI_LINK_ID_MASK) >> link_id = (p[0] & RSN_MLO_LINK_KDE_LI_LINK_ID_MASK) >>
RSN_MLO_LINK_KDE_LI_LINK_ID_SHIFT; RSN_MLO_LINK_KDE_LI_LINK_ID_SHIFT;
if (link_id >= MAX_NUM_MLD_LINKS) if (link_id >= MAX_NUM_MLO_LINKS)
return 2; return 2;
ie->valid_mlo_links |= BIT(link_id); ie->valid_mlo_links |= BIT(link_id);
@ -3629,57 +3619,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;
} }
@ -3804,11 +3743,6 @@ int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie)
ie->supp_oper_classes = pos + 2; ie->supp_oper_classes = pos + 2;
ie->supp_oper_classes_len = pos[1]; ie->supp_oper_classes_len = pos[1];
} }
} else if (*pos == WLAN_EID_SSID) {
ie->ssid = pos + 2;
ie->ssid_len = pos[1];
wpa_hexdump_ascii(MSG_DEBUG, "RSN: SSID in EAPOL-Key",
ie->ssid, ie->ssid_len);
} else if (*pos == WLAN_EID_VENDOR_SPECIFIC) { } else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
ret = wpa_parse_generic(pos, ie); ret = wpa_parse_generic(pos, ie);
if (ret == 1) { if (ret == 1) {
@ -4319,24 +4253,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

@ -9,15 +9,12 @@
#ifndef WPA_COMMON_H #ifndef WPA_COMMON_H
#define WPA_COMMON_H #define WPA_COMMON_H
#include "common/defs.h"
/* IEEE 802.11i */ /* IEEE 802.11i */
#define PMKID_LEN 16 #define PMKID_LEN 16
#define PMK_LEN 32 #define PMK_LEN 32
#define PMK_LEN_SUITE_B_192 48 #define PMK_LEN_SUITE_B_192 48
#define PMK_LEN_MAX 64 #define PMK_LEN_MAX 64
#define WPA_REPLAY_COUNTER_LEN 8 #define WPA_REPLAY_COUNTER_LEN 8
#define RSN_PN_LEN 6
#define WPA_NONCE_LEN 32 #define WPA_NONCE_LEN 32
#define WPA_KEY_RSC_LEN 8 #define WPA_KEY_RSC_LEN 8
#define WPA_GMK_LEN 32 #define WPA_GMK_LEN 32
@ -144,7 +141,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)
@ -340,54 +336,52 @@ struct rsn_ie_hdr {
} STRUCT_PACKED; } STRUCT_PACKED;
#define KDE_HDR_LEN (1 + 1 + RSN_SELECTOR_LEN)
struct rsn_error_kde { struct rsn_error_kde {
be16 mui; be16 mui;
be16 error_type; be16 error_type;
} STRUCT_PACKED; } STRUCT_PACKED;
#define WPA_IGTK_KDE_PREFIX_LEN (2 + RSN_PN_LEN) #define WPA_IGTK_KDE_PREFIX_LEN (2 + 6)
struct wpa_igtk_kde { struct wpa_igtk_kde {
u8 keyid[2]; u8 keyid[2];
u8 pn[RSN_PN_LEN]; u8 pn[6];
u8 igtk[WPA_IGTK_MAX_LEN]; u8 igtk[WPA_IGTK_MAX_LEN];
} STRUCT_PACKED; } STRUCT_PACKED;
#define WPA_BIGTK_KDE_PREFIX_LEN (2 + RSN_PN_LEN) #define WPA_BIGTK_KDE_PREFIX_LEN (2 + 6)
struct wpa_bigtk_kde { struct wpa_bigtk_kde {
u8 keyid[2]; u8 keyid[2];
u8 pn[RSN_PN_LEN]; u8 pn[6];
u8 bigtk[WPA_BIGTK_MAX_LEN]; u8 bigtk[WPA_BIGTK_MAX_LEN];
} STRUCT_PACKED; } STRUCT_PACKED;
#define RSN_MLO_GTK_KDE_PREFIX_LENGTH (1 + RSN_PN_LEN) #define RSN_MLO_GTK_KDE_PREFIX_LENGTH (1 + 6)
#define RSN_MLO_GTK_KDE_PREFIX0_KEY_ID_MASK 0x03 #define RSN_MLO_GTK_KDE_PREFIX0_KEY_ID_MASK 0x03
#define RSN_MLO_GTK_KDE_PREFIX0_TX 0x04 #define RSN_MLO_GTK_KDE_PREFIX0_TX 0x04
#define RSN_MLO_GTK_KDE_PREFIX0_LINK_ID_SHIFT 4 #define RSN_MLO_GTK_KDE_PREFIX0_LINK_ID_SHIFT 4
#define RSN_MLO_GTK_KDE_PREFIX0_LINK_ID_MASK 0xF0 #define RSN_MLO_GTK_KDE_PREFIX0_LINK_ID_MASK 0xF0
#define RSN_MLO_IGTK_KDE_PREFIX_LENGTH (2 + RSN_PN_LEN + 1) #define RSN_MLO_IGTK_KDE_PREFIX_LENGTH (2 + 6 + 1)
#define RSN_MLO_IGTK_KDE_PREFIX8_LINK_ID_SHIFT 4 #define RSN_MLO_IGTK_KDE_PREFIX8_LINK_ID_SHIFT 4
#define RSN_MLO_IGTK_KDE_PREFIX8_LINK_ID_MASK 0xF0 #define RSN_MLO_IGTK_KDE_PREFIX8_LINK_ID_MASK 0xF0
struct rsn_mlo_igtk_kde { struct rsn_mlo_igtk_kde {
u8 keyid[2]; u8 keyid[2];
u8 pn[RSN_PN_LEN]; u8 pn[6];
u8 prefix8; u8 prefix8;
u8 igtk[WPA_IGTK_MAX_LEN]; u8 igtk[WPA_IGTK_MAX_LEN];
} STRUCT_PACKED; } STRUCT_PACKED;
#define RSN_MLO_BIGTK_KDE_PREFIX_LENGTH (2 + RSN_PN_LEN + 1) #define RSN_MLO_BIGTK_KDE_PREFIX_LENGTH (2 + 6 + 1)
#define RSN_MLO_BIGTK_KDE_PREFIX8_LINK_ID_SHIFT 4 #define RSN_MLO_BIGTK_KDE_PREFIX8_LINK_ID_SHIFT 4
#define RSN_MLO_BIGTK_KDE_PREFIX8_LINK_ID_MASK 0xF0 #define RSN_MLO_BIGTK_KDE_PREFIX8_LINK_ID_MASK 0xF0
struct rsn_mlo_bigtk_kde { struct rsn_mlo_bigtk_kde {
u8 keyid[2]; u8 keyid[2];
u8 pn[RSN_PN_LEN]; u8 pn[6];
u8 prefix8; u8 prefix8;
u8 bigtk[WPA_BIGTK_MAX_LEN]; u8 bigtk[WPA_BIGTK_MAX_LEN];
} STRUCT_PACKED; } STRUCT_PACKED;
#define RSN_MLO_LINK_KDE_FIXED_LENGTH (1 + ETH_ALEN) #define RSN_MLO_LINK_KDE_FIXED_LENGTH (1 + 6)
#define RSN_MLO_LINK_KDE_LINK_INFO_INDEX 0 #define RSN_MLO_LINK_KDE_LINK_INFO_INDEX 0
#define RSN_MLO_LINK_KDE_LI_LINK_ID_SHIFT 0 #define RSN_MLO_LINK_KDE_LI_LINK_ID_SHIFT 0
#define RSN_MLO_LINK_KDE_LI_LINK_ID_MASK 0x0F #define RSN_MLO_LINK_KDE_LI_LINK_ID_MASK 0x0F
@ -563,6 +557,8 @@ int wpa_compare_rsn_ie(int ft_initial_assoc,
const u8 *ie2, size_t ie2len); const u8 *ie2, size_t ie2len);
int wpa_insert_pmkid(u8 *ies, size_t *ies_len, const u8 *pmkid, bool replace); int wpa_insert_pmkid(u8 *ies, size_t *ies_len, const u8 *pmkid, bool replace);
#define MAX_NUM_MLO_LINKS 15
struct wpa_ft_ies { struct wpa_ft_ies {
const u8 *mdie; const u8 *mdie;
size_t mdie_len; size_t mdie_len;
@ -600,14 +596,14 @@ struct wpa_ft_ies {
const u8 *rsnxe; const u8 *rsnxe;
size_t rsnxe_len; size_t rsnxe_len;
u16 valid_mlo_gtks; /* bitmap of valid link GTK subelements */ u16 valid_mlo_gtks; /* bitmap of valid link GTK subelements */
const u8 *mlo_gtk[MAX_NUM_MLD_LINKS]; const u8 *mlo_gtk[MAX_NUM_MLO_LINKS];
size_t mlo_gtk_len[MAX_NUM_MLD_LINKS]; size_t mlo_gtk_len[MAX_NUM_MLO_LINKS];
u16 valid_mlo_igtks; /* bitmap of valid link IGTK subelements */ u16 valid_mlo_igtks; /* bitmap of valid link IGTK subelements */
const u8 *mlo_igtk[MAX_NUM_MLD_LINKS]; const u8 *mlo_igtk[MAX_NUM_MLO_LINKS];
size_t mlo_igtk_len[MAX_NUM_MLD_LINKS]; size_t mlo_igtk_len[MAX_NUM_MLO_LINKS];
u16 valid_mlo_bigtks; /* bitmap of valid link BIGTK subelements */ u16 valid_mlo_bigtks; /* bitmap of valid link BIGTK subelements */
const u8 *mlo_bigtk[MAX_NUM_MLD_LINKS]; const u8 *mlo_bigtk[MAX_NUM_MLO_LINKS];
size_t mlo_bigtk_len[MAX_NUM_MLD_LINKS]; size_t mlo_bigtk_len[MAX_NUM_MLO_LINKS];
struct wpabuf *fte_buf; struct wpabuf *fte_buf;
}; };
@ -644,14 +640,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);
@ -707,34 +695,22 @@ struct wpa_eapol_ie_parse {
size_t supp_channels_len; size_t supp_channels_len;
const u8 *supp_oper_classes; const u8 *supp_oper_classes;
size_t supp_oper_classes_len; size_t supp_oper_classes_len;
const u8 *ssid;
size_t ssid_len;
u8 qosinfo; u8 qosinfo;
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_MLO_LINKS];
size_t mlo_gtk_len[MAX_NUM_MLD_LINKS]; size_t mlo_gtk_len[MAX_NUM_MLO_LINKS];
u16 valid_mlo_igtks; /* bitmap of valid link IGTK KDEs */ u16 valid_mlo_igtks; /* bitmap of valid link IGTK KDEs */
const u8 *mlo_igtk[MAX_NUM_MLD_LINKS]; const u8 *mlo_igtk[MAX_NUM_MLO_LINKS];
size_t mlo_igtk_len[MAX_NUM_MLD_LINKS]; size_t mlo_igtk_len[MAX_NUM_MLO_LINKS];
u16 valid_mlo_bigtks; /* bitmap of valid link BIGTK KDEs */ u16 valid_mlo_bigtks; /* bitmap of valid link BIGTK KDEs */
const u8 *mlo_bigtk[MAX_NUM_MLD_LINKS]; const u8 *mlo_bigtk[MAX_NUM_MLO_LINKS];
size_t mlo_bigtk_len[MAX_NUM_MLD_LINKS]; size_t mlo_bigtk_len[MAX_NUM_MLO_LINKS];
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_MLO_LINKS];
size_t mlo_link_len[MAX_NUM_MLD_LINKS]; size_t mlo_link_len[MAX_NUM_MLO_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 +782,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 "
@ -417,9 +413,6 @@ extern "C" {
/* parameters: <STA address> <dialog token> <report mode> <beacon report> */ /* parameters: <STA address> <dialog token> <report mode> <beacon report> */
#define BEACON_RESP_RX "BEACON-RESP-RX " #define BEACON_RESP_RX "BEACON-RESP-RX "
/* parameters: <STA address> <dialog token> <link measurement report> */
#define LINK_MSR_RESP_RX "LINK-MSR-RESP-RX "
/* PMKSA cache entry added; parameters: <BSSID> <network_id> */ /* PMKSA cache entry added; parameters: <BSSID> <network_id> */
#define PMKSA_CACHE_ADDED "PMKSA-CACHE-ADDED " #define PMKSA_CACHE_ADDED "PMKSA-CACHE-ADDED "
/* PMKSA cache entry removed; parameters: <BSSID> <network_id> */ /* PMKSA cache entry removed; parameters: <BSSID> <network_id> */

View file

@ -1835,7 +1835,6 @@ int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem,
ret = 0; ret = 0;
fail: fail:
EVP_MAC_CTX_free(ctx); EVP_MAC_CTX_free(ctx);
EVP_MAC_free(emac);
return ret; return ret;
#else /* OpenSSL version >= 3.0 */ #else /* OpenSSL version >= 3.0 */
CMAC_CTX *ctx; CMAC_CTX *ctx;
@ -3933,10 +3932,9 @@ static int openssl_evp_pkey_ec_prime_len(struct crypto_ec_key *key)
group = EC_GROUP_new_by_curve_name(nid); group = EC_GROUP_new_by_curve_name(nid);
prime = BN_new(); prime = BN_new();
if (!group || !prime) if (!group || !prime)
goto fail; return -1;
if (EC_GROUP_get_curve(group, prime, NULL, NULL, NULL) == 1) if (EC_GROUP_get_curve(group, prime, NULL, NULL, NULL) == 1)
prime_len = BN_num_bytes(prime); prime_len = BN_num_bytes(prime);
fail:
EC_GROUP_free(group); EC_GROUP_free(group);
BN_free(prime); BN_free(prime);
return prime_len; return prime_len;
@ -4882,7 +4880,7 @@ hpke_labeled_expand(struct hpke_context *ctx, bool kem, const u8 *prk,
#if OPENSSL_VERSION_NUMBER >= 0x30000000L #if OPENSSL_VERSION_NUMBER >= 0x30000000L
hmac = EVP_MAC_fetch(NULL, "HMAC", NULL); hmac = EVP_MAC_fetch(NULL, "HMAC", NULL);
if (!hmac) if (!hmac)
goto fail; return -1;
params[0] = OSSL_PARAM_construct_utf8_string( params[0] = OSSL_PARAM_construct_utf8_string(
"digest", "digest",
@ -4891,7 +4889,7 @@ hpke_labeled_expand(struct hpke_context *ctx, bool kem, const u8 *prk,
#else /* OpenSSL version >= 3.0 */ #else /* OpenSSL version >= 3.0 */
hctx = HMAC_CTX_new(); hctx = HMAC_CTX_new();
if (!hctx) if (!hctx)
goto fail; return -1;
#endif /* OpenSSL version >= 3.0 */ #endif /* OpenSSL version >= 3.0 */
while (left > 0) { while (left > 0) {
@ -4900,7 +4898,7 @@ hpke_labeled_expand(struct hpke_context *ctx, bool kem, const u8 *prk,
EVP_MAC_CTX_free(hctx); EVP_MAC_CTX_free(hctx);
hctx = EVP_MAC_CTX_new(hmac); hctx = EVP_MAC_CTX_new(hmac);
if (!hctx) if (!hctx)
goto fail; return -1;
if (EVP_MAC_init(hctx, prk, mdlen, params) != 1) if (EVP_MAC_init(hctx, prk, mdlen, params) != 1)
goto fail; goto fail;

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
@ -47,7 +43,6 @@ enum nan_service_protocol_type;
#define HOSTAPD_CHAN_VHT_80MHZ_SUBCHANNEL 0x00000800 #define HOSTAPD_CHAN_VHT_80MHZ_SUBCHANNEL 0x00000800
#define HOSTAPD_CHAN_VHT_160MHZ_SUBCHANNEL 0x00001000 #define HOSTAPD_CHAN_VHT_160MHZ_SUBCHANNEL 0x00001000
#define HOSTAPD_CHAN_EHT_320MHZ_SUBCHANNEL 0x00002000
#define HOSTAPD_CHAN_INDOOR_ONLY 0x00010000 #define HOSTAPD_CHAN_INDOOR_ONLY 0x00010000
#define HOSTAPD_CHAN_GO_CONCURRENT 0x00020000 #define HOSTAPD_CHAN_GO_CONCURRENT 0x00020000
@ -251,11 +246,6 @@ struct hostapd_hw_modes {
*/ */
enum hostapd_hw_mode mode; enum hostapd_hw_mode mode;
/**
* is_6ghz - Whether the mode information is for the 6 GHz band
*/
bool is_6ghz;
/** /**
* num_channels - Number of entries in the channels array * num_channels - Number of entries in the channels array
*/ */
@ -321,27 +311,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
@ -726,14 +695,6 @@ struct wpa_driver_scan_params {
*/ */
unsigned int min_probe_req_content:1; unsigned int min_probe_req_content:1;
/**
* link_id - Specify the link that is requesting the scan on an MLD
*
* This is set when operating as an AP MLD and doing an OBSS scan.
* -1 indicates that no particular link ID is set.
*/
s8 link_id;
/* /*
* NOTE: Whenever adding new parameters here, please make sure * NOTE: Whenever adding new parameters here, please make sure
* wpa_scan_clone_params() and wpa_scan_free_params() get updated with * wpa_scan_clone_params() and wpa_scan_free_params() get updated with
@ -1388,12 +1349,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 {
@ -1417,23 +1372,6 @@ struct wowlan_triggers {
u8 rfkill_release; u8 rfkill_release;
}; };
struct unsol_bcast_probe_resp {
/**
* Unsolicited broadcast Probe Response interval in TUs
*/
unsigned int unsol_bcast_probe_resp_interval;
/**
* Unsolicited broadcast Probe Response template data
*/
u8 *unsol_bcast_probe_resp_tmpl;
/**
* Unsolicited broadcast Probe Response template length
*/
size_t unsol_bcast_probe_resp_tmpl_len;
};
struct wpa_driver_ap_params { struct wpa_driver_ap_params {
/** /**
* head - Beacon head from IEEE 802.11 header to IEs before TIM IE * head - Beacon head from IEEE 802.11 header to IEs before TIM IE
@ -1776,6 +1714,21 @@ struct wpa_driver_ap_params {
*/ */
size_t fd_frame_tmpl_len; size_t fd_frame_tmpl_len;
/**
* Unsolicited broadcast Probe Response interval in TUs
*/
unsigned int unsol_bcast_probe_resp_interval;
/**
* Unsolicited broadcast Probe Response template data
*/
u8 *unsol_bcast_probe_resp_tmpl;
/**
* Unsolicited broadcast Probe Response template length
*/
size_t unsol_bcast_probe_resp_tmpl_len;
/** /**
* mbssid_tx_iface - Transmitting interface of the MBSSID set * mbssid_tx_iface - Transmitting interface of the MBSSID set
*/ */
@ -1842,9 +1795,6 @@ struct wpa_driver_ap_params {
*/ */
u8 **rnr_elem_offset; u8 **rnr_elem_offset;
/* Unsolicited broadcast Probe Response data */
struct unsol_bcast_probe_resp ubpr;
/** /**
* allowed_freqs - List of allowed 20 MHz channel center frequencies in * allowed_freqs - List of allowed 20 MHz channel center frequencies in
* MHz for AP operation. Drivers which support this parameter will * MHz for AP operation. Drivers which support this parameter will
@ -2359,12 +2309,6 @@ struct wpa_driver_capa {
#define WPA_DRIVER_FLAGS2_OWE_OFFLOAD_AP 0x0000000000080000ULL #define WPA_DRIVER_FLAGS2_OWE_OFFLOAD_AP 0x0000000000080000ULL
/** Driver support AP SAE authentication offload */ /** Driver support AP SAE authentication offload */
#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 */
#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) \
@ -2767,7 +2711,6 @@ struct beacon_data {
* @counter_offset_presp: Offset to the count field in probe resp. * @counter_offset_presp: Offset to the count field in probe resp.
* @punct_bitmap - Preamble puncturing bitmap * @punct_bitmap - Preamble puncturing bitmap
* @link_id: Link ID to determine the link for MLD; -1 for non-MLD * @link_id: Link ID to determine the link for MLD; -1 for non-MLD
* @ubpr: Unsolicited broadcast Probe Response frame data
*/ */
struct csa_settings { struct csa_settings {
u8 cs_count; u8 cs_count;
@ -2782,8 +2725,6 @@ struct csa_settings {
u16 punct_bitmap; u16 punct_bitmap;
int link_id; int link_id;
struct unsol_bcast_probe_resp ubpr;
}; };
/** /**
@ -2795,8 +2736,6 @@ struct csa_settings {
* @beacon_after: Next Beacon/Probe Response/(Re)Association Response frame info * @beacon_after: Next Beacon/Probe Response/(Re)Association Response frame info
* @counter_offset_beacon: Offset to the count field in Beacon frame tail * @counter_offset_beacon: Offset to the count field in Beacon frame tail
* @counter_offset_presp: Offset to the count field in Probe Response frame * @counter_offset_presp: Offset to the count field in Probe Response frame
* @ubpr: Unsolicited broadcast Probe Response frame data
* @link_id: If >= 0 indicates the link of the AP MLD to configure
*/ */
struct cca_settings { struct cca_settings {
u8 cca_count; u8 cca_count;
@ -2807,10 +2746,6 @@ struct cca_settings {
u16 counter_offset_beacon; u16 counter_offset_beacon;
u16 counter_offset_presp; u16 counter_offset_presp;
struct unsol_bcast_probe_resp ubpr;
int link_id;
}; };
/* TDLS peer capabilities for send_tdls_mgmt() */ /* TDLS peer capabilities for send_tdls_mgmt() */
@ -3425,17 +3360,6 @@ struct wpa_driver_ops {
int (*update_ft_ies)(void *priv, const u8 *md, const u8 *ies, int (*update_ft_ies)(void *priv, const u8 *md, const u8 *ies,
size_t ies_len); size_t ies_len);
/**
* get_scan_results - Fetch the latest scan results
* @priv: Private driver interface data
* @bssid: Return results only for the specified BSSID, %NULL for all
*
* Returns: Allocated buffer of scan results (caller is responsible for
* freeing the data structure) on success, NULL on failure
*/
struct wpa_scan_results * (*get_scan_results)(void *priv,
const u8 *bssid);
/** /**
* get_scan_results2 - Fetch the latest scan results * get_scan_results2 - Fetch the latest scan results
* @priv: private driver interface data * @priv: private driver interface data
@ -3637,15 +3561,13 @@ struct wpa_driver_ops {
/** /**
* flush - Flush all association stations (AP only) * flush - Flush all association stations (AP only)
* @priv: Private driver interface data * @priv: Private driver interface data
* @link_id: In case of MLO, valid link ID on which all associated
* stations will be flushed, -1 otherwise.
* Returns: 0 on success, -1 on failure * Returns: 0 on success, -1 on failure
* *
* This function requests the driver to disassociate all associated * This function requests the driver to disassociate all associated
* stations. This function does not need to be implemented if the * stations. This function does not need to be implemented if the
* driver does not process association frames internally. * driver does not process association frames internally.
*/ */
int (*flush)(void *priv, int link_id); int (*flush)(void *priv);
/** /**
* set_generic_elem - Add IEs into Beacon/Probe Response frames (AP) * set_generic_elem - Add IEs into Beacon/Probe Response frames (AP)
@ -4622,14 +4544,13 @@ struct wpa_driver_ops {
/** /**
* stop_ap - Removes beacon from AP * stop_ap - Removes beacon from AP
* @priv: Private driver interface data * @priv: Private driver interface data
* @link_id: Link ID of the specified link; -1 for non-MLD
* Returns: 0 on success, -1 on failure (or if not supported) * Returns: 0 on success, -1 on failure (or if not supported)
* *
* This optional function can be used to disable AP mode related * This optional function can be used to disable AP mode related
* configuration. Unlike deinit_ap, it does not change to station * configuration. Unlike deinit_ap, it does not change to station
* mode. * mode.
*/ */
int (*stop_ap)(void *priv, int link_id); int (*stop_ap)(void *priv);
/** /**
* get_survey - Retrieve survey data * get_survey - Retrieve survey data
@ -5209,137 +5130,15 @@ struct wpa_driver_ops {
* @priv: Private driver interface data * @priv: Private driver interface data
* @link_id: The link ID * @link_id: The link ID
* @addr: The MAC address to use for the link * @addr: The MAC address to use for the link
* @bss_ctx: BSS context for %WPA_IF_AP_BSS interfaces
* Returns: 0 on success, negative value on failure * Returns: 0 on success, negative value on failure
*/ */
int (*link_add)(void *priv, u8 link_id, const u8 *addr, void *bss_ctx); int (*link_add)(void *priv, u8 link_id, const u8 *addr);
/**
* link_remove - Remove a link from the AP MLD interface
* @priv: Private driver interface data
* @type: Interface type
* @ifname: Interface name of the virtual interface from where the link
* is to be removed.
* @link_id: Valid link ID to remove
* Returns: 0 on success, -1 on failure
*/
int (*link_remove)(void *priv, enum wpa_driver_if_type type,
const char *ifname, u8 link_id);
/**
* is_drv_shared - Check whether the driver interface is shared
* @priv: Private driver interface data from init()
* @link_id: Link ID to match
* Returns: true if it is being used or else false.
*
* Checks whether the driver interface is being used by other partner
* BSS(s) or not. This is used to decide whether the driver interface
* needs to be deinitilized when one interface is getting deinitialized.
*
* NOTE: @link_id will be used only when there is only one BSS
* 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);
/**
* link_sta_remove - Remove a link STA from an MLD STA
* @priv: Private driver interface data
* @link_id: The link ID which the link STA is using
* @addr: The MLD MAC address of the MLD STA
* Returns: 0 on success, negative value on failure
*/
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 +5766,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,
}; };
@ -6498,14 +6292,6 @@ union wpa_event_data {
*/ */
void *drv_priv; void *drv_priv;
/**
* ctx - Pointer to store ctx of private BSS information
*
* If not set to NULL, this is used for forwarding the packet
* to right link BSS of ML BSS.
*/
void *ctx;
/** /**
* freq - Frequency (in MHz) on which the frame was received * freq - Frequency (in MHz) on which the frame was received
*/ */
@ -6556,8 +6342,6 @@ union wpa_event_data {
* (if available). * (if available).
* @scan_start_tsf_bssid: The BSSID according to which %scan_start_tsf * @scan_start_tsf_bssid: The BSSID according to which %scan_start_tsf
* is set. * is set.
* @scan_cookie: Unique identification representing the corresponding
* scan request. 0 if no unique identification is available.
*/ */
struct scan_info { struct scan_info {
int aborted; int aborted;
@ -6569,7 +6353,6 @@ union wpa_event_data {
int nl_scan_event; int nl_scan_event;
u64 scan_start_tsf; u64 scan_start_tsf;
u8 scan_start_tsf_bssid[ETH_ALEN]; u8 scan_start_tsf_bssid[ETH_ALEN];
u64 scan_cookie;
} scan_info; } scan_info;
/** /**
@ -6926,7 +6709,6 @@ union wpa_event_data {
*/ */
struct bss_color_collision { struct bss_color_collision {
u64 bitmap; u64 bitmap;
int link_id;
} bss_color_collision; } bss_color_collision;
/** /**

View file

@ -632,7 +632,7 @@ atheros_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx,
static int static int
atheros_flush(void *priv, int link_id) atheros_flush(void *priv)
{ {
u8 allsta[IEEE80211_ADDR_LEN]; u8 allsta[IEEE80211_ADDR_LEN];
os_memset(allsta, 0xff, IEEE80211_ADDR_LEN); os_memset(allsta, 0xff, IEEE80211_ADDR_LEN);

View file

@ -946,7 +946,7 @@ bsd_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx,
static int static int
bsd_flush(void *priv, int link_id) bsd_flush(void *priv)
{ {
u8 allsta[IEEE80211_ADDR_LEN]; u8 allsta[IEEE80211_ADDR_LEN];

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

@ -572,7 +572,7 @@ static int hostap_set_ssid(void *priv, const u8 *buf, int len)
} }
static int hostap_flush(void *priv, int link_id) static int hostap_flush(void *priv)
{ {
struct hostap_driver_data *drv = priv; struct hostap_driver_data *drv = priv;
struct prism2_hostapd_param param; struct prism2_hostapd_param param;

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

File diff suppressed because it is too large Load diff

View file

@ -55,6 +55,7 @@ struct nl80211_wiphy_data {
struct i802_link { struct i802_link {
unsigned int beacon_set:1; unsigned int beacon_set:1;
s8 link_id;
int freq; int freq;
int bandwidth; int bandwidth;
u8 addr[ETH_ALEN]; u8 addr[ETH_ALEN];
@ -65,9 +66,9 @@ struct i802_bss {
struct wpa_driver_nl80211_data *drv; struct wpa_driver_nl80211_data *drv;
struct i802_bss *next; struct i802_bss *next;
u16 valid_links; size_t n_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 +201,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,20 +353,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)
{
if (link_id < 0 || link_id >= MAX_NUM_MLD_LINKS)
return false;
if (links & BIT(link_id))
return true;
return false;
}
static inline bool static inline bool
nl80211_attr_supported(struct wpa_driver_nl80211_data *drv, unsigned int attr) nl80211_attr_supported(struct wpa_driver_nl80211_data *drv, unsigned int attr)
@ -405,14 +391,11 @@ int wpa_driver_nl80211_scan(struct i802_bss *bss,
int wpa_driver_nl80211_sched_scan(void *priv, int wpa_driver_nl80211_sched_scan(void *priv,
struct wpa_driver_scan_params *params); struct wpa_driver_scan_params *params);
int wpa_driver_nl80211_stop_sched_scan(void *priv); int wpa_driver_nl80211_stop_sched_scan(void *priv);
struct wpa_scan_results * wpa_driver_nl80211_get_scan_results(void *priv, struct wpa_scan_results * wpa_driver_nl80211_get_scan_results(void *priv);
const u8 *bssid);
void nl80211_dump_scan(struct wpa_driver_nl80211_data *drv); void nl80211_dump_scan(struct wpa_driver_nl80211_data *drv);
int wpa_driver_nl80211_abort_scan(void *priv, u64 scan_cookie); 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

@ -889,10 +889,6 @@ static void wiphy_info_extended_capab(struct wpa_driver_nl80211_data *drv,
nla_get_u16(tb1[NL80211_ATTR_MLD_CAPA_AND_OPS]); nla_get_u16(tb1[NL80211_ATTR_MLD_CAPA_AND_OPS]);
} }
wpa_printf(MSG_DEBUG,
"nl80211: EML Capability: 0x%x MLD Capability: 0x%x",
capa->eml_capa, capa->mld_capa_and_ops);
drv->num_iface_capa++; drv->num_iface_capa++;
if (drv->num_iface_capa == NL80211_IFTYPE_MAX) if (drv->num_iface_capa == NL80211_IFTYPE_MAX)
break; break;
@ -1120,9 +1116,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
@ -1444,14 +1437,6 @@ static void qca_nl80211_get_features(struct wpa_driver_nl80211_data *drv)
if (check_feature(QCA_WLAN_VENDOR_FEATURE_AP_ALLOWED_FREQ_LIST, if (check_feature(QCA_WLAN_VENDOR_FEATURE_AP_ALLOWED_FREQ_LIST,
&info)) &info))
drv->qca_ap_allowed_freqs = 1; drv->qca_ap_allowed_freqs = 1;
if (check_feature(QCA_WLAN_VENDOR_FEATURE_HT_VHT_TWT_RESPONDER, &info))
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 +1464,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 +1479,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 |=
@ -2173,9 +2156,6 @@ wpa_driver_nl80211_postprocess_modes(struct hostapd_hw_modes *modes,
for (m = 0; m < *num_modes; m++) { for (m = 0; m < *num_modes; m++) {
if (!modes[m].num_channels) if (!modes[m].num_channels)
continue; continue;
modes[m].is_6ghz = false;
if (modes[m].channels[0].freq < 2000) { if (modes[m].channels[0].freq < 2000) {
modes[m].num_channels = 0; modes[m].num_channels = 0;
continue; continue;
@ -2187,14 +2167,10 @@ wpa_driver_nl80211_postprocess_modes(struct hostapd_hw_modes *modes,
break; break;
} }
} }
} else if (modes[m].channels[0].freq > 50000) { } else if (modes[m].channels[0].freq > 50000)
modes[m].mode = HOSTAPD_MODE_IEEE80211AD; modes[m].mode = HOSTAPD_MODE_IEEE80211AD;
} else if (is_6ghz_freq(modes[m].channels[0].freq)) { else
modes[m].mode = HOSTAPD_MODE_IEEE80211A; modes[m].mode = HOSTAPD_MODE_IEEE80211A;
modes[m].is_6ghz = true;
} else {
modes[m].mode = HOSTAPD_MODE_IEEE80211A;
}
} }
/* Remove unsupported bands */ /* Remove unsupported bands */
@ -2422,57 +2398,6 @@ static void nl80211_reg_rule_vht(struct nlattr *tb[],
} }
static void nl80211_set_6ghz_mode(struct hostapd_hw_modes *mode, int start,
int end, int max_bw)
{
int c;
for (c = 0; c < mode->num_channels; c++) {
struct hostapd_channel_data *chan = &mode->channels[c];
if (chan->freq - 10 < start || chan->freq + 10 > end)
continue;
if (max_bw >= 80)
chan->flag |= HOSTAPD_CHAN_VHT_80MHZ_SUBCHANNEL;
if (max_bw >= 160)
chan->flag |= HOSTAPD_CHAN_VHT_160MHZ_SUBCHANNEL;
if (max_bw >= 320)
chan->flag |= HOSTAPD_CHAN_EHT_320MHZ_SUBCHANNEL;
}
}
static void nl80211_reg_rule_6ghz(struct nlattr *tb[],
struct phy_info_arg *results)
{
u32 start, end, max_bw;
u16 m;
if (!tb[NL80211_ATTR_FREQ_RANGE_START] ||
!tb[NL80211_ATTR_FREQ_RANGE_END] ||
!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
return;
start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
if (max_bw < 80)
return;
for (m = 0; m < *results->num_modes; m++) {
if (results->modes[m].num_channels == 0 ||
!is_6ghz_freq(results->modes[m].channels[0].freq))
continue;
nl80211_set_6ghz_mode(&results->modes[m], start, end, max_bw);
}
}
static void nl80211_set_dfs_domain(enum nl80211_dfs_regions region, static void nl80211_set_dfs_domain(enum nl80211_dfs_regions region,
u8 *dfs_domain) u8 *dfs_domain)
{ {
@ -2591,13 +2516,6 @@ static int nl80211_get_reg(struct nl_msg *msg, void *arg)
nl80211_reg_rule_vht(tb_rule, results); nl80211_reg_rule_vht(tb_rule, results);
} }
nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
{
nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
nla_data(nl_rule), nla_len(nl_rule), reg_policy);
nl80211_reg_rule_6ghz(tb_rule, results);
}
return NL_SKIP; return NL_SKIP;
} }
@ -2739,133 +2657,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

@ -22,7 +22,7 @@
static void static void
nl80211_control_port_frame_tx_status(struct i802_bss *bss, nl80211_control_port_frame_tx_status(struct wpa_driver_nl80211_data *drv,
const u8 *frame, size_t len, const u8 *frame, size_t len,
struct nlattr *ack, struct nlattr *cookie); struct nlattr *ack, struct nlattr *cookie);
@ -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
@ -478,7 +477,10 @@ static void qca_nl80211_link_reconfig_event(struct wpa_driver_nl80211_data *drv,
* links when the link used for (re)association is removed. * links when the link used for (re)association is removed.
*/ */
if (removed_links & BIT(drv->sta_mlo_info.assoc_link_id)) { if (removed_links & BIT(drv->sta_mlo_info.assoc_link_id)) {
for_each_link(drv->sta_mlo_info.valid_links, i) { for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
if (!(drv->sta_mlo_info.valid_links & BIT(i)))
continue;
os_memcpy(drv->bssid, drv->sta_mlo_info.links[i].bssid, os_memcpy(drv->bssid, drv->sta_mlo_info.links[i].bssid,
ETH_ALEN); ETH_ALEN);
drv->sta_mlo_info.assoc_link_id = i; drv->sta_mlo_info.assoc_link_id = i;
@ -700,7 +702,10 @@ static int nl80211_update_rejected_links_info(struct driver_sta_mlo_info *mlo,
} }
/* Get MLO links info for rejected links */ /* Get MLO links info for rejected links */
for_each_link((mlo->req_links & ~mlo->valid_links), i) { for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
if (!((mlo->req_links & ~mlo->valid_links) & BIT(i)))
continue;
os_memcpy(mlo->links[i].bssid, resp_info.addr[i], ETH_ALEN); os_memcpy(mlo->links[i].bssid, resp_info.addr[i], ETH_ALEN);
os_memcpy(mlo->links[i].addr, req_info.addr[i], ETH_ALEN); os_memcpy(mlo->links[i].addr, req_info.addr[i], ETH_ALEN);
} }
@ -870,7 +875,9 @@ qca_nl80211_tid_to_link_map_event(struct wpa_driver_nl80211_data *drv,
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"nl80211: TID-to-link: Received uplink %x downlink %x", "nl80211: TID-to-link: Received uplink %x downlink %x",
uplink, downlink); uplink, downlink);
for_each_link(drv->sta_mlo_info.valid_links, i) { for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
if (!(drv->sta_mlo_info.valid_links & BIT(i)))
continue;
if (uplink & BIT(i)) if (uplink & BIT(i))
event.t2l_map_info.t2lmap[i].uplink |= event.t2l_map_info.t2lmap[i].uplink |=
BIT(tidnum); BIT(tidnum);
@ -1205,6 +1212,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 +1226,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,31 +1268,13 @@ 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 (finished)
data.ch_switch.link_id = nla_get_u8(link);
wpa_printf(MSG_DEBUG, "nl80211: Link ID: %d",
data.ch_switch.link_id);
} else {
data.ch_switch.link_id = NL80211_DRV_LINK_ID_NA;
}
if (finished) {
if (data.ch_switch.link_id != NL80211_DRV_LINK_ID_NA) {
struct i802_link *mld_link;
mld_link = nl80211_get_link(bss,
data.ch_switch.link_id);
mld_link->freq = data.ch_switch.freq;
if (bw)
mld_link->bandwidth = channel_width_to_int(
data.ch_switch.ch_width);
} else {
bss->flink->freq = data.ch_switch.freq; bss->flink->freq = data.ch_switch.freq;
if (bw)
bss->flink->bandwidth = channel_width_to_int( if (link)
data.ch_switch.ch_width); data.ch_switch.link_id = nla_get_u8(link);
} else
} data.ch_switch.link_id = NL80211_DRV_LINK_ID_NA;
if (link && is_sta_interface(drv->nlmode)) { if (link && is_sta_interface(drv->nlmode)) {
u8 link_id = data.ch_switch.link_id; u8 link_id = data.ch_switch.link_id;
@ -1304,14 +1293,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 ?
@ -1385,20 +1366,18 @@ static void mlme_event_mgmt(struct i802_bss *bss,
event.rx_mgmt.frame_len = len; event.rx_mgmt.frame_len = len;
event.rx_mgmt.ssi_signal = ssi_signal; event.rx_mgmt.ssi_signal = ssi_signal;
event.rx_mgmt.drv_priv = bss; event.rx_mgmt.drv_priv = bss;
event.rx_mgmt.ctx = bss->ctx;
event.rx_mgmt.link_id = link_id; event.rx_mgmt.link_id = link_id;
wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event); wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
} }
static void mlme_event_mgmt_tx_status(struct i802_bss *bss, static void mlme_event_mgmt_tx_status(struct wpa_driver_nl80211_data *drv,
struct nlattr *cookie, const u8 *frame, struct nlattr *cookie, const u8 *frame,
size_t len, struct nlattr *ack) size_t len, struct nlattr *ack)
{ {
union wpa_event_data event; union wpa_event_data event;
const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *) frame; const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *) frame;
struct wpa_driver_nl80211_data *drv = bss->drv;
u16 fc = le_to_host16(hdr->frame_control); u16 fc = le_to_host16(hdr->frame_control);
u64 cookie_val = 0; u64 cookie_val = 0;
@ -1417,7 +1396,7 @@ static void mlme_event_mgmt_tx_status(struct i802_bss *bss,
WPA_GET_BE16(frame + 2 * ETH_ALEN) == ETH_P_PAE) { WPA_GET_BE16(frame + 2 * ETH_ALEN) == ETH_P_PAE) {
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"nl80211: Work around misdelivered control port TX status for EAPOL"); "nl80211: Work around misdelivered control port TX status for EAPOL");
nl80211_control_port_frame_tx_status(bss, frame, len, ack, nl80211_control_port_frame_tx_status(drv, frame, len, ack,
cookie); cookie);
return; return;
} }
@ -1453,7 +1432,7 @@ static void mlme_event_mgmt_tx_status(struct i802_bss *bss,
event.tx_status.ack = ack != NULL; event.tx_status.ack = ack != NULL;
event.tx_status.link_id = cookie_val == drv->send_frame_cookie ? event.tx_status.link_id = cookie_val == drv->send_frame_cookie ?
drv->send_frame_link_id : NL80211_DRV_LINK_ID_NA; drv->send_frame_link_id : NL80211_DRV_LINK_ID_NA;
wpa_supplicant_event(bss->ctx, EVENT_TX_STATUS, &event); wpa_supplicant_event(drv->ctx, EVENT_TX_STATUS, &event);
} }
@ -1639,17 +1618,18 @@ static void mlme_event_unprot_beacon(struct wpa_driver_nl80211_data *drv,
} }
static s8 static struct i802_link *
nl80211_get_link_id_by_freq(struct i802_bss *bss, unsigned int freq) nl80211_get_mld_link_by_freq(struct i802_bss *bss, unsigned int freq)
{ {
unsigned int i; unsigned int i;
for_each_link(bss->valid_links, i) { for (i = 0; i < bss->n_links; i++) {
if ((unsigned int) bss->links[i].freq == freq) if ((unsigned int) bss->links[i].freq == freq &&
return i; bss->links[i].link_id != -1)
return &bss->links[i];
} }
return NL80211_DRV_LINK_ID_NA; return NULL;
} }
@ -1683,12 +1663,12 @@ static void mlme_event(struct i802_bss *bss,
/* Determine the MLD link either by an explicitly provided link id or /* Determine the MLD link either by an explicitly provided link id or
* finding a match based on the frequency. */ * finding a match based on the frequency. */
if (link) if (link)
link_id = nla_get_u8(link); mld_link = nl80211_get_link(bss, nla_get_u8(link));
else if (freq) else if (freq)
link_id = nl80211_get_link_id_by_freq(bss, nla_get_u32(freq)); mld_link = nl80211_get_mld_link_by_freq(bss, nla_get_u32(freq));
if (nl80211_link_valid(bss->valid_links, link_id)) if (mld_link)
mld_link = nl80211_get_link(bss, link_id); link_id = mld_link->link_id;
data = nla_data(frame); data = nla_data(frame);
len = nla_len(frame); len = nla_len(frame);
@ -1761,7 +1741,7 @@ static void mlme_event(struct i802_bss *bss,
nla_len(frame), link_id); nla_len(frame), link_id);
break; break;
case NL80211_CMD_FRAME_TX_STATUS: case NL80211_CMD_FRAME_TX_STATUS:
mlme_event_mgmt_tx_status(bss, cookie, nla_data(frame), mlme_event_mgmt_tx_status(drv, cookie, nla_data(frame),
nla_len(frame), ack); nla_len(frame), ack);
break; break;
case NL80211_CMD_UNPROT_DEAUTHENTICATE: case NL80211_CMD_UNPROT_DEAUTHENTICATE:
@ -1940,7 +1920,7 @@ static void mlme_event_dh_event(struct wpa_driver_nl80211_data *drv,
os_memset(&data, 0, sizeof(data)); os_memset(&data, 0, sizeof(data));
addr = nla_data(tb[NL80211_ATTR_MAC]); addr = nla_data(tb[NL80211_ATTR_MAC]);
if (!bss->valid_links && if (bss->links[0].link_id == NL80211_DRV_LINK_ID_NA &&
(tb[NL80211_ATTR_MLO_LINK_ID] || (tb[NL80211_ATTR_MLO_LINK_ID] ||
tb[NL80211_ATTR_MLD_ADDR])) { tb[NL80211_ATTR_MLD_ADDR])) {
wpa_printf(MSG_ERROR, wpa_printf(MSG_ERROR,
@ -1977,10 +1957,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 +1967,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 +2030,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 +2071,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;
} }
@ -2224,7 +2184,7 @@ static void nl80211_new_station_event(struct wpa_driver_nl80211_data *drv,
u8 *req_ies = NULL, *resp_ies = NULL; u8 *req_ies = NULL, *resp_ies = NULL;
size_t req_ies_len = 0, resp_ies_len = 0; size_t req_ies_len = 0, resp_ies_len = 0;
if (!bss->valid_links && if (bss->links[0].link_id == NL80211_DRV_LINK_ID_NA &&
(tb[NL80211_ATTR_MLO_LINK_ID] || (tb[NL80211_ATTR_MLO_LINK_ID] ||
tb[NL80211_ATTR_MLD_ADDR])) { tb[NL80211_ATTR_MLD_ADDR])) {
wpa_printf(MSG_ERROR, wpa_printf(MSG_ERROR,
@ -2443,33 +2403,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);
} }
@ -2515,6 +2452,7 @@ static void nl80211_radar_event(struct wpa_driver_nl80211_data *drv,
{ {
union wpa_event_data data; union wpa_event_data data;
enum nl80211_radar_event event_type; enum nl80211_radar_event event_type;
struct i802_link *mld_link = NULL;
if (!tb[NL80211_ATTR_WIPHY_FREQ] || !tb[NL80211_ATTR_RADAR_EVENT]) if (!tb[NL80211_ATTR_WIPHY_FREQ] || !tb[NL80211_ATTR_RADAR_EVENT])
return; return;
@ -2524,13 +2462,11 @@ static void nl80211_radar_event(struct wpa_driver_nl80211_data *drv,
data.dfs_event.freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]); data.dfs_event.freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
event_type = nla_get_u32(tb[NL80211_ATTR_RADAR_EVENT]); event_type = nla_get_u32(tb[NL80211_ATTR_RADAR_EVENT]);
if (tb[NL80211_ATTR_MLO_LINK_ID]) { if (data.dfs_event.freq) {
data.dfs_event.link_id = mld_link = nl80211_get_mld_link_by_freq(drv->first_bss,
nla_get_u8(tb[NL80211_ATTR_MLO_LINK_ID]);
} else if (data.dfs_event.freq) {
data.dfs_event.link_id =
nl80211_get_link_id_by_freq(drv->first_bss,
data.dfs_event.freq); data.dfs_event.freq);
if (mld_link)
data.dfs_event.link_id = mld_link->link_id;
} }
/* Check HT params */ /* Check HT params */
@ -2896,6 +2832,7 @@ static void qca_nl80211_dfs_offload_radar_event(
{ {
union wpa_event_data data; union wpa_event_data data;
struct nlattr *tb[NL80211_ATTR_MAX + 1]; struct nlattr *tb[NL80211_ATTR_MAX + 1];
struct i802_link *mld_link = NULL;
wpa_printf(MSG_DEBUG, wpa_printf(MSG_DEBUG,
"nl80211: DFS offload radar vendor event received"); "nl80211: DFS offload radar vendor event received");
@ -2914,13 +2851,11 @@ static void qca_nl80211_dfs_offload_radar_event(
data.dfs_event.freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]); data.dfs_event.freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
data.dfs_event.link_id = NL80211_DRV_LINK_ID_NA; data.dfs_event.link_id = NL80211_DRV_LINK_ID_NA;
if (tb[NL80211_ATTR_MLO_LINK_ID]) { if (data.dfs_event.freq) {
data.dfs_event.link_id = mld_link = nl80211_get_mld_link_by_freq(drv->first_bss,
nla_get_u8(tb[NL80211_ATTR_MLO_LINK_ID]);
} else if (data.dfs_event.freq) {
data.dfs_event.link_id =
nl80211_get_link_id_by_freq(drv->first_bss,
data.dfs_event.freq); data.dfs_event.freq);
if (mld_link)
data.dfs_event.link_id = mld_link->link_id;
} }
wpa_printf(MSG_DEBUG, "nl80211: DFS event on freq %d MHz, link=%d", wpa_printf(MSG_DEBUG, "nl80211: DFS event on freq %d MHz, link=%d",
@ -3032,7 +2967,6 @@ static void send_vendor_scan_event(struct wpa_driver_nl80211_data *drv,
info = &event.scan_info; info = &event.scan_info;
info->aborted = aborted; info->aborted = aborted;
info->external_scan = external_scan; info->external_scan = external_scan;
info->scan_cookie = nla_get_u64(tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE]);
if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS]) { if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS]) {
nla_for_each_nested(nl, nla_for_each_nested(nl,
@ -3110,7 +3044,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;
} }
@ -3721,7 +3655,8 @@ static void nl80211_sta_opmode_change_event(struct wpa_driver_nl80211_data *drv,
} }
static void nl80211_control_port_frame(struct i802_bss *bss, struct nlattr **tb) static void nl80211_control_port_frame(struct wpa_driver_nl80211_data *drv,
struct nlattr **tb)
{ {
u8 *src_addr; u8 *src_addr;
u16 ethertype; u16 ethertype;
@ -3750,7 +3685,7 @@ static void nl80211_control_port_frame(struct i802_bss *bss, struct nlattr **tb)
MAC2STR(src_addr)); MAC2STR(src_addr));
break; break;
case ETH_P_PAE: case ETH_P_PAE:
drv_event_eapol_rx2(bss->ctx, src_addr, drv_event_eapol_rx2(drv->ctx, src_addr,
nla_data(tb[NL80211_ATTR_FRAME]), nla_data(tb[NL80211_ATTR_FRAME]),
nla_len(tb[NL80211_ATTR_FRAME]), nla_len(tb[NL80211_ATTR_FRAME]),
encrypted, link_id); encrypted, link_id);
@ -3766,11 +3701,10 @@ static void nl80211_control_port_frame(struct i802_bss *bss, struct nlattr **tb)
static void static void
nl80211_control_port_frame_tx_status(struct i802_bss *bss, nl80211_control_port_frame_tx_status(struct wpa_driver_nl80211_data *drv,
const u8 *frame, size_t len, const u8 *frame, size_t len,
struct nlattr *ack, struct nlattr *cookie) struct nlattr *ack, struct nlattr *cookie)
{ {
struct wpa_driver_nl80211_data *drv = bss->drv;
union wpa_event_data event; union wpa_event_data event;
if (!cookie || len < ETH_HLEN) if (!cookie || len < ETH_HLEN)
@ -3789,7 +3723,7 @@ nl80211_control_port_frame_tx_status(struct i802_bss *bss,
nla_get_u64(cookie) == drv->eapol_tx_cookie ? nla_get_u64(cookie) == drv->eapol_tx_cookie ?
drv->eapol_tx_link_id : NL80211_DRV_LINK_ID_NA; drv->eapol_tx_link_id : NL80211_DRV_LINK_ID_NA;
wpa_supplicant_event(bss->ctx, EVENT_EAPOL_TX_STATUS, &event); wpa_supplicant_event(drv->ctx, EVENT_EAPOL_TX_STATUS, &event);
} }
@ -3815,11 +3749,8 @@ static void nl80211_frame_wait_cancel(struct wpa_driver_nl80211_data *drv,
(long long unsigned int) cookie, (long long unsigned int) cookie,
match ? " (match)" : "", match ? " (match)" : "",
drv->send_frame_cookie == cookie ? " (match-saved)" : ""); drv->send_frame_cookie == cookie ? " (match-saved)" : "");
if (drv->send_frame_cookie == cookie) { if (drv->send_frame_cookie == cookie)
drv->send_frame_cookie = (u64) -1; drv->send_frame_cookie = (u64) -1;
if (!match)
goto send_event;
}
if (!match) if (!match)
return; return;
@ -3829,7 +3760,6 @@ static void nl80211_frame_wait_cancel(struct wpa_driver_nl80211_data *drv,
(drv->num_send_frame_cookies - i - 1) * sizeof(u64)); (drv->num_send_frame_cookies - i - 1) * sizeof(u64));
drv->num_send_frame_cookies--; drv->num_send_frame_cookies--;
send_event:
wpa_supplicant_event(drv->ctx, EVENT_TX_WAIT_EXPIRE, NULL); wpa_supplicant_event(drv->ctx, EVENT_TX_WAIT_EXPIRE, NULL);
} }
@ -3847,62 +3777,48 @@ static void nl80211_assoc_comeback(struct wpa_driver_nl80211_data *drv,
#ifdef CONFIG_IEEE80211AX #ifdef CONFIG_IEEE80211AX
static void nl80211_obss_color_event(struct i802_bss *bss, static void nl80211_obss_color_collision(struct i802_bss *bss,
enum nl80211_commands cmd,
struct nlattr *tb[]) struct nlattr *tb[])
{ {
union wpa_event_data data; union wpa_event_data data;
enum wpa_event_type event_type;
os_memset(&data, 0, sizeof(data));
data.bss_color_collision.link_id = NL80211_DRV_LINK_ID_NA;
switch (cmd) {
case NL80211_CMD_OBSS_COLOR_COLLISION:
event_type = EVENT_BSS_COLOR_COLLISION;
if (!tb[NL80211_ATTR_OBSS_COLOR_BITMAP]) if (!tb[NL80211_ATTR_OBSS_COLOR_BITMAP])
return; return;
os_memset(&data, 0, sizeof(data));
data.bss_color_collision.bitmap = data.bss_color_collision.bitmap =
nla_get_u64(tb[NL80211_ATTR_OBSS_COLOR_BITMAP]); nla_get_u64(tb[NL80211_ATTR_OBSS_COLOR_BITMAP]);
wpa_printf(MSG_DEBUG,
"nl80211: BSS color collision - bitmap %08llx", wpa_printf(MSG_DEBUG, "nl80211: BSS color collision - bitmap %08llx",
(long long unsigned int) (long long unsigned int) data.bss_color_collision.bitmap);
data.bss_color_collision.bitmap); wpa_supplicant_event(bss->ctx, EVENT_BSS_COLOR_COLLISION, &data);
break; }
case NL80211_CMD_COLOR_CHANGE_STARTED:
event_type = EVENT_CCA_STARTED_NOTIFY;
static void nl80211_color_change_announcement_started(struct i802_bss *bss)
{
union wpa_event_data data = {};
wpa_printf(MSG_DEBUG, "nl80211: CCA started"); wpa_printf(MSG_DEBUG, "nl80211: CCA started");
break; wpa_supplicant_event(bss->ctx, EVENT_CCA_STARTED_NOTIFY, &data);
case NL80211_CMD_COLOR_CHANGE_ABORTED: }
event_type = EVENT_CCA_ABORTED_NOTIFY;
static void nl80211_color_change_announcement_aborted(struct i802_bss *bss)
{
union wpa_event_data data = {};
wpa_printf(MSG_DEBUG, "nl80211: CCA aborted"); wpa_printf(MSG_DEBUG, "nl80211: CCA aborted");
break; wpa_supplicant_event(bss->ctx, EVENT_CCA_ABORTED_NOTIFY, &data);
case NL80211_CMD_COLOR_CHANGE_COMPLETED: }
event_type = EVENT_CCA_NOTIFY;
static void nl80211_color_change_announcement_completed(struct i802_bss *bss)
{
union wpa_event_data data = {};
wpa_printf(MSG_DEBUG, "nl80211: CCA completed"); wpa_printf(MSG_DEBUG, "nl80211: CCA completed");
break; wpa_supplicant_event(bss->ctx, EVENT_CCA_NOTIFY, &data);
default:
wpa_printf(MSG_DEBUG, "nl80211: Unknown CCA command %d", cmd);
return;
}
if (tb[NL80211_ATTR_MLO_LINK_ID]) {
data.bss_color_collision.link_id =
nla_get_u8(tb[NL80211_ATTR_MLO_LINK_ID]);
if (!nl80211_link_valid(bss->valid_links,
data.bss_color_collision.link_id)) {
wpa_printf(MSG_DEBUG,
"nl80211: Invalid BSS color event link ID %d",
data.bss_color_collision.link_id);
return;
}
wpa_printf(MSG_DEBUG, "nl80211: BSS color event - Link ID %d",
data.bss_color_collision.link_id);
}
wpa_supplicant_event(bss->ctx, event_type, &data);
} }
#endif /* CONFIG_IEEE80211AX */ #endif /* CONFIG_IEEE80211AX */
@ -3949,7 +3865,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 +3877,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 +3919,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 +4002,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 +4039,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);
@ -4148,7 +4064,7 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
case NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS: case NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS:
if (!frame) if (!frame)
break; break;
nl80211_control_port_frame_tx_status(bss, nl80211_control_port_frame_tx_status(drv,
nla_data(frame), nla_data(frame),
nla_len(frame), nla_len(frame),
tb[NL80211_ATTR_ACK], tb[NL80211_ATTR_ACK],
@ -4163,10 +4079,16 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
break; break;
#ifdef CONFIG_IEEE80211AX #ifdef CONFIG_IEEE80211AX
case NL80211_CMD_OBSS_COLOR_COLLISION: case NL80211_CMD_OBSS_COLOR_COLLISION:
nl80211_obss_color_collision(bss, tb);
break;
case NL80211_CMD_COLOR_CHANGE_STARTED: case NL80211_CMD_COLOR_CHANGE_STARTED:
nl80211_color_change_announcement_started(bss);
break;
case NL80211_CMD_COLOR_CHANGE_ABORTED: case NL80211_CMD_COLOR_CHANGE_ABORTED:
nl80211_color_change_announcement_aborted(bss);
break;
case NL80211_CMD_COLOR_CHANGE_COMPLETED: case NL80211_CMD_COLOR_CHANGE_COMPLETED:
nl80211_obss_color_event(bss, cmd, tb); nl80211_color_change_announcement_completed(bss);
break; break;
#endif /* CONFIG_IEEE80211AX */ #endif /* CONFIG_IEEE80211AX */
case NL80211_CMD_LINKS_REMOVED: case NL80211_CMD_LINKS_REMOVED:
@ -4257,16 +4179,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,
@ -4324,7 +4237,7 @@ int process_bss_event(struct nl_msg *msg, void *arg)
nl80211_external_auth(bss->drv, tb); nl80211_external_auth(bss->drv, tb);
break; break;
case NL80211_CMD_CONTROL_PORT_FRAME: case NL80211_CMD_CONTROL_PORT_FRAME:
nl80211_control_port_frame(bss, tb); nl80211_control_port_frame(bss->drv, tb);
break; break;
default: default:
wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event " wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown 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,52 +402,23 @@ 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 enum nl80211_iftype old_mode = drv->nlmode;
/* 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.
*/ */
drv->ap_scan_as_station = drv->nlmode;
if (wpa_driver_nl80211_set_mode( if (wpa_driver_nl80211_set_mode(
bss, NL80211_IFTYPE_STATION) || bss, NL80211_IFTYPE_STATION))
wpa_driver_nl80211_scan(bss, params)) { goto fail;
nl80211_restore_ap_mode(bss);
if (wpa_driver_nl80211_scan(bss, params)) {
wpa_driver_nl80211_set_mode(bss, old_mode);
goto fail; goto fail;
} }
/* Restore AP mode when processing scan results */
drv->ap_scan_as_station = old_mode;
ret = 0; ret = 0;
} else } else
goto fail; goto fail;
@ -483,20 +440,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;
@ -780,7 +728,7 @@ static int nl80211_scan_filtered(struct wpa_driver_nl80211_data *drv,
static struct wpa_scan_res * static struct wpa_scan_res *
nl80211_parse_bss_info(struct wpa_driver_nl80211_data *drv, nl80211_parse_bss_info(struct wpa_driver_nl80211_data *drv,
struct nl_msg *msg, const u8 *bssid) struct nl_msg *msg)
{ {
struct nlattr *tb[NL80211_ATTR_MAX + 1]; struct nlattr *tb[NL80211_ATTR_MAX + 1];
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
@ -814,9 +762,6 @@ nl80211_parse_bss_info(struct wpa_driver_nl80211_data *drv,
if (nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS], if (nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS],
bss_policy)) bss_policy))
return NULL; return NULL;
if (bssid && bss[NL80211_BSS_BSSID] &&
!ether_addr_equal(bssid, nla_data(bss[NL80211_BSS_BSSID])))
return NULL;
if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) { if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) {
ie = nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]); ie = nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
ie_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]); ie_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
@ -921,7 +866,6 @@ nl80211_parse_bss_info(struct wpa_driver_nl80211_data *drv,
struct nl80211_bss_info_arg { struct nl80211_bss_info_arg {
struct wpa_driver_nl80211_data *drv; struct wpa_driver_nl80211_data *drv;
struct wpa_scan_results *res; struct wpa_scan_results *res;
const u8 *bssid;
}; };
static int bss_info_handler(struct nl_msg *msg, void *arg) static int bss_info_handler(struct nl_msg *msg, void *arg)
@ -931,7 +875,7 @@ static int bss_info_handler(struct nl_msg *msg, void *arg)
struct wpa_scan_res **tmp; struct wpa_scan_res **tmp;
struct wpa_scan_res *r; struct wpa_scan_res *r;
r = nl80211_parse_bss_info(_arg->drv, msg, _arg->bssid); r = nl80211_parse_bss_info(_arg->drv, msg);
if (!r) if (!r)
return NL_SKIP; return NL_SKIP;
@ -1029,7 +973,7 @@ static void nl80211_update_scan_res_noise(struct wpa_scan_res *res,
static struct wpa_scan_results * static struct wpa_scan_results *
nl80211_get_scan_results(struct wpa_driver_nl80211_data *drv, const u8 *bssid) nl80211_get_scan_results(struct wpa_driver_nl80211_data *drv)
{ {
struct nl_msg *msg; struct nl_msg *msg;
struct wpa_scan_results *res; struct wpa_scan_results *res;
@ -1049,7 +993,6 @@ try_again:
arg.drv = drv; arg.drv = drv;
arg.res = res; arg.res = res;
arg.bssid = bssid;
ret = send_and_recv_resp(drv, msg, bss_info_handler, &arg); ret = send_and_recv_resp(drv, msg, bss_info_handler, &arg);
if (ret == -EAGAIN) { if (ret == -EAGAIN) {
count++; count++;
@ -1086,18 +1029,16 @@ try_again:
/** /**
* wpa_driver_nl80211_get_scan_results - Fetch the latest scan results * wpa_driver_nl80211_get_scan_results - Fetch the latest scan results
* @priv: Pointer to private nl80211 data from wpa_driver_nl80211_init() * @priv: Pointer to private wext data from wpa_driver_nl80211_init()
* @bssid: Return results only for the specified BSSID, %NULL for all
* Returns: Scan results on success, -1 on failure * Returns: Scan results on success, -1 on failure
*/ */
struct wpa_scan_results * wpa_driver_nl80211_get_scan_results(void *priv, struct wpa_scan_results * wpa_driver_nl80211_get_scan_results(void *priv)
const u8 *bssid)
{ {
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;
struct wpa_scan_results *res; struct wpa_scan_results *res;
res = nl80211_get_scan_results(drv, bssid); res = nl80211_get_scan_results(drv);
if (res) if (res)
wpa_driver_nl80211_check_bss_status(drv, res); wpa_driver_nl80211_check_bss_status(drv, res);
return res; return res;
@ -1114,7 +1055,7 @@ static int nl80211_dump_scan_handler(struct nl_msg *msg, void *arg)
struct nl80211_dump_scan_ctx *ctx = arg; struct nl80211_dump_scan_ctx *ctx = arg;
struct wpa_scan_res *r; struct wpa_scan_res *r;
r = nl80211_parse_bss_info(ctx->drv, msg, NULL); r = nl80211_parse_bss_info(ctx->drv, msg);
if (!r) if (!r)
return NL_SKIP; return NL_SKIP;
wpa_printf(MSG_DEBUG, "nl80211: %d " MACSTR " %d%s", wpa_printf(MSG_DEBUG, "nl80211: %d " MACSTR " %d%s",
@ -1327,11 +1268,6 @@ int wpa_driver_nl80211_vendor_scan(struct i802_bss *bss,
goto fail; goto fail;
} }
if (is_ap_interface(drv->nlmode) &&
params->link_id != NL80211_DRV_LINK_ID_NA &&
nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_SCAN_LINK_ID, params->link_id))
goto fail;
nla_nest_end(msg, attr); nla_nest_end(msg, attr);
ret = send_and_recv_resp(drv, msg, scan_cookie_handler, &cookie); ret = send_and_recv_resp(drv, msg, scan_cookie_handler, &cookie);
@ -1351,9 +1287,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

@ -255,18 +255,8 @@ static void * eap_wsc_init(struct eap_sm *sm)
cfg.new_ap_settings = &new_ap_settings; cfg.new_ap_settings = &new_ap_settings;
} }
pos = os_strstr(phase1, "multi_ap="); if (os_strstr(phase1, "multi_ap=1"))
if (pos) {
u16 id = atoi(pos + 9);
if (id != 0) {
cfg.multi_ap_backhaul_sta = 1; cfg.multi_ap_backhaul_sta = 1;
cfg.multi_ap_profile = id;
} else {
wpa_printf(MSG_DEBUG,
"EAP-WSC: Invalid multi_ap setting");
}
}
data->wps = wps_init(&cfg); data->wps = wps_init(&cfg);
if (data->wps == NULL) { if (data->wps == NULL) {

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

@ -30,9 +30,6 @@
#include "eloop.h" #include "eloop.h"
#include "l2_packet.h" #include "l2_packet.h"
#ifndef ETHER_VLAN_ENCAP_LEN
#define ETHER_VLAN_ENCAP_LEN 4
#endif
static const u8 pae_group_addr[ETH_ALEN] = static const u8 pae_group_addr[ETH_ALEN] =
{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 }; { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 };

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);
} }
@ -3386,7 +3332,7 @@ skip_sd:
} }
void p2p_sd_query_cb(struct p2p_data *p2p, int success) static void p2p_sd_cb(struct p2p_data *p2p, int success)
{ {
p2p_dbg(p2p, "Service Discovery Query TX callback: success=%d", p2p_dbg(p2p, "Service Discovery Query TX callback: success=%d",
success); success);
@ -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 "
@ -3889,7 +3835,7 @@ void p2p_send_action_cb(struct p2p_data *p2p, unsigned int freq, const u8 *dst,
p2p_go_neg_conf_cb(p2p, result); p2p_go_neg_conf_cb(p2p, result);
break; break;
case P2P_PENDING_SD: case P2P_PENDING_SD:
p2p_sd_query_cb(p2p, success); p2p_sd_cb(p2p, success);
break; break;
case P2P_PENDING_PD: case P2P_PENDING_PD:
p2p_prov_disc_cb(p2p, success); p2p_prov_disc_cb(p2p, success);
@ -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,
@ -980,9 +899,6 @@ void p2p_pref_channel_filter(const struct p2p_channels *a,
const struct weighted_pcl *freq_list, const struct weighted_pcl *freq_list,
unsigned int num_channels, unsigned int num_channels,
struct p2p_channels *res, bool go); struct p2p_channels *res, bool go);
void p2p_sd_query_cb(struct p2p_data *p2p, int success);
void p2p_dbg(struct p2p_data *p2p, const char *fmt, ...) void p2p_dbg(struct p2p_data *p2p, const char *fmt, ...)
PRINTF_FORMAT(2, 3); PRINTF_FORMAT(2, 3);
void p2p_info(struct p2p_data *p2p, const char *fmt, ...) void p2p_info(struct p2p_data *p2p, const char *fmt, ...)

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