import NetworkManager-1.40.0-5.el8_7
This commit is contained in:
parent
150055e042
commit
dd18beb5dd
69
SOURCES/1002-dns-sort-according-to-priority-rh2134563.patch
Normal file
69
SOURCES/1002-dns-sort-according-to-priority-rh2134563.patch
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
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
|
||||||
|
|
@ -0,0 +1,220 @@
|
|||||||
|
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
|
||||||
|
|
@ -0,0 +1,287 @@
|
|||||||
|
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
|
||||||
|
|
@ -0,0 +1,94 @@
|
|||||||
|
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
|
||||||
|
|
@ -6,7 +6,7 @@
|
|||||||
%global epoch_version 1
|
%global epoch_version 1
|
||||||
%global real_version 1.40.0
|
%global real_version 1.40.0
|
||||||
%global rpm_version %{real_version}
|
%global rpm_version %{real_version}
|
||||||
%global release_version 2
|
%global release_version 5
|
||||||
%global snapshot %{nil}
|
%global snapshot %{nil}
|
||||||
%global git_sha %{nil}
|
%global git_sha %{nil}
|
||||||
%global bcond_default_debug 0
|
%global bcond_default_debug 0
|
||||||
@ -196,6 +196,10 @@ Patch3: 0003-order-ipv6-addresses.patch
|
|||||||
|
|
||||||
# Bugfixes that are only relevant until next rebase of the package.
|
# Bugfixes that are only relevant until next rebase of the package.
|
||||||
Patch1001: 1001-revert-restart-DHCP-when-MAC-changes-rh2124443.patch
|
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
|
||||||
|
|
||||||
Requires(post): systemd
|
Requires(post): systemd
|
||||||
%if 0%{?fedora} || 0%{?rhel} >= 8
|
%if 0%{?fedora} || 0%{?rhel} >= 8
|
||||||
@ -1231,6 +1235,16 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* 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
|
* 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)
|
- Don't restart DHCP when MAC changes, to avoid that the IP changes (rh #2124443)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user