diff options
Diffstat (limited to 'src/platform/tests')
-rw-r--r-- | src/platform/tests/test-cleanup.c | 33 | ||||
-rw-r--r-- | src/platform/tests/test-common.c | 414 | ||||
-rw-r--r-- | src/platform/tests/test-common.h | 70 | ||||
-rw-r--r-- | src/platform/tests/test-link.c | 187 | ||||
-rw-r--r-- | src/platform/tests/test-route.c | 200 |
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; }); |