diff options
Diffstat (limited to 'src/platform/tests/test-common.c')
| -rw-r--r-- | src/platform/tests/test-common.c | 3788 |
1 files changed, 2114 insertions, 1674 deletions
diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c index 9f6a29bc..e305357a 100644 --- a/src/platform/tests/test-common.c +++ b/src/platform/tests/test-common.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2016 - 2017 Red Hat, Inc. */ @@ -14,2021 +14,2461 @@ #include "test-common.h" #define SIGNAL_DATA_FMT "'%s-%s' ifindex %d%s%s%s (%d times received)" -#define SIGNAL_DATA_ARG(data) (data)->name, nm_platform_signal_change_type_to_string ((data)->change_type), (data)->ifindex, (data)->ifname ? " ifname '" : "", (data)->ifname ?: "", (data)->ifname ? "'" : "", (data)->received_count +#define SIGNAL_DATA_ARG(data) \ + (data)->name, nm_platform_signal_change_type_to_string((data)->change_type), (data)->ifindex, \ + (data)->ifname ? " ifname '" : "", (data)->ifname ?: "", (data)->ifname ? "'" : "", \ + (data)->received_count int NMTSTP_ENV1_IFINDEX = -1; -int NMTSTP_ENV1_EX = -1; +int NMTSTP_ENV1_EX = -1; /*****************************************************************************/ void -nmtstp_setup_platform (void) +nmtstp_setup_platform(void) { - g_assert (_nmtstp_setup_platform_func); - _nmtstp_setup_platform_func (); + g_assert(_nmtstp_setup_platform_func); + _nmtstp_setup_platform_func(); } gboolean -nmtstp_is_root_test (void) +nmtstp_is_root_test(void) { - g_assert (_nmtstp_setup_platform_func); - return _nmtstp_setup_platform_func == nm_linux_platform_setup; + g_assert(_nmtstp_setup_platform_func); + return _nmtstp_setup_platform_func == nm_linux_platform_setup; } gboolean -nmtstp_is_sysfs_writable (void) +nmtstp_is_sysfs_writable(void) { - return !nmtstp_is_root_test () - || (access ("/sys/devices", W_OK) == 0); + return !nmtstp_is_root_test() || (access("/sys/devices", W_OK) == 0); } static void -_init_platform (NMPlatform **platform, gboolean external_command) +_init_platform(NMPlatform **platform, gboolean external_command) { - g_assert (platform); - if (!*platform) - *platform = NM_PLATFORM_GET; - g_assert (NM_IS_PLATFORM (*platform)); + g_assert(platform); + if (!*platform) + *platform = NM_PLATFORM_GET; + g_assert(NM_IS_PLATFORM(*platform)); - if (external_command) - g_assert (NM_IS_LINUX_PLATFORM (*platform)); + if (external_command) + g_assert(NM_IS_LINUX_PLATFORM(*platform)); } /*****************************************************************************/ static GArray * -_ipx_address_get_all (NMPlatform *self, int ifindex, NMPObjectType obj_type) +_ipx_address_get_all(NMPlatform *self, int ifindex, NMPObjectType obj_type) { - NMPLookup lookup; + NMPLookup lookup; - g_assert (NM_IS_PLATFORM (self)); - g_assert (ifindex > 0); - g_assert (NM_IN_SET (obj_type, NMP_OBJECT_TYPE_IP4_ADDRESS, NMP_OBJECT_TYPE_IP6_ADDRESS)); - nmp_lookup_init_object (&lookup, - obj_type, - ifindex); - return nmp_cache_lookup_to_array (nm_platform_lookup (self, &lookup), - obj_type, - FALSE /*addresses are always visible. */); + g_assert(NM_IS_PLATFORM(self)); + g_assert(ifindex > 0); + g_assert(NM_IN_SET(obj_type, NMP_OBJECT_TYPE_IP4_ADDRESS, NMP_OBJECT_TYPE_IP6_ADDRESS)); + nmp_lookup_init_object(&lookup, obj_type, ifindex); + return nmp_cache_lookup_to_array(nm_platform_lookup(self, &lookup), + obj_type, + FALSE /*addresses are always visible. */); } GArray * -nmtstp_platform_ip4_address_get_all (NMPlatform *self, int ifindex) +nmtstp_platform_ip4_address_get_all(NMPlatform *self, int ifindex) { - return _ipx_address_get_all (self, ifindex, NMP_OBJECT_TYPE_IP4_ADDRESS); + return _ipx_address_get_all(self, ifindex, NMP_OBJECT_TYPE_IP4_ADDRESS); } GArray * -nmtstp_platform_ip6_address_get_all (NMPlatform *self, int ifindex) +nmtstp_platform_ip6_address_get_all(NMPlatform *self, int ifindex) { - return _ipx_address_get_all (self, ifindex, NMP_OBJECT_TYPE_IP6_ADDRESS); + return _ipx_address_get_all(self, ifindex, NMP_OBJECT_TYPE_IP6_ADDRESS); +} + +const NMPlatformIPAddress * +nmtstp_platform_ip_address_find(NMPlatform *self, int ifindex, int addr_family, gconstpointer addr) +{ + const gboolean IS_IPv4 = NM_IS_IPv4(addr_family); + const NMPlatformIPAddress *found = NULL; + NMDedupMultiIter iter; + const NMPObject * obj; + NMPLookup lookup; + + g_assert(NM_IS_PLATFORM(self)); + nm_assert(ifindex >= 0); + nm_assert_addr_family(addr_family); + nm_assert(addr); + + nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4), ifindex); + nm_platform_iter_obj_for_each(&iter, self, &lookup, &obj) + { + const NMPlatformIPAddress *a = NMP_OBJECT_CAST_IP_ADDRESS(obj); + + g_assert(NMP_OBJECT_GET_ADDR_FAMILY(obj) == addr_family); + g_assert(ifindex <= 0 || a->ifindex == ifindex); + + if (memcmp(addr, a->address_ptr, nm_utils_addr_family_to_size(addr_family)) != 0) + continue; + + g_assert(!found); + found = a; + } + + if (!IS_IPv4 && ifindex > 0) + g_assert(found + == (const NMPlatformIPAddress *) nm_platform_ip6_address_get(self, ifindex, addr)); + + return found; +} + +/*****************************************************************************/ + +typedef struct { + NMIPAddr addr; + int addr_family; + bool found : 1; +} IPAddressesAssertData; + +void +_nmtstp_platform_ip_addresses_assert(const char * filename, + int lineno, + NMPlatform * self, + int ifindex, + gboolean force_exact_4, + gboolean force_exact_6, + gboolean ignore_ll6, + guint addrs_len, + const char *const *addrs) +{ + gs_free IPAddressesAssertData *addrs_bin = NULL; + int IS_IPv4; + guint i; + + g_assert(filename); + g_assert(lineno >= 0); + g_assert(NM_IS_PLATFORM(self)); + g_assert(ifindex >= 0); + + addrs_bin = g_new(IPAddressesAssertData, addrs_len); + + for (i = 0; i < addrs_len; i++) { + const char *addrstr = addrs[i]; + int addr_family; + NMIPAddr a; + + if (!addrstr) { + addr_family = AF_UNSPEC; + a = nm_ip_addr_zero; + } else if (inet_pton(AF_INET, addrstr, &a) == 1) + addr_family = AF_INET; + else if (inet_pton(AF_INET6, addrstr, &a) == 1) + addr_family = AF_INET6; + else + g_error("%s:%d: invalid IP address in argument: %s", filename, lineno, addrstr); + + addrs_bin[i] = (IPAddressesAssertData){ + .addr_family = addr_family, + .addr = a, + .found = FALSE, + }; + } + + for (IS_IPv4 = 1; IS_IPv4 >= 0; IS_IPv4--) { + const int addr_family = IS_IPv4 ? AF_INET : AF_INET6; + gs_unref_ptrarray GPtrArray *plat_addrs = NULL; + NMPLookup lookup; + guint j; + + plat_addrs = nm_platform_lookup_clone( + self, + nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4), ifindex), + NULL, + NULL); + + for (i = 0; i < addrs_len; i++) { + IPAddressesAssertData *addr_bin = &addrs_bin[i]; + + if (addr_bin->addr_family != addr_family) + continue; + + g_assert(!addr_bin->found); + for (j = 0; j < nm_g_ptr_array_len(plat_addrs);) { + const NMPlatformIPAddress *a = NMP_OBJECT_CAST_IP_ADDRESS(plat_addrs->pdata[j]); + + if (memcmp(&addr_bin->addr, + a->address_ptr, + nm_utils_addr_family_to_size(addr_family)) + != 0) { + j++; + continue; + } + + g_assert(!addr_bin->found); + addr_bin->found = TRUE; + g_ptr_array_remove_index_fast(plat_addrs, j); + } + + if (!addr_bin->found) { + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + + g_error("%s:%d: IPv%c address %s was not found on ifindex %d", + filename, + lineno, + nm_utils_addr_family_to_char(addr_bin->addr_family), + nm_utils_inet_ntop(addr_bin->addr_family, &addr_bin->addr, sbuf), + ifindex); + } + } + if (!IS_IPv4 && ignore_ll6 && nm_g_ptr_array_len(plat_addrs) > 0) { + /* we prune all remaining, non-matching IPv6 link local addresses. */ + for (j = 0; j < nm_g_ptr_array_len(plat_addrs);) { + const NMPlatformIPAddress *a = NMP_OBJECT_CAST_IP_ADDRESS(plat_addrs->pdata[j]); + + if (!IN6_IS_ADDR_LINKLOCAL(a->address_ptr)) { + j++; + continue; + } + + g_ptr_array_remove_index_fast(plat_addrs, j); + } + } + if ((IS_IPv4 ? force_exact_4 : force_exact_6) && nm_g_ptr_array_len(plat_addrs) > 0) { + char sbuf[sizeof(_nm_utils_to_string_buffer)]; + + g_error("%s:%d: %u IPv%c addresses found on ifindex %d that should not be there (one " + "is %s)", + filename, + lineno, + plat_addrs->len, + nm_utils_addr_family_to_char(addr_family), + ifindex, + nmp_object_to_string(plat_addrs->pdata[0], + NMP_OBJECT_TO_STRING_PUBLIC, + sbuf, + sizeof(sbuf))); + } + } } /*****************************************************************************/ gboolean -nmtstp_platform_ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, guint8 plen, guint32 metric) +nmtstp_platform_ip4_route_delete(NMPlatform *platform, + int ifindex, + in_addr_t network, + guint8 plen, + guint32 metric) { - NMDedupMultiIter iter; + NMDedupMultiIter iter; - nm_platform_process_events (platform); + nm_platform_process_events(platform); - nm_dedup_multi_iter_for_each (&iter, - nm_platform_lookup_object (platform, - NMP_OBJECT_TYPE_IP4_ROUTE, - ifindex)) { - const NMPlatformIP4Route *r = NMP_OBJECT_CAST_IP4_ROUTE (iter.current->obj); + nm_dedup_multi_iter_for_each ( + &iter, + nm_platform_lookup_object(platform, NMP_OBJECT_TYPE_IP4_ROUTE, ifindex)) { + const NMPlatformIP4Route *r = NMP_OBJECT_CAST_IP4_ROUTE(iter.current->obj); - if ( r->ifindex != ifindex - || r->network != network - || r->plen != plen - || r->metric != metric) { - continue; - } + if (r->ifindex != ifindex || r->network != network || r->plen != plen + || r->metric != metric) { + continue; + } - return nm_platform_object_delete (platform, NMP_OBJECT_UP_CAST (r)); - } + return nm_platform_object_delete(platform, NMP_OBJECT_UP_CAST(r)); + } - return TRUE; + return TRUE; } gboolean -nmtstp_platform_ip6_route_delete (NMPlatform *platform, int ifindex, struct in6_addr network, guint8 plen, guint32 metric) +nmtstp_platform_ip6_route_delete(NMPlatform * platform, + int ifindex, + struct in6_addr network, + guint8 plen, + guint32 metric) { - NMDedupMultiIter iter; + NMDedupMultiIter iter; - nm_platform_process_events (platform); + nm_platform_process_events(platform); - nm_dedup_multi_iter_for_each (&iter, - nm_platform_lookup_object (platform, - NMP_OBJECT_TYPE_IP6_ROUTE, - ifindex)) { - const NMPlatformIP6Route *r = NMP_OBJECT_CAST_IP6_ROUTE (iter.current->obj); + nm_dedup_multi_iter_for_each ( + &iter, + nm_platform_lookup_object(platform, NMP_OBJECT_TYPE_IP6_ROUTE, ifindex)) { + const NMPlatformIP6Route *r = NMP_OBJECT_CAST_IP6_ROUTE(iter.current->obj); - if ( r->ifindex != ifindex - || !IN6_ARE_ADDR_EQUAL (&r->network, &network) - || r->plen != plen - || r->metric != metric) { - continue; - } + if (r->ifindex != ifindex || !IN6_ARE_ADDR_EQUAL(&r->network, &network) || r->plen != plen + || r->metric != metric) { + continue; + } - return nm_platform_object_delete (platform, NMP_OBJECT_UP_CAST (r)); - } + return nm_platform_object_delete(platform, NMP_OBJECT_UP_CAST(r)); + } - return TRUE; + return TRUE; } /*****************************************************************************/ SignalData * -add_signal_full (const char *name, NMPlatformSignalChangeType change_type, GCallback callback, int ifindex, const char *ifname) +add_signal_full(const char * name, + NMPlatformSignalChangeType change_type, + GCallback callback, + int ifindex, + const char * ifname) { - SignalData *data = g_new0 (SignalData, 1); + SignalData *data = g_new0(SignalData, 1); - data->name = name; - data->change_type = change_type; - data->received_count = 0; - data->handler_id = g_signal_connect (NM_PLATFORM_GET, name, callback, data); - data->ifindex = ifindex; - data->ifname = ifname; + data->name = name; + data->change_type = change_type; + data->received_count = 0; + data->handler_id = g_signal_connect(NM_PLATFORM_GET, name, callback, data); + data->ifindex = ifindex; + data->ifname = ifname; - g_assert (data->handler_id > 0); + g_assert(data->handler_id > 0); - return data; + return data; } void -_accept_signal (const char *file, int line, const char *func, SignalData *data) -{ - _LOGD ("NMPlatformSignalAssert: %s:%d, %s(): Accepting signal one time: "SIGNAL_DATA_FMT, file, line, func, SIGNAL_DATA_ARG (data)); - if (data->received_count != 1) - g_error ("NMPlatformSignalAssert: %s:%d, %s(): failure to accept signal one time: "SIGNAL_DATA_FMT, file, line, func, SIGNAL_DATA_ARG (data)); - data->received_count = 0; +_accept_signal(const char *file, int line, const char *func, SignalData *data) +{ + _LOGD("NMPlatformSignalAssert: %s:%d, %s(): Accepting signal one time: " SIGNAL_DATA_FMT, + file, + line, + func, + SIGNAL_DATA_ARG(data)); + if (data->received_count != 1) + g_error("NMPlatformSignalAssert: %s:%d, %s(): failure to accept signal one " + "time: " SIGNAL_DATA_FMT, + file, + line, + func, + SIGNAL_DATA_ARG(data)); + data->received_count = 0; } void -_accept_signals (const char *file, int line, const char *func, SignalData *data, int min, int max) -{ - _LOGD ("NMPlatformSignalAssert: %s:%d, %s(): Accepting signal [%d,%d] times: "SIGNAL_DATA_FMT, file, line, func, min, max, SIGNAL_DATA_ARG (data)); - if (data->received_count < min || data->received_count > max) - g_error ("NMPlatformSignalAssert: %s:%d, %s(): failure to accept signal [%d,%d] times: "SIGNAL_DATA_FMT, file, line, func, min, max, SIGNAL_DATA_ARG (data)); - data->received_count = 0; +_accept_signals(const char *file, int line, const char *func, SignalData *data, int min, int max) +{ + _LOGD("NMPlatformSignalAssert: %s:%d, %s(): Accepting signal [%d,%d] times: " SIGNAL_DATA_FMT, + file, + line, + func, + min, + max, + SIGNAL_DATA_ARG(data)); + if (data->received_count < min || data->received_count > max) + g_error("NMPlatformSignalAssert: %s:%d, %s(): failure to accept signal [%d,%d] " + "times: " SIGNAL_DATA_FMT, + file, + line, + func, + min, + max, + SIGNAL_DATA_ARG(data)); + data->received_count = 0; } void -_ensure_no_signal (const char *file, int line, const char *func, SignalData *data) -{ - _LOGD ("NMPlatformSignalAssert: %s:%d, %s(): Accepting signal 0 times: "SIGNAL_DATA_FMT, file, line, func, SIGNAL_DATA_ARG (data)); - if (data->received_count > 0) - g_error ("NMPlatformSignalAssert: %s:%d, %s(): failure to accept signal 0 times: "SIGNAL_DATA_FMT, file, line, func, SIGNAL_DATA_ARG (data)); +_ensure_no_signal(const char *file, int line, const char *func, SignalData *data) +{ + _LOGD("NMPlatformSignalAssert: %s:%d, %s(): Accepting signal 0 times: " SIGNAL_DATA_FMT, + file, + line, + func, + SIGNAL_DATA_ARG(data)); + if (data->received_count > 0) + g_error("NMPlatformSignalAssert: %s:%d, %s(): failure to accept signal 0 " + "times: " SIGNAL_DATA_FMT, + file, + line, + func, + SIGNAL_DATA_ARG(data)); } void -_accept_or_wait_signal (const char *file, int line, const char *func, SignalData *data) +_accept_or_wait_signal(const char *file, int line, const char *func, SignalData *data) { - _LOGD ("NMPlatformSignalAssert: %s:%d, %s(): accept-or-wait signal: "SIGNAL_DATA_FMT, file, line, func, SIGNAL_DATA_ARG (data)); - if (data->received_count == 0) { - data->loop = g_main_loop_new (NULL, FALSE); - g_main_loop_run (data->loop); - nm_clear_pointer (&data->loop, g_main_loop_unref); - } + _LOGD("NMPlatformSignalAssert: %s:%d, %s(): accept-or-wait signal: " SIGNAL_DATA_FMT, + file, + line, + func, + SIGNAL_DATA_ARG(data)); + if (data->received_count == 0) { + data->loop = g_main_loop_new(NULL, FALSE); + g_main_loop_run(data->loop); + nm_clear_pointer(&data->loop, g_main_loop_unref); + } - _accept_signal (file, line, func, data); + _accept_signal(file, line, func, data); } void -_wait_signal (const char *file, int line, const char *func, SignalData *data) +_wait_signal(const char *file, int line, const char *func, SignalData *data) { - _LOGD ("NMPlatformSignalAssert: %s:%d, %s(): wait signal: "SIGNAL_DATA_FMT, file, line, func, SIGNAL_DATA_ARG (data)); - if (data->received_count) - g_error ("NMPlatformSignalAssert: %s:%d, %s(): failure to wait for signal: "SIGNAL_DATA_FMT, file, line, func, SIGNAL_DATA_ARG (data)); + _LOGD("NMPlatformSignalAssert: %s:%d, %s(): wait signal: " SIGNAL_DATA_FMT, + file, + line, + func, + SIGNAL_DATA_ARG(data)); + if (data->received_count) + g_error("NMPlatformSignalAssert: %s:%d, %s(): failure to wait for signal: " SIGNAL_DATA_FMT, + file, + line, + func, + SIGNAL_DATA_ARG(data)); - data->loop = g_main_loop_new (NULL, FALSE); - g_main_loop_run (data->loop); - nm_clear_pointer (&data->loop, g_main_loop_unref); + data->loop = g_main_loop_new(NULL, FALSE); + g_main_loop_run(data->loop); + nm_clear_pointer(&data->loop, g_main_loop_unref); - _accept_signal (file, line, func, data); + _accept_signal(file, line, func, data); } void -_free_signal (const char *file, int line, const char *func, SignalData *data) +_free_signal(const char *file, int line, const char *func, SignalData *data) { - _LOGD ("NMPlatformSignalAssert: %s:%d, %s(): free signal: "SIGNAL_DATA_FMT, file, line, func, SIGNAL_DATA_ARG (data)); - if (data->received_count != 0) - g_error ("NMPlatformSignalAssert: %s:%d, %s(): failure to free non-accepted signal: "SIGNAL_DATA_FMT, file, line, func, SIGNAL_DATA_ARG (data)); + _LOGD("NMPlatformSignalAssert: %s:%d, %s(): free signal: " SIGNAL_DATA_FMT, + file, + line, + func, + SIGNAL_DATA_ARG(data)); + if (data->received_count != 0) + g_error("NMPlatformSignalAssert: %s:%d, %s(): failure to free non-accepted " + "signal: " SIGNAL_DATA_FMT, + file, + line, + func, + SIGNAL_DATA_ARG(data)); - g_signal_handler_disconnect (NM_PLATFORM_GET, data->handler_id); - g_free (data); + g_signal_handler_disconnect(NM_PLATFORM_GET, data->handler_id); + g_free(data); } void -link_callback (NMPlatform *platform, int obj_type_i, int ifindex, NMPlatformLink *received, int change_type_i, SignalData *data) -{ - const NMPObjectType obj_type = obj_type_i; - const NMPlatformSignalChangeType change_type = change_type_i; - NMPLookup lookup; - NMDedupMultiIter iter; - const NMPlatformLink *cached; - - g_assert_cmpint (obj_type, ==, NMP_OBJECT_TYPE_LINK); - g_assert (received); - g_assert_cmpint (received->ifindex, ==, ifindex); - g_assert (data && data->name); - g_assert_cmpstr (data->name, ==, NM_PLATFORM_SIGNAL_LINK_CHANGED); - - if (data->ifindex && data->ifindex != received->ifindex) - return; - if (data->ifname && g_strcmp0 (data->ifname, nm_platform_link_get_name (NM_PLATFORM_GET, ifindex)) != 0) - return; - if (change_type != data->change_type) - return; - - if (data->loop) { - _LOGD ("Quitting main loop."); - g_main_loop_quit (data->loop); - } - - data->received_count++; - _LOGD ("Received signal '%s-%s' ifindex %d ifname '%s' %dth time.", data->name, nm_platform_signal_change_type_to_string (data->change_type), ifindex, received->name, data->received_count); - - if (change_type == NM_PLATFORM_SIGNAL_REMOVED) - g_assert (!nm_platform_link_get_name (NM_PLATFORM_GET, ifindex)); - else - g_assert (nm_platform_link_get_name (NM_PLATFORM_GET, ifindex)); - - /* Check the data */ - g_assert (received->ifindex > 0); - - nmp_lookup_init_obj_type (&lookup, NMP_OBJECT_TYPE_LINK); - nmp_cache_iter_for_each_link (&iter, - nm_platform_lookup (platform, &lookup), - &cached) { - if (!nmp_object_is_visible (NMP_OBJECT_UP_CAST (cached))) - continue; - if (cached->ifindex == received->ifindex) { - g_assert_cmpint (nm_platform_link_cmp (cached, received), ==, 0); - g_assert (!memcmp (cached, received, sizeof (*cached))); - if (data->change_type == NM_PLATFORM_SIGNAL_REMOVED) - g_error ("Deleted link still found in the local cache."); - return; - } - } - - if (data->change_type != NM_PLATFORM_SIGNAL_REMOVED) - g_error ("Added/changed link not found in the local cache."); +link_callback(NMPlatform * platform, + int obj_type_i, + int ifindex, + NMPlatformLink *received, + int change_type_i, + SignalData * data) +{ + const NMPObjectType obj_type = obj_type_i; + const NMPlatformSignalChangeType change_type = change_type_i; + NMPLookup lookup; + NMDedupMultiIter iter; + const NMPlatformLink * cached; + + g_assert_cmpint(obj_type, ==, NMP_OBJECT_TYPE_LINK); + g_assert(received); + g_assert_cmpint(received->ifindex, ==, ifindex); + g_assert(data && data->name); + g_assert_cmpstr(data->name, ==, NM_PLATFORM_SIGNAL_LINK_CHANGED); + + if (data->ifindex && data->ifindex != received->ifindex) + return; + if (data->ifname + && g_strcmp0(data->ifname, nm_platform_link_get_name(NM_PLATFORM_GET, ifindex)) != 0) + return; + if (change_type != data->change_type) + return; + + if (data->loop) { + _LOGD("Quitting main loop."); + g_main_loop_quit(data->loop); + } + + data->received_count++; + _LOGD("Received signal '%s-%s' ifindex %d ifname '%s' %dth time.", + data->name, + nm_platform_signal_change_type_to_string(data->change_type), + ifindex, + received->name, + data->received_count); + + if (change_type == NM_PLATFORM_SIGNAL_REMOVED) + g_assert(!nm_platform_link_get_name(NM_PLATFORM_GET, ifindex)); + else + g_assert(nm_platform_link_get_name(NM_PLATFORM_GET, ifindex)); + + /* Check the data */ + g_assert(received->ifindex > 0); + + nmp_lookup_init_obj_type(&lookup, NMP_OBJECT_TYPE_LINK); + nmp_cache_iter_for_each_link (&iter, nm_platform_lookup(platform, &lookup), &cached) { + if (!nmp_object_is_visible(NMP_OBJECT_UP_CAST(cached))) + continue; + if (cached->ifindex == received->ifindex) { + g_assert_cmpint(nm_platform_link_cmp(cached, received), ==, 0); + g_assert(!memcmp(cached, received, sizeof(*cached))); + if (data->change_type == NM_PLATFORM_SIGNAL_REMOVED) + g_error("Deleted link still found in the local cache."); + return; + } + } + + if (data->change_type != NM_PLATFORM_SIGNAL_REMOVED) + g_error("Added/changed link not found in the local cache."); } /*****************************************************************************/ static const NMPlatformIP4Route * -_ip4_route_get (NMPlatform *platform, - int ifindex, - guint32 network, - int plen, - guint32 metric, - guint8 tos, - guint *out_c_exists) -{ - NMDedupMultiIter iter; - NMPLookup lookup; - const NMPObject *o = NULL; - guint c; - const NMPlatformIP4Route *r = NULL; - - _init_platform (&platform, FALSE); - - nmp_lookup_init_ip4_route_by_weak_id (&lookup, - network, - plen, - metric, - tos); - - c = 0; - nmp_cache_iter_for_each (&iter, - nm_platform_lookup (platform, &lookup), - &o) { - if ( NMP_OBJECT_CAST_IP4_ROUTE (o)->ifindex != ifindex - && ifindex > 0) - continue; - if (!r) - r = NMP_OBJECT_CAST_IP4_ROUTE (o); - c++; - } - - NM_SET_OUT (out_c_exists, c); - return r; +_ip4_route_get(NMPlatform *platform, + int ifindex, + guint32 network, + int plen, + guint32 metric, + guint8 tos, + guint * out_c_exists) +{ + NMDedupMultiIter iter; + NMPLookup lookup; + const NMPObject * o = NULL; + guint c; + const NMPlatformIP4Route *r = NULL; + + _init_platform(&platform, FALSE); + + nmp_lookup_init_ip4_route_by_weak_id(&lookup, network, plen, metric, tos); + + c = 0; + nmp_cache_iter_for_each (&iter, nm_platform_lookup(platform, &lookup), &o) { + if (NMP_OBJECT_CAST_IP4_ROUTE(o)->ifindex != ifindex && ifindex > 0) + continue; + if (!r) + r = NMP_OBJECT_CAST_IP4_ROUTE(o); + c++; + } + + NM_SET_OUT(out_c_exists, c); + return r; } const NMPlatformIP4Route * -_nmtstp_assert_ip4_route_exists (const char *file, - guint line, - const char *func, - NMPlatform *platform, - int c_exists, - const char *ifname, - guint32 network, - int plen, - guint32 metric, - guint8 tos) -{ - int ifindex; - guint c; - const NMPlatformIP4Route *r = NULL; - - _init_platform (&platform, FALSE); - - ifindex = -1; - if (ifname) { - ifindex = nm_platform_link_get_ifindex (platform, ifname); - g_assert (ifindex > 0); - } - - r = _ip4_route_get (platform, - ifindex, - network, - plen, - metric, - tos, - &c); - - if (c != c_exists && c_exists != -1) { - char sbuf[NM_UTILS_INET_ADDRSTRLEN]; - - g_error ("[%s:%u] %s(): The ip4 route %s/%d metric %u tos %u shall exist %u times, but platform has it %u times", - file, line, func, - _nm_utils_inet4_ntop (network, sbuf), - plen, - metric, - tos, - c_exists, - c); - } - - return r; +_nmtstp_assert_ip4_route_exists(const char *file, + guint line, + const char *func, + NMPlatform *platform, + int c_exists, + const char *ifname, + guint32 network, + int plen, + guint32 metric, + guint8 tos) +{ + int ifindex; + guint c; + const NMPlatformIP4Route *r = NULL; + + _init_platform(&platform, FALSE); + + ifindex = -1; + if (ifname) { + ifindex = nm_platform_link_get_ifindex(platform, ifname); + g_assert(ifindex > 0); + } + + r = _ip4_route_get(platform, ifindex, network, plen, metric, tos, &c); + + if (c != c_exists && c_exists != -1) { + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + + g_error("[%s:%u] %s(): The ip4 route %s/%d metric %u tos %u shall exist %u times, but " + "platform has it %u times", + file, + line, + func, + _nm_utils_inet4_ntop(network, sbuf), + plen, + metric, + tos, + c_exists, + c); + } + + return r; } const NMPlatformIP4Route * -nmtstp_ip4_route_get (NMPlatform *platform, - int ifindex, - guint32 network, - int plen, - guint32 metric, - guint8 tos) -{ - return _ip4_route_get (platform, - ifindex, - network, - plen, - metric, - tos, - NULL); +nmtstp_ip4_route_get(NMPlatform *platform, + int ifindex, + guint32 network, + int plen, + guint32 metric, + guint8 tos) +{ + return _ip4_route_get(platform, ifindex, network, plen, metric, tos, NULL); } /*****************************************************************************/ static const NMPlatformIP6Route * -_ip6_route_get (NMPlatform *platform, - int ifindex, - const struct in6_addr *network, - guint plen, - guint32 metric, - const struct in6_addr *src, - guint8 src_plen, - guint *out_c_exists) -{ - NMDedupMultiIter iter; - NMPLookup lookup; - const NMPObject *o = NULL; - guint c; - const NMPlatformIP6Route *r = NULL; - - _init_platform (&platform, FALSE); - - nmp_lookup_init_ip6_route_by_weak_id (&lookup, - network, - plen, - metric, - src, - src_plen); - - c = 0; - nmp_cache_iter_for_each (&iter, - nm_platform_lookup (platform, &lookup), - &o) { - if ( NMP_OBJECT_CAST_IP6_ROUTE (o)->ifindex != ifindex - && ifindex > 0) - continue; - if (!r) - r = NMP_OBJECT_CAST_IP6_ROUTE (o); - c++; - } - - NM_SET_OUT (out_c_exists, c); - return r; +_ip6_route_get(NMPlatform * platform, + int ifindex, + const struct in6_addr *network, + guint plen, + guint32 metric, + const struct in6_addr *src, + guint8 src_plen, + guint * out_c_exists) +{ + NMDedupMultiIter iter; + NMPLookup lookup; + const NMPObject * o = NULL; + guint c; + const NMPlatformIP6Route *r = NULL; + + _init_platform(&platform, FALSE); + + nmp_lookup_init_ip6_route_by_weak_id(&lookup, network, plen, metric, src, src_plen); + + c = 0; + nmp_cache_iter_for_each (&iter, nm_platform_lookup(platform, &lookup), &o) { + if (NMP_OBJECT_CAST_IP6_ROUTE(o)->ifindex != ifindex && ifindex > 0) + continue; + if (!r) + r = NMP_OBJECT_CAST_IP6_ROUTE(o); + c++; + } + + NM_SET_OUT(out_c_exists, c); + return r; } const NMPlatformIP6Route * -_nmtstp_assert_ip6_route_exists (const char *file, - guint line, - const char *func, - NMPlatform *platform, - int c_exists, - const char *ifname, - const struct in6_addr *network, - guint plen, - guint32 metric, - const struct in6_addr *src, - guint8 src_plen) -{ - int ifindex; - guint c; - const NMPlatformIP6Route *r = NULL; - - _init_platform (&platform, FALSE); - - ifindex = -1; - if (ifname) { - ifindex = nm_platform_link_get_ifindex (platform, ifname); - g_assert (ifindex > 0); - } - - r = _ip6_route_get (platform, - ifindex, - network, - plen, - metric, - src, - src_plen, - &c); - - if (c != c_exists && c_exists != -1) { - char s_src[NM_UTILS_INET_ADDRSTRLEN]; - char s_network[NM_UTILS_INET_ADDRSTRLEN]; - - g_error ("[%s:%u] %s(): The ip6 route %s/%d metric %u src %s/%d shall exist %u times, but platform has it %u times", - file, line, func, - _nm_utils_inet6_ntop (network, s_network), - plen, - metric, - _nm_utils_inet6_ntop (src, s_src), - src_plen, - c_exists, - c); - } - - return r; +_nmtstp_assert_ip6_route_exists(const char * file, + guint line, + const char * func, + NMPlatform * platform, + int c_exists, + const char * ifname, + const struct in6_addr *network, + guint plen, + guint32 metric, + const struct in6_addr *src, + guint8 src_plen) +{ + int ifindex; + guint c; + const NMPlatformIP6Route *r = NULL; + + _init_platform(&platform, FALSE); + + ifindex = -1; + if (ifname) { + ifindex = nm_platform_link_get_ifindex(platform, ifname); + g_assert(ifindex > 0); + } + + r = _ip6_route_get(platform, ifindex, network, plen, metric, src, src_plen, &c); + + if (c != c_exists && c_exists != -1) { + char s_src[NM_UTILS_INET_ADDRSTRLEN]; + char s_network[NM_UTILS_INET_ADDRSTRLEN]; + + g_error("[%s:%u] %s(): The ip6 route %s/%d metric %u src %s/%d shall exist %u times, but " + "platform has it %u times", + file, + line, + func, + _nm_utils_inet6_ntop(network, s_network), + plen, + metric, + _nm_utils_inet6_ntop(src, s_src), + src_plen, + c_exists, + c); + } + + return r; } const NMPlatformIP6Route * -nmtstp_ip6_route_get (NMPlatform *platform, - int ifindex, - const struct in6_addr *network, - guint plen, - guint32 metric, - const struct in6_addr *src, - guint8 src_plen) -{ - return _ip6_route_get (platform, - ifindex, - network, - plen, - metric, - src, - src_plen, - NULL); +nmtstp_ip6_route_get(NMPlatform * platform, + int ifindex, + const struct in6_addr *network, + guint plen, + guint32 metric, + const struct in6_addr *src, + guint8 src_plen) +{ + return _ip6_route_get(platform, ifindex, network, plen, metric, src, src_plen, NULL); } /*****************************************************************************/ int -nmtstp_run_command (const char *format, ...) +nmtstp_run_command(const char *format, ...) { - int result; - gs_free char *command = NULL; - va_list ap; + int result; + gs_free char *command = NULL; + va_list ap; - va_start (ap, format); - command = g_strdup_vprintf (format, ap); - va_end (ap); + va_start(ap, format); + command = g_strdup_vprintf(format, ap); + va_end(ap); - _LOGD ("Running command: %s", command); - result = system (command); - _LOGD ("Command finished: result=%d", result); + _LOGD("Running command: %s", command); + result = system(command); + _LOGD("Command finished: result=%d", result); - return result; + return result; } /*****************************************************************************/ typedef struct { - GMainLoop *loop; - guint signal_counts; - guint id; + GMainLoop *loop; + guint signal_counts; + guint id; } WaitForSignalData; static void -_wait_for_signal_cb (NMPlatform *platform, - int obj_type_i, - int ifindex, - NMPlatformLink *plink, - int change_type_i, - gpointer user_data) +_wait_for_signal_cb(NMPlatform * platform, + int obj_type_i, + int ifindex, + NMPlatformLink *plink, + int change_type_i, + gpointer user_data) { - WaitForSignalData *data = user_data; + WaitForSignalData *data = user_data; - data->signal_counts++; - nm_clear_g_source (&data->id); - g_main_loop_quit (data->loop); + data->signal_counts++; + nm_clear_g_source(&data->id); + g_main_loop_quit(data->loop); } static gboolean -_wait_for_signal_timeout (gpointer user_data) +_wait_for_signal_timeout(gpointer user_data) { - WaitForSignalData *data = user_data; + WaitForSignalData *data = user_data; - g_assert (data->id); - data->id = 0; - g_main_loop_quit (data->loop); - return G_SOURCE_REMOVE; + g_assert(data->id); + data->id = 0; + g_main_loop_quit(data->loop); + return G_SOURCE_REMOVE; } guint -nmtstp_wait_for_signal (NMPlatform *platform, gint64 timeout_msec) -{ - WaitForSignalData data = { 0 }; - gulong id_link, id_ip4_address, id_ip6_address, id_ip4_route, id_ip6_route; - gulong id_qdisc, id_tfilter; - - _init_platform (&platform, FALSE); - - data.loop = g_main_loop_new (NULL, FALSE); - - id_link = g_signal_connect (platform, NM_PLATFORM_SIGNAL_LINK_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data); - id_ip4_address = g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data); - id_ip6_address = g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data); - id_ip4_route = g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data); - id_ip6_route = g_signal_connect (platform, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data); - id_qdisc = g_signal_connect (platform, NM_PLATFORM_SIGNAL_QDISC_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data); - id_tfilter = g_signal_connect (platform, NM_PLATFORM_SIGNAL_TFILTER_CHANGED, G_CALLBACK (_wait_for_signal_cb), &data); - - /* if timeout_msec is negative, it means the wait-time already expired. - * Maybe, we should do nothing and return right away, without even - * processing events from platform. However, that inconsistency (of not - * processing events from mainloop) is inconvenient. - * - * It's better that on the return of nmtstp_wait_for_signal(), we always - * have no events pending. So, a negative timeout is treated the same as - * a zero timeout: we check whether there are any events pending in platform, - * and quite the mainloop immediately afterwards. But we always check. */ - - data.id = g_timeout_add (CLAMP (timeout_msec, 0, G_MAXUINT32), - _wait_for_signal_timeout, &data); - - g_main_loop_run (data.loop); - - g_assert (!data.id); - g_assert (nm_clear_g_signal_handler (platform, &id_link)); - g_assert (nm_clear_g_signal_handler (platform, &id_ip4_address)); - g_assert (nm_clear_g_signal_handler (platform, &id_ip6_address)); - g_assert (nm_clear_g_signal_handler (platform, &id_ip4_route)); - g_assert (nm_clear_g_signal_handler (platform, &id_ip6_route)); - g_assert (nm_clear_g_signal_handler (platform, &id_tfilter)); - g_assert (nm_clear_g_signal_handler (platform, &id_qdisc)); - - nm_clear_pointer (&data.loop, g_main_loop_unref); - - /* return the number of signals, or 0 if timeout was reached .*/ - return data.signal_counts; +nmtstp_wait_for_signal(NMPlatform *platform, gint64 timeout_msec) +{ + WaitForSignalData data = {0}; + gulong id_link, id_ip4_address, id_ip6_address, id_ip4_route, id_ip6_route; + gulong id_qdisc, id_tfilter; + + _init_platform(&platform, FALSE); + + data.loop = g_main_loop_new(NULL, FALSE); + + id_link = g_signal_connect(platform, + NM_PLATFORM_SIGNAL_LINK_CHANGED, + G_CALLBACK(_wait_for_signal_cb), + &data); + id_ip4_address = g_signal_connect(platform, + NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, + G_CALLBACK(_wait_for_signal_cb), + &data); + id_ip6_address = g_signal_connect(platform, + NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, + G_CALLBACK(_wait_for_signal_cb), + &data); + id_ip4_route = g_signal_connect(platform, + NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, + G_CALLBACK(_wait_for_signal_cb), + &data); + id_ip6_route = g_signal_connect(platform, + NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, + G_CALLBACK(_wait_for_signal_cb), + &data); + id_qdisc = g_signal_connect(platform, + NM_PLATFORM_SIGNAL_QDISC_CHANGED, + G_CALLBACK(_wait_for_signal_cb), + &data); + id_tfilter = g_signal_connect(platform, + NM_PLATFORM_SIGNAL_TFILTER_CHANGED, + G_CALLBACK(_wait_for_signal_cb), + &data); + + /* if timeout_msec is negative, it means the wait-time already expired. + * Maybe, we should do nothing and return right away, without even + * processing events from platform. However, that inconsistency (of not + * processing events from mainloop) is inconvenient. + * + * It's better that on the return of nmtstp_wait_for_signal(), we always + * have no events pending. So, a negative timeout is treated the same as + * a zero timeout: we check whether there are any events pending in platform, + * and quite the mainloop immediately afterwards. But we always check. */ + + data.id = g_timeout_add(CLAMP(timeout_msec, 0, G_MAXUINT32), _wait_for_signal_timeout, &data); + + g_main_loop_run(data.loop); + + g_assert(!data.id); + g_assert(nm_clear_g_signal_handler(platform, &id_link)); + g_assert(nm_clear_g_signal_handler(platform, &id_ip4_address)); + g_assert(nm_clear_g_signal_handler(platform, &id_ip6_address)); + g_assert(nm_clear_g_signal_handler(platform, &id_ip4_route)); + g_assert(nm_clear_g_signal_handler(platform, &id_ip6_route)); + g_assert(nm_clear_g_signal_handler(platform, &id_tfilter)); + g_assert(nm_clear_g_signal_handler(platform, &id_qdisc)); + + nm_clear_pointer(&data.loop, g_main_loop_unref); + + /* return the number of signals, or 0 if timeout was reached .*/ + return data.signal_counts; } guint -nmtstp_wait_for_signal_until (NMPlatform *platform, gint64 until_ms) +nmtstp_wait_for_signal_until(NMPlatform *platform, gint64 until_ms) { - gint64 now; - guint signal_counts; + gint64 now; + guint signal_counts; - while (TRUE) { - now = nm_utils_get_monotonic_timestamp_msec (); + while (TRUE) { + now = nm_utils_get_monotonic_timestamp_msec(); - if (until_ms < now) - return 0; + if (until_ms < now) + return 0; - signal_counts = nmtstp_wait_for_signal (platform, until_ms - now); - if (signal_counts) - return signal_counts; - } + signal_counts = nmtstp_wait_for_signal(platform, until_ms - now); + if (signal_counts) + return signal_counts; + } } const NMPlatformLink * -nmtstp_wait_for_link (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, gint64 timeout_msec) +nmtstp_wait_for_link(NMPlatform *platform, + const char *ifname, + NMLinkType expected_link_type, + gint64 timeout_msec) { - return nmtstp_wait_for_link_until (platform, ifname, expected_link_type, - timeout_msec - ? nm_utils_get_monotonic_timestamp_msec () + timeout_msec - : 0); + return nmtstp_wait_for_link_until( + platform, + ifname, + expected_link_type, + timeout_msec ? nm_utils_get_monotonic_timestamp_msec() + timeout_msec : 0); } const NMPlatformLink * -nmtstp_wait_for_link_until (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, gint64 until_ms) +nmtstp_wait_for_link_until(NMPlatform *platform, + const char *ifname, + NMLinkType expected_link_type, + gint64 until_ms) { - const NMPlatformLink *plink; - gint64 now; - gboolean waited_once = FALSE; + const NMPlatformLink *plink; + gint64 now; + gboolean waited_once = FALSE; - _init_platform (&platform, FALSE); + _init_platform(&platform, FALSE); - while (TRUE) { - now = nm_utils_get_monotonic_timestamp_msec (); + while (TRUE) { + now = nm_utils_get_monotonic_timestamp_msec(); - plink = nm_platform_link_get_by_ifname (platform, ifname); - if ( plink - && (expected_link_type == NM_LINK_TYPE_NONE || plink->type == expected_link_type)) - return plink; + plink = nm_platform_link_get_by_ifname(platform, ifname); + if (plink && (expected_link_type == NM_LINK_TYPE_NONE || plink->type == expected_link_type)) + return plink; - if (until_ms == 0) { - /* don't wait, don't even poll the socket. */ - return NULL; - } + if (until_ms == 0) { + /* don't wait, don't even poll the socket. */ + return NULL; + } - if ( waited_once - && until_ms < now) { - /* timeout reached (+ we already waited for a signal at least once). */ - return NULL; - } + if (waited_once && until_ms < now) { + /* timeout reached (+ we already waited for a signal at least once). */ + return NULL; + } - waited_once = TRUE; - /* regardless of whether timeout is already reached, we poll the netlink - * socket a bit. */ - nmtstp_wait_for_signal (platform, until_ms - now); - } + waited_once = TRUE; + /* regardless of whether timeout is already reached, we poll the netlink + * socket a bit. */ + nmtstp_wait_for_signal(platform, until_ms - now); + } } /*****************************************************************************/ int -nmtstp_run_command_check_external_global (void) +nmtstp_run_command_check_external_global(void) { - if (!nmtstp_is_root_test ()) - return FALSE; - switch (nmtst_get_rand_uint32 () % 3) { - case 0: - return -1; - case 1: - return FALSE; - default: - return TRUE; - } + if (!nmtstp_is_root_test()) + return FALSE; + switch (nmtst_get_rand_uint32() % 3) { + case 0: + return -1; + case 1: + return FALSE; + default: + return TRUE; + } } gboolean -nmtstp_run_command_check_external (int external_command) +nmtstp_run_command_check_external(int external_command) { - if (external_command != -1) { - g_assert (NM_IN_SET (external_command, FALSE, TRUE)); - g_assert (!external_command || nmtstp_is_root_test ()); - return !!external_command; - } - if (!nmtstp_is_root_test ()) - return FALSE; - return (nmtst_get_rand_uint32 () % 2) == 0; + if (external_command != -1) { + g_assert(NM_IN_SET(external_command, FALSE, TRUE)); + g_assert(!external_command || nmtstp_is_root_test()); + return !!external_command; + } + if (!nmtstp_is_root_test()) + return FALSE; + return (nmtst_get_rand_uint32() % 2) == 0; } /*****************************************************************************/ -#define CHECK_LIFETIME_MAX_DIFF 2 +#define CHECK_LIFETIME_MAX_DIFF 2 gboolean -nmtstp_ip_address_check_lifetime (const NMPlatformIPAddress *addr, - gint64 now, - guint32 expected_lifetime, - guint32 expected_preferred) +nmtstp_ip_address_check_lifetime(const NMPlatformIPAddress *addr, + gint64 now, + guint32 expected_lifetime, + guint32 expected_preferred) { - gint64 offset; - int i; + gint64 offset; + int i; - g_assert (addr); + g_assert(addr); - if (now == -1) - now = nm_utils_get_monotonic_timestamp_sec (); - g_assert (now > 0); + if (now == -1) + now = nm_utils_get_monotonic_timestamp_sec(); + g_assert(now > 0); - g_assert (expected_preferred <= expected_lifetime); + g_assert(expected_preferred <= expected_lifetime); - if ( expected_lifetime == NM_PLATFORM_LIFETIME_PERMANENT - && expected_preferred == NM_PLATFORM_LIFETIME_PERMANENT) { - return addr->timestamp == 0 - && addr->lifetime == NM_PLATFORM_LIFETIME_PERMANENT - && addr->preferred == NM_PLATFORM_LIFETIME_PERMANENT; - } + if (expected_lifetime == NM_PLATFORM_LIFETIME_PERMANENT + && expected_preferred == NM_PLATFORM_LIFETIME_PERMANENT) { + return addr->timestamp == 0 && addr->lifetime == NM_PLATFORM_LIFETIME_PERMANENT + && addr->preferred == NM_PLATFORM_LIFETIME_PERMANENT; + } - if (addr->timestamp == 0) - return FALSE; + if (addr->timestamp == 0) + return FALSE; - offset = (gint64) now - addr->timestamp; + offset = (gint64) now - addr->timestamp; - for (i = 0; i < 2; i++) { - guint32 lft = i ? expected_lifetime : expected_preferred; - guint32 adr = i ? addr->lifetime : addr->preferred; + for (i = 0; i < 2; i++) { + guint32 lft = i ? expected_lifetime : expected_preferred; + guint32 adr = i ? addr->lifetime : addr->preferred; - if (lft == NM_PLATFORM_LIFETIME_PERMANENT) { - if (adr != NM_PLATFORM_LIFETIME_PERMANENT) - return FALSE; - } else { - if ( adr - offset <= lft - CHECK_LIFETIME_MAX_DIFF - || adr - offset >= lft + CHECK_LIFETIME_MAX_DIFF) - return FALSE; - } - } - return TRUE; + if (lft == NM_PLATFORM_LIFETIME_PERMANENT) { + if (adr != NM_PLATFORM_LIFETIME_PERMANENT) + return FALSE; + } else { + if (((gint64) adr) - offset <= ((gint64) lft) - CHECK_LIFETIME_MAX_DIFF + || ((gint64) adr) - offset >= ((gint64) lft) + CHECK_LIFETIME_MAX_DIFF) + return FALSE; + } + } + return TRUE; } void -nmtstp_ip_address_assert_lifetime (const NMPlatformIPAddress *addr, - gint64 now, - guint32 expected_lifetime, - guint32 expected_preferred) +nmtstp_ip_address_assert_lifetime(const NMPlatformIPAddress *addr, + gint64 now, + guint32 expected_lifetime, + guint32 expected_preferred) { - gint64 n = now; - gint64 offset; - int i; + gint64 n = now; + gint64 offset; + int i; - g_assert (addr); + g_assert(addr); - if (now == -1) - now = nm_utils_get_monotonic_timestamp_sec (); - g_assert (now > 0); + if (now == -1) + now = nm_utils_get_monotonic_timestamp_sec(); + g_assert(now > 0); - g_assert (expected_preferred <= expected_lifetime); + g_assert(expected_preferred <= expected_lifetime); - if ( expected_lifetime == NM_PLATFORM_LIFETIME_PERMANENT - && expected_preferred == NM_PLATFORM_LIFETIME_PERMANENT) { - g_assert_cmpint (addr->timestamp, ==, 0); - g_assert_cmpint (addr->lifetime, ==, NM_PLATFORM_LIFETIME_PERMANENT); - g_assert_cmpint (addr->preferred, ==, NM_PLATFORM_LIFETIME_PERMANENT); - return; - } + if (expected_lifetime == NM_PLATFORM_LIFETIME_PERMANENT + && expected_preferred == NM_PLATFORM_LIFETIME_PERMANENT) { + g_assert_cmpint(addr->timestamp, ==, 0); + g_assert_cmpint(addr->lifetime, ==, NM_PLATFORM_LIFETIME_PERMANENT); + g_assert_cmpint(addr->preferred, ==, NM_PLATFORM_LIFETIME_PERMANENT); + return; + } - g_assert_cmpint (addr->timestamp, >, 0); - g_assert_cmpint (addr->timestamp, <=, now); + g_assert_cmpint(addr->timestamp, >, 0); + g_assert_cmpint(addr->timestamp, <=, now); - offset = (gint64) now - addr->timestamp; - g_assert_cmpint (offset, >=, 0); + offset = (gint64) now - addr->timestamp; + g_assert_cmpint(offset, >=, 0); - for (i = 0; i < 2; i++) { - guint32 lft = i ? expected_lifetime : expected_preferred; - guint32 adr = i ? addr->lifetime : addr->preferred; + for (i = 0; i < 2; i++) { + guint32 lft = i ? expected_lifetime : expected_preferred; + guint32 adr = i ? addr->lifetime : addr->preferred; - if (lft == NM_PLATFORM_LIFETIME_PERMANENT) - g_assert_cmpint (adr, ==, NM_PLATFORM_LIFETIME_PERMANENT); - else { - g_assert_cmpint (adr - offset, <=, lft + CHECK_LIFETIME_MAX_DIFF); - g_assert_cmpint (adr - offset, >=, lft - CHECK_LIFETIME_MAX_DIFF); - } - } + if (lft == NM_PLATFORM_LIFETIME_PERMANENT) + g_assert_cmpint(adr, ==, NM_PLATFORM_LIFETIME_PERMANENT); + else { + g_assert_cmpint(adr - offset, <=, lft + CHECK_LIFETIME_MAX_DIFF); + g_assert_cmpint(adr - offset, >=, lft - CHECK_LIFETIME_MAX_DIFF); + } + } - g_assert (nmtstp_ip_address_check_lifetime (addr, n, expected_lifetime, expected_preferred)); + g_assert(nmtstp_ip_address_check_lifetime(addr, n, expected_lifetime, expected_preferred)); } /*****************************************************************************/ static void -_ip_address_add (NMPlatform *platform, - gboolean external_command, - gboolean is_v4, - int ifindex, - const NMIPAddr *address, - int plen, - const NMIPAddr *peer_address, - guint32 lifetime, - guint32 preferred, - guint32 flags, - const char *label) -{ - gint64 end_time; - - external_command = nmtstp_run_command_check_external (external_command); - - _init_platform (&platform, external_command); - - if (external_command) { - const char *ifname; - gs_free char *s_valid = NULL; - gs_free char *s_preferred = NULL; - gs_free char *s_label = NULL; - char b1[NM_UTILS_INET_ADDRSTRLEN]; - char b2[NM_UTILS_INET_ADDRSTRLEN]; - - ifname = nm_platform_link_get_name (platform, ifindex); - g_assert (ifname); - - if (lifetime != NM_PLATFORM_LIFETIME_PERMANENT) - s_valid = g_strdup_printf (" valid_lft %d", lifetime); - if (preferred != NM_PLATFORM_LIFETIME_PERMANENT) - s_preferred = g_strdup_printf (" preferred_lft %d", preferred); - if (label) - s_label = g_strdup_printf ("%s:%s", ifname, label); - - if (is_v4) { - char s_peer[NM_UTILS_INET_ADDRSTRLEN + 50]; - - g_assert (flags == 0); - - if ( peer_address->addr4 != address->addr4 - || nmtst_get_rand_uint32 () % 2) { - /* If the peer is the same as the local address, we can omit it. The result should be identical */ - nm_sprintf_buf (s_peer, " peer %s", _nm_utils_inet4_ntop (peer_address->addr4, b2)); - } else - s_peer[0] = '\0'; - - nmtstp_run_command_check ("ip address change %s%s/%d dev %s%s%s%s", - _nm_utils_inet4_ntop (address->addr4, b1), - s_peer, - plen, - ifname, - s_valid ?: "", - s_preferred ?: "", - s_label ?: ""); - } else { - g_assert (label == NULL); - - /* flags not implemented (yet) */ - g_assert (flags == 0); - nmtstp_run_command_check ("ip address change %s%s%s/%d dev %s%s%s%s", - _nm_utils_inet6_ntop (&address->addr6, b1), - !IN6_IS_ADDR_UNSPECIFIED (&peer_address->addr6) ? " peer " : "", - !IN6_IS_ADDR_UNSPECIFIED (&peer_address->addr6) ? _nm_utils_inet6_ntop (&peer_address->addr6, b2) : "", - plen, - ifname, - s_valid ?: "", - s_preferred ?: "", - s_label ?: ""); - } - } else { - gboolean success; - - if (is_v4) { - success = nm_platform_ip4_address_add (platform, - ifindex, - address->addr4, - plen, - peer_address->addr4, - 0u, - lifetime, - preferred, - flags, - label); - } else { - g_assert (label == NULL); - success = nm_platform_ip6_address_add (platform, - ifindex, - address->addr6, - plen, - peer_address->addr6, - lifetime, - preferred, - flags); - } - g_assert (success); - } - - /* Let's wait until we see the address. */ - end_time = nm_utils_get_monotonic_timestamp_msec () + 500; - do { - - if (external_command) - nm_platform_process_events (platform); - - /* let's wait until we see the address as we added it. */ - if (is_v4) { - const NMPlatformIP4Address *a; - - g_assert (flags == 0); - a = nm_platform_ip4_address_get (platform, ifindex, address->addr4, plen, peer_address->addr4); - if ( a - && a->peer_address == peer_address->addr4 - && nmtstp_ip_address_check_lifetime ((NMPlatformIPAddress*) a, -1, lifetime, preferred) - && strcmp (a->label, label ?: "") == 0) - break; - } else { - const NMPlatformIP6Address *a; - - g_assert (label == NULL); - g_assert (flags == 0); - - a = nm_platform_ip6_address_get (platform, ifindex, address->addr6); - if ( a - && !memcmp (nm_platform_ip6_address_get_peer (a), - (IN6_IS_ADDR_UNSPECIFIED (&peer_address->addr6) || IN6_ARE_ADDR_EQUAL (&address->addr6, &peer_address->addr6)) - ? &address->addr6 : &peer_address->addr6, - sizeof (struct in6_addr)) - && nmtstp_ip_address_check_lifetime ((NMPlatformIPAddress*) a, -1, lifetime, preferred)) - break; - } - - /* for internal command, we expect not to reach this line.*/ - g_assert (external_command); - - nmtstp_assert_wait_for_signal_until (platform, end_time); - } while (TRUE); +_ip_address_add(NMPlatform * platform, + gboolean external_command, + gboolean is_v4, + int ifindex, + const NMIPAddr *address, + int plen, + const NMIPAddr *peer_address, + guint32 lifetime, + guint32 preferred, + guint32 flags, + const char * label) +{ + gint64 end_time; + + external_command = nmtstp_run_command_check_external(external_command); + + _init_platform(&platform, external_command); + + if (external_command) { + const char * ifname; + gs_free char *s_valid = NULL; + gs_free char *s_preferred = NULL; + gs_free char *s_label = NULL; + char b1[NM_UTILS_INET_ADDRSTRLEN]; + char b2[NM_UTILS_INET_ADDRSTRLEN]; + + ifname = nm_platform_link_get_name(platform, ifindex); + g_assert(ifname); + + if (lifetime != NM_PLATFORM_LIFETIME_PERMANENT) + s_valid = g_strdup_printf(" valid_lft %d", lifetime); + if (preferred != NM_PLATFORM_LIFETIME_PERMANENT) + s_preferred = g_strdup_printf(" preferred_lft %d", preferred); + if (label) + s_label = g_strdup_printf("%s:%s", ifname, label); + + if (is_v4) { + char s_peer[NM_UTILS_INET_ADDRSTRLEN + 50]; + + g_assert(flags == 0); + + if (peer_address->addr4 != address->addr4 || nmtst_get_rand_uint32() % 2) { + /* If the peer is the same as the local address, we can omit it. The result should be identical */ + nm_sprintf_buf(s_peer, " peer %s", _nm_utils_inet4_ntop(peer_address->addr4, b2)); + } else + s_peer[0] = '\0'; + + nmtstp_run_command_check("ip address change %s%s/%d dev %s%s%s%s", + _nm_utils_inet4_ntop(address->addr4, b1), + s_peer, + plen, + ifname, + s_valid ?: "", + s_preferred ?: "", + s_label ?: ""); + } else { + g_assert(label == NULL); + + /* flags not implemented (yet) */ + g_assert(flags == 0); + nmtstp_run_command_check("ip address change %s%s%s/%d dev %s%s%s%s", + _nm_utils_inet6_ntop(&address->addr6, b1), + !IN6_IS_ADDR_UNSPECIFIED(&peer_address->addr6) ? " peer " : "", + !IN6_IS_ADDR_UNSPECIFIED(&peer_address->addr6) + ? _nm_utils_inet6_ntop(&peer_address->addr6, b2) + : "", + plen, + ifname, + s_valid ?: "", + s_preferred ?: "", + s_label ?: ""); + } + } else { + gboolean success; + + if (is_v4) { + success = nm_platform_ip4_address_add(platform, + ifindex, + address->addr4, + plen, + peer_address->addr4, + 0u, + lifetime, + preferred, + flags, + label); + } else { + g_assert(label == NULL); + success = nm_platform_ip6_address_add(platform, + ifindex, + address->addr6, + plen, + peer_address->addr6, + lifetime, + preferred, + flags); + } + g_assert(success); + } + + /* Let's wait until we see the address. */ + end_time = nm_utils_get_monotonic_timestamp_msec() + 500; + do { + if (external_command) + nm_platform_process_events(platform); + + /* let's wait until we see the address as we added it. */ + if (is_v4) { + const NMPlatformIP4Address *a; + + g_assert(flags == 0); + a = nm_platform_ip4_address_get(platform, + ifindex, + address->addr4, + plen, + peer_address->addr4); + if (a && a->peer_address == peer_address->addr4 + && nmtstp_ip_address_check_lifetime((NMPlatformIPAddress *) a, + -1, + lifetime, + preferred) + && strcmp(a->label, label ?: "") == 0) + break; + } else { + const NMPlatformIP6Address *a; + + g_assert(label == NULL); + g_assert(flags == 0); + + a = nm_platform_ip6_address_get(platform, ifindex, &address->addr6); + if (a + && !memcmp(nm_platform_ip6_address_get_peer(a), + (IN6_IS_ADDR_UNSPECIFIED(&peer_address->addr6) + || IN6_ARE_ADDR_EQUAL(&address->addr6, &peer_address->addr6)) + ? &address->addr6 + : &peer_address->addr6, + sizeof(struct in6_addr)) + && nmtstp_ip_address_check_lifetime((NMPlatformIPAddress *) a, + -1, + lifetime, + preferred)) + break; + } + + /* for internal command, we expect not to reach this line.*/ + g_assert(external_command); + + nmtstp_assert_wait_for_signal_until(platform, end_time); + } while (TRUE); +} + +void +nmtstp_ip4_address_add(NMPlatform *platform, + gboolean external_command, + int ifindex, + in_addr_t address, + int plen, + in_addr_t peer_address, + guint32 lifetime, + guint32 preferred, + guint32 flags, + const char *label) +{ + _ip_address_add(platform, + external_command, + TRUE, + ifindex, + (NMIPAddr *) &address, + plen, + (NMIPAddr *) &peer_address, + lifetime, + preferred, + flags, + label); +} + +void +nmtstp_ip6_address_add(NMPlatform * platform, + gboolean external_command, + int ifindex, + struct in6_addr address, + int plen, + struct in6_addr peer_address, + guint32 lifetime, + guint32 preferred, + guint32 flags) +{ + _ip_address_add(platform, + external_command, + FALSE, + ifindex, + (NMIPAddr *) &address, + plen, + (NMIPAddr *) &peer_address, + lifetime, + preferred, + flags, + NULL); } void -nmtstp_ip4_address_add (NMPlatform *platform, - gboolean external_command, - int ifindex, - in_addr_t address, - int plen, - in_addr_t peer_address, - guint32 lifetime, - guint32 preferred, - guint32 flags, - const char *label) -{ - _ip_address_add (platform, - external_command, - TRUE, - ifindex, - (NMIPAddr *) &address, - plen, - (NMIPAddr *) &peer_address, - lifetime, - preferred, - flags, - label); +nmtstp_ip4_route_add(NMPlatform * platform, + int ifindex, + NMIPConfigSource source, + in_addr_t network, + guint8 plen, + in_addr_t gateway, + in_addr_t pref_src, + guint32 metric, + guint32 mss) +{ + NMPlatformIP4Route route = {}; + + route.ifindex = ifindex; + route.rt_source = source; + route.network = network; + route.plen = plen; + route.gateway = gateway; + route.pref_src = pref_src; + route.metric = metric; + route.mss = mss; + + g_assert( + NMTST_NM_ERR_SUCCESS(nm_platform_ip4_route_add(platform, NMP_NLM_FLAG_REPLACE, &route))); } void -nmtstp_ip6_address_add (NMPlatform *platform, - gboolean external_command, - int ifindex, - struct in6_addr address, - int plen, - struct in6_addr peer_address, - guint32 lifetime, - guint32 preferred, - guint32 flags) -{ - _ip_address_add (platform, - external_command, - FALSE, - ifindex, - (NMIPAddr *) &address, - plen, - (NMIPAddr *) &peer_address, - lifetime, - preferred, - flags, - NULL); -} - -void nmtstp_ip4_route_add (NMPlatform *platform, - int ifindex, - NMIPConfigSource source, - in_addr_t network, - guint8 plen, - in_addr_t gateway, - in_addr_t pref_src, - guint32 metric, - guint32 mss) -{ - NMPlatformIP4Route route = { }; - - route.ifindex = ifindex; - route.rt_source = source; - route.network = network; - route.plen = plen; - route.gateway = gateway; - route.pref_src = pref_src; - route.metric = metric; - route.mss = mss; - - g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_ip4_route_add (platform, NMP_NLM_FLAG_REPLACE, &route))); -} - -void nmtstp_ip6_route_add (NMPlatform *platform, - int ifindex, - NMIPConfigSource source, - struct in6_addr network, - guint8 plen, - struct in6_addr gateway, - struct in6_addr pref_src, - guint32 metric, - guint32 mss) -{ - NMPlatformIP6Route route = { }; - - route.ifindex = ifindex; - route.rt_source = source; - route.network = network; - route.plen = plen; - route.gateway = gateway; - route.pref_src = pref_src; - route.metric = metric; - route.mss = mss; - - g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_ip6_route_add (platform, NMP_NLM_FLAG_REPLACE, &route))); +nmtstp_ip6_route_add(NMPlatform * platform, + int ifindex, + NMIPConfigSource source, + struct in6_addr network, + guint8 plen, + struct in6_addr gateway, + struct in6_addr pref_src, + guint32 metric, + guint32 mss) +{ + NMPlatformIP6Route route = {}; + + route.ifindex = ifindex; + route.rt_source = source; + route.network = network; + route.plen = plen; + route.gateway = gateway; + route.pref_src = pref_src; + route.metric = metric; + route.mss = mss; + + g_assert( + NMTST_NM_ERR_SUCCESS(nm_platform_ip6_route_add(platform, NMP_NLM_FLAG_REPLACE, &route))); } /*****************************************************************************/ static void -_ip_address_del (NMPlatform *platform, - gboolean external_command, - gboolean is_v4, - int ifindex, - const NMIPAddr *address, - int plen, - const NMIPAddr *peer_address) -{ - gint64 end_time; - - external_command = nmtstp_run_command_check_external (external_command); - - _init_platform (&platform, external_command); - - if (external_command) { - const char *ifname; - char b1[NM_UTILS_INET_ADDRSTRLEN]; - char b2[NM_UTILS_INET_ADDRSTRLEN]; - int success; - gboolean had_address; - - ifname = nm_platform_link_get_name (platform, ifindex); - g_assert (ifname); - - /* let's wait until we see the address as we added it. */ - if (is_v4) - had_address = !!nm_platform_ip4_address_get (platform, ifindex, address->addr4, plen, peer_address->addr4); - else - had_address = !!nm_platform_ip6_address_get (platform, ifindex, address->addr6); - - if (is_v4) { - success = nmtstp_run_command ("ip address delete %s%s%s/%d dev %s", - _nm_utils_inet4_ntop (address->addr4, b1), - peer_address->addr4 != address->addr4 ? " peer " : "", - peer_address->addr4 != address->addr4 ? _nm_utils_inet4_ntop (peer_address->addr4, b2) : "", - plen, - ifname); - } else { - g_assert (!peer_address); - success = nmtstp_run_command ("ip address delete %s/%d dev %s", - _nm_utils_inet6_ntop (&address->addr6, b1), - plen, - ifname); - } - g_assert (success == 0 || !had_address); - } else { - gboolean success; - - if (is_v4) { - success = nm_platform_ip4_address_delete (platform, - ifindex, - address->addr4, - plen, - peer_address->addr4); - } else { - g_assert (!peer_address); - success = nm_platform_ip6_address_delete (platform, - ifindex, - address->addr6, - plen); - } - g_assert (success); - } - - /* Let's wait until we get the result */ - end_time = nm_utils_get_monotonic_timestamp_msec () + 250; - do { - if (external_command) - nm_platform_process_events (platform); - - /* let's wait until we see the address as we added it. */ - if (is_v4) { - const NMPlatformIP4Address *a; - - a = nm_platform_ip4_address_get (platform, ifindex, address->addr4, plen, peer_address->addr4); - if (!a) - break; - } else { - const NMPlatformIP6Address *a; - - a = nm_platform_ip6_address_get (platform, ifindex, address->addr6); - if (!a) - break; - } - - /* for internal command, we expect not to reach this line.*/ - g_assert (external_command); - - nmtstp_assert_wait_for_signal_until (platform, end_time); - } while (TRUE); +_ip_address_del(NMPlatform * platform, + gboolean external_command, + gboolean is_v4, + int ifindex, + const NMIPAddr *address, + int plen, + const NMIPAddr *peer_address) +{ + gint64 end_time; + + external_command = nmtstp_run_command_check_external(external_command); + + _init_platform(&platform, external_command); + + if (external_command) { + const char *ifname; + char b1[NM_UTILS_INET_ADDRSTRLEN]; + char b2[NM_UTILS_INET_ADDRSTRLEN]; + int success; + gboolean had_address; + + ifname = nm_platform_link_get_name(platform, ifindex); + g_assert(ifname); + + /* let's wait until we see the address as we added it. */ + if (is_v4) + had_address = !!nm_platform_ip4_address_get(platform, + ifindex, + address->addr4, + plen, + peer_address->addr4); + else + had_address = !!nm_platform_ip6_address_get(platform, ifindex, &address->addr6); + + if (is_v4) { + success = nmtstp_run_command("ip address delete %s%s%s/%d dev %s", + _nm_utils_inet4_ntop(address->addr4, b1), + peer_address->addr4 != address->addr4 ? " peer " : "", + peer_address->addr4 != address->addr4 + ? _nm_utils_inet4_ntop(peer_address->addr4, b2) + : "", + plen, + ifname); + } else { + g_assert(!peer_address); + success = nmtstp_run_command("ip address delete %s/%d dev %s", + _nm_utils_inet6_ntop(&address->addr6, b1), + plen, + ifname); + } + g_assert(success == 0 || !had_address); + } else { + gboolean success; + + if (is_v4) { + success = nm_platform_ip4_address_delete(platform, + ifindex, + address->addr4, + plen, + peer_address->addr4); + } else { + g_assert(!peer_address); + success = nm_platform_ip6_address_delete(platform, ifindex, address->addr6, plen); + } + g_assert(success); + } + + /* Let's wait until we get the result */ + end_time = nm_utils_get_monotonic_timestamp_msec() + 250; + do { + if (external_command) + nm_platform_process_events(platform); + + /* let's wait until we see the address as we added it. */ + if (is_v4) { + const NMPlatformIP4Address *a; + + a = nm_platform_ip4_address_get(platform, + ifindex, + address->addr4, + plen, + peer_address->addr4); + if (!a) + break; + } else { + const NMPlatformIP6Address *a; + + a = nm_platform_ip6_address_get(platform, ifindex, &address->addr6); + if (!a) + break; + } + + /* for internal command, we expect not to reach this line.*/ + g_assert(external_command); + + nmtstp_assert_wait_for_signal_until(platform, end_time); + } while (TRUE); } void -nmtstp_ip4_address_del (NMPlatform *platform, - gboolean external_command, - int ifindex, - in_addr_t address, - int plen, - in_addr_t peer_address) -{ - _ip_address_del (platform, - external_command, - TRUE, - ifindex, - (NMIPAddr *) &address, - plen, - (NMIPAddr *) &peer_address); +nmtstp_ip4_address_del(NMPlatform *platform, + gboolean external_command, + int ifindex, + in_addr_t address, + int plen, + in_addr_t peer_address) +{ + _ip_address_del(platform, + external_command, + TRUE, + ifindex, + (NMIPAddr *) &address, + plen, + (NMIPAddr *) &peer_address); } void -nmtstp_ip6_address_del (NMPlatform *platform, - gboolean external_command, - int ifindex, - struct in6_addr address, - int plen) +nmtstp_ip6_address_del(NMPlatform * platform, + gboolean external_command, + int ifindex, + struct in6_addr address, + int plen) { - _ip_address_del (platform, - external_command, - FALSE, - ifindex, - (NMIPAddr *) &address, - plen, - NULL); + _ip_address_del(platform, external_command, FALSE, ifindex, (NMIPAddr *) &address, plen, NULL); } /*****************************************************************************/ -#define _assert_pllink(platform, success, pllink, name, type) \ - G_STMT_START { \ - const NMPlatformLink *_pllink = (pllink); \ - \ - if ((success)) { \ - g_assert (_pllink); \ - g_assert (_pllink == nmtstp_link_get_typed (platform, _pllink->ifindex, (name), (type))); \ - } else { \ - g_assert (!_pllink); \ - g_assert (!nmtstp_link_get (platform, 0, (name))); \ - } \ - } G_STMT_END +#define _assert_pllink(platform, success, pllink, name, type) \ + G_STMT_START \ + { \ + const NMPlatformLink *_pllink = (pllink); \ + \ + if ((success)) { \ + g_assert(_pllink); \ + g_assert(_pllink \ + == nmtstp_link_get_typed(platform, _pllink->ifindex, (name), (type))); \ + } else { \ + g_assert(!_pllink); \ + g_assert(!nmtstp_link_get(platform, 0, (name))); \ + } \ + } \ + G_STMT_END const NMPlatformLink * -nmtstp_link_veth_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const char *peer) +nmtstp_link_bridge_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkBridge *lnk) +{ + const NMPlatformLink * pllink = NULL; + const NMPlatformLnkBridge *ll = NULL; + int r = 0; + + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); + + external_command = nmtstp_run_command_check_external(external_command); + + _init_platform(&platform, external_command); + + if (external_command) { + char sbuf_gfw[100]; + char sbuf_mhm[100]; + char sbuf_mlmc[100]; + char sbuf_mlmi[100]; + char sbuf_mmi[100]; + char sbuf_mqi[100]; + char sbuf_mqii[100]; + char sbuf_msqc[100]; + char sbuf_msqi[100]; + char sbuf_mqri[100]; + + r = nmtstp_run_command( + "ip link add %s type bridge " + "forward_delay %u " + "hello_time %u " + "max_age %u " + "ageing_time %u " + "stp_state %d " + "priority %u " + "vlan_protocol %u " + "vlan_stats_enabled %d " + "%s" /* group_fwd_mask */ + "group_address " NM_ETHER_ADDR_FORMAT_STR " " + "mcast_snooping %d " + "mcast_router %u " + "mcast_query_use_ifaddr %d " + "mcast_querier %d " + "%s" /* mcast_hash_max */ + "%s" /* mcast_last_member_count */ + "%s" /* mcast_startup_query_count */ + "%s" /* mcast_last_member_interval */ + "%s" /* mcast_membership_interval */ + "%s" /* mcast_querier_interval */ + "%s" /* mcast_query_interval */ + "%s" /* mcast_query_response_interval */ + "%s" /* mcast_startup_query_interval */ + "", + name, + lnk->forward_delay, + lnk->hello_time, + lnk->max_age, + lnk->ageing_time, + (int) lnk->stp_state, + lnk->priority, + lnk->vlan_protocol, + (int) lnk->vlan_stats_enabled, + lnk->group_fwd_mask != 0 + ? nm_sprintf_buf(sbuf_gfw, "group_fwd_mask %#x ", lnk->group_fwd_mask) + : "", + NM_ETHER_ADDR_FORMAT_VAL(lnk->group_addr), + (int) lnk->mcast_snooping, + lnk->mcast_router, + (int) lnk->mcast_query_use_ifaddr, + (int) lnk->mcast_querier, + lnk->mcast_hash_max != NM_BRIDGE_MULTICAST_HASH_MAX_DEF + ? nm_sprintf_buf(sbuf_mhm, "mcast_hash_max %u ", lnk->mcast_hash_max) + : "", + lnk->mcast_last_member_count != NM_BRIDGE_MULTICAST_LAST_MEMBER_COUNT_DEF + ? nm_sprintf_buf(sbuf_mlmc, + "mcast_last_member_count %u ", + lnk->mcast_last_member_count) + : "", + lnk->mcast_startup_query_count != NM_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT_DEF + ? nm_sprintf_buf(sbuf_msqc, + "mcast_startup_query_count %u ", + lnk->mcast_startup_query_count) + : "", + lnk->mcast_last_member_interval != NM_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL_DEF + ? nm_sprintf_buf(sbuf_mlmi, + "mcast_last_member_interval %" G_GUINT64_FORMAT " ", + lnk->mcast_last_member_interval) + : "", + lnk->mcast_membership_interval != NM_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL_DEF + ? nm_sprintf_buf(sbuf_mmi, + "mcast_membership_interval %" G_GUINT64_FORMAT " ", + lnk->mcast_membership_interval) + : "", + lnk->mcast_querier_interval != NM_BRIDGE_MULTICAST_QUERIER_INTERVAL_DEF + ? nm_sprintf_buf(sbuf_mqi, + "mcast_querier_interval %" G_GUINT64_FORMAT " ", + lnk->mcast_querier_interval) + : "", + lnk->mcast_query_interval != NM_BRIDGE_MULTICAST_QUERY_INTERVAL_DEF + ? nm_sprintf_buf(sbuf_mqii, + "mcast_query_interval %" G_GUINT64_FORMAT " ", + lnk->mcast_query_interval) + : "", + lnk->mcast_query_response_interval != NM_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL_DEF + ? nm_sprintf_buf(sbuf_mqri, + "mcast_query_response_interval %" G_GUINT64_FORMAT " ", + lnk->mcast_query_response_interval) + : "", + lnk->mcast_startup_query_interval != NM_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL_DEF + ? nm_sprintf_buf(sbuf_msqi, + "mcast_startup_query_interval %" G_GUINT64_FORMAT " ", + lnk->mcast_startup_query_interval) + : ""); + if (r == 0) + pllink = nmtstp_assert_wait_for_link(platform, name, NM_LINK_TYPE_BRIDGE, 100); + else + _LOGI( + "Adding bridge device via iproute2 failed. Assume iproute2 is not up to the task."); + } + + if (!pllink) { + r = nm_platform_link_bridge_add(platform, name, NULL, 0, lnk, &pllink); + } + + _assert_pllink(platform, r == 0, pllink, name, NM_LINK_TYPE_BRIDGE); + + ll = NMP_OBJECT_CAST_LNK_BRIDGE(NMP_OBJECT_UP_CAST(pllink)->_link.netlink.lnk); + + g_assert_cmpint(lnk->forward_delay, ==, ll->forward_delay); + g_assert_cmpint(lnk->hello_time, ==, ll->hello_time); + g_assert_cmpint(lnk->max_age, ==, ll->max_age); + g_assert_cmpint(lnk->ageing_time, ==, ll->ageing_time); + g_assert_cmpint(lnk->stp_state, ==, ll->stp_state); + g_assert_cmpint(lnk->priority, ==, ll->priority); + g_assert_cmpint(lnk->vlan_stats_enabled, ==, ll->vlan_stats_enabled); + g_assert_cmpint(lnk->group_fwd_mask, ==, ll->group_fwd_mask); + g_assert_cmpint(lnk->mcast_snooping, ==, ll->mcast_snooping); + g_assert_cmpint(lnk->mcast_router, ==, ll->mcast_router); + g_assert_cmpint(lnk->mcast_query_use_ifaddr, ==, ll->mcast_query_use_ifaddr); + g_assert_cmpint(lnk->mcast_querier, ==, ll->mcast_querier); + g_assert_cmpint(lnk->mcast_hash_max, ==, ll->mcast_hash_max); + g_assert_cmpint(lnk->mcast_last_member_count, ==, ll->mcast_last_member_count); + g_assert_cmpint(lnk->mcast_startup_query_count, ==, ll->mcast_startup_query_count); + g_assert_cmpint(lnk->mcast_last_member_interval, ==, ll->mcast_last_member_interval); + g_assert_cmpint(lnk->mcast_membership_interval, ==, ll->mcast_membership_interval); + g_assert_cmpint(lnk->mcast_querier_interval, ==, ll->mcast_querier_interval); + g_assert_cmpint(lnk->mcast_query_interval, ==, ll->mcast_query_interval); + g_assert_cmpint(lnk->mcast_query_response_interval, ==, ll->mcast_query_response_interval); + g_assert_cmpint(lnk->mcast_startup_query_interval, ==, ll->mcast_startup_query_interval); + + return pllink; +} +const NMPlatformLink * +nmtstp_link_veth_add(NMPlatform *platform, + gboolean external_command, + const char *name, + const char *peer) { - const NMPlatformLink *pllink = NULL; - gboolean success; + const NMPlatformLink *pllink = NULL; + gboolean success; - g_assert (nm_utils_ifname_valid_kernel (name, NULL)); + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); - external_command = nmtstp_run_command_check_external (external_command); + external_command = nmtstp_run_command_check_external(external_command); - _init_platform (&platform, external_command); + _init_platform(&platform, external_command); - if (external_command) { - success = !nmtstp_run_command ("ip link add dev %s type veth peer name %s", - name, peer); - if (success) { - pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_VETH, 100); - nmtstp_assert_wait_for_link (platform, peer, NM_LINK_TYPE_VETH, 10); - } - } else - success = NMTST_NM_ERR_SUCCESS (nm_platform_link_veth_add (platform, name, peer, &pllink)); + if (external_command) { + success = !nmtstp_run_command("ip link add dev %s type veth peer name %s", name, peer); + if (success) { + pllink = nmtstp_assert_wait_for_link(platform, name, NM_LINK_TYPE_VETH, 100); + nmtstp_assert_wait_for_link(platform, peer, NM_LINK_TYPE_VETH, 10); + } + } else + success = NMTST_NM_ERR_SUCCESS(nm_platform_link_veth_add(platform, name, peer, &pllink)); - g_assert (success); - _assert_pllink (platform, success, pllink, name, NM_LINK_TYPE_VETH); - return pllink; + g_assert(success); + _assert_pllink(platform, success, pllink, name, NM_LINK_TYPE_VETH); + return pllink; } const NMPlatformLink * -nmtstp_link_dummy_add (NMPlatform *platform, - gboolean external_command, - const char *name) +nmtstp_link_dummy_add(NMPlatform *platform, gboolean external_command, const char *name) { - const NMPlatformLink *pllink = NULL; - gboolean success; + const NMPlatformLink *pllink = NULL; + gboolean success; - g_assert (nm_utils_ifname_valid_kernel (name, NULL)); + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); - external_command = nmtstp_run_command_check_external (external_command); + external_command = nmtstp_run_command_check_external(external_command); - _init_platform (&platform, external_command); + _init_platform(&platform, external_command); - if (external_command) { - success = !nmtstp_run_command ("ip link add %s type dummy", - name); - if (success) - pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_DUMMY, 100); - } else - success = NMTST_NM_ERR_SUCCESS (nm_platform_link_dummy_add (platform, name, &pllink)); + if (external_command) { + success = !nmtstp_run_command("ip link add %s type dummy", name); + if (success) + pllink = nmtstp_assert_wait_for_link(platform, name, NM_LINK_TYPE_DUMMY, 100); + } else + success = NMTST_NM_ERR_SUCCESS(nm_platform_link_dummy_add(platform, name, &pllink)); - g_assert (success); - _assert_pllink (platform, success, pllink, name, NM_LINK_TYPE_DUMMY); - return pllink; + g_assert(success); + _assert_pllink(platform, success, pllink, name, NM_LINK_TYPE_DUMMY); + return pllink; } const NMPlatformLink * -nmtstp_link_gre_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkGre *lnk) +nmtstp_link_gre_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkGre *lnk) { - const NMPlatformLink *pllink = NULL; - gboolean success; - char b1[INET_ADDRSTRLEN]; - char b2[INET_ADDRSTRLEN]; - NMLinkType link_type; + const NMPlatformLink *pllink = NULL; + gboolean success; + char b1[INET_ADDRSTRLEN]; + char b2[INET_ADDRSTRLEN]; + NMLinkType link_type; - g_assert (nm_utils_ifname_valid_kernel (name, NULL)); + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); - external_command = nmtstp_run_command_check_external (external_command); - link_type = lnk->is_tap ? NM_LINK_TYPE_GRETAP : NM_LINK_TYPE_GRE; + external_command = nmtstp_run_command_check_external(external_command); + link_type = lnk->is_tap ? NM_LINK_TYPE_GRETAP : NM_LINK_TYPE_GRE; - _init_platform (&platform, external_command); + _init_platform(&platform, external_command); - if (external_command) { - gs_free char *dev = NULL; - char *obj, *type; + if (external_command) { + gs_free char *dev = NULL; + char * obj, *type; - if (lnk->parent_ifindex) - dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (platform, lnk->parent_ifindex)); + if (lnk->parent_ifindex) + dev = + g_strdup_printf("dev %s", nm_platform_link_get_name(platform, lnk->parent_ifindex)); - obj = lnk->is_tap ? "link" : "tunnel"; - type = lnk->is_tap ? "type gretap" : "mode gre"; + obj = lnk->is_tap ? "link" : "tunnel"; + type = lnk->is_tap ? "type gretap" : "mode gre"; - success = !nmtstp_run_command ("ip %s add %s %s %s local %s remote %s ttl %u tos %02x %s", - obj, - name, - type, - dev ?: "", - _nm_utils_inet4_ntop (lnk->local, b1), - _nm_utils_inet4_ntop (lnk->remote, b2), - lnk->ttl, - lnk->tos, - lnk->path_mtu_discovery ? "pmtudisc" : "nopmtudisc"); - if (success) - pllink = nmtstp_assert_wait_for_link (platform, name, link_type, 100); - } else - success = NMTST_NM_ERR_SUCCESS (nm_platform_link_gre_add (platform, name, NULL, 0, lnk, &pllink)); + success = !nmtstp_run_command("ip %s add %s %s %s local %s remote %s ttl %u tos %02x %s", + obj, + name, + type, + dev ?: "", + _nm_utils_inet4_ntop(lnk->local, b1), + _nm_utils_inet4_ntop(lnk->remote, b2), + lnk->ttl, + lnk->tos, + lnk->path_mtu_discovery ? "pmtudisc" : "nopmtudisc"); + if (success) + pllink = nmtstp_assert_wait_for_link(platform, name, link_type, 100); + } else + success = + NMTST_NM_ERR_SUCCESS(nm_platform_link_gre_add(platform, name, NULL, 0, lnk, &pllink)); - _assert_pllink (platform, success, pllink, name, link_type); + _assert_pllink(platform, success, pllink, name, link_type); - return pllink; + return pllink; } const NMPlatformLink * -nmtstp_link_ip6tnl_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkIp6Tnl *lnk) -{ - const NMPlatformLink *pllink = NULL; - gboolean success; - char b1[NM_UTILS_INET_ADDRSTRLEN]; - char b2[NM_UTILS_INET_ADDRSTRLEN]; - char encap[20]; - char tclass[20]; - gboolean encap_ignore; - gboolean tclass_inherit; - - g_assert (nm_utils_ifname_valid_kernel (name, NULL)); - g_assert (!lnk->is_gre); - - external_command = nmtstp_run_command_check_external (external_command); - - _init_platform (&platform, external_command); - - if (external_command) { - gs_free char *dev = NULL; - const char *mode; - - if (lnk->parent_ifindex) - dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (platform, lnk->parent_ifindex)); - - switch (lnk->proto) { - case IPPROTO_IPIP: - mode = "ipip6"; - break; - case IPPROTO_IPV6: - mode = "ip6ip6"; - break; - default: - g_assert_not_reached (); - } - - encap_ignore = NM_FLAGS_HAS (lnk->flags, IP6_TNL_F_IGN_ENCAP_LIMIT); - tclass_inherit = NM_FLAGS_HAS (lnk->flags, IP6_TNL_F_USE_ORIG_TCLASS); - - success = !nmtstp_run_command ("ip -6 tunnel add %s mode %s %s local %s remote %s ttl %u tclass %s encaplimit %s flowlabel %x", - name, - mode, - dev, - _nm_utils_inet6_ntop (&lnk->local, b1), - _nm_utils_inet6_ntop (&lnk->remote, b2), - lnk->ttl, - tclass_inherit ? "inherit" : nm_sprintf_buf (tclass, "%02x", lnk->tclass), - encap_ignore ? "none" : nm_sprintf_buf (encap, "%u", lnk->encap_limit), - lnk->flow_label); - if (success) - pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_IP6TNL, 100); - } else - success = NMTST_NM_ERR_SUCCESS (nm_platform_link_ip6tnl_add (platform, name, lnk, &pllink)); - - _assert_pllink (platform, success, pllink, name, NM_LINK_TYPE_IP6TNL); - - return pllink; +nmtstp_link_ip6tnl_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkIp6Tnl *lnk) +{ + const NMPlatformLink *pllink = NULL; + gboolean success; + char b1[NM_UTILS_INET_ADDRSTRLEN]; + char b2[NM_UTILS_INET_ADDRSTRLEN]; + char encap[20]; + char tclass[20]; + gboolean encap_ignore; + gboolean tclass_inherit; + + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); + g_assert(!lnk->is_gre); + + external_command = nmtstp_run_command_check_external(external_command); + + _init_platform(&platform, external_command); + + if (external_command) { + gs_free char *dev = NULL; + const char * mode; + + if (lnk->parent_ifindex) + dev = + g_strdup_printf("dev %s", nm_platform_link_get_name(platform, lnk->parent_ifindex)); + + switch (lnk->proto) { + case IPPROTO_IPIP: + mode = "ipip6"; + break; + case IPPROTO_IPV6: + mode = "ip6ip6"; + break; + default: + g_assert_not_reached(); + } + + encap_ignore = NM_FLAGS_HAS(lnk->flags, IP6_TNL_F_IGN_ENCAP_LIMIT); + tclass_inherit = NM_FLAGS_HAS(lnk->flags, IP6_TNL_F_USE_ORIG_TCLASS); + + success = !nmtstp_run_command( + "ip -6 tunnel add %s mode %s %s local %s remote %s ttl %u tclass %s encaplimit %s " + "flowlabel %x", + name, + mode, + dev, + _nm_utils_inet6_ntop(&lnk->local, b1), + _nm_utils_inet6_ntop(&lnk->remote, b2), + lnk->ttl, + tclass_inherit ? "inherit" : nm_sprintf_buf(tclass, "%02x", lnk->tclass), + encap_ignore ? "none" : nm_sprintf_buf(encap, "%u", lnk->encap_limit), + lnk->flow_label); + if (success) + pllink = nmtstp_assert_wait_for_link(platform, name, NM_LINK_TYPE_IP6TNL, 100); + } else + success = NMTST_NM_ERR_SUCCESS(nm_platform_link_ip6tnl_add(platform, name, lnk, &pllink)); + + _assert_pllink(platform, success, pllink, name, NM_LINK_TYPE_IP6TNL); + + return pllink; } const NMPlatformLink * -nmtstp_link_ip6gre_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkIp6Tnl *lnk) -{ - const NMPlatformLink *pllink = NULL; - gboolean success; - char b1[NM_UTILS_INET_ADDRSTRLEN]; - char b2[NM_UTILS_INET_ADDRSTRLEN]; - char tclass[20]; - gboolean tclass_inherit; - - g_assert (nm_utils_ifname_valid_kernel (name, NULL)); - g_assert (lnk->is_gre); - - external_command = nmtstp_run_command_check_external (external_command); - - _init_platform (&platform, external_command); - - if (external_command) { - gs_free char *dev = NULL; - - if (lnk->parent_ifindex) - dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (platform, lnk->parent_ifindex)); - - tclass_inherit = NM_FLAGS_HAS (lnk->flags, IP6_TNL_F_USE_ORIG_TCLASS); - - success = !nmtstp_run_command ("ip link add %s type %s %s local %s remote %s ttl %u tclass %s flowlabel %x", - name, - lnk->is_tap ? "ip6gretap" : "ip6gre", - dev, - _nm_utils_inet6_ntop (&lnk->local, b1), - _nm_utils_inet6_ntop (&lnk->remote, b2), - lnk->ttl, - tclass_inherit ? "inherit" : nm_sprintf_buf (tclass, "%02x", lnk->tclass), - lnk->flow_label); - if (success) { - pllink = nmtstp_assert_wait_for_link (platform, - name, - lnk->is_tap ? NM_LINK_TYPE_IP6GRETAP : NM_LINK_TYPE_IP6GRE, - 100); - } - } else - success = NMTST_NM_ERR_SUCCESS (nm_platform_link_ip6gre_add (platform, name, NULL, 0, lnk, &pllink)); - - _assert_pllink (platform, success, pllink, name, lnk->is_tap ? NM_LINK_TYPE_IP6GRETAP : NM_LINK_TYPE_IP6GRE); - - return pllink; +nmtstp_link_ip6gre_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkIp6Tnl *lnk) +{ + const NMPlatformLink *pllink = NULL; + gboolean success; + char b1[NM_UTILS_INET_ADDRSTRLEN]; + char b2[NM_UTILS_INET_ADDRSTRLEN]; + char tclass[20]; + gboolean tclass_inherit; + + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); + g_assert(lnk->is_gre); + + external_command = nmtstp_run_command_check_external(external_command); + + _init_platform(&platform, external_command); + + if (external_command) { + gs_free char *dev = NULL; + + if (lnk->parent_ifindex) + dev = + g_strdup_printf("dev %s", nm_platform_link_get_name(platform, lnk->parent_ifindex)); + + tclass_inherit = NM_FLAGS_HAS(lnk->flags, IP6_TNL_F_USE_ORIG_TCLASS); + + success = !nmtstp_run_command( + "ip link add %s type %s %s local %s remote %s ttl %u tclass %s flowlabel %x", + name, + lnk->is_tap ? "ip6gretap" : "ip6gre", + dev, + _nm_utils_inet6_ntop(&lnk->local, b1), + _nm_utils_inet6_ntop(&lnk->remote, b2), + lnk->ttl, + tclass_inherit ? "inherit" : nm_sprintf_buf(tclass, "%02x", lnk->tclass), + lnk->flow_label); + if (success) { + pllink = nmtstp_assert_wait_for_link(platform, + name, + lnk->is_tap ? NM_LINK_TYPE_IP6GRETAP + : NM_LINK_TYPE_IP6GRE, + 100); + } + } else + success = NMTST_NM_ERR_SUCCESS( + nm_platform_link_ip6gre_add(platform, name, NULL, 0, lnk, &pllink)); + + _assert_pllink(platform, + success, + pllink, + name, + lnk->is_tap ? NM_LINK_TYPE_IP6GRETAP : NM_LINK_TYPE_IP6GRE); + + return pllink; } const NMPlatformLink * -nmtstp_link_ipip_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkIpIp *lnk) +nmtstp_link_ipip_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkIpIp *lnk) { - const NMPlatformLink *pllink = NULL; - gboolean success; - char b1[INET_ADDRSTRLEN]; - char b2[INET_ADDRSTRLEN]; + const NMPlatformLink *pllink = NULL; + gboolean success; + char b1[INET_ADDRSTRLEN]; + char b2[INET_ADDRSTRLEN]; - g_assert (nm_utils_ifname_valid_kernel (name, NULL)); + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); - external_command = nmtstp_run_command_check_external (external_command); + external_command = nmtstp_run_command_check_external(external_command); - _init_platform (&platform, external_command); + _init_platform(&platform, external_command); - if (external_command) { - gs_free char *dev = NULL; + if (external_command) { + gs_free char *dev = NULL; - if (lnk->parent_ifindex) - dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (platform, lnk->parent_ifindex)); + if (lnk->parent_ifindex) + dev = + g_strdup_printf("dev %s", nm_platform_link_get_name(platform, lnk->parent_ifindex)); - success = !nmtstp_run_command ("ip tunnel add %s mode ipip %s local %s remote %s ttl %u tos %02x %s", - name, - dev, - _nm_utils_inet4_ntop (lnk->local, b1), - _nm_utils_inet4_ntop (lnk->remote, b2), - lnk->ttl, - lnk->tos, - lnk->path_mtu_discovery ? "pmtudisc" : "nopmtudisc"); - if (success) - pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_IPIP, 100); - } else - success = NMTST_NM_ERR_SUCCESS (nm_platform_link_ipip_add (platform, name, lnk, &pllink)); + success = !nmtstp_run_command( + "ip tunnel add %s mode ipip %s local %s remote %s ttl %u tos %02x %s", + name, + dev, + _nm_utils_inet4_ntop(lnk->local, b1), + _nm_utils_inet4_ntop(lnk->remote, b2), + lnk->ttl, + lnk->tos, + lnk->path_mtu_discovery ? "pmtudisc" : "nopmtudisc"); + if (success) + pllink = nmtstp_assert_wait_for_link(platform, name, NM_LINK_TYPE_IPIP, 100); + } else + success = NMTST_NM_ERR_SUCCESS(nm_platform_link_ipip_add(platform, name, lnk, &pllink)); - _assert_pllink (platform, success, pllink, name, NM_LINK_TYPE_IPIP); + _assert_pllink(platform, success, pllink, name, NM_LINK_TYPE_IPIP); - return pllink; + return pllink; } const NMPlatformLink * -nmtstp_link_macvlan_add (NMPlatform *platform, - gboolean external_command, - const char *name, - int parent, - const NMPlatformLnkMacvlan *lnk) +nmtstp_link_macvlan_add(NMPlatform * platform, + gboolean external_command, + const char * name, + int parent, + const NMPlatformLnkMacvlan *lnk) { - const NMPlatformLink *pllink = NULL; - gboolean success; - NMLinkType link_type; + const NMPlatformLink *pllink = NULL; + gboolean success; + NMLinkType link_type; - g_assert (nm_utils_ifname_valid_kernel (name, NULL)); + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); - external_command = nmtstp_run_command_check_external (external_command); + external_command = nmtstp_run_command_check_external(external_command); - _init_platform (&platform, external_command); + _init_platform(&platform, external_command); - link_type = lnk->tap ? NM_LINK_TYPE_MACVTAP : NM_LINK_TYPE_MACVLAN; + link_type = lnk->tap ? NM_LINK_TYPE_MACVTAP : NM_LINK_TYPE_MACVLAN; - if (external_command) { - const char *dev; - char *modes[] = { - [MACVLAN_MODE_BRIDGE] = "bridge", - [MACVLAN_MODE_VEPA] = "vepa", - [MACVLAN_MODE_PRIVATE] = "private", - [MACVLAN_MODE_PASSTHRU] = "passthru", - }; + if (external_command) { + const char *dev; + char * modes[] = { + [MACVLAN_MODE_BRIDGE] = "bridge", + [MACVLAN_MODE_VEPA] = "vepa", + [MACVLAN_MODE_PRIVATE] = "private", + [MACVLAN_MODE_PASSTHRU] = "passthru", + }; - dev = nm_platform_link_get_name (platform, parent); - g_assert (dev); - g_assert_cmpint (lnk->mode, <, G_N_ELEMENTS (modes)); + dev = nm_platform_link_get_name(platform, parent); + g_assert(dev); + g_assert_cmpint(lnk->mode, <, G_N_ELEMENTS(modes)); - success = !nmtstp_run_command ("ip link add name %s link %s type %s mode %s %s", - name, - dev, - lnk->tap ? "macvtap" : "macvlan", - modes[lnk->mode], - lnk->no_promisc ? "nopromisc" : ""); - if (success) - pllink = nmtstp_assert_wait_for_link (platform, name, link_type, 100); - } else - success = NMTST_NM_ERR_SUCCESS (nm_platform_link_macvlan_add (platform, name, parent, lnk, &pllink)); + success = !nmtstp_run_command("ip link add name %s link %s type %s mode %s %s", + name, + dev, + lnk->tap ? "macvtap" : "macvlan", + modes[lnk->mode], + lnk->no_promisc ? "nopromisc" : ""); + if (success) + pllink = nmtstp_assert_wait_for_link(platform, name, link_type, 100); + } else + success = NMTST_NM_ERR_SUCCESS( + nm_platform_link_macvlan_add(platform, name, parent, lnk, &pllink)); - _assert_pllink (platform, success, pllink, name, link_type); + _assert_pllink(platform, success, pllink, name, link_type); - return pllink; + return pllink; } const NMPlatformLink * -nmtstp_link_sit_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkSit *lnk) +nmtstp_link_sit_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkSit *lnk) { - const NMPlatformLink *pllink = NULL; - gboolean success; - char b1[INET_ADDRSTRLEN]; - char b2[INET_ADDRSTRLEN]; + const NMPlatformLink *pllink = NULL; + gboolean success; + char b1[INET_ADDRSTRLEN]; + char b2[INET_ADDRSTRLEN]; - g_assert (nm_utils_ifname_valid_kernel (name, NULL)); + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); - external_command = nmtstp_run_command_check_external (external_command); + external_command = nmtstp_run_command_check_external(external_command); - _init_platform (&platform, external_command); + _init_platform(&platform, external_command); - if (external_command) { - const char *dev = ""; + if (external_command) { + const char *dev = ""; - if (lnk->parent_ifindex) { - const char *parent_name; + if (lnk->parent_ifindex) { + const char *parent_name; - parent_name = nm_platform_link_get_name (platform, lnk->parent_ifindex); - g_assert (parent_name); - dev = nm_sprintf_bufa (100, " dev %s", parent_name); - } + parent_name = nm_platform_link_get_name(platform, lnk->parent_ifindex); + g_assert(parent_name); + dev = nm_sprintf_bufa(100, " dev %s", parent_name); + } - success = !nmtstp_run_command ("ip tunnel add %s mode sit%s local %s remote %s ttl %u tos %02x %s", - name, - dev, - _nm_utils_inet4_ntop (lnk->local, b1), - _nm_utils_inet4_ntop (lnk->remote, b2), - lnk->ttl, - lnk->tos, - lnk->path_mtu_discovery ? "pmtudisc" : "nopmtudisc"); - if (success) - pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_SIT, 100); - } else - success = NMTST_NM_ERR_SUCCESS (nm_platform_link_sit_add (platform, name, lnk, &pllink)); + success = + !nmtstp_run_command("ip tunnel add %s mode sit%s local %s remote %s ttl %u tos %02x %s", + name, + dev, + _nm_utils_inet4_ntop(lnk->local, b1), + _nm_utils_inet4_ntop(lnk->remote, b2), + lnk->ttl, + lnk->tos, + lnk->path_mtu_discovery ? "pmtudisc" : "nopmtudisc"); + if (success) + pllink = nmtstp_assert_wait_for_link(platform, name, NM_LINK_TYPE_SIT, 100); + } else + success = NMTST_NM_ERR_SUCCESS(nm_platform_link_sit_add(platform, name, lnk, &pllink)); - _assert_pllink (platform, success, pllink, name, NM_LINK_TYPE_SIT); + _assert_pllink(platform, success, pllink, name, NM_LINK_TYPE_SIT); - return pllink; + return pllink; } const NMPlatformLink * -nmtstp_link_tun_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkTun *lnk, - int *out_fd) -{ - const NMPlatformLink *pllink = NULL; - int err; - int r; - - g_assert (nm_utils_ifname_valid_kernel (name, NULL)); - g_assert (lnk); - g_assert (NM_IN_SET (lnk->type, IFF_TUN, IFF_TAP)); - g_assert (!out_fd || *out_fd == -1); - - if (!lnk->persist) { - /* ip tuntap does not support non-persistent devices. - * - * Add this device only via NMPlatform. */ - if (external_command == -1) - external_command = FALSE; - } - - external_command = nmtstp_run_command_check_external (external_command); - - _init_platform (&platform, external_command); - - if (external_command) { - g_assert (lnk->persist); - - err = nmtstp_run_command ("ip tuntap add" - " mode %s" - "%s" /* user */ - "%s" /* group */ - "%s" /* pi */ - "%s" /* vnet_hdr */ - "%s" /* multi_queue */ - " name %s", - lnk->type == IFF_TUN ? "tun" : "tap", - lnk->owner_valid ? nm_sprintf_bufa (100, " user %u", (guint) lnk->owner) : "", - lnk->group_valid ? nm_sprintf_bufa (100, " group %u", (guint) lnk->group) : "", - lnk->pi ? " pi" : "", - lnk->vnet_hdr ? " vnet_hdr" : "", - lnk->multi_queue ? " multi_queue" : "", - name); - /* Older versions of iproute2 don't support adding devices. - * On failure, fallback to using platform code. */ - if (err == 0) - pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_TUN, 100); - else - g_error ("failure to add tun/tap device via ip-route"); - } else { - g_assert (lnk->persist || out_fd); - r = nm_platform_link_tun_add (platform, name, lnk, &pllink, out_fd); - g_assert_cmpint (r, ==, 0); - } - - g_assert (pllink); - g_assert_cmpint (pllink->type, ==, NM_LINK_TYPE_TUN); - g_assert_cmpstr (pllink->name, ==, name); - return pllink; +nmtstp_link_tun_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkTun *lnk, + int * out_fd) +{ + const NMPlatformLink *pllink = NULL; + int err; + int r; + + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); + g_assert(lnk); + g_assert(NM_IN_SET(lnk->type, IFF_TUN, IFF_TAP)); + g_assert(!out_fd || *out_fd == -1); + + if (!lnk->persist) { + /* ip tuntap does not support non-persistent devices. + * + * Add this device only via NMPlatform. */ + if (external_command == -1) + external_command = FALSE; + } + + external_command = nmtstp_run_command_check_external(external_command); + + _init_platform(&platform, external_command); + + if (external_command) { + g_assert(lnk->persist); + + err = nmtstp_run_command( + "ip tuntap add" + " mode %s" + "%s" /* user */ + "%s" /* group */ + "%s" /* pi */ + "%s" /* vnet_hdr */ + "%s" /* multi_queue */ + " name %s", + lnk->type == IFF_TUN ? "tun" : "tap", + lnk->owner_valid ? nm_sprintf_bufa(100, " user %u", (guint) lnk->owner) : "", + lnk->group_valid ? nm_sprintf_bufa(100, " group %u", (guint) lnk->group) : "", + lnk->pi ? " pi" : "", + lnk->vnet_hdr ? " vnet_hdr" : "", + lnk->multi_queue ? " multi_queue" : "", + name); + /* Older versions of iproute2 don't support adding devices. + * On failure, fallback to using platform code. */ + if (err == 0) + pllink = nmtstp_assert_wait_for_link(platform, name, NM_LINK_TYPE_TUN, 100); + else + g_error("failure to add tun/tap device via ip-route"); + } else { + g_assert(lnk->persist || out_fd); + r = nm_platform_link_tun_add(platform, name, lnk, &pllink, out_fd); + g_assert_cmpint(r, ==, 0); + } + + g_assert(pllink); + g_assert_cmpint(pllink->type, ==, NM_LINK_TYPE_TUN); + g_assert_cmpstr(pllink->name, ==, name); + return pllink; } const NMPlatformLink * -nmtstp_link_vrf_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkVrf *lnk, - gboolean *out_not_supported) +nmtstp_link_vrf_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkVrf *lnk, + gboolean * out_not_supported) { - const NMPlatformLink *pllink = NULL; - int r = 0; + const NMPlatformLink *pllink = NULL; + int r = 0; - g_assert (nm_utils_ifname_valid_kernel (name, NULL)); + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); - NM_SET_OUT (out_not_supported, FALSE); - external_command = nmtstp_run_command_check_external (external_command); + NM_SET_OUT(out_not_supported, FALSE); + external_command = nmtstp_run_command_check_external(external_command); - _init_platform (&platform, external_command); + _init_platform(&platform, external_command); - if (external_command) { - r = nmtstp_run_command ("ip link add %s type vrf table %u", - name, - lnk->table); + if (external_command) { + r = nmtstp_run_command("ip link add %s type vrf table %u", name, lnk->table); - if (r == 0) - pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_VRF, 100); - else - _LOGI ("Adding vrf device via iproute2 failed. Assume iproute2 is not up to the task."); - } + if (r == 0) + pllink = nmtstp_assert_wait_for_link(platform, name, NM_LINK_TYPE_VRF, 100); + else + _LOGI("Adding vrf device via iproute2 failed. Assume iproute2 is not up to the task."); + } - if (!pllink) { - r = nm_platform_link_vrf_add (platform, name, lnk, &pllink); - if (r == -EOPNOTSUPP) - NM_SET_OUT (out_not_supported, TRUE); - } + if (!pllink) { + r = nm_platform_link_vrf_add(platform, name, lnk, &pllink); + if (r == -EOPNOTSUPP) + NM_SET_OUT(out_not_supported, TRUE); + } - _assert_pllink (platform, r == 0, pllink, name, NM_LINK_TYPE_VRF); + _assert_pllink(platform, r == 0, pllink, name, NM_LINK_TYPE_VRF); - return pllink; + return pllink; } const NMPlatformLink * -nmtstp_link_vxlan_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkVxlan *lnk) -{ - const NMPlatformLink *pllink = NULL; - int err; - int r; - - g_assert (nm_utils_ifname_valid_kernel (name, NULL)); - - external_command = nmtstp_run_command_check_external (external_command); - - _init_platform (&platform, external_command); - - if (external_command) { - gs_free char *dev = NULL; - char local[NM_UTILS_INET_ADDRSTRLEN]; - char group[NM_UTILS_INET_ADDRSTRLEN]; - - if (lnk->parent_ifindex) - dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (platform, lnk->parent_ifindex)); - - if (lnk->local) - _nm_utils_inet4_ntop (lnk->local, local); - else if (memcmp (&lnk->local6, &in6addr_any, sizeof (in6addr_any))) - _nm_utils_inet6_ntop (&lnk->local6, local); - else - local[0] = '\0'; - - if (lnk->group) - _nm_utils_inet4_ntop (lnk->group, group); - else if (memcmp (&lnk->group6, &in6addr_any, sizeof (in6addr_any))) - _nm_utils_inet6_ntop (&lnk->group6, group); - else - group[0] = '\0'; - - err = nmtstp_run_command ("ip link add %s type vxlan id %u %s local %s group %s ttl %u tos %02x dstport %u srcport %u %u ageing %u", - name, - lnk->id, - dev ?: "", - local, - group, - lnk->ttl, - lnk->tos, - lnk->dst_port, - lnk->src_port_min, lnk->src_port_max, - lnk->ageing); - /* Older versions of iproute2 don't support adding vxlan devices. - * On failure, fallback to using platform code. */ - if (err == 0) - pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_VXLAN, 100); - else - _LOGI ("Adding vxlan device via iproute2 failed. Assume iproute2 is not up to the task."); - } - if (!pllink) { - r = nm_platform_link_vxlan_add (platform, name, lnk, &pllink); - g_assert (NMTST_NM_ERR_SUCCESS (r)); - g_assert (pllink); - } - - g_assert_cmpint (pllink->type, ==, NM_LINK_TYPE_VXLAN); - g_assert_cmpstr (pllink->name, ==, name); - return pllink; +nmtstp_link_vxlan_add(NMPlatform * platform, + gboolean external_command, + const char * name, + const NMPlatformLnkVxlan *lnk) +{ + const NMPlatformLink *pllink = NULL; + int err; + int r; + + g_assert(nm_utils_ifname_valid_kernel(name, NULL)); + + external_command = nmtstp_run_command_check_external(external_command); + + _init_platform(&platform, external_command); + + if (external_command) { + gs_free char *dev = NULL; + char local[NM_UTILS_INET_ADDRSTRLEN]; + char group[NM_UTILS_INET_ADDRSTRLEN]; + + if (lnk->parent_ifindex) + dev = + g_strdup_printf("dev %s", nm_platform_link_get_name(platform, lnk->parent_ifindex)); + + if (lnk->local) + _nm_utils_inet4_ntop(lnk->local, local); + else if (memcmp(&lnk->local6, &in6addr_any, sizeof(in6addr_any))) + _nm_utils_inet6_ntop(&lnk->local6, local); + else + local[0] = '\0'; + + if (lnk->group) + _nm_utils_inet4_ntop(lnk->group, group); + else if (memcmp(&lnk->group6, &in6addr_any, sizeof(in6addr_any))) + _nm_utils_inet6_ntop(&lnk->group6, group); + else + group[0] = '\0'; + + err = nmtstp_run_command("ip link add %s type vxlan id %u %s local %s group %s ttl %u tos " + "%02x dstport %u srcport %u %u ageing %u", + name, + lnk->id, + dev ?: "", + local, + group, + lnk->ttl, + lnk->tos, + lnk->dst_port, + lnk->src_port_min, + lnk->src_port_max, + lnk->ageing); + /* Older versions of iproute2 don't support adding vxlan devices. + * On failure, fallback to using platform code. */ + if (err == 0) + pllink = nmtstp_assert_wait_for_link(platform, name, NM_LINK_TYPE_VXLAN, 100); + else + _LOGI( + "Adding vxlan device via iproute2 failed. Assume iproute2 is not up to the task."); + } + if (!pllink) { + r = nm_platform_link_vxlan_add(platform, name, lnk, &pllink); + g_assert(NMTST_NM_ERR_SUCCESS(r)); + g_assert(pllink); + } + + g_assert_cmpint(pllink->type, ==, NM_LINK_TYPE_VXLAN); + g_assert_cmpstr(pllink->name, ==, name); + return pllink; } /*****************************************************************************/ const NMPlatformLink * -nmtstp_link_get_typed (NMPlatform *platform, - int ifindex, - const char *name, - NMLinkType link_type) +nmtstp_link_get_typed(NMPlatform *platform, int ifindex, const char *name, NMLinkType link_type) { - const NMPlatformLink *pllink = NULL; + const NMPlatformLink *pllink = NULL; - _init_platform (&platform, FALSE); + _init_platform(&platform, FALSE); - if (ifindex > 0) { - pllink = nm_platform_link_get (platform, ifindex); + if (ifindex > 0) { + pllink = nm_platform_link_get(platform, ifindex); - if (pllink) { - g_assert_cmpint (pllink->ifindex, ==, ifindex); - if (name) - g_assert_cmpstr (name, ==, pllink->name); - } else { - if (name) - g_assert (!nm_platform_link_get_by_ifname (platform, name)); - } - } else { - g_assert (name); + if (pllink) { + g_assert_cmpint(pllink->ifindex, ==, ifindex); + if (name) + g_assert_cmpstr(name, ==, pllink->name); + } else { + if (name) + g_assert(!nm_platform_link_get_by_ifname(platform, name)); + } + } else { + g_assert(name); - pllink = nm_platform_link_get_by_ifname (platform, name); + pllink = nm_platform_link_get_by_ifname(platform, name); - if (pllink) - g_assert_cmpstr (name, ==, pllink->name); - } + if (pllink) + g_assert_cmpstr(name, ==, pllink->name); + } - g_assert (!name || nm_utils_ifname_valid_kernel (name, NULL)); + g_assert(!name || nm_utils_ifname_valid_kernel(name, NULL)); - if (pllink && link_type != NM_LINK_TYPE_NONE) - g_assert_cmpint (pllink->type, ==, link_type); + if (pllink && link_type != NM_LINK_TYPE_NONE) + g_assert_cmpint(pllink->type, ==, link_type); - return pllink; + return pllink; } const NMPlatformLink * -nmtstp_link_get (NMPlatform *platform, - int ifindex, - const char *name) +nmtstp_link_get(NMPlatform *platform, int ifindex, const char *name) { - return nmtstp_link_get_typed (platform, ifindex, name, NM_LINK_TYPE_NONE); + return nmtstp_link_get_typed(platform, ifindex, name, NM_LINK_TYPE_NONE); } /*****************************************************************************/ void -nmtstp_link_delete (NMPlatform *platform, - gboolean external_command, - int ifindex, - const char *name, - gboolean require_exist) +nmtstp_link_delete(NMPlatform *platform, + gboolean external_command, + int ifindex, + const char *name, + gboolean require_exist) { - gint64 end_time; - const NMPlatformLink *pllink; - gboolean success; - gs_free char *name_copy = NULL; + gint64 end_time; + const NMPlatformLink *pllink; + gboolean success; + gs_free char * name_copy = NULL; - external_command = nmtstp_run_command_check_external (external_command); + external_command = nmtstp_run_command_check_external(external_command); - _init_platform (&platform, external_command); + _init_platform(&platform, external_command); - pllink = nmtstp_link_get (platform, ifindex, name); + pllink = nmtstp_link_get(platform, ifindex, name); - if (!pllink) { - g_assert (!require_exist); - return; - } + if (!pllink) { + g_assert(!require_exist); + return; + } - name = name_copy = g_strdup (pllink->name); - ifindex = pllink->ifindex; + name = name_copy = g_strdup(pllink->name); + ifindex = pllink->ifindex; - if (external_command) { - nmtstp_run_command_check ("ip link delete %s", name); - } else { - success = nm_platform_link_delete (platform, ifindex); - g_assert (success); - } + if (external_command) { + nmtstp_run_command_check("ip link delete %s", name); + } else { + success = nm_platform_link_delete(platform, ifindex); + g_assert(success); + } - /* Let's wait until we get the result */ - end_time = nm_utils_get_monotonic_timestamp_msec () + 250; - do { - if (external_command) - nm_platform_process_events (platform); + /* Let's wait until we get the result */ + end_time = nm_utils_get_monotonic_timestamp_msec() + 250; + do { + if (external_command) + nm_platform_process_events(platform); - if (!nm_platform_link_get (platform, ifindex)) { - g_assert (!nm_platform_link_get_by_ifname (platform, name)); - break; - } + if (!nm_platform_link_get(platform, ifindex)) { + g_assert(!nm_platform_link_get_by_ifname(platform, name)); + break; + } - /* for internal command, we expect not to reach this line.*/ - g_assert (external_command); + /* for internal command, we expect not to reach this line.*/ + g_assert(external_command); - nmtstp_assert_wait_for_signal_until (platform, end_time); - } while (TRUE); + nmtstp_assert_wait_for_signal_until(platform, end_time); + } while (TRUE); } /*****************************************************************************/ void -nmtstp_link_set_updown (NMPlatform *platform, - gboolean external_command, - int ifindex, - gboolean up) +nmtstp_link_set_updown(NMPlatform *platform, gboolean external_command, int ifindex, gboolean up) { - const NMPlatformLink *plink; - gint64 end_time; + const NMPlatformLink *plink; + gint64 end_time; - external_command = nmtstp_run_command_check_external (external_command); + external_command = nmtstp_run_command_check_external(external_command); - _init_platform (&platform, external_command); + _init_platform(&platform, external_command); - if (external_command) { - const char *ifname; + if (external_command) { + const char *ifname; - ifname = nm_platform_link_get_name (platform, ifindex); - g_assert (ifname); + ifname = nm_platform_link_get_name(platform, ifindex); + g_assert(ifname); - nmtstp_run_command_check ("ip link set %s %s", - ifname, - up ? "up" : "down"); - } else { - if (up) - g_assert (nm_platform_link_set_up (platform, ifindex, NULL)); - else - g_assert (nm_platform_link_set_down (platform, ifindex)); - } + nmtstp_run_command_check("ip link set %s %s", ifname, up ? "up" : "down"); + } else { + if (up) + g_assert(nm_platform_link_set_up(platform, ifindex, NULL)); + else + g_assert(nm_platform_link_set_down(platform, ifindex)); + } - /* Let's wait until we get the result */ - end_time = nm_utils_get_monotonic_timestamp_msec () + 250; - do { - if (external_command) - nm_platform_process_events (platform); + /* Let's wait until we get the result */ + end_time = nm_utils_get_monotonic_timestamp_msec() + 250; + do { + if (external_command) + nm_platform_process_events(platform); - /* let's wait until we see the address as we added it. */ - plink = nm_platform_link_get (platform, ifindex); - g_assert (plink); + /* let's wait until we see the address as we added it. */ + plink = nm_platform_link_get(platform, ifindex); + g_assert(plink); - if (NM_FLAGS_HAS (plink->n_ifi_flags, IFF_UP) == !!up) - break; + if (NM_FLAGS_HAS(plink->n_ifi_flags, IFF_UP) == !!up) + break; + + /* for internal command, we expect not to reach this line.*/ + g_assert(external_command); + + nmtstp_assert_wait_for_signal_until(platform, end_time); + } while (TRUE); +} + +/*****************************************************************************/ + +gboolean +nmtstp_kernel_support_get(NMPlatformKernelSupportType type) +{ + const NMPlatformLink *pllink; + NMTernary v; - /* for internal command, we expect not to reach this line.*/ - g_assert (external_command); + v = nm_platform_kernel_support_get_full(type, FALSE); + if (v != NM_TERNARY_DEFAULT) + return v != NM_TERNARY_FALSE; - nmtstp_assert_wait_for_signal_until (platform, end_time); - } while (TRUE); + switch (type) { + case NM_PLATFORM_KERNEL_SUPPORT_TYPE_IFLA_BR_VLAN_STATS_ENABLED: + pllink = nmtstp_link_bridge_add(NULL, -1, "br-test-11", &nm_platform_lnk_bridge_default); + nmtstp_link_delete(NULL, -1, pllink->ifindex, NULL, TRUE); + v = nm_platform_kernel_support_get_full(type, FALSE); + g_assert(v != NM_TERNARY_DEFAULT); + return v; + default: + g_assert_not_reached(); + } } /*****************************************************************************/ struct _NMTstpNamespaceHandle { - pid_t pid; - int pipe_fd; + pid_t pid; + int pipe_fd; }; NMTstpNamespaceHandle * -nmtstp_namespace_create (int unshare_flags, GError **error) -{ - NMTstpNamespaceHandle *ns_handle; - int e; - int errsv; - pid_t pid, pid2; - int pipefd_c2p[2]; - int pipefd_p2c[2]; - ssize_t r; - - e = pipe2 (pipefd_c2p, O_CLOEXEC); - if (e != 0) { - errsv = errno; - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "pipe() failed with %d (%s)", errsv, nm_strerror_native (errsv)); - return FALSE; - } - - e = pipe2 (pipefd_p2c, O_CLOEXEC); - if (e != 0) { - errsv = errno; - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "pipe() failed with %d (%s)", errsv, nm_strerror_native (errsv)); - nm_close (pipefd_c2p[0]); - nm_close (pipefd_c2p[1]); - return FALSE; - } - - pid = fork (); - if (pid < 0) { - errsv = errno; - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "fork() failed with %d (%s)", errsv, nm_strerror_native (errsv)); - nm_close (pipefd_c2p[0]); - nm_close (pipefd_c2p[1]); - nm_close (pipefd_p2c[0]); - nm_close (pipefd_p2c[1]); - return FALSE; - } - - if (pid == 0) { - char read_buf[1]; - - nm_close (pipefd_c2p[0]); /* close read-end */ - nm_close (pipefd_p2c[1]); /* close write-end */ - - if (unshare (unshare_flags) != 0) { - errsv = errno; - if (errsv == 0) - errsv = -1; - } else - errsv = 0; - - /* sync with parent process and send result. */ - do { - r = write (pipefd_c2p[1], &errsv, sizeof (errsv)); - } while (r < 0 && errno == EINTR); - if (r != sizeof (errsv)) { - errsv = errno; - if (errsv == 0) - errsv = -2; - } - nm_close (pipefd_c2p[1]); - - /* wait until parent process terminates (or kills us). */ - if (errsv == 0) { - do { - r = read (pipefd_p2c[0], read_buf, sizeof (read_buf)); - } while (r < 0 && errno == EINTR); - } - nm_close (pipefd_p2c[0]); - _exit (0); - } - - nm_close (pipefd_c2p[1]); /* close write-end */ - nm_close (pipefd_p2c[0]); /* close read-end */ - - /* sync with child process. */ - do { - r = read (pipefd_c2p[0], &errsv, sizeof (errsv)); - } while (r < 0 && errno == EINTR); - - nm_close (pipefd_c2p[0]); - - if ( r != sizeof (errsv) - || errsv != 0) { - int status; - - if (r != sizeof (errsv)) { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "child process failed for unknown reason"); - } else { - g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, - "child process signaled failure %d (%s)", errsv, nm_strerror_native (errsv)); - } - nm_close (pipefd_p2c[1]); - kill (pid, SIGKILL); - do { - pid2 = waitpid (pid, &status, 0); - } while (pid2 == -1 && errno == EINTR); - return FALSE; - } - - ns_handle = g_new0 (NMTstpNamespaceHandle, 1); - ns_handle->pid = pid; - ns_handle->pipe_fd = pipefd_p2c[1]; - return ns_handle; +nmtstp_namespace_create(int unshare_flags, GError **error) +{ + NMTstpNamespaceHandle *ns_handle; + int e; + int errsv; + pid_t pid, pid2; + int pipefd_c2p[2]; + int pipefd_p2c[2]; + ssize_t r; + + e = pipe2(pipefd_c2p, O_CLOEXEC); + if (e != 0) { + errsv = errno; + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "pipe() failed with %d (%s)", + errsv, + nm_strerror_native(errsv)); + return FALSE; + } + + e = pipe2(pipefd_p2c, O_CLOEXEC); + if (e != 0) { + errsv = errno; + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "pipe() failed with %d (%s)", + errsv, + nm_strerror_native(errsv)); + nm_close(pipefd_c2p[0]); + nm_close(pipefd_c2p[1]); + return FALSE; + } + + pid = fork(); + if (pid < 0) { + errsv = errno; + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "fork() failed with %d (%s)", + errsv, + nm_strerror_native(errsv)); + nm_close(pipefd_c2p[0]); + nm_close(pipefd_c2p[1]); + nm_close(pipefd_p2c[0]); + nm_close(pipefd_p2c[1]); + return FALSE; + } + + if (pid == 0) { + char read_buf[1]; + + nm_close(pipefd_c2p[0]); /* close read-end */ + nm_close(pipefd_p2c[1]); /* close write-end */ + + if (unshare(unshare_flags) != 0) { + errsv = errno; + if (errsv == 0) + errsv = -1; + } else + errsv = 0; + + /* sync with parent process and send result. */ + do { + r = write(pipefd_c2p[1], &errsv, sizeof(errsv)); + } while (r < 0 && errno == EINTR); + if (r != sizeof(errsv)) { + errsv = errno; + if (errsv == 0) + errsv = -2; + } + nm_close(pipefd_c2p[1]); + + /* wait until parent process terminates (or kills us). */ + if (errsv == 0) { + do { + r = read(pipefd_p2c[0], read_buf, sizeof(read_buf)); + } while (r < 0 && errno == EINTR); + } + nm_close(pipefd_p2c[0]); + _exit(0); + } + + nm_close(pipefd_c2p[1]); /* close write-end */ + nm_close(pipefd_p2c[0]); /* close read-end */ + + /* sync with child process. */ + do { + r = read(pipefd_c2p[0], &errsv, sizeof(errsv)); + } while (r < 0 && errno == EINTR); + + nm_close(pipefd_c2p[0]); + + if (r != sizeof(errsv) || errsv != 0) { + int status; + + if (r != sizeof(errsv)) { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "child process failed for unknown reason"); + } else { + g_set_error(error, + NM_UTILS_ERROR, + NM_UTILS_ERROR_UNKNOWN, + "child process signaled failure %d (%s)", + errsv, + nm_strerror_native(errsv)); + } + nm_close(pipefd_p2c[1]); + kill(pid, SIGKILL); + do { + pid2 = waitpid(pid, &status, 0); + } while (pid2 == -1 && errno == EINTR); + return FALSE; + } + + ns_handle = g_new0(NMTstpNamespaceHandle, 1); + ns_handle->pid = pid; + ns_handle->pipe_fd = pipefd_p2c[1]; + return ns_handle; } pid_t -nmtstp_namespace_handle_get_pid (NMTstpNamespaceHandle *ns_handle) +nmtstp_namespace_handle_get_pid(NMTstpNamespaceHandle *ns_handle) { - g_return_val_if_fail (ns_handle, 0); - g_return_val_if_fail (ns_handle->pid > 0, 0); + g_return_val_if_fail(ns_handle, 0); + g_return_val_if_fail(ns_handle->pid > 0, 0); - return ns_handle->pid; + return ns_handle->pid; } void -nmtstp_namespace_handle_release (NMTstpNamespaceHandle *ns_handle) +nmtstp_namespace_handle_release(NMTstpNamespaceHandle *ns_handle) { - pid_t pid; - int status; + pid_t pid; + int status; - if (!ns_handle) - return; + if (!ns_handle) + return; - g_return_if_fail (ns_handle->pid > 0); + g_return_if_fail(ns_handle->pid > 0); - nm_close (ns_handle->pipe_fd); - ns_handle->pipe_fd = 0; + nm_close(ns_handle->pipe_fd); + ns_handle->pipe_fd = 0; - kill (ns_handle->pid, SIGKILL); + kill(ns_handle->pid, SIGKILL); - do { - pid = waitpid (ns_handle->pid, &status, 0); - } while (pid == -1 && errno == EINTR); - ns_handle->pid = 0; + do { + pid = waitpid(ns_handle->pid, &status, 0); + } while (pid == -1 && errno == EINTR); + ns_handle->pid = 0; - g_free (ns_handle); + g_free(ns_handle); } int -nmtstp_namespace_get_fd_for_process (pid_t pid, const char *ns_name) +nmtstp_namespace_get_fd_for_process(pid_t pid, const char *ns_name) { - char p[1000]; + char p[1000]; - g_return_val_if_fail (pid > 0, 0); - g_return_val_if_fail (ns_name && ns_name[0] && strlen (ns_name) < 50, 0); + g_return_val_if_fail(pid > 0, 0); + g_return_val_if_fail(ns_name && ns_name[0] && strlen(ns_name) < 50, 0); - nm_sprintf_buf (p, "/proc/%lu/ns/%s", (unsigned long) pid, ns_name); + nm_sprintf_buf(p, "/proc/%lu/ns/%s", (unsigned long) pid, ns_name); - return open(p, O_RDONLY | O_CLOEXEC); + return open(p, O_RDONLY | O_CLOEXEC); } /*****************************************************************************/ void -nmtstp_netns_select_random (NMPlatform **platforms, gsize n_platforms, NMPNetns **netns) +nmtstp_netns_select_random(NMPlatform **platforms, gsize n_platforms, NMPNetns **netns) { - int i; + int i; - g_assert (platforms); - g_assert (n_platforms && n_platforms <= G_MAXINT32); - g_assert (netns && !*netns); - for (i = 0; i < n_platforms; i++) - g_assert (NM_IS_PLATFORM (platforms[i])); + g_assert(platforms); + g_assert(n_platforms && n_platforms <= G_MAXINT32); + g_assert(netns && !*netns); + for (i = 0; i < n_platforms; i++) + g_assert(NM_IS_PLATFORM(platforms[i])); - i = nmtst_get_rand_uint32 () % (n_platforms + 1); - if (i == 0) - return; - g_assert (nm_platform_netns_push (platforms[i - 1], netns)); + i = nmtst_get_rand_uint32() % (n_platforms + 1); + if (i == 0) + return; + g_assert(nm_platform_netns_push(platforms[i - 1], netns)); } /*****************************************************************************/ @@ -2036,94 +2476,94 @@ nmtstp_netns_select_random (NMPlatform **platforms, gsize n_platforms, NMPNetns NMTST_DEFINE(); static gboolean -unshare_user (void) +unshare_user(void) { - FILE *f; - uid_t uid = geteuid (); - gid_t gid = getegid (); + FILE *f; + uid_t uid = geteuid(); + gid_t gid = getegid(); - /* Already a root? */ - if (gid == 0 && uid == 0) - return TRUE; + /* Already a root? */ + if (gid == 0 && uid == 0) + return TRUE; - /* Become a root in new user NS. */ - if (unshare (CLONE_NEWUSER) != 0) - return FALSE; + /* Become a root in new user NS. */ + if (unshare(CLONE_NEWUSER) != 0) + return FALSE; - /* Since Linux 3.19 we have to disable setgroups() in order to map users. - * Just proceed if the file is not there. */ - f = fopen ("/proc/self/setgroups", "we"); - if (f) { - fprintf (f, "deny"); - fclose (f); - } + /* Since Linux 3.19 we have to disable setgroups() in order to map users. + * Just proceed if the file is not there. */ + f = fopen("/proc/self/setgroups", "we"); + if (f) { + fprintf(f, "deny"); + fclose(f); + } - /* Map current UID to root in NS to be created. */ - f = fopen ("/proc/self/uid_map", "we"); - if (!f) - return FALSE; - fprintf (f, "0 %d 1", uid); - fclose (f); + /* Map current UID to root in NS to be created. */ + f = fopen("/proc/self/uid_map", "we"); + if (!f) + return FALSE; + fprintf(f, "0 %d 1", uid); + fclose(f); - /* Map current GID to root in NS to be created. */ - f = fopen ("/proc/self/gid_map", "we"); - if (!f) - return FALSE; - fprintf (f, "0 %d 1", gid); - fclose (f); + /* Map current GID to root in NS to be created. */ + f = fopen("/proc/self/gid_map", "we"); + if (!f) + return FALSE; + fprintf(f, "0 %d 1", gid); + fclose(f); - return TRUE; + return TRUE; } int -main (int argc, char **argv) +main(int argc, char **argv) { - int result; - const char *program = *argv; + int result; + const char *program = *argv; - _nmtstp_init_tests (&argc, &argv); + _nmtstp_init_tests(&argc, &argv); - if ( nmtstp_is_root_test () - && (geteuid () != 0 || getegid () != 0)) { - if ( g_getenv ("NMTST_FORCE_REAL_ROOT") - || !unshare_user ()) { - /* Try to exec as sudo, this function does not return, if a sudo-cmd is set. */ - nmtst_reexec_sudo (); + if (nmtstp_is_root_test() && (geteuid() != 0 || getegid() != 0)) { + if (g_getenv("NMTST_FORCE_REAL_ROOT") || !unshare_user()) { + /* Try to exec as sudo, this function does not return, if a sudo-cmd is set. */ + nmtst_reexec_sudo(); #ifdef REQUIRE_ROOT_TESTS - g_print ("Fail test: requires root privileges (%s)\n", program); - return EXIT_FAILURE; + g_print("Fail test: requires root privileges (%s)\n", program); + return EXIT_FAILURE; #else - g_print ("Skipping test: requires root privileges (%s)\n", program); - return g_test_run (); + g_print("Skipping test: requires root privileges (%s)\n", program); + return g_test_run(); #endif - } - } + } + } - if (nmtstp_is_root_test () && !g_getenv ("NMTST_NO_UNSHARE")) { - int errsv; + if (nmtstp_is_root_test() && !g_getenv("NMTST_NO_UNSHARE")) { + int errsv; - if (unshare (CLONE_NEWNET | CLONE_NEWNS) != 0) { - errsv = errno; - g_error ("unshare(CLONE_NEWNET|CLONE_NEWNS) failed with %s (%d)", nm_strerror_native (errsv), errsv); - } + if (unshare(CLONE_NEWNET | CLONE_NEWNS) != 0) { + errsv = errno; + g_error("unshare(CLONE_NEWNET|CLONE_NEWNS) failed with %s (%d)", + nm_strerror_native(errsv), + errsv); + } - /* We need a read-only /sys so that the platform knows there's no udev. */ - mount (NULL, "/sys", "sysfs", MS_SLAVE, NULL); - if (mount ("sys", "/sys", "sysfs", MS_RDONLY, NULL) != 0) { - errsv = errno; - g_error ("mount(\"/sys\") failed with %s (%d)", nm_strerror_native (errsv), errsv); - } - } + /* We need a read-only /sys so that the platform knows there's no udev. */ + mount(NULL, "/sys", "sysfs", MS_SLAVE, NULL); + if (mount("sys", "/sys", "sysfs", MS_RDONLY, NULL) != 0) { + errsv = errno; + g_error("mount(\"/sys\") failed with %s (%d)", nm_strerror_native(errsv), errsv); + } + } - nmtstp_setup_platform (); + nmtstp_setup_platform(); - _nmtstp_setup_tests (); + _nmtstp_setup_tests(); - result = g_test_run (); + result = g_test_run(); - nmtstp_link_delete (NM_PLATFORM_GET, -1, -1, DEVICE_NAME, FALSE); + nmtstp_link_delete(NM_PLATFORM_GET, -1, -1, DEVICE_NAME, FALSE); - g_object_unref (NM_PLATFORM_GET); - return result; + g_object_unref(NM_PLATFORM_GET); + return result; } |