Fix DHCP release on bridge among others

Resolves: RHEL-157393 RHEL-247438 RHEL-247440
This commit is contained in:
Rahul Rajesh 2026-08-24 11:20:33 -04:00
parent 22541787fd
commit 26c7ed0b73
5 changed files with 294 additions and 1 deletions

View File

@ -0,0 +1,46 @@
From 0dae9a3bb499e9c2334ed11dc04fe291e9114da1 Mon Sep 17 00:00:00 2001
From: Rahul Rajesh <rajeshrah22@gmail.com>
Date: Mon, 20 Apr 2026 16:23:20 -0400
Subject: [PATCH 1004/1007] device: cleanup DHCP before devices removed
Add _dev_ipdhcpx_cleanup in __set_state_full in DEACTIVATING STATE
before STATE_CHANGED signal is emitted to ensure DHCP RELEASE
packet is sent.
Assisted-by: Cursor with Claude Opus 4.5
(cherry picked from commit 09784fcce3ce4afb4b9d1f8c7352406156bcf6c2)
(cherry picked from commit 755ad4a80276f6e0407e4d3f8025cf604398eb53)
---
src/core/devices/nm-device.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
index a103652abc..0d7100a08e 100644
--- a/src/core/devices/nm-device.c
+++ b/src/core/devices/nm-device.c
@@ -17932,6 +17932,14 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason,
nm_device_cleanup(self, reason, CLEANUP_TYPE_DECONFIGURE);
}
break;
+ case NM_DEVICE_STATE_DEACTIVATING:
+ /* When deactivating, certain devices are removed/disconnected after the
+ * STATE_CHANGED signal is sent and before the DHCP release packet
+ * can be sent. To ensure the release packet is sent, we cleanup DHCP
+ * before the signal is emitted*/
+ _dev_ipdhcpx_cleanup(self, AF_INET, TRUE, FALSE);
+ _dev_ipdhcpx_cleanup(self, AF_INET6, TRUE, FALSE);
+ break;
case NM_DEVICE_STATE_DISCONNECTED:
if (old_state > NM_DEVICE_STATE_DISCONNECTED) {
/* Ensure devices that previously assumed a connection now have
@@ -17981,6 +17989,7 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason,
(guint32) state,
(guint32) old_state,
(guint32) reason);
+
g_signal_emit(self,
signals[STATE_CHANGED],
0,
--
2.54.0

View File

@ -0,0 +1,72 @@
From 913d4ca8ba18f015e7bcfe8a1ffdc91b6d971897 Mon Sep 17 00:00:00 2001
From: Gris Ge <fge@redhat.com>
Date: Thu, 19 Mar 2026 15:42:47 +0800
Subject: [PATCH 1005/1007] manager: Ensure DHCP interface delete first when
daemon stop
Given linux bridge/bond holds DHCP config with
`ipv4.dhcp-send-release: ture` or `ipv6.dhcp-send-release: true`,
when stopping NetworkManager daemon, then NM daemon might
remove/deactivate physical interface first causing DHCP release packet
cannot be delivered.
To fix the issue, we sort the device deletion to let software device
that holds DHCP config to remove first.
Merge Request: https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2379
Co-authored-by: Rahul Rajesh <rajeshrah22@gmail.com>
(cherry picked from commit 1747eb96d6f3285b1cc2b4ec2b1be7ef7b35c1c4)
(cherry picked from commit 3285528757425f3c4c352713c8b66b57bfdf085b)
---
src/core/nm-manager.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c
index 87dde2c3af..ada26de1bd 100644
--- a/src/core/nm-manager.c
+++ b/src/core/nm-manager.c
@@ -8146,6 +8146,27 @@ nm_manager_start(NMManager *self, GError **error)
return TRUE;
}
+static int
+compare_device_remove_order(const CList *a, const CList *b, const void *user_data)
+{
+ NMDevice *dev_a = c_list_entry(a, NMDevice, devices_lst);
+ NMDevice *dev_b = c_list_entry(b, NMDevice, devices_lst);
+
+ gboolean a_has_dhcp =
+ nm_device_get_dhcp_config(dev_a, AF_INET) || nm_device_get_dhcp_config(dev_a, AF_INET6);
+ gboolean b_has_dhcp =
+ nm_device_get_dhcp_config(dev_b, AF_INET) || nm_device_get_dhcp_config(dev_b, AF_INET6);
+ gboolean a_is_software = nm_device_is_software(dev_a);
+ gboolean b_is_software = nm_device_is_software(dev_b);
+
+ /* priority: software AND dhcp first, then dhcp only
+ * then everything else,*/
+ uint a_score = a_has_dhcp ? (a_is_software ? 2 : 1) : 0;
+ uint b_score = b_has_dhcp ? (b_is_software ? 2 : 1) : 0;
+
+ return b_score - a_score;
+}
+
void
nm_manager_stop(NMManager *self)
{
@@ -8167,6 +8188,12 @@ nm_manager_stop(NMManager *self)
nm_dbus_manager_stop(nm_dbus_object_get_manager(NM_DBUS_OBJECT(self)));
+ /* When OVS internal interface or linux bridge holds DHCP, if we delete its
+ * physical interface first, then we cannot send out DHCP release request
+ * anymore. To fix that, we need to remove/deactivate software interfaces that
+ * holds DHCP config first.
+ */
+ c_list_sort(&priv->devices_lst_head, compare_device_remove_order, NULL);
while ((device = c_list_first_entry(&priv->devices_lst_head, NMDevice, devices_lst)))
remove_device(self, device, TRUE);
--
2.54.0

View File

@ -0,0 +1,102 @@
From fec27aaf7c7a8e1891eb92c10e899765b6bec951 Mon Sep 17 00:00:00 2001
From: Rahul Rajesh <rajeshrah22@gmail.com>
Date: Thu, 19 Mar 2026 11:41:37 -0400
Subject: [PATCH 1006/1007] core: use GDir to avoid libgvfs loading
Replace GFile with GDir to avoid libgvfs and other DBus infra
initialization.
This was done mainly to avoid heavy initialization just for executing
NetworkManager --print-config command.
Resolves: https://redhat.atlassian.net/browse/RHEL-140113
(cherry picked from commit 2e1ee043a797cab9b6a6ba92be02c4923acd6b35)
(cherry picked from commit 1cafab5b6bed8f26a1fb1cda9fac50157c3e6414)
---
src/core/nm-config.c | 34 ++++++++++++----------------------
1 file changed, 12 insertions(+), 22 deletions(-)
diff --git a/src/core/nm-config.c b/src/core/nm-config.c
index d8bf2e3ed7..c47c7c5280 100644
--- a/src/core/nm-config.c
+++ b/src/core/nm-config.c
@@ -1256,34 +1256,28 @@ read_base_config(GKeyFile *keyfile,
return TRUE;
}
+/* We want to use GDir instead of GFile here to avoid loading GVFS modules and
+ * initalizing DBUS infra for communicating with GVFS.
+ * https://redhat.atlassian.net/browse/RHEL-140113
+ */
static GPtrArray *
_get_config_dir_files(const char *config_dir)
{
- GFile *dir;
- GFileEnumerator *direnum;
- GFileInfo *info;
- GPtrArray *confs;
- const char *name;
-
+ GDir *dir;
+ GPtrArray *confs;
+ const char *name;
g_return_val_if_fail(config_dir, NULL);
-
confs = g_ptr_array_new_with_free_func(g_free);
if (!*config_dir)
return confs;
-
- dir = g_file_new_for_path(config_dir);
- direnum = g_file_enumerate_children(dir, G_FILE_ATTRIBUTE_STANDARD_NAME, 0, NULL, NULL);
- if (direnum) {
- while ((info = g_file_enumerator_next_file(direnum, NULL, NULL))) {
- name = g_file_info_get_name(info);
+ dir = g_dir_open(config_dir, 0, NULL);
+ if (dir) {
+ while ((name = g_dir_read_name(dir))) {
if (NM_STR_HAS_SUFFIX(name, ".conf"))
g_ptr_array_add(confs, g_strdup(name));
- g_object_unref(info);
}
- g_object_unref(direnum);
+ g_dir_close(dir);
}
- g_object_unref(dir);
-
g_ptr_array_sort(confs, nm_strcmp_p);
return confs;
}
@@ -1339,8 +1333,7 @@ read_entire_config(const NMConfigCmdLineOptions *cli,
run_config_dir = RUN_CONFIG_DIR;
/* create a default configuration file. */
- keyfile = nm_config_create_keyfile();
-
+ keyfile = nm_config_create_keyfile();
system_confs = _get_config_dir_files(system_config_dir);
confs = _get_config_dir_files(config_dir);
run_confs = _get_config_dir_files(run_config_dir);
@@ -3292,7 +3285,6 @@ init_sync(GInitable *initable, GCancellable *cancellable, GError **error)
g_set_error(error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND, "unspecified error");
g_return_val_if_reached(FALSE);
}
-
s = priv->cli.config_dir ?: "" DEFAULT_CONFIG_DIR;
priv->config_dir = g_strdup(s[0] == '/' ? s : "");
@@ -3300,12 +3292,10 @@ init_sync(GInitable *initable, GCancellable *cancellable, GError **error)
if (s[0] != '/' || nm_streq(s, priv->config_dir))
s = "";
priv->system_config_dir = g_strdup(s);
-
if (priv->cli.intern_config_file)
priv->intern_config_file = g_strdup(priv->cli.intern_config_file);
else
priv->intern_config_file = g_strdup(DEFAULT_INTERN_CONFIG_FILE);
-
warnings = g_ptr_array_new_with_free_func(g_free);
keyfile = read_entire_config(&priv->cli,
--
2.54.0

View File

@ -0,0 +1,64 @@
From cfc8ba399552b51adfa3cea6962960e20e3545e6 Mon Sep 17 00:00:00 2001
From: Josephine Pfeiffer <josie@redhat.com>
Date: Wed, 17 Jun 2026 10:25:09 +0200
Subject: [PATCH 1007/1007] device: refresh L3 merge flags on reapply for
non-restarted sources
Setting ipv6.ignore-auto-dns=yes (or ignore-auto-routes, never-default) and
running reapply did not take effect: DHCPv6-provided DNS persisted until a
full connection down/up.
On reapply, check_and_reapply_connection() invalidates the per-device
merge-flags cache, but the flags only reach NML3Cfg when an l3cd is
re-registered via nm_l3cfg_add_config(). DHCPv4 restarts from stage3 and
re-registers its l3cd, so IPv4 worked. DHCPv6 does not restart when the NDisc
DHCP level is unchanged (_dev_ipdhcp6_set_dhcp_level() early-returns), so its
l3cd kept stale merge flags and the cached lease's DNS was merged in.
Re-register the active l3cds during reapply so refreshed merge flags reach
l3cfg for sources that are not restarted. nm_l3cfg_add_config() is an upsert
that only updates merge flags on the existing entry; addresses are unchanged,
so no address/route flap or re-ACD occurs.
(cherry picked from commit b4ff1df28696d344f8f0c3d2d3d9f63781807939)
(cherry picked from commit 64b4e80001311923258610dafd440dc738d2a348)
---
NEWS | 4 ++++
src/core/devices/nm-device.c | 6 ++++++
2 files changed, 10 insertions(+)
diff --git a/NEWS b/NEWS
index 112d76839b..d7abdcffd5 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,10 @@ Overview of changes since NetworkManager-1.54.3
* Allow persisting the managed state across reboots from nmcli and the D-Bus API.
* Allow changing the device's administrative state in the kernel at the same
time as a change to the managed state from nmcli and the D-Bus API.
+* Fix reapply not honoring the ipv6.ignore-auto-dns, ipv6.ignore-auto-routes
+ and ipv6.never-default properties when DHCPv6 was not restarted (for example
+ when the IPv6 DNS came from a DHCPv6 lease), so that DHCPv6-provided DNS and
+ routes are now correctly suppressed on reapply without a connection restart.
===============================================
NetworkManager-1.54.3
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
index 0d7100a08e..1eb68bf988 100644
--- a/src/core/devices/nm-device.c
+++ b/src/core/devices/nm-device.c
@@ -14557,6 +14557,12 @@ check_and_reapply_connection(NMDevice *self,
reactivate_proxy_config(self);
+ /* Reapply may have changed the per-device L3 merge flags (ignore-auto-dns,
+ * ignore-auto-routes, never-default). Re-register the active l3cds so the
+ * refreshed flags reach l3cfg even for sources that are not restarted on
+ * reapply (e.g. DHCPv6 when the NDisc DHCP level is unchanged). */
+ _dev_l3_register_l3cds(self, priv->l3cfg, TRUE, FALSE);
+
nm_device_l3cfg_commit(
self,
NM_FLAGS_HAS(reapply_flags, NM_DEVICE_REAPPLY_FLAGS_PRESERVE_EXTERNAL_IP)
--
2.54.0

View File

@ -7,7 +7,7 @@
%global real_version 1.54.4
%global git_tag_version 1.54.4
%global rpm_version %{real_version}
%global release_version 2
%global release_version 3
%global snapshot %{nil}
%global git_sha %{nil}
%global bcond_default_debug 0
@ -193,6 +193,10 @@ Patch0001: 0001-revert-change-default-value-for-ipv4.dad-timeout-from-0-to-200ms
Patch1001: 1001-The-valid-range-of-arp_missed_max-according-to-the-k.patch
Patch1002: 1002-libnm-sd-shared-reject-urls-containing-unexpected-ch.patch
Patch1003: 1003-dhcp-dhclient-validate-hostname-before-pasting-it-in.patch
Patch1004: 1004-device-cleanup-DHCP-before-devices-removed.patch
Patch1005: 1005-manager-Ensure-DHCP-interface-delete-first-when-daem.patch
Patch1006: 1006-core-use-GDir-to-avoid-libgvfs-loading.patch
Patch1007: 1007-device-refresh-L3-merge-flags-on-reapply-for-non-res.patch
Requires(post): systemd
Requires(post): systemd-udev
@ -1090,6 +1094,11 @@ fi
%changelog
* Mon Aug 24 2026 Rahul Rajesh <rrajesh@redhat.com> - 1:1.54.4-3
- Fix DHCP release on OVS bridge interface (RHEL-157393)
- Fix avc error on print-config (RHEL-247438)
- Fix ipv6.ignore-auto-dns=yes fails to suppress DHCPv6 DNS after reapply (RHEL-247440)
* Thu Jul 2 2026 Ján Václav <jvaclav@redhat.com> - 1:1.54.4-2
- Fix CVE-2026-10805 (RHEL-191626)