summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2013-12-01 23:31:47 +0100
committerThomas Haller <thaller@redhat.com>2014-06-30 18:35:46 +0200
commit29d538239f519e7328c3895b086136ca1b2864f8 (patch)
treec4c9ae949bf601413dc458f9e91585e370c2eec7
parent794ed1c9efc8ddd3677e125795acd40c69a5ed5a (diff)
downloadNetworkManager-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.c86
-rw-r--r--libnm-util/nm-connection.h12
-rw-r--r--libnm-util/nm-setting-connection.c30
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,