diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c index 0c4d7ce18..c10c99581 100644 --- a/libnm-core/nm-connection.c +++ b/libnm-core/nm-connection.c @@ -16,7 +16,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright 2007 - 2017 Red Hat, Inc. + * Copyright 2007 - 2018 Red Hat, Inc. * Copyright 2007 - 2008 Novell, Inc. */ @@ -809,16 +809,30 @@ _normalize_ethernet_link_neg (NMConnection *self) return FALSE; } +/** + * _supports_addr_family: + * @self: a #NMConnection + * @family: AF_* + * + * Check whether the connection supports certain L3 address family, + * in order to be able to tell whether is should have the corresponding + * setting ("ipv4" for AF_INET and "ipv6" for AF_INET6). + * + * If AF_UNSPEC is given, then the function checks whether the connection + * supports any L3 configuration at all. + * + * Returns: %TRUE if the AF is supported, %FALSE otherwise + **/ static gboolean -_without_ip_config (NMConnection *self) +_supports_addr_family (NMConnection *self, int family) { const char *connection_type = nm_connection_get_connection_type (self); - g_return_val_if_fail (connection_type, FALSE); + g_return_val_if_fail (connection_type, TRUE); if (strcmp (connection_type, NM_SETTING_OVS_INTERFACE_SETTING_NAME) == 0) - return FALSE; + return TRUE; - return !!nm_setting_connection_get_master (nm_connection_get_setting_connection (self)); + return !nm_setting_connection_get_master (nm_connection_get_setting_connection (self)); } static gboolean @@ -841,32 +855,18 @@ _normalize_ip_config (NMConnection *self, GHashTable *parameters) s_ip6 = nm_connection_get_setting_ip6_config (self); s_proxy = nm_connection_get_setting_proxy (self); - if (_without_ip_config (self)) { - /* Slave connections don't have IP configuration. */ - - if (s_ip4) - nm_connection_remove_setting (self, NM_TYPE_SETTING_IP4_CONFIG); - - if (s_ip6) - nm_connection_remove_setting (self, NM_TYPE_SETTING_IP6_CONFIG); - - if (s_proxy) - nm_connection_remove_setting (self, NM_TYPE_SETTING_PROXY); - - return s_ip4 || s_ip6 || s_proxy; - } else { - /* Ensure all non-slave connections have IP4 and IP6 settings objects. If no - * IP6 setting was specified, then assume that means IP6 config is allowed - * to fail. But if no IP4 setting was specified, assume the caller was just - * being lazy. - */ + if (_supports_addr_family (self, AF_INET)) { if (!s_ip4) { + /* But if no IP4 setting was specified, assume the caller was just + * being lazy and use the default method. + */ setting = nm_setting_ip4_config_new (); g_object_set (setting, NM_SETTING_IP_CONFIG_METHOD, default_ip4_method, NULL); nm_connection_add_setting (self, setting); + changed = TRUE; } else { if ( nm_setting_ip_config_get_gateway (s_ip4) && nm_setting_ip_config_get_never_default (s_ip4)) { @@ -890,7 +890,18 @@ _normalize_ip_config (NMConnection *self, GHashTable *parameters) changed = TRUE; } } + } else { + if (s_ip4) { + nm_connection_remove_setting (self, NM_TYPE_SETTING_IP4_CONFIG); + changed = TRUE; + } + } + + if (_supports_addr_family (self, AF_INET6)) { if (!s_ip6) { + /* If no IP6 setting was specified, then assume that means IP6 config is + * allowed to fail. + */ setting = nm_setting_ip6_config_new (); g_object_set (setting, @@ -898,6 +909,7 @@ _normalize_ip_config (NMConnection *self, GHashTable *parameters) NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, NULL); nm_connection_add_setting (self, setting); + changed = TRUE; } else { const char *token; @@ -930,14 +942,27 @@ _normalize_ip_config (NMConnection *self, GHashTable *parameters) changed = TRUE; } } + } else { + if (s_ip6) { + nm_connection_remove_setting (self, NM_TYPE_SETTING_IP6_CONFIG); + changed = TRUE; + } + } + if (_supports_addr_family (self, AF_UNSPEC)) { if (!s_proxy) { setting = nm_setting_proxy_new (); nm_connection_add_setting (self, setting); + changed = TRUE; + } + } else { + if (s_proxy) { + nm_connection_remove_setting (self, NM_TYPE_SETTING_PROXY); + changed = TRUE; } - - return !s_ip4 || !s_ip6 || !s_proxy || changed; } + + return changed; } static gboolean @@ -1288,39 +1313,79 @@ _nm_connection_verify (NMConnection *connection, GError **error) nm_assert (normalizable_error_type != NM_SETTING_VERIFY_ERROR); if (NM_IN_SET (normalizable_error_type, NM_SETTING_VERIFY_SUCCESS, NM_SETTING_VERIFY_NORMALIZABLE)) { - if (_without_ip_config (connection)) { - if (s_ip4 || s_ip6 || s_proxy) { + if (_supports_addr_family (connection, AF_INET)) { + if (!s_ip4 && normalizable_error_type == NM_SETTING_VERIFY_SUCCESS) { + g_set_error_literal (&normalizable_error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("setting is required for non-slave connections")); + g_prefix_error (&normalizable_error, "%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME); + + /* having a master without IP config was not a verify() error, accept + * it for backward compatibility. */ + normalizable_error_type = NM_SETTING_VERIFY_NORMALIZABLE; + } + } else { + if (s_ip4) { g_clear_error (&normalizable_error); g_set_error_literal (&normalizable_error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING, _("setting not allowed in slave connection")); - g_prefix_error (&normalizable_error, "%s: ", - s_ip4 - ? NM_SETTING_IP4_CONFIG_SETTING_NAME - : (s_ip6 - ? NM_SETTING_IP6_CONFIG_SETTING_NAME - : NM_SETTING_PROXY_SETTING_NAME)); + g_prefix_error (&normalizable_error, "%s: ", NM_SETTING_IP4_CONFIG_SETTING_NAME); /* having a slave with IP config *was* and is a verify() error. */ normalizable_error_type = NM_SETTING_VERIFY_NORMALIZABLE_ERROR; } - } else { - if ( normalizable_error_type == NM_SETTING_VERIFY_SUCCESS - && (!s_ip4 || !s_ip6 || !s_proxy)) { + } + + if (_supports_addr_family (connection, AF_INET6)) { + if (!s_ip6 && normalizable_error_type == NM_SETTING_VERIFY_SUCCESS) { g_set_error_literal (&normalizable_error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_SETTING, _("setting is required for non-slave connections")); - g_prefix_error (&normalizable_error, "%s: ", - !s_ip4 - ? NM_SETTING_IP4_CONFIG_SETTING_NAME - : (!s_ip6 - ? NM_SETTING_IP6_CONFIG_SETTING_NAME - : NM_SETTING_PROXY_SETTING_NAME)); + g_prefix_error (&normalizable_error, "%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME); + /* having a master without IP config was not a verify() error, accept * it for backward compatibility. */ normalizable_error_type = NM_SETTING_VERIFY_NORMALIZABLE; } + } else { + if (s_ip6) { + g_clear_error (&normalizable_error); + g_set_error_literal (&normalizable_error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("setting not allowed in slave connection")); + g_prefix_error (&normalizable_error, "%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME); + /* having a slave with IP config *was* and is a verify() error. */ + normalizable_error_type = NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + } + + if (_supports_addr_family (connection, AF_UNSPEC)) { + if (!s_proxy && normalizable_error_type == NM_SETTING_VERIFY_SUCCESS) { + g_set_error_literal (&normalizable_error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_MISSING_SETTING, + _("setting is required for non-slave connections")); + g_prefix_error (&normalizable_error, "%s: ", NM_SETTING_PROXY_SETTING_NAME); + + /* having a master without proxy config was not a verify() error, accept + * it for backward compatibility. */ + normalizable_error_type = NM_SETTING_VERIFY_NORMALIZABLE; + } + } else { + if (s_proxy) { + g_clear_error (&normalizable_error); + g_set_error_literal (&normalizable_error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + _("setting not allowed in slave connection")); + g_prefix_error (&normalizable_error, "%s: ", NM_SETTING_PROXY_SETTING_NAME); + /* having a slave with proxy config *was* and is a verify() error. */ + normalizable_error_type = NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } } }