[wpa_supplicant] cumilative patch from commit bb945b98f
Bug: 275651698
Test: Connect to open, WPA2, WPA3 and passpoint network
Test: Establish P2P connection
Test: Basic SoftAp tests
Test: Regression test (b/275948027)
BYPASS_INCLUSIVE_LANGUAGE_REASON=Merged from opne source
bb945b98f Add 40 and 80 MHz channels 165 and 173 for 5 GHz IBSS/mesh
0059fa5ba 6 GHz: Fix secondary channel setting
744295c8b Add 6 GHz channel validation during channel switching
5349a45d3 Set interface state as inactive if mesh bringup fails
a4af79624 Handle signal termination in hostapd_cli for all cases
cf8f13ac8 Add support to send 320 MHz bandwidth through vendor subcmd
a0403c023 EHT: Validate the puncturing bitmap for ACS
af0f60e7d EHT: Calculate puncturing bitmap for ACS
f3206fbe9 EHT: Configuration option for ACS puncturing threshold
e3621867c EHT: Process puncturing bitmap from channel switch event
e277e577c nl80211: Send EHT puncturing bitmap to the driver for switch command
29a882bed EHT: Configure puncturing bitmap during channel switch
4942b19ff EHT: Send puncturing bitmap to the driver for AP bring up
f9fc2eabb EHT: Add puncturing bitmap to EHT Operation element
46a5d989d EHT: Downgrade bandwidths for VHT and HE when using puncturing
7618269ec EHT: Validate puncturing bitmap
9102fda31 EHT: Add configuration option for puncturing in AP mode
9e79439fc nl80211: Retrieve driver support for EHT puncturing
507be376c Sync with wireless-next.git include/uapi/linux/nl80211.h
591256a8c FILS: 320 MHz support in FD frame
903e3a1e6 FILS: Fix maximum NSS calculation for FD frame
ecae45ff6 FILS: Make HE a requirement for FILS discovery
4e86692ff AP: Fix 6 GHz AP setup after disable-enable
a34b8477a ml80211: Put wiphy idx to obtain correct country code
1491fc64a Define QCA vendor per-enum 64-bit pad attributes
55e31699e qca-vendor: Add QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NF_CAL_VAL
b1f85957c Add QCA vendor commands to set and get MLO links state information
44b32a752 mesh: Add EHT support
c4cb62ca8 WPA_AUTH: MLO: Add functions to get the AA and SPA
cab963e9f AP: Split check_assoc_ies()
7a7a2256c common: Support parsing link specific association request
b39e35693 common: Add support for clearing elements
0b2fc4268 common: Split ieee8021_parse_elems()
df6561ec0 nl80211: AP MLD support for adding multi link stations
b8b4ceb8d nl80211: Properly stop and deinit MLO AP
2f8fc46ed nl80211: Provide link_id in EAPOL_RX and RX_MGMT events
821374d43 nl80211: Introduce and implement a callback to add an MLO link for AP MLD
47269be36 nl80211: Refactor i802_bss to support multiple links
eb146ee80 AP: Add some bridge port attribute settings
f628e6b30 nl80211: Make sure scan frequency debug buffer is NUL terminated
41d23254b nl80211: Fix frequencies array boundary check for scanned frequencies
a9012070a Android: Add wowlan_disconnect_on_deinit to template configuration
e2ea0fd70 EST: Write the RSA private key using the standard PRIVATE KEY format
bfd236df2 webkit2: Avoid deprecated function call
2c3202682 P2P: Filter out 6 GHz frequencies if not allowed for P2P connection
b2bf7e39e Update PMK in wpa_sm when roam+auth event indicated with authorized flag
6b9c86466 nl80211: Replace the channel flags for VHT support
6f63aca7b DPP: Allow both STA and AP configObject to be set
7292e30b7 DPP: Fix @CONF-OBJ-SEP@ parsing for multiple configs
c31600ce1 P2P: Allow GO BSSID to be specified for P2P_GROUP_ADD commands
0430756e6 P2P: Optimize join scan frequency
b3921db42 nl80211: Add frequency info in start AP command
40c139664 macsec_linux: Add support for MACsec hardware offload
6d24673ab mka: Allow configuration of MACsec hardware offload
3081a9cb6 hostapd: Output country_code and country3 when using STATUS
91ad7a309 FT: Store PTKSA entry for the correct BSSID in the FT protocol case
3f3e356fa Mark addr argument to storing PTKSA const
242c3ad99 FT: Store PTKSA from FT protocol
ba6954874 Mark wpa_auth_remove_ptksa() static
3b1ad1334 FT: Include KDK in FT specific PTK derivation on the AP
870a5bdc0 nl80211: Report guard interval and dual carrier modulation
edcad193a dbus: Add inactive time to D-Bus signal info
a678a510f dbus: Add D-Bus signal for PSK mismatch heuristics
691f729d5 P2P: Make invitation flow less aggressive
f4a7e2a07 Rework IBSS/mesh 80 MHz channel selection
f91f971bd Fix creating 6 GHz IBSS/mesh on 5/6 GHz-capable PHYs
c623cee42 Make arrays static const in ibss_mesh_select_*()
64043e615 Split ibss_mesh_setup_freq() into multiple functions
8085a7e65 wpa_supplicant: Add option to explicitly set 4addr mode
1ffc7d1c6 Apply bias towards 6 GHz in roaming
faa410292 WNM: Event report handling for BSS color collision and in-use
97405be96 Small textual improvements to wpa_supplicant man page
ec02a0e93 hostapd: Output hw_mode when using STATUS
390e24c6c EAP-TTLS server: Add Ident field to MS-CHAP-Error
4ae798a22 P2P: Pick the best driver pref freq for invitation process
6c75f1dfa Send broadcast Probe Response frames on the 6 GHz band
edfcb2f1a MLD STA: Indicate MLO support in NL80211_CMD_CONNECT
c91852044 MLD STA: Add support for SAE external authentication offload to userspace
575712450 qca-vendor: Add QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_LOW_LATENCY
ba150059d FT: Store PMK-R0/PMK-R1 after EAPOL-Key msg 2/4 MIC validation
56662f36d Refine vendor subcmd QCA_NL80211_VENDOR_SUBCMD_ROAM_STATS
72b8193f4 MACsec: Remove EAP Session-Id length constraint
3915e8834 hostapd: Report error on unknown ACCEPT_ACL/DENY_ACL commands
2cff340d1 utils: Move log2pcap to python3
12de8112b Fix BSS age underflow
d31c2b43a Fix segfault in case of an invalid configuration
a32b424a3 MLD STA: Use AP MLD address in PMKSA cache attempts for driver-SME case
8c4790cef MLD STA: Store PMKSA with AP MLD address for MLO connection event
bf124a03d SAE: Update PT value at later point for SME cases, if needed
1aadcca0a P2P: Enable SAE-H2E for client when joining a 6 GHz group
37f8257c4 SAE: Extend automatic enabling of H2E on 6 GHz to additional cases
89377c6b9 OCV: Fix build without CONFIG_OCV=y
2e47ea22c P2P: Fix handling Service Discovery Response received by GO device
dc7e330e0 Set OCV capability based on Association Request frame RSNE
831be6514 WPS: Do not indicate incorrect PBC overlap based on partner link
c9fc12425 P2P: Make wpas_p2p_notif_pbc_overlap() static
Change-Id: I1eb61fc82b98b937a2ff37a30e60e28129fe143d
Merged-In: I1eb61fc82b98b937a2ff37a30e60e28129fe143d
diff --git a/wpa_supplicant/aidl/p2p_iface.cpp b/wpa_supplicant/aidl/p2p_iface.cpp
index 2afd75b..5122cea 100644
--- a/wpa_supplicant/aidl/p2p_iface.cpp
+++ b/wpa_supplicant/aidl/p2p_iface.cpp
@@ -122,11 +122,6 @@
wpa_network->disabled = 2;
// set necessary fields
- if (!isAnyEtherAddr(group_owner_bssid)) {
- os_memcpy(wpa_network->bssid, group_owner_bssid, ETH_ALEN);
- wpa_network->bssid_set = 1;
- }
-
wpa_network->ssid = (uint8_t *)os_malloc(ssid.size());
if (wpa_network->ssid == NULL) {
wpa_config_remove_network(wpa_s->conf, wpa_network->id);
@@ -194,7 +189,8 @@
if (wpas_p2p_group_add_persistent(
wpa_s, wpa_network, 0, 0, freq, 0, ht40, vht,
- CONF_OPER_CHWIDTH_USE_HT, he, 0, NULL, 0, 0, is6GhzAllowed(wpa_s), P2P_JOIN_LIMIT, true)) {
+ CONF_OPER_CHWIDTH_USE_HT, he, 0, NULL, 0, 0, is6GhzAllowed(wpa_s),
+ P2P_JOIN_LIMIT, isAnyEtherAddr(group_owner_bssid) ? NULL : group_owner_bssid)) {
ret = -1;
}
@@ -1618,7 +1614,8 @@
} else if (ssid->disabled == 2) {
if (wpas_p2p_group_add_persistent(
wpa_s, ssid, 0, 0, 0, 0, ht40, vht,
- CONF_OPER_CHWIDTH_USE_HT, he, edmg, NULL, 0, 0, is6GhzAllowed(wpa_s), 0, false)) {
+ CONF_OPER_CHWIDTH_USE_HT, he, edmg, NULL, 0, 0,
+ is6GhzAllowed(wpa_s), 0, NULL)) {
return createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN);
} else {
return ndk::ScopedAStatus::ok();
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index f4c3811..9a2598b 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -326,6 +326,16 @@
if (mode && is_6ghz_freq(ssid->frequency) &&
conf->hw_mode == HOSTAPD_MODE_IEEE80211A) {
+ if (mode->eht_capab[wpas_mode_to_ieee80211_mode(
+ ssid->mode)].eht_supported &&
+ ssid->eht)
+ conf->ieee80211be = 1;
+
+ if (mode->he_capab[wpas_mode_to_ieee80211_mode(
+ ssid->mode)].he_supported &&
+ ssid->he)
+ conf->ieee80211ax = 1;
+
#ifdef CONFIG_P2P
wpas_conf_ap_he_6ghz(wpa_s, mode, ssid, conf);
#endif /* CONFIG_P2P */
@@ -400,6 +410,11 @@
/* check this before VHT, because setting oper chan
* width and friends is the same call for HE and VHT
* and checks if conf->ieee8021ax == 1 */
+ if (mode->eht_capab[wpas_mode_to_ieee80211_mode(
+ ssid->mode)].eht_supported &&
+ ssid->eht)
+ conf->ieee80211be = 1;
+
if (mode->he_capab[wpas_mode_to_ieee80211_mode(
ssid->mode)].he_supported &&
ssid->he)
@@ -1826,7 +1841,8 @@
void wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht,
- int offset, int width, int cf1, int cf2, int finished)
+ int offset, int width, int cf1, int cf2,
+ u16 punct_bitmap, int finished)
{
struct hostapd_iface *iface = wpa_s->ap_iface;
@@ -1838,7 +1854,8 @@
if (wpa_s->current_ssid)
wpa_s->current_ssid->frequency = freq;
hostapd_event_ch_switch(iface->bss[0], freq, ht,
- offset, width, cf1, cf2, finished);
+ offset, width, cf1, cf2, punct_bitmap,
+ finished);
}
diff --git a/wpa_supplicant/ap.h b/wpa_supplicant/ap.h
index 865429e..5835ecd 100644
--- a/wpa_supplicant/ap.h
+++ b/wpa_supplicant/ap.h
@@ -73,7 +73,8 @@
struct csa_settings *settings);
int ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *txtaddr);
void wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht,
- int offset, int width, int cf1, int cf2, int finished);
+ int offset, int width, int cf1, int cf2,
+ u16 punct_bitmap, int finished);
struct wpabuf * wpas_ap_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
int ndef);
#ifdef CONFIG_AP
diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
index 0f986bb..3204414 100644
--- a/wpa_supplicant/bss.c
+++ b/wpa_supplicant/bss.c
@@ -249,11 +249,11 @@
const u8 *ssid, size_t ssid_len)
{
struct wpa_bss *bss;
- if (!wpa_supplicant_filter_bssid_match(wpa_s, bssid))
+
+ if (bssid && !wpa_supplicant_filter_bssid_match(wpa_s, bssid))
return NULL;
dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
- if ((!bssid ||
- os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0) &&
+ if ((!bssid || os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0) &&
bss->ssid_len == ssid_len &&
os_memcmp(bss->ssid, ssid, ssid_len) == 0)
return bss;
@@ -987,6 +987,10 @@
return;
os_get_reltime(&t);
+
+ if (t.sec < age)
+ return; /* avoid underflow; there can be no older entries */
+
t.sec -= age;
dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) {
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index f3e2edb..18abd53 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2678,6 +2678,7 @@
{ INT_RANGE(macsec_integ_only, 0, 1) },
{ INT_RANGE(macsec_replay_protect, 0, 1) },
{ INT(macsec_replay_window) },
+ { INT_RANGE(macsec_offload, 0, 2) },
{ INT_RANGE(macsec_port, 1, 65534) },
{ INT_RANGE(mka_priority, 0, 255) },
{ INT_RANGE(macsec_csindex, 0, 1) },
@@ -2711,6 +2712,7 @@
{ INT_RANGE(transition_disable, 0, 255) },
{ INT_RANGE(sae_pk, 0, 2) },
{ INT_RANGE(disable_eht, 0, 1)},
+ { INT_RANGE(enable_4addr_mode, 0, 1)},
};
#undef OFFSET
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 1b8526b..c7b7826 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -339,13 +339,13 @@
while (wpa_config_get_line(buf, sizeof(buf), f, &line, &pos)) {
if (os_strcmp(pos, "network={") == 0) {
ssid = wpa_config_read_network(f, &line, id++);
- ssid->ro = ro;
if (ssid == NULL) {
wpa_printf(MSG_ERROR, "Line %d: failed to "
"parse network block.", line);
errors++;
continue;
}
+ ssid->ro = ro;
if (head == NULL) {
head = tail = ssid;
} else {
@@ -814,6 +814,7 @@
INT(macsec_integ_only);
INT(macsec_replay_protect);
INT(macsec_replay_window);
+ INT(macsec_offload);
INT(macsec_port);
INT_DEF(mka_priority, DEFAULT_PRIO_NOT_KEY_SERVER);
INT(macsec_csindex);
@@ -890,6 +891,7 @@
INT(disable_he);
#endif /* CONFIG_HE_OVERRIDES */
INT(disable_eht);
+ INT(enable_4addr_mode);
#undef STR
#undef INT
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index 33b46e5..785acc3 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -583,6 +583,8 @@
int he;
+ int eht;
+
enum oper_chan_width max_oper_chwidth;
unsigned int vht_center_freq1;
@@ -926,6 +928,18 @@
u32 macsec_replay_window;
/**
+ * macsec_offload - Enable MACsec hardware offload
+ *
+ * This setting applies only when MACsec is in use, i.e.,
+ * - the key server has decided to enable MACsec
+ *
+ * 0 = MACSEC_OFFLOAD_OFF (default)
+ * 1 = MACSEC_OFFLOAD_PHY
+ * 2 = MACSEC_OFFLOAD_MAC
+ */
+ int macsec_offload;
+
+ /**
* macsec_port - MACsec port (in SCI)
*
* Port component of the SCI.
@@ -1239,6 +1253,17 @@
* to 1 to have it disabled.
*/
int disable_eht;
+
+ /**
+ * enable_4addr_mode - Set 4addr mode after association
+ * 0 = Do not attempt to set 4addr mode
+ * 1 = Try to set 4addr mode after association
+ *
+ * Linux requires that an interface is set to 4addr mode before it can
+ * be added to a bridge. Set this to 1 for networks where you intent
+ * to use the interface in a bridge.
+ */
+ int enable_4addr_mode;
};
#endif /* CONFIG_SSID_H */
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 27397e9..9abfeb2 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -7113,7 +7113,8 @@
static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
int id, int freq, int vht_center_freq2,
int ht40, int vht, int vht_chwidth,
- int he, int edmg, bool allow_6ghz)
+ int he, int edmg, bool allow_6ghz,
+ const u8 *go_bssid)
{
struct wpa_ssid *ssid;
@@ -7128,7 +7129,8 @@
return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq,
vht_center_freq2, 0, ht40, vht,
vht_chwidth, he, edmg,
- NULL, 0, 0, allow_6ghz, 0, false);
+ NULL, 0, 0, allow_6ghz, 0,
+ go_bssid);
}
@@ -7142,6 +7144,7 @@
int edmg = wpa_s->conf->p2p_go_edmg;
int max_oper_chwidth, chwidth = 0, freq2 = 0;
char *token, *context = NULL;
+ u8 go_bssid_buf[ETH_ALEN], *go_bssid = NULL;
#ifdef CONFIG_ACS
int acs = 0;
#endif /* CONFIG_ACS */
@@ -7170,6 +7173,10 @@
persistent = 1;
} else if (os_strcmp(token, "allow_6ghz") == 0) {
allow_6ghz = true;
+ } else if (os_strncmp(token, "go_bssid=", 9) == 0) {
+ if (hwaddr_aton(token + 9, go_bssid_buf))
+ return -1;
+ go_bssid = go_bssid_buf;
} else {
wpa_printf(MSG_DEBUG,
"CTRL: Invalid P2P_GROUP_ADD parameter: '%s'",
@@ -7213,7 +7220,8 @@
return p2p_ctrl_group_add_persistent(wpa_s, group_id,
freq, freq2, ht40, vht,
max_oper_chwidth, he,
- edmg, allow_6ghz);
+ edmg, allow_6ghz,
+ go_bssid);
return wpas_p2p_group_add(wpa_s, persistent, freq, freq2, ht40, vht,
max_oper_chwidth, he, edmg, allow_6ghz);
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index 9c23588..8fc29b3 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -1102,6 +1102,29 @@
}
+void wpas_dbus_signal_psk_mismatch(struct wpa_supplicant *wpa_s)
+{
+ struct wpas_dbus_priv *iface;
+ DBusMessage *msg;
+
+ iface = wpa_s->global->dbus;
+
+ /* Do nothing if the control interface is not turned on */
+ if (!iface || !wpa_s->dbus_new_path)
+ return;
+
+ msg = dbus_message_new_signal(wpa_s->dbus_new_path,
+ WPAS_DBUS_NEW_IFACE_INTERFACE,
+ "PskMismatch");
+ if (!msg)
+ return;
+
+ dbus_connection_send(iface->con, msg, NULL);
+
+ dbus_message_unref(msg);
+}
+
+
/**
* wpas_dbus_signal_sta - Send a station related event signal
* @wpa_s: %wpa_supplicant network interface data
diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h
index ca8506f..5c5d855 100644
--- a/wpa_supplicant/dbus/dbus_new.h
+++ b/wpa_supplicant/dbus/dbus_new.h
@@ -254,6 +254,7 @@
const u8 *ie, size_t ie_len, u32 ssi_signal);
void wpas_dbus_signal_eap_status(struct wpa_supplicant *wpa_s,
const char *status, const char *parameter);
+void wpas_dbus_signal_psk_mismatch(struct wpa_supplicant *wpa_s);
void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
const u8 *sta);
void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s,
@@ -585,6 +586,10 @@
{
}
+static inline void wpas_dbus_signal_psk_mismatch(struct wpa_supplicant *wpa_s)
+{
+}
+
static inline
void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
const u8 *sta)
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
index 9d1728c..a178d87 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
@@ -356,10 +356,10 @@
int persistent_group = 0;
int freq = 0;
int retry_limit = 0;
- int force_go_bssid = 0;
char *iface = NULL;
unsigned int group_id = 0;
struct wpa_ssid *ssid;
+ u8 go_bssid_buf[ETH_ALEN], *go_bssid = NULL;
dbus_message_iter_init(message, &iter);
@@ -383,15 +383,18 @@
retry_limit = entry.int32_value;
if (retry_limit <= 0)
goto inv_args_clear;
- } else if (os_strcmp(entry.key, "force_go_bssid") == 0 &&
- entry.type == DBUS_TYPE_BOOLEAN) {
- force_go_bssid = entry.bool_value;
} else if (os_strcmp(entry.key, "persistent_group_object") ==
0 &&
- entry.type == DBUS_TYPE_OBJECT_PATH)
+ entry.type == DBUS_TYPE_OBJECT_PATH) {
pg_object_path = os_strdup(entry.str_value);
- else
+ } else if (os_strcmp(entry.key, "go_bssid") == 0 &&
+ entry.type == DBUS_TYPE_STRING) {
+ if (hwaddr_aton(entry.str_value, go_bssid_buf))
+ goto inv_args_clear;
+ go_bssid = go_bssid_buf;
+ } else {
goto inv_args_clear;
+ }
wpa_dbus_dict_entry_clear(&entry);
}
@@ -437,7 +440,7 @@
if (wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0, 0, 0,
0, 0, 0, 0, NULL, 0, 0,
false, retry_limit,
- force_go_bssid)) {
+ go_bssid)) {
reply = wpas_dbus_error_unknown_error(
message,
"Failed to reinvoke a persistent group");
diff --git a/wpa_supplicant/dbus/dbus_new_helpers.c b/wpa_supplicant/dbus/dbus_new_helpers.c
index e21f912..06f74ad 100644
--- a/wpa_supplicant/dbus/dbus_new_helpers.c
+++ b/wpa_supplicant/dbus/dbus_new_helpers.c
@@ -1086,6 +1086,9 @@
(si->data.current_rx_rate &&
!wpa_dbus_dict_append_uint32(&iter_dict, "linktxspeed",
si->data.current_tx_rate)) ||
+ (si->data.inactive_msec &&
+ !wpa_dbus_dict_append_uint32(&iter_dict, "inactive-time",
+ si->data.inactive_msec)) ||
(si->data.tx_retry_failed &&
!wpa_dbus_dict_append_uint32(&iter_dict, "retries-failed",
si->data.tx_retry_failed)) ||
diff --git a/wpa_supplicant/doc/docbook/wpa_supplicant.sgml b/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
index 9a7d601..898765c 100644
--- a/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
+++ b/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
@@ -2,7 +2,7 @@
<refentry>
<refentryinfo>
- <date>13 September 2022</date>
+ <date>1 February 2023</date>
</refentryinfo>
<refmeta>
@@ -30,7 +30,7 @@
<para>
Wireless networks do not require physical access to the network equipment
- in the same way as wired networks. This makes it easier for unauthorized
+ in the same way that wired networks do. This makes it easier for unauthorized
users to passively monitor a network and capture all transmitted frames.
In addition, unauthorized use of the network is much easier. In many cases,
this can happen even without user's explicit knowledge since the wireless
@@ -42,14 +42,14 @@
Link-layer encryption can be used to provide a layer of security for
wireless networks. The original wireless LAN standard, IEEE 802.11,
included a simple encryption mechanism, WEP. However, that proved to
- be flawed in many areas and network protected with WEP cannot be consider
+ be flawed in many areas and networks protected with WEP cannot be considered
secure. IEEE 802.1X authentication and frequently changed dynamic WEP keys
can be used to improve the network security, but even that has inherited
security issues due to the use of WEP for encryption. Wi-Fi Protected
- Access and IEEE 802.11i amendment to the wireless LAN standard introduce
+ Access and the IEEE 802.11i amendment to the wireless LAN standard introduce
a much improved mechanism for securing wireless networks. IEEE 802.11i
- enabled networks that are using CCMP (encryption mechanism based on strong
- cryptographic algorithm AES) can finally be called secure used for
+ enabled networks that are using CCMP (an encryption mechanism based on the strong
+ cryptographic algorithm AES) can finally be called secure and used for
applications which require efficient protection against unauthorized
access.
</para>
@@ -70,13 +70,13 @@
wpa_supplicant.</para>
<para>Before wpa_supplicant can do its work, the network interface
- must be available. That means that the physical device must be
+ must be available. That means that the physical device must be
present and enabled, and the driver for the device must be
loaded. The daemon will exit immediately if the device is not already
available.</para>
<para>After <command>wpa_supplicant</command> has configured the
- network device, higher level configuration such as DHCP may
+ network device, higher level configuration of the device, such as DHCP, may
proceed. There are a variety of ways to integrate wpa_supplicant
into a machine's networking scripts, a few of which are described
in sections below.</para>
@@ -87,7 +87,7 @@
<itemizedlist>
<listitem>
<para><command>wpa_supplicant</command> requests the kernel
- driver to scan neighboring BSSes</para>
+ driver to scan neighboring BSSes (Basic Service Set)</para>
</listitem>
<listitem>
@@ -520,10 +520,10 @@
wpa_supplicant -B -c/etc/wpa_supplicant.conf -iwlan0
</programlisting></blockquote>
- <para>This makes the process fork into background.</para>
+ <para>This makes the process fork into the background.</para>
- <para>The easiest way to debug problems, and to get debug log for
- bug reports, is to start <command>wpa_supplicant</command> on
+ <para>The easiest way to debug problems, and to get a debug log for
+ bug reports, is to start <command>wpa_supplicant</command> in the
foreground with debugging enabled:</para>
<blockquote><programlisting>
@@ -707,7 +707,7 @@
<refsect1>
<title>Interface to pcmcia-cs/cardmrg</title>
- <para>For example, following small changes to pcmcia-cs scripts
+ <para>For example, the following small changes to pcmcia-cs scripts
can be used to enable WPA support:</para>
<para>Add MODE="Managed" and WPA="y" to the network scheme in
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index 5dd2a51..d707cf5 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -350,8 +350,11 @@
static inline int wpa_drv_sta_add(struct wpa_supplicant *wpa_s,
struct hostapd_sta_add_params *params)
{
- if (wpa_s->driver->sta_add)
+ if (wpa_s->driver->sta_add) {
+ /* Set link_id to -1 as it's needed for AP only */
+ params->mld_link_id = -1;
return wpa_s->driver->sta_add(wpa_s->drv_priv, params);
+ }
return -1;
}
@@ -803,6 +806,14 @@
window);
}
+static inline int wpa_drv_set_offload(struct wpa_supplicant *wpa_s, u8 offload)
+{
+ if (!wpa_s->driver->set_offload)
+ return -1;
+ return wpa_s->driver->set_offload(wpa_s->drv_priv, offload);
+
+}
+
static inline int wpa_drv_set_current_cipher_suite(struct wpa_supplicant *wpa_s,
u64 cs)
{
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 3275b64..253f87d 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -394,7 +394,7 @@
}
-static void wpa_find_assoc_pmkid(struct wpa_supplicant *wpa_s)
+static void wpa_find_assoc_pmkid(struct wpa_supplicant *wpa_s, bool authorized)
{
struct wpa_ie_data ie;
int pmksa_set = -1;
@@ -418,6 +418,8 @@
NULL, NULL, 0, NULL, 0);
if (pmksa_set == 0) {
eapol_sm_notify_pmkid_attempt(wpa_s->eapol);
+ if (authorized)
+ wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
break;
}
}
@@ -982,6 +984,7 @@
if (wpa_s->conf->sae_pwe ==
SAE_PWE_HUNT_AND_PECK &&
!ssid->sae_password_id &&
+ !is_6ghz_freq(bss->freq) &&
wpa_key_mgmt_sae(ssid->key_mgmt)) {
if (debug_print)
wpa_dbg(wpa_s, MSG_DEBUG,
@@ -1825,7 +1828,8 @@
struct wpa_bss *selected,
struct wpa_ssid *ssid)
{
- if (wpas_wps_partner_link_overlap_detect(wpa_s) ||
+ if ((eap_is_wps_pbc_enrollee(&ssid->eap) &&
+ wpas_wps_partner_link_overlap_detect(wpa_s)) ||
wpas_wps_scan_pbc_overlap(wpa_s, selected, ssid)) {
wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OVERLAP
"PBC session overlap");
@@ -1973,7 +1977,7 @@
struct wpa_bss *selected)
{
int min_diff, diff;
- int to_5ghz;
+ int to_5ghz, to_6ghz;
int cur_level;
unsigned int cur_est, sel_est;
struct wpa_signal_info si;
@@ -2040,8 +2044,11 @@
}
to_5ghz = selected->freq > 4000 && current_bss->freq < 4000;
+ to_6ghz = is_6ghz_freq(selected->freq) &&
+ !is_6ghz_freq(current_bss->freq);
- if (cur_level < 0 && cur_level > selected->level + to_5ghz * 2 &&
+ if (cur_level < 0 &&
+ cur_level > selected->level + to_5ghz * 2 + to_6ghz * 2 &&
sel_est < cur_est * 1.2) {
wpa_dbg(wpa_s, MSG_DEBUG, "Skip roam - Current BSS has better "
"signal level");
@@ -2093,6 +2100,8 @@
if (to_5ghz)
min_diff -= 2;
+ if (to_6ghz)
+ min_diff -= 2;
diff = selected->level - cur_level;
if (diff < min_diff) {
wpa_dbg(wpa_s, MSG_DEBUG,
@@ -2703,6 +2712,26 @@
#endif /* CONFIG_INTERWORKING */
+static void wpa_supplicant_set_4addr_mode(struct wpa_supplicant *wpa_s)
+{
+ if (wpa_s->enabled_4addr_mode) {
+ wpa_printf(MSG_DEBUG, "4addr mode already set");
+ return;
+ }
+
+ if (wpa_drv_set_4addr_mode(wpa_s, 1) < 0) {
+ wpa_msg(wpa_s, MSG_ERROR, "Failed to set 4addr mode");
+ goto fail;
+ }
+ wpa_s->enabled_4addr_mode = 1;
+ wpa_msg(wpa_s, MSG_INFO, "Successfully set 4addr mode");
+ return;
+
+fail:
+ wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
+}
+
+
static void multi_ap_process_assoc_resp(struct wpa_supplicant *wpa_s,
const u8 *ies, size_t ies_len)
{
@@ -2755,11 +2784,7 @@
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;
+ wpa_supplicant_set_4addr_mode(wpa_s);
return;
fail:
@@ -2848,8 +2873,10 @@
p += len;
}
- if (!found || wpa_parse_wpa_ie(p, len, &ie) < 0)
+ if (!found || wpa_parse_wpa_ie(p, len, &ie) < 0) {
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_OCV, 0);
return 0;
+ }
wpa_hexdump(MSG_DEBUG,
"WPA: Update cipher suite selection based on IEs in driver-generated WPA/RSNE in AssocReq",
@@ -2876,6 +2903,13 @@
return -1;
}
+#ifdef CONFIG_OCV
+ if (((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) ||
+ (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_OCV)) && ssid->ocv)
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_OCV,
+ !!(ie.capabilities & WPA_CAPABILITY_OCVC));
+#endif /* CONFIG_OCV */
+
/*
* Update PMK in wpa_sm and the driver if roamed to WPA/WPA2 PSK from a
* different AKM.
@@ -3154,7 +3188,8 @@
if (wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, p, len))
break;
found = 1;
- wpa_find_assoc_pmkid(wpa_s);
+ wpa_find_assoc_pmkid(wpa_s,
+ data->assoc_info.authorized);
}
if (!found_x && p[0] == WLAN_EID_RSNX) {
if (wpa_sm_set_assoc_rsnxe(wpa_s->wpa, p, len))
@@ -3237,7 +3272,9 @@
#ifdef CONFIG_OWE
if (wpa_s->key_mgmt == WPA_KEY_MGMT_OWE &&
(!bssid_known ||
- owe_process_assoc_resp(wpa_s->wpa, bssid,
+ owe_process_assoc_resp(wpa_s->wpa,
+ wpa_s->valid_links ?
+ wpa_s->ap_mld_addr : bssid,
data->assoc_info.resp_ies,
data->assoc_info.resp_ies_len) < 0)) {
wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_UNSPECIFIED);
@@ -3977,6 +4014,9 @@
#ifdef CONFIG_DPP2
wpa_s->dpp_pfs_fallback = 0;
#endif /* CONFIG_DPP2 */
+
+ if (wpa_s->current_ssid && wpa_s->current_ssid->enable_4addr_mode)
+ wpa_supplicant_set_4addr_mode(wpa_s);
}
@@ -4086,6 +4126,7 @@
if (wpas_p2p_4way_hs_failed(wpa_s) > 0)
return; /* P2P group removed */
wpas_auth_failed(wpa_s, "WRONG_KEY", prev_pending_bssid);
+ wpas_notify_psk_mismatch(wpa_s);
#ifdef CONFIG_DPP2
wpas_dpp_send_conn_status_result(wpa_s,
DPP_STATUS_AUTH_FAILURE);
@@ -5095,7 +5136,10 @@
data->assoc_info.fils_pmk,
data->assoc_info.fils_pmk_len,
data->assoc_info.fils_pmkid,
- wpa_s->bssid, fils_cache_id);
+ wpa_s->valid_links ?
+ wpa_s->ap_mld_addr :
+ wpa_s->bssid,
+ fils_cache_id);
} else if (data->assoc_info.fils_pmkid) {
/* Update the current PMKSA used for this connection */
pmksa_cache_set_current(wpa_s->wpa,
@@ -5729,6 +5773,7 @@
data->ch_switch.ch_width,
data->ch_switch.cf1,
data->ch_switch.cf2,
+ data->ch_switch.punct_bitmap,
1);
}
#endif /* CONFIG_AP */
diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c
index 16530fb..486fc6a 100644
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
@@ -225,7 +225,7 @@
ifmsh->conf->ieee80211n,
ifmsh->conf->ieee80211ac,
ifmsh->conf->ieee80211ax,
- false,
+ ifmsh->conf->ieee80211be,
ifmsh->conf->secondary_channel,
hostapd_get_oper_chwidth(ifmsh->conf),
hostapd_get_oper_centr_freq_seg0_idx(ifmsh->conf),
@@ -634,6 +634,7 @@
wpa_s->mesh_ht_enabled = !!params->freq.ht_enabled;
wpa_s->mesh_vht_enabled = !!params->freq.vht_enabled;
wpa_s->mesh_he_enabled = !!params->freq.he_enabled;
+ wpa_s->mesh_eht_enabled = !!params->freq.eht_enabled;
if (params->freq.ht_enabled && params->freq.sec_channel_offset)
ssid->ht40 = params->freq.sec_channel_offset;
@@ -662,6 +663,8 @@
}
if (wpa_s->mesh_he_enabled)
ssid->he = 1;
+ if (wpa_s->mesh_eht_enabled)
+ ssid->eht = 1;
if (ssid->beacon_int > 0)
params->beacon_int = ssid->beacon_int;
else if (wpa_s->conf->beacon_int > 0)
diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
index c1ed8c4..da6d9db 100644
--- a/wpa_supplicant/mesh_mpm.c
+++ b/wpa_supplicant/mesh_mpm.c
@@ -263,6 +263,13 @@
if (type != PLINK_CLOSE && conf->ocv)
buf_len += OCV_OCI_EXTENDED_LEN;
#endif /* CONFIG_OCV */
+#ifdef CONFIG_IEEE80211BE
+ if (type != PLINK_CLOSE && wpa_s->mesh_eht_enabled) {
+ buf_len += 3 + 2 + EHT_PHY_CAPAB_LEN + EHT_MCS_NSS_CAPAB_LEN +
+ EHT_PPE_THRESH_CAPAB_LEN;
+ buf_len += 3 + sizeof(struct ieee80211_eht_operation);
+}
+#endif /* CONFIG_IEEE80211BE */
buf = wpabuf_alloc(buf_len);
if (!buf)
@@ -390,7 +397,6 @@
wpabuf_put_data(buf, he_capa_oper, pos - he_capa_oper);
}
#endif /* CONFIG_IEEE80211AX */
-
#ifdef CONFIG_OCV
if (type != PLINK_CLOSE && conf->ocv) {
struct wpa_channel_info ci;
@@ -407,6 +413,21 @@
}
#endif /* CONFIG_OCV */
+#ifdef CONFIG_IEEE80211BE
+ if (type != PLINK_CLOSE && wpa_s->mesh_eht_enabled) {
+ u8 eht_capa_oper[3 +
+ 2 +
+ EHT_PHY_CAPAB_LEN +
+ EHT_MCS_NSS_CAPAB_LEN +
+ EHT_PPE_THRESH_CAPAB_LEN +
+ 3 + sizeof(struct ieee80211_eht_operation)];
+ pos = hostapd_eid_eht_capab(bss, eht_capa_oper,
+ IEEE80211_MODE_MESH);
+ pos = hostapd_eid_eht_operation(bss, pos);
+ wpabuf_put_data(buf, eht_capa_oper, pos - eht_capa_oper);
+ }
+#endif /* CONFIG_IEEE80211BE */
+
if (ampe && mesh_rsn_protect_frame(wpa_s->mesh_rsn, sta, cat, buf)) {
wpa_msg(wpa_s, MSG_INFO,
"Mesh MPM: failed to add AMPE and MIC IE");
@@ -758,6 +779,13 @@
elems->he_capabilities, elems->he_capabilities_len);
copy_sta_he_6ghz_capab(data, sta, elems->he_6ghz_band_cap);
#endif /* CONFIG_IEEE80211AX */
+#ifdef CONFIG_IEEE80211BE
+ copy_sta_eht_capab(data, sta, IEEE80211_MODE_MESH,
+ elems->he_capabilities,
+ elems->he_capabilities_len,
+ elems->eht_capabilities,
+ elems->eht_capabilities_len);
+#endif /*CONFIG_IEEE80211BE */
if (hostapd_get_aid(data, sta) < 0) {
wpa_msg(wpa_s, MSG_ERROR, "No AIDs available");
@@ -779,6 +807,8 @@
params.he_capab = sta->he_capab;
params.he_capab_len = sta->he_capab_len;
params.he_6ghz_capab = sta->he_6ghz_capab;
+ params.eht_capab = sta->eht_capab;
+ params.eht_capab_len = sta->eht_capab_len;
params.flags |= WPA_STA_WMM;
params.flags_mask |= WPA_STA_AUTHENTICATED;
if (conf->security == MESH_CONF_SEC_NONE) {
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 3122c58..1123d3f 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -967,6 +967,12 @@
}
+void wpas_notify_psk_mismatch(struct wpa_supplicant *wpa_s)
+{
+ wpas_dbus_signal_psk_mismatch(wpa_s);
+}
+
+
void wpas_notify_network_bssid_set_changed(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid)
{
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index b1824ec..914f950 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -152,6 +152,7 @@
void wpas_notify_eap_status(struct wpa_supplicant *wpa_s, const char *status,
const char *parameter);
void wpas_notify_eap_error(struct wpa_supplicant *wpa_s, int error_code);
+void wpas_notify_psk_mismatch(struct wpa_supplicant *wpa_s);
void wpas_notify_network_bssid_set_changed(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid);
void wpas_notify_network_type_changed(struct wpa_supplicant *wpa_s,
diff --git a/wpa_supplicant/op_classes.c b/wpa_supplicant/op_classes.c
index 5dca8f7..b4ad3ca 100644
--- a/wpa_supplicant/op_classes.c
+++ b/wpa_supplicant/op_classes.c
@@ -103,10 +103,7 @@
NOT_ALLOWED)
return NOT_ALLOWED;
- if ((i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_70)) ||
- (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_50)) ||
- (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_30)) ||
- (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_10)))
+ if (!(flags & HOSTAPD_CHAN_VHT_80MHZ_SUBCHANNEL))
return NOT_ALLOWED;
if (flags & HOSTAPD_CHAN_NO_IR)
@@ -175,14 +172,8 @@
NOT_ALLOWED)
return NOT_ALLOWED;
- if ((i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_150)) ||
- (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_130)) ||
- (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_110)) ||
- (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_90)) ||
- (i == 4 && !(flags & HOSTAPD_CHAN_VHT_90_70)) ||
- (i == 5 && !(flags & HOSTAPD_CHAN_VHT_110_50)) ||
- (i == 6 && !(flags & HOSTAPD_CHAN_VHT_130_30)) ||
- (i == 7 && !(flags & HOSTAPD_CHAN_VHT_150_10)))
+ if (!(flags & HOSTAPD_CHAN_VHT_80MHZ_SUBCHANNEL) ||
+ !(flags & HOSTAPD_CHAN_VHT_160MHZ_SUBCHANNEL))
return NOT_ALLOWED;
if (flags & HOSTAPD_CHAN_NO_IR)
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 926ba7a..a5fdc9a 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -165,6 +165,8 @@
struct wpa_used_freq_data *freqs, unsigned int num,
enum wpas_p2p_channel_update_trig trig);
static void wpas_p2p_reconsider_moving_go(void *eloop_ctx, void *timeout_ctx);
+static int wpas_p2p_disallowed_freq(struct wpa_global *global,
+ unsigned int freq);
static int wpas_get_6ghz_he_chwidth_capab(struct hostapd_hw_modes *mode)
@@ -3136,6 +3138,68 @@
}
+/**
+ * Pick the best frequency the driver suggests.
+ *
+ * num_pref_freq is used as both input and output
+ * - input: the max size of pref_freq_list,
+ * - output: the valid size of pref_freq_list filled with data.
+ */
+static int wpas_p2p_pick_best_pref_freq(struct wpa_supplicant *wpa_s, bool go,
+ struct weighted_pcl *pref_freq_list,
+ unsigned int *num_pref_freq)
+{
+ int best_freq = 0;
+ unsigned int max_pref_freq, i;
+ int res;
+ enum wpa_driver_if_type iface_type;
+
+ max_pref_freq = *num_pref_freq;
+ *num_pref_freq = 0;
+
+ if (go)
+ iface_type = WPA_IF_P2P_GO;
+ else
+ iface_type = WPA_IF_P2P_CLIENT;
+
+ res = wpa_drv_get_pref_freq_list(wpa_s, iface_type, &max_pref_freq,
+ pref_freq_list);
+ if (!res && !is_p2p_allow_6ghz(wpa_s->global->p2p))
+ max_pref_freq = p2p_remove_6ghz_channels(pref_freq_list,
+ max_pref_freq);
+ if (res || !max_pref_freq) {
+ wpa_printf(MSG_DEBUG,
+ "P2P: No preferred frequency list available");
+ return 0;
+ }
+
+ *num_pref_freq = max_pref_freq;
+ i = 0;
+ while (i < *num_pref_freq &&
+ (!p2p_supported_freq(wpa_s->global->p2p,
+ pref_freq_list[i].freq) ||
+ wpas_p2p_disallowed_freq(wpa_s->global,
+ pref_freq_list[i].freq) ||
+ !p2p_pref_freq_allowed(&pref_freq_list[i], go))) {
+ wpa_printf(MSG_DEBUG,
+ "P2P: preferred_freq_list[%d]=%d is disallowed",
+ i, pref_freq_list[i].freq);
+ i++;
+ }
+ if (i != *num_pref_freq) {
+ best_freq = pref_freq_list[i].freq;
+ wpa_printf(MSG_DEBUG, "P2P: Using preferred_freq_list[%d]=%d",
+ i, best_freq);
+ } else {
+ wpa_printf(MSG_DEBUG,
+ "P2P: All driver preferred frequencies are disallowed for P2P use");
+ *num_pref_freq = 0;
+ }
+
+ return best_freq;
+}
+
+
static u8 wpas_invitation_process(void *ctx, const u8 *sa, const u8 *bssid,
const u8 *go_dev_addr, const u8 *ssid,
size_t ssid_len, int *go, u8 *group_bssid,
@@ -3148,6 +3212,10 @@
struct wpa_used_freq_data *freqs;
struct wpa_supplicant *grp;
int best_freq;
+ struct weighted_pcl pref_freq_list[P2P_MAX_PREF_CHANNELS];
+ unsigned int num_pref_freq;
+ int res;
+
if (!persistent_group) {
wpa_printf(MSG_DEBUG, "P2P: Invitation from " MACSTR
@@ -3253,6 +3321,12 @@
os_free(freqs);
}
+ num_pref_freq = P2P_MAX_PREF_CHANNELS;
+ res = wpas_p2p_pick_best_pref_freq(wpa_s, *go, pref_freq_list,
+ &num_pref_freq);
+ if (res > 0)
+ best_freq = res;
+
/* Get one of the frequencies currently in use */
if (best_freq > 0) {
wpa_printf(MSG_DEBUG, "P2P: Trying to prefer a channel already used by one of the interfaces");
@@ -3331,7 +3405,7 @@
wpa_s->conf->p2p_go_edmg, NULL,
go ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0,
1, is_p2p_allow_6ghz(wpa_s->global->p2p), 0,
- false);
+ NULL);
} else if (bssid) {
wpa_s->user_initiated_pd = 0;
wpa_msg_global(wpa_s, MSG_INFO,
@@ -3562,7 +3636,7 @@
P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
0, 1,
is_p2p_allow_6ghz(wpa_s->global->p2p), 0,
- false);
+ NULL);
}
@@ -3741,13 +3815,7 @@
if (res == NO_IR)
ret = NO_IR;
if (!is_6ghz) {
- if (i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_70))
- return NOT_ALLOWED;
- if (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_50))
- return NOT_ALLOWED;
- if (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_30))
- return NOT_ALLOWED;
- if (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_10))
+ if (!(flags & HOSTAPD_CHAN_VHT_80MHZ_SUBCHANNEL))
return NOT_ALLOWED;
} else if (is_6ghz &&
(!(wpas_get_6ghz_he_chwidth_capab(mode) &
@@ -3825,21 +3893,8 @@
ret = NO_IR;
if (!is_6ghz_op_class(op_class)) {
- if (i == 0 && !(flags & HOSTAPD_CHAN_VHT_10_150))
- return NOT_ALLOWED;
- if (i == 1 && !(flags & HOSTAPD_CHAN_VHT_30_130))
- return NOT_ALLOWED;
- if (i == 2 && !(flags & HOSTAPD_CHAN_VHT_50_110))
- return NOT_ALLOWED;
- if (i == 3 && !(flags & HOSTAPD_CHAN_VHT_70_90))
- return NOT_ALLOWED;
- if (i == 4 && !(flags & HOSTAPD_CHAN_VHT_90_70))
- return NOT_ALLOWED;
- if (i == 5 && !(flags & HOSTAPD_CHAN_VHT_110_50))
- return NOT_ALLOWED;
- if (i == 6 && !(flags & HOSTAPD_CHAN_VHT_130_30))
- return NOT_ALLOWED;
- if (i == 7 && !(flags & HOSTAPD_CHAN_VHT_150_10))
+ if (!(flags & HOSTAPD_CHAN_VHT_80MHZ_SUBCHANNEL) ||
+ !(flags & HOSTAPD_CHAN_VHT_160MHZ_SUBCHANNEL))
return NOT_ALLOWED;
} else if (is_6ghz_op_class(op_class) &&
(!(wpas_get_6ghz_he_chwidth_capab(mode) &
@@ -4648,7 +4703,7 @@
persistent_go->mode ==
WPAS_MODE_P2P_GO ?
P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
- 0, 0, false, 0, false);
+ 0, 0, false, 0, NULL);
} else if (response_done) {
wpas_p2p_group_add(wpa_s, 1, freq,
0, 0, 0, 0, 0, 0, false);
@@ -4771,7 +4826,7 @@
NULL,
persistent_go->mode == WPAS_MODE_P2P_GO ?
P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0, 0,
- is_p2p_allow_6ghz(wpa_s->global->p2p), 0, false);
+ is_p2p_allow_6ghz(wpa_s->global->p2p), 0, NULL);
} else {
wpas_p2p_group_add(wpa_s, 1, freq, 0, 0, 0, 0, 0, 0,
is_p2p_allow_6ghz(wpa_s->global->p2p));
@@ -5854,50 +5909,14 @@
i++;
}
} else if (!wpa_s->conf->num_p2p_pref_chan) {
- enum wpa_driver_if_type iface_type;
-
- if (go)
- iface_type = WPA_IF_P2P_GO;
- else
- iface_type = WPA_IF_P2P_CLIENT;
-
wpa_printf(MSG_DEBUG, "P2P: best_freq=%d, go=%d",
- best_freq, go);
+ best_freq, go);
- res = wpa_drv_get_pref_freq_list(wpa_s, iface_type,
- &max_pref_freq,
- pref_freq_list);
- if (!res && max_pref_freq > 0) {
- *num_pref_freq = max_pref_freq;
- i = 0;
- while (i < *num_pref_freq &&
- (!p2p_supported_freq(wpa_s->global->p2p,
- pref_freq_list[i].freq) ||
- wpas_p2p_disallowed_freq(
- wpa_s->global,
- pref_freq_list[i].freq) ||
- !p2p_pref_freq_allowed(&pref_freq_list[i],
- go))) {
- wpa_printf(MSG_DEBUG,
- "P2P: preferred_freq_list[%d]=%d is disallowed",
- i, pref_freq_list[i].freq);
- i++;
- }
- if (i != *num_pref_freq) {
- best_freq = pref_freq_list[i].freq;
- wpa_printf(MSG_DEBUG,
- "P2P: Using preferred_freq_list[%d]=%d",
- i, best_freq);
- } else {
- wpa_printf(MSG_DEBUG,
- "P2P: All driver preferred frequencies are "
- "disallowed for P2P use");
- *num_pref_freq = 0;
- }
- } else {
- wpa_printf(MSG_DEBUG,
- "P2P: No preferred frequency list available");
- }
+ *num_pref_freq = max_pref_freq;
+ res = wpas_p2p_pick_best_pref_freq(wpa_s, go, pref_freq_list,
+ num_pref_freq);
+ if (res > 0)
+ best_freq = res;
}
}
@@ -6996,7 +7015,7 @@
static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s,
struct wpa_ssid *params, int addr_allocated,
int freq, int force_scan, int retry_limit,
- bool force_go_bssid)
+ const u8 *go_bssid)
{
struct wpa_ssid *ssid;
int other_iface_found = 0;
@@ -7023,6 +7042,16 @@
WPA_CIPHER_CCMP;
ssid->group_cipher = params->pbss ? WPA_CIPHER_GCMP : WPA_CIPHER_CCMP;
ssid->key_mgmt = WPA_KEY_MGMT_PSK;
+ if (is_6ghz_freq(freq) &&
+ is_p2p_6ghz_capable(wpa_s->global->p2p)) {
+ ssid->auth_alg |= WPA_AUTH_ALG_SAE;
+ ssid->key_mgmt |= WPA_KEY_MGMT_SAE;
+ ssid->ieee80211w = MGMT_FRAME_PROTECTION_OPTIONAL;
+ ssid->sae_pwe = SAE_PWE_HASH_TO_ELEMENT;
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "P2P: Enable SAE auth_alg and key_mgmt");
+ }
+
ssid->ssid = os_malloc(params->ssid_len);
if (ssid->ssid == NULL) {
wpa_config_remove_network(wpa_s->conf, ssid->id);
@@ -7039,9 +7068,9 @@
if (params->passphrase)
ssid->passphrase = os_strdup(params->passphrase);
- if (force_go_bssid && params->bssid_set) {
+ if (go_bssid) {
ssid->bssid_set = 1;
- os_memcpy(ssid->bssid, params->bssid, ETH_ALEN);
+ os_memcpy(ssid->bssid, go_bssid, ETH_ALEN);
}
wpa_s->show_group_started = 1;
@@ -7091,7 +7120,7 @@
const struct p2p_channels *channels,
int connection_timeout, int force_scan,
bool allow_6ghz, int retry_limit,
- bool force_go_bssid)
+ const u8 *go_bssid)
{
struct p2p_go_neg_results params;
int go = 0, freq;
@@ -7160,8 +7189,7 @@
}
return wpas_start_p2p_client(wpa_s, ssid, addr_allocated, freq,
- force_scan, retry_limit,
- force_go_bssid);
+ force_scan, retry_limit, go_bssid);
} else {
return -1;
}
@@ -8412,7 +8440,7 @@
}
-int wpas_p2p_notif_pbc_overlap(struct wpa_supplicant *wpa_s)
+static int wpas_p2p_notif_pbc_overlap(struct wpa_supplicant *wpa_s)
{
if (wpa_s->p2p_group_interface != P2P_GROUP_INTERFACE_CLIENT &&
!wpa_s->p2p_in_provisioning)
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index e113c62..d71f770 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -53,7 +53,7 @@
const struct p2p_channels *channels,
int connection_timeout, int force_scan,
bool allow_6ghz, int retry_limit,
- bool force_go_bssid);
+ const u8 *go_bssid);
struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid);
enum wpas_p2p_prov_disc_use {
@@ -207,7 +207,6 @@
void wpas_p2p_interface_unavailable(struct wpa_supplicant *wpa_s);
void wpas_p2p_notif_connected(struct wpa_supplicant *wpa_s);
void wpas_p2p_notif_disconnected(struct wpa_supplicant *wpa_s);
-int wpas_p2p_notif_pbc_overlap(struct wpa_supplicant *wpa_s);
int wpas_p2p_4way_hs_failed(struct wpa_supplicant *wpa_s);
void wpas_p2p_ap_setup_failed(struct wpa_supplicant *wpa_s);
bool wpas_p2p_retry_limit_exceeded(struct wpa_supplicant *wpa_s);
@@ -305,11 +304,6 @@
{
}
-static inline int wpas_p2p_notif_pbc_overlap(struct wpa_supplicant *wpa_s)
-{
- return 0;
-}
-
static inline int wpas_p2p_4way_hs_failed(struct wpa_supplicant *wpa_s)
{
return 0;
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 88d7e6e..c3984a4 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -445,18 +445,20 @@
}
if (params->freqs == NULL && wpa_s->p2p_in_invitation) {
+ struct wpa_ssid *ssid = wpa_s->current_ssid;
+
/*
* Perform a single-channel scan if the GO has already been
* discovered on another non-P2P interface. Note that a scan
- * initiated by a P2P interface (e.g. the device interface)
+ * initiated by a P2P interface (e.g., the device interface)
* should already have sufficient IEs and scan results will be
* fetched on interface creation in that case.
*/
- if (wpa_s->p2p_in_invitation == 1 && wpa_s->current_ssid) {
+ if (wpa_s->p2p_in_invitation == 1 && ssid) {
struct wpa_supplicant *ifs;
struct wpa_bss *bss = NULL;
- struct wpa_ssid *ssid = wpa_s->current_ssid;
- u8 *bssid = ssid->bssid_set ? ssid->bssid : NULL;
+ const u8 *bssid = ssid->bssid_set ? ssid->bssid : NULL;
+
dl_list_for_each(ifs, &wpa_s->radio->ifaces,
struct wpa_supplicant, radio_list) {
bss = wpa_bss_get(ifs, bssid, ssid->ssid,
@@ -466,15 +468,20 @@
}
if (bss && !disabled_freq(wpa_s, bss->freq)) {
params->freqs = os_calloc(2, sizeof(int));
- if (params->freqs)
+ if (params->freqs) {
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "P2P: Scan only the known GO frequency %d MHz during invitation",
+ bss->freq);
params->freqs[0] = bss->freq;
+ }
}
}
+
/*
* Optimize scan based on GO information during persistent
* group reinvocation
*/
- if (params->freqs == NULL && wpa_s->p2p_in_invitation < 5 &&
+ if (!params->freqs && wpa_s->p2p_in_invitation < 5 &&
wpa_s->p2p_invite_go_freq > 0) {
if (wpa_s->p2p_invite_go_freq == 2 ||
wpa_s->p2p_invite_go_freq == 5) {
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index 406e357..ea4023c 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -198,6 +198,9 @@
if (wpa_key_mgmt_sae_ext_key(key_mgmt) &&
wpa_s->conf->sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK)
use_pt = 1;
+ if (bss && is_6ghz_freq(bss->freq) &&
+ wpa_s->conf->sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK)
+ use_pt = 1;
#ifdef CONFIG_SAE_PK
if ((rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_PK)) &&
ssid->sae_pk != SAE_PK_MODE_DISABLED &&
@@ -231,6 +234,8 @@
}
}
+ if (use_pt && !ssid->pt)
+ wpa_s_setup_sae_pt(wpa_s->conf, ssid, true);
if (use_pt &&
sae_prepare_commit_pt(&wpa_s->sme.sae, ssid->pt,
wpa_s->own_addr, addr,
@@ -1301,11 +1306,30 @@
#ifdef CONFIG_SAE
+#define WPA_AUTH_FRAME_ML_IE_LEN (6 + ETH_ALEN)
+
+static void wpa_auth_ml_ie(struct wpabuf *buf, const u8 *mld_addr)
+{
+
+ wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
+ wpabuf_put_u8(buf, 4 + ETH_ALEN);
+ wpabuf_put_u8(buf, WLAN_EID_EXT_MULTI_LINK);
+
+ /* Basic Multi-Link element Control field */
+ wpabuf_put_u8(buf, 0x0);
+ wpabuf_put_u8(buf, 0x0);
+
+ /* Common Info */
+ wpabuf_put_u8(buf, 0x7); /* length = Length field + MLD MAC address */
+ wpabuf_put_data(buf, mld_addr, ETH_ALEN);
+}
+
+
static int sme_external_auth_build_buf(struct wpabuf *buf,
struct wpabuf *params,
const u8 *sa, const u8 *da,
u16 auth_transaction, u16 seq_num,
- u16 status_code)
+ u16 status_code, const u8 *mld_addr)
{
struct ieee80211_mgmt *resp;
@@ -1324,6 +1348,9 @@
if (params)
wpabuf_put_buf(buf, params);
+ if (mld_addr)
+ wpa_auth_ml_ie(buf, mld_addr);
+
return 0;
}
@@ -1337,7 +1364,9 @@
bool use_pk;
u16 status;
- resp = sme_auth_build_sae_commit(wpa_s, ssid, bssid, NULL,
+ resp = sme_auth_build_sae_commit(wpa_s, ssid, bssid,
+ wpa_s->sme.ext_ml_auth ?
+ wpa_s->sme.ext_auth_ap_mld_addr : NULL,
1, 0, &use_pt, &use_pk);
if (!resp) {
wpa_printf(MSG_DEBUG, "SAE: Failed to build SAE commit");
@@ -1345,7 +1374,9 @@
}
wpa_s->sme.sae.state = SAE_COMMITTED;
- buf = wpabuf_alloc(4 + SAE_COMMIT_MAX_LEN + wpabuf_len(resp));
+ buf = wpabuf_alloc(4 + SAE_COMMIT_MAX_LEN + wpabuf_len(resp) +
+ (wpa_s->sme.ext_ml_auth ? WPA_AUTH_FRAME_ML_IE_LEN :
+ 0));
if (!buf) {
wpabuf_free(resp);
return -1;
@@ -1359,7 +1390,11 @@
else
status = WLAN_STATUS_SUCCESS;
sme_external_auth_build_buf(buf, resp, wpa_s->own_addr,
- bssid, 1, wpa_s->sme.seq_num, status);
+ wpa_s->sme.ext_ml_auth ?
+ wpa_s->sme.ext_auth_ap_mld_addr : bssid, 1,
+ wpa_s->sme.seq_num, status,
+ wpa_s->sme.ext_ml_auth ?
+ wpa_s->own_addr : NULL);
wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1, 0, 0);
wpabuf_free(resp);
wpabuf_free(buf);
@@ -1400,7 +1435,7 @@
os_memcmp(ssid_str, ssid->ssid, ssid_str_len) == 0 &&
wpa_key_mgmt_sae(ssid->key_mgmt)) {
/* Make sure PT is derived */
- wpa_s_setup_sae_pt(wpa_s->conf, ssid);
+ wpa_s_setup_sae_pt(wpa_s->conf, ssid, false);
wpa_s->sme.ext_auth_wpa_ssid = ssid;
break;
}
@@ -1426,7 +1461,9 @@
}
wpa_s->sme.sae.state = SAE_CONFIRMED;
- buf = wpabuf_alloc(4 + SAE_CONFIRM_MAX_LEN + wpabuf_len(resp));
+ buf = wpabuf_alloc(4 + SAE_CONFIRM_MAX_LEN + wpabuf_len(resp) +
+ (wpa_s->sme.ext_ml_auth ? WPA_AUTH_FRAME_ML_IE_LEN :
+ 0));
if (!buf) {
wpa_printf(MSG_DEBUG, "SAE: Auth Confirm buf alloc failure");
wpabuf_free(resp);
@@ -1435,7 +1472,10 @@
wpa_s->sme.seq_num++;
sme_external_auth_build_buf(buf, resp, wpa_s->own_addr,
da, 2, wpa_s->sme.seq_num,
- WLAN_STATUS_SUCCESS);
+ WLAN_STATUS_SUCCESS,
+ wpa_s->sme.ext_ml_auth ?
+ wpa_s->own_addr : NULL);
+
wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1, 0, 0);
wpabuf_free(resp);
wpabuf_free(buf);
@@ -1487,6 +1527,13 @@
os_memcpy(wpa_s->sme.ext_auth_ssid, data->external_auth.ssid,
data->external_auth.ssid_len);
wpa_s->sme.ext_auth_ssid_len = data->external_auth.ssid_len;
+ if (data->external_auth.mld_addr) {
+ wpa_s->sme.ext_ml_auth = true;
+ os_memcpy(wpa_s->sme.ext_auth_ap_mld_addr,
+ data->external_auth.mld_addr, ETH_ALEN);
+ } else {
+ wpa_s->sme.ext_ml_auth = false;
+ }
wpa_s->sme.seq_num = 0;
wpa_s->sme.sae.state = SAE_NOTHING;
wpa_s->sme.sae.send_confirm = 0;
@@ -1548,6 +1595,42 @@
}
+static int sme_external_ml_auth(struct wpa_supplicant *wpa_s,
+ const u8 *data, size_t len, int ie_offset)
+{
+ struct ieee802_11_elems elems;
+ const u8 *mld_addr;
+
+ if (ieee802_11_parse_elems(data + ie_offset, len - ie_offset,
+ &elems, 0) != ParseOK) {
+ wpa_printf(MSG_DEBUG, "MLD: Failed parsing elements");
+ return -1;
+ }
+
+ if (!elems.basic_mle || !elems.basic_mle_len) {
+ wpa_printf(MSG_DEBUG, "MLD: No ML element in authentication");
+ return -1;
+ }
+
+ mld_addr = get_basic_mle_mld_addr(elems.basic_mle, elems.basic_mle_len);
+ if (!mld_addr) {
+ wpa_printf(MSG_DEBUG, "MLD: No MLD address in ML element");
+ return -1;
+ }
+
+ wpa_printf(MSG_DEBUG, "MLD: mld_address=" MACSTR, MAC2STR(mld_addr));
+
+ if (os_memcmp(wpa_s->sme.ext_auth_ap_mld_addr, mld_addr, ETH_ALEN) !=
+ 0) {
+ wpa_printf(MSG_DEBUG, "MLD: Unexpected MLD address (expected "
+ MACSTR ")", MAC2STR(wpa_s->ap_mld_addr));
+ return -1;
+ }
+
+ return 0;
+}
+
+
static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
u16 status_code, const u8 *data, size_t len,
int external, const u8 *sa, int *ie_offset)
@@ -1615,8 +1698,7 @@
token_len = elen - 1;
}
- if (ie_offset)
- *ie_offset = token_pos + token_len - data;
+ *ie_offset = token_pos + token_len - data;
wpa_s->sme.sae_token = wpabuf_alloc_copy(token_pos, token_len);
if (!wpa_s->sme.sae_token) {
@@ -1627,13 +1709,18 @@
wpa_hexdump_buf(MSG_DEBUG, "SME: Requested anti-clogging token",
wpa_s->sme.sae_token);
- if (!external)
+ if (!external) {
sme_send_authentication(wpa_s, wpa_s->current_bss,
wpa_s->current_ssid, 2);
- else
+ } else {
+ if (wpa_s->sme.ext_ml_auth &&
+ sme_external_ml_auth(wpa_s, data, len, *ie_offset))
+ return -1;
+
sme_external_auth_send_sae_commit(
wpa_s, wpa_s->sme.ext_auth_bssid,
wpa_s->sme.ext_auth_wpa_ssid);
+ }
return 0;
}
@@ -1649,13 +1736,18 @@
if (sme_set_sae_group(wpa_s, external) < 0)
return -1; /* no other groups enabled */
wpa_dbg(wpa_s, MSG_DEBUG, "SME: Try next enabled SAE group");
- if (!external)
+ if (!external) {
sme_send_authentication(wpa_s, wpa_s->current_bss,
wpa_s->current_ssid, 1);
- else
+ } else {
+ if (wpa_s->sme.ext_ml_auth &&
+ sme_external_ml_auth(wpa_s, data, len, *ie_offset))
+ return -1;
+
sme_external_auth_send_sae_commit(
wpa_s, wpa_s->sme.ext_auth_bssid,
wpa_s->sme.ext_auth_wpa_ssid);
+ }
return 0;
}
@@ -1743,11 +1835,16 @@
wpabuf_free(wpa_s->sme.sae_token);
wpa_s->sme.sae_token = NULL;
- if (!external)
+ if (!external) {
sme_send_authentication(wpa_s, wpa_s->current_bss,
wpa_s->current_ssid, 0);
- else
+ } else {
+ if (wpa_s->sme.ext_ml_auth &&
+ sme_external_ml_auth(wpa_s, data, len, *ie_offset))
+ return -1;
+
sme_external_auth_send_sae_confirm(wpa_s, sa);
+ }
return 0;
} else if (auth_transaction == 2) {
if (status_code != WLAN_STATUS_SUCCESS)
@@ -1758,6 +1855,10 @@
if (sae_check_confirm(&wpa_s->sme.sae, data, len,
ie_offset) < 0)
return -1;
+ if (external && wpa_s->sme.ext_ml_auth &&
+ sme_external_ml_auth(wpa_s, data, len, *ie_offset))
+ return -1;
+
wpa_s->sme.sae.state = SAE_ACCEPTED;
sae_clear_temp_data(&wpa_s->sme.sae);
@@ -1823,12 +1924,13 @@
if (le_to_host16(header->u.auth.auth_alg) == WLAN_AUTH_SAE) {
int res;
+ int ie_offset = 0;
res = sme_sae_auth(
wpa_s, le_to_host16(header->u.auth.auth_transaction),
le_to_host16(header->u.auth.status_code),
header->u.auth.variable,
- len - auth_length, 1, header->sa, NULL);
+ len - auth_length, 1, header->sa, &ie_offset);
if (res < 0) {
/* Notify failure to the driver */
sme_send_external_auth_status(
@@ -1841,7 +1943,10 @@
if (res != 1)
return;
- if (sme_sae_set_pmk(wpa_s, wpa_s->sme.ext_auth_bssid) < 0)
+ if (sme_sae_set_pmk(wpa_s,
+ wpa_s->sme.ext_ml_auth ?
+ wpa_s->sme.ext_auth_ap_mld_addr :
+ wpa_s->sme.ext_auth_bssid) < 0)
return;
}
}
diff --git a/wpa_supplicant/utils/log2pcap.py b/wpa_supplicant/utils/log2pcap.py
index 141aecb..9a3f08d 100755
--- a/wpa_supplicant/utils/log2pcap.py
+++ b/wpa_supplicant/utils/log2pcap.py
@@ -1,6 +1,6 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
-# Copyright (c) 2012, Intel Corporation
+# Copyright (c) 2012-2022, Intel Corporation
#
# Author: Johannes Berg <johannes@sipsolutions.net>
#
@@ -8,6 +8,7 @@
# See README for more details.
import sys, struct, re
+from binascii import unhexlify
def write_pcap_header(pcap_file):
pcap_file.write(
@@ -32,7 +33,7 @@
sys.exit(2)
input_file = open(input, 'r')
- pcap_file = open(pcap, 'w')
+ pcap_file = open(pcap, 'wb')
frame_re = re.compile(r'(([0-9]+.[0-9]{6}):\s*)?nl80211: MLME event frame - hexdump\(len=[0-9]*\):((\s*[0-9a-fA-F]{2})*)')
write_pcap_header(pcap_file)
@@ -47,7 +48,7 @@
ts = 0
hexdata = m.group(3)
hexdata = hexdata.split()
- data = ''.join([chr(int(x, 16)) for x in hexdata])
+ data = unhexlify("".join(hexdata))
pcap_addpacket(pcap_file, ts, data)
input_file.close()
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index bfdc42d..f808ac4 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -1487,6 +1487,7 @@
"macsec_integ_only",
"macsec_replay_protect",
"macsec_replay_window",
+ "macsec_offload",
"macsec_port",
"mka_priority",
#endif /* CONFIG_MACSEC */
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 521ff90..134bcf1 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -2338,7 +2338,8 @@
}
-void wpa_s_setup_sae_pt(struct wpa_config *conf, struct wpa_ssid *ssid)
+void wpa_s_setup_sae_pt(struct wpa_config *conf, struct wpa_ssid *ssid,
+ bool force)
{
#ifdef CONFIG_SAE
int *groups = conf->sae_groups;
@@ -2355,6 +2356,7 @@
if (!password ||
(conf->sae_pwe == SAE_PWE_HUNT_AND_PECK && !ssid->sae_password_id &&
!wpa_key_mgmt_sae_ext_key(ssid->key_mgmt) &&
+ !force &&
!sae_pk_valid_password(password)) ||
conf->sae_pwe == SAE_PWE_FORCE_HUNT_AND_PECK) {
/* PT derivation not needed */
@@ -2467,7 +2469,7 @@
#endif /* CONFIG_SAE */
}
#ifdef CONFIG_SAE
- wpa_s_setup_sae_pt(wpa_s->conf, ssid);
+ wpa_s_setup_sae_pt(wpa_s->conf, ssid, false);
#endif /* CONFIG_SAE */
if (rand_style > WPAS_MAC_ADDR_STYLE_PERMANENT) {
@@ -2529,6 +2531,7 @@
if (bss)
ssid->frequency = bss->freq;
if (wpa_supplicant_join_mesh(wpa_s, ssid) < 0) {
+ wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
wpa_msg(wpa_s, MSG_ERROR, "Could not join mesh");
return;
}
@@ -2651,116 +2654,142 @@
}
-void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s,
- const struct wpa_ssid *ssid,
- struct hostapd_freq_params *freq)
+static struct wpa_bss * ibss_find_existing_bss(struct wpa_supplicant *wpa_s,
+ const struct wpa_ssid *ssid)
{
- int ieee80211_mode = wpas_mode_to_ieee80211_mode(ssid->mode);
- enum hostapd_hw_mode hw_mode;
- struct hostapd_hw_modes *mode = NULL;
- int ht40plus[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157,
- 184, 192 };
- int bw80[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5955,
- 6035, 6115, 6195, 6275, 6355, 6435, 6515,
- 6595, 6675, 6755, 6835, 6915, 6995 };
- int bw160[] = { 5955, 6115, 6275, 6435, 6595, 6755, 6915 };
- struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL;
- u8 channel;
- int i, chan_idx, ht40 = -1, res, obss_scan = 1;
- unsigned int j, k;
- struct hostapd_freq_params vht_freq;
- int chwidth, seg0, seg1;
- u32 vht_caps = 0;
- bool is_24ghz, is_6ghz;
-
- freq->freq = ssid->frequency;
+ unsigned int j;
for (j = 0; j < wpa_s->last_scan_res_used; j++) {
struct wpa_bss *bss = wpa_s->last_scan_res[j];
- if (ssid->mode != WPAS_MODE_IBSS)
- break;
-
- /* Don't adjust control freq in case of fixed_freq */
- if (ssid->fixed_freq)
- break;
-
if (!bss_is_ibss(bss))
continue;
if (ssid->ssid_len == bss->ssid_len &&
- os_memcmp(ssid->ssid, bss->ssid, bss->ssid_len) == 0) {
- wpa_printf(MSG_DEBUG,
- "IBSS already found in scan results, adjust control freq: %d",
- bss->freq);
- freq->freq = bss->freq;
- obss_scan = 0;
- break;
- }
+ os_memcmp(ssid->ssid, bss->ssid, bss->ssid_len) == 0)
+ return bss;
}
+ return NULL;
+}
+
+static bool ibss_mesh_can_use_ht(struct wpa_supplicant *wpa_s,
+ const struct wpa_ssid *ssid,
+ struct hostapd_hw_modes *mode)
+{
/* For IBSS check HT_IBSS flag */
if (ssid->mode == WPAS_MODE_IBSS &&
!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_HT_IBSS))
- return;
+ return false;
if (wpa_s->group_cipher == WPA_CIPHER_WEP40 ||
wpa_s->group_cipher == WPA_CIPHER_WEP104 ||
wpa_s->pairwise_cipher == WPA_CIPHER_TKIP) {
wpa_printf(MSG_DEBUG,
"IBSS: WEP/TKIP detected, do not try to enable HT");
- return;
+ return false;
}
- hw_mode = ieee80211_freq_to_chan(freq->freq, &channel);
- for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
- if (wpa_s->hw.modes[i].mode == hw_mode) {
- mode = &wpa_s->hw.modes[i];
- break;
- }
- }
-
- if (!mode)
- return;
-
- freq->channel = channel;
-
- is_24ghz = hw_mode == HOSTAPD_MODE_IEEE80211G ||
- hw_mode == HOSTAPD_MODE_IEEE80211B;
-
- /* HT/VHT and corresponding overrides are not applicable to 6 GHz.
- * However, HE is mandatory for 6 GHz.
- */
- is_6ghz = is_6ghz_freq(freq->freq);
- if (is_6ghz)
- goto skip_to_6ghz;
+ if (!ht_supported(mode))
+ return false;
#ifdef CONFIG_HT_OVERRIDES
- if (ssid->disable_ht) {
- freq->ht_enabled = 0;
- return;
- }
+ if (ssid->disable_ht)
+ return false;
#endif /* CONFIG_HT_OVERRIDES */
- freq->ht_enabled = ht_supported(mode);
- if (!freq->ht_enabled)
- return;
+ return true;
+}
- /* Allow HE on 2.4 GHz without VHT: see nl80211_put_freq_params() */
- if (is_24ghz)
- freq->he_enabled = mode->he_capab[ieee80211_mode].he_supported;
+
+static bool ibss_mesh_can_use_vht(struct wpa_supplicant *wpa_s,
+ const struct wpa_ssid *ssid,
+ struct hostapd_hw_modes *mode)
+{
+ if (mode->mode != HOSTAPD_MODE_IEEE80211A)
+ return false;
+
+ if (!drv_supports_vht(wpa_s, ssid))
+ return false;
+
+ /* For IBSS check VHT_IBSS flag */
+ if (ssid->mode == WPAS_MODE_IBSS &&
+ !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_VHT_IBSS))
+ return false;
+
+ if (!vht_supported(mode))
+ return false;
+
+#ifdef CONFIG_VHT_OVERRIDES
+ if (ssid->disable_vht)
+ return false;
+#endif /* CONFIG_VHT_OVERRIDES */
+
+ return true;
+}
+
+
+static bool ibss_mesh_can_use_he(struct wpa_supplicant *wpa_s,
+ const struct wpa_ssid *ssid,
+ const struct hostapd_hw_modes *mode,
+ int ieee80211_mode)
+{
#ifdef CONFIG_HE_OVERRIDES
- if (is_24ghz && ssid->disable_he)
- freq->he_enabled = 0;
+ if (ssid->disable_he)
+ return false;
#endif /* CONFIG_HE_OVERRIDES */
- /* Setup higher BW only for 5 GHz */
- if (mode->mode != HOSTAPD_MODE_IEEE80211A)
+ switch (mode->mode) {
+ case HOSTAPD_MODE_IEEE80211G:
+ case HOSTAPD_MODE_IEEE80211B:
+ case HOSTAPD_MODE_IEEE80211A:
+ return mode->he_capab[ieee80211_mode].he_supported;
+ default:
+ return false;
+ }
+}
+
+
+static bool ibss_mesh_can_use_eht(struct wpa_supplicant *wpa_s,
+ const struct wpa_ssid *ssid,
+ const struct hostapd_hw_modes *mode,
+ int ieee80211_mode)
+{
+ if (ssid->disable_eht)
+ return false;
+
+ switch(mode->mode) {
+ case HOSTAPD_MODE_IEEE80211G:
+ case HOSTAPD_MODE_IEEE80211B:
+ case HOSTAPD_MODE_IEEE80211A:
+ return mode->eht_capab[ieee80211_mode].eht_supported;
+ default:
+ return false;
+ }
+}
+
+
+static void ibss_mesh_select_40mhz(struct wpa_supplicant *wpa_s,
+ const struct wpa_ssid *ssid,
+ struct hostapd_hw_modes *mode,
+ struct hostapd_freq_params *freq,
+ int obss_scan) {
+ int chan_idx;
+ struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL;
+ int i, res;
+ unsigned int j;
+ static const int ht40plus[] = {
+ 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157, 165, 173,
+ 184, 192
+ };
+ int ht40 = -1;
+
+ if (!freq->ht_enabled)
return;
for (chan_idx = 0; chan_idx < mode->num_channels; chan_idx++) {
pri_chan = &mode->channels[chan_idx];
- if (pri_chan->chan == channel)
+ if (pri_chan->chan == freq->channel)
break;
pri_chan = NULL;
}
@@ -2771,21 +2800,14 @@
if (pri_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
return;
- freq->channel = pri_chan->chan;
-
#ifdef CONFIG_HT_OVERRIDES
- if (ssid->disable_ht40) {
-#ifdef CONFIG_VHT_OVERRIDES
- if (ssid->disable_vht)
- return;
-#endif /* CONFIG_VHT_OVERRIDES */
- goto skip_ht40;
- }
-#endif /* CONFIG_HT_OVERRIDES */
+ if (ssid->disable_ht40)
+ return;
+#endif
/* Check/setup HT40+/HT40- */
for (j = 0; j < ARRAY_SIZE(ht40plus); j++) {
- if (ht40plus[j] == channel) {
+ if (ht40plus[j] == freq->channel) {
ht40 = 1;
break;
}
@@ -2794,7 +2816,7 @@
/* Find secondary channel */
for (i = 0; i < mode->num_channels; i++) {
sec_chan = &mode->channels[i];
- if (sec_chan->chan == channel + ht40 * 4)
+ if (sec_chan->chan == freq->channel + ht40 * 4)
break;
sec_chan = NULL;
}
@@ -2847,38 +2869,48 @@
wpa_scan_results_free(scan_res);
}
-#ifdef CONFIG_HT_OVERRIDES
-skip_ht40:
-#endif /* CONFIG_HT_OVERRIDES */
wpa_printf(MSG_DEBUG,
"IBSS/mesh: setup freq channel %d, sec_channel_offset %d",
freq->channel, freq->sec_channel_offset);
+}
- if (!drv_supports_vht(wpa_s, ssid))
- return;
- /* For IBSS check VHT_IBSS flag */
- if (ssid->mode == WPAS_MODE_IBSS &&
- !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_VHT_IBSS))
- return;
+static bool ibss_mesh_select_80_160mhz(struct wpa_supplicant *wpa_s,
+ const struct wpa_ssid *ssid,
+ struct hostapd_hw_modes *mode,
+ struct hostapd_freq_params *freq,
+ int ieee80211_mode, bool is_6ghz) {
+ static const int bw80[] = {
+ 5180, 5260, 5500, 5580, 5660, 5745, 5825,
+ 5955, 6035, 6115, 6195, 6275, 6355, 6435,
+ 6515, 6595, 6675, 6755, 6835, 6915, 6995
+ };
+ static const int bw160[] = {
+ 5955, 6115, 6275, 6435, 6595, 6755, 6915
+ };
+ struct hostapd_freq_params vht_freq;
+ int i;
+ unsigned int j, k;
+ int chwidth, seg0, seg1;
+ u32 vht_caps = 0;
+ u8 channel = freq->channel;
-#ifdef CONFIG_VHT_OVERRIDES
- if (ssid->disable_vht) {
- freq->vht_enabled = 0;
- return;
- }
-#endif /* CONFIG_VHT_OVERRIDES */
+ if (!freq->vht_enabled && !freq->he_enabled)
+ return true;
-skip_to_6ghz:
vht_freq = *freq;
- /* 6 GHz does not have VHT enabled, so allow that exception here. */
- vht_freq.vht_enabled = vht_supported(mode);
- if (!vht_freq.vht_enabled && !is_6ghz)
- return;
-
- /* Enable HE with VHT for 5 GHz */
- freq->he_enabled = mode->he_capab[ieee80211_mode].he_supported;
+ chwidth = CONF_OPER_CHWIDTH_USE_HT;
+ seg0 = freq->channel + 2 * freq->sec_channel_offset;
+ seg1 = 0;
+ if (freq->sec_channel_offset == 0) {
+ seg0 = 0;
+ /* Don't try 80 MHz if 40 MHz failed, except in 6 GHz */
+ if (freq->ht_enabled && !is_6ghz)
+ goto skip_80mhz;
+ }
+ if (ssid->max_oper_chwidth == CONF_OPER_CHWIDTH_USE_HT)
+ goto skip_80mhz;
/* setup center_freq1, bandwidth */
for (j = 0; j < ARRAY_SIZE(bw80); j++) {
@@ -2889,26 +2921,24 @@
if (j == ARRAY_SIZE(bw80) ||
ieee80211_freq_to_chan(bw80[j], &channel) == NUM_HOSTAPD_MODES)
- return;
+ goto skip_80mhz;
- /* Back to HT configuration if channel not usable */
+ /* Use 40 MHz if channel not usable */
if (!ibss_mesh_is_80mhz_avail(channel, mode))
- return;
+ goto skip_80mhz;
chwidth = CONF_OPER_CHWIDTH_80MHZ;
seg0 = channel + 6;
seg1 = 0;
+ /* In 160 MHz, the initial four 20 MHz channels were validated
+ * above. If 160 MHz is supported, check the remaining four 20 MHz
+ * channels for the total of 160 MHz bandwidth for 6 GHz.
+ */
if ((mode->he_capab[ieee80211_mode].phy_cap[
HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
- HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G) && is_6ghz) {
- /* In 160 MHz, the initial four 20 MHz channels were validated
- * above; check the remaining four 20 MHz channels for the total
- * of 160 MHz bandwidth.
- */
- if (!ibss_mesh_is_80mhz_avail(channel + 16, mode))
- return;
-
+ HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G) && is_6ghz &&
+ ibss_mesh_is_80mhz_avail(channel + 16, mode)) {
for (j = 0; j < ARRAY_SIZE(bw160); j++) {
if (freq->freq == bw160[j]) {
chwidth = CONF_OPER_CHWIDTH_160MHZ;
@@ -2927,7 +2957,7 @@
if (ieee80211_freq_to_chan(bw80[k], &channel) ==
NUM_HOSTAPD_MODES)
- return;
+ break;
for (i = channel; i < channel + 16; i += 4) {
struct hostapd_channel_data *chan;
@@ -2962,36 +2992,92 @@
vht_caps |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
seg0 = 114;
}
- } else if (ssid->max_oper_chwidth == CONF_OPER_CHWIDTH_USE_HT) {
- chwidth = CONF_OPER_CHWIDTH_USE_HT;
- seg0 = channel + 2;
-#ifdef CONFIG_HT_OVERRIDES
- if (ssid->disable_ht40)
- seg0 = 0;
-#endif /* CONFIG_HT_OVERRIDES */
}
-#ifdef CONFIG_HE_OVERRIDES
- if (ssid->disable_he) {
- vht_freq.he_enabled = 0;
- freq->he_enabled = 0;
- }
-#endif /* CONFIG_HE_OVERRIDES */
+skip_80mhz:
if (hostapd_set_freq_params(&vht_freq, mode->mode, freq->freq,
freq->channel, ssid->enable_edmg,
ssid->edmg_channel, freq->ht_enabled,
- vht_freq.vht_enabled, freq->he_enabled,
- false,
+ freq->vht_enabled, freq->he_enabled,
+ freq->eht_enabled,
freq->sec_channel_offset,
chwidth, seg0, seg1, vht_caps,
&mode->he_capab[ieee80211_mode],
- NULL) != 0)
- return;
+ &mode->eht_capab[ieee80211_mode]) != 0)
+ return false;
*freq = vht_freq;
wpa_printf(MSG_DEBUG, "IBSS: VHT setup freq cf1 %d, cf2 %d, bw %d",
freq->center_freq1, freq->center_freq2, freq->bandwidth);
+ return true;
+}
+
+
+void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s,
+ const struct wpa_ssid *ssid,
+ struct hostapd_freq_params *freq)
+{
+ int ieee80211_mode = wpas_mode_to_ieee80211_mode(ssid->mode);
+ enum hostapd_hw_mode hw_mode;
+ struct hostapd_hw_modes *mode = NULL;
+ int i, obss_scan = 1;
+ u8 channel;
+ bool is_6ghz;
+
+ freq->freq = ssid->frequency;
+
+ if (ssid->mode == WPAS_MODE_IBSS && !ssid->fixed_freq) {
+ struct wpa_bss *bss = ibss_find_existing_bss(wpa_s, ssid);
+
+ if (bss) {
+ wpa_printf(MSG_DEBUG,
+ "IBSS already found in scan results, adjust control freq: %d",
+ bss->freq);
+ freq->freq = bss->freq;
+ obss_scan = 0;
+ }
+ }
+
+ hw_mode = ieee80211_freq_to_chan(freq->freq, &channel);
+ for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
+ if (wpa_s->hw.modes[i].mode == hw_mode &&
+ hw_mode_get_channel(&wpa_s->hw.modes[i], freq->freq,
+ NULL) != NULL) {
+ mode = &wpa_s->hw.modes[i];
+ break;
+ }
+ }
+
+ if (!mode)
+ return;
+
+ is_6ghz = is_6ghz_freq(freq->freq);
+
+ freq->ht_enabled = 0;
+ freq->vht_enabled = 0;
+ freq->he_enabled = 0;
+ freq->eht_enabled = 0;
+
+ if (!is_6ghz)
+ freq->ht_enabled = ibss_mesh_can_use_ht(wpa_s, ssid, mode);
+ if (freq->ht_enabled)
+ freq->vht_enabled = ibss_mesh_can_use_vht(wpa_s, ssid, mode);
+ if (freq->vht_enabled || is_6ghz)
+ freq->he_enabled = ibss_mesh_can_use_he(wpa_s, ssid, mode,
+ ieee80211_mode);
+ freq->channel = channel;
+ /* Setup higher BW only for 5 GHz */
+ if (mode->mode == HOSTAPD_MODE_IEEE80211A) {
+ ibss_mesh_select_40mhz(wpa_s, ssid, mode, freq, obss_scan);
+ if (!ibss_mesh_select_80_160mhz(wpa_s, ssid, mode, freq,
+ ieee80211_mode, is_6ghz))
+ freq->he_enabled = freq->vht_enabled = false;
+ }
+
+ if (freq->he_enabled)
+ freq->eht_enabled = ibss_mesh_can_use_eht(wpa_s, ssid, mode,
+ ieee80211_mode);
}
@@ -3178,7 +3264,13 @@
const u8 *cache_id = NULL;
const u8 *addr = bss->bssid;
- if (wpa_s->valid_links)
+ if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
+ (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_MLO) &&
+ !is_zero_ether_addr(bss->mld_addr))
+ addr = bss->mld_addr;
+
+ if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
+ wpa_s->valid_links)
addr = wpa_s->ap_mld_addr;
try_opportunistic = (ssid->proactive_key_caching < 0 ?
@@ -4754,7 +4846,7 @@
wpa_s->last_owe_group = 0;
if (ssid) {
ssid->owe_transition_bss_select_count = 0;
- wpa_s_setup_sae_pt(wpa_s->conf, ssid);
+ wpa_s_setup_sae_pt(wpa_s->conf, ssid, false);
}
if (wpa_s->connect_without_scan ||
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index 7a5f9cb..8753fba 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -1142,6 +1142,15 @@
# 0: No replay window, strict check (default)
# 1..2^32-1: number of packets that could be misordered
#
+# macsec_offload - Enable MACsec hardware offload
+#
+# This setting applies only when MACsec is in use, i.e.,
+# - the key server has decided to enable MACsec
+#
+# 0 = MACSEC_OFFLOAD_OFF (default)
+# 1 = MACSEC_OFFLOAD_PHY
+# 2 = MACSEC_OFFLOAD_MAC
+#
# macsec_port: IEEE 802.1X/MACsec port
# Port component of the SCI
# Range: 1-65534 (default: 1)
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index d364212..01b3148 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1002,6 +1002,8 @@
u8 ext_auth_ssid[SSID_MAX_LEN];
size_t ext_auth_ssid_len;
int ext_auth_key_mgmt;
+ u8 ext_auth_ap_mld_addr[ETH_ALEN];
+ bool ext_ml_auth;
int *sae_rejected_groups;
#endif /* CONFIG_SAE */
} sme;
@@ -1022,6 +1024,7 @@
unsigned int mesh_ht_enabled:1;
unsigned int mesh_vht_enabled:1;
unsigned int mesh_he_enabled:1;
+ unsigned int mesh_eht_enabled:1;
struct wpa_driver_mesh_join_params *mesh_params;
#ifdef CONFIG_PMKSA_CACHE_EXTERNAL
/* struct external_pmksa_cache::list */
@@ -1844,7 +1847,8 @@
int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
int wpas_get_ssid_pmf(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
int pmf_in_use(struct wpa_supplicant *wpa_s, const u8 *addr);
-void wpa_s_setup_sae_pt(struct wpa_config *conf, struct wpa_ssid *ssid);
+void wpa_s_setup_sae_pt(struct wpa_config *conf, struct wpa_ssid *ssid,
+ bool force);
bool wpas_is_sae_avoided(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid,
@@ -1862,6 +1866,7 @@
int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
int *freq_array, unsigned int len,
bool exclude_current);
+int disabled_freq(struct wpa_supplicant *wpa_s, int freq);
void wpas_network_reenabled(void *eloop_ctx, void *timeout_ctx);
diff --git a/wpa_supplicant/wpa_supplicant_template.conf b/wpa_supplicant/wpa_supplicant_template.conf
index a1846b1..cec26c4 100644
--- a/wpa_supplicant/wpa_supplicant_template.conf
+++ b/wpa_supplicant/wpa_supplicant_template.conf
@@ -8,3 +8,4 @@
oce=1
sae_pwe=2
p2p_optimize_listen_chan=1
+wowlan_disconnect_on_deinit=1
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index 0921f52..bba7777 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -1415,7 +1415,7 @@
}
-static void wpa_supplicant_store_ptk(void *ctx, u8 *addr, int cipher,
+static void wpa_supplicant_store_ptk(void *ctx, const u8 *addr, int cipher,
u32 life_time, const struct wpa_ptk *ptk)
{
struct wpa_supplicant *wpa_s = ctx;
diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c
index c3ef93b..600b3bc 100644
--- a/wpa_supplicant/wpas_kay.c
+++ b/wpa_supplicant/wpas_kay.c
@@ -98,6 +98,12 @@
}
+static int wpas_set_offload(void *wpa_s, u8 offload)
+{
+ return wpa_drv_set_offload(wpa_s, offload);
+}
+
+
static unsigned int conf_offset_val(enum confidentiality_offset co)
{
switch (co) {
@@ -219,6 +225,7 @@
kay_ctx->enable_protect_frames = wpas_enable_protect_frames;
kay_ctx->enable_encrypt = wpas_enable_encrypt;
kay_ctx->set_replay_protect = wpas_set_replay_protect;
+ kay_ctx->set_offload = wpas_set_offload;
kay_ctx->set_current_cipher_suite = wpas_set_current_cipher_suite;
kay_ctx->enable_controlled_port = wpas_enable_controlled_port;
kay_ctx->get_receive_lowest_pn = wpas_get_receive_lowest_pn;
@@ -239,7 +246,8 @@
kay_ctx->disable_transmit_sa = wpas_disable_transmit_sa;
res = ieee802_1x_kay_init(kay_ctx, policy, ssid->macsec_replay_protect,
- ssid->macsec_replay_window, ssid->macsec_port,
+ ssid->macsec_replay_window,
+ ssid->macsec_offload, ssid->macsec_port,
ssid->mka_priority, ssid->macsec_csindex,
wpa_s->ifname, wpa_s->own_addr);
/* ieee802_1x_kay_init() frees kay_ctx on failure */
@@ -262,32 +270,6 @@
}
-static int ieee802_1x_auth_get_session_id(struct wpa_supplicant *wpa_s,
- const u8 *addr, u8 *sid, size_t *len)
-{
- const u8 *session_id;
- size_t id_len, need_len;
-
- session_id = eapol_sm_get_session_id(wpa_s->eapol, &id_len);
- if (session_id == NULL) {
- wpa_printf(MSG_DEBUG,
- "Failed to get SessionID from EAPOL state machines");
- return -1;
- }
-
- need_len = 1 + 2 * 32 /* random size */;
- if (need_len > id_len) {
- wpa_printf(MSG_DEBUG, "EAP Session-Id not long enough");
- return -1;
- }
-
- os_memcpy(sid, session_id, need_len);
- *len = need_len;
-
- return 0;
-}
-
-
static int ieee802_1x_auth_get_msk(struct wpa_supplicant *wpa_s, const u8 *addr,
u8 *msk, size_t *len)
{
@@ -320,8 +302,8 @@
void * ieee802_1x_notify_create_actor(struct wpa_supplicant *wpa_s,
const u8 *peer_addr)
{
- u8 *sid;
- size_t sid_len = 128;
+ const u8 *sid;
+ size_t sid_len;
struct mka_key_name *ckn;
struct mka_key *cak;
struct mka_key *msk;
@@ -335,10 +317,9 @@
MACSTR, MAC2STR(peer_addr));
msk = os_zalloc(sizeof(*msk));
- sid = os_zalloc(sid_len);
ckn = os_zalloc(sizeof(*ckn));
cak = os_zalloc(sizeof(*cak));
- if (!msk || !sid || !ckn || !cak)
+ if (!msk || !ckn || !cak)
goto fail;
msk->len = DEFAULT_KEY_LEN;
@@ -347,8 +328,8 @@
goto fail;
}
- if (ieee802_1x_auth_get_session_id(wpa_s, wpa_s->bssid, sid, &sid_len))
- {
+ sid = eapol_sm_get_session_id(wpa_s->eapol, &sid_len);
+ if (!sid) {
wpa_printf(MSG_ERROR,
"IEEE 802.1X: Could not get EAP Session Id");
goto fail;
@@ -382,7 +363,6 @@
os_memset(msk, 0, sizeof(*msk));
os_free(msk);
}
- os_free(sid);
os_free(ckn);
if (cak) {
os_memset(cak, 0, sizeof(*cak));
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index de7dc98..cd94b64 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -1014,6 +1014,7 @@
*/
wpas_notify_wps_event_fail(wpa_s, &data.fail);
wpa_s->supp_pbc_active = false;
+ wpa_s->wps_overlap = false;
wpas_clear_wps(wpa_s);
}
@@ -1386,6 +1387,7 @@
}
wpa_s->supp_pbc_active = false;
+ wpa_s->wps_overlap = false;
wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_CANCEL);
wpa_s->after_wps = 0;