[PATCH 01/18] auto-t: hostapd.py: add 'bssid' property
by James Prestwood
This gets the APs BSSID, bypassing the need to use hwsim
for obtaining this address.
---
autotests/util/hostapd.py | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/autotests/util/hostapd.py b/autotests/util/hostapd.py
index 6031b1dc..f75dbe6b 100644
--- a/autotests/util/hostapd.py
+++ b/autotests/util/hostapd.py
@@ -234,3 +234,13 @@ class HostapdCLI:
'''
cmd = self.cmdline + ['req_beacon', addr, request]
ctx.start_process(cmd, wait=True)
+
+ @property
+ def bssid(self):
+ cmd = self.cmdline + ['status']
+ status = ctx.start_process(cmd, wait=True, need_out=True).out
+ status = status.split('\n')
+
+ bssid = [x for x in status if x.startswith('bssid')]
+ bssid = bssid[0].split('=')
+ return bssid[1]
--
2.31.1
9 months, 1 week
[PATCH v4 1/3] station: add ConnectBssid() developer method
by James Prestwood
This method will initiate a connection to a specific BSS rather
than relying on a network based connection (which the user has
no control over which specific BSS is selected).
---
src/station.c | 143 ++++++++++++++++++++++++++++++++++++++------------
1 file changed, 109 insertions(+), 34 deletions(-)
v4:
* Reworked station_parse_bss to just parse security
* Updated the common code in station to use station_parse_bss_security
* Limited ConnectBssid() to only non-hidden networks
diff --git a/src/station.c b/src/station.c
index bc4e7539..49f78fce 100644
--- a/src/station.c
+++ b/src/station.c
@@ -286,6 +286,25 @@ static int bss_signal_strength_compare(const void *a, const void *b, void *user)
return (bss->signal_strength > new_bss->signal_strength) ? 1 : -1;
}
+static int station_parse_bss_security(struct station *station,
+ struct scan_bss *bss,
+ enum security *security_out)
+{
+ struct ie_rsn_info info;
+ int r;
+
+ r = scan_bss_get_rsn_info(bss, &info);
+ if (r < 0) {
+ if (r != -ENOENT)
+ return r;
+
+ *security_out = security_determine(bss->capability, NULL);
+ } else
+ *security_out = security_determine(bss->capability, &info);
+
+ return 0;
+}
+
/*
* Returns the network object the BSS was added to or NULL if ignored.
*/
@@ -293,8 +312,6 @@ static struct network *station_add_seen_bss(struct station *station,
struct scan_bss *bss)
{
struct network *network;
- struct ie_rsn_info info;
- int r;
enum security security;
const char *path;
char ssid[33];
@@ -323,15 +340,8 @@ static struct network *station_add_seen_bss(struct station *station,
return NULL;
}
- memset(&info, 0, sizeof(info));
- r = scan_bss_get_rsn_info(bss, &info);
- if (r < 0) {
- if (r != -ENOENT)
- return NULL;
-
- security = security_determine(bss->capability, NULL);
- } else
- security = security_determine(bss->capability, &info);
+ if (station_parse_bss_security(station, bss, &security) < 0)
+ return NULL;
path = iwd_network_get_path(station, ssid, security);
@@ -1872,8 +1882,6 @@ static bool station_roam_scan_notify(int err, struct l_queue *bss_list,
while ((bss = l_queue_pop_head(bss_list))) {
double rank;
- struct ie_rsn_info info;
- int r;
/* Skip the BSS we are connected to if doing an AP roam */
if (station->ap_directed_roaming && !memcmp(bss->addr,
@@ -1886,15 +1894,8 @@ static bool station_roam_scan_notify(int err, struct l_queue *bss_list,
memcmp(bss->ssid, hs->ssid, hs->ssid_len))
goto next;
- memset(&info, 0, sizeof(info));
- r = scan_bss_get_rsn_info(bss, &info);
- if (r < 0) {
- if (r != -ENOENT)
- goto next;
-
- security = security_determine(bss->capability, NULL);
- } else
- security = security_determine(bss->capability, &info);
+ if (station_parse_bss_security(station, bss, &security) < 0)
+ goto next;
if (security != orig_security)
goto next;
@@ -3023,20 +3024,10 @@ static struct l_dbus_message *station_dbus_get_hidden_access_points(
entry; entry = entry->next) {
struct scan_bss *bss = entry->data;
int16_t signal_strength = bss->signal_strength;
- struct ie_rsn_info info;
enum security security;
- int r;
- memset(&info, 0, sizeof(info));
- r = scan_bss_get_rsn_info(bss, &info);
- if (r < 0) {
- if (r != -ENOENT)
- continue;
-
- security = security_determine(bss->capability, NULL);
- } else {
- security = security_determine(bss->capability, &info);
- }
+ if (station_parse_bss_security(station, bss, &security) < 0)
+ continue;
l_dbus_message_builder_enter_struct(builder, "sns");
l_dbus_message_builder_append_basic(builder, 's',
@@ -3540,6 +3531,12 @@ static struct station *station_create(struct netdev *netdev)
station_fill_scan_freq_subsets(station);
+ if (iwd_is_developer_mode())
+ l_dbus_object_add_interface(dbus,
+ netdev_get_path(station->netdev),
+ IWD_STATION_DEBUG_INTERFACE,
+ station);
+
return station;
}
@@ -3553,6 +3550,10 @@ static void station_free(struct station *station)
l_dbus_object_remove_interface(dbus_get_bus(),
netdev_get_path(station->netdev),
IWD_STATION_DIAGNOSTIC_INTERFACE);
+ if (iwd_is_developer_mode())
+ l_dbus_object_remove_interface(dbus_get_bus(),
+ netdev_get_path(station->netdev),
+ IWD_STATION_DEBUG_INTERFACE);
if (station->netconfig) {
netconfig_destroy(station->netconfig);
@@ -3761,6 +3762,21 @@ invalid_args:
return dbus_error_invalid_args(message);
}
+static struct network *station_find_network_from_bss(struct station *station,
+ struct scan_bss *bss)
+{
+ enum security security;
+ char ssid[33];
+
+ memcpy(ssid, bss->ssid, bss->ssid_len);
+ ssid[bss->ssid_len] = '\0';
+
+ if (station_parse_bss_security(station, bss, &security) < 0)
+ return NULL;
+
+ return station_network_find(station, ssid, security);
+}
+
static void station_setup_diagnostic_interface(
struct l_dbus_interface *interface)
{
@@ -3777,6 +3793,56 @@ static void station_destroy_diagnostic_interface(void *user_data)
{
}
+static struct l_dbus_message *station_force_connect_bssid(struct l_dbus *dbus,
+ struct l_dbus_message *message,
+ void *user_data)
+{
+ struct station *station = user_data;
+ struct l_queue *bss_list;
+ struct scan_bss *target;
+ struct network *network;
+ struct l_dbus_message_iter iter;
+ uint8_t *mac;
+ uint32_t mac_len;
+
+ if (!l_dbus_message_get_arguments(message, "ay", &iter))
+ goto invalid_args;
+
+ if (!l_dbus_message_iter_get_fixed_array(&iter, &mac, &mac_len))
+ goto invalid_args;
+
+ if (mac_len != 6)
+ return dbus_error_invalid_args(message);
+
+ bss_list = station_get_bss_list(station);
+
+ target = l_queue_find(bss_list, bss_match_bssid, mac);
+ if (!target)
+ return dbus_error_invalid_args(message);
+
+ if (util_ssid_is_hidden(target->ssid_len, target->ssid))
+ return dbus_error_not_found(message);
+
+ network = station_find_network_from_bss(station, target);
+ if (!network)
+ return dbus_error_invalid_args(message);
+
+ l_debug("Attempting forced connection to BSS "MAC, MAC_STR(mac));
+
+ return __network_connect(network, target, message);
+
+invalid_args:
+ return dbus_error_invalid_args(message);
+}
+
+static void station_setup_debug_interface(
+ struct l_dbus_interface *interface)
+{
+ l_dbus_interface_method(interface, "ConnectBssid", 0,
+ station_force_connect_bssid, "", "ay",
+ "mac");
+}
+
static void ap_roam_frame_event(const struct mmpdu_header *hdr,
const void *body, size_t body_len,
int rssi, void *user_data)
@@ -3848,6 +3914,12 @@ static int station_init(void)
station_setup_diagnostic_interface,
station_destroy_diagnostic_interface,
false);
+ if (iwd_is_developer_mode())
+ l_dbus_register_interface(dbus_get_bus(),
+ IWD_STATION_DEBUG_INTERFACE,
+ station_setup_debug_interface,
+ NULL,
+ false);
if (!l_settings_get_uint(iwd_get_config(), "General",
"ManagementFrameProtection",
@@ -3889,6 +3961,9 @@ static void station_exit(void)
{
l_dbus_unregister_interface(dbus_get_bus(),
IWD_STATION_DIAGNOSTIC_INTERFACE);
+ if (iwd_is_developer_mode())
+ l_dbus_unregister_interface(dbus_get_bus(),
+ IWD_STATION_DEBUG_INTERFACE);
l_dbus_unregister_interface(dbus_get_bus(), IWD_STATION_INTERFACE);
netdev_watch_remove(netdev_watch);
l_queue_destroy(station_list, NULL);
--
2.31.1
9 months, 1 week
[PATCH v3 1/4] netdev: move failure point out of netdev_connect_common
by James Prestwood
The only point of failure in netdev_connect_common was setting
up the handshake type. Moving this outside of netdev_connect_common
makes the code flow much better in netdev_{connect,reassociate} as
nothing needs to be reset upon failure.
---
src/netdev.c | 37 ++++++++++++++++++++-----------------
1 file changed, 20 insertions(+), 17 deletions(-)
v3:
* Fixed previous break to open networks due to netdev_connect_common
not handling the !is_rsn special case. This check was moved into
netdev_handshake_state_setup_connection_type.
diff --git a/src/netdev.c b/src/netdev.c
index 1b72b0a7..f9731892 100644
--- a/src/netdev.c
+++ b/src/netdev.c
@@ -3364,6 +3364,9 @@ static int netdev_handshake_state_setup_connection_type(
bool softmac = wiphy_supports_cmds_auth_assoc(wiphy);
bool canroam = wiphy_supports_firmware_roam(wiphy);
+ if (hs->supplicant_ie == NULL)
+ goto softmac;
+
/*
* Sanity check that any FT AKMs are set only on softmac or on
* devices that support firmware roam
@@ -3442,7 +3445,7 @@ offload_1x:
return 0;
}
-static int netdev_connect_common(struct netdev *netdev,
+static void netdev_connect_common(struct netdev *netdev,
struct scan_bss *bss,
struct scan_bss *prev_bss,
struct handshake_state *hs,
@@ -3458,13 +3461,8 @@ static int netdev_connect_common(struct netdev *netdev,
bool is_rsn = hs->supplicant_ie != NULL;
const uint8_t *prev_bssid = prev_bss ? prev_bss->addr : NULL;
- if (!is_rsn) {
- nhs->type = CONNECTION_TYPE_SOFTMAC;
+ if (!is_rsn)
goto build_cmd_connect;
- }
-
- if (netdev_handshake_state_setup_connection_type(hs) < 0)
- return -ENOTSUP;
if (nhs->type != CONNECTION_TYPE_SOFTMAC)
goto build_cmd_connect;
@@ -3534,7 +3532,7 @@ build_cmd_connect:
wiphy_radio_work_insert(netdev->wiphy, &netdev->work, 1,
&connect_work_ops);
- return 0;
+ return;
}
int netdev_connect(struct netdev *netdev, struct scan_bss *bss,
@@ -3554,9 +3552,14 @@ int netdev_connect(struct netdev *netdev, struct scan_bss *bss,
if (netdev->connected || netdev->connect_cmd_id || netdev->work.id)
return -EISCONN;
- return netdev_connect_common(netdev, bss, NULL, hs, vendor_ies,
+ if (netdev_handshake_state_setup_connection_type(hs) < 0)
+ return -ENOTSUP;
+
+ netdev_connect_common(netdev, bss, NULL, hs, vendor_ies,
num_vendor_ies, event_filter, cb,
user_data);
+
+ return 0;
}
static void disconnect_idle(struct l_idle *idle, void *user_data)
@@ -3646,24 +3649,24 @@ int netdev_reassociate(struct netdev *netdev, struct scan_bss *target_bss,
{
struct handshake_state *old_hs;
struct eapol_sm *old_sm;
- int ret;
old_sm = netdev->sm;
old_hs = netdev->handshake;
- ret = netdev_connect_common(netdev, target_bss, orig_bss, hs, NULL, 0,
- event_filter, cb, user_data);
- if (ret < 0)
- return ret;
-
- if (netdev->ap)
- memcpy(netdev->ap->prev_bssid, orig_bss->addr, ETH_ALEN);
+ if (netdev_handshake_state_setup_connection_type(hs) < 0)
+ return -ENOTSUP;
netdev->associated = false;
netdev->operational = false;
netdev->connected = false;
netdev->in_reassoc = true;
+ netdev_connect_common(netdev, target_bss, orig_bss, hs, NULL, 0,
+ event_filter, cb, user_data);
+
+ if (netdev->ap)
+ memcpy(netdev->ap->prev_bssid, orig_bss->addr, ETH_ALEN);
+
netdev_rssi_polling_update(netdev);
if (old_sm)
--
2.31.1
9 months, 1 week
Failing to resolve after roams
by Michael Johnson
Hi all,
I'm having a problem with iwd when it comes to roaming. Most of the
time it is working perfectly but rarely I get into this situation
where I can't resolve any hostnames.
I'm using a default server setup on ubuntu which uses systemd-networkd
and systemd-resolved with iwd configured to use
`EnableNetworkConfiguration=true`.
Here are the debug logs of a failure case:
```
Aug 10 09:48:04.120612 p3-631 systemd-networkd[341]: wlan0: Lost carrier
Aug 10 09:48:04.121287 p3-631 kernel: wlan0: send auth to <BSSID> (try 1/3)
Aug 10 09:48:04.123440 p3-631 iwd[413]:
src/netdev.c:netdev_mlme_notify() MLME notification Authenticate(37)
Aug 10 09:48:04.123440 p3-631 iwd[413]: src/netdev.c:netdev_authenticate_event()
Aug 10 09:48:04.125236 p3-631 kernel: wlan0: authenticated
Aug 10 09:48:04.125339 p3-631 kernel: wlan0: associate with <BSSID> (try 1/3)
Aug 10 09:48:04.133316 p3-631 kernel: wlan0: RX ReassocResp from
<BSSID> (capab=0x1511 status=0 aid=8)
Aug 10 09:48:04.134574 p3-631 iwd[413]:
src/netdev.c:netdev_mlme_notify() MLME notification Associate(38)
Aug 10 09:48:04.134574 p3-631 iwd[413]: src/netdev.c:netdev_associate_event()
Aug 10 09:48:04.134574 p3-631 iwd[413]: src/netdev.c:netdev_set_gtk() 5
Aug 10 09:48:04.134574 p3-631 iwd[413]:
src/station.c:station_handshake_event() Setting keys
Aug 10 09:48:04.134574 p3-631 iwd[413]: src/netdev.c:netdev_set_tk() 5
Aug 10 09:48:04.134574 p3-631 iwd[413]:
src/netdev.c:netdev_mlme_notify() MLME notification Connect(46)
Aug 10 09:48:04.134574 p3-631 iwd[413]: src/netdev.c:netdev_connect_event()
Aug 10 09:48:04.135502 p3-631 iwd[413]:
src/station.c:station_fast_transition_cb() 5, result: 0
Aug 10 09:48:04.135502 p3-631 iwd[413]:
src/station.c:station_enter_state() Old State: roaming, new state:
connected
Aug 10 09:48:04.135502 p3-631 iwd[413]:
src/wiphy.c:wiphy_radio_work_done() Work item 315 done
Aug 10 09:48:04.135791 p3-631 iwd[413]:
src/netdev.c:netdev_link_notify() event 16 on ifindex 5
Aug 10 09:48:04.135936 p3-631 iwd[413]:
src/netdev.c:netdev_link_notify() event 16 on ifindex 5
Aug 10 09:48:04.136075 p3-631 iwd[413]:
src/netdev.c:netdev_link_notify() event 16 on ifindex 5
Aug 10 09:48:04.136231 p3-631 iwd[413]:
src/netdev.c:netdev_link_notify() event 16 on ifindex 5
Aug 10 09:48:04.136460 p3-631 iwd[413]: src/wiphy.c:wiphy_reg_notify()
Notification of command Reg Change(36)
Aug 10 09:48:04.136460 p3-631 iwd[413]:
src/wiphy.c:wiphy_update_reg_domain() New reg domain country code for
(global) is US
Aug 10 09:48:04.136741 p3-631 iwd[413]:
src/netdev.c:netdev_mlme_notify() MLME notification Frame TX
Status(60)
Aug 10 09:48:04.137287 p3-631 kernel: wlan0: associated
```
```
$ sudo resolvectl status
...
Link 5 (wlan0)
Current Scopes: none
```
What I noticed is that when the roam works, there is a
`systemd-networkd[341]: wlan0: Gained carrier` line at the end which
is missing here.
Unfortunately it happens rarely enough that capturing the netlink
traffic is a pain so I can't see if the issue is on the iwd or systemd
side.
Has anyone else seen something like this?
Kind Regards,
Michael
9 months, 1 week
[PATCH 1/3] storage: provide storage_is_file
by Matt Oberle
Add a function 'storage_is_file' which will use stat to verify a
file's existence given a path relative to the storage directory.
Not all filesystems provide a file type via readdir's d_type.
XFS is a notable system with optional d_type support.
When d_type is not supported stat must be used as a fallback.
If a stat fallback is not provided iwd will fail to load state files.
---
src/storage.c | 18 ++++++++++++++++++
src/storage.h | 1 +
2 files changed, 19 insertions(+)
diff --git a/src/storage.c b/src/storage.c
index 00d93933..4b89c615 100644
--- a/src/storage.c
+++ b/src/storage.c
@@ -29,11 +29,13 @@
#include <errno.h>
#include <ctype.h>
#include <fcntl.h>
+#include <stdbool.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
+#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -445,3 +447,19 @@ void storage_known_frequencies_sync(struct l_settings *known_freqs)
l_free(known_freq_file_path);
}
+
+bool storage_is_file(const char *filename)
+{
+ char *path;
+ struct stat st;
+ int err;
+
+ path = storage_get_path("%s", filename);
+ err = stat(path, &st);
+ l_free(path);
+
+ if (!err && S_ISREG(st.st_mode) != 0)
+ return true;
+
+ return false;
+}
diff --git a/src/storage.h b/src/storage.h
index 80b63c53..e1ec2cd4 100644
--- a/src/storage.h
+++ b/src/storage.h
@@ -32,6 +32,7 @@ ssize_t write_file(const void *buffer, size_t len, bool preserve_times,
const char *path_fmt, ...)
__attribute__((format(printf, 4, 5)));
+bool storage_is_file(const char *filename);
bool storage_create_dirs(void);
void storage_cleanup_dirs(void);
char *storage_get_path(const char *format, ...);
--
2.32.0
9 months, 1 week
How to connect to client network using ell dbus interface
by salahaldeen.altous@leica-camera.com
Hi,
I am trying to integrate station API to my application (C code), I am using the interface net.connman.iwd.Station to run a scan() and the interface net.connman.iwd.Network to connect() but how I can start a simple agent to provide the password? Can you provide me with a complete procedure to connect to WP2 network using ell dbus binding?
Regards,
Salahaldeen
9 months, 1 week
how to get info about connected clients when iwd runs in AP mode?
by salahaldeen.altous@leica-camera.com
Hi,
I have a device which running as AP point. I would like to know every time there is a new connection/discounntion for this access point.
Does iwd API support this? DHCP is enable in AP configuration (EnableNetworkConfiguration=True)
Regards,
Salahaldeen Altous
9 months, 1 week
iwd provides only Legacy Access point (802.11b)
by salahaldeen.altous@leica-camera.com
Hi,
I have my device started as AP and when I connect to iPhone, this warning comes (Legacy access Point 802.11b provides sub-optimal performance!!).
Is that possible to run iwd with 802.11g/n mode? my hardware support support all these modes.
Best regards,
Salahaldeen Altous
9 months, 1 week
[PATCH] test-runner: Drop unused parameter
by Andrew Zaborowski
---
tools/test-runner | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/test-runner b/tools/test-runner
index 75e46444..f5ab7c58 100755
--- a/tools/test-runner
+++ b/tools/test-runner
@@ -164,7 +164,7 @@ class Process:
case.
'''
def __init__(self, args, wait=False, env=None, ctx=None, check=False,
- outfile=None, namespace=None, need_out=False, cleanup=None):
+ outfile=None, namespace=None, cleanup=None):
self.killed = False
self.args = args
self.wait = wait
--
2.30.2
9 months, 1 week
[PATCH v2 1/4] netdev: move failure point out of netdev_connect_common
by James Prestwood
The only point of failure in netdev_connect_common was setting
up the handshake type. Moving this outside of netdev_connect_common
makes the code flow much better in netdev_{connect,reassociate} as
nothing needs to be reset upon failure.
---
src/netdev.c | 30 ++++++++++++++++--------------
1 file changed, 16 insertions(+), 14 deletions(-)
diff --git a/src/netdev.c b/src/netdev.c
index 1b72b0a7..479791fd 100644
--- a/src/netdev.c
+++ b/src/netdev.c
@@ -3442,7 +3442,7 @@ offload_1x:
return 0;
}
-static int netdev_connect_common(struct netdev *netdev,
+static void netdev_connect_common(struct netdev *netdev,
struct scan_bss *bss,
struct scan_bss *prev_bss,
struct handshake_state *hs,
@@ -3463,9 +3463,6 @@ static int netdev_connect_common(struct netdev *netdev,
goto build_cmd_connect;
}
- if (netdev_handshake_state_setup_connection_type(hs) < 0)
- return -ENOTSUP;
-
if (nhs->type != CONNECTION_TYPE_SOFTMAC)
goto build_cmd_connect;
@@ -3534,7 +3531,7 @@ build_cmd_connect:
wiphy_radio_work_insert(netdev->wiphy, &netdev->work, 1,
&connect_work_ops);
- return 0;
+ return;
}
int netdev_connect(struct netdev *netdev, struct scan_bss *bss,
@@ -3554,9 +3551,14 @@ int netdev_connect(struct netdev *netdev, struct scan_bss *bss,
if (netdev->connected || netdev->connect_cmd_id || netdev->work.id)
return -EISCONN;
- return netdev_connect_common(netdev, bss, NULL, hs, vendor_ies,
+ if (netdev_handshake_state_setup_connection_type(hs) < 0)
+ return -ENOTSUP;
+
+ netdev_connect_common(netdev, bss, NULL, hs, vendor_ies,
num_vendor_ies, event_filter, cb,
user_data);
+
+ return 0;
}
static void disconnect_idle(struct l_idle *idle, void *user_data)
@@ -3646,24 +3648,24 @@ int netdev_reassociate(struct netdev *netdev, struct scan_bss *target_bss,
{
struct handshake_state *old_hs;
struct eapol_sm *old_sm;
- int ret;
old_sm = netdev->sm;
old_hs = netdev->handshake;
- ret = netdev_connect_common(netdev, target_bss, orig_bss, hs, NULL, 0,
- event_filter, cb, user_data);
- if (ret < 0)
- return ret;
-
- if (netdev->ap)
- memcpy(netdev->ap->prev_bssid, orig_bss->addr, ETH_ALEN);
+ if (netdev_handshake_state_setup_connection_type(hs) < 0)
+ return -ENOTSUP;
netdev->associated = false;
netdev->operational = false;
netdev->connected = false;
netdev->in_reassoc = true;
+ netdev_connect_common(netdev, target_bss, orig_bss, hs, NULL, 0,
+ event_filter, cb, user_data);
+
+ if (netdev->ap)
+ memcpy(netdev->ap->prev_bssid, orig_bss->addr, ETH_ALEN);
+
netdev_rssi_polling_update(netdev);
if (old_sm)
--
2.31.1
9 months, 1 week