iwd.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/5] netconfig: Move loading settings to new method, refactor
@ 2021-08-27  3:02 Andrew Zaborowski
  2021-08-27  3:02 ` [PATCH 2/5] netconfig: FILS IP assigment API Andrew Zaborowski
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Andrew Zaborowski @ 2021-08-27  3:02 UTC (permalink / raw)
  To: iwd

[-- 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

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-08-27  3:02 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-27  3:02 [PATCH 1/5] netconfig: Move loading settings to new method, refactor Andrew Zaborowski
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

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).