From 2d668d763e57a70dddb4683a00bcb7a961286cd7 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Wed, 6 Mar 2013 10:10:21 -0500 Subject: [PATCH] libnm-util: add NMSettingConnection:interface-name https://bugzilla.gnome.org/show_bug.cgi?id=693684 --- libnm-util/libnm-util.ver | 1 + libnm-util/nm-setting-connection.c | 81 ++++++++++++++++++++++++++++++ libnm-util/nm-setting-connection.h | 24 +++++---- libnm-util/tests/test-general.c | 23 +++++---- 4 files changed, 107 insertions(+), 22 deletions(-) diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index a03d836c68..b53dbd6a88 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -241,6 +241,7 @@ global: nm_setting_connection_get_autoconnect; nm_setting_connection_get_connection_type; nm_setting_connection_get_id; + nm_setting_connection_get_interface_name; nm_setting_connection_get_master; nm_setting_connection_get_num_permissions; nm_setting_connection_get_num_secondaries; diff --git a/libnm-util/nm-setting-connection.c b/libnm-util/nm-setting-connection.c index 4dafb2b11f..16c3e73bf4 100644 --- a/libnm-util/nm-setting-connection.c +++ b/libnm-util/nm-setting-connection.c @@ -82,6 +82,7 @@ typedef struct { typedef struct { char *id; char *uuid; + char *interface_name; char *type; char *master; char *slave_type; @@ -97,6 +98,7 @@ enum { PROP_0, PROP_ID, PROP_UUID, + PROP_INTERFACE_NAME, PROP_TYPE, PROP_PERMISSIONS, PROP_AUTOCONNECT, @@ -237,6 +239,22 @@ nm_setting_connection_get_uuid (NMSettingConnection *setting) return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->uuid; } +/** + * nm_setting_connection_get_interface_name: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:interface-name property of the connection. + * + * Returns: the connection's interface name + **/ +const char * +nm_setting_connection_get_interface_name (NMSettingConnection *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NULL); + + return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->interface_name; +} + /** * nm_setting_connection_get_connection_type: * @setting: the #NMSettingConnection @@ -647,6 +665,7 @@ static gboolean verify (NMSetting *setting, GSList *all_settings, GError **error) { NMSettingConnectionPrivate *priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); + GSList *iter; if (!priv->id) { g_set_error_literal (error, @@ -681,6 +700,38 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return FALSE; } + /* If the connection has a virtual interface name, it must match + * the connection setting's interface name. + */ + for (iter = all_settings; iter; iter = iter->next) { + const char *virtual_iface; + + virtual_iface = nm_setting_get_virtual_iface_name (iter->data); + if (virtual_iface) { + if (priv->interface_name) { + if (strcmp (priv->interface_name, virtual_iface) != 0) { + g_set_error (error, + NM_SETTING_CONNECTION_ERROR, + NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY, + NM_SETTING_CONNECTION_INTERFACE_NAME); + return FALSE; + } + } else + priv->interface_name = g_strdup (virtual_iface); + break; + } + } + + if (priv->interface_name) { + if (!nm_utils_iface_valid_name (priv->interface_name)) { + g_set_error (error, + NM_SETTING_CONNECTION_ERROR, + NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY, + NM_SETTING_CONNECTION_INTERFACE_NAME); + return FALSE; + } + } + if (!priv->type) { g_set_error_literal (error, NM_SETTING_CONNECTION_ERROR, @@ -781,6 +832,7 @@ finalize (GObject *object) g_free (priv->id); g_free (priv->uuid); + g_free (priv->interface_name); g_free (priv->type); g_free (priv->zone); g_free (priv->master); @@ -821,6 +873,10 @@ set_property (GObject *object, guint prop_id, g_free (priv->uuid); priv->uuid = g_value_dup_string (value); break; + case PROP_INTERFACE_NAME: + g_free (priv->interface_name); + priv->interface_name = g_value_dup_string (value); + break; case PROP_TYPE: g_free (priv->type); priv->type = g_value_dup_string (value); @@ -884,6 +940,9 @@ get_property (GObject *object, guint prop_id, case PROP_UUID: g_value_set_string (value, nm_setting_connection_get_uuid (setting)); break; + case PROP_INTERFACE_NAME: + g_value_set_string (value, nm_setting_connection_get_interface_name (setting)); + break; case PROP_TYPE: g_value_set_string (value, nm_setting_connection_get_connection_type (setting)); break; @@ -983,6 +1042,28 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_FUZZY_IGNORE)); + /** + * NMSettingConnection:interface-name: + * + * The name of the network interface this connection is bound to. If + * not set, then the connection can be attached to any interface of the + * appropriate type (subject to restrictions imposed by other settings). + * + * For connection types where interface names cannot easily be + * made persistent (eg, mobile broadband or USB ethernet), this + * property should not be used. Setting this property restricts + * the interfaces a connection can be used with, and if interface + * names change or are reordered the connection may be applied to + * the wrong interface. + **/ + g_object_class_install_property + (object_class, PROP_INTERFACE_NAME, + g_param_spec_string (NM_SETTING_CONNECTION_INTERFACE_NAME, + "Interface name", + "Interface name to be bound to, or NULL", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + /** * NMSettingConnection:type: * diff --git a/libnm-util/nm-setting-connection.h b/libnm-util/nm-setting-connection.h index 73c598cb9a..fd6f30d087 100644 --- a/libnm-util/nm-setting-connection.h +++ b/libnm-util/nm-setting-connection.h @@ -68,17 +68,18 @@ typedef enum #define NM_SETTING_CONNECTION_ERROR nm_setting_connection_error_quark () GQuark nm_setting_connection_error_quark (void); -#define NM_SETTING_CONNECTION_ID "id" -#define NM_SETTING_CONNECTION_UUID "uuid" -#define NM_SETTING_CONNECTION_TYPE "type" -#define NM_SETTING_CONNECTION_AUTOCONNECT "autoconnect" -#define NM_SETTING_CONNECTION_TIMESTAMP "timestamp" -#define NM_SETTING_CONNECTION_READ_ONLY "read-only" -#define NM_SETTING_CONNECTION_PERMISSIONS "permissions" -#define NM_SETTING_CONNECTION_ZONE "zone" -#define NM_SETTING_CONNECTION_MASTER "master" -#define NM_SETTING_CONNECTION_SLAVE_TYPE "slave-type" -#define NM_SETTING_CONNECTION_SECONDARIES "secondaries" +#define NM_SETTING_CONNECTION_ID "id" +#define NM_SETTING_CONNECTION_UUID "uuid" +#define NM_SETTING_CONNECTION_INTERFACE_NAME "interface-name" +#define NM_SETTING_CONNECTION_TYPE "type" +#define NM_SETTING_CONNECTION_AUTOCONNECT "autoconnect" +#define NM_SETTING_CONNECTION_TIMESTAMP "timestamp" +#define NM_SETTING_CONNECTION_READ_ONLY "read-only" +#define NM_SETTING_CONNECTION_PERMISSIONS "permissions" +#define NM_SETTING_CONNECTION_ZONE "zone" +#define NM_SETTING_CONNECTION_MASTER "master" +#define NM_SETTING_CONNECTION_SLAVE_TYPE "slave-type" +#define NM_SETTING_CONNECTION_SECONDARIES "secondaries" /** * NMSettingConnection: @@ -105,6 +106,7 @@ GType nm_setting_connection_get_type (void); NMSetting * nm_setting_connection_new (void); const char *nm_setting_connection_get_id (NMSettingConnection *setting); const char *nm_setting_connection_get_uuid (NMSettingConnection *setting); +const char *nm_setting_connection_get_interface_name (NMSettingConnection *setting); const char *nm_setting_connection_get_connection_type (NMSettingConnection *setting); gboolean nm_setting_connection_get_autoconnect (NMSettingConnection *setting); guint64 nm_setting_connection_get_timestamp (NMSettingConnection *setting); diff --git a/libnm-util/tests/test-general.c b/libnm-util/tests/test-general.c index c67a4c0f53..f3d28e8965 100644 --- a/libnm-util/tests/test-general.c +++ b/libnm-util/tests/test-general.c @@ -865,17 +865,18 @@ test_connection_diff_a_only (void) gboolean same; const DiffSetting settings[] = { { NM_SETTING_CONNECTION_SETTING_NAME, { - { NM_SETTING_CONNECTION_ID, NM_SETTING_DIFF_RESULT_IN_A }, - { NM_SETTING_CONNECTION_UUID, NM_SETTING_DIFF_RESULT_IN_A }, - { NM_SETTING_CONNECTION_TYPE, NM_SETTING_DIFF_RESULT_IN_A }, - { NM_SETTING_CONNECTION_TIMESTAMP, NM_SETTING_DIFF_RESULT_IN_A }, - { NM_SETTING_CONNECTION_AUTOCONNECT, NM_SETTING_DIFF_RESULT_IN_A }, - { NM_SETTING_CONNECTION_READ_ONLY, NM_SETTING_DIFF_RESULT_IN_A }, - { NM_SETTING_CONNECTION_PERMISSIONS, NM_SETTING_DIFF_RESULT_IN_A }, - { NM_SETTING_CONNECTION_ZONE, NM_SETTING_DIFF_RESULT_IN_A }, - { NM_SETTING_CONNECTION_MASTER, NM_SETTING_DIFF_RESULT_IN_A }, - { NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_DIFF_RESULT_IN_A }, - { NM_SETTING_CONNECTION_SECONDARIES, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_ID, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_UUID, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_INTERFACE_NAME, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_TYPE, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_TIMESTAMP, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_AUTOCONNECT, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_READ_ONLY, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_PERMISSIONS, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_ZONE, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_MASTER, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_SLAVE_TYPE, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_SECONDARIES, NM_SETTING_DIFF_RESULT_IN_A }, { NULL, NM_SETTING_DIFF_RESULT_UNKNOWN } } }, { NM_SETTING_WIRED_SETTING_NAME, {