import NetworkManager-1.46.0-18.el9_4

i9 changed/i9/NetworkManager-1.46.0-18.el9_4.inferit
MSVSphere Packaging Team 4 months ago committed by tigro
parent 94004d8e88
commit 7478f9c917
Signed by: tigro
GPG Key ID: 1EC08A25C9DB2503

@ -0,0 +1,37 @@
From 567853b4299f529ff886bd86292f680cd3b651c6 Mon Sep 17 00:00:00 2001
From: Fernando Fernandez Mancera <ffmancera@riseup.net>
Date: Thu, 25 Jul 2024 10:20:14 +0200
Subject: [PATCH] ovs: wait for the link to be ready before activating
When activating an ovs-interface we already wait for the cloned MAC
address to be set, ifindex is present and platform link also present but
in some cases this is not enough.
If an udev rule is in place it might modify the interface when it is in
a later stage of the activation causing some race conditions or
problems. In order to solve that, we must wait until the link is fully
initialized.
(cherry picked from commit 83bf7a8cdb56154cee6ed53c1cc3046ed9db73b8)
(cherry picked from commit 00e178351beba50b9d4c877364c6b46cc182dfcd)
(cherry picked from commit 6328a1a0d1e4ae4f86c11b97a9ee54ec15fa233a)
---
src/core/devices/ovs/nm-device-ovs-interface.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/core/devices/ovs/nm-device-ovs-interface.c b/src/core/devices/ovs/nm-device-ovs-interface.c
index 17eb2c2d12..104b312674 100644
--- a/src/core/devices/ovs/nm-device-ovs-interface.c
+++ b/src/core/devices/ovs/nm-device-ovs-interface.c
@@ -155,6 +155,8 @@ check_waiting_for_link(NMDevice *device, const char *from)
reason = "no ifindex";
} else if (!(pllink = nm_platform_link_get(platform, ip_ifindex))) {
reason = "platform link not found";
+ } else if (!pllink->initialized) {
+ reason = "link is not ready yet";
} else if (priv->wait_link.cloned_mac
&& !nm_utils_hwaddr_matches(priv->wait_link.cloned_mac,
-1,
--
2.45.2

@ -0,0 +1,67 @@
From 0d744e4942d1a8bc7c600ddde82057bb8aa7c985 Mon Sep 17 00:00:00 2001
From: Fernando Fernandez Mancera <ffmancera@riseup.net>
Date: Wed, 31 Jul 2024 01:07:23 +0200
Subject: [PATCH] ovs: fix triggering stage3 activation without DHCP client
initialized
It is possible that we learn the link is ready on stage3_ip_config
rather than in link_changed event due to a stage3_ip_config scheduled by
another component. In such cases, we proceed with IP configuration
without allocating the resources needed like initializing DHCP client.
In order to avoid that, if we learn during stage3_ip_config that the
link is now ready, we need to schedule another stage3_ip_config to
allocate the resources we might need.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2004
Fixes: 83bf7a8cdb56 ('ovs: wait for the link to be ready before activating')
(cherry picked from commit 40d51b91048e01f3bdfe6df1e0de7184b1ac2715)
(cherry picked from commit 63dfd3b60b2764e652e18977b74de00b9a2a5d60)
(cherry picked from commit f8f5626f727517d2d0140e3dc46de449877e151f)
---
src/core/devices/ovs/nm-device-ovs-interface.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/src/core/devices/ovs/nm-device-ovs-interface.c b/src/core/devices/ovs/nm-device-ovs-interface.c
index 104b312674..a1efa5e96a 100644
--- a/src/core/devices/ovs/nm-device-ovs-interface.c
+++ b/src/core/devices/ovs/nm-device-ovs-interface.c
@@ -379,6 +379,7 @@ act_stage3_ip_config(NMDevice *device, int addr_family)
{
NMDeviceOvsInterface *self = NM_DEVICE_OVS_INTERFACE(device);
NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE(self);
+ bool old_wait_link;
/*
* When the ovs-interface device enters stage3, it becomes eligible to be attached to
@@ -432,6 +433,7 @@ act_stage3_ip_config(NMDevice *device, int addr_family)
priv->wait_link.cloned_mac_evaluated = TRUE;
}
+ old_wait_link = priv->wait_link.waiting;
priv->wait_link.waiting = TRUE;
if (check_waiting_for_link(device, addr_family == AF_INET ? "stage3-ipv4" : "stage3-ipv6")) {
nm_device_devip_set_state(device, addr_family, NM_DEVICE_IP_STATE_PENDING, NULL);
@@ -450,6 +452,18 @@ act_stage3_ip_config(NMDevice *device, int addr_family)
nm_utils_addr_family_to_char(addr_family));
priv->wait_link.waiting = FALSE;
+ /*
+ * It is possible we detect the link is ready before link_changed event does. It could happen
+ * because another stage3_ip_config scheduled happened right after the link is ready.
+ * Therefore, if we learn on this function that we are not waiting for the link anymore,
+ * we schedule a sync. stage3_ip_config. Otherwise, it could happen that we proceed with
+ * IP configuration without the needed allocated resources like DHCP client.
+ */
+ if (old_wait_link) {
+ nm_device_bring_up(device);
+ nm_device_activate_schedule_stage3_ip_config(device, TRUE);
+ return;
+ }
nm_clear_g_source_inst(&priv->wait_link.tun_set_ifindex_idle_source);
nm_clear_g_signal_handler(nm_device_get_platform(device), &priv->wait_link.tun_link_signal_id);
--
2.45.2

@ -0,0 +1,231 @@
From cf4f45af5cb23978123a991c191bf409bc237a9b Mon Sep 17 00:00:00 2001
From: Wen Liang <liangwen12year@gmail.com>
Date: Mon, 29 Jul 2024 14:42:05 -0400
Subject: [PATCH 1/1] policy: unblock the autoconnect for children when parent
is available
When parent is available and in the process of activation, we should
unblock the autoconnect and schedule an auto activate for the children.
Notice that when the parent is the ovs-interface, the kernel link is
only created in stage3, if we only unblock the children in the stage1,
then the children device and connection will be blocked again due
to the fact the kernel link for the parent ovs-interface is not
existed yet, thus, we have to separately unblock the children
when the parent ovs-interface is in the activated state.
https://issues.redhat.com/browse/RHEL-46904
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2003
https://gitlab.freedesktop.org/NetworkManager/NetworkManager-ci/-/merge_requests/1735
(cherry picked from commit 5f64f292e6a518098f874ba9ff876e413e38a3ca)
(cherry picked from commit 8243425c6d031c685518a74018cd39cd6c10a36b)
(cherry picked from commit 02db74ed0bc5ac8b3c942c2c4bc61a56258cc063)
---
src/core/nm-policy.c | 136 +++++++++++++++++++++++++++++++++++--------
1 file changed, 111 insertions(+), 25 deletions(-)
diff --git a/src/core/nm-policy.c b/src/core/nm-policy.c
index feea97b114..9777cf326f 100644
--- a/src/core/nm-policy.c
+++ b/src/core/nm-policy.c
@@ -17,6 +17,7 @@
#include "NetworkManagerUtils.h"
#include "devices/nm-device.h"
+#include "devices/nm-device-factory.h"
#include "dns/nm-dns-manager.h"
#include "nm-act-request.h"
#include "nm-auth-utils.h"
@@ -1773,6 +1774,74 @@ _connection_autoconnect_retries_set(NMPolicy *self,
}
}
+static void
+unblock_autoconnect_for_children(NMPolicy *self,
+ const char *parent_device,
+ const char *parent_uuid_settings,
+ const char *parent_uuid_applied,
+ const char *parent_mac_addr,
+ gboolean reset_devcon_autoconnect)
+{
+ NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self);
+ NMSettingsConnection *const *connections;
+ gboolean changed;
+ guint i;
+
+ _LOGT(LOGD_CORE,
+ "block-autoconnect: unblocking child profiles for parent ifname=%s%s%s, uuid=%s%s%s"
+ "%s%s%s",
+ NM_PRINT_FMT_QUOTE_STRING(parent_device),
+ NM_PRINT_FMT_QUOTE_STRING(parent_uuid_settings),
+ NM_PRINT_FMT_QUOTED(parent_uuid_applied,
+ ", applied-uuid=\"",
+ parent_uuid_applied,
+ "\"",
+ ""));
+
+ changed = FALSE;
+ connections = nm_settings_get_connections(priv->settings, NULL);
+ for (i = 0; connections[i]; i++) {
+ NMSettingsConnection *sett_conn = connections[i];
+ NMConnection *connection;
+ NMDeviceFactory *factory;
+ const char *parent_name = NULL;
+
+ connection = nm_settings_connection_get_connection(sett_conn);
+ factory = nm_device_factory_manager_find_factory_for_connection(connection);
+ if (factory)
+ parent_name = nm_device_factory_get_connection_parent(factory, connection);
+
+ if (!parent_name)
+ continue;
+
+ if (!NM_IN_STRSET(parent_name,
+ parent_device,
+ parent_uuid_applied,
+ parent_uuid_settings,
+ parent_mac_addr))
+ continue;
+
+ if (reset_devcon_autoconnect) {
+ if (nm_manager_devcon_autoconnect_retries_reset(priv->manager, NULL, sett_conn))
+ changed = TRUE;
+ }
+
+ /* unblock the devices associated with that connection */
+ if (nm_manager_devcon_autoconnect_blocked_reason_set(
+ priv->manager,
+ NULL,
+ sett_conn,
+ NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_FAILED,
+ FALSE)) {
+ if (!nm_settings_connection_autoconnect_is_blocked(sett_conn))
+ changed = TRUE;
+ }
+ }
+
+ if (changed)
+ nm_policy_device_recheck_auto_activate_all_schedule(self);
+}
+
static void
unblock_autoconnect_for_ports(NMPolicy *self,
const char *master_device,
@@ -1854,16 +1923,21 @@ unblock_autoconnect_for_ports_for_sett_conn(NMPolicy *self, NMSettingsConnection
}
static void
-activate_slave_connections(NMPolicy *self, NMDevice *device)
-{
- const char *master_device;
- const char *master_uuid_settings = NULL;
- const char *master_uuid_applied = NULL;
+activate_port_or_children_connections(NMPolicy *self,
+ NMDevice *device,
+ gboolean activate_children_connections_only)
+{
+ const char *controller_device;
+ const char *controller_uuid_settings = NULL;
+ const char *controller_uuid_applied = NULL;
+ const char *parent_mac_addr = NULL;
NMActRequest *req;
gboolean internal_activation = FALSE;
- master_device = nm_device_get_iface(device);
- nm_assert(master_device);
+ controller_device = nm_device_get_iface(device);
+ nm_assert(controller_device);
+
+ parent_mac_addr = nm_device_get_permanent_hw_address(device);
req = nm_device_get_act_request(device);
if (req) {
@@ -1873,25 +1947,33 @@ activate_slave_connections(NMPolicy *self, NMDevice *device)
sett_conn = nm_active_connection_get_settings_connection(NM_ACTIVE_CONNECTION(req));
if (sett_conn)
- master_uuid_settings = nm_settings_connection_get_uuid(sett_conn);
+ controller_uuid_settings = nm_settings_connection_get_uuid(sett_conn);
connection = nm_active_connection_get_applied_connection(NM_ACTIVE_CONNECTION(req));
if (connection)
- master_uuid_applied = nm_connection_get_uuid(connection);
+ controller_uuid_applied = nm_connection_get_uuid(connection);
- if (nm_streq0(master_uuid_settings, master_uuid_applied))
- master_uuid_applied = NULL;
+ if (nm_streq0(controller_uuid_settings, controller_uuid_applied))
+ controller_uuid_applied = NULL;
subject = nm_active_connection_get_subject(NM_ACTIVE_CONNECTION(req));
internal_activation =
subject && (nm_auth_subject_get_subject_type(subject) == NM_AUTH_SUBJECT_TYPE_INTERNAL);
}
- unblock_autoconnect_for_ports(self,
- master_device,
- master_uuid_settings,
- master_uuid_applied,
- !internal_activation);
+ if (!activate_children_connections_only) {
+ unblock_autoconnect_for_ports(self,
+ controller_device,
+ controller_uuid_settings,
+ controller_uuid_applied,
+ !internal_activation);
+ }
+ unblock_autoconnect_for_children(self,
+ controller_device,
+ controller_uuid_settings,
+ controller_uuid_applied,
+ parent_mac_addr,
+ !internal_activation);
}
static gboolean
@@ -2059,13 +2141,12 @@ device_state_changed(NMDevice *device,
}
break;
case NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED:
- /* A connection that fails due to dependency-failed is not
- * able to reconnect until the master connection activates
- * again; when this happens, the master clears the blocked
- * reason for all its slaves in activate_slave_connections()
- * and tries to reconnect them. For this to work, the slave
- * should be marked as blocked when it fails with
- * dependency-failed.
+ /* A connection that fails due to dependency-failed is not able to
+ * reconnect until the connection it depends on activates again;
+ * when this happens, the controller or parent clears the blocked
+ * reason for all its dependent devices in activate_port_or_children_connections()
+ * and tries to reconnect them. For this to work, the port should
+ * be marked as blocked when it fails with dependency-failed.
*/
_LOGD(LOGD_DEVICE,
"block-autoconnect: connection[%p] (%s) now blocked from autoconnect due to "
@@ -2109,6 +2190,11 @@ device_state_changed(NMDevice *device,
}
break;
case NM_DEVICE_STATE_ACTIVATED:
+ if (nm_device_get_device_type(device) == NM_DEVICE_TYPE_OVS_INTERFACE) {
+ /* When parent is ovs-interface, the kernel link is only created in stage3, we have to
+ * delay unblocking the children and schedule them for activation until parent is activated */
+ activate_port_or_children_connections(self, device, TRUE);
+ }
if (sett_conn) {
/* Reset auto retries back to default since connection was successful */
nm_manager_devcon_autoconnect_retries_reset(priv->manager, device, sett_conn);
@@ -2193,9 +2279,9 @@ device_state_changed(NMDevice *device,
break;
case NM_DEVICE_STATE_PREPARE:
- /* Reset auto-connect retries of all slaves and schedule them for
+ /* Reset auto-connect retries of all ports or children and schedule them for
* activation. */
- activate_slave_connections(self, device);
+ activate_port_or_children_connections(self, device, FALSE);
/* Now that the device state is progressing, we don't care
* anymore for the AC state. */
--
2.45.0

@ -0,0 +1,338 @@
From 0c55f0128ad17764fbe0862819fe43f32abfb27c Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Fri, 31 May 2024 10:34:28 +0200
Subject: [PATCH 1/2] lldp: fix crash dereferencing NULL pointer during debug
logging
During nm_lldp_neighbor_parse(), the NMLldpNeighbor is not yet added to
the NMLldpRX instance. Consequently, n->lldp_rx is NULL.
Note how we use lldp_x for logging, because we need it for the context
for which interface the logging statement is.
Thus, those debug logging statements will follow a NULL pointer and lead
to a crash.
Fixes: 630de288d2e4 ('lldp: add libnm-lldp as fork of systemd's sd_lldp_rx')
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/1550
(cherry picked from commit c2cddd3241349c0d5612d7603261c182fbc6d7c3)
(cherry picked from commit 8a2f7bd6e0572cc524e6bd6e4c2893e03f98a6f0)
(cherry picked from commit 6da9b98975ed790a9c00f57bd97e56c77ecb7673)
---
src/core/devices/nm-lldp-listener.c | 15 ++++++++-
src/libnm-lldp/nm-lldp-neighbor.c | 47 +++++++++++++++--------------
src/libnm-lldp/nm-lldp-neighbor.h | 4 ++-
src/libnm-lldp/nm-lldp-rx.c | 2 +-
src/libnm-lldp/nm-lldp-rx.h | 2 +-
5 files changed, 44 insertions(+), 26 deletions(-)
diff --git a/src/core/devices/nm-lldp-listener.c b/src/core/devices/nm-lldp-listener.c
index ac7e97f0c2..59c8f54c01 100644
--- a/src/core/devices/nm-lldp-listener.c
+++ b/src/core/devices/nm-lldp-listener.c
@@ -704,9 +704,16 @@ lldp_neighbor_to_variant(LldpNeighbor *neigh)
/*****************************************************************************/
+static void
+nmtst_lldp_event_handler(NMLldpRX *lldp, NMLldpRXEvent event, NMLldpNeighbor *n, void *user_data)
+{
+ g_assert_not_reached();
+}
+
GVariant *
nmtst_lldp_parse_from_raw(const guint8 *raw_data, gsize raw_len)
{
+ nm_auto(nm_lldp_rx_unrefp) NMLldpRX *lldp_rx = NULL;
nm_auto(nm_lldp_neighbor_unrefp) NMLldpNeighbor *neighbor_nm = NULL;
nm_auto(lldp_neighbor_freep) LldpNeighbor *neigh = NULL;
GVariant *variant;
@@ -714,7 +721,13 @@ nmtst_lldp_parse_from_raw(const guint8 *raw_data, gsize raw_len)
g_assert(raw_data);
g_assert(raw_len > 0);
- neighbor_nm = nm_lldp_neighbor_new_from_raw(raw_data, raw_len);
+ lldp_rx = nm_lldp_rx_new(&((NMLldpRXConfig){
+ .ifindex = 1,
+ .neighbors_max = MAX_NEIGHBORS,
+ .callback = nmtst_lldp_event_handler,
+ }));
+
+ neighbor_nm = nm_lldp_neighbor_new_from_raw(lldp_rx, raw_data, raw_len);
g_assert(neighbor_nm);
neigh = lldp_neighbor_new(neighbor_nm);
diff --git a/src/libnm-lldp/nm-lldp-neighbor.c b/src/libnm-lldp/nm-lldp-neighbor.c
index a2a9695e85..0880c02d98 100644
--- a/src/libnm-lldp/nm-lldp-neighbor.c
+++ b/src/libnm-lldp/nm-lldp-neighbor.c
@@ -65,6 +65,7 @@ parse_string(NMLldpRX *lldp_rx, char **s, const void *q, size_t n)
const char *p = q;
char *k;
+ nm_assert(lldp_rx);
nm_assert(s);
nm_assert(p || n == 0);
@@ -99,31 +100,33 @@ parse_string(NMLldpRX *lldp_rx, char **s, const void *q, size_t n)
}
int
-nm_lldp_neighbor_parse(NMLldpNeighbor *n)
+nm_lldp_neighbor_parse(NMLldpRX *lldp_rx, NMLldpNeighbor *n)
{
struct ether_header h;
const uint8_t *p;
size_t left;
int r;
+ nm_assert(lldp_rx);
nm_assert(n);
+ nm_assert(!n->lldp_rx);
if (n->raw_size < sizeof(struct ether_header)) {
- _LOG2D(n->lldp_rx, "Received truncated packet, ignoring.");
+ _LOG2D(lldp_rx, "Received truncated packet, ignoring.");
return -NME_UNSPEC;
}
memcpy(&h, NM_LLDP_NEIGHBOR_RAW(n), sizeof(h));
if (h.ether_type != htobe16(NM_ETHERTYPE_LLDP)) {
- _LOG2D(n->lldp_rx, "Received packet with wrong type, ignoring.");
+ _LOG2D(lldp_rx, "Received packet with wrong type, ignoring.");
return -NME_UNSPEC;
}
if (h.ether_dhost[0] != 0x01 || h.ether_dhost[1] != 0x80 || h.ether_dhost[2] != 0xc2
|| h.ether_dhost[3] != 0x00 || h.ether_dhost[4] != 0x00
|| !NM_IN_SET(h.ether_dhost[5], 0x00, 0x03, 0x0e)) {
- _LOG2D(n->lldp_rx, "Received packet with wrong destination address, ignoring.");
+ _LOG2D(lldp_rx, "Received packet with wrong destination address, ignoring.");
return -NME_UNSPEC;
}
@@ -138,7 +141,7 @@ nm_lldp_neighbor_parse(NMLldpNeighbor *n)
uint16_t length;
if (left < 2) {
- _LOG2D(n->lldp_rx, "TLV lacks header, ignoring.");
+ _LOG2D(lldp_rx, "TLV lacks header, ignoring.");
return -NME_UNSPEC;
}
@@ -147,14 +150,14 @@ nm_lldp_neighbor_parse(NMLldpNeighbor *n)
p += 2, left -= 2;
if (left < length) {
- _LOG2D(n->lldp_rx, "TLV truncated, ignoring datagram.");
+ _LOG2D(lldp_rx, "TLV truncated, ignoring datagram.");
return -NME_UNSPEC;
}
switch (type) {
case NM_LLDP_TYPE_END:
if (length != 0) {
- _LOG2D(n->lldp_rx, "End marker TLV not zero-sized, ignoring datagram.");
+ _LOG2D(lldp_rx, "End marker TLV not zero-sized, ignoring datagram.");
return -NME_UNSPEC;
}
@@ -166,12 +169,12 @@ nm_lldp_neighbor_parse(NMLldpNeighbor *n)
case NM_LLDP_TYPE_CHASSIS_ID:
if (length < 2 || length > 256) {
/* includes the chassis subtype, hence one extra byte */
- _LOG2D(n->lldp_rx, "Chassis ID field size out of range, ignoring datagram.");
+ _LOG2D(lldp_rx, "Chassis ID field size out of range, ignoring datagram.");
return -NME_UNSPEC;
}
if (n->id.chassis_id) {
- _LOG2D(n->lldp_rx, "Duplicate chassis ID field, ignoring datagram.");
+ _LOG2D(lldp_rx, "Duplicate chassis ID field, ignoring datagram.");
return -NME_UNSPEC;
}
@@ -182,12 +185,12 @@ nm_lldp_neighbor_parse(NMLldpNeighbor *n)
case NM_LLDP_TYPE_PORT_ID:
if (length < 2 || length > 256) {
/* includes the port subtype, hence one extra byte */
- _LOG2D(n->lldp_rx, "Port ID field size out of range, ignoring datagram.");
+ _LOG2D(lldp_rx, "Port ID field size out of range, ignoring datagram.");
return -NME_UNSPEC;
}
if (n->id.port_id) {
- _LOG2D(n->lldp_rx, "Duplicate port ID field, ignoring datagram.");
+ _LOG2D(lldp_rx, "Duplicate port ID field, ignoring datagram.");
return -NME_UNSPEC;
}
@@ -197,12 +200,12 @@ nm_lldp_neighbor_parse(NMLldpNeighbor *n)
case NM_LLDP_TYPE_TTL:
if (length != 2) {
- _LOG2D(n->lldp_rx, "TTL field has wrong size, ignoring datagram.");
+ _LOG2D(lldp_rx, "TTL field has wrong size, ignoring datagram.");
return -NME_UNSPEC;
}
if (n->has_ttl) {
- _LOG2D(n->lldp_rx, "Duplicate TTL field, ignoring datagram.");
+ _LOG2D(lldp_rx, "Duplicate TTL field, ignoring datagram.");
return -NME_UNSPEC;
}
@@ -211,26 +214,26 @@ nm_lldp_neighbor_parse(NMLldpNeighbor *n)
break;
case NM_LLDP_TYPE_PORT_DESCRIPTION:
- r = parse_string(n->lldp_rx, &n->port_description, p, length);
+ r = parse_string(lldp_rx, &n->port_description, p, length);
if (r < 0)
return r;
break;
case NM_LLDP_TYPE_SYSTEM_NAME:
- r = parse_string(n->lldp_rx, &n->system_name, p, length);
+ r = parse_string(lldp_rx, &n->system_name, p, length);
if (r < 0)
return r;
break;
case NM_LLDP_TYPE_SYSTEM_DESCRIPTION:
- r = parse_string(n->lldp_rx, &n->system_description, p, length);
+ r = parse_string(lldp_rx, &n->system_description, p, length);
if (r < 0)
return r;
break;
case NM_LLDP_TYPE_SYSTEM_CAPABILITIES:
if (length != 4) {
- _LOG2D(n->lldp_rx, "System capabilities field has wrong size.");
+ _LOG2D(lldp_rx, "System capabilities field has wrong size.");
return -NME_UNSPEC;
}
@@ -241,13 +244,13 @@ nm_lldp_neighbor_parse(NMLldpNeighbor *n)
case NM_LLDP_TYPE_PRIVATE:
if (length < 4) {
- _LOG2D(n->lldp_rx, "Found private TLV that is too short, ignoring.");
+ _LOG2D(lldp_rx, "Found private TLV that is too short, ignoring.");
return -NME_UNSPEC;
}
/* RFC 8520: MUD URL */
if (memcmp(p, NM_LLDP_OUI_IANA_MUD, sizeof(NM_LLDP_OUI_IANA_MUD)) == 0) {
- r = parse_string(n->lldp_rx,
+ r = parse_string(lldp_rx,
&n->mud_url,
p + sizeof(NM_LLDP_OUI_IANA_MUD),
length - sizeof(NM_LLDP_OUI_IANA_MUD));
@@ -262,7 +265,7 @@ nm_lldp_neighbor_parse(NMLldpNeighbor *n)
end_marker:
if (!n->id.chassis_id || !n->id.port_id || !n->has_ttl) {
- _LOG2D(n->lldp_rx, "One or more mandatory TLV missing in datagram. Ignoring.");
+ _LOG2D(lldp_rx, "One or more mandatory TLV missing in datagram. Ignoring.");
return -NME_UNSPEC;
}
@@ -740,7 +743,7 @@ nm_lldp_neighbor_new(size_t raw_size)
}
NMLldpNeighbor *
-nm_lldp_neighbor_new_from_raw(const void *raw, size_t raw_size)
+nm_lldp_neighbor_new_from_raw(NMLldpRX *lldp_rx, const void *raw, size_t raw_size)
{
nm_auto(nm_lldp_neighbor_unrefp) NMLldpNeighbor *n = NULL;
int r;
@@ -751,7 +754,7 @@ nm_lldp_neighbor_new_from_raw(const void *raw, size_t raw_size)
nm_memcpy(NM_LLDP_NEIGHBOR_RAW(n), raw, raw_size);
- r = nm_lldp_neighbor_parse(n);
+ r = nm_lldp_neighbor_parse(lldp_rx, n);
if (r < 0)
return NULL;
diff --git a/src/libnm-lldp/nm-lldp-neighbor.h b/src/libnm-lldp/nm-lldp-neighbor.h
index 1adc967e7e..038591a066 100644
--- a/src/libnm-lldp/nm-lldp-neighbor.h
+++ b/src/libnm-lldp/nm-lldp-neighbor.h
@@ -75,11 +75,13 @@ NM_LLDP_NEIGHBOR_TLV_DATA(const NMLldpNeighbor *n)
return ((uint8_t *) NM_LLDP_NEIGHBOR_RAW(n)) + n->rindex + 2;
}
+struct _NMLldpRX;
+
int nm_lldp_neighbor_prioq_compare_func(const void *a, const void *b);
void nm_lldp_neighbor_unlink(NMLldpNeighbor *n);
NMLldpNeighbor *nm_lldp_neighbor_new(size_t raw_size);
-int nm_lldp_neighbor_parse(NMLldpNeighbor *n);
+int nm_lldp_neighbor_parse(struct _NMLldpRX *lldp_rx, NMLldpNeighbor *n);
void nm_lldp_neighbor_start_ttl(NMLldpNeighbor *n);
#endif /* __NM_LLDP_NEIGHBOR_H__ */
diff --git a/src/libnm-lldp/nm-lldp-rx.c b/src/libnm-lldp/nm-lldp-rx.c
index 345c6d5661..90414b3ee7 100644
--- a/src/libnm-lldp/nm-lldp-rx.c
+++ b/src/libnm-lldp/nm-lldp-rx.c
@@ -255,7 +255,7 @@ lldp_rx_receive_datagram(int fd, GIOCondition condition, gpointer user_data)
} else
n->timestamp_usec = nm_utils_get_monotonic_timestamp_usec();
- r = nm_lldp_neighbor_parse(n);
+ r = nm_lldp_neighbor_parse(lldp_rx, n);
if (r < 0) {
_LOG2D(lldp_rx, "Failure parsing invalid LLDP datagram.");
return G_SOURCE_CONTINUE;
diff --git a/src/libnm-lldp/nm-lldp-rx.h b/src/libnm-lldp/nm-lldp-rx.h
index a3f3805376..d96ffcd888 100644
--- a/src/libnm-lldp/nm-lldp-rx.h
+++ b/src/libnm-lldp/nm-lldp-rx.h
@@ -68,7 +68,7 @@ NMLldpNeighbor **nm_lldp_rx_get_neighbors(NMLldpRX *lldp_rx, guint *out_len);
/*****************************************************************************/
-NMLldpNeighbor *nm_lldp_neighbor_new_from_raw(const void *raw, size_t raw_size);
+NMLldpNeighbor *nm_lldp_neighbor_new_from_raw(NMLldpRX *lldp_rx, const void *raw, size_t raw_size);
NMLldpNeighbor *nm_lldp_neighbor_ref(NMLldpNeighbor *n);
NMLldpNeighbor *nm_lldp_neighbor_unref(NMLldpNeighbor *n);
--
2.46.0
From 36b12bf4f96ed03dd07740070eaf183edf94b5dc Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Fri, 31 May 2024 10:49:50 +0200
Subject: [PATCH 2/2] lldp: fix multiple access to argument in logging macro
Fixes: 630de288d2e4 ('lldp: add libnm-lldp as fork of systemd's sd_lldp_rx')
(cherry picked from commit 4365de5226aa80c01181a11988a731913e97b264)
(cherry picked from commit a1c18ce20d826763db9b175addb36e691e45fda9)
(cherry picked from commit 9905bcdcb73d12bb4a95b117e5efd5a9e168dcf4)
---
src/libnm-lldp/nm-lldp-rx-internal.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libnm-lldp/nm-lldp-rx-internal.h b/src/libnm-lldp/nm-lldp-rx-internal.h
index 47d063ae70..1296a9d33f 100644
--- a/src/libnm-lldp/nm-lldp-rx-internal.h
+++ b/src/libnm-lldp/nm-lldp-rx-internal.h
@@ -34,7 +34,7 @@ struct _NMLldpRX {
NMLldpRX *_lldp_rx = (lldp_rx); \
\
if (_NMLOG2_ENABLED(_level)) { \
- _nm_log(level, \
+ _nm_log(_level, \
_NMLOG2_DOMAIN, \
0, \
_lldp_rx->config.log_ifname, \
--
2.46.0

@ -0,0 +1,267 @@
From 2e88b3f69f552cb91057527de2acd6d8c95fb51d Mon Sep 17 00:00:00 2001
From: Beniamino Galvani <bgalvani@redhat.com>
Date: Wed, 19 Jun 2024 20:14:14 +0200
Subject: [PATCH 1/2] nm-daemon-helper: add "service" argument
Introduce a new argument to specify a comma-separated list of NSS
services to use for the "resolve-address" command. For now only accept
"dns" and "files"; the latter can be used to do a lookup into
/etc/hosts.
Note that previously the command failed in presence of extra
arguments. Therefore, when downgrading NetworkManager without
restarting the service, the previously-installed version of the daemon
(newer) would spawn the helper with the extra argument, and the
newly-installed version of the helper (older) would fail. This issue
only impacts hostname resolution and can be fixed by just restarting
the daemon.
In the upgrade path everything works as before, with the only
difference that the helper will use by default both "dns" and "files"
services.
Don't strictly check for the absence of extra arguments, so that in
the future we can introduce more arguments without necessarily break
the downgrade path.
(cherry picked from commit 229bebfae95f789018433900868700c16a20a17b)
(cherry picked from commit c36a74f698cc31fba20d9fd0a74d5cf74b832071)
(cherry picked from commit e86ddd9fc590e3b4462464c0562ab115f654f5d1)
---
src/nm-daemon-helper/nm-daemon-helper.c | 67 +++++++++++++++++--------
1 file changed, 45 insertions(+), 22 deletions(-)
diff --git a/src/nm-daemon-helper/nm-daemon-helper.c b/src/nm-daemon-helper/nm-daemon-helper.c
index 810ea5fa94..32be93a4ef 100644
--- a/src/nm-daemon-helper/nm-daemon-helper.c
+++ b/src/nm-daemon-helper/nm-daemon-helper.c
@@ -55,26 +55,31 @@ cmd_version(void)
static int
cmd_resolve_address(void)
{
- nm_auto_free char *address = NULL;
+ nm_auto_free char *address = NULL;
+ nm_auto_free char *services = NULL;
union {
struct sockaddr_in in;
struct sockaddr_in6 in6;
} sockaddr;
socklen_t sockaddr_size;
char name[NI_MAXHOST];
+ char *saveptr = NULL;
+ char *service;
+ char *str;
int ret;
address = read_arg();
if (!address)
return RETURN_INVALID_ARGS;
- if (more_args())
- return RETURN_INVALID_ARGS;
+ services = read_arg();
+ if (!services) {
+ /* Called by an old NM version which doesn't support the 'services'
+ * argument. Use both services. */
+ services = strdup("dns,files");
+ }
memset(&sockaddr, 0, sizeof(sockaddr));
-#if defined(__GLIBC__)
- __nss_configure_lookup("hosts", "dns");
-#endif
if (inet_pton(AF_INET, address, &sockaddr.in.sin_addr) == 1) {
sockaddr.in.sin_family = AF_INET;
@@ -85,33 +90,51 @@ cmd_resolve_address(void)
} else
return RETURN_INVALID_ARGS;
- ret = getnameinfo((struct sockaddr *) &sockaddr,
- sockaddr_size,
- name,
- sizeof(name),
- NULL,
- 0,
- NI_NAMEREQD);
- if (ret != 0) {
- if (ret == EAI_SYSTEM) {
- int errsv = errno;
+ for (str = services; (service = strtok_r(str, ",", &saveptr)); str = NULL) {
+ if (!NM_IN_STRSET(service, "dns", "files")) {
+ fprintf(stderr, "Unsupported resolver service '%s'\n", service);
+ continue;
+ }
+
+#if defined(__GLIBC__)
+ __nss_configure_lookup("hosts", service);
+#endif
+
+ ret = getnameinfo((struct sockaddr *) &sockaddr,
+ sockaddr_size,
+ name,
+ sizeof(name),
+ NULL,
+ 0,
+ NI_NAMEREQD);
+
+ if (ret == 0) {
+ printf("%s", name);
+ return RETURN_SUCCESS;
+ } else if (ret == EAI_SYSTEM) {
char buf[1024];
+ int errsv = errno;
fprintf(stderr,
- "getnameinfo() failed: %d (%s), system error: %d (%s)\n",
+ "getnameinfo() via service '%s' failed: %d (%s), system error: %d (%s)\n",
+ service,
ret,
gai_strerror(ret),
errsv,
_nm_strerror_r(errsv, buf, sizeof(buf)));
} else {
- fprintf(stderr, "getnameinfo() failed: %d (%s)\n", ret, gai_strerror(ret));
+ fprintf(stderr,
+ "getnameinfo() via service '%s' failed: %d (%s)\n",
+ service,
+ ret,
+ gai_strerror(ret));
}
- return RETURN_ERROR;
+#if !defined(__GLIBC__)
+ break;
+#endif
}
- printf("%s", name);
-
- return RETURN_SUCCESS;
+ return RETURN_ERROR;
}
int
--
2.46.0
From 824ab3b1033c5693cca6add3c6e15b2c8789a7df Mon Sep 17 00:00:00 2001
From: Beniamino Galvani <bgalvani@redhat.com>
Date: Wed, 19 Jun 2024 20:29:37 +0200
Subject: [PATCH 2/2] core: also use /etc/hosts for hostname resolution
Before introducing the hostname lookup via nm-daemon-helper and
systemd-resolved, we used GLib's GResolver which internally relies on
the libc resolver and generally also returns results from /etc/hosts.
With the new mechanism we only ask to systemd-resolved (with
NO_SYNTHESIZE) or perform the lookup via the "dns" NSS module. In both
ways, /etc/hosts is not evaluated.
Since users relied on having the hostname resolved via /etc/hosts,
restore that behavior. Now, after trying the resolution via
systemd-resolved and the "dns" NSS module, we also try via the "files"
NSS module which reads /etc/hosts.
Fixes: 27eae4043b27 ('device: add a nm_device_resolve_address()')
(cherry picked from commit 410afccb32f5814c6aeebec837505e3f94b7408c)
(cherry picked from commit cb54fe7ce9a69b1f8abfd6fa5f2bf83e971ff997)
(cherry picked from commit e3861be84505d795c34347af84bbf73dc4196586)
---
src/core/devices/nm-device-utils.c | 49 ++++++++++++++++++++++--------
1 file changed, 36 insertions(+), 13 deletions(-)
diff --git a/src/core/devices/nm-device-utils.c b/src/core/devices/nm-device-utils.c
index ed0a27382a..75423528c5 100644
--- a/src/core/devices/nm-device-utils.c
+++ b/src/core/devices/nm-device-utils.c
@@ -233,14 +233,36 @@ resolve_addr_helper_cb(GObject *source, GAsyncResult *result, gpointer user_data
resolve_addr_complete(info, g_steal_pointer(&output), g_steal_pointer(&error));
}
+typedef enum {
+ RESOLVE_ADDR_SERVICE_NONE = 0x0,
+ RESOLVE_ADDR_SERVICE_DNS = 0x1,
+ RESOLVE_ADDR_SERVICE_FILES = 0x2,
+} ResolveAddrService;
+
static void
-resolve_addr_spawn_helper(ResolveAddrInfo *info)
+resolve_addr_spawn_helper(ResolveAddrInfo *info, ResolveAddrService services)
{
- char addr_str[NM_INET_ADDRSTRLEN];
+ char addr_str[NM_INET_ADDRSTRLEN];
+ char str[256];
+ char *s = str;
+ gsize len = sizeof(str);
+ gboolean comma = FALSE;
+
+ nm_assert(services != RESOLVE_ADDR_SERVICE_NONE);
+ nm_assert((services & ~(RESOLVE_ADDR_SERVICE_DNS | RESOLVE_ADDR_SERVICE_FILES)) == 0);
+
+ if (services & RESOLVE_ADDR_SERVICE_DNS) {
+ nm_strbuf_append(&s, &len, "%sdns", comma ? "," : "");
+ comma = TRUE;
+ }
+ if (services & RESOLVE_ADDR_SERVICE_FILES) {
+ nm_strbuf_append(&s, &len, "%sfiles", comma ? "," : "");
+ comma = TRUE;
+ }
nm_inet_ntop(info->addr_family, &info->address, addr_str);
- _LOG2D(info, "start lookup via nm-daemon-helper");
- nm_utils_spawn_helper(NM_MAKE_STRV("resolve-address", addr_str),
+ _LOG2D(info, "start lookup via nm-daemon-helper using services: %s", str);
+ nm_utils_spawn_helper(NM_MAKE_STRV("resolve-address", addr_str, str),
g_task_get_cancellable(info->task),
resolve_addr_helper_cb,
info);
@@ -270,27 +292,28 @@ resolve_addr_resolved_cb(NMDnsSystemdResolved *resolved,
dbus_error = g_dbus_error_get_remote_error(error);
if (NM_STR_HAS_PREFIX(dbus_error, "org.freedesktop.resolve1.")) {
/* systemd-resolved is enabled but it couldn't resolve the
- * address via DNS. Don't fall back to spawning the helper,
- * because the helper will possibly ask again to
+ * address via DNS. Spawn again the helper to check if we
+ * can find a result in /etc/hosts. Don't enable the 'dns'
+ * service otherwise the helper will possibly ask again to
* systemd-resolved (via /etc/resolv.conf), potentially using
* other protocols than DNS or returning synthetic results.
*
- * Consider the error as the final indication that the address
- * can't be resolved.
- *
* See: https://www.freedesktop.org/wiki/Software/systemd/resolved/#commonerrors
*/
- resolve_addr_complete(info, NULL, g_error_copy(error));
+ resolve_addr_spawn_helper(info, RESOLVE_ADDR_SERVICE_FILES);
return;
}
- resolve_addr_spawn_helper(info);
+ /* systemd-resolved couldn't be contacted, use the helper */
+ resolve_addr_spawn_helper(info, RESOLVE_ADDR_SERVICE_DNS | RESOLVE_ADDR_SERVICE_FILES);
return;
}
if (names_len == 0) {
_LOG2D(info, "systemd-resolved returned no result");
- resolve_addr_complete(info, g_strdup(""), NULL);
+ /* We passed the NO_SYNTHESIZE flag and so systemd-resolved
+ * didn't look into /etc/hosts. Spawn the helper for that. */
+ resolve_addr_spawn_helper(info, RESOLVE_ADDR_SERVICE_FILES);
return;
}
@@ -354,7 +377,7 @@ nm_device_resolve_address(int addr_family,
return;
}
- resolve_addr_spawn_helper(info);
+ resolve_addr_spawn_helper(info, RESOLVE_ADDR_SERVICE_DNS | RESOLVE_ADDR_SERVICE_FILES);
}
char *
--
2.46.0

@ -7,7 +7,7 @@
%global epoch_version 1 %global epoch_version 1
%global real_version 1.46.0 %global real_version 1.46.0
%global rpm_version %{real_version} %global rpm_version %{real_version}
%global release_version 13 %global release_version 18
%global snapshot %{nil} %global snapshot %{nil}
%global git_sha %{nil} %global git_sha %{nil}
%global bcond_default_debug 0 %global bcond_default_debug 0
@ -231,6 +231,11 @@ Patch1007: 1007-platform-avoid-routes-resync-rhel36162.patch
Patch1008: 1008-checkpoint-preserve-in-memory-state-rhel32493.patch Patch1008: 1008-checkpoint-preserve-in-memory-state-rhel32493.patch
Patch1010: 1010-allow-ip-configurations-without-addresses-rhel28544.patch Patch1010: 1010-allow-ip-configurations-without-addresses-rhel28544.patch
Patch1011: 1011-vpn-handle-hint-tags-in-the-daemon-rhel44712.patch Patch1011: 1011-vpn-handle-hint-tags-in-the-daemon-rhel44712.patch
Patch1013: 1013-ovs-wait-for-the-link-to-be-ready-before-activating-rhel-49799.patch
Patch1014: 1014-ovs-fix-triggering-stage3-without-dhcp-client-rhel-49799.patch
Patch1015: 1015-policy-unblock-the-autoconnect-for-children-when-parent-is-available-rhel-53344.patch
Patch1016: 1016-fix-lldp-crash-dereferencing-null-pointer-rhel-46200.patch
Patch1017: 1017-use-etc-hosts-for-hostname-resolution-rhel-53202.patch
Requires(post): systemd Requires(post): systemd
%if 0%{?fedora} || 0%{?rhel} >= 8 %if 0%{?fedora} || 0%{?rhel} >= 8
@ -1310,8 +1315,22 @@ fi
%changelog %changelog
* Wed Jul 24 2024 Sergey Cherevko <s.cherevko@msvsphere-os.ru> - 1:1.46.0-13.inferit * Tue Aug 20 2024 Fernando Fernandez Mancera <ferferna@redhat.com> - 1:1.46.0-18
- Update to 1.46.0-13 - Fix crash dereferencing NULL pointer during debug logging (RHEL-46200)
- Use /etc/hosts for hostname reesolution (RHEL-53202)
* Tue Aug 13 2024 Wen Liang <wenliang@redhat.com> - 1:1.46.0-17
- Unblock the autoconnect for children when parent is available (RHEL-53344)
* Wed Jul 31 2024 Fernando Fernandez Mancera <ferferna@redhat.com> - 1:1.46.0-16
- Revert OVS checkpoint rollback patches.
- Fix OVS stage3 activation without DHCP client initialized (RHEL-49799)
* Thu Jul 25 2024 Fernando Fernandez Mancera <ferferna@redhat.com> - 1:1.46.0-15
- Wait for link to be ready before activating ovs-interface (RHEL-49799)
* Tue Jul 23 2024 Fernando Fernandez Mancera <ferferna@redhat.com> - 1:1.46.0-14
- Fix OVS checkpoint rollback (RHEL-32646)
* Fri Jun 28 2024 Beniamino Galvani <bgalvani@redhat.com> - 1:1.46.0-13 * Fri Jun 28 2024 Beniamino Galvani <bgalvani@redhat.com> - 1:1.46.0-13
- Revert "Fix port reactivation when controller is deactivating" (RHEL-32646) - Revert "Fix port reactivation when controller is deactivating" (RHEL-32646)

Loading…
Cancel
Save