diff options
Diffstat (limited to 'src/platform/tests/test-route.c')
| -rw-r--r-- | src/platform/tests/test-route.c | 541 |
1 files changed, 405 insertions, 136 deletions
diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c index 9960d867..2c00fada 100644 --- a/src/platform/tests/test-route.c +++ b/src/platform/tests/test-route.c @@ -27,13 +27,50 @@ #include "test-common.h" -#define DEVICE_NAME "nm-test-device" +#define DEVICE_IFINDEX NMTSTP_ENV1_IFINDEX +#define EX NMTSTP_ENV1_EX + +static void +_wait_for_ipv6_addr_non_tentative (NMPlatform *platform, + gint64 timeout_ms, + int ifindex, + guint addr_n, + const struct in6_addr *addrs) +{ + guint i; + + /* Wait that the addresses become non-tentative. Dummy interfaces are NOARP + * and thus don't do DAD, but the kernel sets the address as tentative for a + * small amount of time, which prevents the immediate addition of the route + * with RTA_PREFSRC */ + + NMTST_WAIT_ASSERT (400, { + gboolean should_wait = FALSE; + const NMPlatformIP6Address *plt_addr; + + for (i = 0; i < addr_n; i++) { + plt_addr = nm_platform_ip6_address_get (platform, ifindex, addrs[i]); + if ( !plt_addr + || NM_FLAGS_HAS (plt_addr->n_ifa_flags, IFA_F_TENTATIVE)) { + should_wait = TRUE; + break; + } + } + if (!should_wait) + return; + nmtstp_assert_wait_for_signal (platform, + (nmtst_wait_end_us - g_get_monotonic_time ()) / 1000); + }); +} + static void ip4_route_callback (NMPlatform *platform, int obj_type_i, int ifindex, const NMPlatformIP4Route *received, int change_type_i, SignalData *data) { const NMPObjectType obj_type = obj_type_i; const NMPlatformSignalChangeType change_type = change_type_i; + NMPObject o_id; + nm_auto_nmpobj NMPObject *o_id_p = nmp_object_new (NMP_OBJECT_TYPE_IP4_ROUTE, NULL); g_assert_cmpint (obj_type, ==, NMP_OBJECT_TYPE_IP4_ROUTE); g_assert (received); @@ -41,6 +78,11 @@ ip4_route_callback (NMPlatform *platform, int obj_type_i, int ifindex, const NMP g_assert (data && data->name); g_assert_cmpstr (data->name, ==, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED); + /* run code for initializing the ID only */ + nmp_object_stackinit_id (&o_id, NMP_OBJECT_UP_CAST (received)); + nmp_object_copy (o_id_p, NMP_OBJECT_UP_CAST (received), TRUE); + nmp_object_copy (o_id_p, NMP_OBJECT_UP_CAST (received), FALSE); + if (data->ifindex && data->ifindex != received->ifindex) return; if (data->change_type != change_type) @@ -58,6 +100,8 @@ ip6_route_callback (NMPlatform *platform, int obj_type_i, int ifindex, const NMP { const NMPObjectType obj_type = obj_type_i; const NMPlatformSignalChangeType change_type = change_type_i; + NMPObject o_id; + nm_auto_nmpobj NMPObject *o_id_p = nmp_object_new (NMP_OBJECT_TYPE_IP6_ROUTE, NULL); g_assert_cmpint (obj_type, ==, NMP_OBJECT_TYPE_IP6_ROUTE); g_assert (received); @@ -65,6 +109,11 @@ ip6_route_callback (NMPlatform *platform, int obj_type_i, int ifindex, const NMP g_assert (data && data->name); g_assert_cmpstr (data->name, ==, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED); + /* run code for initializing the ID only */ + nmp_object_stackinit_id (&o_id, NMP_OBJECT_UP_CAST (received)); + nmp_object_copy (o_id_p, NMP_OBJECT_UP_CAST (received), TRUE); + nmp_object_copy (o_id_p, NMP_OBJECT_UP_CAST (received), FALSE); + if (data->ifindex && data->ifindex != received->ifindex) return; if (data->change_type != change_type) @@ -90,50 +139,50 @@ test_ip4_route_metric0 (void) int mss = 1000; /* 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, 0, DEVICE_NAME, network, plen, 0, 0); + nmtstp_assert_ip4_route_exists (NULL, 0, DEVICE_NAME, network, plen, metric, 0); /* add the first route */ nmtstp_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, INADDR_ANY, 0, metric, mss); accept_signal (route_added); - nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, 0); - nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (NULL, 0, DEVICE_NAME, network, plen, 0, 0); + nmtstp_assert_ip4_route_exists (NULL, 1, DEVICE_NAME, network, plen, metric, 0); /* Deleting route with metric 0 does nothing */ - g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0)); + g_assert (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0)); 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, 0, DEVICE_NAME, network, plen, 0, 0); + nmtstp_assert_ip4_route_exists (NULL, 1, DEVICE_NAME, network, plen, metric, 0); /* add the second route */ nmtstp_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, INADDR_ANY, 0, 0, mss); accept_signal (route_added); - nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, 0); - nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (NULL, 1, DEVICE_NAME, network, plen, 0, 0); + nmtstp_assert_ip4_route_exists (NULL, 1, DEVICE_NAME, network, plen, metric, 0); /* Delete route with metric 0 */ - g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0)); + g_assert (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0)); 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, 0, DEVICE_NAME, network, plen, 0, 0); + nmtstp_assert_ip4_route_exists (NULL, 1, DEVICE_NAME, network, plen, metric, 0); /* 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 (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0)); 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, 0, DEVICE_NAME, network, plen, 0, 0); + nmtstp_assert_ip4_route_exists (NULL, 1, DEVICE_NAME, network, plen, metric, 0); /* Delete the other route */ - g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); + g_assert (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); 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, 0, DEVICE_NAME, network, plen, 0, 0); + nmtstp_assert_ip4_route_exists (NULL, 0, DEVICE_NAME, network, plen, metric, 0); free_signal (route_added); free_signal (route_changed); @@ -147,7 +196,7 @@ test_ip4_route (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); - GArray *routes; + GPtrArray *routes; NMPlatformIP4Route rts[3]; in_addr_t network; guint8 plen = 24; @@ -164,9 +213,9 @@ test_ip4_route (void) accept_signal (route_added); /* Add route */ - nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (NULL, 0, DEVICE_NAME, network, plen, metric, 0); nmtstp_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, 0, metric, mss); - nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, network, plen, metric); + nmtstp_assert_ip4_route_exists (NULL, 1, DEVICE_NAME, network, plen, metric, 0); accept_signal (route_added); /* Add route again */ @@ -174,9 +223,9 @@ test_ip4_route (void) accept_signals (route_changed, 0, 1); /* Add default route */ - nmtstp_assert_ip4_route_exists (NULL, FALSE, DEVICE_NAME, 0, 0, metric); + nmtstp_assert_ip4_route_exists (NULL, 0, DEVICE_NAME, 0, 0, metric, 0); nmtstp_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, 0, 0, gateway, 0, metric, mss); - nmtstp_assert_ip4_route_exists (NULL, TRUE, DEVICE_NAME, 0, 0, metric); + nmtstp_assert_ip4_route_exists (NULL, 1, DEVICE_NAME, 0, 0, metric, 0); accept_signal (route_added); /* Add default route again */ @@ -184,7 +233,7 @@ test_ip4_route (void) accept_signals (route_changed, 0, 1); /* Test route listing */ - routes = nm_platform_ip4_route_get_all (NM_PLATFORM_GET, ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT); + routes = nmtstp_ip4_route_get_all (NM_PLATFORM_GET, ifindex); memset (rts, 0, sizeof (rts)); rts[0].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); rts[0].network = gateway; @@ -211,23 +260,23 @@ test_ip4_route (void) rts[2].mss = mss; rts[2].scope_inv = nm_platform_route_scope_inv (RT_SCOPE_UNIVERSE); g_assert_cmpint (routes->len, ==, 3); - nmtst_platform_ip4_routes_equal ((NMPlatformIP4Route *) routes->data, rts, routes->len, TRUE); - g_array_unref (routes); + nmtst_platform_ip4_routes_equal_aptr ((const NMPObject *const*) routes->pdata, rts, routes->len, TRUE); + g_ptr_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 (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); + nmtstp_assert_ip4_route_exists (NULL, 0, DEVICE_NAME, network, plen, metric, 0); accept_signal (route_removed); /* Remove route again */ - g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); + g_assert (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); /* Remove default route */ - g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, 0, 0, metric)); + g_assert (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, 0, 0, metric)); accept_signal (route_removed); /* Remove route to gateway */ - g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, gateway, 32, metric)); + g_assert (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, gateway, 32, metric)); accept_signal (route_removed); free_signal (route_added); @@ -242,7 +291,7 @@ test_ip6_route (void) SignalData *route_added = add_signal (NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip6_route_callback); SignalData *route_changed = add_signal (NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, ip6_route_callback); SignalData *route_removed = add_signal (NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip6_route_callback); - GArray *routes; + GPtrArray *routes; NMPlatformIP6Route rts[3]; struct in6_addr network; guint8 plen = 64; @@ -259,28 +308,16 @@ test_ip6_route (void) NM_PLATFORM_LIFETIME_PERMANENT, NM_PLATFORM_LIFETIME_PERMANENT, 0)); accept_signals (route_added, 0, 1); - /* Wait that the address becomes non-tentative. Dummy interfaces are NOARP - * and thus don't do DAD, but the kernel sets the address as tentative for a - * small amount of time, which prevents the immediate addition of the route - * with RTA_PREFSRC */ - NMTST_WAIT_ASSERT (200, { - const NMPlatformIP6Address *plt_addr; - - nmtstp_wait_for_signal (NM_PLATFORM_GET, 50); - nm_platform_process_events (NM_PLATFORM_GET); - plt_addr = nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, pref_src, 128); - if (plt_addr && !NM_FLAGS_HAS (plt_addr->n_ifa_flags, IFA_F_TENTATIVE)) - break; - }); + _wait_for_ipv6_addr_non_tentative (NM_PLATFORM_GET, 200, ifindex, 1, &pref_src); /* Add route to gateway */ nmtstp_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, gateway, 128, in6addr_any, in6addr_any, metric, mss); accept_signal (route_added); /* Add route */ - g_assert (!nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric)); + g_assert (!nmtstp_ip6_route_get (NM_PLATFORM_GET, ifindex, &network, plen, metric, NULL, 0)); nmtstp_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, pref_src, metric, mss); - g_assert (nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, network, plen, metric)); + g_assert (nmtstp_ip6_route_get (NM_PLATFORM_GET, ifindex, &network, plen, metric, NULL, 0)); accept_signal (route_added); /* Add route again */ @@ -288,9 +325,9 @@ test_ip6_route (void) 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 (!nmtstp_ip6_route_get (NM_PLATFORM_GET, ifindex, &in6addr_any, 0, metric, NULL, 0)); nmtstp_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, in6addr_any, 0, gateway, in6addr_any, metric, mss); - g_assert (nm_platform_ip6_route_get (NM_PLATFORM_GET, ifindex, in6addr_any, 0, metric)); + g_assert (nmtstp_ip6_route_get (NM_PLATFORM_GET, ifindex, &in6addr_any, 0, metric, NULL, 0)); accept_signal (route_added); /* Add default route again */ @@ -298,7 +335,7 @@ test_ip6_route (void) accept_signals (route_changed, 0, 1); /* Test route listing */ - routes = nm_platform_ip6_route_get_all (NM_PLATFORM_GET, ifindex, NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT); + routes = nmtstp_ip6_route_get_all (NM_PLATFORM_GET, ifindex); memset (rts, 0, sizeof (rts)); rts[0].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); rts[0].network = gateway; @@ -325,23 +362,23 @@ test_ip6_route (void) rts[2].metric = nm_utils_ip6_route_metric_normalize (metric); rts[2].mss = mss; g_assert_cmpint (routes->len, ==, 3); - nmtst_platform_ip6_routes_equal ((NMPlatformIP6Route *) routes->data, rts, routes->len, TRUE); - g_array_unref (routes); + nmtst_platform_ip6_routes_equal_aptr ((const NMPObject *const*) routes->pdata, rts, routes->len, TRUE); + g_ptr_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 (nmtstp_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); + g_assert (!nmtstp_ip6_route_get (NM_PLATFORM_GET, ifindex, &network, plen, metric, NULL, 0)); accept_signal (route_removed); /* Remove route again */ - g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); + g_assert (nmtstp_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); /* Remove default route */ - g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, in6addr_any, 0, metric)); + g_assert (nmtstp_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, in6addr_any, 0, metric)); accept_signal (route_removed); /* Remove route to gateway */ - g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, gateway, 128, metric)); + g_assert (nmtstp_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, gateway, 128, metric)); accept_signal (route_removed); free_signal (route_added); @@ -352,6 +389,45 @@ test_ip6_route (void) /*****************************************************************************/ static void +test_ip_route_get (void) +{ + int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); + in_addr_t a; + NMPlatformError result; + nm_auto_nmpobj NMPObject *route = NULL; + const NMPlatformIP4Route *r; + + nmtstp_run_command_check ("ip route add 1.2.3.0/24 dev %s", DEVICE_NAME); + + NMTST_WAIT_ASSERT (100, { + nmtstp_wait_for_signal (NM_PLATFORM_GET, 10); + if (nmtstp_ip4_route_get (NM_PLATFORM_GET, ifindex, nmtst_inet4_from_string ("1.2.3.0"), 24, 0, 0)) + break; + }); + + a = nmtst_inet4_from_string ("1.2.3.1"); + result = nm_platform_ip_route_get (NM_PLATFORM_GET, + AF_INET, + &a, + nmtst_get_rand_int () % 2 ? 0 : ifindex, + &route); + + g_assert (result == NM_PLATFORM_ERROR_SUCCESS); + g_assert (NMP_OBJECT_GET_TYPE (route) == NMP_OBJECT_TYPE_IP4_ROUTE); + g_assert (!NMP_OBJECT_IS_STACKINIT (route)); + g_assert (route->parent._ref_count == 1); + r = NMP_OBJECT_CAST_IP4_ROUTE (route); + g_assert (r->rt_cloned); + g_assert (r->ifindex == ifindex); + g_assert (r->network == a); + g_assert (r->plen == 32); + + nmtstp_run_command_check ("ip route flush dev %s", DEVICE_NAME); + + nmtstp_wait_for_signal (NM_PLATFORM_GET, 50); +} + +static void test_ip4_zero_gateway (void) { int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); @@ -361,15 +437,14 @@ test_ip4_zero_gateway (void) 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 ( nmtstp_ip4_route_get (NM_PLATFORM_GET, ifindex, nmtst_inet4_from_string ("1.2.3.1"), 32, 0, 0) + && nmtstp_ip4_route_get (NM_PLATFORM_GET, ifindex, nmtst_inet4_from_string ("1.2.3.2"), 32, 0, 0)) break; }); nmtstp_run_command_check ("ip route flush dev %s", DEVICE_NAME); nmtstp_wait_for_signal (NM_PLATFORM_GET, 50); - nm_platform_process_events (NM_PLATFORM_GET); } static void @@ -378,7 +453,7 @@ test_ip4_route_options (void) int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); NMPlatformIP4Route route = { }; in_addr_t network; - GArray *routes; + GPtrArray *routes; NMPlatformIP4Route rts[1]; inet_pton (AF_INET, "172.16.1.0", &network); @@ -396,12 +471,10 @@ test_ip4_route_options (void) route.mtu = 1350; route.lock_cwnd = TRUE; - g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, &route)); + g_assert (nm_platform_ip4_route_add (NM_PLATFORM_GET, NMP_NLM_FLAG_REPLACE, &route) == NM_PLATFORM_ERROR_SUCCESS); /* Test route listing */ - routes = nm_platform_ip4_route_get_all (NM_PLATFORM_GET, ifindex, - NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | - NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT); + routes = nmtstp_ip4_route_get_all (NM_PLATFORM_GET, ifindex); memset (rts, 0, sizeof (rts)); rts[0].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); rts[0].scope_inv = nm_platform_route_scope_inv (RT_SCOPE_LINK); @@ -416,69 +489,268 @@ test_ip4_route_options (void) rts[0].initrwnd = 50; rts[0].mtu = 1350; rts[0].lock_cwnd = TRUE; - g_assert_cmpint (routes->len, ==, 1); - nmtst_platform_ip4_routes_equal ((NMPlatformIP4Route *) routes->data, rts, routes->len, TRUE); + nmtst_platform_ip4_routes_equal_aptr ((const NMPObject *const*) routes->pdata, rts, routes->len, TRUE); /* Remove route */ - /* FIXME. Due to a bug, we cannot delete routes with non-zero TOS. See bgo#785004. */ - //g_assert (nm_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, 24, 20)); + g_assert (nm_platform_ip_route_delete (NM_PLATFORM_GET, routes->pdata[0])); - g_array_unref (routes); + g_ptr_array_unref (routes); } static void -test_ip6_route_options (void) +test_ip6_route_options (gconstpointer test_data) { - int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); - NMPlatformIP6Route route = { }; - struct in6_addr network; - GArray *routes; - NMPlatformIP6Route rts[3]; - - inet_pton (AF_INET6, "2001:db8:a:b:0:0:0:0", &network); - - route.ifindex = ifindex; - route.rt_source = NM_IP_CONFIG_SOURCE_USER; - route.network = network; - route.plen = 64; - route.gateway = in6addr_any; - route.metric = 1024; - route.window = 20000; - route.cwnd = 8; - route.initcwnd = 22; - route.initrwnd = 33; - route.mtu = 1300; - route.lock_mtu = TRUE; - - g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, &route)); - - /* Test route listing */ - routes = nm_platform_ip6_route_get_all (NM_PLATFORM_GET, ifindex, - NM_PLATFORM_GET_ROUTE_FLAGS_WITH_DEFAULT | - NM_PLATFORM_GET_ROUTE_FLAGS_WITH_NON_DEFAULT); - memset (rts, 0, sizeof (rts)); - rts[0].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); - rts[0].network = network; - rts[0].plen = 64; - rts[0].ifindex = ifindex; - rts[0].gateway = in6addr_any; - rts[0].metric = 1024; - rts[0].window = 20000; - rts[0].cwnd = 8; - rts[0].initcwnd = 22; - rts[0].initrwnd = 33; - rts[0].mtu = 1300; - rts[0].lock_mtu = TRUE; - - g_assert_cmpint (routes->len, ==, 1); - nmtst_platform_ip6_routes_equal ((NMPlatformIP6Route *) routes->data, rts, routes->len, TRUE); + const int TEST_IDX = GPOINTER_TO_INT (test_data); + const int IFINDEX = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); + GPtrArray *routes; +#define RTS_MAX 3 + NMPlatformIP6Route rts_add[RTS_MAX] = { }; + NMPlatformIP6Route rts_cmp[RTS_MAX] = { }; + NMPlatformIP6Address addr[1] = { }; + struct in6_addr addr_in6[G_N_ELEMENTS (addr)] = { }; + guint rts_n = 0; + guint addr_n = 0; + guint i; + + switch (TEST_IDX) { + case 1: + rts_add[rts_n++] = ((NMPlatformIP6Route) { + .ifindex = IFINDEX, + .rt_source = NM_IP_CONFIG_SOURCE_USER, + .network = *nmtst_inet6_from_string ("2001:db8:a:b:0:0:0:0"), + .plen = 64, + .gateway = in6addr_any, + .metric = 1024, + .window = 20000, + .cwnd = 8, + .initcwnd = 22, + .initrwnd = 33, + .mtu = 1300, + .lock_mtu = TRUE, + }); + break; + case 2: + addr[addr_n++] = ((NMPlatformIP6Address) { + .ifindex = IFINDEX, + .address = *nmtst_inet6_from_string ("2000::2"), + .plen = 128, + .peer_address = in6addr_any, + .lifetime = NM_PLATFORM_LIFETIME_PERMANENT, + .preferred = NM_PLATFORM_LIFETIME_PERMANENT, + .n_ifa_flags = 0, + }); + rts_add[rts_n++] = ((NMPlatformIP6Route) { + .ifindex = IFINDEX, + .rt_source = NM_IP_CONFIG_SOURCE_USER, + .network = *nmtst_inet6_from_string ("1010::1"), + .plen = 128, + .gateway = in6addr_any, + .metric = 256, + .pref_src = *nmtst_inet6_from_string ("2000::2"), + }); + break; + case 3: + addr[addr_n++] = ((NMPlatformIP6Address) { + .ifindex = IFINDEX, + .address = *nmtst_inet6_from_string ("2001:db8:8086::5"), + .plen = 128, + .peer_address = in6addr_any, + .lifetime = NM_PLATFORM_LIFETIME_PERMANENT, + .preferred = NM_PLATFORM_LIFETIME_PERMANENT, + .n_ifa_flags = 0, + }); + rts_add[rts_n++] = ((NMPlatformIP6Route) { + .ifindex = IFINDEX, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), + .network = *nmtst_inet6_from_string ("2001:db8:8086::"), + .plen = 110, + .metric = 10021, + .mss = 0, + }); + rts_add[rts_n++] = ((NMPlatformIP6Route) { + .ifindex = IFINDEX, + .rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER), + .network = *nmtst_inet6_from_string ("2001:db8:abad:c0de::"), + .plen = 64, + .gateway = *nmtst_inet6_from_string ("2001:db8:8086::1"), + .metric = 21, + .mss = 0, + }); + break; + default: + g_assert_not_reached (); + } + + for (i = 0; i < addr_n; i++) { + g_assert (addr[i].ifindex == IFINDEX); + addr_in6[i] = addr[i].address; + g_assert (nm_platform_ip6_address_add (NM_PLATFORM_GET, + IFINDEX, + addr[i].address, + addr[i].plen, + addr[i].peer_address, + addr[i].lifetime, + addr[i].preferred, + addr[i].n_ifa_flags)); + } + + _wait_for_ipv6_addr_non_tentative (NM_PLATFORM_GET, 400, IFINDEX, addr_n, addr_in6); + + for (i = 0; i < rts_n; i++) + g_assert (nm_platform_ip6_route_add (NM_PLATFORM_GET, NMP_NLM_FLAG_REPLACE, &rts_add[i]) == NM_PLATFORM_ERROR_SUCCESS); + + routes = nmtstp_ip6_route_get_all (NM_PLATFORM_GET, IFINDEX); + switch (TEST_IDX) { + case 1: + case 2: + case 3: + for (i = 0; i < rts_n; i++) { + rts_cmp[i] = rts_add[i]; + rts_cmp[i].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); + } + break; + default: + g_assert_not_reached (); + } + g_assert_cmpint (routes->len, ==, rts_n); + nmtst_platform_ip6_routes_equal_aptr ((const NMPObject *const*) routes->pdata, rts_cmp, routes->len, TRUE); + g_ptr_array_unref (routes); + + for (i = 0; i < rts_n; i++) { + g_assert (nmtstp_platform_ip6_route_delete (NM_PLATFORM_GET, IFINDEX, + rts_add[i].network, rts_add[i].plen, + rts_add[i].metric)); + } + + for (i = 0; i < addr_n; i++) { + nmtstp_ip6_address_del (NM_PLATFORM_GET, + EX, + IFINDEX, + rts_add[i].network, + rts_add[i].plen); + } +} - /* Remove route */ - g_assert (nm_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, network, 64, 1024)); +/*****************************************************************************/ - g_array_unref (routes); +static void +test_ip (gconstpointer test_data) +{ + const int TEST_IDX = GPOINTER_TO_INT (test_data); + const int IFINDEX = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); + guint i, j, k; + const NMPlatformLink *l; + char ifname[IFNAMSIZ]; + char ifname2[IFNAMSIZ]; + char s1[NM_UTILS_INET_ADDRSTRLEN]; + NMPlatform *platform = NM_PLATFORM_GET; + const int EX_ = -1; + struct { + int ifindex; + } iface_data[10] = { 0 }; + int order_idx[G_N_ELEMENTS (iface_data)] = { 0 }; + guint order_len; + guint try; + + for (i = 0; i < G_N_ELEMENTS (iface_data); i++) { + nm_sprintf_buf (ifname, "v%02u", i); + nm_sprintf_buf (ifname2, "w%02u", i); + + g_assert (!nm_platform_link_get_by_ifname (platform, ifname)); + g_assert (!nm_platform_link_get_by_ifname (platform, ifname2)); + l = nmtstp_link_veth_add (platform, EX_, ifname, ifname2); + iface_data[i].ifindex = l->ifindex; + + nmtstp_link_set_updown (platform, EX_, iface_data[i].ifindex, TRUE); + nmtstp_link_set_updown (platform, EX_, nmtstp_link_get (platform, -1, ifname2)->ifindex, TRUE); + + nm_sprintf_buf (s1, "192.168.7.%d", 100 + i); + nmtstp_ip4_address_add (platform, + EX_, + iface_data[i].ifindex, + nmtst_inet4_from_string (s1), + 24, + nmtst_inet4_from_string (s1), + 3600, + 3600, + 0, + NULL); + } + + order_len = 0; + for (try = 0; try < 5 * G_N_ELEMENTS (order_idx); try++) { + NMPObject o; + NMPlatformIP4Route *r; + guint idx; + const NMDedupMultiHeadEntry *head_entry; + NMPLookup lookup; + + nmp_object_stackinit (&o, NMP_OBJECT_TYPE_IP4_ROUTE, NULL); + r = NMP_OBJECT_CAST_IP4_ROUTE (&o); + r->network = nmtst_inet4_from_string ("192.168.9.0"); + r->plen = 24; + r->metric = 109; + + if ( order_len == 0 + || ( order_len < G_N_ELEMENTS (order_idx) + && nmtst_get_rand_int () % 2)) { +again_find_idx: + idx = nmtst_get_rand_int () % G_N_ELEMENTS (iface_data); + for (i = 0; i < order_len; i++) { + if (order_idx[i] == idx) + goto again_find_idx; + } + order_idx[order_len++] = idx; + + r->ifindex = iface_data[idx].ifindex; + g_assert (nm_platform_ip4_route_add (platform, NMP_NLM_FLAG_APPEND, r) == NM_PLATFORM_ERROR_SUCCESS); + } else { + i = nmtst_get_rand_int () % order_len; + idx = order_idx[i]; + for (i++; i < order_len; i++) + order_idx[i - 1] = order_idx[i]; + order_len--; + + r->ifindex = iface_data[idx].ifindex; + g_assert (nm_platform_ip_route_delete (platform, &o)); + } + + head_entry = nm_platform_lookup (platform, + nmp_lookup_init_obj_type (&lookup, NMP_OBJECT_TYPE_IP4_ROUTE)); + for (j = 0; j < G_N_ELEMENTS (iface_data); j++) { + gboolean has; + NMDedupMultiIter iter; + const NMPObject *o_cached; + + has = FALSE; + for (k = 0; k < order_len; k++) { + if (order_idx[k] == j) { + g_assert (!has); + has = TRUE; + } + } + + nmp_cache_iter_for_each (&iter, head_entry, &o_cached) { + const NMPlatformIP4Route *r_cached = NMP_OBJECT_CAST_IP4_ROUTE (o_cached); + + if ( r_cached->ifindex != iface_data[j].ifindex + || r_cached->metric != 109) + continue; + + g_assert (has); + has = FALSE; + } + g_assert (!has); + } + } + + for (i = 0; i < G_N_ELEMENTS (iface_data); i++) + g_assert (nm_platform_link_delete (platform, iface_data[i].ifindex)); + + (void) TEST_IDX; + (void) IFINDEX; } /*****************************************************************************/ @@ -494,22 +766,19 @@ _nmtstp_init_tests (int *argc, char ***argv) void _nmtstp_setup_tests (void) { - SignalData *link_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, DEVICE_NAME); - - nm_platform_link_delete (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME)); - g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, DEVICE_NAME)); - g_assert (nm_platform_link_dummy_add (NM_PLATFORM_GET, DEVICE_NAME, NULL) == NM_PLATFORM_ERROR_SUCCESS); - accept_signal (link_added); - free_signal (link_added); - - g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME), NULL)); - - g_test_add_func ("/route/ip4", test_ip4_route); - g_test_add_func ("/route/ip6", test_ip6_route); - g_test_add_func ("/route/ip4_metric0", test_ip4_route_metric0); - g_test_add_func ("/route/ip4_options", test_ip4_route_options); - g_test_add_func ("/route/ip6_options", test_ip6_route_options); - - if (nmtstp_is_root_test ()) - g_test_add_func ("/route/ip4_zero_gateway", test_ip4_zero_gateway); +#define add_test_func(testpath, test_func) nmtstp_env1_add_test_func(testpath, test_func, TRUE) +#define add_test_func_data(testpath, test_func, arg) nmtstp_env1_add_test_func_data(testpath, test_func, arg, TRUE) + add_test_func ("/route/ip4", test_ip4_route); + add_test_func ("/route/ip6", test_ip6_route); + add_test_func ("/route/ip4_metric0", test_ip4_route_metric0); + add_test_func ("/route/ip4_options", test_ip4_route_options); + add_test_func_data ("/route/ip6_options/1", test_ip6_route_options, GINT_TO_POINTER (1)); + add_test_func_data ("/route/ip6_options/2", test_ip6_route_options, GINT_TO_POINTER (2)); + add_test_func_data ("/route/ip6_options/3", test_ip6_route_options, GINT_TO_POINTER (3)); + + if (nmtstp_is_root_test ()) { + add_test_func_data ("/route/ip/1", test_ip, GINT_TO_POINTER (1)); + add_test_func ("/route/ip_route_get", test_ip_route_get); + add_test_func ("/route/ip4_zero_gateway", test_ip4_zero_gateway); + } } |