2020-12-23 22:21:36 +01:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
2019-09-25 13:13:40 +02:00
|
|
|
/*
|
2019-10-01 09:20:35 +02:00
|
|
|
* Copyright (C) 2004 - 2016 Red Hat, Inc.
|
|
|
|
|
* Copyright (C) 2005 - 2008 Novell, Inc.
|
2004-06-24 14:18:37 +00:00
|
|
|
*/
|
|
|
|
|
|
2021-02-04 18:04:13 +01:00
|
|
|
#include "src/core/nm-default-daemon.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
|
|
|
|
2019-03-23 15:09:29 +01:00
|
|
|
#include <linux/fib_rules.h>
|
2020-05-13 13:57:35 +02:00
|
|
|
#include <linux/pkt_sched.h>
|
2020-12-13 16:08:56 +01:00
|
|
|
#include <linux/if_ether.h>
|
2019-03-23 15:09:29 +01:00
|
|
|
|
2021-02-18 17:37:47 +01:00
|
|
|
#include "libnm-glib-aux/nm-c-list.h"
|
2018-05-18 13:06:03 +02:00
|
|
|
|
2021-05-02 21:47:22 +02:00
|
|
|
#include "libnm-glib-aux/nm-uuid.h"
|
2021-05-05 17:18:55 +02:00
|
|
|
#include "libnm-glib-aux/nm-str-buf.h"
|
2021-03-19 10:46:41 +01:00
|
|
|
#include "libnm-base/nm-net-aux.h"
|
2021-08-20 18:40:21 +08:00
|
|
|
#include "libnm-core-aux-intern/nm-libnm-core-utils.h"
|
2021-02-12 15:01:09 +01:00
|
|
|
#include "libnm-core-aux-intern/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"
|
2023-07-04 12:50:29 +02:00
|
|
|
#include "settings/nm-settings.h"
|
2021-02-12 15:01:09 +01:00
|
|
|
#include "libnm-core-intern/nm-core-internal.h"
|
2021-03-04 11:29:39 +01:00
|
|
|
#include "libnm-platform/nmp-object.h"
|
2004-06-24 14:18:37 +00:00
|
|
|
|
2021-03-04 11:29:39 +01:00
|
|
|
#include "libnm-platform/nm-platform.h"
|
|
|
|
|
#include "libnm-platform/nm-linux-platform.h"
|
2021-10-27 11:09:52 +02:00
|
|
|
#include "libnm-platform/nm-platform-utils.h"
|
2016-03-01 09:56:51 +01:00
|
|
|
#include "nm-auth-utils.h"
|
2023-06-12 12:11:54 +02:00
|
|
|
#include "devices/nm-device.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
|
|
|
|
2022-02-18 13:25:13 +01:00
|
|
|
G_STATIC_ASSERT(NM_SHUTDOWN_TIMEOUT_1500_MSEC <= NM_SHUTDOWN_TIMEOUT_MAX_MSEC);
|
2022-02-18 15:00:37 +01:00
|
|
|
G_STATIC_ASSERT(NM_SHUTDOWN_TIMEOUT_5000_MSEC <= NM_SHUTDOWN_TIMEOUT_MAX_MSEC);
|
2022-02-18 13:25:13 +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
|
|
|
{
|
2021-11-09 13:28:54 +01:00
|
|
|
NMSettingWireless *s_wifi;
|
2016-03-01 09:56:51 +01:00
|
|
|
NMSettingWirelessSecurity *s_wsec;
|
2021-11-09 13:28:54 +01:00
|
|
|
const char *method;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-12-12 17:11:34 +01:00
|
|
|
method = nm_utils_get_ip_config_method(connection, AF_INET);
|
2018-12-12 17:11:34 +01:00
|
|
|
if (!nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_SHARED))
|
|
|
|
|
return NULL;
|
2020-09-28 16:03:33 +02: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
|
|
|
}
|
2020-09-28 16:03:33 +02: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 *
|
core: avoid clone of all-connections list for nm_utils_complete_generic()
NMSettings exposes a cached list of all connection. We don't need
to clone it. Note that this is not save against concurrent modification,
meaning, add/remove of connections in NMSettings will invalidate the
list.
However, it wasn't save against that previously either, because
altough we cloned the container (GSList), we didn't take an additional
reference to the elements.
This is purely a performance optimization, we don't need to clone the
list. Also, since the original list is of type "NMConnection *const*",
use that type insistently, instead of dependent API requiring GSList.
IMO, GSList is anyway not a very nice API for many use cases because
it requires an additional slice allocation for each element. It's
slower, and often less convenient to use.
2018-03-14 08:57:42 +01:00
|
|
|
get_new_connection_name(NMConnection *const *existing_connections,
|
2021-11-09 13:28:54 +01:00
|
|
|
const char *preferred,
|
|
|
|
|
const char *fallback_prefix)
|
2016-03-01 09:56:51 +01:00
|
|
|
{
|
core: avoid clone of all-connections list for nm_utils_complete_generic()
NMSettings exposes a cached list of all connection. We don't need
to clone it. Note that this is not save against concurrent modification,
meaning, add/remove of connections in NMSettings will invalidate the
list.
However, it wasn't save against that previously either, because
altough we cloned the container (GSList), we didn't take an additional
reference to the elements.
This is purely a performance optimization, we don't need to clone the
list. Also, since the original list is of type "NMConnection *const*",
use that type insistently, instead of dependent API requiring GSList.
IMO, GSList is anyway not a very nice API for many use cases because
it requires an additional slice allocation for each element. It's
slower, and often less convenient to use.
2018-03-14 08:57:42 +01:00
|
|
|
gs_free const char **existing_names = NULL;
|
|
|
|
|
guint i, existing_len = 0;
|
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
|
|
|
|
core: avoid clone of all-connections list for nm_utils_complete_generic()
NMSettings exposes a cached list of all connection. We don't need
to clone it. Note that this is not save against concurrent modification,
meaning, add/remove of connections in NMSettings will invalidate the
list.
However, it wasn't save against that previously either, because
altough we cloned the container (GSList), we didn't take an additional
reference to the elements.
This is purely a performance optimization, we don't need to clone the
list. Also, since the original list is of type "NMConnection *const*",
use that type insistently, instead of dependent API requiring GSList.
IMO, GSList is anyway not a very nice API for many use cases because
it requires an additional slice allocation for each element. It's
slower, and often less convenient to use.
2018-03-14 08:57:42 +01:00
|
|
|
if (existing_connections) {
|
|
|
|
|
existing_len = NM_PTRARRAY_LEN(existing_connections);
|
|
|
|
|
existing_names = g_new(const char *, existing_len);
|
|
|
|
|
for (i = 0; i < existing_len; i++) {
|
|
|
|
|
NMConnection *candidate;
|
2021-11-09 13:28:54 +01:00
|
|
|
const char *id;
|
2015-09-24 12:44:20 +02:00
|
|
|
|
core: avoid clone of all-connections list for nm_utils_complete_generic()
NMSettings exposes a cached list of all connection. We don't need
to clone it. Note that this is not save against concurrent modification,
meaning, add/remove of connections in NMSettings will invalidate the
list.
However, it wasn't save against that previously either, because
altough we cloned the container (GSList), we didn't take an additional
reference to the elements.
This is purely a performance optimization, we don't need to clone the
list. Also, since the original list is of type "NMConnection *const*",
use that type insistently, instead of dependent API requiring GSList.
IMO, GSList is anyway not a very nice API for many use cases because
it requires an additional slice allocation for each element. It's
slower, and often less convenient to use.
2018-03-14 08:57:42 +01:00
|
|
|
candidate = existing_connections[i];
|
|
|
|
|
nm_assert(NM_IS_CONNECTION(candidate));
|
2018-03-14 08:29:02 +01:00
|
|
|
|
core: avoid clone of all-connections list for nm_utils_complete_generic()
NMSettings exposes a cached list of all connection. We don't need
to clone it. Note that this is not save against concurrent modification,
meaning, add/remove of connections in NMSettings will invalidate the
list.
However, it wasn't save against that previously either, because
altough we cloned the container (GSList), we didn't take an additional
reference to the elements.
This is purely a performance optimization, we don't need to clone the
list. Also, since the original list is of type "NMConnection *const*",
use that type insistently, instead of dependent API requiring GSList.
IMO, GSList is anyway not a very nice API for many use cases because
it requires an additional slice allocation for each element. It's
slower, and often less convenient to use.
2018-03-14 08:57:42 +01:00
|
|
|
id = nm_connection_get_id(candidate);
|
|
|
|
|
nm_assert(id);
|
2015-09-24 12:44:20 +02:00
|
|
|
|
core: avoid clone of all-connections list for nm_utils_complete_generic()
NMSettings exposes a cached list of all connection. We don't need
to clone it. Note that this is not save against concurrent modification,
meaning, add/remove of connections in NMSettings will invalidate the
list.
However, it wasn't save against that previously either, because
altough we cloned the container (GSList), we didn't take an additional
reference to the elements.
This is purely a performance optimization, we don't need to clone the
list. Also, since the original list is of type "NMConnection *const*",
use that type insistently, instead of dependent API requiring GSList.
IMO, GSList is anyway not a very nice API for many use cases because
it requires an additional slice allocation for each element. It's
slower, and often less convenient to use.
2018-03-14 08:57:42 +01:00
|
|
|
existing_names[i] = id;
|
|
|
|
|
|
|
|
|
|
if (preferred && nm_streq(preferred, id)) {
|
|
|
|
|
/* the preferred name is already taken. Forget about it. */
|
|
|
|
|
preferred = NULL;
|
|
|
|
|
}
|
2018-03-14 08:29:02 +01:00
|
|
|
}
|
core: avoid clone of all-connections list for nm_utils_complete_generic()
NMSettings exposes a cached list of all connection. We don't need
to clone it. Note that this is not save against concurrent modification,
meaning, add/remove of connections in NMSettings will invalidate the
list.
However, it wasn't save against that previously either, because
altough we cloned the container (GSList), we didn't take an additional
reference to the elements.
This is purely a performance optimization, we don't need to clone the
list. Also, since the original list is of type "NMConnection *const*",
use that type insistently, instead of dependent API requiring GSList.
IMO, GSList is anyway not a very nice API for many use cases because
it requires an additional slice allocation for each element. It's
slower, and often less convenient to use.
2018-03-14 08:57:42 +01:00
|
|
|
nm_assert(!existing_connections[i]);
|
2015-09-24 12:44:20 +02:00
|
|
|
}
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
/* Return the preferred name if it was unique */
|
core: avoid clone of all-connections list for nm_utils_complete_generic()
NMSettings exposes a cached list of all connection. We don't need
to clone it. Note that this is not save against concurrent modification,
meaning, add/remove of connections in NMSettings will invalidate the
list.
However, it wasn't save against that previously either, because
altough we cloned the container (GSList), we didn't take an additional
reference to the elements.
This is purely a performance optimization, we don't need to clone the
list. Also, since the original list is of type "NMConnection *const*",
use that type insistently, instead of dependent API requiring GSList.
IMO, GSList is anyway not a very nice API for many use cases because
it requires an additional slice allocation for each element. It's
slower, and often less convenient to use.
2018-03-14 08:57:42 +01:00
|
|
|
if (preferred)
|
2016-03-01 09:56:51 +01:00
|
|
|
return g_strdup(preferred);
|
2015-09-24 12:44:20 +02:00
|
|
|
|
2020-07-01 17:20:40 -04:00
|
|
|
/* Otherwise, find the next available unique connection name using the given
|
2016-03-01 09:56:51 +01:00
|
|
|
* connection name template.
|
|
|
|
|
*/
|
2018-03-14 08:29:02 +01:00
|
|
|
for (i = 1; TRUE; i++) {
|
|
|
|
|
char *temp;
|
2015-07-24 18:54:13 +02:00
|
|
|
|
2017-12-27 14:17:34 +01:00
|
|
|
/* TRANSLATORS: the first %s is a prefix for the connection id, such
|
2016-03-01 09:56:51 +01:00
|
|
|
* as "Wired Connection" or "VPN Connection". The %d is a number
|
|
|
|
|
* that is combined with the first argument to create a unique
|
|
|
|
|
* connection id. */
|
2018-03-14 08:29:02 +01:00
|
|
|
temp = g_strdup_printf(C_("connection id fallback", "%s %u"), fallback_prefix, i);
|
core: avoid clone of all-connections list for nm_utils_complete_generic()
NMSettings exposes a cached list of all connection. We don't need
to clone it. Note that this is not save against concurrent modification,
meaning, add/remove of connections in NMSettings will invalidate the
list.
However, it wasn't save against that previously either, because
altough we cloned the container (GSList), we didn't take an additional
reference to the elements.
This is purely a performance optimization, we don't need to clone the
list. Also, since the original list is of type "NMConnection *const*",
use that type insistently, instead of dependent API requiring GSList.
IMO, GSList is anyway not a very nice API for many use cases because
it requires an additional slice allocation for each element. It's
slower, and often less convenient to use.
2018-03-14 08:57:42 +01:00
|
|
|
|
2023-10-19 16:45:11 +02:00
|
|
|
if (!nm_strv_contains(existing_names, existing_len, temp))
|
2018-03-14 08:29:02 +01:00
|
|
|
return temp;
|
core: avoid clone of all-connections list for nm_utils_complete_generic()
NMSettings exposes a cached list of all connection. We don't need
to clone it. Note that this is not save against concurrent modification,
meaning, add/remove of connections in NMSettings will invalidate the
list.
However, it wasn't save against that previously either, because
altough we cloned the container (GSList), we didn't take an additional
reference to the elements.
This is purely a performance optimization, we don't need to clone the
list. Also, since the original list is of type "NMConnection *const*",
use that type insistently, instead of dependent API requiring GSList.
IMO, GSList is anyway not a very nice API for many use cases because
it requires an additional slice allocation for each element. It's
slower, and often less convenient to use.
2018-03-14 08:57:42 +01:00
|
|
|
|
2018-03-14 08:29:02 +01:00
|
|
|
g_free(temp);
|
2016-03-01 09:56:51 +01:00
|
|
|
}
|
2015-07-24 18:54:13 +02:00
|
|
|
}
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
static char *
|
2021-11-09 13:28:54 +01:00
|
|
|
get_new_connection_ifname(NMPlatform *platform,
|
core: avoid clone of all-connections list for nm_utils_complete_generic()
NMSettings exposes a cached list of all connection. We don't need
to clone it. Note that this is not save against concurrent modification,
meaning, add/remove of connections in NMSettings will invalidate the
list.
However, it wasn't save against that previously either, because
altough we cloned the container (GSList), we didn't take an additional
reference to the elements.
This is purely a performance optimization, we don't need to clone the
list. Also, since the original list is of type "NMConnection *const*",
use that type insistently, instead of dependent API requiring GSList.
IMO, GSList is anyway not a very nice API for many use cases because
it requires an additional slice allocation for each element. It's
slower, and often less convenient to use.
2018-03-14 08:57:42 +01:00
|
|
|
NMConnection *const *existing_connections,
|
2021-11-09 13:28:54 +01:00
|
|
|
const char *prefix)
|
2015-07-24 18:54:13 +02:00
|
|
|
{
|
core: avoid clone of all-connections list for nm_utils_complete_generic()
NMSettings exposes a cached list of all connection. We don't need
to clone it. Note that this is not save against concurrent modification,
meaning, add/remove of connections in NMSettings will invalidate the
list.
However, it wasn't save against that previously either, because
altough we cloned the container (GSList), we didn't take an additional
reference to the elements.
This is purely a performance optimization, we don't need to clone the
list. Also, since the original list is of type "NMConnection *const*",
use that type insistently, instead of dependent API requiring GSList.
IMO, GSList is anyway not a very nice API for many use cases because
it requires an additional slice allocation for each element. It's
slower, and often less convenient to use.
2018-03-14 08:57:42 +01:00
|
|
|
guint i, j;
|
2016-03-01 09:56:51 +01:00
|
|
|
|
2018-03-14 08:29:02 +01:00
|
|
|
for (i = 0; TRUE; i++) {
|
core: avoid clone of all-connections list for nm_utils_complete_generic()
NMSettings exposes a cached list of all connection. We don't need
to clone it. Note that this is not save against concurrent modification,
meaning, add/remove of connections in NMSettings will invalidate the
list.
However, it wasn't save against that previously either, because
altough we cloned the container (GSList), we didn't take an additional
reference to the elements.
This is purely a performance optimization, we don't need to clone the
list. Also, since the original list is of type "NMConnection *const*",
use that type insistently, instead of dependent API requiring GSList.
IMO, GSList is anyway not a very nice API for many use cases because
it requires an additional slice allocation for each element. It's
slower, and often less convenient to use.
2018-03-14 08:57:42 +01:00
|
|
|
char *name;
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
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
|
|
|
|
core: avoid clone of all-connections list for nm_utils_complete_generic()
NMSettings exposes a cached list of all connection. We don't need
to clone it. Note that this is not save against concurrent modification,
meaning, add/remove of connections in NMSettings will invalidate the
list.
However, it wasn't save against that previously either, because
altough we cloned the container (GSList), we didn't take an additional
reference to the elements.
This is purely a performance optimization, we don't need to clone the
list. Also, since the original list is of type "NMConnection *const*",
use that type insistently, instead of dependent API requiring GSList.
IMO, GSList is anyway not a very nice API for many use cases because
it requires an additional slice allocation for each element. It's
slower, and often less convenient to use.
2018-03-14 08:57:42 +01:00
|
|
|
if (existing_connections) {
|
|
|
|
|
for (j = 0; existing_connections[j]; j++) {
|
|
|
|
|
if (nm_streq0(nm_connection_get_interface_name(existing_connections[j]), name))
|
|
|
|
|
goto next;
|
2016-03-01 09:56:51 +01:00
|
|
|
}
|
|
|
|
|
}
|
2015-07-24 18:54:13 +02:00
|
|
|
|
core: avoid clone of all-connections list for nm_utils_complete_generic()
NMSettings exposes a cached list of all connection. We don't need
to clone it. Note that this is not save against concurrent modification,
meaning, add/remove of connections in NMSettings will invalidate the
list.
However, it wasn't save against that previously either, because
altough we cloned the container (GSList), we didn't take an additional
reference to the elements.
This is purely a performance optimization, we don't need to clone the
list. Also, since the original list is of type "NMConnection *const*",
use that type insistently, instead of dependent API requiring GSList.
IMO, GSList is anyway not a very nice API for many use cases because
it requires an additional slice allocation for each element. It's
slower, and often less convenient to use.
2018-03-14 08:57:42 +01:00
|
|
|
return name;
|
2015-07-24 18:54:13 +02:00
|
|
|
|
core: avoid clone of all-connections list for nm_utils_complete_generic()
NMSettings exposes a cached list of all connection. We don't need
to clone it. Note that this is not save against concurrent modification,
meaning, add/remove of connections in NMSettings will invalidate the
list.
However, it wasn't save against that previously either, because
altough we cloned the container (GSList), we didn't take an additional
reference to the elements.
This is purely a performance optimization, we don't need to clone the
list. Also, since the original list is of type "NMConnection *const*",
use that type insistently, instead of dependent API requiring GSList.
IMO, GSList is anyway not a very nice API for many use cases because
it requires an additional slice allocation for each element. It's
slower, and often less convenient to use.
2018-03-14 08:57:42 +01:00
|
|
|
next:
|
2016-03-01 09:56:51 +01:00
|
|
|
g_free(name);
|
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, int addr_family)
|
2015-07-24 18:54:13 +02:00
|
|
|
{
|
2016-03-01 09:56:51 +01:00
|
|
|
NMSettingConnection *s_con;
|
2021-11-09 13:28:54 +01:00
|
|
|
NMSettingIPConfig *s_ip;
|
|
|
|
|
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
|
|
|
|
2020-10-30 12:13:18 +01:00
|
|
|
if (NM_IS_IPv4(addr_family)) {
|
2016-03-01 09:56:51 +01:00
|
|
|
g_return_val_if_fail(s_con != NULL, NM_SETTING_IP4_CONFIG_METHOD_AUTO);
|
2015-07-24 18:54:13 +02:00
|
|
|
|
2018-12-12 17:11:34 +01:00
|
|
|
s_ip = nm_connection_get_setting_ip4_config(connection);
|
|
|
|
|
if (!s_ip)
|
2016-03-01 09:56:51 +01:00
|
|
|
return NM_SETTING_IP4_CONFIG_METHOD_DISABLED;
|
2017-10-23 11:47:25 +02:00
|
|
|
|
2018-12-12 17:11:34 +01:00
|
|
|
method = nm_setting_ip_config_get_method(s_ip);
|
|
|
|
|
g_return_val_if_fail(method != NULL, NM_SETTING_IP4_CONFIG_METHOD_AUTO);
|
2017-10-23 11:47:25 +02:00
|
|
|
return method;
|
2018-12-12 17:11:34 +01:00
|
|
|
}
|
2015-10-01 13:01:39 +02:00
|
|
|
|
2020-10-30 12:13:18 +01:00
|
|
|
g_return_val_if_fail(s_con != NULL, NM_SETTING_IP6_CONFIG_METHOD_AUTO);
|
2015-10-01 13:01:39 +02:00
|
|
|
|
2020-10-30 12:13:18 +01:00
|
|
|
s_ip = nm_connection_get_setting_ip6_config(connection);
|
|
|
|
|
if (!s_ip)
|
|
|
|
|
return NM_SETTING_IP6_CONFIG_METHOD_IGNORE;
|
2015-10-01 13:01:39 +02:00
|
|
|
|
2020-10-30 12:13:18 +01:00
|
|
|
method = nm_setting_ip_config_get_method(s_ip);
|
|
|
|
|
g_return_val_if_fail(method != NULL, NM_SETTING_IP6_CONFIG_METHOD_AUTO);
|
|
|
|
|
return method;
|
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,
|
2021-11-09 13:28:54 +01:00
|
|
|
gboolean *out_is_never_default)
|
2017-08-30 19:17:29 +02:00
|
|
|
{
|
2021-11-09 13:28:54 +01:00
|
|
|
const char *method;
|
2017-08-30 19:17:29 +02:00
|
|
|
NMSettingIPConfig *s_ip;
|
|
|
|
|
gboolean is_never_default = FALSE;
|
|
|
|
|
gboolean has_default_route = FALSE;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-08-30 19:17:29 +02:00
|
|
|
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);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-08-30 19:17:29 +02:00
|
|
|
if (!connection)
|
|
|
|
|
goto out;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2019-03-02 22:17:49 +01:00
|
|
|
s_ip = nm_connection_get_setting_ip_config(connection, addr_family);
|
2017-08-30 19:17:29 +02:00
|
|
|
if (!s_ip)
|
|
|
|
|
goto out;
|
|
|
|
|
if (nm_setting_ip_config_get_never_default(s_ip)) {
|
|
|
|
|
is_never_default = TRUE;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-12-12 17:11:34 +01:00
|
|
|
method = nm_utils_get_ip_config_method(connection, addr_family);
|
2020-10-30 12:13:18 +01:00
|
|
|
if (NM_IS_IPv4(addr_family)) {
|
2018-12-12 17:11:34 +01:00
|
|
|
if (NM_IN_STRSET(method,
|
|
|
|
|
NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
|
2017-08-30 19:17:29 +02:00
|
|
|
NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL))
|
|
|
|
|
goto out;
|
|
|
|
|
} else {
|
2018-12-12 17:11:34 +01:00
|
|
|
if (NM_IN_STRSET(method,
|
|
|
|
|
NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
|
2019-04-26 13:25:21 +02:00
|
|
|
NM_SETTING_IP6_CONFIG_METHOD_DISABLED,
|
2017-08-30 19:17:29 +02:00
|
|
|
NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL))
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-08-30 19:17:29 +02:00
|
|
|
has_default_route = TRUE;
|
|
|
|
|
out:
|
|
|
|
|
NM_SET_OUT(out_is_never_default, is_never_default);
|
|
|
|
|
return has_default_route;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
void
|
|
|
|
|
nm_utils_ppp_ip_methods_enabled(NMConnection *connection,
|
2021-11-09 13:28:54 +01:00
|
|
|
gboolean *out_ip4_enabled,
|
|
|
|
|
gboolean *out_ip6_enabled)
|
2021-08-06 15:17:05 +02:00
|
|
|
{
|
|
|
|
|
NM_SET_OUT(out_ip4_enabled,
|
|
|
|
|
nm_streq0(nm_utils_get_ip_config_method(connection, AF_INET),
|
|
|
|
|
NM_SETTING_IP4_CONFIG_METHOD_AUTO));
|
|
|
|
|
NM_SET_OUT(out_ip6_enabled,
|
|
|
|
|
nm_streq0(nm_utils_get_ip_config_method(connection, AF_INET6),
|
|
|
|
|
NM_SETTING_IP6_CONFIG_METHOD_AUTO));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
void
|
2021-11-09 13:28:54 +01:00
|
|
|
_nm_utils_complete_generic_with_params(NMPlatform *platform,
|
|
|
|
|
NMConnection *connection,
|
|
|
|
|
const char *ctype,
|
2021-07-02 09:16:33 +02:00
|
|
|
NMConnection *const *existing_connections,
|
2021-11-09 13:28:54 +01:00
|
|
|
const char *preferred_id,
|
|
|
|
|
const char *fallback_id_prefix,
|
|
|
|
|
const char *ifname_prefix,
|
|
|
|
|
const char *ifname,
|
2021-07-02 09:16:33 +02:00
|
|
|
...)
|
2004-07-06 01:34:10 +00:00
|
|
|
{
|
2021-11-09 13:28:54 +01:00
|
|
|
NMSettingConnection *s_con;
|
|
|
|
|
char *id;
|
|
|
|
|
char *generated_ifname;
|
2021-07-02 09:16:33 +02:00
|
|
|
gs_unref_hashtable GHashTable *parameters = NULL;
|
|
|
|
|
va_list ap;
|
2021-11-09 13:28:54 +01:00
|
|
|
const char *p_val;
|
|
|
|
|
const char *p_key;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
g_assert(fallback_id_prefix);
|
2019-05-07 10:15:10 +02:00
|
|
|
g_return_if_fail(ifname_prefix == NULL || ifname == NULL);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-08-20 18:40:21 +08:00
|
|
|
s_con = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_CONNECTION);
|
2016-03-01 09:56:51 +01:00
|
|
|
g_object_set(G_OBJECT(s_con), NM_SETTING_CONNECTION_TYPE, ctype, NULL);
|
2020-09-28 16:03:33 +02: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];
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-02-28 16:05:39 +01:00
|
|
|
g_object_set(G_OBJECT(s_con),
|
|
|
|
|
NM_SETTING_CONNECTION_UUID,
|
2021-05-02 14:55:46 +02:00
|
|
|
nm_uuid_generate_random_str_arr(uuid),
|
2017-02-28 16:05:39 +01:00
|
|
|
NULL);
|
2016-03-01 09:56:51 +01:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
/* Add a connection ID if absent */
|
|
|
|
|
if (!nm_setting_connection_get_id(s_con)) {
|
2018-03-14 08:29:02 +01:00
|
|
|
id = get_new_connection_name(existing_connections, preferred_id, fallback_id_prefix);
|
2016-03-01 09:56:51 +01:00
|
|
|
g_object_set(G_OBJECT(s_con), NM_SETTING_CONNECTION_ID, id, NULL);
|
|
|
|
|
g_free(id);
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
/* Add an interface name, if requested */
|
2021-07-02 08:21:07 +02:00
|
|
|
if (nm_setting_connection_get_interface_name(s_con)) {
|
|
|
|
|
/* pass */
|
|
|
|
|
} else if (ifname) {
|
2016-03-01 09:56:51 +01:00
|
|
|
g_object_set(G_OBJECT(s_con), NM_SETTING_CONNECTION_INTERFACE_NAME, ifname, NULL);
|
2019-05-07 10:15:10 +02:00
|
|
|
} else if (ifname_prefix && !nm_setting_connection_get_interface_name(s_con)) {
|
|
|
|
|
generated_ifname = get_new_connection_ifname(platform, existing_connections, ifname_prefix);
|
|
|
|
|
g_object_set(G_OBJECT(s_con), NM_SETTING_CONNECTION_INTERFACE_NAME, generated_ifname, NULL);
|
|
|
|
|
g_free(generated_ifname);
|
2015-04-23 12:51:01 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
/* Normalize */
|
2021-07-02 09:16:33 +02:00
|
|
|
va_start(ap, ifname);
|
|
|
|
|
while ((p_key = va_arg(ap, const char *))) {
|
|
|
|
|
p_val = va_arg(ap, const char *);
|
|
|
|
|
if (!p_val) {
|
|
|
|
|
if (parameters)
|
|
|
|
|
g_hash_table_remove(parameters, p_key);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (!parameters)
|
|
|
|
|
parameters = g_hash_table_new(nm_str_hash, g_str_equal);
|
|
|
|
|
g_hash_table_insert(parameters, (char *) p_key, (char *) p_val);
|
|
|
|
|
}
|
|
|
|
|
va_end(ap);
|
2016-03-01 09:56:51 +01:00
|
|
|
nm_connection_normalize(connection, parameters, NULL, NULL);
|
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;
|
2020-09-28 16:03:33 +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)
|
|
|
|
|
{
|
2021-11-09 13:28:54 +01:00
|
|
|
GHashTable *props;
|
|
|
|
|
const char *orig_ip6_method, *candidate_ip6_method;
|
2016-03-01 09:56:51 +01:00
|
|
|
NMSettingIPConfig *candidate_ip6;
|
|
|
|
|
gboolean allow = FALSE;
|
2020-09-28 16:03:33 +02: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;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-12-12 17:11:34 +01:00
|
|
|
orig_ip6_method = nm_utils_get_ip_config_method(orig, AF_INET6);
|
|
|
|
|
candidate_ip6_method = nm_utils_get_ip_config_method(candidate, AF_INET6);
|
2016-03-01 09:56:51 +01:00
|
|
|
candidate_ip6 = nm_connection_get_setting_ip6_config(candidate);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-12-12 17:11:34 +01:00
|
|
|
if (nm_streq(orig_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)
|
|
|
|
|
&& nm_streq(candidate_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)
|
|
|
|
|
&& (!candidate_ip6 || nm_setting_ip_config_get_may_fail(candidate_ip6))) {
|
|
|
|
|
/* 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.
|
|
|
|
|
*/
|
2016-03-01 09:56:51 +01:00
|
|
|
allow = TRUE;
|
2018-12-12 17:11:34 +01:00
|
|
|
} else if (NM_IN_STRSET(orig_ip6_method,
|
|
|
|
|
NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL,
|
2019-11-15 14:12:28 -08:00
|
|
|
NM_SETTING_IP6_CONFIG_METHOD_DISABLED,
|
2018-12-12 17:11:34 +01:00
|
|
|
NM_SETTING_IP6_CONFIG_METHOD_AUTO)
|
|
|
|
|
&& nm_streq0(candidate_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) {
|
2019-11-15 14:12:28 -08:00
|
|
|
/* If the generated connection method is 'link-local', disabled' or 'auto' and
|
|
|
|
|
* the candidate method is 'ignore' we can take the connection, because NM didn't
|
|
|
|
|
* simply take care of IPv6.
|
2018-12-12 17:11:34 +01:00
|
|
|
*/
|
2016-03-01 09:56:51 +01:00
|
|
|
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
|
|
|
}
|
2018-12-12 17:11:34 +01: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
|
|
|
{
|
2019-02-08 12:24:07 +01:00
|
|
|
NMIPAddr a1;
|
|
|
|
|
NMIPAddr a2;
|
2019-02-08 13:07:56 +01:00
|
|
|
guint64 m1;
|
|
|
|
|
guint64 m2;
|
|
|
|
|
int family;
|
|
|
|
|
guint plen;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-04-13 19:15:02 +02:00
|
|
|
family = nm_ip_route_get_family(route1);
|
2019-02-08 13:07:56 +01:00
|
|
|
NM_CMP_DIRECT(family, nm_ip_route_get_family(route2));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2019-02-08 13:07:56 +01:00
|
|
|
nm_assert_addr_family(family);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2019-02-08 13:07:56 +01:00
|
|
|
plen = nm_ip_route_get_prefix(route1);
|
|
|
|
|
NM_CMP_DIRECT(plen, nm_ip_route_get_prefix(route2));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2019-02-08 13:07:56 +01:00
|
|
|
m1 = nm_ip_route_get_metric(route1);
|
|
|
|
|
m2 = nm_ip_route_get_metric(route2);
|
|
|
|
|
NM_CMP_DIRECT(m1 == -1 ? default_metric : m1, m2 == -1 ? default_metric : m2);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2019-02-08 13:07:56 +01:00
|
|
|
NM_CMP_DIRECT_STRCMP0(nm_ip_route_get_next_hop(route1), nm_ip_route_get_next_hop(route2));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2019-02-08 13:07:56 +01:00
|
|
|
if (!inet_pton(family, nm_ip_route_get_dest(route1), &a1))
|
|
|
|
|
nm_assert_not_reached();
|
|
|
|
|
if (!inet_pton(family, nm_ip_route_get_dest(route2), &a2))
|
|
|
|
|
nm_assert_not_reached();
|
glib-aux: rename IP address related helpers from "nm-inet-utils.h"
- name things related to `in_addr_t`, `struct in6_addr`, `NMIPAddr` as
`nm_ip4_addr_*()`, `nm_ip6_addr_*()`, `nm_ip_addr_*()`, respectively.
- we have a wrapper `nm_inet_ntop()` for `inet_ntop()`. This name
of our wrapper is chosen to be familiar with the libc underlying
function. With this, also name functions that are about string
representations of addresses `nm_inet_*()`, `nm_inet4_*()`,
`nm_inet6_*()`. For example, `nm_inet_parse_str()`,
`nm_inet_is_normalized()`.
<<<<
R() {
git grep -l "$1" | xargs sed -i "s/\<$1\>/$2/g"
}
R NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX NM_CMP_DIRECT_IP4_ADDR_SAME_PREFIX
R NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX NM_CMP_DIRECT_IP6_ADDR_SAME_PREFIX
R NM_UTILS_INET_ADDRSTRLEN NM_INET_ADDRSTRLEN
R _nm_utils_inet4_ntop nm_inet4_ntop
R _nm_utils_inet6_ntop nm_inet6_ntop
R _nm_utils_ip4_get_default_prefix nm_ip4_addr_get_default_prefix
R _nm_utils_ip4_get_default_prefix0 nm_ip4_addr_get_default_prefix0
R _nm_utils_ip4_netmask_to_prefix nm_ip4_addr_netmask_to_prefix
R _nm_utils_ip4_prefix_to_netmask nm_ip4_addr_netmask_from_prefix
R nm_utils_inet4_ntop_dup nm_inet4_ntop_dup
R nm_utils_inet6_ntop_dup nm_inet6_ntop_dup
R nm_utils_inet_ntop nm_inet_ntop
R nm_utils_inet_ntop_dup nm_inet_ntop_dup
R nm_utils_ip4_address_clear_host_address nm_ip4_addr_clear_host_address
R nm_utils_ip4_address_is_link_local nm_ip4_addr_is_link_local
R nm_utils_ip4_address_is_loopback nm_ip4_addr_is_loopback
R nm_utils_ip4_address_is_zeronet nm_ip4_addr_is_zeronet
R nm_utils_ip4_address_same_prefix nm_ip4_addr_same_prefix
R nm_utils_ip4_address_same_prefix_cmp nm_ip4_addr_same_prefix_cmp
R nm_utils_ip6_address_clear_host_address nm_ip6_addr_clear_host_address
R nm_utils_ip6_address_same_prefix nm_ip6_addr_same_prefix
R nm_utils_ip6_address_same_prefix_cmp nm_ip6_addr_same_prefix_cmp
R nm_utils_ip6_is_ula nm_ip6_addr_is_ula
R nm_utils_ip_address_same_prefix nm_ip_addr_same_prefix
R nm_utils_ip_address_same_prefix_cmp nm_ip_addr_same_prefix_cmp
R nm_utils_ip_is_site_local nm_ip_addr_is_site_local
R nm_utils_ipaddr_is_normalized nm_inet_is_normalized
R nm_utils_ipaddr_is_valid nm_inet_is_valid
R nm_utils_ipx_address_clear_host_address nm_ip_addr_clear_host_address
R nm_utils_parse_inaddr nm_inet_parse_str
R nm_utils_parse_inaddr_bin nm_inet_parse_bin
R nm_utils_parse_inaddr_bin_full nm_inet_parse_bin_full
R nm_utils_parse_inaddr_prefix nm_inet_parse_with_prefix_str
R nm_utils_parse_inaddr_prefix_bin nm_inet_parse_with_prefix_bin
R test_nm_utils_ip6_address_same_prefix test_nm_ip_addr_same_prefix
./contrib/scripts/nm-code-format.sh -F
2022-08-19 13:15:20 +02:00
|
|
|
nm_ip_addr_clear_host_address(family, &a1, NULL, plen);
|
|
|
|
|
nm_ip_addr_clear_host_address(family, &a2, NULL, plen);
|
2019-02-08 13:07:56 +01:00
|
|
|
NM_CMP_DIRECT_MEMCMP(&a1, &a2, nm_utils_addr_family_to_size(family));
|
2020-09-28 16:03:33 +02: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,
|
2021-11-09 13:28:54 +01:00
|
|
|
GHashTable *settings,
|
2016-03-01 09:56:51 +01:00
|
|
|
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;
|
2021-11-09 13:28:54 +01:00
|
|
|
NMIPRoute **routes2;
|
|
|
|
|
NMSettingIPConfig *s_ip1, *s_ip2;
|
2017-03-16 17:42:30 +01:00
|
|
|
gint64 m;
|
2021-11-09 13:28:54 +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;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
s_name = v4 ? NM_SETTING_IP4_CONFIG_SETTING_NAME : NM_SETTING_IP6_CONFIG_SETTING_NAME;
|
2020-09-28 16:03:33 +02: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;
|
2020-09-28 16:03:33 +02: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);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
if (!s_ip1 || !s_ip2)
|
|
|
|
|
return FALSE;
|
2020-09-28 16:03:33 +02: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);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-09-01 09:14:13 +02:00
|
|
|
routes1 = g_new(NMIPRoute *, (gsize) num1 + num2);
|
|
|
|
|
routes2 = &routes1[num1];
|
2020-09-28 16:03:33 +02: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);
|
2020-09-28 16:03:33 +02: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;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
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);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-09-01 09:14:13 +02:00
|
|
|
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;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-09-01 09:14:13 +02:00
|
|
|
/* 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,
|
2021-11-09 13:28:54 +01:00
|
|
|
GHashTable *settings,
|
2016-03-01 09:56:51 +01:00
|
|
|
gboolean device_has_carrier)
|
2014-02-14 12:54:36 +01:00
|
|
|
{
|
2021-11-09 13:28:54 +01:00
|
|
|
GHashTable *props;
|
|
|
|
|
const char *orig_ip4_method, *candidate_ip4_method;
|
2016-03-01 09:56:51 +01:00
|
|
|
NMSettingIPConfig *candidate_ip4;
|
2020-09-28 16:03:33 +02: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;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-12-12 17:11:34 +01:00
|
|
|
orig_ip4_method = nm_utils_get_ip_config_method(orig, AF_INET);
|
|
|
|
|
candidate_ip4_method = nm_utils_get_ip_config_method(candidate, AF_INET);
|
2016-03-01 09:56:51 +01:00
|
|
|
candidate_ip4 = nm_connection_get_setting_ip4_config(candidate);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-12-12 17:11:34 +01:00
|
|
|
if (nm_streq(orig_ip4_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)
|
|
|
|
|
&& nm_streq(candidate_ip4_method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)
|
|
|
|
|
&& (!candidate_ip4 || nm_setting_ip_config_get_may_fail(candidate_ip4))
|
|
|
|
|
&& !device_has_carrier) {
|
|
|
|
|
/* 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.
|
|
|
|
|
*/
|
2016-03-01 09:56:51 +01:00
|
|
|
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
|
|
|
{
|
2021-11-09 13:28:54 +01:00
|
|
|
GHashTable *props;
|
|
|
|
|
const char *orig_ifname, *cand_ifname;
|
2016-03-01 09:56:51 +01:00
|
|
|
NMSettingConnection *s_con_orig, *s_con_cand;
|
2020-09-28 16:03:33 +02: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;
|
2020-09-28 16:03:33 +02: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);
|
2020-09-28 16:03:33 +02: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
|
|
|
{
|
2021-11-09 13:28:54 +01:00
|
|
|
GHashTable *props;
|
|
|
|
|
const char *orig_mac = NULL, *cand_mac = NULL;
|
2016-03-01 09:56:51 +01:00
|
|
|
NMSettingWired *s_wired_orig, *s_wired_cand;
|
2020-09-28 16:03:33 +02: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;
|
2020-09-28 16:03:33 +02: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);
|
2020-09-28 16:03:33 +02: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);
|
2020-09-28 16:03:33 +02: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,
|
2021-11-09 13:28:54 +01:00
|
|
|
GHashTable *settings)
|
2016-09-21 17:07:42 +02:00
|
|
|
{
|
2021-11-09 13:28:54 +01:00
|
|
|
GHashTable *props;
|
|
|
|
|
const char *orig_mac = NULL, *cand_mac = NULL;
|
2016-09-21 17:07:42 +02:00
|
|
|
NMSettingInfiniband *s_infiniband_orig, *s_infiniband_cand;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-09-21 17:07:42 +02:00
|
|
|
props = check_property_in_hash(settings,
|
|
|
|
|
NM_SETTING_INFINIBAND_SETTING_NAME,
|
|
|
|
|
NM_SETTING_INFINIBAND_MAC_ADDRESS);
|
|
|
|
|
if (!props)
|
|
|
|
|
return TRUE;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-09-21 17:07:42 +02:00
|
|
|
/* 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);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-09-21 17:07:42 +02:00
|
|
|
s_infiniband_cand = nm_connection_get_setting_infiniband(candidate);
|
|
|
|
|
if (s_infiniband_cand)
|
|
|
|
|
cand_mac = nm_setting_infiniband_get_mac_address(s_infiniband_cand);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-09-21 17:07:42 +02:00
|
|
|
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,
|
2021-11-09 13:28:54 +01:00
|
|
|
GHashTable *settings)
|
2015-08-06 17:06:42 +02:00
|
|
|
{
|
2021-11-09 13:28:54 +01:00
|
|
|
GHashTable *props;
|
|
|
|
|
const char *orig_mac = NULL, *cand_mac = NULL;
|
2016-03-01 09:56:51 +01:00
|
|
|
NMSettingWired *s_wired_orig, *s_wired_cand;
|
2020-09-28 16:03:33 +02: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;
|
2020-09-28 16:03:33 +02: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_cloned_mac_address(s_wired_orig);
|
2020-09-28 16:03:33 +02: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);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2017-05-05 14:11:05 +02:00
|
|
|
/* special cloned mac address entries are accepted. */
|
2023-11-14 11:56:30 +01:00
|
|
|
if (NM_CLONED_MAC_IS_SPECIAL(orig_mac, FALSE))
|
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
|
|
|
orig_mac = NULL;
|
2023-11-14 11:56:30 +01:00
|
|
|
if (NM_CLONED_MAC_IS_SPECIAL(cand_mac, FALSE))
|
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
|
|
|
cand_mac = NULL;
|
2020-09-28 16:03:33 +02: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_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
|
|
|
}
|
|
|
|
|
|
2023-07-04 12:50:29 +02:00
|
|
|
static gboolean
|
|
|
|
|
check_connection_controller(NMConnection *orig, NMConnection *candidate, GHashTable *settings)
|
|
|
|
|
{
|
|
|
|
|
GHashTable *props;
|
|
|
|
|
const char *orig_controller = NULL, *cand_controller = NULL;
|
|
|
|
|
NMSettingConnection *s_con_orig, *s_con_cand, *s_con_controller;
|
|
|
|
|
NMSettingsConnection *con_controller;
|
|
|
|
|
|
|
|
|
|
props = check_property_in_hash(settings,
|
|
|
|
|
NM_SETTING_CONNECTION_SETTING_NAME,
|
|
|
|
|
NM_SETTING_CONNECTION_MASTER);
|
|
|
|
|
if (!props)
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
|
|
s_con_orig = nm_connection_get_setting_connection(orig);
|
|
|
|
|
s_con_cand = nm_connection_get_setting_connection(candidate);
|
|
|
|
|
orig_controller = nm_setting_connection_get_master(s_con_orig);
|
|
|
|
|
cand_controller = nm_setting_connection_get_master(s_con_cand);
|
|
|
|
|
|
|
|
|
|
/* A generated connection uses the UUID to specify the controller. Accept
|
|
|
|
|
* candidates that specify as controller an interface name matching that
|
|
|
|
|
* UUID */
|
|
|
|
|
if (orig_controller && cand_controller) {
|
|
|
|
|
if (nm_utils_is_uuid(orig_controller)) {
|
|
|
|
|
con_controller = nm_settings_get_connection_by_uuid(NM_SETTINGS_GET, orig_controller);
|
|
|
|
|
/* no connection found for that uuid */
|
|
|
|
|
if (!con_controller)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
s_con_controller =
|
|
|
|
|
nm_settings_connection_get_setting(con_controller, NM_META_SETTING_TYPE_CONNECTION);
|
|
|
|
|
if (nm_streq0(nm_setting_connection_get_interface_name(s_con_controller),
|
|
|
|
|
cand_controller)) {
|
|
|
|
|
remove_from_hash(settings,
|
|
|
|
|
props,
|
|
|
|
|
NM_SETTING_CONNECTION_SETTING_NAME,
|
|
|
|
|
NM_SETTING_CONNECTION_MASTER);
|
|
|
|
|
return TRUE;
|
|
|
|
|
} else {
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
{
|
2021-11-09 13:28:54 +01:00
|
|
|
GHashTable *props1, *props2, *props3;
|
2016-03-01 09:56:51 +01:00
|
|
|
NMSettingWired *s_wired_orig, *s_wired_cand;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
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;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
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);
|
2021-11-09 13:28:54 +01:00
|
|
|
const char *nettype = nm_setting_wired_get_s390_nettype(s_wired_cand);
|
2016-03-01 09:56:51 +01:00
|
|
|
guint32 num_options = nm_setting_wired_get_num_s390_options(s_wired_cand);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
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,
|
2021-11-09 13:28:54 +01:00
|
|
|
GHashTable *settings,
|
2016-03-01 09:56:51 +01:00
|
|
|
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
|
|
|
|
2023-07-04 12:50:29 +02:00
|
|
|
if (!check_connection_controller(orig, candidate, settings))
|
|
|
|
|
return NULL;
|
|
|
|
|
|
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
|
|
|
|
2023-03-24 17:42:15 +00:00
|
|
|
/* match properties are for matching from static to generated connections,
|
|
|
|
|
* so they are not really part of the difference. */
|
|
|
|
|
g_hash_table_remove(settings, NM_SETTING_MATCH_SETTING_NAME);
|
|
|
|
|
|
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
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 *
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_utils_match_connection(NMConnection *const *connections,
|
|
|
|
|
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
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++) {
|
settings: use delegation instead of inheritance for NMSettingsConnection and NMConnection
NMConnection is an interface, which is implemented by the types
NMSimpleConnection (libnm-core), NMSettingsConnection (src) and
NMRemoteConnection (libnm).
NMSettingsConnection does a lot of things already:
1) it "is-a" NMDBusObject and exports the API of a connection profile
on D-Bus
2) it interacts with NMSettings and contains functionality
for tracking the profiles.
3) it is the base-class of types like NMSKeyfileConnection and
NMIfcfgConnection. These handle how the profile is persisted
on disk.
4) it implements NMConnection interface, to itself track the
settings of the profile.
3) and 4) would be better implemented via delegation than inheritance.
Address 4) and don't let NMSettingsConnection implemente the NMConnection
interface. Instead, a settings-connection references now a NMSimpleConnection
instance, to which it delegates for keeping the actual profiles.
Advantages:
- by delegating, there is a clearer separation of what
NMSettingsConnection does. For example, in C we often required
casts from NMSettingsConnection to NMConnection. NMConnection
is a very trivial object with very little logic. When we have
a NMConnection instance at hand, it's good to know that it is
*only* that simple instead of also being an entire
NMSettingsConnection instance.
The main purpose of this patch is to simplify the code by separating
the NMConnection from the NMSettingsConnection. We should generally
be aware whether we handle a NMSettingsConnection or a trivial
NMConnection instance. Now, because NMSettingsConnection no longer
"is-a" NMConnection, this distinction is apparent.
- NMConnection is implemented as an interface and we create
NMSimpleConnection instances whenever we need a real instance.
In GLib, interfaces have a performance overhead, that we needlessly
pay all the time. With this change, we no longer require
NMConnection to be an interface. Thus, in the future we could compile
a version of libnm-core for the daemon, where NMConnection is not an
interface but a GObject implementation akin to NMSimpleConnection.
- In the previous implementation, we cannot treat NMConnection immutable
and copy-on-write.
For example, when NMDevice needs a snapshot of the activated
profile as applied-connection, all it can do is clone the entire
NMSettingsConnection as a NMSimpleConnection.
Likewise, when we get a NMConnection instance and want to keep
a reference to it, we cannot do that, because we never know
who also references and modifies the instance.
By separating NMSettingsConnection we could in the future have
NMConnection immutable and copy-on-write, to avoid all unnecessary
clones.
2018-08-11 11:08:17 +02:00
|
|
|
NMConnection *candidate = *connections;
|
2021-11-09 13:28:54 +01:00
|
|
|
GHashTable *diffs = NULL;
|
2015-10-03 19:44:27 +02:00
|
|
|
|
settings: use delegation instead of inheritance for NMSettingsConnection and NMConnection
NMConnection is an interface, which is implemented by the types
NMSimpleConnection (libnm-core), NMSettingsConnection (src) and
NMRemoteConnection (libnm).
NMSettingsConnection does a lot of things already:
1) it "is-a" NMDBusObject and exports the API of a connection profile
on D-Bus
2) it interacts with NMSettings and contains functionality
for tracking the profiles.
3) it is the base-class of types like NMSKeyfileConnection and
NMIfcfgConnection. These handle how the profile is persisted
on disk.
4) it implements NMConnection interface, to itself track the
settings of the profile.
3) and 4) would be better implemented via delegation than inheritance.
Address 4) and don't let NMSettingsConnection implemente the NMConnection
interface. Instead, a settings-connection references now a NMSimpleConnection
instance, to which it delegates for keeping the actual profiles.
Advantages:
- by delegating, there is a clearer separation of what
NMSettingsConnection does. For example, in C we often required
casts from NMSettingsConnection to NMConnection. NMConnection
is a very trivial object with very little logic. When we have
a NMConnection instance at hand, it's good to know that it is
*only* that simple instead of also being an entire
NMSettingsConnection instance.
The main purpose of this patch is to simplify the code by separating
the NMConnection from the NMSettingsConnection. We should generally
be aware whether we handle a NMSettingsConnection or a trivial
NMConnection instance. Now, because NMSettingsConnection no longer
"is-a" NMConnection, this distinction is apparent.
- NMConnection is implemented as an interface and we create
NMSimpleConnection instances whenever we need a real instance.
In GLib, interfaces have a performance overhead, that we needlessly
pay all the time. With this change, we no longer require
NMConnection to be an interface. Thus, in the future we could compile
a version of libnm-core for the daemon, where NMConnection is not an
interface but a GObject implementation akin to NMSimpleConnection.
- In the previous implementation, we cannot treat NMConnection immutable
and copy-on-write.
For example, when NMDevice needs a snapshot of the activated
profile as applied-connection, all it can do is clone the entire
NMSettingsConnection as a NMSimpleConnection.
Likewise, when we get a NMConnection instance and want to keep
a reference to it, we cannot do that, because we never know
who also references and modifies the instance.
By separating NMSettingsConnection we could in the future have
NMConnection immutable and copy-on-write, to avoid all unnecessary
clones.
2018-08-11 11:08:17 +02:00
|
|
|
nm_assert(NM_IS_CONNECTION(candidate));
|
|
|
|
|
|
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
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;
|
2020-09-28 16:03:33 +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
2018-04-04 14:48:52 +02:00
|
|
|
/* 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);
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
if (!best_match && nm_logging_enabled(LOGL_DEBUG, LOGD_CORE)) {
|
2021-11-09 13:28:54 +01:00
|
|
|
GString *diff_string;
|
2016-03-01 09:56:51 +01:00
|
|
|
GHashTableIter s_iter, p_iter;
|
|
|
|
|
gpointer setting_name, setting;
|
|
|
|
|
gpointer property_name, value;
|
2020-09-28 16:03:33 +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);
|
|
|
|
|
}
|
2020-09-28 16:03:33 +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
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
g_hash_table_unref(diffs);
|
|
|
|
|
continue;
|
2015-10-03 19:44:27 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
/* Exact match */
|
|
|
|
|
return candidate;
|
2015-10-03 19:44:27 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +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
|
|
|
|
2023-06-12 12:11:54 +02:00
|
|
|
const struct _NMMatchSpecDeviceData *
|
|
|
|
|
nm_match_spec_device_data_init_from_device(struct _NMMatchSpecDeviceData *out_data,
|
|
|
|
|
NMDevice *device)
|
|
|
|
|
{
|
|
|
|
|
const char *hw_address;
|
|
|
|
|
gboolean is_fake;
|
|
|
|
|
|
|
|
|
|
nm_assert(out_data);
|
|
|
|
|
|
|
|
|
|
if (!device) {
|
|
|
|
|
*out_data = (NMMatchSpecDeviceData){};
|
|
|
|
|
return out_data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nm_assert(NM_IS_DEVICE(device));
|
|
|
|
|
|
|
|
|
|
hw_address = nm_device_get_permanent_hw_address_full(
|
|
|
|
|
device,
|
|
|
|
|
!nm_device_get_unmanaged_flags(device, NM_UNMANAGED_PLATFORM_INIT),
|
|
|
|
|
&is_fake);
|
|
|
|
|
|
|
|
|
|
/* Note that here we access various getters on @device, without cloning
|
|
|
|
|
* or taking ownership and return it to the caller.
|
|
|
|
|
*
|
|
|
|
|
* The returned data is only valid, until NMDevice gets modified again. */
|
|
|
|
|
|
|
|
|
|
*out_data = (NMMatchSpecDeviceData){
|
|
|
|
|
.interface_name = nm_device_get_iface(device),
|
|
|
|
|
.device_type = nm_device_get_type_description(device),
|
|
|
|
|
.driver = nm_device_get_driver(device),
|
|
|
|
|
.driver_version = nm_device_get_driver_version(device),
|
|
|
|
|
.hwaddr = is_fake ? NULL : hw_address,
|
|
|
|
|
.s390_subchannels = nm_device_get_s390_subchannels(device),
|
|
|
|
|
.dhcp_plugin = nm_dhcp_manager_get_config(nm_dhcp_manager_get()),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return out_data;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-12 12:32:46 +02:00
|
|
|
const NMMatchSpecDeviceData *
|
|
|
|
|
nm_match_spec_device_data_init_from_platform(NMMatchSpecDeviceData *out_data,
|
|
|
|
|
const NMPlatformLink *pllink,
|
|
|
|
|
const char *match_device_type,
|
|
|
|
|
const char *match_dhcp_plugin)
|
|
|
|
|
{
|
|
|
|
|
nm_assert(out_data);
|
|
|
|
|
|
|
|
|
|
/* we can only match by certain properties that are available on the
|
|
|
|
|
* platform link (and even @pllink might be missing.
|
|
|
|
|
*
|
|
|
|
|
* It's still useful because of specs like "*" and "except:interface-name:eth0",
|
|
|
|
|
* which match even in that case. */
|
|
|
|
|
|
|
|
|
|
*out_data = (NMMatchSpecDeviceData){
|
|
|
|
|
.interface_name = pllink ? pllink->name : NULL,
|
|
|
|
|
.device_type = match_device_type,
|
|
|
|
|
.driver = pllink ? pllink->driver : NULL,
|
|
|
|
|
.driver_version = NULL,
|
|
|
|
|
.hwaddr = NULL,
|
|
|
|
|
.s390_subchannels = NULL,
|
|
|
|
|
.dhcp_plugin = match_dhcp_plugin,
|
|
|
|
|
};
|
|
|
|
|
return out_data;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-12 12:11:54 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2017-12-13 15:10:11 +01:00
|
|
|
int
|
|
|
|
|
nm_match_spec_device_by_pllink(const NMPlatformLink *pllink,
|
2021-11-09 13:28:54 +01:00
|
|
|
const char *match_device_type,
|
|
|
|
|
const char *match_dhcp_plugin,
|
|
|
|
|
const GSList *specs,
|
2017-12-13 15:10:11 +01:00
|
|
|
int no_match_value)
|
|
|
|
|
{
|
2023-06-12 12:32:46 +02:00
|
|
|
NMMatchSpecMatchType m;
|
|
|
|
|
NMMatchSpecDeviceData data;
|
2017-12-13 15:10:11 +01:00
|
|
|
|
|
|
|
|
m = nm_match_spec_device(specs,
|
2023-06-12 12:32:46 +02:00
|
|
|
nm_match_spec_device_data_init_from_platform(&data,
|
|
|
|
|
pllink,
|
|
|
|
|
match_device_type,
|
|
|
|
|
match_dhcp_plugin));
|
2023-06-08 14:35:46 +02:00
|
|
|
return nm_match_spec_match_type_to_bool(m, no_match_value);
|
2017-12-13 15:10:11 +01:00
|
|
|
}
|
|
|
|
|
|
2018-05-18 13:06:03 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2019-03-23 15:09:29 +01:00
|
|
|
NMPlatformRoutingRule *
|
|
|
|
|
nm_ip_routing_rule_to_platform(const NMIPRoutingRule *rule, NMPlatformRoutingRule *out_pl)
|
|
|
|
|
{
|
2021-03-19 07:45:09 +01:00
|
|
|
gboolean uid_range_has;
|
|
|
|
|
guint32 uid_range_start = 0;
|
|
|
|
|
guint32 uid_range_end = 0;
|
|
|
|
|
|
2019-03-23 15:09:29 +01:00
|
|
|
nm_assert(rule);
|
|
|
|
|
nm_assert(nm_ip_routing_rule_validate(rule, NULL));
|
|
|
|
|
nm_assert(out_pl);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-03-19 07:45:09 +01:00
|
|
|
uid_range_has = nm_ip_routing_rule_get_uid_range(rule, &uid_range_start, &uid_range_end);
|
|
|
|
|
|
2019-03-23 15:09:29 +01:00
|
|
|
*out_pl = (NMPlatformRoutingRule){
|
2019-07-11 18:54:48 +02:00
|
|
|
.addr_family = nm_ip_routing_rule_get_addr_family(rule),
|
|
|
|
|
.flags = (nm_ip_routing_rule_get_invert(rule) ? FIB_RULE_INVERT : 0),
|
|
|
|
|
.priority = nm_ip_routing_rule_get_priority(rule),
|
|
|
|
|
.tos = nm_ip_routing_rule_get_tos(rule),
|
|
|
|
|
.ip_proto = nm_ip_routing_rule_get_ipproto(rule),
|
|
|
|
|
.fwmark = nm_ip_routing_rule_get_fwmark(rule),
|
|
|
|
|
.fwmask = nm_ip_routing_rule_get_fwmask(rule),
|
|
|
|
|
.sport_range =
|
|
|
|
|
{
|
|
|
|
|
.start = nm_ip_routing_rule_get_source_port_start(rule),
|
|
|
|
|
.end = nm_ip_routing_rule_get_source_port_end(rule),
|
2019-03-23 15:09:29 +01:00
|
|
|
},
|
2019-07-11 18:54:48 +02:00
|
|
|
.dport_range =
|
|
|
|
|
{
|
|
|
|
|
.start = nm_ip_routing_rule_get_destination_port_start(rule),
|
|
|
|
|
.end = nm_ip_routing_rule_get_destination_port_end(rule),
|
2019-03-23 15:09:29 +01:00
|
|
|
},
|
2019-07-11 18:54:48 +02:00
|
|
|
.src = *(nm_ip_routing_rule_get_from_bin(rule) ?: &nm_ip_addr_zero),
|
|
|
|
|
.dst = *(nm_ip_routing_rule_get_to_bin(rule) ?: &nm_ip_addr_zero),
|
|
|
|
|
.src_len = nm_ip_routing_rule_get_from_len(rule),
|
|
|
|
|
.dst_len = nm_ip_routing_rule_get_to_len(rule),
|
|
|
|
|
.action = nm_ip_routing_rule_get_action(rule),
|
|
|
|
|
.table = nm_ip_routing_rule_get_table(rule),
|
|
|
|
|
.suppress_prefixlen_inverse =
|
|
|
|
|
~((guint32) nm_ip_routing_rule_get_suppress_prefixlength(rule)),
|
2021-03-19 07:45:09 +01:00
|
|
|
.uid_range_has = uid_range_has,
|
|
|
|
|
.uid_range =
|
|
|
|
|
{
|
|
|
|
|
.start = uid_range_start,
|
|
|
|
|
.end = uid_range_end,
|
|
|
|
|
},
|
2022-11-11 15:27:38 +01:00
|
|
|
.protocol = RTPROT_STATIC,
|
2019-03-23 15:09:29 +01:00
|
|
|
};
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2019-03-23 15:09:29 +01:00
|
|
|
nm_ip_routing_rule_get_xifname_bin(rule, TRUE, out_pl->iifname);
|
|
|
|
|
nm_ip_routing_rule_get_xifname_bin(rule, FALSE, out_pl->oifname);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2019-03-23 15:09:29 +01:00
|
|
|
return out_pl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2018-05-18 13:06:03 +02:00
|
|
|
struct _NMShutdownWaitObjHandle {
|
|
|
|
|
CList lst;
|
2019-08-23 07:45:41 +02:00
|
|
|
gpointer watched_obj;
|
2021-11-09 13:28:54 +01:00
|
|
|
char *msg_reason;
|
2019-06-20 07:31:29 +02:00
|
|
|
bool free_msg_reason : 1;
|
2019-08-23 07:45:41 +02:00
|
|
|
bool is_cancellable : 1;
|
2018-05-18 13:06:03 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static CList _shutdown_waitobj_lst_head;
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_shutdown_waitobj_unregister(NMShutdownWaitObjHandle *handle)
|
|
|
|
|
{
|
|
|
|
|
c_list_unlink_stale(&handle->lst);
|
2019-06-20 07:31:29 +02:00
|
|
|
if (handle->free_msg_reason)
|
|
|
|
|
g_free(handle->msg_reason);
|
2018-05-18 13:06:03 +02:00
|
|
|
g_slice_free(NMShutdownWaitObjHandle, handle);
|
|
|
|
|
|
|
|
|
|
/* FIXME(shutdown): check whether the object list is empty, and
|
|
|
|
|
* signal shutdown-complete */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_shutdown_waitobj_cb(gpointer user_data, GObject *where_the_object_was)
|
|
|
|
|
{
|
|
|
|
|
NMShutdownWaitObjHandle *handle = user_data;
|
|
|
|
|
|
|
|
|
|
nm_assert(handle);
|
|
|
|
|
nm_assert(handle->watched_obj == where_the_object_was);
|
|
|
|
|
_shutdown_waitobj_unregister(handle);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2019-06-20 07:31:29 +02:00
|
|
|
* nm_shutdown_wait_obj_register_full:
|
2018-05-18 13:06:03 +02:00
|
|
|
* @watched_obj: the object to watch. Takes a weak reference on the object
|
|
|
|
|
* to be notified when it gets destroyed.
|
2019-08-31 11:33:15 +02:00
|
|
|
* If wait_type is %NM_SHUTDOWN_WAIT_TYPE_HANDLE, this must be %NULL.
|
2019-08-23 07:45:41 +02:00
|
|
|
* @wait_type: whether @watched_obj is just a plain GObject or a GCancellable
|
|
|
|
|
* that should be cancelled.
|
2019-06-20 07:31:29 +02:00
|
|
|
* @msg_reason: a reason message, for debugging and logging purposes.
|
|
|
|
|
* @free_msg_reason: if %TRUE, then ownership of @msg_reason will be taken
|
|
|
|
|
* and the string will be freed with g_free() afterwards. If %FALSE,
|
|
|
|
|
* the caller must ensure that @msg_reason string outlives the watched
|
|
|
|
|
* objects (e.g. being a static strings).
|
2018-05-18 13:06:03 +02:00
|
|
|
*
|
|
|
|
|
* Keep track of @watched_obj until it gets destroyed. During shutdown,
|
|
|
|
|
* we wait until all watched objects are destroyed. This is useful, if
|
|
|
|
|
* this object still conducts some asynchronous action, which needs to
|
|
|
|
|
* complete before NetworkManager is allowed to terminate. We re-use
|
|
|
|
|
* the reference-counter of @watched_obj as signal, that the object
|
|
|
|
|
* is still used.
|
|
|
|
|
*
|
2019-08-23 07:45:41 +02:00
|
|
|
* If @wait_type is %NM_SHUTDOWN_WAIT_TYPE_CANCELLABLE, then during shutdown
|
2022-02-18 13:18:47 +01:00
|
|
|
* (after %NM_SHUTDOWN_TIMEOUT_MAX_MSEC), the cancellable will be cancelled to notify
|
2019-08-23 07:45:41 +02:00
|
|
|
* the source of the shutdown. Note that otherwise, in this mode also @watched_obj
|
|
|
|
|
* is only tracked with a weak-pointer. Especially, it does not register to the
|
|
|
|
|
* "cancelled" signal to automatically unregister (otherwise, you would never
|
|
|
|
|
* know whether the returned NMShutdownWaitObjHandle is still valid.
|
|
|
|
|
*
|
2018-05-18 13:06:03 +02:00
|
|
|
* FIXME(shutdown): proper shutdown is not yet implemented, and registering
|
|
|
|
|
* an object (currently) has no effect.
|
|
|
|
|
*
|
2022-02-18 13:18:47 +01:00
|
|
|
* FIXME(shutdown): during shutdown, after %NM_SHUTDOWN_TIMEOUT_MAX_MSEC timeout, cancel
|
2019-08-23 07:45:41 +02:00
|
|
|
* all remaining %NM_SHUTDOWN_WAIT_TYPE_CANCELLABLE instances. Also, when somebody
|
|
|
|
|
* enqueues a cancellable after that point, cancel it right away on an idle handler.
|
|
|
|
|
*
|
2018-05-18 13:06:03 +02:00
|
|
|
* Returns: a handle to unregister the object. The caller may choose to ignore
|
|
|
|
|
* the handle, in which case, the object will be automatically unregistered,
|
|
|
|
|
* once it gets destroyed.
|
2019-08-23 07:45:41 +02:00
|
|
|
* Note that the handle is only valid as long as @watched_obj exists. If
|
|
|
|
|
* you plan to use it, ensure that you take care of not using it after
|
|
|
|
|
* destroying @watched_obj.
|
2018-05-18 13:06:03 +02:00
|
|
|
*/
|
|
|
|
|
NMShutdownWaitObjHandle *
|
2019-08-23 07:45:41 +02:00
|
|
|
nm_shutdown_wait_obj_register_full(gpointer watched_obj,
|
|
|
|
|
NMShutdownWaitType wait_type,
|
2021-11-09 13:28:54 +01:00
|
|
|
char *msg_reason,
|
2019-06-20 07:31:29 +02:00
|
|
|
gboolean free_msg_reason)
|
2018-05-18 13:06:03 +02:00
|
|
|
{
|
|
|
|
|
NMShutdownWaitObjHandle *handle;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2019-08-23 07:45:41 +02:00
|
|
|
if (wait_type == NM_SHUTDOWN_WAIT_TYPE_OBJECT)
|
|
|
|
|
g_return_val_if_fail(G_IS_OBJECT(watched_obj), NULL);
|
|
|
|
|
else if (wait_type == NM_SHUTDOWN_WAIT_TYPE_CANCELLABLE)
|
|
|
|
|
g_return_val_if_fail(G_IS_CANCELLABLE(watched_obj), NULL);
|
2019-08-31 11:33:15 +02:00
|
|
|
else if (wait_type == NM_SHUTDOWN_WAIT_TYPE_HANDLE)
|
|
|
|
|
g_return_val_if_fail(!watched_obj, NULL);
|
2019-08-23 07:45:41 +02:00
|
|
|
else
|
|
|
|
|
g_return_val_if_reached(NULL);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2018-05-18 13:06:03 +02:00
|
|
|
if (G_UNLIKELY(!_shutdown_waitobj_lst_head.next))
|
|
|
|
|
c_list_init(&_shutdown_waitobj_lst_head);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-06-15 18:09:55 +02:00
|
|
|
/* Beware: there are callers with g_main_context_get_thread_default()
|
|
|
|
|
* not being g_main_context_get_default(). For example _fw_nft_call().
|
|
|
|
|
*
|
|
|
|
|
* If you schedule any sources or async operations, you probably need to
|
|
|
|
|
* make sure to use the default context. */
|
|
|
|
|
|
2018-05-18 13:06:03 +02:00
|
|
|
handle = g_slice_new(NMShutdownWaitObjHandle);
|
2019-06-20 07:31:29 +02:00
|
|
|
*handle = (NMShutdownWaitObjHandle){
|
|
|
|
|
/* depending on @free_msg_reason, we take ownership of @msg_reason.
|
|
|
|
|
* In either case, we just reference the string without cloning
|
|
|
|
|
* it. */
|
|
|
|
|
.watched_obj = watched_obj,
|
|
|
|
|
.msg_reason = msg_reason,
|
|
|
|
|
.free_msg_reason = free_msg_reason,
|
2019-08-23 07:45:41 +02:00
|
|
|
.is_cancellable = (wait_type == NM_SHUTDOWN_WAIT_TYPE_CANCELLABLE),
|
2019-06-20 07:31:29 +02:00
|
|
|
};
|
2018-05-18 13:06:03 +02:00
|
|
|
c_list_link_tail(&_shutdown_waitobj_lst_head, &handle->lst);
|
2019-08-31 11:33:15 +02:00
|
|
|
if (watched_obj)
|
|
|
|
|
g_object_weak_ref(watched_obj, _shutdown_waitobj_cb, handle);
|
2018-05-18 13:06:03 +02:00
|
|
|
return handle;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_shutdown_wait_obj_unregister(NMShutdownWaitObjHandle *handle)
|
|
|
|
|
{
|
|
|
|
|
g_return_if_fail(handle);
|
|
|
|
|
|
2019-08-31 11:33:15 +02:00
|
|
|
nm_assert(!handle->watched_obj || G_IS_OBJECT(handle->watched_obj));
|
2018-05-18 13:06:03 +02:00
|
|
|
nm_assert(nm_c_list_contains_entry(&_shutdown_waitobj_lst_head, handle, lst));
|
|
|
|
|
|
2019-08-31 11:33:15 +02:00
|
|
|
if (handle->watched_obj)
|
|
|
|
|
g_object_weak_unref(handle->watched_obj, _shutdown_waitobj_cb, handle);
|
2018-05-18 13:06:03 +02:00
|
|
|
_shutdown_waitobj_unregister(handle);
|
|
|
|
|
}
|
2018-10-19 10:21:53 +02:00
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_utils_file_is_in_path:
|
|
|
|
|
* @abs_filename: the absolute filename to test
|
|
|
|
|
* @abs_path: the absolute path, to check whether filename is in.
|
|
|
|
|
*
|
|
|
|
|
* This tests, whether @abs_filename is a file which lies inside @abs_path.
|
|
|
|
|
* Basically, this checks whether @abs_filename is the same as @abs_path +
|
|
|
|
|
* basename(@abs_filename). It allows simple normalizations, like coalescing
|
|
|
|
|
* multiple "//".
|
|
|
|
|
*
|
|
|
|
|
* However, beware that this function is purely filename based. That means,
|
|
|
|
|
* it will reject files that reference the same file (i.e. inode) via
|
|
|
|
|
* symlinks or bind mounts. Maybe one would like to check for file (inode)
|
|
|
|
|
* identity, but that is not really possible based on the file name alone.
|
|
|
|
|
*
|
|
|
|
|
* This means, that nm_utils_file_is_in_path("/var/run/some-file", "/var/run")
|
|
|
|
|
* will succeed, but nm_utils_file_is_in_path("/run/some-file", "/var/run")
|
|
|
|
|
* will not (although, it's well known that they reference the same path).
|
|
|
|
|
*
|
|
|
|
|
* Also, note that @abs_filename must not have trailing slashes itself.
|
|
|
|
|
* So, this will reject nm_utils_file_is_in_path("/usr/lib/", "/usr") as
|
|
|
|
|
* invalid, because the function searches for file names (and "lib/" is
|
|
|
|
|
* clearly a directory).
|
|
|
|
|
*
|
|
|
|
|
* Returns: if @abs_filename is a file inside @abs_path, returns the
|
2020-07-01 17:20:40 -04:00
|
|
|
* trailing part of @abs_filename which is the filename. Otherwise,
|
2018-10-19 10:21:53 +02:00
|
|
|
* %NULL.
|
|
|
|
|
*/
|
|
|
|
|
const char *
|
|
|
|
|
nm_utils_file_is_in_path(const char *abs_filename, const char *abs_path)
|
|
|
|
|
{
|
|
|
|
|
const char *path;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail(abs_filename && abs_filename[0] == '/', NULL);
|
|
|
|
|
g_return_val_if_fail(abs_path && abs_path[0] == '/', NULL);
|
|
|
|
|
|
2022-04-12 16:26:47 +02:00
|
|
|
path = nm_path_startswith(abs_filename, abs_path);
|
2018-10-19 10:21:53 +02:00
|
|
|
if (!path)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
nm_assert(path[0] != '/');
|
|
|
|
|
nm_assert(path > abs_filename);
|
|
|
|
|
nm_assert(path <= &abs_filename[strlen(abs_filename)]);
|
|
|
|
|
|
|
|
|
|
/* we require a non-empty remainder with no slashes. That is, only a filename.
|
|
|
|
|
*
|
|
|
|
|
* Note this will reject "/var/run/" as not being in "/var",
|
|
|
|
|
* while "/var/run" would pass. The function searches for files
|
|
|
|
|
* only, so a trailing slash (indicating a directory) is not allowed).
|
|
|
|
|
* This is despite that the function cannot determine whether "/var/run"
|
|
|
|
|
* is itself a file or a directory. "*/
|
|
|
|
|
return path[0] && !strchr(path, '/') ? path : NULL;
|
|
|
|
|
}
|
2020-05-13 13:57:35 +02:00
|
|
|
|
|
|
|
|
/* The returned qdisc array is valid as long as s_tc is not modified */
|
|
|
|
|
GPtrArray *
|
|
|
|
|
nm_utils_qdiscs_from_tc_setting(NMPlatform *platform, NMSettingTCConfig *s_tc, int ip_ifindex)
|
|
|
|
|
{
|
|
|
|
|
GPtrArray *qdiscs;
|
|
|
|
|
guint nqdiscs;
|
|
|
|
|
guint i;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-05-13 13:57:35 +02:00
|
|
|
nqdiscs = nm_setting_tc_config_get_num_qdiscs(s_tc);
|
|
|
|
|
qdiscs = g_ptr_array_new_full(nqdiscs, (GDestroyNotify) nmp_object_unref);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-05-13 13:57:35 +02:00
|
|
|
for (i = 0; i < nqdiscs; i++) {
|
2021-11-09 13:28:54 +01:00
|
|
|
NMTCQdisc *s_qdisc = nm_setting_tc_config_get_qdisc(s_tc, i);
|
|
|
|
|
NMPObject *q = nmp_object_new(NMP_OBJECT_TYPE_QDISC, NULL);
|
2020-05-13 13:57:35 +02:00
|
|
|
NMPlatformQdisc *qdisc = NMP_OBJECT_CAST_QDISC(q);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-05-13 13:57:35 +02:00
|
|
|
qdisc->ifindex = ip_ifindex;
|
|
|
|
|
qdisc->kind = nm_tc_qdisc_get_kind(s_qdisc);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-05-13 13:57:35 +02:00
|
|
|
qdisc->addr_family = AF_UNSPEC;
|
|
|
|
|
qdisc->handle = nm_tc_qdisc_get_handle(s_qdisc);
|
|
|
|
|
qdisc->parent = nm_tc_qdisc_get_parent(s_qdisc);
|
|
|
|
|
qdisc->info = 0;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-05-13 13:57:35 +02:00
|
|
|
#define GET_ATTR(name, dst, variant_type, type, dflt) \
|
|
|
|
|
G_STMT_START \
|
|
|
|
|
{ \
|
|
|
|
|
GVariant *_variant = nm_tc_qdisc_get_attribute(s_qdisc, "" name ""); \
|
|
|
|
|
\
|
|
|
|
|
if (_variant && g_variant_is_of_type(_variant, G_VARIANT_TYPE_##variant_type)) \
|
|
|
|
|
(dst) = g_variant_get_##type(_variant); \
|
|
|
|
|
else \
|
|
|
|
|
(dst) = (dflt); \
|
|
|
|
|
} \
|
|
|
|
|
G_STMT_END
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-05-13 13:57:35 +02:00
|
|
|
if (strcmp(qdisc->kind, "fq_codel") == 0) {
|
|
|
|
|
GET_ATTR("limit", qdisc->fq_codel.limit, UINT32, uint32, 0);
|
|
|
|
|
GET_ATTR("flows", qdisc->fq_codel.flows, UINT32, uint32, 0);
|
|
|
|
|
GET_ATTR("target", qdisc->fq_codel.target, UINT32, uint32, 0);
|
|
|
|
|
GET_ATTR("interval", qdisc->fq_codel.interval, UINT32, uint32, 0);
|
|
|
|
|
GET_ATTR("quantum", qdisc->fq_codel.quantum, UINT32, uint32, 0);
|
|
|
|
|
GET_ATTR("ce_threshold",
|
|
|
|
|
qdisc->fq_codel.ce_threshold,
|
|
|
|
|
UINT32,
|
|
|
|
|
uint32,
|
|
|
|
|
NM_PLATFORM_FQ_CODEL_CE_THRESHOLD_DISABLED);
|
|
|
|
|
GET_ATTR("memory_limit",
|
|
|
|
|
qdisc->fq_codel.memory_limit,
|
|
|
|
|
UINT32,
|
|
|
|
|
uint32,
|
|
|
|
|
NM_PLATFORM_FQ_CODEL_MEMORY_LIMIT_UNSET);
|
|
|
|
|
GET_ATTR("ecn", qdisc->fq_codel.ecn, BOOLEAN, boolean, FALSE);
|
2020-04-30 09:19:55 +02:00
|
|
|
} else if (nm_streq(qdisc->kind, "sfq")) {
|
|
|
|
|
GET_ATTR("limit", qdisc->sfq.limit, UINT32, uint32, 0);
|
|
|
|
|
GET_ATTR("flows", qdisc->sfq.flows, UINT32, uint32, 0);
|
|
|
|
|
GET_ATTR("divisor", qdisc->sfq.divisor, UINT32, uint32, 0);
|
|
|
|
|
GET_ATTR("perturb", qdisc->sfq.perturb_period, INT32, int32, 0);
|
|
|
|
|
GET_ATTR("quantum", qdisc->sfq.quantum, UINT32, uint32, 0);
|
|
|
|
|
GET_ATTR("depth", qdisc->sfq.depth, UINT32, uint32, 0);
|
2020-05-08 19:11:44 +02:00
|
|
|
} else if (nm_streq(qdisc->kind, "tbf")) {
|
|
|
|
|
GET_ATTR("rate", qdisc->tbf.rate, UINT64, uint64, 0);
|
|
|
|
|
GET_ATTR("burst", qdisc->tbf.burst, UINT32, uint32, 0);
|
|
|
|
|
GET_ATTR("limit", qdisc->tbf.limit, UINT32, uint32, 0);
|
|
|
|
|
GET_ATTR("latency", qdisc->tbf.latency, UINT32, uint32, 0);
|
2020-05-13 13:57:35 +02:00
|
|
|
}
|
2020-07-22 10:33:16 +02:00
|
|
|
#undef GET_ATTR
|
2020-05-13 13:57:35 +02:00
|
|
|
|
|
|
|
|
g_ptr_array_add(qdiscs, q);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return qdiscs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* The returned tfilter array is valid as long as s_tc is not modified */
|
|
|
|
|
GPtrArray *
|
|
|
|
|
nm_utils_tfilters_from_tc_setting(NMPlatform *platform, NMSettingTCConfig *s_tc, int ip_ifindex)
|
|
|
|
|
{
|
|
|
|
|
GPtrArray *tfilters;
|
|
|
|
|
guint ntfilters;
|
|
|
|
|
guint i;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-05-13 13:57:35 +02:00
|
|
|
ntfilters = nm_setting_tc_config_get_num_tfilters(s_tc);
|
|
|
|
|
tfilters = g_ptr_array_new_full(ntfilters, (GDestroyNotify) nmp_object_unref);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-05-13 13:57:35 +02:00
|
|
|
for (i = 0; i < ntfilters; i++) {
|
2021-11-09 13:28:54 +01:00
|
|
|
NMTCTfilter *s_tfilter = nm_setting_tc_config_get_tfilter(s_tc, i);
|
|
|
|
|
NMTCAction *action;
|
|
|
|
|
NMPObject *t = nmp_object_new(NMP_OBJECT_TYPE_TFILTER, NULL);
|
2020-05-13 13:57:35 +02:00
|
|
|
NMPlatformTfilter *tfilter = NMP_OBJECT_CAST_TFILTER(t);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-05-13 13:57:35 +02:00
|
|
|
tfilter->ifindex = ip_ifindex;
|
|
|
|
|
tfilter->kind = nm_tc_tfilter_get_kind(s_tfilter);
|
|
|
|
|
tfilter->addr_family = AF_UNSPEC;
|
|
|
|
|
tfilter->handle = nm_tc_tfilter_get_handle(s_tfilter);
|
|
|
|
|
tfilter->parent = nm_tc_tfilter_get_parent(s_tfilter);
|
|
|
|
|
tfilter->info = TC_H_MAKE(0, htons(ETH_P_ALL));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-05-13 13:57:35 +02:00
|
|
|
action = nm_tc_tfilter_get_action(s_tfilter);
|
|
|
|
|
if (action) {
|
|
|
|
|
GVariant *var;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-05-13 13:57:35 +02:00
|
|
|
tfilter->action.kind = nm_tc_action_get_kind(action);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-05-13 13:57:35 +02:00
|
|
|
if (strcmp(tfilter->action.kind, "simple") == 0) {
|
|
|
|
|
var = nm_tc_action_get_attribute(action, "sdata");
|
|
|
|
|
if (var && g_variant_is_of_type(var, G_VARIANT_TYPE_BYTESTRING)) {
|
|
|
|
|
g_strlcpy(tfilter->action.simple.sdata,
|
|
|
|
|
g_variant_get_bytestring(var),
|
|
|
|
|
sizeof(tfilter->action.simple.sdata));
|
|
|
|
|
}
|
|
|
|
|
} else if (strcmp(tfilter->action.kind, "mirred") == 0) {
|
|
|
|
|
if (nm_tc_action_get_attribute(action, "egress"))
|
|
|
|
|
tfilter->action.mirred.egress = TRUE;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-05-13 13:57:35 +02:00
|
|
|
if (nm_tc_action_get_attribute(action, "ingress"))
|
|
|
|
|
tfilter->action.mirred.ingress = TRUE;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-05-13 13:57:35 +02:00
|
|
|
if (nm_tc_action_get_attribute(action, "mirror"))
|
|
|
|
|
tfilter->action.mirred.mirror = TRUE;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-05-13 13:57:35 +02:00
|
|
|
if (nm_tc_action_get_attribute(action, "redirect"))
|
|
|
|
|
tfilter->action.mirred.redirect = TRUE;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-05-13 13:57:35 +02:00
|
|
|
var = nm_tc_action_get_attribute(action, "dev");
|
|
|
|
|
if (var && g_variant_is_of_type(var, G_VARIANT_TYPE_STRING)) {
|
|
|
|
|
int ifindex;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-05-13 13:57:35 +02:00
|
|
|
ifindex =
|
|
|
|
|
nm_platform_link_get_ifindex(platform, g_variant_get_string(var, NULL));
|
|
|
|
|
if (ifindex > 0)
|
|
|
|
|
tfilter->action.mirred.ifindex = ifindex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-05-13 13:57:35 +02:00
|
|
|
g_ptr_array_add(tfilters, t);
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-05-13 13:57:35 +02:00
|
|
|
return tfilters;
|
|
|
|
|
}
|
2020-07-22 10:33:16 +02:00
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_utils_ip_route_attribute_to_platform(int addr_family,
|
2021-11-09 13:28:54 +01:00
|
|
|
NMIPRoute *s_route,
|
2020-07-22 10:33:16 +02:00
|
|
|
NMPlatformIPRoute *r,
|
2021-08-06 15:17:05 +02:00
|
|
|
gint64 route_table)
|
2020-07-22 10:33:16 +02:00
|
|
|
{
|
2022-02-03 22:52:55 +01:00
|
|
|
const int IS_IPv4 = NM_IS_IPv4(addr_family);
|
2021-11-09 13:28:54 +01:00
|
|
|
GVariant *variant;
|
2020-07-22 10:33:16 +02:00
|
|
|
guint32 table;
|
|
|
|
|
NMIPAddr addr;
|
|
|
|
|
NMPlatformIP4Route *r4 = (NMPlatformIP4Route *) r;
|
|
|
|
|
NMPlatformIP6Route *r6 = (NMPlatformIP6Route *) r;
|
|
|
|
|
gboolean onlink;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-22 10:33:16 +02:00
|
|
|
nm_assert(s_route);
|
2022-02-03 22:52:55 +01:00
|
|
|
nm_assert(addr_family == nm_ip_route_get_family(s_route));
|
2020-07-22 10:33:16 +02:00
|
|
|
nm_assert(r);
|
2021-08-06 15:17:05 +02:00
|
|
|
nm_assert(route_table >= -1);
|
|
|
|
|
nm_assert(route_table <= (gint64) G_MAXUINT32);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-22 10:33:16 +02:00
|
|
|
#define GET_ATTR(name, dst, variant_type, type, dflt) \
|
|
|
|
|
G_STMT_START \
|
|
|
|
|
{ \
|
|
|
|
|
GVariant *_variant = nm_ip_route_get_attribute(s_route, "" name ""); \
|
|
|
|
|
\
|
|
|
|
|
if (_variant && g_variant_is_of_type(_variant, G_VARIANT_TYPE_##variant_type)) \
|
|
|
|
|
(dst) = g_variant_get_##type(_variant); \
|
|
|
|
|
else \
|
|
|
|
|
(dst) = (dflt); \
|
|
|
|
|
} \
|
|
|
|
|
G_STMT_END
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-22 10:33:16 +02:00
|
|
|
if ((variant = nm_ip_route_get_attribute(s_route, NM_IP_ROUTE_ATTRIBUTE_TYPE))
|
|
|
|
|
&& g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING)) {
|
2021-03-19 10:46:41 +01:00
|
|
|
int type;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-03-19 10:46:41 +01:00
|
|
|
type = nm_net_aux_rtnl_rtntype_a2n(g_variant_get_string(variant, NULL));
|
2022-02-25 21:01:04 +01:00
|
|
|
nm_assert(NM_IN_SET(type,
|
|
|
|
|
RTN_UNICAST,
|
|
|
|
|
RTN_LOCAL,
|
|
|
|
|
RTN_BLACKHOLE,
|
|
|
|
|
RTN_UNREACHABLE,
|
|
|
|
|
RTN_PROHIBIT,
|
|
|
|
|
RTN_THROW));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-22 10:33:16 +02:00
|
|
|
r->type_coerced = nm_platform_route_type_coerce(type);
|
|
|
|
|
} else
|
|
|
|
|
r->type_coerced = nm_platform_route_type_coerce(RTN_UNICAST);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-22 10:33:16 +02:00
|
|
|
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_TABLE, table, UINT32, uint32, 0);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
if (table != 0)
|
|
|
|
|
r->table_coerced = nm_platform_route_table_coerce(table);
|
|
|
|
|
else if (r->type_coerced == nm_platform_route_type_coerce(RTN_LOCAL))
|
2020-07-22 10:33:16 +02:00
|
|
|
r->table_coerced = nm_platform_route_table_coerce(RT_TABLE_LOCAL);
|
2021-08-06 15:17:05 +02:00
|
|
|
else if (route_table == 0)
|
|
|
|
|
r->table_coerced = nm_platform_route_table_coerce(RT_TABLE_MAIN);
|
|
|
|
|
else if (route_table > 0)
|
|
|
|
|
r->table_coerced = nm_platform_route_table_coerce(route_table);
|
2020-07-22 10:33:16 +02:00
|
|
|
else
|
2021-08-06 15:17:05 +02:00
|
|
|
r->table_any = TRUE;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2022-02-03 22:52:55 +01:00
|
|
|
if (IS_IPv4) {
|
2020-07-22 10:33:16 +02:00
|
|
|
guint8 scope;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-22 10:33:16 +02:00
|
|
|
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_TOS, r4->tos, BYTE, byte, 0);
|
|
|
|
|
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_SCOPE, scope, BYTE, byte, RT_SCOPE_NOWHERE);
|
libnm,platform: fix range for "weight" property of next hops for routes
In kernel, the valid range for the weight is 1-256 (on netlink this is
expressed as u8 in rtnh_hops, ranging 0-255).
We need an additional value, to represent
- unset weight, for non-ECMP routes in kernel.
- in libnm API, to express routes that should not be merged as ECMP
routes (the default).
Extend the type in NMPlatformIP4Route.weight to u16, and fix the code
for the special handling of the numeric range.
Also the libnm API needs to change. Modify the type of the attribute on
D-Bus from "b" to "u", to use a 32 bit integer. We use 32 bit, because
we already have common code to handle 32 bit unsigned integers, despite
only requiring 257 values. It seems better to stick to a few data types
(u32) instead of introducing more, only because the range is limited.
Co-Authored-By: Fernando Fernandez Mancera <ffmancera@riseup.net>
Fixes: 1bbdecf5e125 ('platform: manage ECMP routes')
2022-12-24 21:50:38 +01:00
|
|
|
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_WEIGHT, r4->weight, UINT32, uint32, 0);
|
2020-07-22 10:33:16 +02:00
|
|
|
r4->scope_inv = nm_platform_route_scope_inv(scope);
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2023-02-01 08:58:15 +01:00
|
|
|
/* Note that for IPv4 routes in kernel, the onlink flag can be set for
|
|
|
|
|
* each next hop separately (rtnh_flags). Not for NetworkManager. We can
|
|
|
|
|
* only merge routes as ECMP routes (when setting a weight) if they all
|
|
|
|
|
* share the same onlink flag. See NM_PLATFORM_IP_ROUTE_CMP_TYPE_ECMP_ID.
|
|
|
|
|
* That simplifies the code. */
|
2020-07-22 10:33:16 +02:00
|
|
|
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_ONLINK, onlink, BOOLEAN, boolean, FALSE);
|
|
|
|
|
r->r_rtm_flags = ((onlink) ? (unsigned) RTNH_F_ONLINK : 0u);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2022-06-23 22:01:12 +02:00
|
|
|
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_ADVMSS, r->mss, UINT32, uint32, 0);
|
2020-07-22 10:33:16 +02:00
|
|
|
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_WINDOW, r->window, UINT32, uint32, 0);
|
|
|
|
|
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_CWND, r->cwnd, UINT32, uint32, 0);
|
|
|
|
|
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_INITCWND, r->initcwnd, UINT32, uint32, 0);
|
|
|
|
|
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_INITRWND, r->initrwnd, UINT32, uint32, 0);
|
|
|
|
|
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_MTU, r->mtu, UINT32, uint32, 0);
|
2022-06-23 22:01:12 +02:00
|
|
|
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_RTO_MIN, r->rto_min, UINT32, uint32, 0);
|
|
|
|
|
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_QUICKACK, r->quickack, BOOLEAN, boolean, FALSE);
|
2020-07-22 10:33:16 +02:00
|
|
|
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_LOCK_WINDOW, r->lock_window, BOOLEAN, boolean, FALSE);
|
|
|
|
|
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_LOCK_CWND, r->lock_cwnd, BOOLEAN, boolean, FALSE);
|
|
|
|
|
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_LOCK_INITCWND, r->lock_initcwnd, BOOLEAN, boolean, FALSE);
|
|
|
|
|
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_LOCK_INITRWND, r->lock_initrwnd, BOOLEAN, boolean, FALSE);
|
|
|
|
|
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_LOCK_MTU, r->lock_mtu, BOOLEAN, boolean, FALSE);
|
2022-06-23 22:01:12 +02:00
|
|
|
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_LOCK_ADVMSS, r->lock_mss, BOOLEAN, boolean, FALSE);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-22 10:33:16 +02:00
|
|
|
if ((variant = nm_ip_route_get_attribute(s_route, NM_IP_ROUTE_ATTRIBUTE_SRC))
|
|
|
|
|
&& g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING)) {
|
|
|
|
|
if (inet_pton(addr_family, g_variant_get_string(variant, NULL), &addr) == 1) {
|
2022-02-03 22:52:55 +01:00
|
|
|
if (IS_IPv4)
|
2020-07-22 10:33:16 +02:00
|
|
|
r4->pref_src = addr.addr4;
|
|
|
|
|
else
|
|
|
|
|
r6->pref_src = addr.addr6;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2022-02-03 22:52:55 +01:00
|
|
|
if (!IS_IPv4 && (variant = nm_ip_route_get_attribute(s_route, NM_IP_ROUTE_ATTRIBUTE_FROM))
|
2020-07-22 10:33:16 +02:00
|
|
|
&& g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING)) {
|
2020-07-22 10:51:39 +02:00
|
|
|
int prefix;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
glib-aux: rename IP address related helpers from "nm-inet-utils.h"
- name things related to `in_addr_t`, `struct in6_addr`, `NMIPAddr` as
`nm_ip4_addr_*()`, `nm_ip6_addr_*()`, `nm_ip_addr_*()`, respectively.
- we have a wrapper `nm_inet_ntop()` for `inet_ntop()`. This name
of our wrapper is chosen to be familiar with the libc underlying
function. With this, also name functions that are about string
representations of addresses `nm_inet_*()`, `nm_inet4_*()`,
`nm_inet6_*()`. For example, `nm_inet_parse_str()`,
`nm_inet_is_normalized()`.
<<<<
R() {
git grep -l "$1" | xargs sed -i "s/\<$1\>/$2/g"
}
R NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX NM_CMP_DIRECT_IP4_ADDR_SAME_PREFIX
R NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX NM_CMP_DIRECT_IP6_ADDR_SAME_PREFIX
R NM_UTILS_INET_ADDRSTRLEN NM_INET_ADDRSTRLEN
R _nm_utils_inet4_ntop nm_inet4_ntop
R _nm_utils_inet6_ntop nm_inet6_ntop
R _nm_utils_ip4_get_default_prefix nm_ip4_addr_get_default_prefix
R _nm_utils_ip4_get_default_prefix0 nm_ip4_addr_get_default_prefix0
R _nm_utils_ip4_netmask_to_prefix nm_ip4_addr_netmask_to_prefix
R _nm_utils_ip4_prefix_to_netmask nm_ip4_addr_netmask_from_prefix
R nm_utils_inet4_ntop_dup nm_inet4_ntop_dup
R nm_utils_inet6_ntop_dup nm_inet6_ntop_dup
R nm_utils_inet_ntop nm_inet_ntop
R nm_utils_inet_ntop_dup nm_inet_ntop_dup
R nm_utils_ip4_address_clear_host_address nm_ip4_addr_clear_host_address
R nm_utils_ip4_address_is_link_local nm_ip4_addr_is_link_local
R nm_utils_ip4_address_is_loopback nm_ip4_addr_is_loopback
R nm_utils_ip4_address_is_zeronet nm_ip4_addr_is_zeronet
R nm_utils_ip4_address_same_prefix nm_ip4_addr_same_prefix
R nm_utils_ip4_address_same_prefix_cmp nm_ip4_addr_same_prefix_cmp
R nm_utils_ip6_address_clear_host_address nm_ip6_addr_clear_host_address
R nm_utils_ip6_address_same_prefix nm_ip6_addr_same_prefix
R nm_utils_ip6_address_same_prefix_cmp nm_ip6_addr_same_prefix_cmp
R nm_utils_ip6_is_ula nm_ip6_addr_is_ula
R nm_utils_ip_address_same_prefix nm_ip_addr_same_prefix
R nm_utils_ip_address_same_prefix_cmp nm_ip_addr_same_prefix_cmp
R nm_utils_ip_is_site_local nm_ip_addr_is_site_local
R nm_utils_ipaddr_is_normalized nm_inet_is_normalized
R nm_utils_ipaddr_is_valid nm_inet_is_valid
R nm_utils_ipx_address_clear_host_address nm_ip_addr_clear_host_address
R nm_utils_parse_inaddr nm_inet_parse_str
R nm_utils_parse_inaddr_bin nm_inet_parse_bin
R nm_utils_parse_inaddr_bin_full nm_inet_parse_bin_full
R nm_utils_parse_inaddr_prefix nm_inet_parse_with_prefix_str
R nm_utils_parse_inaddr_prefix_bin nm_inet_parse_with_prefix_bin
R test_nm_utils_ip6_address_same_prefix test_nm_ip_addr_same_prefix
./contrib/scripts/nm-code-format.sh -F
2022-08-19 13:15:20 +02:00
|
|
|
if (nm_inet_parse_with_prefix_bin(addr_family,
|
|
|
|
|
g_variant_get_string(variant, NULL),
|
|
|
|
|
NULL,
|
|
|
|
|
&addr,
|
|
|
|
|
&prefix)) {
|
2020-07-22 10:51:39 +02:00
|
|
|
if (prefix < 0)
|
|
|
|
|
prefix = 128;
|
2020-07-22 10:33:16 +02:00
|
|
|
r6->src = addr.addr6;
|
2020-07-22 10:51:39 +02:00
|
|
|
r6->src_plen = prefix;
|
2020-07-22 10:33:16 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#undef GET_ATTR
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-30 11:02:56 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
void
|
2020-07-30 13:24:48 +02:00
|
|
|
nm_utils_ip_addresses_to_dbus(int addr_family,
|
|
|
|
|
const NMDedupMultiHeadEntry *head_entry,
|
2021-11-09 13:28:54 +01:00
|
|
|
const NMPObject *best_default_route,
|
|
|
|
|
GVariant **out_address_data,
|
|
|
|
|
GVariant **out_addresses)
|
2020-07-30 11:02:56 +02:00
|
|
|
{
|
2021-08-06 15:17:05 +02:00
|
|
|
const int IS_IPv4 = NM_IS_IPv4(addr_family);
|
|
|
|
|
GVariantBuilder builder_data;
|
|
|
|
|
GVariantBuilder builder_legacy;
|
glib-aux: rename IP address related helpers from "nm-inet-utils.h"
- name things related to `in_addr_t`, `struct in6_addr`, `NMIPAddr` as
`nm_ip4_addr_*()`, `nm_ip6_addr_*()`, `nm_ip_addr_*()`, respectively.
- we have a wrapper `nm_inet_ntop()` for `inet_ntop()`. This name
of our wrapper is chosen to be familiar with the libc underlying
function. With this, also name functions that are about string
representations of addresses `nm_inet_*()`, `nm_inet4_*()`,
`nm_inet6_*()`. For example, `nm_inet_parse_str()`,
`nm_inet_is_normalized()`.
<<<<
R() {
git grep -l "$1" | xargs sed -i "s/\<$1\>/$2/g"
}
R NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX NM_CMP_DIRECT_IP4_ADDR_SAME_PREFIX
R NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX NM_CMP_DIRECT_IP6_ADDR_SAME_PREFIX
R NM_UTILS_INET_ADDRSTRLEN NM_INET_ADDRSTRLEN
R _nm_utils_inet4_ntop nm_inet4_ntop
R _nm_utils_inet6_ntop nm_inet6_ntop
R _nm_utils_ip4_get_default_prefix nm_ip4_addr_get_default_prefix
R _nm_utils_ip4_get_default_prefix0 nm_ip4_addr_get_default_prefix0
R _nm_utils_ip4_netmask_to_prefix nm_ip4_addr_netmask_to_prefix
R _nm_utils_ip4_prefix_to_netmask nm_ip4_addr_netmask_from_prefix
R nm_utils_inet4_ntop_dup nm_inet4_ntop_dup
R nm_utils_inet6_ntop_dup nm_inet6_ntop_dup
R nm_utils_inet_ntop nm_inet_ntop
R nm_utils_inet_ntop_dup nm_inet_ntop_dup
R nm_utils_ip4_address_clear_host_address nm_ip4_addr_clear_host_address
R nm_utils_ip4_address_is_link_local nm_ip4_addr_is_link_local
R nm_utils_ip4_address_is_loopback nm_ip4_addr_is_loopback
R nm_utils_ip4_address_is_zeronet nm_ip4_addr_is_zeronet
R nm_utils_ip4_address_same_prefix nm_ip4_addr_same_prefix
R nm_utils_ip4_address_same_prefix_cmp nm_ip4_addr_same_prefix_cmp
R nm_utils_ip6_address_clear_host_address nm_ip6_addr_clear_host_address
R nm_utils_ip6_address_same_prefix nm_ip6_addr_same_prefix
R nm_utils_ip6_address_same_prefix_cmp nm_ip6_addr_same_prefix_cmp
R nm_utils_ip6_is_ula nm_ip6_addr_is_ula
R nm_utils_ip_address_same_prefix nm_ip_addr_same_prefix
R nm_utils_ip_address_same_prefix_cmp nm_ip_addr_same_prefix_cmp
R nm_utils_ip_is_site_local nm_ip_addr_is_site_local
R nm_utils_ipaddr_is_normalized nm_inet_is_normalized
R nm_utils_ipaddr_is_valid nm_inet_is_valid
R nm_utils_ipx_address_clear_host_address nm_ip_addr_clear_host_address
R nm_utils_parse_inaddr nm_inet_parse_str
R nm_utils_parse_inaddr_bin nm_inet_parse_bin
R nm_utils_parse_inaddr_bin_full nm_inet_parse_bin_full
R nm_utils_parse_inaddr_prefix nm_inet_parse_with_prefix_str
R nm_utils_parse_inaddr_prefix_bin nm_inet_parse_with_prefix_bin
R test_nm_utils_ip6_address_same_prefix test_nm_ip_addr_same_prefix
./contrib/scripts/nm-code-format.sh -F
2022-08-19 13:15:20 +02:00
|
|
|
char addr_str[NM_INET_ADDRSTRLEN];
|
2021-08-06 15:17:05 +02:00
|
|
|
NMDedupMultiIter iter;
|
|
|
|
|
const NMPObject *obj;
|
core: limit number of exported addresses/routes on D-Bus to 100
It doesn't scale to export all addresses/routes on D-Bus as properties.
In particular not combined with PropertiesChanged signal. On a busy
system, this causes severe performance issues. It also doesn't seem very
useful. Routes and addresses are complex things (e.g. policy routing).
If you want to do anything serious, you must check netlink (or find
another way to get the information).
Note that NMPlatform already ignores routes of certain protocols
(ip_route_is_alive()). It also does not expose most route attributes,
making the output only useful for very limited cases (e.g. displaying to
the user for information).
Limit the number of exported entries to 100.
Try adding 100K routes one-by-one. Run a `nmcli monitor` instance.
Re-nice the nmcli process and/or keep the CPUs busy. Then start a script
that adds 100k routes. Observe. Glib's D-Bus worker thread receives the
messages and queues them for the main thread. The main thread is too
slow to process them, the memory consumption grows very quickly in Giga
bytes. Afterwards, the memory also is not returned to the operation
system, either because of fragmentation or because the libc allocator
does anyway not return heap memory.
It doesn't work to expose an unlimited number of objects on D-Bus. At
least not with an API, that sends the full list of all routes, whenever
a route changes. Nobody can use that feature either, because the only
use is a quick overview in `nmcli` output or a GUI. If you see 100+
routes there, that becomes unmanageable anyway. Instead use netlink if
you want to handle the full list of addresses/routes (or some other
API).
2023-11-20 12:38:08 +01:00
|
|
|
const gsize MAX_ADDRESSES = 100;
|
|
|
|
|
gsize i;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 13:24:48 +02:00
|
|
|
nm_assert_addr_family(addr_family);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 11:02:56 +02:00
|
|
|
if (out_address_data)
|
|
|
|
|
g_variant_builder_init(&builder_data, G_VARIANT_TYPE("aa{sv}"));
|
2020-07-30 13:24:48 +02:00
|
|
|
if (out_addresses) {
|
|
|
|
|
if (IS_IPv4)
|
|
|
|
|
g_variant_builder_init(&builder_legacy, G_VARIANT_TYPE("aau"));
|
|
|
|
|
else
|
|
|
|
|
g_variant_builder_init(&builder_legacy, G_VARIANT_TYPE("a(ayuay)"));
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 13:24:48 +02:00
|
|
|
if (!head_entry)
|
|
|
|
|
goto out;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
i = 0;
|
|
|
|
|
nm_dedup_multi_iter_init(&iter, head_entry);
|
|
|
|
|
while (
|
|
|
|
|
nm_platform_dedup_multi_iter_next_obj(&iter, &obj, NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4))) {
|
|
|
|
|
const NMPlatformIPXAddress *address = NMP_OBJECT_CAST_IPX_ADDRESS(obj);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
core: limit number of exported addresses/routes on D-Bus to 100
It doesn't scale to export all addresses/routes on D-Bus as properties.
In particular not combined with PropertiesChanged signal. On a busy
system, this causes severe performance issues. It also doesn't seem very
useful. Routes and addresses are complex things (e.g. policy routing).
If you want to do anything serious, you must check netlink (or find
another way to get the information).
Note that NMPlatform already ignores routes of certain protocols
(ip_route_is_alive()). It also does not expose most route attributes,
making the output only useful for very limited cases (e.g. displaying to
the user for information).
Limit the number of exported entries to 100.
Try adding 100K routes one-by-one. Run a `nmcli monitor` instance.
Re-nice the nmcli process and/or keep the CPUs busy. Then start a script
that adds 100k routes. Observe. Glib's D-Bus worker thread receives the
messages and queues them for the main thread. The main thread is too
slow to process them, the memory consumption grows very quickly in Giga
bytes. Afterwards, the memory also is not returned to the operation
system, either because of fragmentation or because the libc allocator
does anyway not return heap memory.
It doesn't work to expose an unlimited number of objects on D-Bus. At
least not with an API, that sends the full list of all routes, whenever
a route changes. Nobody can use that feature either, because the only
use is a quick overview in `nmcli` output or a GUI. If you see 100+
routes there, that becomes unmanageable anyway. Instead use netlink if
you want to handle the full list of addresses/routes (or some other
API).
2023-11-20 12:38:08 +01:00
|
|
|
if (i > MAX_ADDRESSES) {
|
|
|
|
|
/* Limited. The rest is hidden. */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-30 13:24:48 +02:00
|
|
|
if (out_address_data) {
|
|
|
|
|
GVariantBuilder addr_builder;
|
|
|
|
|
gconstpointer p;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 13:24:48 +02:00
|
|
|
g_variant_builder_init(&addr_builder, G_VARIANT_TYPE("a{sv}"));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 13:24:48 +02:00
|
|
|
g_variant_builder_add(
|
|
|
|
|
&addr_builder,
|
|
|
|
|
"{sv}",
|
|
|
|
|
"address",
|
glib-aux: rename IP address related helpers from "nm-inet-utils.h"
- name things related to `in_addr_t`, `struct in6_addr`, `NMIPAddr` as
`nm_ip4_addr_*()`, `nm_ip6_addr_*()`, `nm_ip_addr_*()`, respectively.
- we have a wrapper `nm_inet_ntop()` for `inet_ntop()`. This name
of our wrapper is chosen to be familiar with the libc underlying
function. With this, also name functions that are about string
representations of addresses `nm_inet_*()`, `nm_inet4_*()`,
`nm_inet6_*()`. For example, `nm_inet_parse_str()`,
`nm_inet_is_normalized()`.
<<<<
R() {
git grep -l "$1" | xargs sed -i "s/\<$1\>/$2/g"
}
R NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX NM_CMP_DIRECT_IP4_ADDR_SAME_PREFIX
R NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX NM_CMP_DIRECT_IP6_ADDR_SAME_PREFIX
R NM_UTILS_INET_ADDRSTRLEN NM_INET_ADDRSTRLEN
R _nm_utils_inet4_ntop nm_inet4_ntop
R _nm_utils_inet6_ntop nm_inet6_ntop
R _nm_utils_ip4_get_default_prefix nm_ip4_addr_get_default_prefix
R _nm_utils_ip4_get_default_prefix0 nm_ip4_addr_get_default_prefix0
R _nm_utils_ip4_netmask_to_prefix nm_ip4_addr_netmask_to_prefix
R _nm_utils_ip4_prefix_to_netmask nm_ip4_addr_netmask_from_prefix
R nm_utils_inet4_ntop_dup nm_inet4_ntop_dup
R nm_utils_inet6_ntop_dup nm_inet6_ntop_dup
R nm_utils_inet_ntop nm_inet_ntop
R nm_utils_inet_ntop_dup nm_inet_ntop_dup
R nm_utils_ip4_address_clear_host_address nm_ip4_addr_clear_host_address
R nm_utils_ip4_address_is_link_local nm_ip4_addr_is_link_local
R nm_utils_ip4_address_is_loopback nm_ip4_addr_is_loopback
R nm_utils_ip4_address_is_zeronet nm_ip4_addr_is_zeronet
R nm_utils_ip4_address_same_prefix nm_ip4_addr_same_prefix
R nm_utils_ip4_address_same_prefix_cmp nm_ip4_addr_same_prefix_cmp
R nm_utils_ip6_address_clear_host_address nm_ip6_addr_clear_host_address
R nm_utils_ip6_address_same_prefix nm_ip6_addr_same_prefix
R nm_utils_ip6_address_same_prefix_cmp nm_ip6_addr_same_prefix_cmp
R nm_utils_ip6_is_ula nm_ip6_addr_is_ula
R nm_utils_ip_address_same_prefix nm_ip_addr_same_prefix
R nm_utils_ip_address_same_prefix_cmp nm_ip_addr_same_prefix_cmp
R nm_utils_ip_is_site_local nm_ip_addr_is_site_local
R nm_utils_ipaddr_is_normalized nm_inet_is_normalized
R nm_utils_ipaddr_is_valid nm_inet_is_valid
R nm_utils_ipx_address_clear_host_address nm_ip_addr_clear_host_address
R nm_utils_parse_inaddr nm_inet_parse_str
R nm_utils_parse_inaddr_bin nm_inet_parse_bin
R nm_utils_parse_inaddr_bin_full nm_inet_parse_bin_full
R nm_utils_parse_inaddr_prefix nm_inet_parse_with_prefix_str
R nm_utils_parse_inaddr_prefix_bin nm_inet_parse_with_prefix_bin
R test_nm_utils_ip6_address_same_prefix test_nm_ip_addr_same_prefix
./contrib/scripts/nm-code-format.sh -F
2022-08-19 13:15:20 +02:00
|
|
|
g_variant_new_string(nm_inet_ntop(addr_family, address->ax.address_ptr, addr_str)));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 13:24:48 +02:00
|
|
|
g_variant_builder_add(&addr_builder,
|
|
|
|
|
"{sv}",
|
|
|
|
|
"prefix",
|
|
|
|
|
g_variant_new_uint32(address->ax.plen));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 13:24:48 +02:00
|
|
|
p = NULL;
|
|
|
|
|
if (IS_IPv4) {
|
|
|
|
|
if (address->a4.peer_address != address->a4.address)
|
|
|
|
|
p = &address->a4.peer_address;
|
|
|
|
|
} else {
|
|
|
|
|
if (!IN6_IS_ADDR_UNSPECIFIED(&address->a6.peer_address)
|
|
|
|
|
&& !IN6_ARE_ADDR_EQUAL(&address->a6.peer_address, &address->a6.address))
|
|
|
|
|
p = &address->a6.peer_address;
|
|
|
|
|
}
|
|
|
|
|
if (p) {
|
glib-aux: rename IP address related helpers from "nm-inet-utils.h"
- name things related to `in_addr_t`, `struct in6_addr`, `NMIPAddr` as
`nm_ip4_addr_*()`, `nm_ip6_addr_*()`, `nm_ip_addr_*()`, respectively.
- we have a wrapper `nm_inet_ntop()` for `inet_ntop()`. This name
of our wrapper is chosen to be familiar with the libc underlying
function. With this, also name functions that are about string
representations of addresses `nm_inet_*()`, `nm_inet4_*()`,
`nm_inet6_*()`. For example, `nm_inet_parse_str()`,
`nm_inet_is_normalized()`.
<<<<
R() {
git grep -l "$1" | xargs sed -i "s/\<$1\>/$2/g"
}
R NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX NM_CMP_DIRECT_IP4_ADDR_SAME_PREFIX
R NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX NM_CMP_DIRECT_IP6_ADDR_SAME_PREFIX
R NM_UTILS_INET_ADDRSTRLEN NM_INET_ADDRSTRLEN
R _nm_utils_inet4_ntop nm_inet4_ntop
R _nm_utils_inet6_ntop nm_inet6_ntop
R _nm_utils_ip4_get_default_prefix nm_ip4_addr_get_default_prefix
R _nm_utils_ip4_get_default_prefix0 nm_ip4_addr_get_default_prefix0
R _nm_utils_ip4_netmask_to_prefix nm_ip4_addr_netmask_to_prefix
R _nm_utils_ip4_prefix_to_netmask nm_ip4_addr_netmask_from_prefix
R nm_utils_inet4_ntop_dup nm_inet4_ntop_dup
R nm_utils_inet6_ntop_dup nm_inet6_ntop_dup
R nm_utils_inet_ntop nm_inet_ntop
R nm_utils_inet_ntop_dup nm_inet_ntop_dup
R nm_utils_ip4_address_clear_host_address nm_ip4_addr_clear_host_address
R nm_utils_ip4_address_is_link_local nm_ip4_addr_is_link_local
R nm_utils_ip4_address_is_loopback nm_ip4_addr_is_loopback
R nm_utils_ip4_address_is_zeronet nm_ip4_addr_is_zeronet
R nm_utils_ip4_address_same_prefix nm_ip4_addr_same_prefix
R nm_utils_ip4_address_same_prefix_cmp nm_ip4_addr_same_prefix_cmp
R nm_utils_ip6_address_clear_host_address nm_ip6_addr_clear_host_address
R nm_utils_ip6_address_same_prefix nm_ip6_addr_same_prefix
R nm_utils_ip6_address_same_prefix_cmp nm_ip6_addr_same_prefix_cmp
R nm_utils_ip6_is_ula nm_ip6_addr_is_ula
R nm_utils_ip_address_same_prefix nm_ip_addr_same_prefix
R nm_utils_ip_address_same_prefix_cmp nm_ip_addr_same_prefix_cmp
R nm_utils_ip_is_site_local nm_ip_addr_is_site_local
R nm_utils_ipaddr_is_normalized nm_inet_is_normalized
R nm_utils_ipaddr_is_valid nm_inet_is_valid
R nm_utils_ipx_address_clear_host_address nm_ip_addr_clear_host_address
R nm_utils_parse_inaddr nm_inet_parse_str
R nm_utils_parse_inaddr_bin nm_inet_parse_bin
R nm_utils_parse_inaddr_bin_full nm_inet_parse_bin_full
R nm_utils_parse_inaddr_prefix nm_inet_parse_with_prefix_str
R nm_utils_parse_inaddr_prefix_bin nm_inet_parse_with_prefix_bin
R test_nm_utils_ip6_address_same_prefix test_nm_ip_addr_same_prefix
./contrib/scripts/nm-code-format.sh -F
2022-08-19 13:15:20 +02:00
|
|
|
g_variant_builder_add(&addr_builder,
|
|
|
|
|
"{sv}",
|
|
|
|
|
"peer",
|
|
|
|
|
g_variant_new_string(nm_inet_ntop(addr_family, p, addr_str)));
|
2020-07-30 13:24:48 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 13:24:48 +02:00
|
|
|
if (IS_IPv4) {
|
|
|
|
|
if (*address->a4.label) {
|
2020-07-30 11:02:56 +02:00
|
|
|
g_variant_builder_add(&addr_builder,
|
|
|
|
|
"{sv}",
|
|
|
|
|
NM_IP_ADDRESS_ATTRIBUTE_LABEL,
|
2020-07-30 13:24:48 +02:00
|
|
|
g_variant_new_string(address->a4.label));
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
2020-07-30 11:02:56 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 13:24:48 +02:00
|
|
|
g_variant_builder_add(&builder_data, "a{sv}", &addr_builder);
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 13:24:48 +02:00
|
|
|
if (out_addresses) {
|
|
|
|
|
if (IS_IPv4) {
|
2020-07-30 11:02:56 +02:00
|
|
|
const guint32 dbus_addr[3] = {
|
2020-07-30 13:24:48 +02:00
|
|
|
address->a4.address,
|
|
|
|
|
address->a4.plen,
|
|
|
|
|
(i == 0 && best_default_route)
|
|
|
|
|
? NMP_OBJECT_CAST_IP4_ROUTE(best_default_route)->gateway
|
|
|
|
|
: (guint32) 0,
|
2020-07-30 11:02:56 +02:00
|
|
|
};
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-04-15 09:43:42 +02:00
|
|
|
g_variant_builder_add(&builder_legacy, "@au", nm_g_variant_new_au(dbus_addr, 3));
|
2020-07-30 13:24:48 +02:00
|
|
|
} else {
|
2020-07-30 11:02:56 +02:00
|
|
|
g_variant_builder_add(
|
|
|
|
|
&builder_legacy,
|
|
|
|
|
"(@ayu@ay)",
|
2020-10-29 12:41:35 +01:00
|
|
|
nm_g_variant_new_ay_in6addr(&address->a6.address),
|
2020-07-30 13:24:48 +02:00
|
|
|
address->a6.plen,
|
2020-10-29 12:41:35 +01:00
|
|
|
nm_g_variant_new_ay_in6addr(
|
2020-07-30 11:02:56 +02:00
|
|
|
(i == 0 && best_default_route)
|
|
|
|
|
? &NMP_OBJECT_CAST_IP6_ROUTE(best_default_route)->gateway
|
2020-10-29 12:41:35 +01:00
|
|
|
: &in6addr_any));
|
2020-07-30 11:02:56 +02:00
|
|
|
}
|
|
|
|
|
}
|
2021-08-06 15:17:05 +02:00
|
|
|
|
|
|
|
|
i++;
|
2020-07-30 11:02:56 +02:00
|
|
|
}
|
|
|
|
|
|
2020-07-30 13:24:48 +02:00
|
|
|
out:
|
2020-07-30 11:02:56 +02:00
|
|
|
NM_SET_OUT(out_address_data, g_variant_builder_end(&builder_data));
|
|
|
|
|
NM_SET_OUT(out_addresses, g_variant_builder_end(&builder_legacy));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2020-07-30 13:24:48 +02:00
|
|
|
nm_utils_ip_routes_to_dbus(int addr_family,
|
|
|
|
|
const NMDedupMultiHeadEntry *head_entry,
|
2021-11-09 13:28:54 +01:00
|
|
|
GVariant **out_route_data,
|
|
|
|
|
GVariant **out_routes)
|
2020-07-30 11:02:56 +02:00
|
|
|
{
|
2020-10-30 12:13:18 +01:00
|
|
|
const int IS_IPv4 = NM_IS_IPv4(addr_family);
|
2020-07-30 11:02:56 +02:00
|
|
|
NMDedupMultiIter iter;
|
2020-07-30 13:24:48 +02:00
|
|
|
const NMPObject *obj;
|
2020-07-30 11:02:56 +02:00
|
|
|
GVariantBuilder builder_data;
|
|
|
|
|
GVariantBuilder builder_legacy;
|
glib-aux: rename IP address related helpers from "nm-inet-utils.h"
- name things related to `in_addr_t`, `struct in6_addr`, `NMIPAddr` as
`nm_ip4_addr_*()`, `nm_ip6_addr_*()`, `nm_ip_addr_*()`, respectively.
- we have a wrapper `nm_inet_ntop()` for `inet_ntop()`. This name
of our wrapper is chosen to be familiar with the libc underlying
function. With this, also name functions that are about string
representations of addresses `nm_inet_*()`, `nm_inet4_*()`,
`nm_inet6_*()`. For example, `nm_inet_parse_str()`,
`nm_inet_is_normalized()`.
<<<<
R() {
git grep -l "$1" | xargs sed -i "s/\<$1\>/$2/g"
}
R NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX NM_CMP_DIRECT_IP4_ADDR_SAME_PREFIX
R NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX NM_CMP_DIRECT_IP6_ADDR_SAME_PREFIX
R NM_UTILS_INET_ADDRSTRLEN NM_INET_ADDRSTRLEN
R _nm_utils_inet4_ntop nm_inet4_ntop
R _nm_utils_inet6_ntop nm_inet6_ntop
R _nm_utils_ip4_get_default_prefix nm_ip4_addr_get_default_prefix
R _nm_utils_ip4_get_default_prefix0 nm_ip4_addr_get_default_prefix0
R _nm_utils_ip4_netmask_to_prefix nm_ip4_addr_netmask_to_prefix
R _nm_utils_ip4_prefix_to_netmask nm_ip4_addr_netmask_from_prefix
R nm_utils_inet4_ntop_dup nm_inet4_ntop_dup
R nm_utils_inet6_ntop_dup nm_inet6_ntop_dup
R nm_utils_inet_ntop nm_inet_ntop
R nm_utils_inet_ntop_dup nm_inet_ntop_dup
R nm_utils_ip4_address_clear_host_address nm_ip4_addr_clear_host_address
R nm_utils_ip4_address_is_link_local nm_ip4_addr_is_link_local
R nm_utils_ip4_address_is_loopback nm_ip4_addr_is_loopback
R nm_utils_ip4_address_is_zeronet nm_ip4_addr_is_zeronet
R nm_utils_ip4_address_same_prefix nm_ip4_addr_same_prefix
R nm_utils_ip4_address_same_prefix_cmp nm_ip4_addr_same_prefix_cmp
R nm_utils_ip6_address_clear_host_address nm_ip6_addr_clear_host_address
R nm_utils_ip6_address_same_prefix nm_ip6_addr_same_prefix
R nm_utils_ip6_address_same_prefix_cmp nm_ip6_addr_same_prefix_cmp
R nm_utils_ip6_is_ula nm_ip6_addr_is_ula
R nm_utils_ip_address_same_prefix nm_ip_addr_same_prefix
R nm_utils_ip_address_same_prefix_cmp nm_ip_addr_same_prefix_cmp
R nm_utils_ip_is_site_local nm_ip_addr_is_site_local
R nm_utils_ipaddr_is_normalized nm_inet_is_normalized
R nm_utils_ipaddr_is_valid nm_inet_is_valid
R nm_utils_ipx_address_clear_host_address nm_ip_addr_clear_host_address
R nm_utils_parse_inaddr nm_inet_parse_str
R nm_utils_parse_inaddr_bin nm_inet_parse_bin
R nm_utils_parse_inaddr_bin_full nm_inet_parse_bin_full
R nm_utils_parse_inaddr_prefix nm_inet_parse_with_prefix_str
R nm_utils_parse_inaddr_prefix_bin nm_inet_parse_with_prefix_bin
R test_nm_utils_ip6_address_same_prefix test_nm_ip_addr_same_prefix
./contrib/scripts/nm-code-format.sh -F
2022-08-19 13:15:20 +02:00
|
|
|
char addr_str[NM_INET_ADDRSTRLEN];
|
core: limit number of exported addresses/routes on D-Bus to 100
It doesn't scale to export all addresses/routes on D-Bus as properties.
In particular not combined with PropertiesChanged signal. On a busy
system, this causes severe performance issues. It also doesn't seem very
useful. Routes and addresses are complex things (e.g. policy routing).
If you want to do anything serious, you must check netlink (or find
another way to get the information).
Note that NMPlatform already ignores routes of certain protocols
(ip_route_is_alive()). It also does not expose most route attributes,
making the output only useful for very limited cases (e.g. displaying to
the user for information).
Limit the number of exported entries to 100.
Try adding 100K routes one-by-one. Run a `nmcli monitor` instance.
Re-nice the nmcli process and/or keep the CPUs busy. Then start a script
that adds 100k routes. Observe. Glib's D-Bus worker thread receives the
messages and queues them for the main thread. The main thread is too
slow to process them, the memory consumption grows very quickly in Giga
bytes. Afterwards, the memory also is not returned to the operation
system, either because of fragmentation or because the libc allocator
does anyway not return heap memory.
It doesn't work to expose an unlimited number of objects on D-Bus. At
least not with an API, that sends the full list of all routes, whenever
a route changes. Nobody can use that feature either, because the only
use is a quick overview in `nmcli` output or a GUI. If you see 100+
routes there, that becomes unmanageable anyway. Instead use netlink if
you want to handle the full list of addresses/routes (or some other
API).
2023-11-20 12:38:08 +01:00
|
|
|
const gsize MAX_ROUTES = 100;
|
|
|
|
|
gsize i;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 13:24:48 +02:00
|
|
|
nm_assert_addr_family(addr_family);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 11:02:56 +02:00
|
|
|
if (out_route_data)
|
|
|
|
|
g_variant_builder_init(&builder_data, G_VARIANT_TYPE("aa{sv}"));
|
2020-07-30 13:24:48 +02:00
|
|
|
if (out_routes) {
|
|
|
|
|
if (IS_IPv4)
|
|
|
|
|
g_variant_builder_init(&builder_legacy, G_VARIANT_TYPE("aau"));
|
|
|
|
|
else
|
|
|
|
|
g_variant_builder_init(&builder_legacy, G_VARIANT_TYPE("a(ayuayu)"));
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
core: limit number of exported addresses/routes on D-Bus to 100
It doesn't scale to export all addresses/routes on D-Bus as properties.
In particular not combined with PropertiesChanged signal. On a busy
system, this causes severe performance issues. It also doesn't seem very
useful. Routes and addresses are complex things (e.g. policy routing).
If you want to do anything serious, you must check netlink (or find
another way to get the information).
Note that NMPlatform already ignores routes of certain protocols
(ip_route_is_alive()). It also does not expose most route attributes,
making the output only useful for very limited cases (e.g. displaying to
the user for information).
Limit the number of exported entries to 100.
Try adding 100K routes one-by-one. Run a `nmcli monitor` instance.
Re-nice the nmcli process and/or keep the CPUs busy. Then start a script
that adds 100k routes. Observe. Glib's D-Bus worker thread receives the
messages and queues them for the main thread. The main thread is too
slow to process them, the memory consumption grows very quickly in Giga
bytes. Afterwards, the memory also is not returned to the operation
system, either because of fragmentation or because the libc allocator
does anyway not return heap memory.
It doesn't work to expose an unlimited number of objects on D-Bus. At
least not with an API, that sends the full list of all routes, whenever
a route changes. Nobody can use that feature either, because the only
use is a quick overview in `nmcli` output or a GUI. If you see 100+
routes there, that becomes unmanageable anyway. Instead use netlink if
you want to handle the full list of addresses/routes (or some other
API).
2023-11-20 12:38:08 +01:00
|
|
|
i = 0;
|
2020-07-30 11:02:56 +02:00
|
|
|
nm_dedup_multi_iter_init(&iter, head_entry);
|
2020-07-30 13:24:48 +02:00
|
|
|
while (nm_platform_dedup_multi_iter_next_obj(&iter, &obj, NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4))) {
|
|
|
|
|
const NMPlatformIPXRoute *r = NMP_OBJECT_CAST_IPX_ROUTE(obj);
|
|
|
|
|
struct in6_addr n;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 13:24:48 +02:00
|
|
|
nm_assert(r);
|
|
|
|
|
nm_assert(r->rx.plen <= 8u * nm_utils_addr_family_to_size(addr_family));
|
|
|
|
|
nm_assert(!IS_IPv4
|
glib-aux: rename IP address related helpers from "nm-inet-utils.h"
- name things related to `in_addr_t`, `struct in6_addr`, `NMIPAddr` as
`nm_ip4_addr_*()`, `nm_ip6_addr_*()`, `nm_ip_addr_*()`, respectively.
- we have a wrapper `nm_inet_ntop()` for `inet_ntop()`. This name
of our wrapper is chosen to be familiar with the libc underlying
function. With this, also name functions that are about string
representations of addresses `nm_inet_*()`, `nm_inet4_*()`,
`nm_inet6_*()`. For example, `nm_inet_parse_str()`,
`nm_inet_is_normalized()`.
<<<<
R() {
git grep -l "$1" | xargs sed -i "s/\<$1\>/$2/g"
}
R NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX NM_CMP_DIRECT_IP4_ADDR_SAME_PREFIX
R NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX NM_CMP_DIRECT_IP6_ADDR_SAME_PREFIX
R NM_UTILS_INET_ADDRSTRLEN NM_INET_ADDRSTRLEN
R _nm_utils_inet4_ntop nm_inet4_ntop
R _nm_utils_inet6_ntop nm_inet6_ntop
R _nm_utils_ip4_get_default_prefix nm_ip4_addr_get_default_prefix
R _nm_utils_ip4_get_default_prefix0 nm_ip4_addr_get_default_prefix0
R _nm_utils_ip4_netmask_to_prefix nm_ip4_addr_netmask_to_prefix
R _nm_utils_ip4_prefix_to_netmask nm_ip4_addr_netmask_from_prefix
R nm_utils_inet4_ntop_dup nm_inet4_ntop_dup
R nm_utils_inet6_ntop_dup nm_inet6_ntop_dup
R nm_utils_inet_ntop nm_inet_ntop
R nm_utils_inet_ntop_dup nm_inet_ntop_dup
R nm_utils_ip4_address_clear_host_address nm_ip4_addr_clear_host_address
R nm_utils_ip4_address_is_link_local nm_ip4_addr_is_link_local
R nm_utils_ip4_address_is_loopback nm_ip4_addr_is_loopback
R nm_utils_ip4_address_is_zeronet nm_ip4_addr_is_zeronet
R nm_utils_ip4_address_same_prefix nm_ip4_addr_same_prefix
R nm_utils_ip4_address_same_prefix_cmp nm_ip4_addr_same_prefix_cmp
R nm_utils_ip6_address_clear_host_address nm_ip6_addr_clear_host_address
R nm_utils_ip6_address_same_prefix nm_ip6_addr_same_prefix
R nm_utils_ip6_address_same_prefix_cmp nm_ip6_addr_same_prefix_cmp
R nm_utils_ip6_is_ula nm_ip6_addr_is_ula
R nm_utils_ip_address_same_prefix nm_ip_addr_same_prefix
R nm_utils_ip_address_same_prefix_cmp nm_ip_addr_same_prefix_cmp
R nm_utils_ip_is_site_local nm_ip_addr_is_site_local
R nm_utils_ipaddr_is_normalized nm_inet_is_normalized
R nm_utils_ipaddr_is_valid nm_inet_is_valid
R nm_utils_ipx_address_clear_host_address nm_ip_addr_clear_host_address
R nm_utils_parse_inaddr nm_inet_parse_str
R nm_utils_parse_inaddr_bin nm_inet_parse_bin
R nm_utils_parse_inaddr_bin_full nm_inet_parse_bin_full
R nm_utils_parse_inaddr_prefix nm_inet_parse_with_prefix_str
R nm_utils_parse_inaddr_prefix_bin nm_inet_parse_with_prefix_bin
R test_nm_utils_ip6_address_same_prefix test_nm_ip_addr_same_prefix
./contrib/scripts/nm-code-format.sh -F
2022-08-19 13:15:20 +02:00
|
|
|
|| r->r4.network == nm_ip4_addr_clear_host_address(r->r4.network, r->r4.plen));
|
|
|
|
|
nm_assert(IS_IPv4
|
|
|
|
|
|| (memcmp(&r->r6.network,
|
|
|
|
|
nm_ip6_addr_clear_host_address(&n, &r->r6.network, r->r6.plen),
|
|
|
|
|
sizeof(n))
|
|
|
|
|
== 0));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 13:24:48 +02:00
|
|
|
if (r->rx.type_coerced != nm_platform_route_type_coerce(RTN_UNICAST))
|
2020-07-30 11:02:56 +02:00
|
|
|
continue;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
core: limit number of exported addresses/routes on D-Bus to 100
It doesn't scale to export all addresses/routes on D-Bus as properties.
In particular not combined with PropertiesChanged signal. On a busy
system, this causes severe performance issues. It also doesn't seem very
useful. Routes and addresses are complex things (e.g. policy routing).
If you want to do anything serious, you must check netlink (or find
another way to get the information).
Note that NMPlatform already ignores routes of certain protocols
(ip_route_is_alive()). It also does not expose most route attributes,
making the output only useful for very limited cases (e.g. displaying to
the user for information).
Limit the number of exported entries to 100.
Try adding 100K routes one-by-one. Run a `nmcli monitor` instance.
Re-nice the nmcli process and/or keep the CPUs busy. Then start a script
that adds 100k routes. Observe. Glib's D-Bus worker thread receives the
messages and queues them for the main thread. The main thread is too
slow to process them, the memory consumption grows very quickly in Giga
bytes. Afterwards, the memory also is not returned to the operation
system, either because of fragmentation or because the libc allocator
does anyway not return heap memory.
It doesn't work to expose an unlimited number of objects on D-Bus. At
least not with an API, that sends the full list of all routes, whenever
a route changes. Nobody can use that feature either, because the only
use is a quick overview in `nmcli` output or a GUI. If you see 100+
routes there, that becomes unmanageable anyway. Instead use netlink if
you want to handle the full list of addresses/routes (or some other
API).
2023-11-20 12:38:08 +01:00
|
|
|
if (i >= MAX_ROUTES) {
|
|
|
|
|
/* Limited. The rest is hidden. */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
|
2020-07-30 11:02:56 +02:00
|
|
|
if (out_route_data) {
|
2020-07-30 13:24:48 +02:00
|
|
|
GVariantBuilder route_builder;
|
|
|
|
|
gconstpointer gateway;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 11:02:56 +02:00
|
|
|
g_variant_builder_init(&route_builder, G_VARIANT_TYPE("a{sv}"));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 11:02:56 +02:00
|
|
|
g_variant_builder_add(
|
|
|
|
|
&route_builder,
|
|
|
|
|
"{sv}",
|
|
|
|
|
"dest",
|
glib-aux: rename IP address related helpers from "nm-inet-utils.h"
- name things related to `in_addr_t`, `struct in6_addr`, `NMIPAddr` as
`nm_ip4_addr_*()`, `nm_ip6_addr_*()`, `nm_ip_addr_*()`, respectively.
- we have a wrapper `nm_inet_ntop()` for `inet_ntop()`. This name
of our wrapper is chosen to be familiar with the libc underlying
function. With this, also name functions that are about string
representations of addresses `nm_inet_*()`, `nm_inet4_*()`,
`nm_inet6_*()`. For example, `nm_inet_parse_str()`,
`nm_inet_is_normalized()`.
<<<<
R() {
git grep -l "$1" | xargs sed -i "s/\<$1\>/$2/g"
}
R NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX NM_CMP_DIRECT_IP4_ADDR_SAME_PREFIX
R NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX NM_CMP_DIRECT_IP6_ADDR_SAME_PREFIX
R NM_UTILS_INET_ADDRSTRLEN NM_INET_ADDRSTRLEN
R _nm_utils_inet4_ntop nm_inet4_ntop
R _nm_utils_inet6_ntop nm_inet6_ntop
R _nm_utils_ip4_get_default_prefix nm_ip4_addr_get_default_prefix
R _nm_utils_ip4_get_default_prefix0 nm_ip4_addr_get_default_prefix0
R _nm_utils_ip4_netmask_to_prefix nm_ip4_addr_netmask_to_prefix
R _nm_utils_ip4_prefix_to_netmask nm_ip4_addr_netmask_from_prefix
R nm_utils_inet4_ntop_dup nm_inet4_ntop_dup
R nm_utils_inet6_ntop_dup nm_inet6_ntop_dup
R nm_utils_inet_ntop nm_inet_ntop
R nm_utils_inet_ntop_dup nm_inet_ntop_dup
R nm_utils_ip4_address_clear_host_address nm_ip4_addr_clear_host_address
R nm_utils_ip4_address_is_link_local nm_ip4_addr_is_link_local
R nm_utils_ip4_address_is_loopback nm_ip4_addr_is_loopback
R nm_utils_ip4_address_is_zeronet nm_ip4_addr_is_zeronet
R nm_utils_ip4_address_same_prefix nm_ip4_addr_same_prefix
R nm_utils_ip4_address_same_prefix_cmp nm_ip4_addr_same_prefix_cmp
R nm_utils_ip6_address_clear_host_address nm_ip6_addr_clear_host_address
R nm_utils_ip6_address_same_prefix nm_ip6_addr_same_prefix
R nm_utils_ip6_address_same_prefix_cmp nm_ip6_addr_same_prefix_cmp
R nm_utils_ip6_is_ula nm_ip6_addr_is_ula
R nm_utils_ip_address_same_prefix nm_ip_addr_same_prefix
R nm_utils_ip_address_same_prefix_cmp nm_ip_addr_same_prefix_cmp
R nm_utils_ip_is_site_local nm_ip_addr_is_site_local
R nm_utils_ipaddr_is_normalized nm_inet_is_normalized
R nm_utils_ipaddr_is_valid nm_inet_is_valid
R nm_utils_ipx_address_clear_host_address nm_ip_addr_clear_host_address
R nm_utils_parse_inaddr nm_inet_parse_str
R nm_utils_parse_inaddr_bin nm_inet_parse_bin
R nm_utils_parse_inaddr_bin_full nm_inet_parse_bin_full
R nm_utils_parse_inaddr_prefix nm_inet_parse_with_prefix_str
R nm_utils_parse_inaddr_prefix_bin nm_inet_parse_with_prefix_bin
R test_nm_utils_ip6_address_same_prefix test_nm_ip_addr_same_prefix
./contrib/scripts/nm-code-format.sh -F
2022-08-19 13:15:20 +02:00
|
|
|
g_variant_new_string(nm_inet_ntop(addr_family, r->rx.network_ptr, addr_str)));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 11:02:56 +02:00
|
|
|
g_variant_builder_add(&route_builder,
|
|
|
|
|
"{sv}",
|
|
|
|
|
"prefix",
|
2020-07-30 13:24:48 +02:00
|
|
|
g_variant_new_uint32(r->rx.plen));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 13:24:48 +02:00
|
|
|
gateway = nm_platform_ip_route_get_gateway(addr_family, &r->rx);
|
|
|
|
|
if (!nm_ip_addr_is_null(addr_family, gateway)) {
|
2020-07-30 11:02:56 +02:00
|
|
|
g_variant_builder_add(
|
|
|
|
|
&route_builder,
|
|
|
|
|
"{sv}",
|
|
|
|
|
"next-hop",
|
glib-aux: rename IP address related helpers from "nm-inet-utils.h"
- name things related to `in_addr_t`, `struct in6_addr`, `NMIPAddr` as
`nm_ip4_addr_*()`, `nm_ip6_addr_*()`, `nm_ip_addr_*()`, respectively.
- we have a wrapper `nm_inet_ntop()` for `inet_ntop()`. This name
of our wrapper is chosen to be familiar with the libc underlying
function. With this, also name functions that are about string
representations of addresses `nm_inet_*()`, `nm_inet4_*()`,
`nm_inet6_*()`. For example, `nm_inet_parse_str()`,
`nm_inet_is_normalized()`.
<<<<
R() {
git grep -l "$1" | xargs sed -i "s/\<$1\>/$2/g"
}
R NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX NM_CMP_DIRECT_IP4_ADDR_SAME_PREFIX
R NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX NM_CMP_DIRECT_IP6_ADDR_SAME_PREFIX
R NM_UTILS_INET_ADDRSTRLEN NM_INET_ADDRSTRLEN
R _nm_utils_inet4_ntop nm_inet4_ntop
R _nm_utils_inet6_ntop nm_inet6_ntop
R _nm_utils_ip4_get_default_prefix nm_ip4_addr_get_default_prefix
R _nm_utils_ip4_get_default_prefix0 nm_ip4_addr_get_default_prefix0
R _nm_utils_ip4_netmask_to_prefix nm_ip4_addr_netmask_to_prefix
R _nm_utils_ip4_prefix_to_netmask nm_ip4_addr_netmask_from_prefix
R nm_utils_inet4_ntop_dup nm_inet4_ntop_dup
R nm_utils_inet6_ntop_dup nm_inet6_ntop_dup
R nm_utils_inet_ntop nm_inet_ntop
R nm_utils_inet_ntop_dup nm_inet_ntop_dup
R nm_utils_ip4_address_clear_host_address nm_ip4_addr_clear_host_address
R nm_utils_ip4_address_is_link_local nm_ip4_addr_is_link_local
R nm_utils_ip4_address_is_loopback nm_ip4_addr_is_loopback
R nm_utils_ip4_address_is_zeronet nm_ip4_addr_is_zeronet
R nm_utils_ip4_address_same_prefix nm_ip4_addr_same_prefix
R nm_utils_ip4_address_same_prefix_cmp nm_ip4_addr_same_prefix_cmp
R nm_utils_ip6_address_clear_host_address nm_ip6_addr_clear_host_address
R nm_utils_ip6_address_same_prefix nm_ip6_addr_same_prefix
R nm_utils_ip6_address_same_prefix_cmp nm_ip6_addr_same_prefix_cmp
R nm_utils_ip6_is_ula nm_ip6_addr_is_ula
R nm_utils_ip_address_same_prefix nm_ip_addr_same_prefix
R nm_utils_ip_address_same_prefix_cmp nm_ip_addr_same_prefix_cmp
R nm_utils_ip_is_site_local nm_ip_addr_is_site_local
R nm_utils_ipaddr_is_normalized nm_inet_is_normalized
R nm_utils_ipaddr_is_valid nm_inet_is_valid
R nm_utils_ipx_address_clear_host_address nm_ip_addr_clear_host_address
R nm_utils_parse_inaddr nm_inet_parse_str
R nm_utils_parse_inaddr_bin nm_inet_parse_bin
R nm_utils_parse_inaddr_bin_full nm_inet_parse_bin_full
R nm_utils_parse_inaddr_prefix nm_inet_parse_with_prefix_str
R nm_utils_parse_inaddr_prefix_bin nm_inet_parse_with_prefix_bin
R test_nm_utils_ip6_address_same_prefix test_nm_ip_addr_same_prefix
./contrib/scripts/nm-code-format.sh -F
2022-08-19 13:15:20 +02:00
|
|
|
g_variant_new_string(nm_inet_ntop(addr_family, gateway, addr_str)));
|
2020-07-30 11:02:56 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 11:02:56 +02:00
|
|
|
g_variant_builder_add(&route_builder,
|
|
|
|
|
"{sv}",
|
|
|
|
|
"metric",
|
2020-07-30 13:24:48 +02:00
|
|
|
g_variant_new_uint32(r->rx.metric));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 13:24:48 +02:00
|
|
|
if (!nm_platform_route_table_is_main(r->rx.table_coerced)) {
|
2020-07-30 11:02:56 +02:00
|
|
|
g_variant_builder_add(
|
|
|
|
|
&route_builder,
|
|
|
|
|
"{sv}",
|
|
|
|
|
"table",
|
2020-07-30 13:24:48 +02:00
|
|
|
g_variant_new_uint32(
|
|
|
|
|
nm_platform_route_table_uncoerce(r->rx.table_coerced, TRUE)));
|
2020-07-30 11:02:56 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 11:02:56 +02:00
|
|
|
g_variant_builder_add(&builder_data, "a{sv}", &route_builder);
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 11:02:56 +02:00
|
|
|
if (out_routes) {
|
2020-07-30 13:24:48 +02:00
|
|
|
/* legacy versions of nm_ip[46]_route_set_prefix() in libnm-util assert that the
|
2020-07-30 11:02:56 +02:00
|
|
|
* plen is positive. Skip the default routes not to break older clients. */
|
2020-07-30 13:24:48 +02:00
|
|
|
if (!nm_platform_route_table_is_main(r->rx.table_coerced)
|
|
|
|
|
|| NM_PLATFORM_IP_ROUTE_IS_DEFAULT(r))
|
|
|
|
|
continue;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 13:24:48 +02:00
|
|
|
if (IS_IPv4) {
|
2020-07-30 11:02:56 +02:00
|
|
|
const guint32 dbus_route[4] = {
|
2020-07-30 13:24:48 +02:00
|
|
|
r->r4.network,
|
|
|
|
|
r->r4.plen,
|
|
|
|
|
r->r4.gateway,
|
|
|
|
|
r->r4.metric,
|
2020-07-30 11:02:56 +02:00
|
|
|
};
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-04-15 09:43:42 +02:00
|
|
|
g_variant_builder_add(&builder_legacy, "@au", nm_g_variant_new_au(dbus_route, 4));
|
2020-07-30 13:24:48 +02:00
|
|
|
} else {
|
2020-10-29 12:41:35 +01:00
|
|
|
g_variant_builder_add(&builder_legacy,
|
|
|
|
|
"(@ayu@ayu)",
|
|
|
|
|
nm_g_variant_new_ay_in6addr(&r->r6.network),
|
|
|
|
|
(guint32) r->r6.plen,
|
|
|
|
|
nm_g_variant_new_ay_in6addr(&r->r6.gateway),
|
|
|
|
|
(guint32) r->r6.metric);
|
2020-07-30 11:02:56 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
2020-07-30 11:02:56 +02:00
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2020-07-30 11:02:56 +02:00
|
|
|
NM_SET_OUT(out_route_data, g_variant_builder_end(&builder_data));
|
|
|
|
|
NM_SET_OUT(out_routes, g_variant_builder_end(&builder_legacy));
|
|
|
|
|
}
|
2020-10-27 09:37:43 +01:00
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
NMSetting *
|
|
|
|
|
nm_utils_platform_capture_ip_setting(NMPlatform *platform,
|
|
|
|
|
int addr_family,
|
|
|
|
|
int ifindex,
|
|
|
|
|
gboolean maybe_ipv6_disabled)
|
|
|
|
|
{
|
2021-11-09 13:28:54 +01:00
|
|
|
const int IS_IPv4 = NM_IS_IPv4(addr_family);
|
|
|
|
|
gs_unref_object NMSettingIPConfig *s_ip = NULL;
|
2021-08-06 15:17:05 +02:00
|
|
|
NMPLookup lookup;
|
|
|
|
|
NMDedupMultiIter iter;
|
2021-11-09 13:28:54 +01:00
|
|
|
const NMPObject *obj;
|
|
|
|
|
const char *method = NULL;
|
glib-aux: rename IP address related helpers from "nm-inet-utils.h"
- name things related to `in_addr_t`, `struct in6_addr`, `NMIPAddr` as
`nm_ip4_addr_*()`, `nm_ip6_addr_*()`, `nm_ip_addr_*()`, respectively.
- we have a wrapper `nm_inet_ntop()` for `inet_ntop()`. This name
of our wrapper is chosen to be familiar with the libc underlying
function. With this, also name functions that are about string
representations of addresses `nm_inet_*()`, `nm_inet4_*()`,
`nm_inet6_*()`. For example, `nm_inet_parse_str()`,
`nm_inet_is_normalized()`.
<<<<
R() {
git grep -l "$1" | xargs sed -i "s/\<$1\>/$2/g"
}
R NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX NM_CMP_DIRECT_IP4_ADDR_SAME_PREFIX
R NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX NM_CMP_DIRECT_IP6_ADDR_SAME_PREFIX
R NM_UTILS_INET_ADDRSTRLEN NM_INET_ADDRSTRLEN
R _nm_utils_inet4_ntop nm_inet4_ntop
R _nm_utils_inet6_ntop nm_inet6_ntop
R _nm_utils_ip4_get_default_prefix nm_ip4_addr_get_default_prefix
R _nm_utils_ip4_get_default_prefix0 nm_ip4_addr_get_default_prefix0
R _nm_utils_ip4_netmask_to_prefix nm_ip4_addr_netmask_to_prefix
R _nm_utils_ip4_prefix_to_netmask nm_ip4_addr_netmask_from_prefix
R nm_utils_inet4_ntop_dup nm_inet4_ntop_dup
R nm_utils_inet6_ntop_dup nm_inet6_ntop_dup
R nm_utils_inet_ntop nm_inet_ntop
R nm_utils_inet_ntop_dup nm_inet_ntop_dup
R nm_utils_ip4_address_clear_host_address nm_ip4_addr_clear_host_address
R nm_utils_ip4_address_is_link_local nm_ip4_addr_is_link_local
R nm_utils_ip4_address_is_loopback nm_ip4_addr_is_loopback
R nm_utils_ip4_address_is_zeronet nm_ip4_addr_is_zeronet
R nm_utils_ip4_address_same_prefix nm_ip4_addr_same_prefix
R nm_utils_ip4_address_same_prefix_cmp nm_ip4_addr_same_prefix_cmp
R nm_utils_ip6_address_clear_host_address nm_ip6_addr_clear_host_address
R nm_utils_ip6_address_same_prefix nm_ip6_addr_same_prefix
R nm_utils_ip6_address_same_prefix_cmp nm_ip6_addr_same_prefix_cmp
R nm_utils_ip6_is_ula nm_ip6_addr_is_ula
R nm_utils_ip_address_same_prefix nm_ip_addr_same_prefix
R nm_utils_ip_address_same_prefix_cmp nm_ip_addr_same_prefix_cmp
R nm_utils_ip_is_site_local nm_ip_addr_is_site_local
R nm_utils_ipaddr_is_normalized nm_inet_is_normalized
R nm_utils_ipaddr_is_valid nm_inet_is_valid
R nm_utils_ipx_address_clear_host_address nm_ip_addr_clear_host_address
R nm_utils_parse_inaddr nm_inet_parse_str
R nm_utils_parse_inaddr_bin nm_inet_parse_bin
R nm_utils_parse_inaddr_bin_full nm_inet_parse_bin_full
R nm_utils_parse_inaddr_prefix nm_inet_parse_with_prefix_str
R nm_utils_parse_inaddr_prefix_bin nm_inet_parse_with_prefix_bin
R test_nm_utils_ip6_address_same_prefix test_nm_ip_addr_same_prefix
./contrib/scripts/nm-code-format.sh -F
2022-08-19 13:15:20 +02:00
|
|
|
char sbuf[NM_INET_ADDRSTRLEN];
|
2021-11-09 13:28:54 +01:00
|
|
|
const NMPlatformIPXRoute *best_default_route = NULL;
|
2021-08-06 15:17:05 +02:00
|
|
|
|
|
|
|
|
s_ip =
|
|
|
|
|
NM_SETTING_IP_CONFIG(IS_IPv4 ? nm_setting_ip4_config_new() : nm_setting_ip6_config_new());
|
|
|
|
|
|
|
|
|
|
if (ifindex <= 0 || !nm_platform_link_get(platform, ifindex)) {
|
|
|
|
|
g_object_set(s_ip,
|
|
|
|
|
NM_SETTING_IP_CONFIG_METHOD,
|
|
|
|
|
IS_IPv4 ? NM_SETTING_IP4_CONFIG_METHOD_DISABLED
|
|
|
|
|
: NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
|
|
|
|
|
NULL);
|
|
|
|
|
return NM_SETTING(g_steal_pointer(&s_ip));
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-24 23:32:13 +02:00
|
|
|
nmp_lookup_init_object_by_ifindex(&lookup, NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4), ifindex);
|
2021-08-06 15:17:05 +02:00
|
|
|
nm_platform_iter_obj_for_each (&iter, platform, &lookup, &obj) {
|
2021-11-09 13:28:54 +01:00
|
|
|
const NMPlatformIPXAddress *address = NMP_OBJECT_CAST_IPX_ADDRESS(obj);
|
|
|
|
|
nm_auto_unref_ip_address NMIPAddress *s_addr = NULL;
|
2021-08-06 15:17:05 +02:00
|
|
|
|
|
|
|
|
if (!IS_IPv4) {
|
|
|
|
|
/* Ignore link-local address. */
|
|
|
|
|
if (IN6_IS_ADDR_LINKLOCAL(address->ax.address_ptr)) {
|
|
|
|
|
if (!method)
|
|
|
|
|
method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Detect dynamic address */
|
|
|
|
|
if (address->ax.lifetime != NM_PLATFORM_LIFETIME_PERMANENT) {
|
|
|
|
|
method =
|
|
|
|
|
IS_IPv4 ? NM_SETTING_IP4_CONFIG_METHOD_AUTO : NM_SETTING_IP6_CONFIG_METHOD_AUTO;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Static address found. */
|
|
|
|
|
if (IS_IPv4) {
|
|
|
|
|
if (!method)
|
|
|
|
|
method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
|
|
|
|
|
} else {
|
|
|
|
|
if (NM_IN_STRSET(method, NULL, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL))
|
|
|
|
|
method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s_addr =
|
|
|
|
|
nm_ip_address_new_binary(addr_family, address->ax.address_ptr, address->ax.plen, NULL);
|
|
|
|
|
|
|
|
|
|
if (IS_IPv4) {
|
|
|
|
|
if (address->a4.label[0]) {
|
|
|
|
|
nm_ip_address_set_attribute(s_addr,
|
|
|
|
|
NM_IP_ADDRESS_ATTRIBUTE_LABEL,
|
|
|
|
|
g_variant_new_string(address->a4.label));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nm_setting_ip_config_add_address(s_ip, s_addr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!method) {
|
|
|
|
|
/* Use 'disabled/ignore' if the method wasn't previously set */
|
|
|
|
|
if (IS_IPv4)
|
|
|
|
|
method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED;
|
|
|
|
|
else
|
|
|
|
|
method = maybe_ipv6_disabled ? NM_SETTING_IP6_CONFIG_METHOD_DISABLED
|
|
|
|
|
: NM_SETTING_IP6_CONFIG_METHOD_IGNORE;
|
|
|
|
|
}
|
2023-07-17 14:09:04 -04:00
|
|
|
|
|
|
|
|
/* The IPv6 method "ignore" and "disabled" are not supported for loopback */
|
|
|
|
|
if (ifindex == 1
|
|
|
|
|
&& NM_IN_STRSET(method,
|
|
|
|
|
NM_SETTING_IP6_CONFIG_METHOD_DISABLED,
|
|
|
|
|
NM_SETTING_IP6_CONFIG_METHOD_IGNORE))
|
|
|
|
|
method = NM_SETTING_IP6_CONFIG_METHOD_AUTO;
|
2021-08-06 15:17:05 +02:00
|
|
|
g_object_set(s_ip, NM_SETTING_IP_CONFIG_METHOD, method, NULL);
|
|
|
|
|
|
2022-06-24 23:32:13 +02:00
|
|
|
nmp_lookup_init_object_by_ifindex(&lookup, NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4), ifindex);
|
2021-08-06 15:17:05 +02:00
|
|
|
nm_platform_iter_obj_for_each (&iter, platform, &lookup, &obj) {
|
2021-11-09 13:28:54 +01:00
|
|
|
const NMPlatformIPXRoute *route = NMP_OBJECT_CAST_IPX_ROUTE(obj);
|
2021-08-06 15:17:05 +02:00
|
|
|
nm_auto_unref_ip_route NMIPRoute *s_route = NULL;
|
|
|
|
|
|
|
|
|
|
if (!IS_IPv4) {
|
|
|
|
|
/* Ignore link-local route. */
|
|
|
|
|
if (IN6_IS_ADDR_LINKLOCAL(route->rx.network_ptr))
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(route)) {
|
|
|
|
|
if (!best_default_route)
|
|
|
|
|
best_default_route = route;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-27 11:09:52 +02:00
|
|
|
if (route->rx.rt_source
|
|
|
|
|
!= nmp_utils_ip_config_source_round_trip_rtprot(NM_IP_CONFIG_SOURCE_USER)) {
|
|
|
|
|
/* Ignore routes provided by external sources */
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-06 15:17:05 +02:00
|
|
|
s_route = nm_ip_route_new_binary(addr_family,
|
|
|
|
|
route->rx.network_ptr,
|
|
|
|
|
route->rx.plen,
|
|
|
|
|
nm_platform_ip_route_get_gateway(addr_family, &route->rx),
|
|
|
|
|
route->rx.metric,
|
|
|
|
|
NULL);
|
|
|
|
|
nm_setting_ip_config_add_route(s_ip, s_route);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (best_default_route && nm_setting_ip_config_get_num_addresses(s_ip) > 0) {
|
glib-aux: rename IP address related helpers from "nm-inet-utils.h"
- name things related to `in_addr_t`, `struct in6_addr`, `NMIPAddr` as
`nm_ip4_addr_*()`, `nm_ip6_addr_*()`, `nm_ip_addr_*()`, respectively.
- we have a wrapper `nm_inet_ntop()` for `inet_ntop()`. This name
of our wrapper is chosen to be familiar with the libc underlying
function. With this, also name functions that are about string
representations of addresses `nm_inet_*()`, `nm_inet4_*()`,
`nm_inet6_*()`. For example, `nm_inet_parse_str()`,
`nm_inet_is_normalized()`.
<<<<
R() {
git grep -l "$1" | xargs sed -i "s/\<$1\>/$2/g"
}
R NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX NM_CMP_DIRECT_IP4_ADDR_SAME_PREFIX
R NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX NM_CMP_DIRECT_IP6_ADDR_SAME_PREFIX
R NM_UTILS_INET_ADDRSTRLEN NM_INET_ADDRSTRLEN
R _nm_utils_inet4_ntop nm_inet4_ntop
R _nm_utils_inet6_ntop nm_inet6_ntop
R _nm_utils_ip4_get_default_prefix nm_ip4_addr_get_default_prefix
R _nm_utils_ip4_get_default_prefix0 nm_ip4_addr_get_default_prefix0
R _nm_utils_ip4_netmask_to_prefix nm_ip4_addr_netmask_to_prefix
R _nm_utils_ip4_prefix_to_netmask nm_ip4_addr_netmask_from_prefix
R nm_utils_inet4_ntop_dup nm_inet4_ntop_dup
R nm_utils_inet6_ntop_dup nm_inet6_ntop_dup
R nm_utils_inet_ntop nm_inet_ntop
R nm_utils_inet_ntop_dup nm_inet_ntop_dup
R nm_utils_ip4_address_clear_host_address nm_ip4_addr_clear_host_address
R nm_utils_ip4_address_is_link_local nm_ip4_addr_is_link_local
R nm_utils_ip4_address_is_loopback nm_ip4_addr_is_loopback
R nm_utils_ip4_address_is_zeronet nm_ip4_addr_is_zeronet
R nm_utils_ip4_address_same_prefix nm_ip4_addr_same_prefix
R nm_utils_ip4_address_same_prefix_cmp nm_ip4_addr_same_prefix_cmp
R nm_utils_ip6_address_clear_host_address nm_ip6_addr_clear_host_address
R nm_utils_ip6_address_same_prefix nm_ip6_addr_same_prefix
R nm_utils_ip6_address_same_prefix_cmp nm_ip6_addr_same_prefix_cmp
R nm_utils_ip6_is_ula nm_ip6_addr_is_ula
R nm_utils_ip_address_same_prefix nm_ip_addr_same_prefix
R nm_utils_ip_address_same_prefix_cmp nm_ip_addr_same_prefix_cmp
R nm_utils_ip_is_site_local nm_ip_addr_is_site_local
R nm_utils_ipaddr_is_normalized nm_inet_is_normalized
R nm_utils_ipaddr_is_valid nm_inet_is_valid
R nm_utils_ipx_address_clear_host_address nm_ip_addr_clear_host_address
R nm_utils_parse_inaddr nm_inet_parse_str
R nm_utils_parse_inaddr_bin nm_inet_parse_bin
R nm_utils_parse_inaddr_bin_full nm_inet_parse_bin_full
R nm_utils_parse_inaddr_prefix nm_inet_parse_with_prefix_str
R nm_utils_parse_inaddr_prefix_bin nm_inet_parse_with_prefix_bin
R test_nm_utils_ip6_address_same_prefix test_nm_ip_addr_same_prefix
./contrib/scripts/nm-code-format.sh -F
2022-08-19 13:15:20 +02:00
|
|
|
g_object_set(
|
|
|
|
|
s_ip,
|
|
|
|
|
NM_SETTING_IP_CONFIG_GATEWAY,
|
|
|
|
|
nm_inet_ntop(addr_family,
|
2021-08-06 15:17:05 +02:00
|
|
|
nm_platform_ip_route_get_gateway(addr_family, &best_default_route->rx),
|
|
|
|
|
sbuf),
|
glib-aux: rename IP address related helpers from "nm-inet-utils.h"
- name things related to `in_addr_t`, `struct in6_addr`, `NMIPAddr` as
`nm_ip4_addr_*()`, `nm_ip6_addr_*()`, `nm_ip_addr_*()`, respectively.
- we have a wrapper `nm_inet_ntop()` for `inet_ntop()`. This name
of our wrapper is chosen to be familiar with the libc underlying
function. With this, also name functions that are about string
representations of addresses `nm_inet_*()`, `nm_inet4_*()`,
`nm_inet6_*()`. For example, `nm_inet_parse_str()`,
`nm_inet_is_normalized()`.
<<<<
R() {
git grep -l "$1" | xargs sed -i "s/\<$1\>/$2/g"
}
R NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX NM_CMP_DIRECT_IP4_ADDR_SAME_PREFIX
R NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX NM_CMP_DIRECT_IP6_ADDR_SAME_PREFIX
R NM_UTILS_INET_ADDRSTRLEN NM_INET_ADDRSTRLEN
R _nm_utils_inet4_ntop nm_inet4_ntop
R _nm_utils_inet6_ntop nm_inet6_ntop
R _nm_utils_ip4_get_default_prefix nm_ip4_addr_get_default_prefix
R _nm_utils_ip4_get_default_prefix0 nm_ip4_addr_get_default_prefix0
R _nm_utils_ip4_netmask_to_prefix nm_ip4_addr_netmask_to_prefix
R _nm_utils_ip4_prefix_to_netmask nm_ip4_addr_netmask_from_prefix
R nm_utils_inet4_ntop_dup nm_inet4_ntop_dup
R nm_utils_inet6_ntop_dup nm_inet6_ntop_dup
R nm_utils_inet_ntop nm_inet_ntop
R nm_utils_inet_ntop_dup nm_inet_ntop_dup
R nm_utils_ip4_address_clear_host_address nm_ip4_addr_clear_host_address
R nm_utils_ip4_address_is_link_local nm_ip4_addr_is_link_local
R nm_utils_ip4_address_is_loopback nm_ip4_addr_is_loopback
R nm_utils_ip4_address_is_zeronet nm_ip4_addr_is_zeronet
R nm_utils_ip4_address_same_prefix nm_ip4_addr_same_prefix
R nm_utils_ip4_address_same_prefix_cmp nm_ip4_addr_same_prefix_cmp
R nm_utils_ip6_address_clear_host_address nm_ip6_addr_clear_host_address
R nm_utils_ip6_address_same_prefix nm_ip6_addr_same_prefix
R nm_utils_ip6_address_same_prefix_cmp nm_ip6_addr_same_prefix_cmp
R nm_utils_ip6_is_ula nm_ip6_addr_is_ula
R nm_utils_ip_address_same_prefix nm_ip_addr_same_prefix
R nm_utils_ip_address_same_prefix_cmp nm_ip_addr_same_prefix_cmp
R nm_utils_ip_is_site_local nm_ip_addr_is_site_local
R nm_utils_ipaddr_is_normalized nm_inet_is_normalized
R nm_utils_ipaddr_is_valid nm_inet_is_valid
R nm_utils_ipx_address_clear_host_address nm_ip_addr_clear_host_address
R nm_utils_parse_inaddr nm_inet_parse_str
R nm_utils_parse_inaddr_bin nm_inet_parse_bin
R nm_utils_parse_inaddr_bin_full nm_inet_parse_bin_full
R nm_utils_parse_inaddr_prefix nm_inet_parse_with_prefix_str
R nm_utils_parse_inaddr_prefix_bin nm_inet_parse_with_prefix_bin
R test_nm_utils_ip6_address_same_prefix test_nm_ip_addr_same_prefix
./contrib/scripts/nm-code-format.sh -F
2022-08-19 13:15:20 +02:00
|
|
|
NULL);
|
2021-08-06 15:17:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NM_SETTING(g_steal_pointer(&s_ip));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2021-03-04 07:54:57 +01:00
|
|
|
/* Singleton NMPlatform subclass instance and cached class object */
|
|
|
|
|
NM_DEFINE_SINGLETON_INSTANCE(NMPlatform);
|
|
|
|
|
|
|
|
|
|
NM_DEFINE_SINGLETON_REGISTER(NMPlatform);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_platform_setup:
|
|
|
|
|
* @instance: the #NMPlatform instance
|
|
|
|
|
*
|
|
|
|
|
* Failing to set up #NMPlatform singleton results in a fatal error,
|
|
|
|
|
* as well as trying to initialize it multiple times without freeing
|
|
|
|
|
* it.
|
|
|
|
|
*
|
|
|
|
|
* NetworkManager will typically use only one platform object during
|
|
|
|
|
* its run. Test programs might want to switch platform implementations,
|
|
|
|
|
* though.
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
nm_platform_setup(NMPlatform *instance)
|
|
|
|
|
{
|
|
|
|
|
g_return_if_fail(NM_IS_PLATFORM(instance));
|
|
|
|
|
g_return_if_fail(!singleton_instance);
|
|
|
|
|
|
|
|
|
|
singleton_instance = instance;
|
|
|
|
|
|
|
|
|
|
nm_singleton_instance_register();
|
|
|
|
|
|
|
|
|
|
nm_log_dbg(LOGD_CORE,
|
|
|
|
|
"setup %s singleton (" NM_HASH_OBFUSCATE_PTR_FMT ")",
|
|
|
|
|
"NMPlatform",
|
|
|
|
|
NM_HASH_OBFUSCATE_PTR(instance));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_platform_get:
|
|
|
|
|
* @self: platform instance
|
|
|
|
|
*
|
|
|
|
|
* Retrieve #NMPlatform singleton. Use this whenever you want to connect to
|
|
|
|
|
* #NMPlatform signals. It is an error to call it before nm_platform_setup().
|
|
|
|
|
*
|
|
|
|
|
* Returns: (transfer none): The #NMPlatform singleton reference.
|
|
|
|
|
*/
|
|
|
|
|
NMPlatform *
|
2022-10-11 11:09:44 +02:00
|
|
|
nm_platform_get(void)
|
2021-03-04 07:54:57 +01:00
|
|
|
{
|
|
|
|
|
g_assert(singleton_instance);
|
|
|
|
|
|
|
|
|
|
return singleton_instance;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_linux_platform_setup(void)
|
2021-09-17 17:48:35 +02:00
|
|
|
{
|
2022-12-16 18:07:07 +01:00
|
|
|
nm_platform_setup(nm_linux_platform_new(NULL, FALSE, FALSE, FALSE));
|
2021-09-17 17:48:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_linux_platform_setup_with_tc_cache(void)
|
2021-03-04 07:54:57 +01:00
|
|
|
{
|
2022-12-16 18:07:07 +01:00
|
|
|
nm_platform_setup(nm_linux_platform_new(NULL, FALSE, FALSE, TRUE));
|
2021-03-04 07:54:57 +01:00
|
|
|
}
|
2023-02-15 10:33:27 +01:00
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
NM_UTILS_FLAGS2STR_DEFINE(
|
|
|
|
|
nm_settings_autoconnect_blocked_reason_to_string,
|
|
|
|
|
NMSettingsAutoconnectBlockedReason,
|
2023-02-09 21:04:15 +01:00
|
|
|
NM_UTILS_FLAGS2STR(NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_NONE, "none"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_USER_REQUEST, "user-request"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_FAILED, "failed"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_NO_SECRETS, "no-secrets"), );
|