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
This commit is contained in:
@@ -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)
|
||||
activate_port_or_children_connections(NMPolicy *self,
|
||||
NMDevice *device,
|
||||
gboolean activate_children_connections_only)
|
||||
{
|
||||
const char *master_device;
|
||||
const char *master_uuid_settings = NULL;
|
||||
const char *master_uuid_applied = NULL;
|
||||
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. */
|
||||
|
Reference in New Issue
Block a user