2008-11-03 04:13:42 +00:00
|
|
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
2004-06-24 14:18:37 +00:00
|
|
|
/* NetworkManager -- Network link manager
|
|
|
|
|
*
|
|
|
|
|
* 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 of the License, 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.
|
|
|
|
|
*
|
2008-06-26 18:31:52 +00:00
|
|
|
* 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.
|
2004-06-24 14:18:37 +00:00
|
|
|
*
|
2016-03-01 09:56:51 +01:00
|
|
|
* Copyright 2004 - 2016 Red Hat, Inc.
|
2014-09-05 10:55:37 +02:00
|
|
|
* Copyright 2005 - 2008 Novell, Inc.
|
2004-06-24 14:18:37 +00:00
|
|
|
*/
|
|
|
|
|
|
2016-02-19 14:57:48 +01:00
|
|
|
#include "nm-default.h"
|
2014-08-25 16:21:59 +02:00
|
|
|
|
2004-06-24 14:18:37 +00:00
|
|
|
#include "NetworkManagerUtils.h"
|
2016-03-01 09:56:51 +01:00
|
|
|
|
2016-06-01 12:31:36 +02:00
|
|
|
#include "nm-common-macros.h"
|
2005-03-14 Ray Strode <rstrode@redhat.com>
Fourth (probably working) cut at porting to
dbus 0.30 api and new hal. This cut adds
some new logging macros to make debugging
easier.
* dispatcher-daemon/NetworkManagerDispatcher.c:
* info-daemon/NetworkmanagerInfo.c:
* info-daemon/NetworkManagerInfoPassphraseDialog.c:
* info-daemon/NetworkManagerInfoVPN.c:
* src/NetworkManager.c:
* src/NetworkManagerAP.c:
* src/NetworkManagerAPList.c:
* src/NetworkManagerDHCP.c:
* src/NetworkManagerDbus.c:
* src/NetworkManagerDevice.c:
* src/NetworkManagerPolicy.c:
* src/NetworkManagerSystem.c:
* src/NetworkManagerUtils.c:
* src/NetworkManagerWireless.c:
* src/autoip.c:
* src/nm-dbus-nm.c:
* src/backends/NetworkManagerDebian.c:
* src/backends/NetworkManagerGentoo.c:
* src/backends/NetworkManagerRedHat.c:
* src/backends/NetworkManagerSlackware.c:
use new logging macros.
* dispatcher-daemon/NetworkManagerDispatcher.c:
(nmd_dbus_filter): s/dbus_free/g_free/
* info-daemon/Makefile.am: link in utils library.
* info-daemon/NetworkmanagerInfo.c: use new logging
macros.
(nmi_dbus_get_network): don't assume enumerations
are 32-bit.
(nmi_dbus_nmi_message_handler): don't free what
doesn't belong to us.
* libnm_glib/libnm_glib.c:
(libnm_glib_get_nm_status):
(libnm_glib_init): don't free what doesn't
belong to us.
(libnm_glib_dbus): strdup result, so it doesn't get
lost when message is unref'd.
* panel-applet/NMWirelessAppletDbus.c:
(nmwa_dbus_update_devices): s/dbus_free/g_free/
* src/NetworkManager.c:
(nm_monitor_wired_link_state): request initial status
dump of all cards when we start up, instead of relying
on /sys/.../carrier.
(nm_info_handler), (nm_set_up_log_handlers):
log handlers to specify what syslog priorites
the logging macros default to.
* src/NetworkManagerAPList.c:
(nm_ap_list_populate_from_nmi):
s/dbus_free_string_array/g_strfreev/
* src/NetworkManagerDbus.c:
(nm_dbus_get_network_object):
validate d-bus message argument types.
Advance message iterator after reading argument,
prepend instead of append to GSList.
* src/NetworkManagerDevice.c:
(nm_device_probe_wired_link_status):
remove redundant /sys in /sys path. remove wrong
contents == NULL means has carrier assumption.
* src/nm-netlink-monitor.c
(nm_netlink_monitor_request_status): implement
function to ask kernel to dump interface link
status over netlink socket.
* test/*.c: s/dbus_free/g_free/
* utils/nm-utils.h:
(nm_print_backtrace): new macro to print backtrace.
(nm_get_timestamp): new macro to get sub-second precise
unix timestamp.
(nm_info), (nm_debug), (nm_warning), (nm_error):
new logging functions. nm_info just prints,
nm_debug includes timestamp and function,
nm_warning includes function, nm_error includes
backtrace and sigtrap.
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@497 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2005-03-15 05:30:15 +00:00
|
|
|
#include "nm-utils.h"
|
2011-01-13 13:28:52 -06:00
|
|
|
#include "nm-setting-connection.h"
|
|
|
|
|
#include "nm-setting-ip4-config.h"
|
|
|
|
|
#include "nm-setting-ip6-config.h"
|
2016-03-01 09:56:51 +01:00
|
|
|
#include "nm-core-internal.h"
|
2004-06-24 14:18:37 +00:00
|
|
|
|
2016-11-21 00:43:52 +01:00
|
|
|
#include "platform/nm-platform.h"
|
2016-03-01 09:56:51 +01:00
|
|
|
#include "nm-exported-object.h"
|
|
|
|
|
#include "nm-auth-utils.h"
|
2014-08-11 09:37:05 +02:00
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2015-01-14 13:15:24 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
/**
|
|
|
|
|
* nm_utils_get_shared_wifi_permission:
|
|
|
|
|
* @connection: the NMConnection to lookup the permission.
|
|
|
|
|
*
|
|
|
|
|
* Returns: a static string of the wifi-permission (if any) or %NULL.
|
|
|
|
|
*/
|
|
|
|
|
const char *
|
|
|
|
|
nm_utils_get_shared_wifi_permission (NMConnection *connection)
|
2015-01-14 13:15:24 +01:00
|
|
|
{
|
2016-03-01 09:56:51 +01:00
|
|
|
NMSettingWireless *s_wifi;
|
|
|
|
|
NMSettingWirelessSecurity *s_wsec;
|
|
|
|
|
const char *method = NULL;
|
2015-01-14 13:15:24 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
|
|
|
|
|
if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) != 0)
|
|
|
|
|
return NULL; /* Not shared */
|
2015-01-14 13:15:24 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
s_wifi = nm_connection_get_setting_wireless (connection);
|
|
|
|
|
if (s_wifi) {
|
|
|
|
|
s_wsec = nm_connection_get_setting_wireless_security (connection);
|
|
|
|
|
if (s_wsec)
|
|
|
|
|
return NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED;
|
|
|
|
|
else
|
|
|
|
|
return NM_AUTH_PERMISSION_WIFI_SHARE_OPEN;
|
2015-01-14 13:15:24 +01:00
|
|
|
}
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
return NULL;
|
2015-01-14 13:15:24 +01:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2015-01-14 13:15:24 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
static char *
|
|
|
|
|
get_new_connection_name (const GSList *existing,
|
|
|
|
|
const char *preferred,
|
|
|
|
|
const char *fallback_prefix)
|
|
|
|
|
{
|
|
|
|
|
GSList *names = NULL;
|
|
|
|
|
const GSList *iter;
|
|
|
|
|
char *cname = NULL;
|
|
|
|
|
int i = 0;
|
|
|
|
|
gboolean preferred_found = FALSE;
|
2015-01-14 13:15:24 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
g_assert (fallback_prefix);
|
2015-01-14 13:15:24 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
for (iter = existing; iter; iter = g_slist_next (iter)) {
|
|
|
|
|
NMConnection *candidate = NM_CONNECTION (iter->data);
|
|
|
|
|
const char *id;
|
2015-09-24 12:44:20 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
id = nm_connection_get_id (candidate);
|
|
|
|
|
g_assert (id);
|
|
|
|
|
names = g_slist_append (names, (gpointer) id);
|
2015-09-24 12:44:20 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
if (preferred && !preferred_found && (strcmp (preferred, id) == 0))
|
|
|
|
|
preferred_found = TRUE;
|
2015-09-24 12:44:20 +02:00
|
|
|
}
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
/* Return the preferred name if it was unique */
|
|
|
|
|
if (preferred && !preferred_found) {
|
|
|
|
|
g_slist_free (names);
|
|
|
|
|
return g_strdup (preferred);
|
2015-09-24 12:44:20 +02:00
|
|
|
}
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
/* Otherwise find the next available unique connection name using the given
|
|
|
|
|
* connection name template.
|
|
|
|
|
*/
|
|
|
|
|
while (!cname && (i++ < 10000)) {
|
|
|
|
|
char *temp;
|
|
|
|
|
gboolean found = FALSE;
|
2015-07-24 18:54:13 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
/* Translators: the first %s is a prefix for the connection id, such
|
|
|
|
|
* as "Wired Connection" or "VPN Connection". The %d is a number
|
|
|
|
|
* that is combined with the first argument to create a unique
|
|
|
|
|
* connection id. */
|
|
|
|
|
temp = g_strdup_printf (C_("connection id fallback", "%s %d"),
|
|
|
|
|
fallback_prefix, i);
|
|
|
|
|
for (iter = names; iter; iter = g_slist_next (iter)) {
|
|
|
|
|
if (!strcmp (iter->data, temp)) {
|
|
|
|
|
found = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!found)
|
|
|
|
|
cname = temp;
|
|
|
|
|
else
|
|
|
|
|
g_free (temp);
|
|
|
|
|
}
|
2015-07-24 18:54:13 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
g_slist_free (names);
|
|
|
|
|
return cname;
|
2015-07-24 18:54:13 +02:00
|
|
|
}
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
static char *
|
2016-03-08 13:57:20 +01:00
|
|
|
get_new_connection_ifname (NMPlatform *platform,
|
|
|
|
|
const GSList *existing,
|
2016-03-01 09:56:51 +01:00
|
|
|
const char *prefix)
|
2015-07-24 18:54:13 +02:00
|
|
|
{
|
2016-03-01 09:56:51 +01:00
|
|
|
int i;
|
|
|
|
|
char *name;
|
|
|
|
|
const GSList *iter;
|
|
|
|
|
gboolean found;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < 500; i++) {
|
|
|
|
|
name = g_strdup_printf ("%s%d", prefix, i);
|
2015-07-24 18:54:13 +02:00
|
|
|
|
2016-03-08 13:57:20 +01:00
|
|
|
if (nm_platform_link_get_by_ifname (platform, name))
|
2016-03-01 09:56:51 +01:00
|
|
|
goto next;
|
2015-07-24 18:54:13 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
for (iter = existing, found = FALSE; iter; iter = g_slist_next (iter)) {
|
|
|
|
|
NMConnection *candidate = iter->data;
|
2015-07-24 18:54:13 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
if (g_strcmp0 (nm_connection_get_interface_name (candidate), name) == 0) {
|
|
|
|
|
found = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-07-24 18:54:13 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
if (!found)
|
|
|
|
|
return name;
|
2015-07-24 18:54:13 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
next:
|
|
|
|
|
g_free (name);
|
2015-07-24 18:54:13 +02:00
|
|
|
}
|
2016-03-01 09:56:51 +01:00
|
|
|
|
|
|
|
|
return NULL;
|
2015-07-24 18:54:13 +02:00
|
|
|
}
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
const char *
|
|
|
|
|
nm_utils_get_ip_config_method (NMConnection *connection,
|
|
|
|
|
GType ip_setting_type)
|
2015-07-24 18:54:13 +02:00
|
|
|
{
|
2016-03-01 09:56:51 +01:00
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
NMSettingIPConfig *s_ip4, *s_ip6;
|
|
|
|
|
const char *method;
|
2015-07-24 18:54:13 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
s_con = nm_connection_get_setting_connection (connection);
|
2015-07-24 18:54:13 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
if (ip_setting_type == NM_TYPE_SETTING_IP4_CONFIG) {
|
|
|
|
|
g_return_val_if_fail (s_con != NULL, NM_SETTING_IP4_CONFIG_METHOD_AUTO);
|
2015-07-24 18:54:13 +02:00
|
|
|
|
2017-10-23 11:47:25 +02:00
|
|
|
s_ip4 = nm_connection_get_setting_ip4_config (connection);
|
|
|
|
|
if (!s_ip4)
|
2016-03-01 09:56:51 +01:00
|
|
|
return NM_SETTING_IP4_CONFIG_METHOD_DISABLED;
|
2017-10-23 11:47:25 +02:00
|
|
|
method = nm_setting_ip_config_get_method (s_ip4);
|
|
|
|
|
g_return_val_if_fail (method != NULL, NM_SETTING_IP4_CONFIG_METHOD_AUTO);
|
|
|
|
|
|
|
|
|
|
return method;
|
2015-10-01 13:01:39 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
} else if (ip_setting_type == NM_TYPE_SETTING_IP6_CONFIG) {
|
|
|
|
|
g_return_val_if_fail (s_con != NULL, NM_SETTING_IP6_CONFIG_METHOD_AUTO);
|
2015-10-01 13:01:39 +02:00
|
|
|
|
2017-10-23 11:47:25 +02:00
|
|
|
s_ip6 = nm_connection_get_setting_ip6_config (connection);
|
|
|
|
|
if (!s_ip6)
|
2016-03-01 09:56:51 +01:00
|
|
|
return NM_SETTING_IP6_CONFIG_METHOD_IGNORE;
|
2017-10-23 11:47:25 +02:00
|
|
|
method = nm_setting_ip_config_get_method (s_ip6);
|
|
|
|
|
g_return_val_if_fail (method != NULL, NM_SETTING_IP6_CONFIG_METHOD_AUTO);
|
|
|
|
|
|
|
|
|
|
return method;
|
2015-10-01 13:01:39 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
} else
|
|
|
|
|
g_assert_not_reached ();
|
2015-10-01 13:01:39 +02:00
|
|
|
}
|
|
|
|
|
|
2017-08-30 19:17:29 +02:00
|
|
|
gboolean
|
|
|
|
|
nm_utils_connection_has_default_route (NMConnection *connection,
|
|
|
|
|
int addr_family,
|
|
|
|
|
gboolean *out_is_never_default)
|
|
|
|
|
{
|
|
|
|
|
const char *method;
|
|
|
|
|
NMSettingIPConfig *s_ip;
|
|
|
|
|
gboolean is_never_default = FALSE;
|
|
|
|
|
gboolean has_default_route = FALSE;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
|
|
|
|
|
g_return_val_if_fail (NM_IN_SET (addr_family, AF_INET, AF_INET6), FALSE);
|
|
|
|
|
|
|
|
|
|
if (!connection)
|
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
|
|
if (addr_family == AF_INET)
|
|
|
|
|
s_ip = nm_connection_get_setting_ip4_config (connection);
|
|
|
|
|
else
|
|
|
|
|
s_ip = nm_connection_get_setting_ip6_config (connection);
|
|
|
|
|
if (!s_ip)
|
|
|
|
|
goto out;
|
|
|
|
|
if (nm_setting_ip_config_get_never_default (s_ip)) {
|
|
|
|
|
is_never_default = TRUE;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (addr_family == AF_INET) {
|
|
|
|
|
method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG);
|
|
|
|
|
if (NM_IN_STRSET (method, NULL,
|
|
|
|
|
NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
|
|
|
|
|
NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL))
|
|
|
|
|
goto out;
|
|
|
|
|
} else {
|
|
|
|
|
method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
|
|
|
|
if (NM_IN_STRSET (method, NULL,
|
|
|
|
|
NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
|
|
|
|
|
NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL))
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
has_default_route = TRUE;
|
|
|
|
|
out:
|
|
|
|
|
NM_SET_OUT (out_is_never_default, is_never_default);
|
|
|
|
|
return has_default_route;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
void
|
2016-03-08 13:57:20 +01:00
|
|
|
nm_utils_complete_generic (NMPlatform *platform,
|
|
|
|
|
NMConnection *connection,
|
2016-03-01 09:56:51 +01:00
|
|
|
const char *ctype,
|
|
|
|
|
const GSList *existing,
|
|
|
|
|
const char *preferred_id,
|
|
|
|
|
const char *fallback_id_prefix,
|
|
|
|
|
const char *ifname_prefix,
|
|
|
|
|
gboolean default_enable_ipv6)
|
2004-07-06 01:34:10 +00:00
|
|
|
{
|
2016-03-01 09:56:51 +01:00
|
|
|
NMSettingConnection *s_con;
|
2017-02-28 16:05:39 +01:00
|
|
|
char *id, *ifname;
|
2016-03-01 09:56:51 +01:00
|
|
|
GHashTable *parameters;
|
2004-07-06 01:34:10 +00:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
g_assert (fallback_id_prefix);
|
|
|
|
|
|
|
|
|
|
s_con = nm_connection_get_setting_connection (connection);
|
|
|
|
|
if (!s_con) {
|
|
|
|
|
s_con = (NMSettingConnection *) nm_setting_connection_new ();
|
|
|
|
|
nm_connection_add_setting (connection, NM_SETTING (s_con));
|
2015-04-23 12:51:01 +02:00
|
|
|
}
|
2016-03-01 09:56:51 +01:00
|
|
|
g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_TYPE, ctype, NULL);
|
2007-11-15 18:33:17 +00:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
if (!nm_setting_connection_get_uuid (s_con)) {
|
2017-02-28 16:05:39 +01:00
|
|
|
char uuid[37];
|
|
|
|
|
|
|
|
|
|
g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_buf (uuid), NULL);
|
2016-03-01 09:56:51 +01:00
|
|
|
}
|
2007-11-15 18:33:17 +00:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
/* Add a connection ID if absent */
|
|
|
|
|
if (!nm_setting_connection_get_id (s_con)) {
|
|
|
|
|
id = get_new_connection_name (existing, preferred_id, fallback_id_prefix);
|
|
|
|
|
g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_ID, id, NULL);
|
|
|
|
|
g_free (id);
|
|
|
|
|
}
|
2007-11-15 18:33:17 +00:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
/* Add an interface name, if requested */
|
|
|
|
|
if (ifname_prefix && !nm_setting_connection_get_interface_name (s_con)) {
|
2016-03-08 13:57:20 +01:00
|
|
|
ifname = get_new_connection_ifname (platform, existing, ifname_prefix);
|
2016-03-01 09:56:51 +01:00
|
|
|
g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_INTERFACE_NAME, ifname, NULL);
|
|
|
|
|
g_free (ifname);
|
2015-04-23 12:51:01 +02:00
|
|
|
}
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
/* Normalize */
|
2017-10-13 16:12:35 +02:00
|
|
|
parameters = g_hash_table_new (nm_str_hash, g_str_equal);
|
2016-03-01 09:56:51 +01:00
|
|
|
g_hash_table_insert (parameters, NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD,
|
|
|
|
|
default_enable_ipv6 ? NM_SETTING_IP6_CONFIG_METHOD_AUTO : NM_SETTING_IP6_CONFIG_METHOD_IGNORE);
|
|
|
|
|
nm_connection_normalize (connection, parameters, NULL, NULL);
|
|
|
|
|
g_hash_table_destroy (parameters);
|
2004-07-06 01:34:10 +00:00
|
|
|
}
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
/*****************************************************************************/
|
2004-06-24 14:18:37 +00:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
static GHashTable *
|
|
|
|
|
check_property_in_hash (GHashTable *hash,
|
|
|
|
|
const char *s_name,
|
|
|
|
|
const char *p_name)
|
2014-02-13 18:12:41 +01:00
|
|
|
{
|
2016-03-01 09:56:51 +01:00
|
|
|
GHashTable *props;
|
2014-08-28 23:36:45 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
props = g_hash_table_lookup (hash, s_name);
|
|
|
|
|
if ( !props
|
|
|
|
|
|| !g_hash_table_lookup (props, p_name)) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
return props;
|
2014-02-13 18:12:41 +01:00
|
|
|
}
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
static void
|
|
|
|
|
remove_from_hash (GHashTable *s_hash,
|
|
|
|
|
GHashTable *p_hash,
|
|
|
|
|
const char *s_name,
|
|
|
|
|
const char *p_name)
|
2015-03-27 11:55:51 +01:00
|
|
|
{
|
2016-03-01 09:56:51 +01:00
|
|
|
if (!p_hash)
|
2015-03-27 11:55:51 +01:00
|
|
|
return;
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
g_hash_table_remove (p_hash, p_name);
|
|
|
|
|
if (g_hash_table_size (p_hash) == 0)
|
|
|
|
|
g_hash_table_remove (s_hash, s_name);
|
|
|
|
|
}
|
2015-03-27 11:55:51 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
static gboolean
|
|
|
|
|
check_ip6_method (NMConnection *orig,
|
|
|
|
|
NMConnection *candidate,
|
|
|
|
|
GHashTable *settings)
|
|
|
|
|
{
|
|
|
|
|
GHashTable *props;
|
|
|
|
|
const char *orig_ip6_method, *candidate_ip6_method;
|
|
|
|
|
NMSettingIPConfig *candidate_ip6;
|
|
|
|
|
gboolean allow = FALSE;
|
2015-03-27 11:55:51 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
props = check_property_in_hash (settings,
|
|
|
|
|
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
|
|
|
|
NM_SETTING_IP_CONFIG_METHOD);
|
|
|
|
|
if (!props)
|
|
|
|
|
return TRUE;
|
2015-03-27 11:55:51 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
/* If the generated connection is 'link-local' and the candidate is both 'auto'
|
|
|
|
|
* and may-fail=TRUE, then the candidate is OK to use. may-fail is included
|
|
|
|
|
* in the decision because if the candidate is 'auto' but may-fail=FALSE, then
|
|
|
|
|
* the connection could not possibly have been previously activated on the
|
|
|
|
|
* device if the device has no non-link-local IPv6 address.
|
|
|
|
|
*/
|
|
|
|
|
orig_ip6_method = nm_utils_get_ip_config_method (orig, NM_TYPE_SETTING_IP6_CONFIG);
|
|
|
|
|
candidate_ip6_method = nm_utils_get_ip_config_method (candidate, NM_TYPE_SETTING_IP6_CONFIG);
|
|
|
|
|
candidate_ip6 = nm_connection_get_setting_ip6_config (candidate);
|
2015-03-27 11:55:51 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
if ( strcmp (orig_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0
|
|
|
|
|
&& strcmp (candidate_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0
|
|
|
|
|
&& (!candidate_ip6 || nm_setting_ip_config_get_may_fail (candidate_ip6))) {
|
|
|
|
|
allow = TRUE;
|
2015-03-27 11:55:51 +01:00
|
|
|
}
|
2014-02-13 18:12:41 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
/* If the generated connection method is 'link-local' or 'auto' and the candidate
|
|
|
|
|
* method is 'ignore' we can take the connection, because NM didn't simply take care
|
|
|
|
|
* of IPv6.
|
|
|
|
|
*/
|
|
|
|
|
if ( ( strcmp (orig_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0
|
|
|
|
|
|| strcmp (orig_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0)
|
|
|
|
|
&& strcmp (candidate_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) {
|
|
|
|
|
allow = TRUE;
|
2008-04-27 12:23:17 +00:00
|
|
|
}
|
2004-10-28 19:49:55 +00:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
if (allow) {
|
|
|
|
|
remove_from_hash (settings, props,
|
|
|
|
|
NM_SETTING_IP6_CONFIG_SETTING_NAME,
|
|
|
|
|
NM_SETTING_IP_CONFIG_METHOD);
|
2008-04-27 12:23:17 +00:00
|
|
|
}
|
2016-03-01 09:56:51 +01:00
|
|
|
return allow;
|
2015-01-09 11:25:06 +01:00
|
|
|
}
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
static int
|
|
|
|
|
route_compare (NMIPRoute *route1, NMIPRoute *route2, gint64 default_metric)
|
2014-10-01 15:01:13 +02:00
|
|
|
{
|
2016-03-01 09:56:51 +01:00
|
|
|
gint64 r, metric1, metric2;
|
2017-04-13 19:15:02 +02:00
|
|
|
int family;
|
|
|
|
|
guint plen;
|
|
|
|
|
NMIPAddr a1 = { 0 }, a2 = { 0 };
|
2015-06-30 14:51:42 +02:00
|
|
|
|
2017-04-13 19:15:02 +02:00
|
|
|
family = nm_ip_route_get_family (route1);
|
|
|
|
|
r = family - nm_ip_route_get_family (route2);
|
2016-03-01 09:56:51 +01:00
|
|
|
if (r)
|
|
|
|
|
return r > 0 ? 1 : -1;
|
2015-06-30 12:28:29 +02:00
|
|
|
|
2017-04-13 19:15:02 +02:00
|
|
|
plen = nm_ip_route_get_prefix (route1);
|
|
|
|
|
r = plen - nm_ip_route_get_prefix (route2);
|
2016-03-01 09:56:51 +01:00
|
|
|
if (r)
|
2017-04-13 19:15:02 +02:00
|
|
|
return r > 0 ? 1 : -1;
|
2014-10-01 15:01:13 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
metric1 = nm_ip_route_get_metric (route1) == -1 ? default_metric : nm_ip_route_get_metric (route1);
|
|
|
|
|
metric2 = nm_ip_route_get_metric (route2) == -1 ? default_metric : nm_ip_route_get_metric (route2);
|
2014-02-14 12:54:36 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
r = metric1 - metric2;
|
|
|
|
|
if (r)
|
|
|
|
|
return r > 0 ? 1 : -1;
|
2014-02-14 12:54:36 +01:00
|
|
|
|
2017-04-13 19:15:02 +02:00
|
|
|
r = g_strcmp0 (nm_ip_route_get_next_hop (route1), nm_ip_route_get_next_hop (route2));
|
2016-03-01 09:56:51 +01:00
|
|
|
if (r)
|
2017-04-13 19:15:02 +02:00
|
|
|
return r;
|
|
|
|
|
|
|
|
|
|
/* NMIPRoute validates family and dest. inet_pton() is not expected to fail. */
|
|
|
|
|
inet_pton (family, nm_ip_route_get_dest (route1), &a1);
|
|
|
|
|
inet_pton (family, nm_ip_route_get_dest (route2), &a2);
|
|
|
|
|
nm_utils_ipx_address_clear_host_address (family, &a1, &a1, plen);
|
|
|
|
|
nm_utils_ipx_address_clear_host_address (family, &a2, &a2, plen);
|
|
|
|
|
r = memcmp (&a1, &a2, sizeof (a1));
|
|
|
|
|
if (r)
|
|
|
|
|
return r;
|
2014-02-14 12:54:36 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
return 0;
|
2014-02-14 12:54:36 +01:00
|
|
|
}
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
static int
|
2017-03-16 17:42:30 +01:00
|
|
|
route_ptr_compare (const void *a, const void *b, gpointer metric)
|
2014-02-14 12:54:36 +01:00
|
|
|
{
|
2017-03-16 17:42:30 +01:00
|
|
|
return route_compare (*(NMIPRoute **) a, *(NMIPRoute **) b, *((gint64 *) metric));
|
2014-02-14 12:54:36 +01:00
|
|
|
}
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
static gboolean
|
|
|
|
|
check_ip_routes (NMConnection *orig,
|
|
|
|
|
NMConnection *candidate,
|
|
|
|
|
GHashTable *settings,
|
|
|
|
|
gint64 default_metric,
|
|
|
|
|
gboolean v4)
|
2014-02-14 12:54:36 +01:00
|
|
|
{
|
2017-09-01 09:14:13 +02:00
|
|
|
gs_free NMIPRoute **routes1 = NULL;
|
|
|
|
|
NMIPRoute **routes2;
|
2016-03-01 09:56:51 +01:00
|
|
|
NMSettingIPConfig *s_ip1, *s_ip2;
|
2017-03-16 17:42:30 +01:00
|
|
|
gint64 m;
|
2016-03-01 09:56:51 +01:00
|
|
|
const char *s_name;
|
|
|
|
|
GHashTable *props;
|
2017-09-01 09:14:13 +02:00
|
|
|
guint i, i1, i2, num1, num2;
|
|
|
|
|
const guint8 PLEN = v4 ? 32 : 128;
|
2014-02-14 12:54:36 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
s_name = v4 ? NM_SETTING_IP4_CONFIG_SETTING_NAME :
|
|
|
|
|
NM_SETTING_IP6_CONFIG_SETTING_NAME;
|
2014-02-14 12:54:36 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
props = check_property_in_hash (settings,
|
|
|
|
|
s_name,
|
|
|
|
|
NM_SETTING_IP_CONFIG_ROUTES);
|
|
|
|
|
if (!props)
|
|
|
|
|
return TRUE;
|
2014-02-14 12:54:36 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
s_ip1 = (NMSettingIPConfig *) nm_connection_get_setting_by_name (orig, s_name);
|
|
|
|
|
s_ip2 = (NMSettingIPConfig *) nm_connection_get_setting_by_name (candidate, s_name);
|
2014-02-14 12:54:36 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
if (!s_ip1 || !s_ip2)
|
|
|
|
|
return FALSE;
|
2014-02-14 12:54:36 +01:00
|
|
|
|
2017-09-01 09:14:13 +02:00
|
|
|
num1 = nm_setting_ip_config_get_num_routes (s_ip1);
|
|
|
|
|
num2 = nm_setting_ip_config_get_num_routes (s_ip2);
|
2014-02-14 12:54:36 +01:00
|
|
|
|
2017-09-01 09:14:13 +02:00
|
|
|
routes1 = g_new (NMIPRoute *, (gsize) num1 + num2);
|
|
|
|
|
routes2 = &routes1[num1];
|
2014-02-14 12:54:36 +01:00
|
|
|
|
2017-09-01 09:14:13 +02:00
|
|
|
for (i = 0; i < num1; i++)
|
2016-03-01 09:56:51 +01:00
|
|
|
routes1[i] = nm_setting_ip_config_get_route (s_ip1, i);
|
2017-09-01 09:14:13 +02:00
|
|
|
for (i = 0; i < num2; i++)
|
2016-03-01 09:56:51 +01:00
|
|
|
routes2[i] = nm_setting_ip_config_get_route (s_ip2, i);
|
2014-02-14 12:54:36 +01:00
|
|
|
|
2017-03-16 17:42:30 +01:00
|
|
|
m = nm_setting_ip_config_get_route_metric (s_ip2);
|
|
|
|
|
if (m != -1)
|
|
|
|
|
default_metric = m;
|
|
|
|
|
|
2017-09-01 09:14:13 +02:00
|
|
|
g_qsort_with_data (routes1, num1, sizeof (NMIPRoute *), route_ptr_compare, &default_metric);
|
|
|
|
|
g_qsort_with_data (routes2, num2, sizeof (NMIPRoute *), route_ptr_compare, &default_metric);
|
|
|
|
|
|
|
|
|
|
for (i1 = 0, i2 = 0; i2 < num2; i1++) {
|
|
|
|
|
if (i1 >= num1)
|
|
|
|
|
return FALSE;
|
|
|
|
|
if (route_compare (routes1[i1], routes2[i2], default_metric) == 0) {
|
|
|
|
|
i2++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* if @orig (@routes1) contains /32 routes that are missing in @candidate,
|
|
|
|
|
* we accept that.
|
|
|
|
|
*
|
|
|
|
|
* A /32 may have been added automatically, as a direct-route to the gateway.
|
|
|
|
|
* The generated connection (@orig) would contain that route, so we shall ignore
|
|
|
|
|
* it.
|
|
|
|
|
*
|
|
|
|
|
* Likeweise for /128 for IPv6. */
|
|
|
|
|
if (nm_ip_route_get_prefix (routes1[i1]) == PLEN)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2014-02-14 12:54:36 +01:00
|
|
|
|
2017-09-01 09:14:13 +02:00
|
|
|
/* check that @orig has no left-over (except host routes that we ignore). */
|
|
|
|
|
for (; i1 < num1; i1++) {
|
|
|
|
|
if (nm_ip_route_get_prefix (routes1[i1]) != PLEN)
|
2016-03-01 09:56:51 +01:00
|
|
|
return FALSE;
|
2014-02-14 12:54:36 +01:00
|
|
|
}
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
remove_from_hash (settings, props, s_name, NM_SETTING_IP_CONFIG_ROUTES);
|
|
|
|
|
return TRUE;
|
2014-02-14 12:54:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2016-03-01 09:56:51 +01:00
|
|
|
check_ip4_method (NMConnection *orig,
|
|
|
|
|
NMConnection *candidate,
|
|
|
|
|
GHashTable *settings,
|
|
|
|
|
gboolean device_has_carrier)
|
2014-02-14 12:54:36 +01:00
|
|
|
{
|
2016-03-01 09:56:51 +01:00
|
|
|
GHashTable *props;
|
|
|
|
|
const char *orig_ip4_method, *candidate_ip4_method;
|
|
|
|
|
NMSettingIPConfig *candidate_ip4;
|
2014-02-14 12:54:36 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
props = check_property_in_hash (settings,
|
|
|
|
|
NM_SETTING_IP4_CONFIG_SETTING_NAME,
|
|
|
|
|
NM_SETTING_IP_CONFIG_METHOD);
|
|
|
|
|
if (!props)
|
|
|
|
|
return TRUE;
|
2014-02-14 12:54:36 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
/* If the generated connection is 'disabled' (device had no IP addresses)
|
|
|
|
|
* but it has no carrier, that most likely means that IP addressing could
|
|
|
|
|
* not complete and thus no IP addresses were assigned. In that case, allow
|
|
|
|
|
* matching to the "auto" method.
|
|
|
|
|
*/
|
|
|
|
|
orig_ip4_method = nm_utils_get_ip_config_method (orig, NM_TYPE_SETTING_IP4_CONFIG);
|
|
|
|
|
candidate_ip4_method = nm_utils_get_ip_config_method (candidate, NM_TYPE_SETTING_IP4_CONFIG);
|
|
|
|
|
candidate_ip4 = nm_connection_get_setting_ip4_config (candidate);
|
2014-12-04 18:05:24 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
if ( strcmp (orig_ip4_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0
|
|
|
|
|
&& strcmp (candidate_ip4_method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0
|
|
|
|
|
&& (!candidate_ip4 || nm_setting_ip_config_get_may_fail (candidate_ip4))
|
|
|
|
|
&& (device_has_carrier == FALSE)) {
|
|
|
|
|
remove_from_hash (settings, props,
|
|
|
|
|
NM_SETTING_IP4_CONFIG_SETTING_NAME,
|
|
|
|
|
NM_SETTING_IP_CONFIG_METHOD);
|
|
|
|
|
return TRUE;
|
2014-12-04 18:05:24 +01:00
|
|
|
}
|
2016-03-01 09:56:51 +01:00
|
|
|
return FALSE;
|
2014-12-04 18:05:24 +01:00
|
|
|
}
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
static gboolean
|
|
|
|
|
check_connection_interface_name (NMConnection *orig,
|
|
|
|
|
NMConnection *candidate,
|
|
|
|
|
GHashTable *settings)
|
2014-02-14 12:54:36 +01:00
|
|
|
{
|
2016-03-01 09:56:51 +01:00
|
|
|
GHashTable *props;
|
|
|
|
|
const char *orig_ifname, *cand_ifname;
|
|
|
|
|
NMSettingConnection *s_con_orig, *s_con_cand;
|
2014-02-14 12:54:36 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
props = check_property_in_hash (settings,
|
|
|
|
|
NM_SETTING_CONNECTION_SETTING_NAME,
|
|
|
|
|
NM_SETTING_CONNECTION_INTERFACE_NAME);
|
|
|
|
|
if (!props)
|
|
|
|
|
return TRUE;
|
2014-02-14 12:54:36 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
/* If one of the interface names is NULL, we accept that connection */
|
|
|
|
|
s_con_orig = nm_connection_get_setting_connection (orig);
|
|
|
|
|
s_con_cand = nm_connection_get_setting_connection (candidate);
|
|
|
|
|
orig_ifname = nm_setting_connection_get_interface_name (s_con_orig);
|
|
|
|
|
cand_ifname = nm_setting_connection_get_interface_name (s_con_cand);
|
2014-02-14 12:54:36 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
if (!orig_ifname || !cand_ifname) {
|
|
|
|
|
remove_from_hash (settings, props,
|
|
|
|
|
NM_SETTING_CONNECTION_SETTING_NAME,
|
|
|
|
|
NM_SETTING_CONNECTION_INTERFACE_NAME);
|
|
|
|
|
return TRUE;
|
2014-02-14 12:54:36 +01:00
|
|
|
}
|
2016-03-01 09:56:51 +01:00
|
|
|
return FALSE;
|
2014-02-14 12:54:36 +01:00
|
|
|
}
|
2014-10-01 16:15:52 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
static gboolean
|
|
|
|
|
check_connection_mac_address (NMConnection *orig,
|
|
|
|
|
NMConnection *candidate,
|
|
|
|
|
GHashTable *settings)
|
2014-10-01 16:15:52 +02:00
|
|
|
{
|
2016-03-01 09:56:51 +01:00
|
|
|
GHashTable *props;
|
|
|
|
|
const char *orig_mac = NULL, *cand_mac = NULL;
|
|
|
|
|
NMSettingWired *s_wired_orig, *s_wired_cand;
|
2014-03-04 17:01:10 -05:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
props = check_property_in_hash (settings,
|
|
|
|
|
NM_SETTING_WIRED_SETTING_NAME,
|
|
|
|
|
NM_SETTING_WIRED_MAC_ADDRESS);
|
|
|
|
|
if (!props)
|
|
|
|
|
return TRUE;
|
2014-03-12 12:06:20 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
/* If one of the MAC addresses is NULL, we accept that connection */
|
|
|
|
|
s_wired_orig = nm_connection_get_setting_wired (orig);
|
|
|
|
|
if (s_wired_orig)
|
|
|
|
|
orig_mac = nm_setting_wired_get_mac_address (s_wired_orig);
|
2014-03-12 12:06:20 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
s_wired_cand = nm_connection_get_setting_wired (candidate);
|
|
|
|
|
if (s_wired_cand)
|
|
|
|
|
cand_mac = nm_setting_wired_get_mac_address (s_wired_cand);
|
2014-03-12 12:06:20 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
if (!orig_mac || !cand_mac) {
|
|
|
|
|
remove_from_hash (settings, props,
|
|
|
|
|
NM_SETTING_WIRED_SETTING_NAME,
|
|
|
|
|
NM_SETTING_WIRED_MAC_ADDRESS);
|
|
|
|
|
return TRUE;
|
2014-03-12 12:06:20 +01:00
|
|
|
}
|
2016-03-01 09:56:51 +01:00
|
|
|
return FALSE;
|
2015-08-06 17:06:42 +02:00
|
|
|
}
|
|
|
|
|
|
2016-09-21 17:07:42 +02:00
|
|
|
static gboolean
|
|
|
|
|
check_connection_infiniband_mac_address (NMConnection *orig,
|
|
|
|
|
NMConnection *candidate,
|
|
|
|
|
GHashTable *settings)
|
|
|
|
|
{
|
|
|
|
|
GHashTable *props;
|
|
|
|
|
const char *orig_mac = NULL, *cand_mac = NULL;
|
|
|
|
|
NMSettingInfiniband *s_infiniband_orig, *s_infiniband_cand;
|
|
|
|
|
|
|
|
|
|
props = check_property_in_hash (settings,
|
|
|
|
|
NM_SETTING_INFINIBAND_SETTING_NAME,
|
|
|
|
|
NM_SETTING_INFINIBAND_MAC_ADDRESS);
|
|
|
|
|
if (!props)
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
|
|
/* If one of the MAC addresses is NULL, we accept that connection */
|
|
|
|
|
s_infiniband_orig = nm_connection_get_setting_infiniband (orig);
|
|
|
|
|
if (s_infiniband_orig)
|
|
|
|
|
orig_mac = nm_setting_infiniband_get_mac_address (s_infiniband_orig);
|
|
|
|
|
|
|
|
|
|
s_infiniband_cand = nm_connection_get_setting_infiniband (candidate);
|
|
|
|
|
if (s_infiniband_cand)
|
|
|
|
|
cand_mac = nm_setting_infiniband_get_mac_address (s_infiniband_cand);
|
|
|
|
|
|
|
|
|
|
if (!orig_mac || !cand_mac) {
|
|
|
|
|
remove_from_hash (settings, props,
|
|
|
|
|
NM_SETTING_INFINIBAND_SETTING_NAME,
|
|
|
|
|
NM_SETTING_INFINIBAND_MAC_ADDRESS);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
static gboolean
|
|
|
|
|
check_connection_cloned_mac_address (NMConnection *orig,
|
device: extend MAC address handling including randomization for ethernet and wifi
Extend the "ethernet.cloned-mac-address" and "wifi.cloned-mac-address"
settings. Instead of specifying an explicit MAC address, the additional
special values "permanent", "preserve", "random", "random-bia", "stable" and
"stable-bia" are supported.
"permanent" means to use the permanent hardware address. Previously that
was the default if no explict cloned-mac-address was set. The default is
thus still "permanent", but it can be overwritten by global
configuration.
"preserve" means not to configure the MAC address when activating the
device. That was actually the default behavior before introducing MAC
address handling with commit 1b49f941a69af910b0e68530be7339e8053068e5.
"random" and "random-bia" use a randomized MAC address for each
connection. "stable" and "stable-bia" use a generated, stable
address based on some token. The "bia" suffix says to generate a
burned-in address. The stable method by default uses as token the
connection UUID, but the token can be explicitly choosen via
"stable:<TOKEN>" and "stable-bia:<TOKEN>".
On a D-Bus level, the "cloned-mac-address" is a bytestring and thus
cannot express the new forms. It is replaced by the new
"assigned-mac-address" field. For the GObject property, libnm's API,
nmcli, keyfile, etc. the old name "cloned-mac-address" is still used.
Deprecating the old field seems more complicated then just extending
the use of the existing "cloned-mac-address" field, although the name
doesn't match well with the extended meaning.
There is some overlap with the "wifi.mac-address-randomization" setting.
https://bugzilla.gnome.org/show_bug.cgi?id=705545
https://bugzilla.gnome.org/show_bug.cgi?id=708820
https://bugzilla.gnome.org/show_bug.cgi?id=758301
2016-05-24 15:57:16 +02:00
|
|
|
NMConnection *candidate,
|
|
|
|
|
GHashTable *settings)
|
2015-08-06 17:06:42 +02:00
|
|
|
{
|
2016-03-01 09:56:51 +01:00
|
|
|
GHashTable *props;
|
|
|
|
|
const char *orig_mac = NULL, *cand_mac = NULL;
|
|
|
|
|
NMSettingWired *s_wired_orig, *s_wired_cand;
|
2014-03-12 12:06:20 +01:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
props = check_property_in_hash (settings,
|
|
|
|
|
NM_SETTING_WIRED_SETTING_NAME,
|
|
|
|
|
NM_SETTING_WIRED_CLONED_MAC_ADDRESS);
|
|
|
|
|
if (!props)
|
2014-06-30 13:55:04 +02:00
|
|
|
return TRUE;
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
/* If one of the MAC addresses is NULL, we accept that connection */
|
|
|
|
|
s_wired_orig = nm_connection_get_setting_wired (orig);
|
|
|
|
|
if (s_wired_orig)
|
|
|
|
|
orig_mac = nm_setting_wired_get_cloned_mac_address (s_wired_orig);
|
2014-04-10 15:29:45 -05:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
s_wired_cand = nm_connection_get_setting_wired (candidate);
|
|
|
|
|
if (s_wired_cand)
|
|
|
|
|
cand_mac = nm_setting_wired_get_cloned_mac_address (s_wired_cand);
|
2014-04-10 15:29:45 -05:00
|
|
|
|
2017-05-05 14:11:05 +02:00
|
|
|
/* special cloned mac address entries are accepted. */
|
device: extend MAC address handling including randomization for ethernet and wifi
Extend the "ethernet.cloned-mac-address" and "wifi.cloned-mac-address"
settings. Instead of specifying an explicit MAC address, the additional
special values "permanent", "preserve", "random", "random-bia", "stable" and
"stable-bia" are supported.
"permanent" means to use the permanent hardware address. Previously that
was the default if no explict cloned-mac-address was set. The default is
thus still "permanent", but it can be overwritten by global
configuration.
"preserve" means not to configure the MAC address when activating the
device. That was actually the default behavior before introducing MAC
address handling with commit 1b49f941a69af910b0e68530be7339e8053068e5.
"random" and "random-bia" use a randomized MAC address for each
connection. "stable" and "stable-bia" use a generated, stable
address based on some token. The "bia" suffix says to generate a
burned-in address. The stable method by default uses as token the
connection UUID, but the token can be explicitly choosen via
"stable:<TOKEN>" and "stable-bia:<TOKEN>".
On a D-Bus level, the "cloned-mac-address" is a bytestring and thus
cannot express the new forms. It is replaced by the new
"assigned-mac-address" field. For the GObject property, libnm's API,
nmcli, keyfile, etc. the old name "cloned-mac-address" is still used.
Deprecating the old field seems more complicated then just extending
the use of the existing "cloned-mac-address" field, although the name
doesn't match well with the extended meaning.
There is some overlap with the "wifi.mac-address-randomization" setting.
https://bugzilla.gnome.org/show_bug.cgi?id=705545
https://bugzilla.gnome.org/show_bug.cgi?id=708820
https://bugzilla.gnome.org/show_bug.cgi?id=758301
2016-05-24 15:57:16 +02:00
|
|
|
if (NM_CLONED_MAC_IS_SPECIAL (orig_mac))
|
|
|
|
|
orig_mac = NULL;
|
|
|
|
|
if (NM_CLONED_MAC_IS_SPECIAL (cand_mac))
|
|
|
|
|
cand_mac = NULL;
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
if (!orig_mac || !cand_mac) {
|
|
|
|
|
remove_from_hash (settings, props,
|
|
|
|
|
NM_SETTING_WIRED_SETTING_NAME,
|
|
|
|
|
NM_SETTING_WIRED_CLONED_MAC_ADDRESS);
|
|
|
|
|
return TRUE;
|
2014-04-10 15:29:45 -05:00
|
|
|
}
|
2016-03-01 09:56:51 +01:00
|
|
|
return FALSE;
|
2014-04-10 15:29:45 -05:00
|
|
|
}
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
static gboolean
|
|
|
|
|
check_connection_s390_props (NMConnection *orig,
|
|
|
|
|
NMConnection *candidate,
|
|
|
|
|
GHashTable *settings)
|
2014-04-10 15:29:45 -05:00
|
|
|
{
|
2016-03-01 09:56:51 +01:00
|
|
|
GHashTable *props1, *props2, *props3;
|
|
|
|
|
NMSettingWired *s_wired_orig, *s_wired_cand;
|
|
|
|
|
|
|
|
|
|
props1 = check_property_in_hash (settings,
|
|
|
|
|
NM_SETTING_WIRED_SETTING_NAME,
|
|
|
|
|
NM_SETTING_WIRED_S390_SUBCHANNELS);
|
|
|
|
|
props2 = check_property_in_hash (settings,
|
|
|
|
|
NM_SETTING_WIRED_SETTING_NAME,
|
|
|
|
|
NM_SETTING_WIRED_S390_NETTYPE);
|
|
|
|
|
props3 = check_property_in_hash (settings,
|
|
|
|
|
NM_SETTING_WIRED_SETTING_NAME,
|
|
|
|
|
NM_SETTING_WIRED_S390_OPTIONS);
|
|
|
|
|
if (!props1 && !props2 && !props3)
|
2014-04-10 15:29:45 -05:00
|
|
|
return TRUE;
|
2016-03-01 09:56:51 +01:00
|
|
|
|
|
|
|
|
/* If the generated connection did not contain wired setting,
|
|
|
|
|
* allow it to match to a connection with a wired setting,
|
|
|
|
|
* but default (empty) s390-* properties */
|
|
|
|
|
s_wired_orig = nm_connection_get_setting_wired (orig);
|
|
|
|
|
s_wired_cand = nm_connection_get_setting_wired (candidate);
|
|
|
|
|
if (!s_wired_orig && s_wired_cand) {
|
|
|
|
|
const char * const *subchans = nm_setting_wired_get_s390_subchannels (s_wired_cand);
|
|
|
|
|
const char *nettype = nm_setting_wired_get_s390_nettype (s_wired_cand);
|
|
|
|
|
guint32 num_options = nm_setting_wired_get_num_s390_options (s_wired_cand);
|
|
|
|
|
|
|
|
|
|
if ((!subchans || !*subchans) && !nettype && num_options == 0) {
|
|
|
|
|
remove_from_hash (settings, props1,
|
|
|
|
|
NM_SETTING_WIRED_SETTING_NAME,
|
|
|
|
|
NM_SETTING_WIRED_S390_SUBCHANNELS);
|
|
|
|
|
remove_from_hash (settings, props2,
|
|
|
|
|
NM_SETTING_WIRED_SETTING_NAME,
|
|
|
|
|
NM_SETTING_WIRED_S390_NETTYPE);
|
|
|
|
|
remove_from_hash (settings, props3,
|
|
|
|
|
NM_SETTING_WIRED_SETTING_NAME,
|
|
|
|
|
NM_SETTING_WIRED_S390_OPTIONS);
|
2014-04-10 15:29:45 -05:00
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
static NMConnection *
|
|
|
|
|
check_possible_match (NMConnection *orig,
|
|
|
|
|
NMConnection *candidate,
|
|
|
|
|
GHashTable *settings,
|
|
|
|
|
gboolean device_has_carrier,
|
|
|
|
|
gint64 default_v4_metric,
|
|
|
|
|
gint64 default_v6_metric)
|
2014-04-10 15:29:45 -05:00
|
|
|
{
|
2016-03-01 09:56:51 +01:00
|
|
|
g_return_val_if_fail (settings != NULL, NULL);
|
2014-04-10 15:29:45 -05:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
if (!check_ip6_method (orig, candidate, settings))
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
if (!check_ip4_method (orig, candidate, settings, device_has_carrier))
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
if (!check_ip_routes (orig, candidate, settings, default_v4_metric, TRUE))
|
|
|
|
|
return NULL;
|
2015-10-03 19:44:27 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
if (!check_ip_routes (orig, candidate, settings, default_v6_metric, FALSE))
|
|
|
|
|
return NULL;
|
2015-10-03 19:44:27 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
if (!check_connection_interface_name (orig, candidate, settings))
|
|
|
|
|
return NULL;
|
2015-10-03 19:44:27 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
if (!check_connection_mac_address (orig, candidate, settings))
|
|
|
|
|
return NULL;
|
2015-10-03 19:44:27 +02:00
|
|
|
|
2016-09-21 17:07:42 +02:00
|
|
|
if (!check_connection_infiniband_mac_address (orig, candidate, settings))
|
|
|
|
|
return NULL;
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
if (!check_connection_cloned_mac_address (orig, candidate, settings))
|
|
|
|
|
return NULL;
|
2015-10-03 19:44:27 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
if (!check_connection_s390_props (orig, candidate, settings))
|
|
|
|
|
return NULL;
|
2015-10-03 19:44:27 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
if (g_hash_table_size (settings) == 0)
|
|
|
|
|
return candidate;
|
|
|
|
|
else
|
|
|
|
|
return NULL;
|
2015-10-03 19:44:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2016-03-01 09:56:51 +01:00
|
|
|
* nm_utils_match_connection:
|
|
|
|
|
* @connections: a (optionally pre-sorted) list of connections from which to
|
|
|
|
|
* find a matching connection to @original based on "inferrable" properties
|
|
|
|
|
* @original: the #NMConnection to find a match for from @connections
|
Revert "core: merge branch 'bg/restart-assume-rh1551958'"
This reverts commit cc1920d71470042c4e0837848da9183526b663d0, reversing
changes made to eb8257dea5802a004af9cccacb30af98440e2172.
This breaks restart, at least for Wi-Fi devices:
#0 0x00007ffff5ee8771 in _g_log_abort (breakpoint=breakpoint@entry=1) at gmessages.c:554
#1 0x00007ffff5ee9a5b in g_logv (log_domain=0x7ffff671a738 "GLib-GIO", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fffffffd720) at gmessages.c:1362
#2 0x00007ffff5ee9baf in g_log (log_domain=log_domain@entry=0x7ffff671a738 "GLib-GIO", log_level=log_level@entry=G_LOG_LEVEL_CRITICAL, format=format@entry=0x7ffff5f347ea "%s: assertion '%s' failed") at gmessages.c:1403
#3 0x00007ffff5eea0f9 in g_return_if_fail_warning (log_domain=log_domain@entry=0x7ffff671a738 "GLib-GIO", pretty_function=pretty_function@entry=0x7ffff673fc10 <__func__.25628> "g_dbus_proxy_call_internal", expression=expression@entry=0x7ffff673fb1c "G_IS_DBUS_PROXY (proxy)") at gmessages.c:2702
#4 0x00007ffff66cdc5f in g_dbus_proxy_call_internal (proxy=0x0, method_name=method_name@entry=0x555555810510 "Scan", parameters=0x555555c7a530, flags=flags@entry=G_DBUS_CALL_FLAGS_NONE, timeout_msec=timeout_msec@entry=-1, fd_list=fd_list@entry=0x0, cancellable=0x0, callback=0x55555574cb96 <scan_request_cb>, user_data=0x555555ac2220) at gdbusproxy.c:2664
#5 0x00007ffff66cf686 in g_dbus_proxy_call (proxy=<optimized out>, method_name=method_name@entry=0x555555810510 "Scan", parameters=<optimized out>, flags=flags@entry=G_DBUS_CALL_FLAGS_NONE, timeout_msec=timeout_msec@entry=-1, cancellable=cancellable@entry=0x0, callback=0x55555574cb96 <scan_request_cb>, user_data=0x555555ac2220) at gdbusproxy.c:2970
#6 0x000055555574e026 in nm_supplicant_interface_request_scan (self=0x555555ac2220 [NMSupplicantInterface], ssids=ssids@entry=0x0) at src/supplicant/nm-supplicant-interface.c:1821
#7 0x00007fffe1038276 in request_wireless_scan (self=self@entry=0x555555c6ee60 [NMDeviceWifi], periodic=periodic@entry=0, force_if_scanning=force_if_scanning@entry=0, ssids=<optimized out>, ssids@entry=0x0) at src/devices/wifi/nm-device-wifi.c:1347
#8 0x00007fffe1039011 in device_state_changed (device=0x555555c6ee60 [NMDeviceWifi], new_state=NM_DEVICE_STATE_DISCONNECTED, old_state=<optimized out>, reason=<optimized out>)
at src/devices/wifi/nm-device-wifi.c:2998
#9 0x00007ffff432ed1e in ffi_call_unix64 () at ../src/x86/unix64.S:76
#10 0x00007ffff432e68f in ffi_call (cif=cif@entry=0x7fffffffdc70, fn=fn@entry=0x7fffe1038e1e <device_state_changed>, rvalue=<optimized out>, avalue=avalue@entry=0x7fffffffdb60)
at ../src/x86/ffi64.c:525
#15 0x00007ffff63db66f in <emit signal ??? on instance 0x555555c6ee60 [NMDeviceWifi]> (instance=instance@entry=0x555555c6ee60, signal_id=<optimized out>, detail=detail@entry=0)
at gsignal.c:3447
#11 0x00007ffff63bff39 in g_cclosure_marshal_generic (closure=0x555555c22ea0, return_gvalue=0x0, n_param_values=<optimized out>, param_values=<optimized out>, invocation_hint=<optimized out>, marshal_data=<optimized out>) at gclosure.c:1490
#12 0x00007ffff63bf73d in g_closure_invoke (closure=0x555555c22ea0, return_value=0x0, n_param_values=4, param_values=0x7fffffffdea0, invocation_hint=0x7fffffffde20) at gclosure.c:804
#13 0x00007ffff63d1f30 in signal_emit_unlocked_R (node=node@entry=0x555555c22750, detail=detail@entry=0, instance=instance@entry=0x555555c6ee60, emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0x7fffffffdea0) at gsignal.c:3673
#14 0x00007ffff63dad05 in g_signal_emit_valist (instance=0x555555c6ee60, signal_id=<optimized out>, detail=0, var_args=var_args@entry=0x7fffffffe0b0) at gsignal.c:3391
#16 0x00005555556f0f18 in _set_state_full (self=self@entry=0x555555c6ee60 [NMDeviceWifi], state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED, quitting=quitting@entry=0) at src/devices/nm-device.c:13268
#17 0x00005555556f1774 in nm_device_state_changed (self=self@entry=0x555555c6ee60 [NMDeviceWifi], state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) at src/devices/nm-device.c:13435
#18 0x00005555555bcf95 in recheck_assume_connection (self=self@entry=0x555555b09140 [NMManager], device=device@entry=0x555555c6ee60 [NMDeviceWifi]) at src/nm-manager.c:2297
#19 0x00005555555bd53e in _device_realize_finish (self=self@entry=0x555555b09140 [NMManager], device=device@entry=0x555555c6ee60 [NMDeviceWifi], plink=plink@entry=0x555555ae43d8)
at src/nm-manager.c:2473
#20 0x00005555555c01d0 in platform_link_added (self=self@entry=0x555555b09140 [NMManager], ifindex=<optimized out>, plink=plink@entry=0x555555ae43d8, guess_assume=<optimized out>, dev_state=<optimized out>) at src/nm-manager.c:2789
#21 0x00005555555c0cec in platform_query_devices (self=self@entry=0x555555b09140 [NMManager]) at src/nm-manager.c:2901
#22 0x00005555555c439e in nm_manager_start (self=0x555555b09140 [NMManager], error=<optimized out>) at src/nm-manager.c:5632
#23 0x000055555558498e in main (argc=<optimized out>, argv=<optimized out>) at src/main.c:413
(cherry picked from commit d18d292b69069a17597989251c05606cbe50a0eb)
2018-04-04 14:48:52 +02:00
|
|
|
* @indicated: whether the match is already hinted/indicated. That is the
|
|
|
|
|
* case when we found the connection in the state file from a previous run.
|
|
|
|
|
* In this case, we perform a relexed check, as we have a good hint
|
|
|
|
|
* that the connection actually matches.
|
2016-03-01 09:56:51 +01:00
|
|
|
* @device_has_carrier: pass %TRUE if the device that generated @original has
|
|
|
|
|
* a carrier, %FALSE if not
|
|
|
|
|
* @match_filter_func: a function to check whether each connection from @connections
|
|
|
|
|
* should be considered for matching. This function should return %TRUE if the
|
|
|
|
|
* connection should be considered, %FALSE if the connection should be ignored
|
|
|
|
|
* @match_compat_data: data pointer passed to @match_filter_func
|
2015-10-03 19:44:27 +02:00
|
|
|
*
|
2016-03-01 09:56:51 +01:00
|
|
|
* Checks each connection from @connections until a matching connection is found
|
|
|
|
|
* considering only setting properties marked with %NM_SETTING_PARAM_INFERRABLE
|
|
|
|
|
* and checking a few other characteristics like IPv6 method. If the caller
|
|
|
|
|
* desires some priority order of the connections, @connections should be
|
|
|
|
|
* sorted before calling this function.
|
2015-10-03 19:44:27 +02:00
|
|
|
*
|
2016-03-01 09:56:51 +01:00
|
|
|
* Returns: the best #NMConnection matching @original, or %NULL if no connection
|
|
|
|
|
* matches well enough.
|
2015-10-03 19:44:27 +02:00
|
|
|
*/
|
2016-03-01 09:56:51 +01:00
|
|
|
NMConnection *
|
2017-03-13 14:48:06 +01:00
|
|
|
nm_utils_match_connection (NMConnection *const*connections,
|
2016-03-01 09:56:51 +01:00
|
|
|
NMConnection *original,
|
Revert "core: merge branch 'bg/restart-assume-rh1551958'"
This reverts commit cc1920d71470042c4e0837848da9183526b663d0, reversing
changes made to eb8257dea5802a004af9cccacb30af98440e2172.
This breaks restart, at least for Wi-Fi devices:
#0 0x00007ffff5ee8771 in _g_log_abort (breakpoint=breakpoint@entry=1) at gmessages.c:554
#1 0x00007ffff5ee9a5b in g_logv (log_domain=0x7ffff671a738 "GLib-GIO", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fffffffd720) at gmessages.c:1362
#2 0x00007ffff5ee9baf in g_log (log_domain=log_domain@entry=0x7ffff671a738 "GLib-GIO", log_level=log_level@entry=G_LOG_LEVEL_CRITICAL, format=format@entry=0x7ffff5f347ea "%s: assertion '%s' failed") at gmessages.c:1403
#3 0x00007ffff5eea0f9 in g_return_if_fail_warning (log_domain=log_domain@entry=0x7ffff671a738 "GLib-GIO", pretty_function=pretty_function@entry=0x7ffff673fc10 <__func__.25628> "g_dbus_proxy_call_internal", expression=expression@entry=0x7ffff673fb1c "G_IS_DBUS_PROXY (proxy)") at gmessages.c:2702
#4 0x00007ffff66cdc5f in g_dbus_proxy_call_internal (proxy=0x0, method_name=method_name@entry=0x555555810510 "Scan", parameters=0x555555c7a530, flags=flags@entry=G_DBUS_CALL_FLAGS_NONE, timeout_msec=timeout_msec@entry=-1, fd_list=fd_list@entry=0x0, cancellable=0x0, callback=0x55555574cb96 <scan_request_cb>, user_data=0x555555ac2220) at gdbusproxy.c:2664
#5 0x00007ffff66cf686 in g_dbus_proxy_call (proxy=<optimized out>, method_name=method_name@entry=0x555555810510 "Scan", parameters=<optimized out>, flags=flags@entry=G_DBUS_CALL_FLAGS_NONE, timeout_msec=timeout_msec@entry=-1, cancellable=cancellable@entry=0x0, callback=0x55555574cb96 <scan_request_cb>, user_data=0x555555ac2220) at gdbusproxy.c:2970
#6 0x000055555574e026 in nm_supplicant_interface_request_scan (self=0x555555ac2220 [NMSupplicantInterface], ssids=ssids@entry=0x0) at src/supplicant/nm-supplicant-interface.c:1821
#7 0x00007fffe1038276 in request_wireless_scan (self=self@entry=0x555555c6ee60 [NMDeviceWifi], periodic=periodic@entry=0, force_if_scanning=force_if_scanning@entry=0, ssids=<optimized out>, ssids@entry=0x0) at src/devices/wifi/nm-device-wifi.c:1347
#8 0x00007fffe1039011 in device_state_changed (device=0x555555c6ee60 [NMDeviceWifi], new_state=NM_DEVICE_STATE_DISCONNECTED, old_state=<optimized out>, reason=<optimized out>)
at src/devices/wifi/nm-device-wifi.c:2998
#9 0x00007ffff432ed1e in ffi_call_unix64 () at ../src/x86/unix64.S:76
#10 0x00007ffff432e68f in ffi_call (cif=cif@entry=0x7fffffffdc70, fn=fn@entry=0x7fffe1038e1e <device_state_changed>, rvalue=<optimized out>, avalue=avalue@entry=0x7fffffffdb60)
at ../src/x86/ffi64.c:525
#15 0x00007ffff63db66f in <emit signal ??? on instance 0x555555c6ee60 [NMDeviceWifi]> (instance=instance@entry=0x555555c6ee60, signal_id=<optimized out>, detail=detail@entry=0)
at gsignal.c:3447
#11 0x00007ffff63bff39 in g_cclosure_marshal_generic (closure=0x555555c22ea0, return_gvalue=0x0, n_param_values=<optimized out>, param_values=<optimized out>, invocation_hint=<optimized out>, marshal_data=<optimized out>) at gclosure.c:1490
#12 0x00007ffff63bf73d in g_closure_invoke (closure=0x555555c22ea0, return_value=0x0, n_param_values=4, param_values=0x7fffffffdea0, invocation_hint=0x7fffffffde20) at gclosure.c:804
#13 0x00007ffff63d1f30 in signal_emit_unlocked_R (node=node@entry=0x555555c22750, detail=detail@entry=0, instance=instance@entry=0x555555c6ee60, emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0x7fffffffdea0) at gsignal.c:3673
#14 0x00007ffff63dad05 in g_signal_emit_valist (instance=0x555555c6ee60, signal_id=<optimized out>, detail=0, var_args=var_args@entry=0x7fffffffe0b0) at gsignal.c:3391
#16 0x00005555556f0f18 in _set_state_full (self=self@entry=0x555555c6ee60 [NMDeviceWifi], state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED, quitting=quitting@entry=0) at src/devices/nm-device.c:13268
#17 0x00005555556f1774 in nm_device_state_changed (self=self@entry=0x555555c6ee60 [NMDeviceWifi], state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) at src/devices/nm-device.c:13435
#18 0x00005555555bcf95 in recheck_assume_connection (self=self@entry=0x555555b09140 [NMManager], device=device@entry=0x555555c6ee60 [NMDeviceWifi]) at src/nm-manager.c:2297
#19 0x00005555555bd53e in _device_realize_finish (self=self@entry=0x555555b09140 [NMManager], device=device@entry=0x555555c6ee60 [NMDeviceWifi], plink=plink@entry=0x555555ae43d8)
at src/nm-manager.c:2473
#20 0x00005555555c01d0 in platform_link_added (self=self@entry=0x555555b09140 [NMManager], ifindex=<optimized out>, plink=plink@entry=0x555555ae43d8, guess_assume=<optimized out>, dev_state=<optimized out>) at src/nm-manager.c:2789
#21 0x00005555555c0cec in platform_query_devices (self=self@entry=0x555555b09140 [NMManager]) at src/nm-manager.c:2901
#22 0x00005555555c439e in nm_manager_start (self=0x555555b09140 [NMManager], error=<optimized out>) at src/nm-manager.c:5632
#23 0x000055555558498e in main (argc=<optimized out>, argv=<optimized out>) at src/main.c:413
(cherry picked from commit d18d292b69069a17597989251c05606cbe50a0eb)
2018-04-04 14:48:52 +02:00
|
|
|
gboolean indicated,
|
2016-03-01 09:56:51 +01:00
|
|
|
gboolean device_has_carrier,
|
|
|
|
|
gint64 default_v4_metric,
|
|
|
|
|
gint64 default_v6_metric,
|
|
|
|
|
NMUtilsMatchFilterFunc match_filter_func,
|
|
|
|
|
gpointer match_filter_data)
|
2015-10-03 19:44:27 +02:00
|
|
|
{
|
2016-03-01 09:56:51 +01:00
|
|
|
NMConnection *best_match = NULL;
|
2015-10-03 19:44:27 +02:00
|
|
|
|
2017-03-13 14:48:06 +01:00
|
|
|
if (!connections)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
for (; *connections; connections++) {
|
|
|
|
|
NMConnection *candidate = NM_CONNECTION (*connections);
|
2016-03-01 09:56:51 +01:00
|
|
|
GHashTable *diffs = NULL;
|
2015-10-03 19:44:27 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
if (match_filter_func) {
|
|
|
|
|
if (!match_filter_func (candidate, match_filter_data))
|
|
|
|
|
continue;
|
2015-10-03 19:44:27 +02:00
|
|
|
}
|
|
|
|
|
|
Revert "core: merge branch 'bg/restart-assume-rh1551958'"
This reverts commit cc1920d71470042c4e0837848da9183526b663d0, reversing
changes made to eb8257dea5802a004af9cccacb30af98440e2172.
This breaks restart, at least for Wi-Fi devices:
#0 0x00007ffff5ee8771 in _g_log_abort (breakpoint=breakpoint@entry=1) at gmessages.c:554
#1 0x00007ffff5ee9a5b in g_logv (log_domain=0x7ffff671a738 "GLib-GIO", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7fffffffd720) at gmessages.c:1362
#2 0x00007ffff5ee9baf in g_log (log_domain=log_domain@entry=0x7ffff671a738 "GLib-GIO", log_level=log_level@entry=G_LOG_LEVEL_CRITICAL, format=format@entry=0x7ffff5f347ea "%s: assertion '%s' failed") at gmessages.c:1403
#3 0x00007ffff5eea0f9 in g_return_if_fail_warning (log_domain=log_domain@entry=0x7ffff671a738 "GLib-GIO", pretty_function=pretty_function@entry=0x7ffff673fc10 <__func__.25628> "g_dbus_proxy_call_internal", expression=expression@entry=0x7ffff673fb1c "G_IS_DBUS_PROXY (proxy)") at gmessages.c:2702
#4 0x00007ffff66cdc5f in g_dbus_proxy_call_internal (proxy=0x0, method_name=method_name@entry=0x555555810510 "Scan", parameters=0x555555c7a530, flags=flags@entry=G_DBUS_CALL_FLAGS_NONE, timeout_msec=timeout_msec@entry=-1, fd_list=fd_list@entry=0x0, cancellable=0x0, callback=0x55555574cb96 <scan_request_cb>, user_data=0x555555ac2220) at gdbusproxy.c:2664
#5 0x00007ffff66cf686 in g_dbus_proxy_call (proxy=<optimized out>, method_name=method_name@entry=0x555555810510 "Scan", parameters=<optimized out>, flags=flags@entry=G_DBUS_CALL_FLAGS_NONE, timeout_msec=timeout_msec@entry=-1, cancellable=cancellable@entry=0x0, callback=0x55555574cb96 <scan_request_cb>, user_data=0x555555ac2220) at gdbusproxy.c:2970
#6 0x000055555574e026 in nm_supplicant_interface_request_scan (self=0x555555ac2220 [NMSupplicantInterface], ssids=ssids@entry=0x0) at src/supplicant/nm-supplicant-interface.c:1821
#7 0x00007fffe1038276 in request_wireless_scan (self=self@entry=0x555555c6ee60 [NMDeviceWifi], periodic=periodic@entry=0, force_if_scanning=force_if_scanning@entry=0, ssids=<optimized out>, ssids@entry=0x0) at src/devices/wifi/nm-device-wifi.c:1347
#8 0x00007fffe1039011 in device_state_changed (device=0x555555c6ee60 [NMDeviceWifi], new_state=NM_DEVICE_STATE_DISCONNECTED, old_state=<optimized out>, reason=<optimized out>)
at src/devices/wifi/nm-device-wifi.c:2998
#9 0x00007ffff432ed1e in ffi_call_unix64 () at ../src/x86/unix64.S:76
#10 0x00007ffff432e68f in ffi_call (cif=cif@entry=0x7fffffffdc70, fn=fn@entry=0x7fffe1038e1e <device_state_changed>, rvalue=<optimized out>, avalue=avalue@entry=0x7fffffffdb60)
at ../src/x86/ffi64.c:525
#15 0x00007ffff63db66f in <emit signal ??? on instance 0x555555c6ee60 [NMDeviceWifi]> (instance=instance@entry=0x555555c6ee60, signal_id=<optimized out>, detail=detail@entry=0)
at gsignal.c:3447
#11 0x00007ffff63bff39 in g_cclosure_marshal_generic (closure=0x555555c22ea0, return_gvalue=0x0, n_param_values=<optimized out>, param_values=<optimized out>, invocation_hint=<optimized out>, marshal_data=<optimized out>) at gclosure.c:1490
#12 0x00007ffff63bf73d in g_closure_invoke (closure=0x555555c22ea0, return_value=0x0, n_param_values=4, param_values=0x7fffffffdea0, invocation_hint=0x7fffffffde20) at gclosure.c:804
#13 0x00007ffff63d1f30 in signal_emit_unlocked_R (node=node@entry=0x555555c22750, detail=detail@entry=0, instance=instance@entry=0x555555c6ee60, emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0x7fffffffdea0) at gsignal.c:3673
#14 0x00007ffff63dad05 in g_signal_emit_valist (instance=0x555555c6ee60, signal_id=<optimized out>, detail=0, var_args=var_args@entry=0x7fffffffe0b0) at gsignal.c:3391
#16 0x00005555556f0f18 in _set_state_full (self=self@entry=0x555555c6ee60 [NMDeviceWifi], state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED, quitting=quitting@entry=0) at src/devices/nm-device.c:13268
#17 0x00005555556f1774 in nm_device_state_changed (self=self@entry=0x555555c6ee60 [NMDeviceWifi], state=state@entry=NM_DEVICE_STATE_DISCONNECTED, reason=reason@entry=NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) at src/devices/nm-device.c:13435
#18 0x00005555555bcf95 in recheck_assume_connection (self=self@entry=0x555555b09140 [NMManager], device=device@entry=0x555555c6ee60 [NMDeviceWifi]) at src/nm-manager.c:2297
#19 0x00005555555bd53e in _device_realize_finish (self=self@entry=0x555555b09140 [NMManager], device=device@entry=0x555555c6ee60 [NMDeviceWifi], plink=plink@entry=0x555555ae43d8)
at src/nm-manager.c:2473
#20 0x00005555555c01d0 in platform_link_added (self=self@entry=0x555555b09140 [NMManager], ifindex=<optimized out>, plink=plink@entry=0x555555ae43d8, guess_assume=<optimized out>, dev_state=<optimized out>) at src/nm-manager.c:2789
#21 0x00005555555c0cec in platform_query_devices (self=self@entry=0x555555b09140 [NMManager]) at src/nm-manager.c:2901
#22 0x00005555555c439e in nm_manager_start (self=0x555555b09140 [NMManager], error=<optimized out>) at src/nm-manager.c:5632
#23 0x000055555558498e in main (argc=<optimized out>, argv=<optimized out>) at src/main.c:413
(cherry picked from commit d18d292b69069a17597989251c05606cbe50a0eb)
2018-04-04 14:48:52 +02:00
|
|
|
if (indicated) {
|
|
|
|
|
NMSettingConnection *s_orig, *s_cand;
|
|
|
|
|
|
|
|
|
|
s_orig = nm_connection_get_setting_connection (original);
|
|
|
|
|
s_cand = nm_connection_get_setting_connection (candidate);
|
|
|
|
|
|
|
|
|
|
/* It is indicated that this connection matches. Assume we have
|
|
|
|
|
* a match, but check for particular differences that let us
|
|
|
|
|
* reject the candidate. */
|
|
|
|
|
if (!nm_streq0 (nm_setting_connection_get_connection_type (s_orig),
|
|
|
|
|
nm_setting_connection_get_connection_type (s_cand)))
|
|
|
|
|
continue;
|
|
|
|
|
if (!nm_streq0 (nm_setting_connection_get_slave_type (s_orig),
|
|
|
|
|
nm_setting_connection_get_slave_type (s_cand)))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* this is good enough for a match */
|
|
|
|
|
} else if (!nm_connection_diff (original, candidate, NM_SETTING_COMPARE_FLAG_INFERRABLE, &diffs)) {
|
2016-03-01 09:56:51 +01:00
|
|
|
if (!best_match) {
|
|
|
|
|
best_match = check_possible_match (original, candidate, diffs, device_has_carrier,
|
|
|
|
|
default_v4_metric, default_v6_metric);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!best_match && nm_logging_enabled (LOGL_DEBUG, LOGD_CORE)) {
|
|
|
|
|
GString *diff_string;
|
|
|
|
|
GHashTableIter s_iter, p_iter;
|
|
|
|
|
gpointer setting_name, setting;
|
|
|
|
|
gpointer property_name, value;
|
2015-10-03 19:44:27 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
diff_string = g_string_new (NULL);
|
|
|
|
|
g_hash_table_iter_init (&s_iter, diffs);
|
|
|
|
|
while (g_hash_table_iter_next (&s_iter, &setting_name, &setting)) {
|
|
|
|
|
g_hash_table_iter_init (&p_iter, setting);
|
|
|
|
|
while (g_hash_table_iter_next (&p_iter, &property_name, &value)) {
|
|
|
|
|
if (diff_string->len)
|
|
|
|
|
g_string_append (diff_string, ", ");
|
|
|
|
|
g_string_append_printf (diff_string, "%s.%s",
|
|
|
|
|
(char *) setting_name,
|
|
|
|
|
(char *) property_name);
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-10-03 19:44:27 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
nm_log_dbg (LOGD_CORE, "Connection '%s' differs from candidate '%s' in %s",
|
|
|
|
|
nm_connection_get_id (original),
|
|
|
|
|
nm_connection_get_id (candidate),
|
|
|
|
|
diff_string->str);
|
|
|
|
|
g_string_free (diff_string, TRUE);
|
2015-10-03 19:44:27 +02:00
|
|
|
}
|
2016-03-01 09:56:51 +01:00
|
|
|
|
|
|
|
|
g_hash_table_unref (diffs);
|
|
|
|
|
continue;
|
2015-10-03 19:44:27 +02:00
|
|
|
}
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
/* Exact match */
|
|
|
|
|
return candidate;
|
2015-10-03 19:44:27 +02:00
|
|
|
}
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
/* Best match (if any) */
|
|
|
|
|
return best_match;
|
2015-10-03 19:44:27 +02:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2015-04-03 10:08:52 -04:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_utils_g_value_set_object_path:
|
|
|
|
|
* @value: a #GValue, initialized to store an object path
|
|
|
|
|
* @object: (allow-none): an #NMExportedObject
|
|
|
|
|
*
|
|
|
|
|
* Sets @value to @object's object path. If @object is %NULL, or not
|
|
|
|
|
* exported, @value is set to "/".
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
nm_utils_g_value_set_object_path (GValue *value, gpointer object)
|
|
|
|
|
{
|
|
|
|
|
g_return_if_fail (!object || NM_IS_EXPORTED_OBJECT (object));
|
|
|
|
|
|
|
|
|
|
if (object && nm_exported_object_is_exported (object))
|
2015-04-16 12:34:55 -04:00
|
|
|
g_value_set_string (value, nm_exported_object_get_path (object));
|
2015-04-03 10:08:52 -04:00
|
|
|
else
|
2015-04-16 12:34:55 -04:00
|
|
|
g_value_set_string (value, "/");
|
2015-04-03 10:08:52 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_utils_g_value_set_object_path_array:
|
|
|
|
|
* @value: a #GValue, initialized to store an object path
|
|
|
|
|
* @objects: a #GSList of #NMExportedObjects
|
2015-08-06 10:29:29 +02:00
|
|
|
* @filter_func: (allow-none): function to call on each object in @objects
|
|
|
|
|
* @user_data: data to pass to @filter_func
|
2015-04-03 10:08:52 -04:00
|
|
|
*
|
|
|
|
|
* Sets @value to an array of object paths of the objects in @objects.
|
|
|
|
|
*/
|
|
|
|
|
void
|
2015-08-06 10:29:29 +02:00
|
|
|
nm_utils_g_value_set_object_path_array (GValue *value,
|
|
|
|
|
GSList *objects,
|
|
|
|
|
NMUtilsObjectFunc filter_func,
|
|
|
|
|
gpointer user_data)
|
2015-04-03 10:08:52 -04:00
|
|
|
{
|
2015-08-18 15:12:43 +02:00
|
|
|
char **paths;
|
|
|
|
|
guint i;
|
2015-04-03 10:08:52 -04:00
|
|
|
GSList *iter;
|
|
|
|
|
|
2015-08-18 15:12:43 +02:00
|
|
|
paths = g_new (char *, g_slist_length (objects) + 1);
|
|
|
|
|
for (i = 0, iter = objects; iter; iter = iter->next) {
|
2015-04-03 10:08:52 -04:00
|
|
|
NMExportedObject *object = iter->data;
|
2015-12-04 13:12:04 +01:00
|
|
|
const char *path;
|
2015-04-03 10:08:52 -04:00
|
|
|
|
2015-12-04 13:12:04 +01:00
|
|
|
path = nm_exported_object_get_path (object);
|
|
|
|
|
if (!path)
|
2015-04-03 10:08:52 -04:00
|
|
|
continue;
|
2015-08-18 15:12:43 +02:00
|
|
|
if (filter_func && !filter_func ((GObject *) object, user_data))
|
2015-08-06 10:29:29 +02:00
|
|
|
continue;
|
2015-12-04 13:12:04 +01:00
|
|
|
paths[i++] = g_strdup (path);
|
2015-04-03 10:08:52 -04:00
|
|
|
}
|
2015-08-18 15:12:43 +02:00
|
|
|
paths[i] = NULL;
|
|
|
|
|
g_value_take_boxed (value, paths);
|
2015-04-03 10:08:52 -04:00
|
|
|
}
|
2015-04-15 14:53:30 -04:00
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|