summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2014-08-26 16:06:39 +0200
committerThomas Haller <thaller@redhat.com>2014-10-06 16:44:25 +0200
commit670cc69d8a297b8114e93a9c0c7952b0ce980fd5 (patch)
treee62719d4d98859680612cdef406a5e36c2d6adb0
parentd7722d5f2f759bdd793f2da33fa6d0836f2fa951 (diff)
downloadNetworkManager-th/bgo580018_autoconnect_priority.tar.gz
core: prefer connections with higher priority for autoconnectth/bgo580018_autoconnect_priority
https://bugzilla.gnome.org/show_bug.cgi?id=580018 Signed-off-by: Thomas Haller <thaller@redhat.com>
-rw-r--r--src/NetworkManagerUtils.c27
-rw-r--r--src/NetworkManagerUtils.h2
-rw-r--r--src/nm-policy.c4
-rw-r--r--src/tests/test-general.c100
4 files changed, 133 insertions, 0 deletions
diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c
index f4c3df9f5e..3128f8a5d8 100644
--- a/src/NetworkManagerUtils.c
+++ b/src/NetworkManagerUtils.c
@@ -1434,6 +1434,33 @@ 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) {
+ if (a_ap > b_ap)
+ return -1;
+ return 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 eead08aae3..0d96276d4c 100644
--- a/src/NetworkManagerUtils.h
+++ b/src/NetworkManagerUtils.h
@@ -132,6 +132,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 ();
}