diff options
author | Thomas Haller <thaller@redhat.com> | 2013-12-01 23:31:47 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2014-06-30 18:35:46 +0200 |
commit | 29d538239f519e7328c3895b086136ca1b2864f8 (patch) | |
tree | c4c9ae949bf601413dc458f9e91585e370c2eec7 | |
parent | 794ed1c9efc8ddd3677e125795acd40c69a5ed5a (diff) | |
download | NetworkManager-29d538239f519e7328c3895b086136ca1b2864f8.tar.gz |
libnm-util: normalize IP settings in connection
This is the same behaviour as nm_utils_normalize_connection(),
which will soon be removed in favor of nm_connection_normalize().
This takes care, that normal connections always have an IP4 and IP6 setting,
and that slave connections never have it.
Signed-off-by: Thomas Haller <thaller@redhat.com>
-rw-r--r-- | libnm-util/nm-connection.c | 86 | ||||
-rw-r--r-- | libnm-util/nm-connection.h | 12 | ||||
-rw-r--r-- | libnm-util/nm-setting-connection.c | 30 |
3 files changed, 97 insertions, 31 deletions
diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c index b4a1857108..572b9108f4 100644 --- a/libnm-util/nm-connection.c +++ b/libnm-util/nm-connection.c @@ -631,6 +631,61 @@ _normalize_virtual_iface_name (NMConnection *self) return was_modified; } +static gboolean +_normalize_ip_config (NMConnection *self, GHashTable *parameters) +{ + NMSettingConnection *s_con = nm_connection_get_setting_connection (self); + const char *default_ip4_method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; + const char *default_ip6_method = NULL; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + NMSetting *setting; + + if (parameters) + default_ip6_method = g_hash_table_lookup (parameters, NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD); + if (!default_ip6_method) + default_ip6_method = NM_SETTING_IP6_CONFIG_METHOD_AUTO; + + s_ip4 = nm_connection_get_setting_ip4_config (self); + s_ip6 = nm_connection_get_setting_ip6_config (self); + + if (nm_setting_connection_get_master (s_con)) { + /* 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); + + return s_ip4 || s_ip6; + } 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 (!s_ip4) { + setting = nm_setting_ip4_config_new (); + + g_object_set (setting, + NM_SETTING_IP4_CONFIG_METHOD, default_ip4_method, + NULL); + nm_connection_add_setting (self, setting); + } + if (!s_ip6) { + setting = nm_setting_ip6_config_new (); + + g_object_set (setting, + NM_SETTING_IP6_CONFIG_METHOD, default_ip6_method, + NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NULL); + nm_connection_add_setting (self, setting); + } + return !s_ip4 || !s_ip6; + } +} + /** * nm_connection_verify: * @connection: the #NMConnection to verify @@ -667,6 +722,8 @@ _nm_connection_verify (NMConnection *connection, GError **error) { NMConnectionPrivate *priv; NMSettingConnection *s_con; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; GHashTableIter iter; gpointer value; GSList *all_settings = NULL, *setting_i; @@ -782,6 +839,34 @@ _nm_connection_verify (NMConnection *connection, GError **error) goto EXIT; } + s_ip4 = nm_connection_get_setting_ip4_config (connection); + s_ip6 = nm_connection_get_setting_ip6_config (connection); + + if (nm_setting_connection_get_master (s_con)) { + if ((normalizable_error_type == NM_SETTING_VERIFY_SUCCESS || + (normalizable_error_type == NM_SETTING_VERIFY_NORMALIZABLE)) && (s_ip4 || s_ip6)) { + g_clear_error (&normalizable_error); + g_set_error (&normalizable_error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_SETTING, + "slave connection cannot have an IP%c setting", + s_ip4 ? '4' : '6'); + /* 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)) { + g_set_error (&normalizable_error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_SETTING_NOT_FOUND, + "connection needs an IP%c setting", + !s_ip4 ? '4' : '6'); + /* having a master without IP config was not a verify() error, accept + * it for backward compatibility. */ + normalizable_error_type = NM_SETTING_VERIFY_NORMALIZABLE; + } + } + if (normalizable_error_type != NM_SETTING_VERIFY_SUCCESS) { g_propagate_error (error, normalizable_error); normalizable_error = NULL; @@ -845,6 +930,7 @@ nm_connection_normalize (NMConnection *connection, * errors, because in that case we rather fail without touching the settings. */ was_modified |= _normalize_virtual_iface_name (connection); + was_modified |= _normalize_ip_config (connection, parameters); /* Verify anew. */ success = _nm_connection_verify (connection, error); diff --git a/libnm-util/nm-connection.h b/libnm-util/nm-connection.h index dcc24b9178..692bdc688b 100644 --- a/libnm-util/nm-connection.h +++ b/libnm-util/nm-connection.h @@ -86,6 +86,8 @@ G_BEGIN_DECLS * #NMSettingWireless. * @NM_CONNECTION_ERROR_SETTING_NOT_FOUND: the #NMConnection object * did not contain the specified #NMSetting object + *@NM_CONNECTION_ERROR_INVALID_SETTING: the #NMConnection object contains + * a conflicting setting object * * Describes errors that may result from operations involving a #NMConnection. * @@ -95,9 +97,17 @@ typedef enum NM_CONNECTION_ERROR_UNKNOWN = 0, /*< nick=UnknownError >*/ NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND, /*< nick=ConnectionSettingNotFound >*/ NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID, /*< nick=ConnectionTypeInvalid >*/ - NM_CONNECTION_ERROR_SETTING_NOT_FOUND /*< nick=SettingNotFound >*/ + NM_CONNECTION_ERROR_SETTING_NOT_FOUND, /*< nick=SettingNotFound >*/ + NM_CONNECTION_ERROR_INVALID_SETTING, /*< nick=InvalidSetting >*/ } NMConnectionError; +/* + * NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD: overwrite the ip6 method + * when normalizing ip6 configuration. If omited, this defaults to + * @NM_SETTING_IP6_CONFIG_METHOD_AUTO. + */ +#define NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD "ip6-config-method" + #define NM_CONNECTION_ERROR nm_connection_error_quark () GQuark nm_connection_error_quark (void); diff --git a/libnm-util/nm-setting-connection.c b/libnm-util/nm-setting-connection.c index 16541f398e..c49413bef3 100644 --- a/libnm-util/nm-setting-connection.c +++ b/libnm-util/nm-setting-connection.c @@ -882,9 +882,6 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) } if (is_slave) { - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; - if (!priv->master) { g_set_error_literal (error, NM_SETTING_CONNECTION_ERROR, @@ -893,33 +890,6 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_MASTER); return NM_SETTING_VERIFY_ERROR; } - - /* Bond/bridge/team slaves are not allowed to have any IP configuration. */ - s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_find_in_list (all_settings, NM_SETTING_IP4_CONFIG_SETTING_NAME)); - if (s_ip4) { - if (strcmp (nm_setting_ip4_config_get_method (s_ip4), - NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) { - g_set_error_literal (error, - NM_SETTING_CONNECTION_ERROR, - NM_SETTING_CONNECTION_ERROR_IP_CONFIG_NOT_ALLOWED, - _("IPv4 configuration is not allowed for slave")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE); - return FALSE; - } - } - - s_ip6 = NM_SETTING_IP6_CONFIG (nm_setting_find_in_list (all_settings, NM_SETTING_IP6_CONFIG_SETTING_NAME)); - if (s_ip6) { - if (strcmp (nm_setting_ip6_config_get_method (s_ip6), - NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) { - g_set_error_literal (error, - NM_SETTING_CONNECTION_ERROR, - NM_SETTING_CONNECTION_ERROR_IP_CONFIG_NOT_ALLOWED, - _("IPv6 configuration is not allowed for slave")); - g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE); - return FALSE; - } - } } else { if (priv->master) { g_set_error_literal (error, |