summaryrefslogtreecommitdiff
path: root/src/platform/tests
diff options
context:
space:
mode:
Diffstat (limited to 'src/platform/tests')
-rw-r--r--src/platform/tests/test-cleanup.c33
-rw-r--r--src/platform/tests/test-common.c414
-rw-r--r--src/platform/tests/test-common.h70
-rw-r--r--src/platform/tests/test-link.c187
-rw-r--r--src/platform/tests/test-route.c200
5 files changed, 792 insertions, 112 deletions
diff --git a/src/platform/tests/test-cleanup.c b/src/platform/tests/test-cleanup.c
index 3b52487a56..15af4909c7 100644
--- a/src/platform/tests/test-cleanup.c
+++ b/src/platform/tests/test-cleanup.c
@@ -33,26 +33,21 @@ test_cleanup_internal (void)
GArray *addresses6;
GArray *routes4;
GArray *routes6;
- in_addr_t addr4;
- in_addr_t network4;
int plen4 = 24;
- in_addr_t gateway4;
- struct in6_addr addr6;
- struct in6_addr network6;
int plen6 = 64;
- struct in6_addr gateway6;
int lifetime = NM_PLATFORM_LIFETIME_PERMANENT;
int preferred = NM_PLATFORM_LIFETIME_PERMANENT;
int metric = 20;
int mss = 1000;
guint32 flags = 0;
-
- inet_pton (AF_INET, "192.0.2.1", &addr4);
- inet_pton (AF_INET, "192.0.3.0", &network4);
- inet_pton (AF_INET, "198.51.100.1", &gateway4);
- inet_pton (AF_INET6, "2001:db8:a:b:1:2:3:4", &addr6);
- inet_pton (AF_INET6, "2001:db8:c:d:0:0:0:0", &network6);
- inet_pton (AF_INET6, "2001:db8:e:f:1:2:3:4", &gateway6);
+ const char *const ADDR4 = "192.0.2.1";
+ const char *const NETWORK4 = "192.0.3.0";
+ const char *const GATEWAY4 = "198.51.100.1";
+ const char *const ADDR6 = "2001:db8:a:b:1:2:3:4";
+ const char *const NETWORK6 = "2001:db8:c:d:0:0:0:0";
+ const char *const GATEWAY6 = "2001:db8:e:f:1:2:3:4";
+ const guint32 addr4 = nmtst_inet4_from_string (ADDR4);
+ const struct in6_addr addr6 = *nmtst_inet6_from_string (ADDR6);
/* Create and set up device */
g_assert (nm_platform_link_dummy_add (NM_PLATFORM_GET, DEVICE_NAME, NULL) == NM_PLATFORM_ERROR_SUCCESS);
@@ -65,12 +60,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));
+ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, nmtst_platform_ip4_route_full (ifindex, GATEWAY4, 32, NULL, NM_IP_CONFIG_SOURCE_USER, metric, mss, 0, FALSE, NULL)));
+ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, nmtst_platform_ip4_route_full (ifindex, NETWORK4, plen4, GATEWAY4, NM_IP_CONFIG_SOURCE_USER, metric, mss, 0, FALSE, NULL)));
+ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, nmtst_platform_ip4_route_full (ifindex, NULL, 0, GATEWAY4, NM_IP_CONFIG_SOURCE_USER, metric, mss, 0, FALSE, NULL)));
+ g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, nmtst_platform_ip6_route_full (ifindex, GATEWAY6, 128, NULL, NM_IP_CONFIG_SOURCE_USER, metric, mss)));
+ g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, nmtst_platform_ip6_route_full (ifindex, NETWORK6, plen6, GATEWAY6, NM_IP_CONFIG_SOURCE_USER, metric, mss)));
+ g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, nmtst_platform_ip6_route_full (ifindex, NULL, 0, GATEWAY6, NM_IP_CONFIG_SOURCE_USER, 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 b1947a6d11..2177d58252 100644
--- a/src/platform/tests/test-common.c
+++ b/src/platform/tests/test-common.c
@@ -25,6 +25,9 @@
#include <sys/wait.h>
#include <fcntl.h>
+#include "nm-platform-utils.h"
+#include "nmp-object.h"
+
#include "test-common.h"
#define SIGNAL_DATA_FMT "'%s-%s' ifindex %d%s%s%s (%d times received)"
@@ -196,8 +199,156 @@ link_callback (NMPlatform *platform, NMPObjectType obj_type, int ifindex, NMPlat
/*****************************************************************************/
+static int
+_sort_routes (gconstpointer p_a, gconstpointer p_b, gpointer user_data)
+{
+ gboolean is_v4 = GPOINTER_TO_INT (user_data);
+
+ if (is_v4)
+ return nm_platform_ip4_route_cmp (p_a, p_b);
+ else
+ return nm_platform_ip6_route_cmp (p_a, p_b);
+}
+
+const NMPlatformIPXRoute **
+nmtstp_ip_route_get_by_destination (NMPlatform *platform,
+ gboolean is_v4,
+ int ifindex,
+ const NMIPAddr *network,
+ guint8 plen,
+ guint32 metric,
+ const NMIPAddr *gateway,
+ guint *out_len)
+{
+ gs_unref_array GArray *routes = NULL;
+ GPtrArray *result = NULL;
+ gs_unref_hashtable GHashTable *check_dupes = NULL;
+ NMIPAddr network_clean;
+ guint i;
+
+ g_assert (ifindex >= 0);
+ g_assert (plen >= 0 && plen <= (is_v4 ? 32 : 128));
+
+ NM_SET_OUT (out_len, 0);
+
+ _init_platform (&platform, FALSE);
+
+ check_dupes = g_hash_table_new ((GHashFunc) nmp_object_id_hash, (GEqualFunc) nmp_object_id_equal);
+ result = g_ptr_array_new ();
+
+ network = nm_utils_ipx_address_clear_host_address (is_v4 ? AF_INET : AF_INET6,
+ &network_clean,
+ network ?: &nm_ip_addr_zero,
+ plen);
+
+ if (!is_v4)
+ metric = nm_utils_ip6_route_metric_normalize (metric);
+
+ if (is_v4)
+ routes = nm_platform_ip4_route_get_all (platform, ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_RTPROT_KERNEL);
+ else
+ routes = nm_platform_ip6_route_get_all (platform, ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_RTPROT_KERNEL);
+
+ for (i = 0; routes && i < routes->len; i++) {
+ const NMPlatformIPXRoute *r_i = is_v4
+ ? (NMPlatformIPXRoute *) &g_array_index (routes, NMPlatformIP4Route, i)
+ : (NMPlatformIPXRoute *) &g_array_index (routes, NMPlatformIP6Route, i);
+ const NMPlatformIPXRoute *r_2;
+ const NMPObject *o_2;
+
+ g_assert (r_i->rx.ifindex == ifindex);
+
+ if ( r_i->rx.plen != plen
+ || r_i->rx.metric != metric)
+ continue;
+
+ if (is_v4) {
+ if (r_i->r4.network != *((guint32 *) network))
+ continue;
+ if ( gateway
+ && r_i->r4.gateway != *((guint32 *) gateway))
+ continue;
+ } else {
+ if (!IN6_ARE_ADDR_EQUAL (&r_i->r6.network, network))
+ continue;
+ if ( gateway
+ && !IN6_ARE_ADDR_EQUAL (&r_i->r6.gateway, gateway))
+ continue;
+ }
+
+ r_2 = is_v4
+ ? (NMPlatformIPXRoute *) nm_platform_ip4_route_get (platform, &r_i->r4)
+ : (NMPlatformIPXRoute *) nm_platform_ip6_route_get (platform, &r_i->r6);
+ g_assert (r_2);
+ g_assert ( ( is_v4 && nm_platform_ip4_route_cmp (&r_i->r4, &r_2->r4) == 0)
+ || (!is_v4 && nm_platform_ip6_route_cmp (&r_i->r6, &r_2->r6) == 0));
+
+ o_2 = NMP_OBJECT_UP_CAST (r_2);
+ g_assert (NMP_OBJECT_IS_VALID (o_2));
+ g_assert (NMP_OBJECT_GET_TYPE (o_2) == (is_v4 ? NMP_OBJECT_TYPE_IP4_ROUTE : NMP_OBJECT_TYPE_IP6_ROUTE));
+
+ g_ptr_array_add (result, (gpointer) r_2);
+ if (!nm_g_hash_table_add (check_dupes, (gpointer) o_2))
+ g_assert_not_reached ();
+ }
+
+ /* check whether the multi-index of the platform cache agrees... */
+ if (NM_IS_LINUX_PLATFORM (platform)) {
+ const NMPlatformObject *const *routes_cached;
+ NMPCacheId cache_id;
+ guint len;
+
+ if (is_v4)
+ nmp_cache_id_init_routes_by_destination_ip4 (&cache_id, network->addr4, plen, metric);
+ else
+ nmp_cache_id_init_routes_by_destination_ip6 (&cache_id, &network->addr6, plen, metric);
+
+ routes_cached = nm_linux_platform_lookup (platform, &cache_id, &len);
+
+ if (len)
+ g_assert (routes_cached && routes_cached[len] == NULL);
+ else
+ g_assert (!routes_cached);
+
+ for (i =0; routes_cached && i < len; i++) {
+ const NMPObject *o;
+ const NMPObject *o_2;
+
+ g_assert (routes_cached [i]);
+ o = NMP_OBJECT_UP_CAST (routes_cached [i]);
+ g_assert (NMP_OBJECT_IS_VALID (o));
+ g_assert (NMP_OBJECT_GET_TYPE (o) == (is_v4 ? NMP_OBJECT_TYPE_IP4_ROUTE : NMP_OBJECT_TYPE_IP6_ROUTE));
+
+ if (gateway) {
+ if ( ( is_v4 && o->ip4_route.gateway != *((guint32 *) gateway))
+ || (!is_v4 && !IN6_ARE_ADDR_EQUAL (&o->ip6_route.gateway, gateway)))
+ continue;
+ }
+
+ o_2 = g_hash_table_lookup (check_dupes, o);
+ g_assert (o_2);
+ g_assert (o_2 == o);
+
+ if (!g_hash_table_remove (check_dupes, o))
+ g_assert_not_reached ();
+ }
+
+ g_assert (g_hash_table_size (check_dupes) == 0);
+ }
+
+ if (result->len > 0) {
+ g_ptr_array_sort_with_data (result, _sort_routes, GINT_TO_POINTER (!!is_v4));
+ NM_SET_OUT (out_len, result->len);
+ g_ptr_array_add (result, NULL);
+ return (gpointer) g_ptr_array_free (result, FALSE);
+ }
+ g_ptr_array_unref (result);
+ return NULL;
+}
+
+
gboolean
-nmtstp_ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 metric)
+nmtstp_ip4_route_exists (const char *ifname, guint32 network, guint8 plen, guint32 metric, const guint32 *gateway)
{
gs_free char *arg_network = NULL;
const char *argv[] = {
@@ -216,6 +367,7 @@ nmtstp_ip4_route_exists (const char *ifname, guint32 network, int plen, guint32
gboolean success;
gs_free_error GError *error = NULL;
gs_free char *metric_pattern = NULL;
+ gs_free char *via_pattern = NULL;
g_assert (ifname && nm_utils_iface_valid_name (ifname));
g_assert (!strstr (ifname, " metric "));
@@ -253,6 +405,7 @@ nmtstp_ip4_route_exists (const char *ifname, guint32 network, int plen, guint32
g_assert (std_out);
metric_pattern = g_strdup_printf (" metric %u", metric);
+ via_pattern = gateway ? g_strdup_printf (" via %s", nm_utils_inet4_ntop (*gateway, NULL)) : NULL;
out = std_out;
while (out) {
char *eol = strchr (out, '\n');
@@ -264,44 +417,93 @@ nmtstp_ip4_route_exists (const char *ifname, guint32 network, int plen, guint32
continue;
if (metric == 0) {
- if (!strstr (line, " metric "))
- return TRUE;
+ if (strstr (line, " metric "))
+ continue;
+ } else {
+ p = strstr (line, metric_pattern);
+ if (!p || !NM_IN_SET (p[strlen (metric_pattern)], ' ', '\0'))
+ continue;
+ }
+
+ if (gateway) {
+ if (*gateway == 0) {
+ if (strstr (line, " via "))
+ continue;
+ } else {
+ p = strstr (line, via_pattern);
+ if (!p || !NM_IN_SET (p[strlen (via_pattern)], ' ', '\0'))
+ continue;
+ }
}
- p = strstr (line, metric_pattern);
- if (p && NM_IN_SET (p[strlen (metric_pattern)], ' ', '\0'))
- return TRUE;
+ return TRUE;
}
return FALSE;
}
-void
-_nmtstp_assert_ip4_route_exists (const char *file, guint line, const char *func, NMPlatform *platform, gboolean exists, const char *ifname, guint32 network, int plen, guint32 metric)
+const NMPlatformIP4Route *
+_nmtstp_assert_ip4_route_exists (const char *file,
+ guint line,
+ const char *func,
+ NMPlatform *platform,
+ gboolean exists,
+ const char *ifname,
+ guint32 network,
+ guint8 plen,
+ guint32 metric,
+ const guint32 *gateway)
{
int ifindex;
gboolean exists_checked;
+ char s_buf[NM_UTILS_INET_ADDRSTRLEN];
+ gs_free const NMPlatformIP4Route **routes = NULL;
+ guint len;
_init_platform (&platform, FALSE);
/* Check for existance of the route by spawning iproute2. Do this because platform
* code might be entirely borked, but we expect ip-route to give a correct result.
* If the ip command cannot be found, we accept this as success. */
- exists_checked = nmtstp_ip4_route_exists (ifname, network, plen, metric);
+ exists_checked = nmtstp_ip4_route_exists (ifname, network, plen, metric, gateway);
if (exists_checked != -1 && !exists_checked != !exists) {
- g_error ("[%s:%u] %s(): We expect the ip4 route %s/%d metric %u %s, but it %s",
+ g_error ("[%s:%u] %s(): We expect the ip4 route %s/%d%s metric %u %s, but it %s",
file, line, func,
- nm_utils_inet4_ntop (network, NULL), plen, metric,
+ nm_utils_inet4_ntop (network, NULL), plen,
+ gateway ? nm_sprintf_bufa (100, " gateway %s", nm_utils_inet4_ntop (*gateway, s_buf)) : " no-gateway",
+ metric,
exists ? "to exist" : "not to exist",
exists ? "doesn't" : "does");
}
ifindex = nm_platform_link_get_ifindex (platform, ifname);
g_assert (ifindex > 0);
- if (!nm_platform_ip4_route_get (platform, ifindex, network, plen, metric) != !exists) {
- g_error ("[%s:%u] %s(): The ip4 route %s/%d metric %u %s, but platform thinks %s",
- file, line, func,
- nm_utils_inet4_ntop (network, NULL), plen, metric,
- exists ? "exists" : "does not exist",
- exists ? "it doesn't" : "it does");
+
+ routes = (gpointer) nmtstp_ip_route_get_by_destination (platform, TRUE, ifindex, (NMIPAddr *) &network,
+ plen, metric, (NMIPAddr *) gateway, &len);
+ if (routes) {
+ if (!exists) {
+ g_error ("[%s:%u] %s(): The ip4 route %s/%d via %s metric %u %s, but platform thinks %s",
+ file, line, func,
+ nm_utils_inet4_ntop (network, NULL),
+ plen,
+ nm_utils_inet4_ntop (gateway ? *gateway : 0, s_buf),
+ metric,
+ exists ? "exists" : "does not exist",
+ exists ? "it doesn't" : "it does");
+ }
+ g_assert (len == 1);
+ return routes[0];
+ } else {
+ if (exists) {
+ g_error ("[%s:%u] %s(): The ip4 route %s/%d via %s metric %u %s, but platform thinks %s",
+ file, line, func,
+ nm_utils_inet4_ntop (network, NULL),
+ plen,
+ nm_utils_inet4_ntop (gateway ? *gateway : 0, s_buf),
+ metric,
+ exists ? "exists" : "does not exist",
+ exists ? "it doesn't" : "it does");
+ }
+ return NULL;
}
}
@@ -414,7 +616,7 @@ 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, guint 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, nm_utils_get_monotonic_timestamp_ms () + (gint64) timeout_ms);
}
const NMPlatformLink *
@@ -443,7 +645,7 @@ nmtstp_wait_for_link_until (NMPlatform *platform, const char *ifname, NMLinkType
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);
+ return nmtstp_assert_wait_for_link_until (platform, ifname, expected_link_type, nm_utils_get_monotonic_timestamp_ms () + (gint64) timeout_ms);
}
const NMPlatformLink *
@@ -458,6 +660,55 @@ nmtstp_assert_wait_for_link_until (NMPlatform *platform, const char *ifname, NML
/*****************************************************************************/
+static const void *
+_wait_for_ip_route_until (NMPlatform *platform, int is_v4, int ifindex, const NMIPAddr *network, guint8 plen, guint32 metric, const NMIPAddr *gateway, gint64 until_ms)
+{
+ gint64 now;
+
+ _init_platform (&platform, FALSE);
+
+ while (TRUE) {
+ gs_free const NMPlatformIPXRoute **routes = NULL;
+
+ now = nm_utils_get_monotonic_timestamp_ms ();
+
+ routes = nmtstp_ip_route_get_by_destination (platform, is_v4, ifindex, network, plen, metric, gateway, NULL);
+ if (routes)
+ return routes[0];
+
+ if (until_ms < now)
+ return NULL;
+
+ nmtstp_wait_for_signal (platform, MAX (1, until_ms - now));
+ }
+}
+
+const NMPlatformIP4Route *
+nmtstp_wait_for_ip4_route (NMPlatform *platform, int ifindex, guint32 network, guint8 plen, guint32 metric, guint32 gateway, guint timeout_ms)
+{
+ return _wait_for_ip_route_until (platform, TRUE, ifindex, (NMIPAddr *) &network, plen, metric, (NMIPAddr *) &gateway, nm_utils_get_monotonic_timestamp_ms () + (gint64) timeout_ms);
+}
+
+const NMPlatformIP4Route *
+nmtstp_wait_for_ip4_route_until (NMPlatform *platform, int ifindex, guint32 network, guint8 plen, guint32 metric, guint32 gateway, gint64 until_ms)
+{
+ return _wait_for_ip_route_until (platform, TRUE, ifindex, (NMIPAddr *) &network, plen, metric, (NMIPAddr *) &gateway, until_ms);
+}
+
+const NMPlatformIP6Route *
+nmtstp_wait_for_ip6_route (NMPlatform *platform, int ifindex, const struct in6_addr *network, guint8 plen, guint32 metric, const struct in6_addr *gateway, guint timeout_ms)
+{
+ return _wait_for_ip_route_until (platform, FALSE, ifindex, (NMIPAddr *) network, plen, metric, (NMIPAddr *) gateway, nm_utils_get_monotonic_timestamp_ms () + (gint64) timeout_ms);
+}
+
+const NMPlatformIP6Route *
+nmtstp_wait_for_ip6_route_until (NMPlatform *platform, int ifindex, const struct in6_addr *network, guint8 plen, guint32 metric, const struct in6_addr *gateway, gint64 until_ms)
+{
+ return _wait_for_ip_route_until (platform, FALSE, ifindex, (NMIPAddr *) network, plen, metric, (NMIPAddr *) gateway, until_ms);
+}
+
+/*****************************************************************************/
+
int
nmtstp_run_command_check_external_global (void)
{
@@ -592,7 +843,7 @@ _ip_address_add (NMPlatform *platform,
gboolean is_v4,
int ifindex,
const NMIPAddr *address,
- int plen,
+ guint8 plen,
const NMIPAddr *peer_address,
guint32 lifetime,
guint32 preferred,
@@ -730,7 +981,7 @@ nmtstp_ip4_address_add (NMPlatform *platform,
gboolean external_command,
int ifindex,
in_addr_t address,
- int plen,
+ guint8 plen,
in_addr_t peer_address,
guint32 lifetime,
guint32 preferred,
@@ -755,7 +1006,7 @@ nmtstp_ip6_address_add (NMPlatform *platform,
gboolean external_command,
int ifindex,
struct in6_addr address,
- int plen,
+ guint8 plen,
struct in6_addr peer_address,
guint32 lifetime,
guint32 preferred,
@@ -782,7 +1033,7 @@ _ip_address_del (NMPlatform *platform,
gboolean is_v4,
int ifindex,
const NMIPAddr *address,
- int plen,
+ guint8 plen,
const NMIPAddr *peer_address)
{
gint64 end_time;
@@ -873,7 +1124,7 @@ nmtstp_ip4_address_del (NMPlatform *platform,
gboolean external_command,
int ifindex,
in_addr_t address,
- int plen,
+ guint8 plen,
in_addr_t peer_address)
{
_ip_address_del (platform,
@@ -890,7 +1141,7 @@ nmtstp_ip6_address_del (NMPlatform *platform,
gboolean external_command,
int ifindex,
struct in6_addr address,
- int plen)
+ guint8 plen)
{
_ip_address_del (platform,
external_command,
@@ -903,6 +1154,119 @@ nmtstp_ip6_address_del (NMPlatform *platform,
/*****************************************************************************/
+static gconstpointer
+_ip_route_add (NMPlatform *platform,
+ gboolean external_command,
+ gboolean is_v4,
+ const NMPlatformIPXRoute *route)
+{
+ gint64 end_time;
+ char s_network[NM_UTILS_INET_ADDRSTRLEN];
+ char s_gateway[NM_UTILS_INET_ADDRSTRLEN];
+ char s_pref_src[NM_UTILS_INET_ADDRSTRLEN];
+ const NMPlatformLink *pllink;
+ NMPObject obj_normalized;
+ const NMPlatformIPXRoute *route_orig;
+ guint i, len;
+
+ g_assert (route);
+ g_assert (route->rx.ifindex > 0);
+
+ external_command = nmtstp_run_command_check_external (external_command);
+
+ _init_platform (&platform, external_command);
+
+ route_orig = route;
+ if (is_v4)
+ nmp_object_stackinit_id_ip4_route (&obj_normalized, &route->r4, NM_PLATFORM_IP_ROUTE_ID_TYPE_ID);
+ else
+ nmp_object_stackinit_id_ip6_route (&obj_normalized, &route->r6, NM_PLATFORM_IP_ROUTE_ID_TYPE_ID);
+ route = &obj_normalized.ipx_route;
+
+ pllink = nmtstp_link_get (platform, route->rx.ifindex, NULL);
+ g_assert (pllink);
+
+ if (external_command) {
+ s_network[0] = '\0';
+ s_gateway[0] = '\0';
+ s_pref_src[0] = '\0';
+ if (is_v4) {
+ nm_utils_inet4_ntop (route->r4.network, s_network);
+ if (route->r4.gateway)
+ nm_utils_inet4_ntop (route->r4.gateway, s_gateway);
+ if (route->r4.pref_src)
+ nm_utils_inet4_ntop (route->r4.pref_src, s_pref_src);
+ } else {
+ nm_utils_inet6_ntop (&route->r6.network, s_network);
+ if (!IN6_IS_ADDR_UNSPECIFIED (&route->r6.gateway))
+ nm_utils_inet6_ntop (&route->r6.gateway, s_gateway);
+ }
+
+ nmtstp_run_command_check ("ip route append %s/%u%s dev '%s' metric %u proto %u%s%s",
+ s_network,
+ route->rx.plen,
+ s_gateway[0] ? nm_sprintf_bufa (100, " via %s", s_gateway) : "",
+ pllink->name,
+ route->rx.metric,
+ nmp_utils_ip_config_source_coerce_to_rtprot (route->r4.rt_source),
+ s_pref_src[0] ? nm_sprintf_bufa (100, " src %s", s_pref_src) : "",
+ route->rx.mss ? nm_sprintf_bufa (100, " advmss %u", route->rx.mss) : "");
+ } else {
+ gboolean success;
+
+ if (is_v4)
+ success = nm_platform_ip4_route_add (platform, &route_orig->r4);
+ else
+ success = nm_platform_ip6_route_add (platform, &route_orig->r6);
+ g_assert (success);
+ }
+
+ /* Let's wait until we see the address. */
+ end_time = nm_utils_get_monotonic_timestamp_ms () + 250;
+ do {
+ gs_free const NMPlatformIPXRoute **routes = NULL;
+
+ if (external_command)
+ nm_platform_process_events (platform);
+
+ /* let's wait until we see the address as we added it. */
+ routes = nmtstp_ip_route_get_by_destination (platform, is_v4, route->rx.ifindex,
+ (NMIPAddr *) route->rx.network_ptr,
+ route->rx.plen,
+ route->rx.metric,
+ is_v4 ? (NMIPAddr *) &route->r4.gateway : (NMIPAddr *) &route->r6.gateway,
+ &len);
+ for (i = 0; i < len; i++) {
+ const NMPObject *o2;
+
+ o2 = NMP_OBJECT_UP_CAST (routes[i]);
+ if (nmp_object_equal (o2, &obj_normalized))
+ return &o2->ipx_route;
+ }
+
+ /* for internal command, we expect not to reach this line.*/
+ g_assert (external_command);
+
+ nmtstp_assert_wait_for_signal_until (platform, end_time);
+ } while (TRUE);
+}
+
+const NMPlatformIP4Route *
+nmtstp_ip4_route_add (NMPlatform *platform, gboolean external_command,
+ const NMPlatformIP4Route *route)
+{
+ return _ip_route_add (platform, external_command, TRUE, (const NMPlatformIPXRoute *) route);
+}
+
+const NMPlatformIP6Route *
+nmtstp_ip6_route_add (NMPlatform *platform, gboolean external_command,
+ const NMPlatformIP6Route *route)
+{
+ return _ip_route_add (platform, external_command, FALSE, (const NMPlatformIPXRoute *) route);
+}
+
+/*****************************************************************************/
+
#define _assert_pllink(platform, success, pllink, name, type) \
G_STMT_START { \
const NMPlatformLink *_pllink = (pllink); \
diff --git a/src/platform/tests/test-common.h b/src/platform/tests/test-common.h
index 0e3cf10ba4..c4c0e4abd7 100644
--- a/src/platform/tests/test-common.h
+++ b/src/platform/tests/test-common.h
@@ -109,6 +109,47 @@ const NMPlatformLink *nmtstp_wait_for_link_until (NMPlatform *platform, const ch
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);
+const NMPlatformIP4Route *nmtstp_wait_for_ip4_route (NMPlatform *platform, int ifindex, guint32 network, guint8 plen, guint32 metric, guint32 gateway, guint timeout_ms);
+const NMPlatformIP4Route *nmtstp_wait_for_ip4_route_until (NMPlatform *platform, int ifindex, guint32 network, guint8 plen, guint32 metric, guint32 gateway, gint64 until_ms);
+const NMPlatformIP6Route *nmtstp_wait_for_ip6_route (NMPlatform *platform, int ifindex, const struct in6_addr *network, guint8 plen, guint32 metric, const struct in6_addr *gateway, guint timeout_ms);
+const NMPlatformIP6Route *nmtstp_wait_for_ip6_route_until (NMPlatform *platform, int ifindex, const struct in6_addr *network, guint8 plen, guint32 metric, const struct in6_addr *gateway, gint64 until_ms);
+
+#define nmtstp_assert_wait_for_ip4_route(platform, ifindex, network, plen, metric, gateway, timeout_ms) \
+ ({ \
+ const NMPlatformIP4Route *_plroute; \
+ \
+ _plroute = nmtstp_wait_for_ip4_route (platform, ifindex, network, plen, metric, gateway, timeout_ms); \
+ g_assert (_plroute); \
+ _plroute; \
+ })
+
+#define nmtstp_assert_wait_for_ip4_route_until(platform, ifindex, network, plen, metric, gateway, until_ms) \
+ ({ \
+ const NMPlatformIP4Route *_plroute; \
+ \
+ _plroute = nmtstp_wait_for_ip4_route_until (platform, ifindex, network, plen, metric, gateway, until_ms); \
+ g_assert (_plroute); \
+ _plroute; \
+ })
+
+#define nmtstp_assert_wait_for_ip6_route(platform, ifindex, network, plen, metric, gateway, timeout_ms) \
+ ({ \
+ const NMPlatformIP6Route *_plroute; \
+ \
+ _plroute = nmtstp_wait_for_ip6_route (platform, ifindex, network, plen, metric, gateway, timeout_ms); \
+ g_assert (_plroute); \
+ _plroute; \
+ })
+
+#define nmtstp_assert_wait_for_ip6_route_until(platform, ifindex, network, plen, metric, gateway, until_ms) \
+ ({ \
+ const NMPlatformIP6Route *_plroute; \
+ \
+ _plroute = nmtstp_wait_for_ip6_route_until (platform, ifindex, network, plen, metric, gateway, until_ms); \
+ g_assert (_plroute); \
+ _plroute; \
+ })
+
/*****************************************************************************/
int nmtstp_run_command_check_external_global (void);
@@ -116,10 +157,19 @@ gboolean nmtstp_run_command_check_external (int external_command);
/*****************************************************************************/
-gboolean nmtstp_ip4_route_exists (const char *ifname, guint32 network, int plen, guint32 metric);
+const NMPlatformIPXRoute **nmtstp_ip_route_get_by_destination (NMPlatform *platform,
+ gboolean is_v4,
+ int ifindex,
+ const NMIPAddr *network,
+ guint8 plen,
+ guint32 metric,
+ const NMIPAddr *gateway,
+ guint *out_len);
+
+gboolean nmtstp_ip4_route_exists (const char *ifname, guint32 network, guint8 plen, guint32 metric, const guint32 *gateway);
-void _nmtstp_assert_ip4_route_exists (const char *file, guint line, const char *func, NMPlatform *platform, gboolean exists, const char *ifname, guint32 network, int plen, guint32 metric);
-#define nmtstp_assert_ip4_route_exists(platform, exists, ifname, network, plen, metric) _nmtstp_assert_ip4_route_exists (__FILE__, __LINE__, G_STRFUNC, platform, exists, ifname, network, plen, metric)
+const NMPlatformIP4Route *_nmtstp_assert_ip4_route_exists (const char *file, guint line, const char *func, NMPlatform *platform, gboolean exists, const char *ifname, guint32 network, guint8 plen, guint32 metric, const guint32 *gateway);
+#define nmtstp_assert_ip4_route_exists(platform, exists, ifname, network, plen, metric, gateway) _nmtstp_assert_ip4_route_exists (__FILE__, __LINE__, G_STRFUNC, platform, exists, ifname, network, plen, metric, gateway)
/*****************************************************************************/
@@ -136,7 +186,7 @@ void nmtstp_ip4_address_add (NMPlatform *platform,
gboolean external_command,
int ifindex,
in_addr_t address,
- int plen,
+ guint8 plen,
in_addr_t peer_address,
guint32 lifetime,
guint32 preferred,
@@ -146,7 +196,7 @@ void nmtstp_ip6_address_add (NMPlatform *platform,
gboolean external_command,
int ifindex,
struct in6_addr address,
- int plen,
+ guint8 plen,
struct in6_addr peer_address,
guint32 lifetime,
guint32 preferred,
@@ -155,13 +205,19 @@ void nmtstp_ip4_address_del (NMPlatform *platform,
gboolean external_command,
int ifindex,
in_addr_t address,
- int plen,
+ guint8 plen,
in_addr_t peer_address);
void nmtstp_ip6_address_del (NMPlatform *platform,
gboolean external_command,
int ifindex,
struct in6_addr address,
- int plen);
+ guint8 plen);
+
+const NMPlatformIP4Route *nmtstp_ip4_route_add (NMPlatform *platform, gboolean external_command,
+ const NMPlatformIP4Route *route);
+
+const NMPlatformIP6Route *nmtstp_ip6_route_add (NMPlatform *platform, gboolean external_command,
+ const NMPlatformIP6Route *route);
/*****************************************************************************/
diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c
index 9d548aabdb..258b6f3476 100644
--- a/src/platform/tests/test-link.c
+++ b/src/platform/tests/test-link.c
@@ -2292,6 +2292,188 @@ test_netns_bind_to_path (gpointer fixture, gconstpointer test_data)
/*****************************************************************************/
+static void
+test_route_external (gconstpointer user_data)
+{
+ const gboolean EX = (nmtst_get_rand_int () % 3) - 1;
+ const char *const MODE = user_data;
+ const char *IF[2] = { "IF0", "IF1" };
+ int ifindex[2];
+ const char *gateway[2] = {
+ "192.168.171.1",
+ "192.168.172.1",
+ };
+ gs_unref_object NMPlatform *pl = NULL;
+ int delete_idx;
+ gs_free const NMPlatformIPXRoute **routes = NULL;
+ guint routes_len;
+
+ g_object_unref (NM_PLATFORM_GET);
+
+ g_assert (NM_IN_STRSET (MODE, "change", "append"));
+
+ pl = nm_linux_platform_new (NM_PLATFORM_NETNS_SUPPORT_DEFAULT);
+
+ ifindex[0] = nmtstp_link_dummy_add (pl, EX, IF[0])->ifindex;
+ ifindex[1] = nmtstp_link_dummy_add (pl, EX, IF[1])->ifindex;
+ nmtstp_link_set_updown (pl, EX, ifindex[0], TRUE);
+ nmtstp_link_set_updown (pl, EX, ifindex[1], TRUE);
+
+ nmtstp_ip4_address_add (pl, EX, ifindex[0],
+ nmtst_inet4_from_string ("192.168.171.5"), 24,
+ nmtst_inet4_from_string ("192.168.171.5"),
+ NM_PLATFORM_LIFETIME_PERMANENT, NM_PLATFORM_LIFETIME_PERMANENT, 0, NULL);
+ nmtstp_ip4_address_add (pl, EX, ifindex[1],
+ nmtst_inet4_from_string ("192.168.172.5"), 24,
+ nmtst_inet4_from_string ("192.168.172.5"),
+ NM_PLATFORM_LIFETIME_PERMANENT, NM_PLATFORM_LIFETIME_PERMANENT, 0, NULL);
+
+#define ADDR4(addr_str) (nmtst_ip4_address_to_ptr (nmtst_inet4_from_string (addr_str)))
+
+ nmtstp_run_command_check ("ip route add 192.168.200.0/24 via %s metric 423", gateway[0]);
+ nmtstp_assert_wait_for_ip4_route (pl, ifindex[0], nmtst_inet4_from_string ("192.168.200.0"), 24,
+ 423, nmtst_inet4_from_string (gateway[0]), 100);
+
+ nmtstp_run_command_check ("ip route %s 192.168.200.0/24 via 192.168.172.1 metric 423", MODE);
+
+ if (NM_IN_STRSET (MODE, "changed")) {
+
+ nmtstp_assert_wait_for_ip4_route (pl, ifindex[1], nmtst_inet4_from_string ("192.168.200.0"), 24,
+ 423, nmtst_inet4_from_string (gateway[1]), 100);
+ /* is the route still on ifindex[0]? */
+ routes = nmtstp_ip_route_get_by_destination (pl, TRUE, ifindex[0],
+ ADDR4 ("192.168.200.0"), 24, 423,
+ ADDR4 (gateway[0]), NULL);
+ g_assert (!routes);
+ } else if (NM_IN_STRSET (MODE, "append")) {
+ nmtstp_assert_wait_for_ip4_route (pl, ifindex[1], nmtst_inet4_from_string ("192.168.200.0"), 24,
+ 423, nmtst_inet4_from_string (gateway[1]), 100);
+ /* the route on ifindex[0] should continue to exist */
+ routes = nmtstp_ip_route_get_by_destination (pl, TRUE, ifindex[0],
+ ADDR4 ("192.168.200.0"), 24, 423,
+ ADDR4 (gateway[0]), &routes_len);
+ g_assert (routes_len == 1);
+ g_clear_pointer (&routes, g_free);
+
+ delete_idx = nmtst_get_rand_int () % 2;
+
+ routes = nmtstp_ip_route_get_by_destination (pl, TRUE, ifindex[delete_idx],
+ ADDR4 ("192.168.200.0"), 24, 423,
+ ADDR4 (gateway[delete_idx]), &routes_len);
+ g_assert (routes_len == 1);
+ if (!nm_platform_ip4_route_delete (pl, &routes[0]->r4))
+ g_assert_not_reached ();
+ g_clear_pointer (&routes, g_free);
+
+ routes = nmtstp_ip_route_get_by_destination (pl, TRUE, ifindex[delete_idx],
+ ADDR4 ("192.168.200.0"), 24, 423,
+ ADDR4 (gateway[delete_idx]), &routes_len);
+ g_assert (!routes);
+
+ routes = nmtstp_ip_route_get_by_destination (pl, TRUE, ifindex[!delete_idx],
+ ADDR4 ("192.168.200.0"), 24, 423,
+ ADDR4 (gateway[!delete_idx]), &routes_len);
+ g_assert (routes_len == 1);
+ g_clear_pointer (&routes, g_free);
+ }
+
+ nmtstp_link_del (pl, EX, ifindex[0], IF[0]);
+ nmtstp_link_del (pl, EX, ifindex[1], IF[1]);
+
+ SETUP ();
+}
+
+/*****************************************************************************/
+
+static void
+test_route_modify (gconstpointer test_data)
+{
+#if 0
+ const char *const MODE = test_data;
+ const gboolean EX = (nmtst_get_rand_int () % 3) - 1;
+ const char *IF = "IF0";
+ int ifindex;
+ const char *gateway[2] = {
+ "192.168.181.1",
+ "192.168.181.2",
+ };
+ guint idx[2] = { 0, 1, };
+ guint i;
+ gs_unref_object NMPlatform *pl = NULL;
+
+ g_assert (NM_IN_STRSET (MODE, "delete", "update"));
+
+ g_object_unref (NM_PLATFORM_GET);
+
+ pl = nm_linux_platform_new (NM_PLATFORM_NETNS_SUPPORT_DEFAULT);
+
+ nmtst_rand_perm (NULL, idx, idx, sizeof (idx[0]), G_N_ELEMENTS (idx));
+
+ ifindex = nmtstp_link_dummy_add (pl, EX, IF)->ifindex;
+ nmtstp_link_set_updown (pl, EX, ifindex, TRUE);
+
+ nmtstp_ip4_address_add (pl, EX, ifindex,
+ nmtst_inet4_from_string ("192.168.181.5"), 24,
+ nmtst_inet4_from_string ("192.168.181.5"),
+ NM_PLATFORM_LIFETIME_PERMANENT, NM_PLATFORM_LIFETIME_PERMANENT, 0, NULL);
+
+ nmtstp_run_command_check ("ip route add 192.168.213.0/24 via %s metric 423", gateway[idx[0]]);
+ if (nmtst_get_rand_int () % 2) {
+ nmtstp_assert_wait_for_ip4_route (pl, ifindex, nmtst_inet4_from_string ("192.168.213.0"), 24,
+ 423, nmtst_inet4_from_string (gateway[idx[0]]), 100);
+ }
+
+ if (nmtst_get_rand_int () % 2) {
+ nmtstp_run_command_check ("ip route append 192.168.213.0/24 via %s metric 423", gateway[idx[1]]);
+ nmtstp_assert_wait_for_ip4_route (pl, ifindex, nmtst_inet4_from_string ("192.168.213.0"), 24,
+ 423, nmtst_inet4_from_string (gateway[idx[1]]), 100);
+ } else {
+ nmtstp_ip4_route_add (pl, EX, ifindex, NM_IP_CONFIG_SOURCE_RTPROT_BOOT,
+ nmtst_inet4_from_string ("192.168.213.0"), 24,
+ nmtst_inet4_from_string (gateway[idx[1]]), 0,
+ 423, 0);
+ }
+
+ g_assert (nm_platform_ip4_route_get (pl, ifindex,
+ nmtst_inet4_from_string ("192.168.213.0"), 24, 423,
+ nmtst_inet4_from_string (gateway[idx[0]])));
+ g_assert (nm_platform_ip4_route_get (pl, ifindex,
+ nmtst_inet4_from_string ("192.168.213.0"), 24, 423,
+ nmtst_inet4_from_string (gateway[idx[1]])));
+
+ nmtst_rand_perm (NULL, idx, idx, sizeof (idx[0]), G_N_ELEMENTS (idx));
+
+ for (i = 0; i < G_N_ELEMENTS (idx); i++) {
+ const NMPlatformIP4Route *plroute;
+
+ if (NM_IN_STRSET (MODE, "delete")) {
+ g_assert (nm_platform_ip4_route_delete (pl, ifindex,
+ nmtst_inet4_from_string ("192.168.213.0"), 24, 423,
+ nmtst_inet4_from_string (gateway[idx[i]])));
+ g_assert (!nm_platform_ip4_route_get (pl, ifindex,
+ nmtst_inet4_from_string ("192.168.213.0"), 24, 423,
+ nmtst_inet4_from_string (gateway[idx[i]])));
+
+ plroute = nm_platform_ip4_route_get (pl, ifindex,
+ nmtst_inet4_from_string ("192.168.213.0"), 24, 423,
+ nmtst_inet4_from_string (gateway[idx[!i]]));
+ g_assert ((i == 0 && plroute) || (i == 1 && !plroute));
+ } else if (NM_IN_STRSET (MODE, "update")) {
+ plroute = nmtstp_ip4_route_add (pl, FALSE, ifindex, NM_IP_CONFIG_SOURCE_USER,
+ nmtst_inet4_from_string ("192.168.213.0"), 24,
+ nmtst_inet4_from_string (gateway[idx[i]]), 0,
+ 423, 1400);
+ }
+ }
+
+ nmtstp_link_del (pl, EX, ifindex, IF);
+
+ SETUP ();
+#endif
+}
+
+/*****************************************************************************/
+
void
_nmtstp_init_tests (int *argc, char ***argv)
{
@@ -2335,6 +2517,11 @@ _nmtstp_setup_tests (void)
g_test_add_data_func ("/link/create-many-links/20", GUINT_TO_POINTER (20), test_create_many_links);
g_test_add_data_func ("/link/create-many-links/1000", GUINT_TO_POINTER (1000), test_create_many_links);
+ g_test_add_data_func ("/route/external/change", "change", test_route_external);
+ g_test_add_data_func ("/route/external/append", "append", test_route_external);
+ g_test_add_data_func ("/route/modify/delete", "delete", test_route_modify);
+ g_test_add_data_func ("/route/modify/update", "update", test_route_modify);
+
g_test_add_func ("/link/nl-bugs/veth", test_nl_bugs_veth);
g_test_add_func ("/link/nl-bugs/spurious-newlink", test_nl_bugs_spuroius_newlink);
g_test_add_func ("/link/nl-bugs/spurious-dellink", test_nl_bugs_spuroius_dellink);
diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c
index 360404e944..781d6d922b 100644
--- a/src/platform/tests/test-route.c
+++ b/src/platform/tests/test-route.c
@@ -76,56 +76,70 @@ test_ip4_route_metric0 (void)
SignalData *route_added = add_signal (NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip4_route_callback);
SignalData *route_changed = add_signal (NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, ip4_route_callback);
SignalData *route_removed = add_signal (NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip4_route_callback);
- in_addr_t network = nmtst_inet4_from_string ("192.0.2.5"); /* from 192.0.2.0/24 (TEST-NET-1) (rfc5737) */
+ const char *const NETWORK = "192.0.2.5"; /* from 192.0.2.0/24 (TEST-NET-1) (rfc5737) */
+ const guint32 network = nmtst_inet4_from_string (NETWORK);
int plen = 32;
int metric = 22987;
int mss = 1000;
+ NMPlatformIP4Route r = {
+ .ifindex = ifindex,
+ .network = network,
+ .plen = plen,
+ .rt_source = NM_IP_CONFIG_SOURCE_USER,
+ .metric = metric,
+ .mss = mss,
+ };
+ NMPlatformIP4Route r_metric0;
+
+ r_metric0 = r;
+ r_metric0.metric = 0;
/* No routes initially */
- nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0);
- nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric);
+ nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0, NULL);
+ nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric, NULL);
/* 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));
+
+ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, &r));
accept_signal (route_added);
- nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0);
- nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric);
+ nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0, NULL);
+ nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric, NULL);
/* Deleting route with metric 0 does nothing */
- g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0));
+ g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, &r_metric0));
ensure_no_signal (route_removed);
- nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0);
- nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric);
+ nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0, NULL);
+ nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric, NULL);
/* 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));
+ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, &r_metric0));
accept_signal (route_added);
- nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, 0);
- nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric);
+ nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, 0, NULL);
+ nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric, NULL);
/* Delete route with metric 0 */
- g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0));
+ g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, &r_metric0));
accept_signal (route_removed);
- nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0);
- nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric);
+ nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0, NULL);
+ nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric, NULL);
/* Delete route with metric 0 again (we expect nothing to happen) */
- g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0));
+ g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, &r_metric0));
ensure_no_signal (route_removed);
- nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0);
- nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric);
+ nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0, NULL);
+ nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric, NULL);
/* Delete the other route */
- g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric));
+ g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, &r));
accept_signal (route_removed);
- nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0);
- nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric);
+ nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0, NULL);
+ nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric, NULL);
free_signal (route_added);
free_signal (route_changed);
@@ -141,38 +155,61 @@ test_ip4_route (void)
SignalData *route_removed = add_signal (NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip4_route_callback);
GArray *routes;
NMPlatformIP4Route rts[3];
- in_addr_t network;
guint8 plen = 24;
- in_addr_t gateway;
/* Choose a high metric so that we hopefully don't conflict. */
int metric = 22986;
int mss = 1000;
-
- inet_pton (AF_INET, "192.0.3.0", &network);
- inet_pton (AF_INET, "198.51.100.1", &gateway);
+ const char *const NETWORK = "192.0.3.0";
+ const char *const GATEWAY = "198.51.100.1";
+ const guint32 network = nmtst_inet4_from_string (NETWORK);
+ const guint32 gateway = nmtst_inet4_from_string (GATEWAY);
+ NMPlatformIP4Route r = {
+ .ifindex = ifindex,
+ .network = network,
+ .plen = plen,
+ .gateway = gateway,
+ .metric = metric,
+ .mss = mss,
+ .rt_source = NM_IP_CONFIG_SOURCE_USER,
+ };
+ NMPlatformIP4Route r_gateway = {
+ .ifindex = ifindex,
+ .network = gateway,
+ .plen = 32,
+ .metric = metric,
+ .mss = mss,
+ .rt_source = NM_IP_CONFIG_SOURCE_USER,
+ };
+ NMPlatformIP4Route r_default = {
+ .ifindex = ifindex,
+ .gateway = gateway,
+ .metric = metric,
+ .mss = mss,
+ .rt_source = NM_IP_CONFIG_SOURCE_USER,
+ };
/* 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));
+ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, &r_gateway));
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_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric);
+ nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric, NULL);
+ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, &r));
+ nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric, NULL);
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));
+ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, &r));
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_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, 0, 0, metric);
+ nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, 0, 0, metric, NULL);
+ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, &r_default));
+ nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, 0, 0, metric, NULL);
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));
+ g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, &r_default));
accept_signals (route_changed, 0, 1);
/* Test route listing */
@@ -185,7 +222,8 @@ test_ip4_route (void)
rts[0].gateway = INADDR_ANY;
rts[0].metric = metric;
rts[0].mss = mss;
- rts[0].scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK);
+ rts[0].rt_scope = RT_SCOPE_LINK;
+ rts[0].rt_scope_is_set = TRUE;
rts[1].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
rts[1].network = network;
rts[1].plen = plen;
@@ -193,7 +231,8 @@ test_ip4_route (void)
rts[1].gateway = gateway;
rts[1].metric = metric;
rts[1].mss = mss;
- rts[1].scope_inv = nm_platform_route_scope_inv (RT_SCOPE_UNIVERSE);
+ rts[1].rt_scope = RT_SCOPE_UNIVERSE;
+ rts[1].rt_scope_is_set = TRUE;
rts[2].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER);
rts[2].network = 0;
rts[2].plen = 0;
@@ -201,18 +240,19 @@ test_ip4_route (void)
rts[2].gateway = gateway;
rts[2].metric = metric;
rts[2].mss = mss;
- rts[2].scope_inv = nm_platform_route_scope_inv (RT_SCOPE_UNIVERSE);
+ rts[2].rt_scope = RT_SCOPE_UNIVERSE;
+ rts[2].rt_scope_is_set = TRUE;
g_assert_cmpint (routes->len, ==, 3);
nmtst_platform_ip4_routes_equal ((NMPlatformIP4Route *) routes->data, rts, routes->len, TRUE);
g_array_unref (routes);
/* Remove route */
- g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric));
- nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric);
+ g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, &r));
+ nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric, NULL);
accept_signal (route_removed);
/* Remove route again */
- g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric));
+ g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, &r));
free_signal (route_added);
free_signal (route_changed);
@@ -228,38 +268,60 @@ test_ip6_route (void)
SignalData *route_removed = add_signal (NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip6_route_callback);
GArray *routes;
NMPlatformIP6Route rts[3];
- struct in6_addr network;
+ const char *const NETWORK = "2001:db8:a:b:0:0:0:0";
+ const char *const GATEWAY = "2001:db8:c:d:1:2:3:4";
+ const struct in6_addr network = *nmtst_inet6_from_string (NETWORK);
+ const struct in6_addr gateway = *nmtst_inet6_from_string (GATEWAY);
guint8 plen = 64;
- struct in6_addr gateway;
- /* 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);
+ NMPlatformIP6Route r = {
+ .ifindex = ifindex,
+ .network = network,
+ .plen = plen,
+ .gateway = gateway,
+ .metric = metric,
+ .mss = mss,
+ .rt_source = NM_IP_CONFIG_SOURCE_USER,
+ };
+ NMPlatformIP6Route r_gateway = {
+ .ifindex = ifindex,
+ .network = gateway,
+ .plen = 128,
+ .metric = metric,
+ .mss = mss,
+ .rt_source = NM_IP_CONFIG_SOURCE_USER,
+ };
+ NMPlatformIP6Route r_default = {
+ .ifindex = ifindex,
+ .gateway = gateway,
+ .metric = metric,
+ .mss = mss,
+ .rt_source = NM_IP_CONFIG_SOURCE_USER,
+ };
/* 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));
+ g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, &r_gateway));
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));
- g_assert (nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric));
+ g_assert (!nm_platform_ip6_route_get (NM_PLATFORM_GET, &r));
+ g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, &r));
+ g_assert (nm_platform_ip6_route_get (NM_PLATFORM_GET, &r));
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));
+ g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, &r));
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));
- g_assert (nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, in6addr_any, 0, metric));
+ g_assert (!nm_platform_ip6_route_get (NM_PLATFORM_GET, &r_default));
+ g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, &r_default));
+ g_assert (nm_platform_ip6_route_get (NM_PLATFORM_GET, &r_default));
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));
+ g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, &r_default));
accept_signals (route_changed, 0, 1);
/* Test route listing */
@@ -291,12 +353,12 @@ test_ip6_route (void)
g_array_unref (routes);
/* Remove route */
- g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric));
- g_assert (!nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric));
+ g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, &r));
+ g_assert (!nm_platform_ip6_route_get (NM_PLATFORM_GET, &r));
accept_signal (route_removed);
/* Remove route again */
- g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric));
+ g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, &r));
free_signal (route_added);
free_signal (route_changed);
@@ -309,14 +371,30 @@ static void
test_ip4_zero_gateway (void)
{
int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME);
+ NMPlatformIP4Route r_global = {
+ .ifindex = ifindex,
+ .network = nmtst_inet4_from_string ("1.2.3.1"),
+ .plen = 32,
+ .rt_source = NM_IP_CONFIG_SOURCE_RTPROT_BOOT,
+ .rt_scope = RT_SCOPE_UNIVERSE,
+ .rt_scope_is_set = TRUE,
+ };
+ NMPlatformIP4Route r_local = {
+ .ifindex = ifindex,
+ .network = nmtst_inet4_from_string ("1.2.3.2"),
+ .plen = 32,
+ .rt_source = NM_IP_CONFIG_SOURCE_RTPROT_BOOT,
+ .rt_scope = RT_SCOPE_LINK,
+ .rt_scope_is_set = TRUE,
+ };
nmtstp_run_command_check ("ip route add 1.2.3.1/32 via 0.0.0.0 dev %s", DEVICE_NAME);
nmtstp_run_command_check ("ip route add 1.2.3.2/32 dev %s", DEVICE_NAME);
NMTST_WAIT_ASSERT (100, {
nmtstp_wait_for_signal (NM_PLATFORM_GET, 10);
- if ( nm_platform_ip4_route_get (NM_PLATFORM_GET, ifindex, nmtst_inet4_from_string ("1.2.3.1"), 32, 0)
- && nm_platform_ip4_route_get (NM_PLATFORM_GET, ifindex, nmtst_inet4_from_string ("1.2.3.2"), 32, 0))
+ if ( nm_platform_ip4_route_get (NM_PLATFORM_GET, &r_global)
+ && nm_platform_ip4_route_get (NM_PLATFORM_GET, &r_local))
break;
});