diff options
Diffstat (limited to 'src/platform/tests')
| -rw-r--r-- | src/platform/tests/monitor.c | 82 | ||||
| -rw-r--r-- | src/platform/tests/test-address.c | 676 | ||||
| -rw-r--r-- | src/platform/tests/test-cleanup.c | 264 | ||||
| -rw-r--r-- | src/platform/tests/test-common.c | 3788 | ||||
| -rw-r--r-- | src/platform/tests/test-common.h | 803 | ||||
| -rw-r--r-- | src/platform/tests/test-link.c | 6515 | ||||
| -rw-r--r-- | src/platform/tests/test-nmp-object.c | 987 | ||||
| -rw-r--r-- | src/platform/tests/test-platform-general.c | 736 | ||||
| -rw-r--r-- | src/platform/tests/test-route.c | 3381 | ||||
| -rw-r--r-- | src/platform/tests/test-tc.c | 347 |
10 files changed, 9800 insertions, 7779 deletions
diff --git a/src/platform/tests/monitor.c b/src/platform/tests/monitor.c index aec29b75..a8d0fad2 100644 --- a/src/platform/tests/monitor.c +++ b/src/platform/tests/monitor.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2015 Red Hat, Inc. */ @@ -12,61 +12,67 @@ #include "nm-test-utils-core.h" -NMTST_DEFINE (); +NMTST_DEFINE(); static struct { - gboolean persist; + gboolean persist; } global_opt = { - .persist = TRUE, + .persist = TRUE, }; static gboolean -read_argv (int *argc, char ***argv) +read_argv(int *argc, char ***argv) { - GOptionContext *context; - GOptionEntry options[] = { - { "no-persist", 'P', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &global_opt.persist, "Exit after processing netlink messages", NULL }, - { 0 }, - }; - gs_free_error GError *error = NULL; - - context = g_option_context_new (NULL); - g_option_context_set_summary (context, "Monitor netlink events in NMPlatform."); - g_option_context_add_main_entries (context, options, NULL); - - if (!g_option_context_parse (context, argc, argv, &error)) { - g_warning ("Error parsing command line arguments: %s", error->message); - g_option_context_free (context); - return FALSE; - } - - g_option_context_free (context); - return TRUE; + GOptionContext *context; + GOptionEntry options[] = { + {"no-persist", + 'P', + G_OPTION_FLAG_REVERSE, + G_OPTION_ARG_NONE, + &global_opt.persist, + "Exit after processing netlink messages", + NULL}, + {0}, + }; + gs_free_error GError *error = NULL; + + context = g_option_context_new(NULL); + g_option_context_set_summary(context, "Monitor netlink events in NMPlatform."); + g_option_context_add_main_entries(context, options, NULL); + + if (!g_option_context_parse(context, argc, argv, &error)) { + g_warning("Error parsing command line arguments: %s", error->message); + g_option_context_free(context); + return FALSE; + } + + g_option_context_free(context); + return TRUE; } int -main (int argc, char **argv) +main(int argc, char **argv) { - GMainLoop *loop; + GMainLoop *loop; - if (!g_getenv ("G_MESSAGES_DEBUG")) - g_setenv ("G_MESSAGES_DEBUG", "all", TRUE); + if (!g_getenv("G_MESSAGES_DEBUG")) + g_setenv("G_MESSAGES_DEBUG", "all", TRUE); - nmtst_init_with_logging (&argc, &argv, "DEBUG", "ALL"); + nmtst_init_with_logging(&argc, &argv, "DEBUG", "ALL"); - if (!read_argv (&argc, &argv)) - return 2; + if (!read_argv(&argc, &argv)) + return 2; - nm_log_info (LOGD_PLATFORM, "platform monitor start"); + nm_log_info(LOGD_PLATFORM, "platform monitor start"); - loop = g_main_loop_new (NULL, FALSE); + loop = g_main_loop_new(NULL, FALSE); - nm_linux_platform_setup (); + nm_linux_platform_setup(); - if (global_opt.persist) - g_main_loop_run (loop); + if (global_opt.persist) + g_main_loop_run(loop); - g_main_loop_unref (loop); + g_main_loop_unref(loop); - return EXIT_SUCCESS; + return EXIT_SUCCESS; } diff --git a/src/platform/tests/test-address.c b/src/platform/tests/test-address.c index 26072400..5ea30a57 100644 --- a/src/platform/tests/test-address.c +++ b/src/platform/tests/test-address.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2015 Red Hat, Inc. */ @@ -7,12 +7,12 @@ #include "test-common.h" -#define IP4_ADDRESS "192.0.2.1" -#define IP4_ADDRESS_PEER "192.0.2.2" +#define IP4_ADDRESS "192.0.2.1" +#define IP4_ADDRESS_PEER "192.0.2.2" #define IP4_ADDRESS_PEER2 "192.0.3.1" -#define IP4_PLEN 24 -#define IP6_ADDRESS "2001:db8:a:b:1:2:3:4" -#define IP6_PLEN 64 +#define IP4_PLEN 24 +#define IP6_ADDRESS "2001:db8:a:b:1:2:3:4" +#define IP6_PLEN 64 #define DEVICE_IFINDEX NMTSTP_ENV1_IFINDEX #define EX NMTSTP_ENV1_EX @@ -20,320 +20,420 @@ /*****************************************************************************/ static void -ip4_address_callback (NMPlatform *platform, NMPObjectType obj_type, int ifindex, NMPlatformIP4Address *received, NMPlatformSignalChangeType change_type, SignalData *data) +ip4_address_callback(NMPlatform * platform, + NMPObjectType obj_type, + int ifindex, + NMPlatformIP4Address * received, + NMPlatformSignalChangeType change_type, + SignalData * data) { - g_assert (received); - g_assert_cmpint (received->ifindex, ==, ifindex); - g_assert (data && data->name); - g_assert_cmpstr (data->name, ==, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED); + g_assert(received); + g_assert_cmpint(received->ifindex, ==, ifindex); + g_assert(data && data->name); + g_assert_cmpstr(data->name, ==, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED); - if (data->ifindex && data->ifindex != received->ifindex) - return; - if (data->change_type != change_type) - return; + if (data->ifindex && data->ifindex != received->ifindex) + return; + if (data->change_type != change_type) + return; - if (data->loop) - g_main_loop_quit (data->loop); + if (data->loop) + g_main_loop_quit(data->loop); - data->received_count++; - _LOGD ("Received signal '%s' %dth time.", data->name, data->received_count); + data->received_count++; + _LOGD("Received signal '%s' %dth time.", data->name, data->received_count); } static void -ip6_address_callback (NMPlatform *platform, NMPObjectType obj_type, int ifindex, NMPlatformIP6Address *received, NMPlatformSignalChangeType change_type, SignalData *data) +ip6_address_callback(NMPlatform * platform, + NMPObjectType obj_type, + int ifindex, + NMPlatformIP6Address * received, + NMPlatformSignalChangeType change_type, + SignalData * data) { - g_assert (received); - g_assert_cmpint (received->ifindex, ==, ifindex); - g_assert (data && data->name); - g_assert_cmpstr (data->name, ==, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED); + g_assert(received); + g_assert_cmpint(received->ifindex, ==, ifindex); + g_assert(data && data->name); + g_assert_cmpstr(data->name, ==, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED); - if (data->ifindex && data->ifindex != received->ifindex) - return; - if (data->change_type != change_type) - return; + if (data->ifindex && data->ifindex != received->ifindex) + return; + if (data->change_type != change_type) + return; - if (data->loop) - g_main_loop_quit (data->loop); + if (data->loop) + g_main_loop_quit(data->loop); - data->received_count++; - _LOGD ("Received signal '%s' %dth time.", data->name, data->received_count); + data->received_count++; + _LOGD("Received signal '%s' %dth time.", data->name, data->received_count); } /*****************************************************************************/ static void -test_ip4_address_general (void) +test_ip4_address_general(void) { - const int ifindex = DEVICE_IFINDEX; - SignalData *address_added = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip4_address_callback, ifindex); - SignalData *address_changed = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, ip4_address_callback, ifindex); - SignalData *address_removed = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip4_address_callback, ifindex); - GArray *addresses; - NMPlatformIP4Address *address; - in_addr_t addr; - guint32 lifetime = 2000; - guint32 preferred = 1000; - - inet_pton (AF_INET, IP4_ADDRESS, &addr); - - /* Add address */ - g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr)); - nmtstp_ip4_address_add (NULL, EX, ifindex, addr, IP4_PLEN, addr, lifetime, preferred, 0, NULL); - g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr)); - accept_signal (address_added); - - /* Add address again (aka update) */ - nmtstp_ip4_address_add (NULL, EX, ifindex, addr, IP4_PLEN, addr, lifetime + 100, preferred + 50, 0, NULL); - accept_signals (address_changed, 0, 1); - - /* Test address listing */ - addresses = nmtstp_platform_ip4_address_get_all (NM_PLATFORM_GET, ifindex); - g_assert (addresses); - g_assert_cmpint (addresses->len, ==, 1); - address = &g_array_index (addresses, NMPlatformIP4Address, 0); - g_assert_cmpint (address->ifindex, ==, ifindex); - g_assert_cmphex (address->address, ==, addr); - g_assert_cmphex (address->peer_address, ==, addr); - g_assert_cmpint (address->plen, ==, IP4_PLEN); - g_array_unref (addresses); - - /* Remove address */ - nmtstp_ip4_address_del (NULL, EX, ifindex, addr, IP4_PLEN, addr); - g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr)); - accept_signal (address_removed); - - /* Remove address again */ - nmtstp_ip4_address_del (NULL, EX, ifindex, addr, IP4_PLEN, addr); - - free_signal (address_added); - free_signal (address_changed); - free_signal (address_removed); + const int ifindex = DEVICE_IFINDEX; + SignalData *address_added = add_signal_ifindex(NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, + NM_PLATFORM_SIGNAL_ADDED, + ip4_address_callback, + ifindex); + SignalData *address_changed = add_signal_ifindex(NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, + NM_PLATFORM_SIGNAL_CHANGED, + ip4_address_callback, + ifindex); + SignalData *address_removed = add_signal_ifindex(NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, + NM_PLATFORM_SIGNAL_REMOVED, + ip4_address_callback, + ifindex); + GArray * addresses; + NMPlatformIP4Address *address; + in_addr_t addr; + guint32 lifetime = 2000; + guint32 preferred = 1000; + + inet_pton(AF_INET, IP4_ADDRESS, &addr); + + /* Add address */ + g_assert(!nm_platform_ip4_address_get(NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr)); + nmtstp_ip4_address_add(NULL, EX, ifindex, addr, IP4_PLEN, addr, lifetime, preferred, 0, NULL); + g_assert(nm_platform_ip4_address_get(NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr)); + accept_signal(address_added); + + /* Add address again (aka update) */ + nmtstp_ip4_address_add(NULL, + EX, + ifindex, + addr, + IP4_PLEN, + addr, + lifetime + 100, + preferred + 50, + 0, + NULL); + accept_signals(address_changed, 0, 1); + + /* Test address listing */ + addresses = nmtstp_platform_ip4_address_get_all(NM_PLATFORM_GET, ifindex); + g_assert(addresses); + g_assert_cmpint(addresses->len, ==, 1); + address = &g_array_index(addresses, NMPlatformIP4Address, 0); + g_assert_cmpint(address->ifindex, ==, ifindex); + g_assert_cmphex(address->address, ==, addr); + g_assert_cmphex(address->peer_address, ==, addr); + g_assert_cmpint(address->plen, ==, IP4_PLEN); + g_array_unref(addresses); + + /* Remove address */ + nmtstp_ip4_address_del(NULL, EX, ifindex, addr, IP4_PLEN, addr); + g_assert(!nm_platform_ip4_address_get(NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr)); + accept_signal(address_removed); + + /* Remove address again */ + nmtstp_ip4_address_del(NULL, EX, ifindex, addr, IP4_PLEN, addr); + + free_signal(address_added); + free_signal(address_changed); + free_signal(address_removed); } static void -test_ip6_address_general (void) +test_ip6_address_general(void) { - const int ifindex = DEVICE_IFINDEX; - SignalData *address_added = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip6_address_callback, ifindex); - SignalData *address_changed = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, ip6_address_callback, ifindex); - SignalData *address_removed = add_signal_ifindex (NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip6_address_callback, ifindex); - GArray *addresses; - NMPlatformIP6Address *address; - struct in6_addr addr; - guint32 lifetime = 2000; - guint32 preferred = 1000; - guint flags = 0; - - inet_pton (AF_INET6, IP6_ADDRESS, &addr); - - /* Add address */ - g_assert (!nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr)); - nmtstp_ip6_address_add (NULL, EX, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, flags); - g_assert (nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr)); - accept_signal (address_added); - - /* Add address again (aka update) */ - nmtstp_ip6_address_add (NULL, EX, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, flags); - accept_signals (address_changed, 0, 2); - - /* Test address listing */ - addresses = nmtstp_platform_ip6_address_get_all (NM_PLATFORM_GET, ifindex); - g_assert (addresses); - g_assert_cmpint (addresses->len, ==, 1); - address = &g_array_index (addresses, NMPlatformIP6Address, 0); - g_assert_cmpint (address->ifindex, ==, ifindex); - g_assert (!memcmp (&address->address, &addr, sizeof (addr))); - g_assert_cmpint (address->plen, ==, IP6_PLEN); - g_array_unref (addresses); - - /* Remove address */ - nmtstp_ip6_address_del (NULL, EX, ifindex, addr, IP6_PLEN); - g_assert (!nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr)); - accept_signal (address_removed); - - /* Remove address again */ - nmtstp_ip6_address_del (NULL, EX, ifindex, addr, IP6_PLEN); - - /* ensure not pending signal. */ - accept_signals (address_changed, 0, 1); - - free_signal (address_added); - free_signal (address_changed); - free_signal (address_removed); + const int ifindex = DEVICE_IFINDEX; + SignalData *address_added = add_signal_ifindex(NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, + NM_PLATFORM_SIGNAL_ADDED, + ip6_address_callback, + ifindex); + SignalData *address_changed = add_signal_ifindex(NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, + NM_PLATFORM_SIGNAL_CHANGED, + ip6_address_callback, + ifindex); + SignalData *address_removed = add_signal_ifindex(NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, + NM_PLATFORM_SIGNAL_REMOVED, + ip6_address_callback, + ifindex); + GArray * addresses; + NMPlatformIP6Address *address; + struct in6_addr addr; + guint32 lifetime = 2000; + guint32 preferred = 1000; + guint flags = 0; + + inet_pton(AF_INET6, IP6_ADDRESS, &addr); + + /* Add address */ + g_assert(!nm_platform_ip6_address_get(NM_PLATFORM_GET, ifindex, &addr)); + nmtstp_ip6_address_add(NULL, + EX, + ifindex, + addr, + IP6_PLEN, + in6addr_any, + lifetime, + preferred, + flags); + g_assert(nm_platform_ip6_address_get(NM_PLATFORM_GET, ifindex, &addr)); + accept_signal(address_added); + + /* Add address again (aka update) */ + nmtstp_ip6_address_add(NULL, + EX, + ifindex, + addr, + IP6_PLEN, + in6addr_any, + lifetime, + preferred, + flags); + accept_signals(address_changed, 0, 2); + + /* Test address listing */ + addresses = nmtstp_platform_ip6_address_get_all(NM_PLATFORM_GET, ifindex); + g_assert(addresses); + g_assert_cmpint(addresses->len, ==, 1); + address = &g_array_index(addresses, NMPlatformIP6Address, 0); + g_assert_cmpint(address->ifindex, ==, ifindex); + g_assert(!memcmp(&address->address, &addr, sizeof(addr))); + g_assert_cmpint(address->plen, ==, IP6_PLEN); + g_array_unref(addresses); + + /* Remove address */ + nmtstp_ip6_address_del(NULL, EX, ifindex, addr, IP6_PLEN); + g_assert(!nm_platform_ip6_address_get(NM_PLATFORM_GET, ifindex, &addr)); + accept_signal(address_removed); + + /* Remove address again */ + nmtstp_ip6_address_del(NULL, EX, ifindex, addr, IP6_PLEN); + + /* ensure not pending signal. */ + accept_signals(address_changed, 0, 1); + + free_signal(address_added); + free_signal(address_changed); + free_signal(address_removed); } static void -test_ip4_address_general_2 (void) +test_ip4_address_general_2(void) { - const int ifindex = DEVICE_IFINDEX; - SignalData *address_added = add_signal (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip4_address_callback); - SignalData *address_removed = add_signal (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip4_address_callback); - in_addr_t addr; - guint32 lifetime = 2000; - guint32 preferred = 1000; - - inet_pton (AF_INET, IP4_ADDRESS, &addr); - g_assert (ifindex > 0); - - /* Looks like addresses are not announced by kernel when the interface - * is down. Link-local IPv6 address is automatically added. - */ - g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, DEVICE_IFINDEX, NULL)); - - /* Add/delete notification */ - nmtstp_ip4_address_add (NULL, EX, ifindex, addr, IP4_PLEN, addr, lifetime, preferred, 0, NULL); - accept_signal (address_added); - g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr)); - nmtstp_ip4_address_del (NULL, EX, ifindex, addr, IP4_PLEN, addr); - accept_signal (address_removed); - g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr)); - - /* Add/delete conflict */ - nmtstp_ip4_address_add (NULL, EX, ifindex, addr, IP4_PLEN, addr, lifetime, preferred, 0, NULL); - g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr)); - accept_signal (address_added); - - free_signal (address_added); - free_signal (address_removed); + const int ifindex = DEVICE_IFINDEX; + SignalData *address_added = add_signal(NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, + NM_PLATFORM_SIGNAL_ADDED, + ip4_address_callback); + SignalData *address_removed = add_signal(NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, + NM_PLATFORM_SIGNAL_REMOVED, + ip4_address_callback); + in_addr_t addr; + guint32 lifetime = 2000; + guint32 preferred = 1000; + + inet_pton(AF_INET, IP4_ADDRESS, &addr); + g_assert(ifindex > 0); + + /* Looks like addresses are not announced by kernel when the interface + * is down. Link-local IPv6 address is automatically added. + */ + g_assert(nm_platform_link_set_up(NM_PLATFORM_GET, DEVICE_IFINDEX, NULL)); + + /* Add/delete notification */ + nmtstp_ip4_address_add(NULL, EX, ifindex, addr, IP4_PLEN, addr, lifetime, preferred, 0, NULL); + accept_signal(address_added); + g_assert(nm_platform_ip4_address_get(NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr)); + nmtstp_ip4_address_del(NULL, EX, ifindex, addr, IP4_PLEN, addr); + accept_signal(address_removed); + g_assert(!nm_platform_ip4_address_get(NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr)); + + /* Add/delete conflict */ + nmtstp_ip4_address_add(NULL, EX, ifindex, addr, IP4_PLEN, addr, lifetime, preferred, 0, NULL); + g_assert(nm_platform_ip4_address_get(NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr)); + accept_signal(address_added); + + free_signal(address_added); + free_signal(address_removed); } static void -test_ip6_address_general_2 (void) +test_ip6_address_general_2(void) { - const int ifindex = DEVICE_IFINDEX; - SignalData *address_added = add_signal (NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip6_address_callback); - SignalData *address_removed = add_signal (NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip6_address_callback); - struct in6_addr addr; - guint32 lifetime = 2000; - guint32 preferred = 1000; - guint flags = 0; - - inet_pton (AF_INET6, IP6_ADDRESS, &addr); - - /* Add/delete notification */ - nmtstp_ip6_address_add (NULL, EX, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, 0); - accept_signal (address_added); - g_assert (nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr)); - - nmtstp_ip6_address_del (NULL, EX, ifindex, addr, IP6_PLEN); - accept_signal (address_removed); - g_assert (!nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr)); - - /* Add/delete conflict */ - nmtstp_ip6_address_add (NULL, EX, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, 0); - accept_signal (address_added); - g_assert (nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr)); - - nmtstp_ip6_address_add (NULL, EX, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, flags); - ensure_no_signal (address_added); - g_assert (nm_platform_ip6_address_get (NM_PLATFORM_GET, ifindex, addr)); - - free_signal (address_added); - free_signal (address_removed); + const int ifindex = DEVICE_IFINDEX; + SignalData * address_added = add_signal(NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, + NM_PLATFORM_SIGNAL_ADDED, + ip6_address_callback); + SignalData * address_removed = add_signal(NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, + NM_PLATFORM_SIGNAL_REMOVED, + ip6_address_callback); + struct in6_addr addr; + guint32 lifetime = 2000; + guint32 preferred = 1000; + guint flags = 0; + + inet_pton(AF_INET6, IP6_ADDRESS, &addr); + + /* Add/delete notification */ + nmtstp_ip6_address_add(NULL, EX, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, 0); + accept_signal(address_added); + g_assert(nm_platform_ip6_address_get(NM_PLATFORM_GET, ifindex, &addr)); + + nmtstp_ip6_address_del(NULL, EX, ifindex, addr, IP6_PLEN); + accept_signal(address_removed); + g_assert(!nm_platform_ip6_address_get(NM_PLATFORM_GET, ifindex, &addr)); + + /* Add/delete conflict */ + nmtstp_ip6_address_add(NULL, EX, ifindex, addr, IP6_PLEN, in6addr_any, lifetime, preferred, 0); + accept_signal(address_added); + g_assert(nm_platform_ip6_address_get(NM_PLATFORM_GET, ifindex, &addr)); + + nmtstp_ip6_address_add(NULL, + EX, + ifindex, + addr, + IP6_PLEN, + in6addr_any, + lifetime, + preferred, + flags); + ensure_no_signal(address_added); + g_assert(nm_platform_ip6_address_get(NM_PLATFORM_GET, ifindex, &addr)); + + free_signal(address_added); + free_signal(address_removed); } /*****************************************************************************/ static void -test_ip4_address_peer (void) +test_ip4_address_peer(void) { - const int ifindex = DEVICE_IFINDEX; - SignalData *address_added = add_signal (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_ADDED, ip4_address_callback); - SignalData *address_removed = add_signal (NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, ip4_address_callback); - in_addr_t addr, addr_peer, addr_peer2; - guint32 lifetime = 2000; - guint32 preferred = 1000; - const NMPlatformIP4Address *a; - - inet_pton (AF_INET, IP4_ADDRESS, &addr); - inet_pton (AF_INET, IP4_ADDRESS_PEER, &addr_peer); - inet_pton (AF_INET, IP4_ADDRESS_PEER2, &addr_peer2); - g_assert (ifindex > 0); - - g_assert (addr != addr_peer); - - g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, ifindex, NULL)); - accept_signals (address_removed, 0, G_MAXINT); - accept_signals (address_added, 0, G_MAXINT); - - /* Add/delete notification */ - nmtstp_ip4_address_add (NULL, EX, ifindex, addr, IP4_PLEN, addr_peer, lifetime, preferred, 0, NULL); - accept_signal (address_added); - a = nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer); - g_assert (a); - g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer2)); - - nmtstp_ip_address_assert_lifetime ((NMPlatformIPAddress *) a, -1, lifetime, preferred); - - nmtstp_ip4_address_add (NULL, EX, ifindex, addr, IP4_PLEN, addr_peer2, lifetime, preferred, 0, NULL); - accept_signal (address_added); - g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer)); - a = nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer2); - g_assert (a); - - nmtstp_ip_address_assert_lifetime ((NMPlatformIPAddress *) a, -1, lifetime, preferred); - - g_assert (addr != addr_peer); - nmtstp_ip4_address_del (NULL, EX, ifindex, addr, IP4_PLEN, addr_peer); - accept_signal (address_removed); - g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer)); - g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer2)); - - free_signal (address_added); - free_signal (address_removed); + const int ifindex = DEVICE_IFINDEX; + SignalData * address_added = add_signal(NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, + NM_PLATFORM_SIGNAL_ADDED, + ip4_address_callback); + SignalData * address_removed = add_signal(NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, + NM_PLATFORM_SIGNAL_REMOVED, + ip4_address_callback); + in_addr_t addr, addr_peer, addr_peer2; + guint32 lifetime = 2000; + guint32 preferred = 1000; + const NMPlatformIP4Address *a; + + inet_pton(AF_INET, IP4_ADDRESS, &addr); + inet_pton(AF_INET, IP4_ADDRESS_PEER, &addr_peer); + inet_pton(AF_INET, IP4_ADDRESS_PEER2, &addr_peer2); + g_assert(ifindex > 0); + + g_assert(addr != addr_peer); + + g_assert(nm_platform_link_set_up(NM_PLATFORM_GET, ifindex, NULL)); + accept_signals(address_removed, 0, G_MAXINT); + accept_signals(address_added, 0, G_MAXINT); + + /* Add/delete notification */ + nmtstp_ip4_address_add(NULL, + EX, + ifindex, + addr, + IP4_PLEN, + addr_peer, + lifetime, + preferred, + 0, + NULL); + accept_signal(address_added); + a = nm_platform_ip4_address_get(NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer); + g_assert(a); + g_assert(!nm_platform_ip4_address_get(NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer2)); + + nmtstp_ip_address_assert_lifetime((NMPlatformIPAddress *) a, -1, lifetime, preferred); + + nmtstp_ip4_address_add(NULL, + EX, + ifindex, + addr, + IP4_PLEN, + addr_peer2, + lifetime, + preferred, + 0, + NULL); + accept_signal(address_added); + g_assert(nm_platform_ip4_address_get(NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer)); + a = nm_platform_ip4_address_get(NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer2); + g_assert(a); + + nmtstp_ip_address_assert_lifetime((NMPlatformIPAddress *) a, -1, lifetime, preferred); + + g_assert(addr != addr_peer); + nmtstp_ip4_address_del(NULL, EX, ifindex, addr, IP4_PLEN, addr_peer); + accept_signal(address_removed); + g_assert(!nm_platform_ip4_address_get(NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer)); + g_assert(nm_platform_ip4_address_get(NM_PLATFORM_GET, ifindex, addr, IP4_PLEN, addr_peer2)); + + free_signal(address_added); + free_signal(address_removed); } /*****************************************************************************/ static void -test_ip4_address_peer_zero (void) +test_ip4_address_peer_zero(void) { - const int ifindex = DEVICE_IFINDEX; - in_addr_t addr, addr_peer; - guint32 lifetime = 2000; - guint32 preferred = 1000; - const gint8 plen = 24; - const char *label = NULL; - in_addr_t peers[3], r_peers[3]; - int i; - GArray *addrs; - - g_assert (ifindex > 0); - - inet_pton (AF_INET, "192.168.5.2", &addr); - inet_pton (AF_INET, "192.168.6.2", &addr_peer); - peers[0] = addr; - peers[1] = addr_peer; - peers[2] = 0; - - g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, ifindex, NULL)); - - nmtst_rand_perm (NULL, r_peers, peers, sizeof (peers[0]), G_N_ELEMENTS (peers)); - for (i = 0; i < G_N_ELEMENTS (peers); i++) { - g_assert (!nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, plen, r_peers[i])); - - nmtstp_ip4_address_add (NULL, EX, ifindex, addr, plen, r_peers[i], lifetime, preferred, 0, label); - - addrs = nmtstp_platform_ip4_address_get_all (NM_PLATFORM_GET, ifindex); - g_assert (addrs); - g_assert_cmpint (addrs->len, ==, i + 1); - g_array_unref (addrs); - } - - if (nmtst_is_debug () && nmtstp_is_root_test ()) - nmtstp_run_command_check ("ip address show dev %s", DEVICE_NAME); - - nmtst_rand_perm (NULL, r_peers, peers, sizeof (peers[0]), G_N_ELEMENTS (peers)); - for (i = 0; i < G_N_ELEMENTS (peers); i++) { - g_assert (nm_platform_ip4_address_get (NM_PLATFORM_GET, ifindex, addr, plen, r_peers[i])); - - nmtstp_ip4_address_del (NULL, EX, ifindex, addr, plen, r_peers[i]); - - addrs = nmtstp_platform_ip4_address_get_all (NM_PLATFORM_GET, ifindex); - g_assert (addrs); - g_assert_cmpint (addrs->len, ==, G_N_ELEMENTS (peers) - i - 1); - g_array_unref (addrs); - } + const int ifindex = DEVICE_IFINDEX; + in_addr_t addr, addr_peer; + guint32 lifetime = 2000; + guint32 preferred = 1000; + const gint8 plen = 24; + const char *label = NULL; + in_addr_t peers[3], r_peers[3]; + int i; + GArray * addrs; + + g_assert(ifindex > 0); + + inet_pton(AF_INET, "192.168.5.2", &addr); + inet_pton(AF_INET, "192.168.6.2", &addr_peer); + peers[0] = addr; + peers[1] = addr_peer; + peers[2] = 0; + + g_assert(nm_platform_link_set_up(NM_PLATFORM_GET, ifindex, NULL)); + + nmtst_rand_perm(NULL, r_peers, peers, sizeof(peers[0]), G_N_ELEMENTS(peers)); + for (i = 0; i < G_N_ELEMENTS(peers); i++) { + g_assert(!nm_platform_ip4_address_get(NM_PLATFORM_GET, ifindex, addr, plen, r_peers[i])); + + nmtstp_ip4_address_add(NULL, + EX, + ifindex, + addr, + plen, + r_peers[i], + lifetime, + preferred, + 0, + label); + + addrs = nmtstp_platform_ip4_address_get_all(NM_PLATFORM_GET, ifindex); + g_assert(addrs); + g_assert_cmpint(addrs->len, ==, i + 1); + g_array_unref(addrs); + } + + if (nmtst_is_debug() && nmtstp_is_root_test()) + nmtstp_run_command_check("ip address show dev %s", DEVICE_NAME); + + nmtst_rand_perm(NULL, r_peers, peers, sizeof(peers[0]), G_N_ELEMENTS(peers)); + for (i = 0; i < G_N_ELEMENTS(peers); i++) { + g_assert(nm_platform_ip4_address_get(NM_PLATFORM_GET, ifindex, addr, plen, r_peers[i])); + + nmtstp_ip4_address_del(NULL, EX, ifindex, addr, plen, r_peers[i]); + + addrs = nmtstp_platform_ip4_address_get_all(NM_PLATFORM_GET, ifindex); + g_assert(addrs); + g_assert_cmpint(addrs->len, ==, G_N_ELEMENTS(peers) - i - 1); + g_array_unref(addrs); + } } /*****************************************************************************/ @@ -341,9 +441,9 @@ test_ip4_address_peer_zero (void) NMTstpSetupFunc const _nmtstp_setup_platform_func = SETUP; void -_nmtstp_init_tests (int *argc, char ***argv) +_nmtstp_init_tests(int *argc, char ***argv) { - nmtst_init_with_logging (argc, argv, NULL, "ALL"); + nmtst_init_with_logging(argc, argv, NULL, "ALL"); } /***************************************************************************** @@ -351,15 +451,15 @@ _nmtstp_init_tests (int *argc, char ***argv) *****************************************************************************/ void -_nmtstp_setup_tests (void) +_nmtstp_setup_tests(void) { #define add_test_func(testpath, test_func) nmtstp_env1_add_test_func(testpath, test_func, FALSE) - add_test_func ("/address/ipv4/general", test_ip4_address_general); - add_test_func ("/address/ipv6/general", test_ip6_address_general); + add_test_func("/address/ipv4/general", test_ip4_address_general); + add_test_func("/address/ipv6/general", test_ip6_address_general); - add_test_func ("/address/ipv4/general-2", test_ip4_address_general_2); - add_test_func ("/address/ipv6/general-2", test_ip6_address_general_2); + add_test_func("/address/ipv4/general-2", test_ip4_address_general_2); + add_test_func("/address/ipv6/general-2", test_ip6_address_general_2); - add_test_func ("/address/ipv4/peer", test_ip4_address_peer); - add_test_func ("/address/ipv4/peer/zero", test_ip4_address_peer_zero); + add_test_func("/address/ipv4/peer", test_ip4_address_peer); + add_test_func("/address/ipv4/peer/zero", test_ip4_address_peer_zero); } diff --git a/src/platform/tests/test-cleanup.c b/src/platform/tests/test-cleanup.c index d19ff1f0..c364bfa1 100644 --- a/src/platform/tests/test-cleanup.c +++ b/src/platform/tests/test-cleanup.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2016 Red Hat, Inc. */ @@ -8,113 +8,181 @@ #include "test-common.h" static void -test_cleanup_internal (void) +test_cleanup_internal(void) { - SignalData *link_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, DEVICE_NAME); - int ifindex; - GArray *addresses4; - GArray *addresses6; - GPtrArray *routes4; - GPtrArray *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); - - /* Create and set up device */ - g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_link_dummy_add (NM_PLATFORM_GET, DEVICE_NAME, NULL))); - 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)); - ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); - g_assert (ifindex > 0); - - /* wait for kernel to add the IPv6 link local address... it takes a bit. */ - NMTST_WAIT_ASSERT (300, { - gs_unref_array GArray *addrs = NULL; - const NMPlatformIP6Address *a; - - if (nmtst_wait_iteration > 0) { - nmtstp_wait_for_signal (NM_PLATFORM_GET, nmtst_wait_remaining_us / 1000); - nm_platform_process_events (NM_PLATFORM_GET); - } - addrs = nmtstp_platform_ip6_address_get_all (NM_PLATFORM_GET, ifindex); - if ( addrs->len == 1 - && (a = &g_array_index (addrs, NMPlatformIP6Address, 0)) - && IN6_IS_ADDR_LINKLOCAL (&a->address)) - break; - }); - - g_assert (nm_platform_ip4_address_add (NM_PLATFORM_GET, ifindex, addr4, plen4, addr4, nm_platform_ip4_broadcast_address_create (addr4, plen4), lifetime, preferred, 0, NULL)); - g_assert (nm_platform_ip6_address_add (NM_PLATFORM_GET, ifindex, addr6, plen6, in6addr_any, lifetime, preferred, flags)); - nmtstp_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, gateway4, 32, INADDR_ANY, 0, metric, mss); - nmtstp_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network4, plen4, gateway4, 0, metric, mss); - nmtstp_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, 0, 0, gateway4, 0, metric, mss); - nmtstp_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, gateway6, 128, in6addr_any, in6addr_any, metric, mss); - nmtstp_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network6, plen6, gateway6, in6addr_any, metric, mss); - nmtstp_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, in6addr_any, 0, gateway6, in6addr_any, metric, mss); - - addresses4 = nmtstp_platform_ip4_address_get_all (NM_PLATFORM_GET, ifindex); - addresses6 = nmtstp_platform_ip6_address_get_all (NM_PLATFORM_GET, ifindex); - routes4 = nmtstp_ip4_route_get_all (NM_PLATFORM_GET, ifindex); - routes6 = nmtstp_ip6_route_get_all (NM_PLATFORM_GET, ifindex); - - g_assert_cmpint (addresses4->len, ==, 1); - g_assert_cmpint (addresses6->len, ==, 2); /* also has a IPv6 LL address. */ - g_assert_cmpint (routes4->len, ==, 3); - g_assert_cmpint (routes6->len, ==, 3); - - g_array_unref (addresses4); - g_array_unref (addresses6); - g_ptr_array_unref (routes4); - g_ptr_array_unref (routes6); - - /* Delete interface with all addresses and routes */ - g_assert (nm_platform_link_delete (NM_PLATFORM_GET, ifindex)); - - addresses4 = nmtstp_platform_ip4_address_get_all (NM_PLATFORM_GET, ifindex); - addresses6 = nmtstp_platform_ip6_address_get_all (NM_PLATFORM_GET, ifindex); - routes4 = nmtstp_ip4_route_get_all (NM_PLATFORM_GET, ifindex); - routes6 = nmtstp_ip6_route_get_all (NM_PLATFORM_GET, ifindex); - - g_assert_cmpint (addresses4->len, ==, 0); - g_assert_cmpint (addresses6->len, ==, 0); - g_assert (!routes4); - g_assert (!routes6); - - g_array_unref (addresses4); - g_array_unref (addresses6); + SignalData * link_added = add_signal_ifname(NM_PLATFORM_SIGNAL_LINK_CHANGED, + NM_PLATFORM_SIGNAL_ADDED, + link_callback, + DEVICE_NAME); + int ifindex; + GArray * addresses4; + GArray * addresses6; + GPtrArray * routes4; + GPtrArray * 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); + + /* Create and set up device */ + g_assert(NMTST_NM_ERR_SUCCESS(nm_platform_link_dummy_add(NM_PLATFORM_GET, DEVICE_NAME, NULL))); + 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)); + ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME); + g_assert(ifindex > 0); + + /* wait for kernel to add the IPv6 link local address... it takes a bit. */ + NMTST_WAIT_ASSERT(300, { + gs_unref_array GArray * addrs = NULL; + const NMPlatformIP6Address *a; + + if (nmtst_wait_iteration > 0) { + nmtstp_wait_for_signal(NM_PLATFORM_GET, nmtst_wait_remaining_us / 1000); + nm_platform_process_events(NM_PLATFORM_GET); + } + addrs = nmtstp_platform_ip6_address_get_all(NM_PLATFORM_GET, ifindex); + if (addrs->len == 1 && (a = &g_array_index(addrs, NMPlatformIP6Address, 0)) + && IN6_IS_ADDR_LINKLOCAL(&a->address)) + break; + }); + + g_assert(nm_platform_ip4_address_add(NM_PLATFORM_GET, + ifindex, + addr4, + plen4, + addr4, + nm_platform_ip4_broadcast_address_create(addr4, plen4), + lifetime, + preferred, + 0, + NULL)); + g_assert(nm_platform_ip6_address_add(NM_PLATFORM_GET, + ifindex, + addr6, + plen6, + in6addr_any, + lifetime, + preferred, + flags)); + nmtstp_ip4_route_add(NM_PLATFORM_GET, + ifindex, + NM_IP_CONFIG_SOURCE_USER, + gateway4, + 32, + INADDR_ANY, + 0, + metric, + mss); + nmtstp_ip4_route_add(NM_PLATFORM_GET, + ifindex, + NM_IP_CONFIG_SOURCE_USER, + network4, + plen4, + gateway4, + 0, + metric, + mss); + nmtstp_ip4_route_add(NM_PLATFORM_GET, + ifindex, + NM_IP_CONFIG_SOURCE_USER, + 0, + 0, + gateway4, + 0, + metric, + mss); + nmtstp_ip6_route_add(NM_PLATFORM_GET, + ifindex, + NM_IP_CONFIG_SOURCE_USER, + gateway6, + 128, + in6addr_any, + in6addr_any, + metric, + mss); + nmtstp_ip6_route_add(NM_PLATFORM_GET, + ifindex, + NM_IP_CONFIG_SOURCE_USER, + network6, + plen6, + gateway6, + in6addr_any, + metric, + mss); + nmtstp_ip6_route_add(NM_PLATFORM_GET, + ifindex, + NM_IP_CONFIG_SOURCE_USER, + in6addr_any, + 0, + gateway6, + in6addr_any, + metric, + mss); + + addresses4 = nmtstp_platform_ip4_address_get_all(NM_PLATFORM_GET, ifindex); + addresses6 = nmtstp_platform_ip6_address_get_all(NM_PLATFORM_GET, ifindex); + routes4 = nmtstp_ip4_route_get_all(NM_PLATFORM_GET, ifindex); + routes6 = nmtstp_ip6_route_get_all(NM_PLATFORM_GET, ifindex); + + g_assert_cmpint(addresses4->len, ==, 1); + g_assert_cmpint(addresses6->len, ==, 2); /* also has a IPv6 LL address. */ + g_assert_cmpint(routes4->len, ==, 3); + g_assert_cmpint(routes6->len, ==, 3); + + g_array_unref(addresses4); + g_array_unref(addresses6); + g_ptr_array_unref(routes4); + g_ptr_array_unref(routes6); + + /* Delete interface with all addresses and routes */ + g_assert(nm_platform_link_delete(NM_PLATFORM_GET, ifindex)); + + addresses4 = nmtstp_platform_ip4_address_get_all(NM_PLATFORM_GET, ifindex); + addresses6 = nmtstp_platform_ip6_address_get_all(NM_PLATFORM_GET, ifindex); + routes4 = nmtstp_ip4_route_get_all(NM_PLATFORM_GET, ifindex); + routes6 = nmtstp_ip6_route_get_all(NM_PLATFORM_GET, ifindex); + + g_assert_cmpint(addresses4->len, ==, 0); + g_assert_cmpint(addresses6->len, ==, 0); + g_assert(!routes4); + g_assert(!routes6); + + g_array_unref(addresses4); + g_array_unref(addresses6); } NMTstpSetupFunc const _nmtstp_setup_platform_func = SETUP; void -_nmtstp_init_tests (int *argc, char ***argv) +_nmtstp_init_tests(int *argc, char ***argv) { - nmtst_init_with_logging (argc, argv, NULL, "ALL"); + nmtst_init_with_logging(argc, argv, NULL, "ALL"); } void -_nmtstp_setup_tests (void) +_nmtstp_setup_tests(void) { - nmtstp_link_delete (NM_PLATFORM_GET, -1, -1, DEVICE_NAME, FALSE); + nmtstp_link_delete(NM_PLATFORM_GET, -1, -1, DEVICE_NAME, FALSE); - g_test_add_func ("/internal", test_cleanup_internal); - /* FIXME: add external cleanup check */ + g_test_add_func("/internal", test_cleanup_internal); + /* FIXME: add external cleanup check */ } diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c index 9f6a29bc..e305357a 100644 --- a/src/platform/tests/test-common.c +++ b/src/platform/tests/test-common.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2016 - 2017 Red Hat, Inc. */ @@ -14,2021 +14,2461 @@ #include "test-common.h" #define SIGNAL_DATA_FMT "'%s-%s' ifindex %d%s%s%s (%d times received)" -#define SIGNAL_DATA_ARG(data) (data)->name, nm_platform_signal_change_type_to_string ((data)->change_type), (data)->ifindex, (data)->ifname ? " ifname '" : "", (data)->ifname ?: "", (data)->ifname ? "'" : "", (data)->received_count +#define SIGNAL_DATA_ARG(data) \ + (data)->name, nm_platform_signal_change_type_to_string((data)->change_type), (data)->ifindex, \ + (data)->ifname ? " ifname '" : "", (data)->ifname ?: "", (data)->ifname ? "'" : "", \ + (data)->received_count int NMTSTP_ENV1_IFINDEX = -1; -int NMTSTP_ENV1_EX = -1; +int NMTSTP_ENV1_EX = -1; /*****************************************************************************/ void -nmtstp_setup_platform (void) +nmtstp_setup_platform(void) { - g_assert (_nmtstp_setup_platform_func); - _nmtstp_setup_platform_func (); + g_assert(_nmtstp_setup_platform_func); + _nmtstp_setup_platform_func(); } gboolean -nmtstp_is_root_test (void) +nmtstp_is_root_test(void) { - g_assert (_nmtstp_setup_platform_func); - return _nmtstp_setup_platform_func == nm_linux_platform_setup; + g_assert(_nmtstp_setup_platform_func); + return _nmtstp_setup_platform_func == nm_linux_platform_setup; } gboolean -nmtstp_is_sysfs_writable (void) +nmtstp_is_sysfs_writable(void) { - return !nmtstp_is_root_test () - || (access ("/sys/devices", W_OK) == 0); + return !nmtstp_is_root_test() || (access("/sys/devices", W_OK) == 0); } static void -_init_platform (NMPlatform **platform, gboolean external_command) +_init_platform(NMPlatform **platform, gboolean external_command) { - g_assert (platform); - if (!*platform) - *platform = NM_PLATFORM_GET; - g_assert (NM_IS_PLATFORM (*platform)); + g_assert(platform); + if (!*platform) + *platform = NM_PLATFORM_GET; + g_assert(NM_IS_PLATFORM(*platform)); - if (external_command) - g_assert (NM_IS_LINUX_PLATFORM (*platform)); + if (external_command) + g_assert(NM_IS_LINUX_PLATFORM(*platform)); } /*****************************************************************************/ static GArray * -_ipx_address_get_all (NMPlatform *self, int ifindex, NMPObjectType obj_type) +_ipx_address_get_all(NMPlatform *self, int ifindex, NMPObjectType obj_type) { - NMPLookup lookup; + NMPLookup lookup; - g_assert (NM_IS_PLATFORM (self)); - g_assert (ifindex > 0); - g_assert (NM_IN_SET (obj_type, NMP_OBJECT_TYPE_IP4_ADDRESS, NMP_OBJECT_TYPE_IP6_ADDRESS)); - nmp_lookup_init_object (&lookup, - obj_type, - ifindex); - return nmp_cache_lookup_to_array (nm_platform_lookup (self, &lookup), - obj_type, - FALSE /*addresses are always visible. */); + g_assert(NM_IS_PLATFORM(self)); + g_assert(ifindex > 0); + g_assert(NM_IN_SET(obj_type, NMP_OBJECT_TYPE_IP4_ADDRESS, NMP_OBJECT_TYPE_IP6_ADDRESS)); + nmp_lookup_init_object(&lookup, obj_type, ifindex); + return nmp_cache_lookup_to_array(nm_platform_lookup(self, &lookup), + obj_type, + FALSE /*addresses are always visible. */); } GArray * -nmtstp_platform_ip4_address_get_all (NMPlatform *self, int ifindex) +nmtstp_platform_ip4_address_get_all(NMPlatform *self, int ifindex) { - return _ipx_address_get_all (self, ifindex, NMP_OBJECT_TYPE_IP4_ADDRESS); + return _ipx_address_get_all(self, ifindex, NMP_OBJECT_TYPE_IP4_ADDRESS); } GArray * -nmtstp_platform_ip6_address_get_all (NMPlatform *self, int ifindex) +nmtstp_platform_ip6_address_get_all(NMPlatform *self, int ifindex) { - return _ipx_address_get_all (self, ifindex, NMP_OBJECT_TYPE_IP6_ADDRESS); + return _ipx_address_get_all(self, ifindex, NMP_OBJECT_TYPE_IP6_ADDRESS); +} + +const NMPlatformIPAddress * +nmtstp_platform_ip_address_find(NMPlatform *self, int ifindex, int addr_family, gconstpointer addr) +{ + const gboolean IS_IPv4 = NM_IS_IPv4(addr_family); + const NMPlatformIPAddress *found = NULL; + NMDedupMultiIter iter; + const NMPObject * obj; + NMPLookup lookup; + + g_assert(NM_IS_PLATFORM(self)); + nm_assert(ifindex >= 0); + nm_assert_addr_family(addr_family); + nm_assert(addr); + + nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4), ifindex); + nm_platform_iter_obj_for_each(&iter, self, &lookup, &obj) + { + const NMPlatformIPAddress *a = NMP_OBJECT_CAST_IP_ADDRESS(obj); + + g_assert(NMP_OBJECT_GET_ADDR_FAMILY(obj) == addr_family); + g_assert(ifindex <= 0 || a->ifindex == ifindex); + + if (memcmp(addr, a->address_ptr, nm_utils_addr_family_to_size(addr_family)) != 0) + continue; + + g_assert(!found); + found = a; + } + + if (!IS_IPv4 && ifindex > 0) + g_assert(found + == (const NMPlatformIPAddress *) nm_platform_ip6_address_get(self, ifindex, addr)); + + return found; +} + +/*****************************************************************************/ + +typedef struct { + NMIPAddr addr; + int addr_family; + bool found : 1; +} IPAddressesAssertData; + +void +_nmtstp_platform_ip_addresses_assert(const char * filename, + int lineno, + NMPlatform * self, + int ifindex, + gboolean force_exact_4, + gboolean force_exact_6, + gboolean ignore_ll6, + guint addrs_len, + const char *const *addrs) +{ + gs_free IPAddressesAssertData *addrs_bin = NULL; + int IS_IPv4; + guint i; + + g_assert(filename); + g_assert(lineno >= 0); + g_assert(NM_IS_PLATFORM(self)); + g_assert(ifindex >= 0); + + addrs_bin = g_new(IPAddressesAssertData, addrs_len); + + for (i = 0; i < addrs_len; i++) { + const char *addrstr = addrs[i]; + int addr_family; + NMIPAddr a; + + if (!addrstr) { + addr_family = AF_UNSPEC; + a = nm_ip_addr_zero; + } else if (inet_pton(AF_INET, addrstr, &a) == 1) + addr_family = AF_INET; + else if (inet_pton(AF_INET6, addrstr, &a) == 1) + addr_family = AF_INET6; + else + g_error("%s:%d: invalid IP address in argument: %s", filename, lineno, addrstr); + + addrs_bin[i] = (IPAddressesAssertData){ + .addr_family = addr_family, + .addr = a, + .found = FALSE, + }; + } + + for (IS_IPv4 = 1; IS_IPv4 >= 0; IS_IPv4--) { + const int addr_family = IS_IPv4 ? AF_INET : AF_INET6; + gs_unref_ptrarray GPtrArray *plat_addrs = NULL; + NMPLookup lookup; + guint j; + + plat_addrs = nm_platform_lookup_clone( + self, + nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4), ifindex), + NULL, + NULL); + + for (i = 0; i < addrs_len; i++) { + IPAddressesAssertData *addr_bin = &addrs_bin[i]; + + if (addr_bin->addr_family != addr_family) + continue; + + g_assert(!addr_bin->found); + for (j = 0; j < nm_g_ptr_array_len(plat_addrs);) { + const NMPlatformIPAddress *a = NMP_OBJECT_CAST_IP_ADDRESS(plat_addrs->pdata[j]); + + if (memcmp(&addr_bin->addr, + a->address_ptr, + nm_utils_addr_family_to_size(addr_family)) + != 0) { + j++; + continue; + } + + g_assert(!addr_bin->found); + addr_bin->found = TRUE; + g_ptr_array_remove_index_fast(plat_addrs, j); + } + + if (!addr_bin->found) { + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + + g_error("%s:%d: IPv%c address %s was not found on ifindex %d", + filename, + lineno, + nm_utils_addr_family_to_char(addr_bin->addr_family), + nm_utils_inet_ntop(addr_bin->addr_family, &addr_bin->addr, sbuf), + ifindex); + } + } + if (!IS_IPv4 && ignore_ll6 && nm_g_ptr_array_len(plat_addrs) > 0) { + /* we prune all remaining, non-matching IPv6 link local addresses. */ + for (j = 0; j < nm_g_ptr_array_len(plat_addrs);) { + const NMPlatformIPAddress *a = NMP_OBJECT_CAST_IP_ADDRESS(plat_addrs->pdata[j]); + + if (!IN6_IS_ADDR_LINKLOCAL(a->address_ptr)) { + j++; + continue; + } + + g_ptr_array_remove_index_fast(plat_addrs, j); + } + } + if ((IS_IPv4 ? force_exact_4 : force_exact_6) && nm_g_ptr_array_len(plat_addrs) > 0) { + char sbuf[sizeof(_nm_utils_to_string_buffer)]; + + g_error("%s:%d: %u IPv%c addresses found on ifindex %d that should not be there (one " + "is %s)", + filename, + lineno, + plat_addrs->len, + nm_utils_addr_family_to_char(addr_family), + ifindex, + nmp_object_to_string(plat_addrs->pdata[0], + NMP_OBJECT_TO_STRING_PUBLIC, + sbuf, + sizeof(sbuf))); + } + } } /*****************************************************************************/ gboolean -nmtstp_platform_ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen, guint32 metric) +nmtstp_platform_ip4_route_delete(NMPlatform *platform, + int ifindex, + in_addr_t network, + guint8 plen, + guint32 metric) { - NMDedupMultiIter iter; + NMDedupMultiIter iter; - nm_platform_process_events (platform); + nm_platform_process_events(platform); - nm_dedup_multi_iter_for_each (&iter, - nm_platform_lookup_object (platform, - NMP_OBJECT_TYPE_IP4_ROUTE, - ifindex)) { - const NMPlatformIP4Route *r = NMP_OBJECT_CAST_IP4_ROUTE (iter.current->obj); + nm_dedup_multi_iter_for_each ( + &iter, + nm_platform_lookup_object(platform, NMP_OBJECT_TYPE_IP4_ROUTE, ifindex)) { + const NMPlatformIP4Route *r = NMP_OBJECT_CAST_IP4_ROUTE(iter.current->obj); - if ( r->ifindex != ifindex - || r->network != network - || r->plen != plen - || r->metric != metric) { - continue; - } + if (r->ifindex != ifindex || r->network != network || r->plen != plen + || r->metric != metric) { + continue; + } - return nm_platform_object_delete (platform, NMP_OBJECT_UP_CAST (r)); - } + return nm_platform_object_delete(platform, NMP_OBJECT_UP_CAST(r)); + } - return TRUE; + return TRUE; } gboolean -nmtstp_platform_ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric) +nmtstp_platform_ip6_route_delete(NMPlatform * platform, + int ifindex, + struct in6_addr network, + guint8 plen, + guint32 metric) { - NMDedupMultiIter iter; + NMDedupMultiIter iter; - nm_platform_process_events (platform); + nm_platform_process_events(platform); - nm_dedup_multi_iter_for_each (&iter, - nm_platform_lookup_object (platform, - NMP_OBJECT_TYPE_IP6_ROUTE, - ifindex)) { - const NMPlatformIP6Route *r = NMP_OBJECT_CAST_IP6_ROUTE (iter.current->obj); + nm_dedup_multi_iter_for_each ( + &iter, + nm_platform_lookup_object(platform, NMP_OBJECT_TYPE_IP6_ROUTE, ifindex)) { + const NMPlatformIP6Route *r = NMP_OBJECT_CAST_IP6_ROUTE(iter.current->obj); - if ( r->ifindex != ifindex - || !IN6_ARE_ADDR_EQUAL (&r->network, &network) - || r->plen != plen - || r->metric != metric) { - continue; - } + if (r->ifindex != ifindex || !IN6_ARE_ADDR_EQUAL(&r->network, &network) || r->plen != plen + || r->metric != metric) { + continue; + } - return nm_platform_object_delete (platform, NMP_OBJECT_UP_CAST (r)); - } + return nm_platform_object_delete(platform, NMP_OBJECT_UP_CAST(r)); + } - return TRUE; + return TRUE; } /*****************************************************************************/ SignalData * -add_signal_full (const char *name, NMPlatformSignalChangeType change_type, GCallback callback, int ifindex, const char *ifname) +add_signal_full(const char * name, + NMPlatformSignalChangeType change_type, + GCallback callback, + int ifindex, + const char * ifname) { - SignalData *data = g_new0 (SignalData, 1); + SignalData *data = g_new0(SignalData, 1); - data->name = name; - data->change_type = change_type; - data->received_count = 0; - data->handler_id = g_signal_connect (NM_PLATFORM_GET, name, callback, data); - data->ifindex = ifindex; - data->ifname = ifname; + data->name = name; + data->change_type = change_type; + data->received_count = 0; + data->handler_id = g_signal_connect(NM_PLATFORM_GET, name, callback, data); + data->ifindex = ifindex; + data->ifname = ifname; - g_assert (data->handler_id > 0); + g_assert(data->handler_id > 0); - return data; + return data; } void -_accept_signal (const char *file, int line, const char *func, SignalData *data) -{ - _LOGD ("NMPlatformSignalAssert: %s:%d, %s(): Accepting signal one time: "SIGNAL_DATA_FMT, file, line, func, SIGNAL_DATA_ARG (data)); - if (data->received_count != 1) - g_error ("NMPlatformSignalAssert: %s:%d, %s(): failure to accept signal one time: "SIGNAL_DATA_FMT, file, line, func, SIGNAL_DATA_ARG (data)); - data->received_count = 0; +_accept_signal(const char *file, int line, const char *func, SignalData *data) +{ + _LOGD("NMPlatformSignalAssert: %s:%d, %s(): Accepting signal one time: " SIGNAL_DATA_FMT, + file, + line, + func, + SIGNAL_DATA_ARG(data)); + if (data->received_count != 1) + g_error("NMPlatformSignalAssert: %s:%d, %s(): failure to accept signal one " + "time: " SIGNAL_DATA_FMT, + file, + line, + func, + SIGNAL_DATA_ARG(data)); + data->received_count = 0; } void -_accept_signals (const char *file, int line, const char *func, SignalData *data, int min, int max) -{ - _LOGD ("NMPlatformSignalAssert: %s:%d, %s(): Accepting signal [%d,%d] times: "SIGNAL_DATA_FMT, file, line, func, min, max, SIGNAL_DATA_ARG (data)); - if (data->received_count < min || data->received_count > max) - g_error ("NMPlatformSignalAssert: %s:%d, %s(): failure to accept signal [%d,%d] times: "SIGNAL_DATA_FMT, file, line, func, min, max, SIGNAL_DATA_ARG (data)); - data->received_count = 0; +_accept_signals(const char *file, int line, const char *func, SignalData *data, int min, int max) +{ + _LOGD("NMPlatformSignalAssert: %s:%d, %s(): Accepting signal [%d,%d] times: " SIGNAL_DATA_FMT, + file, + line, + func, + min, + max, + SIGNAL_DATA_ARG(data)); + if (data->received_count < min || data->received_count > max) + g_error("NMPlatformSignalAssert: %s:%d, %s(): failure to accept signal [%d,%d] " + "times: " SIGNAL_DATA_FMT, + file, + line, + func, + min, + max, + SIGNAL_DATA_ARG(data)); + data->received_count = 0; } void -_ensure_no_signal (const char *file, int line, const char *func, SignalData *data) -{ - _LOGD ("NMPlatformSignalAssert: %s:%d, %s(): Accepting signal 0 times: "SIGNAL_DATA_FMT, file, line, func, SIGNAL_DATA_ARG (data)); - if (data->received_count > 0) - g_error ("NMPlatformSignalAssert: %s:%d, %s(): failure to accept signal 0 times: "SIGNAL_DATA_FMT, file, line, func, SIGNAL_DATA_ARG (data)); +_ensure_no_signal(const char *file, int line, const char *func, SignalData *data) +{ + _LOGD("NMPlatformSignalAssert: %s:%d, %s(): Accepting signal 0 times: " SIGNAL_DATA_FMT, + file, + line, + func, + SIGNAL_DATA_ARG(data)); + if (data->received_count > 0) + g_error("NMPlatformSignalAssert: %s:%d, %s(): failure to accept signal 0 " + "times: " SIGNAL_DATA_FMT, + file, + line, + func, + SIGNAL_DATA_ARG(data)); } void -_accept_or_wait_signal (const char *file, int line, const char *func, SignalData *data) +_accept_or_wait_signal(const char *file, int line, const char *func, SignalData *data) { - _LOGD ("NMPlatformSignalAssert: %s:%d, %s(): accept-or-wait signal: "SIGNAL_DATA_FMT, file, line, func, SIGNAL_DATA_ARG (data)); - if (data->received_count == 0) { - data->loop = g_main_loop_new (NULL, FALSE); - g_main_loop_run (data->loop); - nm_clear_pointer (&data->loop, g_main_loop_unref); - } + _LOGD("NMPlatformSignalAssert: %s:%d, %s(): accept-or-wait signal: " SIGNAL_DATA_FMT, + file, + line, + func, + SIGNAL_DATA_ARG(data)); + if (data->received_count == 0) { + data->loop = g_main_loop_new(NULL, FALSE); + g_main_loop_run(data->loop); + nm_clear_pointer(&data->loop, g_main_loop_unref); + } - _accept_signal (file, line, func, data); + _accept_signal(file, line, func, data); } void -_wait_signal (const char *file, int line, const char *func, SignalData *data) +_wait_signal(const char *file, int line, const char *func, SignalData *data) { - _LOGD ("NMPlatformSignalAssert: %s:%d, %s(): wait signal: "SIGNAL_DATA_FMT, file, line, func, SIGNAL_DATA_ARG (data)); - if (data->received_count) - g_error ("NMPlatformSignalAssert: %s:%d, %s(): failure to wait for signal: "SIGNAL_DATA_FMT, file, line, func, SIGNAL_DATA_ARG (data)); + _LOGD("NMPlatformSignalAssert: %s:%d, %s(): wait signal: " SIGNAL_DATA_FMT, + file, + line, + func, + SIGNAL_DATA_ARG(data)); + if (data->received_count) + g_error("NMPlatformSignalAssert: %s:%d, %s(): failure to wait for signal: " SIGNAL_DATA_FMT, + file, + line, + func, + SIGNAL_DATA_ARG(data)); - data->loop = g_main_loop_new (NULL, FALSE); - g_main_loop_run (data->loop); - nm_clear_pointer (&data->loop, g_main_loop_unref); + data->loop = g_main_loop_new(NULL, FALSE); + g_main_loop_run(data->loop); + nm_clear_pointer(&data->loop, g_main_loop_unref); - _accept_signal (file, line, func, data); + _accept_signal(file, line, func, data); } void -_free_signal (const char *file, int line, const char *func, SignalData *data) +_free_signal(const char *file, int line, const char *func, SignalData *data) { - _LOGD ("NMPlatformSignalAssert: %s:%d, %s(): free signal: "SIGNAL_DATA_FMT, file, line, func, SIGNAL_DATA_ARG (data)); - if (data->received_count != 0) - g_error ("NMPlatformSignalAssert: %s:%d, %s(): failure to free non-accepted signal: "SIGNAL_DATA_FMT, file, line, func, SIGNAL_DATA_ARG (data)); + _LOGD("NMPlatformSignalAssert: %s:%d, %s(): free signal: " SIGNAL_DATA_FMT, + file, + line, + func, + SIGNAL_DATA_ARG(data)); + if (data->received_count != 0) + g_error("NMPlatformSignalAssert: %s:%d, %s(): failure to free non-accepted " + "signal: " SIGNAL_DATA_FMT, + file, + line, + func, + SIGNAL_DATA_ARG(data)); - g_signal_handler_disconnect (NM_PLATFORM_GET, data->handler_id); - g_free (data); + g_signal_handler_disconnect(NM_PLATFORM_GET, data->handler_id); + g_free(data); } void -link_callback (NMPlatform *platform, int obj_type_i, int ifindex, NMPlatformLink *received, int change_type_i, SignalData *data) -{ - const NMPObjectType obj_type = obj_type_i; - const NMPlatformSignalChangeType change_type = change_type_i; - NMPLookup lookup; - NMDedupMultiIter iter; - const NMPlatformLink *cached; - - g_assert_cmpint (obj_type, ==, NMP_OBJECT_TYPE_LINK); - g_assert (received); - g_assert_cmpint (received->ifindex, ==, ifindex); - g_assert (data && data->name); - g_assert_cmpstr (data->name, ==, NM_PLATFORM_SIGNAL_LINK_CHANGED); - - if (data->ifindex && data->ifindex != received->ifindex) - return; - if (data->ifname && g_strcmp0 (data->ifname, nm_platform_link_get_name (NM_PLATFORM_GET, ifindex)) != 0) - return; - if (change_type != data->change_type) - return; - - if (data->loop) { - _LOGD ("Quitting main loop."); - g_main_loop_quit (data->loop); - } - - data->received_count++; - _LOGD ("Received signal '%s-%s' ifindex %d ifname '%s' %dth time.", data->name, nm_platform_signal_change_type_to_string (data->change_type), ifindex, received->name, data->received_count); - - if (change_type == NM_PLATFORM_SIGNAL_REMOVED) - g_assert (!nm_platform_link_get_name (NM_PLATFORM_GET, ifindex)); - else - g_assert (nm_platform_link_get_name (NM_PLATFORM_GET, ifindex)); - - /* Check the data */ - g_assert (received->ifindex > 0); - - nmp_lookup_init_obj_type (&lookup, NMP_OBJECT_TYPE_LINK); - nmp_cache_iter_for_each_link (&iter, - nm_platform_lookup (platform, &lookup), - &cached) { - if (!nmp_object_is_visible (NMP_OBJECT_UP_CAST (cached))) - continue; - if (cached->ifindex == received->ifindex) { - g_assert_cmpint (nm_platform_link_cmp (cached, received), ==, 0); - g_assert (!memcmp (cached, received, sizeof (*cached))); - if (data->change_type == NM_PLATFORM_SIGNAL_REMOVED) - g_error ("Deleted link still found in the local cache."); - return; - } - } - - if (data->change_type != NM_PLATFORM_SIGNAL_REMOVED) - g_error ("Added/changed link not found in the local cache."); +link_callback(NMPlatform * platform, + int obj_type_i, + int ifindex, + NMPlatformLink *received, + int change_type_i, + SignalData * data) +{ + const NMPObjectType obj_type = obj_type_i; + const NMPlatformSignalChangeType change_type = change_type_i; + NMPLookup lookup; + NMDedupMultiIter iter; + const NMPlatformLink * cached; + + g_assert_cmpint(obj_type, ==, NMP_OBJECT_TYPE_LINK); + g_assert(received); + g_assert_cmpint(received->ifindex, ==, ifindex); + g_assert(data && data->name); + g_assert_cmpstr(data->name, ==, NM_PLATFORM_SIGNAL_LINK_CHANGED); + + if (data->ifindex && data->ifindex != received->ifindex) + return; + if (data->ifname + && g_strcmp0(data->ifname, nm_platform_link_get_name(NM_PLATFORM_GET, ifindex)) != 0) + return; + if (change_type != data->change_type) + return; + + if (data->loop) { + _LOGD("Quitting main loop."); + g_main_loop_quit(data->loop); + } + + data->received_count++; + _LOGD("Received signal '%s-%s' ifindex %d ifname '%s' %dth time.", + data->name, + nm_platform_signal_change_type_to_string(data->change_type), + ifindex, + received->name, + data->received_count); + + if (change_type == NM_PLATFORM_SIGNAL_REMOVED) + g_assert(!nm_platform_link_get_name(NM_PLATFORM_GET, ifindex)); + else + g_assert(nm_platform_link_get_name(NM_PLATFORM_GET, ifindex)); + + /* Check the data */ + g_assert(received->ifindex > 0); + + nmp_lookup_init_obj_type(&lookup, NMP_OBJECT_TYPE_LINK); + nmp_cache_iter_for_each_link (&iter, nm_platform_lookup(platform, &lookup), &cached) { + if (!nmp_object_is_visible(NMP_OBJECT_UP_CAST(cached))) + continue; + if (cached->ifindex == received->ifindex) { + g_assert_cmpint(nm_platform_link_cmp(cached, received), ==, 0); + g_assert(!memcmp(cached, received, sizeof(*cached))); + if (data->change_type == NM_PLATFORM_SIGNAL_REMOVED) + g_error("Deleted link still found in the local cache."); + return; + } + } + + if (data->change_type != NM_PLATFORM_SIGNAL_REMOVED) + g_error("Added/changed link not found in the local cache."); } /*****************************************************************************/ static const NMPlatformIP4Route * -_ip4_route_get (NMPlatform *platform, - int ifindex, - guint32 network, - int plen, - guint32 metric, - guint8 tos, - guint *out_c_exists) -{ - NMDedupMultiIter iter; - NMPLookup lookup; - const NMPObject *o = NULL; - guint c; - const NMPlatformIP4Route *r = NULL; - - _init_platform (&platform, FALSE); - - nmp_lookup_init_ip4_route_by_weak_id (&lookup, - network, - plen, - metric, - tos); - - c = 0; - nmp_cache_iter_for_each (&iter, - nm_platform_lookup (platform, &lookup), - &o) { - if ( NMP_OBJECT_CAST_IP4_ROUTE (o)->ifindex != ifindex - && ifindex > 0) - continue; - if (!r) - r = NMP_OBJECT_CAST_IP4_ROUTE (o); - c++; - } - - NM_SET_OUT (out_c_exists, c); - return r; +_ip4_route_get(NMPlatform *platform, + int ifindex, + guint32 network, + int plen, + guint32 metric, + guint8 tos, + guint * out_c_exists) +{ + NMDedupMultiIter iter; + NMPLookup lookup; + const NMPObject * o = NULL; + guint c; + const NMPlatformIP4Route *r = NULL; + + _init_platform(&platform, FALSE); + + nmp_lookup_init_ip4_route_by_weak_id(&lookup, network, plen, metric, tos); + + c = 0; + nmp_cache_iter_for_each (&iter, nm_platform_lookup(platform, &lookup), &o) { + if (NMP_OBJECT_CAST_IP4_ROUTE(o)->ifindex != ifindex && ifindex > 0) + continue; + if (!r) + r = NMP_OBJECT_CAST_IP4_ROUTE(o); + c++; + } + + NM_SET_OUT(out_c_exists, c); + return r; } const NMPlatformIP4Route * -_nmtstp_assert_ip4_route_exists (const char *file, - guint line, - const char *func, - NMPlatform *platform, - int c_exists, - const char *ifname, - guint32 network, - int plen, - guint32 metric, - guint8 tos) -{ - int ifindex; - guint c; - const NMPlatformIP4Route *r = NULL; - - _init_platform (&platform, FALSE); - - ifindex = -1; - if (ifname) { - ifindex = nm_platform_link_get_ifindex (platform, ifname); - g_assert (ifindex > 0); - } - - r = _ip4_route_get (platform, - ifindex, - network, - plen, - metric, - tos, - &c); - - if (c != c_exists && c_exists != -1) { - char sbuf[NM_UTILS_INET_ADDRSTRLEN]; - - g_error ("[%s:%u] %s(): The ip4 route %s/%d metric %u tos %u shall exist %u times, but platform has it %u times", - file, line, func, - _nm_utils_inet4_ntop (network, sbuf), - plen, - metric, - tos, - c_exists, - c); - } - - return r; +_nmtstp_assert_ip4_route_exists(const char *file, + guint line, + const char *func, + NMPlatform *platform, + int c_exists, + const char *ifname, + guint32 network, + int plen, + guint32 metric, + guint8 tos) +{ + int ifindex; + guint c; + const NMPlatformIP4Route *r = NULL; + + _init_platform(&platform, FALSE); + + ifindex = -1; + if (ifname) { + ifindex = nm_platform_link_get_ifindex(platform, ifname); + g_assert(ifindex > 0); + } + + r = _ip4_route_get(platform, ifindex, network, plen, metric, tos, &c); + + if (c != c_exists && c_exists != -1) { + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + + g_error("[%s:%u] %s(): The ip4 route %s/%d metric %u tos %u shall exist %u times, but " + "platform has it %u times", + file, + line, + func, + _nm_utils_inet4_ntop(network, sbuf), + plen, + metric, + tos, + c_exists, + c); + } + + return r; } const NMPlatformIP4Route * -nmtstp_ip4_route_get (NMPlatform *platform, - int ifindex, - guint32 network, - int plen, - guint32 metric, - guint8 tos) -{ - return _ip4_route_get (platform, - ifindex, - network, - plen, - metric, - tos, - NULL); +nmtstp_ip4_route_get(NMPlatform *platform, + int ifindex, + guint32 network, + int plen, + guint32 metric, + guint8 tos) +{ + return _ip4_route_get(platform, ifindex, network, plen, metric, tos, NULL); } /*****************************************************************************/ static const NMPlatformIP6Route * -_ip6_route_get (NMPlatform *platform, - int ifindex, - const struct in6_addr *network, - guint plen, - guint32 metric, - const struct in6_addr *src, - guint8 src_plen, - guint *out_c_exists) -{ - NMDedupMultiIter iter; - NMPLookup lookup; - const NMPObject *o = NULL; - guint c; - const NMPlatformIP6Route *r = NULL; - - _init_platform (&platform, FALSE); - - nmp_lookup_init_ip6_route_by_weak_id (&lookup, - network, - plen, - metric, - src, - src_plen); - - c = 0; - nmp_cache_iter_for_each (&iter, - nm_platform_lookup (platform, &lookup), - &o) { - if ( NMP_OBJECT_CAST_IP6_ROUTE (o)->ifindex != ifindex - && ifindex > 0) - continue; - if (!r) - r = NMP_OBJECT_CAST_IP6_ROUTE (o); - c++; - } - - NM_SET_OUT (out_c_exists, c); - return r; +_ip6_route_get(NMPlatform * platform, + int ifindex, + const struct in6_addr *network, + guint plen, + guint32 metric, + const struct in6_addr *src, + guint8 src_plen, + guint * out_c_exists) +{ + NMDedupMultiIter iter; + NMPLookup lookup; + const NMPObject * o = NULL; + guint c; + const NMPlatformIP6Route *r = NULL; + + _init_platform(&platform, FALSE); + + nmp_lookup_init_ip6_route_by_weak_id(&lookup, network, plen, metric, src, src_plen); + + c = 0; + nmp_cache_iter_for_each (&iter, nm_platform_lookup(platform, &lookup), &o) { + if (NMP_OBJECT_CAST_IP6_ROUTE(o)->ifindex != ifindex && ifindex > 0) + continue; + if (!r) + r = NMP_OBJECT_CAST_IP6_ROUTE(o); + c++; + } + + NM_SET_OUT(out_c_exists, c); + return r; } const NMPlatformIP6Route * -_nmtstp_assert_ip6_route_exists (const char *file, - guint line, - const char *func, - NMPlatform *platform, - int c_exists, - const char *ifname, - const struct in6_addr *network, - guint plen, - guint32 metric, - const struct in6_addr *src, - guint8 src_plen) -{ - int ifindex; - guint c; - const NMPlatformIP6Route *r = NULL; - - _init_platform (&platform, FALSE); - - ifindex = -1; - if (ifname) { - ifindex = nm_platform_link_get_ifindex (platform, ifname); - g_assert (ifindex > 0); - } - - r = _ip6_route_get (platform, - ifindex, - network, - plen, - metric, - src, - src_plen, - &c); - - if (c != c_exists && c_exists != -1) { - char s_src[NM_UTILS_INET_ADDRSTRLEN]; - char s_network[NM_UTILS_INET_ADDRSTRLEN]; - - g_error ("[%s:%u] %s(): The ip6 route %s/%d metric %u src %s/%d shall exist %u times, but platform has it %u times", - file, line, func, - _nm_utils_inet6_ntop (network, s_network), - plen, - metric, - _nm_utils_inet6_ntop (src, s_src), - src_plen, - c_exists, - c); - } - - return r; +_nmtstp_assert_ip6_route_exists(const char * file, + guint line, + const char * func, + NMPlatform * platform, + int c_exists, + const char * ifname, + const struct in6_addr *network, + guint plen, + guint32 metric, + const struct in6_addr *src, + guint8 src_plen) +{ + int ifindex; + guint c; + const NMPlatformIP6Route *r = NULL; + + _init_platform(&platform, FALSE); + + ifindex = -1; + if (ifname) { + ifindex = nm_platform_link_get_ifindex(platform, ifname); + g_assert(ifindex > 0); + } + + r = _ip6_route_get(platform, ifindex, network, plen, metric, src, src_plen, &c); + + if (c != c_exists && c_exists != -1) { + char s_src[NM_UTILS_INET_ADDRSTRLEN]; + char s_network[NM_UTILS_INET_ADDRSTRLEN]; + + g_error("[%s:%u] %s(): The ip6 route %s/%d metric %u src %s/%d shall exist %u times, but " + "platform has it %u times", + file, + line, + func, + _nm_utils_inet6_ntop(network, s_network), + plen, + metric, + _nm_utils_inet6_ntop(src, s_src), + src_plen, + c_exists, + c); + } + + return r; } const NMPlatformIP6Route * -nmtstp_ip6_route_get (NMPlatform *platform, - int ifindex, - const struct in6_addr *network, - guint plen, - guint32 metric, - const struct in6_addr *src, - guint8 src_plen) -{ - return _ip6_route_get (platform, - ifindex, - network, - plen, - metric, - src, - src_plen, - NULL); +nmtstp_ip6_route_get(NMPlatform * platform, + int ifindex, + const struct in6_addr *network, + guint plen, + guint32 metric, + const struct in6_addr *src, + guint8 src_plen) +{ + return _ip6_route_get(platform, ifindex, network, plen, metric, src, src_plen, NULL); } /*****************************************************************************/ int -nmtstp_run_command (const char *format, ...) +nmtstp_run_command(const char *format, ...) { - int result; - gs_free char *command = NULL; - va_list ap; + int result; + gs_free char *command = NULL; + va_list ap; - va_start (ap, format); - command = g_strdup_vprintf (format, ap); - va_end (ap); + va_start(ap, format); + command = g_strdup_vprintf(format, ap); + va_end(ap); - _LOGD ("Running command: %s", command); - result = system (command); - _LOGD ("Command finished: result=%d", result); + _LOGD("Running command: %s", command); + result = system(command); + _LOGD("Command finished: result=%d", result); - return result; + return result; } /*****************************************************************************/ typedef struct { - GMainLoop *loop; - guint signal_counts; - guint id; + GMainLoop *loop; + guint signal_counts; + guint id; } WaitForSignalData; static void -_wait_for_signal_cb (NMPlatform *platform, - int obj_type_i, - int ifindex, - NMPlatformLink *plink, - int change_type_i, - gpointer user_data) +_wait_for_signal_cb(NMPlatform * platform, + int obj_type_i, + int ifindex, + NMPlatformLink *plink, + int change_type_i, + gpointer user_data) { - WaitForSignalData *data = user_data; + WaitForSignalData *data = user_data; - data->signal_counts++; - nm_clear_g_source (&data->id); - g_main_loop_quit (data->loop); + data->signal_counts++; + nm_clear_g_source(&data->id); + g_main_loop_quit(data->loop); } static gboolean -_wait_for_signal_timeout (gpointer user_data) +_wait_for_signal_timeout(gpointer user_data) { - WaitForSignalData *data = user_data; + WaitForSignalData *data = user_data; - g_assert (data->id); - data->id = 0; - g_main_loop_quit (data->loop); - return G_SOURCE_REMOVE; + g_assert(data->id); + data->id = 0; + g_main_loop_quit(data->loop); + return G_SOURCE_REMOVE; } guint -nmtstp_wait_for_signal (NMPlatform *platform, gint64 timeout_msec) -{ - WaitForSignalData data = { 0 }; - gulong id_link, id_ip4_address, id_ip6_address, id_ip4_route, id_ip6_route; - gulong id_qdisc, id_tfilter; - - _init_platform (&platform, FALSE); - - data.loop = g_main_loop_new (NULL, FALSE); - - id_link = g_signal_connect (platform, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data); - id_ip4_address = g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data); - id_ip6_address = g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data); - id_ip4_route = g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data); - id_ip6_route = g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data); - id_qdisc = g_signal_connect (platform, NM_PLATFORM_SIGNAL_QDISC_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data); - id_tfilter = g_signal_connect (platform, NM_PLATFORM_SIGNAL_TFILTER_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data); - - /* if timeout_msec is negative, it means the wait-time already expired. - * Maybe, we should do nothing and return right away, without even - * processing events from platform. However, that inconsistency (of not - * processing events from mainloop) is inconvenient. - * - * It's better that on the return of nmtstp_wait_for_signal(), we always - * have no events pending. So, a negative timeout is treated the same as - * a zero timeout: we check whether there are any events pending in platform, - * and quite the mainloop immediately afterwards. But we always check. */ - - data.id = g_timeout_add (CLAMP (timeout_msec, 0, G_MAXUINT32), - _wait_for_signal_timeout, &data); - - g_main_loop_run (data.loop); - - g_assert (!data.id); - g_assert (nm_clear_g_signal_handler (platform, &id_link)); - g_assert (nm_clear_g_signal_handler (platform, &id_ip4_address)); - g_assert (nm_clear_g_signal_handler (platform, &id_ip6_address)); - g_assert (nm_clear_g_signal_handler (platform, &id_ip4_route)); - g_assert (nm_clear_g_signal_handler (platform, &id_ip6_route)); - g_assert (nm_clear_g_signal_handler (platform, &id_tfilter)); - g_assert (nm_clear_g_signal_handler (platform, &id_qdisc)); - - nm_clear_pointer (&data.loop, g_main_loop_unref); - - /* return the number of signals, or 0 if timeout was reached .*/ - return data.signal_counts; +nmtstp_wait_for_signal(NMPlatform *platform, gint64 timeout_msec) +{ + WaitForSignalData data = {0}; + gulong id_link, id_ip4_address, id_ip6_address, id_ip4_route, id_ip6_route; + gulong id_qdisc, id_tfilter; + + _init_platform(&platform, FALSE); + + data.loop = g_main_loop_new(NULL, FALSE); + + id_link = g_signal_connect(platform, + NM_PLATFORM_SIGNAL_LINK_CHANGED, + G_CALLBACK(_wait_for_signal_cb), + &data); + id_ip4_address = g_signal_connect(platform, + NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, + G_CALLBACK(_wait_for_signal_cb), + &data); + id_ip6_address = g_signal_connect(platform, + NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, + G_CALLBACK(_wait_for_signal_cb), + &data); + id_ip4_route = g_signal_connect(platform, + NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, + G_CALLBACK(_wait_for_signal_cb), + &data); + id_ip6_route = g_signal_connect(platform, + NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, + G_CALLBACK(_wait_for_signal_cb), + &data); + id_qdisc = g_signal_connect(platform, + NM_PLATFORM_SIGNAL_QDISC_CHANGED, + G_CALLBACK(_wait_for_signal_cb), + &data); + id_tfilter = g_signal_connect(platform, + NM_PLATFORM_SIGNAL_TFILTER_CHANGED, + G_CALLBACK(_wait_for_signal_cb), + &data); + + /* if timeout_msec is negative, it means the wait-time already expired. + * Maybe, we should do nothing and return right away, without even + * processing events from platform. However, that inconsistency (of not + * processing events from mainloop) is inconvenient. + * + * It's better that on the return of nmtstp_wait_for_signal(), we always + * have no events pending. So, a negative timeout is treated the same as + * a zero timeout: we check whether there are any events pending in platform, + * and quite the mainloop immediately afterwards. But we always check. */ + + data.id = g_timeout_add(CLAMP(timeout_msec, 0, G_MAXUINT32), _wait_for_signal_timeout, &data); + + g_main_loop_run(data.loop); + + g_assert(!data.id); + g_assert(nm_clear_g_signal_handler(platform, &id_link)); + g_assert(nm_clear_g_signal_handler(platform, &id_ip4_address)); + g_assert(nm_clear_g_signal_handler(platform, &id_ip6_address)); + g_assert(nm_clear_g_signal_handler(platform, &id_ip4_route)); + g_assert(nm_clear_g_signal_handler(platform, &id_ip6_route)); + g_assert(nm_clear_g_signal_handler(platform, &id_tfilter)); + g_assert(nm_clear_g_signal_handler(platform, &id_qdisc)); + + nm_clear_pointer(&data.loop, g_main_loop_unref); + + /* return the number of signals, or 0 if timeout was reached .*/ + return data.signal_counts; } guint -nmtstp_wait_for_signal_until (NMPlatform *platform, gint64 until_ms) +nmtstp_wait_for_signal_until(NMPlatform *platform, gint64 until_ms) { - gint64 now; - guint signal_counts; + gint64 now; + guint signal_counts; - while (TRUE) { - now = nm_utils_get_monotonic_timestamp_msec (); + while (TRUE) { + now = nm_utils_get_monotonic_timestamp_msec(); - if (until_ms < now) - return 0; + if (until_ms < now) + return 0; - signal_counts = nmtstp_wait_for_signal (platform, until_ms - now); - if (signal_counts) - return signal_counts; - } + signal_counts = nmtstp_wait_for_signal(platform, until_ms - now); + if (signal_counts) + return signal_counts; + } } const NMPlatformLink * -nmtstp_wait_for_link (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, gint64 timeout_msec) +nmtstp_wait_for_link(NMPlatform *platform, + const char *ifname, + NMLinkType expected_link_type, + gint64 timeout_msec) { - return nmtstp_wait_for_link_until (platform, ifname, expected_link_type, - timeout_msec - ? nm_utils_get_monotonic_timestamp_msec () + timeout_msec - : 0); + return nmtstp_wait_for_link_until( + platform, + ifname, + expected_link_type, + timeout_msec ? nm_utils_get_monotonic_timestamp_msec() + timeout_msec : 0); } const NMPlatformLink * -nmtstp_wait_for_link_until (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, gint64 until_ms) +nmtstp_wait_for_link_until(NMPlatform *platform, + const char *ifname, + NMLinkType expected_link_type, + gint64 until_ms) { - const NMPlatformLink *plink; - gint64 now; - gboolean waited_once = FALSE; + const NMPlatformLink *plink; + gint64 now; + gboolean waited_once = FALSE; - _init_platform (&platform, FALSE); + _init_platform(&platform, FALSE); - while (TRUE) { - now = nm_utils_get_monotonic_timestamp_msec (); + while (TRUE) { + now = nm_utils_get_monotonic_timestamp_msec(); - plink = nm_platform_link_get_by_ifname (platform, ifname); - if ( plink - && (expected_link_type == NM_LINK_TYPE_NONE || plink->type == expected_link_type)) - return plink; + plink = nm_platform_link_get_by_ifname(platform, ifname); + if (plink && (expected_link_type == NM_LINK_TYPE_NONE || plink->type == expected_link_type)) + return plink; - if (until_ms == 0) { - /* don't wait, don't even poll the socket. */ - return NULL; - } + if (until_ms == 0) { + /* don't wait, don't even poll the socket. */ + return NULL; + } - if ( waited_once - && until_ms < now) { - /* timeout reached (+ we already waited for a signal at least once). */ - return NULL; - } + if (waited_once && until_ms < now) { + /* timeout reached (+ we already waited for a signal at least once). */ + return NULL; + } - waited_once = TRUE; - /* regardless of whether timeout is already reached, we poll the netlink - * socket a bit. */ - nmtstp_wait_for_signal (platform, until_ms - now); - } + waited_once = TRUE; + /* regardless of whether timeout is already reached, we poll the netlink + * socket a bit. */ + nmtstp_wait_for_signal(platform, until_ms - now); + } } /*****************************************************************************/ int -nmtstp_run_command_check_external_global (void) +nmtstp_run_command_check_external_global(void) { - if (!nmtstp_is_root_test ()) - return FALSE; - switch (nmtst_get_rand_uint32 () % 3) { - case 0: - return -1; - case 1: - return FALSE; - default: - return TRUE; - } + if (!nmtstp_is_root_test()) + return FALSE; + switch (nmtst_get_rand_uint32() % 3) { + case 0: + return -1; + case 1: + return FALSE; + default: + return TRUE; + } } gboolean -nmtstp_run_command_check_external (int external_command) +nmtstp_run_command_check_external(int external_command) { - if (external_command != -1) { - g_assert (NM_IN_SET (external_command, FALSE, TRUE)); - g_assert (!external_command || nmtstp_is_root_test ()); - return !!external_command; - } - if (!nmtstp_is_root_test ()) - return FALSE; - return (nmtst_get_rand_uint32 () % 2) == 0; + if (external_command != -1) { + g_assert(NM_IN_SET(external_command, FALSE, TRUE)); + g_assert(!external_command || nmtstp_is_root_test()); + return !!external_command; + } + if (!nmtstp_is_root_test()) + return FALSE; + return (nmtst_get_rand_uint32() % 2) == 0; } /*****************************************************************************/ -#define CHECK_LIFETIME_MAX_DIFF 2 +#define CHECK_LIFETIME_MAX_DIFF 2 gboolean -nmtstp_ip_address_check_lifetime (const NMPlatformIPAddress *addr, - gint64 now, - guint32 expected_lifetime, - guint32 expected_preferred) +nmtstp_ip_address_check_lifetime(const NMPlatformIPAddress *addr, + gint64 now, + guint32 expected_lifetime, + guint32 expected_preferred) { - gint64 offset; - int i; + gint64 offset; + int i; - g_assert (addr); + g_assert(addr); - if (now == -1) - now = nm_utils_get_monotonic_timestamp_sec (); - g_assert (now > 0); + if (now == -1) + now = nm_utils_get_monotonic_timestamp_sec(); + g_assert(now > 0); - g_assert (expected_preferred <= expected_lifetime); + g_assert(expected_preferred <= expected_lifetime); - if ( expected_lifetime == NM_PLATFORM_LIFETIME_PERMANENT - && expected_preferred == NM_PLATFORM_LIFETIME_PERMANENT) { - return addr->timestamp == 0 - && addr->lifetime == NM_PLATFORM_LIFETIME_PERMANENT - && addr->preferred == NM_PLATFORM_LIFETIME_PERMANENT; - } + if (expected_lifetime == NM_PLATFORM_LIFETIME_PERMANENT + && expected_preferred == NM_PLATFORM_LIFETIME_PERMANENT) { + return addr->timestamp == 0 && addr->lifetime == NM_PLATFORM_LIFETIME_PERMANENT + && addr->preferred == NM_PLATFORM_LIFETIME_PERMANENT; + } - if (addr->timestamp == 0) - return FALSE; + if (addr->timestamp == 0) + return FALSE; - offset = (gint64) now - addr->timestamp; + offset = (gint64) now - addr->timestamp; - for (i = 0; i < 2; i++) { - guint32 lft = i ? expected_lifetime : expected_preferred; - guint32 adr = i ? addr->lifetime : addr->preferred; + for (i = 0; i < 2; i++) { + guint32 lft = i ? expected_lifetime : expected_preferred; + guint32 adr = i ? addr->lifetime : addr->preferred; - if (lft == NM_PLATFORM_LIFETIME_PERMANENT) { - if (adr != NM_PLATFORM_LIFETIME_PERMANENT) - return FALSE; - } else { - if ( adr - offset <= lft - CHECK_LIFETIME_MAX_DIFF - || adr - offset >= lft + CHECK_LIFETIME_MAX_DIFF) - return FALSE; - } - } - return TRUE; + if (lft == NM_PLATFORM_LIFETIME_PERMANENT) { + if (adr != NM_PLATFORM_LIFETIME_PERMANENT) + return FALSE; + } else { + if (((gint64) adr) - offset <= ((gint64) lft) - CHECK_LIFETIME_MAX_DIFF + || ((gint64) adr) - offset >= ((gint64) lft) + CHECK_LIFETIME_MAX_DIFF) + return FALSE; + } + } + return TRUE; } void -nmtstp_ip_address_assert_lifetime (const NMPlatformIPAddress *addr, - gint64 now, - guint32 expected_lifetime, - guint32 expected_preferred) +nmtstp_ip_address_assert_lifetime(const NMPlatformIPAddress *addr, + gint64 now, + guint32 expected_lifetime, + guint32 expected_preferred) { - gint64 n = now; - gint64 offset; - int i; + gint64 n = now; + gint64 offset; + int i; - g_assert (addr); + g_assert(addr); - if (now == -1) - now = nm_utils_get_monotonic_timestamp_sec (); - g_assert (now > 0); + if (now == -1) + now = nm_utils_get_monotonic_timestamp_sec(); + g_assert(now > 0); - g_assert (expected_preferred <= expected_lifetime); + g_assert(expected_preferred <= expected_lifetime); - if ( expected_lifetime == NM_PLATFORM_LIFETIME_PERMANENT - && expected_preferred == NM_PLATFORM_LIFETIME_PERMANENT) { - g_assert_cmpint (addr->timestamp, ==, 0); - g_assert_cmpint (addr->lifetime, ==, NM_PLATFORM_LIFETIME_PERMANENT); - g_assert_cmpint (addr->preferred, ==, NM_PLATFORM_LIFETIME_PERMANENT); - return; - } + if (expected_lifetime == NM_PLATFORM_LIFETIME_PERMANENT + && expected_preferred == NM_PLATFORM_LIFETIME_PERMANENT) { + g_assert_cmpint(addr->timestamp, ==, 0); + g_assert_cmpint(addr->lifetime, ==, NM_PLATFORM_LIFETIME_PERMANENT); + g_assert_cmpint(addr->preferred, ==, NM_PLATFORM_LIFETIME_PERMANENT); + return; + } - g_assert_cmpint (addr->timestamp, >, 0); - g_assert_cmpint (addr->timestamp, <=, now); + g_assert_cmpint(addr->timestamp, >, 0); + g_assert_cmpint(addr->timestamp, <=, now); - offset = (gint64) now - addr->timestamp; - g_assert_cmpint (offset, >=, 0); + offset = (gint64) now - addr->timestamp; + g_assert_cmpint(offset, >=, 0); - for (i = 0; i < 2; i++) { - guint32 lft = i ? expected_lifetime : expected_preferred; - guint32 adr = i ? addr->lifetime : addr->preferred; + for (i = 0; i < 2; i++) { + guint32 lft = i ? expected_lifetime : expected_preferred; + guint32 adr = i ? addr->lifetime : addr->preferred; - if (lft == NM_PLATFORM_LIFETIME_PERMANENT) - g_assert_cmpint (adr, ==, NM_PLATFORM_LIFETIME_PERMANENT); - else { - g_assert_cmpint (adr - offset, <=, lft + CHECK_LIFETIME_MAX_DIFF); - g_assert_cmpint (adr - offset, >=, lft - CHECK_LIFETIME_MAX_DIFF); - } - } + if (lft == NM_PLATFORM_LIFETIME_PERMANENT) + g_assert_cmpint(adr, ==, NM_PLATFORM_LIFETIME_PERMANENT); + else { + g_assert_cmpint(adr - offset, <=, lft + CHECK_LIFETIME_MAX_DIFF); + g_assert_cmpint(adr - offset, >=, lft - CHECK_LIFETIME_MAX_DIFF); + } + } - g_assert (nmtstp_ip_address_check_lifetime (addr, n, expected_lifetime, expected_preferred)); + g_assert(nmtstp_ip_address_check_lifetime(addr, n, expected_lifetime, expected_preferred)); } /*****************************************************************************/ static void -_ip_address_add (NMPlatform *platform, - gboolean external_command, - gboolean is_v4, - int ifindex, - const NMIPAddr *address, - int plen, - const NMIPAddr *peer_address, - guint32 lifetime, - guint32 preferred, - guint32 flags, - const char *label) -{ - gint64 end_time; - - external_command = nmtstp_run_command_check_external (external_command); - - _init_platform (&platform, external_command); - - if (external_command) { - const char *ifname; - gs_free char *s_valid = NULL; - gs_free char *s_preferred = NULL; - gs_free char *s_label = NULL; - char b1[NM_UTILS_INET_ADDRSTRLEN]; - char b2[NM_UTILS_INET_ADDRSTRLEN]; - - ifname = nm_platform_link_get_name (platform, ifindex); - g_assert (ifname); - - if (lifetime != NM_PLATFORM_LIFETIME_PERMANENT) - s_valid = g_strdup_printf (" valid_lft %d", lifetime); - if (preferred != NM_PLATFORM_LIFETIME_PERMANENT) - s_preferred = g_strdup_printf (" preferred_lft %d", preferred); - if (label) - s_label = g_strdup_printf ("%s:%s", ifname, label); - - if (is_v4) { - char s_peer[NM_UTILS_INET_ADDRSTRLEN + 50]; - - g_assert (flags == 0); - - if ( peer_address->addr4 != address->addr4 - || nmtst_get_rand_uint32 () % 2) { - /* If the peer is the same as the local address, we can omit it. The result should be identical */ - nm_sprintf_buf (s_peer, " peer %s", _nm_utils_inet4_ntop (peer_address->addr4, b2)); - } else - s_peer[0] = '\0'; - - nmtstp_run_command_check ("ip address change %s%s/%d dev %s%s%s%s", - _nm_utils_inet4_ntop (address->addr4, b1), - s_peer, - plen, - ifname, - s_valid ?: "", - s_preferred ?: "", - s_label ?: ""); - } else { - g_assert (label == NULL); - - /* flags not implemented (yet) */ - g_assert (flags == 0); - nmtstp_run_command_check ("ip address change %s%s%s/%d dev %s%s%s%s", - _nm_utils_inet6_ntop (&address->addr6, b1), - !IN6_IS_ADDR_UNSPECIFIED (&peer_address->addr6) ? " peer " : "", - !IN6_IS_ADDR_UNSPECIFIED (&peer_address->addr6) ? _nm_utils_inet6_ntop (&peer_address->addr6, b2) : "", - plen, - ifname, - s_valid ?: "", - s_preferred ?: "", - s_label ?: ""); - } - } else { - gboolean success; - - if (is_v4) { - success = nm_platform_ip4_address_add (platform, - ifindex, - address->addr4, - plen, - peer_address->addr4, - 0u, - lifetime, - preferred, - flags, - label); - } else { - g_assert (label == NULL); - success = nm_platform_ip6_address_add (platform, - ifindex, - address->addr6, - plen, - peer_address->addr6, - lifetime, - preferred, - flags); - } - g_assert (success); - } - - /* Let's wait until we see the address. */ - end_time = nm_utils_get_monotonic_timestamp_msec () + 500; - do { - - if (external_command) - nm_platform_process_events (platform); - - /* let's wait until we see the address as we added it. */ - if (is_v4) { - const NMPlatformIP4Address *a; - - g_assert (flags == 0); - a = nm_platform_ip4_address_get (platform, ifindex, address->addr4, plen, peer_address->addr4); - if ( a - && a->peer_address == peer_address->addr4 - && nmtstp_ip_address_check_lifetime ((NMPlatformIPAddress*) a, -1, lifetime, preferred) - && strcmp (a->label, label ?: "") == 0) - break; - } else { - const NMPlatformIP6Address *a; - - g_assert (label == NULL); - g_assert (flags == 0); - - a = nm_platform_ip6_address_get (platform, ifindex, address->addr6); - if ( a - && !memcmp (nm_platform_ip6_address_get_peer (a), - (IN6_IS_ADDR_UNSPECIFIED (&peer_address->addr6) || IN6_ARE_ADDR_EQUAL (&address->addr6, &peer_address->addr6)) - ? &address->addr6 : &peer_address->addr6, - sizeof (struct in6_addr)) - && nmtstp_ip_address_check_lifetime ((NMPlatformIPAddress*) a, -1, lifetime, preferred)) - break; - } - - /* 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); +_ip_address_add(NMPlatform * platform, + gboolean external_command, + gboolean is_v4, + int ifindex, + const NMIPAddr *address, + int plen, + const NMIPAddr *peer_address, + guint32 lifetime, + guint32 preferred, + guint32 flags, + const char * label) +{ + gint64 end_time; + + external_command = nmtstp_run_command_check_external(external_command); + + _init_platform(&platform, external_command); + + if (external_command) { + const char * ifname; + gs_free char *s_valid = NULL; + gs_free char *s_preferred = NULL; + gs_free char *s_label = NULL; + char b1[NM_UTILS_INET_ADDRSTRLEN]; + char b2[NM_UTILS_INET_ADDRSTRLEN]; + + ifname = nm_platform_link_get_name(platform, ifindex); + g_assert(ifname); + + if (lifetime != NM_PLATFORM_LIFETIME_PERMANENT) + s_valid = g_strdup_printf(" valid_lft %d", lifetime); + if (preferred != NM_PLATFORM_LIFETIME_PERMANENT) + s_preferred = g_strdup_printf(" preferred_lft %d", preferred); + if (label) + s_label = g_strdup_printf("%s:%s", ifname, label); + + if (is_v4) { + char s_peer[NM_UTILS_INET_ADDRSTRLEN + 50]; + + g_assert(flags == 0); + + if (peer_address->addr4 != address->addr4 || nmtst_get_rand_uint32() % 2) { + /* If the peer is the same as the local address, we can omit it. The result should be identical */ + nm_sprintf_buf(s_peer, " peer %s", _nm_utils_inet4_ntop(peer_address->addr4, b2)); + } else + s_peer[0] = '\0'; + + nmtstp_run_command_check("ip address change %s%s/%d dev %s%s%s%s", + _nm_utils_inet4_ntop(address->addr4, b1), + s_peer, + plen, + ifname, + s_valid ?: "", + s_preferred ?: "", + s_label ?: ""); + } else { + g_assert(label == NULL); + + /* flags not implemented (yet) */ + g_assert(flags == 0); + nmtstp_run_command_check("ip address change %s%s%s/%d dev %s%s%s%s", + _nm_utils_inet6_ntop(&address->addr6, b1), + !IN6_IS_ADDR_UNSPECIFIED(&peer_address->addr6) ? " peer " : "", + !IN6_IS_ADDR_UNSPECIFIED(&peer_address->addr6) + ? _nm_utils_inet6_ntop(&peer_address->addr6, b2) + : "", + plen, + ifname, + s_valid ?: "", + s_preferred ?: "", + s_label ?: ""); + } + } else { + gboolean success; + + if (is_v4) { + success = nm_platform_ip4_address_add(platform, + ifindex, + address->addr4, + plen, + peer_address->addr4, + 0u, + lifetime, + preferred, + flags, + label); + } else { + g_assert(label == NULL); + success = nm_platform_ip6_address_add(platform, + ifindex, + address->addr6, + plen, + peer_address->addr6, + lifetime, + preferred, + flags); + } + g_assert(success); + } + + /* Let's wait until we see the address. */ + end_time = nm_utils_get_monotonic_timestamp_msec() + 500; + do { + if (external_command) + nm_platform_process_events(platform); + + /* let's wait until we see the address as we added it. */ + if (is_v4) { + const NMPlatformIP4Address *a; + + g_assert(flags == 0); + a = nm_platform_ip4_address_get(platform, + ifindex, + address->addr4, + plen, + peer_address->addr4); + if (a && a->peer_address == peer_address->addr4 + && nmtstp_ip_address_check_lifetime((NMPlatformIPAddress *) a, + -1, + lifetime, + preferred) + && strcmp(a->label, label ?: "") == 0) + break; + } else { + const NMPlatformIP6Address *a; + + g_assert(label == NULL); + g_assert(flags == 0); + + a = nm_platform_ip6_address_get(platform, ifindex, &address->addr6); + if (a + && !memcmp(nm_platform_ip6_address_get_peer(a), + (IN6_IS_ADDR_UNSPECIFIED(&peer_address->addr6) + || IN6_ARE_ADDR_EQUAL(&address->addr6, &peer_address->addr6)) + ? &address->addr6 + : &peer_address->addr6, + sizeof(struct in6_addr)) + && nmtstp_ip_address_check_lifetime((NMPlatformIPAddress *) a, + -1, + lifetime, + preferred)) + break; + } + + /* 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); +} + +void +nmtstp_ip4_address_add(NMPlatform *platform, + gboolean external_command, + int ifindex, + in_addr_t address, + int plen, + in_addr_t peer_address, + guint32 lifetime, + guint32 preferred, + guint32 flags, + const char *label) +{ + _ip_address_add(platform, + external_command, + TRUE, + ifindex, + (NMIPAddr *) &address, + plen, + (NMIPAddr *) &peer_address, + lifetime, + preferred, + flags, + label); +} + +void +nmtstp_ip6_address_add(NMPlatform * platform, + gboolean external_command, + int ifindex, + struct in6_addr address, + int plen, + struct in6_addr peer_address, + guint32 lifetime, + guint32 preferred, + guint32 flags) +{ + _ip_address_add(platform, + external_command, + FALSE, + ifindex, + (NMIPAddr *) &address, + plen, + (NMIPAddr *) &peer_address, + lifetime, + preferred, + flags, + NULL); } void -nmtstp_ip4_address_add (NMPlatform *platform, - gboolean external_command, - int ifindex, - in_addr_t address, - int plen, - in_addr_t peer_address, - guint32 lifetime, - guint32 preferred, - guint32 flags, - const char *label) -{ - _ip_address_add (platform, - external_command, - TRUE, - ifindex, - (NMIPAddr *) &address, - plen, - (NMIPAddr *) &peer_address, - lifetime, - preferred, - flags, - label); +nmtstp_ip4_route_add(NMPlatform * platform, + int ifindex, + NMIPConfigSource source, + in_addr_t network, + guint8 plen, + in_addr_t gateway, + in_addr_t pref_src, + guint32 metric, + guint32 mss) +{ + NMPlatformIP4Route route = {}; + + route.ifindex = ifindex; + route.rt_source = source; + route.network = network; + route.plen = plen; + route.gateway = gateway; + route.pref_src = pref_src; + route.metric = metric; + route.mss = mss; + + g_assert( + NMTST_NM_ERR_SUCCESS(nm_platform_ip4_route_add(platform, NMP_NLM_FLAG_REPLACE, &route))); } void -nmtstp_ip6_address_add (NMPlatform *platform, - gboolean external_command, - int ifindex, - struct in6_addr address, - int plen, - struct in6_addr peer_address, - guint32 lifetime, - guint32 preferred, - guint32 flags) -{ - _ip_address_add (platform, - external_command, - FALSE, - ifindex, - (NMIPAddr *) &address, - plen, - (NMIPAddr *) &peer_address, - lifetime, - preferred, - flags, - NULL); -} - -void nmtstp_ip4_route_add (NMPlatform *platform, - int ifindex, - NMIPConfigSource source, - in_addr_t network, - guint8 plen, - in_addr_t gateway, - in_addr_t pref_src, - guint32 metric, - guint32 mss) -{ - NMPlatformIP4Route route = { }; - - route.ifindex = ifindex; - route.rt_source = source; - route.network = network; - route.plen = plen; - route.gateway = gateway; - route.pref_src = pref_src; - route.metric = metric; - route.mss = mss; - - g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_ip4_route_add (platform, NMP_NLM_FLAG_REPLACE, &route))); -} - -void nmtstp_ip6_route_add (NMPlatform *platform, - int ifindex, - NMIPConfigSource source, - struct in6_addr network, - guint8 plen, - struct in6_addr gateway, - struct in6_addr pref_src, - guint32 metric, - guint32 mss) -{ - NMPlatformIP6Route route = { }; - - route.ifindex = ifindex; - route.rt_source = source; - route.network = network; - route.plen = plen; - route.gateway = gateway; - route.pref_src = pref_src; - route.metric = metric; - route.mss = mss; - - g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_ip6_route_add (platform, NMP_NLM_FLAG_REPLACE, &route))); +nmtstp_ip6_route_add(NMPlatform * platform, + int ifindex, + NMIPConfigSource source, + struct in6_addr network, + guint8 plen, + struct in6_addr gateway, + struct in6_addr pref_src, + guint32 metric, + guint32 mss) +{ + NMPlatformIP6Route route = {}; + + route.ifindex = ifindex; + route.rt_source = source; + route.network = network; + route.plen = plen; + route.gateway = gateway; + route.pref_src = pref_src; + route.metric = metric; + route.mss = mss; + + g_assert( + NMTST_NM_ERR_SUCCESS(nm_platform_ip6_route_add(platform, NMP_NLM_FLAG_REPLACE, &route))); } /*****************************************************************************/ static void -_ip_address_del (NMPlatform *platform, - gboolean external_command, - gboolean is_v4, - int ifindex, - const NMIPAddr *address, - int plen, - const NMIPAddr *peer_address) -{ - gint64 end_time; - - external_command = nmtstp_run_command_check_external (external_command); - - _init_platform (&platform, external_command); - - if (external_command) { - const char *ifname; - char b1[NM_UTILS_INET_ADDRSTRLEN]; - char b2[NM_UTILS_INET_ADDRSTRLEN]; - int success; - gboolean had_address; - - ifname = nm_platform_link_get_name (platform, ifindex); - g_assert (ifname); - - /* let's wait until we see the address as we added it. */ - if (is_v4) - had_address = !!nm_platform_ip4_address_get (platform, ifindex, address->addr4, plen, peer_address->addr4); - else - had_address = !!nm_platform_ip6_address_get (platform, ifindex, address->addr6); - - if (is_v4) { - success = nmtstp_run_command ("ip address delete %s%s%s/%d dev %s", - _nm_utils_inet4_ntop (address->addr4, b1), - peer_address->addr4 != address->addr4 ? " peer " : "", - peer_address->addr4 != address->addr4 ? _nm_utils_inet4_ntop (peer_address->addr4, b2) : "", - plen, - ifname); - } else { - g_assert (!peer_address); - success = nmtstp_run_command ("ip address delete %s/%d dev %s", - _nm_utils_inet6_ntop (&address->addr6, b1), - plen, - ifname); - } - g_assert (success == 0 || !had_address); - } else { - gboolean success; - - if (is_v4) { - success = nm_platform_ip4_address_delete (platform, - ifindex, - address->addr4, - plen, - peer_address->addr4); - } else { - g_assert (!peer_address); - success = nm_platform_ip6_address_delete (platform, - ifindex, - address->addr6, - plen); - } - g_assert (success); - } - - /* Let's wait until we get the result */ - end_time = nm_utils_get_monotonic_timestamp_msec () + 250; - do { - if (external_command) - nm_platform_process_events (platform); - - /* let's wait until we see the address as we added it. */ - if (is_v4) { - const NMPlatformIP4Address *a; - - a = nm_platform_ip4_address_get (platform, ifindex, address->addr4, plen, peer_address->addr4); - if (!a) - break; - } else { - const NMPlatformIP6Address *a; - - a = nm_platform_ip6_address_get (platform, ifindex, address->addr6); - if (!a) - break; - } - - /* 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); +_ip_address_del(NMPlatform * platform, + gboolean external_command, + gboolean is_v4, + int ifindex, + const NMIPAddr *address, + int plen, + const NMIPAddr *peer_address) +{ + gint64 end_time; + + external_command = nmtstp_run_command_check_external(external_command); + + _init_platform(&platform, external_command); + + if (external_command) { + const char *ifname; + char b1[NM_UTILS_INET_ADDRSTRLEN]; + char b2[NM_UTILS_INET_ADDRSTRLEN]; + int success; + gboolean had_address; + + ifname = nm_platform_link_get_name(platform, ifindex); + g_assert(ifname); + + /* let's wait until we see the address as we added it. */ + if (is_v4) + had_address = !!nm_platform_ip4_address_get(platform, + ifindex, + address->addr4, + plen, + peer_address->addr4); + else + had_address = !!nm_platform_ip6_address_get(platform, ifindex, &address->addr6); + + if (is_v4) { + success = nmtstp_run_command("ip address delete %s%s%s/%d dev %s", + _nm_utils_inet4_ntop(address->addr4, b1), + peer_address->addr4 != address->addr4 ? " peer " : "", + peer_address->addr4 != address->addr4 + ? _nm_utils_inet4_ntop(peer_address->addr4, b2) + : "", + plen, + ifname); + } else { + g_assert(!peer_address); + success = nmtstp_run_command("ip address delete %s/%d dev %s", + _nm_utils_inet6_ntop(&address->addr6, b1), + plen, + ifname); + } + g_assert(success == 0 || !had_address); + } else { + gboolean success; + + if (is_v4) { + success = nm_platform_ip4_address_delete(platform, + ifindex, + address->addr4, + plen, + peer_address->addr4); + } else { + g_assert(!peer_address); + success = nm_platform_ip6_address_delete(platform, ifindex, address->addr6, plen); + } + g_assert(success); + } + + /* Let's wait until we get the result */ + end_time = nm_utils_get_monotonic_timestamp_msec() + 250; + do { + if (external_command) + nm_platform_process_events(platform); + + /* let's wait until we see the address as we added it. */ + if (is_v4) { + const NMPlatformIP4Address *a; + + a = nm_platform_ip4_address_get(platform, + ifindex, + address->addr4, + plen, + peer_address->addr4); + if (!a) + break; + } else { + const NMPlatformIP6Address *a; + + a = nm_platform_ip6_address_get(platform, ifindex, &address->addr6); + if (!a) + break; + } + + /* 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); } void -nmtstp_ip4_address_del (NMPlatform *platform, - gboolean external_command, - int ifindex, - in_addr_t address, - int plen, - in_addr_t peer_address) -{ - _ip_address_del (platform, - external_command, - TRUE, - ifindex, - (NMIPAddr *) &address, - plen, - (NMIPAddr *) &peer_address); +nmtstp_ip4_address_del(NMPlatform *platform, + gboolean external_command, + int ifindex, + in_addr_t address, + int plen, + in_addr_t peer_address) +{ + _ip_address_del(platform, + external_command, + TRUE, + ifindex, + (NMIPAddr *) &address, + plen, + (NMIPAddr *) &peer_address); } void -nmtstp_ip6_address_del (NMPlatform *platform, - gboolean external_command, - int ifindex, - struct in6_addr address, - int plen) +nmtstp_ip6_address_del(NMPlatform * platform, + gboolean external_command, + int ifindex, + struct in6_addr address, + int plen) { - _ip_address_del (platform, - external_command, - FALSE, - ifindex, - (NMIPAddr *) &address, - plen, - NULL); + _ip_address_del(platform, external_command, FALSE, ifindex, (NMIPAddr *) &address, plen, NULL); } /*****************************************************************************/ -#define _assert_pllink(platform, success, pllink, name, type) \ - G_STMT_START { \ - const NMPlatformLink *_pllink = (pllink); \ - \ - if ((success)) { \ - g_assert (_pllink); \ - g_assert (_pllink == nmtstp_link_get_typed (platform, _pllink->ifindex, (name), (type))); \ - } else { \ - g_assert (!_pllink); \ - g_assert (!nmtstp_link_get (platform, 0, (name))); \ - } \ - } G_STMT_END +#define _assert_pllink(platform, success, pllink, name, type) \ + G_STMT_START \ + { \ + const NMPlatformLink *_pllink = (pllink); \ + \ + if ((success)) { \ + g_assert(_pllink); \ + g_assert(_pllink \ + == nmtstp_link_get_typed(platform, _pllink->ifindex, (name), (type))); \ + } else { \ + g_assert(!_pllink); \ + g_assert(!nmtstp_link_get(platform, 0, (name))); \ + } \ + } \ + G_STMT_END const NMPlatformLink * -nmtstp_link_veth_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const char *peer) +nmtstp_link_bridge_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkBridge *lnk) +{ + const NMPlatformLink * pllink = NULL; + const NMPlatformLnkBridge *ll = NULL; + int r = 0; + + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); + + external_command = nmtstp_run_command_check_external(external_command); + + _init_platform(&platform, external_command); + + if (external_command) { + char sbuf_gfw[100]; + char sbuf_mhm[100]; + char sbuf_mlmc[100]; + char sbuf_mlmi[100]; + char sbuf_mmi[100]; + char sbuf_mqi[100]; + char sbuf_mqii[100]; + char sbuf_msqc[100]; + char sbuf_msqi[100]; + char sbuf_mqri[100]; + + r = nmtstp_run_command( + "ip link add %s type bridge " + "forward_delay %u " + "hello_time %u " + "max_age %u " + "ageing_time %u " + "stp_state %d " + "priority %u " + "vlan_protocol %u " + "vlan_stats_enabled %d " + "%s" /* group_fwd_mask */ + "group_address " NM_ETHER_ADDR_FORMAT_STR " " + "mcast_snooping %d " + "mcast_router %u " + "mcast_query_use_ifaddr %d " + "mcast_querier %d " + "%s" /* mcast_hash_max */ + "%s" /* mcast_last_member_count */ + "%s" /* mcast_startup_query_count */ + "%s" /* mcast_last_member_interval */ + "%s" /* mcast_membership_interval */ + "%s" /* mcast_querier_interval */ + "%s" /* mcast_query_interval */ + "%s" /* mcast_query_response_interval */ + "%s" /* mcast_startup_query_interval */ + "", + name, + lnk->forward_delay, + lnk->hello_time, + lnk->max_age, + lnk->ageing_time, + (int) lnk->stp_state, + lnk->priority, + lnk->vlan_protocol, + (int) lnk->vlan_stats_enabled, + lnk->group_fwd_mask != 0 + ? nm_sprintf_buf(sbuf_gfw, "group_fwd_mask %#x ", lnk->group_fwd_mask) + : "", + NM_ETHER_ADDR_FORMAT_VAL(lnk->group_addr), + (int) lnk->mcast_snooping, + lnk->mcast_router, + (int) lnk->mcast_query_use_ifaddr, + (int) lnk->mcast_querier, + lnk->mcast_hash_max != NM_BRIDGE_MULTICAST_HASH_MAX_DEF + ? nm_sprintf_buf(sbuf_mhm, "mcast_hash_max %u ", lnk->mcast_hash_max) + : "", + lnk->mcast_last_member_count != NM_BRIDGE_MULTICAST_LAST_MEMBER_COUNT_DEF + ? nm_sprintf_buf(sbuf_mlmc, + "mcast_last_member_count %u ", + lnk->mcast_last_member_count) + : "", + lnk->mcast_startup_query_count != NM_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT_DEF + ? nm_sprintf_buf(sbuf_msqc, + "mcast_startup_query_count %u ", + lnk->mcast_startup_query_count) + : "", + lnk->mcast_last_member_interval != NM_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL_DEF + ? nm_sprintf_buf(sbuf_mlmi, + "mcast_last_member_interval %" G_GUINT64_FORMAT " ", + lnk->mcast_last_member_interval) + : "", + lnk->mcast_membership_interval != NM_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL_DEF + ? nm_sprintf_buf(sbuf_mmi, + "mcast_membership_interval %" G_GUINT64_FORMAT " ", + lnk->mcast_membership_interval) + : "", + lnk->mcast_querier_interval != NM_BRIDGE_MULTICAST_QUERIER_INTERVAL_DEF + ? nm_sprintf_buf(sbuf_mqi, + "mcast_querier_interval %" G_GUINT64_FORMAT " ", + lnk->mcast_querier_interval) + : "", + lnk->mcast_query_interval != NM_BRIDGE_MULTICAST_QUERY_INTERVAL_DEF + ? nm_sprintf_buf(sbuf_mqii, + "mcast_query_interval %" G_GUINT64_FORMAT " ", + lnk->mcast_query_interval) + : "", + lnk->mcast_query_response_interval != NM_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL_DEF + ? nm_sprintf_buf(sbuf_mqri, + "mcast_query_response_interval %" G_GUINT64_FORMAT " ", + lnk->mcast_query_response_interval) + : "", + lnk->mcast_startup_query_interval != NM_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL_DEF + ? nm_sprintf_buf(sbuf_msqi, + "mcast_startup_query_interval %" G_GUINT64_FORMAT " ", + lnk->mcast_startup_query_interval) + : ""); + if (r == 0) + pllink = nmtstp_assert_wait_for_link(platform, name, NM_LINK_TYPE_BRIDGE, 100); + else + _LOGI( + "Adding bridge device via iproute2 failed. Assume iproute2 is not up to the task."); + } + + if (!pllink) { + r = nm_platform_link_bridge_add(platform, name, NULL, 0, lnk, &pllink); + } + + _assert_pllink(platform, r == 0, pllink, name, NM_LINK_TYPE_BRIDGE); + + ll = NMP_OBJECT_CAST_LNK_BRIDGE(NMP_OBJECT_UP_CAST(pllink)->_link.netlink.lnk); + + g_assert_cmpint(lnk->forward_delay, ==, ll->forward_delay); + g_assert_cmpint(lnk->hello_time, ==, ll->hello_time); + g_assert_cmpint(lnk->max_age, ==, ll->max_age); + g_assert_cmpint(lnk->ageing_time, ==, ll->ageing_time); + g_assert_cmpint(lnk->stp_state, ==, ll->stp_state); + g_assert_cmpint(lnk->priority, ==, ll->priority); + g_assert_cmpint(lnk->vlan_stats_enabled, ==, ll->vlan_stats_enabled); + g_assert_cmpint(lnk->group_fwd_mask, ==, ll->group_fwd_mask); + g_assert_cmpint(lnk->mcast_snooping, ==, ll->mcast_snooping); + g_assert_cmpint(lnk->mcast_router, ==, ll->mcast_router); + g_assert_cmpint(lnk->mcast_query_use_ifaddr, ==, ll->mcast_query_use_ifaddr); + g_assert_cmpint(lnk->mcast_querier, ==, ll->mcast_querier); + g_assert_cmpint(lnk->mcast_hash_max, ==, ll->mcast_hash_max); + g_assert_cmpint(lnk->mcast_last_member_count, ==, ll->mcast_last_member_count); + g_assert_cmpint(lnk->mcast_startup_query_count, ==, ll->mcast_startup_query_count); + g_assert_cmpint(lnk->mcast_last_member_interval, ==, ll->mcast_last_member_interval); + g_assert_cmpint(lnk->mcast_membership_interval, ==, ll->mcast_membership_interval); + g_assert_cmpint(lnk->mcast_querier_interval, ==, ll->mcast_querier_interval); + g_assert_cmpint(lnk->mcast_query_interval, ==, ll->mcast_query_interval); + g_assert_cmpint(lnk->mcast_query_response_interval, ==, ll->mcast_query_response_interval); + g_assert_cmpint(lnk->mcast_startup_query_interval, ==, ll->mcast_startup_query_interval); + + return pllink; +} +const NMPlatformLink * +nmtstp_link_veth_add(NMPlatform *platform, + gboolean external_command, + const char *name, + const char *peer) { - const NMPlatformLink *pllink = NULL; - gboolean success; + const NMPlatformLink *pllink = NULL; + gboolean success; - g_assert (nm_utils_ifname_valid_kernel (name, NULL)); + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); - external_command = nmtstp_run_command_check_external (external_command); + external_command = nmtstp_run_command_check_external(external_command); - _init_platform (&platform, external_command); + _init_platform(&platform, external_command); - if (external_command) { - success = !nmtstp_run_command ("ip link add dev %s type veth peer name %s", - name, peer); - if (success) { - pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_VETH, 100); - nmtstp_assert_wait_for_link (platform, peer, NM_LINK_TYPE_VETH, 10); - } - } else - success = NMTST_NM_ERR_SUCCESS (nm_platform_link_veth_add (platform, name, peer, &pllink)); + if (external_command) { + success = !nmtstp_run_command("ip link add dev %s type veth peer name %s", name, peer); + if (success) { + pllink = nmtstp_assert_wait_for_link(platform, name, NM_LINK_TYPE_VETH, 100); + nmtstp_assert_wait_for_link(platform, peer, NM_LINK_TYPE_VETH, 10); + } + } else + success = NMTST_NM_ERR_SUCCESS(nm_platform_link_veth_add(platform, name, peer, &pllink)); - g_assert (success); - _assert_pllink (platform, success, pllink, name, NM_LINK_TYPE_VETH); - return pllink; + g_assert(success); + _assert_pllink(platform, success, pllink, name, NM_LINK_TYPE_VETH); + return pllink; } const NMPlatformLink * -nmtstp_link_dummy_add (NMPlatform *platform, - gboolean external_command, - const char *name) +nmtstp_link_dummy_add(NMPlatform *platform, gboolean external_command, const char *name) { - const NMPlatformLink *pllink = NULL; - gboolean success; + const NMPlatformLink *pllink = NULL; + gboolean success; - g_assert (nm_utils_ifname_valid_kernel (name, NULL)); + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); - external_command = nmtstp_run_command_check_external (external_command); + external_command = nmtstp_run_command_check_external(external_command); - _init_platform (&platform, external_command); + _init_platform(&platform, external_command); - if (external_command) { - success = !nmtstp_run_command ("ip link add %s type dummy", - name); - if (success) - pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_DUMMY, 100); - } else - success = NMTST_NM_ERR_SUCCESS (nm_platform_link_dummy_add (platform, name, &pllink)); + if (external_command) { + success = !nmtstp_run_command("ip link add %s type dummy", name); + if (success) + pllink = nmtstp_assert_wait_for_link(platform, name, NM_LINK_TYPE_DUMMY, 100); + } else + success = NMTST_NM_ERR_SUCCESS(nm_platform_link_dummy_add(platform, name, &pllink)); - g_assert (success); - _assert_pllink (platform, success, pllink, name, NM_LINK_TYPE_DUMMY); - return pllink; + g_assert(success); + _assert_pllink(platform, success, pllink, name, NM_LINK_TYPE_DUMMY); + return pllink; } const NMPlatformLink * -nmtstp_link_gre_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkGre *lnk) +nmtstp_link_gre_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkGre *lnk) { - const NMPlatformLink *pllink = NULL; - gboolean success; - char b1[INET_ADDRSTRLEN]; - char b2[INET_ADDRSTRLEN]; - NMLinkType link_type; + const NMPlatformLink *pllink = NULL; + gboolean success; + char b1[INET_ADDRSTRLEN]; + char b2[INET_ADDRSTRLEN]; + NMLinkType link_type; - g_assert (nm_utils_ifname_valid_kernel (name, NULL)); + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); - external_command = nmtstp_run_command_check_external (external_command); - link_type = lnk->is_tap ? NM_LINK_TYPE_GRETAP : NM_LINK_TYPE_GRE; + external_command = nmtstp_run_command_check_external(external_command); + link_type = lnk->is_tap ? NM_LINK_TYPE_GRETAP : NM_LINK_TYPE_GRE; - _init_platform (&platform, external_command); + _init_platform(&platform, external_command); - if (external_command) { - gs_free char *dev = NULL; - char *obj, *type; + if (external_command) { + gs_free char *dev = NULL; + char * obj, *type; - if (lnk->parent_ifindex) - dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (platform, lnk->parent_ifindex)); + if (lnk->parent_ifindex) + dev = + g_strdup_printf("dev %s", nm_platform_link_get_name(platform, lnk->parent_ifindex)); - obj = lnk->is_tap ? "link" : "tunnel"; - type = lnk->is_tap ? "type gretap" : "mode gre"; + obj = lnk->is_tap ? "link" : "tunnel"; + type = lnk->is_tap ? "type gretap" : "mode gre"; - success = !nmtstp_run_command ("ip %s add %s %s %s local %s remote %s ttl %u tos %02x %s", - obj, - name, - type, - dev ?: "", - _nm_utils_inet4_ntop (lnk->local, b1), - _nm_utils_inet4_ntop (lnk->remote, b2), - lnk->ttl, - lnk->tos, - lnk->path_mtu_discovery ? "pmtudisc" : "nopmtudisc"); - if (success) - pllink = nmtstp_assert_wait_for_link (platform, name, link_type, 100); - } else - success = NMTST_NM_ERR_SUCCESS (nm_platform_link_gre_add (platform, name, NULL, 0, lnk, &pllink)); + success = !nmtstp_run_command("ip %s add %s %s %s local %s remote %s ttl %u tos %02x %s", + obj, + name, + type, + dev ?: "", + _nm_utils_inet4_ntop(lnk->local, b1), + _nm_utils_inet4_ntop(lnk->remote, b2), + lnk->ttl, + lnk->tos, + lnk->path_mtu_discovery ? "pmtudisc" : "nopmtudisc"); + if (success) + pllink = nmtstp_assert_wait_for_link(platform, name, link_type, 100); + } else + success = + NMTST_NM_ERR_SUCCESS(nm_platform_link_gre_add(platform, name, NULL, 0, lnk, &pllink)); - _assert_pllink (platform, success, pllink, name, link_type); + _assert_pllink(platform, success, pllink, name, link_type); - return pllink; + return pllink; } const NMPlatformLink * -nmtstp_link_ip6tnl_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkIp6Tnl *lnk) -{ - const NMPlatformLink *pllink = NULL; - gboolean success; - char b1[NM_UTILS_INET_ADDRSTRLEN]; - char b2[NM_UTILS_INET_ADDRSTRLEN]; - char encap[20]; - char tclass[20]; - gboolean encap_ignore; - gboolean tclass_inherit; - - g_assert (nm_utils_ifname_valid_kernel (name, NULL)); - g_assert (!lnk->is_gre); - - external_command = nmtstp_run_command_check_external (external_command); - - _init_platform (&platform, external_command); - - if (external_command) { - gs_free char *dev = NULL; - const char *mode; - - if (lnk->parent_ifindex) - dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (platform, lnk->parent_ifindex)); - - switch (lnk->proto) { - case IPPROTO_IPIP: - mode = "ipip6"; - break; - case IPPROTO_IPV6: - mode = "ip6ip6"; - break; - default: - g_assert_not_reached (); - } - - encap_ignore = NM_FLAGS_HAS (lnk->flags, IP6_TNL_F_IGN_ENCAP_LIMIT); - tclass_inherit = NM_FLAGS_HAS (lnk->flags, IP6_TNL_F_USE_ORIG_TCLASS); - - success = !nmtstp_run_command ("ip -6 tunnel add %s mode %s %s local %s remote %s ttl %u tclass %s encaplimit %s flowlabel %x", - name, - mode, - dev, - _nm_utils_inet6_ntop (&lnk->local, b1), - _nm_utils_inet6_ntop (&lnk->remote, b2), - lnk->ttl, - tclass_inherit ? "inherit" : nm_sprintf_buf (tclass, "%02x", lnk->tclass), - encap_ignore ? "none" : nm_sprintf_buf (encap, "%u", lnk->encap_limit), - lnk->flow_label); - if (success) - pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_IP6TNL, 100); - } else - success = NMTST_NM_ERR_SUCCESS (nm_platform_link_ip6tnl_add (platform, name, lnk, &pllink)); - - _assert_pllink (platform, success, pllink, name, NM_LINK_TYPE_IP6TNL); - - return pllink; +nmtstp_link_ip6tnl_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkIp6Tnl *lnk) +{ + const NMPlatformLink *pllink = NULL; + gboolean success; + char b1[NM_UTILS_INET_ADDRSTRLEN]; + char b2[NM_UTILS_INET_ADDRSTRLEN]; + char encap[20]; + char tclass[20]; + gboolean encap_ignore; + gboolean tclass_inherit; + + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); + g_assert(!lnk->is_gre); + + external_command = nmtstp_run_command_check_external(external_command); + + _init_platform(&platform, external_command); + + if (external_command) { + gs_free char *dev = NULL; + const char * mode; + + if (lnk->parent_ifindex) + dev = + g_strdup_printf("dev %s", nm_platform_link_get_name(platform, lnk->parent_ifindex)); + + switch (lnk->proto) { + case IPPROTO_IPIP: + mode = "ipip6"; + break; + case IPPROTO_IPV6: + mode = "ip6ip6"; + break; + default: + g_assert_not_reached(); + } + + encap_ignore = NM_FLAGS_HAS(lnk->flags, IP6_TNL_F_IGN_ENCAP_LIMIT); + tclass_inherit = NM_FLAGS_HAS(lnk->flags, IP6_TNL_F_USE_ORIG_TCLASS); + + success = !nmtstp_run_command( + "ip -6 tunnel add %s mode %s %s local %s remote %s ttl %u tclass %s encaplimit %s " + "flowlabel %x", + name, + mode, + dev, + _nm_utils_inet6_ntop(&lnk->local, b1), + _nm_utils_inet6_ntop(&lnk->remote, b2), + lnk->ttl, + tclass_inherit ? "inherit" : nm_sprintf_buf(tclass, "%02x", lnk->tclass), + encap_ignore ? "none" : nm_sprintf_buf(encap, "%u", lnk->encap_limit), + lnk->flow_label); + if (success) + pllink = nmtstp_assert_wait_for_link(platform, name, NM_LINK_TYPE_IP6TNL, 100); + } else + success = NMTST_NM_ERR_SUCCESS(nm_platform_link_ip6tnl_add(platform, name, lnk, &pllink)); + + _assert_pllink(platform, success, pllink, name, NM_LINK_TYPE_IP6TNL); + + return pllink; } const NMPlatformLink * -nmtstp_link_ip6gre_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkIp6Tnl *lnk) -{ - const NMPlatformLink *pllink = NULL; - gboolean success; - char b1[NM_UTILS_INET_ADDRSTRLEN]; - char b2[NM_UTILS_INET_ADDRSTRLEN]; - char tclass[20]; - gboolean tclass_inherit; - - g_assert (nm_utils_ifname_valid_kernel (name, NULL)); - g_assert (lnk->is_gre); - - external_command = nmtstp_run_command_check_external (external_command); - - _init_platform (&platform, external_command); - - if (external_command) { - gs_free char *dev = NULL; - - if (lnk->parent_ifindex) - dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (platform, lnk->parent_ifindex)); - - tclass_inherit = NM_FLAGS_HAS (lnk->flags, IP6_TNL_F_USE_ORIG_TCLASS); - - success = !nmtstp_run_command ("ip link add %s type %s %s local %s remote %s ttl %u tclass %s flowlabel %x", - name, - lnk->is_tap ? "ip6gretap" : "ip6gre", - dev, - _nm_utils_inet6_ntop (&lnk->local, b1), - _nm_utils_inet6_ntop (&lnk->remote, b2), - lnk->ttl, - tclass_inherit ? "inherit" : nm_sprintf_buf (tclass, "%02x", lnk->tclass), - lnk->flow_label); - if (success) { - pllink = nmtstp_assert_wait_for_link (platform, - name, - lnk->is_tap ? NM_LINK_TYPE_IP6GRETAP : NM_LINK_TYPE_IP6GRE, - 100); - } - } else - success = NMTST_NM_ERR_SUCCESS (nm_platform_link_ip6gre_add (platform, name, NULL, 0, lnk, &pllink)); - - _assert_pllink (platform, success, pllink, name, lnk->is_tap ? NM_LINK_TYPE_IP6GRETAP : NM_LINK_TYPE_IP6GRE); - - return pllink; +nmtstp_link_ip6gre_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkIp6Tnl *lnk) +{ + const NMPlatformLink *pllink = NULL; + gboolean success; + char b1[NM_UTILS_INET_ADDRSTRLEN]; + char b2[NM_UTILS_INET_ADDRSTRLEN]; + char tclass[20]; + gboolean tclass_inherit; + + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); + g_assert(lnk->is_gre); + + external_command = nmtstp_run_command_check_external(external_command); + + _init_platform(&platform, external_command); + + if (external_command) { + gs_free char *dev = NULL; + + if (lnk->parent_ifindex) + dev = + g_strdup_printf("dev %s", nm_platform_link_get_name(platform, lnk->parent_ifindex)); + + tclass_inherit = NM_FLAGS_HAS(lnk->flags, IP6_TNL_F_USE_ORIG_TCLASS); + + success = !nmtstp_run_command( + "ip link add %s type %s %s local %s remote %s ttl %u tclass %s flowlabel %x", + name, + lnk->is_tap ? "ip6gretap" : "ip6gre", + dev, + _nm_utils_inet6_ntop(&lnk->local, b1), + _nm_utils_inet6_ntop(&lnk->remote, b2), + lnk->ttl, + tclass_inherit ? "inherit" : nm_sprintf_buf(tclass, "%02x", lnk->tclass), + lnk->flow_label); + if (success) { + pllink = nmtstp_assert_wait_for_link(platform, + name, + lnk->is_tap ? NM_LINK_TYPE_IP6GRETAP + : NM_LINK_TYPE_IP6GRE, + 100); + } + } else + success = NMTST_NM_ERR_SUCCESS( + nm_platform_link_ip6gre_add(platform, name, NULL, 0, lnk, &pllink)); + + _assert_pllink(platform, + success, + pllink, + name, + lnk->is_tap ? NM_LINK_TYPE_IP6GRETAP : NM_LINK_TYPE_IP6GRE); + + return pllink; } const NMPlatformLink * -nmtstp_link_ipip_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkIpIp *lnk) +nmtstp_link_ipip_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkIpIp *lnk) { - const NMPlatformLink *pllink = NULL; - gboolean success; - char b1[INET_ADDRSTRLEN]; - char b2[INET_ADDRSTRLEN]; + const NMPlatformLink *pllink = NULL; + gboolean success; + char b1[INET_ADDRSTRLEN]; + char b2[INET_ADDRSTRLEN]; - g_assert (nm_utils_ifname_valid_kernel (name, NULL)); + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); - external_command = nmtstp_run_command_check_external (external_command); + external_command = nmtstp_run_command_check_external(external_command); - _init_platform (&platform, external_command); + _init_platform(&platform, external_command); - if (external_command) { - gs_free char *dev = NULL; + if (external_command) { + gs_free char *dev = NULL; - if (lnk->parent_ifindex) - dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (platform, lnk->parent_ifindex)); + if (lnk->parent_ifindex) + dev = + g_strdup_printf("dev %s", nm_platform_link_get_name(platform, lnk->parent_ifindex)); - success = !nmtstp_run_command ("ip tunnel add %s mode ipip %s local %s remote %s ttl %u tos %02x %s", - name, - dev, - _nm_utils_inet4_ntop (lnk->local, b1), - _nm_utils_inet4_ntop (lnk->remote, b2), - lnk->ttl, - lnk->tos, - lnk->path_mtu_discovery ? "pmtudisc" : "nopmtudisc"); - if (success) - pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_IPIP, 100); - } else - success = NMTST_NM_ERR_SUCCESS (nm_platform_link_ipip_add (platform, name, lnk, &pllink)); + success = !nmtstp_run_command( + "ip tunnel add %s mode ipip %s local %s remote %s ttl %u tos %02x %s", + name, + dev, + _nm_utils_inet4_ntop(lnk->local, b1), + _nm_utils_inet4_ntop(lnk->remote, b2), + lnk->ttl, + lnk->tos, + lnk->path_mtu_discovery ? "pmtudisc" : "nopmtudisc"); + if (success) + pllink = nmtstp_assert_wait_for_link(platform, name, NM_LINK_TYPE_IPIP, 100); + } else + success = NMTST_NM_ERR_SUCCESS(nm_platform_link_ipip_add(platform, name, lnk, &pllink)); - _assert_pllink (platform, success, pllink, name, NM_LINK_TYPE_IPIP); + _assert_pllink(platform, success, pllink, name, NM_LINK_TYPE_IPIP); - return pllink; + return pllink; } const NMPlatformLink * -nmtstp_link_macvlan_add (NMPlatform *platform, - gboolean external_command, - const char *name, - int parent, - const NMPlatformLnkMacvlan *lnk) +nmtstp_link_macvlan_add(NMPlatform * platform, + gboolean external_command, + const char * name, + int parent, + const NMPlatformLnkMacvlan *lnk) { - const NMPlatformLink *pllink = NULL; - gboolean success; - NMLinkType link_type; + const NMPlatformLink *pllink = NULL; + gboolean success; + NMLinkType link_type; - g_assert (nm_utils_ifname_valid_kernel (name, NULL)); + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); - external_command = nmtstp_run_command_check_external (external_command); + external_command = nmtstp_run_command_check_external(external_command); - _init_platform (&platform, external_command); + _init_platform(&platform, external_command); - link_type = lnk->tap ? NM_LINK_TYPE_MACVTAP : NM_LINK_TYPE_MACVLAN; + link_type = lnk->tap ? NM_LINK_TYPE_MACVTAP : NM_LINK_TYPE_MACVLAN; - if (external_command) { - const char *dev; - char *modes[] = { - [MACVLAN_MODE_BRIDGE] = "bridge", - [MACVLAN_MODE_VEPA] = "vepa", - [MACVLAN_MODE_PRIVATE] = "private", - [MACVLAN_MODE_PASSTHRU] = "passthru", - }; + if (external_command) { + const char *dev; + char * modes[] = { + [MACVLAN_MODE_BRIDGE] = "bridge", + [MACVLAN_MODE_VEPA] = "vepa", + [MACVLAN_MODE_PRIVATE] = "private", + [MACVLAN_MODE_PASSTHRU] = "passthru", + }; - dev = nm_platform_link_get_name (platform, parent); - g_assert (dev); - g_assert_cmpint (lnk->mode, <, G_N_ELEMENTS (modes)); + dev = nm_platform_link_get_name(platform, parent); + g_assert(dev); + g_assert_cmpint(lnk->mode, <, G_N_ELEMENTS(modes)); - success = !nmtstp_run_command ("ip link add name %s link %s type %s mode %s %s", - name, - dev, - lnk->tap ? "macvtap" : "macvlan", - modes[lnk->mode], - lnk->no_promisc ? "nopromisc" : ""); - if (success) - pllink = nmtstp_assert_wait_for_link (platform, name, link_type, 100); - } else - success = NMTST_NM_ERR_SUCCESS (nm_platform_link_macvlan_add (platform, name, parent, lnk, &pllink)); + success = !nmtstp_run_command("ip link add name %s link %s type %s mode %s %s", + name, + dev, + lnk->tap ? "macvtap" : "macvlan", + modes[lnk->mode], + lnk->no_promisc ? "nopromisc" : ""); + if (success) + pllink = nmtstp_assert_wait_for_link(platform, name, link_type, 100); + } else + success = NMTST_NM_ERR_SUCCESS( + nm_platform_link_macvlan_add(platform, name, parent, lnk, &pllink)); - _assert_pllink (platform, success, pllink, name, link_type); + _assert_pllink(platform, success, pllink, name, link_type); - return pllink; + return pllink; } const NMPlatformLink * -nmtstp_link_sit_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkSit *lnk) +nmtstp_link_sit_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkSit *lnk) { - const NMPlatformLink *pllink = NULL; - gboolean success; - char b1[INET_ADDRSTRLEN]; - char b2[INET_ADDRSTRLEN]; + const NMPlatformLink *pllink = NULL; + gboolean success; + char b1[INET_ADDRSTRLEN]; + char b2[INET_ADDRSTRLEN]; - g_assert (nm_utils_ifname_valid_kernel (name, NULL)); + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); - external_command = nmtstp_run_command_check_external (external_command); + external_command = nmtstp_run_command_check_external(external_command); - _init_platform (&platform, external_command); + _init_platform(&platform, external_command); - if (external_command) { - const char *dev = ""; + if (external_command) { + const char *dev = ""; - if (lnk->parent_ifindex) { - const char *parent_name; + if (lnk->parent_ifindex) { + const char *parent_name; - parent_name = nm_platform_link_get_name (platform, lnk->parent_ifindex); - g_assert (parent_name); - dev = nm_sprintf_bufa (100, " dev %s", parent_name); - } + parent_name = nm_platform_link_get_name(platform, lnk->parent_ifindex); + g_assert(parent_name); + dev = nm_sprintf_bufa(100, " dev %s", parent_name); + } - success = !nmtstp_run_command ("ip tunnel add %s mode sit%s local %s remote %s ttl %u tos %02x %s", - name, - dev, - _nm_utils_inet4_ntop (lnk->local, b1), - _nm_utils_inet4_ntop (lnk->remote, b2), - lnk->ttl, - lnk->tos, - lnk->path_mtu_discovery ? "pmtudisc" : "nopmtudisc"); - if (success) - pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_SIT, 100); - } else - success = NMTST_NM_ERR_SUCCESS (nm_platform_link_sit_add (platform, name, lnk, &pllink)); + success = + !nmtstp_run_command("ip tunnel add %s mode sit%s local %s remote %s ttl %u tos %02x %s", + name, + dev, + _nm_utils_inet4_ntop(lnk->local, b1), + _nm_utils_inet4_ntop(lnk->remote, b2), + lnk->ttl, + lnk->tos, + lnk->path_mtu_discovery ? "pmtudisc" : "nopmtudisc"); + if (success) + pllink = nmtstp_assert_wait_for_link(platform, name, NM_LINK_TYPE_SIT, 100); + } else + success = NMTST_NM_ERR_SUCCESS(nm_platform_link_sit_add(platform, name, lnk, &pllink)); - _assert_pllink (platform, success, pllink, name, NM_LINK_TYPE_SIT); + _assert_pllink(platform, success, pllink, name, NM_LINK_TYPE_SIT); - return pllink; + return pllink; } const NMPlatformLink * -nmtstp_link_tun_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkTun *lnk, - int *out_fd) -{ - const NMPlatformLink *pllink = NULL; - int err; - int r; - - g_assert (nm_utils_ifname_valid_kernel (name, NULL)); - g_assert (lnk); - g_assert (NM_IN_SET (lnk->type, IFF_TUN, IFF_TAP)); - g_assert (!out_fd || *out_fd == -1); - - if (!lnk->persist) { - /* ip tuntap does not support non-persistent devices. - * - * Add this device only via NMPlatform. */ - if (external_command == -1) - external_command = FALSE; - } - - external_command = nmtstp_run_command_check_external (external_command); - - _init_platform (&platform, external_command); - - if (external_command) { - g_assert (lnk->persist); - - err = nmtstp_run_command ("ip tuntap add" - " mode %s" - "%s" /* user */ - "%s" /* group */ - "%s" /* pi */ - "%s" /* vnet_hdr */ - "%s" /* multi_queue */ - " name %s", - lnk->type == IFF_TUN ? "tun" : "tap", - lnk->owner_valid ? nm_sprintf_bufa (100, " user %u", (guint) lnk->owner) : "", - lnk->group_valid ? nm_sprintf_bufa (100, " group %u", (guint) lnk->group) : "", - lnk->pi ? " pi" : "", - lnk->vnet_hdr ? " vnet_hdr" : "", - lnk->multi_queue ? " multi_queue" : "", - name); - /* Older versions of iproute2 don't support adding devices. - * On failure, fallback to using platform code. */ - if (err == 0) - pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_TUN, 100); - else - g_error ("failure to add tun/tap device via ip-route"); - } else { - g_assert (lnk->persist || out_fd); - r = nm_platform_link_tun_add (platform, name, lnk, &pllink, out_fd); - g_assert_cmpint (r, ==, 0); - } - - g_assert (pllink); - g_assert_cmpint (pllink->type, ==, NM_LINK_TYPE_TUN); - g_assert_cmpstr (pllink->name, ==, name); - return pllink; +nmtstp_link_tun_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkTun *lnk, + int * out_fd) +{ + const NMPlatformLink *pllink = NULL; + int err; + int r; + + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); + g_assert(lnk); + g_assert(NM_IN_SET(lnk->type, IFF_TUN, IFF_TAP)); + g_assert(!out_fd || *out_fd == -1); + + if (!lnk->persist) { + /* ip tuntap does not support non-persistent devices. + * + * Add this device only via NMPlatform. */ + if (external_command == -1) + external_command = FALSE; + } + + external_command = nmtstp_run_command_check_external(external_command); + + _init_platform(&platform, external_command); + + if (external_command) { + g_assert(lnk->persist); + + err = nmtstp_run_command( + "ip tuntap add" + " mode %s" + "%s" /* user */ + "%s" /* group */ + "%s" /* pi */ + "%s" /* vnet_hdr */ + "%s" /* multi_queue */ + " name %s", + lnk->type == IFF_TUN ? "tun" : "tap", + lnk->owner_valid ? nm_sprintf_bufa(100, " user %u", (guint) lnk->owner) : "", + lnk->group_valid ? nm_sprintf_bufa(100, " group %u", (guint) lnk->group) : "", + lnk->pi ? " pi" : "", + lnk->vnet_hdr ? " vnet_hdr" : "", + lnk->multi_queue ? " multi_queue" : "", + name); + /* Older versions of iproute2 don't support adding devices. + * On failure, fallback to using platform code. */ + if (err == 0) + pllink = nmtstp_assert_wait_for_link(platform, name, NM_LINK_TYPE_TUN, 100); + else + g_error("failure to add tun/tap device via ip-route"); + } else { + g_assert(lnk->persist || out_fd); + r = nm_platform_link_tun_add(platform, name, lnk, &pllink, out_fd); + g_assert_cmpint(r, ==, 0); + } + + g_assert(pllink); + g_assert_cmpint(pllink->type, ==, NM_LINK_TYPE_TUN); + g_assert_cmpstr(pllink->name, ==, name); + return pllink; } const NMPlatformLink * -nmtstp_link_vrf_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkVrf *lnk, - gboolean *out_not_supported) +nmtstp_link_vrf_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkVrf *lnk, + gboolean * out_not_supported) { - const NMPlatformLink *pllink = NULL; - int r = 0; + const NMPlatformLink *pllink = NULL; + int r = 0; - g_assert (nm_utils_ifname_valid_kernel (name, NULL)); + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); - NM_SET_OUT (out_not_supported, FALSE); - external_command = nmtstp_run_command_check_external (external_command); + NM_SET_OUT(out_not_supported, FALSE); + external_command = nmtstp_run_command_check_external(external_command); - _init_platform (&platform, external_command); + _init_platform(&platform, external_command); - if (external_command) { - r = nmtstp_run_command ("ip link add %s type vrf table %u", - name, - lnk->table); + if (external_command) { + r = nmtstp_run_command("ip link add %s type vrf table %u", name, lnk->table); - if (r == 0) - pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_VRF, 100); - else - _LOGI ("Adding vrf device via iproute2 failed. Assume iproute2 is not up to the task."); - } + if (r == 0) + pllink = nmtstp_assert_wait_for_link(platform, name, NM_LINK_TYPE_VRF, 100); + else + _LOGI("Adding vrf device via iproute2 failed. Assume iproute2 is not up to the task."); + } - if (!pllink) { - r = nm_platform_link_vrf_add (platform, name, lnk, &pllink); - if (r == -EOPNOTSUPP) - NM_SET_OUT (out_not_supported, TRUE); - } + if (!pllink) { + r = nm_platform_link_vrf_add(platform, name, lnk, &pllink); + if (r == -EOPNOTSUPP) + NM_SET_OUT(out_not_supported, TRUE); + } - _assert_pllink (platform, r == 0, pllink, name, NM_LINK_TYPE_VRF); + _assert_pllink(platform, r == 0, pllink, name, NM_LINK_TYPE_VRF); - return pllink; + return pllink; } const NMPlatformLink * -nmtstp_link_vxlan_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkVxlan *lnk) -{ - const NMPlatformLink *pllink = NULL; - int err; - int r; - - g_assert (nm_utils_ifname_valid_kernel (name, NULL)); - - external_command = nmtstp_run_command_check_external (external_command); - - _init_platform (&platform, external_command); - - if (external_command) { - gs_free char *dev = NULL; - char local[NM_UTILS_INET_ADDRSTRLEN]; - char group[NM_UTILS_INET_ADDRSTRLEN]; - - if (lnk->parent_ifindex) - dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (platform, lnk->parent_ifindex)); - - if (lnk->local) - _nm_utils_inet4_ntop (lnk->local, local); - else if (memcmp (&lnk->local6, &in6addr_any, sizeof (in6addr_any))) - _nm_utils_inet6_ntop (&lnk->local6, local); - else - local[0] = '\0'; - - if (lnk->group) - _nm_utils_inet4_ntop (lnk->group, group); - else if (memcmp (&lnk->group6, &in6addr_any, sizeof (in6addr_any))) - _nm_utils_inet6_ntop (&lnk->group6, group); - else - group[0] = '\0'; - - err = nmtstp_run_command ("ip link add %s type vxlan id %u %s local %s group %s ttl %u tos %02x dstport %u srcport %u %u ageing %u", - name, - lnk->id, - dev ?: "", - local, - group, - lnk->ttl, - lnk->tos, - lnk->dst_port, - lnk->src_port_min, lnk->src_port_max, - lnk->ageing); - /* Older versions of iproute2 don't support adding vxlan devices. - * On failure, fallback to using platform code. */ - if (err == 0) - pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_VXLAN, 100); - else - _LOGI ("Adding vxlan device via iproute2 failed. Assume iproute2 is not up to the task."); - } - if (!pllink) { - r = nm_platform_link_vxlan_add (platform, name, lnk, &pllink); - g_assert (NMTST_NM_ERR_SUCCESS (r)); - g_assert (pllink); - } - - g_assert_cmpint (pllink->type, ==, NM_LINK_TYPE_VXLAN); - g_assert_cmpstr (pllink->name, ==, name); - return pllink; +nmtstp_link_vxlan_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkVxlan *lnk) +{ + const NMPlatformLink *pllink = NULL; + int err; + int r; + + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); + + external_command = nmtstp_run_command_check_external(external_command); + + _init_platform(&platform, external_command); + + if (external_command) { + gs_free char *dev = NULL; + char local[NM_UTILS_INET_ADDRSTRLEN]; + char group[NM_UTILS_INET_ADDRSTRLEN]; + + if (lnk->parent_ifindex) + dev = + g_strdup_printf("dev %s", nm_platform_link_get_name(platform, lnk->parent_ifindex)); + + if (lnk->local) + _nm_utils_inet4_ntop(lnk->local, local); + else if (memcmp(&lnk->local6, &in6addr_any, sizeof(in6addr_any))) + _nm_utils_inet6_ntop(&lnk->local6, local); + else + local[0] = '\0'; + + if (lnk->group) + _nm_utils_inet4_ntop(lnk->group, group); + else if (memcmp(&lnk->group6, &in6addr_any, sizeof(in6addr_any))) + _nm_utils_inet6_ntop(&lnk->group6, group); + else + group[0] = '\0'; + + err = nmtstp_run_command("ip link add %s type vxlan id %u %s local %s group %s ttl %u tos " + "%02x dstport %u srcport %u %u ageing %u", + name, + lnk->id, + dev ?: "", + local, + group, + lnk->ttl, + lnk->tos, + lnk->dst_port, + lnk->src_port_min, + lnk->src_port_max, + lnk->ageing); + /* Older versions of iproute2 don't support adding vxlan devices. + * On failure, fallback to using platform code. */ + if (err == 0) + pllink = nmtstp_assert_wait_for_link(platform, name, NM_LINK_TYPE_VXLAN, 100); + else + _LOGI( + "Adding vxlan device via iproute2 failed. Assume iproute2 is not up to the task."); + } + if (!pllink) { + r = nm_platform_link_vxlan_add(platform, name, lnk, &pllink); + g_assert(NMTST_NM_ERR_SUCCESS(r)); + g_assert(pllink); + } + + g_assert_cmpint(pllink->type, ==, NM_LINK_TYPE_VXLAN); + g_assert_cmpstr(pllink->name, ==, name); + return pllink; } /*****************************************************************************/ const NMPlatformLink * -nmtstp_link_get_typed (NMPlatform *platform, - int ifindex, - const char *name, - NMLinkType link_type) +nmtstp_link_get_typed(NMPlatform *platform, int ifindex, const char *name, NMLinkType link_type) { - const NMPlatformLink *pllink = NULL; + const NMPlatformLink *pllink = NULL; - _init_platform (&platform, FALSE); + _init_platform(&platform, FALSE); - if (ifindex > 0) { - pllink = nm_platform_link_get (platform, ifindex); + if (ifindex > 0) { + pllink = nm_platform_link_get(platform, ifindex); - if (pllink) { - g_assert_cmpint (pllink->ifindex, ==, ifindex); - if (name) - g_assert_cmpstr (name, ==, pllink->name); - } else { - if (name) - g_assert (!nm_platform_link_get_by_ifname (platform, name)); - } - } else { - g_assert (name); + if (pllink) { + g_assert_cmpint(pllink->ifindex, ==, ifindex); + if (name) + g_assert_cmpstr(name, ==, pllink->name); + } else { + if (name) + g_assert(!nm_platform_link_get_by_ifname(platform, name)); + } + } else { + g_assert(name); - pllink = nm_platform_link_get_by_ifname (platform, name); + pllink = nm_platform_link_get_by_ifname(platform, name); - if (pllink) - g_assert_cmpstr (name, ==, pllink->name); - } + if (pllink) + g_assert_cmpstr(name, ==, pllink->name); + } - g_assert (!name || nm_utils_ifname_valid_kernel (name, NULL)); + g_assert(!name || nm_utils_ifname_valid_kernel(name, NULL)); - if (pllink && link_type != NM_LINK_TYPE_NONE) - g_assert_cmpint (pllink->type, ==, link_type); + if (pllink && link_type != NM_LINK_TYPE_NONE) + g_assert_cmpint(pllink->type, ==, link_type); - return pllink; + return pllink; } const NMPlatformLink * -nmtstp_link_get (NMPlatform *platform, - int ifindex, - const char *name) +nmtstp_link_get(NMPlatform *platform, int ifindex, const char *name) { - return nmtstp_link_get_typed (platform, ifindex, name, NM_LINK_TYPE_NONE); + return nmtstp_link_get_typed(platform, ifindex, name, NM_LINK_TYPE_NONE); } /*****************************************************************************/ void -nmtstp_link_delete (NMPlatform *platform, - gboolean external_command, - int ifindex, - const char *name, - gboolean require_exist) +nmtstp_link_delete(NMPlatform *platform, + gboolean external_command, + int ifindex, + const char *name, + gboolean require_exist) { - gint64 end_time; - const NMPlatformLink *pllink; - gboolean success; - gs_free char *name_copy = NULL; + gint64 end_time; + const NMPlatformLink *pllink; + gboolean success; + gs_free char * name_copy = NULL; - external_command = nmtstp_run_command_check_external (external_command); + external_command = nmtstp_run_command_check_external(external_command); - _init_platform (&platform, external_command); + _init_platform(&platform, external_command); - pllink = nmtstp_link_get (platform, ifindex, name); + pllink = nmtstp_link_get(platform, ifindex, name); - if (!pllink) { - g_assert (!require_exist); - return; - } + if (!pllink) { + g_assert(!require_exist); + return; + } - name = name_copy = g_strdup (pllink->name); - ifindex = pllink->ifindex; + name = name_copy = g_strdup(pllink->name); + ifindex = pllink->ifindex; - if (external_command) { - nmtstp_run_command_check ("ip link delete %s", name); - } else { - success = nm_platform_link_delete (platform, ifindex); - g_assert (success); - } + if (external_command) { + nmtstp_run_command_check("ip link delete %s", name); + } else { + success = nm_platform_link_delete(platform, ifindex); + g_assert(success); + } - /* Let's wait until we get the result */ - end_time = nm_utils_get_monotonic_timestamp_msec () + 250; - do { - if (external_command) - nm_platform_process_events (platform); + /* Let's wait until we get the result */ + end_time = nm_utils_get_monotonic_timestamp_msec() + 250; + do { + if (external_command) + nm_platform_process_events(platform); - if (!nm_platform_link_get (platform, ifindex)) { - g_assert (!nm_platform_link_get_by_ifname (platform, name)); - break; - } + if (!nm_platform_link_get(platform, ifindex)) { + g_assert(!nm_platform_link_get_by_ifname(platform, name)); + break; + } - /* for internal command, we expect not to reach this line.*/ - g_assert (external_command); + /* 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); + nmtstp_assert_wait_for_signal_until(platform, end_time); + } while (TRUE); } /*****************************************************************************/ void -nmtstp_link_set_updown (NMPlatform *platform, - gboolean external_command, - int ifindex, - gboolean up) +nmtstp_link_set_updown(NMPlatform *platform, gboolean external_command, int ifindex, gboolean up) { - const NMPlatformLink *plink; - gint64 end_time; + const NMPlatformLink *plink; + gint64 end_time; - external_command = nmtstp_run_command_check_external (external_command); + external_command = nmtstp_run_command_check_external(external_command); - _init_platform (&platform, external_command); + _init_platform(&platform, external_command); - if (external_command) { - const char *ifname; + if (external_command) { + const char *ifname; - ifname = nm_platform_link_get_name (platform, ifindex); - g_assert (ifname); + ifname = nm_platform_link_get_name(platform, ifindex); + g_assert(ifname); - nmtstp_run_command_check ("ip link set %s %s", - ifname, - up ? "up" : "down"); - } else { - if (up) - g_assert (nm_platform_link_set_up (platform, ifindex, NULL)); - else - g_assert (nm_platform_link_set_down (platform, ifindex)); - } + nmtstp_run_command_check("ip link set %s %s", ifname, up ? "up" : "down"); + } else { + if (up) + g_assert(nm_platform_link_set_up(platform, ifindex, NULL)); + else + g_assert(nm_platform_link_set_down(platform, ifindex)); + } - /* Let's wait until we get the result */ - end_time = nm_utils_get_monotonic_timestamp_msec () + 250; - do { - if (external_command) - nm_platform_process_events (platform); + /* Let's wait until we get the result */ + end_time = nm_utils_get_monotonic_timestamp_msec() + 250; + do { + if (external_command) + nm_platform_process_events(platform); - /* let's wait until we see the address as we added it. */ - plink = nm_platform_link_get (platform, ifindex); - g_assert (plink); + /* let's wait until we see the address as we added it. */ + plink = nm_platform_link_get(platform, ifindex); + g_assert(plink); - if (NM_FLAGS_HAS (plink->n_ifi_flags, IFF_UP) == !!up) - break; + if (NM_FLAGS_HAS(plink->n_ifi_flags, IFF_UP) == !!up) + break; + + /* 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); +} + +/*****************************************************************************/ + +gboolean +nmtstp_kernel_support_get(NMPlatformKernelSupportType type) +{ + const NMPlatformLink *pllink; + NMTernary v; - /* for internal command, we expect not to reach this line.*/ - g_assert (external_command); + v = nm_platform_kernel_support_get_full(type, FALSE); + if (v != NM_TERNARY_DEFAULT) + return v != NM_TERNARY_FALSE; - nmtstp_assert_wait_for_signal_until (platform, end_time); - } while (TRUE); + switch (type) { + case NM_PLATFORM_KERNEL_SUPPORT_TYPE_IFLA_BR_VLAN_STATS_ENABLED: + pllink = nmtstp_link_bridge_add(NULL, -1, "br-test-11", &nm_platform_lnk_bridge_default); + nmtstp_link_delete(NULL, -1, pllink->ifindex, NULL, TRUE); + v = nm_platform_kernel_support_get_full(type, FALSE); + g_assert(v != NM_TERNARY_DEFAULT); + return v; + default: + g_assert_not_reached(); + } } /*****************************************************************************/ struct _NMTstpNamespaceHandle { - pid_t pid; - int pipe_fd; + pid_t pid; + int pipe_fd; }; NMTstpNamespaceHandle * -nmtstp_namespace_create (int unshare_flags, GError **error) -{ - NMTstpNamespaceHandle *ns_handle; - int e; - int errsv; - pid_t pid, pid2; - int pipefd_c2p[2]; - int pipefd_p2c[2]; - ssize_t r; - - e = pipe2 (pipefd_c2p, O_CLOEXEC); - if (e != 0) { - errsv = errno; - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "pipe() failed with %d (%s)", errsv, nm_strerror_native (errsv)); - return FALSE; - } - - e = pipe2 (pipefd_p2c, O_CLOEXEC); - if (e != 0) { - errsv = errno; - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "pipe() failed with %d (%s)", errsv, nm_strerror_native (errsv)); - nm_close (pipefd_c2p[0]); - nm_close (pipefd_c2p[1]); - return FALSE; - } - - pid = fork (); - if (pid < 0) { - errsv = errno; - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "fork() failed with %d (%s)", errsv, nm_strerror_native (errsv)); - nm_close (pipefd_c2p[0]); - nm_close (pipefd_c2p[1]); - nm_close (pipefd_p2c[0]); - nm_close (pipefd_p2c[1]); - return FALSE; - } - - if (pid == 0) { - char read_buf[1]; - - nm_close (pipefd_c2p[0]); /* close read-end */ - nm_close (pipefd_p2c[1]); /* close write-end */ - - if (unshare (unshare_flags) != 0) { - errsv = errno; - if (errsv == 0) - errsv = -1; - } else - errsv = 0; - - /* sync with parent process and send result. */ - do { - r = write (pipefd_c2p[1], &errsv, sizeof (errsv)); - } while (r < 0 && errno == EINTR); - if (r != sizeof (errsv)) { - errsv = errno; - if (errsv == 0) - errsv = -2; - } - nm_close (pipefd_c2p[1]); - - /* wait until parent process terminates (or kills us). */ - if (errsv == 0) { - do { - r = read (pipefd_p2c[0], read_buf, sizeof (read_buf)); - } while (r < 0 && errno == EINTR); - } - nm_close (pipefd_p2c[0]); - _exit (0); - } - - nm_close (pipefd_c2p[1]); /* close write-end */ - nm_close (pipefd_p2c[0]); /* close read-end */ - - /* sync with child process. */ - do { - r = read (pipefd_c2p[0], &errsv, sizeof (errsv)); - } while (r < 0 && errno == EINTR); - - nm_close (pipefd_c2p[0]); - - if ( r != sizeof (errsv) - || errsv != 0) { - int status; - - if (r != sizeof (errsv)) { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "child process failed for unknown reason"); - } else { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "child process signaled failure %d (%s)", errsv, nm_strerror_native (errsv)); - } - nm_close (pipefd_p2c[1]); - kill (pid, SIGKILL); - do { - pid2 = waitpid (pid, &status, 0); - } while (pid2 == -1 && errno == EINTR); - return FALSE; - } - - ns_handle = g_new0 (NMTstpNamespaceHandle, 1); - ns_handle->pid = pid; - ns_handle->pipe_fd = pipefd_p2c[1]; - return ns_handle; +nmtstp_namespace_create(int unshare_flags, GError **error) +{ + NMTstpNamespaceHandle *ns_handle; + int e; + int errsv; + pid_t pid, pid2; + int pipefd_c2p[2]; + int pipefd_p2c[2]; + ssize_t r; + + e = pipe2(pipefd_c2p, O_CLOEXEC); + if (e != 0) { + errsv = errno; + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "pipe() failed with %d (%s)", + errsv, + nm_strerror_native(errsv)); + return FALSE; + } + + e = pipe2(pipefd_p2c, O_CLOEXEC); + if (e != 0) { + errsv = errno; + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "pipe() failed with %d (%s)", + errsv, + nm_strerror_native(errsv)); + nm_close(pipefd_c2p[0]); + nm_close(pipefd_c2p[1]); + return FALSE; + } + + pid = fork(); + if (pid < 0) { + errsv = errno; + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "fork() failed with %d (%s)", + errsv, + nm_strerror_native(errsv)); + nm_close(pipefd_c2p[0]); + nm_close(pipefd_c2p[1]); + nm_close(pipefd_p2c[0]); + nm_close(pipefd_p2c[1]); + return FALSE; + } + + if (pid == 0) { + char read_buf[1]; + + nm_close(pipefd_c2p[0]); /* close read-end */ + nm_close(pipefd_p2c[1]); /* close write-end */ + + if (unshare(unshare_flags) != 0) { + errsv = errno; + if (errsv == 0) + errsv = -1; + } else + errsv = 0; + + /* sync with parent process and send result. */ + do { + r = write(pipefd_c2p[1], &errsv, sizeof(errsv)); + } while (r < 0 && errno == EINTR); + if (r != sizeof(errsv)) { + errsv = errno; + if (errsv == 0) + errsv = -2; + } + nm_close(pipefd_c2p[1]); + + /* wait until parent process terminates (or kills us). */ + if (errsv == 0) { + do { + r = read(pipefd_p2c[0], read_buf, sizeof(read_buf)); + } while (r < 0 && errno == EINTR); + } + nm_close(pipefd_p2c[0]); + _exit(0); + } + + nm_close(pipefd_c2p[1]); /* close write-end */ + nm_close(pipefd_p2c[0]); /* close read-end */ + + /* sync with child process. */ + do { + r = read(pipefd_c2p[0], &errsv, sizeof(errsv)); + } while (r < 0 && errno == EINTR); + + nm_close(pipefd_c2p[0]); + + if (r != sizeof(errsv) || errsv != 0) { + int status; + + if (r != sizeof(errsv)) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "child process failed for unknown reason"); + } else { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "child process signaled failure %d (%s)", + errsv, + nm_strerror_native(errsv)); + } + nm_close(pipefd_p2c[1]); + kill(pid, SIGKILL); + do { + pid2 = waitpid(pid, &status, 0); + } while (pid2 == -1 && errno == EINTR); + return FALSE; + } + + ns_handle = g_new0(NMTstpNamespaceHandle, 1); + ns_handle->pid = pid; + ns_handle->pipe_fd = pipefd_p2c[1]; + return ns_handle; } pid_t -nmtstp_namespace_handle_get_pid (NMTstpNamespaceHandle *ns_handle) +nmtstp_namespace_handle_get_pid(NMTstpNamespaceHandle *ns_handle) { - g_return_val_if_fail (ns_handle, 0); - g_return_val_if_fail (ns_handle->pid > 0, 0); + g_return_val_if_fail(ns_handle, 0); + g_return_val_if_fail(ns_handle->pid > 0, 0); - return ns_handle->pid; + return ns_handle->pid; } void -nmtstp_namespace_handle_release (NMTstpNamespaceHandle *ns_handle) +nmtstp_namespace_handle_release(NMTstpNamespaceHandle *ns_handle) { - pid_t pid; - int status; + pid_t pid; + int status; - if (!ns_handle) - return; + if (!ns_handle) + return; - g_return_if_fail (ns_handle->pid > 0); + g_return_if_fail(ns_handle->pid > 0); - nm_close (ns_handle->pipe_fd); - ns_handle->pipe_fd = 0; + nm_close(ns_handle->pipe_fd); + ns_handle->pipe_fd = 0; - kill (ns_handle->pid, SIGKILL); + kill(ns_handle->pid, SIGKILL); - do { - pid = waitpid (ns_handle->pid, &status, 0); - } while (pid == -1 && errno == EINTR); - ns_handle->pid = 0; + do { + pid = waitpid(ns_handle->pid, &status, 0); + } while (pid == -1 && errno == EINTR); + ns_handle->pid = 0; - g_free (ns_handle); + g_free(ns_handle); } int -nmtstp_namespace_get_fd_for_process (pid_t pid, const char *ns_name) +nmtstp_namespace_get_fd_for_process(pid_t pid, const char *ns_name) { - char p[1000]; + char p[1000]; - g_return_val_if_fail (pid > 0, 0); - g_return_val_if_fail (ns_name && ns_name[0] && strlen (ns_name) < 50, 0); + g_return_val_if_fail(pid > 0, 0); + g_return_val_if_fail(ns_name && ns_name[0] && strlen(ns_name) < 50, 0); - nm_sprintf_buf (p, "/proc/%lu/ns/%s", (unsigned long) pid, ns_name); + nm_sprintf_buf(p, "/proc/%lu/ns/%s", (unsigned long) pid, ns_name); - return open(p, O_RDONLY | O_CLOEXEC); + return open(p, O_RDONLY | O_CLOEXEC); } /*****************************************************************************/ void -nmtstp_netns_select_random (NMPlatform **platforms, gsize n_platforms, NMPNetns **netns) +nmtstp_netns_select_random(NMPlatform **platforms, gsize n_platforms, NMPNetns **netns) { - int i; + int i; - g_assert (platforms); - g_assert (n_platforms && n_platforms <= G_MAXINT32); - g_assert (netns && !*netns); - for (i = 0; i < n_platforms; i++) - g_assert (NM_IS_PLATFORM (platforms[i])); + g_assert(platforms); + g_assert(n_platforms && n_platforms <= G_MAXINT32); + g_assert(netns && !*netns); + for (i = 0; i < n_platforms; i++) + g_assert(NM_IS_PLATFORM(platforms[i])); - i = nmtst_get_rand_uint32 () % (n_platforms + 1); - if (i == 0) - return; - g_assert (nm_platform_netns_push (platforms[i - 1], netns)); + i = nmtst_get_rand_uint32() % (n_platforms + 1); + if (i == 0) + return; + g_assert(nm_platform_netns_push(platforms[i - 1], netns)); } /*****************************************************************************/ @@ -2036,94 +2476,94 @@ nmtstp_netns_select_random (NMPlatform **platforms, gsize n_platforms, NMPNetns NMTST_DEFINE(); static gboolean -unshare_user (void) +unshare_user(void) { - FILE *f; - uid_t uid = geteuid (); - gid_t gid = getegid (); + FILE *f; + uid_t uid = geteuid(); + gid_t gid = getegid(); - /* Already a root? */ - if (gid == 0 && uid == 0) - return TRUE; + /* Already a root? */ + if (gid == 0 && uid == 0) + return TRUE; - /* Become a root in new user NS. */ - if (unshare (CLONE_NEWUSER) != 0) - return FALSE; + /* Become a root in new user NS. */ + if (unshare(CLONE_NEWUSER) != 0) + return FALSE; - /* Since Linux 3.19 we have to disable setgroups() in order to map users. - * Just proceed if the file is not there. */ - f = fopen ("/proc/self/setgroups", "we"); - if (f) { - fprintf (f, "deny"); - fclose (f); - } + /* Since Linux 3.19 we have to disable setgroups() in order to map users. + * Just proceed if the file is not there. */ + f = fopen("/proc/self/setgroups", "we"); + if (f) { + fprintf(f, "deny"); + fclose(f); + } - /* Map current UID to root in NS to be created. */ - f = fopen ("/proc/self/uid_map", "we"); - if (!f) - return FALSE; - fprintf (f, "0 %d 1", uid); - fclose (f); + /* Map current UID to root in NS to be created. */ + f = fopen("/proc/self/uid_map", "we"); + if (!f) + return FALSE; + fprintf(f, "0 %d 1", uid); + fclose(f); - /* Map current GID to root in NS to be created. */ - f = fopen ("/proc/self/gid_map", "we"); - if (!f) - return FALSE; - fprintf (f, "0 %d 1", gid); - fclose (f); + /* Map current GID to root in NS to be created. */ + f = fopen("/proc/self/gid_map", "we"); + if (!f) + return FALSE; + fprintf(f, "0 %d 1", gid); + fclose(f); - return TRUE; + return TRUE; } int -main (int argc, char **argv) +main(int argc, char **argv) { - int result; - const char *program = *argv; + int result; + const char *program = *argv; - _nmtstp_init_tests (&argc, &argv); + _nmtstp_init_tests(&argc, &argv); - if ( nmtstp_is_root_test () - && (geteuid () != 0 || getegid () != 0)) { - if ( g_getenv ("NMTST_FORCE_REAL_ROOT") - || !unshare_user ()) { - /* Try to exec as sudo, this function does not return, if a sudo-cmd is set. */ - nmtst_reexec_sudo (); + if (nmtstp_is_root_test() && (geteuid() != 0 || getegid() != 0)) { + if (g_getenv("NMTST_FORCE_REAL_ROOT") || !unshare_user()) { + /* Try to exec as sudo, this function does not return, if a sudo-cmd is set. */ + nmtst_reexec_sudo(); #ifdef REQUIRE_ROOT_TESTS - g_print ("Fail test: requires root privileges (%s)\n", program); - return EXIT_FAILURE; + g_print("Fail test: requires root privileges (%s)\n", program); + return EXIT_FAILURE; #else - g_print ("Skipping test: requires root privileges (%s)\n", program); - return g_test_run (); + g_print("Skipping test: requires root privileges (%s)\n", program); + return g_test_run(); #endif - } - } + } + } - if (nmtstp_is_root_test () && !g_getenv ("NMTST_NO_UNSHARE")) { - int errsv; + if (nmtstp_is_root_test() && !g_getenv("NMTST_NO_UNSHARE")) { + int errsv; - if (unshare (CLONE_NEWNET | CLONE_NEWNS) != 0) { - errsv = errno; - g_error ("unshare(CLONE_NEWNET|CLONE_NEWNS) failed with %s (%d)", nm_strerror_native (errsv), errsv); - } + if (unshare(CLONE_NEWNET | CLONE_NEWNS) != 0) { + errsv = errno; + g_error("unshare(CLONE_NEWNET|CLONE_NEWNS) failed with %s (%d)", + nm_strerror_native(errsv), + errsv); + } - /* We need a read-only /sys so that the platform knows there's no udev. */ - mount (NULL, "/sys", "sysfs", MS_SLAVE, NULL); - if (mount ("sys", "/sys", "sysfs", MS_RDONLY, NULL) != 0) { - errsv = errno; - g_error ("mount(\"/sys\") failed with %s (%d)", nm_strerror_native (errsv), errsv); - } - } + /* We need a read-only /sys so that the platform knows there's no udev. */ + mount(NULL, "/sys", "sysfs", MS_SLAVE, NULL); + if (mount("sys", "/sys", "sysfs", MS_RDONLY, NULL) != 0) { + errsv = errno; + g_error("mount(\"/sys\") failed with %s (%d)", nm_strerror_native(errsv), errsv); + } + } - nmtstp_setup_platform (); + nmtstp_setup_platform(); - _nmtstp_setup_tests (); + _nmtstp_setup_tests(); - result = g_test_run (); + result = g_test_run(); - nmtstp_link_delete (NM_PLATFORM_GET, -1, -1, DEVICE_NAME, FALSE); + nmtstp_link_delete(NM_PLATFORM_GET, -1, -1, DEVICE_NAME, FALSE); - g_object_unref (NM_PLATFORM_GET); - return result; + g_object_unref(NM_PLATFORM_GET); + return result; } diff --git a/src/platform/tests/test-common.h b/src/platform/tests/test-common.h index 522c3756..1d996f46 100644 --- a/src/platform/tests/test-common.h +++ b/src/platform/tests/test-common.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2016 - 2017 Red Hat, Inc. */ @@ -22,359 +22,476 @@ /*****************************************************************************/ -#define _NMLOG_PREFIX_NAME "platform-test" -#define _NMLOG_DOMAIN LOGD_PLATFORM -#define _NMLOG(level, ...) _LOG(level, _NMLOG_DOMAIN, __VA_ARGS__) - -#define _LOG(level, domain, ...) \ - G_STMT_START { \ - const NMLogLevel __level = (level); \ - const NMLogDomain __domain = (domain); \ - \ - if (nm_logging_enabled (__level, __domain)) { \ - gint64 _ts = nm_utils_get_monotonic_timestamp_nsec (); \ - \ - _nm_log (__level, __domain, 0, NULL, NULL, \ - "%s[%ld.%09ld]: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ - _NMLOG_PREFIX_NAME, \ - (long) (_ts / NM_UTILS_NSEC_PER_SEC), \ - (long) (_ts % NM_UTILS_NSEC_PER_SEC) \ - _NM_UTILS_MACRO_REST (__VA_ARGS__)); \ - } \ - } G_STMT_END +#define _NMLOG_PREFIX_NAME "platform-test" +#define _NMLOG_DOMAIN LOGD_PLATFORM +#define _NMLOG(level, ...) _LOG(level, _NMLOG_DOMAIN, __VA_ARGS__) + +#define _LOG(level, domain, ...) \ + G_STMT_START \ + { \ + const NMLogLevel __level = (level); \ + const NMLogDomain __domain = (domain); \ + \ + if (nm_logging_enabled(__level, __domain)) { \ + gint64 _ts = nm_utils_get_monotonic_timestamp_nsec(); \ + \ + _nm_log(__level, \ + __domain, \ + 0, \ + NULL, \ + NULL, \ + "%s[%ld.%09ld]: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME, \ + (long) (_ts / NM_UTILS_NSEC_PER_SEC), \ + (long) (_ts % NM_UTILS_NSEC_PER_SEC) _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } \ + G_STMT_END /*****************************************************************************/ -gboolean nmtstp_is_root_test (void); -gboolean nmtstp_is_sysfs_writable (void); +gboolean nmtstp_is_root_test(void); +gboolean nmtstp_is_sysfs_writable(void); /*****************************************************************************/ typedef struct _NMTstpNamespaceHandle NMTstpNamespaceHandle; -NMTstpNamespaceHandle *nmtstp_namespace_create (int flags, GError **error); +NMTstpNamespaceHandle *nmtstp_namespace_create(int flags, GError **error); -void nmtstp_namespace_handle_release (NMTstpNamespaceHandle *handle); -pid_t nmtstp_namespace_handle_get_pid (NMTstpNamespaceHandle *handle); +void nmtstp_namespace_handle_release(NMTstpNamespaceHandle *handle); +pid_t nmtstp_namespace_handle_get_pid(NMTstpNamespaceHandle *handle); -int nmtstp_namespace_get_fd_for_process (pid_t pid, const char *ns_name); +int nmtstp_namespace_get_fd_for_process(pid_t pid, const char *ns_name); /*****************************************************************************/ -void nmtstp_netns_select_random (NMPlatform **platforms, gsize n_platforms, NMPNetns **netns); +void nmtstp_netns_select_random(NMPlatform **platforms, gsize n_platforms, NMPNetns **netns); /*****************************************************************************/ typedef struct { - gulong handler_id; - const char *name; - NMPlatformSignalChangeType change_type; - int received_count; - GMainLoop *loop; - int ifindex; - const char *ifname; + gulong handler_id; + const char * name; + NMPlatformSignalChangeType change_type; + int received_count; + GMainLoop * loop; + int ifindex; + const char * ifname; } SignalData; -SignalData *add_signal_full (const char *name, NMPlatformSignalChangeType change_type, GCallback callback, int ifindex, const char *ifname); -#define add_signal(name, change_type, callback) add_signal_full (name, change_type, (GCallback) callback, 0, NULL) -#define add_signal_ifindex(name, change_type, callback, ifindex) add_signal_full (name, change_type, (GCallback) callback, ifindex, NULL) -#define add_signal_ifname(name, change_type, callback, ifname) add_signal_full (name, change_type, (GCallback) callback, 0, ifname) -void _accept_signal (const char *file, int line, const char *func, SignalData *data); -void _accept_signals (const char *file, int line, const char *func, SignalData *data, int min, int max); -void _wait_signal (const char *file, int line, const char *func, SignalData *data); -void _accept_or_wait_signal (const char *file, int line, const char *func, SignalData *data); -void _ensure_no_signal (const char *file, int line, const char *func, SignalData *data); -void _free_signal (const char *file, int line, const char *func, SignalData *data); +SignalData *add_signal_full(const char * name, + NMPlatformSignalChangeType change_type, + GCallback callback, + int ifindex, + const char * ifname); +#define add_signal(name, change_type, callback) \ + add_signal_full(name, change_type, (GCallback) callback, 0, NULL) +#define add_signal_ifindex(name, change_type, callback, ifindex) \ + add_signal_full(name, change_type, (GCallback) callback, ifindex, NULL) +#define add_signal_ifname(name, change_type, callback, ifname) \ + add_signal_full(name, change_type, (GCallback) callback, 0, ifname) +void _accept_signal(const char *file, int line, const char *func, SignalData *data); +void +_accept_signals(const char *file, int line, const char *func, SignalData *data, int min, int max); +void _wait_signal(const char *file, int line, const char *func, SignalData *data); +void _accept_or_wait_signal(const char *file, int line, const char *func, SignalData *data); +void _ensure_no_signal(const char *file, int line, const char *func, SignalData *data); +void _free_signal(const char *file, int line, const char *func, SignalData *data); #define accept_signal(data) _accept_signal(__FILE__, __LINE__, G_STRFUNC, data) -#define accept_signals(data, min, max) _accept_signals(__FILE__, __LINE__, G_STRFUNC, data, min, max) -#define wait_signal(data) _wait_signal(__FILE__, __LINE__, G_STRFUNC, data) +#define accept_signals(data, min, max) \ + _accept_signals(__FILE__, __LINE__, G_STRFUNC, data, min, max) +#define wait_signal(data) _wait_signal(__FILE__, __LINE__, G_STRFUNC, data) #define accept_or_wait_signal(data) _accept_or_wait_signal(__FILE__, __LINE__, G_STRFUNC, data) -#define ensure_no_signal(data) _ensure_no_signal(__FILE__, __LINE__, G_STRFUNC, data) -#define free_signal(data) _free_signal(__FILE__, __LINE__, G_STRFUNC, data) +#define ensure_no_signal(data) _ensure_no_signal(__FILE__, __LINE__, G_STRFUNC, data) +#define free_signal(data) _free_signal(__FILE__, __LINE__, G_STRFUNC, data) -void link_callback (NMPlatform *platform, int obj_type_i, int ifindex, NMPlatformLink *received, int change_type_i, SignalData *data); +void link_callback(NMPlatform * platform, + int obj_type_i, + int ifindex, + NMPlatformLink *received, + int change_type_i, + SignalData * data); /*****************************************************************************/ -int nmtstp_run_command (const char *format, ...) _nm_printf (1, 2); -#define nmtstp_run_command_check(...) do { g_assert_cmpint (nmtstp_run_command (__VA_ARGS__), ==, 0); } while (0) +int nmtstp_run_command(const char *format, ...) _nm_printf(1, 2); +#define nmtstp_run_command_check(...) \ + do { \ + g_assert_cmpint(nmtstp_run_command(__VA_ARGS__), ==, 0); \ + } while (0) /*****************************************************************************/ -guint nmtstp_wait_for_signal (NMPlatform *platform, gint64 timeout_msec); -guint 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, gint64 timeout_msec); -const NMPlatformLink *nmtstp_wait_for_link_until (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, gint64 until_ms); - -#define nmtstp_assert_wait_for_signal(platform, timeout_msec) \ - G_STMT_START { \ - if (nmtstp_wait_for_signal (platform, timeout_msec) == 0) \ - g_assert_not_reached (); \ - } G_STMT_END - -#define nmtstp_assert_wait_for_signal_until(platform, until_ms) \ - G_STMT_START { \ - if (nmtstp_wait_for_signal_until (platform, until_ms) == 0) \ - g_assert_not_reached (); \ - } G_STMT_END +guint nmtstp_wait_for_signal(NMPlatform *platform, gint64 timeout_msec); +guint 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, + gint64 timeout_msec); +const NMPlatformLink *nmtstp_wait_for_link_until(NMPlatform *platform, + const char *ifname, + NMLinkType expected_link_type, + gint64 until_ms); + +#define nmtstp_assert_wait_for_signal(platform, timeout_msec) \ + G_STMT_START \ + { \ + if (nmtstp_wait_for_signal(platform, timeout_msec) == 0) \ + g_assert_not_reached(); \ + } \ + G_STMT_END + +#define nmtstp_assert_wait_for_signal_until(platform, until_ms) \ + G_STMT_START \ + { \ + if (nmtstp_wait_for_signal_until(platform, until_ms) == 0) \ + g_assert_not_reached(); \ + } \ + G_STMT_END #define nmtstp_assert_wait_for_link(platform, ifname, expected_link_type, timeout_msec) \ - nmtst_assert_nonnull (nmtstp_wait_for_link (platform, ifname, expected_link_type, timeout_msec)) + nmtst_assert_nonnull(nmtstp_wait_for_link(platform, ifname, expected_link_type, timeout_msec)) #define nmtstp_assert_wait_for_link_until(platform, ifname, expected_link_type, until_ms) \ - nmtst_assert_nonnull (nmtstp_wait_for_link_until (platform, ifname, expected_link_type, until_ms)) + nmtst_assert_nonnull(nmtstp_wait_for_link_until(platform, ifname, expected_link_type, until_ms)) /*****************************************************************************/ -int nmtstp_run_command_check_external_global (void); -gboolean nmtstp_run_command_check_external (int external_command); +int nmtstp_run_command_check_external_global(void); +gboolean nmtstp_run_command_check_external(int external_command); /*****************************************************************************/ -const NMPlatformIP4Route *_nmtstp_assert_ip4_route_exists (const char *file, - guint line, - const char *func, - NMPlatform *platform, - int c_exists, - const char *ifname, - guint32 network, - int plen, - guint32 metric, - guint8 tos); -#define nmtstp_assert_ip4_route_exists(platform, c_exists, ifname, network, plen, metric, tos) _nmtstp_assert_ip4_route_exists (__FILE__, __LINE__, G_STRFUNC, platform, c_exists, ifname, network, plen, metric, tos) - -const NMPlatformIP4Route *nmtstp_ip4_route_get (NMPlatform *platform, - int ifindex, - guint32 network, - int plen, - guint32 metric, - guint8 tos); - -const NMPlatformIP6Route *_nmtstp_assert_ip6_route_exists (const char *file, - guint line, - const char *func, - NMPlatform *platform, - int c_exists, - const char *ifname, - const struct in6_addr *network, - guint plen, - guint32 metric, - const struct in6_addr *src, - guint8 src_plen); -#define nmtstp_assert_ip6_route_exists(platform, c_exists, ifname, network, plen, metric, src, src_plen) _nmtstp_assert_ip6_route_exists (__FILE__, __LINE__, G_STRFUNC, platform, c_exists, ifname, network, plen, metric, src, src_plen) - -const NMPlatformIP6Route *nmtstp_ip6_route_get (NMPlatform *platform, - int ifindex, - const struct in6_addr *network, - guint plen, - guint32 metric, - const struct in6_addr *src, - guint8 src_plen); +const NMPlatformIP4Route *_nmtstp_assert_ip4_route_exists(const char *file, + guint line, + const char *func, + NMPlatform *platform, + int c_exists, + const char *ifname, + guint32 network, + int plen, + guint32 metric, + guint8 tos); +#define nmtstp_assert_ip4_route_exists(platform, c_exists, ifname, network, plen, metric, tos) \ + _nmtstp_assert_ip4_route_exists(__FILE__, \ + __LINE__, \ + G_STRFUNC, \ + platform, \ + c_exists, \ + ifname, \ + network, \ + plen, \ + metric, \ + tos) + +const NMPlatformIP4Route *nmtstp_ip4_route_get(NMPlatform *platform, + int ifindex, + guint32 network, + int plen, + guint32 metric, + guint8 tos); + +const NMPlatformIP6Route *_nmtstp_assert_ip6_route_exists(const char * file, + guint line, + const char * func, + NMPlatform * platform, + int c_exists, + const char * ifname, + const struct in6_addr *network, + guint plen, + guint32 metric, + const struct in6_addr *src, + guint8 src_plen); +#define nmtstp_assert_ip6_route_exists(platform, \ + c_exists, \ + ifname, \ + network, \ + plen, \ + metric, \ + src, \ + src_plen) \ + _nmtstp_assert_ip6_route_exists(__FILE__, \ + __LINE__, \ + G_STRFUNC, \ + platform, \ + c_exists, \ + ifname, \ + network, \ + plen, \ + metric, \ + src, \ + src_plen) + +const NMPlatformIP6Route *nmtstp_ip6_route_get(NMPlatform * platform, + int ifindex, + const struct in6_addr *network, + guint plen, + guint32 metric, + const struct in6_addr *src, + guint8 src_plen); /*****************************************************************************/ -gboolean nmtstp_ip_address_check_lifetime (const NMPlatformIPAddress *addr, - gint64 now, - guint32 expected_lifetime, - guint32 expected_preferred); -void nmtstp_ip_address_assert_lifetime (const NMPlatformIPAddress *addr, - gint64 now, - guint32 expected_lifetime, - guint32 expected_preferred); - -void nmtstp_ip4_address_add (NMPlatform *platform, - gboolean external_command, - int ifindex, - in_addr_t address, - int plen, - in_addr_t peer_address, - guint32 lifetime, - guint32 preferred, - guint32 flags, - const char *label); -void nmtstp_ip6_address_add (NMPlatform *platform, - gboolean external_command, - int ifindex, - struct in6_addr address, - int plen, - struct in6_addr peer_address, - guint32 lifetime, - guint32 preferred, - guint32 flags); -void nmtstp_ip4_address_del (NMPlatform *platform, - gboolean external_command, - int ifindex, - in_addr_t address, - int plen, - in_addr_t peer_address); -void nmtstp_ip6_address_del (NMPlatform *platform, - gboolean external_command, - int ifindex, - struct in6_addr address, - int plen); - -void nmtstp_ip4_route_add (NMPlatform *platform, - int ifindex, - NMIPConfigSource source, - in_addr_t network, - guint8 plen, - in_addr_t gateway, - in_addr_t pref_src, - guint32 metric, - guint32 mss); - -void nmtstp_ip6_route_add (NMPlatform *platform, - int ifindex, - NMIPConfigSource source, - struct in6_addr network, - guint8 plen, - struct in6_addr gateway, - struct in6_addr pref_src, - guint32 metric, - guint32 mss); +gboolean nmtstp_ip_address_check_lifetime(const NMPlatformIPAddress *addr, + gint64 now, + guint32 expected_lifetime, + guint32 expected_preferred); +void nmtstp_ip_address_assert_lifetime(const NMPlatformIPAddress *addr, + gint64 now, + guint32 expected_lifetime, + guint32 expected_preferred); + +void nmtstp_ip4_address_add(NMPlatform *platform, + gboolean external_command, + int ifindex, + in_addr_t address, + int plen, + in_addr_t peer_address, + guint32 lifetime, + guint32 preferred, + guint32 flags, + const char *label); +void nmtstp_ip6_address_add(NMPlatform * platform, + gboolean external_command, + int ifindex, + struct in6_addr address, + int plen, + struct in6_addr peer_address, + guint32 lifetime, + guint32 preferred, + guint32 flags); +void nmtstp_ip4_address_del(NMPlatform *platform, + gboolean external_command, + int ifindex, + in_addr_t address, + int plen, + in_addr_t peer_address); +void nmtstp_ip6_address_del(NMPlatform * platform, + gboolean external_command, + int ifindex, + struct in6_addr address, + int plen); + +void nmtstp_ip4_route_add(NMPlatform * platform, + int ifindex, + NMIPConfigSource source, + in_addr_t network, + guint8 plen, + in_addr_t gateway, + in_addr_t pref_src, + guint32 metric, + guint32 mss); + +void nmtstp_ip6_route_add(NMPlatform * platform, + int ifindex, + NMIPConfigSource source, + struct in6_addr network, + guint8 plen, + struct in6_addr gateway, + struct in6_addr pref_src, + guint32 metric, + guint32 mss); static inline GPtrArray * -nmtstp_ip4_route_get_all (NMPlatform *platform, - int ifindex) +nmtstp_ip4_route_get_all(NMPlatform *platform, int ifindex) { - return nm_platform_lookup_object_clone (platform, - NMP_OBJECT_TYPE_IP4_ROUTE, - ifindex, - nm_platform_lookup_predicate_routes_main_skip_rtprot_kernel, - NULL); + return nm_platform_lookup_object_clone( + platform, + NMP_OBJECT_TYPE_IP4_ROUTE, + ifindex, + nm_platform_lookup_predicate_routes_main_skip_rtprot_kernel, + NULL); } static inline GPtrArray * -nmtstp_ip6_route_get_all (NMPlatform *platform, - int ifindex) +nmtstp_ip6_route_get_all(NMPlatform *platform, int ifindex) { - return nm_platform_lookup_object_clone (platform, - NMP_OBJECT_TYPE_IP6_ROUTE, - ifindex, - nm_platform_lookup_predicate_routes_main_skip_rtprot_kernel, - NULL); + return nm_platform_lookup_object_clone( + platform, + NMP_OBJECT_TYPE_IP6_ROUTE, + ifindex, + nm_platform_lookup_predicate_routes_main_skip_rtprot_kernel, + NULL); } /*****************************************************************************/ -GArray *nmtstp_platform_ip4_address_get_all (NMPlatform *self, int ifindex); -GArray *nmtstp_platform_ip6_address_get_all (NMPlatform *self, int ifindex); +GArray *nmtstp_platform_ip4_address_get_all(NMPlatform *self, int ifindex); +GArray *nmtstp_platform_ip6_address_get_all(NMPlatform *self, int ifindex); + +/*****************************************************************************/ + +const NMPlatformIPAddress * +nmtstp_platform_ip_address_find(NMPlatform *self, int ifindex, int addr_family, gconstpointer addr); + +static inline const NMPlatformIP4Address * +nmtstp_platform_ip4_address_find(NMPlatform *self, int ifindex, in_addr_t addr) +{ + return (const NMPlatformIP4Address *) + nmtstp_platform_ip_address_find(self, ifindex, AF_INET, &addr); +} + +static inline const NMPlatformIP6Address * +nmtstp_platform_ip6_address_find(NMPlatform *self, int ifindex, const struct in6_addr *addr) +{ + return (const NMPlatformIP6Address *) + nmtstp_platform_ip_address_find(self, ifindex, AF_INET6, addr); +} + +void _nmtstp_platform_ip_addresses_assert(const char * filename, + int lineno, + NMPlatform * self, + int ifindex, + gboolean force_exact_4, + gboolean force_exact_6, + gboolean ignore_ll6, + guint addrs_len, + const char *const *addrs); + +#define nmtstp_platform_ip_addresses_assert(self, \ + ifindex, \ + force_exact_4, \ + force_exact_6, \ + ignore_ll6, \ + ...) \ + _nmtstp_platform_ip_addresses_assert(__FILE__, \ + __LINE__, \ + (self), \ + (ifindex), \ + (force_exact_4), \ + (force_exact_6), \ + (ignore_ll6), \ + NM_NARG(__VA_ARGS__), \ + ((const char *const[]){"dummy", ##__VA_ARGS__, NULL}) \ + + 1) /*****************************************************************************/ static inline gboolean -_nmtstp_platform_routing_rules_get_all_predicate (const NMPObject *obj, - gpointer user_data) +_nmtstp_platform_routing_rules_get_all_predicate(const NMPObject *obj, gpointer user_data) { - int addr_family = GPOINTER_TO_INT (user_data); + int addr_family = GPOINTER_TO_INT(user_data); - g_assert (NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_ROUTING_RULE); + g_assert(NMP_OBJECT_GET_TYPE(obj) == NMP_OBJECT_TYPE_ROUTING_RULE); - return addr_family == AF_UNSPEC - || NMP_OBJECT_CAST_ROUTING_RULE (obj)->addr_family == addr_family; + return addr_family == AF_UNSPEC + || NMP_OBJECT_CAST_ROUTING_RULE(obj)->addr_family == addr_family; } static inline GPtrArray * -nmtstp_platform_routing_rules_get_all (NMPlatform *platform, int addr_family) +nmtstp_platform_routing_rules_get_all(NMPlatform *platform, int addr_family) { - NMPLookup lookup; + NMPLookup lookup; - g_assert (NM_IS_PLATFORM (platform)); - g_assert (NM_IN_SET (addr_family, AF_UNSPEC, AF_INET, AF_INET6)); + g_assert(NM_IS_PLATFORM(platform)); + g_assert(NM_IN_SET(addr_family, AF_UNSPEC, AF_INET, AF_INET6)); - nmp_lookup_init_obj_type (&lookup, NMP_OBJECT_TYPE_ROUTING_RULE); - return nm_platform_lookup_clone (platform, - &lookup, - _nmtstp_platform_routing_rules_get_all_predicate, - GINT_TO_POINTER (addr_family)); + nmp_lookup_init_obj_type(&lookup, NMP_OBJECT_TYPE_ROUTING_RULE); + return nm_platform_lookup_clone(platform, + &lookup, + _nmtstp_platform_routing_rules_get_all_predicate, + GINT_TO_POINTER(addr_family)); } static inline guint -nmtstp_platform_routing_rules_get_count (NMPlatform *platform, int addr_family) +nmtstp_platform_routing_rules_get_count(NMPlatform *platform, int addr_family) { - const NMDedupMultiHeadEntry *head_entry; - NMDedupMultiIter iter; - const NMPObject *obj; - NMPLookup lookup; - guint n; - - g_assert (NM_IS_PLATFORM (platform)); - g_assert (NM_IN_SET (addr_family, AF_UNSPEC, AF_INET, AF_INET6)); - - nmp_lookup_init_obj_type (&lookup, NMP_OBJECT_TYPE_ROUTING_RULE); - head_entry = nm_platform_lookup (platform, &lookup); - - n = 0; - nmp_cache_iter_for_each (&iter, head_entry, &obj) { - if (_nmtstp_platform_routing_rules_get_all_predicate (obj, GINT_TO_POINTER (addr_family))) - n++; - } - return n; + const NMDedupMultiHeadEntry *head_entry; + NMDedupMultiIter iter; + const NMPObject * obj; + NMPLookup lookup; + guint n; + + g_assert(NM_IS_PLATFORM(platform)); + g_assert(NM_IN_SET(addr_family, AF_UNSPEC, AF_INET, AF_INET6)); + + nmp_lookup_init_obj_type(&lookup, NMP_OBJECT_TYPE_ROUTING_RULE); + head_entry = nm_platform_lookup(platform, &lookup); + + n = 0; + nmp_cache_iter_for_each (&iter, head_entry, &obj) { + if (_nmtstp_platform_routing_rules_get_all_predicate(obj, GINT_TO_POINTER(addr_family))) + n++; + } + return n; } -gboolean nmtstp_platform_ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen, guint32 metric); -gboolean nmtstp_platform_ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric); - -const NMPlatformLink *nmtstp_link_get_typed (NMPlatform *platform, int ifindex, const char *name, NMLinkType link_type); -const NMPlatformLink *nmtstp_link_get (NMPlatform *platform, int ifindex, const char *name); - -void nmtstp_link_set_updown (NMPlatform *platform, - gboolean external_command, - int ifindex, - gboolean up); - -const NMPlatformLink *nmtstp_link_veth_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const char *peer); -const NMPlatformLink *nmtstp_link_dummy_add (NMPlatform *platform, - gboolean external_command, - const char *name); -const NMPlatformLink *nmtstp_link_gre_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkGre *lnk); -const NMPlatformLink *nmtstp_link_ip6tnl_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkIp6Tnl *lnk); -const NMPlatformLink *nmtstp_link_ip6gre_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkIp6Tnl *lnk); -const NMPlatformLink *nmtstp_link_ipip_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkIpIp *lnk); -const NMPlatformLink *nmtstp_link_macvlan_add (NMPlatform *platform, - gboolean external_command, - const char *name, - int parent, - const NMPlatformLnkMacvlan *lnk); -const NMPlatformLink *nmtstp_link_sit_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkSit *lnk); -const NMPlatformLink *nmtstp_link_tun_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkTun *lnk, - int *out_fd); -const NMPlatformLink *nmtstp_link_vrf_add (NMPlatform *platform, - gboolean external_command, +gboolean nmtstp_platform_ip4_route_delete(NMPlatform *platform, + int ifindex, + in_addr_t network, + guint8 plen, + guint32 metric); +gboolean nmtstp_platform_ip6_route_delete(NMPlatform * platform, + int ifindex, + struct in6_addr network, + guint8 plen, + guint32 metric); + +const NMPlatformLink * +nmtstp_link_get_typed(NMPlatform *platform, int ifindex, const char *name, NMLinkType link_type); +const NMPlatformLink *nmtstp_link_get(NMPlatform *platform, int ifindex, const char *name); + +gboolean nmtstp_kernel_support_get(NMPlatformKernelSupportType type); + +void +nmtstp_link_set_updown(NMPlatform *platform, gboolean external_command, int ifindex, gboolean up); + +const NMPlatformLink *nmtstp_link_bridge_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkBridge *lnk); +const NMPlatformLink *nmtstp_link_veth_add(NMPlatform *platform, + gboolean external_command, const char *name, - const NMPlatformLnkVrf *lnk, - gboolean *out_not_supported); -const NMPlatformLink *nmtstp_link_vxlan_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkVxlan *lnk); - -void nmtstp_link_delete (NMPlatform *platform, - gboolean external_command, - int ifindex, - const char *name, - gboolean require_exist); + const char *peer); +const NMPlatformLink * +nmtstp_link_dummy_add(NMPlatform *platform, gboolean external_command, const char *name); +const NMPlatformLink *nmtstp_link_gre_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkGre *lnk); +const NMPlatformLink *nmtstp_link_ip6tnl_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkIp6Tnl *lnk); +const NMPlatformLink *nmtstp_link_ip6gre_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkIp6Tnl *lnk); +const NMPlatformLink *nmtstp_link_ipip_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkIpIp *lnk); +const NMPlatformLink *nmtstp_link_macvlan_add(NMPlatform * platform, + gboolean external_command, + const char * name, + int parent, + const NMPlatformLnkMacvlan *lnk); +const NMPlatformLink *nmtstp_link_sit_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkSit *lnk); +const NMPlatformLink *nmtstp_link_tun_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkTun *lnk, + int * out_fd); +const NMPlatformLink *nmtstp_link_vrf_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkVrf *lnk, + gboolean * out_not_supported); +const NMPlatformLink *nmtstp_link_vxlan_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkVxlan *lnk); + +void nmtstp_link_delete(NMPlatform *platform, + gboolean external_command, + int ifindex, + const char *name, + gboolean require_exist); /*****************************************************************************/ @@ -382,100 +499,112 @@ extern int NMTSTP_ENV1_IFINDEX; extern int NMTSTP_ENV1_EX; static inline void -_nmtstp_env1_wrapper_setup (const NmtstTestData *test_data) +_nmtstp_env1_wrapper_setup(const NmtstTestData *test_data) { - int *p_ifindex; - gpointer p_ifup; + int * p_ifindex; + gpointer p_ifup; - nmtst_test_data_unpack (test_data, &p_ifindex, NULL, NULL, NULL, &p_ifup); + nmtst_test_data_unpack(test_data, &p_ifindex, NULL, NULL, NULL, &p_ifup); - g_assert (p_ifindex && *p_ifindex == -1); + g_assert(p_ifindex && *p_ifindex == -1); - _LOGT ("TEST[%s]: setup", test_data->testpath); + _LOGT("TEST[%s]: setup", test_data->testpath); - nmtstp_link_delete (NM_PLATFORM_GET, -1, -1, DEVICE_NAME, FALSE); + nmtstp_link_delete(NM_PLATFORM_GET, -1, -1, DEVICE_NAME, FALSE); - g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_link_dummy_add (NM_PLATFORM_GET, DEVICE_NAME, NULL))); + g_assert(NMTST_NM_ERR_SUCCESS(nm_platform_link_dummy_add(NM_PLATFORM_GET, DEVICE_NAME, NULL))); - *p_ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); - g_assert_cmpint (*p_ifindex, >, 0); - g_assert_cmpint (NMTSTP_ENV1_IFINDEX, ==, -1); + *p_ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME); + g_assert_cmpint(*p_ifindex, >, 0); + g_assert_cmpint(NMTSTP_ENV1_IFINDEX, ==, -1); - if (GPOINTER_TO_INT (p_ifup)) - g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, *p_ifindex, NULL)); + if (GPOINTER_TO_INT(p_ifup)) + g_assert(nm_platform_link_set_up(NM_PLATFORM_GET, *p_ifindex, NULL)); - nm_platform_process_events (NM_PLATFORM_GET); + nm_platform_process_events(NM_PLATFORM_GET); - NMTSTP_ENV1_IFINDEX = *p_ifindex; - NMTSTP_ENV1_EX = nmtstp_run_command_check_external_global (); + NMTSTP_ENV1_IFINDEX = *p_ifindex; + NMTSTP_ENV1_EX = nmtstp_run_command_check_external_global(); } static inline void -_nmtstp_env1_wrapper_run (gconstpointer user_data) +_nmtstp_env1_wrapper_run(gconstpointer user_data) { - const NmtstTestData *test_data = user_data; - GTestDataFunc test_func_data; - GTestFunc test_func; - gconstpointer d; - - nmtst_test_data_unpack (test_data, NULL, &test_func, &test_func_data, &d, NULL); - - _LOGT ("TEST[%s]: run", test_data->testpath); - if (test_func) - test_func (); - else - test_func_data (d); + const NmtstTestData *test_data = user_data; + GTestDataFunc test_func_data; + GTestFunc test_func; + gconstpointer d; + + nmtst_test_data_unpack(test_data, NULL, &test_func, &test_func_data, &d, NULL); + + _LOGT("TEST[%s]: run", test_data->testpath); + if (test_func) + test_func(); + else + test_func_data(d); } static inline void -_nmtstp_env1_wrapper_teardown (const NmtstTestData *test_data) +_nmtstp_env1_wrapper_teardown(const NmtstTestData *test_data) { - int *p_ifindex; + int *p_ifindex; - nmtst_test_data_unpack (test_data, &p_ifindex, NULL, NULL, NULL, NULL); + nmtst_test_data_unpack(test_data, &p_ifindex, NULL, NULL, NULL, NULL); - g_assert_cmpint (NMTSTP_ENV1_IFINDEX, ==, *p_ifindex); - NMTSTP_ENV1_IFINDEX = -1; + g_assert_cmpint(NMTSTP_ENV1_IFINDEX, ==, *p_ifindex); + NMTSTP_ENV1_IFINDEX = -1; - _LOGT ("TEST[%s]: teardown", test_data->testpath); + _LOGT("TEST[%s]: teardown", test_data->testpath); - g_assert_cmpint (*p_ifindex, ==, nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME)); - g_assert (nm_platform_link_delete (NM_PLATFORM_GET, *p_ifindex)); + g_assert_cmpint(*p_ifindex, ==, nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME)); + g_assert(nm_platform_link_delete(NM_PLATFORM_GET, *p_ifindex)); - nm_platform_process_events (NM_PLATFORM_GET); + nm_platform_process_events(NM_PLATFORM_GET); - _LOGT ("TEST[%s]: finished", test_data->testpath); + _LOGT("TEST[%s]: finished", test_data->testpath); - *p_ifindex = -1; + *p_ifindex = -1; } /* add test function, that set's up a particular environment, consisting * of a dummy device with ifindex NMTSTP_ENV1_IFINDEX. */ #define _nmtstp_env1_add_test_func_full(testpath, test_func, test_data_func, arg, ifup) \ - nmtst_add_test_func_full (testpath, \ - _nmtstp_env1_wrapper_run, \ - _nmtstp_env1_wrapper_setup, \ - _nmtstp_env1_wrapper_teardown, \ - ({ static int _ifindex = -1; &_ifindex; }), \ - ({ GTestFunc _test_func = (test_func); _test_func; }), \ - ({ GTestDataFunc _test_func = (test_data_func); _test_func; }), \ - (arg), \ - ({ gboolean _ifup = (ifup); GINT_TO_POINTER (_ifup);})) + nmtst_add_test_func_full(testpath, \ + _nmtstp_env1_wrapper_run, \ + _nmtstp_env1_wrapper_setup, \ + _nmtstp_env1_wrapper_teardown, \ + ({ \ + static int _ifindex = -1; \ + &_ifindex; \ + }), \ + ({ \ + GTestFunc _test_func = (test_func); \ + _test_func; \ + }), \ + ({ \ + GTestDataFunc _test_func = (test_data_func); \ + _test_func; \ + }), \ + (arg), \ + ({ \ + gboolean _ifup = (ifup); \ + GINT_TO_POINTER(_ifup); \ + })) #define nmtstp_env1_add_test_func_data(testpath, test_func, arg, ifup) \ - _nmtstp_env1_add_test_func_full(testpath, NULL, test_func, arg, ifup) + _nmtstp_env1_add_test_func_full(testpath, NULL, test_func, arg, ifup) #define nmtstp_env1_add_test_func(testpath, test_func, ifup) \ - _nmtstp_env1_add_test_func_full(testpath, test_func, NULL, NULL, ifup) + _nmtstp_env1_add_test_func_full(testpath, test_func, NULL, NULL, ifup) /*****************************************************************************/ -typedef void (*NMTstpSetupFunc) (void); +typedef void (*NMTstpSetupFunc)(void); extern NMTstpSetupFunc const _nmtstp_setup_platform_func; -void nmtstp_setup_platform (void); +void nmtstp_setup_platform(void); /*****************************************************************************/ -void _nmtstp_init_tests (int *argc, char ***argv); -void _nmtstp_setup_tests (void); +void _nmtstp_init_tests(int *argc, char ***argv); +void _nmtstp_setup_tests(void); diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c index d7285c83..829abcc9 100644 --- a/src/platform/tests/test-link.c +++ b/src/platform/tests/test-link.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2016 Red Hat, Inc. */ @@ -19,3305 +19,3699 @@ #include "test-common.h" #include "nm-test-utils-core.h" -#define LO_INDEX 1 -#define LO_NAME "lo" +#define LO_INDEX 1 +#define LO_NAME "lo" #define LO_TYPEDESC "loopback" #define DUMMY_TYPEDESC "dummy" -#define BOGUS_NAME "nm-bogus-device" -#define BOGUS_IFINDEX INT_MAX -#define SLAVE_NAME "nm-test-slave" -#define PARENT_NAME "nm-test-parent" -#define VLAN_ID 4077 -#define VLAN_FLAGS 0 -#define MTU 1357 +#define BOGUS_NAME "nm-bogus-device" +#define BOGUS_IFINDEX INT_MAX +#define SLAVE_NAME "nm-test-slave" +#define PARENT_NAME "nm-test-parent" +#define VLAN_ID 4077 +#define VLAN_FLAGS 0 +#define MTU 1357 #define _ADD_DUMMY(platform, name) \ - g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_link_dummy_add ((platform), (name), NULL))) + g_assert(NMTST_NM_ERR_SUCCESS(nm_platform_link_dummy_add((platform), (name), NULL))) static void test_bogus(void) { - size_t addrlen; + size_t addrlen; - g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, BOGUS_NAME)); - g_assert (!nm_platform_link_delete (NM_PLATFORM_GET, BOGUS_IFINDEX)); - g_assert (!nm_platform_link_get_ifindex (NM_PLATFORM_GET, BOGUS_NAME)); - g_assert (!nm_platform_link_get_name (NM_PLATFORM_GET, BOGUS_IFINDEX)); - g_assert (!nm_platform_link_get_type (NM_PLATFORM_GET, BOGUS_IFINDEX)); - g_assert (!nm_platform_link_get_type_name (NM_PLATFORM_GET, BOGUS_IFINDEX)); + g_assert(!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, BOGUS_NAME)); + g_assert(!nm_platform_link_delete(NM_PLATFORM_GET, BOGUS_IFINDEX)); + g_assert(!nm_platform_link_get_ifindex(NM_PLATFORM_GET, BOGUS_NAME)); + g_assert(!nm_platform_link_get_name(NM_PLATFORM_GET, BOGUS_IFINDEX)); + g_assert(!nm_platform_link_get_type(NM_PLATFORM_GET, BOGUS_IFINDEX)); + g_assert(!nm_platform_link_get_type_name(NM_PLATFORM_GET, BOGUS_IFINDEX)); - g_assert (!nm_platform_link_set_up (NM_PLATFORM_GET, BOGUS_IFINDEX, NULL)); + g_assert(!nm_platform_link_set_up(NM_PLATFORM_GET, BOGUS_IFINDEX, NULL)); - g_assert (!nm_platform_link_set_down (NM_PLATFORM_GET, BOGUS_IFINDEX)); + g_assert(!nm_platform_link_set_down(NM_PLATFORM_GET, BOGUS_IFINDEX)); - g_assert (!nm_platform_link_set_arp (NM_PLATFORM_GET, BOGUS_IFINDEX)); + g_assert(!nm_platform_link_set_arp(NM_PLATFORM_GET, BOGUS_IFINDEX)); - g_assert (!nm_platform_link_set_noarp (NM_PLATFORM_GET, BOGUS_IFINDEX)); + g_assert(!nm_platform_link_set_noarp(NM_PLATFORM_GET, BOGUS_IFINDEX)); - g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, BOGUS_IFINDEX)); - g_assert (!nm_platform_link_is_connected (NM_PLATFORM_GET, BOGUS_IFINDEX)); - g_assert (!nm_platform_link_uses_arp (NM_PLATFORM_GET, BOGUS_IFINDEX)); + g_assert(!nm_platform_link_is_up(NM_PLATFORM_GET, BOGUS_IFINDEX)); + g_assert(!nm_platform_link_is_connected(NM_PLATFORM_GET, BOGUS_IFINDEX)); + g_assert(!nm_platform_link_uses_arp(NM_PLATFORM_GET, BOGUS_IFINDEX)); - g_assert (!nm_platform_link_get_address (NM_PLATFORM_GET, BOGUS_IFINDEX, &addrlen)); - g_assert (!addrlen); - g_assert (!nm_platform_link_get_address (NM_PLATFORM_GET, BOGUS_IFINDEX, NULL)); + g_assert(!nm_platform_link_get_address(NM_PLATFORM_GET, BOGUS_IFINDEX, &addrlen)); + g_assert(!addrlen); + g_assert(!nm_platform_link_get_address(NM_PLATFORM_GET, BOGUS_IFINDEX, NULL)); - g_assert (!NMTST_NM_ERR_SUCCESS (nm_platform_link_set_mtu (NM_PLATFORM_GET, BOGUS_IFINDEX, MTU))); + g_assert(!NMTST_NM_ERR_SUCCESS(nm_platform_link_set_mtu(NM_PLATFORM_GET, BOGUS_IFINDEX, MTU))); - g_assert (!nm_platform_link_get_mtu (NM_PLATFORM_GET, BOGUS_IFINDEX)); + g_assert(!nm_platform_link_get_mtu(NM_PLATFORM_GET, BOGUS_IFINDEX)); - g_assert (!nm_platform_link_supports_carrier_detect (NM_PLATFORM_GET, BOGUS_IFINDEX)); - g_assert (!nm_platform_link_supports_vlans (NM_PLATFORM_GET, BOGUS_IFINDEX)); + g_assert(!nm_platform_link_supports_carrier_detect(NM_PLATFORM_GET, BOGUS_IFINDEX)); + g_assert(!nm_platform_link_supports_vlans(NM_PLATFORM_GET, BOGUS_IFINDEX)); - g_assert (!nm_platform_link_get_lnk_vlan (NM_PLATFORM_GET, BOGUS_IFINDEX, NULL)); - g_assert (!nm_platform_link_vlan_set_ingress_map (NM_PLATFORM_GET, BOGUS_IFINDEX, 0, 0)); - g_assert (!nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, BOGUS_IFINDEX, 0, 0)); + g_assert(!nm_platform_link_get_lnk_vlan(NM_PLATFORM_GET, BOGUS_IFINDEX, NULL)); + g_assert(!nm_platform_link_vlan_set_ingress_map(NM_PLATFORM_GET, BOGUS_IFINDEX, 0, 0)); + g_assert(!nm_platform_link_vlan_set_egress_map(NM_PLATFORM_GET, BOGUS_IFINDEX, 0, 0)); } static void -test_loopback (void) +test_loopback(void) { - g_assert (nm_platform_link_get_by_ifname (NM_PLATFORM_GET, LO_NAME)); - g_assert_cmpint (nm_platform_link_get_type (NM_PLATFORM_GET, LO_INDEX), ==, NM_LINK_TYPE_LOOPBACK); - g_assert_cmpint (nm_platform_link_get_ifindex (NM_PLATFORM_GET, LO_NAME), ==, LO_INDEX); - g_assert_cmpstr (nm_platform_link_get_name (NM_PLATFORM_GET, LO_INDEX), ==, LO_NAME); - g_assert_cmpstr (nm_platform_link_get_type_name (NM_PLATFORM_GET, LO_INDEX), ==, LO_TYPEDESC); - - g_assert (nm_platform_link_supports_carrier_detect (NM_PLATFORM_GET, LO_INDEX)); - g_assert (!nm_platform_link_supports_vlans (NM_PLATFORM_GET, LO_INDEX)); + g_assert(nm_platform_link_get_by_ifname(NM_PLATFORM_GET, LO_NAME)); + g_assert_cmpint(nm_platform_link_get_type(NM_PLATFORM_GET, LO_INDEX), + ==, + NM_LINK_TYPE_LOOPBACK); + g_assert_cmpint(nm_platform_link_get_ifindex(NM_PLATFORM_GET, LO_NAME), ==, LO_INDEX); + g_assert_cmpstr(nm_platform_link_get_name(NM_PLATFORM_GET, LO_INDEX), ==, LO_NAME); + g_assert_cmpstr(nm_platform_link_get_type_name(NM_PLATFORM_GET, LO_INDEX), ==, LO_TYPEDESC); + + g_assert(nm_platform_link_supports_carrier_detect(NM_PLATFORM_GET, LO_INDEX)); + g_assert(!nm_platform_link_supports_vlans(NM_PLATFORM_GET, LO_INDEX)); } static gboolean -software_add (NMLinkType link_type, const char *name) +software_add(NMLinkType link_type, const char *name) { - switch (link_type) { - case NM_LINK_TYPE_DUMMY: - return NMTST_NM_ERR_SUCCESS (nm_platform_link_dummy_add (NM_PLATFORM_GET, name, NULL)); - case NM_LINK_TYPE_BRIDGE: - return NMTST_NM_ERR_SUCCESS (nm_platform_link_bridge_add (NM_PLATFORM_GET, name, NULL, 0, NULL)); - case NM_LINK_TYPE_BOND: - { - gboolean bond0_exists = !!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "bond0"); - int r; - - r = nm_platform_link_bond_add (NM_PLATFORM_GET, name, NULL); - - /* Check that bond0 is *not* automatically created. */ - if (!bond0_exists) - g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "bond0")); - return r >= 0; - } - case NM_LINK_TYPE_TEAM: - return NMTST_NM_ERR_SUCCESS (nm_platform_link_team_add (NM_PLATFORM_GET, name, NULL)); - case NM_LINK_TYPE_VLAN: { - SignalData *parent_added; - SignalData *parent_changed; - - /* Don't call link_callback for the bridge interface */ - parent_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, PARENT_NAME); - if (NMTST_NM_ERR_SUCCESS (nm_platform_link_bridge_add (NM_PLATFORM_GET, PARENT_NAME, NULL, 0, NULL))) - accept_signal (parent_added); - free_signal (parent_added); - - { - int parent_ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, PARENT_NAME); - gboolean was_up = nm_platform_link_is_up (NM_PLATFORM_GET, parent_ifindex); - - parent_changed = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, link_callback, parent_ifindex); - g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, parent_ifindex, NULL)); - if (was_up) { - /* when NM is running in the background, it will mess with addrgenmode which might cause additional signals. */ - accept_signals (parent_changed, 0, 1); - } else - accept_signals (parent_changed, 1, 2); - free_signal (parent_changed); - - return NMTST_NM_ERR_SUCCESS (nm_platform_link_vlan_add (NM_PLATFORM_GET, name, parent_ifindex, VLAN_ID, 0, NULL)); - } - } - default: - g_error ("Link type %d unhandled.", link_type); - } - g_assert_not_reached (); + switch (link_type) { + case NM_LINK_TYPE_DUMMY: + return NMTST_NM_ERR_SUCCESS(nm_platform_link_dummy_add(NM_PLATFORM_GET, name, NULL)); + case NM_LINK_TYPE_BRIDGE: + return NMTST_NM_ERR_SUCCESS(nm_platform_link_bridge_add(NM_PLATFORM_GET, + name, + NULL, + 0, + &nm_platform_lnk_bridge_default, + NULL)); + case NM_LINK_TYPE_BOND: + { + gboolean bond0_exists = !!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, "bond0"); + int r; + + r = nm_platform_link_bond_add(NM_PLATFORM_GET, name, NULL); + + /* Check that bond0 is *not* automatically created. */ + if (!bond0_exists) + g_assert(!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, "bond0")); + return r >= 0; + } + case NM_LINK_TYPE_TEAM: + return NMTST_NM_ERR_SUCCESS(nm_platform_link_team_add(NM_PLATFORM_GET, name, NULL)); + case NM_LINK_TYPE_VLAN: + { + SignalData *parent_added; + SignalData *parent_changed; + + /* Don't call link_callback for the bridge interface */ + parent_added = add_signal_ifname(NM_PLATFORM_SIGNAL_LINK_CHANGED, + NM_PLATFORM_SIGNAL_ADDED, + link_callback, + PARENT_NAME); + if (NMTST_NM_ERR_SUCCESS(nm_platform_link_bridge_add(NM_PLATFORM_GET, + PARENT_NAME, + NULL, + 0, + &nm_platform_lnk_bridge_default, + NULL))) + accept_signal(parent_added); + free_signal(parent_added); + + { + int parent_ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, PARENT_NAME); + gboolean was_up = nm_platform_link_is_up(NM_PLATFORM_GET, parent_ifindex); + + parent_changed = add_signal_ifindex(NM_PLATFORM_SIGNAL_LINK_CHANGED, + NM_PLATFORM_SIGNAL_CHANGED, + link_callback, + parent_ifindex); + g_assert(nm_platform_link_set_up(NM_PLATFORM_GET, parent_ifindex, NULL)); + if (was_up) { + /* when NM is running in the background, it will mess with addrgenmode which might cause additional signals. */ + accept_signals(parent_changed, 0, 1); + } else + accept_signals(parent_changed, 1, 2); + free_signal(parent_changed); + + return NMTST_NM_ERR_SUCCESS( + nm_platform_link_vlan_add(NM_PLATFORM_GET, name, parent_ifindex, VLAN_ID, 0, NULL)); + } + } + default: + g_error("Link type %d unhandled.", link_type); + } + g_assert_not_reached(); } static void -test_link_changed_signal_cb (NMPlatform *platform, - int obj_type_i, - int ifindex, - const NMPlatformIP4Route *route, - int change_type_i, - gboolean *p_test_link_changed_signal_arg) +test_link_changed_signal_cb(NMPlatform * platform, + int obj_type_i, + int ifindex, + const NMPlatformIP4Route *route, + int change_type_i, + gboolean * p_test_link_changed_signal_arg) { - const NMPObjectType obj_type = obj_type_i; - const NMPlatformSignalChangeType change_type = change_type_i; - - /* test invocation of platform signals with multiple listeners - * connected to the signal. Platform signals have enum-typed - * arguments and there seem to be an issue with invoking such - * signals on s390x and ppc64 archs. - * https://bugzilla.redhat.com/show_bug.cgi?id=1260577 - * - * As the test shows, the failure is not reproducible for - * platform signals. - */ - g_assert (NM_IS_PLATFORM (platform)); - g_assert (platform == NM_PLATFORM_GET); - - g_assert (ifindex > 0); - g_assert (route); - - g_assert_cmpint (obj_type, ==, NMP_OBJECT_TYPE_LINK); - - g_assert_cmpint ((gint64) change_type, !=, (gint64) 0); - g_assert_cmpint (change_type, !=, NM_PLATFORM_SIGNAL_NONE); - - *p_test_link_changed_signal_arg = TRUE; + const NMPObjectType obj_type = obj_type_i; + const NMPlatformSignalChangeType change_type = change_type_i; + + /* test invocation of platform signals with multiple listeners + * connected to the signal. Platform signals have enum-typed + * arguments and there seem to be an issue with invoking such + * signals on s390x and ppc64 archs. + * https://bugzilla.redhat.com/show_bug.cgi?id=1260577 + * + * As the test shows, the failure is not reproducible for + * platform signals. + */ + g_assert(NM_IS_PLATFORM(platform)); + g_assert(platform == NM_PLATFORM_GET); + + g_assert(ifindex > 0); + g_assert(route); + + g_assert_cmpint(obj_type, ==, NMP_OBJECT_TYPE_LINK); + + g_assert_cmpint((gint64) change_type, !=, (gint64) 0); + g_assert_cmpint(change_type, !=, NM_PLATFORM_SIGNAL_NONE); + + *p_test_link_changed_signal_arg = TRUE; } static void -test_slave (int master, int type, SignalData *master_changed) +test_slave(int master, int type, SignalData *master_changed) { - int ifindex; - SignalData *link_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, SLAVE_NAME); - SignalData *link_changed, *link_removed; - char *value; - NMLinkType link_type = nm_platform_link_get_type (NM_PLATFORM_GET, master); - gboolean test_link_changed_signal_arg1; - gboolean test_link_changed_signal_arg2; - - g_assert (NM_IN_SET (link_type, NM_LINK_TYPE_TEAM, NM_LINK_TYPE_BOND, NM_LINK_TYPE_BRIDGE)); - - g_assert (software_add (type, SLAVE_NAME)); - ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, SLAVE_NAME); - g_assert (ifindex > 0); - link_changed = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, link_callback, ifindex); - link_removed = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, link_callback, ifindex); - accept_signal (link_added); - - /* Set the slave up to see whether master's IFF_LOWER_UP is set correctly. - * - * See https://bugzilla.redhat.com/show_bug.cgi?id=910348 - */ - g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex)); - g_assert (nm_platform_link_set_down (NM_PLATFORM_GET, ifindex)); - g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex)); - ensure_no_signal (link_changed); - - /* Enslave */ - link_changed->ifindex = ifindex; - g_assert (nm_platform_link_enslave (NM_PLATFORM_GET, master, ifindex)); - g_assert_cmpint (nm_platform_link_get_master (NM_PLATFORM_GET, ifindex), ==, master); - - accept_signals (link_changed, 1, 3); - accept_signals (master_changed, 0, 2); - - /* enslaveing brings put the slave */ - if (NM_IN_SET (link_type, NM_LINK_TYPE_BOND, NM_LINK_TYPE_TEAM)) - g_assert (nm_platform_link_is_up (NM_PLATFORM_GET, ifindex)); - else - g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex)); - - test_link_changed_signal_arg1 = FALSE; - test_link_changed_signal_arg2 = FALSE; - g_signal_connect (NM_PLATFORM_GET, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK (test_link_changed_signal_cb), &test_link_changed_signal_arg1); - g_signal_connect (NM_PLATFORM_GET, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK (test_link_changed_signal_cb), &test_link_changed_signal_arg2); - - /* Set master up */ - g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, master, NULL)); - g_assert (nm_platform_link_is_up (NM_PLATFORM_GET, master)); - accept_signals (master_changed, 1, 3); - - g_signal_handlers_disconnect_by_func (NM_PLATFORM_GET, G_CALLBACK (test_link_changed_signal_cb), &test_link_changed_signal_arg1); - g_signal_handlers_disconnect_by_func (NM_PLATFORM_GET, G_CALLBACK (test_link_changed_signal_cb), &test_link_changed_signal_arg2); - g_assert (test_link_changed_signal_arg1); - g_assert (test_link_changed_signal_arg2); - - /* Master with a disconnected slave is disconnected - * - * For some reason, bonding and teaming slaves are automatically set up. We - * need to set them back down for this test. - */ - switch (nm_platform_link_get_type (NM_PLATFORM_GET, master)) { - case NM_LINK_TYPE_BOND: - case NM_LINK_TYPE_TEAM: - g_assert (nm_platform_link_set_down (NM_PLATFORM_GET, ifindex)); - accept_signal (link_changed); - accept_signals (master_changed, 0, 3); - break; - default: - break; - } - g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex)); - g_assert (!nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex)); - if ( nmtstp_is_root_test () - && nm_platform_link_is_connected (NM_PLATFORM_GET, master)) { - if (nm_platform_link_get_type (NM_PLATFORM_GET, master) == NM_LINK_TYPE_TEAM) { - /* Older team versions (e.g. Fedora 17) have a bug that team master stays - * IFF_LOWER_UP even if its slave is down. Double check it with iproute2 and if - * `ip link` also claims master to be up, accept it. */ - char *stdout_str = NULL; - - nmtst_spawn_sync (NULL, &stdout_str, NULL, 0, "/sbin/ip", "link", "show", "dev", nm_platform_link_get_name (NM_PLATFORM_GET, master)); - - g_assert (strstr (stdout_str, "LOWER_UP")); - g_free (stdout_str); - } else - g_assert_not_reached (); - } - - /* Set slave up and see if master gets up too */ - g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, ifindex, NULL)); - g_assert (nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex)); - g_assert (nm_platform_link_is_connected (NM_PLATFORM_GET, master)); - accept_signals (link_changed, 1, 3); - /* NM running, can cause additional change of addrgenmode */ - accept_signals (master_changed, 0, 3); - - /* Enslave again - * - * Gracefully succeed if already enslaved. - */ - ensure_no_signal (link_changed); - g_assert (nm_platform_link_enslave (NM_PLATFORM_GET, master, ifindex)); - accept_signals (link_changed, 0, 2); - accept_signals (master_changed, 0, 2); - - /* Set slave option */ - switch (type) { - case NM_LINK_TYPE_BRIDGE: - if (nmtstp_is_sysfs_writable ()) { - g_assert (nm_platform_sysctl_slave_set_option (NM_PLATFORM_GET, ifindex, "priority", "614")); - value = nm_platform_sysctl_slave_get_option (NM_PLATFORM_GET, ifindex, "priority"); - g_assert_cmpstr (value, ==, "614"); - g_free (value); - } - break; - default: - break; - } - - /* Release */ - ensure_no_signal (link_added); - ensure_no_signal (link_changed); - ensure_no_signal (link_removed); - g_assert (nm_platform_link_release (NM_PLATFORM_GET, master, ifindex)); - g_assert_cmpint (nm_platform_link_get_master (NM_PLATFORM_GET, ifindex), ==, 0); - if (link_changed->received_count > 0) { - accept_signals (link_added, 0, 1); - accept_signals (link_changed, 1, 5); - accept_signals (link_removed, 0, 1); - } else { - /* Due to https://bugzilla.redhat.com/show_bug.cgi?id=1285719 , kernel might send a - * wrong RTM_DELLINK message so that we instead see an removed+added signal. */ - accept_signal (link_added); - ensure_no_signal (link_changed); - accept_signal (link_removed); - } - accept_signals (master_changed, 0, 3); - - ensure_no_signal (master_changed); - - /* Release again */ - ensure_no_signal (link_changed); - g_assert (!nm_platform_link_release (NM_PLATFORM_GET, master, ifindex)); - - ensure_no_signal (master_changed); - - /* Remove */ - ensure_no_signal (link_added); - ensure_no_signal (link_changed); - ensure_no_signal (link_removed); - nmtstp_link_delete (NULL, -1, ifindex, NULL, TRUE); - accept_signals (master_changed, 0, 1); - accept_signals (link_changed, 0, 1); - accept_signal (link_removed); - - free_signal (link_added); - free_signal (link_changed); - free_signal (link_removed); + int ifindex; + SignalData *link_added = add_signal_ifname(NM_PLATFORM_SIGNAL_LINK_CHANGED, + NM_PLATFORM_SIGNAL_ADDED, + link_callback, + SLAVE_NAME); + SignalData *link_changed, *link_removed; + char * value; + NMLinkType link_type = nm_platform_link_get_type(NM_PLATFORM_GET, master); + gboolean test_link_changed_signal_arg1; + gboolean test_link_changed_signal_arg2; + + g_assert(NM_IN_SET(link_type, NM_LINK_TYPE_TEAM, NM_LINK_TYPE_BOND, NM_LINK_TYPE_BRIDGE)); + + g_assert(software_add(type, SLAVE_NAME)); + ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, SLAVE_NAME); + g_assert(ifindex > 0); + link_changed = add_signal_ifindex(NM_PLATFORM_SIGNAL_LINK_CHANGED, + NM_PLATFORM_SIGNAL_CHANGED, + link_callback, + ifindex); + link_removed = add_signal_ifindex(NM_PLATFORM_SIGNAL_LINK_CHANGED, + NM_PLATFORM_SIGNAL_REMOVED, + link_callback, + ifindex); + accept_signal(link_added); + + /* Set the slave up to see whether master's IFF_LOWER_UP is set correctly. + * + * See https://bugzilla.redhat.com/show_bug.cgi?id=910348 + */ + g_assert(!nm_platform_link_is_up(NM_PLATFORM_GET, ifindex)); + g_assert(nm_platform_link_set_down(NM_PLATFORM_GET, ifindex)); + g_assert(!nm_platform_link_is_up(NM_PLATFORM_GET, ifindex)); + ensure_no_signal(link_changed); + + /* Enslave */ + link_changed->ifindex = ifindex; + g_assert(nm_platform_link_enslave(NM_PLATFORM_GET, master, ifindex)); + g_assert_cmpint(nm_platform_link_get_master(NM_PLATFORM_GET, ifindex), ==, master); + + accept_signals(link_changed, 1, 3); + accept_signals(master_changed, 0, 2); + + /* enslaveing brings put the slave */ + if (NM_IN_SET(link_type, NM_LINK_TYPE_BOND, NM_LINK_TYPE_TEAM)) + g_assert(nm_platform_link_is_up(NM_PLATFORM_GET, ifindex)); + else + g_assert(!nm_platform_link_is_up(NM_PLATFORM_GET, ifindex)); + + test_link_changed_signal_arg1 = FALSE; + test_link_changed_signal_arg2 = FALSE; + g_signal_connect(NM_PLATFORM_GET, + NM_PLATFORM_SIGNAL_LINK_CHANGED, + G_CALLBACK(test_link_changed_signal_cb), + &test_link_changed_signal_arg1); + g_signal_connect(NM_PLATFORM_GET, + NM_PLATFORM_SIGNAL_LINK_CHANGED, + G_CALLBACK(test_link_changed_signal_cb), + &test_link_changed_signal_arg2); + + /* Set master up */ + g_assert(nm_platform_link_set_up(NM_PLATFORM_GET, master, NULL)); + g_assert(nm_platform_link_is_up(NM_PLATFORM_GET, master)); + accept_signals(master_changed, 1, 3); + + g_signal_handlers_disconnect_by_func(NM_PLATFORM_GET, + G_CALLBACK(test_link_changed_signal_cb), + &test_link_changed_signal_arg1); + g_signal_handlers_disconnect_by_func(NM_PLATFORM_GET, + G_CALLBACK(test_link_changed_signal_cb), + &test_link_changed_signal_arg2); + g_assert(test_link_changed_signal_arg1); + g_assert(test_link_changed_signal_arg2); + + /* Master with a disconnected slave is disconnected + * + * For some reason, bonding and teaming slaves are automatically set up. We + * need to set them back down for this test. + */ + switch (nm_platform_link_get_type(NM_PLATFORM_GET, master)) { + case NM_LINK_TYPE_BOND: + case NM_LINK_TYPE_TEAM: + g_assert(nm_platform_link_set_down(NM_PLATFORM_GET, ifindex)); + accept_signal(link_changed); + accept_signals(master_changed, 0, 3); + break; + default: + break; + } + g_assert(!nm_platform_link_is_up(NM_PLATFORM_GET, ifindex)); + g_assert(!nm_platform_link_is_connected(NM_PLATFORM_GET, ifindex)); + if (nmtstp_is_root_test() && nm_platform_link_is_connected(NM_PLATFORM_GET, master)) { + if (nm_platform_link_get_type(NM_PLATFORM_GET, master) == NM_LINK_TYPE_TEAM) { + /* Older team versions (e.g. Fedora 17) have a bug that team master stays + * IFF_LOWER_UP even if its slave is down. Double check it with iproute2 and if + * `ip link` also claims master to be up, accept it. */ + char *stdout_str = NULL; + + nmtst_spawn_sync(NULL, + &stdout_str, + NULL, + 0, + "/sbin/ip", + "link", + "show", + "dev", + nm_platform_link_get_name(NM_PLATFORM_GET, master)); + + g_assert(strstr(stdout_str, "LOWER_UP")); + g_free(stdout_str); + } else + g_assert_not_reached(); + } + + /* Set slave up and see if master gets up too */ + g_assert(nm_platform_link_set_up(NM_PLATFORM_GET, ifindex, NULL)); + g_assert(nm_platform_link_is_connected(NM_PLATFORM_GET, ifindex)); + g_assert(nm_platform_link_is_connected(NM_PLATFORM_GET, master)); + accept_signals(link_changed, 1, 3); + /* NM running, can cause additional change of addrgenmode */ + accept_signals(master_changed, 0, 3); + + /* Enslave again + * + * Gracefully succeed if already enslaved. + */ + ensure_no_signal(link_changed); + g_assert(nm_platform_link_enslave(NM_PLATFORM_GET, master, ifindex)); + accept_signals(link_changed, 0, 2); + accept_signals(master_changed, 0, 2); + + /* Set slave option */ + switch (type) { + case NM_LINK_TYPE_BRIDGE: + if (nmtstp_is_sysfs_writable()) { + g_assert( + nm_platform_sysctl_slave_set_option(NM_PLATFORM_GET, ifindex, "priority", "614")); + value = nm_platform_sysctl_slave_get_option(NM_PLATFORM_GET, ifindex, "priority"); + g_assert_cmpstr(value, ==, "614"); + g_free(value); + } + break; + default: + break; + } + + /* Release */ + ensure_no_signal(link_added); + ensure_no_signal(link_changed); + ensure_no_signal(link_removed); + g_assert(nm_platform_link_release(NM_PLATFORM_GET, master, ifindex)); + g_assert_cmpint(nm_platform_link_get_master(NM_PLATFORM_GET, ifindex), ==, 0); + if (link_changed->received_count > 0) { + accept_signals(link_added, 0, 1); + accept_signals(link_changed, 1, 5); + accept_signals(link_removed, 0, 1); + } else { + /* Due to https://bugzilla.redhat.com/show_bug.cgi?id=1285719 , kernel might send a + * wrong RTM_DELLINK message so that we instead see an removed+added signal. */ + accept_signal(link_added); + ensure_no_signal(link_changed); + accept_signal(link_removed); + } + accept_signals(master_changed, 0, 3); + + ensure_no_signal(master_changed); + + /* Release again */ + ensure_no_signal(link_changed); + g_assert(!nm_platform_link_release(NM_PLATFORM_GET, master, ifindex)); + + ensure_no_signal(master_changed); + + /* Remove */ + ensure_no_signal(link_added); + ensure_no_signal(link_changed); + ensure_no_signal(link_removed); + nmtstp_link_delete(NULL, -1, ifindex, NULL, TRUE); + accept_signals(master_changed, 0, 1); + accept_signals(link_changed, 0, 1); + accept_signal(link_removed); + + free_signal(link_added); + free_signal(link_changed); + free_signal(link_removed); } static void -test_software (NMLinkType link_type, const char *link_typename) +test_software(NMLinkType link_type, const char *link_typename) { - int ifindex; - char *value; - int vlan_parent = -1, vlan_id; - - SignalData *link_added, *link_changed, *link_removed; - - /* Add */ - link_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, DEVICE_NAME); - g_assert (software_add (link_type, DEVICE_NAME)); - accept_signal (link_added); - g_assert (nm_platform_link_get_by_ifname (NM_PLATFORM_GET, DEVICE_NAME)); - ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); - g_assert (ifindex >= 0); - g_assert_cmpint (nm_platform_link_get_type (NM_PLATFORM_GET, ifindex), ==, link_type); - g_assert_cmpstr (nm_platform_link_get_type_name (NM_PLATFORM_GET, ifindex), ==, link_typename); - link_changed = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, link_callback, ifindex); - link_removed = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, link_callback, ifindex); - if (link_type == NM_LINK_TYPE_VLAN) { - const NMPlatformLink *plink; - const NMPlatformLnkVlan *plnk; - - plnk = nm_platform_link_get_lnk_vlan (NM_PLATFORM_GET, ifindex, &plink); - g_assert (plnk); - g_assert (plink); - - vlan_parent = plink->parent; - vlan_id = plnk->id; - g_assert_cmpint (vlan_parent, ==, nm_platform_link_get_ifindex (NM_PLATFORM_GET, PARENT_NAME)); - g_assert_cmpint (vlan_id, ==, VLAN_ID); - } - - /* Add again */ - g_assert (!software_add (link_type, DEVICE_NAME)); - - /* Set ARP/NOARP */ - g_assert (nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex)); - g_assert (nm_platform_link_set_noarp (NM_PLATFORM_GET, ifindex)); - g_assert (!nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex)); - accept_signals (link_changed, 1, 2); - g_assert (nm_platform_link_set_arp (NM_PLATFORM_GET, ifindex)); - g_assert (nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex)); - accept_signal (link_changed); - - /* Set master option */ - if (nmtstp_is_root_test ()) { - switch (link_type) { - case NM_LINK_TYPE_BRIDGE: - if (nmtstp_is_sysfs_writable ()) { - g_assert (nm_platform_sysctl_master_set_option (NM_PLATFORM_GET, ifindex, "forward_delay", "628")); - value = nm_platform_sysctl_master_get_option (NM_PLATFORM_GET, ifindex, "forward_delay"); - g_assert_cmpstr (value, ==, "628"); - g_free (value); - } - break; - case NM_LINK_TYPE_BOND: - if (nmtstp_is_sysfs_writable ()) { - g_assert (nm_platform_sysctl_master_set_option (NM_PLATFORM_GET, ifindex, "mode", "active-backup")); - value = nm_platform_sysctl_master_get_option (NM_PLATFORM_GET, ifindex, "mode"); - /* When reading back, the output looks slightly different. */ - g_assert (g_str_has_prefix (value, "active-backup")); - g_free (value); - } - break; - default: - break; - } - } - - /* Enslave and release */ - switch (link_type) { - case NM_LINK_TYPE_BRIDGE: - case NM_LINK_TYPE_BOND: - case NM_LINK_TYPE_TEAM: - link_changed->ifindex = ifindex; - test_slave (ifindex, NM_LINK_TYPE_DUMMY, link_changed); - link_changed->ifindex = 0; - break; - default: - break; - } - free_signal (link_changed); - - /* Delete */ - nmtstp_link_delete (NULL, -1, ifindex, DEVICE_NAME, TRUE); - accept_signal (link_removed); - - /* Delete again */ - g_assert (nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME) <= 0); - g_assert (!nm_platform_link_delete (NM_PLATFORM_GET, ifindex)); - - /* VLAN: Delete parent */ - if (link_type == NM_LINK_TYPE_VLAN) { - SignalData *link_removed_parent = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, link_callback, vlan_parent); - - nmtstp_link_delete (NULL, -1, vlan_parent, NULL, TRUE); - accept_signal (link_removed_parent); - free_signal (link_removed_parent); - } - - /* No pending signal */ - free_signal (link_added); - free_signal (link_removed); + int ifindex; + char *value; + int vlan_parent = -1, vlan_id; + + SignalData *link_added, *link_changed, *link_removed; + + /* Add */ + link_added = add_signal_ifname(NM_PLATFORM_SIGNAL_LINK_CHANGED, + NM_PLATFORM_SIGNAL_ADDED, + link_callback, + DEVICE_NAME); + g_assert(software_add(link_type, DEVICE_NAME)); + accept_signal(link_added); + g_assert(nm_platform_link_get_by_ifname(NM_PLATFORM_GET, DEVICE_NAME)); + ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME); + g_assert(ifindex >= 0); + g_assert_cmpint(nm_platform_link_get_type(NM_PLATFORM_GET, ifindex), ==, link_type); + g_assert_cmpstr(nm_platform_link_get_type_name(NM_PLATFORM_GET, ifindex), ==, link_typename); + link_changed = add_signal_ifindex(NM_PLATFORM_SIGNAL_LINK_CHANGED, + NM_PLATFORM_SIGNAL_CHANGED, + link_callback, + ifindex); + link_removed = add_signal_ifindex(NM_PLATFORM_SIGNAL_LINK_CHANGED, + NM_PLATFORM_SIGNAL_REMOVED, + link_callback, + ifindex); + if (link_type == NM_LINK_TYPE_VLAN) { + const NMPlatformLink * plink; + const NMPlatformLnkVlan *plnk; + + plnk = nm_platform_link_get_lnk_vlan(NM_PLATFORM_GET, ifindex, &plink); + g_assert(plnk); + g_assert(plink); + + vlan_parent = plink->parent; + vlan_id = plnk->id; + g_assert_cmpint(vlan_parent, + ==, + nm_platform_link_get_ifindex(NM_PLATFORM_GET, PARENT_NAME)); + g_assert_cmpint(vlan_id, ==, VLAN_ID); + } + + /* Add again */ + g_assert(!software_add(link_type, DEVICE_NAME)); + + /* Set ARP/NOARP */ + g_assert(nm_platform_link_uses_arp(NM_PLATFORM_GET, ifindex)); + g_assert(nm_platform_link_set_noarp(NM_PLATFORM_GET, ifindex)); + g_assert(!nm_platform_link_uses_arp(NM_PLATFORM_GET, ifindex)); + accept_signals(link_changed, 1, 2); + g_assert(nm_platform_link_set_arp(NM_PLATFORM_GET, ifindex)); + g_assert(nm_platform_link_uses_arp(NM_PLATFORM_GET, ifindex)); + accept_signal(link_changed); + + /* Set master option */ + if (nmtstp_is_root_test()) { + switch (link_type) { + case NM_LINK_TYPE_BRIDGE: + if (nmtstp_is_sysfs_writable()) { + g_assert(nm_platform_sysctl_master_set_option(NM_PLATFORM_GET, + ifindex, + "forward_delay", + "628")); + value = + nm_platform_sysctl_master_get_option(NM_PLATFORM_GET, ifindex, "forward_delay"); + g_assert_cmpstr(value, ==, "628"); + g_free(value); + } + break; + case NM_LINK_TYPE_BOND: + if (nmtstp_is_sysfs_writable()) { + g_assert(nm_platform_sysctl_master_set_option(NM_PLATFORM_GET, + ifindex, + "mode", + "active-backup")); + value = nm_platform_sysctl_master_get_option(NM_PLATFORM_GET, ifindex, "mode"); + /* When reading back, the output looks slightly different. */ + g_assert(g_str_has_prefix(value, "active-backup")); + g_free(value); + } + break; + default: + break; + } + } + + /* Enslave and release */ + switch (link_type) { + case NM_LINK_TYPE_BRIDGE: + case NM_LINK_TYPE_BOND: + case NM_LINK_TYPE_TEAM: + link_changed->ifindex = ifindex; + test_slave(ifindex, NM_LINK_TYPE_DUMMY, link_changed); + link_changed->ifindex = 0; + break; + default: + break; + } + free_signal(link_changed); + + /* Delete */ + nmtstp_link_delete(NULL, -1, ifindex, DEVICE_NAME, TRUE); + accept_signal(link_removed); + + /* Delete again */ + g_assert(nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME) <= 0); + g_assert(!nm_platform_link_delete(NM_PLATFORM_GET, ifindex)); + + /* VLAN: Delete parent */ + if (link_type == NM_LINK_TYPE_VLAN) { + SignalData *link_removed_parent = add_signal_ifindex(NM_PLATFORM_SIGNAL_LINK_CHANGED, + NM_PLATFORM_SIGNAL_REMOVED, + link_callback, + vlan_parent); + + nmtstp_link_delete(NULL, -1, vlan_parent, NULL, TRUE); + accept_signal(link_removed_parent); + free_signal(link_removed_parent); + } + + /* No pending signal */ + free_signal(link_added); + free_signal(link_removed); } static void -test_bridge (void) +test_bridge(void) { - test_software (NM_LINK_TYPE_BRIDGE, "bridge"); + test_software(NM_LINK_TYPE_BRIDGE, "bridge"); } static int -_system (const char *cmd) +_system(const char *cmd) { - /* some gcc version really want to warn on -Werror=unused-result. Add a bogus wrapper - * function. */ - return system (cmd); + /* some gcc version really want to warn on -Werror=unused-result. Add a bogus wrapper + * function. */ + return system(cmd); } static void -test_bond (void) +test_bond(void) { - if ( nmtstp_is_root_test () - && !g_file_test ("/proc/1/net/bonding", G_FILE_TEST_IS_DIR) - && _system("modprobe --show bonding") != 0) { - g_test_skip ("Skipping test for bonding: bonding module not available"); - return; - } - - test_software (NM_LINK_TYPE_BOND, "bond"); + if (nmtstp_is_root_test() && !g_file_test("/proc/1/net/bonding", G_FILE_TEST_IS_DIR) + && _system("modprobe --show bonding") != 0) { + g_test_skip("Skipping test for bonding: bonding module not available"); + return; + } + + test_software(NM_LINK_TYPE_BOND, "bond"); } static void -test_team (void) +test_team(void) { - int r; + int r; - if (nmtstp_is_root_test ()) { - r = nm_platform_link_team_add (NM_PLATFORM_GET, "nm-team-check", NULL); + if (nmtstp_is_root_test()) { + r = nm_platform_link_team_add(NM_PLATFORM_GET, "nm-team-check", NULL); - if (r < 0) { - g_assert_cmpint (r, ==, -EOPNOTSUPP); - g_test_skip ("Skipping test for teaming: team module not functioning"); - return; - } + if (r < 0) { + g_assert_cmpint(r, ==, -EOPNOTSUPP); + g_test_skip("Skipping test for teaming: team module not functioning"); + return; + } - nmtstp_link_delete (NM_PLATFORM_GET, -1, -1, "nm-team-check", FALSE); - } + nmtstp_link_delete(NM_PLATFORM_GET, -1, -1, "nm-team-check", FALSE); + } - test_software (NM_LINK_TYPE_TEAM, "team"); + test_software(NM_LINK_TYPE_TEAM, "team"); } static void -test_vlan (void) +test_vlan(void) { - test_software (NM_LINK_TYPE_VLAN, "vlan"); + test_software(NM_LINK_TYPE_VLAN, "vlan"); } /*****************************************************************************/ static void -test_bridge_addr (void) +test_bridge_addr(void) { - char addr[ETH_ALEN]; - NMPlatformLink link; - const NMPlatformLink *plink = NULL; - - nm_utils_hwaddr_aton ("de:ad:be:ef:00:11", addr, sizeof (addr)); - - g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_link_bridge_add (NM_PLATFORM_GET, DEVICE_NAME, addr, sizeof (addr), &plink))); - g_assert (plink); - link = *plink; - g_assert_cmpstr (link.name, ==, DEVICE_NAME); - - g_assert_cmpint (link.l_address.len, ==, sizeof (addr)); - g_assert (!memcmp (link.l_address.data, addr, sizeof (addr))); - - plink = nm_platform_link_get (NM_PLATFORM_GET, link.ifindex); - g_assert (plink); - - if (nm_platform_kernel_support_get (NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL)) { - g_assert (!nm_platform_link_get_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex)); - g_assert_cmpint (_nm_platform_uint8_inv (plink->inet6_addr_gen_mode_inv), ==, NM_IN6_ADDR_GEN_MODE_EUI64); - - g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex, TRUE))); - g_assert (nm_platform_link_get_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex)); - plink = nm_platform_link_get (NM_PLATFORM_GET, link.ifindex); - g_assert (plink); - g_assert_cmpint (_nm_platform_uint8_inv (plink->inet6_addr_gen_mode_inv), ==, NM_IN6_ADDR_GEN_MODE_NONE); - - g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex, FALSE))); - g_assert (!nm_platform_link_get_user_ipv6ll_enabled (NM_PLATFORM_GET, link.ifindex)); - plink = nm_platform_link_get (NM_PLATFORM_GET, link.ifindex); - g_assert (plink); - g_assert_cmpint (_nm_platform_uint8_inv (plink->inet6_addr_gen_mode_inv), ==, NM_IN6_ADDR_GEN_MODE_EUI64); - } - - g_assert_cmpint (plink->l_address.len, ==, sizeof (addr)); - g_assert (!memcmp (plink->l_address.data, addr, sizeof (addr))); - - nmtstp_link_delete (NULL, -1, link.ifindex, link.name, TRUE); + char addr[ETH_ALEN]; + NMPlatformLink link; + const NMPlatformLink *plink = NULL; + + nm_utils_hwaddr_aton("de:ad:be:ef:00:11", addr, sizeof(addr)); + + g_assert(NMTST_NM_ERR_SUCCESS(nm_platform_link_bridge_add(NM_PLATFORM_GET, + DEVICE_NAME, + addr, + sizeof(addr), + &nm_platform_lnk_bridge_default, + &plink))); + g_assert(plink); + link = *plink; + g_assert_cmpstr(link.name, ==, DEVICE_NAME); + + g_assert_cmpint(link.l_address.len, ==, sizeof(addr)); + g_assert(!memcmp(link.l_address.data, addr, sizeof(addr))); + + plink = nm_platform_link_get(NM_PLATFORM_GET, link.ifindex); + g_assert(plink); + + if (nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL)) { + g_assert(!nm_platform_link_get_user_ipv6ll_enabled(NM_PLATFORM_GET, link.ifindex)); + g_assert_cmpint(_nm_platform_uint8_inv(plink->inet6_addr_gen_mode_inv), + ==, + NM_IN6_ADDR_GEN_MODE_EUI64); + + g_assert(NMTST_NM_ERR_SUCCESS( + nm_platform_link_set_user_ipv6ll_enabled(NM_PLATFORM_GET, link.ifindex, TRUE))); + g_assert(nm_platform_link_get_user_ipv6ll_enabled(NM_PLATFORM_GET, link.ifindex)); + plink = nm_platform_link_get(NM_PLATFORM_GET, link.ifindex); + g_assert(plink); + g_assert_cmpint(_nm_platform_uint8_inv(plink->inet6_addr_gen_mode_inv), + ==, + NM_IN6_ADDR_GEN_MODE_NONE); + + g_assert(NMTST_NM_ERR_SUCCESS( + nm_platform_link_set_user_ipv6ll_enabled(NM_PLATFORM_GET, link.ifindex, FALSE))); + g_assert(!nm_platform_link_get_user_ipv6ll_enabled(NM_PLATFORM_GET, link.ifindex)); + plink = nm_platform_link_get(NM_PLATFORM_GET, link.ifindex); + g_assert(plink); + g_assert_cmpint(_nm_platform_uint8_inv(plink->inet6_addr_gen_mode_inv), + ==, + NM_IN6_ADDR_GEN_MODE_EUI64); + } + + g_assert_cmpint(plink->l_address.len, ==, sizeof(addr)); + g_assert(!memcmp(plink->l_address.data, addr, sizeof(addr))); + + nmtstp_link_delete(NULL, -1, link.ifindex, link.name, TRUE); } /*****************************************************************************/ static void -test_internal (void) +test_internal(void) { - SignalData *link_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, DEVICE_NAME); - SignalData *link_changed, *link_removed; - const char mac[6] = { 0x00, 0xff, 0x11, 0xee, 0x22, 0xdd }; - const char *address; - size_t addrlen; - int ifindex; - - /* Check the functions for non-existent devices */ - g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, DEVICE_NAME)); - g_assert (!nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME)); - - /* Add device */ - g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_link_dummy_add (NM_PLATFORM_GET, DEVICE_NAME, NULL))); - accept_signal (link_added); - - /* Try to add again */ - g_assert (nm_platform_link_dummy_add (NM_PLATFORM_GET, DEVICE_NAME, NULL) == -NME_PL_EXISTS); - - /* Check device index, name and type */ - ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); - g_assert (ifindex > 0); - g_assert_cmpstr (nm_platform_link_get_name (NM_PLATFORM_GET, ifindex), ==, DEVICE_NAME); - g_assert_cmpint (nm_platform_link_get_type (NM_PLATFORM_GET, ifindex), ==, NM_LINK_TYPE_DUMMY); - g_assert_cmpstr (nm_platform_link_get_type_name (NM_PLATFORM_GET, ifindex), ==, DUMMY_TYPEDESC); - link_changed = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, link_callback, ifindex); - link_removed = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, link_callback, ifindex); - - /* Up/connected */ - g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex)); - g_assert (!nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex)); - g_assert (nm_platform_link_set_up (NM_PLATFORM_GET, ifindex, NULL)); - g_assert (nm_platform_link_is_up (NM_PLATFORM_GET, ifindex)); - g_assert (nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex)); - accept_signals (link_changed, 1, 2); - g_assert (nm_platform_link_set_down (NM_PLATFORM_GET, ifindex)); - g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex)); - g_assert (!nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex)); - accept_signal (link_changed); - - /* arp/noarp */ - g_assert (!nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex)); - g_assert (nm_platform_link_set_arp (NM_PLATFORM_GET, ifindex)); - g_assert (nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex)); - accept_signal (link_changed); - g_assert (nm_platform_link_set_noarp (NM_PLATFORM_GET, ifindex)); - g_assert (!nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex)); - accept_signal (link_changed); - - /* Features */ - g_assert (!nm_platform_link_supports_carrier_detect (NM_PLATFORM_GET, ifindex)); - g_assert (nm_platform_link_supports_vlans (NM_PLATFORM_GET, ifindex)); - - /* Set MAC address */ - g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_link_set_address (NM_PLATFORM_GET, ifindex, mac, sizeof (mac)))); - address = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, &addrlen); - g_assert (addrlen == sizeof(mac)); - g_assert (!memcmp (address, mac, addrlen)); - address = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, NULL); - g_assert (!memcmp (address, mac, addrlen)); - accept_signal (link_changed); - - /* Set MTU */ - g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_link_set_mtu (NM_PLATFORM_GET, ifindex, MTU))); - g_assert_cmpint (nm_platform_link_get_mtu (NM_PLATFORM_GET, ifindex), ==, MTU); - accept_signal (link_changed); - - /* Delete device */ - nmtstp_link_delete (NULL, -1, ifindex, DEVICE_NAME, TRUE); - accept_signal (link_removed); - - /* Try to delete again */ - g_assert (!nm_platform_link_delete (NM_PLATFORM_GET, ifindex)); - - free_signal (link_added); - free_signal (link_changed); - free_signal (link_removed); + SignalData *link_added = add_signal_ifname(NM_PLATFORM_SIGNAL_LINK_CHANGED, + NM_PLATFORM_SIGNAL_ADDED, + link_callback, + DEVICE_NAME); + SignalData *link_changed, *link_removed; + const char mac[6] = {0x00, 0xff, 0x11, 0xee, 0x22, 0xdd}; + const char *address; + size_t addrlen; + int ifindex; + + /* Check the functions for non-existent devices */ + g_assert(!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, DEVICE_NAME)); + g_assert(!nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME)); + + /* Add device */ + g_assert(NMTST_NM_ERR_SUCCESS(nm_platform_link_dummy_add(NM_PLATFORM_GET, DEVICE_NAME, NULL))); + accept_signal(link_added); + + /* Try to add again */ + g_assert(nm_platform_link_dummy_add(NM_PLATFORM_GET, DEVICE_NAME, NULL) == -NME_PL_EXISTS); + + /* Check device index, name and type */ + ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME); + g_assert(ifindex > 0); + g_assert_cmpstr(nm_platform_link_get_name(NM_PLATFORM_GET, ifindex), ==, DEVICE_NAME); + g_assert_cmpint(nm_platform_link_get_type(NM_PLATFORM_GET, ifindex), ==, NM_LINK_TYPE_DUMMY); + g_assert_cmpstr(nm_platform_link_get_type_name(NM_PLATFORM_GET, ifindex), ==, DUMMY_TYPEDESC); + link_changed = add_signal_ifindex(NM_PLATFORM_SIGNAL_LINK_CHANGED, + NM_PLATFORM_SIGNAL_CHANGED, + link_callback, + ifindex); + link_removed = add_signal_ifindex(NM_PLATFORM_SIGNAL_LINK_CHANGED, + NM_PLATFORM_SIGNAL_REMOVED, + link_callback, + ifindex); + + /* Up/connected */ + g_assert(!nm_platform_link_is_up(NM_PLATFORM_GET, ifindex)); + g_assert(!nm_platform_link_is_connected(NM_PLATFORM_GET, ifindex)); + g_assert(nm_platform_link_set_up(NM_PLATFORM_GET, ifindex, NULL)); + g_assert(nm_platform_link_is_up(NM_PLATFORM_GET, ifindex)); + g_assert(nm_platform_link_is_connected(NM_PLATFORM_GET, ifindex)); + accept_signals(link_changed, 1, 2); + g_assert(nm_platform_link_set_down(NM_PLATFORM_GET, ifindex)); + g_assert(!nm_platform_link_is_up(NM_PLATFORM_GET, ifindex)); + g_assert(!nm_platform_link_is_connected(NM_PLATFORM_GET, ifindex)); + accept_signal(link_changed); + + /* arp/noarp */ + g_assert(!nm_platform_link_uses_arp(NM_PLATFORM_GET, ifindex)); + g_assert(nm_platform_link_set_arp(NM_PLATFORM_GET, ifindex)); + g_assert(nm_platform_link_uses_arp(NM_PLATFORM_GET, ifindex)); + accept_signal(link_changed); + g_assert(nm_platform_link_set_noarp(NM_PLATFORM_GET, ifindex)); + g_assert(!nm_platform_link_uses_arp(NM_PLATFORM_GET, ifindex)); + accept_signal(link_changed); + + /* Features */ + g_assert(!nm_platform_link_supports_carrier_detect(NM_PLATFORM_GET, ifindex)); + g_assert(nm_platform_link_supports_vlans(NM_PLATFORM_GET, ifindex)); + + /* Set MAC address */ + g_assert(NMTST_NM_ERR_SUCCESS( + nm_platform_link_set_address(NM_PLATFORM_GET, ifindex, mac, sizeof(mac)))); + address = nm_platform_link_get_address(NM_PLATFORM_GET, ifindex, &addrlen); + g_assert(addrlen == sizeof(mac)); + g_assert(!memcmp(address, mac, addrlen)); + address = nm_platform_link_get_address(NM_PLATFORM_GET, ifindex, NULL); + g_assert(!memcmp(address, mac, addrlen)); + accept_signal(link_changed); + + /* Set MTU */ + g_assert(NMTST_NM_ERR_SUCCESS(nm_platform_link_set_mtu(NM_PLATFORM_GET, ifindex, MTU))); + g_assert_cmpint(nm_platform_link_get_mtu(NM_PLATFORM_GET, ifindex), ==, MTU); + accept_signal(link_changed); + + /* Delete device */ + nmtstp_link_delete(NULL, -1, ifindex, DEVICE_NAME, TRUE); + accept_signal(link_removed); + + /* Try to delete again */ + g_assert(!nm_platform_link_delete(NM_PLATFORM_GET, ifindex)); + + free_signal(link_added); + free_signal(link_changed); + free_signal(link_removed); } /*****************************************************************************/ static void -test_external (void) +test_external(void) { - const NMPlatformLink *pllink; - SignalData *link_added, *link_changed, *link_removed; - int ifindex; - - link_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, DEVICE_NAME); - - nmtstp_run_command_check ("ip link add %s type %s", DEVICE_NAME, "dummy"); - wait_signal (link_added); - - g_assert (nm_platform_link_get_by_ifname (NM_PLATFORM_GET, DEVICE_NAME)); - ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); - g_assert (ifindex > 0); - g_assert_cmpstr (nm_platform_link_get_name (NM_PLATFORM_GET, ifindex), ==, DEVICE_NAME); - g_assert_cmpint (nm_platform_link_get_type (NM_PLATFORM_GET, ifindex), ==, NM_LINK_TYPE_DUMMY); - g_assert_cmpstr (nm_platform_link_get_type_name (NM_PLATFORM_GET, ifindex), ==, DUMMY_TYPEDESC); - link_changed = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_CHANGED, link_callback, ifindex); - link_removed = add_signal_ifindex (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_REMOVED, link_callback, ifindex); - - pllink = nm_platform_link_get (NM_PLATFORM_GET, ifindex); - g_assert (pllink); - if (!pllink->initialized) { - /* we still lack the notification via UDEV. Expect another link changed signal. */ - wait_signal (link_changed); - } - - /* Up/connected/arp */ - g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex)); - g_assert (!nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex)); - g_assert (!nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex)); - - nmtstp_run_command_check ("ip link set %s up", DEVICE_NAME); - wait_signal (link_changed); - - g_assert (nm_platform_link_is_up (NM_PLATFORM_GET, ifindex)); - g_assert (nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex)); - nmtstp_run_command_check ("ip link set %s down", DEVICE_NAME); - wait_signal (link_changed); - g_assert (!nm_platform_link_is_up (NM_PLATFORM_GET, ifindex)); - g_assert (!nm_platform_link_is_connected (NM_PLATFORM_GET, ifindex)); - - nmtstp_run_command_check ("ip link set %s arp on", DEVICE_NAME); - wait_signal (link_changed); - g_assert (nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex)); - nmtstp_run_command_check ("ip link set %s arp off", DEVICE_NAME); - wait_signal (link_changed); - g_assert (!nm_platform_link_uses_arp (NM_PLATFORM_GET, ifindex)); - - nmtstp_run_command_check ("ip link del %s", DEVICE_NAME); - wait_signal (link_removed); - accept_signals (link_changed, 0, 1); - g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, DEVICE_NAME)); - - free_signal (link_added); - free_signal (link_changed); - free_signal (link_removed); + const NMPlatformLink *pllink; + SignalData * link_added, *link_changed, *link_removed; + int ifindex; + + link_added = add_signal_ifname(NM_PLATFORM_SIGNAL_LINK_CHANGED, + NM_PLATFORM_SIGNAL_ADDED, + link_callback, + DEVICE_NAME); + + nmtstp_run_command_check("ip link add %s type %s", DEVICE_NAME, "dummy"); + wait_signal(link_added); + + g_assert(nm_platform_link_get_by_ifname(NM_PLATFORM_GET, DEVICE_NAME)); + ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME); + g_assert(ifindex > 0); + g_assert_cmpstr(nm_platform_link_get_name(NM_PLATFORM_GET, ifindex), ==, DEVICE_NAME); + g_assert_cmpint(nm_platform_link_get_type(NM_PLATFORM_GET, ifindex), ==, NM_LINK_TYPE_DUMMY); + g_assert_cmpstr(nm_platform_link_get_type_name(NM_PLATFORM_GET, ifindex), ==, DUMMY_TYPEDESC); + link_changed = add_signal_ifindex(NM_PLATFORM_SIGNAL_LINK_CHANGED, + NM_PLATFORM_SIGNAL_CHANGED, + link_callback, + ifindex); + link_removed = add_signal_ifindex(NM_PLATFORM_SIGNAL_LINK_CHANGED, + NM_PLATFORM_SIGNAL_REMOVED, + link_callback, + ifindex); + + pllink = nm_platform_link_get(NM_PLATFORM_GET, ifindex); + g_assert(pllink); + if (!pllink->initialized) { + /* we still lack the notification via UDEV. Expect another link changed signal. */ + wait_signal(link_changed); + } + + /* Up/connected/arp */ + g_assert(!nm_platform_link_is_up(NM_PLATFORM_GET, ifindex)); + g_assert(!nm_platform_link_is_connected(NM_PLATFORM_GET, ifindex)); + g_assert(!nm_platform_link_uses_arp(NM_PLATFORM_GET, ifindex)); + + nmtstp_run_command_check("ip link set %s up", DEVICE_NAME); + wait_signal(link_changed); + + g_assert(nm_platform_link_is_up(NM_PLATFORM_GET, ifindex)); + g_assert(nm_platform_link_is_connected(NM_PLATFORM_GET, ifindex)); + nmtstp_run_command_check("ip link set %s down", DEVICE_NAME); + wait_signal(link_changed); + g_assert(!nm_platform_link_is_up(NM_PLATFORM_GET, ifindex)); + g_assert(!nm_platform_link_is_connected(NM_PLATFORM_GET, ifindex)); + + nmtstp_run_command_check("ip link set %s arp on", DEVICE_NAME); + wait_signal(link_changed); + g_assert(nm_platform_link_uses_arp(NM_PLATFORM_GET, ifindex)); + nmtstp_run_command_check("ip link set %s arp off", DEVICE_NAME); + wait_signal(link_changed); + g_assert(!nm_platform_link_uses_arp(NM_PLATFORM_GET, ifindex)); + + nmtstp_run_command_check("ip link del %s", DEVICE_NAME); + wait_signal(link_removed); + accept_signals(link_changed, 0, 1); + g_assert(!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, DEVICE_NAME)); + + free_signal(link_added); + free_signal(link_changed); + free_signal(link_removed); } /*****************************************************************************/ static guint8 * -_copy_base64 (guint8 *dst, gsize dst_len, const char *base64_src) +_copy_base64(guint8 *dst, gsize dst_len, const char *base64_src) { - g_assert (dst); - g_assert (dst_len > 0); - - if (!base64_src) - memset (dst, 0, dst_len); - else { - gs_free guint8 *b = NULL; - gsize l; - - b = g_base64_decode (base64_src, &l); - g_assert (b); - g_assert (l == dst_len); - - memcpy (dst, b, dst_len); - } - return dst; + g_assert(dst); + g_assert(dst_len > 0); + + if (!base64_src) + memset(dst, 0, dst_len); + else { + gs_free guint8 *b = NULL; + gsize l; + + b = g_base64_decode(base64_src, &l); + g_assert(b); + g_assert(l == dst_len); + + memcpy(dst, b, dst_len); + } + return dst; } typedef struct { - const char *pri; - const char *pub; - const char *pre; + const char *pri; + const char *pub; + const char *pre; } KeyPair; static void -_test_wireguard_change (NMPlatform *platform, - int ifindex, - int test_mode) +_test_wireguard_change(NMPlatform *platform, int ifindex, int test_mode) { - const KeyPair self_key = - { "yOWEsaXFxX9/DOkQPzqB9RufZOpfSP4LZZCErP0N0Xo=", "s6pVT2xPwktor9O5bVOSzcPqBu9uzQOUzPQHXLU2jmk=" }; - const KeyPair keys[100] = { - { "+BDHMh11bkheGfvlQpqt8P/H7N1sPXtVi05XraZS0E8=", "QItu7PJadBVXFXGv55CMtVnbRHdrI6E2CGlu2N5oGx4=", "2IvZnKTzbF1UlChznWSsEYtGbPjhYSTT41GXO6zLxvk=" }, - { "qGZyV2BO1nyY/FGYd6elBPirwJC9QyZwqbm2OJAgLkY=", "v8L1FEitO0xo+wW/CVVUnALlw0zGveApSFdlITi/5lI=", "/R2c0JmBNGJzT594NQ0mBJ2XJjxt2QUSo+ZiqeY0EQA=" }, - { "YDgsIb0oe+9NcxIx2r0HEEPQpRMxmRN0ALoLm9Sh40Q=", "nFPs1HaU7uFBvE9xZCMF8oOAjzLpZ49AzDHOluY1O2E=", "zsYED2Ef7zIHJoRBPcen+w4ktrRsLPEfYwZhWIuXfds=" }, - { "kHkosM503LWu43tdYXbNwVOpRrtPgd9XFqcN7k4t6G4=", "b8e092WT+eNmnxCr5WE2QC/MXAjDagfG1g03cs2mBC0=", "VXz0ShGWT7H0CBCg2awfatmOJF15ZtaSMPhMsp+hc3A=" }, - { "4C2w5CEnxH59Y2aa6CJXgLdDtWoNMS2UJounRCM1Jkk=", "gC/R9umlnEQL+Qsz/Y64AlsdMge4ECe5/u/JHZCMWSs=", "2bmL5ISr+V5a7l7xFJ695BLIJyBgx8xnxzybkxiRHOg=" }, - { "KHJSzFGkXcZf/wbH2rr99SYtGKWbL680wA2AcDE94lo=", "BsN23h4aOi458Q3EgMQsodsWQxd9h/RxqskAUpsXfgg=", "nK4Zv34YKEhjuexhq1SgK4oTd4MZJT5gcpYvEuPjc7Q=" }, - { "QGMulXJ9e3AVxtpi8+UUVqPOr/YBWvCNFVsWS9IUnUA=", "kjVclP5Ifi6og2BBCEHKS/aa/WktArB4+ig06lYaVlg=", "0+mmceDPcSRK3vFnYqHd9iAfY+Nyjzf/1KgDeYGlRkQ=" }, - { "AOJiDD4y6GA7P7gugjjQG9Cctvc5Y27fajHz6aU3gU4=", "gEnHn6euHtcMEwZBlX6HANPeN9Of+voBDtltS38xDUw=", "wIH1OxgX6GLxx/bnR+t3fbmjGZDTU3WMxp7t1XGezqM=" }, - { "COsls2BlCltaIrrq1+FU51cWddlmoPPppSeIDunOxGA=", "+n6WuV8Tb1/iZArTrHsyNqkRHABbavBQt9Me72K2KEc=", "t4baiprSO9ZbKD2/RutOY9cr+yCajQWZGCTnQdrFQj0=" }, - { "uHawQq2BRyJlsTPoCa+MfBVnv4MwtRoS+S9FEpFOEVg=", "8lcmr27afeb6iI3BQCaDtvalF2Cl7gxRZgs+nyJ/fEg=", "Eh9o/6W60iujBLIHuRfNrPhOWAn7PambT2JRln9iwA0=" }, - { "yL7hmoE/JfRGAotRzx9xOpjfrDA3BFlPEemFiQw40Wk=", "BHK0PHi5kp7rOfQ46oc9xlVpB+pZeZYXTtH7EXr5TwU=", "BS2h2ZZyW0BlYMmLR29xyHEcZ4jtO7rgj1jkz/EEaxU=" }, - { "ON8YrTHQgoC5e0mAR9FakZ8hZ/9I7ysuE21sG546J1Y=", "Bm3l5I6iH1tDrv6EgdZU9PzHqp0H26Z6ggmmIypwxy8=", "qKVfbCnK1EI3eC28SsL+jyBnEnIF/nRJQJzDevBFdNQ=" }, - { "KGLO0RI0VlQFCG+ETUqk25HdaKUnUPXKOKkTh/w8BXU=", "sBDBwQFC7k8UMdMzuavKBkBjYYKigzvYmGF5rm6muQc=", "BNfZF9d7540pUGGOQCh3iDxAZcPBqX4qqM00GSLPBek=" }, - { "KGdWyEodIn7KKI2e4EFK9tT6Bt3bNMFBRFVTKjjJm2E=", "lrbjU/Xn9wDCZQiU8E5fY6igTSozghvo47QeVIIWaUk=", "LczqW48MW8qDQIZYRELsz/VCzVDc5niROvk7OqrTxR0=" }, - { "wO3xinUGABgEmX+RJZbBbOtAmBuPPFG6oVdimvoo90w=", "dCIvTzR6EerOOsRKnWly1a9WGzbJ4qc+6t3SSzLgWFk=", "wFj0zpr5PadBoBy0couLuZ1qudZbXLbV/j3UT+AyKeo=" }, - { "+JNOBlO4tp9vvQk6UO4r3sILyEgjl+BBoWketZufyn0=", "Q6LSv9y7YQkJEzQ/1mpjJEgOrO8GYPUTgcizjh7Cm34=", "kg7AG9MuN04xPJ5Z0IcNZ4a8d1b/n4GsGIeyA4FaaSE=" }, - { "+EJcThLRwjZ+h1CNNFu15HWzznf4u/lPVw8hifTm2Ec=", "Kkn2jFqwBzyIFQfD0OpmePFSmBYmhKagv4pGgkqsWgE=", "jYpxojj8WKYe/XIXMP+uv1Fv0+TKrs83tqfzP0AGdcI=" }, - { "+DKFqSMNFmxriEFj3qatuzYeTJ9+xWYspZ4ydL3eC0Q=", "3o37bsg6HhRg/M9+fTlLcFYc2w/Bz9rLQySvvYCKbRE=", "Jb9qoDIBat1EexlgfpRbXa7OflptME8/zt93bldkiVE=" }, - { "EH3MjFOMqRoDFQz+hSlJpntWBeH3lTk6WPjTIQjr42o=", "PbPewED/nxSBLdM7AXMj7uS3bCgAAg8M6F4iPLd0b1U=", "pj4+UgOGkpJwlRvX5BRXZzmzAUnDtUtJsS7LzbcJWzw=" }, - { "kL6M2KvO+vPBLEc/a0DpEHTibQ1bwaMRT9b9SkzeP0Y=", "pS3G2bHHlkOE6UHP0qVitDuxXgjEaZTviTjNc55RbVs=", "ZVZpWOtYqhX3CpF1kATg/38J6pvUJo8AS1sVYjs3rUE=" }, - { "sFlcRLDn36fnew2Ld92IHJwnKifdS3aF1MWRPs6K3Wg=", "OpjUOTiWExaDYULTINB4yQFqc3mnU3RjQzGRV+KtdFY=", "of0V/uoFRNljv/XTt/tXgoquLRH93Ty0KNiaPUpEi2w=" }, - { "UJ8hjDsg3jfsnnfPH8Gw9FnCb6taTuviurAfZu+kEFg=", "3byjHksUOv8CNjGGKvHvvrJDURBhCIL5UtfZbgyVWCE=", "9f7dbWif51gGrE7R9LeuewQSrvGFGTOB3ceJC67jSkI=" }, - { "iFFPKGIfqeUKY/w72KAZSjd/PGTqCakHYBV10xMDfnI=", "ehneHATNSXtsJTOiPjVSc0QARkihgcfcvoXKFWKfQnI=", "yKdqDBcRwA7RCg4GiY/b5IsWcExPleOBde/hjxc36a4=" }, - { "GDGocdPJTPUAllxQo7SpXZKqMPn7lpxQELQUX9ETHmE=", "n0ScNEou4ekfrXRRXvcADLu2Afj8g5D3TuDP/I4KrnY=", "8QhswqAhi/ehhcmCwQF5aSh80TvIGC/gRL5jBn5wOH8=" }, - { "UCcrlN8fX2ZdNdhaEBNwktwL+H0ZO7fhaj7rgdUutmw=", "LF8J728ilXs4TphnrgR6r0p7W3912DYnsXkGMEPQnRE=", "cYfMjxl2REYir7frGeB0u+NHAaFYF02ysgpBhOL5ygc=" }, - { "SH0657XuIiHidVmViXZF30RUWtkuWXcWWHmKZHTiOG8=", "7k6j49W1u5qgLE5MQUc1osPVW1oPPhzjrGvJ7o9YamY=", "dV2+7rNk/3LR2IcwYg/c+Wvzep1yjY7/u1I+nnlTQ00=" }, - { "qFQWs6jzrscV42pGISQyA7JDvFFAvEQCWJi584VHD2g=", "AT63nHKLC17yUvkR4lOVPxCr4DD3QhXmcmecOTn+Amc=", "2Qe2fwJbFcu1CmKpktElOFkSQMqlyvlV3ZUIAd/Dcts=" }, - { "6J+yLxgPwWtUbk9I3zbeD8RuK6XkQjJ0wTJ1zSVhflQ=", "NJzMBYyPZjk3eLmgdKaOeWyNER5YZF1mR8Umeiu9f28=", "pp+4+XHw5ZmHGJ7WbZ1xLYRsnTI17QIbb0bzHzYZrBs=" }, - { "KJGoWYNVDUWcEMg+E4tljv1LiWAbdRw2QVapYqdFa1Y=", "M2SGk9WVnzYNGnT777G/JE8uUsY2f7mszTwlue73UDE=", "Jg8N7GbhbYB400foFP+OH0v+hCaL1jW61bajSA6EZqc=" }, - { "uAgrgppPyIvk8S1CHUmaCaORsgFFfBreB8pxXmbSdXw=", "dJ22bER4fD3qF2/yIGWQ7SgmZ990sy/SbANjmUMkzws=", "mKkd0OoAR9sClmD+k3fL9weBsoCy5GQGz9BP0kAQIjc=" }, - { "EI3Q8gePNPrtFyoMcv7hOihQgroF/dfjzPn8yvpGPWQ=", "Y9QhJFeiyuuIZNPU56B6U//ZK+XTTe4EP7h/p3Q+dE8=", "qBVUYw9rTWaxn55nUd55NpCWtxOUSWLt4WJGusiDS8Q=" }, - { "oEQvdRm/yHkx+JvlhHGT5RUFrFEUleKb9DCT55EqZ30=", "8hsh/UHwWADTHntOJq4dy0o7ahcNAAlo2rDpjzzrVXk=", "/GF2inW2mPtA26IgFdgOEBbBEerT740wWuP/8NyANdc=" }, - { "6OWrGKZKNsgfRezSUw29EnHymcgKyEKvX5/pZQlLmWs=", "oaJeO6YSS2dodNEf97DvgWrYnFFelG5daEdN84jVVGw=", "T5wvTdyVxK0LY96kouLjs06oUfhGChfty8OUL1Mddro=" }, - { "mPmzQbh2R+r1DC5hSquzKM1SDrxUdfnBPRPJrpqrgkE=", "BtUHAnYWjDjBI42qBf9dJqezTUikYsF96o6PKEWPrVo=", "MxU8EMmq+vVHpuK/AkFZrZDF2b+VbSqukZLPbNsCcgo=" }, - { "8GVxuoo1Veyr+nqxr5Q4vmsMf5qfiXwSlQ4q3+BU60g=", "uSOLe/E9/OjIgUOk0NMBHB45E0+q4Rd+IUO2UOxmKlM=", "+30F+56OE0Sr3wY2clKw4kgE+2XiucMg7xjK6EemXuk=" }, - { "qORPKb+qFuU/9TpFbRUupHsqm9iyk9pa6cpik+EVDkg=", "bMZxxd+Z9I0XA1h9U8JEY+/mRxWGnvbXDZ5Dxz7YzS0=", "SmkkqOz4OhHuSL6cxuRm9+Mlt50Sfd0sMDFTC78gqOE=" }, - { "2Ko3IYhXKcdOMIJGNpASk9saNSZsI64lyJPOoxpQ2kI=", "xVOc9PxY1VFaZfemmKi+Ei2liHhmeTu+JMa+rS00gnA=", "+398DlW8kWeI2aRaC4QfcrEjwqPKCohyDeWdaI1wvv0=" }, - { "CPioGCVpxnym62nH/QoCt1RiiaaxUcuFjvh5kRhjqHA=", "W0XxlBLrZgFKhggMvvv6oFf/RJbfs92qv8JK9e+5i2o=", "bsK2U6CRAUv1uVgYQ7NpqjWWswFIDiDPDEtU1XQygSA=" }, - { "AF17siKaeiO85hikYN0IWCMGWqPm1UOoCkXMltJGUVk=", "B+PFos9aN2S5bLxzGZHljRZj41j3rIx8RWu0vDUzq1w=", "Qb8d6iDYv3m1h7PE8j0Exl2cSwpHkim/fJ1S4P7MYvY=" }, - { "wMFDBTJzx5tDCBhMkrptYJ8w9EeURjc4xeDQpevxAWo=", "4ec439EXE5WQzvtV9reSX+aMmdq5k7o9Ayt8oQp+RhQ=", "jwQlvdNH5WtSSU10H+fh/JisOlaBaohDPEp/BYnTt1Q=" }, - { "4GaJpIFigNDwd31O84pLIMM/o2qhp0ydlI/ydD/2a2Q=", "r/LdkCoK5/BPGdq2+XJO8sCRhI+8ULFmg0887V43PAI=", "Da+3ZZvEJdx4TYFMIDUlbkmytILnSTNxTKX+sQdjMd4=" }, - { "gMnojGqCLmMfGp2m31xlKZ/rIV2b8ockw9DPahRyu0c=", "H6tKCTosnM4BXKqflXrkTdJyNlCIZhQ3ZRxfrvSdrDk=", "4Z6K3LKIMV89plcjMb9CzSzJl03SWRe/++geBMZcOtY=" }, - { "wKCg22aNNoHnDJ0oAKE46FcSSsREW4AaGn5WxCSeXUs=", "9NDTFC0iPt4HbbWepLHhN5poNTN2fdxJKNadsNT7qzY=", "GSVTOCnfLpJ1VCOLHaKSjCMv7/OlcnQiP5+5woqkud8=" }, - { "oCoykq7pcJcg2X2V5TBRzGwn8hzzHC05WUreuotdznY=", "DxfwnbMqr5Wn5SAyFolfEmNQT6l84Oq69ngpg6H6Iio=", "p1RHBuqhuDa1MAQ2lbqmUQFu0CTwYlf73fWZSj9tQhA=" }, - { "UO7YVyRUVkcKr7c63VWWV2zj36XD3HyDfLZCqvrZmFc=", "360lzYtIyHq5lv/QXSCe4bL4G2J1jBXFJ8yS+Ycr7Bc=", "RRPQ1XWF1HN8Us4dtfn2eemdjgtWm7U8r7mM3y00NOk=" }, - { "eCGFYV/NuGP4H552E8Of1xU+3IvZxGyX+p5UFGW8iHI=", "LqhZ4AS9dQ/MhsQnE5Oy7Q8INXY+P+mrfGY5dtg9SlE=", "SICfqs8T5wP6IzATDCT4ovamBKPdkZ7JP4Cfsb3izec=" }, - { "oI3HBZknoIMMZw1BuYMkTBylt25reX7AbCqtWQv8cno=", "B7dUgLgvQhi0RGmvaMrmf26WdjEVrhaiBclVkCKd4AA=", "5O9K9pLXwxFAt5lfMWh4qGbwX1BM7sz0QGYxAnR77dk=" }, - { "sBfYn14EFVIS2M/E1aahP7mOmRNbNtyDChDMS1s6aGs=", "FLYv0ZvzxMkc9A7OzhC4P1ZRu1aKIQd7u6gqfdekC3c=", "kaYLcNCXnCLgiB8fleMQuboUJsj5u3YAmXL9x3ywV0M=" }, - { "qFwZESU/XYZXUtxwrGsFU9qPAFTzjm7EhTS1Q6ajGlM=", "hraQQaqJCkS2yQXv+ccMOVh9V9a/qgSZJgdMAhrt8ms=", "72oDfnWOn39gdk/ncw8Lv267I0I+m73SwxrpYojpWYk=" }, - { "YHhp6Zf/miuc2QXeI2lTezy0lL0pTv2b+nWNkmjYQWI=", "UhNO5arLzF0WlZSgNOx7+IjWN+GSxDdQxZRp8uIwsyI=", "1Q39Nzv2NGI9zWKWMpYLURAMZUg+FP+OboHHzFU8Anc=" }, - { "mLBBXKaCJ+7qeBZpS3wxGi/SQ4kLzun+K+QwwdwfJVQ=", "gIq/nh7NwCJ36MvRnyrWHaRWu8lTmwfN2NvsjVl6SXQ=", "AahcNR91GDyJBIP+vC8ZuIV8ukqjSGtd8s+cmjVC2Ao=" }, - { "OJG4LZlNNngFtAEQdbVVWVm6QAjOOauGcMZGbQrb40M=", "pFHAC6HaWAOtvTRRVfSHvzG05mp4SJZXKsN/tkSF0kM=", "IoXT3wIqWNxQhYuHWl12ODq/P7RM9LwaqglhmjKg+0g=" }, - { "OOwBFOQNhepiqDf04DehQLh1gpBNOluDF1ia752Yfng=", "u715uJ/XhdjXjThCTJ9w6zzXnIhp3VCxhtso1wk+oBQ=", "5x1Ip3Ym0KzDjGhiYjmpeWWr+dgrZlYwfr02GngPOTM=" }, - { "eNPFnwkQy1qw+IjFAlrDA6+sIsxbWDlzbNSsBW8R1UA=", "OaOXaAfPb1MRpWadawFje8YZ0oxJgdCIDIP8c5X+r1U=", "NtfaRRD0GqujnaQQoNoBbtovgO4dfVwEmEQx/YgnDpw=" }, - { "OLdaZItbtxH3mGqItkibIJp7KV27FrQavjhd5zq6s3Q=", "SLSmAYxkMCGj0DO35cMLkC3NVAqK2VmVFndbOZEdA24=", "SnBO68XQTDjxYbmYaAeEHgLwD2u4D+BPT86raRuUQZM=" }, - { "UBQOEz08izwr4eEK/SnQUpkt+TxCjo6Sya/XOGMLOE0=", "wQwrwezI9LzKevGsJJCBHDG8noR0yIEtOK5Rig97SSo=", "DpyS+0d7lrlFWkztsniG2v/j44vcuvWz3sPeghRyb5A=" }, - { "mN98iuqUKh67ggUdq9ZIQNZCZM90fgycTVqYKEo+DkY=", "GYdXVW1jpS0dN1q9zMehubP7LfYqs34kszN0bXQqxxA=", "AJPIHffB4uvvJJki4xCG0VORVBbF6bc2mZQqUx+idPc=" }, - { "OEd/1it8C3o+NOWxDI3DfLMXVBHJQg15N3E8F8d99l8=", "QL1NcuUkoXxDy7M9VjGslCejcUlnUDHRghFVnr+8fmA=", "nven9Dicl8U6QXuDO8rRNtjd4NYaa90SU+Gmv435XKY=" }, - { "AFMCGDu2oAP68miucsi4fmYX2KeRZnsEGv8tQm8JEng=", "1sNxvk8uZhFsBUgxOXmuCMjDAgBbjVeWe9oaFk5Osy0=", "t5iI5XXd56S5q0Y9HC91gzgF9uGjL9FIy6NUaKqkydo=" }, - { "CIAwfJghQHHr4YlztN9at6/iWkrEVCGFAxNVuQCuT3I=", "zpUOF1h17g7RpBzrVlN7oTRz6e+dxcDL8OsAtHwgLC8=", "kOSwC1p6Uoti9E9Eg7ViPZwCytuvp5Fr5Buw677aogU=" }, - { "sC8vrAVBU0zvhWDRfzfySjvopXm2/cTMkTLmioyO3Es=", "p6H7GWm8NfgyO5OCX/COjvVT4MAnTs9ZUj4uZMK8XHA=", "9Tzqo57V/h7+6nSNAHSBKdmU7ultlvZbAnNKSRlrLi4=" }, - { "eI63gjxCZGnzqZxPEi/ifYphXhxIRI2ZxK8jzqo3mmU=", "XyNzEuU9x37fxFCnrZH89Krs5/UqGVx5wNkGfQCAYz0=", "vZ2fTlRPnJQ+q33YdS5p1aweqPGj/kTMc4Uq80FtFjI=" }, - { "aNJlGtm79/RS4SQ/PC4YM6LFo9zAqDr2/RjLqk/z/1A=", "lgZ9akPrABmfHQMlfNFnnpAJzGtcsaU9mUjEYKfzZHc=", "d0Xt1Bcgphd1HMI0RneA4VdBbMZL1qNGJAvFhb080eA=" }, - { "oONSnHirNh3cuH93Ty0C9AXKebGY+cdF3R0DtPzIQlo=", "TuREKfA8EVQiYWsPx8veUzjN2cz/b72limSLWlrCWxw=", "vEqqKbpZf0EM6EApMUaUH65r3Zr81Y/DSODhE4H7U3Y=" }, - { "+D6RyLEaHJ9YF9WDyOlwh87KaNJcc6lqX8Arp6yqHF0=", "EpecjfIo1/EEbmsgUtzEDqLu2ut+SMmzqaBL9Z/MlCA=", "oYfO6/7XQgEYT9zmr4sqFrk0muK/fEv3FfD8MzZzjkE=" }, - { "OCmW5KQql2PRMJnsMYQjXlr6TSYUbxJBknqZtXJPSHM=", "ZZR2ghHlCwAJu/XlsEZuNS6XiGPwuXzyMPPywYFapVM=", "fqSCXq+pKJJ6yNvlOi+tyQ9E4Y6kc4kblGrVqN2WuXA=" }, - { "APWXDAe8d2ia1CUbf/IzSPXOUjR8TVuJgmISiWw0/EY=", "jrT5P5YCkG+U7cfNTvCKy0GSEgsjwmJtHg+8HBP6ZCA=", "t75aUjZXMPir8Ao0yhVClh9/BdWxSL+11CjK3iELNWk=" }, - { "8Nw4sRis7M/6Om+3w5YHXthyMzLGuP48teqdzbHNPlA=", "lj3q3ZYij3ZJ/QunK8n9I00cv/Z+O1TU1kFFl8x3DTE=", "adqB79P7gbXEYYnSd1/UPCwFffTAPXa9kHWynRBYcGo=" }, - { "yOupps5XbjV0fIZKnGhrpcxB7yDQzbBILC0UMJyVS1c=", "+MDV/t9UCIdgm3IkH3BZlxaRPJ3lejRmrm4UPApq4mk=", "AOJPmQxsU6hjOd+9mHnF0VL7Afih3P1Fr625xFT4FtY=" }, - { "cD2DEl4MBwONuTV0db5XreoVjQAUZFNXqIeFEU3KFkE=", "2CeHrjN7tBX48k4Sgv5fIHG06e57q/ucCL+8DIRmfXw=", "3EUo6MRzs6rSoY/7AFs8wiBiTXPcHzerLh6Xp3aMGKo=" }, - { "EA+S3a9ZeOLiRbhTxaT2wkpyDheAmai+UJa6SFGzSm8=", "GGByUKZx/FPa2OkJoqVTHXx+6jrIpIw5rf0rp43MHko=", "BXoDA3yn0JcMV7hHVzEqhlwAORvhToFO1qG00nas92A=" }, - { "eBeJi/imBiV52WEqrwAprUQggqdQmvTTmWtLq8pDDkM=", "zCX26ZTOZHLpq5x5aIUL1XhIVoXJLp/zcXwnmFA3jBo=", "Dm/DCxXWYXEsmQgxAD3KREK2PF0bUSnV5WRAaya8s1I=" }, - { "8C7p+EQO+CnWUSjHVu3PpeWpUIbLy48zpftZu021plM=", "DxpnF/IbKAh6kmWC5Jpj8iw387EDkrvjsjOb9fbTSng=", "bGrk0OshJB+0oQOK0QGKU8+lotnIDz3oeUnMZGienyM=" }, - { "COIez7YcBJiOJCLxxWV5UGLW5/o009YI0aszlD/PiUc=", "eD9USWV37LFIOxlDSHyOmfFqNJFpORRlzEI+HoF/czI=", "n+/ra86gUSF2pNZS51nt2JgrzXnQJl+dWswOq/Ahs94=" }, - { "iBBSTG9VLC+T9+ahNaQ4umZoig8o7w1DaeOw+cD2BGc=", "XnAxqDlvGnQ6aakv8ABGHVj07qVQfk4NChZbstTMBxg=", "7KKSwu/4yWr1UzFmNMGtiaSwdYMhP/HKbrQLlABL4UE=" }, - { "eNmwattflehr9+KsVqTuwt1YaAc5ONkaIaTQt9Gkhn8=", "1NNVvm++YTTGMKyAXfGOCZ4aDDdFFH5Um3vAg4XimDo=", "bXNrnDTP0pBay9ytZe7xpiKoSi12F7WUXqoIeI++Xvo=" }, - { "QJotpmZINx9eptKpkh9j3JlEDcHdWnjEbicdBS7gPXM=", "3gLYKeoruVZ/AYjym0gciDvRHj45UIWyHhNjWj2Wj28=", "NwuUkkE5yOWT7wed7bltgAk71miz3cSooiIDAdv6kKw=" }, - { "OAYGuxH70OPQvhVIX4BhSCWUyzAI5H2IkYxKgC/AO0M=", "Rj9iNF/FagkXfdLPqc9LHfaoGR8GlvY3gun2FilE508=", "hkNXLVMlBRsMEaQKkSzevcEK2sMu0AShGKQJMNqdzWM=" }, - { "uBrgZ7wLHrOV/0dNiEqo7FjY9VnJqL5eUDHJWAc9QXg=", "3Hnln8ZHfSaK4OzESJe5U6NcLaW56wzfZICzvzefnSo=", "DhXsehe5FAmbUidXT5ZpZIAuu1eF9rkU6cF3FBoKwOE=" }, - { "sJknn3CHvx/812EWU3ddLdLLZFBKsc+wx35GXyiRsHY=", "qqa2dNSt0jWozGyqpokP392H5/DOAUUZmUpyZDaUEEE=", "1Dyz8CvmF17oKT/wG2fu3vRzPzgQv8/OY9GJYew4FG8=" }, - { "yOumS9HN68ZwIm+5hZol3jFQ0DB4SKuW/ld3y8wioGk=", "6PowsbKj/fKSzXZMAfaSkP3fE+4AThL9xm6ysQzMDxg=", "vF8cKu9X9FxgCjyVZ5RG7nuue8RelF5Qsb8Efme4M4A=" }, - { "mISm5vQfPdK72SsaHh6O1/ARvaWCtm+KZNcpTsyt500=", "YCORDQDpb1U8vADdstBgXkg0N7QaAc5VoXJ4QFuA/UY=", "JlrBmfaCgbfEVD9YQq3c03WwwsHWc1nBwp1JkFORC3A=" }, - { "cPyu3Qry6qbsiOJKFGRziZ9LJWJ47k3ZSXiGkQXuQm0=", "/cmBZTbqEp8sababPAxGb3OvDAEE7MlwPOwEFHE+7yM=", "lp0Hhc/rVtpT5FtLLccChqDl3El48XtP6Wm6JwjI7jo=" }, - { "YKsMYU0SINbPwWw4RDCJV6GnzDlSp1ZNwUw2euGWi0A=", "/KmBReATQbFnLg8YKV0jwhqKeishRoWvlVtMX3550Vk=", "7fXpPSMo1Fw2sOXtjTtvFU+DbZvS/FWB9wAsywWx6R4=" }, - { "WD0YI3y71eIp/GXw9i+7scEiQKSBkGihZWE+s6fGmWo=", "RdthAL/qPnAZFb3xBgRMiAtGHNjgokzoKX9iO2K5qhc=", "4dk4HGkT9dBmomGNorDE/hLr/HEFhljtl4zz3M4sG58=" }, - { "oD8KWhJYZVhutJRb0kZlZnB22QUXzi2FfPRD0ll65UM=", "MYTBGHh4Ukj97pKj6qcfWmxGNQzmU3/aBOX2f1tfhG0=", "VT1gC+a9nRJzYMi/TPvRVnn3IQlaop/jKmmxZePEME0=" }, - { "0Ns/1SOiqR2CpHRG03QNzJJd5gxTm1XJmSkFlugjQ3k=", "KvQAI+ekNOa2xfEvfyc9JGcS+CTUrnnhsKrlyJGJixg=", "J8LmSX6zElX3S9q4PNvh2NKUtAiQ3oHiYjSJ7yErPlY=" }, - { "mD6TeF4ezSPXN/csN1OhoAREFSXllI+zl4DUOInVq2Q=", "WmLJ9ep2EqFcSftnYFJsmWyUxqL0zzuSzVEv94PcISM=", "U2+ILy2NDmmfgSW78C8dl8GyHESUc1lXPHPpg5F+gr8=" }, - { "SMJoXOYgHz8HSzY+ByeWLcSP5qFwv7YjRe0bcKesRnM=", "DEsNSOY3TEs9J2YgqroQ4xKq8T8xNJQjvvE4UrTItQw=", "Bws1Hk2+lO+JQ7ME16EbwAdsBkWsGvti0Gb6LY2Lrms=" }, - { "iGhXF0Hg0tqZmpwAMiolxvbvTPClQ7LlBAspSSyFEHE=", "7Xxzpwl7yRWehHNWTYVtFkdChJdXhtY4Mtw1fA9QcCg=", "Swjfv0PjuaE8Oq3a17BVno5I+q49dZlPwKK1bPUoKNI=" }, - { "MIazjx3qTi6Qz3WzhtCPw3i4Q2uZBHcuMoh++ZGFYUk=", "oni8pbFqk9Ya+Fx+911Nl1SN0FD/hR1jwb2RH3t/pRk=", "ZYAFcj67LkbNURYbSnCCWGxAG8QLDGWwbl968mA6ZA4=" }, - { "MAadYdiFM2cPuJF19q20Yoo5KJabuR9TUQ9jG5nvA1w=", "5OcE8XV+UPoBVbgqBQdVF62GZCW9DOQEdxrQsktPPBA=", "FCZsEFXouy+xtxv8X7VroXtvPG1Z1HFHL724tz1jcUI=" }, - { "+GwxMmD2dee5+QmvXNI0NdP+rNWoSXTN42otbp0aZ24=", "Y0N44baz9ihclCUnv6rRbDqCYu4BxQlBfNnTz3NNe2A=", "/LqSgkVQNkQ/oBiZSgpM9Rw7BJv0RvRpEQpvlizvHy0=" }, - { "8FREpCtncOcT7+W2nW4aYSjmSbADtVSH9rIliQZZUH4=", "fTNSd0JeREhXmPfjrmrAu6Lu/yHkB9GyxR3SyO4kZ28=", "262KN/iG/iJEaZeerFm1yVtvhFVGgQFwSvtxTcjZzeg=" }, - { "EDhaRQGtscjoSE9wJOnSXoQVtVruIqyzknty+x/vDWo=", "eMmMgws6ZxDIxZ6QSwGjZO1Mx/r5T+fJjSTKGMBk/BU=", "0CyaJV6AG9bZ0C4yeZ/RDsOs9BdNqZpUxAsD30WmJO4=" }, - { "CJV0UB2YdvVDG1cs4oiJgHAS+f1FocGr/vGCfiovsWQ=", "9/O9GWZEOXVm7On8lftL27PffRORju8OKl6gZd/74CA=", "A+kXRVNOwIrA5DUa+3v7dpRC+Gbxm23LTiYmOUAXUyY=" }, - { "gCjDsJUwZGA7BjYVoCQsvdIgN9Q4lBHlSyKwUrl751A=", "HRwS8T9y2qPYk7JVU/8Y+6cS+Bk8XCLCXxwN/ttbQiI=", "iFotjA6rhUfkDv4S/wspJgEWunEmrlGSGsXcJ0+8laQ=" }, - { "6N5pL4gsuK+shHpDxirTnAGdyKXIlYHyfIhtB0njJGA=", "CVZvW7NaN2XMEEKHodghBA9hLCwee/jrmttiWh/CmEg=", "OpPEd3Sp8r6KdjNDTN4bVHETlGJ92BCK74FCdEaDe9g=" }, - { "UIPPTUdvhlg8qEDv6JRxM4/8F5ORjJz4ud82QZrgeEY=", "7Nd13z5EpB3ChytvQC1CxvDY7n0H8r2Y7lzLEY8hdEk=", "b22PvgU0M2QfNC7ZGN+RXNe5fjOzMsY32IcHTwLNIqw=" }, - { "oBn53Q5fmxKX02PgI6F47Rb+XoLeFQO07ok2tYhk0lE=", "e0gtPDKXCZSoNW1uHqBPQXLfiYgyeqPMU2zZJgPXACI=", "wmjW2wDT2EzFkyaGui7YWNLTRu8Q4eD/GVKM2utZkEs=" }, - }; - gs_unref_ptrarray GPtrArray *allowed_ips_keep_alive = NULL; - gs_unref_array GArray *peers = NULL; - NMPlatformLnkWireGuard lnk_wireguard; - int r; - guint i; - - allowed_ips_keep_alive = g_ptr_array_new_with_free_func (g_free); - - peers = g_array_new (FALSE, TRUE, sizeof (NMPWireGuardPeer)); - - lnk_wireguard = (NMPlatformLnkWireGuard) { - .listen_port = 50754, - .fwmark = 0x1102, - }; - _copy_base64 (lnk_wireguard.private_key, sizeof (lnk_wireguard.private_key), self_key.pri); - _copy_base64 (lnk_wireguard.public_key, sizeof (lnk_wireguard.public_key), self_key.pub); - - if (test_mode == 0) { - /* no peers. */ - } else if (NM_IN_SET (test_mode, 1, 2)) { - guint num_peers = (test_mode == 1) ? 1 : G_N_ELEMENTS (keys); - - for (i = 0; i < num_peers; i++) { - NMPWireGuardPeer peer; - char s_addr[NM_UTILS_INET_ADDRSTRLEN]; - NMSockAddrUnion endpoint; - guint i_allowed_ips, n_allowed_ips; - NMPWireGuardAllowedIP *allowed_ips; - - if ((i % 2) == 1) { - endpoint = (NMSockAddrUnion) { - .in = { - .sin_family = AF_INET, - .sin_addr.s_addr = nmtst_inet4_from_string (nm_sprintf_buf (s_addr, "192.168.7.%d", i)), - .sin_port = htons (14000 + i), - }, - }; - } else { - endpoint = (NMSockAddrUnion) { - .in6 = { - .sin6_family = AF_INET6, - .sin6_addr = *nmtst_inet6_from_string (nm_sprintf_buf (s_addr, "a:b:c:e::1:%d", i)), - .sin6_port = htons (16000 + i), - }, - }; - } - - if (test_mode == 1) - n_allowed_ips = 1; - else - n_allowed_ips = i % 10; - allowed_ips = g_new0 (NMPWireGuardAllowedIP, n_allowed_ips); - g_ptr_array_add (allowed_ips_keep_alive, allowed_ips); - for (i_allowed_ips = 0; i_allowed_ips < n_allowed_ips; i_allowed_ips++) { - NMPWireGuardAllowedIP *aip = &allowed_ips[i_allowed_ips]; - - aip->family = (i_allowed_ips % 2) ? AF_INET : AF_INET6; - if (aip->family == AF_INET) { - aip->addr.addr4 = nmtst_inet4_from_string (nm_sprintf_buf (s_addr, "10.%u.%u.0", i, i_allowed_ips)); - aip->mask = 32 - (i_allowed_ips % 8); - } else { - aip->addr.addr6 = *nmtst_inet6_from_string (nm_sprintf_buf (s_addr, "a:d:f:%02x:%02x::", i, i_allowed_ips)); - aip->mask = 128 - (i_allowed_ips % 10); - } - } - - peer = (NMPWireGuardPeer) { - .persistent_keepalive_interval = 60+i, - .endpoint = endpoint, - .allowed_ips = n_allowed_ips > 0 ? allowed_ips : NULL, - .allowed_ips_len = n_allowed_ips, - }; - _copy_base64 (peer.public_key, sizeof (peer.public_key), keys[i].pub); - _copy_base64 (peer.preshared_key, sizeof (peer.preshared_key), (i % 3) ? NULL : keys[i].pre); - - g_array_append_val (peers, peer); - } - } else - g_assert_not_reached (); - - r = nm_platform_link_wireguard_change (platform, - ifindex, - &lnk_wireguard, - (const NMPWireGuardPeer *) peers->data, - NULL, - peers->len, - NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_PRIVATE_KEY - | NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_LISTEN_PORT - | NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_FWMARK - | NM_PLATFORM_WIREGUARD_CHANGE_FLAG_REPLACE_PEERS); - g_assert (NMTST_NM_ERR_SUCCESS (r)); + const KeyPair self_key = {"yOWEsaXFxX9/DOkQPzqB9RufZOpfSP4LZZCErP0N0Xo=", + "s6pVT2xPwktor9O5bVOSzcPqBu9uzQOUzPQHXLU2jmk="}; + const KeyPair keys[100] = { + {"+BDHMh11bkheGfvlQpqt8P/H7N1sPXtVi05XraZS0E8=", + "QItu7PJadBVXFXGv55CMtVnbRHdrI6E2CGlu2N5oGx4=", + "2IvZnKTzbF1UlChznWSsEYtGbPjhYSTT41GXO6zLxvk="}, + {"qGZyV2BO1nyY/FGYd6elBPirwJC9QyZwqbm2OJAgLkY=", + "v8L1FEitO0xo+wW/CVVUnALlw0zGveApSFdlITi/5lI=", + "/R2c0JmBNGJzT594NQ0mBJ2XJjxt2QUSo+ZiqeY0EQA="}, + {"YDgsIb0oe+9NcxIx2r0HEEPQpRMxmRN0ALoLm9Sh40Q=", + "nFPs1HaU7uFBvE9xZCMF8oOAjzLpZ49AzDHOluY1O2E=", + "zsYED2Ef7zIHJoRBPcen+w4ktrRsLPEfYwZhWIuXfds="}, + {"kHkosM503LWu43tdYXbNwVOpRrtPgd9XFqcN7k4t6G4=", + "b8e092WT+eNmnxCr5WE2QC/MXAjDagfG1g03cs2mBC0=", + "VXz0ShGWT7H0CBCg2awfatmOJF15ZtaSMPhMsp+hc3A="}, + {"4C2w5CEnxH59Y2aa6CJXgLdDtWoNMS2UJounRCM1Jkk=", + "gC/R9umlnEQL+Qsz/Y64AlsdMge4ECe5/u/JHZCMWSs=", + "2bmL5ISr+V5a7l7xFJ695BLIJyBgx8xnxzybkxiRHOg="}, + {"KHJSzFGkXcZf/wbH2rr99SYtGKWbL680wA2AcDE94lo=", + "BsN23h4aOi458Q3EgMQsodsWQxd9h/RxqskAUpsXfgg=", + "nK4Zv34YKEhjuexhq1SgK4oTd4MZJT5gcpYvEuPjc7Q="}, + {"QGMulXJ9e3AVxtpi8+UUVqPOr/YBWvCNFVsWS9IUnUA=", + "kjVclP5Ifi6og2BBCEHKS/aa/WktArB4+ig06lYaVlg=", + "0+mmceDPcSRK3vFnYqHd9iAfY+Nyjzf/1KgDeYGlRkQ="}, + {"AOJiDD4y6GA7P7gugjjQG9Cctvc5Y27fajHz6aU3gU4=", + "gEnHn6euHtcMEwZBlX6HANPeN9Of+voBDtltS38xDUw=", + "wIH1OxgX6GLxx/bnR+t3fbmjGZDTU3WMxp7t1XGezqM="}, + {"COsls2BlCltaIrrq1+FU51cWddlmoPPppSeIDunOxGA=", + "+n6WuV8Tb1/iZArTrHsyNqkRHABbavBQt9Me72K2KEc=", + "t4baiprSO9ZbKD2/RutOY9cr+yCajQWZGCTnQdrFQj0="}, + {"uHawQq2BRyJlsTPoCa+MfBVnv4MwtRoS+S9FEpFOEVg=", + "8lcmr27afeb6iI3BQCaDtvalF2Cl7gxRZgs+nyJ/fEg=", + "Eh9o/6W60iujBLIHuRfNrPhOWAn7PambT2JRln9iwA0="}, + {"yL7hmoE/JfRGAotRzx9xOpjfrDA3BFlPEemFiQw40Wk=", + "BHK0PHi5kp7rOfQ46oc9xlVpB+pZeZYXTtH7EXr5TwU=", + "BS2h2ZZyW0BlYMmLR29xyHEcZ4jtO7rgj1jkz/EEaxU="}, + {"ON8YrTHQgoC5e0mAR9FakZ8hZ/9I7ysuE21sG546J1Y=", + "Bm3l5I6iH1tDrv6EgdZU9PzHqp0H26Z6ggmmIypwxy8=", + "qKVfbCnK1EI3eC28SsL+jyBnEnIF/nRJQJzDevBFdNQ="}, + {"KGLO0RI0VlQFCG+ETUqk25HdaKUnUPXKOKkTh/w8BXU=", + "sBDBwQFC7k8UMdMzuavKBkBjYYKigzvYmGF5rm6muQc=", + "BNfZF9d7540pUGGOQCh3iDxAZcPBqX4qqM00GSLPBek="}, + {"KGdWyEodIn7KKI2e4EFK9tT6Bt3bNMFBRFVTKjjJm2E=", + "lrbjU/Xn9wDCZQiU8E5fY6igTSozghvo47QeVIIWaUk=", + "LczqW48MW8qDQIZYRELsz/VCzVDc5niROvk7OqrTxR0="}, + {"wO3xinUGABgEmX+RJZbBbOtAmBuPPFG6oVdimvoo90w=", + "dCIvTzR6EerOOsRKnWly1a9WGzbJ4qc+6t3SSzLgWFk=", + "wFj0zpr5PadBoBy0couLuZ1qudZbXLbV/j3UT+AyKeo="}, + {"+JNOBlO4tp9vvQk6UO4r3sILyEgjl+BBoWketZufyn0=", + "Q6LSv9y7YQkJEzQ/1mpjJEgOrO8GYPUTgcizjh7Cm34=", + "kg7AG9MuN04xPJ5Z0IcNZ4a8d1b/n4GsGIeyA4FaaSE="}, + {"+EJcThLRwjZ+h1CNNFu15HWzznf4u/lPVw8hifTm2Ec=", + "Kkn2jFqwBzyIFQfD0OpmePFSmBYmhKagv4pGgkqsWgE=", + "jYpxojj8WKYe/XIXMP+uv1Fv0+TKrs83tqfzP0AGdcI="}, + {"+DKFqSMNFmxriEFj3qatuzYeTJ9+xWYspZ4ydL3eC0Q=", + "3o37bsg6HhRg/M9+fTlLcFYc2w/Bz9rLQySvvYCKbRE=", + "Jb9qoDIBat1EexlgfpRbXa7OflptME8/zt93bldkiVE="}, + {"EH3MjFOMqRoDFQz+hSlJpntWBeH3lTk6WPjTIQjr42o=", + "PbPewED/nxSBLdM7AXMj7uS3bCgAAg8M6F4iPLd0b1U=", + "pj4+UgOGkpJwlRvX5BRXZzmzAUnDtUtJsS7LzbcJWzw="}, + {"kL6M2KvO+vPBLEc/a0DpEHTibQ1bwaMRT9b9SkzeP0Y=", + "pS3G2bHHlkOE6UHP0qVitDuxXgjEaZTviTjNc55RbVs=", + "ZVZpWOtYqhX3CpF1kATg/38J6pvUJo8AS1sVYjs3rUE="}, + {"sFlcRLDn36fnew2Ld92IHJwnKifdS3aF1MWRPs6K3Wg=", + "OpjUOTiWExaDYULTINB4yQFqc3mnU3RjQzGRV+KtdFY=", + "of0V/uoFRNljv/XTt/tXgoquLRH93Ty0KNiaPUpEi2w="}, + {"UJ8hjDsg3jfsnnfPH8Gw9FnCb6taTuviurAfZu+kEFg=", + "3byjHksUOv8CNjGGKvHvvrJDURBhCIL5UtfZbgyVWCE=", + "9f7dbWif51gGrE7R9LeuewQSrvGFGTOB3ceJC67jSkI="}, + {"iFFPKGIfqeUKY/w72KAZSjd/PGTqCakHYBV10xMDfnI=", + "ehneHATNSXtsJTOiPjVSc0QARkihgcfcvoXKFWKfQnI=", + "yKdqDBcRwA7RCg4GiY/b5IsWcExPleOBde/hjxc36a4="}, + {"GDGocdPJTPUAllxQo7SpXZKqMPn7lpxQELQUX9ETHmE=", + "n0ScNEou4ekfrXRRXvcADLu2Afj8g5D3TuDP/I4KrnY=", + "8QhswqAhi/ehhcmCwQF5aSh80TvIGC/gRL5jBn5wOH8="}, + {"UCcrlN8fX2ZdNdhaEBNwktwL+H0ZO7fhaj7rgdUutmw=", + "LF8J728ilXs4TphnrgR6r0p7W3912DYnsXkGMEPQnRE=", + "cYfMjxl2REYir7frGeB0u+NHAaFYF02ysgpBhOL5ygc="}, + {"SH0657XuIiHidVmViXZF30RUWtkuWXcWWHmKZHTiOG8=", + "7k6j49W1u5qgLE5MQUc1osPVW1oPPhzjrGvJ7o9YamY=", + "dV2+7rNk/3LR2IcwYg/c+Wvzep1yjY7/u1I+nnlTQ00="}, + {"qFQWs6jzrscV42pGISQyA7JDvFFAvEQCWJi584VHD2g=", + "AT63nHKLC17yUvkR4lOVPxCr4DD3QhXmcmecOTn+Amc=", + "2Qe2fwJbFcu1CmKpktElOFkSQMqlyvlV3ZUIAd/Dcts="}, + {"6J+yLxgPwWtUbk9I3zbeD8RuK6XkQjJ0wTJ1zSVhflQ=", + "NJzMBYyPZjk3eLmgdKaOeWyNER5YZF1mR8Umeiu9f28=", + "pp+4+XHw5ZmHGJ7WbZ1xLYRsnTI17QIbb0bzHzYZrBs="}, + {"KJGoWYNVDUWcEMg+E4tljv1LiWAbdRw2QVapYqdFa1Y=", + "M2SGk9WVnzYNGnT777G/JE8uUsY2f7mszTwlue73UDE=", + "Jg8N7GbhbYB400foFP+OH0v+hCaL1jW61bajSA6EZqc="}, + {"uAgrgppPyIvk8S1CHUmaCaORsgFFfBreB8pxXmbSdXw=", + "dJ22bER4fD3qF2/yIGWQ7SgmZ990sy/SbANjmUMkzws=", + "mKkd0OoAR9sClmD+k3fL9weBsoCy5GQGz9BP0kAQIjc="}, + {"EI3Q8gePNPrtFyoMcv7hOihQgroF/dfjzPn8yvpGPWQ=", + "Y9QhJFeiyuuIZNPU56B6U//ZK+XTTe4EP7h/p3Q+dE8=", + "qBVUYw9rTWaxn55nUd55NpCWtxOUSWLt4WJGusiDS8Q="}, + {"oEQvdRm/yHkx+JvlhHGT5RUFrFEUleKb9DCT55EqZ30=", + "8hsh/UHwWADTHntOJq4dy0o7ahcNAAlo2rDpjzzrVXk=", + "/GF2inW2mPtA26IgFdgOEBbBEerT740wWuP/8NyANdc="}, + {"6OWrGKZKNsgfRezSUw29EnHymcgKyEKvX5/pZQlLmWs=", + "oaJeO6YSS2dodNEf97DvgWrYnFFelG5daEdN84jVVGw=", + "T5wvTdyVxK0LY96kouLjs06oUfhGChfty8OUL1Mddro="}, + {"mPmzQbh2R+r1DC5hSquzKM1SDrxUdfnBPRPJrpqrgkE=", + "BtUHAnYWjDjBI42qBf9dJqezTUikYsF96o6PKEWPrVo=", + "MxU8EMmq+vVHpuK/AkFZrZDF2b+VbSqukZLPbNsCcgo="}, + {"8GVxuoo1Veyr+nqxr5Q4vmsMf5qfiXwSlQ4q3+BU60g=", + "uSOLe/E9/OjIgUOk0NMBHB45E0+q4Rd+IUO2UOxmKlM=", + "+30F+56OE0Sr3wY2clKw4kgE+2XiucMg7xjK6EemXuk="}, + {"qORPKb+qFuU/9TpFbRUupHsqm9iyk9pa6cpik+EVDkg=", + "bMZxxd+Z9I0XA1h9U8JEY+/mRxWGnvbXDZ5Dxz7YzS0=", + "SmkkqOz4OhHuSL6cxuRm9+Mlt50Sfd0sMDFTC78gqOE="}, + {"2Ko3IYhXKcdOMIJGNpASk9saNSZsI64lyJPOoxpQ2kI=", + "xVOc9PxY1VFaZfemmKi+Ei2liHhmeTu+JMa+rS00gnA=", + "+398DlW8kWeI2aRaC4QfcrEjwqPKCohyDeWdaI1wvv0="}, + {"CPioGCVpxnym62nH/QoCt1RiiaaxUcuFjvh5kRhjqHA=", + "W0XxlBLrZgFKhggMvvv6oFf/RJbfs92qv8JK9e+5i2o=", + "bsK2U6CRAUv1uVgYQ7NpqjWWswFIDiDPDEtU1XQygSA="}, + {"AF17siKaeiO85hikYN0IWCMGWqPm1UOoCkXMltJGUVk=", + "B+PFos9aN2S5bLxzGZHljRZj41j3rIx8RWu0vDUzq1w=", + "Qb8d6iDYv3m1h7PE8j0Exl2cSwpHkim/fJ1S4P7MYvY="}, + {"wMFDBTJzx5tDCBhMkrptYJ8w9EeURjc4xeDQpevxAWo=", + "4ec439EXE5WQzvtV9reSX+aMmdq5k7o9Ayt8oQp+RhQ=", + "jwQlvdNH5WtSSU10H+fh/JisOlaBaohDPEp/BYnTt1Q="}, + {"4GaJpIFigNDwd31O84pLIMM/o2qhp0ydlI/ydD/2a2Q=", + "r/LdkCoK5/BPGdq2+XJO8sCRhI+8ULFmg0887V43PAI=", + "Da+3ZZvEJdx4TYFMIDUlbkmytILnSTNxTKX+sQdjMd4="}, + {"gMnojGqCLmMfGp2m31xlKZ/rIV2b8ockw9DPahRyu0c=", + "H6tKCTosnM4BXKqflXrkTdJyNlCIZhQ3ZRxfrvSdrDk=", + "4Z6K3LKIMV89plcjMb9CzSzJl03SWRe/++geBMZcOtY="}, + {"wKCg22aNNoHnDJ0oAKE46FcSSsREW4AaGn5WxCSeXUs=", + "9NDTFC0iPt4HbbWepLHhN5poNTN2fdxJKNadsNT7qzY=", + "GSVTOCnfLpJ1VCOLHaKSjCMv7/OlcnQiP5+5woqkud8="}, + {"oCoykq7pcJcg2X2V5TBRzGwn8hzzHC05WUreuotdznY=", + "DxfwnbMqr5Wn5SAyFolfEmNQT6l84Oq69ngpg6H6Iio=", + "p1RHBuqhuDa1MAQ2lbqmUQFu0CTwYlf73fWZSj9tQhA="}, + {"UO7YVyRUVkcKr7c63VWWV2zj36XD3HyDfLZCqvrZmFc=", + "360lzYtIyHq5lv/QXSCe4bL4G2J1jBXFJ8yS+Ycr7Bc=", + "RRPQ1XWF1HN8Us4dtfn2eemdjgtWm7U8r7mM3y00NOk="}, + {"eCGFYV/NuGP4H552E8Of1xU+3IvZxGyX+p5UFGW8iHI=", + "LqhZ4AS9dQ/MhsQnE5Oy7Q8INXY+P+mrfGY5dtg9SlE=", + "SICfqs8T5wP6IzATDCT4ovamBKPdkZ7JP4Cfsb3izec="}, + {"oI3HBZknoIMMZw1BuYMkTBylt25reX7AbCqtWQv8cno=", + "B7dUgLgvQhi0RGmvaMrmf26WdjEVrhaiBclVkCKd4AA=", + "5O9K9pLXwxFAt5lfMWh4qGbwX1BM7sz0QGYxAnR77dk="}, + {"sBfYn14EFVIS2M/E1aahP7mOmRNbNtyDChDMS1s6aGs=", + "FLYv0ZvzxMkc9A7OzhC4P1ZRu1aKIQd7u6gqfdekC3c=", + "kaYLcNCXnCLgiB8fleMQuboUJsj5u3YAmXL9x3ywV0M="}, + {"qFwZESU/XYZXUtxwrGsFU9qPAFTzjm7EhTS1Q6ajGlM=", + "hraQQaqJCkS2yQXv+ccMOVh9V9a/qgSZJgdMAhrt8ms=", + "72oDfnWOn39gdk/ncw8Lv267I0I+m73SwxrpYojpWYk="}, + {"YHhp6Zf/miuc2QXeI2lTezy0lL0pTv2b+nWNkmjYQWI=", + "UhNO5arLzF0WlZSgNOx7+IjWN+GSxDdQxZRp8uIwsyI=", + "1Q39Nzv2NGI9zWKWMpYLURAMZUg+FP+OboHHzFU8Anc="}, + {"mLBBXKaCJ+7qeBZpS3wxGi/SQ4kLzun+K+QwwdwfJVQ=", + "gIq/nh7NwCJ36MvRnyrWHaRWu8lTmwfN2NvsjVl6SXQ=", + "AahcNR91GDyJBIP+vC8ZuIV8ukqjSGtd8s+cmjVC2Ao="}, + {"OJG4LZlNNngFtAEQdbVVWVm6QAjOOauGcMZGbQrb40M=", + "pFHAC6HaWAOtvTRRVfSHvzG05mp4SJZXKsN/tkSF0kM=", + "IoXT3wIqWNxQhYuHWl12ODq/P7RM9LwaqglhmjKg+0g="}, + {"OOwBFOQNhepiqDf04DehQLh1gpBNOluDF1ia752Yfng=", + "u715uJ/XhdjXjThCTJ9w6zzXnIhp3VCxhtso1wk+oBQ=", + "5x1Ip3Ym0KzDjGhiYjmpeWWr+dgrZlYwfr02GngPOTM="}, + {"eNPFnwkQy1qw+IjFAlrDA6+sIsxbWDlzbNSsBW8R1UA=", + "OaOXaAfPb1MRpWadawFje8YZ0oxJgdCIDIP8c5X+r1U=", + "NtfaRRD0GqujnaQQoNoBbtovgO4dfVwEmEQx/YgnDpw="}, + {"OLdaZItbtxH3mGqItkibIJp7KV27FrQavjhd5zq6s3Q=", + "SLSmAYxkMCGj0DO35cMLkC3NVAqK2VmVFndbOZEdA24=", + "SnBO68XQTDjxYbmYaAeEHgLwD2u4D+BPT86raRuUQZM="}, + {"UBQOEz08izwr4eEK/SnQUpkt+TxCjo6Sya/XOGMLOE0=", + "wQwrwezI9LzKevGsJJCBHDG8noR0yIEtOK5Rig97SSo=", + "DpyS+0d7lrlFWkztsniG2v/j44vcuvWz3sPeghRyb5A="}, + {"mN98iuqUKh67ggUdq9ZIQNZCZM90fgycTVqYKEo+DkY=", + "GYdXVW1jpS0dN1q9zMehubP7LfYqs34kszN0bXQqxxA=", + "AJPIHffB4uvvJJki4xCG0VORVBbF6bc2mZQqUx+idPc="}, + {"OEd/1it8C3o+NOWxDI3DfLMXVBHJQg15N3E8F8d99l8=", + "QL1NcuUkoXxDy7M9VjGslCejcUlnUDHRghFVnr+8fmA=", + "nven9Dicl8U6QXuDO8rRNtjd4NYaa90SU+Gmv435XKY="}, + {"AFMCGDu2oAP68miucsi4fmYX2KeRZnsEGv8tQm8JEng=", + "1sNxvk8uZhFsBUgxOXmuCMjDAgBbjVeWe9oaFk5Osy0=", + "t5iI5XXd56S5q0Y9HC91gzgF9uGjL9FIy6NUaKqkydo="}, + {"CIAwfJghQHHr4YlztN9at6/iWkrEVCGFAxNVuQCuT3I=", + "zpUOF1h17g7RpBzrVlN7oTRz6e+dxcDL8OsAtHwgLC8=", + "kOSwC1p6Uoti9E9Eg7ViPZwCytuvp5Fr5Buw677aogU="}, + {"sC8vrAVBU0zvhWDRfzfySjvopXm2/cTMkTLmioyO3Es=", + "p6H7GWm8NfgyO5OCX/COjvVT4MAnTs9ZUj4uZMK8XHA=", + "9Tzqo57V/h7+6nSNAHSBKdmU7ultlvZbAnNKSRlrLi4="}, + {"eI63gjxCZGnzqZxPEi/ifYphXhxIRI2ZxK8jzqo3mmU=", + "XyNzEuU9x37fxFCnrZH89Krs5/UqGVx5wNkGfQCAYz0=", + "vZ2fTlRPnJQ+q33YdS5p1aweqPGj/kTMc4Uq80FtFjI="}, + {"aNJlGtm79/RS4SQ/PC4YM6LFo9zAqDr2/RjLqk/z/1A=", + "lgZ9akPrABmfHQMlfNFnnpAJzGtcsaU9mUjEYKfzZHc=", + "d0Xt1Bcgphd1HMI0RneA4VdBbMZL1qNGJAvFhb080eA="}, + {"oONSnHirNh3cuH93Ty0C9AXKebGY+cdF3R0DtPzIQlo=", + "TuREKfA8EVQiYWsPx8veUzjN2cz/b72limSLWlrCWxw=", + "vEqqKbpZf0EM6EApMUaUH65r3Zr81Y/DSODhE4H7U3Y="}, + {"+D6RyLEaHJ9YF9WDyOlwh87KaNJcc6lqX8Arp6yqHF0=", + "EpecjfIo1/EEbmsgUtzEDqLu2ut+SMmzqaBL9Z/MlCA=", + "oYfO6/7XQgEYT9zmr4sqFrk0muK/fEv3FfD8MzZzjkE="}, + {"OCmW5KQql2PRMJnsMYQjXlr6TSYUbxJBknqZtXJPSHM=", + "ZZR2ghHlCwAJu/XlsEZuNS6XiGPwuXzyMPPywYFapVM=", + "fqSCXq+pKJJ6yNvlOi+tyQ9E4Y6kc4kblGrVqN2WuXA="}, + {"APWXDAe8d2ia1CUbf/IzSPXOUjR8TVuJgmISiWw0/EY=", + "jrT5P5YCkG+U7cfNTvCKy0GSEgsjwmJtHg+8HBP6ZCA=", + "t75aUjZXMPir8Ao0yhVClh9/BdWxSL+11CjK3iELNWk="}, + {"8Nw4sRis7M/6Om+3w5YHXthyMzLGuP48teqdzbHNPlA=", + "lj3q3ZYij3ZJ/QunK8n9I00cv/Z+O1TU1kFFl8x3DTE=", + "adqB79P7gbXEYYnSd1/UPCwFffTAPXa9kHWynRBYcGo="}, + {"yOupps5XbjV0fIZKnGhrpcxB7yDQzbBILC0UMJyVS1c=", + "+MDV/t9UCIdgm3IkH3BZlxaRPJ3lejRmrm4UPApq4mk=", + "AOJPmQxsU6hjOd+9mHnF0VL7Afih3P1Fr625xFT4FtY="}, + {"cD2DEl4MBwONuTV0db5XreoVjQAUZFNXqIeFEU3KFkE=", + "2CeHrjN7tBX48k4Sgv5fIHG06e57q/ucCL+8DIRmfXw=", + "3EUo6MRzs6rSoY/7AFs8wiBiTXPcHzerLh6Xp3aMGKo="}, + {"EA+S3a9ZeOLiRbhTxaT2wkpyDheAmai+UJa6SFGzSm8=", + "GGByUKZx/FPa2OkJoqVTHXx+6jrIpIw5rf0rp43MHko=", + "BXoDA3yn0JcMV7hHVzEqhlwAORvhToFO1qG00nas92A="}, + {"eBeJi/imBiV52WEqrwAprUQggqdQmvTTmWtLq8pDDkM=", + "zCX26ZTOZHLpq5x5aIUL1XhIVoXJLp/zcXwnmFA3jBo=", + "Dm/DCxXWYXEsmQgxAD3KREK2PF0bUSnV5WRAaya8s1I="}, + {"8C7p+EQO+CnWUSjHVu3PpeWpUIbLy48zpftZu021plM=", + "DxpnF/IbKAh6kmWC5Jpj8iw387EDkrvjsjOb9fbTSng=", + "bGrk0OshJB+0oQOK0QGKU8+lotnIDz3oeUnMZGienyM="}, + {"COIez7YcBJiOJCLxxWV5UGLW5/o009YI0aszlD/PiUc=", + "eD9USWV37LFIOxlDSHyOmfFqNJFpORRlzEI+HoF/czI=", + "n+/ra86gUSF2pNZS51nt2JgrzXnQJl+dWswOq/Ahs94="}, + {"iBBSTG9VLC+T9+ahNaQ4umZoig8o7w1DaeOw+cD2BGc=", + "XnAxqDlvGnQ6aakv8ABGHVj07qVQfk4NChZbstTMBxg=", + "7KKSwu/4yWr1UzFmNMGtiaSwdYMhP/HKbrQLlABL4UE="}, + {"eNmwattflehr9+KsVqTuwt1YaAc5ONkaIaTQt9Gkhn8=", + "1NNVvm++YTTGMKyAXfGOCZ4aDDdFFH5Um3vAg4XimDo=", + "bXNrnDTP0pBay9ytZe7xpiKoSi12F7WUXqoIeI++Xvo="}, + {"QJotpmZINx9eptKpkh9j3JlEDcHdWnjEbicdBS7gPXM=", + "3gLYKeoruVZ/AYjym0gciDvRHj45UIWyHhNjWj2Wj28=", + "NwuUkkE5yOWT7wed7bltgAk71miz3cSooiIDAdv6kKw="}, + {"OAYGuxH70OPQvhVIX4BhSCWUyzAI5H2IkYxKgC/AO0M=", + "Rj9iNF/FagkXfdLPqc9LHfaoGR8GlvY3gun2FilE508=", + "hkNXLVMlBRsMEaQKkSzevcEK2sMu0AShGKQJMNqdzWM="}, + {"uBrgZ7wLHrOV/0dNiEqo7FjY9VnJqL5eUDHJWAc9QXg=", + "3Hnln8ZHfSaK4OzESJe5U6NcLaW56wzfZICzvzefnSo=", + "DhXsehe5FAmbUidXT5ZpZIAuu1eF9rkU6cF3FBoKwOE="}, + {"sJknn3CHvx/812EWU3ddLdLLZFBKsc+wx35GXyiRsHY=", + "qqa2dNSt0jWozGyqpokP392H5/DOAUUZmUpyZDaUEEE=", + "1Dyz8CvmF17oKT/wG2fu3vRzPzgQv8/OY9GJYew4FG8="}, + {"yOumS9HN68ZwIm+5hZol3jFQ0DB4SKuW/ld3y8wioGk=", + "6PowsbKj/fKSzXZMAfaSkP3fE+4AThL9xm6ysQzMDxg=", + "vF8cKu9X9FxgCjyVZ5RG7nuue8RelF5Qsb8Efme4M4A="}, + {"mISm5vQfPdK72SsaHh6O1/ARvaWCtm+KZNcpTsyt500=", + "YCORDQDpb1U8vADdstBgXkg0N7QaAc5VoXJ4QFuA/UY=", + "JlrBmfaCgbfEVD9YQq3c03WwwsHWc1nBwp1JkFORC3A="}, + {"cPyu3Qry6qbsiOJKFGRziZ9LJWJ47k3ZSXiGkQXuQm0=", + "/cmBZTbqEp8sababPAxGb3OvDAEE7MlwPOwEFHE+7yM=", + "lp0Hhc/rVtpT5FtLLccChqDl3El48XtP6Wm6JwjI7jo="}, + {"YKsMYU0SINbPwWw4RDCJV6GnzDlSp1ZNwUw2euGWi0A=", + "/KmBReATQbFnLg8YKV0jwhqKeishRoWvlVtMX3550Vk=", + "7fXpPSMo1Fw2sOXtjTtvFU+DbZvS/FWB9wAsywWx6R4="}, + {"WD0YI3y71eIp/GXw9i+7scEiQKSBkGihZWE+s6fGmWo=", + "RdthAL/qPnAZFb3xBgRMiAtGHNjgokzoKX9iO2K5qhc=", + "4dk4HGkT9dBmomGNorDE/hLr/HEFhljtl4zz3M4sG58="}, + {"oD8KWhJYZVhutJRb0kZlZnB22QUXzi2FfPRD0ll65UM=", + "MYTBGHh4Ukj97pKj6qcfWmxGNQzmU3/aBOX2f1tfhG0=", + "VT1gC+a9nRJzYMi/TPvRVnn3IQlaop/jKmmxZePEME0="}, + {"0Ns/1SOiqR2CpHRG03QNzJJd5gxTm1XJmSkFlugjQ3k=", + "KvQAI+ekNOa2xfEvfyc9JGcS+CTUrnnhsKrlyJGJixg=", + "J8LmSX6zElX3S9q4PNvh2NKUtAiQ3oHiYjSJ7yErPlY="}, + {"mD6TeF4ezSPXN/csN1OhoAREFSXllI+zl4DUOInVq2Q=", + "WmLJ9ep2EqFcSftnYFJsmWyUxqL0zzuSzVEv94PcISM=", + "U2+ILy2NDmmfgSW78C8dl8GyHESUc1lXPHPpg5F+gr8="}, + {"SMJoXOYgHz8HSzY+ByeWLcSP5qFwv7YjRe0bcKesRnM=", + "DEsNSOY3TEs9J2YgqroQ4xKq8T8xNJQjvvE4UrTItQw=", + "Bws1Hk2+lO+JQ7ME16EbwAdsBkWsGvti0Gb6LY2Lrms="}, + {"iGhXF0Hg0tqZmpwAMiolxvbvTPClQ7LlBAspSSyFEHE=", + "7Xxzpwl7yRWehHNWTYVtFkdChJdXhtY4Mtw1fA9QcCg=", + "Swjfv0PjuaE8Oq3a17BVno5I+q49dZlPwKK1bPUoKNI="}, + {"MIazjx3qTi6Qz3WzhtCPw3i4Q2uZBHcuMoh++ZGFYUk=", + "oni8pbFqk9Ya+Fx+911Nl1SN0FD/hR1jwb2RH3t/pRk=", + "ZYAFcj67LkbNURYbSnCCWGxAG8QLDGWwbl968mA6ZA4="}, + {"MAadYdiFM2cPuJF19q20Yoo5KJabuR9TUQ9jG5nvA1w=", + "5OcE8XV+UPoBVbgqBQdVF62GZCW9DOQEdxrQsktPPBA=", + "FCZsEFXouy+xtxv8X7VroXtvPG1Z1HFHL724tz1jcUI="}, + {"+GwxMmD2dee5+QmvXNI0NdP+rNWoSXTN42otbp0aZ24=", + "Y0N44baz9ihclCUnv6rRbDqCYu4BxQlBfNnTz3NNe2A=", + "/LqSgkVQNkQ/oBiZSgpM9Rw7BJv0RvRpEQpvlizvHy0="}, + {"8FREpCtncOcT7+W2nW4aYSjmSbADtVSH9rIliQZZUH4=", + "fTNSd0JeREhXmPfjrmrAu6Lu/yHkB9GyxR3SyO4kZ28=", + "262KN/iG/iJEaZeerFm1yVtvhFVGgQFwSvtxTcjZzeg="}, + {"EDhaRQGtscjoSE9wJOnSXoQVtVruIqyzknty+x/vDWo=", + "eMmMgws6ZxDIxZ6QSwGjZO1Mx/r5T+fJjSTKGMBk/BU=", + "0CyaJV6AG9bZ0C4yeZ/RDsOs9BdNqZpUxAsD30WmJO4="}, + {"CJV0UB2YdvVDG1cs4oiJgHAS+f1FocGr/vGCfiovsWQ=", + "9/O9GWZEOXVm7On8lftL27PffRORju8OKl6gZd/74CA=", + "A+kXRVNOwIrA5DUa+3v7dpRC+Gbxm23LTiYmOUAXUyY="}, + {"gCjDsJUwZGA7BjYVoCQsvdIgN9Q4lBHlSyKwUrl751A=", + "HRwS8T9y2qPYk7JVU/8Y+6cS+Bk8XCLCXxwN/ttbQiI=", + "iFotjA6rhUfkDv4S/wspJgEWunEmrlGSGsXcJ0+8laQ="}, + {"6N5pL4gsuK+shHpDxirTnAGdyKXIlYHyfIhtB0njJGA=", + "CVZvW7NaN2XMEEKHodghBA9hLCwee/jrmttiWh/CmEg=", + "OpPEd3Sp8r6KdjNDTN4bVHETlGJ92BCK74FCdEaDe9g="}, + {"UIPPTUdvhlg8qEDv6JRxM4/8F5ORjJz4ud82QZrgeEY=", + "7Nd13z5EpB3ChytvQC1CxvDY7n0H8r2Y7lzLEY8hdEk=", + "b22PvgU0M2QfNC7ZGN+RXNe5fjOzMsY32IcHTwLNIqw="}, + {"oBn53Q5fmxKX02PgI6F47Rb+XoLeFQO07ok2tYhk0lE=", + "e0gtPDKXCZSoNW1uHqBPQXLfiYgyeqPMU2zZJgPXACI=", + "wmjW2wDT2EzFkyaGui7YWNLTRu8Q4eD/GVKM2utZkEs="}, + }; + gs_unref_ptrarray GPtrArray *allowed_ips_keep_alive = NULL; + gs_unref_array GArray *peers = NULL; + NMPlatformLnkWireGuard lnk_wireguard; + int r; + guint i; + + allowed_ips_keep_alive = g_ptr_array_new_with_free_func(g_free); + + peers = g_array_new(FALSE, TRUE, sizeof(NMPWireGuardPeer)); + + lnk_wireguard = (NMPlatformLnkWireGuard){ + .listen_port = 50754, + .fwmark = 0x1102, + }; + _copy_base64(lnk_wireguard.private_key, sizeof(lnk_wireguard.private_key), self_key.pri); + _copy_base64(lnk_wireguard.public_key, sizeof(lnk_wireguard.public_key), self_key.pub); + + if (test_mode == 0) { + /* no peers. */ + } else if (NM_IN_SET(test_mode, 1, 2)) { + guint num_peers = (test_mode == 1) ? 1 : G_N_ELEMENTS(keys); + + for (i = 0; i < num_peers; i++) { + NMPWireGuardPeer peer; + char s_addr[NM_UTILS_INET_ADDRSTRLEN]; + NMSockAddrUnion endpoint; + guint i_allowed_ips, n_allowed_ips; + NMPWireGuardAllowedIP *allowed_ips; + + if ((i % 2) == 1) { + endpoint = (NMSockAddrUnion){ + .in = + { + .sin_family = AF_INET, + .sin_addr.s_addr = + nmtst_inet4_from_string(nm_sprintf_buf(s_addr, "192.168.7.%d", i)), + .sin_port = htons(14000 + i), + }, + }; + } else { + endpoint = (NMSockAddrUnion){ + .in6 = + { + .sin6_family = AF_INET6, + .sin6_addr = *nmtst_inet6_from_string( + nm_sprintf_buf(s_addr, "a:b:c:e::1:%d", i)), + .sin6_port = htons(16000 + i), + }, + }; + } + + if (test_mode == 1) + n_allowed_ips = 1; + else + n_allowed_ips = i % 10; + allowed_ips = g_new0(NMPWireGuardAllowedIP, n_allowed_ips); + g_ptr_array_add(allowed_ips_keep_alive, allowed_ips); + for (i_allowed_ips = 0; i_allowed_ips < n_allowed_ips; i_allowed_ips++) { + NMPWireGuardAllowedIP *aip = &allowed_ips[i_allowed_ips]; + + aip->family = (i_allowed_ips % 2) ? AF_INET : AF_INET6; + if (aip->family == AF_INET) { + aip->addr.addr4 = nmtst_inet4_from_string( + nm_sprintf_buf(s_addr, "10.%u.%u.0", i, i_allowed_ips)); + aip->mask = 32 - (i_allowed_ips % 8); + } else { + aip->addr.addr6 = *nmtst_inet6_from_string( + nm_sprintf_buf(s_addr, "a:d:f:%02x:%02x::", i, i_allowed_ips)); + aip->mask = 128 - (i_allowed_ips % 10); + } + } + + peer = (NMPWireGuardPeer){ + .persistent_keepalive_interval = 60 + i, + .endpoint = endpoint, + .allowed_ips = n_allowed_ips > 0 ? allowed_ips : NULL, + .allowed_ips_len = n_allowed_ips, + }; + _copy_base64(peer.public_key, sizeof(peer.public_key), keys[i].pub); + _copy_base64(peer.preshared_key, + sizeof(peer.preshared_key), + (i % 3) ? NULL : keys[i].pre); + + g_array_append_val(peers, peer); + } + } else + g_assert_not_reached(); + + r = nm_platform_link_wireguard_change(platform, + ifindex, + &lnk_wireguard, + (const NMPWireGuardPeer *) peers->data, + NULL, + peers->len, + NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_PRIVATE_KEY + | NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_LISTEN_PORT + | NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_FWMARK + | NM_PLATFORM_WIREGUARD_CHANGE_FLAG_REPLACE_PEERS); + g_assert(NMTST_NM_ERR_SUCCESS(r)); } /*****************************************************************************/ typedef struct { - NMLinkType link_type; - int test_mode; - gboolean external_command; + NMLinkType link_type; + int test_mode; + gboolean external_command; } TestAddSoftwareDetectData; static void -test_software_detect (gconstpointer user_data) +test_software_detect(gconstpointer user_data) { - const TestAddSoftwareDetectData *test_data = user_data; - int ifindex, ifindex_parent; - const NMPlatformLink *plink; - const NMPObject *lnk; - int r; - guint i_step; - const gboolean ext = test_data->external_command; - NMPlatformLnkTun lnk_tun; - NMPlatformLnkGre lnk_gre = { }; - nm_auto_close int tun_fd = -1; - - nmtstp_run_command_check ("ip link add %s type dummy", PARENT_NAME); - ifindex_parent = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, PARENT_NAME, NM_LINK_TYPE_DUMMY, 100)->ifindex; - - switch (test_data->link_type) { - case NM_LINK_TYPE_GRE: { - gboolean gracefully_skip = FALSE; - - lnk_gre.local = nmtst_inet4_from_string ("192.168.233.204"); - lnk_gre.remote = nmtst_inet4_from_string ("172.168.10.25"); - lnk_gre.parent_ifindex = ifindex_parent; - lnk_gre.ttl = 174; - lnk_gre.tos = 37; - lnk_gre.path_mtu_discovery = TRUE; - - if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "gre0")) { - /* Seems that the ip_gre module is not loaded... try to load it. */ - gracefully_skip = nm_utils_modprobe (NULL, TRUE, "ip_gre", NULL) != 0; - } - - if (!nmtstp_link_gre_add (NULL, ext, DEVICE_NAME, &lnk_gre)) { - if (gracefully_skip) { - g_test_skip ("Cannot create gre tunnel because of missing ip_gre module (modprobe ip_gre)"); - goto out_delete_parent; - } - g_error ("Failed adding GRE tunnel"); - } - break; - } - case NM_LINK_TYPE_GRETAP: { - gboolean gracefully_skip = FALSE; - - lnk_gre.local = nmtst_inet4_from_string ("192.168.1.133"); - lnk_gre.remote = nmtst_inet4_from_string ("172.168.101.2"); - lnk_gre.parent_ifindex = ifindex_parent; - lnk_gre.ttl = 39; - lnk_gre.tos = 12; - lnk_gre.path_mtu_discovery = FALSE; - lnk_gre.is_tap = TRUE; - - if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "gretap0")) { - /* Seems that the ip_gre module is not loaded... try to load it. */ - gracefully_skip = nm_utils_modprobe (NULL, TRUE, "ip_gre", NULL) != 0; - } - - if (!nmtstp_link_gre_add (NULL, ext, DEVICE_NAME, &lnk_gre)) { - if (gracefully_skip) { - g_test_skip ("Cannot create gretap tunnel because of missing ip_gre module (modprobe ip_gre)"); - goto out_delete_parent; - } - g_error ("Failed adding GRETAP tunnel"); - } - break; - } - case NM_LINK_TYPE_IPIP: { - NMPlatformLnkIpIp lnk_ipip = { }; - gboolean gracefully_skip = FALSE; - - if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "tunl0")) { - /* Seems that the ipip module is not loaded... try to load it. */ - gracefully_skip = nm_utils_modprobe (NULL, TRUE, "ipip", NULL) != 0; - } - - lnk_ipip.local = nmtst_inet4_from_string ("1.2.3.4"); - lnk_ipip.remote = nmtst_inet4_from_string ("5.6.7.8"); - lnk_ipip.parent_ifindex = ifindex_parent; - lnk_ipip.tos = 32; - lnk_ipip.path_mtu_discovery = FALSE; - - if (!nmtstp_link_ipip_add (NULL, ext, DEVICE_NAME, &lnk_ipip)) { - if (gracefully_skip) { - g_test_skip ("Cannot create ipip tunnel because of missing ipip module (modprobe ipip)"); - goto out_delete_parent; - } - g_error ("Failed adding IPIP tunnel"); - } - break; - } - case NM_LINK_TYPE_IP6TNL: { - NMPlatformLnkIp6Tnl lnk_ip6tnl = { }; - gboolean gracefully_skip = FALSE; - - if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "ip6tnl0")) { - /* Seems that the ip6_tunnel module is not loaded... try to load it. */ - gracefully_skip = nm_utils_modprobe (NULL, TRUE, "ip6_tunnel", NULL) != 0; - } - - switch (test_data->test_mode) { - case 0: - lnk_ip6tnl.local = *nmtst_inet6_from_string ("fd01::15"); - lnk_ip6tnl.remote = *nmtst_inet6_from_string ("fd01::16"); - lnk_ip6tnl.parent_ifindex = ifindex_parent; - lnk_ip6tnl.tclass = 20; - lnk_ip6tnl.encap_limit = 6; - lnk_ip6tnl.flow_label = 1337; - lnk_ip6tnl.proto = IPPROTO_IPV6; - break; - case 1: - lnk_ip6tnl.local = *nmtst_inet6_from_string ("fd01::17"); - lnk_ip6tnl.remote = *nmtst_inet6_from_string ("fd01::18"); - lnk_ip6tnl.parent_ifindex = ifindex_parent; - lnk_ip6tnl.tclass = 0; - lnk_ip6tnl.encap_limit = 0; - lnk_ip6tnl.flow_label = 1338; - lnk_ip6tnl.proto = IPPROTO_IPV6; - lnk_ip6tnl.flags = IP6_TNL_F_IGN_ENCAP_LIMIT | IP6_TNL_F_USE_ORIG_TCLASS; - break; - } - - if (!nmtstp_link_ip6tnl_add (NULL, ext, DEVICE_NAME, &lnk_ip6tnl)) { - if (gracefully_skip) { - g_test_skip ("Cannot create ip6tnl tunnel because of missing ip6_tunnel module (modprobe ip6_tunnel)"); - goto out_delete_parent; - } - g_error ("Failed adding IP6TNL tunnel"); - } - break; - } - case NM_LINK_TYPE_IP6GRE: { - NMPlatformLnkIp6Tnl lnk_ip6tnl = { }; - gboolean gracefully_skip = FALSE; - - if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "ip6gre0")) { - /* Seems that the ip6_tunnel module is not loaded... try to load it. */ - gracefully_skip = nm_utils_modprobe (NULL, TRUE, "ip6_gre", NULL) != 0; - } - - lnk_ip6tnl.local = *nmtst_inet6_from_string ("fd01::42"); - lnk_ip6tnl.remote = *nmtst_inet6_from_string ("fd01::aaaa"); - lnk_ip6tnl.parent_ifindex = ifindex_parent; - lnk_ip6tnl.tclass = 21; - lnk_ip6tnl.flow_label = 1338; - lnk_ip6tnl.is_gre = TRUE; - - if (!nmtstp_link_ip6gre_add (NULL, ext, DEVICE_NAME, &lnk_ip6tnl)) { - if (gracefully_skip) { - g_test_skip ("Cannot create ip6gre tunnel because of missing ip6_gre module (modprobe ip6_gre)"); - goto out_delete_parent; - } - g_error ("Failed adding IP6GRE tunnel"); - } - break; - } - case NM_LINK_TYPE_IP6GRETAP: { - NMPlatformLnkIp6Tnl lnk_ip6tnl = { }; - gboolean gracefully_skip = FALSE; - - if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "ip6gre0")) { - /* Seems that the ip6_tunnel module is not loaded... try to load it. */ - gracefully_skip = nm_utils_modprobe (NULL, TRUE, "ip6_gre", NULL) != 0; - } - - lnk_ip6tnl.local = *nmtst_inet6_from_string ("fe80::abcd"); - lnk_ip6tnl.remote = *nmtst_inet6_from_string ("fc01::bbbb"); - lnk_ip6tnl.parent_ifindex = ifindex_parent; - lnk_ip6tnl.ttl = 10; - lnk_ip6tnl.tclass = 22; - lnk_ip6tnl.flow_label = 1339; - lnk_ip6tnl.is_gre = TRUE; - lnk_ip6tnl.is_tap = TRUE; - - if (!nmtstp_link_ip6gre_add (NULL, ext, DEVICE_NAME, &lnk_ip6tnl)) { - if (gracefully_skip) { - g_test_skip ("Cannot create ip6gretap tunnel because of missing ip6_gre module (modprobe ip6_gre)"); - goto out_delete_parent; - } - g_error ("Failed adding IP6GRETAP tunnel"); - } - break; - } - case NM_LINK_TYPE_MACVLAN: { - NMPlatformLnkMacvlan lnk_macvlan = { }; - const NMPlatformLink *dummy; - char buf[256]; - int i; - - lnk_macvlan.mode = MACVLAN_MODE_BRIDGE; - lnk_macvlan.no_promisc = FALSE; - lnk_macvlan.tap = FALSE; - - /* Since in old kernel versions sysfs files for macvtaps are not - * namespaced, the creation can fail if a macvtap in another namespace - * has the same index. Try to detect this situation and skip already - * used indexes. - * The fix (17af2bce) is included kernel 4.7, dated 24 July, 2016. - */ - for (i = ifindex_parent + 1; i < ifindex_parent + 100; i++) { - snprintf (buf, sizeof (buf), "/sys/class/macvtap/tap%d", i); - if (!g_file_test (buf, G_FILE_TEST_IS_SYMLINK)) - break; - - _LOGD ("skipping ifindex %d as already used by a macvtap", i); - - dummy = nmtstp_link_dummy_add (NM_PLATFORM_GET, FALSE, "dummy-tmp"); - g_assert_cmpint (dummy->ifindex, ==, i); - nmtstp_link_delete (NM_PLATFORM_GET, FALSE, dummy->ifindex, NULL, TRUE); - } - - if (!nmtstp_link_macvlan_add (NULL, ext, DEVICE_NAME, ifindex_parent, &lnk_macvlan)) - g_error ("Failed adding MACVLAN interface"); - break; - } - case NM_LINK_TYPE_MACVTAP: { - NMPlatformLnkMacvlan lnk_macvtap = { }; - - lnk_macvtap.mode = MACVLAN_MODE_PRIVATE; - lnk_macvtap.no_promisc = FALSE; - lnk_macvtap.tap = TRUE; - - if (!nmtstp_link_macvlan_add (NULL, ext, DEVICE_NAME, ifindex_parent, &lnk_macvtap)) - g_error ("Failed adding MACVTAP interface"); - break; - } - case NM_LINK_TYPE_SIT: { - NMPlatformLnkSit lnk_sit = { }; - gboolean gracefully_skip = FALSE; - - lnk_sit.local = nmtst_inet4_from_string ("192.168.200.1"); - lnk_sit.remote = nmtst_inet4_from_string ("172.25.100.14"); - lnk_sit.parent_ifindex = ifindex_parent; - lnk_sit.ttl = 0; - lnk_sit.tos = 31; - lnk_sit.path_mtu_discovery = FALSE; - - if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "sit0")) { - /* Seems that the sit module is not loaded... try to load it. */ - gracefully_skip = nm_utils_modprobe (NULL, TRUE, "sit", NULL) != 0; - } - - if (!nmtstp_link_sit_add (NULL, ext, DEVICE_NAME, &lnk_sit)) { - if (gracefully_skip) { - g_test_skip ("Cannot create sit tunnel because of missing sit module (modprobe sit)"); - goto out_delete_parent; - } - g_error ("Failed adding SIT tunnel"); - } - break; - } - case NM_LINK_TYPE_VLAN: - nmtstp_run_command_check ("ip link add name %s link %s type vlan id 1242", DEVICE_NAME, PARENT_NAME); - break; - case NM_LINK_TYPE_VRF: { - NMPlatformLnkVrf lnk_vrf = { }; - gboolean not_supported; - - lnk_vrf.table = 9876; - - if (!nmtstp_link_vrf_add (NULL, ext, DEVICE_NAME, &lnk_vrf, ¬_supported)) { - if (not_supported) { - g_test_skip ("Cannot create VRF interface because of missing kernel support"); - goto out_delete_parent; - } - g_error ("Failed adding VRF interface"); - } - break; - } - case NM_LINK_TYPE_VXLAN: { - NMPlatformLnkVxlan lnk_vxlan = { }; - - switch (test_data->test_mode) { - case 0: - lnk_vxlan.parent_ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, PARENT_NAME); - lnk_vxlan.id = 42; - lnk_vxlan.local = nmtst_inet4_from_string ("23.1.2.164"); - lnk_vxlan.group = nmtst_inet4_from_string ("239.1.2.134"); - lnk_vxlan.dst_port = 4789; - lnk_vxlan.learning = TRUE; - lnk_vxlan.ageing = 1245; - break; - case 1: - lnk_vxlan.parent_ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, PARENT_NAME); - lnk_vxlan.id = 11214423; - lnk_vxlan.local6 = *nmtst_inet6_from_string ("1:2:3:4:334:23::23"); - lnk_vxlan.group6 = *nmtst_inet6_from_string ("ff0e::115"); - lnk_vxlan.ttl = 32; - lnk_vxlan.dst_port = 57412; - lnk_vxlan.src_port_min = 1000; - lnk_vxlan.src_port_max = 1003; - lnk_vxlan.learning = TRUE; - lnk_vxlan.ageing = 3245; - break; - } - - g_assert (nmtstp_link_vxlan_add (NULL, ext, DEVICE_NAME, &lnk_vxlan)); - break; - } - case NM_LINK_TYPE_TUN: { - gboolean owner_valid = nmtst_get_rand_bool (); - gboolean group_valid = nmtst_get_rand_bool (); - - switch (test_data->test_mode) { - case 0: - lnk_tun = (NMPlatformLnkTun) { - .type = nmtst_get_rand_bool () ? IFF_TUN : IFF_TAP, - .owner = owner_valid ? getuid () : 0, - .owner_valid = owner_valid, - .group = group_valid ? getgid () : 0, - .group_valid = group_valid, - .pi = nmtst_get_rand_bool (), - .vnet_hdr = nmtst_get_rand_bool (), - .multi_queue = nmtst_get_rand_bool (), - - /* if we add the device via iproute2 (external), we can only - * create persistent devices. */ - .persist = (ext == 1) ? TRUE : nmtst_get_rand_bool (), - }; - break; - default: - g_assert_not_reached (); - break; - } - - g_assert (nmtstp_link_tun_add (NULL, ext, DEVICE_NAME, &lnk_tun, - (!lnk_tun.persist || nmtst_get_rand_bool ()) - ? &tun_fd - : NULL)); - break; - } - case NM_LINK_TYPE_WIREGUARD: { - const NMPlatformLink *link; - - r = nm_platform_link_wireguard_add (NM_PLATFORM_GET, DEVICE_NAME, &link); - if (r == -EOPNOTSUPP) { - g_test_skip ("wireguard not supported (modprobe wireguard?)"); - goto out_delete_parent; - } - - g_assert (NMTST_NM_ERR_SUCCESS (r)); - g_assert (NMP_OBJECT_GET_TYPE (NMP_OBJECT_UP_CAST (link)) == NMP_OBJECT_TYPE_LINK); - break; - } - default: - g_assert_not_reached (); - } - - ifindex = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, DEVICE_NAME, test_data->link_type, 100)->ifindex; - - nmtstp_link_set_updown (NULL, -1, ifindex_parent, TRUE); - - for (i_step = 0; i_step < 5; i_step++) { - - _LOGD ("test-software-detect: step %u", i_step); - if (nmtst_is_debug ()) - nmtstp_run_command_check ("ip -d link show %s", DEVICE_NAME); - - if (i_step > 0) { - gboolean set_up = (i_step % 2) == 1; - - if ( test_data->link_type == NM_LINK_TYPE_VXLAN - && set_up) { - /* On RHEL-7, we need to add a tiny sleep here, otherwise, - * upping the vxlan device fails with EADDRINUSE. - * https://bugzilla.redhat.com/show_bug.cgi?id=1277131 */ - g_usleep (1); - } - nmtstp_link_set_updown (NULL, -1, ifindex, set_up); - } - - lnk = nm_platform_link_get_lnk (NM_PLATFORM_GET, ifindex, test_data->link_type, &plink); - g_assert (plink); - g_assert_cmpint (plink->ifindex, ==, ifindex); - - if ( !lnk - && test_data->link_type == NM_LINK_TYPE_TUN) { - /* this is ok. Kernel apparently does not support tun properties via netlink. We - * fetch them from sysfs below. */ - } else - g_assert (lnk); - - switch (test_data->link_type) { - case NM_LINK_TYPE_GRE: { - const NMPlatformLnkGre *plnk = &lnk->lnk_gre; - - g_assert (plnk == nm_platform_link_get_lnk_gre (NM_PLATFORM_GET, ifindex, NULL)); - g_assert (nm_platform_lnk_gre_cmp (plnk, &lnk_gre) == 0); - - break; - } - case NM_LINK_TYPE_GRETAP: { - const NMPlatformLnkGre *plnk = &lnk->lnk_gre; - - g_assert (plnk == nm_platform_link_get_lnk_gretap (NM_PLATFORM_GET, ifindex, NULL)); - g_assert (nm_platform_lnk_gre_cmp (plnk, &lnk_gre) == 0); - break; - } - case NM_LINK_TYPE_IP6TNL: { - const NMPlatformLnkIp6Tnl *plnk = &lnk->lnk_ip6tnl; - - switch (test_data->test_mode) { - case 0: - g_assert (plnk == nm_platform_link_get_lnk_ip6tnl (NM_PLATFORM_GET, ifindex, NULL)); - g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent); - nmtst_assert_ip6_address (&plnk->local, "fd01::15"); - nmtst_assert_ip6_address (&plnk->remote, "fd01::16"); - g_assert_cmpint (plnk->ttl, ==, 0); - g_assert_cmpint (plnk->tclass, ==, 20); - g_assert_cmpint (plnk->encap_limit, ==, 6); - g_assert_cmpint (plnk->flow_label, ==, 1337); - g_assert_cmpint (plnk->proto, ==, IPPROTO_IPV6); - break; - case 1: - g_assert (plnk == nm_platform_link_get_lnk_ip6tnl (NM_PLATFORM_GET, ifindex, NULL)); - g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent); - nmtst_assert_ip6_address (&plnk->local, "fd01::17"); - nmtst_assert_ip6_address (&plnk->remote, "fd01::18"); - g_assert_cmpint (plnk->ttl, ==, 0); - g_assert_cmpint (plnk->flow_label, ==, 1338); - g_assert_cmpint (plnk->proto, ==, IPPROTO_IPV6); - g_assert_cmpint (plnk->flags & 0xFFFF, /* ignore kernel internal flags */ - ==, - IP6_TNL_F_IGN_ENCAP_LIMIT | IP6_TNL_F_USE_ORIG_TCLASS); - break; - } - break; - } - case NM_LINK_TYPE_IP6GRE: { - const NMPlatformLnkIp6Tnl *plnk = &lnk->lnk_ip6tnl; - - g_assert (plnk == nm_platform_link_get_lnk_ip6gre (NM_PLATFORM_GET, ifindex, NULL)); - g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent); - nmtst_assert_ip6_address (&plnk->local, "fd01::42"); - nmtst_assert_ip6_address (&plnk->remote, "fd01::aaaa"); - g_assert_cmpint (plnk->tclass, ==, 21); - g_assert_cmpint (plnk->flow_label, ==, 1338); - g_assert_cmpint (plnk->is_gre, ==, TRUE); - g_assert_cmpint (plnk->is_tap, ==, FALSE); - break; - } - case NM_LINK_TYPE_IP6GRETAP: { - const NMPlatformLnkIp6Tnl *plnk = &lnk->lnk_ip6tnl; - - g_assert (plnk == nm_platform_link_get_lnk_ip6gretap (NM_PLATFORM_GET, ifindex, NULL)); - g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent); - nmtst_assert_ip6_address (&plnk->local, "fe80::abcd"); - nmtst_assert_ip6_address (&plnk->remote, "fc01::bbbb"); - g_assert_cmpint (plnk->ttl, ==, 10); - g_assert_cmpint (plnk->tclass, ==, 22); - g_assert_cmpint (plnk->flow_label, ==, 1339); - g_assert_cmpint (plnk->is_gre, ==, TRUE); - g_assert_cmpint (plnk->is_tap, ==, TRUE); - break; - } - case NM_LINK_TYPE_IPIP: { - const NMPlatformLnkIpIp *plnk = &lnk->lnk_ipip; - - g_assert (plnk == nm_platform_link_get_lnk_ipip (NM_PLATFORM_GET, ifindex, NULL)); - g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent); - nmtst_assert_ip4_address (plnk->local, "1.2.3.4"); - nmtst_assert_ip4_address (plnk->remote, "5.6.7.8"); - g_assert_cmpint (plnk->ttl, ==, 0); - g_assert_cmpint (plnk->tos, ==, 32); - g_assert_cmpint (plnk->path_mtu_discovery, ==, FALSE); - break; - } - case NM_LINK_TYPE_MACVLAN: { - const NMPlatformLnkMacvlan *plnk = &lnk->lnk_macvlan; - - g_assert (plnk == nm_platform_link_get_lnk_macvlan (NM_PLATFORM_GET, ifindex, NULL)); - g_assert_cmpint (plnk->no_promisc, ==, FALSE); - g_assert_cmpint (plnk->mode, ==, MACVLAN_MODE_BRIDGE); - break; - } - case NM_LINK_TYPE_MACVTAP: { - const NMPlatformLnkMacvlan *plnk = &lnk->lnk_macvlan; - - g_assert (plnk == nm_platform_link_get_lnk_macvtap (NM_PLATFORM_GET, ifindex, NULL)); - g_assert_cmpint (plnk->no_promisc, ==, FALSE); - g_assert_cmpint (plnk->mode, ==, MACVLAN_MODE_PRIVATE); - break; - } - case NM_LINK_TYPE_SIT: { - const NMPlatformLnkSit *plnk = &lnk->lnk_sit; - - g_assert (plnk == nm_platform_link_get_lnk_sit (NM_PLATFORM_GET, ifindex, NULL)); - g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent); - nmtst_assert_ip4_address (plnk->local, "192.168.200.1"); - nmtst_assert_ip4_address (plnk->remote, "172.25.100.14"); - g_assert_cmpint (plnk->ttl, ==, 0); - g_assert_cmpint (plnk->tos, ==, 31); - g_assert_cmpint (plnk->path_mtu_discovery, ==, FALSE); - break; - } - case NM_LINK_TYPE_TUN: { - const NMPlatformLnkTun *plnk; - NMPlatformLnkTun lnk_tun2; - - g_assert ((lnk ? &lnk->lnk_tun : NULL) == nm_platform_link_get_lnk_tun (NM_PLATFORM_GET, ifindex, NULL)); - - /* kernel might not expose tun options via netlink. Either way, try - * to read them (either from platform cache, or fallback to sysfs). - * See also: rh#1547213. */ - if (!nm_platform_link_tun_get_properties (NM_PLATFORM_GET, - ifindex, - &lnk_tun2)) - g_assert_not_reached (); - - plnk = lnk ? &lnk->lnk_tun : &lnk_tun2; - if (lnk) - g_assert (memcmp (plnk, &lnk_tun2, sizeof (NMPlatformLnkTun)) == 0); - - if (i_step == 0) { - /* Before we upped the device for the first time the kernel didn't notify - * us of the owner set after the link creation: - * https://bugzilla.redhat.com/show_bug.cgi?id=1566062 - */ - break; - } - - g_assert (nm_platform_lnk_tun_cmp (plnk, &lnk_tun) == 0); - break; - } - case NM_LINK_TYPE_VLAN: { - const NMPlatformLnkVlan *plnk = &lnk->lnk_vlan; - - g_assert (plnk == nm_platform_link_get_lnk_vlan (NM_PLATFORM_GET, ifindex, NULL)); - g_assert_cmpint (plnk->id, ==, 1242); - break; - } - case NM_LINK_TYPE_VRF: { - const NMPlatformLnkVrf *plnk = &lnk->lnk_vrf; - - g_assert (plnk == nm_platform_link_get_lnk_vrf (NM_PLATFORM_GET, ifindex, NULL)); - g_assert_cmpint (plnk->table, ==, 9876); - break; - } - case NM_LINK_TYPE_VXLAN: { - const NMPlatformLnkVxlan *plnk = &lnk->lnk_vxlan; - - g_assert (plnk == nm_platform_link_get_lnk_vxlan (NM_PLATFORM_GET, ifindex, NULL)); - g_assert_cmpint (plnk->parent_ifindex, !=, 0); - g_assert_cmpint (plnk->tos, ==, 0); - g_assert_cmpint (plnk->learning, ==, TRUE); - g_assert_cmpint (plnk->limit, ==, 0); - g_assert_cmpint (plnk->proxy, ==, FALSE); - g_assert_cmpint (plnk->rsc, ==, FALSE); - g_assert_cmpint (plnk->l2miss, ==, FALSE); - g_assert_cmpint (plnk->l3miss, ==, FALSE); - - switch (test_data->test_mode) { - case 0: - g_assert_cmpint (plnk->id, ==, 42); - nmtst_assert_ip4_address (plnk->local, "23.1.2.164"); - nmtst_assert_ip4_address (plnk->group, "239.1.2.134"); - nmtst_assert_ip6_address (&plnk->group6, "::"); - nmtst_assert_ip6_address (&plnk->local6, "::"); - g_assert_cmpint (plnk->ttl, ==, 0); - g_assert_cmpint (plnk->ageing, ==, 1245); - g_assert_cmpint (plnk->dst_port, ==, 4789); - if ( plnk->src_port_min != 0 - || plnk->src_port_max != 0) { - /* on some kernels, omitting the port range results in setting - * following default port range. */ - g_assert_cmpint (plnk->src_port_min, ==, 32768); - g_assert_cmpint (plnk->src_port_max, ==, 61000); - } - break; - case 1: - g_assert_cmpint (plnk->id, ==, 11214423); - nmtst_assert_ip4_address (plnk->local, "0.0.0.0"); - nmtst_assert_ip4_address (plnk->group, "0.0.0.0"); - nmtst_assert_ip6_address (&plnk->group6, "ff0e::115"); - nmtst_assert_ip6_address (&plnk->local6, "1:2:3:4:334:23::23"); - g_assert_cmpint (plnk->ageing, ==, 3245); - g_assert_cmpint (plnk->dst_port, ==, 57412); - g_assert_cmpint (plnk->ttl, ==, 32); - g_assert_cmpint (plnk->src_port_min, ==, 1000); - g_assert_cmpint (plnk->src_port_max, ==, 1003); - break; - } - break; - } - case NM_LINK_TYPE_WIREGUARD: { - const NMPlatformLnkWireGuard *plnk = &lnk->lnk_wireguard; - - g_assert (plnk == nm_platform_link_get_lnk_wireguard (NM_PLATFORM_GET, ifindex, NULL)); - - if (plink->n_ifi_flags & IFF_UP) { - _test_wireguard_change (NM_PLATFORM_GET, plink->ifindex, test_data->test_mode); - if (_LOGD_ENABLED ()) - _system ("WG_HIDE_KEYS=never wg show all"); - } - break; - } - default: - g_assert_not_reached (); - } - } - - nmtstp_link_delete (NULL, -1, ifindex, DEVICE_NAME, TRUE); + const TestAddSoftwareDetectData *test_data = user_data; + int ifindex, ifindex_parent; + const NMPlatformLink * plink; + const NMPObject * lnk; + int r; + guint i_step; + const gboolean ext = test_data->external_command; + NMPlatformLnkBridge lnk_bridge = {}; + NMPlatformLnkTun lnk_tun; + NMPlatformLnkGre lnk_gre = {}; + nm_auto_close int tun_fd = -1; + + nmtstp_run_command_check("ip link add %s type dummy", PARENT_NAME); + ifindex_parent = + nmtstp_assert_wait_for_link(NM_PLATFORM_GET, PARENT_NAME, NM_LINK_TYPE_DUMMY, 100)->ifindex; + + switch (test_data->link_type) { + case NM_LINK_TYPE_BRIDGE: + + lnk_bridge.forward_delay = 1560; + lnk_bridge.hello_time = 150; + lnk_bridge.max_age = 2100; + lnk_bridge.ageing_time = 2200; + lnk_bridge.stp_state = TRUE; + lnk_bridge.priority = 22; + lnk_bridge.vlan_protocol = 0x8100; + lnk_bridge.vlan_stats_enabled = + nmtstp_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_IFLA_BR_VLAN_STATS_ENABLED) + ? TRUE + : FALSE; + lnk_bridge.group_fwd_mask = 8; + lnk_bridge.group_addr = (NMEtherAddr){{0x01, 0x80, 0xC2, 0x00, 0x00, 0x08}}; + lnk_bridge.mcast_snooping = TRUE; + lnk_bridge.mcast_router = 1; + lnk_bridge.mcast_query_use_ifaddr = TRUE; + lnk_bridge.mcast_querier = TRUE; + lnk_bridge.mcast_hash_max = 1024; + lnk_bridge.mcast_last_member_count = 2; + lnk_bridge.mcast_startup_query_count = 3; + lnk_bridge.mcast_last_member_interval = 5000; + lnk_bridge.mcast_membership_interval = 25000; + lnk_bridge.mcast_querier_interval = 26000; + lnk_bridge.mcast_query_interval = 12000; + lnk_bridge.mcast_query_response_interval = 5200; + lnk_bridge.mcast_startup_query_interval = 3000; + + if (!nmtstp_link_bridge_add(NULL, ext, DEVICE_NAME, &lnk_bridge)) + g_error("Failed adding Bridge interface"); + break; + + case NM_LINK_TYPE_GRE: + { + gboolean gracefully_skip = FALSE; + + lnk_gre.local = nmtst_inet4_from_string("192.168.233.204"); + lnk_gre.remote = nmtst_inet4_from_string("172.168.10.25"); + lnk_gre.parent_ifindex = ifindex_parent; + lnk_gre.ttl = 174; + lnk_gre.tos = 37; + lnk_gre.path_mtu_discovery = TRUE; + + if (!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, "gre0")) { + /* Seems that the ip_gre module is not loaded... try to load it. */ + gracefully_skip = nm_utils_modprobe(NULL, TRUE, "ip_gre", NULL) != 0; + } + + if (!nmtstp_link_gre_add(NULL, ext, DEVICE_NAME, &lnk_gre)) { + if (gracefully_skip) { + g_test_skip( + "Cannot create gre tunnel because of missing ip_gre module (modprobe ip_gre)"); + goto out_delete_parent; + } + g_error("Failed adding GRE tunnel"); + } + break; + } + case NM_LINK_TYPE_GRETAP: + { + gboolean gracefully_skip = FALSE; + + lnk_gre.local = nmtst_inet4_from_string("192.168.1.133"); + lnk_gre.remote = nmtst_inet4_from_string("172.168.101.2"); + lnk_gre.parent_ifindex = ifindex_parent; + lnk_gre.ttl = 39; + lnk_gre.tos = 12; + lnk_gre.path_mtu_discovery = FALSE; + lnk_gre.is_tap = TRUE; + + if (!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, "gretap0")) { + /* Seems that the ip_gre module is not loaded... try to load it. */ + gracefully_skip = nm_utils_modprobe(NULL, TRUE, "ip_gre", NULL) != 0; + } + + if (!nmtstp_link_gre_add(NULL, ext, DEVICE_NAME, &lnk_gre)) { + if (gracefully_skip) { + g_test_skip("Cannot create gretap tunnel because of missing ip_gre module " + "(modprobe ip_gre)"); + goto out_delete_parent; + } + g_error("Failed adding GRETAP tunnel"); + } + break; + } + case NM_LINK_TYPE_IPIP: + { + NMPlatformLnkIpIp lnk_ipip = {}; + gboolean gracefully_skip = FALSE; + + if (!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, "tunl0")) { + /* Seems that the ipip module is not loaded... try to load it. */ + gracefully_skip = nm_utils_modprobe(NULL, TRUE, "ipip", NULL) != 0; + } + + lnk_ipip.local = nmtst_inet4_from_string("1.2.3.4"); + lnk_ipip.remote = nmtst_inet4_from_string("5.6.7.8"); + lnk_ipip.parent_ifindex = ifindex_parent; + lnk_ipip.tos = 32; + lnk_ipip.path_mtu_discovery = FALSE; + + if (!nmtstp_link_ipip_add(NULL, ext, DEVICE_NAME, &lnk_ipip)) { + if (gracefully_skip) { + g_test_skip( + "Cannot create ipip tunnel because of missing ipip module (modprobe ipip)"); + goto out_delete_parent; + } + g_error("Failed adding IPIP tunnel"); + } + break; + } + case NM_LINK_TYPE_IP6TNL: + { + NMPlatformLnkIp6Tnl lnk_ip6tnl = {}; + gboolean gracefully_skip = FALSE; + + if (!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, "ip6tnl0")) { + /* Seems that the ip6_tunnel module is not loaded... try to load it. */ + gracefully_skip = nm_utils_modprobe(NULL, TRUE, "ip6_tunnel", NULL) != 0; + } + + switch (test_data->test_mode) { + case 0: + lnk_ip6tnl.local = *nmtst_inet6_from_string("fd01::15"); + lnk_ip6tnl.remote = *nmtst_inet6_from_string("fd01::16"); + lnk_ip6tnl.parent_ifindex = ifindex_parent; + lnk_ip6tnl.tclass = 20; + lnk_ip6tnl.encap_limit = 6; + lnk_ip6tnl.flow_label = 1337; + lnk_ip6tnl.proto = IPPROTO_IPV6; + break; + case 1: + lnk_ip6tnl.local = *nmtst_inet6_from_string("fd01::17"); + lnk_ip6tnl.remote = *nmtst_inet6_from_string("fd01::18"); + lnk_ip6tnl.parent_ifindex = ifindex_parent; + lnk_ip6tnl.tclass = 0; + lnk_ip6tnl.encap_limit = 0; + lnk_ip6tnl.flow_label = 1338; + lnk_ip6tnl.proto = IPPROTO_IPV6; + lnk_ip6tnl.flags = IP6_TNL_F_IGN_ENCAP_LIMIT | IP6_TNL_F_USE_ORIG_TCLASS; + break; + } + + if (!nmtstp_link_ip6tnl_add(NULL, ext, DEVICE_NAME, &lnk_ip6tnl)) { + if (gracefully_skip) { + g_test_skip("Cannot create ip6tnl tunnel because of missing ip6_tunnel module " + "(modprobe ip6_tunnel)"); + goto out_delete_parent; + } + g_error("Failed adding IP6TNL tunnel"); + } + break; + } + case NM_LINK_TYPE_IP6GRE: + { + NMPlatformLnkIp6Tnl lnk_ip6tnl = {}; + gboolean gracefully_skip = FALSE; + + if (!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, "ip6gre0")) { + /* Seems that the ip6_tunnel module is not loaded... try to load it. */ + gracefully_skip = nm_utils_modprobe(NULL, TRUE, "ip6_gre", NULL) != 0; + } + + lnk_ip6tnl.local = *nmtst_inet6_from_string("fd01::42"); + lnk_ip6tnl.remote = *nmtst_inet6_from_string("fd01::aaaa"); + lnk_ip6tnl.parent_ifindex = ifindex_parent; + lnk_ip6tnl.tclass = 21; + lnk_ip6tnl.flow_label = 1338; + lnk_ip6tnl.is_gre = TRUE; + + if (!nmtstp_link_ip6gre_add(NULL, ext, DEVICE_NAME, &lnk_ip6tnl)) { + if (gracefully_skip) { + g_test_skip("Cannot create ip6gre tunnel because of missing ip6_gre module " + "(modprobe ip6_gre)"); + goto out_delete_parent; + } + g_error("Failed adding IP6GRE tunnel"); + } + break; + } + case NM_LINK_TYPE_IP6GRETAP: + { + NMPlatformLnkIp6Tnl lnk_ip6tnl = {}; + gboolean gracefully_skip = FALSE; + + if (!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, "ip6gre0")) { + /* Seems that the ip6_tunnel module is not loaded... try to load it. */ + gracefully_skip = nm_utils_modprobe(NULL, TRUE, "ip6_gre", NULL) != 0; + } + + lnk_ip6tnl.local = *nmtst_inet6_from_string("fe80::abcd"); + lnk_ip6tnl.remote = *nmtst_inet6_from_string("fc01::bbbb"); + lnk_ip6tnl.parent_ifindex = ifindex_parent; + lnk_ip6tnl.ttl = 10; + lnk_ip6tnl.tclass = 22; + lnk_ip6tnl.flow_label = 1339; + lnk_ip6tnl.is_gre = TRUE; + lnk_ip6tnl.is_tap = TRUE; + + if (!nmtstp_link_ip6gre_add(NULL, ext, DEVICE_NAME, &lnk_ip6tnl)) { + if (gracefully_skip) { + g_test_skip("Cannot create ip6gretap tunnel because of missing ip6_gre module " + "(modprobe ip6_gre)"); + goto out_delete_parent; + } + g_error("Failed adding IP6GRETAP tunnel"); + } + break; + } + case NM_LINK_TYPE_MACVLAN: + { + NMPlatformLnkMacvlan lnk_macvlan = {}; + const NMPlatformLink *dummy; + char buf[256]; + int i; + + lnk_macvlan.mode = MACVLAN_MODE_BRIDGE; + lnk_macvlan.no_promisc = FALSE; + lnk_macvlan.tap = FALSE; + + /* Since in old kernel versions sysfs files for macvtaps are not + * namespaced, the creation can fail if a macvtap in another namespace + * has the same index. Try to detect this situation and skip already + * used indexes. + * The fix (17af2bce) is included kernel 4.7, dated 24 July, 2016. + */ + for (i = ifindex_parent + 1; i < ifindex_parent + 100; i++) { + snprintf(buf, sizeof(buf), "/sys/class/macvtap/tap%d", i); + if (!g_file_test(buf, G_FILE_TEST_IS_SYMLINK)) + break; + + _LOGD("skipping ifindex %d as already used by a macvtap", i); + + dummy = nmtstp_link_dummy_add(NM_PLATFORM_GET, FALSE, "dummy-tmp"); + g_assert_cmpint(dummy->ifindex, ==, i); + nmtstp_link_delete(NM_PLATFORM_GET, FALSE, dummy->ifindex, NULL, TRUE); + } + + if (!nmtstp_link_macvlan_add(NULL, ext, DEVICE_NAME, ifindex_parent, &lnk_macvlan)) + g_error("Failed adding MACVLAN interface"); + break; + } + case NM_LINK_TYPE_MACVTAP: + { + NMPlatformLnkMacvlan lnk_macvtap = {}; + + lnk_macvtap.mode = MACVLAN_MODE_PRIVATE; + lnk_macvtap.no_promisc = FALSE; + lnk_macvtap.tap = TRUE; + + if (!nmtstp_link_macvlan_add(NULL, ext, DEVICE_NAME, ifindex_parent, &lnk_macvtap)) + g_error("Failed adding MACVTAP interface"); + break; + } + case NM_LINK_TYPE_SIT: + { + NMPlatformLnkSit lnk_sit = {}; + gboolean gracefully_skip = FALSE; + + lnk_sit.local = nmtst_inet4_from_string("192.168.200.1"); + lnk_sit.remote = nmtst_inet4_from_string("172.25.100.14"); + lnk_sit.parent_ifindex = ifindex_parent; + lnk_sit.ttl = 0; + lnk_sit.tos = 31; + lnk_sit.path_mtu_discovery = FALSE; + + if (!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, "sit0")) { + /* Seems that the sit module is not loaded... try to load it. */ + gracefully_skip = nm_utils_modprobe(NULL, TRUE, "sit", NULL) != 0; + } + + if (!nmtstp_link_sit_add(NULL, ext, DEVICE_NAME, &lnk_sit)) { + if (gracefully_skip) { + g_test_skip( + "Cannot create sit tunnel because of missing sit module (modprobe sit)"); + goto out_delete_parent; + } + g_error("Failed adding SIT tunnel"); + } + break; + } + case NM_LINK_TYPE_VLAN: + nmtstp_run_command_check("ip link add name %s link %s type vlan id 1242", + DEVICE_NAME, + PARENT_NAME); + break; + case NM_LINK_TYPE_VRF: + { + NMPlatformLnkVrf lnk_vrf = {}; + gboolean not_supported; + + lnk_vrf.table = 9876; + + if (!nmtstp_link_vrf_add(NULL, ext, DEVICE_NAME, &lnk_vrf, ¬_supported)) { + if (not_supported) { + g_test_skip("Cannot create VRF interface because of missing kernel support"); + goto out_delete_parent; + } + g_error("Failed adding VRF interface"); + } + break; + } + case NM_LINK_TYPE_VXLAN: + { + NMPlatformLnkVxlan lnk_vxlan = {}; + + switch (test_data->test_mode) { + case 0: + lnk_vxlan.parent_ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, PARENT_NAME); + lnk_vxlan.id = 42; + lnk_vxlan.local = nmtst_inet4_from_string("23.1.2.164"); + lnk_vxlan.group = nmtst_inet4_from_string("239.1.2.134"); + lnk_vxlan.dst_port = 4789; + lnk_vxlan.learning = TRUE; + lnk_vxlan.ageing = 1245; + break; + case 1: + lnk_vxlan.parent_ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, PARENT_NAME); + lnk_vxlan.id = 11214423; + lnk_vxlan.local6 = *nmtst_inet6_from_string("1:2:3:4:334:23::23"); + lnk_vxlan.group6 = *nmtst_inet6_from_string("ff0e::115"); + lnk_vxlan.ttl = 32; + lnk_vxlan.dst_port = 57412; + lnk_vxlan.src_port_min = 1000; + lnk_vxlan.src_port_max = 1003; + lnk_vxlan.learning = TRUE; + lnk_vxlan.ageing = 3245; + break; + } + + g_assert(nmtstp_link_vxlan_add(NULL, ext, DEVICE_NAME, &lnk_vxlan)); + break; + } + case NM_LINK_TYPE_TUN: + { + gboolean owner_valid = nmtst_get_rand_bool(); + gboolean group_valid = nmtst_get_rand_bool(); + + switch (test_data->test_mode) { + case 0: + lnk_tun = (NMPlatformLnkTun){ + .type = nmtst_get_rand_bool() ? IFF_TUN : IFF_TAP, + .owner = owner_valid ? getuid() : 0, + .owner_valid = owner_valid, + .group = group_valid ? getgid() : 0, + .group_valid = group_valid, + .pi = nmtst_get_rand_bool(), + .vnet_hdr = nmtst_get_rand_bool(), + .multi_queue = nmtst_get_rand_bool(), + + /* if we add the device via iproute2 (external), we can only + * create persistent devices. */ + .persist = (ext == 1) ? TRUE : nmtst_get_rand_bool(), + }; + break; + default: + g_assert_not_reached(); + break; + } + + g_assert(nmtstp_link_tun_add(NULL, + ext, + DEVICE_NAME, + &lnk_tun, + (!lnk_tun.persist || nmtst_get_rand_bool()) ? &tun_fd : NULL)); + break; + } + case NM_LINK_TYPE_WIREGUARD: + { + const NMPlatformLink *link; + + r = nm_platform_link_wireguard_add(NM_PLATFORM_GET, DEVICE_NAME, &link); + if (r == -EOPNOTSUPP) { + g_test_skip("wireguard not supported (modprobe wireguard?)"); + goto out_delete_parent; + } + + g_assert(NMTST_NM_ERR_SUCCESS(r)); + g_assert(NMP_OBJECT_GET_TYPE(NMP_OBJECT_UP_CAST(link)) == NMP_OBJECT_TYPE_LINK); + break; + } + default: + g_assert_not_reached(); + } + + ifindex = nmtstp_assert_wait_for_link(NM_PLATFORM_GET, DEVICE_NAME, test_data->link_type, 100) + ->ifindex; + + nmtstp_link_set_updown(NULL, -1, ifindex_parent, TRUE); + + for (i_step = 0; i_step < 5; i_step++) { + _LOGD("test-software-detect: step %u", i_step); + if (nmtst_is_debug()) + nmtstp_run_command_check("ip -d link show %s", DEVICE_NAME); + + if (i_step > 0) { + gboolean set_up = (i_step % 2) == 1; + + if (test_data->link_type == NM_LINK_TYPE_VXLAN && set_up) { + /* On RHEL-7, we need to add a tiny sleep here, otherwise, + * upping the vxlan device fails with EADDRINUSE. + * https://bugzilla.redhat.com/show_bug.cgi?id=1277131 */ + g_usleep(1); + } + nmtstp_link_set_updown(NULL, -1, ifindex, set_up); + } + + lnk = nm_platform_link_get_lnk(NM_PLATFORM_GET, ifindex, test_data->link_type, &plink); + g_assert(plink); + g_assert_cmpint(plink->ifindex, ==, ifindex); + + if (!lnk && test_data->link_type == NM_LINK_TYPE_TUN) { + /* this is ok. Kernel apparently does not support tun properties via netlink. We + * fetch them from sysfs below. */ + } else + g_assert(lnk); + + switch (test_data->link_type) { + case NM_LINK_TYPE_BRIDGE: + { + const NMPlatformLnkBridge *plnk = &lnk->lnk_bridge; + + g_assert(plnk == nm_platform_link_get_lnk_bridge(NM_PLATFORM_GET, ifindex, NULL)); + g_assert_cmpint(nm_platform_lnk_bridge_cmp(&lnk_bridge, plnk), ==, 0); + g_assert_cmpint(plnk->forward_delay, ==, 1560); + g_assert_cmpint(plnk->hello_time, ==, 150); + g_assert_cmpint(plnk->max_age, ==, 2100); + g_assert_cmpint(plnk->ageing_time, ==, 2200); + g_assert_cmpint(plnk->stp_state, ==, TRUE); + g_assert_cmpint(plnk->priority, ==, 22); + g_assert_cmpint(plnk->vlan_protocol, ==, 0x8100); + g_assert_cmpint(plnk->vlan_stats_enabled, ==, lnk_bridge.vlan_stats_enabled); + g_assert_cmpint(plnk->group_fwd_mask, ==, 8); + g_assert_cmpint(plnk->mcast_snooping, ==, TRUE); + g_assert_cmpint(plnk->mcast_router, ==, 1); + g_assert_cmpint(plnk->mcast_query_use_ifaddr, ==, TRUE); + g_assert_cmpint(plnk->mcast_querier, ==, TRUE); + g_assert_cmpint(plnk->mcast_hash_max, ==, 1024); + g_assert_cmpint(plnk->mcast_last_member_count, ==, 2); + g_assert_cmpint(plnk->mcast_startup_query_count, ==, 3); + g_assert_cmpint(plnk->mcast_last_member_interval, ==, 5000); + g_assert_cmpint(plnk->mcast_membership_interval, ==, 25000); + g_assert_cmpint(plnk->mcast_querier_interval, ==, 26000); + g_assert_cmpint(plnk->mcast_query_interval, ==, 12000); + g_assert_cmpint(plnk->mcast_query_response_interval, ==, 5200); + g_assert_cmpint(plnk->mcast_startup_query_interval, ==, 3000); + g_assert_cmpint(nm_platform_lnk_bridge_cmp(&lnk_bridge, plnk), ==, 0); + break; + } + case NM_LINK_TYPE_GRE: + { + const NMPlatformLnkGre *plnk = &lnk->lnk_gre; + + g_assert(plnk == nm_platform_link_get_lnk_gre(NM_PLATFORM_GET, ifindex, NULL)); + g_assert(nm_platform_lnk_gre_cmp(plnk, &lnk_gre) == 0); + + break; + } + case NM_LINK_TYPE_GRETAP: + { + const NMPlatformLnkGre *plnk = &lnk->lnk_gre; + + g_assert(plnk == nm_platform_link_get_lnk_gretap(NM_PLATFORM_GET, ifindex, NULL)); + g_assert(nm_platform_lnk_gre_cmp(plnk, &lnk_gre) == 0); + break; + } + case NM_LINK_TYPE_IP6TNL: + { + const NMPlatformLnkIp6Tnl *plnk = &lnk->lnk_ip6tnl; + + switch (test_data->test_mode) { + case 0: + g_assert(plnk == nm_platform_link_get_lnk_ip6tnl(NM_PLATFORM_GET, ifindex, NULL)); + g_assert_cmpint(plnk->parent_ifindex, ==, ifindex_parent); + nmtst_assert_ip6_address(&plnk->local, "fd01::15"); + nmtst_assert_ip6_address(&plnk->remote, "fd01::16"); + g_assert_cmpint(plnk->ttl, ==, 0); + g_assert_cmpint(plnk->tclass, ==, 20); + g_assert_cmpint(plnk->encap_limit, ==, 6); + g_assert_cmpint(plnk->flow_label, ==, 1337); + g_assert_cmpint(plnk->proto, ==, IPPROTO_IPV6); + break; + case 1: + g_assert(plnk == nm_platform_link_get_lnk_ip6tnl(NM_PLATFORM_GET, ifindex, NULL)); + g_assert_cmpint(plnk->parent_ifindex, ==, ifindex_parent); + nmtst_assert_ip6_address(&plnk->local, "fd01::17"); + nmtst_assert_ip6_address(&plnk->remote, "fd01::18"); + g_assert_cmpint(plnk->ttl, ==, 0); + g_assert_cmpint(plnk->flow_label, ==, 1338); + g_assert_cmpint(plnk->proto, ==, IPPROTO_IPV6); + g_assert_cmpint(plnk->flags & 0xFFFF, /* ignore kernel internal flags */ + ==, + IP6_TNL_F_IGN_ENCAP_LIMIT | IP6_TNL_F_USE_ORIG_TCLASS); + break; + } + break; + } + case NM_LINK_TYPE_IP6GRE: + { + const NMPlatformLnkIp6Tnl *plnk = &lnk->lnk_ip6tnl; + + g_assert(plnk == nm_platform_link_get_lnk_ip6gre(NM_PLATFORM_GET, ifindex, NULL)); + g_assert_cmpint(plnk->parent_ifindex, ==, ifindex_parent); + nmtst_assert_ip6_address(&plnk->local, "fd01::42"); + nmtst_assert_ip6_address(&plnk->remote, "fd01::aaaa"); + g_assert_cmpint(plnk->tclass, ==, 21); + g_assert_cmpint(plnk->flow_label, ==, 1338); + g_assert_cmpint(plnk->is_gre, ==, TRUE); + g_assert_cmpint(plnk->is_tap, ==, FALSE); + break; + } + case NM_LINK_TYPE_IP6GRETAP: + { + const NMPlatformLnkIp6Tnl *plnk = &lnk->lnk_ip6tnl; + + g_assert(plnk == nm_platform_link_get_lnk_ip6gretap(NM_PLATFORM_GET, ifindex, NULL)); + g_assert_cmpint(plnk->parent_ifindex, ==, ifindex_parent); + nmtst_assert_ip6_address(&plnk->local, "fe80::abcd"); + nmtst_assert_ip6_address(&plnk->remote, "fc01::bbbb"); + g_assert_cmpint(plnk->ttl, ==, 10); + g_assert_cmpint(plnk->tclass, ==, 22); + g_assert_cmpint(plnk->flow_label, ==, 1339); + g_assert_cmpint(plnk->is_gre, ==, TRUE); + g_assert_cmpint(plnk->is_tap, ==, TRUE); + break; + } + case NM_LINK_TYPE_IPIP: + { + const NMPlatformLnkIpIp *plnk = &lnk->lnk_ipip; + + g_assert(plnk == nm_platform_link_get_lnk_ipip(NM_PLATFORM_GET, ifindex, NULL)); + g_assert_cmpint(plnk->parent_ifindex, ==, ifindex_parent); + nmtst_assert_ip4_address(plnk->local, "1.2.3.4"); + nmtst_assert_ip4_address(plnk->remote, "5.6.7.8"); + g_assert_cmpint(plnk->ttl, ==, 0); + g_assert_cmpint(plnk->tos, ==, 32); + g_assert_cmpint(plnk->path_mtu_discovery, ==, FALSE); + break; + } + case NM_LINK_TYPE_MACVLAN: + { + const NMPlatformLnkMacvlan *plnk = &lnk->lnk_macvlan; + + g_assert(plnk == nm_platform_link_get_lnk_macvlan(NM_PLATFORM_GET, ifindex, NULL)); + g_assert_cmpint(plnk->no_promisc, ==, FALSE); + g_assert_cmpint(plnk->mode, ==, MACVLAN_MODE_BRIDGE); + break; + } + case NM_LINK_TYPE_MACVTAP: + { + const NMPlatformLnkMacvlan *plnk = &lnk->lnk_macvlan; + + g_assert(plnk == nm_platform_link_get_lnk_macvtap(NM_PLATFORM_GET, ifindex, NULL)); + g_assert_cmpint(plnk->no_promisc, ==, FALSE); + g_assert_cmpint(plnk->mode, ==, MACVLAN_MODE_PRIVATE); + break; + } + case NM_LINK_TYPE_SIT: + { + const NMPlatformLnkSit *plnk = &lnk->lnk_sit; + + g_assert(plnk == nm_platform_link_get_lnk_sit(NM_PLATFORM_GET, ifindex, NULL)); + g_assert_cmpint(plnk->parent_ifindex, ==, ifindex_parent); + nmtst_assert_ip4_address(plnk->local, "192.168.200.1"); + nmtst_assert_ip4_address(plnk->remote, "172.25.100.14"); + g_assert_cmpint(plnk->ttl, ==, 0); + g_assert_cmpint(plnk->tos, ==, 31); + g_assert_cmpint(plnk->path_mtu_discovery, ==, FALSE); + break; + } + case NM_LINK_TYPE_TUN: + { + const NMPlatformLnkTun *plnk; + NMPlatformLnkTun lnk_tun2; + + g_assert((lnk ? &lnk->lnk_tun : NULL) + == nm_platform_link_get_lnk_tun(NM_PLATFORM_GET, ifindex, NULL)); + + /* kernel might not expose tun options via netlink. Either way, try + * to read them (either from platform cache, or fallback to sysfs). + * See also: rh#1547213. */ + if (!nm_platform_link_tun_get_properties(NM_PLATFORM_GET, ifindex, &lnk_tun2)) + g_assert_not_reached(); + + plnk = lnk ? &lnk->lnk_tun : &lnk_tun2; + if (lnk) + g_assert(memcmp(plnk, &lnk_tun2, sizeof(NMPlatformLnkTun)) == 0); + + if (i_step == 0) { + /* Before we upped the device for the first time the kernel didn't notify + * us of the owner set after the link creation: + * https://bugzilla.redhat.com/show_bug.cgi?id=1566062 + */ + break; + } + + g_assert(nm_platform_lnk_tun_cmp(plnk, &lnk_tun) == 0); + break; + } + case NM_LINK_TYPE_VLAN: + { + const NMPlatformLnkVlan *plnk = &lnk->lnk_vlan; + + g_assert(plnk == nm_platform_link_get_lnk_vlan(NM_PLATFORM_GET, ifindex, NULL)); + g_assert_cmpint(plnk->id, ==, 1242); + break; + } + case NM_LINK_TYPE_VRF: + { + const NMPlatformLnkVrf *plnk = &lnk->lnk_vrf; + + g_assert(plnk == nm_platform_link_get_lnk_vrf(NM_PLATFORM_GET, ifindex, NULL)); + g_assert_cmpint(plnk->table, ==, 9876); + break; + } + case NM_LINK_TYPE_VXLAN: + { + const NMPlatformLnkVxlan *plnk = &lnk->lnk_vxlan; + + g_assert(plnk == nm_platform_link_get_lnk_vxlan(NM_PLATFORM_GET, ifindex, NULL)); + g_assert_cmpint(plnk->parent_ifindex, !=, 0); + g_assert_cmpint(plnk->tos, ==, 0); + g_assert_cmpint(plnk->learning, ==, TRUE); + g_assert_cmpint(plnk->limit, ==, 0); + g_assert_cmpint(plnk->proxy, ==, FALSE); + g_assert_cmpint(plnk->rsc, ==, FALSE); + g_assert_cmpint(plnk->l2miss, ==, FALSE); + g_assert_cmpint(plnk->l3miss, ==, FALSE); + + switch (test_data->test_mode) { + case 0: + g_assert_cmpint(plnk->id, ==, 42); + nmtst_assert_ip4_address(plnk->local, "23.1.2.164"); + nmtst_assert_ip4_address(plnk->group, "239.1.2.134"); + nmtst_assert_ip6_address(&plnk->group6, "::"); + nmtst_assert_ip6_address(&plnk->local6, "::"); + g_assert_cmpint(plnk->ttl, ==, 0); + g_assert_cmpint(plnk->ageing, ==, 1245); + g_assert_cmpint(plnk->dst_port, ==, 4789); + if (plnk->src_port_min != 0 || plnk->src_port_max != 0) { + /* on some kernels, omitting the port range results in setting + * following default port range. */ + g_assert_cmpint(plnk->src_port_min, ==, 32768); + g_assert_cmpint(plnk->src_port_max, ==, 61000); + } + break; + case 1: + g_assert_cmpint(plnk->id, ==, 11214423); + nmtst_assert_ip4_address(plnk->local, "0.0.0.0"); + nmtst_assert_ip4_address(plnk->group, "0.0.0.0"); + nmtst_assert_ip6_address(&plnk->group6, "ff0e::115"); + nmtst_assert_ip6_address(&plnk->local6, "1:2:3:4:334:23::23"); + g_assert_cmpint(plnk->ageing, ==, 3245); + g_assert_cmpint(plnk->dst_port, ==, 57412); + g_assert_cmpint(plnk->ttl, ==, 32); + g_assert_cmpint(plnk->src_port_min, ==, 1000); + g_assert_cmpint(plnk->src_port_max, ==, 1003); + break; + } + break; + } + case NM_LINK_TYPE_WIREGUARD: + { + const NMPlatformLnkWireGuard *plnk = &lnk->lnk_wireguard; + + g_assert(plnk == nm_platform_link_get_lnk_wireguard(NM_PLATFORM_GET, ifindex, NULL)); + + if (plink->n_ifi_flags & IFF_UP) { + _test_wireguard_change(NM_PLATFORM_GET, plink->ifindex, test_data->test_mode); + if (_LOGD_ENABLED()) + _system("WG_HIDE_KEYS=never wg show all"); + } + break; + } + default: + g_assert_not_reached(); + } + } + + nmtstp_link_delete(NULL, -1, ifindex, DEVICE_NAME, TRUE); out_delete_parent: - nmtstp_link_delete (NULL, -1, ifindex_parent, PARENT_NAME, TRUE); + nmtstp_link_delete(NULL, -1, ifindex_parent, PARENT_NAME, TRUE); } static void -test_software_detect_add (const char *testpath, - NMLinkType link_type, - int test_mode) +test_software_detect_add(const char *testpath, NMLinkType link_type, int test_mode) { - TestAddSoftwareDetectData *test_data; - char *path; - - test_data = g_new0 (TestAddSoftwareDetectData, 1); - test_data->link_type = link_type; - test_data->test_mode = test_mode; - test_data->external_command = TRUE; - - path = g_strdup_printf ("%s/external", testpath); - g_test_add_data_func_full (path, test_data, test_software_detect, g_free); - g_free (path); - - test_data = g_new0 (TestAddSoftwareDetectData, 1); - test_data->link_type = link_type; - test_data->test_mode = test_mode; - test_data->external_command = FALSE; - - path = g_strdup_printf ("%s/platform", testpath); - g_test_add_data_func_full (path, test_data, test_software_detect, g_free); - g_free (path); - - test_data = g_new0 (TestAddSoftwareDetectData, 1); - test_data->link_type = link_type; - test_data->test_mode = test_mode; - test_data->external_command = -1; - - path = g_strdup_printf ("%s/random", testpath); - g_test_add_data_func_full (path, test_data, test_software_detect, g_free); - g_free (path); + TestAddSoftwareDetectData *test_data; + char * path; + + test_data = g_new0(TestAddSoftwareDetectData, 1); + test_data->link_type = link_type; + test_data->test_mode = test_mode; + test_data->external_command = TRUE; + + path = g_strdup_printf("%s/external", testpath); + g_test_add_data_func_full(path, test_data, test_software_detect, g_free); + g_free(path); + + test_data = g_new0(TestAddSoftwareDetectData, 1); + test_data->link_type = link_type; + test_data->test_mode = test_mode; + test_data->external_command = FALSE; + + path = g_strdup_printf("%s/platform", testpath); + g_test_add_data_func_full(path, test_data, test_software_detect, g_free); + g_free(path); + + test_data = g_new0(TestAddSoftwareDetectData, 1); + test_data->link_type = link_type; + test_data->test_mode = test_mode; + test_data->external_command = -1; + + path = g_strdup_printf("%s/random", testpath); + g_test_add_data_func_full(path, test_data, test_software_detect, g_free); + g_free(path); } /*****************************************************************************/ static void -_assert_xgress_qos_mappings_impl (int ifindex, - gboolean is_ingress_map , - int n_entries, - int n, - ...) +_assert_xgress_qos_mappings_impl(int ifindex, gboolean is_ingress_map, int n_entries, int n, ...) { - const NMPlatformLink *plink; - const NMPObject *lnk; - guint n_map; - const NMVlanQosMapping *map; - va_list ap; - guint i; - - lnk = nm_platform_link_get_lnk (NM_PLATFORM_GET, ifindex, NM_LINK_TYPE_VLAN, &plink); - - g_assert (plink); - g_assert_cmpint (plink->ifindex, ==, ifindex); - g_assert (lnk); - g_assert (&lnk->lnk_vlan == nm_platform_link_get_lnk_vlan (NM_PLATFORM_GET, ifindex, NULL)); - - if (nmtst_is_debug ()) - nmtstp_run_command_check ("ip -d link show %s", plink->name); - - if (is_ingress_map) { - map = lnk->_lnk_vlan.ingress_qos_map; - n_map = lnk->_lnk_vlan.n_ingress_qos_map; - } else { - map = lnk->_lnk_vlan.egress_qos_map; - n_map = lnk->_lnk_vlan.n_egress_qos_map; - } - - if (n_entries != -1) - g_assert_cmpint (n_map, ==, n_entries); - - for (i = 0; i < n_map; i++) { - if (is_ingress_map) { - g_assert_cmpint (map[i].from, >=, 0); - g_assert_cmpint (map[i].from, <=, 7); - } - if (i > 0) - g_assert_cmpint (map[i - 1].from, <, map[i].from); - } - - va_start (ap, n); - for (; n > 0; n--) { - gboolean found = FALSE; - guint from = va_arg (ap, guint); - guint to = va_arg (ap, guint); - - for (i = 0; i < n_map; i++) { - if (map[i].from == from) { - g_assert (!found); - found = TRUE; - - g_assert (map[i].to == to); - } - } - g_assert (found); - } - va_end (ap); + const NMPlatformLink * plink; + const NMPObject * lnk; + guint n_map; + const NMVlanQosMapping *map; + va_list ap; + guint i; + + lnk = nm_platform_link_get_lnk(NM_PLATFORM_GET, ifindex, NM_LINK_TYPE_VLAN, &plink); + + g_assert(plink); + g_assert_cmpint(plink->ifindex, ==, ifindex); + g_assert(lnk); + g_assert(&lnk->lnk_vlan == nm_platform_link_get_lnk_vlan(NM_PLATFORM_GET, ifindex, NULL)); + + if (nmtst_is_debug()) + nmtstp_run_command_check("ip -d link show %s", plink->name); + + if (is_ingress_map) { + map = lnk->_lnk_vlan.ingress_qos_map; + n_map = lnk->_lnk_vlan.n_ingress_qos_map; + } else { + map = lnk->_lnk_vlan.egress_qos_map; + n_map = lnk->_lnk_vlan.n_egress_qos_map; + } + + if (n_entries != -1) + g_assert_cmpint(n_map, ==, n_entries); + + for (i = 0; i < n_map; i++) { + if (is_ingress_map) { + g_assert_cmpint(map[i].from, >=, 0); + g_assert_cmpint(map[i].from, <=, 7); + } + if (i > 0) + g_assert_cmpint(map[i - 1].from, <, map[i].from); + } + + va_start(ap, n); + for (; n > 0; n--) { + gboolean found = FALSE; + guint from = va_arg(ap, guint); + guint to = va_arg(ap, guint); + + for (i = 0; i < n_map; i++) { + if (map[i].from == from) { + g_assert(!found); + found = TRUE; + + g_assert(map[i].to == to); + } + } + g_assert(found); + } + va_end(ap); } -#define _assert_xgress_qos_mappings(ifindex, is_ingress_map, n_entries, ...) \ - _assert_xgress_qos_mappings_impl ((ifindex), (is_ingress_map), (n_entries), \ - (G_STATIC_ASSERT_EXPR ((NM_NARG (__VA_ARGS__) % 2) == 0), NM_NARG (__VA_ARGS__) / 2), \ - __VA_ARGS__) -#define _assert_ingress_qos_mappings(ifindex, n_entries, ...) _assert_xgress_qos_mappings (ifindex, TRUE, n_entries, __VA_ARGS__) -#define _assert_egress_qos_mappings(ifindex, n_entries, ...) _assert_xgress_qos_mappings (ifindex, FALSE, n_entries, __VA_ARGS__) +#define _assert_xgress_qos_mappings(ifindex, is_ingress_map, n_entries, ...) \ + _assert_xgress_qos_mappings_impl( \ + (ifindex), \ + (is_ingress_map), \ + (n_entries), \ + (G_STATIC_ASSERT_EXPR((NM_NARG(__VA_ARGS__) % 2) == 0), NM_NARG(__VA_ARGS__) / 2), \ + __VA_ARGS__) +#define _assert_ingress_qos_mappings(ifindex, n_entries, ...) \ + _assert_xgress_qos_mappings(ifindex, TRUE, n_entries, __VA_ARGS__) +#define _assert_egress_qos_mappings(ifindex, n_entries, ...) \ + _assert_xgress_qos_mappings(ifindex, FALSE, n_entries, __VA_ARGS__) static void -_assert_vlan_flags (int ifindex, NMVlanFlags flags) +_assert_vlan_flags(int ifindex, NMVlanFlags flags) { - const NMPlatformLnkVlan *plnk; + const NMPlatformLnkVlan *plnk; - plnk = nm_platform_link_get_lnk_vlan (NM_PLATFORM_GET, ifindex, NULL); - g_assert (plnk); - g_assert_cmpint (plnk->flags, ==, flags); + plnk = nm_platform_link_get_lnk_vlan(NM_PLATFORM_GET, ifindex, NULL); + g_assert(plnk); + g_assert_cmpint(plnk->flags, ==, flags); } static void -test_vlan_set_xgress (void) +test_vlan_set_xgress(void) { - int ifindex, ifindex_parent; - - nmtstp_run_command_check ("ip link add %s type dummy", PARENT_NAME); - ifindex_parent = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, PARENT_NAME, NM_LINK_TYPE_DUMMY, 100)->ifindex; - - nmtstp_run_command_check ("ip link add name %s link %s type vlan id 1245", DEVICE_NAME, PARENT_NAME); - ifindex = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, DEVICE_NAME, NM_LINK_TYPE_VLAN, 100)->ifindex; - - /* ingress-qos-map */ - - g_assert (nm_platform_link_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 4, 5)); - _assert_ingress_qos_mappings (ifindex, 1, - 4, 5); - - g_assert (nm_platform_link_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 3, 7)); - _assert_ingress_qos_mappings (ifindex, 2, - 3, 7, - 4, 5); - - g_assert (nm_platform_link_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 3, 8)); - _assert_ingress_qos_mappings (ifindex, 2, - 3, 8, - 4, 5); - - g_assert (nm_platform_link_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 0, 4)); - _assert_ingress_qos_mappings (ifindex, 3, - 0, 4, - 3, 8, - 4, 5); - - g_assert (nm_platform_link_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 0, G_MAXUINT32)); - _assert_ingress_qos_mappings (ifindex, 3, - 0, G_MAXUINT32, - 3, 8, - 4, 5); - - g_assert (nm_platform_link_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 0, G_MAXUINT32 - 1)); - _assert_ingress_qos_mappings (ifindex, 3, - 0, G_MAXUINT32 - 1, - 3, 8, - 4, 5); - - g_assert (nm_platform_link_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 0, 5)); - _assert_ingress_qos_mappings (ifindex, 3, - 0, 5, - 3, 8, - 4, 5); - - g_assert (nm_platform_link_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 0, 5)); - _assert_ingress_qos_mappings (ifindex, 3, - 0, 5, - 3, 8, - 4, 5); - - /* Set invalid values: */ - g_assert (nm_platform_link_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 8, 3)); - _assert_ingress_qos_mappings (ifindex, 3, - 0, 5, - 3, 8, - 4, 5); - - g_assert (nm_platform_link_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 9, 4)); - _assert_ingress_qos_mappings (ifindex, 3, - 0, 5, - 3, 8, - 4, 5); - - /* egress-qos-map */ - - g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 7, 3)); - _assert_egress_qos_mappings (ifindex, 1, - 7, 3); - - g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 8, 4)); - _assert_egress_qos_mappings (ifindex, 2, - 7, 3, - 8, 4); - - g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 0, 4)); - _assert_egress_qos_mappings (ifindex, 3, - 0, 4, - 7, 3, - 8, 4); - - g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 1, 4)); - _assert_egress_qos_mappings (ifindex, 4, - 0, 4, - 1, 4, - 7, 3, - 8, 4); - - g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 1, 5)); - _assert_egress_qos_mappings (ifindex, 4, - 0, 4, - 1, 5, - 7, 3, - 8, 4); - - g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 9, 5)); - _assert_egress_qos_mappings (ifindex, 5, - 0, 4, - 1, 5, - 7, 3, - 8, 4, - 9, 5); - - g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 8, 5)); - _assert_egress_qos_mappings (ifindex, 5, - 0, 4, - 1, 5, - 7, 3, - 8, 5, - 9, 5); - - g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 8, 0)); - _assert_egress_qos_mappings (ifindex, 4, - 0, 4, - 1, 5, - 7, 3, - 9, 5); - - g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 0, 0)); - _assert_egress_qos_mappings (ifindex, 3, - 1, 5, - 7, 3, - 9, 5); - - g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 100, 4)); - _assert_egress_qos_mappings (ifindex, 4, - 1, 5, - 7, 3, - 9, 5, - 100, 4); - - g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, G_MAXUINT32, 4)); - _assert_egress_qos_mappings (ifindex, 5, - 1, 5, - 7, 3, - 9, 5, - 100, 4, - G_MAXUINT32, 4); - - g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, G_MAXUINT32, 8)); - _assert_egress_qos_mappings (ifindex, 5, - 1, 5, - 7, 3, - 9, 5, - 100, 4, - G_MAXUINT32, 4); - - g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, G_MAXUINT32, 0)); - _assert_egress_qos_mappings (ifindex, 4, - 1, 5, - 7, 3, - 9, 5, - 100, 4); - - g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 100, 0)); - _assert_egress_qos_mappings (ifindex, 3, - 1, 5, - 7, 3, - 9, 5); - - g_assert (nm_platform_link_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 1, 0)); - _assert_egress_qos_mappings (ifindex, 2, - 7, 3, - 9, 5); - - { - const NMVlanQosMapping ingress_map[] = { - { .from = 1, .to = 5 }, - }; - - g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET, - ifindex, - 0, - 0, - TRUE, - ingress_map, - G_N_ELEMENTS (ingress_map), - FALSE, - NULL, - 0)); - _assert_ingress_qos_mappings (ifindex, 1, - 1, 5); - } - - { - const NMVlanQosMapping ingress_map[] = { - { .from = 3, .to = 5 }, - { .from = 7, .to = 1655 }, - { .from = 7, .to = 17655 }, - { .from = 5, .to = 754 }, - { .from = 4, .to = 12 }, - }; - - g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET, - ifindex, - 0, - 0, - TRUE, - ingress_map, - G_N_ELEMENTS (ingress_map), - FALSE, - NULL, - 0)); - _assert_ingress_qos_mappings (ifindex, 4, - 3, 5, - 4, 12, - 7, 17655, - 5, 754); - } - - { - const NMVlanQosMapping ingress_map[] = { - { .from = 3, .to = 18 }, - { .from = 6, .to = 121 }, - }; - - g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET, - ifindex, - 0, - 0, - FALSE, - ingress_map, - G_N_ELEMENTS (ingress_map), - FALSE, - NULL, - 0)); - _assert_ingress_qos_mappings (ifindex, 5, - 3, 18, - 4, 12, - 6, 121, - 7, 17655, - 5, 754); - } - - { - const NMVlanQosMapping ingress_map[] = { - { .from = 3, .to = 0 }, - { .from = 6, .to = 7 }, - }; - - g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET, - ifindex, - 0, - 0, - TRUE, - ingress_map, - G_N_ELEMENTS (ingress_map), - FALSE, - NULL, - 0)); - _assert_ingress_qos_mappings (ifindex, 1, - 6, 7); - } - - { - const NMVlanQosMapping ingress_map[] = { - { .from = 1, .to = 5 }, - }; - - g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET, - ifindex, - 0, - 0, - TRUE, - ingress_map, - G_N_ELEMENTS (ingress_map), - FALSE, - NULL, - 0)); - _assert_ingress_qos_mappings (ifindex, 1, - 1, 5); - } - - { - const NMVlanQosMapping egress_map[] = { - { .from = 5, .to = 1 }, - }; - - g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET, - ifindex, - 0, - 0, - FALSE, - NULL, - 0, - TRUE, - egress_map, - G_N_ELEMENTS (egress_map))); - _assert_egress_qos_mappings (ifindex, 1, - 5, 1); - } - - { - const NMVlanQosMapping egress_map[] = { - { .from = 5, .to = 3 }, - { .from = 1655, .to = 5 }, - { .from = 1655, .to = 7 }, - { .from = G_MAXUINT32, .to = 6 }, - { .from = G_MAXUINT32, .to = 8 }, - { .from = 754, .to = 4 }, - { .from = 3, .to = 2 }, - }; - - g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET, - ifindex, - 0, - 0, - FALSE, - NULL, - 0, - TRUE, - egress_map, - G_N_ELEMENTS (egress_map))); - _assert_egress_qos_mappings (ifindex, 5, - 3, 2, - 5, 3, - 754, 4, - 1655, 7, - G_MAXUINT32, 6); - } - - { - const NMVlanQosMapping egress_map[] = { - { .from = 754, .to = 3 }, - { .from = 755, .to = 8 }, - { .from = 1655, .to = 0 }, - { .from = 6, .to = 1 }, - }; - - g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET, - ifindex, - 0, - 0, - FALSE, - NULL, - 0, - FALSE, - egress_map, - G_N_ELEMENTS (egress_map))); - _assert_egress_qos_mappings (ifindex, 5, - 3, 2, - 5, 3, - 6, 1, - 754, 3, - G_MAXUINT32, 6); - } - - { - const NMVlanQosMapping egress_map[] = { - { .from = 6, .to = 0 }, - { .from = 3, .to = 4 }, - }; - - g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET, - ifindex, - 0, - 0, - FALSE, - NULL, - 0, - TRUE, - egress_map, - G_N_ELEMENTS (egress_map))); - _assert_egress_qos_mappings (ifindex, 1, - 3, 4); - } - - { - const NMVlanQosMapping egress_map[] = { - { .from = 1, .to = 5 }, - }; - - g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET, - ifindex, - 0, - 0, - FALSE, - NULL, - 0, - TRUE, - egress_map, - G_N_ELEMENTS (egress_map))); - _assert_egress_qos_mappings (ifindex, 1, - 1, 5); - } - - { - const NMVlanQosMapping ingress_map[] = { - { .from = 6, .to = 145 }, - { .from = 4, .to = 1 }, - { .from = 6, .to = 12 }, - }; - const NMVlanQosMapping egress_map[] = { - { .from = 1, .to = 5 }, - { .from = 3232, .to = 7 }, - }; - - g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET, - ifindex, - NM_VLAN_FLAG_REORDER_HEADERS | NM_VLAN_FLAG_GVRP, - NM_VLAN_FLAG_REORDER_HEADERS, - TRUE, - ingress_map, - G_N_ELEMENTS (ingress_map), - TRUE, - egress_map, - G_N_ELEMENTS (egress_map))); - _assert_ingress_qos_mappings (ifindex, 2, - 4, 1, - 6, 12); - _assert_egress_qos_mappings (ifindex, 2, - 1, 5, - 3232, 7); - _assert_vlan_flags (ifindex, NM_VLAN_FLAG_REORDER_HEADERS); - } - - { - const NMVlanQosMapping ingress_map[] = { - { .from = 6, .to = 145 }, - { .from = 4, .to = 1 }, - { .from = 6, .to = 12 }, - }; - const NMVlanQosMapping egress_map[] = { - { .from = 1, .to = 7 }, - { .from = 64, .to = 10 }, - { .from = 64, .to = 10 }, - { .from = 64, .to = 10 }, - { .from = 64, .to = 10 }, - { .from = 3232, .to = 0 }, - { .from = 64, .to = 4 }, - }; - - g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET, - ifindex, - NM_VLAN_FLAG_GVRP, - NM_VLAN_FLAG_GVRP, - FALSE, - ingress_map, - G_N_ELEMENTS (ingress_map), - FALSE, - egress_map, - G_N_ELEMENTS (egress_map))); - _assert_ingress_qos_mappings (ifindex, 2, - 4, 1, - 6, 12); - _assert_egress_qos_mappings (ifindex, 2, - 1, 7, - 64, 4); - _assert_vlan_flags (ifindex, NM_VLAN_FLAG_REORDER_HEADERS | NM_VLAN_FLAG_GVRP); - } - - nmtstp_link_delete (NULL, -1, ifindex, DEVICE_NAME, TRUE); - nmtstp_link_delete (NULL, -1, ifindex_parent, PARENT_NAME, TRUE); + int ifindex, ifindex_parent; + + nmtstp_run_command_check("ip link add %s type dummy", PARENT_NAME); + ifindex_parent = + nmtstp_assert_wait_for_link(NM_PLATFORM_GET, PARENT_NAME, NM_LINK_TYPE_DUMMY, 100)->ifindex; + + nmtstp_run_command_check("ip link add name %s link %s type vlan id 1245", + DEVICE_NAME, + PARENT_NAME); + ifindex = + nmtstp_assert_wait_for_link(NM_PLATFORM_GET, DEVICE_NAME, NM_LINK_TYPE_VLAN, 100)->ifindex; + + /* ingress-qos-map */ + + g_assert(nm_platform_link_vlan_set_ingress_map(NM_PLATFORM_GET, ifindex, 4, 5)); + _assert_ingress_qos_mappings(ifindex, 1, 4, 5); + + g_assert(nm_platform_link_vlan_set_ingress_map(NM_PLATFORM_GET, ifindex, 3, 7)); + _assert_ingress_qos_mappings(ifindex, 2, 3, 7, 4, 5); + + g_assert(nm_platform_link_vlan_set_ingress_map(NM_PLATFORM_GET, ifindex, 3, 8)); + _assert_ingress_qos_mappings(ifindex, 2, 3, 8, 4, 5); + + g_assert(nm_platform_link_vlan_set_ingress_map(NM_PLATFORM_GET, ifindex, 0, 4)); + _assert_ingress_qos_mappings(ifindex, 3, 0, 4, 3, 8, 4, 5); + + g_assert(nm_platform_link_vlan_set_ingress_map(NM_PLATFORM_GET, ifindex, 0, G_MAXUINT32)); + _assert_ingress_qos_mappings(ifindex, 3, 0, G_MAXUINT32, 3, 8, 4, 5); + + g_assert(nm_platform_link_vlan_set_ingress_map(NM_PLATFORM_GET, ifindex, 0, G_MAXUINT32 - 1)); + _assert_ingress_qos_mappings(ifindex, 3, 0, G_MAXUINT32 - 1, 3, 8, 4, 5); + + g_assert(nm_platform_link_vlan_set_ingress_map(NM_PLATFORM_GET, ifindex, 0, 5)); + _assert_ingress_qos_mappings(ifindex, 3, 0, 5, 3, 8, 4, 5); + + g_assert(nm_platform_link_vlan_set_ingress_map(NM_PLATFORM_GET, ifindex, 0, 5)); + _assert_ingress_qos_mappings(ifindex, 3, 0, 5, 3, 8, 4, 5); + + /* Set invalid values: */ + g_assert(nm_platform_link_vlan_set_ingress_map(NM_PLATFORM_GET, ifindex, 8, 3)); + _assert_ingress_qos_mappings(ifindex, 3, 0, 5, 3, 8, 4, 5); + + g_assert(nm_platform_link_vlan_set_ingress_map(NM_PLATFORM_GET, ifindex, 9, 4)); + _assert_ingress_qos_mappings(ifindex, 3, 0, 5, 3, 8, 4, 5); + + /* egress-qos-map */ + + g_assert(nm_platform_link_vlan_set_egress_map(NM_PLATFORM_GET, ifindex, 7, 3)); + _assert_egress_qos_mappings(ifindex, 1, 7, 3); + + g_assert(nm_platform_link_vlan_set_egress_map(NM_PLATFORM_GET, ifindex, 8, 4)); + _assert_egress_qos_mappings(ifindex, 2, 7, 3, 8, 4); + + g_assert(nm_platform_link_vlan_set_egress_map(NM_PLATFORM_GET, ifindex, 0, 4)); + _assert_egress_qos_mappings(ifindex, 3, 0, 4, 7, 3, 8, 4); + + g_assert(nm_platform_link_vlan_set_egress_map(NM_PLATFORM_GET, ifindex, 1, 4)); + _assert_egress_qos_mappings(ifindex, 4, 0, 4, 1, 4, 7, 3, 8, 4); + + g_assert(nm_platform_link_vlan_set_egress_map(NM_PLATFORM_GET, ifindex, 1, 5)); + _assert_egress_qos_mappings(ifindex, 4, 0, 4, 1, 5, 7, 3, 8, 4); + + g_assert(nm_platform_link_vlan_set_egress_map(NM_PLATFORM_GET, ifindex, 9, 5)); + _assert_egress_qos_mappings(ifindex, 5, 0, 4, 1, 5, 7, 3, 8, 4, 9, 5); + + g_assert(nm_platform_link_vlan_set_egress_map(NM_PLATFORM_GET, ifindex, 8, 5)); + _assert_egress_qos_mappings(ifindex, 5, 0, 4, 1, 5, 7, 3, 8, 5, 9, 5); + + g_assert(nm_platform_link_vlan_set_egress_map(NM_PLATFORM_GET, ifindex, 8, 0)); + _assert_egress_qos_mappings(ifindex, 4, 0, 4, 1, 5, 7, 3, 9, 5); + + g_assert(nm_platform_link_vlan_set_egress_map(NM_PLATFORM_GET, ifindex, 0, 0)); + _assert_egress_qos_mappings(ifindex, 3, 1, 5, 7, 3, 9, 5); + + g_assert(nm_platform_link_vlan_set_egress_map(NM_PLATFORM_GET, ifindex, 100, 4)); + _assert_egress_qos_mappings(ifindex, 4, 1, 5, 7, 3, 9, 5, 100, 4); + + g_assert(nm_platform_link_vlan_set_egress_map(NM_PLATFORM_GET, ifindex, G_MAXUINT32, 4)); + _assert_egress_qos_mappings(ifindex, 5, 1, 5, 7, 3, 9, 5, 100, 4, G_MAXUINT32, 4); + + g_assert(nm_platform_link_vlan_set_egress_map(NM_PLATFORM_GET, ifindex, G_MAXUINT32, 8)); + _assert_egress_qos_mappings(ifindex, 5, 1, 5, 7, 3, 9, 5, 100, 4, G_MAXUINT32, 4); + + g_assert(nm_platform_link_vlan_set_egress_map(NM_PLATFORM_GET, ifindex, G_MAXUINT32, 0)); + _assert_egress_qos_mappings(ifindex, 4, 1, 5, 7, 3, 9, 5, 100, 4); + + g_assert(nm_platform_link_vlan_set_egress_map(NM_PLATFORM_GET, ifindex, 100, 0)); + _assert_egress_qos_mappings(ifindex, 3, 1, 5, 7, 3, 9, 5); + + g_assert(nm_platform_link_vlan_set_egress_map(NM_PLATFORM_GET, ifindex, 1, 0)); + _assert_egress_qos_mappings(ifindex, 2, 7, 3, 9, 5); + + { + const NMVlanQosMapping ingress_map[] = { + {.from = 1, .to = 5}, + }; + + g_assert(nm_platform_link_vlan_change(NM_PLATFORM_GET, + ifindex, + 0, + 0, + TRUE, + ingress_map, + G_N_ELEMENTS(ingress_map), + FALSE, + NULL, + 0)); + _assert_ingress_qos_mappings(ifindex, 1, 1, 5); + } + + { + const NMVlanQosMapping ingress_map[] = { + {.from = 3, .to = 5}, + {.from = 7, .to = 1655}, + {.from = 7, .to = 17655}, + {.from = 5, .to = 754}, + {.from = 4, .to = 12}, + }; + + g_assert(nm_platform_link_vlan_change(NM_PLATFORM_GET, + ifindex, + 0, + 0, + TRUE, + ingress_map, + G_N_ELEMENTS(ingress_map), + FALSE, + NULL, + 0)); + _assert_ingress_qos_mappings(ifindex, 4, 3, 5, 4, 12, 7, 17655, 5, 754); + } + + { + const NMVlanQosMapping ingress_map[] = { + {.from = 3, .to = 18}, + {.from = 6, .to = 121}, + }; + + g_assert(nm_platform_link_vlan_change(NM_PLATFORM_GET, + ifindex, + 0, + 0, + FALSE, + ingress_map, + G_N_ELEMENTS(ingress_map), + FALSE, + NULL, + 0)); + _assert_ingress_qos_mappings(ifindex, 5, 3, 18, 4, 12, 6, 121, 7, 17655, 5, 754); + } + + { + const NMVlanQosMapping ingress_map[] = { + {.from = 3, .to = 0}, + {.from = 6, .to = 7}, + }; + + g_assert(nm_platform_link_vlan_change(NM_PLATFORM_GET, + ifindex, + 0, + 0, + TRUE, + ingress_map, + G_N_ELEMENTS(ingress_map), + FALSE, + NULL, + 0)); + _assert_ingress_qos_mappings(ifindex, 1, 6, 7); + } + + { + const NMVlanQosMapping ingress_map[] = { + {.from = 1, .to = 5}, + }; + + g_assert(nm_platform_link_vlan_change(NM_PLATFORM_GET, + ifindex, + 0, + 0, + TRUE, + ingress_map, + G_N_ELEMENTS(ingress_map), + FALSE, + NULL, + 0)); + _assert_ingress_qos_mappings(ifindex, 1, 1, 5); + } + + { + const NMVlanQosMapping egress_map[] = { + {.from = 5, .to = 1}, + }; + + g_assert(nm_platform_link_vlan_change(NM_PLATFORM_GET, + ifindex, + 0, + 0, + FALSE, + NULL, + 0, + TRUE, + egress_map, + G_N_ELEMENTS(egress_map))); + _assert_egress_qos_mappings(ifindex, 1, 5, 1); + } + + { + const NMVlanQosMapping egress_map[] = { + {.from = 5, .to = 3}, + {.from = 1655, .to = 5}, + {.from = 1655, .to = 7}, + {.from = G_MAXUINT32, .to = 6}, + {.from = G_MAXUINT32, .to = 8}, + {.from = 754, .to = 4}, + {.from = 3, .to = 2}, + }; + + g_assert(nm_platform_link_vlan_change(NM_PLATFORM_GET, + ifindex, + 0, + 0, + FALSE, + NULL, + 0, + TRUE, + egress_map, + G_N_ELEMENTS(egress_map))); + _assert_egress_qos_mappings(ifindex, 5, 3, 2, 5, 3, 754, 4, 1655, 7, G_MAXUINT32, 6); + } + + { + const NMVlanQosMapping egress_map[] = { + {.from = 754, .to = 3}, + {.from = 755, .to = 8}, + {.from = 1655, .to = 0}, + {.from = 6, .to = 1}, + }; + + g_assert(nm_platform_link_vlan_change(NM_PLATFORM_GET, + ifindex, + 0, + 0, + FALSE, + NULL, + 0, + FALSE, + egress_map, + G_N_ELEMENTS(egress_map))); + _assert_egress_qos_mappings(ifindex, 5, 3, 2, 5, 3, 6, 1, 754, 3, G_MAXUINT32, 6); + } + + { + const NMVlanQosMapping egress_map[] = { + {.from = 6, .to = 0}, + {.from = 3, .to = 4}, + }; + + g_assert(nm_platform_link_vlan_change(NM_PLATFORM_GET, + ifindex, + 0, + 0, + FALSE, + NULL, + 0, + TRUE, + egress_map, + G_N_ELEMENTS(egress_map))); + _assert_egress_qos_mappings(ifindex, 1, 3, 4); + } + + { + const NMVlanQosMapping egress_map[] = { + {.from = 1, .to = 5}, + }; + + g_assert(nm_platform_link_vlan_change(NM_PLATFORM_GET, + ifindex, + 0, + 0, + FALSE, + NULL, + 0, + TRUE, + egress_map, + G_N_ELEMENTS(egress_map))); + _assert_egress_qos_mappings(ifindex, 1, 1, 5); + } + + { + const NMVlanQosMapping ingress_map[] = { + {.from = 6, .to = 145}, + {.from = 4, .to = 1}, + {.from = 6, .to = 12}, + }; + const NMVlanQosMapping egress_map[] = { + {.from = 1, .to = 5}, + {.from = 3232, .to = 7}, + }; + + g_assert(nm_platform_link_vlan_change(NM_PLATFORM_GET, + ifindex, + NM_VLAN_FLAG_REORDER_HEADERS | NM_VLAN_FLAG_GVRP, + NM_VLAN_FLAG_REORDER_HEADERS, + TRUE, + ingress_map, + G_N_ELEMENTS(ingress_map), + TRUE, + egress_map, + G_N_ELEMENTS(egress_map))); + _assert_ingress_qos_mappings(ifindex, 2, 4, 1, 6, 12); + _assert_egress_qos_mappings(ifindex, 2, 1, 5, 3232, 7); + _assert_vlan_flags(ifindex, NM_VLAN_FLAG_REORDER_HEADERS); + } + + { + const NMVlanQosMapping ingress_map[] = { + {.from = 6, .to = 145}, + {.from = 4, .to = 1}, + {.from = 6, .to = 12}, + }; + const NMVlanQosMapping egress_map[] = { + {.from = 1, .to = 7}, + {.from = 64, .to = 10}, + {.from = 64, .to = 10}, + {.from = 64, .to = 10}, + {.from = 64, .to = 10}, + {.from = 3232, .to = 0}, + {.from = 64, .to = 4}, + }; + + g_assert(nm_platform_link_vlan_change(NM_PLATFORM_GET, + ifindex, + NM_VLAN_FLAG_GVRP, + NM_VLAN_FLAG_GVRP, + FALSE, + ingress_map, + G_N_ELEMENTS(ingress_map), + FALSE, + egress_map, + G_N_ELEMENTS(egress_map))); + _assert_ingress_qos_mappings(ifindex, 2, 4, 1, 6, 12); + _assert_egress_qos_mappings(ifindex, 2, 1, 7, 64, 4); + _assert_vlan_flags(ifindex, NM_VLAN_FLAG_REORDER_HEADERS | NM_VLAN_FLAG_GVRP); + } + + nmtstp_link_delete(NULL, -1, ifindex, DEVICE_NAME, TRUE); + nmtstp_link_delete(NULL, -1, ifindex_parent, PARENT_NAME, TRUE); } /*****************************************************************************/ static void -test_create_many_links_do (guint n_devices) +test_create_many_links_do(guint n_devices) { - gint64 time, start_time = nm_utils_get_monotonic_timestamp_nsec (); - guint i; - char name[64]; - const NMPlatformLink *pllink; - gs_unref_array GArray *ifindexes = g_array_sized_new (FALSE, FALSE, sizeof (int), n_devices); - const int EX = ((int) (nmtst_get_rand_uint32 () % 4)) - 1; + gint64 time, start_time = nm_utils_get_monotonic_timestamp_nsec(); + guint i; + char name[64]; + const NMPlatformLink *pllink; + gs_unref_array GArray *ifindexes = g_array_sized_new(FALSE, FALSE, sizeof(int), n_devices); + const int EX = ((int) (nmtst_get_rand_uint32() % 4)) - 1; - g_assert (EX >= -1 && EX <= 2); + g_assert(EX >= -1 && EX <= 2); - _LOGI (">>> create devices (EX=%d)...", EX); + _LOGI(">>> create devices (EX=%d)...", EX); - for (i = 0; i < n_devices; i++) { - nm_sprintf_buf (name, "t-%05u", i); - if (EX == 2) { - /* This mode is different from letting nmtstp_link_dummy_add() - * because in this case we don't process any platform events - * while adding all the links. */ - nmtstp_run_command_check ("ip link add %s type dummy", name); - } else - nmtstp_link_dummy_add (NULL, EX, name); - } + for (i = 0; i < n_devices; i++) { + nm_sprintf_buf(name, "t-%05u", i); + if (EX == 2) { + /* This mode is different from letting nmtstp_link_dummy_add() + * because in this case we don't process any platform events + * while adding all the links. */ + nmtstp_run_command_check("ip link add %s type dummy", name); + } else + nmtstp_link_dummy_add(NULL, EX, name); + } - _LOGI (">>> process events after creating devices..."); + _LOGI(">>> process events after creating devices..."); - nm_platform_process_events (NM_PLATFORM_GET); + nm_platform_process_events(NM_PLATFORM_GET); - _LOGI (">>> check devices..."); + _LOGI(">>> check devices..."); - for (i = 0; i < n_devices; i++) { - nm_sprintf_buf (name, "t-%05u", i); + for (i = 0; i < n_devices; i++) { + nm_sprintf_buf(name, "t-%05u", i); - pllink = nm_platform_link_get_by_ifname (NM_PLATFORM_GET, name); - g_assert (pllink); - g_assert_cmpint (pllink->type, ==, NM_LINK_TYPE_DUMMY); - g_assert_cmpstr (pllink->name, ==, name); + pllink = nm_platform_link_get_by_ifname(NM_PLATFORM_GET, name); + g_assert(pllink); + g_assert_cmpint(pllink->type, ==, NM_LINK_TYPE_DUMMY); + g_assert_cmpstr(pllink->name, ==, name); - g_array_append_val (ifindexes, pllink->ifindex); - } + g_array_append_val(ifindexes, pllink->ifindex); + } - _LOGI (">>> delete devices..."); + _LOGI(">>> delete devices..."); - g_assert_cmpint (ifindexes->len, ==, n_devices); - for (i = 0; i < n_devices; i++) { - nm_sprintf_buf (name, "t-%05u", i); + g_assert_cmpint(ifindexes->len, ==, n_devices); + for (i = 0; i < n_devices; i++) { + nm_sprintf_buf(name, "t-%05u", i); - if (EX == 2) - nmtstp_run_command_check ("ip link delete %s", name); - else - nmtstp_link_delete (NULL, EX, g_array_index (ifindexes, int, i), name, TRUE); - } + if (EX == 2) + nmtstp_run_command_check("ip link delete %s", name); + else + nmtstp_link_delete(NULL, EX, g_array_index(ifindexes, int, i), name, TRUE); + } - _LOGI (">>> process events after deleting devices..."); - nm_platform_process_events (NM_PLATFORM_GET); + _LOGI(">>> process events after deleting devices..."); + nm_platform_process_events(NM_PLATFORM_GET); - time = nm_utils_get_monotonic_timestamp_nsec () - start_time; - _LOGI (">>> finished in %ld.%09ld seconds", (long) (time / NM_UTILS_NSEC_PER_SEC), (long) (time % NM_UTILS_NSEC_PER_SEC)); + time = nm_utils_get_monotonic_timestamp_nsec() - start_time; + _LOGI(">>> finished in %ld.%09ld seconds", + (long) (time / NM_UTILS_NSEC_PER_SEC), + (long) (time % NM_UTILS_NSEC_PER_SEC)); } static void -test_create_many_links (gconstpointer user_data) +test_create_many_links(gconstpointer user_data) { - guint n_devices = GPOINTER_TO_UINT (user_data); + guint n_devices = GPOINTER_TO_UINT(user_data); - if (n_devices > 100 && nmtst_test_quick ()) { - g_print ("Skipping test: don't run long running test %s (NMTST_DEBUG=slow)\n", g_get_prgname () ?: "test-link-linux"); - g_test_skip ("Skip long running test"); - return; - } + if (n_devices > 100 && nmtst_test_quick()) { + g_print("Skipping test: don't run long running test %s (NMTST_DEBUG=slow)\n", + g_get_prgname() ?: "test-link-linux"); + g_test_skip("Skip long running test"); + return; + } - test_create_many_links_do (n_devices); + test_create_many_links_do(n_devices); } /*****************************************************************************/ static void -test_nl_bugs_veth (void) +test_nl_bugs_veth(void) { - const char *IFACE_VETH0 = "nm-test-veth0"; - const char *IFACE_VETH1 = "nm-test-veth1"; - int ifindex_veth0, ifindex_veth1; - int i; - const NMPlatformLink *pllink_veth0, *pllink_veth1; - gs_free_error GError *error = NULL; - NMTstpNamespaceHandle *ns_handle = NULL; - - /* create veth pair. */ - ifindex_veth0 = nmtstp_link_veth_add (NM_PLATFORM_GET, -1, IFACE_VETH0, IFACE_VETH1)->ifindex; - ifindex_veth1 = nmtstp_link_get_typed (NM_PLATFORM_GET, -1, IFACE_VETH1, NM_LINK_TYPE_VETH)->ifindex; - - /* assert that nm_platform_link_veth_get_properties() returns the expected peer ifindexes. */ - g_assert (nm_platform_link_veth_get_properties (NM_PLATFORM_GET, ifindex_veth0, &i)); - g_assert_cmpint (i, ==, ifindex_veth1); - - g_assert (nm_platform_link_veth_get_properties (NM_PLATFORM_GET, ifindex_veth1, &i)); - g_assert_cmpint (i, ==, ifindex_veth0); - - /* assert that NMPlatformLink.parent is the peer-ifindex. */ - pllink_veth0 = nm_platform_link_get (NM_PLATFORM_GET, ifindex_veth0); - g_assert (pllink_veth0); - if (pllink_veth0->parent == 0) { - /* Kernels prior to 4.1 dated 21 June, 2015 don't support exposing the veth peer - * as IFA_LINK. skip the remainder of the test. */ - goto out; - } - g_assert_cmpint (pllink_veth0->parent, ==, ifindex_veth1); - - /* The following tests whether we have a workaround for kernel bug - * https://bugzilla.redhat.com/show_bug.cgi?id=1285827 in place. */ - pllink_veth1 = nm_platform_link_get (NM_PLATFORM_GET, ifindex_veth1); - g_assert (pllink_veth1); - g_assert_cmpint (pllink_veth1->parent, ==, ifindex_veth0); - - /* move one veth peer to another namespace and check that the - * parent/IFLA_LINK of the remaining peer properly updates - * (https://bugzilla.redhat.com/show_bug.cgi?id=1262908). */ - ns_handle = nmtstp_namespace_create (CLONE_NEWNET, &error); - g_assert_no_error (error); - g_assert (ns_handle); - - nmtstp_run_command_check ("ip link set %s netns %ld", IFACE_VETH1, (long) nmtstp_namespace_handle_get_pid (ns_handle)); - NMTST_WAIT_ASSERT (100, { - nmtstp_wait_for_signal (NM_PLATFORM_GET, 50); - nm_platform_process_events (NM_PLATFORM_GET); - - pllink_veth1 = nm_platform_link_get (NM_PLATFORM_GET, ifindex_veth1); - pllink_veth0 = nm_platform_link_get (NM_PLATFORM_GET, ifindex_veth0); - if ( !pllink_veth1 - && pllink_veth0 - && pllink_veth0->parent == NM_PLATFORM_LINK_OTHER_NETNS) { - break; - } - }); + const char * IFACE_VETH0 = "nm-test-veth0"; + const char * IFACE_VETH1 = "nm-test-veth1"; + int ifindex_veth0, ifindex_veth1; + int i; + const NMPlatformLink *pllink_veth0, *pllink_veth1; + gs_free_error GError * error = NULL; + NMTstpNamespaceHandle *ns_handle = NULL; + + /* create veth pair. */ + ifindex_veth0 = nmtstp_link_veth_add(NM_PLATFORM_GET, -1, IFACE_VETH0, IFACE_VETH1)->ifindex; + ifindex_veth1 = + nmtstp_link_get_typed(NM_PLATFORM_GET, -1, IFACE_VETH1, NM_LINK_TYPE_VETH)->ifindex; + + /* assert that nm_platform_link_veth_get_properties() returns the expected peer ifindexes. */ + g_assert(nm_platform_link_veth_get_properties(NM_PLATFORM_GET, ifindex_veth0, &i)); + g_assert_cmpint(i, ==, ifindex_veth1); + + g_assert(nm_platform_link_veth_get_properties(NM_PLATFORM_GET, ifindex_veth1, &i)); + g_assert_cmpint(i, ==, ifindex_veth0); + + /* assert that NMPlatformLink.parent is the peer-ifindex. */ + pllink_veth0 = nm_platform_link_get(NM_PLATFORM_GET, ifindex_veth0); + g_assert(pllink_veth0); + if (pllink_veth0->parent == 0) { + /* Kernels prior to 4.1 dated 21 June, 2015 don't support exposing the veth peer + * as IFA_LINK. skip the remainder of the test. */ + goto out; + } + g_assert_cmpint(pllink_veth0->parent, ==, ifindex_veth1); + + /* The following tests whether we have a workaround for kernel bug + * https://bugzilla.redhat.com/show_bug.cgi?id=1285827 in place. */ + pllink_veth1 = nm_platform_link_get(NM_PLATFORM_GET, ifindex_veth1); + g_assert(pllink_veth1); + g_assert_cmpint(pllink_veth1->parent, ==, ifindex_veth0); + + /* move one veth peer to another namespace and check that the + * parent/IFLA_LINK of the remaining peer properly updates + * (https://bugzilla.redhat.com/show_bug.cgi?id=1262908). */ + ns_handle = nmtstp_namespace_create(CLONE_NEWNET, &error); + g_assert_no_error(error); + g_assert(ns_handle); + + nmtstp_run_command_check("ip link set %s netns %ld", + IFACE_VETH1, + (long) nmtstp_namespace_handle_get_pid(ns_handle)); + NMTST_WAIT_ASSERT(100, { + nmtstp_wait_for_signal(NM_PLATFORM_GET, 50); + nm_platform_process_events(NM_PLATFORM_GET); + + pllink_veth1 = nm_platform_link_get(NM_PLATFORM_GET, ifindex_veth1); + pllink_veth0 = nm_platform_link_get(NM_PLATFORM_GET, ifindex_veth0); + if (!pllink_veth1 && pllink_veth0 && pllink_veth0->parent == NM_PLATFORM_LINK_OTHER_NETNS) { + break; + } + }); out: - nmtstp_link_delete (NULL, -1, ifindex_veth0, IFACE_VETH0, TRUE); - g_assert (!nmtstp_link_get (NM_PLATFORM_GET, ifindex_veth0, IFACE_VETH0)); - g_assert (!nmtstp_link_get (NM_PLATFORM_GET, ifindex_veth1, IFACE_VETH1)); - nmtstp_namespace_handle_release (ns_handle); + nmtstp_link_delete(NULL, -1, ifindex_veth0, IFACE_VETH0, TRUE); + g_assert(!nmtstp_link_get(NM_PLATFORM_GET, ifindex_veth0, IFACE_VETH0)); + g_assert(!nmtstp_link_get(NM_PLATFORM_GET, ifindex_veth1, IFACE_VETH1)); + nmtstp_namespace_handle_release(ns_handle); } /*****************************************************************************/ static void -test_nl_bugs_spuroius_newlink (void) +test_nl_bugs_spuroius_newlink(void) { - const char *IFACE_BOND0 = "nm-test-bond0"; - const char *IFACE_DUMMY0 = "nm-test-dummy0"; - int ifindex_bond0, ifindex_dummy0; - const NMPlatformLink *pllink; - gboolean wait_for_settle; + const char * IFACE_BOND0 = "nm-test-bond0"; + const char * IFACE_DUMMY0 = "nm-test-dummy0"; + int ifindex_bond0, ifindex_dummy0; + const NMPlatformLink *pllink; + gboolean wait_for_settle; - /* see https://bugzilla.redhat.com/show_bug.cgi?id=1285719 */ + /* see https://bugzilla.redhat.com/show_bug.cgi?id=1285719 */ - nmtstp_run_command_check ("ip link add %s type dummy", IFACE_DUMMY0); - ifindex_dummy0 = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, IFACE_DUMMY0, NM_LINK_TYPE_DUMMY, 100)->ifindex; + nmtstp_run_command_check("ip link add %s type dummy", IFACE_DUMMY0); + ifindex_dummy0 = + nmtstp_assert_wait_for_link(NM_PLATFORM_GET, IFACE_DUMMY0, NM_LINK_TYPE_DUMMY, 100) + ->ifindex; - nmtstp_run_command_check ("ip link add %s type bond", IFACE_BOND0); - ifindex_bond0 = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, IFACE_BOND0, NM_LINK_TYPE_BOND, 100)->ifindex; + nmtstp_run_command_check("ip link add %s type bond", IFACE_BOND0); + ifindex_bond0 = + nmtstp_assert_wait_for_link(NM_PLATFORM_GET, IFACE_BOND0, NM_LINK_TYPE_BOND, 100)->ifindex; - nmtstp_link_set_updown (NULL, -1, ifindex_bond0, TRUE); + nmtstp_link_set_updown(NULL, -1, ifindex_bond0, TRUE); - nmtstp_run_command_check ("ip link set %s master %s", IFACE_DUMMY0, IFACE_BOND0); - NMTST_WAIT_ASSERT (100, { - nmtstp_wait_for_signal (NM_PLATFORM_GET, 50); + nmtstp_run_command_check("ip link set %s master %s", IFACE_DUMMY0, IFACE_BOND0); + NMTST_WAIT_ASSERT(100, { + nmtstp_wait_for_signal(NM_PLATFORM_GET, 50); - pllink = nm_platform_link_get (NM_PLATFORM_GET, ifindex_dummy0); - g_assert (pllink); - if (pllink->master == ifindex_bond0) - break; - }); + pllink = nm_platform_link_get(NM_PLATFORM_GET, ifindex_dummy0); + g_assert(pllink); + if (pllink->master == ifindex_bond0) + break; + }); - nmtstp_run_command_check ("ip link del %s", IFACE_BOND0); + nmtstp_run_command_check("ip link del %s", IFACE_BOND0); - wait_for_settle = TRUE; - nmtstp_wait_for_signal (NM_PLATFORM_GET, 50); + wait_for_settle = TRUE; + nmtstp_wait_for_signal(NM_PLATFORM_GET, 50); again: - nm_platform_process_events (NM_PLATFORM_GET); - pllink = nm_platform_link_get (NM_PLATFORM_GET, ifindex_bond0); - g_assert (!pllink); - - if (wait_for_settle) { - wait_for_settle = FALSE; - NMTST_WAIT (300, { nmtstp_wait_for_signal (NM_PLATFORM_GET, 50); }); - goto again; - } - - g_assert (!nmtstp_link_get (NM_PLATFORM_GET, ifindex_bond0, IFACE_BOND0)); - nmtstp_link_delete (NULL, -1, ifindex_dummy0, IFACE_DUMMY0, TRUE); + nm_platform_process_events(NM_PLATFORM_GET); + pllink = nm_platform_link_get(NM_PLATFORM_GET, ifindex_bond0); + g_assert(!pllink); + + if (wait_for_settle) { + wait_for_settle = FALSE; + NMTST_WAIT(300, { nmtstp_wait_for_signal(NM_PLATFORM_GET, 50); }); + goto again; + } + + g_assert(!nmtstp_link_get(NM_PLATFORM_GET, ifindex_bond0, IFACE_BOND0)); + nmtstp_link_delete(NULL, -1, ifindex_dummy0, IFACE_DUMMY0, TRUE); } /*****************************************************************************/ static void -test_nl_bugs_spuroius_dellink (void) +test_nl_bugs_spuroius_dellink(void) { - const char *IFACE_BRIDGE0 = "nm-test-bridge0"; - const char *IFACE_DUMMY0 = "nm-test-dummy0"; - int ifindex_bridge0, ifindex_dummy0; - const NMPlatformLink *pllink; - gboolean wait_for_settle; + const char * IFACE_BRIDGE0 = "nm-test-bridge0"; + const char * IFACE_DUMMY0 = "nm-test-dummy0"; + int ifindex_bridge0, ifindex_dummy0; + const NMPlatformLink *pllink; + gboolean wait_for_settle; - /* see https://bugzilla.redhat.com/show_bug.cgi?id=1285719 */ + /* see https://bugzilla.redhat.com/show_bug.cgi?id=1285719 */ - nmtstp_run_command_check ("ip link add %s type dummy", IFACE_DUMMY0); - ifindex_dummy0 = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, IFACE_DUMMY0, NM_LINK_TYPE_DUMMY, 100)->ifindex; + nmtstp_run_command_check("ip link add %s type dummy", IFACE_DUMMY0); + ifindex_dummy0 = + nmtstp_assert_wait_for_link(NM_PLATFORM_GET, IFACE_DUMMY0, NM_LINK_TYPE_DUMMY, 100) + ->ifindex; - nmtstp_run_command_check ("ip link add %s type bridge", IFACE_BRIDGE0); - ifindex_bridge0 = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, IFACE_BRIDGE0, NM_LINK_TYPE_BRIDGE, 100)->ifindex; + nmtstp_run_command_check("ip link add %s type bridge", IFACE_BRIDGE0); + ifindex_bridge0 = + nmtstp_assert_wait_for_link(NM_PLATFORM_GET, IFACE_BRIDGE0, NM_LINK_TYPE_BRIDGE, 100) + ->ifindex; - nmtstp_link_set_updown (NULL, -1, ifindex_bridge0, TRUE); + nmtstp_link_set_updown(NULL, -1, ifindex_bridge0, TRUE); - nmtstp_run_command_check ("ip link set %s master %s", IFACE_DUMMY0, IFACE_BRIDGE0); - NMTST_WAIT_ASSERT (100, { - nmtstp_wait_for_signal (NM_PLATFORM_GET, 50); + nmtstp_run_command_check("ip link set %s master %s", IFACE_DUMMY0, IFACE_BRIDGE0); + NMTST_WAIT_ASSERT(100, { + nmtstp_wait_for_signal(NM_PLATFORM_GET, 50); - pllink = nm_platform_link_get (NM_PLATFORM_GET, ifindex_dummy0); - g_assert (pllink); - if (pllink->master == ifindex_bridge0) - break; - }); + pllink = nm_platform_link_get(NM_PLATFORM_GET, ifindex_dummy0); + g_assert(pllink); + if (pllink->master == ifindex_bridge0) + break; + }); - nm_platform_process_events (NM_PLATFORM_GET); + nm_platform_process_events(NM_PLATFORM_GET); - nmtstp_run_command_check ("ip link set %s nomaster", IFACE_DUMMY0); + nmtstp_run_command_check("ip link set %s nomaster", IFACE_DUMMY0); - wait_for_settle = TRUE; - nmtstp_wait_for_signal (NM_PLATFORM_GET, 50); + wait_for_settle = TRUE; + nmtstp_wait_for_signal(NM_PLATFORM_GET, 50); again: - nm_platform_process_events (NM_PLATFORM_GET); - pllink = nm_platform_link_get (NM_PLATFORM_GET, ifindex_bridge0); - g_assert (pllink); - pllink = nm_platform_link_get (NM_PLATFORM_GET, ifindex_dummy0); - g_assert (pllink); - g_assert_cmpint (pllink->parent, ==, 0); - - if (wait_for_settle) { - wait_for_settle = FALSE; - NMTST_WAIT (300, { nmtstp_wait_for_signal (NM_PLATFORM_GET, 50); }); - goto again; - } - - nmtstp_link_delete (NULL, -1, ifindex_bridge0, IFACE_BRIDGE0, TRUE); - nmtstp_link_delete (NULL, -1, ifindex_dummy0, IFACE_DUMMY0, TRUE); + nm_platform_process_events(NM_PLATFORM_GET); + pllink = nm_platform_link_get(NM_PLATFORM_GET, ifindex_bridge0); + g_assert(pllink); + pllink = nm_platform_link_get(NM_PLATFORM_GET, ifindex_dummy0); + g_assert(pllink); + g_assert_cmpint(pllink->parent, ==, 0); + + if (wait_for_settle) { + wait_for_settle = FALSE; + NMTST_WAIT(300, { nmtstp_wait_for_signal(NM_PLATFORM_GET, 50); }); + goto again; + } + + nmtstp_link_delete(NULL, -1, ifindex_bridge0, IFACE_BRIDGE0, TRUE); + nmtstp_link_delete(NULL, -1, ifindex_dummy0, IFACE_DUMMY0, TRUE); } /*****************************************************************************/ static void -_test_netns_setup (gpointer fixture, gconstpointer test_data) +_test_netns_setup(gpointer fixture, gconstpointer test_data) { - /* the singleton platform instance has netns support disabled. - * Destroy the instance before the test and re-create it afterwards. */ - g_object_unref (NM_PLATFORM_GET); + /* the singleton platform instance has netns support disabled. + * Destroy the instance before the test and re-create it afterwards. */ + g_object_unref(NM_PLATFORM_GET); } static void -_test_netns_teardown (gpointer fixture, gconstpointer test_data) +_test_netns_teardown(gpointer fixture, gconstpointer test_data) { - nmtstp_setup_platform (); + nmtstp_setup_platform(); } static NMPlatform * -_test_netns_create_platform (void) +_test_netns_create_platform(void) { - NMPNetns *netns; - NMPlatform *platform; + NMPNetns * netns; + NMPlatform *platform; - netns = nmp_netns_new (); - g_assert (NMP_IS_NETNS (netns)); + netns = nmp_netns_new(); + g_assert(NMP_IS_NETNS(netns)); - platform = nm_linux_platform_new (TRUE, TRUE); - g_assert (NM_IS_LINUX_PLATFORM (platform)); + platform = nm_linux_platform_new(TRUE, TRUE); + g_assert(NM_IS_LINUX_PLATFORM(platform)); - nmp_netns_pop (netns); - g_object_unref (netns); + nmp_netns_pop(netns); + g_object_unref(netns); - return platform; + return platform; } static gboolean -_test_netns_check_skip (void) +_test_netns_check_skip(void) { - static int support = -1; - static int support_errsv = 0; - NMPNetns *netns; - gs_unref_object NMPNetns *netns2 = NULL; - - netns = nmp_netns_get_current (); - if (!netns) { - g_test_skip ("No netns support"); - return TRUE; - } - - g_assert (nmp_netns_get_fd_net (netns) > 0); - - if (support == -1) { - support = (setns (nmp_netns_get_fd_net (netns), CLONE_NEWNET) == 0); - if (!support) - support_errsv = errno; - } - if (!support) { - _LOGD ("setns() failed with \"%s\". This indicates missing support (valgrind?)", nm_strerror_native (support_errsv)); - g_test_skip ("No netns support (setns failed)"); - return TRUE; - } - - netns2 = nmp_netns_new (); - if (!netns2) { - /* skip tests for https://bugzilla.gnome.org/show_bug.cgi?id=790214 */ - g_assert_cmpint (errno, ==, EINVAL); - g_test_skip ("No netns support to create another netns"); - return TRUE; - } - nmp_netns_pop (netns2); - - return FALSE; + static int support = -1; + static int support_errsv = 0; + NMPNetns * netns; + gs_unref_object NMPNetns *netns2 = NULL; + + netns = nmp_netns_get_current(); + if (!netns) { + g_test_skip("No netns support"); + return TRUE; + } + + g_assert(nmp_netns_get_fd_net(netns) > 0); + + if (support == -1) { + support = (setns(nmp_netns_get_fd_net(netns), CLONE_NEWNET) == 0); + if (!support) + support_errsv = errno; + } + if (!support) { + _LOGD("setns() failed with \"%s\". This indicates missing support (valgrind?)", + nm_strerror_native(support_errsv)); + g_test_skip("No netns support (setns failed)"); + return TRUE; + } + + netns2 = nmp_netns_new(); + if (!netns2) { + /* skip tests for https://bugzilla.gnome.org/show_bug.cgi?id=790214 */ + g_assert_cmpint(errno, ==, EINVAL); + g_test_skip("No netns support to create another netns"); + return TRUE; + } + nmp_netns_pop(netns2); + + return FALSE; } static gboolean -_check_sysctl_skip (void) +_check_sysctl_skip(void) { - if (access ("/proc/sys/net/ipv4/ip_forward", W_OK) == -1) { - g_test_skip ("Can not write sysctls"); - return TRUE; - } + if (access("/proc/sys/net/ipv4/ip_forward", W_OK) == -1) { + g_test_skip("Can not write sysctls"); + return TRUE; + } - return FALSE; + return FALSE; } /*****************************************************************************/ -#define _sysctl_assert_eq(plat, path, value) \ - G_STMT_START { \ - gs_free char *_val = NULL; \ - \ - _val = nm_platform_sysctl_get (plat, NMP_SYSCTL_PATHID_ABSOLUTE (path)); \ - g_assert_cmpstr (_val, ==, value); \ - } G_STMT_END +#define _sysctl_assert_eq(plat, path, value) \ + G_STMT_START \ + { \ + gs_free char *_val = NULL; \ + \ + _val = nm_platform_sysctl_get(plat, NMP_SYSCTL_PATHID_ABSOLUTE(path)); \ + g_assert_cmpstr(_val, ==, value); \ + } \ + G_STMT_END static void -test_netns_general (gpointer fixture, gconstpointer test_data) +test_netns_general(gpointer fixture, gconstpointer test_data) { - gs_unref_object NMPlatform *platform_1 = NULL; - gs_unref_object NMPlatform *platform_2 = NULL; - NMPNetns *netns_tmp; - char sbuf[100]; - int i, j, k; - gboolean ethtool_support; - NMPUtilsEthtoolDriverInfo driver_info; - - if (_test_netns_check_skip ()) - return; - - if (_check_sysctl_skip ()) - return; - - platform_1 = nm_linux_platform_new (TRUE, TRUE); - platform_2 = _test_netns_create_platform (); - - /* add some dummy devices. The "other-*" devices are there to bump the ifindex */ - for (k = 0; k < 2; k++) { - NMPlatform *p = (k == 0 ? platform_1 : platform_2); - const char *id = (k == 0 ? "a" : "b"); - - for (i = 0, j = nmtst_get_rand_uint32 () % 5; i < j; i++) - _ADD_DUMMY (p, nm_sprintf_buf (sbuf, "other-a-%s-%02d", id, i)); - - _ADD_DUMMY (p, "dummy1_"); - - for (i = 0, j = nmtst_get_rand_uint32 () % 5; i < j; i++) - _ADD_DUMMY (p, nm_sprintf_buf (sbuf, "other-b-%s-%02d", id, i)); - - _ADD_DUMMY (p, nm_sprintf_buf (sbuf, "dummy2%s", id)); - - for (i = 0, j = nmtst_get_rand_uint32 () % 5; i < j; i++) - _ADD_DUMMY (p, nm_sprintf_buf (sbuf, "other-c-%s-%02d", id, i)); - } - - _sysctl_assert_eq (platform_1,"/sys/devices/virtual/net/dummy1_/ifindex", - nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_1, 0, "dummy1_", NM_LINK_TYPE_DUMMY)->ifindex)); - _sysctl_assert_eq (platform_1, "/sys/devices/virtual/net/dummy2a/ifindex", - nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_1, 0, "dummy2a", NM_LINK_TYPE_DUMMY)->ifindex)); - _sysctl_assert_eq (platform_1, "/sys/devices/virtual/net/dummy2b/ifindex", - NULL); - - _sysctl_assert_eq (platform_2, "/sys/devices/virtual/net/dummy1_/ifindex", - nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_2, 0, "dummy1_", NM_LINK_TYPE_DUMMY)->ifindex)); - _sysctl_assert_eq (platform_2, "/sys/devices/virtual/net/dummy2a/ifindex", - NULL); - _sysctl_assert_eq (platform_2, "/sys/devices/virtual/net/dummy2b/ifindex", - nm_sprintf_buf (sbuf, "%d", nmtstp_link_get_typed (platform_2, 0, "dummy2b", NM_LINK_TYPE_DUMMY)->ifindex)); - - for (i = 0; i < 10; i++) { - NMPlatform *pl; - const char *path; - - j = nmtst_get_rand_uint32 () % 2; - - if (nmtst_get_rand_uint32 () % 2) { - pl = platform_1; - if (nmtst_get_rand_uint32 () % 2) - path = "/proc/sys/net/ipv6/conf/dummy1_/disable_ipv6"; - else - path = "/proc/sys/net/ipv6/conf/dummy2a/disable_ipv6"; - } else { - pl = platform_2; - if (nmtst_get_rand_uint32 () % 2) - path = "/proc/sys/net/ipv6/conf/dummy1_/disable_ipv6"; - else - path = "/proc/sys/net/ipv6/conf/dummy2b/disable_ipv6"; - } - g_assert (nm_platform_sysctl_set (pl, NMP_SYSCTL_PATHID_ABSOLUTE (path), nm_sprintf_buf (sbuf, "%d", j))); - _sysctl_assert_eq (pl, path, nm_sprintf_buf (sbuf, "%d", j)); - } - - _sysctl_assert_eq (platform_1, "/proc/sys/net/ipv6/conf/dummy2b/disable_ipv6", NULL); - _sysctl_assert_eq (platform_2, "/proc/sys/net/ipv6/conf/dummy2a/disable_ipv6", NULL); - - /* Kernels prior to 3.19 dated 8 February, 2015 don't support ethtool -i for dummy devices. - * Work around that and skip asserts that are known to fail. */ - ethtool_support = nmtstp_run_command ("ethtool -i dummy1_ > /dev/null") == 0; - if (ethtool_support) { - g_assert (nmp_utils_ethtool_get_driver_info (nmtstp_link_get_typed (platform_1, 0, "dummy1_", NM_LINK_TYPE_DUMMY)->ifindex, &driver_info)); - g_assert (nmp_utils_ethtool_get_driver_info (nmtstp_link_get_typed (platform_1, 0, "dummy2a", NM_LINK_TYPE_DUMMY)->ifindex, &driver_info)); - g_assert_cmpint (nmtstp_run_command ("ethtool -i dummy1_ > /dev/null"), ==, 0); - g_assert_cmpint (nmtstp_run_command ("ethtool -i dummy2a > /dev/null"), ==, 0); - g_assert_cmpint (nmtstp_run_command ("ethtool -i dummy2b 2> /dev/null"), !=, 0); - } - - g_assert (nm_platform_netns_push (platform_2, &netns_tmp)); - - if (ethtool_support) { - g_assert (nmp_utils_ethtool_get_driver_info (nmtstp_link_get_typed (platform_2, 0, "dummy1_", NM_LINK_TYPE_DUMMY)->ifindex, &driver_info)); - g_assert (nmp_utils_ethtool_get_driver_info (nmtstp_link_get_typed (platform_2, 0, "dummy2b", NM_LINK_TYPE_DUMMY)->ifindex, &driver_info)); - g_assert_cmpint (nmtstp_run_command ("ethtool -i dummy1_ > /dev/null"), ==, 0); - g_assert_cmpint (nmtstp_run_command ("ethtool -i dummy2a 2> /dev/null"), !=, 0); - g_assert_cmpint (nmtstp_run_command ("ethtool -i dummy2b > /dev/null"), ==, 0); - } - - nmp_netns_pop (netns_tmp); + gs_unref_object NMPlatform *platform_1 = NULL; + gs_unref_object NMPlatform *platform_2 = NULL; + NMPNetns * netns_tmp; + char sbuf[100]; + int i, j, k; + gboolean ethtool_support; + NMPUtilsEthtoolDriverInfo driver_info; + + if (_test_netns_check_skip()) + return; + + if (_check_sysctl_skip()) + return; + + platform_1 = nm_linux_platform_new(TRUE, TRUE); + platform_2 = _test_netns_create_platform(); + + /* add some dummy devices. The "other-*" devices are there to bump the ifindex */ + for (k = 0; k < 2; k++) { + NMPlatform *p = (k == 0 ? platform_1 : platform_2); + const char *id = (k == 0 ? "a" : "b"); + + for (i = 0, j = nmtst_get_rand_uint32() % 5; i < j; i++) + _ADD_DUMMY(p, nm_sprintf_buf(sbuf, "other-a-%s-%02d", id, i)); + + _ADD_DUMMY(p, "dummy1_"); + + for (i = 0, j = nmtst_get_rand_uint32() % 5; i < j; i++) + _ADD_DUMMY(p, nm_sprintf_buf(sbuf, "other-b-%s-%02d", id, i)); + + _ADD_DUMMY(p, nm_sprintf_buf(sbuf, "dummy2%s", id)); + + for (i = 0, j = nmtst_get_rand_uint32() % 5; i < j; i++) + _ADD_DUMMY(p, nm_sprintf_buf(sbuf, "other-c-%s-%02d", id, i)); + } + + _sysctl_assert_eq( + platform_1, + "/sys/devices/virtual/net/dummy1_/ifindex", + nm_sprintf_buf( + sbuf, + "%d", + nmtstp_link_get_typed(platform_1, 0, "dummy1_", NM_LINK_TYPE_DUMMY)->ifindex)); + _sysctl_assert_eq( + platform_1, + "/sys/devices/virtual/net/dummy2a/ifindex", + nm_sprintf_buf( + sbuf, + "%d", + nmtstp_link_get_typed(platform_1, 0, "dummy2a", NM_LINK_TYPE_DUMMY)->ifindex)); + _sysctl_assert_eq(platform_1, "/sys/devices/virtual/net/dummy2b/ifindex", NULL); + + _sysctl_assert_eq( + platform_2, + "/sys/devices/virtual/net/dummy1_/ifindex", + nm_sprintf_buf( + sbuf, + "%d", + nmtstp_link_get_typed(platform_2, 0, "dummy1_", NM_LINK_TYPE_DUMMY)->ifindex)); + _sysctl_assert_eq(platform_2, "/sys/devices/virtual/net/dummy2a/ifindex", NULL); + _sysctl_assert_eq( + platform_2, + "/sys/devices/virtual/net/dummy2b/ifindex", + nm_sprintf_buf( + sbuf, + "%d", + nmtstp_link_get_typed(platform_2, 0, "dummy2b", NM_LINK_TYPE_DUMMY)->ifindex)); + + for (i = 0; i < 10; i++) { + NMPlatform *pl; + const char *path; + + j = nmtst_get_rand_uint32() % 2; + + if (nmtst_get_rand_uint32() % 2) { + pl = platform_1; + if (nmtst_get_rand_uint32() % 2) + path = "/proc/sys/net/ipv6/conf/dummy1_/disable_ipv6"; + else + path = "/proc/sys/net/ipv6/conf/dummy2a/disable_ipv6"; + } else { + pl = platform_2; + if (nmtst_get_rand_uint32() % 2) + path = "/proc/sys/net/ipv6/conf/dummy1_/disable_ipv6"; + else + path = "/proc/sys/net/ipv6/conf/dummy2b/disable_ipv6"; + } + g_assert(nm_platform_sysctl_set(pl, + NMP_SYSCTL_PATHID_ABSOLUTE(path), + nm_sprintf_buf(sbuf, "%d", j))); + _sysctl_assert_eq(pl, path, nm_sprintf_buf(sbuf, "%d", j)); + } + + _sysctl_assert_eq(platform_1, "/proc/sys/net/ipv6/conf/dummy2b/disable_ipv6", NULL); + _sysctl_assert_eq(platform_2, "/proc/sys/net/ipv6/conf/dummy2a/disable_ipv6", NULL); + + /* Kernels prior to 3.19 dated 8 February, 2015 don't support ethtool -i for dummy devices. + * Work around that and skip asserts that are known to fail. */ + ethtool_support = nmtstp_run_command("ethtool -i dummy1_ > /dev/null") == 0; + if (ethtool_support) { + g_assert(nmp_utils_ethtool_get_driver_info( + nmtstp_link_get_typed(platform_1, 0, "dummy1_", NM_LINK_TYPE_DUMMY)->ifindex, + &driver_info)); + g_assert(nmp_utils_ethtool_get_driver_info( + nmtstp_link_get_typed(platform_1, 0, "dummy2a", NM_LINK_TYPE_DUMMY)->ifindex, + &driver_info)); + g_assert_cmpint(nmtstp_run_command("ethtool -i dummy1_ > /dev/null"), ==, 0); + g_assert_cmpint(nmtstp_run_command("ethtool -i dummy2a > /dev/null"), ==, 0); + g_assert_cmpint(nmtstp_run_command("ethtool -i dummy2b 2> /dev/null"), !=, 0); + } + + g_assert(nm_platform_netns_push(platform_2, &netns_tmp)); + + if (ethtool_support) { + g_assert(nmp_utils_ethtool_get_driver_info( + nmtstp_link_get_typed(platform_2, 0, "dummy1_", NM_LINK_TYPE_DUMMY)->ifindex, + &driver_info)); + g_assert(nmp_utils_ethtool_get_driver_info( + nmtstp_link_get_typed(platform_2, 0, "dummy2b", NM_LINK_TYPE_DUMMY)->ifindex, + &driver_info)); + g_assert_cmpint(nmtstp_run_command("ethtool -i dummy1_ > /dev/null"), ==, 0); + g_assert_cmpint(nmtstp_run_command("ethtool -i dummy2a 2> /dev/null"), !=, 0); + g_assert_cmpint(nmtstp_run_command("ethtool -i dummy2b > /dev/null"), ==, 0); + } + + nmp_netns_pop(netns_tmp); } /*****************************************************************************/ static void -test_netns_set_netns (gpointer fixture, gconstpointer test_data) +test_netns_set_netns(gpointer fixture, gconstpointer test_data) { - NMPlatform *platforms[3]; - gs_unref_object NMPlatform *platform_0 = NULL; - gs_unref_object NMPlatform *platform_1 = NULL; - gs_unref_object NMPlatform *platform_2 = NULL; - nm_auto_pop_netns NMPNetns *netns_pop = NULL; + NMPlatform * platforms[3]; + gs_unref_object NMPlatform *platform_0 = NULL; + gs_unref_object NMPlatform *platform_1 = NULL; + gs_unref_object NMPlatform *platform_2 = NULL; + nm_auto_pop_netns NMPNetns *netns_pop = NULL; - if (_test_netns_check_skip ()) - return; + if (_test_netns_check_skip()) + return; - platforms[0] = platform_0 = nm_linux_platform_new (TRUE, TRUE); - platforms[1] = platform_1 = _test_netns_create_platform (); - platforms[2] = platform_2 = _test_netns_create_platform (); + platforms[0] = platform_0 = nm_linux_platform_new(TRUE, TRUE); + platforms[1] = platform_1 = _test_netns_create_platform(); + platforms[2] = platform_2 = _test_netns_create_platform(); - nmtstp_netns_select_random (platforms, G_N_ELEMENTS (platforms), &netns_pop); + nmtstp_netns_select_random(platforms, G_N_ELEMENTS(platforms), &netns_pop); #define LINK_MOVE_NAME "link-move" - g_assert (!nm_platform_link_get_by_ifname (platform_1, LINK_MOVE_NAME)); - g_assert (!nm_platform_link_get_by_ifname (platform_2, LINK_MOVE_NAME)); - _ADD_DUMMY (platform_1, LINK_MOVE_NAME); - g_assert ( nm_platform_link_get_by_ifname (platform_1, LINK_MOVE_NAME)); - g_assert (!nm_platform_link_get_by_ifname (platform_2, LINK_MOVE_NAME)); - g_assert (nm_platform_link_set_netns (platform_1, - nm_platform_link_get_by_ifname (platform_1, LINK_MOVE_NAME)->ifindex, - nmp_netns_get_fd_net (nm_platform_netns_get (platform_2)))); - g_assert (!nm_platform_link_get_by_ifname (platform_1, LINK_MOVE_NAME)); - g_assert (!nm_platform_link_get_by_ifname (platform_2, LINK_MOVE_NAME)); - nmtstp_assert_wait_for_link (platform_2, LINK_MOVE_NAME, NM_LINK_TYPE_DUMMY, 100); - g_assert (!nm_platform_link_get_by_ifname (platform_1, LINK_MOVE_NAME)); - g_assert ( nm_platform_link_get_by_ifname (platform_2, LINK_MOVE_NAME)); + g_assert(!nm_platform_link_get_by_ifname(platform_1, LINK_MOVE_NAME)); + g_assert(!nm_platform_link_get_by_ifname(platform_2, LINK_MOVE_NAME)); + _ADD_DUMMY(platform_1, LINK_MOVE_NAME); + g_assert(nm_platform_link_get_by_ifname(platform_1, LINK_MOVE_NAME)); + g_assert(!nm_platform_link_get_by_ifname(platform_2, LINK_MOVE_NAME)); + g_assert(nm_platform_link_set_netns( + platform_1, + nm_platform_link_get_by_ifname(platform_1, LINK_MOVE_NAME)->ifindex, + nmp_netns_get_fd_net(nm_platform_netns_get(platform_2)))); + g_assert(!nm_platform_link_get_by_ifname(platform_1, LINK_MOVE_NAME)); + g_assert(!nm_platform_link_get_by_ifname(platform_2, LINK_MOVE_NAME)); + nmtstp_assert_wait_for_link(platform_2, LINK_MOVE_NAME, NM_LINK_TYPE_DUMMY, 100); + g_assert(!nm_platform_link_get_by_ifname(platform_1, LINK_MOVE_NAME)); + g_assert(nm_platform_link_get_by_ifname(platform_2, LINK_MOVE_NAME)); } /*****************************************************************************/ static char * -_get_current_namespace_id (int ns_type) +_get_current_namespace_id(int ns_type) { - const char *p; - GError *error = NULL; - char *id; - - switch (ns_type) { - case CLONE_NEWNET: - p = "/proc/self/ns/net"; - break; - case CLONE_NEWNS: - p = "/proc/self/ns/mnt"; - break; - default: - g_assert_not_reached (); - } - - id = g_file_read_link (p, &error); - g_assert_no_error (error); - g_assert (id); - return id; + const char *p; + GError * error = NULL; + char * id; + + switch (ns_type) { + case CLONE_NEWNET: + p = "/proc/self/ns/net"; + break; + case CLONE_NEWNS: + p = "/proc/self/ns/mnt"; + break; + default: + g_assert_not_reached(); + } + + id = g_file_read_link(p, &error); + g_assert_no_error(error); + g_assert(id); + return id; } static char * -_get_sysctl_value (const char *path) +_get_sysctl_value(const char *path) { - char *data = NULL; - gs_free_error GError *error = NULL; - - if (!g_file_get_contents (path, &data, NULL, &error)) { - nmtst_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT, NULL); - g_assert (!data); - } else { - g_assert_no_error (error); - g_assert (data); - g_strstrip (data); - } - return data; + char * data = NULL; + gs_free_error GError *error = NULL; + + if (!g_file_get_contents(path, &data, NULL, &error)) { + nmtst_assert_error(error, G_FILE_ERROR, G_FILE_ERROR_NOENT, NULL); + g_assert(!data); + } else { + g_assert_no_error(error); + g_assert(data); + g_strstrip(data); + } + return data; } static void -test_netns_push (gpointer fixture, gconstpointer test_data) +test_netns_push(gpointer fixture, gconstpointer test_data) { - gs_unref_object NMPlatform *platform_0 = NULL; - gs_unref_object NMPlatform *platform_1 = NULL; - gs_unref_object NMPlatform *platform_2 = NULL; - nm_auto_pop_netns NMPNetns *netns_pop = NULL; - gs_unref_ptrarray GPtrArray *device_names = g_ptr_array_new_with_free_func (g_free); - int i, j; - const int ns_types_list[] = { CLONE_NEWNET, CLONE_NEWNS, CLONE_NEWNET | CLONE_NEWNS }; - const int ns_types_test[] = { CLONE_NEWNET, CLONE_NEWNS }; - typedef struct { - NMPlatform *platform; - const char *device_name; - const char *sysctl_path; - const char *sysctl_value; - const char *ns_net; - const char *ns_mnt; - } PlatformData; - PlatformData pl[3] = { }; - PlatformData *pl_base; - struct { - PlatformData *pl; - int ns_types; - } stack[6] = { }; - int nstack; - - if (_test_netns_check_skip ()) - return; - - if (_check_sysctl_skip ()) - return; - - pl[0].platform = platform_0 = nm_linux_platform_new (TRUE, TRUE); - pl[1].platform = platform_1 = _test_netns_create_platform (); - pl[2].platform = platform_2 = _test_netns_create_platform (); - - pl_base = &pl[0]; - i = nmtst_get_rand_uint32 () % (G_N_ELEMENTS (pl) + 1); - if (i < G_N_ELEMENTS (pl)) { - pl_base = &pl[i]; - g_assert (nm_platform_netns_push (pl[i].platform, &netns_pop)); - } - - for (i = 0; i < G_N_ELEMENTS (pl); i++) { - nm_auto_pop_netns NMPNetns *netns_free = NULL; - char *tmp; - - g_assert (nm_platform_netns_push (pl[i].platform, &netns_free)); - - tmp = g_strdup_printf ("nmtst-dev-%d", i); - g_ptr_array_add (device_names, tmp); - pl[i].device_name = tmp; - - tmp = g_strdup_printf ("/proc/sys/net/ipv6/conf/%s/disable_ipv6", pl[i].device_name); - g_ptr_array_add (device_names, tmp); - pl[i].sysctl_path = tmp; - - pl[i].sysctl_value = nmtst_get_rand_uint32 () % 2 ? "1" : "0"; - - _ADD_DUMMY (pl[i].platform, pl[i].device_name); - - g_assert (nm_platform_sysctl_set (pl[i].platform, NMP_SYSCTL_PATHID_ABSOLUTE (pl[i].sysctl_path), pl[i].sysctl_value)); - - tmp = _get_current_namespace_id (CLONE_NEWNET); - g_ptr_array_add (device_names, tmp); - pl[i].ns_net = tmp; - - tmp = _get_current_namespace_id (CLONE_NEWNS); - g_ptr_array_add (device_names, tmp); - pl[i].ns_mnt = tmp; - } - - nstack = nmtst_get_rand_uint32 () % (G_N_ELEMENTS (stack) + 1); - for (i = 0; i < nstack; i++) { - stack[i].pl = &pl[nmtst_get_rand_uint32 () % G_N_ELEMENTS (pl)]; - stack[i].ns_types = ns_types_list[nmtst_get_rand_uint32 () % G_N_ELEMENTS (ns_types_list)]; - - nmp_netns_push_type (nm_platform_netns_get (stack[i].pl->platform), stack[i].ns_types); - } - - /* pop some again. */ - for (i = nmtst_get_rand_uint32 () % (nstack + 1); i > 0; i--) { - g_assert (nstack > 0); - nstack--; - nmp_netns_pop (nm_platform_netns_get (stack[nstack].pl->platform)); - } - - for (i = 0; i < G_N_ELEMENTS (ns_types_test); i++) { - int ns_type = ns_types_test[i]; - PlatformData *p; - gs_free char *current_namespace_id = NULL; - - p = pl_base; - for (j = nstack; j >= 1; ) { - j--; - if (NM_FLAGS_ANY (stack[j].ns_types, ns_type)) { - p = stack[j].pl; - break; - } - } - - current_namespace_id = _get_current_namespace_id (ns_type); - - if (ns_type == CLONE_NEWNET) { - g_assert_cmpstr (current_namespace_id, ==, p->ns_net); - for (j = 0; j < G_N_ELEMENTS (pl); j++) { - gs_free char *data = NULL; - - if (p == &pl[j]) - g_assert_cmpint (nmtstp_run_command ("ip link show %s 1>/dev/null", pl[j].device_name), ==, 0); - else - g_assert_cmpint (nmtstp_run_command ("ip link show %s 2>/dev/null", pl[j].device_name), !=, 0); - - data = _get_sysctl_value (pl[j].sysctl_path); - if (p == &pl[j]) - g_assert_cmpstr (data, ==, pl[j].sysctl_value); - else - g_assert (!data); - } - } else if (ns_type == CLONE_NEWNS) { - g_assert_cmpstr (current_namespace_id, ==, p->ns_mnt); - for (j = 0; j < G_N_ELEMENTS (pl); j++) { - char path[600]; - gs_free char *data = NULL; - - nm_sprintf_buf (path, "/sys/devices/virtual/net/%s/ifindex", pl[j].device_name); - - data = _get_sysctl_value (path); - if (p == &pl[j]) - g_assert_cmpstr (data, ==, nm_sprintf_buf (path, "%d", nmtstp_link_get_typed (p->platform, 0, p->device_name, NM_LINK_TYPE_DUMMY)->ifindex)); - else - g_assert (!data); - } - } else - g_assert_not_reached (); - } - - for (i = nstack; i >= 1; ) { - i--; - nmp_netns_pop (nm_platform_netns_get (stack[i].pl->platform)); - } + gs_unref_object NMPlatform *platform_0 = NULL; + gs_unref_object NMPlatform *platform_1 = NULL; + gs_unref_object NMPlatform *platform_2 = NULL; + nm_auto_pop_netns NMPNetns *netns_pop = NULL; + gs_unref_ptrarray GPtrArray *device_names = g_ptr_array_new_with_free_func(g_free); + int i, j; + const int ns_types_list[] = {CLONE_NEWNET, CLONE_NEWNS, CLONE_NEWNET | CLONE_NEWNS}; + const int ns_types_test[] = {CLONE_NEWNET, CLONE_NEWNS}; + typedef struct { + NMPlatform *platform; + const char *device_name; + const char *sysctl_path; + const char *sysctl_value; + const char *ns_net; + const char *ns_mnt; + } PlatformData; + PlatformData pl[3] = {}; + PlatformData *pl_base; + struct { + PlatformData *pl; + int ns_types; + } stack[6] = {}; + int nstack; + + if (_test_netns_check_skip()) + return; + + if (_check_sysctl_skip()) + return; + + pl[0].platform = platform_0 = nm_linux_platform_new(TRUE, TRUE); + pl[1].platform = platform_1 = _test_netns_create_platform(); + pl[2].platform = platform_2 = _test_netns_create_platform(); + + pl_base = &pl[0]; + i = nmtst_get_rand_uint32() % (G_N_ELEMENTS(pl) + 1); + if (i < G_N_ELEMENTS(pl)) { + pl_base = &pl[i]; + g_assert(nm_platform_netns_push(pl[i].platform, &netns_pop)); + } + + for (i = 0; i < G_N_ELEMENTS(pl); i++) { + nm_auto_pop_netns NMPNetns *netns_free = NULL; + char * tmp; + + g_assert(nm_platform_netns_push(pl[i].platform, &netns_free)); + + tmp = g_strdup_printf("nmtst-dev-%d", i); + g_ptr_array_add(device_names, tmp); + pl[i].device_name = tmp; + + tmp = g_strdup_printf("/proc/sys/net/ipv6/conf/%s/disable_ipv6", pl[i].device_name); + g_ptr_array_add(device_names, tmp); + pl[i].sysctl_path = tmp; + + pl[i].sysctl_value = nmtst_get_rand_uint32() % 2 ? "1" : "0"; + + _ADD_DUMMY(pl[i].platform, pl[i].device_name); + + g_assert(nm_platform_sysctl_set(pl[i].platform, + NMP_SYSCTL_PATHID_ABSOLUTE(pl[i].sysctl_path), + pl[i].sysctl_value)); + + tmp = _get_current_namespace_id(CLONE_NEWNET); + g_ptr_array_add(device_names, tmp); + pl[i].ns_net = tmp; + + tmp = _get_current_namespace_id(CLONE_NEWNS); + g_ptr_array_add(device_names, tmp); + pl[i].ns_mnt = tmp; + } + + nstack = nmtst_get_rand_uint32() % (G_N_ELEMENTS(stack) + 1); + for (i = 0; i < nstack; i++) { + stack[i].pl = &pl[nmtst_get_rand_uint32() % G_N_ELEMENTS(pl)]; + stack[i].ns_types = ns_types_list[nmtst_get_rand_uint32() % G_N_ELEMENTS(ns_types_list)]; + + nmp_netns_push_type(nm_platform_netns_get(stack[i].pl->platform), stack[i].ns_types); + } + + /* pop some again. */ + for (i = nmtst_get_rand_uint32() % (nstack + 1); i > 0; i--) { + g_assert(nstack > 0); + nstack--; + nmp_netns_pop(nm_platform_netns_get(stack[nstack].pl->platform)); + } + + for (i = 0; i < G_N_ELEMENTS(ns_types_test); i++) { + int ns_type = ns_types_test[i]; + PlatformData *p; + gs_free char *current_namespace_id = NULL; + + p = pl_base; + for (j = nstack; j >= 1;) { + j--; + if (NM_FLAGS_ANY(stack[j].ns_types, ns_type)) { + p = stack[j].pl; + break; + } + } + + current_namespace_id = _get_current_namespace_id(ns_type); + + if (ns_type == CLONE_NEWNET) { + g_assert_cmpstr(current_namespace_id, ==, p->ns_net); + for (j = 0; j < G_N_ELEMENTS(pl); j++) { + gs_free char *data = NULL; + + if (p == &pl[j]) + g_assert_cmpint( + nmtstp_run_command("ip link show %s 1>/dev/null", pl[j].device_name), + ==, + 0); + else + g_assert_cmpint( + nmtstp_run_command("ip link show %s 2>/dev/null", pl[j].device_name), + !=, + 0); + + data = _get_sysctl_value(pl[j].sysctl_path); + if (p == &pl[j]) + g_assert_cmpstr(data, ==, pl[j].sysctl_value); + else + g_assert(!data); + } + } else if (ns_type == CLONE_NEWNS) { + g_assert_cmpstr(current_namespace_id, ==, p->ns_mnt); + for (j = 0; j < G_N_ELEMENTS(pl); j++) { + char path[600]; + gs_free char *data = NULL; + + nm_sprintf_buf(path, "/sys/devices/virtual/net/%s/ifindex", pl[j].device_name); + + data = _get_sysctl_value(path); + if (p == &pl[j]) + g_assert_cmpstr(data, + ==, + nm_sprintf_buf(path, + "%d", + nmtstp_link_get_typed(p->platform, + 0, + p->device_name, + NM_LINK_TYPE_DUMMY) + ->ifindex)); + else + g_assert(!data); + } + } else + g_assert_not_reached(); + } + + for (i = nstack; i >= 1;) { + i--; + nmp_netns_pop(nm_platform_netns_get(stack[i].pl->platform)); + } } /*****************************************************************************/ static void -test_netns_bind_to_path (gpointer fixture, gconstpointer test_data) +test_netns_bind_to_path(gpointer fixture, gconstpointer test_data) { #define P_VAR_RUN "/run" #define P_VAR_RUN_NETNS "/run/netns" -#define P_VAR_RUN_NETNS_BINDNAME "/run/netns/"P_NETNS_BINDNAME +#define P_VAR_RUN_NETNS_BINDNAME "/run/netns/" P_NETNS_BINDNAME #define P_NETNS_BINDNAME "nmtst-iproute2-netns" - gs_unref_object NMPlatform *platform_0 = NULL; - gs_unref_object NMPlatform *platform_1 = NULL; - gs_unref_object NMPlatform *platform_2 = NULL; - nm_auto_pop_netns NMPNetns *netns_pop = NULL; - NMPlatform *platforms[3]; - NMPNetns *netns; - int i; + gs_unref_object NMPlatform *platform_0 = NULL; + gs_unref_object NMPlatform *platform_1 = NULL; + gs_unref_object NMPlatform *platform_2 = NULL; + nm_auto_pop_netns NMPNetns *netns_pop = NULL; + NMPlatform * platforms[3]; + NMPNetns * netns; + int i; - if (_test_netns_check_skip ()) - return; + if (_test_netns_check_skip()) + return; - platforms[0] = platform_0 = nm_linux_platform_new (TRUE, TRUE); - platforms[1] = platform_1 = _test_netns_create_platform (); - platforms[2] = platform_2 = _test_netns_create_platform (); + platforms[0] = platform_0 = nm_linux_platform_new(TRUE, TRUE); + platforms[1] = platform_1 = _test_netns_create_platform(); + platforms[2] = platform_2 = _test_netns_create_platform(); - nmtstp_netns_select_random (platforms, G_N_ELEMENTS (platforms), &netns_pop); + nmtstp_netns_select_random(platforms, G_N_ELEMENTS(platforms), &netns_pop); - g_assert_cmpint (mount ("tmpfs", P_VAR_RUN, "tmpfs", MS_NOATIME | MS_NODEV | MS_NOSUID, "mode=0755,size=32K"), ==, 0); - g_assert_cmpint (mkdir (P_VAR_RUN_NETNS, 755), ==, 0); + g_assert_cmpint( + mount("tmpfs", P_VAR_RUN, "tmpfs", MS_NOATIME | MS_NODEV | MS_NOSUID, "mode=0755,size=32K"), + ==, + 0); + g_assert_cmpint(mkdir(P_VAR_RUN_NETNS, 755), ==, 0); - i = (nmtst_get_rand_uint32 () % 2) + 1; - netns = nm_platform_netns_get (platforms[i]); + i = (nmtst_get_rand_uint32() % 2) + 1; + netns = nm_platform_netns_get(platforms[i]); - _ADD_DUMMY (platforms[i], "dummy2b"); + _ADD_DUMMY(platforms[i], "dummy2b"); - g_assert (!g_file_test (P_VAR_RUN_NETNS_BINDNAME, G_FILE_TEST_EXISTS)); - g_assert_cmpint (nmtstp_run_command ("ip netns exec "P_NETNS_BINDNAME" true 2>/dev/null"), !=, 0); + g_assert(!g_file_test(P_VAR_RUN_NETNS_BINDNAME, G_FILE_TEST_EXISTS)); + g_assert_cmpint(nmtstp_run_command("ip netns exec " P_NETNS_BINDNAME " true 2>/dev/null"), + !=, + 0); - g_assert (nmp_netns_bind_to_path (netns, P_VAR_RUN_NETNS_BINDNAME, NULL)); + g_assert(nmp_netns_bind_to_path(netns, P_VAR_RUN_NETNS_BINDNAME, NULL)); - g_assert (g_file_test (P_VAR_RUN_NETNS_BINDNAME, G_FILE_TEST_EXISTS)); - g_assert_cmpint (nmtstp_run_command ("ip netns exec "P_NETNS_BINDNAME" true"), ==, 0); - g_assert_cmpint (nmtstp_run_command ("ip netns exec "P_NETNS_BINDNAME" ip link show dummy2b 1>/dev/null"), ==, 0); + g_assert(g_file_test(P_VAR_RUN_NETNS_BINDNAME, G_FILE_TEST_EXISTS)); + g_assert_cmpint(nmtstp_run_command("ip netns exec " P_NETNS_BINDNAME " true"), ==, 0); + g_assert_cmpint( + nmtstp_run_command("ip netns exec " P_NETNS_BINDNAME " ip link show dummy2b 1>/dev/null"), + ==, + 0); - g_assert (nmp_netns_bind_to_path_destroy (netns, P_VAR_RUN_NETNS_BINDNAME)); + g_assert(nmp_netns_bind_to_path_destroy(netns, P_VAR_RUN_NETNS_BINDNAME)); - g_assert (!g_file_test (P_VAR_RUN_NETNS_BINDNAME, G_FILE_TEST_EXISTS)); - g_assert_cmpint (nmtstp_run_command ("ip netns exec "P_NETNS_BINDNAME" true 2>/dev/null"), !=, 0); + g_assert(!g_file_test(P_VAR_RUN_NETNS_BINDNAME, G_FILE_TEST_EXISTS)); + g_assert_cmpint(nmtstp_run_command("ip netns exec " P_NETNS_BINDNAME " true 2>/dev/null"), + !=, + 0); - g_assert_cmpint (umount (P_VAR_RUN), ==, 0); + g_assert_cmpint(umount(P_VAR_RUN), ==, 0); } /*****************************************************************************/ static void -test_sysctl_rename (void) +test_sysctl_rename(void) { - NMPlatform *const PL = NM_PLATFORM_GET; - const char *const IFNAME[3] = { - "nm-dummy-0", - "nm-dummy-1", - "nm-dummy-2", - }; - int ifindex[G_N_ELEMENTS (IFNAME)] = { 0 }; - nm_auto_close int dirfd = -1; - int i; - char ifname_buf[IFNAMSIZ]; - char *s; - const NMPlatformLink *pllink; - - ifindex[0] = nmtstp_link_dummy_add (PL, -1, IFNAME[0])->ifindex; - ifindex[1] = nmtstp_link_dummy_add (PL, -1, IFNAME[1])->ifindex; - - s = (nmtst_get_rand_uint32 () % 2) ? NULL : ifname_buf; - - if (nmtst_get_rand_uint32 () % 2) { - /* bring the platform cache out of sync */ - nmtstp_run_command_check ("ip link set %s name %s", IFNAME[0], IFNAME[2]); - nm_platform_process_events (PL); - nmtstp_run_command_check ("ip link set %s name %s", IFNAME[2], IFNAME[0]); - - pllink = nm_platform_link_get_by_ifname (PL, IFNAME[2]); - g_assert (pllink && pllink->ifindex == ifindex[0]); - pllink = nm_platform_link_get_by_ifname (PL, IFNAME[0]); - g_assert (!pllink); - } - - /* open dirfd for IFNAME[0] */ - i = nmtst_get_rand_uint32 () % (2 + G_N_ELEMENTS (IFNAME)); - if (i == 0) { - dirfd = nm_platform_sysctl_open_netdir (PL, - ifindex[0], - s); - } else { - const char *ifname_guess; - - /* provide a wrong or no guess. */ - ifname_guess = i == 1 ? NULL : IFNAME[i - 2]; - dirfd = nmp_utils_sysctl_open_netdir (ifindex[0], - ifname_guess, - s); - } - g_assert (dirfd >= 0); - if (s) - g_assert_cmpstr (s, ==, IFNAME[0]); - - /* possibly rename the interfaces. */ - switch (nmtst_get_rand_uint32 () % 4) { - case 0: - break; - case 1: - nmtstp_run_command_check ("ip link set %s name %s", IFNAME[0], IFNAME[2]); - break; - case 2: - nmtstp_run_command_check ("ip link set %s name %s", IFNAME[0], IFNAME[2]); - nmtstp_run_command_check ("ip link set %s name %s", IFNAME[1], IFNAME[0]); - break; - } - - /* possibly, resync platform cache (should make no difference). */ - if (nmtst_get_rand_uint32 () % 2) - nm_platform_process_events (PL); - - /* check that we still read the same file. */ - switch (nmtst_get_rand_uint32 () % 2) { - case 0: { - gs_free char *c = NULL; - - if (!nm_utils_file_get_contents (dirfd, - "ifindex", - 1*1024*1024, - NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, - &c, - NULL, - NULL, - NULL)) - g_assert_not_reached(); - g_assert_cmpint (ifindex[0], ==, (int) _nm_utils_ascii_str_to_int64 (c, 10, 0, G_MAXINT, -1)); - break; - } - case 1: { - g_assert_cmpint (ifindex[0], ==, (gint32) nm_platform_sysctl_get_int32 (PL, NMP_SYSCTL_PATHID_NETDIR (dirfd, s ?: "<unknown>", "ifindex"), -1)); - break; - } - } - - nm_platform_process_events (PL); - nmtstp_link_delete (PL, -1, ifindex[0], NULL, TRUE); - nmtstp_link_delete (PL, -1, ifindex[1], NULL, TRUE); + NMPlatform *const PL = NM_PLATFORM_GET; + const char *const IFNAME[3] = { + "nm-dummy-0", + "nm-dummy-1", + "nm-dummy-2", + }; + int ifindex[G_N_ELEMENTS(IFNAME)] = {0}; + nm_auto_close int dirfd = -1; + int i; + char ifname_buf[IFNAMSIZ]; + char * s; + const NMPlatformLink *pllink; + + ifindex[0] = nmtstp_link_dummy_add(PL, -1, IFNAME[0])->ifindex; + ifindex[1] = nmtstp_link_dummy_add(PL, -1, IFNAME[1])->ifindex; + + s = (nmtst_get_rand_uint32() % 2) ? NULL : ifname_buf; + + if (nmtst_get_rand_uint32() % 2) { + /* bring the platform cache out of sync */ + nmtstp_run_command_check("ip link set %s name %s", IFNAME[0], IFNAME[2]); + nm_platform_process_events(PL); + nmtstp_run_command_check("ip link set %s name %s", IFNAME[2], IFNAME[0]); + + pllink = nm_platform_link_get_by_ifname(PL, IFNAME[2]); + g_assert(pllink && pllink->ifindex == ifindex[0]); + pllink = nm_platform_link_get_by_ifname(PL, IFNAME[0]); + g_assert(!pllink); + } + + /* open dirfd for IFNAME[0] */ + i = nmtst_get_rand_uint32() % (2 + G_N_ELEMENTS(IFNAME)); + if (i == 0) { + dirfd = nm_platform_sysctl_open_netdir(PL, ifindex[0], s); + } else { + const char *ifname_guess; + + /* provide a wrong or no guess. */ + ifname_guess = i == 1 ? NULL : IFNAME[i - 2]; + dirfd = nmp_utils_sysctl_open_netdir(ifindex[0], ifname_guess, s); + } + g_assert(dirfd >= 0); + if (s) + g_assert_cmpstr(s, ==, IFNAME[0]); + + /* possibly rename the interfaces. */ + switch (nmtst_get_rand_uint32() % 4) { + case 0: + break; + case 1: + nmtstp_run_command_check("ip link set %s name %s", IFNAME[0], IFNAME[2]); + break; + case 2: + nmtstp_run_command_check("ip link set %s name %s", IFNAME[0], IFNAME[2]); + nmtstp_run_command_check("ip link set %s name %s", IFNAME[1], IFNAME[0]); + break; + } + + /* possibly, resync platform cache (should make no difference). */ + if (nmtst_get_rand_uint32() % 2) + nm_platform_process_events(PL); + + /* check that we still read the same file. */ + switch (nmtst_get_rand_uint32() % 2) { + case 0: + { + gs_free char *c = NULL; + + if (!nm_utils_file_get_contents(dirfd, + "ifindex", + 1 * 1024 * 1024, + NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, + &c, + NULL, + NULL, + NULL)) + g_assert_not_reached(); + g_assert_cmpint(ifindex[0], ==, (int) _nm_utils_ascii_str_to_int64(c, 10, 0, G_MAXINT, -1)); + break; + } + case 1: + { + g_assert_cmpint(ifindex[0], + ==, + (gint32) nm_platform_sysctl_get_int32( + PL, + NMP_SYSCTL_PATHID_NETDIR(dirfd, s ?: "<unknown>", "ifindex"), + -1)); + break; + } + } + + nm_platform_process_events(PL); + nmtstp_link_delete(PL, -1, ifindex[0], NULL, TRUE); + nmtstp_link_delete(PL, -1, ifindex[1], NULL, TRUE); } /*****************************************************************************/ static void -test_sysctl_netns_switch (void) +test_sysctl_netns_switch(void) { - const char *const IFNAME = "nm-dummy-0"; - int ifindex, ifindex_tmp; - nm_auto_close int dirfd = -1; - char ifname_buf[IFNAMSIZ]; - char *s; - gs_unref_object NMPlatform *platform_0 = NULL; - gs_unref_object NMPlatform *platform_1 = NULL; - gs_unref_object NMPlatform *platform_2 = NULL; - nm_auto_pop_netns NMPNetns *netns_pop_1 = NULL; - nm_auto_pop_netns NMPNetns *netns_pop_2 = NULL; - nm_auto_pop_netns NMPNetns *netns_pop_3 = NULL; - NMPlatform *PL; - NMPlatform *platforms[3]; - - if (_test_netns_check_skip ()) - return; - - platforms[0] = platform_0 = nm_linux_platform_new (TRUE, TRUE); - platforms[1] = platform_1 = _test_netns_create_platform (); - platforms[2] = platform_2 = _test_netns_create_platform (); - PL = platforms[nmtst_get_rand_uint32 () % 3]; - - nmtstp_netns_select_random (platforms, G_N_ELEMENTS (platforms), &netns_pop_1); - - ifindex = nmtstp_link_dummy_add (PL, FALSE, IFNAME)->ifindex; - - nmtstp_netns_select_random (platforms, G_N_ELEMENTS (platforms), &netns_pop_2); - - s = (nmtst_get_rand_uint32 () % 2) ? NULL : ifname_buf; - dirfd = nm_platform_sysctl_open_netdir (PL, - ifindex, - s); - g_assert (dirfd >= 0); - if (s) - g_assert_cmpstr (s, ==, IFNAME); - - nmtstp_netns_select_random (platforms, G_N_ELEMENTS (platforms), &netns_pop_3); - - /* even if we switch to other namespaces, we can still lookup the path correctly, - * either using dirfd or via the platform instance (which switches namespace as needed). */ - { - gs_free char *c = NULL; - - if (!nm_utils_file_get_contents (dirfd, - "ifindex", - 0, - NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, - &c, - NULL, - NULL, - NULL)) - g_assert_not_reached(); - g_assert_cmpint (ifindex, ==, (int) _nm_utils_ascii_str_to_int64 (c, 10, 0, G_MAXINT, -1)); - } - g_assert_cmpint (ifindex, ==, (gint32) nm_platform_sysctl_get_int32 (PL, NMP_SYSCTL_PATHID_NETDIR (dirfd, s ?: "<unknown>", "ifindex"), -1)); - g_assert_cmpint (ifindex, ==, (gint32) nm_platform_sysctl_get_int32 (PL, NMP_SYSCTL_PATHID_ABSOLUTE (nm_sprintf_bufa (100, "/sys/class/net/%s/ifindex", IFNAME)), -1)); - - /* also test that nm_platform_sysctl_get() sets errno to ENOENT for non-existing paths. */ - { - gint64 i64; - int errsv; - char *v; - - errno = ESRCH; - v = nm_platform_sysctl_get (PL, NMP_SYSCTL_PATHID_ABSOLUTE ("/sys/devices/virtual/net/not-existing/ifindex")); - errsv = errno; - g_assert (!v); - g_assert_cmpint (errsv, ==, ENOENT); - - errno = ESRCH; - i64 = nm_platform_sysctl_get_int_checked (PL, NMP_SYSCTL_PATHID_ABSOLUTE ("/sys/devices/virtual/net/not-existing/ifindex"), 10, 1, G_MAXINT, -1); - errsv = errno; - g_assert_cmpint (i64, ==, -1); - g_assert_cmpint (errsv, ==, ENOENT); - - errno = ESRCH; - v = nm_platform_sysctl_get (PL, NMP_SYSCTL_PATHID_ABSOLUTE ("/sys/devices/virtual/net/lo/not-existing")); - errsv = errno; - g_assert (!v); - g_assert_cmpint (errsv, ==, ENOENT); - - errno = ESRCH; - i64 = nm_platform_sysctl_get_int_checked (PL, NMP_SYSCTL_PATHID_ABSOLUTE ("/sys/devices/virtual/net/lo/not-existing"), 10, 1, G_MAXINT, -1); - errsv = errno; - g_assert_cmpint (i64, ==, -1); - g_assert_cmpint (errsv, ==, ENOENT); - } - - /* accessing the path directly, only succeeds iff the current namespace happens to be the namespace - * in which we created the link. */ - { - gs_free char *c = NULL; - - if (!nm_utils_file_get_contents (-1, - nm_sprintf_bufa (100, "/sys/class/net/%s/ifindex", IFNAME), - 0, - NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, - &c, - NULL, - NULL, - NULL)) - ifindex_tmp = -1; - else - ifindex_tmp = _nm_utils_ascii_str_to_int64 (c, 10, 0, G_MAXINT, -2); - } - if (nmp_netns_get_current () == nm_platform_netns_get (PL)) - g_assert_cmpint (ifindex_tmp, ==, ifindex); - else - g_assert_cmpint (ifindex_tmp, ==, -1); - - nmtstp_link_delete (PL, FALSE, ifindex, NULL, TRUE); + const char *const IFNAME = "nm-dummy-0"; + int ifindex, ifindex_tmp; + nm_auto_close int dirfd = -1; + char ifname_buf[IFNAMSIZ]; + char * s; + gs_unref_object NMPlatform *platform_0 = NULL; + gs_unref_object NMPlatform *platform_1 = NULL; + gs_unref_object NMPlatform *platform_2 = NULL; + nm_auto_pop_netns NMPNetns *netns_pop_1 = NULL; + nm_auto_pop_netns NMPNetns *netns_pop_2 = NULL; + nm_auto_pop_netns NMPNetns *netns_pop_3 = NULL; + NMPlatform * PL; + NMPlatform * platforms[3]; + + if (_test_netns_check_skip()) + return; + + platforms[0] = platform_0 = nm_linux_platform_new(TRUE, TRUE); + platforms[1] = platform_1 = _test_netns_create_platform(); + platforms[2] = platform_2 = _test_netns_create_platform(); + PL = platforms[nmtst_get_rand_uint32() % 3]; + + nmtstp_netns_select_random(platforms, G_N_ELEMENTS(platforms), &netns_pop_1); + + ifindex = nmtstp_link_dummy_add(PL, FALSE, IFNAME)->ifindex; + + nmtstp_netns_select_random(platforms, G_N_ELEMENTS(platforms), &netns_pop_2); + + s = (nmtst_get_rand_uint32() % 2) ? NULL : ifname_buf; + dirfd = nm_platform_sysctl_open_netdir(PL, ifindex, s); + g_assert(dirfd >= 0); + if (s) + g_assert_cmpstr(s, ==, IFNAME); + + nmtstp_netns_select_random(platforms, G_N_ELEMENTS(platforms), &netns_pop_3); + + /* even if we switch to other namespaces, we can still lookup the path correctly, + * either using dirfd or via the platform instance (which switches namespace as needed). */ + { + gs_free char *c = NULL; + + if (!nm_utils_file_get_contents(dirfd, + "ifindex", + 0, + NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, + &c, + NULL, + NULL, + NULL)) + g_assert_not_reached(); + g_assert_cmpint(ifindex, ==, (int) _nm_utils_ascii_str_to_int64(c, 10, 0, G_MAXINT, -1)); + } + g_assert_cmpint(ifindex, + ==, + (gint32) nm_platform_sysctl_get_int32( + PL, + NMP_SYSCTL_PATHID_NETDIR(dirfd, s ?: "<unknown>", "ifindex"), + -1)); + g_assert_cmpint( + ifindex, + ==, + (gint32) nm_platform_sysctl_get_int32( + PL, + NMP_SYSCTL_PATHID_ABSOLUTE(nm_sprintf_bufa(100, "/sys/class/net/%s/ifindex", IFNAME)), + -1)); + + /* also test that nm_platform_sysctl_get() sets errno to ENOENT for non-existing paths. */ + { + gint64 i64; + int errsv; + char * v; + + errno = ESRCH; + v = nm_platform_sysctl_get( + PL, + NMP_SYSCTL_PATHID_ABSOLUTE("/sys/devices/virtual/net/not-existing/ifindex")); + errsv = errno; + g_assert(!v); + g_assert_cmpint(errsv, ==, ENOENT); + + errno = ESRCH; + i64 = nm_platform_sysctl_get_int_checked( + PL, + NMP_SYSCTL_PATHID_ABSOLUTE("/sys/devices/virtual/net/not-existing/ifindex"), + 10, + 1, + G_MAXINT, + -1); + errsv = errno; + g_assert_cmpint(i64, ==, -1); + g_assert_cmpint(errsv, ==, ENOENT); + + errno = ESRCH; + v = nm_platform_sysctl_get( + PL, + NMP_SYSCTL_PATHID_ABSOLUTE("/sys/devices/virtual/net/lo/not-existing")); + errsv = errno; + g_assert(!v); + g_assert_cmpint(errsv, ==, ENOENT); + + errno = ESRCH; + i64 = nm_platform_sysctl_get_int_checked( + PL, + NMP_SYSCTL_PATHID_ABSOLUTE("/sys/devices/virtual/net/lo/not-existing"), + 10, + 1, + G_MAXINT, + -1); + errsv = errno; + g_assert_cmpint(i64, ==, -1); + g_assert_cmpint(errsv, ==, ENOENT); + } + + /* accessing the path directly, only succeeds iff the current namespace happens to be the namespace + * in which we created the link. */ + { + gs_free char *c = NULL; + + if (!nm_utils_file_get_contents(-1, + nm_sprintf_bufa(100, "/sys/class/net/%s/ifindex", IFNAME), + 0, + NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, + &c, + NULL, + NULL, + NULL)) + ifindex_tmp = -1; + else + ifindex_tmp = _nm_utils_ascii_str_to_int64(c, 10, 0, G_MAXINT, -2); + } + if (nmp_netns_get_current() == nm_platform_netns_get(PL)) + g_assert_cmpint(ifindex_tmp, ==, ifindex); + else + g_assert_cmpint(ifindex_tmp, ==, -1); + + nmtstp_link_delete(PL, FALSE, ifindex, NULL, TRUE); } typedef struct { - GMainLoop *loop; - const char *path; - gboolean expected_success; - gint32 expected_value; + GMainLoop * loop; + const char *path; + gboolean expected_success; + gint32 expected_value; } SetAsyncData; static void -sysctl_set_async_cb (GError *error, gpointer user_data) +sysctl_set_async_cb(GError *error, gpointer user_data) { - SetAsyncData *data = user_data; - - if (data->expected_success) { - g_assert_no_error (error); - g_assert_cmpint (nm_platform_sysctl_get_int32 (NM_PLATFORM_GET, - NMP_SYSCTL_PATHID_ABSOLUTE (data->path), - -1), - ==, - data->expected_value); - } else - g_assert (error); - - g_main_loop_quit (data->loop); + SetAsyncData *data = user_data; + + if (data->expected_success) { + g_assert_no_error(error); + g_assert_cmpint(nm_platform_sysctl_get_int32(NM_PLATFORM_GET, + NMP_SYSCTL_PATHID_ABSOLUTE(data->path), + -1), + ==, + data->expected_value); + } else + g_assert(error); + + g_main_loop_quit(data->loop); } static void -test_sysctl_set_async (void) +test_sysctl_set_async(void) { - NMPlatform *const PL = NM_PLATFORM_GET; - const char *const IFNAME = "nm-dummy-0"; - const char *const PATH = "/proc/sys/net/ipv4/conf/nm-dummy-0/rp_filter"; - GMainLoop *loop; - gs_unref_object GCancellable *cancellable = NULL; - gboolean proc_writable; - SetAsyncData data; - int ifindex; - - ifindex = nmtstp_link_dummy_add (PL, -1, IFNAME)->ifindex; - loop = g_main_loop_new (NULL, FALSE); - cancellable = g_cancellable_new (); - proc_writable = access (PATH, W_OK) == 0; - - data = (SetAsyncData) { - .loop = loop, - .path = PATH, - .expected_success = proc_writable, - .expected_value = 2, - }; - - nm_platform_sysctl_set_async (PL, - NMP_SYSCTL_PATHID_ABSOLUTE (PATH), - (const char *[]) { "2", NULL}, - sysctl_set_async_cb, - &data, - cancellable); - - if (!nmtst_main_loop_run (loop, 1000)) - g_assert_not_reached (); - - data = (SetAsyncData) { - .loop = loop, - .path = PATH, - .expected_success = proc_writable, - .expected_value = 1, - }; - - nm_platform_sysctl_set_async (PL, - NMP_SYSCTL_PATHID_ABSOLUTE (PATH), - (const char *[]) { "2", "0", "1", "0", "1", NULL}, - sysctl_set_async_cb, - &data, - cancellable); - - if (!nmtst_main_loop_run (loop, 2000)) - g_assert_not_reached (); - - nmtstp_link_delete (NULL, -1, ifindex, IFNAME, TRUE); - g_main_loop_unref (loop); + NMPlatform *const PL = NM_PLATFORM_GET; + const char *const IFNAME = "nm-dummy-0"; + const char *const PATH = "/proc/sys/net/ipv4/conf/nm-dummy-0/rp_filter"; + GMainLoop * loop; + gs_unref_object GCancellable *cancellable = NULL; + gboolean proc_writable; + SetAsyncData data; + int ifindex; + + ifindex = nmtstp_link_dummy_add(PL, -1, IFNAME)->ifindex; + loop = g_main_loop_new(NULL, FALSE); + cancellable = g_cancellable_new(); + proc_writable = access(PATH, W_OK) == 0; + + data = (SetAsyncData){ + .loop = loop, + .path = PATH, + .expected_success = proc_writable, + .expected_value = 2, + }; + + nm_platform_sysctl_set_async(PL, + NMP_SYSCTL_PATHID_ABSOLUTE(PATH), + (const char *[]){"2", NULL}, + sysctl_set_async_cb, + &data, + cancellable); + + if (!nmtst_main_loop_run(loop, 1000)) + g_assert_not_reached(); + + data = (SetAsyncData){ + .loop = loop, + .path = PATH, + .expected_success = proc_writable, + .expected_value = 1, + }; + + nm_platform_sysctl_set_async(PL, + NMP_SYSCTL_PATHID_ABSOLUTE(PATH), + (const char *[]){"2", "0", "1", "0", "1", NULL}, + sysctl_set_async_cb, + &data, + cancellable); + + if (!nmtst_main_loop_run(loop, 2000)) + g_assert_not_reached(); + + nmtstp_link_delete(NULL, -1, ifindex, IFNAME, TRUE); + g_main_loop_unref(loop); } static void -test_sysctl_set_async_fail (void) +test_sysctl_set_async_fail(void) { - NMPlatform *const PL = NM_PLATFORM_GET; - const char *const IFNAME = "nm-dummy-0"; - const char *const PATH = "/proc/sys/net/ipv4/conf/nm-dummy-0/does-not-exist"; - GMainLoop *loop; - gs_unref_object GCancellable *cancellable = NULL; - SetAsyncData data; - int ifindex; - - ifindex = nmtstp_link_dummy_add (PL, -1, IFNAME)->ifindex; - loop = g_main_loop_new (NULL, FALSE); - cancellable = g_cancellable_new (); - - data = (SetAsyncData) { - .loop = loop, - .path = PATH, - .expected_success = FALSE, - }; - - nm_platform_sysctl_set_async (PL, - NMP_SYSCTL_PATHID_ABSOLUTE (PATH), - (const char *[]) { "2", NULL}, - sysctl_set_async_cb, - &data, - cancellable); - - if (!nmtst_main_loop_run (loop, 1000)) - g_assert_not_reached (); - - nmtstp_link_delete (NULL, -1, ifindex, IFNAME, TRUE); - g_main_loop_unref (loop); + NMPlatform *const PL = NM_PLATFORM_GET; + const char *const IFNAME = "nm-dummy-0"; + const char *const PATH = "/proc/sys/net/ipv4/conf/nm-dummy-0/does-not-exist"; + GMainLoop * loop; + gs_unref_object GCancellable *cancellable = NULL; + SetAsyncData data; + int ifindex; + + ifindex = nmtstp_link_dummy_add(PL, -1, IFNAME)->ifindex; + loop = g_main_loop_new(NULL, FALSE); + cancellable = g_cancellable_new(); + + data = (SetAsyncData){ + .loop = loop, + .path = PATH, + .expected_success = FALSE, + }; + + nm_platform_sysctl_set_async(PL, + NMP_SYSCTL_PATHID_ABSOLUTE(PATH), + (const char *[]){"2", NULL}, + sysctl_set_async_cb, + &data, + cancellable); + + if (!nmtst_main_loop_run(loop, 1000)) + g_assert_not_reached(); + + nmtstp_link_delete(NULL, -1, ifindex, IFNAME, TRUE); + g_main_loop_unref(loop); } /*****************************************************************************/ static gpointer -_test_netns_mt_thread (gpointer data) +_test_netns_mt_thread(gpointer data) { - NMPNetns *netns1 = data; - gs_unref_object NMPNetns *netns2 = NULL; - NMPNetns *netns_bottom; - NMPNetns *initial; - - netns_bottom = nmp_netns_get_initial (); - g_assert (netns_bottom); - - /* I don't know why, but we need to create a new netns here at least once. - * Otherwise, setns(, CLONE_NEWNS) below fails with EINVAL (???). - * - * Something is not right here, but what? */ - netns2 = nmp_netns_new (); - nmp_netns_pop (netns2); - g_clear_object (&netns2); - - nmp_netns_push (netns1); - nmp_netns_push_type (netns_bottom, CLONE_NEWNET); - nmp_netns_push_type (netns_bottom, CLONE_NEWNS); - nmp_netns_push_type (netns1, CLONE_NEWNS); - nmp_netns_pop (netns1); - nmp_netns_pop (netns_bottom); - nmp_netns_pop (netns_bottom); - nmp_netns_pop (netns1); - - initial = nmp_netns_get_initial (); - g_assert (NMP_IS_NETNS (initial)); - return g_object_ref (initial); + NMPNetns * netns1 = data; + gs_unref_object NMPNetns *netns2 = NULL; + NMPNetns * netns_bottom; + NMPNetns * initial; + + netns_bottom = nmp_netns_get_initial(); + g_assert(netns_bottom); + + /* I don't know why, but we need to create a new netns here at least once. + * Otherwise, setns(, CLONE_NEWNS) below fails with EINVAL (???). + * + * Something is not right here, but what? */ + netns2 = nmp_netns_new(); + nmp_netns_pop(netns2); + g_clear_object(&netns2); + + nmp_netns_push(netns1); + nmp_netns_push_type(netns_bottom, CLONE_NEWNET); + nmp_netns_push_type(netns_bottom, CLONE_NEWNS); + nmp_netns_push_type(netns1, CLONE_NEWNS); + nmp_netns_pop(netns1); + nmp_netns_pop(netns_bottom); + nmp_netns_pop(netns_bottom); + nmp_netns_pop(netns1); + + initial = nmp_netns_get_initial(); + g_assert(NMP_IS_NETNS(initial)); + return g_object_ref(initial); } static void -test_netns_mt (void) +test_netns_mt(void) { - gs_unref_object NMPNetns *netns1 = NULL; - NMPNetns *initial_from_other_thread; - GThread *th; - - if (_test_netns_check_skip ()) - return; - - netns1 = nmp_netns_new (); - g_assert (NMP_NETNS (netns1)); - nmp_netns_pop (netns1); - - th = g_thread_new ("nm-test-netns-mt", _test_netns_mt_thread, netns1); - initial_from_other_thread = g_thread_join (th); - g_assert (NMP_IS_NETNS (initial_from_other_thread)); - - if (nmtst_get_rand_bool ()) { - nmp_netns_push (initial_from_other_thread); - nmp_netns_pop (initial_from_other_thread); - } - - g_object_add_weak_pointer (G_OBJECT (initial_from_other_thread), (gpointer *) &initial_from_other_thread); - g_object_unref (initial_from_other_thread); - g_assert (initial_from_other_thread == NULL); + gs_unref_object NMPNetns *netns1 = NULL; + NMPNetns * initial_from_other_thread; + GThread * th; + + if (_test_netns_check_skip()) + return; + + netns1 = nmp_netns_new(); + g_assert(NMP_NETNS(netns1)); + nmp_netns_pop(netns1); + + th = g_thread_new("nm-test-netns-mt", _test_netns_mt_thread, netns1); + initial_from_other_thread = g_thread_join(th); + g_assert(NMP_IS_NETNS(initial_from_other_thread)); + + if (nmtst_get_rand_bool()) { + nmp_netns_push(initial_from_other_thread); + nmp_netns_pop(initial_from_other_thread); + } + + g_object_add_weak_pointer(G_OBJECT(initial_from_other_thread), + (gpointer *) &initial_from_other_thread); + g_object_unref(initial_from_other_thread); + g_assert(initial_from_other_thread == NULL); } /*****************************************************************************/ static void -ethtool_features_dump (const NMEthtoolFeatureStates *features) +ethtool_features_dump(const NMEthtoolFeatureStates *features) { - guint i, j; - - g_assert (features); - - _LOGT (">>> %u features (%u ss-features)", features->n_states, features->n_ss_features); - - for (i = 0; i < features->n_states; i++) { - const NMEthtoolFeatureState *s = &features->states_list[i]; - - _LOGT (">>> feature-list[%3u]: %3d = %-32s (%3u) | %s %s %s %s", - i, - (int) s->info->ethtool_id, - s->info->kernel_names[s->idx_kernel_name], - s->idx_ss_features, - s->active ? "ACT" : "act", - s->available ? "AVA" : "ava", - s->never_changed ? "NCH" : "nch", - s->requested ? "REQ" : "req"); - } - for (i = 0; i < _NM_ETHTOOL_ID_FEATURE_NUM; i++) { - _LOGT (">>> feature-idx [%3u]: %-32s = %u features", - i + (guint) _NM_ETHTOOL_ID_FEATURE_FIRST, - nm_ethtool_data[i + _NM_ETHTOOL_ID_FEATURE_FIRST]->optname, - (guint) NM_PTRARRAY_LEN (features->states_indexed[i])); - for (j = 0; features->states_indexed[i] && features->states_indexed[i][j]; j++) { - const NMEthtoolFeatureState *s = features->states_indexed[i][j]; - - _LOGT (">>> %3u: %-32s | %s %s %s %s", - j, - s->info->kernel_names[s->idx_kernel_name], - s->active ? "ACT" : "act", - s->available ? "AVA" : "ava", - s->never_changed ? "NCH" : "nch", - s->requested ? "REQ" : "req"); - } - } + guint i, j; + + g_assert(features); + + _LOGT(">>> %u features (%u ss-features)", features->n_states, features->n_ss_features); + + for (i = 0; i < features->n_states; i++) { + const NMEthtoolFeatureState *s = &features->states_list[i]; + + _LOGT(">>> feature-list[%3u]: %3d = %-32s (%3u) | %s %s %s %s", + i, + (int) s->info->ethtool_id, + s->info->kernel_names[s->idx_kernel_name], + s->idx_ss_features, + s->active ? "ACT" : "act", + s->available ? "AVA" : "ava", + s->never_changed ? "NCH" : "nch", + s->requested ? "REQ" : "req"); + } + for (i = 0; i < _NM_ETHTOOL_ID_FEATURE_NUM; i++) { + _LOGT(">>> feature-idx [%3u]: %-32s = %u features", + i + (guint) _NM_ETHTOOL_ID_FEATURE_FIRST, + nm_ethtool_data[i + _NM_ETHTOOL_ID_FEATURE_FIRST]->optname, + (guint) NM_PTRARRAY_LEN(features->states_indexed[i])); + for (j = 0; features->states_indexed[i] && features->states_indexed[i][j]; j++) { + const NMEthtoolFeatureState *s = features->states_indexed[i][j]; + + _LOGT(">>> %3u: %-32s | %s %s %s %s", + j, + s->info->kernel_names[s->idx_kernel_name], + s->active ? "ACT" : "act", + s->available ? "AVA" : "ava", + s->never_changed ? "NCH" : "nch", + s->requested ? "REQ" : "req"); + } + } } static void -test_ethtool_features_get (void) +test_ethtool_features_get(void) { - gs_unref_ptrarray GPtrArray *gfree_keeper = g_ptr_array_new_with_free_func (g_free); - const int IFINDEX = 1; - guint i; - guint i_run; - - for (i_run = 0; i_run < 5; i_run++) { - NMEthtoolFeatureStates *features; - NMTernary *requested; - gboolean do_set = TRUE; - - requested = g_new (NMTernary, _NM_ETHTOOL_ID_FEATURE_NUM); - for (i = 0; i < _NM_ETHTOOL_ID_FEATURE_NUM; i++) - requested[i] = NM_TERNARY_DEFAULT; - g_ptr_array_add (gfree_keeper, requested); - - if (i_run == 0) { - requested[_NM_ETHTOOL_ID_FEATURE_AS_IDX (NM_ETHTOOL_ID_FEATURE_RX)] = NM_TERNARY_FALSE; - requested[_NM_ETHTOOL_ID_FEATURE_AS_IDX (NM_ETHTOOL_ID_FEATURE_TSO)] = NM_TERNARY_FALSE; - requested[_NM_ETHTOOL_ID_FEATURE_AS_IDX (NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION)] = NM_TERNARY_FALSE; - } else if (i_run == 1) - do_set = FALSE; - else if (i_run == 2) { - requested[_NM_ETHTOOL_ID_FEATURE_AS_IDX (NM_ETHTOOL_ID_FEATURE_TSO)] = NM_TERNARY_FALSE; - requested[_NM_ETHTOOL_ID_FEATURE_AS_IDX (NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION)] = NM_TERNARY_TRUE; - } else if (i_run == 3) - do_set = FALSE; - - _LOGT (">>> ethtool-features-get RUN %u (do-set=%s", i_run, do_set ? "set" : "reset"); - - features = nmp_utils_ethtool_get_features (IFINDEX); - g_ptr_array_add (gfree_keeper, features); - - ethtool_features_dump (features); - - if (_LOGT_ENABLED ()) - _system ("ethtool -k lo"); - - if (!do_set) { - requested = gfree_keeper->pdata[i_run * 2 - 2]; - features = gfree_keeper->pdata[i_run * 2 - 1]; - } - - nmp_utils_ethtool_set_features (IFINDEX, features, requested, do_set); - } + gs_unref_ptrarray GPtrArray *gfree_keeper = g_ptr_array_new_with_free_func(g_free); + const int IFINDEX = 1; + guint i; + guint i_run; + + for (i_run = 0; i_run < 5; i_run++) { + NMEthtoolFeatureStates *features; + NMTernary * requested; + gboolean do_set = TRUE; + + requested = g_new(NMTernary, _NM_ETHTOOL_ID_FEATURE_NUM); + for (i = 0; i < _NM_ETHTOOL_ID_FEATURE_NUM; i++) + requested[i] = NM_TERNARY_DEFAULT; + g_ptr_array_add(gfree_keeper, requested); + + if (i_run == 0) { + requested[_NM_ETHTOOL_ID_FEATURE_AS_IDX(NM_ETHTOOL_ID_FEATURE_RX)] = NM_TERNARY_FALSE; + requested[_NM_ETHTOOL_ID_FEATURE_AS_IDX(NM_ETHTOOL_ID_FEATURE_TSO)] = NM_TERNARY_FALSE; + requested[_NM_ETHTOOL_ID_FEATURE_AS_IDX(NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION)] = + NM_TERNARY_FALSE; + } else if (i_run == 1) + do_set = FALSE; + else if (i_run == 2) { + requested[_NM_ETHTOOL_ID_FEATURE_AS_IDX(NM_ETHTOOL_ID_FEATURE_TSO)] = NM_TERNARY_FALSE; + requested[_NM_ETHTOOL_ID_FEATURE_AS_IDX(NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION)] = + NM_TERNARY_TRUE; + } else if (i_run == 3) + do_set = FALSE; + + _LOGT(">>> ethtool-features-get RUN %u (do-set=%s", i_run, do_set ? "set" : "reset"); + + features = nmp_utils_ethtool_get_features(IFINDEX); + g_ptr_array_add(gfree_keeper, features); + + ethtool_features_dump(features); + + if (_LOGT_ENABLED()) + _system("ethtool -k lo"); + + if (!do_set) { + requested = gfree_keeper->pdata[i_run * 2 - 2]; + features = gfree_keeper->pdata[i_run * 2 - 1]; + } + + nmp_utils_ethtool_set_features(IFINDEX, features, requested, do_set); + } } /*****************************************************************************/ @@ -3325,73 +3719,98 @@ test_ethtool_features_get (void) NMTstpSetupFunc const _nmtstp_setup_platform_func = SETUP; void -_nmtstp_init_tests (int *argc, char ***argv) +_nmtstp_init_tests(int *argc, char ***argv) { - nmtst_init_with_logging (argc, argv, NULL, "ALL"); + nmtst_init_with_logging(argc, argv, NULL, "ALL"); } void -_nmtstp_setup_tests (void) +_nmtstp_setup_tests(void) { - nmtstp_link_delete (NM_PLATFORM_GET, -1, -1, DEVICE_NAME, FALSE); - nmtstp_link_delete (NM_PLATFORM_GET, -1, -1, SLAVE_NAME, FALSE); - nmtstp_link_delete (NM_PLATFORM_GET, -1, -1, PARENT_NAME, FALSE); - g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, DEVICE_NAME)); - g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, SLAVE_NAME)); - g_assert (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, PARENT_NAME)); - - g_test_add_func ("/link/bogus", test_bogus); - g_test_add_func ("/link/loopback", test_loopback); - g_test_add_func ("/link/internal", test_internal); - g_test_add_func ("/link/software/bridge", test_bridge); - g_test_add_func ("/link/software/bond", test_bond); - g_test_add_func ("/link/software/team", test_team); - g_test_add_func ("/link/software/vlan", test_vlan); - g_test_add_func ("/link/software/bridge/addr", test_bridge_addr); - - if (nmtstp_is_root_test ()) { - g_test_add_func ("/link/external", test_external); - - test_software_detect_add ("/link/software/detect/gre", NM_LINK_TYPE_GRE, 0); - test_software_detect_add ("/link/software/detect/gretap", NM_LINK_TYPE_GRETAP, 0); - test_software_detect_add ("/link/software/detect/ip6tnl/0", NM_LINK_TYPE_IP6TNL, 0); - test_software_detect_add ("/link/software/detect/ip6tnl/1", NM_LINK_TYPE_IP6TNL, 1); - test_software_detect_add ("/link/software/detect/ip6gre", NM_LINK_TYPE_IP6GRE, 0); - test_software_detect_add ("/link/software/detect/ip6gretap", NM_LINK_TYPE_IP6GRETAP, 0); - test_software_detect_add ("/link/software/detect/ipip", NM_LINK_TYPE_IPIP, 0); - test_software_detect_add ("/link/software/detect/macvlan", NM_LINK_TYPE_MACVLAN, 0); - test_software_detect_add ("/link/software/detect/macvtap", NM_LINK_TYPE_MACVTAP, 0); - test_software_detect_add ("/link/software/detect/sit", NM_LINK_TYPE_SIT, 0); - test_software_detect_add ("/link/software/detect/tun", NM_LINK_TYPE_TUN, 0); - test_software_detect_add ("/link/software/detect/vlan", NM_LINK_TYPE_VLAN, 0); - test_software_detect_add ("/link/software/detect/vrf", NM_LINK_TYPE_VRF, 0); - test_software_detect_add ("/link/software/detect/vxlan/0", NM_LINK_TYPE_VXLAN, 0); - test_software_detect_add ("/link/software/detect/vxlan/1", NM_LINK_TYPE_VXLAN, 1); - test_software_detect_add ("/link/software/detect/wireguard/0", NM_LINK_TYPE_WIREGUARD, 0); - test_software_detect_add ("/link/software/detect/wireguard/1", NM_LINK_TYPE_WIREGUARD, 1); - test_software_detect_add ("/link/software/detect/wireguard/2", NM_LINK_TYPE_WIREGUARD, 2); - - g_test_add_func ("/link/software/vlan/set-xgress", test_vlan_set_xgress); - - 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_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); - - g_test_add_vtable ("/general/netns/general", 0, NULL, _test_netns_setup, test_netns_general, _test_netns_teardown); - g_test_add_vtable ("/general/netns/set-netns", 0, NULL, _test_netns_setup, test_netns_set_netns, _test_netns_teardown); - g_test_add_vtable ("/general/netns/push", 0, NULL, _test_netns_setup, test_netns_push, _test_netns_teardown); - g_test_add_vtable ("/general/netns/bind-to-path", 0, NULL, _test_netns_setup, test_netns_bind_to_path, _test_netns_teardown); - - g_test_add_func ("/general/netns/mt", test_netns_mt); - - g_test_add_func ("/general/sysctl/rename", test_sysctl_rename); - g_test_add_func ("/general/sysctl/netns-switch", test_sysctl_netns_switch); - g_test_add_func ("/general/sysctl/set-async", test_sysctl_set_async); - g_test_add_func ("/general/sysctl/set-async-fail", test_sysctl_set_async_fail); - - g_test_add_func ("/link/ethtool/features/get", test_ethtool_features_get); - } + nmtstp_link_delete(NM_PLATFORM_GET, -1, -1, DEVICE_NAME, FALSE); + nmtstp_link_delete(NM_PLATFORM_GET, -1, -1, SLAVE_NAME, FALSE); + nmtstp_link_delete(NM_PLATFORM_GET, -1, -1, PARENT_NAME, FALSE); + g_assert(!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, DEVICE_NAME)); + g_assert(!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, SLAVE_NAME)); + g_assert(!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, PARENT_NAME)); + + g_test_add_func("/link/bogus", test_bogus); + g_test_add_func("/link/loopback", test_loopback); + g_test_add_func("/link/internal", test_internal); + g_test_add_func("/link/software/bridge", test_bridge); + g_test_add_func("/link/software/bond", test_bond); + g_test_add_func("/link/software/team", test_team); + g_test_add_func("/link/software/vlan", test_vlan); + g_test_add_func("/link/software/bridge/addr", test_bridge_addr); + + if (nmtstp_is_root_test()) { + g_test_add_func("/link/external", test_external); + + test_software_detect_add("/link/software/detect/bridge", NM_LINK_TYPE_BRIDGE, 0); + test_software_detect_add("/link/software/detect/gre", NM_LINK_TYPE_GRE, 0); + test_software_detect_add("/link/software/detect/gretap", NM_LINK_TYPE_GRETAP, 0); + test_software_detect_add("/link/software/detect/ip6tnl/0", NM_LINK_TYPE_IP6TNL, 0); + test_software_detect_add("/link/software/detect/ip6tnl/1", NM_LINK_TYPE_IP6TNL, 1); + test_software_detect_add("/link/software/detect/ip6gre", NM_LINK_TYPE_IP6GRE, 0); + test_software_detect_add("/link/software/detect/ip6gretap", NM_LINK_TYPE_IP6GRETAP, 0); + test_software_detect_add("/link/software/detect/ipip", NM_LINK_TYPE_IPIP, 0); + test_software_detect_add("/link/software/detect/macvlan", NM_LINK_TYPE_MACVLAN, 0); + test_software_detect_add("/link/software/detect/macvtap", NM_LINK_TYPE_MACVTAP, 0); + test_software_detect_add("/link/software/detect/sit", NM_LINK_TYPE_SIT, 0); + test_software_detect_add("/link/software/detect/tun", NM_LINK_TYPE_TUN, 0); + test_software_detect_add("/link/software/detect/vlan", NM_LINK_TYPE_VLAN, 0); + test_software_detect_add("/link/software/detect/vrf", NM_LINK_TYPE_VRF, 0); + test_software_detect_add("/link/software/detect/vxlan/0", NM_LINK_TYPE_VXLAN, 0); + test_software_detect_add("/link/software/detect/vxlan/1", NM_LINK_TYPE_VXLAN, 1); + test_software_detect_add("/link/software/detect/wireguard/0", NM_LINK_TYPE_WIREGUARD, 0); + test_software_detect_add("/link/software/detect/wireguard/1", NM_LINK_TYPE_WIREGUARD, 1); + test_software_detect_add("/link/software/detect/wireguard/2", NM_LINK_TYPE_WIREGUARD, 2); + + g_test_add_func("/link/software/vlan/set-xgress", test_vlan_set_xgress); + + 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_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); + + g_test_add_vtable("/general/netns/general", + 0, + NULL, + _test_netns_setup, + test_netns_general, + _test_netns_teardown); + g_test_add_vtable("/general/netns/set-netns", + 0, + NULL, + _test_netns_setup, + test_netns_set_netns, + _test_netns_teardown); + g_test_add_vtable("/general/netns/push", + 0, + NULL, + _test_netns_setup, + test_netns_push, + _test_netns_teardown); + g_test_add_vtable("/general/netns/bind-to-path", + 0, + NULL, + _test_netns_setup, + test_netns_bind_to_path, + _test_netns_teardown); + + g_test_add_func("/general/netns/mt", test_netns_mt); + + g_test_add_func("/general/sysctl/rename", test_sysctl_rename); + g_test_add_func("/general/sysctl/netns-switch", test_sysctl_netns_switch); + g_test_add_func("/general/sysctl/set-async", test_sysctl_set_async); + g_test_add_func("/general/sysctl/set-async-fail", test_sysctl_set_async_fail); + + g_test_add_func("/link/ethtool/features/get", test_ethtool_features_get); + } } diff --git a/src/platform/tests/test-nmp-object.c b/src/platform/tests/test-nmp-object.c index 8ecfac8a..e61e6b09 100644 --- a/src/platform/tests/test-nmp-object.c +++ b/src/platform/tests/test-nmp-object.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2015 - 2017 Red Hat, Inc. */ @@ -14,571 +14,604 @@ #include "nm-test-utils-core.h" struct { - GList *udev_devices; + GList *udev_devices; } global; /*****************************************************************************/ static void -test_obj_base (void) +test_obj_base(void) { - static const union { - GObject g; - NMPObject k; - } x = { }; - static const union { - GTypeClass k; - NMPClass c; - } l = { }; - static const GObject *g = &x.g; - static const GTypeClass *k = &l.k; - static const NMPObject *o = &x.k; - static const NMPClass *c = &l.c; - - NMObjBaseInst *obj; - gs_unref_object GCancellable *obj_cancellable = g_cancellable_new (); - nm_auto_nmpobj NMPObject *obj_link = nmp_object_new_link (10); - - g_assert (&g->g_type_instance == (void *) &o->_class); - g_assert (&g->g_type_instance.g_class == (void *) &o->_class); - - g_assert (sizeof (o->parent.parent) == sizeof (GTypeInstance)); - - g_assert (&c->parent == (void *) c); - g_assert (&c->parent.parent.g_type_class == (void *) c); - g_assert (&c->parent.parent.g_type == (void *) c); - g_assert (&c->parent.parent.g_type == &k->g_type); - - g_assert (sizeof (c->parent.parent) == sizeof (GTypeClass)); - - g_assert (&o->parent == (void *) o); - g_assert (&o->parent.klass == (void *) &o->_class); - - obj = (NMObjBaseInst *) obj_cancellable; - g_assert (!NMP_CLASS_IS_VALID ((NMPClass *) obj->klass)); - g_assert (G_TYPE_CHECK_INSTANCE_TYPE (obj, G_TYPE_CANCELLABLE)); - - obj = (NMObjBaseInst *) obj_link; - g_assert (NMP_CLASS_IS_VALID ((NMPClass *) obj->klass)); - g_assert (!G_TYPE_CHECK_INSTANCE_TYPE (obj, G_TYPE_CANCELLABLE)); - + static const union { + GObject g; + NMPObject k; + } x = {}; + static const union { + GTypeClass k; + NMPClass c; + } l = {}; + static const GObject * g = &x.g; + static const GTypeClass *k = &l.k; + static const NMPObject * o = &x.k; + static const NMPClass * c = &l.c; + + NMObjBaseInst * obj; + gs_unref_object GCancellable *obj_cancellable = g_cancellable_new(); + nm_auto_nmpobj NMPObject *obj_link = nmp_object_new_link(10); + + g_assert(&g->g_type_instance == (void *) &o->_class); + g_assert(&g->g_type_instance.g_class == (void *) &o->_class); + + g_assert(sizeof(o->parent.parent) == sizeof(GTypeInstance)); + + g_assert(&c->parent == (void *) c); + g_assert(&c->parent.parent.g_type_class == (void *) c); + g_assert(&c->parent.parent.g_type == (void *) c); + g_assert(&c->parent.parent.g_type == &k->g_type); + + g_assert(sizeof(c->parent.parent) == sizeof(GTypeClass)); + + g_assert(&o->parent == (void *) o); + g_assert(&o->parent.klass == (void *) &o->_class); + + obj = (NMObjBaseInst *) obj_cancellable; + g_assert(!NMP_CLASS_IS_VALID((NMPClass *) obj->klass)); + g_assert(G_TYPE_CHECK_INSTANCE_TYPE(obj, G_TYPE_CANCELLABLE)); + + obj = (NMObjBaseInst *) obj_link; + g_assert(NMP_CLASS_IS_VALID((NMPClass *) obj->klass)); + g_assert(!G_TYPE_CHECK_INSTANCE_TYPE(obj, G_TYPE_CANCELLABLE)); } /*****************************************************************************/ static gboolean -_nmp_object_id_equal (const NMPObject *a, const NMPObject *b) +_nmp_object_id_equal(const NMPObject *a, const NMPObject *b) { - gboolean a_b = nmp_object_id_equal (a, b); + gboolean a_b = nmp_object_id_equal(a, b); - g_assert (NM_IN_SET (a_b, FALSE, TRUE) && a_b == nmp_object_id_equal (b, a)); - return a_b; + g_assert(NM_IN_SET(a_b, FALSE, TRUE) && a_b == nmp_object_id_equal(b, a)); + return a_b; } #define nmp_object_id_equal _nmp_object_id_equal static gboolean -_nmp_object_equal (const NMPObject *a, const NMPObject *b) +_nmp_object_equal(const NMPObject *a, const NMPObject *b) { - gboolean a_b = nmp_object_equal (a, b); + gboolean a_b = nmp_object_equal(a, b); - g_assert (NM_IN_SET (a_b, FALSE, TRUE) && a_b == nmp_object_equal (b, a)); - return a_b; + g_assert(NM_IN_SET(a_b, FALSE, TRUE) && a_b == nmp_object_equal(b, a)); + return a_b; } #define nmp_object_equal _nmp_object_equal /*****************************************************************************/ static void -_assert_cache_multi_lookup_contains (const NMPCache *cache, const NMDedupMultiHeadEntry *head_entry, const NMPObject *obj, gboolean visible_only, gboolean contains) +_assert_cache_multi_lookup_contains(const NMPCache * cache, + const NMDedupMultiHeadEntry *head_entry, + const NMPObject * obj, + gboolean visible_only, + gboolean contains) { - NMDedupMultiIter iter; - gboolean found; - guint i, len; - const NMPObject *o; - - g_assert (NMP_OBJECT_IS_VALID (obj)); - - g_assert (nmp_cache_lookup_obj (cache, obj) == obj); - g_assert (!head_entry || (head_entry->len > 0 && c_list_length (&head_entry->lst_entries_head) == head_entry->len)); - - len = head_entry ? head_entry->len : 0; - - found = FALSE; - i = 0; - nmp_cache_iter_for_each (&iter, - head_entry, - &o) { - g_assert (NMP_OBJECT_IS_VALID (o)); - if (obj == o) { - if ( !visible_only - || nmp_object_is_visible (o)) { - g_assert (!found); - found = TRUE; - } - } - i++; - } - - g_assert (len == i); - g_assert (!!contains == found); + NMDedupMultiIter iter; + gboolean found; + guint i, len; + const NMPObject *o; + + g_assert(NMP_OBJECT_IS_VALID(obj)); + + g_assert(nmp_cache_lookup_obj(cache, obj) == obj); + g_assert(!head_entry + || (head_entry->len > 0 + && c_list_length(&head_entry->lst_entries_head) == head_entry->len)); + + len = head_entry ? head_entry->len : 0; + + found = FALSE; + i = 0; + nmp_cache_iter_for_each (&iter, head_entry, &o) { + g_assert(NMP_OBJECT_IS_VALID(o)); + if (obj == o) { + if (!visible_only || nmp_object_is_visible(o)) { + g_assert(!found); + found = TRUE; + } + } + i++; + } + + g_assert(len == i); + g_assert(!!contains == found); } static void -_assert_cache_multi_lookup_contains_link (const NMPCache *cache, - gboolean visible_only, - const NMPObject *obj, - gboolean contains) +_assert_cache_multi_lookup_contains_link(const NMPCache * cache, + gboolean visible_only, + const NMPObject *obj, + gboolean contains) { - const NMDedupMultiHeadEntry *head_entry; - NMPLookup lookup; + const NMDedupMultiHeadEntry *head_entry; + NMPLookup lookup; - g_assert (cache); + g_assert(cache); - nmp_lookup_init_obj_type (&lookup, NMP_OBJECT_TYPE_LINK); - head_entry = nmp_cache_lookup (cache, &lookup); - _assert_cache_multi_lookup_contains (cache, head_entry, obj, visible_only, contains); + nmp_lookup_init_obj_type(&lookup, NMP_OBJECT_TYPE_LINK); + head_entry = nmp_cache_lookup(cache, &lookup); + _assert_cache_multi_lookup_contains(cache, head_entry, obj, visible_only, contains); } /*****************************************************************************/ static void -ops_post_check (NMPCache *cache, - NMPCacheOpsType ops_type, - const NMPObject *obj_old, - const NMPObject *obj_new, - const NMPObject *obj_new_expected, - NMPCacheOpsType expected_ops_type) +ops_post_check(NMPCache * cache, + NMPCacheOpsType ops_type, + const NMPObject *obj_old, + const NMPObject *obj_new, + const NMPObject *obj_new_expected, + NMPCacheOpsType expected_ops_type) { - g_assert (cache); - - g_assert_cmpint (expected_ops_type, ==, ops_type); - - switch (ops_type) { - case NMP_CACHE_OPS_ADDED: - g_assert (!obj_old); - g_assert (NMP_OBJECT_IS_VALID (obj_new)); - g_assert (nmp_object_is_alive (obj_new)); - g_assert (nmp_object_id_equal (obj_new_expected, obj_new)); - g_assert (nmp_object_equal (obj_new_expected, obj_new)); - break; - case NMP_CACHE_OPS_UPDATED: - g_assert (obj_old != obj_new); - g_assert (NMP_OBJECT_IS_VALID (obj_old)); - g_assert (NMP_OBJECT_IS_VALID (obj_new)); - g_assert (nmp_object_is_alive (obj_old)); - g_assert (nmp_object_is_alive (obj_new)); - g_assert (nmp_object_id_equal (obj_new_expected, obj_new)); - g_assert (nmp_object_id_equal (obj_new_expected, obj_old)); - g_assert (nmp_object_id_equal (obj_old, obj_new)); - g_assert (nmp_object_equal (obj_new_expected, obj_new)); - g_assert (!nmp_object_equal (obj_new_expected, obj_old)); - g_assert (!nmp_object_equal (obj_old, obj_new)); - break; - case NMP_CACHE_OPS_REMOVED: - g_assert (!obj_new); - g_assert (NMP_OBJECT_IS_VALID (obj_old)); - g_assert (nmp_object_is_alive (obj_old)); - if (obj_new_expected) - g_assert (nmp_object_id_equal (obj_new_expected, obj_old)); - break; - case NMP_CACHE_OPS_UNCHANGED: - g_assert (obj_old == obj_new); - if (obj_old) { - g_assert (NMP_OBJECT_IS_VALID (obj_old)); - g_assert (nmp_object_is_alive (obj_old)); - g_assert (nmp_object_equal (obj_old, obj_new)); - g_assert (nmp_object_id_equal (obj_new_expected, obj_new)); - } else - g_assert (!obj_new_expected); - break; - default: - g_assert_not_reached (); - } + g_assert(cache); + + g_assert_cmpint(expected_ops_type, ==, ops_type); + + switch (ops_type) { + case NMP_CACHE_OPS_ADDED: + g_assert(!obj_old); + g_assert(NMP_OBJECT_IS_VALID(obj_new)); + g_assert(nmp_object_is_alive(obj_new)); + g_assert(nmp_object_id_equal(obj_new_expected, obj_new)); + g_assert(nmp_object_equal(obj_new_expected, obj_new)); + break; + case NMP_CACHE_OPS_UPDATED: + g_assert(obj_old != obj_new); + g_assert(NMP_OBJECT_IS_VALID(obj_old)); + g_assert(NMP_OBJECT_IS_VALID(obj_new)); + g_assert(nmp_object_is_alive(obj_old)); + g_assert(nmp_object_is_alive(obj_new)); + g_assert(nmp_object_id_equal(obj_new_expected, obj_new)); + g_assert(nmp_object_id_equal(obj_new_expected, obj_old)); + g_assert(nmp_object_id_equal(obj_old, obj_new)); + g_assert(nmp_object_equal(obj_new_expected, obj_new)); + g_assert(!nmp_object_equal(obj_new_expected, obj_old)); + g_assert(!nmp_object_equal(obj_old, obj_new)); + break; + case NMP_CACHE_OPS_REMOVED: + g_assert(!obj_new); + g_assert(NMP_OBJECT_IS_VALID(obj_old)); + g_assert(nmp_object_is_alive(obj_old)); + if (obj_new_expected) + g_assert(nmp_object_id_equal(obj_new_expected, obj_old)); + break; + case NMP_CACHE_OPS_UNCHANGED: + g_assert(obj_old == obj_new); + if (obj_old) { + g_assert(NMP_OBJECT_IS_VALID(obj_old)); + g_assert(nmp_object_is_alive(obj_old)); + g_assert(nmp_object_equal(obj_old, obj_new)); + g_assert(nmp_object_id_equal(obj_new_expected, obj_new)); + } else + g_assert(!obj_new_expected); + break; + default: + g_assert_not_reached(); + } } static void -_nmp_cache_update_netlink (NMPCache *cache, NMPObject *obj, const NMPObject **out_obj_old, const NMPObject **out_obj_new, NMPCacheOpsType expected_ops_type) +_nmp_cache_update_netlink(NMPCache * cache, + NMPObject * obj, + const NMPObject **out_obj_old, + const NMPObject **out_obj_new, + NMPCacheOpsType expected_ops_type) { - NMPCacheOpsType ops_type; - const NMPObject *obj_prev; - const NMPObject *obj_old; - const NMPObject *obj_new; - nm_auto_nmpobj NMPObject *obj_new_expected = NULL; - - g_assert (cache); - g_assert (NMP_OBJECT_IS_VALID (obj)); - - obj_prev = nmp_cache_lookup_link (cache, NMP_OBJECT_CAST_LINK (obj)->ifindex); - obj_new_expected = nmp_object_clone (obj, FALSE); - if (obj_prev && obj_prev->_link.udev.device) - obj_new_expected->_link.udev.device = udev_device_ref (obj_prev->_link.udev.device); - _nmp_object_fixup_link_udev_fields (&obj_new_expected, NULL, nmp_cache_use_udev_get (cache)); - - ops_type = nmp_cache_update_netlink (cache, obj, FALSE, &obj_old, &obj_new); - ops_post_check (cache, ops_type, obj_old, obj_new, - nmp_object_is_alive (obj_new_expected) ? obj_new_expected : NULL, - expected_ops_type); - - if (out_obj_new) - *out_obj_new = obj_new; - else - nmp_object_unref (obj_new); - if (out_obj_old) - *out_obj_old = obj_old; - else - nmp_object_unref (obj_old); + NMPCacheOpsType ops_type; + const NMPObject *obj_prev; + const NMPObject *obj_old; + const NMPObject *obj_new; + nm_auto_nmpobj NMPObject *obj_new_expected = NULL; + + g_assert(cache); + g_assert(NMP_OBJECT_IS_VALID(obj)); + + obj_prev = nmp_cache_lookup_link(cache, NMP_OBJECT_CAST_LINK(obj)->ifindex); + obj_new_expected = nmp_object_clone(obj, FALSE); + if (obj_prev && obj_prev->_link.udev.device) + obj_new_expected->_link.udev.device = udev_device_ref(obj_prev->_link.udev.device); + _nmp_object_fixup_link_udev_fields(&obj_new_expected, NULL, nmp_cache_use_udev_get(cache)); + + ops_type = nmp_cache_update_netlink(cache, obj, FALSE, &obj_old, &obj_new); + ops_post_check(cache, + ops_type, + obj_old, + obj_new, + nmp_object_is_alive(obj_new_expected) ? obj_new_expected : NULL, + expected_ops_type); + + if (out_obj_new) + *out_obj_new = obj_new; + else + nmp_object_unref(obj_new); + if (out_obj_old) + *out_obj_old = obj_old; + else + nmp_object_unref(obj_old); } static const NMPlatformLink pl_link_2 = { - .ifindex = 2, - .name = "eth0", - .type = NM_LINK_TYPE_ETHERNET, + .ifindex = 2, + .name = "eth0", + .type = NM_LINK_TYPE_ETHERNET, }; static const NMPlatformLink pl_link_3 = { - .ifindex = 3, - .name = "wlan0", - .type = NM_LINK_TYPE_WIFI, + .ifindex = 3, + .name = "wlan0", + .type = NM_LINK_TYPE_WIFI, }; static void -test_cache_link (void) +test_cache_link(void) { - NMPCache *cache; - NMPObject *objm1; - const NMPObject *obj_old, *obj_new; - NMPObject objs1; - struct udev_device *udev_device_2 = g_list_nth_data (global.udev_devices, 0); - struct udev_device *udev_device_3 = g_list_nth_data (global.udev_devices, 0); - NMPCacheOpsType ops_type; - nm_auto_unref_dedup_multi_index NMDedupMultiIndex *multi_idx = NULL; - gboolean use_udev = nmtst_get_rand_uint32 () % 2; - - multi_idx = nm_dedup_multi_index_new (); - - cache = nmp_cache_new (multi_idx, use_udev); - - /* if we have a link, and don't set is_in_netlink, adding it has no effect. */ - objm1 = nmp_object_new (NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2); - g_assert (NMP_OBJECT_UP_CAST (&objm1->object) == objm1); - g_assert (!nmp_object_is_alive (objm1)); - _nmp_cache_update_netlink (cache, objm1, &obj_old, &obj_new, NMP_CACHE_OPS_UNCHANGED); - ASSERT_nmp_cache_is_consistent (cache); - g_assert (!obj_old); - g_assert (!obj_new); - g_assert (!nmp_cache_lookup_obj (cache, objm1)); - g_assert (!nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&objs1, pl_link_2.ifindex))); - nmp_object_unref (objm1); - - /* Only when setting @is_in_netlink the link is added. */ - objm1 = nmp_object_new (NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2); - objm1->_link.netlink.is_in_netlink = TRUE; - g_assert (nmp_object_is_alive (objm1)); - _nmp_cache_update_netlink (cache, objm1, &obj_old, &obj_new, NMP_CACHE_OPS_ADDED); - ASSERT_nmp_cache_is_consistent (cache); - g_assert (!obj_old); - g_assert (obj_new); - g_assert (objm1 == obj_new); - g_assert (nmp_object_equal (objm1, obj_new)); - g_assert (nmp_cache_lookup_obj (cache, objm1) == obj_new); - g_assert (nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&objs1, pl_link_2.ifindex)) == obj_new); - g_assert (nmp_object_is_visible (obj_new)); - _assert_cache_multi_lookup_contains_link (cache, FALSE, obj_new, TRUE); - _assert_cache_multi_lookup_contains_link (cache, TRUE, obj_new, TRUE); - nmp_object_unref (objm1); - nmp_object_unref (obj_new); - - /* updating the same link with identical value, has no effect. */ - objm1 = nmp_object_new (NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2); - objm1->_link.netlink.is_in_netlink = TRUE; - g_assert (nmp_object_is_alive (objm1)); - _nmp_cache_update_netlink (cache, objm1, &obj_old, &obj_new, NMP_CACHE_OPS_UNCHANGED); - ASSERT_nmp_cache_is_consistent (cache); - g_assert (obj_old); - g_assert (obj_new); - g_assert (obj_new != objm1); - g_assert (nmp_object_equal (objm1, obj_new)); - g_assert (nmp_cache_lookup_obj (cache, objm1) == obj_new); - g_assert (nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&objs1, pl_link_2.ifindex)) == obj_new); - nmp_object_unref (objm1); - nmp_object_unref (obj_new); - nmp_object_unref (obj_new); - - /* remove the link from netlink */ - objm1 = nmp_object_new (NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2); - g_assert (!nmp_object_is_alive (objm1)); - _nmp_cache_update_netlink (cache, objm1, &obj_old, &obj_new, NMP_CACHE_OPS_REMOVED); - ASSERT_nmp_cache_is_consistent (cache); - g_assert (obj_old); - g_assert (!obj_new); - g_assert (!nmp_cache_lookup_obj (cache, objm1)); - g_assert (!nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&objs1, pl_link_2.ifindex))); - nmp_object_unref (objm1); - nmp_object_unref (obj_old); - nmp_object_unref (obj_new); - - if (udev_device_2) { - /* now add the link only with aspect UDEV. */ - ops_type = nmp_cache_update_link_udev (cache, pl_link_2.ifindex, udev_device_2, &obj_old, &obj_new); - ASSERT_nmp_cache_is_consistent (cache); - g_assert_cmpint (ops_type, ==, NMP_CACHE_OPS_ADDED); - g_assert (!obj_old); - g_assert (obj_new); - g_assert (nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&objs1, pl_link_2.ifindex)) == obj_new); - g_assert (!nmp_object_is_visible (obj_new)); - _assert_cache_multi_lookup_contains_link (cache, TRUE, obj_new, FALSE); - _assert_cache_multi_lookup_contains_link (cache, FALSE, obj_new, TRUE); - nmp_object_unref (obj_new); - } - - /* add it in netlink too. */ - objm1 = nmp_object_new (NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2); - objm1->_link.netlink.is_in_netlink = TRUE; - g_assert (nmp_object_is_alive (objm1)); - _nmp_cache_update_netlink (cache, objm1, &obj_old, &obj_new, udev_device_2 ? NMP_CACHE_OPS_UPDATED : NMP_CACHE_OPS_ADDED); - ASSERT_nmp_cache_is_consistent (cache); - if (udev_device_2) { - g_assert (obj_old); - g_assert (!nmp_object_is_visible (obj_old)); - } else - g_assert (!obj_old); - g_assert (nmp_object_equal (objm1, obj_new)); - g_assert (nmp_cache_lookup_obj (cache, objm1) == obj_new); - g_assert (nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&objs1, pl_link_2.ifindex)) == obj_new); - g_assert (nmp_object_is_visible (obj_new)); - _assert_cache_multi_lookup_contains_link (cache, TRUE, obj_new, TRUE); - _assert_cache_multi_lookup_contains_link (cache, FALSE, obj_new, TRUE); - nmp_object_unref (objm1); - nmp_object_unref (obj_old); - nmp_object_unref (obj_new); - - /* remove again from netlink. */ - objm1 = nmp_object_new (NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2); - objm1->_link.netlink.is_in_netlink = FALSE; - g_assert (!nmp_object_is_alive (objm1)); - _nmp_cache_update_netlink (cache, objm1, &obj_old, &obj_new, udev_device_2 ? NMP_CACHE_OPS_UPDATED : NMP_CACHE_OPS_REMOVED); - ASSERT_nmp_cache_is_consistent (cache); - if (udev_device_2) - g_assert (obj_new == objm1); - else - g_assert (!obj_new); - g_assert (obj_old); - g_assert (nmp_object_is_alive (obj_old)); - if (udev_device_2) { - g_assert (nmp_cache_lookup_obj (cache, objm1) == obj_new); - g_assert (nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&objs1, pl_link_2.ifindex)) == obj_new); - g_assert (!nmp_object_is_visible (obj_new)); - _assert_cache_multi_lookup_contains_link (cache, TRUE, obj_new, FALSE); - _assert_cache_multi_lookup_contains_link (cache, FALSE, obj_new, TRUE); - } else { - g_assert (nmp_cache_lookup_obj (cache, objm1) == NULL); - g_assert (nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&objs1, pl_link_2.ifindex)) == NULL); - g_assert (!nmp_object_is_alive (obj_new)); - g_assert (!nmp_object_is_visible (obj_new)); - } - nmp_object_unref (objm1); - nmp_object_unref (obj_old); - nmp_object_unref (obj_new); - - /* now another link only with aspect UDEV. */ - if (udev_device_3) { - /* now add the link only with aspect UDEV. */ - ops_type = nmp_cache_update_link_udev (cache, pl_link_3.ifindex, udev_device_3, &obj_old, &obj_new); - g_assert_cmpint (ops_type, ==, NMP_CACHE_OPS_ADDED); - ASSERT_nmp_cache_is_consistent (cache); - g_assert (NMP_OBJECT_IS_VALID (obj_new)); - g_assert (!obj_old); - g_assert (!nmp_object_is_visible (obj_new)); - g_assert (nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&objs1, pl_link_3.ifindex)) == obj_new); - _assert_cache_multi_lookup_contains_link (cache, TRUE, obj_new, FALSE); - _assert_cache_multi_lookup_contains_link (cache, FALSE, obj_new, TRUE); - g_assert_cmpint (obj_new->_link.netlink.is_in_netlink, ==, FALSE); - g_assert_cmpint (obj_new->link.initialized, ==, FALSE); - nmp_object_unref (obj_new); - - /* add it in netlink too. */ - objm1 = nmp_object_new (NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_3); - objm1->_link.netlink.is_in_netlink = TRUE; - g_assert (nmp_object_is_alive (objm1)); - _nmp_cache_update_netlink (cache, objm1, &obj_old, &obj_new, NMP_CACHE_OPS_UPDATED); - ASSERT_nmp_cache_is_consistent (cache); - g_assert (obj_old); - g_assert (obj_new == objm1); - g_assert (nmp_object_equal (objm1, obj_new)); - g_assert (!obj_old || !nmp_object_is_visible (obj_old)); - g_assert (nmp_cache_lookup_obj (cache, objm1) == obj_new); - g_assert (nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&objs1, pl_link_3.ifindex)) == obj_new); - g_assert (nmp_object_is_visible (obj_new)); - _assert_cache_multi_lookup_contains_link (cache, TRUE, obj_new, TRUE); - _assert_cache_multi_lookup_contains_link (cache, FALSE, obj_new, TRUE); - g_assert_cmpint (obj_new->_link.netlink.is_in_netlink, ==, TRUE); - g_assert_cmpint (obj_new->link.initialized, ==, TRUE); - nmp_object_unref (objm1); - nmp_object_unref (obj_old); - nmp_object_unref (obj_new); - - /* remove UDEV. */ - ops_type = nmp_cache_update_link_udev (cache, pl_link_3.ifindex, NULL, &obj_old, &obj_new); - g_assert_cmpint (ops_type, ==, NMP_CACHE_OPS_UPDATED); - ASSERT_nmp_cache_is_consistent (cache); - g_assert (obj_old && nmp_object_is_visible (obj_old)); - g_assert (nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&objs1, pl_link_3.ifindex)) == obj_new); - g_assert (nmp_object_is_visible (obj_new)); - _assert_cache_multi_lookup_contains_link (cache, TRUE, obj_new, TRUE); - _assert_cache_multi_lookup_contains_link (cache, FALSE, obj_new, TRUE); - g_assert_cmpint (obj_new->_link.netlink.is_in_netlink, ==, TRUE); - g_assert_cmpint (obj_new->link.initialized, ==, !nmp_cache_use_udev_get (cache)); - nmp_object_unref (obj_new); - nmp_object_unref (obj_old); - } - - nmp_cache_free (cache); + NMPCache * cache; + NMPObject * objm1; + const NMPObject * obj_old, *obj_new; + NMPObject objs1; + struct udev_device * udev_device_2 = g_list_nth_data(global.udev_devices, 0); + struct udev_device * udev_device_3 = g_list_nth_data(global.udev_devices, 0); + NMPCacheOpsType ops_type; + nm_auto_unref_dedup_multi_index NMDedupMultiIndex *multi_idx = NULL; + gboolean use_udev = nmtst_get_rand_uint32() % 2; + + multi_idx = nm_dedup_multi_index_new(); + + cache = nmp_cache_new(multi_idx, use_udev); + + /* if we have a link, and don't set is_in_netlink, adding it has no effect. */ + objm1 = nmp_object_new(NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2); + g_assert(NMP_OBJECT_UP_CAST(&objm1->object) == objm1); + g_assert(!nmp_object_is_alive(objm1)); + _nmp_cache_update_netlink(cache, objm1, &obj_old, &obj_new, NMP_CACHE_OPS_UNCHANGED); + nmtst_assert_nmp_cache_is_consistent(cache); + g_assert(!obj_old); + g_assert(!obj_new); + g_assert(!nmp_cache_lookup_obj(cache, objm1)); + g_assert(!nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&objs1, pl_link_2.ifindex))); + nmp_object_unref(objm1); + + /* Only when setting @is_in_netlink the link is added. */ + objm1 = nmp_object_new(NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2); + objm1->_link.netlink.is_in_netlink = TRUE; + g_assert(nmp_object_is_alive(objm1)); + _nmp_cache_update_netlink(cache, objm1, &obj_old, &obj_new, NMP_CACHE_OPS_ADDED); + nmtst_assert_nmp_cache_is_consistent(cache); + g_assert(!obj_old); + g_assert(obj_new); + g_assert(objm1 == obj_new); + g_assert(nmp_object_equal(objm1, obj_new)); + g_assert(nmp_cache_lookup_obj(cache, objm1) == obj_new); + g_assert(nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&objs1, pl_link_2.ifindex)) + == obj_new); + g_assert(nmp_object_is_visible(obj_new)); + _assert_cache_multi_lookup_contains_link(cache, FALSE, obj_new, TRUE); + _assert_cache_multi_lookup_contains_link(cache, TRUE, obj_new, TRUE); + nmp_object_unref(objm1); + nmp_object_unref(obj_new); + + /* updating the same link with identical value, has no effect. */ + objm1 = nmp_object_new(NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2); + objm1->_link.netlink.is_in_netlink = TRUE; + g_assert(nmp_object_is_alive(objm1)); + _nmp_cache_update_netlink(cache, objm1, &obj_old, &obj_new, NMP_CACHE_OPS_UNCHANGED); + nmtst_assert_nmp_cache_is_consistent(cache); + g_assert(obj_old); + g_assert(obj_new); + g_assert(obj_new != objm1); + g_assert(nmp_object_equal(objm1, obj_new)); + g_assert(nmp_cache_lookup_obj(cache, objm1) == obj_new); + g_assert(nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&objs1, pl_link_2.ifindex)) + == obj_new); + nmp_object_unref(objm1); + nmp_object_unref(obj_new); + nmp_object_unref(obj_new); + + /* remove the link from netlink */ + objm1 = nmp_object_new(NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2); + g_assert(!nmp_object_is_alive(objm1)); + _nmp_cache_update_netlink(cache, objm1, &obj_old, &obj_new, NMP_CACHE_OPS_REMOVED); + nmtst_assert_nmp_cache_is_consistent(cache); + g_assert(obj_old); + g_assert(!obj_new); + g_assert(!nmp_cache_lookup_obj(cache, objm1)); + g_assert(!nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&objs1, pl_link_2.ifindex))); + nmp_object_unref(objm1); + nmp_object_unref(obj_old); + nmp_object_unref(obj_new); + + if (udev_device_2) { + /* now add the link only with aspect UDEV. */ + ops_type = + nmp_cache_update_link_udev(cache, pl_link_2.ifindex, udev_device_2, &obj_old, &obj_new); + nmtst_assert_nmp_cache_is_consistent(cache); + g_assert_cmpint(ops_type, ==, NMP_CACHE_OPS_ADDED); + g_assert(!obj_old); + g_assert(obj_new); + g_assert( + nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&objs1, pl_link_2.ifindex)) + == obj_new); + g_assert(!nmp_object_is_visible(obj_new)); + _assert_cache_multi_lookup_contains_link(cache, TRUE, obj_new, FALSE); + _assert_cache_multi_lookup_contains_link(cache, FALSE, obj_new, TRUE); + nmp_object_unref(obj_new); + } + + /* add it in netlink too. */ + objm1 = nmp_object_new(NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2); + objm1->_link.netlink.is_in_netlink = TRUE; + g_assert(nmp_object_is_alive(objm1)); + _nmp_cache_update_netlink(cache, + objm1, + &obj_old, + &obj_new, + udev_device_2 ? NMP_CACHE_OPS_UPDATED : NMP_CACHE_OPS_ADDED); + nmtst_assert_nmp_cache_is_consistent(cache); + if (udev_device_2) { + g_assert(obj_old); + g_assert(!nmp_object_is_visible(obj_old)); + } else + g_assert(!obj_old); + g_assert(nmp_object_equal(objm1, obj_new)); + g_assert(nmp_cache_lookup_obj(cache, objm1) == obj_new); + g_assert(nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&objs1, pl_link_2.ifindex)) + == obj_new); + g_assert(nmp_object_is_visible(obj_new)); + _assert_cache_multi_lookup_contains_link(cache, TRUE, obj_new, TRUE); + _assert_cache_multi_lookup_contains_link(cache, FALSE, obj_new, TRUE); + nmp_object_unref(objm1); + nmp_object_unref(obj_old); + nmp_object_unref(obj_new); + + /* remove again from netlink. */ + objm1 = nmp_object_new(NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_2); + objm1->_link.netlink.is_in_netlink = FALSE; + g_assert(!nmp_object_is_alive(objm1)); + _nmp_cache_update_netlink(cache, + objm1, + &obj_old, + &obj_new, + udev_device_2 ? NMP_CACHE_OPS_UPDATED : NMP_CACHE_OPS_REMOVED); + nmtst_assert_nmp_cache_is_consistent(cache); + if (udev_device_2) + g_assert(obj_new == objm1); + else + g_assert(!obj_new); + g_assert(obj_old); + g_assert(nmp_object_is_alive(obj_old)); + if (udev_device_2) { + g_assert(nmp_cache_lookup_obj(cache, objm1) == obj_new); + g_assert( + nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&objs1, pl_link_2.ifindex)) + == obj_new); + g_assert(!nmp_object_is_visible(obj_new)); + _assert_cache_multi_lookup_contains_link(cache, TRUE, obj_new, FALSE); + _assert_cache_multi_lookup_contains_link(cache, FALSE, obj_new, TRUE); + } else { + g_assert(nmp_cache_lookup_obj(cache, objm1) == NULL); + g_assert( + nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&objs1, pl_link_2.ifindex)) + == NULL); + g_assert(!nmp_object_is_alive(obj_new)); + g_assert(!nmp_object_is_visible(obj_new)); + } + nmp_object_unref(objm1); + nmp_object_unref(obj_old); + nmp_object_unref(obj_new); + + /* now another link only with aspect UDEV. */ + if (udev_device_3) { + /* now add the link only with aspect UDEV. */ + ops_type = + nmp_cache_update_link_udev(cache, pl_link_3.ifindex, udev_device_3, &obj_old, &obj_new); + g_assert_cmpint(ops_type, ==, NMP_CACHE_OPS_ADDED); + nmtst_assert_nmp_cache_is_consistent(cache); + g_assert(NMP_OBJECT_IS_VALID(obj_new)); + g_assert(!obj_old); + g_assert(!nmp_object_is_visible(obj_new)); + g_assert( + nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&objs1, pl_link_3.ifindex)) + == obj_new); + _assert_cache_multi_lookup_contains_link(cache, TRUE, obj_new, FALSE); + _assert_cache_multi_lookup_contains_link(cache, FALSE, obj_new, TRUE); + g_assert_cmpint(obj_new->_link.netlink.is_in_netlink, ==, FALSE); + g_assert_cmpint(obj_new->link.initialized, ==, FALSE); + nmp_object_unref(obj_new); + + /* add it in netlink too. */ + objm1 = nmp_object_new(NMP_OBJECT_TYPE_LINK, (NMPlatformObject *) &pl_link_3); + objm1->_link.netlink.is_in_netlink = TRUE; + g_assert(nmp_object_is_alive(objm1)); + _nmp_cache_update_netlink(cache, objm1, &obj_old, &obj_new, NMP_CACHE_OPS_UPDATED); + nmtst_assert_nmp_cache_is_consistent(cache); + g_assert(obj_old); + g_assert(obj_new == objm1); + g_assert(nmp_object_equal(objm1, obj_new)); + g_assert(!obj_old || !nmp_object_is_visible(obj_old)); + g_assert(nmp_cache_lookup_obj(cache, objm1) == obj_new); + g_assert( + nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&objs1, pl_link_3.ifindex)) + == obj_new); + g_assert(nmp_object_is_visible(obj_new)); + _assert_cache_multi_lookup_contains_link(cache, TRUE, obj_new, TRUE); + _assert_cache_multi_lookup_contains_link(cache, FALSE, obj_new, TRUE); + g_assert_cmpint(obj_new->_link.netlink.is_in_netlink, ==, TRUE); + g_assert_cmpint(obj_new->link.initialized, ==, TRUE); + nmp_object_unref(objm1); + nmp_object_unref(obj_old); + nmp_object_unref(obj_new); + + /* remove UDEV. */ + ops_type = nmp_cache_update_link_udev(cache, pl_link_3.ifindex, NULL, &obj_old, &obj_new); + g_assert_cmpint(ops_type, ==, NMP_CACHE_OPS_UPDATED); + nmtst_assert_nmp_cache_is_consistent(cache); + g_assert(obj_old && nmp_object_is_visible(obj_old)); + g_assert( + nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&objs1, pl_link_3.ifindex)) + == obj_new); + g_assert(nmp_object_is_visible(obj_new)); + _assert_cache_multi_lookup_contains_link(cache, TRUE, obj_new, TRUE); + _assert_cache_multi_lookup_contains_link(cache, FALSE, obj_new, TRUE); + g_assert_cmpint(obj_new->_link.netlink.is_in_netlink, ==, TRUE); + g_assert_cmpint(obj_new->link.initialized, ==, !nmp_cache_use_udev_get(cache)); + nmp_object_unref(obj_new); + nmp_object_unref(obj_old); + } + + nmp_cache_free(cache); } -const char noqueue[] = "noqueue"; +const char noqueue[] = "noqueue"; const char fq_codel[] = "fq_codel"; -const char ingress[] = "ingress"; +const char ingress[] = "ingress"; static const NMPlatformQdisc pl_qdisc_1a = { - .ifindex = 1, - .kind = noqueue, - .addr_family = AF_UNSPEC, - .handle = 0, - .parent = TC_H_ROOT, - .info = 0, + .ifindex = 1, + .kind = noqueue, + .addr_family = AF_UNSPEC, + .handle = 0, + .parent = TC_H_ROOT, + .info = 0, }; static const NMPlatformQdisc pl_qdisc_1b = { - .ifindex = 1, - .kind = fq_codel, - .addr_family = AF_UNSPEC, - .handle = 0, - .parent = TC_H_ROOT, - .info = 0, + .ifindex = 1, + .kind = fq_codel, + .addr_family = AF_UNSPEC, + .handle = 0, + .parent = TC_H_ROOT, + .info = 0, }; static const NMPlatformQdisc pl_qdisc_1c = { - .ifindex = 1, - .kind = ingress, - .addr_family = AF_UNSPEC, - .handle = TC_H_MAKE(TC_H_INGRESS, 0), - .parent = TC_H_INGRESS, - .info = 0, + .ifindex = 1, + .kind = ingress, + .addr_family = AF_UNSPEC, + .handle = TC_H_MAKE(TC_H_INGRESS, 0), + .parent = TC_H_INGRESS, + .info = 0, }; static const NMPlatformQdisc pl_qdisc_2 = { - .ifindex = 2, - .kind = fq_codel, - .addr_family = AF_UNSPEC, - .handle = 0, - .parent = TC_H_ROOT, - .info = 0, + .ifindex = 2, + .kind = fq_codel, + .addr_family = AF_UNSPEC, + .handle = 0, + .parent = TC_H_ROOT, + .info = 0, }; static void -test_cache_qdisc (void) +test_cache_qdisc(void) { - NMPCache *cache; - nm_auto_unref_dedup_multi_index NMDedupMultiIndex *multi_idx = NULL; - NMPLookup lookup; - const NMDedupMultiHeadEntry *head_entry; - nm_auto_nmpobj NMPObject *obj1a = nmp_object_new (NMP_OBJECT_TYPE_QDISC, (NMPlatformObject *) &pl_qdisc_1a); - nm_auto_nmpobj NMPObject *obj1b = nmp_object_new (NMP_OBJECT_TYPE_QDISC, (NMPlatformObject *) &pl_qdisc_1b); - nm_auto_nmpobj NMPObject *obj1c = nmp_object_new (NMP_OBJECT_TYPE_QDISC, (NMPlatformObject *) &pl_qdisc_1c); - nm_auto_nmpobj NMPObject *obj2 = nmp_object_new (NMP_OBJECT_TYPE_QDISC, (NMPlatformObject *) &pl_qdisc_2); - - multi_idx = nm_dedup_multi_index_new (); - cache = nmp_cache_new (multi_idx, nmtst_get_rand_uint32 () % 2); - - g_assert (nmp_cache_lookup_obj (cache, obj1a) == NULL); - - g_assert (nmp_cache_update_netlink (cache, obj1a, FALSE, NULL, NULL) == NMP_CACHE_OPS_ADDED); - g_assert (nmp_cache_lookup_obj (cache, obj1a) == obj1a); - g_assert (nmp_cache_lookup_obj (cache, obj1b) == obj1a); - g_assert (nmp_cache_lookup_obj (cache, obj2) == NULL); - - g_assert (nmp_cache_update_netlink (cache, obj1b, FALSE, NULL, NULL) == NMP_CACHE_OPS_UPDATED); - g_assert (nmp_cache_lookup_obj (cache, obj1a) == obj1b); - g_assert (nmp_cache_lookup_obj (cache, obj1b) == obj1b); - g_assert (nmp_cache_lookup_obj (cache, obj2) == NULL); - - g_assert (nmp_cache_update_netlink (cache, obj1c, FALSE, NULL, NULL) == NMP_CACHE_OPS_ADDED); - g_assert (nmp_cache_lookup_obj (cache, obj1a) == obj1b); - g_assert (nmp_cache_lookup_obj (cache, obj1b) == obj1b); - g_assert (nmp_cache_lookup_obj (cache, obj1c) == obj1c); - g_assert (nmp_cache_lookup_obj (cache, obj2) == NULL); - - g_assert (nmp_cache_update_netlink (cache, obj2, FALSE, NULL, NULL) == NMP_CACHE_OPS_ADDED); - g_assert (nmp_cache_lookup_obj (cache, obj1a) == obj1b); - g_assert (nmp_cache_lookup_obj (cache, obj1b) == obj1b); - g_assert (nmp_cache_lookup_obj (cache, obj2) == obj2); - - head_entry = nmp_cache_lookup (cache, - nmp_lookup_init_object (&lookup, - NMP_OBJECT_TYPE_QDISC, - 1)); - g_assert (head_entry->len == 2); - - nmp_cache_free (cache); + NMPCache * cache; + nm_auto_unref_dedup_multi_index NMDedupMultiIndex *multi_idx = NULL; + NMPLookup lookup; + const NMDedupMultiHeadEntry * head_entry; + nm_auto_nmpobj NMPObject *obj1a = + nmp_object_new(NMP_OBJECT_TYPE_QDISC, (NMPlatformObject *) &pl_qdisc_1a); + nm_auto_nmpobj NMPObject *obj1b = + nmp_object_new(NMP_OBJECT_TYPE_QDISC, (NMPlatformObject *) &pl_qdisc_1b); + nm_auto_nmpobj NMPObject *obj1c = + nmp_object_new(NMP_OBJECT_TYPE_QDISC, (NMPlatformObject *) &pl_qdisc_1c); + nm_auto_nmpobj NMPObject *obj2 = + nmp_object_new(NMP_OBJECT_TYPE_QDISC, (NMPlatformObject *) &pl_qdisc_2); + + multi_idx = nm_dedup_multi_index_new(); + cache = nmp_cache_new(multi_idx, nmtst_get_rand_uint32() % 2); + + g_assert(nmp_cache_lookup_obj(cache, obj1a) == NULL); + + g_assert(nmp_cache_update_netlink(cache, obj1a, FALSE, NULL, NULL) == NMP_CACHE_OPS_ADDED); + g_assert(nmp_cache_lookup_obj(cache, obj1a) == obj1a); + g_assert(nmp_cache_lookup_obj(cache, obj1b) == obj1a); + g_assert(nmp_cache_lookup_obj(cache, obj2) == NULL); + + g_assert(nmp_cache_update_netlink(cache, obj1b, FALSE, NULL, NULL) == NMP_CACHE_OPS_UPDATED); + g_assert(nmp_cache_lookup_obj(cache, obj1a) == obj1b); + g_assert(nmp_cache_lookup_obj(cache, obj1b) == obj1b); + g_assert(nmp_cache_lookup_obj(cache, obj2) == NULL); + + g_assert(nmp_cache_update_netlink(cache, obj1c, FALSE, NULL, NULL) == NMP_CACHE_OPS_ADDED); + g_assert(nmp_cache_lookup_obj(cache, obj1a) == obj1b); + g_assert(nmp_cache_lookup_obj(cache, obj1b) == obj1b); + g_assert(nmp_cache_lookup_obj(cache, obj1c) == obj1c); + g_assert(nmp_cache_lookup_obj(cache, obj2) == NULL); + + g_assert(nmp_cache_update_netlink(cache, obj2, FALSE, NULL, NULL) == NMP_CACHE_OPS_ADDED); + g_assert(nmp_cache_lookup_obj(cache, obj1a) == obj1b); + g_assert(nmp_cache_lookup_obj(cache, obj1b) == obj1b); + g_assert(nmp_cache_lookup_obj(cache, obj2) == obj2); + + head_entry = nmp_cache_lookup(cache, nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_QDISC, 1)); + g_assert(head_entry->len == 2); + + nmp_cache_free(cache); } /*****************************************************************************/ -NMTST_DEFINE (); +NMTST_DEFINE(); int -main (int argc, char **argv) +main(int argc, char **argv) { - int result; - NMUdevClient *udev_client; + int result; + NMUdevClient *udev_client; - nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT"); + nmtst_init_assert_logging(&argc, &argv, "INFO", "DEFAULT"); - udev_client = nm_udev_client_new ((const char *[]) { "net", NULL }, - NULL, NULL); - { - struct udev_enumerate *enumerator; - struct udev_list_entry *devices, *l; + udev_client = nm_udev_client_new((const char *[]){"net", NULL}, NULL, NULL); + { + struct udev_enumerate * enumerator; + struct udev_list_entry *devices, *l; - enumerator = nm_udev_client_enumerate_new (udev_client); + enumerator = nm_udev_client_enumerate_new(udev_client); - /* Demand that the device is initialized (udev rules ran, - * device has a stable name now) in case udev is running - * (not in a container). */ - if (access ("/sys", W_OK) == 0) - udev_enumerate_add_match_is_initialized (enumerator); + /* Demand that the device is initialized (udev rules ran, + * device has a stable name now) in case udev is running + * (not in a container). */ + if (access("/sys", W_OK) == 0) + udev_enumerate_add_match_is_initialized(enumerator); - udev_enumerate_scan_devices (enumerator); + udev_enumerate_scan_devices(enumerator); - devices = udev_enumerate_get_list_entry (enumerator); - for (l = devices; l != NULL; l = udev_list_entry_get_next (l)) { - struct udev_device *udevice; + devices = udev_enumerate_get_list_entry(enumerator); + for (l = devices; l != NULL; l = udev_list_entry_get_next(l)) { + struct udev_device *udevice; - udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerator), - udev_list_entry_get_name (l)); - if (udevice == NULL) - continue; + udevice = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerator), + udev_list_entry_get_name(l)); + if (udevice == NULL) + continue; - global.udev_devices = g_list_prepend (global.udev_devices, udevice); - } - global.udev_devices = g_list_reverse (global.udev_devices); + global.udev_devices = g_list_prepend(global.udev_devices, udevice); + } + global.udev_devices = g_list_reverse(global.udev_devices); - udev_enumerate_unref (enumerator); - } + udev_enumerate_unref(enumerator); + } - g_test_add_func ("/nmp-object/obj-base", test_obj_base); - g_test_add_func ("/nmp-object/cache_link", test_cache_link); - g_test_add_func ("/nmp-object/cache_qdisc", test_cache_qdisc); + g_test_add_func("/nmp-object/obj-base", test_obj_base); + g_test_add_func("/nmp-object/cache_link", test_cache_link); + g_test_add_func("/nmp-object/cache_qdisc", test_cache_qdisc); - result = g_test_run (); + result = g_test_run(); - while (global.udev_devices) { - udev_device_unref (global.udev_devices->data); - global.udev_devices = g_list_delete_link (global.udev_devices, global.udev_devices); - } + while (global.udev_devices) { + udev_device_unref(global.udev_devices->data); + global.udev_devices = g_list_delete_link(global.udev_devices, global.udev_devices); + } - nm_udev_client_unref (udev_client); + nm_udev_client_unref(udev_client); - return result; + return result; } - diff --git a/src/platform/tests/test-platform-general.c b/src/platform/tests/test-platform-general.c index 255210f2..f98f84c9 100644 --- a/src/platform/tests/test-platform-general.c +++ b/src/platform/tests/test-platform-general.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2015 - 2018 Red Hat, Inc. */ @@ -14,64 +14,730 @@ /*****************************************************************************/ +G_STATIC_ASSERT(G_STRUCT_OFFSET(NMPlatformIPAddress, address_ptr) + == G_STRUCT_OFFSET(NMPlatformIP4Address, address)); +G_STATIC_ASSERT(G_STRUCT_OFFSET(NMPlatformIPAddress, address_ptr) + == G_STRUCT_OFFSET(NMPlatformIP6Address, address)); + +G_STATIC_ASSERT(G_STRUCT_OFFSET(NMPlatformIPRoute, network_ptr) + == G_STRUCT_OFFSET(NMPlatformIP4Route, network)); +G_STATIC_ASSERT(G_STRUCT_OFFSET(NMPlatformIPRoute, network_ptr) + == G_STRUCT_OFFSET(NMPlatformIP6Route, network)); + +/*****************************************************************************/ + static void -test_init_linux_platform (void) +test_init_linux_platform(void) { - gs_unref_object NMPlatform *platform = NULL; + gs_unref_object NMPlatform *platform = NULL; - platform = nm_linux_platform_new (TRUE, NM_PLATFORM_NETNS_SUPPORT_DEFAULT); + platform = nm_linux_platform_new(TRUE, NM_PLATFORM_NETNS_SUPPORT_DEFAULT); } /*****************************************************************************/ static void -test_link_get_all (void) +test_link_get_all(void) { - gs_unref_object NMPlatform *platform = NULL; - gs_unref_ptrarray GPtrArray *links = NULL; + gs_unref_object NMPlatform *platform = NULL; + gs_unref_ptrarray GPtrArray *links = NULL; - platform = nm_linux_platform_new (TRUE, NM_PLATFORM_NETNS_SUPPORT_DEFAULT); + platform = nm_linux_platform_new(TRUE, NM_PLATFORM_NETNS_SUPPORT_DEFAULT); - links = nm_platform_link_get_all (platform, TRUE); + links = nm_platform_link_get_all(platform, TRUE); } /*****************************************************************************/ static void -test_nm_platform_link_flags2str (void) +test_nm_platform_link_flags2str(void) { - int i; - - for (i = 0; i < 100; i++) { - char buf[NM_PLATFORM_LINK_FLAGS2STR_MAX_LEN + 100]; - const char *s; - const guint flags = ((i == 0) ? ~0u : nmtst_get_rand_uint ()); - gsize l; - - s = nm_platform_link_flags2str (flags, buf, sizeof (buf)); - g_assert (s); - - l = strlen (s); - if (l > NM_PLATFORM_LINK_FLAGS2STR_MAX_LEN) - g_error ("nm_platform_link_flags2str(%x) produced a longer output than %zu chars: \"%s\"", flags, NM_PLATFORM_LINK_FLAGS2STR_MAX_LEN, s); - if ( flags == ~0u - && l != NM_PLATFORM_LINK_FLAGS2STR_MAX_LEN) - g_error ("nm_platform_link_flags2str(%x) is expected to produce %zu chars, but produced %zu: \"%s\"", flags, NM_PLATFORM_LINK_FLAGS2STR_MAX_LEN, l, s); - } + int i; + + for (i = 0; i < 100; i++) { + char buf[NM_PLATFORM_LINK_FLAGS2STR_MAX_LEN + 100]; + const char *s; + const guint flags = ((i == 0) ? ~0u : nmtst_get_rand_uint()); + gsize l; + + s = nm_platform_link_flags2str(flags, buf, sizeof(buf)); + g_assert(s); + + l = strlen(s); + if (l > NM_PLATFORM_LINK_FLAGS2STR_MAX_LEN) + g_error( + "nm_platform_link_flags2str(%x) produced a longer output than %zu chars: \"%s\"", + flags, + NM_PLATFORM_LINK_FLAGS2STR_MAX_LEN, + s); + if (flags == ~0u && l != NM_PLATFORM_LINK_FLAGS2STR_MAX_LEN) + g_error("nm_platform_link_flags2str(%x) is expected to produce %zu chars, but produced " + "%zu: \"%s\"", + flags, + NM_PLATFORM_LINK_FLAGS2STR_MAX_LEN, + l, + s); + } +} + +/*****************************************************************************/ + +static int +_address_pretty_sort_cmp(gconstpointer a, gconstpointer b, gpointer test_data) +{ + const int TEST_DATA_I = GPOINTER_TO_INT(test_data); + const int addr_family = (TEST_DATA_I == 0 ? AF_INET : AF_INET6); + const int IPV6_PREFER_TEMP = (TEST_DATA_I == 2); + const NMPlatformIPXAddress *a_a = a; + const NMPlatformIPXAddress *a_b = b; + + if (addr_family == AF_INET) + return nm_platform_ip4_address_pretty_sort_cmp(&a_a->a4, &a_b->a4); + + return nm_platform_ip6_address_pretty_sort_cmp(&a_a->a6, &a_b->a6, IPV6_PREFER_TEMP); +} + +static void +test_platform_ip_address_pretty_sort_cmp(gconstpointer test_data) +{ + static const char *const EXPECTED_BUFFER[3] = { + [0] = ("5b1aea34648cabfec7c3523f76cf1ce34ca17a9a32f3f0f218424e48836dd1cb504e03d53e1124c5" + "0065aeb2e6fbf952902383028e3b47f280f062ea1a7e0b7be218d067530e1b0487b8c3b99f2b8a1a" + "8982c42f0000003437c5156e072b2f2f0037c9cfe07c34ddb3980deb14ab7b5af84a034703000000" + "883b0f3fd6ed84d6c959e553b887edcd01c2f5d200000043b809d259e499db7d00f1853bdcb0e4bc" + "0e2b00b667b7b16d8d1e69c803000000b973972c17a47631c169f11ff9119c400368b6630000007a" + "034f43340d01683c0045097aea4a849f060ddf57b24a5be9636360d603000000ad7c499dd538d345" + "74c038404923e75d0209e2fc0000004acc807cdce682f80f00315c45ef817264c89a736ed55ed637" + "b96c200203000000faf1809becd2506315a6da29b2e94d3a031fe0e900000083a36035fb6297dfa7" + "00686b5efd0d53bb6215de4bb6f6f3d031a79028030000008bb836c0a25ea71f5daaed4d99eb2ebe" + "033c432f000000bf4ccf30d3aaaf02a4005d7308b67f91bf9d82c856ba942455e8d07c8403000000" + "f2abb982b001ec16901f55f960c55c22022099a80000002b4d4647f53b1921af0088e3759a08e7a5" + "6663861eea1bf42c12ea3b9503000000fb95e8332fdfff658483a2d039a7bf1402d3481e00000060" + "e89f7abdb682380a00eae374835b4a49a2b980b6aba92da6409969aa03000000e00473755d31e5b2" + "de252167c1c91b3a02ba0c700000007740318db913a353ed006efc068829c0e66ad0143a0554efb4" + "40e55b8b03000000c0cfb2b4386bec092fa5757ecde9348b00c12ebd000000ab667224dae775e5cc" + "0041aca2ff0f576767d3648102b61886d149f07403000000153ece68ade15cec25a59273e7519f34" + "c4458d70000000f3819aa46fbe1439340033ae6dec0fb124f264af67eed7c9a8ecc8fb1103000000" + "fcebbaeb0c56535923f14874042a8aff021f8e5ec3cc13cc36bbe3c9bb0ec36f00e007bb64a2827b" + "7cdd38d0314c178e5a06c40b03000000ab90135fa636af4464d210a256be75e0029c44770000004b" + "2e69220d6c0fc09c25d6534c809829af4a9df58dbfef186d416f3a1e030000002c932e655203d82a" + "3c84c4eb274ed18603780281000000f2235376239daeaacb3cae864b437baaae91921681c2162b9b" + "69e66142030000004fda8a3e0b841cf76391dd68269b53ec0244a831000000b78c54dda9ac3bb1b1" + "d43e6505621b9a7f0422ae3fc8979ee0416f95e70300000057d6249b652ba98c7dc7f17f666969e4" + "023baf7a000000ee0b06fa9e988f80f0de6dc8dfcf2a3ad3bbcc0fa3b314f695111d891d03000000" + "cd897619f51f44e644d7cf1d06b2b1150082549e62c12fba5b1cdec48d10bbb13b8313d8cd2a24d3" + "4fc812bd2f8a59d90fcc00ac030000005292cd32dc096cd5d8a4c5cf3351ee1c03c2056c00000051" + "bbce426cfa4b861cc78592be7b14e7ba9c15acb881ae55f0e5fe7d360300000066a3ae3939762df3" + "3a2d55060c78d55100b110fd00000041b9aca07b6e4925dd27943a272c171ed15abbbe1cd911db7b" + "86ed271803000000a5edc511c1507a141e0f515638c7ba31027609450000003357ae79989870ccec" + "3def0ad92749e016663fe6ee0228c1da82d1595603000000348352d715cf9d411ea012e5307294b6" + "0146dac4000000075efee38dd16f8ee4ccd2f50c30706cae3fdcc2f0ee3d5e26bb20413203000000" + "862573c2303dd1d65c7b2cffeca6d1adaccae11f0000000f855ebf3b772eb2b1c896c9a7304f6645" + "0a5f6abd850b06e3b10123e6030000001dff045298cfee0636674cdefb57b9ae54cfe8f400000038" + "1ba2c4396de60f032bc7f34de2959871c0d4c0d4eb720c4ab550c5db03000000f32f4af595d785d5" + "c1b5aad487c192f08bd7a09b00000043288cd9bf66ec305a225a0c71b2ce78bb16104c8eaf18c565" + "b16c7376030000005219061ab4c5c79489b2cc6a883c146972decb8b000000f5e6d66df46ea13910" + "7754dee62c36d2fc70ccc567df7a49b8585287dc03000000cfb18b2b2cb749e2e03e544d0eb4f73e" + "75039fcf251b32fc79685b05ddd3aa9ba511d2e40edb4d758fb554158ae5c7c0beb42b3403000000" + "895d5f24037d233302ad3b82d639272e0246eadfbd2146bf8cfdb205f90e54b58a6ee136a779f37c" + "30d2c5053c40ecaec38b6b8e03000000bea73223e59bf0193432e9fa7a899f2d8ec7e4b89bf5a5d0" + "6776e66a9d80ab132e1ac921eb76adbb229df32e561fa80a0fc4676703000000a23eb66e720da9e0" + "7ac998b5690807d50217369ee1af4ca5a6a95581af5fd7ceacdca10f47d7b351a36b178aabc78a4a" + "1a0dd8c003000000e2815a1a37a52bddd1c2f1018b587eed03bb58f0e9201f17bd99fcf72909ac9e" + "7a55299e9bb4fd53bc7417940fcffe3f81cafd6302000000d6732578acd14320aefd4503189f7630" + "038e501c0000002b9f3c39f24b0572b100745cb25851429b3bbfb50168dfd04eb62f22ca02000000" + "891715df7fc6a902edae579e2e10c7f7022ba0340436242cbeb0248cee3fbc160032d4f28aa28c08" + "f80dd50c6712dfb4abba4a32020000008ffe423d01883918039249f398f9b37ea091465100000064" + "3722d9b707c0d8a400b7c8307f06b4b29088f20d9ac676d5e4bafc4e02000000fde69eec3af2e6d0" + "bd68ab722af14548b29572e504265f6c72923e22594f3f790008ed2e2ebb0771db46a54cadb245ea" + "8c3b371502000000710c030690f5f18ea125dbf7d7e93bd6011fa56dfdcfc1155f236c8b9c79a620" + "00660bbf024b03ff0a8e27c405e64244e36f90d402000000fd41fe47684b370b6ec6584d64496089" + "570968ead4d1ae91c819bb068196d59900de3246e43f5e7945aaf95e2ffa3a119c64ed0402000000" + "a660ac824b7fae389861419c50da49bf02092583000000259f9f0251becc987907879cca68fec7bb" + "bb5f8edf248b4995d184e82002000000a19cdf6dd1c173f6078a806d329c9b0000bfc972000000f5" + "b2cd3dbddc74e26de958e48d2ab8b0313e7f8933e315130f641e447502000000b9b68c08a5e4351e" + "a349e1ccf662e058b879a45100000045fcb6a035339d504c9726d80d9c2d89df765b4d9a130257dc" + "d1e1b34902000000bcd7be07d78e6222e45aaf61814f703b40125e6b000000cbaaa37b861e6d46da" + "fe7d6ec4ac1ea051010911915ddb05f2c43bd794010000005bfe47c6f53a54e01b0c1d89414d94d0" + "032d2ec50000000103781b0f294a2b7300421398f4de67e9cee64b38b56e03e01539ce4101000000" + "18238487a417f3da01d99dae5f19009601582cab0000005b2363d13edc5aa115005eb914d8fbe9a4" + "fdb3d117d76b0de5bd82e9ea010000003d1b91caae8cb60b49ba9be338d856a40267c3d400000064" + "9da90bd2fff2f2560046870bd7d5f14870c6d18d6242b356b9ef1b2101000000f90adac616a31dc2" + "e46a234558817151008fc9c900000073e64b0bd761fdf274005dca8ce1bd1871ae17bb4515856092" + "b4d9e89b010000006855676c277cf1bd017c9148da5892bb0351c3a70000009f3391ce7d3fd48469" + "005f0c233dbdd2a97835df1f1782dee86c1de913010000003ee1d76fc1ea76e98c9dfc78997ab53e" + "00c21963f5b4cb2454830c68e44ea74b002b83f9b3bee14d861a4c9eeecc89f65408c1b701000000" + "d9e1825fa638e1af284a024b7f9e85ff00e050a2000000276e08cb887464b93400c3127c750fabdd" + "69121aec129cdc690d58fbcc01000000d0d44ff1e51c35157666c05348e6f50700a8e89800000012" + "b900b2061d0c334b009f2dd1cdf64b0f9a60e0e289f08db3fde6b0250100000039dd8f88152a5845" + "4d9ca9d20f45dfa702e78604000000fbcd7db68b9ae586da00b4070c50320427c4dd3d031e33f22c" + "210aeb09010000007000b96d06992b6a58acd3995b9663d20248f333ef467092818aa77d6732b678" + "00844ef5a943825fcd743f59bd14c89b955e1a13010000007acbce3e3bcdf3824f1b134847ff26ba" + "009a774900000017ec852d59f3d17232edd86ad6c3103a68843a9aef34983882d3d3878501000000" + "5e0dfe491d1ba96742c7b5e02b2271220188b02a06d0dc5504b0595daf37deb499996bfb667f072d" + "ec1e5d9cdc8a11f4409bcfb30100000099d90a8543961b2ccd47724a3c460ba80383f4c500000063" + "eafb1ac4c0982b283aa9986700b2a2b3ed257b8b0489f48f053ec8ca0100000027335a25a364d101" + "5ffac03089f4553902b01784000000d7b83579b8da27345a72437f9b6245de39ec9e71ee4b951507" + "f121014a01000000efc67bce716c856e3973dc42a1003be94f89d8ee0000009b5d5bbe6c10085f3d" + "6176f78a19bb8df1804c122fce5078c156e8f3fe010000000ea8042602a1f8e6f5657f3f9e3eb807" + "cbad7645000000b8df6f628a70456d79f25d5895fb57fa60d9279fb2b8fcbac65ad47b8a01000000" + "da40d88d40a6d75bc404156225b7eedefc2b44574b15e2ae496ad01bf007eacb0a28aec868282510" + "b60291ea6480e356925b568a0000000087bb24e5264fd3ebe9cf9f6df9615189018ee815000000a7" + "5c9555876b6a3f13002b6cb8360feaac1d5c302df59dd32a7a859db500000000362956cd46646a0e" + "222160e5f769bb290366ed370000005b6a813387e99bb834009da86c64fefab2548759d313a5b92d" + "8e47935e0000000034f0386a253c21d94064f6b021281e230094ae20000000d71fd050bf8d85055b" + "00e3756ccdb3455c60ca7b11c66af76e594f24a100000000e143fd52599364e13468f80fd514573f" + "b572671c0000006932d1d5f5d0ce2cf6007a70ba5193a162bc92ec1b11d9172c857ae81200000000" + "3e29535402e9b690c628d048eacce745ea213cb1000000b632ef3be6070dafa200187470e9da5570" + "9427c226d324d9a08487fd0d00000000b7a350f9fc1519defa7db4532545666937c22a3b000000dc" + "c405cbee5016c25200d8901d7a0165fe20744edb6ba04f14a4c73cf500000000a4bab14874afdf54" + "e6aae816430607ca0675e09818e9bbec5918c59068baf76a008940f6fc3bbdc7f6090f756aae660b" + "6e4c699300000000d9c1e67743efb54e54270e46042e911803894e38000000376feecb80ac245409" + "c0becc271d9c2f67179bff0644399ae7e3c9472e00000000c5cfd9f2343b21362c19a0921dce2f83" + "00defa45000000270b9977e166bee737fe73670c439a644c323b59b4cd20eb7dabea74f700000000" + "f6989d2d6a909e986ff7add5df2c93e05459507b0000000f466554d2ae4d52a8c67b2e48b47003c8" + "1785d3ffdbd9a617df6b3542000000004c5cf8107ba282f4f983821918f93e742d08f0550000006f" + "2292362e5d68265d9f98c82d9b7a559be3acf4fc36fa6b5159747cf200000000ab2dadc5a39411fd" + "4ff1116d478987316a553fc2000000cfc6ebe434a7ae8ff040483e310819e3b10db116431ec6f769" + "438a72e1000000002495a609675344f7e2e3a5ebaec3c85f0a1742f70abe95c50345132a61eda239" + "d9d083c3bf085387046ef8a36f0e9e696b382ab0000000009a6ce5d906837dbca6a5ee19d6f63fe9" + "03dd01f7246f13b2050424a2b3a45ef7a029c896b4132bd895072cfeffe9d6815997069500000000" + "0d3c723b91adb0da7c4aa7e7eb5a15bc03015fb98b841fd84cc43c510385b9a4c2aac1d67a909b29" + "7c703915312e9c3cae02dfa000000000dd603bd35e7fa0f02f2f3313d8469d09a92409c0b7f0318a" + "575a4f8e061db3dd7fde25654a4059d565dbc8a91e3b4457b077ddad3108be69f9b97d05c917ad6b" + "10e693bb6e26f2ba90c8e909a9fe20e5c7a4c656482a9b0d00625009a40aeb62a42b6a62548e3c38" + "cd3c72f203000000ca82ac5180101be4f85cef468ea086ea01aafdc3a9fe1ec787bc45db7c52a52d" + "00bd39a44e8e8bc17c01ac63eca0c1cf5ff7f03a03000000c9a89192c1c8be55281a59d1fd338f35" + "0075f8cea9fec34573654ea6624f138ef9531cd9367a02e4d241989477a363d53b02239e03000000" + "24438387def0f4c6544e4b275d9b714600f810d2a9fec17647176b7c07d856e3b883efebc09dd9d6" + "1966b7ae7412041d57393c6f03000000182c0287822a272bec4501a1e27acfee018588ffa9fe6cae" + "426de59560fad65d67c624f285d7174177a47579dda0b6eaa9a84c820300000070b1646d8026e9f1" + "704f1b16286ba2da017ef082a9feed33ef60a8b540b26f66761d1f13badfad0fe8fa8f3c1aad2a82" + "fa40546c03000000df2d7c2790d3119a051bb2ee8192ac0cfa3abc1ea9fe3e7d75a2f42b50c6a363" + "40132378b95c59313bacba64dbe996206e6904f50200000047150b9b14010469823acb72bb89182f" + "00112196a9feb9153b36bc60be5b534e006527f67485ab35aca0c7ee419733853cf09e8b02000000" + "e79c10acfce165e332a62384ec04e5ba009185ada9fe0070a36dd51323b2c54200154d12f86c260a" + "9edfa7a74c1c83c1050f63f802000000443cacf59c6379a44b7892f487afa98c0221c19ca9fe942f" + "460bcea75481f25e007d0de9a7afe283bd2f22ead05ff72006c83bc0020000004bdade862c224f6f" + "36506ebd455e679c00369bb8a9fecec3f8c8fa6867a982be8a934f852cc3d4d82bc0ec7303f99f8f" + "def85b7502000000a0bef8675b29a197b7b3cceaf5f1bb120335256aa9fe6e5d58099ffc4a503a71" + "2350acbd48411f0dc15d2f0f49dad345d966279502000000e06302aba042aaa218dc091e9aa1477f" + "6fdc9830a9fec95829a8838314dff34d24c332219a1b163a732d803e0e2f4f916d06412601000000" + "98c39e7cc282208fefc57ff447036b9501adcb22a9fe793f797a3c7dadd1c86e009d0c90bc512e13" + "7dcef5e4a27985bd5cfd5ce601000000152f2b70eaef7443e0f79ab6902dde5301b3ec71a9fe9f25" + "4ac95883195580410062ed564153e17478f8c3344d89c0bbfaa100fd01000000be184524a6bdc878" + "9cf851782d895bcc03a98489a9fe8c1287e6f7bb020ffdb00012098610e52bb2a16a4008aefd545b" + "0d80684e01000000ba8110fb9733cc24904f288262e6ea77032fa5f8a9feeefa701d120523bd98f2" + "00098b43cd68be6e3f81268193fd637e9037d7a701000000c47cf0f551e96770a754ac19ef820fe0" + "0031f2d3a9fe049150b8d10ab700cc3a7cf51be0403b654ba2f56808092069af5f5b481b01000000" + "68cb3bc873b04d937a6ed8f7bc51e54066fed098a9fe048a92d3adc69a84eb47622400207799416a" + "f1f0a086fbd7e2f7dea0077a00000000c386e9c6e6a2cbfa10ee58bdc75183600085d627a9feb1cb" + "e491cbbbf9443fd6007eb3c5bf64b671d6f18dbf463f9b83f512dc1c00000000fbab244735d67c61" + "283031667b2d74a102e0b1b1a9fe2aa590a2312e17f1a35900459582f4ef43c780908872746e39ef" + "a9a89f8700000000fcdf6d9be94030b34774d1d7dddedd9802f0f627a9fe965a87041331b2834bcf" + "00b4e3ce848518c4e3f6cbf25e5e1b992231bb0200000000173c333cd03bc905b7b899afeb760e3f" + "024a2efca9fe96b89b1bc8f415bd4e77be46bae5a1b3cae76665a268abfe8a41a84e27c100000000" + "cb29efdf672d2fa57fc85ebbe276c5660364192da9fee7af5eb888e9eb37bb046686943b101e1f55" + "3215abf8fbdf17c3677e5a3a00000000608df061d45d864d09f4ecf17625f82d03c74828a9fe1e37" + "1051852c972ea7954079884af257b044fd13a6826a4c619f3d136cac000000009402a4c216772167" + "3f2b02b3256ead1f03ea9bc1a9fefca162fb81e733cff620ca7feefe1933631e8e69f6d9d6962d2c"), + [1] = ("54270e46020000006a894e387625da376feecb80ac245409c0becc271d9c2f67179bff0644399ae7" + "9c64ed0432d599eaa660ac824b7fae389861419c7a899f2d010000009bf5a5d06776e66a9d80ab13" + "2e1ac921eb76adbb229df32e561fa80a40e55b8b1dd92e18c0cfb2b4386bec092fa5757ecde9348b" + "c4e1966800000000b3121cd5ef51e696c816290dbaee0e7726d082e1530ff5397c9125f59577d71c" + "4b258a005116d11354edff62ceaa458fc75a91c425a5927300000000c4458d70911714f1819aa46f" + "be143934c933ae6dec0fb124f264af67eed7c9a8c38b6b8ee2614344bea73223e59bf0193432e9fa" + "4cc43c5103000000c2aac1d67a909b297c703915312e9c3c5a06c40b20ea99d5ab90135fa636af44" + "64d210a256be75e0509c4477d19ac64b2e69220d12ea3b9501000000fb95e8332fdfff658483a2d0" + "39a7bf148ed3481e0bccc460e89f7abdb682380a62eae374835b4a49a2b980b6aba92da6409969aa" + "288cd9bf00000000225a0c71b2ce78bb16104c8eaf18c565ecc8fb112087b97cfcebbaeb0c565359" + "23f14874042a8aff1d1f8e5ec3cc13cc36bbe3c9bb0ec36f0000000064a2827b7cdd38d0314c178e" + "925b568ae56bc4e9fefb24e5264fd3ebe9cf9f6df9615189f78ee815b2781ea55c9555876b6a3f13" + "02e9b69000000000eacce745ea213cb1a84035b632ef3be6070dafa2fed87470e9da55709427c226" + "d324d9a086ed27184b443181a5edc511c1507a142fea9bc10300000062fb81e733cff620ca7feefe" + "1933631e8e69f6d9fed62d2c6e6904f57239c09c47150b9b14010469823acb72bb89182f93112196" + "9985d62700000000e491cbbbf9443fd6a77eb3c5bf64b671d6f18dbffeff9b8306c83bc026977911" + "4bdade862c224f6f36506ebd455e679cef369bb8d514573f03000000f6932f6932d1d5f5d0ce2cf6" + "bf7a70ba5193a162fe92ec1b11d9172cf84a03478b82cdd8883b0f3fd6ed84d6c959e553b887edcd" + "6297dfa700000000fd0d53bb6215de4bb6f6f3d031a790287e45e9c1feb836c0a25ea71f5daaed4d" + "99eb2ebebe3c432fec7d3abc4ccf30d3aaaf02a41e0f515601000000f57609453df7803357ae7998" + "9870ccec3def0ad9000000000000000000000000000000019f05a16768cb3bc873b04d937a6ed8f7" + "ae8cb60b0300000038d856a40c67c3d4afa9c8649da90bd2fff2f256000000000000000000000000" + "00000001955e1a13d1111b067acbce3e3bcdf38200154d12010000009edfa7a74c1c83c18e47935e" + "8354846e34f0386a00000000000000000000000000000001ac26c7d41fd050bf8d85055bcfe3756c" + "a2f56808092069affaa100fdfdd68d34be184524a6bdc8789cf85178000000000000000000000000" + "00000000020ffdb0e612098610e52bb2a16a40086f0e9e6903000000ec2e2924348352d715cf9d41" + "1ea012e5307294b600000000000000000000000000000000ccd2f50c30706cae3fdcc2f0ee3d5e26" + "81ae55f0030000000aa20624fbab244735d67c61283031667b2d74a1000000000000000000000000" + "0000000000459582f4ef43c780908872746e39efaefd545b020000007ced4f8b362956cd46646a0e" + "222160e5f769bb2900000000000000000000000000000000a19da86c64fefab2548759d313a5b92d" + "f05d7308020000009d82c856ba942455050f63f8282f3464443cacf5000000000000000000000000" + "0000000069d9942f460bcea75481f25e307d0de96e91b91501000000be5b534e0a6527f67485ab35" + "aca0c7ee4197338500000000000000000000000000000000aefd4503189f7630248e501c9052c22b" + "5d68265d010000009b7a559be3acf4fc36fa6b513cf09e8b99289462000000000000000000000000" + "00000000b49185ad9b7d0070a36dd51323b2c542e5fe7d360100000066a3ae3939762df33a2d5506" + "0c78d551cbb110fd000000000000000000000000000000002c171ed15abbbe1cd911db7b56e8f3fe" + "9a6ce5d900000000a6a5ee19d6f63fe9cbdd01f7246f13b2050424a2000000000000000000000000" + "00000000ffe9d6812231bb02f922259b173c333cbae87d60000000005d31e5b2de252167c1c91b3a" + "36ba0c700ee78477000000000000000000000000000000006ad0143a0554efb46b382ab0404cdf02" + "7c52a52d030000004e8e8bc17c01ac63eca0c1cfbb204132fb7213e4000000000000000000000000" + "00000000accae11f8045a80f855ebf3b772eb2b1d03bc90503000000eb760e3f004a2efc8ffc96b8" + "9b1bc8f415bd4e7700000000000000000000000000000000d149f074a378b881153ece68ade15cec" + "7666c05303000000ffa8e89871fb9510b900b2061d0c334b819f2dd1000000000000000000000000" + "00000000095a3230fde69eec3af2e6d0bd68ab7210613fc90200000016a31dc2e46a234558817151" + "b38fc9c909cf8d7100000000000000000000000000000000ae17bb4515856092b4d9e89b676761b2" + "57d6249b020000007dc7f17f666969e45c3baf7a119a65ee0b06fa9e000000000000000000000000" + "00000000b314f695bd82e9ea8891ed0a3d1b91cab56e03e0010000002f70249eefc67bce716c856e" + "3973dc42a1003be9000000000000000000000000000000006176f78a19bb8df1804c122fce5078c1" + "eecc89f601000000d635edea8ffe423d01883918039249f398f9b37e000000000000000000000000" + "000000001fb7c8307f06b4b29088f20d9ac676d5f90e54b501000000a779f37c30d2c5053c40ecae" + "210aeb0934cb2a2400000000000000000000000000000000df48f333ef467092818aa77d6732b678" + "bcd7be0700000000e45aaf61814f703b40125e6baf4648cbaaa37b86000000000000000000000000" + "000000005ddb05f2a84e27c18a06e2c9cb29efdf50da49bf00000000d94beb259f9f0251becc9879" + "07879cca68fec7bb000000000000000000000000000000009402a4c2167721673f2b02b3256ead1f" + "a349e1cc00000000b879a45176740744fcb6a035339d504c9726d80d000000000000000000000000" + "000000009518862bc9a89192c1c8be55281a59d1ebfdcec30000000067a982be8a934f852cc3d4d8" + "2bc0ec7303f99f8f00000000000000000000000000000000901f55f960c55c22f32099a8020bea2a" + "5b1aea3401000000c7c3523f76cf1ce34ca17a9a32f3f0f218424e48000000000000000000000000" + "00000002e6fbf952902383028e3b47f2111d891d536c75bb01000000720da9e07ac998b5690807d5" + "2617369ee1af4ca500000000000000000000ffff47d7b351a36b178aabc78a4a0d80684ee5dbf45b" + "17a4763102000000f9119c40b468b66331bca67a034f43340d01683c00000000000000000000ffff" + "b24a5be9b10123e6e4f15ecd1dff045298cfee069c88b02a0300000004b0595daf37deb499996bfb" + "667f072dec1e5d9cdc8a11f4409bcfb3c167090e99d90a8543961b2ccd47724a3c460ba85183f4c5" + "a7afe28302000000d05ff720b16c73761a3fcb675219061ab4c5c79489b2cc6a883c146972decb8b" + "5adac8f5e6d66df46ea139107754dee62c36d2fcc7a4c65601000000cd625009a40aeb62a42b6a62" + "548e3c38b96c20022753c5fbfaf1809becd2506315a6da29b2e94d3ab51fe0e9af98b180a36035fb" + "e36f90d401000000fd41fe47684b370b6ec6584d64496089570968ead4d1ae91c819bb068196d599" + "efde3246e43f5e7945aaf95e2ffa3a11b9ef1b21cdb3455c00000000c66af76e80f062ea1a7e0b7b" + "e218d067530e1b0487b8c3b99f2b8a1a8982c42f53700a3437c5156e072b2f2fb337c9cfe07c34dd" + "c896c9a7000000000a5f6abd850b06e3d9662795ce2cc1cee06302aba042aaa218dc091e9aa1477f" + "6fdc9830d7fbc95829a8838314dff34d24c332214d4647f5000000000f88e3759a08e7a56663861e" + "ea1bf42ccd3c72f2ad063857ca82ac5180101be4f85cef468ea086ea9aaafdc388811ec787bc45db" + "7625ca4a00000000e682f80f94315c45ef817264c89a736ed55ed637b077ddad3108be69f9b97d05" + "c917ad6b10e693bb6e26f2ba90c8e909e85e20e5b0916e5d030000004a503a712350acbd48411f0d" + "c15d2f0f49dad345599706954d2471f00d3c723b91adb0da7c4aa7e7eb5a15bcde015fb98b841fd8" + "ba8110fb03000000904f288262e6ea77a22fa5f863eaeefa701d120523bd98f29b098b43cd68be6e" + "3f81268193fd637e585287dc6ca972a2cfb18b2b3cae864b0200000091921681c2162b9bfa40546c" + "db544e44df2d7c2790d3119a051bb2ee8192ac0cfa3abc1ea0ab3e7d75a2f42b50c6a36340132378" + "8c3b371502000000710c030690f5f18ea125dbf7d7e93bd65c1fa56dfdcfc1155f236c8b9c79a620" + "5f660bbf024b03ff0a8e27c405e6424457393c6fdac12ebd01000000667224dae775e5ccd141aca2" + "ff0f576767d3648102b61886b62f22ca33478e1f891715df7fc6a902edae579e2e10c7f7a22ba034" + "abf85f0c0100000008d33a2ea67776d7f88d69c8c7e3b2d3c93ef054e93f8120abb42316c533d9c9" + "4d88189c471a1ff2f0ce3ff66e782110125ae2eddaae7d6300000000c0982b283aa9986700b2a2b3" + "ed257b8b0489f48f053ec8cac72105b327335a25a364d1015ffac03089f45539e1b0178462156cd6" + "6855676c00000000017c9148da5892bb4951c3a7ed55689d3391ce7d3fd48469845f0c233dbdd2a9" + "7835df1f1782dee88487fd0db5971b46b7a350f998c39e7c00000000efc57ff447036b9551adcb22" + "fd50793f797a3c7dadd1c86e759d0c90bc512e137dcef5e4a27985bd8d1e69c83dc21056b973972c" + "bc51e540030000006c3d048a92d3adc69a84eb47622400207799416afef0a086fbd7e2f7dea0077a" + "e9c0c0d9c386e9c6e6a2cbfa10ee58bdc75183600422ae3f03000000c43bd794c697895e5bfe47c6" + "f53a54e01b0c1d89fecd94d0e02d2ec587fc330003781b0f294a2b73c4421398f4de67e9cee64b38" + "69121aec010000000fcc00ac2daa755e5292cd32dc096cd5d8a4c5cffe91ee1cfcc2056cc1ff8e51" + "bbce426cfa4b861cc78592be7b14e7ba9c15acb836674cde0200000054cfe8f42bf0e9381ba2c439" + "6de60f032bc7f34dfe959871c0d4c0d4eb720c4ae3c9472e5f2da5d9c5cfd9f2343b21362c19a092" + "b2cd3dbd01000000e958e48d2ab8b0313e7f8933e315130fa9a84c82feb83f6e70b1646d8026e9f1" + "704f1b16286ba2dabc7ef0820c91ed33ef60a8b5bcfe97e1000000007ad742d3d7320a4f880cf47f" + "5dd0cf69cb22840ffeb3fe7749509cb6752b2cee30b7e7736a0afc9879ea40e69710fc9f6e8e99cd" + "1dce2f83020000003a3efc240b9977e166bee737fe73670c439a644c000000000000000000000000" + "000000015e0dfe491d1ba96742c7b5e02b227122cf844ef501000000cd743f59bd14c89b5cfd5ce6" + "e82e7854152f2b700000000000000000000000000000000127e19f254ac9588319558041fc62ed56" + "b83579b80300000072437f9b6245de39ec9e71ee4b951507beb42b34000000000000000000000000" + "00000001d639272e4a46eadfbd2146bf8cfdb205b3980deb020000006c1de913df1424ce3ee1d76f" + "c1ea76e98c9dfc7800000000000000000000000000000001e44ea74b4f2b83f9b3bee14d861a4c9e" + "0436242c03000000ee3fbc164632d4f28aa28c08f80dd50c6712dfb4000000000000000000000000" + "00000000078a806d329c9b008bbfc9723107f3f52af145480300000004265f6c72923e22594f3f79" + "e208ed2e2ebb07710000000000000000000000000000000039dd8f88152a58454d9ca9d20f45dfa7" + "922b6cb8030000001d5c302df59dd32a677e5a3af4fe297f608df061000000000000000000000000" + "000000008ae21e371051852c972ea7954079884a9a1b163a030000000e2f4f911a0dd8c052ed6b13" + "e2815a1a37a52bdd00000000000000000000000000000000bd99fcf72909ac9e7a55299e9bb4fd53" + "9f3c2c8803000000f51f44e644d7cf1d06b2b115d882549e62c12fba000000000000000000000000" + "000000004fc812bd2f8a59d96d064126666befbbf257b044030000006a4c619f9037d7a754655354" + "c47cf0f551e967700000000000000000000000000000000050b8d10ab700cc3a7cf51be0403b654b" + "74e7860402000000cd7db68b9ae586dacdb4070c50320427c4dd3d03000000000000000000000000" + "00000000d538d34574c038404923e75d0e09e2fcfc1519de010000002545666937c22a3b6e9686dc" + "c405cbee5016c252000000000000000000000000000000006e4c699341b95f41d9c1e67743efb54e" + "6aae660b01000000fc1fb23d24438387def0f4c6544e4b275d9b7146000000000000000000000000" + "00000000b883efebc09dd9d61966b7ae7412041dd7ac5f9901000000822a272bec4501a1e27acfee" + "7a8588ffd5a06cae0000000000000000000000000000000077a47579dda0b6ead1e1b34901eaedd5" + "61c2f5d200000000b809d259e499db7dc8f1853bdcb0e4bc0e2b00b6000000000000000000000000" + "000000005e7fa0f02f2f3313d8469d09a92409c0b4d54acb00000000a417f3da01d99dae5f190096" + "cc582cabd5ddd15a00000000000000000000000000000000fdb3d117d76b0de5416f95e7bb75d72f" + "fc2b445700000000496ad01bf007eacb0a28aec868282510b60291ea000000000000000000000000" + "000000005b29a197b7b3cceaf5f1bb12c535256a74993ade03000000e62112898dab2dade2ab2fc9" + "c56a7c86be5f962200000000000000000000000000000000bdd06352cb2c354434819f4b248eb2b8" + "dc335c8b030000000a3c8e7c91bf821c4b09cee3c37ff4283a631480000000000000000000000000" + "000000005588456e4ead7cbda620a3abae816e34e3ff1a5f03000000b4425486c619147eb0216050" + "ed7afd741024e83600000000000000000000000000000000f493472201e48d163106cc397446a33f" + "bc74179403000000438a72e12ae0436a2495a609675344f7e2e3a5eb000000000000000000000000" + "0000000061eda239d9d083c3bf085387046ef8a34153e174020000004d89c0bb5408c1b7d17fb084" + "d9e1825fa638e1af000000000000000000000000000000006e08cb887464b9344ec3127c750fabdd" + "6c0fc09c02000000809829af4a9df58dbfef186d416f3a1ef170d10f000000000000000000000000" + "0000000087780281d47a32f2235376239daeaacba9a89f8701000000fcdf6d9be94030b34774d1d7" + "dddedd9899f0f62700000000000000000000000000000000848518c4e3f6cbf25e5e1b990fc46767" + "fd338f35010000006e8cc34573654ea6624f138ef9531cd9367a02e4000000000000000000000000" + "00000000da40d88d40a6d75bc404156225b7eede2cb749e2010000000eb4f73e75039fcf251b32fc" + "79685b05ddd3aa9b000000000000000000000000000000000d58fbcc58fc4c2fd0d44ff1e51c3515" + "b7f0318a01000000061db3dd7fde25654a4059d565dbc8a91e3b4457000000000000000000000000" + "00000000c1b5aad487c192f08bd7a09bdd21444359747cf200000000ab2dadc5a39411fd4ff1116d" + "478987316a553fc2000000000000000000000000000000000819e3b10db116431ec6f7691539ce41" + "b95c593100000000dbe9962069e66142e22753344fda8a3e0b841cf7000000000000000000000000" + "000000008c54dda9ac3bb1b1d43e6505621b9a7f672d2fa501000000e276c5661a64192db44ce7af" + "5eb888e9eb37bb0400000000000000000000000000000002641e447514ca565fb9b68c08a5e4351e" + "9f3c39f201000000de745cb25851429b3bbfb50168dfd04edf6b3542000000000000000000000000" + "0000000218f93e742d08f0550b55726f2292362e70ccc56700000000a4c73cf5ffa4ffc8a4bab148" + "74afdf54e6aae8160000000000000000000000000000000268baf76ab08940f6fc3bbdc7f6090f75" + "4f1b134803000000449a774929e86716ec852d59f3d17232edd86ad6000000000000000000000000" + "000000027dba1ee7e143fd52599364e13468f80f40b26f6603000000badfad0fe8fa8f3c1aad2a82" + "530b7447d9c2f401000000000000000000000000000000028147507e1cd59ea1ae6da48b1eba6d16" + "dedea2030100000002a1f8e6f5657f3f9e3eb807cbad76451055edb8000000000000000000000000" + "00000002d9279fb2b8fcbac6abea74f7a6df7979f6989d2d000000006ff7add5df2c93e05459507b" + "5d8c6a0f466554d200000000000000000000ffff1785d3ffdbd9a617857ae8126b028c0e3e295354"), + [2] = ("4cc43c5103000000c2aac1d67a909b297c703915312e9c3c5a06c40b20ea99d5ab90135fa636af44" + "64d210a256be75e0509c4477d19ac64b2e69220d54270e46020000006a894e387625da376feecb80" + "ac245409c0becc271d9c2f67179bff0644399ae79c64ed0432d599eaa660ac824b7fae389861419c" + "12ea3b9501000000fb95e8332fdfff658483a2d039a7bf148ed3481e0bccc460e89f7abdb682380a" + "62eae374835b4a49a2b980b6aba92da6409969aa7a899f2d010000009bf5a5d06776e66a9d80ab13" + "2e1ac921eb76adbb229df32e561fa80a40e55b8b1dd92e18c0cfb2b4386bec092fa5757ecde9348b" + "288cd9bf00000000225a0c71b2ce78bb16104c8eaf18c565ecc8fb112087b97cfcebbaeb0c565359" + "23f14874042a8aff1d1f8e5ec3cc13cc36bbe3c9c4e1966800000000b3121cd5ef51e696c816290d" + "baee0e7726d082e1530ff5397c9125f59577d71c4b258a005116d11354edff62ceaa458fc75a91c4" + "25a5927300000000c4458d70911714f1819aa46fbe143934c933ae6dec0fb124f264af67eed7c9a8" + "c38b6b8ee2614344bea73223e59bf0193432e9fa2fea9bc10300000062fb81e733cff620ca7feefe" + "1933631e8e69f6d9fed62d2c6e6904f57239c09c47150b9b14010469823acb72bb89182f93112196" + "9985d62700000000e491cbbbf9443fd6a77eb3c5bf64b671d6f18dbffeff9b8306c83bc026977911" + "4bdade862c224f6f36506ebd455e679cef369bb8bb0ec36f0000000064a2827b7cdd38d0314c178e" + "925b568ae56bc4e9fefb24e5264fd3ebe9cf9f6df9615189f78ee815b2781ea55c9555876b6a3f13" + "02e9b69000000000eacce745ea213cb1a84035b632ef3be6070dafa2fed87470e9da55709427c226" + "d324d9a086ed27184b443181a5edc511c1507a14d514573f03000000f6932f6932d1d5f5d0ce2cf6" + "bf7a70ba5193a162fe92ec1b11d9172cf84a03478b82cdd8883b0f3fd6ed84d6c959e553b887edcd" + "6297dfa700000000fd0d53bb6215de4bb6f6f3d031a790287e45e9c1feb836c0a25ea71f5daaed4d" + "99eb2ebebe3c432fec7d3abc4ccf30d3aaaf02a4ae8cb60b0300000038d856a40c67c3d4afa9c864" + "9da90bd2fff2f25600000000000000000000000000000001955e1a13d1111b067acbce3e3bcdf382" + "00154d12010000009edfa7a74c1c83c18e47935e8354846e34f0386a000000000000000000000000" + "00000001ac26c7d41fd050bf8d85055bcfe3756c1e0f515601000000f57609453df7803357ae7998" + "9870ccec3def0ad9000000000000000000000000000000019f05a16768cb3bc873b04d937a6ed8f7" + "7c52a52d030000004e8e8bc17c01ac63eca0c1cfbb204132fb7213e4000000000000000000000000" + "00000000accae11f8045a80f855ebf3b772eb2b1d03bc90503000000eb760e3f004a2efc8ffc96b8" + "9b1bc8f415bd4e7700000000000000000000000000000000d149f074a378b881153ece68ade15cec" + "6f0e9e6903000000ec2e2924348352d715cf9d411ea012e5307294b6000000000000000000000000" + "00000000ccd2f50c30706cae3fdcc2f0ee3d5e267666c05303000000ffa8e89871fb9510b900b206" + "1d0c334b819f2dd100000000000000000000000000000000095a3230fde69eec3af2e6d0bd68ab72" + "81ae55f0030000000aa20624fbab244735d67c61283031667b2d74a1000000000000000000000000" + "0000000000459582f4ef43c780908872746e39ef10613fc90200000016a31dc2e46a234558817151" + "b38fc9c909cf8d7100000000000000000000000000000000ae17bb4515856092b4d9e89b676761b2" + "57d6249b020000007dc7f17f666969e45c3baf7a119a65ee0b06fa9e000000000000000000000000" + "00000000b314f695bd82e9ea8891ed0a3d1b91ca6e91b91501000000be5b534e0a6527f67485ab35" + "aca0c7ee4197338500000000000000000000000000000000aefd4503189f7630248e501c9052c22b" + "5d68265d010000009b7a559be3acf4fc36fa6b513cf09e8b99289462000000000000000000000000" + "00000000b49185ad9b7d0070a36dd51323b2c542b56e03e0010000002f70249eefc67bce716c856e" + "3973dc42a1003be9000000000000000000000000000000006176f78a19bb8df1804c122fce5078c1" + "e5fe7d360100000066a3ae3939762df33a2d55060c78d551cbb110fd000000000000000000000000" + "000000002c171ed15abbbe1cd911db7b56e8f3feeecc89f601000000d635edea8ffe423d01883918" + "039249f398f9b37e000000000000000000000000000000001fb7c8307f06b4b29088f20d9ac676d5" + "f90e54b501000000a779f37c30d2c5053c40ecae210aeb0934cb2a24000000000000000000000000" + "00000000df48f333ef467092818aa77d6732b678bcd7be0700000000e45aaf61814f703b40125e6b" + "af4648cbaaa37b86000000000000000000000000000000005ddb05f2a84e27c18a06e2c9cb29efdf" + "50da49bf00000000d94beb259f9f0251becc987907879cca68fec7bb000000000000000000000000" + "000000009402a4c2167721673f2b02b3256ead1fa349e1cc00000000b879a45176740744fcb6a035" + "339d504c9726d80d000000000000000000000000000000009518862bc9a89192c1c8be55281a59d1" + "bae87d60000000005d31e5b2de252167c1c91b3a36ba0c700ee78477000000000000000000000000" + "000000006ad0143a0554efb46b382ab0404cdf02ebfdcec30000000067a982be8a934f852cc3d4d8" + "2bc0ec7303f99f8f00000000000000000000000000000000901f55f960c55c22f32099a8020bea2a" + "a2f56808092069affaa100fdfdd68d34be184524a6bdc8789cf85178000000000000000000000000" + "00000000020ffdb0e612098610e52bb2a16a4008aefd545b020000007ced4f8b362956cd46646a0e" + "222160e5f769bb2900000000000000000000000000000000a19da86c64fefab2548759d313a5b92d" + "f05d7308020000009d82c856ba942455050f63f8282f3464443cacf5000000000000000000000000" + "0000000069d9942f460bcea75481f25e307d0de99a6ce5d900000000a6a5ee19d6f63fe9cbdd01f7" + "246f13b2050424a200000000000000000000000000000000ffe9d6812231bb02f922259b173c333c" + "5b1aea3401000000c7c3523f76cf1ce34ca17a9a32f3f0f218424e48000000000000000000000000" + "00000002e6fbf952902383028e3b47f2111d891d17a4763102000000f9119c40b468b66331bca67a" + "034f43340d01683c00000000000000000000ffffb24a5be9b10123e6e4f15ecd1dff045298cfee06" + "536c75bb01000000720da9e07ac998b5690807d52617369ee1af4ca500000000000000000000ffff" + "47d7b351a36b178aabc78a4a0d80684ee5dbf45bb0916e5d030000004a503a712350acbd48411f0d" + "c15d2f0f49dad345599706954d2471f00d3c723b91adb0da7c4aa7e7eb5a15bcde015fb98b841fd8" + "ba8110fb03000000904f288262e6ea77a22fa5f863eaeefa701d120523bd98f29b098b43cd68be6e" + "3f81268193fd637e585287dc6ca972a2cfb18b2b3cae864b0200000091921681c2162b9bfa40546c" + "db544e44df2d7c2790d3119a051bb2ee8192ac0cfa3abc1ea0ab3e7d75a2f42b50c6a36340132378" + "8c3b371502000000710c030690f5f18ea125dbf7d7e93bd65c1fa56dfdcfc1155f236c8b9c79a620" + "5f660bbf024b03ff0a8e27c405e6424457393c6fdac12ebd01000000667224dae775e5ccd141aca2" + "ff0f576767d3648102b61886b62f22ca33478e1f891715df7fc6a902edae579e2e10c7f7a22ba034" + "abf85f0c0100000008d33a2ea67776d7f88d69c8c7e3b2d3c93ef054e93f8120abb42316c533d9c9" + "4d88189c471a1ff2f0ce3ff66e782110125ae2edc7a4c65601000000cd625009a40aeb62a42b6a62" + "548e3c38b96c20022753c5fbfaf1809becd2506315a6da29b2e94d3ab51fe0e9af98b180a36035fb" + "daae7d6300000000c0982b283aa9986700b2a2b3ed257b8b0489f48f053ec8cac72105b327335a25" + "a364d1015ffac03089f45539e1b0178462156cd66855676c00000000017c9148da5892bb4951c3a7" + "ed55689d3391ce7d3fd48469845f0c233dbdd2a97835df1f1782dee88487fd0db5971b46b7a350f9" + "cdb3455c00000000c66af76e80f062ea1a7e0b7be218d067530e1b0487b8c3b99f2b8a1a8982c42f" + "53700a3437c5156e072b2f2fb337c9cfe07c34ddc896c9a7000000000a5f6abd850b06e3d9662795" + "ce2cc1cee06302aba042aaa218dc091e9aa1477f6fdc9830d7fbc95829a8838314dff34d24c33221" + "98c39e7c00000000efc57ff447036b9551adcb22fd50793f797a3c7dadd1c86e759d0c90bc512e13" + "7dcef5e4a27985bd8d1e69c83dc21056b973972c7625ca4a00000000e682f80f94315c45ef817264" + "c89a736ed55ed637b077ddad3108be69f9b97d05c917ad6b10e693bb6e26f2ba90c8e909e85e20e5" + "9c88b02a0300000004b0595daf37deb499996bfb667f072dec1e5d9cdc8a11f4409bcfb3c167090e" + "99d90a8543961b2ccd47724a3c460ba85183f4c5a7afe28302000000d05ff720b16c73761a3fcb67" + "5219061ab4c5c79489b2cc6a883c146972decb8b5adac8f5e6d66df46ea139107754dee62c36d2fc" + "e36f90d401000000fd41fe47684b370b6ec6584d64496089570968ead4d1ae91c819bb068196d599" + "efde3246e43f5e7945aaf95e2ffa3a11b9ef1b214d4647f5000000000f88e3759a08e7a56663861e" + "ea1bf42ccd3c72f2ad063857ca82ac5180101be4f85cef468ea086ea9aaafdc388811ec787bc45db" + "0422ae3f03000000c43bd794c697895e5bfe47c6f53a54e01b0c1d89fecd94d0e02d2ec587fc3300" + "03781b0f294a2b73c4421398f4de67e9cee64b38bc51e540030000006c3d048a92d3adc69a84eb47" + "622400207799416afef0a086fbd7e2f7dea0077ae9c0c0d9c386e9c6e6a2cbfa10ee58bdc7518360" + "36674cde0200000054cfe8f42bf0e9381ba2c4396de60f032bc7f34dfe959871c0d4c0d4eb720c4a" + "e3c9472e5f2da5d9c5cfd9f2343b21362c19a092b2cd3dbd01000000e958e48d2ab8b0313e7f8933" + "e315130fa9a84c82feb83f6e70b1646d8026e9f1704f1b16286ba2dabc7ef0820c91ed33ef60a8b5" + "bcfe97e1000000007ad742d3d7320a4f880cf47f5dd0cf69cb22840ffeb3fe7749509cb6752b2cee" + "30b7e7736a0afc9879ea40e69710fc9f6e8e99cd69121aec010000000fcc00ac2daa755e5292cd32" + "dc096cd5d8a4c5cffe91ee1cfcc2056cc1ff8e51bbce426cfa4b861cc78592be7b14e7ba9c15acb8" + "b83579b80300000072437f9b6245de39ec9e71ee4b951507beb42b34000000000000000000000000" + "00000001d639272e4a46eadfbd2146bf8cfdb205b3980deb020000006c1de913df1424ce3ee1d76f" + "c1ea76e98c9dfc7800000000000000000000000000000001e44ea74b4f2b83f9b3bee14d861a4c9e" + "cf844ef501000000cd743f59bd14c89b5cfd5ce6e82e7854152f2b70000000000000000000000000" + "0000000127e19f254ac9588319558041fc62ed561dce2f83020000003a3efc240b9977e166bee737" + "fe73670c439a644c000000000000000000000000000000015e0dfe491d1ba96742c7b5e02b227122" + "2af145480300000004265f6c72923e22594f3f79e208ed2e2ebb0771000000000000000000000000" + "0000000039dd8f88152a58454d9ca9d20f45dfa774993ade03000000e62112898dab2dade2ab2fc9" + "c56a7c86be5f962200000000000000000000000000000000bdd06352cb2c354434819f4b248eb2b8" + "922b6cb8030000001d5c302df59dd32a677e5a3af4fe297f608df061000000000000000000000000" + "000000008ae21e371051852c972ea7954079884a9f3c2c8803000000f51f44e644d7cf1d06b2b115" + "d882549e62c12fba000000000000000000000000000000004fc812bd2f8a59d96d064126666befbb" + "dc335c8b030000000a3c8e7c91bf821c4b09cee3c37ff4283a631480000000000000000000000000" + "000000005588456e4ead7cbda620a3abae816e34e3ff1a5f03000000b4425486c619147eb0216050" + "ed7afd741024e83600000000000000000000000000000000f493472201e48d163106cc397446a33f" + "f257b044030000006a4c619f9037d7a754655354c47cf0f551e96770000000000000000000000000" + "0000000050b8d10ab700cc3a7cf51be0403b654bbc74179403000000438a72e12ae0436a2495a609" + "675344f7e2e3a5eb0000000000000000000000000000000061eda239d9d083c3bf085387046ef8a3" + "4153e174020000004d89c0bb5408c1b7d17fb084d9e1825fa638e1af000000000000000000000000" + "000000006e08cb887464b9344ec3127c750fabdd6c0fc09c02000000809829af4a9df58dbfef186d" + "416f3a1ef170d10f0000000000000000000000000000000087780281d47a32f2235376239daeaacb" + "74e7860402000000cd7db68b9ae586dacdb4070c50320427c4dd3d03000000000000000000000000" + "00000000d538d34574c038404923e75d0e09e2fca9a89f8701000000fcdf6d9be94030b34774d1d7" + "dddedd9899f0f62700000000000000000000000000000000848518c4e3f6cbf25e5e1b990fc46767" + "fd338f35010000006e8cc34573654ea6624f138ef9531cd9367a02e4000000000000000000000000" + "00000000da40d88d40a6d75bc404156225b7eede2cb749e2010000000eb4f73e75039fcf251b32fc" + "79685b05ddd3aa9b000000000000000000000000000000000d58fbcc58fc4c2fd0d44ff1e51c3515" + "6aae660b01000000fc1fb23d24438387def0f4c6544e4b275d9b7146000000000000000000000000" + "00000000b883efebc09dd9d61966b7ae7412041db7f0318a01000000061db3dd7fde25654a4059d5" + "65dbc8a91e3b445700000000000000000000000000000000c1b5aad487c192f08bd7a09bdd214443" + "61c2f5d200000000b809d259e499db7dc8f1853bdcb0e4bc0e2b00b6000000000000000000000000" + "000000005e7fa0f02f2f3313d8469d09a92409c0b4d54acb00000000a417f3da01d99dae5f190096" + "cc582cabd5ddd15a00000000000000000000000000000000fdb3d117d76b0de5416f95e7bb75d72f" + "59747cf200000000ab2dadc5a39411fd4ff1116d478987316a553fc2000000000000000000000000" + "000000000819e3b10db116431ec6f7691539ce41b95c593100000000dbe9962069e66142e2275334" + "4fda8a3e0b841cf7000000000000000000000000000000008c54dda9ac3bb1b1d43e6505621b9a7f" + "fc2b445700000000496ad01bf007eacb0a28aec868282510b60291ea000000000000000000000000" + "000000005b29a197b7b3cceaf5f1bb12c535256a0436242c03000000ee3fbc164632d4f28aa28c08" + "f80dd50c6712dfb400000000000000000000000000000000078a806d329c9b008bbfc9723107f3f5" + "9a1b163a030000000e2f4f911a0dd8c052ed6b13e2815a1a37a52bdd000000000000000000000000" + "00000000bd99fcf72909ac9e7a55299e9bb4fd53fc1519de010000002545666937c22a3b6e9686dc" + "c405cbee5016c252000000000000000000000000000000006e4c699341b95f41d9c1e67743efb54e" + "d7ac5f9901000000822a272bec4501a1e27acfee7a8588ffd5a06cae000000000000000000000000" + "0000000077a47579dda0b6ead1e1b34901eaedd54f1b134803000000449a774929e86716ec852d59" + "f3d17232edd86ad6000000000000000000000000000000027dba1ee7e143fd52599364e13468f80f" + "40b26f6603000000badfad0fe8fa8f3c1aad2a82530b7447d9c2f401000000000000000000000000" + "000000028147507e1cd59ea1ae6da48b1eba6d16dedea2030100000002a1f8e6f5657f3f9e3eb807" + "cbad76451055edb800000000000000000000000000000002d9279fb2b8fcbac6abea74f7a6df7979" + "672d2fa501000000e276c5661a64192db44ce7af5eb888e9eb37bb04000000000000000000000000" + "00000002641e447514ca565fb9b68c08a5e4351e9f3c39f201000000de745cb25851429b3bbfb501" + "68dfd04edf6b35420000000000000000000000000000000218f93e742d08f0550b55726f2292362e" + "70ccc56700000000a4c73cf5ffa4ffc8a4bab14874afdf54e6aae816000000000000000000000000" + "0000000268baf76ab08940f6fc3bbdc7f6090f75f6989d2d000000006ff7add5df2c93e05459507b" + "5d8c6a0f466554d200000000000000000000ffff1785d3ffdbd9a617857ae8126b028c0e3e295354"), + }; + const int TEST_DATA_I = GPOINTER_TO_INT(test_data); + const int addr_family = (TEST_DATA_I == 0 ? AF_INET : AF_INET6); + const int IPV6_PREFER_TEMP = (TEST_DATA_I == 2); + const guint N_ADDRESSES = 100; + const gsize ELM_SIZE = + addr_family == AF_INET ? sizeof(NMPlatformIP4Address) : sizeof(NMPlatformIP6Address); + const gboolean DO_REGENERATE = FALSE; + const gboolean PRINT_RESULT = DO_REGENERATE; + const gboolean CHECK_RESULT = !DO_REGENERATE; + gs_free guint8 *addresses = NULL; + gs_free guint64 *rand_map = NULL; + gsize i, j; + + /* + * First we create a list of addresses filled with (stable) random bytes. + * We tweak some fields explicitly (stable randomly), so that we cover all + * relevant cases. + * + * Then we sort the list of addresses, and compare that the result is + * as our EXPECTED_BUFFER. + */ + + addresses = g_malloc(ELM_SIZE * N_ADDRESSES); + rand_map = g_malloc(sizeof(rand_map[0]) * N_ADDRESSES); + nmtst_stable_rand(258829693, addresses, ELM_SIZE * N_ADDRESSES); + nmtst_stable_rand(710086081, rand_map, sizeof(rand_map[0]) * N_ADDRESSES); + + for (i = 0; i < N_ADDRESSES; i++) { + NMPlatformIPXAddress *a = (gpointer)(&addresses[i * ELM_SIZE]); + guint64 r = rand_map[i]; + struct in6_addr * a6; + +#define CONSUME_BITS(r, nbits) \ + ({ \ + guint64 _r = (r); \ + const int _nbits = (nbits); \ + \ + r >>= (_nbits); \ + (_r & (((((guint64) 1u) << (_nbits)) - 1u))); \ + }) + + if (addr_family == AF_INET) { + if (CONSUME_BITS(r, 1)) { + /* randomly create a link-local address or not. */ + g_assert((NM_IPV4LL_NETWORK & ~NM_IPV4LL_NETMASK) == 0); + a->a4.address = (a->a4.address & ~NM_IPV4LL_NETMASK) | NM_IPV4LL_NETWORK; + } + } else { + a6 = &a->a6.address; + switch (CONSUME_BITS(r, 4)) { + case 0: + a6->s6_addr32[0] = 0; + a6->s6_addr32[1] = 0; + a6->s6_addr32[2] = htonl(0xffff); + g_assert(IN6_IS_ADDR_V4MAPPED(a6)); + break; + case 1: + a6->s6_addr32[0] = 0; + a6->s6_addr32[1] = 0; + a6->s6_addr32[2] = 0; + a6->s6_addr32[3] = htonl(2); + g_assert(IN6_IS_ADDR_V4COMPAT(a6)); + break; + case 2: + a6->s6_addr32[0] = 0; + a6->s6_addr32[1] = 0; + a6->s6_addr32[2] = 0; + a6->s6_addr32[3] = 0; + g_assert(IN6_IS_ADDR_UNSPECIFIED(a6)); + break; + case 3: + a6->s6_addr32[0] = 0; + a6->s6_addr32[1] = 0; + a6->s6_addr32[2] = 0; + a6->s6_addr32[3] = htonl(1); + g_assert(IN6_IS_ADDR_LOOPBACK(a6)); + break; + case 4: + a6->s6_addr32[0] = (a6->s6_addr32[0] & ~htonl(0xffc00000)) | htonl(0xfe800000); + g_assert(IN6_IS_ADDR_LINKLOCAL(a6)); + break; + case 6: + a6->s6_addr32[0] = (a6->s6_addr32[0] & ~htonl(0xffc00000)) | htonl(0xfec00000); + g_assert(IN6_IS_ADDR_SITELOCAL(a6)); + break; + case 7: + case 8: + case 9: + case 10: + break; + default: + memset(a6, 0, sizeof(*a6)); + break; + } + } + + if (CONSUME_BITS(r, 5) != 0) { + /* randomly make addr-source the same (so that several addresses compare + * equal). */ + a->a4.addr_source = CONSUME_BITS(r, 2); + } + + if (addr_family == AF_INET) { + if (CONSUME_BITS(r, 1)) { + /* randomly make the label empty or not. */ + a->a4.label[0] = '\0'; + } + } + if (addr_family == AF_INET) { + if (CONSUME_BITS(r, 2) != 0) { + /* randomly make the label empty or not. */ + a->a4.plen = CONSUME_BITS(r, 2); + } + } + if (addr_family == AF_INET) { + if (CONSUME_BITS(r, 1)) { + a->a4.address = (a->a4.address & ~0xFFFFFFu) | (CONSUME_BITS(r, 2) << 24); + } + } + } + + g_qsort_with_data(addresses, + N_ADDRESSES, + ELM_SIZE, + _address_pretty_sort_cmp, + (gpointer) test_data); + + for (i = 0; i < N_ADDRESSES; i++) { + const NMPlatformIPXAddress *a = (gconstpointer)(&addresses[i * ELM_SIZE]); + + for (j = i + 1; j < N_ADDRESSES; j++) { + const NMPlatformIPXAddress *b = (gconstpointer)(&addresses[j * ELM_SIZE]); + int c1; + int c2; + + if (addr_family == AF_INET) { + c1 = nm_platform_ip4_address_pretty_sort_cmp(&a->a4, &b->a4); + c2 = nm_platform_ip4_address_pretty_sort_cmp(&b->a4, &a->a4); + } else { + c1 = nm_platform_ip6_address_pretty_sort_cmp(&a->a6, &b->a6, IPV6_PREFER_TEMP); + c2 = nm_platform_ip6_address_pretty_sort_cmp(&b->a6, &a->a6, IPV6_PREFER_TEMP); + } + + g_assert_cmpint(c1, >=, -1); + g_assert_cmpint(c1, <=, 1); + g_assert_cmpint(c1, ==, -c2); + } + } + + if (PRINT_RESULT) { + g_print("\n\n\t\t[%d] = (\n", TEST_DATA_I); + for (i = 0; i < ELM_SIZE * N_ADDRESSES;) { + g_print("\t\t\t\""); + for (j = 0; j < 40 && i < ELM_SIZE * N_ADDRESSES; j++, i++) + g_print("%02x", addresses[i]); + g_print("\"\n"); + } + g_print("\t\t),\n\n"); + return; + } + + if (CHECK_RESULT) { + gs_free guint8 *bin_arr = NULL; + gsize bin_len; + + bin_arr = nm_utils_hexstr2bin_alloc(EXPECTED_BUFFER[TEST_DATA_I], + FALSE, + FALSE, + NULL, + 0, + &bin_len); + g_assert_cmpmem(addresses, ELM_SIZE * N_ADDRESSES, bin_arr, bin_len); + } } /*****************************************************************************/ -NMTST_DEFINE (); +NMTST_DEFINE(); int -main (int argc, char **argv) +main(int argc, char **argv) { - nmtst_init_assert_logging (&argc, &argv, "WARN", "DEFAULT"); + nmtst_init_assert_logging(&argc, &argv, "WARN", "DEFAULT"); - g_test_add_func ("/general/init_linux_platform", test_init_linux_platform); - g_test_add_func ("/general/link_get_all", test_link_get_all); - g_test_add_func ("/general/nm_platform_link_flags2str", test_nm_platform_link_flags2str); + g_test_add_func("/general/init_linux_platform", test_init_linux_platform); + g_test_add_func("/general/link_get_all", test_link_get_all); + g_test_add_func("/general/nm_platform_link_flags2str", test_nm_platform_link_flags2str); + g_test_add_data_func("/general/platform_ip_address_pretty_sort_cmp/4", + GINT_TO_POINTER(0), + test_platform_ip_address_pretty_sort_cmp); + g_test_add_data_func("/general/platform_ip_address_pretty_sort_cmp/6/1", + GINT_TO_POINTER(1), + test_platform_ip_address_pretty_sort_cmp); + g_test_add_data_func("/general/platform_ip_address_pretty_sort_cmp/6/2", + GINT_TO_POINTER(2), + test_platform_ip_address_pretty_sort_cmp); - return g_test_run (); + return g_test_run(); } diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c index 42b5baf0..1305e586 100644 --- a/src/platform/tests/test-route.c +++ b/src/platform/tests/test-route.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2016 - 2017 Red Hat, Inc. */ @@ -18,1710 +18,1870 @@ #define EX NMTSTP_ENV1_EX static void -_wait_for_ipv4_addr_device_route (NMPlatform *platform, - gint64 timeout_msec, - int ifindex, - in_addr_t addr, - guint8 plen) +_wait_for_ipv4_addr_device_route(NMPlatform *platform, + gint64 timeout_msec, + int ifindex, + in_addr_t addr, + guint8 plen) { - /* Wait that the addresses gets a device-route. After adding a address, - * the device route is not added immediately. It takes a moment... */ - - addr = nm_utils_ip4_address_clear_host_address (addr, plen); - NMTST_WAIT_ASSERT (400, { - NMDedupMultiIter iter; - NMPLookup lookup; - const NMPObject *o; - - nmp_cache_iter_for_each (&iter, - nm_platform_lookup (platform, - nmp_lookup_init_object (&lookup, - NMP_OBJECT_TYPE_IP4_ROUTE, - ifindex)), - &o) { - const NMPlatformIP4Route *r = NMP_OBJECT_CAST_IP4_ROUTE (o); - - if ( r->plen == plen - && addr == nm_utils_ip4_address_clear_host_address (r->network, plen) - && r->metric == 0 - && r->scope_inv == nm_platform_route_scope_inv (RT_SCOPE_LINK) - && r->rt_source == NM_IP_CONFIG_SOURCE_RTPROT_KERNEL) - return; - } - nmtstp_assert_wait_for_signal (platform, - (nmtst_wait_end_us - g_get_monotonic_time ()) / 1000); - }); + /* Wait that the addresses gets a device-route. After adding a address, + * the device route is not added immediately. It takes a moment... */ + + addr = nm_utils_ip4_address_clear_host_address(addr, plen); + NMTST_WAIT_ASSERT(400, { + NMDedupMultiIter iter; + NMPLookup lookup; + const NMPObject *o; + + nmp_cache_iter_for_each ( + &iter, + nm_platform_lookup(platform, + nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP4_ROUTE, ifindex)), + &o) { + const NMPlatformIP4Route *r = NMP_OBJECT_CAST_IP4_ROUTE(o); + + if (r->plen == plen && addr == nm_utils_ip4_address_clear_host_address(r->network, plen) + && r->metric == 0 && r->scope_inv == nm_platform_route_scope_inv(RT_SCOPE_LINK) + && r->rt_source == NM_IP_CONFIG_SOURCE_RTPROT_KERNEL) + return; + } + nmtstp_assert_wait_for_signal(platform, + (nmtst_wait_end_us - g_get_monotonic_time()) / 1000); + }); } static void -_wait_for_ipv6_addr_non_tentative (NMPlatform *platform, - gint64 timeout_msec, - int ifindex, - guint addr_n, - const struct in6_addr *addrs) +_wait_for_ipv6_addr_non_tentative(NMPlatform * platform, + gint64 timeout_msec, + 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 (timeout_msec, { - 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); - }); + 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(timeout_msec, { + 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) +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); - g_assert_cmpint (received->ifindex, ==, ifindex); - 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) - return; - - if (data->loop) - g_main_loop_quit (data->loop); - - data->received_count++; - _LOGD ("Received signal '%s' %dth time.", data->name, data->received_count); + 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); + g_assert_cmpint(received->ifindex, ==, ifindex); + 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) + return; + + if (data->loop) + g_main_loop_quit(data->loop); + + data->received_count++; + _LOGD("Received signal '%s' %dth time.", data->name, data->received_count); } static void -ip6_route_callback (NMPlatform *platform, int obj_type_i, int ifindex, const NMPlatformIP6Route *received, int change_type_i, SignalData *data) +ip6_route_callback(NMPlatform * platform, + int obj_type_i, + int ifindex, + const NMPlatformIP6Route *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_IP6_ROUTE, NULL); - - g_assert_cmpint (obj_type, ==, NMP_OBJECT_TYPE_IP6_ROUTE); - g_assert (received); - g_assert_cmpint (received->ifindex, ==, ifindex); - 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) - return; - - if (data->loop) - g_main_loop_quit (data->loop); - - data->received_count++; - _LOGD ("Received signal '%s' %dth time.", data->name, data->received_count); + 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); + g_assert_cmpint(received->ifindex, ==, ifindex); + 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) + return; + + if (data->loop) + g_main_loop_quit(data->loop); + + data->received_count++; + _LOGD("Received signal '%s' %dth time.", data->name, data->received_count); } static void -test_ip4_route_metric0 (void) +test_ip4_route_metric0(void) { - int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); - 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) */ - int plen = 32; - int metric = 22987; - int mss = 1000; - - /* No routes initially */ - 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, 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 (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0)); - ensure_no_signal (route_removed); - - 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, 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 (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0)); - accept_signal (route_removed); - - 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 (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, 0)); - ensure_no_signal (route_removed); - - 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 (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); - accept_signal (route_removed); - - 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); - free_signal (route_removed); + int ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME); + 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) */ + int plen = 32; + int metric = 22987; + int mss = 1000; + + /* No routes initially */ + 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, 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(nmtstp_platform_ip4_route_delete(NM_PLATFORM_GET, ifindex, network, plen, 0)); + ensure_no_signal(route_removed); + + 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, 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(nmtstp_platform_ip4_route_delete(NM_PLATFORM_GET, ifindex, network, plen, 0)); + accept_signal(route_removed); + + 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(nmtstp_platform_ip4_route_delete(NM_PLATFORM_GET, ifindex, network, plen, 0)); + ensure_no_signal(route_removed); + + 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(nmtstp_platform_ip4_route_delete(NM_PLATFORM_GET, ifindex, network, plen, metric)); + accept_signal(route_removed); + + 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); + free_signal(route_removed); } static void -test_ip4_route (void) +test_ip4_route(void) { - int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); - 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); - GPtrArray *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); - - /* Add route to gateway */ - nmtstp_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, gateway, 32, INADDR_ANY, 0, metric, mss); - accept_signal (route_added); - - /* Add route */ - nmtstp_assert_ip4_route_exists (NULL, 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, 1, DEVICE_NAME, network, plen, metric, 0); - accept_signal (route_added); - - /* Add route again */ - nmtstp_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, 0, metric, mss); - accept_signals (route_changed, 0, 1); - - /* Add default route */ - nmtstp_assert_ip4_route_exists (NULL, 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, 1, DEVICE_NAME, 0, 0, metric, 0); - accept_signal (route_added); - - /* Add default route again */ - nmtstp_ip4_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, 0, 0, gateway, 0, metric, mss); - accept_signals (route_changed, 0, 1); - - /* Test route listing */ - 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; - rts[0].plen = 32; - rts[0].ifindex = ifindex; - 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[1].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); - rts[1].network = network; - rts[1].plen = plen; - rts[1].ifindex = ifindex; - 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[2].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); - rts[2].network = 0; - rts[2].plen = 0; - rts[2].ifindex = ifindex; - rts[2].gateway = gateway; - rts[2].metric = metric; - 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_aptr ((const NMPObject *const*) routes->pdata, rts, routes->len, TRUE); - g_ptr_array_unref (routes); - - /* Remove route */ - 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 (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); - - /* Remove default route */ - g_assert (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, 0, 0, metric)); - accept_signal (route_removed); - - /* Remove route to gateway */ - g_assert (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, ifindex, gateway, 32, metric)); - accept_signal (route_removed); - - free_signal (route_added); - free_signal (route_changed); - free_signal (route_removed); + int ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME); + 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); + GPtrArray * 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); + + /* Add route to gateway */ + nmtstp_ip4_route_add(NM_PLATFORM_GET, + ifindex, + NM_IP_CONFIG_SOURCE_USER, + gateway, + 32, + INADDR_ANY, + 0, + metric, + mss); + accept_signal(route_added); + + /* Add route */ + nmtstp_assert_ip4_route_exists(NULL, 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, 1, DEVICE_NAME, network, plen, metric, 0); + accept_signal(route_added); + + /* Add route again */ + nmtstp_ip4_route_add(NM_PLATFORM_GET, + ifindex, + NM_IP_CONFIG_SOURCE_USER, + network, + plen, + gateway, + 0, + metric, + mss); + accept_signals(route_changed, 0, 1); + + /* Add default route */ + nmtstp_assert_ip4_route_exists(NULL, 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, 1, DEVICE_NAME, 0, 0, metric, 0); + accept_signal(route_added); + + /* Add default route again */ + nmtstp_ip4_route_add(NM_PLATFORM_GET, + ifindex, + NM_IP_CONFIG_SOURCE_USER, + 0, + 0, + gateway, + 0, + metric, + mss); + accept_signals(route_changed, 0, 1); + + /* Test route listing */ + 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; + rts[0].plen = 32; + rts[0].ifindex = ifindex; + 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[1].rt_source = nmp_utils_ip_config_source_round_trip_rtprot(NM_IP_CONFIG_SOURCE_USER); + rts[1].network = network; + rts[1].plen = plen; + rts[1].ifindex = ifindex; + 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[2].rt_source = nmp_utils_ip_config_source_round_trip_rtprot(NM_IP_CONFIG_SOURCE_USER); + rts[2].network = 0; + rts[2].plen = 0; + rts[2].ifindex = ifindex; + rts[2].gateway = gateway; + rts[2].metric = metric; + 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_aptr((const NMPObject *const *) routes->pdata, + rts, + routes->len, + TRUE); + g_ptr_array_unref(routes); + + /* Remove route */ + 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(nmtstp_platform_ip4_route_delete(NM_PLATFORM_GET, ifindex, network, plen, metric)); + + /* Remove default route */ + g_assert(nmtstp_platform_ip4_route_delete(NM_PLATFORM_GET, ifindex, 0, 0, metric)); + accept_signal(route_removed); + + /* Remove route to gateway */ + g_assert(nmtstp_platform_ip4_route_delete(NM_PLATFORM_GET, ifindex, gateway, 32, metric)); + accept_signal(route_removed); + + free_signal(route_added); + free_signal(route_changed); + free_signal(route_removed); } static void -test_ip6_route (void) +test_ip6_route(void) { - int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); - 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); - GPtrArray *routes; - NMPlatformIP6Route rts[3]; - struct in6_addr network; - guint8 plen = 64; - struct in6_addr gateway, pref_src; - /* Choose a high metric so that we hopefully don't conflict. */ - const int metric = 22987; - int mss = 1000; - - inet_pton (AF_INET6, "2001:db8:a:b:0:0:0:0", &network); - inet_pton (AF_INET6, "2001:db8:c:d:1:2:3:4", &gateway); - inet_pton (AF_INET6, "::42", &pref_src); - - g_assert (nm_platform_ip6_address_add (NM_PLATFORM_GET, ifindex, pref_src, 128, in6addr_any, - NM_PLATFORM_LIFETIME_PERMANENT, NM_PLATFORM_LIFETIME_PERMANENT, 0)); - accept_signals (route_added, 0, 3); - - _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_signals (route_added, 0, 3); - - /* Add route */ - 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 (nmtstp_ip6_route_get (NM_PLATFORM_GET, ifindex, &network, plen, metric, NULL, 0)); - accept_signal (route_added); - - /* Add route again */ - nmtstp_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, network, plen, gateway, pref_src, metric, mss); - accept_signals (route_changed, 0, 1); - - /* Add default route */ - g_assert (!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 (nmtstp_ip6_route_get (NM_PLATFORM_GET, ifindex, &in6addr_any, 0, metric, NULL, 0)); - accept_signal (route_added); - - /* Add default route again */ - nmtstp_ip6_route_add (NM_PLATFORM_GET, ifindex, NM_IP_CONFIG_SOURCE_USER, in6addr_any, 0, gateway, in6addr_any, metric, mss); - accept_signals (route_changed, 0, 1); - - /* Test route listing */ - 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; - rts[0].plen = 128; - rts[0].ifindex = ifindex; - rts[0].gateway = in6addr_any; - rts[0].pref_src = in6addr_any; - rts[0].metric = metric; - rts[0].mss = mss; - 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; - rts[1].ifindex = ifindex; - rts[1].gateway = gateway; - rts[1].pref_src = pref_src; - rts[1].metric = metric; - rts[1].mss = mss; - rts[2].rt_source = nmp_utils_ip_config_source_round_trip_rtprot (NM_IP_CONFIG_SOURCE_USER); - rts[2].network = in6addr_any; - rts[2].plen = 0; - rts[2].ifindex = ifindex; - rts[2].gateway = gateway; - rts[2].pref_src = in6addr_any; - rts[2].metric = metric; - rts[2].mss = mss; - g_assert_cmpint (routes->len, ==, 3); - nmtst_platform_ip6_routes_equal_aptr ((const NMPObject *const*) routes->pdata, rts, routes->len, TRUE); - g_ptr_array_unref (routes); - - /* Remove route */ - 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 (nmtstp_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, network, plen, metric)); - - /* Remove default route */ - 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 (nmtstp_platform_ip6_route_delete (NM_PLATFORM_GET, ifindex, gateway, 128, metric)); - accept_signal (route_removed); - - free_signal (route_added); - free_signal (route_changed); - free_signal (route_removed); + int ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME); + 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); + GPtrArray * routes; + NMPlatformIP6Route rts[3]; + struct in6_addr network; + guint8 plen = 64; + struct in6_addr gateway, pref_src; + /* Choose a high metric so that we hopefully don't conflict. */ + const int metric = 22987; + int mss = 1000; + + inet_pton(AF_INET6, "2001:db8:a:b:0:0:0:0", &network); + inet_pton(AF_INET6, "2001:db8:c:d:1:2:3:4", &gateway); + inet_pton(AF_INET6, "::42", &pref_src); + + g_assert(nm_platform_ip6_address_add(NM_PLATFORM_GET, + ifindex, + pref_src, + 128, + in6addr_any, + NM_PLATFORM_LIFETIME_PERMANENT, + NM_PLATFORM_LIFETIME_PERMANENT, + 0)); + accept_signals(route_added, 0, 3); + + _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_signals(route_added, 0, 3); + + /* Add route */ + 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(nmtstp_ip6_route_get(NM_PLATFORM_GET, ifindex, &network, plen, metric, NULL, 0)); + accept_signal(route_added); + + /* Add route again */ + nmtstp_ip6_route_add(NM_PLATFORM_GET, + ifindex, + NM_IP_CONFIG_SOURCE_USER, + network, + plen, + gateway, + pref_src, + metric, + mss); + accept_signals(route_changed, 0, 1); + + /* Add default route */ + g_assert(!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(nmtstp_ip6_route_get(NM_PLATFORM_GET, ifindex, &in6addr_any, 0, metric, NULL, 0)); + accept_signal(route_added); + + /* Add default route again */ + nmtstp_ip6_route_add(NM_PLATFORM_GET, + ifindex, + NM_IP_CONFIG_SOURCE_USER, + in6addr_any, + 0, + gateway, + in6addr_any, + metric, + mss); + accept_signals(route_changed, 0, 1); + + /* Test route listing */ + 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; + rts[0].plen = 128; + rts[0].ifindex = ifindex; + rts[0].gateway = in6addr_any; + rts[0].pref_src = in6addr_any; + rts[0].metric = metric; + rts[0].mss = mss; + 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; + rts[1].ifindex = ifindex; + rts[1].gateway = gateway; + rts[1].pref_src = pref_src; + rts[1].metric = metric; + rts[1].mss = mss; + rts[2].rt_source = nmp_utils_ip_config_source_round_trip_rtprot(NM_IP_CONFIG_SOURCE_USER); + rts[2].network = in6addr_any; + rts[2].plen = 0; + rts[2].ifindex = ifindex; + rts[2].gateway = gateway; + rts[2].pref_src = in6addr_any; + rts[2].metric = metric; + rts[2].mss = mss; + g_assert_cmpint(routes->len, ==, 3); + nmtst_platform_ip6_routes_equal_aptr((const NMPObject *const *) routes->pdata, + rts, + routes->len, + TRUE); + g_ptr_array_unref(routes); + + /* Remove route */ + 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(nmtstp_platform_ip6_route_delete(NM_PLATFORM_GET, ifindex, network, plen, metric)); + + /* Remove default route */ + 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(nmtstp_platform_ip6_route_delete(NM_PLATFORM_GET, ifindex, gateway, 128, metric)); + accept_signal(route_removed); + + free_signal(route_added); + free_signal(route_changed); + free_signal(route_removed); } /*****************************************************************************/ static void -test_ip4_route_get (void) +test_ip4_route_get(void) { - int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); - in_addr_t a; - int 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_uint32 () % 2 ? 0 : ifindex, - &route); - - g_assert (NMTST_NM_ERR_SUCCESS (result)); - 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 (NM_FLAGS_HAS (r->r_rtm_flags, RTM_F_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); + int ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME); + in_addr_t a; + int 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_uint32() % 2 ? 0 : ifindex, + &route); + + g_assert(NMTST_NM_ERR_SUCCESS(result)); + 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(NM_FLAGS_HAS(r->r_rtm_flags, RTM_F_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) +test_ip4_zero_gateway(void) { - int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); - - 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 ( 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); + int ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME); + + 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 (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); } static void -test_ip4_route_options (gconstpointer test_data) +test_ip4_route_options(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); - gs_unref_ptrarray GPtrArray *routes = NULL; + const int TEST_IDX = GPOINTER_TO_INT(test_data); + const int IFINDEX = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME); + gs_unref_ptrarray GPtrArray *routes = NULL; #define RTS_MAX 3 - NMPlatformIP4Route rts_add[RTS_MAX] = { }; - NMPlatformIP4Route rts_cmp[RTS_MAX] = { }; - NMPlatformIP4Address addr[1] = { }; - guint i; - guint rts_n = 0; - guint addr_n = 0; - - switch (TEST_IDX) { - case 1: - rts_add[rts_n++] = ((NMPlatformIP4Route) { - .ifindex = IFINDEX, - .rt_source = NM_IP_CONFIG_SOURCE_USER, - .network = nmtst_inet4_from_string ("172.16.1.0"), - .plen = 24, - .metric = 20, - .tos = 0x28, - .window = 10000, - .cwnd = 16, - .initcwnd = 30, - .initrwnd = 50, - .mtu = 1350, - .lock_cwnd = TRUE, - }); - break; - case 2: - addr[addr_n++] = ((NMPlatformIP4Address) { - .ifindex = IFINDEX, - .address = nmtst_inet4_from_string ("172.16.1.5"), - .peer_address = nmtst_inet4_from_string ("172.16.1.5"), - .plen = 24, - .lifetime = NM_PLATFORM_LIFETIME_PERMANENT, - .preferred = NM_PLATFORM_LIFETIME_PERMANENT, - .n_ifa_flags = 0, - }); - rts_add[rts_n++] = ((NMPlatformIP4Route) { - .ifindex = IFINDEX, - .rt_source = NM_IP_CONFIG_SOURCE_USER, - .network = nmtst_inet4_from_string ("172.17.1.0"), - .gateway = nmtst_inet4_from_string ("172.16.1.1"), - .plen = 24, - .metric = 20, - }); - rts_add[rts_n++] = ((NMPlatformIP4Route) { - .ifindex = IFINDEX, - .rt_source = NM_IP_CONFIG_SOURCE_USER, - .network = nmtst_inet4_from_string ("172.19.1.0"), - .gateway = nmtst_inet4_from_string ("172.18.1.1"), - .r_rtm_flags = RTNH_F_ONLINK, - .plen = 24, - .metric = 20, - }); - break; - default: - g_assert_not_reached (); - break; - } - g_assert (rts_n <= G_N_ELEMENTS (rts_add)); - g_assert (addr_n <= G_N_ELEMENTS (addr)); - - for (i = 0; i < addr_n; i++) { - const NMPlatformIP4Address *a = &addr[i]; - - g_assert (a->ifindex == IFINDEX); - g_assert (nm_platform_ip4_address_add (NM_PLATFORM_GET, - a->ifindex, - a->address, - a->plen, - a->peer_address, - nm_platform_ip4_broadcast_address_create (a->address, a->plen), - a->lifetime, - a->preferred, - a->n_ifa_flags, - a->label)); - if (a->peer_address == a->address) - _wait_for_ipv4_addr_device_route (NM_PLATFORM_GET, 200, a->ifindex, a->address, a->plen); - } - - for (i = 0; i < rts_n; i++) - g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_ip4_route_add (NM_PLATFORM_GET, NMP_NLM_FLAG_REPLACE, &rts_add[i]))); - - for (i = 0; i < rts_n; i++) { - rts_cmp[i] = rts_add[i]; - nm_platform_ip_route_normalize (AF_INET, NM_PLATFORM_IP_ROUTE_CAST (&rts_cmp[i])); - } - - routes = nmtstp_ip4_route_get_all (NM_PLATFORM_GET, IFINDEX); - g_assert_cmpint (routes->len, ==, rts_n); - nmtst_platform_ip4_routes_equal_aptr ((const NMPObject *const*) routes->pdata, rts_cmp, routes->len, TRUE); - - for (i = 0; i < rts_n; i++) { - g_assert (nmtstp_platform_ip4_route_delete (NM_PLATFORM_GET, IFINDEX, - rts_add[i].network, rts_add[i].plen, - rts_add[i].metric)); - } + NMPlatformIP4Route rts_add[RTS_MAX] = {}; + NMPlatformIP4Route rts_cmp[RTS_MAX] = {}; + NMPlatformIP4Address addr[1] = {}; + guint i; + guint rts_n = 0; + guint addr_n = 0; + + switch (TEST_IDX) { + case 1: + rts_add[rts_n++] = ((NMPlatformIP4Route){ + .ifindex = IFINDEX, + .rt_source = NM_IP_CONFIG_SOURCE_USER, + .network = nmtst_inet4_from_string("172.16.1.0"), + .plen = 24, + .metric = 20, + .tos = 0x28, + .window = 10000, + .cwnd = 16, + .initcwnd = 30, + .initrwnd = 50, + .mtu = 1350, + .lock_cwnd = TRUE, + }); + break; + case 2: + addr[addr_n++] = ((NMPlatformIP4Address){ + .ifindex = IFINDEX, + .address = nmtst_inet4_from_string("172.16.1.5"), + .peer_address = nmtst_inet4_from_string("172.16.1.5"), + .plen = 24, + .lifetime = NM_PLATFORM_LIFETIME_PERMANENT, + .preferred = NM_PLATFORM_LIFETIME_PERMANENT, + .n_ifa_flags = 0, + }); + rts_add[rts_n++] = ((NMPlatformIP4Route){ + .ifindex = IFINDEX, + .rt_source = NM_IP_CONFIG_SOURCE_USER, + .network = nmtst_inet4_from_string("172.17.1.0"), + .gateway = nmtst_inet4_from_string("172.16.1.1"), + .plen = 24, + .metric = 20, + }); + rts_add[rts_n++] = ((NMPlatformIP4Route){ + .ifindex = IFINDEX, + .rt_source = NM_IP_CONFIG_SOURCE_USER, + .network = nmtst_inet4_from_string("172.19.1.0"), + .gateway = nmtst_inet4_from_string("172.18.1.1"), + .r_rtm_flags = RTNH_F_ONLINK, + .plen = 24, + .metric = 20, + }); + break; + default: + g_assert_not_reached(); + break; + } + g_assert(rts_n <= G_N_ELEMENTS(rts_add)); + g_assert(addr_n <= G_N_ELEMENTS(addr)); + + for (i = 0; i < addr_n; i++) { + const NMPlatformIP4Address *a = &addr[i]; + + g_assert(a->ifindex == IFINDEX); + g_assert(nm_platform_ip4_address_add( + NM_PLATFORM_GET, + a->ifindex, + a->address, + a->plen, + a->peer_address, + nm_platform_ip4_broadcast_address_create(a->address, a->plen), + a->lifetime, + a->preferred, + a->n_ifa_flags, + a->label)); + if (a->peer_address == a->address) + _wait_for_ipv4_addr_device_route(NM_PLATFORM_GET, 200, a->ifindex, a->address, a->plen); + } + + for (i = 0; i < rts_n; i++) + g_assert(NMTST_NM_ERR_SUCCESS( + nm_platform_ip4_route_add(NM_PLATFORM_GET, NMP_NLM_FLAG_REPLACE, &rts_add[i]))); + + for (i = 0; i < rts_n; i++) { + rts_cmp[i] = rts_add[i]; + nm_platform_ip_route_normalize(AF_INET, NM_PLATFORM_IP_ROUTE_CAST(&rts_cmp[i])); + } + + routes = nmtstp_ip4_route_get_all(NM_PLATFORM_GET, IFINDEX); + g_assert_cmpint(routes->len, ==, rts_n); + nmtst_platform_ip4_routes_equal_aptr((const NMPObject *const *) routes->pdata, + rts_cmp, + routes->len, + TRUE); + + for (i = 0; i < rts_n; i++) { + g_assert(nmtstp_platform_ip4_route_delete(NM_PLATFORM_GET, + IFINDEX, + rts_add[i].network, + rts_add[i].plen, + rts_add[i].metric)); + } #undef RTS_MAX } static void -test_ip6_route_get (void) +test_ip6_route_get(void) { - int ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); - const struct in6_addr *a; - int result; - nm_auto_nmpobj NMPObject *route = NULL; - const NMPlatformIP6Route *r; - - nmtstp_run_command_check ("ip -6 route add fd01:abcd::/64 via fe80::99 dev %s", DEVICE_NAME); - - NMTST_WAIT_ASSERT (100, { - nmtstp_wait_for_signal (NM_PLATFORM_GET, 10); - if (nmtstp_ip6_route_get (NM_PLATFORM_GET, - ifindex, - nmtst_inet6_from_string ("fd01:abcd::"), - 64, - NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6, - NULL, - 0)) - break; - }); - - a = nmtst_inet6_from_string ("fd01:abcd::42"); - result = nm_platform_ip_route_get (NM_PLATFORM_GET, - AF_INET6, - a, - nmtst_get_rand_uint32 () % 2 ? 0 : ifindex, - &route); - - g_assert (NMTST_NM_ERR_SUCCESS (result)); - g_assert (NMP_OBJECT_GET_TYPE (route) == NMP_OBJECT_TYPE_IP6_ROUTE); - g_assert (!NMP_OBJECT_IS_STACKINIT (route)); - g_assert (route->parent._ref_count == 1); - r = NMP_OBJECT_CAST_IP6_ROUTE (route); - g_assert (r->ifindex == ifindex); - nmtst_assert_ip6_address (&r->network, "fd01:abcd::42"); - g_assert_cmpint (r->plen, ==, 128); - nmtst_assert_ip6_address (&r->gateway, "fe80::99"); - - nmtstp_run_command_check ("ip -6 route flush dev %s", DEVICE_NAME); - - nmtstp_wait_for_signal (NM_PLATFORM_GET, 50); + int ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME); + const struct in6_addr *a; + int result; + nm_auto_nmpobj NMPObject *route = NULL; + const NMPlatformIP6Route *r; + + nmtstp_run_command_check("ip -6 route add fd01:abcd::/64 via fe80::99 dev %s", DEVICE_NAME); + + NMTST_WAIT_ASSERT(100, { + nmtstp_wait_for_signal(NM_PLATFORM_GET, 10); + if (nmtstp_ip6_route_get(NM_PLATFORM_GET, + ifindex, + nmtst_inet6_from_string("fd01:abcd::"), + 64, + NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6, + NULL, + 0)) + break; + }); + + a = nmtst_inet6_from_string("fd01:abcd::42"); + result = nm_platform_ip_route_get(NM_PLATFORM_GET, + AF_INET6, + a, + nmtst_get_rand_uint32() % 2 ? 0 : ifindex, + &route); + + g_assert(NMTST_NM_ERR_SUCCESS(result)); + g_assert(NMP_OBJECT_GET_TYPE(route) == NMP_OBJECT_TYPE_IP6_ROUTE); + g_assert(!NMP_OBJECT_IS_STACKINIT(route)); + g_assert(route->parent._ref_count == 1); + r = NMP_OBJECT_CAST_IP6_ROUTE(route); + g_assert(r->ifindex == ifindex); + nmtst_assert_ip6_address(&r->network, "fd01:abcd::42"); + g_assert_cmpint(r->plen, ==, 128); + nmtst_assert_ip6_address(&r->gateway, "fe80::99"); + + nmtstp_run_command_check("ip -6 route flush dev %s", DEVICE_NAME); + + nmtstp_wait_for_signal(NM_PLATFORM_GET, 50); } static void -test_ip6_route_options (gconstpointer test_data) +test_ip6_route_options(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); - gs_unref_ptrarray GPtrArray *routes = NULL; + const int TEST_IDX = GPOINTER_TO_INT(test_data); + const int IFINDEX = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME); + gs_unref_ptrarray GPtrArray *routes = NULL; #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 (); - } - g_assert (rts_n <= G_N_ELEMENTS (rts_add)); - g_assert (addr_n <= G_N_ELEMENTS (addr)); - - 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 (NMTST_NM_ERR_SUCCESS (nm_platform_ip6_route_add (NM_PLATFORM_GET, NMP_NLM_FLAG_REPLACE, &rts_add[i]))); - - for (i = 0; i < rts_n; i++) { - rts_cmp[i] = rts_add[i]; - nm_platform_ip_route_normalize (AF_INET6, NM_PLATFORM_IP_ROUTE_CAST (&rts_cmp[i])); - } - - routes = nmtstp_ip6_route_get_all (NM_PLATFORM_GET, IFINDEX); - g_assert_cmpint (routes->len, ==, rts_n); - nmtst_platform_ip6_routes_equal_aptr ((const NMPObject *const*) routes->pdata, rts_cmp, routes->len, TRUE); - - 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); - } + 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(); + } + g_assert(rts_n <= G_N_ELEMENTS(rts_add)); + g_assert(addr_n <= G_N_ELEMENTS(addr)); + + 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(NMTST_NM_ERR_SUCCESS( + nm_platform_ip6_route_add(NM_PLATFORM_GET, NMP_NLM_FLAG_REPLACE, &rts_add[i]))); + + for (i = 0; i < rts_n; i++) { + rts_cmp[i] = rts_add[i]; + nm_platform_ip_route_normalize(AF_INET6, NM_PLATFORM_IP_ROUTE_CAST(&rts_cmp[i])); + } + + routes = nmtstp_ip6_route_get_all(NM_PLATFORM_GET, IFINDEX); + g_assert_cmpint(routes->len, ==, rts_n); + nmtst_platform_ip6_routes_equal_aptr((const NMPObject *const *) routes->pdata, + rts_cmp, + routes->len, + TRUE); + + 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); + } #undef RTS_MAX } /*****************************************************************************/ static void -test_ip (gconstpointer test_data) +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_uint32 () % 2)) { + 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_uint32() % 2)) { again_find_idx: - idx = nmtst_get_rand_uint32 () % 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 (NMTST_NM_ERR_SUCCESS (nm_platform_ip4_route_add (platform, NMP_NLM_FLAG_APPEND, r))); - } else { - i = nmtst_get_rand_uint32 () % 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_object_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; + idx = nmtst_get_rand_uint32() % 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( + NMTST_NM_ERR_SUCCESS(nm_platform_ip4_route_add(platform, NMP_NLM_FLAG_APPEND, r))); + } else { + i = nmtst_get_rand_uint32() % 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_object_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; } /*****************************************************************************/ -#define FRA_SUPPRESS_IFGROUP 13 -#define FRA_SUPPRESS_PREFIXLEN 14 -#define FRA_L3MDEV 19 -#define FRA_UID_RANGE 20 -#define FRA_PROTOCOL 21 -#define FRA_IP_PROTO 22 -#define FRA_SPORT_RANGE 23 -#define FRA_DPORT_RANGE 24 +#define FRA_SUPPRESS_IFGROUP 13 +#define FRA_SUPPRESS_PREFIXLEN 14 +#define FRA_L3MDEV 19 +#define FRA_UID_RANGE 20 +#define FRA_PROTOCOL 21 +#define FRA_IP_PROTO 22 +#define FRA_SPORT_RANGE 23 +#define FRA_DPORT_RANGE 24 static const NMPObject * -_rule_find_by_priority (NMPlatform *platform, - guint32 priority) +_rule_find_by_priority(NMPlatform *platform, guint32 priority) { - const NMDedupMultiHeadEntry *head_entry; - NMDedupMultiIter iter; - const NMPObject *o; - const NMPObject *obj = NULL; - NMPLookup lookup; - - nmp_lookup_init_obj_type (&lookup, NMP_OBJECT_TYPE_ROUTING_RULE); - head_entry = nm_platform_lookup (platform, &lookup); - nmp_cache_iter_for_each (&iter, head_entry, &o) { - if (NMP_OBJECT_CAST_ROUTING_RULE (o)->priority != priority) - continue; - g_assert (!obj); - obj = o; - } - return obj; + const NMDedupMultiHeadEntry *head_entry; + NMDedupMultiIter iter; + const NMPObject * o; + const NMPObject * obj = NULL; + NMPLookup lookup; + + nmp_lookup_init_obj_type(&lookup, NMP_OBJECT_TYPE_ROUTING_RULE); + head_entry = nm_platform_lookup(platform, &lookup); + nmp_cache_iter_for_each (&iter, head_entry, &o) { + if (NMP_OBJECT_CAST_ROUTING_RULE(o)->priority != priority) + continue; + g_assert(!obj); + obj = o; + } + return obj; } static const NMPObject * -_rule_check_kernel_support_one (NMPlatform *platform, - const NMPlatformRoutingRule *rr) +_rule_check_kernel_support_one(NMPlatform *platform, const NMPlatformRoutingRule *rr) { - nm_auto_nmpobj const NMPObject *obj = NULL; - int r; + nm_auto_nmpobj const NMPObject *obj = NULL; + int r; - g_assert (!_rule_find_by_priority (platform, rr->priority)); + g_assert(!_rule_find_by_priority(platform, rr->priority)); - r = nm_platform_routing_rule_add (platform, NMP_NLM_FLAG_ADD, rr); - g_assert_cmpint (r, ==, 0); + r = nm_platform_routing_rule_add(platform, NMP_NLM_FLAG_ADD, rr); + g_assert_cmpint(r, ==, 0); - obj = nmp_object_ref (_rule_find_by_priority (platform, rr->priority)); - g_assert (obj); + obj = nmp_object_ref(_rule_find_by_priority(platform, rr->priority)); + g_assert(obj); - r = nm_platform_object_delete (platform, obj); - g_assert_cmpint (r, ==, TRUE); + r = nm_platform_object_delete(platform, obj); + g_assert_cmpint(r, ==, TRUE); - g_assert (!_rule_find_by_priority (platform, rr->priority)); + g_assert(!_rule_find_by_priority(platform, rr->priority)); - return g_steal_pointer (&obj); + return g_steal_pointer(&obj); } static gboolean -_rule_check_kernel_support (NMPlatform *platform, - int attribute) +_rule_check_kernel_support(NMPlatform *platform, int attribute) { - static int support[] = { - [FRA_SUPPRESS_IFGROUP] = 0, - [FRA_SUPPRESS_PREFIXLEN] = 0, - [FRA_L3MDEV] = 0, - [FRA_UID_RANGE] = 0, - [FRA_PROTOCOL] = 0, - [FRA_IP_PROTO] = 0, - [FRA_SPORT_RANGE] = 0, - [FRA_DPORT_RANGE] = 0, - }; - const guint32 PROBE_PRORITY = 12033; - gboolean sup; - int i; - - g_assert (NM_IS_PLATFORM (platform)); - - if (attribute == -1) { - for (i = 0; i < G_N_ELEMENTS (support); i++) { - if (support[i] < 0) { - /* indicate that some test was skipped. */ - return FALSE; - } - } - return TRUE; - } - - g_assert (attribute >= 0 && attribute < G_N_ELEMENTS (support)); - - if (support[attribute] != 0) - return support[attribute] >= 0; - - switch (attribute) { - case FRA_SUPPRESS_IFGROUP: { - nm_auto_nmpobj const NMPObject *obj = NULL; - const NMPlatformRoutingRule rr = { - .addr_family = AF_INET, - .priority = PROBE_PRORITY, - .suppress_ifgroup_inverse = ~((guint32) 1245), - }; - - obj = _rule_check_kernel_support_one (platform, &rr); - - sup = NMP_OBJECT_CAST_ROUTING_RULE (obj)->suppress_prefixlen_inverse == rr.suppress_ifgroup_inverse; - break; - } - case FRA_SUPPRESS_PREFIXLEN: { - nm_auto_nmpobj const NMPObject *obj = NULL; - const NMPlatformRoutingRule rr = { - .addr_family = AF_INET, - .priority = PROBE_PRORITY, - .suppress_prefixlen_inverse = ~((guint32) 1245), - }; - - obj = _rule_check_kernel_support_one (platform, &rr); - - sup = NMP_OBJECT_CAST_ROUTING_RULE (obj)->suppress_prefixlen_inverse == rr.suppress_prefixlen_inverse; - break; - } - case FRA_L3MDEV: { - nm_auto_nmpobj const NMPObject *obj = NULL; - const NMPlatformRoutingRule rr = { - .addr_family = AF_INET, - .priority = PROBE_PRORITY, - .l3mdev = TRUE, - }; - - obj = _rule_check_kernel_support_one (platform, &rr); - - sup = NMP_OBJECT_CAST_ROUTING_RULE (obj)->l3mdev != 0; - break; - } - case FRA_UID_RANGE: { - nm_auto_nmpobj const NMPObject *obj = NULL; - const NMPlatformRoutingRule rr = { - .addr_family = AF_INET, - .priority = PROBE_PRORITY, - .uid_range = { - .start = 0, - .end = 0, - }, - .uid_range_has = TRUE, - }; - - obj = _rule_check_kernel_support_one (platform, &rr); - - sup = NMP_OBJECT_CAST_ROUTING_RULE (obj)->uid_range_has; - break; - } - case FRA_PROTOCOL: { - nm_auto_nmpobj const NMPObject *obj = NULL; - const NMPlatformRoutingRule rr = { - .addr_family = AF_INET, - .priority = PROBE_PRORITY, - .protocol = 30, - }; - - obj = _rule_check_kernel_support_one (platform, &rr); - - sup = NMP_OBJECT_CAST_ROUTING_RULE (obj)->protocol == 30; - break; - } - case FRA_IP_PROTO: { - nm_auto_nmpobj const NMPObject *obj = NULL; - const NMPlatformRoutingRule rr = { - .addr_family = AF_INET, - .priority = PROBE_PRORITY, - .ip_proto = 30, - }; - - obj = _rule_check_kernel_support_one (platform, &rr); - - sup = NMP_OBJECT_CAST_ROUTING_RULE (obj)->ip_proto == 30; - break; - } - case FRA_SPORT_RANGE: - case FRA_DPORT_RANGE: - /* these were added at the same time as FRA_IP_PROTO. */ - sup = _rule_check_kernel_support (platform, FRA_IP_PROTO); - break; - default: - g_assert_not_reached (); - return FALSE; - } - - support[attribute] = sup ? 1 : -1; - - _LOGD ("kernel support for routing rule attribute #%d %s", attribute, sup ? "detected" : "not detected"); - return sup; + static int support[] = { + [FRA_SUPPRESS_IFGROUP] = 0, + [FRA_SUPPRESS_PREFIXLEN] = 0, + [FRA_L3MDEV] = 0, + [FRA_UID_RANGE] = 0, + [FRA_PROTOCOL] = 0, + [FRA_IP_PROTO] = 0, + [FRA_SPORT_RANGE] = 0, + [FRA_DPORT_RANGE] = 0, + }; + const guint32 PROBE_PRORITY = 12033; + gboolean sup; + int i; + + g_assert(NM_IS_PLATFORM(platform)); + + if (attribute == -1) { + for (i = 0; i < G_N_ELEMENTS(support); i++) { + if (support[i] < 0) { + /* indicate that some test was skipped. */ + return FALSE; + } + } + return TRUE; + } + + g_assert(attribute >= 0 && attribute < G_N_ELEMENTS(support)); + + if (support[attribute] != 0) + return support[attribute] >= 0; + + switch (attribute) { + case FRA_SUPPRESS_IFGROUP: + { + nm_auto_nmpobj const NMPObject *obj = NULL; + const NMPlatformRoutingRule rr = { + .addr_family = AF_INET, + .priority = PROBE_PRORITY, + .suppress_ifgroup_inverse = ~((guint32) 1245), + }; + + obj = _rule_check_kernel_support_one(platform, &rr); + + sup = NMP_OBJECT_CAST_ROUTING_RULE(obj)->suppress_prefixlen_inverse + == rr.suppress_ifgroup_inverse; + break; + } + case FRA_SUPPRESS_PREFIXLEN: + { + nm_auto_nmpobj const NMPObject *obj = NULL; + const NMPlatformRoutingRule rr = { + .addr_family = AF_INET, + .priority = PROBE_PRORITY, + .suppress_prefixlen_inverse = ~((guint32) 1245), + }; + + obj = _rule_check_kernel_support_one(platform, &rr); + + sup = NMP_OBJECT_CAST_ROUTING_RULE(obj)->suppress_prefixlen_inverse + == rr.suppress_prefixlen_inverse; + break; + } + case FRA_L3MDEV: + { + nm_auto_nmpobj const NMPObject *obj = NULL; + const NMPlatformRoutingRule rr = { + .addr_family = AF_INET, + .priority = PROBE_PRORITY, + .l3mdev = TRUE, + }; + + obj = _rule_check_kernel_support_one(platform, &rr); + + sup = NMP_OBJECT_CAST_ROUTING_RULE(obj)->l3mdev != 0; + break; + } + case FRA_UID_RANGE: + { + nm_auto_nmpobj const NMPObject *obj = NULL; + const NMPlatformRoutingRule rr = { + .addr_family = AF_INET, + .priority = PROBE_PRORITY, + .uid_range = + { + .start = 0, + .end = 0, + }, + .uid_range_has = TRUE, + }; + + obj = _rule_check_kernel_support_one(platform, &rr); + + sup = NMP_OBJECT_CAST_ROUTING_RULE(obj)->uid_range_has; + break; + } + case FRA_PROTOCOL: + { + nm_auto_nmpobj const NMPObject *obj = NULL; + const NMPlatformRoutingRule rr = { + .addr_family = AF_INET, + .priority = PROBE_PRORITY, + .protocol = 30, + }; + + obj = _rule_check_kernel_support_one(platform, &rr); + + sup = NMP_OBJECT_CAST_ROUTING_RULE(obj)->protocol == 30; + break; + } + case FRA_IP_PROTO: + { + nm_auto_nmpobj const NMPObject *obj = NULL; + const NMPlatformRoutingRule rr = { + .addr_family = AF_INET, + .priority = PROBE_PRORITY, + .ip_proto = 30, + }; + + obj = _rule_check_kernel_support_one(platform, &rr); + + sup = NMP_OBJECT_CAST_ROUTING_RULE(obj)->ip_proto == 30; + break; + } + case FRA_SPORT_RANGE: + case FRA_DPORT_RANGE: + /* these were added at the same time as FRA_IP_PROTO. */ + sup = _rule_check_kernel_support(platform, FRA_IP_PROTO); + break; + default: + g_assert_not_reached(); + return FALSE; + } + + support[attribute] = sup ? 1 : -1; + + _LOGD("kernel support for routing rule attribute #%d %s", + attribute, + sup ? "detected" : "not detected"); + return sup; } static const NMPObject * -_platform_has_routing_rule (NMPlatform *platform, - const NMPObject *obj) +_platform_has_routing_rule(NMPlatform *platform, const NMPObject *obj) { - const NMPObject *o; + const NMPObject *o; - g_assert (NM_IS_PLATFORM (platform)); - g_assert (NMP_OBJECT_IS_VALID (obj)); - g_assert (NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_ROUTING_RULE); + g_assert(NM_IS_PLATFORM(platform)); + g_assert(NMP_OBJECT_IS_VALID(obj)); + g_assert(NMP_OBJECT_GET_TYPE(obj) == NMP_OBJECT_TYPE_ROUTING_RULE); - o = nm_platform_lookup_obj (platform, NMP_CACHE_ID_TYPE_OBJECT_TYPE, obj); - if (o) - g_assert (nm_platform_routing_rule_cmp (NMP_OBJECT_CAST_ROUTING_RULE (obj), NMP_OBJECT_CAST_ROUTING_RULE (o), NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID) == 0); + o = nm_platform_lookup_obj(platform, NMP_CACHE_ID_TYPE_OBJECT_TYPE, obj); + if (o) + g_assert(nm_platform_routing_rule_cmp(NMP_OBJECT_CAST_ROUTING_RULE(obj), + NMP_OBJECT_CAST_ROUTING_RULE(o), + NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID) + == 0); - return o; + return o; } static guint32 -_rr_rand_choose_u32 (guint32 p) +_rr_rand_choose_u32(guint32 p) { - /* mostly, we just return zero. We want that each rule only has few - * fields set -- having most fields at zero. */ - if ((p % 10000u) < 7500u) - return 0; + /* mostly, we just return zero. We want that each rule only has few + * fields set -- having most fields at zero. */ + if ((p % 10000u) < 7500u) + return 0; - /* give 0xFFFFFFFFu extra probability. */ - if ((p % 10000u) < 8250u) - return 0xFFFFFFFFu; + /* give 0xFFFFFFFFu extra probability. */ + if ((p % 10000u) < 8250u) + return 0xFFFFFFFFu; - /* choose a small number. */ - if ((p % 10000u) < 9125u) - return (~p) % 10; + /* choose a small number. */ + if ((p % 10000u) < 9125u) + return (~p) % 10; - /* finally, full random number. */ - return ~p; + /* finally, full random number. */ + return ~p; } -#define _rr_rand_choose_u8(p) ((guint8) _rr_rand_choose_u32 ((p))) +#define _rr_rand_choose_u8(p) ((guint8) _rr_rand_choose_u32((p))) static const NMPObject * -_rule_create_random (NMPlatform *platform) +_rule_create_random(NMPlatform *platform) { - NMPObject *obj; - NMPlatformRoutingRule *rr; - guint32 p; - int addr_size; - guint i; - char saddr[NM_UTILS_INET_ADDRSTRLEN]; - static struct { - guint32 uid; - guint32 euid; - bool initialized; - } uids; - - if (G_UNLIKELY (!uids.initialized)) { - uids.uid = getuid (); - uids.euid = geteuid (); - uids.initialized = TRUE; - } - - obj = nmp_object_new (NMP_OBJECT_TYPE_ROUTING_RULE, NULL); - rr = NMP_OBJECT_CAST_ROUTING_RULE (obj); - - rr->addr_family = nmtst_rand_select (AF_INET, AF_INET6); - - addr_size = nm_utils_addr_family_to_size (rr->addr_family); - - p = nmtst_get_rand_uint32 (); - if ((p % 1000u) < 50) - rr->priority = 10000 + ((~p) % 20u); - - p = nmtst_get_rand_uint32 (); - if ((p % 1000u) < 40) - nm_sprintf_buf (rr->iifname, "t-iif-%u", (~p) % 20); - else if ((p % 1000u) < 80) - nm_sprintf_buf (rr->iifname, "%s", DEVICE_NAME); - - p = nmtst_get_rand_uint32 (); - if ((p % 1000u) < 40) - nm_sprintf_buf (rr->oifname, "t-oif-%d", (~p) % 20); - else if ((p % 1000u) < 80) - nm_sprintf_buf (rr->oifname, "%s", DEVICE_NAME); - - for (i = 0; i < 2; i++) { - NMIPAddr *p_addr = i ? &rr->src : &rr->dst; - guint8 *p_len = i ? &rr->src_len : &rr->dst_len; - - p = nmtst_get_rand_uint32 (); - if ((p % 1000u) < 100) { - /* if we set src_len/dst_len to zero, the src/dst is actually ignored. - * - * For fuzzying, still set the address. It shall have no further effect. - * */ - *p_len = (~p) % (addr_size * 8 + 1); - p = nmtst_get_rand_uint32 (); - if ((p % 3u) == 0) { - if (rr->addr_family == AF_INET) - p_addr->addr4 = nmtst_inet4_from_string (nm_sprintf_buf (saddr, "192.192.5.%u", (~p) % 256u)); - else - p_addr->addr6 = *nmtst_inet6_from_string (nm_sprintf_buf (saddr, "1:2:3:4::f:%02x", (~p) % 256u)); - } else if ((p % 3u) == 1) - nmtst_rand_buf (NULL, p_addr, addr_size); - } - } - - p = nmtst_get_rand_uint32 (); - if ((p % 1000u) < 50) - rr->tun_id = 10000 + ((~p) % 20); + NMPObject * obj; + NMPlatformRoutingRule *rr; + guint32 p; + int addr_size; + guint i; + char saddr[NM_UTILS_INET_ADDRSTRLEN]; + static struct { + guint32 uid; + guint32 euid; + bool initialized; + } uids; + + if (G_UNLIKELY(!uids.initialized)) { + uids.uid = getuid(); + uids.euid = geteuid(); + uids.initialized = TRUE; + } + + obj = nmp_object_new(NMP_OBJECT_TYPE_ROUTING_RULE, NULL); + rr = NMP_OBJECT_CAST_ROUTING_RULE(obj); + + rr->addr_family = nmtst_rand_select(AF_INET, AF_INET6); + + addr_size = nm_utils_addr_family_to_size(rr->addr_family); + + p = nmtst_get_rand_uint32(); + if ((p % 1000u) < 50) + rr->priority = 10000 + ((~p) % 20u); + + p = nmtst_get_rand_uint32(); + if ((p % 1000u) < 40) + nm_sprintf_buf(rr->iifname, "t-iif-%u", (~p) % 20); + else if ((p % 1000u) < 80) + nm_sprintf_buf(rr->iifname, "%s", DEVICE_NAME); + + p = nmtst_get_rand_uint32(); + if ((p % 1000u) < 40) + nm_sprintf_buf(rr->oifname, "t-oif-%d", (~p) % 20); + else if ((p % 1000u) < 80) + nm_sprintf_buf(rr->oifname, "%s", DEVICE_NAME); + + for (i = 0; i < 2; i++) { + NMIPAddr *p_addr = i ? &rr->src : &rr->dst; + guint8 * p_len = i ? &rr->src_len : &rr->dst_len; + + p = nmtst_get_rand_uint32(); + if ((p % 1000u) < 100) { + /* if we set src_len/dst_len to zero, the src/dst is actually ignored. + * + * For fuzzying, still set the address. It shall have no further effect. + * */ + *p_len = (~p) % (addr_size * 8 + 1); + p = nmtst_get_rand_uint32(); + if ((p % 3u) == 0) { + if (rr->addr_family == AF_INET) + p_addr->addr4 = + nmtst_inet4_from_string(nm_sprintf_buf(saddr, "192.192.5.%u", (~p) % 256u)); + else + p_addr->addr6 = *nmtst_inet6_from_string( + nm_sprintf_buf(saddr, "1:2:3:4::f:%02x", (~p) % 256u)); + } else if ((p % 3u) == 1) + nmtst_rand_buf(NULL, p_addr, addr_size); + } + } + + p = nmtst_get_rand_uint32(); + if ((p % 1000u) < 50) + rr->tun_id = 10000 + ((~p) % 20); again_action: - p = nmtst_get_rand_uint32 (); - if ((p % 1000u) < 500) - rr->action = FR_ACT_UNSPEC; - else if ((p % 1000u) < 750) - rr->action = (~p) % 12u; - else - rr->action = (~p) % 0x100u; - - rr->priority = _rr_rand_choose_u32 (nmtst_get_rand_uint32 ()); - - if ( rr->action == FR_ACT_GOTO - && rr->priority == G_MAXINT32) - goto again_action; - - p = nmtst_get_rand_uint32 (); - if ((p % 10000u) < 100) - rr->goto_target = rr->priority + 1; - else - rr->goto_target = _rr_rand_choose_u32 (nmtst_get_rand_uint32 ()); - if ( rr->action == FR_ACT_GOTO - && rr->goto_target <= rr->priority) - goto again_action; - - p = nmtst_get_rand_uint32 (); - if ((p % 1000u) < 25) { - if (_rule_check_kernel_support (platform, FRA_L3MDEV)) { - rr->l3mdev = TRUE; - rr->table = RT_TABLE_UNSPEC; - } - } + p = nmtst_get_rand_uint32(); + if ((p % 1000u) < 500) + rr->action = FR_ACT_UNSPEC; + else if ((p % 1000u) < 750) + rr->action = (~p) % 12u; + else + rr->action = (~p) % 0x100u; + + rr->priority = _rr_rand_choose_u32(nmtst_get_rand_uint32()); + + if (rr->action == FR_ACT_GOTO && rr->priority == G_MAXINT32) + goto again_action; + + p = nmtst_get_rand_uint32(); + if ((p % 10000u) < 100) + rr->goto_target = rr->priority + 1; + else + rr->goto_target = _rr_rand_choose_u32(nmtst_get_rand_uint32()); + if (rr->action == FR_ACT_GOTO && rr->goto_target <= rr->priority) + goto again_action; + + p = nmtst_get_rand_uint32(); + if ((p % 1000u) < 25) { + if (_rule_check_kernel_support(platform, FRA_L3MDEV)) { + rr->l3mdev = TRUE; + rr->table = RT_TABLE_UNSPEC; + } + } again_table: - if (!rr->l3mdev) { - p = nmtst_get_rand_uint32 (); - if ((p % 1000u) < 700) - rr->table = RT_TABLE_UNSPEC; - else if ((p % 1000u) < 850) - rr->table = RT_TABLE_MAIN; - else - rr->table = 10000 + ((~p) % 10); - if ( rr->action == FR_ACT_TO_TBL - && rr->table == RT_TABLE_UNSPEC) - goto again_table; - } - - rr->fwmark = _rr_rand_choose_u32 (nmtst_get_rand_uint32 ()); - rr->fwmask = _rr_rand_choose_u32 (nmtst_get_rand_uint32 ()); - - rr->flow = _rr_rand_choose_u32 (nmtst_get_rand_uint32 ()); - - if (_rule_check_kernel_support (platform, FRA_PROTOCOL)) - rr->protocol = _rr_rand_choose_u8 (nmtst_get_rand_uint32 ()); + if (!rr->l3mdev) { + p = nmtst_get_rand_uint32(); + if ((p % 1000u) < 700) + rr->table = RT_TABLE_UNSPEC; + else if ((p % 1000u) < 850) + rr->table = RT_TABLE_MAIN; + else + rr->table = 10000 + ((~p) % 10); + if (rr->action == FR_ACT_TO_TBL && rr->table == RT_TABLE_UNSPEC) + goto again_table; + } + + rr->fwmark = _rr_rand_choose_u32(nmtst_get_rand_uint32()); + rr->fwmask = _rr_rand_choose_u32(nmtst_get_rand_uint32()); + + rr->flow = _rr_rand_choose_u32(nmtst_get_rand_uint32()); + + if (_rule_check_kernel_support(platform, FRA_PROTOCOL)) + rr->protocol = _rr_rand_choose_u8(nmtst_get_rand_uint32()); #define IPTOS_TOS_MASK 0x1E again_tos: - rr->tos = _rr_rand_choose_u8 (nmtst_get_rand_uint32 ()); - if ( rr->addr_family == AF_INET - && rr->tos & ~IPTOS_TOS_MASK) - goto again_tos; + rr->tos = _rr_rand_choose_u8(nmtst_get_rand_uint32()); + if (rr->addr_family == AF_INET && rr->tos & ~IPTOS_TOS_MASK) + goto again_tos; - if (_rule_check_kernel_support (platform, FRA_IP_PROTO)) - rr->ip_proto = _rr_rand_choose_u8 (nmtst_get_rand_uint32 ()); + if (_rule_check_kernel_support(platform, FRA_IP_PROTO)) + rr->ip_proto = _rr_rand_choose_u8(nmtst_get_rand_uint32()); - if (_rule_check_kernel_support (platform, FRA_SUPPRESS_PREFIXLEN)) - rr->suppress_prefixlen_inverse = ~_rr_rand_choose_u32 (nmtst_get_rand_uint32 ()); + if (_rule_check_kernel_support(platform, FRA_SUPPRESS_PREFIXLEN)) + rr->suppress_prefixlen_inverse = ~_rr_rand_choose_u32(nmtst_get_rand_uint32()); - if (_rule_check_kernel_support (platform, FRA_SUPPRESS_IFGROUP)) - rr->suppress_ifgroup_inverse = ~_rr_rand_choose_u32 (nmtst_get_rand_uint32 ()); + if (_rule_check_kernel_support(platform, FRA_SUPPRESS_IFGROUP)) + rr->suppress_ifgroup_inverse = ~_rr_rand_choose_u32(nmtst_get_rand_uint32()); - if (_rule_check_kernel_support (platform, FRA_UID_RANGE)) { - p = nmtst_get_rand_uint32 (); - rr->uid_range_has = (p % 10000u) < 200; - } + if (_rule_check_kernel_support(platform, FRA_UID_RANGE)) { + p = nmtst_get_rand_uint32(); + rr->uid_range_has = (p % 10000u) < 200; + } again_uid_range: - rr->uid_range.start = nmtst_rand_select (0u, uids.uid, uids.euid); - rr->uid_range.end = nmtst_rand_select (0u, uids.uid, uids.euid); - if (rr->uid_range_has) { - if (rr->uid_range.end < rr->uid_range.start) - NM_SWAP (rr->uid_range.start, rr->uid_range.end); - if ( rr->uid_range.start == ((guint32) -1) - || rr->uid_range.end == ((guint32) -1)) - goto again_uid_range; - } - - for (i = 0; i < 2; i++) { - NMFibRulePortRange *range = i ? &rr->sport_range : &rr->dport_range; - int attribute = i ? FRA_SPORT_RANGE : FRA_DPORT_RANGE; - - if (!_rule_check_kernel_support (platform, attribute)) - continue; - - p = nmtst_get_rand_uint32 (); - if ((p % 10000u) < 300) { - while (range->start == 0) { - p = p ^ nmtst_get_rand_uint32 (); - range->start = nmtst_rand_select (1u, 0xFFFEu, ((p ) % 0xFFFEu) + 1); - range->end = nmtst_rand_select (1u, 0xFFFEu, ((p >> 16) % 0xFFFEu) + 1, range->start); - if (range->end < range->start) - NM_SWAP (range->start, range->end); - } - } - } - - p = nmtst_get_rand_uint32 () % 1000u; - if (p < 100) - rr->flags |= FIB_RULE_INVERT; - - return obj; + rr->uid_range.start = nmtst_rand_select(0u, uids.uid, uids.euid); + rr->uid_range.end = nmtst_rand_select(0u, uids.uid, uids.euid); + if (rr->uid_range_has) { + if (rr->uid_range.end < rr->uid_range.start) + NM_SWAP(&rr->uid_range.start, &rr->uid_range.end); + if (rr->uid_range.start == ((guint32) -1) || rr->uid_range.end == ((guint32) -1)) + goto again_uid_range; + } + + for (i = 0; i < 2; i++) { + NMFibRulePortRange *range = i ? &rr->sport_range : &rr->dport_range; + int attribute = i ? FRA_SPORT_RANGE : FRA_DPORT_RANGE; + + if (!_rule_check_kernel_support(platform, attribute)) + continue; + + p = nmtst_get_rand_uint32(); + if ((p % 10000u) < 300) { + while (range->start == 0) { + p = p ^ nmtst_get_rand_uint32(); + range->start = nmtst_rand_select(1u, 0xFFFEu, ((p) % 0xFFFEu) + 1); + range->end = + nmtst_rand_select(1u, 0xFFFEu, ((p >> 16) % 0xFFFEu) + 1, range->start); + if (range->end < range->start) + NM_SWAP(&range->start, &range->end); + } + } + } + + p = nmtst_get_rand_uint32() % 1000u; + if (p < 100) + rr->flags |= FIB_RULE_INVERT; + + return obj; } static gboolean -_rule_fuzzy_equal (const NMPObject *obj, - const NMPObject *obj_comp, - int op_type) +_rule_fuzzy_equal(const NMPObject *obj, const NMPObject *obj_comp, int op_type) { - const NMPlatformRoutingRule *rr = NMP_OBJECT_CAST_ROUTING_RULE (obj); - NMPlatformRoutingRule rr_co = *NMP_OBJECT_CAST_ROUTING_RULE (obj_comp); - - switch (op_type) { - case RTM_NEWRULE: - /* when adding rules with RTM_NEWRULE, kernel checks whether an existing - * rule already exists and may fail with EEXIST. This check has issues - * and reject legitimate rules (rh#1686075). - * - * Work around that. */ - if (rr->src_len == 0) - rr_co.src_len = 0; - if (rr->dst_len == 0) - rr_co.dst_len = 0; - if (rr->flow == 0) - rr_co.flow = 0; - if (rr->tos == 0) - rr_co.tos = 0; - rr_co.suppress_prefixlen_inverse = rr->suppress_prefixlen_inverse; - rr_co.suppress_ifgroup_inverse = rr->suppress_ifgroup_inverse; - if (!NM_FLAGS_HAS (rr->flags, FIB_RULE_INVERT)) - rr_co.flags &= ~((guint32) FIB_RULE_INVERT); - else - rr_co.flags |= ((guint32) FIB_RULE_INVERT); - break; - case RTM_DELRULE: - /* when deleting a rule with RTM_DELRULE, kernel tries to find the - * cadidate to delete. It might delete the wrong rule (rh#1685816). */ - if (rr->action == FR_ACT_UNSPEC) - rr_co.action = FR_ACT_UNSPEC; - if (rr->iifname[0] == '\0') - rr_co.iifname[0] = '\0'; - if (rr->oifname[0] == '\0') - rr_co.oifname[0] = '\0'; - if (rr->src_len == 0) - rr_co.src_len = 0; - if (rr->dst_len == 0) - rr_co.dst_len = 0; - if (rr->tun_id == 0) - rr_co.tun_id = 0; - if (rr->fwmark == 0) - rr_co.fwmark = 0; - if (rr->fwmask == 0) - rr_co.fwmask = 0; - if (rr->flow == 0) - rr_co.flow = 0; - if (rr->protocol == 0) - rr_co.protocol = 0; - if (rr->table == RT_TABLE_UNSPEC) - rr_co.table = RT_TABLE_UNSPEC; - if (rr->l3mdev == 0) - rr_co.l3mdev = 0; - if (rr->tos == 0) - rr_co.tos = 0; - if (rr->ip_proto == 0) - rr_co.ip_proto = 0; - rr_co.suppress_prefixlen_inverse = rr->suppress_prefixlen_inverse; - if (rr->suppress_ifgroup_inverse == 0) - rr_co.suppress_ifgroup_inverse = 0; - if (!rr->uid_range_has) - rr_co.uid_range_has = FALSE; - if (rr->sport_range.start == 0 && rr->sport_range.end == 0) { - rr_co.sport_range.start = 0; - rr_co.sport_range.end = 0; - } - if (rr->dport_range.start == 0 && rr->dport_range.end == 0) { - rr_co.dport_range.start = 0; - rr_co.dport_range.end = 0; - } - if (!NM_FLAGS_HAS (rr->flags, FIB_RULE_INVERT)) - rr_co.flags &= ~((guint32) FIB_RULE_INVERT); - else - rr_co.flags |= ((guint32) FIB_RULE_INVERT); - break; - default: - g_assert_not_reached (); - break; - } - - return nm_platform_routing_rule_cmp (rr, &rr_co, NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID) == 0; + const NMPlatformRoutingRule *rr = NMP_OBJECT_CAST_ROUTING_RULE(obj); + NMPlatformRoutingRule rr_co = *NMP_OBJECT_CAST_ROUTING_RULE(obj_comp); + + switch (op_type) { + case RTM_NEWRULE: + /* when adding rules with RTM_NEWRULE, kernel checks whether an existing + * rule already exists and may fail with EEXIST. This check has issues + * and reject legitimate rules (rh#1686075). + * + * Work around that. */ + if (rr->src_len == 0) + rr_co.src_len = 0; + if (rr->dst_len == 0) + rr_co.dst_len = 0; + if (rr->flow == 0) + rr_co.flow = 0; + if (rr->tos == 0) + rr_co.tos = 0; + rr_co.suppress_prefixlen_inverse = rr->suppress_prefixlen_inverse; + rr_co.suppress_ifgroup_inverse = rr->suppress_ifgroup_inverse; + if (!NM_FLAGS_HAS(rr->flags, FIB_RULE_INVERT)) + rr_co.flags &= ~((guint32) FIB_RULE_INVERT); + else + rr_co.flags |= ((guint32) FIB_RULE_INVERT); + break; + case RTM_DELRULE: + /* when deleting a rule with RTM_DELRULE, kernel tries to find the + * candidate to delete. It might delete the wrong rule (rh#1685816). */ + if (rr->action == FR_ACT_UNSPEC) + rr_co.action = FR_ACT_UNSPEC; + if (rr->iifname[0] == '\0') + rr_co.iifname[0] = '\0'; + if (rr->oifname[0] == '\0') + rr_co.oifname[0] = '\0'; + if (rr->src_len == 0) + rr_co.src_len = 0; + if (rr->dst_len == 0) + rr_co.dst_len = 0; + if (rr->tun_id == 0) + rr_co.tun_id = 0; + if (rr->fwmark == 0) + rr_co.fwmark = 0; + if (rr->fwmask == 0) + rr_co.fwmask = 0; + if (rr->flow == 0) + rr_co.flow = 0; + if (rr->protocol == 0) + rr_co.protocol = 0; + if (rr->table == RT_TABLE_UNSPEC) + rr_co.table = RT_TABLE_UNSPEC; + if (rr->l3mdev == 0) + rr_co.l3mdev = 0; + if (rr->tos == 0) + rr_co.tos = 0; + if (rr->ip_proto == 0) + rr_co.ip_proto = 0; + rr_co.suppress_prefixlen_inverse = rr->suppress_prefixlen_inverse; + if (rr->suppress_ifgroup_inverse == 0) + rr_co.suppress_ifgroup_inverse = 0; + if (!rr->uid_range_has) + rr_co.uid_range_has = FALSE; + if (rr->sport_range.start == 0 && rr->sport_range.end == 0) { + rr_co.sport_range.start = 0; + rr_co.sport_range.end = 0; + } + if (rr->dport_range.start == 0 && rr->dport_range.end == 0) { + rr_co.dport_range.start = 0; + rr_co.dport_range.end = 0; + } + if (!NM_FLAGS_HAS(rr->flags, FIB_RULE_INVERT)) + rr_co.flags &= ~((guint32) FIB_RULE_INVERT); + else + rr_co.flags |= ((guint32) FIB_RULE_INVERT); + break; + default: + g_assert_not_reached(); + break; + } + + return nm_platform_routing_rule_cmp(rr, &rr_co, NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID) == 0; } static void -test_rule (gconstpointer test_data) +test_rule(gconstpointer test_data) { - const int TEST_IDX = GPOINTER_TO_INT (test_data); - const gboolean TEST_SYNC = (TEST_IDX == 4); - gs_unref_ptrarray GPtrArray *objs = NULL; - gs_unref_ptrarray GPtrArray *objs_initial = NULL; - NMPlatform *platform = NM_PLATFORM_GET; - guint i, j, n; - int r; - gboolean had_an_issue_exist = FALSE; - - nm_platform_process_events (platform); - - objs_initial = nmtstp_platform_routing_rules_get_all (platform, AF_UNSPEC); - g_assert (objs_initial); - g_assert_cmpint (objs_initial->len, ==, 5); - - nmtstp_run_command_check ("ip rule add table 766"); - nm_platform_process_events (platform); - - for (i = 6; i > 0; i--) { - gs_unref_ptrarray GPtrArray *objs_extern = NULL; - const NMPObject *obj; - - objs_extern = nmtstp_platform_routing_rules_get_all (platform, AF_UNSPEC); - - g_assert (objs_extern); - g_assert_cmpint (objs_extern->len, ==, i); - - if (TEST_IDX != 1) - nmtst_rand_perm (NULL, objs_extern->pdata, NULL, sizeof (gpointer), objs_extern->len); - - obj = objs_extern->pdata[0]; - - r = nm_platform_object_delete (platform, obj); - g_assert_cmpint (r, ==, TRUE); - - g_assert (!_platform_has_routing_rule (platform, obj)); - } - - g_assert_cmpint (nmtstp_platform_routing_rules_get_count (platform, AF_UNSPEC), ==, 0); - -#define RR(...) \ - nmp_object_new (NMP_OBJECT_TYPE_ROUTING_RULE, \ - (const NMPlatformObject *) &((NMPlatformRoutingRule) { \ - __VA_ARGS__ \ - })) - - objs = g_ptr_array_new_with_free_func ((GDestroyNotify) nmp_object_unref); - - g_ptr_array_add (objs, RR ( - .addr_family = AF_INET, - .priority = 10, - )); - - g_ptr_array_add (objs, RR ( - .addr_family = AF_INET, - .priority = 400, - .action = FR_ACT_GOTO, - .goto_target = 10000, - )); - - g_ptr_array_add (objs, RR ( - .addr_family = AF_INET6, - )); - - g_ptr_array_add (objs, RR ( - .addr_family = AF_INET6, - .action = FR_ACT_TO_TBL, - .table = RT_TABLE_MAIN, - )); - - g_ptr_array_add (objs, RR ( - .addr_family = AF_INET6, - .priority = 30, - )); - - g_ptr_array_add (objs, RR ( - .addr_family = AF_INET6, - .priority = 50, - .iifname = "t-iif-1", - )); - - g_ptr_array_add (objs, RR ( - .addr_family = AF_INET6, - .priority = 50, - .iifname = "t-oif-1", - )); - - g_ptr_array_add (objs, RR ( - .addr_family = AF_INET, - .priority = 50, - .iifname = "t-oif-2", - )); - - g_ptr_array_add (objs, RR ( - .addr_family = AF_INET, - .priority = 51, - .iifname = DEVICE_NAME, - )); - - if (TEST_IDX == 1) { - g_ptr_array_add (objs, RR ( - .addr_family = AF_INET, - .table = 10000, - )); - } - - if (TEST_IDX != 1) { - nmtst_rand_perm (NULL, objs->pdata, NULL, sizeof (gpointer), objs->len); - g_ptr_array_set_size (objs, nmtst_get_rand_uint32 () % (objs->len + 1)); - } - - n = (TEST_IDX != 1) ? nmtst_get_rand_uint32 () % 50u : 0u; - for (i = 0; i < n; i++) { - nm_auto_nmpobj const NMPObject *o = NULL; - guint try = 0; + const int TEST_IDX = GPOINTER_TO_INT(test_data); + const gboolean TEST_SYNC = (TEST_IDX == 4); + gs_unref_ptrarray GPtrArray *objs = NULL; + gs_unref_ptrarray GPtrArray *objs_initial = NULL; + NMPlatform * platform = NM_PLATFORM_GET; + guint i, j, n; + int r; + gboolean had_an_issue_exist = FALSE; + + nm_platform_process_events(platform); + + objs_initial = nmtstp_platform_routing_rules_get_all(platform, AF_UNSPEC); + g_assert(objs_initial); + g_assert_cmpint(objs_initial->len, ==, 5); + + nmtstp_run_command_check("ip rule add table 766"); + nm_platform_process_events(platform); + + for (i = 6; i > 0; i--) { + gs_unref_ptrarray GPtrArray *objs_extern = NULL; + const NMPObject * obj; + + objs_extern = nmtstp_platform_routing_rules_get_all(platform, AF_UNSPEC); + + g_assert(objs_extern); + g_assert_cmpint(objs_extern->len, ==, i); + + if (TEST_IDX != 1) + nmtst_rand_perm(NULL, objs_extern->pdata, NULL, sizeof(gpointer), objs_extern->len); + + obj = objs_extern->pdata[0]; + + r = nm_platform_object_delete(platform, obj); + g_assert_cmpint(r, ==, TRUE); + + g_assert(!_platform_has_routing_rule(platform, obj)); + } + + g_assert_cmpint(nmtstp_platform_routing_rules_get_count(platform, AF_UNSPEC), ==, 0); + +#define RR(...) \ + nmp_object_new(NMP_OBJECT_TYPE_ROUTING_RULE, \ + (const NMPlatformObject *) &((NMPlatformRoutingRule){__VA_ARGS__})) + + objs = g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref); + + g_ptr_array_add(objs, RR(.addr_family = AF_INET, .priority = 10, )); + + g_ptr_array_add( + objs, + RR(.addr_family = AF_INET, .priority = 400, .action = FR_ACT_GOTO, .goto_target = 10000, )); + + g_ptr_array_add(objs, RR(.addr_family = AF_INET6, )); + + g_ptr_array_add(objs, + RR(.addr_family = AF_INET6, .action = FR_ACT_TO_TBL, .table = RT_TABLE_MAIN, )); + + g_ptr_array_add(objs, RR(.addr_family = AF_INET6, .priority = 30, )); + + g_ptr_array_add(objs, RR(.addr_family = AF_INET6, .priority = 50, .iifname = "t-iif-1", )); + + g_ptr_array_add(objs, RR(.addr_family = AF_INET6, .priority = 50, .iifname = "t-oif-1", )); + + g_ptr_array_add(objs, RR(.addr_family = AF_INET, .priority = 50, .iifname = "t-oif-2", )); + + g_ptr_array_add(objs, RR(.addr_family = AF_INET, .priority = 51, .iifname = DEVICE_NAME, )); + + if (TEST_IDX == 1) { + g_ptr_array_add(objs, RR(.addr_family = AF_INET, .table = 10000, )); + } + + if (TEST_IDX != 1) { + nmtst_rand_perm(NULL, objs->pdata, NULL, sizeof(gpointer), objs->len); + g_ptr_array_set_size(objs, nmtst_get_rand_uint32() % (objs->len + 1)); + } + + n = (TEST_IDX != 1) ? nmtst_get_rand_uint32() % 50u : 0u; + for (i = 0; i < n; i++) { + nm_auto_nmpobj const NMPObject *o = NULL; + guint try = 0; again: - o = _rule_create_random (platform); - for (j = 0; j < objs->len; j++) { - if (nm_platform_routing_rule_cmp (NMP_OBJECT_CAST_ROUTING_RULE (o), - NMP_OBJECT_CAST_ROUTING_RULE (objs->pdata[j]), - NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID) == 0) { - try++; - g_assert (try < 200); - nm_clear_pointer (&o, nmp_object_unref); - goto again; - } - } - g_ptr_array_add (objs, (gpointer) g_steal_pointer (&o)); - } - - if (TEST_IDX != 1) - nmtst_rand_perm (NULL, objs->pdata, NULL, sizeof (gpointer), objs->len); - - if (TEST_SYNC) { - gs_unref_hashtable GHashTable *unique_priorities = g_hash_table_new (NULL, NULL); - nm_auto_unref_rules_manager NMPRulesManager *rules_manager = nmp_rules_manager_new (platform); - gs_unref_ptrarray GPtrArray *objs_sync = NULL; - gconstpointer USER_TAG_1 = &platform; - gconstpointer USER_TAG_2 = &unique_priorities; - - objs_sync = g_ptr_array_new_with_free_func ((GDestroyNotify) nmp_object_unref); - - /* ensure that priorities are unique. Otherwise it confuses the test, because - * kernel may wrongly be unable to add/delete routes based on a wrong match - * (rh#1685816, rh#1685816). */ - for (i = 0; i < objs->len; i++) { - const NMPObject *obj = objs->pdata[i]; - guint32 prio = NMP_OBJECT_CAST_ROUTING_RULE (obj)->priority; - - if ( !NM_IN_SET (prio, 0, 32766, 32767) - && !g_hash_table_contains (unique_priorities, GUINT_TO_POINTER (prio))) { - g_hash_table_add (unique_priorities, GUINT_TO_POINTER (prio)); - g_ptr_array_add (objs_sync, (gpointer) nmp_object_ref (obj)); - } - } - - for (i = 0; i < objs_sync->len; i++) { - nmp_rules_manager_track (rules_manager, - NMP_OBJECT_CAST_ROUTING_RULE (objs_sync->pdata[i]), - 1, - USER_TAG_1, - NULL); - if (nmtst_get_rand_bool ()) { - /* this has no effect, because a negative priority (of same absolute value) - * has lower priority than the positive priority above. */ - nmp_rules_manager_track (rules_manager, - NMP_OBJECT_CAST_ROUTING_RULE (objs_sync->pdata[i]), - -1, - USER_TAG_2, - NULL); - } - if (nmtst_get_rand_uint32 () % objs_sync->len == 0) { - nmp_rules_manager_sync (rules_manager, FALSE); - g_assert_cmpint (nmtstp_platform_routing_rules_get_count (platform, AF_UNSPEC), ==, i + 1); - } - } - - nmp_rules_manager_sync (rules_manager, FALSE); - g_assert_cmpint (nmtstp_platform_routing_rules_get_count (platform, AF_UNSPEC), ==, objs_sync->len); - - for (i = 0; i < objs_sync->len; i++) { - switch (nmtst_get_rand_uint32 () % 3) { - case 0: - nmp_rules_manager_untrack (rules_manager, - NMP_OBJECT_CAST_ROUTING_RULE (objs_sync->pdata[i]), - USER_TAG_1); - nmp_rules_manager_untrack (rules_manager, - NMP_OBJECT_CAST_ROUTING_RULE (objs_sync->pdata[i]), - USER_TAG_1); - break; - case 1: - nmp_rules_manager_track (rules_manager, - NMP_OBJECT_CAST_ROUTING_RULE (objs_sync->pdata[i]), - -1, - USER_TAG_1, - NULL); - break; - case 2: - nmp_rules_manager_track (rules_manager, - NMP_OBJECT_CAST_ROUTING_RULE (objs_sync->pdata[i]), - -2, - USER_TAG_2, - NULL); - break; - } - if (nmtst_get_rand_uint32 () % objs_sync->len == 0) { - nmp_rules_manager_sync (rules_manager, FALSE); - g_assert_cmpint (nmtstp_platform_routing_rules_get_count (platform, AF_UNSPEC), ==, objs_sync->len - i - 1); - } - } - - nmp_rules_manager_sync (rules_manager, FALSE); - - } else { - for (i = 0; i < objs->len;) { - const NMPObject *obj = objs->pdata[i]; - - for (j = 0; j < objs->len; j++) - g_assert ((j < i) == (!!_platform_has_routing_rule (platform, objs->pdata[j]))); - - r = nm_platform_routing_rule_add (platform, NMP_NLM_FLAG_ADD, NMP_OBJECT_CAST_ROUTING_RULE (obj)); - - if (r == -EEXIST) { - g_assert (!_platform_has_routing_rule (platform, obj)); - /* this should not happen, but there are bugs in kernel (rh#1686075). */ - for (j = 0; j < i; j++) { - const NMPObject *obj2 = objs->pdata[j]; - - g_assert (_platform_has_routing_rule (platform, obj2)); - - if (_rule_fuzzy_equal (obj, obj2, RTM_NEWRULE)) { - r = 0; - break; - } - } - if (r == 0) { - /* OK, the rule is shadowed by another rule, and kernel does not allow - * us to add this one (rh#1686075). Drop this from the test. */ - g_ptr_array_remove_index (objs, i); - had_an_issue_exist = TRUE; - continue; - } - } - - if (r != 0) { - NMPLookup lookup; - const NMDedupMultiHeadEntry *head_entry; - NMDedupMultiIter iter; - const NMPObject *o; - - g_print (">>> failing... errno=%d, rule=%s\n", r, nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_ALL, NULL, 0)); - - nmp_lookup_init_obj_type (&lookup, NMP_OBJECT_TYPE_ROUTING_RULE); - head_entry = nm_platform_lookup (platform, &lookup); - nmp_cache_iter_for_each (&iter, head_entry, &o) { - char ch = ' '; - - if ( NMP_OBJECT_CAST_ROUTING_RULE (o)->addr_family == NMP_OBJECT_CAST_ROUTING_RULE (obj)->addr_family - && NMP_OBJECT_CAST_ROUTING_RULE (o)->priority == NMP_OBJECT_CAST_ROUTING_RULE (obj)->priority) - ch = '*'; - g_print (">>> existing rule: %c %s\n", ch, nmp_object_to_string (o, NMP_OBJECT_TO_STRING_ALL, NULL, 0)); - } - - nmtstp_run_command_check ("ip rule"); - nmtstp_run_command_check ("ip -6 rule"); - g_assert_cmpint (r, ==, 0); - } - - g_assert (_platform_has_routing_rule (platform, obj)); - - g_assert_cmpint (nmtstp_platform_routing_rules_get_count (platform, AF_UNSPEC), ==, i + 1); - - i++; - } - - if (TEST_IDX != 1) - nmtst_rand_perm (NULL, objs->pdata, NULL, sizeof (gpointer), objs->len); - - if (_LOGD_ENABLED ()) { - nmtstp_run_command_check ("ip rule"); - nmtstp_run_command_check ("ip -6 rule"); - } - - for (i = 0; i < objs->len; i++) { - const NMPObject *obj = objs->pdata[i]; - const NMPObject *obj2; - - for (j = 0; j < objs->len; j++) - g_assert ((j < i) == (!_platform_has_routing_rule (platform, objs->pdata[j]))); - - g_assert (_platform_has_routing_rule (platform, obj)); - - r = nm_platform_object_delete (platform, obj); - g_assert_cmpint (r, ==, TRUE); - - obj2 = _platform_has_routing_rule (platform, obj); - - if (obj2) { - guint k; - - /* When deleting a rule, kernel does a fuzzy match, ignoring for example: - * - action, if it is FR_ACT_UNSPEC - * - iifname,oifname if it is unspecified - * rh#1685816 - * - * That means, we may have deleted the wrong rule. Which one? */ - k = i; - for (j = i + 1; j < objs->len; j++) { - if (!_platform_has_routing_rule (platform, objs->pdata[j])) { - g_assert_cmpint (k, ==, i); - k = j; - } - } - g_assert_cmpint (k, >, i); - - if (!_rule_fuzzy_equal (obj, objs->pdata[k], RTM_DELRULE)) { - g_print (">>> failing...\n"); - g_print (">>> no fuzzy match between: %s\n", nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_ALL, NULL, 0)); - g_print (">>> and: %s\n", nmp_object_to_string (objs->pdata[k], NMP_OBJECT_TO_STRING_ALL, NULL, 0)); - g_assert_not_reached (); - } - - objs->pdata[i] = objs->pdata[k]; - objs->pdata[k] = (gpointer) obj; - obj2 = NULL; - } - - g_assert (!obj2); - - g_assert_cmpint (nmtstp_platform_routing_rules_get_count (platform, AF_UNSPEC), ==, objs->len -i - 1); - } - } - - g_assert_cmpint (nmtstp_platform_routing_rules_get_count (platform, AF_UNSPEC), ==, 0); - - for (i = 0; i < objs_initial->len; i++) { - const NMPObject *obj = objs_initial->pdata[i]; - - for (j = 0; j < objs_initial->len; j++) - g_assert ((j < i) == (!!_platform_has_routing_rule (platform, objs_initial->pdata[j]))); - - r = nm_platform_routing_rule_add (platform, NMP_NLM_FLAG_ADD, NMP_OBJECT_CAST_ROUTING_RULE (obj)); - g_assert_cmpint (r, ==, 0); - } - for (j = 0; j < objs_initial->len; j++) - g_assert (_platform_has_routing_rule (platform, objs_initial->pdata[j])); - g_assert_cmpint (nmtstp_platform_routing_rules_get_count (platform, AF_UNSPEC), ==, objs_initial->len); - - /* the tests passed as good as we could (as good as we implemented workarounds for them). - * Still, with this kernel, not all features were fully tested. Mark the test as skipped. */ - if (had_an_issue_exist) - g_test_skip ("adding a rule failed with EEXIST although it should not (rh#1686075)"); - else if (!_rule_check_kernel_support (platform, -1)) - g_test_skip ("some kernel features were not available and skipped for the test"); + o = _rule_create_random(platform); + for (j = 0; j < objs->len; j++) { + if (nm_platform_routing_rule_cmp(NMP_OBJECT_CAST_ROUTING_RULE(o), + NMP_OBJECT_CAST_ROUTING_RULE(objs->pdata[j]), + NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID) + == 0) { + try++; + g_assert(try < 200); + nm_clear_pointer(&o, nmp_object_unref); + goto again; + } + } + g_ptr_array_add(objs, (gpointer) g_steal_pointer(&o)); + } + + if (TEST_IDX != 1) + nmtst_rand_perm(NULL, objs->pdata, NULL, sizeof(gpointer), objs->len); + + if (TEST_SYNC) { + gs_unref_hashtable GHashTable *unique_priorities = g_hash_table_new(NULL, NULL); + nm_auto_unref_rules_manager NMPRulesManager *rules_manager = + nmp_rules_manager_new(platform); + gs_unref_ptrarray GPtrArray *objs_sync = NULL; + gconstpointer USER_TAG_1 = &platform; + gconstpointer USER_TAG_2 = &unique_priorities; + + objs_sync = g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref); + + /* ensure that priorities are unique. Otherwise, it confuses the test, because + * kernel may wrongly be unable to add/delete routes based on a wrong match + * (rh#1685816, rh#1685816). */ + for (i = 0; i < objs->len; i++) { + const NMPObject *obj = objs->pdata[i]; + guint32 prio = NMP_OBJECT_CAST_ROUTING_RULE(obj)->priority; + + if (!NM_IN_SET(prio, 0, 32766, 32767) + && !g_hash_table_contains(unique_priorities, GUINT_TO_POINTER(prio))) { + g_hash_table_add(unique_priorities, GUINT_TO_POINTER(prio)); + g_ptr_array_add(objs_sync, (gpointer) nmp_object_ref(obj)); + } + } + + for (i = 0; i < objs_sync->len; i++) { + nmp_rules_manager_track(rules_manager, + NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), + 1, + USER_TAG_1, + NULL); + if (nmtst_get_rand_bool()) { + /* this has no effect, because a negative priority (of same absolute value) + * has lower priority than the positive priority above. */ + nmp_rules_manager_track(rules_manager, + NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), + -1, + USER_TAG_2, + NULL); + } + if (nmtst_get_rand_uint32() % objs_sync->len == 0) { + nmp_rules_manager_sync(rules_manager, FALSE); + g_assert_cmpint(nmtstp_platform_routing_rules_get_count(platform, AF_UNSPEC), + ==, + i + 1); + } + } + + nmp_rules_manager_sync(rules_manager, FALSE); + g_assert_cmpint(nmtstp_platform_routing_rules_get_count(platform, AF_UNSPEC), + ==, + objs_sync->len); + + for (i = 0; i < objs_sync->len; i++) { + switch (nmtst_get_rand_uint32() % 3) { + case 0: + nmp_rules_manager_untrack(rules_manager, + NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), + USER_TAG_1); + nmp_rules_manager_untrack(rules_manager, + NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), + USER_TAG_1); + break; + case 1: + nmp_rules_manager_track(rules_manager, + NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), + -1, + USER_TAG_1, + NULL); + break; + case 2: + nmp_rules_manager_track(rules_manager, + NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), + -2, + USER_TAG_2, + NULL); + break; + } + if (nmtst_get_rand_uint32() % objs_sync->len == 0) { + nmp_rules_manager_sync(rules_manager, FALSE); + g_assert_cmpint(nmtstp_platform_routing_rules_get_count(platform, AF_UNSPEC), + ==, + objs_sync->len - i - 1); + } + } + + nmp_rules_manager_sync(rules_manager, FALSE); + + } else { + for (i = 0; i < objs->len;) { + const NMPObject *obj = objs->pdata[i]; + + for (j = 0; j < objs->len; j++) + g_assert((j < i) == (!!_platform_has_routing_rule(platform, objs->pdata[j]))); + + r = nm_platform_routing_rule_add(platform, + NMP_NLM_FLAG_ADD, + NMP_OBJECT_CAST_ROUTING_RULE(obj)); + + if (r == -EEXIST) { + g_assert(!_platform_has_routing_rule(platform, obj)); + /* this should not happen, but there are bugs in kernel (rh#1686075). */ + for (j = 0; j < i; j++) { + const NMPObject *obj2 = objs->pdata[j]; + + g_assert(_platform_has_routing_rule(platform, obj2)); + + if (_rule_fuzzy_equal(obj, obj2, RTM_NEWRULE)) { + r = 0; + break; + } + } + if (r == 0) { + /* OK, the rule is shadowed by another rule, and kernel does not allow + * us to add this one (rh#1686075). Drop this from the test. */ + g_ptr_array_remove_index(objs, i); + had_an_issue_exist = TRUE; + continue; + } + } + + if (r != 0) { + NMPLookup lookup; + const NMDedupMultiHeadEntry *head_entry; + NMDedupMultiIter iter; + const NMPObject * o; + + g_print(">>> failing... errno=%d, rule=%s\n", + r, + nmp_object_to_string(obj, NMP_OBJECT_TO_STRING_ALL, NULL, 0)); + + nmp_lookup_init_obj_type(&lookup, NMP_OBJECT_TYPE_ROUTING_RULE); + head_entry = nm_platform_lookup(platform, &lookup); + nmp_cache_iter_for_each (&iter, head_entry, &o) { + char ch = ' '; + + if (NMP_OBJECT_CAST_ROUTING_RULE(o)->addr_family + == NMP_OBJECT_CAST_ROUTING_RULE(obj)->addr_family + && NMP_OBJECT_CAST_ROUTING_RULE(o)->priority + == NMP_OBJECT_CAST_ROUTING_RULE(obj)->priority) + ch = '*'; + g_print(">>> existing rule: %c %s\n", + ch, + nmp_object_to_string(o, NMP_OBJECT_TO_STRING_ALL, NULL, 0)); + } + + nmtstp_run_command_check("ip rule"); + nmtstp_run_command_check("ip -6 rule"); + g_assert_cmpint(r, ==, 0); + } + + g_assert(_platform_has_routing_rule(platform, obj)); + + g_assert_cmpint(nmtstp_platform_routing_rules_get_count(platform, AF_UNSPEC), + ==, + i + 1); + + i++; + } + + if (TEST_IDX != 1) + nmtst_rand_perm(NULL, objs->pdata, NULL, sizeof(gpointer), objs->len); + + if (_LOGD_ENABLED()) { + nmtstp_run_command_check("ip rule"); + nmtstp_run_command_check("ip -6 rule"); + } + + for (i = 0; i < objs->len; i++) { + const NMPObject *obj = objs->pdata[i]; + const NMPObject *obj2; + + for (j = 0; j < objs->len; j++) + g_assert((j < i) == (!_platform_has_routing_rule(platform, objs->pdata[j]))); + + g_assert(_platform_has_routing_rule(platform, obj)); + + r = nm_platform_object_delete(platform, obj); + g_assert_cmpint(r, ==, TRUE); + + obj2 = _platform_has_routing_rule(platform, obj); + + if (obj2) { + guint k; + + /* When deleting a rule, kernel does a fuzzy match, ignoring for example: + * - action, if it is FR_ACT_UNSPEC + * - iifname,oifname if it is unspecified + * rh#1685816 + * + * That means, we may have deleted the wrong rule. Which one? */ + k = i; + for (j = i + 1; j < objs->len; j++) { + if (!_platform_has_routing_rule(platform, objs->pdata[j])) { + g_assert_cmpint(k, ==, i); + k = j; + } + } + g_assert_cmpint(k, >, i); + + if (!_rule_fuzzy_equal(obj, objs->pdata[k], RTM_DELRULE)) { + g_print(">>> failing...\n"); + g_print(">>> no fuzzy match between: %s\n", + nmp_object_to_string(obj, NMP_OBJECT_TO_STRING_ALL, NULL, 0)); + g_print( + ">>> and: %s\n", + nmp_object_to_string(objs->pdata[k], NMP_OBJECT_TO_STRING_ALL, NULL, 0)); + g_assert_not_reached(); + } + + objs->pdata[i] = objs->pdata[k]; + objs->pdata[k] = (gpointer) obj; + obj2 = NULL; + } + + g_assert(!obj2); + + g_assert_cmpint(nmtstp_platform_routing_rules_get_count(platform, AF_UNSPEC), + ==, + objs->len - i - 1); + } + } + + g_assert_cmpint(nmtstp_platform_routing_rules_get_count(platform, AF_UNSPEC), ==, 0); + + for (i = 0; i < objs_initial->len; i++) { + const NMPObject *obj = objs_initial->pdata[i]; + + for (j = 0; j < objs_initial->len; j++) + g_assert((j < i) == (!!_platform_has_routing_rule(platform, objs_initial->pdata[j]))); + + r = nm_platform_routing_rule_add(platform, + NMP_NLM_FLAG_ADD, + NMP_OBJECT_CAST_ROUTING_RULE(obj)); + g_assert_cmpint(r, ==, 0); + } + for (j = 0; j < objs_initial->len; j++) + g_assert(_platform_has_routing_rule(platform, objs_initial->pdata[j])); + g_assert_cmpint(nmtstp_platform_routing_rules_get_count(platform, AF_UNSPEC), + ==, + objs_initial->len); + + /* the tests passed as good as we could (as good as we implemented workarounds for them). + * Still, with this kernel, not all features were fully tested. Mark the test as skipped. */ + if (had_an_issue_exist) + g_test_skip("adding a rule failed with EEXIST although it should not (rh#1686075)"); + else if (!_rule_check_kernel_support(platform, -1)) + g_test_skip("some kernel features were not available and skipped for the test"); } /*****************************************************************************/ @@ -1729,37 +1889,38 @@ again: NMTstpSetupFunc const _nmtstp_setup_platform_func = SETUP; void -_nmtstp_init_tests (int *argc, char ***argv) +_nmtstp_init_tests(int *argc, char ***argv) { - nmtst_init_with_logging (argc, argv, NULL, "ALL"); + nmtst_init_with_logging(argc, argv, NULL, "ALL"); } void -_nmtstp_setup_tests (void) +_nmtstp_setup_tests(void) { #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_data ("/route/ip4_options/1", test_ip4_route_options, GINT_TO_POINTER (1)); - if (nmtstp_is_root_test ()) - add_test_func_data ("/route/ip4_options/2", test_ip4_route_options, GINT_TO_POINTER (2)); - 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/ip4_route_get", test_ip4_route_get); - add_test_func ("/route/ip6_route_get", test_ip6_route_get); - add_test_func ("/route/ip4_zero_gateway", test_ip4_zero_gateway); - } - - if (nmtstp_is_root_test ()) { - add_test_func_data ("/route/rule/1", test_rule, GINT_TO_POINTER (1)); - add_test_func_data ("/route/rule/2", test_rule, GINT_TO_POINTER (2)); - add_test_func_data ("/route/rule/3", test_rule, GINT_TO_POINTER (3)); - add_test_func_data ("/route/rule/4", test_rule, GINT_TO_POINTER (4)); - } +#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_data("/route/ip4_options/1", test_ip4_route_options, GINT_TO_POINTER(1)); + if (nmtstp_is_root_test()) + add_test_func_data("/route/ip4_options/2", test_ip4_route_options, GINT_TO_POINTER(2)); + 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/ip4_route_get", test_ip4_route_get); + add_test_func("/route/ip6_route_get", test_ip6_route_get); + add_test_func("/route/ip4_zero_gateway", test_ip4_zero_gateway); + } + + if (nmtstp_is_root_test()) { + add_test_func_data("/route/rule/1", test_rule, GINT_TO_POINTER(1)); + add_test_func_data("/route/rule/2", test_rule, GINT_TO_POINTER(2)); + add_test_func_data("/route/rule/3", test_rule, GINT_TO_POINTER(3)); + add_test_func_data("/route/rule/4", test_rule, GINT_TO_POINTER(4)); + } } diff --git a/src/platform/tests/test-tc.c b/src/platform/tests/test-tc.c index 0c90fcfa..4cbe4f5d 100644 --- a/src/platform/tests/test-tc.c +++ b/src/platform/tests/test-tc.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1+ +/* SPDX-License-Identifier: LGPL-2.1+ */ #include "nm-default.h" @@ -11,194 +11,193 @@ #include "test-common.h" static NMPObject * -qdisc_new (int ifindex, const char *kind, guint32 parent) +qdisc_new(int ifindex, const char *kind, guint32 parent) { - NMPObject *obj; + NMPObject *obj; - obj = nmp_object_new (NMP_OBJECT_TYPE_QDISC, NULL); - obj->qdisc = (NMPlatformQdisc) { - .ifindex = ifindex, - .kind = kind, - .parent = parent, - }; + obj = nmp_object_new(NMP_OBJECT_TYPE_QDISC, NULL); + obj->qdisc = (NMPlatformQdisc){ + .ifindex = ifindex, + .kind = kind, + .parent = parent, + }; - return obj; + return obj; } static GPtrArray * -qdiscs_lookup (int ifindex) +qdiscs_lookup(int ifindex) { - NMPLookup lookup; + NMPLookup lookup; - return nm_platform_lookup_clone (NM_PLATFORM_GET, - nmp_lookup_init_object (&lookup, - NMP_OBJECT_TYPE_QDISC, - ifindex), - NULL, NULL); + return nm_platform_lookup_clone(NM_PLATFORM_GET, + nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_QDISC, ifindex), + NULL, + NULL); } static void -test_qdisc1 (void) +test_qdisc1(void) { - int ifindex; - gs_unref_ptrarray GPtrArray *known = NULL; - gs_unref_ptrarray GPtrArray *plat = NULL; - NMPObject *obj; - NMPlatformQdisc *qdisc; - - ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); - g_assert_cmpint (ifindex, >, 0); - - nmtstp_run_command ("tc qdisc del dev %s root", DEVICE_NAME); - nmtstp_run_command_check ("tc qdisc add dev %s root sfq", DEVICE_NAME); - - nmtstp_wait_for_signal (NM_PLATFORM_GET, 0); - - known = g_ptr_array_new_with_free_func ((GDestroyNotify) nmp_object_unref); - g_ptr_array_add (known, qdisc_new (ifindex, "fq_codel", TC_H_ROOT)); - g_ptr_array_add (known, qdisc_new (ifindex, "ingress", TC_H_INGRESS)); - - g_assert (nm_platform_qdisc_sync (NM_PLATFORM_GET, ifindex, known)); - plat = qdiscs_lookup (ifindex); - g_assert (plat); - g_assert_cmpint (plat->len, ==, 2); - - obj = plat->pdata[0]; - qdisc = NMP_OBJECT_CAST_QDISC (obj); - g_assert_cmpint (qdisc->parent, ==, TC_H_ROOT); - g_assert_cmpstr (qdisc->kind, ==, "fq_codel"); - - obj = plat->pdata[1]; - qdisc = NMP_OBJECT_CAST_QDISC (obj); - g_assert_cmpint (qdisc->parent, ==, TC_H_INGRESS); - g_assert_cmpstr (qdisc->kind, ==, "ingress"); + int ifindex; + gs_unref_ptrarray GPtrArray *known = NULL; + gs_unref_ptrarray GPtrArray *plat = NULL; + NMPObject * obj; + NMPlatformQdisc * qdisc; + + ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME); + g_assert_cmpint(ifindex, >, 0); + + nmtstp_run_command("tc qdisc del dev %s root", DEVICE_NAME); + nmtstp_run_command_check("tc qdisc add dev %s root sfq", DEVICE_NAME); + + nmtstp_wait_for_signal(NM_PLATFORM_GET, 0); + + known = g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref); + g_ptr_array_add(known, qdisc_new(ifindex, "fq_codel", TC_H_ROOT)); + g_ptr_array_add(known, qdisc_new(ifindex, "ingress", TC_H_INGRESS)); + + g_assert(nm_platform_qdisc_sync(NM_PLATFORM_GET, ifindex, known)); + plat = qdiscs_lookup(ifindex); + g_assert(plat); + g_assert_cmpint(plat->len, ==, 2); + + obj = plat->pdata[0]; + qdisc = NMP_OBJECT_CAST_QDISC(obj); + g_assert_cmpint(qdisc->parent, ==, TC_H_ROOT); + g_assert_cmpstr(qdisc->kind, ==, "fq_codel"); + + obj = plat->pdata[1]; + qdisc = NMP_OBJECT_CAST_QDISC(obj); + g_assert_cmpint(qdisc->parent, ==, TC_H_INGRESS); + g_assert_cmpstr(qdisc->kind, ==, "ingress"); } static void -test_qdisc_fq_codel (void) +test_qdisc_fq_codel(void) { - int ifindex; - gs_unref_ptrarray GPtrArray *known = NULL; - gs_unref_ptrarray GPtrArray *plat = NULL; - NMPObject *obj; - NMPlatformQdisc *qdisc; - - ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); - g_assert_cmpint (ifindex, >, 0); - - nmtstp_run_command ("tc qdisc del dev %s root", DEVICE_NAME); - - nmtstp_wait_for_signal (NM_PLATFORM_GET, 0); - - known = g_ptr_array_new_with_free_func ((GDestroyNotify) nmp_object_unref); - obj = qdisc_new (ifindex, "fq_codel", TC_H_ROOT); - obj->qdisc.handle = TC_H_MAKE (0x8142 << 16, 0); - obj->qdisc.fq_codel.limit = 2048; - obj->qdisc.fq_codel.flows = 64; - obj->qdisc.fq_codel.quantum = 1000; - g_ptr_array_add (known, obj); - - g_assert (nm_platform_qdisc_sync (NM_PLATFORM_GET, ifindex, known)); - plat = qdiscs_lookup (ifindex); - g_assert (plat); - g_assert_cmpint (plat->len, ==, 1); - - obj = plat->pdata[0]; - qdisc = NMP_OBJECT_CAST_QDISC (obj); - g_assert_cmpstr (qdisc->kind, ==, "fq_codel"); - g_assert_cmpint (qdisc->handle, ==, TC_H_MAKE (0x8142 << 16, 0)); - g_assert_cmpint (qdisc->parent, ==, TC_H_ROOT); - g_assert_cmpint (qdisc->fq_codel.limit, ==, 2048); - g_assert_cmpint (qdisc->fq_codel.flows, ==, 64); - g_assert_cmpint (qdisc->fq_codel.quantum, ==, 1000); + int ifindex; + gs_unref_ptrarray GPtrArray *known = NULL; + gs_unref_ptrarray GPtrArray *plat = NULL; + NMPObject * obj; + NMPlatformQdisc * qdisc; + + ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME); + g_assert_cmpint(ifindex, >, 0); + + nmtstp_run_command("tc qdisc del dev %s root", DEVICE_NAME); + + nmtstp_wait_for_signal(NM_PLATFORM_GET, 0); + + known = g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref); + obj = qdisc_new(ifindex, "fq_codel", TC_H_ROOT); + obj->qdisc.handle = TC_H_MAKE(0x8142 << 16, 0); + obj->qdisc.fq_codel.limit = 2048; + obj->qdisc.fq_codel.flows = 64; + obj->qdisc.fq_codel.quantum = 1000; + g_ptr_array_add(known, obj); + + g_assert(nm_platform_qdisc_sync(NM_PLATFORM_GET, ifindex, known)); + plat = qdiscs_lookup(ifindex); + g_assert(plat); + g_assert_cmpint(plat->len, ==, 1); + + obj = plat->pdata[0]; + qdisc = NMP_OBJECT_CAST_QDISC(obj); + g_assert_cmpstr(qdisc->kind, ==, "fq_codel"); + g_assert_cmpint(qdisc->handle, ==, TC_H_MAKE(0x8142 << 16, 0)); + g_assert_cmpint(qdisc->parent, ==, TC_H_ROOT); + g_assert_cmpint(qdisc->fq_codel.limit, ==, 2048); + g_assert_cmpint(qdisc->fq_codel.flows, ==, 64); + g_assert_cmpint(qdisc->fq_codel.quantum, ==, 1000); } static void -test_qdisc_sfq (void) +test_qdisc_sfq(void) { - int ifindex; - gs_unref_ptrarray GPtrArray *known = NULL; - gs_unref_ptrarray GPtrArray *plat = NULL; - NMPObject *obj; - NMPlatformQdisc *qdisc; - - ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); - g_assert_cmpint (ifindex, >, 0); - - nmtstp_run_command ("tc qdisc del dev %s root", DEVICE_NAME); - - nmtstp_wait_for_signal (NM_PLATFORM_GET, 0); - - known = g_ptr_array_new_with_free_func ((GDestroyNotify) nmp_object_unref); - obj = qdisc_new (ifindex, "sfq", TC_H_ROOT); - obj->qdisc.handle = TC_H_MAKE (0x8143 << 16, 0); - obj->qdisc.sfq.perturb_period = 10; - obj->qdisc.sfq.quantum = 1540; - obj->qdisc.sfq.flows = 256; - g_ptr_array_add (known, obj); - - g_assert (nm_platform_qdisc_sync (NM_PLATFORM_GET, ifindex, known)); - plat = qdiscs_lookup (ifindex); - g_assert (plat); - g_assert_cmpint (plat->len, ==, 1); - - obj = plat->pdata[0]; - qdisc = NMP_OBJECT_CAST_QDISC (obj); - g_assert_cmpstr (qdisc->kind, ==, "sfq"); - g_assert_cmpint (qdisc->handle, ==, TC_H_MAKE (0x8143 << 16, 0)); - g_assert_cmpint (qdisc->parent, ==, TC_H_ROOT); - g_assert_cmpint (qdisc->sfq.perturb_period, ==, 10); - g_assert_cmpint (qdisc->sfq.quantum, ==, 1540); - g_assert_cmpint (qdisc->sfq.flows, ==, 256); + int ifindex; + gs_unref_ptrarray GPtrArray *known = NULL; + gs_unref_ptrarray GPtrArray *plat = NULL; + NMPObject * obj; + NMPlatformQdisc * qdisc; + + ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME); + g_assert_cmpint(ifindex, >, 0); + + nmtstp_run_command("tc qdisc del dev %s root", DEVICE_NAME); + + nmtstp_wait_for_signal(NM_PLATFORM_GET, 0); + + known = g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref); + obj = qdisc_new(ifindex, "sfq", TC_H_ROOT); + obj->qdisc.handle = TC_H_MAKE(0x8143 << 16, 0); + obj->qdisc.sfq.perturb_period = 10; + obj->qdisc.sfq.quantum = 1540; + obj->qdisc.sfq.flows = 256; + g_ptr_array_add(known, obj); + + g_assert(nm_platform_qdisc_sync(NM_PLATFORM_GET, ifindex, known)); + plat = qdiscs_lookup(ifindex); + g_assert(plat); + g_assert_cmpint(plat->len, ==, 1); + + obj = plat->pdata[0]; + qdisc = NMP_OBJECT_CAST_QDISC(obj); + g_assert_cmpstr(qdisc->kind, ==, "sfq"); + g_assert_cmpint(qdisc->handle, ==, TC_H_MAKE(0x8143 << 16, 0)); + g_assert_cmpint(qdisc->parent, ==, TC_H_ROOT); + g_assert_cmpint(qdisc->sfq.perturb_period, ==, 10); + g_assert_cmpint(qdisc->sfq.quantum, ==, 1540); + g_assert_cmpint(qdisc->sfq.flows, ==, 256); } static void -test_qdisc_tbf (void) +test_qdisc_tbf(void) { - int ifindex; - gs_unref_ptrarray GPtrArray *known = NULL; - gs_unref_ptrarray GPtrArray *plat = NULL; - NMPObject *obj; - NMPlatformQdisc *qdisc; - - ifindex = nm_platform_link_get_ifindex (NM_PLATFORM_GET, DEVICE_NAME); - g_assert_cmpint (ifindex, >, 0); - - nmtstp_run_command ("tc qdisc del dev %s root", DEVICE_NAME); - - nmtstp_wait_for_signal (NM_PLATFORM_GET, 0); - - known = g_ptr_array_new_with_free_func ((GDestroyNotify) nmp_object_unref); - obj = qdisc_new (ifindex, "tbf", TC_H_ROOT); - obj->qdisc.handle = TC_H_MAKE (0x8143 << 16, 0); - obj->qdisc.tbf.rate = 1000000; - obj->qdisc.tbf.burst = 2000; - obj->qdisc.tbf.limit = 3000; - g_ptr_array_add (known, obj); - - obj = qdisc_new (ifindex, "sfq", TC_H_MAKE (0x8143 << 16, 0)); - obj->qdisc.handle = TC_H_MAKE (0x8005 << 16, 0); - g_ptr_array_add (known, obj); - - g_assert (nm_platform_qdisc_sync (NM_PLATFORM_GET, ifindex, known)); - plat = qdiscs_lookup (ifindex); - g_assert (plat); - g_assert_cmpint (plat->len, ==, 2); - - obj = plat->pdata[0]; - qdisc = NMP_OBJECT_CAST_QDISC (obj); - g_assert_cmpstr (qdisc->kind, ==, "tbf"); - g_assert_cmpint (qdisc->handle, ==, TC_H_MAKE (0x8143 << 16, 0)); - g_assert_cmpint (qdisc->parent, ==, TC_H_ROOT); - g_assert_cmpint (qdisc->tbf.rate, ==, 1000000); - g_assert_cmpint (qdisc->tbf.burst, ==, 2000); - g_assert_cmpint (qdisc->tbf.limit, ==, 3000); - - obj = plat->pdata[1]; - qdisc = NMP_OBJECT_CAST_QDISC (obj); - g_assert_cmpstr (qdisc->kind, ==, "sfq"); - g_assert_cmpint (qdisc->parent, ==, TC_H_MAKE (0x8143 << 16, 0)); - g_assert_cmpint (qdisc->handle, ==, TC_H_MAKE (0x8005 << 16, 0)); + int ifindex; + gs_unref_ptrarray GPtrArray *known = NULL; + gs_unref_ptrarray GPtrArray *plat = NULL; + NMPObject * obj; + NMPlatformQdisc * qdisc; + + ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, DEVICE_NAME); + g_assert_cmpint(ifindex, >, 0); + + nmtstp_run_command("tc qdisc del dev %s root", DEVICE_NAME); + + nmtstp_wait_for_signal(NM_PLATFORM_GET, 0); + + known = g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref); + obj = qdisc_new(ifindex, "tbf", TC_H_ROOT); + obj->qdisc.handle = TC_H_MAKE(0x8143 << 16, 0); + obj->qdisc.tbf.rate = 1000000; + obj->qdisc.tbf.burst = 2000; + obj->qdisc.tbf.limit = 3000; + g_ptr_array_add(known, obj); + + obj = qdisc_new(ifindex, "sfq", TC_H_MAKE(0x8143 << 16, 0)); + obj->qdisc.handle = TC_H_MAKE(0x8005 << 16, 0); + g_ptr_array_add(known, obj); + + g_assert(nm_platform_qdisc_sync(NM_PLATFORM_GET, ifindex, known)); + plat = qdiscs_lookup(ifindex); + g_assert(plat); + g_assert_cmpint(plat->len, ==, 2); + + obj = plat->pdata[0]; + qdisc = NMP_OBJECT_CAST_QDISC(obj); + g_assert_cmpstr(qdisc->kind, ==, "tbf"); + g_assert_cmpint(qdisc->handle, ==, TC_H_MAKE(0x8143 << 16, 0)); + g_assert_cmpint(qdisc->parent, ==, TC_H_ROOT); + g_assert_cmpint(qdisc->tbf.rate, ==, 1000000); + g_assert_cmpint(qdisc->tbf.burst, ==, 2000); + g_assert_cmpint(qdisc->tbf.limit, ==, 3000); + + obj = plat->pdata[1]; + qdisc = NMP_OBJECT_CAST_QDISC(obj); + g_assert_cmpstr(qdisc->kind, ==, "sfq"); + g_assert_cmpint(qdisc->parent, ==, TC_H_MAKE(0x8143 << 16, 0)); + g_assert_cmpint(qdisc->handle, ==, TC_H_MAKE(0x8005 << 16, 0)); } /*****************************************************************************/ @@ -206,18 +205,18 @@ test_qdisc_tbf (void) NMTstpSetupFunc const _nmtstp_setup_platform_func = SETUP; void -_nmtstp_init_tests (int *argc, char ***argv) +_nmtstp_init_tests(int *argc, char ***argv) { - nmtst_init_with_logging (argc, argv, NULL, "ALL"); + nmtst_init_with_logging(argc, argv, NULL, "ALL"); } void -_nmtstp_setup_tests (void) +_nmtstp_setup_tests(void) { - if (nmtstp_is_root_test ()) { - nmtstp_env1_add_test_func ("/link/qdisc/1", test_qdisc1, TRUE); - nmtstp_env1_add_test_func ("/link/qdisc/fq_codel", test_qdisc_fq_codel, TRUE); - nmtstp_env1_add_test_func ("/link/qdisc/sfq", test_qdisc_sfq, TRUE); - nmtstp_env1_add_test_func ("/link/qdisc/tbf", test_qdisc_tbf, TRUE); - } + if (nmtstp_is_root_test()) { + nmtstp_env1_add_test_func("/link/qdisc/1", test_qdisc1, TRUE); + nmtstp_env1_add_test_func("/link/qdisc/fq_codel", test_qdisc_fq_codel, TRUE); + nmtstp_env1_add_test_func("/link/qdisc/sfq", test_qdisc_sfq, TRUE); + nmtstp_env1_add_test_func("/link/qdisc/tbf", test_qdisc_tbf, TRUE); + } } |