summary refs log tree commit diff
path: root/src/dhcp-manager
diff options
context:
space:
mode:
Diffstat (limited to 'src/dhcp-manager')
-rw-r--r--src/dhcp-manager/Makefile.in1
-rw-r--r--src/dhcp-manager/nm-dhcp-systemd.c13
-rw-r--r--src/dhcp-manager/systemd-dhcp/nm-sd-adapt.c73
-rw-r--r--src/dhcp-manager/systemd-dhcp/nm-sd-adapt.h15
-rw-r--r--src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c10
-rw-r--r--src/dhcp-manager/systemd-dhcp/src/shared/macro.h9
-rw-r--r--src/dhcp-manager/tests/Makefile.am1
-rw-r--r--src/dhcp-manager/tests/Makefile.in2
8 files changed, 91 insertions, 33 deletions
diff --git a/src/dhcp-manager/Makefile.in b/src/dhcp-manager/Makefile.in
index 8c6e059c..6a2cad49 100644
--- a/src/dhcp-manager/Makefile.in
+++ b/src/dhcp-manager/Makefile.in
@@ -336,6 +336,7 @@ LOG_DRIVER = @LOG_DRIVER@
 LTLIBICONV = @LTLIBICONV@
 LTLIBINTL = @LTLIBINTL@
 LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
diff --git a/src/dhcp-manager/nm-dhcp-systemd.c b/src/dhcp-manager/nm-dhcp-systemd.c
index 2bd0d72f..571765f7 100644
--- a/src/dhcp-manager/nm-dhcp-systemd.c
+++ b/src/dhcp-manager/nm-dhcp-systemd.c
@@ -397,6 +397,7 @@ nm_dhcp_systemd_get_lease_ip_configs (const char *iface,
 		ip4_config = lease_to_ip4_config (lease, NULL, default_route_metric, FALSE, NULL);
 		if (ip4_config)
 			leases = g_slist_append (leases, ip4_config);
+		sd_dhcp_lease_unref (lease);
 	}
 
 	return leases;
@@ -532,6 +533,7 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last
 	struct in_addr last_addr = { 0 };
 	const char *hostname;
 	int r, i;
+	gboolean success = FALSE;
 
 	g_assert (priv->client4 == NULL);
 	g_assert (priv->client6 == NULL);
@@ -618,8 +620,6 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last
 		}
 	}
 
-	if (lease)
-		sd_dhcp_lease_unref (lease);
 
 	/* Add requested options */
 	for (i = 0; dhcp4_requests[i].name; i++) {
@@ -642,12 +642,13 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last
 		goto error;
 	}
 
-	return TRUE;
+	success = TRUE;
 
 error:
-	sd_dhcp_client_unref (priv->client4);
-	priv->client4 = NULL;
-	return FALSE;
+	sd_dhcp_lease_unref (lease);
+	if (!success)
+		priv->client4 = sd_dhcp_client_unref (priv->client4);
+	return success;
 }
 
 static void
diff --git a/src/dhcp-manager/systemd-dhcp/nm-sd-adapt.c b/src/dhcp-manager/systemd-dhcp/nm-sd-adapt.c
index a6d81727..3870342c 100644
--- a/src/dhcp-manager/systemd-dhcp/nm-sd-adapt.c
+++ b/src/dhcp-manager/systemd-dhcp/nm-sd-adapt.c
@@ -31,12 +31,28 @@ struct sd_event_source {
 	gpointer user_data;
 
 	GIOChannel *channel;
-	sd_event_io_handler_t io_cb;
 
-	uint64_t usec;
-	sd_event_time_handler_t time_cb;
+	union {
+		struct {
+			sd_event_io_handler_t cb;
+		} io;
+		struct {
+			sd_event_time_handler_t cb;
+			uint64_t usec;
+		} time;
+	};
 };
 
+static struct sd_event_source *
+source_new (void)
+{
+	struct sd_event_source *source;
+
+	source = g_slice_new0 (struct sd_event_source);
+	source->refcount = 1;
+	return source;
+}
+
 int
 sd_event_source_set_priority (sd_event_source *s, int64_t priority)
 {
@@ -62,7 +78,7 @@ sd_event_source_unref (sd_event_source *s)
 			 */
 			g_io_channel_unref (s->channel);
 		}
-		g_free (s);
+		g_slice_free (struct sd_event_source, s);
 	}
 	return NULL;
 }
@@ -81,6 +97,7 @@ static gboolean
 io_ready (GIOChannel *channel, GIOCondition condition, struct sd_event_source *source)
 {
 	int r, revents = 0;
+	gboolean result;
 
 	if (condition & G_IO_IN)
 		revents |= EPOLLIN;
@@ -93,13 +110,18 @@ io_ready (GIOChannel *channel, GIOCondition condition, struct sd_event_source *s
 	if (condition & G_IO_HUP)
 		revents |= EPOLLHUP;
 
-	r = source->io_cb (source, g_io_channel_unix_get_fd (channel), revents, source->user_data);
-	if (r < 0) {
+	source->refcount++;
+
+	r = source->io.cb (source, g_io_channel_unix_get_fd (channel), revents, source->user_data);
+	if (r < 0 || source->refcount <= 1) {
 		source->id = 0;
-		return G_SOURCE_REMOVE;
-	}
+		result = G_SOURCE_REMOVE;
+	} else
+		result = G_SOURCE_CONTINUE;
 
-	return G_SOURCE_CONTINUE;
+	sd_event_source_unref (source);
+
+	return result;
 }
 
 int
@@ -109,13 +131,16 @@ sd_event_add_io (sd_event *e, sd_event_source **s, int fd, uint32_t events, sd_e
 	GIOChannel *channel;
 	GIOCondition condition = 0;
 
+	/* systemd supports floating sd_event_source by omitting the @s argument.
+	 * We don't have such users and don't implement floating references. */
+	g_return_val_if_fail (s, -EINVAL);
+
 	channel = g_io_channel_unix_new (fd);
 	if (!channel)
 		return -EINVAL;
 
-	source = g_new0 (struct sd_event_source, 1);
-	source->refcount = 1;
-	source->io_cb = callback;
+	source = source_new ();
+	source->io.cb = callback;
 	source->user_data = userdata;
 	source->channel = channel;
 
@@ -141,15 +166,14 @@ sd_event_add_io (sd_event *e, sd_event_source **s, int fd, uint32_t events, sd_e
 static gboolean
 time_ready (struct sd_event_source *source)
 {
-	int r;
+	source->refcount++;
 
-	r = source->time_cb (source, source->usec, source->user_data);
-	if (r < 0) {
-		source->id = 0;
-		return G_SOURCE_REMOVE;
-	}
+	source->time.cb (source, source->time.usec, source->user_data);
+	source->id = 0;
+
+	sd_event_source_unref (source);
 
-	return G_SOURCE_CONTINUE;
+	return G_SOURCE_REMOVE;
 }
 
 int
@@ -158,11 +182,14 @@ sd_event_add_time(sd_event *e, sd_event_source **s, clockid_t clock, uint64_t us
 	struct sd_event_source *source;
 	uint64_t n = now (clock);
 
-	source = g_new0 (struct sd_event_source, 1);
-	source->refcount = 1;
-	source->time_cb = callback;
+	/* systemd supports floating sd_event_source by omitting the @s argument.
+	 * We don't have such users and don't implement floating references. */
+	g_return_val_if_fail (s, -EINVAL);
+
+	source = source_new ();
+	source->time.cb = callback;
 	source->user_data = userdata;
-	source->usec = usec;
+	source->time.usec = usec;
 
 	if (usec > 1000)
 		usec = n < usec - 1000 ? usec - n : 1000;
diff --git a/src/dhcp-manager/systemd-dhcp/nm-sd-adapt.h b/src/dhcp-manager/systemd-dhcp/nm-sd-adapt.h
index f8856a1b..5e91c307 100644
--- a/src/dhcp-manager/systemd-dhcp/nm-sd-adapt.h
+++ b/src/dhcp-manager/systemd-dhcp/nm-sd-adapt.h
@@ -35,6 +35,7 @@
 #endif
 #include <unistd.h>
 #include <sys/syscall.h>
+#include <time.h>
 
 #include "nm-logging.h"
 
@@ -43,6 +44,12 @@
 #define BPF_XOR 0xa0
 #endif
 
+#ifndef CLOCK_BOOTTIME
+#define CLOCK_BOOTTIME 7
+#endif
+
+/*****************************************************************************/
+
 static inline guint32
 _slog_level_to_nm (int slevel)
 {
@@ -75,18 +82,20 @@ G_STMT_START { \
 
 #define log_assert_failed(e, file, line, func) \
 G_STMT_START { \
-	nm_log_err (LOGD_DHCP, #file ":" #line "(" #func "): assertion failed: " # e); \
+	nm_log_err (LOGD_DHCP, "%s:%d (%s): assertion failed: %s", (""file), (line), (func), G_STRINGIFY (e)); \
 	g_assert (FALSE); \
 } G_STMT_END
 
 #define log_assert_failed_unreachable(t, file, line, func) \
 G_STMT_START { \
-	nm_log_err (LOGD_DHCP, #file ":" #line "(" #func "): assert unreachable: " # t); \
+	nm_log_err (LOGD_DHCP, "%s:%d (%s): assert unreachable: %s", (""file), (line), (func), G_STRINGIFY (t)); \
 	g_assert_not_reached (); \
 } G_STMT_END
 
 #define log_assert_failed_return(e, file, line, func) \
-	nm_log_err (LOGD_DHCP, #file ":" #line "(" #func "): assert return: " # e); \
+G_STMT_START { \
+	nm_log_err (LOGD_DHCP, "%s:%d (%s): assert return: %s", (""file), (line), (func), G_STRINGIFY (e)); \
+} G_STMT_END
 
 #define log_oom nm_log_err(LOGD_CORE, "%s:%s/%s: OOM", __FILE__, __LINE__, __func__)
 
diff --git a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c
index 6c5a6ab5..6754fe19 100644
--- a/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/dhcp-manager/systemd-dhcp/src/libsystemd-network/sd-dhcp6-client.c
@@ -285,6 +285,11 @@ static void client_notify(sd_dhcp6_client *client, int event) {
 static int client_reset(sd_dhcp6_client *client) {
         assert_return(client, -EINVAL);
 
+	if (client->lease) {
+		dhcp6_lease_clear_timers(&client->lease->ia);
+		client->lease = sd_dhcp6_lease_unref(client->lease);
+	}
+
         client->receive_message =
                 sd_event_source_unref(client->receive_message);
 
@@ -828,7 +833,10 @@ static int client_receive_advertise(sd_dhcp6_client *client,
 
         r = dhcp6_lease_get_preference(client->lease, &pref_lease);
         if (!client->lease || r < 0 || pref_advertise > pref_lease) {
-                sd_dhcp6_lease_unref(client->lease);
+                if (client->lease) {
+                        dhcp6_lease_clear_timers(&client->lease->ia);
+                        sd_dhcp6_lease_unref(client->lease);
+                }
                 client->lease = lease;
                 lease = NULL;
                 r = 0;
diff --git a/src/dhcp-manager/systemd-dhcp/src/shared/macro.h b/src/dhcp-manager/systemd-dhcp/src/shared/macro.h
index e6cf6eec..bdda4dce 100644
--- a/src/dhcp-manager/systemd-dhcp/src/shared/macro.h
+++ b/src/dhcp-manager/systemd-dhcp/src/shared/macro.h
@@ -46,6 +46,7 @@
 #define _alignas_(x) __attribute__((aligned(__alignof(x))))
 #define _cleanup_(x) __attribute__((cleanup(x)))
 
+#if (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))) || defined (__clang__)
 /* Temporarily disable some warnings */
 #define DISABLE_WARNING_DECLARATION_AFTER_STATEMENT                     \
         _Pragma("GCC diagnostic push");                                 \
@@ -69,6 +70,14 @@
 
 #define REENABLE_WARNING                                                \
         _Pragma("GCC diagnostic pop")
+#else
+#define DISABLE_WARNING_DECLARATION_AFTER_STATEMENT
+#define DISABLE_WARNING_FORMAT_NONLITERAL
+#define DISABLE_WARNING_MISSING_PROTOTYPES
+#define DISABLE_WARNING_NONNULL
+#define DISABLE_WARNING_SHADOW
+#define REENABLE_WARNING
+#endif
 
 /* automake test harness */
 #define EXIT_TEST_SKIP 77
diff --git a/src/dhcp-manager/tests/Makefile.am b/src/dhcp-manager/tests/Makefile.am
index 8aa79a29..4c4c7e81 100644
--- a/src/dhcp-manager/tests/Makefile.am
+++ b/src/dhcp-manager/tests/Makefile.am
@@ -1,5 +1,6 @@
 AM_CPPFLAGS = \
 	-I$(top_srcdir)/include \
+	-I${top_builddir}/include \
 	-I${top_srcdir}/libnm-core \
 	-I${top_builddir}/libnm-core \
 	-I$(top_srcdir)/src/dhcp-manager \
diff --git a/src/dhcp-manager/tests/Makefile.in b/src/dhcp-manager/tests/Makefile.in
index 6125aea8..c98dbd5f 100644
--- a/src/dhcp-manager/tests/Makefile.in
+++ b/src/dhcp-manager/tests/Makefile.in
@@ -516,6 +516,7 @@ LOG_DRIVER = @LOG_DRIVER@
 LTLIBICONV = @LTLIBICONV@
 LTLIBINTL = @LTLIBINTL@
 LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
@@ -658,6 +659,7 @@ with_resolvconf = @with_resolvconf@
 with_valgrind = @with_valgrind@
 AM_CPPFLAGS = \
 	-I$(top_srcdir)/include \
+	-I${top_builddir}/include \
 	-I${top_srcdir}/libnm-core \
 	-I${top_builddir}/libnm-core \
 	-I$(top_srcdir)/src/dhcp-manager \