diff options
author | Thomas Haller <thaller@redhat.com> | 2018-04-10 11:45:35 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2018-08-08 11:24:29 +0200 |
commit | 55ae69233dc1192738ebc4d27b5ff61876353eb6 (patch) | |
tree | ec3551a96db4b3846e4edde53ab3d0b8e6d05324 /libnm-core | |
parent | 2ead94d5f9f57542dd1612cdd36c38b46b39c5bf (diff) | |
download | NetworkManager-55ae69233dc1192738ebc4d27b5ff61876353eb6.tar.gz |
all: add connection.multi-connect property for wildcard profiles
Add a new option that allows to activate a profile multiple times
(at the same time). Previoulsy, all profiles were implicitly
NM_SETTING_CONNECTION_MULTI_CONNECT_SINGLE, meaning, that activating
a profile that is already active will deactivate it first.
This will make more sense, as we also add more match-options how
profiles can be restricted to particular devices. We already have
connection.type, connection.interface-name, and (ethernet|wifi).mac-address
to restrict a profile to particular devices. For example, it is however
not possible to specify a wildcard like "eth*" to match a profile to
a set of devices by interface-name. That is another missing feature,
and once we extend the matching capabilities, it makes more sense to
activate a profile multiple times.
See also https://bugzilla.redhat.com/show_bug.cgi?id=997998, which
previously changed that a connection is restricted to a single activation
at a time. This work relaxes that again.
This only adds the new property, it is not used nor implemented yet.
https://bugzilla.redhat.com/show_bug.cgi?id=1555012
Diffstat (limited to 'libnm-core')
-rw-r--r-- | libnm-core/nm-connection.c | 26 | ||||
-rw-r--r-- | libnm-core/nm-core-internal.h | 2 | ||||
-rw-r--r-- | libnm-core/nm-dbus-interface.h | 24 | ||||
-rw-r--r-- | libnm-core/nm-setting-connection.c | 61 | ||||
-rw-r--r-- | libnm-core/nm-setting-connection.h | 3 | ||||
-rw-r--r-- | libnm-core/nm-setting-vpn.c | 11 | ||||
-rw-r--r-- | libnm-core/tests/test-general.c | 1 |
7 files changed, 128 insertions, 0 deletions
diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c index 9e2e801444..a5df08142f 100644 --- a/libnm-core/nm-connection.c +++ b/libnm-core/nm-connection.c @@ -2081,6 +2081,32 @@ nm_connection_get_interface_name (NMConnection *connection) return s_con ? nm_setting_connection_get_interface_name (s_con) : NULL; } +NMConnectionMultiConnect +_nm_connection_get_multi_connect (NMConnection *connection) +{ + NMSettingConnection *s_con; + NMConnectionMultiConnect multi_connect; + const NMConnectionMultiConnect DEFAULT = NM_CONNECTION_MULTI_CONNECT_SINGLE; + + /* connection.multi_connect property cannot be specified via regular + * connection defaults in NetworkManager.conf, because those are per-device, + * and we need to determine the multi_connect independent of a particular + * device. + * + * There is however still a default-value, so theoretically, the default + * value could be specified in NetworkManager.conf. Just not as [connection*] + * and indepdented of a device. */ + + s_con = nm_connection_get_setting_connection (connection); + if (!s_con) + return DEFAULT; + + multi_connect = nm_setting_connection_get_multi_connect (s_con); + return multi_connect == NM_CONNECTION_MULTI_CONNECT_DEFAULT + ? DEFAULT + : multi_connect; +} + gboolean _nm_connection_verify_required_interface_name (NMConnection *connection, GError **error) diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index 4945118ffd..38caa66ff9 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -437,6 +437,8 @@ _nm_connection_get_uuid (NMConnection *connection) return connection ? nm_connection_get_uuid (connection) : NULL; } +NMConnectionMultiConnect _nm_connection_get_multi_connect (NMConnection *connection); + /*****************************************************************************/ typedef enum { diff --git a/libnm-core/nm-dbus-interface.h b/libnm-core/nm-dbus-interface.h index 507e3851b7..4e12dc63a2 100644 --- a/libnm-core/nm-dbus-interface.h +++ b/libnm-core/nm-dbus-interface.h @@ -656,6 +656,30 @@ typedef enum { } NMMetered; /** + * NMConnectionMultiConnect: + * @NM_CONNECTION_MULTI_CONNECT_DEFAULT: indicates that the per-connection + * setting is unspecified. In this case, it will fallback to the default + * value, which is @NM_CONNECTION_MULTI_CONNECT_SINGLE. + * @NM_CONNECTION_MULTI_CONNECT_SINGLE: the connection profile can only + * be active once at each moment. Activating a profile that is already active, + * will first deactivate it. + * @NM_CONNECTION_MULTI_CONNECT_MANUAL_MULTIPLE: the profile can + * be manually activated multiple times on different devices. However, + * regarding autoconnect, the profile will autoconnect only if it is + * currently not connected otherwise. + * @NM_CONNECTION_MULTI_CONNECT_MULTIPLE: the profile can autoactivate + * and be manually activated multiple times together. + * + * Since: 1.14 + */ +typedef enum { + NM_CONNECTION_MULTI_CONNECT_DEFAULT = 0, + NM_CONNECTION_MULTI_CONNECT_SINGLE = 1, + NM_CONNECTION_MULTI_CONNECT_MANUAL_MULTIPLE = 2, + NM_CONNECTION_MULTI_CONNECT_MULTIPLE = 3, +} NMConnectionMultiConnect; + +/** * NMActiveConnectionState: * @NM_ACTIVE_CONNECTION_STATE_UNKNOWN: the state of the connection is unknown * @NM_ACTIVE_CONNECTION_STATE_ACTIVATING: a network connection is being prepared diff --git a/libnm-core/nm-setting-connection.c b/libnm-core/nm-setting-connection.c index 88aa28dd6e..c4190831b1 100644 --- a/libnm-core/nm-setting-connection.c +++ b/libnm-core/nm-setting-connection.c @@ -72,6 +72,7 @@ typedef struct { gboolean autoconnect; int autoconnect_priority; int autoconnect_retries; + int multi_connect; guint64 timestamp; gboolean read_only; char *zone; @@ -93,6 +94,7 @@ enum { PROP_AUTOCONNECT, PROP_AUTOCONNECT_PRIORITY, PROP_AUTOCONNECT_RETRIES, + PROP_MULTI_CONNECT, PROP_TIMESTAMP, PROP_READ_ONLY, PROP_ZONE, @@ -555,6 +557,22 @@ nm_setting_connection_get_autoconnect_retries (NMSettingConnection *setting) } /** + * nm_setting_connection_get_multi_connect: + * @setting: the #NMSettingConnection + * + * Returns: the #NMSettingConnection:multi-connect property of the connection. + * + * Since: 1.14 + **/ +NMConnectionMultiConnect +nm_setting_connection_get_multi_connect (NMSettingConnection *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), -1); + + return (NMConnectionMultiConnect) NM_SETTING_CONNECTION_GET_PRIVATE (setting)->multi_connect; +} + +/** * nm_setting_connection_get_auth_retries: * @setting: the #NMSettingConnection * @@ -1087,6 +1105,19 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } + if (!NM_IN_SET (priv->multi_connect, (int) NM_CONNECTION_MULTI_CONNECT_DEFAULT, + (int) NM_CONNECTION_MULTI_CONNECT_SINGLE, + (int) NM_CONNECTION_MULTI_CONNECT_MANUAL_MULTIPLE, + (int) NM_CONNECTION_MULTI_CONNECT_MULTIPLE)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("value %d is not valid"), priv->multi_connect); + g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_MULTI_CONNECT); + return FALSE; + } + /* *** errors above here should be always fatal, below NORMALIZABLE_ERROR *** */ if (!priv->uuid) { @@ -1328,6 +1359,9 @@ set_property (GObject *object, guint prop_id, case PROP_AUTOCONNECT_RETRIES: priv->autoconnect_retries = g_value_get_int (value); break; + case PROP_MULTI_CONNECT: + priv->multi_connect = g_value_get_int (value); + break; case PROP_TIMESTAMP: priv->timestamp = g_value_get_uint64 (value); break; @@ -1423,6 +1457,9 @@ get_property (GObject *object, guint prop_id, case PROP_AUTOCONNECT_RETRIES: g_value_set_int (value, nm_setting_connection_get_autoconnect_retries (setting)); break; + case PROP_MULTI_CONNECT: + g_value_set_int (value, priv->multi_connect); + break; case PROP_TIMESTAMP: g_value_set_uint64 (value, nm_setting_connection_get_timestamp (setting)); break; @@ -1765,6 +1802,30 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) G_PARAM_STATIC_STRINGS)); /** + * NMSettingConnection:multi-connect: + * + * Specifies whether the profile can be active multiple times at a particular + * moment. The value is of type #NMConnectionMultiConnect. + * + * Since: 1.14 + */ + /* ---ifcfg-rh--- + * property: multi-connect + * variable: MULTI_CONNECT(+) + * description: whether the profile can be active on multiple devices at a given + * moment. The values are numbers corresponding to #NMConnectionMultiConnect enum. + * example: ZONE=3 + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_MULTI_CONNECT, + g_param_spec_int (NM_SETTING_CONNECTION_MULTI_CONNECT, "", "", + G_MININT32, G_MAXINT32, NM_CONNECTION_MULTI_CONNECT_DEFAULT, + G_PARAM_READWRITE | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + + /** * NMSettingConnection:timestamp: * * The time, in seconds since the Unix Epoch, that the connection was last diff --git a/libnm-core/nm-setting-connection.h b/libnm-core/nm-setting-connection.h index c3ec1a6dab..ab20cefd96 100644 --- a/libnm-core/nm-setting-connection.h +++ b/libnm-core/nm-setting-connection.h @@ -52,6 +52,7 @@ G_BEGIN_DECLS #define NM_SETTING_CONNECTION_AUTOCONNECT "autoconnect" #define NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY "autoconnect-priority" #define NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES "autoconnect-retries" +#define NM_SETTING_CONNECTION_MULTI_CONNECT "multi-connect" #define NM_SETTING_CONNECTION_TIMESTAMP "timestamp" #define NM_SETTING_CONNECTION_READ_ONLY "read-only" #define NM_SETTING_CONNECTION_PERMISSIONS "permissions" @@ -145,6 +146,8 @@ gboolean nm_setting_connection_get_autoconnect (NMSettingConnection *set int nm_setting_connection_get_autoconnect_priority (NMSettingConnection *setting); NM_AVAILABLE_IN_1_6 int nm_setting_connection_get_autoconnect_retries (NMSettingConnection *setting); +NM_AVAILABLE_IN_1_14 +NMConnectionMultiConnect nm_setting_connection_get_multi_connect (NMSettingConnection *setting); guint64 nm_setting_connection_get_timestamp (NMSettingConnection *setting); gboolean nm_setting_connection_get_read_only (NMSettingConnection *setting); diff --git a/libnm-core/nm-setting-vpn.c b/libnm-core/nm-setting-vpn.c index 66c902045d..d36ce93485 100644 --- a/libnm-core/nm-setting-vpn.c +++ b/libnm-core/nm-setting-vpn.c @@ -480,6 +480,7 @@ static gboolean verify (NMSetting *setting, NMConnection *connection, GError **error) { NMSettingVpnPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); + NMSettingConnection *s_con; if (!priv->service_type) { g_set_error_literal (error, @@ -509,6 +510,16 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } + if ( connection + && (s_con = nm_connection_get_setting_connection (connection)) + && nm_setting_connection_get_multi_connect (s_con) != NM_CONNECTION_MULTI_CONNECT_DEFAULT) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("cannot set connection.multi-connect for VPN setting")); + return FALSE; + } + return TRUE; } diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index 093ebf55a8..e4a9e8f952 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -2595,6 +2595,7 @@ test_connection_diff_a_only (void) { NM_SETTING_CONNECTION_AUTOCONNECT, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY, NM_SETTING_DIFF_RESULT_IN_A }, { NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES, NM_SETTING_DIFF_RESULT_IN_A }, + { NM_SETTING_CONNECTION_MULTI_CONNECT, 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 }, |