about summary refs log tree commit diff
path: root/src/platform/tests/test-common.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2018-06-04 00:07:45 +0200
committerMichael Biebl <biebl@debian.org>2018-06-04 00:07:45 +0200
commit04bc9e1cd3544445d883ad29ea108c1645c8e7b7 (patch)
treed10c354b1b980ca8a7b9e48ec9019e8ed88bde2b /src/platform/tests/test-common.c
parentee9c73a923909e23a649407be77e25235d769e25 (diff)
New upstream version 1.11.4 upstream/1.11.4
Diffstat (limited to 'src/platform/tests/test-common.c')
-rw-r--r--src/platform/tests/test-common.c122
1 files changed, 96 insertions, 26 deletions
diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c
index d56e681e..42569d5b 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,11 +23,12 @@
 #include <sched.h>
 #include <sys/wait.h>
 #include <fcntl.h>
+#include <linux/if_tun.h>
 
 #include "test-common.h"
 
 #define SIGNAL_DATA_FMT "'%s-%s' ifindex %d%s%s%s (%d times received)"
-#define SIGNAL_DATA_ARG(data) (data)->name, nm_platform_signal_change_type_to_string ((data)->change_type), (data)->ifindex, (data)->ifname ? " ifname '" : "", (data)->ifname ? (data)->ifname : "", (data)->ifname ? "'" : "", (data)->received_count
+#define SIGNAL_DATA_ARG(data) (data)->name, nm_platform_signal_change_type_to_string ((data)->change_type), (data)->ifindex, (data)->ifname ? " ifname '" : "", (data)->ifname ?: "", (data)->ifname ? "'" : "", (data)->received_count
 
 int NMTSTP_ENV1_IFINDEX = -1;
 int NMTSTP_ENV1_EX = -1;
@@ -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
@@ -1259,7 +1258,7 @@ nmtstp_link_gre_add (NMPlatform *platform,
 
 		success = !nmtstp_run_command ("ip tunnel add %s mode gre %s local %s remote %s ttl %u tos %02x %s",
 		                                name,
-		                                dev ? dev : "",
+		                                dev ?: "",
 		                                nm_utils_inet4_ntop (lnk->local, NULL),
 		                                nm_utils_inet4_ntop (lnk->remote, buffer),
 		                                lnk->ttl,
@@ -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,
@@ -1498,7 +1568,7 @@ nmtstp_link_vxlan_add (NMPlatform *platform,
 		err = nmtstp_run_command ("ip link add %s type vxlan id %u %s local %s group %s ttl %u tos %02x dstport %u srcport %u %u ageing %u",
 		                          name,
 		                          lnk->id,
-		                          dev ? dev : "",
+		                          dev ?: "",
 		                          local,
 		                          remote,
 		                          lnk->ttl,