* [PATCH 01/15] wiphy: add driver quirk for the colocated scan flag
@ 2025-08-22 19:51 James Prestwood
2025-08-22 19:51 ` [PATCH 02/15] wiphy: add comments around the driver quirks James Prestwood
` (14 more replies)
0 siblings, 15 replies; 25+ messages in thread
From: James Prestwood @ 2025-08-22 19:51 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
Some drivers do not handle the colocated scan flag very well and this
results in BSS's not being seen in scans. This of course results in
very poor behavior.
This has been seen on ath11k specifically but after some
conversations [1] on the linux-wireless mailing list others have
reported issues with iwlwifi acting similarly. Since there are many
hardware variants that use both ath11k and iwlwifi this new quirk
isn't being forced to those drivers, but let users configure IWD to
disable the flag if needed.
[1] https://lore.kernel.org/linux-wireless/d1e75a08-047d-7947-d51a-2e486efead77@candelatech.com/
---
src/wiphy.c | 23 +++++++++++++++++------
src/wiphy.h | 1 +
2 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/src/wiphy.c b/src/wiphy.c
index fb544fe6..c7f2805e 100644
--- a/src/wiphy.c
+++ b/src/wiphy.c
@@ -75,6 +75,8 @@ enum driver_flag {
OWE_DISABLE = 0x8,
MULTICAST_RX_DISABLE = 0x10,
SAE_DISABLE = 0x20,
+ /* Disables use of the NL80211_SCAN_FLAG_COLOCATED_6GHZ flag in scans */
+ COLOCATED_SCAN_DISABLE = 0x40,
};
struct driver_flag_name {
@@ -103,12 +105,13 @@ static const struct driver_info driver_infos[] = {
};
static const struct driver_flag_name driver_flag_names[] = {
- { "DefaultInterface", DEFAULT_IF },
- { "ForcePae", FORCE_PAE },
- { "PowerSaveDisable", POWER_SAVE_DISABLE },
- { "OweDisable", OWE_DISABLE },
- { "MulticastRxDisable", MULTICAST_RX_DISABLE },
- { "SaeDisable", SAE_DISABLE },
+ { "DefaultInterface", DEFAULT_IF },
+ { "ForcePae", FORCE_PAE },
+ { "PowerSaveDisable", POWER_SAVE_DISABLE },
+ { "OweDisable", OWE_DISABLE },
+ { "MulticastRxDisable", MULTICAST_RX_DISABLE },
+ { "SaeDisable", SAE_DISABLE },
+ { "ColocatedScanDisable", COLOCATED_SCAN_DISABLE },
};
struct wiphy {
@@ -963,6 +966,11 @@ bool wiphy_supports_multicast_rx(const struct wiphy *wiphy)
!(wiphy->driver_flags & MULTICAST_RX_DISABLE);
}
+bool wiphy_supports_colocated_flag(const struct wiphy *wiphy)
+{
+ return !(wiphy->driver_flags & COLOCATED_SCAN_DISABLE);
+}
+
const uint8_t *wiphy_get_ht_capabilities(const struct wiphy *wiphy,
enum band_freq band,
size_t *size)
@@ -1382,6 +1390,9 @@ static void wiphy_print_basic_info(struct wiphy *wiphy)
if (wiphy->driver_flags & SAE_DISABLE)
flags = l_strv_append(flags, "SaeDisable");
+ if (wiphy->driver_flags & COLOCATED_SCAN_DISABLE)
+ flags = l_strv_append(flags, "ColocatedScanDisable");
+
joined = l_strjoinv(flags, ' ');
l_info("\tDriver Flags: %s", joined);
diff --git a/src/wiphy.h b/src/wiphy.h
index 9fcbdcd2..19d79405 100644
--- a/src/wiphy.h
+++ b/src/wiphy.h
@@ -144,6 +144,7 @@ bool wiphy_country_is_unknown(struct wiphy *wiphy);
bool wiphy_supports_uapsd(const struct wiphy *wiphy);
bool wiphy_supports_cmd_offchannel(const struct wiphy *wiphy);
bool wiphy_supports_multicast_rx(const struct wiphy *wiphy);
+bool wiphy_supports_colocated_flag(const struct wiphy *wiphy);
const uint8_t *wiphy_get_ht_capabilities(const struct wiphy *wiphy,
enum band_freq band,
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 02/15] wiphy: add comments around the driver quirks
2025-08-22 19:51 [PATCH 01/15] wiphy: add driver quirk for the colocated scan flag James Prestwood
@ 2025-08-22 19:51 ` James Prestwood
2025-08-22 19:51 ` [PATCH 03/15] scan: check support before using colocated flag James Prestwood
` (13 subsequent siblings)
14 siblings, 0 replies; 25+ messages in thread
From: James Prestwood @ 2025-08-22 19:51 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
---
src/wiphy.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/src/wiphy.c b/src/wiphy.c
index c7f2805e..b6774f69 100644
--- a/src/wiphy.c
+++ b/src/wiphy.c
@@ -69,11 +69,23 @@ static uint32_t work_ids;
static unsigned int wiphy_dump_id;
enum driver_flag {
+ /* Force the use of the default interface created by the kernel */
DEFAULT_IF = 0x1,
+ /*
+ * Force the use of the PAE socket rather than control port, even if
+ * control port is supported
+ */
FORCE_PAE = 0x2,
+ /* Disable power save on the adapter during initialization */
POWER_SAVE_DISABLE = 0x4,
+ /* Don't use OWE when connecting to open networks */
OWE_DISABLE = 0x8,
+ /* Disables multicast RX frame registration */
MULTICAST_RX_DISABLE = 0x10,
+ /*
+ * Don't use SAE (WPA3) when connecting to hybrid networks. This will
+ * prevent IWD from connecting to WPA3-only networks
+ */
SAE_DISABLE = 0x20,
/* Disables use of the NL80211_SCAN_FLAG_COLOCATED_6GHZ flag in scans */
COLOCATED_SCAN_DISABLE = 0x40,
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 03/15] scan: check support before using colocated flag
2025-08-22 19:51 [PATCH 01/15] wiphy: add driver quirk for the colocated scan flag James Prestwood
2025-08-22 19:51 ` [PATCH 02/15] wiphy: add comments around the driver quirks James Prestwood
@ 2025-08-22 19:51 ` James Prestwood
2025-08-22 19:51 ` [PATCH 04/15] monitor: add Cisco Meraki as a printable vendor James Prestwood
` (12 subsequent siblings)
14 siblings, 0 replies; 25+ messages in thread
From: James Prestwood @ 2025-08-22 19:51 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
---
src/scan.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/scan.c b/src/scan.c
index dfd667bb..d9f27c83 100644
--- a/src/scan.c
+++ b/src/scan.c
@@ -414,7 +414,8 @@ static struct l_genl_msg *scan_build_cmd(struct scan_context *sc,
if (params->ap_scan)
flags |= NL80211_SCAN_FLAG_AP;
- flags |= NL80211_SCAN_FLAG_COLOCATED_6GHZ;
+ if (wiphy_supports_colocated_flag(sc->wiphy))
+ flags |= NL80211_SCAN_FLAG_COLOCATED_6GHZ;
if (flags)
l_genl_msg_append_attr(msg, NL80211_ATTR_SCAN_FLAGS, 4, &flags);
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 04/15] monitor: add Cisco Meraki as a printable vendor
2025-08-22 19:51 [PATCH 01/15] wiphy: add driver quirk for the colocated scan flag James Prestwood
2025-08-22 19:51 ` [PATCH 02/15] wiphy: add comments around the driver quirks James Prestwood
2025-08-22 19:51 ` [PATCH 03/15] scan: check support before using colocated flag James Prestwood
@ 2025-08-22 19:51 ` James Prestwood
2025-08-22 19:51 ` [PATCH 05/15] vendor_quirks: initial skeleton James Prestwood
` (11 subsequent siblings)
14 siblings, 0 replies; 25+ messages in thread
From: James Prestwood @ 2025-08-22 19:51 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
---
monitor/nlmon.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/monitor/nlmon.c b/monitor/nlmon.c
index 7924f6f2..65437dc8 100644
--- a/monitor/nlmon.c
+++ b/monitor/nlmon.c
@@ -404,6 +404,7 @@ static const struct {
{ { 0x00, 0x50, 0xf2 }, "Microsoft" },
{ { 0x00, 0x90, 0x4c }, "Epigram" },
{ { 0x50, 0x6f, 0x9a }, "Wi-Fi Alliance" },
+ { { 0x00, 0x18, 0x0a }, "Cisco Meraki" },
{ }
};
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 05/15] vendor_quirks: initial skeleton
2025-08-22 19:51 [PATCH 01/15] wiphy: add driver quirk for the colocated scan flag James Prestwood
` (2 preceding siblings ...)
2025-08-22 19:51 ` [PATCH 04/15] monitor: add Cisco Meraki as a printable vendor James Prestwood
@ 2025-08-22 19:51 ` James Prestwood
2025-08-23 14:43 ` Marcel Holtmann
2025-08-26 14:56 ` Denis Kenzior
2025-08-22 19:51 ` [PATCH 06/15] vendor_quirks: add two new vendor quirks James Prestwood
` (10 subsequent siblings)
14 siblings, 2 replies; 25+ messages in thread
From: James Prestwood @ 2025-08-22 19:51 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
This module will provide a database for known issues or quirks with
wireless vendors. For now the list of quirks is limited to 32 as
that is the size returned in the bit mask. This could be extended
to 64 in the future if needed, but of course the goal is to never
reach that level.
The vendor_quirks() API is intended to be called from scan.c when
parsing vendor attributes. This will lookup any quirks associated
with the OUI provided and a mask of quirks will be returned. This
can be repeated against all the vendor OUI's seen in the scan. The
result is then a bitmask containing all quirks for that BSS. This
can then be referenced later during various operations in IWD.
---
Makefile.am | 2 ++
src/vendor_quirks.c | 53 +++++++++++++++++++++++++++++++++++++++++++++
src/vendor_quirks.h | 25 +++++++++++++++++++++
3 files changed, 80 insertions(+)
create mode 100644 src/vendor_quirks.c
create mode 100644 src/vendor_quirks.h
diff --git a/Makefile.am b/Makefile.am
index 92adfa6e..c01cd4c4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -274,6 +274,8 @@ src_iwd_SOURCES = src/main.c linux/nl80211.h src/iwd.h \
src/dpp.c \
src/udev.c \
src/pmksa.h src/pmksa.c \
+ src/vendor_quirks.h \
+ src/vendor_quirks.c \
$(eap_sources) \
$(builtin_sources)
diff --git a/src/vendor_quirks.c b/src/vendor_quirks.c
new file mode 100644
index 00000000..ccfcb444
--- /dev/null
+++ b/src/vendor_quirks.c
@@ -0,0 +1,53 @@
+/*
+ *
+ * Wireless daemon for Linux
+ *
+ * Copyright (C) 2025 Locus Robotics Corporation. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include <ell/ell.h>
+
+#include "src/vendor_quirks.h"
+
+static const struct {
+ uint8_t oui[3];
+ uint32_t quirks;
+} quirk_db[] = {
+ { }
+};
+
+uint32_t vendor_quirks(const uint8_t *oui)
+{
+ size_t i;
+ uint32_t ret = 0;
+
+ for (i = 0; i < L_ARRAY_SIZE(quirk_db); i++) {
+ if (memcmp(quirk_db[i].oui, oui, 3))
+ continue;
+
+ ret |= quirk_db[i].quirks;
+ }
+
+ return ret;
+}
diff --git a/src/vendor_quirks.h b/src/vendor_quirks.h
new file mode 100644
index 00000000..758073b3
--- /dev/null
+++ b/src/vendor_quirks.h
@@ -0,0 +1,25 @@
+/*
+ *
+ * Wireless daemon for Linux
+ *
+ * Copyright (C) 2025 Locus Robotics Corporation. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <stdint.h>
+
+uint32_t vendor_quirks(const uint8_t *oui);
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 06/15] vendor_quirks: add two new vendor quirks
2025-08-22 19:51 [PATCH 01/15] wiphy: add driver quirk for the colocated scan flag James Prestwood
` (3 preceding siblings ...)
2025-08-22 19:51 ` [PATCH 05/15] vendor_quirks: initial skeleton James Prestwood
@ 2025-08-22 19:51 ` James Prestwood
2025-08-23 14:46 ` Marcel Holtmann
2025-08-22 19:51 ` [PATCH 07/15] handshake: pass object to handshake_util_ap_ie_matches James Prestwood
` (9 subsequent siblings)
14 siblings, 1 reply; 25+ messages in thread
From: James Prestwood @ 2025-08-22 19:51 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
VENDOR_QUIRK_BAD_BSS_TM_CANDIDATE_LIST:
When a BSS requests a station roam it can optionally include a
list of BSS's that can be roamed to. IWD uses this list and only
scans on those frequencies. In some cases though the AP's list
contains very poor options and it would be better for IWD to
request a full neighbor report.
VENDOR_QUIRK_REPLAY_COUNTER_MISMATCH:
On some Aruba APs there is a mismatch in the replay counters
between what is seen in scans versus authentications/associations.
This difference is not allowed in the spec, therefore IWD will
not connect. This quirk is intended to relax that check.
---
src/vendor_quirks.c | 5 ++++-
src/vendor_quirks.h | 15 +++++++++++++++
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/src/vendor_quirks.c b/src/vendor_quirks.c
index ccfcb444..e005ba3b 100644
--- a/src/vendor_quirks.c
+++ b/src/vendor_quirks.c
@@ -34,7 +34,10 @@ static const struct {
uint8_t oui[3];
uint32_t quirks;
} quirk_db[] = {
- { }
+ /* Cisco Meraki */
+ { { 0x00, 0x18, 0x0a }, VENDOR_QUIRK_BAD_BSS_TM_CANDIDATE_LIST },
+ /* Hewlitt Packard, owns Aruba */
+ { { 0x00, 0x0b, 0x86 }, VENDOR_QUIRK_REPLAY_COUNTER_MISMATCH },
};
uint32_t vendor_quirks(const uint8_t *oui)
diff --git a/src/vendor_quirks.h b/src/vendor_quirks.h
index 758073b3..6c587d45 100644
--- a/src/vendor_quirks.h
+++ b/src/vendor_quirks.h
@@ -22,4 +22,19 @@
#include <stdint.h>
+enum vendor_quirk {
+ /*
+ * The neighbor list in a BSS Transition Management request from an AP
+ * contains a very sparse BSS list which generally leads to poor roaming
+ * decisions.
+ */
+ VENDOR_QUIRK_BAD_BSS_TM_CANDIDATE_LIST = 1 << 0,
+ /*
+ * The PTK/GTK replay counter differs between a scan and FT
+ * authentication. This is not allowable in the spec, but seen with
+ * certain vendors.
+ */
+ VENDOR_QUIRK_REPLAY_COUNTER_MISMATCH = 1 << 1,
+};
+
uint32_t vendor_quirks(const uint8_t *oui);
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 07/15] handshake: pass object to handshake_util_ap_ie_matches
2025-08-22 19:51 [PATCH 01/15] wiphy: add driver quirk for the colocated scan flag James Prestwood
` (4 preceding siblings ...)
2025-08-22 19:51 ` [PATCH 06/15] vendor_quirks: add two new vendor quirks James Prestwood
@ 2025-08-22 19:51 ` James Prestwood
2025-08-22 19:51 ` [PATCH 08/15] handshake: add vendor quirks into handshake object James Prestwood
` (8 subsequent siblings)
14 siblings, 0 replies; 25+ messages in thread
From: James Prestwood @ 2025-08-22 19:51 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
This is to prepare for supporting a vendor quirk, where we'll need
the handshake to lookup if the quirk to disable a specific check.
---
src/eapol.c | 2 +-
src/ft.c | 10 ++++++----
src/handshake.c | 3 ++-
src/handshake.h | 3 ++-
4 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/src/eapol.c b/src/eapol.c
index 6e37a54a..ab77746f 100644
--- a/src/eapol.c
+++ b/src/eapol.c
@@ -1810,7 +1810,7 @@ static void eapol_handle_ptk_3_of_4(struct eapol_sm *sm,
if ((rsne[1] != hs->authenticator_ie[1] ||
memcmp(rsne + 2, hs->authenticator_ie + 2, rsne[1])) &&
- !handshake_util_ap_ie_matches(&rsn_info,
+ !handshake_util_ap_ie_matches(hs, &rsn_info,
hs->authenticator_ie,
hs->wpa_ie))
goto error_ie_different;
diff --git a/src/ft.c b/src/ft.c
index d8bee74c..0d6be4d4 100644
--- a/src/ft.c
+++ b/src/ft.c
@@ -223,7 +223,8 @@ static bool ft_parse_associate_resp_frame(const uint8_t *frame, size_t frame_len
return true;
}
-static bool ft_verify_rsne(const uint8_t *rsne, const uint8_t *pmk_r0_name,
+static bool ft_verify_rsne(struct handshake_state *hs,
+ const uint8_t *rsne, const uint8_t *pmk_r0_name,
const uint8_t *authenticator_ie)
{
/*
@@ -253,7 +254,7 @@ static bool ft_verify_rsne(const uint8_t *rsne, const uint8_t *pmk_r0_name,
memcmp(msg2_rsne.pmkids, pmk_r0_name, 16))
return false;
- if (!handshake_util_ap_ie_matches(&msg2_rsne, authenticator_ie, false))
+ if (!handshake_util_ap_ie_matches(hs, &msg2_rsne, authenticator_ie, false))
return false;
return true;
@@ -301,7 +302,8 @@ static int parse_ies(struct handshake_state *hs,
is_rsn = hs->supplicant_ie != NULL;
if (is_rsn) {
- if (!ft_verify_rsne(rsne, hs->pmk_r0_name, authenticator_ie))
+ if (!ft_verify_rsne(hs, rsne, hs->pmk_r0_name,
+ authenticator_ie))
goto ft_error;
} else if (rsne)
goto ft_error;
@@ -480,7 +482,7 @@ int __ft_rx_associate(uint32_t ifindex, const uint8_t *frame, size_t frame_len)
memcmp(msg4_rsne.pmkids, hs->pmk_r1_name, 16))
return -EBADMSG;
- if (!handshake_util_ap_ie_matches(&msg4_rsne,
+ if (!handshake_util_ap_ie_matches(hs, &msg4_rsne,
hs->authenticator_ie,
false))
return -EBADMSG;
diff --git a/src/handshake.c b/src/handshake.c
index c469e6fa..92edac30 100644
--- a/src/handshake.c
+++ b/src/handshake.c
@@ -877,7 +877,8 @@ void handshake_state_set_igtk(struct handshake_state *s, const uint8_t *key,
* results vs the RSN/WPA IE obtained as part of the 4-way handshake. If they
* don't match, the EAPoL packet must be silently discarded.
*/
-bool handshake_util_ap_ie_matches(const struct ie_rsn_info *msg_info,
+bool handshake_util_ap_ie_matches(struct handshake_state *s,
+ const struct ie_rsn_info *msg_info,
const uint8_t *scan_ie, bool is_wpa)
{
struct ie_rsn_info scan_info;
diff --git a/src/handshake.h b/src/handshake.h
index c6e3c10b..b8891490 100644
--- a/src/handshake.h
+++ b/src/handshake.h
@@ -312,7 +312,8 @@ bool handshake_state_set_pmksa(struct handshake_state *s, struct pmksa *pmksa);
void handshake_state_cache_pmksa(struct handshake_state *s);
bool handshake_state_remove_pmksa(struct handshake_state *s);
-bool handshake_util_ap_ie_matches(const struct ie_rsn_info *msg_info,
+bool handshake_util_ap_ie_matches(struct handshake_state *s,
+ const struct ie_rsn_info *msg_info,
const uint8_t *scan_ie, bool is_wpa);
const uint8_t *handshake_util_find_kde(enum handshake_kde selector,
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 08/15] handshake: add vendor quirks into handshake object
2025-08-22 19:51 [PATCH 01/15] wiphy: add driver quirk for the colocated scan flag James Prestwood
` (5 preceding siblings ...)
2025-08-22 19:51 ` [PATCH 07/15] handshake: pass object to handshake_util_ap_ie_matches James Prestwood
@ 2025-08-22 19:51 ` James Prestwood
2025-08-22 19:51 ` [PATCH 09/15] scan: store vendor quirks in scan_bss James Prestwood
` (7 subsequent siblings)
14 siblings, 0 replies; 25+ messages in thread
From: James Prestwood @ 2025-08-22 19:51 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
---
src/handshake.c | 6 ++++++
src/handshake.h | 4 ++++
2 files changed, 10 insertions(+)
diff --git a/src/handshake.c b/src/handshake.c
index 92edac30..02f0e436 100644
--- a/src/handshake.c
+++ b/src/handshake.c
@@ -368,6 +368,12 @@ void handshake_state_set_vendor_ies(struct handshake_state *s,
}
}
+void handshake_state_set_vendor_quirks(struct handshake_state *s,
+ uint32_t quirks_mask)
+{
+ s->vendor_quirks = quirks_mask;
+}
+
void handshake_state_set_kh_ids(struct handshake_state *s,
const uint8_t *r0khid, size_t r0khid_len,
const uint8_t *r1khid)
diff --git a/src/handshake.h b/src/handshake.h
index b8891490..df0f8315 100644
--- a/src/handshake.h
+++ b/src/handshake.h
@@ -107,6 +107,7 @@ struct handshake_state {
uint8_t *authenticator_fte;
uint8_t *supplicant_fte;
uint8_t *vendor_ies;
+ uint32_t vendor_quirks;
size_t vendor_ies_len;
enum ie_rsn_cipher_suite pairwise_cipher;
enum ie_rsn_cipher_suite group_cipher;
@@ -237,6 +238,9 @@ void handshake_state_set_vendor_ies(struct handshake_state *s,
const struct iovec *iov,
size_t n_iovs);
+void handshake_state_set_vendor_quirks(struct handshake_state *s,
+ uint32_t quirks_mask);
+
void handshake_state_set_kh_ids(struct handshake_state *s,
const uint8_t *r0khid, size_t r0khid_len,
const uint8_t *r1khid);
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 09/15] scan: store vendor quirks in scan_bss
2025-08-22 19:51 [PATCH 01/15] wiphy: add driver quirk for the colocated scan flag James Prestwood
` (6 preceding siblings ...)
2025-08-22 19:51 ` [PATCH 08/15] handshake: add vendor quirks into handshake object James Prestwood
@ 2025-08-22 19:51 ` James Prestwood
2025-08-22 19:51 ` [PATCH 10/15] station: set vendor quirks into handshake object James Prestwood
` (6 subsequent siblings)
14 siblings, 0 replies; 25+ messages in thread
From: James Prestwood @ 2025-08-22 19:51 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
As each vendor IE is parsed lookup if there are any quirks associated
with it, and store these in a bit mask.
---
src/scan.c | 6 ++++++
src/scan.h | 1 +
2 files changed, 7 insertions(+)
diff --git a/src/scan.c b/src/scan.c
index d9f27c83..b87c4621 100644
--- a/src/scan.c
+++ b/src/scan.c
@@ -51,6 +51,7 @@
#include "src/mpdu.h"
#include "src/band.h"
#include "src/scan.h"
+#include "src/vendor_quirks.h"
/* User configurable options */
static double RANK_2G_FACTOR;
@@ -1221,6 +1222,11 @@ static void scan_parse_vendor_specific(struct scan_bss *bss, const void *data,
uint16_t cost_flags;
bool dgaf_disable;
+ if (L_WARN_ON(len < 3))
+ return;
+
+ bss->vendor_quirks |= vendor_quirks(data);
+
if (!bss->wpa && is_ie_wpa_ie(data, len)) {
bss->wpa = l_memdup(data - 2, len + 2);
return;
diff --git a/src/scan.h b/src/scan.h
index 4c1ebc21..b2a63505 100644
--- a/src/scan.h
+++ b/src/scan.h
@@ -79,6 +79,7 @@ struct scan_bss {
uint8_t *wfd; /* Concatenated WFD IEs */
ssize_t wfd_size; /* Size of Concatenated WFD IEs */
int8_t snr;
+ uint32_t vendor_quirks;
bool mde_present : 1;
bool cc_present : 1;
bool cap_rm_neighbor_report : 1;
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 10/15] station: set vendor quirks into handshake object
2025-08-22 19:51 [PATCH 01/15] wiphy: add driver quirk for the colocated scan flag James Prestwood
` (7 preceding siblings ...)
2025-08-22 19:51 ` [PATCH 09/15] scan: store vendor quirks in scan_bss James Prestwood
@ 2025-08-22 19:51 ` James Prestwood
2025-08-22 19:51 ` [PATCH 11/15] handshake: use vendor quirk to disable check of replay counters James Prestwood
` (5 subsequent siblings)
14 siblings, 0 replies; 25+ messages in thread
From: James Prestwood @ 2025-08-22 19:51 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
---
src/station.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/station.c b/src/station.c
index a4c3e7d1..339ee73c 100644
--- a/src/station.c
+++ b/src/station.c
@@ -1446,6 +1446,8 @@ static struct handshake_state *station_handshake_setup(struct station *station,
vendor_ies = network_info_get_extra_ies(info, bss, &iov_elems);
handshake_state_set_vendor_ies(hs, vendor_ies, iov_elems);
+ handshake_state_set_vendor_quirks(hs, bss->vendor_quirks);
+
/*
* It can't hurt to try the FILS IP Address Assignment independent of
* which auth-proto is actually used.
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 11/15] handshake: use vendor quirk to disable check of replay counters
2025-08-22 19:51 [PATCH 01/15] wiphy: add driver quirk for the colocated scan flag James Prestwood
` (8 preceding siblings ...)
2025-08-22 19:51 ` [PATCH 10/15] station: set vendor quirks into handshake object James Prestwood
@ 2025-08-22 19:51 ` James Prestwood
2025-08-22 19:51 ` [PATCH 12/15] station: get neighbor report on BSS TM request James Prestwood
` (4 subsequent siblings)
14 siblings, 0 replies; 25+ messages in thread
From: James Prestwood @ 2025-08-22 19:51 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood, Michael Johnson
This has been a long standing issue on Aruba APs where the scan
IEs differ from the IEs received during FT. For compatibility we
have been carrying a patch to disable the replay counter check but
this isn't something that was ever acceptable for upstream. Now
with the addition of vendor quirks this check can be disabled only
for the OUI of Aruba APs.
Reported-by: Michael Johnson <mjohnson459@gmail.com>
Co-authored-by: Michael Johnson <<mjohnson459@gmail.com>
---
src/handshake.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/src/handshake.c b/src/handshake.c
index 02f0e436..6db897bf 100644
--- a/src/handshake.c
+++ b/src/handshake.c
@@ -44,6 +44,7 @@
#include "src/erp.h"
#include "src/band.h"
#include "src/pmksa.h"
+#include "src/vendor_quirks.h"
static inline unsigned int n_ecc_groups(void)
{
@@ -914,11 +915,15 @@ bool handshake_util_ap_ie_matches(struct handshake_state *s,
if (msg_info->no_pairwise != scan_info.no_pairwise)
return false;
- if (msg_info->ptksa_replay_counter != scan_info.ptksa_replay_counter)
- return false;
+ if (!(s->vendor_quirks & VENDOR_QUIRK_REPLAY_COUNTER_MISMATCH)) {
+ if (msg_info->ptksa_replay_counter !=
+ scan_info.ptksa_replay_counter)
+ return false;
- if (msg_info->gtksa_replay_counter != scan_info.gtksa_replay_counter)
- return false;
+ if (msg_info->gtksa_replay_counter !=
+ scan_info.gtksa_replay_counter)
+ return false;
+ }
if (msg_info->mfpr != scan_info.mfpr)
return false;
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 12/15] station: get neighbor report on BSS TM request
2025-08-22 19:51 [PATCH 01/15] wiphy: add driver quirk for the colocated scan flag James Prestwood
` (9 preceding siblings ...)
2025-08-22 19:51 ` [PATCH 11/15] handshake: use vendor quirk to disable check of replay counters James Prestwood
@ 2025-08-22 19:51 ` James Prestwood
2025-08-22 19:51 ` [PATCH 13/15] station: check vendor quirk for BSS TM request candidate list James Prestwood
` (3 subsequent siblings)
14 siblings, 0 replies; 25+ messages in thread
From: James Prestwood @ 2025-08-22 19:51 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
If a BSS is requesting IWD roam elsewhere but does not include a
preferred candidate list try getting a neighbor report before doing
a full scan.
If the limited scan based on the candidate list comes up empty this
would previously result in IWD giving up on the AP roam entirely.
This patch also improves that behavior slightly by doing a full
scan afterwards as a last ditch effort. If no BSS's are found after
that, IWD will give up on the AP roam.
---
src/station.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/src/station.c b/src/station.c
index 339ee73c..4919f89e 100644
--- a/src/station.c
+++ b/src/station.c
@@ -2435,8 +2435,16 @@ static void station_roam_failed(struct station *station)
* We were told by the AP to roam, but failed. Try ourselves or
* wait for the AP to tell us to roam again
*/
- if (station->ap_directed_roaming)
+ if (station->ap_directed_roaming) {
+ /*
+ * The candidate list from the AP (or neighbor report) found
+ * no BSS's. Force a full scan
+ */
+ if (!station->roam_scan_full)
+ goto full_scan;
+
goto delayed_retry;
+ }
/*
* If we tried a limited scan, failed and the signal is still low,
@@ -2448,6 +2456,8 @@ static void station_roam_failed(struct station *station)
* the scan here, so that the destroy callback is not called
* after the return of this function
*/
+full_scan:
+ station_debug_event(station, "full-roam-scan");
scan_cancel(netdev_get_wdev_id(station->netdev),
station->roam_scan_id);
@@ -3373,7 +3383,15 @@ static void station_ap_directed_roam(struct station *station,
station_neighbor_report_cb(station->netdev, 0, body + pos,
body_len - pos, station);
} else {
- l_debug("roam: AP did not include a preferred candidate list");
+ if (station->connected_bss->cap_rm_neighbor_report) {
+ if (!netdev_neighbor_report_req(station->netdev,
+ station_neighbor_report_cb))
+ return;
+
+ l_warn("failed to request neighbor report!");
+ }
+
+ l_debug("full scan after BSS transition request");
if (station_roam_scan(station, NULL) < 0)
station_roam_failed(station);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 13/15] station: check vendor quirk for BSS TM request candidate list
2025-08-22 19:51 [PATCH 01/15] wiphy: add driver quirk for the colocated scan flag James Prestwood
` (10 preceding siblings ...)
2025-08-22 19:51 ` [PATCH 12/15] station: get neighbor report on BSS TM request James Prestwood
@ 2025-08-22 19:51 ` James Prestwood
2025-08-23 14:48 ` Marcel Holtmann
2025-08-22 19:51 ` [PATCH 14/15] station: clear roam_freqs on delayed roam James Prestwood
` (2 subsequent siblings)
14 siblings, 1 reply; 25+ messages in thread
From: James Prestwood @ 2025-08-22 19:51 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
If the AP vendor has known issues with the preferred candidate list
ignore it and jump directly to requesting a neighbor report.
---
src/station.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/station.c b/src/station.c
index 4919f89e..3424964d 100644
--- a/src/station.c
+++ b/src/station.c
@@ -64,6 +64,7 @@
#include "src/eap-tls-common.h"
#include "src/storage.h"
#include "src/pmksa.h"
+#include "src/vendor_quirks.h"
#define STATION_RECENT_NETWORK_LIMIT 5
#define STATION_RECENT_FREQS_LIMIT 5
@@ -3378,7 +3379,9 @@ static void station_ap_directed_roam(struct station *station,
l_timeout_remove(station->roam_trigger_timeout);
station->roam_trigger_timeout = NULL;
- if (req_mode & WNM_REQUEST_MODE_PREFERRED_CANDIDATE_LIST) {
+ if ((req_mode & WNM_REQUEST_MODE_PREFERRED_CANDIDATE_LIST) &&
+ !(station->connected_bss->vendor_quirks &
+ VENDOR_QUIRK_BAD_BSS_TM_CANDIDATE_LIST)) {
l_debug("roam: AP sent a preferred candidate list");
station_neighbor_report_cb(station->netdev, 0, body + pos,
body_len - pos, station);
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 14/15] station: clear roam_freqs on delayed roam
2025-08-22 19:51 [PATCH 01/15] wiphy: add driver quirk for the colocated scan flag James Prestwood
` (11 preceding siblings ...)
2025-08-22 19:51 ` [PATCH 13/15] station: check vendor quirk for BSS TM request candidate list James Prestwood
@ 2025-08-22 19:51 ` James Prestwood
2025-08-26 15:00 ` Denis Kenzior
2025-08-22 19:51 ` [PATCH 15/15] auto-t: add AP roam test for bad neighbor reports/candidate lists James Prestwood
2025-08-26 14:47 ` [PATCH 01/15] wiphy: add driver quirk for the colocated scan flag Denis Kenzior
14 siblings, 1 reply; 25+ messages in thread
From: James Prestwood @ 2025-08-22 19:51 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
If there were no BSS candidates found after trying to roam make
sure the old roam_freqs list gets cleared so IWD doesn't end up
scanning potentially old frequencies on the next retry.
---
src/station.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/station.c b/src/station.c
index 3424964d..968aafb0 100644
--- a/src/station.c
+++ b/src/station.c
@@ -2407,6 +2407,11 @@ static void station_roam_retry(struct station *station)
station->roam_scan_full = false;
station->ap_directed_roaming = false;
+ if (station->roam_freqs) {
+ scan_freq_set_free(station->roam_freqs);
+ station->roam_freqs = NULL;
+ }
+
if (station->signal_low)
station_roam_timeout_rearm(station, roam_retry_interval);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 15/15] auto-t: add AP roam test for bad neighbor reports/candidate lists
2025-08-22 19:51 [PATCH 01/15] wiphy: add driver quirk for the colocated scan flag James Prestwood
` (12 preceding siblings ...)
2025-08-22 19:51 ` [PATCH 14/15] station: clear roam_freqs on delayed roam James Prestwood
@ 2025-08-22 19:51 ` James Prestwood
2025-08-26 14:47 ` [PATCH 01/15] wiphy: add driver quirk for the colocated scan flag Denis Kenzior
14 siblings, 0 replies; 25+ messages in thread
From: James Prestwood @ 2025-08-22 19:51 UTC (permalink / raw)
To: iwd; +Cc: James Prestwood
---
.../testAPRoam/bad_neighbor_report_test.py | 133 ++++++++++++++++++
1 file changed, 133 insertions(+)
create mode 100644 autotests/testAPRoam/bad_neighbor_report_test.py
diff --git a/autotests/testAPRoam/bad_neighbor_report_test.py b/autotests/testAPRoam/bad_neighbor_report_test.py
new file mode 100644
index 00000000..4bf3b63b
--- /dev/null
+++ b/autotests/testAPRoam/bad_neighbor_report_test.py
@@ -0,0 +1,133 @@
+#!/usr/bin/python3
+
+import unittest
+import sys
+
+sys.path.append('../util')
+import iwd
+from iwd import IWD
+from iwd import NetworkType
+
+from hostapd import HostapdCLI
+
+class Test(unittest.TestCase):
+ def initial_connection(self):
+ ordered_network = self.device.get_ordered_network('TestAPRoam')
+
+ self.assertEqual(ordered_network.type, NetworkType.psk)
+
+ condition = 'not obj.connected'
+ self.wd.wait_for_object_condition(ordered_network.network_object, condition)
+
+ self.device.connect_bssid(self.bss_hostapd[0].bssid)
+
+ condition = 'obj.state == DeviceState.connected'
+ self.wd.wait_for_object_condition(self.device, condition)
+
+ self.bss_hostapd[0].wait_for_event('AP-STA-CONNECTED')
+
+ self.assertFalse(self.bss_hostapd[1].list_sta())
+
+ def test_full_scan(self):
+ """
+ Tests that IWD first tries a limited scan, then a full scan after
+ an AP directed roam. After the full scan yields no results IWD
+ should stop trying to roam.
+ """
+ self.initial_connection()
+
+ # Disable other APs, so the scans come up empty
+ self.bss_hostapd[1].disable()
+ self.bss_hostapd[2].disable()
+
+ # Send a bad candidate list with the BSS TM request which contains a
+ # channel with no AP operating on it.
+ self.bss_hostapd[0].send_bss_transition(
+ self.device.address,
+ [(self.bss_hostapd[1].bssid, "8f0000005105060603000000")]
+ )
+ self.device.wait_for_event("roam-scan-triggered")
+ self.device.wait_for_event("no-roam-candidates")
+ # IWD should then trigger a full scan
+ self.device.wait_for_event("full-roam-scan")
+ self.device.wait_for_event("no-roam-candidates", timeout=30)
+
+ # IWD should not trigger a roam again after the above 2 failures.
+ with self.assertRaises(TimeoutError):
+ self.device.wait_for_event("roam-scan-triggered", timeout=60)
+
+ def test_bad_candidate_list(self):
+ """
+ Tests behavior when the AP sends a candidate list but the scan
+ finds no BSS's. IWD should fall back to a full scan after.
+ """
+ self.initial_connection()
+
+ # Send a bad candidate list with the BSS TM request which contains a
+ # channel with no AP operating on it.
+ self.bss_hostapd[0].send_bss_transition(
+ self.device.address,
+ [(self.bss_hostapd[1].bssid, "8f0000005105060603000000")]
+ )
+ self.device.wait_for_event("roam-scan-triggered")
+ self.device.wait_for_event("no-roam-candidates")
+ # IWD should then trigger a full scan
+ self.device.wait_for_event("full-roam-scan")
+ self.device.wait_for_event("roaming", timeout=30)
+ self.device.wait_for_event("connected")
+
+ def test_bad_neighbor_report(self):
+ """
+ Tests behavior when the AP sends no candidate list. IWD should
+ request a neighbor report. If the limited scan yields no BSS's IWD
+ should fall back to a full scan.
+ """
+
+ # Set a bad neighbor (channel that no AP is on) to force the limited
+ # roam scan to fail
+ self.bss_hostapd[0].set_neighbor(
+ self.bss_hostapd[1].bssid,
+ "TestAPRoam",
+ '%s8f000000%s%s060603000000' % (self.bss_hostapd[1].bssid.replace(':', ''), "51", "0b")
+ )
+
+ self.initial_connection()
+
+ self.bss_hostapd[0].send_bss_transition(self.device.address, [])
+ self.device.wait_for_event("roam-scan-triggered")
+ # The AP will have sent a neighbor report with a single BSS but on
+ # channel 11 which no AP is on. This should result in a limited scan
+ # picking up no candidates.
+ self.device.wait_for_event("no-roam-candidates", timeout=30)
+ # IWD should then trigger a full scan
+ self.device.wait_for_event("full-roam-scan")
+ self.device.wait_for_event("roaming", timeout=30)
+ self.device.wait_for_event("connected")
+
+ def setUp(self):
+ self.wd = IWD(True)
+
+ devices = self.wd.list_devices(1)
+ self.device = devices[0]
+
+ def tearDown(self):
+ self.wd = None
+ self.device = None
+
+ for hapd in self.bss_hostapd:
+ hapd.reload()
+
+ @classmethod
+ def setUpClass(cls):
+ IWD.copy_to_storage('TestAPRoam.psk')
+
+ cls.bss_hostapd = [ HostapdCLI(config='ssid1.conf'),
+ HostapdCLI(config='ssid2.conf'),
+ HostapdCLI(config='ssid3.conf') ]
+
+ @classmethod
+ def tearDownClass(cls):
+ IWD.clear_storage()
+
+if __name__ == '__main__':
+ unittest.main(exit=True)
--
2.34.1
^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH 05/15] vendor_quirks: initial skeleton
2025-08-22 19:51 ` [PATCH 05/15] vendor_quirks: initial skeleton James Prestwood
@ 2025-08-23 14:43 ` Marcel Holtmann
2025-08-25 14:31 ` James Prestwood
2025-08-26 14:56 ` Denis Kenzior
1 sibling, 1 reply; 25+ messages in thread
From: Marcel Holtmann @ 2025-08-23 14:43 UTC (permalink / raw)
To: James Prestwood; +Cc: iwd
Hi James,
> This module will provide a database for known issues or quirks with
> wireless vendors. For now the list of quirks is limited to 32 as
> that is the size returned in the bit mask. This could be extended
> to 64 in the future if needed, but of course the goal is to never
> reach that level.
>
> The vendor_quirks() API is intended to be called from scan.c when
> parsing vendor attributes. This will lookup any quirks associated
> with the OUI provided and a mask of quirks will be returned. This
> can be repeated against all the vendor OUI's seen in the scan. The
> result is then a bitmask containing all quirks for that BSS. This
> can then be referenced later during various operations in IWD.
> ---
> Makefile.am | 2 ++
> src/vendor_quirks.c | 53 +++++++++++++++++++++++++++++++++++++++++++++
> src/vendor_quirks.h | 25 +++++++++++++++++++++
> 3 files changed, 80 insertions(+)
> create mode 100644 src/vendor_quirks.c
> create mode 100644 src/vendor_quirks.h
>
> diff --git a/Makefile.am b/Makefile.am
> index 92adfa6e..c01cd4c4 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -274,6 +274,8 @@ src_iwd_SOURCES = src/main.c linux/nl80211.h src/iwd.h \
> src/dpp.c \
> src/udev.c \
> src/pmksa.h src/pmksa.c \
> + src/vendor_quirks.h \
> + src/vendor_quirks.c \
> $(eap_sources) \
> $(builtin_sources)
>
> diff --git a/src/vendor_quirks.c b/src/vendor_quirks.c
> new file mode 100644
> index 00000000..ccfcb444
> --- /dev/null
> +++ b/src/vendor_quirks.c
> @@ -0,0 +1,53 @@
> +/*
> + *
> + * Wireless daemon for Linux
> + *
> + * Copyright (C) 2025 Locus Robotics Corporation. All rights reserved.
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
> + *
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include <config.h>
> +#endif
> +
> +#include <string.h>
> +
> +#include <ell/ell.h>
> +
> +#include "src/vendor_quirks.h"
> +
> +static const struct {
> + uint8_t oui[3];
> + uint32_t quirks;
> +} quirk_db[] = {
> + { }
> +};
> +
> +uint32_t vendor_quirks(const uint8_t *oui)
> +{
> + size_t i;
> + uint32_t ret = 0;
> +
> + for (i = 0; i < L_ARRAY_SIZE(quirk_db); i++) {
> + if (memcmp(quirk_db[i].oui, oui, 3))
> + continue;
> +
> + ret |= quirk_db[i].quirks;
> + }
if you are using an empty {} entry to signal end of the array, then it makes no sense to also use L_ARRAY_SIZE.
Regards
Marcel
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 06/15] vendor_quirks: add two new vendor quirks
2025-08-22 19:51 ` [PATCH 06/15] vendor_quirks: add two new vendor quirks James Prestwood
@ 2025-08-23 14:46 ` Marcel Holtmann
2025-08-25 14:32 ` James Prestwood
0 siblings, 1 reply; 25+ messages in thread
From: Marcel Holtmann @ 2025-08-23 14:46 UTC (permalink / raw)
To: James Prestwood; +Cc: iwd
Hi James,
> VENDOR_QUIRK_BAD_BSS_TM_CANDIDATE_LIST:
> When a BSS requests a station roam it can optionally include a
> list of BSS's that can be roamed to. IWD uses this list and only
> scans on those frequencies. In some cases though the AP's list
> contains very poor options and it would be better for IWD to
> request a full neighbor report.
>
> VENDOR_QUIRK_REPLAY_COUNTER_MISMATCH:
> On some Aruba APs there is a mismatch in the replay counters
> between what is seen in scans versus authentications/associations.
> This difference is not allowed in the spec, therefore IWD will
> not connect. This quirk is intended to relax that check.
> ---
> src/vendor_quirks.c | 5 ++++-
> src/vendor_quirks.h | 15 +++++++++++++++
> 2 files changed, 19 insertions(+), 1 deletion(-)
>
> diff --git a/src/vendor_quirks.c b/src/vendor_quirks.c
> index ccfcb444..e005ba3b 100644
> --- a/src/vendor_quirks.c
> +++ b/src/vendor_quirks.c
> @@ -34,7 +34,10 @@ static const struct {
> uint8_t oui[3];
> uint32_t quirks;
> } quirk_db[] = {
> - { }
> + /* Cisco Meraki */
> + { { 0x00, 0x18, 0x0a }, VENDOR_QUIRK_BAD_BSS_TM_CANDIDATE_LIST },
> + /* Hewlitt Packard, owns Aruba */
> + { { 0x00, 0x0b, 0x86 }, VENDOR_QUIRK_REPLAY_COUNTER_MISMATCH },
> };
are you sure the name is Hewlitt ;)
Regards
Marcel
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 13/15] station: check vendor quirk for BSS TM request candidate list
2025-08-22 19:51 ` [PATCH 13/15] station: check vendor quirk for BSS TM request candidate list James Prestwood
@ 2025-08-23 14:48 ` Marcel Holtmann
2025-08-25 14:37 ` James Prestwood
0 siblings, 1 reply; 25+ messages in thread
From: Marcel Holtmann @ 2025-08-23 14:48 UTC (permalink / raw)
To: James Prestwood; +Cc: iwd
Hi James,
> If the AP vendor has known issues with the preferred candidate list
> ignore it and jump directly to requesting a neighbor report.
> ---
> src/station.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/src/station.c b/src/station.c
> index 4919f89e..3424964d 100644
> --- a/src/station.c
> +++ b/src/station.c
> @@ -64,6 +64,7 @@
> #include "src/eap-tls-common.h"
> #include "src/storage.h"
> #include "src/pmksa.h"
> +#include "src/vendor_quirks.h"
>
> #define STATION_RECENT_NETWORK_LIMIT 5
> #define STATION_RECENT_FREQS_LIMIT 5
> @@ -3378,7 +3379,9 @@ static void station_ap_directed_roam(struct station *station,
> l_timeout_remove(station->roam_trigger_timeout);
> station->roam_trigger_timeout = NULL;
>
> - if (req_mode & WNM_REQUEST_MODE_PREFERRED_CANDIDATE_LIST) {
> + if ((req_mode & WNM_REQUEST_MODE_PREFERRED_CANDIDATE_LIST) &&
> + !(station->connected_bss->vendor_quirks &
> + VENDOR_QUIRK_BAD_BSS_TM_CANDIDATE_LIST)) {
this is unreadable in the long term. I would either add a variable or add a helper for the quirks.
As a side note, you might want to actually somewhere print the quirks which are active. Otherwise your debugging in the future will become a nightmare.
Regards
Marcel
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 05/15] vendor_quirks: initial skeleton
2025-08-23 14:43 ` Marcel Holtmann
@ 2025-08-25 14:31 ` James Prestwood
0 siblings, 0 replies; 25+ messages in thread
From: James Prestwood @ 2025-08-25 14:31 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: iwd
Hi Marcel,
On 8/23/25 7:43 AM, Marcel Holtmann wrote:
> Hi James,
>
>> This module will provide a database for known issues or quirks with
>> wireless vendors. For now the list of quirks is limited to 32 as
>> that is the size returned in the bit mask. This could be extended
>> to 64 in the future if needed, but of course the goal is to never
>> reach that level.
>>
>> The vendor_quirks() API is intended to be called from scan.c when
>> parsing vendor attributes. This will lookup any quirks associated
>> with the OUI provided and a mask of quirks will be returned. This
>> can be repeated against all the vendor OUI's seen in the scan. The
>> result is then a bitmask containing all quirks for that BSS. This
>> can then be referenced later during various operations in IWD.
>> ---
>> Makefile.am | 2 ++
>> src/vendor_quirks.c | 53 +++++++++++++++++++++++++++++++++++++++++++++
>> src/vendor_quirks.h | 25 +++++++++++++++++++++
>> 3 files changed, 80 insertions(+)
>> create mode 100644 src/vendor_quirks.c
>> create mode 100644 src/vendor_quirks.h
>>
>> diff --git a/Makefile.am b/Makefile.am
>> index 92adfa6e..c01cd4c4 100644
>> --- a/Makefile.am
>> +++ b/Makefile.am
>> @@ -274,6 +274,8 @@ src_iwd_SOURCES = src/main.c linux/nl80211.h src/iwd.h \
>> src/dpp.c \
>> src/udev.c \
>> src/pmksa.h src/pmksa.c \
>> + src/vendor_quirks.h \
>> + src/vendor_quirks.c \
>> $(eap_sources) \
>> $(builtin_sources)
>>
>> diff --git a/src/vendor_quirks.c b/src/vendor_quirks.c
>> new file mode 100644
>> index 00000000..ccfcb444
>> --- /dev/null
>> +++ b/src/vendor_quirks.c
>> @@ -0,0 +1,53 @@
>> +/*
>> + *
>> + * Wireless daemon for Linux
>> + *
>> + * Copyright (C) 2025 Locus Robotics Corporation. All rights reserved.
>> + *
>> + * This library is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU Lesser General Public
>> + * License as published by the Free Software Foundation; either
>> + * version 2.1 of the License, or (at your option) any later version.
>> + *
>> + * This library is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
>> + * Lesser General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU Lesser General Public
>> + * License along with this library; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
>> + *
>> + */
>> +
>> +#ifdef HAVE_CONFIG_H
>> +#include <config.h>
>> +#endif
>> +
>> +#include <string.h>
>> +
>> +#include <ell/ell.h>
>> +
>> +#include "src/vendor_quirks.h"
>> +
>> +static const struct {
>> + uint8_t oui[3];
>> + uint32_t quirks;
>> +} quirk_db[] = {
>> + { }
>> +};
>> +
>> +uint32_t vendor_quirks(const uint8_t *oui)
>> +{
>> + size_t i;
>> + uint32_t ret = 0;
>> +
>> + for (i = 0; i < L_ARRAY_SIZE(quirk_db); i++) {
>> + if (memcmp(quirk_db[i].oui, oui, 3))
>> + continue;
>> +
>> + ret |= quirk_db[i].quirks;
>> + }
> if you are using an empty {} entry to signal end of the array, then it makes no sense to also use L_ARRAY_SIZE.
I'm not, it was just to get the skeleton module to compile. The compiler
wasn't letting me define an empty static array like that. In subsequent
patches that empty entry gets replaced with real data.
Thanks,
James
>
> Regards
>
> Marcel
>
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 06/15] vendor_quirks: add two new vendor quirks
2025-08-23 14:46 ` Marcel Holtmann
@ 2025-08-25 14:32 ` James Prestwood
0 siblings, 0 replies; 25+ messages in thread
From: James Prestwood @ 2025-08-25 14:32 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: iwd
Hi Marcel,
On 8/23/25 7:46 AM, Marcel Holtmann wrote:
> Hi James,
>
>> VENDOR_QUIRK_BAD_BSS_TM_CANDIDATE_LIST:
>> When a BSS requests a station roam it can optionally include a
>> list of BSS's that can be roamed to. IWD uses this list and only
>> scans on those frequencies. In some cases though the AP's list
>> contains very poor options and it would be better for IWD to
>> request a full neighbor report.
>>
>> VENDOR_QUIRK_REPLAY_COUNTER_MISMATCH:
>> On some Aruba APs there is a mismatch in the replay counters
>> between what is seen in scans versus authentications/associations.
>> This difference is not allowed in the spec, therefore IWD will
>> not connect. This quirk is intended to relax that check.
>> ---
>> src/vendor_quirks.c | 5 ++++-
>> src/vendor_quirks.h | 15 +++++++++++++++
>> 2 files changed, 19 insertions(+), 1 deletion(-)
>>
>> diff --git a/src/vendor_quirks.c b/src/vendor_quirks.c
>> index ccfcb444..e005ba3b 100644
>> --- a/src/vendor_quirks.c
>> +++ b/src/vendor_quirks.c
>> @@ -34,7 +34,10 @@ static const struct {
>> uint8_t oui[3];
>> uint32_t quirks;
>> } quirk_db[] = {
>> - { }
>> + /* Cisco Meraki */
>> + { { 0x00, 0x18, 0x0a }, VENDOR_QUIRK_BAD_BSS_TM_CANDIDATE_LIST },
>> + /* Hewlitt Packard, owns Aruba */
>> + { { 0x00, 0x0b, 0x86 }, VENDOR_QUIRK_REPLAY_COUNTER_MISMATCH },
>> };
> are you sure the name is Hewlitt ;)
Whoops, will fix in v2
>
> Regards
>
> Marcel
>
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 13/15] station: check vendor quirk for BSS TM request candidate list
2025-08-23 14:48 ` Marcel Holtmann
@ 2025-08-25 14:37 ` James Prestwood
0 siblings, 0 replies; 25+ messages in thread
From: James Prestwood @ 2025-08-25 14:37 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: iwd
Hi Marcel,
On 8/23/25 7:48 AM, Marcel Holtmann wrote:
> Hi James,
>
>> If the AP vendor has known issues with the preferred candidate list
>> ignore it and jump directly to requesting a neighbor report.
>> ---
>> src/station.c | 5 ++++-
>> 1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/src/station.c b/src/station.c
>> index 4919f89e..3424964d 100644
>> --- a/src/station.c
>> +++ b/src/station.c
>> @@ -64,6 +64,7 @@
>> #include "src/eap-tls-common.h"
>> #include "src/storage.h"
>> #include "src/pmksa.h"
>> +#include "src/vendor_quirks.h"
>>
>> #define STATION_RECENT_NETWORK_LIMIT 5
>> #define STATION_RECENT_FREQS_LIMIT 5
>> @@ -3378,7 +3379,9 @@ static void station_ap_directed_roam(struct station *station,
>> l_timeout_remove(station->roam_trigger_timeout);
>> station->roam_trigger_timeout = NULL;
>>
>> - if (req_mode & WNM_REQUEST_MODE_PREFERRED_CANDIDATE_LIST) {
>> + if ((req_mode & WNM_REQUEST_MODE_PREFERRED_CANDIDATE_LIST) &&
>> + !(station->connected_bss->vendor_quirks &
>> + VENDOR_QUIRK_BAD_BSS_TM_CANDIDATE_LIST)) {
> this is unreadable in the long term. I would either add a variable or add a helper for the quirks.
Agreed. I think a variable makes the most sense. I contemplated
something like:
vendor_quirk_is_set()
But you'd need to pass in the mask/enum which probably ends up eating up
more characters anyways. Instead I can just do a local variable:
bool ignore_candidates = station->connected_bss->vendor_quirks &
VENDOR_QUIRK_BAD_BSS_TM_CANDIDATE_LIST;
>
> As a side note, you might want to actually somewhere print the quirks which are active. Otherwise your debugging in the future will become a nightmare.
Good idea, I could probably do this upon connecting and when roams
finish. Its probably a bit too verbose for scan results.
Thanks,
James
>
> Regards
>
> Marcel
>
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 01/15] wiphy: add driver quirk for the colocated scan flag
2025-08-22 19:51 [PATCH 01/15] wiphy: add driver quirk for the colocated scan flag James Prestwood
` (13 preceding siblings ...)
2025-08-22 19:51 ` [PATCH 15/15] auto-t: add AP roam test for bad neighbor reports/candidate lists James Prestwood
@ 2025-08-26 14:47 ` Denis Kenzior
2025-08-26 15:24 ` James Prestwood
14 siblings, 1 reply; 25+ messages in thread
From: Denis Kenzior @ 2025-08-26 14:47 UTC (permalink / raw)
To: James Prestwood, iwd
Hi James,
On 8/22/25 2:51 PM, James Prestwood wrote:
> Some drivers do not handle the colocated scan flag very well and this
> results in BSS's not being seen in scans. This of course results in
> very poor behavior.
>
> This has been seen on ath11k specifically but after some
> conversations [1] on the linux-wireless mailing list others have
> reported issues with iwlwifi acting similarly. Since there are many
> hardware variants that use both ath11k and iwlwifi this new quirk
> isn't being forced to those drivers, but let users configure IWD to
> disable the flag if needed.
>
> [1] https://lore.kernel.org/linux-wireless/d1e75a08-047d-7947-d51a-2e486efead77@candelatech.com/
So why does dropping the colocated flag help? You have a 2/5 G network that
isn't related to the 6G network at all, meaning that there is no RNR element.
Hence 6G must be scanned passively on social channels. If you don't add the
colocated flag, the end result should be the same, no? Or is colocated flag
forcing the use of RNR element only?
> ---
> src/wiphy.c | 23 +++++++++++++++++------
> src/wiphy.h | 1 +
> 2 files changed, 18 insertions(+), 6 deletions(-)
>
Anyway, I went ahead and applied patches 1-4.
Regards,
-Denis
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 05/15] vendor_quirks: initial skeleton
2025-08-22 19:51 ` [PATCH 05/15] vendor_quirks: initial skeleton James Prestwood
2025-08-23 14:43 ` Marcel Holtmann
@ 2025-08-26 14:56 ` Denis Kenzior
1 sibling, 0 replies; 25+ messages in thread
From: Denis Kenzior @ 2025-08-26 14:56 UTC (permalink / raw)
To: James Prestwood, iwd
Hi James,
On 8/22/25 2:51 PM, James Prestwood wrote:
> This module will provide a database for known issues or quirks with
> wireless vendors. For now the list of quirks is limited to 32 as
> that is the size returned in the bit mask. This could be extended
> to 64 in the future if needed, but of course the goal is to never
> reach that level.
You can always do something like:
struct vendor_quirks {
uint32_t behavior_a : 1;
uint32_t behavior_b : 1;
};
struct vendor_quirks vendor_quirks(const uint8_t *oui);
and just keep extending these as needed. Let the compiler figure out how much
space is actually needed. Also makes the flags less verbose and more compact.
>
> The vendor_quirks() API is intended to be called from scan.c when
> parsing vendor attributes. This will lookup any quirks associated
> with the OUI provided and a mask of quirks will be returned. This
> can be repeated against all the vendor OUI's seen in the scan. The
> result is then a bitmask containing all quirks for that BSS. This
> can then be referenced later during various operations in IWD.
Now, are you sure that just the oui is enough? What about mac address ranges or
maybe IE contents?
Regards,
-Denis
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 14/15] station: clear roam_freqs on delayed roam
2025-08-22 19:51 ` [PATCH 14/15] station: clear roam_freqs on delayed roam James Prestwood
@ 2025-08-26 15:00 ` Denis Kenzior
0 siblings, 0 replies; 25+ messages in thread
From: Denis Kenzior @ 2025-08-26 15:00 UTC (permalink / raw)
To: James Prestwood, iwd
Hi James,
On 8/22/25 2:51 PM, James Prestwood wrote:
> If there were no BSS candidates found after trying to roam make
> sure the old roam_freqs list gets cleared so IWD doesn't end up
> scanning potentially old frequencies on the next retry.
> ---
> src/station.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
Applied, thanks.
Regards,
-Denis
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 01/15] wiphy: add driver quirk for the colocated scan flag
2025-08-26 14:47 ` [PATCH 01/15] wiphy: add driver quirk for the colocated scan flag Denis Kenzior
@ 2025-08-26 15:24 ` James Prestwood
0 siblings, 0 replies; 25+ messages in thread
From: James Prestwood @ 2025-08-26 15:24 UTC (permalink / raw)
To: Denis Kenzior, iwd
Hi Denis,
On 8/26/25 7:47 AM, Denis Kenzior wrote:
> Hi James,
>
> On 8/22/25 2:51 PM, James Prestwood wrote:
>> Some drivers do not handle the colocated scan flag very well and this
>> results in BSS's not being seen in scans. This of course results in
>> very poor behavior.
>>
>> This has been seen on ath11k specifically but after some
>> conversations [1] on the linux-wireless mailing list others have
>> reported issues with iwlwifi acting similarly. Since there are many
>> hardware variants that use both ath11k and iwlwifi this new quirk
>> isn't being forced to those drivers, but let users configure IWD to
>> disable the flag if needed.
>>
>> [1]
>> https://lore.kernel.org/linux-wireless/d1e75a08-047d-7947-d51a-2e486efead77@candelatech.com/
>
> So why does dropping the colocated flag help? You have a 2/5 G
> network that isn't related to the 6G network at all, meaning that
> there is no RNR element. Hence 6G must be scanned passively on social
> channels. If you don't add the colocated flag, the end result should
> be the same, no? Or is colocated flag forcing the use of RNR element
> only?
We noticed this issue specifically with a 6Ghz-only network. So in
theory there should have been no RNR element at all... Despite this, and
performing full spectrum scans, we would get a very limited set of BSS's
back on 6ghz. I suspect maybe the kernel was only scanning social
channels, but removing the colocated flag got things working as I would
expect.
I asked the question, and Ben said he saw similar behavior on iwlwifi.
Its likely an oversight in the kernel. It would be nice to fix there,
but my dedication to fixing the kernel is ever dwindling. Based on my
testing after removing the flag I opted for a one-line workaround...
>
>> ---
>> src/wiphy | 23 +++++++++++++++++------
>> src/wiphy.h | 1 +
>> 2 files changed, 18 insertions(+), 6 deletions(-)
>>
>
> Anyway, I went ahead and applied patches 1-4.
>
> Regards,
> -Denis
^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2025-08-26 15:24 UTC | newest]
Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-22 19:51 [PATCH 01/15] wiphy: add driver quirk for the colocated scan flag James Prestwood
2025-08-22 19:51 ` [PATCH 02/15] wiphy: add comments around the driver quirks James Prestwood
2025-08-22 19:51 ` [PATCH 03/15] scan: check support before using colocated flag James Prestwood
2025-08-22 19:51 ` [PATCH 04/15] monitor: add Cisco Meraki as a printable vendor James Prestwood
2025-08-22 19:51 ` [PATCH 05/15] vendor_quirks: initial skeleton James Prestwood
2025-08-23 14:43 ` Marcel Holtmann
2025-08-25 14:31 ` James Prestwood
2025-08-26 14:56 ` Denis Kenzior
2025-08-22 19:51 ` [PATCH 06/15] vendor_quirks: add two new vendor quirks James Prestwood
2025-08-23 14:46 ` Marcel Holtmann
2025-08-25 14:32 ` James Prestwood
2025-08-22 19:51 ` [PATCH 07/15] handshake: pass object to handshake_util_ap_ie_matches James Prestwood
2025-08-22 19:51 ` [PATCH 08/15] handshake: add vendor quirks into handshake object James Prestwood
2025-08-22 19:51 ` [PATCH 09/15] scan: store vendor quirks in scan_bss James Prestwood
2025-08-22 19:51 ` [PATCH 10/15] station: set vendor quirks into handshake object James Prestwood
2025-08-22 19:51 ` [PATCH 11/15] handshake: use vendor quirk to disable check of replay counters James Prestwood
2025-08-22 19:51 ` [PATCH 12/15] station: get neighbor report on BSS TM request James Prestwood
2025-08-22 19:51 ` [PATCH 13/15] station: check vendor quirk for BSS TM request candidate list James Prestwood
2025-08-23 14:48 ` Marcel Holtmann
2025-08-25 14:37 ` James Prestwood
2025-08-22 19:51 ` [PATCH 14/15] station: clear roam_freqs on delayed roam James Prestwood
2025-08-26 15:00 ` Denis Kenzior
2025-08-22 19:51 ` [PATCH 15/15] auto-t: add AP roam test for bad neighbor reports/candidate lists James Prestwood
2025-08-26 14:47 ` [PATCH 01/15] wiphy: add driver quirk for the colocated scan flag Denis Kenzior
2025-08-26 15:24 ` James Prestwood
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).