2020-12-23 22:21:36 +01:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
2019-09-25 13:13:40 +02:00
|
|
|
/*
|
2018-05-24 15:03:40 +02:00
|
|
|
* Copyright (C) 2012 - 2018 Red Hat, Inc.
|
2013-03-27 22:23:24 +01:00
|
|
|
*/
|
|
|
|
|
|
2021-03-04 11:29:39 +01:00
|
|
|
#include "libnm-glib-aux/nm-default-glib-i18n-lib.h"
|
2014-11-13 10:07:02 -05:00
|
|
|
|
2016-03-01 09:56:51 +01:00
|
|
|
#include "nm-platform.h"
|
|
|
|
|
|
2022-07-14 22:19:47 +02:00
|
|
|
#include "libnm-std-aux/nm-linux-compat.h"
|
|
|
|
|
|
2013-03-27 22:23:24 +01:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <netinet/in.h>
|
2013-03-27 22:23:24 +01:00
|
|
|
#include <arpa/inet.h>
|
2018-03-13 13:35:35 +00:00
|
|
|
#include <sys/socket.h>
|
|
|
|
|
#include <netdb.h>
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
#include <linux/fib_rules.h>
|
2015-10-12 15:15:21 +02:00
|
|
|
#include <linux/ip.h>
|
2018-11-12 15:23:36 +01:00
|
|
|
#include <linux/if.h>
|
2015-10-13 16:08:30 +02:00
|
|
|
#include <linux/if_tun.h>
|
2015-10-12 15:15:21 +02:00
|
|
|
#include <linux/if_tunnel.h>
|
2016-10-07 21:35:58 +02:00
|
|
|
#include <linux/rtnetlink.h>
|
2019-04-09 16:23:39 +02:00
|
|
|
#include <linux/tc_act/tc_mirred.h>
|
2017-07-04 12:49:47 +02:00
|
|
|
#include <libudev.h>
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2021-03-19 10:46:41 +01:00
|
|
|
#include "libnm-base/nm-net-aux.h"
|
2021-02-18 17:37:47 +01:00
|
|
|
#include "libnm-glib-aux/nm-dedup-multi.h"
|
|
|
|
|
#include "libnm-glib-aux/nm-secret-utils.h"
|
2021-03-02 21:05:11 +01:00
|
|
|
#include "libnm-glib-aux/nm-time-utils.h"
|
2021-03-04 11:29:39 +01:00
|
|
|
#include "libnm-log-core/nm-logging.h"
|
2021-02-18 08:13:35 +01:00
|
|
|
#include "libnm-platform/nm-platform-utils.h"
|
2021-03-02 21:05:11 +01:00
|
|
|
#include "libnm-platform/nmp-netns.h"
|
|
|
|
|
#include "libnm-udev-aux/nm-udev-utils.h"
|
2017-06-29 11:18:10 +02:00
|
|
|
#include "nm-platform-private.h"
|
2015-10-29 11:27:55 +01:00
|
|
|
#include "nmp-object.h"
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2016-02-18 20:21:27 +01:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
G_STATIC_ASSERT(G_STRUCT_OFFSET(NMPlatformIPAddress, address_ptr)
|
|
|
|
|
== G_STRUCT_OFFSET(NMPlatformIP4Address, address));
|
|
|
|
|
G_STATIC_ASSERT(G_STRUCT_OFFSET(NMPlatformIPAddress, address_ptr)
|
|
|
|
|
== G_STRUCT_OFFSET(NMPlatformIP6Address, address));
|
|
|
|
|
G_STATIC_ASSERT(G_STRUCT_OFFSET(NMPlatformIPRoute, network_ptr)
|
|
|
|
|
== G_STRUCT_OFFSET(NMPlatformIP4Route, network));
|
|
|
|
|
G_STATIC_ASSERT(G_STRUCT_OFFSET(NMPlatformIPRoute, network_ptr)
|
|
|
|
|
== G_STRUCT_OFFSET(NMPlatformIP6Route, network));
|
|
|
|
|
|
|
|
|
|
G_STATIC_ASSERT(_nm_alignof(NMPlatformIPRoute) == _nm_alignof(NMPlatformIP4Route));
|
|
|
|
|
G_STATIC_ASSERT(_nm_alignof(NMPlatformIPRoute) == _nm_alignof(NMPlatformIP6Route));
|
|
|
|
|
G_STATIC_ASSERT(_nm_alignof(NMPlatformIPRoute) == _nm_alignof(NMPlatformIPXRoute));
|
|
|
|
|
|
|
|
|
|
G_STATIC_ASSERT(_nm_alignof(NMPlatformIPAddress) == _nm_alignof(NMPlatformIP4Address));
|
|
|
|
|
G_STATIC_ASSERT(_nm_alignof(NMPlatformIPAddress) == _nm_alignof(NMPlatformIP6Address));
|
|
|
|
|
G_STATIC_ASSERT(_nm_alignof(NMPlatformIPAddress) == _nm_alignof(NMPlatformIPXAddress));
|
2020-06-05 15:14:30 +02:00
|
|
|
|
2019-05-30 07:54:11 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2021-03-03 20:57:01 +01:00
|
|
|
G_STATIC_ASSERT(sizeof(((NMPLinkAddress *) NULL)->data) == _NM_UTILS_HWADDR_LEN_MAX);
|
|
|
|
|
G_STATIC_ASSERT(sizeof(((NMPlatformLink *) NULL)->l_address.data) == _NM_UTILS_HWADDR_LEN_MAX);
|
2021-07-26 10:57:30 -04:00
|
|
|
G_STATIC_ASSERT(sizeof(((NMPlatformLink *) NULL)->l_perm_address.data) == _NM_UTILS_HWADDR_LEN_MAX);
|
2021-03-03 20:57:01 +01:00
|
|
|
G_STATIC_ASSERT(sizeof(((NMPlatformLink *) NULL)->l_broadcast.data) == _NM_UTILS_HWADDR_LEN_MAX);
|
2019-05-30 07:54:11 +02:00
|
|
|
|
2023-03-03 16:36:23 +01:00
|
|
|
static const char *
|
|
|
|
|
_nmp_link_port_data_to_string(NMPortKind port_kind,
|
|
|
|
|
const NMPlatformLinkPortData *port_data,
|
|
|
|
|
char *sbuf,
|
|
|
|
|
gsize sbuf_len)
|
|
|
|
|
{
|
|
|
|
|
const char *sbuf0 = sbuf;
|
2023-03-09 12:18:14 +01:00
|
|
|
char s0[120];
|
2023-03-03 16:36:23 +01:00
|
|
|
|
|
|
|
|
nm_assert(port_data);
|
|
|
|
|
|
|
|
|
|
switch (port_kind) {
|
|
|
|
|
case NM_PORT_KIND_NONE:
|
|
|
|
|
nm_strbuf_append_c(&sbuf, &sbuf_len, '\0');
|
|
|
|
|
goto out;
|
|
|
|
|
case NM_PORT_KIND_BOND:
|
2023-03-09 12:18:14 +01:00
|
|
|
nm_strbuf_append(&sbuf,
|
|
|
|
|
&sbuf_len,
|
|
|
|
|
"port bond queue-id %u%s",
|
|
|
|
|
port_data->bond.queue_id,
|
|
|
|
|
port_data->bond.prio_has || port_data->bond.prio != 0
|
|
|
|
|
? nm_sprintf_buf(s0,
|
|
|
|
|
" prio%s %u",
|
|
|
|
|
port_data->bond.prio_has ? "" : "?",
|
|
|
|
|
port_data->bond.prio)
|
|
|
|
|
: "");
|
2023-03-03 16:36:23 +01:00
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nm_strbuf_append(&sbuf, &sbuf_len, "invalid-port-type %d", (int) port_kind);
|
|
|
|
|
|
|
|
|
|
out:
|
|
|
|
|
return sbuf0;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-30 07:54:11 +02:00
|
|
|
static const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
_nmp_link_address_to_string(const NMPLinkAddress *addr,
|
2021-03-03 20:57:01 +01:00
|
|
|
char buf[static(_NM_UTILS_HWADDR_LEN_MAX * 3)])
|
2019-05-30 07:54:11 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_assert(addr);
|
2019-05-30 07:54:11 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (addr->len > 0) {
|
2021-03-03 20:57:01 +01:00
|
|
|
if (!_nm_utils_hwaddr_ntoa(addr->data,
|
|
|
|
|
addr->len,
|
|
|
|
|
TRUE,
|
|
|
|
|
buf,
|
|
|
|
|
_NM_UTILS_HWADDR_LEN_MAX * 3)) {
|
2020-09-28 16:03:33 +02:00
|
|
|
buf[0] = '\0';
|
|
|
|
|
g_return_val_if_reached(buf);
|
|
|
|
|
}
|
|
|
|
|
} else
|
|
|
|
|
buf[0] = '\0';
|
2019-05-30 07:54:11 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return buf;
|
2019-05-30 07:54:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gconstpointer
|
2020-09-28 16:03:33 +02:00
|
|
|
nmp_link_address_get(const NMPLinkAddress *addr, size_t *length)
|
2019-05-30 07:54:11 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!addr || addr->len <= 0) {
|
|
|
|
|
NM_SET_OUT(length, 0);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2019-05-30 07:54:11 +02:00
|
|
|
|
2021-03-03 20:57:01 +01:00
|
|
|
if (addr->len > _NM_UTILS_HWADDR_LEN_MAX) {
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_SET_OUT(length, 0);
|
|
|
|
|
g_return_val_if_reached(NULL);
|
|
|
|
|
}
|
2019-05-30 07:54:11 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_SET_OUT(length, addr->len);
|
|
|
|
|
return addr->data;
|
2019-05-30 07:54:11 +02:00
|
|
|
}
|
|
|
|
|
|
2019-07-04 11:14:35 +02:00
|
|
|
GBytes *
|
2020-09-28 16:03:33 +02:00
|
|
|
nmp_link_address_get_as_bytes(const NMPLinkAddress *addr)
|
2019-07-04 11:14:35 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
gconstpointer data;
|
|
|
|
|
size_t length;
|
2019-07-04 11:14:35 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
data = nmp_link_address_get(addr, &length);
|
2019-07-04 11:14:35 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return length > 0 ? g_bytes_new(data, length) : NULL;
|
2019-07-04 11:14:35 +02:00
|
|
|
}
|
|
|
|
|
|
2019-05-30 07:54:11 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
#define _NMLOG_DOMAIN LOGD_PLATFORM
|
|
|
|
|
#define _NMLOG_PREFIX_NAME "platform"
|
|
|
|
|
|
2023-01-18 12:52:58 +01:00
|
|
|
#define NMLOG_COMMON(level, name, ...) \
|
|
|
|
|
G_STMT_START \
|
|
|
|
|
{ \
|
|
|
|
|
char __prefix[64]; \
|
|
|
|
|
const char *__p_prefix = _NMLOG_PREFIX_NAME; \
|
|
|
|
|
const NMPlatform *const __self = (self); \
|
|
|
|
|
const char *__name = name; \
|
|
|
|
|
\
|
|
|
|
|
if (__self && NM_PLATFORM_GET_PRIVATE(__self)->log_with_ptr) { \
|
|
|
|
|
g_snprintf(__prefix, \
|
|
|
|
|
sizeof(__prefix), \
|
|
|
|
|
"%s[" NM_HASH_OBFUSCATE_PTR_FMT "]", \
|
|
|
|
|
_NMLOG_PREFIX_NAME, \
|
|
|
|
|
NM_HASH_OBFUSCATE_PTR(__self)); \
|
|
|
|
|
__p_prefix = __prefix; \
|
|
|
|
|
} \
|
|
|
|
|
_nm_log((level), \
|
|
|
|
|
_NMLOG_DOMAIN, \
|
|
|
|
|
0, \
|
|
|
|
|
__name, \
|
|
|
|
|
NULL, \
|
|
|
|
|
"%s: %s%s%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
|
|
|
|
|
__p_prefix, \
|
|
|
|
|
NM_PRINT_FMT_QUOTED(__name, "(", __name, ") ", "") \
|
|
|
|
|
_NM_UTILS_MACRO_REST(__VA_ARGS__)); \
|
|
|
|
|
} \
|
2022-08-10 12:25:16 +02:00
|
|
|
G_STMT_END
|
2020-09-28 16:03:33 +02:00
|
|
|
|
|
|
|
|
#define _NMLOG(level, ...) \
|
|
|
|
|
G_STMT_START \
|
|
|
|
|
{ \
|
|
|
|
|
const NMLogLevel __level = (level); \
|
|
|
|
|
\
|
|
|
|
|
if (nm_logging_enabled(__level, _NMLOG_DOMAIN)) { \
|
|
|
|
|
NMLOG_COMMON(level, NULL, __VA_ARGS__); \
|
|
|
|
|
} \
|
|
|
|
|
} \
|
|
|
|
|
G_STMT_END
|
|
|
|
|
|
|
|
|
|
#define _NMLOG2(level, ...) \
|
|
|
|
|
G_STMT_START \
|
|
|
|
|
{ \
|
|
|
|
|
const NMLogLevel __level = (level); \
|
|
|
|
|
\
|
|
|
|
|
if (nm_logging_enabled(__level, _NMLOG_DOMAIN)) { \
|
|
|
|
|
NMLOG_COMMON(level, name, __VA_ARGS__); \
|
|
|
|
|
} \
|
|
|
|
|
} \
|
|
|
|
|
G_STMT_END
|
|
|
|
|
|
|
|
|
|
#define _NMLOG3(level, ...) \
|
|
|
|
|
G_STMT_START \
|
|
|
|
|
{ \
|
|
|
|
|
const NMLogLevel __level = (level); \
|
|
|
|
|
\
|
|
|
|
|
if (nm_logging_enabled(__level, _NMLOG_DOMAIN)) { \
|
|
|
|
|
NMLOG_COMMON(level, \
|
|
|
|
|
ifindex > 0 ? nm_platform_link_get_name(self, ifindex) : NULL, \
|
|
|
|
|
__VA_ARGS__); \
|
|
|
|
|
} \
|
|
|
|
|
} \
|
|
|
|
|
G_STMT_END
|
2015-07-02 14:33:37 +02:00
|
|
|
|
2015-10-12 15:15:21 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
static guint signals[_NM_PLATFORM_SIGNAL_ID_LAST] = {0};
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2015-05-12 07:34:56 +02:00
|
|
|
enum {
|
2020-09-28 16:03:33 +02:00
|
|
|
PROP_0,
|
2022-12-16 18:07:07 +01:00
|
|
|
PROP_MULTI_IDX,
|
2020-09-28 16:03:33 +02:00
|
|
|
PROP_NETNS_SUPPORT,
|
|
|
|
|
PROP_USE_UDEV,
|
|
|
|
|
PROP_LOG_WITH_PTR,
|
2021-09-17 17:32:57 +02:00
|
|
|
PROP_CACHE_TC,
|
2020-09-28 16:03:33 +02:00
|
|
|
LAST_PROP,
|
2015-05-12 07:34:56 +02:00
|
|
|
};
|
|
|
|
|
|
2016-09-28 15:58:24 +02:00
|
|
|
typedef struct _NMPlatformPrivate {
|
2020-09-28 16:03:33 +02:00
|
|
|
bool use_udev : 1;
|
|
|
|
|
bool log_with_ptr : 1;
|
2021-09-17 17:32:57 +02:00
|
|
|
bool cache_tc : 1;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
|
|
|
|
guint ip4_dev_route_blacklist_check_id;
|
|
|
|
|
guint ip4_dev_route_blacklist_gc_timeout_id;
|
2021-11-09 13:28:54 +01:00
|
|
|
GHashTable *ip4_dev_route_blacklist_hash;
|
2022-09-22 13:33:17 +02:00
|
|
|
CList ip6_dadfailed_lst_head;
|
2020-09-28 16:03:33 +02:00
|
|
|
NMDedupMultiIndex *multi_idx;
|
2021-11-09 13:28:54 +01:00
|
|
|
NMPCache *cache;
|
2015-05-12 07:34:56 +02:00
|
|
|
} NMPlatformPrivate;
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
G_DEFINE_TYPE(NMPlatform, nm_platform, G_TYPE_OBJECT)
|
2016-09-28 15:58:24 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
#define NM_PLATFORM_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMPlatform, NM_IS_PLATFORM)
|
2016-09-28 15:58:24 +02:00
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
static void _ip4_dev_route_blacklist_schedule(NMPlatform *self);
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2017-06-29 10:51:38 +02:00
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_get_use_udev(NMPlatform *self)
|
2017-06-29 10:51:38 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return NM_PLATFORM_GET_PRIVATE(self)->use_udev;
|
2017-06-29 10:51:38 +02:00
|
|
|
}
|
|
|
|
|
|
2017-04-17 18:40:52 +02:00
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_get_log_with_ptr(NMPlatform *self)
|
2017-04-17 18:40:52 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return NM_PLATFORM_GET_PRIVATE(self)->log_with_ptr;
|
2017-04-17 18:40:52 +02:00
|
|
|
}
|
|
|
|
|
|
2021-09-17 17:32:57 +02:00
|
|
|
gboolean
|
|
|
|
|
nm_platform_get_cache_tc(NMPlatform *self)
|
|
|
|
|
{
|
|
|
|
|
return NM_PLATFORM_GET_PRIVATE(self)->cache_tc;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-17 18:40:52 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2015-11-27 12:54:31 +01:00
|
|
|
guint
|
2020-09-28 16:03:33 +02:00
|
|
|
_nm_platform_signal_id_get(NMPlatformSignalIdType signal_type)
|
2015-11-27 12:54:31 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_assert(signal_type > 0 && signal_type != NM_PLATFORM_SIGNAL_ID_NONE
|
|
|
|
|
&& signal_type < _NM_PLATFORM_SIGNAL_ID_LAST);
|
2015-11-27 12:54:31 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return signals[signal_type];
|
2015-11-27 12:54:31 +01:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2015-11-27 12:54:31 +01:00
|
|
|
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
/* Just always initialize a @klass instance. NM_PLATFORM_GET_CLASS()
|
|
|
|
|
* is only a plain read on the self instance, which the compiler
|
|
|
|
|
* like can optimize out.
|
|
|
|
|
*/
|
2020-09-28 16:03:33 +02:00
|
|
|
#define _CHECK_SELF_VOID(self, klass) \
|
|
|
|
|
NMPlatformClass *klass; \
|
|
|
|
|
do { \
|
|
|
|
|
g_return_if_fail(NM_IS_PLATFORM(self)); \
|
|
|
|
|
klass = NM_PLATFORM_GET_CLASS(self); \
|
|
|
|
|
(void) klass; \
|
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
|
|
#define _CHECK_SELF(self, klass, err_val) \
|
|
|
|
|
NMPlatformClass *klass; \
|
|
|
|
|
do { \
|
|
|
|
|
g_return_val_if_fail(NM_IS_PLATFORM(self), err_val); \
|
|
|
|
|
klass = NM_PLATFORM_GET_CLASS(self); \
|
|
|
|
|
(void) klass; \
|
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
|
|
#define _CHECK_SELF_NETNS(self, klass, netns, err_val) \
|
|
|
|
|
nm_auto_pop_netns NMPNetns *netns = NULL; \
|
2021-11-09 13:28:54 +01:00
|
|
|
NMPlatformClass *klass; \
|
2020-09-28 16:03:33 +02:00
|
|
|
do { \
|
|
|
|
|
g_return_val_if_fail(NM_IS_PLATFORM(self), err_val); \
|
|
|
|
|
klass = NM_PLATFORM_GET_CLASS(self); \
|
|
|
|
|
(void) klass; \
|
|
|
|
|
if (!nm_platform_netns_push(self, &netns)) \
|
|
|
|
|
return (err_val); \
|
|
|
|
|
} while (0)
|
2016-09-10 16:48:01 +02:00
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2013-03-27 22:23:24 +01:00
|
|
|
|
core: pass NMDedupMultiIndex instance to NMIP4Config and other
NMIP4Config, NMIP6Config, and NMPlatform shall share one
NMDedupMultiIndex instance.
For that, pass an NMDedupMultiIndex instance to NMPlatform and NMNetns.
NMNetns than passes it on to NMDevice, NMDhcpClient, NMIP4Config and NMIP6Config.
So currently NMNetns is the access point to the shared NMDedupMultiIndex
instance, and it gets it from it's NMPlatform instance.
The NMDedupMultiIndex instance is really a singleton, we don't want
multiple instances of it. However, for testing, instead of adding a
singleton instance, pass the instance explicitly around.
2017-06-12 08:16:47 +02:00
|
|
|
NMDedupMultiIndex *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_get_multi_idx(NMPlatform *self)
|
core: pass NMDedupMultiIndex instance to NMIP4Config and other
NMIP4Config, NMIP6Config, and NMPlatform shall share one
NMDedupMultiIndex instance.
For that, pass an NMDedupMultiIndex instance to NMPlatform and NMNetns.
NMNetns than passes it on to NMDevice, NMDhcpClient, NMIP4Config and NMIP6Config.
So currently NMNetns is the access point to the shared NMDedupMultiIndex
instance, and it gets it from it's NMPlatform instance.
The NMDedupMultiIndex instance is really a singleton, we don't want
multiple instances of it. However, for testing, instead of adding a
singleton instance, pass the instance explicitly around.
2017-06-12 08:16:47 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(NM_IS_PLATFORM(self), NULL);
|
core: pass NMDedupMultiIndex instance to NMIP4Config and other
NMIP4Config, NMIP6Config, and NMPlatform shall share one
NMDedupMultiIndex instance.
For that, pass an NMDedupMultiIndex instance to NMPlatform and NMNetns.
NMNetns than passes it on to NMDevice, NMDhcpClient, NMIP4Config and NMIP6Config.
So currently NMNetns is the access point to the shared NMDedupMultiIndex
instance, and it gets it from it's NMPlatform instance.
The NMDedupMultiIndex instance is really a singleton, we don't want
multiple instances of it. However, for testing, instead of adding a
singleton instance, pass the instance explicitly around.
2017-06-12 08:16:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return NM_PLATFORM_GET_PRIVATE(self)->multi_idx;
|
core: pass NMDedupMultiIndex instance to NMIP4Config and other
NMIP4Config, NMIP6Config, and NMPlatform shall share one
NMDedupMultiIndex instance.
For that, pass an NMDedupMultiIndex instance to NMPlatform and NMNetns.
NMNetns than passes it on to NMDevice, NMDhcpClient, NMIP4Config and NMIP6Config.
So currently NMNetns is the access point to the shared NMDedupMultiIndex
instance, and it gets it from it's NMPlatform instance.
The NMDedupMultiIndex instance is really a singleton, we don't want
multiple instances of it. However, for testing, instead of adding a
singleton instance, pass the instance explicitly around.
2017-06-12 08:16:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
static NM_UTILS_LOOKUP_STR_DEFINE(
|
|
|
|
|
_nmp_nlm_flag_to_string_lookup,
|
|
|
|
|
NMPNlmFlags,
|
|
|
|
|
NM_UTILS_LOOKUP_DEFAULT(NULL),
|
|
|
|
|
NM_UTILS_LOOKUP_ITEM(NMP_NLM_FLAG_ADD, "add"),
|
|
|
|
|
NM_UTILS_LOOKUP_ITEM(NMP_NLM_FLAG_CHANGE, "change"),
|
|
|
|
|
NM_UTILS_LOOKUP_ITEM(NMP_NLM_FLAG_REPLACE, "replace"),
|
|
|
|
|
NM_UTILS_LOOKUP_ITEM(NMP_NLM_FLAG_PREPEND, "prepend"),
|
|
|
|
|
NM_UTILS_LOOKUP_ITEM(NMP_NLM_FLAG_APPEND, "append"),
|
|
|
|
|
NM_UTILS_LOOKUP_ITEM(NMP_NLM_FLAG_TEST, "test"),
|
|
|
|
|
NM_UTILS_LOOKUP_ITEM_IGNORE(NMP_NLM_FLAG_F_APPEND),
|
|
|
|
|
NM_UTILS_LOOKUP_ITEM_IGNORE(NMP_NLM_FLAG_FMASK),
|
|
|
|
|
NM_UTILS_LOOKUP_ITEM_IGNORE(NMP_NLM_FLAG_SUPPRESS_NETLINK_FAILURE),
|
|
|
|
|
NM_UTILS_LOOKUP_ITEM_IGNORE(NMP_NLM_FLAG_F_ECHO), );
|
|
|
|
|
|
|
|
|
|
#define _nmp_nlm_flag_to_string(flags) \
|
|
|
|
|
({ \
|
|
|
|
|
NMPNlmFlags _flags = (flags); \
|
|
|
|
|
\
|
|
|
|
|
_nmp_nlm_flag_to_string_lookup(flags) \
|
|
|
|
|
?: nm_sprintf_bufa(100, "new[0x%x]", (unsigned) _flags); \
|
|
|
|
|
})
|
2017-08-21 14:35:04 +02:00
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
volatile int _nm_platform_kernel_support_state[_NM_PLATFORM_KERNEL_SUPPORT_NUM] = {};
|
2019-04-17 07:57:29 +02:00
|
|
|
|
|
|
|
|
static const struct {
|
2020-09-28 16:03:33 +02:00
|
|
|
bool compile_time_default;
|
|
|
|
|
const char *name;
|
|
|
|
|
const char *desc;
|
2019-04-17 07:57:29 +02:00
|
|
|
} _nm_platform_kernel_support_info[_NM_PLATFORM_KERNEL_SUPPORT_NUM] = {
|
2020-09-28 16:03:33 +02:00
|
|
|
[NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_L3MDEV] =
|
|
|
|
|
{
|
|
|
|
|
.compile_time_default = (FRA_MAX >= 19 /* FRA_L3MDEV */),
|
|
|
|
|
.name = "FRA_L3MDEV",
|
|
|
|
|
.desc = "FRA_L3MDEV attribute for policy routing rules",
|
|
|
|
|
},
|
|
|
|
|
[NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_UID_RANGE] =
|
|
|
|
|
{
|
|
|
|
|
.compile_time_default = (FRA_MAX >= 20 /* FRA_UID_RANGE */),
|
|
|
|
|
.name = "FRA_UID_RANGE",
|
|
|
|
|
.desc = "FRA_UID_RANGE attribute for policy routing rules",
|
|
|
|
|
},
|
|
|
|
|
[NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_PROTOCOL] =
|
|
|
|
|
{
|
|
|
|
|
.compile_time_default = (FRA_MAX >= 21 /* FRA_PROTOCOL */),
|
|
|
|
|
.name = "FRA_PROTOCOL",
|
|
|
|
|
.desc = "FRA_PROTOCOL attribute for policy routing rules",
|
|
|
|
|
},
|
|
|
|
|
[NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_IP_PROTO] =
|
|
|
|
|
{
|
|
|
|
|
.compile_time_default = (FRA_MAX >= 22 /* FRA_IP_PROTO */),
|
|
|
|
|
.name = "FRA_IP_PROTO",
|
|
|
|
|
.desc = "FRA_IP_PROTO, FRA_SPORT_RANGE, FRA_DPORT_RANGE attributes for policy routing "
|
|
|
|
|
"rules",
|
|
|
|
|
},
|
|
|
|
|
[NM_PLATFORM_KERNEL_SUPPORT_TYPE_IFLA_BR_VLAN_STATS_ENABLED] =
|
|
|
|
|
{
|
|
|
|
|
.compile_time_default = (IFLA_BR_MAX >= 41 /* IFLA_BR_VLAN_STATS_ENABLED */),
|
|
|
|
|
.name = "IFLA_BR_VLAN_STATS_ENABLE",
|
|
|
|
|
.desc = "IFLA_BR_VLAN_STATS_ENABLE bridge link attribute",
|
|
|
|
|
},
|
2021-08-18 20:58:52 -04:00
|
|
|
[NM_PLATFORM_KERNEL_SUPPORT_TYPE_IFLA_PERM_ADDRESS] =
|
|
|
|
|
{
|
|
|
|
|
.compile_time_default = (IFLA_MAX >= 54 /* IFLA_PERM_ADDRESS */),
|
|
|
|
|
.name = "IFLA_PERM_ADDRESS",
|
|
|
|
|
.desc = "IFLA_PERM_ADDRESS netlink attribute",
|
|
|
|
|
},
|
2019-04-17 07:57:29 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
_nm_platform_kernel_support_init(NMPlatformKernelSupportType type, int value)
|
2014-01-07 17:21:12 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
volatile int *p_state;
|
|
|
|
|
gboolean set_default = FALSE;
|
platform: cleanup detecting kernel support for IFA_FLAGS and IPv6LL
- cache the result in NMPlatformPrivate. No need to call the virtual
function every time. The result is not ever going to change.
- if we are unable to detect support, assume support. Those features
were added quite a while ago to kernel, we should default to "support".
Note, that we detect support based on the presence of the absence of
certain netlink flags. That means, we will still detect no support.
The only moment when we actually use the fallback value, is when we
didn't encounter an RTM_NEWADDR or AF_INET6-IFLA_AF_SPEC message yet,
which would be very unusual, because we fill the cache initially and
usually will have some addresses there.
- for no strong reason, track "undetected" as numerical value zero,
and "support"/"no-support" as 1/-1. We already did that previously for
_support_user_ipv6ll, so this just unifies the implementations.
The minor reason is that this puts @_support_user_ipv6ll to the BSS
section and allows us to omit initializing priv->check_support_user_ipv6ll_cached
in platforms constructor.
- detect _support_kernel_extended_ifa_flags also based on IPv4
RTM_NEWADDR messages. Originally, extended flags were added for IPv6,
and later to IPv4 as well. Once we see an IPv4 message with IFA_FLAGS,
we know we have support.
2017-08-16 11:58:57 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_assert(_NM_INT_NOT_NEGATIVE(type) && type < G_N_ELEMENTS(_nm_platform_kernel_support_state));
|
2014-01-07 17:21:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
p_state = &_nm_platform_kernel_support_state[type];
|
2014-01-07 17:21:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (value == 0) {
|
|
|
|
|
set_default = TRUE;
|
|
|
|
|
value = _nm_platform_kernel_support_info[type].compile_time_default ? 1 : -1;
|
|
|
|
|
}
|
2017-10-10 18:20:05 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_assert(NM_IN_SET(value, -1, 1));
|
2017-10-10 18:20:05 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!g_atomic_int_compare_and_exchange(p_state, 0, value)) {
|
|
|
|
|
value = g_atomic_int_get(p_state);
|
|
|
|
|
nm_assert(NM_IN_SET(value, -1, 1));
|
|
|
|
|
return value;
|
|
|
|
|
}
|
2019-04-17 07:57:29 +02:00
|
|
|
|
|
|
|
|
#undef NM_THREAD_SAFE_ON_MAIN_THREAD
|
|
|
|
|
#define NM_THREAD_SAFE_ON_MAIN_THREAD 0
|
2014-07-24 15:57:08 -05:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (set_default) {
|
|
|
|
|
nm_log_dbg(LOGD_PLATFORM,
|
|
|
|
|
"platform: kernel-support for %s (%s) not detected: assume %ssupported",
|
|
|
|
|
_nm_platform_kernel_support_info[type].name,
|
|
|
|
|
_nm_platform_kernel_support_info[type].desc,
|
|
|
|
|
value >= 0 ? "" : "not ");
|
|
|
|
|
} else {
|
|
|
|
|
nm_log_dbg(LOGD_PLATFORM,
|
|
|
|
|
"platform: kernel-support for %s (%s) detected: %ssupported",
|
|
|
|
|
_nm_platform_kernel_support_info[type].name,
|
|
|
|
|
_nm_platform_kernel_support_info[type].desc,
|
|
|
|
|
value >= 0 ? "" : "not ");
|
|
|
|
|
}
|
2017-10-10 18:20:05 +02:00
|
|
|
|
2019-04-17 07:57:29 +02:00
|
|
|
#undef NM_THREAD_SAFE_ON_MAIN_THREAD
|
|
|
|
|
#define NM_THREAD_SAFE_ON_MAIN_THREAD 1
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return value;
|
2014-07-24 15:57:08 -05:00
|
|
|
}
|
|
|
|
|
|
2019-04-17 07:57:29 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2022-07-07 12:55:50 +02:00
|
|
|
const NMPGenlFamilyInfo nmp_genl_family_infos[_NMP_GENL_FAMILY_TYPE_NUM] = {
|
|
|
|
|
[NMP_GENL_FAMILY_TYPE_ETHTOOL] =
|
|
|
|
|
{
|
|
|
|
|
.name = "ethtool",
|
|
|
|
|
},
|
|
|
|
|
[NMP_GENL_FAMILY_TYPE_MPTCP_PM] =
|
|
|
|
|
{
|
2022-07-14 22:19:47 +02:00
|
|
|
.name = MPTCP_PM_NAME,
|
2022-07-07 12:55:50 +02:00
|
|
|
},
|
|
|
|
|
[NMP_GENL_FAMILY_TYPE_NL80211] =
|
|
|
|
|
{
|
|
|
|
|
.name = "nl80211",
|
|
|
|
|
},
|
|
|
|
|
[NMP_GENL_FAMILY_TYPE_NL802154] =
|
|
|
|
|
{
|
|
|
|
|
.name = "nl802154",
|
|
|
|
|
},
|
|
|
|
|
[NMP_GENL_FAMILY_TYPE_WIREGUARD] =
|
|
|
|
|
{
|
|
|
|
|
.name = "wireguard",
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
NMPGenlFamilyType
|
|
|
|
|
nmp_genl_family_type_from_name(const char *name)
|
|
|
|
|
{
|
|
|
|
|
int imin, imax, imid;
|
|
|
|
|
|
|
|
|
|
if (NM_MORE_ASSERT_ONCE(50)) {
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < (int) G_N_ELEMENTS(nmp_genl_family_infos); i++) {
|
|
|
|
|
nm_assert(nmp_genl_family_infos[i].name);
|
|
|
|
|
if (i > 0)
|
|
|
|
|
nm_assert(strcmp(nmp_genl_family_infos[i - 1].name, nmp_genl_family_infos[i].name)
|
|
|
|
|
< 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!name)
|
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
|
|
imin = 0;
|
|
|
|
|
imax = G_N_ELEMENTS(nmp_genl_family_infos) - 1;
|
|
|
|
|
imid = imax / 2;
|
|
|
|
|
|
|
|
|
|
while (TRUE) {
|
|
|
|
|
int c;
|
|
|
|
|
|
|
|
|
|
c = strcmp(nmp_genl_family_infos[imid].name, name);
|
|
|
|
|
if (c == 0)
|
|
|
|
|
return (NMPGenlFamilyType) imid;
|
|
|
|
|
|
|
|
|
|
if (c < 0)
|
|
|
|
|
imin = imid + 1;
|
|
|
|
|
else
|
|
|
|
|
imax = imid - 1;
|
|
|
|
|
|
|
|
|
|
if (imin > imax)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
imid = (imax + imin) / 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out:
|
|
|
|
|
return _NMP_GENL_FAMILY_TYPE_NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2015-06-19 15:38:41 +02:00
|
|
|
/**
|
|
|
|
|
* nm_platform_process_events:
|
|
|
|
|
* @self: platform instance
|
|
|
|
|
*
|
|
|
|
|
* Process pending events or handle pending delayed-actions.
|
|
|
|
|
* Effectively, this reads the netlink socket and processes
|
|
|
|
|
* new netlink messages. Possibly it will raise change signals.
|
|
|
|
|
*/
|
|
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_process_events(NMPlatform *self)
|
2015-06-19 15:38:41 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF_VOID(self, klass);
|
2015-06-19 15:38:41 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (klass->process_events)
|
|
|
|
|
klass->process_events(self);
|
2015-06-19 15:38:41 +02:00
|
|
|
}
|
|
|
|
|
|
2018-01-11 11:15:35 +01:00
|
|
|
const NMPlatformLink *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_process_events_ensure_link(NMPlatform *self, int ifindex, const char *ifname)
|
2018-01-11 11:15:35 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPObject *obj;
|
|
|
|
|
gboolean refreshed = FALSE;
|
2018-01-11 11:15:35 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(NM_IS_PLATFORM(self), NULL);
|
2018-01-11 11:15:35 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (ifindex <= 0 && !ifname)
|
|
|
|
|
return NULL;
|
2018-01-11 11:15:35 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* we look into the cache, whether a link for given ifindex/ifname
|
2020-09-28 14:50:01 +02:00
|
|
|
* exits. If not, we poll the netlink socket, maybe the event
|
|
|
|
|
* with the link is waiting.
|
|
|
|
|
*
|
|
|
|
|
* Then we try again to find the object.
|
|
|
|
|
*
|
|
|
|
|
* If the link is already cached the first time, we avoid polling
|
|
|
|
|
* the netlink socket. */
|
2018-01-11 11:15:35 +01:00
|
|
|
again:
|
2020-09-28 16:03:33 +02:00
|
|
|
obj = nmp_cache_lookup_link_full(
|
|
|
|
|
nm_platform_get_cache(self),
|
|
|
|
|
ifindex,
|
|
|
|
|
ifname,
|
|
|
|
|
FALSE, /* also invisible. We don't care here whether udev is ready */
|
|
|
|
|
NM_LINK_TYPE_NONE,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL);
|
|
|
|
|
if (obj)
|
|
|
|
|
return NMP_OBJECT_CAST_LINK(obj);
|
|
|
|
|
if (!refreshed) {
|
|
|
|
|
refreshed = TRUE;
|
|
|
|
|
nm_platform_process_events(self);
|
|
|
|
|
goto again;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
2018-01-11 11:15:35 +01:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2016-12-08 15:12:52 +01:00
|
|
|
/**
|
|
|
|
|
* nm_platform_sysctl_open_netdir:
|
|
|
|
|
* @self: platform instance
|
|
|
|
|
* @ifindex: the ifindex for which to open /sys/class/net/%s
|
|
|
|
|
* @out_ifname: optional output argument of the found ifname.
|
|
|
|
|
*
|
|
|
|
|
* Wraps nmp_utils_sysctl_open_netdir() by first changing into the right
|
|
|
|
|
* network-namespace.
|
|
|
|
|
*
|
|
|
|
|
* Returns: on success, the open file descriptor to the /sys/class/net/%s
|
|
|
|
|
* directory.
|
|
|
|
|
*/
|
|
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_sysctl_open_netdir(NMPlatform *self, int ifindex, char *out_ifname)
|
2016-12-08 15:12:52 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const char *ifname_guess;
|
|
|
|
|
_CHECK_SELF_NETNS(self, klass, netns, -1);
|
2016-12-08 15:12:52 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, -1);
|
2016-12-08 15:12:52 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* we don't have an @ifname_guess argument to make the API nicer.
|
2020-09-28 14:50:01 +02:00
|
|
|
* But still do a cache-lookup first. Chances are good that we have
|
|
|
|
|
* the right ifname cached and save if_indextoname() */
|
2020-09-28 16:03:33 +02:00
|
|
|
ifname_guess = nm_platform_link_get_name(self, ifindex);
|
2016-12-08 15:12:52 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return nmp_utils_sysctl_open_netdir(ifindex, ifname_guess, out_ifname);
|
2016-12-08 15:12:52 +01:00
|
|
|
}
|
|
|
|
|
|
2013-04-03 16:10:38 +02:00
|
|
|
/**
|
|
|
|
|
* nm_platform_sysctl_set:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2016-12-08 14:29:00 +01:00
|
|
|
* @pathid: if @dirfd is present, this must be the full path that is looked up.
|
|
|
|
|
* It is required for logging.
|
|
|
|
|
* @dirfd: optional file descriptor for parent directory for openat()
|
2013-04-03 16:10:38 +02:00
|
|
|
* @path: Absolute option path
|
|
|
|
|
* @value: Value to write
|
|
|
|
|
*
|
|
|
|
|
* This function is intended to be used for writing values to sysctl-style
|
|
|
|
|
* virtual runtime configuration files. This includes not only /proc/sys
|
|
|
|
|
* but also for example /sys/class.
|
|
|
|
|
*
|
|
|
|
|
* Returns: %TRUE on success.
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_sysctl_set(NMPlatform *self,
|
|
|
|
|
const char *pathid,
|
|
|
|
|
int dirfd,
|
|
|
|
|
const char *path,
|
|
|
|
|
const char *value)
|
2013-04-03 16:10:38 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2013-04-03 16:10:38 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(path, FALSE);
|
|
|
|
|
g_return_val_if_fail(value, FALSE);
|
2013-04-03 16:10:38 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->sysctl_set(self, pathid, dirfd, path, value);
|
2013-04-03 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
|
2019-03-05 10:20:25 +01:00
|
|
|
/**
|
|
|
|
|
* nm_platform_sysctl_set_async:
|
|
|
|
|
* @self: platform instance
|
|
|
|
|
* @pathid: if @dirfd is present, this must be the full path that is looked up
|
|
|
|
|
* @dirfd: optional file descriptor for parent directory for openat()
|
|
|
|
|
* @path: absolute option path
|
|
|
|
|
* @values: NULL-terminated array of strings to be written
|
|
|
|
|
* @callback: function called on termination
|
|
|
|
|
* @data: data passed to callback function
|
|
|
|
|
* @cancellable: to cancel the operation
|
|
|
|
|
*
|
|
|
|
|
* This function is intended to be used for writing values to sysctl-style
|
|
|
|
|
* virtual runtime configuration files. This includes not only /proc/sys
|
|
|
|
|
* but also for example /sys/class. The function does not block and returns
|
|
|
|
|
* immediately. The callback is always invoked, and asynchronously. The file
|
|
|
|
|
* is closed after writing each value and reopened to write the next one so
|
|
|
|
|
* that the function can be used safely on all /proc and /sys files,
|
|
|
|
|
* independently of how /proc/sys/kernel/sysctl_writes_strict is configured.
|
|
|
|
|
*/
|
2020-09-28 16:03:33 +02:00
|
|
|
void
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_sysctl_set_async(NMPlatform *self,
|
|
|
|
|
const char *pathid,
|
2020-09-28 16:03:33 +02:00
|
|
|
int dirfd,
|
2021-11-09 13:28:54 +01:00
|
|
|
const char *path,
|
|
|
|
|
const char *const *values,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPlatformAsyncCallback callback,
|
|
|
|
|
gpointer data,
|
2021-11-09 13:28:54 +01:00
|
|
|
GCancellable *cancellable)
|
2019-03-05 10:20:25 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF_VOID(self, klass);
|
2019-03-05 10:20:25 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
klass->sysctl_set_async(self, pathid, dirfd, path, values, callback, data, cancellable);
|
2019-03-05 10:20:25 +01:00
|
|
|
}
|
|
|
|
|
|
2015-04-08 15:54:30 +02:00
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_sysctl_ip_conf_set_ipv6_hop_limit_safe(NMPlatform *self, const char *iface, int value)
|
2015-04-08 15:54:30 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const char *path;
|
|
|
|
|
gint64 cur;
|
|
|
|
|
char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
|
2015-04-08 15:54:30 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2015-06-17 15:00:10 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* the hop-limit provided via RA is uint8. */
|
|
|
|
|
if (value > 0xFF)
|
|
|
|
|
return FALSE;
|
2015-04-08 15:54:30 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* don't allow unreasonable small values */
|
|
|
|
|
if (value < 10)
|
|
|
|
|
return FALSE;
|
2015-04-08 15:54:30 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
path = nm_utils_sysctl_ip_conf_path(AF_INET6, buf, iface, "hop_limit");
|
|
|
|
|
cur = nm_platform_sysctl_get_int_checked(self,
|
|
|
|
|
NMP_SYSCTL_PATHID_ABSOLUTE(path),
|
|
|
|
|
10,
|
|
|
|
|
1,
|
|
|
|
|
G_MAXINT32,
|
|
|
|
|
-1);
|
2015-04-08 15:54:30 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* only allow increasing the hop-limit to avoid DOS by an attacker
|
2020-09-28 14:50:01 +02:00
|
|
|
* setting a low hop-limit (CVE-2015-2924, rh#1209902) */
|
2015-04-08 15:54:30 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (value < cur)
|
|
|
|
|
return FALSE;
|
|
|
|
|
if (value != cur) {
|
|
|
|
|
char svalue[20];
|
2015-04-08 15:54:30 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
sprintf(svalue, "%d", value);
|
|
|
|
|
nm_platform_sysctl_set(self, NMP_SYSCTL_PATHID_ABSOLUTE(path), svalue);
|
|
|
|
|
}
|
2015-04-08 15:54:30 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return TRUE;
|
2019-08-23 10:39:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_sysctl_ip_neigh_set_ipv6_reachable_time(NMPlatform *self,
|
|
|
|
|
const char *iface,
|
|
|
|
|
guint value_ms)
|
2019-08-23 10:39:22 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
char path[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
|
|
|
|
|
char str[128];
|
|
|
|
|
guint clamped;
|
2019-08-23 10:39:22 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2019-08-23 10:39:22 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!value_ms)
|
|
|
|
|
return TRUE;
|
2019-08-23 10:39:22 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* RFC 4861 says the value can't be greater than one hour.
|
2020-09-28 14:50:01 +02:00
|
|
|
* Also use a reasonable lower threshold. */
|
2020-09-28 16:03:33 +02:00
|
|
|
clamped = NM_CLAMP(value_ms, 100, 3600000);
|
|
|
|
|
nm_sprintf_buf(path, "/proc/sys/net/ipv6/neigh/%s/base_reachable_time_ms", iface);
|
|
|
|
|
nm_sprintf_buf(str, "%u", clamped);
|
|
|
|
|
if (!nm_platform_sysctl_set(self, NMP_SYSCTL_PATHID_ABSOLUTE(path), str))
|
|
|
|
|
return FALSE;
|
2019-08-23 10:39:22 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* Set stale time in the same way as kernel */
|
|
|
|
|
nm_sprintf_buf(path, "/proc/sys/net/ipv6/neigh/%s/gc_stale_time", iface);
|
|
|
|
|
nm_sprintf_buf(str, "%u", clamped * 3 / 1000);
|
2019-08-23 10:39:22 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return nm_platform_sysctl_set(self, NMP_SYSCTL_PATHID_ABSOLUTE(path), str);
|
2019-08-23 10:39:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_sysctl_ip_neigh_set_ipv6_retrans_time(NMPlatform *self,
|
|
|
|
|
const char *iface,
|
|
|
|
|
guint value_ms)
|
2019-08-23 10:39:22 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
char path[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
|
|
|
|
|
char str[128];
|
2019-08-23 10:39:22 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2019-08-23 10:39:22 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!value_ms)
|
|
|
|
|
return TRUE;
|
2019-08-23 10:39:22 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_sprintf_buf(path, "/proc/sys/net/ipv6/neigh/%s/retrans_time_ms", iface);
|
|
|
|
|
nm_sprintf_buf(str, "%u", NM_CLAMP(value_ms, 10, 3600000));
|
2019-08-23 10:39:22 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return nm_platform_sysctl_set(self, NMP_SYSCTL_PATHID_ABSOLUTE(path), str);
|
2015-04-08 15:54:30 +02:00
|
|
|
}
|
|
|
|
|
|
2013-04-03 16:10:38 +02:00
|
|
|
/**
|
|
|
|
|
* nm_platform_sysctl_get:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2016-12-08 14:29:00 +01:00
|
|
|
* @dirfd: if non-negative, used to lookup the path via openat().
|
|
|
|
|
* @pathid: if @dirfd is present, this must be the full path that is looked up.
|
|
|
|
|
* It is required for logging.
|
2013-04-03 16:10:38 +02:00
|
|
|
* @path: Absolute path to sysctl
|
|
|
|
|
*
|
|
|
|
|
* Returns: (transfer full): Contents of the virtual sysctl file.
|
2019-04-04 10:57:32 +02:00
|
|
|
*
|
|
|
|
|
* If the path does not exist, %NULL is returned and %errno set to %ENOENT.
|
2013-04-03 16:10:38 +02:00
|
|
|
*/
|
|
|
|
|
char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_sysctl_get(NMPlatform *self, const char *pathid, int dirfd, const char *path)
|
2013-04-03 16:10:38 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, NULL);
|
2013-04-03 16:10:38 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(path, NULL);
|
2013-04-03 16:10:38 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->sysctl_get(self, pathid, dirfd, path);
|
2013-04-03 16:10:38 +02:00
|
|
|
}
|
|
|
|
|
|
2013-11-08 08:49:06 -05:00
|
|
|
/**
|
2014-01-06 19:59:17 +01:00
|
|
|
* nm_platform_sysctl_get_int32:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2016-12-08 14:29:00 +01:00
|
|
|
* @pathid: if @dirfd is present, this must be the full path that is looked up.
|
|
|
|
|
* It is required for logging.
|
|
|
|
|
* @dirfd: if non-negative, used to lookup the path via openat().
|
2013-11-08 08:49:06 -05:00
|
|
|
* @path: Absolute path to sysctl
|
2014-01-06 19:59:17 +01:00
|
|
|
* @fallback: default value, if the content of path could not be read
|
|
|
|
|
* as decimal integer.
|
2013-11-08 08:49:06 -05:00
|
|
|
*
|
2014-01-06 19:59:17 +01:00
|
|
|
* Returns: contents of the sysctl file parsed as s32 integer, or
|
2014-03-23 14:57:39 +01:00
|
|
|
* @fallback on error. On error, %errno will be set to a non-zero
|
|
|
|
|
* value, on success %errno will be set to zero.
|
2013-11-08 08:49:06 -05:00
|
|
|
*/
|
2014-01-06 19:59:17 +01:00
|
|
|
gint32
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_sysctl_get_int32(NMPlatform *self,
|
|
|
|
|
const char *pathid,
|
|
|
|
|
int dirfd,
|
|
|
|
|
const char *path,
|
|
|
|
|
gint32 fallback)
|
|
|
|
|
{
|
|
|
|
|
return nm_platform_sysctl_get_int_checked(self,
|
|
|
|
|
pathid,
|
|
|
|
|
dirfd,
|
|
|
|
|
path,
|
|
|
|
|
10,
|
|
|
|
|
G_MININT32,
|
|
|
|
|
G_MAXINT32,
|
|
|
|
|
fallback);
|
2014-03-12 12:27:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_platform_sysctl_get_int_checked:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2016-12-08 14:29:00 +01:00
|
|
|
* @pathid: if @dirfd is present, this must be the full path that is looked up.
|
|
|
|
|
* It is required for logging.
|
|
|
|
|
* @dirfd: if non-negative, used to lookup the path via openat().
|
2014-03-12 12:27:58 +01:00
|
|
|
* @path: Absolute path to sysctl
|
|
|
|
|
* @base: base of numeric conversion
|
|
|
|
|
* @min: minimal value that is still valid
|
|
|
|
|
* @max: maximal value that is still valid
|
|
|
|
|
* @fallback: default value, if the content of path could not be read
|
|
|
|
|
* as valid integer.
|
|
|
|
|
*
|
|
|
|
|
* Returns: contents of the sysctl file parsed as s64 integer, or
|
|
|
|
|
* @fallback on error. On error, %errno will be set to a non-zero
|
|
|
|
|
* value. On success, %errno will be set to zero. The returned value
|
|
|
|
|
* will always be in the range between @min and @max
|
|
|
|
|
* (inclusive) or @fallback.
|
2019-04-04 10:57:32 +02:00
|
|
|
* If the file does not exist, the fallback is returned and %errno
|
|
|
|
|
* is set to ENOENT.
|
2014-03-12 12:27:58 +01:00
|
|
|
*/
|
|
|
|
|
gint64
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_sysctl_get_int_checked(NMPlatform *self,
|
|
|
|
|
const char *pathid,
|
|
|
|
|
int dirfd,
|
|
|
|
|
const char *path,
|
|
|
|
|
guint base,
|
|
|
|
|
gint64 min,
|
|
|
|
|
gint64 max,
|
|
|
|
|
gint64 fallback)
|
|
|
|
|
{
|
2021-11-09 13:28:54 +01:00
|
|
|
char *value = NULL;
|
2020-09-28 16:03:33 +02:00
|
|
|
gint32 ret;
|
|
|
|
|
int errsv;
|
|
|
|
|
|
|
|
|
|
_CHECK_SELF(self, klass, fallback);
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail(path, fallback);
|
|
|
|
|
|
|
|
|
|
if (!path) {
|
|
|
|
|
errno = EINVAL;
|
|
|
|
|
return fallback;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
value = nm_platform_sysctl_get(self, pathid, dirfd, path);
|
|
|
|
|
if (!value) {
|
|
|
|
|
/* nm_platform_sysctl_get() set errno to ENOENT if the file does not exist.
|
2020-09-28 14:50:01 +02:00
|
|
|
* Propagate/preserve that. */
|
2020-09-28 16:03:33 +02:00
|
|
|
if (errno != ENOENT)
|
|
|
|
|
errno = EINVAL;
|
|
|
|
|
return fallback;
|
|
|
|
|
}
|
2013-11-08 08:49:06 -05:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
ret = _nm_utils_ascii_str_to_int64(value, base, min, max, fallback);
|
|
|
|
|
errsv = errno;
|
|
|
|
|
g_free(value);
|
|
|
|
|
errno = errsv;
|
|
|
|
|
return ret;
|
2013-11-08 08:49:06 -05:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2013-04-03 16:10:38 +02:00
|
|
|
|
2018-12-13 11:48:06 +01:00
|
|
|
char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_sysctl_ip_conf_get(NMPlatform *self,
|
|
|
|
|
int addr_family,
|
|
|
|
|
const char *ifname,
|
|
|
|
|
const char *property)
|
2018-12-13 11:48:06 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
|
2018-12-13 11:48:06 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return nm_platform_sysctl_get(
|
|
|
|
|
self,
|
|
|
|
|
NMP_SYSCTL_PATHID_ABSOLUTE(
|
|
|
|
|
nm_utils_sysctl_ip_conf_path(addr_family, buf, ifname, property)));
|
2018-12-13 11:48:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gint64
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_sysctl_ip_conf_get_int_checked(NMPlatform *self,
|
|
|
|
|
int addr_family,
|
|
|
|
|
const char *ifname,
|
|
|
|
|
const char *property,
|
|
|
|
|
guint base,
|
|
|
|
|
gint64 min,
|
|
|
|
|
gint64 max,
|
|
|
|
|
gint64 fallback)
|
|
|
|
|
{
|
|
|
|
|
char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
|
|
|
|
|
|
|
|
|
|
return nm_platform_sysctl_get_int_checked(
|
|
|
|
|
self,
|
|
|
|
|
NMP_SYSCTL_PATHID_ABSOLUTE(
|
|
|
|
|
nm_utils_sysctl_ip_conf_path(addr_family, buf, ifname, property)),
|
|
|
|
|
base,
|
|
|
|
|
min,
|
|
|
|
|
max,
|
|
|
|
|
fallback);
|
2018-12-13 11:48:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_sysctl_ip_conf_set(NMPlatform *self,
|
|
|
|
|
int addr_family,
|
|
|
|
|
const char *ifname,
|
|
|
|
|
const char *property,
|
|
|
|
|
const char *value)
|
2018-12-13 11:48:06 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
|
2018-12-13 11:48:06 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return nm_platform_sysctl_set(
|
|
|
|
|
self,
|
|
|
|
|
NMP_SYSCTL_PATHID_ABSOLUTE(
|
|
|
|
|
nm_utils_sysctl_ip_conf_path(addr_family, buf, ifname, property)),
|
|
|
|
|
value);
|
2018-12-13 11:48:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_sysctl_ip_conf_set_int64(NMPlatform *self,
|
|
|
|
|
int addr_family,
|
|
|
|
|
const char *ifname,
|
|
|
|
|
const char *property,
|
|
|
|
|
gint64 value)
|
2018-12-13 11:48:06 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
char buf[NM_UTILS_SYSCTL_IP_CONF_PATH_BUFSIZE];
|
|
|
|
|
char s[64];
|
2018-12-13 11:48:06 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return nm_platform_sysctl_set(
|
|
|
|
|
self,
|
|
|
|
|
NMP_SYSCTL_PATHID_ABSOLUTE(
|
|
|
|
|
nm_utils_sysctl_ip_conf_path(addr_family, buf, ifname, property)),
|
|
|
|
|
nm_sprintf_buf(s, "%" G_GINT64_FORMAT, value));
|
2018-12-13 11:48:06 +01:00
|
|
|
}
|
|
|
|
|
|
2019-04-25 12:44:53 +02:00
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_sysctl_ip_conf_get_rp_filter_ipv4(NMPlatform *self,
|
|
|
|
|
const char *ifname,
|
|
|
|
|
gboolean consider_all,
|
2021-11-09 13:28:54 +01:00
|
|
|
gboolean *out_due_to_all)
|
2020-09-28 16:03:33 +02:00
|
|
|
{
|
|
|
|
|
int val, val_all;
|
|
|
|
|
|
|
|
|
|
NM_SET_OUT(out_due_to_all, FALSE);
|
|
|
|
|
|
|
|
|
|
if (!ifname)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
val = nm_platform_sysctl_ip_conf_get_int_checked(self,
|
|
|
|
|
AF_INET,
|
|
|
|
|
ifname,
|
|
|
|
|
"rp_filter",
|
|
|
|
|
10,
|
|
|
|
|
0,
|
|
|
|
|
2,
|
|
|
|
|
-1);
|
|
|
|
|
if (val == -1)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
/* the effectively used value is the rp_filter sysctl value of MAX(all,ifname).
|
2020-09-28 14:50:01 +02:00
|
|
|
* Note that this is the numerical MAX(), despite rp_filter "1" being more strict
|
|
|
|
|
* than "2". */
|
2020-09-28 16:03:33 +02:00
|
|
|
if (val < 2 && consider_all && !nm_streq(ifname, "all")) {
|
|
|
|
|
val_all = nm_platform_sysctl_ip_conf_get_int_checked(self,
|
|
|
|
|
AF_INET,
|
|
|
|
|
"all",
|
|
|
|
|
"rp_filter",
|
|
|
|
|
10,
|
|
|
|
|
0,
|
|
|
|
|
2,
|
|
|
|
|
val);
|
|
|
|
|
if (val_all > val) {
|
|
|
|
|
val = val_all;
|
|
|
|
|
NM_SET_OUT(out_due_to_all, TRUE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return val;
|
2019-04-25 12:44:53 +02:00
|
|
|
}
|
|
|
|
|
|
2018-12-13 11:48:06 +01:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2016-04-13 18:36:23 +02:00
|
|
|
static int
|
2020-09-28 16:03:33 +02:00
|
|
|
_link_get_all_presort(gconstpointer p_a, gconstpointer p_b, gpointer sort_by_name)
|
2016-04-13 18:36:23 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPlatformLink *a = NMP_OBJECT_CAST_LINK(*((const NMPObject **) p_a));
|
|
|
|
|
const NMPlatformLink *b = NMP_OBJECT_CAST_LINK(*((const NMPObject **) p_b));
|
2016-04-13 18:36:23 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* Loopback always first */
|
2022-06-12 19:50:09 -04:00
|
|
|
if (a->ifindex == NM_LOOPBACK_IFINDEX)
|
2020-09-28 16:03:33 +02:00
|
|
|
return -1;
|
2022-06-12 19:50:09 -04:00
|
|
|
if (b->ifindex == NM_LOOPBACK_IFINDEX)
|
2020-09-28 16:03:33 +02:00
|
|
|
return 1;
|
2017-02-23 18:26:02 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (GPOINTER_TO_INT(sort_by_name)) {
|
|
|
|
|
/* Initialized links first */
|
|
|
|
|
if (a->initialized > b->initialized)
|
|
|
|
|
return -1;
|
|
|
|
|
if (a->initialized < b->initialized)
|
|
|
|
|
return 1;
|
2017-02-23 18:26:02 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return strcmp(a->name, b->name);
|
|
|
|
|
} else
|
|
|
|
|
return a->ifindex - b->ifindex;
|
2016-04-13 18:36:23 +02:00
|
|
|
}
|
|
|
|
|
|
2013-03-27 22:23:24 +01:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_get_all:
|
2017-07-04 22:29:27 +02:00
|
|
|
* @self: platform instance
|
|
|
|
|
* @sort_by_name: whether to sort by name or ifindex.
|
2013-03-27 22:23:24 +01:00
|
|
|
*
|
|
|
|
|
* Retrieve a snapshot of configuration for all links at once. The result is
|
2017-07-04 22:29:27 +02:00
|
|
|
* owned by the caller and should be freed with g_ptr_array_unref().
|
2013-03-27 22:23:24 +01:00
|
|
|
*/
|
2017-07-04 22:29:27 +02:00
|
|
|
GPtrArray *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_all(NMPlatform *self, gboolean sort_by_name)
|
|
|
|
|
{
|
2021-11-09 13:28:54 +01:00
|
|
|
gs_unref_ptrarray GPtrArray *links = NULL;
|
|
|
|
|
GPtrArray *result;
|
|
|
|
|
guint i, nresult;
|
2020-09-28 16:03:33 +02:00
|
|
|
gs_unref_hashtable GHashTable *unseen = NULL;
|
2021-11-09 13:28:54 +01:00
|
|
|
const NMPlatformLink *item;
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPLookup lookup;
|
|
|
|
|
|
|
|
|
|
_CHECK_SELF(self, klass, NULL);
|
|
|
|
|
|
|
|
|
|
nmp_lookup_init_obj_type(&lookup, NMP_OBJECT_TYPE_LINK);
|
|
|
|
|
links = nm_dedup_multi_objs_to_ptr_array_head(nm_platform_lookup(self, &lookup), NULL, NULL);
|
|
|
|
|
if (!links)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < links->len;) {
|
|
|
|
|
if (!nmp_object_is_visible(links->pdata[i]))
|
|
|
|
|
g_ptr_array_remove_index_fast(links, i);
|
|
|
|
|
else
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (links->len == 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
/* first sort the links by their ifindex or name. Below we will sort
|
2020-09-28 14:50:01 +02:00
|
|
|
* further by moving children/slaves to the end. */
|
2020-09-28 16:03:33 +02:00
|
|
|
g_ptr_array_sort_with_data(links, _link_get_all_presort, GINT_TO_POINTER(sort_by_name));
|
2016-04-13 18:36:23 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
unseen = g_hash_table_new(nm_direct_hash, NULL);
|
|
|
|
|
for (i = 0; i < links->len; i++) {
|
|
|
|
|
item = NMP_OBJECT_CAST_LINK(links->pdata[i]);
|
|
|
|
|
nm_assert(item->ifindex > 0);
|
|
|
|
|
if (!g_hash_table_insert(unseen, GINT_TO_POINTER(item->ifindex), NULL))
|
|
|
|
|
nm_assert_not_reached();
|
|
|
|
|
}
|
2013-11-06 22:15:03 -06:00
|
|
|
|
2017-07-04 12:49:47 +02:00
|
|
|
#if NM_MORE_ASSERTS
|
2020-09-28 16:03:33 +02:00
|
|
|
/* Ensure that link_get_all returns a consistent and valid result. */
|
|
|
|
|
for (i = 0; i < links->len; i++) {
|
|
|
|
|
item = NMP_OBJECT_CAST_LINK(links->pdata[i]);
|
|
|
|
|
|
|
|
|
|
if (!item->ifindex)
|
|
|
|
|
continue;
|
|
|
|
|
if (item->master != 0) {
|
|
|
|
|
g_warn_if_fail(item->master > 0);
|
|
|
|
|
g_warn_if_fail(item->master != item->ifindex);
|
|
|
|
|
g_warn_if_fail(g_hash_table_contains(unseen, GINT_TO_POINTER(item->master)));
|
|
|
|
|
}
|
|
|
|
|
if (item->parent != 0) {
|
|
|
|
|
if (item->parent != NM_PLATFORM_LINK_OTHER_NETNS) {
|
|
|
|
|
g_warn_if_fail(item->parent > 0);
|
|
|
|
|
g_warn_if_fail(item->parent != item->ifindex);
|
|
|
|
|
g_warn_if_fail(g_hash_table_contains(unseen, GINT_TO_POINTER(item->parent)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-11-06 22:15:03 -06:00
|
|
|
#endif
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* Re-order the links list such that children/slaves come after all ancestors */
|
|
|
|
|
nm_assert(g_hash_table_size(unseen) == links->len);
|
|
|
|
|
nresult = links->len;
|
|
|
|
|
result = g_ptr_array_new_full(nresult, (GDestroyNotify) nmp_object_unref);
|
2013-11-06 22:15:03 -06:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
while (TRUE) {
|
|
|
|
|
gboolean found_something = FALSE;
|
|
|
|
|
guint first_idx = G_MAXUINT;
|
2013-11-06 22:15:03 -06:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
for (i = 0; i < links->len; i++) {
|
|
|
|
|
item = NMP_OBJECT_CAST_LINK(links->pdata[i]);
|
2013-11-06 22:15:03 -06:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!item)
|
|
|
|
|
continue;
|
2013-11-06 22:15:03 -06:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_assert(g_hash_table_contains(unseen, GINT_TO_POINTER(item->ifindex)));
|
2013-11-06 22:15:03 -06:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (item->master > 0 && g_hash_table_contains(unseen, GINT_TO_POINTER(item->master)))
|
|
|
|
|
goto skip;
|
|
|
|
|
if (item->parent > 0 && g_hash_table_contains(unseen, GINT_TO_POINTER(item->parent)))
|
|
|
|
|
goto skip;
|
2013-11-06 22:15:03 -06:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_hash_table_remove(unseen, GINT_TO_POINTER(item->ifindex));
|
|
|
|
|
g_ptr_array_add(result, links->pdata[i]);
|
|
|
|
|
links->pdata[i] = NULL;
|
|
|
|
|
found_something = TRUE;
|
|
|
|
|
continue;
|
2017-07-04 22:29:27 +02:00
|
|
|
skip:
|
2020-09-28 16:03:33 +02:00
|
|
|
if (first_idx == G_MAXUINT)
|
|
|
|
|
first_idx = i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (found_something) {
|
|
|
|
|
if (first_idx == G_MAXUINT)
|
|
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
nm_assert(first_idx != G_MAXUINT);
|
|
|
|
|
/* There is a loop, pop the first (remaining) element from the list.
|
2020-09-28 14:50:01 +02:00
|
|
|
* This can happen for veth pairs where each peer is parent of the other end. */
|
2020-09-28 16:03:33 +02:00
|
|
|
item = NMP_OBJECT_CAST_LINK(links->pdata[first_idx]);
|
|
|
|
|
nm_assert(item);
|
|
|
|
|
g_hash_table_remove(unseen, GINT_TO_POINTER(item->ifindex));
|
|
|
|
|
g_ptr_array_add(result, links->pdata[first_idx]);
|
|
|
|
|
links->pdata[first_idx] = NULL;
|
|
|
|
|
}
|
|
|
|
|
nm_assert(result->len < nresult);
|
|
|
|
|
}
|
|
|
|
|
nm_assert(result->len == nresult);
|
2013-11-06 22:15:03 -06:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return result;
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
2017-07-04 12:49:47 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
const NMPObject *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_obj(NMPlatform *self, int ifindex, gboolean visible_only)
|
2017-07-04 12:49:47 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPObject *obj_cache;
|
2017-07-04 12:49:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, NULL);
|
2018-11-29 12:20:09 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
obj_cache = nmp_cache_lookup_link(nm_platform_get_cache(self), ifindex);
|
|
|
|
|
if (!obj_cache || (visible_only && !nmp_object_is_visible(obj_cache)))
|
|
|
|
|
return NULL;
|
|
|
|
|
return obj_cache;
|
2017-07-04 12:49:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2014-04-22 16:02:15 +02:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_get:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2014-04-22 16:02:15 +02:00
|
|
|
* @ifindex: ifindex of the link
|
|
|
|
|
*
|
2015-06-20 12:05:01 +02:00
|
|
|
* Lookup the internal NMPlatformLink object.
|
2014-04-22 16:02:15 +02:00
|
|
|
*
|
2015-06-20 12:05:01 +02:00
|
|
|
* Returns: %NULL, if such a link exists or the internal
|
|
|
|
|
* platform link object. Do not modify the returned value.
|
|
|
|
|
* Also, be aware that any subsequent platform call might
|
2017-05-11 12:08:02 +02:00
|
|
|
* invalidate/modify the returned instance.
|
2014-04-22 16:02:15 +02:00
|
|
|
**/
|
2015-06-20 12:05:01 +02:00
|
|
|
const NMPlatformLink *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get(NMPlatform *self, int ifindex)
|
2014-04-22 16:02:15 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return NMP_OBJECT_CAST_LINK(nm_platform_link_get_obj(self, ifindex, TRUE));
|
2015-06-20 12:05:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_platform_link_get_by_ifname:
|
|
|
|
|
* @self: platform instance
|
|
|
|
|
* @ifname: the ifname
|
|
|
|
|
*
|
|
|
|
|
* Returns: the first #NMPlatformLink instance with the given name.
|
|
|
|
|
**/
|
|
|
|
|
const NMPlatformLink *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_by_ifname(NMPlatform *self, const char *ifname)
|
2015-06-20 12:05:01 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPObject *obj;
|
2017-07-04 12:49:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, NULL);
|
2015-06-20 12:05:01 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!ifname || !*ifname)
|
|
|
|
|
return NULL;
|
2017-07-04 12:49:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
obj = nmp_cache_lookup_link_full(nm_platform_get_cache(self),
|
|
|
|
|
0,
|
|
|
|
|
ifname,
|
|
|
|
|
TRUE,
|
|
|
|
|
NM_LINK_TYPE_NONE,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL);
|
|
|
|
|
return NMP_OBJECT_CAST_LINK(obj);
|
2017-07-04 12:49:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct _nm_platform_link_get_by_address_data {
|
2020-09-28 16:03:33 +02:00
|
|
|
gconstpointer data;
|
|
|
|
|
guint8 len;
|
2017-07-04 12:49:47 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2021-11-09 13:28:54 +01:00
|
|
|
_nm_platform_link_get_by_address_match_link(const NMPObject *obj,
|
2020-09-28 16:03:33 +02:00
|
|
|
struct _nm_platform_link_get_by_address_data *d)
|
2017-07-04 12:49:47 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return obj->link.l_address.len == d->len && !memcmp(obj->link.l_address.data, d->data, d->len);
|
2014-04-22 16:02:15 +02:00
|
|
|
}
|
|
|
|
|
|
2014-09-18 12:16:11 -05:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_get_by_address:
|
|
|
|
|
* @self: platform instance
|
|
|
|
|
* @address: a pointer to the binary hardware address
|
|
|
|
|
* @length: the size of @address in bytes
|
|
|
|
|
*
|
2015-06-20 12:05:01 +02:00
|
|
|
* Returns: the first #NMPlatformLink object with a matching
|
|
|
|
|
* address.
|
2014-09-18 12:16:11 -05:00
|
|
|
**/
|
2015-06-20 12:05:01 +02:00
|
|
|
const NMPlatformLink *
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_link_get_by_address(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMLinkType link_type,
|
|
|
|
|
gconstpointer address,
|
|
|
|
|
size_t length)
|
2014-09-18 12:16:11 -05:00
|
|
|
{
|
2021-11-09 13:28:54 +01:00
|
|
|
const NMPObject *obj;
|
2020-09-28 16:03:33 +02:00
|
|
|
struct _nm_platform_link_get_by_address_data d = {
|
|
|
|
|
.data = address,
|
|
|
|
|
.len = length,
|
|
|
|
|
};
|
2017-07-04 12:49:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, NULL);
|
2014-09-18 12:16:11 -05:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (length == 0)
|
|
|
|
|
return NULL;
|
2017-07-04 12:49:47 +02:00
|
|
|
|
2021-03-03 20:57:01 +01:00
|
|
|
if (length > _NM_UTILS_HWADDR_LEN_MAX)
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_reached(NULL);
|
|
|
|
|
if (!address)
|
|
|
|
|
g_return_val_if_reached(NULL);
|
2017-07-04 12:49:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
obj = nmp_cache_lookup_link_full(nm_platform_get_cache(self),
|
|
|
|
|
0,
|
|
|
|
|
NULL,
|
|
|
|
|
TRUE,
|
|
|
|
|
link_type,
|
|
|
|
|
(NMPObjectMatchFn) _nm_platform_link_get_by_address_match_link,
|
|
|
|
|
&d);
|
|
|
|
|
return NMP_OBJECT_CAST_LINK(obj);
|
2014-09-18 12:16:11 -05:00
|
|
|
}
|
|
|
|
|
|
platform: merge NMPlatformError with nm-error
Platform had it's own scheme for reporting errors: NMPlatformError.
Before, NMPlatformError indicated success via zero, negative integer
values are numbers from <errno.h>, and positive integer values are
platform specific codes. This changes now according to nm-error:
success is still zero. Negative values indicate a failure, where the
numeric value is either from <errno.h> or one of our error codes.
The meaning of positive values depends on the functions. Most functions
can only report an error reason (negative) and success (zero). For such
functions, positive values should never be returned (but the caller
should anticipate them).
For some functions, positive values could mean additional information
(but still success). That depends.
This is also what systemd does, except that systemd only returns
(negative) integers from <errno.h>, while we merge our own error codes
into the range of <errno.h>.
The advantage is to get rid of one way how to signal errors. The other
advantage is, that these error codes are compatible with all other
nm-errno values. For example, previously negative values indicated error
codes from <errno.h>, but it did not entail error codes from netlink.
2018-12-22 14:13:05 +01:00
|
|
|
static int
|
2021-11-09 13:28:54 +01:00
|
|
|
_link_add_check_existing(NMPlatform *self,
|
|
|
|
|
const char *name,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMLinkType type,
|
|
|
|
|
const NMPlatformLink **out_link)
|
|
|
|
|
{
|
|
|
|
|
const NMPlatformLink *pllink;
|
|
|
|
|
|
|
|
|
|
pllink = nm_platform_link_get_by_ifname(self, name);
|
|
|
|
|
if (pllink) {
|
|
|
|
|
gboolean wrong_type;
|
|
|
|
|
|
|
|
|
|
wrong_type = type != NM_LINK_TYPE_NONE && pllink->type != type;
|
|
|
|
|
_LOG2D("link: skip adding link due to existing interface of type %s%s%s",
|
|
|
|
|
nm_link_type_to_string(pllink->type),
|
|
|
|
|
wrong_type ? ", expected " : "",
|
|
|
|
|
wrong_type ? nm_link_type_to_string(type) : "");
|
|
|
|
|
if (out_link)
|
|
|
|
|
*out_link = pllink;
|
|
|
|
|
if (wrong_type)
|
|
|
|
|
return -NME_PL_WRONG_TYPE;
|
|
|
|
|
return -NME_PL_EXISTS;
|
|
|
|
|
}
|
|
|
|
|
if (out_link)
|
|
|
|
|
*out_link = NULL;
|
|
|
|
|
return 0;
|
2015-06-15 16:19:19 +02:00
|
|
|
}
|
|
|
|
|
|
2013-03-27 22:23:24 +01:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_add:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2013-03-27 22:23:24 +01:00
|
|
|
* @type: Interface type
|
2019-12-31 02:38:06 +01:00
|
|
|
* @name: Interface name
|
2019-12-31 11:47:33 +01:00
|
|
|
* @parent: the IFLA_LINK parameter or 0.
|
2023-03-01 01:21:38 +01:00
|
|
|
* @address: (nullable): set the mac address of the link
|
2014-05-13 18:13:52 +02:00
|
|
|
* @address_len: the length of the @address
|
2019-12-31 02:38:06 +01:00
|
|
|
* @extra_data: depending on @type, additional data.
|
2014-09-18 12:53:19 -05:00
|
|
|
* @out_link: on success, the link object
|
2013-03-27 22:23:24 +01:00
|
|
|
*
|
2014-09-18 12:53:19 -05:00
|
|
|
* Add a software interface. If the interface already exists and is of type
|
platform: merge NMPlatformError with nm-error
Platform had it's own scheme for reporting errors: NMPlatformError.
Before, NMPlatformError indicated success via zero, negative integer
values are numbers from <errno.h>, and positive integer values are
platform specific codes. This changes now according to nm-error:
success is still zero. Negative values indicate a failure, where the
numeric value is either from <errno.h> or one of our error codes.
The meaning of positive values depends on the functions. Most functions
can only report an error reason (negative) and success (zero). For such
functions, positive values should never be returned (but the caller
should anticipate them).
For some functions, positive values could mean additional information
(but still success). That depends.
This is also what systemd does, except that systemd only returns
(negative) integers from <errno.h>, while we merge our own error codes
into the range of <errno.h>.
The advantage is to get rid of one way how to signal errors. The other
advantage is, that these error codes are compatible with all other
nm-errno values. For example, previously negative values indicated error
codes from <errno.h>, but it did not entail error codes from netlink.
2018-12-22 14:13:05 +01:00
|
|
|
* @type, return -NME_PL_EXISTS and returns the link
|
2014-09-18 12:53:19 -05:00
|
|
|
* in @out_link. If the interface already exists and is not of type @type,
|
platform: merge NMPlatformError with nm-error
Platform had it's own scheme for reporting errors: NMPlatformError.
Before, NMPlatformError indicated success via zero, negative integer
values are numbers from <errno.h>, and positive integer values are
platform specific codes. This changes now according to nm-error:
success is still zero. Negative values indicate a failure, where the
numeric value is either from <errno.h> or one of our error codes.
The meaning of positive values depends on the functions. Most functions
can only report an error reason (negative) and success (zero). For such
functions, positive values should never be returned (but the caller
should anticipate them).
For some functions, positive values could mean additional information
(but still success). That depends.
This is also what systemd does, except that systemd only returns
(negative) integers from <errno.h>, while we merge our own error codes
into the range of <errno.h>.
The advantage is to get rid of one way how to signal errors. The other
advantage is, that these error codes are compatible with all other
nm-errno values. For example, previously negative values indicated error
codes from <errno.h>, but it did not entail error codes from netlink.
2018-12-22 14:13:05 +01:00
|
|
|
* return -NME_PL_WRONG_TYPE.
|
2015-06-15 16:19:19 +02:00
|
|
|
*
|
|
|
|
|
* Any link-changed ADDED signal will be emitted directly, before this
|
|
|
|
|
* function finishes.
|
|
|
|
|
*
|
platform: merge NMPlatformError with nm-error
Platform had it's own scheme for reporting errors: NMPlatformError.
Before, NMPlatformError indicated success via zero, negative integer
values are numbers from <errno.h>, and positive integer values are
platform specific codes. This changes now according to nm-error:
success is still zero. Negative values indicate a failure, where the
numeric value is either from <errno.h> or one of our error codes.
The meaning of positive values depends on the functions. Most functions
can only report an error reason (negative) and success (zero). For such
functions, positive values should never be returned (but the caller
should anticipate them).
For some functions, positive values could mean additional information
(but still success). That depends.
This is also what systemd does, except that systemd only returns
(negative) integers from <errno.h>, while we merge our own error codes
into the range of <errno.h>.
The advantage is to get rid of one way how to signal errors. The other
advantage is, that these error codes are compatible with all other
nm-errno values. For example, previously negative values indicated error
codes from <errno.h>, but it did not entail error codes from netlink.
2018-12-22 14:13:05 +01:00
|
|
|
* Returns: the negative nm-error on failure.
|
2013-03-27 22:23:24 +01:00
|
|
|
*/
|
2019-12-31 02:54:07 +01:00
|
|
|
int
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_link_add(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMLinkType type,
|
2021-11-09 13:28:54 +01:00
|
|
|
const char *name,
|
2020-09-28 16:03:33 +02:00
|
|
|
int parent,
|
2021-11-09 13:28:54 +01:00
|
|
|
const void *address,
|
2020-09-28 16:03:33 +02:00
|
|
|
size_t address_len,
|
2020-10-23 09:41:01 +02:00
|
|
|
guint32 mtu,
|
2020-09-28 16:03:33 +02:00
|
|
|
gconstpointer extra_data,
|
|
|
|
|
const NMPlatformLink **out_link)
|
|
|
|
|
{
|
|
|
|
|
int r;
|
2021-03-03 20:57:01 +01:00
|
|
|
char addr_buf[_NM_UTILS_HWADDR_LEN_MAX * 3];
|
2020-10-23 09:41:01 +02:00
|
|
|
char mtu_buf[16];
|
2020-09-28 16:03:33 +02:00
|
|
|
char parent_buf[64];
|
|
|
|
|
char buf[512];
|
|
|
|
|
|
|
|
|
|
_CHECK_SELF(self, klass, -NME_BUG);
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail(name, -NME_BUG);
|
|
|
|
|
g_return_val_if_fail((address != NULL) ^ (address_len == 0), -NME_BUG);
|
2021-03-03 20:57:01 +01:00
|
|
|
g_return_val_if_fail(address_len <= _NM_UTILS_HWADDR_LEN_MAX, -NME_BUG);
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(parent >= 0, -NME_BUG);
|
|
|
|
|
|
|
|
|
|
r = _link_add_check_existing(self, name, type, out_link);
|
|
|
|
|
if (r < 0)
|
|
|
|
|
return r;
|
|
|
|
|
|
|
|
|
|
_LOG2D("link: adding link: "
|
|
|
|
|
"%s " /* type */
|
|
|
|
|
"\"%s\"" /* name */
|
|
|
|
|
"%s%s" /* parent */
|
|
|
|
|
"%s%s" /* address */
|
2020-10-23 09:41:01 +02:00
|
|
|
"%s%s" /* mtu */
|
2020-09-28 16:03:33 +02:00
|
|
|
"%s" /* extra_data */
|
|
|
|
|
"",
|
|
|
|
|
nm_link_type_to_string(type),
|
|
|
|
|
name,
|
|
|
|
|
parent > 0 ? ", parent " : "",
|
|
|
|
|
parent > 0 ? nm_sprintf_buf(parent_buf, "%d", parent) : "",
|
|
|
|
|
address ? ", address: " : "",
|
|
|
|
|
address ? _nm_utils_hwaddr_ntoa(address, address_len, FALSE, addr_buf, sizeof(addr_buf))
|
|
|
|
|
: "",
|
2020-10-23 09:41:01 +02:00
|
|
|
mtu ? ", mtu: " : "",
|
|
|
|
|
mtu ? nm_sprintf_buf(mtu_buf, "%u", mtu) : "",
|
2020-09-28 16:03:33 +02:00
|
|
|
({
|
|
|
|
|
char *buf_p = buf;
|
|
|
|
|
gsize buf_len = sizeof(buf);
|
|
|
|
|
|
|
|
|
|
buf[0] = '\0';
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case NM_LINK_TYPE_BRIDGE:
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&buf_p, &buf_len, ", ");
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_bridge_to_string((const NMPlatformLnkBridge *) extra_data,
|
|
|
|
|
buf_p,
|
|
|
|
|
buf_len);
|
|
|
|
|
break;
|
|
|
|
|
case NM_LINK_TYPE_VLAN:
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&buf_p, &buf_len, ", ");
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_vlan_to_string((const NMPlatformLnkVlan *) extra_data,
|
|
|
|
|
buf_p,
|
|
|
|
|
buf_len);
|
|
|
|
|
break;
|
|
|
|
|
case NM_LINK_TYPE_VRF:
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&buf_p, &buf_len, ", ");
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_vrf_to_string((const NMPlatformLnkVrf *) extra_data,
|
|
|
|
|
buf_p,
|
|
|
|
|
buf_len);
|
|
|
|
|
break;
|
|
|
|
|
case NM_LINK_TYPE_VXLAN:
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&buf_p, &buf_len, ", ");
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_vxlan_to_string((const NMPlatformLnkVxlan *) extra_data,
|
|
|
|
|
buf_p,
|
|
|
|
|
buf_len);
|
|
|
|
|
break;
|
|
|
|
|
case NM_LINK_TYPE_VETH:
|
|
|
|
|
nm_sprintf_buf(buf, ", veth-peer \"%s\"", (const char *) extra_data);
|
|
|
|
|
break;
|
|
|
|
|
case NM_LINK_TYPE_GRE:
|
|
|
|
|
case NM_LINK_TYPE_GRETAP:
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&buf_p, &buf_len, ", ");
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_gre_to_string((const NMPlatformLnkGre *) extra_data,
|
|
|
|
|
buf_p,
|
|
|
|
|
buf_len);
|
|
|
|
|
break;
|
|
|
|
|
case NM_LINK_TYPE_SIT:
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&buf_p, &buf_len, ", ");
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_sit_to_string((const NMPlatformLnkSit *) extra_data,
|
|
|
|
|
buf_p,
|
|
|
|
|
buf_len);
|
|
|
|
|
break;
|
|
|
|
|
case NM_LINK_TYPE_IP6TNL:
|
|
|
|
|
case NM_LINK_TYPE_IP6GRE:
|
|
|
|
|
case NM_LINK_TYPE_IP6GRETAP:
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&buf_p, &buf_len, ", ");
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_ip6tnl_to_string((const NMPlatformLnkIp6Tnl *) extra_data,
|
|
|
|
|
buf_p,
|
|
|
|
|
buf_len);
|
|
|
|
|
break;
|
|
|
|
|
case NM_LINK_TYPE_IPIP:
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&buf_p, &buf_len, ", ");
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_ipip_to_string((const NMPlatformLnkIpIp *) extra_data,
|
|
|
|
|
buf_p,
|
|
|
|
|
buf_len);
|
|
|
|
|
break;
|
|
|
|
|
case NM_LINK_TYPE_MACSEC:
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&buf_p, &buf_len, ", ");
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_macsec_to_string((const NMPlatformLnkMacsec *) extra_data,
|
|
|
|
|
buf_p,
|
|
|
|
|
buf_len);
|
|
|
|
|
break;
|
|
|
|
|
case NM_LINK_TYPE_MACVLAN:
|
|
|
|
|
case NM_LINK_TYPE_MACVTAP:
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&buf_p, &buf_len, ", ");
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_macvlan_to_string((const NMPlatformLnkMacvlan *) extra_data,
|
|
|
|
|
buf_p,
|
|
|
|
|
buf_len);
|
|
|
|
|
break;
|
2022-10-24 10:17:09 +02:00
|
|
|
case NM_LINK_TYPE_VTI:
|
|
|
|
|
nm_strbuf_append_str(&buf_p, &buf_len, ", ");
|
|
|
|
|
nm_platform_lnk_vti_to_string((const NMPlatformLnkVti *) extra_data,
|
|
|
|
|
buf_p,
|
|
|
|
|
buf_len);
|
|
|
|
|
break;
|
2022-10-25 08:31:47 +02:00
|
|
|
case NM_LINK_TYPE_VTI6:
|
|
|
|
|
nm_strbuf_append_str(&buf_p, &buf_len, ", ");
|
|
|
|
|
nm_platform_lnk_vti6_to_string((const NMPlatformLnkVti6 *) extra_data,
|
|
|
|
|
buf_p,
|
|
|
|
|
buf_len);
|
|
|
|
|
break;
|
2022-07-25 16:01:35 +02:00
|
|
|
case NM_LINK_TYPE_BOND:
|
|
|
|
|
nm_strbuf_append_str(&buf_p, &buf_len, ", ");
|
|
|
|
|
nm_platform_lnk_bond_to_string((const NMPlatformLnkBond *) extra_data,
|
|
|
|
|
buf_p,
|
|
|
|
|
buf_len);
|
|
|
|
|
break;
|
2020-09-28 16:03:33 +02:00
|
|
|
default:
|
|
|
|
|
nm_assert(!extra_data);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buf;
|
|
|
|
|
}));
|
|
|
|
|
|
2020-10-23 09:41:01 +02:00
|
|
|
return klass
|
|
|
|
|
->link_add(self, type, name, parent, address, address_len, mtu, extra_data, out_link);
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-16 11:30:44 +01:00
|
|
|
int
|
2023-02-27 10:55:29 +01:00
|
|
|
nm_platform_link_change_extra(NMPlatform *self,
|
|
|
|
|
NMLinkType type,
|
|
|
|
|
int ifindex,
|
|
|
|
|
gconstpointer extra_data)
|
2022-03-16 11:30:44 +01:00
|
|
|
{
|
|
|
|
|
char buf[512];
|
|
|
|
|
const char *name = nm_platform_link_get_name(self, ifindex);
|
|
|
|
|
|
|
|
|
|
_CHECK_SELF(self, klass, -NME_BUG);
|
|
|
|
|
|
|
|
|
|
_LOG2D("link: changing link: "
|
|
|
|
|
"%s " /* type */
|
|
|
|
|
"\"%s\"" /* name */
|
|
|
|
|
"%s" /* extra_data */
|
|
|
|
|
"",
|
|
|
|
|
nm_link_type_to_string(type),
|
|
|
|
|
name,
|
|
|
|
|
({
|
|
|
|
|
char *buf_p = buf;
|
|
|
|
|
gsize buf_len = sizeof(buf);
|
|
|
|
|
|
|
|
|
|
buf[0] = '\0';
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case NM_LINK_TYPE_BRIDGE:
|
|
|
|
|
nm_strbuf_append_str(&buf_p, &buf_len, ", ");
|
|
|
|
|
nm_platform_lnk_bridge_to_string((const NMPlatformLnkBridge *) extra_data,
|
|
|
|
|
buf_p,
|
|
|
|
|
buf_len);
|
|
|
|
|
break;
|
2022-07-25 16:01:35 +02:00
|
|
|
case NM_LINK_TYPE_BOND:
|
|
|
|
|
nm_strbuf_append_str(&buf_p, &buf_len, ", ");
|
|
|
|
|
nm_platform_lnk_bond_to_string((const NMPlatformLnkBond *) extra_data,
|
|
|
|
|
buf_p,
|
|
|
|
|
buf_len);
|
|
|
|
|
break;
|
2022-03-16 11:30:44 +01:00
|
|
|
default:
|
|
|
|
|
nm_assert(!extra_data);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buf;
|
|
|
|
|
}));
|
|
|
|
|
|
2023-02-27 10:55:29 +01:00
|
|
|
return klass->link_change_extra(self, type, ifindex, extra_data);
|
2022-03-16 11:30:44 +01:00
|
|
|
}
|
|
|
|
|
|
2013-03-27 22:23:24 +01:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_delete:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2013-03-27 22:23:24 +01:00
|
|
|
* @ifindex: Interface index
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_delete(NMPlatform *self, int ifindex)
|
2013-03-27 22:23:24 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_LOG3D("link: deleting");
|
|
|
|
|
return klass->link_delete(self, ifindex);
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
2016-03-08 13:02:58 +01:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_set_netns:
|
|
|
|
|
* @self: platform instance
|
|
|
|
|
* @ifindex: Interface index
|
|
|
|
|
* @netns_fd: the file descriptor for the new netns.
|
|
|
|
|
*
|
|
|
|
|
* Returns: %TRUE on success.
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_set_netns(NMPlatform *self, int ifindex, int netns_fd)
|
2016-03-08 13:02:58 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2016-03-08 13:02:58 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
|
|
|
|
g_return_val_if_fail(netns_fd > 0, FALSE);
|
2016-03-08 13:02:58 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_LOG3D("link: move link to network namespace with fd %d", netns_fd);
|
|
|
|
|
return klass->link_set_netns(self, ifindex, netns_fd);
|
2016-03-08 13:02:58 +01:00
|
|
|
}
|
|
|
|
|
|
2013-03-27 22:23:24 +01:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_get_index:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2013-03-27 22:23:24 +01:00
|
|
|
* @name: Interface name
|
|
|
|
|
*
|
|
|
|
|
* Returns: The interface index corresponding to the given interface name
|
2018-09-14 23:49:20 -04:00
|
|
|
* or 0. Interface name is owned by #NMPlatform, don't free it.
|
2013-03-27 22:23:24 +01:00
|
|
|
*/
|
|
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_ifindex(NMPlatform *self, const char *name)
|
2013-03-27 22:23:24 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPlatformLink *pllink;
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
pllink = nm_platform_link_get_by_ifname(self, name);
|
|
|
|
|
return pllink ? pllink->ifindex : 0;
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
2016-12-26 11:54:30 +01:00
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_if_indextoname(NMPlatform *self, int ifindex, char out_ifname[static 16 /* IFNAMSIZ */])
|
2016-12-26 11:54:30 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF_NETNS(self, klass, netns, FALSE);
|
2016-12-26 11:54:30 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return nmp_utils_if_indextoname(ifindex, out_ifname);
|
2016-12-26 11:54:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_if_nametoindex(NMPlatform *self, const char *ifname)
|
2016-12-26 11:54:30 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF_NETNS(self, klass, netns, FALSE);
|
2016-12-26 11:54:30 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return nmp_utils_if_nametoindex(ifname);
|
2016-12-26 11:54:30 +01:00
|
|
|
}
|
|
|
|
|
|
2013-03-27 22:23:24 +01:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_get_name:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2013-03-27 22:23:24 +01:00
|
|
|
* @name: Interface name
|
|
|
|
|
*
|
|
|
|
|
* Returns: The interface name corresponding to the given interface index
|
2013-04-19 15:48:01 +02:00
|
|
|
* or %NULL.
|
2013-03-27 22:23:24 +01:00
|
|
|
*/
|
|
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_name(NMPlatform *self, int ifindex)
|
2013-03-27 22:23:24 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPlatformLink *pllink;
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
pllink = nm_platform_link_get(self, ifindex);
|
|
|
|
|
return pllink ? pllink->name : NULL;
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_platform_link_get_type:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2013-03-27 22:23:24 +01:00
|
|
|
* @ifindex: Interface index.
|
|
|
|
|
*
|
|
|
|
|
* Returns: Link type constant as defined in nm-platform.h. On error,
|
|
|
|
|
* NM_LINK_TYPE_NONE is returned.
|
|
|
|
|
*/
|
|
|
|
|
NMLinkType
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_type(NMPlatform *self, int ifindex)
|
2013-03-27 22:23:24 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPlatformLink *pllink;
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
pllink = nm_platform_link_get(self, ifindex);
|
|
|
|
|
return pllink ? pllink->type : NM_LINK_TYPE_NONE;
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
2013-04-26 11:43:08 -04:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_get_type_name:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2013-04-26 11:43:08 -04:00
|
|
|
* @ifindex: Interface index.
|
|
|
|
|
*
|
|
|
|
|
* Returns: A string describing the type of link. In some cases this
|
|
|
|
|
* may be more specific than nm_platform_link_get_type(), but in
|
|
|
|
|
* other cases it may not. On error, %NULL is returned.
|
|
|
|
|
*/
|
|
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_type_name(NMPlatform *self, int ifindex)
|
2013-04-26 11:43:08 -04:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPObject *obj;
|
2017-07-04 12:49:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
obj = nm_platform_link_get_obj(self, ifindex, TRUE);
|
|
|
|
|
if (!obj)
|
|
|
|
|
return NULL;
|
2017-07-04 12:49:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (obj->link.type != NM_LINK_TYPE_UNKNOWN) {
|
|
|
|
|
/* We could detect the @link_type. In this case the function returns
|
2020-09-28 14:50:01 +02:00
|
|
|
* our internal module names, which differs from rtnl_link_get_type():
|
|
|
|
|
* - NM_LINK_TYPE_INFINIBAND (gives "infiniband", instead of "ipoib")
|
|
|
|
|
* - NM_LINK_TYPE_TAP (gives "tap", instead of "tun").
|
|
|
|
|
* Note that this functions is only used by NMDeviceGeneric to
|
|
|
|
|
* set type_description. */
|
2020-09-28 16:03:33 +02:00
|
|
|
return nm_link_type_to_string(obj->link.type);
|
|
|
|
|
}
|
|
|
|
|
/* Link type not detected. Fallback to rtnl_link_get_type()/IFLA_INFO_KIND. */
|
|
|
|
|
return obj->link.kind ?: "unknown";
|
2013-04-26 11:43:08 -04:00
|
|
|
}
|
|
|
|
|
|
2021-04-23 12:08:09 +02:00
|
|
|
gboolean
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_link_get_udev_property(NMPlatform *self,
|
2021-04-23 12:08:09 +02:00
|
|
|
int ifindex,
|
2021-11-09 13:28:54 +01:00
|
|
|
const char *name,
|
2021-04-23 12:08:09 +02:00
|
|
|
const char **out_value)
|
2020-06-11 14:59:33 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
struct udev_device *udevice = NULL;
|
2021-11-09 13:28:54 +01:00
|
|
|
const char *uproperty;
|
2020-06-11 14:59:33 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
udevice = nm_platform_link_get_udev_device(self, ifindex);
|
|
|
|
|
if (!udevice)
|
|
|
|
|
return FALSE;
|
2020-06-11 14:59:33 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
uproperty = udev_device_get_property_value(udevice, name);
|
|
|
|
|
if (!uproperty)
|
|
|
|
|
return FALSE;
|
2020-06-11 14:59:33 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_SET_OUT(out_value, uproperty);
|
|
|
|
|
return TRUE;
|
2020-06-11 14:59:33 +02:00
|
|
|
}
|
|
|
|
|
|
2015-01-22 16:41:15 +01:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_get_unmanaged:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2015-06-24 14:21:27 +02:00
|
|
|
* @ifindex: interface index
|
|
|
|
|
* @unmanaged: management status (in case %TRUE is returned)
|
2015-01-22 16:41:15 +01:00
|
|
|
*
|
2015-06-24 14:21:27 +02:00
|
|
|
* Returns: %TRUE if platform overrides NM default-unmanaged status,
|
|
|
|
|
* %FALSE otherwise (with @unmanaged unmodified).
|
2015-01-22 16:41:15 +01:00
|
|
|
*/
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_unmanaged(NMPlatform *self, int ifindex, gboolean *unmanaged)
|
2015-01-22 16:41:15 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const char *value;
|
2017-07-04 12:49:47 +02:00
|
|
|
|
2021-04-23 12:08:09 +02:00
|
|
|
if (nm_platform_link_get_udev_property(self, ifindex, "NM_UNMANAGED", &value)) {
|
2021-04-23 14:40:14 +02:00
|
|
|
NM_SET_OUT(unmanaged, _nm_utils_ascii_str_to_bool(value, FALSE));
|
2020-09-28 16:03:33 +02:00
|
|
|
return TRUE;
|
|
|
|
|
}
|
2017-07-04 12:49:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return FALSE;
|
2015-01-22 16:41:15 +01:00
|
|
|
}
|
|
|
|
|
|
2013-06-20 12:48:44 +02:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_is_software:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2013-06-20 12:48:44 +02:00
|
|
|
* @ifindex: Interface index.
|
|
|
|
|
*
|
|
|
|
|
* Returns: %TRUE if ifindex belongs to a software interface, not backed by
|
|
|
|
|
* a physical device.
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_is_software(NMPlatform *self, int ifindex)
|
2013-06-20 12:48:44 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return nm_link_type_is_software(nm_platform_link_get_type(self, ifindex));
|
2013-06-20 12:48:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_platform_link_supports_slaves:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2013-06-20 12:48:44 +02:00
|
|
|
* @ifindex: Interface index.
|
|
|
|
|
*
|
|
|
|
|
* Returns: %TRUE if ifindex belongs to an interface capable of enslaving
|
|
|
|
|
* other interfaces.
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_supports_slaves(NMPlatform *self, int ifindex)
|
2013-06-20 12:48:44 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return nm_link_type_supports_slaves(nm_platform_link_get_type(self, ifindex));
|
2013-06-20 12:48:44 +02:00
|
|
|
}
|
2013-04-26 11:43:08 -04:00
|
|
|
|
2014-02-11 13:58:00 +01:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_refresh:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2014-02-11 13:58:00 +01:00
|
|
|
* @ifindex: Interface index
|
|
|
|
|
*
|
|
|
|
|
* Reload the cache for ifindex synchronously.
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_refresh(NMPlatform *self, int ifindex)
|
2014-02-11 13:58:00 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2014-02-11 13:58:00 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
2014-02-11 13:58:00 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (klass->link_refresh)
|
|
|
|
|
return klass->link_refresh(self, ifindex);
|
2014-02-11 13:58:00 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return TRUE;
|
2014-02-11 13:58:00 +01:00
|
|
|
}
|
|
|
|
|
|
2018-11-29 11:31:50 +01:00
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_ifi_flags(NMPlatform *self, int ifindex, guint requested_flags)
|
2015-06-20 12:05:01 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPlatformLink *pllink;
|
2015-06-20 12:05:01 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* include invisible links (only in netlink, not udev). */
|
|
|
|
|
pllink = NMP_OBJECT_CAST_LINK(nm_platform_link_get_obj(self, ifindex, FALSE));
|
|
|
|
|
if (!pllink)
|
|
|
|
|
return -ENODEV;
|
2018-11-29 11:31:50 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* Errors are signaled as negative values. That means, you cannot request
|
2020-09-28 14:50:01 +02:00
|
|
|
* the most significant bit (2^31) with this API. Assert against that. */
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_assert((int) requested_flags >= 0);
|
|
|
|
|
nm_assert(requested_flags < (guint) G_MAXINT);
|
2018-11-29 11:31:50 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return (int) (pllink->n_ifi_flags & requested_flags);
|
2015-06-20 12:05:01 +02:00
|
|
|
}
|
|
|
|
|
|
2013-03-27 22:23:24 +01:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_is_up:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2013-03-27 22:23:24 +01:00
|
|
|
* @ifindex: Interface index
|
|
|
|
|
*
|
|
|
|
|
* Check if the interface is up.
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_is_up(NMPlatform *self, int ifindex)
|
2013-03-27 22:23:24 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return nm_platform_link_get_ifi_flags(self, ifindex, IFF_UP) == IFF_UP;
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_platform_link_is_connected:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2013-03-27 22:23:24 +01:00
|
|
|
* @ifindex: Interface index
|
|
|
|
|
*
|
|
|
|
|
* Check if the interface is connected.
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_is_connected(NMPlatform *self, int ifindex)
|
2013-03-27 22:23:24 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPlatformLink *pllink;
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
pllink = nm_platform_link_get(self, ifindex);
|
|
|
|
|
return pllink ? pllink->connected : FALSE;
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_platform_link_uses_arp:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2013-03-27 22:23:24 +01:00
|
|
|
* @ifindex: Interface index
|
|
|
|
|
*
|
|
|
|
|
* Check if the interface is configured to use ARP.
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_uses_arp(NMPlatform *self, int ifindex)
|
2013-03-27 22:23:24 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
int f;
|
2018-11-29 11:31:50 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
f = nm_platform_link_get_ifi_flags(self, ifindex, IFF_NOARP);
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (f < 0)
|
|
|
|
|
return FALSE;
|
|
|
|
|
if (f == IFF_NOARP)
|
|
|
|
|
return FALSE;
|
|
|
|
|
return TRUE;
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
2016-04-30 16:48:32 +02:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_set_ipv6_token:
|
|
|
|
|
* @self: platform instance
|
|
|
|
|
* @ifindex: Interface index
|
|
|
|
|
* @iid: Tokenized interface identifier
|
|
|
|
|
*
|
|
|
|
|
* Sets then IPv6 tokenized interface identifier.
|
|
|
|
|
*
|
|
|
|
|
* Returns: %TRUE a tokenized identifier was available
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2021-08-25 14:53:40 +02:00
|
|
|
nm_platform_link_set_ipv6_token(NMPlatform *self, int ifindex, const NMUtilsIPv6IfaceId *iid)
|
2016-04-30 16:48:32 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2016-04-30 16:48:32 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex >= 0, FALSE);
|
2016-04-30 16:48:32 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (klass->link_set_token)
|
|
|
|
|
return klass->link_set_token(self, ifindex, iid);
|
|
|
|
|
return FALSE;
|
2016-04-30 16:48:32 +02:00
|
|
|
}
|
|
|
|
|
|
2015-06-15 14:41:35 +02:00
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_udi(NMPlatform *self, int ifindex)
|
2015-06-15 14:41:35 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
struct udev_device *device;
|
2015-06-15 14:41:35 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
device = nm_platform_link_get_udev_device(self, ifindex);
|
|
|
|
|
return device ? udev_device_get_syspath(device) : NULL;
|
2015-06-15 14:41:35 +02:00
|
|
|
}
|
2014-09-27 09:03:56 +02:00
|
|
|
|
2020-06-11 15:02:38 +02:00
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_path(NMPlatform *self, int ifindex)
|
2020-06-11 15:02:38 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const char *value = NULL;
|
2020-06-11 15:02:38 +02:00
|
|
|
|
2021-04-23 12:08:09 +02:00
|
|
|
nm_platform_link_get_udev_property(self, ifindex, "ID_PATH", &value);
|
2020-09-28 16:03:33 +02:00
|
|
|
return value;
|
2020-06-11 15:02:38 +02:00
|
|
|
}
|
|
|
|
|
|
2017-03-12 15:54:02 +01:00
|
|
|
struct udev_device *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_udev_device(NMPlatform *self, int ifindex)
|
2015-06-15 15:19:28 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPObject *obj_cache;
|
2017-07-04 12:49:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
obj_cache = nm_platform_link_get_obj(self, ifindex, FALSE);
|
|
|
|
|
return obj_cache ? obj_cache->_link.udev.device : NULL;
|
2015-06-15 15:19:28 +02:00
|
|
|
}
|
|
|
|
|
|
2021-08-23 22:31:51 +02:00
|
|
|
int
|
|
|
|
|
nm_platform_link_get_inet6_addr_gen_mode(NMPlatform *self, int ifindex)
|
2014-07-24 15:57:08 -05:00
|
|
|
{
|
2021-08-23 22:31:51 +02:00
|
|
|
return _nm_platform_link_get_inet6_addr_gen_mode(nm_platform_link_get(self, ifindex));
|
2014-07-24 15:57:08 -05:00
|
|
|
}
|
|
|
|
|
|
platform: merge NMPlatformError with nm-error
Platform had it's own scheme for reporting errors: NMPlatformError.
Before, NMPlatformError indicated success via zero, negative integer
values are numbers from <errno.h>, and positive integer values are
platform specific codes. This changes now according to nm-error:
success is still zero. Negative values indicate a failure, where the
numeric value is either from <errno.h> or one of our error codes.
The meaning of positive values depends on the functions. Most functions
can only report an error reason (negative) and success (zero). For such
functions, positive values should never be returned (but the caller
should anticipate them).
For some functions, positive values could mean additional information
(but still success). That depends.
This is also what systemd does, except that systemd only returns
(negative) integers from <errno.h>, while we merge our own error codes
into the range of <errno.h>.
The advantage is to get rid of one way how to signal errors. The other
advantage is, that these error codes are compatible with all other
nm-errno values. For example, previously negative values indicated error
codes from <errno.h>, but it did not entail error codes from netlink.
2018-12-22 14:13:05 +01:00
|
|
|
int
|
2021-08-23 22:31:51 +02:00
|
|
|
nm_platform_link_set_inet6_addr_gen_mode(NMPlatform *self, int ifindex, guint8 mode)
|
2014-07-24 15:57:08 -05:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, -NME_BUG);
|
2014-07-24 15:57:08 -05:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, -NME_BUG);
|
2014-07-24 15:57:08 -05:00
|
|
|
|
2021-08-23 22:31:51 +02:00
|
|
|
return klass->link_set_inet6_addr_gen_mode(self, ifindex, mode);
|
2014-07-24 15:57:08 -05:00
|
|
|
}
|
|
|
|
|
|
2013-03-27 22:53:55 +01:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_set_address:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2013-03-27 22:53:55 +01:00
|
|
|
* @ifindex: Interface index
|
|
|
|
|
* @address: The new MAC address
|
|
|
|
|
*
|
|
|
|
|
* Set interface MAC address.
|
|
|
|
|
*/
|
platform: merge NMPlatformError with nm-error
Platform had it's own scheme for reporting errors: NMPlatformError.
Before, NMPlatformError indicated success via zero, negative integer
values are numbers from <errno.h>, and positive integer values are
platform specific codes. This changes now according to nm-error:
success is still zero. Negative values indicate a failure, where the
numeric value is either from <errno.h> or one of our error codes.
The meaning of positive values depends on the functions. Most functions
can only report an error reason (negative) and success (zero). For such
functions, positive values should never be returned (but the caller
should anticipate them).
For some functions, positive values could mean additional information
(but still success). That depends.
This is also what systemd does, except that systemd only returns
(negative) integers from <errno.h>, while we merge our own error codes
into the range of <errno.h>.
The advantage is to get rid of one way how to signal errors. The other
advantage is, that these error codes are compatible with all other
nm-errno values. For example, previously negative values indicated error
codes from <errno.h>, but it did not entail error codes from netlink.
2018-12-22 14:13:05 +01:00
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_set_address(NMPlatform *self, int ifindex, gconstpointer address, size_t length)
|
2013-03-27 22:53:55 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
gs_free char *mac = NULL;
|
2018-05-28 17:42:56 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, -NME_BUG);
|
2013-03-27 22:53:55 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, -NME_BUG);
|
|
|
|
|
g_return_val_if_fail(address, -NME_BUG);
|
|
|
|
|
g_return_val_if_fail(length > 0, -NME_BUG);
|
2013-03-27 22:53:55 +01:00
|
|
|
|
2021-03-04 12:11:33 +01:00
|
|
|
_LOG3D("link: setting hardware address to %s",
|
|
|
|
|
_nm_utils_hwaddr_ntoa_maybe_a(address, length, &mac));
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->link_set_address(self, ifindex, address, length);
|
2013-03-27 22:53:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_platform_link_get_address:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2013-03-27 22:53:55 +01:00
|
|
|
* @ifindex: Interface index
|
|
|
|
|
* @length: Pointer to a variable to store address length
|
|
|
|
|
*
|
2014-10-03 17:37:26 -05:00
|
|
|
* Returns: the interface hardware address as an array of bytes of
|
|
|
|
|
* length @length.
|
2013-03-27 22:53:55 +01:00
|
|
|
*/
|
|
|
|
|
gconstpointer
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_address(NMPlatform *self, int ifindex, size_t *length)
|
2013-03-27 22:53:55 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPlatformLink *pllink;
|
2015-06-20 12:05:01 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
pllink = nm_platform_link_get(self, ifindex);
|
|
|
|
|
return nmp_link_address_get(pllink ? &pllink->l_address : NULL, length);
|
2013-03-27 22:53:55 +01:00
|
|
|
}
|
|
|
|
|
|
2014-10-03 17:37:26 -05:00
|
|
|
/**
|
2021-08-14 14:53:58 -04:00
|
|
|
* nm_platform_link_get_permanent_address_ethtool:
|
2014-10-03 17:37:26 -05:00
|
|
|
* @self: platform instance
|
|
|
|
|
* @ifindex: Interface index
|
2021-03-03 20:57:01 +01:00
|
|
|
* @buf: buffer of at least %_NM_UTILS_HWADDR_LEN_MAX bytes, on success
|
2014-10-03 17:37:26 -05:00
|
|
|
* the permanent hardware address
|
|
|
|
|
* @length: Pointer to a variable to store address length
|
|
|
|
|
*
|
|
|
|
|
* Returns: %TRUE on success, %FALSE on failure to read the permanent hardware
|
|
|
|
|
* address.
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_link_get_permanent_address_ethtool(NMPlatform *self,
|
2021-08-14 14:53:58 -04:00
|
|
|
int ifindex,
|
|
|
|
|
NMPLinkAddress *out_address)
|
2014-10-03 17:37:26 -05:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2014-10-03 17:37:26 -05:00
|
|
|
|
2021-08-11 08:33:08 -04:00
|
|
|
if (out_address)
|
|
|
|
|
out_address->len = 0;
|
2014-10-03 17:37:26 -05:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
2021-08-11 08:33:08 -04:00
|
|
|
g_return_val_if_fail(out_address, FALSE);
|
2014-10-03 17:37:26 -05:00
|
|
|
|
2021-08-14 14:53:58 -04:00
|
|
|
if (klass->link_get_permanent_address_ethtool)
|
|
|
|
|
return klass->link_get_permanent_address_ethtool(self, ifindex, out_address);
|
2020-09-28 16:03:33 +02:00
|
|
|
return FALSE;
|
2014-10-03 17:37:26 -05:00
|
|
|
}
|
|
|
|
|
|
2021-08-14 15:13:18 -04:00
|
|
|
gboolean
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_link_get_permanent_address(NMPlatform *self,
|
2021-08-14 15:13:18 -04:00
|
|
|
const NMPlatformLink *plink,
|
2021-11-09 13:28:54 +01:00
|
|
|
NMPLinkAddress *out_address)
|
2021-08-14 15:13:18 -04:00
|
|
|
{
|
|
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
|
|
|
|
nm_assert(out_address);
|
|
|
|
|
|
|
|
|
|
if (!plink)
|
|
|
|
|
return FALSE;
|
|
|
|
|
if (plink->l_perm_address.len > 0) {
|
|
|
|
|
*out_address = plink->l_perm_address;
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
2021-08-18 20:58:52 -04:00
|
|
|
if (nm_platform_kernel_support_get_full(NM_PLATFORM_KERNEL_SUPPORT_TYPE_IFLA_PERM_ADDRESS,
|
|
|
|
|
FALSE)
|
|
|
|
|
== NM_OPTION_BOOL_TRUE) {
|
|
|
|
|
/* kernel supports the netlink API IFLA_PERM_ADDRESS, but we don't have the
|
|
|
|
|
* address cached. There is no need to fallback to ethtool ioctl. */
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2021-08-14 15:13:18 -04:00
|
|
|
return nm_platform_link_get_permanent_address_ethtool(self, plink->ifindex, out_address);
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-27 22:53:55 +01:00
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_supports_carrier_detect(NMPlatform *self, int ifindex)
|
2013-03-27 22:53:55 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex >= 0, FALSE);
|
2013-03-27 22:53:55 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->link_supports_carrier_detect(self, ifindex);
|
2013-03-27 22:53:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_supports_vlans(NMPlatform *self, int ifindex)
|
2013-03-27 22:53:55 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex >= 0, FALSE);
|
2013-03-27 22:53:55 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->link_supports_vlans(self, ifindex);
|
2013-03-27 22:53:55 +01:00
|
|
|
}
|
|
|
|
|
|
2017-04-14 23:03:33 +02:00
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_supports_sriov(NMPlatform *self, int ifindex)
|
2017-04-14 23:03:33 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2017-04-14 23:03:33 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex >= 0, FALSE);
|
2017-04-14 23:03:33 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->link_supports_sriov(self, ifindex);
|
2017-04-14 23:03:33 +02:00
|
|
|
}
|
|
|
|
|
|
2018-05-23 14:11:14 +02:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_set_sriov_params:
|
|
|
|
|
* @self: platform instance
|
|
|
|
|
* @ifindex: the index of the interface to change
|
|
|
|
|
* @num_vfs: the number of VFs to create
|
2018-12-04 14:09:50 +01:00
|
|
|
* @autoprobe: the new autoprobe-drivers value (pass
|
2021-01-10 16:51:37 +01:00
|
|
|
* %NM_OPTION_BOOL_DEFAULT to keep current value)
|
2019-03-05 14:39:29 +01:00
|
|
|
* @callback: called when the operation finishes
|
|
|
|
|
* @callback_data: data passed to @callback
|
|
|
|
|
* @cancellable: cancellable to abort the operation
|
|
|
|
|
*
|
|
|
|
|
* Sets SR-IOV parameters asynchronously without
|
|
|
|
|
* blocking the main thread. The callback function is
|
|
|
|
|
* always invoked, and asynchronously.
|
2018-05-23 14:11:14 +02:00
|
|
|
*/
|
2019-03-05 14:39:29 +01:00
|
|
|
void
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_link_set_sriov_params_async(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
int ifindex,
|
|
|
|
|
guint num_vfs,
|
2021-01-10 16:51:37 +01:00
|
|
|
NMOptionBool autoprobe,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPlatformAsyncCallback callback,
|
|
|
|
|
gpointer callback_data,
|
2021-11-09 13:28:54 +01:00
|
|
|
GCancellable *cancellable)
|
2017-04-14 23:03:33 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF_VOID(self, klass);
|
2017-04-14 23:03:33 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_if_fail(ifindex > 0);
|
2017-04-14 23:03:33 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_LOG3D("link: setting %u total VFs and autoprobe %d", num_vfs, (int) autoprobe);
|
|
|
|
|
klass->link_set_sriov_params_async(self,
|
|
|
|
|
ifindex,
|
|
|
|
|
num_vfs,
|
|
|
|
|
autoprobe,
|
|
|
|
|
callback,
|
|
|
|
|
callback_data,
|
|
|
|
|
cancellable);
|
2017-04-14 23:03:33 +02:00
|
|
|
}
|
|
|
|
|
|
2018-05-23 14:33:24 +02:00
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_set_sriov_vfs(NMPlatform *self, int ifindex, const NMPlatformVF *const *vfs)
|
2018-05-23 14:33:24 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
guint i;
|
|
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2018-05-23 14:33:24 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
2018-05-23 14:33:24 +02:00
|
|
|
|
2022-03-30 09:13:45 +02:00
|
|
|
if (_LOGD_ENABLED()) {
|
|
|
|
|
_LOG3D("link: setting VFs");
|
|
|
|
|
for (i = 0; vfs[i]; i++) {
|
|
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
|
|
|
|
const NMPlatformVF *vf = vfs[i];
|
2018-05-23 14:33:24 +02:00
|
|
|
|
2022-03-30 09:13:45 +02:00
|
|
|
_LOG3D("link: VF %s", nm_platform_vf_to_string(vf, sbuf, sizeof(sbuf)));
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
2018-05-23 14:33:24 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->link_set_sriov_vfs(self, ifindex, vfs);
|
2018-05-23 14:33:24 +02:00
|
|
|
}
|
|
|
|
|
|
2019-03-16 17:22:35 +01:00
|
|
|
gboolean
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_link_set_bridge_vlans(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
int ifindex,
|
|
|
|
|
gboolean on_master,
|
|
|
|
|
const NMPlatformBridgeVlan *const *vlans)
|
2019-03-16 17:22:35 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
guint i;
|
|
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2019-03-16 17:22:35 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
2019-03-16 17:22:35 +01:00
|
|
|
|
2022-03-30 09:13:45 +02:00
|
|
|
if (_LOGD_ENABLED()) {
|
|
|
|
|
_LOG3D("link: %s bridge VLANs on %s",
|
|
|
|
|
vlans ? "setting" : "clearing",
|
|
|
|
|
on_master ? "master" : "self");
|
|
|
|
|
if (vlans) {
|
|
|
|
|
for (i = 0; vlans[i]; i++) {
|
|
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
|
|
|
|
const NMPlatformBridgeVlan *vlan = vlans[i];
|
|
|
|
|
|
|
|
|
|
_LOG3D("link: bridge VLAN %s",
|
|
|
|
|
nm_platform_bridge_vlan_to_string(vlan, sbuf, sizeof(sbuf)));
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
}
|
2019-03-16 17:22:35 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->link_set_bridge_vlans(self, ifindex, on_master, vlans);
|
2019-03-16 17:22:35 +01:00
|
|
|
}
|
|
|
|
|
|
2023-01-22 21:37:46 +07:00
|
|
|
gboolean
|
|
|
|
|
nm_platform_link_set_bridge_info(NMPlatform *self,
|
|
|
|
|
int ifindex,
|
|
|
|
|
const NMPlatformLinkSetBridgeInfoData *bridge_info)
|
|
|
|
|
{
|
|
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
|
|
|
|
|
|
|
|
|
if (_LOGD_ENABLED()) {
|
|
|
|
|
if (bridge_info->vlan_filtering_has) {
|
|
|
|
|
_LOG3D("link: setting bridge vlan-filtering %s",
|
|
|
|
|
bridge_info->vlan_filtering_val ? "on" : "off");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bridge_info->vlan_default_pvid_has) {
|
|
|
|
|
_LOG3D("link: setting bridge vlan-default-pvid %d", bridge_info->vlan_default_pvid_val);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return klass->link_set_bridge_info(self, ifindex, bridge_info);
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-27 22:23:24 +01:00
|
|
|
/**
|
2021-04-15 09:50:48 +02:00
|
|
|
* nm_platform_link_change_flags_full:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2021-04-15 09:50:48 +02:00
|
|
|
* @ifindex: interface index
|
|
|
|
|
* @flags_mask: flag mask to be set
|
|
|
|
|
* @flags_set: flag to be set on the flag mask
|
2013-03-27 22:23:24 +01:00
|
|
|
*
|
2021-04-15 09:50:48 +02:00
|
|
|
* Change the interface flag mask to the value specified.
|
2013-03-27 22:23:24 +01:00
|
|
|
*
|
2021-04-15 09:50:48 +02:00
|
|
|
* Returns: nm-errno code.
|
2013-03-27 22:23:24 +01:00
|
|
|
*
|
|
|
|
|
*/
|
2021-04-15 09:50:48 +02:00
|
|
|
int
|
|
|
|
|
nm_platform_link_change_flags_full(NMPlatform *self,
|
|
|
|
|
int ifindex,
|
|
|
|
|
unsigned flags_mask,
|
|
|
|
|
unsigned flags_set)
|
2013-03-27 22:23:24 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2021-04-15 09:50:48 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, -NME_BUG);
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2021-04-15 09:50:48 +02:00
|
|
|
return klass->link_change_flags(self, ifindex, flags_mask, flags_set);
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
2013-04-15 21:48:12 +02:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_set_mtu:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2013-04-15 21:48:12 +02:00
|
|
|
* @ifindex: Interface index
|
|
|
|
|
* @mtu: The new MTU value
|
|
|
|
|
*
|
|
|
|
|
* Set interface MTU.
|
|
|
|
|
*/
|
platform: merge NMPlatformError with nm-error
Platform had it's own scheme for reporting errors: NMPlatformError.
Before, NMPlatformError indicated success via zero, negative integer
values are numbers from <errno.h>, and positive integer values are
platform specific codes. This changes now according to nm-error:
success is still zero. Negative values indicate a failure, where the
numeric value is either from <errno.h> or one of our error codes.
The meaning of positive values depends on the functions. Most functions
can only report an error reason (negative) and success (zero). For such
functions, positive values should never be returned (but the caller
should anticipate them).
For some functions, positive values could mean additional information
(but still success). That depends.
This is also what systemd does, except that systemd only returns
(negative) integers from <errno.h>, while we merge our own error codes
into the range of <errno.h>.
The advantage is to get rid of one way how to signal errors. The other
advantage is, that these error codes are compatible with all other
nm-errno values. For example, previously negative values indicated error
codes from <errno.h>, but it did not entail error codes from netlink.
2018-12-22 14:13:05 +01:00
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_set_mtu(NMPlatform *self, int ifindex, guint32 mtu)
|
2013-04-15 21:48:12 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2013-04-15 21:48:12 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex >= 0, FALSE);
|
|
|
|
|
g_return_val_if_fail(mtu > 0, FALSE);
|
2013-04-15 21:48:12 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_LOG3D("link: setting mtu %" G_GUINT32_FORMAT, mtu);
|
|
|
|
|
return klass->link_set_mtu(self, ifindex, mtu);
|
2013-04-15 21:48:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_platform_link_get_mtu:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2013-04-15 21:48:12 +02:00
|
|
|
* @ifindex: Interface index
|
|
|
|
|
*
|
|
|
|
|
* Returns: MTU value for the interface or 0 on error.
|
|
|
|
|
*/
|
|
|
|
|
guint32
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_mtu(NMPlatform *self, int ifindex)
|
2013-04-15 21:48:12 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPlatformLink *pllink;
|
2013-04-15 21:48:12 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
pllink = nm_platform_link_get(self, ifindex);
|
|
|
|
|
return pllink ? pllink->mtu : 0;
|
2013-04-15 21:48:12 +02:00
|
|
|
}
|
|
|
|
|
|
2017-07-03 10:10:34 +02:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_set_name:
|
|
|
|
|
* @self: platform instance
|
|
|
|
|
* @ifindex: Interface index
|
|
|
|
|
* @name: The new interface name
|
|
|
|
|
*
|
|
|
|
|
* Set interface name.
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_set_name(NMPlatform *self, int ifindex, const char *name)
|
2017-07-03 10:10:34 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2017-07-03 10:10:34 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex >= 0, FALSE);
|
|
|
|
|
g_return_val_if_fail(name, FALSE);
|
2017-07-03 10:10:34 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_LOG3D("link: setting name %s", name);
|
2017-07-03 10:10:34 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (strlen(name) + 1 > IFNAMSIZ)
|
|
|
|
|
return FALSE;
|
2017-07-03 10:10:34 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->link_set_name(self, ifindex, name);
|
2017-07-03 10:10:34 +02:00
|
|
|
}
|
|
|
|
|
|
2023-02-16 16:37:54 +01:00
|
|
|
gboolean
|
|
|
|
|
nm_platform_link_change(NMPlatform *self,
|
|
|
|
|
int ifindex,
|
|
|
|
|
NMPlatformLinkProps *props,
|
2023-03-03 16:36:23 +01:00
|
|
|
NMPlatformLinkBondPort *bond_port,
|
2023-02-16 16:37:54 +01:00
|
|
|
NMPlatformLinkChangeFlags flags)
|
|
|
|
|
{
|
2023-03-09 12:18:14 +01:00
|
|
|
char sbuf_prio[100];
|
|
|
|
|
|
2023-02-16 16:37:54 +01:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail(ifindex >= 0, FALSE);
|
|
|
|
|
|
2023-03-03 16:36:23 +01:00
|
|
|
nm_assert(!NM_FLAGS_ANY(flags,
|
|
|
|
|
NM_PLATFORM_LINK_CHANGE_TX_QUEUE_LENGTH
|
|
|
|
|
| NM_PLATFORM_LINK_CHANGE_GSO_MAX_SIZE
|
|
|
|
|
| NM_PLATFORM_LINK_CHANGE_GSO_MAX_SEGMENTS
|
|
|
|
|
| NM_PLATFORM_LINK_CHANGE_GRO_MAX_SIZE)
|
|
|
|
|
|| props);
|
2023-02-16 16:37:54 +01:00
|
|
|
|
|
|
|
|
if (_LOGD_ENABLED()) {
|
|
|
|
|
nm_auto_free_gstring GString *str = g_string_new("");
|
|
|
|
|
|
|
|
|
|
if (flags & NM_PLATFORM_LINK_CHANGE_TX_QUEUE_LENGTH)
|
|
|
|
|
g_string_append_printf(str, "tx-queue-length %u ", props->tx_queue_length);
|
|
|
|
|
if (flags & NM_PLATFORM_LINK_CHANGE_GSO_MAX_SIZE)
|
|
|
|
|
g_string_append_printf(str, "gso_max_size %u ", props->gso_max_size);
|
|
|
|
|
if (flags & NM_PLATFORM_LINK_CHANGE_GSO_MAX_SEGMENTS)
|
|
|
|
|
g_string_append_printf(str, "gso_max_segments %u ", props->gso_max_segments);
|
|
|
|
|
if (flags & NM_PLATFORM_LINK_CHANGE_GRO_MAX_SIZE)
|
|
|
|
|
g_string_append_printf(str, "gro_max_size %u ", props->gro_max_size);
|
2023-03-09 12:18:14 +01:00
|
|
|
if (bond_port) {
|
|
|
|
|
nm_assert(bond_port->prio_has || bond_port->prio == 0);
|
|
|
|
|
g_string_append_printf(str,
|
|
|
|
|
"bond-port queue-id %d %s",
|
|
|
|
|
bond_port->queue_id,
|
|
|
|
|
bond_port->prio_has || bond_port->prio != 0
|
|
|
|
|
? nm_sprintf_buf(sbuf_prio,
|
|
|
|
|
"prio%s %" G_GINT32_FORMAT,
|
|
|
|
|
!bond_port->prio_has ? "?" : "",
|
|
|
|
|
bond_port->prio)
|
|
|
|
|
: "");
|
|
|
|
|
}
|
2023-02-16 16:37:54 +01:00
|
|
|
|
|
|
|
|
if (str->len > 0 && str->str[str->len - 1] == ' ')
|
|
|
|
|
g_string_truncate(str, str->len - 1);
|
|
|
|
|
|
|
|
|
|
_LOG3D("link: change: %s", str->str);
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-03 16:36:23 +01:00
|
|
|
return klass->link_change(self,
|
|
|
|
|
ifindex,
|
|
|
|
|
props,
|
|
|
|
|
bond_port ? NM_PORT_KIND_BOND : NM_PORT_KIND_NONE,
|
|
|
|
|
(const NMPlatformLinkPortData *) bond_port,
|
|
|
|
|
flags);
|
2023-02-16 16:37:54 +01:00
|
|
|
}
|
|
|
|
|
|
2013-10-11 14:59:26 -04:00
|
|
|
/**
|
2015-03-24 12:18:48 -05:00
|
|
|
* nm_platform_link_get_physical_port_id:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2013-10-11 14:59:26 -04:00
|
|
|
* @ifindex: Interface index
|
|
|
|
|
*
|
2015-03-24 12:18:48 -05:00
|
|
|
* The physical port ID, if present, indicates some unique identifier of
|
|
|
|
|
* the parent interface (eg, the physical port of which this link is a child).
|
|
|
|
|
* Two links that report the same physical port ID can be assumed to be
|
|
|
|
|
* children of the same physical port and may share resources that limit
|
|
|
|
|
* their abilities.
|
|
|
|
|
*
|
2013-10-11 14:59:26 -04:00
|
|
|
* Returns: physical port ID for the interface, or %NULL on error
|
|
|
|
|
* or if the interface has no physical port ID.
|
|
|
|
|
*/
|
|
|
|
|
char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_physical_port_id(NMPlatform *self, int ifindex)
|
2013-10-11 14:59:26 -04:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, NULL);
|
2013-10-11 14:59:26 -04:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex >= 0, NULL);
|
2013-10-11 14:59:26 -04:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (klass->link_get_physical_port_id)
|
|
|
|
|
return klass->link_get_physical_port_id(self, ifindex);
|
|
|
|
|
return NULL;
|
2013-10-11 14:59:26 -04:00
|
|
|
}
|
|
|
|
|
|
2015-03-24 12:35:36 -05:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_get_dev_id:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2015-03-24 12:35:36 -05:00
|
|
|
* @ifindex: Interface index
|
|
|
|
|
*
|
|
|
|
|
* In contrast to the physical device ID (which indicates which parent a
|
|
|
|
|
* child has) the device ID differentiates sibling devices that may share
|
|
|
|
|
* the same MAC address.
|
|
|
|
|
*
|
|
|
|
|
* Returns: device ID for the interface, or 0 on error or if the
|
|
|
|
|
* interface has no device ID.
|
|
|
|
|
*/
|
|
|
|
|
guint
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_dev_id(NMPlatform *self, int ifindex)
|
2015-03-24 12:35:36 -05:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, 0);
|
2015-03-24 12:35:36 -05:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex >= 0, 0);
|
2015-03-24 12:35:36 -05:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (klass->link_get_dev_id)
|
|
|
|
|
return klass->link_get_dev_id(self, ifindex);
|
|
|
|
|
return 0;
|
2015-03-24 12:35:36 -05:00
|
|
|
}
|
|
|
|
|
|
2014-02-05 11:56:44 +01:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_get_wake_onlan:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2014-02-05 11:56:44 +01:00
|
|
|
* @ifindex: Interface index
|
|
|
|
|
*
|
|
|
|
|
* Returns: the "Wake-on-LAN" status for @ifindex.
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_wake_on_lan(NMPlatform *self, int ifindex)
|
2014-02-05 11:56:44 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2014-02-05 11:56:44 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex >= 0, FALSE);
|
2014-02-05 11:56:44 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (klass->link_get_wake_on_lan)
|
|
|
|
|
return klass->link_get_wake_on_lan(self, ifindex);
|
|
|
|
|
return FALSE;
|
2014-02-05 11:56:44 +01:00
|
|
|
}
|
|
|
|
|
|
2014-10-03 13:41:49 -05:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_get_driver_info:
|
|
|
|
|
* @self: platform instance
|
|
|
|
|
* @ifindex: Interface index
|
|
|
|
|
* @out_driver_name: (transfer full): on success, the driver name if available
|
|
|
|
|
* @out_driver_version: (transfer full): on success, the driver version if available
|
|
|
|
|
* @out_fw_version: (transfer full): on success, the firmware version if available
|
|
|
|
|
*
|
|
|
|
|
* Returns: %TRUE on success (though @out_driver_name, @out_driver_version and
|
|
|
|
|
* @out_fw_version can be %NULL if no information was available), %FALSE on
|
|
|
|
|
* failure.
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_driver_info(NMPlatform *self,
|
|
|
|
|
int ifindex,
|
2021-11-09 13:28:54 +01:00
|
|
|
char **out_driver_name,
|
|
|
|
|
char **out_driver_version,
|
|
|
|
|
char **out_fw_version)
|
2014-10-03 13:41:49 -05:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2014-10-03 13:41:49 -05:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex >= 0, FALSE);
|
2014-10-03 13:41:49 -05:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->link_get_driver_info(self,
|
|
|
|
|
ifindex,
|
|
|
|
|
out_driver_name,
|
|
|
|
|
out_driver_version,
|
|
|
|
|
out_fw_version);
|
2014-10-03 13:41:49 -05:00
|
|
|
}
|
|
|
|
|
|
2013-03-27 22:53:55 +01:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_enslave:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2013-03-27 22:53:55 +01:00
|
|
|
* @master: Interface index of the master
|
2018-07-18 17:59:33 +02:00
|
|
|
* @ifindex: Interface index of the slave
|
2013-03-27 22:53:55 +01:00
|
|
|
*
|
2018-07-18 17:59:33 +02:00
|
|
|
* Enslave @ifindex to @master.
|
2013-03-27 22:53:55 +01:00
|
|
|
*/
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_enslave(NMPlatform *self, int master, int ifindex)
|
2013-03-27 22:53:55 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2013-03-27 22:53:55 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(master > 0, FALSE);
|
|
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
2013-03-27 22:53:55 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_LOG3D("link: enslaving to master '%s'", nm_platform_link_get_name(self, master));
|
|
|
|
|
return klass->link_enslave(self, master, ifindex);
|
2013-03-27 22:53:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_platform_link_release:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2013-03-27 22:53:55 +01:00
|
|
|
* @master: Interface index of the master
|
2018-07-18 17:59:33 +02:00
|
|
|
* @ifindex: Interface index of the slave
|
2013-03-27 22:53:55 +01:00
|
|
|
*
|
|
|
|
|
* Release @slave from @master.
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_release(NMPlatform *self, int master, int ifindex)
|
2013-03-27 22:53:55 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2013-03-27 22:53:55 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(master > 0, FALSE);
|
|
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
2013-03-27 22:53:55 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (nm_platform_link_get_master(self, ifindex) != master)
|
|
|
|
|
return FALSE;
|
2013-03-27 22:53:55 +01:00
|
|
|
|
2022-02-22 18:43:46 +01:00
|
|
|
_LOG3D("link: releasing %d from master '%s' (%d)",
|
|
|
|
|
ifindex,
|
|
|
|
|
nm_platform_link_get_name(self, master),
|
|
|
|
|
master);
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->link_release(self, master, ifindex);
|
2013-03-27 22:53:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_platform_link_get_master:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2013-03-27 22:53:55 +01:00
|
|
|
* @slave: Interface index of the slave.
|
|
|
|
|
*
|
2017-05-11 12:08:02 +02:00
|
|
|
* Returns: Interface index of the slave's master.
|
2013-03-27 22:53:55 +01:00
|
|
|
*/
|
|
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_master(NMPlatform *self, int slave)
|
2013-03-27 22:53:55 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPlatformLink *pllink;
|
2015-06-20 12:05:01 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
pllink = nm_platform_link_get(self, slave);
|
|
|
|
|
return pllink ? pllink->master : 0;
|
2013-03-27 22:53:55 +01:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 13:44:44 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2016-03-21 15:22:10 +01:00
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_can_assume(NMPlatform *self, int ifindex)
|
2016-03-21 15:22:10 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2016-03-21 15:22:10 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (klass->link_can_assume)
|
|
|
|
|
return klass->link_can_assume(self, ifindex);
|
|
|
|
|
g_return_val_if_reached(FALSE);
|
2016-03-21 15:22:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2015-10-29 11:27:55 +01:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_get_lnk:
|
|
|
|
|
* @self: the platform instance
|
|
|
|
|
* @ifindex: the link ifindex to lookup
|
|
|
|
|
* @link_type: filter by link-type.
|
2023-03-01 01:21:38 +01:00
|
|
|
* @out_link: (out) (optional) (nullable): returns the platform link instance
|
2015-10-29 11:27:55 +01:00
|
|
|
*
|
|
|
|
|
* If the function returns %NULL, that could mean that no such ifindex
|
|
|
|
|
* exists, of that the link has no lnk data. You can find that out
|
|
|
|
|
* by checking @out_link. @out_link will always be set if a link
|
|
|
|
|
* with @ifindex exists.
|
|
|
|
|
*
|
|
|
|
|
* If @link_type is %NM_LINK_TYPE_NONE, the function returns the lnk
|
|
|
|
|
* object if it is present. If you set link-type, you can be sure
|
|
|
|
|
* that only a link type of the matching type is returned (or %NULL).
|
|
|
|
|
*
|
2023-03-01 01:21:38 +01:00
|
|
|
* Returns: (nullable): the internal link lnk object. The returned object
|
2015-10-29 11:27:55 +01:00
|
|
|
* is owned by the platform cache and must not be modified. Note
|
|
|
|
|
* however, that the object is guaranteed to be immutable, so
|
2018-09-14 23:49:20 -04:00
|
|
|
* you can safely take a reference and keep it for yourself
|
2015-10-29 11:27:55 +01:00
|
|
|
* (but don't modify it).
|
|
|
|
|
*/
|
|
|
|
|
const NMPObject *
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_link_get_lnk(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
int ifindex,
|
|
|
|
|
NMLinkType link_type,
|
|
|
|
|
const NMPlatformLink **out_link)
|
2015-10-12 13:44:44 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPObject *obj;
|
2017-07-04 12:49:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
obj = nm_platform_link_get_obj(self, ifindex, TRUE);
|
|
|
|
|
if (!obj) {
|
|
|
|
|
NM_SET_OUT(out_link, NULL);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2017-07-04 12:49:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_SET_OUT(out_link, &obj->link);
|
2017-07-04 12:49:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!obj->_link.netlink.lnk)
|
|
|
|
|
return NULL;
|
|
|
|
|
if (link_type != NM_LINK_TYPE_NONE
|
|
|
|
|
&& (link_type != obj->link.type
|
|
|
|
|
|| link_type != NMP_OBJECT_GET_CLASS(obj->_link.netlink.lnk)->lnk_link_type))
|
|
|
|
|
return NULL;
|
2017-07-04 12:49:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return obj->_link.netlink.lnk;
|
2015-10-12 13:44:44 +02:00
|
|
|
}
|
|
|
|
|
|
2015-10-29 11:27:55 +01:00
|
|
|
static gconstpointer
|
2020-09-28 16:03:33 +02:00
|
|
|
_link_get_lnk(NMPlatform *self, int ifindex, NMLinkType link_type, const NMPlatformLink **out_link)
|
2015-10-29 11:27:55 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPObject *lnk;
|
2015-10-29 11:27:55 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
lnk = nm_platform_link_get_lnk(self, ifindex, link_type, out_link);
|
|
|
|
|
return lnk ? &lnk->object : NULL;
|
2015-10-29 11:27:55 +01:00
|
|
|
}
|
|
|
|
|
|
2022-07-25 16:01:35 +02:00
|
|
|
const NMPlatformLnkBond *
|
|
|
|
|
nm_platform_link_get_lnk_bond(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
|
|
|
|
{
|
|
|
|
|
return _link_get_lnk(self, ifindex, NM_LINK_TYPE_BOND, out_link);
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-05 13:46:28 -04:00
|
|
|
const NMPlatformLnkBridge *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_lnk_bridge(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
2020-08-05 13:46:28 -04:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return _link_get_lnk(self, ifindex, NM_LINK_TYPE_BRIDGE, out_link);
|
2020-08-05 13:46:28 -04:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 15:15:21 +02:00
|
|
|
const NMPlatformLnkGre *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_lnk_gre(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
2015-10-12 15:15:21 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return _link_get_lnk(self, ifindex, NM_LINK_TYPE_GRE, out_link);
|
2015-10-12 15:15:21 +02:00
|
|
|
}
|
|
|
|
|
|
2018-06-26 10:45:35 +02:00
|
|
|
const NMPlatformLnkGre *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_lnk_gretap(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
2018-06-26 10:45:35 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return _link_get_lnk(self, ifindex, NM_LINK_TYPE_GRETAP, out_link);
|
2018-06-26 10:45:35 +02:00
|
|
|
}
|
|
|
|
|
|
2015-10-15 15:47:14 +02:00
|
|
|
const NMPlatformLnkInfiniband *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_lnk_infiniband(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
2015-10-15 15:47:14 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return _link_get_lnk(self, ifindex, NM_LINK_TYPE_INFINIBAND, out_link);
|
2015-10-15 15:47:14 +02:00
|
|
|
}
|
|
|
|
|
|
2015-11-27 22:22:25 +01:00
|
|
|
const NMPlatformLnkIp6Tnl *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_lnk_ip6tnl(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
2015-11-27 22:22:25 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return _link_get_lnk(self, ifindex, NM_LINK_TYPE_IP6TNL, out_link);
|
2015-11-27 22:22:25 +01:00
|
|
|
}
|
|
|
|
|
|
2018-06-26 12:06:43 +02:00
|
|
|
const NMPlatformLnkIp6Tnl *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_lnk_ip6gre(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
2018-06-26 12:06:43 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return _link_get_lnk(self, ifindex, NM_LINK_TYPE_IP6GRE, out_link);
|
2018-06-26 12:06:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const NMPlatformLnkIp6Tnl *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_lnk_ip6gretap(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
2018-06-26 12:06:43 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return _link_get_lnk(self, ifindex, NM_LINK_TYPE_IP6GRETAP, out_link);
|
2018-06-26 12:06:43 +02:00
|
|
|
}
|
|
|
|
|
|
2015-11-27 14:01:56 +01:00
|
|
|
const NMPlatformLnkIpIp *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_lnk_ipip(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
2015-11-27 14:01:56 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return _link_get_lnk(self, ifindex, NM_LINK_TYPE_IPIP, out_link);
|
2015-11-27 14:01:56 +01:00
|
|
|
}
|
|
|
|
|
|
2016-06-30 18:20:09 +02:00
|
|
|
const NMPlatformLnkMacsec *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_lnk_macsec(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
2016-06-30 18:20:09 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return _link_get_lnk(self, ifindex, NM_LINK_TYPE_MACSEC, out_link);
|
2016-06-30 18:20:09 +02:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 15:15:21 +02:00
|
|
|
const NMPlatformLnkMacvlan *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_lnk_macvlan(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
2015-10-12 15:15:21 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return _link_get_lnk(self, ifindex, NM_LINK_TYPE_MACVLAN, out_link);
|
2015-10-12 15:15:21 +02:00
|
|
|
}
|
|
|
|
|
|
2019-12-31 14:19:40 +01:00
|
|
|
const NMPlatformLnkMacvlan *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_lnk_macvtap(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
2015-12-04 09:49:39 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return _link_get_lnk(self, ifindex, NM_LINK_TYPE_MACVTAP, out_link);
|
2015-12-04 09:49:39 +01:00
|
|
|
}
|
|
|
|
|
|
2015-11-11 18:41:48 +01:00
|
|
|
const NMPlatformLnkSit *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_lnk_sit(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
2015-11-11 18:41:48 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return _link_get_lnk(self, ifindex, NM_LINK_TYPE_SIT, out_link);
|
2015-11-11 18:41:48 +01:00
|
|
|
}
|
|
|
|
|
|
core/platform: add support for TUN/TAP netlink support and various cleanup
Kernel recently got support for exposing TUN/TAP information on netlink
[1], [2], [3]. Add support for it to the platform cache.
The advantage of using netlink is that querying sysctl bypasses the
order of events of the netlink socket. It is out of sync and racy. For
example, platform cache might still think that a tun device exists, but
a subsequent lookup at sysfs might fail because the device was deleted
in the meantime. Another point is, that we don't get change
notifications via sysctl and that it requires various extra syscalls
to read the device information. If the tun information is present on
netlink, put it into the cache. This bypasses checking sysctl while
we keep looking at sysctl for backward compatibility until we require
support from kernel.
Notes:
- we had two link types NM_LINK_TYPE_TAP and NM_LINK_TYPE_TUN. This
deviates from the model of how kernel treats TUN/TAP devices, which
makes it more complicated. The link type of a NMPlatformLink instance
should match what kernel thinks about the device. Point in case,
when parsing RTM_NETLINK messages, we very early need to determine
the link type (_linktype_get_type()). However, to determine the
type of a TUN/TAP at that point, we need to look into nested
netlink attributes which in turn depend on the type (IFLA_INFO_KIND
and IFLA_INFO_DATA), or even worse, we would need to look into
sysctl for older kernel vesions. Now, the TUN/TAP type is a property
of the link type NM_LINK_TYPE_TUN, instead of determining two
different link types.
- various parts of the API (both kernel's sysctl vs. netlink) and
NMDeviceTun vs. NMSettingTun disagree whether the PI is positive
(NM_SETTING_TUN_PI, IFLA_TUN_PI, NMPlatformLnkTun.pi) or inverted
(NM_DEVICE_TUN_NO_PI, IFF_NO_PI). There is no consistent way,
but prefer the positive form for internal API at NMPlatformLnkTun.pi.
- previously NMDeviceTun.mode could not change after initializing
the object. Allow for that to happen, because forcing some properties
that are reported by kernel to not change is wrong, in case they
might change. Of course, in practice kernel doesn't allow the device
to ever change its type, but the type property of the NMDeviceTun
should not make that assumption, because, if it actually changes, what
would it mean?
- note that as of now, new netlink API is not yet merged to mainline Linus
tree. Shortcut _parse_lnk_tun() to not accidentally use unstable API
for now.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1277457
[2] https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/commit/?id=1ec010e705934c8acbe7dbf31afc81e60e3d828b
[3] https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=118eda77d6602616bc523a17ee45171e879d1818
https://bugzilla.redhat.com/show_bug.cgi?id=1547213
https://github.com/NetworkManager/NetworkManager/pull/77
2018-03-13 15:29:03 +01:00
|
|
|
const NMPlatformLnkTun *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_lnk_tun(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
core/platform: add support for TUN/TAP netlink support and various cleanup
Kernel recently got support for exposing TUN/TAP information on netlink
[1], [2], [3]. Add support for it to the platform cache.
The advantage of using netlink is that querying sysctl bypasses the
order of events of the netlink socket. It is out of sync and racy. For
example, platform cache might still think that a tun device exists, but
a subsequent lookup at sysfs might fail because the device was deleted
in the meantime. Another point is, that we don't get change
notifications via sysctl and that it requires various extra syscalls
to read the device information. If the tun information is present on
netlink, put it into the cache. This bypasses checking sysctl while
we keep looking at sysctl for backward compatibility until we require
support from kernel.
Notes:
- we had two link types NM_LINK_TYPE_TAP and NM_LINK_TYPE_TUN. This
deviates from the model of how kernel treats TUN/TAP devices, which
makes it more complicated. The link type of a NMPlatformLink instance
should match what kernel thinks about the device. Point in case,
when parsing RTM_NETLINK messages, we very early need to determine
the link type (_linktype_get_type()). However, to determine the
type of a TUN/TAP at that point, we need to look into nested
netlink attributes which in turn depend on the type (IFLA_INFO_KIND
and IFLA_INFO_DATA), or even worse, we would need to look into
sysctl for older kernel vesions. Now, the TUN/TAP type is a property
of the link type NM_LINK_TYPE_TUN, instead of determining two
different link types.
- various parts of the API (both kernel's sysctl vs. netlink) and
NMDeviceTun vs. NMSettingTun disagree whether the PI is positive
(NM_SETTING_TUN_PI, IFLA_TUN_PI, NMPlatformLnkTun.pi) or inverted
(NM_DEVICE_TUN_NO_PI, IFF_NO_PI). There is no consistent way,
but prefer the positive form for internal API at NMPlatformLnkTun.pi.
- previously NMDeviceTun.mode could not change after initializing
the object. Allow for that to happen, because forcing some properties
that are reported by kernel to not change is wrong, in case they
might change. Of course, in practice kernel doesn't allow the device
to ever change its type, but the type property of the NMDeviceTun
should not make that assumption, because, if it actually changes, what
would it mean?
- note that as of now, new netlink API is not yet merged to mainline Linus
tree. Shortcut _parse_lnk_tun() to not accidentally use unstable API
for now.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1277457
[2] https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/commit/?id=1ec010e705934c8acbe7dbf31afc81e60e3d828b
[3] https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=118eda77d6602616bc523a17ee45171e879d1818
https://bugzilla.redhat.com/show_bug.cgi?id=1547213
https://github.com/NetworkManager/NetworkManager/pull/77
2018-03-13 15:29:03 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return _link_get_lnk(self, ifindex, NM_LINK_TYPE_TUN, out_link);
|
core/platform: add support for TUN/TAP netlink support and various cleanup
Kernel recently got support for exposing TUN/TAP information on netlink
[1], [2], [3]. Add support for it to the platform cache.
The advantage of using netlink is that querying sysctl bypasses the
order of events of the netlink socket. It is out of sync and racy. For
example, platform cache might still think that a tun device exists, but
a subsequent lookup at sysfs might fail because the device was deleted
in the meantime. Another point is, that we don't get change
notifications via sysctl and that it requires various extra syscalls
to read the device information. If the tun information is present on
netlink, put it into the cache. This bypasses checking sysctl while
we keep looking at sysctl for backward compatibility until we require
support from kernel.
Notes:
- we had two link types NM_LINK_TYPE_TAP and NM_LINK_TYPE_TUN. This
deviates from the model of how kernel treats TUN/TAP devices, which
makes it more complicated. The link type of a NMPlatformLink instance
should match what kernel thinks about the device. Point in case,
when parsing RTM_NETLINK messages, we very early need to determine
the link type (_linktype_get_type()). However, to determine the
type of a TUN/TAP at that point, we need to look into nested
netlink attributes which in turn depend on the type (IFLA_INFO_KIND
and IFLA_INFO_DATA), or even worse, we would need to look into
sysctl for older kernel vesions. Now, the TUN/TAP type is a property
of the link type NM_LINK_TYPE_TUN, instead of determining two
different link types.
- various parts of the API (both kernel's sysctl vs. netlink) and
NMDeviceTun vs. NMSettingTun disagree whether the PI is positive
(NM_SETTING_TUN_PI, IFLA_TUN_PI, NMPlatformLnkTun.pi) or inverted
(NM_DEVICE_TUN_NO_PI, IFF_NO_PI). There is no consistent way,
but prefer the positive form for internal API at NMPlatformLnkTun.pi.
- previously NMDeviceTun.mode could not change after initializing
the object. Allow for that to happen, because forcing some properties
that are reported by kernel to not change is wrong, in case they
might change. Of course, in practice kernel doesn't allow the device
to ever change its type, but the type property of the NMDeviceTun
should not make that assumption, because, if it actually changes, what
would it mean?
- note that as of now, new netlink API is not yet merged to mainline Linus
tree. Shortcut _parse_lnk_tun() to not accidentally use unstable API
for now.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1277457
[2] https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/commit/?id=1ec010e705934c8acbe7dbf31afc81e60e3d828b
[3] https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=118eda77d6602616bc523a17ee45171e879d1818
https://bugzilla.redhat.com/show_bug.cgi?id=1547213
https://github.com/NetworkManager/NetworkManager/pull/77
2018-03-13 15:29:03 +01:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 13:44:44 +02:00
|
|
|
const NMPlatformLnkVlan *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_lnk_vlan(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
2015-10-12 13:44:44 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return _link_get_lnk(self, ifindex, NM_LINK_TYPE_VLAN, out_link);
|
2015-10-12 13:44:44 +02:00
|
|
|
}
|
|
|
|
|
|
2019-12-05 10:35:25 +01:00
|
|
|
const NMPlatformLnkVrf *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_lnk_vrf(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
2019-12-05 10:35:25 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return _link_get_lnk(self, ifindex, NM_LINK_TYPE_VRF, out_link);
|
2019-12-05 10:35:25 +01:00
|
|
|
}
|
|
|
|
|
|
2022-10-24 10:17:09 +02:00
|
|
|
const NMPlatformLnkVti *
|
|
|
|
|
nm_platform_link_get_lnk_vti(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
|
|
|
|
{
|
|
|
|
|
return _link_get_lnk(self, ifindex, NM_LINK_TYPE_VTI, out_link);
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-25 08:31:47 +02:00
|
|
|
const NMPlatformLnkVti6 *
|
|
|
|
|
nm_platform_link_get_lnk_vti6(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
|
|
|
|
{
|
|
|
|
|
return _link_get_lnk(self, ifindex, NM_LINK_TYPE_VTI6, out_link);
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-12 15:15:21 +02:00
|
|
|
const NMPlatformLnkVxlan *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_lnk_vxlan(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
2015-10-12 15:15:21 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return _link_get_lnk(self, ifindex, NM_LINK_TYPE_VXLAN, out_link);
|
2015-10-12 15:15:21 +02:00
|
|
|
}
|
|
|
|
|
|
2018-07-28 14:54:33 +02:00
|
|
|
const NMPlatformLnkWireGuard *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_get_lnk_wireguard(NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
2018-03-13 13:35:35 +00:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return _link_get_lnk(self, ifindex, NM_LINK_TYPE_WIREGUARD, out_link);
|
2018-03-13 13:35:35 +00:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 13:44:44 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
static NM_UTILS_FLAGS2STR_DEFINE(
|
|
|
|
|
_wireguard_change_flags_to_string,
|
|
|
|
|
NMPlatformWireGuardChangeFlags,
|
|
|
|
|
NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_FLAG_NONE, "none"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_FLAG_REPLACE_PEERS, "replace-peers"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_PRIVATE_KEY, "has-private-key"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_LISTEN_PORT, "has-listen-port"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_FWMARK, "has-fwmark"), );
|
|
|
|
|
|
|
|
|
|
static NM_UTILS_FLAGS2STR_DEFINE(
|
|
|
|
|
_wireguard_change_peer_flags_to_string,
|
|
|
|
|
NMPlatformWireGuardChangePeerFlags,
|
|
|
|
|
NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_NONE, "none"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_REMOVE_ME, "remove"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_PRESHARED_KEY, "psk"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_KEEPALIVE_INTERVAL, "ka"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_ENDPOINT, "ep"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_HAS_ALLOWEDIPS, "aips"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_REPLACE_ALLOWEDIPS, "remove-aips"), );
|
2019-02-11 11:07:06 +01:00
|
|
|
|
2018-12-25 18:41:28 +01:00
|
|
|
int
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_link_wireguard_change(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
int ifindex,
|
2021-11-09 13:28:54 +01:00
|
|
|
const NMPlatformLnkWireGuard *lnk_wireguard,
|
|
|
|
|
const NMPWireGuardPeer *peers,
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPlatformWireGuardChangePeerFlags *peer_flags,
|
|
|
|
|
guint peers_len,
|
|
|
|
|
NMPlatformWireGuardChangeFlags change_flags)
|
|
|
|
|
{
|
|
|
|
|
_CHECK_SELF(self, klass, -NME_BUG);
|
|
|
|
|
|
|
|
|
|
nm_assert(klass->link_wireguard_change);
|
|
|
|
|
|
|
|
|
|
if (_LOGD_ENABLED()) {
|
|
|
|
|
char buf_lnk[256];
|
|
|
|
|
char buf_peers[512];
|
|
|
|
|
char buf_change_flags[100];
|
|
|
|
|
|
|
|
|
|
buf_peers[0] = '\0';
|
|
|
|
|
if (peers_len > 0) {
|
|
|
|
|
char *b = buf_peers;
|
|
|
|
|
gsize len = sizeof(buf_peers);
|
|
|
|
|
guint i;
|
|
|
|
|
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&b, &len, " { ");
|
2020-09-28 16:03:33 +02:00
|
|
|
for (i = 0; i < peers_len; i++) {
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&b, &len, " { ");
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_wireguard_peer_to_string(&peers[i], b, len);
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_seek_end(&b, &len);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (peer_flags) {
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(
|
2020-09-28 16:03:33 +02:00
|
|
|
&b,
|
|
|
|
|
&len,
|
|
|
|
|
" (%s)",
|
|
|
|
|
_wireguard_change_peer_flags_to_string(peer_flags[i],
|
|
|
|
|
buf_change_flags,
|
|
|
|
|
sizeof(buf_change_flags)));
|
|
|
|
|
}
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&b, &len, " } ");
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&b, &len, "}");
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_LOG3D("link: change wireguard ifindex %d, %s, (%s), %u peers%s",
|
|
|
|
|
ifindex,
|
|
|
|
|
nm_platform_lnk_wireguard_to_string(lnk_wireguard, buf_lnk, sizeof(buf_lnk)),
|
|
|
|
|
_wireguard_change_flags_to_string(change_flags,
|
|
|
|
|
buf_change_flags,
|
|
|
|
|
sizeof(buf_change_flags)),
|
|
|
|
|
peers_len,
|
|
|
|
|
buf_peers);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return klass->link_wireguard_change(self,
|
|
|
|
|
ifindex,
|
|
|
|
|
lnk_wireguard,
|
|
|
|
|
peers,
|
|
|
|
|
peer_flags,
|
|
|
|
|
peers_len,
|
|
|
|
|
change_flags);
|
2018-12-25 18:41:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2015-09-15 15:07:37 +02:00
|
|
|
/**
|
2015-12-09 16:14:49 +01:00
|
|
|
* nm_platform_link_tun_add:
|
2015-09-15 15:07:37 +02:00
|
|
|
* @self: platform instance
|
|
|
|
|
* @name: new interface name
|
|
|
|
|
* @tap: whether the interface is a TAP
|
|
|
|
|
* @owner: interface owner or -1
|
|
|
|
|
* @group: interface group or -1
|
|
|
|
|
* @pi: whether to clear the IFF_NO_PI flag
|
|
|
|
|
* @vnet_hdr: whether to set the IFF_VNET_HDR flag
|
|
|
|
|
* @multi_queue: whether to set the IFF_MULTI_QUEUE flag
|
|
|
|
|
* @out_link: on success, the link object
|
2023-03-01 01:21:38 +01:00
|
|
|
* @out_fd: (out) (optional): if give, return the file descriptor for the
|
2018-04-05 18:23:43 +02:00
|
|
|
* created device. Note that when creating a non-persistent device,
|
|
|
|
|
* this argument is mandatory, otherwise it makes no sense
|
|
|
|
|
* to create such an interface.
|
|
|
|
|
* The caller is responsible for closing this file descriptor.
|
2015-09-15 15:07:37 +02:00
|
|
|
*
|
|
|
|
|
* Create a TUN or TAP interface.
|
|
|
|
|
*/
|
platform: merge NMPlatformError with nm-error
Platform had it's own scheme for reporting errors: NMPlatformError.
Before, NMPlatformError indicated success via zero, negative integer
values are numbers from <errno.h>, and positive integer values are
platform specific codes. This changes now according to nm-error:
success is still zero. Negative values indicate a failure, where the
numeric value is either from <errno.h> or one of our error codes.
The meaning of positive values depends on the functions. Most functions
can only report an error reason (negative) and success (zero). For such
functions, positive values should never be returned (but the caller
should anticipate them).
For some functions, positive values could mean additional information
(but still success). That depends.
This is also what systemd does, except that systemd only returns
(negative) integers from <errno.h>, while we merge our own error codes
into the range of <errno.h>.
The advantage is to get rid of one way how to signal errors. The other
advantage is, that these error codes are compatible with all other
nm-errno values. For example, previously negative values indicated error
codes from <errno.h>, but it did not entail error codes from netlink.
2018-12-22 14:13:05 +01:00
|
|
|
int
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_link_tun_add(NMPlatform *self,
|
|
|
|
|
const char *name,
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPlatformLnkTun *props,
|
2021-11-09 13:28:54 +01:00
|
|
|
const NMPlatformLink **out_link,
|
|
|
|
|
int *out_fd)
|
2015-09-15 15:07:37 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
char b[255];
|
|
|
|
|
int r;
|
2015-09-15 15:07:37 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, -NME_BUG);
|
2015-09-15 15:07:37 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(name, -NME_BUG);
|
|
|
|
|
g_return_val_if_fail(props, -NME_BUG);
|
|
|
|
|
g_return_val_if_fail(NM_IN_SET(props->type, IFF_TUN, IFF_TAP), -NME_BUG);
|
2018-04-05 18:23:43 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* creating a non-persistent device requires that the caller handles
|
2020-09-28 14:50:01 +02:00
|
|
|
* the file descriptor. */
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(props->persist || out_fd, -NME_BUG);
|
2018-04-05 18:23:43 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_SET_OUT(out_fd, -1);
|
2015-09-15 15:07:37 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
r = _link_add_check_existing(self, name, NM_LINK_TYPE_TUN, out_link);
|
|
|
|
|
if (r < 0)
|
|
|
|
|
return r;
|
2015-09-15 15:07:37 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_LOG2D("link: adding link %s", nm_platform_lnk_tun_to_string(props, b, sizeof(b)));
|
2018-06-27 14:22:30 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!klass->link_tun_add(self, name, props, out_link, out_fd))
|
|
|
|
|
return -NME_UNSPEC;
|
|
|
|
|
return 0;
|
2015-09-15 15:07:37 +02:00
|
|
|
}
|
|
|
|
|
|
2018-05-22 11:50:05 +02:00
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_6lowpan_get_properties(NMPlatform *self, int ifindex, int *out_parent)
|
2018-05-22 11:50:05 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPlatformLink *plink;
|
2018-05-22 11:50:05 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
plink = nm_platform_link_get(self, ifindex);
|
|
|
|
|
if (!plink)
|
|
|
|
|
return FALSE;
|
2018-11-29 12:33:14 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (plink->type != NM_LINK_TYPE_6LOWPAN)
|
|
|
|
|
return FALSE;
|
2018-05-22 11:50:05 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (plink->parent != 0) {
|
|
|
|
|
NM_SET_OUT(out_parent, plink->parent);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
2018-05-22 11:50:05 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* As of 4.16 kernel does not expose the peer_ifindex as IFA_LINK.
|
2020-09-28 14:50:01 +02:00
|
|
|
* Find the WPAN device with the same MAC address. */
|
2020-09-28 16:03:33 +02:00
|
|
|
if (out_parent) {
|
|
|
|
|
const NMPlatformLink *parent_plink;
|
2018-05-22 11:50:05 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
parent_plink = nm_platform_link_get_by_address(self,
|
|
|
|
|
NM_LINK_TYPE_WPAN,
|
|
|
|
|
plink->l_address.data,
|
|
|
|
|
plink->l_address.len);
|
|
|
|
|
NM_SET_OUT(out_parent, parent_plink ? parent_plink->ifindex : -1);
|
|
|
|
|
}
|
2018-05-22 11:50:05 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return TRUE;
|
2018-05-22 11:50:05 +02:00
|
|
|
}
|
|
|
|
|
|
2015-12-09 17:29:46 +01:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2016-12-09 13:03:43 +01:00
|
|
|
static gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
link_set_option(NMPlatform *self,
|
|
|
|
|
int ifindex,
|
|
|
|
|
const char *category,
|
|
|
|
|
const char *option,
|
|
|
|
|
const char *value)
|
2015-12-09 17:29:46 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_auto_close int dirfd = -1;
|
|
|
|
|
char ifname_verified[IFNAMSIZ];
|
2021-11-09 13:28:54 +01:00
|
|
|
const char *path;
|
2015-12-09 17:29:46 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!category || !option)
|
|
|
|
|
return FALSE;
|
2015-12-09 17:29:46 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
dirfd = nm_platform_sysctl_open_netdir(self, ifindex, ifname_verified);
|
|
|
|
|
if (dirfd < 0)
|
|
|
|
|
return FALSE;
|
2015-12-09 17:29:46 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
path =
|
|
|
|
|
nm_sprintf_buf_unsafe_a(strlen(category) + strlen(option) + 2, "%s/%s", category, option);
|
|
|
|
|
return nm_platform_sysctl_set(self,
|
2023-06-26 15:01:04 +02:00
|
|
|
NMP_SYSCTL_PATHID_NETDIR_UNSAFE_A(dirfd, ifname_verified, path),
|
2020-09-28 16:03:33 +02:00
|
|
|
value);
|
2015-12-09 17:29:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char *
|
2020-09-28 16:03:33 +02:00
|
|
|
link_get_option(NMPlatform *self, int ifindex, const char *category, const char *option)
|
2015-12-09 17:29:46 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_auto_close int dirfd = -1;
|
|
|
|
|
char ifname_verified[IFNAMSIZ];
|
2021-11-09 13:28:54 +01:00
|
|
|
const char *path;
|
2016-12-09 13:03:43 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!category || !option)
|
|
|
|
|
return NULL;
|
2016-12-09 13:03:43 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
dirfd = nm_platform_sysctl_open_netdir(self, ifindex, ifname_verified);
|
|
|
|
|
if (dirfd < 0)
|
|
|
|
|
return NULL;
|
2015-12-09 17:29:46 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
path =
|
|
|
|
|
nm_sprintf_buf_unsafe_a(strlen(category) + strlen(option) + 2, "%s/%s", category, option);
|
|
|
|
|
return nm_platform_sysctl_get(self,
|
2023-06-26 15:01:04 +02:00
|
|
|
NMP_SYSCTL_PATHID_NETDIR_UNSAFE_A(dirfd, ifname_verified, path));
|
2015-12-09 17:29:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
master_category(NMPlatform *self, int master)
|
2015-12-09 17:29:46 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
switch (nm_platform_link_get_type(self, master)) {
|
|
|
|
|
case NM_LINK_TYPE_BRIDGE:
|
|
|
|
|
return "bridge";
|
|
|
|
|
case NM_LINK_TYPE_BOND:
|
|
|
|
|
return "bonding";
|
|
|
|
|
default:
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2015-12-09 17:29:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
slave_category(NMPlatform *self, int slave)
|
2015-12-09 17:29:46 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
int master = nm_platform_link_get_master(self, slave);
|
2015-12-09 17:29:46 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (master <= 0)
|
|
|
|
|
return NULL;
|
2015-12-09 17:29:46 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
switch (nm_platform_link_get_type(self, master)) {
|
|
|
|
|
case NM_LINK_TYPE_BRIDGE:
|
|
|
|
|
return "brport";
|
2021-08-23 22:00:54 +08:00
|
|
|
case NM_LINK_TYPE_BOND:
|
|
|
|
|
return "bonding_slave";
|
2020-09-28 16:03:33 +02:00
|
|
|
default:
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2015-12-09 17:29:46 +01:00
|
|
|
}
|
|
|
|
|
|
2013-04-04 17:07:47 +02:00
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_sysctl_master_set_option(NMPlatform *self,
|
|
|
|
|
int ifindex,
|
|
|
|
|
const char *option,
|
|
|
|
|
const char *value)
|
2013-04-04 17:07:47 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2013-04-04 17:07:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
|
|
|
|
g_return_val_if_fail(option, FALSE);
|
|
|
|
|
g_return_val_if_fail(value, FALSE);
|
2013-04-04 17:07:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return link_set_option(self, ifindex, master_category(self, ifindex), option, value);
|
2013-04-04 17:07:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_sysctl_master_get_option(NMPlatform *self, int ifindex, const char *option)
|
2013-04-04 17:07:47 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, NULL);
|
2013-04-04 17:07:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
|
|
|
|
g_return_val_if_fail(option, FALSE);
|
2013-04-04 17:07:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return link_get_option(self, ifindex, master_category(self, ifindex), option);
|
2013-04-04 17:07:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_sysctl_slave_set_option(NMPlatform *self,
|
|
|
|
|
int ifindex,
|
|
|
|
|
const char *option,
|
|
|
|
|
const char *value)
|
2013-04-04 17:07:47 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2013-04-04 17:07:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
|
|
|
|
g_return_val_if_fail(option, FALSE);
|
|
|
|
|
g_return_val_if_fail(value, FALSE);
|
2013-04-04 17:07:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return link_set_option(self, ifindex, slave_category(self, ifindex), option, value);
|
2013-04-04 17:07:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_sysctl_slave_get_option(NMPlatform *self, int ifindex, const char *option)
|
2013-04-04 17:07:47 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, NULL);
|
2013-04-04 17:07:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
|
|
|
|
g_return_val_if_fail(option, FALSE);
|
2013-04-04 17:07:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return link_get_option(self, ifindex, slave_category(self, ifindex), option);
|
2013-04-04 17:07:47 +02:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2015-12-09 17:29:46 +01:00
|
|
|
|
2013-03-27 22:53:55 +01:00
|
|
|
gboolean
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_link_vlan_change(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
int ifindex,
|
2021-03-03 20:57:01 +01:00
|
|
|
_NMVlanFlags flags_mask,
|
|
|
|
|
_NMVlanFlags flags_set,
|
2020-09-28 16:03:33 +02:00
|
|
|
gboolean ingress_reset_all,
|
|
|
|
|
const NMVlanQosMapping *ingress_map,
|
|
|
|
|
gsize n_ingress_map,
|
|
|
|
|
gboolean egress_reset_all,
|
|
|
|
|
const NMVlanQosMapping *egress_map,
|
|
|
|
|
gsize n_egress_map)
|
|
|
|
|
{
|
|
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
|
|
|
|
|
|
|
|
|
nm_assert(klass->link_vlan_change);
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail(!n_ingress_map || ingress_map, FALSE);
|
|
|
|
|
g_return_val_if_fail(!n_egress_map || egress_map, FALSE);
|
|
|
|
|
|
|
|
|
|
flags_set &= flags_mask;
|
|
|
|
|
|
|
|
|
|
if (_LOGD_ENABLED()) {
|
|
|
|
|
char buf[512];
|
|
|
|
|
char *b = buf;
|
|
|
|
|
gsize len, i;
|
|
|
|
|
|
|
|
|
|
b[0] = '\0';
|
|
|
|
|
len = sizeof(buf);
|
|
|
|
|
|
|
|
|
|
if (flags_mask)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&b,
|
|
|
|
|
&len,
|
|
|
|
|
" flags 0x%x/0x%x",
|
|
|
|
|
(unsigned) flags_set,
|
|
|
|
|
(unsigned) flags_mask);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
|
|
|
|
if (ingress_reset_all || n_ingress_map) {
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&b, &len, " ingress-qos-map");
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_vlan_qos_mapping_to_string("", ingress_map, n_ingress_map, b, len);
|
|
|
|
|
i = strlen(b);
|
|
|
|
|
b += i;
|
|
|
|
|
len -= i;
|
|
|
|
|
if (ingress_reset_all)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&b, &len, " (reset-all)");
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (egress_reset_all || n_egress_map) {
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&b, &len, " egress-qos-map");
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_vlan_qos_mapping_to_string("", egress_map, n_egress_map, b, len);
|
|
|
|
|
i = strlen(b);
|
|
|
|
|
b += i;
|
|
|
|
|
len -= i;
|
|
|
|
|
if (egress_reset_all)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&b, &len, " (reset-all)");
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_LOG3D("link: change vlan %s", buf);
|
|
|
|
|
}
|
|
|
|
|
return klass->link_vlan_change(self,
|
|
|
|
|
ifindex,
|
|
|
|
|
flags_mask,
|
|
|
|
|
flags_set,
|
|
|
|
|
ingress_reset_all,
|
|
|
|
|
ingress_map,
|
|
|
|
|
n_ingress_map,
|
|
|
|
|
egress_reset_all,
|
|
|
|
|
egress_map,
|
|
|
|
|
n_egress_map);
|
2013-03-27 22:53:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_vlan_set_ingress_map(NMPlatform *self, int ifindex, int from, int to)
|
2013-03-27 22:53:55 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
NMVlanQosMapping map = {
|
|
|
|
|
.from = from,
|
|
|
|
|
.to = to,
|
|
|
|
|
};
|
2015-10-27 16:14:54 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return nm_platform_link_vlan_change(self, ifindex, 0, 0, FALSE, &map, 1, FALSE, NULL, 0);
|
2015-10-27 16:14:54 +01:00
|
|
|
}
|
2013-03-27 22:53:55 +01:00
|
|
|
|
2015-10-27 16:14:54 +01:00
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_vlan_set_egress_map(NMPlatform *self, int ifindex, int from, int to)
|
2015-10-27 16:14:54 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
NMVlanQosMapping map = {
|
|
|
|
|
.from = from,
|
|
|
|
|
.to = to,
|
|
|
|
|
};
|
2013-03-27 22:53:55 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return nm_platform_link_vlan_change(self, ifindex, 0, 0, FALSE, NULL, 0, FALSE, &map, 1);
|
2013-03-27 22:53:55 +01:00
|
|
|
}
|
|
|
|
|
|
platform: merge NMPlatformError with nm-error
Platform had it's own scheme for reporting errors: NMPlatformError.
Before, NMPlatformError indicated success via zero, negative integer
values are numbers from <errno.h>, and positive integer values are
platform specific codes. This changes now according to nm-error:
success is still zero. Negative values indicate a failure, where the
numeric value is either from <errno.h> or one of our error codes.
The meaning of positive values depends on the functions. Most functions
can only report an error reason (negative) and success (zero). For such
functions, positive values should never be returned (but the caller
should anticipate them).
For some functions, positive values could mean additional information
(but still success). That depends.
This is also what systemd does, except that systemd only returns
(negative) integers from <errno.h>, while we merge our own error codes
into the range of <errno.h>.
The advantage is to get rid of one way how to signal errors. The other
advantage is, that these error codes are compatible with all other
nm-errno values. For example, previously negative values indicated error
codes from <errno.h>, but it did not entail error codes from netlink.
2018-12-22 14:13:05 +01:00
|
|
|
static int
|
2021-11-09 13:28:54 +01:00
|
|
|
_infiniband_add_add_or_delete(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
int ifindex,
|
|
|
|
|
int p_key,
|
|
|
|
|
gboolean add,
|
|
|
|
|
const NMPlatformLink **out_link)
|
2013-06-10 16:21:08 -03:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
char name[IFNAMSIZ];
|
|
|
|
|
const NMPlatformLink *parent_link;
|
|
|
|
|
int r;
|
2013-06-10 16:21:08 -03:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, -NME_BUG);
|
2013-06-10 16:21:08 -03:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex >= 0, -NME_BUG);
|
|
|
|
|
g_return_val_if_fail(p_key >= 0 && p_key <= 0xffff, -NME_BUG);
|
2016-04-20 11:44:23 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* the special keys 0x0000 and 0x8000 are not allowed. */
|
|
|
|
|
if (NM_IN_SET(p_key, 0, 0x8000))
|
|
|
|
|
return -NME_UNSPEC;
|
2013-06-10 16:21:08 -03:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
parent_link = nm_platform_link_get(self, ifindex);
|
|
|
|
|
if (!parent_link)
|
|
|
|
|
return -NME_PL_NOT_FOUND;
|
2016-04-20 10:07:03 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (parent_link->type != NM_LINK_TYPE_INFINIBAND)
|
|
|
|
|
return -NME_PL_WRONG_TYPE;
|
2013-06-10 16:21:08 -03:00
|
|
|
|
2023-05-25 21:33:02 +02:00
|
|
|
nm_net_devname_infiniband(name, parent_link->name, p_key);
|
2015-06-15 16:19:19 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (add) {
|
|
|
|
|
r = _link_add_check_existing(self, name, NM_LINK_TYPE_INFINIBAND, out_link);
|
|
|
|
|
if (r < 0)
|
|
|
|
|
return r;
|
2016-04-20 09:16:21 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_LOG3D("link: adding infiniband partition %s, key %d", name, p_key);
|
|
|
|
|
if (!klass->infiniband_partition_add(self, ifindex, p_key, out_link))
|
|
|
|
|
return -NME_UNSPEC;
|
|
|
|
|
} else {
|
|
|
|
|
_LOG3D("link: deleting infiniband partition %s, key %d", name, p_key);
|
2018-05-28 17:42:56 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!klass->infiniband_partition_delete(self, ifindex, p_key))
|
|
|
|
|
return -NME_UNSPEC;
|
|
|
|
|
}
|
2016-04-20 09:16:21 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return 0;
|
2013-06-10 16:21:08 -03:00
|
|
|
}
|
|
|
|
|
|
platform: merge NMPlatformError with nm-error
Platform had it's own scheme for reporting errors: NMPlatformError.
Before, NMPlatformError indicated success via zero, negative integer
values are numbers from <errno.h>, and positive integer values are
platform specific codes. This changes now according to nm-error:
success is still zero. Negative values indicate a failure, where the
numeric value is either from <errno.h> or one of our error codes.
The meaning of positive values depends on the functions. Most functions
can only report an error reason (negative) and success (zero). For such
functions, positive values should never be returned (but the caller
should anticipate them).
For some functions, positive values could mean additional information
(but still success). That depends.
This is also what systemd does, except that systemd only returns
(negative) integers from <errno.h>, while we merge our own error codes
into the range of <errno.h>.
The advantage is to get rid of one way how to signal errors. The other
advantage is, that these error codes are compatible with all other
nm-errno values. For example, previously negative values indicated error
codes from <errno.h>, but it did not entail error codes from netlink.
2018-12-22 14:13:05 +01:00
|
|
|
int
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_link_infiniband_add(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
int parent,
|
|
|
|
|
int p_key,
|
|
|
|
|
const NMPlatformLink **out_link)
|
2016-04-20 09:16:21 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return _infiniband_add_add_or_delete(self, parent, p_key, TRUE, out_link);
|
2016-04-20 09:16:21 +02:00
|
|
|
}
|
|
|
|
|
|
platform: merge NMPlatformError with nm-error
Platform had it's own scheme for reporting errors: NMPlatformError.
Before, NMPlatformError indicated success via zero, negative integer
values are numbers from <errno.h>, and positive integer values are
platform specific codes. This changes now according to nm-error:
success is still zero. Negative values indicate a failure, where the
numeric value is either from <errno.h> or one of our error codes.
The meaning of positive values depends on the functions. Most functions
can only report an error reason (negative) and success (zero). For such
functions, positive values should never be returned (but the caller
should anticipate them).
For some functions, positive values could mean additional information
(but still success). That depends.
This is also what systemd does, except that systemd only returns
(negative) integers from <errno.h>, while we merge our own error codes
into the range of <errno.h>.
The advantage is to get rid of one way how to signal errors. The other
advantage is, that these error codes are compatible with all other
nm-errno values. For example, previously negative values indicated error
codes from <errno.h>, but it did not entail error codes from netlink.
2018-12-22 14:13:05 +01:00
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_infiniband_delete(NMPlatform *self, int parent, int p_key)
|
2016-04-20 09:16:21 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return _infiniband_add_add_or_delete(self, parent, p_key, FALSE, NULL);
|
2016-04-20 09:16:21 +02:00
|
|
|
}
|
|
|
|
|
|
2014-10-06 09:37:34 -05:00
|
|
|
gboolean
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_link_infiniband_get_properties(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
int ifindex,
|
2021-11-09 13:28:54 +01:00
|
|
|
int *out_parent,
|
|
|
|
|
int *out_p_key,
|
2020-09-28 16:03:33 +02:00
|
|
|
const char **out_mode)
|
|
|
|
|
{
|
|
|
|
|
nm_auto_close int dirfd = -1;
|
|
|
|
|
char ifname_verified[IFNAMSIZ];
|
|
|
|
|
const NMPlatformLnkInfiniband *plnk;
|
2021-11-09 13:28:54 +01:00
|
|
|
const NMPlatformLink *plink;
|
|
|
|
|
char *contents;
|
|
|
|
|
const char *mode;
|
2020-09-28 16:03:33 +02:00
|
|
|
int p_key = 0;
|
|
|
|
|
|
|
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2015-10-15 15:47:14 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
2015-10-15 15:47:14 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
plnk = nm_platform_link_get_lnk_infiniband(self, ifindex, &plink);
|
2015-10-15 15:47:14 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!plink || plink->type != NM_LINK_TYPE_INFINIBAND)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
if (plnk) {
|
|
|
|
|
NM_SET_OUT(out_parent, plink->parent);
|
|
|
|
|
NM_SET_OUT(out_p_key, plnk->p_key);
|
|
|
|
|
NM_SET_OUT(out_mode, plnk->mode);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Could not get the link information via netlink. To support older kernels,
|
2020-09-28 14:50:01 +02:00
|
|
|
* fallback to reading sysfs. */
|
2015-10-15 15:47:14 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
dirfd = nm_platform_sysctl_open_netdir(self, ifindex, ifname_verified);
|
|
|
|
|
if (dirfd < 0)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
contents =
|
2023-06-26 15:01:04 +02:00
|
|
|
nm_platform_sysctl_get(self, NMP_SYSCTL_PATHID_NETDIR_A(dirfd, ifname_verified, "mode"));
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!contents)
|
|
|
|
|
return FALSE;
|
|
|
|
|
if (strstr(contents, "datagram"))
|
|
|
|
|
mode = "datagram";
|
|
|
|
|
else if (strstr(contents, "connected"))
|
|
|
|
|
mode = "connected";
|
|
|
|
|
else
|
|
|
|
|
mode = NULL;
|
|
|
|
|
g_free(contents);
|
|
|
|
|
|
2023-06-26 15:01:04 +02:00
|
|
|
p_key = nm_platform_sysctl_get_int_checked(
|
|
|
|
|
self,
|
|
|
|
|
NMP_SYSCTL_PATHID_NETDIR_A(dirfd, ifname_verified, "pkey"),
|
|
|
|
|
16,
|
|
|
|
|
0,
|
|
|
|
|
0xFFFF,
|
|
|
|
|
-1);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (p_key < 0)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
NM_SET_OUT(out_parent, plink->parent);
|
|
|
|
|
NM_SET_OUT(out_p_key, p_key);
|
|
|
|
|
NM_SET_OUT(out_mode, mode);
|
|
|
|
|
return TRUE;
|
2014-10-06 09:37:34 -05:00
|
|
|
}
|
|
|
|
|
|
2013-05-03 13:55:51 -04:00
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_veth_get_properties(NMPlatform *self, int ifindex, int *out_peer_ifindex)
|
2013-05-03 13:55:51 -04:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPlatformLink *plink;
|
|
|
|
|
int peer_ifindex;
|
2013-05-03 13:55:51 -04:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
plink = nm_platform_link_get(self, ifindex);
|
|
|
|
|
if (!plink)
|
|
|
|
|
return FALSE;
|
2018-11-29 12:33:14 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (plink->type != NM_LINK_TYPE_VETH)
|
|
|
|
|
return FALSE;
|
2013-05-03 13:55:51 -04:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (plink->parent != 0) {
|
|
|
|
|
NM_SET_OUT(out_peer_ifindex, plink->parent);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
2015-10-16 17:53:33 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* Pre-4.1 kernel did not expose the peer_ifindex as IFA_LINK. Lookup via ethtool. */
|
|
|
|
|
if (out_peer_ifindex) {
|
|
|
|
|
nm_auto_pop_netns NMPNetns *netns = NULL;
|
2016-02-19 01:06:28 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!nm_platform_netns_push(self, &netns))
|
|
|
|
|
return FALSE;
|
|
|
|
|
peer_ifindex = nmp_utils_ethtool_get_peer_ifindex(plink->ifindex);
|
|
|
|
|
if (peer_ifindex <= 0)
|
|
|
|
|
return FALSE;
|
2015-10-16 17:53:33 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
*out_peer_ifindex = peer_ifindex;
|
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
2013-05-03 13:55:51 -04:00
|
|
|
}
|
|
|
|
|
|
core/platform: add support for TUN/TAP netlink support and various cleanup
Kernel recently got support for exposing TUN/TAP information on netlink
[1], [2], [3]. Add support for it to the platform cache.
The advantage of using netlink is that querying sysctl bypasses the
order of events of the netlink socket. It is out of sync and racy. For
example, platform cache might still think that a tun device exists, but
a subsequent lookup at sysfs might fail because the device was deleted
in the meantime. Another point is, that we don't get change
notifications via sysctl and that it requires various extra syscalls
to read the device information. If the tun information is present on
netlink, put it into the cache. This bypasses checking sysctl while
we keep looking at sysctl for backward compatibility until we require
support from kernel.
Notes:
- we had two link types NM_LINK_TYPE_TAP and NM_LINK_TYPE_TUN. This
deviates from the model of how kernel treats TUN/TAP devices, which
makes it more complicated. The link type of a NMPlatformLink instance
should match what kernel thinks about the device. Point in case,
when parsing RTM_NETLINK messages, we very early need to determine
the link type (_linktype_get_type()). However, to determine the
type of a TUN/TAP at that point, we need to look into nested
netlink attributes which in turn depend on the type (IFLA_INFO_KIND
and IFLA_INFO_DATA), or even worse, we would need to look into
sysctl for older kernel vesions. Now, the TUN/TAP type is a property
of the link type NM_LINK_TYPE_TUN, instead of determining two
different link types.
- various parts of the API (both kernel's sysctl vs. netlink) and
NMDeviceTun vs. NMSettingTun disagree whether the PI is positive
(NM_SETTING_TUN_PI, IFLA_TUN_PI, NMPlatformLnkTun.pi) or inverted
(NM_DEVICE_TUN_NO_PI, IFF_NO_PI). There is no consistent way,
but prefer the positive form for internal API at NMPlatformLnkTun.pi.
- previously NMDeviceTun.mode could not change after initializing
the object. Allow for that to happen, because forcing some properties
that are reported by kernel to not change is wrong, in case they
might change. Of course, in practice kernel doesn't allow the device
to ever change its type, but the type property of the NMDeviceTun
should not make that assumption, because, if it actually changes, what
would it mean?
- note that as of now, new netlink API is not yet merged to mainline Linus
tree. Shortcut _parse_lnk_tun() to not accidentally use unstable API
for now.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1277457
[2] https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/commit/?id=1ec010e705934c8acbe7dbf31afc81e60e3d828b
[3] https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=118eda77d6602616bc523a17ee45171e879d1818
https://bugzilla.redhat.com/show_bug.cgi?id=1547213
https://github.com/NetworkManager/NetworkManager/pull/77
2018-03-13 15:29:03 +01:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_tun_get_properties:
|
|
|
|
|
* @self: the #NMPlatform instance
|
|
|
|
|
* @ifindex: the ifindex to look up
|
2023-03-01 01:21:38 +01:00
|
|
|
* @out_properties: (out) (optional): return the read properties
|
core/platform: add support for TUN/TAP netlink support and various cleanup
Kernel recently got support for exposing TUN/TAP information on netlink
[1], [2], [3]. Add support for it to the platform cache.
The advantage of using netlink is that querying sysctl bypasses the
order of events of the netlink socket. It is out of sync and racy. For
example, platform cache might still think that a tun device exists, but
a subsequent lookup at sysfs might fail because the device was deleted
in the meantime. Another point is, that we don't get change
notifications via sysctl and that it requires various extra syscalls
to read the device information. If the tun information is present on
netlink, put it into the cache. This bypasses checking sysctl while
we keep looking at sysctl for backward compatibility until we require
support from kernel.
Notes:
- we had two link types NM_LINK_TYPE_TAP and NM_LINK_TYPE_TUN. This
deviates from the model of how kernel treats TUN/TAP devices, which
makes it more complicated. The link type of a NMPlatformLink instance
should match what kernel thinks about the device. Point in case,
when parsing RTM_NETLINK messages, we very early need to determine
the link type (_linktype_get_type()). However, to determine the
type of a TUN/TAP at that point, we need to look into nested
netlink attributes which in turn depend on the type (IFLA_INFO_KIND
and IFLA_INFO_DATA), or even worse, we would need to look into
sysctl for older kernel vesions. Now, the TUN/TAP type is a property
of the link type NM_LINK_TYPE_TUN, instead of determining two
different link types.
- various parts of the API (both kernel's sysctl vs. netlink) and
NMDeviceTun vs. NMSettingTun disagree whether the PI is positive
(NM_SETTING_TUN_PI, IFLA_TUN_PI, NMPlatformLnkTun.pi) or inverted
(NM_DEVICE_TUN_NO_PI, IFF_NO_PI). There is no consistent way,
but prefer the positive form for internal API at NMPlatformLnkTun.pi.
- previously NMDeviceTun.mode could not change after initializing
the object. Allow for that to happen, because forcing some properties
that are reported by kernel to not change is wrong, in case they
might change. Of course, in practice kernel doesn't allow the device
to ever change its type, but the type property of the NMDeviceTun
should not make that assumption, because, if it actually changes, what
would it mean?
- note that as of now, new netlink API is not yet merged to mainline Linus
tree. Shortcut _parse_lnk_tun() to not accidentally use unstable API
for now.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1277457
[2] https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/commit/?id=1ec010e705934c8acbe7dbf31afc81e60e3d828b
[3] https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=118eda77d6602616bc523a17ee45171e879d1818
https://bugzilla.redhat.com/show_bug.cgi?id=1547213
https://github.com/NetworkManager/NetworkManager/pull/77
2018-03-13 15:29:03 +01:00
|
|
|
*
|
|
|
|
|
* Only recent versions of kernel export tun properties via netlink.
|
|
|
|
|
* So, if that's the case, then we have the NMPlatformLnkTun instance
|
|
|
|
|
* in the platform cache ready to return. Otherwise, this function
|
|
|
|
|
* falls back reading sysctl to obtain the tun properties. That
|
|
|
|
|
* is racy, because querying sysctl means that the object might
|
|
|
|
|
* be already removed from cache (while NM didn't yet process the
|
|
|
|
|
* netlink message).
|
|
|
|
|
*
|
|
|
|
|
* Hence, to lookup the tun properties, you always need to use this
|
|
|
|
|
* function, and use it with care knowing that it might obtain its
|
|
|
|
|
* data by reading sysctl. Note that we don't want to add this workaround
|
|
|
|
|
* to the platform cache itself, because the cache should (mainly)
|
|
|
|
|
* contain data from netlink. To access the sysctl side channel, the
|
|
|
|
|
* user needs to do explicitly.
|
|
|
|
|
*
|
|
|
|
|
* Returns: #TRUE, if the properties could be read. */
|
2015-10-13 16:08:30 +02:00
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_tun_get_properties(NMPlatform *self, int ifindex, NMPlatformLnkTun *out_properties)
|
|
|
|
|
{
|
|
|
|
|
const NMPObject *plobj;
|
|
|
|
|
const NMPObject *pllnk;
|
|
|
|
|
char ifname[IFNAMSIZ];
|
|
|
|
|
gint64 owner;
|
|
|
|
|
gint64 group;
|
|
|
|
|
gint64 flags;
|
|
|
|
|
|
|
|
|
|
/* we consider also invisible links (those that are not yet in udev). */
|
|
|
|
|
plobj = nm_platform_link_get_obj(self, ifindex, FALSE);
|
|
|
|
|
if (!plobj)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
if (NMP_OBJECT_CAST_LINK(plobj)->type != NM_LINK_TYPE_TUN)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
pllnk = plobj->_link.netlink.lnk;
|
|
|
|
|
if (pllnk) {
|
|
|
|
|
nm_assert(NMP_OBJECT_GET_TYPE(pllnk) == NMP_OBJECT_TYPE_LNK_TUN);
|
|
|
|
|
nm_assert(NMP_OBJECT_GET_CLASS(pllnk)->lnk_link_type == NM_LINK_TYPE_TUN);
|
|
|
|
|
|
|
|
|
|
/* recent kernels expose tun properties via netlink and thus we have them
|
2020-09-28 14:50:01 +02:00
|
|
|
* in the platform cache. */
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_SET_OUT(out_properties, pllnk->lnk_tun);
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* fallback to reading sysctl. */
|
|
|
|
|
{
|
|
|
|
|
nm_auto_close int dirfd = -1;
|
|
|
|
|
|
|
|
|
|
dirfd = nm_platform_sysctl_open_netdir(self, ifindex, ifname);
|
|
|
|
|
if (dirfd < 0)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
2023-06-26 15:01:04 +02:00
|
|
|
owner =
|
|
|
|
|
nm_platform_sysctl_get_int_checked(self,
|
|
|
|
|
NMP_SYSCTL_PATHID_NETDIR_A(dirfd, ifname, "owner"),
|
|
|
|
|
10,
|
|
|
|
|
-1,
|
|
|
|
|
G_MAXUINT32,
|
|
|
|
|
-2);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (owner == -2)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
2023-06-26 15:01:04 +02:00
|
|
|
group =
|
|
|
|
|
nm_platform_sysctl_get_int_checked(self,
|
|
|
|
|
NMP_SYSCTL_PATHID_NETDIR_A(dirfd, ifname, "group"),
|
|
|
|
|
10,
|
|
|
|
|
-1,
|
|
|
|
|
G_MAXUINT32,
|
|
|
|
|
-2);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (group == -2)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
2023-06-26 15:01:04 +02:00
|
|
|
flags = nm_platform_sysctl_get_int_checked(
|
|
|
|
|
self,
|
|
|
|
|
NMP_SYSCTL_PATHID_NETDIR_A(dirfd, ifname, "tun_flags"),
|
|
|
|
|
16,
|
|
|
|
|
0,
|
|
|
|
|
G_MAXINT64,
|
|
|
|
|
-1);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (flags == -1)
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (out_properties) {
|
|
|
|
|
memset(out_properties, 0, sizeof(*out_properties));
|
|
|
|
|
if (owner != -1) {
|
|
|
|
|
out_properties->owner_valid = TRUE;
|
|
|
|
|
out_properties->owner = owner;
|
|
|
|
|
}
|
|
|
|
|
if (group != -1) {
|
|
|
|
|
out_properties->group_valid = TRUE;
|
|
|
|
|
out_properties->group = group;
|
|
|
|
|
}
|
|
|
|
|
out_properties->type = (flags & TUN_TYPE_MASK);
|
|
|
|
|
out_properties->pi = !(flags & IFF_NO_PI);
|
|
|
|
|
out_properties->vnet_hdr = !!(flags & IFF_VNET_HDR);
|
|
|
|
|
out_properties->multi_queue = !!(flags & NM_IFF_MULTI_QUEUE);
|
|
|
|
|
out_properties->persist = !!(flags & IFF_PERSIST);
|
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
2015-10-13 16:08:30 +02:00
|
|
|
}
|
|
|
|
|
|
2014-02-04 14:27:03 +01:00
|
|
|
gboolean
|
2021-03-03 17:32:50 +01:00
|
|
|
nm_platform_wifi_get_capabilities(NMPlatform *self, int ifindex, _NMDeviceWifiCapabilities *caps)
|
2014-02-04 14:27:03 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2014-02-04 14:27:03 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
2014-02-04 14:27:03 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->wifi_get_capabilities(self, ifindex, caps);
|
2014-02-04 14:27:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
guint32
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_wifi_get_frequency(NMPlatform *self, int ifindex)
|
2014-02-04 14:27:03 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, 0);
|
2014-02-04 14:27:03 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, 0);
|
2014-02-04 14:27:03 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->wifi_get_frequency(self, ifindex);
|
2014-02-04 14:27:03 +01:00
|
|
|
}
|
|
|
|
|
|
2020-11-17 16:17:13 +01:00
|
|
|
gboolean
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_wifi_get_station(NMPlatform *self,
|
2020-11-19 11:00:08 +01:00
|
|
|
int ifindex,
|
|
|
|
|
NMEtherAddr *out_bssid,
|
2021-11-09 13:28:54 +01:00
|
|
|
int *out_quality,
|
|
|
|
|
guint32 *out_rate)
|
2020-11-17 16:17:13 +01:00
|
|
|
{
|
|
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
|
|
|
|
|
|
|
|
|
return klass->wifi_get_station(self, ifindex, out_bssid, out_quality, out_rate);
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-03 20:57:01 +01:00
|
|
|
_NM80211Mode
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_wifi_get_mode(NMPlatform *self, int ifindex)
|
2014-02-04 14:27:03 +01:00
|
|
|
{
|
2021-03-03 20:57:01 +01:00
|
|
|
_CHECK_SELF(self, klass, _NM_802_11_MODE_UNKNOWN);
|
2014-02-04 14:27:03 +01:00
|
|
|
|
2021-03-03 20:57:01 +01:00
|
|
|
g_return_val_if_fail(ifindex > 0, _NM_802_11_MODE_UNKNOWN);
|
2014-02-04 14:27:03 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->wifi_get_mode(self, ifindex);
|
2014-02-04 14:27:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2021-03-03 20:57:01 +01:00
|
|
|
nm_platform_wifi_set_mode(NMPlatform *self, int ifindex, _NM80211Mode mode)
|
2014-02-04 14:27:03 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF_VOID(self, klass);
|
2014-02-04 14:27:03 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_if_fail(ifindex > 0);
|
2014-02-04 14:27:03 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
klass->wifi_set_mode(self, ifindex, mode);
|
2014-02-04 14:27:03 +01:00
|
|
|
}
|
|
|
|
|
|
2014-10-23 14:19:59 -04:00
|
|
|
static void
|
2020-09-28 16:03:33 +02:00
|
|
|
wifi_set_powersave(NMPlatform *p, int ifindex, guint32 powersave)
|
2014-10-23 14:19:59 -04:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
/* empty */
|
2014-10-23 14:19:59 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_wifi_set_powersave(NMPlatform *self, int ifindex, guint32 powersave)
|
2014-10-23 14:19:59 -04:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF_VOID(self, klass);
|
2014-10-23 14:19:59 -04:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_if_fail(ifindex > 0);
|
2014-10-23 14:19:59 -04:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
klass->wifi_set_powersave(self, ifindex, powersave);
|
2014-10-23 14:19:59 -04:00
|
|
|
}
|
|
|
|
|
|
2014-02-04 14:27:03 +01:00
|
|
|
guint32
|
2023-03-21 18:05:03 +01:00
|
|
|
nm_platform_wifi_find_frequency(NMPlatform *self, int ifindex, const guint32 *freqs, gboolean ap)
|
2014-02-04 14:27:03 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, 0);
|
2014-02-04 14:27:03 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, 0);
|
|
|
|
|
g_return_val_if_fail(freqs != NULL, 0);
|
2014-02-04 14:27:03 +01:00
|
|
|
|
2023-03-21 18:05:03 +01:00
|
|
|
return klass->wifi_find_frequency(self, ifindex, freqs, ap);
|
2014-02-04 14:27:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_wifi_indicate_addressing_running(NMPlatform *self, int ifindex, gboolean running)
|
2014-02-04 14:27:03 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF_VOID(self, klass);
|
2014-02-04 14:27:03 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_if_fail(ifindex > 0);
|
2014-02-04 14:27:03 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
klass->wifi_indicate_addressing_running(self, ifindex, running);
|
2014-02-04 14:27:03 +01:00
|
|
|
}
|
|
|
|
|
|
2021-03-03 08:51:38 +01:00
|
|
|
_NMSettingWirelessWakeOnWLan
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_wifi_get_wake_on_wlan(NMPlatform *self, int ifindex)
|
2018-06-19 14:44:36 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2018-06-19 14:44:36 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
2018-06-19 14:44:36 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->wifi_get_wake_on_wlan(self, ifindex);
|
2018-06-19 14:44:36 +02:00
|
|
|
}
|
|
|
|
|
|
2018-05-25 17:43:54 +02:00
|
|
|
gboolean
|
2021-03-03 08:51:38 +01:00
|
|
|
nm_platform_wifi_set_wake_on_wlan(NMPlatform *self, int ifindex, _NMSettingWirelessWakeOnWLan wowl)
|
2018-05-25 17:43:54 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2018-05-25 17:43:54 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
2018-05-25 17:43:54 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->wifi_set_wake_on_wlan(self, ifindex, wowl);
|
2018-05-25 17:43:54 +02:00
|
|
|
}
|
|
|
|
|
|
2022-02-28 18:46:12 +02:00
|
|
|
gboolean
|
|
|
|
|
nm_platform_wifi_get_csme_conn_info(NMPlatform *self,
|
|
|
|
|
int ifindex,
|
|
|
|
|
NMPlatformCsmeConnInfo *out_conn_info)
|
|
|
|
|
{
|
|
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
|
|
|
|
|
|
|
|
|
return klass->wifi_get_csme_conn_info(self, ifindex, out_conn_info);
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-28 22:28:41 +02:00
|
|
|
gboolean
|
|
|
|
|
nm_platform_wifi_get_device_from_csme(NMPlatform *self, int ifindex)
|
|
|
|
|
{
|
|
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
|
|
|
|
|
|
|
|
|
return klass->wifi_get_device_from_csme(self, ifindex);
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-04 14:27:03 +01:00
|
|
|
guint32
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_mesh_get_channel(NMPlatform *self, int ifindex)
|
2014-02-04 14:27:03 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, 0);
|
2014-02-04 14:27:03 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, 0);
|
2014-02-04 14:27:03 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->mesh_get_channel(self, ifindex);
|
2014-02-04 14:27:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_mesh_set_channel(NMPlatform *self, int ifindex, guint32 channel)
|
2014-02-04 14:27:03 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2014-02-04 14:27:03 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
2014-02-04 14:27:03 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->mesh_set_channel(self, ifindex, channel);
|
2014-02-04 14:27:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_mesh_set_ssid(NMPlatform *self, int ifindex, const guint8 *ssid, gsize len)
|
2014-02-04 14:27:03 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2014-02-04 14:27:03 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
|
|
|
|
g_return_val_if_fail(ssid != NULL, FALSE);
|
2014-02-04 14:27:03 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->mesh_set_ssid(self, ifindex, ssid, len);
|
2014-02-04 14:27:03 +01:00
|
|
|
}
|
|
|
|
|
|
2018-05-14 10:09:46 +02:00
|
|
|
guint16
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_wpan_get_pan_id(NMPlatform *self, int ifindex)
|
2018-05-14 10:09:46 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2018-05-14 10:09:46 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
2018-05-14 10:09:46 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->wpan_get_pan_id(self, ifindex);
|
2018-05-14 10:09:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_wpan_set_pan_id(NMPlatform *self, int ifindex, guint16 pan_id)
|
2018-05-14 10:09:46 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2018-05-14 10:09:46 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
2018-05-14 10:09:46 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->wpan_set_pan_id(self, ifindex, pan_id);
|
2018-05-14 10:09:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
guint16
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_wpan_get_short_addr(NMPlatform *self, int ifindex)
|
2018-05-14 10:09:46 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2018-05-14 10:09:46 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
2018-05-14 10:09:46 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->wpan_get_short_addr(self, ifindex);
|
2018-05-14 10:09:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_wpan_set_short_addr(NMPlatform *self, int ifindex, guint16 short_addr)
|
2018-05-14 10:09:46 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2018-05-14 10:09:46 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
2018-05-14 10:09:46 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->wpan_set_short_addr(self, ifindex, short_addr);
|
2018-05-14 10:09:46 +02:00
|
|
|
}
|
|
|
|
|
|
2018-09-19 19:43:09 +02:00
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_wpan_set_channel(NMPlatform *self, int ifindex, guint8 page, guint8 channel)
|
2018-09-19 19:43:09 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2018-09-19 19:43:09 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
2018-09-19 19:43:09 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->wpan_set_channel(self, ifindex, page, channel);
|
2018-09-19 19:43:09 +02:00
|
|
|
}
|
|
|
|
|
|
2022-09-20 16:14:21 +02:00
|
|
|
/*****************************************************************************/
|
2014-08-11 21:40:52 +02:00
|
|
|
|
2022-09-20 16:14:21 +02:00
|
|
|
#define _to_string_dev(arr, ifindex) \
|
|
|
|
|
({ \
|
|
|
|
|
const int _ifindex = (ifindex); \
|
|
|
|
|
\
|
|
|
|
|
_ifindex ? nm_sprintf_buf((arr), " dev %d", ifindex) : nm_str_truncate((arr)); \
|
|
|
|
|
})
|
2014-08-11 21:32:47 +02:00
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2016-02-19 23:34:25 +01:00
|
|
|
gboolean
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_ethtool_set_wake_on_lan(NMPlatform *self,
|
2021-01-08 17:01:45 +01:00
|
|
|
int ifindex,
|
|
|
|
|
_NMSettingWiredWakeOnLan wol,
|
2021-11-09 13:28:54 +01:00
|
|
|
const char *wol_password)
|
2016-02-19 23:34:25 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF_NETNS(self, klass, netns, FALSE);
|
2016-02-19 01:06:28 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
2016-12-11 22:46:14 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return nmp_utils_ethtool_set_wake_on_lan(ifindex, wol, wol_password);
|
2016-02-19 23:34:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_ethtool_set_link_settings(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
int ifindex,
|
|
|
|
|
gboolean autoneg,
|
|
|
|
|
guint32 speed,
|
|
|
|
|
NMPlatformLinkDuplexType duplex)
|
2016-02-19 23:34:25 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF_NETNS(self, klass, netns, FALSE);
|
2016-02-19 23:34:25 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
2016-12-11 22:46:14 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return nmp_utils_ethtool_set_link_settings(ifindex, autoneg, speed, duplex);
|
2016-09-10 16:48:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_ethtool_get_link_settings(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
int ifindex,
|
2021-11-09 13:28:54 +01:00
|
|
|
gboolean *out_autoneg,
|
|
|
|
|
guint32 *out_speed,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPlatformLinkDuplexType *out_duplex)
|
2016-09-10 16:48:01 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF_NETNS(self, klass, netns, FALSE);
|
2016-02-19 01:06:28 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
2016-12-11 22:46:14 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return nmp_utils_ethtool_get_link_settings(ifindex, out_autoneg, out_speed, out_duplex);
|
2016-02-19 23:34:25 +01:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2016-02-19 23:34:25 +01:00
|
|
|
|
2018-07-16 15:42:07 +02:00
|
|
|
NMEthtoolFeatureStates *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_ethtool_get_link_features(NMPlatform *self, int ifindex)
|
2018-07-16 15:42:07 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF_NETNS(self, klass, netns, NULL);
|
2018-07-16 15:42:07 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, NULL);
|
2018-07-16 15:42:07 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return nmp_utils_ethtool_get_features(ifindex);
|
2018-07-16 15:42:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_ethtool_set_features(
|
2021-11-09 13:28:54 +01:00
|
|
|
NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
int ifindex,
|
|
|
|
|
const NMEthtoolFeatureStates *features,
|
2021-01-10 16:51:37 +01:00
|
|
|
const NMOptionBool *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */,
|
|
|
|
|
gboolean do_set /* or reset */)
|
2018-07-16 15:42:07 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF_NETNS(self, klass, netns, FALSE);
|
2018-07-16 15:42:07 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
2018-07-16 15:42:07 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return nmp_utils_ethtool_set_features(ifindex, features, requested, do_set);
|
2018-07-16 15:42:07 +02:00
|
|
|
}
|
|
|
|
|
|
2020-05-14 09:16:30 +02:00
|
|
|
gboolean
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_ethtool_get_link_coalesce(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
int ifindex,
|
|
|
|
|
NMEthtoolCoalesceState *coalesce)
|
2020-05-07 17:11:34 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF_NETNS(self, klass, netns, FALSE);
|
2020-05-07 17:11:34 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
|
|
|
|
g_return_val_if_fail(coalesce, FALSE);
|
2020-05-07 17:11:34 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return nmp_utils_ethtool_get_coalesce(ifindex, coalesce);
|
2020-05-07 17:11:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_ethtool_set_coalesce(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
int ifindex,
|
|
|
|
|
const NMEthtoolCoalesceState *coalesce)
|
2020-05-07 17:11:34 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF_NETNS(self, klass, netns, FALSE);
|
2020-05-07 17:11:34 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
2020-05-07 17:11:34 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return nmp_utils_ethtool_set_coalesce(ifindex, coalesce);
|
2020-05-07 17:11:34 +02:00
|
|
|
}
|
|
|
|
|
|
2020-05-14 18:27:54 +02:00
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_ethtool_get_link_ring(NMPlatform *self, int ifindex, NMEthtoolRingState *ring)
|
2020-05-14 18:27:54 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF_NETNS(self, klass, netns, FALSE);
|
2020-05-14 18:27:54 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
|
|
|
|
g_return_val_if_fail(ring, FALSE);
|
2020-05-14 18:27:54 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return nmp_utils_ethtool_get_ring(ifindex, ring);
|
2020-05-14 18:27:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_ethtool_set_ring(NMPlatform *self, int ifindex, const NMEthtoolRingState *ring)
|
2020-05-14 18:27:54 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF_NETNS(self, klass, netns, FALSE);
|
2020-05-14 18:27:54 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
2020-05-14 18:27:54 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return nmp_utils_ethtool_set_ring(ifindex, ring);
|
2020-05-14 18:27:54 +02:00
|
|
|
}
|
|
|
|
|
|
2021-05-11 15:45:22 +08:00
|
|
|
gboolean
|
|
|
|
|
nm_platform_ethtool_get_link_pause(NMPlatform *self, int ifindex, NMEthtoolPauseState *pause)
|
|
|
|
|
{
|
|
|
|
|
_CHECK_SELF_NETNS(self, klass, netns, FALSE);
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
|
|
|
|
g_return_val_if_fail(pause, FALSE);
|
|
|
|
|
|
|
|
|
|
return nmp_utils_ethtool_get_pause(ifindex, pause);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
nm_platform_ethtool_set_pause(NMPlatform *self, int ifindex, const NMEthtoolPauseState *pause)
|
|
|
|
|
{
|
|
|
|
|
_CHECK_SELF_NETNS(self, klass, netns, FALSE);
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
|
|
|
|
|
|
|
|
|
return nmp_utils_ethtool_set_pause(ifindex, pause);
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-16 15:42:07 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
platform: fix cache to use kernel's notion for equality of routes
Until now, NetworkManager's platform cache for routes used the quadruple
network/plen,metric,ifindex for equaliy. That is not kernel's
understanding of how routes behave. For example, with `ip route append`
you can add two IPv4 routes that only differ by their gateway. To
the previous form of platform cache, these two routes would wrongly
look identical, as the cache could not contain both routes. This also
easily leads to cache-inconsistencies.
Now that we have NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID, fix the route's
compare operator to match kernel's.
Well, not entirely. Kernel understands more properties for routes then
NetworkManager. Some of these properties may also be part of the ID according
to kernel. To NetworkManager such routes would still look identical as
they only differ in a property that is not understood. This can still
cause cache-inconsistencies. The only fix here is to add support for
all these properties in NetworkManager as well. However, it's less serious,
because with this commit we support several of the more important properties.
See also the related bug rh#1337855 for kernel.
Another difficulty is that `ip route replace` and `ip route change`
changes an existing route. The replaced route has the same
NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID, but differ in the actual
NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID:
# ip -d -4 route show dev v
# ip monitor route &
# ip route add 192.168.5.0/24 dev v
192.168.5.0/24 dev v scope link
# ip route change 192.168.5.0/24 dev v scope 10
192.168.5.0/24 dev v scope 10
# ip -d -4 route show dev v
unicast 192.168.5.0/24 proto boot scope 10
Note that we only got one RTM_NEWROUTE message, although from NMPCache's
point of view, a new route (with a particular ID) was added and another
route (with a different ID) was deleted. The cumbersome workaround is,
to keep an ordered list of the routes, and figure out which route was
replaced in response to an RTM_NEWROUTE. In absence of bugs, this should
work fine. However, as we only rely on events, we might wrongly
introduce a cache-inconsistancy as well. See the related bug rh#1337860.
Also drop nm_platform_ip4_route_get() and the like. The ID of routes
is complex, so it makes little sense to look up a route directly.
2017-08-02 07:55:05 +02:00
|
|
|
const NMDedupMultiHeadEntry *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lookup_all(NMPlatform *self, NMPCacheIdType cache_id_type, const NMPObject *obj)
|
platform: fix cache to use kernel's notion for equality of routes
Until now, NetworkManager's platform cache for routes used the quadruple
network/plen,metric,ifindex for equaliy. That is not kernel's
understanding of how routes behave. For example, with `ip route append`
you can add two IPv4 routes that only differ by their gateway. To
the previous form of platform cache, these two routes would wrongly
look identical, as the cache could not contain both routes. This also
easily leads to cache-inconsistencies.
Now that we have NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID, fix the route's
compare operator to match kernel's.
Well, not entirely. Kernel understands more properties for routes then
NetworkManager. Some of these properties may also be part of the ID according
to kernel. To NetworkManager such routes would still look identical as
they only differ in a property that is not understood. This can still
cause cache-inconsistencies. The only fix here is to add support for
all these properties in NetworkManager as well. However, it's less serious,
because with this commit we support several of the more important properties.
See also the related bug rh#1337855 for kernel.
Another difficulty is that `ip route replace` and `ip route change`
changes an existing route. The replaced route has the same
NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID, but differ in the actual
NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID:
# ip -d -4 route show dev v
# ip monitor route &
# ip route add 192.168.5.0/24 dev v
192.168.5.0/24 dev v scope link
# ip route change 192.168.5.0/24 dev v scope 10
192.168.5.0/24 dev v scope 10
# ip -d -4 route show dev v
unicast 192.168.5.0/24 proto boot scope 10
Note that we only got one RTM_NEWROUTE message, although from NMPCache's
point of view, a new route (with a particular ID) was added and another
route (with a different ID) was deleted. The cumbersome workaround is,
to keep an ordered list of the routes, and figure out which route was
replaced in response to an RTM_NEWROUTE. In absence of bugs, this should
work fine. However, as we only rely on events, we might wrongly
introduce a cache-inconsistancy as well. See the related bug rh#1337860.
Also drop nm_platform_ip4_route_get() and the like. The ID of routes
is complex, so it makes little sense to look up a route directly.
2017-08-02 07:55:05 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return nmp_cache_lookup_all(nm_platform_get_cache(self), cache_id_type, obj);
|
platform: fix cache to use kernel's notion for equality of routes
Until now, NetworkManager's platform cache for routes used the quadruple
network/plen,metric,ifindex for equaliy. That is not kernel's
understanding of how routes behave. For example, with `ip route append`
you can add two IPv4 routes that only differ by their gateway. To
the previous form of platform cache, these two routes would wrongly
look identical, as the cache could not contain both routes. This also
easily leads to cache-inconsistencies.
Now that we have NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID, fix the route's
compare operator to match kernel's.
Well, not entirely. Kernel understands more properties for routes then
NetworkManager. Some of these properties may also be part of the ID according
to kernel. To NetworkManager such routes would still look identical as
they only differ in a property that is not understood. This can still
cause cache-inconsistencies. The only fix here is to add support for
all these properties in NetworkManager as well. However, it's less serious,
because with this commit we support several of the more important properties.
See also the related bug rh#1337855 for kernel.
Another difficulty is that `ip route replace` and `ip route change`
changes an existing route. The replaced route has the same
NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID, but differ in the actual
NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID:
# ip -d -4 route show dev v
# ip monitor route &
# ip route add 192.168.5.0/24 dev v
192.168.5.0/24 dev v scope link
# ip route change 192.168.5.0/24 dev v scope 10
192.168.5.0/24 dev v scope 10
# ip -d -4 route show dev v
unicast 192.168.5.0/24 proto boot scope 10
Note that we only got one RTM_NEWROUTE message, although from NMPCache's
point of view, a new route (with a particular ID) was added and another
route (with a different ID) was deleted. The cumbersome workaround is,
to keep an ordered list of the routes, and figure out which route was
replaced in response to an RTM_NEWROUTE. In absence of bugs, this should
work fine. However, as we only rely on events, we might wrongly
introduce a cache-inconsistancy as well. See the related bug rh#1337860.
Also drop nm_platform_ip4_route_get() and the like. The ID of routes
is complex, so it makes little sense to look up a route directly.
2017-08-02 07:55:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const NMDedupMultiEntry *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lookup_entry(NMPlatform *self, NMPCacheIdType cache_id_type, const NMPObject *obj)
|
platform: fix cache to use kernel's notion for equality of routes
Until now, NetworkManager's platform cache for routes used the quadruple
network/plen,metric,ifindex for equaliy. That is not kernel's
understanding of how routes behave. For example, with `ip route append`
you can add two IPv4 routes that only differ by their gateway. To
the previous form of platform cache, these two routes would wrongly
look identical, as the cache could not contain both routes. This also
easily leads to cache-inconsistencies.
Now that we have NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID, fix the route's
compare operator to match kernel's.
Well, not entirely. Kernel understands more properties for routes then
NetworkManager. Some of these properties may also be part of the ID according
to kernel. To NetworkManager such routes would still look identical as
they only differ in a property that is not understood. This can still
cause cache-inconsistencies. The only fix here is to add support for
all these properties in NetworkManager as well. However, it's less serious,
because with this commit we support several of the more important properties.
See also the related bug rh#1337855 for kernel.
Another difficulty is that `ip route replace` and `ip route change`
changes an existing route. The replaced route has the same
NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID, but differ in the actual
NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID:
# ip -d -4 route show dev v
# ip monitor route &
# ip route add 192.168.5.0/24 dev v
192.168.5.0/24 dev v scope link
# ip route change 192.168.5.0/24 dev v scope 10
192.168.5.0/24 dev v scope 10
# ip -d -4 route show dev v
unicast 192.168.5.0/24 proto boot scope 10
Note that we only got one RTM_NEWROUTE message, although from NMPCache's
point of view, a new route (with a particular ID) was added and another
route (with a different ID) was deleted. The cumbersome workaround is,
to keep an ordered list of the routes, and figure out which route was
replaced in response to an RTM_NEWROUTE. In absence of bugs, this should
work fine. However, as we only rely on events, we might wrongly
introduce a cache-inconsistancy as well. See the related bug rh#1337860.
Also drop nm_platform_ip4_route_get() and the like. The ID of routes
is complex, so it makes little sense to look up a route directly.
2017-08-02 07:55:05 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return nmp_cache_lookup_entry_with_idx_type(nm_platform_get_cache(self), cache_id_type, obj);
|
platform: fix cache to use kernel's notion for equality of routes
Until now, NetworkManager's platform cache for routes used the quadruple
network/plen,metric,ifindex for equaliy. That is not kernel's
understanding of how routes behave. For example, with `ip route append`
you can add two IPv4 routes that only differ by their gateway. To
the previous form of platform cache, these two routes would wrongly
look identical, as the cache could not contain both routes. This also
easily leads to cache-inconsistencies.
Now that we have NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID, fix the route's
compare operator to match kernel's.
Well, not entirely. Kernel understands more properties for routes then
NetworkManager. Some of these properties may also be part of the ID according
to kernel. To NetworkManager such routes would still look identical as
they only differ in a property that is not understood. This can still
cause cache-inconsistencies. The only fix here is to add support for
all these properties in NetworkManager as well. However, it's less serious,
because with this commit we support several of the more important properties.
See also the related bug rh#1337855 for kernel.
Another difficulty is that `ip route replace` and `ip route change`
changes an existing route. The replaced route has the same
NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID, but differ in the actual
NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID:
# ip -d -4 route show dev v
# ip monitor route &
# ip route add 192.168.5.0/24 dev v
192.168.5.0/24 dev v scope link
# ip route change 192.168.5.0/24 dev v scope 10
192.168.5.0/24 dev v scope 10
# ip -d -4 route show dev v
unicast 192.168.5.0/24 proto boot scope 10
Note that we only got one RTM_NEWROUTE message, although from NMPCache's
point of view, a new route (with a particular ID) was added and another
route (with a different ID) was deleted. The cumbersome workaround is,
to keep an ordered list of the routes, and figure out which route was
replaced in response to an RTM_NEWROUTE. In absence of bugs, this should
work fine. However, as we only rely on events, we might wrongly
introduce a cache-inconsistancy as well. See the related bug rh#1337860.
Also drop nm_platform_ip4_route_get() and the like. The ID of routes
is complex, so it makes little sense to look up a route directly.
2017-08-02 07:55:05 +02:00
|
|
|
}
|
|
|
|
|
|
2017-06-29 14:46:32 +02:00
|
|
|
const NMDedupMultiHeadEntry *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lookup(NMPlatform *self, const NMPLookup *lookup)
|
2017-06-29 14:46:32 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return nmp_cache_lookup(nm_platform_get_cache(self), lookup);
|
2017-06-29 14:46:32 +02:00
|
|
|
}
|
|
|
|
|
|
2017-08-21 23:17:12 +02:00
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lookup_predicate_routes_main(const NMPObject *obj, gpointer user_data)
|
2017-08-21 23:17:12 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_assert(
|
|
|
|
|
NM_IN_SET(NMP_OBJECT_GET_TYPE(obj), NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE));
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
return nm_platform_route_table_is_main(
|
|
|
|
|
nm_platform_ip_route_get_effective_table(&obj->ip_route));
|
2017-08-21 23:17:12 +02:00
|
|
|
}
|
|
|
|
|
|
2017-06-29 15:19:35 +02:00
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lookup_predicate_routes_main_skip_rtprot_kernel(const NMPObject *obj,
|
|
|
|
|
gpointer user_data)
|
2017-06-29 15:19:35 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_assert(
|
|
|
|
|
NM_IN_SET(NMP_OBJECT_GET_TYPE(obj), NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE));
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
return nm_platform_route_table_is_main(nm_platform_ip_route_get_effective_table(&obj->ip_route))
|
2020-09-28 16:03:33 +02:00
|
|
|
&& obj->ip_route.rt_source != NM_IP_CONFIG_SOURCE_RTPROT_KERNEL;
|
2017-06-29 15:19:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_platform_lookup_clone:
|
2017-07-04 12:49:47 +02:00
|
|
|
* @self:
|
2017-06-29 15:19:35 +02:00
|
|
|
* @lookup:
|
|
|
|
|
* @predicate: if given, only objects for which @predicate returns %TRUE are included
|
|
|
|
|
* in the result.
|
|
|
|
|
* @user_data: user data for @predicate
|
|
|
|
|
*
|
|
|
|
|
* Returns the result of lookup in a GPtrArray. The result array contains
|
2018-04-18 14:13:28 +02:00
|
|
|
* references objects from the cache, its destroy function will unref them.
|
2017-06-29 15:19:35 +02:00
|
|
|
*
|
|
|
|
|
* The user must unref the GPtrArray, which will also unref the NMPObject
|
|
|
|
|
* elements.
|
|
|
|
|
*
|
|
|
|
|
* The elements in the array *must* not be modified.
|
|
|
|
|
*
|
|
|
|
|
* Returns: the result of the lookup.
|
|
|
|
|
*/
|
|
|
|
|
GPtrArray *
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_lookup_clone(NMPlatform *self,
|
|
|
|
|
const NMPLookup *lookup,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPObjectPredicateFunc predicate,
|
|
|
|
|
gpointer user_data)
|
2017-06-29 15:19:35 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return nm_dedup_multi_objs_to_ptr_array_head(nm_platform_lookup(self, lookup),
|
|
|
|
|
(NMDedupMultiFcnSelectPredicate) predicate,
|
|
|
|
|
user_data);
|
2017-06-29 15:19:35 +02:00
|
|
|
}
|
|
|
|
|
|
2013-03-27 22:23:24 +01:00
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_ip4_address_add(NMPlatform *self,
|
|
|
|
|
int ifindex,
|
|
|
|
|
in_addr_t address,
|
|
|
|
|
guint8 plen,
|
|
|
|
|
in_addr_t peer_address,
|
|
|
|
|
in_addr_t broadcast_address,
|
|
|
|
|
guint32 lifetime,
|
|
|
|
|
guint32 preferred,
|
|
|
|
|
guint32 flags,
|
2023-02-17 12:07:05 +01:00
|
|
|
const char *label,
|
|
|
|
|
char **out_extack_msg)
|
2020-09-28 16:03:33 +02:00
|
|
|
{
|
|
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
|
|
|
|
g_return_val_if_fail(plen <= 32, FALSE);
|
|
|
|
|
g_return_val_if_fail(lifetime > 0, FALSE);
|
|
|
|
|
g_return_val_if_fail(preferred <= lifetime, FALSE);
|
|
|
|
|
g_return_val_if_fail(!label || strlen(label) < sizeof(((NMPlatformIP4Address *) NULL)->label),
|
|
|
|
|
FALSE);
|
2023-02-17 12:07:05 +01:00
|
|
|
nm_assert(!out_extack_msg || !*out_extack_msg);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
|
|
|
|
if (_LOGD_ENABLED()) {
|
2022-03-30 08:47:34 +02:00
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPlatformIP4Address addr;
|
|
|
|
|
|
|
|
|
|
addr = (NMPlatformIP4Address){
|
|
|
|
|
.ifindex = ifindex,
|
|
|
|
|
.address = address,
|
|
|
|
|
.peer_address = peer_address,
|
|
|
|
|
.plen = plen,
|
|
|
|
|
.timestamp = 0, /* set it at zero, which to_string will treat as *now* */
|
|
|
|
|
.lifetime = lifetime,
|
|
|
|
|
.preferred = preferred,
|
|
|
|
|
.n_ifa_flags = flags,
|
|
|
|
|
.broadcast_address = broadcast_address,
|
|
|
|
|
.use_ip4_broadcast_address = TRUE,
|
|
|
|
|
};
|
|
|
|
|
if (label)
|
|
|
|
|
g_strlcpy(addr.label, label, sizeof(addr.label));
|
|
|
|
|
|
|
|
|
|
_LOG3D("address: adding or updating IPv4 address: %s",
|
2022-03-30 08:47:34 +02:00
|
|
|
nm_platform_ip4_address_to_string(&addr, sbuf, sizeof(sbuf)));
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
return klass->ip4_address_add(self,
|
|
|
|
|
ifindex,
|
|
|
|
|
address,
|
|
|
|
|
plen,
|
|
|
|
|
peer_address,
|
|
|
|
|
broadcast_address,
|
|
|
|
|
lifetime,
|
|
|
|
|
preferred,
|
|
|
|
|
flags,
|
2023-02-17 12:07:05 +01:00
|
|
|
label,
|
|
|
|
|
out_extack_msg);
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_ip6_address_add(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
int ifindex,
|
|
|
|
|
struct in6_addr address,
|
|
|
|
|
guint8 plen,
|
|
|
|
|
struct in6_addr peer_address,
|
|
|
|
|
guint32 lifetime,
|
|
|
|
|
guint32 preferred,
|
2023-02-17 12:07:05 +01:00
|
|
|
guint32 flags,
|
|
|
|
|
char **out_extack_msg)
|
2020-09-28 16:03:33 +02:00
|
|
|
{
|
|
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
|
|
|
|
g_return_val_if_fail(plen <= 128, FALSE);
|
|
|
|
|
g_return_val_if_fail(lifetime > 0, FALSE);
|
|
|
|
|
g_return_val_if_fail(preferred <= lifetime, FALSE);
|
2023-02-17 12:07:05 +01:00
|
|
|
nm_assert(!out_extack_msg || !*out_extack_msg);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
|
|
|
|
if (_LOGD_ENABLED()) {
|
2022-03-30 08:47:34 +02:00
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPlatformIP6Address addr = {0};
|
|
|
|
|
|
|
|
|
|
addr.ifindex = ifindex;
|
|
|
|
|
addr.address = address;
|
|
|
|
|
addr.peer_address = peer_address;
|
|
|
|
|
addr.plen = plen;
|
|
|
|
|
addr.timestamp = 0; /* set it to zero, which to_string will treat as *now* */
|
|
|
|
|
addr.lifetime = lifetime;
|
|
|
|
|
addr.preferred = preferred;
|
|
|
|
|
addr.n_ifa_flags = flags;
|
|
|
|
|
|
|
|
|
|
_LOG3D("address: adding or updating IPv6 address: %s",
|
2022-03-30 08:47:34 +02:00
|
|
|
nm_platform_ip6_address_to_string(&addr, sbuf, sizeof(sbuf)));
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
2022-09-22 13:33:17 +02:00
|
|
|
|
|
|
|
|
nm_platform_ip6_dadfailed_set(self, ifindex, &address, FALSE);
|
|
|
|
|
|
2023-02-17 12:07:05 +01:00
|
|
|
return klass->ip6_address_add(self,
|
|
|
|
|
ifindex,
|
|
|
|
|
address,
|
|
|
|
|
plen,
|
|
|
|
|
peer_address,
|
|
|
|
|
lifetime,
|
|
|
|
|
preferred,
|
|
|
|
|
flags,
|
|
|
|
|
out_extack_msg);
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_ip4_address_delete(NMPlatform *self,
|
|
|
|
|
int ifindex,
|
|
|
|
|
in_addr_t address,
|
|
|
|
|
guint8 plen,
|
|
|
|
|
in_addr_t peer_address)
|
2013-03-27 22:23:24 +01:00
|
|
|
{
|
2022-09-20 16:14:21 +02:00
|
|
|
char str_dev[30];
|
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 b1[NM_INET_ADDRSTRLEN];
|
|
|
|
|
char b2[NM_INET_ADDRSTRLEN];
|
2020-09-28 16:03:33 +02:00
|
|
|
char str_peer[INET_ADDRSTRLEN + 50];
|
2014-08-11 21:40:52 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
|
|
|
|
g_return_val_if_fail(plen <= 32, FALSE);
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_LOG3D("address: deleting IPv4 address %s/%d, %s%s",
|
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_inet4_ntop(address, b1),
|
2020-09-28 16:03:33 +02:00
|
|
|
plen,
|
|
|
|
|
peer_address != 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
|
|
|
? nm_sprintf_buf(str_peer, "peer %s, ", nm_inet4_ntop(peer_address, b2))
|
2020-09-28 16:03:33 +02:00
|
|
|
: "",
|
2022-09-20 16:14:21 +02:00
|
|
|
_to_string_dev(str_dev, ifindex));
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->ip4_address_delete(self, ifindex, address, plen, peer_address);
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_ip6_address_delete(NMPlatform *self, int ifindex, struct in6_addr address, guint8 plen)
|
2013-03-27 22:23:24 +01:00
|
|
|
{
|
2022-09-20 16:14:21 +02:00
|
|
|
char str_dev[30];
|
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];
|
2014-08-11 21:40:52 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(ifindex > 0, FALSE);
|
|
|
|
|
g_return_val_if_fail(plen <= 128, FALSE);
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_LOG3D("address: deleting IPv6 address %s/%d, %s",
|
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_inet6_ntop(&address, sbuf),
|
2020-09-28 16:03:33 +02:00
|
|
|
plen,
|
2022-09-20 16:14:21 +02:00
|
|
|
_to_string_dev(str_dev, ifindex));
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->ip6_address_delete(self, ifindex, address, plen);
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-29 17:14:33 +02:00
|
|
|
const NMPObject *
|
|
|
|
|
nm_platform_ip_address_get(NMPlatform *self,
|
|
|
|
|
int addr_family,
|
|
|
|
|
int ifindex,
|
|
|
|
|
gconstpointer /* (NMPlatformIPAddress *) */ needle)
|
|
|
|
|
{
|
|
|
|
|
const NMPlatformIPXAddress *addr;
|
|
|
|
|
NMPObject obj_id;
|
|
|
|
|
const NMPObject *obj;
|
|
|
|
|
|
|
|
|
|
nm_assert(NM_IS_PLATFORM(self));
|
|
|
|
|
nm_assert_addr_family(addr_family);
|
|
|
|
|
nm_assert(needle);
|
|
|
|
|
|
|
|
|
|
addr = needle;
|
|
|
|
|
|
|
|
|
|
if (ifindex <= 0) {
|
|
|
|
|
/* We allow the caller to override the ifindex. */
|
|
|
|
|
ifindex = addr->ax.ifindex;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (NM_IS_IPv4(addr_family)) {
|
|
|
|
|
nmp_object_stackinit_id_ip4_address(&obj_id,
|
|
|
|
|
ifindex,
|
|
|
|
|
addr->a4.address,
|
|
|
|
|
addr->a4.plen,
|
|
|
|
|
addr->a4.peer_address);
|
|
|
|
|
} else
|
|
|
|
|
nmp_object_stackinit_id_ip6_address(&obj_id, ifindex, &addr->a6.address);
|
|
|
|
|
|
|
|
|
|
obj = nmp_cache_lookup_obj(nm_platform_get_cache(self), &obj_id);
|
|
|
|
|
nm_assert(!obj || nmp_object_is_visible(obj));
|
|
|
|
|
return obj;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-14 12:37:58 +02:00
|
|
|
const NMPlatformIP4Address *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_ip4_address_get(NMPlatform *self,
|
|
|
|
|
int ifindex,
|
|
|
|
|
in_addr_t address,
|
|
|
|
|
guint8 plen,
|
2020-09-30 18:05:19 +02:00
|
|
|
in_addr_t peer_address)
|
2013-03-27 22:23:24 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPObject obj_id;
|
|
|
|
|
const NMPObject *obj;
|
2017-07-04 12:49:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, NULL);
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(plen <= 32, NULL);
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
nmp_object_stackinit_id_ip4_address(&obj_id, ifindex, address, plen, peer_address);
|
|
|
|
|
obj = nmp_cache_lookup_obj(nm_platform_get_cache(self), &obj_id);
|
|
|
|
|
nm_assert(!obj || nmp_object_is_visible(obj));
|
|
|
|
|
return NMP_OBJECT_CAST_IP4_ADDRESS(obj);
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
2015-07-14 12:37:58 +02:00
|
|
|
const NMPlatformIP6Address *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_ip6_address_get(NMPlatform *self, int ifindex, const struct in6_addr *address)
|
2013-03-27 22:23:24 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPObject obj_id;
|
|
|
|
|
const NMPObject *obj;
|
2017-07-04 12:49:47 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, NULL);
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_assert(address);
|
2020-09-16 13:24:07 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
nmp_object_stackinit_id_ip6_address(&obj_id, ifindex, address);
|
|
|
|
|
obj = nmp_cache_lookup_obj(nm_platform_get_cache(self), &obj_id);
|
|
|
|
|
nm_assert(!obj || nmp_object_is_visible(obj));
|
|
|
|
|
return NMP_OBJECT_CAST_IP6_ADDRESS(obj);
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
2018-02-07 22:21:31 +01:00
|
|
|
static gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
_addr_array_clean_expired(int addr_family,
|
|
|
|
|
int ifindex,
|
2021-11-09 13:28:54 +01:00
|
|
|
GPtrArray *array,
|
platform: make "now" timestamp an in/out parameter to nmp_utils_lifetime_get()
nmp_utils_lifetime_get() calculates the lifetime of addresses,
and it bases the result on a "now" timestamp.
If you have two addresses and calculate their expiry, then we want to
base it on top of the same "now" timestamp, meaning, we should
only call nm_utils_get_monotonic_timestamp_sec() once. This is also a
performance optimization. But much more importantly, when we make a
comparison at a certain moment, we need that all sides have the same
understanding of the current timestamp.
But nmp_utils_lifetime_get() does not always require the now timestamp.
And the caller doesn't know, whether it will need it (short of knowing
how nmp_utils_lifetime_get() is implemented). So, make the now parameter
an in/out argument. If we pass in an already valid now timestamp, use
that. Otherwise, fetch the current time and also return it.
(cherry picked from commit deb37401e95d4ea0025e406424c8da7c10bc9712)
2022-03-29 22:45:56 +02:00
|
|
|
gint32 *cached_now,
|
2020-09-28 16:03:33 +02:00
|
|
|
GHashTable **idx)
|
2018-02-07 22:21:31 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
guint i;
|
|
|
|
|
gboolean any_addrs = FALSE;
|
2018-02-07 22:21:31 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_assert_addr_family(addr_family);
|
|
|
|
|
nm_assert(ifindex > 0);
|
platform: make "now" timestamp an in/out parameter to nmp_utils_lifetime_get()
nmp_utils_lifetime_get() calculates the lifetime of addresses,
and it bases the result on a "now" timestamp.
If you have two addresses and calculate their expiry, then we want to
base it on top of the same "now" timestamp, meaning, we should
only call nm_utils_get_monotonic_timestamp_sec() once. This is also a
performance optimization. But much more importantly, when we make a
comparison at a certain moment, we need that all sides have the same
understanding of the current timestamp.
But nmp_utils_lifetime_get() does not always require the now timestamp.
And the caller doesn't know, whether it will need it (short of knowing
how nmp_utils_lifetime_get() is implemented). So, make the now parameter
an in/out argument. If we pass in an already valid now timestamp, use
that. Otherwise, fetch the current time and also return it.
(cherry picked from commit deb37401e95d4ea0025e406424c8da7c10bc9712)
2022-03-29 22:45:56 +02:00
|
|
|
nm_assert(cached_now);
|
|
|
|
|
nm_assert(*cached_now >= 0);
|
2018-02-07 22:21:31 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!array)
|
|
|
|
|
return FALSE;
|
2018-02-07 22:21:31 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* remove all addresses that are already expired. */
|
|
|
|
|
for (i = 0; i < array->len; i++) {
|
|
|
|
|
const NMPlatformIPAddress *a = NMP_OBJECT_CAST_IP_ADDRESS(array->pdata[i]);
|
2018-02-07 22:21:31 +01:00
|
|
|
|
|
|
|
|
#if NM_MORE_ASSERTS > 10
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_assert(a);
|
|
|
|
|
nm_assert(a->ifindex == ifindex);
|
|
|
|
|
{
|
|
|
|
|
const NMPObject *o = NMP_OBJECT_UP_CAST(a);
|
|
|
|
|
guint j;
|
|
|
|
|
|
|
|
|
|
nm_assert(NMP_OBJECT_GET_CLASS(o)->addr_family == addr_family);
|
|
|
|
|
for (j = i + 1; j < array->len; j++) {
|
|
|
|
|
const NMPObject *o2 = array->pdata[j];
|
|
|
|
|
|
|
|
|
|
nm_assert(NMP_OBJECT_GET_TYPE(o) == NMP_OBJECT_GET_TYPE(o2));
|
|
|
|
|
nm_assert(!nmp_object_id_equal(o, o2));
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-02-07 22:21:31 +01:00
|
|
|
#endif
|
|
|
|
|
|
2021-09-07 16:22:51 +02:00
|
|
|
if (!NM_IS_IPv4(addr_family) && NM_FLAGS_HAS(a->n_ifa_flags, IFA_F_SECONDARY)) {
|
2020-09-28 16:03:33 +02:00
|
|
|
/* temporary addresses are never added explicitly by NetworkManager but
|
2020-09-28 14:50:01 +02:00
|
|
|
* kernel adds them via mngtempaddr flag.
|
|
|
|
|
*
|
|
|
|
|
* We drop them from this list. */
|
2020-09-28 16:03:33 +02:00
|
|
|
goto clear_and_next;
|
|
|
|
|
}
|
|
|
|
|
|
platform: make "now" timestamp an in/out parameter to nmp_utils_lifetime_get()
nmp_utils_lifetime_get() calculates the lifetime of addresses,
and it bases the result on a "now" timestamp.
If you have two addresses and calculate their expiry, then we want to
base it on top of the same "now" timestamp, meaning, we should
only call nm_utils_get_monotonic_timestamp_sec() once. This is also a
performance optimization. But much more importantly, when we make a
comparison at a certain moment, we need that all sides have the same
understanding of the current timestamp.
But nmp_utils_lifetime_get() does not always require the now timestamp.
And the caller doesn't know, whether it will need it (short of knowing
how nmp_utils_lifetime_get() is implemented). So, make the now parameter
an in/out argument. If we pass in an already valid now timestamp, use
that. Otherwise, fetch the current time and also return it.
(cherry picked from commit deb37401e95d4ea0025e406424c8da7c10bc9712)
2022-03-29 22:45:56 +02:00
|
|
|
if (!nmp_utils_lifetime_get(a->timestamp, a->lifetime, a->preferred, cached_now, NULL))
|
2020-09-28 16:03:33 +02:00
|
|
|
goto clear_and_next;
|
|
|
|
|
|
2022-03-29 12:32:16 +02:00
|
|
|
if (G_UNLIKELY(!*idx)) {
|
|
|
|
|
*idx =
|
|
|
|
|
g_hash_table_new((GHashFunc) nmp_object_id_hash, (GEqualFunc) nmp_object_id_equal);
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
2022-03-29 12:32:16 +02:00
|
|
|
if (!g_hash_table_add(*idx, (gpointer) NMP_OBJECT_UP_CAST(a)))
|
|
|
|
|
nm_assert_not_reached();
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
any_addrs = TRUE;
|
|
|
|
|
continue;
|
2018-02-07 22:21:31 +01:00
|
|
|
|
2018-02-08 13:38:47 +01:00
|
|
|
clear_and_next:
|
2020-09-28 16:03:33 +02:00
|
|
|
nmp_object_unref(g_steal_pointer(&array->pdata[i]));
|
|
|
|
|
}
|
2018-02-07 22:21:31 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return any_addrs;
|
2018-02-07 22:21:31 +01:00
|
|
|
}
|
|
|
|
|
|
2016-11-14 20:52:24 +01:00
|
|
|
static gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
ip4_addr_subnets_is_plain_address(const GPtrArray *addresses, gconstpointer needle)
|
2016-11-14 20:52:24 +01:00
|
|
|
{
|
2022-03-31 10:57:25 +02:00
|
|
|
return nm_ptr_to_uintptr(needle) >= nm_ptr_to_uintptr(&addresses->pdata[0])
|
|
|
|
|
&& nm_ptr_to_uintptr(needle) < nm_ptr_to_uintptr(&addresses->pdata[addresses->len]);
|
2017-07-11 14:25:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const NMPObject **
|
2020-09-28 16:03:33 +02:00
|
|
|
ip4_addr_subnets_addr_list_get(const GPtrArray *addr_list, guint idx)
|
2017-07-11 14:25:08 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_assert(addr_list);
|
|
|
|
|
nm_assert(addr_list->len > 1);
|
|
|
|
|
nm_assert(idx < addr_list->len);
|
|
|
|
|
nm_assert(addr_list->pdata[idx]);
|
|
|
|
|
nm_assert(!(*((gpointer *) addr_list->pdata[idx]))
|
|
|
|
|
|| NMP_OBJECT_CAST_IP4_ADDRESS(*((gpointer *) addr_list->pdata[idx])));
|
|
|
|
|
nm_assert(idx == 0 || ip4_addr_subnets_addr_list_get(addr_list, idx - 1));
|
|
|
|
|
return addr_list->pdata[idx];
|
2016-11-14 20:52:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2020-09-28 16:03:33 +02:00
|
|
|
ip4_addr_subnets_destroy_index(GHashTable *subnets, const GPtrArray *addresses)
|
2016-11-14 20:52:24 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
GHashTableIter iter;
|
|
|
|
|
gpointer p;
|
2016-11-14 20:52:24 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!subnets)
|
|
|
|
|
return;
|
2016-11-14 20:52:24 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_hash_table_iter_init(&iter, subnets);
|
|
|
|
|
while (g_hash_table_iter_next(&iter, NULL, &p)) {
|
|
|
|
|
if (!ip4_addr_subnets_is_plain_address(addresses, p))
|
|
|
|
|
g_ptr_array_free((GPtrArray *) p, TRUE);
|
|
|
|
|
}
|
2016-11-14 20:52:24 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_hash_table_unref(subnets);
|
2016-11-14 20:52:24 +01:00
|
|
|
}
|
|
|
|
|
|
platform: track IPv4 subnets with prefix length in nm_platform_ip_address_sync()
The entire point of the dance in nm_platform_ip_address_sync() is to ensure that
conflicting IPv4 addresses are in their right order, that is, they have
the right primary/secondary flag.
Kernel only sets secondary flags for addresses that are in the same
subnet, and we also only care about the relative order of addresses
that are in the same subnet. In particular, because we rely on kernel's
"secondary" flag to implement this.
But kernel only treads addresses as secondary, if they share the exact
same subnet. For example, 192.168.0.5/24 and 192.168.0.6/25 would not
be treated as primary/secondary but just as unrelated addresses, even if
the address cleared of it's host part is the same.
This means, we must not only hash the network part of the addresses, but
also the prefix length. Implement that, by tracking the full NMPObject.
(cherry picked from commit 619dc2fcab809a1cae831c1866ce93189b575d53)
2022-04-02 10:32:55 +02:00
|
|
|
static guint
|
|
|
|
|
_ip4_addr_subnets_hash(gconstpointer ptr)
|
|
|
|
|
{
|
|
|
|
|
const NMPlatformIP4Address *addr = NMP_OBJECT_CAST_IP4_ADDRESS(ptr);
|
|
|
|
|
|
2022-09-23 12:56:54 +02:00
|
|
|
return nm_hash_vals(3282159733,
|
|
|
|
|
addr->plen,
|
|
|
|
|
nm_ip4_addr_clear_host_address(addr->address, addr->plen));
|
platform: track IPv4 subnets with prefix length in nm_platform_ip_address_sync()
The entire point of the dance in nm_platform_ip_address_sync() is to ensure that
conflicting IPv4 addresses are in their right order, that is, they have
the right primary/secondary flag.
Kernel only sets secondary flags for addresses that are in the same
subnet, and we also only care about the relative order of addresses
that are in the same subnet. In particular, because we rely on kernel's
"secondary" flag to implement this.
But kernel only treads addresses as secondary, if they share the exact
same subnet. For example, 192.168.0.5/24 and 192.168.0.6/25 would not
be treated as primary/secondary but just as unrelated addresses, even if
the address cleared of it's host part is the same.
This means, we must not only hash the network part of the addresses, but
also the prefix length. Implement that, by tracking the full NMPObject.
(cherry picked from commit 619dc2fcab809a1cae831c1866ce93189b575d53)
2022-04-02 10:32:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
_ip4_addr_subnets_equal(gconstpointer p_a, gconstpointer p_b)
|
|
|
|
|
{
|
|
|
|
|
const NMPlatformIP4Address *a = NMP_OBJECT_CAST_IP4_ADDRESS(p_a);
|
|
|
|
|
const NMPlatformIP4Address *b = NMP_OBJECT_CAST_IP4_ADDRESS(p_b);
|
|
|
|
|
|
|
|
|
|
return a->plen == b->plen
|
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_ip4_addr_clear_host_address(a->address, a->plen)
|
|
|
|
|
== nm_ip4_addr_clear_host_address(b->address, b->plen));
|
platform: track IPv4 subnets with prefix length in nm_platform_ip_address_sync()
The entire point of the dance in nm_platform_ip_address_sync() is to ensure that
conflicting IPv4 addresses are in their right order, that is, they have
the right primary/secondary flag.
Kernel only sets secondary flags for addresses that are in the same
subnet, and we also only care about the relative order of addresses
that are in the same subnet. In particular, because we rely on kernel's
"secondary" flag to implement this.
But kernel only treads addresses as secondary, if they share the exact
same subnet. For example, 192.168.0.5/24 and 192.168.0.6/25 would not
be treated as primary/secondary but just as unrelated addresses, even if
the address cleared of it's host part is the same.
This means, we must not only hash the network part of the addresses, but
also the prefix length. Implement that, by tracking the full NMPObject.
(cherry picked from commit 619dc2fcab809a1cae831c1866ce93189b575d53)
2022-04-02 10:32:55 +02:00
|
|
|
}
|
|
|
|
|
|
2016-11-14 20:52:24 +01:00
|
|
|
static GHashTable *
|
2020-09-28 16:03:33 +02:00
|
|
|
ip4_addr_subnets_build_index(const GPtrArray *addresses,
|
|
|
|
|
gboolean consider_flags,
|
|
|
|
|
gboolean full_index)
|
|
|
|
|
{
|
|
|
|
|
GHashTable *subnets;
|
|
|
|
|
guint i;
|
|
|
|
|
|
|
|
|
|
nm_assert(addresses && addresses->len);
|
|
|
|
|
|
platform: track IPv4 subnets with prefix length in nm_platform_ip_address_sync()
The entire point of the dance in nm_platform_ip_address_sync() is to ensure that
conflicting IPv4 addresses are in their right order, that is, they have
the right primary/secondary flag.
Kernel only sets secondary flags for addresses that are in the same
subnet, and we also only care about the relative order of addresses
that are in the same subnet. In particular, because we rely on kernel's
"secondary" flag to implement this.
But kernel only treads addresses as secondary, if they share the exact
same subnet. For example, 192.168.0.5/24 and 192.168.0.6/25 would not
be treated as primary/secondary but just as unrelated addresses, even if
the address cleared of it's host part is the same.
This means, we must not only hash the network part of the addresses, but
also the prefix length. Implement that, by tracking the full NMPObject.
(cherry picked from commit 619dc2fcab809a1cae831c1866ce93189b575d53)
2022-04-02 10:32:55 +02:00
|
|
|
subnets = g_hash_table_new(_ip4_addr_subnets_hash, _ip4_addr_subnets_equal);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
|
|
|
|
/* Build a hash table of all addresses per subnet */
|
|
|
|
|
for (i = 0; i < addresses->len; i++) {
|
platform: track IPv4 subnets with prefix length in nm_platform_ip_address_sync()
The entire point of the dance in nm_platform_ip_address_sync() is to ensure that
conflicting IPv4 addresses are in their right order, that is, they have
the right primary/secondary flag.
Kernel only sets secondary flags for addresses that are in the same
subnet, and we also only care about the relative order of addresses
that are in the same subnet. In particular, because we rely on kernel's
"secondary" flag to implement this.
But kernel only treads addresses as secondary, if they share the exact
same subnet. For example, 192.168.0.5/24 and 192.168.0.6/25 would not
be treated as primary/secondary but just as unrelated addresses, even if
the address cleared of it's host part is the same.
This means, we must not only hash the network part of the addresses, but
also the prefix length. Implement that, by tracking the full NMPObject.
(cherry picked from commit 619dc2fcab809a1cae831c1866ce93189b575d53)
2022-04-02 10:32:55 +02:00
|
|
|
const NMPObject **p_obj;
|
|
|
|
|
const NMPObject *obj;
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPlatformIP4Address *address;
|
2021-11-09 13:28:54 +01:00
|
|
|
GPtrArray *addr_list;
|
2020-09-28 16:03:33 +02:00
|
|
|
int position;
|
|
|
|
|
gpointer p;
|
|
|
|
|
|
|
|
|
|
if (!addresses->pdata[i])
|
|
|
|
|
continue;
|
|
|
|
|
|
platform: track IPv4 subnets with prefix length in nm_platform_ip_address_sync()
The entire point of the dance in nm_platform_ip_address_sync() is to ensure that
conflicting IPv4 addresses are in their right order, that is, they have
the right primary/secondary flag.
Kernel only sets secondary flags for addresses that are in the same
subnet, and we also only care about the relative order of addresses
that are in the same subnet. In particular, because we rely on kernel's
"secondary" flag to implement this.
But kernel only treads addresses as secondary, if they share the exact
same subnet. For example, 192.168.0.5/24 and 192.168.0.6/25 would not
be treated as primary/secondary but just as unrelated addresses, even if
the address cleared of it's host part is the same.
This means, we must not only hash the network part of the addresses, but
also the prefix length. Implement that, by tracking the full NMPObject.
(cherry picked from commit 619dc2fcab809a1cae831c1866ce93189b575d53)
2022-04-02 10:32:55 +02:00
|
|
|
p_obj = (const NMPObject **) &addresses->pdata[i];
|
|
|
|
|
obj = *p_obj;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
platform: track IPv4 subnets with prefix length in nm_platform_ip_address_sync()
The entire point of the dance in nm_platform_ip_address_sync() is to ensure that
conflicting IPv4 addresses are in their right order, that is, they have
the right primary/secondary flag.
Kernel only sets secondary flags for addresses that are in the same
subnet, and we also only care about the relative order of addresses
that are in the same subnet. In particular, because we rely on kernel's
"secondary" flag to implement this.
But kernel only treads addresses as secondary, if they share the exact
same subnet. For example, 192.168.0.5/24 and 192.168.0.6/25 would not
be treated as primary/secondary but just as unrelated addresses, even if
the address cleared of it's host part is the same.
This means, we must not only hash the network part of the addresses, but
also the prefix length. Implement that, by tracking the full NMPObject.
(cherry picked from commit 619dc2fcab809a1cae831c1866ce93189b575d53)
2022-04-02 10:32:55 +02:00
|
|
|
if (!g_hash_table_lookup_extended(subnets, obj, NULL, &p)) {
|
|
|
|
|
g_hash_table_insert(subnets, (gpointer) obj, p_obj);
|
2020-09-28 16:03:33 +02:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
nm_assert(p);
|
|
|
|
|
|
platform: track IPv4 subnets with prefix length in nm_platform_ip_address_sync()
The entire point of the dance in nm_platform_ip_address_sync() is to ensure that
conflicting IPv4 addresses are in their right order, that is, they have
the right primary/secondary flag.
Kernel only sets secondary flags for addresses that are in the same
subnet, and we also only care about the relative order of addresses
that are in the same subnet. In particular, because we rely on kernel's
"secondary" flag to implement this.
But kernel only treads addresses as secondary, if they share the exact
same subnet. For example, 192.168.0.5/24 and 192.168.0.6/25 would not
be treated as primary/secondary but just as unrelated addresses, even if
the address cleared of it's host part is the same.
This means, we must not only hash the network part of the addresses, but
also the prefix length. Implement that, by tracking the full NMPObject.
(cherry picked from commit 619dc2fcab809a1cae831c1866ce93189b575d53)
2022-04-02 10:32:55 +02:00
|
|
|
address = NMP_OBJECT_CAST_IP4_ADDRESS(obj);
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (full_index) {
|
|
|
|
|
if (ip4_addr_subnets_is_plain_address(addresses, p)) {
|
|
|
|
|
addr_list = g_ptr_array_new();
|
platform: track IPv4 subnets with prefix length in nm_platform_ip_address_sync()
The entire point of the dance in nm_platform_ip_address_sync() is to ensure that
conflicting IPv4 addresses are in their right order, that is, they have
the right primary/secondary flag.
Kernel only sets secondary flags for addresses that are in the same
subnet, and we also only care about the relative order of addresses
that are in the same subnet. In particular, because we rely on kernel's
"secondary" flag to implement this.
But kernel only treads addresses as secondary, if they share the exact
same subnet. For example, 192.168.0.5/24 and 192.168.0.6/25 would not
be treated as primary/secondary but just as unrelated addresses, even if
the address cleared of it's host part is the same.
This means, we must not only hash the network part of the addresses, but
also the prefix length. Implement that, by tracking the full NMPObject.
(cherry picked from commit 619dc2fcab809a1cae831c1866ce93189b575d53)
2022-04-02 10:32:55 +02:00
|
|
|
g_hash_table_insert(subnets, (gpointer) obj, addr_list);
|
2020-09-28 16:03:33 +02:00
|
|
|
g_ptr_array_add(addr_list, p);
|
|
|
|
|
} else
|
|
|
|
|
addr_list = p;
|
|
|
|
|
|
|
|
|
|
if (!consider_flags || NM_FLAGS_HAS(address->n_ifa_flags, IFA_F_SECONDARY))
|
|
|
|
|
position = -1; /* append */
|
|
|
|
|
else
|
|
|
|
|
position = 0; /* prepend */
|
platform: track IPv4 subnets with prefix length in nm_platform_ip_address_sync()
The entire point of the dance in nm_platform_ip_address_sync() is to ensure that
conflicting IPv4 addresses are in their right order, that is, they have
the right primary/secondary flag.
Kernel only sets secondary flags for addresses that are in the same
subnet, and we also only care about the relative order of addresses
that are in the same subnet. In particular, because we rely on kernel's
"secondary" flag to implement this.
But kernel only treads addresses as secondary, if they share the exact
same subnet. For example, 192.168.0.5/24 and 192.168.0.6/25 would not
be treated as primary/secondary but just as unrelated addresses, even if
the address cleared of it's host part is the same.
This means, we must not only hash the network part of the addresses, but
also the prefix length. Implement that, by tracking the full NMPObject.
(cherry picked from commit 619dc2fcab809a1cae831c1866ce93189b575d53)
2022-04-02 10:32:55 +02:00
|
|
|
g_ptr_array_insert(addr_list, position, p_obj);
|
2020-09-28 16:03:33 +02:00
|
|
|
} else {
|
|
|
|
|
/* we only care about the primary. No need to track the secondaries
|
2020-09-28 14:50:01 +02:00
|
|
|
* as a GPtrArray. */
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_assert(ip4_addr_subnets_is_plain_address(addresses, p));
|
|
|
|
|
if (consider_flags && !NM_FLAGS_HAS(address->n_ifa_flags, IFA_F_SECONDARY)) {
|
platform: track IPv4 subnets with prefix length in nm_platform_ip_address_sync()
The entire point of the dance in nm_platform_ip_address_sync() is to ensure that
conflicting IPv4 addresses are in their right order, that is, they have
the right primary/secondary flag.
Kernel only sets secondary flags for addresses that are in the same
subnet, and we also only care about the relative order of addresses
that are in the same subnet. In particular, because we rely on kernel's
"secondary" flag to implement this.
But kernel only treads addresses as secondary, if they share the exact
same subnet. For example, 192.168.0.5/24 and 192.168.0.6/25 would not
be treated as primary/secondary but just as unrelated addresses, even if
the address cleared of it's host part is the same.
This means, we must not only hash the network part of the addresses, but
also the prefix length. Implement that, by tracking the full NMPObject.
(cherry picked from commit 619dc2fcab809a1cae831c1866ce93189b575d53)
2022-04-02 10:32:55 +02:00
|
|
|
g_hash_table_insert(subnets, (gpointer) obj, p_obj);
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-11-14 20:52:24 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return subnets;
|
2016-11-14 20:52:24 +01:00
|
|
|
}
|
|
|
|
|
|
2017-02-08 14:47:14 +01:00
|
|
|
/**
|
|
|
|
|
* ip4_addr_subnets_is_secondary:
|
|
|
|
|
* @address: an address
|
|
|
|
|
* @subnets: the hash table mapping subnets to addresses
|
|
|
|
|
* @addresses: array of addresses in the hash table
|
|
|
|
|
* @out_addr_list: array of addresses belonging to the same subnet
|
|
|
|
|
*
|
|
|
|
|
* Checks whether @address is secondary and returns in @out_addr_list the list of addresses
|
|
|
|
|
* belonging to the same subnet, if it contains other elements.
|
|
|
|
|
*
|
|
|
|
|
* Returns: %TRUE if the address is secondary, %FALSE otherwise
|
|
|
|
|
*/
|
2016-11-14 20:52:24 +01:00
|
|
|
static gboolean
|
2021-11-09 13:28:54 +01:00
|
|
|
ip4_addr_subnets_is_secondary(const NMPObject *address,
|
|
|
|
|
GHashTable *subnets,
|
|
|
|
|
const GPtrArray *addresses,
|
2020-09-28 16:03:33 +02:00
|
|
|
const GPtrArray **out_addr_list)
|
|
|
|
|
{
|
platform: track IPv4 subnets with prefix length in nm_platform_ip_address_sync()
The entire point of the dance in nm_platform_ip_address_sync() is to ensure that
conflicting IPv4 addresses are in their right order, that is, they have
the right primary/secondary flag.
Kernel only sets secondary flags for addresses that are in the same
subnet, and we also only care about the relative order of addresses
that are in the same subnet. In particular, because we rely on kernel's
"secondary" flag to implement this.
But kernel only treads addresses as secondary, if they share the exact
same subnet. For example, 192.168.0.5/24 and 192.168.0.6/25 would not
be treated as primary/secondary but just as unrelated addresses, even if
the address cleared of it's host part is the same.
This means, we must not only hash the network part of the addresses, but
also the prefix length. Implement that, by tracking the full NMPObject.
(cherry picked from commit 619dc2fcab809a1cae831c1866ce93189b575d53)
2022-04-02 10:32:55 +02:00
|
|
|
const GPtrArray *addr_list;
|
|
|
|
|
gconstpointer p;
|
|
|
|
|
const NMPObject **o;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
platform: track IPv4 subnets with prefix length in nm_platform_ip_address_sync()
The entire point of the dance in nm_platform_ip_address_sync() is to ensure that
conflicting IPv4 addresses are in their right order, that is, they have
the right primary/secondary flag.
Kernel only sets secondary flags for addresses that are in the same
subnet, and we also only care about the relative order of addresses
that are in the same subnet. In particular, because we rely on kernel's
"secondary" flag to implement this.
But kernel only treads addresses as secondary, if they share the exact
same subnet. For example, 192.168.0.5/24 and 192.168.0.6/25 would not
be treated as primary/secondary but just as unrelated addresses, even if
the address cleared of it's host part is the same.
This means, we must not only hash the network part of the addresses, but
also the prefix length. Implement that, by tracking the full NMPObject.
(cherry picked from commit 619dc2fcab809a1cae831c1866ce93189b575d53)
2022-04-02 10:32:55 +02:00
|
|
|
p = g_hash_table_lookup(subnets, address);
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_assert(p);
|
|
|
|
|
if (!ip4_addr_subnets_is_plain_address(addresses, p)) {
|
|
|
|
|
addr_list = p;
|
|
|
|
|
nm_assert(addr_list->len > 1);
|
|
|
|
|
NM_SET_OUT(out_addr_list, addr_list);
|
|
|
|
|
o = ip4_addr_subnets_addr_list_get(addr_list, 0);
|
|
|
|
|
nm_assert(o && *o);
|
|
|
|
|
if (*o != address)
|
|
|
|
|
return TRUE;
|
|
|
|
|
} else {
|
|
|
|
|
NM_SET_OUT(out_addr_list, NULL);
|
|
|
|
|
return address != *((gconstpointer *) p);
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
2016-11-14 20:52:24 +01:00
|
|
|
}
|
|
|
|
|
|
2020-03-18 21:54:22 +01:00
|
|
|
typedef enum {
|
2020-09-28 16:03:33 +02:00
|
|
|
IP6_ADDR_SCOPE_LOOPBACK,
|
|
|
|
|
IP6_ADDR_SCOPE_LINKLOCAL,
|
|
|
|
|
IP6_ADDR_SCOPE_SITELOCAL,
|
|
|
|
|
IP6_ADDR_SCOPE_OTHER,
|
2020-03-18 21:54:22 +01:00
|
|
|
} IP6AddrScope;
|
|
|
|
|
|
|
|
|
|
static IP6AddrScope
|
2020-09-28 16:03:33 +02:00
|
|
|
ip6_address_scope(const NMPlatformIP6Address *a)
|
2018-05-30 11:37:09 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
if (IN6_IS_ADDR_LOOPBACK(&a->address))
|
|
|
|
|
return IP6_ADDR_SCOPE_LOOPBACK;
|
|
|
|
|
if (IN6_IS_ADDR_LINKLOCAL(&a->address))
|
|
|
|
|
return IP6_ADDR_SCOPE_LINKLOCAL;
|
|
|
|
|
if (IN6_IS_ADDR_SITELOCAL(&a->address))
|
|
|
|
|
return IP6_ADDR_SCOPE_SITELOCAL;
|
|
|
|
|
return IP6_ADDR_SCOPE_OTHER;
|
2018-05-30 11:37:09 +02:00
|
|
|
}
|
|
|
|
|
|
all: don't use gchar/gshort/gint/glong but C types
We commonly don't use the glib typedefs for char/short/int/long,
but their C types directly.
$ git grep '\<g\(char\|short\|int\|long\|float\|double\)\>' | wc -l
587
$ git grep '\<\(char\|short\|int\|long\|float\|double\)\>' | wc -l
21114
One could argue that using the glib typedefs is preferable in
public API (of our glib based libnm library) or where it clearly
is related to glib, like during
g_object_set (obj, PROPERTY, (gint) value, NULL);
However, that argument does not seem strong, because in practice we don't
follow that argument today, and seldomly use the glib typedefs.
Also, the style guide for this would be hard to formalize, because
"using them where clearly related to a glib" is a very loose suggestion.
Also note that glib typedefs will always just be typedefs of the
underlying C types. There is no danger of glib changing the meaning
of these typedefs (because that would be a major API break of glib).
A simple style guide is instead: don't use these typedefs.
No manual actions, I only ran the bash script:
FILES=($(git ls-files '*.[hc]'))
sed -i \
-e 's/\<g\(char\|short\|int\|long\|float\|double\)\>\( [^ ]\)/\1\2/g' \
-e 's/\<g\(char\|short\|int\|long\|float\|double\)\> /\1 /g' \
-e 's/\<g\(char\|short\|int\|long\|float\|double\)\>/\1/g' \
"${FILES[@]}"
2018-07-11 07:40:19 +02:00
|
|
|
static int
|
2022-03-28 21:36:16 +02:00
|
|
|
ip6_address_scope_cmp_ascending(gconstpointer p_a, gconstpointer p_b, gpointer unused)
|
2018-05-30 11:37:09 +02:00
|
|
|
{
|
2022-03-28 21:36:16 +02:00
|
|
|
NM_CMP_DIRECT(ip6_address_scope(NMP_OBJECT_CAST_IP6_ADDRESS(*(const NMPObject *const *) p_a)),
|
|
|
|
|
ip6_address_scope(NMP_OBJECT_CAST_IP6_ADDRESS(*(const NMPObject *const *) p_b)));
|
2020-09-28 16:03:33 +02:00
|
|
|
return 0;
|
2018-05-30 11:37:09 +02:00
|
|
|
}
|
|
|
|
|
|
2022-03-28 21:36:16 +02:00
|
|
|
static int
|
|
|
|
|
ip6_address_scope_cmp_descending(gconstpointer p_a, gconstpointer p_b, gpointer unused)
|
|
|
|
|
{
|
|
|
|
|
return ip6_address_scope_cmp_ascending(p_b, p_a, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-16 14:24:46 +02:00
|
|
|
/**
|
2020-07-29 12:46:21 +02:00
|
|
|
* nm_platform_ip_address_sync:
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
* @self: platform instance
|
2020-07-29 12:46:21 +02:00
|
|
|
* @addr_family: the address family AF_INET or AF_INET6.
|
2013-04-16 14:24:46 +02:00
|
|
|
* @ifindex: Interface index
|
2022-03-29 16:44:29 +02:00
|
|
|
* @known_addresses: List of addresses. The list will be modified and
|
|
|
|
|
* expired addresses will be cleared (by calling nmp_object_unref()
|
|
|
|
|
* on the array element).
|
2023-03-01 01:21:38 +01:00
|
|
|
* @addresses_prune: (nullable): the list of addresses to delete.
|
2020-07-29 13:49:31 +02:00
|
|
|
* If platform has such an address configured, it will be deleted
|
|
|
|
|
* at the beginning of the sync. Note that the array will be modified
|
|
|
|
|
* by the function.
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
* Addresses that are both contained in @known_addresses and @addresses_prune
|
|
|
|
|
* will be configured.
|
2022-09-08 09:28:28 +02:00
|
|
|
* @flags: #NMPIPAddressSyncFlags to affect the sync. If "with-noprefixroute"
|
|
|
|
|
* flag is set, the method will automatically set IFA_F_NOPREFIXROUTE for
|
|
|
|
|
* all addresses.
|
2013-04-16 14:24:46 +02:00
|
|
|
*
|
|
|
|
|
* A convenience function to synchronize addresses for a specific interface
|
|
|
|
|
* with the least possible disturbance. It simply removes addresses that are
|
|
|
|
|
* not listed and adds addresses that are.
|
|
|
|
|
*
|
|
|
|
|
* Returns: %TRUE on success.
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2022-09-08 09:28:28 +02:00
|
|
|
nm_platform_ip_address_sync(NMPlatform *self,
|
|
|
|
|
int addr_family,
|
|
|
|
|
int ifindex,
|
|
|
|
|
GPtrArray *known_addresses,
|
|
|
|
|
GPtrArray *addresses_prune,
|
|
|
|
|
NMPIPAddressSyncFlags flags)
|
2020-09-28 16:03:33 +02:00
|
|
|
{
|
platform: make "now" timestamp an in/out parameter to nmp_utils_lifetime_get()
nmp_utils_lifetime_get() calculates the lifetime of addresses,
and it bases the result on a "now" timestamp.
If you have two addresses and calculate their expiry, then we want to
base it on top of the same "now" timestamp, meaning, we should
only call nm_utils_get_monotonic_timestamp_sec() once. This is also a
performance optimization. But much more importantly, when we make a
comparison at a certain moment, we need that all sides have the same
understanding of the current timestamp.
But nmp_utils_lifetime_get() does not always require the now timestamp.
And the caller doesn't know, whether it will need it (short of knowing
how nmp_utils_lifetime_get() is implemented). So, make the now parameter
an in/out argument. If we pass in an already valid now timestamp, use
that. Otherwise, fetch the current time and also return it.
(cherry picked from commit deb37401e95d4ea0025e406424c8da7c10bc9712)
2022-03-29 22:45:56 +02:00
|
|
|
gint32 now = 0;
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
const int IS_IPv4 = NM_IS_IPv4(addr_family);
|
|
|
|
|
NMPLookup lookup;
|
platform: re-configure one address at a time in nm_platform_ip_address_sync()
Try to do one change at a time when reconfiguring addresses, to not
remove several/all addresses at once.
For IP addresses, kernel cares about the order in which they were added.
This mostly affects source address selection, and the "secondary" flag
for IPv4 addresses. The order is thus related to the priority of an
address.
There is no direct kernel API to change the order. Instead, we have to
add them in the correct order. During a sync, if an address already
exists in the wrong order, we need to remove it, and re-add it.
Btw, with IPv4 addresses added first via netlink are the primary
address, while with IPv6 it's reverse.
Previously, we would first iterate over all addresses and remove those
that had a conflicting order. This means, that we would potentially
remove all addresses for a short while, before readding them. That seems
problematic.
Instead, first track all addresses that are in the wrong order. And in
the step when we add/update the address, remove it. We now only remove
and address shortly before re-adding it. This way the time for which the
address on the interface is missing is shorter. More importantly, we will
never remove all addresses at the same time.
(cherry picked from commit a6fd6416345ccb397ae174dc39d66e9e7bfa7fe6)
2022-04-27 16:25:01 +02:00
|
|
|
const gboolean EXTRA_LOGGING = FALSE;
|
|
|
|
|
gs_unref_hashtable GHashTable *known_addresses_idx = NULL;
|
|
|
|
|
gs_unref_hashtable GHashTable *plat_addrs_to_delete = NULL;
|
|
|
|
|
gs_unref_ptrarray GPtrArray *plat_addresses = NULL;
|
2022-03-29 16:44:29 +02:00
|
|
|
gboolean success;
|
2020-09-28 16:03:33 +02:00
|
|
|
guint i_plat;
|
|
|
|
|
guint i_know;
|
|
|
|
|
guint i;
|
|
|
|
|
guint j;
|
|
|
|
|
|
|
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
|
|
|
|
|
platform: re-configure one address at a time in nm_platform_ip_address_sync()
Try to do one change at a time when reconfiguring addresses, to not
remove several/all addresses at once.
For IP addresses, kernel cares about the order in which they were added.
This mostly affects source address selection, and the "secondary" flag
for IPv4 addresses. The order is thus related to the priority of an
address.
There is no direct kernel API to change the order. Instead, we have to
add them in the correct order. During a sync, if an address already
exists in the wrong order, we need to remove it, and re-add it.
Btw, with IPv4 addresses added first via netlink are the primary
address, while with IPv6 it's reverse.
Previously, we would first iterate over all addresses and remove those
that had a conflicting order. This means, that we would potentially
remove all addresses for a short while, before readding them. That seems
problematic.
Instead, first track all addresses that are in the wrong order. And in
the step when we add/update the address, remove it. We now only remove
and address shortly before re-adding it. This way the time for which the
address on the interface is missing is shorter. More importantly, we will
never remove all addresses at the same time.
(cherry picked from commit a6fd6416345ccb397ae174dc39d66e9e7bfa7fe6)
2022-04-27 16:25:01 +02:00
|
|
|
#define _plat_addrs_to_delete_ensure(ptr) \
|
|
|
|
|
({ \
|
|
|
|
|
GHashTable **_ptr = (ptr); \
|
|
|
|
|
\
|
|
|
|
|
if (!*_ptr) { \
|
|
|
|
|
*_ptr = g_hash_table_new_full((GHashFunc) nmp_object_id_hash, \
|
|
|
|
|
(GEqualFunc) nmp_object_id_equal, \
|
|
|
|
|
(GDestroyNotify) nmp_object_unref, \
|
|
|
|
|
NULL); \
|
|
|
|
|
} \
|
|
|
|
|
*_ptr; \
|
|
|
|
|
})
|
|
|
|
|
|
2022-03-25 20:33:24 +01:00
|
|
|
/* Disabled. Enable this for printf debugging. */
|
|
|
|
|
if (EXTRA_LOGGING) {
|
2022-03-30 09:23:54 +02:00
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
2022-03-25 20:33:24 +01:00
|
|
|
char sbuf1[50];
|
|
|
|
|
|
|
|
|
|
_LOG3T("IPv%c address sync on %d (%u addresses, %u to prune)",
|
|
|
|
|
nm_utils_addr_family_to_char(addr_family),
|
|
|
|
|
ifindex,
|
|
|
|
|
nm_g_ptr_array_len(known_addresses),
|
|
|
|
|
nm_g_ptr_array_len(addresses_prune));
|
|
|
|
|
for (i = 0; known_addresses && i < known_addresses->len; i++) {
|
|
|
|
|
_LOG3T(" address#%u: %s%s",
|
|
|
|
|
i,
|
|
|
|
|
nmp_object_to_string(known_addresses->pdata[i],
|
|
|
|
|
NMP_OBJECT_TO_STRING_ALL,
|
|
|
|
|
sbuf,
|
|
|
|
|
sizeof(sbuf)),
|
|
|
|
|
IS_IPv4 ? ""
|
|
|
|
|
: nm_sprintf_buf(sbuf1,
|
|
|
|
|
" (scope %d)",
|
|
|
|
|
(int) ip6_address_scope(NMP_OBJECT_CAST_IP6_ADDRESS(
|
|
|
|
|
known_addresses->pdata[i]))));
|
|
|
|
|
}
|
|
|
|
|
for (i = 0; addresses_prune && i < addresses_prune->len; i++) {
|
|
|
|
|
_LOG3T(" prune #%u: %s",
|
|
|
|
|
i,
|
|
|
|
|
nmp_object_to_string(addresses_prune->pdata[i],
|
|
|
|
|
NMP_OBJECT_TO_STRING_ALL,
|
|
|
|
|
sbuf,
|
|
|
|
|
sizeof(sbuf)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
core: change order/priority of static IPv6 addresses relative to autoconf6/DHCPv6
The order of addresses can matter for source address selection.
This is described in RFC 6724 section 5, but if the rules don't
determine a clear winner, the order matters.
Change the relative order of IPv6 addresses. Previously, we would prefer
autoconf6, over DHCPv6, over manual addresses. Now that got reverted
to make more sense and be consistent with IPv4.
Also, if we had multiple autoconf6 addresses (received at different
moments in time), then previously a newly received address would be
added with highest priority. Now, the older address will be preferred
and that order will be enforced (this can be a problem, see (*) below).
For IPv4, it's all simple and sensible. When we add addresses in kernel
via netlink, the first address (of a subnet) becomes the primary.
Note that we only control the order of addresses of the same subnet.
The addresses in ipv4.addresses" are sorted with primary address first.
In the same way is the order for addresses in NML3ConfigData and for
@known_addresses in nm_platform_ip_address_sync(), all primary-first.
Also, manual addresses are sorted with higher priority compared to DHCPv4
addresses (at least since NetworkManager 1.36). That means the way how we
merge NML3ConfigData makes sense (nm_l3_config_data_merge()) because we first
merge the static configuration, then the DHCPv4 configuration, where we just
append the lower priority DHCPv4 addresses.
For IPv6, the address priority is messed up. On netlink/kernel, the last added
address becomes the preferred one (we thus need to add them in the order of
lowest priority first). Consequently and historically, the IPv6 addresses in
@known_addresses parameter to nm_platform_ip_address_sync() were
lowest priority first. And so they were tracked in NML3ConfigData
and in the profile ("ipv6.addresses"). That is confusing.
Also, we usually want to merge NML3ConfigData with different priorities
(e.g. static configuration from the profile before autoconf6/DHCPv6),
as we do with IPv4. However, since internally IPv6 addresses are tracked in
reverse order, it means later NML3ConfigData would be appended and get effectively
a higher priority. That means, autoconf6 addresses were preferred over DHCPv6 and
over manual "ipv6.addresses", respectively. That seems undesirable and inconsistent
with IPv4. Change that. This is a change in behavior.
Note that changing the order of addresses means to remove and re-add
them in the right (inverse) order, with lease important first. This
means, when we add a new address with lower priority, we need to remove
all higher priority addresses temporarily, before readding them. That
is a problem(*).
Note that in the profile, "ipv6.addresses" is still tracked in reverse
order. This did not change, but might change later.
(cherry picked from commit 4a548423b91ebaf590700926709bb95a32a21e99)
2022-03-31 11:46:56 +02:00
|
|
|
/* @known_addresses are in decreasing priority order (highest priority addresses first). */
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* The order we want to enforce is only among addresses with the same
|
2020-09-28 14:50:01 +02:00
|
|
|
* scope, as the kernel keeps addresses sorted by scope. Therefore,
|
|
|
|
|
* apply the same sorting to known addresses, so that we don't try to
|
|
|
|
|
* unnecessary change the order of addresses with different scopes. */
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!IS_IPv4) {
|
|
|
|
|
if (known_addresses)
|
core: change order/priority of static IPv6 addresses relative to autoconf6/DHCPv6
The order of addresses can matter for source address selection.
This is described in RFC 6724 section 5, but if the rules don't
determine a clear winner, the order matters.
Change the relative order of IPv6 addresses. Previously, we would prefer
autoconf6, over DHCPv6, over manual addresses. Now that got reverted
to make more sense and be consistent with IPv4.
Also, if we had multiple autoconf6 addresses (received at different
moments in time), then previously a newly received address would be
added with highest priority. Now, the older address will be preferred
and that order will be enforced (this can be a problem, see (*) below).
For IPv4, it's all simple and sensible. When we add addresses in kernel
via netlink, the first address (of a subnet) becomes the primary.
Note that we only control the order of addresses of the same subnet.
The addresses in ipv4.addresses" are sorted with primary address first.
In the same way is the order for addresses in NML3ConfigData and for
@known_addresses in nm_platform_ip_address_sync(), all primary-first.
Also, manual addresses are sorted with higher priority compared to DHCPv4
addresses (at least since NetworkManager 1.36). That means the way how we
merge NML3ConfigData makes sense (nm_l3_config_data_merge()) because we first
merge the static configuration, then the DHCPv4 configuration, where we just
append the lower priority DHCPv4 addresses.
For IPv6, the address priority is messed up. On netlink/kernel, the last added
address becomes the preferred one (we thus need to add them in the order of
lowest priority first). Consequently and historically, the IPv6 addresses in
@known_addresses parameter to nm_platform_ip_address_sync() were
lowest priority first. And so they were tracked in NML3ConfigData
and in the profile ("ipv6.addresses"). That is confusing.
Also, we usually want to merge NML3ConfigData with different priorities
(e.g. static configuration from the profile before autoconf6/DHCPv6),
as we do with IPv4. However, since internally IPv6 addresses are tracked in
reverse order, it means later NML3ConfigData would be appended and get effectively
a higher priority. That means, autoconf6 addresses were preferred over DHCPv6 and
over manual "ipv6.addresses", respectively. That seems undesirable and inconsistent
with IPv4. Change that. This is a change in behavior.
Note that changing the order of addresses means to remove and re-add
them in the right (inverse) order, with lease important first. This
means, when we add a new address with lower priority, we need to remove
all higher priority addresses temporarily, before readding them. That
is a problem(*).
Note that in the profile, "ipv6.addresses" is still tracked in reverse
order. This did not change, but might change later.
(cherry picked from commit 4a548423b91ebaf590700926709bb95a32a21e99)
2022-03-31 11:46:56 +02:00
|
|
|
g_ptr_array_sort_with_data(known_addresses, ip6_address_scope_cmp_descending, NULL);
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!_addr_array_clean_expired(addr_family,
|
|
|
|
|
ifindex,
|
|
|
|
|
known_addresses,
|
platform: make "now" timestamp an in/out parameter to nmp_utils_lifetime_get()
nmp_utils_lifetime_get() calculates the lifetime of addresses,
and it bases the result on a "now" timestamp.
If you have two addresses and calculate their expiry, then we want to
base it on top of the same "now" timestamp, meaning, we should
only call nm_utils_get_monotonic_timestamp_sec() once. This is also a
performance optimization. But much more importantly, when we make a
comparison at a certain moment, we need that all sides have the same
understanding of the current timestamp.
But nmp_utils_lifetime_get() does not always require the now timestamp.
And the caller doesn't know, whether it will need it (short of knowing
how nmp_utils_lifetime_get() is implemented). So, make the now parameter
an in/out argument. If we pass in an already valid now timestamp, use
that. Otherwise, fetch the current time and also return it.
(cherry picked from commit deb37401e95d4ea0025e406424c8da7c10bc9712)
2022-03-29 22:45:56 +02:00
|
|
|
&now,
|
2020-09-28 16:03:33 +02:00
|
|
|
&known_addresses_idx))
|
|
|
|
|
known_addresses = NULL;
|
|
|
|
|
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
if (nm_g_ptr_array_len(addresses_prune) > 0) {
|
|
|
|
|
/* First delete addresses that we should prune (and which are no longer tracked
|
|
|
|
|
* as @known_addresses. */
|
|
|
|
|
for (i = 0; i < addresses_prune->len; i++) {
|
|
|
|
|
const NMPObject *prune_obj = addresses_prune->pdata[i];
|
|
|
|
|
|
|
|
|
|
nm_assert(NM_IN_SET(NMP_OBJECT_GET_TYPE(prune_obj),
|
|
|
|
|
NMP_OBJECT_TYPE_IP4_ADDRESS,
|
|
|
|
|
NMP_OBJECT_TYPE_IP6_ADDRESS));
|
|
|
|
|
|
|
|
|
|
if (nm_g_hash_table_contains(known_addresses_idx, prune_obj))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
nm_platform_ip_address_delete(self,
|
|
|
|
|
addr_family,
|
|
|
|
|
ifindex,
|
|
|
|
|
NMP_OBJECT_CAST_IP_ADDRESS(prune_obj));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-11 11:41:39 +02:00
|
|
|
/* ensure we have the platform cache up to date. */
|
|
|
|
|
nm_platform_process_events(self);
|
|
|
|
|
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
/* @plat_addresses for IPv6 must be sorted in decreasing priority order (highest priority addresses first).
|
|
|
|
|
* IPv4 are probably unsorted or sorted with lowest priority first, but their order doesn't matter because
|
|
|
|
|
* we check the "secondary" flag. */
|
|
|
|
|
plat_addresses = nm_platform_lookup_clone(
|
|
|
|
|
self,
|
2022-06-24 23:32:13 +02:00
|
|
|
nmp_lookup_init_object_by_ifindex(&lookup, NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4), ifindex),
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
NULL,
|
|
|
|
|
NULL);
|
2018-02-08 13:38:47 +01:00
|
|
|
|
2022-03-25 20:33:24 +01:00
|
|
|
if (EXTRA_LOGGING && plat_addresses) {
|
|
|
|
|
for (i = 0; i < plat_addresses->len; i++) {
|
2022-03-30 09:23:54 +02:00
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
2022-03-25 20:33:24 +01:00
|
|
|
char sbuf1[50];
|
|
|
|
|
|
|
|
|
|
_LOG3T(" platform#%u: %s%s",
|
|
|
|
|
i,
|
|
|
|
|
nmp_object_to_string(plat_addresses->pdata[i],
|
|
|
|
|
NMP_OBJECT_TO_STRING_ALL,
|
|
|
|
|
sbuf,
|
|
|
|
|
sizeof(sbuf)),
|
|
|
|
|
IS_IPv4 ? ""
|
|
|
|
|
: nm_sprintf_buf(sbuf1,
|
|
|
|
|
" (scope %d)",
|
|
|
|
|
(int) ip6_address_scope(NMP_OBJECT_CAST_IP6_ADDRESS(
|
|
|
|
|
plat_addresses->pdata[i]))));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (nm_g_ptr_array_len(plat_addresses) > 0) {
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
/* Delete addresses that interfere with our intended order. */
|
2020-09-28 16:03:33 +02:00
|
|
|
if (IS_IPv4) {
|
platform: track IPv4 subnets with prefix length in nm_platform_ip_address_sync()
The entire point of the dance in nm_platform_ip_address_sync() is to ensure that
conflicting IPv4 addresses are in their right order, that is, they have
the right primary/secondary flag.
Kernel only sets secondary flags for addresses that are in the same
subnet, and we also only care about the relative order of addresses
that are in the same subnet. In particular, because we rely on kernel's
"secondary" flag to implement this.
But kernel only treads addresses as secondary, if they share the exact
same subnet. For example, 192.168.0.5/24 and 192.168.0.6/25 would not
be treated as primary/secondary but just as unrelated addresses, even if
the address cleared of it's host part is the same.
This means, we must not only hash the network part of the addresses, but
also the prefix length. Implement that, by tracking the full NMPObject.
(cherry picked from commit 619dc2fcab809a1cae831c1866ce93189b575d53)
2022-04-02 10:32:55 +02:00
|
|
|
GHashTable *known_subnets = NULL;
|
2022-04-02 10:34:17 +02:00
|
|
|
GHashTable *plat_subnets;
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
gs_free bool *plat_handled_to_free = NULL;
|
|
|
|
|
bool *plat_handled = NULL;
|
|
|
|
|
|
|
|
|
|
/* For IPv4, we only consider it a conflict for addresses in the same
|
|
|
|
|
* subnet. That's where kernel will assign a primary/secondary flag.
|
|
|
|
|
* For different subnets, we don't define the order. */
|
2020-07-29 12:46:21 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
plat_subnets = ip4_addr_subnets_build_index(plat_addresses, TRUE, TRUE);
|
2020-07-29 12:46:21 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
for (i = 0; i < plat_addresses->len; i++) {
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
const NMPObject *plat_obj = plat_addresses->pdata[i];
|
|
|
|
|
const NMPObject *known_obj;
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPlatformIP4Address *plat_address;
|
2021-11-09 13:28:54 +01:00
|
|
|
const GPtrArray *addr_list;
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
gboolean secondary;
|
2020-07-29 12:46:21 +02:00
|
|
|
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
if (plat_handled && plat_handled[i])
|
2020-09-28 16:03:33 +02:00
|
|
|
continue;
|
2013-04-16 14:24:46 +02:00
|
|
|
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
known_obj = nm_g_hash_table_lookup(known_addresses_idx, plat_obj);
|
|
|
|
|
|
|
|
|
|
if (!known_obj) {
|
|
|
|
|
/* this address is added externally. Even if it's presence would mess
|
|
|
|
|
* with our desired order, we cannot delete it. Skip it. */
|
|
|
|
|
if (!plat_handled) {
|
|
|
|
|
plat_handled = nm_malloc0_maybe_a(300,
|
|
|
|
|
sizeof(bool) * plat_addresses->len,
|
|
|
|
|
&plat_handled_to_free);
|
|
|
|
|
}
|
|
|
|
|
plat_handled[i] = TRUE;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2017-12-15 09:46:11 +01:00
|
|
|
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
if (!known_subnets)
|
|
|
|
|
known_subnets = ip4_addr_subnets_build_index(known_addresses, FALSE, FALSE);
|
2020-07-29 12:46:21 +02:00
|
|
|
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
plat_address = NMP_OBJECT_CAST_IP4_ADDRESS(plat_obj);
|
2020-07-29 12:46:21 +02:00
|
|
|
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
secondary =
|
|
|
|
|
ip4_addr_subnets_is_secondary(known_obj, known_subnets, known_addresses, NULL);
|
|
|
|
|
if (secondary == NM_FLAGS_HAS(plat_address->n_ifa_flags, IFA_F_SECONDARY)) {
|
|
|
|
|
/* if we have an existing known-address, with matching secondary role,
|
|
|
|
|
* do not delete the platform-address. */
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2020-07-29 12:46:21 +02:00
|
|
|
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
if (!plat_handled) {
|
|
|
|
|
plat_handled = nm_malloc0_maybe_a(300,
|
|
|
|
|
sizeof(bool) * plat_addresses->len,
|
|
|
|
|
&plat_handled_to_free);
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
plat_handled[i] = TRUE;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
platform: re-configure one address at a time in nm_platform_ip_address_sync()
Try to do one change at a time when reconfiguring addresses, to not
remove several/all addresses at once.
For IP addresses, kernel cares about the order in which they were added.
This mostly affects source address selection, and the "secondary" flag
for IPv4 addresses. The order is thus related to the priority of an
address.
There is no direct kernel API to change the order. Instead, we have to
add them in the correct order. During a sync, if an address already
exists in the wrong order, we need to remove it, and re-add it.
Btw, with IPv4 addresses added first via netlink are the primary
address, while with IPv6 it's reverse.
Previously, we would first iterate over all addresses and remove those
that had a conflicting order. This means, that we would potentially
remove all addresses for a short while, before readding them. That seems
problematic.
Instead, first track all addresses that are in the wrong order. And in
the step when we add/update the address, remove it. We now only remove
and address shortly before re-adding it. This way the time for which the
address on the interface is missing is shorter. More importantly, we will
never remove all addresses at the same time.
(cherry picked from commit a6fd6416345ccb397ae174dc39d66e9e7bfa7fe6)
2022-04-27 16:25:01 +02:00
|
|
|
g_hash_table_add(_plat_addrs_to_delete_ensure(&plat_addrs_to_delete),
|
|
|
|
|
(gpointer) nmp_object_ref(plat_obj));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
|
|
|
|
if (!ip4_addr_subnets_is_secondary(plat_obj,
|
|
|
|
|
plat_subnets,
|
|
|
|
|
plat_addresses,
|
|
|
|
|
&addr_list)
|
|
|
|
|
&& addr_list) {
|
|
|
|
|
/* If we just deleted a primary addresses and there were
|
2020-09-28 14:50:01 +02:00
|
|
|
* secondary ones the kernel can do two things, depending on
|
|
|
|
|
* version and sysctl setting: delete also secondary addresses
|
|
|
|
|
* or promote a secondary to primary. Ensure that secondary
|
|
|
|
|
* addresses are deleted, so that we can start with a clean
|
|
|
|
|
* slate and add addresses in the right order. */
|
2020-09-28 16:03:33 +02:00
|
|
|
for (j = 1; j < addr_list->len; j++) {
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
const NMPObject **o = ip4_addr_subnets_addr_list_get(addr_list, j);
|
|
|
|
|
guint o_idx;
|
|
|
|
|
|
|
|
|
|
o_idx = (o - ((const NMPObject **) &plat_addresses->pdata[0]));
|
|
|
|
|
|
|
|
|
|
nm_assert(o_idx < plat_addresses->len);
|
|
|
|
|
nm_assert(o == ((const NMPObject **) &plat_addresses->pdata[o_idx]));
|
|
|
|
|
|
|
|
|
|
if (plat_handled[o_idx])
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
plat_handled[o_idx] = TRUE;
|
|
|
|
|
|
|
|
|
|
if (!nm_g_hash_table_contains(known_addresses_idx, *o)) {
|
|
|
|
|
/* Again, this is an external address. We cannot delete
|
|
|
|
|
* it to fix the address order. Pass. */
|
platform: re-configure one address at a time in nm_platform_ip_address_sync()
Try to do one change at a time when reconfiguring addresses, to not
remove several/all addresses at once.
For IP addresses, kernel cares about the order in which they were added.
This mostly affects source address selection, and the "secondary" flag
for IPv4 addresses. The order is thus related to the priority of an
address.
There is no direct kernel API to change the order. Instead, we have to
add them in the correct order. During a sync, if an address already
exists in the wrong order, we need to remove it, and re-add it.
Btw, with IPv4 addresses added first via netlink are the primary
address, while with IPv6 it's reverse.
Previously, we would first iterate over all addresses and remove those
that had a conflicting order. This means, that we would potentially
remove all addresses for a short while, before readding them. That seems
problematic.
Instead, first track all addresses that are in the wrong order. And in
the step when we add/update the address, remove it. We now only remove
and address shortly before re-adding it. This way the time for which the
address on the interface is missing is shorter. More importantly, we will
never remove all addresses at the same time.
(cherry picked from commit a6fd6416345ccb397ae174dc39d66e9e7bfa7fe6)
2022-04-27 16:25:01 +02:00
|
|
|
continue;
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
platform: re-configure one address at a time in nm_platform_ip_address_sync()
Try to do one change at a time when reconfiguring addresses, to not
remove several/all addresses at once.
For IP addresses, kernel cares about the order in which they were added.
This mostly affects source address selection, and the "secondary" flag
for IPv4 addresses. The order is thus related to the priority of an
address.
There is no direct kernel API to change the order. Instead, we have to
add them in the correct order. During a sync, if an address already
exists in the wrong order, we need to remove it, and re-add it.
Btw, with IPv4 addresses added first via netlink are the primary
address, while with IPv6 it's reverse.
Previously, we would first iterate over all addresses and remove those
that had a conflicting order. This means, that we would potentially
remove all addresses for a short while, before readding them. That seems
problematic.
Instead, first track all addresses that are in the wrong order. And in
the step when we add/update the address, remove it. We now only remove
and address shortly before re-adding it. This way the time for which the
address on the interface is missing is shorter. More importantly, we will
never remove all addresses at the same time.
(cherry picked from commit a6fd6416345ccb397ae174dc39d66e9e7bfa7fe6)
2022-04-27 16:25:01 +02:00
|
|
|
|
|
|
|
|
g_hash_table_add(_plat_addrs_to_delete_ensure(&plat_addrs_to_delete),
|
|
|
|
|
(gpointer) nmp_object_ref(*o));
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ip4_addr_subnets_destroy_index(plat_subnets, plat_addresses);
|
2022-04-02 10:34:17 +02:00
|
|
|
ip4_addr_subnets_destroy_index(known_subnets, known_addresses);
|
2020-09-28 16:03:33 +02:00
|
|
|
} else {
|
|
|
|
|
IP6AddrScope cur_scope;
|
|
|
|
|
gboolean delete_remaining_addrs;
|
|
|
|
|
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
/* For IPv6, we only compare addresses per-scope. Addresses in different
|
|
|
|
|
* scopes don't have a defined order. */
|
|
|
|
|
|
2022-03-28 21:36:16 +02:00
|
|
|
g_ptr_array_sort_with_data(plat_addresses, ip6_address_scope_cmp_descending, NULL);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
/* First, check that existing addresses have a matching plen as the ones
|
|
|
|
|
* we are about to configure (@known_addresses). If not, delete them. */
|
2020-09-28 16:03:33 +02:00
|
|
|
for (i_plat = 0; i_plat < plat_addresses->len; i_plat++) {
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
const NMPObject *plat_obj = plat_addresses->pdata[i_plat];
|
|
|
|
|
const NMPObject *known_obj;
|
|
|
|
|
|
|
|
|
|
known_obj = nm_g_hash_table_lookup(known_addresses_idx, plat_obj);
|
|
|
|
|
if (!known_obj) {
|
|
|
|
|
/* We don't know this address. It was added externally. Keep it configured.
|
|
|
|
|
* We also don't want to delete the address below, so mark it as handled
|
|
|
|
|
* by clearing the pointer. */
|
|
|
|
|
nm_clear_pointer(&plat_addresses->pdata[i_plat], nmp_object_unref);
|
|
|
|
|
continue;
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
2020-07-29 12:46:21 +02:00
|
|
|
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
if (NMP_OBJECT_CAST_IP6_ADDRESS(plat_obj)->plen
|
|
|
|
|
!= NMP_OBJECT_CAST_IP6_ADDRESS(known_obj)->plen) {
|
|
|
|
|
/* technically, plen is not part of the ID for IPv6 addresses and thus
|
|
|
|
|
* @plat_addr is essentially the same address as @know_addr (w.r.t.
|
|
|
|
|
* its identity, not its other attributes).
|
|
|
|
|
* However, we cannot modify an existing addresses' plen without
|
platform: re-configure one address at a time in nm_platform_ip_address_sync()
Try to do one change at a time when reconfiguring addresses, to not
remove several/all addresses at once.
For IP addresses, kernel cares about the order in which they were added.
This mostly affects source address selection, and the "secondary" flag
for IPv4 addresses. The order is thus related to the priority of an
address.
There is no direct kernel API to change the order. Instead, we have to
add them in the correct order. During a sync, if an address already
exists in the wrong order, we need to remove it, and re-add it.
Btw, with IPv4 addresses added first via netlink are the primary
address, while with IPv6 it's reverse.
Previously, we would first iterate over all addresses and remove those
that had a conflicting order. This means, that we would potentially
remove all addresses for a short while, before readding them. That seems
problematic.
Instead, first track all addresses that are in the wrong order. And in
the step when we add/update the address, remove it. We now only remove
and address shortly before re-adding it. This way the time for which the
address on the interface is missing is shorter. More importantly, we will
never remove all addresses at the same time.
(cherry picked from commit a6fd6416345ccb397ae174dc39d66e9e7bfa7fe6)
2022-04-27 16:25:01 +02:00
|
|
|
* removing and readding it. Thus, we need to delete plat_addr.
|
|
|
|
|
*
|
|
|
|
|
* We don't just add this address to @plat_addrs_to_delete, because
|
|
|
|
|
* it's too different. Instead, delete and re-add below. */
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
nm_platform_ip_address_delete(self,
|
|
|
|
|
AF_INET6,
|
|
|
|
|
ifindex,
|
|
|
|
|
NMP_OBJECT_CAST_IP6_ADDRESS(plat_obj));
|
|
|
|
|
/* Mark address as handled. */
|
|
|
|
|
nm_clear_pointer(&plat_addresses->pdata[i_plat], nmp_object_unref);
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
2017-12-15 09:46:11 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* Next, we must preserve the priority of the routes. That is, source address
|
2020-09-28 14:50:01 +02:00
|
|
|
* selection will choose addresses in the order as they are reported by kernel.
|
|
|
|
|
* Note that the order in @plat_addresses of the remaining matches is highest
|
|
|
|
|
* priority first.
|
|
|
|
|
* We need to compare this to the order of addresses with same scope in
|
|
|
|
|
* @known_addresses (which has lowest priority first).
|
|
|
|
|
*
|
|
|
|
|
* If we find a first discrepancy, we need to delete all remaining addresses
|
platform: fix address order in nm_platform_ip_address_sync()
In the past, nm_platform_ip_address_sync() only had the @known_addresses
argument. We would figure out which addresses to delete and which to preserve,
based on what addresses were known. That means, @known_addresses must have contained
all the addresses we wanted to preserve, even the external ones. That approach
was inherently racy.
Instead, nowadays we have the addresses we want to configure (@known_addresses)
and the addresses we want to delete (@prune_addresses). This started to change in
commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
layer 3 configuration') actually changed to pass separate @prune_addresses argument.
However, the order of IP addresses matters and there is no sensible kernel API
to configure the order (short of adding them in the right order), we still need
to look at all the addresses, check their order, and possibly delete some.
That is, we need to handle addresses we want to delete (@prune_addresses)
but still look at all addresses in platform (@plat_addresses) to check
their order.
Now, first handle @prune_addresses. That's simple. These are just the
addresses we want to delete. Second, get the list of all addresses in
platform (@plat_addresses) and check the order.
Note that if there is an external address that interferes with our
desired order, we will leave it untouched. Thus, such external addresses
might prevent us from getting the order as desired. But that's just
how it is. Don't add addresses outside of NetworkManager to avoid that.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
2022-03-28 21:13:09 +02:00
|
|
|
* for same scope from that point on, because below we must re-add all the
|
2020-09-28 14:50:01 +02:00
|
|
|
* addresses in the right order to get their priority right. */
|
2020-09-28 16:03:33 +02:00
|
|
|
cur_scope = IP6_ADDR_SCOPE_LOOPBACK;
|
|
|
|
|
delete_remaining_addrs = FALSE;
|
|
|
|
|
i_plat = plat_addresses->len;
|
core: change order/priority of static IPv6 addresses relative to autoconf6/DHCPv6
The order of addresses can matter for source address selection.
This is described in RFC 6724 section 5, but if the rules don't
determine a clear winner, the order matters.
Change the relative order of IPv6 addresses. Previously, we would prefer
autoconf6, over DHCPv6, over manual addresses. Now that got reverted
to make more sense and be consistent with IPv4.
Also, if we had multiple autoconf6 addresses (received at different
moments in time), then previously a newly received address would be
added with highest priority. Now, the older address will be preferred
and that order will be enforced (this can be a problem, see (*) below).
For IPv4, it's all simple and sensible. When we add addresses in kernel
via netlink, the first address (of a subnet) becomes the primary.
Note that we only control the order of addresses of the same subnet.
The addresses in ipv4.addresses" are sorted with primary address first.
In the same way is the order for addresses in NML3ConfigData and for
@known_addresses in nm_platform_ip_address_sync(), all primary-first.
Also, manual addresses are sorted with higher priority compared to DHCPv4
addresses (at least since NetworkManager 1.36). That means the way how we
merge NML3ConfigData makes sense (nm_l3_config_data_merge()) because we first
merge the static configuration, then the DHCPv4 configuration, where we just
append the lower priority DHCPv4 addresses.
For IPv6, the address priority is messed up. On netlink/kernel, the last added
address becomes the preferred one (we thus need to add them in the order of
lowest priority first). Consequently and historically, the IPv6 addresses in
@known_addresses parameter to nm_platform_ip_address_sync() were
lowest priority first. And so they were tracked in NML3ConfigData
and in the profile ("ipv6.addresses"). That is confusing.
Also, we usually want to merge NML3ConfigData with different priorities
(e.g. static configuration from the profile before autoconf6/DHCPv6),
as we do with IPv4. However, since internally IPv6 addresses are tracked in
reverse order, it means later NML3ConfigData would be appended and get effectively
a higher priority. That means, autoconf6 addresses were preferred over DHCPv6 and
over manual "ipv6.addresses", respectively. That seems undesirable and inconsistent
with IPv4. Change that. This is a change in behavior.
Note that changing the order of addresses means to remove and re-add
them in the right (inverse) order, with lease important first. This
means, when we add a new address with lower priority, we need to remove
all higher priority addresses temporarily, before readding them. That
is a problem(*).
Note that in the profile, "ipv6.addresses" is still tracked in reverse
order. This did not change, but might change later.
(cherry picked from commit 4a548423b91ebaf590700926709bb95a32a21e99)
2022-03-31 11:46:56 +02:00
|
|
|
i_know = nm_g_ptr_array_len(known_addresses);
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
while (i_plat > 0) {
|
platform: re-configure one address at a time in nm_platform_ip_address_sync()
Try to do one change at a time when reconfiguring addresses, to not
remove several/all addresses at once.
For IP addresses, kernel cares about the order in which they were added.
This mostly affects source address selection, and the "secondary" flag
for IPv4 addresses. The order is thus related to the priority of an
address.
There is no direct kernel API to change the order. Instead, we have to
add them in the correct order. During a sync, if an address already
exists in the wrong order, we need to remove it, and re-add it.
Btw, with IPv4 addresses added first via netlink are the primary
address, while with IPv6 it's reverse.
Previously, we would first iterate over all addresses and remove those
that had a conflicting order. This means, that we would potentially
remove all addresses for a short while, before readding them. That seems
problematic.
Instead, first track all addresses that are in the wrong order. And in
the step when we add/update the address, remove it. We now only remove
and address shortly before re-adding it. This way the time for which the
address on the interface is missing is shorter. More importantly, we will
never remove all addresses at the same time.
(cherry picked from commit a6fd6416345ccb397ae174dc39d66e9e7bfa7fe6)
2022-04-27 16:25:01 +02:00
|
|
|
const NMPObject *plat_obj = plat_addresses->pdata[--i_plat];
|
|
|
|
|
const NMPlatformIP6Address *plat_addr = NMP_OBJECT_CAST_IP6_ADDRESS(plat_obj);
|
|
|
|
|
IP6AddrScope plat_scope;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
|
|
|
|
if (!plat_addr)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
plat_scope = ip6_address_scope(plat_addr);
|
|
|
|
|
if (cur_scope != plat_scope) {
|
|
|
|
|
nm_assert(cur_scope < plat_scope);
|
|
|
|
|
delete_remaining_addrs = FALSE;
|
|
|
|
|
cur_scope = plat_scope;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!delete_remaining_addrs) {
|
core: change order/priority of static IPv6 addresses relative to autoconf6/DHCPv6
The order of addresses can matter for source address selection.
This is described in RFC 6724 section 5, but if the rules don't
determine a clear winner, the order matters.
Change the relative order of IPv6 addresses. Previously, we would prefer
autoconf6, over DHCPv6, over manual addresses. Now that got reverted
to make more sense and be consistent with IPv4.
Also, if we had multiple autoconf6 addresses (received at different
moments in time), then previously a newly received address would be
added with highest priority. Now, the older address will be preferred
and that order will be enforced (this can be a problem, see (*) below).
For IPv4, it's all simple and sensible. When we add addresses in kernel
via netlink, the first address (of a subnet) becomes the primary.
Note that we only control the order of addresses of the same subnet.
The addresses in ipv4.addresses" are sorted with primary address first.
In the same way is the order for addresses in NML3ConfigData and for
@known_addresses in nm_platform_ip_address_sync(), all primary-first.
Also, manual addresses are sorted with higher priority compared to DHCPv4
addresses (at least since NetworkManager 1.36). That means the way how we
merge NML3ConfigData makes sense (nm_l3_config_data_merge()) because we first
merge the static configuration, then the DHCPv4 configuration, where we just
append the lower priority DHCPv4 addresses.
For IPv6, the address priority is messed up. On netlink/kernel, the last added
address becomes the preferred one (we thus need to add them in the order of
lowest priority first). Consequently and historically, the IPv6 addresses in
@known_addresses parameter to nm_platform_ip_address_sync() were
lowest priority first. And so they were tracked in NML3ConfigData
and in the profile ("ipv6.addresses"). That is confusing.
Also, we usually want to merge NML3ConfigData with different priorities
(e.g. static configuration from the profile before autoconf6/DHCPv6),
as we do with IPv4. However, since internally IPv6 addresses are tracked in
reverse order, it means later NML3ConfigData would be appended and get effectively
a higher priority. That means, autoconf6 addresses were preferred over DHCPv6 and
over manual "ipv6.addresses", respectively. That seems undesirable and inconsistent
with IPv4. Change that. This is a change in behavior.
Note that changing the order of addresses means to remove and re-add
them in the right (inverse) order, with lease important first. This
means, when we add a new address with lower priority, we need to remove
all higher priority addresses temporarily, before readding them. That
is a problem(*).
Note that in the profile, "ipv6.addresses" is still tracked in reverse
order. This did not change, but might change later.
(cherry picked from commit 4a548423b91ebaf590700926709bb95a32a21e99)
2022-03-31 11:46:56 +02:00
|
|
|
while (i_know > 0) {
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPlatformIP6Address *know_addr =
|
core: change order/priority of static IPv6 addresses relative to autoconf6/DHCPv6
The order of addresses can matter for source address selection.
This is described in RFC 6724 section 5, but if the rules don't
determine a clear winner, the order matters.
Change the relative order of IPv6 addresses. Previously, we would prefer
autoconf6, over DHCPv6, over manual addresses. Now that got reverted
to make more sense and be consistent with IPv4.
Also, if we had multiple autoconf6 addresses (received at different
moments in time), then previously a newly received address would be
added with highest priority. Now, the older address will be preferred
and that order will be enforced (this can be a problem, see (*) below).
For IPv4, it's all simple and sensible. When we add addresses in kernel
via netlink, the first address (of a subnet) becomes the primary.
Note that we only control the order of addresses of the same subnet.
The addresses in ipv4.addresses" are sorted with primary address first.
In the same way is the order for addresses in NML3ConfigData and for
@known_addresses in nm_platform_ip_address_sync(), all primary-first.
Also, manual addresses are sorted with higher priority compared to DHCPv4
addresses (at least since NetworkManager 1.36). That means the way how we
merge NML3ConfigData makes sense (nm_l3_config_data_merge()) because we first
merge the static configuration, then the DHCPv4 configuration, where we just
append the lower priority DHCPv4 addresses.
For IPv6, the address priority is messed up. On netlink/kernel, the last added
address becomes the preferred one (we thus need to add them in the order of
lowest priority first). Consequently and historically, the IPv6 addresses in
@known_addresses parameter to nm_platform_ip_address_sync() were
lowest priority first. And so they were tracked in NML3ConfigData
and in the profile ("ipv6.addresses"). That is confusing.
Also, we usually want to merge NML3ConfigData with different priorities
(e.g. static configuration from the profile before autoconf6/DHCPv6),
as we do with IPv4. However, since internally IPv6 addresses are tracked in
reverse order, it means later NML3ConfigData would be appended and get effectively
a higher priority. That means, autoconf6 addresses were preferred over DHCPv6 and
over manual "ipv6.addresses", respectively. That seems undesirable and inconsistent
with IPv4. Change that. This is a change in behavior.
Note that changing the order of addresses means to remove and re-add
them in the right (inverse) order, with lease important first. This
means, when we add a new address with lower priority, we need to remove
all higher priority addresses temporarily, before readding them. That
is a problem(*).
Note that in the profile, "ipv6.addresses" is still tracked in reverse
order. This did not change, but might change later.
(cherry picked from commit 4a548423b91ebaf590700926709bb95a32a21e99)
2022-03-31 11:46:56 +02:00
|
|
|
NMP_OBJECT_CAST_IP6_ADDRESS(known_addresses->pdata[--i_know]);
|
2020-09-28 16:03:33 +02:00
|
|
|
IP6AddrScope know_scope;
|
|
|
|
|
|
|
|
|
|
if (!know_addr)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
know_scope = ip6_address_scope(know_addr);
|
|
|
|
|
if (know_scope < plat_scope)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (IN6_ARE_ADDR_EQUAL(&plat_addr->address, &know_addr->address)) {
|
|
|
|
|
/* we have a match. Mark address as handled. */
|
|
|
|
|
goto next_plat;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-02 13:10:24 +02:00
|
|
|
/* "plat_address" has no match. "delete_remaining_addrs" will be set to TRUE and we will
|
|
|
|
|
* delete all the remaining addresses with "cur_scope". */
|
2020-09-28 16:03:33 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2022-05-02 13:10:24 +02:00
|
|
|
delete_remaining_addrs = TRUE;
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
2020-07-29 12:46:21 +02:00
|
|
|
|
platform: re-configure one address at a time in nm_platform_ip_address_sync()
Try to do one change at a time when reconfiguring addresses, to not
remove several/all addresses at once.
For IP addresses, kernel cares about the order in which they were added.
This mostly affects source address selection, and the "secondary" flag
for IPv4 addresses. The order is thus related to the priority of an
address.
There is no direct kernel API to change the order. Instead, we have to
add them in the correct order. During a sync, if an address already
exists in the wrong order, we need to remove it, and re-add it.
Btw, with IPv4 addresses added first via netlink are the primary
address, while with IPv6 it's reverse.
Previously, we would first iterate over all addresses and remove those
that had a conflicting order. This means, that we would potentially
remove all addresses for a short while, before readding them. That seems
problematic.
Instead, first track all addresses that are in the wrong order. And in
the step when we add/update the address, remove it. We now only remove
and address shortly before re-adding it. This way the time for which the
address on the interface is missing is shorter. More importantly, we will
never remove all addresses at the same time.
(cherry picked from commit a6fd6416345ccb397ae174dc39d66e9e7bfa7fe6)
2022-04-27 16:25:01 +02:00
|
|
|
g_hash_table_add(_plat_addrs_to_delete_ensure(&plat_addrs_to_delete),
|
|
|
|
|
(gpointer) nmp_object_ref(plat_obj));
|
2020-09-28 16:03:33 +02:00
|
|
|
next_plat:;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-04-16 14:24:46 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!known_addresses)
|
|
|
|
|
return TRUE;
|
2013-04-16 14:24:46 +02:00
|
|
|
|
2022-03-29 16:44:29 +02:00
|
|
|
success = TRUE;
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* Add missing addresses. New addresses are added by kernel with top
|
2020-09-28 14:50:01 +02:00
|
|
|
* priority.
|
|
|
|
|
*/
|
core: change order/priority of static IPv6 addresses relative to autoconf6/DHCPv6
The order of addresses can matter for source address selection.
This is described in RFC 6724 section 5, but if the rules don't
determine a clear winner, the order matters.
Change the relative order of IPv6 addresses. Previously, we would prefer
autoconf6, over DHCPv6, over manual addresses. Now that got reverted
to make more sense and be consistent with IPv4.
Also, if we had multiple autoconf6 addresses (received at different
moments in time), then previously a newly received address would be
added with highest priority. Now, the older address will be preferred
and that order will be enforced (this can be a problem, see (*) below).
For IPv4, it's all simple and sensible. When we add addresses in kernel
via netlink, the first address (of a subnet) becomes the primary.
Note that we only control the order of addresses of the same subnet.
The addresses in ipv4.addresses" are sorted with primary address first.
In the same way is the order for addresses in NML3ConfigData and for
@known_addresses in nm_platform_ip_address_sync(), all primary-first.
Also, manual addresses are sorted with higher priority compared to DHCPv4
addresses (at least since NetworkManager 1.36). That means the way how we
merge NML3ConfigData makes sense (nm_l3_config_data_merge()) because we first
merge the static configuration, then the DHCPv4 configuration, where we just
append the lower priority DHCPv4 addresses.
For IPv6, the address priority is messed up. On netlink/kernel, the last added
address becomes the preferred one (we thus need to add them in the order of
lowest priority first). Consequently and historically, the IPv6 addresses in
@known_addresses parameter to nm_platform_ip_address_sync() were
lowest priority first. And so they were tracked in NML3ConfigData
and in the profile ("ipv6.addresses"). That is confusing.
Also, we usually want to merge NML3ConfigData with different priorities
(e.g. static configuration from the profile before autoconf6/DHCPv6),
as we do with IPv4. However, since internally IPv6 addresses are tracked in
reverse order, it means later NML3ConfigData would be appended and get effectively
a higher priority. That means, autoconf6 addresses were preferred over DHCPv6 and
over manual "ipv6.addresses", respectively. That seems undesirable and inconsistent
with IPv4. Change that. This is a change in behavior.
Note that changing the order of addresses means to remove and re-add
them in the right (inverse) order, with lease important first. This
means, when we add a new address with lower priority, we need to remove
all higher priority addresses temporarily, before readding them. That
is a problem(*).
Note that in the profile, "ipv6.addresses" is still tracked in reverse
order. This did not change, but might change later.
(cherry picked from commit 4a548423b91ebaf590700926709bb95a32a21e99)
2022-03-31 11:46:56 +02:00
|
|
|
for (i = 0; i < known_addresses->len; i++) {
|
2022-03-29 17:23:52 +02:00
|
|
|
const NMPObject *plat_obj;
|
2022-03-29 17:00:56 +02:00
|
|
|
const NMPObject *known_obj;
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMPlatformIPXAddress *known_address;
|
|
|
|
|
guint32 lifetime;
|
|
|
|
|
guint32 preferred;
|
|
|
|
|
|
core: change order/priority of static IPv6 addresses relative to autoconf6/DHCPv6
The order of addresses can matter for source address selection.
This is described in RFC 6724 section 5, but if the rules don't
determine a clear winner, the order matters.
Change the relative order of IPv6 addresses. Previously, we would prefer
autoconf6, over DHCPv6, over manual addresses. Now that got reverted
to make more sense and be consistent with IPv4.
Also, if we had multiple autoconf6 addresses (received at different
moments in time), then previously a newly received address would be
added with highest priority. Now, the older address will be preferred
and that order will be enforced (this can be a problem, see (*) below).
For IPv4, it's all simple and sensible. When we add addresses in kernel
via netlink, the first address (of a subnet) becomes the primary.
Note that we only control the order of addresses of the same subnet.
The addresses in ipv4.addresses" are sorted with primary address first.
In the same way is the order for addresses in NML3ConfigData and for
@known_addresses in nm_platform_ip_address_sync(), all primary-first.
Also, manual addresses are sorted with higher priority compared to DHCPv4
addresses (at least since NetworkManager 1.36). That means the way how we
merge NML3ConfigData makes sense (nm_l3_config_data_merge()) because we first
merge the static configuration, then the DHCPv4 configuration, where we just
append the lower priority DHCPv4 addresses.
For IPv6, the address priority is messed up. On netlink/kernel, the last added
address becomes the preferred one (we thus need to add them in the order of
lowest priority first). Consequently and historically, the IPv6 addresses in
@known_addresses parameter to nm_platform_ip_address_sync() were
lowest priority first. And so they were tracked in NML3ConfigData
and in the profile ("ipv6.addresses"). That is confusing.
Also, we usually want to merge NML3ConfigData with different priorities
(e.g. static configuration from the profile before autoconf6/DHCPv6),
as we do with IPv4. However, since internally IPv6 addresses are tracked in
reverse order, it means later NML3ConfigData would be appended and get effectively
a higher priority. That means, autoconf6 addresses were preferred over DHCPv6 and
over manual "ipv6.addresses", respectively. That seems undesirable and inconsistent
with IPv4. Change that. This is a change in behavior.
Note that changing the order of addresses means to remove and re-add
them in the right (inverse) order, with lease important first. This
means, when we add a new address with lower priority, we need to remove
all higher priority addresses temporarily, before readding them. That
is a problem(*).
Note that in the profile, "ipv6.addresses" is still tracked in reverse
order. This did not change, but might change later.
(cherry picked from commit 4a548423b91ebaf590700926709bb95a32a21e99)
2022-03-31 11:46:56 +02:00
|
|
|
/* IPv4 addresses we need to add in the order most important first.
|
|
|
|
|
* IPv6 addresses we need to add in the reverse order with least
|
|
|
|
|
* important first. Kernel will interpret the last address as most
|
|
|
|
|
* important.
|
|
|
|
|
*
|
|
|
|
|
* @known_addresses is always in the order most-important-first. */
|
|
|
|
|
i_know = IS_IPv4 ? i : (known_addresses->len - i - 1u);
|
|
|
|
|
|
2022-03-29 17:00:56 +02:00
|
|
|
known_obj = known_addresses->pdata[i_know];
|
|
|
|
|
if (!known_obj)
|
2020-09-28 16:03:33 +02:00
|
|
|
continue;
|
|
|
|
|
|
2022-03-29 17:00:56 +02:00
|
|
|
nm_assert(NMP_OBJECT_GET_TYPE(known_obj) == NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2022-03-29 17:00:56 +02:00
|
|
|
known_address = NMP_OBJECT_CAST_IPX_ADDRESS(known_obj);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-03-04 10:05:18 +01:00
|
|
|
lifetime = nmp_utils_lifetime_get(known_address->ax.timestamp,
|
|
|
|
|
known_address->ax.lifetime,
|
|
|
|
|
known_address->ax.preferred,
|
platform: make "now" timestamp an in/out parameter to nmp_utils_lifetime_get()
nmp_utils_lifetime_get() calculates the lifetime of addresses,
and it bases the result on a "now" timestamp.
If you have two addresses and calculate their expiry, then we want to
base it on top of the same "now" timestamp, meaning, we should
only call nm_utils_get_monotonic_timestamp_sec() once. This is also a
performance optimization. But much more importantly, when we make a
comparison at a certain moment, we need that all sides have the same
understanding of the current timestamp.
But nmp_utils_lifetime_get() does not always require the now timestamp.
And the caller doesn't know, whether it will need it (short of knowing
how nmp_utils_lifetime_get() is implemented). So, make the now parameter
an in/out argument. If we pass in an already valid now timestamp, use
that. Otherwise, fetch the current time and also return it.
(cherry picked from commit deb37401e95d4ea0025e406424c8da7c10bc9712)
2022-03-29 22:45:56 +02:00
|
|
|
&now,
|
2021-03-04 10:05:18 +01:00
|
|
|
&preferred);
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_assert(lifetime > 0);
|
|
|
|
|
|
2022-03-29 17:23:52 +02:00
|
|
|
plat_obj = nm_platform_ip_address_get(self, addr_family, ifindex, known_address);
|
platform: re-configure one address at a time in nm_platform_ip_address_sync()
Try to do one change at a time when reconfiguring addresses, to not
remove several/all addresses at once.
For IP addresses, kernel cares about the order in which they were added.
This mostly affects source address selection, and the "secondary" flag
for IPv4 addresses. The order is thus related to the priority of an
address.
There is no direct kernel API to change the order. Instead, we have to
add them in the correct order. During a sync, if an address already
exists in the wrong order, we need to remove it, and re-add it.
Btw, with IPv4 addresses added first via netlink are the primary
address, while with IPv6 it's reverse.
Previously, we would first iterate over all addresses and remove those
that had a conflicting order. This means, that we would potentially
remove all addresses for a short while, before readding them. That seems
problematic.
Instead, first track all addresses that are in the wrong order. And in
the step when we add/update the address, remove it. We now only remove
and address shortly before re-adding it. This way the time for which the
address on the interface is missing is shorter. More importantly, we will
never remove all addresses at the same time.
(cherry picked from commit a6fd6416345ccb397ae174dc39d66e9e7bfa7fe6)
2022-04-27 16:25:01 +02:00
|
|
|
|
|
|
|
|
if (plat_obj && nm_g_hash_table_contains(plat_addrs_to_delete, plat_obj)) {
|
|
|
|
|
/* This address exists, but it had the wrong priority earlier. We
|
|
|
|
|
* cannot just update it, we need to remove it first. */
|
|
|
|
|
nm_platform_ip_address_delete(self,
|
|
|
|
|
addr_family,
|
|
|
|
|
ifindex,
|
|
|
|
|
NMP_OBJECT_CAST_IP_ADDRESS(plat_obj));
|
|
|
|
|
plat_obj = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-29 17:23:52 +02:00
|
|
|
if (plat_obj
|
|
|
|
|
&& nm_platform_vtable_address.vx[IS_IPv4].address_cmp(
|
|
|
|
|
known_address,
|
|
|
|
|
NMP_OBJECT_CAST_IPX_ADDRESS(plat_obj),
|
|
|
|
|
NM_PLATFORM_IP_ADDRESS_CMP_TYPE_SEMANTICALLY)
|
|
|
|
|
== 0) {
|
2022-03-30 09:23:54 +02:00
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
2022-03-29 17:23:52 +02:00
|
|
|
|
|
|
|
|
/* The object is already added. Skip update. */
|
2022-04-11 11:47:41 +02:00
|
|
|
_LOG3T(
|
2022-03-29 17:23:52 +02:00
|
|
|
"address: skip updating IPv%c address: %s",
|
|
|
|
|
nm_utils_addr_family_to_char(addr_family),
|
|
|
|
|
nmp_object_to_string(known_obj, NMP_OBJECT_TO_STRING_PUBLIC, sbuf, sizeof(sbuf)));
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (IS_IPv4) {
|
|
|
|
|
if (!nm_platform_ip4_address_add(
|
|
|
|
|
self,
|
|
|
|
|
ifindex,
|
|
|
|
|
known_address->a4.address,
|
|
|
|
|
known_address->a4.plen,
|
|
|
|
|
known_address->a4.peer_address,
|
|
|
|
|
nm_platform_ip4_broadcast_address_from_addr(&known_address->a4),
|
|
|
|
|
lifetime,
|
|
|
|
|
preferred,
|
2022-09-08 09:28:28 +02:00
|
|
|
NM_FLAGS_HAS(flags, NMP_IP_ADDRESS_SYNC_FLAGS_WITH_NOPREFIXROUTE)
|
|
|
|
|
? IFA_F_NOPREFIXROUTE
|
|
|
|
|
: 0,
|
2023-02-17 12:07:05 +01:00
|
|
|
known_address->a4.label,
|
|
|
|
|
NULL))
|
2022-03-29 16:44:29 +02:00
|
|
|
success = FALSE;
|
2020-09-28 16:03:33 +02:00
|
|
|
} else {
|
2022-09-08 09:28:28 +02:00
|
|
|
if (!nm_platform_ip6_address_add(
|
|
|
|
|
self,
|
|
|
|
|
ifindex,
|
|
|
|
|
known_address->a6.address,
|
|
|
|
|
known_address->a6.plen,
|
|
|
|
|
known_address->a6.peer_address,
|
|
|
|
|
lifetime,
|
|
|
|
|
preferred,
|
|
|
|
|
(NM_FLAGS_HAS(flags, NMP_IP_ADDRESS_SYNC_FLAGS_WITH_NOPREFIXROUTE)
|
|
|
|
|
? IFA_F_NOPREFIXROUTE
|
|
|
|
|
: 0)
|
2023-02-17 12:07:05 +01:00
|
|
|
| known_address->a6.n_ifa_flags,
|
|
|
|
|
NULL))
|
2022-03-29 16:44:29 +02:00
|
|
|
success = FALSE;
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-29 16:44:29 +02:00
|
|
|
return success;
|
2013-04-16 14:24:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_ip_address_flush(NMPlatform *self, int addr_family, int ifindex)
|
2013-04-16 14:24:46 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
gboolean success = TRUE;
|
l3cfg: fix clearing IPv6 temporary addresses to avoid stale addresses
IPv6 temporary addresses are configured by kernel, with the
"ipv6.ip6-privacy" setting ("use_tempaddr" sysctl) and the
IFA_F_MANAGETEMPADDR flag.
As such, the idea was that during reapply we would not remove them.
However, that is wrong.
The only case when we want to keep those addresses, is if during reapply
we are going to configure the same primary address (with mngtmpaddr
flag) again. Otherwise, theses addresses must always go away.
This is quite serious. This not only affects Reapply. Also during disconnect
we clear IP configuration via l3cfg.
Have an ethernet profile active with "ipv6.ip6-privacy". Unplug
the cable, the device disconnects but the temporary IPv6 address is not
cleared. As such, nm_device_generate_connection() will now generate
an external profile (with "ipv6.method=disabled" and no manual IP addresses).
The result is, that the device cannot properly autoconnect again,
once you replug the cable.
This is serious for disconnect. But I could not actually reproduce the
problem using reapply. That is, because during reapply we usually
toggle ipv6_disable sysctl, which drops all IPv6 addresses. I still
went through the effort of trying to preserve addresses that we still
want to have, because I am not sure whether there are cases where we
don't toggle ipv6_disable. Also, doing ipv6_disable during reapply is
bad anyway, and we might want to avoid that in the future.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 518f6124c6476e5f91b30b7d5583f494e84fd936)
2022-05-05 10:22:20 +02:00
|
|
|
int IS_IPv4;
|
2017-08-14 18:13:10 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.
While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.
With this change, NMPlatform instances can be used individually, not
only as a singleton instance.
Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.
Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.
Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.
This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-18 12:36:09 +02:00
|
|
|
|
l3cfg: fix clearing IPv6 temporary addresses to avoid stale addresses
IPv6 temporary addresses are configured by kernel, with the
"ipv6.ip6-privacy" setting ("use_tempaddr" sysctl) and the
IFA_F_MANAGETEMPADDR flag.
As such, the idea was that during reapply we would not remove them.
However, that is wrong.
The only case when we want to keep those addresses, is if during reapply
we are going to configure the same primary address (with mngtmpaddr
flag) again. Otherwise, theses addresses must always go away.
This is quite serious. This not only affects Reapply. Also during disconnect
we clear IP configuration via l3cfg.
Have an ethernet profile active with "ipv6.ip6-privacy". Unplug
the cable, the device disconnects but the temporary IPv6 address is not
cleared. As such, nm_device_generate_connection() will now generate
an external profile (with "ipv6.method=disabled" and no manual IP addresses).
The result is, that the device cannot properly autoconnect again,
once you replug the cable.
This is serious for disconnect. But I could not actually reproduce the
problem using reapply. That is, because during reapply we usually
toggle ipv6_disable sysctl, which drops all IPv6 addresses. I still
went through the effort of trying to preserve addresses that we still
want to have, because I am not sure whether there are cases where we
don't toggle ipv6_disable. Also, doing ipv6_disable during reapply is
bad anyway, and we might want to avoid that in the future.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 518f6124c6476e5f91b30b7d5583f494e84fd936)
2022-05-05 10:22:20 +02:00
|
|
|
nm_assert_addr_family_or_unspec(addr_family);
|
2017-08-14 18:13:10 +02:00
|
|
|
|
l3cfg: fix clearing IPv6 temporary addresses to avoid stale addresses
IPv6 temporary addresses are configured by kernel, with the
"ipv6.ip6-privacy" setting ("use_tempaddr" sysctl) and the
IFA_F_MANAGETEMPADDR flag.
As such, the idea was that during reapply we would not remove them.
However, that is wrong.
The only case when we want to keep those addresses, is if during reapply
we are going to configure the same primary address (with mngtmpaddr
flag) again. Otherwise, theses addresses must always go away.
This is quite serious. This not only affects Reapply. Also during disconnect
we clear IP configuration via l3cfg.
Have an ethernet profile active with "ipv6.ip6-privacy". Unplug
the cable, the device disconnects but the temporary IPv6 address is not
cleared. As such, nm_device_generate_connection() will now generate
an external profile (with "ipv6.method=disabled" and no manual IP addresses).
The result is, that the device cannot properly autoconnect again,
once you replug the cable.
This is serious for disconnect. But I could not actually reproduce the
problem using reapply. That is, because during reapply we usually
toggle ipv6_disable sysctl, which drops all IPv6 addresses. I still
went through the effort of trying to preserve addresses that we still
want to have, because I am not sure whether there are cases where we
don't toggle ipv6_disable. Also, doing ipv6_disable during reapply is
bad anyway, and we might want to avoid that in the future.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 518f6124c6476e5f91b30b7d5583f494e84fd936)
2022-05-05 10:22:20 +02:00
|
|
|
for (IS_IPv4 = 1; IS_IPv4 >= 0; IS_IPv4--) {
|
|
|
|
|
gs_unref_ptrarray GPtrArray *addresses_prune = NULL;
|
|
|
|
|
const int addr_family2 = IS_IPv4 ? AF_INET : AF_INET6;
|
|
|
|
|
|
|
|
|
|
if (!NM_IN_SET(addr_family, AF_UNSPEC, addr_family2))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
addresses_prune =
|
|
|
|
|
nm_platform_ip_address_get_prune_list(self, addr_family2, ifindex, NULL, 0);
|
|
|
|
|
|
2022-09-08 09:28:28 +02:00
|
|
|
if (!nm_platform_ip_address_sync(self,
|
|
|
|
|
addr_family2,
|
|
|
|
|
ifindex,
|
|
|
|
|
NULL,
|
|
|
|
|
addresses_prune,
|
|
|
|
|
NMP_IP_ADDRESS_SYNC_FLAGS_NONE))
|
l3cfg: fix clearing IPv6 temporary addresses to avoid stale addresses
IPv6 temporary addresses are configured by kernel, with the
"ipv6.ip6-privacy" setting ("use_tempaddr" sysctl) and the
IFA_F_MANAGETEMPADDR flag.
As such, the idea was that during reapply we would not remove them.
However, that is wrong.
The only case when we want to keep those addresses, is if during reapply
we are going to configure the same primary address (with mngtmpaddr
flag) again. Otherwise, theses addresses must always go away.
This is quite serious. This not only affects Reapply. Also during disconnect
we clear IP configuration via l3cfg.
Have an ethernet profile active with "ipv6.ip6-privacy". Unplug
the cable, the device disconnects but the temporary IPv6 address is not
cleared. As such, nm_device_generate_connection() will now generate
an external profile (with "ipv6.method=disabled" and no manual IP addresses).
The result is, that the device cannot properly autoconnect again,
once you replug the cable.
This is serious for disconnect. But I could not actually reproduce the
problem using reapply. That is, because during reapply we usually
toggle ipv6_disable sysctl, which drops all IPv6 addresses. I still
went through the effort of trying to preserve addresses that we still
want to have, because I am not sure whether there are cases where we
don't toggle ipv6_disable. Also, doing ipv6_disable during reapply is
bad anyway, and we might want to avoid that in the future.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 518f6124c6476e5f91b30b7d5583f494e84fd936)
2022-05-05 10:22:20 +02:00
|
|
|
success = FALSE;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
return success;
|
2013-04-16 14:24:46 +02:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2013-04-16 14:24:46 +02:00
|
|
|
|
l3cfg: fix clearing IPv6 temporary addresses to avoid stale addresses
IPv6 temporary addresses are configured by kernel, with the
"ipv6.ip6-privacy" setting ("use_tempaddr" sysctl) and the
IFA_F_MANAGETEMPADDR flag.
As such, the idea was that during reapply we would not remove them.
However, that is wrong.
The only case when we want to keep those addresses, is if during reapply
we are going to configure the same primary address (with mngtmpaddr
flag) again. Otherwise, theses addresses must always go away.
This is quite serious. This not only affects Reapply. Also during disconnect
we clear IP configuration via l3cfg.
Have an ethernet profile active with "ipv6.ip6-privacy". Unplug
the cable, the device disconnects but the temporary IPv6 address is not
cleared. As such, nm_device_generate_connection() will now generate
an external profile (with "ipv6.method=disabled" and no manual IP addresses).
The result is, that the device cannot properly autoconnect again,
once you replug the cable.
This is serious for disconnect. But I could not actually reproduce the
problem using reapply. That is, because during reapply we usually
toggle ipv6_disable sysctl, which drops all IPv6 addresses. I still
went through the effort of trying to preserve addresses that we still
want to have, because I am not sure whether there are cases where we
don't toggle ipv6_disable. Also, doing ipv6_disable during reapply is
bad anyway, and we might want to avoid that in the future.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 518f6124c6476e5f91b30b7d5583f494e84fd936)
2022-05-05 10:22:20 +02:00
|
|
|
static guint
|
|
|
|
|
_ipv6_temporary_addr_prefixes_keep_hash(gconstpointer ptr)
|
2020-07-29 13:49:31 +02:00
|
|
|
{
|
l3cfg: fix clearing IPv6 temporary addresses to avoid stale addresses
IPv6 temporary addresses are configured by kernel, with the
"ipv6.ip6-privacy" setting ("use_tempaddr" sysctl) and the
IFA_F_MANAGETEMPADDR flag.
As such, the idea was that during reapply we would not remove them.
However, that is wrong.
The only case when we want to keep those addresses, is if during reapply
we are going to configure the same primary address (with mngtmpaddr
flag) again. Otherwise, theses addresses must always go away.
This is quite serious. This not only affects Reapply. Also during disconnect
we clear IP configuration via l3cfg.
Have an ethernet profile active with "ipv6.ip6-privacy". Unplug
the cable, the device disconnects but the temporary IPv6 address is not
cleared. As such, nm_device_generate_connection() will now generate
an external profile (with "ipv6.method=disabled" and no manual IP addresses).
The result is, that the device cannot properly autoconnect again,
once you replug the cable.
This is serious for disconnect. But I could not actually reproduce the
problem using reapply. That is, because during reapply we usually
toggle ipv6_disable sysctl, which drops all IPv6 addresses. I still
went through the effort of trying to preserve addresses that we still
want to have, because I am not sure whether there are cases where we
don't toggle ipv6_disable. Also, doing ipv6_disable during reapply is
bad anyway, and we might want to avoid that in the future.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 518f6124c6476e5f91b30b7d5583f494e84fd936)
2022-05-05 10:22:20 +02:00
|
|
|
return nm_hash_mem(1161670183u, ptr, 8);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
_ipv6_temporary_addr_prefixes_keep_equal(gconstpointer ptr_a, gconstpointer ptr_b)
|
|
|
|
|
{
|
|
|
|
|
return !memcmp(ptr_a, ptr_b, 8);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GPtrArray *
|
|
|
|
|
nm_platform_ip_address_get_prune_list(NMPlatform *self,
|
|
|
|
|
int addr_family,
|
|
|
|
|
int ifindex,
|
|
|
|
|
const struct in6_addr *ipv6_temporary_addr_prefixes_keep,
|
|
|
|
|
guint ipv6_temporary_addr_prefixes_keep_len)
|
|
|
|
|
{
|
|
|
|
|
gs_unref_hashtable GHashTable *ipv6_temporary_addr_prefixes_keep_idx = NULL;
|
|
|
|
|
const int IS_IPv4 = NM_IS_IPv4(addr_family);
|
|
|
|
|
const NMDedupMultiHeadEntry *head_entry;
|
|
|
|
|
NMPLookup lookup;
|
|
|
|
|
GPtrArray *result = NULL;
|
|
|
|
|
CList *iter;
|
2020-07-29 14:06:56 +02:00
|
|
|
|
2022-06-24 23:32:13 +02:00
|
|
|
nmp_lookup_init_object_by_ifindex(&lookup,
|
|
|
|
|
NMP_OBJECT_TYPE_IP_ADDRESS(NM_IS_IPv4(addr_family)),
|
|
|
|
|
ifindex);
|
2020-07-29 14:06:56 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
head_entry = nm_platform_lookup(self, &lookup);
|
2020-07-29 14:06:56 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!head_entry)
|
|
|
|
|
return NULL;
|
2020-07-29 14:06:56 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
c_list_for_each (iter, &head_entry->lst_entries_head) {
|
|
|
|
|
const NMPObject *obj = c_list_entry(iter, NMDedupMultiEntry, lst_entries)->obj;
|
2020-07-29 14:06:56 +02:00
|
|
|
|
2022-06-12 19:50:09 -04:00
|
|
|
if (IS_IPv4) {
|
|
|
|
|
const NMPlatformIP4Address *a4 = NMP_OBJECT_CAST_IP4_ADDRESS(obj);
|
|
|
|
|
|
|
|
|
|
if (a4->address == NM_IPV4LO_ADDR1 && a4->plen == NM_IPV4LO_PREFIXLEN) {
|
|
|
|
|
const NMPlatformIP4Address addr = (NMPlatformIP4Address){
|
|
|
|
|
.ifindex = NM_LOOPBACK_IFINDEX,
|
|
|
|
|
.address = NM_IPV4LO_ADDR1,
|
|
|
|
|
.peer_address = NM_IPV4LO_ADDR1,
|
|
|
|
|
.plen = NM_IPV4LO_PREFIXLEN,
|
|
|
|
|
.use_ip4_broadcast_address = TRUE,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (nm_platform_ip4_address_cmp(a4,
|
|
|
|
|
&addr,
|
|
|
|
|
NM_PLATFORM_IP_ADDRESS_CMP_TYPE_SEMANTICALLY)
|
|
|
|
|
== 0) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
l3cfg: fix clearing IPv6 temporary addresses to avoid stale addresses
IPv6 temporary addresses are configured by kernel, with the
"ipv6.ip6-privacy" setting ("use_tempaddr" sysctl) and the
IFA_F_MANAGETEMPADDR flag.
As such, the idea was that during reapply we would not remove them.
However, that is wrong.
The only case when we want to keep those addresses, is if during reapply
we are going to configure the same primary address (with mngtmpaddr
flag) again. Otherwise, theses addresses must always go away.
This is quite serious. This not only affects Reapply. Also during disconnect
we clear IP configuration via l3cfg.
Have an ethernet profile active with "ipv6.ip6-privacy". Unplug
the cable, the device disconnects but the temporary IPv6 address is not
cleared. As such, nm_device_generate_connection() will now generate
an external profile (with "ipv6.method=disabled" and no manual IP addresses).
The result is, that the device cannot properly autoconnect again,
once you replug the cable.
This is serious for disconnect. But I could not actually reproduce the
problem using reapply. That is, because during reapply we usually
toggle ipv6_disable sysctl, which drops all IPv6 addresses. I still
went through the effort of trying to preserve addresses that we still
want to have, because I am not sure whether there are cases where we
don't toggle ipv6_disable. Also, doing ipv6_disable during reapply is
bad anyway, and we might want to avoid that in the future.
Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
(cherry picked from commit 518f6124c6476e5f91b30b7d5583f494e84fd936)
2022-05-05 10:22:20 +02:00
|
|
|
const NMPlatformIP6Address *a6 = NMP_OBJECT_CAST_IP6_ADDRESS(obj);
|
|
|
|
|
|
|
|
|
|
if (NM_FLAGS_HAS(a6->n_ifa_flags, IFA_F_SECONDARY)
|
|
|
|
|
&& ipv6_temporary_addr_prefixes_keep_len > 0 && a6->plen == 64) {
|
|
|
|
|
gboolean keep = FALSE;
|
|
|
|
|
guint i;
|
|
|
|
|
|
|
|
|
|
if (ipv6_temporary_addr_prefixes_keep_len < 10) {
|
|
|
|
|
for (i = 0; i < ipv6_temporary_addr_prefixes_keep_len; i++) {
|
|
|
|
|
if (memcmp(&ipv6_temporary_addr_prefixes_keep[i], &a6->address, 8) == 0) {
|
|
|
|
|
keep = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/* We have a larger number of addresses. We want that our functions are O(n),
|
|
|
|
|
* so build a lookup index. */
|
|
|
|
|
if (!ipv6_temporary_addr_prefixes_keep_idx) {
|
|
|
|
|
ipv6_temporary_addr_prefixes_keep_idx =
|
|
|
|
|
g_hash_table_new(_ipv6_temporary_addr_prefixes_keep_hash,
|
|
|
|
|
_ipv6_temporary_addr_prefixes_keep_equal);
|
|
|
|
|
for (i = 0; i < ipv6_temporary_addr_prefixes_keep_len; i++) {
|
|
|
|
|
g_hash_table_add(ipv6_temporary_addr_prefixes_keep_idx,
|
|
|
|
|
(gpointer) &ipv6_temporary_addr_prefixes_keep[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (g_hash_table_contains(ipv6_temporary_addr_prefixes_keep_idx, &a6->address))
|
|
|
|
|
keep = TRUE;
|
|
|
|
|
}
|
|
|
|
|
if (keep) {
|
|
|
|
|
/* This IPv6 temporary address has a prefix that we want to keep. */
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
2020-07-29 13:49:31 +02:00
|
|
|
|
2022-03-28 21:19:21 +02:00
|
|
|
if (!result)
|
|
|
|
|
result = g_ptr_array_new_full(head_entry->len, (GDestroyNotify) nmp_object_unref);
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_ptr_array_add(result, (gpointer) nmp_object_ref(obj));
|
|
|
|
|
}
|
2020-07-29 14:06:56 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return result;
|
2020-07-29 13:49:31 +02:00
|
|
|
}
|
|
|
|
|
|
core: inject route list to delete for nm_platform_ip_route_sync()
Whenever we call a platform operation that reads or writes the netlink
socket, there is the possibility that the cache gets updated, as we
receive netlink events.
It is thus racy, if nm_platform_ip_route_sync() *first* adds routes, and
then obtains a list of routes to delete. The correct approach is to
determine which routes to delete first (and keep it in a list
@routes_prune), and pass that list down to nm_platform_ip_route_sync().
Arguably, this doesn't yet solve every race. For example, NMDevice
calls update_ext_ip_config() during ip4_config_merge_and_apply().
That is good, as it resyncs with platform. However, before calling
nm_ip4_config_commit() it calls other platform operations, like
_commit_mtu(). So, the race is still there.
2017-09-22 12:37:12 +02:00
|
|
|
GPtrArray *
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_ip_route_get_prune_list(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
int addr_family,
|
|
|
|
|
int ifindex,
|
|
|
|
|
NMIPRouteTableSyncMode route_table_sync)
|
|
|
|
|
{
|
|
|
|
|
NMPLookup lookup;
|
2022-03-28 21:19:21 +02:00
|
|
|
GPtrArray *routes_prune = NULL;
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMDedupMultiHeadEntry *head_entry;
|
2021-11-09 13:28:54 +01:00
|
|
|
CList *iter;
|
|
|
|
|
const NMPlatformLink *pllink;
|
|
|
|
|
const NMPlatformLnkVrf *lnk_vrf;
|
core: don't add dependent local route for addresses
When adding an IPv4 address, kernel automatically adds a local route.
This is done by fib_add_ifaddr(). Note that if the address is
IFA_F_SECONDARY, then the "src" is the primary address. That means, with
nmcli connection add con-name t type ethernet ifname t autoconnect no \
ipv4.method manual ipv6.method disabled \
ipv4.addresses '192.168.77.10/24, 192.168.77.11/24'
we get two routes:
"local 192.168.77.10 dev t table local proto kernel scope host src 192.168.77.10"
"local 192.168.77.11 dev t table local proto kernel scope host src 192.168.77.10"
Our code would only generate instead:
"local 192.168.77.10 dev t table local proto kernel scope host src 192.168.77.10"
"local 192.168.77.11 dev t table local proto kernel scope host src 192.168.77.11"
Afterwards, this artificial route will be leaked:
#!/bin/bash
set -vx
nmcli connection delete t || :
ip link delete t || :
ip link add name t type veth peer t-veth
nmcli connection add con-name t type ethernet ifname t autoconnect no ipv4.method manual ipv4.addresses '192.168.77.10/24, 192.168.77.11/24' ipv6.method disabled
nmcli connection up t
ip route show table all dev t | grep --color '^\|192.168.77.11'
sleep 1
nmcli device modify t -ipv4.addresses 192.168.77.11/24
ip route show table all dev t | grep --color '^\|192.168.77.11'
ip route show table all dev t | grep -q 192.168.77.11 && echo "the local route 192.168.77.11 is still there, because NM adds a local route with wrong pref-src"
It will also be leaked because in the example above ipv4.route-table is
unset, so we are not in full route sync mode and the local table is not
synced.
This was introduced by commit 3e5fc04df320 ('core: add dependent local
routes configured by kernel'), but it's unclear to me why we really need
this. Drop it again and effectively revert commit 3e5fc04df320 ('core:
add dependent local routes configured by kernel').
I think this "solution" is still bad. We need to improve our route sync
approach with L3Cfg rework. For now, it's probably good enough.
https://bugzilla.redhat.com/show_bug.cgi?id=1907661
2021-03-19 21:20:52 +01:00
|
|
|
guint32 local_table;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
|
|
|
|
nm_assert(NM_IS_PLATFORM(self));
|
|
|
|
|
nm_assert(NM_IN_SET(addr_family, AF_INET, AF_INET6));
|
|
|
|
|
nm_assert(NM_IN_SET(route_table_sync,
|
|
|
|
|
NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN,
|
|
|
|
|
NM_IP_ROUTE_TABLE_SYNC_MODE_FULL,
|
2021-03-22 17:31:35 +01:00
|
|
|
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL,
|
|
|
|
|
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2022-06-24 23:32:13 +02:00
|
|
|
nmp_lookup_init_object_by_ifindex(&lookup,
|
|
|
|
|
NMP_OBJECT_TYPE_IP_ROUTE(NM_IS_IPv4(addr_family)),
|
|
|
|
|
ifindex);
|
2020-09-28 16:03:33 +02:00
|
|
|
head_entry = nm_platform_lookup(self, &lookup);
|
|
|
|
|
if (!head_entry)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
core: don't add dependent local route for addresses
When adding an IPv4 address, kernel automatically adds a local route.
This is done by fib_add_ifaddr(). Note that if the address is
IFA_F_SECONDARY, then the "src" is the primary address. That means, with
nmcli connection add con-name t type ethernet ifname t autoconnect no \
ipv4.method manual ipv6.method disabled \
ipv4.addresses '192.168.77.10/24, 192.168.77.11/24'
we get two routes:
"local 192.168.77.10 dev t table local proto kernel scope host src 192.168.77.10"
"local 192.168.77.11 dev t table local proto kernel scope host src 192.168.77.10"
Our code would only generate instead:
"local 192.168.77.10 dev t table local proto kernel scope host src 192.168.77.10"
"local 192.168.77.11 dev t table local proto kernel scope host src 192.168.77.11"
Afterwards, this artificial route will be leaked:
#!/bin/bash
set -vx
nmcli connection delete t || :
ip link delete t || :
ip link add name t type veth peer t-veth
nmcli connection add con-name t type ethernet ifname t autoconnect no ipv4.method manual ipv4.addresses '192.168.77.10/24, 192.168.77.11/24' ipv6.method disabled
nmcli connection up t
ip route show table all dev t | grep --color '^\|192.168.77.11'
sleep 1
nmcli device modify t -ipv4.addresses 192.168.77.11/24
ip route show table all dev t | grep --color '^\|192.168.77.11'
ip route show table all dev t | grep -q 192.168.77.11 && echo "the local route 192.168.77.11 is still there, because NM adds a local route with wrong pref-src"
It will also be leaked because in the example above ipv4.route-table is
unset, so we are not in full route sync mode and the local table is not
synced.
This was introduced by commit 3e5fc04df320 ('core: add dependent local
routes configured by kernel'), but it's unclear to me why we really need
this. Drop it again and effectively revert commit 3e5fc04df320 ('core:
add dependent local routes configured by kernel').
I think this "solution" is still bad. We need to improve our route sync
approach with L3Cfg rework. For now, it's probably good enough.
https://bugzilla.redhat.com/show_bug.cgi?id=1907661
2021-03-19 21:20:52 +01:00
|
|
|
lnk_vrf = nm_platform_link_get_lnk_vrf(self, ifindex, &pllink);
|
|
|
|
|
if (!lnk_vrf && pllink && pllink->master > 0)
|
|
|
|
|
lnk_vrf = nm_platform_link_get_lnk_vrf(self, pllink->master, NULL);
|
|
|
|
|
local_table = lnk_vrf ? lnk_vrf->table : RT_TABLE_LOCAL;
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
c_list_for_each (iter, &head_entry->lst_entries_head) {
|
2021-11-09 13:28:54 +01:00
|
|
|
const NMPObject *obj = c_list_entry(iter, NMDedupMultiEntry, lst_entries)->obj;
|
2021-03-23 10:05:30 +01:00
|
|
|
const NMPlatformIPXRoute *rt = NMP_OBJECT_CAST_IPX_ROUTE(obj);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2021-03-22 17:31:35 +01:00
|
|
|
switch (route_table_sync) {
|
|
|
|
|
case NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN:
|
2021-03-23 10:05:30 +01:00
|
|
|
if (!nm_platform_route_table_is_main(nm_platform_ip_route_get_effective_table(&rt->rx)))
|
2020-09-28 16:03:33 +02:00
|
|
|
continue;
|
2021-03-22 17:31:35 +01:00
|
|
|
break;
|
|
|
|
|
case NM_IP_ROUTE_TABLE_SYNC_MODE_FULL:
|
2021-03-23 10:05:30 +01:00
|
|
|
if (nm_platform_ip_route_get_effective_table(&rt->rx) == RT_TABLE_LOCAL)
|
2021-03-22 17:31:35 +01:00
|
|
|
continue;
|
|
|
|
|
break;
|
|
|
|
|
case NM_IP_ROUTE_TABLE_SYNC_MODE_ALL:
|
core: don't add dependent local route for addresses
When adding an IPv4 address, kernel automatically adds a local route.
This is done by fib_add_ifaddr(). Note that if the address is
IFA_F_SECONDARY, then the "src" is the primary address. That means, with
nmcli connection add con-name t type ethernet ifname t autoconnect no \
ipv4.method manual ipv6.method disabled \
ipv4.addresses '192.168.77.10/24, 192.168.77.11/24'
we get two routes:
"local 192.168.77.10 dev t table local proto kernel scope host src 192.168.77.10"
"local 192.168.77.11 dev t table local proto kernel scope host src 192.168.77.10"
Our code would only generate instead:
"local 192.168.77.10 dev t table local proto kernel scope host src 192.168.77.10"
"local 192.168.77.11 dev t table local proto kernel scope host src 192.168.77.11"
Afterwards, this artificial route will be leaked:
#!/bin/bash
set -vx
nmcli connection delete t || :
ip link delete t || :
ip link add name t type veth peer t-veth
nmcli connection add con-name t type ethernet ifname t autoconnect no ipv4.method manual ipv4.addresses '192.168.77.10/24, 192.168.77.11/24' ipv6.method disabled
nmcli connection up t
ip route show table all dev t | grep --color '^\|192.168.77.11'
sleep 1
nmcli device modify t -ipv4.addresses 192.168.77.11/24
ip route show table all dev t | grep --color '^\|192.168.77.11'
ip route show table all dev t | grep -q 192.168.77.11 && echo "the local route 192.168.77.11 is still there, because NM adds a local route with wrong pref-src"
It will also be leaked because in the example above ipv4.route-table is
unset, so we are not in full route sync mode and the local table is not
synced.
This was introduced by commit 3e5fc04df320 ('core: add dependent local
routes configured by kernel'), but it's unclear to me why we really need
this. Drop it again and effectively revert commit 3e5fc04df320 ('core:
add dependent local routes configured by kernel').
I think this "solution" is still bad. We need to improve our route sync
approach with L3Cfg rework. For now, it's probably good enough.
https://bugzilla.redhat.com/show_bug.cgi?id=1907661
2021-03-19 21:20:52 +01:00
|
|
|
|
|
|
|
|
/* FIXME: we should better handle routes that are automatically added by kernel.
|
|
|
|
|
*
|
|
|
|
|
* For now, make a good guess which are those routes and exclude them from
|
|
|
|
|
* pruning them. */
|
|
|
|
|
|
|
|
|
|
if (NM_IS_IPv4(addr_family)) {
|
2022-06-12 19:50:09 -04:00
|
|
|
if (ifindex == NM_LOOPBACK_IFINDEX
|
|
|
|
|
&& NM_IN_SET(rt->r4.network, NM_IPV4LO_ADDR1, NM_IPV4LO_NETWORK)) {
|
|
|
|
|
NMPlatformIP4Route r;
|
|
|
|
|
|
|
|
|
|
if (rt->r4.network == NM_IPV4LO_ADDR1) {
|
|
|
|
|
r = (NMPlatformIP4Route){
|
|
|
|
|
.ifindex = NM_LOOPBACK_IFINDEX,
|
|
|
|
|
.type_coerced = nm_platform_route_type_coerce(RTN_LOCAL),
|
|
|
|
|
.table_coerced = nm_platform_route_table_coerce(local_table),
|
|
|
|
|
.network = NM_IPV4LO_ADDR1,
|
|
|
|
|
.plen = 32,
|
|
|
|
|
.metric = 0,
|
|
|
|
|
.rt_source = NM_IPV4LO_ADDR1,
|
|
|
|
|
.scope_inv = nm_platform_route_scope_inv(RT_SCOPE_HOST),
|
|
|
|
|
.pref_src = NM_IPV4LO_ADDR1,
|
|
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
r = (NMPlatformIP4Route){
|
|
|
|
|
.ifindex = NM_LOOPBACK_IFINDEX,
|
|
|
|
|
.type_coerced = nm_platform_route_type_coerce(RTN_LOCAL),
|
|
|
|
|
.table_coerced = nm_platform_route_table_coerce(local_table),
|
|
|
|
|
.network = NM_IPV4LO_NETWORK,
|
|
|
|
|
.plen = NM_IPV4LO_PREFIXLEN,
|
|
|
|
|
.metric = 0,
|
|
|
|
|
.rt_source = NM_IPV4LO_ADDR1,
|
|
|
|
|
.scope_inv = nm_platform_route_scope_inv(RT_SCOPE_HOST),
|
|
|
|
|
.pref_src = NM_IPV4LO_ADDR1,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (nm_platform_ip4_route_cmp(&rt->r4,
|
|
|
|
|
&r,
|
|
|
|
|
NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY)
|
|
|
|
|
== 0) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
core: don't add dependent local route for addresses
When adding an IPv4 address, kernel automatically adds a local route.
This is done by fib_add_ifaddr(). Note that if the address is
IFA_F_SECONDARY, then the "src" is the primary address. That means, with
nmcli connection add con-name t type ethernet ifname t autoconnect no \
ipv4.method manual ipv6.method disabled \
ipv4.addresses '192.168.77.10/24, 192.168.77.11/24'
we get two routes:
"local 192.168.77.10 dev t table local proto kernel scope host src 192.168.77.10"
"local 192.168.77.11 dev t table local proto kernel scope host src 192.168.77.10"
Our code would only generate instead:
"local 192.168.77.10 dev t table local proto kernel scope host src 192.168.77.10"
"local 192.168.77.11 dev t table local proto kernel scope host src 192.168.77.11"
Afterwards, this artificial route will be leaked:
#!/bin/bash
set -vx
nmcli connection delete t || :
ip link delete t || :
ip link add name t type veth peer t-veth
nmcli connection add con-name t type ethernet ifname t autoconnect no ipv4.method manual ipv4.addresses '192.168.77.10/24, 192.168.77.11/24' ipv6.method disabled
nmcli connection up t
ip route show table all dev t | grep --color '^\|192.168.77.11'
sleep 1
nmcli device modify t -ipv4.addresses 192.168.77.11/24
ip route show table all dev t | grep --color '^\|192.168.77.11'
ip route show table all dev t | grep -q 192.168.77.11 && echo "the local route 192.168.77.11 is still there, because NM adds a local route with wrong pref-src"
It will also be leaked because in the example above ipv4.route-table is
unset, so we are not in full route sync mode and the local table is not
synced.
This was introduced by commit 3e5fc04df320 ('core: add dependent local
routes configured by kernel'), but it's unclear to me why we really need
this. Drop it again and effectively revert commit 3e5fc04df320 ('core:
add dependent local routes configured by kernel').
I think this "solution" is still bad. We need to improve our route sync
approach with L3Cfg rework. For now, it's probably good enough.
https://bugzilla.redhat.com/show_bug.cgi?id=1907661
2021-03-19 21:20:52 +01:00
|
|
|
/* for each IPv4 address kernel adds a route like
|
|
|
|
|
*
|
|
|
|
|
* local $ADDR dev $IFACE table local proto kernel scope host src $PRIMARY_ADDR
|
|
|
|
|
*
|
|
|
|
|
* Check whether route could be of that kind. */
|
|
|
|
|
if (nm_platform_ip_route_get_effective_table(&rt->rx) == local_table
|
|
|
|
|
&& rt->rx.plen == 32 && rt->rx.rt_source == NM_IP_CONFIG_SOURCE_RTPROT_KERNEL
|
|
|
|
|
&& rt->rx.metric == 0
|
|
|
|
|
&& rt->r4.scope_inv == nm_platform_route_scope_inv(RT_SCOPE_HOST)
|
|
|
|
|
&& rt->r4.gateway == INADDR_ANY) {
|
2022-09-08 09:47:04 +02:00
|
|
|
const NMPlatformIP4Route r = {
|
|
|
|
|
.ifindex = ifindex,
|
|
|
|
|
.type_coerced = nm_platform_route_type_coerce(RTN_LOCAL),
|
|
|
|
|
.plen = 32,
|
|
|
|
|
.rt_source = NM_IP_CONFIG_SOURCE_RTPROT_KERNEL,
|
|
|
|
|
.metric = 0,
|
|
|
|
|
.table_coerced = nm_platform_route_table_coerce(local_table),
|
|
|
|
|
.scope_inv = nm_platform_route_scope_inv(RT_SCOPE_HOST),
|
|
|
|
|
.gateway = INADDR_ANY,
|
|
|
|
|
/* the possible "network" depends on the addresses we have. We don't check that
|
|
|
|
|
* carefully. If the other parameters match, we assume that this route is the one
|
|
|
|
|
* generated by kernel. */
|
|
|
|
|
.network = rt->r4.network,
|
|
|
|
|
.pref_src = rt->r4.pref_src,
|
|
|
|
|
};
|
core: don't add dependent local route for addresses
When adding an IPv4 address, kernel automatically adds a local route.
This is done by fib_add_ifaddr(). Note that if the address is
IFA_F_SECONDARY, then the "src" is the primary address. That means, with
nmcli connection add con-name t type ethernet ifname t autoconnect no \
ipv4.method manual ipv6.method disabled \
ipv4.addresses '192.168.77.10/24, 192.168.77.11/24'
we get two routes:
"local 192.168.77.10 dev t table local proto kernel scope host src 192.168.77.10"
"local 192.168.77.11 dev t table local proto kernel scope host src 192.168.77.10"
Our code would only generate instead:
"local 192.168.77.10 dev t table local proto kernel scope host src 192.168.77.10"
"local 192.168.77.11 dev t table local proto kernel scope host src 192.168.77.11"
Afterwards, this artificial route will be leaked:
#!/bin/bash
set -vx
nmcli connection delete t || :
ip link delete t || :
ip link add name t type veth peer t-veth
nmcli connection add con-name t type ethernet ifname t autoconnect no ipv4.method manual ipv4.addresses '192.168.77.10/24, 192.168.77.11/24' ipv6.method disabled
nmcli connection up t
ip route show table all dev t | grep --color '^\|192.168.77.11'
sleep 1
nmcli device modify t -ipv4.addresses 192.168.77.11/24
ip route show table all dev t | grep --color '^\|192.168.77.11'
ip route show table all dev t | grep -q 192.168.77.11 && echo "the local route 192.168.77.11 is still there, because NM adds a local route with wrong pref-src"
It will also be leaked because in the example above ipv4.route-table is
unset, so we are not in full route sync mode and the local table is not
synced.
This was introduced by commit 3e5fc04df320 ('core: add dependent local
routes configured by kernel'), but it's unclear to me why we really need
this. Drop it again and effectively revert commit 3e5fc04df320 ('core:
add dependent local routes configured by kernel').
I think this "solution" is still bad. We need to improve our route sync
approach with L3Cfg rework. For now, it's probably good enough.
https://bugzilla.redhat.com/show_bug.cgi?id=1907661
2021-03-19 21:20:52 +01:00
|
|
|
|
|
|
|
|
/* to be more confident about comparing the value, use our nm_platform_ip4_route_cmp()
|
|
|
|
|
* implementation. That will also consider parameters that we leave unspecified here. */
|
|
|
|
|
if (nm_platform_ip4_route_cmp(&rt->r4,
|
2022-09-08 09:47:04 +02:00
|
|
|
&r,
|
core: don't add dependent local route for addresses
When adding an IPv4 address, kernel automatically adds a local route.
This is done by fib_add_ifaddr(). Note that if the address is
IFA_F_SECONDARY, then the "src" is the primary address. That means, with
nmcli connection add con-name t type ethernet ifname t autoconnect no \
ipv4.method manual ipv6.method disabled \
ipv4.addresses '192.168.77.10/24, 192.168.77.11/24'
we get two routes:
"local 192.168.77.10 dev t table local proto kernel scope host src 192.168.77.10"
"local 192.168.77.11 dev t table local proto kernel scope host src 192.168.77.10"
Our code would only generate instead:
"local 192.168.77.10 dev t table local proto kernel scope host src 192.168.77.10"
"local 192.168.77.11 dev t table local proto kernel scope host src 192.168.77.11"
Afterwards, this artificial route will be leaked:
#!/bin/bash
set -vx
nmcli connection delete t || :
ip link delete t || :
ip link add name t type veth peer t-veth
nmcli connection add con-name t type ethernet ifname t autoconnect no ipv4.method manual ipv4.addresses '192.168.77.10/24, 192.168.77.11/24' ipv6.method disabled
nmcli connection up t
ip route show table all dev t | grep --color '^\|192.168.77.11'
sleep 1
nmcli device modify t -ipv4.addresses 192.168.77.11/24
ip route show table all dev t | grep --color '^\|192.168.77.11'
ip route show table all dev t | grep -q 192.168.77.11 && echo "the local route 192.168.77.11 is still there, because NM adds a local route with wrong pref-src"
It will also be leaked because in the example above ipv4.route-table is
unset, so we are not in full route sync mode and the local table is not
synced.
This was introduced by commit 3e5fc04df320 ('core: add dependent local
routes configured by kernel'), but it's unclear to me why we really need
this. Drop it again and effectively revert commit 3e5fc04df320 ('core:
add dependent local routes configured by kernel').
I think this "solution" is still bad. We need to improve our route sync
approach with L3Cfg rework. For now, it's probably good enough.
https://bugzilla.redhat.com/show_bug.cgi?id=1907661
2021-03-19 21:20:52 +01:00
|
|
|
NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY)
|
|
|
|
|
== 0)
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/* for each IPv6 address (that is no longer tentative) kernel adds a route like
|
|
|
|
|
*
|
|
|
|
|
* local $ADDR dev $IFACE table local proto kernel metric 0 pref medium
|
|
|
|
|
*
|
|
|
|
|
* Same as for the IPv4 case. */
|
|
|
|
|
if (nm_platform_ip_route_get_effective_table(&rt->rx) == local_table
|
|
|
|
|
&& rt->rx.plen == 128 && rt->rx.rt_source == NM_IP_CONFIG_SOURCE_RTPROT_KERNEL
|
|
|
|
|
&& rt->rx.metric == 0 && rt->r6.rt_pref == NM_ICMPV6_ROUTER_PREF_MEDIUM
|
|
|
|
|
&& IN6_IS_ADDR_UNSPECIFIED(&rt->r6.gateway)) {
|
2022-09-08 09:47:04 +02:00
|
|
|
const NMPlatformIP6Route r = {
|
|
|
|
|
.ifindex = ifindex,
|
|
|
|
|
.type_coerced = nm_platform_route_type_coerce(RTN_LOCAL),
|
|
|
|
|
.plen = 128,
|
|
|
|
|
.rt_source = NM_IP_CONFIG_SOURCE_RTPROT_KERNEL,
|
|
|
|
|
.metric = 0,
|
|
|
|
|
.table_coerced = nm_platform_route_table_coerce(local_table),
|
|
|
|
|
.rt_pref = NM_ICMPV6_ROUTER_PREF_MEDIUM,
|
|
|
|
|
.gateway = IN6ADDR_ANY_INIT,
|
|
|
|
|
.network = rt->r6.network,
|
|
|
|
|
};
|
core: don't add dependent local route for addresses
When adding an IPv4 address, kernel automatically adds a local route.
This is done by fib_add_ifaddr(). Note that if the address is
IFA_F_SECONDARY, then the "src" is the primary address. That means, with
nmcli connection add con-name t type ethernet ifname t autoconnect no \
ipv4.method manual ipv6.method disabled \
ipv4.addresses '192.168.77.10/24, 192.168.77.11/24'
we get two routes:
"local 192.168.77.10 dev t table local proto kernel scope host src 192.168.77.10"
"local 192.168.77.11 dev t table local proto kernel scope host src 192.168.77.10"
Our code would only generate instead:
"local 192.168.77.10 dev t table local proto kernel scope host src 192.168.77.10"
"local 192.168.77.11 dev t table local proto kernel scope host src 192.168.77.11"
Afterwards, this artificial route will be leaked:
#!/bin/bash
set -vx
nmcli connection delete t || :
ip link delete t || :
ip link add name t type veth peer t-veth
nmcli connection add con-name t type ethernet ifname t autoconnect no ipv4.method manual ipv4.addresses '192.168.77.10/24, 192.168.77.11/24' ipv6.method disabled
nmcli connection up t
ip route show table all dev t | grep --color '^\|192.168.77.11'
sleep 1
nmcli device modify t -ipv4.addresses 192.168.77.11/24
ip route show table all dev t | grep --color '^\|192.168.77.11'
ip route show table all dev t | grep -q 192.168.77.11 && echo "the local route 192.168.77.11 is still there, because NM adds a local route with wrong pref-src"
It will also be leaked because in the example above ipv4.route-table is
unset, so we are not in full route sync mode and the local table is not
synced.
This was introduced by commit 3e5fc04df320 ('core: add dependent local
routes configured by kernel'), but it's unclear to me why we really need
this. Drop it again and effectively revert commit 3e5fc04df320 ('core:
add dependent local routes configured by kernel').
I think this "solution" is still bad. We need to improve our route sync
approach with L3Cfg rework. For now, it's probably good enough.
https://bugzilla.redhat.com/show_bug.cgi?id=1907661
2021-03-19 21:20:52 +01:00
|
|
|
|
|
|
|
|
if (nm_platform_ip6_route_cmp(&rt->r6,
|
2022-09-08 09:47:04 +02:00
|
|
|
&r,
|
core: don't add dependent local route for addresses
When adding an IPv4 address, kernel automatically adds a local route.
This is done by fib_add_ifaddr(). Note that if the address is
IFA_F_SECONDARY, then the "src" is the primary address. That means, with
nmcli connection add con-name t type ethernet ifname t autoconnect no \
ipv4.method manual ipv6.method disabled \
ipv4.addresses '192.168.77.10/24, 192.168.77.11/24'
we get two routes:
"local 192.168.77.10 dev t table local proto kernel scope host src 192.168.77.10"
"local 192.168.77.11 dev t table local proto kernel scope host src 192.168.77.10"
Our code would only generate instead:
"local 192.168.77.10 dev t table local proto kernel scope host src 192.168.77.10"
"local 192.168.77.11 dev t table local proto kernel scope host src 192.168.77.11"
Afterwards, this artificial route will be leaked:
#!/bin/bash
set -vx
nmcli connection delete t || :
ip link delete t || :
ip link add name t type veth peer t-veth
nmcli connection add con-name t type ethernet ifname t autoconnect no ipv4.method manual ipv4.addresses '192.168.77.10/24, 192.168.77.11/24' ipv6.method disabled
nmcli connection up t
ip route show table all dev t | grep --color '^\|192.168.77.11'
sleep 1
nmcli device modify t -ipv4.addresses 192.168.77.11/24
ip route show table all dev t | grep --color '^\|192.168.77.11'
ip route show table all dev t | grep -q 192.168.77.11 && echo "the local route 192.168.77.11 is still there, because NM adds a local route with wrong pref-src"
It will also be leaked because in the example above ipv4.route-table is
unset, so we are not in full route sync mode and the local table is not
synced.
This was introduced by commit 3e5fc04df320 ('core: add dependent local
routes configured by kernel'), but it's unclear to me why we really need
this. Drop it again and effectively revert commit 3e5fc04df320 ('core:
add dependent local routes configured by kernel').
I think this "solution" is still bad. We need to improve our route sync
approach with L3Cfg rework. For now, it's probably good enough.
https://bugzilla.redhat.com/show_bug.cgi?id=1907661
2021-03-19 21:20:52 +01:00
|
|
|
NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY)
|
|
|
|
|
== 0)
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2021-09-17 13:53:18 +02:00
|
|
|
|
|
|
|
|
/* Kernels < 5.11 add a route like:
|
|
|
|
|
*
|
|
|
|
|
* unicast ff00::/8 dev $IFACE proto boot scope global metric 256 pref medium
|
|
|
|
|
*
|
|
|
|
|
* to allow sending and receiving IPv6 multicast traffic. Don't remove it.
|
|
|
|
|
* Since kernel 5.11 the route looks like:
|
|
|
|
|
*
|
|
|
|
|
* multicast ff00::/8 dev $IFACE proto kernel metric 256 pref medium
|
|
|
|
|
*
|
|
|
|
|
* As NM ignores routes with rtm_type multicast, there is no need for the code
|
|
|
|
|
* below on newer kernels.
|
|
|
|
|
*/
|
|
|
|
|
if (nm_platform_ip_route_get_effective_table(&rt->rx) == local_table
|
|
|
|
|
&& rt->rx.plen == 8 && rt->rx.rt_source == NM_IP_CONFIG_SOURCE_RTPROT_BOOT
|
|
|
|
|
&& rt->rx.metric == 256 && rt->r6.rt_pref == NM_ICMPV6_ROUTER_PREF_MEDIUM
|
|
|
|
|
&& IN6_IS_ADDR_UNSPECIFIED(&rt->r6.gateway)) {
|
2022-09-08 09:47:04 +02:00
|
|
|
const NMPlatformIP6Route r = {
|
|
|
|
|
.ifindex = ifindex,
|
|
|
|
|
.type_coerced = nm_platform_route_type_coerce(RTN_UNICAST),
|
|
|
|
|
.plen = 8,
|
|
|
|
|
.rt_source = NM_IP_CONFIG_SOURCE_RTPROT_BOOT,
|
|
|
|
|
.metric = 256,
|
|
|
|
|
.table_coerced = nm_platform_route_table_coerce(local_table),
|
|
|
|
|
.rt_pref = NM_ICMPV6_ROUTER_PREF_MEDIUM,
|
|
|
|
|
.gateway = IN6ADDR_ANY_INIT,
|
|
|
|
|
.network =
|
|
|
|
|
NM_IN6ADDR_INIT(0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
|
|
|
|
};
|
2021-09-17 13:53:18 +02:00
|
|
|
|
|
|
|
|
if (nm_platform_ip6_route_cmp(&rt->r6,
|
2022-09-08 09:47:04 +02:00
|
|
|
&r,
|
2021-09-17 13:53:18 +02:00
|
|
|
NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY)
|
|
|
|
|
== 0)
|
|
|
|
|
continue;
|
|
|
|
|
}
|
core: don't add dependent local route for addresses
When adding an IPv4 address, kernel automatically adds a local route.
This is done by fib_add_ifaddr(). Note that if the address is
IFA_F_SECONDARY, then the "src" is the primary address. That means, with
nmcli connection add con-name t type ethernet ifname t autoconnect no \
ipv4.method manual ipv6.method disabled \
ipv4.addresses '192.168.77.10/24, 192.168.77.11/24'
we get two routes:
"local 192.168.77.10 dev t table local proto kernel scope host src 192.168.77.10"
"local 192.168.77.11 dev t table local proto kernel scope host src 192.168.77.10"
Our code would only generate instead:
"local 192.168.77.10 dev t table local proto kernel scope host src 192.168.77.10"
"local 192.168.77.11 dev t table local proto kernel scope host src 192.168.77.11"
Afterwards, this artificial route will be leaked:
#!/bin/bash
set -vx
nmcli connection delete t || :
ip link delete t || :
ip link add name t type veth peer t-veth
nmcli connection add con-name t type ethernet ifname t autoconnect no ipv4.method manual ipv4.addresses '192.168.77.10/24, 192.168.77.11/24' ipv6.method disabled
nmcli connection up t
ip route show table all dev t | grep --color '^\|192.168.77.11'
sleep 1
nmcli device modify t -ipv4.addresses 192.168.77.11/24
ip route show table all dev t | grep --color '^\|192.168.77.11'
ip route show table all dev t | grep -q 192.168.77.11 && echo "the local route 192.168.77.11 is still there, because NM adds a local route with wrong pref-src"
It will also be leaked because in the example above ipv4.route-table is
unset, so we are not in full route sync mode and the local table is not
synced.
This was introduced by commit 3e5fc04df320 ('core: add dependent local
routes configured by kernel'), but it's unclear to me why we really need
this. Drop it again and effectively revert commit 3e5fc04df320 ('core:
add dependent local routes configured by kernel').
I think this "solution" is still bad. We need to improve our route sync
approach with L3Cfg rework. For now, it's probably good enough.
https://bugzilla.redhat.com/show_bug.cgi?id=1907661
2021-03-19 21:20:52 +01:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2021-03-22 17:31:35 +01:00
|
|
|
case NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE:
|
|
|
|
|
break;
|
2021-03-23 10:05:30 +01:00
|
|
|
|
2021-03-22 17:31:35 +01:00
|
|
|
default:
|
|
|
|
|
nm_assert_not_reached();
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2022-03-28 21:19:21 +02:00
|
|
|
if (!routes_prune) {
|
|
|
|
|
routes_prune =
|
|
|
|
|
g_ptr_array_new_full(head_entry->len, (GDestroyNotify) nm_dedup_multi_obj_unref);
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_ptr_array_add(routes_prune, (gpointer) nmp_object_ref(obj));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return routes_prune;
|
core: inject route list to delete for nm_platform_ip_route_sync()
Whenever we call a platform operation that reads or writes the netlink
socket, there is the possibility that the cache gets updated, as we
receive netlink events.
It is thus racy, if nm_platform_ip_route_sync() *first* adds routes, and
then obtains a list of routes to delete. The correct approach is to
determine which routes to delete first (and keep it in a list
@routes_prune), and pass that list down to nm_platform_ip_route_sync().
Arguably, this doesn't yet solve every race. For example, NMDevice
calls update_ext_ip_config() during ip4_config_merge_and_apply().
That is good, as it resyncs with platform. However, before calling
nm_ip4_config_commit() it calls other platform operations, like
_commit_mtu(). So, the race is still there.
2017-09-22 12:37:12 +02:00
|
|
|
}
|
|
|
|
|
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
/**
|
|
|
|
|
* nm_platform_ip_route_sync:
|
|
|
|
|
* @self: the #NMPlatform instance.
|
|
|
|
|
* @addr_family: AF_INET or AF_INET6.
|
|
|
|
|
* @ifindex: the @ifindex for which the routes are to be added.
|
2023-03-01 01:21:38 +01:00
|
|
|
* @routes: (nullable): a list of routes to configure. Must contain
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
* NMPObject instances of routes, according to @addr_family.
|
2023-03-01 01:21:38 +01:00
|
|
|
* @routes_prune: (nullable): the list of routes to delete.
|
core: inject route list to delete for nm_platform_ip_route_sync()
Whenever we call a platform operation that reads or writes the netlink
socket, there is the possibility that the cache gets updated, as we
receive netlink events.
It is thus racy, if nm_platform_ip_route_sync() *first* adds routes, and
then obtains a list of routes to delete. The correct approach is to
determine which routes to delete first (and keep it in a list
@routes_prune), and pass that list down to nm_platform_ip_route_sync().
Arguably, this doesn't yet solve every race. For example, NMDevice
calls update_ext_ip_config() during ip4_config_merge_and_apply().
That is good, as it resyncs with platform. However, before calling
nm_ip4_config_commit() it calls other platform operations, like
_commit_mtu(). So, the race is still there.
2017-09-22 12:37:12 +02:00
|
|
|
* If platform has such a route configured, it will be deleted
|
|
|
|
|
* at the end of the operation. Note that if @routes contains
|
|
|
|
|
* the same route, then it will not be deleted. @routes overrules
|
|
|
|
|
* @routes_prune list.
|
2023-03-01 01:21:38 +01:00
|
|
|
* @out_routes_failed: (out) (optional) (nullable): routes that could
|
platform: rework handling of failed routes during nm_platform_ip_route_sync()
Previously, there was "temporary-not-available" mechanism in NML3Cfg,
which aimed to handle IPv6 routes with prefsrc. Theoretically, that
mechanism may have been extended to other use-cases, like IPv4 routes
with prefsrc. What it attempted to handle, is the inability to configure
such routes, unless the respective prefsrc address is configured and
non-tentative. However, the address that we are waiting for, could also
be on another interface, so that mechanism wasn't applicable. This is
now replaced by _routes_watch_ip_addrs(). It seems there isn't anything
useful left for the "temporary-not-available" mechanism and it can go,
except...
We want to log a warning when we are unable to configure a route. Also,
in the future we might want to know when the IP configuration is
degradated due to inability to configure the desired routes (a condition
that we might want to expose to the user, not only via logging; or we
may want to react on that).
However, with prefsrc routes we don't know right away whether the
inability to configure the route right away indicates an actual problem,
or whether that will resolve itself (e.g. after the address passes
DAD/ACD, after we received an DHCP lease or after the address was
configured on another interface). Consequently, to know whether the
current inability to configure such a route is a problem, we need to
know the larger context. nm_platform_ip_route_sync() does not have that
context.
Instead, nm_platform_ip_route_sync() needs only do debug log about
failure to configure routes. It will now also return all the failed
routes to NML3Cfg, which can decide whether that is a problem.
This reworks the previous "temporary-not-available" mechanism to track
the state of the failed routes, to eventually decide whether there is an
actual problem (and log about it).
Another problem this solves is that since commit ('platform: always
reconfigure IP routes even if removed externally'), we will eagerly
re-try to configure the same route over and over. We cannot just spam
the log with warnings about the same failure on every commit. We need to
remember that we already logged about the problem and rate limit
warnings otherwise. This is what the new mechanism also achieves.
Indeed, all this is mostly for the sole benefit of logging better
warnings (and not duplicated).
2023-03-08 16:08:23 +01:00
|
|
|
* not be synced/added.
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
*
|
|
|
|
|
* Returns: %TRUE on success.
|
|
|
|
|
*/
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_ip_route_sync(NMPlatform *self,
|
|
|
|
|
int addr_family,
|
|
|
|
|
int ifindex,
|
2021-11-09 13:28:54 +01:00
|
|
|
GPtrArray *routes,
|
|
|
|
|
GPtrArray *routes_prune,
|
platform: rework handling of failed routes during nm_platform_ip_route_sync()
Previously, there was "temporary-not-available" mechanism in NML3Cfg,
which aimed to handle IPv6 routes with prefsrc. Theoretically, that
mechanism may have been extended to other use-cases, like IPv4 routes
with prefsrc. What it attempted to handle, is the inability to configure
such routes, unless the respective prefsrc address is configured and
non-tentative. However, the address that we are waiting for, could also
be on another interface, so that mechanism wasn't applicable. This is
now replaced by _routes_watch_ip_addrs(). It seems there isn't anything
useful left for the "temporary-not-available" mechanism and it can go,
except...
We want to log a warning when we are unable to configure a route. Also,
in the future we might want to know when the IP configuration is
degradated due to inability to configure the desired routes (a condition
that we might want to expose to the user, not only via logging; or we
may want to react on that).
However, with prefsrc routes we don't know right away whether the
inability to configure the route right away indicates an actual problem,
or whether that will resolve itself (e.g. after the address passes
DAD/ACD, after we received an DHCP lease or after the address was
configured on another interface). Consequently, to know whether the
current inability to configure such a route is a problem, we need to
know the larger context. nm_platform_ip_route_sync() does not have that
context.
Instead, nm_platform_ip_route_sync() needs only do debug log about
failure to configure routes. It will now also return all the failed
routes to NML3Cfg, which can decide whether that is a problem.
This reworks the previous "temporary-not-available" mechanism to track
the state of the failed routes, to eventually decide whether there is an
actual problem (and log about it).
Another problem this solves is that since commit ('platform: always
reconfigure IP routes even if removed externally'), we will eagerly
re-try to configure the same route over and over. We cannot just spam
the log with warnings about the same failure on every commit. We need to
remember that we already logged about the problem and rate limit
warnings otherwise. This is what the new mechanism also achieves.
Indeed, all this is mostly for the sole benefit of logging better
warnings (and not duplicated).
2023-03-08 16:08:23 +01:00
|
|
|
GPtrArray **out_routes_failed)
|
2020-09-28 16:03:33 +02:00
|
|
|
{
|
2021-11-09 13:28:54 +01:00
|
|
|
const int IS_IPv4 = NM_IS_IPv4(addr_family);
|
|
|
|
|
const NMPlatformVTableRoute *vt;
|
2020-09-28 16:03:33 +02:00
|
|
|
gs_unref_hashtable GHashTable *routes_idx = NULL;
|
2021-11-09 13:28:54 +01:00
|
|
|
const NMPObject *conf_o;
|
|
|
|
|
const NMDedupMultiEntry *plat_entry;
|
2020-09-28 16:03:33 +02:00
|
|
|
guint i;
|
|
|
|
|
int i_type;
|
|
|
|
|
gboolean success = TRUE;
|
2022-03-30 09:23:54 +02:00
|
|
|
char sbuf1[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
|
|
|
|
char sbuf2[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
2020-09-28 16:03:33 +02:00
|
|
|
|
|
|
|
|
nm_assert(NM_IS_PLATFORM(self));
|
|
|
|
|
nm_assert(ifindex > 0);
|
|
|
|
|
|
|
|
|
|
vt = &nm_platform_vtable_route.vx[IS_IPv4];
|
|
|
|
|
|
|
|
|
|
for (i_type = 0; routes && i_type < 2; i_type++) {
|
|
|
|
|
for (i = 0; i < routes->len; i++) {
|
platform: don't add onlink route to gateway in nm_platform_ip_route_sync()
Kernel rejects adding routes that have a gateway, if there is no direct
(onlink) route to that gateway. The exact conditions are non-trivial due
to the complexities of routing, but that's it basically.
Anyway. In NetworkManager we don't want to have such non-obvious
interdependencies. If the user configures a route with a gateway, but
"forgets" to configure a direct route to the gateway, we don't assume
that the user configured the wrong route. Instead, we assume the user
forgot to configure the additional route and add it automatically. That
is for convenience, but also because (as said) the rules for this are
non-trivial. Moreover, it's problematic to report an error in routing
during activation. Should we fail activation altogether? Should we just
log an error and otherwise silently proceed? Logging is not a sensible
behavior that the (possibly non-human) user can meaningfully handle. So
we instead try to make it work.
Previously, nm_platform_ip_route_sync() had the workaround of when we
failed to configure a route and it looked like it might be due to the
missing onlink route, we would add a suitable /32 / /128 route. The
problem is that we want that NML3Cfg is aware of what routes we want to
configure. The lower layer nm_platform_ip_route_sync() adding additional
routes makes that difficult (maybe nm_platform_ip_route_sync() could
return the additional routes that it added, but it doesn't).
The better solution seems to be that
nm_l3_config_data_add_dependent_onlink_routes() adds the required routes
in NML3Cfg during commit. This is done since commit 40732115956f
('Revert "l3cfg: do not add dependent routes for non-default routes"').
Further, since commit ('platform: always reconfigure IP routes even if
removed externally') we also always try to re-add the routes we want,
regardless of whether they appear to be deleted by the user.
So a suitable onlink route really should be always there, and there is
no more need for this workaround.
2023-03-02 20:08:31 +01:00
|
|
|
gs_free char *extack_msg = NULL;
|
2023-02-22 13:05:53 +01:00
|
|
|
int r;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
|
|
|
|
conf_o = routes->pdata[i];
|
|
|
|
|
|
platform: don't add routes that are tracked as external routes
Due to something that really should be fixed, NetworkManager merges the routes
that it wants to configure, with the routes that are configured externally.
This includes a subtract and merge dance, which is wrong.
Anyway. If we are in nm_platform_ip_route_sync(), then we never want to
actively configure a route, that we only have in the list because it is
(or was) present on the interface.
Otherwise we have a problem. Note that we make a plan which
routes/addresses to add/remove before starting. So, if we start with an
IPv4 address configured in kernel, then there is also a corresponding
local route. We would track that local route as external.
During sync, we first remove the IP address, and kernel automatically
also removes the local route. However, as we already made the plan to
keep that route, NetworkManager would wrongly configure it again.
This should fix that bug. It is anyway wrong to even try to explicitly
configure a route, that is purely in the list as being external.
https://bugzilla.redhat.com/show_bug.cgi?id=1979192#c11
2021-07-20 11:53:31 +02:00
|
|
|
/* User space cannot add IPv6 routes with metric 0. However, kernel can, and we might track such
|
|
|
|
|
* routes in @route as they are present external. As we already skipped external routes above,
|
|
|
|
|
* we don't expect a user's choice to add such a route (it won't work anyway). */
|
|
|
|
|
nm_assert(
|
|
|
|
|
IS_IPv4
|
|
|
|
|
|| nm_platform_ip6_route_get_effective_metric(NMP_OBJECT_CAST_IP6_ROUTE(conf_o))
|
|
|
|
|
!= 0);
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
#define VTABLE_IS_DEVICE_ROUTE(vt, o) \
|
|
|
|
|
(vt->is_ip4 ? (NMP_OBJECT_CAST_IP4_ROUTE(o)->gateway == 0) \
|
|
|
|
|
: IN6_IS_ADDR_UNSPECIFIED(&NMP_OBJECT_CAST_IP6_ROUTE(o)->gateway))
|
|
|
|
|
|
|
|
|
|
if ((i_type == 0 && !VTABLE_IS_DEVICE_ROUTE(vt, conf_o))
|
|
|
|
|
|| (i_type == 1 && VTABLE_IS_DEVICE_ROUTE(vt, conf_o))) {
|
|
|
|
|
/* we add routes in two runs over @i_type.
|
2020-09-28 14:50:01 +02:00
|
|
|
*
|
|
|
|
|
* First device routes, then gateway routes. */
|
2020-09-28 16:03:33 +02:00
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!routes_idx) {
|
|
|
|
|
routes_idx = g_hash_table_new((GHashFunc) nmp_object_id_hash,
|
|
|
|
|
(GEqualFunc) nmp_object_id_equal);
|
|
|
|
|
}
|
platform: don't add routes that are tracked as external routes
Due to something that really should be fixed, NetworkManager merges the routes
that it wants to configure, with the routes that are configured externally.
This includes a subtract and merge dance, which is wrong.
Anyway. If we are in nm_platform_ip_route_sync(), then we never want to
actively configure a route, that we only have in the list because it is
(or was) present on the interface.
Otherwise we have a problem. Note that we make a plan which
routes/addresses to add/remove before starting. So, if we start with an
IPv4 address configured in kernel, then there is also a corresponding
local route. We would track that local route as external.
During sync, we first remove the IP address, and kernel automatically
also removes the local route. However, as we already made the plan to
keep that route, NetworkManager would wrongly configure it again.
This should fix that bug. It is anyway wrong to even try to explicitly
configure a route, that is purely in the list as being external.
https://bugzilla.redhat.com/show_bug.cgi?id=1979192#c11
2021-07-20 11:53:31 +02:00
|
|
|
if (!g_hash_table_add(routes_idx, (gpointer) conf_o)) {
|
2020-09-28 16:03:33 +02:00
|
|
|
_LOG3D("route-sync: skip adding duplicate route %s",
|
|
|
|
|
nmp_object_to_string(conf_o,
|
|
|
|
|
NMP_OBJECT_TO_STRING_PUBLIC,
|
|
|
|
|
sbuf1,
|
|
|
|
|
sizeof(sbuf1)));
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
plat_entry = nm_platform_lookup_entry(self, NMP_CACHE_ID_TYPE_OBJECT_TYPE, conf_o);
|
|
|
|
|
if (plat_entry) {
|
|
|
|
|
const NMPObject *plat_o;
|
core: inject route list to delete for nm_platform_ip_route_sync()
Whenever we call a platform operation that reads or writes the netlink
socket, there is the possibility that the cache gets updated, as we
receive netlink events.
It is thus racy, if nm_platform_ip_route_sync() *first* adds routes, and
then obtains a list of routes to delete. The correct approach is to
determine which routes to delete first (and keep it in a list
@routes_prune), and pass that list down to nm_platform_ip_route_sync().
Arguably, this doesn't yet solve every race. For example, NMDevice
calls update_ext_ip_config() during ip4_config_merge_and_apply().
That is good, as it resyncs with platform. However, before calling
nm_ip4_config_commit() it calls other platform operations, like
_commit_mtu(). So, the race is still there.
2017-09-22 12:37:12 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
plat_o = plat_entry->obj;
|
2017-09-04 07:10:42 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (vt->route_cmp(NMP_OBJECT_CAST_IPX_ROUTE(conf_o),
|
|
|
|
|
NMP_OBJECT_CAST_IPX_ROUTE(plat_o),
|
|
|
|
|
NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY)
|
|
|
|
|
== 0)
|
|
|
|
|
continue;
|
2017-09-04 07:10:42 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* we need to replace the existing route with a (slightly) different
|
2020-09-28 14:50:01 +02:00
|
|
|
* one. Delete it first. */
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!nm_platform_object_delete(self, plat_o)) {
|
|
|
|
|
/* ignore error. */
|
|
|
|
|
}
|
|
|
|
|
}
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
r = nm_platform_ip_route_add(self,
|
|
|
|
|
NMP_NLM_FLAG_APPEND
|
|
|
|
|
| NMP_NLM_FLAG_SUPPRESS_NETLINK_FAILURE,
|
2023-02-17 12:07:05 +01:00
|
|
|
conf_o,
|
2023-02-22 13:05:53 +01:00
|
|
|
&extack_msg);
|
2023-03-08 15:06:19 +01:00
|
|
|
if (r == 0) {
|
|
|
|
|
/* success */
|
|
|
|
|
} else if (r == -EEXIST) {
|
|
|
|
|
/* Don't fail for EEXIST. It's not clear that the existing route
|
|
|
|
|
* is identical to the one that we were about to add. However,
|
|
|
|
|
* above we should have deleted conflicting (non-identical) routes. */
|
|
|
|
|
if (_LOGD_ENABLED()) {
|
|
|
|
|
plat_entry =
|
|
|
|
|
nm_platform_lookup_entry(self, NMP_CACHE_ID_TYPE_OBJECT_TYPE, conf_o);
|
|
|
|
|
if (!plat_entry) {
|
|
|
|
|
_LOG3D("route-sync: adding route %s failed with EEXIST, however we "
|
|
|
|
|
"cannot find such a route",
|
|
|
|
|
nmp_object_to_string(conf_o,
|
|
|
|
|
NMP_OBJECT_TO_STRING_PUBLIC,
|
|
|
|
|
sbuf1,
|
|
|
|
|
sizeof(sbuf1)));
|
|
|
|
|
} else if (vt->route_cmp(NMP_OBJECT_CAST_IPX_ROUTE(conf_o),
|
|
|
|
|
NMP_OBJECT_CAST_IPX_ROUTE(plat_entry->obj),
|
|
|
|
|
NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY)
|
|
|
|
|
!= 0) {
|
|
|
|
|
_LOG3D("route-sync: adding route %s failed due to existing "
|
|
|
|
|
"(different!) route %s",
|
|
|
|
|
nmp_object_to_string(conf_o,
|
|
|
|
|
NMP_OBJECT_TO_STRING_PUBLIC,
|
|
|
|
|
sbuf1,
|
|
|
|
|
sizeof(sbuf1)),
|
|
|
|
|
nmp_object_to_string(plat_entry->obj,
|
|
|
|
|
NMP_OBJECT_TO_STRING_PUBLIC,
|
|
|
|
|
sbuf2,
|
|
|
|
|
sizeof(sbuf2)));
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
}
|
2023-03-08 15:06:19 +01:00
|
|
|
} else {
|
platform: rework handling of failed routes during nm_platform_ip_route_sync()
Previously, there was "temporary-not-available" mechanism in NML3Cfg,
which aimed to handle IPv6 routes with prefsrc. Theoretically, that
mechanism may have been extended to other use-cases, like IPv4 routes
with prefsrc. What it attempted to handle, is the inability to configure
such routes, unless the respective prefsrc address is configured and
non-tentative. However, the address that we are waiting for, could also
be on another interface, so that mechanism wasn't applicable. This is
now replaced by _routes_watch_ip_addrs(). It seems there isn't anything
useful left for the "temporary-not-available" mechanism and it can go,
except...
We want to log a warning when we are unable to configure a route. Also,
in the future we might want to know when the IP configuration is
degradated due to inability to configure the desired routes (a condition
that we might want to expose to the user, not only via logging; or we
may want to react on that).
However, with prefsrc routes we don't know right away whether the
inability to configure the route right away indicates an actual problem,
or whether that will resolve itself (e.g. after the address passes
DAD/ACD, after we received an DHCP lease or after the address was
configured on another interface). Consequently, to know whether the
current inability to configure such a route is a problem, we need to
know the larger context. nm_platform_ip_route_sync() does not have that
context.
Instead, nm_platform_ip_route_sync() needs only do debug log about
failure to configure routes. It will now also return all the failed
routes to NML3Cfg, which can decide whether that is a problem.
This reworks the previous "temporary-not-available" mechanism to track
the state of the failed routes, to eventually decide whether there is an
actual problem (and log about it).
Another problem this solves is that since commit ('platform: always
reconfigure IP routes even if removed externally'), we will eagerly
re-try to configure the same route over and over. We cannot just spam
the log with warnings about the same failure on every commit. We need to
remember that we already logged about the problem and rate limit
warnings otherwise. This is what the new mechanism also achieves.
Indeed, all this is mostly for the sole benefit of logging better
warnings (and not duplicated).
2023-03-08 16:08:23 +01:00
|
|
|
_LOG3D(
|
2023-03-08 15:12:35 +01:00
|
|
|
"route-sync: failure to add IPv%c route: %s: %s%s%s%s",
|
2023-03-08 15:06:19 +01:00
|
|
|
vt->is_ip4 ? '4' : '6',
|
|
|
|
|
nmp_object_to_string(conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof(sbuf1)),
|
2023-03-08 15:12:35 +01:00
|
|
|
nm_strerror(r),
|
|
|
|
|
NM_PRINT_FMT_QUOTED(extack_msg, " (", extack_msg, ")", ""));
|
platform: rework handling of failed routes during nm_platform_ip_route_sync()
Previously, there was "temporary-not-available" mechanism in NML3Cfg,
which aimed to handle IPv6 routes with prefsrc. Theoretically, that
mechanism may have been extended to other use-cases, like IPv4 routes
with prefsrc. What it attempted to handle, is the inability to configure
such routes, unless the respective prefsrc address is configured and
non-tentative. However, the address that we are waiting for, could also
be on another interface, so that mechanism wasn't applicable. This is
now replaced by _routes_watch_ip_addrs(). It seems there isn't anything
useful left for the "temporary-not-available" mechanism and it can go,
except...
We want to log a warning when we are unable to configure a route. Also,
in the future we might want to know when the IP configuration is
degradated due to inability to configure the desired routes (a condition
that we might want to expose to the user, not only via logging; or we
may want to react on that).
However, with prefsrc routes we don't know right away whether the
inability to configure the route right away indicates an actual problem,
or whether that will resolve itself (e.g. after the address passes
DAD/ACD, after we received an DHCP lease or after the address was
configured on another interface). Consequently, to know whether the
current inability to configure such a route is a problem, we need to
know the larger context. nm_platform_ip_route_sync() does not have that
context.
Instead, nm_platform_ip_route_sync() needs only do debug log about
failure to configure routes. It will now also return all the failed
routes to NML3Cfg, which can decide whether that is a problem.
This reworks the previous "temporary-not-available" mechanism to track
the state of the failed routes, to eventually decide whether there is an
actual problem (and log about it).
Another problem this solves is that since commit ('platform: always
reconfigure IP routes even if removed externally'), we will eagerly
re-try to configure the same route over and over. We cannot just spam
the log with warnings about the same failure on every commit. We need to
remember that we already logged about the problem and rate limit
warnings otherwise. This is what the new mechanism also achieves.
Indeed, all this is mostly for the sole benefit of logging better
warnings (and not duplicated).
2023-03-08 16:08:23 +01:00
|
|
|
|
2023-03-08 15:06:19 +01:00
|
|
|
success = FALSE;
|
platform: rework handling of failed routes during nm_platform_ip_route_sync()
Previously, there was "temporary-not-available" mechanism in NML3Cfg,
which aimed to handle IPv6 routes with prefsrc. Theoretically, that
mechanism may have been extended to other use-cases, like IPv4 routes
with prefsrc. What it attempted to handle, is the inability to configure
such routes, unless the respective prefsrc address is configured and
non-tentative. However, the address that we are waiting for, could also
be on another interface, so that mechanism wasn't applicable. This is
now replaced by _routes_watch_ip_addrs(). It seems there isn't anything
useful left for the "temporary-not-available" mechanism and it can go,
except...
We want to log a warning when we are unable to configure a route. Also,
in the future we might want to know when the IP configuration is
degradated due to inability to configure the desired routes (a condition
that we might want to expose to the user, not only via logging; or we
may want to react on that).
However, with prefsrc routes we don't know right away whether the
inability to configure the route right away indicates an actual problem,
or whether that will resolve itself (e.g. after the address passes
DAD/ACD, after we received an DHCP lease or after the address was
configured on another interface). Consequently, to know whether the
current inability to configure such a route is a problem, we need to
know the larger context. nm_platform_ip_route_sync() does not have that
context.
Instead, nm_platform_ip_route_sync() needs only do debug log about
failure to configure routes. It will now also return all the failed
routes to NML3Cfg, which can decide whether that is a problem.
This reworks the previous "temporary-not-available" mechanism to track
the state of the failed routes, to eventually decide whether there is an
actual problem (and log about it).
Another problem this solves is that since commit ('platform: always
reconfigure IP routes even if removed externally'), we will eagerly
re-try to configure the same route over and over. We cannot just spam
the log with warnings about the same failure on every commit. We need to
remember that we already logged about the problem and rate limit
warnings otherwise. This is what the new mechanism also achieves.
Indeed, all this is mostly for the sole benefit of logging better
warnings (and not duplicated).
2023-03-08 16:08:23 +01:00
|
|
|
|
|
|
|
|
if (out_routes_failed) {
|
|
|
|
|
if (!*out_routes_failed) {
|
|
|
|
|
*out_routes_failed =
|
|
|
|
|
g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref);
|
|
|
|
|
}
|
|
|
|
|
g_ptr_array_add(*out_routes_failed, (gpointer) nmp_object_ref(conf_o));
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (routes_prune) {
|
|
|
|
|
for (i = 0; i < routes_prune->len; i++) {
|
|
|
|
|
const NMPObject *prune_o;
|
|
|
|
|
|
|
|
|
|
prune_o = routes_prune->pdata[i];
|
|
|
|
|
|
2020-10-30 12:13:18 +01:00
|
|
|
nm_assert((NM_IS_IPv4(addr_family)
|
2020-09-28 16:03:33 +02:00
|
|
|
&& NMP_OBJECT_GET_TYPE(prune_o) == NMP_OBJECT_TYPE_IP4_ROUTE)
|
2020-10-30 12:13:18 +01:00
|
|
|
|| (!NM_IS_IPv4(addr_family)
|
2020-09-28 16:03:33 +02:00
|
|
|
&& NMP_OBJECT_GET_TYPE(prune_o) == NMP_OBJECT_TYPE_IP6_ROUTE));
|
|
|
|
|
|
platform: don't add routes that are tracked as external routes
Due to something that really should be fixed, NetworkManager merges the routes
that it wants to configure, with the routes that are configured externally.
This includes a subtract and merge dance, which is wrong.
Anyway. If we are in nm_platform_ip_route_sync(), then we never want to
actively configure a route, that we only have in the list because it is
(or was) present on the interface.
Otherwise we have a problem. Note that we make a plan which
routes/addresses to add/remove before starting. So, if we start with an
IPv4 address configured in kernel, then there is also a corresponding
local route. We would track that local route as external.
During sync, we first remove the IP address, and kernel automatically
also removes the local route. However, as we already made the plan to
keep that route, NetworkManager would wrongly configure it again.
This should fix that bug. It is anyway wrong to even try to explicitly
configure a route, that is purely in the list as being external.
https://bugzilla.redhat.com/show_bug.cgi?id=1979192#c11
2021-07-20 11:53:31 +02:00
|
|
|
if (nm_g_hash_table_lookup(routes_idx, prune_o))
|
2020-09-28 16:03:33 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (!nm_platform_lookup_entry(self, NMP_CACHE_ID_TYPE_OBJECT_TYPE, prune_o))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (!nm_platform_object_delete(self, prune_o)) {
|
|
|
|
|
/* ignore error... */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return success;
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_ip_route_flush(NMPlatform *self, int addr_family, int ifindex)
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
gboolean success = TRUE;
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_assert(NM_IN_SET(addr_family, AF_UNSPEC, AF_INET, AF_INET6));
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET)) {
|
|
|
|
|
gs_unref_ptrarray GPtrArray *routes_prune = NULL;
|
core: inject route list to delete for nm_platform_ip_route_sync()
Whenever we call a platform operation that reads or writes the netlink
socket, there is the possibility that the cache gets updated, as we
receive netlink events.
It is thus racy, if nm_platform_ip_route_sync() *first* adds routes, and
then obtains a list of routes to delete. The correct approach is to
determine which routes to delete first (and keep it in a list
@routes_prune), and pass that list down to nm_platform_ip_route_sync().
Arguably, this doesn't yet solve every race. For example, NMDevice
calls update_ext_ip_config() during ip4_config_merge_and_apply().
That is good, as it resyncs with platform. However, before calling
nm_ip4_config_commit() it calls other platform operations, like
_commit_mtu(). So, the race is still there.
2017-09-22 12:37:12 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
routes_prune = nm_platform_ip_route_get_prune_list(self,
|
|
|
|
|
AF_INET,
|
|
|
|
|
ifindex,
|
2021-03-22 17:31:35 +01:00
|
|
|
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE);
|
2020-09-28 16:03:33 +02:00
|
|
|
success &= nm_platform_ip_route_sync(self, AF_INET, ifindex, NULL, routes_prune, NULL);
|
|
|
|
|
}
|
|
|
|
|
if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET6)) {
|
|
|
|
|
gs_unref_ptrarray GPtrArray *routes_prune = NULL;
|
core: inject route list to delete for nm_platform_ip_route_sync()
Whenever we call a platform operation that reads or writes the netlink
socket, there is the possibility that the cache gets updated, as we
receive netlink events.
It is thus racy, if nm_platform_ip_route_sync() *first* adds routes, and
then obtains a list of routes to delete. The correct approach is to
determine which routes to delete first (and keep it in a list
@routes_prune), and pass that list down to nm_platform_ip_route_sync().
Arguably, this doesn't yet solve every race. For example, NMDevice
calls update_ext_ip_config() during ip4_config_merge_and_apply().
That is good, as it resyncs with platform. However, before calling
nm_ip4_config_commit() it calls other platform operations, like
_commit_mtu(). So, the race is still there.
2017-09-22 12:37:12 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
routes_prune = nm_platform_ip_route_get_prune_list(self,
|
|
|
|
|
AF_INET6,
|
|
|
|
|
ifindex,
|
2021-03-22 17:31:35 +01:00
|
|
|
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE);
|
2020-09-28 16:03:33 +02:00
|
|
|
success &= nm_platform_ip_route_sync(self, AF_INET6, ifindex, NULL, routes_prune, NULL);
|
|
|
|
|
}
|
|
|
|
|
return success;
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2017-08-17 15:17:40 +02:00
|
|
|
static guint8
|
2020-09-28 16:03:33 +02:00
|
|
|
_ip_route_scope_inv_get_normalized(const NMPlatformIP4Route *route)
|
2017-08-17 15:17:40 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
/* in kernel, you cannot set scope to RT_SCOPE_NOWHERE (255).
|
2020-09-28 14:50:01 +02:00
|
|
|
* That means, in NM, we treat RT_SCOPE_NOWHERE as unset, and detect
|
|
|
|
|
* it based on the presence of the gateway. In other words, when adding
|
|
|
|
|
* a route with scope RT_SCOPE_NOWHERE (in NetworkManager) to kernel,
|
|
|
|
|
* the resulting scope will be either "link" or "universe" (depending
|
|
|
|
|
* on the gateway).
|
|
|
|
|
*
|
|
|
|
|
* Note that internally, we track @scope_inv is the inverse of scope,
|
|
|
|
|
* so that the default equals zero (~(RT_SCOPE_NOWHERE)).
|
|
|
|
|
**/
|
2020-09-28 16:03:33 +02:00
|
|
|
if (route->scope_inv == 0) {
|
|
|
|
|
if (route->type_coerced == nm_platform_route_type_coerce(RTN_LOCAL))
|
|
|
|
|
return nm_platform_route_scope_inv(RT_SCOPE_HOST);
|
|
|
|
|
else {
|
|
|
|
|
return nm_platform_route_scope_inv(!route->gateway ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return route->scope_inv;
|
2017-08-17 15:17:40 +02:00
|
|
|
}
|
|
|
|
|
|
2017-10-09 11:09:16 +02:00
|
|
|
static guint8
|
2020-09-28 16:03:33 +02:00
|
|
|
_route_pref_normalize(guint8 pref)
|
2017-10-09 11:09:16 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
/* for kernel (and ICMPv6) pref can only have one of 3 values. Normalize. */
|
|
|
|
|
return NM_IN_SET(pref, NM_ICMPV6_ROUTER_PREF_LOW, NM_ICMPV6_ROUTER_PREF_HIGH)
|
|
|
|
|
? pref
|
|
|
|
|
: NM_ICMPV6_ROUTER_PREF_MEDIUM;
|
2017-10-09 11:09:16 +02:00
|
|
|
}
|
|
|
|
|
|
2017-08-17 13:37:21 +02:00
|
|
|
/**
|
|
|
|
|
* nm_platform_ip_route_normalize:
|
|
|
|
|
* @addr_family: AF_INET or AF_INET6
|
|
|
|
|
* @route: an NMPlatformIP4Route or NMPlatformIP6Route instance, depending on @addr_family.
|
|
|
|
|
*
|
|
|
|
|
* Adding a route to kernel via nm_platform_ip_route_add() will normalize/coerce some
|
|
|
|
|
* properties of the route. This function modifies (normalizes) the route like it
|
|
|
|
|
* would be done by adding the route in kernel.
|
2017-09-02 16:56:27 +02:00
|
|
|
*
|
|
|
|
|
* Note that this function is related to NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY
|
|
|
|
|
* in that if two routes compare semantically equal, after normalizing they also shall
|
|
|
|
|
* compare equal with NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL.
|
2017-08-17 13:37:21 +02:00
|
|
|
*/
|
|
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_ip_route_normalize(int addr_family, NMPlatformIPRoute *route)
|
|
|
|
|
{
|
|
|
|
|
NMPlatformIP4Route *r4;
|
|
|
|
|
NMPlatformIP6Route *r6;
|
|
|
|
|
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
route->table_coerced =
|
|
|
|
|
nm_platform_route_table_coerce(nm_platform_ip_route_get_effective_table(route));
|
|
|
|
|
route->table_any = FALSE;
|
|
|
|
|
|
|
|
|
|
route->rt_source = nmp_utils_ip_config_source_round_trip_rtprot(route->rt_source);
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
switch (addr_family) {
|
|
|
|
|
case AF_INET:
|
|
|
|
|
r4 = (NMPlatformIP4Route *) route;
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
route->metric = nm_platform_ip4_route_get_effective_metric(r4);
|
|
|
|
|
route->metric_any = FALSE;
|
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
|
|
|
r4->network = nm_ip4_addr_clear_host_address(r4->network, r4->plen);
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
r4->scope_inv = _ip_route_scope_inv_get_normalized(r4);
|
2020-09-28 16:03:33 +02:00
|
|
|
break;
|
|
|
|
|
case AF_INET6:
|
|
|
|
|
r6 = (NMPlatformIP6Route *) route;
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
route->metric = nm_platform_ip6_route_get_effective_metric(r6);
|
|
|
|
|
route->metric_any = FALSE;
|
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_ip6_addr_clear_host_address(&r6->network, &r6->network, r6->plen);
|
|
|
|
|
nm_ip6_addr_clear_host_address(&r6->src, &r6->src, r6->src_plen);
|
2020-09-28 16:03:33 +02:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
nm_assert_not_reached();
|
|
|
|
|
break;
|
|
|
|
|
}
|
2017-08-17 13:37:21 +02:00
|
|
|
}
|
|
|
|
|
|
platform: merge NMPlatformError with nm-error
Platform had it's own scheme for reporting errors: NMPlatformError.
Before, NMPlatformError indicated success via zero, negative integer
values are numbers from <errno.h>, and positive integer values are
platform specific codes. This changes now according to nm-error:
success is still zero. Negative values indicate a failure, where the
numeric value is either from <errno.h> or one of our error codes.
The meaning of positive values depends on the functions. Most functions
can only report an error reason (negative) and success (zero). For such
functions, positive values should never be returned (but the caller
should anticipate them).
For some functions, positive values could mean additional information
(but still success). That depends.
This is also what systemd does, except that systemd only returns
(negative) integers from <errno.h>, while we merge our own error codes
into the range of <errno.h>.
The advantage is to get rid of one way how to signal errors. The other
advantage is, that these error codes are compatible with all other
nm-errno values. For example, previously negative values indicated error
codes from <errno.h>, but it did not entail error codes from netlink.
2018-12-22 14:13:05 +01:00
|
|
|
static int
|
2023-02-17 12:07:05 +01:00
|
|
|
_ip_route_add(NMPlatform *self, NMPNlmFlags flags, NMPObject *obj_stack, char **out_extack_msg)
|
2013-03-27 22:23:24 +01:00
|
|
|
{
|
2022-03-30 09:23:54 +02:00
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
2020-09-28 16:03:33 +02:00
|
|
|
int ifindex;
|
2017-08-02 10:27:32 +02:00
|
|
|
|
2023-03-08 15:06:00 +01:00
|
|
|
_CHECK_SELF(self, klass, -NME_BUG);
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2022-10-18 18:53:46 +02:00
|
|
|
/* The caller already ensures that this is a stack allocated copy, that
|
|
|
|
|
* - stays alive for the duration of the call.
|
|
|
|
|
* - that the ip_route_add() implementation is allowed to modify.
|
|
|
|
|
*/
|
|
|
|
|
nm_assert(obj_stack);
|
|
|
|
|
nm_assert(NMP_OBJECT_IS_STACKINIT(obj_stack));
|
|
|
|
|
nm_assert(NM_IN_SET(NMP_OBJECT_GET_TYPE(obj_stack),
|
|
|
|
|
NMP_OBJECT_TYPE_IP4_ROUTE,
|
|
|
|
|
NMP_OBJECT_TYPE_IP6_ROUTE));
|
2023-02-17 12:07:05 +01:00
|
|
|
nm_assert(!out_extack_msg || !*out_extack_msg);
|
2022-10-18 18:53:46 +02:00
|
|
|
|
|
|
|
|
nm_assert(NMP_OBJECT_GET_TYPE(obj_stack) != NMP_OBJECT_TYPE_IP4_ROUTE
|
|
|
|
|
|| obj_stack->ip4_route.n_nexthops <= 1u || obj_stack->_ip4_route.extra_nexthops);
|
|
|
|
|
|
|
|
|
|
nm_platform_ip_route_normalize(NMP_OBJECT_GET_ADDR_FAMILY((obj_stack)),
|
|
|
|
|
NMP_OBJECT_CAST_IP_ROUTE(obj_stack));
|
|
|
|
|
|
|
|
|
|
ifindex = obj_stack->ip_route.ifindex;
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_LOG3D("route: %-10s IPv%c route: %s",
|
|
|
|
|
_nmp_nlm_flag_to_string(flags & NMP_NLM_FLAG_FMASK),
|
2022-10-18 18:53:46 +02:00
|
|
|
nm_utils_addr_family_to_char(NMP_OBJECT_GET_ADDR_FAMILY(obj_stack)),
|
|
|
|
|
nmp_object_to_string(obj_stack, NMP_OBJECT_TO_STRING_PUBLIC, sbuf, sizeof(sbuf)));
|
|
|
|
|
|
|
|
|
|
/* At this point, we pass "obj_stack" to the klass->ip_route_add() implementation.
|
|
|
|
|
* The callee can rely on:
|
|
|
|
|
* - the object being normalized and validated.
|
|
|
|
|
* - staying fully alive until the function returns. In this case it
|
|
|
|
|
* is stack allocated (and the potential "extra_nexthops" array is
|
|
|
|
|
* guaranteed to stay alive too).
|
|
|
|
|
*/
|
2023-02-17 12:07:05 +01:00
|
|
|
return klass->ip_route_add(self, flags, obj_stack, out_extack_msg);
|
2017-08-14 14:17:00 +02:00
|
|
|
}
|
|
|
|
|
|
platform: merge NMPlatformError with nm-error
Platform had it's own scheme for reporting errors: NMPlatformError.
Before, NMPlatformError indicated success via zero, negative integer
values are numbers from <errno.h>, and positive integer values are
platform specific codes. This changes now according to nm-error:
success is still zero. Negative values indicate a failure, where the
numeric value is either from <errno.h> or one of our error codes.
The meaning of positive values depends on the functions. Most functions
can only report an error reason (negative) and success (zero). For such
functions, positive values should never be returned (but the caller
should anticipate them).
For some functions, positive values could mean additional information
(but still success). That depends.
This is also what systemd does, except that systemd only returns
(negative) integers from <errno.h>, while we merge our own error codes
into the range of <errno.h>.
The advantage is to get rid of one way how to signal errors. The other
advantage is, that these error codes are compatible with all other
nm-errno values. For example, previously negative values indicated error
codes from <errno.h>, but it did not entail error codes from netlink.
2018-12-22 14:13:05 +01:00
|
|
|
int
|
2023-02-17 12:07:05 +01:00
|
|
|
nm_platform_ip_route_add(NMPlatform *self,
|
|
|
|
|
NMPNlmFlags flags,
|
|
|
|
|
const NMPObject *obj,
|
|
|
|
|
char **out_extack_msg)
|
2017-08-14 14:17:00 +02:00
|
|
|
{
|
2022-10-18 18:53:46 +02:00
|
|
|
nm_auto_nmpobj const NMPObject *obj_keep_alive = NULL;
|
|
|
|
|
NMPObject obj_stack;
|
2017-08-14 14:17:00 +02:00
|
|
|
|
2022-10-18 18:53:46 +02:00
|
|
|
nm_assert(
|
|
|
|
|
NM_IN_SET(NMP_OBJECT_GET_TYPE(obj), NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE));
|
|
|
|
|
|
|
|
|
|
nmp_object_stackinit(&obj_stack, NMP_OBJECT_GET_TYPE(obj), &obj->ip_route);
|
|
|
|
|
|
|
|
|
|
if (NMP_OBJECT_GET_TYPE(obj) == NMP_OBJECT_TYPE_IP4_ROUTE && obj->ip4_route.n_nexthops > 1u) {
|
|
|
|
|
/* Ensure @obj stays alive, so we can alias extra_nexthops from the stackallocated
|
|
|
|
|
* @obj_stack. */
|
|
|
|
|
nm_assert(obj->_ip4_route.extra_nexthops);
|
|
|
|
|
obj_keep_alive = nmp_object_ref(obj);
|
|
|
|
|
obj_stack._ip4_route.extra_nexthops = obj->_ip4_route.extra_nexthops;
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
2017-08-14 14:17:00 +02:00
|
|
|
|
2023-02-17 12:07:05 +01:00
|
|
|
return _ip_route_add(self, flags, &obj_stack, out_extack_msg);
|
2017-08-14 14:17:00 +02:00
|
|
|
}
|
|
|
|
|
|
platform: merge NMPlatformError with nm-error
Platform had it's own scheme for reporting errors: NMPlatformError.
Before, NMPlatformError indicated success via zero, negative integer
values are numbers from <errno.h>, and positive integer values are
platform specific codes. This changes now according to nm-error:
success is still zero. Negative values indicate a failure, where the
numeric value is either from <errno.h> or one of our error codes.
The meaning of positive values depends on the functions. Most functions
can only report an error reason (negative) and success (zero). For such
functions, positive values should never be returned (but the caller
should anticipate them).
For some functions, positive values could mean additional information
(but still success). That depends.
This is also what systemd does, except that systemd only returns
(negative) integers from <errno.h>, while we merge our own error codes
into the range of <errno.h>.
The advantage is to get rid of one way how to signal errors. The other
advantage is, that these error codes are compatible with all other
nm-errno values. For example, previously negative values indicated error
codes from <errno.h>, but it did not entail error codes from netlink.
2018-12-22 14:13:05 +01:00
|
|
|
int
|
2022-10-18 18:53:46 +02:00
|
|
|
nm_platform_ip4_route_add(NMPlatform *self,
|
|
|
|
|
NMPNlmFlags flags,
|
|
|
|
|
const NMPlatformIP4Route *route,
|
|
|
|
|
const NMPlatformIP4RtNextHop *extra_nexthops)
|
2017-08-14 14:17:00 +02:00
|
|
|
{
|
2022-09-15 14:03:51 +02:00
|
|
|
gs_free NMPlatformIP4RtNextHop *extra_nexthops_free = NULL;
|
|
|
|
|
NMPObject obj;
|
|
|
|
|
|
|
|
|
|
nm_assert(route);
|
|
|
|
|
nm_assert(route->n_nexthops <= 1u || extra_nexthops);
|
|
|
|
|
|
|
|
|
|
nmp_object_stackinit(&obj, NMP_OBJECT_TYPE_IP4_ROUTE, (const NMPlatformObject *) route);
|
|
|
|
|
|
|
|
|
|
if (route->n_nexthops > 1u) {
|
|
|
|
|
nm_assert(extra_nexthops);
|
|
|
|
|
/* we need to ensure that @extra_nexthops stays alive until the function returns.
|
|
|
|
|
* Copy the buffer.
|
|
|
|
|
*
|
|
|
|
|
* This is probably not necessary, because likely the caller will somehow ensure that
|
|
|
|
|
* the extra_nexthops stay alive. Still do it, because it is a very unusual case and
|
|
|
|
|
* likely cheap. */
|
|
|
|
|
obj._ip4_route.extra_nexthops =
|
|
|
|
|
nm_memdup_maybe_a(500u,
|
|
|
|
|
extra_nexthops,
|
|
|
|
|
sizeof(extra_nexthops[0]) * (route->n_nexthops - 1u),
|
|
|
|
|
&extra_nexthops_free);
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-17 12:07:05 +01:00
|
|
|
return _ip_route_add(self, flags, &obj, NULL);
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
platform: merge NMPlatformError with nm-error
Platform had it's own scheme for reporting errors: NMPlatformError.
Before, NMPlatformError indicated success via zero, negative integer
values are numbers from <errno.h>, and positive integer values are
platform specific codes. This changes now according to nm-error:
success is still zero. Negative values indicate a failure, where the
numeric value is either from <errno.h> or one of our error codes.
The meaning of positive values depends on the functions. Most functions
can only report an error reason (negative) and success (zero). For such
functions, positive values should never be returned (but the caller
should anticipate them).
For some functions, positive values could mean additional information
(but still success). That depends.
This is also what systemd does, except that systemd only returns
(negative) integers from <errno.h>, while we merge our own error codes
into the range of <errno.h>.
The advantage is to get rid of one way how to signal errors. The other
advantage is, that these error codes are compatible with all other
nm-errno values. For example, previously negative values indicated error
codes from <errno.h>, but it did not entail error codes from netlink.
2018-12-22 14:13:05 +01:00
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_ip6_route_add(NMPlatform *self, NMPNlmFlags flags, const NMPlatformIP6Route *route)
|
2013-03-27 22:23:24 +01:00
|
|
|
{
|
2022-10-18 18:53:46 +02:00
|
|
|
NMPObject obj;
|
|
|
|
|
|
|
|
|
|
nmp_object_stackinit(&obj, NMP_OBJECT_TYPE_IP6_ROUTE, (const NMPlatformObject *) route);
|
2023-02-17 12:07:05 +01:00
|
|
|
return _ip_route_add(self, flags, &obj, NULL);
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_object_delete(NMPlatform *self, const NMPObject *obj)
|
|
|
|
|
{
|
2022-03-30 08:47:34 +02:00
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
|
|
|
|
int ifindex;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
|
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
|
|
|
|
|
2022-07-14 22:19:47 +02:00
|
|
|
if (_LOGD_ENABLED()) {
|
|
|
|
|
switch (NMP_OBJECT_GET_TYPE(obj)) {
|
|
|
|
|
case NMP_OBJECT_TYPE_ROUTING_RULE:
|
|
|
|
|
case NMP_OBJECT_TYPE_MPTCP_ADDR:
|
|
|
|
|
_LOGD("%s: delete %s",
|
|
|
|
|
NMP_OBJECT_GET_CLASS(obj)->obj_type_name,
|
|
|
|
|
nmp_object_to_string(obj, NMP_OBJECT_TO_STRING_PUBLIC, sbuf, sizeof(sbuf)));
|
|
|
|
|
break;
|
|
|
|
|
case NMP_OBJECT_TYPE_IP4_ROUTE:
|
|
|
|
|
case NMP_OBJECT_TYPE_IP6_ROUTE:
|
|
|
|
|
case NMP_OBJECT_TYPE_QDISC:
|
|
|
|
|
case NMP_OBJECT_TYPE_TFILTER:
|
|
|
|
|
ifindex = NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj)->ifindex;
|
|
|
|
|
_LOG3D("%s: delete %s",
|
|
|
|
|
NMP_OBJECT_GET_CLASS(obj)->obj_type_name,
|
|
|
|
|
nmp_object_to_string(obj, NMP_OBJECT_TO_STRING_PUBLIC, sbuf, sizeof(sbuf)));
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
g_return_val_if_reached(FALSE);
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return klass->object_delete(self, obj);
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2013-03-27 22:23:24 +01:00
|
|
|
|
platform: merge NMPlatformError with nm-error
Platform had it's own scheme for reporting errors: NMPlatformError.
Before, NMPlatformError indicated success via zero, negative integer
values are numbers from <errno.h>, and positive integer values are
platform specific codes. This changes now according to nm-error:
success is still zero. Negative values indicate a failure, where the
numeric value is either from <errno.h> or one of our error codes.
The meaning of positive values depends on the functions. Most functions
can only report an error reason (negative) and success (zero). For such
functions, positive values should never be returned (but the caller
should anticipate them).
For some functions, positive values could mean additional information
(but still success). That depends.
This is also what systemd does, except that systemd only returns
(negative) integers from <errno.h>, while we merge our own error codes
into the range of <errno.h>.
The advantage is to get rid of one way how to signal errors. The other
advantage is, that these error codes are compatible with all other
nm-errno values. For example, previously negative values indicated error
codes from <errno.h>, but it did not entail error codes from netlink.
2018-12-22 14:13:05 +01:00
|
|
|
int
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_ip_route_get(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
int addr_family,
|
|
|
|
|
gconstpointer address /* in_addr_t or struct in6_addr */,
|
|
|
|
|
int oif_ifindex,
|
2021-11-09 13:28:54 +01:00
|
|
|
NMPObject **out_route)
|
2020-09-28 16:03:33 +02:00
|
|
|
{
|
2022-03-30 08:47:34 +02:00
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_auto_nmpobj NMPObject *route = NULL;
|
|
|
|
|
int result;
|
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 buf[NM_INET_ADDRSTRLEN];
|
2020-09-28 16:03:33 +02:00
|
|
|
char buf_oif[64];
|
|
|
|
|
|
|
|
|
|
_CHECK_SELF(self, klass, FALSE);
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail(address, -NME_BUG);
|
|
|
|
|
g_return_val_if_fail(NM_IN_SET(addr_family, AF_INET, AF_INET6), -NME_BUG);
|
|
|
|
|
|
|
|
|
|
_LOGT("route: get IPv%c route for: %s%s",
|
|
|
|
|
nm_utils_addr_family_to_char(addr_family),
|
|
|
|
|
inet_ntop(addr_family, address, buf, sizeof(buf)),
|
|
|
|
|
oif_ifindex > 0 ? nm_sprintf_buf(buf_oif, " oif %d", oif_ifindex) : "");
|
|
|
|
|
|
|
|
|
|
if (!klass->ip_route_get)
|
|
|
|
|
result = -NME_PL_OPNOTSUPP;
|
|
|
|
|
else {
|
|
|
|
|
result = klass->ip_route_get(self, addr_family, address, oif_ifindex, &route);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (result < 0) {
|
|
|
|
|
nm_assert(!route);
|
|
|
|
|
_LOGW("route: get IPv%c route for: %s failed with %s",
|
|
|
|
|
nm_utils_addr_family_to_char(addr_family),
|
|
|
|
|
inet_ntop(addr_family, address, buf, sizeof(buf)),
|
|
|
|
|
nm_strerror(result));
|
|
|
|
|
} else {
|
|
|
|
|
nm_assert(NM_IN_SET(NMP_OBJECT_GET_TYPE(route),
|
|
|
|
|
NMP_OBJECT_TYPE_IP4_ROUTE,
|
|
|
|
|
NMP_OBJECT_TYPE_IP6_ROUTE));
|
|
|
|
|
nm_assert(!NMP_OBJECT_IS_STACKINIT(route));
|
|
|
|
|
nm_assert(route->parent._ref_count == 1);
|
|
|
|
|
_LOGD("route: get IPv%c route for: %s succeeded: %s",
|
|
|
|
|
nm_utils_addr_family_to_char(addr_family),
|
|
|
|
|
inet_ntop(addr_family, address, buf, sizeof(buf)),
|
2022-03-30 08:47:34 +02:00
|
|
|
nmp_object_to_string(route, NMP_OBJECT_TO_STRING_PUBLIC, sbuf, sizeof(sbuf)));
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_SET_OUT(out_route, g_steal_pointer(&route));
|
|
|
|
|
}
|
|
|
|
|
return result;
|
2017-08-16 16:13:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
#define IP4_DEV_ROUTE_BLACKLIST_TIMEOUT_MS ((int) 1500)
|
|
|
|
|
#define IP4_DEV_ROUTE_BLACKLIST_GC_TIMEOUT_S \
|
|
|
|
|
((int) (((IP4_DEV_ROUTE_BLACKLIST_TIMEOUT_MS + 999) * 3) / 1000))
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
|
|
|
|
static gint64
|
2020-09-28 16:03:33 +02:00
|
|
|
_ip4_dev_route_blacklist_timeout_ms_get(gint64 timeout_msec)
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return timeout_msec >> 1;
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gint64
|
2020-09-28 16:03:33 +02:00
|
|
|
_ip4_dev_route_blacklist_timeout_ms_marked(gint64 timeout_msec)
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return !!(timeout_msec & ((gint64) 1));
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
_ip4_dev_route_blacklist_check_cb(gpointer user_data)
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
{
|
2022-03-30 08:47:34 +02:00
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
2021-11-09 13:28:54 +01:00
|
|
|
NMPlatform *self = user_data;
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self);
|
|
|
|
|
GHashTableIter iter;
|
2021-11-09 13:28:54 +01:00
|
|
|
const NMPObject *p_obj;
|
|
|
|
|
gint64 *p_timeout_ms;
|
2020-09-28 16:03:33 +02:00
|
|
|
gint64 now_ms;
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
priv->ip4_dev_route_blacklist_check_id = 0;
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
|
|
|
|
again:
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!priv->ip4_dev_route_blacklist_hash)
|
|
|
|
|
goto out;
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
now_ms = nm_utils_get_monotonic_timestamp_msec();
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_hash_table_iter_init(&iter, priv->ip4_dev_route_blacklist_hash);
|
|
|
|
|
while (g_hash_table_iter_next(&iter, (gpointer *) &p_obj, (gpointer *) &p_timeout_ms)) {
|
|
|
|
|
if (!_ip4_dev_route_blacklist_timeout_ms_marked(*p_timeout_ms))
|
|
|
|
|
continue;
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* unmark because we checked it. */
|
|
|
|
|
*p_timeout_ms = *p_timeout_ms & ~((gint64) 1);
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (now_ms > _ip4_dev_route_blacklist_timeout_ms_get(*p_timeout_ms))
|
|
|
|
|
continue;
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!nm_platform_lookup_entry(self, NMP_CACHE_ID_TYPE_OBJECT_TYPE, p_obj))
|
|
|
|
|
continue;
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_LOGT("ip4-dev-route: delete %s",
|
2022-03-30 08:47:34 +02:00
|
|
|
nmp_object_to_string(p_obj, NMP_OBJECT_TO_STRING_PUBLIC, sbuf, sizeof(sbuf)));
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_object_delete(self, p_obj);
|
|
|
|
|
goto again;
|
|
|
|
|
}
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
|
|
|
|
out:
|
2020-09-28 16:03:33 +02:00
|
|
|
return G_SOURCE_REMOVE;
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2020-09-28 16:03:33 +02:00
|
|
|
_ip4_dev_route_blacklist_check_schedule(NMPlatform *self)
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self);
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!priv->ip4_dev_route_blacklist_check_id) {
|
|
|
|
|
priv->ip4_dev_route_blacklist_check_id =
|
|
|
|
|
g_idle_add_full(G_PRIORITY_HIGH, _ip4_dev_route_blacklist_check_cb, self, NULL);
|
|
|
|
|
}
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2020-09-28 16:03:33 +02:00
|
|
|
_ip4_dev_route_blacklist_notify_route(NMPlatform *self, const NMPObject *obj)
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPlatformPrivate *priv;
|
2021-11-09 13:28:54 +01:00
|
|
|
const NMPObject *p_obj;
|
|
|
|
|
gint64 *p_timeout_ms;
|
2020-09-28 16:03:33 +02:00
|
|
|
gint64 now_ms;
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_assert(NM_IS_PLATFORM(self));
|
|
|
|
|
nm_assert(NMP_OBJECT_GET_TYPE(obj) == NMP_OBJECT_TYPE_IP4_ROUTE);
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
priv = NM_PLATFORM_GET_PRIVATE(self);
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_assert(priv->ip4_dev_route_blacklist_gc_timeout_id);
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!g_hash_table_lookup_extended(priv->ip4_dev_route_blacklist_hash,
|
|
|
|
|
obj,
|
|
|
|
|
(gpointer *) &p_obj,
|
|
|
|
|
(gpointer *) &p_timeout_ms))
|
|
|
|
|
return;
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
now_ms = nm_utils_get_monotonic_timestamp_msec();
|
|
|
|
|
if (now_ms > _ip4_dev_route_blacklist_timeout_ms_get(*p_timeout_ms)) {
|
|
|
|
|
/* already expired. Wait for gc. */
|
|
|
|
|
return;
|
|
|
|
|
}
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (_ip4_dev_route_blacklist_timeout_ms_marked(*p_timeout_ms)) {
|
|
|
|
|
nm_assert(priv->ip4_dev_route_blacklist_check_id);
|
|
|
|
|
return;
|
|
|
|
|
}
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* We cannot delete it right away because we are in the process of receiving netlink messages.
|
2020-09-28 14:50:01 +02:00
|
|
|
* It may be possible to do so, but complicated and error prone.
|
|
|
|
|
*
|
|
|
|
|
* Instead, we mark the entry and schedule an idle action (with high priority). */
|
2020-09-28 16:03:33 +02:00
|
|
|
*p_timeout_ms = (*p_timeout_ms) | ((gint64) 1);
|
|
|
|
|
_ip4_dev_route_blacklist_check_schedule(self);
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
_ip4_dev_route_blacklist_gc_timeout_handle(gpointer user_data)
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
{
|
2022-03-30 08:47:34 +02:00
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
2021-11-09 13:28:54 +01:00
|
|
|
NMPlatform *self = user_data;
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self);
|
|
|
|
|
GHashTableIter iter;
|
2021-11-09 13:28:54 +01:00
|
|
|
const NMPObject *p_obj;
|
|
|
|
|
gint64 *p_timeout_ms;
|
2020-09-28 16:03:33 +02:00
|
|
|
gint64 now_ms;
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_assert(priv->ip4_dev_route_blacklist_gc_timeout_id);
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
now_ms = nm_utils_get_monotonic_timestamp_msec();
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_hash_table_iter_init(&iter, priv->ip4_dev_route_blacklist_hash);
|
|
|
|
|
while (g_hash_table_iter_next(&iter, (gpointer *) &p_obj, (gpointer *) &p_timeout_ms)) {
|
|
|
|
|
if (now_ms > _ip4_dev_route_blacklist_timeout_ms_get(*p_timeout_ms)) {
|
|
|
|
|
_LOGT("ip4-dev-route: cleanup %s",
|
2022-03-30 08:47:34 +02:00
|
|
|
nmp_object_to_string(p_obj, NMP_OBJECT_TO_STRING_PUBLIC, sbuf, sizeof(sbuf)));
|
2020-09-28 16:03:33 +02:00
|
|
|
g_hash_table_iter_remove(&iter);
|
|
|
|
|
}
|
|
|
|
|
}
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_ip4_dev_route_blacklist_schedule(self);
|
|
|
|
|
return G_SOURCE_CONTINUE;
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2020-09-28 16:03:33 +02:00
|
|
|
_ip4_dev_route_blacklist_schedule(NMPlatform *self)
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self);
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!priv->ip4_dev_route_blacklist_hash
|
|
|
|
|
|| g_hash_table_size(priv->ip4_dev_route_blacklist_hash) == 0) {
|
|
|
|
|
nm_clear_pointer(&priv->ip4_dev_route_blacklist_hash, g_hash_table_unref);
|
|
|
|
|
nm_clear_g_source(&priv->ip4_dev_route_blacklist_gc_timeout_id);
|
|
|
|
|
} else {
|
|
|
|
|
if (!priv->ip4_dev_route_blacklist_gc_timeout_id) {
|
|
|
|
|
/* this timeout is only to garbage collect the expired entries from priv->ip4_dev_route_blacklist_hash.
|
2020-09-28 14:50:01 +02:00
|
|
|
* It can run infrequently, and it doesn't hurt if expired entries linger around a bit
|
|
|
|
|
* longer then necessary. */
|
2020-09-28 16:03:33 +02:00
|
|
|
priv->ip4_dev_route_blacklist_gc_timeout_id =
|
|
|
|
|
g_timeout_add_seconds(IP4_DEV_ROUTE_BLACKLIST_GC_TIMEOUT_S,
|
|
|
|
|
_ip4_dev_route_blacklist_gc_timeout_handle,
|
|
|
|
|
self);
|
|
|
|
|
}
|
|
|
|
|
}
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_platform_ip4_dev_route_blacklist_set:
|
|
|
|
|
* @self:
|
|
|
|
|
* @ifindex:
|
|
|
|
|
* @ip4_dev_route_blacklist:
|
|
|
|
|
*
|
|
|
|
|
* When adding an IP address, kernel automatically adds a device route.
|
2017-08-17 17:20:14 +02:00
|
|
|
* This can be suppressed via the IFA_F_NOPREFIXROUTE address flag. For proper
|
|
|
|
|
* IPv6 support, we require kernel support for IFA_F_NOPREFIXROUTE and always
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
* add the device route manually.
|
|
|
|
|
*
|
|
|
|
|
* For IPv4, this flag is rather new and we don't rely on it yet. We want to use
|
|
|
|
|
* it (but currently still don't). So, for IPv4, kernel possibly adds a device
|
|
|
|
|
* route, however it has a wrong metric of zero. We add our own device route (with
|
|
|
|
|
* proper metric), but need to delete the route that kernel adds.
|
|
|
|
|
*
|
2018-09-14 23:49:20 -04:00
|
|
|
* The problem is, that kernel does not immediately add the route, when adding
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
* the address. It only shows up some time later. So, we register here a list
|
|
|
|
|
* of blacklisted routes, and when they show up within a time out, we assume it's
|
|
|
|
|
* the kernel generated one, and we delete it.
|
|
|
|
|
*
|
|
|
|
|
* Eventually, we want to get rid of this and use IFA_F_NOPREFIXROUTE for IPv4
|
|
|
|
|
* routes as well.
|
|
|
|
|
*/
|
|
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_ip4_dev_route_blacklist_set(NMPlatform *self,
|
|
|
|
|
int ifindex,
|
2021-11-09 13:28:54 +01:00
|
|
|
GPtrArray *ip4_dev_route_blacklist)
|
2020-09-28 16:03:33 +02:00
|
|
|
{
|
2022-03-30 08:47:34 +02:00
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPlatformPrivate *priv;
|
|
|
|
|
GHashTableIter iter;
|
2021-11-09 13:28:54 +01:00
|
|
|
const NMPObject *p_obj;
|
2020-09-28 16:03:33 +02:00
|
|
|
guint i;
|
|
|
|
|
gint64 timeout_msec;
|
|
|
|
|
gint64 timeout_msec_val;
|
2021-11-09 13:28:54 +01:00
|
|
|
gint64 *p_timeout_ms;
|
2020-09-28 16:03:33 +02:00
|
|
|
gboolean needs_check = FALSE;
|
|
|
|
|
|
|
|
|
|
nm_assert(NM_IS_PLATFORM(self));
|
|
|
|
|
nm_assert(ifindex > 0);
|
|
|
|
|
|
|
|
|
|
/* TODO: the blacklist should be maintained by NML3Cfg. */
|
|
|
|
|
|
|
|
|
|
priv = NM_PLATFORM_GET_PRIVATE(self);
|
|
|
|
|
|
|
|
|
|
/* first, expire all for current ifindex... */
|
|
|
|
|
if (priv->ip4_dev_route_blacklist_hash) {
|
|
|
|
|
g_hash_table_iter_init(&iter, priv->ip4_dev_route_blacklist_hash);
|
|
|
|
|
while (g_hash_table_iter_next(&iter, (gpointer *) &p_obj, (gpointer *) &p_timeout_ms)) {
|
|
|
|
|
if (NMP_OBJECT_CAST_IP4_ROUTE(p_obj)->ifindex == ifindex) {
|
|
|
|
|
/* we could g_hash_table_iter_remove(&iter) the current entry.
|
2020-09-28 14:50:01 +02:00
|
|
|
* Instead, just expire it and let _ip4_dev_route_blacklist_gc_timeout_handle()
|
|
|
|
|
* handle it.
|
|
|
|
|
*
|
|
|
|
|
* The assumption is, that ip4_dev_route_blacklist contains the very same entry
|
|
|
|
|
* again, with a new timeout. So, we can un-expire it below. */
|
2020-09-28 16:03:33 +02:00
|
|
|
*p_timeout_ms = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ip4_dev_route_blacklist && ip4_dev_route_blacklist->len > 0) {
|
|
|
|
|
if (!priv->ip4_dev_route_blacklist_hash) {
|
|
|
|
|
priv->ip4_dev_route_blacklist_hash =
|
|
|
|
|
g_hash_table_new_full((GHashFunc) nmp_object_id_hash,
|
|
|
|
|
(GEqualFunc) nmp_object_id_equal,
|
|
|
|
|
(GDestroyNotify) nmp_object_unref,
|
|
|
|
|
nm_g_slice_free_fcn_gint64);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
timeout_msec = nm_utils_get_monotonic_timestamp_msec() + IP4_DEV_ROUTE_BLACKLIST_TIMEOUT_MS;
|
|
|
|
|
timeout_msec_val = (timeout_msec << 1) | ((gint64) 1);
|
|
|
|
|
for (i = 0; i < ip4_dev_route_blacklist->len; i++) {
|
|
|
|
|
const NMPObject *o;
|
|
|
|
|
|
|
|
|
|
needs_check = TRUE;
|
|
|
|
|
o = ip4_dev_route_blacklist->pdata[i];
|
|
|
|
|
if (g_hash_table_lookup_extended(priv->ip4_dev_route_blacklist_hash,
|
|
|
|
|
o,
|
|
|
|
|
(gpointer *) &p_obj,
|
|
|
|
|
(gpointer *) &p_timeout_ms)) {
|
|
|
|
|
if (nmp_object_equal(p_obj, o)) {
|
|
|
|
|
/* un-expire and reuse the entry. */
|
|
|
|
|
_LOGT("ip4-dev-route: register %s (update)",
|
2022-03-30 08:47:34 +02:00
|
|
|
nmp_object_to_string(p_obj,
|
|
|
|
|
NMP_OBJECT_TO_STRING_PUBLIC,
|
|
|
|
|
sbuf,
|
|
|
|
|
sizeof(sbuf)));
|
2020-09-28 16:03:33 +02:00
|
|
|
*p_timeout_ms = timeout_msec_val;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_LOGT("ip4-dev-route: register %s",
|
2022-03-30 08:47:34 +02:00
|
|
|
nmp_object_to_string(o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf, sizeof(sbuf)));
|
2020-09-28 16:03:33 +02:00
|
|
|
p_timeout_ms = g_slice_new(gint64);
|
|
|
|
|
*p_timeout_ms = timeout_msec_val;
|
|
|
|
|
g_hash_table_replace(priv->ip4_dev_route_blacklist_hash,
|
|
|
|
|
(gpointer) nmp_object_ref(o),
|
|
|
|
|
p_timeout_ms);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_ip4_dev_route_blacklist_schedule(self);
|
|
|
|
|
|
|
|
|
|
if (needs_check)
|
|
|
|
|
_ip4_dev_route_blacklist_check_schedule(self);
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
2019-03-05 12:13:04 +01:00
|
|
|
|
|
|
|
|
int
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_routing_rule_add(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPNlmFlags flags,
|
|
|
|
|
const NMPlatformRoutingRule *routing_rule)
|
2019-03-05 12:13:04 +01:00
|
|
|
{
|
2022-03-30 08:47:34 +02:00
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, -NME_BUG);
|
2019-03-05 12:13:04 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(routing_rule, -NME_BUG);
|
2019-03-05 12:13:04 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_LOGD("routing-rule: adding or updating: %s",
|
2022-03-30 08:47:34 +02:00
|
|
|
nm_platform_routing_rule_to_string(routing_rule, sbuf, sizeof(sbuf)));
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->routing_rule_add(self, flags, routing_rule);
|
2019-03-05 12:13:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
platform: add non-exclusive routes and drop route-manager
Previously, we would add exclusive routes via netlink message flags
NLM_F_CREATE | NLM_F_REPLACE for RTM_NEWROUTE. Similar to `ip route replace`.
Using that form of RTM_NEWROUTE message, we could only add a certain
route with a certain network/plen,metric triple once. That was already
hugely inconvenient, because
- when configuring routes, multiple (managed) interfaces may get
conflicting routes (multihoming). Only one of the routes can be actually
configured using `ip route replace`, so we need to track routes that are
currently shadowed.
- when configuring routes, we might replace externally configured
routes on unmanaged interfaces. We should not interfere with such
routes.
That was worked around by having NMRouteManager (and NMDefaultRouteManager).
NMRouteManager would keep a list of the routes which NetworkManager would like
to configure, even if momentarily being unable to do so due to conflicting routes.
This worked mostly well but was complicated. It involved bumping metrics to
avoid conflicts for device routes, as we might require them for gateway routes.
Drop that now. Instead, use the corresponding of `ip route append` to configure
routes. This allows NetworkManager to confiure (almost) all routes that we care.
Especially, it can configure all routes on a managed interface, without
replacing/interfering with routes on other interfaces. Hence, NMRouteManager
becomes obsolete.
It practice it is a bit more complicated because:
- when adding an IPv4 address, kernel will automatically create a device route
for the subnet. We should avoid that by using the IFA_F_NOPREFIXROUTE flag for
IPv4 addresses (still to-do). But as kernel may not support that flag for IPv4
addresses yet (and we don't require such a kernel yet), we still need functionality
similar to nm_route_manager_ip4_route_register_device_route_purge_list().
This functionality is now handled via nm_platform_ip4_dev_route_blacklist_set().
- trying to configure an IPv6 route with a source address will be rejected
by kernel as long as the address is tentative (see related bug rh#1457196).
Preferably, NMDevice would keep the list of routes which should be configured,
while kernel would have the list of what actually is configured. There is a
feed-back loop where both affect each other (for example, when externally deleting
a route, NMDevice must forget about it too). Previously, NMRouteManager would have
the task of remembering all routes which we currently want to configure, but cannot
due to conflicting routes.
We get rid of that, because now we configure non-exclusive routes. We however still
will need to remember IPv6 routes with a source address, that currently cannot be
configured yet. Hence, we will need to keep track of routes that
currently cannot be configured, but later may be.
That is still not done yet, as NMRouteManager didn't handle this
correctly either.
2017-08-14 14:18:53 +02:00
|
|
|
|
platform: merge NMPlatformError with nm-error
Platform had it's own scheme for reporting errors: NMPlatformError.
Before, NMPlatformError indicated success via zero, negative integer
values are numbers from <errno.h>, and positive integer values are
platform specific codes. This changes now according to nm-error:
success is still zero. Negative values indicate a failure, where the
numeric value is either from <errno.h> or one of our error codes.
The meaning of positive values depends on the functions. Most functions
can only report an error reason (negative) and success (zero). For such
functions, positive values should never be returned (but the caller
should anticipate them).
For some functions, positive values could mean additional information
(but still success). That depends.
This is also what systemd does, except that systemd only returns
(negative) integers from <errno.h>, while we merge our own error codes
into the range of <errno.h>.
The advantage is to get rid of one way how to signal errors. The other
advantage is, that these error codes are compatible with all other
nm-errno values. For example, previously negative values indicated error
codes from <errno.h>, but it did not entail error codes from netlink.
2018-12-22 14:13:05 +01:00
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_qdisc_add(NMPlatform *self, NMPNlmFlags flags, const NMPlatformQdisc *qdisc)
|
2017-11-15 20:36:35 +01:00
|
|
|
{
|
2022-03-30 08:47:34 +02:00
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
|
|
|
|
int ifindex = qdisc->ifindex;
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, -NME_BUG);
|
2017-11-15 20:36:35 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* Note: @qdisc must not be copied or kept alive because the lifetime of qdisc.kind
|
2020-09-28 14:50:01 +02:00
|
|
|
* is undefined. */
|
2019-05-01 16:35:29 +02:00
|
|
|
|
2022-03-30 08:47:34 +02:00
|
|
|
_LOG3D("adding or updating a qdisc: %s",
|
|
|
|
|
nm_platform_qdisc_to_string(qdisc, sbuf, sizeof(sbuf)));
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->qdisc_add(self, flags, qdisc);
|
2017-11-15 20:36:35 +01:00
|
|
|
}
|
|
|
|
|
|
2021-09-14 17:46:02 +02:00
|
|
|
int
|
|
|
|
|
nm_platform_qdisc_delete(NMPlatform *self, int ifindex, guint32 parent, gboolean log_error)
|
|
|
|
|
{
|
|
|
|
|
_CHECK_SELF(self, klass, -NME_BUG);
|
|
|
|
|
|
|
|
|
|
_LOG3D("deleting a qdisc: parent 0x%08x", parent);
|
|
|
|
|
return klass->qdisc_delete(self, ifindex, parent, log_error);
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-15 20:36:35 +01:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
platform: merge NMPlatformError with nm-error
Platform had it's own scheme for reporting errors: NMPlatformError.
Before, NMPlatformError indicated success via zero, negative integer
values are numbers from <errno.h>, and positive integer values are
platform specific codes. This changes now according to nm-error:
success is still zero. Negative values indicate a failure, where the
numeric value is either from <errno.h> or one of our error codes.
The meaning of positive values depends on the functions. Most functions
can only report an error reason (negative) and success (zero). For such
functions, positive values should never be returned (but the caller
should anticipate them).
For some functions, positive values could mean additional information
(but still success). That depends.
This is also what systemd does, except that systemd only returns
(negative) integers from <errno.h>, while we merge our own error codes
into the range of <errno.h>.
The advantage is to get rid of one way how to signal errors. The other
advantage is, that these error codes are compatible with all other
nm-errno values. For example, previously negative values indicated error
codes from <errno.h>, but it did not entail error codes from netlink.
2018-12-22 14:13:05 +01:00
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_tfilter_add(NMPlatform *self, NMPNlmFlags flags, const NMPlatformTfilter *tfilter)
|
2017-11-15 20:36:35 +01:00
|
|
|
{
|
2022-03-30 08:47:34 +02:00
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
|
|
|
|
int ifindex = tfilter->ifindex;
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, -NME_BUG);
|
2017-11-15 20:36:35 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* Note: @tfilter must not be copied or kept alive because the lifetime of tfilter.kind
|
2020-09-28 14:50:01 +02:00
|
|
|
* and tfilter.action.kind is undefined. */
|
2019-05-01 16:35:29 +02:00
|
|
|
|
2022-03-30 08:47:34 +02:00
|
|
|
_LOG3D("adding or updating a tfilter: %s",
|
|
|
|
|
nm_platform_tfilter_to_string(tfilter, sbuf, sizeof(sbuf)));
|
2020-09-28 16:03:33 +02:00
|
|
|
return klass->tfilter_add(self, flags, tfilter);
|
2017-11-15 20:36:35 +01:00
|
|
|
}
|
|
|
|
|
|
2021-09-14 17:46:02 +02:00
|
|
|
int
|
|
|
|
|
nm_platform_tfilter_delete(NMPlatform *self, int ifindex, guint32 parent, gboolean log_error)
|
|
|
|
|
{
|
|
|
|
|
_CHECK_SELF(self, klass, -NME_BUG);
|
|
|
|
|
|
|
|
|
|
_LOG3D("deleting a tfilter: parent 0x%08x", parent);
|
|
|
|
|
return klass->tfilter_delete(self, ifindex, parent, log_error);
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-01 16:35:29 +02:00
|
|
|
/**
|
2021-09-14 17:48:09 +02:00
|
|
|
* nm_platform_tc_sync:
|
2019-05-01 16:35:29 +02:00
|
|
|
* @self: the #NMPlatform instance
|
2021-09-14 17:48:09 +02:00
|
|
|
* @ifindex: the ifindex where to configure qdiscs and filters.
|
|
|
|
|
* @known_qdiscs: the list of qdiscs (#NMPObject).
|
2019-05-01 16:35:29 +02:00
|
|
|
* @known_tfilters: the list of tfilters (#NMPObject).
|
|
|
|
|
*
|
2021-09-14 17:48:09 +02:00
|
|
|
* The function promises not to take any reference to the
|
|
|
|
|
* instances from @known_qdiscs and @known_tfilters, nor to
|
|
|
|
|
* keep them around after the function returns. This is important,
|
|
|
|
|
* because it allows the caller to pass NMPlatformQdisc and
|
|
|
|
|
* NMPlatformTfilter instances which "kind" string have a limited
|
|
|
|
|
* lifetime.
|
2019-05-01 16:35:29 +02:00
|
|
|
*
|
|
|
|
|
* Returns: %TRUE on success.
|
|
|
|
|
*/
|
2017-11-15 20:36:35 +01:00
|
|
|
gboolean
|
2021-09-14 17:48:09 +02:00
|
|
|
nm_platform_tc_sync(NMPlatform *self,
|
|
|
|
|
int ifindex,
|
2021-11-09 13:28:54 +01:00
|
|
|
GPtrArray *known_qdiscs,
|
|
|
|
|
GPtrArray *known_tfilters)
|
2017-11-15 20:36:35 +01:00
|
|
|
{
|
2021-09-14 17:48:09 +02:00
|
|
|
guint i;
|
|
|
|
|
gboolean success = TRUE;
|
2017-11-15 20:36:35 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_assert(NM_IS_PLATFORM(self));
|
|
|
|
|
nm_assert(ifindex > 0);
|
2017-11-15 20:36:35 +01:00
|
|
|
|
2021-09-14 17:48:09 +02:00
|
|
|
nm_platform_qdisc_delete(self, ifindex, TC_H_ROOT, FALSE);
|
|
|
|
|
nm_platform_qdisc_delete(self, ifindex, TC_H_INGRESS, FALSE);
|
2017-11-15 20:36:35 +01:00
|
|
|
|
2021-09-14 17:48:09 +02:00
|
|
|
/* At this point we can only have a root default qdisc
|
|
|
|
|
* (which can't be deleted). Ensure it doesn't have any
|
|
|
|
|
* filters attached.
|
|
|
|
|
*/
|
|
|
|
|
nm_platform_tfilter_delete(self, ifindex, TC_H_ROOT, FALSE);
|
2017-11-15 20:36:35 +01:00
|
|
|
|
2021-09-14 17:48:09 +02:00
|
|
|
if (known_qdiscs) {
|
|
|
|
|
for (i = 0; i < known_qdiscs->len; i++) {
|
|
|
|
|
const NMPObject *q = g_ptr_array_index(known_qdiscs, i);
|
2017-11-15 20:36:35 +01:00
|
|
|
|
2021-09-14 17:48:09 +02:00
|
|
|
success &=
|
|
|
|
|
(nm_platform_qdisc_add(self, NMP_NLM_FLAG_ADD, NMP_OBJECT_CAST_QDISC(q)) >= 0);
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
}
|
2017-11-15 20:36:35 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (known_tfilters) {
|
|
|
|
|
for (i = 0; i < known_tfilters->len; i++) {
|
|
|
|
|
const NMPObject *q = g_ptr_array_index(known_tfilters, i);
|
2017-11-15 20:36:35 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
success &=
|
|
|
|
|
(nm_platform_tfilter_add(self, NMP_NLM_FLAG_ADD, NMP_OBJECT_CAST_TFILTER(q)) >= 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-11-15 20:36:35 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return success;
|
2017-11-15 20:36:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2015-10-27 16:14:54 +01:00
|
|
|
const char *
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_vlan_qos_mapping_to_string(const char *name,
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMVlanQosMapping *map,
|
|
|
|
|
gsize n_map,
|
2021-11-09 13:28:54 +01:00
|
|
|
char *buf,
|
2020-09-28 16:03:33 +02:00
|
|
|
gsize len)
|
2015-10-27 16:14:54 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
gsize i;
|
|
|
|
|
char *b;
|
2015-10-27 16:14:54 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_utils_to_string_buffer_init(&buf, &len);
|
2015-10-27 16:14:54 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!n_map) {
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&buf, &len, "");
|
2020-09-28 16:03:33 +02:00
|
|
|
return buf;
|
|
|
|
|
}
|
2015-10-27 16:14:54 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!map)
|
|
|
|
|
g_return_val_if_reached("");
|
2015-10-27 16:14:54 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
b = buf;
|
2015-10-27 16:14:54 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (name) {
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&b, &len, name);
|
|
|
|
|
nm_strbuf_append_str(&b, &len, " {");
|
2020-09-28 16:03:33 +02:00
|
|
|
} else
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_c(&b, &len, '{');
|
2015-10-27 16:14:54 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
for (i = 0; i < n_map; i++)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&b, &len, " %u:%u", map[i].from, map[i].to);
|
|
|
|
|
nm_strbuf_append_str(&b, &len, " }");
|
2020-09-28 16:03:33 +02:00
|
|
|
return buf;
|
2015-10-27 16:14:54 +01:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 10:27:33 +02:00
|
|
|
/**
|
|
|
|
|
* nm_platform_link_to_string:
|
|
|
|
|
* @route: pointer to NMPlatformLink address structure
|
2023-03-01 01:21:38 +01:00
|
|
|
* @buf: (nullable): an optional buffer. If %NULL, a static buffer is used.
|
2015-10-12 10:27:33 +02:00
|
|
|
* @len: the size of the @buf. If @buf is %NULL, this argument is ignored.
|
|
|
|
|
*
|
|
|
|
|
* A method for converting an link struct into a string representation.
|
|
|
|
|
*
|
|
|
|
|
* Returns: a string representation of the link.
|
|
|
|
|
*/
|
2014-02-17 14:08:32 +01:00
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_to_string(const NMPlatformLink *link, char *buf, gsize len)
|
|
|
|
|
{
|
|
|
|
|
char master[20];
|
|
|
|
|
char parent[20];
|
|
|
|
|
char str_flags[1 + NM_PLATFORM_LINK_FLAGS2STR_MAX_LEN + 1];
|
|
|
|
|
char str_highlighted_flags[50];
|
2021-11-09 13:28:54 +01:00
|
|
|
char *s;
|
2020-09-28 16:03:33 +02:00
|
|
|
gsize l;
|
|
|
|
|
char str_addrmode[30];
|
2023-03-03 16:36:23 +01:00
|
|
|
char str_port_data[200];
|
2021-03-03 20:57:01 +01:00
|
|
|
char str_address[_NM_UTILS_HWADDR_LEN_MAX * 3];
|
2021-07-26 10:57:30 -04:00
|
|
|
char str_perm_address[_NM_UTILS_HWADDR_LEN_MAX * 3];
|
2021-03-03 20:57:01 +01:00
|
|
|
char str_broadcast[_NM_UTILS_HWADDR_LEN_MAX * 3];
|
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 str_inet6_token[NM_INET_ADDRSTRLEN];
|
2020-09-28 16:03:33 +02:00
|
|
|
const char *str_link_type;
|
|
|
|
|
|
|
|
|
|
if (!nm_utils_to_string_buffer_init_null(link, &buf, &len))
|
|
|
|
|
return buf;
|
|
|
|
|
|
|
|
|
|
s = str_highlighted_flags;
|
|
|
|
|
l = sizeof(str_highlighted_flags);
|
|
|
|
|
if (NM_FLAGS_HAS(link->n_ifi_flags, IFF_NOARP))
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&s, &l, "NOARP,");
|
2020-09-28 16:03:33 +02:00
|
|
|
if (NM_FLAGS_HAS(link->n_ifi_flags, IFF_UP))
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&s, &l, "UP");
|
2020-09-28 16:03:33 +02:00
|
|
|
else
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&s, &l, "DOWN");
|
2020-09-28 16:03:33 +02:00
|
|
|
if (link->connected)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&s, &l, ",LOWER_UP");
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_assert(s > str_highlighted_flags && l > 0);
|
|
|
|
|
|
|
|
|
|
if (link->n_ifi_flags) {
|
|
|
|
|
str_flags[0] = ';';
|
|
|
|
|
nm_platform_link_flags2str(link->n_ifi_flags, &str_flags[1], sizeof(str_flags) - 1);
|
|
|
|
|
} else
|
|
|
|
|
str_flags[0] = '\0';
|
|
|
|
|
|
|
|
|
|
if (link->master)
|
|
|
|
|
g_snprintf(master, sizeof(master), " master %d", link->master);
|
|
|
|
|
else
|
|
|
|
|
master[0] = 0;
|
|
|
|
|
|
|
|
|
|
if (link->parent > 0)
|
|
|
|
|
g_snprintf(parent, sizeof(parent), "@%d", link->parent);
|
|
|
|
|
else if (link->parent == NM_PLATFORM_LINK_OTHER_NETNS)
|
|
|
|
|
g_strlcpy(parent, "@other-netns", sizeof(parent));
|
|
|
|
|
else
|
|
|
|
|
parent[0] = 0;
|
|
|
|
|
|
|
|
|
|
_nmp_link_address_to_string(&link->l_address, str_address);
|
2021-07-26 10:57:30 -04:00
|
|
|
_nmp_link_address_to_string(&link->l_perm_address, str_perm_address);
|
2020-09-28 16:03:33 +02:00
|
|
|
_nmp_link_address_to_string(&link->l_broadcast, str_broadcast);
|
|
|
|
|
|
2023-03-03 16:36:23 +01:00
|
|
|
_nmp_link_port_data_to_string(link->port_kind,
|
|
|
|
|
&link->port_data,
|
|
|
|
|
str_port_data,
|
|
|
|
|
sizeof(str_port_data));
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
str_link_type = nm_link_type_to_string(link->type);
|
|
|
|
|
|
|
|
|
|
g_snprintf(
|
|
|
|
|
buf,
|
|
|
|
|
len,
|
|
|
|
|
"%d: " /* ifindex */
|
|
|
|
|
"%s" /* name */
|
|
|
|
|
"%s" /* parent */
|
|
|
|
|
" <%s%s>" /* flags */
|
|
|
|
|
" mtu %d"
|
|
|
|
|
"%s" /* master */
|
|
|
|
|
" arp %u" /* arptype */
|
|
|
|
|
" %s" /* link->type */
|
|
|
|
|
"%s%s" /* kind */
|
|
|
|
|
"%s" /* is-in-udev */
|
|
|
|
|
"%s%s" /* addr-gen-mode */
|
|
|
|
|
"%s%s" /* l_address */
|
2021-07-26 10:57:30 -04:00
|
|
|
"%s%s" /* l_perm_address */
|
2020-09-28 16:03:33 +02:00
|
|
|
"%s%s" /* l_broadcast */
|
|
|
|
|
"%s%s" /* inet6_token */
|
|
|
|
|
"%s%s" /* driver */
|
2023-03-03 16:36:23 +01:00
|
|
|
"%s%s" /* port_data */
|
2023-02-16 16:37:54 +01:00
|
|
|
" tx-queue-len %u"
|
|
|
|
|
" gso-max-size %u"
|
|
|
|
|
" gso-max-segs %u"
|
|
|
|
|
" gro-max-size %u"
|
2020-09-28 16:03:33 +02:00
|
|
|
" rx:%" G_GUINT64_FORMAT ",%" G_GUINT64_FORMAT " tx:%" G_GUINT64_FORMAT
|
|
|
|
|
",%" G_GUINT64_FORMAT,
|
|
|
|
|
link->ifindex,
|
|
|
|
|
link->name,
|
|
|
|
|
parent,
|
|
|
|
|
str_highlighted_flags,
|
|
|
|
|
str_flags,
|
|
|
|
|
link->mtu,
|
|
|
|
|
master,
|
|
|
|
|
link->arptype,
|
|
|
|
|
str_link_type ?: "???",
|
|
|
|
|
link->kind ? (g_strcmp0(str_link_type, link->kind) ? "/" : "*") : "?",
|
|
|
|
|
link->kind && g_strcmp0(str_link_type, link->kind) ? link->kind : "",
|
|
|
|
|
link->initialized ? " init" : " not-init",
|
|
|
|
|
link->inet6_addr_gen_mode_inv ? " addrgenmode " : "",
|
|
|
|
|
link->inet6_addr_gen_mode_inv ? nm_platform_link_inet6_addrgenmode2str(
|
|
|
|
|
_nm_platform_uint8_inv(link->inet6_addr_gen_mode_inv),
|
|
|
|
|
str_addrmode,
|
|
|
|
|
sizeof(str_addrmode))
|
|
|
|
|
: "",
|
|
|
|
|
str_address[0] ? " addr " : "",
|
|
|
|
|
str_address[0] ? str_address : "",
|
2021-07-26 10:57:30 -04:00
|
|
|
str_perm_address[0] ? " permaddr " : "",
|
|
|
|
|
str_perm_address[0] ? str_perm_address : "",
|
2020-09-28 16:03:33 +02:00
|
|
|
str_broadcast[0] ? " brd " : "",
|
|
|
|
|
str_broadcast[0] ? str_broadcast : "",
|
|
|
|
|
link->inet6_token.id ? " inet6token " : "",
|
|
|
|
|
link->inet6_token.id
|
2021-08-25 14:53:40 +02:00
|
|
|
? nm_utils_inet6_interface_identifier_to_token(&link->inet6_token, str_inet6_token)
|
2020-09-28 16:03:33 +02:00
|
|
|
: "",
|
|
|
|
|
link->driver ? " driver " : "",
|
|
|
|
|
link->driver ?: "",
|
2023-03-03 16:36:23 +01:00
|
|
|
NM_PRINT_FMT_QUOTED2(str_port_data[0] != '\0', " ", str_port_data, ""),
|
2023-02-16 16:37:54 +01:00
|
|
|
link->link_props.tx_queue_length,
|
|
|
|
|
link->link_props.gso_max_size,
|
|
|
|
|
link->link_props.gso_max_segments,
|
|
|
|
|
link->link_props.gro_max_size,
|
2020-09-28 16:03:33 +02:00
|
|
|
link->rx_packets,
|
|
|
|
|
link->rx_bytes,
|
|
|
|
|
link->tx_packets,
|
|
|
|
|
link->tx_bytes);
|
|
|
|
|
return buf;
|
2014-02-17 14:08:32 +01:00
|
|
|
}
|
|
|
|
|
|
2020-08-05 13:46:28 -04:00
|
|
|
const NMPlatformLnkBridge nm_platform_lnk_bridge_default = {
|
2020-09-28 16:03:33 +02:00
|
|
|
.forward_delay = NM_BRIDGE_FORWARD_DELAY_DEF_SYS,
|
|
|
|
|
.hello_time = NM_BRIDGE_HELLO_TIME_DEF_SYS,
|
|
|
|
|
.max_age = NM_BRIDGE_MAX_AGE_DEF_SYS,
|
|
|
|
|
.ageing_time = NM_BRIDGE_AGEING_TIME_DEF_SYS,
|
|
|
|
|
.stp_state = FALSE,
|
|
|
|
|
.priority = NM_BRIDGE_PRIORITY_DEF,
|
|
|
|
|
.vlan_protocol = 0x8100,
|
|
|
|
|
.vlan_stats_enabled = NM_BRIDGE_VLAN_STATS_ENABLED_DEF,
|
|
|
|
|
.group_fwd_mask = 0,
|
|
|
|
|
.group_addr = NM_ETHER_ADDR_INIT(NM_BRIDGE_GROUP_ADDRESS_DEF_BIN),
|
|
|
|
|
.mcast_snooping = NM_BRIDGE_MULTICAST_SNOOPING_DEF,
|
|
|
|
|
.mcast_router = 1,
|
|
|
|
|
.mcast_query_use_ifaddr = NM_BRIDGE_MULTICAST_QUERY_USE_IFADDR_DEF,
|
|
|
|
|
.mcast_querier = NM_BRIDGE_MULTICAST_QUERIER_DEF,
|
|
|
|
|
.mcast_hash_max = NM_BRIDGE_MULTICAST_HASH_MAX_DEF,
|
|
|
|
|
.mcast_last_member_count = NM_BRIDGE_MULTICAST_LAST_MEMBER_COUNT_DEF,
|
|
|
|
|
.mcast_startup_query_count = NM_BRIDGE_MULTICAST_STARTUP_QUERY_COUNT_DEF,
|
|
|
|
|
.mcast_last_member_interval = NM_BRIDGE_MULTICAST_LAST_MEMBER_INTERVAL_DEF,
|
|
|
|
|
.mcast_membership_interval = NM_BRIDGE_MULTICAST_MEMBERSHIP_INTERVAL_DEF,
|
|
|
|
|
.mcast_querier_interval = NM_BRIDGE_MULTICAST_QUERIER_INTERVAL_DEF,
|
|
|
|
|
.mcast_query_interval = NM_BRIDGE_MULTICAST_QUERY_INTERVAL_DEF,
|
|
|
|
|
.mcast_query_response_interval = NM_BRIDGE_MULTICAST_QUERY_RESPONSE_INTERVAL_DEF,
|
|
|
|
|
.mcast_startup_query_interval = NM_BRIDGE_MULTICAST_STARTUP_QUERY_INTERVAL_DEF,
|
2020-08-05 13:46:28 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_bridge_to_string(const NMPlatformLnkBridge *lnk, char *buf, gsize len)
|
|
|
|
|
{
|
|
|
|
|
if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len))
|
|
|
|
|
return buf;
|
|
|
|
|
|
|
|
|
|
g_snprintf(buf,
|
|
|
|
|
len,
|
|
|
|
|
"forward_delay %u"
|
|
|
|
|
" hello_time %u"
|
|
|
|
|
" max_age %u"
|
|
|
|
|
" ageing_time %u"
|
|
|
|
|
" stp_state %d"
|
|
|
|
|
" priority %u"
|
|
|
|
|
" vlan_protocol %u"
|
|
|
|
|
" vlan_stats_enabled %d"
|
|
|
|
|
" group_fwd_mask %#x"
|
|
|
|
|
" group_address " NM_ETHER_ADDR_FORMAT_STR " mcast_snooping %d"
|
|
|
|
|
" mcast_router %u"
|
|
|
|
|
" mcast_query_use_ifaddr %d"
|
|
|
|
|
" mcast_querier %d"
|
|
|
|
|
" mcast_hash_max %u"
|
|
|
|
|
" mcast_last_member_count %u"
|
|
|
|
|
" mcast_startup_query_count %u"
|
|
|
|
|
" mcast_last_member_interval %" G_GUINT64_FORMAT
|
|
|
|
|
" mcast_membership_interval %" G_GUINT64_FORMAT
|
|
|
|
|
" mcast_querier_interval %" G_GUINT64_FORMAT
|
|
|
|
|
" mcast_query_interval %" G_GUINT64_FORMAT
|
|
|
|
|
" mcast_query_response_interval %" G_GUINT64_FORMAT
|
|
|
|
|
" mcast_startup_query_interval %" G_GUINT64_FORMAT "",
|
|
|
|
|
lnk->forward_delay,
|
|
|
|
|
lnk->hello_time,
|
|
|
|
|
lnk->max_age,
|
|
|
|
|
lnk->ageing_time,
|
|
|
|
|
(int) lnk->stp_state,
|
|
|
|
|
lnk->priority,
|
|
|
|
|
lnk->vlan_protocol,
|
|
|
|
|
(int) lnk->vlan_stats_enabled,
|
|
|
|
|
lnk->group_fwd_mask,
|
2020-10-13 11:11:25 +02:00
|
|
|
NM_ETHER_ADDR_FORMAT_VAL(&lnk->group_addr),
|
2020-09-28 16:03:33 +02:00
|
|
|
(int) lnk->mcast_snooping,
|
|
|
|
|
lnk->mcast_router,
|
|
|
|
|
(int) lnk->mcast_query_use_ifaddr,
|
|
|
|
|
(int) lnk->mcast_querier,
|
|
|
|
|
lnk->mcast_hash_max,
|
|
|
|
|
lnk->mcast_last_member_count,
|
|
|
|
|
lnk->mcast_startup_query_count,
|
|
|
|
|
lnk->mcast_last_member_interval,
|
|
|
|
|
lnk->mcast_membership_interval,
|
|
|
|
|
lnk->mcast_querier_interval,
|
|
|
|
|
lnk->mcast_query_interval,
|
|
|
|
|
lnk->mcast_query_response_interval,
|
|
|
|
|
lnk->mcast_startup_query_interval);
|
|
|
|
|
return buf;
|
2020-08-05 13:46:28 -04:00
|
|
|
}
|
|
|
|
|
|
2022-07-25 16:01:35 +02:00
|
|
|
const char *
|
|
|
|
|
nm_platform_lnk_bond_to_string(const NMPlatformLnkBond *lnk, char *buf, gsize len)
|
|
|
|
|
{
|
|
|
|
|
char sbuf_miimon[30];
|
|
|
|
|
char sbuf_updelay[30];
|
|
|
|
|
char sbuf_downdelay[30];
|
2023-03-02 11:43:25 +01:00
|
|
|
char sbuf_lacp_active[30];
|
2022-07-25 16:01:35 +02:00
|
|
|
char sbuf_peer_notif_delay[60];
|
|
|
|
|
char sbuf_resend_igmp[30];
|
|
|
|
|
char sbuf_lp_interval[30];
|
|
|
|
|
char sbuf_tlb_dynamic_lb[30];
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len))
|
|
|
|
|
return buf;
|
|
|
|
|
|
|
|
|
|
nm_strbuf_append(
|
|
|
|
|
&buf,
|
|
|
|
|
&len,
|
|
|
|
|
"bond"
|
|
|
|
|
" mode %u"
|
2022-09-06 10:17:04 +02:00
|
|
|
" primary %d"
|
2022-07-25 16:01:35 +02:00
|
|
|
"%s" /* miimon */
|
|
|
|
|
"%s" /* updelay */
|
|
|
|
|
"%s" /* downdelay */
|
|
|
|
|
" arp_interval %u"
|
|
|
|
|
"%s" /* resend_igmp */
|
|
|
|
|
" min_links %u"
|
|
|
|
|
"%s" /* lp_interval */
|
|
|
|
|
" packets_per_port %u"
|
|
|
|
|
"%s" /* peer_notif_delay */
|
2022-09-27 09:06:55 +02:00
|
|
|
" arp_all_targets %u"
|
2022-07-25 16:01:35 +02:00
|
|
|
" arp_validate %u"
|
|
|
|
|
" ad_actor_sys_prio %u"
|
|
|
|
|
" ad_user_port_key %u"
|
|
|
|
|
" ad_actor_system " NM_ETHER_ADDR_FORMAT_STR ""
|
|
|
|
|
" primary_reselect %u"
|
|
|
|
|
" fail_over_mac %u"
|
|
|
|
|
" xmit_hash_policy %u"
|
|
|
|
|
" num_gray_arp %u"
|
|
|
|
|
" all_ports_active %u"
|
2023-03-01 15:12:35 +00:00
|
|
|
" arp_missed_max %u"
|
2022-07-25 16:01:35 +02:00
|
|
|
" lacp_rate %u"
|
2023-03-02 11:43:25 +01:00
|
|
|
"%s" /* lacp_active */
|
2022-07-25 16:01:35 +02:00
|
|
|
" ad_select %u"
|
|
|
|
|
" use_carrier %d"
|
|
|
|
|
"%s" /* tlb_dynamic_lb */,
|
|
|
|
|
lnk->mode,
|
|
|
|
|
lnk->primary,
|
|
|
|
|
lnk->miimon_has || lnk->miimon != 0
|
|
|
|
|
? nm_sprintf_buf(sbuf_miimon, " miimon%s %u", !lnk->miimon_has ? "?" : "", lnk->miimon)
|
|
|
|
|
: "",
|
|
|
|
|
lnk->updelay_has || lnk->updelay != 0 ? nm_sprintf_buf(sbuf_updelay,
|
|
|
|
|
" updelay%s %u",
|
|
|
|
|
!lnk->updelay_has ? "?" : "",
|
|
|
|
|
lnk->updelay)
|
|
|
|
|
: "",
|
|
|
|
|
lnk->downdelay_has || lnk->downdelay != 0 ? nm_sprintf_buf(sbuf_downdelay,
|
|
|
|
|
" downdelay%s %u",
|
|
|
|
|
!lnk->downdelay_has ? "?" : "",
|
|
|
|
|
lnk->downdelay)
|
|
|
|
|
: "",
|
|
|
|
|
lnk->arp_interval,
|
|
|
|
|
lnk->resend_igmp_has || lnk->resend_igmp != 0
|
|
|
|
|
? nm_sprintf_buf(sbuf_resend_igmp,
|
|
|
|
|
" resend_igmp%s %u",
|
|
|
|
|
!lnk->resend_igmp_has ? "?" : "",
|
|
|
|
|
lnk->resend_igmp)
|
|
|
|
|
: "",
|
|
|
|
|
lnk->min_links,
|
|
|
|
|
lnk->lp_interval_has || lnk->lp_interval != 1
|
|
|
|
|
? nm_sprintf_buf(sbuf_lp_interval,
|
|
|
|
|
" lp_interval%s %u",
|
|
|
|
|
!lnk->lp_interval_has ? "?" : "",
|
|
|
|
|
lnk->lp_interval)
|
|
|
|
|
: "",
|
|
|
|
|
lnk->packets_per_port,
|
|
|
|
|
lnk->peer_notif_delay_has || lnk->peer_notif_delay != 0
|
|
|
|
|
? nm_sprintf_buf(sbuf_peer_notif_delay,
|
|
|
|
|
" peer_notif_delay%s %u",
|
|
|
|
|
!lnk->peer_notif_delay_has ? "?" : "",
|
|
|
|
|
lnk->peer_notif_delay)
|
|
|
|
|
: "",
|
2022-09-27 09:06:55 +02:00
|
|
|
lnk->arp_all_targets,
|
2022-07-25 16:01:35 +02:00
|
|
|
lnk->arp_validate,
|
|
|
|
|
lnk->ad_actor_sys_prio,
|
|
|
|
|
lnk->ad_user_port_key,
|
|
|
|
|
NM_ETHER_ADDR_FORMAT_VAL(&lnk->ad_actor_system),
|
|
|
|
|
lnk->primary_reselect,
|
|
|
|
|
lnk->fail_over_mac,
|
|
|
|
|
lnk->xmit_hash_policy,
|
|
|
|
|
lnk->num_grat_arp,
|
|
|
|
|
lnk->all_ports_active,
|
2023-03-01 15:12:35 +00:00
|
|
|
lnk->arp_missed_max,
|
2022-07-25 16:01:35 +02:00
|
|
|
lnk->lacp_rate,
|
2023-03-02 11:43:25 +01:00
|
|
|
lnk->lacp_active_has || lnk->lacp_active != 0
|
|
|
|
|
? nm_sprintf_buf(sbuf_lacp_active,
|
|
|
|
|
" lacp_active%s %u",
|
|
|
|
|
!lnk->lacp_active_has ? "?" : "",
|
|
|
|
|
lnk->lacp_active)
|
|
|
|
|
: "",
|
2022-07-25 16:01:35 +02:00
|
|
|
lnk->ad_select,
|
|
|
|
|
(int) lnk->use_carrier,
|
|
|
|
|
lnk->tlb_dynamic_lb_has ? nm_sprintf_buf(sbuf_tlb_dynamic_lb,
|
|
|
|
|
" tlb_dynamic_lb%s %u",
|
|
|
|
|
!lnk->tlb_dynamic_lb_has ? "?" : "",
|
|
|
|
|
(int) lnk->tlb_dynamic_lb)
|
|
|
|
|
: "");
|
|
|
|
|
|
|
|
|
|
if (lnk->arp_ip_targets_num > 0) {
|
|
|
|
|
nm_strbuf_append_str(&buf, &len, " arp_ip_target");
|
|
|
|
|
for (i = 0; i < lnk->arp_ip_targets_num; i++) {
|
|
|
|
|
char target[INET_ADDRSTRLEN];
|
|
|
|
|
|
|
|
|
|
nm_strbuf_append_c(&buf, &len, ' ');
|
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_strbuf_append_str(&buf, &len, nm_inet4_ntop(lnk->arp_ip_target[i], target));
|
2022-07-25 16:01:35 +02:00
|
|
|
}
|
|
|
|
|
}
|
2023-03-02 15:07:07 +01:00
|
|
|
if (lnk->ns_ip6_targets_num > 0) {
|
|
|
|
|
nm_strbuf_append_str(&buf, &len, " ns_ip6_target");
|
|
|
|
|
for (i = 0; i < lnk->ns_ip6_targets_num; i++) {
|
|
|
|
|
char target[INET6_ADDRSTRLEN];
|
|
|
|
|
|
|
|
|
|
nm_strbuf_append_c(&buf, &len, ' ');
|
|
|
|
|
nm_strbuf_append_str(&buf, &len, nm_inet6_ntop(&lnk->ns_ip6_target[i], target));
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-07-25 16:01:35 +02:00
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-12 15:15:21 +02:00
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_gre_to_string(const NMPlatformLnkGre *lnk, char *buf, gsize len)
|
|
|
|
|
{
|
|
|
|
|
char str_local[30];
|
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 str_local1[NM_INET_ADDRSTRLEN];
|
2020-09-28 16:03:33 +02:00
|
|
|
char str_remote[30];
|
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 str_remote1[NM_INET_ADDRSTRLEN];
|
2020-09-28 16:03:33 +02:00
|
|
|
char str_ttl[30];
|
|
|
|
|
char str_tos[30];
|
|
|
|
|
char str_parent_ifindex[30];
|
|
|
|
|
char str_input_flags[30];
|
|
|
|
|
char str_output_flags[30];
|
|
|
|
|
char str_input_key[30];
|
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 str_input_key1[NM_INET_ADDRSTRLEN];
|
2020-09-28 16:03:33 +02:00
|
|
|
char str_output_key[30];
|
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 str_output_key1[NM_INET_ADDRSTRLEN];
|
2020-09-28 16:03:33 +02:00
|
|
|
|
|
|
|
|
if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len))
|
|
|
|
|
return buf;
|
|
|
|
|
|
|
|
|
|
g_snprintf(
|
|
|
|
|
buf,
|
|
|
|
|
len,
|
|
|
|
|
"gre%s" /* is_tap */
|
|
|
|
|
"%s" /* remote */
|
|
|
|
|
"%s" /* local */
|
|
|
|
|
"%s" /* parent_ifindex */
|
|
|
|
|
"%s" /* ttl */
|
|
|
|
|
"%s" /* tos */
|
|
|
|
|
"%s" /* path_mtu_discovery */
|
|
|
|
|
"%s" /* iflags */
|
|
|
|
|
"%s" /* oflags */
|
|
|
|
|
"%s" /* ikey */
|
|
|
|
|
"%s" /* okey */
|
|
|
|
|
"",
|
|
|
|
|
lnk->is_tap ? "tap" : "",
|
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
|
|
|
lnk->remote
|
|
|
|
|
? nm_sprintf_buf(str_remote, " remote %s", nm_inet4_ntop(lnk->remote, str_remote1))
|
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
|
|
|
lnk->local ? nm_sprintf_buf(str_local, " local %s", nm_inet4_ntop(lnk->local, str_local1))
|
|
|
|
|
: "",
|
2020-09-28 16:03:33 +02:00
|
|
|
lnk->parent_ifindex ? nm_sprintf_buf(str_parent_ifindex, " dev %d", lnk->parent_ifindex)
|
|
|
|
|
: "",
|
|
|
|
|
lnk->ttl ? nm_sprintf_buf(str_ttl, " ttl %u", lnk->ttl) : " ttl inherit",
|
|
|
|
|
lnk->tos ? (lnk->tos == 1 ? " tos inherit" : nm_sprintf_buf(str_tos, " tos 0x%x", lnk->tos))
|
|
|
|
|
: "",
|
|
|
|
|
lnk->path_mtu_discovery ? "" : " nopmtudisc",
|
|
|
|
|
lnk->input_flags ? nm_sprintf_buf(str_input_flags, " iflags 0x%x", lnk->input_flags) : "",
|
|
|
|
|
lnk->output_flags ? nm_sprintf_buf(str_output_flags, " oflags 0x%x", lnk->output_flags)
|
|
|
|
|
: "",
|
|
|
|
|
NM_FLAGS_HAS(lnk->input_flags, GRE_KEY) || lnk->input_key
|
|
|
|
|
? nm_sprintf_buf(str_input_key,
|
|
|
|
|
" ikey %s",
|
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_inet4_ntop(lnk->input_key, str_input_key1))
|
2020-09-28 16:03:33 +02:00
|
|
|
: "",
|
|
|
|
|
NM_FLAGS_HAS(lnk->output_flags, GRE_KEY) || lnk->output_key
|
|
|
|
|
? nm_sprintf_buf(str_output_key,
|
|
|
|
|
" okey %s",
|
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_inet4_ntop(lnk->output_key, str_output_key1))
|
2020-09-28 16:03:33 +02:00
|
|
|
: "");
|
|
|
|
|
return buf;
|
2015-10-12 15:15:21 +02:00
|
|
|
}
|
|
|
|
|
|
2015-10-15 15:47:14 +02:00
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_infiniband_to_string(const NMPlatformLnkInfiniband *lnk, char *buf, gsize len)
|
2015-10-15 15:47:14 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
char str_p_key[64];
|
2015-10-15 15:47:14 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len))
|
|
|
|
|
return buf;
|
2015-10-15 15:47:14 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_snprintf(buf,
|
|
|
|
|
len,
|
|
|
|
|
"infiniband"
|
|
|
|
|
"%s" /* p_key */
|
|
|
|
|
"%s%s" /* mode */
|
|
|
|
|
"",
|
|
|
|
|
lnk->p_key ? nm_sprintf_buf(str_p_key, " pkey %d", lnk->p_key) : "",
|
|
|
|
|
lnk->mode ? " mode " : "",
|
|
|
|
|
lnk->mode ?: "");
|
|
|
|
|
return buf;
|
2015-10-15 15:47:14 +02:00
|
|
|
}
|
|
|
|
|
|
2015-11-27 22:22:25 +01:00
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_ip6tnl_to_string(const NMPlatformLnkIp6Tnl *lnk, char *buf, gsize len)
|
|
|
|
|
{
|
|
|
|
|
char str_local[30];
|
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 str_local1[NM_INET_ADDRSTRLEN];
|
2020-09-28 16:03:33 +02:00
|
|
|
char str_remote[30];
|
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 str_remote1[NM_INET_ADDRSTRLEN];
|
2020-09-28 16:03:33 +02:00
|
|
|
char str_ttl[30];
|
|
|
|
|
char str_tclass[30];
|
|
|
|
|
char str_flow[30];
|
|
|
|
|
char str_encap[30];
|
|
|
|
|
char str_proto[30];
|
|
|
|
|
char str_parent_ifindex[30];
|
|
|
|
|
char *str_type;
|
|
|
|
|
|
|
|
|
|
if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len))
|
|
|
|
|
return buf;
|
|
|
|
|
|
|
|
|
|
if (lnk->is_gre)
|
|
|
|
|
str_type = lnk->is_tap ? "ip6gretap" : "ip6gre";
|
|
|
|
|
else
|
|
|
|
|
str_type = "ip6tnl";
|
|
|
|
|
|
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_snprintf(buf,
|
|
|
|
|
len,
|
|
|
|
|
"%s" /* type */
|
|
|
|
|
"%s" /* remote */
|
|
|
|
|
"%s" /* local */
|
|
|
|
|
"%s" /* parent_ifindex */
|
|
|
|
|
"%s" /* ttl */
|
|
|
|
|
"%s" /* tclass */
|
|
|
|
|
"%s" /* encap limit */
|
|
|
|
|
"%s" /* flow label */
|
|
|
|
|
"%s" /* proto */
|
|
|
|
|
" flags 0x%x"
|
|
|
|
|
"",
|
|
|
|
|
str_type,
|
|
|
|
|
nm_sprintf_buf(str_remote, " remote %s", nm_inet6_ntop(&lnk->remote, str_remote1)),
|
|
|
|
|
nm_sprintf_buf(str_local, " local %s", nm_inet6_ntop(&lnk->local, str_local1)),
|
|
|
|
|
lnk->parent_ifindex
|
|
|
|
|
? nm_sprintf_buf(str_parent_ifindex, " dev %d", lnk->parent_ifindex)
|
|
|
|
|
: "",
|
|
|
|
|
lnk->ttl ? nm_sprintf_buf(str_ttl, " ttl %u", lnk->ttl) : " ttl inherit",
|
|
|
|
|
lnk->tclass == 1 ? " tclass inherit"
|
|
|
|
|
: nm_sprintf_buf(str_tclass, " tclass 0x%x", lnk->tclass),
|
|
|
|
|
nm_sprintf_buf(str_encap, " encap-limit %u", lnk->encap_limit),
|
|
|
|
|
nm_sprintf_buf(str_flow, " flow-label 0x05%x", lnk->flow_label),
|
|
|
|
|
nm_sprintf_buf(str_proto, " proto %u", lnk->proto),
|
|
|
|
|
(guint) lnk->flags);
|
2020-09-28 16:03:33 +02:00
|
|
|
return buf;
|
2015-11-27 22:22:25 +01:00
|
|
|
}
|
|
|
|
|
|
2015-11-27 14:01:56 +01:00
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_ipip_to_string(const NMPlatformLnkIpIp *lnk, char *buf, gsize len)
|
|
|
|
|
{
|
|
|
|
|
char str_local[30];
|
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 str_local1[NM_INET_ADDRSTRLEN];
|
2020-09-28 16:03:33 +02:00
|
|
|
char str_remote[30];
|
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 str_remote1[NM_INET_ADDRSTRLEN];
|
2020-09-28 16:03:33 +02:00
|
|
|
char str_ttl[30];
|
|
|
|
|
char str_tos[30];
|
|
|
|
|
char str_parent_ifindex[30];
|
|
|
|
|
|
|
|
|
|
if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len))
|
|
|
|
|
return buf;
|
|
|
|
|
|
|
|
|
|
g_snprintf(
|
|
|
|
|
buf,
|
|
|
|
|
len,
|
|
|
|
|
"ipip"
|
|
|
|
|
"%s" /* remote */
|
|
|
|
|
"%s" /* local */
|
|
|
|
|
"%s" /* parent_ifindex */
|
|
|
|
|
"%s" /* ttl */
|
|
|
|
|
"%s" /* tos */
|
|
|
|
|
"%s" /* path_mtu_discovery */
|
|
|
|
|
"",
|
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
|
|
|
lnk->remote
|
|
|
|
|
? nm_sprintf_buf(str_remote, " remote %s", nm_inet4_ntop(lnk->remote, str_remote1))
|
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
|
|
|
lnk->local ? nm_sprintf_buf(str_local, " local %s", nm_inet4_ntop(lnk->local, str_local1))
|
|
|
|
|
: "",
|
2020-09-28 16:03:33 +02:00
|
|
|
lnk->parent_ifindex ? nm_sprintf_buf(str_parent_ifindex, " dev %d", lnk->parent_ifindex)
|
|
|
|
|
: "",
|
|
|
|
|
lnk->ttl ? nm_sprintf_buf(str_ttl, " ttl %u", lnk->ttl) : " ttl inherit",
|
|
|
|
|
lnk->tos ? (lnk->tos == 1 ? " tos inherit" : nm_sprintf_buf(str_tos, " tos 0x%x", lnk->tos))
|
|
|
|
|
: "",
|
|
|
|
|
lnk->path_mtu_discovery ? "" : " nopmtudisc");
|
|
|
|
|
return buf;
|
2015-11-27 14:01:56 +01:00
|
|
|
}
|
|
|
|
|
|
2016-06-30 18:20:09 +02:00
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_macsec_to_string(const NMPlatformLnkMacsec *lnk, char *buf, gsize len)
|
|
|
|
|
{
|
|
|
|
|
if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len))
|
|
|
|
|
return buf;
|
|
|
|
|
|
|
|
|
|
g_snprintf(buf,
|
|
|
|
|
len,
|
|
|
|
|
"macsec "
|
|
|
|
|
"sci %016llx "
|
|
|
|
|
"protect %s "
|
|
|
|
|
"cipher %016llx "
|
|
|
|
|
"icvlen %u "
|
|
|
|
|
"encodingsa %u "
|
|
|
|
|
"validate %u "
|
|
|
|
|
"encrypt %s "
|
|
|
|
|
"send_sci %s "
|
|
|
|
|
"end_station %s "
|
|
|
|
|
"scb %s "
|
|
|
|
|
"replay %s",
|
|
|
|
|
(unsigned long long) lnk->sci,
|
|
|
|
|
lnk->protect ? "on" : "off",
|
|
|
|
|
(unsigned long long) lnk->cipher_suite,
|
|
|
|
|
lnk->icv_length,
|
|
|
|
|
lnk->encoding_sa,
|
|
|
|
|
lnk->validation,
|
|
|
|
|
lnk->encrypt ? "on" : "off",
|
|
|
|
|
lnk->include_sci ? "on" : "off",
|
|
|
|
|
lnk->es ? "on" : "off",
|
|
|
|
|
lnk->scb ? "on" : "off",
|
|
|
|
|
lnk->replay_protect ? "on" : "off");
|
|
|
|
|
return buf;
|
2016-06-30 18:20:09 +02:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 15:15:21 +02:00
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_macvlan_to_string(const NMPlatformLnkMacvlan *lnk, char *buf, gsize len)
|
2015-10-12 15:15:21 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len))
|
|
|
|
|
return buf;
|
2015-10-12 15:15:21 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_snprintf(buf,
|
|
|
|
|
len,
|
|
|
|
|
"%s mode %u %s",
|
|
|
|
|
lnk->tap ? "macvtap" : "macvlan",
|
|
|
|
|
lnk->mode,
|
|
|
|
|
lnk->no_promisc ? "not-promisc" : "promisc");
|
|
|
|
|
return buf;
|
2015-10-12 15:15:21 +02:00
|
|
|
}
|
|
|
|
|
|
2015-11-11 18:41:48 +01:00
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_sit_to_string(const NMPlatformLnkSit *lnk, char *buf, gsize len)
|
|
|
|
|
{
|
|
|
|
|
char str_local[30];
|
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 str_local1[NM_INET_ADDRSTRLEN];
|
2020-09-28 16:03:33 +02:00
|
|
|
char str_remote[30];
|
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 str_remote1[NM_INET_ADDRSTRLEN];
|
2020-09-28 16:03:33 +02:00
|
|
|
char str_ttl[30];
|
|
|
|
|
char str_tos[30];
|
|
|
|
|
char str_flags[30];
|
|
|
|
|
char str_proto[30];
|
|
|
|
|
char str_parent_ifindex[30];
|
|
|
|
|
|
|
|
|
|
if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len))
|
|
|
|
|
return buf;
|
|
|
|
|
|
|
|
|
|
g_snprintf(
|
|
|
|
|
buf,
|
|
|
|
|
len,
|
|
|
|
|
"sit"
|
|
|
|
|
"%s" /* remote */
|
|
|
|
|
"%s" /* local */
|
|
|
|
|
"%s" /* parent_ifindex */
|
|
|
|
|
"%s" /* ttl */
|
|
|
|
|
"%s" /* tos */
|
|
|
|
|
"%s" /* path_mtu_discovery */
|
|
|
|
|
"%s" /* flags */
|
|
|
|
|
"%s" /* proto */
|
|
|
|
|
"",
|
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
|
|
|
lnk->remote
|
|
|
|
|
? nm_sprintf_buf(str_remote, " remote %s", nm_inet4_ntop(lnk->remote, str_remote1))
|
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
|
|
|
lnk->local ? nm_sprintf_buf(str_local, " local %s", nm_inet4_ntop(lnk->local, str_local1))
|
|
|
|
|
: "",
|
2020-09-28 16:03:33 +02:00
|
|
|
lnk->parent_ifindex ? nm_sprintf_buf(str_parent_ifindex, " dev %d", lnk->parent_ifindex)
|
|
|
|
|
: "",
|
|
|
|
|
lnk->ttl ? nm_sprintf_buf(str_ttl, " ttl %u", lnk->ttl) : " ttl inherit",
|
|
|
|
|
lnk->tos ? (lnk->tos == 1 ? " tos inherit" : nm_sprintf_buf(str_tos, " tos 0x%x", lnk->tos))
|
|
|
|
|
: "",
|
|
|
|
|
lnk->path_mtu_discovery ? "" : " nopmtudisc",
|
|
|
|
|
lnk->flags ? nm_sprintf_buf(str_flags, " flags 0x%x", lnk->flags) : "",
|
|
|
|
|
lnk->proto ? nm_sprintf_buf(str_proto, " proto 0x%x", lnk->proto) : "");
|
|
|
|
|
return buf;
|
2015-11-11 18:41:48 +01:00
|
|
|
}
|
|
|
|
|
|
core/platform: add support for TUN/TAP netlink support and various cleanup
Kernel recently got support for exposing TUN/TAP information on netlink
[1], [2], [3]. Add support for it to the platform cache.
The advantage of using netlink is that querying sysctl bypasses the
order of events of the netlink socket. It is out of sync and racy. For
example, platform cache might still think that a tun device exists, but
a subsequent lookup at sysfs might fail because the device was deleted
in the meantime. Another point is, that we don't get change
notifications via sysctl and that it requires various extra syscalls
to read the device information. If the tun information is present on
netlink, put it into the cache. This bypasses checking sysctl while
we keep looking at sysctl for backward compatibility until we require
support from kernel.
Notes:
- we had two link types NM_LINK_TYPE_TAP and NM_LINK_TYPE_TUN. This
deviates from the model of how kernel treats TUN/TAP devices, which
makes it more complicated. The link type of a NMPlatformLink instance
should match what kernel thinks about the device. Point in case,
when parsing RTM_NETLINK messages, we very early need to determine
the link type (_linktype_get_type()). However, to determine the
type of a TUN/TAP at that point, we need to look into nested
netlink attributes which in turn depend on the type (IFLA_INFO_KIND
and IFLA_INFO_DATA), or even worse, we would need to look into
sysctl for older kernel vesions. Now, the TUN/TAP type is a property
of the link type NM_LINK_TYPE_TUN, instead of determining two
different link types.
- various parts of the API (both kernel's sysctl vs. netlink) and
NMDeviceTun vs. NMSettingTun disagree whether the PI is positive
(NM_SETTING_TUN_PI, IFLA_TUN_PI, NMPlatformLnkTun.pi) or inverted
(NM_DEVICE_TUN_NO_PI, IFF_NO_PI). There is no consistent way,
but prefer the positive form for internal API at NMPlatformLnkTun.pi.
- previously NMDeviceTun.mode could not change after initializing
the object. Allow for that to happen, because forcing some properties
that are reported by kernel to not change is wrong, in case they
might change. Of course, in practice kernel doesn't allow the device
to ever change its type, but the type property of the NMDeviceTun
should not make that assumption, because, if it actually changes, what
would it mean?
- note that as of now, new netlink API is not yet merged to mainline Linus
tree. Shortcut _parse_lnk_tun() to not accidentally use unstable API
for now.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1277457
[2] https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/commit/?id=1ec010e705934c8acbe7dbf31afc81e60e3d828b
[3] https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=118eda77d6602616bc523a17ee45171e879d1818
https://bugzilla.redhat.com/show_bug.cgi?id=1547213
https://github.com/NetworkManager/NetworkManager/pull/77
2018-03-13 15:29:03 +01:00
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_tun_to_string(const NMPlatformLnkTun *lnk, char *buf, gsize len)
|
|
|
|
|
{
|
|
|
|
|
char str_owner[50];
|
|
|
|
|
char str_group[50];
|
|
|
|
|
char str_type[50];
|
|
|
|
|
const char *type;
|
|
|
|
|
|
|
|
|
|
if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len))
|
|
|
|
|
return buf;
|
|
|
|
|
|
|
|
|
|
if (lnk->type == IFF_TUN)
|
|
|
|
|
type = "tun";
|
|
|
|
|
else if (lnk->type == IFF_TAP)
|
|
|
|
|
type = "tap";
|
|
|
|
|
else
|
|
|
|
|
type = nm_sprintf_buf(str_type, "tun type %u", (guint) lnk->type);
|
|
|
|
|
|
|
|
|
|
g_snprintf(buf,
|
|
|
|
|
len,
|
|
|
|
|
"%s" /* type */
|
|
|
|
|
"%s" /* pi */
|
|
|
|
|
"%s" /* vnet_hdr */
|
|
|
|
|
"%s" /* multi_queue */
|
|
|
|
|
"%s" /* persist */
|
|
|
|
|
"%s" /* owner */
|
|
|
|
|
"%s" /* group */
|
|
|
|
|
"",
|
|
|
|
|
type,
|
|
|
|
|
lnk->pi ? " pi" : "",
|
|
|
|
|
lnk->vnet_hdr ? " vnet_hdr" : "",
|
|
|
|
|
lnk->multi_queue ? " multi_queue" : "",
|
|
|
|
|
lnk->persist ? " persist" : "",
|
|
|
|
|
lnk->owner_valid ? nm_sprintf_buf(str_owner, " owner %u", (guint) lnk->owner) : "",
|
|
|
|
|
lnk->group_valid ? nm_sprintf_buf(str_group, " group %u", (guint) lnk->group) : "");
|
|
|
|
|
return buf;
|
core/platform: add support for TUN/TAP netlink support and various cleanup
Kernel recently got support for exposing TUN/TAP information on netlink
[1], [2], [3]. Add support for it to the platform cache.
The advantage of using netlink is that querying sysctl bypasses the
order of events of the netlink socket. It is out of sync and racy. For
example, platform cache might still think that a tun device exists, but
a subsequent lookup at sysfs might fail because the device was deleted
in the meantime. Another point is, that we don't get change
notifications via sysctl and that it requires various extra syscalls
to read the device information. If the tun information is present on
netlink, put it into the cache. This bypasses checking sysctl while
we keep looking at sysctl for backward compatibility until we require
support from kernel.
Notes:
- we had two link types NM_LINK_TYPE_TAP and NM_LINK_TYPE_TUN. This
deviates from the model of how kernel treats TUN/TAP devices, which
makes it more complicated. The link type of a NMPlatformLink instance
should match what kernel thinks about the device. Point in case,
when parsing RTM_NETLINK messages, we very early need to determine
the link type (_linktype_get_type()). However, to determine the
type of a TUN/TAP at that point, we need to look into nested
netlink attributes which in turn depend on the type (IFLA_INFO_KIND
and IFLA_INFO_DATA), or even worse, we would need to look into
sysctl for older kernel vesions. Now, the TUN/TAP type is a property
of the link type NM_LINK_TYPE_TUN, instead of determining two
different link types.
- various parts of the API (both kernel's sysctl vs. netlink) and
NMDeviceTun vs. NMSettingTun disagree whether the PI is positive
(NM_SETTING_TUN_PI, IFLA_TUN_PI, NMPlatformLnkTun.pi) or inverted
(NM_DEVICE_TUN_NO_PI, IFF_NO_PI). There is no consistent way,
but prefer the positive form for internal API at NMPlatformLnkTun.pi.
- previously NMDeviceTun.mode could not change after initializing
the object. Allow for that to happen, because forcing some properties
that are reported by kernel to not change is wrong, in case they
might change. Of course, in practice kernel doesn't allow the device
to ever change its type, but the type property of the NMDeviceTun
should not make that assumption, because, if it actually changes, what
would it mean?
- note that as of now, new netlink API is not yet merged to mainline Linus
tree. Shortcut _parse_lnk_tun() to not accidentally use unstable API
for now.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1277457
[2] https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/commit/?id=1ec010e705934c8acbe7dbf31afc81e60e3d828b
[3] https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=118eda77d6602616bc523a17ee45171e879d1818
https://bugzilla.redhat.com/show_bug.cgi?id=1547213
https://github.com/NetworkManager/NetworkManager/pull/77
2018-03-13 15:29:03 +01:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 13:44:44 +02:00
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_vlan_to_string(const NMPlatformLnkVlan *lnk, char *buf, gsize len)
|
2015-10-12 13:44:44 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
char *b;
|
2022-12-02 10:47:14 +01:00
|
|
|
char protocol[32];
|
2015-10-27 16:14:54 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len))
|
|
|
|
|
return buf;
|
2015-10-12 13:44:44 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
b = buf;
|
2015-10-27 16:14:54 +01:00
|
|
|
|
2022-12-02 10:47:14 +01:00
|
|
|
switch (lnk->protocol) {
|
|
|
|
|
case ETH_P_8021AD:
|
|
|
|
|
nm_sprintf_buf(protocol, "802.1ad");
|
|
|
|
|
break;
|
|
|
|
|
case ETH_P_8021Q:
|
|
|
|
|
nm_sprintf_buf(protocol, "802.1Q");
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
nm_sprintf_buf(protocol, "0x%04hx", lnk->protocol);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&b, &len, "vlan %u", lnk->id);
|
2022-12-02 10:47:14 +01:00
|
|
|
nm_strbuf_append(&b, &len, " protocol %s", protocol);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (lnk->flags)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&b, &len, " flags 0x%x", lnk->flags);
|
2020-09-28 16:03:33 +02:00
|
|
|
return buf;
|
2015-10-12 13:44:44 +02:00
|
|
|
}
|
|
|
|
|
|
2022-10-24 10:17:09 +02:00
|
|
|
const char *
|
|
|
|
|
nm_platform_lnk_vti_to_string(const NMPlatformLnkVti *lnk, char *buf, gsize len)
|
|
|
|
|
{
|
|
|
|
|
char str_local[30 + NM_INET_ADDRSTRLEN];
|
|
|
|
|
char str_local1[NM_INET_ADDRSTRLEN];
|
|
|
|
|
char str_remote[30 + NM_INET_ADDRSTRLEN];
|
|
|
|
|
char str_remote1[NM_INET_ADDRSTRLEN];
|
|
|
|
|
char str_ikey[30];
|
|
|
|
|
char str_okey[30];
|
|
|
|
|
char str_fwmark[30];
|
|
|
|
|
char str_parent_ifindex[30];
|
|
|
|
|
|
|
|
|
|
if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len))
|
|
|
|
|
return buf;
|
|
|
|
|
|
|
|
|
|
g_snprintf(
|
|
|
|
|
buf,
|
|
|
|
|
len,
|
|
|
|
|
"vti"
|
|
|
|
|
"%s" /* remote */
|
|
|
|
|
"%s" /* local */
|
|
|
|
|
"%s" /* parent_ifindex */
|
|
|
|
|
"%s" /* ikey */
|
|
|
|
|
"%s" /* okey */
|
|
|
|
|
"%s" /* fwmark */
|
|
|
|
|
"",
|
|
|
|
|
lnk->remote
|
|
|
|
|
? nm_sprintf_buf(str_remote, " remote %s", nm_inet4_ntop(lnk->remote, str_remote1))
|
|
|
|
|
: "",
|
|
|
|
|
lnk->local ? nm_sprintf_buf(str_local, " local %s", nm_inet4_ntop(lnk->local, str_local1))
|
|
|
|
|
: "",
|
|
|
|
|
lnk->parent_ifindex ? nm_sprintf_buf(str_parent_ifindex, " dev %d", lnk->parent_ifindex)
|
|
|
|
|
: "",
|
|
|
|
|
lnk->ikey ? nm_sprintf_buf(str_ikey, " ikey %u", lnk->ikey) : "",
|
|
|
|
|
lnk->okey ? nm_sprintf_buf(str_okey, " okey %u", lnk->okey) : "",
|
|
|
|
|
lnk->fwmark ? nm_sprintf_buf(str_fwmark, " fwmark 0x%x", lnk->fwmark) : "");
|
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-25 08:31:47 +02:00
|
|
|
const char *
|
|
|
|
|
nm_platform_lnk_vti6_to_string(const NMPlatformLnkVti6 *lnk, char *buf, gsize len)
|
|
|
|
|
{
|
|
|
|
|
char str_local[30 + NM_INET_ADDRSTRLEN];
|
|
|
|
|
char str_local1[NM_INET_ADDRSTRLEN];
|
|
|
|
|
char str_remote[30 + NM_INET_ADDRSTRLEN];
|
|
|
|
|
char str_remote1[NM_INET_ADDRSTRLEN];
|
|
|
|
|
char str_ikey[30];
|
|
|
|
|
char str_okey[30];
|
|
|
|
|
char str_fwmark[30];
|
|
|
|
|
char str_parent_ifindex[30];
|
|
|
|
|
|
|
|
|
|
if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len))
|
|
|
|
|
return buf;
|
|
|
|
|
|
|
|
|
|
g_snprintf(
|
|
|
|
|
buf,
|
|
|
|
|
len,
|
|
|
|
|
"vti6"
|
|
|
|
|
"%s" /* remote */
|
|
|
|
|
"%s" /* local */
|
|
|
|
|
"%s" /* parent_ifindex */
|
|
|
|
|
"%s" /* ikey */
|
|
|
|
|
"%s" /* okey */
|
|
|
|
|
"%s" /* fwmark */
|
|
|
|
|
"",
|
|
|
|
|
IN6_IS_ADDR_UNSPECIFIED(&lnk->remote)
|
|
|
|
|
? ""
|
|
|
|
|
: nm_sprintf_buf(str_remote, " remote %s", nm_inet6_ntop(&lnk->remote, str_remote1)),
|
|
|
|
|
IN6_IS_ADDR_UNSPECIFIED(&lnk->local)
|
|
|
|
|
? ""
|
|
|
|
|
: nm_sprintf_buf(str_local, " local %s", nm_inet6_ntop(&lnk->local, str_local1)),
|
|
|
|
|
lnk->parent_ifindex ? nm_sprintf_buf(str_parent_ifindex, " dev %d", lnk->parent_ifindex)
|
|
|
|
|
: "",
|
|
|
|
|
lnk->ikey ? nm_sprintf_buf(str_ikey, " ikey %u", lnk->ikey) : "",
|
|
|
|
|
lnk->okey ? nm_sprintf_buf(str_okey, " okey %u", lnk->okey) : "",
|
|
|
|
|
lnk->fwmark ? nm_sprintf_buf(str_fwmark, " fwmark 0x%x", lnk->fwmark) : "");
|
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-05 10:35:25 +01:00
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_vrf_to_string(const NMPlatformLnkVrf *lnk, char *buf, gsize len)
|
2019-12-05 10:35:25 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
char *b;
|
2019-12-05 10:35:25 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len))
|
|
|
|
|
return buf;
|
2019-12-05 10:35:25 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
b = buf;
|
2019-12-05 10:35:25 +01:00
|
|
|
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&b, &len, "table %u", lnk->table);
|
2020-09-28 16:03:33 +02:00
|
|
|
return buf;
|
2019-12-05 10:35:25 +01:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 15:15:21 +02:00
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_vxlan_to_string(const NMPlatformLnkVxlan *lnk, char *buf, gsize len)
|
|
|
|
|
{
|
|
|
|
|
char str_group[100];
|
|
|
|
|
char str_group6[100];
|
|
|
|
|
char str_local[100];
|
|
|
|
|
char str_local6[100];
|
2022-09-20 16:14:21 +02:00
|
|
|
char str_dev[30];
|
2020-09-28 16:03:33 +02:00
|
|
|
char str_limit[25];
|
|
|
|
|
char str_src_port[35];
|
|
|
|
|
char str_dst_port[25];
|
|
|
|
|
char str_tos[25];
|
|
|
|
|
char str_ttl[25];
|
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];
|
2020-09-28 16:03:33 +02:00
|
|
|
|
|
|
|
|
if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len))
|
|
|
|
|
return buf;
|
|
|
|
|
|
|
|
|
|
if (lnk->group == 0)
|
|
|
|
|
str_group[0] = '\0';
|
|
|
|
|
else {
|
|
|
|
|
g_snprintf(str_group,
|
|
|
|
|
sizeof(str_group),
|
|
|
|
|
" %s %s",
|
|
|
|
|
IN_MULTICAST(ntohl(lnk->group)) ? "group" : "remote",
|
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_inet4_ntop(lnk->group, sbuf));
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
if (IN6_IS_ADDR_UNSPECIFIED(&lnk->group6))
|
|
|
|
|
str_group6[0] = '\0';
|
|
|
|
|
else {
|
|
|
|
|
g_snprintf(str_group6,
|
|
|
|
|
sizeof(str_group6),
|
|
|
|
|
" %s%s %s",
|
|
|
|
|
IN6_IS_ADDR_MULTICAST(&lnk->group6) ? "group" : "remote",
|
|
|
|
|
str_group[0] ? "6" : "", /* usually, a vxlan has either v4 or v6 only. */
|
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_inet6_ntop(&lnk->group6, sbuf));
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (lnk->local == 0)
|
|
|
|
|
str_local[0] = '\0';
|
|
|
|
|
else {
|
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_snprintf(str_local, sizeof(str_local), " local %s", nm_inet4_ntop(lnk->local, sbuf));
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
if (IN6_IS_ADDR_UNSPECIFIED(&lnk->local6))
|
|
|
|
|
str_local6[0] = '\0';
|
|
|
|
|
else {
|
|
|
|
|
g_snprintf(str_local6,
|
|
|
|
|
sizeof(str_local6),
|
|
|
|
|
" local%s %s",
|
|
|
|
|
str_local[0] ? "6" : "", /* usually, a vxlan has either v4 or v6 only. */
|
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_inet6_ntop(&lnk->local6, sbuf));
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_snprintf(
|
|
|
|
|
buf,
|
|
|
|
|
len,
|
|
|
|
|
"vxlan"
|
|
|
|
|
" id %u" /* id */
|
|
|
|
|
"%s%s" /* group/group6 */
|
|
|
|
|
"%s%s" /* local/local6 */
|
|
|
|
|
"%s" /* dev */
|
|
|
|
|
"%s" /* src_port_min/src_port_max */
|
|
|
|
|
"%s" /* dst_port */
|
|
|
|
|
"%s" /* learning */
|
|
|
|
|
"%s" /* proxy */
|
|
|
|
|
"%s" /* rsc */
|
|
|
|
|
"%s" /* l2miss */
|
|
|
|
|
"%s" /* l3miss */
|
|
|
|
|
"%s" /* tos */
|
|
|
|
|
"%s" /* ttl */
|
|
|
|
|
" ageing %u" /* ageing */
|
|
|
|
|
"%s" /* limit */
|
|
|
|
|
"",
|
|
|
|
|
(guint) lnk->id,
|
|
|
|
|
str_group,
|
|
|
|
|
str_group6,
|
|
|
|
|
str_local,
|
|
|
|
|
str_local6,
|
2022-09-20 16:14:21 +02:00
|
|
|
_to_string_dev(str_dev, lnk->parent_ifindex),
|
2020-09-28 16:03:33 +02:00
|
|
|
lnk->src_port_min || lnk->src_port_max
|
|
|
|
|
? nm_sprintf_buf(str_src_port, " srcport %u %u", lnk->src_port_min, lnk->src_port_max)
|
|
|
|
|
: "",
|
|
|
|
|
lnk->dst_port ? nm_sprintf_buf(str_dst_port, " dstport %u", lnk->dst_port) : "",
|
|
|
|
|
!lnk->learning ? " nolearning" : "",
|
|
|
|
|
lnk->proxy ? " proxy" : "",
|
|
|
|
|
lnk->rsc ? " rsc" : "",
|
|
|
|
|
lnk->l2miss ? " l2miss" : "",
|
|
|
|
|
lnk->l3miss ? " l3miss" : "",
|
|
|
|
|
lnk->tos == 1 ? " tos inherit" : nm_sprintf_buf(str_tos, " tos %#x", lnk->tos),
|
|
|
|
|
lnk->ttl ? nm_sprintf_buf(str_ttl, " ttl %u", lnk->ttl) : "",
|
|
|
|
|
lnk->ageing,
|
|
|
|
|
lnk->limit ? nm_sprintf_buf(str_limit, " maxaddr %u", lnk->limit) : "");
|
|
|
|
|
return buf;
|
2015-10-12 15:15:21 +02:00
|
|
|
}
|
|
|
|
|
|
2018-03-13 13:35:35 +00:00
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_wireguard_peer_to_string(const NMPWireGuardPeer *peer, char *buf, gsize len)
|
|
|
|
|
{
|
2021-11-09 13:28:54 +01:00
|
|
|
char *buf0 = buf;
|
2020-09-28 16:03:33 +02:00
|
|
|
gs_free char *public_key_b64 = 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 s_sockaddr[NM_INET_ADDRSTRLEN + 100];
|
2020-09-28 16:03:33 +02:00
|
|
|
char s_endpoint[20 + sizeof(s_sockaddr)];
|
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 s_addr[NM_INET_ADDRSTRLEN];
|
2020-09-28 16:03:33 +02:00
|
|
|
char s_keepalive[100];
|
|
|
|
|
guint i;
|
|
|
|
|
|
|
|
|
|
nm_utils_to_string_buffer_init(&buf, &len);
|
|
|
|
|
|
|
|
|
|
public_key_b64 = g_base64_encode(peer->public_key, sizeof(peer->public_key));
|
|
|
|
|
|
|
|
|
|
if (peer->endpoint.sa.sa_family != AF_UNSPEC) {
|
|
|
|
|
nm_sprintf_buf(
|
|
|
|
|
s_endpoint,
|
|
|
|
|
" endpoint %s",
|
|
|
|
|
nm_sock_addr_union_to_string(&peer->endpoint, s_sockaddr, sizeof(s_sockaddr)));
|
|
|
|
|
} else
|
|
|
|
|
s_endpoint[0] = '\0';
|
|
|
|
|
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf,
|
|
|
|
|
&len,
|
|
|
|
|
"public-key %s"
|
|
|
|
|
"%s" /* preshared-key */
|
|
|
|
|
"%s" /* endpoint */
|
|
|
|
|
" rx %" G_GUINT64_FORMAT " tx %" G_GUINT64_FORMAT
|
|
|
|
|
"%s" /* persistent-keepalive */
|
|
|
|
|
"%s", /* allowed-ips */
|
|
|
|
|
public_key_b64,
|
|
|
|
|
nm_utils_memeqzero_secret(peer->preshared_key, sizeof(peer->preshared_key))
|
|
|
|
|
? ""
|
|
|
|
|
: " preshared-key (hidden)",
|
|
|
|
|
s_endpoint,
|
|
|
|
|
peer->rx_bytes,
|
|
|
|
|
peer->tx_bytes,
|
|
|
|
|
peer->persistent_keepalive_interval > 0
|
|
|
|
|
? nm_sprintf_buf(s_keepalive,
|
|
|
|
|
" keepalive %u",
|
|
|
|
|
(guint) peer->persistent_keepalive_interval)
|
|
|
|
|
: "",
|
|
|
|
|
peer->allowed_ips_len > 0 ? " allowed-ips" : "");
|
2020-09-28 16:03:33 +02:00
|
|
|
|
|
|
|
|
for (i = 0; i < peer->allowed_ips_len; i++) {
|
|
|
|
|
const NMPWireGuardAllowedIP *allowed_ip = &peer->allowed_ips[i];
|
|
|
|
|
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf,
|
|
|
|
|
&len,
|
|
|
|
|
" %s/%u",
|
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_inet_ntop(allowed_ip->family, &allowed_ip->addr, s_addr),
|
2021-07-30 08:53:16 +02:00
|
|
|
allowed_ip->mask);
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return buf0;
|
2018-03-13 13:35:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_wireguard_to_string(const NMPlatformLnkWireGuard *lnk, char *buf, gsize len)
|
2018-03-13 13:35:35 +00:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
gs_free char *public_b64 = NULL;
|
2018-03-13 13:35:35 +00:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len))
|
|
|
|
|
return buf;
|
2018-03-13 13:35:35 +00:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!nm_utils_memeqzero(lnk->public_key, sizeof(lnk->public_key)))
|
|
|
|
|
public_b64 = g_base64_encode(lnk->public_key, sizeof(lnk->public_key));
|
2018-03-13 13:35:35 +00:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_snprintf(buf,
|
|
|
|
|
len,
|
|
|
|
|
"wireguard"
|
|
|
|
|
"%s%s" /* public-key */
|
|
|
|
|
"%s" /* private-key */
|
|
|
|
|
" listen-port %u"
|
|
|
|
|
" fwmark 0x%x",
|
|
|
|
|
public_b64 ? " public-key " : "",
|
|
|
|
|
public_b64 ?: "",
|
|
|
|
|
nm_utils_memeqzero_secret(lnk->private_key, sizeof(lnk->private_key))
|
|
|
|
|
? ""
|
|
|
|
|
: " private-key (hidden)",
|
|
|
|
|
lnk->listen_port,
|
|
|
|
|
lnk->fwmark);
|
2018-03-13 13:35:35 +00:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return buf;
|
2018-03-13 13:35:35 +00:00
|
|
|
}
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
static NM_UTILS_FLAGS2STR_DEFINE(_rtm_flags_to_string,
|
|
|
|
|
unsigned,
|
|
|
|
|
NM_UTILS_FLAGS2STR(RTNH_F_DEAD, "dead"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(RTNH_F_PERVASIVE, "pervasive"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(RTNH_F_ONLINK, "onlink"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(8 /*RTNH_F_OFFLOAD*/, "offload"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(16 /*RTNH_F_LINKDOWN*/, "linkdown"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(32 /*RTNH_F_UNRESOLVED*/, "unresolved"),
|
|
|
|
|
|
|
|
|
|
NM_UTILS_FLAGS2STR(RTM_F_NOTIFY, "notify"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(RTM_F_CLONED, "cloned"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(RTM_F_EQUALIZE, "equalize"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(RTM_F_PREFIX, "prefix"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(0x1000 /*RTM_F_LOOKUP_TABLE*/, "lookup-table"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(0x2000 /*RTM_F_FIB_MATCH*/, "fib-match"), );
|
2017-11-07 15:32:55 +01:00
|
|
|
|
|
|
|
|
#define _RTM_FLAGS_TO_STRING_MAXLEN 200
|
|
|
|
|
|
|
|
|
|
static const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
_rtm_flags_to_string_full(char *buf, gsize buf_size, unsigned rtm_flags)
|
2017-11-07 15:32:55 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const char *buf0 = buf;
|
2017-11-07 15:32:55 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_assert(buf_size >= _RTM_FLAGS_TO_STRING_MAXLEN);
|
2017-11-07 15:32:55 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!rtm_flags)
|
|
|
|
|
return "";
|
2017-11-07 15:32:55 +01:00
|
|
|
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&buf, &buf_size, " rtm_flags ");
|
2020-09-28 16:03:33 +02:00
|
|
|
_rtm_flags_to_string(rtm_flags, buf, buf_size);
|
|
|
|
|
nm_assert(strlen(buf) < buf_size);
|
|
|
|
|
return buf0;
|
2017-11-07 15:32:55 +01:00
|
|
|
}
|
|
|
|
|
|
2013-08-26 22:10:11 +02:00
|
|
|
/**
|
|
|
|
|
* nm_platform_ip4_route_to_string:
|
|
|
|
|
* @route: pointer to NMPlatformIP4Route route structure
|
2023-03-01 01:21:38 +01:00
|
|
|
* @extra_nexthops: (nullable): the route might be a ECMP multihop route
|
2022-09-15 14:03:51 +02:00
|
|
|
* (with n_nexthops > 1). In that case, provide the list of extra hops
|
|
|
|
|
* to print too. It is allowed for a multihop route to omit the extra hops
|
|
|
|
|
* by passing NULL.
|
2023-03-01 01:21:38 +01:00
|
|
|
* @buf: (nullable): an optional buffer. If %NULL, a static buffer is used.
|
2015-10-12 10:27:33 +02:00
|
|
|
* @len: the size of the @buf. If @buf is %NULL, this argument is ignored.
|
2013-08-26 22:10:11 +02:00
|
|
|
*
|
|
|
|
|
* A method for converting a route struct into a string representation.
|
|
|
|
|
*
|
2013-08-29 20:07:34 +02:00
|
|
|
* Example output: "192.168.1.0/24 via 0.0.0.0 dev em1 metric 0 mss 0"
|
|
|
|
|
*
|
2015-10-12 10:27:33 +02:00
|
|
|
* Returns: a string representation of the route.
|
2013-08-26 22:10:11 +02:00
|
|
|
*/
|
2013-08-29 20:07:34 +02:00
|
|
|
const char *
|
2022-09-15 14:03:51 +02:00
|
|
|
nm_platform_ip4_route_to_string_full(const NMPlatformIP4Route *route,
|
|
|
|
|
const NMPlatformIP4RtNextHop *extra_nexthops,
|
|
|
|
|
char *buf,
|
|
|
|
|
gsize len)
|
|
|
|
|
{
|
|
|
|
|
char *buf0;
|
|
|
|
|
char s_network[INET_ADDRSTRLEN];
|
|
|
|
|
char s_gateway[INET_ADDRSTRLEN];
|
|
|
|
|
char s_pref_src[INET_ADDRSTRLEN];
|
|
|
|
|
char str_dev[30];
|
|
|
|
|
char str_mss[32];
|
|
|
|
|
char str_table[30];
|
|
|
|
|
char str_scope[30];
|
|
|
|
|
char s_source[50];
|
|
|
|
|
char str_tos[32];
|
|
|
|
|
char str_window[32];
|
|
|
|
|
char str_cwnd[32];
|
|
|
|
|
char str_initcwnd[32];
|
|
|
|
|
char str_initrwnd[32];
|
|
|
|
|
char str_rto_min[32];
|
|
|
|
|
char str_mtu[32];
|
|
|
|
|
char str_rtm_flags[_RTM_FLAGS_TO_STRING_MAXLEN];
|
|
|
|
|
char str_type[30];
|
|
|
|
|
char str_metric[30];
|
|
|
|
|
char weight_str[20];
|
|
|
|
|
guint n_nexthops;
|
2020-09-28 16:03:33 +02:00
|
|
|
|
|
|
|
|
if (!nm_utils_to_string_buffer_init_null(route, &buf, &len))
|
|
|
|
|
return buf;
|
|
|
|
|
|
2022-09-15 14:03:51 +02:00
|
|
|
buf0 = buf;
|
|
|
|
|
|
|
|
|
|
n_nexthops = nm_platform_ip4_route_get_n_nexthops(route);
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
inet_ntop(AF_INET, &route->network, s_network, sizeof(s_network));
|
2022-02-02 08:15:45 +01:00
|
|
|
|
|
|
|
|
if (route->gateway == 0)
|
|
|
|
|
s_gateway[0] = '\0';
|
|
|
|
|
else
|
|
|
|
|
inet_ntop(AF_INET, &route->gateway, s_gateway, sizeof(s_gateway));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
2022-09-15 14:03:51 +02:00
|
|
|
nm_strbuf_append(
|
|
|
|
|
&buf,
|
|
|
|
|
&len,
|
2020-09-28 16:03:33 +02:00
|
|
|
"type %s " /* type */
|
|
|
|
|
"%s" /* table */
|
|
|
|
|
"%s/%d"
|
2022-02-02 08:15:45 +01:00
|
|
|
"%s%s" /* gateway */
|
2022-09-15 14:03:51 +02:00
|
|
|
"%s%s" /* weight */
|
|
|
|
|
"%s" /* dev/ifindex */
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
" metric %s"
|
2022-06-23 21:59:40 +02:00
|
|
|
"%s" /* mss */
|
|
|
|
|
" rt-src %s" /* protocol */
|
|
|
|
|
"%s" /* rtm_flags */
|
|
|
|
|
"%s%s" /* scope */
|
|
|
|
|
"%s%s" /* pref-src */
|
|
|
|
|
"%s" /* tos */
|
|
|
|
|
"%s" /* window */
|
|
|
|
|
"%s" /* cwnd */
|
|
|
|
|
"%s" /* initcwnd */
|
|
|
|
|
"%s" /* initrwnd */
|
|
|
|
|
"%s" /* rto_min */
|
|
|
|
|
"%s" /* quickack */
|
|
|
|
|
"%s" /* mtu */
|
2020-09-28 16:03:33 +02:00
|
|
|
"",
|
2021-03-19 10:46:41 +01:00
|
|
|
nm_net_aux_rtnl_rtntype_n2a_maybe_buf(nm_platform_route_type_uncoerce(route->type_coerced),
|
|
|
|
|
str_type),
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
route->table_any
|
|
|
|
|
? "table ?? "
|
|
|
|
|
: (route->table_coerced
|
|
|
|
|
? nm_sprintf_buf(str_table,
|
|
|
|
|
"table %u ",
|
|
|
|
|
nm_platform_route_table_uncoerce(route->table_coerced, FALSE))
|
|
|
|
|
: ""),
|
2020-09-28 16:03:33 +02:00
|
|
|
s_network,
|
|
|
|
|
route->plen,
|
2022-09-15 14:03:51 +02:00
|
|
|
n_nexthops <= 1 && s_gateway[0] ? " via " : "",
|
|
|
|
|
n_nexthops <= 1 ? s_gateway : "",
|
|
|
|
|
NM_PRINT_FMT_QUOTED2(n_nexthops <= 1 && route->weight != 0,
|
|
|
|
|
" weight ",
|
|
|
|
|
nm_sprintf_buf(weight_str, "%u", route->weight),
|
|
|
|
|
""),
|
|
|
|
|
n_nexthops <= 1 ? _to_string_dev(str_dev, route->ifindex) : "",
|
2020-10-22 10:29:03 +02:00
|
|
|
route->metric_any
|
|
|
|
|
? (route->metric ? nm_sprintf_buf(str_metric, "??+%u", route->metric) : "??")
|
|
|
|
|
: nm_sprintf_buf(str_metric, "%u", route->metric),
|
2022-06-23 21:59:40 +02:00
|
|
|
nm_sprintf_buf(str_mss,
|
|
|
|
|
" mss %s%" G_GUINT32_FORMAT,
|
|
|
|
|
route->lock_mss ? "lock " : "",
|
|
|
|
|
route->mss),
|
2020-09-28 16:03:33 +02:00
|
|
|
nmp_utils_ip_config_source_to_string(route->rt_source, s_source, sizeof(s_source)),
|
|
|
|
|
_rtm_flags_to_string_full(str_rtm_flags, sizeof(str_rtm_flags), route->r_rtm_flags),
|
|
|
|
|
route->scope_inv ? " scope " : "",
|
|
|
|
|
route->scope_inv
|
|
|
|
|
? (nm_platform_route_scope2str(nm_platform_route_scope_inv(route->scope_inv),
|
|
|
|
|
str_scope,
|
|
|
|
|
sizeof(str_scope)))
|
|
|
|
|
: "",
|
|
|
|
|
route->pref_src ? " pref-src " : "",
|
|
|
|
|
route->pref_src ? inet_ntop(AF_INET, &route->pref_src, s_pref_src, sizeof(s_pref_src)) : "",
|
|
|
|
|
route->tos ? nm_sprintf_buf(str_tos, " tos 0x%x", (unsigned) route->tos) : "",
|
|
|
|
|
route->window || route->lock_window ? nm_sprintf_buf(str_window,
|
|
|
|
|
" window %s%" G_GUINT32_FORMAT,
|
|
|
|
|
route->lock_window ? "lock " : "",
|
|
|
|
|
route->window)
|
|
|
|
|
: "",
|
|
|
|
|
route->cwnd || route->lock_cwnd ? nm_sprintf_buf(str_cwnd,
|
|
|
|
|
" cwnd %s%" G_GUINT32_FORMAT,
|
|
|
|
|
route->lock_cwnd ? "lock " : "",
|
|
|
|
|
route->cwnd)
|
|
|
|
|
: "",
|
|
|
|
|
route->initcwnd || route->lock_initcwnd
|
|
|
|
|
? nm_sprintf_buf(str_initcwnd,
|
|
|
|
|
" initcwnd %s%" G_GUINT32_FORMAT,
|
|
|
|
|
route->lock_initcwnd ? "lock " : "",
|
|
|
|
|
route->initcwnd)
|
|
|
|
|
: "",
|
|
|
|
|
route->initrwnd || route->lock_initrwnd
|
|
|
|
|
? nm_sprintf_buf(str_initrwnd,
|
|
|
|
|
" initrwnd %s%" G_GUINT32_FORMAT,
|
|
|
|
|
route->lock_initrwnd ? "lock " : "",
|
|
|
|
|
route->initrwnd)
|
|
|
|
|
: "",
|
2022-06-23 21:59:40 +02:00
|
|
|
route->rto_min ? nm_sprintf_buf(str_rto_min, " rto_min %" G_GUINT32_FORMAT, route->rto_min)
|
|
|
|
|
: "",
|
|
|
|
|
route->quickack ? " quickack 1" : "",
|
2020-09-28 16:03:33 +02:00
|
|
|
route->mtu || route->lock_mtu ? nm_sprintf_buf(str_mtu,
|
|
|
|
|
" mtu %s%" G_GUINT32_FORMAT,
|
|
|
|
|
route->lock_mtu ? "lock " : "",
|
|
|
|
|
route->mtu)
|
2023-02-28 14:29:50 +01:00
|
|
|
: "");
|
2022-09-15 14:03:51 +02:00
|
|
|
|
|
|
|
|
if ((n_nexthops == 1 && route->ifindex > 0) || n_nexthops == 0) {
|
|
|
|
|
/* A plain single hop route. Nothing extra to remark. */
|
|
|
|
|
} else {
|
|
|
|
|
nm_strbuf_append(&buf, &len, " n_nexthops %u", n_nexthops);
|
|
|
|
|
if (n_nexthops > 1) {
|
|
|
|
|
nm_strbuf_append(&buf,
|
|
|
|
|
&len,
|
|
|
|
|
" nexthop"
|
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
|
|
|
"%s%s" /* gateway */
|
|
|
|
|
" weight %s" /* weight */
|
|
|
|
|
"%s" /* dev/ifindex */
|
2022-09-15 14:03:51 +02:00
|
|
|
"",
|
|
|
|
|
s_gateway[0] ? " via " : "",
|
|
|
|
|
s_gateway,
|
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
|
|
|
nm_sprintf_buf(weight_str, "%u", route->weight),
|
2022-09-15 14:03:51 +02:00
|
|
|
_to_string_dev(str_dev, route->ifindex));
|
|
|
|
|
if (!extra_nexthops)
|
|
|
|
|
nm_strbuf_append_str(&buf, &len, " nexthops [...]");
|
|
|
|
|
else {
|
|
|
|
|
guint i;
|
|
|
|
|
|
|
|
|
|
for (i = 1; i < n_nexthops; i++) {
|
|
|
|
|
const NMPlatformIP4RtNextHop *nexthop = &extra_nexthops[i - 1];
|
|
|
|
|
|
|
|
|
|
nm_strbuf_append(
|
|
|
|
|
&buf,
|
|
|
|
|
&len,
|
|
|
|
|
" nexthop"
|
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
|
|
|
"%s" /* ifindex */
|
|
|
|
|
"%s%s" /* gateway */
|
|
|
|
|
" weight %s" /* weight */
|
2022-09-15 14:03:51 +02:00
|
|
|
"",
|
|
|
|
|
NM_PRINT_FMT_QUOTED2(nexthop->gateway != 0 || nexthop->ifindex <= 0,
|
|
|
|
|
" via ",
|
|
|
|
|
nm_inet4_ntop(nexthop->gateway, s_gateway),
|
|
|
|
|
""),
|
|
|
|
|
_to_string_dev(str_dev, nexthop->ifindex),
|
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
|
|
|
nm_sprintf_buf(weight_str, "%u", nexthop->weight));
|
2022-09-15 14:03:51 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return buf0;
|
2013-08-29 20:07:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* nm_platform_ip6_route_to_string:
|
|
|
|
|
* @route: pointer to NMPlatformIP6Route route structure
|
2023-03-01 01:21:38 +01:00
|
|
|
* @buf: (nullable): an optional buffer. If %NULL, a static buffer is used.
|
2015-10-12 10:27:33 +02:00
|
|
|
* @len: the size of the @buf. If @buf is %NULL, this argument is ignored.
|
2013-08-29 20:07:34 +02:00
|
|
|
*
|
|
|
|
|
* A method for converting a route struct into a string representation.
|
|
|
|
|
*
|
|
|
|
|
* Example output: "ff02::fb/128 via :: dev em1 metric 0"
|
|
|
|
|
*
|
2015-10-12 10:27:33 +02:00
|
|
|
* Returns: a string representation of the route.
|
2013-08-29 20:07:34 +02:00
|
|
|
*/
|
|
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_ip6_route_to_string(const NMPlatformIP6Route *route, char *buf, gsize len)
|
|
|
|
|
{
|
|
|
|
|
char s_network[INET6_ADDRSTRLEN];
|
|
|
|
|
char s_gateway[INET6_ADDRSTRLEN];
|
|
|
|
|
char s_pref_src[INET6_ADDRSTRLEN];
|
|
|
|
|
char s_src_all[INET6_ADDRSTRLEN + 40];
|
|
|
|
|
char s_src[INET6_ADDRSTRLEN];
|
|
|
|
|
char str_type[30];
|
|
|
|
|
char str_table[30];
|
|
|
|
|
char str_pref[40];
|
|
|
|
|
char str_pref2[30];
|
2022-09-20 16:14:21 +02:00
|
|
|
char str_dev[30];
|
2022-06-23 21:59:40 +02:00
|
|
|
char str_mss[32];
|
2020-09-28 16:03:33 +02:00
|
|
|
char s_source[50];
|
|
|
|
|
char str_window[32];
|
|
|
|
|
char str_cwnd[32];
|
|
|
|
|
char str_initcwnd[32];
|
|
|
|
|
char str_initrwnd[32];
|
2022-06-23 21:59:40 +02:00
|
|
|
char str_rto_min[32];
|
2020-09-28 16:03:33 +02:00
|
|
|
char str_mtu[32];
|
|
|
|
|
char str_rtm_flags[_RTM_FLAGS_TO_STRING_MAXLEN];
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
char str_metric[30];
|
2020-09-28 16:03:33 +02:00
|
|
|
|
|
|
|
|
if (!nm_utils_to_string_buffer_init_null(route, &buf, &len))
|
|
|
|
|
return buf;
|
|
|
|
|
|
|
|
|
|
inet_ntop(AF_INET6, &route->network, s_network, sizeof(s_network));
|
2022-02-02 08:15:45 +01:00
|
|
|
|
|
|
|
|
if (IN6_IS_ADDR_UNSPECIFIED(&route->gateway))
|
|
|
|
|
s_gateway[0] = '\0';
|
|
|
|
|
else
|
|
|
|
|
inet_ntop(AF_INET6, &route->gateway, s_gateway, sizeof(s_gateway));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
|
|
|
|
if (IN6_IS_ADDR_UNSPECIFIED(&route->pref_src))
|
|
|
|
|
s_pref_src[0] = 0;
|
|
|
|
|
else
|
|
|
|
|
inet_ntop(AF_INET6, &route->pref_src, s_pref_src, sizeof(s_pref_src));
|
|
|
|
|
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
g_snprintf(
|
|
|
|
|
buf,
|
|
|
|
|
len,
|
|
|
|
|
"type %s " /* type */
|
|
|
|
|
"%s" /* table */
|
|
|
|
|
"%s/%d"
|
2022-02-02 08:15:45 +01:00
|
|
|
"%s%s" /* gateway */
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
"%s"
|
|
|
|
|
" metric %s"
|
2022-06-23 21:59:40 +02:00
|
|
|
"%s" /* mss */
|
|
|
|
|
" rt-src %s" /* protocol */
|
|
|
|
|
"%s" /* source */
|
|
|
|
|
"%s" /* rtm_flags */
|
|
|
|
|
"%s%s" /* pref-src */
|
|
|
|
|
"%s" /* window */
|
|
|
|
|
"%s" /* cwnd */
|
|
|
|
|
"%s" /* initcwnd */
|
|
|
|
|
"%s" /* initrwnd */
|
|
|
|
|
"%s" /* rto_min */
|
|
|
|
|
"%s" /* quickack */
|
|
|
|
|
"%s" /* mtu */
|
|
|
|
|
"%s" /* pref */
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
"",
|
2021-03-19 10:46:41 +01:00
|
|
|
nm_net_aux_rtnl_rtntype_n2a_maybe_buf(nm_platform_route_type_uncoerce(route->type_coerced),
|
|
|
|
|
str_type),
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
route->table_any
|
|
|
|
|
? "table ?? "
|
|
|
|
|
: (route->table_coerced
|
2020-09-28 16:03:33 +02:00
|
|
|
? nm_sprintf_buf(str_table,
|
|
|
|
|
"table %u ",
|
|
|
|
|
nm_platform_route_table_uncoerce(route->table_coerced, FALSE))
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
: ""),
|
|
|
|
|
s_network,
|
|
|
|
|
route->plen,
|
2022-02-02 08:15:45 +01:00
|
|
|
s_gateway[0] ? " via " : "",
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
s_gateway,
|
2022-09-20 16:14:21 +02:00
|
|
|
_to_string_dev(str_dev, route->ifindex),
|
2020-10-22 10:29:03 +02:00
|
|
|
route->metric_any
|
|
|
|
|
? (route->metric ? nm_sprintf_buf(str_metric, "??+%u", route->metric) : "??")
|
|
|
|
|
: nm_sprintf_buf(str_metric, "%u", route->metric),
|
2022-06-23 21:59:40 +02:00
|
|
|
nm_sprintf_buf(str_mss,
|
|
|
|
|
" mss %s%" G_GUINT32_FORMAT,
|
|
|
|
|
route->lock_mss ? "lock " : "",
|
|
|
|
|
route->mss),
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
nmp_utils_ip_config_source_to_string(route->rt_source, s_source, sizeof(s_source)),
|
|
|
|
|
route->src_plen || !IN6_IS_ADDR_UNSPECIFIED(&route->src)
|
|
|
|
|
? nm_sprintf_buf(s_src_all,
|
|
|
|
|
" src %s/%u",
|
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_inet6_ntop(&route->src, s_src),
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
(unsigned) route->src_plen)
|
|
|
|
|
: "",
|
|
|
|
|
_rtm_flags_to_string_full(str_rtm_flags, sizeof(str_rtm_flags), route->r_rtm_flags),
|
|
|
|
|
s_pref_src[0] ? " pref-src " : "",
|
|
|
|
|
s_pref_src[0] ? s_pref_src : "",
|
|
|
|
|
route->window || route->lock_window ? nm_sprintf_buf(str_window,
|
|
|
|
|
" window %s%" G_GUINT32_FORMAT,
|
|
|
|
|
route->lock_window ? "lock " : "",
|
|
|
|
|
route->window)
|
|
|
|
|
: "",
|
|
|
|
|
route->cwnd || route->lock_cwnd ? nm_sprintf_buf(str_cwnd,
|
|
|
|
|
" cwnd %s%" G_GUINT32_FORMAT,
|
|
|
|
|
route->lock_cwnd ? "lock " : "",
|
|
|
|
|
route->cwnd)
|
|
|
|
|
: "",
|
|
|
|
|
route->initcwnd || route->lock_initcwnd
|
|
|
|
|
? nm_sprintf_buf(str_initcwnd,
|
|
|
|
|
" initcwnd %s%" G_GUINT32_FORMAT,
|
|
|
|
|
route->lock_initcwnd ? "lock " : "",
|
|
|
|
|
route->initcwnd)
|
|
|
|
|
: "",
|
|
|
|
|
route->initrwnd || route->lock_initrwnd
|
|
|
|
|
? nm_sprintf_buf(str_initrwnd,
|
|
|
|
|
" initrwnd %s%" G_GUINT32_FORMAT,
|
|
|
|
|
route->lock_initrwnd ? "lock " : "",
|
|
|
|
|
route->initrwnd)
|
|
|
|
|
: "",
|
2022-06-23 21:59:40 +02:00
|
|
|
route->rto_min ? nm_sprintf_buf(str_rto_min, " rto_min %" G_GUINT32_FORMAT, route->rto_min)
|
|
|
|
|
: "",
|
|
|
|
|
route->quickack ? " quickack 1" : "",
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
route->mtu || route->lock_mtu ? nm_sprintf_buf(str_mtu,
|
|
|
|
|
" mtu %s%" G_GUINT32_FORMAT,
|
|
|
|
|
route->lock_mtu ? "lock " : "",
|
|
|
|
|
route->mtu)
|
|
|
|
|
: "",
|
|
|
|
|
route->rt_pref ? nm_sprintf_buf(
|
|
|
|
|
str_pref,
|
|
|
|
|
" pref %s",
|
|
|
|
|
nm_icmpv6_router_pref_to_string(route->rt_pref, str_pref2, sizeof(str_pref2)))
|
2023-02-28 14:29:50 +01:00
|
|
|
: "");
|
2020-09-28 16:03:33 +02:00
|
|
|
|
|
|
|
|
return buf;
|
2013-08-26 22:10:11 +02:00
|
|
|
}
|
|
|
|
|
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
static void
|
2021-11-09 13:28:54 +01:00
|
|
|
_routing_rule_addr_to_string(char **buf,
|
|
|
|
|
gsize *len,
|
2020-09-28 16:03:33 +02:00
|
|
|
int addr_family,
|
|
|
|
|
const NMIPAddr *addr,
|
|
|
|
|
guint8 plen,
|
|
|
|
|
gboolean is_src)
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01: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
|
|
|
char s_addr[NM_INET_ADDRSTRLEN];
|
2020-09-28 16:03:33 +02:00
|
|
|
gboolean is_zero;
|
|
|
|
|
gsize addr_size;
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_assert_addr_family(addr_family);
|
|
|
|
|
nm_assert(addr);
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
addr_size = nm_utils_addr_family_to_size(addr_family);
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
is_zero = nm_utils_memeqzero(addr, addr_size);
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (plen == 0 && is_zero) {
|
|
|
|
|
if (is_src)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(buf, len, " from all");
|
2020-09-28 16:03:33 +02:00
|
|
|
else
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(buf, len, "");
|
2020-09-28 16:03:33 +02:00
|
|
|
return;
|
|
|
|
|
}
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(buf, len, is_src ? " from " : " to ");
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01: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
|
|
|
nm_strbuf_append_str(buf, len, nm_inet_ntop(addr_family, addr, s_addr));
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (plen != (addr_size * 8))
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(buf, len, "/%u", plen);
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2021-11-09 13:28:54 +01:00
|
|
|
_routing_rule_port_range_to_string(char **buf,
|
|
|
|
|
gsize *len,
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMFibRulePortRange *port_range,
|
2021-11-09 13:28:54 +01:00
|
|
|
const char *name)
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
if (port_range->start == 0 && port_range->end == 0)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(buf, len, "");
|
2020-09-28 16:03:33 +02:00
|
|
|
else {
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(buf, len, " %s %u", name, port_range->start);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (port_range->start != port_range->end)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(buf, len, "-%u", port_range->end);
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_routing_rule_to_string(const NMPlatformRoutingRule *routing_rule, char *buf, gsize len)
|
|
|
|
|
{
|
|
|
|
|
const char *buf0;
|
|
|
|
|
guint32 rr_flags;
|
|
|
|
|
|
|
|
|
|
if (!nm_utils_to_string_buffer_init_null(routing_rule, &buf, &len))
|
|
|
|
|
return buf;
|
|
|
|
|
|
|
|
|
|
if (!NM_IN_SET(routing_rule->addr_family, AF_INET, AF_INET6)) {
|
|
|
|
|
/* invalid addr-family. The other fields are undefined. */
|
|
|
|
|
if (routing_rule->addr_family == AF_UNSPEC)
|
|
|
|
|
g_snprintf(buf, len, "[routing-rule]");
|
|
|
|
|
else
|
|
|
|
|
g_snprintf(buf, len, "[routing-rule family:%u]", routing_rule->addr_family);
|
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buf0 = buf;
|
|
|
|
|
|
|
|
|
|
rr_flags = routing_rule->flags;
|
|
|
|
|
|
|
|
|
|
rr_flags = NM_FLAGS_UNSET(rr_flags, FIB_RULE_INVERT);
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf,
|
|
|
|
|
&len,
|
|
|
|
|
"[%c] " /* addr-family */
|
|
|
|
|
"%u:" /* priority */
|
|
|
|
|
"%s", /* not/FIB_RULE_INVERT */
|
|
|
|
|
nm_utils_addr_family_to_char(routing_rule->addr_family),
|
|
|
|
|
routing_rule->priority,
|
|
|
|
|
(NM_FLAGS_HAS(routing_rule->flags, FIB_RULE_INVERT) ? " not" : ""));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
|
|
|
|
_routing_rule_addr_to_string(&buf,
|
|
|
|
|
&len,
|
|
|
|
|
routing_rule->addr_family,
|
|
|
|
|
&routing_rule->src,
|
|
|
|
|
routing_rule->src_len,
|
|
|
|
|
TRUE);
|
|
|
|
|
|
|
|
|
|
_routing_rule_addr_to_string(&buf,
|
|
|
|
|
&len,
|
|
|
|
|
routing_rule->addr_family,
|
|
|
|
|
&routing_rule->dst,
|
|
|
|
|
routing_rule->dst_len,
|
|
|
|
|
FALSE);
|
|
|
|
|
|
|
|
|
|
if (routing_rule->tos)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " tos 0x%02x", routing_rule->tos);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
|
|
|
|
if (routing_rule->fwmark != 0 || routing_rule->fwmask != 0) {
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " fwmark %#x", (unsigned) routing_rule->fwmark);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (routing_rule->fwmark != 0xFFFFFFFFu)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, "/%#x", (unsigned) routing_rule->fwmask);
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (routing_rule->iifname[0]) {
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " iif %s", routing_rule->iifname);
|
2020-09-28 16:03:33 +02:00
|
|
|
rr_flags = NM_FLAGS_UNSET(rr_flags, FIB_RULE_IIF_DETACHED);
|
|
|
|
|
if (NM_FLAGS_HAS(routing_rule->flags, FIB_RULE_IIF_DETACHED))
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&buf, &len, " [detached]");
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (routing_rule->oifname[0]) {
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " oif %s", routing_rule->oifname);
|
2020-09-28 16:03:33 +02:00
|
|
|
rr_flags = NM_FLAGS_UNSET(rr_flags, FIB_RULE_OIF_DETACHED);
|
|
|
|
|
if (NM_FLAGS_HAS(routing_rule->flags, FIB_RULE_OIF_DETACHED))
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&buf, &len, " [detached]");
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (routing_rule->l3mdev != 0) {
|
|
|
|
|
if (routing_rule->l3mdev == 1)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&buf, &len, " lookup [l3mdev-table]");
|
2020-09-28 16:03:33 +02:00
|
|
|
else {
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf,
|
|
|
|
|
&len,
|
|
|
|
|
" lookup [l3mdev-table/%u]",
|
|
|
|
|
(unsigned) routing_rule->l3mdev);
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (routing_rule->uid_range_has || routing_rule->uid_range.start
|
|
|
|
|
|| routing_rule->uid_range.end) {
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf,
|
|
|
|
|
&len,
|
|
|
|
|
" uidrange %u-%u%s",
|
|
|
|
|
routing_rule->uid_range.start,
|
|
|
|
|
routing_rule->uid_range.end,
|
|
|
|
|
routing_rule->uid_range_has ? "" : "(?)");
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (routing_rule->ip_proto != 0) {
|
|
|
|
|
/* we don't call getprotobynumber(), just print the numeric value.
|
2020-09-28 14:50:01 +02:00
|
|
|
* This differs from what ip-rule prints. */
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " ipproto %u", routing_rule->ip_proto);
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_routing_rule_port_range_to_string(&buf, &len, &routing_rule->sport_range, "sport");
|
|
|
|
|
|
|
|
|
|
_routing_rule_port_range_to_string(&buf, &len, &routing_rule->dport_range, "dport");
|
|
|
|
|
|
|
|
|
|
if (routing_rule->tun_id != 0) {
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " tun_id %" G_GUINT64_FORMAT, routing_rule->tun_id);
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (routing_rule->table != 0) {
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " lookup %u", routing_rule->table);
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (routing_rule->suppress_prefixlen_inverse != 0) {
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf,
|
|
|
|
|
&len,
|
|
|
|
|
" suppress_prefixlen %d",
|
|
|
|
|
(int) (~routing_rule->suppress_prefixlen_inverse));
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (routing_rule->suppress_ifgroup_inverse != 0) {
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf,
|
|
|
|
|
&len,
|
|
|
|
|
" suppress_ifgroup %d",
|
|
|
|
|
(int) (~routing_rule->suppress_ifgroup_inverse));
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (routing_rule->flow) {
|
|
|
|
|
/* FRA_FLOW is only for IPv4, but we want to print the value for all address-families,
|
2020-09-28 14:50:01 +02:00
|
|
|
* to see when it is set. In practice, this should not be set except for IPv4.
|
|
|
|
|
*
|
|
|
|
|
* We don't follow the style how ip-rule prints flow/realms. It's confusing. Just
|
|
|
|
|
* print the value hex. */
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " realms 0x%08x", routing_rule->flow);
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (routing_rule->action == RTN_NAT) {
|
|
|
|
|
G_STATIC_ASSERT_EXPR(RTN_NAT == 10);
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* NAT is deprecated for many years. We don't support RTA_GATEWAY/FRA_UNUSED2
|
2020-09-28 14:50:01 +02:00
|
|
|
* for the gateway, and so do recent kernels ignore that parameter. */
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&buf, &len, " masquerade");
|
2020-09-28 16:03:33 +02:00
|
|
|
} else if (routing_rule->action == FR_ACT_GOTO) {
|
|
|
|
|
if (routing_rule->goto_target != 0)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " goto %u", routing_rule->goto_target);
|
2020-09-28 16:03:33 +02:00
|
|
|
else
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&buf, &len, " goto none");
|
2020-09-28 16:03:33 +02:00
|
|
|
rr_flags = NM_FLAGS_UNSET(rr_flags, FIB_RULE_UNRESOLVED);
|
|
|
|
|
if (NM_FLAGS_HAS(routing_rule->flags, FIB_RULE_UNRESOLVED))
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append_str(&buf, &len, " unresolved");
|
2020-09-28 16:03:33 +02:00
|
|
|
} else if (routing_rule->action != FR_ACT_TO_TBL) {
|
2021-03-19 10:46:41 +01:00
|
|
|
char ss_buf[60];
|
|
|
|
|
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf,
|
|
|
|
|
&len,
|
|
|
|
|
" %s",
|
|
|
|
|
nm_net_aux_rtnl_rtntype_n2a(routing_rule->action)
|
|
|
|
|
?: nm_sprintf_buf(ss_buf, "action-%u", routing_rule->action));
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (routing_rule->protocol != RTPROT_UNSPEC)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " protocol %u", routing_rule->protocol);
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (routing_rule->goto_target != 0 && routing_rule->action != FR_ACT_GOTO) {
|
|
|
|
|
/* a trailing target is set for an unexpected action. Print it. */
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " goto-target %u", routing_rule->goto_target);
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (rr_flags != 0) {
|
|
|
|
|
/* we have some flags we didn't print about yet. */
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " remaining-flags %x", rr_flags);
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return buf0;
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
}
|
|
|
|
|
|
2017-11-15 20:36:35 +01:00
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_qdisc_to_string(const NMPlatformQdisc *qdisc, char *buf, gsize len)
|
|
|
|
|
{
|
2022-09-20 16:14:21 +02:00
|
|
|
char str_dev[30];
|
2020-09-28 16:03:33 +02:00
|
|
|
const char *buf0;
|
|
|
|
|
|
|
|
|
|
if (!nm_utils_to_string_buffer_init_null(qdisc, &buf, &len))
|
|
|
|
|
return buf;
|
|
|
|
|
|
|
|
|
|
buf0 = buf;
|
|
|
|
|
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf,
|
|
|
|
|
&len,
|
|
|
|
|
"%s%s family %u handle %x parent %x info %x",
|
|
|
|
|
qdisc->kind,
|
2022-09-20 16:14:21 +02:00
|
|
|
_to_string_dev(str_dev, qdisc->ifindex),
|
2021-07-30 08:53:16 +02:00
|
|
|
qdisc->addr_family,
|
|
|
|
|
qdisc->handle,
|
|
|
|
|
qdisc->parent,
|
|
|
|
|
qdisc->info);
|
2020-09-28 16:03:33 +02:00
|
|
|
|
|
|
|
|
if (nm_streq0(qdisc->kind, "fq_codel")) {
|
|
|
|
|
if (qdisc->fq_codel.limit)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " limit %u", qdisc->fq_codel.limit);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (qdisc->fq_codel.flows)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " flows %u", qdisc->fq_codel.flows);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (qdisc->fq_codel.target)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " target %u", qdisc->fq_codel.target);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (qdisc->fq_codel.interval)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " interval %u", qdisc->fq_codel.interval);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (qdisc->fq_codel.quantum)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " quantum %u", qdisc->fq_codel.quantum);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (qdisc->fq_codel.ce_threshold != NM_PLATFORM_FQ_CODEL_CE_THRESHOLD_DISABLED)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " ce_threshold %u", qdisc->fq_codel.ce_threshold);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (qdisc->fq_codel.memory_limit != NM_PLATFORM_FQ_CODEL_MEMORY_LIMIT_UNSET)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " memory_limit %u", qdisc->fq_codel.memory_limit);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (qdisc->fq_codel.ecn)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " ecn");
|
2020-09-28 16:03:33 +02:00
|
|
|
} else if (nm_streq0(qdisc->kind, "sfq")) {
|
|
|
|
|
if (qdisc->sfq.quantum)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " quantum %u", qdisc->sfq.quantum);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (qdisc->sfq.perturb_period)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " perturb %d", qdisc->sfq.perturb_period);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (qdisc->sfq.limit)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " limit %u", (guint) qdisc->sfq.limit);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (qdisc->sfq.divisor)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " divisor %u", qdisc->sfq.divisor);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (qdisc->sfq.flows)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " flows %u", qdisc->sfq.flows);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (qdisc->sfq.depth)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " depth %u", qdisc->sfq.depth);
|
2020-09-28 16:03:33 +02:00
|
|
|
} else if (nm_streq0(qdisc->kind, "tbf")) {
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " rate %" G_GUINT64_FORMAT, qdisc->tbf.rate);
|
|
|
|
|
nm_strbuf_append(&buf, &len, " burst %u", qdisc->tbf.burst);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (qdisc->tbf.limit)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " limit %u", qdisc->tbf.limit);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (qdisc->tbf.latency)
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&buf, &len, " latency %uns", qdisc->tbf.latency);
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return buf0;
|
2017-11-15 20:36:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_qdisc_hash_update(const NMPlatformQdisc *obj, NMHashState *h)
|
|
|
|
|
{
|
|
|
|
|
nm_hash_update_str0(h, obj->kind);
|
|
|
|
|
nm_hash_update_vals(h, obj->ifindex, obj->addr_family, obj->handle, obj->parent, obj->info);
|
|
|
|
|
if (nm_streq0(obj->kind, "fq_codel")) {
|
|
|
|
|
nm_hash_update_vals(h,
|
|
|
|
|
obj->fq_codel.limit,
|
|
|
|
|
obj->fq_codel.flows,
|
|
|
|
|
obj->fq_codel.target,
|
|
|
|
|
obj->fq_codel.interval,
|
|
|
|
|
obj->fq_codel.quantum,
|
|
|
|
|
obj->fq_codel.ce_threshold,
|
|
|
|
|
obj->fq_codel.memory_limit,
|
|
|
|
|
NM_HASH_COMBINE_BOOLS(guint8, obj->fq_codel.ecn));
|
|
|
|
|
} else if (nm_streq0(obj->kind, "sfq")) {
|
|
|
|
|
nm_hash_update_vals(h,
|
|
|
|
|
obj->sfq.quantum,
|
|
|
|
|
obj->sfq.perturb_period,
|
|
|
|
|
obj->sfq.limit,
|
|
|
|
|
obj->sfq.divisor,
|
|
|
|
|
obj->sfq.flows,
|
|
|
|
|
obj->sfq.depth);
|
|
|
|
|
} else if (nm_streq0(obj->kind, "tbf")) {
|
|
|
|
|
nm_hash_update_vals(h, obj->tbf.rate, obj->tbf.burst, obj->tbf.limit, obj->tbf.latency);
|
|
|
|
|
}
|
2017-11-15 20:36:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2022-11-21 17:44:07 +01:00
|
|
|
nm_platform_qdisc_cmp(const NMPlatformQdisc *a, const NMPlatformQdisc *b, gboolean compare_handle)
|
2020-09-28 16:03:33 +02:00
|
|
|
{
|
|
|
|
|
NM_CMP_SELF(a, b);
|
|
|
|
|
NM_CMP_FIELD(a, b, ifindex);
|
|
|
|
|
NM_CMP_FIELD(a, b, parent);
|
|
|
|
|
NM_CMP_FIELD_STR_INTERNED(a, b, kind);
|
|
|
|
|
NM_CMP_FIELD(a, b, addr_family);
|
|
|
|
|
if (compare_handle)
|
|
|
|
|
NM_CMP_FIELD(a, b, handle);
|
|
|
|
|
NM_CMP_FIELD(a, b, info);
|
|
|
|
|
|
|
|
|
|
if (nm_streq0(a->kind, "fq_codel")) {
|
|
|
|
|
NM_CMP_FIELD(a, b, fq_codel.limit);
|
|
|
|
|
NM_CMP_FIELD(a, b, fq_codel.flows);
|
|
|
|
|
NM_CMP_FIELD(a, b, fq_codel.target);
|
|
|
|
|
NM_CMP_FIELD(a, b, fq_codel.interval);
|
|
|
|
|
NM_CMP_FIELD(a, b, fq_codel.quantum);
|
|
|
|
|
NM_CMP_FIELD(a, b, fq_codel.ce_threshold);
|
|
|
|
|
NM_CMP_FIELD(a, b, fq_codel.memory_limit);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, fq_codel.ecn);
|
|
|
|
|
} else if (nm_streq0(a->kind, "sfq")) {
|
|
|
|
|
NM_CMP_FIELD(a, b, sfq.quantum);
|
|
|
|
|
NM_CMP_FIELD(a, b, sfq.perturb_period);
|
|
|
|
|
NM_CMP_FIELD(a, b, sfq.limit);
|
|
|
|
|
NM_CMP_FIELD(a, b, sfq.flows);
|
|
|
|
|
NM_CMP_FIELD(a, b, sfq.divisor);
|
|
|
|
|
NM_CMP_FIELD(a, b, sfq.depth);
|
|
|
|
|
} else if (nm_streq0(a->kind, "tbf")) {
|
|
|
|
|
NM_CMP_FIELD(a, b, tbf.rate);
|
|
|
|
|
NM_CMP_FIELD(a, b, tbf.burst);
|
|
|
|
|
NM_CMP_FIELD(a, b, tbf.limit);
|
|
|
|
|
NM_CMP_FIELD(a, b, tbf.latency);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
2017-11-15 20:36:35 +01:00
|
|
|
}
|
|
|
|
|
|
2017-11-15 20:36:35 +01:00
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_tfilter_to_string(const NMPlatformTfilter *tfilter, char *buf, gsize len)
|
|
|
|
|
{
|
2022-09-20 16:14:21 +02:00
|
|
|
char str_dev[30];
|
2020-09-28 16:03:33 +02:00
|
|
|
char act_buf[300];
|
|
|
|
|
char *p;
|
|
|
|
|
gsize l;
|
|
|
|
|
|
|
|
|
|
if (!nm_utils_to_string_buffer_init_null(tfilter, &buf, &len))
|
|
|
|
|
return buf;
|
|
|
|
|
|
|
|
|
|
if (tfilter->action.kind) {
|
|
|
|
|
p = act_buf;
|
|
|
|
|
l = sizeof(act_buf);
|
|
|
|
|
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&p, &l, " \"%s\"", tfilter->action.kind);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (nm_streq(tfilter->action.kind, NM_PLATFORM_ACTION_KIND_SIMPLE)) {
|
|
|
|
|
gs_free char *t = NULL;
|
|
|
|
|
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(
|
2020-09-28 16:03:33 +02:00
|
|
|
&p,
|
|
|
|
|
&l,
|
|
|
|
|
" (\"%s\")",
|
|
|
|
|
nm_utils_str_utf8safe_escape(tfilter->action.kind,
|
|
|
|
|
NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL
|
|
|
|
|
| NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII,
|
|
|
|
|
&t));
|
|
|
|
|
} else if (nm_streq(tfilter->action.kind, NM_PLATFORM_ACTION_KIND_MIRRED)) {
|
2021-07-30 08:53:16 +02:00
|
|
|
nm_strbuf_append(&p,
|
|
|
|
|
&l,
|
|
|
|
|
"%s%s%s%s dev %d",
|
|
|
|
|
tfilter->action.mirred.ingress ? " ingress" : "",
|
|
|
|
|
tfilter->action.mirred.egress ? " egress" : "",
|
|
|
|
|
tfilter->action.mirred.mirror ? " mirror" : "",
|
|
|
|
|
tfilter->action.mirred.redirect ? " redirect" : "",
|
|
|
|
|
tfilter->action.mirred.ifindex);
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
} else
|
|
|
|
|
act_buf[0] = '\0';
|
|
|
|
|
|
|
|
|
|
g_snprintf(buf,
|
|
|
|
|
len,
|
|
|
|
|
"%s%s family %u handle %x parent %x info %x%s",
|
|
|
|
|
tfilter->kind,
|
2022-09-20 16:14:21 +02:00
|
|
|
_to_string_dev(str_dev, tfilter->ifindex),
|
2020-09-28 16:03:33 +02:00
|
|
|
tfilter->addr_family,
|
|
|
|
|
tfilter->handle,
|
|
|
|
|
tfilter->parent,
|
|
|
|
|
tfilter->info,
|
|
|
|
|
act_buf);
|
|
|
|
|
|
|
|
|
|
return buf;
|
2017-11-15 20:36:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_tfilter_hash_update(const NMPlatformTfilter *obj, NMHashState *h)
|
|
|
|
|
{
|
|
|
|
|
nm_hash_update_str0(h, obj->kind);
|
|
|
|
|
nm_hash_update_vals(h, obj->ifindex, obj->addr_family, obj->handle, obj->parent, obj->info);
|
|
|
|
|
if (obj->action.kind) {
|
|
|
|
|
nm_hash_update_str(h, obj->action.kind);
|
|
|
|
|
if (nm_streq(obj->action.kind, NM_PLATFORM_ACTION_KIND_SIMPLE)) {
|
|
|
|
|
nm_hash_update_strarr(h, obj->action.simple.sdata);
|
|
|
|
|
} else if (nm_streq(obj->action.kind, NM_PLATFORM_ACTION_KIND_MIRRED)) {
|
|
|
|
|
nm_hash_update_vals(h,
|
|
|
|
|
obj->action.mirred.ifindex,
|
|
|
|
|
NM_HASH_COMBINE_BOOLS(guint8,
|
|
|
|
|
obj->action.mirred.ingress,
|
|
|
|
|
obj->action.mirred.egress,
|
|
|
|
|
obj->action.mirred.mirror,
|
|
|
|
|
obj->action.mirred.redirect));
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-11-15 20:36:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_tfilter_cmp(const NMPlatformTfilter *a, const NMPlatformTfilter *b)
|
|
|
|
|
{
|
|
|
|
|
NM_CMP_SELF(a, b);
|
|
|
|
|
NM_CMP_FIELD(a, b, ifindex);
|
|
|
|
|
NM_CMP_FIELD(a, b, parent);
|
|
|
|
|
NM_CMP_FIELD_STR_INTERNED(a, b, kind);
|
|
|
|
|
NM_CMP_FIELD(a, b, addr_family);
|
|
|
|
|
NM_CMP_FIELD(a, b, handle);
|
|
|
|
|
NM_CMP_FIELD(a, b, info);
|
|
|
|
|
|
|
|
|
|
NM_CMP_FIELD_STR_INTERNED(a, b, action.kind);
|
|
|
|
|
if (a->action.kind) {
|
|
|
|
|
if (nm_streq(a->action.kind, NM_PLATFORM_ACTION_KIND_SIMPLE)) {
|
|
|
|
|
NM_CMP_FIELD_STR(a, b, action.simple.sdata);
|
|
|
|
|
} else if (nm_streq(a->action.kind, NM_PLATFORM_ACTION_KIND_MIRRED)) {
|
|
|
|
|
NM_CMP_FIELD(a, b, action.mirred.ifindex);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, action.mirred.ingress);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, action.mirred.egress);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, action.mirred.mirror);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, action.mirred.redirect);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
2017-11-15 20:36:35 +01:00
|
|
|
}
|
|
|
|
|
|
2022-07-13 16:24:05 +02:00
|
|
|
static NM_UTILS_FLAGS2STR_DEFINE(_mptcp_flags_to_string,
|
|
|
|
|
guint32,
|
|
|
|
|
NM_UTILS_FLAGS2STR(NM_MPTCP_PM_ADDR_FLAG_SIGNAL, "signal"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(NM_MPTCP_PM_ADDR_FLAG_SUBFLOW, "subflow"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(NM_MPTCP_PM_ADDR_FLAG_BACKUP, "backup"),
|
|
|
|
|
NM_UTILS_FLAGS2STR(NM_MPTCP_PM_ADDR_FLAG_FULLMESH, "fullmesh"));
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
nm_platform_mptcp_addr_to_string(const NMPlatformMptcpAddr *mptcp_addr, char *buf, gsize len)
|
|
|
|
|
{
|
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 str_addr[30 + NM_INET_ADDRSTRLEN];
|
2022-07-13 16:24:05 +02:00
|
|
|
char str_port[30];
|
|
|
|
|
char str_id[30];
|
|
|
|
|
char str_flags[200];
|
|
|
|
|
char str_flags2[30 + sizeof(str_flags)];
|
|
|
|
|
char str_ifindex[30];
|
|
|
|
|
|
|
|
|
|
if (!nm_utils_to_string_buffer_init_null(mptcp_addr, &buf, &len))
|
|
|
|
|
return buf;
|
|
|
|
|
|
|
|
|
|
if (mptcp_addr->addr_family == 0)
|
|
|
|
|
nm_sprintf_buf(str_addr, "no-addr");
|
|
|
|
|
else if (NM_IN_SET(mptcp_addr->addr_family, AF_INET, AF_INET6))
|
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_inet_ntop(mptcp_addr->addr_family, &mptcp_addr->addr, str_addr);
|
2022-07-13 16:24:05 +02:00
|
|
|
else
|
|
|
|
|
nm_sprintf_buf(str_addr, "af %d", mptcp_addr->addr_family);
|
|
|
|
|
|
|
|
|
|
if (mptcp_addr->flags != 0)
|
|
|
|
|
_mptcp_flags_to_string(mptcp_addr->flags, str_flags, sizeof(str_flags));
|
|
|
|
|
else
|
|
|
|
|
str_flags[0] = '\0';
|
|
|
|
|
|
|
|
|
|
g_snprintf(buf,
|
|
|
|
|
len,
|
|
|
|
|
"%s" /* address */
|
|
|
|
|
"%s" /* port */
|
|
|
|
|
"%s" /* id */
|
|
|
|
|
"%s" /* flags */
|
|
|
|
|
"%s" /* ifindex */
|
|
|
|
|
"",
|
|
|
|
|
str_addr,
|
|
|
|
|
mptcp_addr->port == 0 ? "" : nm_sprintf_buf(str_port, " port %u", mptcp_addr->port),
|
|
|
|
|
mptcp_addr->id == 0 ? "" : nm_sprintf_buf(str_id, " id %u", mptcp_addr->id),
|
|
|
|
|
str_flags[0] == '\0' ? "" : nm_sprintf_buf(str_flags2, " flags %s", str_flags),
|
|
|
|
|
mptcp_addr->ifindex == 0
|
|
|
|
|
? ""
|
|
|
|
|
: nm_sprintf_buf(str_ifindex, " ifindex %d", mptcp_addr->ifindex));
|
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_platform_mptcp_addr_hash_update(const NMPlatformMptcpAddr *obj, NMHashState *h)
|
|
|
|
|
{
|
|
|
|
|
nm_assert(obj);
|
|
|
|
|
nm_assert_addr_family_or_unspec(obj->addr_family);
|
|
|
|
|
|
2022-08-02 19:17:28 +02:00
|
|
|
nm_hash_update_vals(h, obj->id, obj->flags, obj->port, obj->addr_family, obj->ifindex);
|
2022-07-13 16:24:05 +02:00
|
|
|
if (NM_IN_SET(obj->addr_family, AF_INET, AF_INET6))
|
|
|
|
|
nm_hash_update(h, &obj->addr, nm_utils_addr_family_to_size(obj->addr_family));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
nm_platform_mptcp_addr_cmp(const NMPlatformMptcpAddr *a, const NMPlatformMptcpAddr *b)
|
|
|
|
|
{
|
|
|
|
|
NM_CMP_SELF(a, b);
|
|
|
|
|
|
|
|
|
|
nm_assert_addr_family_or_unspec(a->addr_family);
|
|
|
|
|
nm_assert_addr_family_or_unspec(b->addr_family);
|
|
|
|
|
|
2022-07-26 18:19:14 +02:00
|
|
|
NM_CMP_FIELD(a, b, ifindex);
|
2022-07-13 16:24:05 +02:00
|
|
|
NM_CMP_FIELD(a, b, id);
|
|
|
|
|
NM_CMP_FIELD(a, b, addr_family);
|
|
|
|
|
if (NM_IN_SET(a->addr_family, AF_INET, AF_INET6))
|
|
|
|
|
NM_CMP_FIELD_MEMCMP_LEN(a, b, addr, nm_utils_addr_family_to_size(a->addr_family));
|
2022-07-26 18:19:14 +02:00
|
|
|
NM_CMP_FIELD(a, b, port);
|
2022-07-13 16:24:05 +02:00
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-27 13:50:43 +02:00
|
|
|
guint
|
|
|
|
|
nm_platform_mptcp_addr_index_addr_cmp(gconstpointer data)
|
|
|
|
|
{
|
|
|
|
|
const NMPlatformMptcpAddr *mptcp_addr = data;
|
|
|
|
|
NMHashState h;
|
|
|
|
|
|
|
|
|
|
nm_hash_init(&h, 1408914077u);
|
|
|
|
|
nm_hash_update_val(&h, mptcp_addr->addr_family);
|
|
|
|
|
nm_hash_update(&h, &mptcp_addr->addr, nm_utils_addr_family_to_size(mptcp_addr->addr_family));
|
|
|
|
|
return nm_hash_complete(&h);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
nm_platform_mptcp_addr_index_addr_equal(gconstpointer data_a, gconstpointer data_b)
|
|
|
|
|
{
|
|
|
|
|
const NMPlatformMptcpAddr *mptcp_addr_a = data_a;
|
|
|
|
|
const NMPlatformMptcpAddr *mptcp_addr_b = data_b;
|
|
|
|
|
|
|
|
|
|
return mptcp_addr_a->addr_family == mptcp_addr_b->addr_family
|
|
|
|
|
&& nm_ip_addr_equal(mptcp_addr_a->addr_family, &mptcp_addr_a->addr, &mptcp_addr_b->addr);
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-23 14:33:24 +02:00
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_vf_to_string(const NMPlatformVF *vf, char *buf, gsize len)
|
|
|
|
|
{
|
2021-11-09 13:28:54 +01:00
|
|
|
char str_mac[128], mac[128];
|
|
|
|
|
char str_spoof_check[64];
|
|
|
|
|
char str_trust[64];
|
|
|
|
|
char str_min_tx_rate[64];
|
|
|
|
|
char str_max_tx_rate[64];
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_auto_free_gstring GString *gstr_vlans = NULL;
|
|
|
|
|
guint i;
|
|
|
|
|
|
|
|
|
|
if (!nm_utils_to_string_buffer_init_null(vf, &buf, &len))
|
|
|
|
|
return buf;
|
|
|
|
|
|
|
|
|
|
if (vf->mac.len) {
|
|
|
|
|
_nm_utils_hwaddr_ntoa(vf->mac.data, vf->mac.len, TRUE, mac, sizeof(mac));
|
|
|
|
|
nm_sprintf_buf(str_mac, " mac %s", mac);
|
|
|
|
|
} else
|
|
|
|
|
str_mac[0] = '\0';
|
|
|
|
|
|
|
|
|
|
if (vf->num_vlans) {
|
|
|
|
|
gstr_vlans = g_string_new("");
|
|
|
|
|
for (i = 0; i < vf->num_vlans; i++) {
|
|
|
|
|
g_string_append_printf(gstr_vlans, " vlan %u", (unsigned) vf->vlans[i].id);
|
|
|
|
|
if (vf->vlans[i].qos)
|
|
|
|
|
g_string_append_printf(gstr_vlans, " qos %u", (unsigned) vf->vlans[i].qos);
|
|
|
|
|
if (vf->vlans[i].proto_ad)
|
|
|
|
|
g_string_append(gstr_vlans, " proto 802.1ad");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_snprintf(buf,
|
|
|
|
|
len,
|
|
|
|
|
"%u" /* index */
|
|
|
|
|
"%s" /* MAC */
|
|
|
|
|
"%s" /* spoof check */
|
|
|
|
|
"%s" /* trust */
|
|
|
|
|
"%s" /* min tx rate */
|
|
|
|
|
"%s" /* max tx rate */
|
|
|
|
|
"%s", /* VLANs */
|
|
|
|
|
vf->index,
|
|
|
|
|
str_mac,
|
|
|
|
|
vf->spoofchk >= 0 ? nm_sprintf_buf(str_spoof_check, " spoofchk %d", vf->spoofchk)
|
|
|
|
|
: "",
|
|
|
|
|
vf->trust >= 0 ? nm_sprintf_buf(str_trust, " trust %d", vf->trust) : "",
|
|
|
|
|
vf->min_tx_rate
|
|
|
|
|
? nm_sprintf_buf(str_min_tx_rate, " min_tx_rate %u", (unsigned) vf->min_tx_rate)
|
|
|
|
|
: "",
|
|
|
|
|
vf->max_tx_rate
|
|
|
|
|
? nm_sprintf_buf(str_max_tx_rate, " max_tx_rate %u", (unsigned) vf->max_tx_rate)
|
|
|
|
|
: "",
|
|
|
|
|
gstr_vlans ? gstr_vlans->str : "");
|
|
|
|
|
|
|
|
|
|
return buf;
|
2018-05-23 14:33:24 +02:00
|
|
|
}
|
|
|
|
|
|
2019-03-16 17:22:35 +01:00
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_bridge_vlan_to_string(const NMPlatformBridgeVlan *vlan, char *buf, gsize len)
|
2019-03-16 17:22:35 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
char str_vid_end[64];
|
2019-04-15 15:14:33 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!nm_utils_to_string_buffer_init_null(vlan, &buf, &len))
|
|
|
|
|
return buf;
|
2019-03-16 17:22:35 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_snprintf(buf,
|
|
|
|
|
len,
|
|
|
|
|
"%u"
|
|
|
|
|
"%s"
|
|
|
|
|
"%s"
|
|
|
|
|
"%s",
|
|
|
|
|
vlan->vid_start,
|
|
|
|
|
vlan->vid_start != vlan->vid_end ? nm_sprintf_buf(str_vid_end, "-%u", vlan->vid_end)
|
|
|
|
|
: "",
|
|
|
|
|
vlan->pvid ? " PVID" : "",
|
|
|
|
|
vlan->untagged ? " untagged" : "");
|
2019-03-16 17:22:35 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return buf;
|
2019-03-16 17:22:35 +01:00
|
|
|
}
|
|
|
|
|
|
2017-10-17 11:53:08 +02:00
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_hash_update(const NMPlatformLink *obj, NMHashState *h)
|
|
|
|
|
{
|
|
|
|
|
nm_hash_update_vals(h,
|
|
|
|
|
obj->ifindex,
|
|
|
|
|
obj->master,
|
|
|
|
|
obj->parent,
|
|
|
|
|
obj->n_ifi_flags,
|
|
|
|
|
obj->mtu,
|
|
|
|
|
obj->type,
|
|
|
|
|
obj->arptype,
|
|
|
|
|
obj->inet6_addr_gen_mode_inv,
|
|
|
|
|
obj->inet6_token,
|
2023-02-16 16:37:54 +01:00
|
|
|
obj->link_props.tx_queue_length,
|
|
|
|
|
obj->link_props.gso_max_size,
|
|
|
|
|
obj->link_props.gso_max_segments,
|
|
|
|
|
obj->link_props.gro_max_size,
|
2023-03-03 16:36:23 +01:00
|
|
|
obj->port_kind,
|
2020-09-28 16:03:33 +02:00
|
|
|
obj->rx_packets,
|
|
|
|
|
obj->rx_bytes,
|
|
|
|
|
obj->tx_packets,
|
|
|
|
|
obj->tx_bytes,
|
|
|
|
|
NM_HASH_COMBINE_BOOLS(guint8, obj->connected, obj->initialized));
|
|
|
|
|
nm_hash_update_strarr(h, obj->name);
|
|
|
|
|
nm_hash_update_str0(h, obj->kind);
|
|
|
|
|
nm_hash_update_str0(h, obj->driver);
|
|
|
|
|
/* nm_hash_update_mem() also hashes the length obj->addr.len */
|
|
|
|
|
nm_hash_update_mem(h,
|
|
|
|
|
obj->l_address.data,
|
|
|
|
|
NM_MIN(obj->l_address.len, sizeof(obj->l_address.data)));
|
2021-07-26 10:57:30 -04:00
|
|
|
nm_hash_update_mem(h,
|
|
|
|
|
obj->l_perm_address.data,
|
|
|
|
|
NM_MIN(obj->l_perm_address.len, sizeof(obj->l_perm_address.data)));
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_hash_update_mem(h,
|
|
|
|
|
obj->l_broadcast.data,
|
|
|
|
|
NM_MIN(obj->l_broadcast.len, sizeof(obj->l_broadcast.data)));
|
2023-03-03 16:36:23 +01:00
|
|
|
|
|
|
|
|
switch (obj->port_kind) {
|
|
|
|
|
case NM_PORT_KIND_NONE:
|
|
|
|
|
break;
|
|
|
|
|
case NM_PORT_KIND_BOND:
|
|
|
|
|
nm_platform_link_bond_port_hash_update(&obj->port_data.bond, h);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_platform_link_bond_port_hash_update(const NMPlatformLinkBondPort *obj, NMHashState *h)
|
|
|
|
|
{
|
2023-03-09 12:18:14 +01:00
|
|
|
nm_hash_update_vals(h, obj->prio, obj->queue_id, NM_HASH_COMBINE_BOOLS(guint8, obj->prio_has));
|
platform: use NMDedupMultiIndex for routes in NMPCache
Rework platform object cache to use NMDedupMultiIndex.
Already previously, NMPCache used NMMultiIndex and had thus
O(1) for most operations. What is new is:
- Contrary to NMMultiIndex, NMDedupMultiIndex preserves the order of
the cached items. That is crucial to handle routes properly as kernel
will replace the first matching route based on network/plen/metric
properties. See related bug rh#1337855.
Without tracking the order of routes as they are exposed
by kernel, we cannot properly maintain the route cache.
- All NMPObject instances are now treated immutable, refcounted
and get de-duplicated via NMDedupMultiIndex. This allows
to have a global NMDedupMultiIndex that can be shared with
NMIP4Config and NMRouteManager. It also allows to share the
objects themselves.
Immutable objects are so much nicer. We can get rid of the
update pre-hook callback, which was required previously because
we would mutate the object inplace. Now, we can just update
the cache, and compare obj_old and obj_new after the fact.
- NMMultiIndex was treated as an internal of NMPCache. On the other
hand, NMDedupMultiIndex exposes NMDedupMultiHeadEntry, which is
basically an object that allows to iterate over all related
objects. That means, we can now lookup objects in the cache
and give the NMDedupMultiHeadEntry instance to the caller,
which then can iterate the list on it's own -- without need
for copying anything.
Currently, at various places we still create copies of lookup
results. That can be improved later.
The ability to share NMPObject instances should enable us to
significantly improve performance and scale with large number
of routes.
Of course there is a memory overhead of having an index for each list
entry. Each NMPObject may also require an NMDedupMultiEntry,
NMDedupMultiHeadEntry, and NMDedupMultiBox item, which are tracked
in a GHashTable. Optimally, one NMDedupMultiHeadEntry is the head
for multiple objects, and NMDedupMultiBox is able to deduplicate several
NMPObjects, so that there is a net saving.
Also, each object type has several indexes of type NMPCacheIdType.
So, worst case an NMPlatformIP4Route in the platform cache is tracked
by 8 NMPCacheIdType indexes, for each we require a NMDedupMultiEntry,
plus the shared NMDedupMultiHeadEntry. The NMDedupMultiBox instance
is shared between the 8 indexes (and possibly other).
2017-06-21 10:53:34 +02:00
|
|
|
}
|
|
|
|
|
|
2014-04-05 18:35:20 +02:00
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_link_cmp(const NMPlatformLink *a, const NMPlatformLink *b)
|
|
|
|
|
{
|
|
|
|
|
NM_CMP_SELF(a, b);
|
|
|
|
|
NM_CMP_FIELD(a, b, ifindex);
|
|
|
|
|
NM_CMP_FIELD(a, b, type);
|
|
|
|
|
NM_CMP_FIELD_STR(a, b, name);
|
|
|
|
|
NM_CMP_FIELD(a, b, master);
|
|
|
|
|
NM_CMP_FIELD(a, b, parent);
|
|
|
|
|
NM_CMP_FIELD(a, b, n_ifi_flags);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, connected);
|
|
|
|
|
NM_CMP_FIELD(a, b, mtu);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, initialized);
|
|
|
|
|
NM_CMP_FIELD(a, b, arptype);
|
|
|
|
|
NM_CMP_FIELD(a, b, l_address.len);
|
2021-07-26 10:57:30 -04:00
|
|
|
NM_CMP_FIELD(a, b, l_perm_address.len);
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_FIELD(a, b, l_broadcast.len);
|
|
|
|
|
NM_CMP_FIELD(a, b, inet6_addr_gen_mode_inv);
|
|
|
|
|
NM_CMP_FIELD_STR_INTERNED(a, b, kind);
|
|
|
|
|
NM_CMP_FIELD_STR_INTERNED(a, b, driver);
|
|
|
|
|
if (a->l_address.len)
|
|
|
|
|
NM_CMP_FIELD_MEMCMP_LEN(a, b, l_address.data, a->l_address.len);
|
2021-07-26 10:57:30 -04:00
|
|
|
if (a->l_perm_address.len)
|
|
|
|
|
NM_CMP_FIELD_MEMCMP_LEN(a, b, l_perm_address.data, a->l_perm_address.len);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (a->l_broadcast.len)
|
|
|
|
|
NM_CMP_FIELD_MEMCMP_LEN(a, b, l_broadcast.data, a->l_broadcast.len);
|
|
|
|
|
NM_CMP_FIELD_MEMCMP(a, b, inet6_token);
|
2023-02-16 16:37:54 +01:00
|
|
|
NM_CMP_FIELD(a, b, link_props.tx_queue_length);
|
|
|
|
|
NM_CMP_FIELD(a, b, link_props.gso_max_size);
|
|
|
|
|
NM_CMP_FIELD(a, b, link_props.gso_max_segments);
|
|
|
|
|
NM_CMP_FIELD(a, b, link_props.gro_max_size);
|
2023-03-03 16:36:23 +01:00
|
|
|
NM_CMP_FIELD(a, b, port_kind);
|
|
|
|
|
switch (a->port_kind) {
|
|
|
|
|
case NM_PORT_KIND_NONE:
|
|
|
|
|
break;
|
|
|
|
|
case NM_PORT_KIND_BOND:
|
|
|
|
|
NM_CMP_RETURN(nm_platform_link_bond_port_cmp(&a->port_data.bond, &b->port_data.bond));
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_FIELD(a, b, rx_packets);
|
|
|
|
|
NM_CMP_FIELD(a, b, rx_bytes);
|
|
|
|
|
NM_CMP_FIELD(a, b, tx_packets);
|
|
|
|
|
NM_CMP_FIELD(a, b, tx_bytes);
|
|
|
|
|
return 0;
|
2014-04-05 18:35:20 +02:00
|
|
|
}
|
|
|
|
|
|
2020-08-05 13:46:28 -04:00
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_bridge_hash_update(const NMPlatformLnkBridge *obj, NMHashState *h)
|
|
|
|
|
{
|
|
|
|
|
nm_hash_update_vals(h,
|
|
|
|
|
obj->forward_delay,
|
|
|
|
|
obj->hello_time,
|
|
|
|
|
obj->max_age,
|
|
|
|
|
obj->ageing_time,
|
|
|
|
|
obj->priority,
|
|
|
|
|
obj->vlan_protocol,
|
|
|
|
|
obj->group_fwd_mask,
|
|
|
|
|
obj->group_addr,
|
|
|
|
|
obj->mcast_hash_max,
|
|
|
|
|
obj->mcast_last_member_count,
|
|
|
|
|
obj->mcast_startup_query_count,
|
|
|
|
|
obj->mcast_last_member_interval,
|
|
|
|
|
obj->mcast_membership_interval,
|
|
|
|
|
obj->mcast_querier_interval,
|
|
|
|
|
obj->mcast_query_interval,
|
|
|
|
|
obj->mcast_router,
|
|
|
|
|
obj->mcast_query_response_interval,
|
|
|
|
|
obj->mcast_startup_query_interval,
|
|
|
|
|
NM_HASH_COMBINE_BOOLS(guint8,
|
|
|
|
|
obj->stp_state,
|
|
|
|
|
obj->mcast_querier,
|
|
|
|
|
obj->mcast_query_use_ifaddr,
|
|
|
|
|
obj->mcast_snooping,
|
|
|
|
|
obj->vlan_stats_enabled));
|
2020-08-05 13:46:28 -04:00
|
|
|
}
|
|
|
|
|
|
2022-07-25 16:01:35 +02:00
|
|
|
void
|
|
|
|
|
nm_platform_lnk_bond_hash_update(const NMPlatformLnkBond *obj, NMHashState *h)
|
|
|
|
|
{
|
|
|
|
|
nm_hash_update_vals(h,
|
|
|
|
|
obj->arp_all_targets,
|
|
|
|
|
obj->arp_interval,
|
|
|
|
|
obj->arp_validate,
|
|
|
|
|
obj->downdelay,
|
|
|
|
|
obj->lp_interval,
|
|
|
|
|
obj->miimon,
|
|
|
|
|
obj->min_links,
|
|
|
|
|
obj->packets_per_port,
|
|
|
|
|
obj->peer_notif_delay,
|
|
|
|
|
obj->primary,
|
|
|
|
|
obj->resend_igmp,
|
|
|
|
|
obj->updelay,
|
|
|
|
|
obj->ad_actor_sys_prio,
|
|
|
|
|
obj->ad_user_port_key,
|
|
|
|
|
obj->ad_actor_system,
|
|
|
|
|
obj->ad_select,
|
|
|
|
|
obj->all_ports_active,
|
2023-03-01 15:12:35 +00:00
|
|
|
obj->arp_missed_max,
|
2022-07-25 16:01:35 +02:00
|
|
|
obj->arp_ip_targets_num,
|
|
|
|
|
obj->fail_over_mac,
|
|
|
|
|
obj->lacp_rate,
|
2023-03-02 11:43:25 +01:00
|
|
|
obj->lacp_active,
|
2023-03-02 15:07:07 +01:00
|
|
|
obj->ns_ip6_targets_num,
|
2022-07-25 16:01:35 +02:00
|
|
|
obj->num_grat_arp,
|
|
|
|
|
obj->mode,
|
|
|
|
|
obj->primary_reselect,
|
|
|
|
|
obj->xmit_hash_policy,
|
|
|
|
|
NM_HASH_COMBINE_BOOLS(guint16,
|
|
|
|
|
obj->downdelay_has,
|
2023-03-02 11:43:25 +01:00
|
|
|
obj->lacp_active_has,
|
2022-07-25 16:01:35 +02:00
|
|
|
obj->lp_interval_has,
|
|
|
|
|
obj->miimon_has,
|
|
|
|
|
obj->peer_notif_delay_has,
|
|
|
|
|
obj->resend_igmp_has,
|
|
|
|
|
obj->tlb_dynamic_lb,
|
|
|
|
|
obj->tlb_dynamic_lb_has,
|
|
|
|
|
obj->updelay_has,
|
|
|
|
|
obj->use_carrier));
|
|
|
|
|
|
|
|
|
|
nm_hash_update(h, obj->arp_ip_target, obj->arp_ip_targets_num * sizeof(obj->arp_ip_target[0]));
|
2023-03-02 15:07:07 +01:00
|
|
|
nm_hash_update(h, obj->ns_ip6_target, obj->ns_ip6_targets_num * sizeof(obj->ns_ip6_target[0]));
|
2022-07-25 16:01:35 +02:00
|
|
|
}
|
|
|
|
|
|
2023-03-03 16:36:23 +01:00
|
|
|
int
|
|
|
|
|
nm_platform_link_bond_port_cmp(const NMPlatformLinkBondPort *a, const NMPlatformLinkBondPort *b)
|
|
|
|
|
{
|
|
|
|
|
NM_CMP_SELF(a, b);
|
|
|
|
|
NM_CMP_FIELD(a, b, queue_id);
|
2023-03-09 12:18:14 +01:00
|
|
|
NM_CMP_FIELD(a, b, prio);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, prio_has);
|
2023-03-03 16:36:23 +01:00
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-25 16:01:35 +02:00
|
|
|
int
|
|
|
|
|
nm_platform_lnk_bond_cmp(const NMPlatformLnkBond *a, const NMPlatformLnkBond *b)
|
|
|
|
|
{
|
|
|
|
|
NM_CMP_SELF(a, b);
|
2023-03-06 11:34:48 +01:00
|
|
|
NM_CMP_FIELD(a, b, arp_ip_targets_num);
|
2023-03-02 15:07:07 +01:00
|
|
|
NM_CMP_FIELD(a, b, ns_ip6_targets_num);
|
|
|
|
|
NM_CMP_FIELD_MEMCMP_LEN(a,
|
|
|
|
|
b,
|
|
|
|
|
ns_ip6_target,
|
|
|
|
|
a->ns_ip6_targets_num * sizeof(a->ns_ip6_target[0]));
|
2022-07-25 16:01:35 +02:00
|
|
|
NM_CMP_FIELD_MEMCMP_LEN(a,
|
|
|
|
|
b,
|
|
|
|
|
arp_ip_target,
|
|
|
|
|
a->arp_ip_targets_num * sizeof(a->arp_ip_target[0]));
|
|
|
|
|
NM_CMP_FIELD(a, b, arp_all_targets);
|
|
|
|
|
NM_CMP_FIELD(a, b, arp_interval);
|
|
|
|
|
NM_CMP_FIELD(a, b, arp_validate);
|
|
|
|
|
NM_CMP_FIELD(a, b, downdelay);
|
|
|
|
|
NM_CMP_FIELD(a, b, lp_interval);
|
|
|
|
|
NM_CMP_FIELD(a, b, miimon);
|
|
|
|
|
NM_CMP_FIELD(a, b, min_links);
|
|
|
|
|
NM_CMP_FIELD(a, b, packets_per_port);
|
|
|
|
|
NM_CMP_FIELD(a, b, peer_notif_delay);
|
|
|
|
|
NM_CMP_FIELD(a, b, primary);
|
|
|
|
|
NM_CMP_FIELD(a, b, resend_igmp);
|
|
|
|
|
NM_CMP_FIELD(a, b, updelay);
|
|
|
|
|
NM_CMP_FIELD(a, b, ad_actor_sys_prio);
|
|
|
|
|
NM_CMP_FIELD(a, b, ad_user_port_key);
|
|
|
|
|
NM_CMP_FIELD_MEMCMP(a, b, ad_actor_system);
|
|
|
|
|
NM_CMP_FIELD(a, b, ad_select);
|
|
|
|
|
NM_CMP_FIELD(a, b, all_ports_active);
|
2023-03-01 15:12:35 +00:00
|
|
|
NM_CMP_FIELD(a, b, arp_missed_max);
|
2022-07-25 16:01:35 +02:00
|
|
|
NM_CMP_FIELD(a, b, fail_over_mac);
|
|
|
|
|
NM_CMP_FIELD(a, b, lacp_rate);
|
2023-03-02 11:43:25 +01:00
|
|
|
NM_CMP_FIELD(a, b, lacp_active);
|
2022-07-25 16:01:35 +02:00
|
|
|
NM_CMP_FIELD(a, b, num_grat_arp);
|
|
|
|
|
NM_CMP_FIELD(a, b, mode);
|
|
|
|
|
NM_CMP_FIELD(a, b, primary_reselect);
|
|
|
|
|
NM_CMP_FIELD(a, b, xmit_hash_policy);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, downdelay_has);
|
2023-03-02 11:43:25 +01:00
|
|
|
NM_CMP_FIELD_BOOL(a, b, lacp_active_has);
|
2022-07-25 16:01:35 +02:00
|
|
|
NM_CMP_FIELD_BOOL(a, b, lp_interval_has);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, miimon_has);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, peer_notif_delay_has);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, resend_igmp_has);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, tlb_dynamic_lb);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, tlb_dynamic_lb_has);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, updelay_has);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, use_carrier);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-05 13:46:28 -04:00
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_bridge_cmp(const NMPlatformLnkBridge *a, const NMPlatformLnkBridge *b)
|
|
|
|
|
{
|
|
|
|
|
NM_CMP_SELF(a, b);
|
|
|
|
|
NM_CMP_FIELD(a, b, forward_delay);
|
|
|
|
|
NM_CMP_FIELD(a, b, hello_time);
|
|
|
|
|
NM_CMP_FIELD(a, b, max_age);
|
|
|
|
|
NM_CMP_FIELD(a, b, ageing_time);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, stp_state);
|
|
|
|
|
NM_CMP_FIELD(a, b, priority);
|
|
|
|
|
NM_CMP_FIELD(a, b, vlan_protocol);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, vlan_stats_enabled);
|
|
|
|
|
NM_CMP_FIELD(a, b, group_fwd_mask);
|
|
|
|
|
NM_CMP_FIELD_MEMCMP(a, b, group_addr);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, mcast_snooping);
|
|
|
|
|
NM_CMP_FIELD(a, b, mcast_router);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, mcast_query_use_ifaddr);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, mcast_querier);
|
|
|
|
|
NM_CMP_FIELD(a, b, mcast_hash_max);
|
|
|
|
|
NM_CMP_FIELD(a, b, mcast_last_member_count);
|
|
|
|
|
NM_CMP_FIELD(a, b, mcast_startup_query_count);
|
|
|
|
|
NM_CMP_FIELD(a, b, mcast_last_member_interval);
|
|
|
|
|
NM_CMP_FIELD(a, b, mcast_membership_interval);
|
|
|
|
|
NM_CMP_FIELD(a, b, mcast_querier_interval);
|
|
|
|
|
NM_CMP_FIELD(a, b, mcast_query_interval);
|
|
|
|
|
NM_CMP_FIELD(a, b, mcast_query_response_interval);
|
|
|
|
|
NM_CMP_FIELD(a, b, mcast_startup_query_interval);
|
|
|
|
|
|
|
|
|
|
return 0;
|
2020-08-05 13:46:28 -04:00
|
|
|
}
|
|
|
|
|
|
2017-10-17 11:53:08 +02:00
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_gre_hash_update(const NMPlatformLnkGre *obj, NMHashState *h)
|
|
|
|
|
{
|
|
|
|
|
nm_hash_update_vals(h,
|
|
|
|
|
obj->local,
|
|
|
|
|
obj->remote,
|
|
|
|
|
obj->parent_ifindex,
|
|
|
|
|
obj->input_flags,
|
|
|
|
|
obj->output_flags,
|
|
|
|
|
obj->input_key,
|
|
|
|
|
obj->output_key,
|
|
|
|
|
obj->ttl,
|
|
|
|
|
obj->tos,
|
|
|
|
|
(bool) obj->path_mtu_discovery,
|
|
|
|
|
(bool) obj->is_tap);
|
2017-06-27 19:08:05 +02:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 15:15:21 +02:00
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_gre_cmp(const NMPlatformLnkGre *a, const NMPlatformLnkGre *b)
|
|
|
|
|
{
|
|
|
|
|
NM_CMP_SELF(a, b);
|
|
|
|
|
NM_CMP_FIELD(a, b, parent_ifindex);
|
|
|
|
|
NM_CMP_FIELD(a, b, input_flags);
|
|
|
|
|
NM_CMP_FIELD(a, b, output_flags);
|
|
|
|
|
NM_CMP_FIELD(a, b, input_key);
|
|
|
|
|
NM_CMP_FIELD(a, b, output_key);
|
|
|
|
|
NM_CMP_FIELD(a, b, local);
|
|
|
|
|
NM_CMP_FIELD(a, b, remote);
|
|
|
|
|
NM_CMP_FIELD(a, b, ttl);
|
|
|
|
|
NM_CMP_FIELD(a, b, tos);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, path_mtu_discovery);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, is_tap);
|
|
|
|
|
return 0;
|
2015-10-12 15:15:21 +02:00
|
|
|
}
|
|
|
|
|
|
2017-10-17 11:53:08 +02:00
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_infiniband_hash_update(const NMPlatformLnkInfiniband *obj, NMHashState *h)
|
2017-06-27 19:08:05 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_hash_update_val(h, obj->p_key);
|
|
|
|
|
nm_hash_update_str0(h, obj->mode);
|
2017-06-27 19:08:05 +02:00
|
|
|
}
|
|
|
|
|
|
2015-10-15 15:47:14 +02:00
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_infiniband_cmp(const NMPlatformLnkInfiniband *a, const NMPlatformLnkInfiniband *b)
|
2015-10-15 15:47:14 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_SELF(a, b);
|
|
|
|
|
NM_CMP_FIELD(a, b, p_key);
|
|
|
|
|
NM_CMP_FIELD_STR_INTERNED(a, b, mode);
|
|
|
|
|
return 0;
|
2015-10-15 15:47:14 +02:00
|
|
|
}
|
|
|
|
|
|
2017-10-17 11:53:08 +02:00
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_ip6tnl_hash_update(const NMPlatformLnkIp6Tnl *obj, NMHashState *h)
|
|
|
|
|
{
|
|
|
|
|
nm_hash_update_vals(h,
|
|
|
|
|
obj->local,
|
|
|
|
|
obj->remote,
|
|
|
|
|
obj->parent_ifindex,
|
|
|
|
|
obj->ttl,
|
|
|
|
|
obj->tclass,
|
|
|
|
|
obj->encap_limit,
|
|
|
|
|
obj->proto,
|
|
|
|
|
obj->flow_label,
|
|
|
|
|
obj->flags,
|
|
|
|
|
obj->input_flags,
|
|
|
|
|
obj->output_flags,
|
|
|
|
|
obj->input_key,
|
|
|
|
|
obj->output_key,
|
|
|
|
|
(bool) obj->is_gre,
|
|
|
|
|
(bool) obj->is_tap);
|
2017-06-27 19:08:05 +02:00
|
|
|
}
|
|
|
|
|
|
2015-11-27 22:22:25 +01:00
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_ip6tnl_cmp(const NMPlatformLnkIp6Tnl *a, const NMPlatformLnkIp6Tnl *b)
|
|
|
|
|
{
|
|
|
|
|
NM_CMP_SELF(a, b);
|
|
|
|
|
NM_CMP_FIELD(a, b, parent_ifindex);
|
|
|
|
|
NM_CMP_FIELD_MEMCMP(a, b, local);
|
|
|
|
|
NM_CMP_FIELD_MEMCMP(a, b, remote);
|
|
|
|
|
NM_CMP_FIELD(a, b, ttl);
|
|
|
|
|
NM_CMP_FIELD(a, b, tclass);
|
|
|
|
|
NM_CMP_FIELD(a, b, encap_limit);
|
|
|
|
|
NM_CMP_FIELD(a, b, flow_label);
|
|
|
|
|
NM_CMP_FIELD(a, b, proto);
|
|
|
|
|
NM_CMP_FIELD(a, b, flags);
|
|
|
|
|
NM_CMP_FIELD(a, b, input_flags);
|
|
|
|
|
NM_CMP_FIELD(a, b, output_flags);
|
|
|
|
|
NM_CMP_FIELD(a, b, input_key);
|
|
|
|
|
NM_CMP_FIELD(a, b, output_key);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, is_gre);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, is_tap);
|
|
|
|
|
return 0;
|
2015-11-27 22:22:25 +01:00
|
|
|
}
|
|
|
|
|
|
2017-10-17 11:53:08 +02:00
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_ipip_hash_update(const NMPlatformLnkIpIp *obj, NMHashState *h)
|
2017-06-27 19:08:05 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_hash_update_vals(h,
|
|
|
|
|
obj->local,
|
|
|
|
|
obj->remote,
|
|
|
|
|
obj->parent_ifindex,
|
|
|
|
|
obj->ttl,
|
|
|
|
|
obj->tos,
|
|
|
|
|
(bool) obj->path_mtu_discovery);
|
2017-06-27 19:08:05 +02:00
|
|
|
}
|
|
|
|
|
|
2015-11-27 14:01:56 +01:00
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_ipip_cmp(const NMPlatformLnkIpIp *a, const NMPlatformLnkIpIp *b)
|
2015-11-27 14:01:56 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_SELF(a, b);
|
|
|
|
|
NM_CMP_FIELD(a, b, parent_ifindex);
|
|
|
|
|
NM_CMP_FIELD(a, b, local);
|
|
|
|
|
NM_CMP_FIELD(a, b, remote);
|
|
|
|
|
NM_CMP_FIELD(a, b, ttl);
|
|
|
|
|
NM_CMP_FIELD(a, b, tos);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, path_mtu_discovery);
|
|
|
|
|
return 0;
|
2015-11-27 14:01:56 +01:00
|
|
|
}
|
|
|
|
|
|
2017-10-17 11:53:08 +02:00
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_macsec_hash_update(const NMPlatformLnkMacsec *obj, NMHashState *h)
|
|
|
|
|
{
|
|
|
|
|
nm_hash_update_vals(h,
|
|
|
|
|
obj->sci,
|
|
|
|
|
obj->cipher_suite,
|
|
|
|
|
obj->window,
|
|
|
|
|
obj->icv_length,
|
|
|
|
|
obj->encoding_sa,
|
|
|
|
|
obj->validation,
|
|
|
|
|
NM_HASH_COMBINE_BOOLS(guint8,
|
|
|
|
|
obj->encrypt,
|
|
|
|
|
obj->protect,
|
|
|
|
|
obj->include_sci,
|
|
|
|
|
obj->es,
|
|
|
|
|
obj->scb,
|
|
|
|
|
obj->replay_protect));
|
2017-06-27 19:08:05 +02:00
|
|
|
}
|
|
|
|
|
|
2016-06-30 18:20:09 +02:00
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_macsec_cmp(const NMPlatformLnkMacsec *a, const NMPlatformLnkMacsec *b)
|
|
|
|
|
{
|
|
|
|
|
NM_CMP_SELF(a, b);
|
|
|
|
|
NM_CMP_FIELD(a, b, sci);
|
|
|
|
|
NM_CMP_FIELD(a, b, icv_length);
|
|
|
|
|
NM_CMP_FIELD(a, b, cipher_suite);
|
|
|
|
|
NM_CMP_FIELD(a, b, window);
|
|
|
|
|
NM_CMP_FIELD(a, b, encoding_sa);
|
|
|
|
|
NM_CMP_FIELD(a, b, validation);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, encrypt);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, protect);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, include_sci);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, es);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, scb);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, replay_protect);
|
|
|
|
|
return 0;
|
2016-06-30 18:20:09 +02:00
|
|
|
}
|
|
|
|
|
|
2017-10-17 11:53:08 +02:00
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_macvlan_hash_update(const NMPlatformLnkMacvlan *obj, NMHashState *h)
|
2017-06-27 19:08:05 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_hash_update_vals(h, obj->mode, NM_HASH_COMBINE_BOOLS(guint8, obj->no_promisc, obj->tap));
|
2017-06-27 19:08:05 +02:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 15:15:21 +02:00
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_macvlan_cmp(const NMPlatformLnkMacvlan *a, const NMPlatformLnkMacvlan *b)
|
2015-10-12 15:15:21 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_SELF(a, b);
|
|
|
|
|
NM_CMP_FIELD(a, b, mode);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, no_promisc);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, tap);
|
|
|
|
|
return 0;
|
2015-10-12 15:15:21 +02:00
|
|
|
}
|
|
|
|
|
|
2017-10-17 11:53:08 +02:00
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_sit_hash_update(const NMPlatformLnkSit *obj, NMHashState *h)
|
2017-06-27 19:08:05 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_hash_update_vals(h,
|
|
|
|
|
obj->local,
|
|
|
|
|
obj->remote,
|
|
|
|
|
obj->parent_ifindex,
|
|
|
|
|
obj->flags,
|
|
|
|
|
obj->ttl,
|
|
|
|
|
obj->tos,
|
|
|
|
|
obj->proto,
|
|
|
|
|
(bool) obj->path_mtu_discovery);
|
2017-06-27 19:08:05 +02:00
|
|
|
}
|
|
|
|
|
|
2015-11-11 18:41:48 +01:00
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_sit_cmp(const NMPlatformLnkSit *a, const NMPlatformLnkSit *b)
|
2015-11-11 18:41:48 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_SELF(a, b);
|
|
|
|
|
NM_CMP_FIELD(a, b, parent_ifindex);
|
|
|
|
|
NM_CMP_FIELD(a, b, local);
|
|
|
|
|
NM_CMP_FIELD(a, b, remote);
|
|
|
|
|
NM_CMP_FIELD(a, b, ttl);
|
|
|
|
|
NM_CMP_FIELD(a, b, tos);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, path_mtu_discovery);
|
|
|
|
|
NM_CMP_FIELD(a, b, flags);
|
|
|
|
|
NM_CMP_FIELD(a, b, proto);
|
|
|
|
|
return 0;
|
2015-11-11 18:41:48 +01:00
|
|
|
}
|
|
|
|
|
|
core/platform: add support for TUN/TAP netlink support and various cleanup
Kernel recently got support for exposing TUN/TAP information on netlink
[1], [2], [3]. Add support for it to the platform cache.
The advantage of using netlink is that querying sysctl bypasses the
order of events of the netlink socket. It is out of sync and racy. For
example, platform cache might still think that a tun device exists, but
a subsequent lookup at sysfs might fail because the device was deleted
in the meantime. Another point is, that we don't get change
notifications via sysctl and that it requires various extra syscalls
to read the device information. If the tun information is present on
netlink, put it into the cache. This bypasses checking sysctl while
we keep looking at sysctl for backward compatibility until we require
support from kernel.
Notes:
- we had two link types NM_LINK_TYPE_TAP and NM_LINK_TYPE_TUN. This
deviates from the model of how kernel treats TUN/TAP devices, which
makes it more complicated. The link type of a NMPlatformLink instance
should match what kernel thinks about the device. Point in case,
when parsing RTM_NETLINK messages, we very early need to determine
the link type (_linktype_get_type()). However, to determine the
type of a TUN/TAP at that point, we need to look into nested
netlink attributes which in turn depend on the type (IFLA_INFO_KIND
and IFLA_INFO_DATA), or even worse, we would need to look into
sysctl for older kernel vesions. Now, the TUN/TAP type is a property
of the link type NM_LINK_TYPE_TUN, instead of determining two
different link types.
- various parts of the API (both kernel's sysctl vs. netlink) and
NMDeviceTun vs. NMSettingTun disagree whether the PI is positive
(NM_SETTING_TUN_PI, IFLA_TUN_PI, NMPlatformLnkTun.pi) or inverted
(NM_DEVICE_TUN_NO_PI, IFF_NO_PI). There is no consistent way,
but prefer the positive form for internal API at NMPlatformLnkTun.pi.
- previously NMDeviceTun.mode could not change after initializing
the object. Allow for that to happen, because forcing some properties
that are reported by kernel to not change is wrong, in case they
might change. Of course, in practice kernel doesn't allow the device
to ever change its type, but the type property of the NMDeviceTun
should not make that assumption, because, if it actually changes, what
would it mean?
- note that as of now, new netlink API is not yet merged to mainline Linus
tree. Shortcut _parse_lnk_tun() to not accidentally use unstable API
for now.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1277457
[2] https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/commit/?id=1ec010e705934c8acbe7dbf31afc81e60e3d828b
[3] https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=118eda77d6602616bc523a17ee45171e879d1818
https://bugzilla.redhat.com/show_bug.cgi?id=1547213
https://github.com/NetworkManager/NetworkManager/pull/77
2018-03-13 15:29:03 +01:00
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_tun_hash_update(const NMPlatformLnkTun *obj, NMHashState *h)
|
core/platform: add support for TUN/TAP netlink support and various cleanup
Kernel recently got support for exposing TUN/TAP information on netlink
[1], [2], [3]. Add support for it to the platform cache.
The advantage of using netlink is that querying sysctl bypasses the
order of events of the netlink socket. It is out of sync and racy. For
example, platform cache might still think that a tun device exists, but
a subsequent lookup at sysfs might fail because the device was deleted
in the meantime. Another point is, that we don't get change
notifications via sysctl and that it requires various extra syscalls
to read the device information. If the tun information is present on
netlink, put it into the cache. This bypasses checking sysctl while
we keep looking at sysctl for backward compatibility until we require
support from kernel.
Notes:
- we had two link types NM_LINK_TYPE_TAP and NM_LINK_TYPE_TUN. This
deviates from the model of how kernel treats TUN/TAP devices, which
makes it more complicated. The link type of a NMPlatformLink instance
should match what kernel thinks about the device. Point in case,
when parsing RTM_NETLINK messages, we very early need to determine
the link type (_linktype_get_type()). However, to determine the
type of a TUN/TAP at that point, we need to look into nested
netlink attributes which in turn depend on the type (IFLA_INFO_KIND
and IFLA_INFO_DATA), or even worse, we would need to look into
sysctl for older kernel vesions. Now, the TUN/TAP type is a property
of the link type NM_LINK_TYPE_TUN, instead of determining two
different link types.
- various parts of the API (both kernel's sysctl vs. netlink) and
NMDeviceTun vs. NMSettingTun disagree whether the PI is positive
(NM_SETTING_TUN_PI, IFLA_TUN_PI, NMPlatformLnkTun.pi) or inverted
(NM_DEVICE_TUN_NO_PI, IFF_NO_PI). There is no consistent way,
but prefer the positive form for internal API at NMPlatformLnkTun.pi.
- previously NMDeviceTun.mode could not change after initializing
the object. Allow for that to happen, because forcing some properties
that are reported by kernel to not change is wrong, in case they
might change. Of course, in practice kernel doesn't allow the device
to ever change its type, but the type property of the NMDeviceTun
should not make that assumption, because, if it actually changes, what
would it mean?
- note that as of now, new netlink API is not yet merged to mainline Linus
tree. Shortcut _parse_lnk_tun() to not accidentally use unstable API
for now.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1277457
[2] https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/commit/?id=1ec010e705934c8acbe7dbf31afc81e60e3d828b
[3] https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=118eda77d6602616bc523a17ee45171e879d1818
https://bugzilla.redhat.com/show_bug.cgi?id=1547213
https://github.com/NetworkManager/NetworkManager/pull/77
2018-03-13 15:29:03 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_hash_update_vals(h,
|
|
|
|
|
obj->type,
|
|
|
|
|
obj->owner,
|
|
|
|
|
obj->group,
|
|
|
|
|
NM_HASH_COMBINE_BOOLS(guint8,
|
|
|
|
|
obj->owner_valid,
|
|
|
|
|
obj->group_valid,
|
|
|
|
|
obj->pi,
|
|
|
|
|
obj->vnet_hdr,
|
|
|
|
|
obj->multi_queue,
|
|
|
|
|
obj->persist));
|
core/platform: add support for TUN/TAP netlink support and various cleanup
Kernel recently got support for exposing TUN/TAP information on netlink
[1], [2], [3]. Add support for it to the platform cache.
The advantage of using netlink is that querying sysctl bypasses the
order of events of the netlink socket. It is out of sync and racy. For
example, platform cache might still think that a tun device exists, but
a subsequent lookup at sysfs might fail because the device was deleted
in the meantime. Another point is, that we don't get change
notifications via sysctl and that it requires various extra syscalls
to read the device information. If the tun information is present on
netlink, put it into the cache. This bypasses checking sysctl while
we keep looking at sysctl for backward compatibility until we require
support from kernel.
Notes:
- we had two link types NM_LINK_TYPE_TAP and NM_LINK_TYPE_TUN. This
deviates from the model of how kernel treats TUN/TAP devices, which
makes it more complicated. The link type of a NMPlatformLink instance
should match what kernel thinks about the device. Point in case,
when parsing RTM_NETLINK messages, we very early need to determine
the link type (_linktype_get_type()). However, to determine the
type of a TUN/TAP at that point, we need to look into nested
netlink attributes which in turn depend on the type (IFLA_INFO_KIND
and IFLA_INFO_DATA), or even worse, we would need to look into
sysctl for older kernel vesions. Now, the TUN/TAP type is a property
of the link type NM_LINK_TYPE_TUN, instead of determining two
different link types.
- various parts of the API (both kernel's sysctl vs. netlink) and
NMDeviceTun vs. NMSettingTun disagree whether the PI is positive
(NM_SETTING_TUN_PI, IFLA_TUN_PI, NMPlatformLnkTun.pi) or inverted
(NM_DEVICE_TUN_NO_PI, IFF_NO_PI). There is no consistent way,
but prefer the positive form for internal API at NMPlatformLnkTun.pi.
- previously NMDeviceTun.mode could not change after initializing
the object. Allow for that to happen, because forcing some properties
that are reported by kernel to not change is wrong, in case they
might change. Of course, in practice kernel doesn't allow the device
to ever change its type, but the type property of the NMDeviceTun
should not make that assumption, because, if it actually changes, what
would it mean?
- note that as of now, new netlink API is not yet merged to mainline Linus
tree. Shortcut _parse_lnk_tun() to not accidentally use unstable API
for now.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1277457
[2] https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/commit/?id=1ec010e705934c8acbe7dbf31afc81e60e3d828b
[3] https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=118eda77d6602616bc523a17ee45171e879d1818
https://bugzilla.redhat.com/show_bug.cgi?id=1547213
https://github.com/NetworkManager/NetworkManager/pull/77
2018-03-13 15:29:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_tun_cmp(const NMPlatformLnkTun *a, const NMPlatformLnkTun *b)
|
core/platform: add support for TUN/TAP netlink support and various cleanup
Kernel recently got support for exposing TUN/TAP information on netlink
[1], [2], [3]. Add support for it to the platform cache.
The advantage of using netlink is that querying sysctl bypasses the
order of events of the netlink socket. It is out of sync and racy. For
example, platform cache might still think that a tun device exists, but
a subsequent lookup at sysfs might fail because the device was deleted
in the meantime. Another point is, that we don't get change
notifications via sysctl and that it requires various extra syscalls
to read the device information. If the tun information is present on
netlink, put it into the cache. This bypasses checking sysctl while
we keep looking at sysctl for backward compatibility until we require
support from kernel.
Notes:
- we had two link types NM_LINK_TYPE_TAP and NM_LINK_TYPE_TUN. This
deviates from the model of how kernel treats TUN/TAP devices, which
makes it more complicated. The link type of a NMPlatformLink instance
should match what kernel thinks about the device. Point in case,
when parsing RTM_NETLINK messages, we very early need to determine
the link type (_linktype_get_type()). However, to determine the
type of a TUN/TAP at that point, we need to look into nested
netlink attributes which in turn depend on the type (IFLA_INFO_KIND
and IFLA_INFO_DATA), or even worse, we would need to look into
sysctl for older kernel vesions. Now, the TUN/TAP type is a property
of the link type NM_LINK_TYPE_TUN, instead of determining two
different link types.
- various parts of the API (both kernel's sysctl vs. netlink) and
NMDeviceTun vs. NMSettingTun disagree whether the PI is positive
(NM_SETTING_TUN_PI, IFLA_TUN_PI, NMPlatformLnkTun.pi) or inverted
(NM_DEVICE_TUN_NO_PI, IFF_NO_PI). There is no consistent way,
but prefer the positive form for internal API at NMPlatformLnkTun.pi.
- previously NMDeviceTun.mode could not change after initializing
the object. Allow for that to happen, because forcing some properties
that are reported by kernel to not change is wrong, in case they
might change. Of course, in practice kernel doesn't allow the device
to ever change its type, but the type property of the NMDeviceTun
should not make that assumption, because, if it actually changes, what
would it mean?
- note that as of now, new netlink API is not yet merged to mainline Linus
tree. Shortcut _parse_lnk_tun() to not accidentally use unstable API
for now.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1277457
[2] https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/commit/?id=1ec010e705934c8acbe7dbf31afc81e60e3d828b
[3] https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=118eda77d6602616bc523a17ee45171e879d1818
https://bugzilla.redhat.com/show_bug.cgi?id=1547213
https://github.com/NetworkManager/NetworkManager/pull/77
2018-03-13 15:29:03 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_SELF(a, b);
|
|
|
|
|
NM_CMP_FIELD(a, b, type);
|
|
|
|
|
NM_CMP_FIELD(a, b, owner);
|
|
|
|
|
NM_CMP_FIELD(a, b, group);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, owner_valid);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, group_valid);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, pi);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, vnet_hdr);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, multi_queue);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, persist);
|
|
|
|
|
return 0;
|
core/platform: add support for TUN/TAP netlink support and various cleanup
Kernel recently got support for exposing TUN/TAP information on netlink
[1], [2], [3]. Add support for it to the platform cache.
The advantage of using netlink is that querying sysctl bypasses the
order of events of the netlink socket. It is out of sync and racy. For
example, platform cache might still think that a tun device exists, but
a subsequent lookup at sysfs might fail because the device was deleted
in the meantime. Another point is, that we don't get change
notifications via sysctl and that it requires various extra syscalls
to read the device information. If the tun information is present on
netlink, put it into the cache. This bypasses checking sysctl while
we keep looking at sysctl for backward compatibility until we require
support from kernel.
Notes:
- we had two link types NM_LINK_TYPE_TAP and NM_LINK_TYPE_TUN. This
deviates from the model of how kernel treats TUN/TAP devices, which
makes it more complicated. The link type of a NMPlatformLink instance
should match what kernel thinks about the device. Point in case,
when parsing RTM_NETLINK messages, we very early need to determine
the link type (_linktype_get_type()). However, to determine the
type of a TUN/TAP at that point, we need to look into nested
netlink attributes which in turn depend on the type (IFLA_INFO_KIND
and IFLA_INFO_DATA), or even worse, we would need to look into
sysctl for older kernel vesions. Now, the TUN/TAP type is a property
of the link type NM_LINK_TYPE_TUN, instead of determining two
different link types.
- various parts of the API (both kernel's sysctl vs. netlink) and
NMDeviceTun vs. NMSettingTun disagree whether the PI is positive
(NM_SETTING_TUN_PI, IFLA_TUN_PI, NMPlatformLnkTun.pi) or inverted
(NM_DEVICE_TUN_NO_PI, IFF_NO_PI). There is no consistent way,
but prefer the positive form for internal API at NMPlatformLnkTun.pi.
- previously NMDeviceTun.mode could not change after initializing
the object. Allow for that to happen, because forcing some properties
that are reported by kernel to not change is wrong, in case they
might change. Of course, in practice kernel doesn't allow the device
to ever change its type, but the type property of the NMDeviceTun
should not make that assumption, because, if it actually changes, what
would it mean?
- note that as of now, new netlink API is not yet merged to mainline Linus
tree. Shortcut _parse_lnk_tun() to not accidentally use unstable API
for now.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1277457
[2] https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/commit/?id=1ec010e705934c8acbe7dbf31afc81e60e3d828b
[3] https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=118eda77d6602616bc523a17ee45171e879d1818
https://bugzilla.redhat.com/show_bug.cgi?id=1547213
https://github.com/NetworkManager/NetworkManager/pull/77
2018-03-13 15:29:03 +01:00
|
|
|
}
|
|
|
|
|
|
2017-10-17 11:53:08 +02:00
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_vlan_hash_update(const NMPlatformLnkVlan *obj, NMHashState *h)
|
2017-06-27 19:08:05 +02:00
|
|
|
{
|
2022-12-02 10:47:14 +01:00
|
|
|
nm_hash_update_vals(h, obj->id, obj->protocol, obj->flags);
|
2017-06-27 19:08:05 +02:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 13:44:44 +02:00
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_vlan_cmp(const NMPlatformLnkVlan *a, const NMPlatformLnkVlan *b)
|
2015-10-12 13:44:44 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_SELF(a, b);
|
|
|
|
|
NM_CMP_FIELD(a, b, id);
|
2022-12-02 10:47:14 +01:00
|
|
|
NM_CMP_FIELD(a, b, protocol);
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_FIELD(a, b, flags);
|
|
|
|
|
return 0;
|
2015-10-12 13:44:44 +02:00
|
|
|
}
|
|
|
|
|
|
2019-12-05 10:35:25 +01:00
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_vrf_hash_update(const NMPlatformLnkVrf *obj, NMHashState *h)
|
2019-12-05 10:35:25 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_hash_update_vals(h, obj->table);
|
2019-12-05 10:35:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_vrf_cmp(const NMPlatformLnkVrf *a, const NMPlatformLnkVrf *b)
|
2019-12-05 10:35:25 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_SELF(a, b);
|
|
|
|
|
NM_CMP_FIELD(a, b, table);
|
|
|
|
|
return 0;
|
2019-12-05 10:35:25 +01:00
|
|
|
}
|
|
|
|
|
|
2022-10-24 10:17:09 +02:00
|
|
|
void
|
|
|
|
|
nm_platform_lnk_vti_hash_update(const NMPlatformLnkVti *obj, NMHashState *h)
|
|
|
|
|
{
|
|
|
|
|
nm_hash_update_vals(h,
|
|
|
|
|
obj->local,
|
|
|
|
|
obj->remote,
|
|
|
|
|
obj->parent_ifindex,
|
|
|
|
|
obj->ikey,
|
|
|
|
|
obj->okey,
|
|
|
|
|
obj->fwmark);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
nm_platform_lnk_vti_cmp(const NMPlatformLnkVti *a, const NMPlatformLnkVti *b)
|
|
|
|
|
{
|
|
|
|
|
NM_CMP_SELF(a, b);
|
|
|
|
|
NM_CMP_FIELD(a, b, parent_ifindex);
|
|
|
|
|
NM_CMP_FIELD(a, b, local);
|
|
|
|
|
NM_CMP_FIELD(a, b, remote);
|
|
|
|
|
NM_CMP_FIELD(a, b, ikey);
|
2022-10-25 08:31:47 +02:00
|
|
|
NM_CMP_FIELD(a, b, okey);
|
|
|
|
|
NM_CMP_FIELD(a, b, fwmark);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
nm_platform_lnk_vti6_hash_update(const NMPlatformLnkVti6 *obj, NMHashState *h)
|
|
|
|
|
{
|
|
|
|
|
nm_hash_update_vals(h,
|
|
|
|
|
obj->local,
|
|
|
|
|
obj->remote,
|
|
|
|
|
obj->parent_ifindex,
|
|
|
|
|
obj->ikey,
|
|
|
|
|
obj->okey,
|
|
|
|
|
obj->fwmark);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
nm_platform_lnk_vti6_cmp(const NMPlatformLnkVti6 *a, const NMPlatformLnkVti6 *b)
|
|
|
|
|
{
|
|
|
|
|
NM_CMP_SELF(a, b);
|
|
|
|
|
NM_CMP_FIELD(a, b, parent_ifindex);
|
|
|
|
|
NM_CMP_FIELD_MEMCMP(a, b, local);
|
|
|
|
|
NM_CMP_FIELD_MEMCMP(a, b, remote);
|
|
|
|
|
NM_CMP_FIELD(a, b, ikey);
|
2022-10-24 10:17:09 +02:00
|
|
|
NM_CMP_FIELD(a, b, okey);
|
|
|
|
|
NM_CMP_FIELD(a, b, fwmark);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-17 11:53:08 +02:00
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_vxlan_hash_update(const NMPlatformLnkVxlan *obj, NMHashState *h)
|
|
|
|
|
{
|
|
|
|
|
nm_hash_update_vals(h,
|
|
|
|
|
obj->group6,
|
|
|
|
|
obj->local6,
|
|
|
|
|
obj->group,
|
|
|
|
|
obj->local,
|
|
|
|
|
obj->parent_ifindex,
|
|
|
|
|
obj->id,
|
|
|
|
|
obj->ageing,
|
|
|
|
|
obj->limit,
|
|
|
|
|
obj->dst_port,
|
|
|
|
|
obj->src_port_min,
|
|
|
|
|
obj->src_port_max,
|
|
|
|
|
obj->tos,
|
|
|
|
|
obj->ttl,
|
|
|
|
|
NM_HASH_COMBINE_BOOLS(guint8,
|
|
|
|
|
obj->learning,
|
|
|
|
|
obj->proxy,
|
|
|
|
|
obj->rsc,
|
|
|
|
|
obj->l2miss,
|
|
|
|
|
obj->l3miss));
|
2017-06-27 19:08:05 +02:00
|
|
|
}
|
|
|
|
|
|
2015-10-12 15:15:21 +02:00
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_vxlan_cmp(const NMPlatformLnkVxlan *a, const NMPlatformLnkVxlan *b)
|
|
|
|
|
{
|
|
|
|
|
NM_CMP_SELF(a, b);
|
|
|
|
|
NM_CMP_FIELD(a, b, parent_ifindex);
|
|
|
|
|
NM_CMP_FIELD(a, b, id);
|
|
|
|
|
NM_CMP_FIELD(a, b, group);
|
|
|
|
|
NM_CMP_FIELD(a, b, local);
|
|
|
|
|
NM_CMP_FIELD_MEMCMP(a, b, group6);
|
|
|
|
|
NM_CMP_FIELD_MEMCMP(a, b, local6);
|
|
|
|
|
NM_CMP_FIELD(a, b, tos);
|
|
|
|
|
NM_CMP_FIELD(a, b, ttl);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, learning);
|
|
|
|
|
NM_CMP_FIELD(a, b, ageing);
|
|
|
|
|
NM_CMP_FIELD(a, b, limit);
|
|
|
|
|
NM_CMP_FIELD(a, b, dst_port);
|
|
|
|
|
NM_CMP_FIELD(a, b, src_port_min);
|
|
|
|
|
NM_CMP_FIELD(a, b, src_port_max);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, proxy);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, rsc);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, l2miss);
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, l3miss);
|
|
|
|
|
return 0;
|
2015-10-12 15:15:21 +02:00
|
|
|
}
|
|
|
|
|
|
2018-03-13 13:35:35 +00:00
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_wireguard_hash_update(const NMPlatformLnkWireGuard *obj, NMHashState *h)
|
2018-03-13 13:35:35 +00:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_hash_update_vals(h, obj->listen_port, obj->fwmark);
|
|
|
|
|
nm_hash_update(h, obj->private_key, sizeof(obj->private_key));
|
|
|
|
|
nm_hash_update(h, obj->public_key, sizeof(obj->public_key));
|
2018-03-13 13:35:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_lnk_wireguard_cmp(const NMPlatformLnkWireGuard *a, const NMPlatformLnkWireGuard *b)
|
2018-03-13 13:35:35 +00:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_SELF(a, b);
|
|
|
|
|
NM_CMP_FIELD(a, b, listen_port);
|
|
|
|
|
NM_CMP_FIELD(a, b, fwmark);
|
|
|
|
|
NM_CMP_FIELD_MEMCMP(a, b, private_key);
|
|
|
|
|
NM_CMP_FIELD_MEMCMP(a, b, public_key);
|
|
|
|
|
return 0;
|
2018-03-13 13:35:35 +00:00
|
|
|
}
|
|
|
|
|
|
2022-09-15 14:03:51 +02:00
|
|
|
void
|
|
|
|
|
nm_platform_ip4_rt_nexthop_hash_update(const NMPlatformIP4RtNextHop *obj,
|
|
|
|
|
gboolean for_id,
|
|
|
|
|
NMHashState *h)
|
|
|
|
|
{
|
|
|
|
|
guint8 w;
|
|
|
|
|
|
|
|
|
|
nm_assert(obj);
|
|
|
|
|
|
|
|
|
|
w = for_id ? NM_MAX(obj->weight, 1u) : obj->weight;
|
|
|
|
|
|
|
|
|
|
nm_hash_update_vals(h, obj->ifindex, obj->gateway, w);
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-17 11:53:08 +02:00
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_ip4_route_hash_update(const NMPlatformIP4Route *obj,
|
|
|
|
|
NMPlatformIPRouteCmpType cmp_type,
|
2021-11-09 13:28:54 +01:00
|
|
|
NMHashState *h)
|
2020-09-28 16:03:33 +02:00
|
|
|
{
|
|
|
|
|
switch (cmp_type) {
|
|
|
|
|
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID:
|
2022-11-08 15:56:56 +01:00
|
|
|
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ECMP_ID:
|
2020-09-28 16:03:33 +02:00
|
|
|
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID:
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
nm_hash_update_vals(
|
|
|
|
|
h,
|
|
|
|
|
nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(obj)),
|
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_ip4_addr_clear_host_address(obj->network, obj->plen),
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
obj->plen,
|
2020-10-22 10:29:03 +02:00
|
|
|
obj->metric,
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
obj->tos,
|
2022-11-08 15:56:56 +01:00
|
|
|
NM_HASH_COMBINE_BOOLS(guint8, obj->metric_any, obj->table_any));
|
|
|
|
|
if (NM_IN_SET(cmp_type,
|
|
|
|
|
NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID,
|
|
|
|
|
NM_PLATFORM_IP_ROUTE_CMP_TYPE_ECMP_ID)) {
|
|
|
|
|
nm_hash_update_vals(h,
|
|
|
|
|
obj->type_coerced,
|
|
|
|
|
nmp_utils_ip_config_source_round_trip_rtprot(obj->rt_source),
|
|
|
|
|
_ip_route_scope_inv_get_normalized(obj),
|
|
|
|
|
obj->mss,
|
|
|
|
|
obj->pref_src,
|
|
|
|
|
obj->window,
|
|
|
|
|
obj->cwnd,
|
|
|
|
|
obj->initcwnd,
|
|
|
|
|
obj->initrwnd,
|
|
|
|
|
obj->mtu,
|
|
|
|
|
obj->rto_min,
|
|
|
|
|
obj->r_rtm_flags & RTNH_F_ONLINK,
|
|
|
|
|
NM_HASH_COMBINE_BOOLS(guint16,
|
|
|
|
|
obj->quickack,
|
|
|
|
|
obj->lock_window,
|
|
|
|
|
obj->lock_cwnd,
|
|
|
|
|
obj->lock_initcwnd,
|
|
|
|
|
obj->lock_initrwnd,
|
|
|
|
|
obj->lock_mtu,
|
|
|
|
|
obj->lock_mss));
|
|
|
|
|
if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) {
|
|
|
|
|
nm_hash_update_vals(h,
|
|
|
|
|
obj->ifindex,
|
|
|
|
|
nm_platform_ip4_route_get_n_nexthops(obj),
|
|
|
|
|
obj->gateway,
|
2022-11-23 13:52:11 +01:00
|
|
|
(guint8) MAX(obj->weight, 1u));
|
2022-11-08 15:56:56 +01:00
|
|
|
}
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
break;
|
|
|
|
|
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY:
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
nm_hash_update_vals(
|
|
|
|
|
h,
|
|
|
|
|
obj->type_coerced,
|
|
|
|
|
nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(obj)),
|
|
|
|
|
obj->ifindex,
|
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_ip4_addr_clear_host_address(obj->network, obj->plen),
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
obj->plen,
|
2020-10-22 10:29:03 +02:00
|
|
|
obj->metric,
|
2022-09-15 14:03:51 +02:00
|
|
|
nm_platform_ip4_route_get_n_nexthops(obj),
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
obj->gateway,
|
2022-11-23 13:52:11 +01:00
|
|
|
(guint8) MAX(obj->weight, 1u),
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
nmp_utils_ip_config_source_round_trip_rtprot(obj->rt_source),
|
|
|
|
|
_ip_route_scope_inv_get_normalized(obj),
|
|
|
|
|
obj->tos,
|
|
|
|
|
obj->mss,
|
|
|
|
|
obj->pref_src,
|
|
|
|
|
obj->window,
|
|
|
|
|
obj->cwnd,
|
|
|
|
|
obj->initcwnd,
|
|
|
|
|
obj->initrwnd,
|
|
|
|
|
obj->mtu,
|
2022-06-23 21:59:40 +02:00
|
|
|
obj->rto_min,
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
obj->r_rtm_flags & (RTM_F_CLONED | RTNH_F_ONLINK),
|
2022-06-23 21:59:40 +02:00
|
|
|
NM_HASH_COMBINE_BOOLS(guint16,
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
obj->metric_any,
|
|
|
|
|
obj->table_any,
|
2022-06-23 21:59:40 +02:00
|
|
|
obj->quickack,
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
obj->lock_window,
|
|
|
|
|
obj->lock_cwnd,
|
|
|
|
|
obj->lock_initcwnd,
|
|
|
|
|
obj->lock_initrwnd,
|
2022-06-23 21:59:40 +02:00
|
|
|
obj->lock_mtu,
|
|
|
|
|
obj->lock_mss));
|
2020-09-28 16:03:33 +02:00
|
|
|
break;
|
|
|
|
|
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL:
|
|
|
|
|
nm_hash_update_vals(h,
|
|
|
|
|
obj->type_coerced,
|
|
|
|
|
obj->table_coerced,
|
|
|
|
|
obj->ifindex,
|
|
|
|
|
obj->network,
|
|
|
|
|
obj->plen,
|
2020-10-22 10:29:03 +02:00
|
|
|
obj->metric,
|
2020-09-28 16:03:33 +02:00
|
|
|
obj->gateway,
|
2022-09-15 14:03:51 +02:00
|
|
|
obj->n_nexthops,
|
|
|
|
|
obj->weight,
|
2020-09-28 16:03:33 +02:00
|
|
|
obj->rt_source,
|
|
|
|
|
obj->scope_inv,
|
|
|
|
|
obj->tos,
|
|
|
|
|
obj->mss,
|
|
|
|
|
obj->pref_src,
|
|
|
|
|
obj->window,
|
|
|
|
|
obj->cwnd,
|
|
|
|
|
obj->initcwnd,
|
|
|
|
|
obj->initrwnd,
|
|
|
|
|
obj->mtu,
|
2022-06-23 21:59:40 +02:00
|
|
|
obj->rto_min,
|
2020-09-28 16:03:33 +02:00
|
|
|
obj->r_rtm_flags,
|
2022-06-23 21:59:40 +02:00
|
|
|
NM_HASH_COMBINE_BOOLS(guint16,
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
obj->metric_any,
|
|
|
|
|
obj->table_any,
|
2022-06-23 21:59:40 +02:00
|
|
|
obj->quickack,
|
2020-09-28 16:03:33 +02:00
|
|
|
obj->lock_window,
|
|
|
|
|
obj->lock_cwnd,
|
|
|
|
|
obj->lock_initcwnd,
|
|
|
|
|
obj->lock_initrwnd,
|
2021-07-20 11:09:40 +02:00
|
|
|
obj->lock_mtu,
|
2023-02-28 14:29:50 +01:00
|
|
|
obj->lock_mss));
|
2020-09-28 16:03:33 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2017-06-12 18:39:53 +02:00
|
|
|
}
|
|
|
|
|
|
2022-09-15 14:03:51 +02:00
|
|
|
int
|
|
|
|
|
nm_platform_ip4_rt_nexthop_cmp(const NMPlatformIP4RtNextHop *a,
|
|
|
|
|
const NMPlatformIP4RtNextHop *b,
|
|
|
|
|
gboolean for_id)
|
|
|
|
|
{
|
|
|
|
|
guint8 w_a;
|
|
|
|
|
guint8 w_b;
|
|
|
|
|
|
|
|
|
|
/* Note that weight zero is not valid (in kernel). We thus treat
|
|
|
|
|
* weight zero usually the same as 1.
|
|
|
|
|
*
|
|
|
|
|
* Not here for cmp/hash_update functions. These functions check for the exact
|
|
|
|
|
* bit-pattern, and not the it means at other places. */
|
|
|
|
|
NM_CMP_SELF(a, b);
|
|
|
|
|
NM_CMP_FIELD(a, b, ifindex);
|
|
|
|
|
NM_CMP_FIELD(a, b, gateway);
|
|
|
|
|
|
|
|
|
|
w_a = for_id ? NM_MAX(a->weight, 1u) : a->weight;
|
|
|
|
|
w_b = for_id ? NM_MAX(b->weight, 1u) : b->weight;
|
|
|
|
|
NM_CMP_DIRECT(w_a, w_b);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-06 09:58:55 +02:00
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_ip4_route_cmp(const NMPlatformIP4Route *a,
|
|
|
|
|
const NMPlatformIP4Route *b,
|
|
|
|
|
NMPlatformIPRouteCmpType cmp_type)
|
|
|
|
|
{
|
|
|
|
|
NM_CMP_SELF(a, b);
|
|
|
|
|
switch (cmp_type) {
|
2022-11-08 15:56:56 +01:00
|
|
|
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ECMP_ID:
|
2020-09-28 16:03:33 +02:00
|
|
|
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID:
|
|
|
|
|
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID:
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, table_any);
|
|
|
|
|
NM_CMP_DIRECT(nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(a)),
|
|
|
|
|
nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(b)));
|
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_CMP_DIRECT_IP4_ADDR_SAME_PREFIX(a->network, b->network, MIN(a->plen, b->plen));
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_FIELD(a, b, plen);
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, metric_any);
|
2020-10-22 10:29:03 +02:00
|
|
|
NM_CMP_FIELD(a, b, metric);
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_FIELD(a, b, tos);
|
2022-11-08 15:56:56 +01:00
|
|
|
if (NM_IN_SET(cmp_type,
|
|
|
|
|
NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID,
|
|
|
|
|
NM_PLATFORM_IP_ROUTE_CMP_TYPE_ECMP_ID)) {
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_FIELD(a, b, type_coerced);
|
|
|
|
|
NM_CMP_DIRECT(nmp_utils_ip_config_source_round_trip_rtprot(a->rt_source),
|
|
|
|
|
nmp_utils_ip_config_source_round_trip_rtprot(b->rt_source));
|
|
|
|
|
NM_CMP_DIRECT(_ip_route_scope_inv_get_normalized(a),
|
|
|
|
|
_ip_route_scope_inv_get_normalized(b));
|
|
|
|
|
NM_CMP_FIELD(a, b, mss);
|
|
|
|
|
NM_CMP_FIELD(a, b, pref_src);
|
|
|
|
|
NM_CMP_FIELD(a, b, window);
|
|
|
|
|
NM_CMP_FIELD(a, b, cwnd);
|
|
|
|
|
NM_CMP_FIELD(a, b, initcwnd);
|
|
|
|
|
NM_CMP_FIELD(a, b, initrwnd);
|
|
|
|
|
NM_CMP_FIELD(a, b, mtu);
|
2022-06-23 21:59:40 +02:00
|
|
|
NM_CMP_FIELD(a, b, rto_min);
|
2023-02-01 08:58:15 +01:00
|
|
|
|
|
|
|
|
/* Note that for NetworkManager, the onlink flag is only part of the entire route.
|
|
|
|
|
* For kernel, each next hop has it's own onlink flag (rtnh_flags). This means,
|
|
|
|
|
* we can only merge ECMP routes, if they agree with their onlink flag, and then
|
|
|
|
|
* all next hops are onlink (or not). */
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_DIRECT(a->r_rtm_flags & RTNH_F_ONLINK, b->r_rtm_flags & RTNH_F_ONLINK);
|
2023-02-01 08:58:15 +01:00
|
|
|
|
2022-06-23 21:59:40 +02:00
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, quickack);
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, lock_window);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, lock_cwnd);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, lock_initcwnd);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, lock_initrwnd);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, lock_mtu);
|
2022-06-23 21:59:40 +02:00
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, lock_mss);
|
2022-11-08 15:56:56 +01:00
|
|
|
if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) {
|
|
|
|
|
NM_CMP_FIELD(a, b, ifindex);
|
|
|
|
|
NM_CMP_FIELD(a, b, gateway);
|
|
|
|
|
NM_CMP_DIRECT(NM_MAX(a->weight, 1u), NM_MAX(b->weight, 1u));
|
|
|
|
|
NM_CMP_DIRECT(nm_platform_ip4_route_get_n_nexthops(a),
|
|
|
|
|
nm_platform_ip4_route_get_n_nexthops(b));
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY:
|
|
|
|
|
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL:
|
|
|
|
|
NM_CMP_FIELD(a, b, type_coerced);
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, table_any);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) {
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
NM_CMP_DIRECT(nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(a)),
|
|
|
|
|
nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(b)));
|
2020-09-28 16:03:33 +02:00
|
|
|
} else
|
|
|
|
|
NM_CMP_FIELD(a, b, table_coerced);
|
|
|
|
|
NM_CMP_FIELD(a, b, ifindex);
|
|
|
|
|
if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY)
|
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_CMP_DIRECT_IP4_ADDR_SAME_PREFIX(a->network, b->network, MIN(a->plen, b->plen));
|
2020-09-28 16:03:33 +02:00
|
|
|
else
|
|
|
|
|
NM_CMP_FIELD(a, b, network);
|
|
|
|
|
NM_CMP_FIELD(a, b, plen);
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, metric_any);
|
2020-10-22 10:29:03 +02:00
|
|
|
NM_CMP_FIELD(a, b, metric);
|
2022-09-15 14:03:51 +02:00
|
|
|
if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) {
|
|
|
|
|
NM_CMP_DIRECT(nm_platform_ip4_route_get_n_nexthops(a),
|
|
|
|
|
nm_platform_ip4_route_get_n_nexthops(b));
|
|
|
|
|
} else
|
|
|
|
|
NM_CMP_FIELD(a, b, n_nexthops);
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_FIELD(a, b, gateway);
|
2022-09-15 14:03:51 +02:00
|
|
|
if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY)
|
|
|
|
|
NM_CMP_DIRECT(NM_MAX(a->weight, 1u), NM_MAX(b->weight, 1u));
|
|
|
|
|
else
|
|
|
|
|
NM_CMP_FIELD(a, b, weight);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) {
|
|
|
|
|
NM_CMP_DIRECT(nmp_utils_ip_config_source_round_trip_rtprot(a->rt_source),
|
|
|
|
|
nmp_utils_ip_config_source_round_trip_rtprot(b->rt_source));
|
|
|
|
|
NM_CMP_DIRECT(_ip_route_scope_inv_get_normalized(a),
|
|
|
|
|
_ip_route_scope_inv_get_normalized(b));
|
|
|
|
|
} else {
|
|
|
|
|
NM_CMP_FIELD(a, b, rt_source);
|
|
|
|
|
NM_CMP_FIELD(a, b, scope_inv);
|
|
|
|
|
}
|
|
|
|
|
NM_CMP_FIELD(a, b, mss);
|
|
|
|
|
NM_CMP_FIELD(a, b, pref_src);
|
|
|
|
|
if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) {
|
|
|
|
|
NM_CMP_DIRECT(a->r_rtm_flags & (RTM_F_CLONED | RTNH_F_ONLINK),
|
|
|
|
|
b->r_rtm_flags & (RTM_F_CLONED | RTNH_F_ONLINK));
|
|
|
|
|
} else
|
|
|
|
|
NM_CMP_FIELD(a, b, r_rtm_flags);
|
|
|
|
|
NM_CMP_FIELD(a, b, tos);
|
2022-06-23 21:59:40 +02:00
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, quickack);
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, lock_window);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, lock_cwnd);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, lock_initcwnd);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, lock_initrwnd);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, lock_mtu);
|
2022-06-23 21:59:40 +02:00
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, lock_mss);
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_FIELD(a, b, window);
|
|
|
|
|
NM_CMP_FIELD(a, b, cwnd);
|
|
|
|
|
NM_CMP_FIELD(a, b, initcwnd);
|
|
|
|
|
NM_CMP_FIELD(a, b, initrwnd);
|
|
|
|
|
NM_CMP_FIELD(a, b, mtu);
|
2022-06-23 21:59:40 +02:00
|
|
|
NM_CMP_FIELD(a, b, rto_min);
|
2020-09-28 16:03:33 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
2013-09-06 09:58:55 +02:00
|
|
|
}
|
|
|
|
|
|
2017-10-17 11:53:08 +02:00
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_ip6_route_hash_update(const NMPlatformIP6Route *obj,
|
|
|
|
|
NMPlatformIPRouteCmpType cmp_type,
|
2021-11-09 13:28:54 +01:00
|
|
|
NMHashState *h)
|
2020-09-28 16:03:33 +02:00
|
|
|
{
|
|
|
|
|
struct in6_addr a1, a2;
|
|
|
|
|
|
|
|
|
|
switch (cmp_type) {
|
|
|
|
|
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID:
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
nm_hash_update_vals(
|
|
|
|
|
h,
|
|
|
|
|
nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(obj)),
|
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_ip6_addr_clear_host_address(&a1, &obj->network, obj->plen),
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
obj->plen,
|
2020-10-22 10:29:03 +02:00
|
|
|
obj->metric,
|
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_ip6_addr_clear_host_address(&a2, &obj->src, obj->src_plen),
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
obj->src_plen,
|
|
|
|
|
NM_HASH_COMBINE_BOOLS(guint8, obj->metric_any, obj->table_any));
|
2020-09-28 16:03:33 +02:00
|
|
|
break;
|
2022-11-08 15:56:56 +01:00
|
|
|
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ECMP_ID:
|
|
|
|
|
nm_assert_not_reached();
|
|
|
|
|
/* fall-through */
|
2020-09-28 16:03:33 +02:00
|
|
|
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID:
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
nm_hash_update_vals(
|
|
|
|
|
h,
|
|
|
|
|
obj->type_coerced,
|
|
|
|
|
nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(obj)),
|
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_ip6_addr_clear_host_address(&a1, &obj->network, obj->plen),
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
obj->plen,
|
2020-10-22 10:29:03 +02:00
|
|
|
obj->metric,
|
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_ip6_addr_clear_host_address(&a2, &obj->src, obj->src_plen),
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
obj->src_plen,
|
|
|
|
|
NM_HASH_COMBINE_BOOLS(guint8, obj->metric_any, obj->table_any),
|
|
|
|
|
/* on top of WEAK_ID: */
|
|
|
|
|
obj->ifindex,
|
|
|
|
|
obj->gateway);
|
2020-09-28 16:03:33 +02:00
|
|
|
break;
|
|
|
|
|
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY:
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
nm_hash_update_vals(
|
|
|
|
|
h,
|
|
|
|
|
obj->type_coerced,
|
|
|
|
|
nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(obj)),
|
|
|
|
|
obj->ifindex,
|
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_ip6_addr_clear_host_address(&a1, &obj->network, obj->plen),
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
obj->plen,
|
2020-10-22 10:29:03 +02:00
|
|
|
obj->metric,
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
obj->gateway,
|
|
|
|
|
obj->pref_src,
|
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_ip6_addr_clear_host_address(&a2, &obj->src, obj->src_plen),
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
obj->src_plen,
|
|
|
|
|
nmp_utils_ip_config_source_round_trip_rtprot(obj->rt_source),
|
|
|
|
|
obj->mss,
|
|
|
|
|
obj->r_rtm_flags & RTM_F_CLONED,
|
2022-06-23 21:59:40 +02:00
|
|
|
NM_HASH_COMBINE_BOOLS(guint16,
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
obj->metric_any,
|
|
|
|
|
obj->table_any,
|
2022-06-23 21:59:40 +02:00
|
|
|
obj->quickack,
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
obj->lock_window,
|
|
|
|
|
obj->lock_cwnd,
|
|
|
|
|
obj->lock_initcwnd,
|
|
|
|
|
obj->lock_initrwnd,
|
2022-06-23 21:59:40 +02:00
|
|
|
obj->lock_mtu,
|
|
|
|
|
obj->lock_mss),
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
obj->window,
|
|
|
|
|
obj->cwnd,
|
|
|
|
|
obj->initcwnd,
|
|
|
|
|
obj->initrwnd,
|
|
|
|
|
obj->mtu,
|
2022-06-23 21:59:40 +02:00
|
|
|
obj->rto_min,
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
_route_pref_normalize(obj->rt_pref));
|
2020-09-28 16:03:33 +02:00
|
|
|
break;
|
|
|
|
|
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL:
|
|
|
|
|
nm_hash_update_vals(h,
|
|
|
|
|
obj->type_coerced,
|
|
|
|
|
obj->table_coerced,
|
|
|
|
|
obj->ifindex,
|
|
|
|
|
obj->network,
|
2020-10-22 10:29:03 +02:00
|
|
|
obj->metric,
|
2020-09-28 16:03:33 +02:00
|
|
|
obj->gateway,
|
|
|
|
|
obj->pref_src,
|
|
|
|
|
obj->src,
|
|
|
|
|
obj->src_plen,
|
|
|
|
|
obj->rt_source,
|
|
|
|
|
obj->mss,
|
|
|
|
|
obj->r_rtm_flags,
|
2021-09-06 13:58:59 +02:00
|
|
|
NM_HASH_COMBINE_BOOLS(guint16,
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
obj->metric_any,
|
|
|
|
|
obj->table_any,
|
2022-06-23 21:59:40 +02:00
|
|
|
obj->quickack,
|
2020-09-28 16:03:33 +02:00
|
|
|
obj->lock_window,
|
|
|
|
|
obj->lock_cwnd,
|
|
|
|
|
obj->lock_initcwnd,
|
|
|
|
|
obj->lock_initrwnd,
|
2021-07-20 11:09:40 +02:00
|
|
|
obj->lock_mtu,
|
2023-02-28 14:29:50 +01:00
|
|
|
obj->lock_mss),
|
2020-09-28 16:03:33 +02:00
|
|
|
obj->window,
|
|
|
|
|
obj->cwnd,
|
|
|
|
|
obj->initcwnd,
|
|
|
|
|
obj->initrwnd,
|
|
|
|
|
obj->mtu,
|
2022-06-23 21:59:40 +02:00
|
|
|
obj->rto_min,
|
2020-09-28 16:03:33 +02:00
|
|
|
obj->rt_pref);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2017-06-12 18:39:53 +02:00
|
|
|
}
|
|
|
|
|
|
2013-09-06 09:58:55 +02:00
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_ip6_route_cmp(const NMPlatformIP6Route *a,
|
|
|
|
|
const NMPlatformIP6Route *b,
|
|
|
|
|
NMPlatformIPRouteCmpType cmp_type)
|
|
|
|
|
{
|
|
|
|
|
NM_CMP_SELF(a, b);
|
|
|
|
|
switch (cmp_type) {
|
2022-11-08 15:56:56 +01:00
|
|
|
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ECMP_ID:
|
|
|
|
|
nm_assert_not_reached();
|
|
|
|
|
/* fall-through */
|
2020-09-28 16:03:33 +02:00
|
|
|
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID:
|
|
|
|
|
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID:
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, table_any);
|
|
|
|
|
NM_CMP_DIRECT(nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(a)),
|
|
|
|
|
nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(b)));
|
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_CMP_DIRECT_IP6_ADDR_SAME_PREFIX(&a->network, &b->network, MIN(a->plen, b->plen));
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_FIELD(a, b, plen);
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, metric_any);
|
2020-10-22 10:29:03 +02:00
|
|
|
NM_CMP_FIELD(a, b, metric);
|
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_CMP_DIRECT_IP6_ADDR_SAME_PREFIX(&a->src, &b->src, MIN(a->src_plen, b->src_plen));
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_FIELD(a, b, src_plen);
|
|
|
|
|
if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) {
|
|
|
|
|
NM_CMP_FIELD(a, b, ifindex);
|
|
|
|
|
NM_CMP_FIELD(a, b, type_coerced);
|
|
|
|
|
NM_CMP_FIELD_IN6ADDR(a, b, gateway);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY:
|
|
|
|
|
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL:
|
|
|
|
|
NM_CMP_FIELD(a, b, type_coerced);
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, table_any);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) {
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
NM_CMP_DIRECT(nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(a)),
|
|
|
|
|
nm_platform_ip_route_get_effective_table(NM_PLATFORM_IP_ROUTE_CAST(b)));
|
2020-09-28 16:03:33 +02:00
|
|
|
} else
|
|
|
|
|
NM_CMP_FIELD(a, b, table_coerced);
|
|
|
|
|
NM_CMP_FIELD(a, b, ifindex);
|
|
|
|
|
if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY)
|
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_CMP_DIRECT_IP6_ADDR_SAME_PREFIX(&a->network, &b->network, MIN(a->plen, b->plen));
|
2020-09-28 16:03:33 +02:00
|
|
|
else
|
|
|
|
|
NM_CMP_FIELD_IN6ADDR(a, b, network);
|
|
|
|
|
NM_CMP_FIELD(a, b, plen);
|
platform: add flags to NMPlatformIP[46]Route to allow overriding the route table and metric
When we (for example) receive a DHCP lease, we track the routes that
should be configured via NMPlatformIP[46]Route instances. Thus, this
structure does not only track the routes that are configured (and
cached in NMPlatform), but it is also used to track the routes that
we want to configure.
This is also the case with the "rt_source" field, which represents the
NMIPConfigSource enum for routes that we want to configure, but
for routes in the cache it corresponds to rtm_protocol.
Note that NMDhcpClient creates NMIP4Config instances, which tracks the
routes as NMPlatformIP4Route instances. Previously, NMDhcpClient didn't
have any way to leave the table/metric undecided, but this information
isn't part of the DHCP lease tself. Instead, NMDevice knows the table/metric
to use. This has various problems:
- NMDhcpClient needs to know the table/metric, for no other purpose
than to set the value when creating the NMIP4Config instance for the
lease. We first pass the information down, only so that it can be
returned with the lease information.
- during reapply or when connectivity check changes, the effectively
used table/metric can change. Previously, we would have to
re-generate the NMIP4Config instances.
Improve that by allowing to leave the table/metric undecided. Higher
layers can decide the effective metric to use.
2020-09-23 13:38:39 +02:00
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, metric_any);
|
2020-10-22 10:29:03 +02:00
|
|
|
NM_CMP_FIELD(a, b, metric);
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_FIELD_IN6ADDR(a, b, gateway);
|
|
|
|
|
NM_CMP_FIELD_IN6ADDR(a, b, pref_src);
|
|
|
|
|
if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) {
|
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_CMP_DIRECT_IP6_ADDR_SAME_PREFIX(&a->src, &b->src, MIN(a->src_plen, b->src_plen));
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_FIELD(a, b, src_plen);
|
|
|
|
|
NM_CMP_DIRECT(nmp_utils_ip_config_source_round_trip_rtprot(a->rt_source),
|
|
|
|
|
nmp_utils_ip_config_source_round_trip_rtprot(b->rt_source));
|
|
|
|
|
} else {
|
|
|
|
|
NM_CMP_FIELD_IN6ADDR(a, b, src);
|
|
|
|
|
NM_CMP_FIELD(a, b, src_plen);
|
|
|
|
|
NM_CMP_FIELD(a, b, rt_source);
|
|
|
|
|
}
|
|
|
|
|
NM_CMP_FIELD(a, b, mss);
|
|
|
|
|
if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) {
|
|
|
|
|
NM_CMP_DIRECT(a->r_rtm_flags & RTM_F_CLONED, b->r_rtm_flags & RTM_F_CLONED);
|
|
|
|
|
} else
|
|
|
|
|
NM_CMP_FIELD(a, b, r_rtm_flags);
|
2022-06-23 21:59:40 +02:00
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, quickack);
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, lock_window);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, lock_cwnd);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, lock_initcwnd);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, lock_initrwnd);
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, lock_mtu);
|
2022-06-23 21:59:40 +02:00
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, lock_mss);
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_FIELD(a, b, window);
|
|
|
|
|
NM_CMP_FIELD(a, b, cwnd);
|
|
|
|
|
NM_CMP_FIELD(a, b, initcwnd);
|
|
|
|
|
NM_CMP_FIELD(a, b, initrwnd);
|
|
|
|
|
NM_CMP_FIELD(a, b, mtu);
|
2022-06-23 21:59:40 +02:00
|
|
|
NM_CMP_FIELD(a, b, rto_min);
|
2020-09-28 16:03:33 +02:00
|
|
|
if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY)
|
|
|
|
|
NM_CMP_DIRECT(_route_pref_normalize(a->rt_pref), _route_pref_normalize(b->rt_pref));
|
|
|
|
|
else
|
|
|
|
|
NM_CMP_FIELD(a, b, rt_pref);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define _ROUTING_RULE_FLAGS_IGNORE \
|
|
|
|
|
(FIB_RULE_UNRESOLVED | FIB_RULE_IIF_DETACHED | FIB_RULE_OIF_DETACHED)
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2019-04-17 09:17:51 +02:00
|
|
|
#define _routing_rule_compare(cmp_type, kernel_support_type) \
|
2020-09-28 16:03:33 +02:00
|
|
|
((cmp_type) == NM_PLATFORM_ROUTING_RULE_CMP_TYPE_FULL \
|
|
|
|
|
|| nm_platform_kernel_support_get(kernel_support_type))
|
2019-04-17 09:17:51 +02:00
|
|
|
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_routing_rule_hash_update(const NMPlatformRoutingRule *obj,
|
|
|
|
|
NMPlatformRoutingRuleCmpType cmp_type,
|
2021-11-09 13:28:54 +01:00
|
|
|
NMHashState *h)
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
gboolean cmp_full = TRUE;
|
|
|
|
|
gsize addr_size;
|
|
|
|
|
guint32 flags_mask = G_MAXUINT32;
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (G_UNLIKELY(!NM_IN_SET(obj->addr_family, AF_INET, AF_INET6))) {
|
|
|
|
|
/* the address family is not one of the supported ones. That means, the
|
2020-09-28 14:50:01 +02:00
|
|
|
* instance will only compare equal to itself (pointer-equality). */
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_hash_update_val(h, (gconstpointer) obj);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (cmp_type) {
|
|
|
|
|
case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID:
|
|
|
|
|
|
|
|
|
|
flags_mask &= ~_ROUTING_RULE_FLAGS_IGNORE;
|
|
|
|
|
|
|
|
|
|
/* fall-through */
|
|
|
|
|
case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_SEMANTICALLY:
|
|
|
|
|
|
|
|
|
|
cmp_full = FALSE;
|
|
|
|
|
|
|
|
|
|
/* fall-through */
|
|
|
|
|
case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_FULL:
|
|
|
|
|
|
|
|
|
|
nm_hash_update_vals(
|
|
|
|
|
h,
|
|
|
|
|
obj->addr_family,
|
|
|
|
|
obj->tun_id,
|
|
|
|
|
obj->table,
|
|
|
|
|
obj->flags & flags_mask,
|
|
|
|
|
obj->priority,
|
|
|
|
|
obj->fwmark,
|
|
|
|
|
obj->fwmask,
|
|
|
|
|
((cmp_full
|
|
|
|
|
|| (cmp_type == NM_PLATFORM_ROUTING_RULE_CMP_TYPE_SEMANTICALLY
|
|
|
|
|
&& obj->action == FR_ACT_GOTO))
|
|
|
|
|
? obj->goto_target
|
|
|
|
|
: (guint32) 0u),
|
|
|
|
|
((cmp_full || obj->addr_family == AF_INET) ? obj->flow : (guint32) 0u),
|
|
|
|
|
NM_HASH_COMBINE_BOOLS(
|
|
|
|
|
guint8,
|
|
|
|
|
(_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_UID_RANGE)
|
|
|
|
|
? obj->uid_range_has
|
|
|
|
|
: FALSE)),
|
|
|
|
|
obj->suppress_prefixlen_inverse,
|
|
|
|
|
obj->suppress_ifgroup_inverse,
|
|
|
|
|
(_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_L3MDEV)
|
|
|
|
|
? (cmp_full ? (guint16) obj->l3mdev : (guint16) !!obj->l3mdev)
|
|
|
|
|
: G_MAXUINT16),
|
|
|
|
|
obj->action,
|
|
|
|
|
obj->tos,
|
|
|
|
|
obj->src_len,
|
|
|
|
|
obj->dst_len,
|
|
|
|
|
(_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_PROTOCOL)
|
|
|
|
|
? (guint16) obj->protocol
|
|
|
|
|
: G_MAXUINT16));
|
|
|
|
|
addr_size = nm_utils_addr_family_to_size(obj->addr_family);
|
|
|
|
|
if (cmp_full || obj->src_len > 0)
|
|
|
|
|
nm_hash_update(h, &obj->src, addr_size);
|
|
|
|
|
if (cmp_full || obj->dst_len > 0)
|
|
|
|
|
nm_hash_update(h, &obj->dst, addr_size);
|
|
|
|
|
if (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_UID_RANGE)) {
|
|
|
|
|
if (cmp_full || obj->uid_range_has)
|
|
|
|
|
nm_hash_update_valp(h, &obj->uid_range);
|
|
|
|
|
}
|
|
|
|
|
if (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_IP_PROTO)) {
|
|
|
|
|
nm_hash_update_val(h, obj->ip_proto);
|
|
|
|
|
nm_hash_update_valp(h, &obj->sport_range);
|
|
|
|
|
nm_hash_update_valp(h, &obj->dport_range);
|
|
|
|
|
}
|
|
|
|
|
nm_hash_update_str(h, obj->iifname);
|
|
|
|
|
nm_hash_update_str(h, obj->oifname);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nm_assert_not_reached();
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_routing_rule_cmp(const NMPlatformRoutingRule *a,
|
|
|
|
|
const NMPlatformRoutingRule *b,
|
|
|
|
|
NMPlatformRoutingRuleCmpType cmp_type)
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
gboolean cmp_full = TRUE;
|
|
|
|
|
gsize addr_size;
|
|
|
|
|
bool valid;
|
|
|
|
|
guint32 flags_mask = G_MAXUINT32;
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_SELF(a, b);
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
valid = NM_IN_SET(a->addr_family, AF_INET, AF_INET6);
|
|
|
|
|
NM_CMP_DIRECT(valid, (bool) NM_IN_SET(b->addr_family, AF_INET, AF_INET6));
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (G_UNLIKELY(!valid)) {
|
|
|
|
|
/* the address family is not one of the supported ones. That means, the
|
2020-09-28 14:50:01 +02:00
|
|
|
* instance will only compare equal to itself. */
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_DIRECT((uintptr_t) a, (uintptr_t) b);
|
|
|
|
|
nm_assert_not_reached();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
switch (cmp_type) {
|
|
|
|
|
case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID:
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
flags_mask &= ~_ROUTING_RULE_FLAGS_IGNORE;
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* fall-through */
|
|
|
|
|
case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_SEMANTICALLY:
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
cmp_full = FALSE;
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* fall-through */
|
|
|
|
|
case NM_PLATFORM_ROUTING_RULE_CMP_TYPE_FULL:
|
|
|
|
|
NM_CMP_FIELD(a, b, addr_family);
|
|
|
|
|
NM_CMP_FIELD(a, b, action);
|
|
|
|
|
NM_CMP_FIELD(a, b, priority);
|
|
|
|
|
NM_CMP_FIELD(a, b, tun_id);
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_L3MDEV)) {
|
|
|
|
|
if (cmp_full)
|
|
|
|
|
NM_CMP_FIELD(a, b, l3mdev);
|
|
|
|
|
else
|
|
|
|
|
NM_CMP_FIELD_BOOL(a, b, l3mdev);
|
|
|
|
|
}
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_FIELD(a, b, table);
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_DIRECT(a->flags & flags_mask, b->flags & flags_mask);
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_FIELD(a, b, fwmark);
|
|
|
|
|
NM_CMP_FIELD(a, b, fwmask);
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (cmp_full
|
|
|
|
|
|| (cmp_type == NM_PLATFORM_ROUTING_RULE_CMP_TYPE_SEMANTICALLY
|
|
|
|
|
&& a->action == FR_ACT_GOTO))
|
|
|
|
|
NM_CMP_FIELD(a, b, goto_target);
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_FIELD(a, b, suppress_prefixlen_inverse);
|
|
|
|
|
NM_CMP_FIELD(a, b, suppress_ifgroup_inverse);
|
|
|
|
|
NM_CMP_FIELD(a, b, tos);
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (cmp_full || a->addr_family == AF_INET)
|
|
|
|
|
NM_CMP_FIELD(a, b, flow);
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_PROTOCOL))
|
|
|
|
|
NM_CMP_FIELD(a, b, protocol);
|
2019-04-17 09:17:51 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_IP_PROTO)) {
|
|
|
|
|
NM_CMP_FIELD(a, b, ip_proto);
|
|
|
|
|
NM_CMP_FIELD(a, b, sport_range.start);
|
|
|
|
|
NM_CMP_FIELD(a, b, sport_range.end);
|
|
|
|
|
NM_CMP_FIELD(a, b, dport_range.start);
|
|
|
|
|
NM_CMP_FIELD(a, b, dport_range.end);
|
|
|
|
|
}
|
2019-04-17 09:17:51 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
addr_size = nm_utils_addr_family_to_size(a->addr_family);
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_FIELD(a, b, src_len);
|
|
|
|
|
if (cmp_full || a->src_len > 0)
|
|
|
|
|
NM_CMP_FIELD_MEMCMP_LEN(a, b, src, addr_size);
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_FIELD(a, b, dst_len);
|
|
|
|
|
if (cmp_full || a->dst_len > 0)
|
|
|
|
|
NM_CMP_FIELD_MEMCMP_LEN(a, b, dst, addr_size);
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (_routing_rule_compare(cmp_type, NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_UID_RANGE)) {
|
|
|
|
|
NM_CMP_FIELD_UNSAFE(a, b, uid_range_has);
|
|
|
|
|
if (cmp_full || a->uid_range_has) {
|
|
|
|
|
NM_CMP_FIELD(a, b, uid_range.start);
|
|
|
|
|
NM_CMP_FIELD(a, b, uid_range.end);
|
|
|
|
|
}
|
|
|
|
|
}
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_FIELD_STR(a, b, iifname);
|
|
|
|
|
NM_CMP_FIELD_STR(a, b, oifname);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_assert_not_reached();
|
|
|
|
|
return 0;
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
}
|
|
|
|
|
|
2014-04-03 11:42:00 +02:00
|
|
|
/**
|
|
|
|
|
* nm_platform_ip_address_cmp_expiry:
|
|
|
|
|
* @a: a NMPlatformIPAddress to compare
|
|
|
|
|
* @b: the other NMPlatformIPAddress to compare
|
|
|
|
|
*
|
|
|
|
|
* Compares two addresses and returns which one has a longer remaining lifetime.
|
|
|
|
|
* If both addresses have the same lifetime, look at the remaining preferred time.
|
|
|
|
|
*
|
|
|
|
|
* For comparison, only the timestamp, lifetime and preferred fields are considered.
|
|
|
|
|
* If they compare equal (== 0), their other fields were not considered.
|
|
|
|
|
*
|
|
|
|
|
* Returns: -1, 0, or 1 according to the comparison
|
|
|
|
|
**/
|
|
|
|
|
int
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_ip_address_cmp_expiry(const NMPlatformIPAddress *a, const NMPlatformIPAddress *b)
|
2014-04-03 11:42:00 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
gint64 ta = 0, tb = 0;
|
2014-04-03 11:42:00 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_CMP_SELF(a, b);
|
2014-04-03 11:42:00 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (a->lifetime == NM_PLATFORM_LIFETIME_PERMANENT || a->lifetime == 0)
|
|
|
|
|
ta = G_MAXINT64;
|
|
|
|
|
else if (a->timestamp)
|
|
|
|
|
ta = ((gint64) a->timestamp) + a->lifetime;
|
2014-04-03 11:42:00 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (b->lifetime == NM_PLATFORM_LIFETIME_PERMANENT || b->lifetime == 0)
|
|
|
|
|
tb = G_MAXINT64;
|
|
|
|
|
else if (b->timestamp)
|
|
|
|
|
tb = ((gint64) b->timestamp) + b->lifetime;
|
2014-04-03 11:42:00 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (ta == tb) {
|
|
|
|
|
/* if the lifetime is equal, compare the preferred time. */
|
|
|
|
|
ta = tb = 0;
|
2014-04-03 11:42:00 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (a->preferred == NM_PLATFORM_LIFETIME_PERMANENT
|
|
|
|
|
|| a->lifetime == 0 /* lifetime==0 means permanent! */)
|
|
|
|
|
ta = G_MAXINT64;
|
|
|
|
|
else if (a->timestamp)
|
|
|
|
|
ta = ((gint64) a->timestamp) + a->preferred;
|
2014-04-03 11:42:00 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (b->preferred == NM_PLATFORM_LIFETIME_PERMANENT || b->lifetime == 0)
|
|
|
|
|
tb = G_MAXINT64;
|
|
|
|
|
else if (b->timestamp)
|
|
|
|
|
tb = ((gint64) b->timestamp) + b->preferred;
|
2014-04-03 11:42:00 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (ta == tb)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2014-04-03 11:42:00 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return ta < tb ? -1 : 1;
|
2014-04-03 11:42:00 +02:00
|
|
|
}
|
|
|
|
|
|
2020-08-06 17:45:20 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
platform: add genl socket support for events and genl family
For generic netlink, the family-id is important. It changes when
loading/unloading a module, so we should not cache it indefinitely.
To get this right, takes some effort. For "nl80211", "nl802154"
and "wireguard", we only cache the family ID in relation to an
interface. If the module gets unloaded, the family ID also becomes
irrelevant and we need to re-fetch it the next time.
For generic families like "mptcp_pm" or "ethtool", they are commonly not
kernel modules and cannot be unloaded. So caching them would be
(probably) fine.
Still. Some generic netlink families emit notifications, and it will
be interesting to be able to handle them. Since that will be useful later,
start by doing something simple: let the generic netlink family also be
cached this way. Generic netlink will send notifications when a family gets
added/deleted, and we can use that to reliably cache the family ID.
We only care about a well-known set of generic families. Unlike libnl
(which has "struct genl_family" object to handle any family), we can hard
code the few we care about (NMPGenlFamilyType).
This adds the necessary infrastructure of NMLinuxPlatform to listen to
events on the generic netlink socket.
2022-06-21 22:01:28 +02:00
|
|
|
guint16
|
|
|
|
|
nm_platform_genl_get_family_id(NMPlatform *self, NMPGenlFamilyType family_type)
|
|
|
|
|
{
|
|
|
|
|
_CHECK_SELF(self, klass, 0);
|
|
|
|
|
|
|
|
|
|
if (!_NM_INT_NOT_NEGATIVE(family_type) || family_type >= _NMP_GENL_FAMILY_TYPE_NUM)
|
|
|
|
|
g_return_val_if_reached(0);
|
|
|
|
|
|
|
|
|
|
return klass->genl_get_family_id(self, family_type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2022-07-14 22:19:47 +02:00
|
|
|
int
|
|
|
|
|
nm_platform_mptcp_addr_update(NMPlatform *self, NMOptionBool add, const NMPlatformMptcpAddr *addr)
|
|
|
|
|
{
|
|
|
|
|
_CHECK_SELF(self, klass, -NME_BUG);
|
|
|
|
|
|
|
|
|
|
return klass->mptcp_addr_update(self, add, addr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GPtrArray *
|
|
|
|
|
nm_platform_mptcp_addrs_dump(NMPlatform *self)
|
|
|
|
|
{
|
|
|
|
|
_CHECK_SELF(self, klass, NULL);
|
|
|
|
|
|
|
|
|
|
return klass->mptcp_addrs_dump(self);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2020-08-06 17:45:20 +02:00
|
|
|
GHashTable *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_ip4_address_addr_to_hash(NMPlatform *self, int ifindex)
|
2020-08-06 17:45:20 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
const NMDedupMultiHeadEntry *head_entry;
|
|
|
|
|
NMDedupMultiIter iter;
|
2021-11-09 13:28:54 +01:00
|
|
|
const NMPObject *obj;
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPLookup lookup;
|
2021-11-09 13:28:54 +01:00
|
|
|
GHashTable *hash;
|
2020-08-06 17:45:20 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(NM_IS_PLATFORM(self), NULL);
|
|
|
|
|
g_return_val_if_fail(ifindex > 0, NULL);
|
2020-08-06 17:45:20 +02:00
|
|
|
|
2022-06-24 23:32:13 +02:00
|
|
|
nmp_lookup_init_object_by_ifindex(&lookup, NMP_OBJECT_TYPE_IP4_ADDRESS, ifindex);
|
2020-08-06 17:45:20 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
head_entry = nmp_cache_lookup(NM_PLATFORM_GET_PRIVATE(self)->cache, &lookup);
|
2020-08-06 17:45:20 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (!head_entry)
|
|
|
|
|
return NULL;
|
2020-08-06 17:45:20 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
hash = g_hash_table_new(nm_direct_hash, NULL);
|
2020-08-06 17:45:20 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
nmp_cache_iter_for_each (&iter, head_entry, &obj) {
|
|
|
|
|
const NMPlatformIP4Address *a = NMP_OBJECT_CAST_IP4_ADDRESS(obj);
|
2020-08-06 17:45:20 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_hash_table_add(hash, GUINT_TO_POINTER(a->address));
|
|
|
|
|
}
|
2020-08-06 17:45:20 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return hash;
|
2020-08-06 17:45:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2021-09-27 07:48:43 +02:00
|
|
|
NMPlatformIP4Route *
|
|
|
|
|
nm_platform_ip4_address_generate_device_route(const NMPlatformIP4Address *addr,
|
|
|
|
|
int ifindex,
|
|
|
|
|
guint32 route_table,
|
|
|
|
|
guint32 route_metric,
|
2021-11-09 13:28:54 +01:00
|
|
|
NMPlatformIP4Route *dst)
|
2021-09-27 07:48:43 +02:00
|
|
|
{
|
|
|
|
|
in_addr_t network_4;
|
|
|
|
|
|
|
|
|
|
/* When you add an IPv4 address (without "noprefixroute" flag), then kernel will
|
|
|
|
|
* automatically add a device route for the IPv4 subnet. This function generates
|
|
|
|
|
* such a route for the given address. */
|
|
|
|
|
|
|
|
|
|
nm_assert(addr);
|
|
|
|
|
nm_assert(addr->plen <= 32);
|
|
|
|
|
|
|
|
|
|
if (addr->plen == 0)
|
|
|
|
|
return 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
|
|
|
network_4 = nm_ip4_addr_clear_host_address(addr->peer_address, addr->plen);
|
2021-09-27 07:48:43 +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_ip4_addr_is_zeronet(network_4)) {
|
2021-09-27 07:48:43 +02:00
|
|
|
/* Kernel doesn't add device-routes for destinations that
|
|
|
|
|
* start with 0.x.y.z. Skip them. */
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (addr->plen == 32 && addr->address == addr->peer_address) {
|
|
|
|
|
/* Kernel doesn't add device-routes for /32 addresses unless
|
|
|
|
|
* they have a peer. */
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*dst = (NMPlatformIP4Route){
|
2023-02-28 14:29:50 +01:00
|
|
|
.ifindex = ifindex,
|
|
|
|
|
.rt_source = NM_IP_CONFIG_SOURCE_KERNEL,
|
|
|
|
|
.network = network_4,
|
|
|
|
|
.plen = addr->plen,
|
|
|
|
|
.pref_src = addr->address,
|
|
|
|
|
.table_coerced = nm_platform_route_table_coerce(route_table),
|
|
|
|
|
.metric = route_metric,
|
|
|
|
|
.scope_inv = nm_platform_route_scope_inv(NM_RT_SCOPE_LINK),
|
2021-09-27 07:48:43 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
nm_platform_ip_route_normalize(AF_INET, (NMPlatformIPRoute *) dst);
|
|
|
|
|
|
|
|
|
|
return dst;
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-24 12:28:07 +02:00
|
|
|
const char *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_signal_change_type_to_string(NMPlatformSignalChangeType change_type)
|
2014-03-07 19:04:38 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
switch (change_type) {
|
|
|
|
|
case NM_PLATFORM_SIGNAL_ADDED:
|
|
|
|
|
return "added";
|
|
|
|
|
case NM_PLATFORM_SIGNAL_CHANGED:
|
|
|
|
|
return "changed";
|
|
|
|
|
case NM_PLATFORM_SIGNAL_REMOVED:
|
|
|
|
|
return "removed";
|
|
|
|
|
default:
|
|
|
|
|
g_return_val_if_reached("UNKNOWN");
|
|
|
|
|
}
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2021-11-09 13:28:54 +01:00
|
|
|
log_link(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPObjectType obj_type,
|
|
|
|
|
int ifindex,
|
2021-11-09 13:28:54 +01:00
|
|
|
NMPlatformLink *device,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPlatformSignalChangeType change_type,
|
|
|
|
|
gpointer user_data)
|
2013-03-27 22:23:24 +01:00
|
|
|
{
|
2022-03-30 08:47:34 +02:00
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
|
|
|
|
|
2022-08-10 12:25:40 +02:00
|
|
|
if (_LOGD_ENABLED()) {
|
|
|
|
|
NMLOG_COMMON(LOGL_DEBUG,
|
|
|
|
|
device->name,
|
|
|
|
|
"signal: link %7s: %s",
|
|
|
|
|
nm_platform_signal_change_type_to_string(change_type),
|
|
|
|
|
nm_platform_link_to_string(device, sbuf, sizeof(sbuf)));
|
|
|
|
|
}
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2021-11-09 13:28:54 +01:00
|
|
|
log_ip4_address(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPObjectType obj_type,
|
|
|
|
|
int ifindex,
|
2021-11-09 13:28:54 +01:00
|
|
|
NMPlatformIP4Address *address,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPlatformSignalChangeType change_type,
|
|
|
|
|
gpointer user_data)
|
2013-03-27 22:23:24 +01:00
|
|
|
{
|
2022-03-30 08:47:34 +02:00
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_LOG3D("signal: address 4 %7s: %s",
|
|
|
|
|
nm_platform_signal_change_type_to_string(change_type),
|
2022-03-30 08:47:34 +02:00
|
|
|
nm_platform_ip4_address_to_string(address, sbuf, sizeof(sbuf)));
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2021-11-09 13:28:54 +01:00
|
|
|
log_ip6_address(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPObjectType obj_type,
|
|
|
|
|
int ifindex,
|
2021-11-09 13:28:54 +01:00
|
|
|
NMPlatformIP6Address *address,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPlatformSignalChangeType change_type,
|
|
|
|
|
gpointer user_data)
|
2013-03-27 22:23:24 +01:00
|
|
|
{
|
2022-03-30 08:47:34 +02:00
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_LOG3D("signal: address 6 %7s: %s",
|
|
|
|
|
nm_platform_signal_change_type_to_string(change_type),
|
2022-03-30 08:47:34 +02:00
|
|
|
nm_platform_ip6_address_to_string(address, sbuf, sizeof(sbuf)));
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2021-11-09 13:28:54 +01:00
|
|
|
log_ip4_route(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPObjectType obj_type,
|
|
|
|
|
int ifindex,
|
2021-11-09 13:28:54 +01:00
|
|
|
NMPlatformIP4Route *route,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPlatformSignalChangeType change_type,
|
|
|
|
|
gpointer user_data)
|
2013-03-27 22:23:24 +01:00
|
|
|
{
|
2022-03-30 08:47:34 +02:00
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_LOG3D("signal: route 4 %7s: %s",
|
|
|
|
|
nm_platform_signal_change_type_to_string(change_type),
|
2022-09-15 14:03:51 +02:00
|
|
|
nmp_object_to_string(NMP_OBJECT_UP_CAST(route),
|
|
|
|
|
NMP_OBJECT_TO_STRING_PUBLIC,
|
|
|
|
|
sbuf,
|
|
|
|
|
sizeof(sbuf)));
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2021-11-09 13:28:54 +01:00
|
|
|
log_ip6_route(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPObjectType obj_type,
|
|
|
|
|
int ifindex,
|
2021-11-09 13:28:54 +01:00
|
|
|
NMPlatformIP6Route *route,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPlatformSignalChangeType change_type,
|
|
|
|
|
gpointer user_data)
|
2013-03-27 22:23:24 +01:00
|
|
|
{
|
2022-03-30 08:47:34 +02:00
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_LOG3D("signal: route 6 %7s: %s",
|
|
|
|
|
nm_platform_signal_change_type_to_string(change_type),
|
2022-09-15 14:03:51 +02:00
|
|
|
nmp_object_to_string(NMP_OBJECT_UP_CAST(route),
|
|
|
|
|
NMP_OBJECT_TO_STRING_PUBLIC,
|
|
|
|
|
sbuf,
|
|
|
|
|
sizeof(sbuf)));
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
static void
|
2021-11-09 13:28:54 +01:00
|
|
|
log_routing_rule(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPObjectType obj_type,
|
|
|
|
|
int ifindex,
|
2021-11-09 13:28:54 +01:00
|
|
|
NMPlatformRoutingRule *routing_rule,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPlatformSignalChangeType change_type,
|
|
|
|
|
gpointer user_data)
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
{
|
2022-03-30 08:47:34 +02:00
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
/* routing rules don't have an ifindex. We probably should refactor the signals that are emitted for platform changes. */
|
|
|
|
|
_LOG3D("signal: rt-rule %7s: %s",
|
|
|
|
|
nm_platform_signal_change_type_to_string(change_type),
|
2022-03-30 08:47:34 +02:00
|
|
|
nm_platform_routing_rule_to_string(routing_rule, sbuf, sizeof(sbuf)));
|
platform: add support for routing-rule objects and cache them in platform
Add and implement NMPlatformRoutingRule types and let the platform cache
handle rules.
Rules are special in two ways:
- they don't have an ifindex. That makes them different from all other
currently existing NMPlatform* types, which have an "ifindex" field and
"implement" NMPlatformObjWithIfindex.
- they have an address family, but contrary to addresses and routes, there
is only one NMPlatformRoutingRule object to handle both address
families.
Both of these points require some special considerations.
Kernel treats routing-rules quite similar to routes. That is, kernel
allows to add different rules/routes, as long as they differ in certain
fields. These "fields" make up the identity of the rules/routes. But
in practice, it's not defined which fields contribute to the identity
of these objects. That makes using the netlink API very hard. For
example, when kernel gains support for a new attribute which
NetworkManager does not know yet, then users can add two rules/routes
that look the same to NetworkManager. That can easily result in cache
inconsistencies.
Another problem is, that older kernel versions may not yet support all
fields, which NetworkManager (and newer kernels) considers for identity.
The older kernel will not simply reject netlink messages with these unknown
keys, instead it will proceed adding the route/rule without it. That means,
the added route/rule will have a different identity than what NetworkManager
intended to add.
2019-02-14 13:08:12 +01:00
|
|
|
}
|
|
|
|
|
|
2017-11-15 20:36:35 +01:00
|
|
|
static void
|
2021-11-09 13:28:54 +01:00
|
|
|
log_qdisc(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPObjectType obj_type,
|
|
|
|
|
int ifindex,
|
2021-11-09 13:28:54 +01:00
|
|
|
NMPlatformQdisc *qdisc,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPlatformSignalChangeType change_type,
|
|
|
|
|
gpointer user_data)
|
2017-11-15 20:36:35 +01:00
|
|
|
{
|
2022-03-30 08:47:34 +02:00
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_LOG3D("signal: qdisc %7s: %s",
|
|
|
|
|
nm_platform_signal_change_type_to_string(change_type),
|
2022-03-30 08:47:34 +02:00
|
|
|
nm_platform_qdisc_to_string(qdisc, sbuf, sizeof(sbuf)));
|
2017-11-15 20:36:35 +01:00
|
|
|
}
|
|
|
|
|
|
2017-11-15 20:36:35 +01:00
|
|
|
static void
|
2021-11-09 13:28:54 +01:00
|
|
|
log_tfilter(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPObjectType obj_type,
|
|
|
|
|
int ifindex,
|
2021-11-09 13:28:54 +01:00
|
|
|
NMPlatformTfilter *tfilter,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPlatformSignalChangeType change_type,
|
|
|
|
|
gpointer user_data)
|
2017-11-15 20:36:35 +01:00
|
|
|
{
|
2022-03-30 08:47:34 +02:00
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
_LOG3D("signal: tfilter %7s: %s",
|
|
|
|
|
nm_platform_signal_change_type_to_string(change_type),
|
2022-03-30 08:47:34 +02:00
|
|
|
nm_platform_tfilter_to_string(tfilter, sbuf, sizeof(sbuf)));
|
2017-11-15 20:36:35 +01:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2013-03-27 22:23:24 +01:00
|
|
|
|
2017-06-29 13:13:54 +02:00
|
|
|
void
|
2021-11-09 13:28:54 +01:00
|
|
|
nm_platform_cache_update_emit_signal(NMPlatform *self,
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPCacheOpsType cache_op,
|
|
|
|
|
const NMPObject *obj_old,
|
|
|
|
|
const NMPObject *obj_new)
|
|
|
|
|
{
|
2022-03-30 08:47:34 +02:00
|
|
|
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
|
2020-09-28 16:03:33 +02:00
|
|
|
gboolean visible_new;
|
|
|
|
|
gboolean visible_old;
|
|
|
|
|
const NMPObject *o;
|
2021-11-09 13:28:54 +01:00
|
|
|
const NMPClass *klass;
|
2020-09-28 16:03:33 +02:00
|
|
|
int ifindex;
|
|
|
|
|
|
|
|
|
|
nm_assert(NM_IN_SET((NMPlatformSignalChangeType) cache_op,
|
|
|
|
|
NM_PLATFORM_SIGNAL_NONE,
|
|
|
|
|
NM_PLATFORM_SIGNAL_ADDED,
|
|
|
|
|
NM_PLATFORM_SIGNAL_CHANGED,
|
|
|
|
|
NM_PLATFORM_SIGNAL_REMOVED));
|
|
|
|
|
|
|
|
|
|
ASSERT_nmp_cache_ops(nm_platform_get_cache(self), cache_op, obj_old, obj_new);
|
|
|
|
|
|
|
|
|
|
NMTST_ASSERT_PLATFORM_NETNS_CURRENT(self);
|
|
|
|
|
|
|
|
|
|
switch (cache_op) {
|
|
|
|
|
case NMP_CACHE_OPS_ADDED:
|
|
|
|
|
if (!nmp_object_is_visible(obj_new))
|
|
|
|
|
return;
|
|
|
|
|
o = obj_new;
|
|
|
|
|
break;
|
|
|
|
|
case NMP_CACHE_OPS_UPDATED:
|
|
|
|
|
visible_old = nmp_object_is_visible(obj_old);
|
|
|
|
|
visible_new = nmp_object_is_visible(obj_new);
|
|
|
|
|
if (!visible_old && visible_new) {
|
|
|
|
|
o = obj_new;
|
|
|
|
|
cache_op = NMP_CACHE_OPS_ADDED;
|
|
|
|
|
} else if (visible_old && !visible_new) {
|
|
|
|
|
o = obj_old;
|
|
|
|
|
cache_op = NMP_CACHE_OPS_REMOVED;
|
|
|
|
|
} else if (!visible_new) {
|
|
|
|
|
/* it was invisible and stayed invisible. Nothing to do. */
|
|
|
|
|
return;
|
|
|
|
|
} else
|
|
|
|
|
o = obj_new;
|
|
|
|
|
break;
|
|
|
|
|
case NMP_CACHE_OPS_REMOVED:
|
|
|
|
|
if (!nmp_object_is_visible(obj_old))
|
|
|
|
|
return;
|
|
|
|
|
o = obj_old;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
nm_assert(cache_op == NMP_CACHE_OPS_UNCHANGED);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
klass = NMP_OBJECT_GET_CLASS(o);
|
|
|
|
|
|
|
|
|
|
if (klass->obj_type == NMP_OBJECT_TYPE_ROUTING_RULE)
|
|
|
|
|
ifindex = 0;
|
|
|
|
|
else
|
|
|
|
|
ifindex = NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(o)->ifindex;
|
|
|
|
|
|
|
|
|
|
if (klass->obj_type == NMP_OBJECT_TYPE_IP4_ROUTE
|
|
|
|
|
&& NM_PLATFORM_GET_PRIVATE(self)->ip4_dev_route_blacklist_gc_timeout_id
|
|
|
|
|
&& NM_IN_SET(cache_op, NMP_CACHE_OPS_ADDED, NMP_CACHE_OPS_UPDATED))
|
|
|
|
|
_ip4_dev_route_blacklist_notify_route(self, o);
|
|
|
|
|
|
|
|
|
|
_LOG3t("emit signal %s %s: %s",
|
|
|
|
|
klass->signal_type,
|
|
|
|
|
nm_platform_signal_change_type_to_string((NMPlatformSignalChangeType) cache_op),
|
2022-03-30 08:47:34 +02:00
|
|
|
nmp_object_to_string(o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf, sizeof(sbuf)));
|
2020-09-28 16:03:33 +02:00
|
|
|
|
|
|
|
|
nmp_object_ref(o);
|
|
|
|
|
g_signal_emit(self,
|
|
|
|
|
_nm_platform_signal_id_get(klass->signal_type_id),
|
|
|
|
|
0,
|
|
|
|
|
(int) klass->obj_type,
|
|
|
|
|
ifindex,
|
|
|
|
|
&o->object,
|
|
|
|
|
(int) cache_op);
|
|
|
|
|
nmp_object_unref(o);
|
2017-06-29 13:13:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2017-06-29 11:18:10 +02:00
|
|
|
NMPCache *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_get_cache(NMPlatform *self)
|
2017-06-29 11:18:10 +02:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
return NM_PLATFORM_GET_PRIVATE(self)->cache;
|
2017-06-29 11:18:10 +02:00
|
|
|
}
|
|
|
|
|
|
2016-02-19 01:06:28 +01:00
|
|
|
NMPNetns *
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_netns_get(NMPlatform *self)
|
2016-02-19 01:06:28 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
_CHECK_SELF(self, klass, NULL);
|
2016-02-19 01:06:28 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return self->_netns;
|
2016-02-19 01:06:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_netns_push(NMPlatform *self, NMPNetns **netns)
|
2016-02-19 01:06:28 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
g_return_val_if_fail(NM_IS_PLATFORM(self), FALSE);
|
2016-02-19 01:06:28 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
if (self->_netns && !nmp_netns_push(self->_netns)) {
|
|
|
|
|
NM_SET_OUT(netns, NULL);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2016-02-19 01:06:28 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
NM_SET_OUT(netns, self->_netns);
|
|
|
|
|
return TRUE;
|
2016-02-19 01:06:28 +01:00
|
|
|
}
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2016-02-19 01:06:28 +01:00
|
|
|
|
2022-09-22 13:33:17 +02:00
|
|
|
typedef struct {
|
|
|
|
|
struct in6_addr address;
|
|
|
|
|
CList lst;
|
|
|
|
|
gint64 timestamp_nsec;
|
|
|
|
|
int ifindex;
|
|
|
|
|
} IP6DadFailedAddr;
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
ip6_dadfailed_addr_free(IP6DadFailedAddr *addr)
|
|
|
|
|
{
|
|
|
|
|
c_list_unlink_stale(&addr->lst);
|
|
|
|
|
nm_g_slice_free(addr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
ip6_dadfailed_prune_old(NMPlatform *self, gint64 now_nsec)
|
|
|
|
|
{
|
|
|
|
|
NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self);
|
|
|
|
|
IP6DadFailedAddr *addr;
|
|
|
|
|
IP6DadFailedAddr *safe;
|
|
|
|
|
|
|
|
|
|
c_list_for_each_entry_safe (addr, safe, &priv->ip6_dadfailed_lst_head, lst) {
|
|
|
|
|
if (addr->timestamp_nsec + (10 * NM_UTILS_NSEC_PER_SEC) > now_nsec)
|
|
|
|
|
break;
|
|
|
|
|
ip6_dadfailed_addr_free(addr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
nm_platform_ip6_dadfailed_check(NMPlatform *self, int ifindex, const struct in6_addr *ip6)
|
|
|
|
|
{
|
|
|
|
|
NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self);
|
|
|
|
|
IP6DadFailedAddr *addr;
|
|
|
|
|
|
|
|
|
|
ip6_dadfailed_prune_old(self, nm_utils_get_monotonic_timestamp_nsec());
|
|
|
|
|
|
|
|
|
|
c_list_for_each_entry_prev (addr, &priv->ip6_dadfailed_lst_head, lst) {
|
|
|
|
|
if (addr->ifindex == ifindex && IN6_ARE_ADDR_EQUAL(&addr->address, ip6)) {
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* If an IPv6 address fails DAD and has infinite lifetime, kernel just
|
|
|
|
|
* sets the DADFAILED flag. However when the address has a finite
|
|
|
|
|
* lifetime kernel deletes it immediately and the RTM_DELLINK netlink
|
|
|
|
|
* message contains the DADFAILED flag. In the second case, we remove
|
|
|
|
|
* the address from the platform cache and there is no way for
|
|
|
|
|
* platform's clients to check whether DAD failed. To work around
|
|
|
|
|
* this, we store all deleted-with-DADFAILED addresses and provide a
|
|
|
|
|
* mechanism to access them.
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
nm_platform_ip6_dadfailed_set(NMPlatform *self,
|
|
|
|
|
int ifindex,
|
|
|
|
|
const struct in6_addr *ip6,
|
|
|
|
|
gboolean failed)
|
|
|
|
|
{
|
|
|
|
|
NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self);
|
|
|
|
|
gint64 now_nsec = nm_utils_get_monotonic_timestamp_nsec();
|
|
|
|
|
IP6DadFailedAddr *addr;
|
|
|
|
|
IP6DadFailedAddr *safe;
|
|
|
|
|
|
|
|
|
|
ip6_dadfailed_prune_old(self, now_nsec);
|
|
|
|
|
|
|
|
|
|
if (failed) {
|
|
|
|
|
addr = g_slice_new(IP6DadFailedAddr);
|
|
|
|
|
*addr = (IP6DadFailedAddr){
|
|
|
|
|
.address = *ip6,
|
|
|
|
|
.ifindex = ifindex,
|
|
|
|
|
.timestamp_nsec = now_nsec,
|
|
|
|
|
};
|
|
|
|
|
c_list_link_tail(&priv->ip6_dadfailed_lst_head, &addr->lst);
|
|
|
|
|
} else {
|
|
|
|
|
c_list_for_each_entry_safe (addr, safe, &priv->ip6_dadfailed_lst_head, lst) {
|
|
|
|
|
if (addr->ifindex == ifindex && IN6_ARE_ADDR_EQUAL(&addr->address, ip6)) {
|
|
|
|
|
ip6_dadfailed_addr_free(addr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
2019-03-04 12:51:07 +01:00
|
|
|
const _NMPlatformVTableRouteUnion nm_platform_vtable_route = {
|
2020-09-28 16:03:33 +02:00
|
|
|
.v4 =
|
|
|
|
|
{
|
|
|
|
|
.is_ip4 = TRUE,
|
|
|
|
|
.obj_type = NMP_OBJECT_TYPE_IP4_ROUTE,
|
|
|
|
|
.addr_family = AF_INET,
|
|
|
|
|
.sizeof_route = sizeof(NMPlatformIP4Route),
|
|
|
|
|
.route_cmp = (int (*)(const NMPlatformIPXRoute *a,
|
|
|
|
|
const NMPlatformIPXRoute *b,
|
|
|
|
|
NMPlatformIPRouteCmpType cmp_type)) nm_platform_ip4_route_cmp,
|
|
|
|
|
.route_to_string = (const char *(*) (const NMPlatformIPXRoute *route,
|
2021-11-09 13:28:54 +01:00
|
|
|
char *buf,
|
2020-09-28 16:03:33 +02:00
|
|
|
gsize len)) nm_platform_ip4_route_to_string,
|
|
|
|
|
},
|
|
|
|
|
.v6 =
|
|
|
|
|
{
|
|
|
|
|
.is_ip4 = FALSE,
|
|
|
|
|
.obj_type = NMP_OBJECT_TYPE_IP6_ROUTE,
|
|
|
|
|
.addr_family = AF_INET6,
|
|
|
|
|
.sizeof_route = sizeof(NMPlatformIP6Route),
|
|
|
|
|
.route_cmp = (int (*)(const NMPlatformIPXRoute *a,
|
|
|
|
|
const NMPlatformIPXRoute *b,
|
|
|
|
|
NMPlatformIPRouteCmpType cmp_type)) nm_platform_ip6_route_cmp,
|
|
|
|
|
.route_to_string = (const char *(*) (const NMPlatformIPXRoute *route,
|
2021-11-09 13:28:54 +01:00
|
|
|
char *buf,
|
2020-09-28 16:03:33 +02:00
|
|
|
gsize len)) nm_platform_ip6_route_to_string,
|
|
|
|
|
},
|
2015-03-25 11:28:19 +01:00
|
|
|
};
|
|
|
|
|
|
2016-10-02 18:22:50 +02:00
|
|
|
/*****************************************************************************/
|
2015-03-25 11:28:19 +01:00
|
|
|
|
2015-05-12 07:34:56 +02:00
|
|
|
static void
|
2020-09-28 16:03:33 +02:00
|
|
|
set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
|
|
|
|
|
{
|
2021-11-09 13:28:54 +01:00
|
|
|
NMPlatform *self = NM_PLATFORM(object);
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self);
|
|
|
|
|
|
|
|
|
|
switch (prop_id) {
|
2022-12-16 18:07:07 +01:00
|
|
|
case PROP_MULTI_IDX:
|
|
|
|
|
/* construct-only */
|
|
|
|
|
{
|
|
|
|
|
NMDedupMultiIndex *multi_idx;
|
|
|
|
|
|
|
|
|
|
multi_idx = g_value_get_pointer(value);
|
|
|
|
|
if (!multi_idx)
|
|
|
|
|
multi_idx = nm_dedup_multi_index_new();
|
|
|
|
|
else
|
|
|
|
|
multi_idx = nm_dedup_multi_index_ref(multi_idx);
|
|
|
|
|
|
|
|
|
|
priv->multi_idx = multi_idx;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-09-28 16:03:33 +02:00
|
|
|
case PROP_NETNS_SUPPORT:
|
|
|
|
|
/* construct-only */
|
|
|
|
|
if (g_value_get_boolean(value)) {
|
|
|
|
|
NMPNetns *netns;
|
|
|
|
|
|
|
|
|
|
netns = nmp_netns_get_current();
|
|
|
|
|
if (netns)
|
|
|
|
|
self->_netns = g_object_ref(netns);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case PROP_USE_UDEV:
|
|
|
|
|
/* construct-only */
|
|
|
|
|
priv->use_udev = g_value_get_boolean(value);
|
|
|
|
|
break;
|
|
|
|
|
case PROP_LOG_WITH_PTR:
|
|
|
|
|
/* construct-only */
|
|
|
|
|
priv->log_with_ptr = g_value_get_boolean(value);
|
|
|
|
|
break;
|
2021-09-17 17:32:57 +02:00
|
|
|
case PROP_CACHE_TC:
|
|
|
|
|
/* construct-only */
|
|
|
|
|
priv->cache_tc = g_value_get_boolean(value);
|
|
|
|
|
break;
|
2020-09-28 16:03:33 +02:00
|
|
|
default:
|
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2015-05-12 07:34:56 +02:00
|
|
|
}
|
|
|
|
|
|
2013-03-27 22:23:24 +01:00
|
|
|
static void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_init(NMPlatform *self)
|
2013-03-27 22:23:24 +01:00
|
|
|
{
|
2020-09-28 16:03:33 +02:00
|
|
|
self->_priv = G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_PLATFORM, NMPlatformPrivate);
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|
|
|
|
|
|
2017-06-29 11:18:10 +02:00
|
|
|
static GObject *
|
2020-09-28 16:03:33 +02:00
|
|
|
constructor(GType type, guint n_construct_params, GObjectConstructParam *construct_params)
|
2017-06-29 11:18:10 +02:00
|
|
|
{
|
2021-11-09 13:28:54 +01:00
|
|
|
GObject *object;
|
|
|
|
|
NMPlatform *self;
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPlatformPrivate *priv;
|
2017-06-29 11:18:10 +02:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
object = G_OBJECT_CLASS(nm_platform_parent_class)
|
|
|
|
|
->constructor(type, n_construct_params, construct_params);
|
|
|
|
|
self = NM_PLATFORM(object);
|
|
|
|
|
priv = NM_PLATFORM_GET_PRIVATE(self);
|
2017-06-29 11:18:10 +02:00
|
|
|
|
2022-12-16 18:07:07 +01:00
|
|
|
nm_assert(priv->multi_idx);
|
|
|
|
|
|
|
|
|
|
priv->cache = nmp_cache_new(priv->multi_idx, priv->use_udev);
|
2022-09-22 13:33:17 +02:00
|
|
|
c_list_init(&priv->ip6_dadfailed_lst_head);
|
2019-03-11 11:37:40 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
return object;
|
2017-06-29 11:18:10 +02:00
|
|
|
}
|
|
|
|
|
|
2016-02-19 01:06:28 +01:00
|
|
|
static void
|
2020-09-28 16:03:33 +02:00
|
|
|
finalize(GObject *object)
|
2016-02-19 01:06:28 +01:00
|
|
|
{
|
2021-11-09 13:28:54 +01:00
|
|
|
NMPlatform *self = NM_PLATFORM(object);
|
2020-09-28 16:03:33 +02:00
|
|
|
NMPlatformPrivate *priv = NM_PLATFORM_GET_PRIVATE(self);
|
2022-09-22 13:33:17 +02:00
|
|
|
IP6DadFailedAddr *addr;
|
2016-02-19 01:06:28 +01:00
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_clear_g_source(&priv->ip4_dev_route_blacklist_check_id);
|
|
|
|
|
nm_clear_g_source(&priv->ip4_dev_route_blacklist_gc_timeout_id);
|
|
|
|
|
nm_clear_pointer(&priv->ip4_dev_route_blacklist_hash, g_hash_table_unref);
|
|
|
|
|
g_clear_object(&self->_netns);
|
|
|
|
|
nm_dedup_multi_index_unref(priv->multi_idx);
|
|
|
|
|
nmp_cache_free(priv->cache);
|
2022-02-21 22:09:36 +01:00
|
|
|
|
2022-09-22 13:33:17 +02:00
|
|
|
while ((addr = c_list_first_entry(&priv->ip6_dadfailed_lst_head, IP6DadFailedAddr, lst))) {
|
|
|
|
|
ip6_dadfailed_addr_free(addr);
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-21 22:09:36 +01:00
|
|
|
G_OBJECT_CLASS(nm_platform_parent_class)->finalize(object);
|
2016-02-19 01:06:28 +01:00
|
|
|
}
|
|
|
|
|
|
2013-03-27 22:23:24 +01:00
|
|
|
static void
|
2020-09-28 16:03:33 +02:00
|
|
|
nm_platform_class_init(NMPlatformClass *platform_class)
|
|
|
|
|
{
|
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS(platform_class);
|
|
|
|
|
|
|
|
|
|
g_type_class_add_private(object_class, sizeof(NMPlatformPrivate));
|
|
|
|
|
|
|
|
|
|
object_class->constructor = constructor;
|
|
|
|
|
object_class->set_property = set_property;
|
|
|
|
|
object_class->finalize = finalize;
|
|
|
|
|
|
|
|
|
|
platform_class->wifi_set_powersave = wifi_set_powersave;
|
|
|
|
|
|
2022-12-16 18:07:07 +01:00
|
|
|
g_object_class_install_property(
|
|
|
|
|
object_class,
|
|
|
|
|
PROP_MULTI_IDX,
|
|
|
|
|
g_param_spec_pointer(NM_PLATFORM_MULTI_IDX,
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
g_object_class_install_property(
|
|
|
|
|
object_class,
|
|
|
|
|
PROP_NETNS_SUPPORT,
|
|
|
|
|
g_param_spec_boolean(NM_PLATFORM_NETNS_SUPPORT,
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
NM_PLATFORM_NETNS_SUPPORT_DEFAULT,
|
|
|
|
|
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
|
|
|
|
|
|
|
|
|
g_object_class_install_property(
|
|
|
|
|
object_class,
|
|
|
|
|
PROP_USE_UDEV,
|
|
|
|
|
g_param_spec_boolean(NM_PLATFORM_USE_UDEV,
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
FALSE,
|
|
|
|
|
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
|
|
|
|
|
|
|
|
|
g_object_class_install_property(
|
|
|
|
|
object_class,
|
|
|
|
|
PROP_LOG_WITH_PTR,
|
|
|
|
|
g_param_spec_boolean(NM_PLATFORM_LOG_WITH_PTR,
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
TRUE,
|
|
|
|
|
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
|
|
|
|
|
2021-09-17 17:32:57 +02:00
|
|
|
g_object_class_install_property(
|
|
|
|
|
object_class,
|
|
|
|
|
PROP_CACHE_TC,
|
|
|
|
|
g_param_spec_boolean(NM_PLATFORM_CACHE_TC,
|
|
|
|
|
"",
|
|
|
|
|
"",
|
|
|
|
|
FALSE,
|
|
|
|
|
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
|
|
|
|
|
2020-09-28 16:03:33 +02:00
|
|
|
#define SIGNAL(signal, signal_id, method) \
|
|
|
|
|
G_STMT_START \
|
|
|
|
|
{ \
|
|
|
|
|
signals[signal] = \
|
|
|
|
|
g_signal_new_class_handler("" signal_id "", \
|
|
|
|
|
G_OBJECT_CLASS_TYPE(object_class), \
|
|
|
|
|
G_SIGNAL_RUN_FIRST, \
|
|
|
|
|
G_CALLBACK(method), \
|
|
|
|
|
NULL, \
|
|
|
|
|
NULL, \
|
|
|
|
|
NULL, \
|
|
|
|
|
G_TYPE_NONE, \
|
|
|
|
|
4, \
|
|
|
|
|
G_TYPE_INT, /* (int) NMPObjectType */ \
|
|
|
|
|
G_TYPE_INT, /* ifindex */ \
|
|
|
|
|
G_TYPE_POINTER /* const NMPObject * */, \
|
|
|
|
|
G_TYPE_INT /* (int) NMPlatformSignalChangeType */ \
|
|
|
|
|
); \
|
|
|
|
|
} \
|
|
|
|
|
G_STMT_END
|
|
|
|
|
|
|
|
|
|
/* Signals */
|
|
|
|
|
SIGNAL(NM_PLATFORM_SIGNAL_ID_LINK, NM_PLATFORM_SIGNAL_LINK_CHANGED, log_link);
|
|
|
|
|
SIGNAL(NM_PLATFORM_SIGNAL_ID_IP4_ADDRESS,
|
|
|
|
|
NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED,
|
|
|
|
|
log_ip4_address);
|
|
|
|
|
SIGNAL(NM_PLATFORM_SIGNAL_ID_IP6_ADDRESS,
|
|
|
|
|
NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED,
|
|
|
|
|
log_ip6_address);
|
|
|
|
|
SIGNAL(NM_PLATFORM_SIGNAL_ID_IP4_ROUTE, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, log_ip4_route);
|
|
|
|
|
SIGNAL(NM_PLATFORM_SIGNAL_ID_IP6_ROUTE, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, log_ip6_route);
|
|
|
|
|
SIGNAL(NM_PLATFORM_SIGNAL_ID_ROUTING_RULE,
|
|
|
|
|
NM_PLATFORM_SIGNAL_ROUTING_RULE_CHANGED,
|
|
|
|
|
log_routing_rule);
|
|
|
|
|
SIGNAL(NM_PLATFORM_SIGNAL_ID_QDISC, NM_PLATFORM_SIGNAL_QDISC_CHANGED, log_qdisc);
|
|
|
|
|
SIGNAL(NM_PLATFORM_SIGNAL_ID_TFILTER, NM_PLATFORM_SIGNAL_TFILTER_CHANGED, log_tfilter);
|
2013-03-27 22:23:24 +01:00
|
|
|
}
|