diff --git a/.NetworkManager.metadata b/.NetworkManager.metadata
index 30eaae1..c2cbe5f 100644
--- a/.NetworkManager.metadata
+++ b/.NetworkManager.metadata
@@ -1 +1 @@
-eba3800b6308c38916f22e8515fb415730a4e89a SOURCES/NetworkManager-1.40.0.tar.xz
+c803db8a3480ed683e8f24424b38b08bb295013d SOURCES/NetworkManager-1.40.16.tar.xz
diff --git a/.gitignore b/.gitignore
index 2ac6a43..911106a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-SOURCES/NetworkManager-1.40.0.tar.xz
+SOURCES/NetworkManager-1.40.16.tar.xz
diff --git a/SOURCES/1001-revert-restart-DHCP-when-MAC-changes-rh2124443.patch b/SOURCES/1001-revert-restart-DHCP-when-MAC-changes-rh2124443.patch
deleted file mode 100644
index d7307a9..0000000
--- a/SOURCES/1001-revert-restart-DHCP-when-MAC-changes-rh2124443.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From e6e54f331776f7832e2a359658e8740bffab60ad Mon Sep 17 00:00:00 2001
-From: Beniamino Galvani <bgalvani@redhat.com>
-Date: Tue, 27 Sep 2022 15:58:10 +0200
-Subject: [PATCH] Revert "device: restart DHCP when the MAC changes"
-
-The commit causes problems with bridges. When a new port is attached
-the MAC of the bridge possibly changes and if we restart DHCP the
-bridge will get a different IP address.
-
-Revert the change until a better solution to the original problem is
-found.
-
-This reverts commit 905adabdba033bbfc33013d0ad203bd444131dc5.
-
-https://bugzilla.redhat.com/show_bug.cgi?id=2124443
-https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1401
-(cherry picked from commit 98197386078a471ed993d009e34e08a6aa7c22d9)
-(cherry picked from commit f9db4f4604e26ff0f769b56b9bef8f7d991d23d9)
----
- src/core/devices/nm-device.c | 9 +++------
- 1 file changed, 3 insertions(+), 6 deletions(-)
-
-diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
-index d63b902b16..7585acf4d3 100644
---- a/src/core/devices/nm-device.c
-+++ b/src/core/devices/nm-device.c
-@@ -6646,7 +6646,6 @@ device_link_changed(gpointer user_data)
-     NMDeviceClass                  *klass             = NM_DEVICE_GET_CLASS(self);
-     NMDevicePrivate                *priv              = NM_DEVICE_GET_PRIVATE(self);
-     gboolean                        ip_ifname_changed = FALSE;
--    gboolean                        hw_addr_changed;
-     nm_auto_nmpobj const NMPObject *pllink_keep_alive = NULL;
-     const NMPlatformLink           *pllink;
-     const char                     *str;
-@@ -6693,9 +6692,9 @@ device_link_changed(gpointer user_data)
-     if (ifindex == nm_device_get_ip_ifindex(self))
-         _stats_update_counters_from_pllink(self, pllink);
- 
--    had_hw_addr     = (priv->hw_addr != NULL);
--    hw_addr_changed = nm_device_update_hw_address(self);
--    got_hw_addr     = (!had_hw_addr && priv->hw_addr);
-+    had_hw_addr = (priv->hw_addr != NULL);
-+    nm_device_update_hw_address(self);
-+    got_hw_addr = (!had_hw_addr && priv->hw_addr);
-     nm_device_update_permanent_hw_address(self, FALSE);
- 
-     if (pllink->name[0] && !nm_streq(priv->iface, pllink->name)) {
-@@ -6746,8 +6745,6 @@ device_link_changed(gpointer user_data)
-     /* Update DHCP, etc, if needed */
-     if (ip_ifname_changed)
-         nm_device_update_dynamic_ip_setup(self, "IP interface changed");
--    else if (hw_addr_changed)
--        nm_device_update_dynamic_ip_setup(self, "hw-address changed");
- 
-     was_up   = priv->up;
-     priv->up = NM_FLAGS_HAS(pllink->n_ifi_flags, IFF_UP);
--- 
-2.37.3
-
diff --git a/SOURCES/1002-dns-sort-according-to-priority-rh2134563.patch b/SOURCES/1002-dns-sort-according-to-priority-rh2134563.patch
deleted file mode 100644
index 12e79f5..0000000
--- a/SOURCES/1002-dns-sort-according-to-priority-rh2134563.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From c35eb06542b555523df8d7a6e1d00826deb4f625 Mon Sep 17 00:00:00 2001
-From: Beniamino Galvani <bgalvani@redhat.com>
-Date: Thu, 13 Oct 2022 17:23:15 +0200
-Subject: [PATCH 1/2] dns: add comment explaining the purpose of `any_removed`
-
-(cherry picked from commit 4d1ecd8d6dbe6666f9005950a95a6ba8321e653c)
-(cherry picked from commit 01b4040a7ad6f0b8c4aad1aabe4827841df2fe1e)
----
- src/core/dns/nm-dns-manager.c | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
-diff --git a/src/core/dns/nm-dns-manager.c b/src/core/dns/nm-dns-manager.c
-index 1e54452aa4..c08e2cacd7 100644
---- a/src/core/dns/nm-dns-manager.c
-+++ b/src/core/dns/nm-dns-manager.c
-@@ -2039,8 +2039,14 @@ nm_dns_manager_set_ip_config(NMDnsManager         *self,
- 
-     if (!ip_data) {
-         ip_data = _dns_config_ip_data_new(data, addr_family, source_tag, l3cd, ip_config_type);
--        if (!any_removed)
-+        if (!any_removed) {
-+            /* `any_removed` tracks whether we deleted any ip_data. If that happened,
-+             * we already compared the old and new l3cds and set `changed` accordingly.
-+             * Here we only need to set `changed` if we are adding a new ip_data without
-+             * removing the old one.
-+             */
-             changed = TRUE;
-+        }
-     } else {
-         ip_data->ip_config_type = ip_config_type;
-         changed                 = TRUE;
--- 
-2.37.3
-
-From b9b64e667afe4f6f55747a55a28e5f50cf352a4a Mon Sep 17 00:00:00 2001
-From: Beniamino Galvani <bgalvani@redhat.com>
-Date: Thu, 13 Oct 2022 17:06:19 +0200
-Subject: [PATCH 2/2] dns: sort the ip-data list when a new element is added
-
-In nm_dns_manager_set_ip_config() we try to avoid calling update_dns()
-unless something changes, because updating DNS is expensive and can
-trigger other actions such as a new hostname resolution.
-
-When we add a new ip_data, even if the new element is equivalent to
-the old one that was removed, we need to sort the list again.
-
-Fixes: ce0a36d20fa6 ('dns: better track l3cd changes')
-https://bugzilla.redhat.com/show_bug.cgi?id=2098574
-(cherry picked from commit 3cc7801779ed05d13c3e2422f11ddb365bc37242)
-(cherry picked from commit db4c55c8d32179bcaf222029469802d96312413b)
----
- src/core/dns/nm-dns-manager.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/src/core/dns/nm-dns-manager.c b/src/core/dns/nm-dns-manager.c
-index c08e2cacd7..a2fead3f35 100644
---- a/src/core/dns/nm-dns-manager.c
-+++ b/src/core/dns/nm-dns-manager.c
-@@ -2039,6 +2039,7 @@ nm_dns_manager_set_ip_config(NMDnsManager         *self,
- 
-     if (!ip_data) {
-         ip_data = _dns_config_ip_data_new(data, addr_family, source_tag, l3cd, ip_config_type);
-+        priv->ip_data_lst_need_sort = TRUE;
-         if (!any_removed) {
-             /* `any_removed` tracks whether we deleted any ip_data. If that happened,
-              * we already compared the old and new l3cds and set `changed` accordingly.
--- 
-2.37.3
-
diff --git a/SOURCES/1003-dhcp-decline-IPv6-lease-if-all-adresses-fail-DAD-rh2132281.patch b/SOURCES/1003-dhcp-decline-IPv6-lease-if-all-adresses-fail-DAD-rh2132281.patch
deleted file mode 100644
index 527c439..0000000
--- a/SOURCES/1003-dhcp-decline-IPv6-lease-if-all-adresses-fail-DAD-rh2132281.patch
+++ /dev/null
@@ -1,220 +0,0 @@
-From 67f7ee1e7a5c4cfc2d0b67c56a8655b3d9f4781d Mon Sep 17 00:00:00 2001
-From: Beniamino Galvani <bgalvani@redhat.com>
-Date: Thu, 1 Sep 2022 10:21:20 +0200
-Subject: [PATCH] dhcp: decline IPv6 lease if all adresses fail DAD
-
-Currently we accept the DHCPv6 just after addresses are configured on
-kernel, without waiting DAD result. Instead, wait that DAD completes
-and decline the lease if all addresses are detected as duplicate.
-
-Note that when an address has non-infinite lifetime and fails DAD,
-kernel removes it automatically. With iproute2 we see something like:
-
-602: testX6    inet6 2620::1234:5678/128 scope global tentative dynamic noprefixroute
-       valid_lft 7500sec preferred_lft 7200sec
-Deleted 602: testX6    inet6 2620::1234:5678/128 scope global dadfailed tentative dynamic noprefixroute
-       valid_lft 7500sec preferred_lft 7200sec
-
-Since the address gets removed from the platform cache, at the moment
-we don't have a way to check the flags of the removal
-message. Therefore, we assume that any address that goes away in
-tentative state was detected as duplicate.
-
-https://bugzilla.redhat.com/show_bug.cgi?id=2096386
-(cherry picked from commit a7eb77260ae6cfc56313e99f6178daa0b8283226)
-(cherry picked from commit b671c36189bcddef058bcdce6c9bfeaddeb6c340)
----
- src/core/dhcp/nm-dhcp-client.c | 128 +++++++++++++++++++++++----------
- 1 file changed, 92 insertions(+), 36 deletions(-)
-
-diff --git a/src/core/dhcp/nm-dhcp-client.c b/src/core/dhcp/nm-dhcp-client.c
-index 77cfeecf81..a22fe65b6d 100644
---- a/src/core/dhcp/nm-dhcp-client.c
-+++ b/src/core/dhcp/nm-dhcp-client.c
-@@ -1043,8 +1043,11 @@ ipv6_lladdr_find(NMDhcpClient *self)
-     return NULL;
- }
- 
--static const NMPlatformIP6Address *
--ipv6_tentative_addr_find(NMDhcpClient *self)
-+static void
-+ipv6_tentative_addr_check(NMDhcpClient                *self,
-+                          GPtrArray                  **tentative,
-+                          GPtrArray                  **missing,
-+                          const NMPlatformIP6Address **valid)
- {
-     NMDhcpClientPrivate        *priv = NM_DHCP_CLIENT_GET_PRIVATE(self);
-     NMDedupMultiIter            iter;
-@@ -1062,16 +1065,26 @@ ipv6_tentative_addr_find(NMDhcpClient *self)
-                                                                     NMP_CACHE_ID_TYPE_OBJECT_TYPE,
-                                                                     &needle));
-         if (!pladdr) {
--            /* Address was removed from platform */
-+            /* address removed: we assume that's because DAD failed */
-+            if (missing) {
-+                if (!*missing)
-+                    *missing = g_ptr_array_new();
-+                g_ptr_array_add(*missing, (gpointer) addr);
-+            }
-             continue;
-         }
- 
-         if (NM_FLAGS_HAS(pladdr->n_ifa_flags, IFA_F_TENTATIVE)
--            && !NM_FLAGS_HAS(pladdr->n_ifa_flags, IFA_F_OPTIMISTIC))
--            return pladdr;
--    }
-+            && !NM_FLAGS_HAS(pladdr->n_ifa_flags, IFA_F_OPTIMISTIC)) {
-+            if (tentative) {
-+                if (!*tentative)
-+                    *tentative = g_ptr_array_new();
-+                g_ptr_array_add(*tentative, (gpointer) addr);
-+            }
-+        }
- 
--    return NULL;
-+        NM_SET_OUT(valid, addr);
-+    }
- }
- 
- static void
-@@ -1108,21 +1121,61 @@ l3_cfg_notify_cb(NML3Cfg *l3cfg, const NML3ConfigNotifyData *notify_data, NMDhcp
- 
-     if (notify_data->notify_type == NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE_ON_IDLE
-         && priv->l3cfg_notify.wait_ipv6_dad) {
--        const NMPlatformIP6Address *tentative;
-+        gs_unref_ptrarray GPtrArray *tentative = NULL;
-+        gs_unref_ptrarray GPtrArray *missing   = NULL;
-+        const NMPlatformIP6Address  *valid     = NULL;
-+        char                         str[NM_UTILS_TO_STRING_BUFFER_SIZE];
-+        guint                        i;
-+        gs_free_error GError        *error = NULL;
-+
-+        ipv6_tentative_addr_check(self, &tentative, &missing, &valid);
-+        if (tentative) {
-+            for (i = 0; i < tentative->len; i++) {
-+                _LOGD("still waiting DAD for address: %s",
-+                      nm_platform_ip6_address_to_string(tentative->pdata[i], str, sizeof(str)));
-+            }
-+        } else {
-+            /* done */
- 
--        tentative = ipv6_tentative_addr_find(self);
--        if (!tentative) {
--            _LOGD("addresses in the lease completed DAD");
-             priv->l3cfg_notify.wait_ipv6_dad = FALSE;
-             nm_clear_g_source_inst(&priv->v6.dad_timeout_source);
-             l3_cfg_notify_check_connected(self);
--            _emit_notify(
--                self,
--                &((NMDhcpClientNotifyData){.notify_type  = NM_DHCP_CLIENT_NOTIFY_TYPE_LEASE_UPDATE,
--                                           .lease_update = {
--                                               .l3cd     = priv->l3cd_curr,
--                                               .accepted = TRUE,
--                                           }}));
-+
-+            if (missing) {
-+                for (i = 0; i < missing->len; i++) {
-+                    _LOGE("DAD failed for address: %s",
-+                          nm_platform_ip6_address_to_string(missing->pdata[i], str, sizeof(str)));
-+                }
-+            }
-+
-+            if (valid) {
-+                /* at least one non-duplicate address */
-+                _LOGD("addresses in the lease completed DAD: accept the lease");
-+
-+                if (_dhcp_client_accept(self, priv->l3cd_curr, &error)) {
-+                    _emit_notify(self,
-+                                 &((NMDhcpClientNotifyData){
-+                                     .notify_type  = NM_DHCP_CLIENT_NOTIFY_TYPE_LEASE_UPDATE,
-+                                     .lease_update = {
-+                                         .l3cd     = priv->l3cd_curr,
-+                                         .accepted = TRUE,
-+                                     }}));
-+                } else {
-+                    gs_free char *reason =
-+                        g_strdup_printf("error accepting lease: %s", error->message);
-+
-+                    _LOGD("accept failed: %s", error->message);
-+                    _emit_notify(self,
-+                                 &((NMDhcpClientNotifyData){
-+                                     .notify_type         = NM_DHCP_CLIENT_NOTIFY_TYPE_IT_LOOKS_BAD,
-+                                     .it_looks_bad.reason = reason,
-+                                 }));
-+                }
-+            } else {
-+                _LOGD("decline the lease");
-+                if (!_dhcp_client_decline(self, priv->l3cd_curr, "DAD failed", &error))
-+                    _LOGD("decline failed: %s", error->message);
-+            }
-         }
-     }
- 
-@@ -1155,20 +1208,23 @@ l3_cfg_notify_cb(NML3Cfg *l3cfg, const NML3ConfigNotifyData *notify_data, NMDhcp
-                                                     address4->peer_address))
-                 goto wait_dhcp_commit_done;
-         } else {
--            const NMPlatformIP6Address *address6 = (const NMPlatformIP6Address *) lease_address;
--            const NMPlatformIP6Address *tentative;
--            char                        str[NM_UTILS_TO_STRING_BUFFER_SIZE];
-+            const NMPlatformIP6Address  *address6  = (const NMPlatformIP6Address *) lease_address;
-+            gs_unref_ptrarray GPtrArray *tentative = NULL;
-+            char                         str[NM_UTILS_TO_STRING_BUFFER_SIZE];
-+            guint                        i;
- 
-             if (!nm_l3_config_data_lookup_address_6(committed_l3cd, &address6->address))
-                 goto wait_dhcp_commit_done;
- 
--            tentative = ipv6_tentative_addr_find(self);
-+            ipv6_tentative_addr_check(self, &tentative, NULL, NULL);
-             if (tentative) {
-                 priv->l3cfg_notify.wait_ipv6_dad = TRUE;
-                 priv->v6.dad_timeout_source =
-                     nm_g_timeout_add_seconds_source(30, ipv6_dad_timeout, self);
--                _LOGD("wait DAD for address %s",
--                      nm_platform_ip6_address_to_string(tentative, str, sizeof(str)));
-+                for (i = 0; i < tentative->len; i++) {
-+                    _LOGD("wait DAD for address %s",
-+                          nm_platform_ip6_address_to_string(tentative->pdata[i], str, sizeof(str)));
-+                }
-             } else {
-                 priv->l3cfg_notify.wait_ipv6_dad = FALSE;
-                 nm_clear_g_source_inst(&priv->v6.dad_timeout_source);
-@@ -1179,22 +1235,22 @@ l3_cfg_notify_cb(NML3Cfg *l3cfg, const NML3ConfigNotifyData *notify_data, NMDhcp
- 
-         l3_cfg_notify_check_connected(self);
- 
--        _LOGD("accept lease");
-+        if (priv->config.addr_family == AF_INET || !priv->l3cfg_notify.wait_ipv6_dad) {
-+            _LOGD("accept lease");
- 
--        if (!_dhcp_client_accept(self, priv->l3cd_curr, &error)) {
--            gs_free char *reason = g_strdup_printf("error accepting lease: %s", error->message);
-+            if (!_dhcp_client_accept(self, priv->l3cd_curr, &error)) {
-+                gs_free char *reason = g_strdup_printf("error accepting lease: %s", error->message);
- 
--            _LOGD("accept failed: %s", error->message);
-+                _LOGD("accept failed: %s", error->message);
- 
--            _emit_notify(self,
--                         &((NMDhcpClientNotifyData){
--                             .notify_type         = NM_DHCP_CLIENT_NOTIFY_TYPE_IT_LOOKS_BAD,
--                             .it_looks_bad.reason = reason,
--                         }));
--            goto wait_dhcp_commit_done;
--        }
-+                _emit_notify(self,
-+                             &((NMDhcpClientNotifyData){
-+                                 .notify_type         = NM_DHCP_CLIENT_NOTIFY_TYPE_IT_LOOKS_BAD,
-+                                 .it_looks_bad.reason = reason,
-+                             }));
-+                goto wait_dhcp_commit_done;
-+            }
- 
--        if (priv->config.addr_family == AF_INET || !priv->l3cfg_notify.wait_ipv6_dad) {
-             _emit_notify(
-                 self,
-                 &((NMDhcpClientNotifyData){.notify_type  = NM_DHCP_CLIENT_NOTIFY_TYPE_LEASE_UPDATE,
--- 
-2.38.1
-
diff --git a/SOURCES/1004-ovs-wait-that-links-disappear-during-initial-cleanup-rh2153429.patch b/SOURCES/1004-ovs-wait-that-links-disappear-during-initial-cleanup-rh2153429.patch
deleted file mode 100644
index 3a13c4b..0000000
--- a/SOURCES/1004-ovs-wait-that-links-disappear-during-initial-cleanup-rh2153429.patch
+++ /dev/null
@@ -1,287 +0,0 @@
-From bfb21252e6e72f214f1f3bd6e76e210207692c88 Mon Sep 17 00:00:00 2001
-From: Beniamino Galvani <bgalvani@redhat.com>
-Date: Tue, 20 Sep 2022 14:05:42 +0200
-Subject: [PATCH] ovs: wait that links disappear during initial cleanup
-
-At startup, we remove from ovsdb any existing interface created by NM
-and later an interface with the same name might be readded. This can
-cause race conditions. Consider this series of events:
-
-1. at startup NM removes the entry from ovsdb;
-2. ovsdb reports success;
-3. NM inserts an interface with the same name again;
-4. ovs-vswitch monitors ovsdb changes, and gets events for removal and
-   insertion. Depending on how those events are split in different
-   batches, it might decide:
-   4a. to delete the link and add it back, or
-   4b. to keep the existing link because the delete and insertion
-       cancel out each other.
-
-When NM sees the link staying in platform, it doesn't know if it's
-because of 4b or because 4a will happen eventually.
-
-To avoid this ambiguity, after ovsdb reports the successful deletion
-NM should also wait that the link disappears from platform.
-
-Unfortunately, this means that ovsdb gets a dependency to the platform
-code.
-
-https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1386
-(cherry picked from commit 4f60fe293cd5461c47d218b632753ecdfb50cbab)
-(cherry picked from commit f702be2992f0f34c82e96b420947f9056a4cb24e)
----
- src/core/devices/ovs/nm-ovsdb.c | 155 +++++++++++++++++++++++++++-----
- 1 file changed, 132 insertions(+), 23 deletions(-)
-
-diff --git a/src/core/devices/ovs/nm-ovsdb.c b/src/core/devices/ovs/nm-ovsdb.c
-index e7c9685240..d3e858a19c 100644
---- a/src/core/devices/ovs/nm-ovsdb.c
-+++ b/src/core/devices/ovs/nm-ovsdb.c
-@@ -18,6 +18,7 @@
- #include "nm-manager.h"
- #include "nm-setting-ovs-external-ids.h"
- #include "nm-priv-helper-call.h"
-+#include "libnm-platform/nm-platform.h"
- 
- /*****************************************************************************/
- 
-@@ -120,6 +121,7 @@ enum {
- static guint signals[LAST_SIGNAL] = {0};
- 
- typedef struct {
-+    NMPlatform        *platform;
-     GSocketConnection *conn;
-     GCancellable      *conn_cancellable;
-     char               buf[4096]; /* Input buffer */
-@@ -135,8 +137,14 @@ typedef struct {
-     GHashTable *bridges;    /* bridge uuid => OpenvswitchBridge */
-     char       *db_uuid;
-     guint       num_failures;
--    guint       num_pending_deletions;
-     bool        ready : 1;
-+    struct {
-+        GPtrArray *interfaces;      /* Interface names we are waiting to go away */
-+        GSource   *timeout_source;  /* After all deletions complete, wait this
-+                                    * timeout for interfaces to disappear */
-+        gulong     link_changed_id; /* Platform link-changed signal handle */
-+        guint      num_pending_del; /* Number of ovsdb deletions pending */
-+    } cleanup;
- } NMOvsdbPrivate;
- 
- struct _NMOvsdb {
-@@ -161,6 +169,7 @@ static void ovsdb_disconnect(NMOvsdb *self, gboolean retry, gboolean is_disposin
- static void ovsdb_read(NMOvsdb *self);
- static void ovsdb_write(NMOvsdb *self);
- static void ovsdb_next_command(NMOvsdb *self);
-+static void cleanup_check_ready(NMOvsdb *self);
- 
- /*****************************************************************************/
- 
-@@ -2283,21 +2292,114 @@ ovsdb_disconnect(NMOvsdb *self, gboolean retry, gboolean is_disposing)
- }
- 
- static void
--_check_ready(NMOvsdb *self)
-+cleanup_emit_ready(NMOvsdb *self, const char *reason)
-+{
-+    NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE(self);
-+
-+    _LOGT("cleanup: ready (%s)", reason);
-+
-+    nm_clear_pointer(&priv->cleanup.interfaces, g_ptr_array_unref);
-+    nm_clear_g_source_inst(&priv->cleanup.timeout_source);
-+    nm_clear_g_signal_handler(priv->platform, &priv->cleanup.link_changed_id);
-+
-+    priv->ready = TRUE;
-+    g_signal_emit(self, signals[READY], 0);
-+    nm_manager_unblock_failed_ovs_interfaces(nm_manager_get());
-+}
-+
-+static gboolean
-+cleanup_timeout(NMOvsdb *self)
-+{
-+    cleanup_emit_ready(self, "timeout");
-+    return G_SOURCE_CONTINUE;
-+}
-+
-+static void
-+cleanup_link_cb(NMPlatform     *platform,
-+                int             obj_type_i,
-+                int             ifindex,
-+                NMPlatformLink *plink,
-+                int             change_type_i,
-+                gpointer        user_data)
-+{
-+    const NMPlatformSignalChangeType change_type = change_type_i;
-+
-+    if (change_type != NM_PLATFORM_SIGNAL_REMOVED)
-+        return;
-+
-+    cleanup_check_ready(user_data);
-+}
-+
-+static void
-+cleanup_check_ready(NMOvsdb *self)
- {
-     NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE(self);
-+    guint           i    = 0;
- 
-     nm_assert(!priv->ready);
- 
--    if (priv->num_pending_deletions == 0) {
--        priv->ready = TRUE;
--        g_signal_emit(self, signals[READY], 0);
--        nm_manager_unblock_failed_ovs_interfaces(nm_manager_get());
-+    if (priv->cleanup.num_pending_del > 0)
-+        return;
-+
-+    /* After we have deleted an interface from ovsdb, the link will stay
-+     * in platform until ovs-vswitch removes it. To avoid race conditions,
-+     * we need to wait until the link goes away; otherwise, after adding the
-+     * interface again, these race conditions can happen:
-+     * 1) we see the link in platform, and proceed with activation. But after
-+     *    that, ovs-vswitchd reads the updates from ovsdb-server and deletes/recreates
-+     *    the link.
-+     * 2) ovs-vswitch combines the delete/insert of the interface to a no-op. NM sees
-+     *    the link staying in platform, but doesn't know whether the link is ready
-+     *    or we are again in case 1)
-+     * In other words, it's necessary to wait that the link goes away before inserting
-+     * the interface again.
-+     */
-+    while (i < nm_g_ptr_array_len(priv->cleanup.interfaces)) {
-+        const char                  *ifname;
-+        const NMDedupMultiHeadEntry *pl_links_head_entry;
-+        NMDedupMultiIter             pliter;
-+        const NMPlatformLink        *link;
-+        gboolean                     found = FALSE;
-+
-+        ifname              = priv->cleanup.interfaces->pdata[i];
-+        pl_links_head_entry = nm_platform_lookup_link_by_ifname(priv->platform, ifname);
-+        nmp_cache_iter_for_each_link (&pliter, pl_links_head_entry, &link) {
-+            if (link->type == NM_LINK_TYPE_OPENVSWITCH
-+                && nmp_object_is_visible(NMP_OBJECT_UP_CAST(link))) {
-+                found = TRUE;
-+                break;
-+            }
-+        }
-+
-+        if (!found) {
-+            g_ptr_array_remove_index_fast(priv->cleanup.interfaces, i);
-+            continue;
-+        }
-+        i++;
-     }
-+
-+    if (nm_g_ptr_array_len(priv->cleanup.interfaces) == 0) {
-+        cleanup_emit_ready(self, "all interfaces deleted");
-+        return;
-+    }
-+
-+    _LOGT("cleanup: still waiting for %d interfaces", priv->cleanup.interfaces->len);
-+
-+    if (priv->cleanup.timeout_source) {
-+        /* We already registered the timeout/change-callback */
-+        return;
-+    }
-+
-+    priv->cleanup.timeout_source =
-+        nm_g_timeout_add_seconds_source(6, G_SOURCE_FUNC(cleanup_timeout), self);
-+    priv->cleanup.link_changed_id = g_signal_connect(priv->platform,
-+                                                     NM_PLATFORM_SIGNAL_LINK_CHANGED,
-+                                                     G_CALLBACK(cleanup_link_cb),
-+                                                     self);
- }
- 
- static void
--_del_initial_iface_cb(GError *error, gpointer user_data)
-+cleanup_del_iface_cb(GError *error, gpointer user_data)
- {
-     NMOvsdb        *self;
-     gs_free char   *ifname = NULL;
-@@ -2309,18 +2411,18 @@ _del_initial_iface_cb(GError *error, gpointer user_data)
-         return;
- 
-     priv = NM_OVSDB_GET_PRIVATE(self);
--    nm_assert(priv->num_pending_deletions > 0);
--    priv->num_pending_deletions--;
-+    nm_assert(priv->cleanup.num_pending_del > 0);
-+    priv->cleanup.num_pending_del--;
- 
--    _LOGD("delete initial interface '%s': %s %s%s%s, pending %u",
-+    _LOGD("cleanup: deleted interface '%s': %s %s%s%s, pending %u",
-           ifname,
-           error ? "error" : "success",
-           error ? "(" : "",
-           error ? error->message : "",
-           error ? ")" : "",
--          priv->num_pending_deletions);
-+          priv->cleanup.num_pending_del);
- 
--    _check_ready(self);
-+    cleanup_check_ready(self);
- }
- 
- static void
-@@ -2331,7 +2433,7 @@ ovsdb_cleanup_initial_interfaces(NMOvsdb *self)
-     NMUtilsUserData            *data;
-     GHashTableIter              iter;
- 
--    if (priv->ready || priv->num_pending_deletions != 0)
-+    if (priv->ready || priv->cleanup.num_pending_del > 0 || priv->cleanup.interfaces)
-         return;
- 
-     /* Delete OVS interfaces added by NM. Bridges and ports and
-@@ -2339,17 +2441,22 @@ ovsdb_cleanup_initial_interfaces(NMOvsdb *self)
-      * when no interface is present. */
-     g_hash_table_iter_init(&iter, self->_priv.interfaces);
-     while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &interface)) {
--        if (interface->connection_uuid) {
--            priv->num_pending_deletions++;
--            _LOGD("deleting initial interface '%s' (pending: %u)",
--                  interface->name,
--                  priv->num_pending_deletions);
--            data = nm_utils_user_data_pack(self, g_strdup(interface->name));
--            nm_ovsdb_del_interface(self, interface->name, _del_initial_iface_cb, data);
-+        if (!interface->connection_uuid) {
-+            /* not created by NM, ignore */
-+            continue;
-         }
-+
-+        if (!priv->cleanup.interfaces)
-+            priv->cleanup.interfaces = g_ptr_array_new_with_free_func(g_free);
-+        g_ptr_array_add(priv->cleanup.interfaces, g_strdup(interface->name));
-+
-+        _LOGD("cleanup: deleting interface '%s'", interface->name);
-+        priv->cleanup.num_pending_del++;
-+        data = nm_utils_user_data_pack(self, g_strdup(interface->name));
-+        nm_ovsdb_del_interface(self, interface->name, cleanup_del_iface_cb, data);
-     }
- 
--    _check_ready(self);
-+    cleanup_check_ready(self);
- }
- 
- static void
-@@ -2622,8 +2729,9 @@ nm_ovsdb_init(NMOvsdb *self)
- 
-     c_list_init(&priv->calls_lst_head);
- 
--    priv->input  = g_string_new(NULL);
--    priv->output = g_string_new(NULL);
-+    priv->platform = g_object_ref(NM_PLATFORM_GET);
-+    priv->input    = g_string_new(NULL);
-+    priv->output   = g_string_new(NULL);
-     priv->bridges =
-         g_hash_table_new_full(nm_pstr_hash, nm_pstr_equal, (GDestroyNotify) _free_bridge, NULL);
-     priv->ports =
-@@ -2653,6 +2761,7 @@ dispose(GObject *object)
-         priv->output = NULL;
-     }
- 
-+    g_clear_object(&priv->platform);
-     nm_clear_pointer(&priv->bridges, g_hash_table_destroy);
-     nm_clear_pointer(&priv->ports, g_hash_table_destroy);
-     nm_clear_pointer(&priv->interfaces, g_hash_table_destroy);
--- 
-2.38.1
-
diff --git a/SOURCES/1005-core-wait-for-carrier-before-resolving-hostname-via-rh2152891.patch b/SOURCES/1005-core-wait-for-carrier-before-resolving-hostname-via-rh2152891.patch
deleted file mode 100644
index cdd64d6..0000000
--- a/SOURCES/1005-core-wait-for-carrier-before-resolving-hostname-via-rh2152891.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From 43c39b1e1ef66f2ecf970086fdd05ce9b0c7fedf Mon Sep 17 00:00:00 2001
-From: Beniamino Galvani <bgalvani@redhat.com>
-Date: Wed, 7 Sep 2022 16:50:02 +0200
-Subject: [PATCH] core: wait for carrier before resolving hostname via DNS
-
-If there is no carrier on a device, don't try to resolve the hostname
-on it. Instead, subscribe to carrier change notifications and retry
-again once carrier goes up.
-
-https://bugzilla.redhat.com/show_bug.cgi?id=2118817
-https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1402
-(cherry picked from commit e3cf5083fba8dd1a3a1df69069de2f7e7411dd5e)
-(cherry picked from commit 1673e3f0518cff15dd19f871baecdf64bef48bc7)
----
- src/core/devices/nm-device.c |  7 +++++++
- src/core/nm-policy.c         | 29 ++++++++++++++++++++++++++---
- 2 files changed, 33 insertions(+), 3 deletions(-)
-
-diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
-index 7585acf4d3..461f57b5c1 100644
---- a/src/core/devices/nm-device.c
-+++ b/src/core/devices/nm-device.c
-@@ -17158,6 +17158,13 @@ nm_device_get_hostname_from_dns_lookup(NMDevice *self, int addr_family, gboolean
-     /* If the device is not supposed to have addresses,
-      * return an immediate empty result.*/
-     if (!nm_device_get_applied_connection(self)) {
-+        nm_clear_pointer(&priv->hostname_resolver_x[IS_IPv4], _hostname_resolver_free);
-+        NM_SET_OUT(out_wait, FALSE);
-+        return NULL;
-+    }
-+
-+    if (!priv->carrier) {
-+        nm_clear_pointer(&priv->hostname_resolver_x[IS_IPv4], _hostname_resolver_free);
-         NM_SET_OUT(out_wait, FALSE);
-         return NULL;
-     }
-diff --git a/src/core/nm-policy.c b/src/core/nm-policy.c
-index 16b0211fa2..c24b484f30 100644
---- a/src/core/nm-policy.c
-+++ b/src/core/nm-policy.c
-@@ -796,6 +796,20 @@ device_dns_lookup_done(NMDevice *device, gpointer user_data)
-     update_system_hostname(self, "lookup finished");
- }
- 
-+static void
-+device_carrier_changed(NMDevice *device, GParamSpec *pspec, gpointer user_data)
-+{
-+    NMPolicyPrivate *priv = user_data;
-+    NMPolicy        *self = _PRIV_TO_SELF(priv);
-+    gs_free char    *msg  = NULL;
-+
-+    if (nm_device_has_carrier(device)) {
-+        g_signal_handlers_disconnect_by_func(device, device_carrier_changed, priv);
-+        msg = g_strdup_printf("device '%s' got carrier", nm_device_get_iface(device));
-+        update_system_hostname(self, msg);
-+    }
-+}
-+
- static void
- update_system_hostname(NMPolicy *self, const char *msg)
- {
-@@ -880,6 +894,7 @@ update_system_hostname(NMPolicy *self, const char *msg)
-         info        = &g_array_index(infos, DeviceHostnameInfo, i);
-         addr_family = info->IS_IPv4 ? AF_INET : AF_INET6;
-         g_signal_handlers_disconnect_by_func(info->device, device_dns_lookup_done, self);
-+        g_signal_handlers_disconnect_by_func(info->device, device_carrier_changed, priv);
- 
-         if (info->from_dhcp) {
-             dhcp_config = nm_device_get_dhcp_config(info->device, addr_family);
-@@ -905,10 +920,18 @@ update_system_hostname(NMPolicy *self, const char *msg)
- 
-         if (priv->hostname_mode != NM_POLICY_HOSTNAME_MODE_DHCP) {
-             if (info->from_dns) {
--                const char *result;
--                gboolean    wait = FALSE;
-+                const char *result = NULL;
-+                gboolean    wait   = FALSE;
- 
--                result = nm_device_get_hostname_from_dns_lookup(info->device, addr_family, &wait);
-+                if (nm_device_has_carrier(info->device)) {
-+                    result =
-+                        nm_device_get_hostname_from_dns_lookup(info->device, addr_family, &wait);
-+                } else {
-+                    g_signal_connect(info->device,
-+                                     "notify::" NM_DEVICE_CARRIER,
-+                                     G_CALLBACK(device_carrier_changed),
-+                                     priv);
-+                }
-                 if (result) {
-                     _set_hostname(self, result, "from address lookup");
-                     return;
--- 
-2.38.1
-
diff --git a/SOURCES/1006-skip-DNS-resolution-for-tentative-IPv6-address-rh2166711.patch b/SOURCES/1006-skip-DNS-resolution-for-tentative-IPv6-address-rh2166711.patch
deleted file mode 100644
index 65a3a61..0000000
--- a/SOURCES/1006-skip-DNS-resolution-for-tentative-IPv6-address-rh2166711.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 413b140ae639d38ffcc125dfc1ef7303f08abebd Mon Sep 17 00:00:00 2001
-From: Beniamino Galvani <bgalvani@redhat.com>
-Date: Tue, 14 Feb 2023 11:39:07 +0100
-Subject: [PATCH] device: skip DNS resolution for tentative IPv6 addresses
-
-A tentative IPv6 address can still fail DAD, so don't use it to
-resolve the hostname via DNS. Furthermore, tentative addresses can't
-be used to contact the nameserver and so the resolution will fail if
-there is no other valid IPv6 address. Wait that the address becomes
-non-tentative.
-
-(cherry picked from commit 4138be6a5a508af66b3b79c0eaeb43e3437ee345)
-(cherry picked from commit 0ebd75381963abc2fb75d39ab44367139db0e34b)
-(cherry picked from commit 26d5ad46806a2dc69238116796be0fbb2b7c273f)
----
- src/core/devices/nm-device.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
-index 461f57b5c1..9af4bf8988 100644
---- a/src/core/devices/nm-device.c
-+++ b/src/core/devices/nm-device.c
-@@ -17117,6 +17117,9 @@ get_address_for_hostname_dns_lookup(NMDevice *self, int addr_family)
-                 return g_inet_address_new_from_bytes(addr->address_ptr, G_SOCKET_FAMILY_IPV4);
-             }
- 
-+            if (addr->n_ifa_flags & IFA_F_TENTATIVE)
-+                continue;
-+
-             /* For IPv6 prefer, in order:
-              * - !link-local, !deprecated
-              * - !link-local, deprecated
--- 
-2.39.1
-
diff --git a/SPECS/NetworkManager.spec b/SPECS/NetworkManager.spec
index 92f214b..de56a7d 100644
--- a/SPECS/NetworkManager.spec
+++ b/SPECS/NetworkManager.spec
@@ -4,9 +4,9 @@
 %global glib2_version %(pkg-config --modversion glib-2.0 2>/dev/null || echo bad)
 
 %global epoch_version 1
-%global real_version 1.40.0
+%global real_version 1.40.16
 %global rpm_version %{real_version}
-%global release_version 6
+%global release_version 1
 %global snapshot %{nil}
 %global git_sha %{nil}
 %global bcond_default_debug 0
@@ -195,12 +195,7 @@ Patch2: 0002-firewall-Default-to-iptables-backend-to-preserve-behavior.patch
 Patch3: 0003-order-ipv6-addresses.patch
 
 # Bugfixes that are only relevant until next rebase of the package.
-Patch1001: 1001-revert-restart-DHCP-when-MAC-changes-rh2124443.patch
-Patch1002: 1002-dns-sort-according-to-priority-rh2134563.patch
-Patch1003: 1003-dhcp-decline-IPv6-lease-if-all-adresses-fail-DAD-rh2132281.patch
-Patch1004: 1004-ovs-wait-that-links-disappear-during-initial-cleanup-rh2153429.patch
-Patch1005: 1005-core-wait-for-carrier-before-resolving-hostname-via-rh2152891.patch
-Patch1006: 1006-skip-DNS-resolution-for-tentative-IPv6-address-rh2166711.patch
+# Patch1001: 1001-some.patch
 
 Requires(post): systemd
 %if 0%{?fedora} || 0%{?rhel} >= 8
@@ -1236,21 +1231,46 @@ fi
 
 
 %changelog
-* Wed Mar  1 2023 Beniamino Galvani <bgalvani@redhat.com> - 1:1.40.0-6
-- Fix hostname resolution from tentative IPv6 addresses (rh #2166711)
-
-* Fri Dec 16 2022 Fernando Fernandez Mancera <ferferna@redhat.com> - 1:1.40.0-5
-- ovs: wait that links disappear during initial cleanup (rh #2153429)
-- core: wait for carrier before resolving hostname via DNS (rh #2152891)
-
-* Mon Nov 28 2022 Fernando Fernandez Mancera <ferferna@redhat.com> - 1:1.40.0-4
-- dhcp: decline IPv6 lease if all addresses fail DAD (rh #2132281)
-
-* Tue Nov  8 2022 Beniamino Galvani <bgalvani@redhat.com> - 1:1.40.0-3
-- dns: ensure that nameservers are sorted according to priority (rh #2134563)
-
-* Thu Oct 20 2022 Beniamino Galvani <bgalvani@redhat.com> - 1:1.40.0-2
-- Don't restart DHCP when MAC changes, to avoid that the IP changes (rh #2124443)
+* Thu Feb 23 2023 Beniamino Galvani <bgalvani@redhat.com> - 1:1.40.16-1
+- Update to 1.40.16 release
+
+* Mon Feb 13 2023 Thomas Haller <thaller@redhat.com> - 1:1.40.14-1
+- Update to 1.40.14 release
+
+* Thu Jan 26 2023 Lubomir Rintel <lkundrak@v3.sk> - 1:1.40.12-1
+- Update to 1.40.12 release
+- core: retry if a rtnetlink socket runs out of buffer space (rh #2154350)
+
+* Wed Jan 11 2023 Beniamino Galvani <bgalvani@redhat.com> - 1:1.40.10-1
+- Update to 1.40.10 release
+- cloud-setup: preserve addresses added externally (rh #2132754)
+- veth: fix detection of existing interface and peer (rh #2129829)
+- dns: ensure dnsmasq is stopped after disabling it and a restart (rh #2120763)
+
+* Wed Dec 21 2022 Thomas Haller <thaller@redhat.com> - 1:1.40.8-2
+- core: avoid infinite autoconnect with multi-connect profiles (rh #2155531)
+
+* Fri Dec 16 2022 Lubomir Rintel <lkundrak@v3.sk> - 1:1.40.8-1
+- Update to 1.40.8 release
+- macsec: fix tracking of parent ifindex (rh #2122564)
+
+* Wed Nov 30 2022 Thomas Haller <thaller@redhat.com> - 1:1.40.6-1
+- Update to 1.40.6 release
+- team: fix configuring empty team port settings (rh #2102375)
+
+* Fri Nov 18 2022 Thomas Haller <thaller@redhat.com> - 1:1.40.4-1
+- Update to 1.40.4 release
+- ifcfg-rh: fix writing invalid ethtool pause settings (rh #2134569)
+
+* Tue Oct 11 2022 Beniamino Galvani <bgalvani@redhat.com> - 1:1.40.2-1
+- Update to 1.40.2 release
+- core: fix persisting Infiniband partition connections (rh #2122703)
+- core: wait for carrier before resolving hostname via DNS (rh #2118817)
+- core: fix handling of autoconnect-retries with multiconnect (rh #2039734)
+- nmcli: allow removing a port connection from a bond (rh #2126262)
+- initrd: decrease autoconnect priority for initrd connections (rh #2089707)
+- dhcp: wait DAD completion for DHCPv6 addresses (send decline) (rh #2096386, rh #2099794)
+- ovs: wait that links disappear during initial cleanup (rh #2060031)
 
 * Fri Aug 26 2022 Ana Cabral <acabral@redhat.com> - 1:1.40.0-1
 - Update to 1.40.0 release
@@ -1430,7 +1450,7 @@ fi
 - Obtain permanent hardware address via netlink or lookup via ethtool (rh #1987286)
 - Show more information about routes in nmcli (rh #1870059)
 - Add test for creation and activation of new connection via interface (rh #1763054)
-- ethtool: fix setting autonegotiation/speed on reactivation (rh #1897004) 
+- ethtool: fix setting autonegotiation/speed on reactivation (rh #1897004)
 - Fix MTU's decrease after the removal of 802-3-ethernet configuration (rh #1973536)
 
 * Thu Aug 19 2021 Wen Liang <wenliang@redhat.com> - 1:1.32.10-2