summaryrefslogtreecommitdiff
path: root/libnm-core
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2018-04-10 11:45:35 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2018-08-08 11:24:29 +0200
commit55ae69233dc1192738ebc4d27b5ff61876353eb6 (patch)
treeec3551a96db4b3846e4edde53ab3d0b8e6d05324 /libnm-core
parent2ead94d5f9f57542dd1612cdd36c38b46b39c5bf (diff)
downloadNetworkManager-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.c26
-rw-r--r--libnm-core/nm-core-internal.h2
-rw-r--r--libnm-core/nm-dbus-interface.h24
-rw-r--r--libnm-core/nm-setting-connection.c61
-rw-r--r--libnm-core/nm-setting-connection.h3
-rw-r--r--libnm-core/nm-setting-vpn.c11
-rw-r--r--libnm-core/tests/test-general.c1
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 },