summary refs log tree commit diff
path: root/src/rdisc
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2016-03-30 00:56:30 +0200
committerMichael Biebl <biebl@debian.org>2016-03-30 00:56:30 +0200
commitd9c99a29a0d3384c9c3d2adce430f5cb1134ab6a (patch)
treefa41baf72753961e71dd8d5bdbe2b89c9109e4f1 /src/rdisc
parentc2de0d98ba39e0a1a970d066fd19be786092f376 (diff)
Imported Upstream version 1.1.92 upstream/1.1.92
Diffstat (limited to 'src/rdisc')
-rw-r--r--src/rdisc/nm-lndp-rdisc.c30
-rw-r--r--src/rdisc/nm-lndp-rdisc.h3
-rw-r--r--src/rdisc/nm-rdisc.c107
-rw-r--r--src/rdisc/nm-rdisc.h10
-rw-r--r--src/rdisc/tests/test-rdisc-fake.c2
-rw-r--r--src/rdisc/tests/test-rdisc-linux.c3
6 files changed, 128 insertions, 27 deletions
diff --git a/src/rdisc/nm-lndp-rdisc.c b/src/rdisc/nm-lndp-rdisc.c
index 06863462..27fd2f83 100644
--- a/src/rdisc/nm-lndp-rdisc.c
+++ b/src/rdisc/nm-lndp-rdisc.c
@@ -31,6 +31,7 @@
 
 #include "NetworkManagerUtils.h"
 #include "nm-platform.h"
+#include "nmp-netns.h"
 
 #define _NMLOG_PREFIX_NAME                "rdisc-lndp"
 
@@ -273,9 +274,14 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
 static gboolean
 event_ready (GIOChannel *source, GIOCondition condition, NMRDisc *rdisc)
 {
+	nm_auto_pop_netns NMPNetns *netns = NULL;
 	NMLNDPRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc);
 
 	_LOGD ("processing libndp events");
+
+	if (!nm_rdisc_netns_push (rdisc, &netns))
+		return G_SOURCE_CONTINUE;
+
 	ndp_callall_eventfd_handler (priv->ndp);
 	return G_SOURCE_CONTINUE;
 }
@@ -298,40 +304,50 @@ start (NMRDisc *rdisc)
 /******************************************************************/
 
 static inline gint32
-ipv6_sysctl_get (const char *ifname, const char *property, gint32 defval)
+ipv6_sysctl_get (NMPlatform *platform, const char *ifname, const char *property, gint32 defval)
 {
-	return nm_platform_sysctl_get_int32 (NM_PLATFORM_GET, nm_utils_ip6_property_path (ifname, property), defval);
+	return nm_platform_sysctl_get_int32 (platform, nm_utils_ip6_property_path (ifname, property), defval);
 }
 
 NMRDisc *
-nm_lndp_rdisc_new (int ifindex,
+nm_lndp_rdisc_new (NMPlatform *platform,
+                   int ifindex,
                    const char *ifname,
                    const char *uuid,
                    NMSettingIP6ConfigAddrGenMode addr_gen_mode,
                    GError **error)
 {
+	nm_auto_pop_netns NMPNetns *netns = NULL;
 	NMRDisc *rdisc;
 	NMLNDPRDiscPrivate *priv;
 	int errsv;
 
+	g_return_val_if_fail (NM_IS_PLATFORM (platform), NULL);
 	g_return_val_if_fail (!error || !*error, NULL);
 
-	rdisc = g_object_new (NM_TYPE_LNDP_RDISC, NULL);
+	if (!nm_platform_netns_push (platform, &netns))
+		return NULL;
+
+	rdisc = g_object_new (NM_TYPE_LNDP_RDISC,
+	                      NM_RDISC_PLATFORM, platform,
+	                      NULL);
 
 	rdisc->ifindex = ifindex;
 	rdisc->ifname = g_strdup (ifname);
 	rdisc->uuid = g_strdup (uuid);
 	rdisc->addr_gen_mode = addr_gen_mode;
 
-	rdisc->max_addresses = ipv6_sysctl_get (ifname, "max_addresses",
+	rdisc->max_addresses = ipv6_sysctl_get (platform, ifname, "max_addresses",
 	                                        NM_RDISC_MAX_ADDRESSES_DEFAULT);
-	rdisc->rtr_solicitations = ipv6_sysctl_get (ifname, "router_solicitations",
+	rdisc->rtr_solicitations = ipv6_sysctl_get (platform, ifname, "router_solicitations",
 	                                            NM_RDISC_RTR_SOLICITATIONS_DEFAULT);
-	rdisc->rtr_solicitation_interval = ipv6_sysctl_get (ifname, "router_solicitation_interval",
+	rdisc->rtr_solicitation_interval = ipv6_sysctl_get (platform, ifname, "router_solicitation_interval",
 	                                                    NM_RDISC_RTR_SOLICITATION_INTERVAL_DEFAULT);
 
 	priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc);
+
 	errsv = ndp_open (&priv->ndp);
+
 	if (errsv != 0) {
 		errsv = errsv > 0 ? errsv : -errsv;
 		g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
diff --git a/src/rdisc/nm-lndp-rdisc.h b/src/rdisc/nm-lndp-rdisc.h
index e6706e3c..4c7c4743 100644
--- a/src/rdisc/nm-lndp-rdisc.h
+++ b/src/rdisc/nm-lndp-rdisc.h
@@ -44,7 +44,8 @@ typedef struct {
 
 GType nm_lndp_rdisc_get_type (void);
 
-NMRDisc *nm_lndp_rdisc_new (int ifindex,
+NMRDisc *nm_lndp_rdisc_new (NMPlatform *platform,
+                            int ifindex,
                             const char *ifname,
                             const char *uuid,
                             NMSettingIP6ConfigAddrGenMode addr_gen_mode,
diff --git a/src/rdisc/nm-rdisc.c b/src/rdisc/nm-rdisc.c
index 82aece30..689fe7f6 100644
--- a/src/rdisc/nm-rdisc.c
+++ b/src/rdisc/nm-rdisc.c
@@ -28,6 +28,8 @@
 #include "nm-rdisc-private.h"
 
 #include "nm-utils.h"
+#include "nm-platform.h"
+#include "nmp-netns.h"
 
 #include <nm-setting-ip6-config.h>
 
@@ -46,6 +48,10 @@ typedef struct {
 
 G_DEFINE_TYPE (NMRDisc, nm_rdisc, G_TYPE_OBJECT)
 
+NM_GOBJECT_PROPERTIES_DEFINE_BASE (
+	PROP_PLATFORM,
+);
+
 enum {
 	CONFIG_CHANGED,
 	RA_TIMEOUT,
@@ -56,6 +62,31 @@ static guint signals[LAST_SIGNAL] = { 0 };
 
 /******************************************************************/
 
+NMPNetns *
+nm_rdisc_netns_get (NMRDisc *self)
+{
+	g_return_val_if_fail (NM_IS_RDISC (self), NULL);
+
+	return self->_netns;
+}
+
+gboolean
+nm_rdisc_netns_push (NMRDisc *self, NMPNetns **netns)
+{
+	g_return_val_if_fail (NM_IS_RDISC (self), FALSE);
+
+	if (   self->_netns
+	    && !nmp_netns_push (self->_netns)) {
+		NM_SET_OUT (netns, NULL);
+		return FALSE;
+	}
+
+	NM_SET_OUT (netns, self->_netns);
+	return TRUE;
+}
+
+/******************************************************************/
+
 gboolean
 nm_rdisc_add_gateway (NMRDisc *rdisc, const NMRDiscGateway *new)
 {
@@ -317,10 +348,14 @@ nm_rdisc_set_iid (NMRDisc *rdisc, const NMUtilsIPv6IfaceId iid)
 static gboolean
 send_rs (NMRDisc *rdisc)
 {
+	nm_auto_pop_netns NMPNetns *netns = NULL;
 	NMRDiscClass *klass = NM_RDISC_GET_CLASS (rdisc);
 	NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc);
 	GError *error = NULL;
 
+	if (!nm_rdisc_netns_push (rdisc, &netns))
+		return G_SOURCE_REMOVE;
+
 	if (klass->send_rs (rdisc, &error)) {
 		_LOGD ("router solicitation sent");
 		priv->solicitations_left--;
@@ -383,6 +418,7 @@ rdisc_ra_timeout_cb (gpointer user_data)
 void
 nm_rdisc_start (NMRDisc *rdisc)
 {
+	nm_auto_pop_netns NMPNetns *netns = NULL;
 	NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc);
 	NMRDiscClass *klass = NM_RDISC_GET_CLASS (rdisc);
 	guint ra_wait_secs;
@@ -391,6 +427,9 @@ nm_rdisc_start (NMRDisc *rdisc)
 
 	_LOGD ("starting router discovery: %d", rdisc->ifindex);
 
+	if (!nm_rdisc_netns_push (rdisc, &netns))
+		return;
+
 	nm_clear_g_source (&priv->ra_timeout_id);
 	ra_wait_secs = CLAMP (rdisc->rtr_solicitations * rdisc->rtr_solicitation_interval, 30, 120);
 	priv->ra_timeout_id = g_timeout_add_seconds (ra_wait_secs, rdisc_ra_timeout_cb, rdisc);
@@ -669,6 +708,33 @@ dns_domain_free (gpointer data)
 }
 
 static void
+set_property (GObject *object, guint prop_id,
+              const GValue *value, GParamSpec *pspec)
+{
+	NMRDisc *self = NM_RDISC (object);
+
+	switch (prop_id) {
+	case PROP_PLATFORM:
+		/* construct-only */
+		self->_platform = g_value_get_object (value) ? : NM_PLATFORM_GET;
+		if (!self->_platform)
+			g_return_if_reached ();
+
+		g_object_ref (self->_platform);
+
+		self->_netns = nm_platform_netns_get (self->_platform);
+		if (self->_netns)
+			g_object_ref (self->_netns);
+
+		g_return_if_fail (!self->_netns || self->_netns == nmp_netns_get_current ());
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
 nm_rdisc_init (NMRDisc *rdisc)
 {
 	NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc);
@@ -715,6 +781,9 @@ finalize (GObject *object)
 	g_array_unref (rdisc->dns_servers);
 	g_array_unref (rdisc->dns_domains);
 
+	g_clear_object (&rdisc->_netns);
+	g_clear_object (&rdisc->_platform);
+
 	G_OBJECT_CLASS (nm_rdisc_parent_class)->finalize (object);
 }
 
@@ -725,23 +794,31 @@ nm_rdisc_class_init (NMRDiscClass *klass)
 
 	g_type_class_add_private (klass, sizeof (NMRDiscPrivate));
 
+	object_class->set_property = set_property;
 	object_class->dispose = dispose;
 	object_class->finalize = finalize;
 	klass->config_changed = config_changed;
 
-	signals[CONFIG_CHANGED] = g_signal_new (
-			NM_RDISC_CONFIG_CHANGED,
-			G_OBJECT_CLASS_TYPE (klass),
-			G_SIGNAL_RUN_FIRST,
-			G_STRUCT_OFFSET (NMRDiscClass, config_changed),
-			NULL, NULL, NULL,
-			G_TYPE_NONE, 1, G_TYPE_INT);
-
-	signals[RA_TIMEOUT] = g_signal_new (
-			NM_RDISC_RA_TIMEOUT,
-			G_OBJECT_CLASS_TYPE (klass),
-			G_SIGNAL_RUN_FIRST,
-			G_STRUCT_OFFSET (NMRDiscClass, ra_timeout),
-			NULL, NULL, NULL,
-			G_TYPE_NONE, 0);
+	obj_properties[PROP_PLATFORM] =
+	    g_param_spec_object (NM_RDISC_PLATFORM, "", "",
+	                         NM_TYPE_PLATFORM,
+	                         G_PARAM_WRITABLE |
+	                         G_PARAM_CONSTRUCT_ONLY |
+	                         G_PARAM_STATIC_STRINGS);
+	g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+
+	signals[CONFIG_CHANGED] =
+	    g_signal_new (NM_RDISC_CONFIG_CHANGED,
+	                  G_OBJECT_CLASS_TYPE (klass),
+	                  G_SIGNAL_RUN_FIRST,
+	                  G_STRUCT_OFFSET (NMRDiscClass, config_changed),
+	                  NULL, NULL, NULL,
+	                  G_TYPE_NONE, 1, G_TYPE_INT);
+	signals[RA_TIMEOUT] =
+	    g_signal_new (NM_RDISC_RA_TIMEOUT,
+	                  G_OBJECT_CLASS_TYPE (klass),
+	                  G_SIGNAL_RUN_FIRST,
+	                  G_STRUCT_OFFSET (NMRDiscClass, ra_timeout),
+	                  NULL, NULL, NULL,
+	                  G_TYPE_NONE, 0);
 }
diff --git a/src/rdisc/nm-rdisc.h b/src/rdisc/nm-rdisc.h
index 51e2602f..5b97bec5 100644
--- a/src/rdisc/nm-rdisc.h
+++ b/src/rdisc/nm-rdisc.h
@@ -21,11 +21,9 @@
 #ifndef __NETWORKMANAGER_RDISC_H__
 #define __NETWORKMANAGER_RDISC_H__
 
-
 #include <stdlib.h>
 #include <netinet/in.h>
 
-#include "nm-default.h"
 #include "nm-setting-ip6-config.h"
 #include "NetworkManagerUtils.h"
 
@@ -36,6 +34,7 @@
 #define NM_IS_RDISC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_RDISC))
 #define NM_RDISC_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_RDISC, NMRDiscClass))
 
+#define NM_RDISC_PLATFORM       "platform"
 #define NM_RDISC_CONFIG_CHANGED "config-changed"
 #define NM_RDISC_RA_TIMEOUT     "ra-timeout"
 
@@ -114,6 +113,9 @@ typedef enum {
 typedef struct {
 	GObject parent;
 
+	NMPlatform *_platform;
+	NMPNetns *_netns;
+
 	int ifindex;
 	char *ifname;
 	char *uuid;
@@ -149,4 +151,8 @@ gboolean nm_rdisc_set_iid (NMRDisc *rdisc, const NMUtilsIPv6IfaceId iid);
 void nm_rdisc_start (NMRDisc *rdisc);
 void nm_rdisc_dad_failed (NMRDisc *rdisc, struct in6_addr *address);
 
+NMPlatform *nm_rdisc_get_platform (NMRDisc *self);
+NMPNetns *nm_rdisc_netns_get (NMRDisc *self);
+gboolean nm_rdisc_netns_push (NMRDisc *self, NMPNetns **netns);
+
 #endif /* __NETWORKMANAGER_RDISC_H__ */
diff --git a/src/rdisc/tests/test-rdisc-fake.c b/src/rdisc/tests/test-rdisc-fake.c
index 00a98dca..1c514b90 100644
--- a/src/rdisc/tests/test-rdisc-fake.c
+++ b/src/rdisc/tests/test-rdisc-fake.c
@@ -431,7 +431,7 @@ main (int argc, char **argv)
 	nmtst_init_with_logging (&argc, &argv, NULL, "DEFAULT");
 
 	if (nmtst_test_quick ()) {
-		g_print ("Skipping test: don't run long running test %s (NMTST_DEBUG=slow)\n", str_if_set (g_get_prgname (), "test-rdisc-fake"));
+		g_print ("Skipping test: don't run long running test %s (NMTST_DEBUG=slow)\n", g_get_prgname () ?: "test-rdisc-fake");
 		return g_test_run ();
 	}
 
diff --git a/src/rdisc/tests/test-rdisc-linux.c b/src/rdisc/tests/test-rdisc-linux.c
index bbdb5fb8..e22eb1ad 100644
--- a/src/rdisc/tests/test-rdisc-linux.c
+++ b/src/rdisc/tests/test-rdisc-linux.c
@@ -61,7 +61,8 @@ main (int argc, char **argv)
 		return EXIT_FAILURE;
 	}
 
-	rdisc = nm_lndp_rdisc_new (ifindex,
+	rdisc = nm_lndp_rdisc_new (NM_PLATFORM_GET,
+	                           ifindex,
 	                           ifname,
 	                           "8ce666e8-d34d-4fb1-b858-f15a7al28086",
 	                           NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64,