diff options
| author | Michael Biebl <biebl@debian.org> | 2020-10-05 22:27:18 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2020-10-05 22:27:18 +0200 |
| commit | aafc1dbe4712c86189bbc1d4d54ad8cb4c69be7e (patch) | |
| tree | a2a9bb4d007339a0b1304540388230ccedac32bd /src/platform/tests/test-link.c | |
| parent | e7b44ef4c80907346ec7492a09c45277459924fc (diff) | |
New upstream version 1.27.90 upstream/1.27.90
Diffstat (limited to 'src/platform/tests/test-link.c')
| -rw-r--r-- | src/platform/tests/test-link.c | 6515 |
1 files changed, 3467 insertions, 3048 deletions
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); + } } |