platform: merge branch 'th/platform-tun'

https://github.com/NetworkManager/NetworkManager/pull/87
This commit is contained in:
Thomas Haller 2018-04-09 20:29:13 +02:00
commit 69e80d6c51
10 changed files with 295 additions and 82 deletions

View file

@ -162,6 +162,14 @@
g_assert_not_reached (); \
} G_STMT_END
#define nmtst_assert_nonnull(command) \
({ \
typeof (*(command)) *_ptr = (command); \
\
g_assert (_ptr && (TRUE || (command))); \
_ptr; \
})
#define nmtst_assert_success(success, error) \
G_STMT_START { \
g_assert_no_error (error); \
@ -808,6 +816,12 @@ nmtst_get_rand_int (void)
return g_rand_int (nmtst_get_rand ());
}
static inline gboolean
nmtst_get_rand_bool (void)
{
return nmtst_get_rand_int () % 2;
}
static inline gpointer
nmtst_rand_buf (GRand *rand, gpointer buffer, gsize buffer_length)
{

View file

@ -264,7 +264,8 @@ create_and_realize (NMDevice *device,
plerr = nm_platform_link_tun_add (nm_device_get_platform (device),
iface,
&props,
out_plink);
out_plink,
NULL);
if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
"Failed to create TUN/TAP interface '%s' for '%s': %s",

View file

@ -347,8 +347,7 @@ static void
_test_recv_fixture_setup (TestRecvFixture *fixture, gconstpointer user_data)
{
const NMPlatformLink *link;
struct ifreq ifr = { };
int fd, s;
nm_auto_close int fd = -1;
fd = open ("/dev/net/tun", O_RDWR | O_CLOEXEC);
if (fd == -1) {
@ -357,20 +356,45 @@ _test_recv_fixture_setup (TestRecvFixture *fixture, gconstpointer user_data)
return;
}
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
nm_utils_ifname_cpy (ifr.ifr_name, TEST_IFNAME);
g_assert (ioctl (fd, TUNSETIFF, &ifr) >= 0);
if (nmtst_get_rand_bool ()) {
const NMPlatformLnkTun lnk = {
.type = IFF_TAP,
.pi = FALSE,
.vnet_hdr = FALSE,
.multi_queue = FALSE,
.persist = FALSE,
};
/* Bring the interface up */
s = socket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
g_assert (s >= 0);
ifr.ifr_flags |= IFF_UP;
g_assert (ioctl (s, SIOCSIFFLAGS, &ifr) >= 0);
nm_close (s);
nm_close (nm_steal_fd (&fd));
link = nmtstp_link_tun_add (NM_PLATFORM_GET,
FALSE,
TEST_IFNAME,
&lnk,
&fd);
g_assert (link);
nmtstp_link_set_updown (NM_PLATFORM_GET, -1, link->ifindex, TRUE);
link = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, TEST_IFNAME, NM_LINK_TYPE_TUN, 0);
} else {
int s;
struct ifreq ifr = { };
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
nm_utils_ifname_cpy (ifr.ifr_name, TEST_IFNAME);
g_assert (ioctl (fd, TUNSETIFF, &ifr) >= 0);
/* Bring the interface up */
s = socket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
g_assert (s >= 0);
ifr.ifr_flags |= IFF_UP;
g_assert (ioctl (s, SIOCSIFFLAGS, &ifr) >= 0);
nm_close (s);
link = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, TEST_IFNAME, NM_LINK_TYPE_TUN, 100);
}
link = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, TEST_IFNAME, NM_LINK_TYPE_TUN, 100);
fixture->ifindex = link->ifindex;
fixture->fd = fd;
fixture->fd = nm_steal_fd (&fd);
memcpy (fixture->mac, link->addr.data, ETH_ALEN);
}

View file

@ -1396,10 +1396,6 @@ _parse_lnk_tun (const char *kind, struct nlattr *info_data)
NMPObject *obj;
NMPlatformLnkTun *props;
/* FIXME: the netlink API is not yet part of a released kernel version
* Disable it for now, until we are sure it is stable. */
return NULL;
if (!info_data || !nm_streq0 (kind, "tun"))
return NULL;
@ -3934,40 +3930,46 @@ cache_on_change (NMPlatform *platform,
&& (obj_new && obj_new->_link.netlink.is_in_netlink)
&& (!obj_old || !obj_old->_link.netlink.is_in_netlink))
{
if (!obj_new->_link.netlink.lnk) {
gboolean re_request_link = FALSE;
const NMPlatformLnkTun *lnk_tun;
if ( !obj_new->_link.netlink.lnk
&& NM_IN_SET (obj_new->link.type, NM_LINK_TYPE_GRE,
NM_LINK_TYPE_IP6TNL,
NM_LINK_TYPE_INFINIBAND,
NM_LINK_TYPE_MACVLAN,
NM_LINK_TYPE_MACVLAN,
NM_LINK_TYPE_SIT,
NM_LINK_TYPE_TUN,
NM_LINK_TYPE_VLAN,
NM_LINK_TYPE_VXLAN)) {
/* certain link-types also come with a IFLA_INFO_DATA/lnk_data. It may happen that
* kernel didn't send this notification, thus when we first learn about a link
* that lacks an lnk_data we re-request it again.
*
* For example https://bugzilla.redhat.com/show_bug.cgi?id=1284001 */
switch (obj_new->link.type) {
case NM_LINK_TYPE_GRE:
case NM_LINK_TYPE_IP6TNL:
case NM_LINK_TYPE_INFINIBAND:
case NM_LINK_TYPE_MACVLAN:
case NM_LINK_TYPE_MACVTAP:
case NM_LINK_TYPE_SIT:
case NM_LINK_TYPE_VLAN:
case NM_LINK_TYPE_VXLAN:
delayed_action_schedule (platform,
DELAYED_ACTION_TYPE_REFRESH_LINK,
GINT_TO_POINTER (obj_new->link.ifindex));
break;
default:
break;
}
}
if ( obj_new->link.type == NM_LINK_TYPE_VETH
&& obj_new->link.parent == 0) {
re_request_link = TRUE;
} else if ( obj_new->link.type == NM_LINK_TYPE_TUN
&& obj_new->_link.netlink.lnk
&& (lnk_tun = &(obj_new->_link.netlink.lnk)->lnk_tun)
&& !lnk_tun->persist
&& lnk_tun->pi
&& !lnk_tun->vnet_hdr
&& !lnk_tun->multi_queue
&& !lnk_tun->owner_valid
&& !lnk_tun->group_valid) {
/* kernel has/had a know issue that the first notification for TUN device would
* be sent with invalid parameters. The message looks like that kind, so refetch
* it. */
re_request_link = TRUE;
} else if ( obj_new->link.type == NM_LINK_TYPE_VETH
&& obj_new->link.parent == 0) {
/* the initial notification when adding a veth pair can lack the parent/IFLA_LINK
* (https://bugzilla.redhat.com/show_bug.cgi?id=1285827).
* Request it again. */
delayed_action_schedule (platform,
DELAYED_ACTION_TYPE_REFRESH_LINK,
GINT_TO_POINTER (obj_new->link.ifindex));
}
if ( obj_new->link.type == NM_LINK_TYPE_ETHERNET
&& obj_new->link.addr.len == 0) {
re_request_link = TRUE;
} else if ( obj_new->link.type == NM_LINK_TYPE_ETHERNET
&& obj_new->link.addr.len == 0) {
/* Due to a kernel bug, we sometimes receive spurious NEWLINK
* messages after a wifi interface has disappeared. Since the
* link is not present anymore we can't determine its type and
@ -3975,6 +3977,9 @@ cache_on_change (NMPlatform *platform,
* specified. Request the link again to check if it really
* exists. https://bugzilla.redhat.com/show_bug.cgi?id=1302037
*/
re_request_link = TRUE;
}
if (re_request_link) {
delayed_action_schedule (platform,
DELAYED_ACTION_TYPE_REFRESH_LINK,
GINT_TO_POINTER (obj_new->link.ifindex));
@ -5591,14 +5596,15 @@ static gboolean
link_tun_add (NMPlatform *platform,
const char *name,
const NMPlatformLnkTun *props,
const NMPlatformLink **out_link)
const NMPlatformLink **out_link,
int *out_fd)
{
const NMPObject *obj;
struct ifreq ifr = { };
nm_auto_close int fd = -1;
if (!NM_IN_SET (props->type, IFF_TAP, IFF_TUN))
return FALSE;
nm_assert (NM_IN_SET (props->type, IFF_TAP, IFF_TUN));
nm_assert (props->persist || out_fd);
fd = open ("/dev/net/tun", O_RDWR | O_CLOEXEC);
if (fd < 0)
@ -5623,18 +5629,23 @@ link_tun_add (NMPlatform *platform,
return FALSE;
}
if (ioctl (fd, TUNSETPERSIST, (int) !!props->persist))
return FALSE;
if (props->persist) {
if (ioctl (fd, TUNSETPERSIST, 1))
return FALSE;
}
do_request_link (platform, 0, name);
obj = nmp_cache_lookup_link_full (nm_platform_get_cache (platform),
0, name, FALSE,
NM_LINK_TYPE_TUN,
NULL, NULL);
if (out_link)
*out_link = obj ? &obj->link : NULL;
return !!obj;
if (!obj)
return FALSE;
NM_SET_OUT (out_link, &obj->link);
NM_SET_OUT (out_fd, nm_steal_fd (&fd));
return TRUE;
}
static gboolean

View file

@ -2046,6 +2046,11 @@ nm_platform_link_vxlan_add (NMPlatform *self,
* @vnet_hdr: whether to set the IFF_VNET_HDR flag
* @multi_queue: whether to set the IFF_MULTI_QUEUE flag
* @out_link: on success, the link object
* @out_fd: (allow-none): if give, return the file descriptor for the
* created device. Note that when creating a non-persistent device,
* this argument is mandatory, otherwise it makes no sense
* to create such an interface.
* The caller is responsible for closing this file descriptor.
*
* Create a TUN or TAP interface.
*/
@ -2053,7 +2058,8 @@ NMPlatformError
nm_platform_link_tun_add (NMPlatform *self,
const char *name,
const NMPlatformLnkTun *props,
const NMPlatformLink **out_link)
const NMPlatformLink **out_link,
int *out_fd)
{
char b[255];
NMPlatformError plerr;
@ -2062,6 +2068,13 @@ nm_platform_link_tun_add (NMPlatform *self,
g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG);
g_return_val_if_fail (props, NM_PLATFORM_ERROR_BUG);
g_return_val_if_fail (NM_IN_SET (props->type, IFF_TUN, IFF_TAP), NM_PLATFORM_ERROR_BUG);
/* creating a non-persistant device requires that the caller handles
* the file descriptor. */
g_return_val_if_fail (props->persist || out_fd, NM_PLATFORM_ERROR_BUG);
NM_SET_OUT (out_fd, -1);
plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_TUN, out_link);
if (plerr != NM_PLATFORM_ERROR_SUCCESS)
@ -2069,7 +2082,7 @@ nm_platform_link_tun_add (NMPlatform *self,
_LOGD ("link: adding tun '%s' %s",
name, nm_platform_lnk_tun_to_string (props, b, sizeof (b)));
if (!klass->link_tun_add (self, name, props, out_link))
if (!klass->link_tun_add (self, name, props, out_link, out_fd))
return NM_PLATFORM_ERROR_UNSPECIFIED;
return NM_PLATFORM_ERROR_SUCCESS;
}
@ -5120,17 +5133,19 @@ nm_platform_lnk_tun_to_string (const NMPlatformLnkTun *lnk, char *buf, gsize len
type = nm_sprintf_buf (str_type, "tun type %u", (guint) lnk->type);
g_snprintf (buf, len,
"%s " /* type */
" pi %s" /* pi */
" vnet_hdr %s" /* vnet_hdr */
"%s" /* type */
"%s" /* pi */
"%s" /* vnet_hdr */
"%s" /* multi_queue */
"%s" /* persist */
"%s" /* owner */
"%s" /* group */
"",
type,
lnk->pi ? "on" : "off",
lnk->vnet_hdr ? "on" : "off",
lnk->pi ? " pi" : "",
lnk->vnet_hdr ? " vnet_hdr" : "",
lnk->multi_queue ? " multi_queue" : "",
lnk->persist ? " persist" : "",
lnk->owner_valid ? nm_sprintf_buf (str_owner, " owner %u", (guint) lnk->owner) : "",
lnk->group_valid ? nm_sprintf_buf (str_group, " group %u", (guint) lnk->group) : "");
return buf;

View file

@ -853,7 +853,8 @@ typedef struct {
gboolean (*link_tun_add) (NMPlatform *platform,
const char *name,
const NMPlatformLnkTun *props,
const NMPlatformLink **out_link);
const NMPlatformLink **out_link,
int *out_fd);
gboolean (*infiniband_partition_add) (NMPlatform *, int parent, int p_key, const NMPlatformLink **out_link);
gboolean (*infiniband_partition_delete) (NMPlatform *, int parent, int p_key);
@ -1286,7 +1287,8 @@ NMPlatformError nm_platform_link_sit_add (NMPlatform *self,
NMPlatformError nm_platform_link_tun_add (NMPlatform *self,
const char *name,
const NMPlatformLnkTun *props,
const NMPlatformLink **out_link);
const NMPlatformLink **out_link,
int *out_fd);
const NMPlatformIP6Address *nm_platform_ip6_address_get (NMPlatform *self, int ifindex, struct in6_addr address);

View file

@ -23,6 +23,7 @@
#include <sched.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <linux/if_tun.h>
#include "test-common.h"
@ -627,7 +628,10 @@ nmtstp_wait_for_signal_until (NMPlatform *platform, gint64 until_ms)
const NMPlatformLink *
nmtstp_wait_for_link (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, gint64 timeout_ms)
{
return nmtstp_wait_for_link_until (platform, ifname, expected_link_type, nm_utils_get_monotonic_timestamp_ms () + timeout_ms);
return nmtstp_wait_for_link_until (platform, ifname, expected_link_type,
timeout_ms
? nm_utils_get_monotonic_timestamp_ms () + timeout_ms
: 0);
}
const NMPlatformLink *
@ -635,6 +639,7 @@ nmtstp_wait_for_link_until (NMPlatform *platform, const char *ifname, NMLinkType
{
const NMPlatformLink *plink;
gint64 now;
gboolean waited_once = FALSE;
_init_platform (&platform, FALSE);
@ -646,29 +651,24 @@ nmtstp_wait_for_link_until (NMPlatform *platform, const char *ifname, NMLinkType
&& (expected_link_type == NM_LINK_TYPE_NONE || plink->type == expected_link_type))
return plink;
if (until_ms < now)
if (until_ms == 0) {
/* don't wait, don't even poll the socket. */
return NULL;
}
if ( waited_once
&& until_ms < now) {
/* timeout reached (+ we already waited for a signal at least once). */
return NULL;
}
waited_once = TRUE;
/* regardless of whether timeout is already reached, we poll the netlink
* socket a bit. */
nmtstp_wait_for_signal (platform, until_ms - now);
}
}
const NMPlatformLink *
nmtstp_assert_wait_for_link (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, guint timeout_ms)
{
return nmtstp_assert_wait_for_link_until (platform, ifname, expected_link_type, nm_utils_get_monotonic_timestamp_ms () + timeout_ms);
}
const NMPlatformLink *
nmtstp_assert_wait_for_link_until (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, gint64 until_ms)
{
const NMPlatformLink *plink;
plink = nmtstp_wait_for_link_until (platform, ifname, expected_link_type, until_ms);
g_assert (plink);
return plink;
}
/*****************************************************************************/
int
@ -1468,6 +1468,73 @@ nmtstp_link_sit_add (NMPlatform *platform,
return pllink;
}
const NMPlatformLink *
nmtstp_link_tun_add (NMPlatform *platform,
gboolean external_command,
const char *name,
const NMPlatformLnkTun *lnk,
int *out_fd)
{
const NMPlatformLink *pllink = NULL;
NMPlatformError plerr;
int err;
g_assert (nm_utils_is_valid_iface_name (name, NULL));
g_assert (lnk);
g_assert (NM_IN_SET (lnk->type, IFF_TUN, IFF_TAP));
g_assert (!out_fd || *out_fd == -1);
if (!lnk->persist) {
/* ip tuntap does not support non-persistent devices.
*
* Add this device only via NMPlatform. */
if (external_command == -1)
external_command = FALSE;
}
external_command = nmtstp_run_command_check_external (external_command);
_init_platform (&platform, external_command);
if (external_command) {
gs_free char *dev = NULL;
gs_free char *local = NULL, *remote = NULL;
g_assert (lnk->persist);
err = nmtstp_run_command ("ip tuntap add"
" mode %s"
"%s" /* user */
"%s" /* group */
"%s" /* pi */
"%s" /* vnet_hdr */
"%s" /* multi_queue */
" name %s",
lnk->type == IFF_TUN ? "tun" : "tap",
lnk->owner_valid ? nm_sprintf_bufa (100, " user %u", (guint) lnk->owner) : "",
lnk->group_valid ? nm_sprintf_bufa (100, " group %u", (guint) lnk->group) : "",
lnk->pi ? " pi" : "",
lnk->vnet_hdr ? " vnet_hdr" : "",
lnk->multi_queue ? " multi_queue" : "",
name);
/* Older versions of iproute2 don't support adding devices.
* On failure, fallback to using platform code. */
if (err == 0)
pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_TUN, 100);
else
g_error ("failure to add tun/tap device via ip-route");
} else {
g_assert (lnk->persist || out_fd);
plerr = nm_platform_link_tun_add (platform, name, lnk, &pllink, out_fd);
g_assert_cmpint (plerr, ==, NM_PLATFORM_ERROR_SUCCESS);
}
g_assert (pllink);
g_assert_cmpint (pllink->type, ==, NM_LINK_TYPE_TUN);
g_assert_cmpstr (pllink->name, ==, name);
return pllink;
}
const NMPlatformLink *
nmtstp_link_vxlan_add (NMPlatform *platform,
gboolean external_command,

View file

@ -129,8 +129,11 @@ const NMPlatformLink *nmtstp_wait_for_link_until (NMPlatform *platform, const ch
g_assert_not_reached (); \
} G_STMT_END
const NMPlatformLink *nmtstp_assert_wait_for_link (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, guint timeout_ms);
const NMPlatformLink *nmtstp_assert_wait_for_link_until (NMPlatform *platform, const char *ifname, NMLinkType expected_link_type, gint64 until_ms);
#define nmtstp_assert_wait_for_link(platform, ifname, expected_link_type, timeout_ms) \
nmtst_assert_nonnull (nmtstp_wait_for_link (platform, ifname, expected_link_type, timeout_ms))
#define nmtstp_assert_wait_for_link_until(platform, ifname, expected_link_type, until_ms) \
nmtst_assert_nonnull (nmtstp_wait_for_link_until (platform, ifname, expected_link_type, until_ms))
/*****************************************************************************/
@ -307,6 +310,11 @@ const NMPlatformLink *nmtstp_link_sit_add (NMPlatform *platform,
gboolean external_command,
const char *name,
const NMPlatformLnkSit *lnk);
const NMPlatformLink *nmtstp_link_tun_add (NMPlatform *platform,
gboolean external_command,
const char *name,
const NMPlatformLnkTun *lnk,
int *out_fd);
const NMPlatformLink *nmtstp_link_vxlan_add (NMPlatform *platform,
gboolean external_command,
const char *name,

View file

@ -23,6 +23,7 @@
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <linux/if_tun.h>
#include "platform/nmp-object.h"
#include "platform/nmp-netns.h"
@ -697,6 +698,8 @@ test_software_detect (gconstpointer user_data)
const NMPObject *lnk;
guint i_step;
const gboolean ext = test_data->external_command;
NMPlatformLnkTun lnk_tun;
nm_auto_close int tun_fd = -1;
nmtstp_run_command_check ("ip link add %s type dummy", PARENT_NAME);
ifindex_parent = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, PARENT_NAME, NM_LINK_TYPE_DUMMY, 100)->ifindex;
@ -892,6 +895,38 @@ test_software_detect (gconstpointer user_data)
g_assert (nmtstp_link_vxlan_add (NULL, ext, DEVICE_NAME, &lnk_vxlan));
break;
}
case NM_LINK_TYPE_TUN: {
gboolean owner_valid = nmtst_get_rand_bool ();
gboolean group_valid = nmtst_get_rand_bool ();
switch (test_data->test_mode) {
case 0:
lnk_tun = (NMPlatformLnkTun) {
.type = nmtst_get_rand_bool () ? IFF_TUN : IFF_TAP,
.owner = owner_valid ? getuid () : 0,
.owner_valid = owner_valid,
.group = group_valid ? getgid () : 0,
.group_valid = group_valid,
.pi = nmtst_get_rand_bool (),
.vnet_hdr = nmtst_get_rand_bool (),
.multi_queue = nmtst_get_rand_bool (),
/* if we add the device via iproute2 (external), we can only
* create persistent devices. */
.persist = (ext == 1) ? TRUE : nmtst_get_rand_bool (),
};
break;
default:
g_assert_not_reached ();
break;
}
g_assert (nmtstp_link_tun_add (NULL, ext, DEVICE_NAME, &lnk_tun,
(!lnk_tun.persist || nmtst_get_rand_bool ())
? &tun_fd
: NULL));
break;
}
default:
g_assert_not_reached ();
}
@ -922,7 +957,13 @@ test_software_detect (gconstpointer user_data)
lnk = nm_platform_link_get_lnk (NM_PLATFORM_GET, ifindex, test_data->link_type, &plink);
g_assert (plink);
g_assert_cmpint (plink->ifindex, ==, ifindex);
g_assert (lnk);
if ( !lnk
&& test_data->link_type == NM_LINK_TYPE_TUN) {
/* this is ok. Kernel apparently does not support tun properties via netlink. We
* fetch them from sysfs below. */
} else
g_assert (lnk);
switch (test_data->link_type) {
case NM_LINK_TYPE_GRE: {
@ -1011,6 +1052,27 @@ test_software_detect (gconstpointer user_data)
g_assert_cmpint (plnk->path_mtu_discovery, ==, FALSE);
break;
}
case NM_LINK_TYPE_TUN: {
const NMPlatformLnkTun *plnk;
NMPlatformLnkTun lnk_tun2;
g_assert ((lnk ? &lnk->lnk_tun : NULL) == nm_platform_link_get_lnk_tun (NM_PLATFORM_GET, ifindex, NULL));
/* kernel might not expose tun options via netlink. Either way, try
* to read them (either from platform cache, or fallback to sysfs).
* See also: rh#1547213. */
if (!nm_platform_link_tun_get_properties (NM_PLATFORM_GET,
ifindex,
&lnk_tun2))
g_assert_not_reached ();
plnk = lnk ? &lnk->lnk_tun : &lnk_tun2;
if (lnk)
g_assert (memcmp (plnk, &lnk_tun2, sizeof (NMPlatformLnkTun)) == 0);
g_assert (nm_platform_lnk_tun_cmp (plnk, &lnk_tun) == 0);
break;
}
case NM_LINK_TYPE_VLAN: {
const NMPlatformLnkVlan *plnk = &lnk->lnk_vlan;
@ -2581,6 +2643,7 @@ _nmtstp_setup_tests (void)
test_software_detect_add ("/link/software/detect/macvlan", NM_LINK_TYPE_MACVLAN, 0);
test_software_detect_add ("/link/software/detect/macvtap", NM_LINK_TYPE_MACVTAP, 0);
test_software_detect_add ("/link/software/detect/sit", NM_LINK_TYPE_SIT, 0);
test_software_detect_add ("/link/software/detect/tun", NM_LINK_TYPE_TUN, 0);
test_software_detect_add ("/link/software/detect/vlan", NM_LINK_TYPE_VLAN, 0);
test_software_detect_add ("/link/software/detect/vxlan/0", NM_LINK_TYPE_VXLAN, 0);
test_software_detect_add ("/link/software/detect/vxlan/1", NM_LINK_TYPE_VXLAN, 1);

View file

@ -121,6 +121,10 @@ else
NMTST_USE_VALGRIND=0
shift;
;;
"-d")
NMTST_SET_DEBUG=1
shift;
;;
"--test"|-t)
shift
TEST="$1"
@ -146,6 +150,10 @@ else
fi
if [ "$NMTST_SET_DEBUG" == 1 -a -z "${NMTST_DEBUG+x}" ]; then
export NMTST_DEBUG=d
fi
if _is_true "$NMTST_MAKE_FIRST" 0; then
git_dir="$(readlink -f "$(git rev-parse --show-toplevel)")"
rel_path="$(realpath --relative-to="$git_dir" -m "$TEST" 2>/dev/null)" || die "cannot resolve test-name \"$TEST\". Did you call the script properly?"