summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2018-05-23 11:52:39 +0200
committerLubomir Rintel <lkundrak@v3.sk>2018-06-26 16:21:54 +0200
commitae8713471c8b2e5254da071467c514a142da69ce (patch)
treeb29e993dad3eb4eddeef607dfeb54d820fcbeba4
parenta7d2cad67eea5a8290daede96f214bc1e235f956 (diff)
downloadNetworkManager-ae8713471c8b2e5254da071467c514a142da69ce.tar.gz
connection: pick relevant L3 settings more flexibly
For some device types it's not going to be sufficient to tell whether they carry "IP". In particular, there's no way to carry legacy IP over the tiny MTU datagrams of IEEE 802.15.4 WPAN links while an IPv6 transport exist in form of 6LoWPAN.
-rw-r--r--libnm-core/nm-connection.c151
1 files changed, 108 insertions, 43 deletions
diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c
index 0c4d7ce18c..c10c995816 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;
+ }
}
}