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.
232 lines
10 KiB
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
|
|
|