From d40ace0df0a6796cdc444a1fc89ba2835734845d Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Thu, 19 Feb 2015 17:53:43 +0100 Subject: [PATCH] utils: match a cloned mac address with a connection that does not specify it We do the same for the original MAC address. A device enslaved to a bond it inherits the bond's MAC address. When NetworkManager tries to assume a connection the generated cloned-mac property causes a mismatch with the connection that originally brought up the device, causing the generated connection to be used instead: NetworkManager[14190]: [1424355817.112154] [NetworkManagerUtils.c:1641] nm_utils_match_connection(): Connection 'eth2' differs from candidate 'bond-slave-eth2' in 802-3-ethernet.cloned-mac-address https://bugzilla.gnome.org/show_bug.cgi?id=744812 https://bugzilla.redhat.com/show_bug.cgi?id=1256430 (cherry picked from commit cd2cef9cab62db042f646bf0fcdc318106fc627f) --- src/NetworkManagerUtils.c | 36 ++++++++++++++++++++++++++++++++++++ src/tests/test-general.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 63741dc..584b10c 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -2033,6 +2033,39 @@ check_connection_mac_address (NMConnection *orig, return FALSE; } +static gboolean +check_connection_cloned_mac_address (NMConnection *orig, + NMConnection *candidate, + GHashTable *settings) +{ + GHashTable *props; + const char *orig_mac = NULL, *cand_mac = NULL; + NMSettingWired *s_wired_orig, *s_wired_cand; + + props = check_property_in_hash (settings, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_CLONED_MAC_ADDRESS); + if (!props) + return TRUE; + + /* If one of the MAC addresses is NULL, we accept that connection */ + s_wired_orig = nm_connection_get_setting_wired (orig); + if (s_wired_orig) + orig_mac = nm_setting_wired_get_cloned_mac_address (s_wired_orig); + + s_wired_cand = nm_connection_get_setting_wired (candidate); + if (s_wired_cand) + cand_mac = nm_setting_wired_get_cloned_mac_address (s_wired_cand); + + if (!orig_mac || !cand_mac) { + remove_from_hash (settings, props, + NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_WIRED_CLONED_MAC_ADDRESS); + return TRUE; + } + return FALSE; +} + static NMConnection * check_possible_match (NMConnection *orig, NMConnection *candidate, @@ -2053,6 +2086,9 @@ check_possible_match (NMConnection *orig, if (!check_connection_mac_address (orig, candidate, settings)) return NULL; + if (!check_connection_cloned_mac_address (orig, candidate, settings)) + return NULL; + if (g_hash_table_size (settings) == 0) return candidate; else diff --git a/src/tests/test-general.c b/src/tests/test-general.c index de65d50..eda7a1f 100644 --- a/src/tests/test-general.c +++ b/src/tests/test-general.c @@ -440,6 +440,50 @@ test_connection_match_wired (void) } static void +test_connection_match_cloned_mac (void) +{ + NMConnection *orig, *exact, *fuzzy, *matched; + GSList *connections = NULL; + NMSettingWired *s_wired; + + orig = _match_connection_new (); + + fuzzy = nm_simple_connection_new_clone (orig); + connections = g_slist_append (connections, fuzzy); + s_wired = nm_connection_get_setting_wired (orig); + g_assert (s_wired); + g_object_set (G_OBJECT (s_wired), + NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "52:54:00:ab:db:23", + NULL); + + matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL); + g_assert (matched == fuzzy); + + exact = nm_simple_connection_new_clone (orig); + connections = g_slist_append (connections, exact); + s_wired = nm_connection_get_setting_wired (exact); + g_assert (s_wired); + g_object_set (G_OBJECT (s_wired), + NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "52:54:00:ab:db:23", + NULL); + + matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL); + g_assert (matched == exact); + + g_object_set (G_OBJECT (s_wired), + NM_SETTING_WIRED_CLONED_MAC_ADDRESS, "52:54:00:ab:db:24", + NULL); + + matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL); + g_assert (matched == fuzzy); + + g_slist_free (connections); + g_object_unref (orig); + g_object_unref (fuzzy); + g_object_unref (exact); +} + +static void test_connection_no_match_ip4_addr (void) { NMConnection *orig, *copy, *matched; @@ -747,6 +791,7 @@ main (int argc, char **argv) g_test_add_func ("/general/connection-match/ip4-method", test_connection_match_ip4_method); g_test_add_func ("/general/connection-match/con-interface-name", test_connection_match_interface_name); g_test_add_func ("/general/connection-match/wired", test_connection_match_wired); + g_test_add_func ("/general/connection-match/cloned_mac", test_connection_match_cloned_mac); 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); -- 2.4.3