3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2026-02-07 10:47:57 +01:00

Compare commits

..

No commits in common. "master" and "3.8" have entirely different histories.
master ... 3.8

41 changed files with 173 additions and 925 deletions

View File

@ -1,14 +1,3 @@
ver 3.10:
Fix issue with handling neighbor report on BSS TM request.
Fix issue with handling deauth and FT association failure.
Fix issue with handling roaming and old frequencies.
ver 3.9:
Fix issue with Access Point mode and frequency unlocking.
Fix issue with network configuration and BSS retry logic.
Fix issue with handling busy notification from Access Point.
Fix issue with handling P-192, P-224 and P-521 for SAE.
ver 3.8: ver 3.8:
Fix issue with handling unit tests and missing kernel features. Fix issue with handling unit tests and missing kernel features.

View File

@ -274,8 +274,6 @@ src_iwd_SOURCES = src/main.c linux/nl80211.h src/iwd.h \
src/dpp.c \ src/dpp.c \
src/udev.c \ src/udev.c \
src/pmksa.h src/pmksa.c \ src/pmksa.h src/pmksa.c \
src/vendor_quirks.h \
src/vendor_quirks.c \
$(eap_sources) \ $(eap_sources) \
$(builtin_sources) $(builtin_sources)

View File

@ -1,156 +0,0 @@
#!/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 test_ignore_candidate_list_quirk(self):
"""
Tests that IWD ignores the candidate list sent by the AP since its
OUI indicates it should be ignored.
"""
# Set the OUI so the candidate list should be ignored
for hapd in self.bss_hostapd:
hapd.set_value('vendor_elements', 'dd0400180a01')
self.initial_connection()
# Send with a candidate list (should be ignored)
self.bss_hostapd[0].send_bss_transition(
self.device.address,
[(self.bss_hostapd[1].bssid, "8f0000005105060603000000")]
)
# IWD should ignore the list and trigger a full scan since we have not
# set any neighbors
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)

View File

@ -3,4 +3,4 @@ RoamThreshold=-72
CriticalRoamThreshold=-72 CriticalRoamThreshold=-72
[Blacklist] [Blacklist]
InitialAccessPointBusyTimeout=20 InitialRoamRequestedTimeout=20

View File

@ -91,11 +91,16 @@ class Test(unittest.TestCase):
# using the same static config. The new client's ACD client should # using the same static config. The new client's ACD client should
# detect an IP conflict and not allow the device to reach the # detect an IP conflict and not allow the device to reach the
# "connected" state although the DBus .Connect call will succeed. # "connected" state although the DBus .Connect call will succeed.
with self.assertRaises(iwd.FailedEx): ordered_network.network_object.connect()
ordered_network.network_object.connect(timeout=500) self.assertEqual(dev2.state, iwd.DeviceState.connecting)
try:
condition = 'obj.state == DeviceState.disconnected' # We should either stay in "connecting" indefinitely or move to
iwd_ns0_1.wait_for_object_condition(dev2, condition, max_wait=21) # "disconnecting"
condition = 'obj.state != DeviceState.connecting'
iwd_ns0_1.wait_for_object_condition(dev2, condition, max_wait=21)
self.assertEqual(dev2.state, iwd.DeviceState.disconnecting)
except TimeoutError:
dev2.disconnect()
iwd_ns0_1.unregister_psk_agent(psk_agent_ns0_1) iwd_ns0_1.unregister_psk_agent(psk_agent_ns0_1)
del dev2 del dev2

View File

@ -8,8 +8,6 @@ from iwd import PSKAgent
from iwd import NetworkType from iwd import NetworkType
class Test(unittest.TestCase): class Test(unittest.TestCase):
def connect_failure(self, ex):
self.failure_triggered = True
def test_netconfig_timeout(self): def test_netconfig_timeout(self):
IWD.copy_to_storage('autoconnect.psk', name='ap-ns1.psk') IWD.copy_to_storage('autoconnect.psk', name='ap-ns1.psk')
@ -29,34 +27,23 @@ class Test(unittest.TestCase):
condition = 'not obj.connected' condition = 'not obj.connected'
wd.wait_for_object_condition(ordered_network.network_object, condition) wd.wait_for_object_condition(ordered_network.network_object, condition)
self.failure_triggered = False ordered_network.network_object.connect()
# Set our error handler here so we can check if it fails condition = 'obj.state == DeviceState.connecting'
ordered_network.network_object.connect(
wait=False,
timeout=1000,
error_handler=self.connect_failure
)
# IWD should attempt to try both BSS's with both failing netconfig.
# Then the autoconnect list should be exhausted, and IWD should
# transition to a disconnected state, then proceed to full autoconnect.
device.wait_for_event("netconfig-failed", timeout=1000)
device.wait_for_event("netconfig-failed", timeout=1000)
device.wait_for_event("disconnected")
device.wait_for_event("autoconnect_full")
# The connect call should have failed
self.assertTrue(self.failure_triggered)
condition = "obj.scanning"
wd.wait_for_object_condition(device, condition)
condition = "not obj.scanning"
wd.wait_for_object_condition(device, condition) wd.wait_for_object_condition(device, condition)
# IWD should attempt to connect, but it will of course fail again. device.wait_for_event("connecting (netconfig)")
device.wait_for_event("netconfig-failed", timeout=1000)
# Netconfig should fail, and IWD should disconnect
from_condition = 'obj.state == DeviceState.connecting'
to_condition = 'obj.state == DeviceState.disconnecting'
wd.wait_for_object_change(device, from_condition, to_condition, max_wait=60)
# Autoconnect should then try again
condition = 'obj.state == DeviceState.connecting'
wd.wait_for_object_condition(device, condition)
device.wait_for_event("connecting (netconfig)")
device.disconnect() device.disconnect()
condition = 'obj.state == DeviceState.disconnected' condition = 'obj.state == DeviceState.disconnected'

View File

@ -19,7 +19,7 @@ class Test(unittest.TestCase):
device = wd.list_devices(1)[0] device = wd.list_devices(1)[0]
device.get_ordered_network('TestFT', full_scan=True) device.get_ordered_network('TestFT', full_scan=True)
device.connect_bssid(self.bss_hostapd[1].bssid, wait=False) device.connect_bssid(self.bss_hostapd[1].bssid)
self.bss_hostapd[1].wait_for_event(f'AP-STA-CONNECTED {device.address}') self.bss_hostapd[1].wait_for_event(f'AP-STA-CONNECTED {device.address}')
device.wait_for_event("connecting (netconfig)") device.wait_for_event("connecting (netconfig)")

View File

@ -1,114 +0,0 @@
#! /usr/bin/python3
import unittest
import sys, os
sys.path.append('../util')
from iwd import IWD
from iwd import NetworkType
from hostapd import HostapdCLI
from packaging import version
from subprocess import run
import re
import testutil
#
# The CSA handling was added in kernel 6.8, so for any earlier kernel this test
# won't pass.
#
def kernel_is_newer(min_version="6.8"):
proc = run(["uname", "-r"], capture_output=True)
version_str = proc.stdout.decode("utf-8")
match = re.match(r"(\d+\.\d+)", version_str)
if not match:
return False
return version.parse(match.group(1)) >= version.parse(min_version)
class Test(unittest.TestCase):
def test_channel_switch_during_roam(self):
wd = self.wd
device = wd.list_devices(1)[0]
ordered_network = device.get_ordered_network('TestFT', full_scan=True)
self.assertEqual(ordered_network.type, NetworkType.psk)
condition = 'not obj.connected'
wd.wait_for_object_condition(ordered_network.network_object, condition)
self.assertFalse(self.bss_hostapd[0].list_sta())
self.assertFalse(self.bss_hostapd[1].list_sta())
device.connect_bssid(self.bss_hostapd[0].bssid)
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(device, condition)
self.bss_hostapd[0].wait_for_event('AP-STA-CONNECTED %s' % device.address)
testutil.test_iface_operstate(device.name)
testutil.test_ifaces_connected(self.bss_hostapd[0].ifname, device.name)
self.assertRaises(Exception, testutil.test_ifaces_connected,
(self.bss_hostapd[1].ifname, device.name, True, True))
# Start a channel switch and wait for it to begin
self.bss_hostapd[1].chan_switch(6, wait=False)
self.bss_hostapd[1].wait_for_event("CTRL-EVENT-STARTED-CHANNEL-SWITCH")
# Initiate a roam immediately which should get rejected by the kernel
device.roam(self.bss_hostapd[1].bssid)
# IWD should authenticate, then proceed to association
device.wait_for_event("ft-authenticating")
device.wait_for_event("ft-roaming")
# The kernel should reject the association, which should trigger a
# disconnect
condition = 'obj.state == DeviceState.disconnected'
wd.wait_for_object_condition(device, condition)
condition = 'obj.state == DeviceState.connected'
wd.wait_for_object_condition(device, condition)
def tearDown(self):
os.system('ip link set "' + self.bss_hostapd[0].ifname + '" down')
os.system('ip link set "' + self.bss_hostapd[1].ifname + '" down')
os.system('ip link set "' + self.bss_hostapd[0].ifname + '" up')
os.system('ip link set "' + self.bss_hostapd[1].ifname + '" up')
for hapd in self.bss_hostapd:
hapd.default()
self.wd.stop()
self.wd = None
def setUp(self):
self.wd = IWD(True)
@classmethod
def setUpClass(cls):
if not kernel_is_newer():
raise unittest.SkipTest()
IWD.copy_to_storage('TestFT.psk')
cls.bss_hostapd = [ HostapdCLI(config='ft-psk-ccmp-1.conf'),
HostapdCLI(config='ft-psk-ccmp-2.conf'),
HostapdCLI(config='ft-psk-ccmp-3.conf') ]
unused = HostapdCLI(config='ft-psk-ccmp-3.conf')
unused.disable()
cls.bss_hostapd[0].set_address('12:00:00:00:00:01')
cls.bss_hostapd[1].set_address('12:00:00:00:00:02')
cls.bss_hostapd[2].set_address('12:00:00:00:00:03')
HostapdCLI.group_neighbors(*cls.bss_hostapd)
@classmethod
def tearDownClass(cls):
IWD.clear_storage()
cls.bss_hostapd = None

View File

@ -288,15 +288,13 @@ class HostapdCLI(object):
cmd = 'RESEND_M3 %s' % address cmd = 'RESEND_M3 %s' % address
self.ctrl_sock.sendall(cmd.encode('utf-8')) self.ctrl_sock.sendall(cmd.encode('utf-8'))
def chan_switch(self, channel, wait=True): def chan_switch(self, channel):
if channel > len(chan_freq_map): if channel > len(chan_freq_map):
raise Exception("Only 2.4GHz channels supported for chan_switch") raise Exception("Only 2.4GHz channels supported for chan_switch")
cmd = self.cmdline + ['chan_switch', '50', str(chan_freq_map[channel])] cmd = self.cmdline + ['chan_switch', '50', str(chan_freq_map[channel])]
ctx.start_process(cmd).wait() ctx.start_process(cmd).wait()
self.wait_for_event('AP-CSA-FINISHED')
if wait:
self.wait_for_event('AP-CSA-FINISHED')
def _get_status(self): def _get_status(self):
ret = {} ret = {}

View File

@ -112,8 +112,8 @@ class AsyncOpAbstract(object):
self._is_completed = True self._is_completed = True
self._exception = _convert_dbus_ex(ex) self._exception = _convert_dbus_ex(ex)
def _wait_for_async_op(self, timeout=50): def _wait_for_async_op(self):
ctx.non_block_wait(lambda s: s._is_completed, timeout, self, exception=None) ctx.non_block_wait(lambda s: s._is_completed, 30, self, exception=None)
self._is_completed = False self._is_completed = False
if self._exception is not None: if self._exception is not None:
@ -280,15 +280,8 @@ class StationDebug(IWDDBusAbstract):
def autoconnect(self): def autoconnect(self):
return self._properties['AutoConnect'] return self._properties['AutoConnect']
def connect_bssid(self, address, wait=True): def connect_bssid(self, address):
self._iface.ConnectBssid( self._iface.ConnectBssid(dbus.ByteArray.fromhex(address.replace(':', '')))
dbus.ByteArray.fromhex(address.replace(':', '')),
reply_handler=self._success,
error_handler=self._failure
)
if wait:
self._wait_for_async_op()
def roam(self, address): def roam(self, address):
self._iface.Roam(dbus.ByteArray.fromhex(address.replace(':', ''))) self._iface.Roam(dbus.ByteArray.fromhex(address.replace(':', '')))
@ -877,8 +870,8 @@ class Device(IWDDBusAbstract):
def stop_adhoc(self): def stop_adhoc(self):
self._prop_proxy.Set(IWD_DEVICE_INTERFACE, 'Mode', 'station') self._prop_proxy.Set(IWD_DEVICE_INTERFACE, 'Mode', 'station')
def connect_bssid(self, address, wait=True): def connect_bssid(self, address):
self._station_debug.connect_bssid(address, wait=wait) self._station_debug.connect_bssid(address)
def roam(self, address): def roam(self, address):
self._station_debug.roam(address) self._station_debug.roam(address)
@ -1006,7 +999,7 @@ class Network(IWDDBusAbstract):
def extended_service_set(self): def extended_service_set(self):
return self._properties['ExtendedServiceSet'] return self._properties['ExtendedServiceSet']
def connect(self, wait=True, timeout=50, reply_handler=None, error_handler=None): def connect(self, wait=True):
''' '''
Connect to the network. Request the device implied by the object Connect to the network. Request the device implied by the object
path to connect to specified network. path to connect to specified network.
@ -1021,19 +1014,12 @@ class Network(IWDDBusAbstract):
@rtype: void @rtype: void
''' '''
if not reply_handler:
reply_handler = self._success
if not error_handler:
error_handler = self._failure
self._iface.Connect(dbus_interface=self._iface_name, self._iface.Connect(dbus_interface=self._iface_name,
reply_handler=reply_handler, reply_handler=self._success,
error_handler=error_handler, error_handler=self._failure)
timeout=timeout)
if wait: if wait:
self._wait_for_async_op(timeout=timeout) self._wait_for_async_op()
def __str__(self, prefix = ''): def __str__(self, prefix = ''):
return prefix + 'Network:\n' \ return prefix + 'Network:\n' \

View File

@ -95,8 +95,6 @@ static const struct diagnostic_dict_mapping diagnostic_mapping[] = {
{ "Frequency", 'u' }, { "Frequency", 'u' },
{ "Channel", 'q' }, { "Channel", 'q' },
{ "Security", 's' }, { "Security", 's' },
{ "InactiveTime", 'u', "ms" },
{ "ConnectedTime", 'u', "s" },
{ NULL } { NULL }
}; };

View File

@ -1,5 +1,5 @@
AC_PREREQ([2.69]) AC_PREREQ([2.69])
AC_INIT([iwd],[3.10]) AC_INIT([iwd],[3.8])
AC_CONFIG_HEADERS(config.h) AC_CONFIG_HEADERS(config.h)
AC_CONFIG_AUX_DIR(build-aux) AC_CONFIG_AUX_DIR(build-aux)

View File

@ -31,12 +31,6 @@ Methods array{dict} GetDiagnostics()
TxMCS [optional] - Transmitting MCS index TxMCS [optional] - Transmitting MCS index
InactiveTime [optional] - Time duration (in ms) for which the STA
connected to this BSS is currently inactive.
ConnectedTime [optional] - Time duration (in s) for which the STA
remains connected to this BSS.
Possible errors: net.connman.iwd.Failed Possible errors: net.connman.iwd.Failed
net.connman.iwd.NotConnected net.connman.iwd.NotConnected
net.connman.iwd.NotFound net.connman.iwd.NotFound

View File

@ -11,12 +11,6 @@ Methods void Connect()
the object path to connect to specified network. the object path to connect to specified network.
Connecting to WEP networks is not supported. Connecting to WEP networks is not supported.
Note: When [General].EnableNetworkConfiguration is set
to true a call to Connect() has the potential to take
a significant amount of time. Specifically if DHCP is
either slow, or is unable to complete. The timeout for
DHCP is roughly 30 seconds per BSS.
Possible errors: net.connman.iwd.Aborted Possible errors: net.connman.iwd.Aborted
net.connman.iwd.Busy net.connman.iwd.Busy
net.connman.iwd.Failed net.connman.iwd.Failed

View File

@ -53,12 +53,6 @@ Methods dict GetDiagnostics()
- GCMP-256 - GCMP-256
- CCMP-256 - CCMP-256
InactiveTime [optional] - Time duration (in ms) for which this STA
is currently inactive.
ConnectedTime [optional] - Time Duration (in s) for which this STA
remains connected to the BSS.
Possible errors: net.connman.iwd.Busy Possible errors: net.connman.iwd.Busy
net.connman.iwd.Failed net.connman.iwd.Failed
net.connman.iwd.NotConnected net.connman.iwd.NotConnected

View File

@ -404,7 +404,6 @@ static const struct {
{ { 0x00, 0x50, 0xf2 }, "Microsoft" }, { { 0x00, 0x50, 0xf2 }, "Microsoft" },
{ { 0x00, 0x90, 0x4c }, "Epigram" }, { { 0x00, 0x90, 0x4c }, "Epigram" },
{ { 0x50, 0x6f, 0x9a }, "Wi-Fi Alliance" }, { { 0x50, 0x6f, 0x9a }, "Wi-Fi Alliance" },
{ { 0x00, 0x18, 0x0a }, "Cisco Meraki" },
{ } { }
}; };

View File

@ -109,8 +109,6 @@ struct ap_state {
struct l_timeout *rekey_timeout; struct l_timeout *rekey_timeout;
unsigned int rekey_time; unsigned int rekey_time;
uint32_t pre_scan_cmd_id;
bool started : 1; bool started : 1;
bool gtk_set : 1; bool gtk_set : 1;
bool netconfig_set_addr4 : 1; bool netconfig_set_addr4 : 1;
@ -356,12 +354,6 @@ static void ap_reset(struct ap_state *ap)
l_timeout_remove(ap->rekey_timeout); l_timeout_remove(ap->rekey_timeout);
ap->rekey_timeout = NULL; ap->rekey_timeout = NULL;
} }
if (ap->pre_scan_cmd_id) {
scan_cancel(netdev_get_wdev_id(ap->netdev),
ap->pre_scan_cmd_id);
ap->pre_scan_cmd_id = 0;
}
} }
static bool ap_event_done(struct ap_state *ap, bool prev_in_event) static bool ap_event_done(struct ap_state *ap, bool prev_in_event)
@ -3860,70 +3852,6 @@ static int ap_load_config(struct ap_state *ap, const struct l_settings *config,
return 0; return 0;
} }
static void ap_pre_scan_trigger(int err, void *user_data)
{
struct ap_state *ap = user_data;
if (err < 0) {
l_error("AP pre-scan failed: %i", err);
ap_start_failed(ap, err);
return;
}
}
static bool ap_check_channel(struct ap_state *ap)
{
const struct band_freq_attrs *freq_attr;
freq_attr = wiphy_get_frequency_info(netdev_get_wiphy(ap->netdev),
band_channel_to_freq(ap->channel, ap->band));
if (L_WARN_ON(!freq_attr))
return false;
/* Check if disabled/no-IR */
if (freq_attr->disabled || freq_attr->no_ir)
return false;
return true;
}
static bool ap_pre_scan_notify(int err, struct l_queue *bss_list,
const struct scan_freq_set *freqs,
void *user_data)
{
struct ap_state *ap = user_data;
if (!ap_check_channel(ap)) {
l_error("Unable to channel %u even after pre-scan",
ap->channel);
goto error;
}
if (ap_start_send(ap))
return false;
error:
ap_start_failed(ap, -ENOTSUP);
return false;
}
static void ap_pre_scan_destroy(void *user_data)
{
struct ap_state *ap = user_data;
ap->pre_scan_cmd_id = 0;
}
static bool ap_pre_scan(struct ap_state *ap)
{
ap->pre_scan_cmd_id = scan_passive(netdev_get_wdev_id(ap->netdev),
NULL, ap_pre_scan_trigger,
ap_pre_scan_notify,
ap, ap_pre_scan_destroy);
return ap->pre_scan_cmd_id != 0;
}
/* /*
* Start a simple independent WPA2 AP on given netdev. * Start a simple independent WPA2 AP on given netdev.
* *
@ -4034,20 +3962,6 @@ struct ap_state *ap_start(struct netdev *netdev, struct l_settings *config,
return ap; return ap;
} }
if (!ap_check_channel(ap)) {
l_debug("Channel %u is disabled/no-IR, pre-scanning",
ap->channel);
if (ap_pre_scan(ap)) {
if (err_out)
*err_out = 0;
return ap;
}
goto error;
}
if (ap_start_send(ap)) { if (ap_start_send(ap)) {
if (err_out) if (err_out)
*err_out = 0; *err_out = 0;

View File

@ -45,7 +45,7 @@
static uint64_t blacklist_multiplier; static uint64_t blacklist_multiplier;
static uint64_t blacklist_initial_timeout; static uint64_t blacklist_initial_timeout;
static uint64_t blacklist_ap_busy_initial_timeout; static uint64_t blacklist_roam_initial_timeout;
static uint64_t blacklist_max_timeout; static uint64_t blacklist_max_timeout;
struct blacklist_entry { struct blacklist_entry {
@ -67,8 +67,8 @@ static uint64_t get_reason_timeout(enum blacklist_reason reason)
switch (reason) { switch (reason) {
case BLACKLIST_REASON_CONNECT_FAILED: case BLACKLIST_REASON_CONNECT_FAILED:
return blacklist_initial_timeout; return blacklist_initial_timeout;
case BLACKLIST_REASON_AP_BUSY: case BLACKLIST_REASON_ROAM_REQUESTED:
return blacklist_ap_busy_initial_timeout; return blacklist_roam_initial_timeout;
default: default:
l_warn("Unhandled blacklist reason: %u", reason); l_warn("Unhandled blacklist reason: %u", reason);
return 0; return 0;
@ -218,19 +218,11 @@ static int blacklist_init(void)
if (!l_settings_get_uint64(config, "Blacklist", if (!l_settings_get_uint64(config, "Blacklist",
"InitialRoamRequestedTimeout", "InitialRoamRequestedTimeout",
&blacklist_ap_busy_initial_timeout)) &blacklist_roam_initial_timeout))
blacklist_ap_busy_initial_timeout = BLACKLIST_DEFAULT_TIMEOUT; blacklist_roam_initial_timeout = BLACKLIST_DEFAULT_TIMEOUT;
else
l_warn("[Blacklist].InitialRoamRequestedTimeout is deprecated, "
"use [Blacklist].InitialAccessPointBusyTimeout");
if (!l_settings_get_uint64(config, "Blacklist",
"InitialAccessPointBusyTimeout",
&blacklist_ap_busy_initial_timeout))
blacklist_ap_busy_initial_timeout = BLACKLIST_DEFAULT_TIMEOUT;
/* For easier user configuration the timeout values are in seconds */ /* For easier user configuration the timeout values are in seconds */
blacklist_ap_busy_initial_timeout *= L_USEC_PER_SEC; blacklist_roam_initial_timeout *= L_USEC_PER_SEC;
if (!l_settings_get_uint64(config, "Blacklist", if (!l_settings_get_uint64(config, "Blacklist",
"Multiplier", "Multiplier",

View File

@ -27,14 +27,12 @@ enum blacklist_reason {
*/ */
BLACKLIST_REASON_CONNECT_FAILED, BLACKLIST_REASON_CONNECT_FAILED,
/* /*
* This type of blacklist is added when an AP indicates that its unable * This type of blacklist is added when a BSS requests IWD roams
* to handle more connections. This is done via BSS-TM requests or * elsewhere. This is to aid in preventing IWD from roaming/connecting
* denied authentications/associations with certain status codes. * back to that BSS in the future unless there are no other "good"
* * candidates to connect to.
* Once this type of blacklist is applied to a BSS IWD will attempt to
* avoid roaming to it for a configured period of time.
*/ */
BLACKLIST_REASON_AP_BUSY, BLACKLIST_REASON_ROAM_REQUESTED,
}; };
void blacklist_add_bss(const uint8_t *addr, enum blacklist_reason reason); void blacklist_add_bss(const uint8_t *addr, enum blacklist_reason reason);

View File

@ -110,14 +110,6 @@ bool diagnostic_info_to_dict(const struct diagnostic_station_info *info,
dbus_append_dict_basic(builder, "ExpectedThroughput", 'u', dbus_append_dict_basic(builder, "ExpectedThroughput", 'u',
&info->expected_throughput); &info->expected_throughput);
if (info->have_inactive_time)
dbus_append_dict_basic(builder, "InactiveTime", 'u',
&info->inactive_time);
if (info->have_connected_time)
dbus_append_dict_basic(builder, "ConnectedTime", 'u',
&info->connected_time);
return true; return true;
} }

View File

@ -43,9 +43,6 @@ struct diagnostic_station_info {
uint32_t expected_throughput; uint32_t expected_throughput;
uint32_t inactive_time;
uint32_t connected_time;
bool have_cur_rssi : 1; bool have_cur_rssi : 1;
bool have_avg_rssi : 1; bool have_avg_rssi : 1;
bool have_rx_mcs : 1; bool have_rx_mcs : 1;
@ -53,8 +50,6 @@ struct diagnostic_station_info {
bool have_rx_bitrate : 1; bool have_rx_bitrate : 1;
bool have_tx_bitrate : 1; bool have_tx_bitrate : 1;
bool have_expected_throughput : 1; bool have_expected_throughput : 1;
bool have_inactive_time : 1;
bool have_connected_time : 1;
}; };
bool diagnostic_info_to_dict(const struct diagnostic_station_info *info, bool diagnostic_info_to_dict(const struct diagnostic_station_info *info,

View File

@ -1810,7 +1810,7 @@ static void eapol_handle_ptk_3_of_4(struct eapol_sm *sm,
if ((rsne[1] != hs->authenticator_ie[1] || if ((rsne[1] != hs->authenticator_ie[1] ||
memcmp(rsne + 2, hs->authenticator_ie + 2, rsne[1])) && memcmp(rsne + 2, hs->authenticator_ie + 2, rsne[1])) &&
!handshake_util_ap_ie_matches(hs, &rsn_info, !handshake_util_ap_ie_matches(&rsn_info,
hs->authenticator_ie, hs->authenticator_ie,
hs->wpa_ie)) hs->wpa_ie))
goto error_ie_different; goto error_ie_different;

View File

@ -223,8 +223,7 @@ static bool ft_parse_associate_resp_frame(const uint8_t *frame, size_t frame_len
return true; return true;
} }
static bool ft_verify_rsne(struct handshake_state *hs, static bool ft_verify_rsne(const uint8_t *rsne, const uint8_t *pmk_r0_name,
const uint8_t *rsne, const uint8_t *pmk_r0_name,
const uint8_t *authenticator_ie) const uint8_t *authenticator_ie)
{ {
/* /*
@ -254,7 +253,7 @@ static bool ft_verify_rsne(struct handshake_state *hs,
memcmp(msg2_rsne.pmkids, pmk_r0_name, 16)) memcmp(msg2_rsne.pmkids, pmk_r0_name, 16))
return false; return false;
if (!handshake_util_ap_ie_matches(hs, &msg2_rsne, authenticator_ie, false)) if (!handshake_util_ap_ie_matches(&msg2_rsne, authenticator_ie, false))
return false; return false;
return true; return true;
@ -302,8 +301,7 @@ static int parse_ies(struct handshake_state *hs,
is_rsn = hs->supplicant_ie != NULL; is_rsn = hs->supplicant_ie != NULL;
if (is_rsn) { if (is_rsn) {
if (!ft_verify_rsne(hs, rsne, hs->pmk_r0_name, if (!ft_verify_rsne(rsne, hs->pmk_r0_name, authenticator_ie))
authenticator_ie))
goto ft_error; goto ft_error;
} else if (rsne) } else if (rsne)
goto ft_error; goto ft_error;
@ -482,7 +480,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)) memcmp(msg4_rsne.pmkids, hs->pmk_r1_name, 16))
return -EBADMSG; return -EBADMSG;
if (!handshake_util_ap_ie_matches(hs, &msg4_rsne, if (!handshake_util_ap_ie_matches(&msg4_rsne,
hs->authenticator_ie, hs->authenticator_ie,
false)) false))
return -EBADMSG; return -EBADMSG;

View File

@ -368,12 +368,6 @@ void handshake_state_set_vendor_ies(struct handshake_state *s,
} }
} }
void handshake_state_set_vendor_quirks(struct handshake_state *s,
struct vendor_quirk quirks)
{
s->vendor_quirks = quirks;
}
void handshake_state_set_kh_ids(struct handshake_state *s, void handshake_state_set_kh_ids(struct handshake_state *s,
const uint8_t *r0khid, size_t r0khid_len, const uint8_t *r0khid, size_t r0khid_len,
const uint8_t *r1khid) const uint8_t *r1khid)
@ -883,8 +877,7 @@ 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 * 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. * don't match, the EAPoL packet must be silently discarded.
*/ */
bool handshake_util_ap_ie_matches(struct handshake_state *s, bool handshake_util_ap_ie_matches(const struct ie_rsn_info *msg_info,
const struct ie_rsn_info *msg_info,
const uint8_t *scan_ie, bool is_wpa) const uint8_t *scan_ie, bool is_wpa)
{ {
struct ie_rsn_info scan_info; struct ie_rsn_info scan_info;
@ -914,15 +907,11 @@ bool handshake_util_ap_ie_matches(struct handshake_state *s,
if (msg_info->no_pairwise != scan_info.no_pairwise) if (msg_info->no_pairwise != scan_info.no_pairwise)
return false; return false;
if (!(s->vendor_quirks.replay_counter_mismatch)) { if (msg_info->ptksa_replay_counter != scan_info.ptksa_replay_counter)
if (msg_info->ptksa_replay_counter != return false;
scan_info.ptksa_replay_counter)
return false;
if (msg_info->gtksa_replay_counter != if (msg_info->gtksa_replay_counter != scan_info.gtksa_replay_counter)
scan_info.gtksa_replay_counter) return false;
return false;
}
if (msg_info->mfpr != scan_info.mfpr) if (msg_info->mfpr != scan_info.mfpr)
return false; return false;

View File

@ -26,8 +26,6 @@
#include <linux/types.h> #include <linux/types.h>
#include <ell/cleanup.h> #include <ell/cleanup.h>
#include "src/vendor_quirks.h"
struct handshake_state; struct handshake_state;
enum crypto_cipher; enum crypto_cipher;
struct eapol_frame; struct eapol_frame;
@ -109,7 +107,6 @@ struct handshake_state {
uint8_t *authenticator_fte; uint8_t *authenticator_fte;
uint8_t *supplicant_fte; uint8_t *supplicant_fte;
uint8_t *vendor_ies; uint8_t *vendor_ies;
struct vendor_quirk vendor_quirks;
size_t vendor_ies_len; size_t vendor_ies_len;
enum ie_rsn_cipher_suite pairwise_cipher; enum ie_rsn_cipher_suite pairwise_cipher;
enum ie_rsn_cipher_suite group_cipher; enum ie_rsn_cipher_suite group_cipher;
@ -240,9 +237,6 @@ void handshake_state_set_vendor_ies(struct handshake_state *s,
const struct iovec *iov, const struct iovec *iov,
size_t n_iovs); size_t n_iovs);
void handshake_state_set_vendor_quirks(struct handshake_state *s,
struct vendor_quirk quirks);
void handshake_state_set_kh_ids(struct handshake_state *s, void handshake_state_set_kh_ids(struct handshake_state *s,
const uint8_t *r0khid, size_t r0khid_len, const uint8_t *r0khid, size_t r0khid_len,
const uint8_t *r1khid); const uint8_t *r1khid);
@ -318,8 +312,7 @@ bool handshake_state_set_pmksa(struct handshake_state *s, struct pmksa *pmksa);
void handshake_state_cache_pmksa(struct handshake_state *s); void handshake_state_cache_pmksa(struct handshake_state *s);
bool handshake_state_remove_pmksa(struct handshake_state *s); bool handshake_state_remove_pmksa(struct handshake_state *s);
bool handshake_util_ap_ie_matches(struct handshake_state *s, bool handshake_util_ap_ie_matches(const struct ie_rsn_info *msg_info,
const struct ie_rsn_info *msg_info,
const uint8_t *scan_ie, bool is_wpa); const uint8_t *scan_ie, bool is_wpa);
const uint8_t *handshake_util_find_kde(enum handshake_kde selector, const uint8_t *handshake_util_find_kde(enum handshake_kde selector,

View File

@ -292,22 +292,12 @@ control how long a misbehaved BSS spends on the blacklist.
The initial time that a BSS spends on the blacklist. Setting this to zero The initial time that a BSS spends on the blacklist. Setting this to zero
will disable blacklisting functionality in IWD. will disable blacklisting functionality in IWD.
* - InitialRoamRequestedTimeout (**deprecated**) * - InitialRoamRequestedTimeout
- Values: uint64 value in seconds (default: **30**) - Values: uint64 value in seconds (default: **30**)
This setting is deprecated, please use The initial time that a BSS will be marked after a BSS requests a roam.
[Blacklist].InitialAccessPointBusyTimeout instead. This is to aid in avoiding roaming back to BSS's which are likely
* - InitialAccessPointBusyTimeout overloaded. Setting this to zero will disabled this form of blacklisting.
- Values: uint64 value in seconds (default: **30**)
The initial time that a BSS will be blacklisted after indicating it
cannot handle more connections. This is triggered by either a BSS
transition management request (telling IWD to roam elsewhere) or by a
denied authentication or association with the NO_MORE_STAS status code.
Once a BSS is blacklisted in this manor IWD will attempt to avoid it for
the configured amount of time.
* - Multiplier * - Multiplier
- Values: unsigned int value greater than zero, in seconds - Values: unsigned int value greater than zero, in seconds
(default: **30**) (default: **30**)

View File

@ -197,12 +197,29 @@ static void request_name_callback(struct l_dbus *dbus, bool success,
{ {
if (!success) { if (!success) {
l_error("Name request failed"); l_error("Name request failed");
l_main_quit(); goto fail_exit;
} }
if (!l_dbus_object_manager_enable(dbus, "/"))
l_warn("Unable to register the ObjectManager");
if (!l_dbus_object_add_interface(dbus, IWD_BASE_PATH,
IWD_DAEMON_INTERFACE,
NULL) ||
!l_dbus_object_add_interface(dbus, IWD_BASE_PATH,
L_DBUS_INTERFACE_PROPERTIES,
NULL))
l_info("Unable to add %s and/or %s at %s",
IWD_DAEMON_INTERFACE, L_DBUS_INTERFACE_PROPERTIES,
IWD_BASE_PATH);
/* TODO: Always request nl80211 for now, ignoring auto-loading */ /* TODO: Always request nl80211 for now, ignoring auto-loading */
l_genl_request_family(genl, NL80211_GENL_NAME, nl80211_appeared, l_genl_request_family(genl, NL80211_GENL_NAME, nl80211_appeared,
NULL, NULL); NULL, NULL);
return;
fail_exit:
l_main_quit();
} }
static struct l_dbus_message *iwd_dbus_get_info(struct l_dbus *dbus, static struct l_dbus_message *iwd_dbus_get_info(struct l_dbus *dbus,
@ -232,25 +249,12 @@ static void dbus_ready(void *user_data)
{ {
struct l_dbus *dbus = user_data; struct l_dbus *dbus = user_data;
l_dbus_name_acquire(dbus, "net.connman.iwd", false, false, false,
request_name_callback, NULL);
l_dbus_register_interface(dbus, IWD_DAEMON_INTERFACE, l_dbus_register_interface(dbus, IWD_DAEMON_INTERFACE,
iwd_setup_deamon_interface, iwd_setup_deamon_interface,
NULL, false); NULL, false);
if (!l_dbus_object_manager_enable(dbus, "/"))
l_warn("Unable to register the ObjectManager");
if (!l_dbus_object_add_interface(dbus, IWD_BASE_PATH,
IWD_DAEMON_INTERFACE,
NULL) ||
!l_dbus_object_add_interface(dbus, IWD_BASE_PATH,
L_DBUS_INTERFACE_PROPERTIES,
NULL))
l_info("Unable to add %s and/or %s at %s",
IWD_DAEMON_INTERFACE, L_DBUS_INTERFACE_PROPERTIES,
IWD_BASE_PATH);
l_dbus_name_acquire(dbus, "net.connman.iwd", false, false, false,
request_name_callback, NULL);
} }
static void dbus_disconnected(void *user_data) static void dbus_disconnected(void *user_data)

View File

@ -637,6 +637,7 @@ static bool netdev_parse_sta_info(struct l_genl_attr *attr,
info->have_tx_mcs = true; info->have_tx_mcs = true;
break; break;
case NL80211_STA_INFO_EXPECTED_THROUGHPUT: case NL80211_STA_INFO_EXPECTED_THROUGHPUT:
if (len != 4) if (len != 4)
return false; return false;
@ -644,22 +645,6 @@ static bool netdev_parse_sta_info(struct l_genl_attr *attr,
info->expected_throughput = l_get_u32(data); info->expected_throughput = l_get_u32(data);
info->have_expected_throughput = true; info->have_expected_throughput = true;
break;
case NL80211_STA_INFO_INACTIVE_TIME:
if (len != 4)
return false;
info->inactive_time = l_get_u32(data);
info->have_inactive_time = true;
break;
case NL80211_STA_INFO_CONNECTED_TIME:
if (len != 4)
return false;
info->connected_time = l_get_u32(data);
info->have_connected_time = true;
break; break;
} }
} }
@ -3008,26 +2993,13 @@ static void netdev_cmd_ft_reassociate_cb(struct l_genl_msg *msg,
void *user_data) void *user_data)
{ {
struct netdev *netdev = user_data; struct netdev *netdev = user_data;
int err = l_genl_msg_get_error(msg);
netdev->connect_cmd_id = 0; netdev->connect_cmd_id = 0;
l_debug("%d", err); if (l_genl_msg_get_error(msg) >= 0)
if (err >= 0)
return; return;
/* netdev_deauth_and_fail_connection(netdev,
* TODO: It is possible to not trigger a disconnect here and maintain
* the current connection. The issue is that IWD has already
* modified the handshake and we've lost all reference to the old
* BSS keys.
*
* This could be remedied in the future by creating an entirely
* new handshake_state object for the association and only when
* the ack indicates success do we clear out the old object.
*/
netdev_disconnect_and_fail_connection(netdev,
NETDEV_RESULT_ASSOCIATION_FAILED, NETDEV_RESULT_ASSOCIATION_FAILED,
MMPDU_STATUS_CODE_UNSPECIFIED); MMPDU_STATUS_CODE_UNSPECIFIED);
} }
@ -5430,9 +5402,6 @@ static void netdev_channel_switch_event(struct l_genl_msg *msg,
if (netdev->type != NL80211_IFTYPE_STATION) if (netdev->type != NL80211_IFTYPE_STATION)
return; return;
if (L_WARN_ON(!netdev->connected))
return;
chandef = l_new(struct band_chandef, 1); chandef = l_new(struct band_chandef, 1);
if (nl80211_parse_chandef(msg, chandef) < 0) { if (nl80211_parse_chandef(msg, chandef) < 0) {
@ -5482,39 +5451,6 @@ static void netdev_michael_mic_failure(struct l_genl_msg *msg,
l_debug("ifindex=%u key_idx=%u type=%u", netdev->index, idx, type); l_debug("ifindex=%u key_idx=%u type=%u", netdev->index, idx, type);
} }
#define MAX_COMEBACK_DELAY 1200
static void netdev_assoc_comeback(struct l_genl_msg *msg,
struct netdev *netdev)
{
const uint8_t *mac;
uint32_t timeout;
if (L_WARN_ON(!netdev->connected))
return;
if (nl80211_parse_attrs(msg, NL80211_ATTR_MAC, &mac,
NL80211_ATTR_TIMEOUT, &timeout,
NL80211_ATTR_UNSPEC) < 0)
return;
if (L_WARN_ON(memcmp(mac, netdev->handshake->aa, ETH_ALEN)))
return;
if (timeout <= MAX_COMEBACK_DELAY) {
l_debug(MAC" requested an association comeback delay of %u TU",
MAC_STR(netdev->handshake->aa), timeout);
return;
}
l_debug("Comeback delay of %u exceeded maximum of %u, deauthenticating",
timeout, MAX_COMEBACK_DELAY);
netdev_deauth_and_fail_connection(netdev,
NETDEV_RESULT_ASSOCIATION_FAILED,
MMPDU_STATUS_CODE_REFUSED_TEMPORARILY);
}
static void netdev_mlme_notify(struct l_genl_msg *msg, void *user_data) static void netdev_mlme_notify(struct l_genl_msg *msg, void *user_data)
{ {
struct netdev *netdev = NULL; struct netdev *netdev = NULL;
@ -5568,9 +5504,6 @@ static void netdev_mlme_notify(struct l_genl_msg *msg, void *user_data)
case NL80211_CMD_MICHAEL_MIC_FAILURE: case NL80211_CMD_MICHAEL_MIC_FAILURE:
netdev_michael_mic_failure(msg, netdev); netdev_michael_mic_failure(msg, netdev);
break; break;
case NL80211_CMD_ASSOC_COMEBACK:
netdev_assoc_comeback(msg, netdev);
break;
} }
} }

View File

@ -168,11 +168,6 @@ static bool network_secret_check_cacheable(void *data, void *user_data)
return false; return false;
} }
void network_clear_blacklist(struct network *network)
{
l_queue_clear(network->blacklist, NULL);
}
void network_connected(struct network *network) void network_connected(struct network *network)
{ {
enum security security = network_get_security(network); enum security security = network_get_security(network);
@ -203,6 +198,8 @@ void network_connected(struct network *network)
l_queue_foreach_remove(network->secrets, l_queue_foreach_remove(network->secrets,
network_secret_check_cacheable, network); network_secret_check_cacheable, network);
l_queue_clear(network->blacklist, NULL);
network->provisioning_hidden = false; network->provisioning_hidden = false;
} }
@ -210,7 +207,7 @@ void network_disconnected(struct network *network)
{ {
network_settings_close(network); network_settings_close(network);
network_clear_blacklist(network); l_queue_clear(network->blacklist, NULL);
if (network->provisioning_hidden) if (network->provisioning_hidden)
station_hide_network(network->station, network); station_hide_network(network->station, network);

View File

@ -74,7 +74,6 @@ bool network_bss_update(struct network *network, struct scan_bss *bss);
const char *network_bss_get_path(const struct network *network, const char *network_bss_get_path(const struct network *network,
const struct scan_bss *bss); const struct scan_bss *bss);
bool network_bss_list_isempty(struct network *network); bool network_bss_list_isempty(struct network *network);
void network_clear_blacklist(struct network *network);
const char *__network_path_append_bss(const char *network_path, const char *__network_path_append_bss(const char *network_path,
const struct scan_bss *bss); const struct scan_bss *bss);

View File

@ -177,7 +177,6 @@ static const struct {
{ NL80211_CMD_UNPROT_BEACON, "Unprotected Beacon" }, { NL80211_CMD_UNPROT_BEACON, "Unprotected Beacon" },
{ NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS, { NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS,
"Control Port TX Status" }, "Control Port TX Status" },
{ NL80211_CMD_ASSOC_COMEBACK, "Association comeback delay" },
{ } { }
}; };

View File

@ -190,7 +190,6 @@ static attr_handler handler_for_nl80211(int type)
case NL80211_ATTR_CENTER_FREQ2: case NL80211_ATTR_CENTER_FREQ2:
case NL80211_ATTR_AKM_SUITES: case NL80211_ATTR_AKM_SUITES:
case NL80211_ATTR_EXTERNAL_AUTH_ACTION: case NL80211_ATTR_EXTERNAL_AUTH_ACTION:
case NL80211_ATTR_TIMEOUT:
return extract_uint32; return extract_uint32;
case NL80211_ATTR_FRAME: case NL80211_ATTR_FRAME:
return extract_iovec; return extract_iovec;

View File

@ -169,14 +169,6 @@ static int sae_choose_next_group(struct sae_sm *sm)
!sm->handshake->ecc_sae_pts[sm->group_retry]) !sm->handshake->ecc_sae_pts[sm->group_retry])
continue; continue;
/*
* TODO: Groups for P192, P224 and P521 are currently
* non-functional with SAE. Until this is fixed we need to
* avoid these groups from being used.
*/
if (group == 21 || group == 25 || group == 26)
continue;
break; break;
} }
@ -1002,8 +994,7 @@ static int sae_process_anti_clogging(struct sae_sm *sm, const uint8_t *ptr,
sm->token_len = len; sm->token_len = len;
sm->sync = 0; sm->sync = 0;
if (L_WARN_ON(!sae_send_commit(sm, true))) sae_send_commit(sm, true);
return -EPROTO;
return -EAGAIN; return -EAGAIN;
} }
@ -1083,9 +1074,7 @@ static int sae_verify_committed(struct sae_sm *sm, uint16_t transaction,
return -ETIMEDOUT; return -ETIMEDOUT;
sm->sync++; sm->sync++;
sae_send_commit(sm, true);
if (L_WARN_ON(!sae_send_commit(sm, true)))
return -EPROTO;
return -EAGAIN; return -EAGAIN;
} }
@ -1140,9 +1129,7 @@ static int sae_verify_committed(struct sae_sm *sm, uint16_t transaction,
sm->group); sm->group);
sm->sync = 0; sm->sync = 0;
sae_send_commit(sm, false);
if (L_WARN_ON(!sae_send_commit(sm, false)))
return -EPROTO;
return -EAGAIN; return -EAGAIN;
} }
@ -1307,8 +1294,7 @@ static int sae_verify_confirmed(struct sae_sm *sm, uint16_t trans,
sm->sync++; sm->sync++;
sm->sc++; sm->sc++;
if (L_WARN_ON(!sae_send_commit(sm, true))) sae_send_commit(sm, true);
return -EPROTO;
if (!sae_send_confirm(sm)) if (!sae_send_confirm(sm))
return -EPROTO; return -EPROTO;

View File

@ -51,7 +51,6 @@
#include "src/mpdu.h" #include "src/mpdu.h"
#include "src/band.h" #include "src/band.h"
#include "src/scan.h" #include "src/scan.h"
#include "src/vendor_quirks.h"
/* User configurable options */ /* User configurable options */
static double RANK_2G_FACTOR; static double RANK_2G_FACTOR;
@ -415,8 +414,7 @@ static struct l_genl_msg *scan_build_cmd(struct scan_context *sc,
if (params->ap_scan) if (params->ap_scan)
flags |= NL80211_SCAN_FLAG_AP; flags |= NL80211_SCAN_FLAG_AP;
if (wiphy_supports_colocated_flag(sc->wiphy)) flags |= NL80211_SCAN_FLAG_COLOCATED_6GHZ;
flags |= NL80211_SCAN_FLAG_COLOCATED_6GHZ;
if (flags) if (flags)
l_genl_msg_append_attr(msg, NL80211_ATTR_SCAN_FLAGS, 4, &flags); l_genl_msg_append_attr(msg, NL80211_ATTR_SCAN_FLAGS, 4, &flags);
@ -1222,11 +1220,6 @@ static void scan_parse_vendor_specific(struct scan_bss *bss, const void *data,
uint16_t cost_flags; uint16_t cost_flags;
bool dgaf_disable; bool dgaf_disable;
if (L_WARN_ON(len < 3))
return;
vendor_quirks_append_for_oui(data, &bss->vendor_quirks);
if (!bss->wpa && is_ie_wpa_ie(data, len)) { if (!bss->wpa && is_ie_wpa_ie(data, len)) {
bss->wpa = l_memdup(data - 2, len + 2); bss->wpa = l_memdup(data - 2, len + 2);
return; return;

View File

@ -21,7 +21,6 @@
*/ */
#include "src/defs.h" #include "src/defs.h"
#include "src/vendor_quirks.h"
struct scan_freq_set; struct scan_freq_set;
struct ie_rsn_info; struct ie_rsn_info;
@ -80,7 +79,6 @@ struct scan_bss {
uint8_t *wfd; /* Concatenated WFD IEs */ uint8_t *wfd; /* Concatenated WFD IEs */
ssize_t wfd_size; /* Size of Concatenated WFD IEs */ ssize_t wfd_size; /* Size of Concatenated WFD IEs */
int8_t snr; int8_t snr;
struct vendor_quirk vendor_quirks;
bool mde_present : 1; bool mde_present : 1;
bool cc_present : 1; bool cc_present : 1;
bool cap_rm_neighbor_report : 1; bool cap_rm_neighbor_report : 1;

View File

@ -64,7 +64,6 @@
#include "src/eap-tls-common.h" #include "src/eap-tls-common.h"
#include "src/storage.h" #include "src/storage.h"
#include "src/pmksa.h" #include "src/pmksa.h"
#include "src/vendor_quirks.h"
#define STATION_RECENT_NETWORK_LIMIT 5 #define STATION_RECENT_NETWORK_LIMIT 5
#define STATION_RECENT_FREQS_LIMIT 5 #define STATION_RECENT_FREQS_LIMIT 5
@ -192,7 +191,8 @@ static uint32_t evaluate_bss_group_rank(const uint8_t *addr, uint32_t freq,
if (blacklist_contains_bss(addr, BLACKLIST_REASON_CONNECT_FAILED)) if (blacklist_contains_bss(addr, BLACKLIST_REASON_CONNECT_FAILED))
return 0; return 0;
roam_blacklist = blacklist_contains_bss(addr, BLACKLIST_REASON_AP_BUSY); roam_blacklist = blacklist_contains_bss(addr,
BLACKLIST_REASON_ROAM_REQUESTED);
good_signal = signal >= netdev_get_low_signal_threshold(freq); good_signal = signal >= netdev_get_low_signal_threshold(freq);
if (good_signal) if (good_signal)
@ -1447,8 +1447,6 @@ static struct handshake_state *station_handshake_setup(struct station *station,
vendor_ies = network_info_get_extra_ies(info, bss, &iov_elems); 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_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 * It can't hurt to try the FILS IP Address Assignment independent of
* which auth-proto is actually used. * which auth-proto is actually used.
@ -1798,15 +1796,6 @@ static void station_enter_state(struct station *station,
periodic_scan_stop(station); periodic_scan_stop(station);
break; break;
case STATION_STATE_CONNECTED: case STATION_STATE_CONNECTED:
network_clear_blacklist(station->connected_network);
if (station->connect_pending) {
struct l_dbus_message *reply =
l_dbus_message_new_method_return(
station->connect_pending);
dbus_pending_reply(&station->connect_pending, reply);
}
l_dbus_object_add_interface(dbus, l_dbus_object_add_interface(dbus,
netdev_get_path(station->netdev), netdev_get_path(station->netdev),
IWD_STATION_DIAGNOSTIC_INTERFACE, IWD_STATION_DIAGNOSTIC_INTERFACE,
@ -2226,26 +2215,6 @@ static void station_early_neighbor_report_cb(struct netdev *netdev, int err,
&station->roam_freqs); &station->roam_freqs);
} }
static bool station_try_next_bss(struct station *station)
{
struct scan_bss *next;
int ret;
next = network_bss_select(station->connected_network, false);
if (!next)
return false;
ret = __station_connect_network(station, station->connected_network,
next, station->state);
if (ret < 0)
return false;
l_debug("Attempting to connect to next BSS "MAC, MAC_STR(next->addr));
return true;
}
static bool station_can_fast_transition(struct station *station, static bool station_can_fast_transition(struct station *station,
struct handshake_state *hs, struct handshake_state *hs,
struct scan_bss *bss) struct scan_bss *bss)
@ -2288,26 +2257,28 @@ static bool station_can_fast_transition(struct station *station,
return true; return true;
} }
static void station_disconnect_on_netconfig_failed(struct netdev *netdev, static void station_disconnect_on_error_cb(struct netdev *netdev, bool success,
bool success, void *user_data)
void *user_data)
{ {
struct station *station = user_data; struct station *station = user_data;
bool continue_autoconnect;
if (station_try_next_bss(station))
return;
if (station->connect_pending) {
struct l_dbus_message *reply = dbus_error_failed(
station->connect_pending);
dbus_pending_reply(&station->connect_pending, reply);
}
station_reset_connection_state(station);
station_enter_state(station, STATION_STATE_DISCONNECTED); station_enter_state(station, STATION_STATE_DISCONNECTED);
station_enter_state(station, STATION_STATE_AUTOCONNECT_FULL);
continue_autoconnect = station->state == STATION_STATE_CONNECTING_AUTO;
if (continue_autoconnect) {
if (station_autoconnect_next(station) < 0) {
l_debug("Nothing left on autoconnect list");
station_enter_state(station,
STATION_STATE_AUTOCONNECT_FULL);
}
return;
}
if (station->autoconnect)
station_enter_state(station, STATION_STATE_AUTOCONNECT_QUICK);
} }
static void station_netconfig_event_handler(enum netconfig_event event, static void station_netconfig_event_handler(enum netconfig_event event,
@ -2320,20 +2291,23 @@ static void station_netconfig_event_handler(enum netconfig_event event,
station_enter_state(station, STATION_STATE_CONNECTED); station_enter_state(station, STATION_STATE_CONNECTED);
break; break;
case NETCONFIG_EVENT_FAILED: case NETCONFIG_EVENT_FAILED:
station_debug_event(station, "netconfig-failed"); if (station->connect_pending) {
struct l_dbus_message *reply = dbus_error_failed(
station->connect_pending);
netconfig_reset(station->netconfig); dbus_pending_reply(&station->connect_pending, reply);
}
if (station->state == STATION_STATE_NETCONFIG) if (station->state == STATION_STATE_NETCONFIG)
network_connect_failed(station->connected_network, network_connect_failed(station->connected_network,
false); false);
network_blacklist_add(station->connected_network,
station->connected_bss);
netdev_disconnect(station->netdev, netdev_disconnect(station->netdev,
station_disconnect_on_netconfig_failed, station_disconnect_on_error_cb,
station); station);
station_reset_connection_state(station);
station_enter_state(station, STATION_STATE_DISCONNECTING);
break; break;
default: default:
l_error("station: Unsupported netconfig event: %d.", event); l_error("station: Unsupported netconfig event: %d.", event);
@ -2407,11 +2381,6 @@ static void station_roam_retry(struct station *station)
station->roam_scan_full = false; station->roam_scan_full = false;
station->ap_directed_roaming = 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) if (station->signal_low)
station_roam_timeout_rearm(station, roam_retry_interval); station_roam_timeout_rearm(station, roam_retry_interval);
} }
@ -2441,16 +2410,8 @@ static void station_roam_failed(struct station *station)
* We were told by the AP to roam, but failed. Try ourselves or * We were told by the AP to roam, but failed. Try ourselves or
* wait for the AP to tell us to roam again * 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; goto delayed_retry;
}
/* /*
* If we tried a limited scan, failed and the signal is still low, * If we tried a limited scan, failed and the signal is still low,
@ -2462,7 +2423,6 @@ static void station_roam_failed(struct station *station)
* the scan here, so that the destroy callback is not called * the scan here, so that the destroy callback is not called
* after the return of this function * after the return of this function
*/ */
full_scan:
scan_cancel(netdev_get_wdev_id(station->netdev), scan_cancel(netdev_get_wdev_id(station->netdev),
station->roam_scan_id); station->roam_scan_id);
@ -2750,15 +2710,11 @@ static bool station_try_next_transition(struct station *station,
enum security security = network_get_security(connected); enum security security = network_get_security(connected);
struct handshake_state *new_hs; struct handshake_state *new_hs;
struct ie_rsn_info cur_rsne, target_rsne; struct ie_rsn_info cur_rsne, target_rsne;
const char *vendor_quirks = vendor_quirks_to_string(bss->vendor_quirks);
iwd_notice(IWD_NOTICE_ROAM_INFO, "bss: "MAC", signal: %d, load: %d/255", iwd_notice(IWD_NOTICE_ROAM_INFO, "bss: "MAC", signal: %d, load: %d/255",
MAC_STR(bss->addr), MAC_STR(bss->addr),
bss->signal_strength / 100, bss->signal_strength / 100,
bss->utilization); bss->utilization);
if (vendor_quirks)
l_debug("vendor quirks for "MAC": %s",
MAC_STR(bss->addr), vendor_quirks);
/* Reset AP roam flag, at this point the roaming behaves the same */ /* Reset AP roam flag, at this point the roaming behaves the same */
station->ap_directed_roaming = false; station->ap_directed_roaming = false;
@ -3059,7 +3015,6 @@ static int station_roam_scan(struct station *station,
if (!freq_set) { if (!freq_set) {
station->roam_scan_full = true; station->roam_scan_full = true;
params.freqs = allowed; params.freqs = allowed;
station_debug_event(station, "full-roam-scan");
} else } else
scan_freq_set_constrain(freq_set, allowed); scan_freq_set_constrain(freq_set, allowed);
@ -3271,8 +3226,6 @@ static void station_ap_directed_roam(struct station *station,
uint16_t dtimer; uint16_t dtimer;
uint8_t valid_interval; uint8_t valid_interval;
bool can_roam = !station_cannot_roam(station); bool can_roam = !station_cannot_roam(station);
bool ignore_candidates =
station->connected_bss->vendor_quirks.ignore_bss_tm_candidates;
l_debug("ifindex: %u", netdev_get_ifindex(station->netdev)); l_debug("ifindex: %u", netdev_get_ifindex(station->netdev));
@ -3373,7 +3326,7 @@ static void station_ap_directed_roam(struct station *station,
} }
blacklist_add_bss(station->connected_bss->addr, blacklist_add_bss(station->connected_bss->addr,
BLACKLIST_REASON_AP_BUSY); BLACKLIST_REASON_ROAM_REQUESTED);
station_debug_event(station, "ap-roam-blacklist-added"); station_debug_event(station, "ap-roam-blacklist-added");
/* /*
@ -3390,21 +3343,12 @@ static void station_ap_directed_roam(struct station *station,
l_timeout_remove(station->roam_trigger_timeout); l_timeout_remove(station->roam_trigger_timeout);
station->roam_trigger_timeout = NULL; station->roam_trigger_timeout = NULL;
if ((req_mode & WNM_REQUEST_MODE_PREFERRED_CANDIDATE_LIST) && if (req_mode & WNM_REQUEST_MODE_PREFERRED_CANDIDATE_LIST) {
!ignore_candidates) {
l_debug("roam: AP sent a preferred candidate list"); l_debug("roam: AP sent a preferred candidate list");
station_neighbor_report_cb(station->netdev, 0, body + pos, station_neighbor_report_cb(station->netdev, 0, body + pos,
body_len - pos, station); body_len - pos, station);
} else { } else {
if (station->connected_bss->cap_rm_neighbor_report) { l_debug("roam: AP did not include a preferred candidate list");
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) if (station_roam_scan(station, NULL) < 0)
station_roam_failed(station); station_roam_failed(station);
} }
@ -3466,6 +3410,26 @@ static void station_event_channel_switched(struct station *station,
network_bss_update(network, station->connected_bss); network_bss_update(network, station->connected_bss);
} }
static bool station_try_next_bss(struct station *station)
{
struct scan_bss *next;
int ret;
next = network_bss_select(station->connected_network, false);
if (!next)
return false;
ret = __station_connect_network(station, station->connected_network,
next, station->state);
if (ret < 0)
return false;
l_debug("Attempting to connect to next BSS "MAC, MAC_STR(next->addr));
return true;
}
static bool station_retry_owe_default_group(struct station *station) static bool station_retry_owe_default_group(struct station *station)
{ {
/* /*
@ -3559,6 +3523,13 @@ static bool station_pmksa_fallback(struct station *station, uint16_t status)
return true; return true;
} }
/* A bit more concise for trying to fit these into 80 characters */
#define IS_TEMPORARY_STATUS(code) \
((code) == MMPDU_STATUS_CODE_DENIED_UNSUFFICIENT_BANDWIDTH || \
(code) == MMPDU_STATUS_CODE_DENIED_POOR_CHAN_CONDITIONS || \
(code) == MMPDU_STATUS_CODE_REJECTED_WITH_SUGG_BSS_TRANS || \
(code) == MMPDU_STATUS_CODE_DENIED_NO_MORE_STAS)
static bool station_retry_with_status(struct station *station, static bool station_retry_with_status(struct station *station,
uint16_t status_code) uint16_t status_code)
{ {
@ -3566,37 +3537,19 @@ static bool station_retry_with_status(struct station *station,
if (station_pmksa_fallback(station, status_code)) if (station_pmksa_fallback(station, status_code))
goto try_next; goto try_next;
switch (status_code) {
/* /*
* Certain Auth/Assoc failures should not cause a timeout blacklist. * Certain Auth/Assoc failures should not cause a timeout blacklist.
* In these cases we want to only temporarily blacklist the BSS until * In these cases we want to only temporarily blacklist the BSS until
* the connection is complete. * the connection is complete.
*/ *
case MMPDU_STATUS_CODE_DENIED_UNSUFFICIENT_BANDWIDTH:
case MMPDU_STATUS_CODE_DENIED_POOR_CHAN_CONDITIONS:
/*
* TODO: The WITH_SUGG_BSS_TRANS case should also include a neighbor * TODO: The WITH_SUGG_BSS_TRANS case should also include a neighbor
* report IE in the frame. This would allow us to target a * report IE in the frame. This would allow us to target a
* specific BSS on our next attempt. There is currently no way to * specific BSS on our next attempt. There is currently no way to
* obtain that IE, but this should be done in the future. * obtain that IE, but this should be done in the future.
*/
case MMPDU_STATUS_CODE_REJECTED_WITH_SUGG_BSS_TRANS:
break;
/*
* If a BSS is indicating its unable to handle more connections we will
* blacklist this the same way we do for BSS's issuing BSS-TM requests
* thereby avoiding roams to this BSS for the configured timeout.
*/ */
case MMPDU_STATUS_CODE_DENIED_NO_MORE_STAS: if (!IS_TEMPORARY_STATUS(status_code))
blacklist_add_bss(station->connected_bss->addr,
BLACKLIST_REASON_AP_BUSY);
break;
/* For any other status codes, blacklist the BSS */
default:
blacklist_add_bss(station->connected_bss->addr, blacklist_add_bss(station->connected_bss->addr,
BLACKLIST_REASON_CONNECT_FAILED); BLACKLIST_REASON_CONNECT_FAILED);
break;
}
/* /*
* Unconditionally network blacklist the BSS if we are retrying. This * Unconditionally network blacklist the BSS if we are retrying. This
@ -3618,6 +3571,13 @@ static void station_connect_ok(struct station *station)
l_debug(""); l_debug("");
if (station->connect_pending) {
struct l_dbus_message *reply =
l_dbus_message_new_method_return(
station->connect_pending);
dbus_pending_reply(&station->connect_pending, reply);
}
/* /*
* Get a neighbor report now so future roams can avoid waiting for * Get a neighbor report now so future roams can avoid waiting for
* a report at that time * a report at that time
@ -3917,7 +3877,6 @@ int __station_connect_network(struct station *station, struct network *network,
{ {
struct handshake_state *hs; struct handshake_state *hs;
int r; int r;
const char *vendor_quirks = vendor_quirks_to_string(bss->vendor_quirks);
/* /*
* If we already have a handshake_state ref this is due to a retry, * If we already have a handshake_state ref this is due to a retry,
@ -3952,10 +3911,6 @@ int __station_connect_network(struct station *station, struct network *network,
bss->signal_strength / 100, bss->signal_strength / 100,
bss->utilization); bss->utilization);
if (vendor_quirks)
l_debug("vendor quirks for "MAC": %s",
MAC_STR(bss->addr), vendor_quirks);
station->connected_bss = bss; station->connected_bss = bss;
station->connected_network = network; station->connected_network = network;
station->hs = handshake_state_ref(hs); station->hs = handshake_state_ref(hs);

View File

@ -1,84 +0,0 @@
/*
*
* 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 <stdio.h>
#include <ell/ell.h>
#include "src/vendor_quirks.h"
static const struct {
uint8_t oui[3];
struct vendor_quirk quirks;
} oui_quirk_db[] = {
{
/* Cisco Meraki */
{ 0x00, 0x18, 0x0a },
{ .ignore_bss_tm_candidates = true },
},
{
/* Hewlett Packard, owns Aruba */
{ 0x00, 0x0b, 0x86 },
{ .replay_counter_mismatch = true },
},
};
void vendor_quirks_append_for_oui(const uint8_t *oui,
struct vendor_quirk *quirks)
{
size_t i;
for (i = 0; i < L_ARRAY_SIZE(oui_quirk_db); i++) {
const struct vendor_quirk *quirk = &oui_quirk_db[i].quirks;
if (memcmp(oui_quirk_db[i].oui, oui, 3))
continue;
quirks->ignore_bss_tm_candidates |=
quirk->ignore_bss_tm_candidates;
quirks->replay_counter_mismatch |=
quirk->replay_counter_mismatch;
}
}
const char *vendor_quirks_to_string(struct vendor_quirk quirks)
{
static char out[1024];
char *pos = out;
size_t s = 0;
if (quirks.ignore_bss_tm_candidates)
s += snprintf(pos, sizeof(out) - s, "IgnoreBssTmCandidateList");
if (quirks.replay_counter_mismatch)
s += snprintf(pos, sizeof(out) - s, "ReplayCounterMismatch");
if (!s)
return NULL;
return out;
}

View File

@ -1,39 +0,0 @@
/*
*
* 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
*
*/
#ifndef __IWD_VENDOR_QUIRKS_H
#define __IWD_VENDOR_QUIRKS_H
#include <stdint.h>
struct vendor_quirk {
bool ignore_bss_tm_candidates : 1;
bool replay_counter_mismatch : 1;
};
void vendor_quirks_append_for_oui(const uint8_t *oui,
struct vendor_quirk *quirks);
const char *vendor_quirks_to_string(struct vendor_quirk quirks);
#endif /* __IWD_VENDOR_QUIRKS_H */

View File

@ -69,26 +69,12 @@ static uint32_t work_ids;
static unsigned int wiphy_dump_id; static unsigned int wiphy_dump_id;
enum driver_flag { enum driver_flag {
/* Force the use of the default interface created by the kernel */
DEFAULT_IF = 0x1, DEFAULT_IF = 0x1,
/*
* Force the use of the PAE socket rather than control port, even if
* control port is supported
*/
FORCE_PAE = 0x2, FORCE_PAE = 0x2,
/* Disable power save on the adapter during initialization */
POWER_SAVE_DISABLE = 0x4, POWER_SAVE_DISABLE = 0x4,
/* Don't use OWE when connecting to open networks */
OWE_DISABLE = 0x8, OWE_DISABLE = 0x8,
/* Disables multicast RX frame registration */
MULTICAST_RX_DISABLE = 0x10, 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, SAE_DISABLE = 0x20,
/* Disables use of the NL80211_SCAN_FLAG_COLOCATED_6GHZ flag in scans */
COLOCATED_SCAN_DISABLE = 0x40,
}; };
struct driver_flag_name { struct driver_flag_name {
@ -117,13 +103,12 @@ static const struct driver_info driver_infos[] = {
}; };
static const struct driver_flag_name driver_flag_names[] = { static const struct driver_flag_name driver_flag_names[] = {
{ "DefaultInterface", DEFAULT_IF }, { "DefaultInterface", DEFAULT_IF },
{ "ForcePae", FORCE_PAE }, { "ForcePae", FORCE_PAE },
{ "PowerSaveDisable", POWER_SAVE_DISABLE }, { "PowerSaveDisable", POWER_SAVE_DISABLE },
{ "OweDisable", OWE_DISABLE }, { "OweDisable", OWE_DISABLE },
{ "MulticastRxDisable", MULTICAST_RX_DISABLE }, { "MulticastRxDisable", MULTICAST_RX_DISABLE },
{ "SaeDisable", SAE_DISABLE }, { "SaeDisable", SAE_DISABLE },
{ "ColocatedScanDisable", COLOCATED_SCAN_DISABLE },
}; };
struct wiphy { struct wiphy {
@ -978,11 +963,6 @@ bool wiphy_supports_multicast_rx(const struct wiphy *wiphy)
!(wiphy->driver_flags & MULTICAST_RX_DISABLE); !(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, const uint8_t *wiphy_get_ht_capabilities(const struct wiphy *wiphy,
enum band_freq band, enum band_freq band,
size_t *size) size_t *size)
@ -1402,9 +1382,6 @@ static void wiphy_print_basic_info(struct wiphy *wiphy)
if (wiphy->driver_flags & SAE_DISABLE) if (wiphy->driver_flags & SAE_DISABLE)
flags = l_strv_append(flags, "SaeDisable"); flags = l_strv_append(flags, "SaeDisable");
if (wiphy->driver_flags & COLOCATED_SCAN_DISABLE)
flags = l_strv_append(flags, "ColocatedScanDisable");
joined = l_strjoinv(flags, ' '); joined = l_strjoinv(flags, ' ');
l_info("\tDriver Flags: %s", joined); l_info("\tDriver Flags: %s", joined);

View File

@ -144,7 +144,6 @@ bool wiphy_country_is_unknown(struct wiphy *wiphy);
bool wiphy_supports_uapsd(const struct wiphy *wiphy); bool wiphy_supports_uapsd(const struct wiphy *wiphy);
bool wiphy_supports_cmd_offchannel(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_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, const uint8_t *wiphy_get_ht_capabilities(const struct wiphy *wiphy,
enum band_freq band, enum band_freq band,

View File

@ -2581,8 +2581,7 @@ static bool getrandom_precheck(const void *data)
static bool aes_cbc_precheck(const void *data) static bool aes_cbc_precheck(const void *data)
{ {
return (l_key_is_supported(L_KEY_FEATURE_DH) && return l_cipher_is_supported(L_CIPHER_AES_CBC);
l_cipher_is_supported(L_CIPHER_AES_CBC));
} }
static bool key_crypto_precheck(const void *data) static bool key_crypto_precheck(const void *data)