parent
94004d8e88
commit
7478f9c917
@ -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
|
||||||
|
|
Loading…
Reference in new issue