Compare commits
No commits in common. 'c9' and 'i9-beta' have entirely different histories.
@ -1 +1 @@
|
||||
6423adef5f4bb2c0cc20c2173e03a7ac8b8565ca SOURCES/NetworkManager-1.48.10.tar.xz
|
||||
6423adef5f4bb2c0cc20c2173e03a7ac8b8565ca SOURCES/NetworkManager-1.48.10.tar.xz
|
||||
|
@ -1,74 +0,0 @@
|
||||
From d9dd0aeff8ba2e1a0005c2e5751907c453927c5c Mon Sep 17 00:00:00 2001
|
||||
From: Gris Ge <fge@redhat.com>
|
||||
Date: Mon, 21 Oct 2024 21:13:29 +0800
|
||||
Subject: [PATCH] sriov: only valid sriov capacity when enabled
|
||||
|
||||
NetworkManager current code will refuse to activate a connection if its
|
||||
interface has no SRIOV capacity but holding a empty SRIOV settings.
|
||||
|
||||
This patch only valid SRIOV capacity when it is enabled(total_vfs > 0).
|
||||
|
||||
Resolves: https://issues.redhat.com/browse/RHEL-58397
|
||||
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
(cherry picked from commit 421ccf8b4cb85c96db3bf1cb6a860e41a784c950)
|
||||
(cherry picked from commit c9e31e70cbf62c65cec460dc198712a61351e9f4)
|
||||
(cherry picked from commit 90a3b014683c3c98c9fb4bbe2add65510e7f1b31)
|
||||
---
|
||||
src/core/devices/nm-device.c | 19 ++++++++++---------
|
||||
1 file changed, 10 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
|
||||
index 4780003a0a..e86c32a902 100644
|
||||
--- a/src/core/devices/nm-device.c
|
||||
+++ b/src/core/devices/nm-device.c
|
||||
@@ -9468,6 +9468,7 @@ check_connection_compatible(NMDevice *self,
|
||||
NMSettingMatch *s_match;
|
||||
const GSList *specs;
|
||||
gboolean has_match = FALSE;
|
||||
+ NMSettingSriov *s_sriov = NULL;
|
||||
|
||||
klass = NM_DEVICE_GET_CLASS(self);
|
||||
if (klass->connection_type_check_compatible) {
|
||||
@@ -9485,12 +9486,14 @@ check_connection_compatible(NMDevice *self,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
- if (!nm_device_has_capability(self, NM_DEVICE_CAP_SRIOV)
|
||||
- && nm_connection_get_setting(connection, NM_TYPE_SETTING_SRIOV)) {
|
||||
- nm_utils_error_set_literal(error,
|
||||
- NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
|
||||
- "device does not support SR-IOV");
|
||||
- return FALSE;
|
||||
+ if (!nm_device_has_capability(self, NM_DEVICE_CAP_SRIOV)) {
|
||||
+ s_sriov = (NMSettingSriov *) nm_connection_get_setting(connection, NM_TYPE_SETTING_SRIOV);
|
||||
+ if (s_sriov && nm_setting_sriov_get_total_vfs(s_sriov)) {
|
||||
+ nm_utils_error_set_literal(error,
|
||||
+ NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
|
||||
+ "device does not support SR-IOV");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
}
|
||||
|
||||
conn_iface = nm_manager_get_connection_iface(NM_MANAGER_GET, connection, NULL, NULL, &local);
|
||||
@@ -10101,7 +10104,7 @@ activate_stage1_device_prepare(NMDevice *self)
|
||||
s_sriov = nm_device_get_applied_setting(self, NM_TYPE_SETTING_SRIOV);
|
||||
}
|
||||
|
||||
- if (s_sriov) {
|
||||
+ if (s_sriov && nm_device_has_capability(self, NM_DEVICE_CAP_SRIOV)) {
|
||||
nm_auto_freev NMPlatformVF **plat_vfs = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
NMSriovVF *vf;
|
||||
@@ -10109,8 +10112,6 @@ activate_stage1_device_prepare(NMDevice *self)
|
||||
guint num;
|
||||
guint i;
|
||||
|
||||
- nm_assert(nm_device_has_capability(self, NM_DEVICE_CAP_SRIOV));
|
||||
-
|
||||
autoprobe = nm_setting_sriov_get_autoprobe_drivers(s_sriov);
|
||||
if (autoprobe == NM_TERNARY_DEFAULT) {
|
||||
autoprobe = nm_config_data_get_connection_default_int64(
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,136 +0,0 @@
|
||||
From 3b1181dc02172033d8e2bb7fd2336b2ea0355a87 Mon Sep 17 00:00:00 2001
|
||||
From: Beniamino Galvani <bgalvani@redhat.com>
|
||||
Date: Mon, 23 Sep 2024 17:28:03 +0200
|
||||
Subject: [PATCH] device: fix bug when deactivating port connections
|
||||
asynchronously
|
||||
|
||||
When the attach_port()/detach_port() methods do not return immediately
|
||||
(currently, only for OVS ports), the following situation can arise:
|
||||
|
||||
- nm_device_controller_attach_port() starts the attachment by sending
|
||||
the command to ovsdb. Note that here we don't set
|
||||
`PortInfo->port_is_attached` to TRUE yet; that happens only after
|
||||
the asynchronous command returns;
|
||||
|
||||
- the activation of the port gets interrupted because the connection
|
||||
is deleted;
|
||||
|
||||
- the port device enters the deactivating state, triggering function
|
||||
port_state_changed()
|
||||
|
||||
- the function calls nm_device_controller_release_port() which checks
|
||||
whether the port is already attached; since
|
||||
`PortInfo->port_is_attached` is not set yet, it assumes the port
|
||||
doesn't need to be detached;
|
||||
|
||||
- in the meantime, the ovsdb operation succeeds. As a consequence,
|
||||
the kernel link is created even if the connection no longer exists.
|
||||
|
||||
Fix this by turning `port_is_attached` into a tri-state variable that
|
||||
also tracks when the port is attaching. When it is, we need to perform
|
||||
an explicit detach during deactivation.
|
||||
|
||||
Fixes: 9fcbc6b37dec ('device: make attach_port() asynchronous')
|
||||
|
||||
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2043
|
||||
|
||||
Resolves: https://issues.redhat.com/browse/RHEL-58026
|
||||
(cherry picked from commit a8329587c8bdd53e2bc4513a4e82529727cfa5ef)
|
||||
(cherry picked from commit d809ca6db24b5145fcc1857b962afb7ae17d07a5)
|
||||
(cherry picked from commit ca6ca684b21235f706b02cee42075f2ee3cb1795)
|
||||
---
|
||||
src/core/devices/nm-device.c | 27 ++++++++++++++++++++++-----
|
||||
1 file changed, 22 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
|
||||
index e86c32a902..f9a2e7e8fe 100644
|
||||
--- a/src/core/devices/nm-device.c
|
||||
+++ b/src/core/devices/nm-device.c
|
||||
@@ -126,12 +126,18 @@ typedef enum _nm_packed {
|
||||
ADDR_METHOD_STATE_FAILED,
|
||||
} AddrMethodState;
|
||||
|
||||
+typedef enum {
|
||||
+ PORT_STATE_NOT_ATTACHED,
|
||||
+ PORT_STATE_ATTACHED,
|
||||
+ PORT_STATE_ATTACHING,
|
||||
+} PortState;
|
||||
+
|
||||
typedef struct {
|
||||
CList lst_port;
|
||||
NMDevice *port;
|
||||
GCancellable *cancellable;
|
||||
gulong watch_id;
|
||||
- bool port_is_attached;
|
||||
+ PortState port_state;
|
||||
bool configure;
|
||||
} PortInfo;
|
||||
|
||||
@@ -6693,7 +6699,7 @@ attach_port_done(NMDevice *self, NMDevice *port, gboolean success)
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
- info->port_is_attached = success;
|
||||
+ info->port_state = (success ? PORT_STATE_ATTACHED : PORT_STATE_NOT_ATTACHED);
|
||||
|
||||
nm_device_port_notify_attach_as_port(info->port, success);
|
||||
|
||||
@@ -6756,7 +6762,7 @@ nm_device_controller_attach_port(NMDevice *self, NMDevice *port, NMConnection *c
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
- if (info->port_is_attached)
|
||||
+ if (info->port_state == PORT_STATE_ATTACHED)
|
||||
success = TRUE;
|
||||
else {
|
||||
configure = (info->configure && connection != NULL);
|
||||
@@ -6765,6 +6771,7 @@ nm_device_controller_attach_port(NMDevice *self, NMDevice *port, NMConnection *c
|
||||
|
||||
nm_clear_g_cancellable(&info->cancellable);
|
||||
info->cancellable = g_cancellable_new();
|
||||
+ info->port_state = PORT_STATE_ATTACHING;
|
||||
success = NM_DEVICE_GET_CLASS(self)->attach_port(self,
|
||||
port,
|
||||
connection,
|
||||
@@ -6819,6 +6826,7 @@ nm_device_controller_release_port(NMDevice *self,
|
||||
PortInfo *info;
|
||||
gs_unref_object NMDevice *self_free = NULL;
|
||||
gs_unref_object NMDevice *port_free = NULL;
|
||||
+ const char *port_state_str;
|
||||
|
||||
g_return_if_fail(NM_DEVICE(self));
|
||||
g_return_if_fail(NM_DEVICE(port));
|
||||
@@ -6830,11 +6838,20 @@ nm_device_controller_release_port(NMDevice *self,
|
||||
|
||||
info = find_port_info(self, port);
|
||||
|
||||
+ if (info->port_state == PORT_STATE_ATTACHED)
|
||||
+ port_state_str = "(attached)";
|
||||
+ else if (info->port_state == PORT_STATE_NOT_ATTACHED)
|
||||
+ port_state_str = "(not attached)";
|
||||
+ else {
|
||||
+ nm_assert(info->port_state == PORT_STATE_ATTACHING);
|
||||
+ port_state_str = "(attaching)";
|
||||
+ }
|
||||
+
|
||||
_LOGT(LOGD_CORE,
|
||||
"controller: release one port " NM_HASH_OBFUSCATE_PTR_FMT "/%s %s%s",
|
||||
NM_HASH_OBFUSCATE_PTR(port),
|
||||
nm_device_get_iface(port),
|
||||
- !info ? "(not registered)" : (info->port_is_attached ? "(attached)" : "(not attached)"),
|
||||
+ !info ? "(not registered)" : port_state_str,
|
||||
release_type == RELEASE_PORT_TYPE_CONFIG_FORCE
|
||||
? " (force-configure)"
|
||||
: (release_type == RELEASE_PORT_TYPE_CONFIG ? " (configure)" : "(no-config)"));
|
||||
@@ -6850,7 +6867,7 @@ nm_device_controller_release_port(NMDevice *self,
|
||||
nm_clear_g_cancellable(&info->cancellable);
|
||||
|
||||
/* first, let subclasses handle the release ... */
|
||||
- if (info->port_is_attached || nm_device_sys_iface_state_is_external(port)
|
||||
+ if (info->port_state != PORT_STATE_NOT_ATTACHED || nm_device_sys_iface_state_is_external(port)
|
||||
|| release_type >= RELEASE_PORT_TYPE_CONFIG_FORCE) {
|
||||
NMTernary ret;
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,57 +0,0 @@
|
||||
From fd2768da4c3f966a215f01f09f8b5d7d534d0193 Mon Sep 17 00:00:00 2001
|
||||
From: Beniamino Galvani <bgalvani@redhat.com>
|
||||
Date: Tue, 24 Sep 2024 16:25:03 +0200
|
||||
Subject: [PATCH] libnm-core: fix validation of ovs-dpdk interface name
|
||||
|
||||
An ovs-dpdk interface doesn't have a kernel link and doesn't have the
|
||||
15-character limit on the name.
|
||||
|
||||
Fixes: 3efe070dfc7a ('libnm: validate "connection.interface-name" at one place only')
|
||||
|
||||
Resolves: https://issues.redhat.com/browse/RHEL-60233
|
||||
|
||||
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2044
|
||||
(cherry picked from commit fda05b0af085d9f7e4cc5691075dae63e7bf02a6)
|
||||
(cherry picked from commit f6e4e537757a414cc896bc1b402da8c9c9e32eaa)
|
||||
(cherry picked from commit c7035db5b43beff7ad7e91685ff17982a540d8e2)
|
||||
---
|
||||
src/libnm-core-impl/nm-setting-connection.c | 4 ++--
|
||||
src/libnm-core-impl/tests/test-general.c | 2 +-
|
||||
2 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/libnm-core-impl/nm-setting-connection.c b/src/libnm-core-impl/nm-setting-connection.c
|
||||
index b51cd46bdd..3298dce60a 100644
|
||||
--- a/src/libnm-core-impl/nm-setting-connection.c
|
||||
+++ b/src/libnm-core-impl/nm-setting-connection.c
|
||||
@@ -1379,13 +1379,13 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
|
||||
if (connection)
|
||||
goto after_interface_name;
|
||||
iface_type = NMU_IFACE_ANY;
|
||||
- } else if (NM_IN_STRSET(ovs_iface_type, "patch")) {
|
||||
+ } else if (NM_IN_STRSET(ovs_iface_type, "patch", "dpdk")) {
|
||||
/* this interface type is internal to OVS. */
|
||||
iface_type = NMU_IFACE_OVS;
|
||||
} else {
|
||||
/* This interface type also requires a netdev. We need to validate
|
||||
* for both OVS and KERNEL. */
|
||||
- nm_assert(NM_IN_STRSET(ovs_iface_type, "internal", "system", "dpdk"));
|
||||
+ nm_assert(NM_IN_STRSET(ovs_iface_type, "internal", "system"));
|
||||
iface_type = NMU_IFACE_OVS_AND_KERNEL;
|
||||
}
|
||||
} else
|
||||
diff --git a/src/libnm-core-impl/tests/test-general.c b/src/libnm-core-impl/tests/test-general.c
|
||||
index 0a39010c11..8d4ea069c5 100644
|
||||
--- a/src/libnm-core-impl/tests/test-general.c
|
||||
+++ b/src/libnm-core-impl/tests/test-general.c
|
||||
@@ -10832,7 +10832,7 @@ test_connection_ovs_ifname(gconstpointer test_data)
|
||||
/* good if bridge, port, or patch interface */
|
||||
g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, "ovs123123123123130123123", NULL);
|
||||
|
||||
- if (!ovs_iface_type || nm_streq(ovs_iface_type, "patch"))
|
||||
+ if (!ovs_iface_type || NM_IN_STRSET(ovs_iface_type, "patch", "dpdk"))
|
||||
nmtst_assert_connection_verifies(con);
|
||||
else {
|
||||
nmtst_assert_connection_unnormalizable(con,
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,541 +0,0 @@
|
||||
From 9628d71b541635047807e3344b871f701bddf77e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= <ihuguet@redhat.com>
|
||||
Date: Wed, 4 Dec 2024 14:24:38 +0100
|
||||
Subject: [PATCH 1/4] libnmc: fix bug checking VersionInfo's capabilities
|
||||
|
||||
Remove the `+ 31u` that was making that it would search for bit 1 at
|
||||
array's element 1, instead of element 0. Fixed comparison >len that
|
||||
shoudl be >=len. Fix a few typos.
|
||||
|
||||
Fixes: bc6098d44106 ('libnm: add internal nmc_client_has_{version_info_v,version_info_capability,capability}() helper')
|
||||
(cherry picked from commit 5a65170b49d38f5195da900f63710c847ce3364e)
|
||||
---
|
||||
src/libnm-client-aux-extern/nm-libnm-aux.c | 11 ++++-------
|
||||
src/libnm-client-impl/nm-client.c | 4 ++--
|
||||
2 files changed, 6 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/libnm-client-aux-extern/nm-libnm-aux.c b/src/libnm-client-aux-extern/nm-libnm-aux.c
|
||||
index 5855bc299b..77f4a19559 100644
|
||||
--- a/src/libnm-client-aux-extern/nm-libnm-aux.c
|
||||
+++ b/src/libnm-client-aux-extern/nm-libnm-aux.c
|
||||
@@ -169,14 +169,11 @@ nmc_client_has_version_info_capability(NMClient *nmc, NMVersionInfoCapability ca
|
||||
len--;
|
||||
ver++;
|
||||
|
||||
- idx = (gsize) capability;
|
||||
- if (idx >= G_MAXSIZE - 31u)
|
||||
- return FALSE;
|
||||
-
|
||||
- idx_hi = ((idx + 31u) / 32u);
|
||||
- idx_lo = (idx % 32u);
|
||||
+ idx = (gsize) capability;
|
||||
+ idx_hi = idx / 32u;
|
||||
+ idx_lo = idx % 32u;
|
||||
|
||||
- if (idx_hi > len)
|
||||
+ if (idx_hi >= len)
|
||||
return FALSE;
|
||||
|
||||
return NM_FLAGS_ANY(ver[idx_hi], (1ull << idx_lo));
|
||||
diff --git a/src/libnm-client-impl/nm-client.c b/src/libnm-client-impl/nm-client.c
|
||||
index 4ecc83899c..677f9aacab 100644
|
||||
--- a/src/libnm-client-impl/nm-client.c
|
||||
+++ b/src/libnm-client-impl/nm-client.c
|
||||
@@ -6315,7 +6315,7 @@ nm_client_get_capabilities(NMClient *client, gsize *length)
|
||||
*
|
||||
* If available, the first element in the array is NM_VERSION which
|
||||
* encodes the daemon version as "(major << 16 | minor << 8 | micro)".
|
||||
- * The following elements are a bitfield of %NMVersionInfoCapabilities
|
||||
+ * The following elements are a bitfield of %NMVersionInfoCapability
|
||||
* that indicate that the daemon supports a certain capability.
|
||||
*
|
||||
* Returns: (transfer none) (array length=length): the
|
||||
@@ -8312,7 +8312,7 @@ nm_client_class_init(NMClientClass *client_class)
|
||||
* Expose version info and capabilities of NetworkManager. If non-empty,
|
||||
* the first element is NM_VERSION, which encodes the version of the
|
||||
* daemon as "(major << 16 | minor << 8 | micro)". The following elements
|
||||
- * is a bitfields of %NMVersionInfoCapabilities. If a bit is set, then
|
||||
+ * is a bitfields of %NMVersionInfoCapability. If a bit is set, then
|
||||
* the running NetworkManager has the respective capability.
|
||||
*
|
||||
* Since: 1.42
|
||||
--
|
||||
2.47.1
|
||||
|
||||
|
||||
From 2498b7aa0b0e654d97c6ded907c20341b866af21 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= <ihuguet@redhat.com>
|
||||
Date: Wed, 27 Nov 2024 08:48:50 +0100
|
||||
Subject: [PATCH 2/4] platform: rename NM_IP_ROUTE_TABLE_SYNC_MODE_FULL ->
|
||||
ALL_EXCEPT_LOCAL
|
||||
|
||||
The difference between FULL and ALL was not obvious without reading the
|
||||
documentation. Moreover, a new mode is going to be introduced so the
|
||||
confusion could grow. Rename to a more explicit name.
|
||||
|
||||
(cherry picked from commit e1840ad5fbe4684cb8fce4a638617729969255e5)
|
||||
---
|
||||
src/libnm-platform/nm-platform.c | 4 ++--
|
||||
src/libnm-platform/nmp-base.h | 6 +++---
|
||||
2 files changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c
|
||||
index af04f29fad..ac2ecb421c 100644
|
||||
--- a/src/libnm-platform/nm-platform.c
|
||||
+++ b/src/libnm-platform/nm-platform.c
|
||||
@@ -4890,7 +4890,7 @@ nm_platform_ip_route_get_prune_list(NMPlatform *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,
|
||||
+ NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_EXCEPT_LOCAL,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE));
|
||||
|
||||
@@ -4915,7 +4915,7 @@ nm_platform_ip_route_get_prune_list(NMPlatform *self,
|
||||
if (!nm_platform_route_table_is_main(nm_platform_ip_route_get_effective_table(&rt->rx)))
|
||||
continue;
|
||||
break;
|
||||
- case NM_IP_ROUTE_TABLE_SYNC_MODE_FULL:
|
||||
+ case NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_EXCEPT_LOCAL:
|
||||
if (nm_platform_ip_route_get_effective_table(&rt->rx) == RT_TABLE_LOCAL)
|
||||
continue;
|
||||
break;
|
||||
diff --git a/src/libnm-platform/nmp-base.h b/src/libnm-platform/nmp-base.h
|
||||
index c7d487e23c..9e2e1063a1 100644
|
||||
--- a/src/libnm-platform/nmp-base.h
|
||||
+++ b/src/libnm-platform/nmp-base.h
|
||||
@@ -211,8 +211,8 @@ nmp_object_type_to_flags(NMPObjectType obj_type)
|
||||
* @NM_IP_ROUTE_TABLE_SYNC_MODE_NONE: indicate an invalid setting.
|
||||
* @NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN: only the main table is synced. For all
|
||||
* other tables, NM won't delete any extra routes.
|
||||
- * @NM_IP_ROUTE_TABLE_SYNC_MODE_FULL: NM will sync all tables, except the
|
||||
- * local table (255).
|
||||
+ * @NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_EXCEPT_LOCAL: NM will sync all tables, except
|
||||
+ * the local table (255).
|
||||
* @NM_IP_ROUTE_TABLE_SYNC_MODE_ALL: NM will sync all tables, including the
|
||||
* local table (255).
|
||||
* @NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE: NM will sync all tables (including
|
||||
@@ -222,7 +222,7 @@ nmp_object_type_to_flags(NMPObjectType obj_type)
|
||||
typedef enum {
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_NONE,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN,
|
||||
- NM_IP_ROUTE_TABLE_SYNC_MODE_FULL,
|
||||
+ NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_EXCEPT_LOCAL,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE,
|
||||
} NMIPRouteTableSyncMode;
|
||||
--
|
||||
2.47.1
|
||||
|
||||
|
||||
From f970d505e9f5cfdc6b699105e404cd06c51439ca Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= <ihuguet@redhat.com>
|
||||
Date: Wed, 27 Nov 2024 13:53:02 +0100
|
||||
Subject: [PATCH 3/4] l3cfg: remove routes added by NM on reapply
|
||||
|
||||
By default, on reapply we were only syncing the main routes table. This
|
||||
causes that routes added by NM to other tables are not removed on
|
||||
reapply. This was done to preserve routes added externally, but routes
|
||||
added by NM itself should be removed.
|
||||
|
||||
Add a new route table syncing mode "main + NM routes". This mode
|
||||
maintains the normal behaviour of syncing completely the main table,
|
||||
and for other tables removes only routes that were added by us, leaving
|
||||
the rest untouched. Use this mode by default, as this is what a user
|
||||
would expect on reapply.
|
||||
|
||||
Note: this might not work if NM is restarted between the profile being
|
||||
modified and the reapply, because NM forgets what routes were added by
|
||||
itself because of the restart. This is a rare corner case, though.
|
||||
|
||||
Use the D-Bus property "VersionInfo" to expose a capability flag
|
||||
indicating that this bug is fixed. It is the first capability that we
|
||||
expose in this way. However, it is convenient to do it this way as it's
|
||||
something that clients like nmstate needs to know, so they can decide
|
||||
whether a conn down is needed or not. It is not enough to decide that by
|
||||
version number because it might be fixed via a downstream patch in distros
|
||||
like RHEL.
|
||||
|
||||
https://issues.redhat.com/browse/RHEL-67324
|
||||
https://issues.redhat.com/browse/RHEL-66262
|
||||
|
||||
Fixes: e9c17fcc9b33 ('l3cfg: default to 'main' route table sync mode')
|
||||
(cherry picked from commit e330eb9c4a721d158641701cb48cd8094246d258)
|
||||
---
|
||||
src/core/nm-l3cfg.c | 22 ++++++-
|
||||
src/core/nm-manager.c | 29 +++++----
|
||||
src/libnm-core-public/nm-dbus-interface.h | 13 ++--
|
||||
src/libnm-platform/nm-platform.c | 78 ++++++++++++++++++++++-
|
||||
src/libnm-platform/nm-platform.h | 5 +-
|
||||
src/libnm-platform/nmp-base.h | 4 ++
|
||||
6 files changed, 127 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/src/core/nm-l3cfg.c b/src/core/nm-l3cfg.c
|
||||
index 57baeac25d..9dd8275b1f 100644
|
||||
--- a/src/core/nm-l3cfg.c
|
||||
+++ b/src/core/nm-l3cfg.c
|
||||
@@ -4997,7 +4997,7 @@ _l3_commit_one(NML3Cfg *self,
|
||||
}
|
||||
|
||||
if (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_NONE)
|
||||
- route_table_sync = NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN;
|
||||
+ route_table_sync = NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN_AND_NM_ROUTES;
|
||||
|
||||
if (any_dirty)
|
||||
_obj_states_track_prune_dirty(self, TRUE);
|
||||
@@ -5026,6 +5026,8 @@ _l3_commit_one(NML3Cfg *self,
|
||||
}
|
||||
|
||||
if (c_list_is_empty(&self->priv.p->blocked_lst_head_x[IS_IPv4])) {
|
||||
+ gs_unref_ptrarray GPtrArray *routes_old = NULL;
|
||||
+
|
||||
addresses_prune =
|
||||
nm_platform_ip_address_get_prune_list(self->priv.platform,
|
||||
addr_family,
|
||||
@@ -5033,10 +5035,26 @@ _l3_commit_one(NML3Cfg *self,
|
||||
nm_g_array_data(ipv6_temp_addrs_keep),
|
||||
nm_g_array_len(ipv6_temp_addrs_keep));
|
||||
|
||||
+ if (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN_AND_NM_ROUTES) {
|
||||
+ NMDedupMultiIter iter;
|
||||
+ const NMPObject *rt_obj;
|
||||
+
|
||||
+ routes_old = g_ptr_array_new();
|
||||
+ nm_l3_config_data_iter_obj_for_each (&iter,
|
||||
+ l3cd_old,
|
||||
+ &rt_obj,
|
||||
+ NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4))
|
||||
+ g_ptr_array_add(routes_old, (gpointer) rt_obj);
|
||||
+
|
||||
+ nm_platform_route_objs_sort(routes_old, NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY);
|
||||
+ }
|
||||
+
|
||||
routes_prune = nm_platform_ip_route_get_prune_list(self->priv.platform,
|
||||
addr_family,
|
||||
self->priv.ifindex,
|
||||
- route_table_sync);
|
||||
+ route_table_sync,
|
||||
+ routes_old);
|
||||
+
|
||||
_obj_state_zombie_lst_prune_all(self, addr_family);
|
||||
}
|
||||
} else {
|
||||
diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c
|
||||
index 0a7e7b2e4a..a673279712 100644
|
||||
--- a/src/core/nm-manager.c
|
||||
+++ b/src/core/nm-manager.c
|
||||
@@ -462,21 +462,24 @@ static GVariant *
|
||||
_version_info_get(void)
|
||||
{
|
||||
const guint32 arr[] = {
|
||||
+ /* The array contains as first element NM_VERSION, which can be
|
||||
+ * used to numerically compare the version (see also NM_ENCODE_VERSION,
|
||||
+ * nm_utils_version(), nm_encode_version() and nm_decode_version(). */
|
||||
NM_VERSION,
|
||||
- };
|
||||
|
||||
- /* The array contains as first element NM_VERSION, which can be
|
||||
- * used to numerically compare the version (see also NM_ENCODE_VERSION,
|
||||
- * nm_utils_version(), nm_encode_version() and nm_decode_version().
|
||||
- *
|
||||
- * The following elements of the array are a bitfield of capabilities.
|
||||
- * These capabilities should only depend on compile-time abilities
|
||||
- * (unlike NM_MANAGER_CAPABILITIES, NMCapability). The supported values
|
||||
- * are from NMVersionInfoCapability enum. This way to expose capabilities
|
||||
- * is more cumbersome but more efficient compared to NM_MANAGER_CAPABILITIES.
|
||||
- * As such, it is cheap to add capabilities for something, where you would
|
||||
- * avoid it as NM_MANAGER_CAPABILITIES due to the overhead.
|
||||
- */
|
||||
+ /* The following elements of the array are a bitfield of capabilities.
|
||||
+ * These capabilities should only depend on compile-time abilities
|
||||
+ * (unlike NM_MANAGER_CAPABILITIES, NMCapability). The supported values
|
||||
+ * are from NMVersionInfoCapability enum. This way to expose capabilities
|
||||
+ * is more cumbersome but more efficient compared to NM_MANAGER_CAPABILITIES.
|
||||
+ * As such, it is cheap to add capabilities for something, where you would
|
||||
+ * avoid it as NM_MANAGER_CAPABILITIES due to the overhead.
|
||||
+ *
|
||||
+ * Each of the array's elements has 32 bits. This means that capabilities
|
||||
+ * with index 0-31 goes to element #1, with index 32-63 to element #2,
|
||||
+ * with index 64-95 to element #3 and so on. */
|
||||
+ 1 << NM_VERSION_INFO_CAPABILITY_SYNC_ROUTE_WITH_TABLE,
|
||||
+ };
|
||||
|
||||
return nm_g_variant_new_au(arr, G_N_ELEMENTS(arr));
|
||||
}
|
||||
diff --git a/src/libnm-core-public/nm-dbus-interface.h b/src/libnm-core-public/nm-dbus-interface.h
|
||||
index 5eedd7da3a..9c737dbea5 100644
|
||||
--- a/src/libnm-core-public/nm-dbus-interface.h
|
||||
+++ b/src/libnm-core-public/nm-dbus-interface.h
|
||||
@@ -93,16 +93,19 @@
|
||||
|
||||
/**
|
||||
* NMVersionInfoCapability:
|
||||
- * %_NM_VERSION_INFO_CAPABILITY_UNUSED: a dummy capability. It has no meaning,
|
||||
- * don't use it.
|
||||
+ * @NM_VERSION_INFO_CAPABILITY_SYNC_ROUTE_WITH_TABLE: Contains the fix to a bug that
|
||||
+ * caused that routes in table other than main were not removed on reapply nor
|
||||
+ * on connection down.
|
||||
+ * https://issues.redhat.com/browse/RHEL-66262
|
||||
+ * https://issues.redhat.com/browse/RHEL-67324
|
||||
*
|
||||
- * Currently no enum values are defined. These capabilities are exposed
|
||||
- * on D-Bus in the "VersionInfo" bit field.
|
||||
+ * The numeric values represent the bit index of the capability. These capabilities
|
||||
+ * can be queried in the "VersionInfo" D-Bus property.
|
||||
*
|
||||
* Since: 1.42
|
||||
*/
|
||||
typedef enum {
|
||||
- _NM_VERSION_INFO_CAPABILITY_UNUSED = 0x7FFFFFFFu,
|
||||
+ NM_VERSION_INFO_CAPABILITY_SYNC_ROUTE_WITH_TABLE = 0,
|
||||
} NMVersionInfoCapability;
|
||||
|
||||
/**
|
||||
diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c
|
||||
index ac2ecb421c..6523fb8a98 100644
|
||||
--- a/src/libnm-platform/nm-platform.c
|
||||
+++ b/src/libnm-platform/nm-platform.c
|
||||
@@ -61,6 +61,8 @@ G_STATIC_ASSERT(sizeof(((NMPlatformLink *) NULL)->l_address.data) == _NM_UTILS_H
|
||||
G_STATIC_ASSERT(sizeof(((NMPlatformLink *) NULL)->l_perm_address.data) == _NM_UTILS_HWADDR_LEN_MAX);
|
||||
G_STATIC_ASSERT(sizeof(((NMPlatformLink *) NULL)->l_broadcast.data) == _NM_UTILS_HWADDR_LEN_MAX);
|
||||
|
||||
+static int _route_objs_cmp_values(gconstpointer a, gconstpointer b, gpointer user_data);
|
||||
+
|
||||
static const char *
|
||||
_nmp_link_port_data_to_string(NMPortKind port_kind,
|
||||
const NMPlatformLinkPortData *port_data,
|
||||
@@ -4872,11 +4874,24 @@ nm_platform_ip_address_get_prune_list(NMPlatform *self,
|
||||
return result;
|
||||
}
|
||||
|
||||
+static gboolean
|
||||
+_route_obj_find_bsearch(GPtrArray *sorted_routes_objs, const NMPObject *route_obj)
|
||||
+{
|
||||
+ gssize pos =
|
||||
+ nm_ptrarray_find_bsearch((gconstpointer *) sorted_routes_objs->pdata,
|
||||
+ sorted_routes_objs->len,
|
||||
+ route_obj,
|
||||
+ _route_objs_cmp_values,
|
||||
+ GINT_TO_POINTER((int) NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY));
|
||||
+ return pos >= 0;
|
||||
+}
|
||||
+
|
||||
GPtrArray *
|
||||
nm_platform_ip_route_get_prune_list(NMPlatform *self,
|
||||
int addr_family,
|
||||
int ifindex,
|
||||
- NMIPRouteTableSyncMode route_table_sync)
|
||||
+ NMIPRouteTableSyncMode route_table_sync,
|
||||
+ GPtrArray *sorted_old_routes_objs)
|
||||
{
|
||||
NMPLookup lookup;
|
||||
GPtrArray *routes_prune = NULL;
|
||||
@@ -4891,9 +4906,20 @@ nm_platform_ip_route_get_prune_list(NMPlatform *self,
|
||||
nm_assert(NM_IN_SET(route_table_sync,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_EXCEPT_LOCAL,
|
||||
+ NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN_AND_NM_ROUTES,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE));
|
||||
|
||||
+ if (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN_AND_NM_ROUTES) {
|
||||
+ nm_assert(sorted_old_routes_objs);
|
||||
+ nm_assert(nm_utils_ptrarray_is_sorted(
|
||||
+ (gconstpointer *) sorted_old_routes_objs->pdata,
|
||||
+ sorted_old_routes_objs->len,
|
||||
+ FALSE,
|
||||
+ _route_objs_cmp_values,
|
||||
+ GINT_TO_POINTER((int) NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY)));
|
||||
+ }
|
||||
+
|
||||
nmp_lookup_init_object_by_ifindex(&lookup,
|
||||
NMP_OBJECT_TYPE_IP_ROUTE(NM_IS_IPv4(addr_family)),
|
||||
ifindex);
|
||||
@@ -4915,6 +4941,11 @@ nm_platform_ip_route_get_prune_list(NMPlatform *self,
|
||||
if (!nm_platform_route_table_is_main(nm_platform_ip_route_get_effective_table(&rt->rx)))
|
||||
continue;
|
||||
break;
|
||||
+ case NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN_AND_NM_ROUTES:
|
||||
+ if (!nm_platform_route_table_is_main(nm_platform_ip_route_get_effective_table(&rt->rx))
|
||||
+ && !_route_obj_find_bsearch(sorted_old_routes_objs, obj))
|
||||
+ continue;
|
||||
+ break;
|
||||
case NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_EXCEPT_LOCAL:
|
||||
if (nm_platform_ip_route_get_effective_table(&rt->rx) == RT_TABLE_LOCAL)
|
||||
continue;
|
||||
@@ -5284,7 +5315,8 @@ nm_platform_ip_route_flush(NMPlatform *self, int addr_family, int ifindex)
|
||||
routes_prune = nm_platform_ip_route_get_prune_list(self,
|
||||
AF_INET,
|
||||
ifindex,
|
||||
- NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE);
|
||||
+ NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE,
|
||||
+ NULL);
|
||||
success &= nm_platform_ip_route_sync(self, AF_INET, ifindex, NULL, routes_prune, NULL);
|
||||
}
|
||||
if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET6)) {
|
||||
@@ -5293,7 +5325,8 @@ nm_platform_ip_route_flush(NMPlatform *self, int addr_family, int ifindex)
|
||||
routes_prune = nm_platform_ip_route_get_prune_list(self,
|
||||
AF_INET6,
|
||||
ifindex,
|
||||
- NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE);
|
||||
+ NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE,
|
||||
+ NULL);
|
||||
success &= nm_platform_ip_route_sync(self, AF_INET6, ifindex, NULL, routes_prune, NULL);
|
||||
}
|
||||
return success;
|
||||
@@ -8767,6 +8800,45 @@ nm_platform_lnk_wireguard_cmp(const NMPlatformLnkWireGuard *a, const NMPlatformL
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int
|
||||
+_route_objs_cmp_values(gconstpointer a, gconstpointer b, gpointer user_data)
|
||||
+{
|
||||
+ const NMPObject *a_obj = a;
|
||||
+ const NMPObject *b_obj = b;
|
||||
+ NMPlatformIPRouteCmpType cmp_type = GPOINTER_TO_INT(user_data);
|
||||
+
|
||||
+ nm_assert(a_obj && b_obj);
|
||||
+ nm_assert(NMP_OBJECT_CAST_IP_ROUTE(a_obj) && NMP_OBJECT_CAST_IP_ROUTE(b_obj));
|
||||
+
|
||||
+ if (NMP_OBJECT_GET_ADDR_FAMILY(a_obj) != NMP_OBJECT_GET_ADDR_FAMILY(b_obj)) {
|
||||
+ return NMP_OBJECT_GET_ADDR_FAMILY(a_obj) == AF_INET ? 1 : -1;
|
||||
+ } else if (NMP_OBJECT_GET_ADDR_FAMILY(a_obj) == AF_INET) {
|
||||
+ return nm_platform_ip4_route_cmp(NMP_OBJECT_CAST_IP4_ROUTE(a_obj),
|
||||
+ NMP_OBJECT_CAST_IP4_ROUTE(b_obj),
|
||||
+ cmp_type);
|
||||
+ } else {
|
||||
+ return nm_platform_ip6_route_cmp(NMP_OBJECT_CAST_IP6_ROUTE(a_obj),
|
||||
+ NMP_OBJECT_CAST_IP6_ROUTE(b_obj),
|
||||
+ cmp_type);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+_route_objs_cmp(gconstpointer a, gconstpointer b, gpointer user_data)
|
||||
+{
|
||||
+ nm_assert(a && b);
|
||||
+
|
||||
+ return _route_objs_cmp_values(*((const NMPObject **) a), *((const NMPObject **) b), user_data);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+nm_platform_route_objs_sort(GPtrArray *routes_objs, NMPlatformIPRouteCmpType cmp_type)
|
||||
+{
|
||||
+ nm_assert(routes_objs);
|
||||
+
|
||||
+ g_ptr_array_sort_with_data(routes_objs, _route_objs_cmp, GINT_TO_POINTER((int) cmp_type));
|
||||
+}
|
||||
+
|
||||
void
|
||||
nm_platform_ip4_rt_nexthop_hash_update(const NMPlatformIP4RtNextHop *obj,
|
||||
gboolean for_id,
|
||||
diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h
|
||||
index e33be81356..22bf0fdbec 100644
|
||||
--- a/src/libnm-platform/nm-platform.h
|
||||
+++ b/src/libnm-platform/nm-platform.h
|
||||
@@ -2389,7 +2389,8 @@ int nm_platform_ip6_route_add(NMPlatform *self, NMPNlmFlags flags, const NMPlatf
|
||||
GPtrArray *nm_platform_ip_route_get_prune_list(NMPlatform *self,
|
||||
int addr_family,
|
||||
int ifindex,
|
||||
- NMIPRouteTableSyncMode route_table_sync);
|
||||
+ NMIPRouteTableSyncMode route_table_sync,
|
||||
+ GPtrArray *old_routes_objs);
|
||||
|
||||
gboolean nm_platform_ip_route_sync(NMPlatform *self,
|
||||
int addr_family,
|
||||
@@ -2495,6 +2496,8 @@ int nm_platform_lnk_wireguard_cmp(const NMPlatformLnkWireGuard *a, const NMPlatf
|
||||
|
||||
GHashTable *nm_platform_ip4_address_addr_to_hash(NMPlatform *self, int ifindex);
|
||||
|
||||
+void nm_platform_route_objs_sort(GPtrArray *routes_objs, NMPlatformIPRouteCmpType cmp_type);
|
||||
+
|
||||
int nm_platform_ip4_route_cmp(const NMPlatformIP4Route *a,
|
||||
const NMPlatformIP4Route *b,
|
||||
NMPlatformIPRouteCmpType cmp_type);
|
||||
diff --git a/src/libnm-platform/nmp-base.h b/src/libnm-platform/nmp-base.h
|
||||
index 9e2e1063a1..3784a78e9d 100644
|
||||
--- a/src/libnm-platform/nmp-base.h
|
||||
+++ b/src/libnm-platform/nmp-base.h
|
||||
@@ -211,6 +211,9 @@ nmp_object_type_to_flags(NMPObjectType obj_type)
|
||||
* @NM_IP_ROUTE_TABLE_SYNC_MODE_NONE: indicate an invalid setting.
|
||||
* @NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN: only the main table is synced. For all
|
||||
* other tables, NM won't delete any extra routes.
|
||||
+ * @NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN_AND_NM_ROUTES: only the main table is synced,
|
||||
+ * plus individual routes in other tables added by NM, leaving routes that
|
||||
+ * were not added by NM untouched.
|
||||
* @NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_EXCEPT_LOCAL: NM will sync all tables, except
|
||||
* the local table (255).
|
||||
* @NM_IP_ROUTE_TABLE_SYNC_MODE_ALL: NM will sync all tables, including the
|
||||
@@ -222,6 +225,7 @@ nmp_object_type_to_flags(NMPObjectType obj_type)
|
||||
typedef enum {
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_NONE,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN,
|
||||
+ NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN_AND_NM_ROUTES,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_EXCEPT_LOCAL,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE,
|
||||
--
|
||||
2.47.1
|
||||
|
||||
|
||||
From 2ac691360f265d655b1e2e1caf9344ae0ec6a802 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= <ihuguet@redhat.com>
|
||||
Date: Tue, 10 Dec 2024 10:15:52 +0100
|
||||
Subject: [PATCH 4/4] l3cfg: get routes to prune from the list of routes
|
||||
configured by NM
|
||||
|
||||
We always sync routes in the main table, but routes in tables other
|
||||
than main are only pruned if were added by NM, by default. Get the list
|
||||
of routes to prune from other tables using obj_state->os_nm_configured,
|
||||
as this tracks what routes were effectively added by NM.
|
||||
|
||||
The list should be the same that the one obtained from l3cfg_old. It
|
||||
could be different if we commited the l3cfg with an NMIPRouteTableSyncMode
|
||||
of NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN, thus not deleting some routes at
|
||||
commit time. However, since the previous commit, we never do it.
|
||||
|
||||
What all this shows is that starting to use different NMIPRouteTableSyncModes
|
||||
is probably a bad idea: it will be a source of bugs of routes not being
|
||||
always synced as users expect, and the use case for them is still to be
|
||||
known.
|
||||
|
||||
(cherry picked from commit c06d130c38a4d4238e18c06f0152f8f1a6bafa7f)
|
||||
---
|
||||
src/core/nm-l3cfg.c | 20 +++++++++++---------
|
||||
1 file changed, 11 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/core/nm-l3cfg.c b/src/core/nm-l3cfg.c
|
||||
index 9dd8275b1f..f29cfa1baf 100644
|
||||
--- a/src/core/nm-l3cfg.c
|
||||
+++ b/src/core/nm-l3cfg.c
|
||||
@@ -5036,15 +5036,17 @@ _l3_commit_one(NML3Cfg *self,
|
||||
nm_g_array_len(ipv6_temp_addrs_keep));
|
||||
|
||||
if (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN_AND_NM_ROUTES) {
|
||||
- NMDedupMultiIter iter;
|
||||
- const NMPObject *rt_obj;
|
||||
-
|
||||
- routes_old = g_ptr_array_new();
|
||||
- nm_l3_config_data_iter_obj_for_each (&iter,
|
||||
- l3cd_old,
|
||||
- &rt_obj,
|
||||
- NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4))
|
||||
- g_ptr_array_add(routes_old, (gpointer) rt_obj);
|
||||
+ GHashTableIter h_iter;
|
||||
+ ObjStateData *obj_state;
|
||||
+
|
||||
+ /* Get list of all the routes that were configured by us */
|
||||
+ routes_old = g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref);
|
||||
+ g_hash_table_iter_init(&h_iter, self->priv.p->obj_state_hash);
|
||||
+ while (g_hash_table_iter_next(&h_iter, (gpointer *) &obj_state, NULL)) {
|
||||
+ if (NMP_OBJECT_GET_TYPE(obj_state->obj) == NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4)
|
||||
+ && obj_state->os_nm_configured)
|
||||
+ g_ptr_array_add(routes_old, (gpointer) nmp_object_ref(obj_state->obj));
|
||||
+ }
|
||||
|
||||
nm_platform_route_objs_sort(routes_old, NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY);
|
||||
}
|
||||
--
|
||||
2.47.1
|
||||
|
@ -1,60 +0,0 @@
|
||||
From d9addb0ded2da8b86fa4b6e1cdc4b96f83729afd Mon Sep 17 00:00:00 2001
|
||||
From: Gris Ge <fge@redhat.com>
|
||||
Date: Wed, 11 Dec 2024 22:22:59 +0800
|
||||
Subject: [PATCH 1/1] vpn: Place gateway route to table defined in
|
||||
ipvx.route-table
|
||||
|
||||
Previously, NM create direct route to gateway to main(254) route table
|
||||
regardless `ipvx.route-table` value.
|
||||
|
||||
Fixed by setting `NMPlatformIP4Route.table_any` to `TRUE`.
|
||||
|
||||
Resolves: https://issues.redhat.com/browse/RHEL-69901
|
||||
|
||||
Signed-off-by: Gris Ge <fge@redhat.com>
|
||||
(cherry picked from commit 6d06286f1db7421bef1c4dab5fada918c59daf87)
|
||||
(cherry picked from commit 29f23d3519dbb4dcffc9682fbdfb721cfc0b851c)
|
||||
(cherry picked from commit 0dc07c5ca4d32b5ea8e104cbad106da9bb5b096d)
|
||||
---
|
||||
src/core/vpn/nm-vpn-connection.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/src/core/vpn/nm-vpn-connection.c b/src/core/vpn/nm-vpn-connection.c
|
||||
index b5a7fc4c29..88c5703a69 100644
|
||||
--- a/src/core/vpn/nm-vpn-connection.c
|
||||
+++ b/src/core/vpn/nm-vpn-connection.c
|
||||
@@ -1242,6 +1242,7 @@ _parent_device_l3cd_add_gateway_route(NML3ConfigData *l3cd,
|
||||
.gateway = parent_gw.addr4,
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_VPN,
|
||||
.metric_any = TRUE,
|
||||
+ .table_any = TRUE,
|
||||
};
|
||||
} else {
|
||||
route.r6 = (NMPlatformIP6Route){
|
||||
@@ -1251,6 +1252,7 @@ _parent_device_l3cd_add_gateway_route(NML3ConfigData *l3cd,
|
||||
.gateway = parent_gw.addr6,
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_VPN,
|
||||
.metric_any = TRUE,
|
||||
+ .table_any = TRUE,
|
||||
};
|
||||
}
|
||||
nm_l3_config_data_add_route(l3cd, addr_family, NULL, &route.rx);
|
||||
@@ -1267,6 +1269,7 @@ _parent_device_l3cd_add_gateway_route(NML3ConfigData *l3cd,
|
||||
.plen = 32,
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_VPN,
|
||||
.metric_any = TRUE,
|
||||
+ .table_any = TRUE,
|
||||
};
|
||||
} else {
|
||||
route.r6 = (NMPlatformIP6Route){
|
||||
@@ -1274,6 +1277,7 @@ _parent_device_l3cd_add_gateway_route(NML3ConfigData *l3cd,
|
||||
.plen = 128,
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_VPN,
|
||||
.metric_any = TRUE,
|
||||
+ .table_any = TRUE,
|
||||
};
|
||||
}
|
||||
nm_l3_config_data_add_route(l3cd, addr_family, NULL, &route.rx);
|
||||
--
|
||||
2.45.0
|
||||
|
@ -1,238 +0,0 @@
|
||||
From 50331402dae72990a268704e4047d6c762572755 Mon Sep 17 00:00:00 2001
|
||||
From: Wen Liang <wenliang@redhat.com>
|
||||
Date: Fri, 20 Dec 2024 10:10:25 -0500
|
||||
Subject: [PATCH 1/1] vpn: fix routing rules support in vpn conenctions
|
||||
|
||||
This commit introduces the ability to manage routing rules specifically
|
||||
for VPN connections. These rules allow finer control over traffic
|
||||
routing by enabling the specification of policy-based routing for
|
||||
traffic over the VPN.
|
||||
|
||||
- Updated the connection backend to apply rules during VPN activation.
|
||||
- Ensured proper cleanup of routing rules upon VPN deactivation.
|
||||
|
||||
This enhancement improves VPN usability in scenarios requiring advanced
|
||||
routing configurations, such as split tunneling and traffic
|
||||
prioritization.
|
||||
|
||||
Resolves: https://issues.redhat.com/browse/RHEL-70160
|
||||
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2092
|
||||
https://gitlab.freedesktop.org/NetworkManager/NetworkManager-ci/-/merge_requests/1842
|
||||
(cherry picked from commit 308e34a501482d01c1cc6c87c38791ad9f34dc1f)
|
||||
(cherry picked from commit a24b347e93e37b04aa0f5698efcb462c02517c09)
|
||||
(cherry picked from commit b5c46f8a8d644e1c5a6dc07e06d5dab3338e9a91)
|
||||
---
|
||||
src/core/devices/nm-device.c | 62 +++++++++++++++++++-------------
|
||||
src/core/devices/nm-device.h | 6 ++++
|
||||
src/core/vpn/nm-vpn-connection.c | 7 +++-
|
||||
3 files changed, 50 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
|
||||
index f9a2e7e8fe..070ba46495 100644
|
||||
--- a/src/core/devices/nm-device.c
|
||||
+++ b/src/core/devices/nm-device.c
|
||||
@@ -10327,31 +10327,34 @@ lldp_setup(NMDevice *self, NMTernary enabled)
|
||||
* as externally added ones. Don't restart NetworkManager if
|
||||
* you care about that.
|
||||
*/
|
||||
-static void
|
||||
-_routing_rules_sync(NMDevice *self, NMTernary set_mode)
|
||||
+void
|
||||
+nm_routing_rules_sync(NMConnection *applied_connection,
|
||||
+ NMTernary set_mode,
|
||||
+ GPtrArray *(*get_extra_rules)(NMDevice *self),
|
||||
+ NMDevice *self,
|
||||
+ NMNetns *netns)
|
||||
{
|
||||
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
|
||||
- NMPGlobalTracker *global_tracker = nm_netns_get_global_tracker(nm_device_get_netns(self));
|
||||
- NMDeviceClass *klass = NM_DEVICE_GET_CLASS(self);
|
||||
+ NMPGlobalTracker *global_tracker = nm_netns_get_global_tracker(netns);
|
||||
gboolean untrack_only_dirty = FALSE;
|
||||
gboolean keep_deleted_rules;
|
||||
gpointer user_tag_1;
|
||||
gpointer user_tag_2;
|
||||
|
||||
- /* take two arbitrary user-tag pointers that belong to @self. */
|
||||
- user_tag_1 = &priv->v4_route_table;
|
||||
- user_tag_2 = &priv->v6_route_table;
|
||||
+ if (self) {
|
||||
+ user_tag_1 = ((guint32 *) self) + 1;
|
||||
+ user_tag_2 = ((guint32 *) self) + 2;
|
||||
+ } else {
|
||||
+ user_tag_1 = ((guint32 *) applied_connection) + 1;
|
||||
+ user_tag_2 = ((guint32 *) applied_connection) + 2;
|
||||
+ }
|
||||
|
||||
if (set_mode == NM_TERNARY_TRUE) {
|
||||
- NMConnection *applied_connection;
|
||||
NMSettingIPConfig *s_ip;
|
||||
guint i, num;
|
||||
int is_ipv4;
|
||||
|
||||
untrack_only_dirty = TRUE;
|
||||
|
||||
- applied_connection = nm_device_get_applied_connection(self);
|
||||
-
|
||||
for (is_ipv4 = 0; applied_connection && is_ipv4 < 2; is_ipv4++) {
|
||||
int addr_family = is_ipv4 ? AF_INET : AF_INET6;
|
||||
|
||||
@@ -10390,10 +10393,10 @@ _routing_rules_sync(NMDevice *self, NMTernary set_mode)
|
||||
}
|
||||
}
|
||||
|
||||
- if (klass->get_extra_rules) {
|
||||
+ if (get_extra_rules) {
|
||||
gs_unref_ptrarray GPtrArray *extra_rules = NULL;
|
||||
|
||||
- extra_rules = klass->get_extra_rules(self);
|
||||
+ extra_rules = get_extra_rules(self);
|
||||
if (extra_rules) {
|
||||
for (i = 0; i < extra_rules->len; i++) {
|
||||
nmp_global_tracker_track_rule(
|
||||
@@ -10408,7 +10411,7 @@ _routing_rules_sync(NMDevice *self, NMTernary set_mode)
|
||||
}
|
||||
|
||||
nmp_global_tracker_untrack_all(global_tracker, user_tag_1, !untrack_only_dirty, TRUE);
|
||||
- if (klass->get_extra_rules)
|
||||
+ if (get_extra_rules)
|
||||
nmp_global_tracker_untrack_all(global_tracker, user_tag_2, !untrack_only_dirty, TRUE);
|
||||
|
||||
keep_deleted_rules = FALSE;
|
||||
@@ -10468,8 +10471,8 @@ tc_commit(NMDevice *self)
|
||||
static void
|
||||
activate_stage2_device_config(NMDevice *self)
|
||||
{
|
||||
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
|
||||
- NMDeviceClass *klass;
|
||||
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
|
||||
+ NMDeviceClass *klass = NM_DEVICE_GET_CLASS(self);
|
||||
NMActStageReturn ret;
|
||||
NMSettingWired *s_wired;
|
||||
gboolean no_firmware = FALSE;
|
||||
@@ -10494,7 +10497,11 @@ activate_stage2_device_config(NMDevice *self)
|
||||
priv->tc_committed = TRUE;
|
||||
}
|
||||
|
||||
- _routing_rules_sync(self, NM_TERNARY_TRUE);
|
||||
+ nm_routing_rules_sync(nm_device_get_applied_connection(self),
|
||||
+ NM_TERNARY_TRUE,
|
||||
+ klass->get_extra_rules,
|
||||
+ self,
|
||||
+ nm_device_get_netns(self));
|
||||
|
||||
if (!nm_device_sys_iface_state_is_external_or_assume(self)) {
|
||||
if (!nm_device_bring_up_full(self, FALSE, TRUE, &no_firmware)) {
|
||||
@@ -10506,7 +10513,6 @@ activate_stage2_device_config(NMDevice *self)
|
||||
}
|
||||
}
|
||||
|
||||
- klass = NM_DEVICE_GET_CLASS(self);
|
||||
if (klass->act_stage2_config_also_for_external_or_assume
|
||||
|| !nm_device_sys_iface_state_is_external_or_assume(self)) {
|
||||
NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE;
|
||||
@@ -13881,7 +13887,11 @@ check_and_reapply_connection(NMDevice *self,
|
||||
|
||||
nm_device_activate_schedule_stage3_ip_config(self, FALSE);
|
||||
|
||||
- _routing_rules_sync(self, NM_TERNARY_TRUE);
|
||||
+ nm_routing_rules_sync(nm_device_get_applied_connection(self),
|
||||
+ NM_TERNARY_TRUE,
|
||||
+ klass->get_extra_rules,
|
||||
+ self,
|
||||
+ nm_device_get_netns(self));
|
||||
|
||||
reactivate_proxy_config(self);
|
||||
|
||||
@@ -16444,6 +16454,7 @@ static void
|
||||
nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanup_type)
|
||||
{
|
||||
NMDevicePrivate *priv;
|
||||
+ NMDeviceClass *klass = NM_DEVICE_GET_CLASS(self);
|
||||
int ifindex;
|
||||
|
||||
g_return_if_fail(NM_IS_DEVICE(self));
|
||||
@@ -16468,8 +16479,8 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu
|
||||
}
|
||||
|
||||
/* Call device type-specific deactivation */
|
||||
- if (NM_DEVICE_GET_CLASS(self)->deactivate)
|
||||
- NM_DEVICE_GET_CLASS(self)->deactivate(self);
|
||||
+ if (klass->deactivate)
|
||||
+ klass->deactivate(self);
|
||||
|
||||
ifindex = nm_device_get_ip_ifindex(self);
|
||||
|
||||
@@ -16491,8 +16502,11 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu
|
||||
|
||||
priv->tc_committed = FALSE;
|
||||
|
||||
- _routing_rules_sync(self,
|
||||
- cleanup_type == CLEANUP_TYPE_KEEP ? NM_TERNARY_DEFAULT : NM_TERNARY_FALSE);
|
||||
+ nm_routing_rules_sync(nm_device_get_applied_connection(self),
|
||||
+ cleanup_type == CLEANUP_TYPE_KEEP ? NM_TERNARY_DEFAULT : NM_TERNARY_FALSE,
|
||||
+ klass->get_extra_rules,
|
||||
+ self,
|
||||
+ nm_device_get_netns(self));
|
||||
|
||||
if (ifindex > 0)
|
||||
nm_platform_ip4_dev_route_blacklist_set(nm_device_get_platform(self), ifindex, NULL);
|
||||
@@ -16521,7 +16535,7 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu
|
||||
/* for other device states (UNAVAILABLE, DISCONNECTED), allow the
|
||||
* device to overwrite the reset behavior, so that Wi-Fi can set
|
||||
* a randomized MAC address used during scanning. */
|
||||
- NM_DEVICE_GET_CLASS(self)->deactivate_reset_hw_addr(self);
|
||||
+ klass->deactivate_reset_hw_addr(self);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/core/devices/nm-device.h b/src/core/devices/nm-device.h
|
||||
index 37eda5c0c8..c3a06c12e6 100644
|
||||
--- a/src/core/devices/nm-device.h
|
||||
+++ b/src/core/devices/nm-device.h
|
||||
@@ -848,4 +848,10 @@ void nm_device_clear_dns_lookup_data(NMDevice *self, const char *reason);
|
||||
|
||||
gboolean nm_device_get_allow_autoconnect_on_external(NMDevice *self);
|
||||
|
||||
+void nm_routing_rules_sync(NMConnection *applied_connection,
|
||||
+ NMTernary set_mode,
|
||||
+ GPtrArray *(*get_extra_rules)(NMDevice *self),
|
||||
+ NMDevice *self,
|
||||
+ NMNetns *netns);
|
||||
+
|
||||
#endif /* __NETWORKMANAGER_DEVICE_H__ */
|
||||
diff --git a/src/core/vpn/nm-vpn-connection.c b/src/core/vpn/nm-vpn-connection.c
|
||||
index 88c5703a69..c14682b8cc 100644
|
||||
--- a/src/core/vpn/nm-vpn-connection.c
|
||||
+++ b/src/core/vpn/nm-vpn-connection.c
|
||||
@@ -905,7 +905,8 @@ fw_call_cleanup(NMVpnConnection *self)
|
||||
static void
|
||||
vpn_cleanup(NMVpnConnection *self, NMDevice *parent_dev)
|
||||
{
|
||||
- const char *iface;
|
||||
+ NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE(self);
|
||||
+ const char *iface;
|
||||
|
||||
/* Remove zone from firewall */
|
||||
iface = nm_vpn_connection_get_ip_iface(self, FALSE);
|
||||
@@ -917,6 +918,8 @@ vpn_cleanup(NMVpnConnection *self, NMDevice *parent_dev)
|
||||
fw_call_cleanup(self);
|
||||
|
||||
_l3cfg_l3cd_clear_all(self);
|
||||
+
|
||||
+ nm_routing_rules_sync(_get_applied_connection(self), NM_TERNARY_FALSE, NULL, NULL, priv->netns);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2278,6 +2281,8 @@ _dbus_signal_ip_config_cb(NMVpnConnection *self, int addr_family, GVariant *dict
|
||||
|
||||
_l3cfg_l3cd_set(self, L3CD_TYPE_IP_X(IS_IPv4), l3cd);
|
||||
|
||||
+ nm_routing_rules_sync(_get_applied_connection(self), NM_TERNARY_TRUE, NULL, NULL, priv->netns);
|
||||
+
|
||||
_check_complete(self, TRUE);
|
||||
}
|
||||
|
||||
--
|
||||
2.45.0
|
||||
|
@ -0,0 +1,10 @@
|
||||
# Enable connectivity checking for NetworkManager.
|
||||
# See `man NetworkManager.conf`.
|
||||
#
|
||||
# Note that connectivity checking works badly with rp_filter set to
|
||||
# strict. Check "/proc/sys/net/ipv4/conf/*/rp_filter".
|
||||
[connectivity]
|
||||
enabled=true
|
||||
uri=http://static.inferitos.ru/test/check-networkmanager.txt
|
||||
response=OK
|
||||
interval=300
|
Loading…
Reference in new issue