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.c12
-rw-r--r--src/platform/tests/test-common.c50
-rw-r--r--src/platform/tests/test-common.h22
-rw-r--r--src/platform/tests/test-general.c4
-rw-r--r--src/platform/tests/test-link.c14
-rw-r--r--src/platform/tests/test-nmp-object.c42
-rw-r--r--src/platform/tests/test-route.c174
7 files changed, 277 insertions, 41 deletions
diff --git a/src/platform/tests/test-cleanup.c b/src/platform/tests/test-cleanup.c
index 4ac49298..71a92cbf 100644
--- a/src/platform/tests/test-cleanup.c
+++ b/src/platform/tests/test-cleanup.c
@@ -65,12 +65,12 @@ test_cleanup_internal (void)
 	/* Add routes and addresses */
 	g_assert (nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, addr4, plen4, addr4, lifetime, preferred, 0, NULL));
 	g_assert (nm_platform_ip6_address_add (NM_PLATFORM_GET, ifindex, addr6, plen6, in6addr_any, lifetime, preferred, flags));
-	g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, gateway4, 32, INADDR_ANY, 0, metric, mss));
-	g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network4, plen4, gateway4, 0, metric, mss));
-	g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, 0, 0, gateway4, 0, metric, mss));
-	g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, gateway6, 128, in6addr_any, metric, mss));
-	g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network6, plen6, gateway6, metric, mss));
-	g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, in6addr_any, 0, gateway6, metric, mss));
+	nmtstp_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, gateway4, 32, INADDR_ANY, 0, metric, mss);
+	nmtstp_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network4, plen4, gateway4, 0, metric, mss);
+	nmtstp_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, 0, 0, gateway4, 0, metric, mss);
+	nmtstp_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, gateway6, 128, in6addr_any, in6addr_any, metric, mss);
+	nmtstp_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network6, plen6, gateway6, in6addr_any, metric, mss);
+	nmtstp_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, in6addr_any, 0, gateway6, in6addr_any, metric, mss);
 
 	addresses4 = nm_platform_ip4_address_get_all (NM_PLATFORM_GET, ifindex);
 	addresses6 = nm_platform_ip6_address_get_all (NM_PLATFORM_GET, ifindex);
diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c
index 0e42a727..04db862d 100644
--- a/src/platform/tests/test-common.c
+++ b/src/platform/tests/test-common.c
@@ -783,6 +783,54 @@ nmtstp_ip6_address_add (NMPlatform *platform,
 	                 NULL);
 }
 
+void nmtstp_ip4_route_add (NMPlatform *platform,
+                           int ifindex,
+                           NMIPConfigSource source,
+                           in_addr_t network,
+                           guint8 plen,
+                           in_addr_t gateway,
+                           in_addr_t pref_src,
+                           guint32 metric,
+                           guint32 mss)
+{
+	NMPlatformIP4Route route = { };
+
+	route.ifindex = ifindex;
+	route.rt_source = source;
+	route.network = network;
+	route.plen = plen;
+	route.gateway = gateway;
+	route.pref_src = pref_src;
+	route.metric = metric;
+	route.mss = mss;
+
+	g_assert (nm_platform_ip4_route_add (platform, &route));
+}
+
+void nmtstp_ip6_route_add (NMPlatform *platform,
+                           int ifindex,
+                           NMIPConfigSource source,
+                           struct in6_addr network,
+                           guint8 plen,
+                           struct in6_addr gateway,
+                           struct in6_addr pref_src,
+                           guint32 metric,
+                           guint32 mss)
+{
+	NMPlatformIP6Route route = { };
+
+	route.ifindex = ifindex;
+	route.rt_source = source;
+	route.network = network;
+	route.plen = plen;
+	route.gateway = gateway;
+	route.pref_src = pref_src;
+	route.metric = metric;
+	route.mss = mss;
+
+	g_assert (nm_platform_ip6_route_add (platform, &route));
+}
+
 /*****************************************************************************/
 
 static void
@@ -1547,7 +1595,7 @@ nmtstp_namespace_get_fd_for_process (pid_t pid, const char *ns_name)
 	g_return_val_if_fail (pid > 0, 0);
 	g_return_val_if_fail (ns_name && ns_name[0] && strlen (ns_name) < 50, 0);
 
-	nm_sprintf_buf (p, "/proc/%lu/ns/%s", (long unsigned) pid, ns_name);
+	nm_sprintf_buf (p, "/proc/%lu/ns/%s", (unsigned long) pid, ns_name);
 
 	return open(p, O_RDONLY | O_CLOEXEC);
 }
diff --git a/src/platform/tests/test-common.h b/src/platform/tests/test-common.h
index 48a41de6..a52a5db5 100644
--- a/src/platform/tests/test-common.h
+++ b/src/platform/tests/test-common.h
@@ -26,7 +26,7 @@
         if (nm_logging_enabled (__level, __domain)) { \
             gint64 _ts = nm_utils_get_monotonic_timestamp_ns (); \
             \
-            _nm_log (__level, __domain, 0, \
+            _nm_log (__level, __domain, 0, NULL, NULL, \
                      "%s[%ld.%09ld]: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \
                      _NMLOG_PREFIX_NAME, \
                      (long) (_ts / NM_UTILS_NS_PER_SECOND), \
@@ -167,6 +167,26 @@ void nmtstp_ip6_address_del (NMPlatform *platform,
                              struct in6_addr address,
                              int plen);
 
+void nmtstp_ip4_route_add (NMPlatform *platform,
+                           int ifindex,
+                           NMIPConfigSource source,
+                           in_addr_t network,
+                           guint8 plen,
+                           in_addr_t gateway,
+                           in_addr_t pref_src,
+                           guint32 metric,
+                           guint32 mss);
+
+void nmtstp_ip6_route_add (NMPlatform *platform,
+                           int ifindex,
+                           NMIPConfigSource source,
+                           struct in6_addr network,
+                           guint8 plen,
+                           struct in6_addr gateway,
+                           struct in6_addr pref_src,
+                           guint32 metric,
+                           guint32 mss);
+
 /*****************************************************************************/
 
 const NMPlatformLink *nmtstp_link_get_typed (NMPlatform *platform, int ifindex, const char *name, NMLinkType link_type);
diff --git a/src/platform/tests/test-general.c b/src/platform/tests/test-general.c
index 658aad26..2ccfac7d 100644
--- a/src/platform/tests/test-general.c
+++ b/src/platform/tests/test-general.c
@@ -35,7 +35,7 @@ test_init_linux_platform (void)
 {
 	gs_unref_object NMPlatform *platform = NULL;
 
-	platform = nm_linux_platform_new (NM_PLATFORM_NETNS_SUPPORT_DEFAULT);
+	platform = nm_linux_platform_new (TRUE, NM_PLATFORM_NETNS_SUPPORT_DEFAULT);
 }
 
 /*****************************************************************************/
@@ -46,7 +46,7 @@ test_link_get_all (void)
 	gs_unref_object NMPlatform *platform = NULL;
 	gs_unref_array GArray *links = NULL;
 
-	platform = nm_linux_platform_new (NM_PLATFORM_NETNS_SUPPORT_DEFAULT);
+	platform = nm_linux_platform_new (TRUE, NM_PLATFORM_NETNS_SUPPORT_DEFAULT);
 
 	links = nm_platform_link_get_all (platform);
 }
diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c
index c2b3de13..ed435567 100644
--- a/src/platform/tests/test-link.c
+++ b/src/platform/tests/test-link.c
@@ -1900,7 +1900,7 @@ _test_netns_create_platform (void)
 	netns = nmp_netns_new ();
 	g_assert (NMP_IS_NETNS (netns));
 
-	platform = nm_linux_platform_new (TRUE);
+	platform = nm_linux_platform_new (TRUE, TRUE);
 	g_assert (NM_IS_LINUX_PLATFORM (platform));
 
 	nmp_netns_pop (netns);
@@ -1961,7 +1961,7 @@ test_netns_general (gpointer fixture, gconstpointer test_data)
 	if (_test_netns_check_skip ())
 		return;
 
-	platform_1 = nm_linux_platform_new (TRUE);
+	platform_1 = nm_linux_platform_new (TRUE, TRUE);
 	platform_2 = _test_netns_create_platform ();
 
 	/* add some dummy devices. The "other-*" devices are there to bump the ifindex */
@@ -2061,7 +2061,7 @@ test_netns_set_netns (gpointer fixture, gconstpointer test_data)
 	if (_test_netns_check_skip ())
 		return;
 
-	platforms[0] = platform_0 = nm_linux_platform_new (TRUE);
+	platforms[0] = platform_0 = nm_linux_platform_new (TRUE, TRUE);
 	platforms[1] = platform_1 = _test_netns_create_platform ();
 	platforms[2] = platform_2 = _test_netns_create_platform ();
 
@@ -2156,7 +2156,7 @@ test_netns_push (gpointer fixture, gconstpointer test_data)
 	if (_test_netns_check_skip ())
 		return;
 
-	pl[0].platform = platform_0 = nm_linux_platform_new (TRUE);
+	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 ();
 
@@ -2288,7 +2288,7 @@ test_netns_bind_to_path (gpointer fixture, gconstpointer test_data)
 	if (_test_netns_check_skip ())
 		return;
 
-	platforms[0] = platform_0 = nm_linux_platform_new (TRUE);
+	platforms[0] = platform_0 = nm_linux_platform_new (TRUE, TRUE);
 	platforms[1] = platform_1 = _test_netns_create_platform ();
 	platforms[2] = platform_2 = _test_netns_create_platform ();
 
@@ -2404,8 +2404,6 @@ test_sysctl_rename (void)
 		g_assert_cmpint (ifindex[0], ==, (gint32) nm_platform_sysctl_get_int32 (PL, NMP_SYSCTL_PATHID_NETDIR (dirfd, s ?: "<unknown>", "ifindex"), -1));
 		break;
 	}
-	default:
-		g_assert_not_reached ();
 	}
 
 	nm_platform_process_events (PL);
@@ -2435,7 +2433,7 @@ test_sysctl_netns_switch (void)
 	if (_test_netns_check_skip ())
 		return;
 
-	platforms[0] = platform_0 = nm_linux_platform_new (TRUE);
+	platforms[0] = platform_0 = nm_linux_platform_new (TRUE, TRUE);
 	platforms[1] = platform_1 = _test_netns_create_platform ();
 	platforms[2] = platform_2 = _test_netns_create_platform ();
 	PL = platforms[nmtst_get_rand_int () % 3];
diff --git a/src/platform/tests/test-nmp-object.c b/src/platform/tests/test-nmp-object.c
index f7b209de..42dfc572 100644
--- a/src/platform/tests/test-nmp-object.c
+++ b/src/platform/tests/test-nmp-object.c
@@ -20,7 +20,10 @@
 
 #include "nm-default.h"
 
+#include <libudev.h>
+
 #include "platform/nmp-object.h"
+#include "nm-utils/nm-udev-utils.h"
 
 #include "nm-test-utils-core.h"
 
@@ -159,7 +162,7 @@ _nmp_cache_update_netlink (NMPCache *cache, NMPObject *obj, NMPObject **out_obj,
 
 	obj_old = nmp_cache_lookup_link (cache, obj->object.ifindex);
 	if (obj_old && obj_old->_link.udev.device)
-		obj_clone->_link.udev.device = g_object_ref (obj_old->_link.udev.device);
+		obj_clone->_link.udev.device = udev_device_ref (obj_old->_link.udev.device);
 	_nmp_object_fixup_link_udev_fields (obj_clone, nmp_cache_use_udev_get (cache));
 
 	g_assert (cache);
@@ -219,8 +222,8 @@ test_cache_link (void)
 	NMPObject objs1;
 	gboolean was_visible;
 	NMPCacheId cache_id_storage;
-	GUdevDevice *udev_device_2 = g_list_nth_data (global.udev_devices, 0);
-	GUdevDevice *udev_device_3 = g_list_nth_data (global.udev_devices, 0);
+	struct udev_device *udev_device_2 = g_list_nth_data (global.udev_devices, 0);
+	struct udev_device *udev_device_3 = g_list_nth_data (global.udev_devices, 0);
 	NMPCacheOpsType ops_type;
 
 	cache = nmp_cache_new (nmtst_get_rand_int () % 2);
@@ -390,23 +393,40 @@ int
 main (int argc, char **argv)
 {
 	int result;
-	gs_unref_object GUdevClient *udev_client = NULL;
+	NMUdevClient *udev_client;
 
 	nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT");
 
-	udev_client = g_udev_client_new ((const char *[]) { "net", NULL });
+	udev_client = nm_udev_client_new ((const char *[]) { "net", NULL },
+	                                  NULL, NULL);
 	{
-		gs_unref_object GUdevEnumerator *udev_enumerator = g_udev_enumerator_new (udev_client);
+		struct udev_enumerate *enumerator;
+		struct udev_list_entry *devices, *l;
 
-		g_udev_enumerator_add_match_subsystem (udev_enumerator, "net");
+		enumerator = nm_udev_client_enumerate_new (udev_client);
 
 		/* Demand that the device is initialized (udev rules ran,
 		 * device has a stable name now) in case udev is running
 		 * (not in a container). */
 		if (access ("/sys", W_OK) == 0)
-			g_udev_enumerator_add_match_is_initialized (udev_enumerator);
+			udev_enumerate_add_match_is_initialized (enumerator);
+
+		udev_enumerate_scan_devices (enumerator);
+
+		devices = udev_enumerate_get_list_entry (enumerator);
+		for (l = devices; l != NULL; l = udev_list_entry_get_next (l)) {
+			struct udev_device *udevice;
+
+			udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerator),
+			                                        udev_list_entry_get_name (l));
+			if (udevice == NULL)
+				continue;
 
-		global.udev_devices = g_udev_enumerator_execute (udev_enumerator);
+			global.udev_devices = g_list_prepend (global.udev_devices, udevice);
+		}
+		global.udev_devices = g_list_reverse (global.udev_devices);
+
+		udev_enumerate_unref (enumerator);
 	}
 
 	g_test_add_func ("/nmp-object/cache_link", test_cache_link);
@@ -414,10 +434,12 @@ main (int argc, char **argv)
 	result = g_test_run ();
 
 	while (global.udev_devices) {
-		g_object_unref (global.udev_devices->data);
+		udev_device_unref (global.udev_devices->data);
 		global.udev_devices = g_list_remove (global.udev_devices, global.udev_devices->data);
 	}
 
+	nm_udev_client_unref (udev_client);
+
 	return result;
 }
 
diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c
index 59a05bd4..6862f13e 100644
--- a/src/platform/tests/test-route.c
+++ b/src/platform/tests/test-route.c
@@ -94,7 +94,7 @@ test_ip4_route_metric0 (void)
 	nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric);
 
 	/* add the first route */
-	g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, INADDR_ANY, 0, metric, mss));
+	nmtstp_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, INADDR_ANY, 0, metric, mss);
 	accept_signal (route_added);
 
 	nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0);
@@ -108,7 +108,7 @@ test_ip4_route_metric0 (void)
 	nmtstp_assert_ip4_route_exists (NULL, TRUE,  DEVICE_NAME, network, plen, metric);
 
 	/* add the second route */
-	g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, INADDR_ANY, 0, 0, mss));
+	nmtstp_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, INADDR_ANY, 0, 0, mss);
 	accept_signal (route_added);
 
 	nmtstp_assert_ip4_route_exists (NULL, TRUE,  DEVICE_NAME, network, plen, 0);
@@ -160,27 +160,27 @@ test_ip4_route (void)
 	inet_pton (AF_INET, "198.51.100.1", &gateway);
 
 	/* Add route to gateway */
-	g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, gateway, 32, INADDR_ANY, 0, metric, mss));
+	nmtstp_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, gateway, 32, INADDR_ANY, 0, metric, mss);
 	accept_signal (route_added);
 
 	/* Add route */
 	nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric);
-	g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, 0, metric, mss));
+	nmtstp_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, 0, metric, mss);
 	nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric);
 	accept_signal (route_added);
 
 	/* Add route again */
-	g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, 0, metric, mss));
+	nmtstp_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, 0, metric, mss);
 	accept_signals (route_changed, 0, 1);
 
 	/* Add default route */
 	nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, 0, 0, metric);
-	g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, 0, 0, gateway, 0, metric, mss));
+	nmtstp_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, 0, 0, gateway, 0, metric, mss);
 	nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, 0, 0, metric);
 	accept_signal (route_added);
 
 	/* Add default route again */
-	g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, 0, 0, gateway, 0, metric, mss));
+	nmtstp_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, 0, 0, gateway, 0, metric, mss);
 	accept_signals (route_changed, 0, 1);
 
 	/* Test route listing */
@@ -222,6 +222,14 @@ test_ip4_route (void)
 	/* Remove route again */
 	g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric));
 
+	/* Remove default route */
+	g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, 0, 0, metric));
+	accept_signal (route_removed);
+
+	/* Remove route to gateway */
+	g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, gateway, 32, metric));
+	accept_signal (route_removed);
+
 	free_signal (route_added);
 	free_signal (route_changed);
 	free_signal (route_removed);
@@ -238,36 +246,55 @@ test_ip6_route (void)
 	NMPlatformIP6Route rts[3];
 	struct in6_addr network;
 	guint8 plen = 64;
-	struct in6_addr gateway;
+	struct in6_addr gateway, pref_src;
 	/* Choose a high metric so that we hopefully don't conflict. */
 	int metric = 22987;
 	int mss = 1000;
 
 	inet_pton (AF_INET6, "2001:db8:a:b:0:0:0:0", &network);
 	inet_pton (AF_INET6, "2001:db8:c:d:1:2:3:4", &gateway);
+	inet_pton (AF_INET6, "::42", &pref_src);
+
+	g_assert (nm_platform_ip6_address_add (NM_PLATFORM_GET, ifindex, pref_src, 128, in6addr_any,
+	                                       NM_PLATFORM_LIFETIME_PERMANENT, NM_PLATFORM_LIFETIME_PERMANENT, 0));
+	accept_signals (route_added, 0, 1);
+
+	/* Wait that the address becomes non-tentative.  Dummy interfaces are NOARP
+	 * and thus don't do DAD, but the kernel sets the address as tentative for a
+	 * small amount of time, which prevents the immediate addition of the route
+	 * with RTA_PREFSRC */
+	NMTST_WAIT_ASSERT (200, {
+		const NMPlatformIP6Address *plt_addr;
+
+		nmtstp_wait_for_signal (NM_PLATFORM_GET, 50);
+		nm_platform_process_events (NM_PLATFORM_GET);
+		plt_addr = nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, pref_src, 128);
+		if (plt_addr && !NM_FLAGS_HAS (plt_addr->n_ifa_flags, IFA_F_TENTATIVE))
+			break;
+	});
 
 	/* Add route to gateway */
-	g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, gateway, 128, in6addr_any, metric, mss));
+	nmtstp_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, gateway, 128, in6addr_any, in6addr_any, metric, mss);
 	accept_signal (route_added);
 
 	/* Add route */
 	g_assert (!nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric));
-	g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, metric, mss));
+	nmtstp_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, pref_src, metric, mss);
 	g_assert (nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric));
 	accept_signal (route_added);
 
 	/* Add route again */
-	g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, metric, mss));
+	nmtstp_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, pref_src, metric, mss);
 	accept_signals (route_changed, 0, 1);
 
 	/* Add default route */
 	g_assert (!nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, in6addr_any, 0, metric));
-	g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, in6addr_any, 0, gateway, metric, mss));
+	nmtstp_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, in6addr_any, 0, gateway, in6addr_any, metric, mss);
 	g_assert (nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, in6addr_any, 0, metric));
 	accept_signal (route_added);
 
 	/* Add default route again */
-	g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, in6addr_any, 0, gateway, metric, mss));
+	nmtstp_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, in6addr_any, 0, gateway, in6addr_any, metric, mss);
 	accept_signals (route_changed, 0, 1);
 
 	/* Test route listing */
@@ -278,6 +305,7 @@ test_ip6_route (void)
 	rts[0].plen = 128;
 	rts[0].ifindex = ifindex;
 	rts[0].gateway = in6addr_any;
+	rts[0].pref_src = in6addr_any;
 	rts[0].metric = nm_utils_ip6_route_metric_normalize (metric);
 	rts[0].mss = mss;
 	rts[1].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
@@ -285,6 +313,7 @@ test_ip6_route (void)
 	rts[1].plen = plen;
 	rts[1].ifindex = ifindex;
 	rts[1].gateway = gateway;
+	rts[1].pref_src = pref_src;
 	rts[1].metric = nm_utils_ip6_route_metric_normalize (metric);
 	rts[1].mss = mss;
 	rts[2].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
@@ -292,6 +321,7 @@ test_ip6_route (void)
 	rts[2].plen = 0;
 	rts[2].ifindex = ifindex;
 	rts[2].gateway = gateway;
+	rts[2].pref_src = in6addr_any;
 	rts[2].metric = nm_utils_ip6_route_metric_normalize (metric);
 	rts[2].mss = mss;
 	g_assert_cmpint (routes->len, ==, 3);
@@ -306,6 +336,14 @@ test_ip6_route (void)
 	/* Remove route again */
 	g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric));
 
+	/* Remove default route */
+	g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, in6addr_any, 0, metric));
+	accept_signal (route_removed);
+
+	/* Remove route to gateway */
+	g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, gateway, 128, metric));
+	accept_signal (route_removed);
+
 	free_signal (route_added);
 	free_signal (route_changed);
 	free_signal (route_removed);
@@ -334,6 +372,114 @@ test_ip4_zero_gateway (void)
 	nm_platform_process_events (NM_PLATFORM_GET);
 }
 
+static void
+test_ip4_route_options (void)
+{
+	int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
+	NMPlatformIP4Route route = { };
+	in_addr_t network;
+	GArray *routes;
+	NMPlatformIP4Route rts[1];
+
+	inet_pton (AF_INET, "172.16.1.0", &network);
+
+	route.ifindex = ifindex;
+	route.rt_source = NM_IP_CONFIG_SOURCE_USER;
+	route.network = network;
+	route.plen = 24;
+	route.metric = 20;
+	route.tos = 0x28;
+	route.window = 10000;
+	route.cwnd = 16;
+	route.initcwnd = 30;
+	route.initrwnd = 50;
+	route.mtu = 1350;
+	route.lock_cwnd = TRUE;
+
+	g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, &route));
+
+	/* Test route listing */
+	routes = nm_platform_ip4_route_get_all (NM_PLATFORM_GET, ifindex,
+	                                        NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT |
+	                                        NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT);
+	memset (rts, 0, sizeof (rts));
+	rts[0].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
+	rts[0].scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK);
+	rts[0].network = network;
+	rts[0].plen = 24;
+	rts[0].ifindex = ifindex;
+	rts[0].metric = 20;
+	rts[0].tos = 0x28;
+	rts[0].window = 10000;
+	rts[0].cwnd = 16;
+	rts[0].initcwnd = 30;
+	rts[0].initrwnd = 50;
+	rts[0].mtu = 1350;
+	rts[0].lock_cwnd = TRUE;
+
+	g_assert_cmpint (routes->len, ==, 1);
+	nmtst_platform_ip4_routes_equal ((NMPlatformIP4Route *) routes->data, rts, routes->len, TRUE);
+
+	/* Remove route */
+	g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, 24, 20));
+
+	g_array_unref (routes);
+}
+
+
+static void
+test_ip6_route_options (void)
+{
+	int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
+	NMPlatformIP6Route route = { };
+	struct in6_addr network;
+	GArray *routes;
+	NMPlatformIP6Route rts[3];
+
+	inet_pton (AF_INET6, "2001:db8:a:b:0:0:0:0", &network);
+
+	route.ifindex = ifindex;
+	route.rt_source = NM_IP_CONFIG_SOURCE_USER;
+	route.network = network;
+	route.plen = 64;
+	route.gateway = in6addr_any;
+	route.metric = 1024;
+	route.window = 20000;
+	route.cwnd = 8;
+	route.initcwnd = 22;
+	route.initrwnd = 33;
+	route.mtu = 1300;
+	route.lock_mtu = TRUE;
+
+	g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, &route));
+
+	/* Test route listing */
+	routes = nm_platform_ip6_route_get_all (NM_PLATFORM_GET, ifindex,
+	                                        NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT |
+	                                        NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT);
+	memset (rts, 0, sizeof (rts));
+	rts[0].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
+	rts[0].network = network;
+	rts[0].plen = 64;
+	rts[0].ifindex = ifindex;
+	rts[0].gateway = in6addr_any;
+	rts[0].metric = 1024;
+	rts[0].window = 20000;
+	rts[0].cwnd = 8;
+	rts[0].initcwnd = 22;
+	rts[0].initrwnd = 33;
+	rts[0].mtu = 1300;
+	rts[0].lock_mtu = TRUE;
+
+	g_assert_cmpint (routes->len, ==, 1);
+	nmtst_platform_ip6_routes_equal ((NMPlatformIP6Route *) routes->data, rts, routes->len, TRUE);
+
+	/* Remove route */
+	g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, network, 64, 1024));
+
+	g_array_unref (routes);
+}
+
 /*****************************************************************************/
 
 NMTstpSetupFunc const _nmtstp_setup_platform_func = SETUP;
@@ -360,6 +506,8 @@ _nmtstp_setup_tests (void)
 	g_test_add_func ("/route/ip4", test_ip4_route);
 	g_test_add_func ("/route/ip6", test_ip6_route);
 	g_test_add_func ("/route/ip4_metric0", test_ip4_route_metric0);
+	g_test_add_func ("/route/ip4_options", test_ip4_route_options);
+	g_test_add_func ("/route/ip6_options", test_ip6_route_options);
 
 	if (nmtstp_is_root_test ())
 		g_test_add_func ("/route/ip4_zero_gateway", test_ip4_zero_gateway);