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