From 884040fa8f7ef6c9f1f46ae0d96a751c4bc6f9ad Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 24 Sep 2014 10:17:50 +0200 Subject: [PATCH 01/13] nmtst: improve nmtst_assert_connection_verifies_without_normalization() If the assertion in verifies_without_normalization() fails due to @was_modified, the error message is not helpful. Assert first against the content of the connection. This prints most likely the settings that were actually modified. Signed-off-by: Thomas Haller --- include/nm-test-utils.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/nm-test-utils.h b/include/nm-test-utils.h index e296df044b..12e84b3393 100644 --- a/include/nm-test-utils.h +++ b/include/nm-test-utils.h @@ -871,9 +871,8 @@ nmtst_assert_connection_verifies_without_normalization (NMConnection *con) success = nm_connection_normalize (con, NULL, &was_modified, &error); g_assert_no_error (error); g_assert (success); - g_assert (!was_modified); - nmtst_assert_connection_equals (con, FALSE, clone, FALSE); + g_assert (!was_modified); } inline static void From b145700656a244c0550178132edb069e14f9413f Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 26 Aug 2014 15:31:06 +0200 Subject: [PATCH 02/13] libnm: make @copy_func argument in _nm_utils_copy_strdict() optional Signed-off-by: Thomas Haller --- libnm-core/nm-utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index f1e592f535..913ba4b4df 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -552,7 +552,7 @@ _nm_utils_copy_slist_to_array (const GSList *list, array = g_ptr_array_new_with_free_func (unref_func); for (iter = list; iter; iter = iter->next) - g_ptr_array_add (array, copy_func (iter->data)); + g_ptr_array_add (array, copy_func ? copy_func (iter->data) : iter->data); return array; } From 24a2f9c6cd4eb644405991570c629e2b73ee2ff8 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 25 Aug 2014 20:39:40 +0200 Subject: [PATCH 03/13] libnm: add NMSettingConnection:autoconnect-priority setting The autoconnect priority has only any relevance, if the connection is autoconnect too. The priority defaults to zero, with higher numbers meaning preferred. The valid range is limited to [-999,999]. Signed-off-by: Thomas Haller --- libnm-core/nm-setting-connection.c | 43 ++++++++++++++++++++++++++++++ libnm-core/nm-setting-connection.h | 6 +++++ libnm-core/tests/test-general.c | 1 + libnm/libnm.ver | 1 + 4 files changed, 51 insertions(+) diff --git a/libnm-core/nm-setting-connection.c b/libnm-core/nm-setting-connection.c index e6b537122a..890f77d1cc 100644 --- a/libnm-core/nm-setting-connection.c +++ b/libnm-core/nm-setting-connection.c @@ -80,6 +80,7 @@ typedef struct { char *slave_type; GSList *permissions; /* list of Permission structs */ gboolean autoconnect; + gint autoconnect_priority; guint64 timestamp; gboolean read_only; char *zone; @@ -95,6 +96,7 @@ enum { PROP_TYPE, PROP_PERMISSIONS, PROP_AUTOCONNECT, + PROP_AUTOCONNECT_PRIORITY, PROP_TIMESTAMP, PROP_READ_ONLY, PROP_ZONE, @@ -497,6 +499,23 @@ nm_setting_connection_get_autoconnect (NMSettingConnection *setting) return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->autoconnect; } +/** + * nm_setting_connection_get_autoconnect_priority: + * @setting: the #NMSettingConnection + * + * Returns the #NMSettingConnection:autoconnect-priority property of the connection. + * The higher number, the higher priority. + * + * Returns: the connection's autoconnect priority + **/ +gint +nm_setting_connection_get_autoconnect_priority (NMSettingConnection *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), 0); + + return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->autoconnect_priority; +} + /** * nm_setting_connection_get_timestamp: * @setting: the #NMSettingConnection @@ -1094,6 +1113,9 @@ set_property (GObject *object, guint prop_id, case PROP_AUTOCONNECT: priv->autoconnect = g_value_get_boolean (value); break; + case PROP_AUTOCONNECT_PRIORITY: + priv->autoconnect_priority = g_value_get_int (value); + break; case PROP_TIMESTAMP: priv->timestamp = g_value_get_uint64 (value); break; @@ -1165,6 +1187,9 @@ get_property (GObject *object, guint prop_id, case PROP_AUTOCONNECT: g_value_set_boolean (value, nm_setting_connection_get_autoconnect (setting)); break; + case PROP_AUTOCONNECT_PRIORITY: + g_value_set_int (value, nm_setting_connection_get_autoconnect_priority (setting)); + break; case PROP_TIMESTAMP: g_value_set_uint64 (value, nm_setting_connection_get_timestamp (setting)); break; @@ -1331,6 +1356,24 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) NM_SETTING_PARAM_FUZZY_IGNORE | G_PARAM_STATIC_STRINGS)); + /** + * NMSettingConnection:autoconnect-priority: + * + * The autoconnect priority. If the connection is set to autoconnect, + * connections with higher priority will be preferred. Defaults to 0. + * The higher number means higher priority. + **/ + g_object_class_install_property + (object_class, PROP_AUTOCONNECT_PRIORITY, + g_param_spec_int (NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY, "", "", + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MIN, + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MAX, + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_DEFAULT, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); + /** * NMSettingConnection:timestamp: * diff --git a/libnm-core/nm-setting-connection.h b/libnm-core/nm-setting-connection.h index 169e2c18ee..4b40401d32 100644 --- a/libnm-core/nm-setting-connection.h +++ b/libnm-core/nm-setting-connection.h @@ -72,11 +72,16 @@ typedef enum #define NM_SETTING_CONNECTION_ERROR nm_setting_connection_error_quark () GQuark nm_setting_connection_error_quark (void); +#define NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MIN -999 +#define NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MAX 999 +#define NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_DEFAULT 0 + #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_AUTOCONNECT_PRIORITY "autoconnect-priority" #define NM_SETTING_CONNECTION_TIMESTAMP "timestamp" #define NM_SETTING_CONNECTION_READ_ONLY "read-only" #define NM_SETTING_CONNECTION_PERMISSIONS "permissions" @@ -111,6 +116,7 @@ const char *nm_setting_connection_get_uuid (NMSettingConnection *set 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); +gint nm_setting_connection_get_autoconnect_priority (NMSettingConnection *setting); guint64 nm_setting_connection_get_timestamp (NMSettingConnection *setting); gboolean nm_setting_connection_get_read_only (NMSettingConnection *setting); diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index 2cb6137866..63811102ca 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -1599,6 +1599,7 @@ test_connection_diff_a_only (void) { 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_AUTOCONNECT_PRIORITY, 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 }, diff --git a/libnm/libnm.ver b/libnm/libnm.ver index bcb3a97381..ca8283abb4 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -530,6 +530,7 @@ global: nm_setting_connection_error_get_type; nm_setting_connection_error_quark; nm_setting_connection_get_autoconnect; + nm_setting_connection_get_autoconnect_priority; nm_setting_connection_get_connection_type; nm_setting_connection_get_gateway_ping_timeout; nm_setting_connection_get_id; From 212f5dcba6a88a6212faee202cc4166963af6e13 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 6 Oct 2014 15:45:02 +0200 Subject: [PATCH 04/13] ifcfg-rh: add svGetValueInt64() utility function Signed-off-by: Thomas Haller --- src/settings/plugins/ifcfg-rh/shvar.c | 37 +++++++++++++++++++++++++++ src/settings/plugins/ifcfg-rh/shvar.h | 2 ++ 2 files changed, 39 insertions(+) diff --git a/src/settings/plugins/ifcfg-rh/shvar.c b/src/settings/plugins/ifcfg-rh/shvar.c index 4e8e29ce59..b4c911fb6d 100644 --- a/src/settings/plugins/ifcfg-rh/shvar.c +++ b/src/settings/plugins/ifcfg-rh/shvar.c @@ -34,6 +34,11 @@ #include "shvar.h" +#include "NetworkManagerUtils.h" +#include "nm-logging.h" + +#define PARSE_WARNING(msg...) nm_log_warn (LOGD_SETTINGS, " " msg) + /* Open the file , returning a shvarFile on success and NULL on failure. * Add a wrinkle to let the caller specify whether or not to create the file * (actually, return a structure anyway) if it doesn't exist. @@ -306,6 +311,38 @@ svTrueValue (shvarFile *s, const char *key, gboolean def) return returnValue; } +/* svGetValueInt64: + * @s: fhe file + * @key: the name of the key to read + * @base: the numeric base (usually 10). Setting to 0 means "auto". Usually you want 10. + * @min: the minimum for range-check + * @max: the maximum for range-check + * @fallback: the fallback value in any error case + * + * Reads a value @key and converts it to an integer using nm_utils_ascii_str_to_int64(). + * In case of error, @errno will be set and @fallback returned. */ +gint64 +svGetValueInt64 (shvarFile *s, const char *key, guint base, gint64 min, gint64 max, gint64 fallback) +{ + char *tmp; + gint64 result; + int errsv; + + tmp = svGetValue (s, key, FALSE); + if (!tmp) { + errno = 0; + return fallback; + } + + result = nm_utils_ascii_str_to_int64 (tmp, base, min, max, fallback); + errsv = errno; + if (errsv != 0) + PARSE_WARNING ("Error reading '%s' value '%s' as integer (%d)", key, tmp, errsv); + + g_free (tmp); + + return result; +} /* Set the variable equal to the value . * If does not exist, and the pointer is set, append diff --git a/src/settings/plugins/ifcfg-rh/shvar.h b/src/settings/plugins/ifcfg-rh/shvar.h index 4cbf1a31a7..b2a2f2636e 100644 --- a/src/settings/plugins/ifcfg-rh/shvar.h +++ b/src/settings/plugins/ifcfg-rh/shvar.h @@ -63,6 +63,8 @@ char *svGetValue (shvarFile *s, const char *key, gboolean verbatim); */ gboolean svTrueValue (shvarFile *s, const char *key, gboolean def); +gint64 svGetValueInt64 (shvarFile *s, const char *key, guint base, gint64 min, gint64 max, gint64 fallback); + /* Set the variable equal to the value . * If does not exist, and the pointer is set, append * the key=value pair after that line. Otherwise, prepend the pair From 210e0dbc1124015161575b201bc7adbcdda96e0e Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 6 Oct 2014 16:04:00 +0200 Subject: [PATCH 05/13] ifcfg-rh: add support for NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY Signed-off-by: Thomas Haller --- src/settings/plugins/ifcfg-rh/reader.c | 8 +++++++- .../ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open | 1 + src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 2 ++ src/settings/plugins/ifcfg-rh/writer.c | 7 +++++++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index 5cb96a0349..1c6aa70cb2 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -169,8 +169,14 @@ make_connection_setting (const char *file, } /* Missing ONBOOT is treated as "ONBOOT=true" by the old network service */ - g_object_set (s_con, NM_SETTING_CONNECTION_AUTOCONNECT, + g_object_set (s_con, + NM_SETTING_CONNECTION_AUTOCONNECT, svTrueValue (ifcfg, "ONBOOT", TRUE), + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY, + (gint) svGetValueInt64 (ifcfg, "AUTOCONNECT_PRIORITY", 10, + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MIN, + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MAX, + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_DEFAULT), NULL); value = svGetValue (ifcfg, "USERS", FALSE); diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open index d4bb8f75b0..48db45b25d 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open @@ -3,6 +3,7 @@ DEVICE=eth2 HWADDR=00:16:41:11:22:33 NM_CONTROLLED=yes BOOTPROTO=dhcp +AUTOCONNECT_PRIORITY=-1 ESSID=blahblah CHANNEL=1 MODE=Managed diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index e72e7a3681..03caff5f81 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -2910,6 +2910,8 @@ test_read_wifi_open (void) NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_AUTOCONNECT); + g_assert_cmpint (nm_setting_connection_get_autoconnect_priority (s_con), ==, -1); + /* ===== WIRELESS SETTING ===== */ s_wireless = nm_connection_get_setting_wireless (connection); diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c index 86f317cc19..70c0e1b024 100644 --- a/src/settings/plugins/ifcfg-rh/writer.c +++ b/src/settings/plugins/ifcfg-rh/writer.c @@ -1664,6 +1664,7 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) GString *str; const char *master; char *tmp; + gint i_int; svSetValue (ifcfg, "NAME", nm_setting_connection_get_id (s_con), FALSE); svSetValue (ifcfg, "UUID", nm_setting_connection_get_uuid (s_con), FALSE); @@ -1672,6 +1673,12 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) nm_setting_connection_get_autoconnect (s_con) ? "yes" : "no", FALSE); + i_int = nm_setting_connection_get_autoconnect_priority (s_con); + tmp = i_int != NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_DEFAULT + ? g_strdup_printf ("%d", i_int) : NULL; + svSetValue (ifcfg, "AUTOCONNECT_PRIORITY", tmp, FALSE); + g_free (tmp); + /* Permissions */ svSetValue (ifcfg, "USERS", NULL, FALSE); n = nm_setting_connection_get_num_permissions (s_con); From c9476a4242cb648126bdc304d7aaa12b0e4b8cbf Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 26 Aug 2014 16:18:28 +0200 Subject: [PATCH 06/13] cli: fix type when setting variadic argument in nmc_property_set_uint() Signed-off-by: Thomas Haller --- clients/cli/settings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/settings.c b/clients/cli/settings.c index b7137560de..9b3cbb2ba9 100644 --- a/clients/cli/settings.c +++ b/clients/cli/settings.c @@ -2155,7 +2155,7 @@ nmc_property_set_uint (NMSetting *setting, const char *prop, const char *val, GE if (!validate_uint (setting, prop, (guint) val_int, error)) return FALSE; - g_object_set (setting, prop, val_int, NULL); + g_object_set (setting, prop, (guint) val_int, NULL); return TRUE; } From 83e99c22276fec33d66b031b2a08db7cd3d3572b Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 26 Aug 2014 16:20:06 +0200 Subject: [PATCH 07/13] cli: add nmc_property_set_int() function Signed-off-by: Thomas Haller --- clients/cli/settings.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/clients/cli/settings.c b/clients/cli/settings.c index 9b3cbb2ba9..79437dca03 100644 --- a/clients/cli/settings.c +++ b/clients/cli/settings.c @@ -2159,6 +2159,26 @@ nmc_property_set_uint (NMSetting *setting, const char *prop, const char *val, GE return TRUE; } +static gboolean +nmc_property_set_int (NMSetting *setting, const char *prop, const char *val, GError **error) +{ + long int val_int; + + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + if (!nmc_string_to_int (val, TRUE, G_MININT, G_MAXINT, &val_int)) { + g_set_error (error, 1, 0, _("'%s' is not a valid number (or out of range)"), val); + return FALSE; + } + + /* Validate the number according to the property spec */ + if (!validate_int (setting, prop, (gint) val_int, error)) + return FALSE; + + g_object_set (setting, prop, (gint) val_int, NULL); + return TRUE; +} + static gboolean nmc_property_set_bool (NMSetting *setting, const char *prop, const char *val, GError **error) { From cf26bb2dea1476fede90725cd19f105a37e437e5 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 26 Aug 2014 16:30:03 +0200 Subject: [PATCH 08/13] cli: support connection.autoconnect-priority property Signed-off-by: Thomas Haller --- clients/cli/connections.c | 30 +++++++++++++++------------ clients/cli/settings.c | 43 ++++++++++++++++++++++++--------------- 2 files changed, 44 insertions(+), 29 deletions(-) diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 22492f371f..301b4c2354 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -61,15 +61,16 @@ static NmcOutputField nmc_fields_con_show[] = { {"TIMESTAMP", N_("TIMESTAMP"), 12}, /* 3 */ {"TIMESTAMP-REAL", N_("TIMESTAMP-REAL"), 34}, /* 4 */ {"AUTOCONNECT", N_("AUTOCONNECT"), 13}, /* 5 */ - {"READONLY", N_("READONLY"), 10}, /* 6 */ - {"DBUS-PATH", N_("DBUS-PATH"), 42}, /* 7 */ - {"ACTIVE", N_("ACTIVE"), 10}, /* 8 */ - {"DEVICE", N_("DEVICE"), 10}, /* 9 */ - {"STATE", N_("STATE"), 12}, /* 10 */ - {"ACTIVE-PATH", N_("ACTIVE-PATH"), 51}, /* 11 */ + {"AUTOCONNECT-PRIORITY", N_("AUTOCONNECT-PRIORITY"), 10}, /* 6 */ + {"READONLY", N_("READONLY"), 10}, /* 7 */ + {"DBUS-PATH", N_("DBUS-PATH"), 42}, /* 8 */ + {"ACTIVE", N_("ACTIVE"), 10}, /* 9 */ + {"DEVICE", N_("DEVICE"), 10}, /* 10 */ + {"STATE", N_("STATE"), 12}, /* 11 */ + {"ACTIVE-PATH", N_("ACTIVE-PATH"), 51}, /* 12 */ {NULL, NULL, 0} }; -#define NMC_FIELDS_CON_SHOW_ALL "NAME,UUID,TYPE,TIMESTAMP,TIMESTAMP-REAL,AUTOCONNECT,READONLY,DBUS-PATH,"\ +#define NMC_FIELDS_CON_SHOW_ALL "NAME,UUID,TYPE,TIMESTAMP,TIMESTAMP-REAL,AUTOCONNECT,AUTOCONNECT-PRIORITY,READONLY,DBUS-PATH,"\ "ACTIVE,DEVICE,STATE,ACTIVE-PATH" #define NMC_FIELDS_CON_SHOW_COMMON "NAME,UUID,TYPE,DEVICE" @@ -745,6 +746,7 @@ fill_output_connection (gpointer data, gpointer user_data, gboolean active_only) time_t timestamp_real; char *timestamp_str; char *timestamp_real_str = ""; + char *prio_str; NmcOutputField *arr; NMActiveConnection *ac = NULL; const char *ac_path = NULL; @@ -772,6 +774,7 @@ fill_output_connection (gpointer data, gpointer user_data, gboolean active_only) timestamp_real_str = g_malloc0 (64); strftime (timestamp_real_str, 64, "%c", localtime (×tamp_real)); } + prio_str = g_strdup_printf ("%u", nm_setting_connection_get_autoconnect_priority (s_con)); arr = nmc_dup_fields_array (nmc_fields_con_show, sizeof (nmc_fields_con_show), @@ -782,12 +785,13 @@ fill_output_connection (gpointer data, gpointer user_data, gboolean active_only) set_val_str (arr, 3, timestamp_str); set_val_str (arr, 4, timestamp ? timestamp_real_str : g_strdup (_("never"))); set_val_strc (arr, 5, nm_setting_connection_get_autoconnect (s_con) ? _("yes") : _("no")); - set_val_strc (arr, 6, nm_setting_connection_get_read_only (s_con) ? _("yes") : _("no")); - set_val_strc (arr, 7, nm_connection_get_path (connection)); - set_val_strc (arr, 8, ac ? _("yes") : _("no")); - set_val_str (arr, 9, ac_dev); - set_val_strc (arr, 10, ac_state); - set_val_strc (arr, 11, ac_path); + set_val_str (arr, 6, prio_str); + set_val_strc (arr, 7, nm_setting_connection_get_read_only (s_con) ? _("yes") : _("no")); + set_val_strc (arr, 8, nm_connection_get_path (connection)); + set_val_strc (arr, 9, ac ? _("yes") : _("no")); + set_val_str (arr, 10, ac_dev); + set_val_strc (arr, 11, ac_state); + set_val_strc (arr, 12, ac_path); g_ptr_array_add (nmc->output_data, arr); } diff --git a/clients/cli/settings.c b/clients/cli/settings.c index 79437dca03..6a78e5e1f7 100644 --- a/clients/cli/settings.c +++ b/clients/cli/settings.c @@ -43,14 +43,15 @@ NmcOutputField nmc_fields_setting_connection[] = { SETTING_FIELD (NM_SETTING_CONNECTION_INTERFACE_NAME, 20), /* 3 */ SETTING_FIELD (NM_SETTING_CONNECTION_TYPE, 17), /* 4 */ SETTING_FIELD (NM_SETTING_CONNECTION_AUTOCONNECT, 13), /* 5 */ - SETTING_FIELD (NM_SETTING_CONNECTION_TIMESTAMP, 10), /* 6 */ - SETTING_FIELD (NM_SETTING_CONNECTION_READ_ONLY, 10), /* 7 */ - SETTING_FIELD (NM_SETTING_CONNECTION_PERMISSIONS, 30), /* 8 */ - SETTING_FIELD (NM_SETTING_CONNECTION_ZONE, 10), /* 9 */ - SETTING_FIELD (NM_SETTING_CONNECTION_MASTER, 20), /* 10 */ - SETTING_FIELD (NM_SETTING_CONNECTION_SLAVE_TYPE, 20), /* 11 */ - SETTING_FIELD (NM_SETTING_CONNECTION_SECONDARIES, 40), /* 12 */ - SETTING_FIELD (NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT, 30), /* 13 */ + SETTING_FIELD (NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY, 10), /* 6 */ + SETTING_FIELD (NM_SETTING_CONNECTION_TIMESTAMP, 10), /* 7 */ + SETTING_FIELD (NM_SETTING_CONNECTION_READ_ONLY, 10), /* 8 */ + SETTING_FIELD (NM_SETTING_CONNECTION_PERMISSIONS, 30), /* 9 */ + SETTING_FIELD (NM_SETTING_CONNECTION_ZONE, 10), /* 10 */ + SETTING_FIELD (NM_SETTING_CONNECTION_MASTER, 20), /* 11 */ + SETTING_FIELD (NM_SETTING_CONNECTION_SLAVE_TYPE, 20), /* 12 */ + SETTING_FIELD (NM_SETTING_CONNECTION_SECONDARIES, 40), /* 13 */ + SETTING_FIELD (NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT, 30), /* 14 */ {NULL, NULL, 0, NULL, FALSE, FALSE, 0} }; #define NMC_FIELDS_SETTING_CONNECTION_ALL "name"","\ @@ -59,6 +60,7 @@ NmcOutputField nmc_fields_setting_connection[] = { NM_SETTING_CONNECTION_INTERFACE_NAME","\ NM_SETTING_CONNECTION_TYPE","\ NM_SETTING_CONNECTION_AUTOCONNECT","\ + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY","\ NM_SETTING_CONNECTION_TIMESTAMP","\ NM_SETTING_CONNECTION_READ_ONLY","\ NM_SETTING_CONNECTION_PERMISSIONS","\ @@ -1004,6 +1006,7 @@ DEFINE_GETTER (nmc_property_connection_get_uuid, NM_SETTING_CONNECTION_UUID) DEFINE_GETTER (nmc_property_connection_get_interface_name, NM_SETTING_CONNECTION_INTERFACE_NAME) DEFINE_GETTER (nmc_property_connection_get_type, NM_SETTING_CONNECTION_TYPE) DEFINE_GETTER (nmc_property_connection_get_autoconnect, NM_SETTING_CONNECTION_AUTOCONNECT) +DEFINE_GETTER (nmc_property_connection_get_autoconnect_priority, NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY) DEFINE_GETTER (nmc_property_connection_get_timestamp, NM_SETTING_CONNECTION_TIMESTAMP) DEFINE_GETTER (nmc_property_connection_get_read_only, NM_SETTING_CONNECTION_READ_ONLY) @@ -5135,6 +5138,13 @@ nmc_properties_init (void) NULL, NULL, NULL); + nmc_add_prop_funcs (GLUE (CONNECTION, AUTOCONNECT_PRIORITY), + nmc_property_connection_get_autoconnect_priority, + nmc_property_set_int, + NULL, + NULL, + NULL, + NULL); nmc_add_prop_funcs (GLUE (CONNECTION, TIMESTAMP), nmc_property_connection_get_timestamp, NULL, /* read-only */ @@ -6502,14 +6512,15 @@ setting_connection_details (NMSetting *setting, NmCli *nmc, const char *one_prop set_val_str (arr, 3, nmc_property_connection_get_interface_name (setting)); set_val_str (arr, 4, nmc_property_connection_get_type (setting)); set_val_str (arr, 5, nmc_property_connection_get_autoconnect (setting)); - set_val_str (arr, 6, nmc_property_connection_get_timestamp (setting)); - set_val_str (arr, 7, nmc_property_connection_get_read_only (setting)); - set_val_str (arr, 8, nmc_property_connection_get_permissions (setting)); - set_val_str (arr, 9, nmc_property_connection_get_zone (setting)); - set_val_str (arr, 10, nmc_property_connection_get_master (setting)); - set_val_str (arr, 11, nmc_property_connection_get_slave_type (setting)); - set_val_str (arr, 12, nmc_property_connection_get_secondaries (setting)); - set_val_str (arr, 13, nmc_property_connection_get_gateway_ping_timeout (setting)); + set_val_str (arr, 6, nmc_property_connection_get_autoconnect_priority (setting)); + set_val_str (arr, 7, nmc_property_connection_get_timestamp (setting)); + set_val_str (arr, 8, nmc_property_connection_get_read_only (setting)); + set_val_str (arr, 9, nmc_property_connection_get_permissions (setting)); + set_val_str (arr, 10, nmc_property_connection_get_zone (setting)); + set_val_str (arr, 11, nmc_property_connection_get_master (setting)); + set_val_str (arr, 12, nmc_property_connection_get_slave_type (setting)); + set_val_str (arr, 13, nmc_property_connection_get_secondaries (setting)); + set_val_str (arr, 14, nmc_property_connection_get_gateway_ping_timeout (setting)); g_ptr_array_add (nmc->output_data, arr); print_data (nmc); /* Print all data */ From 2e8a2921e5ae7bb12dbed9e94311203292ddc9a9 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 24 Sep 2014 09:40:14 +0200 Subject: [PATCH 09/13] core: ensure properly comparing boolean values in connection_sort() Signed-off-by: Thomas Haller --- src/settings/nm-settings.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 096608ce05..5a7bf4159e 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -326,17 +326,17 @@ connection_sort (gconstpointer pa, gconstpointer pb) NMConnection *b = NM_CONNECTION (pb); NMSettingConnection *con_b; guint64 ts_a = 0, ts_b = 0; + gboolean can_ac_a, can_ac_b; con_a = nm_connection_get_setting_connection (a); g_assert (con_a); con_b = nm_connection_get_setting_connection (b); g_assert (con_b); - if (nm_setting_connection_get_autoconnect (con_a) != nm_setting_connection_get_autoconnect (con_b)) { - if (nm_setting_connection_get_autoconnect (con_a)) - return -1; - return 1; - } + can_ac_a = !!nm_setting_connection_get_autoconnect (con_a); + can_ac_b = !!nm_setting_connection_get_autoconnect (con_b); + if (can_ac_a != can_ac_b) + return can_ac_a ? -1 : 1; nm_settings_connection_get_timestamp (NM_SETTINGS_CONNECTION (pa), &ts_a); nm_settings_connection_get_timestamp (NM_SETTINGS_CONNECTION (pb), &ts_b); From f68faccd7fb2dad3bdd98242b2785da67ccdc314 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 26 Aug 2014 15:10:38 +0200 Subject: [PATCH 10/13] core: add nm_device_can_auto_connect() function Signed-off-by: Thomas Haller --- src/devices/nm-device.c | 28 ++++++++++++++++++++++++++++ src/devices/nm-device.h | 4 ++++ 2 files changed, 32 insertions(+) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index c2755ef5a2..46c64a771d 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -1640,6 +1640,34 @@ can_auto_connect (NMDevice *self, return nm_device_connection_is_available (self, connection, FALSE); } +/** + * nm_device_can_auto_connect: + * @self: an #NMDevice + * @connection: a #NMConnection + * @specific_object: (out) (transfer full): on output, the path of an + * object associated with the returned connection, to be passed to + * nm_manager_activate_connection(), or %NULL. + * + * Checks if @connection can be auto-activated on @self right now. + * This requires, at a minimum, that the connection be compatible with + * @self, and that it have the #NMSettingConnection:autoconnect property + * set. Some devices impose additional requirements. (Eg, a Wi-Fi connection + * can only be activated if its SSID was seen in the last scan.) + * + * Returns: %TRUE, if the @connection can be auto-activated. + **/ +gboolean +nm_device_can_auto_connect (NMDevice *self, + NMConnection *connection, + char **specific_object) +{ + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail (specific_object && !*specific_object, FALSE); + + return NM_DEVICE_GET_CLASS (self)->can_auto_connect (self, connection, specific_object); +} + static gboolean device_has_config (NMDevice *self) { diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 28a2ff0be9..2b97a8cd62 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -273,6 +273,10 @@ NMConnection * nm_device_get_best_auto_connection (NMDevice *dev, GSList *connections, char **specific_object); +gboolean nm_device_can_auto_connect (NMDevice *self, + NMConnection *connection, + char **specific_object); + gboolean nm_device_complete_connection (NMDevice *device, NMConnection *connection, const char *specific_object, From 91ec7dac90b3a8f0c45b4501b9e90027680a98e6 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 26 Aug 2014 15:18:47 +0200 Subject: [PATCH 11/13] core: remove nm_device_get_best_auto_connection() nm_device_get_best_auto_connection() was only used at one place. It was a very simple function, just iterated over a list finding the first can_auto_connect() connection. At the very least, the name was misleading, because it did not return the 'best', but the 'first' connection. Get rid of the function altogether. Signed-off-by: Thomas Haller --- src/devices/nm-device.c | 40 ---------------------------------------- src/devices/nm-device.h | 4 ---- src/nm-policy.c | 20 ++++++++++---------- 3 files changed, 10 insertions(+), 54 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 46c64a771d..d2edef95f8 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -1824,46 +1824,6 @@ nm_device_generate_connection (NMDevice *self, NMDevice *master) return connection; } -/** - * nm_device_get_best_auto_connection: - * @self: an #NMDevice - * @connections: (element-type #NMConnection): a list of connections - * @specific_object: (out) (transfer full): on output, the path of an - * object associated with the returned connection, to be passed to - * nm_manager_activate_connection(), or %NULL. - * - * Looks through @connections to see if there is a connection that can - * be auto-activated on @self right now. This requires, at a minimum, - * that the connection be compatible with @self, and that it have the - * #NMSettingConnection:autoconnect property set. Some devices impose - * additional requirements. (Eg, a Wi-Fi connection can only be - * activated if its SSID was seen in the last scan.) - * - * Returns: an auto-activatable #NMConnection, or %NULL if none are - * available. - */ - -NMConnection * -nm_device_get_best_auto_connection (NMDevice *self, - GSList *connections, - char **specific_object) -{ - GSList *iter; - - g_return_val_if_fail (NM_IS_DEVICE (self), NULL); - g_return_val_if_fail (specific_object != NULL, NULL); - g_return_val_if_fail (*specific_object == NULL, NULL); - - for (iter = connections; iter; iter = iter->next) { - NMConnection *connection = NM_CONNECTION (iter->data); - - if (NM_DEVICE_GET_CLASS (self)->can_auto_connect (self, connection, specific_object)) - return connection; - } - - return NULL; -} - gboolean nm_device_complete_connection (NMDevice *self, NMConnection *connection, diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 2b97a8cd62..00da022905 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -269,10 +269,6 @@ gboolean nm_device_master_update_slave_connection (NMDevice *master, NMConnection *connection, GError **error); -NMConnection * nm_device_get_best_auto_connection (NMDevice *dev, - GSList *connections, - char **specific_object); - gboolean nm_device_can_auto_connect (NMDevice *self, NMConnection *connection, char **specific_object); diff --git a/src/nm-policy.c b/src/nm-policy.c index f6ef476bf9..ca17ea0c8e 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -1005,20 +1005,22 @@ auto_activate_device (gpointer user_data) if (nm_device_get_act_request (data->device)) goto out; - iter = connections = nm_manager_get_activatable_connections (priv->manager); + connections = nm_manager_get_activatable_connections (priv->manager); - /* Remove connections that shouldn't be auto-activated */ - while (iter) { + /* Find the first connection that should be auto-activated */ + best_connection = NULL; + for (iter = connections; iter; iter = g_slist_next (iter)) { NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (iter->data); - /* Grab next item before we possibly delete the current item */ - iter = g_slist_next (iter); - if (!nm_settings_connection_can_autoconnect (candidate)) - connections = g_slist_remove (connections, candidate); + continue; + if (nm_device_can_auto_connect (data->device, (NMConnection *) candidate, &specific_object)) { + best_connection = (NMConnection *) candidate; + break; + } } + g_slist_free (connections); - best_connection = nm_device_get_best_auto_connection (data->device, connections, &specific_object); if (best_connection) { GError *error = NULL; NMAuthSubject *subject; @@ -1041,8 +1043,6 @@ auto_activate_device (gpointer user_data) g_object_unref (subject); } - g_slist_free (connections); - out: activate_data_free (data); return G_SOURCE_REMOVE; From 59f2c0fb3e9a7266ff39f4e1212024e9d845be75 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 26 Aug 2014 15:49:18 +0200 Subject: [PATCH 12/13] core/policy: refactor auto_activate_device() to use a GPtrArray Next we want to sort the array, g_slist_sort() is not guaranteed to be stable, while g_ptr_array_sort() is. Also, sorting a GSList has worse performance. Signed-off-by: Thomas Haller --- src/nm-policy.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/nm-policy.c b/src/nm-policy.c index ca17ea0c8e..d20cf78ce5 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -42,6 +42,7 @@ #include "nm-firewall-manager.h" #include "nm-dispatcher.h" #include "nm-utils.h" +#include "nm-core-internal.h" #include "nm-glib-compat.h" #include "nm-manager.h" #include "nm-settings.h" @@ -990,7 +991,9 @@ auto_activate_device (gpointer user_data) NMPolicyPrivate *priv; NMConnection *best_connection; char *specific_object = NULL; - GSList *connections, *iter; + GPtrArray *connections; + GSList *connection_list; + guint i; g_assert (data); policy = data->policy; @@ -1005,12 +1008,17 @@ auto_activate_device (gpointer user_data) if (nm_device_get_act_request (data->device)) goto out; - connections = nm_manager_get_activatable_connections (priv->manager); + connection_list = nm_manager_get_activatable_connections (priv->manager); + if (!connection_list) + goto out; + + connections = _nm_utils_copy_slist_to_array (connection_list, NULL, NULL); + g_slist_free (connection_list); /* Find the first connection that should be auto-activated */ best_connection = NULL; - for (iter = connections; iter; iter = g_slist_next (iter)) { - NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (iter->data); + for (i = 0; i < connections->len; i++) { + NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (connections->pdata[i]); if (!nm_settings_connection_can_autoconnect (candidate)) continue; @@ -1019,7 +1027,7 @@ auto_activate_device (gpointer user_data) break; } } - g_slist_free (connections); + g_ptr_array_free (connections, TRUE); if (best_connection) { GError *error = NULL; From f87e876f79c4e71b20fe961622a80bde69b71bfb Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 26 Aug 2014 16:06:39 +0200 Subject: [PATCH 13/13] core: prefer connections with higher priority for autoconnect https://bugzilla.gnome.org/show_bug.cgi?id=580018 Signed-off-by: Thomas Haller --- src/NetworkManagerUtils.c | 25 ++++++++++ src/NetworkManagerUtils.h | 2 + src/nm-policy.c | 4 ++ src/tests/test-general.c | 100 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 131 insertions(+) diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index dcc64270c1..bdf03557a1 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -1634,6 +1634,31 @@ nm_utils_match_connection (GSList *connections, return best_match; } +int +nm_utils_cmp_connection_by_autoconnect_priority (NMConnection **a, NMConnection **b) +{ + NMSettingConnection *a_s_con, *b_s_con; + gboolean a_ac, b_ac; + gint a_ap, b_ap; + + a_s_con = nm_connection_get_setting_connection (*a); + b_s_con = nm_connection_get_setting_connection (*b); + + a_ac = !!nm_setting_connection_get_autoconnect (a_s_con); + b_ac = !!nm_setting_connection_get_autoconnect (b_s_con); + if (a_ac != b_ac) + return ((int) b_ac) - ((int) a_ac); + if (!a_ac) + return 0; + + a_ap = nm_setting_connection_get_autoconnect_priority (a_s_con); + b_ap = nm_setting_connection_get_autoconnect_priority (b_s_con); + if (a_ap != b_ap) + return (a_ap > b_ap) ? -1 : 1; + + return 0; +} + /* nm_utils_ascii_str_to_int64: * * A wrapper for g_ascii_strtoll, that checks whether the whole string diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h index d66a1ddd9e..88de6dd208 100644 --- a/src/NetworkManagerUtils.h +++ b/src/NetworkManagerUtils.h @@ -138,6 +138,8 @@ NMConnection *nm_utils_match_connection (GSList *connections, NMUtilsMatchFilterFunc match_filter_func, gpointer match_filter_data); +int nm_utils_cmp_connection_by_autoconnect_priority (NMConnection **a, NMConnection **b); + gint64 nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max, gint64 fallback); #define NM_UTILS_NS_PER_SECOND ((gint64) 1000000000) diff --git a/src/nm-policy.c b/src/nm-policy.c index d20cf78ce5..120afd65c6 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -1015,6 +1015,10 @@ auto_activate_device (gpointer user_data) connections = _nm_utils_copy_slist_to_array (connection_list, NULL, NULL); g_slist_free (connection_list); + /* sort is stable (which is important at this point) so that connections + * with same priority are still sorted by last-connected-timestamp. */ + g_ptr_array_sort (connections, (GCompareFunc) nm_utils_cmp_connection_by_autoconnect_priority); + /* Find the first connection that should be auto-activated */ best_connection = NULL; for (i = 0; i < connections->len; i++) { diff --git a/src/tests/test-general.c b/src/tests/test-general.c index c1970b897c..ec771bc55b 100644 --- a/src/tests/test-general.c +++ b/src/tests/test-general.c @@ -581,6 +581,104 @@ test_connection_no_match_ip4_addr (void) g_object_unref (copy); } +static NMConnection * +_create_connection_autoconnect (const char *id, gboolean autoconnect, int autoconnect_priority) +{ + NMConnection *c; + NMSettingConnection *s_con; + + c = nmtst_create_minimal_connection (id, NULL, NM_SETTING_WIRED_SETTING_NAME, &s_con); + g_object_set (s_con, + NM_SETTING_CONNECTION_AUTOCONNECT, autoconnect, + NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY, autoconnect_priority, + NULL); + nmtst_connection_normalize (c); + return c; +} + +static void +_test_connection_sort_autoconnect_priority_one (NMConnection **list, gboolean shuffle) +{ + int i, j; + int count = 0; + gs_unref_ptrarray GPtrArray *connections = g_ptr_array_new (); + + while (list[count]) + count++; + g_assert (count > 1); + + /* copy the list of connections over to @connections and shuffle. */ + for (i = 0; i < count; i++) + g_ptr_array_add (connections, list[i]); + if (shuffle) { + for (i = count - 1; i > 0; i--) { + j = g_rand_int (nmtst_get_rand ()) % (i + 1); + NMTST_SWAP (connections->pdata[i], connections->pdata[j]); + } + } + + /* sort it... */ + g_ptr_array_sort (connections, (GCompareFunc) nm_utils_cmp_connection_by_autoconnect_priority); + + for (i = 0; i < count; i++) { + if (list[i] == connections->pdata[i]) + continue; + if (shuffle && nm_utils_cmp_connection_by_autoconnect_priority (&list[i], (NMConnection **) &connections->pdata[i]) == 0) + continue; + g_message ("After sorting, the order of connections is not as expected!! Offending index: %d", i); + for (j = 0; j < count; j++) + g_message (" %3d: %p/%-20s - %p/%-20s", j, list[j], nm_connection_get_id (list[j]), connections->pdata[j], nm_connection_get_id (connections->pdata[j])); + g_assert_not_reached (); + } +} + +static void +_test_connection_sort_autoconnect_priority_free (NMConnection **list) +{ + while (*list) { + g_object_unref (*list); + *list = NULL; + } +} + +static void +test_connection_sort_autoconnect_priority (void) +{ + NMConnection *c1[] = { + _create_connection_autoconnect ("AC/100", TRUE, 100), + _create_connection_autoconnect ("AC/100", TRUE, 100), + _create_connection_autoconnect ("AC/99", TRUE, 99), + _create_connection_autoconnect ("AC/0", TRUE, 0), + _create_connection_autoconnect ("AC/0", TRUE, 0), + _create_connection_autoconnect ("AC/-1", TRUE, -1), + _create_connection_autoconnect ("AC/-3", TRUE, -3), + _create_connection_autoconnect ("ac/0", FALSE, 0), + _create_connection_autoconnect ("ac/0", FALSE, 0), + _create_connection_autoconnect ("ac/1", FALSE, 1), + _create_connection_autoconnect ("ac/-1", FALSE, -1), + _create_connection_autoconnect ("ac/1", FALSE, 1), + _create_connection_autoconnect ("ac/0", FALSE, 0), + NULL, + }; + NMConnection *c2[] = { + _create_connection_autoconnect ("AC/100", TRUE, 100), + _create_connection_autoconnect ("AC/99", TRUE, 99), + _create_connection_autoconnect ("AC/0", TRUE, 0), + _create_connection_autoconnect ("AC/-1", TRUE, -1), + _create_connection_autoconnect ("AC/-3", TRUE, -3), + _create_connection_autoconnect ("ac/0", FALSE, 0), + NULL, + }; + + _test_connection_sort_autoconnect_priority_one (c1, FALSE); + _test_connection_sort_autoconnect_priority_one (c2, FALSE); + _test_connection_sort_autoconnect_priority_one (c1, TRUE); + _test_connection_sort_autoconnect_priority_one (c2, TRUE); + + _test_connection_sort_autoconnect_priority_free (c1); + _test_connection_sort_autoconnect_priority_free (c2); +} + /*******************************************/ NMTST_DEFINE (); @@ -602,6 +700,8 @@ main (int argc, char **argv) g_test_add_func ("/general/connection-match/wired", test_connection_match_wired); g_test_add_func ("/general/connection-match/no-match-ip4-addr", test_connection_no_match_ip4_addr); + g_test_add_func ("/general/connection-sort/autoconnect-priority", test_connection_sort_autoconnect_priority); + return g_test_run (); }