From: Andrew Zaborowski <andrew.zaborowski@intel.com>
To: iwd@lists.01.org
Subject: [PATCH 1/5] netconfig: Move loading settings to new method, refactor
Date: Fri, 27 Aug 2021 05:02:03 +0200 [thread overview]
Message-ID: <20210827030207.353705-1-andrew.zaborowski@intel.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 13946 bytes --]
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
next reply other threads:[~2021-08-27 3:02 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-27 3:02 Andrew Zaborowski [this message]
2021-08-27 3:02 ` [PATCH 2/5] netconfig: FILS IP assigment API Andrew Zaborowski
2021-08-27 3:02 ` [PATCH 3/5] station, netdev: Enable FILS IP Address Assignment Andrew Zaborowski
2021-08-27 3:02 ` [PATCH 4/5] ie: Extract same-subnet check code to util.h Andrew Zaborowski
2021-08-27 3:02 ` [PATCH 5/5] netconfig: Apply MACs received in FILS IP Assigment Andrew Zaborowski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210827030207.353705-1-andrew.zaborowski@intel.com \
--to=andrew.zaborowski@intel.com \
--cc=iwd@lists.01.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).