summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiří Klimeš <jklimes@redhat.com>2015-10-29 18:57:52 +0100
committerJiří Klimeš <jklimes@redhat.com>2015-11-03 08:31:04 +0100
commit212b3e671316c7c3e78ae0e7e00e99328137e857 (patch)
treed0a1f854e7669ec0c9497ed28a0f173ede98af68
parent05dad07978a8e1ba956cfa4de2178ef7429af080 (diff)
downloadNetworkManager-212b3e671316c7c3e78ae0e7e00e99328137e857.tar.gz
core: fix assuming a connection without S390 properties (rh #1276343)
When a connection should be assumed and the generated connection did not contain a wired setting, the connection did not match due to S390 properties. Such a connection should be allowed to match to a connection with a wired setting with default (empty) S390 properties. This can happen when there is a VLAN profile configured that contains a wired setting in it and NetworkManager is (re)started. Example/reproducer: $ nmcli con add type vlan con-name vlan-test autoconnect no dev em1 id 44 $ nmcli con mod vlan-test eth.mtu 1450 (modify the connection, so that it has a wired setting) $ nmcli con up vlan-test (activate the connection) $ sudo systemctl restart NetworkManager $ nmcli device check that 'vlan-test' connection is active on em1.44 device (and not the auto-generated em1.44) https://bugzilla.redhat.com/show_bug.cgi?id=1276343
-rw-r--r--src/NetworkManagerUtils.c52
-rw-r--r--src/tests/test-general.c33
2 files changed, 85 insertions, 0 deletions
diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c
index cd8d717e96..d683d7fa73 100644
--- a/src/NetworkManagerUtils.c
+++ b/src/NetworkManagerUtils.c
@@ -2211,6 +2211,9 @@ remove_from_hash (GHashTable *s_hash,
const char *s_name,
const char *p_name)
{
+ if (!p_hash)
+ return;
+
g_hash_table_remove (p_hash, p_name);
if (g_hash_table_size (p_hash) == 0)
g_hash_table_remove (s_hash, s_name);
@@ -2399,6 +2402,52 @@ check_connection_cloned_mac_address (NMConnection *orig,
return FALSE;
}
+static gboolean
+check_connection_s390_props (NMConnection *orig,
+ NMConnection *candidate,
+ GHashTable *settings)
+{
+ GHashTable *props1, *props2, *props3;
+ NMSettingWired *s_wired_orig, *s_wired_cand;
+
+ props1 = check_property_in_hash (settings,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_S390_SUBCHANNELS);
+ props2 = check_property_in_hash (settings,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_S390_NETTYPE);
+ props3 = check_property_in_hash (settings,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_S390_OPTIONS);
+ if (!props1 && !props2 && !props3)
+ return TRUE;
+
+ /* If the generated connection did not contain wired setting,
+ * allow it to match to a connection with a wired setting,
+ * but default (empty) s390-* properties */
+ s_wired_orig = nm_connection_get_setting_wired (orig);
+ s_wired_cand = nm_connection_get_setting_wired (candidate);
+ if (!s_wired_orig && s_wired_cand) {
+ const char * const *subchans = nm_setting_wired_get_s390_subchannels (s_wired_cand);
+ const char *nettype = nm_setting_wired_get_s390_nettype (s_wired_cand);
+ guint32 num_options = nm_setting_wired_get_num_s390_options (s_wired_cand);
+
+ if ((!subchans || !*subchans) && !nettype && num_options == 0) {
+ remove_from_hash (settings, props1,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_S390_SUBCHANNELS);
+ remove_from_hash (settings, props2,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_S390_NETTYPE);
+ remove_from_hash (settings, props3,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_S390_OPTIONS);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
static NMConnection *
check_possible_match (NMConnection *orig,
NMConnection *candidate,
@@ -2422,6 +2471,9 @@ check_possible_match (NMConnection *orig,
if (!check_connection_cloned_mac_address (orig, candidate, settings))
return NULL;
+ if (!check_connection_s390_props (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 2eb524c3b4..da68c9a97c 100644
--- a/src/tests/test-general.c
+++ b/src/tests/test-general.c
@@ -439,6 +439,38 @@ test_connection_match_wired (void)
}
static void
+test_connection_match_wired2 (void)
+{
+ NMConnection *orig, *copy, *matched;
+ GSList *connections = NULL;
+ NMSettingWired *s_wired;
+ const char *mac = "52:54:00:ab:db:23";
+
+ orig = _match_connection_new ();
+ s_wired = nm_connection_get_setting_wired (orig);
+ g_assert (s_wired);
+ g_object_set (G_OBJECT (s_wired),
+ NM_SETTING_WIRED_PORT, "tp", /* port is not compared */
+ NM_SETTING_WIRED_MAC_ADDRESS, mac, /* we allow MAC address just in one connection */
+ NULL);
+
+ copy = nm_simple_connection_new_clone (orig);
+ connections = g_slist_append (connections, copy);
+
+ /* Check that if the generated connection do not have wired setting
+ * and s390 properties in the existing connection's setting are default,
+ * the connections match. It can happen if assuming VLAN devices. */
+ nm_connection_remove_setting (orig, NM_TYPE_SETTING_WIRED);
+
+ matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL);
+ g_assert (matched == copy);
+
+ g_slist_free (connections);
+ g_object_unref (orig);
+ g_object_unref (copy);
+}
+
+static void
test_connection_match_cloned_mac (void)
{
NMConnection *orig, *exact, *fuzzy, *matched;
@@ -1100,6 +1132,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/wired2", test_connection_match_wired2);
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-match/no-match-vlan", test_connection_no_match_vlan);