about summary refs log tree commit diff
path: root/src/platform
diff options
context:
space:
mode:
Diffstat (limited to 'src/platform')
-rw-r--r--src/platform/nm-linux-platform.c9
-rw-r--r--src/platform/nmp-netns.c6
-rw-r--r--src/platform/tests/test-common.c37
-rw-r--r--src/platform/tests/test-link.c17
-rw-r--r--src/platform/tests/test-route.c44
5 files changed, 71 insertions, 42 deletions
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index fe270e88..e5961c7e 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -4437,10 +4437,13 @@ event_valid_msg (NMPlatform *platform, struct nl_msg *msg, gboolean handle_event
 			nm_auto_nmpobj const NMPObject *obj_replace = NULL;
 			gboolean resync_required = FALSE;
 			gboolean only_dirty = FALSE;
+			gboolean is_ipv6;
 
-			if (NM_FLAGS_HAS (obj->ip_route.r_rtm_flags, RTM_F_CLONED)) {
-				/* a cloned route might be a response for RTM_GETROUTE. Check, whether it is. */
-				nm_assert (!nmp_object_is_alive (obj));
+			/* IPv4 routes that are a response to RTM_GETROUTE must have
+			 * the cloned flag while IPv6 routes don't have to. */
+			is_ipv6 = NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_IP6_ROUTE;
+			if (is_ipv6 || NM_FLAGS_HAS (obj->ip_route.r_rtm_flags, RTM_F_CLONED)) {
+				nm_assert (is_ipv6 || !nmp_object_is_alive (obj));
 				priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
 				if (NM_FLAGS_HAS (priv->delayed_action.flags, DELAYED_ACTION_TYPE_WAIT_FOR_NL_RESPONSE)) {
 					guint i;
diff --git a/src/platform/nmp-netns.c b/src/platform/nmp-netns.c
index bc305f01..d8561aef 100644
--- a/src/platform/nmp-netns.c
+++ b/src/platform/nmp-netns.c
@@ -475,6 +475,7 @@ nmp_netns_new (void)
 	NMPNetns *self;
 	int errsv;
 	GError *error = NULL;
+	unsigned long mountflags = 0;
 
 	_stack_ensure_init ();
 
@@ -503,7 +504,10 @@ nmp_netns_new (void)
 		goto err_out;
 	}
 
-	if (mount ("sysfs", "/sys", "sysfs", 0, NULL) != 0) {
+	if (access ("/sys", W_OK) == -1)
+		mountflags = MS_RDONLY;
+
+	if (mount ("sysfs", "/sys", "sysfs", mountflags, NULL) != 0) {
 		errsv = errno;
 		_LOGE (NULL, "failed mount /sys: %s", g_strerror (errsv));
 		goto err_out;
diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c
index 9a12f8f9..d56e681e 100644
--- a/src/platform/tests/test-common.c
+++ b/src/platform/tests/test-common.c
@@ -1931,47 +1931,12 @@ main (int argc, char **argv)
 			g_error ("unshare(CLONE_NEWNET|CLONE_NEWNS) failed with %s (%d)", strerror (errsv), errsv);
 		}
 
-		/* Below we need a read-only /sys (to signal that we're in an environment
-		 * we don't have udev and writable /sys/devices so that we still are able
-		 * to test device classes that modify the device attributes (such as bridges).
-		 *
-		 * We use two sysfs instances to achieve this, binding the /device subtree
-		 * of the writeable one to the read-only one.
-		 *
-		 * We abuse a /sys/kernel/debug for our temporary writable sysfs mount,
-		 * just because it's guarranteed to exist and mounts are allowed there even
-		 * after the sysfs mount point hardening [linux 0cbee99269]. It's just in
-		 * our mount namespace, we release it quickly and don't need debugfs anyway...
-		 * An alrernative would be to create a temporary directory, but that seems
-		 * like an overkill. */
-
-		/* Make the mounts below /sys private to our namespace. Other mounts
-		 * wouldn't be permitted for good reasons. */
+		/* We need a read-only /sys so that the platform knows there's no udev. */
 		mount (NULL, "/sys", "sysfs", MS_SLAVE, NULL);
-
-		/* Mount the read-only sysfs. */
 		if (mount ("sys", "/sys", "sysfs", MS_RDONLY, NULL) != 0) {
 			errsv = errno;
 			g_error ("mount(\"/sys\") failed with %s (%d)", strerror (errsv), errsv);
 		}
-
-		/* Create the writable /sys/devices tree. */
-		if (mount ("sys", "/sys/kernel/debug", "sysfs", 0, NULL) != 0) {
-			errsv = errno;
-			g_error ("mount(\"/sys/devices/k\") failed with %s (%d)", strerror (errsv), errsv);
-		}
-
-		/* Bind mound the writable device tree to the read-only sysfs. */
-		if (mount ("/sys/kernel/debug/devices", "/sys/devices", "sysfs", MS_BIND, NULL) != 0) {
-			errsv = errno;
-			g_error ("mount(\"/sys\") failed with %s (%d)", strerror (errsv), errsv);
-		}
-
-		/* Release the temporary mount now that we bound the /devices subtree. */
-		if (umount ("/sys/kernel/debug") != 0) {
-			errsv = errno;
-			g_error ("umount(\"/sys/kernel/debug\") failed with  %s (%d)", strerror (errsv), errsv);
-		}
 	}
 
 	nmtstp_setup_platform ();
diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c
index d3a10bd6..ef78cc24 100644
--- a/src/platform/tests/test-link.c
+++ b/src/platform/tests/test-link.c
@@ -1949,6 +1949,17 @@ _test_netns_check_skip (void)
 	return FALSE;
 }
 
+static gboolean
+_check_sysctl_skip (void)
+{
+	if (access ("/proc/sys/net/ipv4/ip_forward", W_OK) == -1) {
+		g_test_skip ("Can not write sysctls");
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
 /*****************************************************************************/
 
 #define _sysctl_assert_eq(plat, path, value) \
@@ -1973,6 +1984,9 @@ test_netns_general (gpointer fixture, gconstpointer test_data)
 	if (_test_netns_check_skip ())
 		return;
 
+	if (_check_sysctl_skip ())
+		return;
+
 	platform_1 = nm_linux_platform_new (TRUE, TRUE);
 	platform_2 = _test_netns_create_platform ();
 
@@ -2168,6 +2182,9 @@ test_netns_push (gpointer fixture, gconstpointer test_data)
 	if (_test_netns_check_skip ())
 		return;
 
+	if (_check_sysctl_skip ())
+		return;
+
 	pl[0].platform = platform_0 = nm_linux_platform_new (TRUE, TRUE);
 	pl[1].platform = platform_1 = _test_netns_create_platform ();
 	pl[2].platform = platform_2 = _test_netns_create_platform ();
diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c
index fe97db07..13648f16 100644
--- a/src/platform/tests/test-route.c
+++ b/src/platform/tests/test-route.c
@@ -424,7 +424,7 @@ test_ip6_route (void)
 /*****************************************************************************/
 
 static void
-test_ip_route_get (void)
+test_ip4_route_get (void)
 {
 	int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
 	in_addr_t a;
@@ -586,6 +586,45 @@ test_ip4_route_options (gconstpointer test_data)
 }
 
 static void
+test_ip6_route_get (void)
+{
+	int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
+	const struct in6_addr *a;
+	NMPlatformError result;
+	nm_auto_nmpobj NMPObject *route = NULL;
+	const NMPlatformIP6Route *r;
+
+	nmtstp_run_command_check ("ip -6 route add fd01:abcd::/64 via fe80::99 dev %s", DEVICE_NAME);
+
+	NMTST_WAIT_ASSERT (100, {
+		nmtstp_wait_for_signal (NM_PLATFORM_GET, 10);
+		if (nmtstp_ip6_route_get (NM_PLATFORM_GET, ifindex, nmtst_inet6_from_string ("fd01:abcd::"), 64, 0, NULL, 0))
+			break;
+	});
+
+	a = nmtst_inet6_from_string ("fd01:abcd::42");
+	result = nm_platform_ip_route_get (NM_PLATFORM_GET,
+	                                   AF_INET6,
+	                                   a,
+	                                   nmtst_get_rand_int () % 2 ? 0 : ifindex,
+	                                   &route);
+
+	g_assert (result == NM_PLATFORM_ERROR_SUCCESS);
+	g_assert (NMP_OBJECT_GET_TYPE (route) == NMP_OBJECT_TYPE_IP6_ROUTE);
+	g_assert (!NMP_OBJECT_IS_STACKINIT (route));
+	g_assert (route->parent._ref_count == 1);
+	r = NMP_OBJECT_CAST_IP6_ROUTE (route);
+	g_assert (r->ifindex == ifindex);
+	nmtst_assert_ip6_address (&r->network, "fd01:abcd::42");
+	g_assert_cmpint (r->plen, ==, 128);
+	nmtst_assert_ip6_address (&r->gateway, "fe80::99");
+
+	nmtstp_run_command_check ("ip -6 route flush dev %s", DEVICE_NAME);
+
+	nmtstp_wait_for_signal (NM_PLATFORM_GET, 50);
+}
+
+static void
 test_ip6_route_options (gconstpointer test_data)
 {
 	const int TEST_IDX = GPOINTER_TO_INT (test_data);
@@ -860,7 +899,8 @@ _nmtstp_setup_tests (void)
 
 	if (nmtstp_is_root_test ()) {
 		add_test_func_data ("/route/ip/1", test_ip, GINT_TO_POINTER (1));
-		add_test_func ("/route/ip_route_get", test_ip_route_get);
+		add_test_func ("/route/ip4_route_get", test_ip4_route_get);
+		add_test_func ("/route/ip6_route_get", test_ip6_route_get);
 		add_test_func ("/route/ip4_zero_gateway", test_ip4_zero_gateway);
 	}
 }