You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
NetworkManager/SOURCES/1015-policy-unblock-the-aut...

232 lines
10 KiB

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