[RFC connman v1 1/1] gsupplicant: Add support for WPA3-Personal
by Ariel D'Alessandro
Hi all, Daniel:
WPA3 support has been recently added to connman (wpa_supplicant). As
we've been discussing on a previous thread, this only supports
WPA3-Personal-only mode.
This RFC patchset adds support for WPA3-Personal transition mode, which
supports both WPA2-Personal (PSK) and WPA3-Personal (SAE).
Based on the AP accepted key management protocols, connman configures
wpa_supplicant as follows:
* WPA3-Personal-only mode: key_mgmt="SAE" ; ieee80211w=2
* WPA3-Personal transition mode: key_mgmt="SAE WPA-PSK" ; ieee80211w=1
This patch applies cleanly on top of current master branch (commit
e36a38d8).
I'd like to hear any thoughts you might have about this.
For reference, see wpa_supplicant configuration [0].
Regards,
Ariel D'Alessandro
[0] https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf
Ariel D'Alessandro (1):
gsupplicant: Add support for WPA3-Personal transition mode
gsupplicant/supplicant.c | 29 +++++++++++++++++++----------
1 file changed, 19 insertions(+), 10 deletions(-)
--
2.30.2
8 months, 1 week
Cannot connect to SAE protected AP with iwd 1.16 and beyond
by Jesus Gonzalez
First of all: I looked around and found no dedicated bug tracker. if this is not the place to report bugs, please excuse me, and I would be glad to be pointed in the correct direction. Thank you!
Starting with iwd 1.16 I am not able to connect to my home WLAN network. It is a WPA3 SAE protected access point running on a Netgear R7800 with OpenWRT, in case it matters. Connecting to my WPA2 PSK AP on my phone as a test works just fine.
The connection log from the client: https://pastebin.com/48umPPzh
The only but decisive log entry in the AP: https://pastebin.com/W7JsH1kY
It seems after iwd 1.16 the client tries to associate before it is correctly authenticated. Maybe a race condition, and iwd got too fast for the router?
I tried to bisect between 1.15 and 1.16 to get the commit, but I ran into problems while building (make[1]: *** No rule to make target 'ell/util.c', needed by 'ell/util.lo'. Stop.) and I currently lack the time to troubleshoot Makefiles.
Sorry for the vague infos. If you want more logs, tell me what you need and I'll be happy to provide it! Thank you!
8 months, 2 weeks
[PATCH] test-runner: Fix verbose check for processes in namespaces
by Andrew Zaborowski
Check whether verbose output is enabled for process name arg[0] before
prepending the "ip netns exec" part to arg since arg[0] is going to be
"ip" after that.
---
tools/test-runner | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/test-runner b/tools/test-runner
index 8b244e99..42f140bf 100755
--- a/tools/test-runner
+++ b/tools/test-runner
@@ -176,12 +176,12 @@ class Process(subprocess.Popen):
global config
self.ctx = config.ctx
- if namespace:
- args = ['ip', 'netns', 'exec', namespace] + args
-
if self.ctx.is_verbose(args[0], log=False):
self.verbose = True
+ if namespace:
+ args = ['ip', 'netns', 'exec', namespace] + args
+
if outfile:
self._append_outfile(outfile)
--
2.30.2
8 months, 3 weeks
[PATCH] ap: Add MACs to FILS IP Assignment responses
by Andrew Zaborowski
Try to include the gateway and DNS MAC addresses in the corresponding
fields in the FILS IP Address Assignment IEs we send to the clients.
---
src/ap.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 122 insertions(+), 2 deletions(-)
diff --git a/src/ap.c b/src/ap.c
index 77de596a..d6802fda 100644
--- a/src/ap.c
+++ b/src/ap.c
@@ -92,6 +92,10 @@ struct ap_state {
struct l_dhcp_server *netconfig_dhcp;
struct l_rtnl_address *netconfig_addr4;
uint32_t rtnl_add_cmd;
+ uint32_t rtnl_get_gateway4_mac_cmd;
+ uint32_t rtnl_get_dns4_mac_cmd;
+ uint8_t netconfig_gateway4_mac[6];
+ uint8_t netconfig_dns4_mac[6];
bool started : 1;
bool gtk_set : 1;
@@ -211,6 +215,16 @@ static void ap_reset(struct ap_state *ap)
if (ap->rtnl_add_cmd)
l_netlink_cancel(rtnl, ap->rtnl_add_cmd);
+ if (ap->rtnl_get_gateway4_mac_cmd) {
+ l_netlink_cancel(rtnl, ap->rtnl_get_gateway4_mac_cmd);
+ ap->rtnl_get_gateway4_mac_cmd = 0;
+ }
+
+ if (ap->rtnl_get_dns4_mac_cmd) {
+ l_netlink_cancel(rtnl, ap->rtnl_get_dns4_mac_cmd);
+ ap->rtnl_get_dns4_mac_cmd = 0;
+ }
+
l_queue_destroy(ap->sta_states, ap_sta_free);
if (ap->rates)
@@ -1470,13 +1484,19 @@ static uint32_t ap_assoc_resp(struct ap_state *ap, struct sta_state *sta,
if (lease_lifetime != 0xffffffff)
ip_resp_info.ipv4_lifetime = lease_lifetime;
- if (lease_gateway_str)
+ if (lease_gateway_str) {
ip_resp_info.ipv4_gateway =
IP4_FROM_STR(lease_gateway_str);
+ memcpy(ip_resp_info.ipv4_gateway_mac,
+ ap->netconfig_gateway4_mac, 6);
+ }
- if (lease_dns_str_list && lease_dns_str_list[0])
+ if (lease_dns_str_list && lease_dns_str_list[0]) {
ip_resp_info.ipv4_dns =
IP4_FROM_STR(lease_dns_str_list[0]);
+ memcpy(ip_resp_info.ipv4_dns_mac,
+ ap->netconfig_dns4_mac, 6);
+ }
l_strv_free(lease_dns_str_list);
sta->ip_alloc_sent = true;
@@ -2561,6 +2581,104 @@ static void ap_mlme_notify(struct l_genl_msg *msg, void *user_data)
}
}
+static void ap_get_gateway4_mac_cb(int error, const uint8_t *hwaddr,
+ size_t hwaddr_len, void *user_data)
+{
+ struct ap_state *ap = user_data;
+
+ ap->rtnl_get_gateway4_mac_cmd = 0;
+
+ if (error) {
+ l_debug("Error: %s (%i)", strerror(-error), -error);
+ return;
+ }
+
+ if (L_WARN_ON(unlikely(hwaddr_len != 6)))
+ return;
+
+ l_debug("Resolved mac to " MAC, MAC_STR(hwaddr));
+ memcpy(ap->netconfig_gateway4_mac, hwaddr, 6);
+}
+
+static void ap_get_dns4_mac_cb(int error, const uint8_t *hwaddr,
+ size_t hwaddr_len, void *user_data)
+{
+ struct ap_state *ap = user_data;
+
+ ap->rtnl_get_dns4_mac_cmd = 0;
+
+ if (error) {
+ l_debug("Error: %s (%i)", strerror(-error), -error);
+ return;
+ }
+
+ if (L_WARN_ON(unlikely(hwaddr_len != 6)))
+ return;
+
+ l_debug("Resolved mac to " MAC, MAC_STR(hwaddr));
+ memcpy(ap->netconfig_dns4_mac, hwaddr, 6);
+}
+
+static void ap_query_macs(struct ap_state *ap, const char *addr_str,
+ uint8_t prefix_len, const char *gateway_str,
+ const char **dns_str_list)
+{
+ uint32_t local = IP4_FROM_STR(addr_str);
+ uint32_t gateway = 0;
+ uint32_t dns = 0;
+ uint32_t ifindex = netdev_get_ifindex(ap->netdev);
+
+ /*
+ * For simplicity only check the ARP/NDP tables to see if we already
+ * have the MACs that we need. There doesn't seem to be an API to
+ * actually resolve addresses that are not in these tables other than
+ * by triggering IP traffic to those hosts, such as a ping. In a PC
+ * or mobile device scenario we're likely to have these MACs already,
+ * otherwise we give up as this is a pretty low-priority feature.
+ */
+
+ if (gateway_str) {
+ gateway = IP4_FROM_STR(gateway_str);
+ if (L_WARN_ON(unlikely(!gateway)))
+ return;
+
+ if (gateway == local)
+ memcpy(ap->netconfig_gateway4_mac,
+ netdev_get_address(ap->netdev), 6);
+ else {
+ ap->rtnl_get_gateway4_mac_cmd =
+ l_rtnl_neighbor_get_hwaddr(rtnl, ifindex,
+ AF_INET, &gateway,
+ ap_get_gateway4_mac_cb,
+ ap, NULL);
+ if (!ap->rtnl_get_gateway4_mac_cmd)
+ l_debug("l_rtnl_neighbor_get_hwaddr() failed "
+ "for the gateway IP");
+ }
+ }
+
+ if (dns_str_list) {
+ dns = IP4_FROM_STR(dns_str_list[0]);
+ if (L_WARN_ON(unlikely(!dns)))
+ return;
+
+ /* TODO: can also skip query if dns == gateway */
+ if (dns == local)
+ memcpy(ap->netconfig_dns4_mac,
+ netdev_get_address(ap->netdev), 6);
+ else if (util_ip_subnet_match(prefix_len, &dns, &local)) {
+ ap->rtnl_get_dns4_mac_cmd =
+ l_rtnl_neighbor_get_hwaddr(rtnl, ifindex,
+ AF_INET, &dns,
+ ap_get_dns4_mac_cb,
+ ap, NULL);
+ if (!ap->rtnl_get_dns4_mac_cmd)
+ l_debug("l_rtnl_neighbor_get_hwaddr() failed "
+ "for the DNS IP");
+ }
+ }
+}
+
#define AP_DEFAULT_IPV4_PREFIX_LEN 28
static int ap_setup_netconfig4(struct ap_state *ap, const char **addr_str_list,
@@ -2689,6 +2807,8 @@ static int ap_setup_netconfig4(struct ap_state *ap, const char **addr_str_list,
ap->netconfig_set_addr4 = false;
}
+ ap_query_macs(ap, addr_str_buf, prefix_len, gateway_str, dns_str_list);
+
cleanup:
l_dhcp_server_destroy(dhcp);
l_rtnl_address_free(new_addr);
--
2.30.2
8 months, 3 weeks
[PATCH 5/5] netconfig: Apply MACs received in FILS IP Assigment
by Andrew Zaborowski
Use the MAC addresses for the gateways and DNS servers received in the
FILS IP Assigment IE together with the gateway IP and DNS server IP.
Commit the IP to MAC mappings directly to the ARP/NDP tables so that the
network stack can skip sending the corresponding queries over the air.
---
src/netconfig.c | 119 +++++++++++++++++++++++++++++++++++++++---------
1 file changed, 98 insertions(+), 21 deletions(-)
diff --git a/src/netconfig.c b/src/netconfig.c
index 6e1e1aa7..9bbaece5 100644
--- a/src/netconfig.c
+++ b/src/netconfig.c
@@ -196,22 +196,40 @@ static inline char *netconfig_ipv6_to_string(const uint8_t *addr)
return addr_str;
}
+static void netconfig_set_neighbor_entry_cb(int error,
+ uint16_t type, const void *data,
+ uint32_t len, void *user_data)
+{
+ if (error)
+ l_error("l_rtnl_neighbor_set_hwaddr failed: %s (%i)",
+ strerror(-error), error);
+}
+
static int netconfig_set_dns(struct netconfig *netconfig)
{
char **dns6_list = NULL;
char **dns4_list = NULL;
unsigned int n_entries = 0;
char **dns_list;
+ const uint8_t *fils_dns4_mac = NULL;
+ const uint8_t *fils_dns6_mac = NULL;
+ const struct ie_fils_ip_addr_response_info *fils =
+ netconfig->fils_override;
if (!netconfig->dns4_overrides &&
netconfig->rtm_protocol == RTPROT_DHCP) {
const struct l_dhcp_lease *lease;
- if (netconfig->fils_override &&
- netconfig->fils_override->ipv4_dns) {
+ if (fils && fils->ipv4_dns) {
dns4_list = l_new(char *, 2);
- dns4_list[0] = netconfig_ipv4_to_string(
- netconfig->fils_override->ipv4_dns);
+ dns4_list[0] = netconfig_ipv4_to_string(fils->ipv4_dns);
+
+ if (!l_memeqzero(fils->ipv4_dns_mac, 6) &&
+ util_ip_subnet_match(
+ fils->ipv4_prefix_len,
+ &fils->ipv4_addr,
+ &fils->ipv4_dns))
+ fils_dns4_mac = fils->ipv4_dns_mac;
} else if ((lease = l_dhcp_client_get_lease(
netconfig->dhcp_client)))
dns4_list = l_dhcp_lease_get_dns(lease);
@@ -221,12 +239,17 @@ static int netconfig_set_dns(struct netconfig *netconfig)
netconfig->rtm_v6_protocol == RTPROT_DHCP) {
const struct l_dhcp6_lease *lease;
- if (netconfig->fils_override &&
- !l_memeqzero(netconfig->fils_override->ipv6_dns,
+ if (fils && !l_memeqzero(fils->ipv6_dns,
16)) {
dns6_list = l_new(char *, 2);
- dns6_list[0] = netconfig_ipv6_to_string(
- netconfig->fils_override->ipv6_dns);
+ dns6_list[0] = netconfig_ipv6_to_string(fils->ipv6_dns);
+
+ if (!l_memeqzero(fils->ipv6_dns_mac, 6) &&
+ util_ip_subnet_match(
+ fils->ipv6_prefix_len,
+ fils->ipv6_addr,
+ fils->ipv6_dns))
+ fils_dns6_mac = fils->ipv6_dns_mac;
} else if ((lease = l_dhcp6_client_get_lease(
netconfig->dhcp6_client)))
dns6_list = l_dhcp6_lease_get_dns(lease);
@@ -242,15 +265,28 @@ static int netconfig_set_dns(struct netconfig *netconfig)
APPEND_STRDUPV(dns_list, n_entries, netconfig->dns4_overrides);
APPENDV(dns_list, n_entries, dns4_list);
- /* Contents now belong to ret, so not l_strfreev */
- l_free(dns4_list);
APPEND_STRDUPV(dns_list, n_entries, netconfig->dns6_overrides);
APPENDV(dns_list, n_entries, dns6_list);
- /* Contents now belong to ret, so not l_strfreev */
- l_free(dns6_list);
-
resolve_set_dns(netconfig->resolve, dns_list);
+
+ if (fils_dns4_mac && !l_rtnl_neighbor_set_hwaddr(rtnl,
+ netconfig->ifindex, AF_INET,
+ &fils->ipv4_dns, fils_dns4_mac, 6,
+ netconfig_set_neighbor_entry_cb, NULL,
+ NULL))
+ l_debug("l_rtnl_neighbor_set_hwaddr failed");
+
+ if (fils_dns6_mac && !l_rtnl_neighbor_set_hwaddr(rtnl,
+ netconfig->ifindex, AF_INET6,
+ fils->ipv6_dns, fils_dns6_mac, 6,
+ netconfig_set_neighbor_entry_cb, NULL,
+ NULL))
+ l_debug("l_rtnl_neighbor_set_hwaddr failed");
+
l_strv_free(dns_list);
+ /* Contents belonged to dns_list, so not l_strfreev */
+ l_free(dns4_list);
+ l_free(dns6_list);
return 0;
}
@@ -361,7 +397,8 @@ static struct l_rtnl_address *netconfig_get_static4_address(
return ifaddr;
}
-static char *netconfig_ipv4_get_gateway(struct netconfig *netconfig)
+static char *netconfig_ipv4_get_gateway(struct netconfig *netconfig,
+ const uint8_t **out_mac)
{
const struct l_dhcp_lease *lease;
char *gateway;
@@ -379,10 +416,18 @@ static char *netconfig_ipv4_get_gateway(struct netconfig *netconfig)
case RTPROT_DHCP:
if (netconfig->fils_override &&
- netconfig->fils_override->ipv4_gateway)
- return netconfig_ipv4_to_string(
+ netconfig->fils_override->ipv4_gateway) {
+ gateway = netconfig_ipv4_to_string(
netconfig->fils_override->ipv4_gateway);
+ if (gateway && !l_memeqzero(netconfig->fils_override->
+ ipv4_gateway_mac, 6))
+ *out_mac = netconfig->fils_override->
+ ipv4_gateway_mac;
+
+ return gateway;
+ }
+
lease = l_dhcp_client_get_lease(netconfig->dhcp_client);
if (!lease)
return NULL;
@@ -431,7 +476,8 @@ no_prefix_len:
}
static struct l_rtnl_route *netconfig_get_static6_gateway(
- struct netconfig *netconfig)
+ struct netconfig *netconfig,
+ const uint8_t **out_mac)
{
L_AUTO_FREE_VAR(char *, gateway);
struct l_rtnl_route *ret;
@@ -441,10 +487,13 @@ static struct l_rtnl_route *netconfig_get_static6_gateway(
if (!gateway && netconfig->rtm_v6_protocol == RTPROT_DHCP &&
netconfig->fils_override &&
!l_memeqzero(netconfig->fils_override->ipv6_gateway,
- 16))
+ 16)) {
gateway = netconfig_ipv6_to_string(
netconfig->fils_override->ipv6_gateway);
- else if (!gateway)
+
+ if (!l_memeqzero(netconfig->fils_override->ipv6_gateway_mac, 6))
+ *out_mac = netconfig->fils_override->ipv6_gateway_mac;
+ } else if (!gateway)
return NULL;
ret = l_rtnl_route_new_gateway(gateway);
@@ -678,6 +727,7 @@ static void netconfig_route_add_cmd_cb(int error, uint16_t type,
static bool netconfig_ipv4_routes_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];
@@ -704,7 +754,7 @@ static bool netconfig_ipv4_routes_install(struct netconfig *netconfig)
return false;
}
- gateway = netconfig_ipv4_get_gateway(netconfig);
+ gateway = netconfig_ipv4_get_gateway(netconfig, &gateway_mac);
if (!gateway) {
l_debug("No gateway obtained from %s.",
netconfig->rtm_protocol == RTPROT_STATIC ?
@@ -732,6 +782,24 @@ 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,
+ 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");
+ }
+
return true;
}
@@ -764,6 +832,7 @@ static void netconfig_ipv6_ifaddr_add_cmd_cb(int error, uint16_t type,
{
struct netconfig *netconfig = user_data;
struct l_rtnl_route *gateway;
+ const uint8_t *gateway_mac = NULL;
netconfig->addr6_add_cmd_id = 0;
@@ -773,13 +842,21 @@ static void netconfig_ipv6_ifaddr_add_cmd_cb(int error, uint16_t type,
return;
}
- gateway = netconfig_get_static6_gateway(netconfig);
+ gateway = netconfig_get_static6_gateway(netconfig, &gateway_mac);
if (gateway) {
L_WARN_ON(!l_rtnl_route_add(rtnl, netconfig->ifindex,
gateway,
netconfig_route_generic_cb,
netconfig, NULL));
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);
--
2.30.2
8 months, 3 weeks
[PATCH 1/3] auto-t: hwsim.py: turn Hwsim into singleton (per-namespace)
by James Prestwood
This prevents reallocation of new Hwsim classes on each call if one
already exists. This is a bit more efficient on memory.
---
autotests/util/hwsim.py | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/autotests/util/hwsim.py b/autotests/util/hwsim.py
index db106dcb..cc62495c 100755
--- a/autotests/util/hwsim.py
+++ b/autotests/util/hwsim.py
@@ -3,6 +3,7 @@ import dbus
import sys
import collections
+from weakref import WeakValueDictionary
from abc import ABCMeta, abstractmethod
from enum import Enum
@@ -297,7 +298,25 @@ class RadioList(collections.Mapping):
return obj
class Hwsim(iwd.AsyncOpAbstract):
+ _instances = WeakValueDictionary()
+
+ def __new__(cls, namespace=ctx):
+ name = namespace.name
+
+ if name not in cls._instances.keys():
+ obj = object.__new__(cls)
+ obj._initialized = False
+
+ cls._instances[name] = obj
+
+ return cls._instances[name]
+
def __init__(self, namespace=ctx):
+ if self._initialized:
+ return
+
+ self._initialized = True
+
self._bus = namespace.get_bus()
self._rule_manager_if = dbus.Interface(
--
2.31.1
8 months, 3 weeks
[PATCH 1/5] netconfig: Move loading settings to new method, refactor
by Andrew Zaborowski
Split loading settings out of network_configure into a new method,
network_load_settings. Make sure both consistently handle errors by
printing messages and informing the caller.
---
src/netconfig.c | 236 ++++++++++++++++++++++++++++++------------------
src/netconfig.h | 5 +-
src/p2p.c | 12 ++-
src/station.c | 20 ++--
4 files changed, 175 insertions(+), 98 deletions(-)
diff --git a/src/netconfig.c b/src/netconfig.c
index 005316cd..10c9b90c 100644
--- a/src/netconfig.c
+++ b/src/netconfig.c
@@ -47,6 +47,7 @@
#include "src/common.h"
#include "src/network.h"
#include "src/resolve.h"
+#include "src/util.h"
#include "src/netconfig.h"
struct netconfig {
@@ -270,49 +271,47 @@ static int netconfig_set_domains(struct netconfig *netconfig)
}
static struct l_rtnl_address *netconfig_get_static4_address(
- struct netconfig *netconfig)
+ const struct l_settings *active_settings)
{
struct l_rtnl_address *ifaddr = NULL;
- char *ip;
- char *netmask;
+ L_AUTO_FREE_VAR(char *, ip) = NULL;
+ L_AUTO_FREE_VAR(char *, netmask) = NULL;
struct in_addr in_addr;
- char *broadcast;
+ L_AUTO_FREE_VAR(char *, broadcast) = NULL;
uint32_t prefix_len;
- ip = l_settings_get_string(netconfig->active_settings, "IPv4",
- "Address");
+ ip = l_settings_get_string(active_settings, "IPv4", "Address");
if (!ip)
return NULL;
- netmask = l_settings_get_string(netconfig->active_settings,
- "IPv4", "Netmask");
+ netmask = l_settings_get_string(active_settings, "IPv4", "Netmask");
+ if (netmask) {
+ if (inet_pton(AF_INET, netmask, &in_addr) != 1) {
+ l_error("netconfig: Can't parse IPv4 Netmask");
+ return NULL;
+ }
- if (netmask && inet_pton(AF_INET, netmask, &in_addr) > 0)
prefix_len = __builtin_popcountl(in_addr.s_addr);
- else
- prefix_len = 24;
- l_free(netmask);
+ if (ntohl(in_addr.s_addr) !=
+ util_netmask_from_prefix(prefix_len)) {
+ l_error("netconfig: Invalid IPv4 Netmask");
+ return NULL;
+ }
+ } else
+ prefix_len = 24;
ifaddr = l_rtnl_address_new(ip, prefix_len);
- l_free(ip);
-
if (!ifaddr) {
- l_error("Unable to parse IPv4.Address, ignoring...");
+ l_error("netconfig: Unable to parse IPv4.Address");
return NULL;
}
- broadcast = l_settings_get_string(netconfig->active_settings,
- "IPv4", "Broadcast");
- if (broadcast) {
- bool r = l_rtnl_address_set_broadcast(ifaddr, broadcast);
- l_free(broadcast);
-
- if (!r) {
- l_error("Unable to parse IPv4.Broadcast, ignoring...");
- l_rtnl_address_free(ifaddr);
- return NULL;
- }
+ broadcast = l_settings_get_string(active_settings, "IPv4", "Broadcast");
+ if (broadcast && !l_rtnl_address_set_broadcast(ifaddr, broadcast)) {
+ l_error("netconfig: Unable to parse IPv4.Broadcast");
+ l_rtnl_address_free(ifaddr);
+ return NULL;
}
l_rtnl_address_set_noprefixroute(ifaddr, true);
@@ -347,15 +346,14 @@ static char *netconfig_ipv4_get_gateway(struct netconfig *netconfig)
}
static struct l_rtnl_address *netconfig_get_static6_address(
- struct netconfig *netconfig)
+ const struct l_settings *active_settings)
{
L_AUTO_FREE_VAR(char *, ip);
char *p;
struct l_rtnl_address *ret;
uint32_t prefix_len = 128;
- ip = l_settings_get_string(netconfig->active_settings, "IPv6",
- "Address");
+ ip = l_settings_get_string(active_settings, "IPv6", "Address");
if (!ip)
return NULL;
@@ -898,14 +896,17 @@ static void netconfig_ipv4_acd_event(enum l_acd_event event, void *user_data)
}
}
-static void netconfig_ipv4_select_and_install(struct netconfig *netconfig)
+static bool netconfig_ipv4_select_and_install(struct netconfig *netconfig)
{
- char ip[INET6_ADDRSTRLEN];
+ if (netconfig->rtm_protocol == RTPROT_STATIC) {
+ char ip[INET6_ADDRSTRLEN];
+
+ if (L_WARN_ON(!netconfig->v4_address ||
+ !l_rtnl_address_get_address(
+ netconfig->v4_address,
+ ip)))
+ return false;
- netconfig->v4_address = netconfig_get_static4_address(netconfig);
- if (netconfig->v4_address &&
- l_rtnl_address_get_address(netconfig->v4_address, ip)) {
- netconfig->rtm_protocol = RTPROT_STATIC;
netconfig->acd = l_acd_new(netconfig->ifindex);
l_acd_set_event_handler(netconfig->acd,
netconfig_ipv4_acd_event, netconfig,
@@ -926,47 +927,43 @@ static void netconfig_ipv4_select_and_install(struct netconfig *netconfig)
netconfig, NULL)));
}
- return;
+ return true;
}
- netconfig->rtm_protocol = RTPROT_DHCP;
-
if (l_dhcp_client_start(netconfig->dhcp_client))
- return;
+ return true;
l_error("netconfig: Failed to start DHCPv4 client for interface %u",
netconfig->ifindex);
+ return false;
}
-static void netconfig_ipv6_select_and_install(struct netconfig *netconfig)
+static bool netconfig_ipv6_select_and_install(struct netconfig *netconfig)
{
struct netdev *netdev = netdev_find(netconfig->ifindex);
- struct l_rtnl_address *address;
- bool enabled;
- if (!l_settings_get_bool(netconfig->active_settings, "IPv6",
- "Enabled", &enabled))
- enabled = ipv6_enabled;
-
- if (!enabled) {
+ if (netconfig->rtm_v6_protocol == RTPROT_UNSPEC) {
l_debug("IPV6 configuration disabled");
- return;
+ return true;
}
sysfs_write_ipv6_setting(netdev_get_name(netdev), "disable_ipv6", "0");
- address = netconfig_get_static6_address(netconfig);
- if (address) {
- netconfig->rtm_v6_protocol = RTPROT_STATIC;
+ if (netconfig->rtm_v6_protocol == RTPROT_STATIC) {
+ struct l_rtnl_address *address =
+ netconfig_get_static6_address(
+ netconfig->active_settings);
+
L_WARN_ON(!(netconfig->addr6_add_cmd_id =
l_rtnl_ifaddr_add(rtnl, netconfig->ifindex, address,
netconfig_ipv6_ifaddr_add_cmd_cb,
netconfig, NULL)));
l_rtnl_address_free(address);
- return;
+ return true;
}
- netconfig->rtm_v6_protocol = RTPROT_DHCP;
+ /* DHCP */
+ return true;
}
static int validate_dns_list(int family, char **dns_list)
@@ -998,77 +995,144 @@ static int validate_dns_list(int family, char **dns_list)
return n_valid;
}
-bool netconfig_configure(struct netconfig *netconfig,
+bool netconfig_load_settings(struct netconfig *netconfig,
const struct l_settings *active_settings,
- const uint8_t *mac_address,
- netconfig_notify_func_t notify, void *user_data)
+ const uint8_t *mac_address)
{
char *mdns;
- char hostname[HOST_NAME_MAX + 1];
bool send_hostname;
+ bool v6_enabled;
+ char hostname[HOST_NAME_MAX + 1];
+ char **dns4_overrides = NULL;
+ char **dns6_overrides = NULL;
+ struct l_rtnl_address *v4_address = NULL;
+ struct l_rtnl_address *v6_address = NULL;
- netconfig->dns4_overrides = l_settings_get_string_list(active_settings,
+ dns4_overrides = l_settings_get_string_list(active_settings,
"IPv4", "DNS", ' ');
+ if (dns4_overrides) {
+ int r = validate_dns_list(AF_INET, dns4_overrides);
- if (netconfig->dns4_overrides) {
- int r = validate_dns_list(AF_INET, netconfig->dns4_overrides);
+ if (unlikely(r <= 0)) {
+ l_strfreev(dns4_overrides);
+ dns4_overrides = NULL;
- if (r <= 0) {
- l_strfreev(netconfig->dns4_overrides);
- netconfig->dns4_overrides = NULL;
+ if (r < 0)
+ goto err_dns4;
}
if (r == 0)
l_error("netconfig: Empty IPv4.DNS entry, skipping...");
}
- netconfig->dns6_overrides = l_settings_get_string_list(active_settings,
+ dns6_overrides = l_settings_get_string_list(active_settings,
"IPv6", "DNS", ' ');
- if (netconfig->dns6_overrides) {
- int r = validate_dns_list(AF_INET6, netconfig->dns6_overrides);
+ if (dns6_overrides) {
+ int r = validate_dns_list(AF_INET6, dns6_overrides);
+
+ if (unlikely(r <= 0)) {
+ l_strfreev(dns6_overrides);
+ dns6_overrides = NULL;
- if (r <= 0) {
- l_strfreev(netconfig->dns6_overrides);
- netconfig->dns6_overrides = NULL;
+ if (r < 0)
+ goto err_dns6;
}
if (r == 0)
l_error("netconfig: Empty IPv6.DNS entry, skipping...");
}
- netconfig->active_settings = active_settings;
- netconfig->notify = notify;
- netconfig->user_data = user_data;
-
- l_dhcp_client_set_address(netconfig->dhcp_client, ARPHRD_ETHER,
- mac_address, ETH_ALEN);
- l_dhcp6_client_set_address(netconfig->dhcp6_client, ARPHRD_ETHER,
- mac_address, ETH_ALEN);
-
if (!l_settings_get_bool(active_settings,
"IPv4", "SendHostname", &send_hostname))
send_hostname = false;
if (send_hostname) {
- if (gethostname(hostname, sizeof(hostname)) == 0) {
- l_dhcp_client_set_hostname(
- netconfig->dhcp_client, hostname);
- } else {
+ if (gethostname(hostname, sizeof(hostname)) != 0) {
l_warn("netconfig: Unable to get hostname. "
"Error %d: %s", errno, strerror(errno));
+ send_hostname = false;
}
}
- netconfig_ipv4_select_and_install(netconfig);
+ mdns = l_settings_get_string(active_settings,
+ "Network", "MulticastDNS");
- netconfig_ipv6_select_and_install(netconfig);
+ if (l_settings_has_key(active_settings, "IPv4", "Address")) {
+ v4_address = netconfig_get_static4_address(active_settings);
+
+ if (unlikely(!v4_address)) {
+ l_error("netconfig: Can't parse IPv4 address");
+ goto err_v4_addr;
+ }
+ }
+
+ if (!l_settings_get_bool(active_settings, "IPv6",
+ "Enabled", &v6_enabled))
+ v6_enabled = ipv6_enabled;
+
+ if (l_settings_has_key(active_settings, "IPv6", "Address")) {
+ v6_address = netconfig_get_static6_address(active_settings);
+ l_rtnl_address_free(v6_address);
+
+ if (unlikely(!v6_address)) {
+ l_error("netconfig: Can't parse IPv6 address");
+ goto err_v6_addr;
+ }
+ }
+
+ /* No more validation steps for now, commit new values */
+
+ if (v4_address) {
+ netconfig->v4_address = v4_address;
+ netconfig->rtm_protocol = RTPROT_STATIC;
+ } else
+ netconfig->rtm_protocol = RTPROT_DHCP;
+
+ if (!v6_enabled)
+ netconfig->rtm_v6_protocol = RTPROT_UNSPEC;
+ else if (v6_address)
+ netconfig->rtm_v6_protocol = RTPROT_STATIC;
+ else
+ netconfig->rtm_v6_protocol = RTPROT_DHCP;
+
+ if (send_hostname)
+ l_dhcp_client_set_hostname(netconfig->dhcp_client, hostname);
- mdns = l_settings_get_string(active_settings,
- "Network", "MulticastDNS");
resolve_set_mdns(netconfig->resolve, mdns);
l_free(mdns);
+ l_dhcp_client_set_address(netconfig->dhcp_client, ARPHRD_ETHER,
+ mac_address, ETH_ALEN);
+ l_dhcp6_client_set_address(netconfig->dhcp6_client, ARPHRD_ETHER,
+ mac_address, ETH_ALEN);
+
+ netconfig->active_settings = active_settings;
+ return true;
+
+err_v6_addr:
+ l_rtnl_address_free(v4_address);
+err_v4_addr:
+ l_free(mdns);
+ l_strfreev(dns6_overrides);
+err_dns6:
+ l_strfreev(dns4_overrides);
+err_dns4:
+ return false;
+}
+
+bool netconfig_configure(struct netconfig *netconfig,
+ netconfig_notify_func_t notify, void *user_data)
+{
+ netconfig->notify = notify;
+ netconfig->user_data = user_data;
+
+ if (unlikely(!netconfig_ipv4_select_and_install(netconfig)))
+ return false;
+
+ if (unlikely(!netconfig_ipv6_select_and_install(netconfig)))
+ return false;
+
return true;
}
diff --git a/src/netconfig.h b/src/netconfig.h
index 2c68cb1c..73e4df8b 100644
--- a/src/netconfig.h
+++ b/src/netconfig.h
@@ -29,9 +29,10 @@ enum netconfig_event {
typedef void (*netconfig_notify_func_t)(enum netconfig_event event,
void *user_data);
-bool netconfig_configure(struct netconfig *netconfig,
+bool netconfig_load_settings(struct netconfig *netconfig,
const struct l_settings *active_settings,
- const uint8_t *mac_address,
+ const uint8_t *mac_address);
+bool netconfig_configure(struct netconfig *netconfig,
netconfig_notify_func_t notify,
void *user_data);
bool netconfig_reconfigure(struct netconfig *netconfig);
diff --git a/src/p2p.c b/src/p2p.c
index 8170bbe0..3328271b 100644
--- a/src/p2p.c
+++ b/src/p2p.c
@@ -1328,8 +1328,16 @@ static void p2p_start_client_netconfig(struct p2p_device *dev)
}
settings = dev->conn_netconfig_settings ?: p2p_dhcp_settings;
- netconfig_configure(dev->conn_netconfig, settings, dev->conn_addr,
- p2p_netconfig_event_handler, dev);
+
+ if (!netconfig_load_settings(dev->conn_netconfig, settings,
+ dev->conn_addr) ||
+ !netconfig_configure(dev->conn_netconfig,
+ p2p_netconfig_event_handler,
+ dev)) {
+ p2p_connect_failed(dev);
+ return;
+ }
+
dev->conn_dhcp_timeout = l_timeout_create(p2p_dhcp_timeout_val,
p2p_dhcp_timeout, dev,
p2p_dhcp_timeout_destroy);
diff --git a/src/station.c b/src/station.c
index d61e775a..f6237ade 100644
--- a/src/station.c
+++ b/src/station.c
@@ -2443,14 +2443,12 @@ static void station_connect_ok(struct station *station)
network_connected(station->connected_network);
- if (station->netconfig)
- netconfig_configure(station->netconfig,
- network_get_settings(
- station->connected_network),
- netdev_get_address(station->netdev),
- station_netconfig_event_handler,
- station);
- else
+ if (station->netconfig) {
+ if (L_WARN_ON(!netconfig_configure(station->netconfig,
+ station_netconfig_event_handler,
+ station)))
+ return;
+ } else
station_enter_state(station, STATION_STATE_CONNECTED);
}
@@ -2592,6 +2590,12 @@ int __station_connect_network(struct station *station, struct network *network,
struct handshake_state *hs;
int r;
+ if (station->netconfig && !netconfig_load_settings(
+ station->netconfig,
+ network_get_settings(network),
+ netdev_get_address(station->netdev)))
+ return -EINVAL;
+
hs = station_handshake_setup(station, network, bss);
if (!hs)
return -ENOTSUP;
--
2.30.2
8 months, 4 weeks
[PATCH 1/4] test-runner: inherit Popen by Process class
by James Prestwood
The Procss class was doing quite a bit of what Popen already does like
storing the return code and process arguments. In addition the Process
class ended up storing a Popen object which was frequently accessed.
For both simplicity and memory savings have Process inherit Popen and
add the additional functionality test-runner needs like stdout
processing to output files and the console.
To do this Popen.wait() needed to be overridden to to prevent blocking
as well as wait for the HUP signal so we are sure all the process
output was written. kill() was also overritten to perform cleanup.
The most intrusive change was removing wait as a kwarg, and instead
requiring the caller to call wait(). This doesn't change much in
terms of complexity to the caller, but simplifies the __init__
routine of Process.
Some convenient improvements:
- Separate multiple process instance output (Terminate: <args> will
be written to outfiles each time a process dies.)
- Append to outfile if the same process is started again
- Wait for HUP before returning from wait(). This allows any remaining
output to be written without the need to manually call process_io.
- Store ctx as a class variable so callers don't need to pass it in
(e.g. when using Process directly rather than start_process)
---
tools/test-runner | 228 +++++++++++++++++++++++-----------------------
1 file changed, 112 insertions(+), 116 deletions(-)
diff --git a/tools/test-runner b/tools/test-runner
index d7ff3d15..8b244e99 100755
--- a/tools/test-runner
+++ b/tools/test-runner
@@ -57,7 +57,7 @@ def dbg(*s, **kwargs):
def exit_vm():
if config:
for p in config.ctx.processes:
- print("Process %s still running!" % p.name)
+ print("Process %s still running!" % p.args[0])
p.kill()
p = None
@@ -159,102 +159,61 @@ busconfig.dtd\">
<allow eavesdrop=\"true\"/>
</policy>
'''
-class Process:
- '''
- Start a process. If 'wait' is True the constructor will start
- the process and wait for it to exit. No PID is tracked in this
- case.
- '''
- def __init__(self, args, wait=False, env=None, ctx=None, check=False,
- outfile=None, namespace=None, need_out=False, cleanup=None):
- self.killed = False
- self.args = args
- self.wait = wait
- self.name = args[0]
- self.ret = None
- self.ctx = ctx
+
+class Process(subprocess.Popen):
+ ctx = None
+
+ def __init__(self, args, namespace=None, outfile=None, env=None, check=False, cleanup=None):
self.write_fds = []
self.io_watch = None
self.cleanup = cleanup
self.verbose = False
self.out = ''
+ self.hup = False
+ self.killed = False
- if namespace:
- self.args = ['ip', 'netns', 'exec', namespace]
- self.args.extend(args)
-
- if ctx:
- # Verbose requested, add stdout/stderr to write FD list.
- # This will end up always returning true if logging is
- # on which isn't desired so pass log=False as to only
- # allow stdout to processes listed in --verbose.
- if ctx.is_verbose(self.name, log=False):
- self.verbose = True
-
- # Add output file to FD list
- if outfile:
- try:
- f = open(outfile, 'w')
- except Exception as e:
- dbg(e)
- exit(0)
-
- if ctx.args.log_uid:
- os.fchown(f.fileno(), int(ctx.args.log_uid), int(ctx.args.log_gid))
+ if not self.ctx:
+ global config
+ self.ctx = config.ctx
- self.write_fds.append(f)
+ if namespace:
+ args = ['ip', 'netns', 'exec', namespace] + args
- # Add log file to FD list
- if ctx.args.log:
- test = os.path.basename(os.getcwd())
- test_dir = '%s/%s' % (ctx.args.log, test)
+ if self.ctx.is_verbose(args[0], log=False):
+ self.verbose = True
- if not path_exists(test_dir):
- os.mkdir(test_dir)
- os.chown(test_dir, int(ctx.args.log_uid),
- int(ctx.args.log_gid))
+ if outfile:
+ self._append_outfile(outfile)
- f = open('%s/%s' % (test_dir, args[0]), 'a+')
- os.fchown(f.fileno(), int(ctx.args.log_uid), int(ctx.args.log_gid))
- self.write_fds.append(f)
+ if self.ctx.args.log:
+ logfile = '%s/%s/%s' % (self.ctx.args.log,
+ os.path.basename(os.getcwd()),
+ args[0])
+ self._append_outfile(logfile)
- self.pid = subprocess.Popen(self.args, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- env=env, cwd=os.getcwd())
+ super().__init__(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
+ env=env, cwd=os.getcwd())
# Set as non-blocking so read() in the IO callback doesn't block forever
- fl = fcntl.fcntl(self.pid.stdout, fcntl.F_GETFL)
- fcntl.fcntl(self.pid.stdout, fcntl.F_SETFL, fl | os.O_NONBLOCK)
+ fl = fcntl.fcntl(self.stdout, fcntl.F_GETFL)
+ fcntl.fcntl(self.stdout, fcntl.F_SETFL, fl | os.O_NONBLOCK)
- if not wait and not check:
- self.io_watch = GLib.io_add_watch(self.pid.stdout, GLib.IO_IN |
- GLib.IO_HUP | GLib.IO_ERR, self.io_callback)
+ self.io_watch = GLib.io_add_watch(self.stdout, GLib.IO_IN |
+ GLib.IO_HUP | GLib.IO_ERR, self.process_io)
- print("Starting process {}".format(self.pid.args))
+ print("Starting process {}".format(self.args))
- if not wait and not check:
- return
-
- Namespace.non_block_wait(self.wait_for_process, 10, 1)
- self.killed = True
- self.ret = self.pid.returncode
+ if check:
+ self.wait(10)
+ self.killed = True
+ if self.returncode != 0:
+ raise subprocess.CalledProcessError(returncode=self.returncode,
+ cmd=args)
- self.process_io(self.pid.stdout)
+ def process_io(self, source, condition):
+ if condition & GLib.IO_HUP:
+ self.hup = True
- self.write_fds = []
-
- print("%s returned %d" % (args[0], self.ret))
- if check and self.ret != 0:
- raise subprocess.CalledProcessError(returncode=self.ret, cmd=self.args)
-
- def wait_for_process(self, timeout):
- try:
- self.pid.wait(timeout)
- return True
- except:
- return False
-
- def process_io(self, source):
data = source.read()
if not data:
@@ -267,6 +226,12 @@ class Process:
for f in self.write_fds:
f.write(data)
+
+ # Write out a separator so multiple process calls per
+ # test are easer to read.
+ if self.hup:
+ f.write("Terminated: {}\n\n".format(self.args))
+
f.flush()
if self.verbose:
@@ -275,42 +240,73 @@ class Process:
return True
- def io_callback(self, source, cb_condition):
- return self.process_io(source)
+ def _append_outfile(self, file):
+ gid = int(self.ctx.args.log_gid)
+ uid = int(self.ctx.args.log_uid)
+ dir = os.path.dirname(file)
- def __del__(self):
- print("Del process %s" % self.args)
+ if not path_exists(dir):
+ os.mkdir(dir)
+ os.chown(dir, uid, gid)
- if not self.killed:
- self.kill()
+ file = os.path.join(dir,file)
- def kill(self, force=False):
- print("Killing process %s" % self.args)
+ # If the out file exists, append. Useful for processes like
+ # hostapd_cli where it is called multiple times independently.
+ if os.path.isfile(file):
+ mode = 'a'
+ else:
+ mode = 'w'
+
+ try:
+ f = open(os.path.join(dir, file), mode)
+ except Exception as e:
+ traceback.print_exc()
+ exit(0)
+
+ os.fchown(f.fileno(), uid, gid)
+
+ self.write_fds.append(f)
+
+ def wait_for_socket(self, socket, wait):
+ Namespace.non_block_wait(os.path.exists, wait, socket)
+
+ # Wait for both process termination and HUP signal
+ def __wait(self, timeout):
+ try:
+ super().wait(timeout)
+ if not self.hup:
+ return False
+
+ return True
+ except:
+ return False
+
+ # Override wait() so it can do so non-blocking
+ def wait(self, timeout=10):
+ Namespace.non_block_wait(self.__wait, timeout, 1)
+ # Override kill()
+ def kill(self, force=False):
if self.killed:
return
+ print("Killing process {}".format(self.args))
+
if force:
- self.pid.kill()
+ super().kill()
else:
- self.pid.terminate()
+ self.terminate()
try:
- self.pid.wait(timeout=15)
+ self.wait(timeout=15)
except:
dbg("Process %s did not complete in 15 seconds!" % self.name)
- self.pid.kill()
-
- if self.ctx and self in self.ctx.processes:
- self.ctx.processes.remove(self)
+ super().kill()
if self.cleanup:
self.cleanup()
- self.process_io(self.pid.stdout)
-
- self.ctx = None
- self.pid = None
self.write_fds = []
if self.io_watch:
@@ -320,8 +316,8 @@ class Process:
self.cleanup = None
self.killed = True
- def wait_for_socket(self, socket, wait):
- Namespace.non_block_wait(os.path.exists, wait, socket)
+ if self in self.ctx.processes:
+ self.ctx.processes.remove(self)
def __str__(self):
return str(self.args) + '\n'
@@ -333,10 +329,10 @@ class Interface:
self.config = config
def __del__(self):
- Process(['iw', 'dev', self.name, 'del'], True)
+ Process(['iw', 'dev', self.name, 'del']).wait()
def set_interface_state(self, state):
- Process(['ifconfig', self.name, state], True)
+ Process(['ifconfig', self.name, state]).wait()
class Radio:
def __init__(self, name):
@@ -360,7 +356,7 @@ class Radio:
self.use = use
Process(['iw', 'phy', self.name, 'interface', 'add', ifname,
- 'type', 'managed'], True)
+ 'type', 'managed']).wait()
return self.interface
@@ -463,8 +459,8 @@ class Hostapd:
print("Initializing hostapd instances")
- ctx.start_process(['ip', 'link', 'set', 'eth0', 'up'], wait=True)
- ctx.start_process(['ip', 'link', 'set', 'eth1', 'up'], wait=True)
+ ctx.start_process(['ip', 'link', 'set', 'eth0', 'up']).wait()
+ ctx.start_process(['ip', 'link', 'set', 'eth1', 'up']).wait()
self.global_ctrl_iface = '/var/run/hostapd/ctrl'
@@ -575,9 +571,9 @@ class Namespace:
self.radios = radios
self.args = args
- Process(['ip', 'netns', 'add', name], wait=True)
+ Process(['ip', 'netns', 'add', name]).wait()
for r in radios:
- Process(['iw', 'phy', r.name, 'set', 'netns', 'name', name], wait=True)
+ Process(['iw', 'phy', r.name, 'set', 'netns', 'name', name]).wait()
self.start_dbus()
@@ -590,7 +586,6 @@ class Namespace:
self.radios = []
for p in list(self.processes):
- print("Killing process %s" % p.name)
p.kill()
self.processes = []
@@ -598,7 +593,7 @@ class Namespace:
def __del__(self):
print("Removing namespace %s" % self.name)
- Process(['ip', 'netns', 'del', self.name], wait=True)
+ Process(['ip', 'netns', 'del', self.name]).wait()
def get_bus(self):
return self._bus
@@ -617,7 +612,7 @@ class Namespace:
# In case this process needs DBus...
env['DBUS_SYSTEM_BUS_ADDRESS'] = self.dbus_address
- p = Process(args, ctx=self, namespace=ns, env=env, **kwargs)
+ p = Process(args, namespace=ns, env=env, **kwargs)
if not kwargs.get('wait', False):
self.processes.append(p)
@@ -629,7 +624,7 @@ class Namespace:
def is_process_running(self, process):
for p in self.processes:
- if p.name == process:
+ if p.args[0] == process:
return True
return False
@@ -654,7 +649,7 @@ class Namespace:
f.write('</busconfig>\n')
p = self.start_process(['dbus-daemon', '--config-file=%s' % self.dbus_cfg],
- wait=False, cleanup=self._cleanup_dbus)
+ cleanup=self._cleanup_dbus)
p.wait_for_socket(self.dbus_address.split('=')[1], 5)
@@ -865,7 +860,7 @@ class TestContext(Namespace):
def start_radios(self):
reg_domain = self.hw_config['SETUP'].get('reg_domain', None)
if reg_domain:
- Process(['iw', 'reg', 'set', reg_domain], True)
+ Process(['iw', 'reg', 'set', reg_domain]).wait()
if self.args.hw:
self.discover_radios()
@@ -942,7 +937,7 @@ class TestContext(Namespace):
print("Ofono or Phonesim not found, skipping test")
return
- Process(['ifconfig', 'lo', 'up'], wait=True)
+ Process(['ifconfig', 'lo', 'up']).wait()
os.environ['OFONO_PHONESIM_CONFIG'] = '/tmp/phonesim.conf'
@@ -1327,7 +1322,7 @@ def post_test(ctx, to_copy):
else:
os.remove('/tmp/' + f)
- Process(['ifconfig', 'lo', 'down'], wait=True)
+ Process(['ifconfig', 'lo', 'down']).wait()
except Exception as e:
print("Exception thrown in post_test")
finally:
@@ -1451,7 +1446,8 @@ def run_unit_tests(ctx, args):
units = build_unit_list(args)
for u in units:
- if ctx.start_process([u], wait=True).ret != 0:
+ p = ctx.start_process([u]).wait()
+ if p.returncode != 0:
dbg("Unit test %s failed" % os.path.basename(u))
else:
dbg("Unit test %s passed" % os.path.basename(u))
--
2.31.1
8 months, 4 weeks
[PATCH 1/9] handshake: Add HANDSHAKE_EVENT_P2P_IP_REQUEST
by Andrew Zaborowski
Add a handshake event for use by the AP side for mechanisms that
allocate client IPs during the handshake: P2P address allocation and
FILS address assignment. This is emitted only when EAPOL or the
auth_proto is actually about to send the network configuration data to
the client so that ap.c can skip allocating a DHCP leases altogether if
the client doesn't send the required KDE or IE.
---
src/eapol.c | 17 +++++++++++++++++
src/handshake.h | 1 +
src/station.c | 1 +
3 files changed, 19 insertions(+)
diff --git a/src/eapol.c b/src/eapol.c
index f78bef2f..5a3ef7a0 100644
--- a/src/eapol.c
+++ b/src/eapol.c
@@ -1350,6 +1350,23 @@ static void eapol_send_ptk_3_of_4(struct eapol_sm *sm)
key_data_len += gtk_kde[1] + 2;
}
+ if (sm->handshake->support_ip_allocation &&
+ !sm->handshake->client_ip_addr) {
+ handshake_event(sm->handshake, HANDSHAKE_EVENT_P2P_IP_REQUEST);
+
+ /*
+ * If .support_ip_allocation was set, the
+ * HANDSHAKE_EVENT_P2P_IP_REQUEST handler is expected to set
+ * .client_ip_addr if not already set. Check if the handler
+ * was successful in allocating an address, if it wasn't we'll
+ * just skip the IP Address Allocation KDE. In either case if
+ * we need to resend message 3/4 the event callback won't be
+ * triggered again because the condition above will be false.
+ */
+ if (!sm->handshake->client_ip_addr)
+ sm->handshake->support_ip_allocation = false;
+ }
+
if (sm->handshake->support_ip_allocation) {
/* Wi-Fi P2P Technical Specification v1.7 Table 59 */
key_data_buf[key_data_len++] = IE_TYPE_VENDOR_SPECIFIC;
diff --git a/src/handshake.h b/src/handshake.h
index a4c54b5a..31dce117 100644
--- a/src/handshake.h
+++ b/src/handshake.h
@@ -57,6 +57,7 @@ enum handshake_event {
HANDSHAKE_EVENT_REKEY_FAILED,
HANDSHAKE_EVENT_EAP_NOTIFY,
HANDSHAKE_EVENT_TRANSITION_DISABLE,
+ HANDSHAKE_EVENT_P2P_IP_REQUEST,
};
typedef void (*handshake_event_func_t)(struct handshake_state *hs,
diff --git a/src/station.c b/src/station.c
index d3482e2c..d61e775a 100644
--- a/src/station.c
+++ b/src/station.c
@@ -753,6 +753,7 @@ static void station_handshake_event(struct handshake_state *hs,
case HANDSHAKE_EVENT_COMPLETE:
case HANDSHAKE_EVENT_SETTING_KEYS_FAILED:
case HANDSHAKE_EVENT_EAP_NOTIFY:
+ case HANDSHAKE_EVENT_P2P_IP_REQUEST:
/*
* currently we don't care about any other events. The
* netdev_connect_cb will notify us when the connection is
--
2.30.2
8 months, 4 weeks
[PATCH v3 1/5] ie: add is_ie_default_sae_group_oui
by James Prestwood
Start an OUI list of vendors who have buggy SAE group negotiation
---
src/ie.c | 26 ++++++++++++++++++++++++++
src/ie.h | 2 ++
2 files changed, 28 insertions(+)
v3
* Changed to a for loop
* Added length prefix to OUI match table
diff --git a/src/ie.c b/src/ie.c
index c03b16b4..6f487912 100644
--- a/src/ie.c
+++ b/src/ie.c
@@ -1364,6 +1364,32 @@ bool is_ie_wpa_ie(const uint8_t *data, uint8_t len)
return false;
}
+/*
+ * List of vendor OUIs (prefixed with a length byte) which require forcing
+ * the default SAE group.
+ */
+static const uint8_t use_default_sae_group_ouis[][5] = {
+ { 0x04, 0xf4, 0xf5, 0xe8, 0x05 },
+};
+
+bool is_ie_default_sae_group_oui(const uint8_t *data, uint16_t len)
+{
+ unsigned int i;
+ const uint8_t *oui;
+
+ for (i = 0; i < L_ARRAY_SIZE(use_default_sae_group_ouis); i++) {
+ oui = use_default_sae_group_ouis[i];
+
+ if (len < oui[0])
+ continue;
+
+ if (!memcmp(oui + 1, data, oui[0]))
+ return true;
+ }
+
+ return false;
+}
+
int ie_parse_wpa(struct ie_tlv_iter *iter, struct ie_rsn_info *out_info)
{
const uint8_t *data = iter->data;
diff --git a/src/ie.h b/src/ie.h
index 05afce39..8d4ab3c1 100644
--- a/src/ie.h
+++ b/src/ie.h
@@ -551,6 +551,8 @@ int ie_parse_wpa_from_data(const uint8_t *data, size_t len,
struct ie_rsn_info *info);
bool is_ie_wfa_ie(const uint8_t *data, uint8_t len, uint8_t oi_type);
bool is_ie_wpa_ie(const uint8_t *data, uint8_t len);
+bool is_ie_default_sae_group_oui(const uint8_t *data, uint16_t len);
+
bool ie_build_wpa(const struct ie_rsn_info *info, uint8_t *to);
int ie_parse_bss_load(struct ie_tlv_iter *iter, uint16_t *out_sta_count,
--
2.31.1
8 months, 4 weeks