diff options
author | Thomas Haller <thaller@redhat.com> | 2014-08-26 16:06:39 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2014-10-06 16:44:25 +0200 |
commit | 670cc69d8a297b8114e93a9c0c7952b0ce980fd5 (patch) | |
tree | e62719d4d98859680612cdef406a5e36c2d6adb0 | |
parent | d7722d5f2f759bdd793f2da33fa6d0836f2fa951 (diff) | |
download | NetworkManager-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.c | 27 | ||||
-rw-r--r-- | src/NetworkManagerUtils.h | 2 | ||||
-rw-r--r-- | src/nm-policy.c | 4 | ||||
-rw-r--r-- | src/tests/test-general.c | 100 |
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 (); } |