From b59c804695f6353ff41d92e757d695749d537ec3 Mon Sep 17 00:00:00 2001 From: MSVSphere Packaging Team Date: Wed, 13 Sep 2023 03:00:47 +0300 Subject: [PATCH 1/6] import NetworkManager-1.42.2-8.el9_2 --- ...-IPv6-method-from-ignore-rhbz2229671.patch | 42 +++++++++ ...onnection-flags-on-updat-rhbz2229671.patch | 89 +++++++++++++++++++ SPECS/NetworkManager.spec | 10 ++- 3 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 SOURCES/1006-assume-change-IPv6-method-from-ignore-rhbz2229671.patch create mode 100644 SOURCES/1007-settings-preserve-existing-connection-flags-on-updat-rhbz2229671.patch diff --git a/SOURCES/1006-assume-change-IPv6-method-from-ignore-rhbz2229671.patch b/SOURCES/1006-assume-change-IPv6-method-from-ignore-rhbz2229671.patch new file mode 100644 index 0000000..84e562b --- /dev/null +++ b/SOURCES/1006-assume-change-IPv6-method-from-ignore-rhbz2229671.patch @@ -0,0 +1,42 @@ +From 72fc1ef4c365cfda7fc0a86afd3ce124d57e8d5c Mon Sep 17 00:00:00 2001 +From: Wen Liang +Date: Mon, 17 Jul 2023 14:09:04 -0400 +Subject: [PATCH] assume: change IPv6 method from "ignore" and "disabled" into + "auto" + +IPv6 method "disabled" and "ignore" are not supported for loopback +device, when generating the assume connection, the generated connection +will fail verification. Therefore, change the IPv6 method into "auto", +as a result, for loopback external connection, NM will not toggle the +`disable_ipv6` sysctl setting when `systemd-sysctl` sets it into 1. + +https://bugzilla.redhat.com/show_bug.cgi?id=2207878 + +https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1694 +(cherry picked from commit e8a2306afbcd3e328f62004af92cd21b2477f0ac) +(cherry picked from commit 832e8df0c17f44be2c62485c19a0b20f6d3efa07) +--- + src/core/NetworkManagerUtils.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/core/NetworkManagerUtils.c b/src/core/NetworkManagerUtils.c +index 6f4c60f876..84ee6c3a0d 100644 +--- a/src/core/NetworkManagerUtils.c ++++ b/src/core/NetworkManagerUtils.c +@@ -1748,6 +1748,13 @@ nm_utils_platform_capture_ip_setting(NMPlatform *platform, + method = maybe_ipv6_disabled ? NM_SETTING_IP6_CONFIG_METHOD_DISABLED + : NM_SETTING_IP6_CONFIG_METHOD_IGNORE; + } ++ ++ /* The IPv6 method "ignore" and "disabled" are not supported for loopback */ ++ if (ifindex == 1 ++ && NM_IN_STRSET(method, ++ NM_SETTING_IP6_CONFIG_METHOD_DISABLED, ++ NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) ++ method = NM_SETTING_IP6_CONFIG_METHOD_AUTO; + g_object_set(s_ip, NM_SETTING_IP_CONFIG_METHOD, method, NULL); + + nmp_lookup_init_object_by_ifindex(&lookup, NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4), ifindex); +-- +2.41.0 + diff --git a/SOURCES/1007-settings-preserve-existing-connection-flags-on-updat-rhbz2229671.patch b/SOURCES/1007-settings-preserve-existing-connection-flags-on-updat-rhbz2229671.patch new file mode 100644 index 0000000..8a114e9 --- /dev/null +++ b/SOURCES/1007-settings-preserve-existing-connection-flags-on-updat-rhbz2229671.patch @@ -0,0 +1,89 @@ +From 895ed1ef14c49a94fb665e519bad409adf53c80f Mon Sep 17 00:00:00 2001 +From: Beniamino Galvani +Date: Mon, 27 Feb 2023 09:10:34 +0100 +Subject: [PATCH] settings: preserve existing connection flags on update + +We are passing to the plugin only 'sett_flags', which is the bitmask +of flags to change and works together with 'sett_mask'; however, +plugins interpret that value as the new flags value. The result is +that if there is no change needed (0/0), the existing flags are lost. +Simple reproducer: + + ip link add dummy1 type dummy + ip link set dummy1 up + ip addr add dev dummy1 fd01::12/64 + sleep 1 + + # now, a external connection is created by NM + + echo "BEFORE:" + cat /run/NetworkManager/system-connections/dummy1.nmconnection | grep "nm-generated\|volatile\|external" + + # just add a new address to the interface to make it lose + # the external flag + + ip addr add dev dummy1 172.25.42.1/24 + sleep 1 + + echo "AFTER:" + cat /run/NetworkManager/system-connections/dummy1.nmconnection | grep "nm-generated\|volatile\|external" + +Output: + + BEFORE: + nm-generated=true + volatile=true + external=true + AFTER: + +Fixes: d35d3c468a30 ('settings: rework tracking settings connections and settings plugins') + +https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1548 +(cherry picked from commit 86b922695f18566132980bd23516038b6ca4c0f4) +(cherry picked from commit 4353f842303d0d905c92e8e497e22f8440261381) +--- + src/core/settings/nm-settings.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/core/settings/nm-settings.c b/src/core/settings/nm-settings.c +index 63476c3c94..9995b490d2 100644 +--- a/src/core/settings/nm-settings.c ++++ b/src/core/settings/nm-settings.c +@@ -2009,6 +2009,7 @@ nm_settings_update_connection(NMSettings *self, + const char *uuid; + gboolean tombstone_in_memory = FALSE; + gboolean tombstone_on_disk = FALSE; ++ NMSettingsConnectionIntFlags new_flags; + + g_return_val_if_fail(NM_IS_SETTINGS(self), FALSE); + g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(sett_conn), FALSE); +@@ -2228,13 +2229,16 @@ nm_settings_update_connection(NMSettings *self, + } + } + ++ new_flags = nm_settings_connection_get_flags(sett_conn); ++ new_flags = NM_FLAGS_ASSIGN_MASK(new_flags, sett_mask, sett_flags); ++ + if (!update_storage) { + success = _add_connection_to_first_plugin(self, + plugin_name, + sett_conn_entry, + connection, + new_in_memory, +- sett_flags, ++ new_flags, + new_shadowed_storage_filename, + new_shadowed_owned, + &new_storage, +@@ -2245,7 +2249,7 @@ nm_settings_update_connection(NMSettings *self, + success = _update_connection_to_plugin(self, + update_storage, + connection, +- sett_flags, ++ new_flags, + update_reason, + new_shadowed_storage_filename, + new_shadowed_owned, +-- +2.41.0 + diff --git a/SPECS/NetworkManager.spec b/SPECS/NetworkManager.spec index 0e582c8..4da7924 100644 --- a/SPECS/NetworkManager.spec +++ b/SPECS/NetworkManager.spec @@ -6,7 +6,7 @@ %global epoch_version 1 %global real_version 1.42.2 %global rpm_version %{real_version} -%global release_version 6 +%global release_version 8 %global snapshot %{nil} %global git_sha %{nil} %global bcond_default_debug 0 @@ -208,6 +208,8 @@ Patch1002: 1002-Revert-infiniband-avoid-normalizing-the-p-key-rh2209976.patch Patch1003: 1003-unblock-autoconnect-upon-reapply-rh2217903.patch Patch1004: 1004-core-fix-l3cd-comparison-rhbz2219847.patch Patch1005: 1005-firewall-create-dynamic-sets-rhbz2220952.patch +Patch1006: 1006-assume-change-IPv6-method-from-ignore-rhbz2229671.patch +Patch1007: 1007-settings-preserve-existing-connection-flags-on-updat-rhbz2229671.patch Requires(post): systemd %if 0%{?fedora} || 0%{?rhel} >= 8 @@ -1256,6 +1258,12 @@ fi %changelog +* Wed Aug 16 2023 Fernando Fernandez Mancera - 1:1.42.2-8 +- settings: preserve existing connection flags on update (rh #2229671) + +* Mon Aug 14 2023 Fernando Fernandez Mancera - 1:1.42.2-7 +- assume: change IPv6 method from "ignore" and "disabled" into "auto" (rh #2229671) + * Wed Jul 12 2023 Fernando Fernandez Mancera - 1:1.42.2-6 - firewall: create "dynamic" sets for nft rules for slb-bonding (rh #2220952) From 12ccc1f166d1207187a63e4f5049185550c1d7cc Mon Sep 17 00:00:00 2001 From: MSVSphere Packaging Team Date: Wed, 8 Nov 2023 13:44:17 +0300 Subject: [PATCH 2/6] import NetworkManager-1.44.0-3.el9 --- .NetworkManager.metadata | 2 +- .gitignore | 2 +- ...e-the-address-when-removed-rh2196441.patch | 138 ----- ...exported-on-D-Bus-in-aut-rhbz2210271.patch | 54 ++ ...void-normalizing-the-p-key-rh2209976.patch | 270 --------- ...gfault-crash-when-rollback-rhel-1526.patch | 67 +++ ...k-autoconnect-upon-reapply-rh2217903.patch | 45 -- ...core-fix-l3cd-comparison-rhbz2219847.patch | 88 --- ...wall-create-dynamic-sets-rhbz2220952.patch | 530 ------------------ ...-IPv6-method-from-ignore-rhbz2229671.patch | 42 -- ...onnection-flags-on-updat-rhbz2229671.patch | 89 --- SPECS/NetworkManager.spec | 129 +++-- 12 files changed, 214 insertions(+), 1242 deletions(-) delete mode 100644 SOURCES/1001-ipv6ll-don-t-regenerate-the-address-when-removed-rh2196441.patch create mode 100644 SOURCES/1001-nm-manager-ensure-device-is-exported-on-D-Bus-in-aut-rhbz2210271.patch delete mode 100644 SOURCES/1002-Revert-infiniband-avoid-normalizing-the-p-key-rh2209976.patch create mode 100644 SOURCES/1002-checkpoint-Fix-segfault-crash-when-rollback-rhel-1526.patch delete mode 100644 SOURCES/1003-unblock-autoconnect-upon-reapply-rh2217903.patch delete mode 100644 SOURCES/1004-core-fix-l3cd-comparison-rhbz2219847.patch delete mode 100644 SOURCES/1005-firewall-create-dynamic-sets-rhbz2220952.patch delete mode 100644 SOURCES/1006-assume-change-IPv6-method-from-ignore-rhbz2229671.patch delete mode 100644 SOURCES/1007-settings-preserve-existing-connection-flags-on-updat-rhbz2229671.patch diff --git a/.NetworkManager.metadata b/.NetworkManager.metadata index 3d5d32c..dab89c7 100644 --- a/.NetworkManager.metadata +++ b/.NetworkManager.metadata @@ -1 +1 @@ -83eaa880bb7d4d8f178e426c30d17895e117fb79 SOURCES/NetworkManager-1.42.2.tar.xz +b3d857c8fdfae1dd36d6bd833cd84a85fcf71880 SOURCES/NetworkManager-1.44.0.tar.xz diff --git a/.gitignore b/.gitignore index b799024..22242f5 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/NetworkManager-1.42.2.tar.xz +SOURCES/NetworkManager-1.44.0.tar.xz diff --git a/SOURCES/1001-ipv6ll-don-t-regenerate-the-address-when-removed-rh2196441.patch b/SOURCES/1001-ipv6ll-don-t-regenerate-the-address-when-removed-rh2196441.patch deleted file mode 100644 index 9a1bead..0000000 --- a/SOURCES/1001-ipv6ll-don-t-regenerate-the-address-when-removed-rh2196441.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 8848568653c686aec4b9edd2deaa630588533b49 Mon Sep 17 00:00:00 2001 -From: Beniamino Galvani -Date: Thu, 11 May 2023 13:32:13 +0200 -Subject: [PATCH] ipv6ll: don't regenerate the address when it's removed - externally - -Currently if the IPv6 link-local address is removed after it passed -DAD, NetworkManager tries to generate a new link-local address. If -this fails, which is always the case for EUI64, ipv6ll is considered -as failed and the connection can go down (depending on may-fail). - -This is particularly bad for virtual interfaces because if somebody -removes the link-local address, the activation can fail and destroy -the interface, breaking all services that require it. Also, it's a -change in behavior introduced in 1.36.0. - -It seems that a better approach here is to re-add the address that was -removed externally. - -[bgalvani@redhat.com: since the branch is missing commit 7ca95cee15b3 -('platform: always reconfigure IP routes even if removed externally'), -we need to set flag NM_L3CFG_CONFIG_FLAGS_FORCE_ONCE when committing -the address, otherwise it's not re-added] - -Fixes: aa070fb82190 ('core: add NML3IPv6LL helper') -https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1622 -(cherry picked from commit 53ba9f4701f30b12637df2c7215a0b7da845b34c) -(cherry picked from commit 2976e4c3b7fcee06051ce83c9a7fa911ad192dc4) ---- - src/core/nm-l3-ipv6ll.c | 34 ++++++++++++++++++++++------------ - 1 file changed, 22 insertions(+), 12 deletions(-) - -diff --git a/src/core/nm-l3-ipv6ll.c b/src/core/nm-l3-ipv6ll.c -index 2e2a6a0a5a..0133ebe6dd 100644 ---- a/src/core/nm-l3-ipv6ll.c -+++ b/src/core/nm-l3-ipv6ll.c -@@ -391,7 +391,7 @@ _pladdr_find_ll(NML3IPv6LL *self, gboolean *out_cur_addr_failed) - /*****************************************************************************/ - - static void --_lladdr_handle_changed(NML3IPv6LL *self) -+_lladdr_handle_changed(NML3IPv6LL *self, gboolean force_commit) - { - const NML3ConfigData *l3cd; - gboolean changed = FALSE; -@@ -420,7 +420,9 @@ _lladdr_handle_changed(NML3IPv6LL *self) - NM_DNS_PRIORITY_DEFAULT_NORMAL, - NM_L3_ACD_DEFEND_TYPE_ALWAYS, - 0, -- NM_L3CFG_CONFIG_FLAGS_NONE, -+ /* Even if the address was removed from platform, it must -+ * be re-added, hence FORCE_ONCE. */ -+ NM_L3CFG_CONFIG_FLAGS_FORCE_ONCE, - NM_L3_CONFIG_MERGE_FLAGS_NONE)) - changed = TRUE; - } else { -@@ -434,7 +436,7 @@ _lladdr_handle_changed(NML3IPv6LL *self) - self->l3cfg_commit_handle, - "ipv6ll"); - -- if (changed) -+ if (changed || force_commit) - nm_l3cfg_commit_on_idle_schedule(self->l3cfg, NM_L3_CFG_COMMIT_TYPE_AUTO); - - if (!self->emit_changed_idle_source) { -@@ -515,6 +517,7 @@ _check(NML3IPv6LL *self) - const NMPlatformIP6Address *pladdr; - char sbuf[INET6_ADDRSTRLEN]; - gboolean cur_addr_failed; -+ gboolean restarted = FALSE; - struct in6_addr lladdr; - - pladdr = _pladdr_find_ll(self, &cur_addr_failed); -@@ -526,14 +529,14 @@ _check(NML3IPv6LL *self) - if (_set_cur_lladdr_obj(self, NM_L3_IPV6LL_STATE_DAD_IN_PROGRESS, pladdr)) { - _LOGT("changed: waiting for address %s to complete DAD", - nm_inet6_ntop(&self->cur_lladdr, sbuf)); -- _lladdr_handle_changed(self); -+ _lladdr_handle_changed(self, FALSE); - } - return; - } - - if (_set_cur_lladdr_obj(self, NM_L3_IPV6LL_STATE_READY, pladdr)) { - _LOGT("changed: address %s is ready", nm_inet6_ntop(&self->cur_lladdr, sbuf)); -- _lladdr_handle_changed(self); -+ _lladdr_handle_changed(self, FALSE); - } - return; - } -@@ -543,11 +546,17 @@ _check(NML3IPv6LL *self) - * Prematurely abort DAD to generate a new address below. */ - nm_assert( - NM_IN_SET(self->state, NM_L3_IPV6LL_STATE_DAD_IN_PROGRESS, NM_L3_IPV6LL_STATE_READY)); -- if (self->state == NM_L3_IPV6LL_STATE_DAD_IN_PROGRESS) -- _LOGT("changed: address %s did not complete DAD", -- nm_inet6_ntop(&self->cur_lladdr, sbuf)); -- else { -+ -+ if (cur_addr_failed) { -+ /* On DAD failure, we always try to regenerate a new address. */ -+ _LOGT("changed: address %s failed", nm_inet6_ntop(&self->cur_lladdr, sbuf)); -+ } else { - _LOGT("changed: address %s is gone", nm_inet6_ntop(&self->cur_lladdr, sbuf)); -+ /* When the address is removed, we always try to re-add it. */ -+ nm_clear_g_source_inst(&self->wait_for_addr_source); -+ lladdr = self->cur_lladdr; -+ restarted = TRUE; -+ goto commit; - } - - /* reset the state here, so that we are sure that the following -@@ -569,18 +578,19 @@ _check(NML3IPv6LL *self) - if (_set_cur_lladdr_bin(self, NM_L3_IPV6LL_STATE_DAD_FAILED, NULL)) { - _LOGW("changed: no IPv6 link local address to retry after Duplicate Address Detection " - "failures (back off)"); -- _lladdr_handle_changed(self); -+ _lladdr_handle_changed(self, FALSE); - } - return; - } - -+commit: - /* we give NML3Cfg 2 seconds to configure the address on the interface. We - * thus very soon expect to see this address configured (and kernel started DAD). - * If that does not happen within timeout, we assume that this address failed DAD. */ - self->wait_for_addr_source = nm_g_timeout_add_source(2000, _wait_for_addr_timeout_cb, self); -- if (_set_cur_lladdr_bin(self, NM_L3_IPV6LL_STATE_DAD_IN_PROGRESS, &lladdr)) { -+ if (_set_cur_lladdr_bin(self, NM_L3_IPV6LL_STATE_DAD_IN_PROGRESS, &lladdr) || restarted) { - _LOGT("changed: starting DAD for address %s", nm_inet6_ntop(&self->cur_lladdr, sbuf)); -- _lladdr_handle_changed(self); -+ _lladdr_handle_changed(self, restarted); - } - return; - } --- -2.39.2 - diff --git a/SOURCES/1001-nm-manager-ensure-device-is-exported-on-D-Bus-in-aut-rhbz2210271.patch b/SOURCES/1001-nm-manager-ensure-device-is-exported-on-D-Bus-in-aut-rhbz2210271.patch new file mode 100644 index 0000000..1867761 --- /dev/null +++ b/SOURCES/1001-nm-manager-ensure-device-is-exported-on-D-Bus-in-aut-rhbz2210271.patch @@ -0,0 +1,54 @@ +From 6302c2ea52c6c28d36b6006b29823c469e171e2a Mon Sep 17 00:00:00 2001 +From: Wen Liang +Date: Thu, 3 Aug 2023 10:16:42 -0400 +Subject: [PATCH] nm-manager: ensure device is exported on D-Bus in + authentication request + +The device authentication request is an async process, it can not know +the answer right away, it is not guarantee that device is still +exported on D-Bus when authentication finishes. Thus, do not return +SUCCESS and abort the authentication request when device is not alive. + +https://bugzilla.redhat.com/show_bug.cgi?id=2210271 +(cherry picked from commit b341161e2a4988403ae4a6ef7653e01567da36a0) +(cherry picked from commit 0e27e84247ed824b27d105292d7bf42dc0341cbb) +--- + src/core/nm-manager.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c +index 9c7212202b..937acbba1e 100644 +--- a/src/core/nm-manager.c ++++ b/src/core/nm-manager.c +@@ -3222,6 +3222,13 @@ device_auth_done_cb(NMAuthChain *chain, GDBusMethodInvocation *context, gpointer + nm_assert(error || (result == NM_AUTH_CALL_RESULT_YES)); + } + ++ if (!error && !nm_dbus_object_is_exported(NM_DBUS_OBJECT(device))) { ++ g_set_error(&error, ++ NM_MANAGER_ERROR, ++ NM_MANAGER_ERROR_UNKNOWN_DEVICE, ++ "device no longer exists"); ++ } ++ + callback(device, context, subject, error, nm_auth_chain_get_data(chain, "user-data")); + } + +@@ -3287,6 +3294,14 @@ nm_manager_device_auth_request(NMManager *self, + &error)) + goto fail_on_idle; + ++ if (!nm_dbus_object_is_exported(NM_DBUS_OBJECT(device))) { ++ g_set_error(&error, ++ NM_MANAGER_ERROR, ++ NM_MANAGER_ERROR_UNKNOWN_DEVICE, ++ "device no longer exists"); ++ goto fail_on_idle; ++ } ++ + chain = nm_auth_chain_new_subject(subject, context, device_auth_done_cb, self); + if (cancellable) + nm_auth_chain_set_cancellable(chain, cancellable); +-- +2.41.0 + diff --git a/SOURCES/1002-Revert-infiniband-avoid-normalizing-the-p-key-rh2209976.patch b/SOURCES/1002-Revert-infiniband-avoid-normalizing-the-p-key-rh2209976.patch deleted file mode 100644 index 614aeed..0000000 --- a/SOURCES/1002-Revert-infiniband-avoid-normalizing-the-p-key-rh2209976.patch +++ /dev/null @@ -1,270 +0,0 @@ -From 0ad139d4f8c49ec1c0e511776fc62c415ec5910c Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 24 May 2023 09:44:59 +0200 -Subject: [PATCH 1/2] Revert "infiniband: avoid normalizing the p-key when - reading from ifcfg" - -Historically, initscripts' ifup-ib would set the highest bit of -PKEY_ID=. That changed and needs to be restored. - -Note that it probably makes little sense to ever configure p-keys -without the highest bit set, because that flag indicates full membership -and kernel will automatically add it. At least, kernel will add the flag -for the p-key, but not for the automatically chosen interface name. - -Meaning, writing 0x00f0 to create_child sysctl, results in an interface -"$parent.00f0", but `ip -d link` shows pkey 0x80f0. - -As NetworkManager otherwise supports p-keys without the highest bit set, -and since that high bit is honored for the interface name, we cannot -just always add the high bit. NetworkManager always assuming the highest -bit is set, would change the interface names of existing configuration. - -With this revert, when a user configures a small p-key and the profile -is stored in ifcfg-rh format, the settings backend will automatically -mangle the profile and set 0x8000. That is different from when the -profile is stored in keyfile format. Since using small p-keys is -probably an odd case, we don't try to workaround that any other way -(like that ifcfg format could represent the orignal value of the profile -and not doing such mangling, or to add the high bit throughout -NetworkManager to the p-key). It's an inconsistency, but given the -existing behaviors it seems best to stick (revert) to it. - -This reverts commit a4fe16a426097eee263cb3ef831dcea468b1ca26. - -Affected versions were 1.42.2+ and 1.40.2+. - -See-also: https://src.fedoraproject.org/rpms/rdma/blob/05333c3602aa3c1d82a6363521bdd5a498eac6d0/f/rdma.ifup-ib#_75 - -https://bugzilla.redhat.com/show_bug.cgi?id=2209164 -(cherry picked from commit f8e5e07355e23b6d59b1b1c9cd2387c6b40b214b) -(cherry picked from commit 76de1b7ec29729af901e7e246387af9fda56f6ac) ---- - .../plugins/ifcfg-rh/nms-ifcfg-rh-reader.c | 18 ++++++ - .../plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 57 ++++++++++++++----- - 2 files changed, 60 insertions(+), 15 deletions(-) - -diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c -index aa593331c5..c8150782ec 100644 ---- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c -+++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c -@@ -5406,6 +5406,24 @@ parse_infiniband_p_key(shvarFile *ifcfg, int *out_p_key, char **out_parent, GErr - return FALSE; - } - -+ /* The highest bit 0x8000 indicates full membership, which kernel always -+ * automatically sets. -+ * -+ * NetworkManager supports p-keys without the high bit set. That affects -+ * the interface name (nmp_utils_new_infiniband_name()) and is what -+ * we write to "create_child"/"delete_child" sysctl. Kernel will honor -+ * such p-keys for the interface name, but for other purposes it adds the -+ * highest bit. That makes using p-keys without the highest bit odd. -+ * -+ * Historically, /etc/sysconfig/network-scripts/ifup-ib would always add "|=0x8000". -+ * The reader does that too. -+ * -+ * Note that this means ifcfg cannot handle p-keys without the highest bit set, -+ * and when trying to store that to ifcfg format, the profile will be mangled/modified -+ * by the ifcg plugin (unlike keyfile backend, which preserves the original p-key value). -+ */ -+ id |= 0x8000; -+ - *out_p_key = id; - *out_parent = g_steal_pointer(&physdev); - return TRUE; -diff --git a/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c -index 40ff7c670e..8714f19682 100644 ---- a/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c -+++ b/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c -@@ -8409,21 +8409,21 @@ test_read_ipoib(void) - s_infiniband = nmtst_connection_assert_setting(connection, NM_TYPE_SETTING_INFINIBAND); - - pkey = nm_setting_infiniband_get_p_key(s_infiniband); -- g_assert(pkey); -- g_assert_cmpint(pkey, ==, 12); -+ g_assert_cmpint(pkey, ==, 0x800c); - - transport_mode = nm_setting_infiniband_get_transport_mode(s_infiniband); -- g_assert(transport_mode); - g_assert_cmpstr(transport_mode, ==, "connected"); - } - - static void - test_write_infiniband(gconstpointer test_data) - { -- const int TEST_IDX = GPOINTER_TO_INT(test_data); -- nmtst_auto_unlinkfile char *testfile = NULL; -- gs_unref_object NMConnection *connection = NULL; -- gs_unref_object NMConnection *reread = NULL; -+ const int TEST_IDX = GPOINTER_TO_INT(test_data); -+ nmtst_auto_unlinkfile char *testfile = NULL; -+ gs_unref_object NMConnection *connection = NULL; -+ gs_unref_object NMConnection *expected = NULL; -+ gs_unref_object NMConnection *reread = NULL; -+ gboolean reread_same = FALSE; - NMSettingConnection *s_con; - NMSettingInfiniband *s_infiniband; - NMSettingIPConfig *s_ip4; -@@ -8433,6 +8433,7 @@ test_write_infiniband(gconstpointer test_data) - NMIPAddress *addr; - GError *error = NULL; - const char *interface_name = NULL; -+ int p_key; - - connection = nm_simple_connection_new(); - -@@ -8448,14 +8449,21 @@ test_write_infiniband(gconstpointer test_data) - NM_SETTING_INFINIBAND_SETTING_NAME, - NULL); - -- if (NM_IN_SET(TEST_IDX, 1, 3)) -- interface_name = "ib0.000c"; -+ if (NM_IN_SET(TEST_IDX, 1, 2)) -+ p_key = nmtst_get_rand_bool() ? 0x000c : 0x800c; -+ else -+ p_key = -1; -+ -+ if (NM_IN_SET(TEST_IDX, 1, 3)) { -+ if (p_key >= 0x8000) -+ interface_name = "ib0.800c"; -+ } - - g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, interface_name, NULL); - - s_infiniband = _nm_connection_new_setting(connection, NM_TYPE_SETTING_INFINIBAND); - g_object_set(s_infiniband, NM_SETTING_INFINIBAND_TRANSPORT_MODE, "connected", NULL); -- if (NM_IN_SET(TEST_IDX, 1, 2)) { -+ if (p_key == -1) { - g_object_set(s_infiniband, - NM_SETTING_INFINIBAND_MAC_ADDRESS, - mac, -@@ -8465,7 +8473,7 @@ test_write_infiniband(gconstpointer test_data) - } else { - g_object_set(s_infiniband, - NM_SETTING_INFINIBAND_P_KEY, -- 12, -+ p_key, - NM_SETTING_INFINIBAND_PARENT, - "ib0", - NULL); -@@ -8494,13 +8502,32 @@ test_write_infiniband(gconstpointer test_data) - - nmtst_assert_connection_verifies(connection); - -- _writer_new_connection(connection, TEST_SCRATCH_DIR, &testfile); -- -- reread = _connection_from_file(testfile, NULL, TYPE_INFINIBAND, NULL); -+ if (p_key != -1 && p_key < 0x8000) { -+ expected = nm_simple_connection_new_clone(connection); -+ g_object_set(nm_connection_get_setting(expected, NM_TYPE_SETTING_INFINIBAND), -+ NM_SETTING_INFINIBAND_P_KEY, -+ (int) (p_key | 0x8000), -+ NULL); -+ } else -+ expected = g_object_ref(connection); - -- nmtst_assert_connection_equals(connection, TRUE, reread, FALSE); -+ _writer_new_connection_reread(connection, -+ TEST_SCRATCH_DIR, -+ &testfile, -+ NO_EXPECTED, -+ &reread, -+ &reread_same); -+ _assert_reread_same(expected, reread); -+ if (p_key == -1 || p_key > 0x8000) -+ g_assert(reread_same); -+ else -+ g_assert(!reread_same); - - g_assert_cmpstr(interface_name, ==, nm_connection_get_interface_name(reread)); -+ g_assert_cmpint(nm_setting_infiniband_get_p_key( -+ _nm_connection_get_setting(reread, NM_TYPE_SETTING_INFINIBAND)), -+ ==, -+ p_key == -1 ? -1 : (p_key | 0x8000)); - } - - static void --- -2.38.1 - - -From 13156501fb6f214eccf22fe6b7447dae9b052b8d Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 24 May 2023 10:44:58 +0200 -Subject: [PATCH 2/2] libnm/docs: clarify behavior of infiniband.p-key property - -(cherry picked from commit ea18e66ef657b55eca941dca3de4949b950e656b) -(cherry picked from commit 2945254e29c58839410127e695e0216763a3dd01) ---- - src/libnm-core-impl/nm-setting-infiniband.c | 19 ++++++++++++++++--- - src/libnmc-setting/settings-docs.h.in | 2 +- - .../gen-metadata-nm-settings-nmcli.xml.in | 2 +- - 3 files changed, 18 insertions(+), 5 deletions(-) - -diff --git a/src/libnm-core-impl/nm-setting-infiniband.c b/src/libnm-core-impl/nm-setting-infiniband.c -index 410f1f0687..7ba5720619 100644 ---- a/src/libnm-core-impl/nm-setting-infiniband.c -+++ b/src/libnm-core-impl/nm-setting-infiniband.c -@@ -449,9 +449,20 @@ nm_setting_infiniband_class_init(NMSettingInfinibandClass *klass) - * NMSettingInfiniband:p-key: - * - * The InfiniBand P_Key to use for this device. A value of -1 means to use -- * the default P_Key (aka "the P_Key at index 0"). Otherwise, it is a 16-bit -- * unsigned integer, whose high bit is set if it is a "full membership" -- * P_Key. -+ * the default P_Key (aka "the P_Key at index 0"). Otherwise, it is a -+ * 16-bit unsigned integer, whose high bit 0x8000 is set if it is a "full -+ * membership" P_Key. The values 0 and 0x8000 are not allowed. -+ * -+ * With the p-key set, the interface name is always "$parent.$p_key". -+ * Setting "connection.interface-name" to another name is not supported. -+ * -+ * Note that kernel will internally always set the full membership bit, -+ * although the interface name does not reflect that. Thus, not setting -+ * the high bit is probably not useful. -+ * -+ * If the profile is stored in ifcfg-rh format, then the full membership -+ * bit is automatically added. To get consistent behavior, it is -+ * best to only use p-key values with the full membership bit set. - **/ - /* ---ifcfg-rh--- - * property: p-key -@@ -460,6 +471,8 @@ nm_setting_infiniband_class_init(NMSettingInfinibandClass *klass) - * description: InfiniBand P_Key. The value can be a hex number prefixed with "0x" - * or a decimal number. - * When PKEY_ID is specified, PHYSDEV and DEVICE also must be specified. -+ * Note that ifcfg-rh format will always automatically set the full membership -+ * bit 0x8000. Other p-key cannot be stored. - * example: PKEY=yes PKEY_ID=2 PHYSDEV=mlx4_ib0 DEVICE=mlx4_ib0.8002 - * ---end--- - */ -diff --git a/src/libnmc-setting/settings-docs.h.in b/src/libnmc-setting/settings-docs.h.in -index cd5b231bb9..00532df93c 100644 ---- a/src/libnmc-setting/settings-docs.h.in -+++ b/src/libnmc-setting/settings-docs.h.in -@@ -153,7 +153,7 @@ - #define DESCRIBE_DOC_NM_SETTING_GSM_USERNAME N_("The username used to authenticate with the network, if required. Many providers do not require a username, or accept any username. But if a username is required, it is specified here.") - #define DESCRIBE_DOC_NM_SETTING_INFINIBAND_MAC_ADDRESS N_("If specified, this connection will only apply to the IPoIB device whose permanent MAC address matches. This property does not change the MAC address of the device (i.e. MAC spoofing).") - #define DESCRIBE_DOC_NM_SETTING_INFINIBAND_MTU N_("If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple frames.") --#define DESCRIBE_DOC_NM_SETTING_INFINIBAND_P_KEY N_("The InfiniBand P_Key to use for this device. A value of -1 means to use the default P_Key (aka \"the P_Key at index 0\"). Otherwise, it is a 16-bit unsigned integer, whose high bit is set if it is a \"full membership\" P_Key.") -+#define DESCRIBE_DOC_NM_SETTING_INFINIBAND_P_KEY N_("The InfiniBand P_Key to use for this device. A value of -1 means to use the default P_Key (aka \"the P_Key at index 0\"). Otherwise, it is a 16-bit unsigned integer, whose high bit 0x8000 is set if it is a \"full membership\" P_Key. The values 0 and 0x8000 are not allowed. With the p-key set, the interface name is always \"$parent.$p_key\". Setting \"connection.interface-name\" to another name is not supported. Note that kernel will internally always set the full membership bit, although the interface name does not reflect that. Thus, not setting the high bit is probably not useful. If the profile is stored in ifcfg-rh format, then the full membership bit is automatically added. To get consistent behavior, it is best to only use p-key values with the full membership bit set.") - #define DESCRIBE_DOC_NM_SETTING_INFINIBAND_PARENT N_("The interface name of the parent device of this device. Normally NULL, but if the \"p_key\" property is set, then you must specify the base device by setting either this property or \"mac-address\".") - #define DESCRIBE_DOC_NM_SETTING_INFINIBAND_TRANSPORT_MODE N_("The IP-over-InfiniBand transport mode. Either \"datagram\" or \"connected\".") - #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ADDRESSES N_("A list of IPv4 addresses and their prefix length. Multiple addresses can be separated by comma. For example \"192.168.1.5/24, 10.1.0.5/24\". The addresses are listed in decreasing priority, meaning the first address will be the primary address.") -diff --git a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in -index dfea3c3440..3d2bb5186b 100644 ---- a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in -+++ b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in -@@ -611,7 +611,7 @@ - description="The IP-over-InfiniBand transport mode. Either "datagram" or "connected"." /> - -+ description="The InfiniBand P_Key to use for this device. A value of -1 means to use the default P_Key (aka "the P_Key at index 0"). Otherwise, it is a 16-bit unsigned integer, whose high bit 0x8000 is set if it is a "full membership" P_Key. The values 0 and 0x8000 are not allowed. With the p-key set, the interface name is always "$parent.$p_key". Setting "connection.interface-name" to another name is not supported. Note that kernel will internally always set the full membership bit, although the interface name does not reflect that. Thus, not setting the high bit is probably not useful. If the profile is stored in ifcfg-rh format, then the full membership bit is automatically added. To get consistent behavior, it is best to only use p-key values with the full membership bit set." /> - --- -2.38.1 - diff --git a/SOURCES/1002-checkpoint-Fix-segfault-crash-when-rollback-rhel-1526.patch b/SOURCES/1002-checkpoint-Fix-segfault-crash-when-rollback-rhel-1526.patch new file mode 100644 index 0000000..63671a3 --- /dev/null +++ b/SOURCES/1002-checkpoint-Fix-segfault-crash-when-rollback-rhel-1526.patch @@ -0,0 +1,67 @@ +From d9b3114b6ef8e0f4d50a8d56d750a698d85fa984 Mon Sep 17 00:00:00 2001 +From: Gris Ge +Date: Tue, 29 Aug 2023 08:25:23 +0800 +Subject: [PATCH] checkpoint: Fix segfault crash when rollback + +When rolling back a checkpoint, NM will crash due to dereference a NULL +pointer of `priv->removed_devices->len`. + +To fix it, we just place a NULL check before that code block. + +Fixes: 1f1b71ad9f8a ('checkpoint: preserve devices that were removed and + readded') + +Reference: https://issues.redhat.com/browse/RHEL-1526 + +Signed-off-by: Gris Ge +(cherry picked from commit 3162507d6ca381cfbe02ceba2d80ba0f3ba3e5f7) +(cherry picked from commit e5600d4c5a33749939b984184f27fbe4159a2b65) +--- + src/core/nm-checkpoint.c | 23 +++++++++++++---------- + 1 file changed, 13 insertions(+), 10 deletions(-) + +diff --git a/src/core/nm-checkpoint.c b/src/core/nm-checkpoint.c +index 5c4d4e53d6..74adf48477 100644 +--- a/src/core/nm-checkpoint.c ++++ b/src/core/nm-checkpoint.c +@@ -460,24 +460,27 @@ next_dev: + NMDeviceState state; + + nm_manager_for_each_device (priv->manager, device, tmp_lst) { +- gboolean found = FALSE; +- + if (g_hash_table_contains(priv->devices, device)) + continue; + + /* Also ignore devices that were in the checkpoint initially and + * were moved to 'removed_devices' because they got removed from + * the system. */ +- for (i = 0; i < priv->removed_devices->len; i++) { +- dev_checkpoint = priv->removed_devices->pdata[i]; +- if (dev_checkpoint->dev_type == nm_device_get_device_type(device) +- && nm_streq0(dev_checkpoint->original_dev_name, nm_device_get_iface(device))) { +- found = TRUE; +- break; ++ if (priv->removed_devices) { ++ gboolean found = FALSE; ++ ++ for (i = 0; i < priv->removed_devices->len; i++) { ++ dev_checkpoint = priv->removed_devices->pdata[i]; ++ if (dev_checkpoint->dev_type == nm_device_get_device_type(device) ++ && nm_streq0(dev_checkpoint->original_dev_name, ++ nm_device_get_iface(device))) { ++ found = TRUE; ++ break; ++ } + } ++ if (found) ++ continue; + } +- if (found) +- continue; + + state = nm_device_get_state(device); + if (state > NM_DEVICE_STATE_DISCONNECTED && state < NM_DEVICE_STATE_DEACTIVATING) { +-- +2.41.0 + diff --git a/SOURCES/1003-unblock-autoconnect-upon-reapply-rh2217903.patch b/SOURCES/1003-unblock-autoconnect-upon-reapply-rh2217903.patch deleted file mode 100644 index aa73fab..0000000 --- a/SOURCES/1003-unblock-autoconnect-upon-reapply-rh2217903.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 18ce5f43bd16b3cc394424619652c782cb3795c3 Mon Sep 17 00:00:00 2001 -From: Gris Ge -Date: Tue, 27 Jun 2023 15:02:54 +0800 -Subject: [PATCH] setting-connection: Unblock autoconnect upon finish of - `Reapply` - -The activation of a connection will clear the block of autoconnect, -we should do the same for reapply. - -Signed-off-by: Gris Ge -(cherry picked from commit 0486efd3584c70179072f611e63b9c0ff6851b80) ---- - 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 c168fa045d..62a9ff1e84 100644 ---- a/src/core/devices/nm-device.c -+++ b/src/core/devices/nm-device.c -@@ -12902,6 +12902,7 @@ check_and_reapply_connection(NMDevice *self, - NMConnection *con_old; - NMConnection *con_new; - GHashTableIter iter; -+ NMSettingsConnection *sett_conn; - - if (priv->state < NM_DEVICE_STATE_PREPARE || priv->state > NM_DEVICE_STATE_ACTIVATED) { - g_set_error_literal(error, -@@ -13074,6 +13075,14 @@ check_and_reapply_connection(NMDevice *self, - if (priv->state >= NM_DEVICE_STATE_ACTIVATED) - nm_device_update_metered(self); - -+ sett_conn = nm_device_get_settings_connection(self); -+ if (sett_conn) { -+ nm_settings_connection_autoconnect_blocked_reason_set( -+ sett_conn, -+ NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST, -+ FALSE); -+ } -+ - /* Notify dispatcher when re-applied */ - _LOGD(LOGD_DEVICE, "Notifying re-apply complete"); - nm_dispatcher_call_device(NM_DISPATCHER_ACTION_REAPPLY, self, NULL, NULL, NULL, NULL); --- -2.39.3 - diff --git a/SOURCES/1004-core-fix-l3cd-comparison-rhbz2219847.patch b/SOURCES/1004-core-fix-l3cd-comparison-rhbz2219847.patch deleted file mode 100644 index 6fc8606..0000000 --- a/SOURCES/1004-core-fix-l3cd-comparison-rhbz2219847.patch +++ /dev/null @@ -1,88 +0,0 @@ -From d6f13aefda85ea06985e7fe2f776abd8ee0406cf Mon Sep 17 00:00:00 2001 -From: Beniamino Galvani -Date: Fri, 24 Mar 2023 17:42:45 +0100 -Subject: [PATCH] core: fix l3cd comparison - -NM_CMP_SELF(a, b) returns immediately if the objects are the same. - -Fixes: cb29244552af ('core: support compare flags in nm_l3_config_data_cmp_full()') -Fixes-test: @dracut_NM_iSCSI_ibft_table - -https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1583 -(cherry picked from commit 0a02995175e06e62924705393121a1c5efc3822d) -(cherry picked from commit 5d95c20787077a91d684259d67f2e0ff3a1d7a1a) ---- - src/core/nm-l3-config-data.c | 54 +++++++++++++++++++----------------- - 1 file changed, 28 insertions(+), 26 deletions(-) - -diff --git a/src/core/nm-l3-config-data.c b/src/core/nm-l3-config-data.c -index 17bb9db87d..d5dedb9c8a 100644 ---- a/src/core/nm-l3-config-data.c -+++ b/src/core/nm-l3-config-data.c -@@ -2297,35 +2297,37 @@ nm_l3_config_data_cmp_full(const NML3ConfigData *a, - const NMPObject *def_route_a = a->best_default_route_x[IS_IPv4]; - const NMPObject *def_route_b = b->best_default_route_x[IS_IPv4]; - -- NM_CMP_SELF(def_route_a, def_route_b); -- -- if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_ROUTES)) { -- NM_CMP_RETURN(nmp_object_cmp_full(def_route_a, -- def_route_b, -- NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_IFINDEX) -- ? NMP_OBJECT_CMP_FLAGS_NONE -- : NMP_OBJECT_CMP_FLAGS_IGNORE_IFINDEX)); -- } else if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_ROUTES_ID)) { -- if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_IFINDEX)) { -- NM_CMP_DIRECT(def_route_a->obj_with_ifindex.ifindex, -- def_route_b->obj_with_ifindex.ifindex); -- } -+ if (def_route_a != def_route_b) { -+ if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_ROUTES)) { -+ NM_CMP_RETURN( -+ nmp_object_cmp_full(def_route_a, -+ def_route_b, -+ NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_IFINDEX) -+ ? NMP_OBJECT_CMP_FLAGS_NONE -+ : NMP_OBJECT_CMP_FLAGS_IGNORE_IFINDEX)); -+ } else if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_ROUTES_ID)) { -+ if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_IFINDEX)) { -+ NM_CMP_DIRECT(def_route_a->obj_with_ifindex.ifindex, -+ def_route_b->obj_with_ifindex.ifindex); -+ } - -- if (IS_IPv4) { -- NMPlatformIP4Route ra = def_route_a->ip4_route; -- NMPlatformIP4Route rb = def_route_b->ip4_route; -+ if (IS_IPv4) { -+ NMPlatformIP4Route ra = def_route_a->ip4_route; -+ NMPlatformIP4Route rb = def_route_b->ip4_route; - -- NM_CMP_DIRECT(ra.metric, rb.metric); -- NM_CMP_DIRECT(ra.plen, rb.plen); -- NM_CMP_RETURN_DIRECT(nm_ip4_addr_same_prefix_cmp(ra.network, rb.network, ra.plen)); -- } else { -- NMPlatformIP6Route ra = def_route_a->ip6_route; -- NMPlatformIP6Route rb = def_route_b->ip6_route; -+ NM_CMP_DIRECT(ra.metric, rb.metric); -+ NM_CMP_DIRECT(ra.plen, rb.plen); -+ NM_CMP_RETURN_DIRECT( -+ nm_ip4_addr_same_prefix_cmp(ra.network, rb.network, ra.plen)); -+ } else { -+ NMPlatformIP6Route ra = def_route_a->ip6_route; -+ NMPlatformIP6Route rb = def_route_b->ip6_route; - -- NM_CMP_DIRECT(ra.metric, rb.metric); -- NM_CMP_DIRECT(ra.plen, rb.plen); -- NM_CMP_RETURN_DIRECT( -- nm_ip6_addr_same_prefix_cmp(&ra.network, &rb.network, ra.plen)); -+ NM_CMP_DIRECT(ra.metric, rb.metric); -+ NM_CMP_DIRECT(ra.plen, rb.plen); -+ NM_CMP_RETURN_DIRECT( -+ nm_ip6_addr_same_prefix_cmp(&ra.network, &rb.network, ra.plen)); -+ } - } - } - --- -2.38.1 - diff --git a/SOURCES/1005-firewall-create-dynamic-sets-rhbz2220952.patch b/SOURCES/1005-firewall-create-dynamic-sets-rhbz2220952.patch deleted file mode 100644 index 43fc6bb..0000000 --- a/SOURCES/1005-firewall-create-dynamic-sets-rhbz2220952.patch +++ /dev/null @@ -1,530 +0,0 @@ -From c00002b12d34c12d418f5753e03df43ecb6ef67d Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 10 May 2023 08:37:06 +0200 -Subject: [PATCH 1/5] glib-aux: add - NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_DOUBLE_QUOTE flag to escape double quotes - -This is useful when printing a string for debugging. Then we can -printf("v=\"%s\"", utf8safe_escaped_text), which can be safely unescaped -with `echo -e`. - -(cherry picked from commit c26a94e95551021d86cae6fc0e6aafb97b1363f6) -(cherry picked from commit 18848c77c7a44b179ad0c582ac60cee7602d1786) ---- - src/libnm-glib-aux/nm-shared-utils.c | 21 +++++++++++++-------- - src/libnm-glib-aux/nm-shared-utils.h | 8 ++++++-- - 2 files changed, 19 insertions(+), 10 deletions(-) - -diff --git a/src/libnm-glib-aux/nm-shared-utils.c b/src/libnm-glib-aux/nm-shared-utils.c -index 702a63e9f6..49f2c93e35 100644 ---- a/src/libnm-glib-aux/nm-shared-utils.c -+++ b/src/libnm-glib-aux/nm-shared-utils.c -@@ -2755,13 +2755,16 @@ nm_utils_buf_utf8safe_escape(gconstpointer buf, - if (g_utf8_validate(str, buflen, &p) && nul_terminated) { - /* note that g_utf8_validate() does not allow NUL character inside @str. Good. - * We can treat @str like a NUL terminated string. */ -- if (!NM_STRCHAR_ANY(str, -- ch, -- (ch == '\\' -- || (NM_FLAGS_HAS(flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL) -- && nm_ascii_is_ctrl_or_del(ch)) -- || (NM_FLAGS_HAS(flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII) -- && nm_ascii_is_non_ascii(ch))))) -+ if (!NM_STRCHAR_ANY( -+ str, -+ ch, -+ (ch == '\\' -+ || (NM_FLAGS_HAS(flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL) -+ && nm_ascii_is_ctrl_or_del(ch)) -+ || (NM_FLAGS_HAS(flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII) -+ && nm_ascii_is_non_ascii(ch)) -+ || (NM_FLAGS_HAS(flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_DOUBLE_QUOTE) -+ && ch == '"')))) - return str; - } - -@@ -2781,7 +2784,9 @@ nm_utils_buf_utf8safe_escape(gconstpointer buf, - else if ((NM_FLAGS_HAS(flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL) - && nm_ascii_is_ctrl_or_del(ch)) - || (NM_FLAGS_HAS(flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII) -- && nm_ascii_is_non_ascii(ch))) -+ && nm_ascii_is_non_ascii(ch)) -+ || (NM_FLAGS_HAS(flags, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_DOUBLE_QUOTE) -+ && ch == '"')) - _str_buf_append_c_escape_octal(&strbuf, ch); - else - nm_str_buf_append_c(&strbuf, ch); -diff --git a/src/libnm-glib-aux/nm-shared-utils.h b/src/libnm-glib-aux/nm-shared-utils.h -index 083ed137ee..ad24e7c427 100644 ---- a/src/libnm-glib-aux/nm-shared-utils.h -+++ b/src/libnm-glib-aux/nm-shared-utils.h -@@ -1243,12 +1243,16 @@ typedef enum { - * It will backslash escape ascii characters according to nm_ascii_is_non_ascii(). */ - NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_NON_ASCII = 0x0002, - -+ /* Escape '"' as ASCII "\\042". This is useful when escaping a string so that -+ * it can be unescaped with `echo -e $PASTE_TEXT`. */ -+ NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_DOUBLE_QUOTE = 0x0004, -+ - /* This flag only has an effect during escaping to ensure we - * don't leak secrets in memory. Note that during unescape we - * know the maximum result size from the beginning, and no - * reallocation happens. Thus, unescape always avoids leaking - * secrets already. */ -- NM_UTILS_STR_UTF8_SAFE_FLAG_SECRET = 0x0004, -+ NM_UTILS_STR_UTF8_SAFE_FLAG_SECRET = 0x0008, - - /* This flag only has an effect during unescaping. It means - * that non-escaped whitespaces (g_ascii_isspace()) will be -@@ -1256,7 +1260,7 @@ typedef enum { - * this flag is only useful for gracefully accepting user input - * with spaces. With this flag, escape and unescape may no longer - * yield the original input. */ -- NM_UTILS_STR_UTF8_SAFE_UNESCAPE_STRIP_SPACES = 0x0008, -+ NM_UTILS_STR_UTF8_SAFE_UNESCAPE_STRIP_SPACES = 0x0010, - } NMUtilsStrUtf8SafeFlags; - - const char *nm_utils_buf_utf8safe_escape(gconstpointer buf, --- -2.41.0 - - -From 668d8caff3b0a8ea45a63ef9676f05d87428825d Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 10 May 2023 08:41:00 +0200 -Subject: [PATCH 2/5] glib-aux: add nmtst_assert_cmpmem() helper - -g_assert_cmpmem() exists, but it does not print the actual buffer -content on test failure. It is useful to see what actually failed in -the test output. - -Also, nmtst_assert_cmpmem() prints a backslash escaped output, that you -can unescape in the terminal with `echo -e`. You can also directly copy -and paste the output to C source code. - -(cherry picked from commit 3c3938406dd825f6a0d9e6e55319f0f68a6e2f83) -(cherry picked from commit 4ec00efca9154029f377f8498ef4bd3bd9b4cfa9) ---- - src/libnm-glib-aux/nm-test-utils.h | 48 ++++++++++++++++++++++++++++++ - 1 file changed, 48 insertions(+) - -diff --git a/src/libnm-glib-aux/nm-test-utils.h b/src/libnm-glib-aux/nm-test-utils.h -index b65818e00a..a55977d1ce 100644 ---- a/src/libnm-glib-aux/nm-test-utils.h -+++ b/src/libnm-glib-aux/nm-test-utils.h -@@ -203,6 +203,54 @@ - } \ - G_STMT_END - -+#define nmtst_assert_cmpmem(m1, l1, m2, l2) \ -+ G_STMT_START \ -+ { \ -+ const guint8 *const _m1 = (gpointer) (m1); \ -+ const guint8 *const _m2 = (gpointer) (m2); \ -+ const gsize _l1 = (l1); \ -+ const gsize _l2 = (l2); \ -+ \ -+ /* This is like g_assert_cmpmem(), however on failure it actually -+ * prints the compared buffer contents, which is useful for debugging -+ * the test failure. */ \ -+ \ -+ g_assert(_l1 == 0 || _m1); \ -+ g_assert(_l2 == 0 || _m2); \ -+ \ -+ if (_l1 != _l2 || (_l1 > 0 && memcmp(_m1, _m2, _l1) != 0)) { \ -+ gs_free char *_s1 = NULL; \ -+ gs_free char *_s2 = NULL; \ -+ \ -+ g_error( \ -+ "ERROR: %s:%d : buffer [\"%s\" (%s, %zu bytes)] differs from [\"%s\" (%s, %zu " \ -+ "bytes)]:\n" \ -+ " a=[ \"%s\" ]\n" \ -+ " b=[ \"%s\" ]\n", \ -+ __FILE__, \ -+ (int) __LINE__, \ -+ #m1, \ -+ #l1, \ -+ _l1, \ -+ #m2, \ -+ #l2, \ -+ _l2, \ -+ (_s1 = nm_utils_buf_utf8safe_escape_cp( \ -+ _m1, \ -+ _l1, \ -+ NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL \ -+ | NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_DOUBLE_QUOTE)) \ -+ ?: "", \ -+ (_s2 = nm_utils_buf_utf8safe_escape_cp( \ -+ _m2, \ -+ _l2, \ -+ NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL \ -+ | NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_DOUBLE_QUOTE)) \ -+ ?: ""); \ -+ } \ -+ } \ -+ G_STMT_END -+ - /*****************************************************************************/ - - /* Our nm-error error numbers use negative values to signal failure. --- -2.41.0 - - -From 90b9aa2be6ec9ee3527edf146d6fce74cb2d9926 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 10 May 2023 07:44:52 +0200 -Subject: [PATCH 3/5] bond: don't configure "counter" on nft rules for - slb-bonding/mlag - -Counters are convenient for debugging, but have a performance overhead. -Configure them only when debug logging in NetworkManager is enabled. - -(cherry picked from commit 2c716f04f9b75ed8df70314920a705b48c36c8eb) -(cherry picked from commit 7bb285abb70d76dff33517252b71d0b8f96adc41) ---- - src/core/nm-bond-manager.c | 8 ++++++- - src/core/nm-firewall-utils.c | 43 +++++++++++++++++++++--------------- - src/core/nm-firewall-utils.h | 3 ++- - 3 files changed, 34 insertions(+), 20 deletions(-) - -diff --git a/src/core/nm-bond-manager.c b/src/core/nm-bond-manager.c -index 2d15b0b5a0..9985fccf11 100644 ---- a/src/core/nm-bond-manager.c -+++ b/src/core/nm-bond-manager.c -@@ -438,6 +438,7 @@ _nft_call(NMBondManager *self, - { - gs_unref_bytes GBytes *stdin_buf = NULL; - gs_free const char *const *previous_members_strv = NULL; -+ gboolean with_counters; - - if (up) { - gs_unref_ptrarray GPtrArray *arr = NULL; -@@ -480,11 +481,16 @@ _nft_call(NMBondManager *self, - } - } - -+ /* counters in the nft rules are convenient for debugging, but have a performance overhead. -+ * Enable counters based on whether NM logging is enabled. */ -+ with_counters = _NMLOG_ENABLED(LOGL_TRACE); -+ - stdin_buf = nm_firewall_nft_stdio_mlag(up, - bond_ifname, - bond_ifnames_down, - active_members, -- previous_members_strv); -+ previous_members_strv, -+ with_counters); - - nm_clear_g_cancellable(&self->cancellable); - self->cancellable = g_cancellable_new(); -diff --git a/src/core/nm-firewall-utils.c b/src/core/nm-firewall-utils.c -index f231583a21..b8ae4397bf 100644 ---- a/src/core/nm-firewall-utils.c -+++ b/src/core/nm-firewall-utils.c -@@ -763,13 +763,15 @@ nm_firewall_nft_stdio_mlag(gboolean up, - const char *bond_ifname, - const char *const *bond_ifnames_down, - const char *const *active_members, -- const char *const *previous_members) -+ const char *const *previous_members, -+ gboolean with_counters) - { - nm_auto_str_buf NMStrBuf strbuf_table_name = - NM_STR_BUF_INIT_A(NM_UTILS_GET_NEXT_REALLOC_SIZE_32, FALSE); - nm_auto_str_buf NMStrBuf strbuf = NM_STR_BUF_INIT(NM_UTILS_GET_NEXT_REALLOC_SIZE_1000, FALSE); - const char *table_name; - gsize i; -+ const char *const s_counter = with_counters ? " counter" : ""; - - if (NM_MORE_ASSERTS > 10 && active_members) { - /* No duplicates. We make certain assumptions here, and we don't -@@ -876,9 +878,10 @@ nm_firewall_nft_stdio_mlag(gboolean up, - _append(&strbuf, - "add rule netdev %s %s pkttype {" - " broadcast, multicast " -- "} counter drop", -+ "}%s drop", - table_name, -- chain_name); -+ chain_name, -+ s_counter); - } - - /* OVS SLB rule 2 -@@ -905,15 +908,17 @@ nm_firewall_nft_stdio_mlag(gboolean up, - table_name, - bond_ifname); - _append(&strbuf, -- "add rule netdev %s tx-snoop-source-mac set update ether saddr . vlan id" -- " timeout 5s @macset-tagged counter return" -+ "add rule netdev %s tx-snoop-source-mac set update ether saddr . vlan id " -+ "timeout 5s @macset-tagged%s return" - "", /* tagged */ -- table_name); -+ table_name, -+ s_counter); - _append(&strbuf, -- "add rule netdev %s tx-snoop-source-mac set update ether saddr" -- " timeout 5s @macset-untagged counter" -+ "add rule netdev %s tx-snoop-source-mac set update ether saddr timeout 5s " -+ "@macset-untagged%s" - "", /* untagged*/ -- table_name); -+ table_name, -+ s_counter); - - _append(&strbuf, - "add chain netdev %s rx-drop-looped-packets {" -@@ -921,18 +926,20 @@ nm_firewall_nft_stdio_mlag(gboolean up, - "}", - table_name, - bond_ifname); -+ _append( -+ &strbuf, -+ "add rule netdev %s rx-drop-looped-packets ether saddr . vlan id @macset-tagged%s drop", -+ table_name, -+ s_counter); - _append(&strbuf, -- "add rule netdev %s rx-drop-looped-packets ether saddr . vlan id" -- " @macset-tagged counter drop", -- table_name); -- _append(&strbuf, -- "add rule netdev %s rx-drop-looped-packets ether type vlan counter return" -+ "add rule netdev %s rx-drop-looped-packets ether type vlan%s return" - "", /* avoid looking up tagged packets in untagged table */ -- table_name); -+ table_name, -+ s_counter); - _append(&strbuf, -- "add rule netdev %s rx-drop-looped-packets ether saddr @macset-untagged" -- " counter drop", -- table_name); -+ "add rule netdev %s rx-drop-looped-packets ether saddr @macset-untagged%s drop", -+ table_name, -+ s_counter); - } - - out: -diff --git a/src/core/nm-firewall-utils.h b/src/core/nm-firewall-utils.h -index ca138ccf78..9f13a5127e 100644 ---- a/src/core/nm-firewall-utils.h -+++ b/src/core/nm-firewall-utils.h -@@ -39,6 +39,7 @@ GBytes *nm_firewall_nft_stdio_mlag(gboolean up, - const char *bond_ifname, - const char *const *bond_ifnames_down, - const char *const *active_members, -- const char *const *previous_members); -+ const char *const *previous_members, -+ gboolean with_counters); - - #endif /* __NM_FIREWALL_UTILS_H__ */ --- -2.41.0 - - -From 863171b69d72053d0b6bfafe510af62098c218d8 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 10 May 2023 08:42:49 +0200 -Subject: [PATCH 4/5] core/tests: add test for nm_firewall_nft_stdio_mlag() - -If only to hit some of the code paths in our test, and to have valgrind -check (some of) the code paths. - -(cherry picked from commit a20d4a7a912a7e7a535318bc7294ebd8b6bb6655) -(cherry picked from commit 8e7d94b10c50a4ce963ddf441752522183b35ab3) ---- - src/core/tests/test-core.c | 122 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 122 insertions(+) - -diff --git a/src/core/tests/test-core.c b/src/core/tests/test-core.c -index 887803bffe..d90e44f04f 100644 ---- a/src/core/tests/test-core.c -+++ b/src/core/tests/test-core.c -@@ -18,6 +18,7 @@ - - #include "dns/nm-dns-manager.h" - #include "nm-connectivity.h" -+#include "nm-firewall-utils.h" - - #include "nm-test-utils-core.h" - -@@ -2580,6 +2581,125 @@ test_connectivity_state_cmp(void) - - /*****************************************************************************/ - -+static void -+test_nm_firewall_nft_stdio_mlag(void) -+{ -+#define _T(up, \ -+ bond_ifname, \ -+ bond_ifnames_down, \ -+ active_members, \ -+ previous_members, \ -+ with_counters, \ -+ expected) \ -+ G_STMT_START \ -+ { \ -+ gs_unref_bytes GBytes *_b = NULL; \ -+ \ -+ _b = nm_firewall_nft_stdio_mlag((up), \ -+ (bond_ifname), \ -+ (bond_ifnames_down), \ -+ (active_members), \ -+ (previous_members), \ -+ (with_counters)); \ -+ \ -+ g_assert(_b); \ -+ nmtst_assert_cmpmem(expected, \ -+ NM_STRLEN(expected), \ -+ g_bytes_get_data(_b, NULL), \ -+ g_bytes_get_size(_b)); \ -+ } \ -+ G_STMT_END -+ -+ _T(TRUE, -+ "bond0", -+ NM_MAKE_STRV("eth0"), -+ NM_MAKE_STRV("eth1"), -+ NM_MAKE_STRV("eth2"), -+ TRUE, -+ "add table netdev nm-mlag-eth0\012delete table netdev nm-mlag-eth0\012add table netdev " -+ "nm-mlag-bond0\012flush table netdev nm-mlag-bond0\012add chain netdev nm-mlag-bond0 " -+ "rx-drop-bc-mc-eth2 { type filter hook ingress device eth2 priority filter; }\012delete " -+ "chain netdev nm-mlag-bond0 rx-drop-bc-mc-eth2\012add chain netdev nm-mlag-bond0 " -+ "rx-drop-bc-mc-eth1 { type filter hook ingress device eth1 priority filter; }\012delete " -+ "chain netdev nm-mlag-bond0 rx-drop-bc-mc-eth1\012add set netdev nm-mlag-bond0 " -+ "macset-tagged { typeof ether saddr . vlan id; flags dynamic,timeout; }\012add set netdev " -+ "nm-mlag-bond0 macset-untagged { typeof ether saddr; flags dynamic,timeout; }\012add chain " -+ "netdev nm-mlag-bond0 tx-snoop-source-mac { type filter hook egress device bond0 priority " -+ "filter; }\012add rule netdev nm-mlag-bond0 tx-snoop-source-mac set update ether saddr . " -+ "vlan id timeout 5s @macset-tagged counter return\012add rule netdev nm-mlag-bond0 " -+ "tx-snoop-source-mac set update ether saddr timeout 5s @macset-untagged counter\012add " -+ "chain netdev nm-mlag-bond0 rx-drop-looped-packets { type filter hook ingress device bond0 " -+ "priority filter; }\012add rule netdev nm-mlag-bond0 rx-drop-looped-packets ether saddr . " -+ "vlan id @macset-tagged counter drop\012add rule netdev nm-mlag-bond0 " -+ "rx-drop-looped-packets ether type vlan counter return\012add rule netdev nm-mlag-bond0 " -+ "rx-drop-looped-packets ether saddr @macset-untagged counter drop\012"); -+ -+ _T(TRUE, -+ "bond0", -+ NM_MAKE_STRV("eth0"), -+ NM_MAKE_STRV("eth1"), -+ NM_MAKE_STRV("eth2"), -+ FALSE, -+ "add table netdev nm-mlag-eth0\012delete table netdev nm-mlag-eth0\012add table netdev " -+ "nm-mlag-bond0\012flush table netdev nm-mlag-bond0\012add chain netdev nm-mlag-bond0 " -+ "rx-drop-bc-mc-eth2 { type filter hook ingress device eth2 priority filter; }\012delete " -+ "chain netdev nm-mlag-bond0 rx-drop-bc-mc-eth2\012add chain netdev nm-mlag-bond0 " -+ "rx-drop-bc-mc-eth1 { type filter hook ingress device eth1 priority filter; }\012delete " -+ "chain netdev nm-mlag-bond0 rx-drop-bc-mc-eth1\012add set netdev nm-mlag-bond0 " -+ "macset-tagged { typeof ether saddr . vlan id; flags dynamic,timeout; }\012add set netdev " -+ "nm-mlag-bond0 macset-untagged { typeof ether saddr; flags dynamic,timeout; }\012add chain " -+ "netdev nm-mlag-bond0 tx-snoop-source-mac { type filter hook egress device bond0 priority " -+ "filter; }\012add rule netdev nm-mlag-bond0 tx-snoop-source-mac set update ether saddr . " -+ "vlan id timeout 5s @macset-tagged return\012add rule netdev nm-mlag-bond0 " -+ "tx-snoop-source-mac set update ether saddr timeout 5s @macset-untagged\012add chain netdev " -+ "nm-mlag-bond0 rx-drop-looped-packets { type filter hook ingress device bond0 priority " -+ "filter; }\012add rule netdev nm-mlag-bond0 rx-drop-looped-packets ether saddr . vlan id " -+ "@macset-tagged drop\012add rule netdev nm-mlag-bond0 rx-drop-looped-packets ether type " -+ "vlan return\012add rule netdev nm-mlag-bond0 rx-drop-looped-packets ether saddr " -+ "@macset-untagged drop\012"); -+ -+ _T(TRUE, -+ "bond0", -+ NM_MAKE_STRV("eth0", "eth1"), -+ NM_MAKE_STRV("eth2", "eth3"), -+ NM_MAKE_STRV("eth4", "eth5"), -+ FALSE, -+ "add table netdev nm-mlag-eth0\012delete table netdev nm-mlag-eth0\012add table netdev " -+ "nm-mlag-eth1\012delete table netdev nm-mlag-eth1\012add table netdev " -+ "nm-mlag-bond0\012flush table netdev nm-mlag-bond0\012add chain netdev nm-mlag-bond0 " -+ "rx-drop-bc-mc-eth4 { type filter hook ingress device eth4 priority filter; }\012delete " -+ "chain netdev nm-mlag-bond0 rx-drop-bc-mc-eth4\012add chain netdev nm-mlag-bond0 " -+ "rx-drop-bc-mc-eth5 { type filter hook ingress device eth5 priority filter; }\012delete " -+ "chain netdev nm-mlag-bond0 rx-drop-bc-mc-eth5\012add chain netdev nm-mlag-bond0 " -+ "rx-drop-bc-mc-eth2 { type filter hook ingress device eth2 priority filter; }\012delete " -+ "chain netdev nm-mlag-bond0 rx-drop-bc-mc-eth2\012add chain netdev nm-mlag-bond0 " -+ "rx-drop-bc-mc-eth3 { type filter hook ingress device eth3 priority filter; }\012add rule " -+ "netdev nm-mlag-bond0 rx-drop-bc-mc-eth3 pkttype { broadcast, multicast } drop\012add set " -+ "netdev nm-mlag-bond0 macset-tagged { typeof ether saddr . vlan id; flags dynamic,timeout; " -+ "}\012add set netdev nm-mlag-bond0 macset-untagged { typeof ether saddr; flags " -+ "dynamic,timeout; }\012add chain netdev nm-mlag-bond0 tx-snoop-source-mac { type filter " -+ "hook egress device bond0 priority filter; }\012add rule netdev nm-mlag-bond0 " -+ "tx-snoop-source-mac set update ether saddr . vlan id timeout 5s @macset-tagged " -+ "return\012add rule netdev nm-mlag-bond0 tx-snoop-source-mac set update ether saddr timeout " -+ "5s @macset-untagged\012add chain netdev nm-mlag-bond0 rx-drop-looped-packets { type filter " -+ "hook ingress device bond0 priority filter; }\012add rule netdev nm-mlag-bond0 " -+ "rx-drop-looped-packets ether saddr . vlan id @macset-tagged drop\012add rule netdev " -+ "nm-mlag-bond0 rx-drop-looped-packets ether type vlan return\012add rule netdev " -+ "nm-mlag-bond0 rx-drop-looped-packets ether saddr @macset-untagged drop\012"); -+ -+ _T(FALSE, -+ "bond0", -+ NM_MAKE_STRV("eth0", "eth1"), -+ NM_MAKE_STRV("eth2", "eth3"), -+ NM_MAKE_STRV("eth4", "eth5"), -+ FALSE, -+ "add table netdev nm-mlag-eth0\012delete table netdev nm-mlag-eth0\012add table netdev " -+ "nm-mlag-eth1\012delete table netdev nm-mlag-eth1\012add table netdev " -+ "nm-mlag-bond0\012delete table netdev nm-mlag-bond0\012"); -+} -+ -+/*****************************************************************************/ -+ - NMTST_DEFINE(); - - int -@@ -2654,5 +2774,7 @@ main(int argc, char **argv) - g_test_add_func("/core/general/test_kernel_cmdline_match_check", - test_kernel_cmdline_match_check); - -+ g_test_add_func("/core/test_nm_firewall_nft_stdio_mlag", test_nm_firewall_nft_stdio_mlag); -+ - return g_test_run(); - } --- -2.41.0 - - -From e981987cd4315c0d37f980b28c02c35340d81a2f Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Tue, 2 May 2023 08:54:21 +0200 -Subject: [PATCH 5/5] firewall: create "dynamic" sets for nft rules for - slb-bonding - -A workaround for a nftables issue ([1]). I don't know why that matters. - -[1] https://bugzilla.redhat.com/show_bug.cgi?id=2177667 - -Fixes: e9268e392418 ('firewall: add mlag firewall utils for multi chassis link aggregation (MLAG) for bonding-slb') - -https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1614 -(cherry picked from commit d3b54963622f242db1ebeda21dedd9558b484355) -(cherry picked from commit 0d9d753523bc30bfd42519e1716a2d7e447f011e) ---- - src/core/nm-firewall-utils.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/core/nm-firewall-utils.c b/src/core/nm-firewall-utils.c -index b8ae4397bf..ac12d3e432 100644 ---- a/src/core/nm-firewall-utils.c -+++ b/src/core/nm-firewall-utils.c -@@ -892,12 +892,12 @@ nm_firewall_nft_stdio_mlag(gboolean up, - */ - _append(&strbuf, - "add set netdev %s macset-tagged {" -- " typeof ether saddr . vlan id; flags timeout; " -+ " typeof ether saddr . vlan id; flags dynamic,timeout; " - "}", - table_name); - _append(&strbuf, - "add set netdev %s macset-untagged {" -- " typeof ether saddr; flags timeout;" -+ " typeof ether saddr; flags dynamic,timeout; " - "}", - table_name); - --- -2.41.0 - diff --git a/SOURCES/1006-assume-change-IPv6-method-from-ignore-rhbz2229671.patch b/SOURCES/1006-assume-change-IPv6-method-from-ignore-rhbz2229671.patch deleted file mode 100644 index 84e562b..0000000 --- a/SOURCES/1006-assume-change-IPv6-method-from-ignore-rhbz2229671.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 72fc1ef4c365cfda7fc0a86afd3ce124d57e8d5c Mon Sep 17 00:00:00 2001 -From: Wen Liang -Date: Mon, 17 Jul 2023 14:09:04 -0400 -Subject: [PATCH] assume: change IPv6 method from "ignore" and "disabled" into - "auto" - -IPv6 method "disabled" and "ignore" are not supported for loopback -device, when generating the assume connection, the generated connection -will fail verification. Therefore, change the IPv6 method into "auto", -as a result, for loopback external connection, NM will not toggle the -`disable_ipv6` sysctl setting when `systemd-sysctl` sets it into 1. - -https://bugzilla.redhat.com/show_bug.cgi?id=2207878 - -https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1694 -(cherry picked from commit e8a2306afbcd3e328f62004af92cd21b2477f0ac) -(cherry picked from commit 832e8df0c17f44be2c62485c19a0b20f6d3efa07) ---- - src/core/NetworkManagerUtils.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/src/core/NetworkManagerUtils.c b/src/core/NetworkManagerUtils.c -index 6f4c60f876..84ee6c3a0d 100644 ---- a/src/core/NetworkManagerUtils.c -+++ b/src/core/NetworkManagerUtils.c -@@ -1748,6 +1748,13 @@ nm_utils_platform_capture_ip_setting(NMPlatform *platform, - method = maybe_ipv6_disabled ? NM_SETTING_IP6_CONFIG_METHOD_DISABLED - : NM_SETTING_IP6_CONFIG_METHOD_IGNORE; - } -+ -+ /* The IPv6 method "ignore" and "disabled" are not supported for loopback */ -+ if (ifindex == 1 -+ && NM_IN_STRSET(method, -+ NM_SETTING_IP6_CONFIG_METHOD_DISABLED, -+ NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) -+ method = NM_SETTING_IP6_CONFIG_METHOD_AUTO; - g_object_set(s_ip, NM_SETTING_IP_CONFIG_METHOD, method, NULL); - - nmp_lookup_init_object_by_ifindex(&lookup, NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4), ifindex); --- -2.41.0 - diff --git a/SOURCES/1007-settings-preserve-existing-connection-flags-on-updat-rhbz2229671.patch b/SOURCES/1007-settings-preserve-existing-connection-flags-on-updat-rhbz2229671.patch deleted file mode 100644 index 8a114e9..0000000 --- a/SOURCES/1007-settings-preserve-existing-connection-flags-on-updat-rhbz2229671.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 895ed1ef14c49a94fb665e519bad409adf53c80f Mon Sep 17 00:00:00 2001 -From: Beniamino Galvani -Date: Mon, 27 Feb 2023 09:10:34 +0100 -Subject: [PATCH] settings: preserve existing connection flags on update - -We are passing to the plugin only 'sett_flags', which is the bitmask -of flags to change and works together with 'sett_mask'; however, -plugins interpret that value as the new flags value. The result is -that if there is no change needed (0/0), the existing flags are lost. -Simple reproducer: - - ip link add dummy1 type dummy - ip link set dummy1 up - ip addr add dev dummy1 fd01::12/64 - sleep 1 - - # now, a external connection is created by NM - - echo "BEFORE:" - cat /run/NetworkManager/system-connections/dummy1.nmconnection | grep "nm-generated\|volatile\|external" - - # just add a new address to the interface to make it lose - # the external flag - - ip addr add dev dummy1 172.25.42.1/24 - sleep 1 - - echo "AFTER:" - cat /run/NetworkManager/system-connections/dummy1.nmconnection | grep "nm-generated\|volatile\|external" - -Output: - - BEFORE: - nm-generated=true - volatile=true - external=true - AFTER: - -Fixes: d35d3c468a30 ('settings: rework tracking settings connections and settings plugins') - -https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1548 -(cherry picked from commit 86b922695f18566132980bd23516038b6ca4c0f4) -(cherry picked from commit 4353f842303d0d905c92e8e497e22f8440261381) ---- - src/core/settings/nm-settings.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/src/core/settings/nm-settings.c b/src/core/settings/nm-settings.c -index 63476c3c94..9995b490d2 100644 ---- a/src/core/settings/nm-settings.c -+++ b/src/core/settings/nm-settings.c -@@ -2009,6 +2009,7 @@ nm_settings_update_connection(NMSettings *self, - const char *uuid; - gboolean tombstone_in_memory = FALSE; - gboolean tombstone_on_disk = FALSE; -+ NMSettingsConnectionIntFlags new_flags; - - g_return_val_if_fail(NM_IS_SETTINGS(self), FALSE); - g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(sett_conn), FALSE); -@@ -2228,13 +2229,16 @@ nm_settings_update_connection(NMSettings *self, - } - } - -+ new_flags = nm_settings_connection_get_flags(sett_conn); -+ new_flags = NM_FLAGS_ASSIGN_MASK(new_flags, sett_mask, sett_flags); -+ - if (!update_storage) { - success = _add_connection_to_first_plugin(self, - plugin_name, - sett_conn_entry, - connection, - new_in_memory, -- sett_flags, -+ new_flags, - new_shadowed_storage_filename, - new_shadowed_owned, - &new_storage, -@@ -2245,7 +2249,7 @@ nm_settings_update_connection(NMSettings *self, - success = _update_connection_to_plugin(self, - update_storage, - connection, -- sett_flags, -+ new_flags, - update_reason, - new_shadowed_storage_filename, - new_shadowed_owned, --- -2.41.0 - diff --git a/SPECS/NetworkManager.spec b/SPECS/NetworkManager.spec index 4da7924..4ccfc53 100644 --- a/SPECS/NetworkManager.spec +++ b/SPECS/NetworkManager.spec @@ -1,12 +1,12 @@ %global wpa_supplicant_version 1:1.1 -%global ppp_version %(sed -n 's/^#define\\s*VERSION\\s*"\\([^\\s]*\\)"$/\\1/p' %{_includedir}/pppd/patchlevel.h 2>/dev/null | grep . || echo bad) +%global ppp_version %(pkg-config --modversion pppd 2>/dev/null || sed -n 's/^#define\\s*VERSION\\s*"\\([^\\s]*\\)"$/\\1/p' %{_includedir}/pppd/patchlevel.h 2>/dev/null | grep . || echo bad) %global glib2_version %(pkg-config --modversion glib-2.0 2>/dev/null || echo bad) %global epoch_version 1 -%global real_version 1.42.2 +%global real_version 1.44.0 %global rpm_version %{real_version} -%global release_version 8 +%global release_version 3 %global snapshot %{nil} %global git_sha %{nil} %global bcond_default_debug 0 @@ -202,14 +202,8 @@ Source7: readme-ifcfg-rh.txt # Patch0001: 0001-some.patch # Bugfixes that are only relevant until next rebase of the package. -# Patch1001: 1001-some.patch -Patch1001: 1001-ipv6ll-don-t-regenerate-the-address-when-removed-rh2196441.patch -Patch1002: 1002-Revert-infiniband-avoid-normalizing-the-p-key-rh2209976.patch -Patch1003: 1003-unblock-autoconnect-upon-reapply-rh2217903.patch -Patch1004: 1004-core-fix-l3cd-comparison-rhbz2219847.patch -Patch1005: 1005-firewall-create-dynamic-sets-rhbz2220952.patch -Patch1006: 1006-assume-change-IPv6-method-from-ignore-rhbz2229671.patch -Patch1007: 1007-settings-preserve-existing-connection-flags-on-updat-rhbz2229671.patch +Patch1001: 1001-nm-manager-ensure-device-is-exported-on-D-Bus-in-aut-rhbz2210271.patch +Patch1002: 1002-checkpoint-Fix-segfault-crash-when-rollback-rhel-1526.patch Requires(post): systemd %if 0%{?fedora} || 0%{?rhel} >= 8 @@ -598,8 +592,8 @@ Requires: %{name}-libnm%{?_isa} = %{epoch}:%{version}-%{release} %description cloud-setup Installs a nm-cloud-setup tool that can automatically configure -NetworkManager in cloud setups. Currently only EC2 is supported. -This tool is still experimental. +NetworkManager in cloud environment. Only certain cloud providers +like Aliyun, Azure, EC2, GCP are supported. %endif @@ -732,9 +726,9 @@ Preferably use nmcli instead. -Difcfg_rh=true \ -Difupdown=false \ %if %{with ppp} - -Dpppd_plugin_dir="%{_libdir}/pppd/%{ppp_version}" \ - -Dpppd="%{_sbindir}/pppd" \ -Dppp=true \ + -Dpppd="%{_sbindir}/pppd" \ + -Dpppd_plugin_dir="%{_libdir}/pppd/%{ppp_version}" \ %else -Dppp=false \ %endif @@ -1246,6 +1240,7 @@ fi %{_unitdir}/nm-cloud-setup.timer %{nmlibdir}/dispatcher.d/90-nm-cloud-setup.sh %{nmlibdir}/dispatcher.d/no-wait.d/90-nm-cloud-setup.sh +%{nmlibdir}/dispatcher.d/pre-up.d/90-nm-cloud-setup.sh %{_mandir}/man8/nm-cloud-setup.8* %endif @@ -1258,30 +1253,88 @@ fi %changelog -* Wed Aug 16 2023 Fernando Fernandez Mancera - 1:1.42.2-8 -- settings: preserve existing connection flags on update (rh #2229671) - -* Mon Aug 14 2023 Fernando Fernandez Mancera - 1:1.42.2-7 -- assume: change IPv6 method from "ignore" and "disabled" into "auto" (rh #2229671) - -* Wed Jul 12 2023 Fernando Fernandez Mancera - 1:1.42.2-6 -- firewall: create "dynamic" sets for nft rules for slb-bonding (rh #2220952) - -* Wed Jul 5 2023 Wen Liang - 1:1.42.2-5 -- make sure that the IP and DNS configuration gets applied when it changes (rh #2219847) - -* Thu Jun 29 2023 Gris Ge - 1:1.42.2-4 -- unblock autoconnect upon reapply finish (rh #2217903) - -* Mon May 29 2023 Wen Liang - 1:1.42.2-3 -- revert "infiniband: avoid normalizing the p-key when reading from ifcfg" (rh #2209976) - -* Tue May 23 2023 Beniamino Galvani - 1:1.42.2-2 -- don't fail when the IPv6 link-local address is removed (rh #2196441) - -* Wed Mar 15 2023 MSVSphere Packaging Team - 1.40.0-1 +* Wed Aug 30 2023 Fernando Fernandez Mancera - 1:1.44.0-3 +- checkpoint: Fix segfault crash when rollback (rhel-1526) + +* Wed Aug 23 2023 Fernando Fernandez Mancera - 1:1.44.0-2 +- manager: ensure device is exported on D-Bus in authentication request (rh #2210271) + +* Thu Aug 10 2023 Fernando Fernandez Mancera - 1:1.44.0-1 +- update to 1.44.0 release +- nmcli: add nmcli version mismatch warning (rh #2173196) +- checkpoint: preserve devices that were removed and readded (rh #2177590) + +* Wed Jul 26 2023 Wen Liang - 1:1.43.90-1 +- update to 1.43.90 release (release candidate) +- manager: allow controller activation if device is deactivating (rh #2125615) +- assume: change IPv6 method from "ignore" and "disabled" into "auto" for loopback device (rh #2207878) +- device: delete software device when lose carrier and is controller (rh #2224479) +- core: better handle ignore-carrier=no for bond/bridge/team devices (rh #2180363) + +* Wed Jul 12 2023 Beniamino Galvani - 1:1.43.11-1 +- update to 1.43.11 release (development) +- fix assertion about missing ifindex when resetting MAC (rh #2215022) +- fix wrong order of entries in resolv.conf after reconnect (rh #2218448) +- do not fail activation when SR-IOV VF parameters can't be applied (rh #2210164) +- warn that the ifcfg-rh plugin is deprecated (rh #2190375) + +* Wed Jun 14 2023 Thomas Haller - 1:1.43.10-1 +- Update to 1.43.10 release (development) +- fix reading infiniband p-key from ifcfg files (rh #2209974) +- improve autoconnect when selecting controller (rh #2121451) +- fix managing devices after network reconnect (rh #2149012) +- better handle ignore-carrier for bond/bridge/team (rh #2180363) +- cloud-setup: block wait-online while configuration is ongoing (rh #2151040) +- cloud-setup: avoid leaving half configured system (rh #2207812) +- cloud-setup: log warning when no provider detected (rh #2214880) +- cloud-setup: fix RPM description (rh #2214491) + +* Wed May 31 2023 Thomas Haller - 1:1.43.9-1 +- Update to 1.43.9 release (development) +- improve autoconnect logic for port/controller configurations (rh #2121451) +- fix handling external devices during network off/on (rh #2149012) + +* Tue May 16 2023 Beniamino Galvani - 1:1.43.8-1 +- Update to 1.43.8 release (development) +- ipv6ll: don't regenerate the address when it's removed externally (rh #2196441) + +* Wed May 3 2023 Thomas Haller - 1:1.43.7-1 +- Update to 1.43.7 release (development) +- bond: support port priorities (rh #2152304) +- ovs: fix autoconnect race (rh #2152864) + +* Wed Apr 19 2023 Beniamino Galvani - 1:1.43.6-1 +- Update to 1.43.6 release (development) +- fix assertion failure when renewing DHCP lease (rh #2179890) +- emit the dhcp-change dispatcher script event on lease renewal (rh #2179537) +- ensure the NetworkManager is restarted when dbus is restarted (rh #2161915) +- add support for the "no-aaaa" resolv.conf option (rh #2176137) - + +* Wed Apr 05 2023 Lubomir Rintel - 1:1.43.5-1 +- Update to 1.43.5 release (development) +- cloud-init/ec2: use right HTTP method for IMDSv2 (rh #2179718) +- core: request a bus name only when dbus objects are present (rh #2175919) +- core: fix autoconnect retry count tracking (rh #2174353) +- core: fix retry on netlink socket buffer exhaustion (rh #2169512) +- ovs: fix a race condition on port detachment (rh #2054933) + +* Wed Mar 22 2023 Thomas Haller - 1:1.43.4-1 +- Update to 1.43.4 release (development) +- core: fix handling of IPv4 prefsrc routes with ACD (rh #2046293) +- core: don't configure static routes without addresses (rh #2102212) +- core: fix race activating VLAN devices (rh #2155991) + +* Wed Mar 15 2023 MSVSphere Packaging Team - 1:1.43.3-1 - Rebuilt for MSVSphere 9.1. +* Thu Mar 09 2023 Lubomir Rintel - 1:1.43.3-1 +- Update to an early 1.44 snapshot +- cloud-setup: add IDMSv2 support (rh #2151986) +- core: add [link] setting (rh #2158328) +- dhcp: expose client ID, DUID and IAID that have been used (rh #2169869) +- ovs: ensure device has a proper MAC address once we start dhcp (rh #2168477) +- team: fix assumption of team port management (rh #2092215) + * Thu Feb 23 2023 Beniamino Galvani - 1:1.42.2-1 - Update to 1.42.2 release - fix hostname lookup from IPv6 address (rh #2167816) @@ -1292,7 +1345,7 @@ fi * Fri Feb 10 2023 Thomas Haller - 1:1.42.0-1 - Update to 1.42.0 release -* Thu Jan 26 2023 Lubomir Rintel - - 1:1.41.91-1 +* Thu Jan 26 2023 Lubomir Rintel - 1:1.41.91-1 - Update to 1.41.91 release (release candidate) - core: retry if a rtnetlink socket runs out of buffer space (rh #2154350) - dns: allow changing resolv.conf options alone via global-dns (rh #2019306) From 9e619dc366b4c0c6ac2cd5bc4a5d78809d05870a Mon Sep 17 00:00:00 2001 From: MSVSphere Packaging Team Date: Thu, 25 Jan 2024 03:32:33 +0300 Subject: [PATCH 3/6] import NetworkManager-1.44.0-4.el9_3 --- ...etter-way-for-dns-changes-RHEL-14889.patch | 310 ++++++++++++++++++ SPECS/NetworkManager.spec | 6 +- 2 files changed, 315 insertions(+), 1 deletion(-) create mode 100644 SOURCES/1003-better-way-for-dns-changes-RHEL-14889.patch diff --git a/SOURCES/1003-better-way-for-dns-changes-RHEL-14889.patch b/SOURCES/1003-better-way-for-dns-changes-RHEL-14889.patch new file mode 100644 index 0000000..75a3daa --- /dev/null +++ b/SOURCES/1003-better-way-for-dns-changes-RHEL-14889.patch @@ -0,0 +1,310 @@ +From a3e39a3bf9667bb69fb2f37b605caffbd969889a Mon Sep 17 00:00:00 2001 +From: Gris Ge +Date: Tue, 26 Sep 2023 15:00:32 +0800 +Subject: [PATCH 1/2] emit DNS CONFIG_CHANGED signal even dns=none + +Instruct the `NMDnsManager` to emit `CONFIG_CHANGED` signal even +`dns=none` or failed to modify `/etc/resolv.conf`. + +The `NMPolicy` will only update hostname when DNS is managed. + +Signed-off-by: Gris Ge +(cherry picked from commit a847ba807572c3ef3682e833432f2f93e9d519a0) +(cherry picked from commit d10f20fd01a7bb3225c7e38ed80449e19156344b) +--- + src/core/dns/nm-dns-manager.c | 12 +++++++++++- + src/core/dns/nm-dns-manager.h | 2 ++ + src/core/nm-policy.c | 10 ++++++---- + 3 files changed, 19 insertions(+), 5 deletions(-) + +diff --git a/src/core/dns/nm-dns-manager.c b/src/core/dns/nm-dns-manager.c +index 535646930c..231ef72f49 100644 +--- a/src/core/dns/nm-dns-manager.c ++++ b/src/core/dns/nm-dns-manager.c +@@ -1948,7 +1948,7 @@ plugin_skip:; + } + + /* signal that DNS resolution configs were changed */ +- if ((do_update || caching || force_emit) && result == SR_SUCCESS) ++ if ((caching || force_emit) && result == SR_SUCCESS) + g_signal_emit(self, signals[CONFIG_CHANGED], 0); + + nm_clear_pointer(&priv->config_variant, g_variant_unref); +@@ -1964,6 +1964,16 @@ plugin_skip:; + return TRUE; + } + ++gboolean ++nm_dns_manager_is_unmanaged(NMDnsManager *self) ++{ ++ NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE(self); ++ ++ return NM_IN_SET(priv->rc_manager, ++ NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED, ++ NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE); ++} ++ + /*****************************************************************************/ + + gboolean +diff --git a/src/core/dns/nm-dns-manager.h b/src/core/dns/nm-dns-manager.h +index 42f9dec588..9b8c2972b4 100644 +--- a/src/core/dns/nm-dns-manager.h ++++ b/src/core/dns/nm-dns-manager.h +@@ -148,4 +148,6 @@ char *nmtst_dns_create_resolv_conf(const char *const *searches, + const char *const *nameservers, + const char *const *options); + ++gboolean nm_dns_manager_is_unmanaged(NMDnsManager *self); ++ + #endif /* __NETWORKMANAGER_DNS_MANAGER_H__ */ +diff --git a/src/core/nm-policy.c b/src/core/nm-policy.c +index efdb06360f..1cf6b3398d 100644 +--- a/src/core/nm-policy.c ++++ b/src/core/nm-policy.c +@@ -2635,11 +2635,13 @@ dns_config_changed(NMDnsManager *dns_manager, gpointer user_data) + if (priv->updating_dns) + return; + +- nm_manager_for_each_device (priv->manager, device, tmp_lst) { +- nm_device_clear_dns_lookup_data(device, "DNS configuration changed"); +- } ++ if (!nm_dns_manager_is_unmanaged(dns_manager)) { ++ nm_manager_for_each_device (priv->manager, device, tmp_lst) { ++ nm_device_clear_dns_lookup_data(device, "DNS configuration changed"); ++ } + +- update_system_hostname(self, "DNS configuration changed"); ++ update_system_hostname(self, "DNS configuration changed"); ++ } + } + + static void +-- +2.41.0 + + +From de4c05300e25b49bf077ac7929622f2721815b29 Mon Sep 17 00:00:00 2001 +From: Gris Ge +Date: Tue, 26 Sep 2023 17:14:58 +0800 +Subject: [PATCH 2/2] dispatch `dns-change` dispatcher event + +Introducing new dispatcher event -- `dns-change` which will be emitted when +DNS configuration changed(even in `dns=none` mode). This is to solve two +use cases: + * Invoke dispatch script for DNS changes triggered by the global DNS + API. + + * Do not invoke [OpenShift resolv-prepender][1] for non-DNS changes. + +Bug reference: https://issues.redhat.com/browse/RHEL-1671 + +[1]: https://github.com/openshift/machine-config-operator/blob/master/templates/common/on-prem/files/resolv-prepender.yaml + +Signed-off-by: Gris Ge +(cherry picked from commit a1db61ebc9712d1faf2ef8f1b2cb14cd819346d3) +(cherry picked from commit 3cdce71b95cea11bf409d9353c35a4dea6f33984) +--- + man/NetworkManager-dispatcher.xml | 15 +++++- + src/core/nm-dispatcher.c | 51 ++++++++++++++++--- + src/core/nm-dispatcher.h | 3 ++ + src/core/nm-policy.c | 2 + + src/libnm-core-aux-extern/nm-dispatcher-api.h | 1 + + src/nm-dispatcher/nm-dispatcher-utils.c | 8 ++- + 6 files changed, 69 insertions(+), 11 deletions(-) + +diff --git a/man/NetworkManager-dispatcher.xml b/man/NetworkManager-dispatcher.xml +index 036b3c8dcc..e87226d05e 100644 +--- a/man/NetworkManager-dispatcher.xml ++++ b/man/NetworkManager-dispatcher.xml +@@ -68,8 +68,9 @@ + device an operation just happened on, and second the action. For device actions, + the interface is the name of the kernel interface suitable for IP configuration. + Thus it is either VPN_IP_IFACE, DEVICE_IP_IFACE, or DEVICE_IFACE, as applicable. +- For the hostname action the device name is always "none" +- and for connectivity-change it is empty. ++ For the hostname action the device name is always "none". ++ For connectivity-change it is empty. ++ For dns-change it is empty. + + The actions are: + +@@ -170,6 +171,16 @@ + The connection was reapplied on the device. + + ++ ++ dns-change ++ ++ The DNS configuration has changed. This action is raised even if ++ NetworkManager is configured to not manage resolv.conf (for example, ++ via dns=none). In such case, the dispatch script can discover the ++ DNS configuration provided by currently active connections by ++ looking at file /run/NetworkManager/resolv.conf ++ ++ + + + The environment contains more information about the interface and the connection. +diff --git a/src/core/nm-dispatcher.c b/src/core/nm-dispatcher.c +index cdc07dd60e..9aa4194e83 100644 +--- a/src/core/nm-dispatcher.c ++++ b/src/core/nm-dispatcher.c +@@ -50,6 +50,8 @@ + } \ + G_STMT_END + ++static gboolean nm_dispatcher_need_device(NMDispatcherAction action); ++ + /*****************************************************************************/ + + struct NMDispatcherCallId { +@@ -469,7 +471,8 @@ static const char *action_table[] = {[NM_DISPATCHER_ACTION_HOSTNAME] = NMD_ + [NM_DISPATCHER_ACTION_DHCP_CHANGE_6] = NMD_ACTION_DHCP6_CHANGE, + [NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE] = + NMD_ACTION_CONNECTIVITY_CHANGE, +- [NM_DISPATCHER_ACTION_REAPPLY] = NMD_ACTION_REAPPLY}; ++ [NM_DISPATCHER_ACTION_REAPPLY] = NMD_ACTION_REAPPLY, ++ [NM_DISPATCHER_ACTION_DNS_CHANGE] = NMD_ACTION_DNS_CHANGE}; + + static const char * + action_to_string(NMDispatcherAction action) +@@ -530,9 +533,7 @@ _dispatcher_call(NMDispatcherAction action, + if (G_UNLIKELY(!request_id)) + request_id = ++gl.request_id_counter; + +- /* All actions except 'hostname' and 'connectivity-change' require a device */ +- if (action == NM_DISPATCHER_ACTION_HOSTNAME +- || action == NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE) { ++ if (!nm_dispatcher_need_device(action)) { + _LOG2D(request_id, + log_ifname, + log_con_uuid, +@@ -592,9 +593,8 @@ _dispatcher_call(NMDispatcherAction action, + g_variant_builder_init(&vpn_ip4_props, G_VARIANT_TYPE_VARDICT); + g_variant_builder_init(&vpn_ip6_props, G_VARIANT_TYPE_VARDICT); + +- /* hostname and connectivity-change actions don't send device data */ +- if (action != NM_DISPATCHER_ACTION_HOSTNAME +- && action != NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE) { ++ /* hostname, DNS and connectivity-change actions don't send device data */ ++ if (nm_dispatcher_need_device(action)) { + fill_device_props(device, + &device_props, + &device_proxy_props, +@@ -925,6 +925,30 @@ nm_dispatcher_call_connectivity(NMConnectivityState connectivity_state, + out_call_id); + } + ++/** ++ * nm_dispatcher_call_dns_change(): ++ * ++ * This method does not block the caller. ++ * ++ * Returns: %TRUE if the action was dispatched, %FALSE on failure ++ */ ++gboolean ++nm_dispatcher_call_dns_change(void) ++{ ++ return _dispatcher_call(NM_DISPATCHER_ACTION_DNS_CHANGE, ++ FALSE, ++ NULL, ++ NULL, ++ NULL, ++ FALSE, ++ NM_CONNECTIVITY_UNKNOWN, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL); ++} ++ + void + nm_dispatcher_call_cancel(NMDispatcherCallId *call_id) + { +@@ -937,3 +961,16 @@ nm_dispatcher_call_cancel(NMDispatcherCallId *call_id) + _LOG3D(call_id, "cancelling dispatcher callback action"); + call_id->callback = NULL; + } ++ ++/* All actions except 'hostname', 'connectivity-change' and 'dns-change' require ++ * a device */ ++static gboolean ++nm_dispatcher_need_device(NMDispatcherAction action) ++{ ++ if (action == NM_DISPATCHER_ACTION_HOSTNAME ++ || action == NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE ++ || action == NM_DISPATCHER_ACTION_DNS_CHANGE) { ++ return FALSE; ++ } ++ return TRUE; ++} +diff --git a/src/core/nm-dispatcher.h b/src/core/nm-dispatcher.h +index 3071639922..a1cb96b798 100644 +--- a/src/core/nm-dispatcher.h ++++ b/src/core/nm-dispatcher.h +@@ -23,6 +23,7 @@ typedef enum { + NM_DISPATCHER_ACTION_DHCP_CHANGE_6, + NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE, + NM_DISPATCHER_ACTION_REAPPLY, ++ NM_DISPATCHER_ACTION_DNS_CHANGE, + } NMDispatcherAction; + + #define NM_DISPATCHER_ACTION_DHCP_CHANGE_X(IS_IPv4) \ +@@ -69,6 +70,8 @@ gboolean nm_dispatcher_call_connectivity(NMConnectivityState state, + gpointer user_data, + NMDispatcherCallId **out_call_id); + ++gboolean nm_dispatcher_call_dns_change(void); ++ + void nm_dispatcher_call_cancel(NMDispatcherCallId *call_id); + + #endif /* __NM_DISPATCHER_H__ */ +diff --git a/src/core/nm-policy.c b/src/core/nm-policy.c +index 1cf6b3398d..2873847df3 100644 +--- a/src/core/nm-policy.c ++++ b/src/core/nm-policy.c +@@ -2642,6 +2642,8 @@ dns_config_changed(NMDnsManager *dns_manager, gpointer user_data) + + update_system_hostname(self, "DNS configuration changed"); + } ++ ++ nm_dispatcher_call_dns_change(); + } + + static void +diff --git a/src/libnm-core-aux-extern/nm-dispatcher-api.h b/src/libnm-core-aux-extern/nm-dispatcher-api.h +index 56da5fba7a..7cb370a92e 100644 +--- a/src/libnm-core-aux-extern/nm-dispatcher-api.h ++++ b/src/libnm-core-aux-extern/nm-dispatcher-api.h +@@ -34,6 +34,7 @@ + #define NMD_ACTION_DHCP6_CHANGE "dhcp6-change" + #define NMD_ACTION_CONNECTIVITY_CHANGE "connectivity-change" + #define NMD_ACTION_REAPPLY "reapply" ++#define NMD_ACTION_DNS_CHANGE "dns-change" + + typedef enum { + DISPATCH_RESULT_UNKNOWN = 0, +diff --git a/src/nm-dispatcher/nm-dispatcher-utils.c b/src/nm-dispatcher/nm-dispatcher-utils.c +index 74ea4e4001..f8a4c28000 100644 +--- a/src/nm-dispatcher/nm-dispatcher-utils.c ++++ b/src/nm-dispatcher/nm-dispatcher-utils.c +@@ -453,8 +453,12 @@ nm_dispatcher_utils_construct_envp(const char *action, + + items = g_ptr_array_new_with_free_func(g_free); + +- /* Hostname and connectivity changes don't require a device nor contain a connection */ +- if (NM_IN_STRSET(action, NMD_ACTION_HOSTNAME, NMD_ACTION_CONNECTIVITY_CHANGE)) ++ /* Hostname, dns and connectivity changes don't require a device nor contain ++ * a connection */ ++ if (NM_IN_STRSET(action, ++ NMD_ACTION_HOSTNAME, ++ NMD_ACTION_CONNECTIVITY_CHANGE, ++ NMD_ACTION_DNS_CHANGE)) + goto done; + + /* Connection properties */ +-- +2.41.0 + diff --git a/SPECS/NetworkManager.spec b/SPECS/NetworkManager.spec index 4ccfc53..dc7acc1 100644 --- a/SPECS/NetworkManager.spec +++ b/SPECS/NetworkManager.spec @@ -6,7 +6,7 @@ %global epoch_version 1 %global real_version 1.44.0 %global rpm_version %{real_version} -%global release_version 3 +%global release_version 4 %global snapshot %{nil} %global git_sha %{nil} %global bcond_default_debug 0 @@ -204,6 +204,7 @@ Source7: readme-ifcfg-rh.txt # Bugfixes that are only relevant until next rebase of the package. Patch1001: 1001-nm-manager-ensure-device-is-exported-on-D-Bus-in-aut-rhbz2210271.patch Patch1002: 1002-checkpoint-Fix-segfault-crash-when-rollback-rhel-1526.patch +Patch1003: 1003-better-way-for-dns-changes-RHEL-14889.patch Requires(post): systemd %if 0%{?fedora} || 0%{?rhel} >= 8 @@ -1253,6 +1254,9 @@ fi %changelog +* Fri Nov 17 2023 Íñigo Huguet - 1:1.44.0-4 +- Add 'dns-change' dispatch event (RHEL-14889) + * Wed Aug 30 2023 Fernando Fernandez Mancera - 1:1.44.0-3 - checkpoint: Fix segfault crash when rollback (rhel-1526) From 3ad63e35f84eb9e73e77024102b228dc1da685fb Mon Sep 17 00:00:00 2001 From: MSVSphere Packaging Team Date: Wed, 6 Mar 2024 03:33:34 +0300 Subject: [PATCH 4/6] import NetworkManager-1.44.0-5.el9_3 --- ...ring-resetting-in-reapply-RHEL-25061.patch | 270 ++++++++++++++++++ SPECS/NetworkManager.spec | 6 +- 2 files changed, 275 insertions(+), 1 deletion(-) create mode 100644 SOURCES/1004-bridge-skip-VLAN-filtering-resetting-in-reapply-RHEL-25061.patch diff --git a/SOURCES/1004-bridge-skip-VLAN-filtering-resetting-in-reapply-RHEL-25061.patch b/SOURCES/1004-bridge-skip-VLAN-filtering-resetting-in-reapply-RHEL-25061.patch new file mode 100644 index 0000000..7ed37c2 --- /dev/null +++ b/SOURCES/1004-bridge-skip-VLAN-filtering-resetting-in-reapply-RHEL-25061.patch @@ -0,0 +1,270 @@ +From 8f8845484ee74b1934cbd5f0cca997ba0504d543 Mon Sep 17 00:00:00 2001 +From: Gris Ge +Date: Thu, 8 Feb 2024 23:36:34 +0800 +Subject: [PATCH] bridge: skip VLAN filtering resetting in reapply if no vlan + change changed + +When doing reapply on linux bridge interface, NetworkManager will reset +the VLAN filtering and default PVID which cause PVID been readded to all +bridge ports regardless they are managed by NetworkManager. + +This is because Linux kernel will re-add PVID to bridge port upon the +changes of bridge default-pvid value. + +To fix the issue, this patch introduce netlink parsing code for +`vlan_filtering` and `default_pvid` of NMPlatformLnkBridge, and use that +to compare desired VLAN filtering settings, skip the reset of VLAN +filter if `default_pvid` and `vlan_filtering` are unchanged. + +Signed-off-by: Gris Ge +(cherry picked from commit 02c34d538c6a2b22bd09318496ba104eb43246b4) +(cherry picked from commit f990f9b4e4ffb5195fc89c4a8c6f251c0e01b501) +(cherry picked from commit c448e225198f7f8851fc01a8394529e7cbe25d4d) +--- + src/core/devices/nm-device-bridge.c | 79 +++++++++++++++++--------- + src/core/platform/tests/test-link.c | 2 + + src/libnm-platform/nm-linux-platform.c | 6 ++ + src/libnm-platform/nm-platform.c | 13 ++++- + src/libnm-platform/nm-platform.h | 2 + + 5 files changed, 72 insertions(+), 30 deletions(-) + +diff --git a/src/core/devices/nm-device-bridge.c b/src/core/devices/nm-device-bridge.c +index 9a45dbf3fc..73effc50b4 100644 +--- a/src/core/devices/nm-device-bridge.c ++++ b/src/core/devices/nm-device-bridge.c +@@ -712,7 +712,27 @@ master_update_slave_connection(NMDevice *device, + } + + static gboolean +-bridge_set_vlan_options(NMDevice *device, NMSettingBridge *s_bridge) ++is_bridge_pvid_changed(NMDevice *device, NMSettingBridge *s_bridge) ++{ ++ int ifindex = nm_device_get_ifindex(device); ++ const NMPlatformLnkBridge *nmp_link_br; ++ NMPlatform *platform = nm_device_get_platform(device); ++ bool desired_vlan_filtering = nm_setting_bridge_get_vlan_filtering(s_bridge); ++ guint16 desired_pvid = nm_setting_bridge_get_vlan_default_pvid(s_bridge); ++ ++ nm_platform_link_refresh(platform, ifindex); ++ nmp_link_br = nm_platform_link_get_lnk_bridge(platform, ifindex, NULL); ++ ++ if (nmp_link_br) { ++ return desired_vlan_filtering != nmp_link_br->vlan_filtering ++ || desired_pvid != nmp_link_br->default_pvid; ++ } else { ++ return TRUE; ++ } ++} ++ ++static gboolean ++bridge_set_vlan_options(NMDevice *device, NMSettingBridge *s_bridge, gboolean is_reapply) + { + NMDeviceBridge *self = NM_DEVICE_BRIDGE(device); + gconstpointer hwaddr; +@@ -753,31 +773,37 @@ bridge_set_vlan_options(NMDevice *device, NMSettingBridge *s_bridge) + + self->vlan_configured = TRUE; + +- /* Filtering must be disabled to change the default PVID. +- * Clear the default PVID so that we later can force the re-creation of +- * default PVID VLANs by writing the option again. */ +- +- nm_platform_link_set_bridge_info( +- plat, +- ifindex, +- &((NMPlatformLinkSetBridgeInfoData){.vlan_filtering_has = TRUE, +- .vlan_filtering_val = FALSE, +- .vlan_default_pvid_has = TRUE, +- .vlan_default_pvid_val = 0})); ++ if (!is_reapply || is_bridge_pvid_changed(device, s_bridge)) { ++ /* Filtering must be disabled to change the default PVID. ++ * Clear the default PVID so that we later can force the re-creation of ++ * default PVID VLANs by writing the option again. */ + +- /* Clear all existing VLANs */ +- if (!nm_platform_link_set_bridge_vlans(plat, ifindex, FALSE, NULL)) +- return FALSE; ++ if (is_reapply) { ++ _LOGD(LOGD_BRIDGE, "default_pvid is changed, resetting bridge VLAN filtering"); ++ } + +- /* Now set the default PVID. After this point the kernel creates +- * a PVID VLAN on each port, including the bridge itself. */ +- pvid = nm_setting_bridge_get_vlan_default_pvid(s_bridge); +- if (pvid) { + nm_platform_link_set_bridge_info( + plat, + ifindex, +- &((NMPlatformLinkSetBridgeInfoData){.vlan_default_pvid_has = TRUE, +- .vlan_default_pvid_val = pvid})); ++ &((NMPlatformLinkSetBridgeInfoData){.vlan_filtering_has = TRUE, ++ .vlan_filtering_val = FALSE, ++ .vlan_default_pvid_has = TRUE, ++ .vlan_default_pvid_val = 0})); ++ ++ /* Clear all existing VLANs */ ++ if (!nm_platform_link_set_bridge_vlans(plat, ifindex, FALSE, NULL)) ++ return FALSE; ++ ++ /* Now set the default PVID. After this point the kernel creates ++ * a PVID VLAN on each port, including the bridge itself. */ ++ pvid = nm_setting_bridge_get_vlan_default_pvid(s_bridge); ++ if (pvid) { ++ nm_platform_link_set_bridge_info( ++ plat, ++ ifindex, ++ &((NMPlatformLinkSetBridgeInfoData){.vlan_default_pvid_has = TRUE, ++ .vlan_default_pvid_val = pvid})); ++ } + } + + /* Create VLANs only after setting the default PVID, so that +@@ -836,7 +862,7 @@ _platform_lnk_bridge_init_from_setting(NMSettingBridge *s_bridge, NMPlatformLnkB + } + + static gboolean +-link_config(NMDevice *device, NMConnection *connection) ++link_config(NMDevice *device, NMConnection *connection, gboolean is_reapply) + { + int ifindex = nm_device_get_ifindex(device); + NMSettingBridge *s_bridge; +@@ -850,7 +876,7 @@ link_config(NMDevice *device, NMConnection *connection) + if (nm_platform_link_bridge_change(nm_device_get_platform(device), ifindex, &props) < 0) + return FALSE; + +- return bridge_set_vlan_options(device, s_bridge); ++ return bridge_set_vlan_options(device, s_bridge, is_reapply); + } + + static NMActStageReturn +@@ -861,7 +887,7 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) + connection = nm_device_get_applied_connection(device); + g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE); + +- if (!link_config(device, connection)) { ++ if (!link_config(device, connection, FALSE)) { + NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED); + return NM_ACT_STAGE_RETURN_FAILURE; + } +@@ -1003,7 +1029,7 @@ attach_port(NMDevice *device, + s_port = nm_connection_get_setting_bridge_port(connection); + + if (!nm_device_sys_iface_state_is_external(device)) +- bridge_set_vlan_options(device, s_bridge); ++ bridge_set_vlan_options(device, s_bridge, FALSE); + + if (nm_setting_bridge_get_vlan_filtering(s_bridge)) { + gs_free const NMPlatformBridgeVlan **plat_vlans = NULL; +@@ -1218,8 +1244,7 @@ reapply_connection(NMDevice *device, NMConnection *con_old, NMConnection *con_ne + /* Make sure bridge_set_vlan_options() called by link_config() + * sets vlan_filtering and default_pvid anew. */ + self->vlan_configured = FALSE; +- +- link_config(device, con_new); ++ link_config(device, con_new, TRUE); + } + + /*****************************************************************************/ +diff --git a/src/core/platform/tests/test-link.c b/src/core/platform/tests/test-link.c +index 8a54ac4853..fdece007bc 100644 +--- a/src/core/platform/tests/test-link.c ++++ b/src/core/platform/tests/test-link.c +@@ -1403,6 +1403,8 @@ test_software_detect(gconstpointer user_data) + lnk_bridge.mcast_query_interval = 12000; + lnk_bridge.mcast_query_response_interval = 5200; + lnk_bridge.mcast_startup_query_interval = 3000; ++ lnk_bridge.vlan_filtering = FALSE; ++ lnk_bridge.default_pvid = 1; + + if (!nmtstp_link_bridge_add(NULL, ext, DEVICE_NAME, &lnk_bridge)) + g_error("Failed adding Bridge interface"); +diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c +index 99eab9c784..9b4ac14024 100644 +--- a/src/libnm-platform/nm-linux-platform.c ++++ b/src/libnm-platform/nm-linux-platform.c +@@ -1515,6 +1515,8 @@ _parse_lnk_bridge(const char *kind, struct nlattr *info_data) + [IFLA_BR_MCAST_QUERY_INTVL] = {.type = NLA_U64}, + [IFLA_BR_MCAST_QUERY_RESPONSE_INTVL] = {.type = NLA_U64}, + [IFLA_BR_MCAST_STARTUP_QUERY_INTVL] = {.type = NLA_U64}, ++ [IFLA_BR_VLAN_FILTERING] = {.type = NLA_U8}, ++ [IFLA_BR_VLAN_DEFAULT_PVID] = {.type = NLA_U16}, + }; + NMPlatformLnkBridge *props; + struct nlattr *tb[G_N_ELEMENTS(policy)]; +@@ -1585,6 +1587,10 @@ _parse_lnk_bridge(const char *kind, struct nlattr *info_data) + props->mcast_query_response_interval = nla_get_u64(tb[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL]); + if (tb[IFLA_BR_MCAST_STARTUP_QUERY_INTVL]) + props->mcast_startup_query_interval = nla_get_u64(tb[IFLA_BR_MCAST_STARTUP_QUERY_INTVL]); ++ if (tb[IFLA_BR_VLAN_FILTERING]) ++ props->vlan_filtering = !!nla_get_u8(tb[IFLA_BR_VLAN_FILTERING]); ++ if (tb[IFLA_BR_VLAN_DEFAULT_PVID]) ++ props->default_pvid = nla_get_u16(tb[IFLA_BR_VLAN_DEFAULT_PVID]); + + return obj; + } +diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c +index 041354cf44..3b61375bad 100644 +--- a/src/libnm-platform/nm-platform.c ++++ b/src/libnm-platform/nm-platform.c +@@ -6086,7 +6086,8 @@ nm_platform_lnk_bridge_to_string(const NMPlatformLnkBridge *lnk, char *buf, gsiz + " 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 "", ++ " mcast_startup_query_interval %" G_GUINT64_FORMAT " vlan_filtering %d" ++ " default_pvid %" G_GUINT16_FORMAT "", + lnk->forward_delay, + lnk->hello_time, + lnk->max_age, +@@ -6109,7 +6110,9 @@ nm_platform_lnk_bridge_to_string(const NMPlatformLnkBridge *lnk, char *buf, gsiz + lnk->mcast_querier_interval, + lnk->mcast_query_interval, + lnk->mcast_query_response_interval, +- lnk->mcast_startup_query_interval); ++ lnk->mcast_startup_query_interval, ++ lnk->vlan_filtering, ++ lnk->default_pvid); + return buf; + } + +@@ -7978,12 +7981,14 @@ nm_platform_lnk_bridge_hash_update(const NMPlatformLnkBridge *obj, NMHashState * + obj->mcast_router, + obj->mcast_query_response_interval, + obj->mcast_startup_query_interval, ++ obj->default_pvid, + NM_HASH_COMBINE_BOOLS(guint8, + obj->stp_state, + obj->mcast_querier, + obj->mcast_query_use_ifaddr, + obj->mcast_snooping, +- obj->vlan_stats_enabled)); ++ obj->vlan_stats_enabled, ++ obj->vlan_filtering)); + } + + void +@@ -8124,6 +8129,8 @@ nm_platform_lnk_bridge_cmp(const NMPlatformLnkBridge *a, const NMPlatformLnkBrid + 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); ++ NM_CMP_FIELD_BOOL(a, b, vlan_filtering); ++ NM_CMP_FIELD(a, b, default_pvid); + + return 0; + } +diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h +index aeea5c42db..a4410b0a7c 100644 +--- a/src/libnm-platform/nm-platform.h ++++ b/src/libnm-platform/nm-platform.h +@@ -765,6 +765,8 @@ typedef struct { + bool mcast_snooping : 1; + bool stp_state : 1; + bool vlan_stats_enabled : 1; ++ bool vlan_filtering; ++ guint16 default_pvid; + } _nm_alignas(NMPlatformObject) NMPlatformLnkBridge; + + extern const NMPlatformLnkBridge nm_platform_lnk_bridge_default; +-- +2.43.0 + diff --git a/SPECS/NetworkManager.spec b/SPECS/NetworkManager.spec index dc7acc1..641062c 100644 --- a/SPECS/NetworkManager.spec +++ b/SPECS/NetworkManager.spec @@ -6,7 +6,7 @@ %global epoch_version 1 %global real_version 1.44.0 %global rpm_version %{real_version} -%global release_version 4 +%global release_version 5 %global snapshot %{nil} %global git_sha %{nil} %global bcond_default_debug 0 @@ -205,6 +205,7 @@ Source7: readme-ifcfg-rh.txt Patch1001: 1001-nm-manager-ensure-device-is-exported-on-D-Bus-in-aut-rhbz2210271.patch Patch1002: 1002-checkpoint-Fix-segfault-crash-when-rollback-rhel-1526.patch Patch1003: 1003-better-way-for-dns-changes-RHEL-14889.patch +Patch1004: 1004-bridge-skip-VLAN-filtering-resetting-in-reapply-RHEL-25061.patch Requires(post): systemd %if 0%{?fedora} || 0%{?rhel} >= 8 @@ -1254,6 +1255,9 @@ fi %changelog +* Wed Feb 21 2024 Fernando Fernandez Mancera - 1:1.44.0-5 +- skip VLAN filtering resetting in reapply if no vlan change changed (RHEL-25061) + * Fri Nov 17 2023 Íñigo Huguet - 1:1.44.0-4 - Add 'dns-change' dispatch event (RHEL-14889) From 122eb51982f29d9e4ef1360f04c19f6fd8eafb34 Mon Sep 17 00:00:00 2001 From: MSVSphere Packaging Team Date: Wed, 1 May 2024 03:31:07 +0300 Subject: [PATCH 5/6] import NetworkManager-1.46.0-4.el9_4 --- .NetworkManager.metadata | 2 +- .gitignore | 2 +- ...for-ipv4.dad-timeout-from-0-to-200ms.patch | 61 ++++ ...ective-from-nm-cloud-setup-rhel27053.patch | 25 ++ ...exported-on-D-Bus-in-aut-rhbz2210271.patch | 54 --- ...ck-on-internal-global-dns-rhel-29725.patch | 235 +++++++++++++ ...gfault-crash-when-rollback-rhel-1526.patch | 67 ---- ...etter-way-for-dns-changes-RHEL-14889.patch | 310 ------------------ ...dge-and-port-to-be-parent-rhel-28545.patch | 127 +++++++ ...ring-resetting-in-reapply-RHEL-25061.patch | 270 --------------- ...04-nm-dispatcher-fix-crash-rhel28973.patch | 50 +++ ...-while-enumerating-devices-rhel25808.patch | 66 ++++ SOURCES/22-wifi-mac-addr.conf | 31 ++ SOURCES/readme-ifcfg-rh-migrated.txt | 84 +++++ SPECS/NetworkManager.spec | 153 +++++++-- 15 files changed, 801 insertions(+), 736 deletions(-) create mode 100644 SOURCES/0001-revert-change-default-value-for-ipv4.dad-timeout-from-0-to-200ms.patch create mode 100644 SOURCES/1001-drop-privateusers-directive-from-nm-cloud-setup-rhel27053.patch delete mode 100644 SOURCES/1001-nm-manager-ensure-device-is-exported-on-D-Bus-in-aut-rhbz2210271.patch create mode 100644 SOURCES/1002-allow-rollback-on-internal-global-dns-rhel-29725.patch delete mode 100644 SOURCES/1002-checkpoint-Fix-segfault-crash-when-rollback-rhel-1526.patch delete mode 100644 SOURCES/1003-better-way-for-dns-changes-RHEL-14889.patch create mode 100644 SOURCES/1003-do-not-allow-ovs-bridge-and-port-to-be-parent-rhel-28545.patch delete mode 100644 SOURCES/1004-bridge-skip-VLAN-filtering-resetting-in-reapply-RHEL-25061.patch create mode 100644 SOURCES/1004-nm-dispatcher-fix-crash-rhel28973.patch create mode 100644 SOURCES/1005-fix-race-condition-while-enumerating-devices-rhel25808.patch create mode 100644 SOURCES/22-wifi-mac-addr.conf create mode 100644 SOURCES/readme-ifcfg-rh-migrated.txt diff --git a/.NetworkManager.metadata b/.NetworkManager.metadata index dab89c7..51191f7 100644 --- a/.NetworkManager.metadata +++ b/.NetworkManager.metadata @@ -1 +1 @@ -b3d857c8fdfae1dd36d6bd833cd84a85fcf71880 SOURCES/NetworkManager-1.44.0.tar.xz +3c11d700a2e81a7abce285ab94d015ac966f59d3 SOURCES/NetworkManager-1.46.0.tar.xz diff --git a/.gitignore b/.gitignore index 22242f5..32f1f94 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/NetworkManager-1.44.0.tar.xz +SOURCES/NetworkManager-1.46.0.tar.xz diff --git a/SOURCES/0001-revert-change-default-value-for-ipv4.dad-timeout-from-0-to-200ms.patch b/SOURCES/0001-revert-change-default-value-for-ipv4.dad-timeout-from-0-to-200ms.patch new file mode 100644 index 0000000..2eec3bc --- /dev/null +++ b/SOURCES/0001-revert-change-default-value-for-ipv4.dad-timeout-from-0-to-200ms.patch @@ -0,0 +1,61 @@ +diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c +index 16f8e1f261..036233e668 100644 +--- a/src/core/devices/nm-device.c ++++ b/src/core/devices/nm-device.c +@@ -1661,7 +1661,7 @@ _prop_get_ipv4_dad_timeout(NMDevice *self) + self, + 0, + NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX, +- 200); ++ 0); + } + + static guint32 +diff --git a/src/libnm-core-impl/nm-setting-ip-config.c b/src/libnm-core-impl/nm-setting-ip-config.c +index bfebe7d13d..de56ed74ea 100644 +--- a/src/libnm-core-impl/nm-setting-ip-config.c ++++ b/src/libnm-core-impl/nm-setting-ip-config.c +@@ -6655,7 +6655,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) + * + * A zero value means that no duplicate address detection is performed, -1 means + * the default value (either the value configured globally in NetworkManger.conf +- * or 200ms). A value greater than zero is a timeout in milliseconds. Note that ++ * or zero). A value greater than zero is a timeout in milliseconds. Note that + * the time intervals are subject to randomization as per RFC 5227 and so the + * actual duration can be between half and the full time specified in this + * property. +diff --git a/src/libnmc-setting/settings-docs.h.in b/src/libnmc-setting/settings-docs.h.in +index 77cde6620e..e42cb74e7f 100644 +--- a/src/libnmc-setting/settings-docs.h.in ++++ b/src/libnmc-setting/settings-docs.h.in +@@ -162,7 +162,7 @@ + #define DESCRIBE_DOC_NM_SETTING_INFINIBAND_TRANSPORT_MODE N_("The IP-over-InfiniBand transport mode. Either \"datagram\" or \"connected\".") + #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ADDRESSES N_("A list of IPv4 addresses and their prefix length. Multiple addresses can be separated by comma. For example \"192.168.1.5/24, 10.1.0.5/24\". The addresses are listed in decreasing priority, meaning the first address will be the primary address.") + #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_AUTO_ROUTE_EXT_GW N_("VPN connections will default to add the route automatically unless this setting is set to FALSE. For other connection types, adding such an automatic route is currently not supported and setting this to TRUE has no effect.") +-#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DAD_TIMEOUT N_("Maximum timeout in milliseconds used to check for the presence of duplicate IP addresses on the network. If an address conflict is detected, the activation will fail. The property is currently implemented only for IPv4. A zero value means that no duplicate address detection is performed, -1 means the default value (either the value configured globally in NetworkManger.conf or 200ms). A value greater than zero is a timeout in milliseconds. Note that the time intervals are subject to randomization as per RFC 5227 and so the actual duration can be between half and the full time specified in this property.") ++#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DAD_TIMEOUT N_("Maximum timeout in milliseconds used to check for the presence of duplicate IP addresses on the network. If an address conflict is detected, the activation will fail. The property is currently implemented only for IPv4. A zero value means that no duplicate address detection is performed, -1 means the default value (either the value configured globally in NetworkManger.conf or zero). A value greater than zero is a timeout in milliseconds. Note that the time intervals are subject to randomization as per RFC 5227 and so the actual duration can be between half and the full time specified in this property.") + #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID N_("A string sent to the DHCP server to identify the local machine which the DHCP server may use to customize the DHCP lease and options. When the property is a hex string ('aa:bb:cc') it is interpreted as a binary client ID, in which case the first byte is assumed to be the 'type' field as per RFC 2132 section 9.14 and the remaining bytes may be an hardware address (e.g. '01:xx:xx:xx:xx:xx:xx' where 1 is the Ethernet ARP type and the rest is a MAC address). If the property is not a hex string it is considered as a non-hardware-address client ID and the 'type' field is set to 0. The special values \"mac\" and \"perm-mac\" are supported, which use the current or permanent MAC address of the device to generate a client identifier with type ethernet (01). Currently, these options only work for ethernet type of links. The special value \"ipv6-duid\" uses the DUID from \"ipv6.dhcp-duid\" property as an RFC4361-compliant client identifier. As IAID it uses \"ipv4.dhcp-iaid\" and falls back to \"ipv6.dhcp-iaid\" if unset. The special value \"duid\" generates a RFC4361-compliant client identifier based on \"ipv4.dhcp-iaid\" and uses a DUID generated by hashing /etc/machine-id. The special value \"stable\" is supported to generate a type 0 client identifier based on the stable-id (see connection.stable-id) and a per-host key. If you set the stable-id, you may want to include the \"${DEVICE}\" or \"${MAC}\" specifier to get a per-device key. The special value \"none\" prevents any client identifier from being sent. Note that this is normally not recommended. If unset, a globally configured default from NetworkManager.conf is used. If still unset, the default depends on the DHCP plugin. The internal dhcp client will default to \"mac\" and the dhclient plugin will try to use one from its config file if present, or won't sent any client-id otherwise.") + #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_DSCP N_("Specifies the value for the DSCP field (traffic class) of the IP header. When empty, the global default value is used; if no global default is specified, it is assumed to be \"CS0\". Allowed values are: \"CS0\", \"CS4\" and \"CS6\". The property is currently valid only for IPv4, and it is supported only by the \"internal\" DHCP plugin.") + #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_FQDN N_("If the \"dhcp-send-hostname\" property is TRUE, then the specified FQDN will be sent to the DHCP server when acquiring a lease. This property and \"dhcp-hostname\" are mutually exclusive and cannot be set at the same time.") +@@ -192,7 +192,7 @@ + #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE N_("Configure method for creating the IPv6 interface identifer of addresses with RFC4862 IPv6 Stateless Address Autoconfiguration and Link Local addresses. The permitted values are: \"eui64\" (0), \"stable-privacy\" (1), \"default\" (3) or \"default-or-eui64\" (2). If the property is set to \"eui64\", the addresses will be generated using the interface token derived from hardware address. This makes the host part of the address to stay constant, making it possible to track the host's presence when it changes networks. The address changes when the interface hardware is replaced. If a duplicate address is detected, there is also no fallback to generate another address. When configured, the \"ipv6.token\" is used instead of the MAC address to generate addresses for stateless autoconfiguration. If the property is set to \"stable-privacy\", the interface identifier is generated as specified by RFC7217. This works by hashing a host specific key (see NetworkManager(8) manual), the interface name, the connection's \"connection.stable-id\" property and the address prefix. This improves privacy by making it harder to use the address to track the host's presence and the address is stable when the network interface hardware is replaced. The special values \"default\" and \"default-or-eui64\" will fallback to the global connection default as documented in the NetworkManager.conf(5) manual. If the global default is not specified, the fallback value is \"stable-privacy\" or \"eui64\", respectively. If not specified, when creating a new profile the default is \"default\". Note that this setting is distinct from the Privacy Extensions as configured by \"ip6-privacy\" property and it does not affect the temporary addresses configured with this option.") + #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_ADDRESSES N_("A list of IPv6 addresses and their prefix length. Multiple addresses can be separated by comma. For example \"2001:db8:85a3::8a2e:370:7334/64, 2001:db8:85a3::5/64\". The addresses are listed in decreasing priority, meaning the first address will be the primary address. This can make a difference with IPv6 source address selection (RFC 6724, section 5).") + #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_AUTO_ROUTE_EXT_GW N_("VPN connections will default to add the route automatically unless this setting is set to FALSE. For other connection types, adding such an automatic route is currently not supported and setting this to TRUE has no effect.") +-#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DAD_TIMEOUT N_("Maximum timeout in milliseconds used to check for the presence of duplicate IP addresses on the network. If an address conflict is detected, the activation will fail. The property is currently implemented only for IPv4. A zero value means that no duplicate address detection is performed, -1 means the default value (either the value configured globally in NetworkManger.conf or 200ms). A value greater than zero is a timeout in milliseconds. Note that the time intervals are subject to randomization as per RFC 5227 and so the actual duration can be between half and the full time specified in this property.") ++#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DAD_TIMEOUT N_("Maximum timeout in milliseconds used to check for the presence of duplicate IP addresses on the network. If an address conflict is detected, the activation will fail. The property is currently implemented only for IPv4. A zero value means that no duplicate address detection is performed, -1 means the default value (either the value configured globally in NetworkManger.conf or zero). A value greater than zero is a timeout in milliseconds. Note that the time intervals are subject to randomization as per RFC 5227 and so the actual duration can be between half and the full time specified in this property.") + #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_DSCP N_("Specifies the value for the DSCP field (traffic class) of the IP header. When empty, the global default value is used; if no global default is specified, it is assumed to be \"CS0\". Allowed values are: \"CS0\", \"CS4\" and \"CS6\". The property is currently valid only for IPv4, and it is supported only by the \"internal\" DHCP plugin.") + #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_DUID N_("A string containing the DHCPv6 Unique Identifier (DUID) used by the dhcp client to identify itself to DHCPv6 servers (RFC 3315). The DUID is carried in the Client Identifier option. If the property is a hex string ('aa:bb:cc') it is interpreted as a binary DUID and filled as an opaque value in the Client Identifier option. The special value \"lease\" will retrieve the DUID previously used from the lease file belonging to the connection. If no DUID is found and \"dhclient\" is the configured dhcp client, the DUID is searched in the system-wide dhclient lease file. If still no DUID is found, or another dhcp client is used, a global and permanent DUID-UUID (RFC 6355) will be generated based on the machine-id. The special values \"llt\" and \"ll\" will generate a DUID of type LLT or LL (see RFC 3315) based on the current MAC address of the device. In order to try providing a stable DUID-LLT, the time field will contain a constant timestamp that is used globally (for all profiles) and persisted to disk. The special values \"stable-llt\", \"stable-ll\" and \"stable-uuid\" will generate a DUID of the corresponding type, derived from the connection's stable-id and a per-host unique key. You may want to include the \"${DEVICE}\" or \"${MAC}\" specifier in the stable-id, in case this profile gets activated on multiple devices. So, the link-layer address of \"stable-ll\" and \"stable-llt\" will be a generated address derived from the stable id. The DUID-LLT time value in the \"stable-llt\" option will be picked among a static timespan of three years (the upper bound of the interval is the same constant timestamp used in \"llt\"). When the property is unset, the global value provided for \"ipv6.dhcp-duid\" is used. If no global value is provided, the default \"lease\" value is assumed.") + #define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_HOSTNAME N_("If the \"dhcp-send-hostname\" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease. This property and \"dhcp-fqdn\" are mutually exclusive and cannot be set at the same time.") +diff --git a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in +index 8806bf2550..09648f3ff8 100644 +--- a/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in ++++ b/src/nmcli/gen-metadata-nm-settings-nmcli.xml.in +@@ -1337,7 +1337,7 @@ + values="-1 - 2147483647" + special-values="default (-1), infinity (2147483647)" /> + diff --git a/SOURCES/1001-drop-privateusers-directive-from-nm-cloud-setup-rhel27053.patch b/SOURCES/1001-drop-privateusers-directive-from-nm-cloud-setup-rhel27053.patch new file mode 100644 index 0000000..372b0f4 --- /dev/null +++ b/SOURCES/1001-drop-privateusers-directive-from-nm-cloud-setup-rhel27053.patch @@ -0,0 +1,25 @@ +From 6e84d852487f070ab3f61c24d78fc05338f171f6 Mon Sep 17 00:00:00 2001 +From: Fernando Fernandez Mancera +Date: Wed, 20 Mar 2024 19:10:45 +0100 +Subject: [PATCH] cloud: drop PrivateUsers directive from nm-cloud-setup + +https://issues.redhat.com/browse/RHEL-27503 +--- + src/nm-cloud-setup/nm-cloud-setup.service.in | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/nm-cloud-setup/nm-cloud-setup.service.in b/src/nm-cloud-setup/nm-cloud-setup.service.in +index e73654d892..4aa6017e48 100644 +--- a/src/nm-cloud-setup/nm-cloud-setup.service.in ++++ b/src/nm-cloud-setup/nm-cloud-setup.service.in +@@ -28,7 +28,6 @@ MemoryDenyWriteExecute=yes + NoNewPrivileges=yes + PrivateDevices=yes + PrivateTmp=yes +-PrivateUsers=yes + ProtectClock=yes + ProtectControlGroups=yes + ProtectHome=yes +-- +2.44.0 + diff --git a/SOURCES/1001-nm-manager-ensure-device-is-exported-on-D-Bus-in-aut-rhbz2210271.patch b/SOURCES/1001-nm-manager-ensure-device-is-exported-on-D-Bus-in-aut-rhbz2210271.patch deleted file mode 100644 index 1867761..0000000 --- a/SOURCES/1001-nm-manager-ensure-device-is-exported-on-D-Bus-in-aut-rhbz2210271.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 6302c2ea52c6c28d36b6006b29823c469e171e2a Mon Sep 17 00:00:00 2001 -From: Wen Liang -Date: Thu, 3 Aug 2023 10:16:42 -0400 -Subject: [PATCH] nm-manager: ensure device is exported on D-Bus in - authentication request - -The device authentication request is an async process, it can not know -the answer right away, it is not guarantee that device is still -exported on D-Bus when authentication finishes. Thus, do not return -SUCCESS and abort the authentication request when device is not alive. - -https://bugzilla.redhat.com/show_bug.cgi?id=2210271 -(cherry picked from commit b341161e2a4988403ae4a6ef7653e01567da36a0) -(cherry picked from commit 0e27e84247ed824b27d105292d7bf42dc0341cbb) ---- - src/core/nm-manager.c | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - -diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c -index 9c7212202b..937acbba1e 100644 ---- a/src/core/nm-manager.c -+++ b/src/core/nm-manager.c -@@ -3222,6 +3222,13 @@ device_auth_done_cb(NMAuthChain *chain, GDBusMethodInvocation *context, gpointer - nm_assert(error || (result == NM_AUTH_CALL_RESULT_YES)); - } - -+ if (!error && !nm_dbus_object_is_exported(NM_DBUS_OBJECT(device))) { -+ g_set_error(&error, -+ NM_MANAGER_ERROR, -+ NM_MANAGER_ERROR_UNKNOWN_DEVICE, -+ "device no longer exists"); -+ } -+ - callback(device, context, subject, error, nm_auth_chain_get_data(chain, "user-data")); - } - -@@ -3287,6 +3294,14 @@ nm_manager_device_auth_request(NMManager *self, - &error)) - goto fail_on_idle; - -+ if (!nm_dbus_object_is_exported(NM_DBUS_OBJECT(device))) { -+ g_set_error(&error, -+ NM_MANAGER_ERROR, -+ NM_MANAGER_ERROR_UNKNOWN_DEVICE, -+ "device no longer exists"); -+ goto fail_on_idle; -+ } -+ - chain = nm_auth_chain_new_subject(subject, context, device_auth_done_cb, self); - if (cancellable) - nm_auth_chain_set_cancellable(chain, cancellable); --- -2.41.0 - diff --git a/SOURCES/1002-allow-rollback-on-internal-global-dns-rhel-29725.patch b/SOURCES/1002-allow-rollback-on-internal-global-dns-rhel-29725.patch new file mode 100644 index 0000000..49d3107 --- /dev/null +++ b/SOURCES/1002-allow-rollback-on-internal-global-dns-rhel-29725.patch @@ -0,0 +1,235 @@ +From ba47f23b08bb59ec2daf6bce73a94182d8028c82 Mon Sep 17 00:00:00 2001 +From: Gris Ge +Date: Wed, 13 Mar 2024 20:52:37 +0800 +Subject: [PATCH] checkpoint: Allow rollback on internal global DNS + +With `NM_CHECKPOINT_CREATE_FLAG_TRACK_INTERNAL_GLOBAL_DNS` flag set on +checkpoint creation, the checkpoint rollback will restore the +global DNS in internal configure file +`/var/lib/NetworkManager/NetworkManager-intern.conf`. + +If user has set global DNS in /etc folder, this flag will not take any +effect. + +Resolves: https://issues.redhat.com/browse/RHEL-23446 + +Signed-off-by: Gris Ge +(cherry picked from commit 86d67da28dd047a08a01687d8154b377d1c25b4c) +(cherry picked from commit 69d5761fa87bb85df037ad9044c03dd1922d3ee4) +--- + src/core/nm-checkpoint.c | 28 ++++++++++++++ + src/core/nm-config-data.c | 47 +++++++++++++++++++++++ + src/core/nm-config-data.h | 3 +- + src/core/nm-manager.c | 11 +++++- + src/core/nm-manager.h | 3 ++ + src/libnm-core-public/nm-dbus-interface.h | 6 +++ + 6 files changed, 96 insertions(+), 2 deletions(-) + +diff --git a/src/core/nm-checkpoint.c b/src/core/nm-checkpoint.c +index 74adf48477..cc5c189bf9 100644 +--- a/src/core/nm-checkpoint.c ++++ b/src/core/nm-checkpoint.c +@@ -13,6 +13,7 @@ + #include "nm-core-utils.h" + #include "nm-dbus-interface.h" + #include "devices/nm-device.h" ++#include "nm-config.h" + #include "nm-manager.h" + #include "settings/nm-settings.h" + #include "settings/nm-settings-connection.h" +@@ -55,6 +56,8 @@ struct _NMCheckpointPrivate { + + NMCheckpointTimeoutCallback timeout_cb; + gpointer timeout_data; ++ ++ NMGlobalDnsConfig *global_dns_config; + }; + + struct _NMCheckpointClass { +@@ -491,6 +494,17 @@ next_dev: + } + } + } ++ if (NM_FLAGS_HAS(priv->flags, NM_CHECKPOINT_CREATE_FLAG_TRACK_INTERNAL_GLOBAL_DNS) ++ && priv->global_dns_config) { ++ gs_free_error GError *error = NULL; ++ NMConfig *config; ++ ++ config = nm_manager_get_config(priv->manager); ++ nm_assert(config); ++ if (!nm_config_set_global_dns(config, priv->global_dns_config, &error)) { ++ _LOGE("set global DNS failed with error: %s", error->message); ++ } ++ } + + return g_variant_new("(a{su})", &builder); + } +@@ -742,6 +756,19 @@ nm_checkpoint_new(NMManager *manager, + NM_MANAGER_DEVICE_REMOVED, + G_CALLBACK(_device_removed), + self); ++ if (NM_FLAGS_HAS(flags, NM_CHECKPOINT_CREATE_FLAG_TRACK_INTERNAL_GLOBAL_DNS)) { ++ NMConfigData *config_data; ++ NMGlobalDnsConfig *dns_config = NULL; ++ ++ config_data = nm_config_get_data(nm_manager_get_config(manager)); ++ if (config_data) { ++ dns_config = nm_config_data_get_global_dns_config(config_data); ++ if (!dns_config || nm_global_dns_config_is_internal(dns_config)) { ++ priv->global_dns_config = nm_global_dns_config_clone(dns_config); ++ } ++ } ++ } ++ + return self; + } + +@@ -756,6 +783,7 @@ dispose(GObject *object) + nm_clear_pointer(&priv->devices, g_hash_table_unref); + nm_clear_pointer(&priv->connection_uuids, g_hash_table_unref); + nm_clear_pointer(&priv->removed_devices, g_ptr_array_unref); ++ nm_global_dns_config_free(priv->global_dns_config); + + nm_clear_g_signal_handler(priv->manager, &priv->dev_removed_id); + g_clear_object(&priv->manager); +diff --git a/src/core/nm-config-data.c b/src/core/nm-config-data.c +index 468e56b821..d4498edd88 100644 +--- a/src/core/nm-config-data.c ++++ b/src/core/nm-config-data.c +@@ -2436,3 +2436,50 @@ nm_config_data_class_init(NMConfigDataClass *config_class) + + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + } ++ ++static NMGlobalDnsDomain * ++nm_global_dns_domain_clone(NMGlobalDnsDomain *old_domain) ++{ ++ if (old_domain) { ++ NMGlobalDnsDomain *new_domain = g_malloc0(sizeof(NMGlobalDnsDomain)); ++ new_domain->name = g_strdup(old_domain->name); ++ new_domain->servers = (char **) nm_strv_dup(old_domain->servers, -1, TRUE); ++ new_domain->options = (char **) nm_strv_dup(old_domain->options, -1, TRUE); ++ return new_domain; ++ } else { ++ return NULL; ++ } ++} ++ ++NMGlobalDnsConfig * ++nm_global_dns_config_clone(NMGlobalDnsConfig *old_dns_config) ++{ ++ NMGlobalDnsConfig *new_dns_config; ++ gpointer key, value; ++ NMGlobalDnsDomain *old_domain; ++ GHashTableIter iter; ++ ++ new_dns_config = g_malloc0(sizeof(NMGlobalDnsConfig)); ++ new_dns_config->internal = TRUE; ++ ++ if (old_dns_config) { ++ new_dns_config->internal = old_dns_config->internal; ++ new_dns_config->searches = nm_strv_dup(old_dns_config->searches, -1, TRUE); ++ new_dns_config->options = nm_strv_dup(old_dns_config->options, -1, TRUE); ++ new_dns_config->domains = g_hash_table_new_full(nm_str_hash, ++ g_str_equal, ++ g_free, ++ (GDestroyNotify) global_dns_domain_free); ++ if (old_dns_config->domains) { ++ g_hash_table_iter_init(&iter, old_dns_config->domains); ++ while (g_hash_table_iter_next(&iter, &key, &value)) { ++ old_domain = value; ++ g_hash_table_insert(new_dns_config->domains, ++ g_strdup(key), ++ nm_global_dns_domain_clone(old_domain)); ++ } ++ } ++ global_dns_config_seal_domains(new_dns_config); ++ } ++ return new_dns_config; ++} +diff --git a/src/core/nm-config-data.h b/src/core/nm-config-data.h +index 9e7a50fc24..0344ce9055 100644 +--- a/src/core/nm-config-data.h ++++ b/src/core/nm-config-data.h +@@ -280,7 +280,8 @@ int nm_global_dns_config_cmp(const NMGlobalDnsConfig *a, + const NMGlobalDnsConfig *b, + gboolean check_internal); + void nm_global_dns_config_update_checksum(const NMGlobalDnsConfig *dns_config, GChecksum *sum); +-void nm_global_dns_config_free(NMGlobalDnsConfig *dns_config); ++NMGlobalDnsConfig *nm_global_dns_config_clone(NMGlobalDnsConfig *dns_config); ++void nm_global_dns_config_free(NMGlobalDnsConfig *dns_config); + + NMGlobalDnsConfig *nm_global_dns_config_from_dbus(const GValue *value, GError **error); + void nm_global_dns_config_to_dbus(const NMGlobalDnsConfig *dns_config, GValue *value); +diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c +index 730ba4763b..6739e5599e 100644 +--- a/src/core/nm-manager.c ++++ b/src/core/nm-manager.c +@@ -8458,7 +8458,8 @@ impl_manager_checkpoint_create(NMDBusObject *obj, + | NM_CHECKPOINT_CREATE_FLAG_DELETE_NEW_CONNECTIONS + | NM_CHECKPOINT_CREATE_FLAG_DISCONNECT_NEW_DEVICES + | NM_CHECKPOINT_CREATE_FLAG_ALLOW_OVERLAPPING +- | NM_CHECKPOINT_CREATE_FLAG_NO_PRESERVE_EXTERNAL_PORTS)))) { ++ | NM_CHECKPOINT_CREATE_FLAG_NO_PRESERVE_EXTERNAL_PORTS ++ | NM_CHECKPOINT_CREATE_FLAG_TRACK_INTERNAL_GLOBAL_DNS)))) { + g_dbus_method_invocation_return_error_literal(invocation, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_INVALID_ARGUMENTS, +@@ -9765,3 +9766,11 @@ nm_manager_class_init(NMManagerClass *manager_class) + 1, + NM_TYPE_DEVICE); + } ++ ++NMConfig * ++nm_manager_get_config(NMManager *self) ++{ ++ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self); ++ ++ return priv->config; ++} +diff --git a/src/core/nm-manager.h b/src/core/nm-manager.h +index 3028eb7ebe..3c5213c4f2 100644 +--- a/src/core/nm-manager.h ++++ b/src/core/nm-manager.h +@@ -10,6 +10,7 @@ + #include "settings/nm-settings-connection.h" + #include "c-list/src/c-list.h" + #include "nm-dbus-manager.h" ++#include "nm-config-data.h" + + #define NM_TYPE_MANAGER (nm_manager_get_type()) + #define NM_MANAGER(obj) (_NM_G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_MANAGER, NMManager)) +@@ -266,4 +267,6 @@ gboolean nm_manager_devcon_autoconnect_blocked_reason_set(NMManager * + NMSettingsAutoconnectBlockedReason value, + gboolean set); + ++NMConfig *nm_manager_get_config(NMManager *self); ++ + #endif /* __NETWORKMANAGER_MANAGER_H__ */ +diff --git a/src/libnm-core-public/nm-dbus-interface.h b/src/libnm-core-public/nm-dbus-interface.h +index 66cd590d6c..ab94244c21 100644 +--- a/src/libnm-core-public/nm-dbus-interface.h ++++ b/src/libnm-core-public/nm-dbus-interface.h +@@ -991,6 +991,11 @@ typedef enum { + * With this flag, the rollback detaches all external ports. + * This only has an effect for bridge ports. Before 1.38, this was the default + * behavior. Since: 1.38. ++ * @NM_CHECKPOINT_CREATE_FLAG_TRACK_INTERNAL_GLOBAL_DNS: during rollback, ++ * by default changes to global DNS via D-BUS interface are preserved. ++ * With this flag, the rollback reverts the global DNS changes made via D-Bus ++ * interface. Global DNS defined in [global-dns] section of ++ * NetworkManager.conf is not impacted by this flag. Since: 1.48. + * + * The flags for CheckpointCreate call + * +@@ -1003,6 +1008,7 @@ typedef enum /*< flags >*/ { + NM_CHECKPOINT_CREATE_FLAG_DISCONNECT_NEW_DEVICES = 0x04, + NM_CHECKPOINT_CREATE_FLAG_ALLOW_OVERLAPPING = 0x08, + NM_CHECKPOINT_CREATE_FLAG_NO_PRESERVE_EXTERNAL_PORTS = 0x10, ++ NM_CHECKPOINT_CREATE_FLAG_TRACK_INTERNAL_GLOBAL_DNS = 0x20, + } NMCheckpointCreateFlags; + + /** +-- +2.44.0 + diff --git a/SOURCES/1002-checkpoint-Fix-segfault-crash-when-rollback-rhel-1526.patch b/SOURCES/1002-checkpoint-Fix-segfault-crash-when-rollback-rhel-1526.patch deleted file mode 100644 index 63671a3..0000000 --- a/SOURCES/1002-checkpoint-Fix-segfault-crash-when-rollback-rhel-1526.patch +++ /dev/null @@ -1,67 +0,0 @@ -From d9b3114b6ef8e0f4d50a8d56d750a698d85fa984 Mon Sep 17 00:00:00 2001 -From: Gris Ge -Date: Tue, 29 Aug 2023 08:25:23 +0800 -Subject: [PATCH] checkpoint: Fix segfault crash when rollback - -When rolling back a checkpoint, NM will crash due to dereference a NULL -pointer of `priv->removed_devices->len`. - -To fix it, we just place a NULL check before that code block. - -Fixes: 1f1b71ad9f8a ('checkpoint: preserve devices that were removed and - readded') - -Reference: https://issues.redhat.com/browse/RHEL-1526 - -Signed-off-by: Gris Ge -(cherry picked from commit 3162507d6ca381cfbe02ceba2d80ba0f3ba3e5f7) -(cherry picked from commit e5600d4c5a33749939b984184f27fbe4159a2b65) ---- - src/core/nm-checkpoint.c | 23 +++++++++++++---------- - 1 file changed, 13 insertions(+), 10 deletions(-) - -diff --git a/src/core/nm-checkpoint.c b/src/core/nm-checkpoint.c -index 5c4d4e53d6..74adf48477 100644 ---- a/src/core/nm-checkpoint.c -+++ b/src/core/nm-checkpoint.c -@@ -460,24 +460,27 @@ next_dev: - NMDeviceState state; - - nm_manager_for_each_device (priv->manager, device, tmp_lst) { -- gboolean found = FALSE; -- - if (g_hash_table_contains(priv->devices, device)) - continue; - - /* Also ignore devices that were in the checkpoint initially and - * were moved to 'removed_devices' because they got removed from - * the system. */ -- for (i = 0; i < priv->removed_devices->len; i++) { -- dev_checkpoint = priv->removed_devices->pdata[i]; -- if (dev_checkpoint->dev_type == nm_device_get_device_type(device) -- && nm_streq0(dev_checkpoint->original_dev_name, nm_device_get_iface(device))) { -- found = TRUE; -- break; -+ if (priv->removed_devices) { -+ gboolean found = FALSE; -+ -+ for (i = 0; i < priv->removed_devices->len; i++) { -+ dev_checkpoint = priv->removed_devices->pdata[i]; -+ if (dev_checkpoint->dev_type == nm_device_get_device_type(device) -+ && nm_streq0(dev_checkpoint->original_dev_name, -+ nm_device_get_iface(device))) { -+ found = TRUE; -+ break; -+ } - } -+ if (found) -+ continue; - } -- if (found) -- continue; - - state = nm_device_get_state(device); - if (state > NM_DEVICE_STATE_DISCONNECTED && state < NM_DEVICE_STATE_DEACTIVATING) { --- -2.41.0 - diff --git a/SOURCES/1003-better-way-for-dns-changes-RHEL-14889.patch b/SOURCES/1003-better-way-for-dns-changes-RHEL-14889.patch deleted file mode 100644 index 75a3daa..0000000 --- a/SOURCES/1003-better-way-for-dns-changes-RHEL-14889.patch +++ /dev/null @@ -1,310 +0,0 @@ -From a3e39a3bf9667bb69fb2f37b605caffbd969889a Mon Sep 17 00:00:00 2001 -From: Gris Ge -Date: Tue, 26 Sep 2023 15:00:32 +0800 -Subject: [PATCH 1/2] emit DNS CONFIG_CHANGED signal even dns=none - -Instruct the `NMDnsManager` to emit `CONFIG_CHANGED` signal even -`dns=none` or failed to modify `/etc/resolv.conf`. - -The `NMPolicy` will only update hostname when DNS is managed. - -Signed-off-by: Gris Ge -(cherry picked from commit a847ba807572c3ef3682e833432f2f93e9d519a0) -(cherry picked from commit d10f20fd01a7bb3225c7e38ed80449e19156344b) ---- - src/core/dns/nm-dns-manager.c | 12 +++++++++++- - src/core/dns/nm-dns-manager.h | 2 ++ - src/core/nm-policy.c | 10 ++++++---- - 3 files changed, 19 insertions(+), 5 deletions(-) - -diff --git a/src/core/dns/nm-dns-manager.c b/src/core/dns/nm-dns-manager.c -index 535646930c..231ef72f49 100644 ---- a/src/core/dns/nm-dns-manager.c -+++ b/src/core/dns/nm-dns-manager.c -@@ -1948,7 +1948,7 @@ plugin_skip:; - } - - /* signal that DNS resolution configs were changed */ -- if ((do_update || caching || force_emit) && result == SR_SUCCESS) -+ if ((caching || force_emit) && result == SR_SUCCESS) - g_signal_emit(self, signals[CONFIG_CHANGED], 0); - - nm_clear_pointer(&priv->config_variant, g_variant_unref); -@@ -1964,6 +1964,16 @@ plugin_skip:; - return TRUE; - } - -+gboolean -+nm_dns_manager_is_unmanaged(NMDnsManager *self) -+{ -+ NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE(self); -+ -+ return NM_IN_SET(priv->rc_manager, -+ NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED, -+ NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE); -+} -+ - /*****************************************************************************/ - - gboolean -diff --git a/src/core/dns/nm-dns-manager.h b/src/core/dns/nm-dns-manager.h -index 42f9dec588..9b8c2972b4 100644 ---- a/src/core/dns/nm-dns-manager.h -+++ b/src/core/dns/nm-dns-manager.h -@@ -148,4 +148,6 @@ char *nmtst_dns_create_resolv_conf(const char *const *searches, - const char *const *nameservers, - const char *const *options); - -+gboolean nm_dns_manager_is_unmanaged(NMDnsManager *self); -+ - #endif /* __NETWORKMANAGER_DNS_MANAGER_H__ */ -diff --git a/src/core/nm-policy.c b/src/core/nm-policy.c -index efdb06360f..1cf6b3398d 100644 ---- a/src/core/nm-policy.c -+++ b/src/core/nm-policy.c -@@ -2635,11 +2635,13 @@ dns_config_changed(NMDnsManager *dns_manager, gpointer user_data) - if (priv->updating_dns) - return; - -- nm_manager_for_each_device (priv->manager, device, tmp_lst) { -- nm_device_clear_dns_lookup_data(device, "DNS configuration changed"); -- } -+ if (!nm_dns_manager_is_unmanaged(dns_manager)) { -+ nm_manager_for_each_device (priv->manager, device, tmp_lst) { -+ nm_device_clear_dns_lookup_data(device, "DNS configuration changed"); -+ } - -- update_system_hostname(self, "DNS configuration changed"); -+ update_system_hostname(self, "DNS configuration changed"); -+ } - } - - static void --- -2.41.0 - - -From de4c05300e25b49bf077ac7929622f2721815b29 Mon Sep 17 00:00:00 2001 -From: Gris Ge -Date: Tue, 26 Sep 2023 17:14:58 +0800 -Subject: [PATCH 2/2] dispatch `dns-change` dispatcher event - -Introducing new dispatcher event -- `dns-change` which will be emitted when -DNS configuration changed(even in `dns=none` mode). This is to solve two -use cases: - * Invoke dispatch script for DNS changes triggered by the global DNS - API. - - * Do not invoke [OpenShift resolv-prepender][1] for non-DNS changes. - -Bug reference: https://issues.redhat.com/browse/RHEL-1671 - -[1]: https://github.com/openshift/machine-config-operator/blob/master/templates/common/on-prem/files/resolv-prepender.yaml - -Signed-off-by: Gris Ge -(cherry picked from commit a1db61ebc9712d1faf2ef8f1b2cb14cd819346d3) -(cherry picked from commit 3cdce71b95cea11bf409d9353c35a4dea6f33984) ---- - man/NetworkManager-dispatcher.xml | 15 +++++- - src/core/nm-dispatcher.c | 51 ++++++++++++++++--- - src/core/nm-dispatcher.h | 3 ++ - src/core/nm-policy.c | 2 + - src/libnm-core-aux-extern/nm-dispatcher-api.h | 1 + - src/nm-dispatcher/nm-dispatcher-utils.c | 8 ++- - 6 files changed, 69 insertions(+), 11 deletions(-) - -diff --git a/man/NetworkManager-dispatcher.xml b/man/NetworkManager-dispatcher.xml -index 036b3c8dcc..e87226d05e 100644 ---- a/man/NetworkManager-dispatcher.xml -+++ b/man/NetworkManager-dispatcher.xml -@@ -68,8 +68,9 @@ - device an operation just happened on, and second the action. For device actions, - the interface is the name of the kernel interface suitable for IP configuration. - Thus it is either VPN_IP_IFACE, DEVICE_IP_IFACE, or DEVICE_IFACE, as applicable. -- For the hostname action the device name is always "none" -- and for connectivity-change it is empty. -+ For the hostname action the device name is always "none". -+ For connectivity-change it is empty. -+ For dns-change it is empty. - - The actions are: - -@@ -170,6 +171,16 @@ - The connection was reapplied on the device. - - -+ -+ dns-change -+ -+ The DNS configuration has changed. This action is raised even if -+ NetworkManager is configured to not manage resolv.conf (for example, -+ via dns=none). In such case, the dispatch script can discover the -+ DNS configuration provided by currently active connections by -+ looking at file /run/NetworkManager/resolv.conf -+ -+ - - - The environment contains more information about the interface and the connection. -diff --git a/src/core/nm-dispatcher.c b/src/core/nm-dispatcher.c -index cdc07dd60e..9aa4194e83 100644 ---- a/src/core/nm-dispatcher.c -+++ b/src/core/nm-dispatcher.c -@@ -50,6 +50,8 @@ - } \ - G_STMT_END - -+static gboolean nm_dispatcher_need_device(NMDispatcherAction action); -+ - /*****************************************************************************/ - - struct NMDispatcherCallId { -@@ -469,7 +471,8 @@ static const char *action_table[] = {[NM_DISPATCHER_ACTION_HOSTNAME] = NMD_ - [NM_DISPATCHER_ACTION_DHCP_CHANGE_6] = NMD_ACTION_DHCP6_CHANGE, - [NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE] = - NMD_ACTION_CONNECTIVITY_CHANGE, -- [NM_DISPATCHER_ACTION_REAPPLY] = NMD_ACTION_REAPPLY}; -+ [NM_DISPATCHER_ACTION_REAPPLY] = NMD_ACTION_REAPPLY, -+ [NM_DISPATCHER_ACTION_DNS_CHANGE] = NMD_ACTION_DNS_CHANGE}; - - static const char * - action_to_string(NMDispatcherAction action) -@@ -530,9 +533,7 @@ _dispatcher_call(NMDispatcherAction action, - if (G_UNLIKELY(!request_id)) - request_id = ++gl.request_id_counter; - -- /* All actions except 'hostname' and 'connectivity-change' require a device */ -- if (action == NM_DISPATCHER_ACTION_HOSTNAME -- || action == NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE) { -+ if (!nm_dispatcher_need_device(action)) { - _LOG2D(request_id, - log_ifname, - log_con_uuid, -@@ -592,9 +593,8 @@ _dispatcher_call(NMDispatcherAction action, - g_variant_builder_init(&vpn_ip4_props, G_VARIANT_TYPE_VARDICT); - g_variant_builder_init(&vpn_ip6_props, G_VARIANT_TYPE_VARDICT); - -- /* hostname and connectivity-change actions don't send device data */ -- if (action != NM_DISPATCHER_ACTION_HOSTNAME -- && action != NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE) { -+ /* hostname, DNS and connectivity-change actions don't send device data */ -+ if (nm_dispatcher_need_device(action)) { - fill_device_props(device, - &device_props, - &device_proxy_props, -@@ -925,6 +925,30 @@ nm_dispatcher_call_connectivity(NMConnectivityState connectivity_state, - out_call_id); - } - -+/** -+ * nm_dispatcher_call_dns_change(): -+ * -+ * This method does not block the caller. -+ * -+ * Returns: %TRUE if the action was dispatched, %FALSE on failure -+ */ -+gboolean -+nm_dispatcher_call_dns_change(void) -+{ -+ return _dispatcher_call(NM_DISPATCHER_ACTION_DNS_CHANGE, -+ FALSE, -+ NULL, -+ NULL, -+ NULL, -+ FALSE, -+ NM_CONNECTIVITY_UNKNOWN, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ NULL); -+} -+ - void - nm_dispatcher_call_cancel(NMDispatcherCallId *call_id) - { -@@ -937,3 +961,16 @@ nm_dispatcher_call_cancel(NMDispatcherCallId *call_id) - _LOG3D(call_id, "cancelling dispatcher callback action"); - call_id->callback = NULL; - } -+ -+/* All actions except 'hostname', 'connectivity-change' and 'dns-change' require -+ * a device */ -+static gboolean -+nm_dispatcher_need_device(NMDispatcherAction action) -+{ -+ if (action == NM_DISPATCHER_ACTION_HOSTNAME -+ || action == NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE -+ || action == NM_DISPATCHER_ACTION_DNS_CHANGE) { -+ return FALSE; -+ } -+ return TRUE; -+} -diff --git a/src/core/nm-dispatcher.h b/src/core/nm-dispatcher.h -index 3071639922..a1cb96b798 100644 ---- a/src/core/nm-dispatcher.h -+++ b/src/core/nm-dispatcher.h -@@ -23,6 +23,7 @@ typedef enum { - NM_DISPATCHER_ACTION_DHCP_CHANGE_6, - NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE, - NM_DISPATCHER_ACTION_REAPPLY, -+ NM_DISPATCHER_ACTION_DNS_CHANGE, - } NMDispatcherAction; - - #define NM_DISPATCHER_ACTION_DHCP_CHANGE_X(IS_IPv4) \ -@@ -69,6 +70,8 @@ gboolean nm_dispatcher_call_connectivity(NMConnectivityState state, - gpointer user_data, - NMDispatcherCallId **out_call_id); - -+gboolean nm_dispatcher_call_dns_change(void); -+ - void nm_dispatcher_call_cancel(NMDispatcherCallId *call_id); - - #endif /* __NM_DISPATCHER_H__ */ -diff --git a/src/core/nm-policy.c b/src/core/nm-policy.c -index 1cf6b3398d..2873847df3 100644 ---- a/src/core/nm-policy.c -+++ b/src/core/nm-policy.c -@@ -2642,6 +2642,8 @@ dns_config_changed(NMDnsManager *dns_manager, gpointer user_data) - - update_system_hostname(self, "DNS configuration changed"); - } -+ -+ nm_dispatcher_call_dns_change(); - } - - static void -diff --git a/src/libnm-core-aux-extern/nm-dispatcher-api.h b/src/libnm-core-aux-extern/nm-dispatcher-api.h -index 56da5fba7a..7cb370a92e 100644 ---- a/src/libnm-core-aux-extern/nm-dispatcher-api.h -+++ b/src/libnm-core-aux-extern/nm-dispatcher-api.h -@@ -34,6 +34,7 @@ - #define NMD_ACTION_DHCP6_CHANGE "dhcp6-change" - #define NMD_ACTION_CONNECTIVITY_CHANGE "connectivity-change" - #define NMD_ACTION_REAPPLY "reapply" -+#define NMD_ACTION_DNS_CHANGE "dns-change" - - typedef enum { - DISPATCH_RESULT_UNKNOWN = 0, -diff --git a/src/nm-dispatcher/nm-dispatcher-utils.c b/src/nm-dispatcher/nm-dispatcher-utils.c -index 74ea4e4001..f8a4c28000 100644 ---- a/src/nm-dispatcher/nm-dispatcher-utils.c -+++ b/src/nm-dispatcher/nm-dispatcher-utils.c -@@ -453,8 +453,12 @@ nm_dispatcher_utils_construct_envp(const char *action, - - items = g_ptr_array_new_with_free_func(g_free); - -- /* Hostname and connectivity changes don't require a device nor contain a connection */ -- if (NM_IN_STRSET(action, NMD_ACTION_HOSTNAME, NMD_ACTION_CONNECTIVITY_CHANGE)) -+ /* Hostname, dns and connectivity changes don't require a device nor contain -+ * a connection */ -+ if (NM_IN_STRSET(action, -+ NMD_ACTION_HOSTNAME, -+ NMD_ACTION_CONNECTIVITY_CHANGE, -+ NMD_ACTION_DNS_CHANGE)) - goto done; - - /* Connection properties */ --- -2.41.0 - diff --git a/SOURCES/1003-do-not-allow-ovs-bridge-and-port-to-be-parent-rhel-28545.patch b/SOURCES/1003-do-not-allow-ovs-bridge-and-port-to-be-parent-rhel-28545.patch new file mode 100644 index 0000000..013905f --- /dev/null +++ b/SOURCES/1003-do-not-allow-ovs-bridge-and-port-to-be-parent-rhel-28545.patch @@ -0,0 +1,127 @@ +From cf230074965216c94bb25bc3c3fff7f1d698c250 Mon Sep 17 00:00:00 2001 +From: Gris Ge +Date: Fri, 15 Mar 2024 15:46:02 +0800 +Subject: [PATCH] ovs: Do not allow OVS bridge and port to be parent + +When creating VLAN over OVS internal interface which holding the same +name as its controller OVS bridge, NetworkManager will fail with error: + + Error: Connection activation failed: br0.101 failed to create + resources: cannot retrieve ifindex of interface br0 (Open vSwitch + Bridge) + +Expanded the `find_device_by_iface()` with additional argument +`child: NmConnection *` which will validate whether candidate is +suitable to be parent device. + +In `nm_device_check_parent_connection_compatible()`, we only not allow OVS +bridge and OVS port being parent. + +Resolves: https://issues.redhat.com/browse/RHEL-26753 + +Signed-off-by: Gris Ge +(cherry picked from commit 7096f52a5967ef053a4cf8e5ca8a71c1495578f9) +(cherry picked from commit d3329f0599f5fdfc2ef9f2c1395b5eb7bcc3c2a5) +--- + src/core/devices/nm-device.c | 11 +++++++++++ + src/core/devices/nm-device.h | 1 + + src/core/nm-manager.c | 14 +++++++++----- + 3 files changed, 21 insertions(+), 5 deletions(-) + +diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c +index 30c38ba990..78b0e618be 100644 +--- a/src/core/devices/nm-device.c ++++ b/src/core/devices/nm-device.c +@@ -9508,6 +9508,17 @@ nm_device_check_slave_connection_compatible(NMDevice *self, NMConnection *slave) + return nm_streq(connection_type, slave_type); + } + ++gboolean ++nm_device_can_be_parent(NMDevice *self) ++{ ++ NMDeviceType device_type = nm_device_get_device_type(self); ++ ++ if ((device_type == NM_DEVICE_TYPE_OVS_BRIDGE) || (device_type == NM_DEVICE_TYPE_OVS_PORT)) ++ return FALSE; ++ else ++ return TRUE; ++} ++ + /** + * nm_device_can_assume_connections: + * @self: #NMDevice instance +diff --git a/src/core/devices/nm-device.h b/src/core/devices/nm-device.h +index b096d23ac1..7353a3f327 100644 +--- a/src/core/devices/nm-device.h ++++ b/src/core/devices/nm-device.h +@@ -550,6 +550,7 @@ gboolean nm_device_check_connection_compatible(NMDevice *device, + GError **error); + + gboolean nm_device_check_slave_connection_compatible(NMDevice *device, NMConnection *connection); ++gboolean nm_device_can_be_parent(NMDevice *device); + + gboolean nm_device_can_assume_connections(NMDevice *self); + gboolean nm_device_unmanage_on_quit(NMDevice *self); +diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c +index 6739e5599e..7f94f7cd9c 100644 +--- a/src/core/nm-manager.c ++++ b/src/core/nm-manager.c +@@ -1914,7 +1914,8 @@ find_device_by_ip_iface(NMManager *self, const char *iface) + * is given, this function will only return master devices and will ensure + * @slave, when activated, can be a slave of the returned master device. If + * @connection is given, this function will only consider devices that are +- * compatible with @connection. ++ * compatible with @connection. If @child is given, this function will only ++ * return parent device. + * + * Returns: the matching #NMDevice + */ +@@ -1922,7 +1923,8 @@ static NMDevice * + find_device_by_iface(NMManager *self, + const char *iface, + NMConnection *connection, +- NMConnection *slave) ++ NMConnection *slave, ++ NMConnection *child) + { + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self); + NMDevice *fallback = NULL; +@@ -1941,6 +1943,8 @@ find_device_by_iface(NMManager *self, + if (!nm_device_check_slave_connection_compatible(candidate, slave)) + continue; + } ++ if (child && !nm_device_can_be_parent(candidate)) ++ continue; + + if (nm_device_is_real(candidate)) + return candidate; +@@ -2405,7 +2409,7 @@ find_parent_device_for_connection(NMManager *self, + NM_SET_OUT(out_parent_spec, parent_name); + + /* Try as an interface name of a parent device */ +- parent = find_device_by_iface(self, parent_name, NULL, NULL); ++ parent = find_device_by_iface(self, parent_name, NULL, NULL, connection); + if (parent) + return parent; + +@@ -5003,7 +5007,7 @@ find_master(NMManager *self, + } + + if (!master_connection) { +- master_device = find_device_by_iface(self, master, NULL, connection); ++ master_device = find_device_by_iface(self, master, NULL, connection, NULL); + if (!master_device) { + g_set_error(error, + NM_MANAGER_ERROR, +@@ -6445,7 +6449,7 @@ validate_activation_request(NMManager *self, + if (!iface) + return NULL; + +- device = find_device_by_iface(self, iface, connection, NULL); ++ device = find_device_by_iface(self, iface, connection, NULL, NULL); + if (!device) { + g_set_error_literal(error, + NM_MANAGER_ERROR, +-- +2.44.0 + diff --git a/SOURCES/1004-bridge-skip-VLAN-filtering-resetting-in-reapply-RHEL-25061.patch b/SOURCES/1004-bridge-skip-VLAN-filtering-resetting-in-reapply-RHEL-25061.patch deleted file mode 100644 index 7ed37c2..0000000 --- a/SOURCES/1004-bridge-skip-VLAN-filtering-resetting-in-reapply-RHEL-25061.patch +++ /dev/null @@ -1,270 +0,0 @@ -From 8f8845484ee74b1934cbd5f0cca997ba0504d543 Mon Sep 17 00:00:00 2001 -From: Gris Ge -Date: Thu, 8 Feb 2024 23:36:34 +0800 -Subject: [PATCH] bridge: skip VLAN filtering resetting in reapply if no vlan - change changed - -When doing reapply on linux bridge interface, NetworkManager will reset -the VLAN filtering and default PVID which cause PVID been readded to all -bridge ports regardless they are managed by NetworkManager. - -This is because Linux kernel will re-add PVID to bridge port upon the -changes of bridge default-pvid value. - -To fix the issue, this patch introduce netlink parsing code for -`vlan_filtering` and `default_pvid` of NMPlatformLnkBridge, and use that -to compare desired VLAN filtering settings, skip the reset of VLAN -filter if `default_pvid` and `vlan_filtering` are unchanged. - -Signed-off-by: Gris Ge -(cherry picked from commit 02c34d538c6a2b22bd09318496ba104eb43246b4) -(cherry picked from commit f990f9b4e4ffb5195fc89c4a8c6f251c0e01b501) -(cherry picked from commit c448e225198f7f8851fc01a8394529e7cbe25d4d) ---- - src/core/devices/nm-device-bridge.c | 79 +++++++++++++++++--------- - src/core/platform/tests/test-link.c | 2 + - src/libnm-platform/nm-linux-platform.c | 6 ++ - src/libnm-platform/nm-platform.c | 13 ++++- - src/libnm-platform/nm-platform.h | 2 + - 5 files changed, 72 insertions(+), 30 deletions(-) - -diff --git a/src/core/devices/nm-device-bridge.c b/src/core/devices/nm-device-bridge.c -index 9a45dbf3fc..73effc50b4 100644 ---- a/src/core/devices/nm-device-bridge.c -+++ b/src/core/devices/nm-device-bridge.c -@@ -712,7 +712,27 @@ master_update_slave_connection(NMDevice *device, - } - - static gboolean --bridge_set_vlan_options(NMDevice *device, NMSettingBridge *s_bridge) -+is_bridge_pvid_changed(NMDevice *device, NMSettingBridge *s_bridge) -+{ -+ int ifindex = nm_device_get_ifindex(device); -+ const NMPlatformLnkBridge *nmp_link_br; -+ NMPlatform *platform = nm_device_get_platform(device); -+ bool desired_vlan_filtering = nm_setting_bridge_get_vlan_filtering(s_bridge); -+ guint16 desired_pvid = nm_setting_bridge_get_vlan_default_pvid(s_bridge); -+ -+ nm_platform_link_refresh(platform, ifindex); -+ nmp_link_br = nm_platform_link_get_lnk_bridge(platform, ifindex, NULL); -+ -+ if (nmp_link_br) { -+ return desired_vlan_filtering != nmp_link_br->vlan_filtering -+ || desired_pvid != nmp_link_br->default_pvid; -+ } else { -+ return TRUE; -+ } -+} -+ -+static gboolean -+bridge_set_vlan_options(NMDevice *device, NMSettingBridge *s_bridge, gboolean is_reapply) - { - NMDeviceBridge *self = NM_DEVICE_BRIDGE(device); - gconstpointer hwaddr; -@@ -753,31 +773,37 @@ bridge_set_vlan_options(NMDevice *device, NMSettingBridge *s_bridge) - - self->vlan_configured = TRUE; - -- /* Filtering must be disabled to change the default PVID. -- * Clear the default PVID so that we later can force the re-creation of -- * default PVID VLANs by writing the option again. */ -- -- nm_platform_link_set_bridge_info( -- plat, -- ifindex, -- &((NMPlatformLinkSetBridgeInfoData){.vlan_filtering_has = TRUE, -- .vlan_filtering_val = FALSE, -- .vlan_default_pvid_has = TRUE, -- .vlan_default_pvid_val = 0})); -+ if (!is_reapply || is_bridge_pvid_changed(device, s_bridge)) { -+ /* Filtering must be disabled to change the default PVID. -+ * Clear the default PVID so that we later can force the re-creation of -+ * default PVID VLANs by writing the option again. */ - -- /* Clear all existing VLANs */ -- if (!nm_platform_link_set_bridge_vlans(plat, ifindex, FALSE, NULL)) -- return FALSE; -+ if (is_reapply) { -+ _LOGD(LOGD_BRIDGE, "default_pvid is changed, resetting bridge VLAN filtering"); -+ } - -- /* Now set the default PVID. After this point the kernel creates -- * a PVID VLAN on each port, including the bridge itself. */ -- pvid = nm_setting_bridge_get_vlan_default_pvid(s_bridge); -- if (pvid) { - nm_platform_link_set_bridge_info( - plat, - ifindex, -- &((NMPlatformLinkSetBridgeInfoData){.vlan_default_pvid_has = TRUE, -- .vlan_default_pvid_val = pvid})); -+ &((NMPlatformLinkSetBridgeInfoData){.vlan_filtering_has = TRUE, -+ .vlan_filtering_val = FALSE, -+ .vlan_default_pvid_has = TRUE, -+ .vlan_default_pvid_val = 0})); -+ -+ /* Clear all existing VLANs */ -+ if (!nm_platform_link_set_bridge_vlans(plat, ifindex, FALSE, NULL)) -+ return FALSE; -+ -+ /* Now set the default PVID. After this point the kernel creates -+ * a PVID VLAN on each port, including the bridge itself. */ -+ pvid = nm_setting_bridge_get_vlan_default_pvid(s_bridge); -+ if (pvid) { -+ nm_platform_link_set_bridge_info( -+ plat, -+ ifindex, -+ &((NMPlatformLinkSetBridgeInfoData){.vlan_default_pvid_has = TRUE, -+ .vlan_default_pvid_val = pvid})); -+ } - } - - /* Create VLANs only after setting the default PVID, so that -@@ -836,7 +862,7 @@ _platform_lnk_bridge_init_from_setting(NMSettingBridge *s_bridge, NMPlatformLnkB - } - - static gboolean --link_config(NMDevice *device, NMConnection *connection) -+link_config(NMDevice *device, NMConnection *connection, gboolean is_reapply) - { - int ifindex = nm_device_get_ifindex(device); - NMSettingBridge *s_bridge; -@@ -850,7 +876,7 @@ link_config(NMDevice *device, NMConnection *connection) - if (nm_platform_link_bridge_change(nm_device_get_platform(device), ifindex, &props) < 0) - return FALSE; - -- return bridge_set_vlan_options(device, s_bridge); -+ return bridge_set_vlan_options(device, s_bridge, is_reapply); - } - - static NMActStageReturn -@@ -861,7 +887,7 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) - connection = nm_device_get_applied_connection(device); - g_return_val_if_fail(connection, NM_ACT_STAGE_RETURN_FAILURE); - -- if (!link_config(device, connection)) { -+ if (!link_config(device, connection, FALSE)) { - NM_SET_OUT(out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED); - return NM_ACT_STAGE_RETURN_FAILURE; - } -@@ -1003,7 +1029,7 @@ attach_port(NMDevice *device, - s_port = nm_connection_get_setting_bridge_port(connection); - - if (!nm_device_sys_iface_state_is_external(device)) -- bridge_set_vlan_options(device, s_bridge); -+ bridge_set_vlan_options(device, s_bridge, FALSE); - - if (nm_setting_bridge_get_vlan_filtering(s_bridge)) { - gs_free const NMPlatformBridgeVlan **plat_vlans = NULL; -@@ -1218,8 +1244,7 @@ reapply_connection(NMDevice *device, NMConnection *con_old, NMConnection *con_ne - /* Make sure bridge_set_vlan_options() called by link_config() - * sets vlan_filtering and default_pvid anew. */ - self->vlan_configured = FALSE; -- -- link_config(device, con_new); -+ link_config(device, con_new, TRUE); - } - - /*****************************************************************************/ -diff --git a/src/core/platform/tests/test-link.c b/src/core/platform/tests/test-link.c -index 8a54ac4853..fdece007bc 100644 ---- a/src/core/platform/tests/test-link.c -+++ b/src/core/platform/tests/test-link.c -@@ -1403,6 +1403,8 @@ test_software_detect(gconstpointer user_data) - lnk_bridge.mcast_query_interval = 12000; - lnk_bridge.mcast_query_response_interval = 5200; - lnk_bridge.mcast_startup_query_interval = 3000; -+ lnk_bridge.vlan_filtering = FALSE; -+ lnk_bridge.default_pvid = 1; - - if (!nmtstp_link_bridge_add(NULL, ext, DEVICE_NAME, &lnk_bridge)) - g_error("Failed adding Bridge interface"); -diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c -index 99eab9c784..9b4ac14024 100644 ---- a/src/libnm-platform/nm-linux-platform.c -+++ b/src/libnm-platform/nm-linux-platform.c -@@ -1515,6 +1515,8 @@ _parse_lnk_bridge(const char *kind, struct nlattr *info_data) - [IFLA_BR_MCAST_QUERY_INTVL] = {.type = NLA_U64}, - [IFLA_BR_MCAST_QUERY_RESPONSE_INTVL] = {.type = NLA_U64}, - [IFLA_BR_MCAST_STARTUP_QUERY_INTVL] = {.type = NLA_U64}, -+ [IFLA_BR_VLAN_FILTERING] = {.type = NLA_U8}, -+ [IFLA_BR_VLAN_DEFAULT_PVID] = {.type = NLA_U16}, - }; - NMPlatformLnkBridge *props; - struct nlattr *tb[G_N_ELEMENTS(policy)]; -@@ -1585,6 +1587,10 @@ _parse_lnk_bridge(const char *kind, struct nlattr *info_data) - props->mcast_query_response_interval = nla_get_u64(tb[IFLA_BR_MCAST_QUERY_RESPONSE_INTVL]); - if (tb[IFLA_BR_MCAST_STARTUP_QUERY_INTVL]) - props->mcast_startup_query_interval = nla_get_u64(tb[IFLA_BR_MCAST_STARTUP_QUERY_INTVL]); -+ if (tb[IFLA_BR_VLAN_FILTERING]) -+ props->vlan_filtering = !!nla_get_u8(tb[IFLA_BR_VLAN_FILTERING]); -+ if (tb[IFLA_BR_VLAN_DEFAULT_PVID]) -+ props->default_pvid = nla_get_u16(tb[IFLA_BR_VLAN_DEFAULT_PVID]); - - return obj; - } -diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c -index 041354cf44..3b61375bad 100644 ---- a/src/libnm-platform/nm-platform.c -+++ b/src/libnm-platform/nm-platform.c -@@ -6086,7 +6086,8 @@ nm_platform_lnk_bridge_to_string(const NMPlatformLnkBridge *lnk, char *buf, gsiz - " 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 "", -+ " mcast_startup_query_interval %" G_GUINT64_FORMAT " vlan_filtering %d" -+ " default_pvid %" G_GUINT16_FORMAT "", - lnk->forward_delay, - lnk->hello_time, - lnk->max_age, -@@ -6109,7 +6110,9 @@ nm_platform_lnk_bridge_to_string(const NMPlatformLnkBridge *lnk, char *buf, gsiz - lnk->mcast_querier_interval, - lnk->mcast_query_interval, - lnk->mcast_query_response_interval, -- lnk->mcast_startup_query_interval); -+ lnk->mcast_startup_query_interval, -+ lnk->vlan_filtering, -+ lnk->default_pvid); - return buf; - } - -@@ -7978,12 +7981,14 @@ nm_platform_lnk_bridge_hash_update(const NMPlatformLnkBridge *obj, NMHashState * - obj->mcast_router, - obj->mcast_query_response_interval, - obj->mcast_startup_query_interval, -+ obj->default_pvid, - NM_HASH_COMBINE_BOOLS(guint8, - obj->stp_state, - obj->mcast_querier, - obj->mcast_query_use_ifaddr, - obj->mcast_snooping, -- obj->vlan_stats_enabled)); -+ obj->vlan_stats_enabled, -+ obj->vlan_filtering)); - } - - void -@@ -8124,6 +8129,8 @@ nm_platform_lnk_bridge_cmp(const NMPlatformLnkBridge *a, const NMPlatformLnkBrid - 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); -+ NM_CMP_FIELD_BOOL(a, b, vlan_filtering); -+ NM_CMP_FIELD(a, b, default_pvid); - - return 0; - } -diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h -index aeea5c42db..a4410b0a7c 100644 ---- a/src/libnm-platform/nm-platform.h -+++ b/src/libnm-platform/nm-platform.h -@@ -765,6 +765,8 @@ typedef struct { - bool mcast_snooping : 1; - bool stp_state : 1; - bool vlan_stats_enabled : 1; -+ bool vlan_filtering; -+ guint16 default_pvid; - } _nm_alignas(NMPlatformObject) NMPlatformLnkBridge; - - extern const NMPlatformLnkBridge nm_platform_lnk_bridge_default; --- -2.43.0 - diff --git a/SOURCES/1004-nm-dispatcher-fix-crash-rhel28973.patch b/SOURCES/1004-nm-dispatcher-fix-crash-rhel28973.patch new file mode 100644 index 0000000..87f0d68 --- /dev/null +++ b/SOURCES/1004-nm-dispatcher-fix-crash-rhel28973.patch @@ -0,0 +1,50 @@ +From e4fb80046cf36a7e210e8660ef50c93ef8971a5e Mon Sep 17 00:00:00 2001 +From: Beniamino Galvani +Date: Wed, 13 Mar 2024 10:47:31 +0100 +Subject: [PATCH 1/2] nm-dispatcher: fix crash when parsing output dictionary + +'stdout' is NULL when the script didn't write anything or failed. + +Fixes the following crash detected by NMCI in test +'dispatcher_device_handler_dummy'. + + nm-dispatcher[936339]: g_strsplit: assertion 'string != NULL' failed + + build_result_options (nm-dispatcher) + complete_request (nm-dispatcher) + complete_script (nm-dispatcher) + script_watch_cb (nm-dispatcher) + g_child_watch_dispatch (libglib-2.0.so.0) + g_main_dispatch (libglib-2.0.so.0) + g_main_context_iterate (libglib-2.0.so.0) + g_main_context_iteration (libglib-2.0.so.0) + main (nm-dispatcher) + __libc_start_main (libc.so.6) + _start (nm-dispatcher) + +Fixes: d72f26b87528 ('dispatcher: read device-handler's stdout into a dictionary') + +https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1889 +(cherry picked from commit e5c2c5f1c2f55c139f39830651df2c901c3a0bf9) +(cherry picked from commit 669bf33de38a8a15e77662daadf94d6395838eee) +--- + src/nm-dispatcher/nm-dispatcher.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/nm-dispatcher/nm-dispatcher.c b/src/nm-dispatcher/nm-dispatcher.c +index efb4ec0087..ce252b92bf 100644 +--- a/src/nm-dispatcher/nm-dispatcher.c ++++ b/src/nm-dispatcher/nm-dispatcher.c +@@ -306,6 +306,9 @@ build_result_options(char *stdout) + char *key; + char *value; + ++ if (!stdout) ++ return NULL; ++ + lines = g_strsplit(stdout, "\n", 65); + + for (i = 0; lines[i] && i < 64; i++) { +-- +2.41.0 + diff --git a/SOURCES/1005-fix-race-condition-while-enumerating-devices-rhel25808.patch b/SOURCES/1005-fix-race-condition-while-enumerating-devices-rhel25808.patch new file mode 100644 index 0000000..48d6cc5 --- /dev/null +++ b/SOURCES/1005-fix-race-condition-while-enumerating-devices-rhel25808.patch @@ -0,0 +1,66 @@ +From 8ff08068342d1d8efe1e6d6c9a241e3395641a76 Mon Sep 17 00:00:00 2001 +From: Beniamino Galvani +Date: Thu, 21 Mar 2024 09:45:15 +0100 +Subject: [PATCH 2/2] manager: fix race condition while enumerating devices at + startup + +While enumerating devices at startup, we take a snapshot of existing +links from platform and we start creating device instances for +them. It's possible that in the meantime, while processing netlink +events in platform_link_added(), a link gets renamed. If that happens, +then we have two different views of the same ifindex: the cached link +from `links` and the link in platform. + +This can cause issues: in platform_link_added() we create the device +with the cached name; then in NMDevice's constructor(), we look up +from platform the ifindex for the given name. Because of the rename, +this lookup can match a newly created, different link. + +The end result is that the ifindex from the initial snapshot doesn't +get a NMDevice and is not handled by NetworkManager. + +Fix this problem by fetching the latest version of the link from +platform to make sure we have a consistent view of the state. + +https://issues.redhat.com/browse/RHEL-25808 +https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1897 +(cherry picked from commit de130df3e2207dc015c4fa82ecf766be2851532c) +(cherry picked from commit 6f3739e76f1f31d71bc3fbd7a4b0955071d59cc4) +--- + src/core/nm-manager.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c +index 7f94f7cd9c..a77ba9d3b1 100644 +--- a/src/core/nm-manager.c ++++ b/src/core/nm-manager.c +@@ -4438,10 +4438,25 @@ platform_query_devices(NMManager *self) + links = nm_platform_link_get_all(priv->platform); + if (!links) + return; ++ + for (i = 0; i < links->len; i++) { +- const NMPlatformLink *link = NMP_OBJECT_CAST_LINK(links->pdata[i]); ++ const NMPlatformLink *elem = NMP_OBJECT_CAST_LINK(links->pdata[i]); ++ const NMPlatformLink *link; + const NMConfigDeviceStateData *dev_state; + ++ /* ++ * @links is an immutable snapshot of the platform links captured before ++ * the loop was started. It's possible that in the meantime, while ++ * processing netlink events in platform_link_added(), a link was ++ * renamed. If that happens, we have 2 different views of the same ++ * ifindex: the one from @links and the one from platform. This can ++ * cause race conditions; make sure to use the latest known version of ++ * the link. ++ */ ++ link = nm_platform_link_get(priv->platform, elem->ifindex); ++ if (!link) ++ continue; ++ + dev_state = nm_config_device_state_get(priv->config, link->ifindex); + platform_link_added(self, + link->ifindex, +-- +2.41.0 + diff --git a/SOURCES/22-wifi-mac-addr.conf b/SOURCES/22-wifi-mac-addr.conf new file mode 100644 index 0000000..2e329c8 --- /dev/null +++ b/SOURCES/22-wifi-mac-addr.conf @@ -0,0 +1,31 @@ +# This sets defaults for Wi-Fi profiles to set a generated, stable MAC address. +# +# Do not modify this file. You can hide/overwrite this file by placing a file +# to "/etc/NetworkManager/conf.d/22-wifi-mac-addr.conf". You can also add +# configuration snippets with higher priority that override this setting (see +# `man 5 NetworkManager.conf`). Most importantly, this snippet only sets +# default values for the profile. You can explicitly set the value for each +# profile, so that this default value is not used. +# +# For example, on a particular profile/network set +# +# $ nmcli connection modify "$PROFILE" wifi.cloned-mac-address permanent +# +# to use the hardware MAC address. This prevents the default from this file +# to take effect. +# +# Or +# +# $ nmcli connection modify "$PROFILE" wifi.cloned-mac-address stable connection.stable-id '${NETWORK_SSID}/${BOOT}' +# +# to get a generated MAC address that changes on each boot. Note how setting +# "connection.stable-id" also affects other aspects of the profile. +# +# See `man 5 nm-settings` for "wifi.cloned-mac-address" and "connection.stable-id". + +[connection.22-wifi-mac-addr] +match-device=type:wifi +wifi.cloned-mac-address=stable-ssid + +[.config] +enable=nm-version-min:1.45 diff --git a/SOURCES/readme-ifcfg-rh-migrated.txt b/SOURCES/readme-ifcfg-rh-migrated.txt new file mode 100644 index 0000000..aabbcc8 --- /dev/null +++ b/SOURCES/readme-ifcfg-rh-migrated.txt @@ -0,0 +1,84 @@ +NetworkManager was built to automatically migrate connection profiles in +this directory to equivalent ones in keyfile format in directory +/etc/NetworkManager/system-connections. + +You can check whether the migration is enabled via: + + $ NetworkManager --print-config | grep migrate-ifcfg-rh + +In case it is enabled, all files in this directory are migrated at startup. + +To inspect where your connection files are currently stored use: + + $ nmcli -f name,uuid,filename connection + +Background +========== + +The ifcfg format is deprecated and will be removed in future releases. For +more information see: + +https://lists.freedesktop.org/archives/networkmanager/2023-May/000103.html + +Connection profiles in keyfile format have many benefits. For example, this +format is INI file-based and can easily be parsed and generated. + +Each section in NetworkManager keyfiles corresponds to a NetworkManager +setting name as described in the nm-settings(5) and nm-settings-keyfile(5) +man pages. Each key-value pair in a section is one of the properties listed +in the settings specification of the man page. + +How to keep using ifcfg +======================= + +If you want to keep using connection profiles in ifcfg format, you need to: + + - disable the automatic migration to keyfile by setting + "migrate-ifcfg-rh=false" in the [main] section of NetworkManager + configuration; + + - optionally, set "plugins=ifcfg-rh" in the [main] section of + NetworkManager configuration so that new profiles are created in ifcfg + format. + +At this point, you can migrate all your files back via + + nmcli connection migrate --plugin ifcfg-rh + +Or, if you prefer to migrate only specific connections: + + nmcli connection migrate --plugin ifcfg-rh + +Note that some connection types are not supported by the ifcfg plugin. + +Interface renaming +================== + +Connection profiles stored in ifcfg-rh format support the renaming of +interfaces via udev. This is done via a helper tool +/usr/lib/udev/rename_device that is invoked by udev to parse the files +in /etc/sysconfig/network-scripts; when the HWADDR and DEVICE +variables are set, the interface that matches the MAC address in +HWADDR is renamed to the name specified in DEVICE. + +Connections in keyfile format don't provide the same integration with +udev. The renaming of interfaces must be configured directly in udev, +for example by creating a file: + + /etc/systemd/network/70-rename.link + +with content: + + [Match] + MACAddress=00:11:22:33:44:56 + + [Link] + Name=ethernet1 + +Alternatively, a udev rule can also be used, such as: + + /etc/udev/rules.d/70-interface-names.rules + +with content: + + SUBSYSTEM=="net",ACTION=="add",ATTR{address}=="00:11:22:33:44:56",ATTR{type}=="1",NAME="ethernet1" diff --git a/SPECS/NetworkManager.spec b/SPECS/NetworkManager.spec index 641062c..f87bc49 100644 --- a/SPECS/NetworkManager.spec +++ b/SPECS/NetworkManager.spec @@ -1,12 +1,13 @@ + %global wpa_supplicant_version 1:1.1 %global ppp_version %(pkg-config --modversion pppd 2>/dev/null || sed -n 's/^#define\\s*VERSION\\s*"\\([^\\s]*\\)"$/\\1/p' %{_includedir}/pppd/patchlevel.h 2>/dev/null | grep . || echo bad) %global glib2_version %(pkg-config --modversion glib-2.0 2>/dev/null || echo bad) %global epoch_version 1 -%global real_version 1.44.0 +%global real_version 1.46.0 %global rpm_version %{real_version} -%global release_version 5 +%global release_version 4 %global snapshot %{nil} %global git_sha %{nil} %global bcond_default_debug 0 @@ -155,12 +156,18 @@ %global split_ifcfg_rh 0 %endif -%if 0%{?fedora} >= 36 || 0%{?rhel} >= 9 +%if (0%{?fedora} >= 36 && 0%{?fedora} < 39) || 0%{?rhel} >= 9 %global ifcfg_warning 1 %else %global ifcfg_warning 0 %endif +%if 0%{?fedora} >= 39 +%global ifcfg_migrate 1 +%else +%global ifcfg_migrate 0 +%endif + %if 0%{?fedora} # Although eBPF would be available on Fedora's kernel, it seems # we often get SELinux denials (rh#1651654). But even aside them, @@ -185,7 +192,7 @@ Epoch: %{epoch_version} Version: %{rpm_version} Release: %{release_version}%{?snap}%{?dist} Group: System Environment/Base -License: GPLv2+ and LGPLv2+ +License: GPL-2.0-or-later AND LGPL-2.1-or-later URL: https://networkmanager.dev/ Source: https://download.gnome.org/sources/NetworkManager/%{real_version_major}/%{name}-%{real_version}.tar.xz @@ -193,19 +200,24 @@ Source1: NetworkManager.conf Source2: 00-server.conf Source4: 20-connectivity-fedora.conf Source5: 20-connectivity-redhat.conf -Source6: 70-nm-connectivity.conf -Source7: readme-ifcfg-rh.txt +Source6: 22-wifi-mac-addr.conf +Source7: 70-nm-connectivity.conf +Source8: readme-ifcfg-rh.txt +Source9: readme-ifcfg-rh-migrated.txt # RHEL downstream patches that change behavior from upstream. # These are not bugfixes, hence they are also relevant after # the next rebase of the source tarball. # Patch0001: 0001-some.patch +Patch0001: 0001-revert-change-default-value-for-ipv4.dad-timeout-from-0-to-200ms.patch # Bugfixes that are only relevant until next rebase of the package. -Patch1001: 1001-nm-manager-ensure-device-is-exported-on-D-Bus-in-aut-rhbz2210271.patch -Patch1002: 1002-checkpoint-Fix-segfault-crash-when-rollback-rhel-1526.patch -Patch1003: 1003-better-way-for-dns-changes-RHEL-14889.patch -Patch1004: 1004-bridge-skip-VLAN-filtering-resetting-in-reapply-RHEL-25061.patch +# Patch1001: 1001-some.patch +Patch1001: 1001-drop-privateusers-directive-from-nm-cloud-setup-rhel27053.patch +Patch1002: 1002-allow-rollback-on-internal-global-dns-rhel-29725.patch +Patch1003: 1003-do-not-allow-ovs-bridge-and-port-to-be-parent-rhel-28545.patch +Patch1004: 1004-nm-dispatcher-fix-crash-rhel28973.patch +Patch1005: 1005-fix-race-condition-while-enumerating-devices-rhel25808.patch Requires(post): systemd %if 0%{?fedora} || 0%{?rhel} >= 8 @@ -224,7 +236,7 @@ Requires: libndp >= %{libndp_version} %endif Obsoletes: NetworkManager < %{obsoletes_device_plugins} Obsoletes: NetworkManager < %{obsoletes_ppp_plugin} -Obsoletes: NetworkManager-wimax < 1.2 +Obsoletes: NetworkManager-wimax < 1:1.2 %if 0%{?rhel} && 0%{?rhel} == 8 Suggests: NetworkManager-initscripts-updown %endif @@ -295,21 +307,10 @@ BuildRequires: mobile-broadband-provider-info-devel BuildRequires: newt-devel %endif BuildRequires: /usr/bin/dbus-launch -%if 0%{?fedora} >= 28 || 0%{?rhel} >= 8 BuildRequires: python3 BuildRequires: python3-gobject-base BuildRequires: python3-dbus BuildRequires: python3-pexpect -%else -BuildRequires: python2 -BuildRequires: pygobject3-base -BuildRequires: dbus-python -BuildRequires: pexpect -%if 0%{?rhel} >= 7 && %{with meson} -BuildRequires: python36-dbus -BuildRequires: python36-gobject -%endif -%endif BuildRequires: libselinux-devel BuildRequires: polkit-devel BuildRequires: jansson-devel @@ -392,7 +393,7 @@ Obsoletes: NetworkManager < %{obsoletes_device_plugins} # Team was split from main NM binary between 0.9.10 and 1.0 # We need this Obsoletes in addition to the one above # (git:3aede801521ef7bff039e6e3f1b3c7b566b4338d). -Obsoletes: NetworkManager < 1.0.0 +Obsoletes: NetworkManager < 1:1.0.0 %endif %description team @@ -480,7 +481,7 @@ This package contains NetworkManager support for PPP. Summary: Libraries for adding NetworkManager support to applications. Group: Development/Libraries Conflicts: NetworkManager-glib < 1:1.31.0 -License: LGPLv2+ +License: LGPL-2.1-or-later %description libnm This package contains the libraries that make it easier to use some @@ -493,7 +494,7 @@ Group: Development/Libraries Requires: %{name}-libnm%{?_isa} = %{epoch}:%{version}-%{release} Requires: glib2-devel Requires: pkgconfig -License: LGPLv2+ +License: LGPL-2.1-or-later %description libnm-devel This package contains the header and pkg-config files for development @@ -742,6 +743,9 @@ Preferably use nmcli instead. -Ddist_version=%{version}-%{release} \ %if %{?config_plugins_default_ifcfg_rh} -Dconfig_plugins_default=ifcfg-rh \ +%endif +%if %{?ifcfg_migrate} + -Dconfig_migrate_ifcfg_rh_default=true \ %endif -Dresolvconf=no \ -Dnetconfig=no \ @@ -887,6 +891,9 @@ autoreconf --install --force --with-dist-version=%{version}-%{release} \ %if %{?config_plugins_default_ifcfg_rh} --with-config-plugins-default=ifcfg-rh \ +%endif +%if %{?ifcfg_migrate} + --with-config-migrate-ifcfg-rh-default=yes \ %endif --with-resolvconf=no \ --with-netconfig=no \ @@ -915,11 +922,18 @@ cp %{SOURCE4} %{buildroot}%{nmlibdir}/conf.d/ %if %{with connectivity_redhat} cp %{SOURCE5} %{buildroot}%{nmlibdir}/conf.d/ mkdir -p %{buildroot}%{_sysctldir} -cp %{SOURCE6} %{buildroot}%{_sysctldir} +cp %{SOURCE7} %{buildroot}%{_sysctldir} +%endif + +%if 0%{?fedora} >= 40 +cp %{SOURCE6} %{buildroot}%{nmlibdir}/conf.d/ %endif %if 0%{?ifcfg_warning} -cp %{SOURCE7} %{buildroot}%{_sysconfdir}/sysconfig/network-scripts +cp %{SOURCE8} %{buildroot}%{_sysconfdir}/sysconfig/network-scripts +%endif +%if 0%{?ifcfg_migrate} +cp %{SOURCE9} %{buildroot}%{_sysconfdir}/sysconfig/network-scripts/readme-ifcfg-rh.txt %endif cp examples/dispatcher/10-ifcfg-rh-routes.sh %{buildroot}%{nmlibdir}/dispatcher.d/ @@ -1066,6 +1080,9 @@ fi %dir %{_sysconfdir}/%{name}/dnsmasq-shared.d %dir %{_sysconfdir}/%{name}/system-connections %config(noreplace) %{_sysconfdir}/%{name}/NetworkManager.conf +%if 0%{?fedora} >= 40 +%{nmlibdir}/conf.d/22-wifi-mac-addr.conf +%endif %ghost %{_sysconfdir}/%{name}/VPN %{_bindir}/nm-online %{_libexecdir}/nm-dhcp-helper @@ -1112,7 +1129,7 @@ fi %{_unitdir}/nm-priv-helper.service %dir %{_datadir}/doc/NetworkManager/examples %{_datadir}/doc/NetworkManager/examples/server.conf -%if 0%{?ifcfg_warning} +%if 0%{?ifcfg_warning} || 0%{?ifcfg_migrate} %{_sysconfdir}/sysconfig/network-scripts/readme-ifcfg-rh.txt %endif %doc NEWS AUTHORS README.md CONTRIBUTING.md @@ -1255,11 +1272,81 @@ fi %changelog -* Wed Feb 21 2024 Fernando Fernandez Mancera - 1:1.44.0-5 -- skip VLAN filtering resetting in reapply if no vlan change changed (RHEL-25061) - -* Fri Nov 17 2023 Íñigo Huguet - 1:1.44.0-4 -- Add 'dns-change' dispatch event (RHEL-14889) +* Tue Mar 26 2024 Beniamino Galvani - 1:1.46.0-4 +- Fix nm-dispatcher crash (RHEL-28973) +- Fix race condition while enumerating devices (RHEL-25808) + +* Fri Mar 22 2024 Fernando Fernandez Mancera - 1:1.46.0-3 +- Upgrade release number to build with the right target + +* Wed Mar 20 2024 Fernando Fernandez Mancera - 1.46.0-2 +- Drop PrivateUser directive from nm-cloud-setup service (RHEL-27503) +- Support rollback on global DNS (RHEL-29725) +- Do not allow OVS bridge or port to be parent (RHEL-28545) + +* Thu Feb 22 2024 Stanislas FAYE - 1.46.0-1 +- Update to 1.46.0 release +- Fix DHCPv4 lease can't be renewed after it expires (RHEL-24127) +- Support the MACsec offload mode (RHEL-24337) +- Support creating generic devices via external "device-handler" dispatcher (RHEL-1567) +- Support changing the eswitch mode (RHEL-1441) + +* Fri Feb 09 2024 Íñigo Huguet - 1.45.91-1 +- Update to 1.45.91 release (release candidate) +- Support changing the DSCP header field for DHCP packets, and set the default to CS0 (RHEL-16040) +- Deprecate connection.autoconnect-slaves in favour of autoconnect-ports (RHEL-17621) +- Don't reset bridge's PVID in reapply if it didn't change (RHEL-21576) + +* Thu Jan 25 2024 Stanislas FAYE - 1.45.90-1 +- Update to 1.45.90 release (release candidate) +- Deprecate and Replace connection.slave-type in libnm-core and libnm (RHEL-17620) +- [RFE] Support assigning IPv4 static route to interface without IPv4 address (RHEL-5098) + +* Mon Jan 15 2024 Stanislas FAYE - 1.45.10-1 +- Update to 1.45.10 (development) +- Deprecate and Replace connection.master in libnm-core and libnm (RHEL-17619) + +* Thu Dec 14 2023 Ján Václav - 1.45.9-1 +- Update to 1.45.9 (development) +- Add support for PRP/HSR interface (RHEL-5852) +- Drop support for the 'slaves-order' option in NetworkManager.conf (RHEL-19437) +- Return error when setting invalid IP addresses or properties via D-Bus (RHEL-19315) +- Fix extra route being created besides ECMP route (RHEL-1682) + +* Wed Nov 29 2023 Beniamino Galvani - 1.45.8-1 +- Update to 1.45.8 (development) +- Introduce "stable-ssid" option for wifi.cloned-mac-address property (RHEL-16470) + +* Thu Nov 16 2023 Íñigo Huguet - 1.45.7-1 +- Update to 1.45.7 release (development) +- Migrate to SPDX license + +* Wed Nov 1 2023 Beniamino Galvani - 1.45.6-1 +- Update to 1.45.6 release (development) +- Fix ovs activation with netdev datapath and cloned MAC (RHEL-5886) + +* Wed Oct 18 2023 Íñigo Huguet - 1.45.5-1 +- Update to 1.45.5 release (development) +- Various fixes to Duplicate Address Detection (DAD) (RHEL-1581, RHEL-1411) +- New option to avoid sending the DHCPv4 client-identifier (RHEL-1469) +- Support setting channels in ethtool options (RHEL-1471) + +* Wed Oct 04 2023 Íñigo Huguet - 1.45.4-1 +- Update to 1.45.4 release (development) +- Add 'dns-change' dispatcher event (RHEL-1671) + +* Fri Sep 22 2023 Beniamino Galvani - 1.45.3-1 +- Update to 1.45.3 release (development) +- Improve explanation of the format and routes properties in keyfile man page (RHEL-1407) +- Improve nm-settings-nmcli manpage to show format and valid values of properties (RHEL-2465) +- Honor the autoactivate priority for port connections (RHEL-2202) +- Properly document valid values for ip-tunnel properties (RHEL-1459) + +* Wed Sep 6 2023 Beniamino Galvani - 1.45.2-1 +- update to 1.45.2 release (development) + +* Mon Sep 04 2023 Gris Ge - 1.44.0-4 +- Rebuild for RHEL 9.4 * Wed Aug 30 2023 Fernando Fernandez Mancera - 1:1.44.0-3 - checkpoint: Fix segfault crash when rollback (rhel-1526) From d18e1268bdff5a83b0472ab2811b0ba4bd6fe753 Mon Sep 17 00:00:00 2001 From: MSVSphere Packaging Team Date: Thu, 13 Jun 2024 03:30:39 +0300 Subject: [PATCH 6/6] import NetworkManager-1.46.0-8.el9_4 --- ...-lldp-for-ovs-bridge-ports-rhel31766.patch | 40 ++ ...atform-avoid-routes-resync-rhel36162.patch | 210 ++++++++ ...t-preserve-in-memory-state-rhel32493.patch | 487 ++++++++++++++++++ SPECS/NetworkManager.spec | 17 +- 4 files changed, 753 insertions(+), 1 deletion(-) create mode 100644 SOURCES/1006-fix-lldp-for-ovs-bridge-ports-rhel31766.patch create mode 100644 SOURCES/1007-platform-avoid-routes-resync-rhel36162.patch create mode 100644 SOURCES/1008-checkpoint-preserve-in-memory-state-rhel32493.patch diff --git a/SOURCES/1006-fix-lldp-for-ovs-bridge-ports-rhel31766.patch b/SOURCES/1006-fix-lldp-for-ovs-bridge-ports-rhel31766.patch new file mode 100644 index 0000000..914288c --- /dev/null +++ b/SOURCES/1006-fix-lldp-for-ovs-bridge-ports-rhel31766.patch @@ -0,0 +1,40 @@ +From 6394c2b262d86824a41ca82ad76288c06bfd1989 Mon Sep 17 00:00:00 2001 +From: Fernando Fernandez Mancera +Date: Tue, 26 Mar 2024 12:53:27 +0100 +Subject: [PATCH] libnm-lldp: use ETH_P_ALL instead of NM_ETHERTYPE_LLDP for + the socket + +When creating the socket for listening to LLDP frames we are setting +NM_ETHERTYPE_LLDP (0x88cc) as protocol. In most of the cases, that is +correct but when the interface is attached as a port to a OVS bridge, +kernel is not matching the protocol correctly. The reason might be that +some metadata is added to the packet, but we are not completely sure +about it. + +Instead, we should use ETH_P_ALL to match all the protocols. Later, we +have a eBPF filter to drop the packet by multicast MAC address or +protocol. This is how lldpd is doing it for example. + +https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1903 +(cherry picked from commit 9ac1d6e22bfac7f576dec034a26ac7c9012e5b80) +(cherry picked from commit 2fac176986f3afaa84242e069613cc543bfcc58c) +--- + src/libnm-lldp/nm-lldp-network.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libnm-lldp/nm-lldp-network.c b/src/libnm-lldp/nm-lldp-network.c +index 811c3a7291..28cc745249 100644 +--- a/src/libnm-lldp/nm-lldp-network.c ++++ b/src/libnm-lldp/nm-lldp-network.c +@@ -46,7 +46,7 @@ nm_lldp_network_bind_raw_socket(int ifindex) + + assert(ifindex > 0); + +- fd = socket(AF_PACKET, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, htobe16(NM_ETHERTYPE_LLDP)); ++ fd = socket(AF_PACKET, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, htobe16(ETH_P_ALL)); + if (fd < 0) + return -errno; + +-- +2.44.0 + diff --git a/SOURCES/1007-platform-avoid-routes-resync-rhel36162.patch b/SOURCES/1007-platform-avoid-routes-resync-rhel36162.patch new file mode 100644 index 0000000..91ebcc4 --- /dev/null +++ b/SOURCES/1007-platform-avoid-routes-resync-rhel36162.patch @@ -0,0 +1,210 @@ +From ed5cbbc5847527ed0cfc33f521f7c724975c846b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C3=8D=C3=B1igo=20Huguet?= +Date: Tue, 30 Apr 2024 12:45:04 +0200 +Subject: [PATCH] platform: avoid routes resync for routes that we don't track + +When we recibe a Netlink message with a "route change" event, normally +we just ignore it if it's a route that we don't track (i.e. because of +the route protocol). + +However, it's not that easy if it has the NLM_F_REPLACE flag because +that means that it might be replacing another route. If the kernel has +similar routes which are candidates for the replacement, it's hard for +NM to guess which one of those is being replaced (as the kernel doesn't +have a "route ID" or similar field to indicate it). Moreover, the kernel +might choose to replace a route that we don't have on cache, so we know +nothing about it. + +It is important to note that we cannot just discard Netlink messages of +routes that we don't track if they has the NLM_F_REPLACE. For example, +if we are tracking a route with proto=static, we might receive a replace +message, changing that route to proto=other_proto_that_we_dont_track. We +need to process that message and remove the route from our cache. + +As NM doesn't know what route is being replaced, trying to guess will +lead to errors that will leave the cache in an inconsistent state. +Because of that, it just do a cache resync for the routes. + +For IPv4 there was an optimization to this: if we don't have in the +cache any route candidate for the replacement there are only 2 possible +options: either add the new route to the cache or discard it if we are +not interested on it. We don't need a resync for that. + +This commit is extending that optimization to IPv6 routes. There is no +reason why it shouldn't work in the same way than with IPv4. This +optimization will only work well as long as we find potential candidate +routes in the same way than the kernel (comparing the same fields). NM +calls to this "comparing by WEAK_ID". But this can also happen with IPv4 +routes. + +It is worth it to enable this optimization because there are routing +daemons using custom routing protocols that makes tens or hundreds of +updates per second. If they use NLM_F_REPLACE, this caused NM to do a +resync hundreds of times per second leading to a 100% CPU usage: +https://issues.redhat.com/browse/RHEL-26195 + +An additional but smaller optimization is done in this commit: if we +receive a route message for routes that we don't track AND doesn't have +the NLM_F_REPLACE flag, we can ignore the entire message, thus avoiding +the memory allocation of the nmp_object. That nmp_object was going to be +ignored later, anyway, so better to avoid these allocations that, with +the routing daemon of the above's example, can happen hundreds of times +per second. + +With this changes, the CPU usage doing `ip route replace` 300 times/s +drops from 100% to 1%. Doing `ip route replace` as fast as possible, +without any rate limitting, still keeps NM with a 3% CPU usage in the +system that I have used to test. + +(cherry picked from commit 4d426f581de402e0aebd2ab273ff6649a0a6fee6) +(cherry picked from commit 15ffa8ec6ff7bf43ed1eb123c0d419d6fab8b268) +--- + src/libnm-platform/nm-linux-platform.c | 69 ++++++++++++++++---------- + src/libnm-platform/nmp-object.c | 22 +++++--- + 2 files changed, 57 insertions(+), 34 deletions(-) + +diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c +index 9ecac2d9b3..5b595a9b71 100644 +--- a/src/libnm-platform/nm-linux-platform.c ++++ b/src/libnm-platform/nm-linux-platform.c +@@ -3903,6 +3903,34 @@ _new_from_nl_addr(const struct nlmsghdr *nlh, gboolean id_only) + return g_steal_pointer(&obj); + } + ++static gboolean ++ip_route_is_tracked(guint8 proto, guint8 type) ++{ ++ if (proto > RTPROT_STATIC && !NM_IN_SET(proto, RTPROT_DHCP, RTPROT_RA)) { ++ /* We ignore certain rtm_protocol, because NetworkManager would only ever ++ * configure certain protocols. Other routes are not configured by NetworkManager ++ * and we don't track them in the platform cache. ++ * ++ * This is to help with the performance overhead of a huge number of ++ * routes, for example with the bird BGP software, that adds routes ++ * with RTPROT_BIRD protocol. */ ++ return FALSE; ++ } ++ ++ if (!NM_IN_SET(type, ++ RTN_UNICAST, ++ RTN_LOCAL, ++ RTN_BLACKHOLE, ++ RTN_UNREACHABLE, ++ RTN_PROHIBIT, ++ RTN_THROW)) { ++ /* Certain route types are ignored and not placed into the cache. */ ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ + /* Copied and heavily modified from libnl3's rtnl_route_parse() and parse_multipath(). */ + static NMPObject * + _new_from_nl_route(const struct nlmsghdr *nlh, gboolean id_only, ParseNlmsgIter *parse_nlmsg_iter) +@@ -3963,6 +3991,16 @@ _new_from_nl_route(const struct nlmsghdr *nlh, gboolean id_only, ParseNlmsgIter + * only handle ~supported~ routes. + *****************************************************************/ + ++ /* If it's a route that we don't need to track, abort here to avoid unnecessary ++ * memory allocations to create the nmp_object. However, if the message has the ++ * NLM_F_REPLACE flag, it might be replacing a route that we were tracking so we ++ * have to stop tracking it. That means that we have to process all messages with ++ * NLM_F_REPLACE. See nmp_cache_update_netlink_route(). ++ */ ++ if (!ip_route_is_tracked(rtm->rtm_protocol, rtm->rtm_type) ++ && !(nlh->nlmsg_flags & NLM_F_REPLACE)) ++ return NULL; ++ + addr_family = rtm->rtm_family; + + if (addr_family == AF_INET) +@@ -5519,39 +5557,18 @@ ip_route_get_lock_flag(const NMPlatformIPRoute *route) + static gboolean + ip_route_is_alive(const NMPlatformIPRoute *route) + { +- guint8 prot; ++ guint8 proto, type; + + nm_assert(route); + nm_assert(route->rt_source >= NM_IP_CONFIG_SOURCE_RTPROT_UNSPEC + && route->rt_source <= _NM_IP_CONFIG_SOURCE_RTPROT_LAST); + +- prot = route->rt_source - 1; +- +- nm_assert(nmp_utils_ip_config_source_from_rtprot(prot) == route->rt_source); +- +- if (prot > RTPROT_STATIC && !NM_IN_SET(prot, RTPROT_DHCP, RTPROT_RA)) { +- /* We ignore certain rtm_protocol, because NetworkManager would only ever +- * configure certain protocols. Other routes are not configured by NetworkManager +- * and we don't track them in the platform cache. +- * +- * This is to help with the performance overhead of a huge number of +- * routes, for example with the bird BGP software, that adds routes +- * with RTPROT_BIRD protocol. */ +- return FALSE; +- } ++ proto = route->rt_source - 1; ++ type = nm_platform_route_type_uncoerce(route->type_coerced); + +- if (!NM_IN_SET(nm_platform_route_type_uncoerce(route->type_coerced), +- RTN_UNICAST, +- RTN_LOCAL, +- RTN_BLACKHOLE, +- RTN_UNREACHABLE, +- RTN_PROHIBIT, +- RTN_THROW)) { +- /* Certain route types are ignored and not placed into the cache. */ +- return FALSE; +- } ++ nm_assert(nmp_utils_ip_config_source_from_rtprot(proto) == route->rt_source); + +- return TRUE; ++ return ip_route_is_tracked(proto, type); + } + + /* Copied and modified from libnl3's build_route_msg() and rtnl_route_build_msg(). */ +diff --git a/src/libnm-platform/nmp-object.c b/src/libnm-platform/nmp-object.c +index 4090da71a3..cb4e9764d1 100644 +--- a/src/libnm-platform/nmp-object.c ++++ b/src/libnm-platform/nmp-object.c +@@ -2988,6 +2988,13 @@ nmp_cache_update_netlink_route(NMPCache *cache, + * Since we don't cache all routes (see "route_is_alive"), we cannot know + * with certainty which route was replaced. + * ++ * For example, the kernel might have 3 similar routes (same WEAK_ID), one ++ * of which is not tracked by us so we don't have it into the cache. If we ++ * receive a route replace message, we don't know to what of the 3 routes ++ * it affects (one of the 3 we don't even know that exists). Moreover, if ++ * we only have one route on cache, we don't know if the replace is for a ++ * different one that we don't track. ++ * + * Even if we would cache *all* routes (which we cannot, if kernel adds new + * routing features that modify the known nmp_object_id_equal()), it would + * be hard to find the right route that was replaced. Well, probably we +@@ -3002,15 +3009,14 @@ nmp_cache_update_netlink_route(NMPCache *cache, + * [2] https://bugzilla.redhat.com/show_bug.cgi?id=1337860 + * + * We need to resync. ++ * ++ * However, a resync is expensive. Think of a routing daemon that updates ++ * hundreds of routes per second, the performance penalty is huge. We can ++ * optimize it: if we don't have any matching route on cache (by WEAK_ID), ++ * we don't have anything to replace and we don't need a full resync, but ++ * only to add or discard the new route as usual. + */ +- if (NMP_OBJECT_GET_TYPE(obj_hand_over) == NMP_OBJECT_TYPE_IP4_ROUTE +- && !nmp_cache_lookup_all(cache, NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID, obj_hand_over)) { +- /* For IPv4, we can do a small optimization. We skip the resync, if we have +- * no conflicting routes (by weak-id). +- * +- * This optimization does not work for IPv6 (maybe should be fixed). +- */ +- } else { ++ if (nmp_cache_lookup_all(cache, NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID, obj_hand_over)) { + entry_replace = NULL; + resync_required = TRUE; + goto out; +-- +2.44.0 + diff --git a/SOURCES/1008-checkpoint-preserve-in-memory-state-rhel32493.patch b/SOURCES/1008-checkpoint-preserve-in-memory-state-rhel32493.patch new file mode 100644 index 0000000..e61ee26 --- /dev/null +++ b/SOURCES/1008-checkpoint-preserve-in-memory-state-rhel32493.patch @@ -0,0 +1,487 @@ +From d6837f0bd30da069d327099cb555854630cd4584 Mon Sep 17 00:00:00 2001 +From: Beniamino Galvani +Date: Thu, 2 May 2024 16:40:26 +0200 +Subject: [PATCH 1/2] settings: add + nm_settings_connection_persist_mode_to_string() + +(cherry picked from commit a48b7fe7b9d8adf4902c7b3cfcc4d89bc46cbbef) +(cherry picked from commit e5837aa1d3960b743adcff0a5041445ccd65fb93) +--- + src/core/settings/nm-settings-connection.c | 23 ++++++++++++++++++++++ + src/core/settings/nm-settings-connection.h | 4 ++++ + 2 files changed, 27 insertions(+) + +diff --git a/src/core/settings/nm-settings-connection.c b/src/core/settings/nm-settings-connection.c +index 176cc2c252..459c60ad1e 100644 +--- a/src/core/settings/nm-settings-connection.c ++++ b/src/core/settings/nm-settings-connection.c +@@ -226,6 +226,29 @@ static guint _get_seen_bssids(NMSettingsConnection *self, + + /*****************************************************************************/ + ++char * ++nm_settings_connection_persist_mode_to_string(NMSettingsConnectionPersistMode mode) ++{ ++ switch (mode) { ++ case NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY: ++ return "in-memory"; ++ case NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED: ++ return "in-memory-detached"; ++ case NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY: ++ return "in-memory-only"; ++ case NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP: ++ return "keep"; ++ case NM_SETTINGS_CONNECTION_PERSIST_MODE_NO_PERSIST: ++ return "no-persist"; ++ case NM_SETTINGS_CONNECTION_PERSIST_MODE_TO_DISK: ++ return "to-disk"; ++ } ++ ++ return nm_assert_unreachable_val(NULL); ++} ++ ++/*****************************************************************************/ ++ + NMSettings * + nm_settings_connection_get_settings(NMSettingsConnection *self) + { +diff --git a/src/core/settings/nm-settings-connection.h b/src/core/settings/nm-settings-connection.h +index 835a978e40..d15a75b749 100644 +--- a/src/core/settings/nm-settings-connection.h ++++ b/src/core/settings/nm-settings-connection.h +@@ -379,4 +379,8 @@ void _nm_settings_connection_emit_signal_updated_internal( + + void _nm_settings_connection_cleanup_after_remove(NMSettingsConnection *self); + ++/*****************************************************************************/ ++ ++char *nm_settings_connection_persist_mode_to_string(NMSettingsConnectionPersistMode mode); ++ + #endif /* __NETWORKMANAGER_SETTINGS_CONNECTION_H__ */ +-- +2.41.0 + +From c6f9d0a6d5c864ba0141b6e985727cd69c5560fa Mon Sep 17 00:00:00 2001 +From: Beniamino Galvani +Date: Mon, 15 Apr 2024 10:51:24 +0200 +Subject: [PATCH 2/2] checkpoint: preserve in-memory state of connections + +If a connection is in-memory (i.e. has flag "unsaved"), after a +checkpoint and rollback it can be wrongly persisted to disk: + + - if the connection was modified and written to disk after the + rollback, during the rollback we update it again with persist mode + "keep", which keeps it on disk; + + - if the connection was deleted after the rollback, during the + rollback we add it again with persist mode "to-disk". + +Instead, remember whether the connection had the "unsaved" flag set +and try to restore the previous state. + +However, this is not straightforward as there are 4 different possible +states for the settings connection: persistent; in-memory only; +in-memory shadowing a persistent file; in-memory shadowing a detached +persistent file (i.e. the deletion of the connection doesn't delete +the persistent file). Handle all those cases. + +Fixes: 3e09aed2a09f ('checkpoint: add create, rollback and destroy D-Bus API') +(cherry picked from commit c979bfeb8b0d3bed19bac2ad01a6a6ed899f924e) +(cherry picked from commit ebf25794d9cd89190775ac401c36d63aa1c108f7) +--- + NEWS | 8 ++ + src/core/nm-checkpoint.c | 242 ++++++++++++++++++++++++++++++++------- + 2 files changed, 211 insertions(+), 39 deletions(-) + +diff --git a/NEWS b/NEWS +index 6ac3118db9..e33152c6f4 100644 +--- a/NEWS ++++ b/NEWS +@@ -1,3 +1,11 @@ ++=============================================== ++NetworkManager-1.46.2 ++Overview of changes since NetworkManager-1.46.0 ++=============================================== ++ ++* Properly restore in-memory connection profiles during the rollback ++ of a checkpoint. ++ + ============================================= + NetworkManager-1.46 + Overview of changes since NetworkManager-1.44 +diff --git a/src/core/nm-checkpoint.c b/src/core/nm-checkpoint.c +index cc5c189bf9..ffcf6e3aad 100644 +--- a/src/core/nm-checkpoint.c ++++ b/src/core/nm-checkpoint.c +@@ -10,6 +10,7 @@ + #include "nm-active-connection.h" + #include "nm-act-request.h" + #include "libnm-core-aux-intern/nm-auth-subject.h" ++#include "libnm-core-intern/nm-keyfile-internal.h" + #include "nm-core-utils.h" + #include "nm-dbus-interface.h" + #include "devices/nm-device.h" +@@ -17,6 +18,7 @@ + #include "nm-manager.h" + #include "settings/nm-settings.h" + #include "settings/nm-settings-connection.h" ++#include "settings/plugins/keyfile/nms-keyfile-storage.h" + #include "nm-simple-connection.h" + #include "nm-utils.h" + +@@ -29,11 +31,14 @@ typedef struct { + NMDevice *device; + NMConnection *applied_connection; + NMConnection *settings_connection; ++ NMConnection *settings_connection_shadowed; + guint64 ac_version_id; + NMDeviceState state; + bool is_software : 1; + bool realized : 1; + bool activation_lifetime_bound_to_profile_visibility : 1; ++ bool settings_connection_is_unsaved : 1; ++ bool settings_connection_is_shadowed_owned : 1; + NMUnmanFlagOp unmanaged_explicit; + NMActivationReason activation_reason; + gulong dev_exported_change_id; +@@ -150,37 +155,111 @@ nm_checkpoint_includes_devices_of(NMCheckpoint *self, NMCheckpoint *cp_for_devic + return NULL; + } + ++static NMConnection * ++parse_connection_from_shadowed_file(const char *path, GError **error) ++{ ++ nm_auto_unref_keyfile GKeyFile *keyfile = NULL; ++ gs_free char *base_dir = NULL; ++ char *sep; ++ ++ keyfile = g_key_file_new(); ++ if (!g_key_file_load_from_file(keyfile, path, G_KEY_FILE_NONE, error)) ++ return NULL; ++ ++ sep = strrchr(path, '/'); ++ base_dir = g_strndup(path, sep - path); ++ ++ return nm_keyfile_read(keyfile, base_dir, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, error); ++} ++ + static NMSettingsConnection * +-find_settings_connection(NMCheckpoint *self, +- DeviceCheckpoint *dev_checkpoint, +- gboolean *need_update, +- gboolean *need_activation) ++find_settings_connection(NMCheckpoint *self, ++ DeviceCheckpoint *dev_checkpoint, ++ gboolean *need_update, ++ gboolean *need_update_shadowed, ++ gboolean *need_activation, ++ NMSettingsConnectionPersistMode *persist_mode) + { + NMCheckpointPrivate *priv = NM_CHECKPOINT_GET_PRIVATE(self); + NMActiveConnection *active; + NMSettingsConnection *sett_conn; ++ const char *shadowed_file; ++ NMConnection *shadowed_connection = NULL; + const char *uuid, *ac_uuid; + const CList *tmp_clist; +- +- *need_activation = FALSE; +- *need_update = FALSE; ++ gboolean sett_conn_unsaved; ++ NMSettingsStorage *storage; ++ ++ *need_activation = FALSE; ++ *need_update = FALSE; ++ *need_update_shadowed = FALSE; ++ ++ /* With regard to storage, there are 4 different possible states for the settings ++ * connection: 1) persistent; 2) in-memory only; 3) in-memory shadowing a persistent ++ * file; 4) in-memory shadowing a detached persistent file (i.e. the deletion of ++ * the connection doesn't delete the persistent file). ++ */ ++ if (dev_checkpoint->settings_connection_is_unsaved) { ++ if (dev_checkpoint->settings_connection_shadowed) { ++ if (dev_checkpoint->settings_connection_is_shadowed_owned) ++ *persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY; ++ else ++ *persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_DETACHED; ++ } else ++ *persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY; ++ } else { ++ *persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_TO_DISK; ++ } + + uuid = nm_connection_get_uuid(dev_checkpoint->settings_connection); + sett_conn = nm_settings_get_connection_by_uuid(NM_SETTINGS_GET, uuid); + +- if (!sett_conn) +- return NULL; +- +- /* Now check if the connection changed, ... */ +- if (!nm_connection_compare(dev_checkpoint->settings_connection, +- nm_settings_connection_get_connection(sett_conn), +- NM_SETTING_COMPARE_FLAG_EXACT)) { ++ /* Check if the connection changed */ ++ if (sett_conn ++ && !nm_connection_compare(dev_checkpoint->settings_connection, ++ nm_settings_connection_get_connection(sett_conn), ++ NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP)) { + _LOGT("rollback: settings connection %s changed", uuid); + *need_update = TRUE; + *need_activation = TRUE; + } + +- /* ... is active, ... */ ++ storage = sett_conn ? nm_settings_connection_get_storage(sett_conn) : NULL; ++ shadowed_file = storage ? nm_settings_storage_get_shadowed_storage(storage, NULL) : NULL; ++ shadowed_connection = ++ shadowed_file ? parse_connection_from_shadowed_file(shadowed_file, NULL) : NULL; ++ ++ if (dev_checkpoint->settings_connection_shadowed) { ++ if (!shadowed_connection ++ || !nm_connection_compare(dev_checkpoint->settings_connection_shadowed, ++ shadowed_connection, ++ NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP)) { ++ _LOGT("rollback: shadowed connection changed for %s", uuid); ++ *need_update_shadowed = TRUE; ++ *need_update = TRUE; ++ } ++ } else { ++ if (shadowed_connection) { ++ _LOGT("rollback: shadowed connection changed for %s", uuid); ++ *need_update = TRUE; ++ } ++ } ++ ++ if (!sett_conn) ++ return NULL; ++ ++ /* Check if the connection unsaved flag changed */ ++ sett_conn_unsaved = NM_FLAGS_HAS(nm_settings_connection_get_flags(sett_conn), ++ NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED); ++ if (sett_conn_unsaved != dev_checkpoint->settings_connection_is_unsaved) { ++ _LOGT("rollback: storage changed for settings connection %s: unsaved (%d -> %d)", ++ uuid, ++ dev_checkpoint->settings_connection_is_unsaved, ++ sett_conn_unsaved); ++ *need_update = TRUE; ++ } ++ ++ /* Check if the active state changed */ + nm_manager_for_each_active_connection (priv->manager, active, tmp_clist) { + ac_uuid = + nm_settings_connection_get_uuid(nm_active_connection_get_settings_connection(active)); +@@ -196,7 +275,7 @@ find_settings_connection(NMCheckpoint *self, + return sett_conn; + } + +- /* ... or if the connection was reactivated/reapplied */ ++ /* Check if the connection was reactivated/reapplied */ + if (nm_active_connection_version_id_get(active) != dev_checkpoint->ac_version_id) { + _LOGT("rollback: active connection version id of %s changed", uuid); + *need_activation = TRUE; +@@ -212,12 +291,19 @@ restore_and_activate_connection(NMCheckpoint *self, DeviceCheckpoint *dev_checkp + NMSettingsConnection *connection; + gs_unref_object NMAuthSubject *subject = NULL; + GError *local_error = NULL; +- gboolean need_update, need_activation; ++ gboolean need_update; ++ gboolean need_update_shadowed; ++ gboolean need_activation; + NMSettingsConnectionPersistMode persist_mode; + NMSettingsConnectionIntFlags sett_flags; + NMSettingsConnectionIntFlags sett_mask; + +- connection = find_settings_connection(self, dev_checkpoint, &need_update, &need_activation); ++ connection = find_settings_connection(self, ++ dev_checkpoint, ++ &need_update, ++ &need_update_shadowed, ++ &need_activation, ++ &persist_mode); + + /* FIXME: we need to ensure to re-create/update the profile for the + * same settings plugin. E.g. if it was a keyfile in /run or /etc, +@@ -229,9 +315,26 @@ restore_and_activate_connection(NMCheckpoint *self, DeviceCheckpoint *dev_checkp + sett_mask = NM_SETTINGS_CONNECTION_INT_FLAGS_NONE; + + if (connection) { ++ if (need_update_shadowed) { ++ _LOGD("rollback: updating shadowed file for connection %s", ++ nm_connection_get_uuid(dev_checkpoint->settings_connection)); ++ nm_settings_connection_update( ++ connection, ++ NULL, ++ dev_checkpoint->settings_connection_shadowed, ++ NM_SETTINGS_CONNECTION_PERSIST_MODE_TO_DISK, ++ sett_flags, ++ sett_mask, ++ NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS ++ | NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET, ++ "checkpoint-rollback", ++ NULL); ++ } ++ + if (need_update) { +- _LOGD("rollback: updating connection %s", nm_settings_connection_get_uuid(connection)); +- persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP; ++ _LOGD("rollback: updating connection %s with persist mode \"%s\"", ++ nm_connection_get_uuid(dev_checkpoint->settings_connection), ++ nm_settings_connection_persist_mode_to_string(persist_mode)); + nm_settings_connection_update( + connection, + NULL, +@@ -246,21 +349,54 @@ restore_and_activate_connection(NMCheckpoint *self, DeviceCheckpoint *dev_checkp + } + } else { + /* The connection was deleted, recreate it */ +- _LOGD("rollback: adding connection %s again", +- nm_connection_get_uuid(dev_checkpoint->settings_connection)); +- +- persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_TO_DISK; +- if (!nm_settings_add_connection(NM_SETTINGS_GET, +- NULL, +- dev_checkpoint->settings_connection, +- persist_mode, +- NM_SETTINGS_CONNECTION_ADD_REASON_NONE, +- sett_flags, +- &connection, +- &local_error)) { +- _LOGD("rollback: connection add failure: %s", local_error->message); +- g_clear_error(&local_error); +- return FALSE; ++ if (need_update_shadowed) { ++ _LOGD("rollback: adding back shadowed file for connection %s", ++ nm_connection_get_uuid(dev_checkpoint->settings_connection)); ++ ++ if (!nm_settings_add_connection(NM_SETTINGS_GET, ++ NULL, ++ dev_checkpoint->settings_connection_shadowed, ++ NM_SETTINGS_CONNECTION_PERSIST_MODE_TO_DISK, ++ NM_SETTINGS_CONNECTION_ADD_REASON_NONE, ++ sett_flags, ++ &connection, ++ &local_error)) { ++ _LOGD("rollback: connection add failure: %s", local_error->message); ++ g_clear_error(&local_error); ++ return FALSE; ++ } ++ ++ _LOGD("rollback: updating connection %s with persist mode \"%s\"", ++ nm_connection_get_uuid(dev_checkpoint->settings_connection), ++ nm_settings_connection_persist_mode_to_string(persist_mode)); ++ ++ nm_settings_connection_update( ++ connection, ++ NULL, ++ dev_checkpoint->settings_connection, ++ persist_mode, ++ sett_flags, ++ sett_mask, ++ NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS ++ | NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET, ++ "checkpoint-rollback", ++ NULL); ++ } else { ++ _LOGD("rollback: adding back connection %s with persist mode \"%s\"", ++ nm_connection_get_uuid(dev_checkpoint->settings_connection), ++ nm_settings_connection_persist_mode_to_string(persist_mode)); ++ if (!nm_settings_add_connection(NM_SETTINGS_GET, ++ NULL, ++ dev_checkpoint->settings_connection, ++ persist_mode, ++ NM_SETTINGS_CONNECTION_ADD_REASON_NONE, ++ sett_flags, ++ &connection, ++ &local_error)) { ++ _LOGD("rollback: connection add failure: %s", local_error->message); ++ g_clear_error(&local_error); ++ return FALSE; ++ } + } + need_activation = TRUE; + } +@@ -362,11 +498,15 @@ nm_checkpoint_rollback(NMCheckpoint *self) + while (g_hash_table_iter_next(&iter, (gpointer *) &device, (gpointer *) &dev_checkpoint)) { + guint32 result = NM_ROLLBACK_RESULT_OK; + +- _LOGD("rollback: restoring device %s (state %d, realized %d, explicitly unmanaged %d)", ++ _LOGD("rollback: restoring device %s (state %d, realized %d, explicitly unmanaged %d, " ++ "connection-unsaved %d, connection-shadowed %d, connection-shadowed-owned %d)", + dev_checkpoint->original_dev_name, + (int) dev_checkpoint->state, + dev_checkpoint->realized, +- dev_checkpoint->unmanaged_explicit); ++ dev_checkpoint->unmanaged_explicit, ++ dev_checkpoint->settings_connection_is_unsaved, ++ !!dev_checkpoint->settings_connection_shadowed, ++ dev_checkpoint->settings_connection_is_shadowed_owned); + + if (nm_device_is_real(device)) { + if (!dev_checkpoint->realized) { +@@ -518,6 +658,7 @@ device_checkpoint_destroy(gpointer data) + g_clear_object(&dev_checkpoint->applied_connection); + g_clear_object(&dev_checkpoint->settings_connection); + g_clear_object(&dev_checkpoint->device); ++ g_clear_object(&dev_checkpoint->settings_connection_shadowed); + g_free(dev_checkpoint->original_dev_path); + g_free(dev_checkpoint->original_dev_name); + +@@ -555,7 +696,7 @@ _dev_exported_changed(NMDBusObject *obj, NMCheckpoint *checkpoint) + } + + static DeviceCheckpoint * +-device_checkpoint_create(NMCheckpoint *checkpoint, NMDevice *device) ++device_checkpoint_create(NMCheckpoint *self, NMDevice *device) + { + DeviceCheckpoint *dev_checkpoint; + NMConnection *applied_connection; +@@ -579,7 +720,7 @@ device_checkpoint_create(NMCheckpoint *checkpoint, NMDevice *device) + dev_checkpoint->dev_exported_change_id = g_signal_connect(device, + NM_DBUS_OBJECT_EXPORTED_CHANGED, + G_CALLBACK(_dev_exported_changed), +- checkpoint); ++ self); + + if (nm_device_get_unmanaged_mask(device, NM_UNMANAGED_USER_EXPLICIT)) { + dev_checkpoint->unmanaged_explicit = +@@ -589,6 +730,11 @@ device_checkpoint_create(NMCheckpoint *checkpoint, NMDevice *device) + + act_request = nm_device_get_act_request(device); + if (act_request) { ++ NMSettingsStorage *storage; ++ gboolean shadowed_owned = FALSE; ++ const char *shadowed_file; ++ gs_free_error GError *error = NULL; ++ + settings_connection = nm_act_request_get_settings_connection(act_request); + applied_connection = nm_act_request_get_applied_connection(act_request); + +@@ -602,6 +748,24 @@ device_checkpoint_create(NMCheckpoint *checkpoint, NMDevice *device) + dev_checkpoint->activation_lifetime_bound_to_profile_visibility = + NM_FLAGS_HAS(nm_active_connection_get_state_flags(NM_ACTIVE_CONNECTION(act_request)), + NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY); ++ ++ dev_checkpoint->settings_connection_is_unsaved = ++ NM_FLAGS_HAS(nm_settings_connection_get_flags(settings_connection), ++ NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED); ++ ++ storage = nm_settings_connection_get_storage(settings_connection); ++ shadowed_file = ++ storage ? nm_settings_storage_get_shadowed_storage(storage, &shadowed_owned) : NULL; ++ if (shadowed_file) { ++ dev_checkpoint->settings_connection_is_shadowed_owned = shadowed_owned; ++ dev_checkpoint->settings_connection_shadowed = ++ parse_connection_from_shadowed_file(shadowed_file, &error); ++ if (!dev_checkpoint->settings_connection_shadowed) { ++ _LOGW("error reading shadowed connection file for %s: %s", ++ nm_device_get_iface(device), ++ error->message); ++ } ++ } + } + + return dev_checkpoint; +-- +2.41.0 + diff --git a/SPECS/NetworkManager.spec b/SPECS/NetworkManager.spec index f87bc49..9e7af82 100644 --- a/SPECS/NetworkManager.spec +++ b/SPECS/NetworkManager.spec @@ -7,7 +7,7 @@ %global epoch_version 1 %global real_version 1.46.0 %global rpm_version %{real_version} -%global release_version 4 +%global release_version 8 %global snapshot %{nil} %global git_sha %{nil} %global bcond_default_debug 0 @@ -218,6 +218,9 @@ Patch1002: 1002-allow-rollback-on-internal-global-dns-rhel-29725.patch Patch1003: 1003-do-not-allow-ovs-bridge-and-port-to-be-parent-rhel-28545.patch Patch1004: 1004-nm-dispatcher-fix-crash-rhel28973.patch Patch1005: 1005-fix-race-condition-while-enumerating-devices-rhel25808.patch +Patch1006: 1006-fix-lldp-for-ovs-bridge-ports-rhel31766.patch +Patch1007: 1007-platform-avoid-routes-resync-rhel36162.patch +Patch1008: 1008-checkpoint-preserve-in-memory-state-rhel32493.patch Requires(post): systemd %if 0%{?fedora} || 0%{?rhel} >= 8 @@ -1272,6 +1275,18 @@ fi %changelog +* Thu May 23 2024 Beniamino Galvani - 1:1.46.0-8 +- Preserve in-memory state of connections after checkpoint/rollback (RHEL-32493) + +* Tue May 14 2024 Íñigo Huguet - 1:1.46.0-7 +- Fix CPU usage of 100% when updating routes cache (RHEL-36162) + +* Mon Apr 08 2024 Fernando Fernandez Mancera - 1:1.46.0-6 +- Rebuild because build must go on 0day not 9.4.0 + +* Fri Apr 05 2024 Fernando Fernandez Mancera - 1:1.46.0-5 +- Fix LLDP for OVS Bridge ports (RHEL-31766) + * Tue Mar 26 2024 Beniamino Galvani - 1:1.46.0-4 - Fix nm-dispatcher crash (RHEL-28973) - Fix race condition while enumerating devices (RHEL-25808)