@@ -7,13 +7,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=hostapd
-PKG_RELEASE:=11
+PKG_RELEASE:=1
PKG_SOURCE_URL:=http://w1.fi/hostap.git
PKG_SOURCE_PROTO:=git
-PKG_SOURCE_DATE:=2018-12-02
-PKG_SOURCE_VERSION:=c2c6c01bb8b6fafc2074b46a53c4eab2c145ac6f
-PKG_MIRROR_HASH:=d381123fe42059b553d96122a03c35e7d1709153c3aaf10fa4e74fe59be243dd
+PKG_SOURCE_DATE:=2019-04-21
+PKG_SOURCE_VERSION:=63962824309bb428e5f73d9caae08fcb949fbe36
+PKG_MIRROR_HASH:=b31e09b22284785f84ee4d2dfc2b8fa94cad5d7375d957bf2862a50cb5bc1475
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
PKG_LICENSE:=BSD-3-Clause
@@ -50,13 +50,12 @@ CONFIG_DRIVER_NL80211=y
# WPA2/IEEE 802.11i RSN pre-authentication
CONFIG_RSN_PREAUTH=y
-# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
-CONFIG_PEERKEY=y
-
# IEEE 802.11w (management frame protection)
-# Driver support is also needed for IEEE 802.11w.
#CONFIG_IEEE80211W=y
+# Support Operating Channel Validation
+#CONFIG_OCV=y
+
# Integrated EAP server
#CONFIG_EAP=y
@@ -253,6 +252,11 @@ CONFIG_NO_DUMP_STATE=y
# requirements described above.
CONFIG_NO_RANDOM_POOL=y
+# Should we attempt to use the getrandom(2) call that provides more reliable
+# yet secure randomness source than /dev/random on Linux 3.17 and newer.
+# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
+#CONFIG_GETRANDOM=y
+
# Should we use poll instead of select? Select is used by default.
#CONFIG_ELOOP_POLL=y
@@ -360,8 +364,6 @@ CONFIG_TLS=internal
#CONFIG_TAXONOMY=y
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
-# Note: This is an experimental and not yet complete implementation. This
-# should not be enabled for production use.
#CONFIG_FILS=y
# FILS shared key authentication with PFS
#CONFIG_FILS_SK_PFS=y
@@ -374,6 +376,10 @@ CONFIG_TLS=internal
# Experimental implementation of draft-harkins-owe-07.txt
#CONFIG_OWE=y
+# Override default value for the wpa_disable_eapol_key_retries configuration
+# parameter. See that parameter in hostapd.conf for more details.
+#CFLAGS += -DDEFAULT_WPA_DISABLE_EAPOL_KEY_RETRIES=1
+
# uBus IPC/RPC System
# Services can connect to the bus and provide methods
# that can be called by other services or clients.
@@ -53,6 +53,9 @@ CONFIG_RSN_PREAUTH=y
# IEEE 802.11w (management frame protection)
#CONFIG_IEEE80211W=y
+# Support Operating Channel Validation
+#CONFIG_OCV=y
+
# Integrated EAP server
CONFIG_EAP=y
@@ -249,6 +252,11 @@ CONFIG_NO_DUMP_STATE=y
# requirements described above.
CONFIG_NO_RANDOM_POOL=y
+# Should we attempt to use the getrandom(2) call that provides more reliable
+# yet secure randomness source than /dev/random on Linux 3.17 and newer.
+# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
+#CONFIG_GETRANDOM=y
+
# Should we use poll instead of select? Select is used by default.
#CONFIG_ELOOP_POLL=y
@@ -356,8 +364,6 @@ CONFIG_INTERNAL_LIBTOMMATH=y
CONFIG_TAXONOMY=y
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
-# Note: This is an experimental and not yet complete implementation. This
-# should not be enabled for production use.
#CONFIG_FILS=y
# FILS shared key authentication with PFS
#CONFIG_FILS_SK_PFS=y
@@ -53,6 +53,9 @@ CONFIG_RSN_PREAUTH=y
# IEEE 802.11w (management frame protection)
#CONFIG_IEEE80211W=y
+# Support Operating Channel Validation
+#CONFIG_OCV=y
+
# Integrated EAP server
#CONFIG_EAP=y
@@ -249,6 +252,11 @@ CONFIG_NO_DUMP_STATE=y
# requirements described above.
CONFIG_NO_RANDOM_POOL=y
+# Should we attempt to use the getrandom(2) call that provides more reliable
+# yet secure randomness source than /dev/random on Linux 3.17 and newer.
+# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
+#CONFIG_GETRANDOM=y
+
# Should we use poll instead of select? Select is used by default.
#CONFIG_ELOOP_POLL=y
@@ -356,8 +364,6 @@ CONFIG_TLS=internal
#CONFIG_TAXONOMY=y
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
-# Note: This is an experimental and not yet complete implementation. This
-# should not be enabled for production use.
#CONFIG_FILS=y
# FILS shared key authentication with PFS
#CONFIG_FILS_SK_PFS=y
@@ -73,6 +73,12 @@ CONFIG_DRIVER_NL80211=y
# Driver interface for wired Ethernet drivers
CONFIG_DRIVER_WIRED=y
+# Driver interface for MACsec capable Qualcomm Atheros drivers
+#CONFIG_DRIVER_MACSEC_QCA=y
+
+# Driver interface for Linux MACsec drivers
+#CONFIG_DRIVER_MACSEC_LINUX=y
+
# Driver interface for the Broadcom RoboSwitch family
#CONFIG_DRIVER_ROBOSWITCH=y
@@ -83,8 +89,8 @@ CONFIG_DRIVER_WIRED=y
#LIBS += -lsocket -ldlpi -lnsl
#LIBS_c += -lsocket
-# Enable IEEE 802.1X Supplicant (automatically included if any EAP method is
-# included)
+# Enable IEEE 802.1X Supplicant (automatically included if any EAP method or
+# MACsec is included)
#CONFIG_IEEE8021X_EAPOL=y
# EAP-MD5
@@ -103,9 +109,6 @@ CONFIG_DRIVER_WIRED=y
#CONFIG_EAP_TTLS=y
# EAP-FAST
-# Note: If OpenSSL is used as the TLS library, OpenSSL 1.0 or newer is needed
-# for EAP-FAST support. Older OpenSSL releases would need to be patched, e.g.,
-# with openssl-0.9.8x-tls-extensions.patch, to add the needed functions.
#CONFIG_EAP_FAST=y
# EAP-GTC
@@ -166,6 +169,9 @@ CONFIG_DRIVER_WIRED=y
# EAP-EKE
#CONFIG_EAP_EKE=y
+# MACsec
+#CONFIG_MACSEC=y
+
# PKCS#12 (PFX) support (used to read private key and certificate file from
# a file that usually has extension .p12 or .pfx)
#CONFIG_PKCS12=y
@@ -226,6 +232,9 @@ CONFIG_CTRL_IFACE=y
# wpa_passphrase). This saves about 0.5 kB in code size.
#CONFIG_NO_WPA_PASSPHRASE=y
+# Simultaneous Authentication of Equals (SAE), WPA3-Personal
+#CONFIG_SAE=y
+
# Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
# This can be used if ap_scan=1 mode is never enabled.
#CONFIG_NO_SCAN_PROCESSING=y
@@ -288,13 +297,13 @@ CONFIG_BACKEND=file
# bridge interfaces (commit 'bridge: respect RFC2863 operational state')').
#CONFIG_NO_LINUX_PACKET_SOCKET_WAR=y
-# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
-#CONFIG_PEERKEY=y
-
# IEEE 802.11w (management frame protection), also known as PMF
# Driver support is also needed for IEEE 802.11w.
#CONFIG_IEEE80211W=y
+# Support Operating Channel Validation
+#CONFIG_OCV=y
+
# Select TLS implementation
# openssl = OpenSSL (default)
# gnutls = GnuTLS
@@ -343,10 +352,6 @@ CONFIG_TLS=internal
#CONFIG_NDIS_EVENTS_INTEGRATED=y
#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
-# Add support for old DBus control interface
-# (fi.epitest.hostap.WPASupplicant)
-#CONFIG_CTRL_IFACE_DBUS=y
-
# Add support for new DBus control interface
# (fi.w1.hostap.wpa_supplicant1)
#CONFIG_CTRL_IFACE_DBUS_NEW=y
@@ -378,10 +383,6 @@ CONFIG_TLS=internal
# IEEE Std 802.11r-2008 (Fast BSS Transition) for station mode
CONFIG_IEEE80211R=y
-# IEEE Std 802.11r-2008 (Fast BSS Transition) for AP mode (implies
-# CONFIG_IEEE80211R).
-#CONFIG_IEEE80211R_AP=y
-
# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt)
#CONFIG_DEBUG_FILE=y
@@ -456,6 +457,11 @@ CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
# that meet the requirements described above.
CONFIG_NO_RANDOM_POOL=y
+# Should we attempt to use the getrandom(2) call that provides more reliable
+# yet secure randomness source than /dev/random on Linux 3.17 and newer.
+# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
+#CONFIG_GETRANDOM=y
+
# IEEE 802.11n (High Throughput) support (mainly for AP mode)
#CONFIG_IEEE80211N=y
@@ -497,8 +503,8 @@ CONFIG_NO_RANDOM_POOL=y
# Enable TDLS support
#CONFIG_TDLS=y
-# Wi-Fi Direct
-# This can be used to enable Wi-Fi Direct extensions for P2P using an external
+# Wi-Fi Display
+# This can be used to enable Wi-Fi Display extensions for P2P using an external
# program to control the additional information exchanges in the messages.
#CONFIG_WIFI_DISPLAY=y
@@ -559,8 +565,6 @@ CONFIG_NO_RANDOM_POOL=y
#CONFIG_MBO=y
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
-# Note: This is an experimental and not yet complete implementation. This
-# should not be enabled for production use.
#CONFIG_FILS=y
# FILS shared key authentication with PFS
#CONFIG_FILS_SK_PFS=y
@@ -592,6 +596,11 @@ CONFIG_NO_RANDOM_POOL=y
# Experimental implementation of draft-harkins-owe-07.txt
#CONFIG_OWE=y
+# Device Provisioning Protocol (DPP)
+# This requires CONFIG_IEEE80211W=y to be enabled, too. (see
+# wpa_supplicant/README-DPP for details)
+#CONFIG_DPP=y
+
# uBus IPC/RPC System
# Services can connect to the bus and provide methods
# that can be called by other services or clients.
@@ -109,9 +109,6 @@ CONFIG_EAP_PEAP=y
CONFIG_EAP_TTLS=y
# EAP-FAST
-# Note: If OpenSSL is used as the TLS library, OpenSSL 1.0 or newer is needed
-# for EAP-FAST support. Older OpenSSL releases would need to be patched, e.g.,
-# with openssl-0.9.8x-tls-extensions.patch, to add the needed functions.
CONFIG_EAP_FAST=y
# EAP-GTC
@@ -235,6 +232,9 @@ CONFIG_CTRL_IFACE=y
# wpa_passphrase). This saves about 0.5 kB in code size.
#CONFIG_NO_WPA_PASSPHRASE=y
+# Simultaneous Authentication of Equals (SAE), WPA3-Personal
+#CONFIG_SAE=y
+
# Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
# This can be used if ap_scan=1 mode is never enabled.
#CONFIG_NO_SCAN_PROCESSING=y
@@ -301,6 +301,9 @@ CONFIG_BACKEND=file
# Driver support is also needed for IEEE 802.11w.
#CONFIG_IEEE80211W=y
+# Support Operating Channel Validation
+#CONFIG_OCV=y
+
# Select TLS implementation
# openssl = OpenSSL (default)
# gnutls = GnuTLS
@@ -349,10 +352,6 @@ CONFIG_INTERNAL_LIBTOMMATH_FAST=y
#CONFIG_NDIS_EVENTS_INTEGRATED=y
#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
-# Add support for old DBus control interface
-# (fi.epitest.hostap.WPASupplicant)
-#CONFIG_CTRL_IFACE_DBUS=y
-
# Add support for new DBus control interface
# (fi.w1.hostap.wpa_supplicant1)
#CONFIG_CTRL_IFACE_DBUS_NEW=y
@@ -458,6 +457,11 @@ CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
# that meet the requirements described above.
CONFIG_NO_RANDOM_POOL=y
+# Should we attempt to use the getrandom(2) call that provides more reliable
+# yet secure randomness source than /dev/random on Linux 3.17 and newer.
+# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
+#CONFIG_GETRANDOM=y
+
# IEEE 802.11n (High Throughput) support (mainly for AP mode)
#CONFIG_IEEE80211N=y
@@ -499,8 +503,8 @@ CONFIG_WNM=y
# Enable TDLS support
#CONFIG_TDLS=y
-# Wi-Fi Direct
-# This can be used to enable Wi-Fi Direct extensions for P2P using an external
+# Wi-Fi Display
+# This can be used to enable Wi-Fi Display extensions for P2P using an external
# program to control the additional information exchanges in the messages.
#CONFIG_WIFI_DISPLAY=y
@@ -561,8 +565,6 @@ CONFIG_WNM=y
#CONFIG_MBO=y
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
-# Note: This is an experimental and not yet complete implementation. This
-# should not be enabled for production use.
#CONFIG_FILS=y
# FILS shared key authentication with PFS
#CONFIG_FILS_SK_PFS=y
@@ -594,6 +596,11 @@ CONFIG_IBSS_RSN=y
# Experimental implementation of draft-harkins-owe-07.txt
#CONFIG_OWE=y
+# Device Provisioning Protocol (DPP)
+# This requires CONFIG_IEEE80211W=y to be enabled, too. (see
+# wpa_supplicant/README-DPP for details)
+#CONFIG_DPP=y
+
# uBus IPC/RPC System
# Services can connect to the bus and provide methods
# that can be called by other services or clients.
@@ -109,9 +109,6 @@ CONFIG_DRIVER_WIRED=y
#CONFIG_EAP_TTLS=y
# EAP-FAST
-# Note: If OpenSSL is used as the TLS library, OpenSSL 1.0 or newer is needed
-# for EAP-FAST support. Older OpenSSL releases would need to be patched, e.g.,
-# with openssl-0.9.8x-tls-extensions.patch, to add the needed functions.
#CONFIG_EAP_FAST=y
# EAP-GTC
@@ -235,6 +232,9 @@ CONFIG_CTRL_IFACE=y
# wpa_passphrase). This saves about 0.5 kB in code size.
#CONFIG_NO_WPA_PASSPHRASE=y
+# Simultaneous Authentication of Equals (SAE), WPA3-Personal
+#CONFIG_SAE=y
+
# Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
# This can be used if ap_scan=1 mode is never enabled.
#CONFIG_NO_SCAN_PROCESSING=y
@@ -301,6 +301,9 @@ CONFIG_BACKEND=file
# Driver support is also needed for IEEE 802.11w.
#CONFIG_IEEE80211W=y
+# Support Operating Channel Validation
+#CONFIG_OCV=y
+
# Select TLS implementation
# openssl = OpenSSL (default)
# gnutls = GnuTLS
@@ -349,10 +352,6 @@ CONFIG_TLS=internal
#CONFIG_NDIS_EVENTS_INTEGRATED=y
#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
-# Add support for old DBus control interface
-# (fi.epitest.hostap.WPASupplicant)
-#CONFIG_CTRL_IFACE_DBUS=y
-
# Add support for new DBus control interface
# (fi.w1.hostap.wpa_supplicant1)
#CONFIG_CTRL_IFACE_DBUS_NEW=y
@@ -458,6 +457,11 @@ CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
# that meet the requirements described above.
CONFIG_NO_RANDOM_POOL=y
+# Should we attempt to use the getrandom(2) call that provides more reliable
+# yet secure randomness source than /dev/random on Linux 3.17 and newer.
+# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
+#CONFIG_GETRANDOM=y
+
# IEEE 802.11n (High Throughput) support (mainly for AP mode)
#CONFIG_IEEE80211N=y
@@ -499,8 +503,8 @@ CONFIG_NO_RANDOM_POOL=y
# Enable TDLS support
#CONFIG_TDLS=y
-# Wi-Fi Direct
-# This can be used to enable Wi-Fi Direct extensions for P2P using an external
+# Wi-Fi Display
+# This can be used to enable Wi-Fi Display extensions for P2P using an external
# program to control the additional information exchanges in the messages.
#CONFIG_WIFI_DISPLAY=y
@@ -561,8 +565,6 @@ CONFIG_NO_RANDOM_POOL=y
#CONFIG_MBO=y
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
-# Note: This is an experimental and not yet complete implementation. This
-# should not be enabled for production use.
#CONFIG_FILS=y
# FILS shared key authentication with PFS
#CONFIG_FILS_SK_PFS=y
@@ -594,6 +596,11 @@ CONFIG_NO_RANDOM_POOL=y
# Experimental implementation of draft-harkins-owe-07.txt
#CONFIG_OWE=y
+# Device Provisioning Protocol (DPP)
+# This requires CONFIG_IEEE80211W=y to be enabled, too. (see
+# wpa_supplicant/README-DPP for details)
+#CONFIG_DPP=y
+
# uBus IPC/RPC System
# Services can connect to the bus and provide methods
# that can be called by other services or clients.
@@ -109,9 +109,6 @@ CONFIG_EAP_PEAP=y
CONFIG_EAP_TTLS=y
# EAP-FAST
-# Note: If OpenSSL is used as the TLS library, OpenSSL 1.0 or newer is needed
-# for EAP-FAST support. Older OpenSSL releases would need to be patched, e.g.,
-# with openssl-0.9.8x-tls-extensions.patch, to add the needed functions.
CONFIG_EAP_FAST=y
# EAP-GTC
@@ -235,6 +232,9 @@ CONFIG_CTRL_IFACE=y
# wpa_passphrase). This saves about 0.5 kB in code size.
#CONFIG_NO_WPA_PASSPHRASE=y
+# Simultaneous Authentication of Equals (SAE), WPA3-Personal
+#CONFIG_SAE=y
+
# Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
# This can be used if ap_scan=1 mode is never enabled.
#CONFIG_NO_SCAN_PROCESSING=y
@@ -301,6 +301,9 @@ CONFIG_BACKEND=file
# Driver support is also needed for IEEE 802.11w.
CONFIG_IEEE80211W=y
+# Support Operating Channel Validation
+#CONFIG_OCV=y
+
# Select TLS implementation
# openssl = OpenSSL (default)
# gnutls = GnuTLS
@@ -349,10 +352,6 @@ CONFIG_INTERNAL_LIBTOMMATH_FAST=y
#CONFIG_NDIS_EVENTS_INTEGRATED=y
#PLATFORMSDKLIB="/opt/Program Files/Microsoft Platform SDK/Lib"
-# Add support for old DBus control interface
-# (fi.epitest.hostap.WPASupplicant)
-#CONFIG_CTRL_IFACE_DBUS=y
-
# Add support for new DBus control interface
# (fi.w1.hostap.wpa_supplicant1)
#CONFIG_CTRL_IFACE_DBUS_NEW=y
@@ -458,6 +457,11 @@ CONFIG_DEBUG_SYSLOG_FACILITY=LOG_DAEMON
# that meet the requirements described above.
CONFIG_NO_RANDOM_POOL=y
+# Should we attempt to use the getrandom(2) call that provides more reliable
+# yet secure randomness source than /dev/random on Linux 3.17 and newer.
+# Requires glibc 2.25 to build, falls back to /dev/random if unavailable.
+#CONFIG_GETRANDOM=y
+
# IEEE 802.11n (High Throughput) support (mainly for AP mode)
#CONFIG_IEEE80211N=y
@@ -499,8 +503,8 @@ CONFIG_P2P=y
# Enable TDLS support
#CONFIG_TDLS=y
-# Wi-Fi Direct
-# This can be used to enable Wi-Fi Direct extensions for P2P using an external
+# Wi-Fi Display
+# This can be used to enable Wi-Fi Display extensions for P2P using an external
# program to control the additional information exchanges in the messages.
#CONFIG_WIFI_DISPLAY=y
@@ -561,8 +565,6 @@ CONFIG_P2P=y
#CONFIG_MBO=y
# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
-# Note: This is an experimental and not yet complete implementation. This
-# should not be enabled for production use.
#CONFIG_FILS=y
# FILS shared key authentication with PFS
#CONFIG_FILS_SK_PFS=y
@@ -594,6 +596,11 @@ CONFIG_IBSS_RSN=y
# Experimental implementation of draft-harkins-owe-07.txt
#CONFIG_OWE=y
+# Device Provisioning Protocol (DPP)
+# This requires CONFIG_IEEE80211W=y to be enabled, too. (see
+# wpa_supplicant/README-DPP for details)
+#CONFIG_DPP=y
+
# uBus IPC/RPC System
# Services can connect to the bus and provide methods
# that can be called by other services or clients.
deleted file mode 100644
@@ -1,211 +0,0 @@
-From 02ae4382f45f772e3630460459eb4e5af64e71b4 Mon Sep 17 00:00:00 2001
-From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:05 -0700
-Subject: [PATCH 01/18] mesh: factor out mesh join function
-
-mesh join function consitss of 2 parts which are preparing
-configurations and sending join event to driver.
-Since physical mesh join event could happen either right
-after mesh configuration is done or after CAC is done
-in case of DFS channel is used, factor out the function
-into 2 parts to reduce redundant calls.
-
-Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
----
- wpa_supplicant/mesh.c | 119 ++++++++++++++++--------------
- wpa_supplicant/mesh.h | 1 +
- wpa_supplicant/wpa_supplicant_i.h | 1 +
- 3 files changed, 67 insertions(+), 54 deletions(-)
-
---- a/wpa_supplicant/mesh.c
-+++ b/wpa_supplicant/mesh.c
-@@ -364,13 +364,48 @@ void wpa_supplicant_mesh_add_scan_ie(str
- }
-
-
-+void wpas_join_mesh(struct wpa_supplicant *wpa_s)
-+{
-+ struct wpa_driver_mesh_join_params *params = wpa_s->mesh_params;
-+ struct wpa_ssid *ssid = wpa_s->current_ssid;
-+ int ret = 0;
-+
-+ if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
-+ wpa_s->pairwise_cipher = wpa_s->mesh_rsn->pairwise_cipher;
-+ wpa_s->group_cipher = wpa_s->mesh_rsn->group_cipher;
-+ wpa_s->mgmt_group_cipher = wpa_s->mesh_rsn->mgmt_group_cipher;
-+ }
-+
-+ if (wpa_s->ifmsh) {
-+ params->ies = wpa_s->ifmsh->mconf->rsn_ie;
-+ params->ie_len = wpa_s->ifmsh->mconf->rsn_ie_len;
-+ params->basic_rates = wpa_s->ifmsh->basic_rates;
-+ params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE;
-+ params->conf.ht_opmode = wpa_s->ifmsh->bss[0]->iface->ht_op_mode;
-+ }
-+
-+ ret = wpa_drv_join_mesh(wpa_s, params);
-+ if (ret)
-+ wpa_msg(wpa_s, MSG_ERROR, "mesh join error=%d\n", ret);
-+
-+ /* hostapd sets the interface down until we associate */
-+ wpa_drv_set_operstate(wpa_s, 1);
-+
-+ if (!ret)
-+ wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
-+
-+ return;
-+}
-+
-+
- int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid)
- {
-- struct wpa_driver_mesh_join_params params;
-+ struct wpa_driver_mesh_join_params *params =
-+ os_zalloc(sizeof(struct wpa_driver_mesh_join_params));
- int ret = 0;
-
-- if (!ssid || !ssid->ssid || !ssid->ssid_len || !ssid->frequency) {
-+ if (!ssid || !ssid->ssid || !ssid->ssid_len || !ssid->frequency || !params) {
- ret = -ENOENT;
- goto out;
- }
-@@ -381,22 +416,22 @@ int wpa_supplicant_join_mesh(struct wpa_
- wpa_s->group_cipher = WPA_CIPHER_NONE;
- wpa_s->mgmt_group_cipher = 0;
-
-- os_memset(¶ms, 0, sizeof(params));
-- params.meshid = ssid->ssid;
-- params.meshid_len = ssid->ssid_len;
-- ibss_mesh_setup_freq(wpa_s, ssid, ¶ms.freq);
-- wpa_s->mesh_ht_enabled = !!params.freq.ht_enabled;
-- wpa_s->mesh_vht_enabled = !!params.freq.vht_enabled;
-- if (params.freq.ht_enabled && params.freq.sec_channel_offset)
-- ssid->ht40 = params.freq.sec_channel_offset;
-+ params->meshid = ssid->ssid;
-+ params->meshid_len = ssid->ssid_len;
-+ ibss_mesh_setup_freq(wpa_s, ssid, ¶ms->freq);
-+ wpa_s->mesh_ht_enabled = !!params->freq.ht_enabled;
-+ wpa_s->mesh_vht_enabled = !!params->freq.vht_enabled;
-+ if (params->freq.ht_enabled && params->freq.sec_channel_offset)
-+ ssid->ht40 = params->freq.sec_channel_offset;
-+
- if (wpa_s->mesh_vht_enabled) {
- ssid->vht = 1;
-- switch (params.freq.bandwidth) {
-+ switch (params->freq.bandwidth) {
- case 80:
-- if (params.freq.center_freq2) {
-+ if (params->freq.center_freq2) {
- ssid->max_oper_chwidth = VHT_CHANWIDTH_80P80MHZ;
- ssid->vht_center_freq2 =
-- params.freq.center_freq2;
-+ params->freq.center_freq2;
- } else {
- ssid->max_oper_chwidth = VHT_CHANWIDTH_80MHZ;
- }
-@@ -410,67 +445,43 @@ int wpa_supplicant_join_mesh(struct wpa_
- }
- }
- if (ssid->beacon_int > 0)
-- params.beacon_int = ssid->beacon_int;
-+ params->beacon_int = ssid->beacon_int;
- else if (wpa_s->conf->beacon_int > 0)
-- params.beacon_int = wpa_s->conf->beacon_int;
-+ params->beacon_int = wpa_s->conf->beacon_int;
- if (ssid->dtim_period > 0)
-- params.dtim_period = ssid->dtim_period;
-+ params->dtim_period = ssid->dtim_period;
- else if (wpa_s->conf->dtim_period > 0)
-- params.dtim_period = wpa_s->conf->dtim_period;
-- params.conf.max_peer_links = wpa_s->conf->max_peer_links;
-+ params->dtim_period = wpa_s->conf->dtim_period;
-+ params->conf.max_peer_links = wpa_s->conf->max_peer_links;
- if (ssid->mesh_rssi_threshold < DEFAULT_MESH_RSSI_THRESHOLD) {
-- params.conf.rssi_threshold = ssid->mesh_rssi_threshold;
-- params.conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_RSSI_THRESHOLD;
-+ params->conf.rssi_threshold = ssid->mesh_rssi_threshold;
-+ params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_RSSI_THRESHOLD;
- }
-
- if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
-- params.flags |= WPA_DRIVER_MESH_FLAG_SAE_AUTH;
-- params.flags |= WPA_DRIVER_MESH_FLAG_AMPE;
-+ params->flags |= WPA_DRIVER_MESH_FLAG_SAE_AUTH;
-+ params->flags |= WPA_DRIVER_MESH_FLAG_AMPE;
- wpa_s->conf->user_mpm = 1;
- }
-
- if (wpa_s->conf->user_mpm) {
-- params.flags |= WPA_DRIVER_MESH_FLAG_USER_MPM;
-- params.conf.auto_plinks = 0;
-+ params->flags |= WPA_DRIVER_MESH_FLAG_USER_MPM;
-+ params->conf.auto_plinks = 0;
- } else {
-- params.flags |= WPA_DRIVER_MESH_FLAG_DRIVER_MPM;
-- params.conf.auto_plinks = 1;
-+ params->flags |= WPA_DRIVER_MESH_FLAG_DRIVER_MPM;
-+ params->conf.auto_plinks = 1;
- }
-- params.conf.peer_link_timeout = wpa_s->conf->mesh_max_inactivity;
-+ params->conf.peer_link_timeout = wpa_s->conf->mesh_max_inactivity;
-
-- if (wpa_supplicant_mesh_init(wpa_s, ssid, ¶ms.freq)) {
-+ wpa_s->mesh_params = params;
-+ if (wpa_supplicant_mesh_init(wpa_s, ssid, ¶ms->freq)) {
- wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh");
- wpa_drv_leave_mesh(wpa_s);
- ret = -1;
- goto out;
- }
-
-- if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
-- wpa_s->pairwise_cipher = wpa_s->mesh_rsn->pairwise_cipher;
-- wpa_s->group_cipher = wpa_s->mesh_rsn->group_cipher;
-- wpa_s->mgmt_group_cipher = wpa_s->mesh_rsn->mgmt_group_cipher;
-- }
--
-- if (wpa_s->ifmsh) {
-- params.ies = wpa_s->ifmsh->mconf->rsn_ie;
-- params.ie_len = wpa_s->ifmsh->mconf->rsn_ie_len;
-- params.basic_rates = wpa_s->ifmsh->basic_rates;
-- params.conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE;
-- params.conf.ht_opmode = wpa_s->ifmsh->bss[0]->iface->ht_op_mode;
-- }
--
-- wpa_msg(wpa_s, MSG_INFO, "joining mesh %s",
-- wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
-- ret = wpa_drv_join_mesh(wpa_s, ¶ms);
-- if (ret)
-- wpa_msg(wpa_s, MSG_ERROR, "mesh join error=%d", ret);
--
-- /* hostapd sets the interface down until we associate */
-- wpa_drv_set_operstate(wpa_s, 1);
--
-- if (!ret)
-- wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
--
-+ wpas_join_mesh(wpa_s);
- out:
- return ret;
- }
---- a/wpa_supplicant/mesh.h
-+++ b/wpa_supplicant/mesh.h
-@@ -21,6 +21,7 @@ int wpas_mesh_add_interface(struct wpa_s
- int wpas_mesh_peer_remove(struct wpa_supplicant *wpa_s, const u8 *addr);
- int wpas_mesh_peer_add(struct wpa_supplicant *wpa_s, const u8 *addr,
- int duration);
-+void wpas_join_mesh(struct wpa_supplicant *wpa_s);
-
- #ifdef CONFIG_MESH
-
---- a/wpa_supplicant/wpa_supplicant_i.h
-+++ b/wpa_supplicant/wpa_supplicant_i.h
-@@ -814,6 +814,7 @@ struct wpa_supplicant {
- unsigned int mesh_if_created:1;
- unsigned int mesh_ht_enabled:1;
- unsigned int mesh_vht_enabled:1;
-+ struct wpa_driver_mesh_join_params *mesh_params;
- #ifdef CONFIG_PMKSA_CACHE_EXTERNAL
- /* struct external_pmksa_cache::list */
- struct dl_list mesh_external_pmksa_cache;
deleted file mode 100644
@@ -1,133 +0,0 @@
-From 89db76eeff6502dfa39b011962ec9d560ed4c2ee Mon Sep 17 00:00:00 2001
-From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:06 -0700
-Subject: [PATCH 02/18] mesh: factor out rsn initialization
-
-RSN initialization can be used in different phases
-if mesh initialization and mesh join don't happen
-in sequence such as DFS CAC is done in between,
-hence factor it out to help convering the case.
-
-Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
----
- wpa_supplicant/mesh.c | 84 +++++++++++++++++++++++++------------------
- wpa_supplicant/mesh.h | 1 +
- 2 files changed, 50 insertions(+), 35 deletions(-)
-
---- a/wpa_supplicant/mesh.c
-+++ b/wpa_supplicant/mesh.c
-@@ -147,6 +147,53 @@ static void wpas_mesh_copy_groups(struct
- }
-
-
-+int wpas_mesh_init_rsn(struct wpa_supplicant *wpa_s)
-+{
-+ struct hostapd_iface *ifmsh = wpa_s->ifmsh;
-+ struct mesh_conf *mconf = wpa_s->ifmsh->mconf;
-+ struct wpa_ssid *ssid = wpa_s->current_ssid;
-+ struct hostapd_data *bss = ifmsh->bss[0];
-+ static int default_groups[] = { 19, 20, 21, 25, 26, -1 };
-+ const char *password;
-+ size_t len;
-+
-+ if (mconf->security != MESH_CONF_SEC_NONE) {
-+ password = ssid->sae_password;
-+ if (!password)
-+ password = ssid->passphrase;
-+ if (!password) {
-+ wpa_printf(MSG_ERROR,
-+ "mesh: Passphrase for SAE not configured");
-+ return -1;
-+ }
-+
-+ bss->conf->wpa = ssid->proto;
-+ bss->conf->wpa_key_mgmt = ssid->key_mgmt;
-+
-+ if (wpa_s->conf->sae_groups &&
-+ wpa_s->conf->sae_groups[0] > 0) {
-+ wpas_mesh_copy_groups(bss, wpa_s);
-+ } else {
-+ bss->conf->sae_groups =
-+ os_memdup(default_groups,
-+ sizeof(default_groups));
-+ if (!bss->conf->sae_groups)
-+ return -1;
-+ }
-+
-+ len = os_strlen(password);
-+ bss->conf->ssid.wpa_passphrase =
-+ dup_binstr(password, len);
-+
-+ wpa_s->mesh_rsn = mesh_rsn_auth_init(wpa_s, mconf);
-+ if (!wpa_s->mesh_rsn)
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+
- static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
- struct wpa_ssid *ssid,
- struct hostapd_freq_params *freq)
-@@ -156,9 +203,6 @@ static int wpa_supplicant_mesh_init(stru
- struct hostapd_config *conf;
- struct mesh_conf *mconf;
- int basic_rates_erp[] = { 10, 20, 55, 60, 110, 120, 240, -1 };
-- static int default_groups[] = { 19, 20, 21, 25, 26, -1 };
-- const char *password;
-- size_t len;
- int rate_len;
- int frequency;
-
-@@ -292,38 +336,8 @@ static int wpa_supplicant_mesh_init(stru
- return -1;
- }
-
-- if (mconf->security != MESH_CONF_SEC_NONE) {
-- password = ssid->sae_password;
-- if (!password)
-- password = ssid->passphrase;
-- if (!password) {
-- wpa_printf(MSG_ERROR,
-- "mesh: Passphrase for SAE not configured");
-- goto out_free;
-- }
--
-- bss->conf->wpa = ssid->proto;
-- bss->conf->wpa_key_mgmt = ssid->key_mgmt;
--
-- if (wpa_s->conf->sae_groups &&
-- wpa_s->conf->sae_groups[0] > 0) {
-- wpas_mesh_copy_groups(bss, wpa_s);
-- } else {
-- bss->conf->sae_groups =
-- os_memdup(default_groups,
-- sizeof(default_groups));
-- if (!bss->conf->sae_groups)
-- goto out_free;
-- }
--
-- len = os_strlen(password);
-- bss->conf->ssid.wpa_passphrase =
-- dup_binstr(password, len);
--
-- wpa_s->mesh_rsn = mesh_rsn_auth_init(wpa_s, mconf);
-- if (!wpa_s->mesh_rsn)
-- goto out_free;
-- }
-+ if (wpas_mesh_init_rsn(wpa_s))
-+ goto out_free;
-
- wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf);
-
---- a/wpa_supplicant/mesh.h
-+++ b/wpa_supplicant/mesh.h
-@@ -22,6 +22,7 @@ int wpas_mesh_peer_remove(struct wpa_sup
- int wpas_mesh_peer_add(struct wpa_supplicant *wpa_s, const u8 *addr,
- int duration);
- void wpas_join_mesh(struct wpa_supplicant *wpa_s);
-+int wpas_mesh_init_rsn(struct wpa_supplicant *wpa_s);
-
- #ifdef CONFIG_MESH
-
deleted file mode 100644
@@ -1,41 +0,0 @@
-From 07bad5f256cbe8a4b45d32c5b43b870ee815fb42 Mon Sep 17 00:00:00 2001
-From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:07 -0700
-Subject: [PATCH 03/18] mesh: relocate RSN init function
-
-RSN init function should work together with mesh join
-when it's used. Since mesh join could be called at different stage
-if DFS channel is used, relocate the function to mesh join.
-It is still the same call flows of mesh join before this changes
-if non-DFS channels are used, hence no side effect will occur.
-
-Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
----
- wpa_supplicant/mesh.c | 9 ++++++---
- 1 file changed, 6 insertions(+), 3 deletions(-)
-
---- a/wpa_supplicant/mesh.c
-+++ b/wpa_supplicant/mesh.c
-@@ -336,9 +336,6 @@ static int wpa_supplicant_mesh_init(stru
- return -1;
- }
-
-- if (wpas_mesh_init_rsn(wpa_s))
-- goto out_free;
--
- wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf);
-
- return 0;
-@@ -384,6 +381,12 @@ void wpas_join_mesh(struct wpa_supplican
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- int ret = 0;
-
-+ if (wpas_mesh_init_rsn(wpa_s)) {
-+ wpa_printf(MSG_ERROR, "Init RSN failed. Deinit mesh...");
-+ wpa_supplicant_mesh_deinit(wpa_s);
-+ return;
-+ }
-+
- if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
- wpa_s->pairwise_cipher = wpa_s->mesh_rsn->pairwise_cipher;
- wpa_s->group_cipher = wpa_s->mesh_rsn->group_cipher;
@@ -1,30 +1,103 @@
-From bd05de484bfa61def530d717c7234381f6b33cf7 Mon Sep 17 00:00:00 2001
+From c05ace7510ead96e72b97ce47b33f7b5865d6d36 Mon Sep 17 00:00:00 2001
From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:08 -0700
-Subject: [PATCH 04/18] mesh: use setup completion callback to complete mesh
- join
+Date: Mon, 27 Aug 2018 14:28:38 -0700
+Subject: [PATCH 1/7] mesh: use setup completion callback to complete mesh join
mesh join function is the last function to be called during
mesh join process, but it's been called a bit earlier than
it's supposed to be, so that some mesh parameter values
such as VHT capabilities not applied correct when mesh join
-is in process. Moreover current design of mesh join that is called
-directly after mesh initialization is not suitable for DFS channels
-to use, since mesh join process should be paused until DFS CAC is
-done and resumed once it's done.
-Using setup completion callback is how AP mode is using for DFS channels
-and mesh can use the same way.
+is in process.
+Moreover current design of mesh join that is called directly
+after mesh initialization isn't suitable for DFS channels to use,
+since mesh join process should be paused until DFS CAC is
+done and resumed after it's done.
The callback will be called by hostapd_setup_interface_complete_sync.
+There is possiblity that completing mesh init fails, so add error
+handle codes.
+Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
---
- wpa_supplicant/mesh.c | 7 +++++--
- wpa_supplicant/mesh.h | 2 +-
- 2 files changed, 6 insertions(+), 3 deletions(-)
+ src/ap/hostapd.c | 11 ++++++++++-
+ wpa_supplicant/mesh.c | 13 +++++++------
+ 2 files changed, 17 insertions(+), 7 deletions(-)
+--- a/src/ap/hostapd.c
++++ b/src/ap/hostapd.c
+@@ -414,6 +414,8 @@ static void hostapd_free_hapd_data(struc
+ #ifdef CONFIG_MESH
+ wpabuf_free(hapd->mesh_pending_auth);
+ hapd->mesh_pending_auth = NULL;
++ /* handling setup failure is already done */
++ hapd->setup_complete_cb = NULL;
+ #endif /* CONFIG_MESH */
+
+ hostapd_clean_rrm(hapd);
+@@ -1980,6 +1982,13 @@ dfs_offload:
+ if (hapd->setup_complete_cb)
+ hapd->setup_complete_cb(hapd->setup_complete_cb_ctx);
+
++#ifdef CONFIG_MESH
++ if (delay_apply_cfg && !iface->mconf) {
++ wpa_printf(MSG_ERROR, "Error while completing mesh init");
++ goto fail;
++ }
++#endif /* CONFIG_MESH */
++
+ wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
+ iface->bss[0]->conf->iface);
+ if (iface->interfaces && iface->interfaces->terminate_on_error > 0)
+@@ -2123,7 +2132,7 @@ int hostapd_setup_interface(struct hosta
+ ret = setup_interface(iface);
+ if (ret) {
+ wpa_printf(MSG_ERROR, "%s: Unable to setup interface.",
+- iface->bss[0]->conf->iface);
++ iface->conf ? iface->conf->bss[0]->iface : "N/A");
+ return -1;
+ }
+
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
-@@ -217,6 +217,7 @@ static int wpa_supplicant_mesh_init(stru
+@@ -190,8 +190,9 @@ static int wpas_mesh_init_rsn(struct wpa
+ }
+
+
+-static int wpas_mesh_complete(struct wpa_supplicant *wpa_s)
++static void wpas_mesh_complete_cb(void *ctx)
+ {
++ struct wpa_supplicant *wpa_s = ctx;
+ struct hostapd_iface *ifmsh = wpa_s->ifmsh;
+ struct wpa_driver_mesh_join_params *params = wpa_s->mesh_params;
+ struct wpa_ssid *ssid = wpa_s->current_ssid;
+@@ -200,7 +201,7 @@ static int wpas_mesh_complete(struct wpa
+ if (!params || !ssid || !ifmsh) {
+ wpa_printf(MSG_ERROR, "mesh: %s called without active mesh",
+ __func__);
+- return -1;
++ return;
+ }
+
+ if (ifmsh->mconf->security != MESH_CONF_SEC_NONE &&
+@@ -208,7 +209,7 @@ static int wpas_mesh_complete(struct wpa
+ wpa_printf(MSG_ERROR,
+ "mesh: RSN initialization failed - deinit mesh");
+ wpa_supplicant_mesh_deinit(wpa_s);
+- return -1;
++ return;
+ }
+
+ if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
+@@ -234,8 +235,6 @@ static int wpas_mesh_complete(struct wpa
+
+ if (!ret)
+ wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
+-
+- return ret;
+ }
+
+
+@@ -262,6 +261,7 @@ static int wpa_supplicant_mesh_init(stru
if (!ifmsh)
return -ENOMEM;
@@ -32,7 +105,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
ifmsh->drv_flags = wpa_s->drv_flags;
ifmsh->num_bss = 1;
ifmsh->bss = os_calloc(wpa_s->ifmsh->num_bss,
-@@ -234,6 +235,8 @@ static int wpa_supplicant_mesh_init(stru
+@@ -279,6 +279,8 @@ static int wpa_supplicant_mesh_init(stru
bss->drv_priv = wpa_s->drv_priv;
bss->iface = ifmsh;
bss->mesh_sta_free_cb = mesh_mpm_free_sta;
@@ -41,33 +114,11 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
frequency = ssid->frequency;
if (frequency != freq->freq &&
frequency == freq->freq + freq->sec_channel_offset * 20) {
-@@ -375,8 +378,9 @@ void wpa_supplicant_mesh_add_scan_ie(str
- }
-
-
--void wpas_join_mesh(struct wpa_supplicant *wpa_s)
-+void wpas_mesh_complete_cb(void *ctx)
- {
-+ struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)ctx;
- struct wpa_driver_mesh_join_params *params = wpa_s->mesh_params;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- int ret = 0;
-@@ -498,7 +502,6 @@ int wpa_supplicant_join_mesh(struct wpa_
+@@ -517,7 +519,6 @@ int wpa_supplicant_join_mesh(struct wpa_
goto out;
}
-- wpas_join_mesh(wpa_s);
+- ret = wpas_mesh_complete(wpa_s);
out:
return ret;
}
---- a/wpa_supplicant/mesh.h
-+++ b/wpa_supplicant/mesh.h
-@@ -21,7 +21,7 @@ int wpas_mesh_add_interface(struct wpa_s
- int wpas_mesh_peer_remove(struct wpa_supplicant *wpa_s, const u8 *addr);
- int wpas_mesh_peer_add(struct wpa_supplicant *wpa_s, const u8 *addr,
- int duration);
--void wpas_join_mesh(struct wpa_supplicant *wpa_s);
-+void wpas_mesh_complete_cb(void *ctx);
- int wpas_mesh_init_rsn(struct wpa_supplicant *wpa_s);
-
- #ifdef CONFIG_MESH
deleted file mode 100644
@@ -1,35 +0,0 @@
-From dbe9afab3b2dceb35d478ac43dfcf8fdc5e23a22 Mon Sep 17 00:00:00 2001
-From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:09 -0700
-Subject: [PATCH 05/18] mesh: reflect country setting to mesh configuration
-
-wpa_supplicant configuration has country parameter that is
-supposed to be used in AP mode to indicate supporting 802.11h
-and 802.11d. Reflect this configuration to Mesh also since Mesh
-is required to support 802.11h and 802.11d to use DFS channels.
-
-Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-[daniel@makrotopia.org: adapted to changed ieee80211_is_dfs prototype]
----
- wpa_supplicant/mesh.c | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
---- a/wpa_supplicant/mesh.c
-+++ b/wpa_supplicant/mesh.c
-@@ -255,6 +255,15 @@ static int wpa_supplicant_mesh_init(stru
- bss->conf->start_disabled = 1;
- bss->conf->mesh = MESH_ENABLED;
- bss->conf->ap_max_inactivity = wpa_s->conf->mesh_max_inactivity;
-+
-+ if (ieee80211_is_dfs(ssid->frequency, wpa_s->hw.modes,
-+ wpa_s->hw.num_modes) && wpa_s->conf->country[0]) {
-+ conf->ieee80211h = 1;
-+ conf->ieee80211d = 1;
-+ conf->country[0] = wpa_s->conf->country[0];
-+ conf->country[1] = wpa_s->conf->country[1];
-+ }
-+
- bss->iconf = conf;
- ifmsh->conf = conf;
-
new file mode 100644
@@ -0,0 +1,26 @@
+From c56f18380d1d404a2abc0ea5373d294508ef1e54 Mon Sep 17 00:00:00 2001
+From: Peter Oh <peter.oh@bowerswilkins.com>
+Date: Mon, 27 Aug 2018 14:28:41 -0700
+Subject: [PATCH 2/7] mesh: update ssid->frequency as pri/sec channel switch
+
+ssid->frequency is one of variables used to gets channel
+number from given frequency. Leave it as unchanged when
+pri/sec channel switched will cause picking up wrong
+channel number after applying secondary channel offset
+for HT40 and leads failing interface bring-up.
+
+Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
+---
+ wpa_supplicant/mesh.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/wpa_supplicant/mesh.c
++++ b/wpa_supplicant/mesh.c
+@@ -286,6 +286,7 @@ static int wpa_supplicant_mesh_init(stru
+ frequency == freq->freq + freq->sec_channel_offset * 20) {
+ wpa_printf(MSG_DEBUG, "mesh: pri/sec channels switched");
+ frequency = freq->freq;
++ ssid->frequency = frequency;
+ }
+ wpa_s->assoc_freq = frequency;
+ wpa_s->current_ssid = ssid;
@@ -1,7 +1,7 @@
-From 51e759da5026b3e64f801135b5d53f2198bbd2f0 Mon Sep 17 00:00:00 2001
+From 593602b7f14be5c2695979639764b1c50f01bbec Mon Sep 17 00:00:00 2001
From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:10 -0700
-Subject: [PATCH 06/18] mesh: inform kernel driver DFS handler in userspace
+Date: Mon, 27 Aug 2018 14:28:49 -0700
+Subject: [PATCH 7/7] mesh: inform kernel driver DFS handler in userspace
NL80211_ATTR_HANDLE_DFS is required by kerenel space
to enable DFS channels that indicates DFS handler
@@ -16,7 +16,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
-@@ -1402,6 +1402,7 @@ struct wpa_driver_mesh_join_params {
+@@ -1436,6 +1436,7 @@ struct wpa_driver_mesh_join_params {
#define WPA_DRIVER_MESH_FLAG_SAE_AUTH 0x00000004
#define WPA_DRIVER_MESH_FLAG_AMPE 0x00000008
unsigned int flags;
@@ -26,7 +26,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
/**
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
-@@ -9375,6 +9375,9 @@ static int nl80211_join_mesh(struct i802
+@@ -9544,6 +9544,9 @@ static int nl80211_join_mesh(struct i802
wpa_printf(MSG_DEBUG, " * flags=%08X", params->flags);
@@ -38,10 +38,10 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
goto fail;
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
-@@ -262,6 +262,7 @@ static int wpa_supplicant_mesh_init(stru
- conf->ieee80211d = 1;
+@@ -308,6 +308,7 @@ static int wpa_supplicant_mesh_init(stru
conf->country[0] = wpa_s->conf->country[0];
conf->country[1] = wpa_s->conf->country[1];
+ conf->country[2] = ' ';
+ wpa_s->mesh_params->handle_dfs = 1;
}
@@ -1,28 +1,42 @@
-From bdc77efe681d5b88f3256e2bb6e706d4eaf09518 Mon Sep 17 00:00:00 2001
+From 2564184440d9d6041d11a8c7d50b31368634c3bd Mon Sep 17 00:00:00 2001
From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:11 -0700
-Subject: [PATCH 07/18] mesh: apply channel attributes before running Mesh
+Date: Mon, 27 Aug 2018 14:28:40 -0700
+Subject: [PATCH] mesh: Apply channel attributes before setup interface
-This helps mesh interface initializes with correct
-channel parameters.
+This helps mesh interface initialization with correct channel
+parameters.
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
---
- wpa_supplicant/mesh.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
+ wpa_supplicant/mesh.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
-@@ -338,6 +338,8 @@ static int wpa_supplicant_mesh_init(stru
+@@ -248,7 +248,7 @@ static int wpa_supplicant_mesh_init(stru
+ struct mesh_conf *mconf;
+ int basic_rates_erp[] = { 10, 20, 55, 60, 110, 120, 240, -1 };
+ int rate_len;
+- int frequency;
++ int frequency, saved_freq;
+
+ if (!wpa_s->conf->user_mpm) {
+ /* not much for us to do here */
+@@ -385,6 +385,13 @@ static int wpa_supplicant_mesh_init(stru
conf->basic_rates[rate_len] = -1;
}
++ /* Handle pri/sec switch frequency within AP configuration parameter
++ * generation without changing the stored network profile in the end. */
++ saved_freq = ssid->frequency;
++ ssid->frequency = frequency;
+ wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf);
++ ssid->frequency = saved_freq;
+
- if (hostapd_setup_interface(ifmsh)) {
- wpa_printf(MSG_ERROR,
- "Failed to initialize hostapd interface for mesh");
-@@ -349,8 +351,6 @@ static int wpa_supplicant_mesh_init(stru
+ if (wpa_drv_init_mesh(wpa_s)) {
+ wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh in driver");
+ return -1;
+@@ -396,8 +403,6 @@ static int wpa_supplicant_mesh_init(stru
return -1;
}
deleted file mode 100644
@@ -1,36 +0,0 @@
-From eb9888ba41faaeb8fd07392ad46808b7d894cc14 Mon Sep 17 00:00:00 2001
-From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:12 -0700
-Subject: [PATCH 08/18] mesh: set interface type to mesh before setting
- interface
-
-Correct interface type is required to start DFS CAC that can be
-triggered during interface setup.
-
-Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
----
- wpa_supplicant/mesh.c | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
---- a/wpa_supplicant/mesh.c
-+++ b/wpa_supplicant/mesh.c
-@@ -340,14 +340,14 @@ static int wpa_supplicant_mesh_init(stru
-
- wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf);
-
-- if (hostapd_setup_interface(ifmsh)) {
-- wpa_printf(MSG_ERROR,
-- "Failed to initialize hostapd interface for mesh");
-+ if (wpa_drv_init_mesh(wpa_s)) {
-+ wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh in driver");
- return -1;
- }
-
-- if (wpa_drv_init_mesh(wpa_s)) {
-- wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh in driver");
-+ if (hostapd_setup_interface(ifmsh)) {
-+ wpa_printf(MSG_ERROR,
-+ "Failed to initialize hostapd interface for mesh");
- return -1;
- }
-
deleted file mode 100644
@@ -1,22 +0,0 @@
-From fa3af966032267e618b19bbf06a536ddb81ddbdf Mon Sep 17 00:00:00 2001
-From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:13 -0700
-Subject: [PATCH 09/18] mesh: set mesh center frequency
-
-vht center frequency value is required to compose the correct channel info.
-
-Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
----
- wpa_supplicant/mesh.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/wpa_supplicant/mesh.c
-+++ b/wpa_supplicant/mesh.c
-@@ -457,6 +457,7 @@ int wpa_supplicant_join_mesh(struct wpa_
-
- if (wpa_s->mesh_vht_enabled) {
- ssid->vht = 1;
-+ ssid->vht_center_freq1 = params->freq.center_freq1;
- switch (params->freq.bandwidth) {
- case 80:
- if (params->freq.center_freq2) {
deleted file mode 100644
@@ -1,176 +0,0 @@
-From 9a8ca54a264a2820af614043e7af853166b320b0 Mon Sep 17 00:00:00 2001
-From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:14 -0700
-Subject: [PATCH 10/18] mesh: consider mesh interface on dfs event handler
-
-Once mesh starts supporting DFS channels, it has to handle DFS related events
-from drivers, hence add mesh interface to the check list.
-
-Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
-Signed-off-by: Masashi Honma <masashi.honma@gmail.com>
----
- wpa_supplicant/ap.c | 71 ++++++++++++++++++++++++++++++-----------
- wpa_supplicant/events.c | 7 ++--
- 2 files changed, 57 insertions(+), 21 deletions(-)
-
---- a/wpa_supplicant/ap.c
-+++ b/wpa_supplicant/ap.c
-@@ -1379,13 +1379,18 @@ int ap_ctrl_iface_chanswitch(struct wpa_
- void wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht,
- int offset, int width, int cf1, int cf2)
- {
-- if (!wpa_s->ap_iface)
-- return;
-+ struct hostapd_iface *iface = wpa_s->ap_iface;
-
-+ if (!wpa_s->ap_iface) {
-+ if (!wpa_s->ifmsh)
-+ return;
-+ else
-+ iface = wpa_s->ifmsh;
-+ }
- wpa_s->assoc_freq = freq;
- if (wpa_s->current_ssid)
- wpa_s->current_ssid->frequency = freq;
-- hostapd_event_ch_switch(wpa_s->ap_iface->bss[0], freq, ht,
-+ hostapd_event_ch_switch(iface->bss[0], freq, ht,
- offset, width, cf1, cf2);
- }
-
-@@ -1582,10 +1587,16 @@ int wpas_ap_pmksa_cache_add_external(str
- void wpas_ap_event_dfs_radar_detected(struct wpa_supplicant *wpa_s,
- struct dfs_event *radar)
- {
-- if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
-- return;
-+ struct hostapd_iface *iface = wpa_s->ap_iface;
-+
-+ if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) {
-+ if (!wpa_s->ifmsh || !wpa_s->ifmsh->bss[0])
-+ return;
-+ else
-+ iface = wpa_s->ifmsh;
-+ }
- wpa_printf(MSG_DEBUG, "DFS radar detected on %d MHz", radar->freq);
-- hostapd_dfs_radar_detected(wpa_s->ap_iface, radar->freq,
-+ hostapd_dfs_radar_detected(iface, radar->freq,
- radar->ht_enabled, radar->chan_offset,
- radar->chan_width,
- radar->cf1, radar->cf2);
-@@ -1595,10 +1606,16 @@ void wpas_ap_event_dfs_radar_detected(st
- void wpas_ap_event_dfs_cac_started(struct wpa_supplicant *wpa_s,
- struct dfs_event *radar)
- {
-- if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
-- return;
-+ struct hostapd_iface *iface = wpa_s->ap_iface;
-+
-+ if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) {
-+ if (!wpa_s->ifmsh || !wpa_s->ifmsh->bss[0])
-+ return;
-+ else
-+ iface = wpa_s->ifmsh;
-+ }
- wpa_printf(MSG_DEBUG, "DFS CAC started on %d MHz", radar->freq);
-- hostapd_dfs_start_cac(wpa_s->ap_iface, radar->freq,
-+ hostapd_dfs_start_cac(iface, radar->freq,
- radar->ht_enabled, radar->chan_offset,
- radar->chan_width, radar->cf1, radar->cf2);
- }
-@@ -1607,10 +1624,16 @@ void wpas_ap_event_dfs_cac_started(struc
- void wpas_ap_event_dfs_cac_finished(struct wpa_supplicant *wpa_s,
- struct dfs_event *radar)
- {
-- if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
-- return;
-+ struct hostapd_iface *iface = wpa_s->ap_iface;
-+
-+ if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) {
-+ if (!wpa_s->ifmsh || !wpa_s->ifmsh->bss[0])
-+ return;
-+ else
-+ iface = wpa_s->ifmsh;
-+ }
- wpa_printf(MSG_DEBUG, "DFS CAC finished on %d MHz", radar->freq);
-- hostapd_dfs_complete_cac(wpa_s->ap_iface, 1, radar->freq,
-+ hostapd_dfs_complete_cac(iface, 1, radar->freq,
- radar->ht_enabled, radar->chan_offset,
- radar->chan_width, radar->cf1, radar->cf2);
- }
-@@ -1619,10 +1642,16 @@ void wpas_ap_event_dfs_cac_finished(stru
- void wpas_ap_event_dfs_cac_aborted(struct wpa_supplicant *wpa_s,
- struct dfs_event *radar)
- {
-- if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
-- return;
-+ struct hostapd_iface *iface = wpa_s->ap_iface;
-+
-+ if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) {
-+ if (!wpa_s->ifmsh || !wpa_s->ifmsh->bss[0])
-+ return;
-+ else
-+ iface = wpa_s->ifmsh;
-+ }
- wpa_printf(MSG_DEBUG, "DFS CAC aborted on %d MHz", radar->freq);
-- hostapd_dfs_complete_cac(wpa_s->ap_iface, 0, radar->freq,
-+ hostapd_dfs_complete_cac(iface, 0, radar->freq,
- radar->ht_enabled, radar->chan_offset,
- radar->chan_width, radar->cf1, radar->cf2);
- }
-@@ -1631,10 +1660,16 @@ void wpas_ap_event_dfs_cac_aborted(struc
- void wpas_ap_event_dfs_cac_nop_finished(struct wpa_supplicant *wpa_s,
- struct dfs_event *radar)
- {
-- if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
-- return;
-+ struct hostapd_iface *iface = wpa_s->ap_iface;
-+
-+ if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) {
-+ if (!wpa_s->ifmsh || !wpa_s->ifmsh->bss[0])
-+ return;
-+ else
-+ iface = wpa_s->ifmsh;
-+ }
- wpa_printf(MSG_DEBUG, "DFS NOP finished on %d MHz", radar->freq);
-- hostapd_dfs_nop_finished(wpa_s->ap_iface, radar->freq,
-+ hostapd_dfs_nop_finished(iface, radar->freq,
- radar->ht_enabled, radar->chan_offset,
- radar->chan_width, radar->cf1, radar->cf2);
- }
---- a/wpa_supplicant/events.c
-+++ b/wpa_supplicant/events.c
-@@ -3840,7 +3840,7 @@ static void wpas_event_dfs_cac_started(s
- struct dfs_event *radar)
- {
- #if defined(NEED_AP_MLME) && defined(CONFIG_AP)
-- if (wpa_s->ap_iface) {
-+ if (wpa_s->ap_iface || wpa_s->ifmsh) {
- wpas_ap_event_dfs_cac_started(wpa_s, radar);
- } else
- #endif /* NEED_AP_MLME && CONFIG_AP */
-@@ -3861,7 +3861,7 @@ static void wpas_event_dfs_cac_finished(
- struct dfs_event *radar)
- {
- #if defined(NEED_AP_MLME) && defined(CONFIG_AP)
-- if (wpa_s->ap_iface) {
-+ if (wpa_s->ap_iface || wpa_s->ifmsh) {
- wpas_ap_event_dfs_cac_finished(wpa_s, radar);
- } else
- #endif /* NEED_AP_MLME && CONFIG_AP */
-@@ -3877,7 +3877,7 @@ static void wpas_event_dfs_cac_aborted(s
- struct dfs_event *radar)
- {
- #if defined(NEED_AP_MLME) && defined(CONFIG_AP)
-- if (wpa_s->ap_iface) {
-+ if (wpa_s->ap_iface || wpa_s->ifmsh) {
- wpas_ap_event_dfs_cac_aborted(wpa_s, radar);
- } else
- #endif /* NEED_AP_MLME && CONFIG_AP */
-@@ -4328,6 +4328,7 @@ void wpa_supplicant_event(void *ctx, enu
- #ifdef CONFIG_AP
- if (wpa_s->current_ssid->mode == WPAS_MODE_AP ||
- wpa_s->current_ssid->mode == WPAS_MODE_P2P_GO ||
-+ wpa_s->current_ssid->mode == WPAS_MODE_MESH ||
- wpa_s->current_ssid->mode ==
- WPAS_MODE_P2P_GROUP_FORMATION) {
- wpas_ap_ch_switch(wpa_s, data->ch_switch.freq,
@@ -1,8 +1,7 @@
-From bbaa6142eadf229334436fdbf51aa65bb819f771 Mon Sep 17 00:00:00 2001
+From 89fa0d75fb1be82330258082ed3d7fd452eb6076 Mon Sep 17 00:00:00 2001
From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:15 -0700
-Subject: [PATCH 11/18] mesh: Allow DFS channels to be selected if dfs is
- enabled
+Date: Mon, 27 Aug 2018 14:28:45 -0700
+Subject: [PATCH 3/7] mesh: Allow DFS channels to be selected if dfs is enabled
Note: DFS is assumed to be usable if a country code has been set
@@ -14,7 +13,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
-@@ -2090,6 +2090,8 @@ void ibss_mesh_setup_freq(struct wpa_sup
+@@ -2148,6 +2148,8 @@ void ibss_mesh_setup_freq(struct wpa_sup
struct hostapd_freq_params vht_freq;
int chwidth, seg0, seg1;
u32 vht_caps = 0;
@@ -23,7 +22,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
freq->freq = ssid->frequency;
-@@ -2166,8 +2168,11 @@ void ibss_mesh_setup_freq(struct wpa_sup
+@@ -2224,8 +2226,11 @@ void ibss_mesh_setup_freq(struct wpa_sup
return;
/* Check primary channel flags */
@@ -34,9 +33,9 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
+ if (!dfs_enabled)
+ return;
- #ifdef CONFIG_HT_OVERRIDES
- if (ssid->disable_ht40)
-@@ -2193,8 +2198,11 @@ void ibss_mesh_setup_freq(struct wpa_sup
+ freq->channel = pri_chan->chan;
+
+@@ -2256,8 +2261,11 @@ void ibss_mesh_setup_freq(struct wpa_sup
return;
/* Check secondary channel flags */
@@ -47,9 +46,9 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
+ if (!dfs_enabled)
+ return;
- freq->channel = pri_chan->chan;
-
-@@ -2284,8 +2292,11 @@ void ibss_mesh_setup_freq(struct wpa_sup
+ if (ht40 == -1) {
+ if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS))
+@@ -2348,8 +2356,11 @@ skip_ht40:
return;
/* Back to HT configuration if channel not usable */
@@ -62,7 +61,7 @@ Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
}
chwidth = VHT_CHANWIDTH_80MHZ;
-@@ -2305,10 +2316,11 @@ void ibss_mesh_setup_freq(struct wpa_sup
+@@ -2369,10 +2380,11 @@ skip_ht40:
if (!chan)
continue;
@@ -1,27 +1,29 @@
-From 267395271c1a36b54ef21070acff2cadce241035 Mon Sep 17 00:00:00 2001
+From 4f4a9b9e2e61fba334a21dadea749e4b440f42e6 Mon Sep 17 00:00:00 2001
From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:17 -0700
-Subject: [PATCH 13/18] mesh: do not allow pri/sec channel switch
+Date: Mon, 27 Aug 2018 14:28:48 -0700
+Subject: [PATCH 6/7] mesh: don't allow pri/sec channel switch
-We don't want mesh to switch the channel from primary to secondary,
-since mesh points are not able to join each other in that case.
+This limitation isn't backed by standard, but it is known that
+mesh doesn't have capability to handle 20/40 coex change in
+current implementation and it will not able to establish
+PLINK when channel switch between primary and secondary happens.
+
+Since it's unknown when we will have the implementation of handling
+20/40 coex change for mesh, it'd better to avoid them from happening
+until standard based implementation is introduced.
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
---
- wpa_supplicant/mesh.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
+ wpa_supplicant/mesh.c | 1 +
+ 1 file changed, 1 insertion(+)
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
-@@ -337,7 +337,10 @@ static int wpa_supplicant_mesh_init(stru
- rate_len * sizeof(int));
+@@ -385,6 +385,7 @@ static int wpa_supplicant_mesh_init(stru
conf->basic_rates[rate_len] = -1;
}
--
-+ /* Do not allow primary/secondary channel switch in mesh mode,
-+ * since mesh is not able to establish a physical link for it
-+ */
-+ conf->no_pri_sec_switch = 1;
- wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf);
- if (wpa_drv_init_mesh(wpa_s)) {
++ conf->no_pri_sec_switch = 1;
+ /* Handle pri/sec switch frequency within AP configuration parameter
+ * generation without changing the stored network profile in the end. */
+ saved_freq = ssid->frequency;
deleted file mode 100644
@@ -1,24 +0,0 @@
-From f95897cef614fff710c31d9e478eacc85d6312d5 Mon Sep 17 00:00:00 2001
-From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:18 -0700
-Subject: [PATCH 14/18] mesh: do not allow scan result to swap pri/sec
-
-Swapping between primary and secondary channel will break
-mesh from joining, hence don't allow it.
-
-Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
----
- wpa_supplicant/wpa_supplicant.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/wpa_supplicant/wpa_supplicant.c
-+++ b/wpa_supplicant/wpa_supplicant.c
-@@ -2215,7 +2215,7 @@ void ibss_mesh_setup_freq(struct wpa_sup
- }
- freq->sec_channel_offset = ht40;
-
-- if (obss_scan) {
-+ if (ssid->mode != WPAS_MODE_MESH && obss_scan) {
- struct wpa_scan_results *scan_res;
-
- scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
@@ -1,44 +1,56 @@
-From 9423e8be0393e82c8622806a0529e47fd5583c0b Mon Sep 17 00:00:00 2001
+From 71e9c65a7c8af90a5fd11072062b596421316452 Mon Sep 17 00:00:00 2001
From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:19 -0700
-Subject: [PATCH 15/18] mesh: do not use offchan mgmt tx on DFS
+Date: Mon, 27 Aug 2018 14:28:46 -0700
+Subject: [PATCH 4/7] mesh: do not set offchanok on DFS channels in non-ETSI
-Drivers don't allow mesh to use offchannel on management Tx.
+mac80211 does not allow mgmt tx to use off channel on
+DFS channels in non-ETSI domain, because it will invalidate
+CAC result on current operating channel.
+(mac80211 commit: 34373d12f3cbb74960a73431138ef619d857996f)
+Hence don't set offchanok for mgmt tx in case of DFS channels
+in non-ETSI.
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-[daniel@makrotopia.org: adapted to changed ieee80211_is_dfs prototype]
---
- src/drivers/driver_nl80211.c | 12 ++++++++++--
- 1 file changed, 10 insertions(+), 2 deletions(-)
+ src/drivers/driver_nl80211.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
-@@ -7268,6 +7268,10 @@ static int wpa_driver_nl80211_send_actio
- struct wpa_driver_nl80211_data *drv = bss->drv;
+@@ -7411,6 +7411,10 @@ static int wpa_driver_nl80211_send_actio
int ret = -1;
u8 *buf;
-+ int offchanok = 1;
-+ u16 num_modes, flags;
+ struct ieee80211_hdr *hdr;
+ struct hostapd_hw_modes *modes;
++ int i, offchanok = 1;
++ u16 num_modes, flags;
+ u8 dfs_domain;
- struct ieee80211_hdr *hdr;
wpa_printf(MSG_DEBUG, "nl80211: Send Action frame (ifindex=%d, "
-@@ -7292,7 +7296,11 @@ static int wpa_driver_nl80211_send_actio
- } else {
+ "freq=%u MHz wait=%d ms no_cck=%d)",
+@@ -7435,6 +7439,21 @@ static int wpa_driver_nl80211_send_actio
os_memset(bss->rand_addr, 0, ETH_ALEN);
}
--
-+ if (is_mesh_interface(drv->nlmode) &&
-+ (modes = nl80211_get_hw_feature_data(bss, &num_modes, &flags,
-+ &dfs_domain)) &&
-+ ieee80211_is_dfs(freq, modes, num_modes))
-+ offchanok = 0;
+
++ if (is_mesh_interface(drv->nlmode)) {
++ modes = nl80211_get_hw_feature_data(bss, &num_modes,
++ &flags, &dfs_domain);
++ if (dfs_domain != HOSTAPD_DFS_REGION_ETSI &&
++ ieee80211_is_dfs(bss->freq, modes, num_modes))
++ offchanok = 0;
++ if (modes) {
++ for (i = 0; i < num_modes; i++) {
++ os_free(modes[i].channels);
++ os_free(modes[i].rates);
++ }
++ os_free(modes);
++ }
++ }
++
if (is_ap_interface(drv->nlmode) &&
(!(drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) ||
(int) freq == bss->freq || drv->device_ap_sme ||
-@@ -7304,7 +7312,7 @@ static int wpa_driver_nl80211_send_actio
+@@ -7446,7 +7465,7 @@ static int wpa_driver_nl80211_send_actio
ret = nl80211_send_frame_cmd(bss, freq, wait_time, buf,
24 + data_len,
&drv->send_action_cookie,
@@ -1,7 +1,7 @@
-From fa9d565fe8841b288f29137c23a7ab2584dd9510 Mon Sep 17 00:00:00 2001
+From 5913d6e2a741683e7c747c046f72ca790bbe1337 Mon Sep 17 00:00:00 2001
From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:20 -0700
-Subject: [PATCH 16/18] mesh: fix channel switch error during CAC
+Date: Mon, 27 Aug 2018 14:28:47 -0700
+Subject: [PATCH 5/7] mesh: fix channel switch error during CAC
Mesh interface has used its channel parameters that configured
during its initialization even after channel switched due to
@@ -10,30 +10,23 @@ This change fixes the error by updating its channel parameters
when channel's been changed from initial one.
Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-[daniel@makrotopia.org: added hw_features_common.h include]
---
wpa_supplicant/mesh.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
-@@ -11,6 +11,7 @@
- #include "utils/common.h"
- #include "utils/eloop.h"
+@@ -13,6 +13,7 @@
#include "utils/uuid.h"
-+#include "common/hw_features_common.h"
#include "common/ieee802_11_defs.h"
#include "common/wpa_ctrl.h"
++#include "common/hw_features_common.h"
#include "ap/sta_info.h"
-@@ -394,10 +395,35 @@ void wpa_supplicant_mesh_add_scan_ie(str
- void wpas_mesh_complete_cb(void *ctx)
- {
- struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)ctx;
-+ struct hostapd_iface *ifmsh = wpa_s->ifmsh;
- struct wpa_driver_mesh_join_params *params = wpa_s->mesh_params;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- int ret = 0;
+ #include "ap/hostapd.h"
+ #include "ap/ieee802_11.h"
+@@ -204,6 +205,30 @@ static void wpas_mesh_complete_cb(void *
+ return;
+ }
+ /*
+ * inspect if channel's been changed since initialized.
@@ -59,6 +52,6 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ }
+ }
+
- if (wpas_mesh_init_rsn(wpa_s)) {
- wpa_printf(MSG_ERROR, "Init RSN failed. Deinit mesh...");
- wpa_supplicant_mesh_deinit(wpa_s);
+ if (ifmsh->mconf->security != MESH_CONF_SEC_NONE &&
+ wpas_mesh_init_rsn(wpa_s)) {
+ wpa_printf(MSG_ERROR,
deleted file mode 100644
@@ -1,107 +0,0 @@
-From d3201adfe7d2219217a07ef16ef365ad59c1a89b Mon Sep 17 00:00:00 2001
-From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Tue, 29 May 2018 14:39:21 -0700
-Subject: [PATCH 17/18] mesh: use right interface context to send DFS event
- messages
-
-use mesh interface context to send DFS event messages when
-DFS events are on mesh interface.
-
-Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
-Signed-off-by: Masashi Honma <masashi.honma@gmail.com>
----
- src/ap/dfs.c | 27 +++++++++++++++++++--------
- 1 file changed, 19 insertions(+), 8 deletions(-)
-
---- a/src/ap/dfs.c
-+++ b/src/ap/dfs.c
-@@ -637,6 +637,17 @@ static unsigned int dfs_get_cac_time(str
- }
-
-
-+static void *get_message_ctx(struct hostapd_iface *iface)
-+{
-+#ifdef CONFIG_MESH
-+ if (iface->mconf)
-+ return iface->owner;
-+#endif /* CONFIG_MESH */
-+
-+ return iface->bss[0]->msg_ctx;
-+}
-+
-+
- /*
- * Main DFS handler
- * 1 - continue channel/ap setup
-@@ -719,7 +730,7 @@ int hostapd_handle_dfs(struct hostapd_if
- /* Finally start CAC */
- hostapd_set_state(iface, HAPD_IFACE_DFS);
- wpa_printf(MSG_DEBUG, "DFS start CAC on %d MHz", iface->freq);
-- wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_START
-+ wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_CAC_START
- "freq=%d chan=%d sec_chan=%d, width=%d, seg0=%d, seg1=%d, cac_time=%ds",
- iface->freq,
- iface->conf->channel, iface->conf->secondary_channel,
-@@ -768,7 +779,7 @@ int hostapd_dfs_complete_cac(struct host
- int ht_enabled, int chan_offset, int chan_width,
- int cf1, int cf2)
- {
-- wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_COMPLETED
-+ wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_CAC_COMPLETED
- "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);
-
-@@ -810,7 +821,7 @@ int hostapd_dfs_pre_cac_expired(struct h
- int ht_enabled, int chan_offset, int chan_width,
- int cf1, int cf2)
- {
-- wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_PRE_CAC_EXPIRED
-+ wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_PRE_CAC_EXPIRED
- "freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d",
- freq, ht_enabled, chan_offset, chan_width, cf1, cf2);
-
-@@ -848,7 +859,7 @@ static int hostapd_dfs_start_channel_swi
-
- wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d",
- channel->chan);
-- wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NEW_CHANNEL
-+ wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_NEW_CHANNEL
- "freq=%d chan=%d sec_chan=%d", channel->freq,
- channel->chan, secondary_channel);
-
-@@ -935,7 +946,7 @@ static int hostapd_dfs_start_channel_swi
-
- wpa_printf(MSG_DEBUG, "DFS will switch to a new channel %d",
- channel->chan);
-- wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NEW_CHANNEL
-+ wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_NEW_CHANNEL
- "freq=%d chan=%d sec_chan=%d", channel->freq,
- channel->chan, secondary_channel);
-
-@@ -997,7 +1008,7 @@ int hostapd_dfs_radar_detected(struct ho
- {
- int res;
-
-- wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_RADAR_DETECTED
-+ wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_RADAR_DETECTED
- "freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d",
- freq, ht_enabled, chan_offset, chan_width, cf1, cf2);
-
-@@ -1028,7 +1039,7 @@ int hostapd_dfs_nop_finished(struct host
- int ht_enabled, int chan_offset, int chan_width,
- int cf1, int cf2)
- {
-- wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_NOP_FINISHED
-+ wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_NOP_FINISHED
- "freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d",
- freq, ht_enabled, chan_offset, chan_width, cf1, cf2);
-
-@@ -1078,7 +1089,7 @@ int hostapd_dfs_start_cac(struct hostapd
- int ht_enabled, int chan_offset, int chan_width,
- int cf1, int cf2)
- {
-- wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_CAC_START
-+ wpa_msg(get_message_ctx(iface), MSG_INFO, DFS_EVENT_CAC_START
- "freq=%d chan=%d chan_offset=%d width=%d seg0=%d "
- "seg1=%d cac_time=%ds",
- freq, (freq - 5000) / 5, chan_offset, chan_width, cf1, cf2, 60);
@@ -23,7 +23,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
-@@ -49,6 +49,7 @@ struct mesh_conf {
+@@ -50,6 +50,7 @@ struct mesh_conf {
int dot11MeshRetryTimeout; /* msec */
int dot11MeshConfirmTimeout; /* msec */
int dot11MeshHoldingTimeout; /* msec */
@@ -31,7 +31,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
};
#define MAX_STA_COUNT 2007
-@@ -628,6 +629,7 @@ struct hostapd_bss_config {
+@@ -645,6 +646,7 @@ struct hostapd_bss_config {
#define MESH_ENABLED BIT(0)
int mesh;
@@ -41,7 +41,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
-@@ -1375,6 +1375,7 @@ struct wpa_driver_mesh_bss_params {
+@@ -1409,6 +1409,7 @@ struct wpa_driver_mesh_bss_params {
#define WPA_DRIVER_MESH_CONF_FLAG_MAX_PEER_LINKS 0x00000004
#define WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE 0x00000008
#define WPA_DRIVER_MESH_CONF_FLAG_RSSI_THRESHOLD 0x00000010
@@ -49,7 +49,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
/*
* TODO: Other mesh configuration parameters would go here.
* See NL80211_MESHCONF_* for all the mesh config parameters.
-@@ -1384,6 +1385,7 @@ struct wpa_driver_mesh_bss_params {
+@@ -1418,6 +1419,7 @@ struct wpa_driver_mesh_bss_params {
int peer_link_timeout;
int max_peer_links;
int rssi_threshold;
@@ -59,7 +59,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
-@@ -9332,6 +9332,9 @@ static int nl80211_put_mesh_config(struc
+@@ -9512,6 +9512,9 @@ static int nl80211_put_mesh_config(struc
if (((params->flags & WPA_DRIVER_MESH_CONF_FLAG_AUTO_PLINKS) &&
nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
params->auto_plinks)) ||
@@ -71,7 +71,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
params->max_peer_links)) ||
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
-@@ -2228,6 +2228,7 @@ static const struct parse_data ssid_fiel
+@@ -2307,6 +2307,7 @@ static const struct parse_data ssid_fiel
#ifdef CONFIG_MESH
{ INT_RANGE(mode, 0, 5) },
{ INT_RANGE(no_auto_peer, 0, 1) },
@@ -79,7 +79,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
{ INT_RANGE(mesh_rssi_threshold, -255, 1) },
#else /* CONFIG_MESH */
{ INT_RANGE(mode, 0, 4) },
-@@ -2779,6 +2780,7 @@ void wpa_config_set_network_defaults(str
+@@ -2868,6 +2869,7 @@ void wpa_config_set_network_defaults(str
ssid->dot11MeshRetryTimeout = DEFAULT_MESH_RETRY_TIMEOUT;
ssid->dot11MeshConfirmTimeout = DEFAULT_MESH_CONFIRM_TIMEOUT;
ssid->dot11MeshHoldingTimeout = DEFAULT_MESH_HOLDING_TIMEOUT;
@@ -87,7 +87,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
ssid->mesh_rssi_threshold = DEFAULT_MESH_RSSI_THRESHOLD;
#endif /* CONFIG_MESH */
#ifdef CONFIG_HT_OVERRIDES
-@@ -3996,6 +3998,7 @@ struct wpa_config * wpa_config_alloc_emp
+@@ -4088,6 +4090,7 @@ struct wpa_config * wpa_config_alloc_emp
config->user_mpm = DEFAULT_USER_MPM;
config->max_peer_links = DEFAULT_MAX_PEER_LINKS;
config->mesh_max_inactivity = DEFAULT_MESH_MAX_INACTIVITY;
@@ -95,7 +95,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
config->dot11RSNASAERetransPeriod =
DEFAULT_DOT11_RSNA_SAE_RETRANS_PERIOD;
config->fast_reauth = DEFAULT_FAST_REAUTH;
-@@ -4618,6 +4621,7 @@ static const struct global_parse_data gl
+@@ -4725,6 +4728,7 @@ static const struct global_parse_data gl
{ INT(user_mpm), 0 },
{ INT_RANGE(max_peer_links, 0, 255), 0 },
{ INT(mesh_max_inactivity), 0 },
@@ -113,7 +113,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
/*
* The default dot11RSNASAERetransPeriod is defined as 40 ms in the standard,
* but use 1000 ms in practice to avoid issues on low power CPUs.
-@@ -1306,6 +1307,14 @@ struct wpa_config {
+@@ -1326,6 +1327,14 @@ struct wpa_config {
int mesh_max_inactivity;
/**
@@ -130,7 +130,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
* This timeout value is used in mesh STA to retransmit
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
-@@ -818,6 +818,7 @@ static void wpa_config_write_network(FIL
+@@ -829,6 +829,7 @@ static void wpa_config_write_network(FIL
#endif /* IEEE8021X_EAPOL */
INT(mode);
INT(no_auto_peer);
@@ -138,7 +138,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
INT(frequency);
INT(fixed_freq);
#ifdef CONFIG_ACS
-@@ -1450,6 +1451,9 @@ static void wpa_config_write_global(FILE
+@@ -1471,6 +1472,9 @@ static void wpa_config_write_global(FILE
fprintf(f, "mesh_max_inactivity=%d\n",
config->mesh_max_inactivity);
@@ -150,7 +150,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
fprintf(f, "dot11RSNASAERetransPeriod=%d\n",
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
-@@ -500,6 +500,11 @@ struct wpa_ssid {
+@@ -514,6 +514,11 @@ struct wpa_ssid {
int dot11MeshConfirmTimeout; /* msec */
int dot11MeshHoldingTimeout; /* msec */
@@ -164,7 +164,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
-@@ -121,6 +121,7 @@ static struct mesh_conf * mesh_config_cr
+@@ -126,6 +126,7 @@ static struct mesh_conf * mesh_config_cr
conf->mesh_cc_id = 0;
conf->mesh_sp_id = MESH_SYNC_METHOD_NEIGHBOR_OFFSET;
conf->mesh_auth_id = (conf->security & MESH_CONF_SEC_AUTH) ? 1 : 0;
@@ -172,7 +172,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
conf->dot11MeshMaxRetries = ssid->dot11MeshMaxRetries;
conf->dot11MeshRetryTimeout = ssid->dot11MeshRetryTimeout;
conf->dot11MeshConfirmTimeout = ssid->dot11MeshConfirmTimeout;
-@@ -256,6 +257,7 @@ static int wpa_supplicant_mesh_init(stru
+@@ -325,6 +326,7 @@ static int wpa_supplicant_mesh_init(stru
bss->conf->start_disabled = 1;
bss->conf->mesh = MESH_ENABLED;
bss->conf->ap_max_inactivity = wpa_s->conf->mesh_max_inactivity;
@@ -180,7 +180,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
if (ieee80211_is_dfs(ssid->frequency, wpa_s->hw.modes,
wpa_s->hw.num_modes) && wpa_s->conf->country[0]) {
-@@ -534,6 +536,10 @@ int wpa_supplicant_join_mesh(struct wpa_
+@@ -543,6 +545,10 @@ int wpa_supplicant_join_mesh(struct wpa_
}
params->conf.peer_link_timeout = wpa_s->conf->mesh_max_inactivity;
@@ -188,12 +188,12 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+ params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_FORWARDING;
+ params->conf.forwarding = ssid->mesh_fwding;
+
+ os_free(wpa_s->mesh_params);
wpa_s->mesh_params = params;
if (wpa_supplicant_mesh_init(wpa_s, ssid, ¶ms->freq)) {
- wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh");
--- a/wpa_supplicant/mesh_mpm.c
+++ b/wpa_supplicant/mesh_mpm.c
-@@ -289,9 +289,9 @@ static void mesh_mpm_send_plink_action(s
+@@ -295,9 +295,9 @@ static void mesh_mpm_send_plink_action(s
info = (bss->num_plinks > 63 ? 63 : bss->num_plinks) << 1;
/* TODO: Add Connected to Mesh Gate/AS subfields */
wpabuf_put_u8(buf, info);
deleted file mode 100644
@@ -1,49 +0,0 @@
-From 838225f2319348e430b553fd9bb3680bd7434ae3 Mon Sep 17 00:00:00 2001
-From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Wed, 18 Apr 2018 14:14:18 -0700
-Subject: [PATCH 1/2] mesh: add VHT_CHANWIDTH_USE_HT to max_oper_chwidth
-
-Channel width in VHT mode refers HT capability when
-the width goes down to below 80MHz, hence add checking
-HT channel width to its max operation channel width.
-So that mesh has capable to select bandwidth below 80Mhz.
-
-Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
----
- wpa_supplicant/config.c | 1 +
- wpa_supplicant/config_ssid.h | 1 +
- wpa_supplicant/wpa_supplicant.c | 3 +++
- 3 files changed, 5 insertions(+)
-
---- a/wpa_supplicant/config.c
-+++ b/wpa_supplicant/config.c
-@@ -2818,6 +2818,7 @@ void wpa_config_set_network_defaults(str
- ssid->mka_priority = DEFAULT_PRIO_NOT_KEY_SERVER;
- #endif /* CONFIG_MACSEC */
- ssid->mac_addr = -1;
-+ ssid->max_oper_chwidth = (u8)DEFAULT_MAX_OPER_CHWIDTH;
- }
-
-
---- a/wpa_supplicant/config_ssid.h
-+++ b/wpa_supplicant/config_ssid.h
-@@ -37,6 +37,7 @@
- #define DEFAULT_AMPDU_FACTOR -1 /* no change */
- #define DEFAULT_AMPDU_DENSITY -1 /* no change */
- #define DEFAULT_USER_SELECTED_SIM 1
-+#define DEFAULT_MAX_OPER_CHWIDTH -1
-
- struct psk_list_entry {
- struct dl_list list;
---- a/wpa_supplicant/wpa_supplicant.c
-+++ b/wpa_supplicant/wpa_supplicant.c
-@@ -2342,6 +2342,9 @@ void ibss_mesh_setup_freq(struct wpa_sup
- vht_caps |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
- seg0 = 114;
- }
-+ } else if (ssid->max_oper_chwidth == VHT_CHANWIDTH_USE_HT) {
-+ chwidth = VHT_CHANWIDTH_USE_HT;
-+ seg0 = vht80[j] + 2;
- }
-
- if (hostapd_set_freq_params(&vht_freq, mode->mode, freq->freq,
deleted file mode 100644
@@ -1,82 +0,0 @@
-From 24fc73b2470ff79cd8c92e029ca785c8e95a204c Mon Sep 17 00:00:00 2001
-From: Peter Oh <peter.oh@bowerswilkins.com>
-Date: Wed, 18 Apr 2018 14:14:19 -0700
-Subject: [PATCH 2/2] mesh: implement use of VHT20 config in mesh mode
-
-mesh in VHT mode is supposed to be able to use any bandwidth
-that 11ac supports, but we don't have a way to set VHT20
-although there are parameters that are supposed to be used.
-This patch along with the patch of
-"mesh: add VHT_CHANWIDTH_USE_HT to max_oper_chwidth" makes mesh
-available to use of any bandwidth using combination of
-existing parameters like below shown.
-
-VHT80:
- default
- do not set any parameters
-VHT40:
- max_oper_chwidth = 0
-VHT20:
- max_oper_chwidth=0
- disable_ht40=1
-HT40:
- disable_vht = 1
-HT20:
- disable_ht40 = 1
-disable HT:
- disable_ht = 1
-
-Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
----
- wpa_supplicant/wpa_supplicant.c | 18 +++++++++++++-----
- 1 file changed, 13 insertions(+), 5 deletions(-)
-
---- a/wpa_supplicant/wpa_supplicant.c
-+++ b/wpa_supplicant/wpa_supplicant.c
-@@ -2174,9 +2174,15 @@ void ibss_mesh_setup_freq(struct wpa_sup
- if (!dfs_enabled)
- return;
-
-+ freq->channel = pri_chan->chan;
-+
- #ifdef CONFIG_HT_OVERRIDES
-- if (ssid->disable_ht40)
-- return;
-+ if (ssid->disable_ht40) {
-+ if (ssid->disable_vht)
-+ return;
-+ else
-+ goto skip_ht40;
-+ }
- #endif /* CONFIG_HT_OVERRIDES */
-
- /* Check/setup HT40+/HT40- */
-@@ -2204,8 +2210,6 @@ void ibss_mesh_setup_freq(struct wpa_sup
- if (!dfs_enabled)
- return;
-
-- freq->channel = pri_chan->chan;
--
- if (ht40 == -1) {
- if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS))
- return;
-@@ -2249,6 +2253,7 @@ void ibss_mesh_setup_freq(struct wpa_sup
- wpa_scan_results_free(scan_res);
- }
-
-+skip_ht40:
- wpa_printf(MSG_DEBUG,
- "IBSS/mesh: setup freq channel %d, sec_channel_offset %d",
- freq->channel, freq->sec_channel_offset);
-@@ -2344,7 +2349,10 @@ void ibss_mesh_setup_freq(struct wpa_sup
- }
- } else if (ssid->max_oper_chwidth == VHT_CHANWIDTH_USE_HT) {
- chwidth = VHT_CHANWIDTH_USE_HT;
-- seg0 = vht80[j] + 2;
-+ if (ssid->disable_ht40)
-+ seg0 = 0;
-+ else
-+ seg0 = vht80[j] + 2;
- }
-
- if (hostapd_set_freq_params(&vht_freq, mode->mode, freq->freq,
deleted file mode 100644
@@ -1,33 +0,0 @@
-From f2973fa39d6109f0f34969e91551a98dc340d537 Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <j@w1.fi>
-Date: Mon, 3 Dec 2018 12:00:26 +0200
-Subject: FT: Fix CONFIG_IEEE80211X=y build without CONFIG_FILS=y
-
-remove_ie() was defined within an ifdef CONFIG_FILS block while it is
-now needed even without CONFIG_FILS=y. Remove the CONFIG_FILS condition
-there.
-
-Fixes 8c41734e5de1 ("FT: Fix Reassociation Request IEs during FT protocol")
-Signed-off-by: Jouni Malinen <j@w1.fi>
----
- wpa_supplicant/sme.c | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/wpa_supplicant/sme.c
-+++ b/wpa_supplicant/sme.c
-@@ -1386,7 +1386,6 @@ void sme_event_auth(struct wpa_supplican
- }
-
-
--#ifdef CONFIG_FILS
- #ifdef CONFIG_IEEE80211R
- static void remove_ie(u8 *buf, size_t *len, u8 eid)
- {
-@@ -1401,7 +1400,6 @@ static void remove_ie(u8 *buf, size_t *l
- }
- }
- #endif /* CONFIG_IEEE80211R */
--#endif /* CONFIG_FILS */
-
-
- void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
@@ -14,7 +14,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/wpa_supplicant/mesh_mpm.c
+++ b/wpa_supplicant/mesh_mpm.c
-@@ -663,11 +663,12 @@ static struct sta_info * mesh_mpm_add_pe
+@@ -685,11 +685,12 @@ static struct sta_info * mesh_mpm_add_pe
}
sta = ap_get_sta(data, addr);
deleted file mode 100644
@@ -1,88 +0,0 @@
-From d42c477cc794163a3757956bbffca5cea000923c Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Tue, 26 Feb 2019 11:43:03 +0200
-Subject: [PATCH 01/14] OpenSSL: Use constant time operations for private
- bignums
-
-This helps in reducing measurable timing differences in operations
-involving private information. BoringSSL has removed BN_FLG_CONSTTIME
-and expects specific constant time functions to be called instead, so a
-bit different approach is needed depending on which library is used.
-
-The main operation that needs protection against side channel attacks is
-BN_mod_exp() that depends on private keys (the public key validation
-step in crypto_dh_derive_secret() is an exception that can use the
-faster version since it does not depend on private keys).
-
-crypto_bignum_div() is currently used only in SAE FFC case with not
-safe-prime groups and only with values that do not depend on private
-keys, so it is not critical to protect it.
-
-crypto_bignum_inverse() is currently used only in SAE FFC PWE
-derivation. The additional protection here is targeting only OpenSSL.
-BoringSSL may need conversion to using BN_mod_inverse_blinded().
-
-This is related to CVE-2019-9494 and CVE-2019-9495.
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/crypto/crypto_openssl.c | 20 +++++++++++++++-----
- 1 file changed, 15 insertions(+), 5 deletions(-)
-
---- a/src/crypto/crypto_openssl.c
-+++ b/src/crypto/crypto_openssl.c
-@@ -549,7 +549,8 @@ int crypto_mod_exp(const u8 *base, size_
- bn_result == NULL)
- goto error;
-
-- if (BN_mod_exp(bn_result, bn_base, bn_exp, bn_modulus, ctx) != 1)
-+ if (BN_mod_exp_mont_consttime(bn_result, bn_base, bn_exp, bn_modulus,
-+ ctx, NULL) != 1)
- goto error;
-
- *result_len = BN_bn2bin(bn_result, result);
-@@ -1295,8 +1296,9 @@ int crypto_bignum_exptmod(const struct c
- bnctx = BN_CTX_new();
- if (bnctx == NULL)
- return -1;
-- res = BN_mod_exp((BIGNUM *) d, (const BIGNUM *) a, (const BIGNUM *) b,
-- (const BIGNUM *) c, bnctx);
-+ res = BN_mod_exp_mont_consttime((BIGNUM *) d, (const BIGNUM *) a,
-+ (const BIGNUM *) b, (const BIGNUM *) c,
-+ bnctx, NULL);
- BN_CTX_free(bnctx);
-
- return res ? 0 : -1;
-@@ -1315,6 +1317,11 @@ int crypto_bignum_inverse(const struct c
- bnctx = BN_CTX_new();
- if (bnctx == NULL)
- return -1;
-+#ifdef OPENSSL_IS_BORINGSSL
-+ /* TODO: use BN_mod_inverse_blinded() ? */
-+#else /* OPENSSL_IS_BORINGSSL */
-+ BN_set_flags((BIGNUM *) a, BN_FLG_CONSTTIME);
-+#endif /* OPENSSL_IS_BORINGSSL */
- res = BN_mod_inverse((BIGNUM *) c, (const BIGNUM *) a,
- (const BIGNUM *) b, bnctx);
- BN_CTX_free(bnctx);
-@@ -1348,6 +1355,9 @@ int crypto_bignum_div(const struct crypt
- bnctx = BN_CTX_new();
- if (bnctx == NULL)
- return -1;
-+#ifndef OPENSSL_IS_BORINGSSL
-+ BN_set_flags((BIGNUM *) a, BN_FLG_CONSTTIME);
-+#endif /* OPENSSL_IS_BORINGSSL */
- res = BN_div((BIGNUM *) c, NULL, (const BIGNUM *) a,
- (const BIGNUM *) b, bnctx);
- BN_CTX_free(bnctx);
-@@ -1439,8 +1449,8 @@ int crypto_bignum_legendre(const struct
- /* exp = (p-1) / 2 */
- !BN_sub(exp, (const BIGNUM *) p, BN_value_one()) ||
- !BN_rshift1(exp, exp) ||
-- !BN_mod_exp(tmp, (const BIGNUM *) a, exp, (const BIGNUM *) p,
-- bnctx))
-+ !BN_mod_exp_mont_consttime(tmp, (const BIGNUM *) a, exp,
-+ (const BIGNUM *) p, bnctx, NULL))
- goto fail;
-
- if (BN_is_word(tmp, 1))
deleted file mode 100644
@@ -1,212 +0,0 @@
-From 6e34f618d37ddbb5854c42e2ad4fca83492fa7b7 Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Wed, 27 Feb 2019 18:38:30 +0200
-Subject: [PATCH 02/14] Add helper functions for constant time operations
-
-These functions can be used to help implement constant time operations
-for various cryptographic operations that must minimize externally
-observable differences in processing (both in timing and also in
-internal cache use, etc.).
-
-This is related to CVE-2019-9494 and CVE-2019-9495.
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/utils/const_time.h | 191 +++++++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 191 insertions(+)
- create mode 100644 src/utils/const_time.h
-
---- /dev/null
-+++ b/src/utils/const_time.h
-@@ -0,0 +1,191 @@
-+/*
-+ * Helper functions for constant time operations
-+ * Copyright (c) 2019, The Linux Foundation
-+ *
-+ * This software may be distributed under the terms of the BSD license.
-+ * See README for more details.
-+ *
-+ * These helper functions can be used to implement logic that needs to minimize
-+ * externally visible differences in execution path by avoiding use of branches,
-+ * avoiding early termination or other time differences, and forcing same memory
-+ * access pattern regardless of values.
-+ */
-+
-+#ifndef CONST_TIME_H
-+#define CONST_TIME_H
-+
-+
-+#if defined(__clang__)
-+#define NO_UBSAN_UINT_OVERFLOW \
-+ __attribute__((no_sanitize("unsigned-integer-overflow")))
-+#else
-+#define NO_UBSAN_UINT_OVERFLOW
-+#endif
-+
-+
-+/**
-+ * const_time_fill_msb - Fill all bits with MSB value
-+ * @val: Input value
-+ * Returns: Value with all the bits set to the MSB of the input val
-+ */
-+static inline unsigned int const_time_fill_msb(unsigned int val)
-+{
-+ /* Move the MSB to LSB and multiple by -1 to fill in all bits. */
-+ return (val >> (sizeof(val) * 8 - 1)) * ~0U;
-+}
-+
-+
-+/* Returns: -1 if val is zero; 0 if val is not zero */
-+static inline unsigned int const_time_is_zero(unsigned int val)
-+ NO_UBSAN_UINT_OVERFLOW
-+{
-+ /* Set MSB to 1 for 0 and fill rest of bits with the MSB value */
-+ return const_time_fill_msb(~val & (val - 1));
-+}
-+
-+
-+/* Returns: -1 if a == b; 0 if a != b */
-+static inline unsigned int const_time_eq(unsigned int a, unsigned int b)
-+{
-+ return const_time_is_zero(a ^ b);
-+}
-+
-+
-+/* Returns: -1 if a == b; 0 if a != b */
-+static inline u8 const_time_eq_u8(unsigned int a, unsigned int b)
-+{
-+ return (u8) const_time_eq(a, b);
-+}
-+
-+
-+/**
-+ * const_time_eq_bin - Constant time memory comparison
-+ * @a: First buffer to compare
-+ * @b: Second buffer to compare
-+ * @len: Number of octets to compare
-+ * Returns: -1 if buffers are equal, 0 if not
-+ *
-+ * This function is meant for comparing passwords or hash values where
-+ * difference in execution time or memory access pattern could provide external
-+ * observer information about the location of the difference in the memory
-+ * buffers. The return value does not behave like memcmp(), i.e.,
-+ * const_time_eq_bin() cannot be used to sort items into a defined order. Unlike
-+ * memcmp(), the execution time of const_time_eq_bin() does not depend on the
-+ * contents of the compared memory buffers, but only on the total compared
-+ * length.
-+ */
-+static inline unsigned int const_time_eq_bin(const void *a, const void *b,
-+ size_t len)
-+{
-+ const u8 *aa = a;
-+ const u8 *bb = b;
-+ size_t i;
-+ u8 res = 0;
-+
-+ for (i = 0; i < len; i++)
-+ res |= aa[i] ^ bb[i];
-+
-+ return const_time_is_zero(res);
-+}
-+
-+
-+/**
-+ * const_time_select - Constant time unsigned int selection
-+ * @mask: 0 (false) or -1 (true) to identify which value to select
-+ * @true_val: Value to select for the true case
-+ * @false_val: Value to select for the false case
-+ * Returns: true_val if mask == -1, false_val if mask == 0
-+ */
-+static inline unsigned int const_time_select(unsigned int mask,
-+ unsigned int true_val,
-+ unsigned int false_val)
-+{
-+ return (mask & true_val) | (~mask & false_val);
-+}
-+
-+
-+/**
-+ * const_time_select_int - Constant time int selection
-+ * @mask: 0 (false) or -1 (true) to identify which value to select
-+ * @true_val: Value to select for the true case
-+ * @false_val: Value to select for the false case
-+ * Returns: true_val if mask == -1, false_val if mask == 0
-+ */
-+static inline int const_time_select_int(unsigned int mask, int true_val,
-+ int false_val)
-+{
-+ return (int) const_time_select(mask, (unsigned int) true_val,
-+ (unsigned int) false_val);
-+}
-+
-+
-+/**
-+ * const_time_select_u8 - Constant time u8 selection
-+ * @mask: 0 (false) or -1 (true) to identify which value to select
-+ * @true_val: Value to select for the true case
-+ * @false_val: Value to select for the false case
-+ * Returns: true_val if mask == -1, false_val if mask == 0
-+ */
-+static inline u8 const_time_select_u8(u8 mask, u8 true_val, u8 false_val)
-+{
-+ return (u8) const_time_select(mask, true_val, false_val);
-+}
-+
-+
-+/**
-+ * const_time_select_s8 - Constant time s8 selection
-+ * @mask: 0 (false) or -1 (true) to identify which value to select
-+ * @true_val: Value to select for the true case
-+ * @false_val: Value to select for the false case
-+ * Returns: true_val if mask == -1, false_val if mask == 0
-+ */
-+static inline s8 const_time_select_s8(u8 mask, s8 true_val, s8 false_val)
-+{
-+ return (s8) const_time_select(mask, (unsigned int) true_val,
-+ (unsigned int) false_val);
-+}
-+
-+
-+/**
-+ * const_time_select_bin - Constant time binary buffer selection copy
-+ * @mask: 0 (false) or -1 (true) to identify which value to copy
-+ * @true_val: Buffer to copy for the true case
-+ * @false_val: Buffer to copy for the false case
-+ * @len: Number of octets to copy
-+ * @dst: Destination buffer for the copy
-+ *
-+ * This function copies the specified buffer into the destination buffer using
-+ * operations with identical memory access pattern regardless of which buffer
-+ * is being copied.
-+ */
-+static inline void const_time_select_bin(u8 mask, const u8 *true_val,
-+ const u8 *false_val, size_t len,
-+ u8 *dst)
-+{
-+ size_t i;
-+
-+ for (i = 0; i < len; i++)
-+ dst[i] = const_time_select_u8(mask, true_val[i], false_val[i]);
-+}
-+
-+
-+static inline int const_time_memcmp(const void *a, const void *b, size_t len)
-+{
-+ const u8 *aa = a;
-+ const u8 *bb = b;
-+ int diff, res = 0;
-+ unsigned int mask;
-+
-+ if (len == 0)
-+ return 0;
-+ do {
-+ len--;
-+ diff = (int) aa[len] - (int) bb[len];
-+ mask = const_time_is_zero((unsigned int) diff);
-+ res = const_time_select_int(mask, res, diff);
-+ } while (len);
-+
-+ return res;
-+}
-+
-+#endif /* CONST_TIME_H */
deleted file mode 100644
@@ -1,55 +0,0 @@
-From c93461c1d98f52681717a088776ab32fd97872b0 Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Fri, 8 Mar 2019 00:24:12 +0200
-Subject: [PATCH 03/14] OpenSSL: Use constant time selection for
- crypto_bignum_legendre()
-
-Get rid of the branches that depend on the result of the Legendre
-operation. This is needed to avoid leaking information about different
-temporary results in blinding mechanisms.
-
-This is related to CVE-2019-9494 and CVE-2019-9495.
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/crypto/crypto_openssl.c | 15 +++++++++------
- 1 file changed, 9 insertions(+), 6 deletions(-)
-
---- a/src/crypto/crypto_openssl.c
-+++ b/src/crypto/crypto_openssl.c
-@@ -24,6 +24,7 @@
- #endif /* CONFIG_ECC */
-
- #include "common.h"
-+#include "utils/const_time.h"
- #include "wpabuf.h"
- #include "dh_group5.h"
- #include "sha1.h"
-@@ -1435,6 +1436,7 @@ int crypto_bignum_legendre(const struct
- BN_CTX *bnctx;
- BIGNUM *exp = NULL, *tmp = NULL;
- int res = -2;
-+ unsigned int mask;
-
- if (TEST_FAIL())
- return -2;
-@@ -1453,12 +1455,13 @@ int crypto_bignum_legendre(const struct
- (const BIGNUM *) p, bnctx, NULL))
- goto fail;
-
-- if (BN_is_word(tmp, 1))
-- res = 1;
-- else if (BN_is_zero(tmp))
-- res = 0;
-- else
-- res = -1;
-+ /* Return 1 if tmp == 1, 0 if tmp == 0, or -1 otherwise. Need to use
-+ * constant time selection to avoid branches here. */
-+ res = -1;
-+ mask = const_time_eq(BN_is_word(tmp, 1), 1);
-+ res = const_time_select_int(mask, 1, res);
-+ mask = const_time_eq(BN_is_zero(tmp), 1);
-+ res = const_time_select_int(mask, 0, res);
-
- fail:
- BN_clear_free(tmp);
deleted file mode 100644
@@ -1,242 +0,0 @@
-From 6513db3e96c43c2e36805cf5ead349765d18eaf7 Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Tue, 26 Feb 2019 13:05:09 +0200
-Subject: [PATCH 05/14] SAE: Minimize timing differences in PWE derivation
-
-The QR test result can provide information about the password to an
-attacker, so try to minimize differences in how the
-sae_test_pwd_seed_ecc() result is used. (CVE-2019-9494)
-
-Use heap memory for the dummy password to allow the same password length
-to be used even with long passwords.
-
-Use constant time selection functions to track the real vs. dummy
-variables so that the exact same operations can be performed for both QR
-test results.
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/common/sae.c | 106 ++++++++++++++++++++++++++++++-------------------------
- 1 file changed, 57 insertions(+), 49 deletions(-)
-
---- a/src/common/sae.c
-+++ b/src/common/sae.c
-@@ -9,6 +9,7 @@
- #include "includes.h"
-
- #include "common.h"
-+#include "utils/const_time.h"
- #include "crypto/crypto.h"
- #include "crypto/sha256.h"
- #include "crypto/random.h"
-@@ -269,15 +270,12 @@ static int sae_test_pwd_seed_ecc(struct
- const u8 *prime,
- const struct crypto_bignum *qr,
- const struct crypto_bignum *qnr,
-- struct crypto_bignum **ret_x_cand)
-+ u8 *pwd_value)
- {
-- u8 pwd_value[SAE_MAX_ECC_PRIME_LEN];
- struct crypto_bignum *y_sqr, *x_cand;
- int res;
- size_t bits;
-
-- *ret_x_cand = NULL;
--
- wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-seed", pwd_seed, SHA256_MAC_LEN);
-
- /* pwd-value = KDF-z(pwd-seed, "SAE Hunting and Pecking", p) */
-@@ -286,7 +284,7 @@ static int sae_test_pwd_seed_ecc(struct
- prime, sae->tmp->prime_len, pwd_value, bits) < 0)
- return -1;
- if (bits % 8)
-- buf_shift_right(pwd_value, sizeof(pwd_value), 8 - bits % 8);
-+ buf_shift_right(pwd_value, sae->tmp->prime_len, 8 - bits % 8);
- wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value",
- pwd_value, sae->tmp->prime_len);
-
-@@ -297,20 +295,13 @@ static int sae_test_pwd_seed_ecc(struct
- if (!x_cand)
- return -1;
- y_sqr = crypto_ec_point_compute_y_sqr(sae->tmp->ec, x_cand);
-- if (!y_sqr) {
-- crypto_bignum_deinit(x_cand, 1);
-+ crypto_bignum_deinit(x_cand, 1);
-+ if (!y_sqr)
- return -1;
-- }
-
- res = is_quadratic_residue_blind(sae, prime, bits, qr, qnr, y_sqr);
- crypto_bignum_deinit(y_sqr, 1);
-- if (res <= 0) {
-- crypto_bignum_deinit(x_cand, 1);
-- return res;
-- }
--
-- *ret_x_cand = x_cand;
-- return 1;
-+ return res;
- }
-
-
-@@ -431,25 +422,30 @@ static int sae_derive_pwe_ecc(struct sae
- const u8 *addr[3];
- size_t len[3];
- size_t num_elem;
-- u8 dummy_password[32];
-- size_t dummy_password_len;
-+ u8 *dummy_password, *tmp_password;
- int pwd_seed_odd = 0;
- u8 prime[SAE_MAX_ECC_PRIME_LEN];
- size_t prime_len;
-- struct crypto_bignum *x = NULL, *qr, *qnr;
-+ struct crypto_bignum *x = NULL, *qr = NULL, *qnr = NULL;
-+ u8 x_bin[SAE_MAX_ECC_PRIME_LEN];
-+ u8 x_cand_bin[SAE_MAX_ECC_PRIME_LEN];
- size_t bits;
-- int res;
--
-- dummy_password_len = password_len;
-- if (dummy_password_len > sizeof(dummy_password))
-- dummy_password_len = sizeof(dummy_password);
-- if (random_get_bytes(dummy_password, dummy_password_len) < 0)
-- return -1;
-+ int res = -1;
-+ u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_*
-+ * mask */
-+
-+ os_memset(x_bin, 0, sizeof(x_bin));
-+
-+ dummy_password = os_malloc(password_len);
-+ tmp_password = os_malloc(password_len);
-+ if (!dummy_password || !tmp_password ||
-+ random_get_bytes(dummy_password, password_len) < 0)
-+ goto fail;
-
- prime_len = sae->tmp->prime_len;
- if (crypto_bignum_to_bin(sae->tmp->prime, prime, sizeof(prime),
- prime_len) < 0)
-- return -1;
-+ goto fail;
- bits = crypto_ec_prime_len_bits(sae->tmp->ec);
-
- /*
-@@ -458,7 +454,7 @@ static int sae_derive_pwe_ecc(struct sae
- */
- if (get_random_qr_qnr(prime, prime_len, sae->tmp->prime, bits,
- &qr, &qnr) < 0)
-- return -1;
-+ goto fail;
-
- wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
- password, password_len);
-@@ -474,7 +470,7 @@ static int sae_derive_pwe_ecc(struct sae
- */
- sae_pwd_seed_key(addr1, addr2, addrs);
-
-- addr[0] = password;
-+ addr[0] = tmp_password;
- len[0] = password_len;
- num_elem = 1;
- if (identifier) {
-@@ -491,9 +487,8 @@ static int sae_derive_pwe_ecc(struct sae
- * attacks that attempt to determine the number of iterations required
- * in the loop.
- */
-- for (counter = 1; counter <= k || !x; counter++) {
-+ for (counter = 1; counter <= k || !found; counter++) {
- u8 pwd_seed[SHA256_MAC_LEN];
-- struct crypto_bignum *x_cand;
-
- if (counter > 200) {
- /* This should not happen in practice */
-@@ -501,40 +496,49 @@ static int sae_derive_pwe_ecc(struct sae
- break;
- }
-
-- wpa_printf(MSG_DEBUG, "SAE: counter = %u", counter);
-+ wpa_printf(MSG_DEBUG, "SAE: counter = %03u", counter);
-+ const_time_select_bin(found, dummy_password, password,
-+ password_len, tmp_password);
- if (hmac_sha256_vector(addrs, sizeof(addrs), num_elem,
- addr, len, pwd_seed) < 0)
- break;
-
- res = sae_test_pwd_seed_ecc(sae, pwd_seed,
-- prime, qr, qnr, &x_cand);
-+ prime, qr, qnr, x_cand_bin);
-+ const_time_select_bin(found, x_bin, x_cand_bin, prime_len,
-+ x_bin);
-+ pwd_seed_odd = const_time_select_u8(
-+ found, pwd_seed_odd,
-+ pwd_seed[SHA256_MAC_LEN - 1] & 0x01);
-+ os_memset(pwd_seed, 0, sizeof(pwd_seed));
- if (res < 0)
- goto fail;
-- if (res > 0 && !x) {
-- wpa_printf(MSG_DEBUG,
-- "SAE: Selected pwd-seed with counter %u",
-- counter);
-- x = x_cand;
-- pwd_seed_odd = pwd_seed[SHA256_MAC_LEN - 1] & 0x01;
-- os_memset(pwd_seed, 0, sizeof(pwd_seed));
--
-- /*
-- * Use a dummy password for the following rounds, if
-- * any.
-- */
-- addr[0] = dummy_password;
-- len[0] = dummy_password_len;
-- } else if (res > 0) {
-- crypto_bignum_deinit(x_cand, 1);
-- }
-+ /* Need to minimize differences in handling res == 0 and 1 here
-+ * to avoid differences in timing and instruction cache access,
-+ * so use const_time_select_*() to make local copies of the
-+ * values based on whether this loop iteration was the one that
-+ * found the pwd-seed/x. */
-+
-+ /* found is 0 or 0xff here and res is 0 or 1. Bitwise OR of them
-+ * (with res converted to 0/0xff) handles this in constant time.
-+ */
-+ found |= res * 0xff;
-+ wpa_printf(MSG_DEBUG, "SAE: pwd-seed result %d found=0x%02x",
-+ res, found);
- }
-
-- if (!x) {
-+ if (!found) {
- wpa_printf(MSG_DEBUG, "SAE: Could not generate PWE");
- res = -1;
- goto fail;
- }
-
-+ x = crypto_bignum_init_set(x_bin, prime_len);
-+ if (!x) {
-+ res = -1;
-+ goto fail;
-+ }
-+
- if (!sae->tmp->pwe_ecc)
- sae->tmp->pwe_ecc = crypto_ec_point_init(sae->tmp->ec);
- if (!sae->tmp->pwe_ecc)
-@@ -543,7 +547,6 @@ static int sae_derive_pwe_ecc(struct sae
- res = crypto_ec_point_solve_y_coord(sae->tmp->ec,
- sae->tmp->pwe_ecc, x,
- pwd_seed_odd);
-- crypto_bignum_deinit(x, 1);
- if (res < 0) {
- /*
- * This should not happen since we already checked that there
-@@ -555,6 +558,11 @@ static int sae_derive_pwe_ecc(struct sae
- fail:
- crypto_bignum_deinit(qr, 0);
- crypto_bignum_deinit(qnr, 0);
-+ os_free(dummy_password);
-+ bin_clear_free(tmp_password, password_len);
-+ crypto_bignum_deinit(x, 1);
-+ os_memset(x_bin, 0, sizeof(x_bin));
-+ os_memset(x_cand_bin, 0, sizeof(x_cand_bin));
-
- return res;
- }
deleted file mode 100644
@@ -1,139 +0,0 @@
-From 362704dda04507e7ebb8035122e83d9f0ae7c320 Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Tue, 26 Feb 2019 19:34:38 +0200
-Subject: [PATCH 06/14] SAE: Avoid branches in is_quadratic_residue_blind()
-
-Make the non-failure path in the function proceed without branches based
-on r_odd and in constant time to minimize risk of observable differences
-in timing or cache use. (CVE-2019-9494)
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/common/sae.c | 64 ++++++++++++++++++++++++++++++++------------------------
- 1 file changed, 37 insertions(+), 27 deletions(-)
-
---- a/src/common/sae.c
-+++ b/src/common/sae.c
-@@ -209,12 +209,14 @@ get_rand_1_to_p_1(const u8 *prime, size_
-
- static int is_quadratic_residue_blind(struct sae_data *sae,
- const u8 *prime, size_t bits,
-- const struct crypto_bignum *qr,
-- const struct crypto_bignum *qnr,
-+ const u8 *qr, const u8 *qnr,
- const struct crypto_bignum *y_sqr)
- {
-- struct crypto_bignum *r, *num;
-+ struct crypto_bignum *r, *num, *qr_or_qnr = NULL;
- int r_odd, check, res = -1;
-+ u8 qr_or_qnr_bin[SAE_MAX_ECC_PRIME_LEN];
-+ size_t prime_len = sae->tmp->prime_len;
-+ unsigned int mask;
-
- /*
- * Use the blinding technique to mask y_sqr while determining
-@@ -225,7 +227,7 @@ static int is_quadratic_residue_blind(st
- * r = a random number between 1 and p-1, inclusive
- * num = (v * r * r) modulo p
- */
-- r = get_rand_1_to_p_1(prime, sae->tmp->prime_len, bits, &r_odd);
-+ r = get_rand_1_to_p_1(prime, prime_len, bits, &r_odd);
- if (!r)
- return -1;
-
-@@ -235,41 +237,45 @@ static int is_quadratic_residue_blind(st
- crypto_bignum_mulmod(num, r, sae->tmp->prime, num) < 0)
- goto fail;
-
-- if (r_odd) {
-- /*
-- * num = (num * qr) module p
-- * LGR(num, p) = 1 ==> quadratic residue
-- */
-- if (crypto_bignum_mulmod(num, qr, sae->tmp->prime, num) < 0)
-- goto fail;
-- check = 1;
-- } else {
-- /*
-- * num = (num * qnr) module p
-- * LGR(num, p) = -1 ==> quadratic residue
-- */
-- if (crypto_bignum_mulmod(num, qnr, sae->tmp->prime, num) < 0)
-- goto fail;
-- check = -1;
-- }
-+ /*
-+ * Need to minimize differences in handling different cases, so try to
-+ * avoid branches and timing differences.
-+ *
-+ * If r_odd:
-+ * num = (num * qr) module p
-+ * LGR(num, p) = 1 ==> quadratic residue
-+ * else:
-+ * num = (num * qnr) module p
-+ * LGR(num, p) = -1 ==> quadratic residue
-+ */
-+ mask = const_time_is_zero(r_odd);
-+ const_time_select_bin(mask, qnr, qr, prime_len, qr_or_qnr_bin);
-+ qr_or_qnr = crypto_bignum_init_set(qr_or_qnr_bin, prime_len);
-+ if (!qr_or_qnr ||
-+ crypto_bignum_mulmod(num, qr_or_qnr, sae->tmp->prime, num) < 0)
-+ goto fail;
-+ /* r_odd is 0 or 1; branchless version of check = r_odd ? 1 : -1, */
-+ check = const_time_select_int(mask, -1, 1);
-
- res = crypto_bignum_legendre(num, sae->tmp->prime);
- if (res == -2) {
- res = -1;
- goto fail;
- }
-- res = res == check;
-+ /* branchless version of res = res == check
-+ * (res is -1, 0, or 1; check is -1 or 1) */
-+ mask = const_time_eq(res, check);
-+ res = const_time_select_int(mask, 1, 0);
- fail:
- crypto_bignum_deinit(num, 1);
- crypto_bignum_deinit(r, 1);
-+ crypto_bignum_deinit(qr_or_qnr, 1);
- return res;
- }
-
-
- static int sae_test_pwd_seed_ecc(struct sae_data *sae, const u8 *pwd_seed,
-- const u8 *prime,
-- const struct crypto_bignum *qr,
-- const struct crypto_bignum *qnr,
-+ const u8 *prime, const u8 *qr, const u8 *qnr,
- u8 *pwd_value)
- {
- struct crypto_bignum *y_sqr, *x_cand;
-@@ -429,6 +435,8 @@ static int sae_derive_pwe_ecc(struct sae
- struct crypto_bignum *x = NULL, *qr = NULL, *qnr = NULL;
- u8 x_bin[SAE_MAX_ECC_PRIME_LEN];
- u8 x_cand_bin[SAE_MAX_ECC_PRIME_LEN];
-+ u8 qr_bin[SAE_MAX_ECC_PRIME_LEN];
-+ u8 qnr_bin[SAE_MAX_ECC_PRIME_LEN];
- size_t bits;
- int res = -1;
- u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_*
-@@ -453,7 +461,9 @@ static int sae_derive_pwe_ecc(struct sae
- * (qnr) modulo p for blinding purposes during the loop.
- */
- if (get_random_qr_qnr(prime, prime_len, sae->tmp->prime, bits,
-- &qr, &qnr) < 0)
-+ &qr, &qnr) < 0 ||
-+ crypto_bignum_to_bin(qr, qr_bin, sizeof(qr_bin), prime_len) < 0 ||
-+ crypto_bignum_to_bin(qnr, qnr_bin, sizeof(qnr_bin), prime_len) < 0)
- goto fail;
-
- wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
-@@ -504,7 +514,7 @@ static int sae_derive_pwe_ecc(struct sae
- break;
-
- res = sae_test_pwd_seed_ecc(sae, pwd_seed,
-- prime, qr, qnr, x_cand_bin);
-+ prime, qr_bin, qnr_bin, x_cand_bin);
- const_time_select_bin(found, x_bin, x_cand_bin, prime_len,
- x_bin);
- pwd_seed_odd = const_time_select_u8(
deleted file mode 100644
@@ -1,113 +0,0 @@
-From 90839597cc4016b33f00055b12d59174c62770a3 Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Sat, 2 Mar 2019 12:24:09 +0200
-Subject: [PATCH 07/14] SAE: Mask timing of MODP groups 22, 23, 24
-
-These groups have significant probability of coming up with pwd-value
-that is equal or greater than the prime and as such, need for going
-through the PWE derivation loop multiple times. This can result in
-sufficient timing different to allow an external observer to determine
-how many rounds are needed and that can leak information about the used
-password.
-
-Force at least 40 loop rounds for these MODP groups similarly to the ECC
-group design to mask timing. This behavior is not described in IEEE Std
-802.11-2016 for SAE, but it does not result in different values (i.e.,
-only different timing), so such implementation specific countermeasures
-can be done without breaking interoperability with other implementation.
-
-Note: These MODP groups 22, 23, and 24 are not considered sufficiently
-strong to be used with SAE (or more or less anything else). As such,
-they should never be enabled in runtime configuration for any production
-use cases. These changes to introduce additional protection to mask
-timing is only for completeness of implementation and not an indication
-that these groups should be used.
-
-This is related to CVE-2019-9494.
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/common/sae.c | 38 ++++++++++++++++++++++++++++----------
- 1 file changed, 28 insertions(+), 10 deletions(-)
-
---- a/src/common/sae.c
-+++ b/src/common/sae.c
-@@ -578,22 +578,27 @@ fail:
- }
-
-
-+static int sae_modp_group_require_masking(int group)
-+{
-+ /* Groups for which pwd-value is likely to be >= p frequently */
-+ return group == 22 || group == 23 || group == 24;
-+}
-+
-+
- static int sae_derive_pwe_ffc(struct sae_data *sae, const u8 *addr1,
- const u8 *addr2, const u8 *password,
- size_t password_len, const char *identifier)
- {
-- u8 counter;
-+ u8 counter, k;
- u8 addrs[2 * ETH_ALEN];
- const u8 *addr[3];
- size_t len[3];
- size_t num_elem;
- int found = 0;
-+ struct crypto_bignum *pwe = NULL;
-
-- if (sae->tmp->pwe_ffc == NULL) {
-- sae->tmp->pwe_ffc = crypto_bignum_init();
-- if (sae->tmp->pwe_ffc == NULL)
-- return -1;
-- }
-+ crypto_bignum_deinit(sae->tmp->pwe_ffc, 1);
-+ sae->tmp->pwe_ffc = NULL;
-
- wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
- password, password_len);
-@@ -617,7 +622,9 @@ static int sae_derive_pwe_ffc(struct sae
- len[num_elem] = sizeof(counter);
- num_elem++;
-
-- for (counter = 1; !found; counter++) {
-+ k = sae_modp_group_require_masking(sae->group) ? 40 : 1;
-+
-+ for (counter = 1; counter <= k || !found; counter++) {
- u8 pwd_seed[SHA256_MAC_LEN];
- int res;
-
-@@ -627,19 +634,30 @@ static int sae_derive_pwe_ffc(struct sae
- break;
- }
-
-- wpa_printf(MSG_DEBUG, "SAE: counter = %u", counter);
-+ wpa_printf(MSG_DEBUG, "SAE: counter = %02u", counter);
- if (hmac_sha256_vector(addrs, sizeof(addrs), num_elem,
- addr, len, pwd_seed) < 0)
- break;
-- res = sae_test_pwd_seed_ffc(sae, pwd_seed, sae->tmp->pwe_ffc);
-+ if (!pwe) {
-+ pwe = crypto_bignum_init();
-+ if (!pwe)
-+ break;
-+ }
-+ res = sae_test_pwd_seed_ffc(sae, pwd_seed, pwe);
- if (res < 0)
- break;
- if (res > 0) {
-- wpa_printf(MSG_DEBUG, "SAE: Use this PWE");
- found = 1;
-+ if (!sae->tmp->pwe_ffc) {
-+ wpa_printf(MSG_DEBUG, "SAE: Use this PWE");
-+ sae->tmp->pwe_ffc = pwe;
-+ pwe = NULL;
-+ }
- }
- }
-
-+ crypto_bignum_deinit(pwe, 1);
-+
- return found ? 0 : -1;
- }
-
deleted file mode 100644
@@ -1,100 +0,0 @@
-From f8f20717f87eff1f025f48ed585c7684debacf72 Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Sat, 2 Mar 2019 12:45:33 +0200
-Subject: [PATCH 08/14] SAE: Use const_time selection for PWE in FFC
-
-This is an initial step towards making the FFC case use strictly
-constant time operations similarly to the ECC case.
-sae_test_pwd_seed_ffc() does not yet have constant time behavior,
-though.
-
-This is related to CVE-2019-9494.
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/common/sae.c | 53 +++++++++++++++++++++++++++++++++++------------------
- 1 file changed, 35 insertions(+), 18 deletions(-)
-
---- a/src/common/sae.c
-+++ b/src/common/sae.c
-@@ -589,17 +589,28 @@ static int sae_derive_pwe_ffc(struct sae
- const u8 *addr2, const u8 *password,
- size_t password_len, const char *identifier)
- {
-- u8 counter, k;
-+ u8 counter, k, sel_counter = 0;
- u8 addrs[2 * ETH_ALEN];
- const u8 *addr[3];
- size_t len[3];
- size_t num_elem;
-- int found = 0;
-- struct crypto_bignum *pwe = NULL;
-+ u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_*
-+ * mask */
-+ u8 mask;
-+ struct crypto_bignum *pwe;
-+ size_t prime_len = sae->tmp->prime_len * 8;
-+ u8 *pwe_buf;
-
- crypto_bignum_deinit(sae->tmp->pwe_ffc, 1);
- sae->tmp->pwe_ffc = NULL;
-
-+ /* Allocate a buffer to maintain selected and candidate PWE for constant
-+ * time selection. */
-+ pwe_buf = os_zalloc(prime_len * 2);
-+ pwe = crypto_bignum_init();
-+ if (!pwe_buf || !pwe)
-+ goto fail;
-+
- wpa_hexdump_ascii_key(MSG_DEBUG, "SAE: password",
- password, password_len);
-
-@@ -638,27 +649,33 @@ static int sae_derive_pwe_ffc(struct sae
- if (hmac_sha256_vector(addrs, sizeof(addrs), num_elem,
- addr, len, pwd_seed) < 0)
- break;
-- if (!pwe) {
-- pwe = crypto_bignum_init();
-- if (!pwe)
-- break;
-- }
- res = sae_test_pwd_seed_ffc(sae, pwd_seed, pwe);
-+ /* res is -1 for fatal failure, 0 if a valid PWE was not found,
-+ * or 1 if a valid PWE was found. */
- if (res < 0)
- break;
-- if (res > 0) {
-- found = 1;
-- if (!sae->tmp->pwe_ffc) {
-- wpa_printf(MSG_DEBUG, "SAE: Use this PWE");
-- sae->tmp->pwe_ffc = pwe;
-- pwe = NULL;
-- }
-- }
-+ /* Store the candidate PWE into the second half of pwe_buf and
-+ * the selected PWE in the beginning of pwe_buf using constant
-+ * time selection. */
-+ if (crypto_bignum_to_bin(pwe, pwe_buf + prime_len, prime_len,
-+ prime_len) < 0)
-+ break;
-+ const_time_select_bin(found, pwe_buf, pwe_buf + prime_len,
-+ prime_len, pwe_buf);
-+ sel_counter = const_time_select_u8(found, sel_counter, counter);
-+ mask = const_time_eq_u8(res, 1);
-+ found = const_time_select_u8(found, found, mask);
- }
-
-- crypto_bignum_deinit(pwe, 1);
-+ if (!found)
-+ goto fail;
-
-- return found ? 0 : -1;
-+ wpa_printf(MSG_DEBUG, "SAE: Use PWE from counter = %02u", sel_counter);
-+ sae->tmp->pwe_ffc = crypto_bignum_init_set(pwe_buf, prime_len);
-+fail:
-+ crypto_bignum_deinit(pwe, 1);
-+ bin_clear_free(pwe_buf, prime_len * 2);
-+ return sae->tmp->pwe_ffc ? 0 : -1;
- }
-
-
deleted file mode 100644
@@ -1,133 +0,0 @@
-From cff138b0747fa39765cbc641b66cfa5d7f1735d1 Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Sat, 2 Mar 2019 16:05:56 +0200
-Subject: [PATCH 09/14] SAE: Use constant time operations in
- sae_test_pwd_seed_ffc()
-
-Try to avoid showing externally visible timing or memory access
-differences regardless of whether the derived pwd-value is smaller than
-the group prime.
-
-This is related to CVE-2019-9494.
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/common/sae.c | 75 ++++++++++++++++++++++++++++++++++----------------------
- 1 file changed, 46 insertions(+), 29 deletions(-)
-
---- a/src/common/sae.c
-+++ b/src/common/sae.c
-@@ -311,14 +311,17 @@ static int sae_test_pwd_seed_ecc(struct
- }
-
-
-+/* Returns -1 on fatal failure, 0 if PWE cannot be derived from the provided
-+ * pwd-seed, or 1 if a valid PWE was derived from pwd-seed. */
- static int sae_test_pwd_seed_ffc(struct sae_data *sae, const u8 *pwd_seed,
- struct crypto_bignum *pwe)
- {
- u8 pwd_value[SAE_MAX_PRIME_LEN];
- size_t bits = sae->tmp->prime_len * 8;
- u8 exp[1];
-- struct crypto_bignum *a, *b;
-- int res;
-+ struct crypto_bignum *a, *b = NULL;
-+ int res, is_val;
-+ u8 pwd_value_valid;
-
- wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-seed", pwd_seed, SHA256_MAC_LEN);
-
-@@ -330,16 +333,29 @@ static int sae_test_pwd_seed_ffc(struct
- wpa_hexdump_key(MSG_DEBUG, "SAE: pwd-value", pwd_value,
- sae->tmp->prime_len);
-
-- if (os_memcmp(pwd_value, sae->tmp->dh->prime, sae->tmp->prime_len) >= 0)
-- {
-- wpa_printf(MSG_DEBUG, "SAE: pwd-value >= p");
-- return 0;
-- }
-+ /* Check whether pwd-value < p */
-+ res = const_time_memcmp(pwd_value, sae->tmp->dh->prime,
-+ sae->tmp->prime_len);
-+ /* pwd-value >= p is invalid, so res is < 0 for the valid cases and
-+ * the negative sign can be used to fill the mask for constant time
-+ * selection */
-+ pwd_value_valid = const_time_fill_msb(res);
-+
-+ /* If pwd-value >= p, force pwd-value to be < p and perform the
-+ * calculations anyway to hide timing difference. The derived PWE will
-+ * be ignored in that case. */
-+ pwd_value[0] = const_time_select_u8(pwd_value_valid, pwd_value[0], 0);
-
- /* PWE = pwd-value^((p-1)/r) modulo p */
-
-+ res = -1;
- a = crypto_bignum_init_set(pwd_value, sae->tmp->prime_len);
-+ if (!a)
-+ goto fail;
-
-+ /* This is an optimization based on the used group that does not depend
-+ * on the password in any way, so it is fine to use separate branches
-+ * for this step without constant time operations. */
- if (sae->tmp->dh->safe_prime) {
- /*
- * r = (p-1)/2 for the group used here, so this becomes:
-@@ -353,33 +369,34 @@ static int sae_test_pwd_seed_ffc(struct
- b = crypto_bignum_init_set(exp, sizeof(exp));
- if (b == NULL ||
- crypto_bignum_sub(sae->tmp->prime, b, b) < 0 ||
-- crypto_bignum_div(b, sae->tmp->order, b) < 0) {
-- crypto_bignum_deinit(b, 0);
-- b = NULL;
-- }
-+ crypto_bignum_div(b, sae->tmp->order, b) < 0)
-+ goto fail;
- }
-
-- if (a == NULL || b == NULL)
-- res = -1;
-- else
-- res = crypto_bignum_exptmod(a, b, sae->tmp->prime, pwe);
--
-- crypto_bignum_deinit(a, 0);
-- crypto_bignum_deinit(b, 0);
--
-- if (res < 0) {
-- wpa_printf(MSG_DEBUG, "SAE: Failed to calculate PWE");
-- return -1;
-- }
--
-- /* if (PWE > 1) --> found */
-- if (crypto_bignum_is_zero(pwe) || crypto_bignum_is_one(pwe)) {
-- wpa_printf(MSG_DEBUG, "SAE: PWE <= 1");
-- return 0;
-- }
-+ if (!b)
-+ goto fail;
-
-- wpa_printf(MSG_DEBUG, "SAE: PWE found");
-- return 1;
-+ res = crypto_bignum_exptmod(a, b, sae->tmp->prime, pwe);
-+ if (res < 0)
-+ goto fail;
-+
-+ /* There were no fatal errors in calculations, so determine the return
-+ * value using constant time operations. We get here for number of
-+ * invalid cases which are cleared here after having performed all the
-+ * computation. PWE is valid if pwd-value was less than prime and
-+ * PWE > 1. Start with pwd-value check first and then use constant time
-+ * operations to clear res to 0 if PWE is 0 or 1.
-+ */
-+ res = const_time_select_u8(pwd_value_valid, 1, 0);
-+ is_val = crypto_bignum_is_zero(pwe);
-+ res = const_time_select_u8(const_time_is_zero(is_val), res, 0);
-+ is_val = crypto_bignum_is_one(pwe);
-+ res = const_time_select_u8(const_time_is_zero(is_val), res, 0);
-+
-+fail:
-+ crypto_bignum_deinit(a, 1);
-+ crypto_bignum_deinit(b, 1);
-+ return res;
- }
-
-
deleted file mode 100644
@@ -1,319 +0,0 @@
-From aaf65feac67c3993935634eefe5bc76b9fce03aa Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Tue, 26 Feb 2019 11:59:45 +0200
-Subject: [PATCH 04/14] EAP-pwd: Use constant time and memory access for
- finding the PWE
-
-This algorithm could leak information to external observers in form of
-timing differences or memory access patterns (cache use). While the
-previous implementation had protection against the most visible timing
-differences (looping 40 rounds and masking the legendre operation), it
-did not protect against memory access patterns between the two possible
-code paths in the masking operations. That might be sufficient to allow
-an unprivileged process running on the same device to be able to
-determine which path is being executed through a cache attack and based
-on that, determine information about the used password.
-
-Convert the PWE finding loop to use constant time functions and
-identical memory access path without different branches for the QR/QNR
-cases to minimize possible side-channel information similarly to the
-changes done for SAE authentication. (CVE-2019-9495)
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/eap_common/eap_pwd_common.c | 187 +++++++++++++++++++++-------------------
- 1 file changed, 99 insertions(+), 88 deletions(-)
-
---- a/src/eap_common/eap_pwd_common.c
-+++ b/src/eap_common/eap_pwd_common.c
-@@ -8,11 +8,15 @@
-
- #include "includes.h"
- #include "common.h"
-+#include "utils/const_time.h"
- #include "crypto/sha256.h"
- #include "crypto/crypto.h"
- #include "eap_defs.h"
- #include "eap_pwd_common.h"
-
-+#define MAX_ECC_PRIME_LEN 66
-+
-+
- /* The random function H(x) = HMAC-SHA256(0^32, x) */
- struct crypto_hash * eap_pwd_h_init(void)
- {
-@@ -102,6 +106,15 @@ EAP_PWD_group * get_eap_pwd_group(u16 nu
- }
-
-
-+static void buf_shift_right(u8 *buf, size_t len, size_t bits)
-+{
-+ size_t i;
-+ for (i = len - 1; i > 0; i--)
-+ buf[i] = (buf[i - 1] << (8 - bits)) | (buf[i] >> bits);
-+ buf[0] >>= bits;
-+}
-+
-+
- /*
- * compute a "random" secret point on an elliptic curve based
- * on the password and identities.
-@@ -113,17 +126,27 @@ int compute_password_element(EAP_PWD_gro
- const u8 *token)
- {
- struct crypto_bignum *qr = NULL, *qnr = NULL, *one = NULL;
-+ struct crypto_bignum *qr_or_qnr = NULL;
-+ u8 qr_bin[MAX_ECC_PRIME_LEN];
-+ u8 qnr_bin[MAX_ECC_PRIME_LEN];
-+ u8 qr_or_qnr_bin[MAX_ECC_PRIME_LEN];
-+ u8 x_bin[MAX_ECC_PRIME_LEN];
- struct crypto_bignum *tmp1 = NULL, *tmp2 = NULL, *pm1 = NULL;
- struct crypto_hash *hash;
- unsigned char pwe_digest[SHA256_MAC_LEN], *prfbuf = NULL, ctr;
-- int is_odd, ret = 0, check, found = 0;
-- size_t primebytelen, primebitlen;
-- struct crypto_bignum *x_candidate = NULL, *rnd = NULL, *cofactor = NULL;
-+ int ret = 0, check, res;
-+ u8 found = 0; /* 0 (false) or 0xff (true) to be used as const_time_*
-+ * mask */
-+ size_t primebytelen = 0, primebitlen;
-+ struct crypto_bignum *x_candidate = NULL, *cofactor = NULL;
- const struct crypto_bignum *prime;
-+ u8 mask, found_ctr = 0, is_odd = 0;
-
- if (grp->pwe)
- return -1;
-
-+ os_memset(x_bin, 0, sizeof(x_bin));
-+
- prime = crypto_ec_get_prime(grp->group);
- cofactor = crypto_bignum_init();
- grp->pwe = crypto_ec_point_init(grp->group);
-@@ -152,8 +175,6 @@ int compute_password_element(EAP_PWD_gro
-
- /* get a random quadratic residue and nonresidue */
- while (!qr || !qnr) {
-- int res;
--
- if (crypto_bignum_rand(tmp1, prime) < 0)
- goto fail;
- res = crypto_bignum_legendre(tmp1, prime);
-@@ -167,6 +188,11 @@ int compute_password_element(EAP_PWD_gro
- if (!tmp1)
- goto fail;
- }
-+ if (crypto_bignum_to_bin(qr, qr_bin, sizeof(qr_bin),
-+ primebytelen) < 0 ||
-+ crypto_bignum_to_bin(qnr, qnr_bin, sizeof(qnr_bin),
-+ primebytelen) < 0)
-+ goto fail;
-
- os_memset(prfbuf, 0, primebytelen);
- ctr = 0;
-@@ -194,17 +220,16 @@ int compute_password_element(EAP_PWD_gro
- eap_pwd_h_update(hash, &ctr, sizeof(ctr));
- eap_pwd_h_final(hash, pwe_digest);
-
-- crypto_bignum_deinit(rnd, 1);
-- rnd = crypto_bignum_init_set(pwe_digest, SHA256_MAC_LEN);
-- if (!rnd) {
-- wpa_printf(MSG_INFO, "EAP-pwd: unable to create rnd");
-- goto fail;
-- }
-+ is_odd = const_time_select_u8(
-+ found, is_odd, pwe_digest[SHA256_MAC_LEN - 1] & 0x01);
- if (eap_pwd_kdf(pwe_digest, SHA256_MAC_LEN,
- (u8 *) "EAP-pwd Hunting And Pecking",
- os_strlen("EAP-pwd Hunting And Pecking"),
- prfbuf, primebitlen) < 0)
- goto fail;
-+ if (primebitlen % 8)
-+ buf_shift_right(prfbuf, primebytelen,
-+ 8 - primebitlen % 8);
-
- crypto_bignum_deinit(x_candidate, 1);
- x_candidate = crypto_bignum_init_set(prfbuf, primebytelen);
-@@ -214,24 +239,13 @@ int compute_password_element(EAP_PWD_gro
- goto fail;
- }
-
-- /*
-- * eap_pwd_kdf() returns a string of bits 0..primebitlen but
-- * BN_bin2bn will treat that string of bits as a big endian
-- * number. If the primebitlen is not an even multiple of 8
-- * then excessive bits-- those _after_ primebitlen-- so now
-- * we have to shift right the amount we masked off.
-- */
-- if ((primebitlen % 8) &&
-- crypto_bignum_rshift(x_candidate,
-- (8 - (primebitlen % 8)),
-- x_candidate) < 0)
-- goto fail;
--
- if (crypto_bignum_cmp(x_candidate, prime) >= 0)
- continue;
-
-- wpa_hexdump(MSG_DEBUG, "EAP-pwd: x_candidate",
-- prfbuf, primebytelen);
-+ wpa_hexdump_key(MSG_DEBUG, "EAP-pwd: x_candidate",
-+ prfbuf, primebytelen);
-+ const_time_select_bin(found, x_bin, prfbuf, primebytelen,
-+ x_bin);
-
- /*
- * compute y^2 using the equation of the curve
-@@ -260,13 +274,15 @@ int compute_password_element(EAP_PWD_gro
- * Flip a coin, multiply by the random quadratic residue or the
- * random quadratic nonresidue and record heads or tails.
- */
-- if (crypto_bignum_is_odd(tmp1)) {
-- crypto_bignum_mulmod(tmp2, qr, prime, tmp2);
-- check = 1;
-- } else {
-- crypto_bignum_mulmod(tmp2, qnr, prime, tmp2);
-- check = -1;
-- }
-+ mask = const_time_eq_u8(crypto_bignum_is_odd(tmp1), 1);
-+ check = const_time_select_s8(mask, 1, -1);
-+ const_time_select_bin(mask, qr_bin, qnr_bin, primebytelen,
-+ qr_or_qnr_bin);
-+ crypto_bignum_deinit(qr_or_qnr, 1);
-+ qr_or_qnr = crypto_bignum_init_set(qr_or_qnr_bin, primebytelen);
-+ if (!qr_or_qnr ||
-+ crypto_bignum_mulmod(tmp2, qr_or_qnr, prime, tmp2) < 0)
-+ goto fail;
-
- /*
- * Now it's safe to do legendre, if check is 1 then it's
-@@ -274,59 +290,12 @@ int compute_password_element(EAP_PWD_gro
- * change result), if check is -1 then it's the opposite test
- * (multiplying a qr by qnr would make a qnr).
- */
-- if (crypto_bignum_legendre(tmp2, prime) == check) {
-- if (found == 1)
-- continue;
--
-- /* need to unambiguously identify the solution */
-- is_odd = crypto_bignum_is_odd(rnd);
--
-- /*
-- * We know x_candidate is a quadratic residue so set
-- * it here.
-- */
-- if (crypto_ec_point_solve_y_coord(grp->group, grp->pwe,
-- x_candidate,
-- is_odd) != 0) {
-- wpa_printf(MSG_INFO,
-- "EAP-pwd: Could not solve for y");
-- continue;
-- }
--
-- /*
-- * If there's a solution to the equation then the point
-- * must be on the curve so why check again explicitly?
-- * OpenSSL code says this is required by X9.62. We're
-- * not X9.62 but it can't hurt just to be sure.
-- */
-- if (!crypto_ec_point_is_on_curve(grp->group,
-- grp->pwe)) {
-- wpa_printf(MSG_INFO,
-- "EAP-pwd: point is not on curve");
-- continue;
-- }
--
-- if (!crypto_bignum_is_one(cofactor)) {
-- /* make sure the point is not in a small
-- * sub-group */
-- if (crypto_ec_point_mul(grp->group, grp->pwe,
-- cofactor,
-- grp->pwe) != 0) {
-- wpa_printf(MSG_INFO,
-- "EAP-pwd: cannot multiply generator by order");
-- continue;
-- }
-- if (crypto_ec_point_is_at_infinity(grp->group,
-- grp->pwe)) {
-- wpa_printf(MSG_INFO,
-- "EAP-pwd: point is at infinity");
-- continue;
-- }
-- }
-- wpa_printf(MSG_DEBUG,
-- "EAP-pwd: found a PWE in %d tries", ctr);
-- found = 1;
-- }
-+ res = crypto_bignum_legendre(tmp2, prime);
-+ if (res == -2)
-+ goto fail;
-+ mask = const_time_eq(res, check);
-+ found_ctr = const_time_select_u8(found, found_ctr, ctr);
-+ found |= mask;
- }
- if (found == 0) {
- wpa_printf(MSG_INFO,
-@@ -334,6 +303,44 @@ int compute_password_element(EAP_PWD_gro
- num);
- goto fail;
- }
-+
-+ /*
-+ * We know x_candidate is a quadratic residue so set it here.
-+ */
-+ crypto_bignum_deinit(x_candidate, 1);
-+ x_candidate = crypto_bignum_init_set(x_bin, primebytelen);
-+ if (!x_candidate ||
-+ crypto_ec_point_solve_y_coord(grp->group, grp->pwe, x_candidate,
-+ is_odd) != 0) {
-+ wpa_printf(MSG_INFO, "EAP-pwd: Could not solve for y");
-+ goto fail;
-+ }
-+
-+ /*
-+ * If there's a solution to the equation then the point must be on the
-+ * curve so why check again explicitly? OpenSSL code says this is
-+ * required by X9.62. We're not X9.62 but it can't hurt just to be sure.
-+ */
-+ if (!crypto_ec_point_is_on_curve(grp->group, grp->pwe)) {
-+ wpa_printf(MSG_INFO, "EAP-pwd: point is not on curve");
-+ goto fail;
-+ }
-+
-+ if (!crypto_bignum_is_one(cofactor)) {
-+ /* make sure the point is not in a small sub-group */
-+ if (crypto_ec_point_mul(grp->group, grp->pwe, cofactor,
-+ grp->pwe) != 0) {
-+ wpa_printf(MSG_INFO,
-+ "EAP-pwd: cannot multiply generator by order");
-+ goto fail;
-+ }
-+ if (crypto_ec_point_is_at_infinity(grp->group, grp->pwe)) {
-+ wpa_printf(MSG_INFO, "EAP-pwd: point is at infinity");
-+ goto fail;
-+ }
-+ }
-+ wpa_printf(MSG_DEBUG, "EAP-pwd: found a PWE in %02d tries", found_ctr);
-+
- if (0) {
- fail:
- crypto_ec_point_deinit(grp->pwe, 1);
-@@ -343,14 +350,18 @@ int compute_password_element(EAP_PWD_gro
- /* cleanliness and order.... */
- crypto_bignum_deinit(cofactor, 1);
- crypto_bignum_deinit(x_candidate, 1);
-- crypto_bignum_deinit(rnd, 1);
- crypto_bignum_deinit(pm1, 0);
- crypto_bignum_deinit(tmp1, 1);
- crypto_bignum_deinit(tmp2, 1);
- crypto_bignum_deinit(qr, 1);
- crypto_bignum_deinit(qnr, 1);
-+ crypto_bignum_deinit(qr_or_qnr, 1);
- crypto_bignum_deinit(one, 0);
-- os_free(prfbuf);
-+ bin_clear_free(prfbuf, primebytelen);
-+ os_memset(qr_bin, 0, sizeof(qr_bin));
-+ os_memset(qnr_bin, 0, sizeof(qnr_bin));
-+ os_memset(qr_or_qnr_bin, 0, sizeof(qr_or_qnr_bin));
-+ os_memset(pwe_digest, 0, sizeof(pwe_digest));
-
- return ret;
- }
deleted file mode 100644
@@ -1,52 +0,0 @@
-From ac8fa9ef198640086cf2ce7c94673be2b6a018a0 Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Tue, 5 Mar 2019 23:43:25 +0200
-Subject: [PATCH 10/14] SAE: Fix confirm message validation in error cases
-
-Explicitly verify that own and peer commit scalar/element are available
-when trying to check SAE confirm message. It could have been possible to
-hit a NULL pointer dereference if the peer element could not have been
-parsed. (CVE-2019-9496)
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/common/sae.c | 14 +++++++++++---
- 1 file changed, 11 insertions(+), 3 deletions(-)
-
---- a/src/common/sae.c
-+++ b/src/common/sae.c
-@@ -1464,23 +1464,31 @@ int sae_check_confirm(struct sae_data *s
-
- wpa_printf(MSG_DEBUG, "SAE: peer-send-confirm %u", WPA_GET_LE16(data));
-
-- if (sae->tmp == NULL) {
-+ if (!sae->tmp || !sae->peer_commit_scalar ||
-+ !sae->tmp->own_commit_scalar) {
- wpa_printf(MSG_DEBUG, "SAE: Temporary data not yet available");
- return -1;
- }
-
-- if (sae->tmp->ec)
-+ if (sae->tmp->ec) {
-+ if (!sae->tmp->peer_commit_element_ecc ||
-+ !sae->tmp->own_commit_element_ecc)
-+ return -1;
- sae_cn_confirm_ecc(sae, data, sae->peer_commit_scalar,
- sae->tmp->peer_commit_element_ecc,
- sae->tmp->own_commit_scalar,
- sae->tmp->own_commit_element_ecc,
- verifier);
-- else
-+ } else {
-+ if (!sae->tmp->peer_commit_element_ffc ||
-+ !sae->tmp->own_commit_element_ffc)
-+ return -1;
- sae_cn_confirm_ffc(sae, data, sae->peer_commit_scalar,
- sae->tmp->peer_commit_element_ffc,
- sae->tmp->own_commit_scalar,
- sae->tmp->own_commit_element_ffc,
- verifier);
-+ }
-
- if (os_memcmp_const(verifier, data + 2, SHA256_MAC_LEN) != 0) {
- wpa_printf(MSG_DEBUG, "SAE: Confirm mismatch");
deleted file mode 100644
@@ -1,53 +0,0 @@
-From 70ff850e89fbc8bc7da515321b4d15b5eef70581 Mon Sep 17 00:00:00 2001
-From: Mathy Vanhoef <mathy.vanhoef@nyu.edu>
-Date: Sun, 31 Mar 2019 17:13:06 +0200
-Subject: [PATCH 11/14] EAP-pwd server: Verify received scalar and element
-
-When processing an EAP-pwd Commit frame, the peer's scalar and element
-(elliptic curve point) were not validated. This allowed an adversary to
-bypass authentication, and impersonate any user if the crypto
-implementation did not verify the validity of the EC point.
-
-Fix this vulnerability by assuring the received scalar lies within the
-valid range, and by checking that the received element is not the point
-at infinity and lies on the elliptic curve being used. (CVE-2019-9498)
-
-The vulnerability is only exploitable if OpenSSL version 1.0.2 or lower
-is used, or if LibreSSL or wolfssl is used. Newer versions of OpenSSL
-(and also BoringSSL) implicitly validate the elliptic curve point in
-EC_POINT_set_affine_coordinates_GFp(), preventing the attack.
-
-Signed-off-by: Mathy Vanhoef <mathy.vanhoef@nyu.edu>
----
- src/eap_server/eap_server_pwd.c | 20 ++++++++++++++++++++
- 1 file changed, 20 insertions(+)
-
---- a/src/eap_server/eap_server_pwd.c
-+++ b/src/eap_server/eap_server_pwd.c
-@@ -718,6 +718,26 @@ eap_pwd_process_commit_resp(struct eap_s
- goto fin;
- }
-
-+ /* verify received scalar */
-+ if (crypto_bignum_is_zero(data->peer_scalar) ||
-+ crypto_bignum_is_one(data->peer_scalar) ||
-+ crypto_bignum_cmp(data->peer_scalar,
-+ crypto_ec_get_order(data->grp->group)) >= 0) {
-+ wpa_printf(MSG_INFO,
-+ "EAP-PWD (server): received scalar is invalid");
-+ goto fin;
-+ }
-+
-+ /* verify received element */
-+ if (!crypto_ec_point_is_on_curve(data->grp->group,
-+ data->peer_element) ||
-+ crypto_ec_point_is_at_infinity(data->grp->group,
-+ data->peer_element)) {
-+ wpa_printf(MSG_INFO,
-+ "EAP-PWD (server): received element is invalid");
-+ goto fin;
-+ }
-+
- /* check to ensure peer's element is not in a small sub-group */
- if (!crypto_bignum_is_one(cofactor)) {
- if (crypto_ec_point_mul(data->grp->group, data->peer_element,
deleted file mode 100644
@@ -1,40 +0,0 @@
-From d63edfa90243e9a7de6ae5c275032f2cc79fef95 Mon Sep 17 00:00:00 2001
-From: Mathy Vanhoef <mathy.vanhoef@nyu.edu>
-Date: Sun, 31 Mar 2019 17:26:01 +0200
-Subject: [PATCH 12/14] EAP-pwd server: Detect reflection attacks
-
-When processing an EAP-pwd Commit frame, verify that the peer's scalar
-and elliptic curve element differ from the one sent by the server. This
-prevents reflection attacks where the adversary reflects the scalar and
-element sent by the server. (CVE-2019-9497)
-
-The vulnerability allows an adversary to complete the EAP-pwd handshake
-as any user. However, the adversary does not learn the negotiated
-session key, meaning the subsequent 4-way handshake would fail. As a
-result, this cannot be abused to bypass authentication unless EAP-pwd is
-used in non-WLAN cases without any following key exchange that would
-require the attacker to learn the MSK.
-
-Signed-off-by: Mathy Vanhoef <mathy.vanhoef@nyu.edu>
----
- src/eap_server/eap_server_pwd.c | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
---- a/src/eap_server/eap_server_pwd.c
-+++ b/src/eap_server/eap_server_pwd.c
-@@ -753,6 +753,15 @@ eap_pwd_process_commit_resp(struct eap_s
- }
- }
-
-+ /* detect reflection attacks */
-+ if (crypto_bignum_cmp(data->my_scalar, data->peer_scalar) == 0 ||
-+ crypto_ec_point_cmp(data->grp->group, data->my_element,
-+ data->peer_element) == 0) {
-+ wpa_printf(MSG_INFO,
-+ "EAP-PWD (server): detected reflection attack!");
-+ goto fin;
-+ }
-+
- /* compute the shared key, k */
- if ((crypto_ec_point_mul(data->grp->group, data->grp->pwe,
- data->peer_scalar, K) < 0) ||
deleted file mode 100644
@@ -1,53 +0,0 @@
-From 8ad8585f91823ddcc3728155e288e0f9f872e31a Mon Sep 17 00:00:00 2001
-From: Mathy Vanhoef <mathy.vanhoef@nyu.edu>
-Date: Sun, 31 Mar 2019 17:43:44 +0200
-Subject: [PATCH 13/14] EAP-pwd client: Verify received scalar and element
-
-When processing an EAP-pwd Commit frame, the server's scalar and element
-(elliptic curve point) were not validated. This allowed an adversary to
-bypass authentication, and act as a rogue Access Point (AP) if the
-crypto implementation did not verify the validity of the EC point.
-
-Fix this vulnerability by assuring the received scalar lies within the
-valid range, and by checking that the received element is not the point
-at infinity and lies on the elliptic curve being used. (CVE-2019-9499)
-
-The vulnerability is only exploitable if OpenSSL version 1.0.2 or lower
-is used, or if LibreSSL or wolfssl is used. Newer versions of OpenSSL
-(and also BoringSSL) implicitly validate the elliptic curve point in
-EC_POINT_set_affine_coordinates_GFp(), preventing the attack.
-
-Signed-off-by: Mathy Vanhoef <mathy.vanhoef@nyu.edu>
----
- src/eap_peer/eap_pwd.c | 20 ++++++++++++++++++++
- 1 file changed, 20 insertions(+)
-
---- a/src/eap_peer/eap_pwd.c
-+++ b/src/eap_peer/eap_pwd.c
-@@ -594,6 +594,26 @@ eap_pwd_perform_commit_exchange(struct e
- goto fin;
- }
-
-+ /* verify received scalar */
-+ if (crypto_bignum_is_zero(data->server_scalar) ||
-+ crypto_bignum_is_one(data->server_scalar) ||
-+ crypto_bignum_cmp(data->server_scalar,
-+ crypto_ec_get_order(data->grp->group)) >= 0) {
-+ wpa_printf(MSG_INFO,
-+ "EAP-PWD (peer): received scalar is invalid");
-+ goto fin;
-+ }
-+
-+ /* verify received element */
-+ if (!crypto_ec_point_is_on_curve(data->grp->group,
-+ data->server_element) ||
-+ crypto_ec_point_is_at_infinity(data->grp->group,
-+ data->server_element)) {
-+ wpa_printf(MSG_INFO,
-+ "EAP-PWD (peer): received element is invalid");
-+ goto fin;
-+ }
-+
- /* check to ensure server's element is not in a small sub-group */
- if (!crypto_bignum_is_one(cofactor)) {
- if (crypto_ec_point_mul(data->grp->group, data->server_element,
deleted file mode 100644
@@ -1,320 +0,0 @@
-From 16d4f1069118aa19bfce013493e1ac5783f92f1d Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Fri, 5 Apr 2019 02:12:50 +0300
-Subject: [PATCH 14/14] EAP-pwd: Check element x,y coordinates explicitly
-
-This adds an explicit check for 0 < x,y < prime based on RFC 5931,
-2.8.5.2.2 requirement. The earlier checks might have covered this
-implicitly, but it is safer to avoid any dependency on implicit checks
-and specific crypto library behavior. (CVE-2019-9498 and CVE-2019-9499)
-
-Furthermore, this moves the EAP-pwd element and scalar parsing and
-validation steps into shared helper functions so that there is no need
-to maintain two separate copies of this common functionality between the
-server and peer implementations.
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/eap_common/eap_pwd_common.c | 106 ++++++++++++++++++++++++++++++++++++++++
- src/eap_common/eap_pwd_common.h | 3 ++
- src/eap_peer/eap_pwd.c | 45 ++---------------
- src/eap_server/eap_server_pwd.c | 45 ++---------------
- 4 files changed, 117 insertions(+), 82 deletions(-)
-
---- a/src/eap_common/eap_pwd_common.c
-+++ b/src/eap_common/eap_pwd_common.c
-@@ -427,3 +427,109 @@ int compute_keys(EAP_PWD_group *grp, con
-
- return 1;
- }
-+
-+
-+static int eap_pwd_element_coord_ok(const struct crypto_bignum *prime,
-+ const u8 *buf, size_t len)
-+{
-+ struct crypto_bignum *val;
-+ int ok = 1;
-+
-+ val = crypto_bignum_init_set(buf, len);
-+ if (!val || crypto_bignum_is_zero(val) ||
-+ crypto_bignum_cmp(val, prime) >= 0)
-+ ok = 0;
-+ crypto_bignum_deinit(val, 0);
-+ return ok;
-+}
-+
-+
-+struct crypto_ec_point * eap_pwd_get_element(EAP_PWD_group *group,
-+ const u8 *buf)
-+{
-+ struct crypto_ec_point *element;
-+ const struct crypto_bignum *prime;
-+ size_t prime_len;
-+ struct crypto_bignum *cofactor = NULL;
-+
-+ prime = crypto_ec_get_prime(group->group);
-+ prime_len = crypto_ec_prime_len(group->group);
-+
-+ /* RFC 5931, 2.8.5.2.2: 0 < x,y < p */
-+ if (!eap_pwd_element_coord_ok(prime, buf, prime_len) ||
-+ !eap_pwd_element_coord_ok(prime, buf + prime_len, prime_len)) {
-+ wpa_printf(MSG_INFO, "EAP-pwd: Invalid coordinate in element");
-+ return NULL;
-+ }
-+
-+ element = crypto_ec_point_from_bin(group->group, buf);
-+ if (!element) {
-+ wpa_printf(MSG_INFO, "EAP-pwd: EC point from element failed");
-+ return NULL;
-+ }
-+
-+ /* RFC 5931, 2.8.5.2.2: on curve and not the point at infinity */
-+ if (!crypto_ec_point_is_on_curve(group->group, element) ||
-+ crypto_ec_point_is_at_infinity(group->group, element)) {
-+ wpa_printf(MSG_INFO, "EAP-pwd: Invalid element");
-+ goto fail;
-+ }
-+
-+ cofactor = crypto_bignum_init();
-+ if (!cofactor || crypto_ec_cofactor(group->group, cofactor) < 0) {
-+ wpa_printf(MSG_INFO,
-+ "EAP-pwd: Unable to get cofactor for curve");
-+ goto fail;
-+ }
-+
-+ if (!crypto_bignum_is_one(cofactor)) {
-+ struct crypto_ec_point *point;
-+ int ok = 1;
-+
-+ /* check to ensure peer's element is not in a small sub-group */
-+ point = crypto_ec_point_init(group->group);
-+ if (!point ||
-+ crypto_ec_point_mul(group->group, element,
-+ cofactor, point) != 0 ||
-+ crypto_ec_point_is_at_infinity(group->group, point))
-+ ok = 0;
-+ crypto_ec_point_deinit(point, 0);
-+
-+ if (!ok) {
-+ wpa_printf(MSG_INFO,
-+ "EAP-pwd: Small sub-group check on peer element failed");
-+ goto fail;
-+ }
-+ }
-+
-+out:
-+ crypto_bignum_deinit(cofactor, 0);
-+ return element;
-+fail:
-+ crypto_ec_point_deinit(element, 0);
-+ element = NULL;
-+ goto out;
-+}
-+
-+
-+struct crypto_bignum * eap_pwd_get_scalar(EAP_PWD_group *group, const u8 *buf)
-+{
-+ struct crypto_bignum *scalar;
-+ const struct crypto_bignum *order;
-+ size_t order_len;
-+
-+ order = crypto_ec_get_order(group->group);
-+ order_len = crypto_ec_order_len(group->group);
-+
-+ /* RFC 5931, 2.8.5.2: 1 < scalar < r */
-+ scalar = crypto_bignum_init_set(buf, order_len);
-+ if (!scalar || crypto_bignum_is_zero(scalar) ||
-+ crypto_bignum_is_one(scalar) ||
-+ crypto_bignum_cmp(scalar, order) >= 0) {
-+ wpa_printf(MSG_INFO, "EAP-pwd: received scalar is invalid");
-+ crypto_bignum_deinit(scalar, 0);
-+ scalar = NULL;
-+ }
-+
-+ return scalar;
-+}
---- a/src/eap_common/eap_pwd_common.h
-+++ b/src/eap_common/eap_pwd_common.h
-@@ -67,5 +67,8 @@ int compute_keys(EAP_PWD_group *grp, con
- struct crypto_hash * eap_pwd_h_init(void);
- void eap_pwd_h_update(struct crypto_hash *hash, const u8 *data, size_t len);
- void eap_pwd_h_final(struct crypto_hash *hash, u8 *digest);
-+struct crypto_ec_point * eap_pwd_get_element(EAP_PWD_group *group,
-+ const u8 *buf);
-+struct crypto_bignum * eap_pwd_get_scalar(EAP_PWD_group *group, const u8 *buf);
-
- #endif /* EAP_PWD_COMMON_H */
---- a/src/eap_peer/eap_pwd.c
-+++ b/src/eap_peer/eap_pwd.c
-@@ -308,7 +308,7 @@ eap_pwd_perform_commit_exchange(struct e
- const struct wpabuf *reqData,
- const u8 *payload, size_t payload_len)
- {
-- struct crypto_ec_point *K = NULL, *point = NULL;
-+ struct crypto_ec_point *K = NULL;
- struct crypto_bignum *mask = NULL, *cofactor = NULL;
- const u8 *ptr = payload;
- u8 *scalar = NULL, *element = NULL;
-@@ -572,63 +572,27 @@ eap_pwd_perform_commit_exchange(struct e
- /* process the request */
- data->k = crypto_bignum_init();
- K = crypto_ec_point_init(data->grp->group);
-- point = crypto_ec_point_init(data->grp->group);
-- if (!data->k || !K || !point) {
-+ if (!data->k || !K) {
- wpa_printf(MSG_INFO, "EAP-PWD (peer): peer data allocation "
- "fail");
- goto fin;
- }
-
- /* element, x then y, followed by scalar */
-- data->server_element = crypto_ec_point_from_bin(data->grp->group, ptr);
-+ data->server_element = eap_pwd_get_element(data->grp, ptr);
- if (!data->server_element) {
- wpa_printf(MSG_INFO, "EAP-PWD (peer): setting peer element "
- "fail");
- goto fin;
- }
- ptr += prime_len * 2;
-- data->server_scalar = crypto_bignum_init_set(ptr, order_len);
-+ data->server_scalar = eap_pwd_get_scalar(data->grp, ptr);
- if (!data->server_scalar) {
- wpa_printf(MSG_INFO,
- "EAP-PWD (peer): setting peer scalar fail");
- goto fin;
- }
-
-- /* verify received scalar */
-- if (crypto_bignum_is_zero(data->server_scalar) ||
-- crypto_bignum_is_one(data->server_scalar) ||
-- crypto_bignum_cmp(data->server_scalar,
-- crypto_ec_get_order(data->grp->group)) >= 0) {
-- wpa_printf(MSG_INFO,
-- "EAP-PWD (peer): received scalar is invalid");
-- goto fin;
-- }
--
-- /* verify received element */
-- if (!crypto_ec_point_is_on_curve(data->grp->group,
-- data->server_element) ||
-- crypto_ec_point_is_at_infinity(data->grp->group,
-- data->server_element)) {
-- wpa_printf(MSG_INFO,
-- "EAP-PWD (peer): received element is invalid");
-- goto fin;
-- }
--
-- /* check to ensure server's element is not in a small sub-group */
-- if (!crypto_bignum_is_one(cofactor)) {
-- if (crypto_ec_point_mul(data->grp->group, data->server_element,
-- cofactor, point) < 0) {
-- wpa_printf(MSG_INFO, "EAP-PWD (peer): cannot multiply "
-- "server element by order!\n");
-- goto fin;
-- }
-- if (crypto_ec_point_is_at_infinity(data->grp->group, point)) {
-- wpa_printf(MSG_INFO, "EAP-PWD (peer): server element "
-- "is at infinity!\n");
-- goto fin;
-- }
-- }
--
- /* compute the shared key, k */
- if (crypto_ec_point_mul(data->grp->group, data->grp->pwe,
- data->server_scalar, K) < 0 ||
-@@ -702,7 +666,6 @@ fin:
- crypto_bignum_deinit(mask, 1);
- crypto_bignum_deinit(cofactor, 1);
- crypto_ec_point_deinit(K, 1);
-- crypto_ec_point_deinit(point, 1);
- if (data->outbuf == NULL)
- eap_pwd_state(data, FAILURE);
- else
---- a/src/eap_server/eap_server_pwd.c
-+++ b/src/eap_server/eap_server_pwd.c
-@@ -669,7 +669,7 @@ eap_pwd_process_commit_resp(struct eap_s
- {
- const u8 *ptr;
- struct crypto_bignum *cofactor = NULL;
-- struct crypto_ec_point *K = NULL, *point = NULL;
-+ struct crypto_ec_point *K = NULL;
- int res = 0;
- size_t prime_len, order_len;
-
-@@ -688,9 +688,8 @@ eap_pwd_process_commit_resp(struct eap_s
-
- data->k = crypto_bignum_init();
- cofactor = crypto_bignum_init();
-- point = crypto_ec_point_init(data->grp->group);
- K = crypto_ec_point_init(data->grp->group);
-- if (!data->k || !cofactor || !point || !K) {
-+ if (!data->k || !cofactor || !K) {
- wpa_printf(MSG_INFO, "EAP-PWD (server): peer data allocation "
- "fail");
- goto fin;
-@@ -704,55 +703,20 @@ eap_pwd_process_commit_resp(struct eap_s
-
- /* element, x then y, followed by scalar */
- ptr = payload;
-- data->peer_element = crypto_ec_point_from_bin(data->grp->group, ptr);
-+ data->peer_element = eap_pwd_get_element(data->grp, ptr);
- if (!data->peer_element) {
- wpa_printf(MSG_INFO, "EAP-PWD (server): setting peer element "
- "fail");
- goto fin;
- }
- ptr += prime_len * 2;
-- data->peer_scalar = crypto_bignum_init_set(ptr, order_len);
-+ data->peer_scalar = eap_pwd_get_scalar(data->grp, ptr);
- if (!data->peer_scalar) {
- wpa_printf(MSG_INFO, "EAP-PWD (server): peer data allocation "
- "fail");
- goto fin;
- }
-
-- /* verify received scalar */
-- if (crypto_bignum_is_zero(data->peer_scalar) ||
-- crypto_bignum_is_one(data->peer_scalar) ||
-- crypto_bignum_cmp(data->peer_scalar,
-- crypto_ec_get_order(data->grp->group)) >= 0) {
-- wpa_printf(MSG_INFO,
-- "EAP-PWD (server): received scalar is invalid");
-- goto fin;
-- }
--
-- /* verify received element */
-- if (!crypto_ec_point_is_on_curve(data->grp->group,
-- data->peer_element) ||
-- crypto_ec_point_is_at_infinity(data->grp->group,
-- data->peer_element)) {
-- wpa_printf(MSG_INFO,
-- "EAP-PWD (server): received element is invalid");
-- goto fin;
-- }
--
-- /* check to ensure peer's element is not in a small sub-group */
-- if (!crypto_bignum_is_one(cofactor)) {
-- if (crypto_ec_point_mul(data->grp->group, data->peer_element,
-- cofactor, point) != 0) {
-- wpa_printf(MSG_INFO, "EAP-PWD (server): cannot "
-- "multiply peer element by order");
-- goto fin;
-- }
-- if (crypto_ec_point_is_at_infinity(data->grp->group, point)) {
-- wpa_printf(MSG_INFO, "EAP-PWD (server): peer element "
-- "is at infinity!\n");
-- goto fin;
-- }
-- }
--
- /* detect reflection attacks */
- if (crypto_bignum_cmp(data->my_scalar, data->peer_scalar) == 0 ||
- crypto_ec_point_cmp(data->grp->group, data->my_element,
-@@ -804,7 +768,6 @@ eap_pwd_process_commit_resp(struct eap_s
-
- fin:
- crypto_ec_point_deinit(K, 1);
-- crypto_ec_point_deinit(point, 1);
- crypto_bignum_deinit(cofactor, 1);
-
- if (res)
deleted file mode 100644
@@ -1,40 +0,0 @@
-From fe76f487e28bdc61940f304f153a954cf36935ea Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Wed, 17 Apr 2019 01:55:32 +0300
-Subject: [PATCH 1/3] EAP-pwd server: Fix reassembly buffer handling
-
-data->inbuf allocation might fail and if that were to happen, the next
-fragment in the exchange could have resulted in NULL pointer
-dereference. Unexpected fragment with more bit might also be able to
-trigger this. Fix that by explicitly checking for data->inbuf to be
-available before using it.
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/eap_server/eap_server_pwd.c | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
---- a/src/eap_server/eap_server_pwd.c
-+++ b/src/eap_server/eap_server_pwd.c
-@@ -947,6 +947,12 @@ static void eap_pwd_process(struct eap_s
- * the first and all intermediate fragments have the M bit set
- */
- if (EAP_PWD_GET_MORE_BIT(lm_exch) || data->in_frag_pos) {
-+ if (!data->inbuf) {
-+ wpa_printf(MSG_DEBUG,
-+ "EAP-pwd: No buffer for reassembly");
-+ eap_pwd_state(data, FAILURE);
-+ return;
-+ }
- if ((data->in_frag_pos + len) > wpabuf_size(data->inbuf)) {
- wpa_printf(MSG_DEBUG, "EAP-pwd: Buffer overflow "
- "attack detected! (%d+%d > %d)",
-@@ -967,7 +973,7 @@ static void eap_pwd_process(struct eap_s
- * last fragment won't have the M bit set (but we're obviously
- * buffering fragments so that's how we know it's the last)
- */
-- if (data->in_frag_pos) {
-+ if (data->in_frag_pos && data->inbuf) {
- pos = wpabuf_head_u8(data->inbuf);
- len = data->in_frag_pos;
- wpa_printf(MSG_DEBUG, "EAP-pwd: Last fragment, %d bytes",
deleted file mode 100644
@@ -1,40 +0,0 @@
-From d2d1a324ce937628e4d9d9999fe113819b7d4478 Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Wed, 17 Apr 2019 02:21:20 +0300
-Subject: [PATCH 3/3] EAP-pwd peer: Fix reassembly buffer handling
-
-Unexpected fragment might result in data->inbuf not being allocated
-before processing and that could have resulted in NULL pointer
-dereference. Fix that by explicitly checking for data->inbuf to be
-available before using it.
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/eap_peer/eap_pwd.c | 9 ++++++++-
- 1 file changed, 8 insertions(+), 1 deletion(-)
-
---- a/src/eap_peer/eap_pwd.c
-+++ b/src/eap_peer/eap_pwd.c
-@@ -969,6 +969,13 @@ eap_pwd_process(struct eap_sm *sm, void
- * buffer and ACK the fragment
- */
- if (EAP_PWD_GET_MORE_BIT(lm_exch) || data->in_frag_pos) {
-+ if (!data->inbuf) {
-+ wpa_printf(MSG_DEBUG,
-+ "EAP-pwd: No buffer for reassembly");
-+ ret->methodState = METHOD_DONE;
-+ ret->decision = DECISION_FAIL;
-+ return NULL;
-+ }
- data->in_frag_pos += len;
- if (data->in_frag_pos > wpabuf_size(data->inbuf)) {
- wpa_printf(MSG_INFO, "EAP-pwd: Buffer overflow attack "
-@@ -995,7 +1002,7 @@ eap_pwd_process(struct eap_sm *sm, void
- /*
- * we're buffering and this is the last fragment
- */
-- if (data->in_frag_pos) {
-+ if (data->in_frag_pos && data->inbuf) {
- wpa_printf(MSG_DEBUG, "EAP-pwd: Last fragment, %d bytes",
- (int) len);
- pos = wpabuf_head_u8(data->inbuf);
deleted file mode 100644
@@ -1,40 +0,0 @@
-From 92e1b96c26a84e503847bdd22ebadf697c4031ad Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <j@w1.fi>
-Date: Sat, 13 Apr 2019 17:20:57 +0300
-Subject: EAP-pwd: Disallow ECC groups with a prime under 256 bits
-
-Based on the SAE implementation guidance update to not allow ECC groups
-with a prime that is under 256 bits, reject groups 25, 26, and 27 in
-EAP-pwd.
-
-Signed-off-by: Jouni Malinen <j@w1.fi>
----
- src/eap_common/eap_pwd_common.c | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
-
---- a/src/eap_common/eap_pwd_common.c
-+++ b/src/eap_common/eap_pwd_common.c
-@@ -85,10 +85,23 @@ static int eap_pwd_kdf(const u8 *key, si
- }
-
-
-+static int eap_pwd_suitable_group(u16 num)
-+{
-+ /* Do not allow ECC groups with prime under 256 bits based on guidance
-+ * for the similar design in SAE. */
-+ return num == 19 || num == 20 || num == 21 ||
-+ num == 28 || num == 29 || num == 30;
-+}
-+
-+
- EAP_PWD_group * get_eap_pwd_group(u16 num)
- {
- EAP_PWD_group *grp;
-
-+ if (!eap_pwd_suitable_group(num)) {
-+ wpa_printf(MSG_INFO, "EAP-pwd: unsuitable group %u", num);
-+ return NULL;
-+ }
- grp = os_zalloc(sizeof(EAP_PWD_group));
- if (!grp)
- return NULL;
deleted file mode 100644
@@ -1,54 +0,0 @@
-From db54db11aec763b6fc74715c36e0f9de0d65e206 Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Mon, 8 Apr 2019 18:01:07 +0300
-Subject: SAE: Reject unsuitable groups based on REVmd changes
-
-The rules defining which DH groups are suitable for SAE use were
-accepted into IEEE 802.11 REVmd based on this document:
-https://mentor.ieee.org/802.11/dcn/19/11-19-0387-02-000m-addressing-some-sae-comments.docx
-
-Enforce those rules in production builds of wpa_supplicant and hostapd.
-CONFIG_TESTING_OPTIONS=y builds can still be used to select any o the
-implemented groups to maintain testing coverage.
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- src/common/sae.c | 23 +++++++++++++++++++++++
- 1 file changed, 23 insertions(+)
-
---- a/src/common/sae.c
-+++ b/src/common/sae.c
-@@ -18,10 +18,33 @@
- #include "sae.h"
-
-
-+static int sae_suitable_group(int group)
-+{
-+#ifdef CONFIG_TESTING_OPTIONS
-+ /* Allow all groups for testing purposes in non-production builds. */
-+ return 1;
-+#else /* CONFIG_TESTING_OPTIONS */
-+ /* Enforce REVmd rules on which SAE groups are suitable for production
-+ * purposes: FFC groups whose prime is >= 3072 bits and ECC groups
-+ * defined over a prime field whose prime is >= 256 bits. Furthermore,
-+ * ECC groups defined over a characteristic 2 finite field and ECC
-+ * groups with a co-factor greater than 1 are not suitable. */
-+ return group == 19 || group == 20 || group == 21 ||
-+ group == 28 || group == 29 || group == 30 ||
-+ group == 15 || group == 16 || group == 17 || group == 18;
-+#endif /* CONFIG_TESTING_OPTIONS */
-+}
-+
-+
- int sae_set_group(struct sae_data *sae, int group)
- {
- struct sae_temporary_data *tmp;
-
-+ if (!sae_suitable_group(group)) {
-+ wpa_printf(MSG_DEBUG, "SAE: Reject unsuitable group %d", group);
-+ return -1;
-+ }
-+
- sae_clear_data(sae);
- tmp = sae->tmp = os_zalloc(sizeof(*tmp));
- if (tmp == NULL)
@@ -32,19 +32,19 @@ Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
+ if (crypto_bignum_to_bin(prime, prime_bin, sizeof(prime_bin),
+ primebytelen) < 0)
+ return -1;
- cofactor = crypto_bignum_init();
grp->pwe = crypto_ec_point_init(grp->group);
tmp1 = crypto_bignum_init();
-@@ -176,8 +182,6 @@ int compute_password_element(EAP_PWD_gro
- "curve");
+ pm1 = crypto_bignum_init();
+@@ -170,8 +176,6 @@ int compute_password_element(EAP_PWD_gro
goto fail;
}
+
- primebitlen = crypto_ec_prime_len_bits(grp->group);
- primebytelen = crypto_ec_prime_len(grp->group);
if ((prfbuf = os_malloc(primebytelen)) == NULL) {
wpa_printf(MSG_INFO, "EAP-pwd: unable to malloc space for prf "
"buffer");
-@@ -243,6 +247,8 @@ int compute_password_element(EAP_PWD_gro
+@@ -237,6 +241,8 @@ int compute_password_element(EAP_PWD_gro
if (primebitlen % 8)
buf_shift_right(prfbuf, primebytelen,
8 - primebitlen % 8);
@@ -53,7 +53,7 @@ Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
crypto_bignum_deinit(x_candidate, 1);
x_candidate = crypto_bignum_init_set(prfbuf, primebytelen);
-@@ -252,9 +258,6 @@ int compute_password_element(EAP_PWD_gro
+@@ -246,9 +252,6 @@ int compute_password_element(EAP_PWD_gro
goto fail;
}
@@ -21,7 +21,7 @@ Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
--- a/src/crypto/crypto_openssl.c
+++ b/src/crypto/crypto_openssl.c
-@@ -1227,7 +1227,13 @@ void crypto_bignum_deinit(struct crypto_
+@@ -1295,7 +1295,13 @@ void crypto_bignum_deinit(struct crypto_
int crypto_bignum_to_bin(const struct crypto_bignum *a,
u8 *buf, size_t buflen, size_t padlen)
{
@@ -35,7 +35,7 @@ Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
if (TEST_FAIL())
return -1;
-@@ -1235,6 +1241,14 @@ int crypto_bignum_to_bin(const struct cr
+@@ -1303,6 +1309,14 @@ int crypto_bignum_to_bin(const struct cr
if (padlen > buflen)
return -1;
@@ -50,7 +50,7 @@ Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
num_bytes = BN_num_bytes((const BIGNUM *) a);
if ((size_t) num_bytes > buflen)
return -1;
-@@ -1247,6 +1261,8 @@ int crypto_bignum_to_bin(const struct cr
+@@ -1315,6 +1329,8 @@ int crypto_bignum_to_bin(const struct cr
BN_bn2bin((const BIGNUM *) a, buf + offset);
return num_bytes + offset;
@@ -17,7 +17,7 @@ Signed-off-by: Jouni Malinen <j@w1.fi>
--- a/src/eap_common/eap_pwd_common.c
+++ b/src/eap_common/eap_pwd_common.c
@@ -155,6 +155,8 @@ int compute_password_element(EAP_PWD_gro
- struct crypto_bignum *x_candidate = NULL, *cofactor = NULL;
+ struct crypto_bignum *x_candidate = NULL;
const struct crypto_bignum *prime;
u8 mask, found_ctr = 0, is_odd = 0;
+ int cmp_prime;
@@ -25,7 +25,7 @@ Signed-off-by: Jouni Malinen <j@w1.fi>
if (grp->pwe)
return -1;
-@@ -247,8 +249,13 @@ int compute_password_element(EAP_PWD_gro
+@@ -241,8 +243,13 @@ int compute_password_element(EAP_PWD_gro
if (primebitlen % 8)
buf_shift_right(prfbuf, primebytelen,
8 - primebitlen % 8);
@@ -41,7 +41,7 @@ Signed-off-by: Jouni Malinen <j@w1.fi>
crypto_bignum_deinit(x_candidate, 1);
x_candidate = crypto_bignum_init_set(prfbuf, primebytelen);
-@@ -311,7 +318,7 @@ int compute_password_element(EAP_PWD_gro
+@@ -306,7 +313,7 @@ int compute_password_element(EAP_PWD_gro
goto fail;
mask = const_time_eq(res, check);
found_ctr = const_time_select_u8(found, found_ctr, ctr);
@@ -23,7 +23,7 @@ Signed-off-by: Jouni Malinen <j@w1.fi>
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
-@@ -129,6 +129,19 @@ int hostapd_notif_assoc(struct hostapd_d
+@@ -131,6 +131,19 @@ int hostapd_notif_assoc(struct hostapd_d
"hostapd_notif_assoc: Skip event with no address");
return -1;
}
@@ -45,7 +45,7 @@ Signed-off-by: Jouni Malinen <j@w1.fi>
hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
-@@ -3978,6 +3978,18 @@ int ieee802_11_mgmt(struct hostapd_data
+@@ -4463,6 +4463,18 @@ int ieee802_11_mgmt(struct hostapd_data
fc = le_to_host16(mgmt->frame_control);
stype = WLAN_FC_GET_STYPE(fc);
@@ -1,6 +1,6 @@
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
-@@ -295,9 +295,10 @@ void wpa_supplicant_cancel_auth_timeout(
+@@ -296,9 +296,10 @@ void wpa_supplicant_cancel_auth_timeout(
*/
void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s)
{
@@ -18,7 +18,7 @@
OBJS += ../src/ap/vlan_init.o
OBJS += ../src/ap/vlan_ifconfig.o
OBJS += ../src/ap/vlan.o
-@@ -354,10 +356,14 @@ CFLAGS += -DCONFIG_MBO
+@@ -360,10 +362,14 @@ CFLAGS += -DCONFIG_MBO
OBJS += ../src/ap/mbo_ap.o
endif
@@ -36,7 +36,7 @@
LIBS += $(DRV_AP_LIBS)
ifdef CONFIG_L2_PACKET
-@@ -1274,6 +1280,12 @@ install: $(addprefix $(DESTDIR)$(BINDIR)
+@@ -1286,6 +1292,12 @@ install: $(addprefix $(DESTDIR)$(BINDIR)
BCHECK=../src/drivers/build.hostapd
@@ -49,7 +49,7 @@
hostapd: $(BCHECK) $(OBJS)
$(Q)$(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS)
@$(E) " LD " $@
-@@ -1316,6 +1328,12 @@ ifeq ($(CONFIG_TLS), linux)
+@@ -1328,6 +1340,12 @@ ifeq ($(CONFIG_TLS), linux)
HOBJS += ../src/crypto/crypto_linux.o
endif
@@ -72,7 +72,7 @@
ifndef CONFIG_NO_GITVER
# Add VERSION_STR postfix for builds from a git repository
-@@ -354,7 +355,9 @@ endif
+@@ -362,7 +363,9 @@ endif
ifdef CONFIG_IBSS_RSN
NEED_RSN_AUTHENTICATOR=y
CFLAGS += -DCONFIG_IBSS_RSN
@@ -82,7 +82,7 @@
OBJS += ibss_rsn.o
endif
-@@ -862,6 +865,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS
+@@ -870,6 +873,10 @@ ifdef CONFIG_DYNAMIC_EAP_METHODS
CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS
LIBS += -ldl -rdynamic
endif
@@ -93,7 +93,7 @@
endif
ifdef CONFIG_AP
-@@ -869,9 +876,11 @@ NEED_EAP_COMMON=y
+@@ -877,9 +884,11 @@ NEED_EAP_COMMON=y
NEED_RSN_AUTHENTICATOR=y
CFLAGS += -DCONFIG_AP
OBJS += ap.o
@@ -105,7 +105,7 @@
OBJS += ../src/ap/hostapd.o
OBJS += ../src/ap/wpa_auth_glue.o
OBJS += ../src/ap/utils.o
-@@ -953,6 +962,12 @@ endif
+@@ -961,6 +970,12 @@ endif
ifdef CONFIG_HS20
OBJS += ../src/ap/hs20.o
endif
@@ -118,7 +118,7 @@
endif
ifdef CONFIG_MBO
-@@ -961,7 +976,9 @@ CFLAGS += -DCONFIG_MBO
+@@ -969,7 +984,9 @@ CFLAGS += -DCONFIG_MBO
endif
ifdef NEED_RSN_AUTHENTICATOR
@@ -128,7 +128,7 @@
NEED_AES_WRAP=y
OBJS += ../src/ap/wpa_auth.o
OBJS += ../src/ap/wpa_auth_ie.o
-@@ -1888,6 +1905,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv)
+@@ -1872,6 +1889,12 @@ wpa_priv: $(BCHECK) $(OBJS_priv)
$(OBJS_c) $(OBJS_t) $(OBJS_t2) $(OBJS) $(BCHECK) $(EXTRA_progs): .config
@@ -141,8 +141,8 @@
wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs)
$(Q)$(LDO) $(LDFLAGS) -o wpa_supplicant $(OBJS) $(LIBS) $(EXTRALIBS)
@$(E) " LD " $@
-@@ -1990,6 +2013,12 @@ endif
- -e 's|\@DBUS_INTERFACE\@|$(DBUS_INTERFACE)|g' $< >$@
+@@ -1972,6 +1995,12 @@ endif
+ $(Q)sed -e 's|\@BINDIR\@|$(BINDIR)|g' $< >$@
@$(E) " sed" $<
+dump_cflags:
@@ -156,7 +156,7 @@
wpa_cli.exe: wpa_cli
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
-@@ -5476,8 +5476,8 @@ union wpa_event_data {
+@@ -5551,8 +5551,8 @@ union wpa_event_data {
* Driver wrapper code should call this function whenever an event is received
* from the driver.
*/
@@ -167,7 +167,7 @@
/**
* wpa_supplicant_event_global - Report a driver event for wpa_supplicant
-@@ -5489,7 +5489,7 @@ void wpa_supplicant_event(void *ctx, enu
+@@ -5564,7 +5564,7 @@ void wpa_supplicant_event(void *ctx, enu
* Same as wpa_supplicant_event(), but we search for the interface in
* wpa_global.
*/
@@ -178,7 +178,7 @@
/*
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
-@@ -1540,8 +1540,8 @@ static void hostapd_event_wds_sta_interf
+@@ -1581,8 +1581,8 @@ static void hostapd_event_wds_sta_interf
}
@@ -189,7 +189,7 @@
{
struct hostapd_data *hapd = ctx;
#ifndef CONFIG_NO_STDOUT_DEBUG
-@@ -1770,7 +1770,7 @@ void wpa_supplicant_event(void *ctx, enu
+@@ -1816,7 +1816,7 @@ void wpa_supplicant_event(void *ctx, enu
}
@@ -231,7 +231,7 @@
os_memset(&global, 0, sizeof(global));
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
-@@ -4026,8 +4026,8 @@ static void wpas_event_assoc_reject(stru
+@@ -4176,8 +4176,8 @@ static void wpas_event_assoc_reject(stru
}
@@ -242,7 +242,7 @@
{
struct wpa_supplicant *wpa_s = ctx;
int resched;
-@@ -4796,7 +4796,7 @@ void wpa_supplicant_event(void *ctx, enu
+@@ -4951,7 +4951,7 @@ void wpa_supplicant_event(void *ctx, enu
}
@@ -253,7 +253,7 @@
struct wpa_supplicant *wpa_s;
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
-@@ -5861,7 +5861,6 @@ struct wpa_interface * wpa_supplicant_ma
+@@ -6087,7 +6087,6 @@ struct wpa_interface * wpa_supplicant_ma
return NULL;
}
@@ -261,7 +261,7 @@
/**
* wpa_supplicant_match_existing - Match existing interfaces
* @global: Pointer to global data from wpa_supplicant_init()
-@@ -5898,6 +5897,11 @@ static int wpa_supplicant_match_existing
+@@ -6124,6 +6123,11 @@ static int wpa_supplicant_match_existing
#endif /* CONFIG_MATCH_IFACE */
@@ -273,7 +273,7 @@
/**
* wpa_supplicant_add_iface - Add a new network interface
-@@ -6154,6 +6158,8 @@ struct wpa_global * wpa_supplicant_init(
+@@ -6380,6 +6384,8 @@ struct wpa_global * wpa_supplicant_init(
#ifndef CONFIG_NO_WPA_MSG
wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
#endif /* CONFIG_NO_WPA_MSG */
@@ -284,7 +284,7 @@
wpa_debug_open_file(params->wpa_debug_file_path);
--- a/hostapd/main.c
+++ b/hostapd/main.c
-@@ -591,6 +591,11 @@ fail:
+@@ -592,6 +592,11 @@ fail:
return -1;
}
@@ -296,8 +296,8 @@
#ifdef CONFIG_WPS
static int gen_uuid(const char *txt_addr)
-@@ -674,6 +679,8 @@ int main(int argc, char *argv[])
- hostapd_dpp_init_global(&interfaces);
+@@ -677,6 +682,8 @@ int main(int argc, char *argv[])
+ return -1;
#endif /* CONFIG_DPP */
+ wpa_supplicant_event = hostapd_wpa_event;
@@ -333,7 +333,7 @@
const struct wpa_driver_ops *const wpa_drivers[] = { NULL };
-@@ -1295,6 +1300,10 @@ static void usage(void)
+@@ -1296,6 +1301,10 @@ static void usage(void)
"option several times.\n");
}
@@ -344,7 +344,7 @@
int main(int argc, char *argv[])
{
-@@ -1315,6 +1324,8 @@ int main(int argc, char *argv[])
+@@ -1316,6 +1325,8 @@ int main(int argc, char *argv[])
if (os_program_init())
return -1;
@@ -1,8 +1,8 @@
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
-@@ -3317,6 +3317,10 @@ static int hostapd_config_fill(struct ho
- }
- #endif /* CONFIG_IEEE80211W */
+@@ -3390,6 +3390,10 @@ static int hostapd_config_fill(struct ho
+ bss->ieee80211w = 1;
+ #endif /* CONFIG_OCV */
#ifdef CONFIG_IEEE80211N
+ } else if (os_strcmp(buf, "noscan") == 0) {
+ conf->noscan = atoi(pos);
@@ -13,7 +13,7 @@
} else if (os_strcmp(buf, "ht_capab") == 0) {
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
-@@ -781,6 +781,8 @@ struct hostapd_config {
+@@ -803,6 +803,8 @@ struct hostapd_config {
int ht_op_mode_fixed;
u16 ht_capab;
@@ -24,7 +24,7 @@
int no_pri_sec_switch;
--- a/src/ap/hw_features.c
+++ b/src/ap/hw_features.c
-@@ -480,7 +480,8 @@ static int ieee80211n_check_40mhz(struct
+@@ -477,7 +477,8 @@ static int ieee80211n_check_40mhz(struct
int ret;
/* Check that HT40 is used and PRI / SEC switch is allowed */
@@ -1,6 +1,6 @@
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
-@@ -2233,6 +2233,7 @@ static const struct parse_data ssid_fiel
+@@ -2312,6 +2312,7 @@ static const struct parse_data ssid_fiel
#else /* CONFIG_MESH */
{ INT_RANGE(mode, 0, 4) },
#endif /* CONFIG_MESH */
@@ -10,7 +10,7 @@
{ STR(id_str) },
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
-@@ -818,6 +818,7 @@ static void wpa_config_write_network(FIL
+@@ -829,6 +829,7 @@ static void wpa_config_write_network(FIL
#endif /* IEEE8021X_EAPOL */
INT(mode);
INT(no_auto_peer);
@@ -20,7 +20,7 @@
INT(fixed_freq);
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
-@@ -288,6 +288,8 @@ static int wpa_supplicant_mesh_init(stru
+@@ -358,6 +358,8 @@ static int wpa_supplicant_mesh_init(stru
frequency);
goto out_free;
}
@@ -31,7 +31,7 @@
if (conf->hw_mode == HOSTAPD_MODE_IEEE80211A && ssid->vht) {
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
-@@ -2081,12 +2081,12 @@ void ibss_mesh_setup_freq(struct wpa_sup
+@@ -2139,12 +2139,12 @@ void ibss_mesh_setup_freq(struct wpa_sup
{
enum hostapd_hw_mode hw_mode;
struct hostapd_hw_modes *mode = NULL;
@@ -46,7 +46,7 @@
unsigned int j, k;
struct hostapd_freq_params vht_freq;
int chwidth, seg0, seg1;
-@@ -2156,7 +2156,7 @@ void ibss_mesh_setup_freq(struct wpa_sup
+@@ -2214,7 +2214,7 @@ void ibss_mesh_setup_freq(struct wpa_sup
return;
/* Setup higher BW only for 5 GHz */
@@ -57,7 +57,7 @@
for (chan_idx = 0; chan_idx < mode->num_channels; chan_idx++) {
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
-@@ -856,6 +856,8 @@ struct wpa_ssid {
+@@ -916,6 +916,8 @@ struct wpa_ssid {
*/
int no_auto_peer;
@@ -1,6 +1,6 @@
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
-@@ -4312,7 +4312,7 @@ wpa_supplicant_alloc(struct wpa_supplica
+@@ -4465,7 +4465,7 @@ wpa_supplicant_alloc(struct wpa_supplica
if (wpa_s == NULL)
return NULL;
wpa_s->scan_req = INITIAL_SCAN_REQ;
@@ -1,14 +1,14 @@
--- a/src/drivers/drivers.mak
+++ b/src/drivers/drivers.mak
-@@ -49,7 +49,6 @@ NEED_SME=y
+@@ -50,7 +50,6 @@ NEED_SME=y
NEED_AP_MLME=y
NEED_NETLINK=y
NEED_LINUX_IOCTL=y
-NEED_RFKILL=y
NEED_RADIOTAP=y
-
- ifdef CONFIG_LIBNL32
-@@ -136,7 +135,6 @@ DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT
+ NEED_LIBNL=y
+ endif
+@@ -107,7 +106,6 @@ DRV_WPA_CFLAGS += -DCONFIG_DRIVER_WEXT
CONFIG_WIRELESS_EXTENSION=y
NEED_NETLINK=y
NEED_LINUX_IOCTL=y
@@ -16,7 +16,7 @@
endif
ifdef CONFIG_DRIVER_NDIS
-@@ -162,7 +160,6 @@ endif
+@@ -133,7 +131,6 @@ endif
ifdef CONFIG_WIRELESS_EXTENSION
DRV_WPA_CFLAGS += -DCONFIG_WIRELESS_EXTENSION
DRV_WPA_OBJS += ../src/drivers/driver_wext.o
@@ -24,7 +24,7 @@
endif
ifdef NEED_NETLINK
-@@ -175,6 +172,7 @@ endif
+@@ -146,6 +143,7 @@ endif
ifdef NEED_RFKILL
DRV_OBJS += ../src/drivers/rfkill.o
@@ -1,6 +1,6 @@
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
-@@ -4318,7 +4318,7 @@ static int nl80211_set_channel(struct i8
+@@ -4434,7 +4434,7 @@ static int nl80211_set_channel(struct i8
freq->freq, freq->ht_enabled, freq->vht_enabled,
freq->bandwidth, freq->center_freq1, freq->center_freq2);
@@ -1,6 +1,6 @@
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
-@@ -1363,15 +1363,35 @@ int ap_switch_channel(struct wpa_supplic
+@@ -1373,15 +1373,35 @@ int ap_switch_channel(struct wpa_supplic
#ifdef CONFIG_CTRL_IFACE
@@ -1,6 +1,6 @@
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
-@@ -2634,10 +2634,15 @@ static int wpa_driver_nl80211_del_beacon
+@@ -2722,10 +2722,15 @@ static int wpa_driver_nl80211_del_beacon
struct nl_msg *msg;
struct wpa_driver_nl80211_data *drv = bss->drv;
@@ -18,7 +18,7 @@
return send_and_recv_msgs(drv, msg, NULL, NULL);
}
-@@ -4919,7 +4924,7 @@ static void nl80211_teardown_ap(struct i
+@@ -5036,7 +5041,7 @@ static void nl80211_teardown_ap(struct i
nl80211_mgmt_unsubscribe(bss, "AP teardown");
nl80211_put_wiphy_data_ap(bss);
@@ -27,7 +27,7 @@
}
-@@ -7160,8 +7165,6 @@ static int wpa_driver_nl80211_if_remove(
+@@ -7302,8 +7307,6 @@ static int wpa_driver_nl80211_if_remove(
} else {
wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context");
nl80211_teardown_ap(bss);
@@ -36,7 +36,7 @@
nl80211_destroy_bss(bss);
if (!bss->added_if)
i802_set_iface_flags(bss, 0);
-@@ -7540,7 +7543,6 @@ static int wpa_driver_nl80211_deinit_ap(
+@@ -7693,7 +7696,6 @@ static int wpa_driver_nl80211_deinit_ap(
if (!is_ap_interface(drv->nlmode))
return -1;
wpa_driver_nl80211_del_beacon(bss);
@@ -44,7 +44,7 @@
/*
* If the P2P GO interface was dynamically added, then it is
-@@ -7560,7 +7562,6 @@ static int wpa_driver_nl80211_stop_ap(vo
+@@ -7713,7 +7715,6 @@ static int wpa_driver_nl80211_stop_ap(vo
if (!is_ap_interface(drv->nlmode))
return -1;
wpa_driver_nl80211_del_beacon(bss);
@@ -78,7 +78,7 @@
#ifdef CONFIG_IEEE80211W
#ifdef NEED_AP_MLME
-@@ -3084,6 +3141,8 @@ static int hostapd_ctrl_iface_receive_pr
+@@ -3172,6 +3229,8 @@ static int hostapd_ctrl_iface_receive_pr
} else if (os_strncmp(buf, "VENDOR ", 7) == 0) {
reply_len = hostapd_ctrl_iface_vendor(hapd, buf + 7, reply,
reply_size);
@@ -89,7 +89,7 @@
#ifdef RADIUS_SERVER
--- a/src/ap/ctrl_iface_ap.c
+++ b/src/ap/ctrl_iface_ap.c
-@@ -864,7 +864,13 @@ int hostapd_parse_csa_settings(const cha
+@@ -872,7 +872,13 @@ int hostapd_parse_csa_settings(const cha
int hostapd_ctrl_iface_stop_ap(struct hostapd_data *hapd)
{
@@ -11,7 +11,7 @@
-include .config
-include $(if $(MULTICALL),../hostapd/.config)
-@@ -117,6 +121,8 @@ OBJS_c += ../src/utils/common.o
+@@ -116,6 +120,8 @@ OBJS_c += ../src/utils/common.o
OBJS_c += ../src/common/cli.o
OBJS += wmm_ac.o
@@ -110,7 +110,7 @@
break;
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
-@@ -125,6 +125,55 @@ static void wpas_update_fils_connect_par
+@@ -126,6 +126,55 @@ static void wpas_update_fils_connect_par
#endif /* CONFIG_FILS && IEEE8021X_EAPOL */
@@ -166,7 +166,7 @@
/* Configure default/group WEP keys for static WEP */
int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
{
-@@ -920,12 +969,16 @@ void wpa_supplicant_set_state(struct wpa
+@@ -940,12 +989,16 @@ void wpa_supplicant_set_state(struct wpa
sme_sched_obss_scan(wpa_s, 1);
@@ -183,7 +183,7 @@
wpa_s->new_connection = 1;
wpa_drv_set_operstate(wpa_s, 0);
#ifndef IEEE8021X_EAPOL
-@@ -1977,6 +2030,8 @@ void wpa_supplicant_associate(struct wpa
+@@ -2035,6 +2088,8 @@ void wpa_supplicant_associate(struct wpa
wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
ssid->id);
wpas_notify_mesh_group_started(wpa_s, ssid);
@@ -192,7 +192,7 @@
#else /* CONFIG_MESH */
wpa_msg(wpa_s, MSG_ERROR,
"mesh mode support not included in the build");
-@@ -5487,6 +5542,16 @@ static int wpa_supplicant_init_iface(str
+@@ -5707,6 +5762,16 @@ static int wpa_supplicant_init_iface(str
sizeof(wpa_s->bridge_ifname));
}
@@ -209,7 +209,7 @@
/* RSNA Supplicant Key Management - INITIALIZE */
eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
-@@ -5808,6 +5873,11 @@ static void wpa_supplicant_deinit_iface(
+@@ -6034,6 +6099,11 @@ static void wpa_supplicant_deinit_iface(
if (terminate)
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
@@ -235,7 +235,7 @@
* bridge_ifname - Optional bridge interface name
*
* If the driver interface (ifname) is included in a Linux bridge
-@@ -513,6 +518,8 @@ struct wpa_supplicant {
+@@ -516,6 +521,8 @@ struct wpa_supplicant {
#endif /* CONFIG_CTRL_IFACE_BINDER */
char bridge_ifname[16];
@@ -246,7 +246,7 @@
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
-@@ -2328,6 +2328,11 @@ static int hostapd_ctrl_iface_chan_switc
+@@ -2385,6 +2385,11 @@ static int hostapd_ctrl_iface_chan_switc
if (ret)
return ret;
@@ -260,7 +260,7 @@
/* Save CHAN_SWITCH VHT config */
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
-@@ -1381,11 +1381,6 @@ int ieee802_11_set_beacon(struct hostapd
+@@ -1397,11 +1397,6 @@ int ieee802_11_set_beacon(struct hostapd
struct wpabuf *beacon, *proberesp, *assocresp;
int res, ret = -1;
@@ -274,7 +274,7 @@
if (ieee802_11_build_ap_params(hapd, ¶ms) < 0)
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
-@@ -4469,6 +4469,13 @@ enum wpa_event_type {
+@@ -4544,6 +4544,13 @@ enum wpa_event_type {
EVENT_CH_SWITCH,
/**
@@ -288,7 +288,7 @@
* EVENT_WNM - Request WNM operation
*
* This event can be used to request a WNM operation to be performed.
-@@ -5306,6 +5313,7 @@ union wpa_event_data {
+@@ -5381,6 +5388,7 @@ union wpa_event_data {
/**
* struct ch_switch
@@ -296,7 +296,7 @@
* @freq: Frequency of new channel in MHz
* @ht_enabled: Whether this is an HT channel
* @ch_offset: Secondary channel offset
-@@ -5314,6 +5322,7 @@ union wpa_event_data {
+@@ -5389,6 +5397,7 @@ union wpa_event_data {
* @cf2: Center frequency 2
*/
struct ch_switch {
@@ -306,7 +306,7 @@
int ch_offset;
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
-@@ -526,7 +526,8 @@ static int calculate_chan_offset(int wid
+@@ -534,7 +534,8 @@ static int calculate_chan_offset(int wid
static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
struct nlattr *ifindex, struct nlattr *freq,
struct nlattr *type, struct nlattr *bw,
@@ -316,7 +316,7 @@
{
struct i802_bss *bss;
union wpa_event_data data;
-@@ -584,11 +585,15 @@ static void mlme_event_ch_switch(struct
+@@ -592,11 +593,15 @@ static void mlme_event_ch_switch(struct
data.ch_switch.cf1 = nla_get_u32(cf1);
if (cf2)
data.ch_switch.cf2 = nla_get_u32(cf2);
@@ -333,7 +333,7 @@
}
-@@ -2446,6 +2451,7 @@ static void do_process_drv_event(struct
+@@ -2508,6 +2513,7 @@ static void do_process_drv_event(struct
tb[NL80211_ATTR_PMK],
tb[NL80211_ATTR_PMKID]);
break;
@@ -341,7 +341,7 @@
case NL80211_CMD_CH_SWITCH_NOTIFY:
mlme_event_ch_switch(drv,
tb[NL80211_ATTR_IFINDEX],
-@@ -2453,7 +2459,8 @@ static void do_process_drv_event(struct
+@@ -2515,7 +2521,8 @@ static void do_process_drv_event(struct
tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
tb[NL80211_ATTR_CHANNEL_WIDTH],
tb[NL80211_ATTR_CENTER_FREQ1],
@@ -353,7 +353,7 @@
mlme_event_disconnect(drv, tb[NL80211_ATTR_REASON_CODE],
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
-@@ -4026,6 +4026,60 @@ static void wpas_event_assoc_reject(stru
+@@ -4176,6 +4176,60 @@ static void wpas_event_assoc_reject(stru
}
@@ -414,7 +414,7 @@
void supplicant_event(void *ctx, enum wpa_event_type event,
union wpa_event_data *data)
{
-@@ -4309,6 +4363,10 @@ void supplicant_event(void *ctx, enum wp
+@@ -4461,6 +4515,10 @@ void supplicant_event(void *ctx, enum wp
data->rx_from_unknown.wds);
break;
#endif /* CONFIG_AP */
@@ -12,7 +12,7 @@
else
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
-@@ -2912,6 +2912,7 @@ static int hostapd_ctrl_iface_receive_pr
+@@ -2997,6 +2997,7 @@ static int hostapd_ctrl_iface_receive_pr
reply_size);
} else if (os_strcmp(buf, "STATUS-DRIVER") == 0) {
reply_len = hostapd_drv_status(hapd, reply, reply_size);
@@ -20,7 +20,7 @@
} else if (os_strcmp(buf, "MIB") == 0) {
reply_len = ieee802_11_get_mib(hapd, reply, reply_size);
if (reply_len >= 0) {
-@@ -2953,6 +2954,7 @@ static int hostapd_ctrl_iface_receive_pr
+@@ -3038,6 +3039,7 @@ static int hostapd_ctrl_iface_receive_pr
} else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
reply_len = hostapd_ctrl_iface_sta_next(hapd, buf + 9, reply,
reply_size);
@@ -30,7 +30,7 @@
reply_len = -1;
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
-@@ -927,6 +927,9 @@ ifdef CONFIG_FILS
+@@ -935,6 +935,9 @@ ifdef CONFIG_FILS
OBJS += ../src/ap/fils_hlp.o
endif
ifdef CONFIG_CTRL_IFACE
@@ -42,7 +42,7 @@
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
-@@ -2117,7 +2117,7 @@ static int wpa_supplicant_ctrl_iface_sta
+@@ -2144,7 +2144,7 @@ static int wpa_supplicant_ctrl_iface_sta
pos += ret;
}
@@ -51,7 +51,7 @@
if (wpa_s->ap_iface) {
pos += ap_ctrl_iface_wpa_get_status(wpa_s, pos,
end - pos,
-@@ -9852,6 +9852,7 @@ char * wpa_supplicant_ctrl_iface_process
+@@ -9968,6 +9968,7 @@ char * wpa_supplicant_ctrl_iface_process
reply_len = -1;
} else if (os_strncmp(buf, "NOTE ", 5) == 0) {
wpa_printf(MSG_INFO, "NOTE: %s", buf + 5);
@@ -59,15 +59,15 @@
} else if (os_strcmp(buf, "MIB") == 0) {
reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size);
if (reply_len >= 0) {
-@@ -9859,6 +9860,7 @@ char * wpa_supplicant_ctrl_iface_process
- reply + reply_len,
- reply_size - reply_len);
+@@ -9980,6 +9981,7 @@ char * wpa_supplicant_ctrl_iface_process
+ reply_size - reply_len);
+ #endif /* CONFIG_MACSEC */
}
+#endif
} else if (os_strncmp(buf, "STATUS", 6) == 0) {
reply_len = wpa_supplicant_ctrl_iface_status(
wpa_s, buf + 6, reply, reply_size);
-@@ -10340,6 +10342,7 @@ char * wpa_supplicant_ctrl_iface_process
+@@ -10461,6 +10463,7 @@ char * wpa_supplicant_ctrl_iface_process
reply_len = wpa_supplicant_ctrl_iface_bss(
wpa_s, buf + 4, reply, reply_size);
#ifdef CONFIG_AP
@@ -75,7 +75,7 @@
} else if (os_strcmp(buf, "STA-FIRST") == 0) {
reply_len = ap_ctrl_iface_sta_first(wpa_s, reply, reply_size);
} else if (os_strncmp(buf, "STA ", 4) == 0) {
-@@ -10348,12 +10351,15 @@ char * wpa_supplicant_ctrl_iface_process
+@@ -10469,12 +10472,15 @@ char * wpa_supplicant_ctrl_iface_process
} else if (os_strncmp(buf, "STA-NEXT ", 9) == 0) {
reply_len = ap_ctrl_iface_sta_next(wpa_s, buf + 9, reply,
reply_size);
@@ -101,7 +101,7 @@
static size_t hostapd_write_ht_mcs_bitmask(char *buf, size_t buflen,
size_t curr_len, const u8 *mcs_set)
-@@ -415,6 +416,7 @@ int hostapd_ctrl_iface_sta_next(struct h
+@@ -423,6 +424,7 @@ int hostapd_ctrl_iface_sta_next(struct h
return hostapd_ctrl_iface_sta_mib(hapd, sta->next, buf, buflen);
}
@@ -109,7 +109,7 @@
#ifdef CONFIG_P2P_MANAGER
static int p2p_manager_disconnect(struct hostapd_data *hapd, u16 stype,
-@@ -753,12 +755,12 @@ int hostapd_ctrl_iface_status(struct hos
+@@ -761,12 +763,12 @@ int hostapd_ctrl_iface_status(struct hos
return len;
len += ret;
}
@@ -126,7 +126,7 @@
if (os_snprintf_error(buflen - len, ret))
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
-@@ -2581,6 +2581,7 @@ static const char * bool_txt(Boolean val
+@@ -2579,6 +2579,7 @@ static const char * bool_txt(Boolean val
return val ? "TRUE" : "FALSE";
}
@@ -134,7 +134,7 @@
int ieee802_1x_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen)
{
-@@ -2756,6 +2757,7 @@ int ieee802_1x_get_mib_sta(struct hostap
+@@ -2765,6 +2766,7 @@ int ieee802_1x_get_mib_sta(struct hostap
return len;
}
@@ -144,7 +144,7 @@
static void ieee802_1x_wnm_notif_send(void *eloop_ctx, void *timeout_ctx)
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
-@@ -3798,6 +3798,7 @@ static const char * wpa_bool_txt(int val
+@@ -4112,6 +4112,7 @@ static const char * wpa_bool_txt(int val
return val ? "TRUE" : "FALSE";
}
@@ -152,7 +152,7 @@
#define RSN_SUITE "%02x-%02x-%02x-%d"
#define RSN_SUITE_ARG(s) \
-@@ -3942,7 +3943,7 @@ int wpa_get_mib_sta(struct wpa_state_mac
+@@ -4256,7 +4257,7 @@ int wpa_get_mib_sta(struct wpa_state_mac
return len;
}
@@ -163,7 +163,7 @@
{
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
-@@ -2319,6 +2319,8 @@ static u32 wpa_key_mgmt_suite(struct wpa
+@@ -2481,6 +2481,8 @@ static u32 wpa_key_mgmt_suite(struct wpa
}
@@ -172,7 +172,7 @@
#define RSN_SUITE "%02x-%02x-%02x-%d"
#define RSN_SUITE_ARG(s) \
((s) >> 24) & 0xff, ((s) >> 16) & 0xff, ((s) >> 8) & 0xff, (s) & 0xff
-@@ -2402,6 +2404,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, ch
+@@ -2564,6 +2566,7 @@ int wpa_sm_get_mib(struct wpa_sm *sm, ch
return (int) len;
}
@@ -182,7 +182,7 @@
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
-@@ -1221,7 +1221,7 @@ int wpas_ap_wps_nfc_report_handover(stru
+@@ -1231,7 +1231,7 @@ int wpas_ap_wps_nfc_report_handover(stru
#endif /* CONFIG_WPS */
@@ -1,6 +1,6 @@
--- a/src/common/wpa_common.c
+++ b/src/common/wpa_common.c
-@@ -2042,6 +2042,31 @@ u32 wpa_akm_to_suite(int akm)
+@@ -2079,6 +2079,31 @@ u32 wpa_akm_to_suite(int akm)
}
@@ -32,7 +32,7 @@
int wpa_compare_rsn_ie(int ft_initial_assoc,
const u8 *ie1, size_t ie1len,
const u8 *ie2, size_t ie2len)
-@@ -2049,8 +2074,19 @@ int wpa_compare_rsn_ie(int ft_initial_as
+@@ -2086,8 +2111,19 @@ int wpa_compare_rsn_ie(int ft_initial_as
if (ie1 == NULL || ie2 == NULL)
return -1;
@@ -10,7 +10,7 @@
bss->wpa_pairwise |= WPA_CIPHER_TKIP;
bss->rsn_pairwise = bss->wpa_pairwise;
bss->wpa_group = wpa_select_ap_group_cipher(bss->wpa,
-@@ -1069,8 +1068,7 @@ int hostapd_init_wps(struct hostapd_data
+@@ -1108,8 +1107,7 @@ int hostapd_init_wps(struct hostapd_data
WPA_CIPHER_GCMP_256)) {
wps->encr_types |= WPS_ENCR_AES;
wps->encr_types_rsn |= WPS_ENCR_AES;
@@ -43,7 +43,7 @@
{
size_t i, llen;
const u8 *pos = buf;
-@@ -499,20 +487,6 @@ static void _wpa_hexdump_ascii(int level
+@@ -505,20 +493,6 @@ static void _wpa_hexdump_ascii(int level
}
@@ -64,7 +64,7 @@
#ifdef CONFIG_DEBUG_FILE
static char *last_path = NULL;
#endif /* CONFIG_DEBUG_FILE */
-@@ -628,7 +602,7 @@ void wpa_msg_register_ifname_cb(wpa_msg_
+@@ -634,7 +608,7 @@ void wpa_msg_register_ifname_cb(wpa_msg_
}
@@ -73,7 +73,7 @@
{
va_list ap;
char *buf;
-@@ -666,7 +640,7 @@ void wpa_msg(void *ctx, int level, const
+@@ -672,7 +646,7 @@ void wpa_msg(void *ctx, int level, const
}
@@ -8,7 +8,7 @@
#include "crypto/random.h"
#include "crypto/tls.h"
#include "common/version.h"
-@@ -682,7 +683,7 @@ int main(int argc, char *argv[])
+@@ -685,7 +686,7 @@ int main(int argc, char *argv[])
wpa_supplicant_event = hostapd_wpa_event;
wpa_supplicant_event_global = hostapd_wpa_event_global;
for (;;) {
@@ -17,7 +17,7 @@
if (c < 0)
break;
switch (c) {
-@@ -719,6 +720,8 @@ int main(int argc, char *argv[])
+@@ -722,6 +723,8 @@ int main(int argc, char *argv[])
break;
#endif /* CONFIG_DEBUG_LINUX_TRACING */
case 'v':
@@ -47,7 +47,7 @@
switch (c) {
@@ -305,8 +306,12 @@ int main(int argc, char *argv[])
break;
- #endif /* CONFIG_DBUS */
+ #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
case 'v':
- printf("%s\n", wpa_supplicant_version);
- exitcode = 0;
@@ -32,7 +32,7 @@
static int hostapd_cli_cmd_disassoc_imminent(struct wpa_ctrl *ctrl, int argc,
-@@ -1510,15 +1506,12 @@ static const struct hostapd_cli_cmd host
+@@ -1531,15 +1527,12 @@ static const struct hostapd_cli_cmd host
{ "disassociate", hostapd_cli_cmd_disassociate,
hostapd_complete_stations,
"<addr> = disassociate a station" },
@@ -48,7 +48,7 @@
{ "wps_pin", hostapd_cli_cmd_wps_pin, NULL,
"<uuid> <pin> [timeout] [addr] = add WPS Enrollee PIN" },
{ "wps_check_pin", hostapd_cli_cmd_wps_check_pin, NULL,
-@@ -1543,7 +1536,6 @@ static const struct hostapd_cli_cmd host
+@@ -1564,7 +1557,6 @@ static const struct hostapd_cli_cmd host
"<SSID> <auth> <encr> <key> = configure AP" },
{ "wps_get_status", hostapd_cli_cmd_wps_get_status, NULL,
"= show current WPS status" },
@@ -1,6 +1,6 @@
--- a/hostapd/main.c
+++ b/hostapd/main.c
-@@ -38,6 +38,8 @@ struct hapd_global {
+@@ -39,6 +39,8 @@ struct hapd_global {
};
static struct hapd_global global;
@@ -9,7 +9,7 @@
#ifndef CONFIG_NO_HOSTAPD_LOGGER
-@@ -148,6 +150,14 @@ static void hostapd_logger_cb(void *ctx,
+@@ -149,6 +151,14 @@ static void hostapd_logger_cb(void *ctx,
}
#endif /* CONFIG_NO_HOSTAPD_LOGGER */
@@ -24,7 +24,7 @@
/**
* hostapd_driver_init - Preparate driver interface
-@@ -166,6 +176,8 @@ static int hostapd_driver_init(struct ho
+@@ -167,6 +177,8 @@ static int hostapd_driver_init(struct ho
return -1;
}
@@ -33,7 +33,7 @@
/* Initialize the driver interface */
if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5]))
b = NULL;
-@@ -406,8 +418,6 @@ static void hostapd_global_deinit(const
+@@ -407,8 +419,6 @@ static void hostapd_global_deinit(const
#endif /* CONFIG_NATIVE_WINDOWS */
eap_server_unregister_methods();
@@ -42,7 +42,7 @@
}
-@@ -433,18 +443,6 @@ static int hostapd_global_run(struct hap
+@@ -434,18 +444,6 @@ static int hostapd_global_run(struct hap
}
#endif /* EAP_SERVER_TNC */
@@ -61,7 +61,7 @@
eloop_run();
return 0;
-@@ -646,8 +644,7 @@ int main(int argc, char *argv[])
+@@ -647,8 +645,7 @@ int main(int argc, char *argv[])
struct hapd_interfaces interfaces;
int ret = 1;
size_t i, j;
@@ -22,7 +22,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
#include "common/defs.h"
#include "common/ieee802_11_defs.h"
#include "common/wpa_common.h"
-@@ -774,6 +775,9 @@ struct wpa_driver_associate_params {
+@@ -791,6 +792,9 @@ struct wpa_driver_associate_params {
* responsible for selecting with which BSS to associate. */
const u8 *bssid;
@@ -42,7 +42,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
#include "config.h"
-@@ -2053,6 +2054,97 @@ static char * wpa_config_write_peerkey(c
+@@ -2130,6 +2131,97 @@ static char * wpa_config_write_peerkey(c
#endif /* NO_CONFIG_WRITE */
@@ -140,7 +140,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
/* Helper macros for network block parser */
#ifdef OFFSET
-@@ -2298,6 +2390,8 @@ static const struct parse_data ssid_fiel
+@@ -2382,6 +2474,8 @@ static const struct parse_data ssid_fiel
{ INT(ap_max_inactivity) },
{ INT(dtim_period) },
{ INT(beacon_int) },
@@ -162,7 +162,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
#define DEFAULT_EAP_WORKAROUND ((unsigned int) -1)
-@@ -757,6 +759,9 @@ struct wpa_ssid {
+@@ -788,6 +790,9 @@ struct wpa_ssid {
*/
void *parent_cred;
@@ -174,7 +174,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
* macsec_policy - Determines the policy for MACsec secure session
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
-@@ -3117,6 +3117,12 @@ static void wpas_start_assoc_cb(struct w
+@@ -3258,6 +3258,12 @@ static void wpas_start_assoc_cb(struct w
params.beacon_int = ssid->beacon_int;
else
params.beacon_int = wpa_s->conf->beacon_int;
@@ -10,7 +10,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
-@@ -5178,7 +5178,7 @@ static int wpa_driver_nl80211_ibss(struc
+@@ -5295,7 +5295,7 @@ static int wpa_driver_nl80211_ibss(struc
struct wpa_driver_associate_params *params)
{
struct nl_msg *msg;
@@ -19,7 +19,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
int count = 0;
wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
-@@ -5205,6 +5205,37 @@ retry:
+@@ -5322,6 +5322,37 @@ retry:
nl80211_put_beacon_int(msg, params->beacon_int))
goto fail;
@@ -19,7 +19,7 @@ Tested-by: Simon Wunderlich <simon.wunderlich@openmesh.com>
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
-@@ -1409,6 +1409,7 @@ struct wpa_driver_mesh_join_params {
+@@ -1443,6 +1443,7 @@ struct wpa_driver_mesh_join_params {
#define WPA_DRIVER_MESH_FLAG_AMPE 0x00000008
unsigned int flags;
u8 handle_dfs;
@@ -29,7 +29,7 @@ Tested-by: Simon Wunderlich <simon.wunderlich@openmesh.com>
/**
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
-@@ -9352,6 +9352,18 @@ static int nl80211_put_mesh_id(struct nl
+@@ -9532,6 +9532,18 @@ static int nl80211_put_mesh_id(struct nl
}
@@ -48,7 +48,7 @@ Tested-by: Simon Wunderlich <simon.wunderlich@openmesh.com>
static int nl80211_put_mesh_config(struct nl_msg *msg,
struct wpa_driver_mesh_bss_params *params)
{
-@@ -9413,6 +9425,7 @@ static int nl80211_join_mesh(struct i802
+@@ -9593,6 +9605,7 @@ static int nl80211_join_mesh(struct i802
nl80211_put_basic_rates(msg, params->basic_rates) ||
nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) ||
nl80211_put_beacon_int(msg, params->beacon_int) ||
@@ -58,7 +58,7 @@ Tested-by: Simon Wunderlich <simon.wunderlich@openmesh.com>
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
-@@ -482,6 +482,7 @@ int wpa_supplicant_join_mesh(struct wpa_
+@@ -491,6 +491,7 @@ int wpa_supplicant_join_mesh(struct wpa_
params->meshid = ssid->ssid;
params->meshid_len = ssid->ssid_len;
@@ -1,6 +1,6 @@
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
-@@ -2154,11 +2154,13 @@ void ibss_mesh_setup_freq(struct wpa_sup
+@@ -2212,11 +2212,13 @@ void ibss_mesh_setup_freq(struct wpa_sup
for (j = 0; j < wpa_s->last_scan_res_used; j++) {
struct wpa_bss *bss = wpa_s->last_scan_res[j];
@@ -1,6 +1,6 @@
--- a/src/ap/acs.c
+++ b/src/ap/acs.c
-@@ -292,18 +292,12 @@ static void acs_fail(struct hostapd_ifac
+@@ -293,18 +293,12 @@ static void acs_fail(struct hostapd_ifac
static long double
acs_survey_interference_factor(struct freq_survey *survey, s8 min_nf)
{
@@ -20,7 +20,7 @@
total = survey->channel_time;
-@@ -392,20 +386,19 @@ static int acs_usable_vht80_chan(struct
+@@ -406,20 +400,19 @@ static int acs_usable_vht160_chan(const
static int acs_survey_is_sufficient(struct freq_survey *survey)
{
if (!(survey->filled & SURVEY_HAS_NF)) {
@@ -1,6 +1,6 @@
--- a/hostapd/Makefile
+++ b/hostapd/Makefile
-@@ -1290,14 +1290,14 @@ hostapd_multi.a: $(BCHECK) $(OBJS)
+@@ -1302,14 +1302,14 @@ hostapd_multi.a: $(BCHECK) $(OBJS)
@$(AR) cr $@ hostapd_multi.o $(OBJS)
hostapd: $(BCHECK) $(OBJS)
@@ -19,7 +19,7 @@
NOBJS = nt_password_hash.o ../src/crypto/ms_funcs.o $(SHA1OBJS)
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
-@@ -1921,23 +1921,23 @@ wpa_supplicant_multi.a: .config $(BCHECK
+@@ -1905,23 +1905,23 @@ wpa_supplicant_multi.a: .config $(BCHECK
@$(AR) cr $@ wpa_supplicant_multi.o $(OBJS)
wpa_supplicant: $(BCHECK) $(OBJS) $(EXTRA_progs)
deleted file mode 100644
@@ -1,306 +0,0 @@
-From 9c06f0f6aed26c1628acaa74df0232dd7b345e9a Mon Sep 17 00:00:00 2001
-From: Venkateswara Naralasetty <vnaralas@codeaurora.org>
-Date: Wed, 5 Dec 2018 11:23:51 +0100
-Subject: [PATCH] hostapd: Add Multi-AP protocol support
-
-The purpose of Multi-AP specification is to enable inter-operability
-across Wi-Fi access points (APs) from different vendors.
-
-This patch introduces one new configuration parameter 'multi_ap' to
-enable Multi-AP functionality and to configure the BSS as a backhaul
-and/or fronthaul BSS.
-
-Advertise vendor specific Multi-AP capabilities in (Re)Association
-Response frame, if Multi-AP functionality is enabled through the
-configuration parameter.
-
-A backhaul AP must support receiving both 3addr and 4addr frames from a
-backhaul STA, so create a VLAN for it just like is done for WDS, i.e.,
-by calling hostapd_set_wds_sta(). Since Multi-AP requires WPA2 (never
-WEP), we can safely call hostapd_set_wds_encryption() as well and we can
-reuse the entire WDS condition.
-
-To parse the Multi-AP Extension subelement, we use get_ie(): even though
-that function is meant for parsing IEs, it works for subelements.
-
-Signed-off-by: Venkateswara Naralasetty <vnaralas@codeaurora.org>
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
-Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
----
- hostapd/config_file.c | 10 +++++
- hostapd/hostapd.conf | 7 ++++
- src/ap/ap_config.h | 4 ++
- src/ap/ieee802_11.c | 77 +++++++++++++++++++++++++++++++++-
- src/ap/sta_info.c | 2 +-
- src/ap/sta_info.h | 1 +
- src/common/ieee802_11_common.c | 24 +++++++++++
- src/common/ieee802_11_common.h | 4 ++
- src/common/ieee802_11_defs.h | 7 ++++
- 9 files changed, 134 insertions(+), 2 deletions(-)
-
---- a/hostapd/config_file.c
-+++ b/hostapd/config_file.c
-@@ -4115,6 +4115,16 @@ static int hostapd_config_fill(struct ho
- } else if (os_strcmp(buf, "coloc_intf_reporting") == 0) {
- bss->coloc_intf_reporting = atoi(pos);
- #endif /* CONFIG_OWE */
-+ } else if (os_strcmp(buf, "multi_ap") == 0) {
-+ int val = atoi(pos);
-+
-+ if (val < 0 || val > 3) {
-+ wpa_printf(MSG_ERROR, "Line %d: Invalid multi_ap '%s'",
-+ line, buf);
-+ return -1;
-+ }
-+
-+ bss->multi_ap = val;
- } else {
- wpa_printf(MSG_ERROR,
- "Line %d: unknown configuration item '%s'",
---- a/hostapd/hostapd.conf
-+++ b/hostapd/hostapd.conf
-@@ -438,6 +438,13 @@ wmm_ac_vo_txop_limit=47
- wmm_ac_vo_acm=0
- # Note: for IEEE 802.11b mode: cWmin=3 cWmax=4 burst=102
-
-+# Enable Multi-AP functionality
-+# 0 = disabled (default)
-+# 1 = AP support backhaul BSS
-+# 2 = AP support fronthaul BSS
-+# 3 = AP supports both backhaul BSS and fronthaul BSS
-+#multi_ap=0
-+
- # Static WEP key configuration
- #
- # The key number to use when transmitting.
---- a/src/ap/ap_config.h
-+++ b/src/ap/ap_config.h
-@@ -688,6 +688,10 @@ struct hostapd_bss_config {
- #endif /* CONFIG_OWE */
-
- int coloc_intf_reporting;
-+
-+#define BACKHAUL_BSS 1
-+#define FRONTHAUL_BSS 2
-+ int multi_ap; /* bitmap of BACKHAUL_BSS, FRONTHAUL_BSS */
- };
-
- /**
---- a/src/ap/ieee802_11.c
-+++ b/src/ap/ieee802_11.c
-@@ -62,6 +62,22 @@ prepare_auth_resp_fils(struct hostapd_da
- int *is_pub);
- #endif /* CONFIG_FILS */
-
-+
-+u8 * hostapd_eid_multi_ap(struct hostapd_data *hapd, u8 *eid)
-+{
-+ u8 multi_ap_val = 0;
-+
-+ if (!hapd->conf->multi_ap)
-+ return eid;
-+ if (hapd->conf->multi_ap & BACKHAUL_BSS)
-+ multi_ap_val |= MULTI_AP_BACKHAUL_BSS;
-+ if (hapd->conf->multi_ap & FRONTHAUL_BSS)
-+ multi_ap_val |= MULTI_AP_FRONTHAUL_BSS;
-+
-+ return eid + add_multi_ap_ie(eid, 9, multi_ap_val);
-+}
-+
-+
- u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid)
- {
- u8 *pos = eid;
-@@ -2210,6 +2226,57 @@ static u16 check_wmm(struct hostapd_data
- return WLAN_STATUS_SUCCESS;
- }
-
-+static u16 check_multi_ap(struct hostapd_data *hapd, struct sta_info *sta,
-+ const u8 *multi_ap_ie, size_t multi_ap_len)
-+{
-+ u8 multi_ap_value = 0;
-+
-+ sta->flags &= ~WLAN_STA_MULTI_AP;
-+
-+ if (!hapd->conf->multi_ap)
-+ return WLAN_STATUS_SUCCESS;
-+
-+ if (multi_ap_ie) {
-+ const u8 *multi_ap_subelem;
-+
-+ multi_ap_subelem = get_ie(multi_ap_ie + 4,
-+ multi_ap_len - 4,
-+ MULTI_AP_SUB_ELEM_TYPE);
-+ if (multi_ap_subelem && multi_ap_subelem[1] == 1) {
-+ multi_ap_value = multi_ap_subelem[2];
-+ } else {
-+ hostapd_logger(hapd, sta->addr,
-+ HOSTAPD_MODULE_IEEE80211,
-+ HOSTAPD_LEVEL_INFO,
-+ "Multi-AP IE has missing or invalid Multi-AP subelement");
-+ return WLAN_STATUS_INVALID_IE;
-+ }
-+ }
-+
-+ if (multi_ap_value == MULTI_AP_BACKHAUL_STA)
-+ sta->flags |= WLAN_STA_MULTI_AP;
-+
-+ if ((hapd->conf->multi_ap & BACKHAUL_BSS) &&
-+ multi_ap_value == MULTI_AP_BACKHAUL_STA)
-+ return WLAN_STATUS_SUCCESS;
-+
-+ if (hapd->conf->multi_ap & FRONTHAUL_BSS) {
-+ if (multi_ap_value == MULTI_AP_BACKHAUL_STA) {
-+ hostapd_logger(hapd, sta->addr,
-+ HOSTAPD_MODULE_IEEE80211,
-+ HOSTAPD_LEVEL_INFO,
-+ "Backhaul STA tries to associate with fronthaul-only BSS");
-+ return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
-+ }
-+ return WLAN_STATUS_SUCCESS;
-+ }
-+
-+ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
-+ HOSTAPD_LEVEL_INFO,
-+ "Non-Multi-AP STA tries to associate with backhaul-only BSS");
-+ return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
-+}
-+
-
- static u16 copy_supp_rates(struct hostapd_data *hapd, struct sta_info *sta,
- struct ieee802_11_elems *elems)
-@@ -2466,6 +2533,11 @@ static u16 check_assoc_ies(struct hostap
- resp = copy_supp_rates(hapd, sta, &elems);
- if (resp != WLAN_STATUS_SUCCESS)
- return resp;
-+
-+ resp = check_multi_ap(hapd, sta, elems.multi_ap, elems.multi_ap_len);
-+ if (resp != WLAN_STATUS_SUCCESS)
-+ return resp;
-+
- #ifdef CONFIG_IEEE80211N
- resp = copy_sta_ht_capab(hapd, sta, elems.ht_capabilities);
- if (resp != WLAN_STATUS_SUCCESS)
-@@ -2996,6 +3068,9 @@ static u16 send_assoc_resp(struct hostap
- }
- #endif /* CONFIG_WPS */
-
-+ if (sta && (sta->flags & WLAN_STA_MULTI_AP))
-+ p = hostapd_eid_multi_ap(hapd, p);
-+
- #ifdef CONFIG_P2P
- if (sta && sta->p2p_ie && hapd->p2p_group) {
- struct wpabuf *p2p_resp_ie;
-@@ -4248,7 +4323,7 @@ static void handle_assoc_cb(struct hosta
- sta->flags |= WLAN_STA_WDS;
- }
-
-- if (sta->flags & WLAN_STA_WDS) {
-+ if (sta->flags & (WLAN_STA_WDS | WLAN_STA_MULTI_AP)) {
- int ret;
- char ifname_wds[IFNAMSIZ + 1];
-
---- a/src/ap/sta_info.c
-+++ b/src/ap/sta_info.c
-@@ -166,7 +166,7 @@ void ap_free_sta(struct hostapd_data *ha
- /* just in case */
- ap_sta_set_authorized(hapd, sta, 0);
-
-- if (sta->flags & WLAN_STA_WDS)
-+ if (sta->flags & (WLAN_STA_WDS | WLAN_STA_MULTI_AP))
- hostapd_set_wds_sta(hapd, NULL, sta->addr, sta->aid, 0);
-
- if (sta->ipaddr)
---- a/src/ap/sta_info.h
-+++ b/src/ap/sta_info.h
-@@ -36,6 +36,7 @@
- #define WLAN_STA_VHT_OPMODE_ENABLED BIT(20)
- #define WLAN_STA_VENDOR_VHT BIT(21)
- #define WLAN_STA_PENDING_FILS_ERP BIT(22)
-+#define WLAN_STA_MULTI_AP BIT(23)
- #define WLAN_STA_PENDING_DISASSOC_CB BIT(29)
- #define WLAN_STA_PENDING_DEAUTH_CB BIT(30)
- #define WLAN_STA_NONERP BIT(31)
---- a/src/common/ieee802_11_common.c
-+++ b/src/common/ieee802_11_common.c
-@@ -126,6 +126,10 @@ static int ieee802_11_parse_vendor_speci
- elems->roaming_cons_sel = pos;
- elems->roaming_cons_sel_len = elen;
- break;
-+ case MULTI_AP_OUI_TYPE:
-+ elems->multi_ap = pos;
-+ elems->multi_ap_len = elen;
-+ break;
- default:
- wpa_printf(MSG_MSGDUMP, "Unknown WFA "
- "information element ignored "
-@@ -1519,6 +1523,26 @@ size_t mbo_add_ie(u8 *buf, size_t len, c
- }
-
-
-+size_t add_multi_ap_ie(u8 *buf, size_t len, u8 value)
-+{
-+ u8 *pos = buf;
-+
-+ if (len < 9)
-+ return 0;
-+
-+ *pos++ = WLAN_EID_VENDOR_SPECIFIC;
-+ *pos++ = 7; /* len */
-+ WPA_PUT_BE24(pos, OUI_WFA);
-+ pos += 3;
-+ *pos++ = MULTI_AP_OUI_TYPE;
-+ *pos++ = MULTI_AP_SUB_ELEM_TYPE;
-+ *pos++ = 1; /* len */
-+ *pos++ = value;
-+
-+ return pos - buf;
-+}
-+
-+
- static const struct country_op_class us_op_class[] = {
- { 1, 115 },
- { 2, 118 },
---- a/src/common/ieee802_11_common.h
-+++ b/src/common/ieee802_11_common.h
-@@ -84,6 +84,7 @@ struct ieee802_11_elems {
- const u8 *power_capab;
- const u8 *roaming_cons_sel;
- const u8 *password_id;
-+ const u8 *multi_ap;
-
- u8 ssid_len;
- u8 supp_rates_len;
-@@ -130,6 +131,7 @@ struct ieee802_11_elems {
- u8 power_capab_len;
- u8 roaming_cons_sel_len;
- u8 password_id_len;
-+ u8 multi_ap_len;
-
- struct mb_ies_info mb_ies;
- };
-@@ -189,6 +191,8 @@ const u8 * get_ie_ext(const u8 *ies, siz
-
- size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len);
-
-+size_t add_multi_ap_ie(u8 *buf, size_t len, u8 value);
-+
- struct country_op_class {
- u8 country_op_class;
- u8 global_op_class;
---- a/src/common/ieee802_11_defs.h
-+++ b/src/common/ieee802_11_defs.h
-@@ -1210,6 +1210,13 @@ struct ieee80211_ampe_ie {
- #define MBO_OUI_TYPE 22
- #define OWE_IE_VENDOR_TYPE 0x506f9a1c
- #define OWE_OUI_TYPE 28
-+#define MULTI_AP_OUI_TYPE 0x1B
-+
-+#define MULTI_AP_SUB_ELEM_TYPE 0x06
-+#define MULTI_AP_TEAR_DOWN BIT(4)
-+#define MULTI_AP_FRONTHAUL_BSS BIT(5)
-+#define MULTI_AP_BACKHAUL_BSS BIT(6)
-+#define MULTI_AP_BACKHAUL_STA BIT(7)
-
- #define WMM_OUI_TYPE 2
- #define WMM_OUI_SUBTYPE_INFORMATION_ELEMENT 0
deleted file mode 100644
@@ -1,311 +0,0 @@
-From 5abc7823bd01f69b8afbe1fd19f65fff86137c44 Mon Sep 17 00:00:00 2001
-From: Venkateswara Naralasetty <vnaralas@codeaurora.org>
-Date: Wed, 5 Dec 2018 11:23:53 +0100
-Subject: [PATCH] wpa_supplicant: Add Multi-AP backhaul STA support
-
-Advertise vendor specific Multi-AP IE in (Re)Association Request frames
-and process Multi-AP IE from (Re)Association Response frames if the user
-enables Multi-AP fuctionality. If the (Re)Association Response frame
-does not contain the Multi-AP IE, disassociate.
-
-This adds a new configuration parameter 'multi_ap_backhaul_sta' to
-enable/disable Multi-AP functionality.
-
-Enable 4-address mode after association (if the Association Response
-frame contains the Multi-AP IE). Also enable the bridge in that case.
-This is necessary because wpa_supplicant only enables the bridge in
-wpa_drv_if_add(), which only gets called when an interface is added
-through the control interface, not when it is configured from the
-command line.
-
-Signed-off-by: Venkateswara Naralasetty <vnaralas@codeaurora.org>
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
-Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
----
- src/drivers/driver.h | 9 ++++++
- src/drivers/driver_nl80211.c | 44 ++++++++++++++++++++++++++
- wpa_supplicant/config.c | 1 +
- wpa_supplicant/config_ssid.h | 7 +++++
- wpa_supplicant/driver_i.h | 8 +++++
- wpa_supplicant/events.c | 50 ++++++++++++++++++++++++++++++
- wpa_supplicant/sme.c | 16 ++++++++++
- wpa_supplicant/wpa_supplicant.c | 18 +++++++++++
- wpa_supplicant/wpa_supplicant.conf | 7 +++++
- wpa_supplicant/wpa_supplicant_i.h | 1 +
- 10 files changed, 161 insertions(+)
-
---- a/src/drivers/driver.h
-+++ b/src/drivers/driver.h
-@@ -4100,6 +4100,15 @@ struct wpa_driver_ops {
- */
- int (*send_external_auth_status)(void *priv,
- struct external_auth *params);
-+
-+ /**
-+ * set_4addr_mode - Set 4-address mode
-+ * @priv: Private driver interface data
-+ * @bridge_ifname: Bridge interface name
-+ * @val: 0 - disable 4addr mode, 1 - enable 4addr mode
-+ * Returns: 0 on success, < 0 on failure
-+ */
-+ int (*set_4addr_mode)(void *priv, const char *bridge_ifname, int val);
- };
-
- /**
---- a/src/drivers/driver_nl80211.c
-+++ b/src/drivers/driver_nl80211.c
-@@ -10728,6 +10728,49 @@ fail:
- }
-
-
-+static int nl80211_set_4addr_mode(void *priv, const char *bridge_ifname,
-+ int val)
-+{
-+ struct i802_bss *bss = priv;
-+ struct wpa_driver_nl80211_data *drv = bss->drv;
-+ struct nl_msg *msg;
-+ int ret = -ENOBUFS;
-+
-+ wpa_printf(MSG_DEBUG, "nl80211: %s 4addr mode (bridge_ifname: %s)",
-+ val ? "Enable" : "Disable", bridge_ifname);
-+
-+ msg = nl80211_cmd_msg(drv->first_bss, 0, NL80211_CMD_SET_INTERFACE);
-+ if (!msg || nla_put_u8(msg, NL80211_ATTR_4ADDR, val))
-+ goto fail;
-+
-+ if (bridge_ifname[0] && bss->added_if_into_bridge && !val) {
-+ if (linux_br_del_if(drv->global->ioctl_sock,
-+ bridge_ifname, bss->ifname)) {
-+ wpa_printf(MSG_ERROR,
-+ "nl80211: Failed to remove interface %s from bridge %s",
-+ bss->ifname, bridge_ifname);
-+ return -1;
-+ }
-+ bss->added_if_into_bridge = 0;
-+ }
-+
-+ ret = send_and_recv_msgs(drv, msg, NULL, NULL);
-+ msg = NULL;
-+ if (!ret) {
-+ if (bridge_ifname[0] && val &&
-+ i802_check_bridge(drv, bss, bridge_ifname, bss->ifname) < 0)
-+ return -1;
-+ return 0;
-+ }
-+
-+fail:
-+ nlmsg_free(msg);
-+ wpa_printf(MSG_ERROR, "nl80211: Failed to enable/disable 4addr");
-+
-+ return ret;
-+}
-+
-+
- const struct wpa_driver_ops wpa_driver_nl80211_ops = {
- .name = "nl80211",
- .desc = "Linux nl80211/cfg80211",
-@@ -10856,4 +10899,5 @@ const struct wpa_driver_ops wpa_driver_n
- .get_ext_capab = nl80211_get_ext_capab,
- .update_connect_params = nl80211_update_connection_params,
- .send_external_auth_status = nl80211_send_external_auth_status,
-+ .set_4addr_mode = nl80211_set_4addr_mode,
- };
---- a/wpa_supplicant/config.c
-+++ b/wpa_supplicant/config.c
-@@ -2416,6 +2416,7 @@ static const struct parse_data ssid_fiel
- #endif /* CONFIG_DPP */
- { INT_RANGE(owe_group, 0, 65535) },
- { INT_RANGE(owe_only, 0, 1) },
-+ { INT_RANGE(multi_ap_backhaul_sta, 0, 1) },
- };
-
- #undef OFFSET
---- a/wpa_supplicant/config_ssid.h
-+++ b/wpa_supplicant/config_ssid.h
-@@ -950,6 +950,13 @@ struct wpa_ssid {
- * the selection attempts for OWE BSS exceed the configured threshold.
- */
- int owe_transition_bss_select_count;
-+
-+ /**
-+ * multi_ap_backhaul_sta - Multi-AP backhaul STA
-+ * 0 = normal (non-Multi-AP) station
-+ * 1 = Multi-AP backhaul station
-+ */
-+ int multi_ap_backhaul_sta;
- };
-
- #endif /* CONFIG_SSID_H */
---- a/wpa_supplicant/driver_i.h
-+++ b/wpa_supplicant/driver_i.h
-@@ -1046,4 +1046,12 @@ wpa_drv_send_external_auth_status(struct
- params);
- }
-
-+static inline int wpa_drv_set_4addr_mode(struct wpa_supplicant *wpa_s, int val)
-+{
-+ if (!wpa_s->driver->set_4addr_mode)
-+ return -1;
-+ return wpa_s->driver->set_4addr_mode(wpa_s->drv_priv,
-+ wpa_s->bridge_ifname, val);
-+}
-+
- #endif /* DRIVER_I_H */
---- a/wpa_supplicant/events.c
-+++ b/wpa_supplicant/events.c
-@@ -324,6 +324,9 @@ void wpa_supplicant_mark_disassoc(struct
- os_memset(wpa_s->last_tk, 0, sizeof(wpa_s->last_tk));
- #endif /* CONFIG_TESTING_OPTIONS */
- wpa_s->ieee80211ac = 0;
-+
-+ if (wpa_s->enabled_4addr_mode && wpa_drv_set_4addr_mode(wpa_s, 0) == 0)
-+ wpa_s->enabled_4addr_mode = 0;
- }
-
-
-@@ -2267,6 +2270,50 @@ static void interworking_process_assoc_r
- #endif /* CONFIG_INTERWORKING */
-
-
-+static void multi_ap_process_assoc_resp(struct wpa_supplicant *wpa_s,
-+ const u8 *ies, size_t ies_len)
-+{
-+ struct ieee802_11_elems elems;
-+ const u8 *map_sub_elem, *pos;
-+ size_t len;
-+
-+ if (!wpa_s->current_ssid ||
-+ !wpa_s->current_ssid->multi_ap_backhaul_sta ||
-+ !ies ||
-+ ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed)
-+ return;
-+
-+ if (!elems.multi_ap || elems.multi_ap_len < 7) {
-+ wpa_printf(MSG_INFO, "AP doesn't support Multi-AP protocol");
-+ goto fail;
-+ }
-+
-+ pos = elems.multi_ap + 4;
-+ len = elems.multi_ap_len - 4;
-+
-+ map_sub_elem = get_ie(pos, len, MULTI_AP_SUB_ELEM_TYPE);
-+ if (!map_sub_elem || map_sub_elem[1] < 1) {
-+ wpa_printf(MSG_INFO, "invalid Multi-AP sub elem type");
-+ goto fail;
-+ }
-+
-+ if (!(map_sub_elem[2] & MULTI_AP_BACKHAUL_BSS)) {
-+ wpa_printf(MSG_INFO, "AP doesn't support backhaul BSS");
-+ goto fail;
-+ }
-+
-+ if (wpa_drv_set_4addr_mode(wpa_s, 1) < 0) {
-+ wpa_printf(MSG_ERROR, "Failed to set 4addr mode");
-+ goto fail;
-+ }
-+ wpa_s->enabled_4addr_mode = 1;
-+ return;
-+
-+fail:
-+ wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
-+}
-+
-+
- #ifdef CONFIG_FST
- static int wpas_fst_update_mbie(struct wpa_supplicant *wpa_s,
- const u8 *ie, size_t ie_len)
-@@ -2343,6 +2390,9 @@ static int wpa_supplicant_event_associnf
- get_ie(data->assoc_info.resp_ies,
- data->assoc_info.resp_ies_len, WLAN_EID_VHT_CAP))
- wpa_s->ieee80211ac = 1;
-+
-+ multi_ap_process_assoc_resp(wpa_s, data->assoc_info.resp_ies,
-+ data->assoc_info.resp_ies_len);
- }
- if (data->assoc_info.beacon_ies)
- wpa_hexdump(MSG_DEBUG, "beacon_ies",
---- a/wpa_supplicant/sme.c
-+++ b/wpa_supplicant/sme.c
-@@ -1552,6 +1552,22 @@ void sme_associate(struct wpa_supplicant
- }
- #endif /* CONFIG_OWE */
-
-+ if (wpa_s->current_ssid && wpa_s->current_ssid->multi_ap_backhaul_sta) {
-+ size_t multi_ap_ie_len;
-+
-+ multi_ap_ie_len = add_multi_ap_ie(
-+ wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
-+ sizeof(wpa_s->sme.assoc_req_ie) -
-+ wpa_s->sme.assoc_req_ie_len,
-+ MULTI_AP_BACKHAUL_STA);
-+ if (multi_ap_ie_len == 0) {
-+ wpa_printf(MSG_ERROR,
-+ "Multi-AP: Failed to build Multi-AP IE");
-+ return;
-+ }
-+ wpa_s->sme.assoc_req_ie_len += multi_ap_ie_len;
-+ }
-+
- params.bssid = bssid;
- params.ssid = wpa_s->sme.ssid;
- params.ssid_len = wpa_s->sme.ssid_len;
---- a/wpa_supplicant/wpa_supplicant.c
-+++ b/wpa_supplicant/wpa_supplicant.c
-@@ -2893,6 +2893,21 @@ static u8 * wpas_populate_assoc_ies(
- }
- #endif /* CONFIG_IEEE80211R */
-
-+ if (ssid->multi_ap_backhaul_sta) {
-+ size_t multi_ap_ie_len;
-+
-+ multi_ap_ie_len = add_multi_ap_ie(wpa_ie + wpa_ie_len,
-+ max_wpa_ie_len - wpa_ie_len,
-+ MULTI_AP_BACKHAUL_STA);
-+ if (multi_ap_ie_len == 0) {
-+ wpa_printf(MSG_ERROR,
-+ "Multi-AP: Failed to build Multi-AP IE");
-+ os_free(wpa_ie);
-+ return NULL;
-+ }
-+ wpa_ie_len += multi_ap_ie_len;
-+ }
-+
- params->wpa_ie = wpa_ie;
- params->wpa_ie_len = wpa_ie_len;
- params->auth_alg = algs;
-@@ -3377,6 +3392,9 @@ void wpa_supplicant_deauthenticate(struc
- zero_addr = 1;
- }
-
-+ if (wpa_s->enabled_4addr_mode && wpa_drv_set_4addr_mode(wpa_s, 0) == 0)
-+ wpa_s->enabled_4addr_mode = 0;
-+
- #ifdef CONFIG_TDLS
- wpa_tdls_teardown_peers(wpa_s->wpa);
- #endif /* CONFIG_TDLS */
---- a/wpa_supplicant/wpa_supplicant.conf
-+++ b/wpa_supplicant/wpa_supplicant.conf
-@@ -1399,6 +1399,13 @@ fast_reauth=1
- # 2: MCS 0-9
- # 3: not supported
-
-+# multi_ap_backhaul_sta: Multi-AP backhaul STA functionality
-+# 0 = normal STA (default)
-+# 1 = backhaul STA
-+# A backhaul STA sends the Multi-AP IE, fails to associate if the AP does not
-+# support Multi-AP, and sets 4-address mode if it does. Thus, the netdev can be
-+# added to a bridge to allow forwarding frames over this backhaul link.
-+
- ##### Fast Session Transfer (FST) support #####################################
- #
- # The options in this section are only available when the build configuration
---- a/wpa_supplicant/wpa_supplicant_i.h
-+++ b/wpa_supplicant/wpa_supplicant_i.h
-@@ -1242,6 +1242,7 @@ struct wpa_supplicant {
- unsigned int disable_fils:1;
- #endif /* CONFIG_FILS */
- unsigned int ieee80211ac:1;
-+ unsigned int enabled_4addr_mode:1;
- };
-
-
deleted file mode 100644
@@ -1,100 +0,0 @@
-From 7488e0ade6dffb6df4c1fb6526a9f3ede0eb18ef Mon Sep 17 00:00:00 2001
-From: Jouni Malinen <jouni@codeaurora.org>
-Date: Thu, 20 Dec 2018 12:41:00 +0200
-Subject: [PATCH] tests: Multi-AP association
-
-Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
----
- tests/hwsim/test_multi_ap.py | 73 ++++++++++++++++++++++++++++++++++++
- tests/hwsim/wpasupplicant.py | 3 +-
- 2 files changed, 75 insertions(+), 1 deletion(-)
- create mode 100644 tests/hwsim/test_multi_ap.py
-
---- /dev/null
-+++ b/tests/hwsim/test_multi_ap.py
-@@ -0,0 +1,73 @@
-+# Test cases for Multi-AP
-+# Copyright (c) 2018, The Linux Foundation
-+#
-+# This software may be distributed under the terms of the BSD license.
-+# See README for more details.
-+
-+import hostapd
-+
-+def test_multi_ap_association(dev, apdev):
-+ """Multi-AP association in backhaul BSS"""
-+ run_multi_ap_association(dev, apdev, 1)
-+ dev[1].connect("multi-ap", psk="12345678", scan_freq="2412",
-+ wait_connect=False)
-+ ev = dev[1].wait_event([ "CTRL-EVENT-DISCONNECTED",
-+ "CTRL-EVENT-CONNECTED",
-+ "CTRL-EVENT-ASSOC-REJECT" ],
-+ timeout=5)
-+ dev[1].request("DISCONNECT")
-+ if ev is None:
-+ raise Exception("Connection result not reported")
-+ if "CTRL-EVENT-ASSOC-REJECT" not in ev:
-+ raise Exception("Association rejection not reported")
-+ if "status_code=12" not in ev:
-+ raise Exception("Unexpected association status code: " + ev)
-+
-+def test_multi_ap_association_shared_bss(dev, apdev):
-+ """Multi-AP association in backhaul BSS (with fronthaul BSS enabled)"""
-+ run_multi_ap_association(dev, apdev, 3)
-+ dev[1].connect("multi-ap", psk="12345678", scan_freq="2412")
-+
-+def run_multi_ap_association(dev, apdev, multi_ap):
-+ params = hostapd.wpa2_params(ssid="multi-ap", passphrase="12345678")
-+ params["multi_ap"] = str(multi_ap)
-+ hapd = hostapd.add_ap(apdev[0], params)
-+
-+ dev[0].connect("multi-ap", psk="12345678", multi_ap_backhaul_sta="1",
-+ scan_freq="2412")
-+
-+def test_multi_ap_disabled_on_ap(dev, apdev):
-+ """Multi-AP association attempt when disabled on AP"""
-+ params = hostapd.wpa2_params(ssid="multi-ap", passphrase="12345678")
-+ hapd = hostapd.add_ap(apdev[0], params)
-+
-+ dev[0].connect("multi-ap", psk="12345678", multi_ap_backhaul_sta="1",
-+ scan_freq="2412", wait_connect=False)
-+ ev = dev[0].wait_event([ "CTRL-EVENT-DISCONNECTED",
-+ "CTRL-EVENT-CONNECTED" ],
-+ timeout=5)
-+ dev[0].request("DISCONNECT")
-+ if ev is None:
-+ raise Exception("Connection result not reported")
-+ if "CTRL-EVENT-DISCONNECTED" not in ev:
-+ raise Exception("Unexpected connection result")
-+
-+def test_multi_ap_fronthaul_on_ap(dev, apdev):
-+ """Multi-AP association attempt when only fronthaul BSS on AP"""
-+ params = hostapd.wpa2_params(ssid="multi-ap", passphrase="12345678")
-+ params["multi_ap"] = "2"
-+ hapd = hostapd.add_ap(apdev[0], params)
-+
-+ dev[0].connect("multi-ap", psk="12345678", multi_ap_backhaul_sta="1",
-+ scan_freq="2412", wait_connect=False)
-+ ev = dev[0].wait_event([ "CTRL-EVENT-DISCONNECTED",
-+ "CTRL-EVENT-CONNECTED",
-+ "CTRL-EVENT-ASSOC-REJECT" ],
-+ timeout=5)
-+ dev[0].request("DISCONNECT")
-+ if ev is None:
-+ raise Exception("Connection result not reported")
-+ if "CTRL-EVENT-ASSOC-REJECT" not in ev:
-+ raise Exception("Association rejection not reported")
-+ if "status_code=12" not in ev:
-+ raise Exception("Unexpected association status code: " + ev)
---- a/tests/hwsim/wpasupplicant.py
-+++ b/tests/hwsim/wpasupplicant.py
-@@ -1031,7 +1031,8 @@ class WpaSupplicant:
- "dpp_csign", "dpp_csign_expiry",
- "dpp_netaccesskey", "dpp_netaccesskey_expiry",
- "group_mgmt", "owe_group",
-- "roaming_consortium_selection" ]
-+ "roaming_consortium_selection", "multi_ap_backhaul_sta" ]
-+
- for field in not_quoted:
- if field in kwargs and kwargs[field]:
- self.set_network(id, field, kwargs[field])
deleted file mode 100644
@@ -1,72 +0,0 @@
-From 0f5029ff41ef286aa7b3e4a3efd3f1a16be925e8 Mon Sep 17 00:00:00 2001
-From: "Arnout Vandecappelle (Essensium/Mind)" <arnout@mind.be>
-Date: Wed, 9 Jan 2019 18:41:08 +0100
-Subject: [PATCH] tests: refactor test_multi_ap
-
-With just one additional argument, the run_multi_ap_association function
-can be used for all tests.
-
-While we're at it, also move it to the top of the file.
-
-Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
----
-v4: new patch
----
- tests/hwsim/test_multi_ap.py | 30 +++++++++++-------------------
- 1 file changed, 11 insertions(+), 19 deletions(-)
-
---- a/tests/hwsim/test_multi_ap.py
-+++ b/tests/hwsim/test_multi_ap.py
-@@ -6,6 +6,15 @@
-
- import hostapd
-
-+def run_multi_ap_association(dev, apdev, multi_ap, wait_connect=True):
-+ params = hostapd.wpa2_params(ssid="multi-ap", passphrase="12345678")
-+ if multi_ap:
-+ params["multi_ap"] = str(multi_ap)
-+ hapd = hostapd.add_ap(apdev[0], params)
-+
-+ dev[0].connect("multi-ap", psk="12345678", scan_freq="2412",
-+ multi_ap_backhaul_sta="1", wait_connect=wait_connect)
-+
- def test_multi_ap_association(dev, apdev):
- """Multi-AP association in backhaul BSS"""
- run_multi_ap_association(dev, apdev, 1)
-@@ -28,21 +37,9 @@ def test_multi_ap_association_shared_bss
- run_multi_ap_association(dev, apdev, 3)
- dev[1].connect("multi-ap", psk="12345678", scan_freq="2412")
-
--def run_multi_ap_association(dev, apdev, multi_ap):
-- params = hostapd.wpa2_params(ssid="multi-ap", passphrase="12345678")
-- params["multi_ap"] = str(multi_ap)
-- hapd = hostapd.add_ap(apdev[0], params)
--
-- dev[0].connect("multi-ap", psk="12345678", multi_ap_backhaul_sta="1",
-- scan_freq="2412")
--
- def test_multi_ap_disabled_on_ap(dev, apdev):
- """Multi-AP association attempt when disabled on AP"""
-- params = hostapd.wpa2_params(ssid="multi-ap", passphrase="12345678")
-- hapd = hostapd.add_ap(apdev[0], params)
--
-- dev[0].connect("multi-ap", psk="12345678", multi_ap_backhaul_sta="1",
-- scan_freq="2412", wait_connect=False)
-+ run_multi_ap_association(dev, apdev, 0, wait_connect=False)
- ev = dev[0].wait_event([ "CTRL-EVENT-DISCONNECTED",
- "CTRL-EVENT-CONNECTED" ],
- timeout=5)
-@@ -54,12 +51,7 @@ def test_multi_ap_disabled_on_ap(dev, ap
-
- def test_multi_ap_fronthaul_on_ap(dev, apdev):
- """Multi-AP association attempt when only fronthaul BSS on AP"""
-- params = hostapd.wpa2_params(ssid="multi-ap", passphrase="12345678")
-- params["multi_ap"] = "2"
-- hapd = hostapd.add_ap(apdev[0], params)
--
-- dev[0].connect("multi-ap", psk="12345678", multi_ap_backhaul_sta="1",
-- scan_freq="2412", wait_connect=False)
-+ run_multi_ap_association(dev, apdev, 2, wait_connect=False)
- ev = dev[0].wait_event([ "CTRL-EVENT-DISCONNECTED",
- "CTRL-EVENT-CONNECTED",
- "CTRL-EVENT-ASSOC-REJECT" ],
deleted file mode 100644
@@ -1,106 +0,0 @@
-From 71b061b8a13791a1ed858d924e401541c8584030 Mon Sep 17 00:00:00 2001
-From: "Arnout Vandecappelle (Essensium/Mind)" <arnout@mind.be>
-Date: Wed, 9 Jan 2019 19:08:00 +0100
-Subject: [PATCH] multi_ap: don't reject backhaul STA on fronhaul BSS
-
-The Multi-AP specification only specifies that information elements have
-to be added to the association requests and responses; it doesn't
-specify anything about what should be done in case they are missing.
-Currently, we reject non-backhaul associations on a backhaul-only BSS,
-and non-fronthaul associations on a fronthaul-only BSS.
-
-However, this makes WPS fail when fronthaul and backhaul are separate
-SSIDs. Indeed, WPS for the backhaul link is performed on the *fronthaul*
-SSID. Thus, the association request used for WPS *will* contain the
-Multi-AP IE indicating a backhaul STA. Rejecting that association makes
-WPS fail.
-
-Therefore, accept a multi-AP backhaul STA association request on a
-fronthaul-only BSS. Still issue a warning about it, but only at level
-DEBUG intead of INFO. Also change the condition checking to make it
-clearer.
-
-While we're at it, also fix the handling of unexpected bits in the
-Multi-AP IE. 4 bits are reserved in the specification, so these
-certainly have to be ignored. The specification also doesn't say that
-setting one of the other bits is not allowed. Therefore, only report
-unexpected values in the Multi-AP IE, don't reject because of it.
-Note that a malformed IE (containing more than one byte) still triggers
-a rejection.
-
-Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
----
-v4: new patch
-
-Cfr. discussion on http://lists.infradead.org/pipermail/hostap/2019-January/039232.html
-and follow-ups.
----
- src/ap/ieee802_11.c | 38 +++++++++++++++++++-----------------
- tests/hwsim/test_multi_ap.py | 6 ++----
- 2 files changed, 22 insertions(+), 22 deletions(-)
-
---- a/src/ap/ieee802_11.c
-+++ b/src/ap/ieee802_11.c
-@@ -2253,28 +2253,30 @@ static u16 check_multi_ap(struct hostapd
- }
- }
-
-- if (multi_ap_value == MULTI_AP_BACKHAUL_STA)
-- sta->flags |= WLAN_STA_MULTI_AP;
--
-- if ((hapd->conf->multi_ap & BACKHAUL_BSS) &&
-- multi_ap_value == MULTI_AP_BACKHAUL_STA)
-- return WLAN_STATUS_SUCCESS;
--
-- if (hapd->conf->multi_ap & FRONTHAUL_BSS) {
-- if (multi_ap_value == MULTI_AP_BACKHAUL_STA) {
-- hostapd_logger(hapd, sta->addr,
-- HOSTAPD_MODULE_IEEE80211,
-- HOSTAPD_LEVEL_INFO,
-- "Backhaul STA tries to associate with fronthaul-only BSS");
-- return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
-- }
-- return WLAN_STATUS_SUCCESS;
-+ if (multi_ap_value && multi_ap_value != MULTI_AP_BACKHAUL_STA)
-+ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
-+ HOSTAPD_LEVEL_INFO,
-+ "Multi-AP IE with unexpected value 0x%02x",
-+ multi_ap_value);
-+
-+ if (!(multi_ap_value & MULTI_AP_BACKHAUL_STA)) {
-+ if (hapd->conf->multi_ap & FRONTHAUL_BSS)
-+ return WLAN_STATUS_SUCCESS;
-+
-+ hostapd_logger(hapd, sta->addr,
-+ HOSTAPD_MODULE_IEEE80211,
-+ HOSTAPD_LEVEL_INFO,
-+ "Non-Multi-AP STA tries to associate with backhaul-only BSS");
-+ return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
- }
-
-- hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
-- HOSTAPD_LEVEL_INFO,
-- "Non-Multi-AP STA tries to associate with backhaul-only BSS");
-- return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
-+ if (!(hapd->conf->multi_ap & BACKHAUL_BSS))
-+ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
-+ HOSTAPD_LEVEL_DEBUG,
-+ "Backhaul STA tries to associate with fronthaul-only BSS");
-+
-+ sta->flags |= WLAN_STA_MULTI_AP;
-+ return WLAN_STATUS_SUCCESS;
- }
-
-
---- a/tests/hwsim/test_multi_ap.py
-+++ b/tests/hwsim/test_multi_ap.py
-@@ -59,7 +59,5 @@ def test_multi_ap_fronthaul_on_ap(dev, a
- dev[0].request("DISCONNECT")
- if ev is None:
- raise Exception("Connection result not reported")
-- if "CTRL-EVENT-ASSOC-REJECT" not in ev:
-- raise Exception("Association rejection not reported")
-- if "status_code=12" not in ev:
-- raise Exception("Unexpected association status code: " + ev)
-+ if "CTRL-EVENT-DISCONNECTED" not in ev:
-+ raise Exception("Unexpected connection result")
deleted file mode 100644
@@ -1,342 +0,0 @@
-From ad3c6faca118c23cdafef418dc27b3cee7d0e06e Mon Sep 17 00:00:00 2001
-From: "Arnout Vandecappelle (Essensium/Mind)" <arnout@mind.be>
-Date: Wed, 9 Jan 2019 19:19:26 +0100
-Subject: [PATCH] WPS: wps_build_wfa_ext(): add multi_ap_subelem parameter
-
-The Multi-AP specification adds a new subelement to the WFA extension
-element in the WPS exchange. Add an additional parameter to
-wps_build_wfa_ext() to add this subelement. The subelement is only added
-if the parameter is non-0. Note that we don't reuse the existing
-MULTI_AP_SUB_ELEM_TYPE definition here, but rather define a new
-WFA_ELEM_MULTI_AP, to make sure the enum of WFA subelement types remains
-complete.
-
-For now, all callers set the multi_ap_subelem parameter to 0.
-
-Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
----
-v4: Split off from supplicant WPS patch
-
-Since the original patch from Davina Lyu didn't have this extra
-argument, I kept myself as the author of this patch.
----
- src/p2p/p2p_build.c | 2 +-
- src/wps/wps.c | 6 +++---
- src/wps/wps_attr_build.c | 11 ++++++++++-
- src/wps/wps_common.c | 16 ++++++++--------
- src/wps/wps_defs.h | 3 ++-
- src/wps/wps_enrollee.c | 10 +++++-----
- src/wps/wps_er.c | 4 ++--
- src/wps/wps_i.h | 3 ++-
- src/wps/wps_registrar.c | 14 +++++++-------
- src/wps/wps_upnp.c | 2 +-
- 10 files changed, 41 insertions(+), 30 deletions(-)
-
---- a/src/p2p/p2p_build.c
-+++ b/src/p2p/p2p_build.c
-@@ -802,7 +802,7 @@ int p2p_build_wps_ie(struct p2p_data *p2
- wpabuf_put_be16(buf, p2p->cfg->config_methods);
- }
-
-- if (wps_build_wfa_ext(buf, 0, NULL, 0) < 0)
-+ if (wps_build_wfa_ext(buf, 0, NULL, 0, 0) < 0)
- return -1;
-
- if (all_attr && p2p->cfg->num_sec_dev_types) {
---- a/src/wps/wps.c
-+++ b/src/wps/wps.c
-@@ -430,7 +430,7 @@ struct wpabuf * wps_build_assoc_req_ie(e
-
- if (wps_build_version(ie) ||
- wps_build_req_type(ie, req_type) ||
-- wps_build_wfa_ext(ie, 0, NULL, 0)) {
-+ wps_build_wfa_ext(ie, 0, NULL, 0, 0)) {
- wpabuf_free(ie);
- return NULL;
- }
-@@ -464,7 +464,7 @@ struct wpabuf * wps_build_assoc_resp_ie(
-
- if (wps_build_version(ie) ||
- wps_build_resp_type(ie, WPS_RESP_AP) ||
-- wps_build_wfa_ext(ie, 0, NULL, 0)) {
-+ wps_build_wfa_ext(ie, 0, NULL, 0, 0)) {
- wpabuf_free(ie);
- return NULL;
- }
-@@ -516,7 +516,7 @@ struct wpabuf * wps_build_probe_req_ie(u
- wps_build_model_name(dev, ie) ||
- wps_build_model_number(dev, ie) ||
- wps_build_dev_name(dev, ie) ||
-- wps_build_wfa_ext(ie, req_type == WPS_REQ_ENROLLEE, NULL, 0) ||
-+ wps_build_wfa_ext(ie, req_type == WPS_REQ_ENROLLEE, NULL, 0, 0) ||
- wps_build_req_dev_type(dev, ie, num_req_dev_types, req_dev_types)
- ||
- wps_build_secondary_dev_type(dev, ie)
---- a/src/wps/wps_attr_build.c
-+++ b/src/wps/wps_attr_build.c
-@@ -203,7 +203,8 @@ int wps_build_version(struct wpabuf *msg
-
-
- int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll,
-- const u8 *auth_macs, size_t auth_macs_count)
-+ const u8 *auth_macs, size_t auth_macs_count,
-+ u8 multi_ap_subelem)
- {
- u8 *len;
-
-@@ -244,6 +245,14 @@ int wps_build_wfa_ext(struct wpabuf *msg
- MAC2STR(&auth_macs[i * ETH_ALEN]));
- }
-
-+ if (multi_ap_subelem) {
-+ wpa_printf(MSG_DEBUG, "WPS: * Multi-AP (0x%x)",
-+ multi_ap_subelem);
-+ wpabuf_put_u8(msg, WFA_ELEM_MULTI_AP);
-+ wpabuf_put_u8(msg, 1); /* length */
-+ wpabuf_put_u8(msg, multi_ap_subelem);
-+ }
-+
- WPA_PUT_BE16(len, (u8 *) wpabuf_put(msg, 0) - len - 2);
-
- #ifdef CONFIG_WPS_TESTING
---- a/src/wps/wps_common.c
-+++ b/src/wps/wps_common.c
-@@ -374,7 +374,7 @@ struct wpabuf * wps_get_oob_cred(struct
- (rf_band && wps_build_rf_bands_attr(plain, rf_band)) ||
- (channel && wps_build_ap_channel(plain, channel)) ||
- wps_build_mac_addr(plain, wps->dev.mac_addr) ||
-- wps_build_wfa_ext(plain, 0, NULL, 0)) {
-+ wps_build_wfa_ext(plain, 0, NULL, 0, 0)) {
- os_free(data.new_psk);
- wpabuf_clear_free(plain);
- return NULL;
-@@ -421,7 +421,7 @@ struct wpabuf * wps_build_nfc_pw_token(u
-
- if (wps_build_oob_dev_pw(data, dev_pw_id, pubkey,
- wpabuf_head(dev_pw), wpabuf_len(dev_pw)) ||
-- wps_build_wfa_ext(data, 0, NULL, 0)) {
-+ wps_build_wfa_ext(data, 0, NULL, 0, 0)) {
- wpa_printf(MSG_ERROR, "WPS: Failed to build NFC password "
- "token");
- wpabuf_clear_free(data);
-@@ -586,7 +586,7 @@ struct wpabuf * wps_build_wsc_ack(struct
- wps_build_msg_type(msg, WPS_WSC_ACK) ||
- wps_build_enrollee_nonce(wps, msg) ||
- wps_build_registrar_nonce(wps, msg) ||
-- wps_build_wfa_ext(msg, 0, NULL, 0)) {
-+ wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
- wpabuf_free(msg);
- return NULL;
- }
-@@ -610,7 +610,7 @@ struct wpabuf * wps_build_wsc_nack(struc
- wps_build_enrollee_nonce(wps, msg) ||
- wps_build_registrar_nonce(wps, msg) ||
- wps_build_config_error(msg, wps->config_error) ||
-- wps_build_wfa_ext(msg, 0, NULL, 0)) {
-+ wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
- wpabuf_free(msg);
- return NULL;
- }
-@@ -726,7 +726,7 @@ struct wpabuf * wps_build_nfc_handover_r
- if (wps_build_oob_dev_pw(msg, DEV_PW_NFC_CONNECTION_HANDOVER,
- nfc_dh_pubkey, NULL, 0) ||
- wps_build_uuid_e(msg, ctx->uuid) ||
-- wps_build_wfa_ext(msg, 0, NULL, 0)) {
-+ wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
- wpabuf_free(msg);
- return NULL;
- }
-@@ -809,7 +809,7 @@ struct wpabuf * wps_build_nfc_handover_s
- wps_build_ssid(msg, ctx) ||
- wps_build_ap_freq(msg, freq) ||
- (bssid && wps_build_mac_addr(msg, bssid)) ||
-- wps_build_wfa_ext(msg, 0, NULL, 0)) {
-+ wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
- wpabuf_free(msg);
- return NULL;
- }
-@@ -848,7 +848,7 @@ struct wpabuf * wps_build_nfc_handover_r
- wps_build_rf_bands(&ctx->dev, msg, 0) ||
- wps_build_serial_number(&ctx->dev, msg) ||
- wps_build_uuid_e(msg, ctx->uuid) ||
-- wps_build_wfa_ext(msg, 0, NULL, 0)) {
-+ wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
- wpabuf_free(msg);
- return NULL;
- }
-@@ -900,7 +900,7 @@ struct wpabuf * wps_build_nfc_handover_s
- wps_build_rf_bands(&ctx->dev, msg, 0) ||
- wps_build_serial_number(&ctx->dev, msg) ||
- wps_build_uuid_e(msg, ctx->uuid) ||
-- wps_build_wfa_ext(msg, 0, NULL, 0)) {
-+ wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
- wpabuf_free(msg);
- return NULL;
- }
---- a/src/wps/wps_defs.h
-+++ b/src/wps/wps_defs.h
-@@ -152,7 +152,8 @@ enum {
- WFA_ELEM_NETWORK_KEY_SHAREABLE = 0x02,
- WFA_ELEM_REQUEST_TO_ENROLL = 0x03,
- WFA_ELEM_SETTINGS_DELAY_TIME = 0x04,
-- WFA_ELEM_REGISTRAR_CONFIGURATION_METHODS = 0x05
-+ WFA_ELEM_REGISTRAR_CONFIGURATION_METHODS = 0x05,
-+ WFA_ELEM_MULTI_AP = 0x06
- };
-
- /* Device Password ID */
---- a/src/wps/wps_enrollee.c
-+++ b/src/wps/wps_enrollee.c
-@@ -152,7 +152,7 @@ static struct wpabuf * wps_build_m1(stru
- wps_build_dev_password_id(msg, wps->dev_pw_id) ||
- wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
- wps_build_os_version(&wps->wps->dev, msg) ||
-- wps_build_wfa_ext(msg, 0, NULL, 0) ||
-+ wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
- wps_build_vendor_ext_m1(&wps->wps->dev, msg)) {
- wpabuf_free(msg);
- return NULL;
-@@ -190,7 +190,7 @@ static struct wpabuf * wps_build_m3(stru
- wps_build_msg_type(msg, WPS_M3) ||
- wps_build_registrar_nonce(wps, msg) ||
- wps_build_e_hash(wps, msg) ||
-- wps_build_wfa_ext(msg, 0, NULL, 0) ||
-+ wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
- wps_build_authenticator(wps, msg)) {
- wpabuf_free(msg);
- return NULL;
-@@ -223,7 +223,7 @@ static struct wpabuf * wps_build_m5(stru
- wps_build_e_snonce1(wps, plain) ||
- wps_build_key_wrap_auth(wps, plain) ||
- wps_build_encr_settings(wps, msg, plain) ||
-- wps_build_wfa_ext(msg, 0, NULL, 0) ||
-+ wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
- wps_build_authenticator(wps, msg)) {
- wpabuf_clear_free(plain);
- wpabuf_free(msg);
-@@ -393,7 +393,7 @@ static struct wpabuf * wps_build_m7(stru
- (wps->wps->ap && wps_build_ap_settings(wps, plain)) ||
- wps_build_key_wrap_auth(wps, plain) ||
- wps_build_encr_settings(wps, msg, plain) ||
-- wps_build_wfa_ext(msg, 0, NULL, 0) ||
-+ wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
- wps_build_authenticator(wps, msg)) {
- wpabuf_clear_free(plain);
- wpabuf_free(msg);
-@@ -430,7 +430,7 @@ static struct wpabuf * wps_build_wsc_don
- wps_build_msg_type(msg, WPS_WSC_DONE) ||
- wps_build_enrollee_nonce(wps, msg) ||
- wps_build_registrar_nonce(wps, msg) ||
-- wps_build_wfa_ext(msg, 0, NULL, 0)) {
-+ wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
- wpabuf_free(msg);
- return NULL;
- }
---- a/src/wps/wps_er.c
-+++ b/src/wps/wps_er.c
-@@ -1530,7 +1530,7 @@ void wps_er_set_sel_reg(struct wps_er *e
- wps_er_build_selected_registrar(msg, sel_reg) ||
- wps_er_build_dev_password_id(msg, dev_passwd_id) ||
- wps_er_build_sel_reg_config_methods(msg, sel_reg_config_methods) ||
-- wps_build_wfa_ext(msg, 0, auth_macs, count) ||
-+ wps_build_wfa_ext(msg, 0, auth_macs, count, 0) ||
- wps_er_build_uuid_r(msg, er->wps->uuid)) {
- wpabuf_free(msg);
- return;
-@@ -2048,7 +2048,7 @@ struct wpabuf * wps_er_config_token_from
- data.wps = wps;
- data.use_cred = cred;
- if (wps_build_cred(&data, ret) ||
-- wps_build_wfa_ext(ret, 0, NULL, 0)) {
-+ wps_build_wfa_ext(ret, 0, NULL, 0, 0)) {
- wpabuf_free(ret);
- return NULL;
- }
---- a/src/wps/wps_i.h
-+++ b/src/wps/wps_i.h
-@@ -163,7 +163,8 @@ int wps_build_encr_settings(struct wps_d
- struct wpabuf *plain);
- int wps_build_version(struct wpabuf *msg);
- int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll,
-- const u8 *auth_macs, size_t auth_macs_count);
-+ const u8 *auth_macs, size_t auth_macs_count,
-+ u8 multi_ap_subelem);
- int wps_build_msg_type(struct wpabuf *msg, enum wps_msg_type msg_type);
- int wps_build_enrollee_nonce(struct wps_data *wps, struct wpabuf *msg);
- int wps_build_registrar_nonce(struct wps_data *wps, struct wpabuf *msg);
---- a/src/wps/wps_registrar.c
-+++ b/src/wps/wps_registrar.c
-@@ -1281,7 +1281,7 @@ static int wps_set_ie(struct wps_registr
- wps_build_sel_reg_config_methods(reg, beacon) ||
- wps_build_sel_pbc_reg_uuid_e(reg, beacon) ||
- (reg->dualband && wps_build_rf_bands(®->wps->dev, beacon, 0)) ||
-- wps_build_wfa_ext(beacon, 0, auth_macs, count) ||
-+ wps_build_wfa_ext(beacon, 0, auth_macs, count, 0) ||
- wps_build_vendor_ext(®->wps->dev, beacon)) {
- wpabuf_free(beacon);
- wpabuf_free(probe);
-@@ -1311,7 +1311,7 @@ static int wps_set_ie(struct wps_registr
- wps_build_device_attrs(®->wps->dev, probe) ||
- wps_build_probe_config_methods(reg, probe) ||
- (reg->dualband && wps_build_rf_bands(®->wps->dev, probe, 0)) ||
-- wps_build_wfa_ext(probe, 0, auth_macs, count) ||
-+ wps_build_wfa_ext(probe, 0, auth_macs, count, 0) ||
- wps_build_vendor_ext(®->wps->dev, probe)) {
- wpabuf_free(beacon);
- wpabuf_free(probe);
-@@ -1845,7 +1845,7 @@ static struct wpabuf * wps_build_m2(stru
- wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
- wps_build_dev_password_id(msg, wps->dev_pw_id) ||
- wps_build_os_version(&wps->wps->dev, msg) ||
-- wps_build_wfa_ext(msg, 0, NULL, 0)) {
-+ wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
- wpabuf_free(msg);
- return NULL;
- }
-@@ -1913,7 +1913,7 @@ static struct wpabuf * wps_build_m2d(str
- wps_build_assoc_state(wps, msg) ||
- wps_build_config_error(msg, err) ||
- wps_build_os_version(&wps->wps->dev, msg) ||
-- wps_build_wfa_ext(msg, 0, NULL, 0)) {
-+ wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
- wpabuf_free(msg);
- return NULL;
- }
-@@ -1949,7 +1949,7 @@ static struct wpabuf * wps_build_m4(stru
- wps_build_r_snonce1(wps, plain) ||
- wps_build_key_wrap_auth(wps, plain) ||
- wps_build_encr_settings(wps, msg, plain) ||
-- wps_build_wfa_ext(msg, 0, NULL, 0) ||
-+ wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
- wps_build_authenticator(wps, msg)) {
- wpabuf_clear_free(plain);
- wpabuf_free(msg);
-@@ -1984,7 +1984,7 @@ static struct wpabuf * wps_build_m6(stru
- wps_build_r_snonce2(wps, plain) ||
- wps_build_key_wrap_auth(wps, plain) ||
- wps_build_encr_settings(wps, msg, plain) ||
-- wps_build_wfa_ext(msg, 0, NULL, 0) ||
-+ wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
- wps_build_authenticator(wps, msg)) {
- wpabuf_clear_free(plain);
- wpabuf_free(msg);
-@@ -2021,7 +2021,7 @@ static struct wpabuf * wps_build_m8(stru
- (!wps->wps->ap && !wps->er && wps_build_ap_settings(wps, plain)) ||
- wps_build_key_wrap_auth(wps, plain) ||
- wps_build_encr_settings(wps, msg, plain) ||
-- wps_build_wfa_ext(msg, 0, NULL, 0) ||
-+ wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
- wps_build_authenticator(wps, msg)) {
- wpabuf_clear_free(plain);
- wpabuf_clear_free(msg);
---- a/src/wps/wps_upnp.c
-+++ b/src/wps/wps_upnp.c
-@@ -599,7 +599,7 @@ static struct wpabuf * build_fake_wsc_ac
- wpabuf_put_be16(msg, ATTR_REGISTRAR_NONCE);
- wpabuf_put_be16(msg, WPS_NONCE_LEN);
- wpabuf_put(msg, WPS_NONCE_LEN);
-- if (wps_build_wfa_ext(msg, 0, NULL, 0)) {
-+ if (wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
- wpabuf_free(msg);
- return NULL;
- }
deleted file mode 100644
@@ -1,217 +0,0 @@
-From 6c4c98db9420a3321bbf091cfc254de5eba4b404 Mon Sep 17 00:00:00 2001
-From: Davina Lu <ylu@quantenna.com>
-Date: Tue, 15 Jan 2019 19:17:51 +0100
-Subject: [PATCH] wpa_supplicant: support Multi-AP backhaul STA onboarding
-
-The Wi-Fi Alliance Multi-AP Specification v1.0 allows onboarding of a
-backhaul STA through WPS. To enable this, the backhaul STA needs to add
-a Multi-AP IE to the WFA vendor extension element in the WSC M1 message
-that indicates it supports the Multi-AP backhaul STA role. The registrar
-(if it support Multi-AP onboarding) will respond to that with a WSC M8
-message that also contains the Multi-AP IE, and that contains the
-credentials for the backhaul SSID (which may be different from the SSID
-on which WPS is performed).
-
-Introduce a new parameter to wpas_wps_start_pbc() and allow it to be
-set via control interface's new multi_ap=1 parameter of WPS_PBC call.
-multi_ap_backhaul_sta is set to 1 in the automatically created SSID.
-Thus, if the AP does not support Multi-AP, association will fail and
-WPS will be terminated.
-
-Only wps_pbc is supported.
-
-The multi_ap argument is only added to the socket interface, not to the
-dbus interface.
-
-Signed-off-by: Davina Lu <ylu@quantenna.com>
-Signed-off-by: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
-Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
-v4: use argument to wps_pbc instead of a global configuration option
- (requested by Jouni)
----
- src/eap_peer/eap_wsc.c | 3 +++
- src/wps/wps.h | 6 ++++++
- src/wps/wps_enrollee.c | 6 +++++-
- wpa_supplicant/ctrl_iface.c | 5 ++++-
- wpa_supplicant/dbus/dbus_new_handlers_wps.c | 2 +-
- wpa_supplicant/dbus/dbus_old_handlers_wps.c | 4 ++--
- wpa_supplicant/events.c | 2 +-
- wpa_supplicant/p2p_supplicant.c | 2 +-
- wpa_supplicant/wps_supplicant.c | 9 +++++++--
- wpa_supplicant/wps_supplicant.h | 2 +-
- 10 files changed, 31 insertions(+), 10 deletions(-)
-
---- a/src/eap_peer/eap_wsc.c
-+++ b/src/eap_peer/eap_wsc.c
-@@ -274,6 +274,9 @@ static void * eap_wsc_init(struct eap_sm
- cfg.pin, cfg.pin_len, 0);
- }
-
-+ if (os_strstr(phase1, "multi_ap=1"))
-+ wps->multi_ap_backhaul_sta = 1;
-+
- /* Use reduced client timeout for WPS to avoid long wait */
- if (sm->ClientTimeout > 30)
- sm->ClientTimeout = 30;
---- a/src/wps/wps.h
-+++ b/src/wps/wps.h
-@@ -613,6 +613,12 @@ struct wps_context {
- int ap_setup_locked;
-
- /**
-+ * multi_ap_backhaul_sta - Whether this is a Multi-AP backhaul STA
-+ * enrollee
-+ */
-+ int multi_ap_backhaul_sta;
-+
-+ /**
- * uuid - Own UUID
- */
- u8 uuid[16];
---- a/src/wps/wps_enrollee.c
-+++ b/src/wps/wps_enrollee.c
-@@ -105,6 +105,7 @@ static struct wpabuf * wps_build_m1(stru
- {
- struct wpabuf *msg;
- u16 config_methods;
-+ u8 multi_ap_backhaul_sta = 0;
-
- if (random_get_bytes(wps->nonce_e, WPS_NONCE_LEN) < 0)
- return NULL;
-@@ -134,6 +135,9 @@ static struct wpabuf * wps_build_m1(stru
- WPS_CONFIG_PHY_PUSHBUTTON);
- }
-
-+ if (wps->wps->multi_ap_backhaul_sta)
-+ multi_ap_backhaul_sta = MULTI_AP_BACKHAUL_STA;
-+
- if (wps_build_version(msg) ||
- wps_build_msg_type(msg, WPS_M1) ||
- wps_build_uuid_e(msg, wps->uuid_e) ||
-@@ -152,7 +156,7 @@ static struct wpabuf * wps_build_m1(stru
- wps_build_dev_password_id(msg, wps->dev_pw_id) ||
- wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
- wps_build_os_version(&wps->wps->dev, msg) ||
-- wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
-+ wps_build_wfa_ext(msg, 0, NULL, 0, multi_ap_backhaul_sta) ||
- wps_build_vendor_ext_m1(&wps->wps->dev, msg)) {
- wpabuf_free(msg);
- return NULL;
---- a/wpa_supplicant/ctrl_iface.c
-+++ b/wpa_supplicant/ctrl_iface.c
-@@ -1167,6 +1167,7 @@ static int wpa_supplicant_ctrl_iface_wps
- #ifdef CONFIG_AP
- u8 *_p2p_dev_addr = NULL;
- #endif /* CONFIG_AP */
-+ int multi_ap = 0;
-
- if (cmd == NULL || os_strcmp(cmd, "any") == 0) {
- _bssid = NULL;
-@@ -1184,6 +1185,8 @@ static int wpa_supplicant_ctrl_iface_wps
- wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
- cmd);
- return -1;
-+ } else if (os_strncmp(cmd, "multi_ap=", 9) == 0) {
-+ multi_ap = atoi(cmd + 9);
- }
-
- #ifdef CONFIG_AP
-@@ -1191,7 +1194,7 @@ static int wpa_supplicant_ctrl_iface_wps
- return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid, _p2p_dev_addr);
- #endif /* CONFIG_AP */
-
-- return wpas_wps_start_pbc(wpa_s, _bssid, 0);
-+ return wpas_wps_start_pbc(wpa_s, _bssid, 0, multi_ap);
- }
-
-
---- a/wpa_supplicant/dbus/dbus_new_handlers_wps.c
-+++ b/wpa_supplicant/dbus/dbus_new_handlers_wps.c
-@@ -289,7 +289,7 @@ DBusMessage * wpas_dbus_handler_wps_star
- if (ret > 0)
- os_snprintf(npin, sizeof(npin), "%08d", ret);
- } else {
-- ret = wpas_wps_start_pbc(wpa_s, params.bssid, 0);
-+ ret = wpas_wps_start_pbc(wpa_s, params.bssid, 0, 0);
- }
-
- if (ret < 0) {
---- a/wpa_supplicant/dbus/dbus_old_handlers_wps.c
-+++ b/wpa_supplicant/dbus/dbus_old_handlers_wps.c
-@@ -37,9 +37,9 @@ DBusMessage * wpas_dbus_iface_wps_pbc(DB
- return wpas_dbus_new_invalid_opts_error(message, NULL);
-
- if (os_strcmp(arg_bssid, "any") == 0)
-- ret = wpas_wps_start_pbc(wpa_s, NULL, 0);
-+ ret = wpas_wps_start_pbc(wpa_s, NULL, 0, 0);
- else if (!hwaddr_aton(arg_bssid, bssid))
-- ret = wpas_wps_start_pbc(wpa_s, bssid, 0);
-+ ret = wpas_wps_start_pbc(wpa_s, bssid, 0, 0);
- else {
- return wpas_dbus_new_invalid_opts_error(message,
- "Invalid BSSID");
---- a/wpa_supplicant/events.c
-+++ b/wpa_supplicant/events.c
-@@ -4816,7 +4816,7 @@ void supplicant_event(void *ctx, enum wp
- break;
- case EVENT_WPS_BUTTON_PUSHED:
- #ifdef CONFIG_WPS
-- wpas_wps_start_pbc(wpa_s, NULL, 0);
-+ wpas_wps_start_pbc(wpa_s, NULL, 0, 0);
- #endif /* CONFIG_WPS */
- break;
- case EVENT_AVOID_FREQUENCIES:
---- a/wpa_supplicant/p2p_supplicant.c
-+++ b/wpa_supplicant/p2p_supplicant.c
-@@ -1649,7 +1649,7 @@ static void wpas_start_wps_enrollee(stru
- wpa_supplicant_ap_deinit(wpa_s);
- wpas_copy_go_neg_results(wpa_s, res);
- if (res->wps_method == WPS_PBC) {
-- wpas_wps_start_pbc(wpa_s, res->peer_interface_addr, 1);
-+ wpas_wps_start_pbc(wpa_s, res->peer_interface_addr, 1, 0);
- #ifdef CONFIG_WPS_NFC
- } else if (res->wps_method == WPS_NFC) {
- wpas_wps_start_nfc(wpa_s, res->peer_device_addr,
---- a/wpa_supplicant/wps_supplicant.c
-+++ b/wpa_supplicant/wps_supplicant.c
-@@ -1137,9 +1137,10 @@ static void wpas_wps_reassoc(struct wpa_
-
-
- int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
-- int p2p_group)
-+ int p2p_group, int multi_ap_backhaul_sta)
- {
- struct wpa_ssid *ssid;
-+ char phase1[32];
-
- #ifdef CONFIG_AP
- if (wpa_s->ap_iface) {
-@@ -1177,10 +1178,14 @@ int wpas_wps_start_pbc(struct wpa_suppli
- }
- }
- #endif /* CONFIG_P2P */
-- if (wpa_config_set(ssid, "phase1", "\"pbc=1\"", 0) < 0)
-+ if (os_snprintf(phase1, sizeof(phase1), "pbc=1%s",
-+ multi_ap_backhaul_sta ? " multi_ap=1" : "") ||
-+ wpa_config_set_quoted(ssid, "phase1", phase1) < 0)
- return -1;
- if (wpa_s->wps_fragment_size)
- ssid->eap.fragment_size = wpa_s->wps_fragment_size;
-+ if (multi_ap_backhaul_sta)
-+ ssid->multi_ap_backhaul_sta = 1;
- wpa_supplicant_wps_event(wpa_s, WPS_EV_PBC_ACTIVE, NULL);
- eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout,
- wpa_s, NULL);
---- a/wpa_supplicant/wps_supplicant.h
-+++ b/wpa_supplicant/wps_supplicant.h
-@@ -30,7 +30,7 @@ void wpas_wps_deinit(struct wpa_supplica
- int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s);
- enum wps_request_type wpas_wps_get_req_type(struct wpa_ssid *ssid);
- int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
-- int p2p_group);
-+ int p2p_group, int multi_ap_backhaul_sta);
- int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
- const char *pin, int p2p_group, u16 dev_pw_id);
- void wpas_wps_pbc_overlap(struct wpa_supplicant *wpa_s);
deleted file mode 100644
@@ -1,339 +0,0 @@
-From 8b04a4cddbd6dbadb24279713af7ac677e80d342 Mon Sep 17 00:00:00 2001
-From: Davina Lu <ylu@quantenna.com>
-Date: Tue, 2 Oct 2018 18:34:14 -0700
-Subject: [PATCH] hostapd: support Multi-AP backhaul STA onboarding
-
-The Wi-Fi Alliance Multi-AP Specification v1.0 allows onboarding of a
-backhaul STA through WPS. To enable this, the WPS registrar offers a
-different set of credentials (backhaul credentials instead of fronthaul
-credentials) when the Multi-AP subelement is present in the WFA vendor
-extension element of the WSC M1 message.
-
-Add 3 new configuration options to specify the backhaul credentials for
-the hostapd internal registrar: multi_ap_backhaul_ssid,
-multi_ap_backhaul_wpa_psk, multi_ap_backhaul_wpa_passphrase. These are
-only relevant for a fronthaul SSID, i.e. where multi_ap is set to 2 or
-3. When these options are set, pass the backhaul credentials instead of
-the normal credentials when the Multi-AP subelement is present.
-
-Ignore the Multi-AP subelement if the backhaul config options are not
-set. Note that for an SSID which is fronthaul and backhaul at the same
-time (i.e., multi_ap == 3), this results in the correct credentials
-being sent anyway.
-
-The security to be used for the backaul BSS is fixed to WPA2PSK. The
-Multi-AP Specification only allows Open and WPA2PSK networks to be
-configured. Although not stated explicitly, the backhaul link is
-intended to be always encrypted, hence WPA2PSK.
-
-To build the credentials, the credential-building code is essentially
-copied and simplified. Indeed, the backhaul credentials are always
-WPA2PSK and never use per-device PSK. All the options set for the
-fronthaul BSS WPS are simply ignored.
-
-Signed-off-by: Davina Lu <ylu@quantenna.com>
-Signed-off-by: Igor Mitsyanko <igor.mitsyanko.os@quantenna.com>
-Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
----
-v4: no change
----
- hostapd/config_file.c | 47 ++++++++++++++++++++++++++++++++++++++++
- hostapd/hostapd.conf | 9 ++++++++
- src/ap/ap_config.c | 2 ++
- src/ap/ap_config.h | 1 +
- src/ap/wps_hostapd.c | 26 ++++++++++++++++++++++
- src/wps/wps.h | 32 +++++++++++++++++++++++++++
- src/wps/wps_attr_parse.c | 11 ++++++++++
- src/wps/wps_attr_parse.h | 1 +
- src/wps/wps_dev_attr.c | 5 +++++
- src/wps/wps_dev_attr.h | 1 +
- src/wps/wps_registrar.c | 25 ++++++++++++++++++++-
- 11 files changed, 159 insertions(+), 1 deletion(-)
-
---- a/hostapd/config_file.c
-+++ b/hostapd/config_file.c
-@@ -3479,6 +3479,53 @@ static int hostapd_config_fill(struct ho
- line, pos);
- return 1;
- }
-+ } else if (os_strcmp(buf, "multi_ap_backhaul_ssid") == 0) {
-+ size_t slen;
-+ char *str = wpa_config_parse_string(pos, &slen);
-+
-+ if (str == NULL || slen < 1 || slen > SSID_MAX_LEN) {
-+ wpa_printf(MSG_ERROR, "Line %d: invalid SSID '%s'",
-+ line, pos);
-+ os_free(str);
-+ return 1;
-+ }
-+ os_memcpy(bss->multi_ap_backhaul_ssid.ssid, str, slen);
-+ bss->multi_ap_backhaul_ssid.ssid_len = slen;
-+ bss->multi_ap_backhaul_ssid.ssid_set = 1;
-+ os_free(str);
-+ } else if (os_strcmp(buf, "multi_ap_backhaul_wpa_passphrase") == 0) {
-+ int len = os_strlen(pos);
-+
-+ if (len < 8 || len > 63) {
-+ wpa_printf(MSG_ERROR,
-+ "Line %d: invalid WPA passphrase length %d (expected 8..63)",
-+ line, len);
-+ return 1;
-+ }
-+ os_free(bss->multi_ap_backhaul_ssid.wpa_passphrase);
-+ bss->multi_ap_backhaul_ssid.wpa_passphrase = os_strdup(pos);
-+ if (bss->multi_ap_backhaul_ssid.wpa_passphrase) {
-+ hostapd_config_clear_wpa_psk(&bss->multi_ap_backhaul_ssid.wpa_psk);
-+ bss->multi_ap_backhaul_ssid.wpa_passphrase_set = 1;
-+ }
-+ } else if (os_strcmp(buf, "multi_ap_backhaul_wpa_psk") == 0) {
-+ hostapd_config_clear_wpa_psk(&bss->multi_ap_backhaul_ssid.wpa_psk);
-+ bss->multi_ap_backhaul_ssid.wpa_psk =
-+ os_zalloc(sizeof(struct hostapd_wpa_psk));
-+ if (bss->multi_ap_backhaul_ssid.wpa_psk == NULL)
-+ return 1;
-+ if (hexstr2bin(pos, bss->multi_ap_backhaul_ssid.wpa_psk->psk,
-+ PMK_LEN) ||
-+ pos[PMK_LEN * 2] != '\0') {
-+ wpa_printf(MSG_ERROR, "Line %d: Invalid PSK '%s'.",
-+ line, pos);
-+ hostapd_config_clear_wpa_psk(&bss->multi_ap_backhaul_ssid.wpa_psk);
-+ return 1;
-+ }
-+ bss->multi_ap_backhaul_ssid.wpa_psk->group = 1;
-+ os_free(bss->multi_ap_backhaul_ssid.wpa_passphrase);
-+ bss->multi_ap_backhaul_ssid.wpa_passphrase = NULL;
-+ bss->multi_ap_backhaul_ssid.wpa_psk_set = 1;
- } else if (os_strcmp(buf, "upnp_iface") == 0) {
- os_free(bss->upnp_iface);
- bss->upnp_iface = os_strdup(pos);
---- a/hostapd/hostapd.conf
-+++ b/hostapd/hostapd.conf
-@@ -1852,6 +1852,15 @@ own_ip_addr=127.0.0.1
- # attribute.
- #ap_settings=hostapd.ap_settings
-
-+# Multi-AP backhaul BSS config
-+# Used in WPS when multi_ap=2 or 3. Defines "backhaul BSS" credentials.
-+# These are passed in WPS M8 instead of the normal (fronthaul) credentials
-+# if the enrollee has the Multi-AP subelement set. Backhaul SSID is formatted
-+# like ssid2. The key is set like wpa_psk or wpa_passphrase.
-+#multi_ap_backhaul_ssid="backhaul"
-+#multi_ap_backhaul_wpa_psk=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
-+#multi_ap_backhaul_wpa_passphrase=secret passphrase
-+
- # WPS UPnP interface
- # If set, support for external Registrars is enabled.
- #upnp_iface=br0
---- a/src/ap/ap_config.c
-+++ b/src/ap/ap_config.c
-@@ -582,6 +582,8 @@ void hostapd_config_free_bss(struct host
- os_free(conf->ap_pin);
- os_free(conf->extra_cred);
- os_free(conf->ap_settings);
-+ hostapd_config_clear_wpa_psk(&conf->multi_ap_backhaul_ssid.wpa_psk);
-+ str_clear_free(conf->multi_ap_backhaul_ssid.wpa_passphrase);
- os_free(conf->upnp_iface);
- os_free(conf->friendly_name);
- os_free(conf->manufacturer_url);
---- a/src/ap/ap_config.h
-+++ b/src/ap/ap_config.h
-@@ -456,6 +456,7 @@ struct hostapd_bss_config {
- int force_per_enrollee_psk;
- u8 *ap_settings;
- size_t ap_settings_len;
-+ struct hostapd_ssid multi_ap_backhaul_ssid;
- char *upnp_iface;
- char *friendly_name;
- char *manufacturer_url;
---- a/src/ap/wps_hostapd.c
-+++ b/src/ap/wps_hostapd.c
-@@ -962,6 +962,7 @@ static void hostapd_free_wps(struct wps_
- wpabuf_free(wps->dev.vendor_ext[i]);
- wps_device_data_free(&wps->dev);
- os_free(wps->network_key);
-+ os_free(wps->multi_ap_backhaul_network_key);
- hostapd_wps_nfc_clear(wps);
- wpabuf_free(wps->dh_pubkey);
- wpabuf_free(wps->dh_privkey);
-@@ -1131,6 +1132,31 @@ int hostapd_init_wps(struct hostapd_data
- wps->encr_types_wpa = WPS_ENCR_AES | WPS_ENCR_TKIP;
- }
-
-+ if (hapd->conf->multi_ap & FRONTHAUL_BSS &&
-+ hapd->conf->multi_ap_backhaul_ssid.ssid_len) {
-+ wps->multi_ap_backhaul_ssid_len =
-+ hapd->conf->multi_ap_backhaul_ssid.ssid_len;
-+ os_memcpy(wps->multi_ap_backhaul_ssid,
-+ hapd->conf->multi_ap_backhaul_ssid.ssid,
-+ wps->multi_ap_backhaul_ssid_len);
-+ if (conf->multi_ap_backhaul_ssid.wpa_passphrase) {
-+ wps->multi_ap_backhaul_network_key =
-+ (u8 *) os_strdup(conf->multi_ap_backhaul_ssid.wpa_passphrase);
-+ wps->multi_ap_backhaul_network_key_len =
-+ os_strlen(conf->multi_ap_backhaul_ssid.wpa_passphrase);
-+ } else if (conf->multi_ap_backhaul_ssid.wpa_psk) {
-+ wps->multi_ap_backhaul_network_key =
-+ os_malloc(2 * PMK_LEN + 1);
-+ if (wps->multi_ap_backhaul_network_key == NULL)
-+ goto fail;
-+ wpa_snprintf_hex((char *) wps->multi_ap_backhaul_network_key,
-+ 2 * PMK_LEN + 1,
-+ conf->multi_ap_backhaul_ssid.wpa_psk->psk,
-+ PMK_LEN);
-+ wps->multi_ap_backhaul_network_key_len = 2 * PMK_LEN;
-+ }
-+ }
-+
- wps->ap_settings = conf->ap_settings;
- wps->ap_settings_len = conf->ap_settings_len;
-
---- a/src/wps/wps.h
-+++ b/src/wps/wps.h
-@@ -100,6 +100,7 @@ struct wps_device_data {
- struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
-
- int p2p;
-+ u8 multi_ap_ext;
- };
-
- /**
-@@ -730,6 +731,37 @@ struct wps_context {
- int psk_set;
-
- /**
-+ * multi_ap_backhaul_ssid - SSID to supply to a Multi-AP backhaul
-+ * enrollee
-+ *
-+ * This SSID is used by the Registrar to fill in information for
-+ * Credentials when the enrollee advertises it is a Multi-AP backhaul
-+ * STA.
-+ */
-+ u8 multi_ap_backhaul_ssid[SSID_MAX_LEN];
-+
-+ /**
-+ * multi_ap_backhaul_ssid_len - Length of multi_ap_backhaul_ssid in
-+ * octets
-+ */
-+ size_t multi_ap_backhaul_ssid_len;
-+
-+ /**
-+ * multi_ap_backhaul_network_key - The Network Key (PSK) for the
-+ * Multi-AP backhaul enrollee.
-+ *
-+ * This key can be either the ASCII passphrase (8..63 characters) or the
-+ * 32-octet PSK (64 hex characters).
-+ */
-+ u8 *multi_ap_backhaul_network_key;
-+
-+ /**
-+ * multi_ap_backhaul_network_key_len - Length of
-+ * multi_ap_backhaul_network_key in octets
-+ */
-+ size_t multi_ap_backhaul_network_key_len;
-+
-+ /**
- * ap_settings - AP Settings override for M7 (only used at AP)
- *
- * If %NULL, AP Settings attributes will be generated based on the
---- a/src/wps/wps_attr_parse.c
-+++ b/src/wps/wps_attr_parse.c
-@@ -67,6 +67,17 @@ static int wps_set_vendor_ext_wfa_subele
- }
- attr->registrar_configuration_methods = pos;
- break;
-+ case WFA_ELEM_MULTI_AP:
-+ if (len != 1) {
-+ wpa_printf(MSG_DEBUG,
-+ "WPS: Invalid Multi-AP Extension length %u",
-+ len);
-+ return -1;
-+ }
-+ attr->multi_ap_ext = *pos;
-+ wpa_printf(MSG_DEBUG, "WPS: Multi-AP Extension 0x%02x",
-+ attr->multi_ap_ext);
-+ break;
- default:
- wpa_printf(MSG_MSGDUMP, "WPS: Skipped unknown WFA Vendor "
- "Extension subelement %u", id);
---- a/src/wps/wps_attr_parse.h
-+++ b/src/wps/wps_attr_parse.h
-@@ -97,6 +97,7 @@ struct wps_parse_attr {
- const u8 *cred[MAX_CRED_COUNT];
- const u8 *req_dev_type[MAX_REQ_DEV_TYPE_COUNT];
- const u8 *vendor_ext[MAX_WPS_PARSE_VENDOR_EXT];
-+ u8 multi_ap_ext;
- };
-
- int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr);
---- a/src/wps/wps_dev_attr.c
-+++ b/src/wps/wps_dev_attr.c
-@@ -389,6 +389,11 @@ int wps_process_os_version(struct wps_de
- return 0;
- }
-
-+void wps_process_vendor_ext_m1(struct wps_device_data *dev, const u8 ext)
-+{
-+ dev->multi_ap_ext = ext;
-+ wpa_printf(MSG_DEBUG, "WPS: Multi-AP extension value %02x", dev->multi_ap_ext);
-+}
-
- int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands)
- {
---- a/src/wps/wps_dev_attr.h
-+++ b/src/wps/wps_dev_attr.h
-@@ -29,6 +29,7 @@ int wps_build_dev_name(struct wps_device
- int wps_process_device_attrs(struct wps_device_data *dev,
- struct wps_parse_attr *attr);
- int wps_process_os_version(struct wps_device_data *dev, const u8 *ver);
-+void wps_process_vendor_ext_m1(struct wps_device_data *dev, const u8 ext);
- int wps_process_rf_bands(struct wps_device_data *dev, const u8 *bands);
- void wps_device_data_free(struct wps_device_data *dev);
- int wps_build_vendor_ext(struct wps_device_data *dev, struct wpabuf *msg);
---- a/src/wps/wps_registrar.c
-+++ b/src/wps/wps_registrar.c
-@@ -1588,7 +1588,6 @@ int wps_build_credential_wrap(struct wpa
- return 0;
- }
-
--
- int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
- {
- struct wpabuf *cred;
-@@ -1603,6 +1602,29 @@ int wps_build_cred(struct wps_data *wps,
- }
- os_memset(&wps->cred, 0, sizeof(wps->cred));
-
-+ if (wps->peer_dev.multi_ap_ext == MULTI_AP_BACKHAUL_STA &&
-+ wps->wps->multi_ap_backhaul_ssid_len) {
-+ wpa_printf(MSG_DEBUG, "WPS: Use backhaul STA credentials");
-+ os_memcpy(wps->cred.ssid, wps->wps->multi_ap_backhaul_ssid,
-+ wps->wps->multi_ap_backhaul_ssid_len);
-+ wps->cred.ssid_len = wps->wps->multi_ap_backhaul_ssid_len;
-+ /* Backhaul is always WPA2PSK */
-+ wps->cred.auth_type = WPS_AUTH_WPA2PSK;
-+ wps->cred.encr_type = WPS_ENCR_AES;
-+ /* Set MAC address in the Credential to be the Enrollee's MAC
-+ * address
-+ */
-+ os_memcpy(wps->cred.mac_addr, wps->mac_addr_e, ETH_ALEN);
-+ if (wps->wps->multi_ap_backhaul_network_key) {
-+ os_memcpy(wps->cred.key,
-+ wps->wps->multi_ap_backhaul_network_key,
-+ wps->wps->multi_ap_backhaul_network_key_len);
-+ wps->cred.key_len =
-+ wps->wps->multi_ap_backhaul_network_key_len;
-+ }
-+ goto use_provided;
-+ }
-+
- os_memcpy(wps->cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
- wps->cred.ssid_len = wps->wps->ssid_len;
-
-@@ -2705,6 +2727,7 @@ static enum wps_process_res wps_process_
- wps->use_psk_key = 1;
- }
- #endif /* WPS_WORKAROUNDS */
-+ wps_process_vendor_ext_m1(&wps->peer_dev, attr->multi_ap_ext);
-
- wps->state = SEND_M2;
- return WPS_CONTINUE;
deleted file mode 100644
@@ -1,181 +0,0 @@
-From bd733055a22c8ca3bcd7648bf716da2713b3d9f1 Mon Sep 17 00:00:00 2001
-From: "Arnout Vandecappelle (Essensium/Mind)" <arnout@mind.be>
-Date: Mon, 21 Jan 2019 16:44:06 +0100
-Subject: [PATCH] hostapd: add README-MULTI-AP
-
-Document what hostapd and wpa_supplicant do for Multi-AP.
-
-This is only included in hostapd, since a Multi-AP device is always an
-access point so it should have hostapd.
-
-Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
----
-v4: wps_pbc has multi_ap as a parameter instead of config option.
----
- hostapd/README-MULTI-AP | 160 ++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 160 insertions(+)
- create mode 100644 hostapd/README-MULTI-AP
-
---- /dev/null
-+++ b/hostapd/README-MULTI-AP
-@@ -0,0 +1,160 @@
-+hostapd, wpa_supplicant and the Multi-AP Specification
-+======================================================
-+
-+This document describes how hostapd and wpa_supplicant can be configured to
-+support the Multi-AP Specification.
-+
-+Introduction to Multi-AP
-+------------------------
-+
-+The Wi-Fi Alliance Multi-AP Specification is the technical specification for
-+Wi-Fi CERTIFIED EasyMesh(TM) [1], the Wi-Fi Alliance® certification program for
-+Multi-AP. It defines control protocols between Wi-Fi® access points (APs) to
-+join them into a network with centralized control and operation. It is targeted
-+only at routers (repeaters, gateways, ...), not at clients. Clients are not
-+involved at all in the protocols.
-+
-+Most of the Multi-AP specification falls outside of the scope of
-+hostapd/wpa_supplicant. hostapd/wpa_supplicant is only involved for the items
-+summarized below. The rest of the protocol must be implemented by a separate
-+daemon, e.g. prplMesh [2]. That daemon also needs to communicate with hostapd,
-+e.g. to get a list of associated clients, but this can be done using the normal
-+hostapd interfaces.
-+
-+hostapd/wpa_supplicant needs to be configured specifically to support:
-+- the WPS onboarding process;
-+- configuring backhaul links.
-+
-+The text below refers to "Multi-AP Specification v1.0" [3].
-+
-+
-+Fronthaul and backhaul links
-+----------------------------
-+
-+In a Multi-AP network, the central controller can configure the SSIDs on the
-+devices that are joined into the network. These are called fronthaul SSIDs.
-+From the point of view of hostapd, there is nothing special about these
-+fronthaul SSIDs.
-+
-+In addition to fronthaul SSIDs, the controller can also configure backhaul
-+links. A backhaul link is a link between two access point devices, giving
-+internet access to access point devices that don't have a wired link. The
-+Multi-AP specification doesn't dictate this, but typically the backhaul link
-+will be bridged into a LAN together with (one of) the fronthaul SSID(s) and the
-+wired Ethernet ports.
-+
-+A backhaul link must be treated specially by hostapd and wpa_supplicant. One
-+side of the backhaul link is configured through the Multi-AP protocol as the
-+"backhaul STA", i.e. the client side of the link. A backhaul STA is like any
-+station and is handled appropriately by wpa_supplicant, but two additional
-+features are required. It must send an additional information element in each
-+(Re-)Association Request ([3], section 5.2, paragraph 4). In addition, it must
-+use 4-address mode for all frames sent over this link ([3], section 14).
-+Therefore, wpa_supplicant must be configured explicitly as the backhaul STA
-+role, by setting 'multi_ap_backhaul_sta=1' in the network configuration block
-+or when configuring the SSID through the client socket. When
-+'multi_ap_backhaul_sta=1', wpa_supplicant includes the Multi-AP IE in
-+(Re-)Association Request messages and verifies that it is included in the
-+(Re-)Association Response. If it is not, association fails. If it is,
-+wpa_supplicant sets 4-address mode for this interface through a driver
-+callback.
-+
-+The AP side of the backhaul link is called a "backhaul SSID". Such an SSID must
-+be handled specially by hostapd, because it must add an additional information
-+element in each (Re-)Association Response, but only to stations that have
-+identified themselves as backhaul stations ([3], section 5.2, paragraph 5-6).
-+This is important because it is possible to use the same BSS and SSID for
-+fronthaul and backhaul at the same time. The additional information element must
-+only be used for frames sent to a backhaul STA, not to a normal STA. Also,
-+frames sent to a backhaul STA must use 4-address mode, while frames sent to a
-+normal STA (fronthaul, when it's a fronthaul and backhaul SSID) must use
-+3-address mode.
-+
-+An SSID is configured in Multi-AP mode in hostapd by setting the 'multi_ap'
-+configuration option to 1 (backhaul SSID), 2 (fronthaul SSID) or 3
-+(simultaneous backhaul and fronthaul SSID). If this option is set, hostapd
-+parses the Multi-AP information element in the Association Request. If the
-+station is a backhaul STA and the SSID is configured as a backhaul SSID,
-+hostapd sets up 4-address mode. Since there may be multiple stations connected
-+simultaneously, and each of them has a different RA (receiver address), a VLAN
-+is created for each backhaul STA and it is automatically added to a bridge.
-+This is the same behavior as for WDS, and the relevant option ('bridge' or
-+'wds_bridge') applies here as well.
-+
-+If 'multi_ap' is 1 (backhaul SSID only), any station that tries to associate
-+without the Multi-AP information element will be denied.
-+
-+If 'multi_ap' is 2 (fronthaul SSID only), any station that tries to associate
-+with the Multi-AP information element will be denied. That is also the only
-+difference with 'multi_ap' set to 0: in the latter case, the Multi-AP
-+information element is simply ignored.
-+
-+In summary, this is the end-to-end behaviour for a backhaul BSS (i.e.,
-+multi_ap_backhaul_sta=1 in wpa_supplicant on STA, and multi_ap=1 or 3 in
-+hostapd on AP). Note that point 1 means that hostapd must not be configured
-+with WPS support on the backhaul BSS (multi_ap=1). hostapd does not check for
-+that.
-+
-+1. Backhaul BSS beacons do not advertise WPS support (other than that, nothing
-+ multi-ap specific).
-+2. STA sends authentication req (nothing multi-ap specific).
-+3. AP sends authentication resp (nothing multi-ap specific).
-+4. STA sends association req with Multi-AP IE.
-+5. AP send association resp with Multi-AP IE.
-+6. STA and AP both use 4-address mode for data.
-+
-+
-+WPS support
-+-----------
-+
-+WPS requires more special handling. WPS must only be advertised on fronthaul
-+SSIDs, not on backhaul SSIDs, so WPS should not be enabled on a backhaul-only
-+SSID in hostapd.conf. The WPS configuration purely works on the fronthaul SSID.
-+When a WPS M1 message has an additional subelement that indicates a request for
-+a multi-AP backhaul link, hostapd must not respond with the normal fronthaul
-+SSID credentials; instead, it should respond with the (potentially different)
-+backhaul SSID credentials.
-+
-+To support this, hostapd has the 'multi_ap_backhaul_ssid',
-+'multi_ap_backhaul_wpa_psk' and 'multi_ap_backhaul_wpa_passphrase' options.
-+When these are set on an SSID with WPS, they are used instead of the normal
-+credentials when hostapd receives a WPS M1 message with the Multi-AP IE. Only
-+WPA2 Personal is supported in the Multi-AP specification, so there is no need
-+to specify authentication or encryption options. For the backhaul credentials,
-+per-device PSK is not supported.
-+
-+If the SSID is a simultaneous backhaul and fronthaul SSID, there is no need to
-+specify the backhaul credentials, since the backhaul and fronthaul credentials
-+are identical.
-+
-+To enable the Multi-AP backhaul STA feature when it performs WPS, a new
-+parameter has been introduced to the WPS_PBC control interface call.
-+When this option is set, it adds the multi-AP backhaul subelement to
-+the association and M1 messages. It then configures the new SSID with
-+'multi_ap_backhaul_sta=1'. Note that this means that if the AP does not
-+follow the Multi-AP specification, wpa_supplicant will fail to
-+associate.
-+
-+In summary, this is the end-to-end behaviour for WPS of a backhaul link (i.e.,
-+multi_ap=1 option is given in the wps_pbc call on the STA side, and multi_ap=2
-+and multi_ap_backhaul_ssid and either multi_ap_backhaul_wpa_psk or
-+multi_ap_backhaul_wpa_passphrase are set to the credentials of a backhaul SSID
-+in hostapd on registrar AP).
-+
-+1. Fronthaul BSS beacons advertise WPS support (nothing multi-ap specific).
-+2. Enrollee sends authentication req (nothing multi-ap specific).
-+3. AP sends authentication resp (nothing multi-ap specific).
-+4. Enrollee sends association req with Multi-AP IE.
-+5. AP send association resp with Multi-AP IE.
-+6. Enrollee sends M1 with additional Multi-AP subelement
-+7. AP sends M8 with backhaul instead of fronthaul credentials.
-+8. Enrollee sends Deauth.
-+
-+
-+References
-+----------
-+
-+[1] https://www.wi-fi.org/discover-wi-fi/wi-fi-easymesh
-+[2] https://github.com/prplfoundation/prplMesh
-+[3] https://www.wi-fi.org/file/multi-ap-specification-v10
-+ (requires registration)
deleted file mode 100644
@@ -1,182 +0,0 @@
-From 0729e01f5830ebf4701f0b1b7ff1bd2a2eedae40 Mon Sep 17 00:00:00 2001
-From: "Arnout Vandecappelle (Essensium/Mind)" <arnout@mind.be>
-Date: Tue, 12 Feb 2019 11:02:42 +0100
-Subject: [PATCH] tests: add WPS tests to multi_ap hwsim tests
-
-Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
----
-v4: new patch
----
- tests/hwsim/test_multi_ap.py | 164 +++++++++++++++++++++++++++++++++++
- 1 file changed, 164 insertions(+)
-
---- a/tests/hwsim/test_multi_ap.py
-+++ b/tests/hwsim/test_multi_ap.py
-@@ -61,3 +61,167 @@ def test_multi_ap_fronthaul_on_ap(dev, a
- raise Exception("Connection result not reported")
- if "CTRL-EVENT-DISCONNECTED" not in ev:
- raise Exception("Unexpected connection result")
-+
-+def run_multi_ap_wps(dev, apdev, params, multi_ap_bssid = None):
-+ """Helper for running Multi-AP WPS tests
-+
-+ dev[0] does multi_ap WPS, dev[1] does normal WPS. apdev[0] is the fronthaul
-+ BSS. If there is a separate backhaul BSS, it must have been set up by the
-+ caller. params are the normal SSID parameters, they will be extended with
-+ the WPS parameters. multi_ap_bssid must be given if it is not equal to the
-+ fronthaul BSSID."""
-+
-+ if multi_ap_bssid is None:
-+ multi_ap_bssid = apdev[0]['bssid']
-+ params.update({"wps_state": "2", "eap_server": "1"})
-+
-+ # WPS with multi-ap station dev[0]
-+ hapd = hostapd.add_ap(apdev[0], params)
-+ hapd.request("WPS_PBC")
-+ if "PBC Status: Active" not in hapd.request("WPS_GET_STATUS"):
-+ raise Exception("PBC status not shown correctly")
-+
-+ dev[0].request("WPS_PBC multi_ap=1")
-+ dev[0].wait_connected(timeout=20)
-+ status = dev[0].get_status()
-+ if status['wpa_state'] != 'COMPLETED' or status['bssid'] != multi_ap_bssid:
-+ raise Exception("Not fully connected")
-+ if status['ssid'] != params['multi_ap_backhaul_ssid'].strip('"'):
-+ raise Exception("Unexpected SSID %s != %s" % (status['ssid'], params["multi_ap_backhaul_ssid"]))
-+ if status['pairwise_cipher'] != 'CCMP':
-+ raise Exception("Unexpected encryption configuration %s" % status['pairwise_cipher'])
-+ if status['key_mgmt'] != 'WPA2-PSK':
-+ raise Exception("Unexpected key_mgmt")
-+
-+ status = hapd.request("WPS_GET_STATUS")
-+ if "PBC Status: Disabled" not in status:
-+ raise Exception("PBC status not shown correctly")
-+ if "Last WPS result: Success" not in status:
-+ raise Exception("Last WPS result not shown correctly")
-+ if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
-+ raise Exception("Peer address not shown correctly")
-+
-+ if len(dev[0].list_networks()) != 1:
-+ raise Exception("Unexpected number of network blocks")
-+
-+ # WPS with non-multi-ap station dev[1]
-+ hapd.request("WPS_PBC")
-+ if "PBC Status: Active" not in hapd.request("WPS_GET_STATUS"):
-+ raise Exception("PBC status not shown correctly")
-+
-+ dev[1].request("WPS_PBC")
-+ dev[1].wait_connected(timeout=20)
-+ status = dev[1].get_status()
-+ if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
-+ raise Exception("Not fully connected")
-+ if status['ssid'] != params["ssid"]:
-+ raise Exception("Unexpected SSID")
-+ # Fronthaul may be something else than WPA2-PSK so don't test it.
-+
-+ status = hapd.request("WPS_GET_STATUS")
-+ if "PBC Status: Disabled" not in status:
-+ raise Exception("PBC status not shown correctly")
-+ if "Last WPS result: Success" not in status:
-+ raise Exception("Last WPS result not shown correctly")
-+ if "Peer Address: " + dev[1].p2p_interface_addr() not in status:
-+ raise Exception("Peer address not shown correctly")
-+
-+ if len(dev[1].list_networks()) != 1:
-+ raise Exception("Unexpected number of network blocks")
-+
-+
-+def test_multi_ap_wps_shared(dev, apdev):
-+ """WPS on shared fronthaul/backhaul AP"""
-+ ssid = "multi-ap-wps"
-+ passphrase = "12345678"
-+ params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase)
-+ params.update({"multi_ap": "3",
-+ "multi_ap_backhaul_ssid": '"%s"' % ssid,
-+ "multi_ap_backhaul_wpa_passphrase": passphrase})
-+ run_multi_ap_wps(dev, apdev, params)
-+
-+def test_multi_ap_wps_shared_psk(dev, apdev):
-+ """WPS on shared fronthaul/backhaul AP using PSK"""
-+ ssid = "multi-ap-wps"
-+ psk = "1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
-+ params = hostapd.wpa2_params(ssid=ssid)
-+ params.update({"wpa_psk": psk, "multi_ap": "3",
-+ "multi_ap_backhaul_ssid": '"%s"' % ssid,
-+ "multi_ap_backhaul_wpa_psk": psk})
-+ run_multi_ap_wps(dev, apdev, params)
-+
-+def test_multi_ap_wps_split(dev, apdev):
-+ """WPS on split fronthaul and backhaul AP"""
-+ backhaul_ssid = "multi-ap-backhaul-wps"
-+ backhaul_passphrase = "87654321"
-+ params = hostapd.wpa2_params(ssid="multi-ap-fronthaul-wps", passphrase="12345678")
-+ params.update({"multi_ap": "2",
-+ "multi_ap_backhaul_ssid": '"%s"' % backhaul_ssid,
-+ "multi_ap_backhaul_wpa_passphrase": backhaul_passphrase})
-+ params_backhaul = hostapd.wpa2_params(ssid=backhaul_ssid, passphrase=backhaul_passphrase)
-+ params_backhaul.update({"multi_ap": "1"})
-+ hapd_backhaul = hostapd.add_ap(apdev[1], params_backhaul)
-+
-+ run_multi_ap_wps(dev, apdev, params, hapd_backhaul.own_addr())
-+
-+def test_multi_ap_wps_split_psk(dev, apdev):
-+ """WPS on split fronthaul and backhaul AP"""
-+ backhaul_ssid = "multi-ap-backhaul-wps"
-+ backhaul_psk = "1234567890abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
-+ params = hostapd.wpa2_params(ssid="multi-ap-fronthaul-wps", passphrase="12345678")
-+ params.update({"multi_ap": "2",
-+ "multi_ap_backhaul_ssid": '"%s"' % backhaul_ssid,
-+ "multi_ap_backhaul_wpa_psk": backhaul_psk})
-+ params_backhaul = hostapd.wpa2_params(ssid=backhaul_ssid)
-+ params_backhaul.update({"multi_ap": "1", "wpa_psk": backhaul_psk})
-+ hapd_backhaul = hostapd.add_ap(apdev[1], params_backhaul)
-+
-+ run_multi_ap_wps(dev, apdev, params, hapd_backhaul.own_addr())
-+
-+def test_multi_ap_wps_split_mixed(dev, apdev):
-+ """WPS on split fronthaul and backhaul AP with mixed-mode fronthaul"""
-+ backhaul_ssid = "multi-ap-backhaul-wps"
-+ backhaul_passphrase = "87654321"
-+ params = hostapd.wpa_mixed_params(ssid="multi-ap-fronthaul-wps", passphrase="12345678")
-+ params.update({"multi_ap": "2",
-+ "multi_ap_backhaul_ssid": '"%s"' % backhaul_ssid,
-+ "multi_ap_backhaul_wpa_passphrase": backhaul_passphrase})
-+ params_backhaul = hostapd.wpa2_params(ssid=backhaul_ssid, passphrase=backhaul_passphrase)
-+ params_backhaul.update({"multi_ap": "1"})
-+ hapd_backhaul = hostapd.add_ap(apdev[1], params_backhaul)
-+
-+ run_multi_ap_wps(dev, apdev, params, hapd_backhaul.own_addr())
-+
-+def test_multi_ap_wps_split_open(dev, apdev):
-+ """WPS on split fronthaul and backhaul AP with open fronthaul"""
-+ backhaul_ssid = "multi-ap-backhaul-wps"
-+ backhaul_passphrase = "87654321"
-+ params = {"ssid": "multi-ap-wps-fronthaul", "multi_ap": "2",
-+ "multi_ap_backhaul_ssid": '"%s"' % backhaul_ssid,
-+ "multi_ap_backhaul_wpa_passphrase": backhaul_passphrase}
-+ params_backhaul = hostapd.wpa2_params(ssid=backhaul_ssid, passphrase=backhaul_passphrase)
-+ params_backhaul.update({"multi_ap": "1"})
-+ hapd_backhaul = hostapd.add_ap(apdev[1], params_backhaul)
-+
-+ run_multi_ap_wps(dev, apdev, params, hapd_backhaul.own_addr())
-+
-+def test_multi_ap_wps_fail_non_multi_ap(dev, apdev):
-+ """Multi-AP WPS on non-WPS AP fails"""
-+
-+ params = hostapd.wpa2_params(ssid="non-multi-ap-wps", passphrase="12345678")
-+ params.update({"wps_state": "2", "eap_server": "1"})
-+
-+ hapd = hostapd.add_ap(apdev[0], params)
-+ hapd.request("WPS_PBC")
-+ if "PBC Status: Active" not in hapd.request("WPS_GET_STATUS"):
-+ raise Exception("PBC status not shown correctly")
-+
-+ dev[0].request("WPS_PBC multi_ap=1")
-+ # Since we will fail to associate and WPS doesn't even get started, there
-+ # isn't much we can do except wait for timeout. For PBC, it is not possible
-+ # to change the timeout from 2 minutes. Instead of waiting for the timeout,
-+ # just check that WPS doesn't finish within reasonable time.
-+ ev = dev[0].wait_event(["WPS-SUCCESS", "WPS-FAIL"], timeout=20)
-+ if ev:
-+ raise Exception("WPS operation completed: " + ev)
-+ dev[0].request("WPS_CANCEL")
@@ -22,7 +22,7 @@
#define OCE_STA_CFON_ENABLED(hapd) \
((hapd->conf->oce & OCE_STA_CFON) && \
-@@ -136,6 +137,7 @@ struct hostapd_data {
+@@ -141,6 +142,7 @@ struct hostapd_data {
struct hostapd_iface *iface;
struct hostapd_config *iconf;
struct hostapd_bss_config *conf;
@@ -30,25 +30,17 @@
int interface_added; /* virtual interface added for this BSS */
unsigned int started:1;
unsigned int disabled:1;
-@@ -547,6 +549,7 @@ hostapd_alloc_bss_data(struct hostapd_if
- struct hostapd_bss_config *bss);
- int hostapd_setup_interface(struct hostapd_iface *iface);
- int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err);
-+void hostapd_set_own_neighbor_report(struct hostapd_data *hapd);
- void hostapd_interface_deinit(struct hostapd_iface *iface);
- void hostapd_interface_free(struct hostapd_iface *iface);
- struct hostapd_iface * hostapd_alloc_iface(void);
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
-@@ -373,6 +373,7 @@ static void hostapd_free_hapd_data(struc
- hapd->started = 0;
+@@ -374,6 +374,7 @@ static void hostapd_free_hapd_data(struc
+ hapd->beacon_set_done = 0;
wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface);
+ hostapd_ubus_free_bss(hapd);
iapp_deinit(hapd->iapp);
hapd->iapp = NULL;
accounting_deinit(hapd);
-@@ -1295,6 +1296,8 @@ static int hostapd_setup_bss(struct host
+@@ -1314,6 +1315,8 @@ static int hostapd_setup_bss(struct host
if (hapd->driver && hapd->driver->set_operstate)
hapd->driver->set_operstate(hapd->drv_priv, 1);
@@ -57,16 +49,7 @@
return 0;
}
-@@ -1709,7 +1712,7 @@ static enum nr_chan_width hostapd_get_nr
- #endif /* NEED_AP_MLME */
-
-
--static void hostapd_set_own_neighbor_report(struct hostapd_data *hapd)
-+void hostapd_set_own_neighbor_report(struct hostapd_data *hapd)
- {
- #ifdef NEED_AP_MLME
- u16 capab = hostapd_own_capab_info(hapd);
-@@ -1930,6 +1933,7 @@ static int hostapd_setup_interface_compl
+@@ -1828,6 +1831,7 @@ static int hostapd_setup_interface_compl
if (err)
goto fail;
@@ -74,7 +57,7 @@
wpa_printf(MSG_DEBUG, "Completing interface initialization");
if (iface->conf->channel) {
#ifdef NEED_AP_MLME
-@@ -2110,6 +2114,7 @@ dfs_offload:
+@@ -2020,6 +2024,7 @@ dfs_offload:
fail:
wpa_printf(MSG_ERROR, "Interface initialization failed");
@@ -82,7 +65,7 @@
hostapd_set_state(iface, HAPD_IFACE_DISABLED);
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
#ifdef CONFIG_FST
-@@ -2576,6 +2581,7 @@ void hostapd_interface_deinit_free(struc
+@@ -2489,6 +2494,7 @@ void hostapd_interface_deinit_free(struc
(unsigned int) iface->conf->num_bss);
driver = iface->bss[0]->driver;
drv_priv = iface->bss[0]->drv_priv;
@@ -92,14 +75,7 @@
__func__, driver, drv_priv);
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
-@@ -1759,12 +1759,13 @@ ieee802_11_set_radius_info(struct hostap
-
-
- static void handle_auth(struct hostapd_data *hapd,
-- const struct ieee80211_mgmt *mgmt, size_t len)
-+ const struct ieee80211_mgmt *mgmt, size_t len,
-+ struct hostapd_frame_info *fi)
- {
+@@ -2029,7 +2029,7 @@ static void handle_auth(struct hostapd_d
u16 auth_alg, auth_transaction, status_code;
u16 resp = WLAN_STATUS_SUCCESS;
struct sta_info *sta = NULL;
@@ -108,19 +84,19 @@
u16 fc;
const u8 *challenge = NULL;
u32 session_timeout, acct_interim_interval;
-@@ -1775,6 +1776,11 @@ static void handle_auth(struct hostapd_d
+@@ -2040,6 +2040,11 @@ static void handle_auth(struct hostapd_d
char *identity = NULL;
char *radius_cui = NULL;
u16 seq_ctrl;
+ struct hostapd_ubus_request req = {
+ .type = HOSTAPD_UBUS_AUTH_REQ,
+ .mgmt_frame = mgmt,
-+ .frame_info = fi,
++ .ssi_signal = rssi,
+ };
if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
-@@ -1935,6 +1941,13 @@ static void handle_auth(struct hostapd_d
+@@ -2201,6 +2206,13 @@ static void handle_auth(struct hostapd_d
resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
goto fail;
}
@@ -134,13 +110,7 @@
if (res == HOSTAPD_ACL_PENDING)
return;
-@@ -3287,12 +3300,12 @@ void fils_hlp_timeout(void *eloop_ctx, v
-
- static void handle_assoc(struct hostapd_data *hapd,
- const struct ieee80211_mgmt *mgmt, size_t len,
-- int reassoc)
-+ int reassoc, struct hostapd_frame_info *fi)
- {
+@@ -3699,7 +3711,7 @@ static void handle_assoc(struct hostapd_
u16 capab_info, listen_interval, seq_ctrl, fc;
u16 resp = WLAN_STATUS_SUCCESS, reply_res;
const u8 *pos;
@@ -149,19 +119,19 @@
struct sta_info *sta;
u8 *tmp = NULL;
struct hostapd_sta_wpa_psk_short *psk = NULL;
-@@ -3301,6 +3314,11 @@ static void handle_assoc(struct hostapd_
+@@ -3708,6 +3720,11 @@ static void handle_assoc(struct hostapd_
#ifdef CONFIG_FILS
int delay_assoc = 0;
#endif /* CONFIG_FILS */
+ struct hostapd_ubus_request req = {
+ .type = HOSTAPD_UBUS_ASSOC_REQ,
+ .mgmt_frame = mgmt,
-+ .frame_info = fi,
++ .ssi_signal = rssi,
+ };
if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
sizeof(mgmt->u.assoc_req))) {
-@@ -3472,6 +3490,14 @@ static void handle_assoc(struct hostapd_
+@@ -3887,6 +3904,14 @@ static void handle_assoc(struct hostapd_
}
#endif /* CONFIG_MBO */
@@ -176,7 +146,7 @@
/*
* sta->capability is used in check_assoc_ies() for RRM enabled
* capability element.
-@@ -3685,6 +3711,7 @@ static void handle_disassoc(struct hosta
+@@ -4114,6 +4139,7 @@ static void handle_disassoc(struct hosta
wpa_printf(MSG_DEBUG, "disassocation: STA=" MACSTR " reason_code=%d",
MAC2STR(mgmt->sa),
le_to_host16(mgmt->u.disassoc.reason_code));
@@ -184,7 +154,7 @@
sta = ap_get_sta(hapd, mgmt->sa);
if (sta == NULL) {
-@@ -3750,6 +3777,8 @@ static void handle_deauth(struct hostapd
+@@ -4179,6 +4205,8 @@ static void handle_deauth(struct hostapd
" reason_code=%d",
MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code));
@@ -193,69 +163,22 @@
sta = ap_get_sta(hapd, mgmt->sa);
if (sta == NULL) {
wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " trying "
-@@ -4089,7 +4118,7 @@ int ieee802_11_mgmt(struct hostapd_data
-
-
- if (stype == WLAN_FC_STYPE_PROBE_REQ) {
-- handle_probe_req(hapd, mgmt, len, ssi_signal);
-+ handle_probe_req(hapd, mgmt, len, fi);
- return 1;
- }
-
-@@ -4109,17 +4138,17 @@ int ieee802_11_mgmt(struct hostapd_data
- switch (stype) {
- case WLAN_FC_STYPE_AUTH:
- wpa_printf(MSG_DEBUG, "mgmt::auth");
-- handle_auth(hapd, mgmt, len);
-+ handle_auth(hapd, mgmt, len, fi);
- ret = 1;
- break;
- case WLAN_FC_STYPE_ASSOC_REQ:
- wpa_printf(MSG_DEBUG, "mgmt::assoc_req");
-- handle_assoc(hapd, mgmt, len, 0);
-+ handle_assoc(hapd, mgmt, len, 0, fi);
- ret = 1;
- break;
- case WLAN_FC_STYPE_REASSOC_REQ:
- wpa_printf(MSG_DEBUG, "mgmt::reassoc_req");
-- handle_assoc(hapd, mgmt, len, 1);
-+ handle_assoc(hapd, mgmt, len, 1, fi);
- ret = 1;
- break;
- case WLAN_FC_STYPE_DISASSOC:
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
-@@ -725,7 +725,7 @@ void sta_track_claim_taxonomy_info(struc
-
- void handle_probe_req(struct hostapd_data *hapd,
- const struct ieee80211_mgmt *mgmt, size_t len,
-- int ssi_signal)
-+ struct hostapd_frame_info *fi)
- {
- u8 *resp;
- struct ieee802_11_elems elems;
-@@ -734,6 +734,7 @@ void handle_probe_req(struct hostapd_dat
- size_t i, resp_len;
- int noack;
- enum ssid_match_result res;
-+ int ssi_signal = fi->ssi_signal;
- int ret;
- u16 csa_offs[2];
- size_t csa_offs_len;
-@@ -742,6 +743,12 @@ void handle_probe_req(struct hostapd_dat
+@@ -744,6 +744,12 @@ void handle_probe_req(struct hostapd_dat
struct hostapd_sta_wpa_psk_short *psk = NULL;
char *identity = NULL;
char *radius_cui = NULL;
+ struct hostapd_ubus_request req = {
+ .type = HOSTAPD_UBUS_PROBE_REQ,
+ .mgmt_frame = mgmt,
-+ .frame_info = fi,
++ .ssi_signal = ssi_signal,
+ .elems = &elems,
+ };
if (len < IEEE80211_HDRLEN)
return;
-@@ -919,6 +926,12 @@ void handle_probe_req(struct hostapd_dat
+@@ -921,6 +927,12 @@ void handle_probe_req(struct hostapd_dat
}
#endif /* CONFIG_P2P */
@@ -268,20 +191,9 @@
/* TODO: verify that supp_rates contains at least one matching rate
* with AP configuration */
---- a/src/ap/beacon.h
-+++ b/src/ap/beacon.h
-@@ -14,7 +14,7 @@ struct ieee80211_mgmt;
-
- void handle_probe_req(struct hostapd_data *hapd,
- const struct ieee80211_mgmt *mgmt, size_t len,
-- int ssi_signal);
-+ struct hostapd_frame_info *fi);
- int ieee802_11_set_beacon(struct hostapd_data *hapd);
- int ieee802_11_set_beacons(struct hostapd_iface *iface);
- int ieee802_11_update_beacons(struct hostapd_iface *iface);
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
-@@ -116,6 +116,10 @@ int hostapd_notif_assoc(struct hostapd_d
+@@ -118,6 +118,10 @@ int hostapd_notif_assoc(struct hostapd_d
u16 reason = WLAN_REASON_UNSPECIFIED;
u16 status = WLAN_STATUS_SUCCESS;
const u8 *p2p_dev_addr = NULL;
@@ -292,7 +204,7 @@
if (addr == NULL) {
/*
-@@ -208,6 +212,12 @@ int hostapd_notif_assoc(struct hostapd_d
+@@ -210,6 +214,12 @@ int hostapd_notif_assoc(struct hostapd_d
goto fail;
}
@@ -307,7 +219,7 @@
wpabuf_free(sta->p2p_ie);
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
-@@ -416,6 +416,7 @@ void ap_handle_timer(void *eloop_ctx, vo
+@@ -423,6 +423,7 @@ void ap_handle_timer(void *eloop_ctx, vo
HOSTAPD_LEVEL_INFO, "deauthenticated due to "
"local deauth request");
ap_free_sta(hapd, sta);
@@ -315,7 +227,7 @@
return;
}
-@@ -563,6 +564,7 @@ skip_poll:
+@@ -577,6 +578,7 @@ skip_poll:
hapd, sta,
WLAN_REASON_PREV_AUTH_NOT_VALID);
ap_free_sta(hapd, sta);
@@ -323,8 +235,8 @@
break;
}
}
-@@ -1224,6 +1226,7 @@ void ap_sta_set_authorized(struct hostap
- buf, ip_addr);
+@@ -1273,6 +1275,7 @@ void ap_sta_set_authorized(struct hostap
+ buf, ip_addr, keyid_buf);
} else {
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf);
+ hostapd_ubus_notify(hapd, "disassoc", sta->addr);
@@ -333,7 +245,7 @@
hapd->msg_ctx_parent != hapd->msg_ctx)
--- a/src/ap/wpa_auth_glue.c
+++ b/src/ap/wpa_auth_glue.c
-@@ -177,6 +177,7 @@ static void hostapd_wpa_auth_psk_failure
+@@ -181,6 +181,7 @@ static void hostapd_wpa_auth_psk_failure
struct hostapd_data *hapd = ctx;
wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POSSIBLE_PSK_MISMATCH MACSTR,
MAC2STR(addr));
@@ -343,7 +255,7 @@
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
-@@ -189,6 +189,12 @@ ifdef CONFIG_EAPOL_TEST
+@@ -188,6 +188,12 @@ ifdef CONFIG_EAPOL_TEST
CFLAGS += -Werror -DEAPOL_TEST
endif
@@ -356,7 +268,7 @@
ifdef CONFIG_CODE_COVERAGE
CFLAGS += -O0 -fprofile-arcs -ftest-coverage
LIBS += -lgcov
-@@ -915,6 +921,9 @@ endif
+@@ -923,6 +929,9 @@ endif
ifdef CONFIG_IEEE80211AX
OBJS += ../src/ap/ieee802_11_he.o
endif
@@ -368,7 +280,7 @@
CFLAGS += -DCONFIG_WNM_AP
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
-@@ -6080,6 +6080,8 @@ struct wpa_supplicant * wpa_supplicant_a
+@@ -6288,6 +6288,8 @@ struct wpa_supplicant * wpa_supplicant_a
}
#endif /* CONFIG_P2P */
@@ -377,7 +289,7 @@
return wpa_s;
}
-@@ -6106,6 +6108,8 @@ int wpa_supplicant_remove_iface(struct w
+@@ -6314,6 +6316,8 @@ int wpa_supplicant_remove_iface(struct w
struct wpa_supplicant *parent = wpa_s->parent;
#endif /* CONFIG_MESH */
@@ -396,7 +308,7 @@
extern const char *const wpa_supplicant_version;
extern const char *const wpa_supplicant_license;
-@@ -500,6 +501,7 @@ struct wpa_supplicant {
+@@ -506,6 +507,7 @@ struct wpa_supplicant {
unsigned char own_addr[ETH_ALEN];
unsigned char perm_addr[ETH_ALEN];
char ifname[100];
@@ -546,7 +546,7 @@ __hostapd_bss_mgmt_enable_f(struct hostapd_data *hapd, int flag)
bss->radio_measurements[0] |=
WLAN_RRM_CAPS_NEIGHBOR_REPORT;
- hostapd_set_own_neighbor_report(hapd);
+ hostapd_neighbor_set_own_report(hapd);
return true;
case BSS_MGMT_EN_BEACON:
flags = WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE |
@@ -1065,8 +1065,8 @@ int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_req
blobmsg_add_macaddr(&b, "address", addr);
if (req->mgmt_frame)
blobmsg_add_macaddr(&b, "target", req->mgmt_frame->da);
- if (req->frame_info)
- blobmsg_add_u32(&b, "signal", req->frame_info->ssi_signal);
+ if (req->ssi_signal)
+ blobmsg_add_u32(&b, "signal", req->ssi_signal);
blobmsg_add_u32(&b, "freq", hapd->iface->freq);
if (req->elems) {
@@ -19,7 +19,7 @@ struct hostapd_ubus_request {
enum hostapd_ubus_event_type type;
const struct ieee80211_mgmt *mgmt_frame;
const struct ieee802_11_elems *elems;
- const struct hostapd_frame_info *frame_info;
+ int ssi_signal; /* dBm */
const u8 *addr;
};