mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-07 00:30:32 +01:00
core: move virtual device autoconnect tracking bits out of NMManager
Virtual devices may be created and destroyed, but we need to keep their autoconnect state across that. Previously this was handled by NMManager, but it really belongs with the other autoconnect tracking in NMPolicy and NMSettingsConnection. This also fixes a bug where NMPolicy would sometimes decide to autoactivate a virtual device connection which NMManager would then have to cancel.
This commit is contained in:
parent
971167e2a8
commit
979b8920b4
5 changed files with 40 additions and 87 deletions
|
|
@ -4610,13 +4610,6 @@ disconnect_cb (NMDevice *device,
|
|||
} else {
|
||||
priv->autoconnect = FALSE;
|
||||
|
||||
/* Software devices are removed when manually disconnected and thus
|
||||
* we need to track the autoconnect flag outside the device.
|
||||
*/
|
||||
nm_manager_prevent_device_auto_connect (nm_manager_get (),
|
||||
nm_device_get_ip_iface (device),
|
||||
TRUE);
|
||||
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_DEACTIVATING,
|
||||
NM_DEVICE_STATE_REASON_USER_REQUESTED);
|
||||
|
|
|
|||
|
|
@ -249,9 +249,6 @@ typedef struct {
|
|||
|
||||
guint timestamp_update_id;
|
||||
|
||||
/* Track auto-activation for software devices */
|
||||
GHashTable *noauto_sw_devices;
|
||||
|
||||
gboolean startup;
|
||||
gboolean disposed;
|
||||
} NMManagerPrivate;
|
||||
|
|
@ -1214,21 +1211,11 @@ system_create_virtual_devices (NMManager *self)
|
|||
connections = nm_settings_get_connections (priv->settings);
|
||||
for (iter = connections; iter; iter = g_slist_next (iter)) {
|
||||
NMConnection *connection = iter->data;
|
||||
NMSettingConnection *s_con = nm_connection_get_setting_connection (connection);
|
||||
|
||||
g_assert (s_con);
|
||||
if (connection_needs_virtual_device (connection)) {
|
||||
char *iface = get_virtual_iface_name (self, connection, NULL);
|
||||
|
||||
/* We only create a virtual interface if the connection can autoconnect
|
||||
* and the interface was not manually disconnected before.
|
||||
*/
|
||||
if ( nm_setting_connection_get_autoconnect (s_con)
|
||||
&& iface
|
||||
&& nm_manager_can_device_auto_connect (self, iface))
|
||||
system_create_virtual_device (self, connection);
|
||||
g_free (iface);
|
||||
}
|
||||
/* We only create a virtual interface if the connection can autoconnect */
|
||||
if ( connection_needs_virtual_device (connection)
|
||||
&& nm_settings_connection_can_autoconnect (NM_SETTINGS_CONNECTION (connection)))
|
||||
system_create_virtual_device (self, connection);
|
||||
}
|
||||
g_slist_free (connections);
|
||||
}
|
||||
|
|
@ -2720,31 +2707,8 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
|
|||
|
||||
device = nm_active_connection_get_device (active);
|
||||
if (!device) {
|
||||
char *iface;
|
||||
|
||||
g_assert (connection_needs_virtual_device (connection));
|
||||
|
||||
iface = get_virtual_iface_name (self, connection, NULL);
|
||||
g_assert (iface);
|
||||
|
||||
/* Create the software device. Only exception is when:
|
||||
* - this is an auto-activation *and* the device denies auto-activation
|
||||
* at this time (the device was manually disconnected/deleted before)
|
||||
*/
|
||||
if (!nm_manager_can_device_auto_connect (self, iface)) {
|
||||
if (nm_active_connection_get_user_requested (active)) {
|
||||
/* Manual activation - allow device auto-activation again */
|
||||
nm_manager_prevent_device_auto_connect (self, iface, FALSE);
|
||||
} else {
|
||||
g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_AUTOCONNECT_NOT_ALLOWED,
|
||||
"Automatic activation of '%s' not allowed for connection '%s'",
|
||||
iface, nm_connection_get_id (connection));
|
||||
g_free (iface);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
g_free (iface);
|
||||
|
||||
device = system_create_virtual_device (self, connection);
|
||||
if (!device) {
|
||||
g_set_error_literal (error,
|
||||
|
|
@ -3617,33 +3581,6 @@ done:
|
|||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Track (software) devices that cannot auto activate.
|
||||
* It is needed especially for software devices, that can be removed and added
|
||||
* again. So we can't simply use a flag inside the device.
|
||||
*/
|
||||
void
|
||||
nm_manager_prevent_device_auto_connect (NMManager *manager, const char *ifname, gboolean prevent)
|
||||
{
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
||||
|
||||
if (prevent)
|
||||
g_hash_table_add (priv->noauto_sw_devices, g_strdup (ifname));
|
||||
else
|
||||
g_hash_table_remove (priv->noauto_sw_devices, ifname);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_manager_can_device_auto_connect (NMManager *manager, const char *ifname)
|
||||
{
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
||||
|
||||
if (!ifname)
|
||||
return FALSE;
|
||||
|
||||
return !g_hash_table_contains (priv->noauto_sw_devices, ifname);
|
||||
}
|
||||
|
||||
static void
|
||||
do_sleep_wake (NMManager *self)
|
||||
{
|
||||
|
|
@ -4719,8 +4656,6 @@ dispose (GObject *object)
|
|||
g_object_unref (priv->fw_monitor);
|
||||
}
|
||||
|
||||
g_hash_table_unref (priv->noauto_sw_devices);
|
||||
|
||||
g_slist_free (priv->factories);
|
||||
|
||||
if (priv->timestamp_update_id) {
|
||||
|
|
@ -5085,9 +5020,6 @@ nm_manager_init (NMManager *manager)
|
|||
KERNEL_FIRMWARE_DIR);
|
||||
}
|
||||
|
||||
/* Hash table storing software devices that should not auto activate */
|
||||
priv->noauto_sw_devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||
|
||||
load_device_factories (manager);
|
||||
|
||||
/* Update timestamps in active connections */
|
||||
|
|
|
|||
|
|
@ -128,12 +128,6 @@ gboolean nm_manager_deactivate_connection (NMManager *manager,
|
|||
NMDeviceStateReason reason,
|
||||
GError **error);
|
||||
|
||||
void nm_manager_prevent_device_auto_connect (NMManager *manager,
|
||||
const char *ifname,
|
||||
gboolean prevent);
|
||||
gboolean nm_manager_can_device_auto_connect (NMManager *manager,
|
||||
const char *ifname);
|
||||
|
||||
/* State handling */
|
||||
|
||||
NMState nm_manager_get_state (NMManager *manager);
|
||||
|
|
|
|||
|
|
@ -1160,6 +1160,28 @@ reset_autoconnect_for_failed_secrets (NMPolicy *policy)
|
|||
g_slist_free (connections);
|
||||
}
|
||||
|
||||
static void
|
||||
block_autoconnect_for_device (NMPolicy *policy, NMDevice *device)
|
||||
{
|
||||
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy);
|
||||
GSList *connections, *iter;
|
||||
|
||||
/* NMDevice keeps its own autoconnect-able-ness state; we only need to
|
||||
* explicitly block connections for software devices, where the NMDevice
|
||||
* might be destroyed and recreated later.
|
||||
*/
|
||||
if (!nm_device_is_software (device))
|
||||
return;
|
||||
|
||||
connections = nm_settings_get_connections (priv->settings);
|
||||
for (iter = connections; iter; iter = g_slist_next (iter)) {
|
||||
if (nm_device_check_connection_compatible (device, iter->data, NULL)) {
|
||||
nm_settings_connection_set_autoconnect_blocked_reason (NM_SETTINGS_CONNECTION (iter->data),
|
||||
NM_DEVICE_STATE_REASON_USER_REQUESTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sleeping_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data)
|
||||
{
|
||||
|
|
@ -1432,8 +1454,15 @@ device_state_changed (NMDevice *device,
|
|||
update_routing_and_dns (policy, FALSE);
|
||||
break;
|
||||
case NM_DEVICE_STATE_DEACTIVATING:
|
||||
if (reason == NM_DEVICE_STATE_REASON_USER_REQUESTED)
|
||||
nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_DEVICE_STATE_REASON_USER_REQUESTED);
|
||||
if (reason == NM_DEVICE_STATE_REASON_USER_REQUESTED) {
|
||||
if (!nm_device_get_autoconnect (device)) {
|
||||
/* The device was disconnected; block all connections on it */
|
||||
block_autoconnect_for_device (policy, device);
|
||||
} else {
|
||||
/* The connection was deactivated, so block just this connection */
|
||||
nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_DEVICE_STATE_REASON_USER_REQUESTED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NM_DEVICE_STATE_DISCONNECTED:
|
||||
/* Reset retry counts for a device's connections when carrier on; if cable
|
||||
|
|
|
|||
|
|
@ -1955,6 +1955,7 @@ gboolean
|
|||
nm_settings_connection_can_autoconnect (NMSettingsConnection *connection)
|
||||
{
|
||||
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection);
|
||||
NMSettingConnection *s_con;
|
||||
const char *permission;
|
||||
|
||||
if ( !priv->visible
|
||||
|
|
@ -1962,6 +1963,10 @@ nm_settings_connection_can_autoconnect (NMSettingsConnection *connection)
|
|||
|| priv->autoconnect_blocked_reason != NM_DEVICE_STATE_REASON_NONE)
|
||||
return FALSE;
|
||||
|
||||
s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection));
|
||||
if (!nm_setting_connection_get_autoconnect (s_con))
|
||||
return FALSE;
|
||||
|
||||
permission = nm_utils_get_shared_wifi_permission (NM_CONNECTION (connection));
|
||||
if (permission) {
|
||||
if (nm_settings_connection_check_permission (connection, permission) == FALSE)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue