2014-01-21 13:07:06 +01:00
|
|
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
|
|
|
|
/*
|
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
|
|
|
* any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
|
*
|
|
|
|
|
* Copyright (C) 2014 Red Hat, Inc.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
2014-11-13 10:07:02 -05:00
|
|
|
#include "config.h"
|
|
|
|
|
|
2014-01-21 13:07:06 +01:00
|
|
|
#include <glib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
|
|
#include "NetworkManagerUtils.h"
|
2014-07-10 10:40:47 +02:00
|
|
|
#include "nm-logging.h"
|
2014-10-21 22:09:52 -04:00
|
|
|
#include "nm-core-internal.h"
|
2014-01-21 13:07:06 +01:00
|
|
|
|
2014-07-10 10:40:47 +02:00
|
|
|
#include "nm-test-utils.h"
|
2014-01-21 13:07:06 +01:00
|
|
|
|
2014-02-13 18:12:41 +01:00
|
|
|
/* Reference implementation for nm_utils_ip6_address_clear_host_address.
|
|
|
|
|
* Taken originally from set_address_masked(), src/rdisc/nm-lndp-rdisc.c
|
|
|
|
|
**/
|
|
|
|
|
static void
|
|
|
|
|
ip6_address_clear_host_address_reference (struct in6_addr *dst, struct in6_addr *src, guint8 plen)
|
|
|
|
|
{
|
|
|
|
|
guint nbytes = plen / 8;
|
|
|
|
|
guint nbits = plen % 8;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail (plen <= 128);
|
|
|
|
|
g_assert (src);
|
|
|
|
|
g_assert (dst);
|
|
|
|
|
|
|
|
|
|
if (plen >= 128)
|
|
|
|
|
*dst = *src;
|
|
|
|
|
else {
|
|
|
|
|
memset (dst, 0, sizeof (*dst));
|
|
|
|
|
memcpy (dst, src, nbytes);
|
|
|
|
|
dst->s6_addr[nbytes] = (src->s6_addr[nbytes] & (0xFF << (8 - nbits)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2014-08-20 13:59:07 -05:00
|
|
|
_randomize_in6_addr (struct in6_addr *addr, GRand *r)
|
2014-02-13 18:12:41 +01:00
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i=0; i < 4; i++)
|
2014-08-20 13:59:07 -05:00
|
|
|
((guint32 *)addr)[i] = g_rand_int (r);
|
2014-02-13 18:12:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_nm_utils_ip6_address_clear_host_address (void)
|
|
|
|
|
{
|
2014-08-20 13:59:07 -05:00
|
|
|
GRand *r = g_rand_new ();
|
2014-02-13 18:12:41 +01:00
|
|
|
int plen, i;
|
|
|
|
|
|
2014-08-20 13:59:07 -05:00
|
|
|
g_rand_set_seed (r, 0);
|
2014-02-13 18:12:41 +01:00
|
|
|
|
|
|
|
|
for (plen = 0; plen <= 128; plen++) {
|
|
|
|
|
for (i =0; i<50; i++) {
|
|
|
|
|
struct in6_addr addr_src, addr_ref;
|
|
|
|
|
struct in6_addr addr1, addr2;
|
|
|
|
|
|
2014-08-20 13:59:07 -05:00
|
|
|
_randomize_in6_addr (&addr_src, r);
|
|
|
|
|
_randomize_in6_addr (&addr_ref, r);
|
|
|
|
|
_randomize_in6_addr (&addr1, r);
|
|
|
|
|
_randomize_in6_addr (&addr2, r);
|
2014-02-13 18:12:41 +01:00
|
|
|
|
|
|
|
|
addr1 = addr_src;
|
|
|
|
|
ip6_address_clear_host_address_reference (&addr_ref, &addr1, plen);
|
|
|
|
|
|
2014-08-20 13:59:07 -05:00
|
|
|
_randomize_in6_addr (&addr1, r);
|
|
|
|
|
_randomize_in6_addr (&addr2, r);
|
2014-02-13 18:12:41 +01:00
|
|
|
addr1 = addr_src;
|
|
|
|
|
nm_utils_ip6_address_clear_host_address (&addr2, &addr1, plen);
|
|
|
|
|
g_assert_cmpint (memcmp (&addr1, &addr_src, sizeof (struct in6_addr)), ==, 0);
|
|
|
|
|
g_assert_cmpint (memcmp (&addr2, &addr_ref, sizeof (struct in6_addr)), ==, 0);
|
|
|
|
|
|
|
|
|
|
/* test for self assignment/inplace update. */
|
2014-08-20 13:59:07 -05:00
|
|
|
_randomize_in6_addr (&addr1, r);
|
2014-02-13 18:12:41 +01:00
|
|
|
addr1 = addr_src;
|
|
|
|
|
nm_utils_ip6_address_clear_host_address (&addr1, &addr1, plen);
|
|
|
|
|
g_assert_cmpint (memcmp (&addr1, &addr_ref, sizeof (struct in6_addr)), ==, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-20 13:59:07 -05:00
|
|
|
g_rand_free (r);
|
2014-02-13 18:12:41 +01:00
|
|
|
}
|
|
|
|
|
|
2014-02-26 09:51:09 +01:00
|
|
|
|
|
|
|
|
static void
|
2014-10-29 10:44:31 +01:00
|
|
|
test_nm_utils_log_connection_diff (void)
|
2014-02-26 09:51:09 +01:00
|
|
|
{
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
NMConnection *connection2;
|
|
|
|
|
|
|
|
|
|
/* if logging is disabled (the default), nm_utils_log_connection_diff() returns
|
|
|
|
|
* early without doing anything. Hence, in the normal testing, this test does nothing.
|
|
|
|
|
* It only gets interesting, when run verbosely with NMTST_DEBUG=debug ... */
|
|
|
|
|
|
|
|
|
|
nm_log (LOGL_DEBUG, LOGD_CORE, "START TEST test_nm_utils_log_connection_diff...");
|
|
|
|
|
|
|
|
|
|
connection = nm_simple_connection_new ();
|
|
|
|
|
nm_connection_add_setting (connection, nm_setting_connection_new ());
|
|
|
|
|
nm_utils_log_connection_diff (connection, NULL, LOGL_DEBUG, LOGD_CORE, "test1", ">>> ");
|
|
|
|
|
|
|
|
|
|
nm_connection_add_setting (connection, nm_setting_wired_new ());
|
|
|
|
|
nm_utils_log_connection_diff (connection, NULL, LOGL_DEBUG, LOGD_CORE, "test2", ">>> ");
|
|
|
|
|
|
|
|
|
|
connection2 = nm_simple_connection_new_clone (connection);
|
|
|
|
|
nm_utils_log_connection_diff (connection, connection2, LOGL_DEBUG, LOGD_CORE, "test3", ">>> ");
|
|
|
|
|
|
|
|
|
|
g_object_set (nm_connection_get_setting_connection (connection),
|
|
|
|
|
NM_SETTING_CONNECTION_ID, "id",
|
|
|
|
|
NM_SETTING_CONNECTION_UUID, "uuid",
|
|
|
|
|
NULL);
|
|
|
|
|
g_object_set (nm_connection_get_setting_connection (connection2),
|
|
|
|
|
NM_SETTING_CONNECTION_ID, "id2",
|
|
|
|
|
NM_SETTING_CONNECTION_MASTER, "master2",
|
|
|
|
|
NULL);
|
|
|
|
|
nm_utils_log_connection_diff (connection, connection2, LOGL_DEBUG, LOGD_CORE, "test4", ">>> ");
|
|
|
|
|
|
|
|
|
|
nm_connection_add_setting (connection, nm_setting_802_1x_new ());
|
|
|
|
|
nm_utils_log_connection_diff (connection, connection2, LOGL_DEBUG, LOGD_CORE, "test5", ">>> ");
|
|
|
|
|
|
|
|
|
|
g_object_set (nm_connection_get_setting_802_1x (connection),
|
|
|
|
|
NM_SETTING_802_1X_PASSWORD, "id2",
|
|
|
|
|
NM_SETTING_802_1X_PASSWORD_FLAGS, NM_SETTING_SECRET_FLAG_NOT_SAVED,
|
|
|
|
|
NULL);
|
|
|
|
|
nm_utils_log_connection_diff (connection, NULL, LOGL_DEBUG, LOGD_CORE, "test6", ">>> ");
|
|
|
|
|
nm_utils_log_connection_diff (connection, connection2, LOGL_DEBUG, LOGD_CORE, "test7", ">>> ");
|
|
|
|
|
nm_utils_log_connection_diff (connection2, connection, LOGL_DEBUG, LOGD_CORE, "test8", ">>> ");
|
|
|
|
|
|
|
|
|
|
g_clear_object (&connection);
|
|
|
|
|
g_clear_object (&connection2);
|
|
|
|
|
|
|
|
|
|
connection = nmtst_create_minimal_connection ("id-vpn-1", NULL, NM_SETTING_VPN_SETTING_NAME, NULL);
|
|
|
|
|
nm_utils_log_connection_diff (connection, NULL, LOGL_DEBUG, LOGD_CORE, "test-vpn-1", ">>> ");
|
|
|
|
|
|
|
|
|
|
g_clear_object (&connection);
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-21 13:07:06 +01:00
|
|
|
/*******************************************/
|
|
|
|
|
|
2014-02-25 17:44:07 -06:00
|
|
|
static NMConnection *
|
|
|
|
|
_match_connection_new (void)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *connection;
|
|
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
NMSettingWired *s_wired;
|
2014-10-19 17:30:10 -04:00
|
|
|
NMSettingIPConfig *s_ip4, *s_ip6;
|
2014-02-25 17:44:07 -06:00
|
|
|
char *uuid;
|
|
|
|
|
|
2014-08-13 14:34:29 -04:00
|
|
|
connection = nm_simple_connection_new ();
|
2014-02-25 17:44:07 -06:00
|
|
|
|
|
|
|
|
s_con = (NMSettingConnection *) nm_setting_connection_new ();
|
|
|
|
|
nm_connection_add_setting (connection, (NMSetting *) s_con);
|
|
|
|
|
uuid = nm_utils_uuid_generate ();
|
|
|
|
|
g_object_set (G_OBJECT (s_con),
|
|
|
|
|
NM_SETTING_CONNECTION_ID, "blahblah",
|
|
|
|
|
NM_SETTING_CONNECTION_UUID, uuid,
|
|
|
|
|
NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
|
|
|
|
|
NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
|
|
|
|
|
NULL);
|
|
|
|
|
g_free (uuid);
|
|
|
|
|
|
|
|
|
|
s_wired = (NMSettingWired *) nm_setting_wired_new ();
|
|
|
|
|
nm_connection_add_setting (connection, (NMSetting *) s_wired);
|
|
|
|
|
|
2014-10-19 17:30:10 -04:00
|
|
|
s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new ();
|
2014-02-25 17:44:07 -06:00
|
|
|
nm_connection_add_setting (connection, (NMSetting *) s_ip4);
|
|
|
|
|
g_object_set (G_OBJECT (s_ip4),
|
2014-10-19 17:30:10 -04:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
|
2014-02-25 17:44:07 -06:00
|
|
|
NULL);
|
|
|
|
|
|
2014-10-19 17:30:10 -04:00
|
|
|
s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new ();
|
2014-02-25 17:44:07 -06:00
|
|
|
nm_connection_add_setting (connection, (NMSetting *) s_ip6);
|
|
|
|
|
g_object_set (G_OBJECT (s_ip6),
|
2014-10-19 17:30:10 -04:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO,
|
2014-02-25 17:44:07 -06:00
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
return connection;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_connection_match_basic (void)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *orig, *copy, *matched;
|
|
|
|
|
GSList *connections = NULL;
|
2014-10-19 17:30:10 -04:00
|
|
|
NMSettingIPConfig *s_ip4;
|
2014-02-25 17:44:07 -06:00
|
|
|
|
|
|
|
|
orig = _match_connection_new ();
|
2014-08-13 14:34:29 -04:00
|
|
|
copy = nm_simple_connection_new_clone (orig);
|
2014-02-25 17:44:07 -06:00
|
|
|
connections = g_slist_append (connections, copy);
|
|
|
|
|
|
2014-02-25 17:56:06 -06:00
|
|
|
matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL);
|
2014-02-25 17:44:07 -06:00
|
|
|
g_assert (matched == copy);
|
|
|
|
|
|
|
|
|
|
/* Now change a material property like IPv4 method and ensure matching fails */
|
|
|
|
|
s_ip4 = nm_connection_get_setting_ip4_config (orig);
|
|
|
|
|
g_assert (s_ip4);
|
|
|
|
|
g_object_set (G_OBJECT (s_ip4),
|
2014-10-19 17:30:10 -04:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL,
|
2014-02-25 17:44:07 -06:00
|
|
|
NULL);
|
2014-02-25 17:56:06 -06:00
|
|
|
matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL);
|
2014-02-25 17:44:07 -06:00
|
|
|
g_assert (matched == NULL);
|
|
|
|
|
|
|
|
|
|
g_slist_free (connections);
|
|
|
|
|
g_object_unref (orig);
|
|
|
|
|
g_object_unref (copy);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_connection_match_ip6_method (void)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *orig, *copy, *matched;
|
|
|
|
|
GSList *connections = NULL;
|
2014-10-19 17:30:10 -04:00
|
|
|
NMSettingIPConfig *s_ip6;
|
2014-02-25 17:44:07 -06:00
|
|
|
|
|
|
|
|
orig = _match_connection_new ();
|
2014-08-13 14:34:29 -04:00
|
|
|
copy = nm_simple_connection_new_clone (orig);
|
2014-02-25 17:44:07 -06:00
|
|
|
connections = g_slist_append (connections, copy);
|
|
|
|
|
|
2014-05-30 09:06:24 +02:00
|
|
|
/* Check that if the generated connection is IPv6 method=link-local, and the
|
2014-02-25 17:44:07 -06:00
|
|
|
* candidate is both method=auto and may-faily=true, that the candidate is
|
|
|
|
|
* matched.
|
|
|
|
|
*/
|
|
|
|
|
s_ip6 = nm_connection_get_setting_ip6_config (orig);
|
|
|
|
|
g_assert (s_ip6);
|
|
|
|
|
g_object_set (G_OBJECT (s_ip6),
|
2014-10-19 17:30:10 -04:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL,
|
2014-02-25 17:44:07 -06:00
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
s_ip6 = nm_connection_get_setting_ip6_config (copy);
|
|
|
|
|
g_assert (s_ip6);
|
|
|
|
|
g_object_set (G_OBJECT (s_ip6),
|
2014-10-19 17:30:10 -04:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO,
|
|
|
|
|
NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE,
|
2014-02-25 17:44:07 -06:00
|
|
|
NULL);
|
|
|
|
|
|
2014-02-25 17:56:06 -06:00
|
|
|
matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL);
|
2014-02-25 17:44:07 -06:00
|
|
|
g_assert (matched == copy);
|
|
|
|
|
|
|
|
|
|
g_slist_free (connections);
|
|
|
|
|
g_object_unref (orig);
|
|
|
|
|
g_object_unref (copy);
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-07 10:33:12 +01:00
|
|
|
static void
|
|
|
|
|
test_connection_match_ip6_method_ignore (void)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *orig, *copy, *matched;
|
|
|
|
|
GSList *connections = NULL;
|
2014-10-19 17:30:10 -04:00
|
|
|
NMSettingIPConfig *s_ip6;
|
2014-03-07 10:33:12 +01:00
|
|
|
|
|
|
|
|
orig = _match_connection_new ();
|
2014-08-13 14:34:29 -04:00
|
|
|
copy = nm_simple_connection_new_clone (orig);
|
2014-03-07 10:33:12 +01:00
|
|
|
connections = g_slist_append (connections, copy);
|
|
|
|
|
|
2014-05-30 09:06:24 +02:00
|
|
|
/* Check that if the generated connection is IPv6 method=link-local, and the
|
2014-03-07 10:33:12 +01:00
|
|
|
* candidate is method=ignore, that the candidate is matched.
|
|
|
|
|
*/
|
|
|
|
|
s_ip6 = nm_connection_get_setting_ip6_config (orig);
|
|
|
|
|
g_assert (s_ip6);
|
|
|
|
|
g_object_set (G_OBJECT (s_ip6),
|
2014-10-19 17:30:10 -04:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL,
|
2014-03-07 10:33:12 +01:00
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
s_ip6 = nm_connection_get_setting_ip6_config (copy);
|
|
|
|
|
g_assert (s_ip6);
|
|
|
|
|
g_object_set (G_OBJECT (s_ip6),
|
2014-10-19 17:30:10 -04:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
|
2014-03-07 10:33:12 +01:00
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL);
|
|
|
|
|
g_assert (matched == copy);
|
|
|
|
|
|
|
|
|
|
g_slist_free (connections);
|
|
|
|
|
g_object_unref (orig);
|
|
|
|
|
g_object_unref (copy);
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-29 16:36:24 +02:00
|
|
|
static void
|
|
|
|
|
test_connection_match_ip6_method_ignore_auto (void)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *orig, *copy, *matched;
|
|
|
|
|
GSList *connections = NULL;
|
2014-10-19 17:30:10 -04:00
|
|
|
NMSettingIPConfig *s_ip6;
|
2014-05-29 16:36:24 +02:00
|
|
|
|
|
|
|
|
orig = _match_connection_new ();
|
2014-08-13 14:34:29 -04:00
|
|
|
copy = nm_simple_connection_new_clone (orig);
|
2014-05-29 16:36:24 +02:00
|
|
|
connections = g_slist_append (connections, copy);
|
|
|
|
|
|
|
|
|
|
/* Check that if the generated connection is IPv6 method=auto, and the
|
|
|
|
|
* candidate is method=ignore, that the candidate is matched.
|
|
|
|
|
*/
|
|
|
|
|
s_ip6 = nm_connection_get_setting_ip6_config (orig);
|
|
|
|
|
g_assert (s_ip6);
|
|
|
|
|
g_object_set (G_OBJECT (s_ip6),
|
2014-10-19 17:30:10 -04:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO,
|
2014-05-29 16:36:24 +02:00
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
s_ip6 = nm_connection_get_setting_ip6_config (copy);
|
|
|
|
|
g_assert (s_ip6);
|
|
|
|
|
g_object_set (G_OBJECT (s_ip6),
|
2014-10-19 17:30:10 -04:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
|
2014-05-29 16:36:24 +02:00
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL);
|
|
|
|
|
g_assert (matched == copy);
|
|
|
|
|
|
|
|
|
|
g_slist_free (connections);
|
|
|
|
|
g_object_unref (orig);
|
|
|
|
|
g_object_unref (copy);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2014-02-25 17:56:06 -06:00
|
|
|
static void
|
|
|
|
|
test_connection_match_ip4_method (void)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *orig, *copy, *matched;
|
|
|
|
|
GSList *connections = NULL;
|
2014-10-19 17:30:10 -04:00
|
|
|
NMSettingIPConfig *s_ip4;
|
2014-02-25 17:56:06 -06:00
|
|
|
|
|
|
|
|
orig = _match_connection_new ();
|
2014-08-13 14:34:29 -04:00
|
|
|
copy = nm_simple_connection_new_clone (orig);
|
2014-02-25 17:56:06 -06:00
|
|
|
connections = g_slist_append (connections, copy);
|
|
|
|
|
|
2014-05-30 09:06:24 +02:00
|
|
|
/* Check that if the generated connection is IPv4 method=disabled, and the
|
2014-02-25 17:56:06 -06:00
|
|
|
* candidate is both method=auto and may-faily=true, and the device has no
|
|
|
|
|
* carrier that the candidate is matched.
|
|
|
|
|
*/
|
|
|
|
|
s_ip4 = nm_connection_get_setting_ip4_config (orig);
|
|
|
|
|
g_assert (s_ip4);
|
|
|
|
|
g_object_set (G_OBJECT (s_ip4),
|
2014-10-19 17:30:10 -04:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
|
2014-02-25 17:56:06 -06:00
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
s_ip4 = nm_connection_get_setting_ip4_config (copy);
|
|
|
|
|
g_assert (s_ip4);
|
|
|
|
|
g_object_set (G_OBJECT (s_ip4),
|
2014-10-19 17:30:10 -04:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
|
|
|
|
|
NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE,
|
2014-02-25 17:56:06 -06:00
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
matched = nm_utils_match_connection (connections, orig, FALSE, NULL, NULL);
|
|
|
|
|
g_assert (matched == copy);
|
|
|
|
|
|
|
|
|
|
/* Ensure when carrier=true matching fails */
|
|
|
|
|
matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL);
|
|
|
|
|
g_assert (matched == NULL);
|
|
|
|
|
|
|
|
|
|
g_slist_free (connections);
|
|
|
|
|
g_object_unref (orig);
|
|
|
|
|
g_object_unref (copy);
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-18 14:21:59 +01:00
|
|
|
static void
|
|
|
|
|
test_connection_match_interface_name (void)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *orig, *copy, *matched;
|
|
|
|
|
GSList *connections = NULL;
|
|
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
|
|
|
|
|
orig = _match_connection_new ();
|
2014-08-13 14:34:29 -04:00
|
|
|
copy = nm_simple_connection_new_clone (orig);
|
2014-03-18 14:21:59 +01:00
|
|
|
connections = g_slist_append (connections, copy);
|
|
|
|
|
|
2014-05-30 09:06:24 +02:00
|
|
|
/* Check that if the generated connection has an interface name and the
|
|
|
|
|
* candidate's interface name is NULL, that the candidate is matched.
|
2014-03-18 14:21:59 +01:00
|
|
|
*/
|
|
|
|
|
s_con = nm_connection_get_setting_connection (orig);
|
|
|
|
|
g_assert (s_con);
|
|
|
|
|
g_object_set (G_OBJECT (s_con),
|
|
|
|
|
NM_SETTING_CONNECTION_INTERFACE_NAME, "em1",
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
s_con = nm_connection_get_setting_connection (copy);
|
|
|
|
|
g_assert (s_con);
|
|
|
|
|
g_object_set (G_OBJECT (s_con),
|
|
|
|
|
NM_SETTING_CONNECTION_INTERFACE_NAME, NULL,
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL);
|
|
|
|
|
g_assert (matched == copy);
|
|
|
|
|
|
|
|
|
|
g_slist_free (connections);
|
|
|
|
|
g_object_unref (orig);
|
|
|
|
|
g_object_unref (copy);
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-08 10:39:31 +02:00
|
|
|
static void
|
|
|
|
|
test_connection_match_wired (void)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *orig, *copy, *matched;
|
|
|
|
|
GSList *connections = NULL;
|
|
|
|
|
NMSettingWired *s_wired;
|
2014-08-21 13:19:53 -04:00
|
|
|
char *subchan_arr[] = { "0.0.8000", "0.0.8001", "0.0.8002", NULL };
|
2014-12-11 11:29:19 +01:00
|
|
|
const char *mac = "52:54:00:ab:db:23";
|
2014-04-08 10:39:31 +02:00
|
|
|
|
|
|
|
|
orig = _match_connection_new ();
|
2014-08-13 14:34:29 -04:00
|
|
|
copy = nm_simple_connection_new_clone (orig);
|
2014-04-08 10:39:31 +02:00
|
|
|
connections = g_slist_append (connections, copy);
|
|
|
|
|
|
|
|
|
|
s_wired = nm_connection_get_setting_wired (orig);
|
|
|
|
|
g_assert (s_wired);
|
|
|
|
|
g_object_set (G_OBJECT (s_wired),
|
|
|
|
|
NM_SETTING_WIRED_PORT, "tp", /* port is not compared */
|
|
|
|
|
NM_SETTING_WIRED_MAC_ADDRESS, mac, /* we allow MAC address just in one connection */
|
|
|
|
|
NM_SETTING_WIRED_S390_SUBCHANNELS, subchan_arr,
|
|
|
|
|
NM_SETTING_WIRED_S390_NETTYPE, "qeth",
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
s_wired = nm_connection_get_setting_wired (copy);
|
|
|
|
|
g_assert (s_wired);
|
|
|
|
|
g_object_set (G_OBJECT (s_wired),
|
|
|
|
|
NM_SETTING_WIRED_S390_SUBCHANNELS, subchan_arr,
|
|
|
|
|
NM_SETTING_WIRED_S390_NETTYPE, "qeth",
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL);
|
|
|
|
|
g_assert (matched == copy);
|
|
|
|
|
|
|
|
|
|
g_slist_free (connections);
|
|
|
|
|
g_object_unref (orig);
|
|
|
|
|
g_object_unref (copy);
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-19 17:53:43 +01:00
|
|
|
static void
|
|
|
|
|
test_connection_match_cloned_mac (void)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *orig, *exact, *fuzzy, *matched;
|
|
|
|
|
GSList *connections = NULL;
|
|
|
|
|
NMSettingWired *s_wired;
|
|
|
|
|
|
|
|
|
|
orig = _match_connection_new ();
|
|
|
|
|
|
|
|
|
|
fuzzy = nm_simple_connection_new_clone (orig);
|
|
|
|
|
connections = g_slist_append (connections, fuzzy);
|
|
|
|
|
s_wired = nm_connection_get_setting_wired (orig);
|
|
|
|
|
g_assert (s_wired);
|
|
|
|
|
g_object_set (G_OBJECT (s_wired),
|
|
|
|
|
NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "52:54:00:ab:db:23",
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL);
|
|
|
|
|
g_assert (matched == fuzzy);
|
|
|
|
|
|
|
|
|
|
exact = nm_simple_connection_new_clone (orig);
|
|
|
|
|
connections = g_slist_append (connections, exact);
|
|
|
|
|
s_wired = nm_connection_get_setting_wired (exact);
|
|
|
|
|
g_assert (s_wired);
|
|
|
|
|
g_object_set (G_OBJECT (s_wired),
|
|
|
|
|
NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "52:54:00:ab:db:23",
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL);
|
|
|
|
|
g_assert (matched == exact);
|
|
|
|
|
|
|
|
|
|
g_object_set (G_OBJECT (s_wired),
|
|
|
|
|
NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "52:54:00:ab:db:24",
|
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL);
|
|
|
|
|
g_assert (matched == fuzzy);
|
|
|
|
|
|
|
|
|
|
g_slist_free (connections);
|
|
|
|
|
g_object_unref (orig);
|
|
|
|
|
g_object_unref (fuzzy);
|
|
|
|
|
g_object_unref (exact);
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-08 10:39:31 +02:00
|
|
|
static void
|
|
|
|
|
test_connection_no_match_ip4_addr (void)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *orig, *copy, *matched;
|
|
|
|
|
GSList *connections = NULL;
|
2014-10-19 17:30:10 -04:00
|
|
|
NMSettingIPConfig *s_ip4, *s_ip6;
|
2014-09-16 16:42:46 -04:00
|
|
|
NMIPAddress *nm_addr;
|
|
|
|
|
GError *error = NULL;
|
2014-04-08 10:39:31 +02:00
|
|
|
|
|
|
|
|
orig = _match_connection_new ();
|
2014-08-13 14:34:29 -04:00
|
|
|
copy = nm_simple_connection_new_clone (orig);
|
2014-04-08 10:39:31 +02:00
|
|
|
connections = g_slist_append (connections, copy);
|
|
|
|
|
|
|
|
|
|
/* Check that if we have two differences, ipv6.method (exception we allow) and
|
|
|
|
|
* ipv4.addresses (which is fatal), we don't match the connections.
|
|
|
|
|
*/
|
|
|
|
|
s_ip6 = nm_connection_get_setting_ip6_config (orig);
|
|
|
|
|
g_assert (s_ip6);
|
|
|
|
|
g_object_set (G_OBJECT (s_ip6),
|
2014-10-19 17:30:10 -04:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL,
|
2014-04-08 10:39:31 +02:00
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
s_ip6 = nm_connection_get_setting_ip6_config (copy);
|
|
|
|
|
g_assert (s_ip6);
|
|
|
|
|
g_object_set (G_OBJECT (s_ip6),
|
2014-10-19 17:30:10 -04:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
|
2014-04-08 10:39:31 +02:00
|
|
|
NULL);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
s_ip4 = nm_connection_get_setting_ip4_config (orig);
|
|
|
|
|
g_assert (s_ip4);
|
|
|
|
|
g_object_set (G_OBJECT (s_ip4),
|
2014-10-19 17:30:10 -04:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
|
2014-10-20 21:30:56 -04:00
|
|
|
NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.254",
|
2014-04-08 10:39:31 +02:00
|
|
|
NULL);
|
2014-10-20 21:30:56 -04:00
|
|
|
nm_addr = nm_ip_address_new (AF_INET, "1.1.1.4", 24, &error);
|
2014-09-16 16:42:46 -04:00
|
|
|
g_assert_no_error (error);
|
2014-10-19 17:30:10 -04:00
|
|
|
nm_setting_ip_config_add_address (s_ip4, nm_addr);
|
2014-09-16 16:42:46 -04:00
|
|
|
nm_ip_address_unref (nm_addr);
|
2014-04-08 10:39:31 +02:00
|
|
|
|
|
|
|
|
s_ip4 = nm_connection_get_setting_ip4_config (copy);
|
|
|
|
|
g_assert (s_ip4);
|
|
|
|
|
g_object_set (G_OBJECT (s_ip4),
|
2014-10-19 17:30:10 -04:00
|
|
|
NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
|
2014-10-20 21:30:56 -04:00
|
|
|
NM_SETTING_IP_CONFIG_GATEWAY, "2.2.2.254",
|
2014-04-08 10:39:31 +02:00
|
|
|
NULL);
|
2014-10-20 21:30:56 -04:00
|
|
|
nm_addr = nm_ip_address_new (AF_INET, "2.2.2.4", 24, &error);
|
2014-09-16 16:42:46 -04:00
|
|
|
g_assert_no_error (error);
|
2014-10-19 17:30:10 -04:00
|
|
|
nm_setting_ip_config_add_address (s_ip4, nm_addr);
|
2014-09-16 16:42:46 -04:00
|
|
|
nm_ip_address_unref (nm_addr);
|
2014-04-08 10:39:31 +02:00
|
|
|
|
|
|
|
|
matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL);
|
|
|
|
|
g_assert (matched != copy);
|
|
|
|
|
|
|
|
|
|
g_slist_free (connections);
|
|
|
|
|
g_object_unref (orig);
|
|
|
|
|
g_object_unref (copy);
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-26 16:06:39 +02:00
|
|
|
static NMConnection *
|
|
|
|
|
_create_connection_autoconnect (const char *id, gboolean autoconnect, int autoconnect_priority)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *c;
|
|
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
|
|
|
|
|
c = nmtst_create_minimal_connection (id, NULL, NM_SETTING_WIRED_SETTING_NAME, &s_con);
|
|
|
|
|
g_object_set (s_con,
|
|
|
|
|
NM_SETTING_CONNECTION_AUTOCONNECT, autoconnect,
|
|
|
|
|
NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY, autoconnect_priority,
|
|
|
|
|
NULL);
|
|
|
|
|
nmtst_connection_normalize (c);
|
|
|
|
|
return c;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_test_connection_sort_autoconnect_priority_one (NMConnection **list, gboolean shuffle)
|
|
|
|
|
{
|
|
|
|
|
int i, j;
|
|
|
|
|
int count = 0;
|
|
|
|
|
gs_unref_ptrarray GPtrArray *connections = g_ptr_array_new ();
|
|
|
|
|
|
|
|
|
|
while (list[count])
|
|
|
|
|
count++;
|
|
|
|
|
g_assert (count > 1);
|
|
|
|
|
|
|
|
|
|
/* copy the list of connections over to @connections and shuffle. */
|
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
|
g_ptr_array_add (connections, list[i]);
|
|
|
|
|
if (shuffle) {
|
|
|
|
|
for (i = count - 1; i > 0; i--) {
|
|
|
|
|
j = g_rand_int (nmtst_get_rand ()) % (i + 1);
|
|
|
|
|
NMTST_SWAP (connections->pdata[i], connections->pdata[j]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* sort it... */
|
|
|
|
|
g_ptr_array_sort (connections, (GCompareFunc) nm_utils_cmp_connection_by_autoconnect_priority);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
|
if (list[i] == connections->pdata[i])
|
|
|
|
|
continue;
|
|
|
|
|
if (shuffle && nm_utils_cmp_connection_by_autoconnect_priority (&list[i], (NMConnection **) &connections->pdata[i]) == 0)
|
|
|
|
|
continue;
|
|
|
|
|
g_message ("After sorting, the order of connections is not as expected!! Offending index: %d", i);
|
|
|
|
|
for (j = 0; j < count; j++)
|
|
|
|
|
g_message (" %3d: %p/%-20s - %p/%-20s", j, list[j], nm_connection_get_id (list[j]), connections->pdata[j], nm_connection_get_id (connections->pdata[j]));
|
|
|
|
|
g_assert_not_reached ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_test_connection_sort_autoconnect_priority_free (NMConnection **list)
|
|
|
|
|
{
|
|
|
|
|
while (*list) {
|
|
|
|
|
g_object_unref (*list);
|
|
|
|
|
*list = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_connection_sort_autoconnect_priority (void)
|
|
|
|
|
{
|
|
|
|
|
NMConnection *c1[] = {
|
|
|
|
|
_create_connection_autoconnect ("AC/100", TRUE, 100),
|
|
|
|
|
_create_connection_autoconnect ("AC/100", TRUE, 100),
|
|
|
|
|
_create_connection_autoconnect ("AC/99", TRUE, 99),
|
|
|
|
|
_create_connection_autoconnect ("AC/0", TRUE, 0),
|
|
|
|
|
_create_connection_autoconnect ("AC/0", TRUE, 0),
|
|
|
|
|
_create_connection_autoconnect ("AC/-1", TRUE, -1),
|
|
|
|
|
_create_connection_autoconnect ("AC/-3", TRUE, -3),
|
|
|
|
|
_create_connection_autoconnect ("ac/0", FALSE, 0),
|
|
|
|
|
_create_connection_autoconnect ("ac/0", FALSE, 0),
|
|
|
|
|
_create_connection_autoconnect ("ac/1", FALSE, 1),
|
|
|
|
|
_create_connection_autoconnect ("ac/-1", FALSE, -1),
|
|
|
|
|
_create_connection_autoconnect ("ac/1", FALSE, 1),
|
|
|
|
|
_create_connection_autoconnect ("ac/0", FALSE, 0),
|
|
|
|
|
NULL,
|
|
|
|
|
};
|
|
|
|
|
NMConnection *c2[] = {
|
|
|
|
|
_create_connection_autoconnect ("AC/100", TRUE, 100),
|
|
|
|
|
_create_connection_autoconnect ("AC/99", TRUE, 99),
|
|
|
|
|
_create_connection_autoconnect ("AC/0", TRUE, 0),
|
|
|
|
|
_create_connection_autoconnect ("AC/-1", TRUE, -1),
|
|
|
|
|
_create_connection_autoconnect ("AC/-3", TRUE, -3),
|
|
|
|
|
_create_connection_autoconnect ("ac/0", FALSE, 0),
|
|
|
|
|
NULL,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
_test_connection_sort_autoconnect_priority_one (c1, FALSE);
|
|
|
|
|
_test_connection_sort_autoconnect_priority_one (c2, FALSE);
|
|
|
|
|
_test_connection_sort_autoconnect_priority_one (c1, TRUE);
|
|
|
|
|
_test_connection_sort_autoconnect_priority_one (c2, TRUE);
|
|
|
|
|
|
|
|
|
|
_test_connection_sort_autoconnect_priority_free (c1);
|
|
|
|
|
_test_connection_sort_autoconnect_priority_free (c2);
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-25 17:44:07 -06:00
|
|
|
/*******************************************/
|
|
|
|
|
|
2015-01-26 18:58:20 +01:00
|
|
|
static const char *_test_match_spec_all[] = {
|
|
|
|
|
"e",
|
|
|
|
|
"em",
|
|
|
|
|
"em*",
|
|
|
|
|
"em\\",
|
|
|
|
|
"em\\*",
|
|
|
|
|
"em\\1",
|
|
|
|
|
"em\\11",
|
|
|
|
|
"em\\2",
|
|
|
|
|
"em1",
|
|
|
|
|
"em11",
|
|
|
|
|
"em2",
|
|
|
|
|
"=em*",
|
|
|
|
|
NULL
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
_test_match_spec_contains (const char **matches, const char *match)
|
|
|
|
|
{
|
|
|
|
|
guint i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; matches && matches[i]; i++) {
|
|
|
|
|
if (strcmp (match, matches[i]) == 0)
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2015-01-23 17:02:16 +01:00
|
|
|
test_match_spec_ifname (const char *spec_str, const char **matches, const char **neg_matches)
|
2015-01-26 18:58:20 +01:00
|
|
|
{
|
|
|
|
|
const char *m;
|
|
|
|
|
GSList *specs, *specs_reverse = NULL;
|
|
|
|
|
guint i;
|
|
|
|
|
|
|
|
|
|
g_assert (spec_str);
|
core: add nm_match_spec_split() function
There are currently three device spec properties: 'main.ignore-carrier',
'main.no-auto-default' and 'keyfile.unmanaged-devices'.
The first two, called g_key_file_parse_value_as_string() to split
the string into individual device specs. This uses ',' as separator
and supports escaping using '\\'.
'keyfile.unmanaged-devices' is split using ',' or ';' as separator
without supporting escaping.
Add a new function nm_match_spec_split(), to unify these two behaviors
and support both formats. That is, both previous formats are mostly
supported, but obviously there are some behavioral changes if the string
contains one of '\\', ',', or ';'.
nm_match_spec_split() is copied from glibs g_key_file_parse_value_as_string()
and adjusted.
2015-02-09 16:57:14 +01:00
|
|
|
|
|
|
|
|
specs = nm_match_spec_split (spec_str);
|
|
|
|
|
specs_reverse = g_slist_reverse (g_slist_copy (specs));
|
2015-01-26 18:58:20 +01:00
|
|
|
|
|
|
|
|
for (i = 0; matches && matches[i]; i++) {
|
2015-01-23 17:02:16 +01:00
|
|
|
g_assert (nm_match_spec_interface_name (specs, matches[i]) == NM_MATCH_SPEC_MATCH);
|
|
|
|
|
g_assert (nm_match_spec_interface_name (specs_reverse, matches[i]) == NM_MATCH_SPEC_MATCH);
|
|
|
|
|
}
|
|
|
|
|
for (i = 0; neg_matches && neg_matches[i]; i++) {
|
|
|
|
|
g_assert (nm_match_spec_interface_name (specs, neg_matches[i]) == NM_MATCH_SPEC_NEG_MATCH);
|
|
|
|
|
g_assert (nm_match_spec_interface_name (specs_reverse, neg_matches[i]) == NM_MATCH_SPEC_NEG_MATCH);
|
2015-01-26 18:58:20 +01:00
|
|
|
}
|
|
|
|
|
for (i = 0; (m = _test_match_spec_all[i]); i++) {
|
|
|
|
|
if (_test_match_spec_contains (matches, m))
|
|
|
|
|
continue;
|
2015-01-23 17:02:16 +01:00
|
|
|
if (_test_match_spec_contains (neg_matches, m))
|
|
|
|
|
continue;
|
|
|
|
|
g_assert (nm_match_spec_interface_name (specs, m) == NM_MATCH_SPEC_NO_MATCH);
|
|
|
|
|
g_assert (nm_match_spec_interface_name (specs_reverse, m) == NM_MATCH_SPEC_NO_MATCH);
|
2015-01-26 18:58:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_slist_free (specs_reverse);
|
core: add nm_match_spec_split() function
There are currently three device spec properties: 'main.ignore-carrier',
'main.no-auto-default' and 'keyfile.unmanaged-devices'.
The first two, called g_key_file_parse_value_as_string() to split
the string into individual device specs. This uses ',' as separator
and supports escaping using '\\'.
'keyfile.unmanaged-devices' is split using ',' or ';' as separator
without supporting escaping.
Add a new function nm_match_spec_split(), to unify these two behaviors
and support both formats. That is, both previous formats are mostly
supported, but obviously there are some behavioral changes if the string
contains one of '\\', ',', or ';'.
nm_match_spec_split() is copied from glibs g_key_file_parse_value_as_string()
and adjusted.
2015-02-09 16:57:14 +01:00
|
|
|
g_slist_free_full (specs, g_free);
|
2015-01-26 18:58:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_nm_match_spec_interface_name (void)
|
|
|
|
|
{
|
|
|
|
|
#define S(...) ((const char *[]) { __VA_ARGS__, NULL } )
|
|
|
|
|
test_match_spec_ifname ("em1",
|
2015-01-23 17:02:16 +01:00
|
|
|
S ("em1"),
|
|
|
|
|
NULL);
|
2015-01-26 18:58:20 +01:00
|
|
|
test_match_spec_ifname ("em1,em2",
|
2015-01-23 17:02:16 +01:00
|
|
|
S ("em1", "em2"),
|
|
|
|
|
NULL);
|
2015-01-26 18:58:20 +01:00
|
|
|
test_match_spec_ifname ("em1,em2,interface-name:em2",
|
2015-01-23 17:02:16 +01:00
|
|
|
S ("em1", "em2"),
|
|
|
|
|
NULL);
|
2015-01-26 18:58:20 +01:00
|
|
|
test_match_spec_ifname ("interface-name:em1",
|
2015-01-23 17:02:16 +01:00
|
|
|
S ("em1"),
|
|
|
|
|
NULL);
|
2015-01-26 18:58:20 +01:00
|
|
|
test_match_spec_ifname ("interface-name:em*",
|
2015-01-23 17:02:16 +01:00
|
|
|
S ("em", "em*", "em\\", "em\\*", "em\\1", "em\\11", "em\\2", "em1", "em11", "em2", "em3"),
|
|
|
|
|
NULL);
|
2015-01-26 18:58:20 +01:00
|
|
|
test_match_spec_ifname ("interface-name:em\\*",
|
2015-01-23 17:02:16 +01:00
|
|
|
S ("em\\", "em\\*", "em\\1", "em\\11", "em\\2"),
|
|
|
|
|
NULL);
|
core: rework matching of nm_match_spec()
This includes several changes how to match device specs:
- matching the interface name is no longer case-insenstive as
interface names themselves are case-sensitive.
- Now we skip patterns that start with "mac:" or "s390-subchannels:"
for comparing interface names. Previously a spec "mac:1" would have
matched an interface named "mac:1", now it doesn't.
To match such an interface, you would have to specify
"interface-name:mac:1".
- previously, a pattern "a" would have matched an interface
named "interface-name:a", now it doesn't. Since valid interface
name (in the kernel) can be at most 15 characters long, this is
however no problem.
- if the spec has the prefix "interface-name:", we support
simple globbing using GPatternSpec. Globbing without exact
spec type will still not match "vboxnet*" -- with the exception
of "*".
You can disable globbing by putting an '=' immediately
after the ':'.
(a) "interface-name:em1" | matches "em1"
(b) "interface-name:em*" | matches "em", "em1", "em2", etc.
(c) "interface-name:em\*" | matches "em\", "em\1", etc.
(d) "interface-name:=em*" | matches "em*"
(e) "em*" | matches "em*"
2015-01-23 16:42:58 +01:00
|
|
|
test_match_spec_ifname ("interface-name:~em\\*",
|
2015-01-23 17:02:16 +01:00
|
|
|
S ("em\\", "em\\*", "em\\1", "em\\11", "em\\2"),
|
|
|
|
|
NULL);
|
2015-01-26 18:58:20 +01:00
|
|
|
test_match_spec_ifname ("interface-name:=em*",
|
2015-01-23 17:02:16 +01:00
|
|
|
S ("em*"),
|
|
|
|
|
NULL);
|
|
|
|
|
test_match_spec_ifname ("interface-name:em*,except:interface-name:em1*",
|
|
|
|
|
S ("em", "em*", "em\\", "em\\*", "em\\1", "em\\11", "em\\2", "em2", "em3"),
|
|
|
|
|
S ("em1", "em11"));
|
|
|
|
|
test_match_spec_ifname ("interface-name:em*,except:interface-name:=em*",
|
|
|
|
|
S ("em", "em\\", "em\\*", "em\\1", "em\\11", "em\\2", "em1", "em11", "em2", "em3"),
|
core: rework matching of nm_match_spec()
This includes several changes how to match device specs:
- matching the interface name is no longer case-insenstive as
interface names themselves are case-sensitive.
- Now we skip patterns that start with "mac:" or "s390-subchannels:"
for comparing interface names. Previously a spec "mac:1" would have
matched an interface named "mac:1", now it doesn't.
To match such an interface, you would have to specify
"interface-name:mac:1".
- previously, a pattern "a" would have matched an interface
named "interface-name:a", now it doesn't. Since valid interface
name (in the kernel) can be at most 15 characters long, this is
however no problem.
- if the spec has the prefix "interface-name:", we support
simple globbing using GPatternSpec. Globbing without exact
spec type will still not match "vboxnet*" -- with the exception
of "*".
You can disable globbing by putting an '=' immediately
after the ':'.
(a) "interface-name:em1" | matches "em1"
(b) "interface-name:em*" | matches "em", "em1", "em2", etc.
(c) "interface-name:em\*" | matches "em\", "em\1", etc.
(d) "interface-name:=em*" | matches "em*"
(e) "em*" | matches "em*"
2015-01-23 16:42:58 +01:00
|
|
|
S ("em*"));
|
core: add nm_match_spec_split() function
There are currently three device spec properties: 'main.ignore-carrier',
'main.no-auto-default' and 'keyfile.unmanaged-devices'.
The first two, called g_key_file_parse_value_as_string() to split
the string into individual device specs. This uses ',' as separator
and supports escaping using '\\'.
'keyfile.unmanaged-devices' is split using ',' or ';' as separator
without supporting escaping.
Add a new function nm_match_spec_split(), to unify these two behaviors
and support both formats. That is, both previous formats are mostly
supported, but obviously there are some behavioral changes if the string
contains one of '\\', ',', or ';'.
nm_match_spec_split() is copied from glibs g_key_file_parse_value_as_string()
and adjusted.
2015-02-09 16:57:14 +01:00
|
|
|
test_match_spec_ifname ("aa,bb,cc\\,dd,e,,",
|
|
|
|
|
S ("aa", "bb", "cc,dd", "e"),
|
|
|
|
|
NULL);
|
|
|
|
|
test_match_spec_ifname ("aa;bb;cc\\;dd;e,;",
|
|
|
|
|
S ("aa", "bb", "cc;dd", "e"),
|
|
|
|
|
NULL);
|
|
|
|
|
test_match_spec_ifname ("interface-name:em\\;1,em\\,2,\\,,\\\\,,em\\\\x",
|
|
|
|
|
S ("em;1", "em,2", ",", "\\", "em\\x"),
|
|
|
|
|
NULL);
|
|
|
|
|
test_match_spec_ifname (" , interface-name:a, ,",
|
|
|
|
|
S (" ", " ", " interface-name:a"),
|
|
|
|
|
NULL);
|
2015-01-26 18:58:20 +01:00
|
|
|
#undef S
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************************************/
|
|
|
|
|
|
2014-07-10 10:40:47 +02:00
|
|
|
NMTST_DEFINE ();
|
|
|
|
|
|
2014-01-21 13:07:06 +01:00
|
|
|
int
|
|
|
|
|
main (int argc, char **argv)
|
|
|
|
|
{
|
2014-07-10 10:40:47 +02:00
|
|
|
nmtst_init_with_logging (&argc, &argv, NULL, "ALL");
|
2014-01-21 13:07:06 +01:00
|
|
|
|
2014-02-13 18:12:41 +01:00
|
|
|
g_test_add_func ("/general/nm_utils_ip6_address_clear_host_address", test_nm_utils_ip6_address_clear_host_address);
|
2014-02-26 09:51:09 +01:00
|
|
|
g_test_add_func ("/general/nm_utils_log_connection_diff", test_nm_utils_log_connection_diff);
|
2014-01-21 13:07:06 +01:00
|
|
|
|
2014-02-25 17:44:07 -06:00
|
|
|
g_test_add_func ("/general/connection-match/basic", test_connection_match_basic);
|
|
|
|
|
g_test_add_func ("/general/connection-match/ip6-method", test_connection_match_ip6_method);
|
2014-03-07 10:33:12 +01:00
|
|
|
g_test_add_func ("/general/connection-match/ip6-method-ignore", test_connection_match_ip6_method_ignore);
|
2014-05-29 16:36:24 +02:00
|
|
|
g_test_add_func ("/general/connection-match/ip6-method-ignore-auto", test_connection_match_ip6_method_ignore_auto);
|
2014-02-25 17:56:06 -06:00
|
|
|
g_test_add_func ("/general/connection-match/ip4-method", test_connection_match_ip4_method);
|
2014-03-18 14:21:59 +01:00
|
|
|
g_test_add_func ("/general/connection-match/con-interface-name", test_connection_match_interface_name);
|
2014-04-08 10:39:31 +02:00
|
|
|
g_test_add_func ("/general/connection-match/wired", test_connection_match_wired);
|
2015-02-19 17:53:43 +01:00
|
|
|
g_test_add_func ("/general/connection-match/cloned_mac", test_connection_match_cloned_mac);
|
2014-04-08 10:39:31 +02:00
|
|
|
g_test_add_func ("/general/connection-match/no-match-ip4-addr", test_connection_no_match_ip4_addr);
|
2014-02-25 17:44:07 -06:00
|
|
|
|
2014-08-26 16:06:39 +02:00
|
|
|
g_test_add_func ("/general/connection-sort/autoconnect-priority", test_connection_sort_autoconnect_priority);
|
|
|
|
|
|
2015-01-26 18:58:20 +01:00
|
|
|
g_test_add_func ("/general/nm_match_spec_interface_name", test_nm_match_spec_interface_name);
|
2014-11-27 14:09:03 +01:00
|
|
|
|
2014-01-21 13:07:06 +01:00
|
|
|
return g_test_run ();
|
|
|
|
|
}
|
|
|
|
|
|