mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-05 05:20:32 +01:00
device: merge branch 'th/device-applied-connection-bgo760884'
https://bugzilla.gnome.org/show_bug.cgi?id=760884 https://bugzilla.gnome.org/show_bug.cgi?id=761714
This commit is contained in:
commit
a058cf41dc
11 changed files with 475 additions and 28 deletions
|
|
@ -1928,7 +1928,7 @@ do_device_reapply (NmCli *nmc, int argc, char **argv)
|
|||
info->queue = g_slist_prepend (info->queue, g_object_ref (device));
|
||||
|
||||
/* Now reapply the connection to the device */
|
||||
nm_device_reapply_async (device, NULL, 0, NULL, reapply_device_cb, info);
|
||||
nm_device_reapply_async (device, NULL, 0, 0, NULL, reapply_device_cb, info);
|
||||
}
|
||||
|
||||
error:
|
||||
|
|
|
|||
|
|
@ -9,6 +9,15 @@
|
|||
The Connection.Active object tracks the life-cycle of the connection
|
||||
attempt and if successful indicates whether the connected network is the
|
||||
"default" or preferred network for access.
|
||||
NetworkManager has the concept of connections, which can be thought of as
|
||||
settings, a profile or a configuration that can be applied on a networking
|
||||
device.
|
||||
Such settings-connections are exposed as D-Bus object and the active-connection
|
||||
expresses this relationship between device and settings-connection.
|
||||
At any time a settings-connection can only be activated on one device and vice
|
||||
versa. However, during activation and deactivation multiple active-connections
|
||||
can reference the same device or settings-connection as they are waiting to
|
||||
be activated or to be deactivated.
|
||||
</tp:docstring>
|
||||
|
||||
<property name="Connection" type="o" access="read">
|
||||
|
|
|
|||
|
|
@ -172,8 +172,18 @@
|
|||
<method name="Reapply">
|
||||
<arg name="connection" type="a{sa{sv}}" direction="in">
|
||||
<tp:docstring>
|
||||
The effective connection settings and properties to use. If empty, the connection
|
||||
settings from the connection that is active on the device will be used.
|
||||
The optional connection settings that will be reapplied on the device. If empty, the
|
||||
currently active settings-connection will be used. The connection cannot arbitrarly
|
||||
differ from the current applied-connection otherwise the call will fail.
|
||||
Only certain changes are supported, like adding or removing IP addresses.
|
||||
</tp:docstring>
|
||||
</arg>
|
||||
<arg name="version_id" type="t" direction="in">
|
||||
<tp:docstring>
|
||||
If non-zero, the current version id of the applied-connection must match.
|
||||
The current version id can be retrieved via GetAppliedConnection.
|
||||
This optional argument allows to catch concurrent modifications between
|
||||
the GetAppliedConnection call and Reapply.
|
||||
</tp:docstring>
|
||||
</arg>
|
||||
<arg name="flags" type="u" direction="in">
|
||||
|
|
@ -183,10 +193,54 @@
|
|||
</tp:docstring>
|
||||
</arg>
|
||||
<tp:docstring>
|
||||
Attempts to update the configuration of a device without deactivating it.
|
||||
You can either modify the configuration by passing the desired setup via "connection"
|
||||
argument or just omit the argument to bring it in sync with the connection that
|
||||
has been activated but could have been modified since.
|
||||
Attempts to update the configuration of a device without deactivating it. NetworkManager
|
||||
has the concept of connections, which are profiles that contain the configuration for
|
||||
a networking device. Those connections are exposed via D-Bus as individual objects
|
||||
that can be created, modified and deleted. When activating such a settings-connection
|
||||
on a device, the settings-connection is cloned to become an applied-connection and used to
|
||||
configure the device (see GetAppliedConnection). Subsequent modification of the
|
||||
settings-connection don't propagate automatically to the device's applied-connection
|
||||
(with exception of the firewall-zone and the metered property). For the changes to take
|
||||
effect, you can either re-activate the settings-connection, or call Reapply.
|
||||
The Reapply call allows you to directly update the applied-connection and reconfigure
|
||||
the device.
|
||||
Reapply can also be useful if the currently applied-connection is equal to the connection
|
||||
that is about to be reapplied. This allows to reconfigure the device and revert external
|
||||
changes like removing or adding an IP address (which NetworkManager doesn't revert
|
||||
automatically because it is assumed that the user made these changes intentionally outside
|
||||
of NetworkManager).
|
||||
Reapply can make the applied-connection different from the settings-connection,
|
||||
just like updating the settings-connection can make them different.
|
||||
</tp:docstring>
|
||||
</method>
|
||||
|
||||
<method name="GetAppliedConnection">
|
||||
<arg name="flags" type="u" direction="in">
|
||||
<tp:docstring>
|
||||
Flags which would modify the behavior of the GetAppliedConnection call.
|
||||
There are no flags defined currently and the users should use the value of 0.
|
||||
</tp:docstring>
|
||||
</arg>
|
||||
<arg name="connection" type="a{sa{sv}}" direction="out">
|
||||
<tp:docstring>
|
||||
The effective connection settings that the connection has currently applied.
|
||||
</tp:docstring>
|
||||
</arg>
|
||||
<arg name="version_id" type="t" direction="out">
|
||||
<tp:docstring>
|
||||
The version-id of the currently applied connection. This can be specified during
|
||||
Reapply to avoid races where you first fetch the applied connection, modify it
|
||||
and try to reapply it. If the applied connection is modified in the meantime, the
|
||||
version_id gets incremented and Reapply will fail.
|
||||
</tp:docstring>
|
||||
</arg>
|
||||
<tp:docstring>
|
||||
Get the currently applied connection on the device. This is a snapshot of the last activated
|
||||
connection on the device, that is the configuration that is currently applied on the device.
|
||||
Usually this is the same as GetSettings of the referenced settings connection. However, it
|
||||
can differ if the settings connection was subsequently modified or the applied connection was
|
||||
modified by Reapply. The applied connection is set when activating a device or when calling
|
||||
Reapply.
|
||||
</tp:docstring>
|
||||
</method>
|
||||
|
||||
|
|
|
|||
|
|
@ -142,6 +142,7 @@ GQuark nm_crypto_error_quark (void);
|
|||
* @NM_DEVICE_ERROR_SPECIFIC_OBJECT_NOT_FOUND: the "specific object" in the
|
||||
* activation request (eg, the #NMAccessPoint or #NMWimaxNsp) was not
|
||||
* found.
|
||||
* @NM_DEVICE_ERROR_VERSION_ID_MISMATCH: the version id did not match.
|
||||
*
|
||||
* Device-related errors.
|
||||
*
|
||||
|
|
@ -158,6 +159,7 @@ typedef enum {
|
|||
NM_DEVICE_ERROR_NOT_SOFTWARE, /*< nick=NotSoftware >*/
|
||||
NM_DEVICE_ERROR_NOT_ALLOWED, /*< nick=NotAllowed >*/
|
||||
NM_DEVICE_ERROR_SPECIFIC_OBJECT_NOT_FOUND, /*< nick=SpecificObjectNotFound >*/
|
||||
NM_DEVICE_ERROR_VERSION_ID_MISMATCH, /*< nick=VersionIdMismatch >*/
|
||||
} NMDeviceError;
|
||||
|
||||
#define NM_DEVICE_ERROR nm_device_error_quark ()
|
||||
|
|
|
|||
|
|
@ -875,6 +875,9 @@ global:
|
|||
nm_connection_get_setting_vxlan;
|
||||
nm_connection_verify_secrets;
|
||||
nm_device_ethernet_get_s390_subchannels;
|
||||
nm_device_get_applied_connection;
|
||||
nm_device_get_applied_connection_async;
|
||||
nm_device_get_applied_connection_finish;
|
||||
nm_device_get_lldp_neighbors;
|
||||
nm_device_get_metered;
|
||||
nm_device_get_nm_plugin_missing;
|
||||
|
|
|
|||
|
|
@ -2167,6 +2167,9 @@ nm_device_is_software (NMDevice *device)
|
|||
* nm_device_reapply:
|
||||
* @device: a #NMDevice
|
||||
* @connection: the #NMConnection to replace the applied settings with or %NULL to reuse existing
|
||||
* @version_id: zero or the expected version id of the applied connection. If specified
|
||||
* and the version id mismatches, the call fails without modification. This allows to
|
||||
* catch concurrent accesses.
|
||||
* @flags: always set this to zero
|
||||
* @cancellable: a #GCancellable, or %NULL
|
||||
* @error: location for a #GError, or %NULL
|
||||
|
|
@ -2181,7 +2184,8 @@ nm_device_is_software (NMDevice *device)
|
|||
gboolean
|
||||
nm_device_reapply (NMDevice *device,
|
||||
NMConnection *connection,
|
||||
guint flags,
|
||||
guint64 version_id,
|
||||
guint32 flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
|
|
@ -2197,7 +2201,7 @@ nm_device_reapply (NMDevice *device,
|
|||
|
||||
|
||||
ret = nmdbus_device_call_reapply_sync (NM_DEVICE_GET_PRIVATE (device)->proxy,
|
||||
dict, flags, cancellable, error);
|
||||
dict, version_id, flags, cancellable, error);
|
||||
if (error && *error)
|
||||
g_dbus_error_strip_remote_error (*error);
|
||||
return ret;
|
||||
|
|
@ -2226,6 +2230,9 @@ device_reapply_cb (GObject *proxy,
|
|||
* nm_device_reapply_async:
|
||||
* @device: a #NMDevice
|
||||
* @connection: the #NMConnection to replace the applied settings with or %NULL to reuse existing
|
||||
* @version_id: zero or the expected version id of the applied connection. If specified
|
||||
* and the version id mismatches, the call fails without modification. This allows to
|
||||
* catch concurrent accesses.
|
||||
* @flags: always set this to zero
|
||||
* @cancellable: a #GCancellable, or %NULL
|
||||
* @callback: callback to be called when the reapply operation completes
|
||||
|
|
@ -2239,7 +2246,8 @@ device_reapply_cb (GObject *proxy,
|
|||
void
|
||||
nm_device_reapply_async (NMDevice *device,
|
||||
NMConnection *connection,
|
||||
guint flags,
|
||||
guint64 version_id,
|
||||
guint32 flags,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
|
|
@ -2258,7 +2266,7 @@ nm_device_reapply_async (NMDevice *device,
|
|||
nm_device_reapply_async);
|
||||
|
||||
nmdbus_device_call_reapply (NM_DEVICE_GET_PRIVATE (device)->proxy,
|
||||
dict, flags, cancellable,
|
||||
dict, version_id, flags, cancellable,
|
||||
device_reapply_cb, simple);
|
||||
}
|
||||
|
||||
|
|
@ -2291,6 +2299,179 @@ nm_device_reapply_finish (NMDevice *device,
|
|||
return g_simple_async_result_get_op_res_gboolean (simple);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* nm_device_get_applied_connection:
|
||||
* @device: a #NMDevice
|
||||
* @flags: the flags argument. Currently this value must always be zero.
|
||||
* @version_id: (out): (allow-none): returns the current version id of
|
||||
* the applied connection
|
||||
* @cancellable: a #GCancellable, or %NULL
|
||||
* @error: location for a #GError, or %NULL
|
||||
*
|
||||
* Fetch the currently applied connection on the device.
|
||||
*
|
||||
* Returns: (transfer-full): a %NMConnection with the currently applied settings
|
||||
* or %NULL on error.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
NMConnection *
|
||||
nm_device_get_applied_connection (NMDevice *device,
|
||||
guint32 flags,
|
||||
guint64 *version_id,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gs_unref_variant GVariant *dict = NULL;
|
||||
guint64 my_version_id;
|
||||
gboolean success;
|
||||
NMConnection *connection;
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
|
||||
g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
|
||||
g_return_val_if_fail (!error || !*error, NULL);
|
||||
|
||||
success = nmdbus_device_call_get_applied_connection_sync (NM_DEVICE_GET_PRIVATE (device)->proxy,
|
||||
flags, &dict, &my_version_id, cancellable, error);
|
||||
if (!success) {
|
||||
if (error && *error)
|
||||
g_dbus_error_strip_remote_error (*error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
connection = nm_simple_connection_new_from_dbus (dict, error);
|
||||
if (!connection)
|
||||
return NULL;
|
||||
|
||||
NM_SET_OUT (version_id, my_version_id);
|
||||
return connection;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
NMConnection *connection;
|
||||
guint64 version_id;
|
||||
} GetAppliedConnectionData;
|
||||
|
||||
static void
|
||||
device_get_applied_connection_data_free (gpointer user_data)
|
||||
{
|
||||
GetAppliedConnectionData *data = user_data;
|
||||
|
||||
g_return_if_fail (data);
|
||||
|
||||
g_object_unref (data->connection);
|
||||
g_slice_free (GetAppliedConnectionData, data);
|
||||
}
|
||||
|
||||
static void
|
||||
device_get_applied_connection_cb (GObject *proxy,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
gs_unref_object GSimpleAsyncResult *simple = user_data;
|
||||
gs_unref_variant GVariant *dict = NULL;
|
||||
guint64 my_version_id;
|
||||
GError *error = NULL;
|
||||
NMConnection *connection;
|
||||
GetAppliedConnectionData *data;
|
||||
|
||||
if (!nmdbus_device_call_get_applied_connection_finish (NMDBUS_DEVICE (proxy), &dict, &my_version_id, result, &error)) {
|
||||
g_dbus_error_strip_remote_error (error);
|
||||
g_simple_async_result_take_error (simple, error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
connection = nm_simple_connection_new_from_dbus (dict, &error);
|
||||
if (!connection) {
|
||||
g_simple_async_result_take_error (simple, error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
data = g_slice_new (GetAppliedConnectionData);
|
||||
data->connection = connection;
|
||||
data->version_id = my_version_id;
|
||||
g_simple_async_result_set_op_res_gpointer (simple, data, device_get_applied_connection_data_free);
|
||||
|
||||
out:
|
||||
g_simple_async_result_complete (simple);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_device_get_applied_connection_async:
|
||||
* @device: a #NMDevice
|
||||
* @flags: the flags argument. Currently this value must always be zero.
|
||||
* @cancellable: a #GCancellable, or %NULL
|
||||
* @callback: callback to be called when the reapply operation completes
|
||||
* @user_data: caller-specific data passed to @callback
|
||||
*
|
||||
* Asynchronously begins an get the a currently applied connection.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
void
|
||||
nm_device_get_applied_connection_async (NMDevice *device,
|
||||
guint32 flags,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSimpleAsyncResult *simple;
|
||||
|
||||
g_return_if_fail (NM_IS_DEVICE (device));
|
||||
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
|
||||
|
||||
simple = g_simple_async_result_new (G_OBJECT (device), callback, user_data,
|
||||
nm_device_get_applied_connection_async);
|
||||
|
||||
nmdbus_device_call_get_applied_connection (NM_DEVICE_GET_PRIVATE (device)->proxy,
|
||||
flags, cancellable,
|
||||
device_get_applied_connection_cb, simple);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_device_get_applied_connection_finish:
|
||||
* @device: a #NMDevice
|
||||
* @result: the result passed to the #GAsyncReadyCallback
|
||||
* @version_id: (out): (allow-none): the current version id of the applied
|
||||
* connection.
|
||||
* @error: location for a #GError, or %NULL
|
||||
*
|
||||
* Gets the result of a call to nm_device_get_applied_connection_async().
|
||||
*
|
||||
* Returns: (transfer-full): a currently applied %NMConnection or %NULL in case
|
||||
* of error.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
NMConnection *
|
||||
nm_device_get_applied_connection_finish (NMDevice *device,
|
||||
GAsyncResult *result,
|
||||
guint64 *version_id,
|
||||
GError **error)
|
||||
{
|
||||
GSimpleAsyncResult *simple;
|
||||
GetAppliedConnectionData *data;
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
|
||||
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (device), nm_device_get_applied_connection_async), NULL);
|
||||
g_return_val_if_fail (!error || !*error, NULL);
|
||||
|
||||
simple = G_SIMPLE_ASYNC_RESULT (result);
|
||||
if (g_simple_async_result_propagate_error (simple, error))
|
||||
return NULL;
|
||||
|
||||
data = g_simple_async_result_get_op_res_gpointer (simple);
|
||||
g_return_val_if_fail (data, NULL);
|
||||
g_return_val_if_fail (NM_IS_CONNECTION (data->connection), NULL);
|
||||
|
||||
NM_SET_OUT (version_id, data->version_id);
|
||||
return g_object_ref (data->connection);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* nm_device_disconnect:
|
||||
* @device: a #NMDevice
|
||||
|
|
|
|||
|
|
@ -140,13 +140,15 @@ char ** nm_device_disambiguate_names (NMDevice **devices,
|
|||
NM_AVAILABLE_IN_1_2
|
||||
gboolean nm_device_reapply (NMDevice *device,
|
||||
NMConnection *connection,
|
||||
guint flags,
|
||||
guint64 version_id,
|
||||
guint32 flags,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
void nm_device_reapply_async (NMDevice *device,
|
||||
NMConnection *connection,
|
||||
guint flags,
|
||||
guint64 version_id,
|
||||
guint32 flags,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
|
|
@ -155,6 +157,24 @@ gboolean nm_device_reapply_finish (NMDevice *device,
|
|||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
NMConnection *nm_device_get_applied_connection (NMDevice *device,
|
||||
guint32 flags,
|
||||
guint64 *version_id,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
void nm_device_get_applied_connection_async (NMDevice *device,
|
||||
guint32 flags,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
NMConnection *nm_device_get_applied_connection_finish (NMDevice *device,
|
||||
GAsyncResult *result,
|
||||
guint64 *version_id,
|
||||
GError **error);
|
||||
|
||||
gboolean nm_device_disconnect (NMDevice *device,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
|
|
|||
|
|
@ -7162,6 +7162,8 @@ nm_device_reactivate_ip6_config (NMDevice *self,
|
|||
/* reapply_connection:
|
||||
* @connection: the new connection settings to be applied or %NULL to reapply
|
||||
* the current settings connection
|
||||
* @version_id: either zero, or the current version id for the applied
|
||||
* connection.
|
||||
* @error: the error if %FALSE is returned
|
||||
*
|
||||
* Change configuration of an already configured device if possible.
|
||||
|
|
@ -7172,6 +7174,7 @@ nm_device_reactivate_ip6_config (NMDevice *self,
|
|||
static gboolean
|
||||
reapply_connection (NMDevice *self,
|
||||
NMConnection *connection,
|
||||
guint64 version_id,
|
||||
GError **error)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
|
@ -7212,12 +7215,26 @@ reapply_connection (NMDevice *self,
|
|||
NM_SETTING_CONNECTION_METERED))
|
||||
return FALSE;
|
||||
|
||||
_LOGD (LOGD_DEVICE, "reapply");
|
||||
if ( version_id != 0
|
||||
&& version_id != nm_active_connection_version_id_get ((NMActiveConnection *) priv->act_request)) {
|
||||
g_set_error_literal (error,
|
||||
NM_DEVICE_ERROR,
|
||||
NM_DEVICE_ERROR_VERSION_ID_MISMATCH,
|
||||
"Reapply failed because device changed in the meantime and the version-id mismatches");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Update applied connection
|
||||
*************************************************************************/
|
||||
|
||||
if (diffs)
|
||||
nm_active_connection_version_id_bump ((NMActiveConnection *) priv->act_request);
|
||||
|
||||
_LOGD (LOGD_DEVICE, "reapply (version-id %llu%s)",
|
||||
(long long unsigned) nm_active_connection_version_id_get (((NMActiveConnection *) priv->act_request)),
|
||||
diffs ? "" : " (unmodified)");
|
||||
|
||||
if (diffs) {
|
||||
con_old = applied_clone = nm_simple_connection_new_clone (applied);
|
||||
con_new = applied;
|
||||
|
|
@ -7243,6 +7260,11 @@ reapply_connection (NMDevice *self,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
NMConnection *connection;
|
||||
guint64 version_id;
|
||||
} ReapplyData;
|
||||
|
||||
static void
|
||||
reapply_cb (NMDevice *self,
|
||||
GDBusMethodInvocation *context,
|
||||
|
|
@ -7250,9 +7272,17 @@ reapply_cb (NMDevice *self,
|
|||
GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
gs_unref_object NMConnection *connection = NM_CONNECTION (user_data);
|
||||
ReapplyData *reapply_data = user_data;
|
||||
guint64 version_id = 0;
|
||||
gs_unref_object NMConnection *connection = NULL;
|
||||
GError *local = NULL;
|
||||
|
||||
if (reapply_data) {
|
||||
connection = reapply_data->connection;
|
||||
version_id = reapply_data->version_id;
|
||||
g_slice_free (ReapplyData, reapply_data);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, subject, error->message);
|
||||
g_dbus_method_invocation_return_gerror (context, error);
|
||||
|
|
@ -7261,6 +7291,7 @@ reapply_cb (NMDevice *self,
|
|||
|
||||
if (!reapply_connection (self,
|
||||
connection ? : (NMConnection *) nm_device_get_settings_connection (self),
|
||||
version_id,
|
||||
&local)) {
|
||||
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, subject, local->message);
|
||||
g_dbus_method_invocation_take_error (context, local);
|
||||
|
|
@ -7275,17 +7306,19 @@ static void
|
|||
impl_device_reapply (NMDevice *self,
|
||||
GDBusMethodInvocation *context,
|
||||
GVariant *settings,
|
||||
guint flags)
|
||||
guint64 version_id,
|
||||
guint32 flags)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
NMSettingsConnection *settings_connection;
|
||||
NMConnection *connection = NULL;
|
||||
GError *error = NULL;
|
||||
ReapplyData *reapply_data;
|
||||
|
||||
/* No flags supported as of now. */
|
||||
if (flags != 0) {
|
||||
error = g_error_new_literal (NM_DEVICE_ERROR,
|
||||
NM_DEVICE_ERROR_NOT_ACTIVE,
|
||||
NM_DEVICE_ERROR_FAILED,
|
||||
"Invalid flags specified");
|
||||
nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, context, error->message);
|
||||
g_dbus_method_invocation_take_error (context, error);
|
||||
|
|
@ -7316,6 +7349,13 @@ impl_device_reapply (NMDevice *self,
|
|||
nm_connection_clear_secrets (connection);
|
||||
}
|
||||
|
||||
if (connection || version_id) {
|
||||
reapply_data = g_slice_new (ReapplyData);
|
||||
reapply_data->connection = connection;
|
||||
reapply_data->version_id = version_id;
|
||||
} else
|
||||
reapply_data = NULL;
|
||||
|
||||
/* Ask the manager to authenticate this request for us */
|
||||
g_signal_emit (self, signals[AUTH_REQUEST], 0,
|
||||
context,
|
||||
|
|
@ -7323,9 +7363,103 @@ impl_device_reapply (NMDevice *self,
|
|||
NM_AUTH_PERMISSION_NETWORK_CONTROL,
|
||||
TRUE,
|
||||
reapply_cb,
|
||||
connection);
|
||||
reapply_data);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
get_applied_connection_cb (NMDevice *self,
|
||||
GDBusMethodInvocation *context,
|
||||
NMAuthSubject *subject,
|
||||
GError *error,
|
||||
gpointer user_data /* possibly dangling pointer */)
|
||||
{
|
||||
NMDevicePrivate *priv;
|
||||
NMConnection *applied_connection;
|
||||
GVariant *settings;
|
||||
|
||||
g_return_if_fail (NM_IS_DEVICE (self));
|
||||
|
||||
if (error) {
|
||||
g_dbus_method_invocation_return_gerror (context, error);
|
||||
return;
|
||||
}
|
||||
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
applied_connection = nm_device_get_applied_connection (self);
|
||||
|
||||
if (!applied_connection) {
|
||||
error = g_error_new_literal (NM_DEVICE_ERROR,
|
||||
NM_DEVICE_ERROR_NOT_ACTIVE,
|
||||
"Device is not activated");
|
||||
g_dbus_method_invocation_take_error (context, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (applied_connection != user_data) {
|
||||
/* The applied connection changed due to a race. Reauthenticate. */
|
||||
g_signal_emit (self, signals[AUTH_REQUEST], 0,
|
||||
context,
|
||||
applied_connection,
|
||||
NM_AUTH_PERMISSION_NETWORK_CONTROL,
|
||||
TRUE,
|
||||
get_applied_connection_cb,
|
||||
applied_connection /* no need take a ref. We will not dereference this pointer. */);
|
||||
return;
|
||||
}
|
||||
|
||||
settings = nm_connection_to_dbus (applied_connection, NM_CONNECTION_SERIALIZE_NO_SECRETS);
|
||||
if (!settings)
|
||||
settings = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0);
|
||||
|
||||
g_dbus_method_invocation_return_value (context,
|
||||
g_variant_new ("(@a{sa{sv}}t)",
|
||||
settings,
|
||||
nm_active_connection_version_id_get ((NMActiveConnection *) priv->act_request)));
|
||||
}
|
||||
|
||||
static void
|
||||
impl_device_get_applied_connection (NMDevice *self,
|
||||
GDBusMethodInvocation *context,
|
||||
guint32 flags)
|
||||
{
|
||||
NMConnection *applied_connection;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_if_fail (NM_IS_DEVICE (self));
|
||||
|
||||
/* No flags supported as of now. */
|
||||
if (flags != 0) {
|
||||
error = g_error_new_literal (NM_DEVICE_ERROR,
|
||||
NM_DEVICE_ERROR_FAILED,
|
||||
"Invalid flags specified");
|
||||
g_dbus_method_invocation_take_error (context, error);
|
||||
return;
|
||||
}
|
||||
|
||||
applied_connection = nm_device_get_applied_connection (self);
|
||||
if (!applied_connection) {
|
||||
error = g_error_new_literal (NM_DEVICE_ERROR,
|
||||
NM_DEVICE_ERROR_NOT_ACTIVE,
|
||||
"Device is not activated");
|
||||
g_dbus_method_invocation_take_error (context, error);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ask the manager to authenticate this request for us */
|
||||
g_signal_emit (self, signals[AUTH_REQUEST], 0,
|
||||
context,
|
||||
applied_connection,
|
||||
NM_AUTH_PERMISSION_NETWORK_CONTROL,
|
||||
TRUE,
|
||||
get_applied_connection_cb,
|
||||
applied_connection /* no need take a ref. We will not dereference this pointer. */);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
disconnect_cb (NMDevice *self,
|
||||
GDBusMethodInvocation *context,
|
||||
|
|
@ -9218,6 +9352,7 @@ nm_device_reapply_settings_immediately (NMDevice *self)
|
|||
NMSettingConnection *s_con_applied;
|
||||
const char *zone;
|
||||
NMMetered metered;
|
||||
guint64 version_id;
|
||||
|
||||
g_return_if_fail (NM_IS_DEVICE (self));
|
||||
|
||||
|
|
@ -9240,7 +9375,8 @@ nm_device_reapply_settings_immediately (NMDevice *self)
|
|||
if (g_strcmp0 ((zone = nm_setting_connection_get_zone (s_con_settings)),
|
||||
nm_setting_connection_get_zone (s_con_applied)) != 0) {
|
||||
|
||||
_LOGD (LOGD_DEVICE, "reapply setting: zone = %s%s%s", NM_PRINT_FMT_QUOTE_STRING (zone));
|
||||
version_id = nm_active_connection_version_id_bump ((NMActiveConnection *) self->priv->act_request);
|
||||
_LOGD (LOGD_DEVICE, "reapply setting: zone = %s%s%s (version-id %llu)", NM_PRINT_FMT_QUOTE_STRING (zone), (long long unsigned) version_id);
|
||||
|
||||
g_object_set (G_OBJECT (s_con_applied),
|
||||
NM_SETTING_CONNECTION_ZONE, zone,
|
||||
|
|
@ -9251,7 +9387,8 @@ nm_device_reapply_settings_immediately (NMDevice *self)
|
|||
|
||||
if ((metered = nm_setting_connection_get_metered (s_con_settings)) != nm_setting_connection_get_metered (s_con_applied)) {
|
||||
|
||||
_LOGD (LOGD_DEVICE, "reapply setting: metered = %d", (int) metered);
|
||||
version_id = nm_active_connection_version_id_bump ((NMActiveConnection *) self->priv->act_request);
|
||||
_LOGD (LOGD_DEVICE, "reapply setting: metered = %d (version-id %llu)", (int) metered, (long long unsigned) version_id);
|
||||
|
||||
g_object_set (G_OBJECT (s_con_applied),
|
||||
NM_SETTING_CONNECTION_METERED, metered,
|
||||
|
|
@ -11681,6 +11818,7 @@ nm_device_class_init (NMDeviceClass *klass)
|
|||
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass),
|
||||
NMDBUS_TYPE_DEVICE_SKELETON,
|
||||
"Reapply", impl_device_reapply,
|
||||
"GetAppliedConnection", impl_device_get_applied_connection,
|
||||
"Disconnect", impl_device_disconnect,
|
||||
"Delete", impl_device_delete,
|
||||
NULL);
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ typedef struct {
|
|||
char *specific_object;
|
||||
NMDevice *device;
|
||||
|
||||
guint64 version_id;
|
||||
|
||||
char *pending_activation_id;
|
||||
|
||||
gboolean is_default;
|
||||
|
|
@ -796,10 +798,45 @@ nm_active_connection_authorize (NMActiveConnection *self,
|
|||
|
||||
/****************************************************************/
|
||||
|
||||
static guint64
|
||||
_version_id_new (void)
|
||||
{
|
||||
static guint64 id = 0;
|
||||
|
||||
return ++id;
|
||||
}
|
||||
|
||||
guint64
|
||||
nm_active_connection_version_id_get (NMActiveConnection *self)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), 0);
|
||||
|
||||
return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->version_id;
|
||||
}
|
||||
|
||||
guint64
|
||||
nm_active_connection_version_id_bump (NMActiveConnection *self)
|
||||
{
|
||||
NMActiveConnectionPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), 0);
|
||||
|
||||
priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
|
||||
priv->version_id = _version_id_new ();
|
||||
_LOGT ("new version-id %llu", (long long unsigned) priv->version_id);
|
||||
return priv->version_id;
|
||||
}
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
static void
|
||||
nm_active_connection_init (NMActiveConnection *self)
|
||||
{
|
||||
NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
|
||||
|
||||
_LOGT ("creating");
|
||||
|
||||
priv->version_id = _version_id_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -810,7 +847,7 @@ constructed (GObject *object)
|
|||
|
||||
G_OBJECT_CLASS (nm_active_connection_parent_class)->constructed (object);
|
||||
|
||||
_LOGD ("constructed (%s)", G_OBJECT_TYPE_NAME (self));
|
||||
_LOGD ("constructed (%s, version-id %llu)", G_OBJECT_TYPE_NAME (self), (long long unsigned) priv->version_id);
|
||||
|
||||
g_return_if_fail (priv->subject);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,6 +83,9 @@ typedef struct {
|
|||
NMMetered new_value);
|
||||
} NMActiveConnectionClass;
|
||||
|
||||
guint64 nm_active_connection_version_id_get (NMActiveConnection *self);
|
||||
guint64 nm_active_connection_version_id_bump (NMActiveConnection *self);
|
||||
|
||||
GType nm_active_connection_get_type (void);
|
||||
|
||||
typedef void (*NMActiveConnectionAuthResultFunc) (NMActiveConnection *self,
|
||||
|
|
|
|||
|
|
@ -1716,10 +1716,10 @@ get_update_modify_permission (NMConnection *old, NMConnection *new)
|
|||
}
|
||||
|
||||
static void
|
||||
impl_settings_connection_update_helper (NMSettingsConnection *self,
|
||||
GDBusMethodInvocation *context,
|
||||
GVariant *new_settings,
|
||||
gboolean save_to_disk)
|
||||
settings_connection_update_helper (NMSettingsConnection *self,
|
||||
GDBusMethodInvocation *context,
|
||||
GVariant *new_settings,
|
||||
gboolean save_to_disk)
|
||||
{
|
||||
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
|
||||
NMAuthSubject *subject = NULL;
|
||||
|
|
@ -1790,7 +1790,7 @@ impl_settings_connection_update (NMSettingsConnection *self,
|
|||
GDBusMethodInvocation *context,
|
||||
GVariant *new_settings)
|
||||
{
|
||||
impl_settings_connection_update_helper (self, context, new_settings, TRUE);
|
||||
settings_connection_update_helper (self, context, new_settings, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1798,7 +1798,7 @@ impl_settings_connection_update_unsaved (NMSettingsConnection *self,
|
|||
GDBusMethodInvocation *context,
|
||||
GVariant *new_settings)
|
||||
{
|
||||
impl_settings_connection_update_helper (self, context, new_settings, FALSE);
|
||||
settings_connection_update_helper (self, context, new_settings, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1807,7 +1807,7 @@ impl_settings_connection_save (NMSettingsConnection *self,
|
|||
{
|
||||
/* Do nothing if the connection is already synced with disk */
|
||||
if (nm_settings_connection_get_unsaved (self))
|
||||
impl_settings_connection_update_helper (self, context, NULL, TRUE);
|
||||
settings_connection_update_helper (self, context, NULL, TRUE);
|
||||
else
|
||||
g_dbus_method_invocation_return_value (context, NULL);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue