mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-07 14:50:24 +01:00
device,cli: allow re-activation of already active connections (bgo #730492)
https://bugzilla.gnome.org/show_bug.cgi?id=730492 https://bugzilla.redhat.com/show_bug.cgi?id=1182085
This commit is contained in:
commit
353570224f
4 changed files with 89 additions and 33 deletions
|
|
@ -1723,6 +1723,7 @@ find_device_for_connection (NmCli *nmc,
|
|||
int i, j;
|
||||
|
||||
g_return_val_if_fail (nmc != NULL, FALSE);
|
||||
g_return_val_if_fail (iface || ap || nsp, FALSE);
|
||||
g_return_val_if_fail (device != NULL && *device == NULL, FALSE);
|
||||
g_return_val_if_fail (spec_object != NULL && *spec_object == NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
|
@ -2208,7 +2209,7 @@ nmc_activate_connection (NmCli *nmc,
|
|||
g_return_val_if_fail (nmc != NULL, FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
if (connection) {
|
||||
if (connection && (ifname || ap || nsp)) {
|
||||
device_found = find_device_for_connection (nmc, connection, ifname, ap, nsp, &device, &spec_object, &local);
|
||||
|
||||
/* Virtual connection may not have their interfaces created yet */
|
||||
|
|
@ -2226,7 +2227,7 @@ nmc_activate_connection (NmCli *nmc,
|
|||
_("unknown device '%s'."), ifname);
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
} else if (!connection) {
|
||||
g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_NOT_FOUND,
|
||||
_("neither a valid connection nor device given"));
|
||||
return FALSE;
|
||||
|
|
|
|||
|
|
@ -5908,6 +5908,26 @@ _carrier_wait_check_act_request_must_queue (NMDevice *self, NMActRequest *req)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
nm_device_steal_connection (NMDevice *self, NMConnection *connection)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
_LOGW (LOGD_DEVICE, "disconnecting connection '%s' for new activation request.",
|
||||
nm_connection_get_id (connection));
|
||||
|
||||
if ( priv->queued_act_request
|
||||
&& connection == nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (priv->queued_act_request)))
|
||||
_clear_queued_act_request (priv);
|
||||
|
||||
if ( priv->act_request
|
||||
&& connection == nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (priv->act_request))
|
||||
&& priv->state < NM_DEVICE_STATE_DEACTIVATING)
|
||||
nm_device_state_changed (self,
|
||||
NM_DEVICE_STATE_DEACTIVATING,
|
||||
NM_DEVICE_STATE_REASON_USER_REQUESTED);
|
||||
}
|
||||
|
||||
void
|
||||
nm_device_queue_activation (NMDevice *self, NMActRequest *req)
|
||||
{
|
||||
|
|
@ -5929,8 +5949,8 @@ nm_device_queue_activation (NMDevice *self, NMActRequest *req)
|
|||
|
||||
_LOGD (LOGD_DEVICE, "queue activation request waiting for %s", must_queue ? "carrier" : "currently active connection to disconnect");
|
||||
|
||||
/* Deactivate existing activation request first */
|
||||
if (priv->act_request) {
|
||||
/* Deactivate existing activation request first */
|
||||
_LOGI (LOGD_DEVICE, "disconnecting for new activation request.");
|
||||
nm_device_state_changed (self,
|
||||
NM_DEVICE_STATE_DEACTIVATING,
|
||||
|
|
@ -7390,10 +7410,9 @@ _cleanup_ip_pre (NMDevice *self, gboolean deconfigure)
|
|||
}
|
||||
|
||||
static void
|
||||
_cleanup_generic_pre (NMDevice *self, gboolean deconfigure)
|
||||
_cancel_activation (NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
NMConnection *connection;
|
||||
|
||||
/* Clean up when device was deactivated during call to firewall */
|
||||
if (priv->fw_call) {
|
||||
|
|
@ -7401,6 +7420,20 @@ _cleanup_generic_pre (NMDevice *self, gboolean deconfigure)
|
|||
priv->fw_call = NULL;
|
||||
}
|
||||
|
||||
ip_check_gw_ping_cleanup (self);
|
||||
|
||||
/* Break the activation chain */
|
||||
activation_source_clear (self, TRUE, AF_INET);
|
||||
activation_source_clear (self, TRUE, AF_INET6);
|
||||
}
|
||||
|
||||
static void
|
||||
_cleanup_generic_pre (NMDevice *self, gboolean deconfigure)
|
||||
{
|
||||
NMConnection *connection;
|
||||
|
||||
_cancel_activation (self);
|
||||
|
||||
connection = nm_device_get_connection (self);
|
||||
if ( deconfigure
|
||||
&& connection
|
||||
|
|
@ -7410,12 +7443,6 @@ _cleanup_generic_pre (NMDevice *self, gboolean deconfigure)
|
|||
NULL);
|
||||
}
|
||||
|
||||
ip_check_gw_ping_cleanup (self);
|
||||
|
||||
/* Break the activation chain */
|
||||
activation_source_clear (self, TRUE, AF_INET);
|
||||
activation_source_clear (self, TRUE, AF_INET6);
|
||||
|
||||
/* Clear any queued transitions */
|
||||
nm_device_queued_state_clear (self);
|
||||
|
||||
|
|
@ -7951,6 +7978,8 @@ _set_state_full (NMDevice *self,
|
|||
}
|
||||
break;
|
||||
case NM_DEVICE_STATE_DEACTIVATING:
|
||||
_cancel_activation (self);
|
||||
|
||||
if (quitting) {
|
||||
nm_dispatcher_call_sync (DISPATCHER_ACTION_PRE_DOWN,
|
||||
nm_act_request_get_connection (req),
|
||||
|
|
|
|||
|
|
@ -387,6 +387,8 @@ void nm_device_queue_state (NMDevice *self,
|
|||
|
||||
gboolean nm_device_get_firmware_missing (NMDevice *self);
|
||||
|
||||
void nm_device_steal_connection (NMDevice *device, NMConnection *connection);
|
||||
|
||||
void nm_device_queue_activation (NMDevice *device, NMActRequest *req);
|
||||
|
||||
gboolean nm_device_supports_vlans (NMDevice *device);
|
||||
|
|
|
|||
|
|
@ -2263,6 +2263,40 @@ nm_manager_get_devices (NMManager *manager)
|
|||
return NM_MANAGER_GET_PRIVATE (manager)->devices;
|
||||
}
|
||||
|
||||
static NMDevice *
|
||||
nm_manager_get_connection_device (NMManager *self,
|
||||
NMConnection *connection)
|
||||
{
|
||||
NMActiveConnection *ac = find_ac_for_connection (self, connection);
|
||||
if (ac == NULL)
|
||||
return NULL;
|
||||
|
||||
return nm_active_connection_get_device (ac);
|
||||
}
|
||||
|
||||
static NMDevice *
|
||||
nm_manager_get_best_device_for_connection (NMManager *self,
|
||||
NMConnection *connection)
|
||||
{
|
||||
const GSList *devices, *iter;
|
||||
NMDevice *act_device = nm_manager_get_connection_device (self, connection);
|
||||
|
||||
if (act_device)
|
||||
return act_device;
|
||||
|
||||
/* Pick the first device that's compatible with the connection. */
|
||||
devices = nm_manager_get_devices (self);
|
||||
for (iter = devices; iter; iter = g_slist_next (iter)) {
|
||||
NMDevice *device = NM_DEVICE (iter->data);
|
||||
|
||||
if (nm_device_check_connection_available (device, connection, NM_DEVICE_CHECK_CON_AVAILABLE_NONE, NULL))
|
||||
return device;
|
||||
}
|
||||
|
||||
/* No luck. :( */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
impl_manager_get_devices (NMManager *manager, GPtrArray **devices, GError **err)
|
||||
{
|
||||
|
|
@ -2650,7 +2684,7 @@ _internal_activate_vpn (NMManager *self, NMActiveConnection *active, GError **er
|
|||
static gboolean
|
||||
_internal_activate_device (NMManager *self, NMActiveConnection *active, GError **error)
|
||||
{
|
||||
NMDevice *device, *master_device = NULL;
|
||||
NMDevice *device, *existing, *master_device = NULL;
|
||||
NMConnection *connection;
|
||||
NMConnection *master_connection = NULL;
|
||||
NMActiveConnection *master_ac = NULL;
|
||||
|
|
@ -2802,6 +2836,11 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
|
|||
nm_active_connection_get_path (master_ac));
|
||||
}
|
||||
|
||||
/* Disconnect the connection if connected or queued on another device */
|
||||
existing = nm_manager_get_connection_device (self, connection);
|
||||
if (existing)
|
||||
nm_device_steal_connection (existing, connection);
|
||||
|
||||
/* Export the new ActiveConnection to clients and start it on the device */
|
||||
nm_active_connection_export (active);
|
||||
g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
|
||||
|
|
@ -2839,6 +2878,7 @@ _internal_activate_generic (NMManager *self, NMActiveConnection *active, GError
|
|||
* is exported, make sure the manager's activating-connection property
|
||||
* is up-to-date.
|
||||
*/
|
||||
active_connection_add (self, active);
|
||||
policy_activating_device_changed (G_OBJECT (priv->policy), NULL, self);
|
||||
}
|
||||
|
||||
|
|
@ -2908,18 +2948,6 @@ _new_active_connection (NMManager *self,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (existing_ac) {
|
||||
NMDevice *existing_device = nm_active_connection_get_device (existing_ac);
|
||||
|
||||
if (existing_device != device) {
|
||||
g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_ALREADY_ACTIVE,
|
||||
"Connection '%s' is already active on %s",
|
||||
nm_connection_get_id (connection),
|
||||
nm_device_get_iface (existing_device));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Normalize the specific object */
|
||||
if (specific_object && g_strcmp0 (specific_object, "/") == 0)
|
||||
specific_object = NULL;
|
||||
|
|
@ -2951,7 +2979,6 @@ _internal_activation_failed (NMManager *self,
|
|||
nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATING);
|
||||
nm_active_connection_set_state (active, NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);
|
||||
}
|
||||
active_connection_remove (self, active);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -3029,10 +3056,8 @@ nm_manager_activate_connection (NMManager *self,
|
|||
device,
|
||||
subject,
|
||||
error);
|
||||
if (active) {
|
||||
if (active)
|
||||
nm_active_connection_authorize (active, _internal_activation_auth_done, self, NULL);
|
||||
active_connection_add (self, active);
|
||||
}
|
||||
return active;
|
||||
}
|
||||
|
||||
|
|
@ -3107,7 +3132,10 @@ validate_activation_request (NMManager *self,
|
|||
"Device not found");
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
} else
|
||||
device = nm_manager_get_best_device_for_connection (self, connection);
|
||||
|
||||
if (!device) {
|
||||
gboolean is_software = nm_connection_is_virtual (connection);
|
||||
|
||||
/* VPN and software-device connections don't need a device yet */
|
||||
|
|
@ -3276,7 +3304,6 @@ impl_manager_activate_connection (NMManager *self,
|
|||
goto error;
|
||||
|
||||
nm_active_connection_authorize (active, _activation_auth_done, self, context);
|
||||
active_connection_add (self, active);
|
||||
g_clear_object (&subject);
|
||||
return;
|
||||
|
||||
|
|
@ -3354,8 +3381,6 @@ _add_and_activate_auth_done (NMActiveConnection *active,
|
|||
activation_add_done,
|
||||
info);
|
||||
} else {
|
||||
active_connection_remove (self, active);
|
||||
|
||||
g_assert (error_desc);
|
||||
error = g_error_new_literal (NM_MANAGER_ERROR,
|
||||
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
||||
|
|
@ -3462,7 +3487,6 @@ impl_manager_add_and_activate_connection (NMManager *self,
|
|||
goto error;
|
||||
|
||||
nm_active_connection_authorize (active, _add_and_activate_auth_done, self, context);
|
||||
active_connection_add (self, active);
|
||||
g_object_unref (connection);
|
||||
g_object_unref (subject);
|
||||
return;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue