From ac73758305faf938318e6c888faf8bc954b8289d Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Fri, 1 Jul 2016 17:05:42 +0200 Subject: [PATCH] libnm-core: ip-config: normalize may-fail for disabled IP methods Since commit 7d1709d7f649 ("device: check may_fail when progressing to IP_CHECK") NM correctly checks the may-fail properties to decide whether a connection must fail after the completion of IP configuration. But for ipv4.method=disabled and ipv6.method=ignore the IP configuration is always considered failed and thus setting may-fail=no results in a connection that can never succeed. To prevent such wrong configuration, force may-fail to TRUE for those methods during connection normalization. https://bugzilla.redhat.com/show_bug.cgi?id=1334884 --- libnm-core/nm-connection.c | 14 ++++++++++ libnm-core/nm-setting-ip4-config.c | 12 ++++++++ libnm-core/nm-setting-ip6-config.c | 12 ++++++++ libnm-core/tests/test-general.c | 44 ++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+) diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c index 7695518115..2fd3401c0c 100644 --- a/libnm-core/nm-connection.c +++ b/libnm-core/nm-connection.c @@ -764,6 +764,13 @@ _normalize_ip_config (NMConnection *self, GHashTable *parameters) g_object_set (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, NULL, NULL); changed = TRUE; } + + if ( nm_streq0 (nm_setting_ip_config_get_method (s_ip4), + NM_SETTING_IP4_CONFIG_METHOD_DISABLED) + && !nm_setting_ip_config_get_may_fail (s_ip4)) { + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); + changed = TRUE; + } } if (!s_ip6) { setting = nm_setting_ip6_config_new (); @@ -797,6 +804,13 @@ _normalize_ip_config (NMConnection *self, GHashTable *parameters) g_object_set (s_ip6, NM_SETTING_IP_CONFIG_GATEWAY, NULL, NULL); changed = TRUE; } + + if ( nm_streq0 (nm_setting_ip_config_get_method (s_ip6), + NM_SETTING_IP6_CONFIG_METHOD_IGNORE) + && !nm_setting_ip_config_get_may_fail (s_ip6)) { + g_object_set (s_ip6, NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); + changed = TRUE; + } } return !s_ip4 || !s_ip6 || changed; } diff --git a/libnm-core/nm-setting-ip4-config.c b/libnm-core/nm-setting-ip4-config.c index 8f43def019..70fab0e2b1 100644 --- a/libnm-core/nm-setting-ip4-config.c +++ b/libnm-core/nm-setting-ip4-config.c @@ -225,6 +225,18 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } + /* Failures from here on are NORMALIZABLE... */ + + if ( !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) + && !nm_setting_ip_config_get_may_fail (s_ip)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property should be TRUE when method is set to disabled")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_MAY_FAIL); + return NM_SETTING_VERIFY_NORMALIZABLE; + } + return TRUE; } diff --git a/libnm-core/nm-setting-ip6-config.c b/libnm-core/nm-setting-ip6-config.c index a5826eb3b1..50b3654301 100644 --- a/libnm-core/nm-setting-ip6-config.c +++ b/libnm-core/nm-setting-ip6-config.c @@ -262,6 +262,18 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; } + /* Failures from here on are NORMALIZABLE... */ + + if ( !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) + && !nm_setting_ip_config_get_may_fail (s_ip)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("property should be TRUE when method is set to ignore")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_MAY_FAIL); + return NM_SETTING_VERIFY_NORMALIZABLE; + } + return TRUE; } diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index aef9f2b13d..b191108702 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -3918,6 +3918,49 @@ test_connection_normalize_gateway_never_default (void) g_assert_cmpstr (NULL, ==, nm_setting_ip_config_get_gateway (s_ip4)); } +static void +test_connection_normalize_may_fail (void) +{ + gs_unref_object NMConnection *con = NULL; + NMSettingIPConfig *s_ip4, *s_ip6; + gs_free_error GError *error = NULL; + + con = nmtst_create_minimal_connection ("test2", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + nmtst_assert_connection_verifies_and_normalizable (con); + + s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); + g_object_set (G_OBJECT (s_ip4), + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_MAY_FAIL, FALSE, + NULL); + + s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); + g_object_set (s_ip6, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP_CONFIG_MAY_FAIL, FALSE, + NULL); + + nm_connection_add_setting (con, (NMSetting *) s_ip4); + nm_connection_add_setting (con, (NMSetting *) s_ip6); + + nmtst_assert_connection_verifies_without_normalization (con); + + /* Now set method=disabled/ignore and check that may-fail becomes TRUE + * after normalization + * */ + g_object_set (s_ip4, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NULL); + g_object_set (s_ip6, + NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NULL); + + nmtst_assert_connection_verifies (con); + nmtst_connection_normalize (con); + g_assert_cmpint (nm_setting_ip_config_get_may_fail (s_ip4), ==, TRUE); + g_assert_cmpint (nm_setting_ip_config_get_may_fail (s_ip6), ==, TRUE); +} + static void test_setting_ip4_gateway (void) { @@ -5321,6 +5364,7 @@ int main (int argc, char **argv) g_test_add_func ("/core/general/test_connection_normalize_slave_type_2", test_connection_normalize_slave_type_2); g_test_add_func ("/core/general/test_connection_normalize_infiniband_mtu", test_connection_normalize_infiniband_mtu); g_test_add_func ("/core/general/test_connection_normalize_gateway_never_default", test_connection_normalize_gateway_never_default); + g_test_add_func ("/core/general/test_connection_normalize_may_fail", test_connection_normalize_may_fail); g_test_add_func ("/core/general/test_setting_connection_permissions_helpers", test_setting_connection_permissions_helpers); g_test_add_func ("/core/general/test_setting_connection_permissions_property", test_setting_connection_permissions_property);