All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/7] ip-pool: Track IPv4 addresses in use
@ 2021-05-25 12:55 Andrew Zaborowski
  2021-05-25 12:55 ` [PATCH 2/7] ip-pool: Add subnet address selection logic Andrew Zaborowski
                   ` (6 more replies)
  0 siblings, 7 replies; 20+ messages in thread
From: Andrew Zaborowski @ 2021-05-25 12:55 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 6544 bytes --]

Add the ip-pool submodule that tracks IPv4 addresses in use on the
system for use when selecting the address for a new AP.
---
 Makefile.am   |   1 +
 src/ip-pool.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/ip-pool.h |  32 ++++++++++
 3 files changed, 193 insertions(+)
 create mode 100644 src/ip-pool.c
 create mode 100644 src/ip-pool.h

diff --git a/Makefile.am b/Makefile.am
index 68035e46..083bc95a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -243,6 +243,7 @@ src_iwd_SOURCES = src/main.c linux/nl80211.h src/iwd.h src/missing.h \
 					src/eap-wsc.c src/eap-wsc.h \
 					src/wscutil.h src/wscutil.c \
 					src/diagnostic.h src/diagnostic.c \
+					src/ip-pool.h src/ip-pool.c \
 					$(eap_sources) \
 					$(builtin_sources)
 
diff --git a/src/ip-pool.c b/src/ip-pool.c
new file mode 100644
index 00000000..1166383c
--- /dev/null
+++ b/src/ip-pool.c
@@ -0,0 +1,160 @@
+/*
+ *
+ *  Wireless daemon for Linux
+ *
+ *  Copyright (C) 2021  Intel Corporation. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <ell/ell.h>
+
+#include "src/util.h"
+#include "src/iwd.h"
+#include "src/module.h"
+#include "src/netdev.h"
+#include "src/ip-pool.h"
+
+static struct l_queue *used_addr4_list;
+static struct l_netlink *rtnl;
+
+static bool ip_pool_addr4_match_ifindex(const void *a, const void *b)
+{
+	const struct ip_pool_addr4_record *addr = a;
+
+	return addr->ifindex == L_PTR_TO_UINT(b) && !addr->secondary;
+}
+
+const struct ip_pool_addr4_record *ip_pool_get_addr4(struct netdev *netdev)
+{
+	return l_queue_find(used_addr4_list, ip_pool_addr4_match_ifindex,
+				L_UINT_TO_PTR(netdev_get_ifindex(netdev)));
+}
+
+static bool ip_pool_addr4_match_free(void *data, void *user_data)
+{
+	const struct ip_pool_addr4_record *a = data;
+	const struct ip_pool_addr4_record *b = user_data;
+
+	if (a->ifindex != b->ifindex || a->addr != b->addr ||
+			a->prefix_len != b->prefix_len)
+		return false;
+
+	l_free(data);
+	return true;
+}
+
+static void ip_pool_addr_notify(uint16_t type, const void *data, uint32_t len,
+				void *user_data)
+{
+	const struct ifaddrmsg *ifa = data;
+	char *ip_str = NULL;
+	int r;
+	struct in_addr ip;
+
+	if (ifa->ifa_family != AF_INET || ifa->ifa_prefixlen < 1)
+		return;
+
+	len -= NLMSG_ALIGN(sizeof(struct ifaddrmsg));
+
+	l_rtnl_ifaddr4_extract(ifa, len, NULL, &ip_str, NULL);
+	if (!ip_str)
+		return;
+
+	r = inet_aton(ip_str, &ip);
+	l_free(ip_str);
+
+	if (r < 0)
+		return;
+
+	if (type == RTM_NEWADDR) {
+		struct ip_pool_addr4_record *addr;
+
+		addr = l_new(struct ip_pool_addr4_record, 1);
+		addr->addr = ntohl(ip.s_addr);
+		addr->prefix_len = ifa->ifa_prefixlen;
+		addr->ifindex = ifa->ifa_index;
+		addr->secondary = !!(ifa->ifa_flags & IFA_F_SECONDARY);
+		l_queue_push_tail(used_addr4_list, addr);
+	} else if (type == RTM_DELADDR) {
+		struct ip_pool_addr4_record addr;
+
+		addr.addr = ntohl(ip.s_addr);
+		addr.prefix_len = ifa->ifa_prefixlen;
+		addr.ifindex = ifa->ifa_index;
+
+		l_queue_foreach_remove(used_addr4_list,
+					ip_pool_addr4_match_free, &addr);
+	}
+}
+
+static void ip_pool_addr4_dump_cb(int error,
+					uint16_t type, const void *data,
+					uint32_t len, void *user_data)
+{
+	if (error) {
+		l_error("addr4_dump_cb: %s (%i)", strerror(-error), -error);
+		return;
+	}
+
+	ip_pool_addr_notify(type, data, len, user_data);
+}
+
+static int ip_pool_init(void)
+{
+	const struct l_settings *settings = iwd_get_config();
+	bool netconfig_enabled;
+
+	if (!l_settings_get_bool(settings, "General",
+				"EnableNetworkConfiguration",
+				&netconfig_enabled))
+		netconfig_enabled = false;
+
+	if (!netconfig_enabled)
+		return 0;
+
+	rtnl = iwd_get_rtnl();
+
+	if (!l_netlink_register(rtnl, RTNLGRP_IPV4_IFADDR,
+				ip_pool_addr_notify, NULL, NULL)) {
+		l_error("Failed to register for RTNL link notifications");
+		return -EIO;
+	}
+
+	if (!l_rtnl_ifaddr4_dump(rtnl, ip_pool_addr4_dump_cb, NULL, NULL)) {
+		l_error("Sending the IPv4 addr dump req failed");
+		return -EIO;
+	}
+
+	used_addr4_list = l_queue_new();
+	return 0;
+}
+
+static void ip_pool_exit(void)
+{
+	l_queue_destroy(used_addr4_list, l_free);
+	used_addr4_list = NULL;
+}
+
+IWD_MODULE(ip_pool, ip_pool_init, ip_pool_exit)
diff --git a/src/ip-pool.h b/src/ip-pool.h
new file mode 100644
index 00000000..6a220735
--- /dev/null
+++ b/src/ip-pool.h
@@ -0,0 +1,32 @@
+/*
+ *
+ *  Wireless daemon for Linux
+ *
+ *  Copyright (C) 2021  Intel Corporation. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+struct netdev;
+
+struct ip_pool_addr4_record {
+	uint32_t addr;
+	uint8_t prefix_len;
+	uint32_t ifindex;
+	bool secondary;
+};
+
+const struct ip_pool_addr4_record *ip_pool_get_addr4(struct netdev *netdev);
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread
* [PATCH 1/7] ap: Don't use L_AUTO_FREE_VAR with l_settings
@ 2021-02-26 16:17 Andrew Zaborowski
  2021-02-26 16:17 ` [PATCH 6/7] autotests: Update APRanges usage in testAP Andrew Zaborowski
  0 siblings, 1 reply; 20+ messages in thread
From: Andrew Zaborowski @ 2021-02-26 16:17 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 2145 bytes --]

L_AUTO_FREE_VAR only causes l_free to be called on the variable that is
freed and may leak the rest of the l_settings object's memory.
---
 src/ap.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/src/ap.c b/src/ap.c
index fd1a9a6b..f7b1cf9f 100644
--- a/src/ap.c
+++ b/src/ap.c
@@ -2544,8 +2544,8 @@ static int ap_load_profile_and_dhcp(struct ap_state *ap, bool *wait_dhcp)
 {
 	uint32_t ifindex = netdev_get_ifindex(ap->netdev);
 	char *passphrase;
-	L_AUTO_FREE_VAR(struct l_settings *, settings) = NULL;
-	int err;
+	struct l_settings *settings = NULL;
+	int err = -EINVAL;
 
 	/* No profile or DHCP settings */
 	if (!ap->config->profile && !pool.used)
@@ -2555,7 +2555,7 @@ static int ap_load_profile_and_dhcp(struct ap_state *ap, bool *wait_dhcp)
 		settings = l_settings_new();
 
 		if (!l_settings_load_from_file(settings, ap->config->profile))
-			return -EINVAL;
+			goto cleanup;
 
 		passphrase = l_settings_get_string(settings, "Security",
 							"Passphrase");
@@ -2564,7 +2564,7 @@ static int ap_load_profile_and_dhcp(struct ap_state *ap, bool *wait_dhcp)
 				l_error("[Security].Passphrase must not exceed "
 						"63 characters");
 				l_free(passphrase);
-				return -EINVAL;
+				goto cleanup;
 			}
 
 			strcpy(ap->config->passphrase, passphrase);
@@ -2573,7 +2573,8 @@ static int ap_load_profile_and_dhcp(struct ap_state *ap, bool *wait_dhcp)
 
 		if (!l_settings_has_group(settings, "IPv4")) {
 			*wait_dhcp = false;
-			return 0;
+			err = 0;
+			goto cleanup;
 		}
 	}
 
@@ -2587,21 +2588,22 @@ static int ap_load_profile_and_dhcp(struct ap_state *ap, bool *wait_dhcp)
 
 		if (!ap->rtnl_add_cmd) {
 			l_error("Failed to add IPv4 address");
-			return -EIO;
+			err = -EIO;
+			goto cleanup;
 		}
 
 		ap->cleanup_ip = true;
 
 		*wait_dhcp = true;
-
-		return 0;
+		err = 0;
 	/* Selected address already set, continue normally */
 	} else if (err == -EALREADY) {
 		*wait_dhcp = false;
-
-		return 0;
+		err = 0;
 	}
 
+cleanup:
+	l_settings_free(settings);
 	return err;
 }
 
-- 
2.27.0

^ permalink raw reply related	[flat|nested] 20+ messages in thread
* [PATCH 1/7] ap: Don't use L_AUTO_FREE_VAR with l_settings
@ 2021-02-25 21:27 Andrew Zaborowski
  2021-02-25 21:27 ` [PATCH 6/7] autotests: Update APRanges usage in testAP Andrew Zaborowski
  0 siblings, 1 reply; 20+ messages in thread
From: Andrew Zaborowski @ 2021-02-25 21:27 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 2145 bytes --]

L_AUTO_FREE_VAR only causes l_free to be called on the variable that is
freed and may leak the rest of the l_settings object's memory.
---
 src/ap.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/src/ap.c b/src/ap.c
index fd1a9a6b..f7b1cf9f 100644
--- a/src/ap.c
+++ b/src/ap.c
@@ -2544,8 +2544,8 @@ static int ap_load_profile_and_dhcp(struct ap_state *ap, bool *wait_dhcp)
 {
 	uint32_t ifindex = netdev_get_ifindex(ap->netdev);
 	char *passphrase;
-	L_AUTO_FREE_VAR(struct l_settings *, settings) = NULL;
-	int err;
+	struct l_settings *settings = NULL;
+	int err = -EINVAL;
 
 	/* No profile or DHCP settings */
 	if (!ap->config->profile && !pool.used)
@@ -2555,7 +2555,7 @@ static int ap_load_profile_and_dhcp(struct ap_state *ap, bool *wait_dhcp)
 		settings = l_settings_new();
 
 		if (!l_settings_load_from_file(settings, ap->config->profile))
-			return -EINVAL;
+			goto cleanup;
 
 		passphrase = l_settings_get_string(settings, "Security",
 							"Passphrase");
@@ -2564,7 +2564,7 @@ static int ap_load_profile_and_dhcp(struct ap_state *ap, bool *wait_dhcp)
 				l_error("[Security].Passphrase must not exceed "
 						"63 characters");
 				l_free(passphrase);
-				return -EINVAL;
+				goto cleanup;
 			}
 
 			strcpy(ap->config->passphrase, passphrase);
@@ -2573,7 +2573,8 @@ static int ap_load_profile_and_dhcp(struct ap_state *ap, bool *wait_dhcp)
 
 		if (!l_settings_has_group(settings, "IPv4")) {
 			*wait_dhcp = false;
-			return 0;
+			err = 0;
+			goto cleanup;
 		}
 	}
 
@@ -2587,21 +2588,22 @@ static int ap_load_profile_and_dhcp(struct ap_state *ap, bool *wait_dhcp)
 
 		if (!ap->rtnl_add_cmd) {
 			l_error("Failed to add IPv4 address");
-			return -EIO;
+			err = -EIO;
+			goto cleanup;
 		}
 
 		ap->cleanup_ip = true;
 
 		*wait_dhcp = true;
-
-		return 0;
+		err = 0;
 	/* Selected address already set, continue normally */
 	} else if (err == -EALREADY) {
 		*wait_dhcp = false;
-
-		return 0;
+		err = 0;
 	}
 
+cleanup:
+	l_settings_free(settings);
 	return err;
 }
 
-- 
2.27.0

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

end of thread, other threads:[~2021-05-26 23:33 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-25 12:55 [PATCH 1/7] ip-pool: Track IPv4 addresses in use Andrew Zaborowski
2021-05-25 12:55 ` [PATCH 2/7] ip-pool: Add subnet address selection logic Andrew Zaborowski
2021-05-26 19:56   ` Denis Kenzior
2021-05-26 20:06     ` Denis Kenzior
2021-05-26 21:50     ` Andrew Zaborowski
2021-05-25 12:55 ` [PATCH 3/7] ap: Refactor DHCP settings loading Andrew Zaborowski
2021-05-25 12:55 ` [PATCH 4/7] ap: Refactor global address pool loading Andrew Zaborowski
2021-05-25 12:55 ` [PATCH 5/7] ap: Send a specific error message on async AP start failure Andrew Zaborowski
2021-05-25 12:55 ` [PATCH 6/7] autotests: Update APRanges usage in testAP Andrew Zaborowski
2021-05-25 12:55 ` [PATCH 7/7] doc: Update AP settings in iwd.ap(5) and iwd.config(5) Andrew Zaborowski
2021-05-26 19:43 ` [PATCH 1/7] ip-pool: Track IPv4 addresses in use Denis Kenzior
2021-05-26 21:37   ` Andrew Zaborowski
2021-05-26 21:56     ` Denis Kenzior
2021-05-26 22:02       ` Denis Kenzior
2021-05-26 22:36       ` Andrew Zaborowski
2021-05-26 22:55         ` Denis Kenzior
2021-05-26 23:26           ` Andrew Zaborowski
2021-05-26 23:33             ` Denis Kenzior
  -- strict thread matches above, loose matches on Subject: below --
2021-02-26 16:17 [PATCH 1/7] ap: Don't use L_AUTO_FREE_VAR with l_settings Andrew Zaborowski
2021-02-26 16:17 ` [PATCH 6/7] autotests: Update APRanges usage in testAP Andrew Zaborowski
2021-02-25 21:27 [PATCH 1/7] ap: Don't use L_AUTO_FREE_VAR with l_settings Andrew Zaborowski
2021-02-25 21:27 ` [PATCH 6/7] autotests: Update APRanges usage in testAP Andrew Zaborowski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.