diff --git a/SOURCES/1013-ovs-wait-for-the-link-to-be-ready-before-activating-rhel-49799.patch b/SOURCES/1013-ovs-wait-for-the-link-to-be-ready-before-activating-rhel-49799.patch new file mode 100644 index 0000000..6d80359 --- /dev/null +++ b/SOURCES/1013-ovs-wait-for-the-link-to-be-ready-before-activating-rhel-49799.patch @@ -0,0 +1,37 @@ +From 567853b4299f529ff886bd86292f680cd3b651c6 Mon Sep 17 00:00:00 2001 +From: Fernando Fernandez Mancera +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 + diff --git a/SOURCES/1014-ovs-fix-triggering-stage3-without-dhcp-client-rhel-49799.patch b/SOURCES/1014-ovs-fix-triggering-stage3-without-dhcp-client-rhel-49799.patch new file mode 100644 index 0000000..946ad4b --- /dev/null +++ b/SOURCES/1014-ovs-fix-triggering-stage3-without-dhcp-client-rhel-49799.patch @@ -0,0 +1,67 @@ +From 0d744e4942d1a8bc7c600ddde82057bb8aa7c985 Mon Sep 17 00:00:00 2001 +From: Fernando Fernandez Mancera +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 + diff --git a/SOURCES/1015-policy-unblock-the-autoconnect-for-children-when-parent-is-available-rhel-53344.patch b/SOURCES/1015-policy-unblock-the-autoconnect-for-children-when-parent-is-available-rhel-53344.patch new file mode 100644 index 0000000..fc8b065 --- /dev/null +++ b/SOURCES/1015-policy-unblock-the-autoconnect-for-children-when-parent-is-available-rhel-53344.patch @@ -0,0 +1,231 @@ +From cf4f45af5cb23978123a991c191bf409bc237a9b Mon Sep 17 00:00:00 2001 +From: Wen Liang +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 + diff --git a/SOURCES/1016-fix-lldp-crash-dereferencing-null-pointer-rhel-46200.patch b/SOURCES/1016-fix-lldp-crash-dereferencing-null-pointer-rhel-46200.patch new file mode 100644 index 0000000..90c70bb --- /dev/null +++ b/SOURCES/1016-fix-lldp-crash-dereferencing-null-pointer-rhel-46200.patch @@ -0,0 +1,338 @@ +From 0c55f0128ad17764fbe0862819fe43f32abfb27c Mon Sep 17 00:00:00 2001 +From: Thomas Haller +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 +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 + diff --git a/SOURCES/1017-use-etc-hosts-for-hostname-resolution-rhel-53202.patch b/SOURCES/1017-use-etc-hosts-for-hostname-resolution-rhel-53202.patch new file mode 100644 index 0000000..8afdf9b --- /dev/null +++ b/SOURCES/1017-use-etc-hosts-for-hostname-resolution-rhel-53202.patch @@ -0,0 +1,267 @@ +From 2e88b3f69f552cb91057527de2acd6d8c95fb51d Mon Sep 17 00:00:00 2001 +From: Beniamino Galvani +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 +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 + diff --git a/SPECS/NetworkManager.spec b/SPECS/NetworkManager.spec index 77a84d0..336f2e9 100644 --- a/SPECS/NetworkManager.spec +++ b/SPECS/NetworkManager.spec @@ -7,7 +7,7 @@ %global epoch_version 1 %global real_version 1.46.0 %global rpm_version %{real_version} -%global release_version 13 +%global release_version 18 %global snapshot %{nil} %global git_sha %{nil} %global bcond_default_debug 0 @@ -223,6 +223,11 @@ Patch1007: 1007-platform-avoid-routes-resync-rhel36162.patch Patch1008: 1008-checkpoint-preserve-in-memory-state-rhel32493.patch Patch1010: 1010-allow-ip-configurations-without-addresses-rhel28544.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 %if 0%{?fedora} || 0%{?rhel} >= 8 @@ -1278,6 +1283,23 @@ fi %changelog +* Tue Aug 20 2024 Fernando Fernandez Mancera - 1:1.46.0-18 +- Fix crash dereferencing NULL pointer during debug logging (RHEL-46200) +- Use /etc/hosts for hostname reesolution (RHEL-53202) + +* Tue Aug 13 2024 Wen Liang - 1:1.46.0-17 +- Unblock the autoconnect for children when parent is available (RHEL-53344) + +* Wed Jul 31 2024 Fernando Fernandez Mancera - 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 - 1:1.46.0-15 +- Wait for link to be ready before activating ovs-interface (RHEL-49799) + +* Tue Jul 23 2024 Fernando Fernandez Mancera - 1:1.46.0-14 +- Fix OVS checkpoint rollback (RHEL-32646) + * Fri Jun 28 2024 Beniamino Galvani - 1:1.46.0-13 - Revert "Fix port reactivation when controller is deactivating" (RHEL-32646)