diff --git a/.NetworkManager.metadata b/.NetworkManager.metadata
index 95d4404..30eaae1 100644
--- a/.NetworkManager.metadata
+++ b/.NetworkManager.metadata
@@ -1 +1 @@
-adbe8e9eef649ac73c4fbaefd71a1335d4d016cd SOURCES/NetworkManager-1.36.0.tar.xz
+eba3800b6308c38916f22e8515fb415730a4e89a SOURCES/NetworkManager-1.40.0.tar.xz
diff --git a/.gitignore b/.gitignore
index db48e32..2ac6a43 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-SOURCES/NetworkManager-1.36.0.tar.xz
+SOURCES/NetworkManager-1.40.0.tar.xz
diff --git a/SOURCES/1001-wwan-dns-fix-rh2059138.patch b/SOURCES/1001-wwan-dns-fix-rh2059138.patch
deleted file mode 100644
index fbfcf88..0000000
--- a/SOURCES/1001-wwan-dns-fix-rh2059138.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From 7ba52fdcfeeb1e5400bcecb9fa93b3099dcccb47 Mon Sep 17 00:00:00 2001
-From: Beniamino Galvani <bgalvani@redhat.com>
-Date: Fri, 25 Feb 2022 10:06:48 +0100
-Subject: [PATCH] core: initialize l3cd dns-priority for ppp and wwan
-
-For devices that configure IP by themselves (by returning
-"->ready_for_ip_config() = TRUE" and implementing
-->act_stage3_ip_config()), we skip manual configuration. Currently,
-manual configuration is the only one that sets flag HAS_DNS_PRIORITY
-into the resulting l3cd.
-
-So, the merged l3cd for such devices misses a dns-priority and is
-ignored by the DNS manager.
-
-Explicitly initialize the priority to 0; in this way, the default
-value for the device will be set in the final l3cd during the merge.
-
-Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
-
-https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/931
-(cherry picked from commit b2e559fab2fa5adbf4e159fc1c2cadd3d965b01b)
-(cherry picked from commit bfd3216584e9fe1eb0b6f3f81e3eb75a40877775)
----
- src/core/devices/wwan/nm-modem-broadband.c | 2 ++
- src/core/ppp/nm-ppp-manager.c              | 1 +
- 2 files changed, 3 insertions(+)
-
-diff --git a/src/core/devices/wwan/nm-modem-broadband.c b/src/core/devices/wwan/nm-modem-broadband.c
-index f5336d3750..b585652e5d 100644
---- a/src/core/devices/wwan/nm-modem-broadband.c
-+++ b/src/core/devices/wwan/nm-modem-broadband.c
-@@ -1032,6 +1032,7 @@ stage3_ip_config_start(NMModem *modem, int addr_family, NMModemIPMethod ip_metho
-         l3cd = nm_l3_config_data_new(nm_platform_get_multi_idx(NM_PLATFORM_GET),
-                                      ifindex,
-                                      NM_IP_CONFIG_SOURCE_WWAN);
-+        nm_l3_config_data_set_dns_priority(l3cd, AF_INET, 0);
- 
-         address = (NMPlatformIP4Address){
-             .address      = address_network,
-@@ -1118,6 +1119,7 @@ stage3_ip_config_start(NMModem *modem, int addr_family, NMModemIPMethod ip_metho
-         l3cd = nm_l3_config_data_new(nm_platform_get_multi_idx(NM_PLATFORM_GET),
-                                      ifindex,
-                                      NM_IP_CONFIG_SOURCE_WWAN);
-+        nm_l3_config_data_set_dns_priority(l3cd, AF_INET6, 0);
- 
-         do_auto = TRUE;
- 
-diff --git a/src/core/ppp/nm-ppp-manager.c b/src/core/ppp/nm-ppp-manager.c
-index dd6b1bc7f0..5761d59d39 100644
---- a/src/core/ppp/nm-ppp-manager.c
-+++ b/src/core/ppp/nm-ppp-manager.c
-@@ -545,6 +545,7 @@ impl_ppp_manager_set_ip4_config(NMDBusObject                      *obj,
-                                  NM_IP_CONFIG_SOURCE_PPP);
- 
-     nm_l3_config_data_set_mtu(l3cd, mtu);
-+    nm_l3_config_data_set_dns_priority(l3cd, AF_INET, 0);
- 
-     address = (NMPlatformIP4Address){
-         .plen = 32,
--- 
-2.34.1
-
diff --git a/SOURCES/1002-checkpoint-preserve-external-bridge-ports-rh2035519.patch b/SOURCES/1002-checkpoint-preserve-external-bridge-ports-rh2035519.patch
deleted file mode 100644
index 5d5d9c4..0000000
--- a/SOURCES/1002-checkpoint-preserve-external-bridge-ports-rh2035519.patch
+++ /dev/null
@@ -1,332 +0,0 @@
-From b55842ac0803b59fe8675464191180e44634ce1f Mon Sep 17 00:00:00 2001
-From: Thomas Haller <thaller@redhat.com>
-Date: Tue, 22 Feb 2022 22:08:18 +0100
-Subject: [PATCH 1/2] core: reject unsupported flags for CheckpointCreate D-Bus
- request
-
-(cherry picked from commit df6ee44fb2b96cf05aaeeee500c75d7d91b37404)
-(cherry picked from commit 4cfc2245d382b0b869bd52238eecd17f1c10af1c)
----
- src/core/nm-manager.c | 34 +++++++++++++++++++++++++---------
- 1 file changed, 25 insertions(+), 9 deletions(-)
-
-diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c
-index b440b22457f2..53ef1754bb72 100644
---- a/src/core/nm-manager.c
-+++ b/src/core/nm-manager.c
-@@ -7453,15 +7453,30 @@ impl_manager_checkpoint_create(NMDBusObject                      *obj,
-                                GDBusMethodInvocation             *invocation,
-                                GVariant                          *parameters)
- {
--    NMManager        *self = NM_MANAGER(obj);
--    NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self);
--    NMAuthChain      *chain;
--    char            **devices;
--    guint32           rollback_timeout;
--    guint32           flags;
-+    NMManager         *self = NM_MANAGER(obj);
-+    NMManagerPrivate  *priv = NM_MANAGER_GET_PRIVATE(self);
-+    NMAuthChain       *chain;
-+    gs_strfreev char **devices = NULL;
-+    guint32            rollback_timeout;
-+    guint32            flags;
- 
-     G_STATIC_ASSERT_EXPR(sizeof(flags) <= sizeof(NMCheckpointCreateFlags));
- 
-+    g_variant_get(parameters, "(^aouu)", &devices, &rollback_timeout, &flags);
-+
-+    if ((NMCheckpointCreateFlags) flags != flags
-+        || NM_FLAGS_ANY(flags,
-+                        ~((guint32) (NM_CHECKPOINT_CREATE_FLAG_DESTROY_ALL
-+                                     | NM_CHECKPOINT_CREATE_FLAG_DELETE_NEW_CONNECTIONS
-+                                     | NM_CHECKPOINT_CREATE_FLAG_DISCONNECT_NEW_DEVICES
-+                                     | NM_CHECKPOINT_CREATE_FLAG_ALLOW_OVERLAPPING)))) {
-+        g_dbus_method_invocation_return_error_literal(invocation,
-+                                                      NM_MANAGER_ERROR,
-+                                                      NM_MANAGER_ERROR_INVALID_ARGUMENTS,
-+                                                      "Invalid flags");
-+        return;
-+    }
-+
-     chain = nm_auth_chain_new_context(invocation, checkpoint_auth_done_cb, self);
-     if (!chain) {
-         g_dbus_method_invocation_return_error_literal(invocation,
-@@ -7471,11 +7486,12 @@ impl_manager_checkpoint_create(NMDBusObject                      *obj,
-         return;
-     }
- 
--    g_variant_get(parameters, "(^aouu)", &devices, &rollback_timeout, &flags);
--
-     c_list_link_tail(&priv->auth_lst_head, nm_auth_chain_parent_lst_list(chain));
-     nm_auth_chain_set_data(chain, "audit-op", NM_AUDIT_OP_CHECKPOINT_CREATE, NULL);
--    nm_auth_chain_set_data(chain, "devices", devices, (GDestroyNotify) g_strfreev);
-+    nm_auth_chain_set_data(chain,
-+                           "devices",
-+                           g_steal_pointer(&devices),
-+                           (GDestroyNotify) g_strfreev);
-     nm_auth_chain_set_data(chain, "flags", GUINT_TO_POINTER(flags), NULL);
-     nm_auth_chain_set_data(chain, "timeout", GUINT_TO_POINTER(rollback_timeout), NULL);
-     nm_auth_chain_add_call(chain, NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK, TRUE);
--- 
-2.35.1
-
-
-From 3c417c8338bf44292d4869763587286c7d492c0c Mon Sep 17 00:00:00 2001
-From: Thomas Haller <thaller@redhat.com>
-Date: Tue, 22 Feb 2022 21:55:57 +0100
-Subject: [PATCH 2/2] core: preserve external ports during checkpoint rollback
-
-When we have a bridge interface with ports attached externally (that is,
-not by NetworkManager itself), then it can make sense that during
-checkpoint rollback we want to keep those ports attached.
-
-During rollback, we may need to deactivate the bridge device and
-re-activate it. Implement this, by setting a flag before deactivating,
-which prevents external ports to be detached. The flag gets cleared,
-when the device state changes to activated (the following activation)
-or unmanaged.
-
-This is an ugly solution, for several reasons.
-
-For one, NMDevice tracks its ports in the "slaves" list. But what
-it does is ugly. There is no clear concept to understand what it
-actually tacks. For example, it tracks externally added interfaces
-(nm_device_sys_iface_state_is_external()) that are attached while
-not being connected. But it also tracks interfaces that we want to attach
-during activation (but which are not yet actually enslaved). It also tracks
-slaves that have no actual netdev device (OVS). So it's not clear what this
-list contains and what it should contain at any point in time. When we skip
-the change of the slaves states during nm_device_master_release_slaves_all(),
-it's not really clear what the effects are. It's ugly, but probably correct
-enough. What would be better, if we had a clear purpose of what the
-lists (or several lists) mean. E.g. a list of all ports that are
-currently, physically attached vs. a list of ports we want to attach vs.
-a list of OVS slaves that have no actual netdev device.
-
-Another problem is that we attach state on the device
-("activation_state_preserve_external_ports"), which should linger there
-during the deactivation and reactivation. How can we be sure that we don't
-leave that flag dangling there, and that the desired following activation
-is the one we cared about? If the follow-up activation fails short (e.g. an
-unmanaged command comes first), will we properly disconnect the slaves?
-Should we even? In practice, it might be correct enough.
-
-Also, we only implement this for bridges. I think this is where it makes
-the most sense. And after all, it's an odd thing to preserve unknown,
-external things during a rollback -- unknown, because we have no knowledge
-about why these ports are attached and what to do with them.
-
-Also, the change doesn't remember the ports that were attached when the
-checkpoint was created. Instead, we preserve all ports that are attached
-during rollback. That seems more useful and easier to implement. So we
-don't actually rollback to the configuration when the checkpoint was
-created. Instead, we rollback, but keep external devices.
-
-Also, we do this now by default and introduce a flag to get the previous
-behavior.
-
-https://bugzilla.redhat.com/show_bug.cgi?id=2035519
-https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/ # 909
-(cherry picked from commit 98b3056604fc565f273c264b892086a75a4db0e9)
-(cherry picked from commit 351ca13358f62f85af675672c3399141bec092cd)
----
- src/core/devices/nm-device.c              | 71 ++++++++++++++++++++++-
- src/core/devices/nm-device.h              |  2 +
- src/core/nm-checkpoint.c                  |  5 ++
- src/core/nm-manager.c                     |  3 +-
- src/libnm-core-public/nm-dbus-interface.h | 16 +++--
- 5 files changed, 90 insertions(+), 7 deletions(-)
-
-diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
-index 35360ceebb7b..a11486d54be3 100644
---- a/src/core/devices/nm-device.c
-+++ b/src/core/devices/nm-device.c
-@@ -76,6 +76,7 @@
- #include "nm-hostname-manager.h"
- 
- #include "nm-device-generic.h"
-+#include "nm-device-bridge.h"
- #include "nm-device-vlan.h"
- #include "nm-device-vrf.h"
- #include "nm-device-wireguard.h"
-@@ -483,9 +484,12 @@ typedef struct _NMDevicePrivate {
- 
-     NMUtilsStableType current_stable_id_type : 3;
- 
-+    bool activation_state_preserve_external_ports : 1;
-+
-     bool nm_owned : 1; /* whether the device is a device owned and created by NM */
- 
--    bool  assume_state_guess_assume : 1;
-+    bool assume_state_guess_assume : 1;
-+
-     char *assume_state_connection_uuid;
- 
-     guint64 udi_id;
-@@ -7666,8 +7670,19 @@ nm_device_master_release_slaves(NMDevice *self)
-     c_list_for_each_safe (iter, safe, &priv->slaves) {
-         SlaveInfo *info = c_list_entry(iter, SlaveInfo, lst_slave);
- 
-+        if (priv->activation_state_preserve_external_ports
-+            && nm_device_sys_iface_state_is_external(info->slave)) {
-+            _LOGT(LOGD_DEVICE,
-+                  "master: preserve external port %s",
-+                  nm_device_get_iface(info->slave));
-+            continue;
-+        }
-         nm_device_master_release_one_slave(self, info->slave, TRUE, FALSE, reason);
-     }
-+
-+    /* We only need this flag for a short time. It served its purpose. Clear
-+     * it again. */
-+    nm_device_activation_state_set_preserve_external_ports(self, FALSE);
- }
- 
- /**
-@@ -15386,6 +15401,16 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason,
-     if (state > NM_DEVICE_STATE_DISCONNECTED)
-         nm_device_assume_state_reset(self);
- 
-+    if (state < NM_DEVICE_STATE_UNAVAILABLE
-+        || (state >= NM_DEVICE_STATE_IP_CONFIG && state < NM_DEVICE_STATE_ACTIVATED)) {
-+        /* preserve-external-ports is used by NMCheckpoint to activate a master
-+         * device, and preserve already attached ports. This means, this state is only
-+         * relevant during the deactivation and the following activation of the
-+         * right profile. Once we are sufficiently far in the activation of the
-+         * intended profile, we clear the state again. */
-+        nm_device_activation_state_set_preserve_external_ports(self, FALSE);
-+    }
-+
-     if (state <= NM_DEVICE_STATE_UNAVAILABLE) {
-         if (available_connections_del_all(self))
-             _notify(self, PROP_AVAILABLE_CONNECTIONS);
-@@ -15790,6 +15815,50 @@ nm_device_get_state(NMDevice *self)
-     return NM_DEVICE_GET_PRIVATE(self)->state;
- }
- 
-+/*****************************************************************************/
-+
-+/**
-+ * nm_device_activation_state_set_preserve_external_ports:
-+ * @self: the NMDevice.
-+ * @flag: whether to set or clear the the flag.
-+ *
-+ * This sets an internal flag to true, which does something specific.
-+ * For non-master devices, it has no effect. For master devices, this
-+ * will prevent to detach all external ports, until the next activation
-+ * completes.
-+ *
-+ * This is used during checkpoint/rollback. We may want to preserve
-+ * externally attached ports during the restore. NMCheckpoint will
-+ * call this before doing a re-activation. By setting the flag,
-+ * we basically preserve such ports.
-+ *
-+ * Once we reach again ACTIVATED state, the flag gets cleared. This
-+ * only has effect for the next activation cycle. */
-+void
-+nm_device_activation_state_set_preserve_external_ports(NMDevice *self, gboolean flag)
-+{
-+    NMDevicePrivate *priv;
-+
-+    g_return_if_fail(NM_IS_DEVICE(self));
-+
-+    priv = NM_DEVICE_GET_PRIVATE(self);
-+
-+    if (!NM_IS_DEVICE_BRIDGE(self)) {
-+        /* This is actually only implemented for bridge devices. While it might
-+         * make sense for bond/team or OVS, it's not clear that it is actually
-+         * useful or desirable. */
-+        return;
-+    }
-+
-+    if (priv->activation_state_preserve_external_ports == flag)
-+        return;
-+
-+    priv->activation_state_preserve_external_ports = flag;
-+    _LOGD(LOGD_DEVICE,
-+          "activation-state: preserve-external-ports %s",
-+          flag ? "enabled" : "disabled");
-+}
-+
- /*****************************************************************************/
- /* NMConfigDevice interface related stuff */
- 
-diff --git a/src/core/devices/nm-device.h b/src/core/devices/nm-device.h
-index cfcd4ade6d80..a7badb861087 100644
---- a/src/core/devices/nm-device.h
-+++ b/src/core/devices/nm-device.h
-@@ -444,6 +444,8 @@ NMDeviceType nm_device_get_device_type(NMDevice *dev);
- NMLinkType   nm_device_get_link_type(NMDevice *dev);
- NMMetered    nm_device_get_metered(NMDevice *dev);
- 
-+void nm_device_activation_state_set_preserve_external_ports(NMDevice *self, gboolean flag);
-+
- guint32 nm_device_get_route_table(NMDevice *self, int addr_family);
- guint32 nm_device_get_route_metric(NMDevice *dev, int addr_family);
- 
-diff --git a/src/core/nm-checkpoint.c b/src/core/nm-checkpoint.c
-index 0153af970de7..5b48f91aa515 100644
---- a/src/core/nm-checkpoint.c
-+++ b/src/core/nm-checkpoint.c
-@@ -282,6 +282,11 @@ restore_and_activate_connection(NMCheckpoint *self, DeviceCheckpoint *dev_checkp
-          * an internal subject. */
-         if (nm_device_get_state(dev_checkpoint->device) > NM_DEVICE_STATE_DISCONNECTED
-             && nm_device_get_state(dev_checkpoint->device) < NM_DEVICE_STATE_DEACTIVATING) {
-+            if (!NM_FLAGS_HAS(priv->flags, NM_CHECKPOINT_CREATE_FLAG_NO_PRESERVE_EXTERNAL_PORTS)) {
-+                nm_device_activation_state_set_preserve_external_ports(dev_checkpoint->device,
-+                                                                       TRUE);
-+            }
-+
-             nm_device_state_changed(dev_checkpoint->device,
-                                     NM_DEVICE_STATE_DEACTIVATING,
-                                     NM_DEVICE_STATE_REASON_NEW_ACTIVATION);
-diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c
-index 53ef1754bb72..6c73d237c845 100644
---- a/src/core/nm-manager.c
-+++ b/src/core/nm-manager.c
-@@ -7469,7 +7469,8 @@ impl_manager_checkpoint_create(NMDBusObject                      *obj,
-                         ~((guint32) (NM_CHECKPOINT_CREATE_FLAG_DESTROY_ALL
-                                      | NM_CHECKPOINT_CREATE_FLAG_DELETE_NEW_CONNECTIONS
-                                      | NM_CHECKPOINT_CREATE_FLAG_DISCONNECT_NEW_DEVICES
--                                     | NM_CHECKPOINT_CREATE_FLAG_ALLOW_OVERLAPPING)))) {
-+                                     | NM_CHECKPOINT_CREATE_FLAG_ALLOW_OVERLAPPING
-+                                     | NM_CHECKPOINT_CREATE_FLAG_NO_PRESERVE_EXTERNAL_PORTS)))) {
-         g_dbus_method_invocation_return_error_literal(invocation,
-                                                       NM_MANAGER_ERROR,
-                                                       NM_MANAGER_ERROR_INVALID_ARGUMENTS,
-diff --git a/src/libnm-core-public/nm-dbus-interface.h b/src/libnm-core-public/nm-dbus-interface.h
-index fe2a6c09db58..0d23c7d7a793 100644
---- a/src/libnm-core-public/nm-dbus-interface.h
-+++ b/src/libnm-core-public/nm-dbus-interface.h
-@@ -959,17 +959,23 @@ typedef enum {
-  *   overlapping younger checkpoints. This opts-in that the
-  *   checkpoint can be automatically destroyed by the rollback
-  *   of an older checkpoint. Since: 1.12.
-+ * @NM_CHECKPOINT_CREATE_FLAG_NO_PRESERVE_EXTERNAL_PORTS: during rollback,
-+ *   by default externally added ports attached to bridge devices are preserved.
-+ *   With this flag, the rollback detaches all external ports.
-+ *   This only has an effect for bridge ports. Before 1.38, 1.36.2, this was the default
-+ *   behavior. Since: 1.38, 1.36.2.
-  *
-  * The flags for CheckpointCreate call
-  *
-  * Since: 1.4 (gi flags generated since 1.12)
-  */
- typedef enum { /*< flags >*/
--               NM_CHECKPOINT_CREATE_FLAG_NONE                   = 0,
--               NM_CHECKPOINT_CREATE_FLAG_DESTROY_ALL            = 0x01,
--               NM_CHECKPOINT_CREATE_FLAG_DELETE_NEW_CONNECTIONS = 0x02,
--               NM_CHECKPOINT_CREATE_FLAG_DISCONNECT_NEW_DEVICES = 0x04,
--               NM_CHECKPOINT_CREATE_FLAG_ALLOW_OVERLAPPING      = 0x08,
-+               NM_CHECKPOINT_CREATE_FLAG_NONE                       = 0,
-+               NM_CHECKPOINT_CREATE_FLAG_DESTROY_ALL                = 0x01,
-+               NM_CHECKPOINT_CREATE_FLAG_DELETE_NEW_CONNECTIONS     = 0x02,
-+               NM_CHECKPOINT_CREATE_FLAG_DISCONNECT_NEW_DEVICES     = 0x04,
-+               NM_CHECKPOINT_CREATE_FLAG_ALLOW_OVERLAPPING          = 0x08,
-+               NM_CHECKPOINT_CREATE_FLAG_NO_PRESERVE_EXTERNAL_PORTS = 0x10,
- } NMCheckpointCreateFlags;
- 
- /**
--- 
-2.35.1
-
diff --git a/SOURCES/1003-fix-ovsdb-removal-ports-rhbz1935026.patch b/SOURCES/1003-fix-ovsdb-removal-ports-rhbz1935026.patch
deleted file mode 100644
index 30821d5..0000000
--- a/SOURCES/1003-fix-ovsdb-removal-ports-rhbz1935026.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 482f9671c69800de2077d2dab9352a9b385115d3 Mon Sep 17 00:00:00 2001
-From: Lubomir Rintel <lkundrak@v3.sk>
-Date: Tue, 22 Feb 2022 16:18:40 +0100
-Subject: [PATCH] ovs-port: fix removal of ovsdb entry if the interface goes
- away
-
-Hope third time is the charm.
-
-The idea here is to remove the OVSDB entry if the device actually went away
-violently (like, the it was actually removed from the platform), but keep it if
-we're shutting down.
-
-Fixes-test: @ovs_nmstate
-Fixes: 966413e78f14 ('ovs-port: avoid removing the OVSDB entry if we're shutting down')
-Fixes: ecc73eb239e6 ('ovs-port: always remove the OVSDB entry on slave release')
-
-https://bugzilla.redhat.com/show_bug.cgi?id=2055665
-(cherry picked from commit 65fdfb25006acc3c67059792579dd7a770d04768)
-(cherry picked from commit fee7328c86e5fe8171f8382492f147e7d263891b)
----
- src/core/devices/ovs/nm-device-ovs-port.c | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
-diff --git a/src/core/devices/ovs/nm-device-ovs-port.c b/src/core/devices/ovs/nm-device-ovs-port.c
-index 8406c3648cef..116f58c43ace 100644
---- a/src/core/devices/ovs/nm-device-ovs-port.c
-+++ b/src/core/devices/ovs/nm-device-ovs-port.c
-@@ -188,8 +188,10 @@ del_iface_cb(GError *error, gpointer user_data)
- static void
- release_slave(NMDevice *device, NMDevice *slave, gboolean configure)
- {
--    NMDeviceOvsPort *self = NM_DEVICE_OVS_PORT(device);
--    bool slave_removed = nm_device_sys_iface_state_get(slave) == NM_DEVICE_SYS_IFACE_STATE_REMOVED;
-+    NMDeviceOvsPort *self              = NM_DEVICE_OVS_PORT(device);
-+    bool             slave_not_managed = !NM_IN_SET(nm_device_sys_iface_state_get(slave),
-+                                        NM_DEVICE_SYS_IFACE_STATE_MANAGED,
-+                                        NM_DEVICE_SYS_IFACE_STATE_ASSUME);
- 
-     _LOGI(LOGD_DEVICE, "releasing ovs interface %s", nm_device_get_ip_iface(slave));
- 
-@@ -197,7 +199,7 @@ release_slave(NMDevice *device, NMDevice *slave, gboolean configure)
-      * removed and thus we're called with configure=FALSE), we still need
-      * to make sure its OVSDB entry is gone.
-      */
--    if (configure || slave_removed) {
-+    if (configure || slave_not_managed) {
-         nm_ovsdb_del_interface(nm_ovsdb_get(),
-                                nm_device_get_iface(slave),
-                                del_iface_cb,
--- 
-2.35.1
-
diff --git a/SOURCES/1004-n-dhcp4-discard-NAKs-from-other-servers-rhbz2067122.patch b/SOURCES/1004-n-dhcp4-discard-NAKs-from-other-servers-rhbz2067122.patch
deleted file mode 100644
index cd6d791..0000000
--- a/SOURCES/1004-n-dhcp4-discard-NAKs-from-other-servers-rhbz2067122.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-From 118561e284ff7f28421b19530d4471075b89645c Mon Sep 17 00:00:00 2001
-From: Beniamino Galvani <bgalvani@redhat.com>
-Date: Thu, 10 Mar 2022 12:07:49 +0100
-Subject: [PATCH] n-dhcp4: discard NAKs from other servers in SELECTING
-
-I got a report of a scenario where multiple servers reply to a REQUEST
-in SELECTING, and all servers send NAKs except the one which sent the
-offer, which replies with a ACK. In that scenario, n-dhcp4 is not able
-to obtain a lease because it restarts from INIT as soon as the first
-NAK is received. For comparison, dhclient can get a lease because it
-ignores all NAKs in SELECTING.
-
-Arguably, the network is misconfigured there, but it would be great if
-n-dhcp4 could still work in such scenario.
-
-According to RFC 2131, ACK and NAK messages from server must contain a
-server-id option. The RFC doesn't explicitly say that the client
-should check the option, but I think it's a reasonable thing to do, at
-least for NAKs.
-
-This patch stores the server-id of the REQUEST in SELECTING, and
-compares it with the server-id from NAKs, to discard other servers'
-replies.
-
-https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1144
----
- src/n-dhcp4/src/n-dhcp4-c-connection.c | 19 +++++++++++++++++++
- src/n-dhcp4/src/n-dhcp4-private.h      |  1 +
- 2 files changed, 20 insertions(+)
-
-diff --git a/src/n-dhcp4/src/n-dhcp4-c-connection.c b/src/n-dhcp4/src/n-dhcp4-c-connection.c
-index 4aba97393d..2f660e3b30 100644
---- a/src/n-dhcp4/src/n-dhcp4-c-connection.c
-+++ b/src/n-dhcp4/src/n-dhcp4-c-connection.c
-@@ -705,6 +705,7 @@ int n_dhcp4_c_connection_select_new(NDhcp4CConnection *connection,
-         message->userdata.start_time = offer->userdata.start_time;
-         message->userdata.base_time = offer->userdata.base_time;
-         message->userdata.client_addr = client.s_addr;
-+        message->userdata.server_id = server.s_addr;
-         n_dhcp4_incoming_get_xid(offer, &xid);
-         n_dhcp4_outgoing_set_xid(message, xid);
- 
-@@ -1224,6 +1225,24 @@ int n_dhcp4_c_connection_dispatch_io(NDhcp4CConnection *connection,
-                                       serv_addr, sizeof(serv_addr)));
-         }
- 
-+        if (type == N_DHCP4_MESSAGE_NAK &&
-+            connection->request->userdata.server_id != INADDR_ANY) {
-+                struct in_addr server;
-+
-+                r = n_dhcp4_incoming_query_server_identifier(message, &server);
-+                if (r)
-+                        return N_DHCP4_E_AGAIN;
-+
-+                if (connection->request->userdata.server_id != server.s_addr) {
-+                        n_dhcp4_log(connection->log_queue,
-+                                    LOG_DEBUG,
-+                                    "discarded NAK with wrong server-id %s",
-+                                    inet_ntop(AF_INET, &server,
-+                                              serv_addr, sizeof(serv_addr)));
-+                        return N_DHCP4_E_AGAIN;
-+                }
-+        }
-+
-         switch (type) {
-         case N_DHCP4_MESSAGE_OFFER:
-         case N_DHCP4_MESSAGE_ACK:
-diff --git a/src/n-dhcp4/src/n-dhcp4-private.h b/src/n-dhcp4/src/n-dhcp4-private.h
-index db7b24ff7d..191e946e70 100644
---- a/src/n-dhcp4/src/n-dhcp4-private.h
-+++ b/src/n-dhcp4/src/n-dhcp4-private.h
-@@ -202,6 +202,7 @@ struct NDhcp4Outgoing {
-                 uint8_t type;
-                 uint8_t message_type;
-                 uint32_t client_addr;
-+                uint32_t server_id;
-                 uint64_t start_time;
-                 uint64_t base_time;
-                 uint64_t send_time;
--- 
-2.35.1
-
diff --git a/SOURCES/1005-fix-dhcp-loses-lease-when-restarting-rhbz2094715.patch b/SOURCES/1005-fix-dhcp-loses-lease-when-restarting-rhbz2094715.patch
deleted file mode 100644
index a9a9b10..0000000
--- a/SOURCES/1005-fix-dhcp-loses-lease-when-restarting-rhbz2094715.patch
+++ /dev/null
@@ -1,1994 +0,0 @@
-From dda06a471935a453f5e30d995c0a16b5f977397a Mon Sep 17 00:00:00 2001
-From: Thomas Haller <thaller@redhat.com>
-Date: Mon, 28 Mar 2022 22:26:15 +0200
-Subject: [PATCH 01/11] platform: add nm_platform_ip_address_delete() helper
-
-(cherry picked from commit a60a262574206976eacc405633c059e0f375f0a8)
-(cherry picked from commit 0fc40735ab582f2ff9f319043d77d5f40253f103)
-(cherry picked from commit 264296868b32a93bdbb21246828c52a282a53d50)
----
- src/libnm-platform/nm-platform.h | 23 +++++++++++++++++++++++
- 1 file changed, 23 insertions(+)
-
-diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h
-index 6f5cd5248f..baa3967db0 100644
---- a/src/libnm-platform/nm-platform.h
-+++ b/src/libnm-platform/nm-platform.h
-@@ -2097,6 +2097,29 @@ gboolean nm_platform_ip4_address_delete(NMPlatform *self,
- gboolean
- nm_platform_ip6_address_delete(NMPlatform *self, int ifindex, struct in6_addr address, guint8 plen);
- 
-+static inline gboolean
-+nm_platform_ip_address_delete(NMPlatform                                       *self,
-+                              int                                               addr_family,
-+                              int                                               ifindex,
-+                              gconstpointer /* (const NMPlatformIPAddress *) */ addr)
-+{
-+    if (NM_IS_IPv4(addr_family)) {
-+        const NMPlatformIP4Address *a = addr;
-+
-+        if (ifindex <= 0)
-+            ifindex = a->ifindex;
-+
-+        return nm_platform_ip4_address_delete(self, ifindex, a->address, a->plen, a->peer_address);
-+    } else {
-+        const NMPlatformIP6Address *a = addr;
-+
-+        if (ifindex <= 0)
-+            ifindex = a->ifindex;
-+
-+        return nm_platform_ip6_address_delete(self, ifindex, a->address, a->plen);
-+    }
-+}
-+
- gboolean nm_platform_ip_address_sync(NMPlatform *self,
-                                      int         addr_family,
-                                      int         ifindex,
--- 
-2.35.1
-
-
-From d403f25a67a48221e80971b6b0509b63c6de0a92 Mon Sep 17 00:00:00 2001
-From: Thomas Haller <thaller@redhat.com>
-Date: Mon, 28 Mar 2022 21:13:09 +0200
-Subject: [PATCH 02/11] platform: fix address order in
- nm_platform_ip_address_sync()
-
-In the past, nm_platform_ip_address_sync() only had the @known_addresses
-argument. We would figure out which addresses to delete and which to preserve,
-based on what addresses were known. That means, @known_addresses must have contained
-all the addresses we wanted to preserve, even the external ones. That approach
-was inherently racy.
-
-Instead, nowadays we have the addresses we want to configure (@known_addresses)
-and the addresses we want to delete (@prune_addresses). This started to change in
-commit dadfc3abd510 ('platform: allow injecting the list of addresses to prune'),
-but only commit 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using
-layer 3 configuration') actually changed to pass separate @prune_addresses argument.
-
-However, the order of IP addresses matters and there is no sensible kernel API
-to configure the order (short of adding them in the right order), we still need
-to look at all the addresses, check their order, and possibly delete some.
-That is, we need to handle addresses we want to delete (@prune_addresses)
-but still look at all addresses in platform (@plat_addresses) to check
-their order.
-
-Now, first handle @prune_addresses. That's simple. These are just the
-addresses we want to delete. Second, get the list of all addresses in
-platform (@plat_addresses) and check the order.
-
-Note that if there is an external address that interferes with our
-desired order, we will leave it untouched. Thus, such external addresses
-might prevent us from getting the order as desired. But that's just
-how it is. Don't add addresses outside of NetworkManager to avoid that.
-
-Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration')
-(cherry picked from commit 80f8e23992b58aa0b6fd88de0d3973eea51691a4)
-(cherry picked from commit 4c3197b37790c6c89c7b3df0e92a26e1f8719a5a)
-(cherry picked from commit cd4601802de52f0239b5b8c19bd90ed9ccb6a50c)
----
- src/libnm-platform/nm-platform.c | 207 +++++++++++++++++++------------
- 1 file changed, 126 insertions(+), 81 deletions(-)
-
-diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c
-index 922f412df7..61fcf459ab 100644
---- a/src/libnm-platform/nm-platform.c
-+++ b/src/libnm-platform/nm-platform.c
-@@ -3889,9 +3889,8 @@ ip6_address_scope_cmp(gconstpointer p_a, gconstpointer p_b, gpointer increasing)
-  *   If platform has such an address configured, it will be deleted
-  *   at the beginning of the sync. Note that the array will be modified
-  *   by the function.
-- *   Note that the addresses must be properly sorted, by their priority.
-- *   Create this list with nm_platform_ip_address_get_prune_list() which
-- *   gets the sorting right.
-+ *   Addresses that are both contained in @known_addresses and @addresses_prune
-+ *   will be configured.
-  *
-  * A convenience function to synchronize addresses for a specific interface
-  * with the least possible disturbance. It simply removes addresses that are
-@@ -3906,11 +3905,12 @@ nm_platform_ip_address_sync(NMPlatform *self,
-                             GPtrArray  *known_addresses,
-                             GPtrArray  *addresses_prune)
- {
--    const gint32                   now                 = nm_utils_get_monotonic_timestamp_sec();
--    const int                      IS_IPv4             = NM_IS_IPv4(addr_family);
-+    const gint32                   now     = nm_utils_get_monotonic_timestamp_sec();
-+    const int                      IS_IPv4 = NM_IS_IPv4(addr_family);
-+    NMPLookup                      lookup;
-     gs_unref_hashtable GHashTable *known_addresses_idx = NULL;
--    GPtrArray                     *plat_addresses;
--    GHashTable                    *known_subnets = NULL;
-+    gs_unref_ptrarray GPtrArray   *plat_addresses      = NULL;
-+    GHashTable                    *known_subnets       = NULL;
-     guint                          i_plat;
-     guint                          i_know;
-     guint                          i;
-@@ -3918,6 +3918,9 @@ nm_platform_ip_address_sync(NMPlatform *self,
- 
-     _CHECK_SELF(self, klass, FALSE);
- 
-+    /* @known_addresses (IPv4) are in decreasing priority order (highest priority addresses first).
-+     * @known_addresses (IPv6) are in increasing priority order (highest priority addresses last) (we will sort them by scope next). */
-+
-     /* The order we want to enforce is only among addresses with the same
-      * scope, as the kernel keeps addresses sorted by scope. Therefore,
-      * apply the same sorting to known addresses, so that we don't try to
-@@ -3936,50 +3939,91 @@ nm_platform_ip_address_sync(NMPlatform *self,
-                                    &known_addresses_idx))
-         known_addresses = NULL;
- 
--    /* @plat_addresses must be sorted in decreasing priority order (highest priority addresses first), contrary to
--     * @known_addresses which is in increasing priority order (lowest priority addresses first). */
--    plat_addresses = addresses_prune;
-+    if (nm_g_ptr_array_len(addresses_prune) > 0) {
-+        /* First delete addresses that we should prune (and which are no longer tracked
-+         * as @known_addresses. */
-+        for (i = 0; i < addresses_prune->len; i++) {
-+            const NMPObject *prune_obj = addresses_prune->pdata[i];
-+
-+            nm_assert(NM_IN_SET(NMP_OBJECT_GET_TYPE(prune_obj),
-+                                NMP_OBJECT_TYPE_IP4_ADDRESS,
-+                                NMP_OBJECT_TYPE_IP6_ADDRESS));
-+
-+            if (nm_g_hash_table_contains(known_addresses_idx, prune_obj))
-+                continue;
-+
-+            nm_platform_ip_address_delete(self,
-+                                          addr_family,
-+                                          ifindex,
-+                                          NMP_OBJECT_CAST_IP_ADDRESS(prune_obj));
-+        }
-+    }
-+
-+    /* @plat_addresses for IPv6 must be sorted in decreasing priority order (highest priority addresses first).
-+     * IPv4 are probably unsorted or sorted with lowest priority first, but their order doesn't matter because
-+     * we check the "secondary" flag. */
-+    plat_addresses = nm_platform_lookup_clone(
-+        self,
-+        nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4), ifindex),
-+        NULL,
-+        NULL);
- 
-     if (nm_g_ptr_array_len(plat_addresses) > 0) {
--        /* Delete unknown addresses */
-+        /* Delete addresses that interfere with our intended order. */
-         if (IS_IPv4) {
--            GHashTable *plat_subnets;
-+            gs_free bool *plat_handled_to_free = NULL;
-+            bool         *plat_handled         = NULL;
-+            GHashTable   *plat_subnets;
-+
-+            /* For IPv4, we only consider it a conflict for addresses in the same
-+             * subnet. That's where kernel will assign a primary/secondary flag.
-+             * For different subnets, we don't define the order. */
- 
-             plat_subnets = ip4_addr_subnets_build_index(plat_addresses, TRUE, TRUE);
- 
-             for (i = 0; i < plat_addresses->len; i++) {
--                const NMPObject            *plat_obj;
-+                const NMPObject            *plat_obj = plat_addresses->pdata[i];
-+                const NMPObject            *known_obj;
-                 const NMPlatformIP4Address *plat_address;
-                 const GPtrArray            *addr_list;
-+                gboolean                    secondary;
- 
--                plat_obj = plat_addresses->pdata[i];
--                if (!plat_obj) {
--                    /* Already deleted */
-+                if (plat_handled && plat_handled[i])
-                     continue;
--                }
- 
--                plat_address = NMP_OBJECT_CAST_IP4_ADDRESS(plat_obj);
-+                known_obj = nm_g_hash_table_lookup(known_addresses_idx, plat_obj);
- 
--                if (known_addresses) {
--                    const NMPObject *o;
-+                if (!known_obj) {
-+                    /* this address is added externally. Even if it's presence would mess
-+                     * with our desired order, we cannot delete it. Skip it. */
-+                    if (!plat_handled) {
-+                        plat_handled = nm_malloc0_maybe_a(300,
-+                                                          sizeof(bool) * plat_addresses->len,
-+                                                          &plat_handled_to_free);
-+                    }
-+                    plat_handled[i] = TRUE;
-+                    continue;
-+                }
- 
--                    o = g_hash_table_lookup(known_addresses_idx, plat_obj);
--                    if (o) {
--                        gboolean secondary;
-+                if (!known_subnets)
-+                    known_subnets = ip4_addr_subnets_build_index(known_addresses, FALSE, FALSE);
- 
--                        if (!known_subnets)
--                            known_subnets =
--                                ip4_addr_subnets_build_index(known_addresses, FALSE, FALSE);
-+                plat_address = NMP_OBJECT_CAST_IP4_ADDRESS(plat_obj);
- 
--                        secondary =
--                            ip4_addr_subnets_is_secondary(o, known_subnets, known_addresses, NULL);
--                        if (secondary == NM_FLAGS_HAS(plat_address->n_ifa_flags, IFA_F_SECONDARY)) {
--                            /* if we have an existing known-address, with matching secondary role,
--                             * do not delete the platform-address. */
--                            continue;
--                        }
--                    }
-+                secondary =
-+                    ip4_addr_subnets_is_secondary(known_obj, known_subnets, known_addresses, NULL);
-+                if (secondary == NM_FLAGS_HAS(plat_address->n_ifa_flags, IFA_F_SECONDARY)) {
-+                    /* if we have an existing known-address, with matching secondary role,
-+                     * do not delete the platform-address. */
-+                    continue;
-+                }
-+
-+                if (!plat_handled) {
-+                    plat_handled = nm_malloc0_maybe_a(300,
-+                                                      sizeof(bool) * plat_addresses->len,
-+                                                      &plat_handled_to_free);
-                 }
-+                plat_handled[i] = TRUE;
- 
-                 nm_platform_ip4_address_delete(self,
-                                                ifindex,
-@@ -3999,22 +4043,27 @@ nm_platform_ip_address_sync(NMPlatform *self,
-                      * addresses are deleted, so that we can start with a clean
-                      * slate and add addresses in the right order. */
-                     for (j = 1; j < addr_list->len; j++) {
--                        const NMPObject **o;
-+                        const NMPObject **o = ip4_addr_subnets_addr_list_get(addr_list, j);
-+                        guint             o_idx;
- 
--                        o = ip4_addr_subnets_addr_list_get(addr_list, j);
--                        nm_assert(o);
-+                        o_idx = (o - ((const NMPObject **) &plat_addresses->pdata[0]));
- 
--                        if (*o) {
--                            const NMPlatformIP4Address *a;
-+                        nm_assert(o_idx < plat_addresses->len);
-+                        nm_assert(o == ((const NMPObject **) &plat_addresses->pdata[o_idx]));
- 
--                            a = NMP_OBJECT_CAST_IP4_ADDRESS(*o);
--                            nm_platform_ip4_address_delete(self,
--                                                           ifindex,
--                                                           a->address,
--                                                           a->plen,
--                                                           a->peer_address);
--                            nmp_object_unref(*o);
--                            *o = NULL;
-+                        if (plat_handled[o_idx])
-+                            continue;
-+
-+                        plat_handled[o_idx] = TRUE;
-+
-+                        if (!nm_g_hash_table_contains(known_addresses_idx, *o)) {
-+                            /* Again, this is an external address. We cannot delete
-+                             * it to fix the address order. Pass. */
-+                        } else {
-+                            nm_platform_ip_address_delete(self,
-+                                                          AF_INET,
-+                                                          ifindex,
-+                                                          NMP_OBJECT_CAST_IP4_ADDRESS(*o));
-                         }
-                     }
-                 }
-@@ -4025,48 +4074,44 @@ nm_platform_ip_address_sync(NMPlatform *self,
-             IP6AddrScope cur_scope;
-             gboolean     delete_remaining_addrs;
- 
-+            /* For IPv6, we only compare addresses per-scope. Addresses in different
-+             * scopes don't have a defined order. */
-+
-             g_ptr_array_sort_with_data(plat_addresses,
-                                        ip6_address_scope_cmp,
-                                        GINT_TO_POINTER(FALSE));
- 
-             known_addresses_len = known_addresses ? known_addresses->len : 0;
- 
--            /* First, compare every address whether it is still a "known address", that is, whether
--             * to keep it or to delete it.
--             *
--             * If we don't find a matching valid address in @known_addresses, we will delete
--             * plat_addr.
--             *
--             * Certain addresses, like temporary addresses, are ignored by this function
--             * if not run with full_sync. These addresses are usually not managed by NetworkManager
--             * directly, or at least, they are not managed via nm_platform_ip6_address_sync().
--             * Only in full_sync mode, we really want to get rid of them (usually, when we take
--             * the interface down).
--             *
--             * Note that we mark handled addresses by setting it to %NULL in @plat_addresses array. */
-+            /* First, check that existing addresses have a matching plen as the ones
-+             * we are about to configure (@known_addresses). If not, delete them. */
-             for (i_plat = 0; i_plat < plat_addresses->len; i_plat++) {
--                const NMPObject            *plat_obj = plat_addresses->pdata[i_plat];
--                const NMPObject            *know_obj;
--                const NMPlatformIP6Address *plat_addr = NMP_OBJECT_CAST_IP6_ADDRESS(plat_obj);
--
--                if (known_addresses_idx) {
--                    know_obj = g_hash_table_lookup(known_addresses_idx, plat_obj);
--                    if (know_obj
--                        && plat_addr->plen == NMP_OBJECT_CAST_IP6_ADDRESS(know_obj)->plen) {
--                        /* technically, plen is not part of the ID for IPv6 addresses and thus
--                         * @plat_addr is essentially the same address as @know_addr (regrading
--                         * its identity, not its other attributes).
--                         * However, we cannot modify an existing addresses' plen without
--                         * removing and readding it. Thus, only keep plat_addr, if the plen
--                         * matches.
--                         *
--                         * keep this one, and continue */
--                        continue;
--                    }
-+                const NMPObject *plat_obj = plat_addresses->pdata[i_plat];
-+                const NMPObject *known_obj;
-+
-+                known_obj = nm_g_hash_table_lookup(known_addresses_idx, plat_obj);
-+                if (!known_obj) {
-+                    /* We don't know this address. It was added externally. Keep it configured.
-+                     * We also don't want to delete the address below, so mark it as handled
-+                     * by clearing the pointer. */
-+                    nm_clear_pointer(&plat_addresses->pdata[i_plat], nmp_object_unref);
-+                    continue;
-                 }
- 
--                nm_platform_ip6_address_delete(self, ifindex, plat_addr->address, plat_addr->plen);
--                nmp_object_unref(g_steal_pointer(&plat_addresses->pdata[i_plat]));
-+                if (NMP_OBJECT_CAST_IP6_ADDRESS(plat_obj)->plen
-+                    != NMP_OBJECT_CAST_IP6_ADDRESS(known_obj)->plen) {
-+                    /* technically, plen is not part of the ID for IPv6 addresses and thus
-+                     * @plat_addr is essentially the same address as @know_addr (w.r.t.
-+                     * its identity, not its other attributes).
-+                     * However, we cannot modify an existing addresses' plen without
-+                     * removing and readding it. Thus, we need to delete plat_addr. */
-+                    nm_platform_ip_address_delete(self,
-+                                                  AF_INET6,
-+                                                  ifindex,
-+                                                  NMP_OBJECT_CAST_IP6_ADDRESS(plat_obj));
-+                    /* Mark address as handled. */
-+                    nm_clear_pointer(&plat_addresses->pdata[i_plat], nmp_object_unref);
-+                }
-             }
- 
-             /* Next, we must preserve the priority of the routes. That is, source address
-@@ -4077,7 +4122,7 @@ nm_platform_ip_address_sync(NMPlatform *self,
-              * @known_addresses (which has lowest priority first).
-              *
-              * If we find a first discrepancy, we need to delete all remaining addresses
--             * with same scope from that point on, because below we must re-add all the
-+             * for same scope from that point on, because below we must re-add all the
-              * addresses in the right order to get their priority right. */
-             cur_scope              = IP6_ADDR_SCOPE_LOOPBACK;
-             delete_remaining_addrs = FALSE;
--- 
-2.35.1
-
-
-From e88a5a73f07d1593b1abe1e89a2b252559770d98 Mon Sep 17 00:00:00 2001
-From: Thomas Haller <thaller@redhat.com>
-Date: Tue, 29 Mar 2022 16:44:29 +0200
-Subject: [PATCH 03/11] platform: fix returning error from
- nm_platform_ip_address_sync()
-
-None of the callers really handle the return value of nm_platform_ip_address_sync()
-or whether the function encountered problems. What would they anyway do
-about that?
-
-For IPv4 we were already ignoring errors to add addresses, but for IPv6 we
-aborted. That seems wrong. As the caller does not really handle errors,
-I think we should follow through and add all addresses in case of error.
-
-Still, also collect a overall "success" of the function and return it.
-
-(cherry picked from commit cedaa191d44fede4048a581f2cd132ec6b03d6e9)
-(cherry picked from commit 8736cc86187d176ca7a7f1dbe5bdee0786c2e037)
-(cherry picked from commit ebfbba550343a24b9e7b73051b0515c7fe637881)
----
- src/libnm-platform/nm-platform.c | 25 +++++++++++--------------
- 1 file changed, 11 insertions(+), 14 deletions(-)
-
-diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c
-index 61fcf459ab..97a86d8061 100644
---- a/src/libnm-platform/nm-platform.c
-+++ b/src/libnm-platform/nm-platform.c
-@@ -3877,14 +3877,9 @@ ip6_address_scope_cmp(gconstpointer p_a, gconstpointer p_b, gpointer increasing)
-  * @self: platform instance
-  * @addr_family: the address family AF_INET or AF_INET6.
-  * @ifindex: Interface index
-- * @known_addresses: List of addresses. The list will be modified and only
-- *   addresses that were successfully added will be kept in the list.
-- *   That means, expired addresses and addresses that could not be added
-- *   will be dropped.
-- *   Hence, the input argument @known_addresses is also an output argument
-- *   telling which addresses were successfully added.
-- *   Addresses are removed by unrefing the instance via nmp_object_unref()
-- *   and leaving a NULL tombstone.
-+ * @known_addresses: List of addresses. The list will be modified and
-+ *   expired addresses will be cleared (by calling nmp_object_unref()
-+ *   on the array element).
-  * @addresses_prune: (allow-none): the list of addresses to delete.
-  *   If platform has such an address configured, it will be deleted
-  *   at the beginning of the sync. Note that the array will be modified
-@@ -3911,6 +3906,7 @@ nm_platform_ip_address_sync(NMPlatform *self,
-     gs_unref_hashtable GHashTable *known_addresses_idx = NULL;
-     gs_unref_ptrarray GPtrArray   *plat_addresses      = NULL;
-     GHashTable                    *known_subnets       = NULL;
-+    gboolean                       success;
-     guint                          i_plat;
-     guint                          i_know;
-     guint                          i;
-@@ -4081,7 +4077,7 @@ nm_platform_ip_address_sync(NMPlatform *self,
-                                        ip6_address_scope_cmp,
-                                        GINT_TO_POINTER(FALSE));
- 
--            known_addresses_len = known_addresses ? known_addresses->len : 0;
-+            known_addresses_len = nm_g_ptr_array_len(known_addresses);
- 
-             /* First, check that existing addresses have a matching plen as the ones
-              * we are about to configure (@known_addresses). If not, delete them. */
-@@ -4182,6 +4178,8 @@ next_plat:;
-     if (IS_IPv4)
-         ip4_addr_subnets_destroy_index(known_subnets, known_addresses);
- 
-+    success = TRUE;
-+
-     /* Add missing addresses. New addresses are added by kernel with top
-      * priority.
-      */
-@@ -4217,9 +4215,8 @@ next_plat:;
-                     lifetime,
-                     preferred,
-                     IFA_F_NOPREFIXROUTE,
--                    known_address->a4.label)) {
--                /* ignore error, for unclear reasons. */
--            }
-+                    known_address->a4.label))
-+                success = FALSE;
-         } else {
-             if (!nm_platform_ip6_address_add(self,
-                                              ifindex,
-@@ -4229,11 +4226,11 @@ next_plat:;
-                                              lifetime,
-                                              preferred,
-                                              IFA_F_NOPREFIXROUTE | known_address->a6.n_ifa_flags))
--                return FALSE;
-+                success = FALSE;
-         }
-     }
- 
--    return TRUE;
-+    return success;
- }
- 
- gboolean
--- 
-2.35.1
-
-
-From 87f194fddde0b54407d99748b7f6761e9bf5632a Mon Sep 17 00:00:00 2001
-From: Thomas Haller <thaller@redhat.com>
-Date: Thu, 31 Mar 2022 10:57:25 +0200
-Subject: [PATCH 04/11] platform: fix undefined behavior for pointer comparison
- in ip4_addr_subnets_is_plain_address()
-
-Fixes: 2f68a5004153 ('platform: fix the order of addition of primary and secondary IPv4 addresses')
-(cherry picked from commit 40f22e69c8c03fbbe40f3ba701c3540470f49dfe)
-(cherry picked from commit 41b56cb2b9397407d24e00f95ba4ffb009212040)
-(cherry picked from commit cea335c454fed307903835eb78b2bb715e0ce377)
----
- src/libnm-platform/nm-platform.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c
-index 97a86d8061..a61c8ae823 100644
---- a/src/libnm-platform/nm-platform.c
-+++ b/src/libnm-platform/nm-platform.c
-@@ -3698,8 +3698,8 @@ clear_and_next:
- static gboolean
- ip4_addr_subnets_is_plain_address(const GPtrArray *addresses, gconstpointer needle)
- {
--    return needle >= (gconstpointer) &addresses->pdata[0]
--           && needle < (gconstpointer) &addresses->pdata[addresses->len];
-+    return nm_ptr_to_uintptr(needle) >= nm_ptr_to_uintptr(&addresses->pdata[0])
-+           && nm_ptr_to_uintptr(needle) < nm_ptr_to_uintptr(&addresses->pdata[addresses->len]);
- }
- 
- static const NMPObject **
--- 
-2.35.1
-
-
-From 887239f75b382f46a8d89865de0a09484aaae93b Mon Sep 17 00:00:00 2001
-From: Thomas Haller <thaller@redhat.com>
-Date: Sat, 2 Apr 2022 10:34:17 +0200
-Subject: [PATCH 05/11] platform: move known_subnets variable to inner scope in
- nm_platform_ip_address_sync()
-
-(cherry picked from commit e1431b43a2e02bdd010474df40ccf4417e8b7d08)
-(cherry picked from commit a8e96e3c4b539391833b74432c3200df4e3a8223)
-(cherry picked from commit 0f0d7d801b95198dd5f578dad4e719388cfd9147)
----
- src/libnm-platform/nm-platform.c | 8 +++-----
- 1 file changed, 3 insertions(+), 5 deletions(-)
-
-diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c
-index a61c8ae823..06db58ad00 100644
---- a/src/libnm-platform/nm-platform.c
-+++ b/src/libnm-platform/nm-platform.c
-@@ -3905,7 +3905,6 @@ nm_platform_ip_address_sync(NMPlatform *self,
-     NMPLookup                      lookup;
-     gs_unref_hashtable GHashTable *known_addresses_idx = NULL;
-     gs_unref_ptrarray GPtrArray   *plat_addresses      = NULL;
--    GHashTable                    *known_subnets       = NULL;
-     gboolean                       success;
-     guint                          i_plat;
-     guint                          i_know;
-@@ -3967,9 +3966,10 @@ nm_platform_ip_address_sync(NMPlatform *self,
-     if (nm_g_ptr_array_len(plat_addresses) > 0) {
-         /* Delete addresses that interfere with our intended order. */
-         if (IS_IPv4) {
-+            GHashTable   *known_subnets        = NULL;
-+            GHashTable   *plat_subnets;
-             gs_free bool *plat_handled_to_free = NULL;
-             bool         *plat_handled         = NULL;
--            GHashTable   *plat_subnets;
- 
-             /* For IPv4, we only consider it a conflict for addresses in the same
-              * subnet. That's where kernel will assign a primary/secondary flag.
-@@ -4065,6 +4065,7 @@ nm_platform_ip_address_sync(NMPlatform *self,
-                 }
-             }
-             ip4_addr_subnets_destroy_index(plat_subnets, plat_addresses);
-+            ip4_addr_subnets_destroy_index(known_subnets, known_addresses);
-         } else {
-             guint        known_addresses_len;
-             IP6AddrScope cur_scope;
-@@ -4175,9 +4176,6 @@ next_plat:;
-     if (!known_addresses)
-         return TRUE;
- 
--    if (IS_IPv4)
--        ip4_addr_subnets_destroy_index(known_subnets, known_addresses);
--
-     success = TRUE;
- 
-     /* Add missing addresses. New addresses are added by kernel with top
--- 
-2.35.1
-
-
-From e97eda3965d925c39081830e75cd0397dbc5f03a Mon Sep 17 00:00:00 2001
-From: Thomas Haller <thaller@redhat.com>
-Date: Sat, 2 Apr 2022 10:32:55 +0200
-Subject: [PATCH 06/11] platform: track IPv4 subnets with prefix length in
- nm_platform_ip_address_sync()
-
-The entire point of the dance in nm_platform_ip_address_sync() is to ensure that
-conflicting IPv4 addresses are in their right order, that is, they have
-the right primary/secondary flag.
-
-Kernel only sets secondary flags for addresses that are in the same
-subnet, and we also only care about the relative order of addresses
-that are in the same subnet. In particular, because we rely on kernel's
-"secondary" flag to implement this.
-
-But kernel only treads addresses as secondary, if they share the exact
-same subnet. For example, 192.168.0.5/24 and 192.168.0.6/25 would not
-be treated as primary/secondary but just as unrelated addresses, even if
-the address cleared of it's host part is the same.
-
-This means, we must not only hash the network part of the addresses, but
-also the prefix length. Implement that, by tracking the full NMPObject.
-
-(cherry picked from commit 619dc2fcab809a1cae831c1866ce93189b575d53)
-(cherry picked from commit 0bdb2e97d9a6bcd86889fb09765835a5886d13fb)
-(cherry picked from commit 9149237287a550e44b3e3196dbb6786ccc3ea05c)
----
- src/libnm-platform/nm-platform.c | 62 +++++++++++++++++++++-----------
- 1 file changed, 41 insertions(+), 21 deletions(-)
-
-diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c
-index 06db58ad00..00a3fb2a0a 100644
---- a/src/libnm-platform/nm-platform.c
-+++ b/src/libnm-platform/nm-platform.c
-@@ -3733,6 +3733,30 @@ ip4_addr_subnets_destroy_index(GHashTable *subnets, const GPtrArray *addresses)
-     g_hash_table_unref(subnets);
- }
- 
-+static guint
-+_ip4_addr_subnets_hash(gconstpointer ptr)
-+{
-+    const NMPlatformIP4Address *addr = NMP_OBJECT_CAST_IP4_ADDRESS(ptr);
-+    NMHashState                 h;
-+
-+    nm_hash_init(&h, 3282159733);
-+    nm_hash_update_vals(&h,
-+                        addr->plen,
-+                        nm_utils_ip4_address_clear_host_address(addr->address, addr->plen));
-+    return nm_hash_complete(&h);
-+}
-+
-+static gboolean
-+_ip4_addr_subnets_equal(gconstpointer p_a, gconstpointer p_b)
-+{
-+    const NMPlatformIP4Address *a = NMP_OBJECT_CAST_IP4_ADDRESS(p_a);
-+    const NMPlatformIP4Address *b = NMP_OBJECT_CAST_IP4_ADDRESS(p_b);
-+
-+    return a->plen == b->plen
-+           && (nm_utils_ip4_address_clear_host_address(a->address, a->plen)
-+               == nm_utils_ip4_address_clear_host_address(b->address, b->plen));
-+}
-+
- static GHashTable *
- ip4_addr_subnets_build_index(const GPtrArray *addresses,
-                              gboolean         consider_flags,
-@@ -3743,34 +3767,35 @@ ip4_addr_subnets_build_index(const GPtrArray *addresses,
- 
-     nm_assert(addresses && addresses->len);
- 
--    subnets = g_hash_table_new(nm_direct_hash, NULL);
-+    subnets = g_hash_table_new(_ip4_addr_subnets_hash, _ip4_addr_subnets_equal);
- 
-     /* Build a hash table of all addresses per subnet */
-     for (i = 0; i < addresses->len; i++) {
-+        const NMPObject           **p_obj;
-+        const NMPObject            *obj;
-         const NMPlatformIP4Address *address;
--        gpointer                    p_address;
-         GPtrArray                  *addr_list;
--        guint32                     net;
-         int                         position;
-         gpointer                    p;
- 
-         if (!addresses->pdata[i])
-             continue;
- 
--        p_address = &addresses->pdata[i];
--        address   = NMP_OBJECT_CAST_IP4_ADDRESS(addresses->pdata[i]);
-+        p_obj = (const NMPObject **) &addresses->pdata[i];
-+        obj   = *p_obj;
- 
--        net = address->address & _nm_utils_ip4_prefix_to_netmask(address->plen);
--        if (!g_hash_table_lookup_extended(subnets, GUINT_TO_POINTER(net), NULL, &p)) {
--            g_hash_table_insert(subnets, GUINT_TO_POINTER(net), p_address);
-+        if (!g_hash_table_lookup_extended(subnets, obj, NULL, &p)) {
-+            g_hash_table_insert(subnets, (gpointer) obj, p_obj);
-             continue;
-         }
-         nm_assert(p);
- 
-+        address = NMP_OBJECT_CAST_IP4_ADDRESS(obj);
-+
-         if (full_index) {
-             if (ip4_addr_subnets_is_plain_address(addresses, p)) {
-                 addr_list = g_ptr_array_new();
--                g_hash_table_insert(subnets, GUINT_TO_POINTER(net), addr_list);
-+                g_hash_table_insert(subnets, (gpointer) obj, addr_list);
-                 g_ptr_array_add(addr_list, p);
-             } else
-                 addr_list = p;
-@@ -3779,13 +3804,13 @@ ip4_addr_subnets_build_index(const GPtrArray *addresses,
-                 position = -1; /* append */
-             else
-                 position = 0; /* prepend */
--            g_ptr_array_insert(addr_list, position, p_address);
-+            g_ptr_array_insert(addr_list, position, p_obj);
-         } else {
-             /* we only care about the primary. No need to track the secondaries
-              * as a GPtrArray. */
-             nm_assert(ip4_addr_subnets_is_plain_address(addresses, p));
-             if (consider_flags && !NM_FLAGS_HAS(address->n_ifa_flags, IFA_F_SECONDARY)) {
--                g_hash_table_insert(subnets, GUINT_TO_POINTER(net), p_address);
-+                g_hash_table_insert(subnets, (gpointer) obj, p_obj);
-             }
-         }
-     }
-@@ -3811,16 +3836,11 @@ ip4_addr_subnets_is_secondary(const NMPObject  *address,
-                               const GPtrArray  *addresses,
-                               const GPtrArray **out_addr_list)
- {
--    const NMPlatformIP4Address *a;
--    const GPtrArray            *addr_list;
--    gconstpointer               p;
--    guint32                     net;
--    const NMPObject           **o;
--
--    a = NMP_OBJECT_CAST_IP4_ADDRESS(address);
-+    const GPtrArray  *addr_list;
-+    gconstpointer     p;
-+    const NMPObject **o;
- 
--    net = a->address & _nm_utils_ip4_prefix_to_netmask(a->plen);
--    p   = g_hash_table_lookup(subnets, GUINT_TO_POINTER(net));
-+    p = g_hash_table_lookup(subnets, address);
-     nm_assert(p);
-     if (!ip4_addr_subnets_is_plain_address(addresses, p)) {
-         addr_list = p;
-@@ -3966,7 +3986,7 @@ nm_platform_ip_address_sync(NMPlatform *self,
-     if (nm_g_ptr_array_len(plat_addresses) > 0) {
-         /* Delete addresses that interfere with our intended order. */
-         if (IS_IPv4) {
--            GHashTable   *known_subnets        = NULL;
-+            GHashTable   *known_subnets = NULL;
-             GHashTable   *plat_subnets;
-             gs_free bool *plat_handled_to_free = NULL;
-             bool         *plat_handled         = NULL;
--- 
-2.35.1
-
-
-From d3effaf3f81c763158c726045df750dd5c3c5e2b Mon Sep 17 00:00:00 2001
-From: Thomas Haller <thaller@redhat.com>
-Date: Tue, 29 Mar 2022 22:45:26 +0200
-Subject: [PATCH 07/11] glib-aux: add
- nm_utils_get_monotonic_timestamp_sec_cached() helper
-
-(cherry picked from commit 3f4586532ffb8db2136bbb4ef906fd21d17d5bd2)
-(cherry picked from commit 66237888e78aeae2f348b6b97c39c203a34ab7be)
-(cherry picked from commit 754942038f536fcc79e476ab0ac38dbcf8e80a51)
----
- src/libnm-glib-aux/nm-time-utils.h | 6 ++++++
- 1 file changed, 6 insertions(+)
-
-diff --git a/src/libnm-glib-aux/nm-time-utils.h b/src/libnm-glib-aux/nm-time-utils.h
-index 3c3e935f8d..461d6845fb 100644
---- a/src/libnm-glib-aux/nm-time-utils.h
-+++ b/src/libnm-glib-aux/nm-time-utils.h
-@@ -41,6 +41,12 @@ nm_utils_get_monotonic_timestamp_msec_cached(gint64 *cache_now)
-     return (*cache_now) ?: (*cache_now = nm_utils_get_monotonic_timestamp_msec());
- }
- 
-+static inline gint32
-+nm_utils_get_monotonic_timestamp_sec_cached(gint32 *cache_now)
-+{
-+    return (*cache_now) ?: (*cache_now = nm_utils_get_monotonic_timestamp_sec());
-+}
-+
- gint64 nm_utils_clock_gettime_nsec(clockid_t clockid);
- gint64 nm_utils_clock_gettime_msec(clockid_t clockid);
- 
--- 
-2.35.1
-
-
-From 8ddff3cdccfb547b04a55a6a44221abf4e0525e8 Mon Sep 17 00:00:00 2001
-From: Thomas Haller <thaller@redhat.com>
-Date: Tue, 29 Mar 2022 22:45:56 +0200
-Subject: [PATCH 08/11] platform: make "now" timestamp an in/out parameter to
- nmp_utils_lifetime_get()
-
-nmp_utils_lifetime_get() calculates the lifetime of addresses,
-and it bases the result on a "now" timestamp.
-
-If you have two addresses and calculate their expiry, then we want to
-base it on top of the same "now" timestamp, meaning, we should
-only call nm_utils_get_monotonic_timestamp_sec() once. This is also a
-performance optimization. But much more importantly, when we make a
-comparison at a certain moment, we need that all sides have the same
-understanding of the current timestamp.
-
-But nmp_utils_lifetime_get() does not always require the now timestamp.
-And the caller doesn't know, whether it will need it (short of knowing
-how nmp_utils_lifetime_get() is implemented). So, make the now parameter
-an in/out argument. If we pass in an already valid now timestamp, use
-that. Otherwise, fetch the current time and also return it.
-
-(cherry picked from commit deb37401e95d4ea0025e406424c8da7c10bc9712)
-(cherry picked from commit 9e40474c715e995c000b29db030b4a4990cc6e51)
-(cherry picked from commit 99d77596cdc0a5d3861aebc03485d8cf9c02dd1e)
----
- src/core/ndisc/nm-ndisc.c              |  3 ++-
- src/libnm-platform/nm-platform-utils.c | 12 +++++++-----
- src/libnm-platform/nm-platform-utils.h |  2 +-
- src/libnm-platform/nm-platform.c       | 13 +++++++------
- 4 files changed, 17 insertions(+), 13 deletions(-)
-
-diff --git a/src/core/ndisc/nm-ndisc.c b/src/core/ndisc/nm-ndisc.c
-index 969eacfaba..04b673e51d 100644
---- a/src/core/ndisc/nm-ndisc.c
-+++ b/src/core/ndisc/nm-ndisc.c
-@@ -996,6 +996,7 @@ nm_ndisc_set_config(NMNDisc *ndisc, const NML3ConfigData *l3cd)
-     const NMPObject       *obj;
-     guint                  len;
-     guint                  i;
-+    gint32                 fake_now = NM_NDISC_EXPIRY_BASE_TIMESTAMP / 1000;
- 
-     nm_assert(NM_IS_NDISC(ndisc));
-     nm_assert(nm_ndisc_get_node_type(ndisc) == NM_NDISC_NODE_TYPE_ROUTER);
-@@ -1018,7 +1019,7 @@ nm_ndisc_set_config(NMNDisc *ndisc, const NML3ConfigData *l3cd)
-         lifetime = nmp_utils_lifetime_get(addr->timestamp,
-                                           addr->lifetime,
-                                           addr->preferred,
--                                          NM_NDISC_EXPIRY_BASE_TIMESTAMP / 1000,
-+                                          &fake_now,
-                                           &preferred);
-         if (!lifetime)
-             continue;
-diff --git a/src/libnm-platform/nm-platform-utils.c b/src/libnm-platform/nm-platform-utils.c
-index 9ad030df76..bebc53a851 100644
---- a/src/libnm-platform/nm-platform-utils.c
-+++ b/src/libnm-platform/nm-platform-utils.c
-@@ -2132,12 +2132,15 @@ guint32
- nmp_utils_lifetime_get(guint32  timestamp,
-                        guint32  lifetime,
-                        guint32  preferred,
--                       gint32   now,
-+                       gint32  *cached_now,
-                        guint32 *out_preferred)
- {
--    guint32 t_lifetime, t_preferred;
-+    guint32 t_lifetime;
-+    guint32 t_preferred;
-+    gint32  now;
- 
--    nm_assert(now >= 0);
-+    nm_assert(cached_now);
-+    nm_assert(*cached_now >= 0);
- 
-     if (timestamp == 0 && lifetime == 0) {
-         /* We treat lifetime==0 && timestamp==0 addresses as permanent addresses to allow easy
-@@ -2150,8 +2153,7 @@ nmp_utils_lifetime_get(guint32  timestamp,
-         return NM_PLATFORM_LIFETIME_PERMANENT;
-     }
- 
--    if (now <= 0)
--        now = nm_utils_get_monotonic_timestamp_sec();
-+    now = nm_utils_get_monotonic_timestamp_sec_cached(cached_now);
- 
-     t_lifetime = nmp_utils_lifetime_rebase_relative_time_on_now(timestamp, lifetime, now);
-     if (!t_lifetime) {
-diff --git a/src/libnm-platform/nm-platform-utils.h b/src/libnm-platform/nm-platform-utils.h
-index a9ccebb3e2..9f17da4886 100644
---- a/src/libnm-platform/nm-platform-utils.h
-+++ b/src/libnm-platform/nm-platform-utils.h
-@@ -86,7 +86,7 @@ nmp_utils_lifetime_rebase_relative_time_on_now(guint32 timestamp, guint32 durati
- guint32 nmp_utils_lifetime_get(guint32  timestamp,
-                                guint32  lifetime,
-                                guint32  preferred,
--                               gint32   now,
-+                               gint32  *cached_now,
-                                guint32 *out_preferred);
- 
- int nmp_utils_modprobe(GError **error, gboolean suppress_error_logging, const char *arg1, ...)
-diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c
-index 00a3fb2a0a..ea7aad9398 100644
---- a/src/libnm-platform/nm-platform.c
-+++ b/src/libnm-platform/nm-platform.c
-@@ -3632,7 +3632,7 @@ static gboolean
- _addr_array_clean_expired(int          addr_family,
-                           int          ifindex,
-                           GPtrArray   *array,
--                          guint32      now,
-+                          gint32      *cached_now,
-                           GHashTable **idx)
- {
-     guint    i;
-@@ -3640,7 +3640,8 @@ _addr_array_clean_expired(int          addr_family,
- 
-     nm_assert_addr_family(addr_family);
-     nm_assert(ifindex > 0);
--    nm_assert(now > 0);
-+    nm_assert(cached_now);
-+    nm_assert(*cached_now >= 0);
- 
-     if (!array)
-         return FALSE;
-@@ -3674,7 +3675,7 @@ _addr_array_clean_expired(int          addr_family,
-             goto clear_and_next;
-         }
- 
--        if (!nmp_utils_lifetime_get(a->timestamp, a->lifetime, a->preferred, now, NULL))
-+        if (!nmp_utils_lifetime_get(a->timestamp, a->lifetime, a->preferred, cached_now, NULL))
-             goto clear_and_next;
- 
-         if (idx) {
-@@ -3920,7 +3921,7 @@ nm_platform_ip_address_sync(NMPlatform *self,
-                             GPtrArray  *known_addresses,
-                             GPtrArray  *addresses_prune)
- {
--    const gint32                   now     = nm_utils_get_monotonic_timestamp_sec();
-+    gint32                         now     = 0;
-     const int                      IS_IPv4 = NM_IS_IPv4(addr_family);
-     NMPLookup                      lookup;
-     gs_unref_hashtable GHashTable *known_addresses_idx = NULL;
-@@ -3950,7 +3951,7 @@ nm_platform_ip_address_sync(NMPlatform *self,
-     if (!_addr_array_clean_expired(addr_family,
-                                    ifindex,
-                                    known_addresses,
--                                   now,
-+                                   &now,
-                                    &known_addresses_idx))
-         known_addresses = NULL;
- 
-@@ -4218,7 +4219,7 @@ next_plat:;
-         lifetime = nmp_utils_lifetime_get(known_address->ax.timestamp,
-                                           known_address->ax.lifetime,
-                                           known_address->ax.preferred,
--                                          now,
-+                                          &now,
-                                           &preferred);
-         nm_assert(lifetime > 0);
- 
--- 
-2.35.1
-
-
-From 09a9467c8112ce29d097bc0c5d236e2da2108afe Mon Sep 17 00:00:00 2001
-From: Thomas Haller <thaller@redhat.com>
-Date: Tue, 29 Mar 2022 18:21:49 +0200
-Subject: [PATCH 09/11] platform: make NMPlatformVTableAddress struct smaller
- and pack NMPObjectType
-
-(cherry picked from commit 7c92663f8d79375c78f6917d4c6e005d7accf2a6)
-(cherry picked from commit 3a98ecfa0edce51c5ed8446bc3a74efc6ec6ac65)
-(cherry picked from commit de4d10f1c1f754a1ea954e8bf073d7cdaa269f96)
----
- src/libnm-platform/nm-platform.h | 6 +++---
- src/libnm-platform/nmp-base.h    | 2 +-
- 2 files changed, 4 insertions(+), 4 deletions(-)
-
-diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h
-index baa3967db0..d978c91b80 100644
---- a/src/libnm-platform/nm-platform.h
-+++ b/src/libnm-platform/nm-platform.h
-@@ -776,10 +776,10 @@ typedef struct {
- #undef __NMPlatformObjWithIfindex_COMMON
- 
- typedef struct {
--    gboolean      is_ip4;
-+    bool          is_ip4;
-+    gint8         addr_family;
-+    guint8        sizeof_route;
-     NMPObjectType obj_type;
--    int           addr_family;
--    gsize         sizeof_route;
-     int (*route_cmp)(const NMPlatformIPXRoute *a,
-                      const NMPlatformIPXRoute *b,
-                      NMPlatformIPRouteCmpType  cmp_type);
-diff --git a/src/libnm-platform/nmp-base.h b/src/libnm-platform/nmp-base.h
-index a80fd4d389..4863168855 100644
---- a/src/libnm-platform/nmp-base.h
-+++ b/src/libnm-platform/nmp-base.h
-@@ -110,7 +110,7 @@ typedef struct _NMPlatformIP6Route       NMPlatformIP6Route;
- typedef struct _NMPlatformLink           NMPlatformLink;
- typedef struct _NMPObject                NMPObject;
- 
--typedef enum {
-+typedef enum _nm_packed {
-     NMP_OBJECT_TYPE_UNKNOWN,
-     NMP_OBJECT_TYPE_LINK,
- 
--- 
-2.35.1
-
-
-From efbeb187430ffec0d50cd79d0867013ea289f5fa Mon Sep 17 00:00:00 2001
-From: Thomas Haller <thaller@redhat.com>
-Date: Tue, 29 Mar 2022 18:20:31 +0200
-Subject: [PATCH 10/11] platform: add semantic comparison for IP addresses and
- add "nm_platform_vtable_address"
-
-We already have a comparison of NMPlatformIPXAddress with the modes
-"full" and "id". The former is needed to fully compare two addresses,
-the latter as identity for tracking addresses in the cache.
-
-In NetworkManager we also use the NMPlatformIP[46]Address structure to
-track the addresses we want to configure. When we add them in kernel,
-we will later see them in the platform cache. However, some fields
-will be slightly different. For example, "addr_source" address will
-always be "kernel", because that one is not a field we configure in
-kernel. Also, the "n_ifa_flags" probably differ (getting "permanent"
-and "secondary" flags).
-
-Add a compare function that can ignore such differences.
-
-Also add nm_platform_vtable_address for accessing the IPv4 and IPv6
-methods generically (based on an "IS_IPv4" variable).
-
-(cherry picked from commit ef1b60c061f85b60329d37d62dc81683ff56f4b7)
-(cherry picked from commit ea6625ce97629b287f484e0d5caeb0d08ed44843)
-(cherry picked from commit 8f83aec9d3dd172dd297ba5394e61c85641dd754)
----
- src/libnm-platform/nm-platform.c | 165 +++++++++++++++++++++++++------
- src/libnm-platform/nm-platform.h |  49 ++++++++-
- src/libnm-platform/nmp-object.c  |  82 +++++++--------
- 3 files changed, 224 insertions(+), 72 deletions(-)
-
-diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c
-index ea7aad9398..8459231dc2 100644
---- a/src/libnm-platform/nm-platform.c
-+++ b/src/libnm-platform/nm-platform.c
-@@ -7831,6 +7831,25 @@ _address_pretty_sort_get_prio_6(const struct in6_addr *addr)
-     return 6;
- }
- 
-+static int
-+_address_cmp_expiry(const NMPlatformIPAddress *a, const NMPlatformIPAddress *b)
-+{
-+    guint32 lifetime_a;
-+    guint32 lifetime_b;
-+    guint32 preferred_a;
-+    guint32 preferred_b;
-+    gint32  now = 0;
-+
-+    lifetime_a =
-+        nmp_utils_lifetime_get(a->timestamp, a->lifetime, a->preferred, &now, &preferred_a);
-+    lifetime_b =
-+        nmp_utils_lifetime_get(b->timestamp, b->lifetime, b->preferred, &now, &preferred_b);
-+
-+    NM_CMP_DIRECT(lifetime_a, lifetime_b);
-+    NM_CMP_DIRECT(preferred_a, preferred_b);
-+    return 0;
-+}
-+
- int
- nm_platform_ip6_address_pretty_sort_cmp(const NMPlatformIP6Address *a1,
-                                         const NMPlatformIP6Address *a2,
-@@ -7910,26 +7929,55 @@ nm_platform_ip4_address_hash_update(const NMPlatformIP4Address *obj, NMHashState
- }
- 
- int
--nm_platform_ip4_address_cmp(const NMPlatformIP4Address *a, const NMPlatformIP4Address *b)
-+nm_platform_ip4_address_cmp(const NMPlatformIP4Address *a,
-+                            const NMPlatformIP4Address *b,
-+                            NMPlatformIPAddressCmpType  cmp_type)
- {
-     NM_CMP_SELF(a, b);
-+
-     NM_CMP_FIELD(a, b, ifindex);
--    NM_CMP_FIELD(a, b, address);
-     NM_CMP_FIELD(a, b, plen);
--    NM_CMP_FIELD(a, b, peer_address);
--    NM_CMP_FIELD_UNSAFE(a, b, use_ip4_broadcast_address);
--    if (a->use_ip4_broadcast_address)
--        NM_CMP_FIELD(a, b, broadcast_address);
--    NM_CMP_FIELD(a, b, addr_source);
--    NM_CMP_FIELD(a, b, timestamp);
--    NM_CMP_FIELD(a, b, lifetime);
--    NM_CMP_FIELD(a, b, preferred);
--    NM_CMP_FIELD(a, b, n_ifa_flags);
--    NM_CMP_FIELD_STR(a, b, label);
--    NM_CMP_FIELD_UNSAFE(a, b, a_acd_not_ready);
--    NM_CMP_FIELD_UNSAFE(a, b, a_assume_config_once);
--    NM_CMP_FIELD_UNSAFE(a, b, a_force_commit);
--    return 0;
-+    NM_CMP_FIELD(a, b, address);
-+
-+    switch (cmp_type) {
-+    case NM_PLATFORM_IP_ADDRESS_CMP_TYPE_ID:
-+        /* for IPv4 addresses, you can add the same local address with differing peer-address
-+         * (IFA_ADDRESS), provided that their net-part differs. */
-+        NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX(a->peer_address, b->peer_address, a->plen);
-+        return 0;
-+    case NM_PLATFORM_IP_ADDRESS_CMP_TYPE_SEMANTICALLY:
-+    case NM_PLATFORM_IP_ADDRESS_CMP_TYPE_FULL:
-+        NM_CMP_FIELD(a, b, peer_address);
-+        NM_CMP_FIELD_STR(a, b, label);
-+        if (cmp_type == NM_PLATFORM_IP_ADDRESS_CMP_TYPE_SEMANTICALLY) {
-+            NM_CMP_RETURN(_address_cmp_expiry((const NMPlatformIPAddress *) a,
-+                                              (const NMPlatformIPAddress *) b));
-+
-+            /* Most flags are set by kernel. We only compare the ones that
-+             * NetworkManager actively sets.
-+             *
-+             * NM actively only sets IFA_F_NOPREFIXROUTE (and IFA_F_MANAGETEMPADDR for IPv6),
-+             * where nm_platform_ip_address_sync() always sets IFA_F_NOPREFIXROUTE.
-+             * There are thus no flags to compare for IPv4. */
-+
-+            NM_CMP_DIRECT(nm_platform_ip4_broadcast_address_from_addr(a),
-+                          nm_platform_ip4_broadcast_address_from_addr(b));
-+        } else {
-+            NM_CMP_FIELD(a, b, timestamp);
-+            NM_CMP_FIELD(a, b, lifetime);
-+            NM_CMP_FIELD(a, b, preferred);
-+            NM_CMP_FIELD(a, b, n_ifa_flags);
-+            NM_CMP_FIELD(a, b, addr_source);
-+            NM_CMP_FIELD_UNSAFE(a, b, use_ip4_broadcast_address);
-+            if (a->use_ip4_broadcast_address)
-+                NM_CMP_FIELD(a, b, broadcast_address);
-+            NM_CMP_FIELD_UNSAFE(a, b, a_acd_not_ready);
-+            NM_CMP_FIELD_UNSAFE(a, b, a_assume_config_once);
-+            NM_CMP_FIELD_UNSAFE(a, b, a_force_commit);
-+        }
-+        return 0;
-+    }
-+    return nm_assert_unreachable_val(0);
- }
- 
- void
-@@ -7950,25 +7998,51 @@ nm_platform_ip6_address_hash_update(const NMPlatformIP6Address *obj, NMHashState
- }
- 
- int
--nm_platform_ip6_address_cmp(const NMPlatformIP6Address *a, const NMPlatformIP6Address *b)
-+nm_platform_ip6_address_cmp(const NMPlatformIP6Address *a,
-+                            const NMPlatformIP6Address *b,
-+                            NMPlatformIPAddressCmpType  cmp_type)
- {
-     const struct in6_addr *p_a, *p_b;
- 
-     NM_CMP_SELF(a, b);
-+
-     NM_CMP_FIELD(a, b, ifindex);
--    NM_CMP_FIELD_MEMCMP(a, b, address);
--    NM_CMP_FIELD(a, b, plen);
--    p_a = nm_platform_ip6_address_get_peer(a);
--    p_b = nm_platform_ip6_address_get_peer(b);
--    NM_CMP_DIRECT_MEMCMP(p_a, p_b, sizeof(*p_a));
--    NM_CMP_FIELD(a, b, addr_source);
--    NM_CMP_FIELD(a, b, timestamp);
--    NM_CMP_FIELD(a, b, lifetime);
--    NM_CMP_FIELD(a, b, preferred);
--    NM_CMP_FIELD(a, b, n_ifa_flags);
--    NM_CMP_FIELD_UNSAFE(a, b, a_assume_config_once);
--    NM_CMP_FIELD_UNSAFE(a, b, a_force_commit);
--    return 0;
-+    NM_CMP_FIELD_IN6ADDR(a, b, address);
-+
-+    switch (cmp_type) {
-+    case NM_PLATFORM_IP_ADDRESS_CMP_TYPE_ID:
-+        /* for IPv6 addresses, the prefix length is not part of the primary identifier. */
-+        return 0;
-+    case NM_PLATFORM_IP_ADDRESS_CMP_TYPE_SEMANTICALLY:
-+    case NM_PLATFORM_IP_ADDRESS_CMP_TYPE_FULL:
-+        NM_CMP_FIELD(a, b, plen);
-+        p_a = nm_platform_ip6_address_get_peer(a);
-+        p_b = nm_platform_ip6_address_get_peer(b);
-+        NM_CMP_DIRECT_MEMCMP(p_a, p_b, sizeof(*p_a));
-+        if (cmp_type == NM_PLATFORM_IP_ADDRESS_CMP_TYPE_SEMANTICALLY) {
-+            NM_CMP_RETURN(_address_cmp_expiry((const NMPlatformIPAddress *) a,
-+                                              (const NMPlatformIPAddress *) b));
-+
-+            /* Most flags are set by kernel. We only compare the ones that
-+             * NetworkManager actively sets.
-+             *
-+             * NM actively only sets IFA_F_NOPREFIXROUTE and IFA_F_MANAGETEMPADDR,
-+             * where nm_platform_ip_address_sync() always sets IFA_F_NOPREFIXROUTE.
-+             * We thus only care about IFA_F_MANAGETEMPADDR. */
-+            NM_CMP_DIRECT(a->n_ifa_flags & IFA_F_MANAGETEMPADDR,
-+                          b->n_ifa_flags & IFA_F_MANAGETEMPADDR);
-+        } else {
-+            NM_CMP_FIELD(a, b, timestamp);
-+            NM_CMP_FIELD(a, b, lifetime);
-+            NM_CMP_FIELD(a, b, preferred);
-+            NM_CMP_FIELD(a, b, n_ifa_flags);
-+            NM_CMP_FIELD(a, b, addr_source);
-+            NM_CMP_FIELD_UNSAFE(a, b, a_assume_config_once);
-+            NM_CMP_FIELD_UNSAFE(a, b, a_force_commit);
-+        }
-+        return 0;
-+    }
-+    return nm_assert_unreachable_val(0);
- }
- 
- void
-@@ -8924,6 +8998,37 @@ nm_platform_netns_push(NMPlatform *self, NMPNetns **netns)
- 
- /*****************************************************************************/
- 
-+const _NMPlatformVTableAddressUnion nm_platform_vtable_address = {
-+    .v4 =
-+        {
-+            .is_ip4         = TRUE,
-+            .obj_type       = NMP_OBJECT_TYPE_IP4_ADDRESS,
-+            .addr_family    = AF_INET,
-+            .sizeof_address = sizeof(NMPlatformIP4Address),
-+            .address_cmp =
-+                (int (*)(const NMPlatformIPXAddress *a,
-+                         const NMPlatformIPXAddress *b,
-+                         NMPlatformIPAddressCmpType  cmp_type)) nm_platform_ip4_address_cmp,
-+            .address_to_string = (const char *(*) (const NMPlatformIPXAddress *address,
-+                                                   char                       *buf,
-+                                                   gsize len)) nm_platform_ip4_address_to_string,
-+        },
-+    .v6 =
-+        {
-+            .is_ip4         = FALSE,
-+            .obj_type       = NMP_OBJECT_TYPE_IP6_ADDRESS,
-+            .addr_family    = AF_INET6,
-+            .sizeof_address = sizeof(NMPlatformIP6Address),
-+            .address_cmp =
-+                (int (*)(const NMPlatformIPXAddress *a,
-+                         const NMPlatformIPXAddress *b,
-+                         NMPlatformIPAddressCmpType  cmp_type)) nm_platform_ip6_address_cmp,
-+            .address_to_string = (const char *(*) (const NMPlatformIPXAddress *address,
-+                                                   char                       *buf,
-+                                                   gsize len)) nm_platform_ip6_address_to_string,
-+        },
-+};
-+
- const _NMPlatformVTableRouteUnion nm_platform_vtable_route = {
-     .v4 =
-         {
-diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h
-index d978c91b80..203f8c7bbd 100644
---- a/src/libnm-platform/nm-platform.h
-+++ b/src/libnm-platform/nm-platform.h
-@@ -94,6 +94,14 @@ typedef enum {
-     NMP_NLM_FLAG_TEST    = NMP_NLM_FLAG_F_EXCL,
- } NMPNlmFlags;
- 
-+typedef enum {
-+    NM_PLATFORM_IP_ADDRESS_CMP_TYPE_ID,
-+
-+    NM_PLATFORM_IP_ADDRESS_CMP_TYPE_SEMANTICALLY,
-+
-+    NM_PLATFORM_IP_ADDRESS_CMP_TYPE_FULL,
-+} NMPlatformIPAddressCmpType;
-+
- typedef enum {
-     /* compare fields which kernel considers as similar routes.
-      * It is a looser comparisong then NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID
-@@ -775,6 +783,27 @@ typedef struct {
- 
- #undef __NMPlatformObjWithIfindex_COMMON
- 
-+typedef struct {
-+    bool          is_ip4;
-+    NMPObjectType obj_type;
-+    gint8         addr_family;
-+    guint8        sizeof_address;
-+    int (*address_cmp)(const NMPlatformIPXAddress *a,
-+                       const NMPlatformIPXAddress *b,
-+                       NMPlatformIPAddressCmpType  cmp_type);
-+    const char *(*address_to_string)(const NMPlatformIPXAddress *address, char *buf, gsize len);
-+} NMPlatformVTableAddress;
-+
-+typedef union {
-+    struct {
-+        NMPlatformVTableAddress v6;
-+        NMPlatformVTableAddress v4;
-+    };
-+    NMPlatformVTableAddress vx[2];
-+} _NMPlatformVTableAddressUnion;
-+
-+extern const _NMPlatformVTableAddressUnion nm_platform_vtable_address;
-+
- typedef struct {
-     bool          is_ip4;
-     gint8         addr_family;
-@@ -2311,8 +2340,24 @@ int nm_platform_lnk_vlan_cmp(const NMPlatformLnkVlan *a, const NMPlatformLnkVlan
- int nm_platform_lnk_vrf_cmp(const NMPlatformLnkVrf *a, const NMPlatformLnkVrf *b);
- int nm_platform_lnk_vxlan_cmp(const NMPlatformLnkVxlan *a, const NMPlatformLnkVxlan *b);
- int nm_platform_lnk_wireguard_cmp(const NMPlatformLnkWireGuard *a, const NMPlatformLnkWireGuard *b);
--int nm_platform_ip4_address_cmp(const NMPlatformIP4Address *a, const NMPlatformIP4Address *b);
--int nm_platform_ip6_address_cmp(const NMPlatformIP6Address *a, const NMPlatformIP6Address *b);
-+int nm_platform_ip4_address_cmp(const NMPlatformIP4Address *a,
-+                                const NMPlatformIP4Address *b,
-+                                NMPlatformIPAddressCmpType  cmp_type);
-+int nm_platform_ip6_address_cmp(const NMPlatformIP6Address *a,
-+                                const NMPlatformIP6Address *b,
-+                                NMPlatformIPAddressCmpType  cmp_type);
-+
-+static inline int
-+nm_platform_ip4_address_cmp_full(const NMPlatformIP4Address *a, const NMPlatformIP4Address *b)
-+{
-+    return nm_platform_ip4_address_cmp(a, b, NM_PLATFORM_IP_ADDRESS_CMP_TYPE_FULL);
-+}
-+
-+static inline int
-+nm_platform_ip6_address_cmp_full(const NMPlatformIP6Address *a, const NMPlatformIP6Address *b)
-+{
-+    return nm_platform_ip6_address_cmp(a, b, NM_PLATFORM_IP_ADDRESS_CMP_TYPE_FULL);
-+}
- 
- int nm_platform_ip4_address_pretty_sort_cmp(const NMPlatformIP4Address *a1,
-                                             const NMPlatformIP4Address *a2);
-diff --git a/src/libnm-platform/nmp-object.c b/src/libnm-platform/nmp-object.c
-index d518e6e589..0102e943ff 100644
---- a/src/libnm-platform/nmp-object.c
-+++ b/src/libnm-platform/nmp-object.c
-@@ -1523,20 +1523,21 @@ nmp_object_id_cmp(const NMPObject *obj1, const NMPObject *obj2)
- 
- _vt_cmd_plobj_id_cmp(link, NMPlatformLink, { NM_CMP_FIELD(obj1, obj2, ifindex); });
- 
--_vt_cmd_plobj_id_cmp(ip4_address, NMPlatformIP4Address, {
--    NM_CMP_FIELD(obj1, obj2, ifindex);
--    NM_CMP_FIELD(obj1, obj2, plen);
--    NM_CMP_FIELD(obj1, obj2, address);
--    /* for IPv4 addresses, you can add the same local address with differing peer-address
--     * (IFA_ADDRESS), provided that their net-part differs. */
--    NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX(obj1->peer_address, obj2->peer_address, obj1->plen);
--});
-+static int
-+_vt_cmd_plobj_id_cmp_ip4_address(const NMPlatformObject *obj1, const NMPlatformObject *obj2)
-+{
-+    return nm_platform_ip4_address_cmp((const NMPlatformIP4Address *) obj1,
-+                                       (const NMPlatformIP4Address *) obj2,
-+                                       NM_PLATFORM_IP_ADDRESS_CMP_TYPE_ID);
-+}
- 
--_vt_cmd_plobj_id_cmp(ip6_address, NMPlatformIP6Address, {
--    NM_CMP_FIELD(obj1, obj2, ifindex);
--    /* for IPv6 addresses, the prefix length is not part of the primary identifier. */
--    NM_CMP_FIELD_IN6ADDR(obj1, obj2, address);
--});
-+static int
-+_vt_cmd_plobj_id_cmp_ip6_address(const NMPlatformObject *obj1, const NMPlatformObject *obj2)
-+{
-+    return nm_platform_ip6_address_cmp((const NMPlatformIP6Address *) obj1,
-+                                       (const NMPlatformIP6Address *) obj2,
-+                                       NM_PLATFORM_IP_ADDRESS_CMP_TYPE_ID);
-+}
- 
- _vt_cmd_plobj_id_cmp(qdisc, NMPlatformQdisc, {
-     NM_CMP_FIELD(obj1, obj2, ifindex);
-@@ -1551,24 +1552,24 @@ _vt_cmd_plobj_id_cmp(tfilter, NMPlatformTfilter, {
- static int
- _vt_cmd_plobj_id_cmp_ip4_route(const NMPlatformObject *obj1, const NMPlatformObject *obj2)
- {
--    return nm_platform_ip4_route_cmp((NMPlatformIP4Route *) obj1,
--                                     (NMPlatformIP4Route *) obj2,
-+    return nm_platform_ip4_route_cmp((const NMPlatformIP4Route *) obj1,
-+                                     (const NMPlatformIP4Route *) obj2,
-                                      NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID);
- }
- 
- static int
- _vt_cmd_plobj_id_cmp_ip6_route(const NMPlatformObject *obj1, const NMPlatformObject *obj2)
- {
--    return nm_platform_ip6_route_cmp((NMPlatformIP6Route *) obj1,
--                                     (NMPlatformIP6Route *) obj2,
-+    return nm_platform_ip6_route_cmp((const NMPlatformIP6Route *) obj1,
-+                                     (const NMPlatformIP6Route *) obj2,
-                                      NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID);
- }
- 
- static int
- _vt_cmd_plobj_id_cmp_routing_rule(const NMPlatformObject *obj1, const NMPlatformObject *obj2)
- {
--    return nm_platform_routing_rule_cmp((NMPlatformRoutingRule *) obj1,
--                                        (NMPlatformRoutingRule *) obj2,
-+    return nm_platform_routing_rule_cmp((const NMPlatformRoutingRule *) obj1,
-+                                        (const NMPlatformRoutingRule *) obj2,
-                                         NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID);
- }
- 
-@@ -3158,28 +3159,29 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
-             .cmd_plobj_to_string_id   = _vt_cmd_plobj_to_string_id_ip4_address,
-             .cmd_plobj_to_string      = (CmdPlobjToStringFunc) nm_platform_ip4_address_to_string,
-             .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_ip4_address_hash_update,
--            .cmd_plobj_cmp         = (CmdPlobjCmpFunc) nm_platform_ip4_address_cmp,
-+            .cmd_plobj_cmp         = (CmdPlobjCmpFunc) nm_platform_ip4_address_cmp_full,
-+        },
-+    [NMP_OBJECT_TYPE_IP6_ADDRESS - 1] =
-+        {
-+            .parent                   = DEDUP_MULTI_OBJ_CLASS_INIT(),
-+            .obj_type                 = NMP_OBJECT_TYPE_IP6_ADDRESS,
-+            .sizeof_data              = sizeof(NMPObjectIP6Address),
-+            .sizeof_public            = sizeof(NMPlatformIP6Address),
-+            .obj_type_name            = "ip6-address",
-+            .addr_family              = AF_INET6,
-+            .rtm_gettype              = RTM_GETADDR,
-+            .signal_type_id           = NM_PLATFORM_SIGNAL_ID_IP6_ADDRESS,
-+            .signal_type              = NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED,
-+            .supported_cache_ids      = _supported_cache_ids_ipx_address,
-+            .cmd_obj_is_alive         = _vt_cmd_obj_is_alive_ipx_address,
-+            .cmd_plobj_id_copy        = _vt_cmd_plobj_id_copy_ip6_address,
-+            .cmd_plobj_id_cmp         = _vt_cmd_plobj_id_cmp_ip6_address,
-+            .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_ip6_address,
-+            .cmd_plobj_to_string_id   = _vt_cmd_plobj_to_string_id_ip6_address,
-+            .cmd_plobj_to_string      = (CmdPlobjToStringFunc) nm_platform_ip6_address_to_string,
-+            .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_ip6_address_hash_update,
-+            .cmd_plobj_cmp         = (CmdPlobjCmpFunc) nm_platform_ip6_address_cmp_full,
-         },
--    [NMP_OBJECT_TYPE_IP6_ADDRESS
--        - 1] = {.parent                   = DEDUP_MULTI_OBJ_CLASS_INIT(),
--                .obj_type                 = NMP_OBJECT_TYPE_IP6_ADDRESS,
--                .sizeof_data              = sizeof(NMPObjectIP6Address),
--                .sizeof_public            = sizeof(NMPlatformIP6Address),
--                .obj_type_name            = "ip6-address",
--                .addr_family              = AF_INET6,
--                .rtm_gettype              = RTM_GETADDR,
--                .signal_type_id           = NM_PLATFORM_SIGNAL_ID_IP6_ADDRESS,
--                .signal_type              = NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED,
--                .supported_cache_ids      = _supported_cache_ids_ipx_address,
--                .cmd_obj_is_alive         = _vt_cmd_obj_is_alive_ipx_address,
--                .cmd_plobj_id_copy        = _vt_cmd_plobj_id_copy_ip6_address,
--                .cmd_plobj_id_cmp         = _vt_cmd_plobj_id_cmp_ip6_address,
--                .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_ip6_address,
--                .cmd_plobj_to_string_id   = _vt_cmd_plobj_to_string_id_ip6_address,
--                .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_ip6_address_to_string,
--                .cmd_plobj_hash_update =
--                    (CmdPlobjHashUpdateFunc) nm_platform_ip6_address_hash_update,
--                .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_ip6_address_cmp},
-     [NMP_OBJECT_TYPE_IP4_ROUTE - 1] =
-         {
-             .parent                   = DEDUP_MULTI_OBJ_CLASS_INIT(),
--- 
-2.35.1
-
-
-From b9cb6401cc5efb4092e8a92af6ed509a986fe495 Mon Sep 17 00:00:00 2001
-From: Fernando Fernandez Mancera <ffmancera@riseup.net>
-Date: Tue, 19 Apr 2022 18:39:37 +0200
-Subject: [PATCH 11/11] l3cfg: drop NM_L3_CFG_COMMIT_TYPE_ASSUME and
- assume_config_once
-
-ASSUME is causing more troubles than benefits it provides. This patch is
-dropping NM_L3_CFG_COMMIT_TYPE_ASSUME and assume_config_once. NM3LCfg
-will commit as if the sys-iface-state is MANAGED.
-
-This patch is part of the effort to remove ASSUME from NetworkManager.
-After ASSUME is dropped when starting NetworkManager it will take full
-control of the interface, re-configuring it. The interface will be
-managed from the start instead of assumed and then managed.
-
-This will solve the situations where an interface is half-up and then a
-restart happens. When NetworkManager is back it won't add the missing
-addresses (which is what assume does) so the interface will fail during
-the activation and will require a full activation.
-
-https://bugzilla.redhat.com/show_bug.cgi?id=2050216
-https://bugzilla.redhat.com/show_bug.cgi?id=2077605
-https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1196
-(cherry picked from commit bf5927b978fccec1390bcc7d3d5719d7fe7c3450)
-(cherry picked from commit a494c00901a56afe422c4944875de0340d305e8a)
-(cherry picked from commit 05c3f384b641624edc1a951899bcb0f770972e28)
----
- src/core/devices/nm-device.c     |  4 ++-
- src/core/nm-l3-config-data.c     | 36 +++----------------------
- src/core/nm-l3-config-data.h     |  1 -
- src/core/nm-l3-ipv4ll.c          |  2 +-
- src/core/nm-l3-ipv6ll.c          |  9 +++----
- src/core/nm-l3cfg.c              | 32 +++-------------------
- src/core/nm-l3cfg.h              |  9 -------
- src/core/tests/test-l3cfg.c      | 12 ++++-----
- src/libnm-platform/nm-platform.c | 46 ++++++++++----------------------
- src/libnm-platform/nm-platform.h |  5 ----
- src/libnm-platform/nmp-object.h  | 15 -----------
- 11 files changed, 34 insertions(+), 137 deletions(-)
-
-diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
-index a11486d54b..264d75d936 100644
---- a/src/core/devices/nm-device.c
-+++ b/src/core/devices/nm-device.c
-@@ -3976,7 +3976,9 @@ _dev_l3_cfg_commit_type_reset(NMDevice *self)
-         commit_type = NM_L3_CFG_COMMIT_TYPE_NONE;
-         goto do_set;
-     case NM_DEVICE_SYS_IFACE_STATE_ASSUME:
--        commit_type = NM_L3_CFG_COMMIT_TYPE_ASSUME;
-+        /* TODO: NM_DEVICE_SYS_IFACE_STATE_ASSUME, will be dropped from the code.
-+         * Meanwhile, the commit type must be updated. */
-+        commit_type = NM_L3_CFG_COMMIT_TYPE_UPDATE;
-         goto do_set;
-     case NM_DEVICE_SYS_IFACE_STATE_MANAGED:
-         commit_type = NM_L3_CFG_COMMIT_TYPE_UPDATE;
-diff --git a/src/core/nm-l3-config-data.c b/src/core/nm-l3-config-data.c
-index 03593ea28c..1cabdb6c9b 100644
---- a/src/core/nm-l3-config-data.c
-+++ b/src/core/nm-l3-config-data.c
-@@ -1172,13 +1172,6 @@ _l3_config_data_add_obj(NMDedupMultiIndex      *multi_idx,
-                     modified                                 = TRUE;
-                 }
- 
--                /* OR assume_config_once flag */
--                if (obj_new->ip_address.a_assume_config_once
--                    && !obj_old->ip_address.a_assume_config_once) {
--                    obj_new = nmp_object_stackinit_obj(&obj_new_stackinit, obj_new);
--                    obj_new_stackinit.ip_address.a_assume_config_once = TRUE;
--                    modified                                          = TRUE;
--                }
-                 break;
-             case NMP_OBJECT_TYPE_IP4_ROUTE:
-             case NMP_OBJECT_TYPE_IP6_ROUTE:
-@@ -1189,13 +1182,6 @@ _l3_config_data_add_obj(NMDedupMultiIndex      *multi_idx,
-                     modified                             = TRUE;
-                 }
- 
--                /* OR assume_config_once flag */
--                if (obj_new->ip_route.r_assume_config_once
--                    && !obj_old->ip_route.r_assume_config_once) {
--                    obj_new = nmp_object_stackinit_obj(&obj_new_stackinit, obj_new);
--                    obj_new_stackinit.ip_route.r_assume_config_once = TRUE;
--                    modified                                        = TRUE;
--                }
-                 break;
-             default:
-                 nm_assert_not_reached();
-@@ -3056,9 +3042,8 @@ nm_l3_config_data_merge(NML3ConfigData       *self,
-             const NMPlatformIPAddress *a_src = NMP_OBJECT_CAST_IP_ADDRESS(obj);
-             NMPlatformIPXAddress       a;
-             NML3ConfigMergeHookResult  hook_result = {
--                 .ip4acd_not_ready   = NM_OPTION_BOOL_DEFAULT,
--                 .assume_config_once = NM_OPTION_BOOL_DEFAULT,
--                 .force_commit       = NM_OPTION_BOOL_DEFAULT,
-+                 .ip4acd_not_ready = NM_OPTION_BOOL_DEFAULT,
-+                 .force_commit     = NM_OPTION_BOOL_DEFAULT,
-             };
- 
- #define _ensure_a()                                       \
-@@ -3091,12 +3076,6 @@ nm_l3_config_data_merge(NML3ConfigData       *self,
-                 a.a4.a_acd_not_ready = (!!hook_result.ip4acd_not_ready);
-             }
- 
--            if (hook_result.assume_config_once != NM_OPTION_BOOL_DEFAULT
--                && (!!hook_result.assume_config_once) != a_src->a_assume_config_once) {
--                _ensure_a();
--                a.ax.a_assume_config_once = (!!hook_result.assume_config_once);
--            }
--
-             if (hook_result.force_commit != NM_OPTION_BOOL_DEFAULT
-                 && (!!hook_result.force_commit) != a_src->a_force_commit) {
-                 _ensure_a();
-@@ -3121,9 +3100,8 @@ nm_l3_config_data_merge(NML3ConfigData       *self,
-                 const NMPlatformIPRoute  *r_src = NMP_OBJECT_CAST_IP_ROUTE(obj);
-                 NMPlatformIPXRoute        r;
-                 NML3ConfigMergeHookResult hook_result = {
--                    .ip4acd_not_ready   = NM_OPTION_BOOL_DEFAULT,
--                    .assume_config_once = NM_OPTION_BOOL_DEFAULT,
--                    .force_commit       = NM_OPTION_BOOL_DEFAULT,
-+                    .ip4acd_not_ready = NM_OPTION_BOOL_DEFAULT,
-+                    .force_commit     = NM_OPTION_BOOL_DEFAULT,
-                 };
- 
- #define _ensure_r()                                     \
-@@ -3149,12 +3127,6 @@ nm_l3_config_data_merge(NML3ConfigData       *self,
-                     r.rx.ifindex = self->ifindex;
-                 }
- 
--                if (hook_result.assume_config_once != NM_OPTION_BOOL_DEFAULT
--                    && (!!hook_result.assume_config_once) != r_src->r_assume_config_once) {
--                    _ensure_r();
--                    r.rx.r_assume_config_once = (!!hook_result.assume_config_once);
--                }
--
-                 if (hook_result.force_commit != NM_OPTION_BOOL_DEFAULT
-                     && (!!hook_result.force_commit) != r_src->r_force_commit) {
-                     _ensure_r();
-diff --git a/src/core/nm-l3-config-data.h b/src/core/nm-l3-config-data.h
-index b7a1bb32f5..20a32c62aa 100644
---- a/src/core/nm-l3-config-data.h
-+++ b/src/core/nm-l3-config-data.h
-@@ -137,7 +137,6 @@ NML3ConfigData *nm_l3_config_data_new_from_platform(NMDedupMultiIndex        *mu
- 
- typedef struct {
-     NMOptionBool ip4acd_not_ready;
--    NMOptionBool assume_config_once;
-     NMOptionBool force_commit;
- } NML3ConfigMergeHookResult;
- 
-diff --git a/src/core/nm-l3-ipv4ll.c b/src/core/nm-l3-ipv4ll.c
-index 68cb17fb09..473f3c0f03 100644
---- a/src/core/nm-l3-ipv4ll.c
-+++ b/src/core/nm-l3-ipv4ll.c
-@@ -600,7 +600,7 @@ _l3cd_config_add(NML3IPv4LL *self)
-         nm_assert_not_reached();
- 
-     self->l3cfg_commit_handle = nm_l3cfg_commit_type_register(self->l3cfg,
--                                                              NM_L3_CFG_COMMIT_TYPE_ASSUME,
-+                                                              NM_L3_CFG_COMMIT_TYPE_UPDATE,
-                                                               self->l3cfg_commit_handle,
-                                                               "ipv4ll");
-     nm_l3cfg_commit_on_idle_schedule(self->l3cfg, NM_L3_CFG_COMMIT_TYPE_AUTO);
-diff --git a/src/core/nm-l3-ipv6ll.c b/src/core/nm-l3-ipv6ll.c
-index 60da4ee8d7..2b9a1a0ef4 100644
---- a/src/core/nm-l3-ipv6ll.c
-+++ b/src/core/nm-l3-ipv6ll.c
-@@ -398,10 +398,7 @@ _lladdr_handle_changed(NML3IPv6LL *self)
-      * NML3IPv4LL, where we use NM_L3_CONFIG_MERGE_FLAGS_ONLY_FOR_ACD. The difference
-      * is that for IPv6 we let kernel do DAD, so we need to actually configure the
-      * address. For IPv4, we can run ACD without configuring anything in kernel,
--     * and let the user decide how to proceed.
--     *
--     * Also in this case, we use the most graceful commit-type (NM_L3_CFG_COMMIT_TYPE_ASSUME),
--     * but for that to work, we also need NM_L3CFG_CONFIG_FLAGS_ASSUME_CONFIG_ONCE flag. */
-+     * and let the user decide how to proceed. */
- 
-     l3cd = nm_l3_ipv6ll_get_l3cd(self);
- 
-@@ -421,7 +418,7 @@ _lladdr_handle_changed(NML3IPv6LL *self)
-                                 NM_DNS_PRIORITY_DEFAULT_NORMAL,
-                                 NM_L3_ACD_DEFEND_TYPE_ALWAYS,
-                                 0,
--                                NM_L3CFG_CONFIG_FLAGS_ASSUME_CONFIG_ONCE,
-+                                NM_L3CFG_CONFIG_FLAGS_NONE,
-                                 NM_L3_CONFIG_MERGE_FLAGS_NONE))
-             changed = TRUE;
-     } else {
-@@ -430,7 +427,7 @@ _lladdr_handle_changed(NML3IPv6LL *self)
-     }
- 
-     self->l3cfg_commit_handle = nm_l3cfg_commit_type_register(self->l3cfg,
--                                                              l3cd ? NM_L3_CFG_COMMIT_TYPE_ASSUME
-+                                                              l3cd ? NM_L3_CFG_COMMIT_TYPE_UPDATE
-                                                                    : NM_L3_CFG_COMMIT_TYPE_NONE,
-                                                               self->l3cfg_commit_handle,
-                                                               "ipv6ll");
-diff --git a/src/core/nm-l3cfg.c b/src/core/nm-l3cfg.c
-index eeb041d042..20058f2321 100644
---- a/src/core/nm-l3cfg.c
-+++ b/src/core/nm-l3cfg.c
-@@ -363,7 +363,6 @@ static NM_UTILS_ENUM2STR_DEFINE(_l3_cfg_commit_type_to_string,
-                                 NML3CfgCommitType,
-                                 NM_UTILS_ENUM2STR(NM_L3_CFG_COMMIT_TYPE_AUTO, "auto"),
-                                 NM_UTILS_ENUM2STR(NM_L3_CFG_COMMIT_TYPE_NONE, "none"),
--                                NM_UTILS_ENUM2STR(NM_L3_CFG_COMMIT_TYPE_ASSUME, "assume"),
-                                 NM_UTILS_ENUM2STR(NM_L3_CFG_COMMIT_TYPE_UPDATE, "update"),
-                                 NM_UTILS_ENUM2STR(NM_L3_CFG_COMMIT_TYPE_REAPPLY, "reapply"), );
- 
-@@ -768,14 +767,6 @@ _nm_n_acd_data_probe_new(NML3Cfg *self, in_addr_t addr, guint32 timeout_msec, gp
-     }                                                                                             \
-     G_STMT_END
- 
--static gboolean
--_obj_state_data_get_assume_config_once(const ObjStateData *obj_state)
--{
--    nm_assert_obj_state(NULL, obj_state);
--
--    return nmp_object_get_assume_config_once(obj_state->obj);
--}
--
- static ObjStateData *
- _obj_state_data_new(const NMPObject *obj, const NMPObject *plobj)
- {
-@@ -1054,10 +1045,6 @@ _obj_states_sync_filter(NML3Cfg *self, const NMPObject *obj, NML3CfgCommitType c
-     nm_assert(c_list_is_empty(&obj_state->os_zombie_lst));
- 
-     if (!obj_state->os_nm_configured) {
--        if (commit_type == NM_L3_CFG_COMMIT_TYPE_ASSUME
--            && !_obj_state_data_get_assume_config_once(obj_state))
--            return FALSE;
--
-         obj_state->os_nm_configured = TRUE;
- 
-         _LOGD("obj-state: configure-first-time: %s",
-@@ -3088,7 +3075,6 @@ nm_l3cfg_commit_on_idle_schedule(NML3Cfg *self, NML3CfgCommitType commit_type)
-     nm_assert(NM_IS_L3CFG(self));
-     nm_assert(NM_IN_SET(commit_type,
-                         NM_L3_CFG_COMMIT_TYPE_AUTO,
--                        NM_L3_CFG_COMMIT_TYPE_ASSUME,
-                         NM_L3_CFG_COMMIT_TYPE_UPDATE,
-                         NM_L3_CFG_COMMIT_TYPE_REAPPLY));
- 
-@@ -3503,7 +3489,6 @@ out_clear:
- typedef struct {
-     NML3Cfg      *self;
-     gconstpointer tag;
--    bool          assume_config_once;
-     bool          to_commit;
-     bool          force_commit_once;
- } L3ConfigMergeHookAddObjData;
-@@ -3523,11 +3508,9 @@ _l3_hook_add_obj_cb(const NML3ConfigData      *l3cd,
-     nm_assert(obj);
-     nm_assert(hook_result);
-     nm_assert(hook_result->ip4acd_not_ready == NM_OPTION_BOOL_DEFAULT);
--    nm_assert(hook_result->assume_config_once == NM_OPTION_BOOL_DEFAULT);
-     nm_assert(hook_result->force_commit == NM_OPTION_BOOL_DEFAULT);
- 
--    hook_result->assume_config_once = hook_data->assume_config_once;
--    hook_result->force_commit       = hook_data->force_commit_once;
-+    hook_result->force_commit = hook_data->force_commit_once;
- 
-     switch (NMP_OBJECT_GET_TYPE(obj)) {
-     case NMP_OBJECT_TYPE_IP4_ADDRESS:
-@@ -3683,9 +3666,7 @@ _l3cfg_update_combined_config(NML3Cfg               *self,
-             if (NM_FLAGS_HAS(l3cd_data->config_flags, NM_L3CFG_CONFIG_FLAGS_ONLY_FOR_ACD))
-                 continue;
- 
--            hook_data.tag = l3cd_data->tag_confdata;
--            hook_data.assume_config_once =
--                NM_FLAGS_HAS(l3cd_data->config_flags, NM_L3CFG_CONFIG_FLAGS_ASSUME_CONFIG_ONCE);
-+            hook_data.tag               = l3cd_data->tag_confdata;
-             hook_data.force_commit_once = l3cd_data->force_commit_once;
- 
-             nm_l3_config_data_merge(l3cd,
-@@ -4212,8 +4193,7 @@ _l3_commit_one(NML3Cfg              *self,
-     nm_assert(NM_IN_SET(commit_type,
-                         NM_L3_CFG_COMMIT_TYPE_NONE,
-                         NM_L3_CFG_COMMIT_TYPE_REAPPLY,
--                        NM_L3_CFG_COMMIT_TYPE_UPDATE,
--                        NM_L3_CFG_COMMIT_TYPE_ASSUME));
-+                        NM_L3_CFG_COMMIT_TYPE_UPDATE));
-     nm_assert_addr_family(addr_family);
- 
-     _LOGT("committing IPv%c configuration (%s)",
-@@ -4299,7 +4279,6 @@ _l3_commit(NML3Cfg *self, NML3CfgCommitType commit_type, gboolean is_idle)
-     nm_assert(NM_IN_SET(commit_type,
-                         NM_L3_CFG_COMMIT_TYPE_NONE,
-                         NM_L3_CFG_COMMIT_TYPE_AUTO,
--                        NM_L3_CFG_COMMIT_TYPE_ASSUME,
-                         NM_L3_CFG_COMMIT_TYPE_UPDATE,
-                         NM_L3_CFG_COMMIT_TYPE_REAPPLY));
-     nm_assert(self->priv.p->commit_reentrant_count == 0);
-@@ -4423,10 +4402,7 @@ nm_l3cfg_commit_type_register(NML3Cfg                 *self,
-     char                     buf[64];
- 
-     nm_assert(NM_IS_L3CFG(self));
--    nm_assert(NM_IN_SET(commit_type,
--                        NM_L3_CFG_COMMIT_TYPE_NONE,
--                        NM_L3_CFG_COMMIT_TYPE_ASSUME,
--                        NM_L3_CFG_COMMIT_TYPE_UPDATE));
-+    nm_assert(NM_IN_SET(commit_type, NM_L3_CFG_COMMIT_TYPE_NONE, NM_L3_CFG_COMMIT_TYPE_UPDATE));
- 
-     /* It would be easy (and maybe convenient) to allow that @existing_handle
-      * can currently be registered on another NML3Cfg instance. But then we couldn't
-diff --git a/src/core/nm-l3cfg.h b/src/core/nm-l3cfg.h
-index 0ea6864661..f6ec39ced8 100644
---- a/src/core/nm-l3cfg.h
-+++ b/src/core/nm-l3cfg.h
-@@ -363,15 +363,6 @@ typedef enum _nm_packed {
-     /* Don't touch the interface. */
-     NM_L3_CFG_COMMIT_TYPE_NONE,
- 
--    /* ASSUME means to keep any pre-existing extra routes/addresses, while
--     * also not adding routes/addresses that are not present yet. This is to
--     * gracefully take over after restart, where the existing IP configuration
--     * should not change.
--     *
--     * The flag NM_L3CFG_CONFIG_FLAGS_ASSUME_CONFIG_ONCE can make certain addresses/
--     * routes commitable also during "assume". */
--    NM_L3_CFG_COMMIT_TYPE_ASSUME,
--
-     /* UPDATE means to add new addresses/routes, while also removing addresses/routes
-      * that are no longer present (but were previously configured by NetworkManager).
-      * Routes/addresses that were removed externally won't be re-added, and routes/addresses
-diff --git a/src/core/tests/test-l3cfg.c b/src/core/tests/test-l3cfg.c
-index 5501079ec4..eebfbcf58e 100644
---- a/src/core/tests/test-l3cfg.c
-+++ b/src/core/tests/test-l3cfg.c
-@@ -382,13 +382,11 @@ test_l3cfg(gconstpointer test_data)
-         nm_l3cfg_commit_type_register(l3cfg0, NM_L3_CFG_COMMIT_TYPE_UPDATE, NULL, "test1");
- 
-     if (!nmtst_get_rand_one_case_in(4)) {
--        commit_type_2 =
--            nm_l3cfg_commit_type_register(l3cfg0,
--                                          nmtst_rand_select(NM_L3_CFG_COMMIT_TYPE_NONE,
--                                                            NM_L3_CFG_COMMIT_TYPE_ASSUME,
--                                                            NM_L3_CFG_COMMIT_TYPE_UPDATE),
--                                          NULL,
--                                          "test2");
-+        commit_type_2 = nm_l3cfg_commit_type_register(
-+            l3cfg0,
-+            nmtst_rand_select(NM_L3_CFG_COMMIT_TYPE_NONE, NM_L3_CFG_COMMIT_TYPE_UPDATE),
-+            NULL,
-+            "test2");
-     } else
-         commit_type_2 = NULL;
- 
-diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c
-index 8459231dc2..b1ae168f66 100644
---- a/src/libnm-platform/nm-platform.c
-+++ b/src/libnm-platform/nm-platform.c
-@@ -6312,7 +6312,6 @@ nm_platform_ip4_address_to_string(const NMPlatformIP4Address *address, char *buf
-         "%s" /* label */
-         " src %s"
-         "%s" /* a_acd_not_ready */
--        "%s" /* a_assume_config_once */
-         "%s" /* a_force_commit */
-         "",
-         s_address,
-@@ -6332,7 +6331,6 @@ nm_platform_ip4_address_to_string(const NMPlatformIP4Address *address, char *buf
-         str_label,
-         nmp_utils_ip_config_source_to_string(address->addr_source, s_source, sizeof(s_source)),
-         address->a_acd_not_ready ? " ip4acd-not-ready" : "",
--        address->a_assume_config_once ? " assume-config-once" : "",
-         address->a_force_commit ? " force-commit" : "");
-     g_free(str_peer);
-     return buf;
-@@ -6453,7 +6451,6 @@ nm_platform_ip6_address_to_string(const NMPlatformIP6Address *address, char *buf
-         buf,
-         len,
-         "%s/%d lft %s pref %s%s%s%s%s src %s"
--        "%s" /* a_assume_config_once */
-         "%s" /* a_force_commit */
-         "",
-         s_address,
-@@ -6465,7 +6462,6 @@ nm_platform_ip6_address_to_string(const NMPlatformIP6Address *address, char *buf
-         str_dev,
-         _to_string_ifa_flags(address->n_ifa_flags, s_flags, sizeof(s_flags)),
-         nmp_utils_ip_config_source_to_string(address->addr_source, s_source, sizeof(s_source)),
--        address->a_assume_config_once ? " assume-config-once" : "",
-         address->a_force_commit ? " force-commit" : "");
-     g_free(str_peer);
-     return buf;
-@@ -6569,7 +6565,6 @@ nm_platform_ip4_route_to_string(const NMPlatformIP4Route *route, char *buf, gsiz
-         "%s"                      /* initcwnd */
-         "%s"                      /* initrwnd */
-         "%s"                      /* mtu */
--        "%s"                      /* r_assume_config_once */
-         "%s"                      /* r_force_commit */
-         "",
-         nm_net_aux_rtnl_rtntype_n2a_maybe_buf(nm_platform_route_type_uncoerce(route->type_coerced),
-@@ -6628,7 +6623,6 @@ nm_platform_ip4_route_to_string(const NMPlatformIP4Route *route, char *buf, gsiz
-                                                        route->lock_mtu ? "lock " : "",
-                                                        route->mtu)
-                                       : "",
--        route->r_assume_config_once ? " assume-config-once" : "",
-         route->r_force_commit ? " force-commit" : "");
-     return buf;
- }
-@@ -6704,7 +6698,6 @@ nm_platform_ip6_route_to_string(const NMPlatformIP6Route *route, char *buf, gsiz
-         "%s"                      /* initrwnd */
-         "%s"                      /* mtu */
-         "%s"                      /* pref */
--        "%s"                      /* r_assume_config_once */
-         "%s"                      /* r_force_commit */
-         "",
-         nm_net_aux_rtnl_rtntype_n2a_maybe_buf(nm_platform_route_type_uncoerce(route->type_coerced),
-@@ -6767,7 +6760,6 @@ nm_platform_ip6_route_to_string(const NMPlatformIP6Route *route, char *buf, gsiz
-             " pref %s",
-             nm_icmpv6_router_pref_to_string(route->rt_pref, str_pref2, sizeof(str_pref2)))
-                        : "",
--        route->r_assume_config_once ? " assume-config-once" : "",
-         route->r_force_commit ? " force-commit" : "");
- 
-     return buf;
-@@ -7923,7 +7915,6 @@ nm_platform_ip4_address_hash_update(const NMPlatformIP4Address *obj, NMHashState
-                         NM_HASH_COMBINE_BOOLS(guint8,
-                                               obj->use_ip4_broadcast_address,
-                                               obj->a_acd_not_ready,
--                                              obj->a_assume_config_once,
-                                               obj->a_force_commit));
-     nm_hash_update_strarr(h, obj->label);
- }
-@@ -7972,7 +7963,6 @@ nm_platform_ip4_address_cmp(const NMPlatformIP4Address *a,
-             if (a->use_ip4_broadcast_address)
-                 NM_CMP_FIELD(a, b, broadcast_address);
-             NM_CMP_FIELD_UNSAFE(a, b, a_acd_not_ready);
--            NM_CMP_FIELD_UNSAFE(a, b, a_assume_config_once);
-             NM_CMP_FIELD_UNSAFE(a, b, a_force_commit);
-         }
-         return 0;
-@@ -7983,18 +7973,17 @@ nm_platform_ip4_address_cmp(const NMPlatformIP4Address *a,
- void
- nm_platform_ip6_address_hash_update(const NMPlatformIP6Address *obj, NMHashState *h)
- {
--    nm_hash_update_vals(
--        h,
--        obj->ifindex,
--        obj->addr_source,
--        obj->timestamp,
--        obj->lifetime,
--        obj->preferred,
--        obj->n_ifa_flags,
--        obj->plen,
--        obj->address,
--        obj->peer_address,
--        NM_HASH_COMBINE_BOOLS(guint8, obj->a_assume_config_once, obj->a_force_commit));
-+    nm_hash_update_vals(h,
-+                        obj->ifindex,
-+                        obj->addr_source,
-+                        obj->timestamp,
-+                        obj->lifetime,
-+                        obj->preferred,
-+                        obj->n_ifa_flags,
-+                        obj->plen,
-+                        obj->address,
-+                        obj->peer_address,
-+                        NM_HASH_COMBINE_BOOLS(guint8, obj->a_force_commit));
- }
- 
- int
-@@ -8037,7 +8026,6 @@ nm_platform_ip6_address_cmp(const NMPlatformIP6Address *a,
-             NM_CMP_FIELD(a, b, preferred);
-             NM_CMP_FIELD(a, b, n_ifa_flags);
-             NM_CMP_FIELD(a, b, addr_source);
--            NM_CMP_FIELD_UNSAFE(a, b, a_assume_config_once);
-             NM_CMP_FIELD_UNSAFE(a, b, a_force_commit);
-         }
-         return 0;
-@@ -8142,7 +8130,7 @@ nm_platform_ip4_route_hash_update(const NMPlatformIP4Route *obj,
-                             obj->initrwnd,
-                             obj->mtu,
-                             obj->r_rtm_flags,
--                            NM_HASH_COMBINE_BOOLS(guint16,
-+                            NM_HASH_COMBINE_BOOLS(guint8,
-                                                   obj->metric_any,
-                                                   obj->table_any,
-                                                   obj->lock_window,
-@@ -8150,7 +8138,6 @@ nm_platform_ip4_route_hash_update(const NMPlatformIP4Route *obj,
-                                                   obj->lock_initcwnd,
-                                                   obj->lock_initrwnd,
-                                                   obj->lock_mtu,
--                                                  obj->r_assume_config_once,
-                                                   obj->r_force_commit));
-         break;
-     }
-@@ -8241,10 +8228,8 @@ nm_platform_ip4_route_cmp(const NMPlatformIP4Route *a,
-         NM_CMP_FIELD(a, b, initcwnd);
-         NM_CMP_FIELD(a, b, initrwnd);
-         NM_CMP_FIELD(a, b, mtu);
--        if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL) {
--            NM_CMP_FIELD_UNSAFE(a, b, r_assume_config_once);
-+        if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL)
-             NM_CMP_FIELD_UNSAFE(a, b, r_force_commit);
--        }
-         break;
-     }
-     return 0;
-@@ -8337,7 +8322,6 @@ nm_platform_ip6_route_hash_update(const NMPlatformIP6Route *obj,
-                                                   obj->lock_initcwnd,
-                                                   obj->lock_initrwnd,
-                                                   obj->lock_mtu,
--                                                  obj->r_assume_config_once,
-                                                   obj->r_force_commit),
-                             obj->window,
-                             obj->cwnd,
-@@ -8421,10 +8405,8 @@ nm_platform_ip6_route_cmp(const NMPlatformIP6Route *a,
-             NM_CMP_DIRECT(_route_pref_normalize(a->rt_pref), _route_pref_normalize(b->rt_pref));
-         else
-             NM_CMP_FIELD(a, b, rt_pref);
--        if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL) {
--            NM_CMP_FIELD_UNSAFE(a, b, r_assume_config_once);
-+        if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL)
-             NM_CMP_FIELD_UNSAFE(a, b, r_force_commit);
--        }
-         break;
-     }
-     return 0;
-diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h
-index 203f8c7bbd..dcbafdc6e8 100644
---- a/src/libnm-platform/nm-platform.h
-+++ b/src/libnm-platform/nm-platform.h
-@@ -331,8 +331,6 @@ typedef enum {
-     /* Meta flags not honored by NMPlatform (netlink code). Instead, they can be
-      * used by the upper layers which use NMPlatformIPRoute to track addresses that
-      * should be configured. */             \
--    /* Whether the address is should be configured once during assume. */                    \
--    bool a_assume_config_once : 1;                                                           \
-     bool a_force_commit : 1;                                                                 \
-                                                                                              \
-     guint8 plen;                                                                             \
-@@ -476,12 +474,9 @@ typedef union {
-      * This field overrides "table_coerced" field. If "table_any" is true, then
-      * the "table_coerced" field is ignored (unlike for the metric). */            \
-     bool table_any : 1;                                                                   \
--                                                                                          \
-     /* Meta flags not honored by NMPlatform (netlink code). Instead, they can be
-      * used by the upper layers which use NMPlatformIPRoute to track routes that
-      * should be configured. */          \
--    /* Whether the route is should be configured once during assume. */                   \
--    bool r_assume_config_once : 1;                                                        \
-     /* Whether the route should be committed even if it was removed externally. */        \
-     bool r_force_commit : 1;                                                              \
-                                                                                           \
-diff --git a/src/libnm-platform/nmp-object.h b/src/libnm-platform/nmp-object.h
-index 784dcc2dec..36d7fefb72 100644
---- a/src/libnm-platform/nmp-object.h
-+++ b/src/libnm-platform/nmp-object.h
-@@ -1097,21 +1097,6 @@ nm_platform_lookup_object_by_addr_family(NMPlatform   *platform,
- 
- /*****************************************************************************/
- 
--static inline gboolean
--nmp_object_get_assume_config_once(const NMPObject *obj)
--{
--    switch (NMP_OBJECT_GET_TYPE(obj)) {
--    case NMP_OBJECT_TYPE_IP4_ADDRESS:
--    case NMP_OBJECT_TYPE_IP6_ADDRESS:
--        return NMP_OBJECT_CAST_IP_ADDRESS(obj)->a_assume_config_once;
--    case NMP_OBJECT_TYPE_IP4_ROUTE:
--    case NMP_OBJECT_TYPE_IP6_ROUTE:
--        return NMP_OBJECT_CAST_IP_ROUTE(obj)->r_assume_config_once;
--    default:
--        return nm_assert_unreachable_val(FALSE);
--    }
--}
--
- static inline gboolean
- nmp_object_get_force_commit(const NMPObject *obj)
- {
--- 
-2.35.1
-
diff --git a/SOURCES/1006-dhcp-routes-src-rh2094778.patch b/SOURCES/1006-dhcp-routes-src-rh2094778.patch
deleted file mode 100644
index c5fee4c..0000000
--- a/SOURCES/1006-dhcp-routes-src-rh2094778.patch
+++ /dev/null
@@ -1,309 +0,0 @@
-From 3547c4d09a1d10b150a61bcbdc2418d750f7f616 Mon Sep 17 00:00:00 2001
-From: Thomas Haller <thaller@redhat.com>
-Date: Fri, 1 Apr 2022 08:39:56 +0200
-Subject: [PATCH 1/2] dhcp: set "src" for DHCPv4 routes
-
-Let's set the "src" (RTA_PREFSRC) of DHCP routes.
-This helps with source address selection.
-
-This can matter if the interface also has static addresses
-configured.
-
-Systemd-networkd also does this ([1], [2]).
-
-[1] https://github.com/systemd/systemd/commit/ac2dce5f36bb8b1a877ff765e6a4dfde6bfb2d49
-[2] https://github.com/systemd/systemd/blob/5b89bff55f45235f72d30d90fd489fe2247ad00d/src/network/networkd-dhcp4.c#L395
-
-Related: https://bugzilla.redhat.com/show_bug.cgi?id=1995372
-
-https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1173
-(cherry picked from commit 2dc7a3d9f9135959adf415405bdcb05a7387c1d4)
-(cherry picked from commit 10b9e07bfc3ae044b35a7dc6559aa6a4583bd7e8)
-(cherry picked from commit f2942d11a75e5fb0bda35f8b659d0643f1f418b2)
----
- src/core/dhcp/nm-dhcp-nettools.c | 16 ++++++++++++----
- src/core/dhcp/nm-dhcp-systemd.c  |  4 +++-
- src/core/dhcp/nm-dhcp-utils.c    | 26 +++++++++++++++-----------
- 3 files changed, 30 insertions(+), 16 deletions(-)
-
-diff --git a/src/core/dhcp/nm-dhcp-nettools.c b/src/core/dhcp/nm-dhcp-nettools.c
-index d7fbe3561599..769b0325f23d 100644
---- a/src/core/dhcp/nm-dhcp-nettools.c
-+++ b/src/core/dhcp/nm-dhcp-nettools.c
-@@ -154,6 +154,7 @@ static gboolean
- lease_parse_address(NDhcp4ClientLease *lease,
-                     NML3ConfigData    *l3cd,
-                     GHashTable        *options,
-+                    in_addr_t         *out_address,
-                     GError           **error)
- {
-     struct in_addr a_address;
-@@ -268,6 +269,8 @@ lease_parse_address(NDhcp4ClientLease *lease,
-                                         .preferred    = a_lifetime,
-                                     }));
- 
-+    NM_SET_OUT(out_address, a_address.s_addr);
-+
-     return TRUE;
- }
- 
-@@ -326,6 +329,7 @@ lease_parse_address_list(NDhcp4ClientLease       *lease,
- static void
- lease_parse_routes(NDhcp4ClientLease *lease,
-                    NML3ConfigData    *l3cd,
-+                   in_addr_t          lease_address,
-                    GHashTable        *options,
-                    NMStrBuf          *sbuf)
- {
-@@ -373,10 +377,11 @@ lease_parse_routes(NDhcp4ClientLease *lease,
- 
-             nm_l3_config_data_add_route_4(l3cd,
-                                           &((const NMPlatformIP4Route){
-+                                              .rt_source     = NM_IP_CONFIG_SOURCE_DHCP,
-                                               .network       = dest,
-                                               .plen          = plen,
-                                               .gateway       = gateway,
--                                              .rt_source     = NM_IP_CONFIG_SOURCE_DHCP,
-+                                              .pref_src      = lease_address,
-                                               .table_any     = TRUE,
-                                               .table_coerced = 0,
-                                               .metric_any    = TRUE,
-@@ -416,10 +421,11 @@ lease_parse_routes(NDhcp4ClientLease *lease,
- 
-             nm_l3_config_data_add_route_4(l3cd,
-                                           &((const NMPlatformIP4Route){
-+                                              .rt_source     = NM_IP_CONFIG_SOURCE_DHCP,
-                                               .network       = dest,
-                                               .plen          = plen,
-                                               .gateway       = gateway,
--                                              .rt_source     = NM_IP_CONFIG_SOURCE_DHCP,
-+                                              .pref_src      = lease_address,
-                                               .table_any     = TRUE,
-                                               .table_coerced = 0,
-                                               .metric_any    = TRUE,
-@@ -464,6 +470,7 @@ lease_parse_routes(NDhcp4ClientLease *lease,
-                                           &((const NMPlatformIP4Route){
-                                               .rt_source     = NM_IP_CONFIG_SOURCE_DHCP,
-                                               .gateway       = gateway,
-+                                              .pref_src      = lease_address,
-                                               .table_any     = TRUE,
-                                               .table_coerced = 0,
-                                               .metric_any    = TRUE,
-@@ -547,6 +554,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
-     const char                             *v_str;
-     guint16                                 v_u16;
-     in_addr_t                               v_inaddr;
-+    in_addr_t                               lease_address;
-     struct in_addr                          v_inaddr_s;
-     int                                     r;
- 
-@@ -556,7 +564,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
- 
-     options = nm_dhcp_option_create_options_dict();
- 
--    if (!lease_parse_address(lease, l3cd, options, error))
-+    if (!lease_parse_address(lease, l3cd, options, &lease_address, error))
-         return NULL;
- 
-     r = n_dhcp4_client_lease_get_server_identifier(lease, &v_inaddr_s);
-@@ -575,7 +583,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
-                                           v_inaddr);
-     }
- 
--    lease_parse_routes(lease, l3cd, options, &sbuf);
-+    lease_parse_routes(lease, l3cd, lease_address, options, &sbuf);
- 
-     lease_parse_address_list(lease, l3cd, NM_DHCP_OPTION_DHCP4_DOMAIN_NAME_SERVER, options, &sbuf);
- 
-diff --git a/src/core/dhcp/nm-dhcp-systemd.c b/src/core/dhcp/nm-dhcp-systemd.c
-index 0884def35dc6..d17646154f67 100644
---- a/src/core/dhcp/nm-dhcp-systemd.c
-+++ b/src/core/dhcp/nm-dhcp-systemd.c
-@@ -309,10 +309,11 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
- 
-             nm_l3_config_data_add_route_4(l3cd,
-                                           &((const NMPlatformIP4Route){
-+                                              .rt_source     = NM_IP_CONFIG_SOURCE_DHCP,
-                                               .network       = network_net,
-                                               .plen          = r_plen,
-                                               .gateway       = r_gateway.s_addr,
--                                              .rt_source     = NM_IP_CONFIG_SOURCE_DHCP,
-+                                              .pref_src      = a_address.s_addr,
-                                               .metric_any    = TRUE,
-                                               .metric        = m,
-                                               .table_any     = TRUE,
-@@ -366,6 +367,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
-                                           &((const NMPlatformIP4Route){
-                                               .rt_source     = NM_IP_CONFIG_SOURCE_DHCP,
-                                               .gateway       = a_router[i].s_addr,
-+                                              .pref_src      = a_address.s_addr,
-                                               .table_any     = TRUE,
-                                               .table_coerced = 0,
-                                               .metric_any    = TRUE,
-diff --git a/src/core/dhcp/nm-dhcp-utils.c b/src/core/dhcp/nm-dhcp-utils.c
-index 4a138086b957..c71796f8bd9d 100644
---- a/src/core/dhcp/nm-dhcp-utils.c
-+++ b/src/core/dhcp/nm-dhcp-utils.c
-@@ -28,7 +28,8 @@ static gboolean
- ip4_process_dhcpcd_rfc3442_routes(const char     *iface,
-                                   const char     *str,
-                                   NML3ConfigData *l3cd,
--                                  guint32        *gwaddr)
-+                                  in_addr_t       address,
-+                                  guint32        *out_gwaddr)
- {
-     gs_free const char **routes = NULL;
-     const char         **r;
-@@ -79,7 +80,7 @@ ip4_process_dhcpcd_rfc3442_routes(const char     *iface,
-         have_routes = TRUE;
-         if (rt_cidr == 0 && rt_addr == 0) {
-             /* FIXME: how to handle multiple routers? */
--            *gwaddr = rt_route;
-+            *out_gwaddr = rt_route;
-         } else {
-             _LOG2I(LOGD_DHCP4,
-                    iface,
-@@ -91,13 +92,13 @@ ip4_process_dhcpcd_rfc3442_routes(const char     *iface,
-             nm_l3_config_data_add_route_4(
-                 l3cd,
-                 &((const NMPlatformIP4Route){
-+                    .rt_source  = NM_IP_CONFIG_SOURCE_DHCP,
-                     .network    = nm_utils_ip4_address_clear_host_address(rt_addr, rt_cidr),
-                     .plen       = rt_cidr,
-                     .gateway    = rt_route,
--                    .rt_source  = NM_IP_CONFIG_SOURCE_DHCP,
-+                    .pref_src   = address,
-                     .metric_any = TRUE,
-                     .table_any  = TRUE,
--
-                 }));
-         }
-     }
-@@ -158,7 +159,8 @@ static gboolean
- ip4_process_dhclient_rfc3442_routes(const char     *iface,
-                                     const char     *str,
-                                     NML3ConfigData *l3cd,
--                                    guint32        *gwaddr)
-+                                    in_addr_t       address,
-+                                    guint32        *out_gwaddr)
- {
-     gs_free const char **octets = NULL;
-     const char *const   *o;
-@@ -182,13 +184,14 @@ ip4_process_dhclient_rfc3442_routes(const char     *iface,
-         have_routes = TRUE;
-         if (!route.plen) {
-             /* gateway passed as classless static route */
--            *gwaddr = route.gateway;
-+            *out_gwaddr = route.gateway;
-         } else {
-             char b1[INET_ADDRSTRLEN];
-             char b2[INET_ADDRSTRLEN];
- 
-             /* normal route */
-             route.rt_source     = NM_IP_CONFIG_SOURCE_DHCP;
-+            route.pref_src      = address;
-             route.table_any     = TRUE;
-             route.table_coerced = 0;
-             route.metric_any    = TRUE;
-@@ -212,14 +215,15 @@ static gboolean
- ip4_process_classless_routes(const char     *iface,
-                              GHashTable     *options,
-                              NML3ConfigData *l3cd,
--                             guint32        *gwaddr)
-+                             in_addr_t       address,
-+                             guint32        *out_gwaddr)
- {
-     const char *str, *p;
- 
-     g_return_val_if_fail(options != NULL, FALSE);
-     g_return_val_if_fail(l3cd != NULL, FALSE);
- 
--    *gwaddr = 0;
-+    *out_gwaddr = 0;
- 
-     /* dhcpd/dhclient in Fedora has support for rfc3442 implemented using a
-      * slightly different format:
-@@ -266,10 +270,10 @@ ip4_process_classless_routes(const char     *iface,
- 
-     if (strchr(str, '/')) {
-         /* dhcpcd format */
--        return ip4_process_dhcpcd_rfc3442_routes(iface, str, l3cd, gwaddr);
-+        return ip4_process_dhcpcd_rfc3442_routes(iface, str, l3cd, address, out_gwaddr);
-     }
- 
--    return ip4_process_dhclient_rfc3442_routes(iface, str, l3cd, gwaddr);
-+    return ip4_process_dhclient_rfc3442_routes(iface, str, l3cd, address, out_gwaddr);
- }
- 
- static void
-@@ -422,7 +426,7 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx,
-     /* Routes: if the server returns classless static routes, we MUST ignore
-      * the 'static_routes' option.
-      */
--    if (!ip4_process_classless_routes(iface, options, l3cd, &gateway))
-+    if (!ip4_process_classless_routes(iface, options, l3cd, address.address, &gateway))
-         process_classful_routes(iface, options, l3cd);
- 
-     if (gateway) {
--- 
-2.36.1
-
-
-From ebfc7c2c58e6125346baf9b530e71b2571dc0c10 Mon Sep 17 00:00:00 2001
-From: Thomas Haller <thaller@redhat.com>
-Date: Wed, 13 Apr 2022 10:43:13 +0200
-Subject: [PATCH 2/2] dhcp/dhclient: fix setting "src" attribute for certain
- routes
-
-Fixes: 2dc7a3d9f913 ('dhcp: set "src" for DHCPv4 routes')
-(cherry picked from commit 197e73ac7c53556b32ff048c9720907be3217487)
-(cherry picked from commit 0c6d242dc0b67b6269657acf33bf9d1f0830f0b4)
-(cherry picked from commit b0a7dda2eae1493a3a285ed1d08178409266ba07)
----
- src/core/dhcp/nm-dhcp-utils.c | 9 +++++++--
- 1 file changed, 7 insertions(+), 2 deletions(-)
-
-diff --git a/src/core/dhcp/nm-dhcp-utils.c b/src/core/dhcp/nm-dhcp-utils.c
-index c71796f8bd9d..35a2c6543759 100644
---- a/src/core/dhcp/nm-dhcp-utils.c
-+++ b/src/core/dhcp/nm-dhcp-utils.c
-@@ -277,7 +277,10 @@ ip4_process_classless_routes(const char     *iface,
- }
- 
- static void
--process_classful_routes(const char *iface, GHashTable *options, NML3ConfigData *l3cd)
-+process_classful_routes(const char     *iface,
-+                        GHashTable     *options,
-+                        NML3ConfigData *l3cd,
-+                        in_addr_t       address)
- {
-     gs_free const char **searches = NULL;
-     const char         **s;
-@@ -325,6 +328,7 @@ process_classful_routes(const char *iface, GHashTable *options, NML3ConfigData *
-             route.plen = 32;
-         }
-         route.gateway       = rt_route;
-+        route.pref_src      = address;
-         route.rt_source     = NM_IP_CONFIG_SOURCE_DHCP;
-         route.table_any     = TRUE;
-         route.table_coerced = 0;
-@@ -427,7 +431,7 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx,
-      * the 'static_routes' option.
-      */
-     if (!ip4_process_classless_routes(iface, options, l3cd, address.address, &gateway))
--        process_classful_routes(iface, options, l3cd);
-+        process_classful_routes(iface, options, l3cd, address.address);
- 
-     if (gateway) {
-         _LOG2I(LOGD_DHCP4, iface, "  gateway %s", _nm_utils_inet4_ntop(gateway, sbuf));
-@@ -457,6 +461,7 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx,
-         const NMPlatformIP4Route r = {
-             .rt_source     = NM_IP_CONFIG_SOURCE_DHCP,
-             .gateway       = gateway,
-+            .pref_src      = address.address,
-             .table_any     = TRUE,
-             .table_coerced = 0,
-             .metric_any    = TRUE,
--- 
-2.36.1
-
diff --git a/SOURCES/1007-platform-workaround-for-preserving-ipv6-address-rhbz2094715.patch b/SOURCES/1007-platform-workaround-for-preserving-ipv6-address-rhbz2094715.patch
deleted file mode 100644
index 62b555b..0000000
--- a/SOURCES/1007-platform-workaround-for-preserving-ipv6-address-rhbz2094715.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 43b27ab2c4735e35d84e6f5c90b8a79e23c05587 Mon Sep 17 00:00:00 2001
-From: Thomas Haller <thaller@redhat.com>
-Date: Thu, 9 Jun 2022 10:00:47 +0200
-Subject: [PATCH 1/1] platform: workaround for preserving IPv6 address order
-
-https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/ ## 1021
----
- src/libnm-platform/nm-platform.c | 25 ++++++++++++++++++++-----
- 1 file changed, 20 insertions(+), 5 deletions(-)
-
-diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c
-index f264ed7a45b2..45534dd96a46 100644
---- a/src/libnm-platform/nm-platform.c
-+++ b/src/libnm-platform/nm-platform.c
-@@ -3978,11 +3978,26 @@ nm_platform_ip_address_sync(NMPlatform *self,
-     /* @plat_addresses for IPv6 must be sorted in decreasing priority order (highest priority addresses first).
-      * IPv4 are probably unsorted or sorted with lowest priority first, but their order doesn't matter because
-      * we check the "secondary" flag. */
--    plat_addresses = nm_platform_lookup_clone(
--        self,
--        nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4), ifindex),
--        NULL,
--        NULL);
-+    if (IS_IPv4) {
-+        plat_addresses = nm_platform_lookup_clone(
-+            self,
-+            nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4), ifindex),
-+            NULL,
-+            NULL);
-+    } else {
-+        /* HACK: early 1.36 versions had a bug of not actually reordering the IPv6 addresses.
-+         * This was fixed by commit cd4601802de5 ('platform: fix address order in
-+         * nm_platform_ip_address_sync()').
-+         *
-+         * However, also in 1.36, the actually implemented order of IPv6 addresses is not
-+         * the one we want ([1]). So disable the fix again, to not reorder IPv6 addresses.
-+         *
-+         * The effect is, that DHCPv6 addresses end up being preferred over SLAAC, because
-+         * they get added later during activation. Of course, if any address gets added
-+         * even later (like a new router appearing), then the order will be wrong again.
-+         *
-+         * [1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/1021 */
-+    }
- 
-     if (nm_g_ptr_array_len(plat_addresses) > 0) {
-         /* Delete addresses that interfere with our intended order. */
--- 
-2.36.1
diff --git a/SOURCES/readme-ifcfg-rh.txt b/SOURCES/readme-ifcfg-rh.txt
new file mode 100644
index 0000000..b69a681
--- /dev/null
+++ b/SOURCES/readme-ifcfg-rh.txt
@@ -0,0 +1,31 @@
+NetworkManager stores new network profiles in keyfile format in the
+/etc/NetworkManager/system-connections/ directory.
+
+Previously, NetworkManager stored network profiles in ifcfg format
+in this directory (/etc/sysconfig/network-scripts/). However, the ifcfg
+format is deprecated. By default, NetworkManager no longer creates
+new profiles in this format.
+
+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.
+
+If you still use network profiles in ifcfg format, consider migrating
+them to keyfile format. To migrate all profiles at once, enter:
+
+# nmcli connection migrate
+
+This command migrates all profiles from ifcfg format to keyfile
+format and stores them in /etc/NetworkManager/system-connections/.
+
+Alternatively, to migrate only a specific profile, enter:
+
+# nmcli connection migrate <profile_name|UUID|D-Bus_path>
+
+For further details, see:
+* nm-settings-keyfile(5)
+* nmcli(1)
diff --git a/SPECS/NetworkManager.spec b/SPECS/NetworkManager.spec
index db7a718..5b4cce8 100644
--- a/SPECS/NetworkManager.spec
+++ b/SPECS/NetworkManager.spec
@@ -1,22 +1,22 @@
-
 %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 glib2_version %(pkg-config --modversion glib-2.0 2>/dev/null || echo bad)
 
 %global epoch_version 1
-%global rpm_version 1.36.0
-%global real_version 1.36.0
-%global release_version 5
+%global real_version 1.40.0
+%global rpm_version %{real_version}
+%global release_version 1
 %global snapshot %{nil}
 %global git_sha %{nil}
+%global bcond_default_debug 0
+%global bcond_default_test 0
 
 %global obsoletes_device_plugins     1:0.9.9.95-1
 %global obsoletes_ppp_plugin         1:1.5.3
 %global obsoletes_initscripts_updown 1:1.36.0-0.6
+%global obsoletes_ifcfg_rh           1:1.36.2
 
-%global systemd_dir %{_prefix}/lib/systemd/system
-%global sysctl_dir %{_prefix}/lib/sysctl.d
 %global nmlibdir %{_prefix}/lib/%{name}
 %global nmplugindir %{_libdir}/%{name}/%{version}-%{release}
 
@@ -39,18 +39,6 @@
 
 ###############################################################################
 
-%if "x__BCOND_DEFAULT_DEBUG__" == "x1" || "x__BCOND_DEFAULT_DEBUG__" == "x0"
-%global bcond_default_debug __BCOND_DEFAULT_DEBUG__
-%else
-%global bcond_default_debug 0
-%endif
-
-%if "x__BCOND_DEFAULT_TEST__" == "x1" || "x__BCOND_DEFAULT_TEST__" == "x0"
-%global bcond_default_test __BCOND_DEFAULT_TEST__
-%else
-%global bcond_default_test 0
-%endif
-
 %bcond_with meson
 %bcond_without adsl
 %bcond_without bluetooth
@@ -83,12 +71,12 @@
 %else
 %bcond_with connectivity_fedora
 %endif
-%if 0%{?rhel} && 0%{?rhel} > 7
+%if 0%{?rhel} && 0%{?rhel} >= 8
 %bcond_without connectivity_redhat
 %else
 %bcond_with connectivity_redhat
 %endif
-%if 0%{?fedora} > 28 || 0%{?rhel} > 7
+%if 0%{?fedora} >= 29 || 0%{?rhel} >= 8
 %bcond_without crypto_gnutls
 %else
 %bcond_with crypto_gnutls
@@ -98,7 +86,7 @@
 %else
 %bcond_without iwd
 %endif
-%if 0%{?fedora} > 31 || 0%{?rhel} > 7
+%if 0%{?fedora} >= 32 || 0%{?rhel} >= 8
 %bcond_without firewalld_zone
 %else
 %bcond_with firewalld_zone
@@ -106,7 +94,7 @@
 
 ###############################################################################
 
-%if 0%{?fedora} || 0%{?rhel} > 7
+%if 0%{?fedora} || 0%{?rhel} >= 8
 %global dbus_version 1.9.18
 %global dbus_sys_dir %{_datadir}/dbus-1/system.d
 %else
@@ -128,15 +116,15 @@
 %global with_modem_manager_1 0
 %endif
 
-%if 0%{?fedora} >= 31 || 0%{?rhel} > 7
+%if 0%{?fedora} >= 31 || 0%{?rhel} >= 8
 %global dhcp_default internal
 %else
 %global dhcp_default dhclient
 %endif
 
-%if 0%{?fedora} || 0%{?rhel} > 7
+%if 0%{?fedora} || 0%{?rhel} >= 8
 %global logging_backend_default journal
-%if 0%{?fedora} || 0%{?rhel} > 8
+%if 0%{?fedora} || 0%{?rhel} >= 9
 %global dns_rc_manager_default auto
 %else
 %global dns_rc_manager_default symlink
@@ -146,10 +134,22 @@
 %global dns_rc_manager_default file
 %endif
 
-%if 0%{?rhel} > 8 || 0%{?fedora} > 32
-%global config_plugins_default keyfile,ifcfg-rh
+%if 0%{?fedora} >= 33 || 0%{?rhel} >= 9
+%global config_plugins_default_ifcfg_rh 0
+%else
+%global config_plugins_default_ifcfg_rh 1
+%endif
+
+%if 0%{?fedora} >= 36 || 0%{?rhel} >= 10
+%global split_ifcfg_rh 1
 %else
-%global config_plugins_default ifcfg-rh
+%global split_ifcfg_rh 0
+%endif
+
+%if 0%{?fedora} >= 36 || 0%{?rhel} >= 9
+%global ifcfg_warning 1
+%else
+%global ifcfg_warning 0
 %endif
 
 %if 0%{?fedora}
@@ -185,6 +185,7 @@ Source2: 00-server.conf
 Source4: 20-connectivity-fedora.conf
 Source5: 20-connectivity-redhat.conf
 Source6: 70-nm-connectivity.conf
+Source7: readme-ifcfg-rh.txt
 
 # RHEL downstream patches that change behavior from upstream.
 # These are not bugfixes, hence they are also relevant after
@@ -192,16 +193,10 @@ Source6: 70-nm-connectivity.conf
 # Patch0001: 0001-some.patch
 
 # Bugfixes that are only relevant until next rebase of the package.
-Patch1001: 1001-wwan-dns-fix-rh2059138.patch
-Patch1002: 1002-checkpoint-preserve-external-bridge-ports-rh2035519.patch
-Patch1003: 1003-fix-ovsdb-removal-ports-rhbz1935026.patch
-Patch1004: 1004-n-dhcp4-discard-NAKs-from-other-servers-rhbz2067122.patch
-Patch1005: 1005-fix-dhcp-loses-lease-when-restarting-rhbz2094715.patch
-Patch1006: 1006-dhcp-routes-src-rh2094778.patch
-Patch1007: 1007-platform-workaround-for-preserving-ipv6-address-rhbz2094715.patch
+# Patch1001: 1001-some.patch
 
 Requires(post): systemd
-%if 0%{?fedora} || 0%{?rhel} > 7
+%if 0%{?fedora} || 0%{?rhel} >= 8
 Requires(post): systemd-udev
 %endif
 Requires(post): /usr/sbin/update-alternatives
@@ -222,6 +217,9 @@ Obsoletes: NetworkManager-wimax < 1.2
 Suggests: NetworkManager-initscripts-updown
 %endif
 Obsoletes: NetworkManager < %{obsoletes_initscripts_updown}
+%if 0%{?split_ifcfg_rh}
+Obsoletes: NetworkManager < %{obsoletes_ifcfg_rh}
+%endif
 
 %if 0%{?rhel} && 0%{?rhel} <= 7
 # Kept for RHEL to ensure that wired 802.1x works out of the box
@@ -244,8 +242,7 @@ BuildRequires: meson
 BuildRequires: automake
 BuildRequires: autoconf
 %endif
-BuildRequires: intltool
-BuildRequires: gettext-devel
+BuildRequires: gettext-devel >= 0.19.8
 
 BuildRequires: dbus-devel >= %{dbus_version}
 BuildRequires: glib2-devel >= 2.40.0
@@ -287,14 +284,16 @@ BuildRequires: mobile-broadband-provider-info-devel
 BuildRequires: newt-devel
 %endif
 BuildRequires: /usr/bin/dbus-launch
-%if 0%{?fedora} > 27 || 0%{?rhel} > 7
+%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
 %endif
 BuildRequires: libselinux-devel
 BuildRequires: polkit-devel
@@ -309,7 +308,7 @@ BuildRequires: libubsan
 BuildRequires: firewalld-filesystem
 %endif
 BuildRequires: iproute
-%if 0%{?fedora} || 0%{?rhel} > 7
+%if 0%{?fedora} || 0%{?rhel} >= 8
 BuildRequires: iproute-tc
 %endif
 
@@ -398,7 +397,7 @@ Requires: wireless-regdb
 Requires: crda
 %endif
 
-%if %{with iwd} && (0%{?fedora} > 24 || 0%{?rhel} > 7)
+%if %{with iwd} && (0%{?fedora} >= 25 || 0%{?rhel} >= 8)
 Requires: (wpa_supplicant >= %{wpa_supplicant_version} or iwd)
 Suggests: wpa_supplicant
 %else
@@ -531,6 +530,9 @@ deployments.
 %package dispatcher-routing-rules
 Summary: NetworkManager dispatcher file for advanced routing rules
 Group: System Environment/Base
+%if 0%{?split_ifcfg_rh}
+Requires: %{name}-initscripts-ifcfg-rh
+%endif
 BuildArch: noarch
 Provides: %{name}-config-routing-rules = %{epoch}:%{version}-%{release}
 Obsoletes: %{name}-config-routing-rules < 1:1.31.0
@@ -555,6 +557,19 @@ by nm-connection-editor and nm-applet in a non-graphical environment.
 %endif
 
 
+%if 0%{?split_ifcfg_rh}
+%package initscripts-ifcfg-rh
+Summary: NetworkManager plugin for reading and writing connections in ifcfg-rh format
+Group: System Environment/Base
+Requires: %{name} = %{epoch}:%{version}-%{release}
+Obsoletes: NetworkManager < %{obsoletes_ifcfg_rh}
+
+%description initscripts-ifcfg-rh
+Installs a plugin for reading and writing connection profiles using
+the Red Hat ifcfg format in /etc/sysconfig/network-scripts/.
+%endif
+
+
 %if %{with nm_cloud_setup}
 %package cloud-setup
 Summary: Automatically configure NetworkManager in cloud
@@ -688,7 +703,6 @@ Preferably use nmcli instead.
 %endif
 	-Dsession_tracking=systemd \
 	-Dsuspend_resume=systemd \
-	-Dsystemdsystemunitdir=%{systemd_dir} \
 	-Dsystem_ca_path=/etc/pki/tls/cert.pem \
 	-Ddbus_conf_dir=%{dbus_sys_dir} \
 	-Dtests=yes \
@@ -705,7 +719,9 @@ Preferably use nmcli instead.
 	-Dfirewalld_zone=false \
 %endif
 	-Ddist_version=%{version}-%{release} \
-	-Dconfig_plugins_default=%{config_plugins_default} \
+%if %{?config_plugins_default_ifcfg_rh}
+	-Dconfig_plugins_default=ifcfg-rh \
+%endif
 	-Dresolvconf=no \
 	-Dnetconfig=no \
 	-Dconfig_dns_rc_manager_default=%{dns_rc_manager_default} \
@@ -719,11 +735,10 @@ Preferably use nmcli instead.
 gtkdocize
 %endif
 autoreconf --install --force
-intltoolize --automake --copy --force
 %configure \
 	--with-runstatedir=%{_rundir} \
-	--disable-silent-rules \
-	--disable-static \
+	--enable-silent-rules=no \
+	--enable-static=no \
 	--with-nft=/usr/sbin/nft \
 	--with-iptables=/usr/sbin/iptables \
 	--with-dhclient=yes \
@@ -738,26 +753,26 @@ intltoolize --automake --copy --force
 %if %{with sanitizer}
 	--with-address-sanitizer=exec \
 %if 0%{?fedora} || 0%{?rhel} >= 8
-	--enable-undefined-sanitizer \
+	--enable-undefined-sanitizer=yes \
 %else
-	--disable-undefined-sanitizer \
+	--enable-undefined-sanitizer=no \
 %endif
 %else
 	--with-address-sanitizer=no \
-	--disable-undefined-sanitizer \
+	--enable-undefined-sanitizer=no \
 %endif
 %if %{with debug}
-	--enable-more-logging \
+	--enable-more-logging=yes \
 	--with-more-asserts=10000 \
 %else
-	--disable-more-logging \
-	--without-more-asserts \
+	--enable-more-logging=no \
+	--with-more-asserts=0 \
 %endif
-	--enable-ld-gc \
+	--enable-ld-gc=yes \
 %if %{with lto}
-	--enable-lto \
+	--enable-lto=yes \
 %else
-	--disable-lto \
+	--enable-lto=no \
 %endif
 	--with-libaudit=yes-disabled-by-default \
 %if 0%{?with_modem_manager_1}
@@ -796,11 +811,11 @@ intltoolize --automake --copy --force
 	--with-nm-cloud-setup=no \
 %endif
 	--enable-vala=yes \
-	--enable-introspection \
+	--enable-introspection=yes \
 %if %{with regen_docs}
-	--enable-gtk-doc \
+	--enable-gtk-doc=yes \
 %else
-	--disable-gtk-doc \
+	--enable-gtk-doc=no \
 %endif
 %if %{with team}
 	--enable-teamdctl=yes \
@@ -815,16 +830,15 @@ intltoolize --automake --copy --force
 	--with-selinux=yes \
 	--enable-polkit=yes \
 	--enable-modify-system=yes \
-	--enable-concheck \
+	--enable-concheck=yes \
 %if 0%{?fedora}
-	--with-libpsl \
+	--with-libpsl=yes \
 %else
-	--without-libpsl \
+	--with-libpsl=no \
 %endif
 	--with-ebpf=%{ebpf_enabled} \
 	--with-session-tracking=systemd \
 	--with-suspend-resume=systemd \
-	--with-systemdsystemunitdir=%{systemd_dir} \
 	--with-system-ca-path=/etc/pki/tls/cert.pem \
 	--with-dbus-sys-dir=%{dbus_sys_dir} \
 	--with-tests=yes \
@@ -841,12 +855,14 @@ intltoolize --automake --copy --force
 	--enable-ppp=yes \
 %endif
 %if %{with firewalld_zone}
-	--enable-firewalld-zone \
+	--enable-firewalld-zone=yes \
 %else
-	--disable-firewalld-zone \
+	--enable-firewalld-zone=no \
 %endif
 	--with-dist-version=%{version}-%{release} \
-	--with-config-plugins-default=%{config_plugins_default} \
+%if %{?config_plugins_default_ifcfg_rh}
+	--with-config-plugins-default=ifcfg-rh \
+%endif
 	--with-resolvconf=no \
 	--with-netconfig=no \
 	--with-config-dns-rc-manager-default=%{dns_rc_manager_default} \
@@ -877,6 +893,10 @@ mkdir -p %{buildroot}%{_sysctldir}
 cp %{SOURCE6} %{buildroot}%{_sysctldir}
 %endif
 
+%if 0%{?ifcfg_warning}
+cp %{SOURCE7} %{buildroot}%{_sysconfdir}/sysconfig/network-scripts
+%endif
+
 cp examples/dispatcher/10-ifcfg-rh-routes.sh %{buildroot}%{nmlibdir}/dispatcher.d/
 ln -s ../no-wait.d/10-ifcfg-rh-routes.sh %{buildroot}%{nmlibdir}/dispatcher.d/pre-up.d/
 ln -s ../10-ifcfg-rh-routes.sh %{buildroot}%{nmlibdir}/dispatcher.d/no-wait.d/
@@ -917,7 +937,7 @@ make -k %{?_smp_mflags} check || :
 
 
 %pre
-if [ -f "%{systemd_dir}/network-online.target.wants/NetworkManager-wait-online.service" ] ; then
+if [ -f "%{_unitdir}/network-online.target.wants/NetworkManager-wait-online.service" ] ; then
     # older versions used to install this file, effectively always enabling
     # NetworkManager-wait-online.service. We no longer do that and rely on
     # preset.
@@ -1005,7 +1025,9 @@ fi
 %{dbus_sys_dir}/org.freedesktop.NetworkManager.conf
 %{dbus_sys_dir}/nm-dispatcher.conf
 %{dbus_sys_dir}/nm-priv-helper.conf
+%if 0%{?split_ifcfg_rh} == 0
 %{dbus_sys_dir}/nm-ifcfg-rh.conf
+%endif
 %{_sbindir}/%{name}
 %{_bindir}/nmcli
 %{_datadir}/bash-completion/completions/nmcli
@@ -1028,7 +1050,9 @@ fi
 %{_libexecdir}/nm-priv-helper
 %dir %{_libdir}/%{name}
 %dir %{nmplugindir}
-%{nmplugindir}/libnm-settings-plugin*.so
+%if 0%{?split_ifcfg_rh} == 0
+%{nmplugindir}/libnm-settings-plugin-ifcfg-rh.so
+%endif
 %if %{with nmtui}
 %exclude %{_mandir}/man1/nmtui*
 %endif
@@ -1046,6 +1070,7 @@ fi
 %{_mandir}/man8/nm-initrd-generator.8.gz
 %{_mandir}/man8/NetworkManager.8.gz
 %{_mandir}/man8/NetworkManager-dispatcher.8.gz
+%{_mandir}/man8/NetworkManager-wait-online.service.8.gz
 %dir %{_localstatedir}/lib/NetworkManager
 %dir %{_sysconfdir}/sysconfig/network-scripts
 %{_datadir}/dbus-1/system-services/org.freedesktop.nm_dispatcher.service
@@ -1056,13 +1081,16 @@ fi
 %{_prefix}/lib/firewalld/zones/nm-shared.xml
 %endif
 # systemd stuff
-%{systemd_dir}/NetworkManager.service
-%{systemd_dir}/NetworkManager-wait-online.service
-%{systemd_dir}/NetworkManager-dispatcher.service
-%{systemd_dir}/nm-priv-helper.service
+%{_unitdir}/NetworkManager.service
+%{_unitdir}/NetworkManager-wait-online.service
+%{_unitdir}/NetworkManager-dispatcher.service
+%{_unitdir}/nm-priv-helper.service
 %dir %{_datadir}/doc/NetworkManager/examples
 %{_datadir}/doc/NetworkManager/examples/server.conf
-%doc NEWS AUTHORS README CONTRIBUTING.md TODO
+%if 0%{?ifcfg_warning}
+%{_sysconfdir}/sysconfig/network-scripts/readme-ifcfg-rh.txt
+%endif
+%doc NEWS AUTHORS README.md CONTRIBUTING.md
 %license COPYING
 %license COPYING.LGPL
 %license COPYING.GFDL
@@ -1104,7 +1132,7 @@ fi
 %if %{with ovs}
 %files ovs
 %{nmplugindir}/libnm-device-plugin-ovs.so
-%{systemd_dir}/NetworkManager.service.d/NetworkManager-ovs.conf
+%{_unitdir}/NetworkManager.service.d/NetworkManager-ovs.conf
 %{_mandir}/man7/nm-openvswitch.7*
 %endif
 
@@ -1175,11 +1203,18 @@ fi
 %endif
 
 
+%if 0%{?split_ifcfg_rh}
+%files initscripts-ifcfg-rh
+%{nmplugindir}/libnm-settings-plugin-ifcfg-rh.so
+%{dbus_sys_dir}/nm-ifcfg-rh.conf
+%endif
+
+
 %if %{with nm_cloud_setup}
 %files cloud-setup
 %{_libexecdir}/nm-cloud-setup
-%{systemd_dir}/nm-cloud-setup.service
-%{systemd_dir}/nm-cloud-setup.timer
+%{_unitdir}/nm-cloud-setup.service
+%{_unitdir}/nm-cloud-setup.timer
 %{nmlibdir}/dispatcher.d/90-nm-cloud-setup.sh
 %{nmlibdir}/dispatcher.d/no-wait.d/90-nm-cloud-setup.sh
 %{_mandir}/man8/nm-cloud-setup.8*
@@ -1194,17 +1229,91 @@ fi
 
 
 %changelog
-* Thu Jun 09 2022 Fernando Fernandez Mancera <ferferna@redhat.com> - 1:1.36.0-5
-- Fix DHCP loses lease when restarting (rh #2094715)
-- core: set "src" attribute for routes from DHCPv4 (rh #2094778)
-- platform: workaround for preserving IPv6 address order (rh #2094715)
-
-* Fri Apr 01 2022 Fernando Fernandez Mancera <ferferna@redhat.com> - 1:1.36.0-4
-- n-dhcp4: discard NAKs from different servers in SELECTING (rh #2067122)
-
-* Fri Mar 11 2022 Thomas Haller <thaller@redhat.com> - 1:1.36.0-3
-- core: preserve external bridge ports during checkpoint rollback (rh #2061711)
-- ovs-port: fix removal of ovsdb entry if the interface goes away (rh #2061709)
+* Fri Aug 26 2022 Ana Cabral <acabral@redhat.com> - 1:1.40.0-1
+- Update to 1.40.0 release
+
+* Tue Aug 16 2022 Ana Cabral <acabral@redhat.com> - 1:1.39.90-1
+- Update to 1.39.90 release (release candidate)
+- Add support for MPTCP (rh #2029636)
+- nmcli: fix assertion failure (rh #2092323)
+- bond: fix arp_ip_target option (rh #2117202)
+- nmci: fix test restart_L2_only_lacp (rh #2092361)
+
+* Fri Jul 29 2022 Lubomir Rintel <lkundrak@v3.sk> - 1:1.39.12-1
+- Update to 1.39.12 release (development)
+- bridge: fix reapply support (rh #2092762)
+
+* Thu Jul 28 2022 Beniamino Galvani <bgalvani@redhat.com> - 1:1.39.11-1
+- Update to 1.39.11 release (development)
+- core: support nm.debug kernel command line option (rh #2102313)
+- ovs: don't ever move unactivated devices to failed state (rh #2077950)
+- dhclient: fix EXTENDED DHCP event handling (rh #2109285)
+- core: make "nmcli net off/on" more robust (rh #2093175)
+- bridge: add reapply support (rh #2092762)
+- bridge: don't reset vlan filtering on external connections (rh #2107647)
+
+* Thu Jul 14 2022 Vojtech Bubela <vbubela@redhat.com> - 1:1.39.10-1
+- Update to 1.39.10 release (development)
+- add support for {rto_min,quickack,advmss} route attributes (rh #2068525)
+- fix empty hostname for "SaveHostname" and make setting hostname async (rh #2090946)
+
+* Thu Jun 30 2022 Lubomir Rintel <lkundrak@v3.sk> - 1:1.39.8-1
+- Update to 1.39.8 release (development)
+- core: make ipv6.addr-gen-mode default configurable (rh #1743161) (rh #2082682)
+- dhcpv6: finish DAD before considering a lease to be good (rh #2096386)
+- core: add connection.wait-activation-delay property (rh #2008337)
+
+* Thu Jun 16 2022 Thomas Haller <thaller@redhat.com> - 1:1.39.7-2
+- fix priority of IPv6 addresses to prefer manual over DHCPv6 over SLAAC (rh #2097293)
+- reverse order of priority for static IPv6 addresses in "ipv6.addresses" (rh #2097293)
+
+* Wed Jun 15 2022 Lubomir Rintel <lkundrak@v3.sk> - 1:1.39.7-1
+- Update to 1.39.7 release (development)
+- core: cancel the IP check on deactivation (rh #2080928)
+- core: ensure DHCP is restarted every time the link goes up (rh #2079406)
+- core: fix a leak of L3 configuration memory (rh #2083453)
+- ppp: fix a race with pppd when removing addresses (rh #2085382)
+- wifi: fix a crash when checking WEP supplicant capability (rh #2092782)
+
+* Wed Jun  1 2022 Beniamino Galvani <bgalvani@redhat.com> - 1:1.39.6-1
+- Update to 1.39.6 release (development)
+- Implement ACD (address conflict detection) for DHCPv4 (rh #1713380)
+
+* Thu May 19 2022 Ana Cabral <acabral@redhat.com> - 1:1.39.5-1
+- Update to 1.39.5 release (development)
+- dhcp: fix ignoring addresses with DHCPv6 otherconf (O flag) (rh #2083968)
+- cloud-setup: reorder addresses to honor "primary_ip_address" (rh #2079849)
+
+* Wed May  4 2022 Wen Liang <wenliang@redhat.com> - 1:1.39.3-1
+- Update to 1.39.3 release (development)
+- l3cfg: drop NM_L3_CFG_COMMIT_TYPE_ASSUME and assume_config_once (rh #2050216)
+
+* Thu Apr 21 2022 Thomas Haller <thaller@redhat.com> - 1:1.39.2-1
+- Update to 1.39.2 release (development)
+- dhcp: set "src" attribute for DHCP routes (rh #1995372)
+- dhcp: drop internal DHCPv4 client based on systemd code (rh #2073067)
+- core: delay startup complete for DNS update (rh #2049421)
+- nmcli: support offline mode to create and edit keyfiles (rh #1361145)
+
+* Wed Apr 6 2022 Ana Cabral <acabral@redhat.com> - 1:1.39.0-1
+- Upgrade to 1.39.0 release (development)
+- Include a migration tool for ifcfg configuration to NM keyfiles
+  (rh #2059608)
+
+* Thu Mar 24 2022 Lubomir Rintel <lkundrak@v3.sk> - 1:1.37.3-1
+- Upgrade to 1.37.3 release (development)
+- core: allow reapply on autoconnect-slaves property change (rh #2065049)
+- wifi: do not advertise channels outside regulatory domain (rh #2062785)
+- wifi: warn about WEP being phased out (rh #2030997)
+- bond: reject reapply when fail_over_mac was changed (rh #2003214)
+
+* Wed Mar  9 2022 Beniamino Galvani <bgalvani@redhat.com> - 1:1.37.2-1
+- Upgrade to 1.37.2 release (development)
+- core: preserve external ports during checkpoint rollback (rh #2061711)
+- core: fix ovs bridge deletion (rh #2061709)
+- core: shorten hostname when too long (rh #2033643)
+- nm-online: bump the timeout upper limit to 2073600 seconds (rh #2025617)
+- cloud-setup: fix crash when handling sigterm (rh #2027674)
 
 * Mon Feb 28 2022 Beniamino Galvani <bgalvani@redhat.com> - 1:1.36.0-2
 - core: fix setting DNS from WWAN and PPP (rh #2059138)