summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2016-02-11 09:18:35 +0100
committerThomas Haller <thaller@redhat.com>2016-02-16 11:24:49 +0100
commit62910d19d731a7cce0cf3acd9268720f74bb6e32 (patch)
tree7846a0c8a2e8803db2ad910782e62bbf3e3e2db9
parent6898e2169e2fc2ca9d938208ad84a112ccb3f23e (diff)
downloadNetworkManager-62910d19d731a7cce0cf3acd9268720f74bb6e32.tar.gz
core: add NMDevice's GetAppliedConnection D-Bus call
Expose applied connection in D-Bus API. https://bugzilla.gnome.org/show_bug.cgi?id=760884
-rw-r--r--introspection/nm-device.xml65
-rw-r--r--src/devices/nm-device.c95
2 files changed, 151 insertions, 9 deletions
diff --git a/introspection/nm-device.xml b/introspection/nm-device.xml
index eada289f28..f1033c73f2 100644
--- a/introspection/nm-device.xml
+++ b/introspection/nm-device.xml
@@ -172,15 +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.
- This optional argument allows to catch concurrent modifications when
- reapplying the currently applied connection with modifications.
+ 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">
@@ -190,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>
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 5d9903dc91..f20a0fc581 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -7366,6 +7366,100 @@ impl_device_reapply (NMDevice *self,
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,
@@ -11724,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);