[PATCH 1/4] crypto: use void* args for aes_siv_{encrypt,decrypt}
by James Prestwood
This makes these APIs more flexible for other storage types
---
src/crypto.c | 8 ++++----
src/crypto.h | 8 ++++----
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/crypto.c b/src/crypto.c
index 3f516940..c5bf6fe1 100644
--- a/src/crypto.c
+++ b/src/crypto.c
@@ -321,9 +321,9 @@ static bool s2v(struct l_checksum *cmac, struct iovec *iov, size_t iov_len,
/*
* RFC 5297 Section 2.6 - SIV Encrypt
*/
-bool aes_siv_encrypt(const uint8_t *key, size_t key_len, const uint8_t *in,
+bool aes_siv_encrypt(const void *key, size_t key_len, const void *in,
size_t in_len, struct iovec *ad, size_t num_ad,
- uint8_t *out)
+ void *out)
{
struct l_checksum *cmac;
struct l_cipher *ctr;
@@ -374,9 +374,9 @@ free_ctr:
return false;
}
-bool aes_siv_decrypt(const uint8_t *key, size_t key_len, const uint8_t *in,
+bool aes_siv_decrypt(const void *key, size_t key_len, const void *in,
size_t in_len, struct iovec *ad, size_t num_ad,
- uint8_t *out)
+ void *out)
{
struct l_checksum *cmac;
struct l_cipher *ctr;
diff --git a/src/crypto.h b/src/crypto.h
index d359da61..eb48fe5b 100644
--- a/src/crypto.h
+++ b/src/crypto.h
@@ -83,12 +83,12 @@ bool aes_wrap(const uint8_t *kek, const uint8_t *in, size_t len, uint8_t *out);
bool arc4_skip(const uint8_t *key, size_t key_len, size_t skip,
const uint8_t *in, size_t len, uint8_t *out);
-bool aes_siv_encrypt(const uint8_t *key, size_t key_len, const uint8_t *in,
+bool aes_siv_encrypt(const void *key, size_t key_len, const void *in,
size_t in_len, struct iovec *ad, size_t num_ad,
- uint8_t *out);
-bool aes_siv_decrypt(const uint8_t *key, size_t key_len, const uint8_t *in,
+ void *out);
+bool aes_siv_decrypt(const void *key, size_t key_len, const void *in,
size_t in_len, struct iovec *ad, size_t num_ad,
- uint8_t *out);
+ void *out);
int crypto_cipher_key_len(enum crypto_cipher cipher);
int crypto_cipher_tk_bits(enum crypto_cipher cipher);
--
2.31.1
5 months, 3 weeks
[PATCH] Enable DBus activation on non-systemd systems.
by Mark Hindley
I have been investigating why legacy DBus activation does not work for iwd on
non-systemd systems. In Debian and Devuan (at least) this has required
alternative means of starting the daemon by initscript be implemented.
However, DBus activation without systemd is possible, without any
impact on systems running systemd.
For this to be supported there are 3 aspects that need to be addressed:
- net.connman.iwd.service: set Exec to iwd path.
- client/dbus-proxy.c: always call get_managed_objects() on init.
- src/main/c: register Object Manager before acquiring name otherwise the call
to get_managed_objects() which triggers activation fails with 'No matching
method found'.
Signed-off-by: Mark Hindley <mark(a)hindley.org.uk>
---
client/dbus-proxy.c | 3 +--
src/main.c | 6 +++---
src/{net.connman.iwd.service => net.connman.iwd.service.in} | 2 +-
3 files changed, 5 insertions(+), 6 deletions(-)
rename src/{net.connman.iwd.service => net.connman.iwd.service.in} (77%)
diff --git a/client/dbus-proxy.c b/client/dbus-proxy.c
index ab9fb5a5..15bb4128 100644
--- a/client/dbus-proxy.c
+++ b/client/dbus-proxy.c
@@ -855,13 +855,12 @@ bool dbus_proxy_init(void)
l_dbus_set_disconnect_handler(dbus, dbus_disconnect_callback, NULL,
NULL);
+ get_managed_objects();
if (command_is_interactive_mode())
l_dbus_add_service_watch(dbus, IWD_SERVICE,
service_appeared_callback,
service_disappeared_callback,
NULL, NULL);
- else
- get_managed_objects();
return true;
}
diff --git a/src/main.c b/src/main.c
index 989665e4..8e3a5ca7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -191,9 +191,6 @@ static void request_name_callback(struct l_dbus *dbus, bool success,
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) ||
@@ -240,6 +237,9 @@ static void dbus_ready(void *user_data)
{
struct l_dbus *dbus = user_data;
+ if (!l_dbus_object_manager_enable(dbus, "/"))
+ l_warn("Unable to register the ObjectManager");
+
l_dbus_name_acquire(dbus, "net.connman.iwd", false, false, false,
request_name_callback, NULL);
diff --git a/src/net.connman.iwd.service b/src/net.connman.iwd.service.in
similarity index 77%
rename from src/net.connman.iwd.service
rename to src/net.connman.iwd.service.in
index d8ece4c3..a7cb7edd 100644
--- a/src/net.connman.iwd.service
+++ b/src/net.connman.iwd.service.in
@@ -1,5 +1,5 @@
[D-BUS Service]
Name=net.connman.iwd
-Exec=/bin/false
+Exec=@libexecdir@/iwd
User=root
SystemdService=iwd.service
--
2.20.1
6 months
[PATCH 1/9] netconfig: Refactor setting new values to system
by Andrew Zaborowski
Refactor and unify how the netconfig values, that we obtain from DHCP or
the settings or otherwise, are written/committed to the system netdevs.
We basically concentrate all of those actions in a new function
netconfig_set() that is called whenever any value changes. The only
exceptions are the sysfs writes and some of the ARP table writes.
This will allow us to more easily delegate committing the values to an
(optional) D-Bus agent, or expose them as D-Bus properties if we ever
choose to do that in the future. For that I'm also passing a bitmask
telling netconfig_set() which values may have actually changed, so we
don't bother looking at those that definitely haven't changed.
---
src/netconfig.c | 541 +++++++++++++++++++++++++++++++++++-------------
1 file changed, 398 insertions(+), 143 deletions(-)
diff --git a/src/netconfig.c b/src/netconfig.c
index e7fd4855..ea77e818 100644
--- a/src/netconfig.c
+++ b/src/netconfig.c
@@ -52,6 +52,15 @@
#include "src/netconfig.h"
#include "src/sysfs.h"
+enum netconfig_changed_flags {
+ NETCONFIG_CHANGED_ADDRESS = 1 << 0,
+ NETCONFIG_CHANGED_NETMASK = 1 << 1,
+ NETCONFIG_CHANGED_GATEWAY = 1 << 2,
+ NETCONFIG_CHANGED_DNS = 1 << 3,
+ NETCONFIG_CHANGED_DOMAINS = 1 << 4,
+ NETCONFIG_CHANGED_ALL = 0x1f,
+};
+
struct netconfig {
uint32_t ifindex;
struct l_dhcp_client *dhcp_client;
@@ -59,7 +68,9 @@ struct netconfig {
uint8_t rtm_protocol;
uint8_t rtm_v6_protocol;
struct l_rtnl_address *v4_address;
+ struct l_rtnl_address *stale_v4_address;
struct l_rtnl_address *v6_address;
+ struct l_rtnl_address *stale_v6_address;
char **dns4_overrides;
char **dns6_overrides;
char **dns4_list;
@@ -70,6 +81,8 @@ struct netconfig {
char *v6_gateway_str;
char *v4_domain;
char **v6_domains;
+ unsigned int pending_v4_set;
+ unsigned int pending_v6_set;
const struct l_settings *active_settings;
@@ -813,10 +826,8 @@ static void netconfig_route6_add_cb(int error, uint16_t type,
}
}
-static bool netconfig_ipv4_routes_install(struct netconfig *netconfig)
+static bool netconfig_ipv4_subnet_route_install(struct netconfig *netconfig)
{
- L_AUTO_FREE_VAR(char *, gateway) = NULL;
- const uint8_t *gateway_mac = NULL;
struct in_addr in_addr;
char ip[INET_ADDRSTRLEN];
char network[INET_ADDRSTRLEN];
@@ -839,10 +850,19 @@ static bool netconfig_ipv4_routes_install(struct netconfig *netconfig)
netconfig_route_generic_cb,
netconfig, NULL)) {
l_error("netconfig: Failed to add subnet route.");
-
return false;
}
+ return true;
+}
+
+static bool netconfig_ipv4_gateway_route_install(struct netconfig *netconfig)
+{
+ L_AUTO_FREE_VAR(char *, gateway) = NULL;
+ const uint8_t *gateway_mac = NULL;
+ struct in_addr in_addr;
+ char ip[INET_ADDRSTRLEN];
+
gateway = netconfig_ipv4_get_gateway(netconfig, &gateway_mac);
if (!gateway) {
l_debug("No gateway obtained from %s.",
@@ -858,6 +878,10 @@ static bool netconfig_ipv4_routes_install(struct netconfig *netconfig)
return true;
}
+ if (!l_rtnl_address_get_address(netconfig->v4_address, ip) ||
+ inet_pton(AF_INET, ip, &in_addr) < 1)
+ return false;
+
netconfig->route4_add_gateway_cmd_id =
l_rtnl_route4_add_gateway(rtnl, netconfig->ifindex, gateway, ip,
ROUTE_PRIORITY_OFFSET,
@@ -871,50 +895,77 @@ static bool netconfig_ipv4_routes_install(struct netconfig *netconfig)
return false;
}
- if (gateway_mac) {
- /*
- * Attempt to use the gateway MAC address received from the AP
- * by writing the mapping directly into the netdev's ARP table
- * so as to save one data frame roundtrip before first IP
- * connections are established. This is very low-priority but
- * print error messages just because they may indicate bigger
- * problems.
- */
- if (!l_rtnl_neighbor_set_hwaddr(rtnl, netconfig->ifindex,
+ /*
+ * Attempt to use the gateway MAC address received from the AP by
+ * writing the mapping directly into the netdev's ARP table so as
+ * to save one data frame roundtrip before first IP connections
+ * are established. This is very low-priority but print error
+ * messages just because they may indicate bigger problems.
+ */
+ if (gateway_mac && !l_rtnl_neighbor_set_hwaddr(rtnl, netconfig->ifindex,
AF_INET,
&netconfig->fils_override->ipv4_gateway,
gateway_mac, 6,
netconfig_set_neighbor_entry_cb, NULL,
NULL))
- l_debug("l_rtnl_neighbor_set_hwaddr failed");
+ l_debug("l_rtnl_neighbor_set_hwaddr failed");
+
+ return true;
+}
+
+static bool netconfig_ipv6_static_gateway_route_install(
+ struct netconfig *netconfig)
+{
+ _auto_(l_rtnl_route_free) struct l_rtnl_route *gateway = NULL;
+ const uint8_t *gateway_mac;
+
+ gateway = netconfig_get_static6_gateway(netconfig,
+ &netconfig->v6_gateway_str,
+ &gateway_mac);
+ if (!gateway) {
+ l_debug("No IPv6 gateway set");
+ return true;
}
+ netconfig->route6_add_cmd_id = l_rtnl_route_add(rtnl,
+ netconfig->ifindex,
+ gateway,
+ netconfig_route6_add_cb,
+ netconfig, NULL);
+ if (!L_WARN_ON(unlikely(!netconfig->route6_add_cmd_id)))
+ return false;
+
+ if (gateway_mac && !l_rtnl_neighbor_set_hwaddr(rtnl, netconfig->ifindex,
+ AF_INET6,
+ netconfig->fils_override->ipv6_gateway,
+ gateway_mac, 6,
+ netconfig_set_neighbor_entry_cb, NULL,
+ NULL))
+ l_debug("l_rtnl_neighbor_set_hwaddr failed");
+
return true;
}
+static void netconfig_set(struct netconfig *netconfig, uint8_t af,
+ unsigned int changed);
+
static void netconfig_ipv4_ifaddr_add_cmd_cb(int error, uint16_t type,
const void *data, uint32_t len,
void *user_data)
{
struct netconfig *netconfig = user_data;
+ unsigned int changed = netconfig->pending_v4_set;
netconfig->addr4_add_cmd_id = 0;
- if (error && error != -EEXIST) {
+ if (error && error != -EEXIST)
l_error("netconfig: Failed to add IP address. "
"Error %d: %s", error, strerror(-error));
- return;
- }
-
- netconfig_gateway_to_arp(netconfig);
-
- if (!netconfig_ipv4_routes_install(netconfig)) {
- l_error("netconfig: Failed to install IPv4 routes.");
- return;
- }
+ else
+ netconfig_ipv4_subnet_route_install(netconfig);
- netconfig_set_dns(netconfig);
- netconfig_set_domains(netconfig);
+ netconfig->pending_v4_set = 0;
+ netconfig_set(netconfig, AF_INET, changed);
}
static void netconfig_ipv6_ifaddr_add_cmd_cb(int error, uint16_t type,
@@ -922,40 +973,16 @@ static void netconfig_ipv6_ifaddr_add_cmd_cb(int error, uint16_t type,
void *user_data)
{
struct netconfig *netconfig = user_data;
- struct l_rtnl_route *gateway;
- const uint8_t *gateway_mac;
+ unsigned int changed = netconfig->pending_v4_set;
netconfig->addr6_add_cmd_id = 0;
- if (error && error != -EEXIST) {
+ if (error && error != -EEXIST)
l_error("netconfig: Failed to add IPv6 address. "
"Error %d: %s", error, strerror(-error));
- return;
- }
-
- gateway = netconfig_get_static6_gateway(netconfig,
- &netconfig->v6_gateway_str,
- &gateway_mac);
- if (gateway) {
- netconfig->route6_add_cmd_id = l_rtnl_route_add(rtnl,
- netconfig->ifindex,
- gateway,
- netconfig_route6_add_cb,
- netconfig, NULL);
- L_WARN_ON(unlikely(!netconfig->route6_add_cmd_id));
- l_rtnl_route_free(gateway);
-
- if (gateway_mac && !l_rtnl_neighbor_set_hwaddr(rtnl,
- netconfig->ifindex, AF_INET6,
- netconfig->fils_override->ipv6_gateway,
- gateway_mac, 6,
- netconfig_set_neighbor_entry_cb, NULL,
- NULL))
- l_debug("l_rtnl_neighbor_set_hwaddr failed");
- }
- netconfig_set_dns(netconfig);
- netconfig_set_domains(netconfig);
+ netconfig->pending_v6_set = 0;
+ netconfig_set(netconfig, AF_INET6, changed);
}
static void netconfig_ifaddr_del_cmd_cb(int error, uint16_t type,
@@ -978,21 +1005,169 @@ static void netconfig_ifaddr_del_cmd_cb(int error, uint16_t type,
"Error %d: %s", error, strerror(-error));
}
+static bool netconfig_address_cmp_address(const struct l_rtnl_address *a,
+ const struct l_rtnl_address *b)
+{
+ char str_a[INET6_ADDRSTRLEN];
+ char str_b[INET6_ADDRSTRLEN];
+
+ if (a == b)
+ return true;
+
+ if (!a || !b)
+ return false;
+
+ if (!l_rtnl_address_get_address(a, str_a) ||
+ !l_rtnl_address_get_address(b, str_b))
+ return false;
+
+ return !strcmp(str_a, str_b);
+}
+
+static bool netconfig_address_cmp_prefix_len(const struct l_rtnl_address *a,
+ const struct l_rtnl_address *b)
+{
+ if (a == b)
+ return true;
+
+ if (!a || !b)
+ return false;
+
+ return l_rtnl_address_get_prefix_length(a) ==
+ l_rtnl_address_get_prefix_length(b);
+}
+
+static void netconfig_set(struct netconfig *netconfig, uint8_t af,
+ unsigned int changed)
+{
+ struct l_rtnl_address *stale_addr;
+
+ if (af == AF_INET)
+ stale_addr = l_steal_ptr(netconfig->stale_v4_address);
+ else
+ stale_addr = l_steal_ptr(netconfig->stale_v6_address);
+
+ if (stale_addr) {
+ L_WARN_ON(!l_rtnl_ifaddr_delete(rtnl, netconfig->ifindex,
+ stale_addr,
+ netconfig_ifaddr_del_cmd_cb,
+ netconfig, NULL));
+ l_rtnl_address_free(stale_addr);
+ }
+
+ if (af == AF_INET) {
+ if (!netconfig->v4_address)
+ return;
+
+ if ((changed & (NETCONFIG_CHANGED_ADDRESS |
+ NETCONFIG_CHANGED_NETMASK)) &&
+ !netconfig->addr4_add_cmd_id) {
+ netconfig->addr4_add_cmd_id = l_rtnl_ifaddr_add(rtnl,
+ netconfig->ifindex,
+ netconfig->v4_address,
+ netconfig_ipv4_ifaddr_add_cmd_cb,
+ netconfig, NULL);
+ if (!L_WARN_ON(!netconfig->addr4_add_cmd_id))
+ changed &= ~(NETCONFIG_CHANGED_ADDRESS |
+ NETCONFIG_CHANGED_NETMASK);
+ }
+
+ /*
+ * If we either started the address addition now or one was
+ * already in progress, wait for that operation's callback
+ * and we'll be called again to set the rest of the values
+ * in the changed bitmask.
+ */
+ if (netconfig->addr4_add_cmd_id) {
+ netconfig->pending_v4_set |= changed;
+ return;
+ }
+
+ /*
+ * For IPv6 the address, the subnet route and the gateway
+ * route are handled automatically for DHCP, only cover the
+ * static and FILS-provided cases here.
+ */
+ } else if (netconfig->rtm_v6_protocol == RTPROT_STATIC ||
+ (netconfig->fils_override &&
+ !l_memeqzero(netconfig->fils_override->ipv6_addr,
+ 16))) {
+ if (!netconfig->v6_address)
+ return;
+
+ if ((changed & (NETCONFIG_CHANGED_ADDRESS |
+ NETCONFIG_CHANGED_NETMASK)) &&
+ !netconfig->addr6_add_cmd_id) {
+ netconfig->addr6_add_cmd_id = l_rtnl_ifaddr_add(rtnl,
+ netconfig->ifindex,
+ netconfig->v6_address,
+ netconfig_ipv6_ifaddr_add_cmd_cb,
+ netconfig, NULL);
+ if (!L_WARN_ON(!netconfig->addr6_add_cmd_id))
+ changed &= ~(NETCONFIG_CHANGED_ADDRESS |
+ NETCONFIG_CHANGED_NETMASK);
+ }
+
+ /*
+ * If we either started the address addition now or one was
+ * already in progress, wait for that operation's callback
+ * and we'll be called again to set the rest of the values
+ * in the changed bitmask.
+ */
+ if (netconfig->addr6_add_cmd_id) {
+ netconfig->pending_v4_set |= changed;
+ return;
+ }
+ }
+
+ if (af == AF_INET) {
+ if (changed & NETCONFIG_CHANGED_GATEWAY) {
+ netconfig_gateway_to_arp(netconfig);
+
+ if (netconfig_ipv4_gateway_route_install(netconfig))
+ changed &= ~NETCONFIG_CHANGED_GATEWAY;
+ } else if (netconfig->notify) {
+ /*
+ * The gateway route addition callback notifies the user
+ * of netconfig success if a gateway is provided, otherwise
+ * notify here.
+ */
+ netconfig->notify(NETCONFIG_EVENT_CONNECTED,
+ netconfig->user_data);
+ netconfig->notify = NULL;
+ }
+ } else if (netconfig->rtm_v6_protocol == RTPROT_STATIC ||
+ (netconfig->fils_override &&
+ !l_memeqzero(netconfig->fils_override->ipv6_gateway,
+ 16))) {
+ if (changed & (NETCONFIG_CHANGED_GATEWAY))
+ if (netconfig_ipv6_static_gateway_route_install(
+ netconfig))
+ changed &= ~NETCONFIG_CHANGED_GATEWAY;
+ }
+
+ if (changed & NETCONFIG_CHANGED_DNS) {
+ netconfig_set_dns(netconfig);
+ changed &= ~NETCONFIG_CHANGED_DNS;
+ }
+
+ if (changed & NETCONFIG_CHANGED_DOMAINS) {
+ netconfig_set_domains(netconfig);
+ changed &= ~NETCONFIG_CHANGED_DOMAINS;
+ }
+}
+
static void netconfig_ipv4_dhcp_event_handler(struct l_dhcp_client *client,
enum l_dhcp_client_event event,
void *userdata)
{
struct netconfig *netconfig = userdata;
+ unsigned int changed = 0;
l_debug("DHCPv4 event %d", event);
switch (event) {
case L_DHCP_CLIENT_EVENT_IP_CHANGED:
- L_WARN_ON(!l_rtnl_ifaddr_delete(rtnl, netconfig->ifindex,
- netconfig->v4_address,
- netconfig_ifaddr_del_cmd_cb,
- netconfig, NULL));
- /* Fall through. */
case L_DHCP_CLIENT_EVENT_LEASE_OBTAINED:
{
char *gateway_str;
@@ -1004,9 +1179,19 @@ static void netconfig_ipv4_dhcp_event_handler(struct l_dhcp_client *client,
else {
l_free(netconfig->v4_gateway_str);
netconfig->v4_gateway_str = gateway_str;
+ changed |= NETCONFIG_CHANGED_GATEWAY;
}
address = netconfig_get_dhcp4_address(netconfig);
+
+ if (!netconfig_address_cmp_prefix_len(netconfig->v4_address,
+ address))
+ changed |= NETCONFIG_CHANGED_NETMASK;
+
+ if (!netconfig_address_cmp_address(netconfig->v4_address,
+ address))
+ changed |= NETCONFIG_CHANGED_ADDRESS;
+
l_rtnl_address_free(netconfig->v4_address);
netconfig->v4_address = address;
@@ -1016,26 +1201,36 @@ static void netconfig_ipv4_dhcp_event_handler(struct l_dhcp_client *client,
return;
}
- netconfig_dns_list_update(netconfig, AF_INET);
- netconfig_domains_update(netconfig, AF_INET);
+ if (netconfig_dns_list_update(netconfig, AF_INET))
+ changed |= NETCONFIG_CHANGED_DNS;
- L_WARN_ON(!(netconfig->addr4_add_cmd_id =
- l_rtnl_ifaddr_add(rtnl, netconfig->ifindex,
- netconfig->v4_address,
- netconfig_ipv4_ifaddr_add_cmd_cb,
- netconfig, NULL)));
+ if (netconfig_domains_update(netconfig, AF_INET))
+ changed |= NETCONFIG_CHANGED_DOMAINS;
+
+ netconfig_set(netconfig, AF_INET, changed);
break;
}
case L_DHCP_CLIENT_EVENT_LEASE_RENEWED:
break;
case L_DHCP_CLIENT_EVENT_LEASE_EXPIRED:
- L_WARN_ON(!l_rtnl_ifaddr_delete(rtnl, netconfig->ifindex,
- netconfig->v4_address,
- netconfig_ifaddr_del_cmd_cb,
- netconfig, NULL));
- l_rtnl_address_free(netconfig->v4_address);
- netconfig->v4_address = NULL;
- l_free(l_steal_ptr(netconfig->v4_gateway_str));
+ l_debug("Lease for interface %u expired", netconfig->ifindex);
+ changed = NETCONFIG_CHANGED_ADDRESS | NETCONFIG_CHANGED_NETMASK;
+ l_rtnl_address_free(netconfig->stale_v4_address);
+ netconfig->stale_v4_address =
+ l_steal_ptr(netconfig->v4_address);
+
+ if (netconfig->v4_gateway_str) {
+ changed |= NETCONFIG_CHANGED_GATEWAY;
+ l_free(l_steal_ptr(netconfig->v4_gateway_str));
+ }
+
+ if (netconfig_dns_list_update(netconfig, AF_INET))
+ changed |= NETCONFIG_CHANGED_DNS;
+
+ if (netconfig_domains_update(netconfig, AF_INET))
+ changed |= NETCONFIG_CHANGED_DOMAINS;
+
+ netconfig_set(netconfig, AF_INET, changed);
/* Fall through. */
case L_DHCP_CLIENT_EVENT_NO_LEASE:
@@ -1059,6 +1254,7 @@ static void netconfig_dhcp6_event_handler(struct l_dhcp6_client *client,
void *userdata)
{
struct netconfig *netconfig = userdata;
+ unsigned int changed = 0;
switch (event) {
case L_DHCP6_CLIENT_EVENT_IP_CHANGED:
@@ -1081,28 +1277,52 @@ static void netconfig_dhcp6_event_handler(struct l_dhcp6_client *client,
else {
l_free(netconfig->v6_gateway_str);
netconfig->v6_gateway_str = gateway_str;
+ changed |= NETCONFIG_CHANGED_GATEWAY;
}
address = l_rtnl_address_new(addr_str,
l_dhcp6_lease_get_prefix_length(lease));
+
+ if (!netconfig_address_cmp_prefix_len(netconfig->v6_address,
+ address))
+ changed |= NETCONFIG_CHANGED_NETMASK;
+
+ if (!netconfig_address_cmp_address(netconfig->v6_address,
+ address))
+ changed |= NETCONFIG_CHANGED_ADDRESS;
+
l_rtnl_address_free(netconfig->v6_address);
netconfig->v6_address = address;
- netconfig_dns_list_update(netconfig, AF_INET6);
- netconfig_domains_update(netconfig, AF_INET6);
- netconfig_set_dns(netconfig);
- netconfig_set_domains(netconfig);
+ if (netconfig_dns_list_update(netconfig, AF_INET6))
+ changed |= NETCONFIG_CHANGED_DNS;
+
+ if (netconfig_domains_update(netconfig, AF_INET6))
+ changed |= NETCONFIG_CHANGED_DOMAINS;
+
+ netconfig_set(netconfig, AF_INET6, changed);
break;
}
case L_DHCP6_CLIENT_EVENT_LEASE_EXPIRED:
- l_debug("Lease for interface %u expired", netconfig->ifindex);
- netconfig_dns_list_update(netconfig, AF_INET6);
- netconfig_domains_update(netconfig, AF_INET6);
- netconfig_set_dns(netconfig);
- netconfig_set_domains(netconfig);
- l_rtnl_address_free(netconfig->v6_address);
- netconfig->v6_address = NULL;
- l_free(l_steal_ptr(netconfig->v6_gateway_str));
+ l_debug("IPv6 lease for interface %u expired",
+ netconfig->ifindex);
+ changed = NETCONFIG_CHANGED_ADDRESS | NETCONFIG_CHANGED_NETMASK;
+ l_rtnl_address_free(netconfig->stale_v6_address);
+ netconfig->stale_v6_address =
+ l_steal_ptr(netconfig->v6_address);
+
+ if (netconfig->v6_gateway_str) {
+ changed |= NETCONFIG_CHANGED_GATEWAY;
+ l_free(l_steal_ptr(netconfig->v6_gateway_str));
+ }
+
+ if (netconfig_dns_list_update(netconfig, AF_INET6))
+ changed |= NETCONFIG_CHANGED_DNS;
+
+ if (netconfig_domains_update(netconfig, AF_INET6))
+ changed |= NETCONFIG_CHANGED_DOMAINS;
+
+ netconfig_set(netconfig, AF_INET6, changed);
/* Fall through */
case L_DHCP6_CLIENT_EVENT_NO_LEASE:
@@ -1113,50 +1333,93 @@ static void netconfig_dhcp6_event_handler(struct l_dhcp6_client *client,
}
}
-static void netconfig_remove_v4_address(struct netconfig *netconfig)
-{
- if (!netconfig->v4_address)
- return;
-
- L_WARN_ON(!l_rtnl_ifaddr_delete(rtnl, netconfig->ifindex,
- netconfig->v4_address,
- netconfig_ifaddr_del_cmd_cb,
- netconfig, NULL));
- l_rtnl_address_free(netconfig->v4_address);
- netconfig->v4_address = NULL;
-}
-
static void netconfig_reset_v4(struct netconfig *netconfig)
{
if (netconfig->rtm_protocol) {
- netconfig_remove_v4_address(netconfig);
+ unsigned int changed = 0;
+
+ if (netconfig->v4_address)
+ changed |= NETCONFIG_CHANGED_ADDRESS |
+ NETCONFIG_CHANGED_NETMASK;
+
+ l_rtnl_address_free(netconfig->stale_v4_address);
+ netconfig->stale_v4_address = l_steal_ptr(netconfig->v4_address);
+
+ if (netconfig->v4_gateway_str)
+ changed |= NETCONFIG_CHANGED_GATEWAY;
+
+ l_free(l_steal_ptr(netconfig->v4_gateway_str));
+
+ if (netconfig->dns4_list)
+ changed |= NETCONFIG_CHANGED_DNS;
l_strv_free(l_steal_ptr(netconfig->dns4_overrides));
l_strv_free(l_steal_ptr(netconfig->dns4_list));
+ if (netconfig->v4_domain)
+ changed |= NETCONFIG_CHANGED_DOMAINS;
+
+ l_free(l_steal_ptr(netconfig->v4_domain));
+
+ netconfig_set(netconfig, AF_INET, changed);
+
l_dhcp_client_stop(netconfig->dhcp_client);
netconfig->rtm_protocol = 0;
l_acd_destroy(netconfig->acd);
netconfig->acd = NULL;
+ }
+}
- l_free(l_steal_ptr(netconfig->v4_gateway_str));
+static void netconfig_reset_v6(struct netconfig *netconfig)
+{
+ if (netconfig->rtm_v6_protocol) {
+ unsigned int changed = 0;
+ struct netdev *netdev = netdev_find(netconfig->ifindex);
- l_free(l_steal_ptr(netconfig->v4_domain));
+ if (netconfig->v6_address)
+ changed |= NETCONFIG_CHANGED_ADDRESS |
+ NETCONFIG_CHANGED_NETMASK;
+
+ l_rtnl_address_free(netconfig->stale_v6_address);
+ netconfig->stale_v6_address = l_steal_ptr(netconfig->v6_address);
+
+ if (netconfig->v6_gateway_str)
+ changed |= NETCONFIG_CHANGED_GATEWAY;
+
+ l_free(l_steal_ptr(netconfig->v6_gateway_str));
+
+ if (netconfig->dns6_list)
+ changed |= NETCONFIG_CHANGED_DNS;
+
+ l_strv_free(l_steal_ptr(netconfig->dns6_overrides));
+ l_strv_free(l_steal_ptr(netconfig->dns6_list));
+
+ if (netconfig->v6_domains)
+ changed |= NETCONFIG_CHANGED_DOMAINS;
+
+ l_free(l_steal_ptr(netconfig->v6_domains));
+
+ netconfig_set(netconfig, AF_INET6, changed);
+
+ l_dhcp6_client_stop(netconfig->dhcp6_client);
+ netconfig->rtm_v6_protocol = 0;
+
+ sysfs_write_ipv6_setting(netdev_get_name(netdev),
+ "disable_ipv6", "1");
}
}
static void netconfig_ipv4_acd_event(enum l_acd_event event, void *user_data)
{
struct netconfig *netconfig = user_data;
+ unsigned int changed;
switch (event) {
case L_ACD_EVENT_AVAILABLE:
- L_WARN_ON(!(netconfig->addr4_add_cmd_id =
- l_rtnl_ifaddr_add(rtnl, netconfig->ifindex,
- netconfig->v4_address,
- netconfig_ipv4_ifaddr_add_cmd_cb,
- netconfig, NULL)));
+ changed = netconfig->pending_v4_set;
+ netconfig->pending_v4_set = 0;
+ netconfig_set(netconfig, AF_INET, changed);
return;
case L_ACD_EVENT_CONFLICT:
/*
@@ -1174,7 +1437,10 @@ static void netconfig_ipv4_acd_event(enum l_acd_event event, void *user_data)
* case.
*/
l_error("netconfig: statically configured address was lost");
- netconfig_remove_v4_address(netconfig);
+
+ l_rtnl_address_free(netconfig->stale_v4_address);
+ netconfig->stale_v4_address = l_steal_ptr(netconfig->v4_address);
+ netconfig_set(netconfig, AF_INET, NETCONFIG_CHANGED_ALL);
break;
}
}
@@ -1212,6 +1478,17 @@ static bool netconfig_ipv4_select_and_install(struct netconfig *netconfig)
if (set_address) {
char ip[INET6_ADDRSTRLEN];
+ unsigned int changed = NETCONFIG_CHANGED_ADDRESS |
+ NETCONFIG_CHANGED_NETMASK;
+
+ if (netconfig->v4_gateway_str)
+ changed |= NETCONFIG_CHANGED_GATEWAY;
+
+ if (netconfig_dns_list_update(netconfig, AF_INET))
+ changed |= NETCONFIG_CHANGED_DNS;
+
+ if (netconfig_domains_update(netconfig, AF_INET))
+ changed |= NETCONFIG_CHANGED_DOMAINS;
if (L_WARN_ON(!netconfig->v4_address ||
!l_rtnl_address_get_address(
@@ -1219,9 +1496,6 @@ static bool netconfig_ipv4_select_and_install(struct netconfig *netconfig)
ip)))
return false;
- netconfig_dns_list_update(netconfig, AF_INET);
- netconfig_domains_update(netconfig, AF_INET);
-
netconfig->acd = l_acd_new(netconfig->ifindex);
l_acd_set_event_handler(netconfig->acd,
netconfig_ipv4_acd_event, netconfig,
@@ -1235,12 +1509,9 @@ static bool netconfig_ipv4_select_and_install(struct netconfig *netconfig)
l_acd_destroy(netconfig->acd);
netconfig->acd = NULL;
- L_WARN_ON(!(netconfig->addr4_add_cmd_id =
- l_rtnl_ifaddr_add(rtnl, netconfig->ifindex,
- netconfig->v4_address,
- netconfig_ipv4_ifaddr_add_cmd_cb,
- netconfig, NULL)));
- }
+ netconfig_set(netconfig, AF_INET, changed);
+ } else
+ netconfig->pending_v4_set |= changed;
return true;
}
@@ -1293,13 +1564,16 @@ static bool netconfig_ipv6_select_and_install(struct netconfig *netconfig)
}
if (netconfig->v6_address) {
- netconfig_dns_list_update(netconfig, AF_INET6);
+ unsigned int changed = NETCONFIG_CHANGED_ADDRESS |
+ NETCONFIG_CHANGED_NETMASK;
- L_WARN_ON(!(netconfig->addr6_add_cmd_id =
- l_rtnl_ifaddr_add(rtnl, netconfig->ifindex,
- netconfig->v6_address,
- netconfig_ipv6_ifaddr_add_cmd_cb,
- netconfig, NULL)));
+ if (netconfig->v6_gateway_str)
+ changed |= NETCONFIG_CHANGED_GATEWAY;
+
+ if (netconfig_dns_list_update(netconfig, AF_INET6))
+ changed |= NETCONFIG_CHANGED_DNS;
+
+ netconfig_set(netconfig, AF_INET6, changed);
return true;
}
@@ -1493,8 +1767,6 @@ bool netconfig_reconfigure(struct netconfig *netconfig, bool set_arp_gw)
bool netconfig_reset(struct netconfig *netconfig)
{
- struct netdev *netdev = netdev_find(netconfig->ifindex);
-
if (netconfig->route4_add_gateway_cmd_id) {
l_netlink_cancel(rtnl, netconfig->route4_add_gateway_cmd_id);
netconfig->route4_add_gateway_cmd_id = 0;
@@ -1519,24 +1791,7 @@ bool netconfig_reset(struct netconfig *netconfig)
resolve_revert(netconfig->resolve);
netconfig_reset_v4(netconfig);
-
- if (netconfig->rtm_v6_protocol) {
- l_rtnl_address_free(netconfig->v6_address);
- netconfig->v6_address = NULL;
-
- l_strv_free(l_steal_ptr(netconfig->dns6_overrides));
- l_strv_free(l_steal_ptr(netconfig->dns6_list));
-
- l_dhcp6_client_stop(netconfig->dhcp6_client);
- netconfig->rtm_v6_protocol = 0;
-
- sysfs_write_ipv6_setting(netdev_get_name(netdev),
- "disable_ipv6", "1");
-
- l_free(l_steal_ptr(netconfig->v6_gateway_str));
-
- l_strv_free(l_steal_ptr(netconfig->v6_domains));
- }
+ netconfig_reset_v6(netconfig);
l_free(l_steal_ptr(netconfig->fils_override));
--
2.32.0
6 months, 1 week
iwd can start in AP mode
by salahaldeen.altous@leica-camera.com
From e8357b81a20f44d3473f652ef233b6598f72273f Mon Sep 17 00:00:00 2001
From: Salahaldeen Altous <salahaldeen.altous(a)leica-camera.com>
Date: Mon, 8 Nov 2021 05:16:26 +0100
Subject: [PATCH] iwd can start in AP mode
By default iwd starts in station mode. This can be changed by setting the
Mode parameter to ap in the main.conf General section. Example
[General]
Mode=ap
---
src/manager.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/manager.c b/src/manager.c
index 558b71b0..a1078713 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -197,6 +197,8 @@ static void manager_create_interfaces(struct wiphy_setup_state *state)
char ifname[10];
uint32_t iftype;
unsigned cmd_id;
+ const char *mode_str;
+ const struct l_settings *config = iwd_get_config();
if (state->aborted)
return;
@@ -223,6 +225,11 @@ static void manager_create_interfaces(struct wiphy_setup_state *state)
snprintf(ifname, sizeof(ifname), "wlan%i", (int) state->id);
l_debug("creating %s", ifname);
iftype = NL80211_IFTYPE_STATION;
+ mode_str = l_settings_get_value(config, "General", "Mode");
+ if (mode_str) {
+ if (!strcmp(mode_str, "ap"))
+ iftype = NL80211_IFTYPE_AP;
+ }
msg = l_genl_msg_new(NL80211_CMD_NEW_INTERFACE);
l_genl_msg_append_attr(msg, NL80211_ATTR_WIPHY, 4, &state->id);
--
2.25.1
6 months, 1 week
[PATCH] gitignore: Add tags and cscope files
by Torsten Schmitz
Ignore files generated by the make targets tags and cscope.
---
.gitignore | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.gitignore b/.gitignore
index 529f677d..7ff12d12 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,8 @@
.libs
.deps
.dirstamp
+tags
+cscope.*
Makefile
Makefile.in
aclocal.m4
--
2.33.1
6 months, 1 week
[PATCH] auto-t: replacing ifconfig with ip commands
by Torsten Schmitz
ifconfig and the rest of net-tools has been deprecated by
many distributions. Use iproute2 instead.
---
autotests/testFILS/fils_256_test.py | 2 +-
autotests/testFILS/fils_384_test.py | 2 +-
.../testFT-8021x-roam/connection_test.py | 18 +++++++------
autotests/testFT-FILS/connection_test.py | 18 ++++++-------
autotests/testNetconfig/connection_test.py | 3 +--
autotests/testNetconfig/static_test.py | 3 +--
autotests/testP2P/connection_test.py | 2 +-
autotests/testPSK-roam/connection_test.py | 16 +++++------
autotests/testPreauth-roam/connection_test.py | 2 +-
autotests/testSAE-roam/connection_test.py | 27 ++++++++++---------
doc/test-runner.txt | 2 +-
tools/test-runner | 6 ++---
12 files changed, 52 insertions(+), 49 deletions(-)
diff --git a/autotests/testFILS/fils_256_test.py b/autotests/testFILS/fils_256_test.py
index a4e58715..5fa371e1 100644
--- a/autotests/testFILS/fils_256_test.py
+++ b/autotests/testFILS/fils_256_test.py
@@ -62,7 +62,7 @@ class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
IWD.copy_to_storage('ssidFILS-256.8021x')
- os.system('ifconfig lo up')
+ os.system('ip link set lo up')
pass
@classmethod
diff --git a/autotests/testFILS/fils_384_test.py b/autotests/testFILS/fils_384_test.py
index e6550a17..b7174418 100644
--- a/autotests/testFILS/fils_384_test.py
+++ b/autotests/testFILS/fils_384_test.py
@@ -62,7 +62,7 @@ class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
IWD.copy_to_storage('ssidFILS-384.8021x')
- os.system('ifconfig lo up')
+ os.system('ip link set lo up')
pass
@classmethod
diff --git a/autotests/testFT-8021x-roam/connection_test.py b/autotests/testFT-8021x-roam/connection_test.py
index e65e4675..652677a9 100644
--- a/autotests/testFT-8021x-roam/connection_test.py
+++ b/autotests/testFT-8021x-roam/connection_test.py
@@ -54,10 +54,10 @@ class Test(unittest.TestCase):
(self.bss_hostapd[0].ifname, device.name, True, True))
def tearDown(self):
- os.system('ifconfig "' + self.bss_hostapd[0].ifname + '" down')
- os.system('ifconfig "' + self.bss_hostapd[1].ifname + '" down')
- os.system('ifconfig "' + self.bss_hostapd[0].ifname + '" up')
- os.system('ifconfig "' + self.bss_hostapd[1].ifname + '" up')
+ 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')
@classmethod
def setUpClass(cls):
@@ -67,10 +67,12 @@ class Test(unittest.TestCase):
HostapdCLI(config='ft-eap-ccmp-2.conf') ]
# Set interface addresses to those expected by hostapd config files
- os.system('ifconfig "' + cls.bss_hostapd[0].ifname +
- '" down hw ether 12:00:00:00:00:01 up')
- os.system('ifconfig "' + cls.bss_hostapd[1].ifname +
- '" down hw ether 12:00:00:00:00:02 up')
+ os.system('ip link set dev "' + cls.bss_hostapd[0].ifname + '" down')
+ os.system('ip link set dev "' + cls.bss_hostapd[0].ifname + \
+ '" address 12:00:00:00:00:01 up')
+ os.system('ip link set dev "' + cls.bss_hostapd[1].ifname + '" down')
+ os.system('ip link set dev "' + cls.bss_hostapd[1].ifname + \
+ '" address 12:00:00:00:00:02 up')
cls.bss_hostapd[0].reload()
cls.bss_hostapd[0].wait_for_event("AP-ENABLED")
diff --git a/autotests/testFT-FILS/connection_test.py b/autotests/testFT-FILS/connection_test.py
index 14025a3b..1fd4633b 100644
--- a/autotests/testFT-FILS/connection_test.py
+++ b/autotests/testFT-FILS/connection_test.py
@@ -124,24 +124,24 @@ class Test(unittest.TestCase):
self.validate_connection(wd)
def tearDown(self):
- os.system('ifconfig "' + self.bss_hostapd[0].ifname + '" down')
- os.system('ifconfig "' + self.bss_hostapd[1].ifname + '" down')
- os.system('ifconfig "' + self.bss_hostapd[0].ifname + '" up')
- os.system('ifconfig "' + self.bss_hostapd[1].ifname + '" up')
+ 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')
@classmethod
def setUpClass(cls):
- os.system('ifconfig lo up')
+ os.system('ip link set lo up')
IWD.copy_to_storage('TestFT.8021x')
cls.bss_hostapd = [ HostapdCLI(config='ft-eap-ccmp-1.conf'),
HostapdCLI(config='ft-eap-ccmp-2.conf') ]
# Set interface addresses to those expected by hostapd config files
- os.system('ifconfig "' + cls.bss_hostapd[0].ifname +
- '" down hw ether 12:00:00:00:00:01 up')
- os.system('ifconfig "' + cls.bss_hostapd[1].ifname +
- '" down hw ether 12:00:00:00:00:02 up')
+ os.system('ip link set dev "' + cls.bss_hostapd[0].ifname + '" down')
+ os.system('ip link set dev "' + cls.bss_hostapd[0].ifname + '" addr 12:00:00:00:00:01 up')
+ os.system('ip link set dev "' + cls.bss_hostapd[1].ifname + '" down')
+ os.system('ip link set dev "' + cls.bss_hostapd[1].ifname + '" addr 12:00:00:00:00:02 up')
cls.bss_hostapd[0].reload()
cls.bss_hostapd[0].wait_for_event("AP-ENABLED")
diff --git a/autotests/testNetconfig/connection_test.py b/autotests/testNetconfig/connection_test.py
index b1d4afef..74ec224a 100644
--- a/autotests/testNetconfig/connection_test.py
+++ b/autotests/testNetconfig/connection_test.py
@@ -59,8 +59,7 @@ class Test(unittest.TestCase):
# TODO: This could be moved into test-runner itself if other tests ever
# require this functionality (p2p, FILS, etc.). Since its simple
# enough it can stay here for now.
- ctx.start_process(['ifconfig', hapd.ifname, '192.168.1.1',
- 'netmask', '255.255.255.0']).wait()
+ ctx.start_process(['ip', 'addr','add', 'dev', hapd.ifname, '192.168.1.1/255.255.255.0']).wait()
ctx.start_process(['touch', '/tmp/dhcpd.leases']).wait()
cls.dhcpd_pid = ctx.start_process(['dhcpd', '-f', '-cf', '/tmp/dhcpd.conf',
'-lf', '/tmp/dhcpd.leases',
diff --git a/autotests/testNetconfig/static_test.py b/autotests/testNetconfig/static_test.py
index eb918e92..4aae4a20 100644
--- a/autotests/testNetconfig/static_test.py
+++ b/autotests/testNetconfig/static_test.py
@@ -86,8 +86,7 @@ class Test(unittest.TestCase):
# TODO: This could be moved into test-runner itself if other tests ever
# require this functionality (p2p, FILS, etc.). Since its simple
# enough it can stay here for now.
- ctx.start_process(['ifconfig', hapd.ifname, '192.168.1.1',
- 'netmask', '255.255.255.0']).wait()
+ ctx.start_process(['ip', 'addr','add', hapd.ifname, '192.168.1.1/255.255.255.0']).wait()
ctx.start_process(['touch', '/tmp/dhcpd.leases']).wait()
cls.dhcpd_pid = ctx.start_process(['dhcpd', '-f', '-cf', '/tmp/dhcpd.conf',
'-lf', '/tmp/dhcpd.leases',
diff --git a/autotests/testP2P/connection_test.py b/autotests/testP2P/connection_test.py
index 04f63fdf..ddebc70a 100644
--- a/autotests/testP2P/connection_test.py
+++ b/autotests/testP2P/connection_test.py
@@ -93,7 +93,7 @@ class Test(unittest.TestCase):
self.assertEqual(wpas.p2p_group['role'], 'GO' if not go else 'client')
if not go:
- ctx.start_process(['ifconfig', peer_ifname, '192.168.1.20', 'netmask', '255.255.255.0']).wait()
+ ctx.start_process(['ip', 'addr', 'add','dev', peer_ifname, '192.168.1.20/255.255.255.0']).wait()
os.system('> /tmp/dhcp.leases')
dhcp = ctx.start_process(['dhcpd', '-f', '-cf', '/tmp/dhcpd.conf', '-lf', '/tmp/dhcp.leases', peer_ifname])
self.dhcp = dhcp
diff --git a/autotests/testPSK-roam/connection_test.py b/autotests/testPSK-roam/connection_test.py
index ee50e4a7..437e52fc 100644
--- a/autotests/testPSK-roam/connection_test.py
+++ b/autotests/testPSK-roam/connection_test.py
@@ -150,10 +150,10 @@ class Test(unittest.TestCase):
self.validate_connection(wd)
def tearDown(self):
- os.system('ifconfig "' + self.bss_hostapd[0].ifname + '" down')
- os.system('ifconfig "' + self.bss_hostapd[1].ifname + '" down')
- os.system('ifconfig "' + self.bss_hostapd[0].ifname + '" up')
- os.system('ifconfig "' + self.bss_hostapd[1].ifname + '" up')
+ 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')
self.rule0.enabled = False
@@ -175,10 +175,10 @@ class Test(unittest.TestCase):
cls.rule0.drop = True
# Set interface addresses to those expected by hostapd config files
- os.system('ifconfig "' + cls.bss_hostapd[0].ifname +
- '" down hw ether 12:00:00:00:00:01 up')
- os.system('ifconfig "' + cls.bss_hostapd[1].ifname +
- '" down hw ether 12:00:00:00:00:02 up')
+ os.system('ip link set dev "' + cls.bss_hostapd[0].ifname + '" down')
+ os.system('ip link set dev "' + cls.bss_hostapd[0].ifname + '" addr 12:00:00:00:00:01 up')
+ os.system('ip link set dev "' + cls.bss_hostapd[1].ifname + '" down')
+ os.system('ip link set dev "' + cls.bss_hostapd[1].ifname + '" addr 12:00:00:00:00:02 up')
cls.bss_hostapd[0].reload()
cls.bss_hostapd[0].wait_for_event("AP-ENABLED")
diff --git a/autotests/testPreauth-roam/connection_test.py b/autotests/testPreauth-roam/connection_test.py
index 63b73b54..61f095d3 100644
--- a/autotests/testPreauth-roam/connection_test.py
+++ b/autotests/testPreauth-roam/connection_test.py
@@ -86,7 +86,7 @@ class Test(unittest.TestCase):
def setUpClass(cls):
IWD.copy_to_storage('TestPreauth.8021x')
- os.system('ifconfig lo up')
+ os.system('ip link set lo up')
@classmethod
def tearDownClass(cls):
diff --git a/autotests/testSAE-roam/connection_test.py b/autotests/testSAE-roam/connection_test.py
index 20d94c8f..23f3aaac 100644
--- a/autotests/testSAE-roam/connection_test.py
+++ b/autotests/testSAE-roam/connection_test.py
@@ -111,12 +111,12 @@ class Test(unittest.TestCase):
self.validate_connection(wd, False)
def tearDown(self):
- os.system('ifconfig "' + self.bss_hostapd[0].ifname + '" down')
- os.system('ifconfig "' + self.bss_hostapd[1].ifname + '" down')
- os.system('ifconfig "' + self.bss_hostapd[2].ifname + '" down')
- os.system('ifconfig "' + self.bss_hostapd[0].ifname + '" up')
- os.system('ifconfig "' + self.bss_hostapd[1].ifname + '" up')
- os.system('ifconfig "' + self.bss_hostapd[2].ifname + '" up')
+ 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[2].ifname + '" down')
+ os.system('ip link set "' + self.bss_hostapd[0].ifname + '" up')
+ os.system('ip link set "' + self.bss_hostapd[1].ifname + '" up')
+ os.system('ip link set "' + self.bss_hostapd[2].ifname + '" up')
@classmethod
def setUpClass(cls):
@@ -124,12 +124,15 @@ class Test(unittest.TestCase):
HostapdCLI(config='ft-sae-2.conf'),
HostapdCLI(config='ft-psk-3.conf') ]
- ctx.start_process(['ifconfig', cls.bss_hostapd[0].ifname, 'down', 'hw', \
- 'ether', '12:00:00:00:00:01', 'up']).wait()
- ctx.start_process(['ifconfig', cls.bss_hostapd[1].ifname, 'down', 'hw', \
- 'ether', '12:00:00:00:00:02', 'up']).wait()
- ctx.start_process(['ifconfig', cls.bss_hostapd[2].ifname, 'down', 'hw', \
- 'ether', '12:00:00:00:00:03', 'up']).wait()
+ ctx.start_process(['ip', 'link', 'set', 'dev', cls.bss_hostapd[0].ifname, 'down'])
+ ctx.start_process(['ip', 'link', 'set', 'dev', cls.bss_hostapd[0].ifname, \
+ 'addr', '12:00:00:00:00:01', 'up']).wait()
+ ctx.start_process(['ip', 'link', 'set', 'dev', cls.bss_hostapd[1].ifname, 'down'])
+ ctx.start_process(['ip', 'link', 'set', 'dev', cls.bss_hostapd[1].ifname, \
+ 'addr', '12:00:00:00:00:02', 'up']).wait()
+ ctx.start_process(['ip', 'link', 'set', 'dev', cls.bss_hostapd[2].ifname, 'down'])
+ ctx.start_process(['ip', 'link', 'set', 'dev', cls.bss_hostapd[2].ifname, \
+ 'adrr', '12:00:00:00:00:03', 'up']).wait()
# Set interface addresses to those expected by hostapd config files
cls.bss_hostapd[0].reload()
diff --git a/doc/test-runner.txt b/doc/test-runner.txt
index 9140aa0f..4f2887c3 100644
--- a/doc/test-runner.txt
+++ b/doc/test-runner.txt
@@ -19,7 +19,7 @@ OS:
1. qemu 2.4.1
2. Linux kernel 4.20+
3. dbus-daemon 1.11.18
- 4. ifconfig 2.10-alpha
+ 4. iproute2
5. iw 3.17
6. python 2.7
7. haveged no ver. avail.
diff --git a/tools/test-runner b/tools/test-runner
index 5fc4285d..7fa8b840 100755
--- a/tools/test-runner
+++ b/tools/test-runner
@@ -361,7 +361,7 @@ class Interface:
Process(['iw', 'dev', self.name, 'del']).wait()
def set_interface_state(self, state):
- Process(['ifconfig', self.name, state]).wait()
+ Process(['ip', 'link', 'set', self.name, state]).wait()
class Radio:
def __init__(self, name):
@@ -971,7 +971,7 @@ class TestContext(Namespace):
print("Ofono or Phonesim not found, skipping test")
return
- Process(['ifconfig', 'lo', 'up']).wait()
+ Process(['ip', 'link', 'set', 'lo', 'up']).wait()
os.environ['OFONO_PHONESIM_CONFIG'] = '/tmp/phonesim.conf'
@@ -1358,7 +1358,7 @@ def post_test(ctx, to_copy):
else:
os.remove('/tmp/' + f)
- Process(['ifconfig', 'lo', 'down']).wait()
+ Process(['ip', 'link', 'set', 'lo', 'down']).wait()
except Exception as e:
print("Exception thrown in post_test")
finally:
--
2.33.1
6 months, 1 week
[PATCH] Set retain attribute on C identifier name sections referenced by __start_/__stop_
by Fangrui Song
LLD 13 and GNU ld 2.37 support -z start-stop-gc which allows garbage
collection of C identifier name sections despite the __start_/__stop_
references. GNU ld before 2015-10 had the behavior as well. Simply set
the retain attribute so that GCC 11 (if configure-time binutils is 2.36
or newer)/Clang 13 will set the SHF_GNU_RETAIN section attribute to
prevent garbage collection.
Without the patch, there are linker errors with -z start-stop-gc (LLD default)
when -Wl,--gc-sections is used:
```
ld.lld: error: undefined symbol: __start___eap
>>> referenced by eap.c
>>> src/eap.o:(eap_init)
```
The remain attribute will not be needed if the metadata sections are
referenced by code directly.
---
client/command.h | 12 +++++++-----
client/dbus-proxy.h | 13 ++++++++-----
src/eap-private.h | 6 +++++-
src/module.h | 20 +++++++++++++-------
4 files changed, 33 insertions(+), 18 deletions(-)
diff --git a/client/command.h b/client/command.h
index d906dc9b..5d5df7fe 100644
--- a/client/command.h
+++ b/client/command.h
@@ -82,11 +82,13 @@ struct command_family_desc {
void (*exit)(void);
} __attribute__((aligned(8)));
-#define COMMAND_FAMILY(name, init, exit) \
- static struct command_family_desc __command_family_ ## name \
- __attribute__((used, section("__command"), aligned(8))) = {\
- #name, init, exit \
- }; \
+#define COMMAND_FAMILY(name, init, exit) \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wattributes\"") \
+ static struct command_family_desc __command_family_##name \
+ __attribute__((used, retain, section("__command"), aligned(8))) = { \
+ #name, init, exit}; \
+ _Pragma("GCC diagnostic pop")
bool command_init(char **argv, int argc);
void command_exit(void);
diff --git a/client/dbus-proxy.h b/client/dbus-proxy.h
index 6852a378..54e95746 100644
--- a/client/dbus-proxy.h
+++ b/client/dbus-proxy.h
@@ -117,11 +117,14 @@ struct interface_type_desc {
void (*exit)(void);
} __attribute__((aligned(8)));
-#define INTERFACE_TYPE(interface, init, exit) \
- static struct interface_type_desc __interface_type_ ## interface\
- __attribute__((used, section("__interface"), aligned(8))) = {\
- #interface, init, exit \
- }; \
+#define INTERFACE_TYPE(interface, init, exit) \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wattributes\"") \
+ static struct interface_type_desc __interface_type_ ## interface \
+ __attribute__((used, retain, section("__interface"), aligned(8))) = { \
+ #interface, init, exit \
+ }; \
+ _Pragma("GCC diagnostic pop")
bool dbus_proxy_init(void);
bool dbus_proxy_exit(void);
diff --git a/src/eap-private.h b/src/eap-private.h
index 5121a330..1eef6bf4 100644
--- a/src/eap-private.h
+++ b/src/eap-private.h
@@ -94,10 +94,14 @@ struct eap_method_desc {
} __attribute__((aligned(8)));
#define EAP_METHOD_BUILTIN(name, init, exit) \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wattributes\"") \
static struct eap_method_desc __eap_builtin_ ## name \
- __attribute__((used, section("__eap"), aligned(8))) = { \
+ __attribute__((used, retain, section("__eap"), \
+ aligned(8))) = { \
#name, init, exit \
}; \
+ _Pragma("GCC diagnostic pop")
int eap_register_method(struct eap_method *method);
int eap_unregister_method(struct eap_method *method);
diff --git a/src/module.h b/src/module.h
index 8e1a9904..b4ec1284 100644
--- a/src/module.h
+++ b/src/module.h
@@ -33,19 +33,25 @@ struct iwd_module_depends {
};
#define IWD_MODULE(name, init, exit) \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wattributes\"") \
static struct iwd_module_desc __iwd_module_ ## name \
- __attribute__((used, section("__iwd_module"), aligned(8))) = {\
+ __attribute__((used, retain, section("__iwd_module"), \
+ aligned(8))) = { \
#name, init, exit \
- };
+ }; \
+ _Pragma("GCC diagnostic pop")
#define IWD_MODULE_DEPENDS(name, dep) \
- static struct iwd_module_depends \
- __iwd_module__##name##_##dep \
- __attribute__((used, section("__iwd_module_dep"), \
- aligned(8))) = { \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wattributes\"") \
+ static struct iwd_module_depends __iwd_module__##name##_##dep \
+ __attribute__((used, retain, \
+ section("__iwd_module_dep"), aligned(8))) = { \
.self = #name, \
.target = #dep, \
- };
+ }; \
+ _Pragma("GCC diagnostic pop")
int iwd_modules_init(void);
void iwd_modules_exit(void);
--
2.34
6 months, 1 week
BUG: iwctl v1.19 (get-networks, command line mode)
by Andrés González
Hello,
After upgrading to v1.19 the following no longer works:
*Command line mode*
$ iwctl station DEVICE scan
$ iwctl station DEVICE get-networks
The second command returns blank. Other commands like "show" work just
fine. Also interactive mode works just fine.
I have downgraded the package to v1.18 and it works well (while I did not
restart the service), so seems to perhaps be the client only?
--
-andrés
6 months, 1 week
Enabling IPv6 causes immediate segfault on connect
by Tmore1
Hello,
After many years of managing wireless with Debian's ifupdown +
wpa_supplicant, I tried iwd, and I love it so far: I really appreciate
its polish, cleanliness, and responsiveness. Thanks much for this
software!
There seems to be a problem with its IPv6 support: on my system
(Debian Sid, iwd 1.19 from distro repo), iwd works perfectly out of the
box, and continues to work with "EnableNetworkConfiguration=True", but
with "EnableIPv6=true", it segfaults immediately upon connect. (This is
especially awkward when iwd is being managed by systemd, since I then
get an endless loop of the daemon crashing and immediately restarting,
with a steady stream of messages hitting syslog ;))
FWIW, some Arch users have reported similar issues:
https://bugs.archlinux.org/task/71718
Here's my debug output:
*****
root@lila:~# /usr/libexec/iwd -d
Wireless daemon version 1.19
src/main.c:main() Using configuration directory /etc/iwd
Loaded configuration from /etc/iwd/main.conf
src/storage.c:storage_create_dirs() Using state directory /var/lib/iwd
src/main.c:nl80211_appeared() Found nl80211 interface
src/module.c:iwd_modules_init()
src/wsc.c:wsc_init()
src/resolve.c:resolve_resolvconf_init() Trying to find resolvconf in $PATH
src/resolve.c:resolve_resolvconf_init() resolvconf found as: /sbin/resolvconf
src/eap.c:__eap_method_enable()
src/eap-wsc.c:eap_wsc_init()
src/eap-md5.c:eap_md5_init()
src/eap-tls.c:eap_tls_init()
src/eap-ttls.c:eap_ttls_init()
src/eap-mschapv2.c:eap_mschapv2_init()
src/eap-sim.c:eap_sim_init()
src/eap-aka.c:eap_aka_prime_init()
src/eap-aka.c:eap_aka_init()
src/eap-peap.c:eap_peap_init()
src/eap-gtc.c:eap_gtc_init()
src/eap-pwd.c:eap_pwd_init()
src/manager.c:manager_wiphy_dump_callback() New wiphy phy0 added (0)
Wiphy: 0, Name: phy0
Permanent Address: xx:xx:xx:xx:xx:xx
2.4Ghz Band:
Bitrates (non-HT):
1.0 Mbps
2.0 Mbps
5.5 Mbps
11.0 Mbps
6.0 Mbps
9.0 Mbps
12.0 Mbps
18.0 Mbps
24.0 Mbps
36.0 Mbps
48.0 Mbps
54.0 Mbps
HT Capabilities:
HT40
Short GI for 20Mhz
Short GI for 40Mhz
HT RX MCS indexes:
0-15
5Ghz Band:
Bitrates (non-HT):
6.0 Mbps
9.0 Mbps
12.0 Mbps
18.0 Mbps
24.0 Mbps
36.0 Mbps
48.0 Mbps
54.0 Mbps
HT Capabilities:
HT40
Short GI for 20Mhz
Short GI for 40Mhz
HT RX MCS indexes:
0-15
VHT Capabilities:
Short GI for 80Mhz
Max RX MCS: 0-9 for NSS: 2
Max TX MCS: 0-9 for NSS: 2
Ciphers: CCMP TKIP BIP
Supported iftypes: ad-hoc station ap p2p-client p2p-go p2p-device
src/manager.c:manager_create_interfaces() creating wlan0
src/manager.c:manager_create_interfaces() creating wlan0-p2p
src/wiphy.c:wiphy_update_reg_domain() New reg domain country code for phy0 is US
src/manager.c:manager_config_notify() Notification of command New Interface(7)
src/netdev.c:netdev_link_notify() event 16 on ifindex 13
src/manager.c:manager_new_station_interface_cb()
src/netdev.c:netdev_create_from_genl() Created interface wlan0[13 a]
src/manager.c:manager_config_notify() Notification of command New Interface(7)
src/manager.c:manager_new_p2p_interface_cb()
src/p2p.c:p2p_device_update_from_genl() Created P2P device b
src/netdev.c:netdev_link_notify() event 16 on ifindex 13
src/wiphy.c:wiphy_reg_notify() Notification of command Wiphy Reg Change(113)
src/wiphy.c:wiphy_update_reg_domain() New reg domain country code for phy0 is XX
src/netdev.c:netdev_set_4addr() netdev: 13 use_4addr: 0
src/netdev.c:netdev_initial_up_cb() Interface 13 initialized
src/netconfig.c:netconfig_new() Starting netconfig for interface: 13
src/station.c:station_enter_state() Old State: disconnected, new state: autoconnect_quick
src/wiphy.c:wiphy_radio_work_insert() Inserting work item 1
src/wiphy.c:wiphy_radio_work_next() Starting work item 1
src/rrm.c:rrm_add_frame_watches()
src/netdev.c:netdev_link_notify() event 16 on ifindex 13
src/netdev.c:netdev_link_notify() event 16 on ifindex 13
src/manager.c:manager_config_notify() Notification of command Set Interface(6)
src/scan.c:scan_notify() Scan notification Trigger Scan(33)
src/scan.c:scan_request_triggered() Active scan triggered for wdev a
src/station.c:station_quick_scan_triggered() Quick scan triggered for wlan0
src/wiphy.c:wiphy_reg_notify() Notification of command Wiphy Reg Change(113)
src/wiphy.c:wiphy_update_reg_domain() New reg domain country code for phy0 is US
src/scan.c:scan_notify() Scan notification New Scan Results(34)
src/netdev.c:netdev_link_notify() event 16 on ifindex 13
src/scan.c:get_scan_callback() get_scan_callback
src/scan.c:scan_parse_bss_information_elements() Load: 0/255
src/scan.c:get_scan_callback() get_scan_callback
src/scan.c:scan_parse_bss_information_elements() Load: 66/255
src/scan.c:get_scan_callback() get_scan_callback
src/scan.c:scan_parse_bss_information_elements() Load: 212/255
src/scan.c:get_scan_callback() get_scan_callback
src/scan.c:scan_parse_bss_information_elements() Load: 43/255
src/scan.c:scan_parse_advertisement_protocol()
src/scan.c:get_scan_callback() get_scan_callback
src/scan.c:scan_parse_bss_information_elements() Load: 206/255
src/scan.c:get_scan_callback() get_scan_callback
src/scan.c:scan_parse_bss_information_elements() Load: 205/255
src/scan.c:get_scan_callback() get_scan_callback
src/scan.c:get_scan_callback() get_scan_callback
src/scan.c:get_scan_callback() get_scan_callback
src/scan.c:get_scan_callback() get_scan_callback
src/scan.c:scan_parse_bss_information_elements() Load: 68/255
src/scan.c:get_scan_callback() get_scan_callback
src/scan.c:get_scan_callback() get_scan_callback
src/scan.c:get_scan_callback() get_scan_callback
src/scan.c:scan_parse_bss_information_elements() Load: 19/255
src/scan.c:get_scan_done() get_scan_done
...
src/station.c:station_autoconnect_start()
src/station.c:station_autoconnect_next() autoconnect: Trying SSID: nnnnnnnn
src/station.c:station_autoconnect_next() autoconnect: 'xx:xx:xx:xx:xx:xx' freq: 5180, rank: 13107, strength: -6300
src/netdev.c:netdev_cqm_rssi_update()
src/wiphy.c:wiphy_radio_work_insert() Inserting work item 2
src/station.c:__station_connect_network() connecting to BSS xx:xx:xx:xx:xx:xx
src/station.c:station_enter_state() Old State: autoconnect_quick, new state: connecting (auto)
src/scan.c:scan_cancel() Trying to cancel scan id 1 for wdev a
src/wiphy.c:wiphy_radio_work_done() Work item 1 done
src/wiphy.c:wiphy_radio_work_next() Starting work item 2
src/netdev.c:netdev_mlme_notify() MLME notification New Station(19)
src/station.c:station_netdev_event() Associating
src/netdev.c:netdev_mlme_notify() MLME notification Authenticate(37)
src/netdev.c:netdev_authenticate_event()
src/netdev.c:netdev_mlme_notify() MLME notification Associate(38)
src/netdev.c:netdev_associate_event()
src/netdev.c:netdev_link_notify() event 16 on ifindex 13
src/netdev.c:netdev_mlme_notify() MLME notification Connect(46)
src/netdev.c:netdev_connect_event()
src/netdev.c:netdev_link_notify() event 16 on ifindex 13
src/netdev.c:netdev_link_notify() event 16 on ifindex 13
src/netdev.c:netdev_get_oci_cb() Obtained OCI: freq: 5180, width: 3, center1: 5210, center2: 0
src/netdev.c:netdev_link_notify() event 16 on ifindex 13
src/netdev.c:netdev_unicast_notify() Unicast notification Control Port Frame(129)
src/netdev.c:netdev_control_port_frame_event()
src/eapol.c:eapol_handle_ptk_1_of_4() ifindex=13
src/netdev.c:netdev_mlme_notify() MLME notification Control Port TX Status(139)
src/netdev.c:netdev_unicast_notify() Unicast notification Control Port Frame(129)
src/netdev.c:netdev_control_port_frame_event()
src/eapol.c:eapol_handle_ptk_3_of_4() ifindex=13
src/netdev.c:netdev_set_gtk() 13
src/station.c:station_handshake_event() Setting keys
src/netdev.c:netdev_set_tk() 13
src/netdev.c:netdev_set_rekey_offload() 13
src/netdev.c:netdev_mlme_notify() MLME notification Control Port TX Status(139)
src/netdev.c:netdev_mlme_notify() MLME notification Notify CQM(64)
src/station.c:station_connect_cb() 13, result: 0
src/station.c:station_connect_ok()
src/wiphy.c:wiphy_radio_work_done() Work item 2 done
src/netdev.c:netdev_link_notify() event 16 on ifindex 13
src/netconfig.c:netconfig_ifaddr_ipv6_added() ifindex 13: ifaddr fe80::1a5e:fff:fe82:bdec/64
Segmentation fault
*****
And here's syslog:
Nov 9 19:55:07 lila kernel: [ 952.596320] wlan0: authenticated
Nov 9 19:55:07 lila kernel: [ 952.597667] wlan0: associate with xx:xx:xx:xx:xx:xx (try 1/3)
Nov 9 19:55:07 lila kernel: [ 952.601524] wlan0: RX AssocResp from xx:xx:xx:xx:xx:xx (capab=0x11 status=0 aid=1)
Nov 9 19:55:07 lila kernel: [ 952.603444] wlan0: associated
Nov 9 19:55:07 lila kernel: [ 952.655558] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
Nov 9 19:55:08 lila avahi-daemon[771]: Joining mDNS multicast group on interface wlan0.IPv6 with address fe80::1a5e:fff:fe82:bdec.
Nov 9 19:55:08 lila avahi-daemon[771]: New relevant interface wlan0.IPv6 for mDNS.
Nov 9 19:55:08 lila avahi-daemon[771]: Registering new address record for fe80::1a5e:fff:fe82:bdec on wlan0.*.
Nov 9 19:55:08 lila kernel: [ 953.801798] iwd[3276]: segfault at 0 ip 00007f3da1e5a231 sp 00007ffdbcbf18c8 error 4 in libc-2.32.so[7f3da1d21000+149000]
Nov 9 19:55:08 lila kernel: [ 953.801833] Code: 84 00 00 00 00 00 0f 1f 00 31 c0 c5 f8 77 c3 66 2e 0f 1f 84 00 00 00 00 00 89 f9 48 89 fa c5 f9 ef c0 83 e1 3f 83 f9 20 77 1f <c5> fd 74 0f c5 fd d7 c1 85 c0 0f 85 df 00 00 00 48 83 c7 20 83 e1
Nov 9 19:55:08 lila kernel: [ 953.841933] wlan0: deauthenticating from xx:xx:xx:xx:xx:xx by local choice (Reason: 3=DEAUTH_LEAVING)
Nov 9 19:55:08 lila avahi-daemon[771]: Interface wlan0.IPv6 no longer relevant for mDNS.
Nov 9 19:55:08 lila avahi-daemon[771]: Leaving mDNS multicast group on interface wlan0.IPv6 with address fe80::1a5e:fff:fe82:bdec.
Nov 9 19:55:08 lila avahi-daemon[771]: Withdrawing address record for fe80::1a5e:fff:fe82:bdec on wlan0.
Tmore1 <tmore1(a)gmx.com>
6 months, 1 week
[PATCH] auto-t: fix testP2P
by Torsten Schmitz
testP2P was failing with
FileNotFoundError: [Errno 2] No such file or directory:
'/tmp/wpa_supplicant.conf'
---
tools/test-runner | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/test-runner b/tools/test-runner
index 9ae33301..5fc4285d 100755
--- a/tools/test-runner
+++ b/tools/test-runner
@@ -955,7 +955,7 @@ class TestContext(Namespace):
else:
wpas_radios = [rad for rad in self.radios if
rad.name in settings]
- self.wpas_interfaces =
[rad.create_interface('wpa_supplicant.conf', 'wpas') \
+ self.wpas_interfaces =
[rad.create_interface(settings[rad.name], 'wpas') \
for rad in wpas_radios]
def start_ofono(self):
--
2.33.1
6 months, 1 week