summary refs log tree commit diff
path: root/src/platform/tests
diff options
context:
space:
mode:
Diffstat (limited to 'src/platform/tests')
-rw-r--r--src/platform/tests/test-cleanup.c2
-rw-r--r--src/platform/tests/test-common.c65
-rw-r--r--src/platform/tests/test-common.h6
-rw-r--r--src/platform/tests/test-general.c4
-rw-r--r--src/platform/tests/test-link.c243
5 files changed, 298 insertions, 22 deletions
diff --git a/src/platform/tests/test-cleanup.c b/src/platform/tests/test-cleanup.c
index 8b8c87d8..12d91812 100644
--- a/src/platform/tests/test-cleanup.c
+++ b/src/platform/tests/test-cleanup.c
@@ -60,7 +60,7 @@ test_cleanup_internal (void)
 	g_assert (ifindex > 0);
 
 	/* wait for kernel to add the IPv6 link local address... it takes a bit. */
-	NMTST_WAIT_ASSERT (100, {
+	NMTST_WAIT_ASSERT (300, {
 		gs_unref_array GArray *addrs = NULL;
 		const NMPlatformIP6Address *a;
 
diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c
index 42569d5b..3dedbd10 100644
--- a/src/platform/tests/test-common.c
+++ b/src/platform/tests/test-common.c
@@ -1243,21 +1243,29 @@ nmtstp_link_gre_add (NMPlatform *platform,
 	const NMPlatformLink *pllink = NULL;
 	gboolean success;
 	char buffer[INET_ADDRSTRLEN];
+	NMLinkType link_type;
 
 	g_assert (nm_utils_is_valid_iface_name (name, NULL));
 
 	external_command = nmtstp_run_command_check_external (external_command);
+	link_type = lnk->is_tap ? NM_LINK_TYPE_GRETAP : NM_LINK_TYPE_GRE;
 
 	_init_platform (&platform, external_command);
 
 	if (external_command) {
 		gs_free char *dev = NULL;
+		char *obj, *type;
 
 		if (lnk->parent_ifindex)
 			dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (platform, lnk->parent_ifindex));
 
-		success = !nmtstp_run_command ("ip tunnel add %s mode gre %s local %s remote %s ttl %u tos %02x %s",
+		obj = lnk->is_tap ? "link" : "tunnel";
+		type = lnk->is_tap ? "type gretap" : "mode gre";
+
+		success = !nmtstp_run_command ("ip %s add %s %s %s local %s remote %s ttl %u tos %02x %s",
+		                                obj,
 		                                name,
+		                                type,
 		                                dev ?: "",
 		                                nm_utils_inet4_ntop (lnk->local, NULL),
 		                                nm_utils_inet4_ntop (lnk->remote, buffer),
@@ -1265,11 +1273,11 @@ nmtstp_link_gre_add (NMPlatform *platform,
 		                                lnk->tos,
 		                                lnk->path_mtu_discovery ? "pmtudisc" : "nopmtudisc");
 		if (success)
-			pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_GRE, 100);
+			pllink = nmtstp_assert_wait_for_link (platform, name, link_type, 100);
 	} else
 		success = nm_platform_link_gre_add (platform, name, lnk, &pllink) == NM_PLATFORM_ERROR_SUCCESS;
 
-	_assert_pllink (platform, success, pllink, name, NM_LINK_TYPE_GRE);
+	_assert_pllink (platform, success, pllink, name, link_type);
 
 	return pllink;
 }
@@ -1289,6 +1297,7 @@ nmtstp_link_ip6tnl_add (NMPlatform *platform,
 	gboolean tclass_inherit;
 
 	g_assert (nm_utils_is_valid_iface_name (name, NULL));
+	g_assert (!lnk->is_gre);
 
 	external_command = nmtstp_run_command_check_external (external_command);
 
@@ -1336,6 +1345,56 @@ nmtstp_link_ip6tnl_add (NMPlatform *platform,
 }
 
 const NMPlatformLink *
+nmtstp_link_ip6gre_add (NMPlatform *platform,
+                        gboolean external_command,
+                        const char *name,
+                        const NMPlatformLnkIp6Tnl *lnk)
+{
+	const NMPlatformLink *pllink = NULL;
+	gboolean success;
+	char buffer[INET6_ADDRSTRLEN];
+	char tclass[20];
+	gboolean tclass_inherit;
+
+	g_assert (nm_utils_is_valid_iface_name (name, NULL));
+	g_assert (lnk->is_gre);
+
+	external_command = nmtstp_run_command_check_external (external_command);
+
+	_init_platform (&platform, external_command);
+
+	if (external_command) {
+		gs_free char *dev = NULL;
+
+		if (lnk->parent_ifindex)
+			dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (platform, lnk->parent_ifindex));
+
+		tclass_inherit = NM_FLAGS_HAS (lnk->flags, IP6_TNL_F_USE_ORIG_TCLASS);
+
+		success = !nmtstp_run_command ("ip link add %s type %s %s local %s remote %s ttl %u tclass %s flowlabel %x",
+		                                name,
+		                                lnk->is_tap ? "ip6gretap" : "ip6gre",
+		                                dev,
+		                                nm_utils_inet6_ntop (&lnk->local, NULL),
+		                                nm_utils_inet6_ntop (&lnk->remote, buffer),
+		                                lnk->ttl,
+		                                tclass_inherit ? "inherit" : nm_sprintf_buf (tclass, "%02x", lnk->tclass),
+		                                lnk->flow_label);
+		if (success) {
+			pllink = nmtstp_assert_wait_for_link (platform,
+			                                      name,
+			                                      lnk->is_tap ? NM_LINK_TYPE_IP6GRETAP : NM_LINK_TYPE_IP6GRE,
+			                                      100);
+		}
+	} else
+		success = nm_platform_link_ip6gre_add (platform, name, lnk, &pllink) == NM_PLATFORM_ERROR_SUCCESS;
+
+	_assert_pllink (platform, success, pllink, name, lnk->is_tap ? NM_LINK_TYPE_IP6GRETAP : NM_LINK_TYPE_IP6GRE);
+
+	return pllink;
+}
+
+const NMPlatformLink *
 nmtstp_link_ipip_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 bd02b0d7..1baadfa1 100644
--- a/src/platform/tests/test-common.h
+++ b/src/platform/tests/test-common.h
@@ -80,7 +80,7 @@ typedef struct {
 	gulong handler_id;
 	const char *name;
 	NMPlatformSignalChangeType change_type;
-	gint received_count;
+	int received_count;
 	GMainLoop *loop;
 	int ifindex;
 	const char *ifname;
@@ -297,6 +297,10 @@ const NMPlatformLink *nmtstp_link_ip6tnl_add (NMPlatform *platform,
                                               gboolean external_command,
                                               const char *name,
                                               const NMPlatformLnkIp6Tnl *lnk);
+const NMPlatformLink *nmtstp_link_ip6gre_add (NMPlatform *platform,
+                                              gboolean external_command,
+                                              const char *name,
+                                              const NMPlatformLnkIp6Tnl *lnk);
 const NMPlatformLink *nmtstp_link_ipip_add (NMPlatform *platform,
                                             gboolean external_command,
                                             const char *name,
diff --git a/src/platform/tests/test-general.c b/src/platform/tests/test-general.c
index 8708c80f..eebc15d8 100644
--- a/src/platform/tests/test-general.c
+++ b/src/platform/tests/test-general.c
@@ -15,7 +15,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * Copyright (C) 2015 Red Hat, Inc.
+ * Copyright (C) 2015 - 2018 Red Hat, Inc.
  */
 
 #include "nm-default.h"
@@ -57,7 +57,7 @@ NMTST_DEFINE ();
 int
 main (int argc, char **argv)
 {
-	nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT");
+	nmtst_init_assert_logging (&argc, &argv, "WARN", "DEFAULT");
 
 	g_test_add_func ("/general/init_linux_platform", test_init_linux_platform);
 	g_test_add_func ("/general/link_get_all", test_link_get_all);
diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c
index cd5880e3..057490c4 100644
--- a/src/platform/tests/test-link.c
+++ b/src/platform/tests/test-link.c
@@ -25,6 +25,7 @@
 #include <sys/types.h>
 #include <linux/if_tun.h>
 
+#include "nm-utils/nm-io-utils.h"
 #include "platform/nmp-object.h"
 #include "platform/nmp-netns.h"
 #include "platform/nm-platform-utils.h"
@@ -699,6 +700,7 @@ test_software_detect (gconstpointer user_data)
 	guint i_step;
 	const gboolean ext = test_data->external_command;
 	NMPlatformLnkTun lnk_tun;
+	NMPlatformLnkGre lnk_gre = { };
 	nm_auto_close int tun_fd = -1;
 
 	nmtstp_run_command_check ("ip link add %s type dummy", PARENT_NAME);
@@ -706,7 +708,6 @@ test_software_detect (gconstpointer user_data)
 
 	switch (test_data->link_type) {
 	case NM_LINK_TYPE_GRE: {
-		NMPlatformLnkGre lnk_gre = { };
 		gboolean gracefully_skip = FALSE;
 
 		lnk_gre.local = nmtst_inet4_from_string ("192.168.233.204");
@@ -730,6 +731,31 @@ test_software_detect (gconstpointer user_data)
 		}
 		break;
 	}
+	case NM_LINK_TYPE_GRETAP: {
+		gboolean gracefully_skip = FALSE;
+
+		lnk_gre.local = nmtst_inet4_from_string ("192.168.1.133");
+		lnk_gre.remote = nmtst_inet4_from_string ("172.168.101.2");
+		lnk_gre.parent_ifindex = ifindex_parent;
+		lnk_gre.ttl = 39;
+		lnk_gre.tos = 12;
+		lnk_gre.path_mtu_discovery = FALSE;
+		lnk_gre.is_tap = TRUE;
+
+		if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "gretap0")) {
+			/* Seems that the ip_gre module is not loaded... try to load it. */
+			gracefully_skip = nm_utils_modprobe (NULL, TRUE, "ip_gre", NULL) != 0;
+		}
+
+		if (!nmtstp_link_gre_add (NULL, ext, DEVICE_NAME, &lnk_gre)) {
+			if (gracefully_skip) {
+				g_test_skip ("Cannot create gretap tunnel because of missing ip_gre module (modprobe ip_gre)");
+				goto out_delete_parent;
+			}
+			g_error ("Failed adding GRETAP tunnel");
+		}
+		break;
+	}
 	case NM_LINK_TYPE_IPIP: {
 		NMPlatformLnkIpIp lnk_ipip = { };
 		gboolean gracefully_skip = FALSE;
@@ -794,6 +820,58 @@ test_software_detect (gconstpointer user_data)
 		}
 		break;
 	}
+	case NM_LINK_TYPE_IP6GRE: {
+		NMPlatformLnkIp6Tnl lnk_ip6tnl = { };
+		gboolean gracefully_skip = FALSE;
+
+		if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "ip6gre0")) {
+			/* Seems that the ip6_tunnel module is not loaded... try to load it. */
+			gracefully_skip = nm_utils_modprobe (NULL, TRUE, "ip6_gre", NULL) != 0;
+		}
+
+		lnk_ip6tnl.local = *nmtst_inet6_from_string ("fd01::42");
+		lnk_ip6tnl.remote = *nmtst_inet6_from_string ("fd01::aaaa");
+		lnk_ip6tnl.parent_ifindex = ifindex_parent;
+		lnk_ip6tnl.tclass = 21;
+		lnk_ip6tnl.flow_label = 1338;
+		lnk_ip6tnl.is_gre = TRUE;
+
+		if (!nmtstp_link_ip6gre_add (NULL, ext, DEVICE_NAME, &lnk_ip6tnl)) {
+			if (gracefully_skip) {
+				g_test_skip ("Cannot create ip6gre tunnel because of missing ip6_gre module (modprobe ip6_gre)");
+				goto out_delete_parent;
+			}
+			g_error ("Failed adding IP6GRE tunnel");
+		}
+		break;
+	}
+	case NM_LINK_TYPE_IP6GRETAP: {
+		NMPlatformLnkIp6Tnl lnk_ip6tnl = { };
+		gboolean gracefully_skip = FALSE;
+
+		if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "ip6gre0")) {
+			/* Seems that the ip6_tunnel module is not loaded... try to load it. */
+			gracefully_skip = nm_utils_modprobe (NULL, TRUE, "ip6_gre", NULL) != 0;
+		}
+
+		lnk_ip6tnl.local = *nmtst_inet6_from_string ("fe80::abcd");
+		lnk_ip6tnl.remote = *nmtst_inet6_from_string ("fc01::bbbb");
+		lnk_ip6tnl.parent_ifindex = ifindex_parent;
+		lnk_ip6tnl.ttl = 10;
+		lnk_ip6tnl.tclass = 22;
+		lnk_ip6tnl.flow_label = 1339;
+		lnk_ip6tnl.is_gre = TRUE;
+		lnk_ip6tnl.is_tap = TRUE;
+
+		if (!nmtstp_link_ip6gre_add (NULL, ext, DEVICE_NAME, &lnk_ip6tnl)) {
+			if (gracefully_skip) {
+				g_test_skip ("Cannot create ip6gretap tunnel because of missing ip6_gre module (modprobe ip6_gre)");
+				goto out_delete_parent;
+			}
+			g_error ("Failed adding IP6GRETAP tunnel");
+		}
+		break;
+	}
 	case NM_LINK_TYPE_MACVLAN: {
 		NMPlatformLnkMacvlan lnk_macvlan = { };
 		const NMPlatformLink *dummy;
@@ -970,16 +1048,15 @@ test_software_detect (gconstpointer user_data)
 			const NMPlatformLnkGre *plnk = &lnk->lnk_gre;
 
 			g_assert (plnk == nm_platform_link_get_lnk_gre (NM_PLATFORM_GET, ifindex, NULL));
-			g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent);
-			g_assert_cmpint (plnk->input_flags, ==, 0);
-			g_assert_cmpint (plnk->output_flags, ==, 0);
-			g_assert_cmpint (plnk->input_key, ==, 0);
-			g_assert_cmpint (plnk->output_key, ==, 0);
-			nmtst_assert_ip4_address (plnk->local, "192.168.233.204");
-			nmtst_assert_ip4_address (plnk->remote, "172.168.10.25");
-			g_assert_cmpint (plnk->ttl, ==, 174);
-			g_assert_cmpint (plnk->tos, ==, 37);
-			g_assert_cmpint (plnk->path_mtu_discovery, ==, TRUE);
+			g_assert (nm_platform_lnk_gre_cmp (plnk, &lnk_gre) == 0);
+
+			break;
+		}
+		case NM_LINK_TYPE_GRETAP: {
+			const NMPlatformLnkGre *plnk = &lnk->lnk_gre;
+
+			g_assert (plnk == nm_platform_link_get_lnk_gretap (NM_PLATFORM_GET, ifindex, NULL));
+			g_assert (nm_platform_lnk_gre_cmp (plnk, &lnk_gre) == 0);
 			break;
 		}
 		case NM_LINK_TYPE_IP6TNL: {
@@ -1012,6 +1089,33 @@ test_software_detect (gconstpointer user_data)
 			}
 			break;
 		}
+		case NM_LINK_TYPE_IP6GRE: {
+			const NMPlatformLnkIp6Tnl *plnk = &lnk->lnk_ip6tnl;
+
+			g_assert (plnk == nm_platform_link_get_lnk_ip6gre (NM_PLATFORM_GET, ifindex, NULL));
+			g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent);
+			nmtst_assert_ip6_address (&plnk->local, "fd01::42");
+			nmtst_assert_ip6_address (&plnk->remote, "fd01::aaaa");
+			g_assert_cmpint (plnk->tclass, ==, 21);
+			g_assert_cmpint (plnk->flow_label, ==, 1338);
+			g_assert_cmpint (plnk->is_gre, ==, TRUE);
+			g_assert_cmpint (plnk->is_tap, ==, FALSE);
+			break;
+		}
+		case NM_LINK_TYPE_IP6GRETAP: {
+			const NMPlatformLnkIp6Tnl *plnk = &lnk->lnk_ip6tnl;
+
+			g_assert (plnk == nm_platform_link_get_lnk_ip6gretap (NM_PLATFORM_GET, ifindex, NULL));
+			g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent);
+			nmtst_assert_ip6_address (&plnk->local, "fe80::abcd");
+			nmtst_assert_ip6_address (&plnk->remote, "fc01::bbbb");
+			g_assert_cmpint (plnk->ttl, ==, 10);
+			g_assert_cmpint (plnk->tclass, ==, 22);
+			g_assert_cmpint (plnk->flow_label, ==, 1339);
+			g_assert_cmpint (plnk->is_gre, ==, TRUE);
+			g_assert_cmpint (plnk->is_tap, ==, TRUE);
+			break;
+		}
 		case NM_LINK_TYPE_IPIP: {
 			const NMPlatformLnkIpIp *plnk = &lnk->lnk_ipip;
 
@@ -1732,7 +1836,7 @@ test_create_many_links_do (guint n_devices)
 	char name[64];
 	const NMPlatformLink *pllink;
 	gs_unref_array GArray *ifindexes = g_array_sized_new (FALSE, FALSE, sizeof (int), n_devices);
-	const gint EX = ((int) (nmtst_get_rand_int () % 4)) - 1;
+	const int EX = ((int) (nmtst_get_rand_int () % 4)) - 1;
 
 	g_assert (EX >= -1 && EX <= 2);
 
@@ -2519,7 +2623,9 @@ test_sysctl_rename (void)
 	case 0: {
 		gs_free char *c = NULL;
 
-		if (nm_utils_file_get_contents (dirfd, "ifindex", 1*1024*1024, &c, NULL, NULL) < 0)
+		if (nm_utils_file_get_contents (dirfd, "ifindex", 1*1024*1024,
+		                                NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE,
+		                                &c, NULL, NULL) < 0)
 			g_assert_not_reached();
 		g_assert_cmpint (ifindex[0], ==, (int) _nm_utils_ascii_str_to_int64 (c, 10, 0, G_MAXINT, -1));
 		break;
@@ -2583,7 +2689,9 @@ test_sysctl_netns_switch (void)
 	{
 		gs_free char *c = NULL;
 
-		if (nm_utils_file_get_contents (dirfd, "ifindex", 0, &c, NULL, NULL) < 0)
+		if (nm_utils_file_get_contents (dirfd, "ifindex", 0,
+		                                NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE,
+		                                &c, NULL, NULL) < 0)
 			g_assert_not_reached();
 		g_assert_cmpint (ifindex, ==, (int) _nm_utils_ascii_str_to_int64 (c, 10, 0, G_MAXINT, -1));
 	}
@@ -2595,7 +2703,11 @@ test_sysctl_netns_switch (void)
 	{
 		gs_free char *c = NULL;
 
-		if (nm_utils_file_get_contents (-1, nm_sprintf_bufa (100, "/sys/class/net/%s/ifindex", IFNAME), 0, &c, NULL, NULL) < 0)
+		if (nm_utils_file_get_contents (-1,
+		                                nm_sprintf_bufa (100, "/sys/class/net/%s/ifindex", IFNAME),
+		                                0,
+		                                NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE,
+		                                &c, NULL, NULL) < 0)
 			ifindex_tmp = -1;
 		else
 			ifindex_tmp = _nm_utils_ascii_str_to_int64 (c, 10, 0, G_MAXINT, -2);
@@ -2610,6 +2722,102 @@ test_sysctl_netns_switch (void)
 
 /*****************************************************************************/
 
+static void
+ethtool_features_dump (const NMEthtoolFeatureStates *features)
+{
+	guint i, j;
+
+	g_assert (features);
+
+	_LOGT (">>> %u features (%u ss-features)", features->n_states, features->n_ss_features);
+
+	for (i = 0; i < features->n_states; i++) {
+		const NMEthtoolFeatureState *s = &features->states_list[i];
+
+		_LOGT (">>> feature-list[%3u]: %3d = %-32s (%3u) | %s %s %s %s",
+		       i,
+		       (int) s->info->ethtool_id,
+		       s->info->kernel_names[s->idx_kernel_name],
+		       s->idx_ss_features,
+		       s->active ? "ACT" : "act",
+		       s->available ? "AVA" : "ava",
+		       s->never_changed ? "NCH" : "nch",
+		       s->requested ? "REQ" : "req");
+	}
+	for (i = 0; i < _NM_ETHTOOL_ID_FEATURE_NUM; i++) {
+		_LOGT (">>> feature-idx [%3u]: %-32s = %u features",
+		       i + (guint) _NM_ETHTOOL_ID_FEATURE_FIRST,
+		       nm_ethtool_data[i + _NM_ETHTOOL_ID_FEATURE_FIRST]->optname,
+		       (guint) NM_PTRARRAY_LEN (features->states_indexed[i]));
+		for (j = 0; features->states_indexed[i] && features->states_indexed[i][j]; j++) {
+			const NMEthtoolFeatureState *s = features->states_indexed[i][j];
+
+			_LOGT (">>>  %3u: %-32s | %s %s %s %s",
+			       j,
+			       s->info->kernel_names[s->idx_kernel_name],
+			       s->active ? "ACT" : "act",
+			       s->available ? "AVA" : "ava",
+			       s->never_changed ? "NCH" : "nch",
+			       s->requested ? "REQ" : "req");
+		}
+	}
+}
+
+static void
+test_ethtool_features_get (void)
+{
+	gs_unref_ptrarray GPtrArray *gfree_keeper = g_ptr_array_new_with_free_func (g_free);
+	const int IFINDEX = 1;
+	guint i;
+	guint i_run;
+
+	for (i_run = 0; i_run < 5; i_run++) {
+		NMEthtoolFeatureStates *features;
+		NMTernary *requested;
+		gboolean do_set = TRUE;
+
+		requested = g_new (NMTernary, _NM_ETHTOOL_ID_FEATURE_NUM);
+		for (i = 0; i < _NM_ETHTOOL_ID_FEATURE_NUM; i++)
+			requested[i] = NM_TERNARY_DEFAULT;
+		g_ptr_array_add (gfree_keeper, requested);
+
+		if (i_run == 0) {
+			requested[NM_ETHTOOL_ID_FEATURE_RX]                    = NM_TERNARY_FALSE;
+			requested[NM_ETHTOOL_ID_FEATURE_TSO]                   = NM_TERNARY_FALSE;
+			requested[NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION]  = NM_TERNARY_FALSE;
+		} else if (i_run == 1)
+			do_set = FALSE;
+		else if (i_run == 2) {
+			requested[NM_ETHTOOL_ID_FEATURE_TSO]                   = NM_TERNARY_FALSE;
+			requested[NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION]  = NM_TERNARY_TRUE;
+		} else if (i_run == 3)
+			do_set = FALSE;
+
+		_LOGT (">>> ethtool-features-get RUN %u (do-set=%s", i_run, do_set ? "set" : "reset");
+
+		features = nmp_utils_ethtool_get_features (IFINDEX);
+		g_ptr_array_add (gfree_keeper, features);
+
+		ethtool_features_dump (features);
+
+		if (_LOGT_ENABLED ()) {
+			int ignore;
+
+			ignore = system ("ethtool -k lo");
+			(void) ignore;
+		}
+
+		if (!do_set) {
+			requested = gfree_keeper->pdata[i_run * 2 - 2];
+			features = gfree_keeper->pdata[i_run * 2 - 1];
+		}
+
+		nmp_utils_ethtool_set_features (IFINDEX, features, requested, do_set);
+	}
+}
+
+/*****************************************************************************/
+
 NMTstpSetupFunc const _nmtstp_setup_platform_func = SETUP;
 
 void
@@ -2641,8 +2849,11 @@ _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/gretap", NM_LINK_TYPE_GRETAP, 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/ip6gre", NM_LINK_TYPE_IP6GRE, 0);
+		test_software_detect_add ("/link/software/detect/ip6gretap", NM_LINK_TYPE_IP6GRETAP, 0);
 		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);
@@ -2668,5 +2879,7 @@ _nmtstp_setup_tests (void)
 
 		g_test_add_func ("/general/sysctl/rename", test_sysctl_rename);
 		g_test_add_func ("/general/sysctl/netns-switch", test_sysctl_netns_switch);
+
+		g_test_add_func ("/link/ethtool/features/get", test_ethtool_features_get);
 	}
 }