From 4112bda940d3ce714f275050d9d73fa235a880ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Fri, 7 Mar 2014 10:33:12 +0100 Subject: [PATCH] core: allow matching IPv6 'link-local' method to 'ignore' (rh #1073824) When an existing connection profile has IPv6 method 'ignore', NM doesn't simply care about IPv6. Thus we should allow matching such a profile to devices with just a link-local address. The example can be a simple configuration like this: /etc/sysconfig/network-scripts/ifcfg-ens3: DEVICE="ens3" ONBOOT=yes NETBOOT=yes UUID="aa17d688-a38d-481d-888d-6d69cca781b8" BOOTPROTO=dhcp HWADDR="52:54:00:32:77:59" TYPE=Ethernet NAME="ens3" https://bugzilla.redhat.com/show_bug.cgi?id=1073824 --- src/NetworkManagerUtils.c | 34 ++++++++++++++++++++++++++++++++++ src/tests/test-general.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index ae6bc504cc..c5823e80c3 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -685,6 +685,37 @@ check_ip6_method_link_local_auto (NMConnection *orig, return FALSE; } +static gboolean +check_ip6_method_link_local_ignore (NMConnection *orig, + NMConnection *candidate, + GHashTable *settings) +{ + GHashTable *props; + const char *orig_ip6_method, *candidate_ip6_method; + + props = g_hash_table_lookup (settings, NM_SETTING_IP6_CONFIG_SETTING_NAME); + if ( !props + || (g_hash_table_size (props) != 1) + || !g_hash_table_lookup (props, NM_SETTING_IP6_CONFIG_METHOD)) { + /* We only handle ipv6 'method' here */ + return FALSE; + } + + /* If the original connection method is 'link-local' and the candidate method + * is 'ignore' we can take the connection, because NM didn't simply take care + * of IPv6. + */ + orig_ip6_method = nm_utils_get_ip_config_method (orig, NM_TYPE_SETTING_IP6_CONFIG); + candidate_ip6_method = nm_utils_get_ip_config_method (candidate, NM_TYPE_SETTING_IP6_CONFIG); + + if ( strcmp (orig_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0 + && strcmp (candidate_ip6_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) { + return TRUE; + } + + return FALSE; +} + static gboolean check_ip4_method_disabled_auto (NMConnection *orig, NMConnection *candidate, @@ -733,6 +764,9 @@ check_possible_match (NMConnection *orig, if (check_ip6_method_link_local_auto (orig, candidate, settings)) return candidate; + if (check_ip6_method_link_local_ignore (orig, candidate, settings)) + return candidate; + if (check_ip4_method_disabled_auto (orig, candidate, settings, device_has_carrier)) return candidate; diff --git a/src/tests/test-general.c b/src/tests/test-general.c index 192fd669b7..a62a1ef621 100644 --- a/src/tests/test-general.c +++ b/src/tests/test-general.c @@ -238,6 +238,40 @@ test_connection_match_ip6_method (void) g_object_unref (copy); } +static void +test_connection_match_ip6_method_ignore (void) +{ + NMConnection *orig, *copy, *matched; + GSList *connections = NULL; + NMSettingIP6Config *s_ip6; + + orig = _match_connection_new (); + copy = nm_connection_duplicate (orig); + connections = g_slist_append (connections, copy); + + /* Check that if the original connection is IPv6 method=link-local, and the + * candidate is method=ignore, that the candidate is matched. + */ + s_ip6 = nm_connection_get_setting_ip6_config (orig); + g_assert (s_ip6); + g_object_set (G_OBJECT (s_ip6), + NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL, + NULL); + + s_ip6 = nm_connection_get_setting_ip6_config (copy); + g_assert (s_ip6); + g_object_set (G_OBJECT (s_ip6), + NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NULL); + + 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_ip4_method (void) { @@ -292,6 +326,7 @@ main (int argc, char **argv) g_test_add_func ("/general/connection-match/basic", test_connection_match_basic); g_test_add_func ("/general/connection-match/ip6-method", test_connection_match_ip6_method); + g_test_add_func ("/general/connection-match/ip6-method-ignore", test_connection_match_ip6_method_ignore); g_test_add_func ("/general/connection-match/ip4-method", test_connection_match_ip4_method); return g_test_run ();