summary refs log tree commit diff
path: root/src/platform/tests
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2018-04-23 18:00:21 +0200
committerMichael Biebl <biebl@debian.org>2018-04-23 18:00:21 +0200
commitf60117b41d5433be1b4a96d82cd11d0c3dce9b63 (patch)
tree2dd55c4ab0fdcbe9cddb26adb4a554b1a45c73c8 /src/platform/tests
parent7e9ff09fcb2366b383b7ebbec80d2f6fff117290 (diff)
New upstream version 1.11.3 upstream/1.11.3
Diffstat (limited to 'src/platform/tests')
-rw-r--r--src/platform/tests/meson.build37
-rw-r--r--src/platform/tests/monitor.c3
-rw-r--r--src/platform/tests/test-address.c5
-rw-r--r--src/platform/tests/test-cleanup.c3
-rw-r--r--src/platform/tests/test-common.c116
-rw-r--r--src/platform/tests/test-common.h30
-rw-r--r--src/platform/tests/test-link.c135
-rw-r--r--src/platform/tests/test-nmp-object.c27
-rw-r--r--src/platform/tests/test-route.c3
9 files changed, 287 insertions, 72 deletions
diff --git a/src/platform/tests/meson.build b/src/platform/tests/meson.build
new file mode 100644
index 00000000..0571efac
--- /dev/null
+++ b/src/platform/tests/meson.build
@@ -0,0 +1,37 @@
+test_units = [
+  ['test-link-fake', 'test-link.c', 60],
+  ['test-link-linux', 'test-link.c', 60],
+  ['test-address-fake', 'test-address.c'],
+  ['test-address-linux', 'test-address.c'],
+  ['test-general', 'test-general.c'],
+  ['test-nmp-object', 'test-nmp-object.c'],
+  ['test-route-fake', 'test-route.c'],
+  ['test-route-linux', 'test-route.c'],
+  ['test-cleanup-fake', 'test-cleanup.c'],
+  ['test-cleanup-linux', 'test-cleanup.c'],
+]
+
+foreach test_unit: test_units
+  exe = executable(
+    'platform-' + test_unit[0],
+    test_unit[1],
+    dependencies: test_nm_dep,
+    c_args: test_cflags_platform
+  )
+
+  test(
+    'platform/' + test_unit[0],
+    test_script,
+    timeout: test_unit.length() > 2 ? test_unit[2] : 30,
+    args: test_args + [exe.full_path()]
+  )
+endforeach
+
+test = 'monitor'
+
+executable(
+  test,
+  test + '.c',
+  dependencies: test_nm_dep,
+  c_args: test_cflags_platform
+)
diff --git a/src/platform/tests/monitor.c b/src/platform/tests/monitor.c
index e1220052..f0e3e6cf 100644
--- a/src/platform/tests/monitor.c
+++ b/src/platform/tests/monitor.c
@@ -1,6 +1,5 @@
 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager audit support
- *
+/*
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
diff --git a/src/platform/tests/test-address.c b/src/platform/tests/test-address.c
index 93851ff7..ddef8853 100644
--- a/src/platform/tests/test-address.c
+++ b/src/platform/tests/test-address.c
@@ -1,6 +1,5 @@
 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager audit support
- *
+/*
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -149,7 +148,7 @@ test_ip6_address_general (void)
 
 	/* Add address again (aka update) */
 	nmtstp_ip6_address_add (NULL, EX, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, flags);
-	accept_signals (address_changed, 0, 1);
+	accept_signals (address_changed, 0, 2);
 
 	/* Test address listing */
 	addresses = nmtstp_platform_ip6_address_get_all (NM_PLATFORM_GET, ifindex);
diff --git a/src/platform/tests/test-cleanup.c b/src/platform/tests/test-cleanup.c
index 937cd12c..a213b31f 100644
--- a/src/platform/tests/test-cleanup.c
+++ b/src/platform/tests/test-cleanup.c
@@ -1,6 +1,5 @@
 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager audit support
- *
+/*
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c
index d56e681e..7885c083 100644
--- a/src/platform/tests/test-common.c
+++ b/src/platform/tests/test-common.c
@@ -1,6 +1,5 @@
 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager audit support
- *
+/*
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -24,6 +23,7 @@
 #include <sched.h>
 #include <sys/wait.h>
 #include <fcntl.h>
+#include <linux/if_tun.h>
 
 #include "test-common.h"
 
@@ -628,7 +628,10 @@ nmtstp_wait_for_signal_until (NMPlatform *platform, gint64 until_ms)
 const NMPlatformLink *
 nmtstp_wait_for_link (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, gint64 timeout_ms)
 {
-	return nmtstp_wait_for_link_until (platform, ifname, expected_link_type, nm_utils_get_monotonic_timestamp_ms () + timeout_ms);
+	return nmtstp_wait_for_link_until (platform, ifname, expected_link_type,
+	                                   timeout_ms
+	                                     ? nm_utils_get_monotonic_timestamp_ms () + timeout_ms
+	                                     : 0);
 }
 
 const NMPlatformLink *
@@ -636,6 +639,7 @@ nmtstp_wait_for_link_until (NMPlatform *platform, const char *ifname, NMLinkType
 {
 	const NMPlatformLink *plink;
 	gint64 now;
+	gboolean waited_once = FALSE;
 
 	_init_platform (&platform, FALSE);
 
@@ -647,29 +651,24 @@ nmtstp_wait_for_link_until (NMPlatform *platform, const char *ifname, NMLinkType
 		    && (expected_link_type == NM_LINK_TYPE_NONE || plink->type == expected_link_type))
 			return plink;
 
-		if (until_ms < now)
+		if (until_ms == 0) {
+			/* don't wait, don't even poll the socket. */
+			return NULL;
+		}
+
+		if (   waited_once
+		    && until_ms < now) {
+			/* timeout reached (+ we already waited for a signal at least once). */
 			return NULL;
+		}
 
+		waited_once = TRUE;
+		/* regardless of whether timeout is already reached, we poll the netlink
+		 * socket a bit. */
 		nmtstp_wait_for_signal (platform, until_ms - now);
 	}
 }
 
-const NMPlatformLink *
-nmtstp_assert_wait_for_link (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, guint timeout_ms)
-{
-	return nmtstp_assert_wait_for_link_until (platform, ifname, expected_link_type, nm_utils_get_monotonic_timestamp_ms () + timeout_ms);
-}
-
-const NMPlatformLink *
-nmtstp_assert_wait_for_link_until (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, gint64 until_ms)
-{
-	const NMPlatformLink *plink;
-
-	plink = nmtstp_wait_for_link_until (platform, ifname, expected_link_type, until_ms);
-	g_assert (plink);
-	return plink;
-}
-
 /*****************************************************************************/
 
 int
@@ -1284,6 +1283,10 @@ nmtstp_link_ip6tnl_add (NMPlatform *platform,
 	const NMPlatformLink *pllink = NULL;
 	gboolean success;
 	char buffer[INET6_ADDRSTRLEN];
+	char encap[20];
+	char tclass[20];
+	gboolean encap_ignore;
+	gboolean tclass_inherit;
 
 	g_assert (nm_utils_is_valid_iface_name (name, NULL));
 
@@ -1309,15 +1312,18 @@ nmtstp_link_ip6tnl_add (NMPlatform *platform,
 			g_assert_not_reached ();
 		}
 
-		success = !nmtstp_run_command ("ip -6 tunnel add %s mode %s %s local %s remote %s ttl %u tclass %02x encaplimit %u flowlabel %x",
+		encap_ignore = NM_FLAGS_HAS (lnk->flags, IP6_TNL_F_IGN_ENCAP_LIMIT);
+		tclass_inherit = NM_FLAGS_HAS (lnk->flags, IP6_TNL_F_USE_ORIG_TCLASS);
+
+		success = !nmtstp_run_command ("ip -6 tunnel add %s mode %s %s local %s remote %s ttl %u tclass %s encaplimit %s flowlabel %x",
 		                                name,
 		                                mode,
 		                                dev,
 		                                nm_utils_inet6_ntop (&lnk->local, NULL),
 		                                nm_utils_inet6_ntop (&lnk->remote, buffer),
 		                                lnk->ttl,
-		                                lnk->tclass,
-		                                lnk->encap_limit,
+		                                tclass_inherit ? "inherit" : nm_sprintf_buf (tclass, "%02x", lnk->tclass),
+		                                encap_ignore ? "none" : nm_sprintf_buf (encap, "%u", lnk->encap_limit),
 		                                lnk->flow_label);
 		if (success)
 			pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_IP6TNL, 100);
@@ -1463,6 +1469,70 @@ nmtstp_link_sit_add (NMPlatform *platform,
 }
 
 const NMPlatformLink *
+nmtstp_link_tun_add (NMPlatform *platform,
+                     gboolean external_command,
+                     const char *name,
+                     const NMPlatformLnkTun *lnk,
+                     int *out_fd)
+{
+	const NMPlatformLink *pllink = NULL;
+	NMPlatformError plerr;
+	int err;
+
+	g_assert (nm_utils_is_valid_iface_name (name, NULL));
+	g_assert (lnk);
+	g_assert (NM_IN_SET (lnk->type, IFF_TUN, IFF_TAP));
+	g_assert (!out_fd || *out_fd == -1);
+
+	if (!lnk->persist) {
+		/* ip tuntap does not support non-persistent devices.
+		 *
+		 * Add this device only via NMPlatform. */
+		if (external_command == -1)
+			external_command = FALSE;
+	}
+
+	external_command = nmtstp_run_command_check_external (external_command);
+
+	_init_platform (&platform, external_command);
+
+	if (external_command) {
+		g_assert (lnk->persist);
+
+		err = nmtstp_run_command ("ip tuntap add"
+		                          " mode %s"
+		                          "%s" /* user */
+		                          "%s" /* group */
+		                          "%s" /* pi */
+		                          "%s" /* vnet_hdr */
+		                          "%s" /* multi_queue */
+		                          " name %s",
+		                          lnk->type == IFF_TUN ? "tun" : "tap",
+		                          lnk->owner_valid ? nm_sprintf_bufa (100, " user %u", (guint) lnk->owner) : "",
+		                          lnk->group_valid ? nm_sprintf_bufa (100, " group %u", (guint) lnk->group) : "",
+		                          lnk->pi ? " pi" : "",
+		                          lnk->vnet_hdr ? " vnet_hdr" : "",
+		                          lnk->multi_queue ? " multi_queue" : "",
+		                          name);
+		/* Older versions of iproute2 don't support adding  devices.
+		 * On failure, fallback to using platform code. */
+		if (err == 0)
+			pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_TUN, 100);
+		else
+			g_error ("failure to add tun/tap device via ip-route");
+	} else {
+		g_assert (lnk->persist || out_fd);
+		plerr = nm_platform_link_tun_add (platform, name, lnk, &pllink, out_fd);
+		g_assert_cmpint (plerr, ==, NM_PLATFORM_ERROR_SUCCESS);
+	}
+
+	g_assert (pllink);
+	g_assert_cmpint (pllink->type, ==, NM_LINK_TYPE_TUN);
+	g_assert_cmpstr (pllink->name, ==, name);
+	return pllink;
+}
+
+const NMPlatformLink *
 nmtstp_link_vxlan_add (NMPlatform *platform,
                        gboolean external_command,
                        const char *name,
diff --git a/src/platform/tests/test-common.h b/src/platform/tests/test-common.h
index fb406a3f..bd02b0d7 100644
--- a/src/platform/tests/test-common.h
+++ b/src/platform/tests/test-common.h
@@ -1,3 +1,21 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright 2016 - 2017 Red Hat, Inc.
+ */
+
 #include <stdlib.h>
 #include <unistd.h>
 #include <syslog.h>
@@ -111,8 +129,11 @@ const NMPlatformLink *nmtstp_wait_for_link_until (NMPlatform *platform, const ch
 			g_assert_not_reached (); \
 	} G_STMT_END
 
-const NMPlatformLink *nmtstp_assert_wait_for_link (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, guint timeout_ms);
-const NMPlatformLink *nmtstp_assert_wait_for_link_until (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, gint64 until_ms);
+#define nmtstp_assert_wait_for_link(platform, ifname, expected_link_type, timeout_ms) \
+	nmtst_assert_nonnull (nmtstp_wait_for_link (platform, ifname, expected_link_type, timeout_ms))
+
+#define nmtstp_assert_wait_for_link_until(platform, ifname, expected_link_type, until_ms) \
+	nmtst_assert_nonnull (nmtstp_wait_for_link_until (platform, ifname, expected_link_type, until_ms))
 
 /*****************************************************************************/
 
@@ -289,6 +310,11 @@ const NMPlatformLink *nmtstp_link_sit_add (NMPlatform *platform,
                                            gboolean external_command,
                                            const char *name,
                                            const NMPlatformLnkSit *lnk);
+const NMPlatformLink *nmtstp_link_tun_add (NMPlatform *platform,
+                                           gboolean external_command,
+                                           const char *name,
+                                           const NMPlatformLnkTun *lnk,
+                                           int *out_fd);
 const NMPlatformLink *nmtstp_link_vxlan_add (NMPlatform *platform,
                                              gboolean external_command,
                                              const char *name,
diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c
index ef78cc24..dcd600ee 100644
--- a/src/platform/tests/test-link.c
+++ b/src/platform/tests/test-link.c
@@ -1,6 +1,5 @@
 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager audit support
- *
+/*
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -24,6 +23,7 @@
 #include <sys/mount.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <linux/if_tun.h>
 
 #include "platform/nmp-object.h"
 #include "platform/nmp-netns.h"
@@ -698,6 +698,8 @@ test_software_detect (gconstpointer user_data)
 	const NMPObject *lnk;
 	guint i_step;
 	const gboolean ext = test_data->external_command;
+	NMPlatformLnkTun lnk_tun;
+	nm_auto_close int tun_fd = -1;
 
 	nmtstp_run_command_check ("ip link add %s type dummy", PARENT_NAME);
 	ifindex_parent = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, PARENT_NAME, NM_LINK_TYPE_DUMMY, 100)->ifindex;
@@ -761,13 +763,27 @@ test_software_detect (gconstpointer user_data)
 			gracefully_skip = nm_utils_modprobe (NULL, TRUE, "ip6_tunnel", NULL) != 0;
 		}
 
-		lnk_ip6tnl.local = *nmtst_inet6_from_string ("fd01::15");
-		lnk_ip6tnl.remote = *nmtst_inet6_from_string ("fd01::16");
-		lnk_ip6tnl.parent_ifindex = ifindex_parent;
-		lnk_ip6tnl.tclass = 20;
-		lnk_ip6tnl.encap_limit = 6;
-		lnk_ip6tnl.flow_label = 1337;
-		lnk_ip6tnl.proto = IPPROTO_IPV6;
+		switch (test_data->test_mode) {
+		case 0:
+			lnk_ip6tnl.local = *nmtst_inet6_from_string ("fd01::15");
+			lnk_ip6tnl.remote = *nmtst_inet6_from_string ("fd01::16");
+			lnk_ip6tnl.parent_ifindex = ifindex_parent;
+			lnk_ip6tnl.tclass = 20;
+			lnk_ip6tnl.encap_limit = 6;
+			lnk_ip6tnl.flow_label = 1337;
+			lnk_ip6tnl.proto = IPPROTO_IPV6;
+			break;
+		case 1:
+			lnk_ip6tnl.local = *nmtst_inet6_from_string ("fd01::17");
+			lnk_ip6tnl.remote = *nmtst_inet6_from_string ("fd01::18");
+			lnk_ip6tnl.parent_ifindex = ifindex_parent;
+			lnk_ip6tnl.tclass = 0;
+			lnk_ip6tnl.encap_limit = 0;
+			lnk_ip6tnl.flow_label = 1338;
+			lnk_ip6tnl.proto = IPPROTO_IPV6;
+			lnk_ip6tnl.flags = IP6_TNL_F_IGN_ENCAP_LIMIT | IP6_TNL_F_USE_ORIG_TCLASS;
+			break;
+		}
 
 		if (!nmtstp_link_ip6tnl_add (NULL, ext, DEVICE_NAME, &lnk_ip6tnl)) {
 			if (gracefully_skip) {
@@ -879,6 +895,38 @@ test_software_detect (gconstpointer user_data)
 		g_assert (nmtstp_link_vxlan_add (NULL, ext, DEVICE_NAME, &lnk_vxlan));
 		break;
 	}
+	case NM_LINK_TYPE_TUN: {
+		gboolean owner_valid = nmtst_get_rand_bool ();
+		gboolean group_valid = nmtst_get_rand_bool ();
+
+		switch (test_data->test_mode) {
+		case 0:
+			lnk_tun = (NMPlatformLnkTun) {
+				.type = nmtst_get_rand_bool () ? IFF_TUN : IFF_TAP,
+				.owner = owner_valid ? getuid () : 0,
+				.owner_valid = owner_valid,
+				.group = group_valid ? getgid () : 0,
+				.group_valid = group_valid,
+				.pi = nmtst_get_rand_bool (),
+				.vnet_hdr = nmtst_get_rand_bool (),
+				.multi_queue = nmtst_get_rand_bool (),
+
+				/* if we add the device via iproute2 (external), we can only
+				 * create persistent devices. */
+				.persist = (ext == 1) ? TRUE : nmtst_get_rand_bool (),
+			};
+			break;
+		default:
+			g_assert_not_reached ();
+			break;
+		}
+
+		g_assert (nmtstp_link_tun_add (NULL, ext, DEVICE_NAME, &lnk_tun,
+		                               (!lnk_tun.persist || nmtst_get_rand_bool ())
+		                                 ? &tun_fd
+		                                 : NULL));
+		break;
+	}
 	default:
 		g_assert_not_reached ();
 	}
@@ -909,7 +957,13 @@ test_software_detect (gconstpointer user_data)
 		lnk = nm_platform_link_get_lnk (NM_PLATFORM_GET, ifindex, test_data->link_type, &plink);
 		g_assert (plink);
 		g_assert_cmpint (plink->ifindex, ==, ifindex);
-		g_assert (lnk);
+
+		if (   !lnk
+		    && test_data->link_type == NM_LINK_TYPE_TUN) {
+			/* this is ok. Kernel apparently does not support tun properties via netlink. We
+			 * fetch them from sysfs below. */
+		} else
+			g_assert (lnk);
 
 		switch (test_data->link_type) {
 		case NM_LINK_TYPE_GRE: {
@@ -931,15 +985,31 @@ test_software_detect (gconstpointer user_data)
 		case NM_LINK_TYPE_IP6TNL: {
 			const NMPlatformLnkIp6Tnl *plnk = &lnk->lnk_ip6tnl;
 
-			g_assert (plnk == nm_platform_link_get_lnk_ip6tnl (NM_PLATFORM_GET, ifindex, NULL));
-			g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent);
-			nmtst_assert_ip6_address (&plnk->local, "fd01::15");
-			nmtst_assert_ip6_address (&plnk->remote, "fd01::16");
-			g_assert_cmpint (plnk->ttl, ==, 0);
-			g_assert_cmpint (plnk->tclass, ==, 20);
-			g_assert_cmpint (plnk->encap_limit, ==, 6);
-			g_assert_cmpint (plnk->flow_label, ==, 1337);
-			g_assert_cmpint (plnk->proto, ==, IPPROTO_IPV6);
+			switch (test_data->test_mode) {
+			case 0:
+				g_assert (plnk == nm_platform_link_get_lnk_ip6tnl (NM_PLATFORM_GET, ifindex, NULL));
+				g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent);
+				nmtst_assert_ip6_address (&plnk->local, "fd01::15");
+				nmtst_assert_ip6_address (&plnk->remote, "fd01::16");
+				g_assert_cmpint (plnk->ttl, ==, 0);
+				g_assert_cmpint (plnk->tclass, ==, 20);
+				g_assert_cmpint (plnk->encap_limit, ==, 6);
+				g_assert_cmpint (plnk->flow_label, ==, 1337);
+				g_assert_cmpint (plnk->proto, ==, IPPROTO_IPV6);
+				break;
+			case 1:
+				g_assert (plnk == nm_platform_link_get_lnk_ip6tnl (NM_PLATFORM_GET, ifindex, NULL));
+				g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent);
+				nmtst_assert_ip6_address (&plnk->local, "fd01::17");
+				nmtst_assert_ip6_address (&plnk->remote, "fd01::18");
+				g_assert_cmpint (plnk->ttl, ==, 0);
+				g_assert_cmpint (plnk->flow_label, ==, 1338);
+				g_assert_cmpint (plnk->proto, ==, IPPROTO_IPV6);
+				g_assert_cmpint (plnk->flags & 0xFFFF, /* ignore kernel internal flags */
+				                 ==,
+				                 IP6_TNL_F_IGN_ENCAP_LIMIT | IP6_TNL_F_USE_ORIG_TCLASS);
+				break;
+			}
 			break;
 		}
 		case NM_LINK_TYPE_IPIP: {
@@ -982,6 +1052,27 @@ test_software_detect (gconstpointer user_data)
 			g_assert_cmpint (plnk->path_mtu_discovery, ==, FALSE);
 			break;
 		}
+		case NM_LINK_TYPE_TUN: {
+			const NMPlatformLnkTun *plnk;
+			NMPlatformLnkTun lnk_tun2;
+
+			g_assert ((lnk ? &lnk->lnk_tun : NULL) == nm_platform_link_get_lnk_tun (NM_PLATFORM_GET, ifindex, NULL));
+
+			/* kernel might not expose tun options via netlink. Either way, try
+			 * to read them (either from platform cache, or fallback to sysfs).
+			 * See also: rh#1547213. */
+			if (!nm_platform_link_tun_get_properties (NM_PLATFORM_GET,
+			                                          ifindex,
+			                                          &lnk_tun2))
+				g_assert_not_reached ();
+
+			plnk = lnk ? &lnk->lnk_tun : &lnk_tun2;
+			if (lnk)
+				g_assert (memcmp (plnk, &lnk_tun2, sizeof (NMPlatformLnkTun)) == 0);
+
+			g_assert (nm_platform_lnk_tun_cmp (plnk, &lnk_tun) == 0);
+			break;
+		}
 		case NM_LINK_TYPE_VLAN: {
 			const NMPlatformLnkVlan *plnk = &lnk->lnk_vlan;
 
@@ -2248,7 +2339,7 @@ test_netns_push (gpointer fixture, gconstpointer test_data)
 		p = pl_base;
 		for (j = nstack; j >= 1; ) {
 			j--;
-			if (NM_FLAGS_HAS (stack[j].ns_types, ns_type)) {
+			if (NM_FLAGS_ANY (stack[j].ns_types, ns_type)) {
 				p = stack[j].pl;
 				break;
 			}
@@ -2546,11 +2637,13 @@ _nmtstp_setup_tests (void)
 		g_test_add_func ("/link/external", test_external);
 
 		test_software_detect_add ("/link/software/detect/gre", NM_LINK_TYPE_GRE, 0);
-		test_software_detect_add ("/link/software/detect/ip6tnl", NM_LINK_TYPE_IP6TNL, 0);
+		test_software_detect_add ("/link/software/detect/ip6tnl/0", NM_LINK_TYPE_IP6TNL, 0);
+		test_software_detect_add ("/link/software/detect/ip6tnl/1", NM_LINK_TYPE_IP6TNL, 1);
 		test_software_detect_add ("/link/software/detect/ipip", NM_LINK_TYPE_IPIP, 0);
 		test_software_detect_add ("/link/software/detect/macvlan", NM_LINK_TYPE_MACVLAN, 0);
 		test_software_detect_add ("/link/software/detect/macvtap", NM_LINK_TYPE_MACVTAP, 0);
 		test_software_detect_add ("/link/software/detect/sit", NM_LINK_TYPE_SIT, 0);
+		test_software_detect_add ("/link/software/detect/tun", NM_LINK_TYPE_TUN, 0);
 		test_software_detect_add ("/link/software/detect/vlan", NM_LINK_TYPE_VLAN, 0);
 		test_software_detect_add ("/link/software/detect/vxlan/0", NM_LINK_TYPE_VXLAN, 0);
 		test_software_detect_add ("/link/software/detect/vxlan/1", NM_LINK_TYPE_VXLAN, 1);
diff --git a/src/platform/tests/test-nmp-object.c b/src/platform/tests/test-nmp-object.c
index 3228de83..047d7a85 100644
--- a/src/platform/tests/test-nmp-object.c
+++ b/src/platform/tests/test-nmp-object.c
@@ -54,27 +54,20 @@ test_obj_base (void)
 	gs_unref_object GCancellable *obj_cancellable = g_cancellable_new ();
 	nm_auto_nmpobj NMPObject *obj_link = nmp_object_new_link (10);
 
-#define STATIC_ASSERT(cond) \
-	G_STMT_START { \
-		G_STATIC_ASSERT (cond); \
-		G_STATIC_ASSERT_EXPR (cond); \
-		g_assert (cond); \
-	} G_STMT_END
+	g_assert (&g->g_type_instance              == (void *) &o->_class);
+	g_assert (&g->g_type_instance.g_class      == (void *) &o->_class);
 
-	STATIC_ASSERT (&g->g_type_instance              == (void *) &o->_class);
-	STATIC_ASSERT (&g->g_type_instance.g_class      == (void *) &o->_class);
+	g_assert (sizeof (o->parent.parent)        == sizeof (GTypeInstance));
 
-	STATIC_ASSERT (sizeof (o->parent.parent)        == sizeof (GTypeInstance));
+	g_assert (&c->parent                       == (void *) c);
+	g_assert (&c->parent.parent.g_type_class   == (void *) c);
+	g_assert (&c->parent.parent.g_type         == (void *) c);
+	g_assert (&c->parent.parent.g_type         == &k->g_type);
 
-	STATIC_ASSERT (&c->parent                       == (void *) c);
-	STATIC_ASSERT (&c->parent.parent.g_type_class   == (void *) c);
-	STATIC_ASSERT (&c->parent.parent.g_type         == (void *) c);
-	STATIC_ASSERT (&c->parent.parent.g_type         == &k->g_type);
+	g_assert (sizeof (c->parent.parent)        == sizeof (GTypeClass));
 
-	STATIC_ASSERT (sizeof (c->parent.parent)        == sizeof (GTypeClass));
-
-	STATIC_ASSERT (&o->parent                       == (void *) o);
-	STATIC_ASSERT (&o->parent.klass                 == (void *) &o->_class);
+	g_assert (&o->parent                       == (void *) o);
+	g_assert (&o->parent.klass                 == (void *) &o->_class);
 
 	obj = (NMObjBaseInst *) obj_cancellable;
 	g_assert (!NMP_CLASS_IS_VALID ((NMPClass *) obj->klass));
diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c
index 13648f16..85b14b57 100644
--- a/src/platform/tests/test-route.c
+++ b/src/platform/tests/test-route.c
@@ -1,6 +1,5 @@
 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager audit support
- *
+/*
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or