summary refs log tree commit diff
path: root/libnm-core/nm-setting-ip-tunnel.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnm-core/nm-setting-ip-tunnel.c')
-rw-r--r--libnm-core/nm-setting-ip-tunnel.c1164
1 files changed, 597 insertions, 567 deletions
diff --git a/libnm-core/nm-setting-ip-tunnel.c b/libnm-core/nm-setting-ip-tunnel.c
index 5db2dde5..e2f0b0ca 100644
--- a/libnm-core/nm-setting-ip-tunnel.c
+++ b/libnm-core/nm-setting-ip-tunnel.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: LGPL-2.1+
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /*
  * Copyright (C) 2015 Red Hat, Inc.
  */
@@ -17,41 +17,40 @@
 
 /*****************************************************************************/
 
-NM_GOBJECT_PROPERTIES_DEFINE_BASE (
-	PROP_PARENT,
-	PROP_MODE,
-	PROP_LOCAL,
-	PROP_REMOTE,
-	PROP_TTL,
-	PROP_TOS,
-	PROP_PATH_MTU_DISCOVERY,
-	PROP_INPUT_KEY,
-	PROP_OUTPUT_KEY,
-	PROP_ENCAPSULATION_LIMIT,
-	PROP_FLOW_LABEL,
-	PROP_MTU,
-	PROP_FLAGS,
-);
+NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PARENT,
+                                  PROP_MODE,
+                                  PROP_LOCAL,
+                                  PROP_REMOTE,
+                                  PROP_TTL,
+                                  PROP_TOS,
+                                  PROP_PATH_MTU_DISCOVERY,
+                                  PROP_INPUT_KEY,
+                                  PROP_OUTPUT_KEY,
+                                  PROP_ENCAPSULATION_LIMIT,
+                                  PROP_FLOW_LABEL,
+                                  PROP_MTU,
+                                  PROP_FLAGS, );
 
 typedef struct {
-	char *parent;
-	char *local;
-	char *remote;
-	char *input_key;
-	char *output_key;
-	guint ttl;
-	guint tos;
-	guint encapsulation_limit;
-	guint flow_label;
-	NMIPTunnelMode mode;
-	guint32 mtu;
-	guint32 flags;
-	bool path_mtu_discovery:1;
+    char *         parent;
+    char *         local;
+    char *         remote;
+    char *         input_key;
+    char *         output_key;
+    guint          ttl;
+    guint          tos;
+    guint          encapsulation_limit;
+    guint          flow_label;
+    NMIPTunnelMode mode;
+    guint32        mtu;
+    guint32        flags;
+    bool           path_mtu_discovery : 1;
 } NMSettingIPTunnelPrivate;
 
-G_DEFINE_TYPE (NMSettingIPTunnel, nm_setting_ip_tunnel, NM_TYPE_SETTING)
+G_DEFINE_TYPE(NMSettingIPTunnel, nm_setting_ip_tunnel, NM_TYPE_SETTING)
 
-#define NM_SETTING_IP_TUNNEL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_IP_TUNNEL, NMSettingIPTunnelPrivate))
+#define NM_SETTING_IP_TUNNEL_GET_PRIVATE(o) \
+    (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_IP_TUNNEL, NMSettingIPTunnelPrivate))
 
 /*****************************************************************************/
 
@@ -66,10 +65,10 @@ G_DEFINE_TYPE (NMSettingIPTunnel, nm_setting_ip_tunnel, NM_TYPE_SETTING)
  * Since: 1.2
  **/
 const char *
-nm_setting_ip_tunnel_get_parent (NMSettingIPTunnel *setting)
+nm_setting_ip_tunnel_get_parent(NMSettingIPTunnel *setting)
 {
-	g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), NULL);
-	return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->parent;
+    g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), NULL);
+    return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->parent;
 }
 
 /**
@@ -83,11 +82,11 @@ nm_setting_ip_tunnel_get_parent (NMSettingIPTunnel *setting)
  * Since: 1.2
  **/
 NMIPTunnelMode
-nm_setting_ip_tunnel_get_mode (NMSettingIPTunnel *setting)
+nm_setting_ip_tunnel_get_mode(NMSettingIPTunnel *setting)
 {
-	g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), 0);
+    g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), 0);
 
-	return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->mode;
+    return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->mode;
 }
 
 /**
@@ -101,11 +100,11 @@ nm_setting_ip_tunnel_get_mode (NMSettingIPTunnel *setting)
  * Since: 1.2
  **/
 const char *
-nm_setting_ip_tunnel_get_local (NMSettingIPTunnel *setting)
+nm_setting_ip_tunnel_get_local(NMSettingIPTunnel *setting)
 {
-	g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), NULL);
+    g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), NULL);
 
-	return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->local;
+    return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->local;
 }
 
 /**
@@ -119,11 +118,11 @@ nm_setting_ip_tunnel_get_local (NMSettingIPTunnel *setting)
  * Since: 1.2
  **/
 const char *
-nm_setting_ip_tunnel_get_remote (NMSettingIPTunnel *setting)
+nm_setting_ip_tunnel_get_remote(NMSettingIPTunnel *setting)
 {
-	g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), NULL);
+    g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), NULL);
 
-	return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->remote;
+    return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->remote;
 }
 
 /**
@@ -138,11 +137,11 @@ nm_setting_ip_tunnel_get_remote (NMSettingIPTunnel *setting)
  **/
 
 guint
-nm_setting_ip_tunnel_get_ttl (NMSettingIPTunnel *setting)
+nm_setting_ip_tunnel_get_ttl(NMSettingIPTunnel *setting)
 {
-	g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), 0);
+    g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), 0);
 
-	return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->ttl;
+    return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->ttl;
 }
 
 /**
@@ -156,11 +155,11 @@ nm_setting_ip_tunnel_get_ttl (NMSettingIPTunnel *setting)
  * Since: 1.2
  **/
 guint
-nm_setting_ip_tunnel_get_tos (NMSettingIPTunnel *setting)
+nm_setting_ip_tunnel_get_tos(NMSettingIPTunnel *setting)
 {
-	g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), 0);
+    g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), 0);
 
-	return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->tos;
+    return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->tos;
 }
 
 /**
@@ -174,11 +173,11 @@ nm_setting_ip_tunnel_get_tos (NMSettingIPTunnel *setting)
  * Since: 1.2
  **/
 gboolean
-nm_setting_ip_tunnel_get_path_mtu_discovery (NMSettingIPTunnel *setting)
+nm_setting_ip_tunnel_get_path_mtu_discovery(NMSettingIPTunnel *setting)
 {
-	g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), TRUE);
+    g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), TRUE);
 
-	return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->path_mtu_discovery;
+    return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->path_mtu_discovery;
 }
 
 /**
@@ -192,11 +191,11 @@ nm_setting_ip_tunnel_get_path_mtu_discovery (NMSettingIPTunnel *setting)
  * Since: 1.2
  **/
 const char *
-nm_setting_ip_tunnel_get_input_key (NMSettingIPTunnel *setting)
+nm_setting_ip_tunnel_get_input_key(NMSettingIPTunnel *setting)
 {
-	g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), NULL);
+    g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), NULL);
 
-	return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->input_key;
+    return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->input_key;
 }
 
 /**
@@ -210,11 +209,11 @@ nm_setting_ip_tunnel_get_input_key (NMSettingIPTunnel *setting)
  * Since: 1.2
  **/
 const char *
-nm_setting_ip_tunnel_get_output_key (NMSettingIPTunnel *setting)
+nm_setting_ip_tunnel_get_output_key(NMSettingIPTunnel *setting)
 {
-	g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), NULL);
+    g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), NULL);
 
-	return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->output_key;
+    return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->output_key;
 }
 
 /**
@@ -228,11 +227,11 @@ nm_setting_ip_tunnel_get_output_key (NMSettingIPTunnel *setting)
  * Since: 1.2
  **/
 guint
-nm_setting_ip_tunnel_get_encapsulation_limit (NMSettingIPTunnel *setting)
+nm_setting_ip_tunnel_get_encapsulation_limit(NMSettingIPTunnel *setting)
 {
-	g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), 0);
+    g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), 0);
 
-	return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->encapsulation_limit;
+    return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->encapsulation_limit;
 }
 
 /**
@@ -246,11 +245,11 @@ nm_setting_ip_tunnel_get_encapsulation_limit (NMSettingIPTunnel *setting)
  * Since: 1.2
  **/
 guint
-nm_setting_ip_tunnel_get_flow_label (NMSettingIPTunnel *setting)
+nm_setting_ip_tunnel_get_flow_label(NMSettingIPTunnel *setting)
 {
-	g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), 0);
+    g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), 0);
 
-	return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->flow_label;
+    return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->flow_label;
 }
 
 /**
@@ -264,11 +263,11 @@ nm_setting_ip_tunnel_get_flow_label (NMSettingIPTunnel *setting)
  * Since: 1.2
  **/
 guint
-nm_setting_ip_tunnel_get_mtu (NMSettingIPTunnel *setting)
+nm_setting_ip_tunnel_get_mtu(NMSettingIPTunnel *setting)
 {
-	g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), 0);
+    g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), 0);
 
-	return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->mtu;
+    return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->mtu;
 }
 
 /*
@@ -282,311 +281,328 @@ nm_setting_ip_tunnel_get_mtu (NMSettingIPTunnel *setting)
  * Since: 1.12
  **/
 NMIPTunnelFlags
-nm_setting_ip_tunnel_get_flags (NMSettingIPTunnel *setting)
+nm_setting_ip_tunnel_get_flags(NMSettingIPTunnel *setting)
 {
-	g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), NM_IP_TUNNEL_FLAG_NONE);
+    g_return_val_if_fail(NM_IS_SETTING_IP_TUNNEL(setting), NM_IP_TUNNEL_FLAG_NONE);
 
-	return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->flags;
+    return NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting)->flags;
 }
 
 /*****************************************************************************/
 
 gboolean
-_nm_ip_tunnel_mode_is_layer2 (NMIPTunnelMode mode)
+_nm_ip_tunnel_mode_is_layer2(NMIPTunnelMode mode)
 {
-	return NM_IN_SET (mode,
-	                  NM_IP_TUNNEL_MODE_GRETAP,
-	                  NM_IP_TUNNEL_MODE_IP6GRETAP);
+    return NM_IN_SET(mode, NM_IP_TUNNEL_MODE_GRETAP, NM_IP_TUNNEL_MODE_IP6GRETAP);
 }
 
 static gboolean
-verify (NMSetting *setting, NMConnection *connection, GError **error)
+verify(NMSetting *setting, NMConnection *connection, GError **error)
 {
-	NMSettingIPTunnelPrivate *priv = NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting);
-	int family = AF_UNSPEC;
-	guint32 flags;
-
-	switch (priv->mode) {
-	case NM_IP_TUNNEL_MODE_IPIP:
-	case NM_IP_TUNNEL_MODE_SIT:
-	case NM_IP_TUNNEL_MODE_ISATAP:
-	case NM_IP_TUNNEL_MODE_GRE:
-	case NM_IP_TUNNEL_MODE_VTI:
-	case NM_IP_TUNNEL_MODE_GRETAP:
-		family = AF_INET;
-		break;
-	case NM_IP_TUNNEL_MODE_IP6IP6:
-	case NM_IP_TUNNEL_MODE_IPIP6:
-	case NM_IP_TUNNEL_MODE_IP6GRE:
-	case NM_IP_TUNNEL_MODE_VTI6:
-	case NM_IP_TUNNEL_MODE_IP6GRETAP:
-		family = AF_INET6;
-		break;
-	case NM_IP_TUNNEL_MODE_UNKNOWN:
-		break;
-	}
-
-	if (family == AF_UNSPEC) {
-		g_set_error (error,
-		             NM_CONNECTION_ERROR,
-		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
-		             _("'%d' is not a valid tunnel mode"),
-		             (int) priv->mode);
-		g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_MODE);
-		return FALSE;
-	}
-
-	if (   priv->parent
-	    && !nm_utils_ifname_valid_kernel (priv->parent, NULL)
-	    && !nm_utils_is_uuid (priv->parent)) {
-		g_set_error (error,
-		             NM_CONNECTION_ERROR,
-		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
-		             _("'%s' is neither an UUID nor an interface name"),
-		             priv->parent);
-		g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME,
-		                NM_SETTING_IP_TUNNEL_PARENT);
-		return FALSE;
-	}
-
-	if (priv->local && !nm_utils_ipaddr_is_valid (family, priv->local)) {
-		g_set_error (error,
-		             NM_CONNECTION_ERROR,
-		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
-		             _("'%s' is not a valid IPv%c address"),
-		             priv->local,
-		             family == AF_INET ? '4' : '6');
-		g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_LOCAL);
-		return FALSE;
-	}
-
-	if (!priv->remote) {
-		g_set_error_literal (error,
-		                     NM_CONNECTION_ERROR,
-		                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
-		                     _("property is missing"));
-		g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_REMOTE);
-		return FALSE;
-	}
-
-	if (!nm_utils_ipaddr_is_valid (family, priv->remote)) {
-		g_set_error (error,
-		             NM_CONNECTION_ERROR,
-		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
-		             _("'%s' is not a valid IPv%c address"),
-		             priv->remote,
-		             family == AF_INET ? '4' : '6');
-		g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME, NM_SETTING_IP_TUNNEL_REMOTE);
-		return FALSE;
-	}
-
-	if (   (priv->input_key && priv->input_key[0])
-	    || (priv->output_key && priv->output_key[0])) {
-		if (!NM_IN_SET (priv->mode,
-		                NM_IP_TUNNEL_MODE_GRE,
-		                NM_IP_TUNNEL_MODE_GRETAP,
-		                NM_IP_TUNNEL_MODE_IP6GRE,
-		                NM_IP_TUNNEL_MODE_IP6GRETAP)) {
-			g_set_error_literal (error,
-			                     NM_CONNECTION_ERROR,
-			                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
-			                     _("tunnel keys can only be specified for GRE tunnels"));
-			return FALSE;
-		}
-	}
-
-	if (priv->input_key && priv->input_key[0]) {
-		gint64 val;
-
-		val = _nm_utils_ascii_str_to_int64 (priv->input_key, 10, 0, G_MAXUINT32, -1);
-		if (val == -1) {
-			g_set_error (error,
-			             NM_CONNECTION_ERROR,
-			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
-			             _("'%s' is not a valid tunnel key"),
-			             priv->input_key);
-			g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME,
-			                NM_SETTING_IP_TUNNEL_INPUT_KEY);
-			return FALSE;
-		}
-	}
-
-	if (priv->output_key && priv->output_key[0]) {
-		gint64 val;
-
-		val = _nm_utils_ascii_str_to_int64 (priv->output_key, 10, 0, G_MAXUINT32, -1);
-		if (val == -1) {
-			g_set_error (error,
-			             NM_CONNECTION_ERROR,
-			             NM_CONNECTION_ERROR_INVALID_PROPERTY,
-			             _("'%s' is not a valid tunnel key"),
-			             priv->output_key);
-			g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME,
-			                NM_SETTING_IP_TUNNEL_OUTPUT_KEY);
-			return FALSE;
-		}
-	}
-
-	if (!priv->path_mtu_discovery && priv->ttl != 0) {
-		g_set_error_literal (error,
-		                     NM_CONNECTION_ERROR,
-		                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
-		                     _("a fixed TTL is allowed only when path MTU discovery is enabled"));
-		g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME,
-		                NM_SETTING_IP_TUNNEL_TTL);
-		return FALSE;
-	}
-
-	flags = priv->flags;
-	if (NM_IN_SET (priv->mode, NM_IP_TUNNEL_MODE_IPIP6, NM_IP_TUNNEL_MODE_IP6IP6))
-		flags &= (guint32) (~_NM_IP_TUNNEL_FLAG_ALL_IP6TNL);
-	if (flags) {
-		g_set_error (error,
-		             NM_CONNECTION_ERROR,
-		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
-		             _("some flags are invalid for the select mode: %s"),
-		             nm_utils_enum_to_str (nm_ip_tunnel_flags_get_type (), flags));
-		g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME,
-		                NM_SETTING_IP_TUNNEL_FLAGS);
-		return FALSE;
-	}
-
-	if (   nm_connection_get_setting_wired (connection)
-	    && !_nm_ip_tunnel_mode_is_layer2 (priv->mode)) {
-		g_set_error (error,
-		             NM_CONNECTION_ERROR,
-		             NM_CONNECTION_ERROR_INVALID_PROPERTY,
-		             _("wired setting not allowed for mode %s"),
-		             nm_utils_enum_to_str (nm_ip_tunnel_mode_get_type (), priv->mode));
-		g_prefix_error (error, "%s.%s: ", NM_SETTING_IP_TUNNEL_SETTING_NAME,
-		                NM_SETTING_IP_TUNNEL_MODE);
-		return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
-	}
-
-	return TRUE;
+    NMSettingIPTunnelPrivate *priv   = NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting);
+    int                       family = AF_UNSPEC;
+    guint32                   flags;
+
+    switch (priv->mode) {
+    case NM_IP_TUNNEL_MODE_IPIP:
+    case NM_IP_TUNNEL_MODE_SIT:
+    case NM_IP_TUNNEL_MODE_ISATAP:
+    case NM_IP_TUNNEL_MODE_GRE:
+    case NM_IP_TUNNEL_MODE_VTI:
+    case NM_IP_TUNNEL_MODE_GRETAP:
+        family = AF_INET;
+        break;
+    case NM_IP_TUNNEL_MODE_IP6IP6:
+    case NM_IP_TUNNEL_MODE_IPIP6:
+    case NM_IP_TUNNEL_MODE_IP6GRE:
+    case NM_IP_TUNNEL_MODE_VTI6:
+    case NM_IP_TUNNEL_MODE_IP6GRETAP:
+        family = AF_INET6;
+        break;
+    case NM_IP_TUNNEL_MODE_UNKNOWN:
+        break;
+    }
+
+    if (family == AF_UNSPEC) {
+        g_set_error(error,
+                    NM_CONNECTION_ERROR,
+                    NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                    _("'%d' is not a valid tunnel mode"),
+                    (int) priv->mode);
+        g_prefix_error(error,
+                       "%s.%s: ",
+                       NM_SETTING_IP_TUNNEL_SETTING_NAME,
+                       NM_SETTING_IP_TUNNEL_MODE);
+        return FALSE;
+    }
+
+    if (priv->parent && !nm_utils_ifname_valid_kernel(priv->parent, NULL)
+        && !nm_utils_is_uuid(priv->parent)) {
+        g_set_error(error,
+                    NM_CONNECTION_ERROR,
+                    NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                    _("'%s' is neither an UUID nor an interface name"),
+                    priv->parent);
+        g_prefix_error(error,
+                       "%s.%s: ",
+                       NM_SETTING_IP_TUNNEL_SETTING_NAME,
+                       NM_SETTING_IP_TUNNEL_PARENT);
+        return FALSE;
+    }
+
+    if (priv->local && !nm_utils_ipaddr_is_valid(family, priv->local)) {
+        g_set_error(error,
+                    NM_CONNECTION_ERROR,
+                    NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                    _("'%s' is not a valid IPv%c address"),
+                    priv->local,
+                    family == AF_INET ? '4' : '6');
+        g_prefix_error(error,
+                       "%s.%s: ",
+                       NM_SETTING_IP_TUNNEL_SETTING_NAME,
+                       NM_SETTING_IP_TUNNEL_LOCAL);
+        return FALSE;
+    }
+
+    if (!priv->remote) {
+        g_set_error_literal(error,
+                            NM_CONNECTION_ERROR,
+                            NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                            _("property is missing"));
+        g_prefix_error(error,
+                       "%s.%s: ",
+                       NM_SETTING_IP_TUNNEL_SETTING_NAME,
+                       NM_SETTING_IP_TUNNEL_REMOTE);
+        return FALSE;
+    }
+
+    if (!nm_utils_ipaddr_is_valid(family, priv->remote)) {
+        g_set_error(error,
+                    NM_CONNECTION_ERROR,
+                    NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                    _("'%s' is not a valid IPv%c address"),
+                    priv->remote,
+                    family == AF_INET ? '4' : '6');
+        g_prefix_error(error,
+                       "%s.%s: ",
+                       NM_SETTING_IP_TUNNEL_SETTING_NAME,
+                       NM_SETTING_IP_TUNNEL_REMOTE);
+        return FALSE;
+    }
+
+    if ((priv->input_key && priv->input_key[0]) || (priv->output_key && priv->output_key[0])) {
+        if (!NM_IN_SET(priv->mode,
+                       NM_IP_TUNNEL_MODE_GRE,
+                       NM_IP_TUNNEL_MODE_GRETAP,
+                       NM_IP_TUNNEL_MODE_IP6GRE,
+                       NM_IP_TUNNEL_MODE_IP6GRETAP)) {
+            g_set_error_literal(error,
+                                NM_CONNECTION_ERROR,
+                                NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                                _("tunnel keys can only be specified for GRE tunnels"));
+            return FALSE;
+        }
+    }
+
+    if (priv->input_key && priv->input_key[0]) {
+        gint64 val;
+
+        val = _nm_utils_ascii_str_to_int64(priv->input_key, 10, 0, G_MAXUINT32, -1);
+        if (val == -1) {
+            g_set_error(error,
+                        NM_CONNECTION_ERROR,
+                        NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                        _("'%s' is not a valid tunnel key"),
+                        priv->input_key);
+            g_prefix_error(error,
+                           "%s.%s: ",
+                           NM_SETTING_IP_TUNNEL_SETTING_NAME,
+                           NM_SETTING_IP_TUNNEL_INPUT_KEY);
+            return FALSE;
+        }
+    }
+
+    if (priv->output_key && priv->output_key[0]) {
+        gint64 val;
+
+        val = _nm_utils_ascii_str_to_int64(priv->output_key, 10, 0, G_MAXUINT32, -1);
+        if (val == -1) {
+            g_set_error(error,
+                        NM_CONNECTION_ERROR,
+                        NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                        _("'%s' is not a valid tunnel key"),
+                        priv->output_key);
+            g_prefix_error(error,
+                           "%s.%s: ",
+                           NM_SETTING_IP_TUNNEL_SETTING_NAME,
+                           NM_SETTING_IP_TUNNEL_OUTPUT_KEY);
+            return FALSE;
+        }
+    }
+
+    if (!priv->path_mtu_discovery && priv->ttl != 0) {
+        g_set_error_literal(error,
+                            NM_CONNECTION_ERROR,
+                            NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                            _("a fixed TTL is allowed only when path MTU discovery is enabled"));
+        g_prefix_error(error,
+                       "%s.%s: ",
+                       NM_SETTING_IP_TUNNEL_SETTING_NAME,
+                       NM_SETTING_IP_TUNNEL_TTL);
+        return FALSE;
+    }
+
+    flags = priv->flags;
+    if (NM_IN_SET(priv->mode, NM_IP_TUNNEL_MODE_IPIP6, NM_IP_TUNNEL_MODE_IP6IP6))
+        flags &= (guint32)(~_NM_IP_TUNNEL_FLAG_ALL_IP6TNL);
+    if (flags) {
+        g_set_error(error,
+                    NM_CONNECTION_ERROR,
+                    NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                    _("some flags are invalid for the select mode: %s"),
+                    nm_utils_enum_to_str(nm_ip_tunnel_flags_get_type(), flags));
+        g_prefix_error(error,
+                       "%s.%s: ",
+                       NM_SETTING_IP_TUNNEL_SETTING_NAME,
+                       NM_SETTING_IP_TUNNEL_FLAGS);
+        return FALSE;
+    }
+
+    if (nm_connection_get_setting_wired(connection) && !_nm_ip_tunnel_mode_is_layer2(priv->mode)) {
+        g_set_error(error,
+                    NM_CONNECTION_ERROR,
+                    NM_CONNECTION_ERROR_INVALID_PROPERTY,
+                    _("wired setting not allowed for mode %s"),
+                    nm_utils_enum_to_str(nm_ip_tunnel_mode_get_type(), priv->mode));
+        g_prefix_error(error,
+                       "%s.%s: ",
+                       NM_SETTING_IP_TUNNEL_SETTING_NAME,
+                       NM_SETTING_IP_TUNNEL_MODE);
+        return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
+    }
+
+    return TRUE;
 }
 
 /*****************************************************************************/
 
 static void
-get_property (GObject *object, guint prop_id,
-              GValue *value, GParamSpec *pspec)
+get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
 {
-	NMSettingIPTunnel *setting = NM_SETTING_IP_TUNNEL (object);
-	NMSettingIPTunnelPrivate *priv = NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting);
-
-	switch (prop_id) {
-	case PROP_PARENT:
-		g_value_set_string (value, priv->parent);
-		break;
-	case PROP_MODE:
-		g_value_set_uint (value, priv->mode);
-		break;
-	case PROP_LOCAL:
-		g_value_set_string (value, priv->local);
-		break;
-	case PROP_REMOTE:
-		g_value_set_string (value, priv->remote);
-		break;
-	case PROP_TTL:
-		g_value_set_uint (value, priv->ttl);
-		break;
-	case PROP_TOS:
-		g_value_set_uint (value, priv->tos);
-		break;
-	case PROP_PATH_MTU_DISCOVERY:
-		g_value_set_boolean (value, priv->path_mtu_discovery);
-		break;
-	case PROP_INPUT_KEY:
-		g_value_set_string (value, priv->input_key);
-		break;
-	case PROP_OUTPUT_KEY:
-		g_value_set_string (value, priv->output_key);
-		break;
-	case PROP_ENCAPSULATION_LIMIT:
-		g_value_set_uint (value, priv->encapsulation_limit);
-		break;
-	case PROP_FLOW_LABEL:
-		g_value_set_uint (value, priv->flow_label);
-		break;
-	case PROP_MTU:
-		g_value_set_uint (value, priv->mtu);
-		break;
-	case PROP_FLAGS:
-		g_value_set_uint (value, priv->flags);
-		break;
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
+    NMSettingIPTunnel *       setting = NM_SETTING_IP_TUNNEL(object);
+    NMSettingIPTunnelPrivate *priv    = NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting);
+
+    switch (prop_id) {
+    case PROP_PARENT:
+        g_value_set_string(value, priv->parent);
+        break;
+    case PROP_MODE:
+        g_value_set_uint(value, priv->mode);
+        break;
+    case PROP_LOCAL:
+        g_value_set_string(value, priv->local);
+        break;
+    case PROP_REMOTE:
+        g_value_set_string(value, priv->remote);
+        break;
+    case PROP_TTL:
+        g_value_set_uint(value, priv->ttl);
+        break;
+    case PROP_TOS:
+        g_value_set_uint(value, priv->tos);
+        break;
+    case PROP_PATH_MTU_DISCOVERY:
+        g_value_set_boolean(value, priv->path_mtu_discovery);
+        break;
+    case PROP_INPUT_KEY:
+        g_value_set_string(value, priv->input_key);
+        break;
+    case PROP_OUTPUT_KEY:
+        g_value_set_string(value, priv->output_key);
+        break;
+    case PROP_ENCAPSULATION_LIMIT:
+        g_value_set_uint(value, priv->encapsulation_limit);
+        break;
+    case PROP_FLOW_LABEL:
+        g_value_set_uint(value, priv->flow_label);
+        break;
+    case PROP_MTU:
+        g_value_set_uint(value, priv->mtu);
+        break;
+    case PROP_FLAGS:
+        g_value_set_uint(value, priv->flags);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+        break;
+    }
 }
 
 static void
-set_property (GObject *object, guint prop_id,
-              const GValue *value, GParamSpec *pspec)
+set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
 {
-	NMSettingIPTunnel *setting = NM_SETTING_IP_TUNNEL (object);
-	NMSettingIPTunnelPrivate *priv = NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting);
-
-	switch (prop_id) {
-	case PROP_PARENT:
-		g_free (priv->parent);
-		priv->parent = g_value_dup_string (value);
-		break;
-	case PROP_MODE:
-		priv->mode = g_value_get_uint (value);
-		break;
-	case PROP_LOCAL:
-		g_free (priv->local);
-		priv->local = g_value_dup_string (value);
-		break;
-	case PROP_REMOTE:
-		g_free (priv->remote);
-		priv->remote = g_value_dup_string (value);
-		break;
-	case PROP_TTL:
-		priv->ttl = g_value_get_uint (value);
-		break;
-	case PROP_TOS:
-		priv->tos = g_value_get_uint (value);
-		break;
-	case PROP_PATH_MTU_DISCOVERY:
-		priv->path_mtu_discovery = g_value_get_boolean (value);
-		break;
-	case PROP_INPUT_KEY:
-		g_free (priv->input_key);
-		priv->input_key = g_value_dup_string (value);
-		break;
-	case PROP_OUTPUT_KEY:
-		g_free (priv->output_key);
-		priv->output_key = g_value_dup_string (value);
-		break;
-	case PROP_ENCAPSULATION_LIMIT:
-		priv->encapsulation_limit = g_value_get_uint (value);
-		break;
-	case PROP_FLOW_LABEL:
-		priv->flow_label = g_value_get_uint (value);
-		break;
-	case PROP_MTU:
-		priv->mtu = g_value_get_uint (value);
-		break;
-	case PROP_FLAGS:
-		priv->flags = g_value_get_uint (value);
-		break;
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
+    NMSettingIPTunnel *       setting = NM_SETTING_IP_TUNNEL(object);
+    NMSettingIPTunnelPrivate *priv    = NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting);
+
+    switch (prop_id) {
+    case PROP_PARENT:
+        g_free(priv->parent);
+        priv->parent = g_value_dup_string(value);
+        break;
+    case PROP_MODE:
+        priv->mode = g_value_get_uint(value);
+        break;
+    case PROP_LOCAL:
+        g_free(priv->local);
+        priv->local = g_value_dup_string(value);
+        break;
+    case PROP_REMOTE:
+        g_free(priv->remote);
+        priv->remote = g_value_dup_string(value);
+        break;
+    case PROP_TTL:
+        priv->ttl = g_value_get_uint(value);
+        break;
+    case PROP_TOS:
+        priv->tos = g_value_get_uint(value);
+        break;
+    case PROP_PATH_MTU_DISCOVERY:
+        priv->path_mtu_discovery = g_value_get_boolean(value);
+        break;
+    case PROP_INPUT_KEY:
+        g_free(priv->input_key);
+        priv->input_key = g_value_dup_string(value);
+        break;
+    case PROP_OUTPUT_KEY:
+        g_free(priv->output_key);
+        priv->output_key = g_value_dup_string(value);
+        break;
+    case PROP_ENCAPSULATION_LIMIT:
+        priv->encapsulation_limit = g_value_get_uint(value);
+        break;
+    case PROP_FLOW_LABEL:
+        priv->flow_label = g_value_get_uint(value);
+        break;
+    case PROP_MTU:
+        priv->mtu = g_value_get_uint(value);
+        break;
+    case PROP_FLAGS:
+        priv->flags = g_value_get_uint(value);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+        break;
+    }
 }
 
 /*****************************************************************************/
 
 static void
-nm_setting_ip_tunnel_init (NMSettingIPTunnel *self)
+nm_setting_ip_tunnel_init(NMSettingIPTunnel *self)
 {
-	NMSettingIPTunnelPrivate *priv = NM_SETTING_IP_TUNNEL_GET_PRIVATE (self);
+    NMSettingIPTunnelPrivate *priv = NM_SETTING_IP_TUNNEL_GET_PRIVATE(self);
 
-	priv->path_mtu_discovery = TRUE;
+    priv->path_mtu_discovery = TRUE;
 }
 
 /**
@@ -599,239 +615,253 @@ nm_setting_ip_tunnel_init (NMSettingIPTunnel *self)
  * Since: 1.2
  **/
 NMSetting *
-nm_setting_ip_tunnel_new (void)
+nm_setting_ip_tunnel_new(void)
 {
-	return (NMSetting *) g_object_new (NM_TYPE_SETTING_IP_TUNNEL, NULL);
+    return (NMSetting *) g_object_new(NM_TYPE_SETTING_IP_TUNNEL, NULL);
 }
 
 static void
-finalize (GObject *object)
+finalize(GObject *object)
 {
-	NMSettingIPTunnel *setting = NM_SETTING_IP_TUNNEL (object);
-	NMSettingIPTunnelPrivate *priv = NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting);
+    NMSettingIPTunnel *       setting = NM_SETTING_IP_TUNNEL(object);
+    NMSettingIPTunnelPrivate *priv    = NM_SETTING_IP_TUNNEL_GET_PRIVATE(setting);
 
-	g_free (priv->parent);
-	g_free (priv->local);
-	g_free (priv->remote);
-	g_free (priv->input_key);
-	g_free (priv->output_key);
+    g_free(priv->parent);
+    g_free(priv->local);
+    g_free(priv->remote);
+    g_free(priv->input_key);
+    g_free(priv->output_key);
 
-	G_OBJECT_CLASS (nm_setting_ip_tunnel_parent_class)->finalize (object);
+    G_OBJECT_CLASS(nm_setting_ip_tunnel_parent_class)->finalize(object);
 }
 
 static void
-nm_setting_ip_tunnel_class_init (NMSettingIPTunnelClass *klass)
+nm_setting_ip_tunnel_class_init(NMSettingIPTunnelClass *klass)
 {
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-	NMSettingClass *setting_class = NM_SETTING_CLASS (klass);
-
-	g_type_class_add_private (klass, sizeof (NMSettingIPTunnelPrivate));
-
-	object_class->get_property = get_property;
-	object_class->set_property = set_property;
-	object_class->finalize     = finalize;
-
-	setting_class->verify = verify;
-
-	/**
-	 * NMSettingIPTunnel:parent:
-	 *
-	 * If given, specifies the parent interface name or parent connection UUID
-	 * the new device will be bound to so that tunneled packets will only be
-	 * routed via that interface.
-	 *
-	 * Since: 1.2
-	 **/
-	obj_properties[PROP_PARENT] =
-	    g_param_spec_string (NM_SETTING_IP_TUNNEL_PARENT, "", "",
-	                         NULL,
-	                         G_PARAM_READWRITE |
-	                         NM_SETTING_PARAM_INFERRABLE |
-	                         G_PARAM_STATIC_STRINGS);
-
-	/**
-	 * NMSettingIPTunnel:mode:
-	 *
-	 * The tunneling mode, for example %NM_IP_TUNNEL_MODE_IPIP or
-	 * %NM_IP_TUNNEL_MODE_GRE.
-	 *
-	 * Since: 1.2
-	 **/
-	obj_properties[PROP_MODE] =
-	    g_param_spec_uint (NM_SETTING_IP_TUNNEL_MODE, "", "",
-	                       0, G_MAXUINT, 0,
-	                       G_PARAM_READWRITE |
-	                       NM_SETTING_PARAM_INFERRABLE |
-	                       G_PARAM_STATIC_STRINGS);
-
-	/**
-	 * NMSettingIPTunnel:local:
-	 *
-	 * The local endpoint of the tunnel; the value can be empty, otherwise it
-	 * must contain an IPv4 or IPv6 address.
-	 *
-	 * Since: 1.2
-	 **/
-	obj_properties[PROP_LOCAL] =
-	    g_param_spec_string (NM_SETTING_IP_TUNNEL_LOCAL, "", "",
-	                         NULL,
-	                         G_PARAM_READWRITE |
-	                         NM_SETTING_PARAM_INFERRABLE |
-	                         G_PARAM_STATIC_STRINGS);
-
-	/**
-	 * NMSettingIPTunnel:remote:
-	 *
-	 * The remote endpoint of the tunnel; the value must contain an IPv4 or IPv6
-	 * address.
-	 *
-	 * Since: 1.2
-	 **/
-	obj_properties[PROP_REMOTE] =
-	    g_param_spec_string (NM_SETTING_IP_TUNNEL_REMOTE, "", "",
-	                         NULL,
-	                         G_PARAM_READWRITE |
-	                         NM_SETTING_PARAM_INFERRABLE |
-	                         G_PARAM_STATIC_STRINGS);
-
-	/**
-	 * NMSettingIPTunnel:ttl
-	 *
-	 * The TTL to assign to tunneled packets. 0 is a special value meaning that
-	 * packets inherit the TTL value.
-	 *
-	 * Since: 1.2
-	 **/
-	obj_properties[PROP_TTL] =
-	    g_param_spec_uint (NM_SETTING_IP_TUNNEL_TTL, "", "",
-	                       0, 255, 0,
-	                       G_PARAM_READWRITE |
-	                       NM_SETTING_PARAM_INFERRABLE |
-	                       G_PARAM_STATIC_STRINGS);
-
-	/**
-	 * NMSettingIPTunnel:tos
-	 *
-	 * The type of service (IPv4) or traffic class (IPv6) field to be set on
-	 * tunneled packets.
-	 *
-	 * Since: 1.2
-	 **/
-	obj_properties[PROP_TOS] =
-	    g_param_spec_uint (NM_SETTING_IP_TUNNEL_TOS, "", "",
-	                       0, 255, 0,
-	                       G_PARAM_READWRITE |
-	                       NM_SETTING_PARAM_INFERRABLE |
-	                       G_PARAM_STATIC_STRINGS);
-
-	/**
-	 * NMSettingIPTunnel:path-mtu-discovery
-	 *
-	 * Whether to enable Path MTU Discovery on this tunnel.
-	 *
-	 * Since: 1.2
-	 **/
-	obj_properties[PROP_PATH_MTU_DISCOVERY] =
-	    g_param_spec_boolean (NM_SETTING_IP_TUNNEL_PATH_MTU_DISCOVERY, "", "",
-	                          TRUE,
-	                          G_PARAM_READWRITE |
-	                          NM_SETTING_PARAM_INFERRABLE |
-	                          G_PARAM_STATIC_STRINGS);
-
-	/**
-	 * NMSettingIPTunnel:input-key:
-	 *
-	 * The key used for tunnel input packets; the property is valid only for
-	 * certain tunnel modes (GRE, IP6GRE). If empty, no key is used.
-	 *
-	 * Since: 1.2
-	 **/
-	obj_properties[PROP_INPUT_KEY] =
-	    g_param_spec_string (NM_SETTING_IP_TUNNEL_INPUT_KEY, "", "",
-	                         NULL,
-	                         G_PARAM_READWRITE |
-	                         NM_SETTING_PARAM_INFERRABLE |
-	                         G_PARAM_STATIC_STRINGS);
-
-	/**
-	 * NMSettingIPTunnel:output-key:
-	 *
-	 * The key used for tunnel output packets; the property is valid only for
-	 * certain tunnel modes (GRE, IP6GRE). If empty, no key is used.
-	 *
-	 * Since: 1.2
-	 **/
-	obj_properties[PROP_OUTPUT_KEY] =
-	    g_param_spec_string (NM_SETTING_IP_TUNNEL_OUTPUT_KEY, "", "",
-	                         NULL,
-	                         G_PARAM_READWRITE |
-	                         NM_SETTING_PARAM_INFERRABLE |
-	                         G_PARAM_STATIC_STRINGS);
-
-	/**
-	 * NMSettingIPTunnel:encapsulation-limit:
-	 *
-	 * How many additional levels of encapsulation are permitted to be prepended
-	 * to packets. This property applies only to IPv6 tunnels.
-	 *
-	 * Since: 1.2
-	 **/
-	obj_properties[PROP_ENCAPSULATION_LIMIT] =
-	    g_param_spec_uint (NM_SETTING_IP_TUNNEL_ENCAPSULATION_LIMIT, "", "",
-	                       0, 255, 0,
-	                       G_PARAM_READWRITE |
-	                       NM_SETTING_PARAM_INFERRABLE |
-	                       G_PARAM_STATIC_STRINGS);
-
-	/**
-	 * NMSettingIPTunnel:flow-label:
-	 *
-	 * The flow label to assign to tunnel packets. This property applies only to
-	 * IPv6 tunnels.
-	 *
-	 * Since: 1.2
-	 **/
-	obj_properties[PROP_FLOW_LABEL] =
-	    g_param_spec_uint (NM_SETTING_IP_TUNNEL_FLOW_LABEL, "", "",
-	                       0, (1 << 20) - 1, 0,
-	                       G_PARAM_READWRITE |
-	                       NM_SETTING_PARAM_INFERRABLE |
-	                       G_PARAM_STATIC_STRINGS);
-
-	/**
-	 * NMSettingIPTunnel:mtu:
-	 *
-	 * If non-zero, only transmit packets of the specified size or smaller,
-	 * breaking larger packets up into multiple fragments.
-	 *
-	 * Since: 1.2
-	 **/
-	obj_properties[PROP_MTU] =
-	    g_param_spec_uint (NM_SETTING_IP_TUNNEL_MTU, "", "",
-	                       0, G_MAXUINT32, 0,
-	                       G_PARAM_READWRITE |
-	                       NM_SETTING_PARAM_FUZZY_IGNORE |
-	                       G_PARAM_STATIC_STRINGS);
-
-	/**
-	 * NMSettingIPTunnel:flags:
-	 *
-	 * Tunnel flags. Currently the following values are supported:
-	 * %NM_IP_TUNNEL_FLAG_IP6_IGN_ENCAP_LIMIT, %NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_TCLASS,
-	 * %NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FLOWLABEL, %NM_IP_TUNNEL_FLAG_IP6_MIP6_DEV,
-	 * %NM_IP_TUNNEL_FLAG_IP6_RCV_DSCP_COPY, %NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FWMARK.
-	 * They are valid only for IPv6 tunnels.
-	 *
-	 * Since: 1.12
-	 **/
-	obj_properties[PROP_FLAGS] =
-	    g_param_spec_uint (NM_SETTING_IP_TUNNEL_FLAGS, "", "",
-	                       0, G_MAXUINT32, 0,
-	                       G_PARAM_READWRITE |
-	                       NM_SETTING_PARAM_FUZZY_IGNORE |
-	                       G_PARAM_STATIC_STRINGS);
-
-	g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
-
-	_nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_IP_TUNNEL);
+    GObjectClass *  object_class  = G_OBJECT_CLASS(klass);
+    NMSettingClass *setting_class = NM_SETTING_CLASS(klass);
+
+    g_type_class_add_private(klass, sizeof(NMSettingIPTunnelPrivate));
+
+    object_class->get_property = get_property;
+    object_class->set_property = set_property;
+    object_class->finalize     = finalize;
+
+    setting_class->verify = verify;
+
+    /**
+     * NMSettingIPTunnel:parent:
+     *
+     * If given, specifies the parent interface name or parent connection UUID
+     * the new device will be bound to so that tunneled packets will only be
+     * routed via that interface.
+     *
+     * Since: 1.2
+     **/
+    obj_properties[PROP_PARENT] = g_param_spec_string(
+        NM_SETTING_IP_TUNNEL_PARENT,
+        "",
+        "",
+        NULL,
+        G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS);
+
+    /**
+     * NMSettingIPTunnel:mode:
+     *
+     * The tunneling mode, for example %NM_IP_TUNNEL_MODE_IPIP or
+     * %NM_IP_TUNNEL_MODE_GRE.
+     *
+     * Since: 1.2
+     **/
+    obj_properties[PROP_MODE] =
+        g_param_spec_uint(NM_SETTING_IP_TUNNEL_MODE,
+                          "",
+                          "",
+                          0,
+                          G_MAXUINT,
+                          0,
+                          G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS);
+
+    /**
+     * NMSettingIPTunnel:local:
+     *
+     * The local endpoint of the tunnel; the value can be empty, otherwise it
+     * must contain an IPv4 or IPv6 address.
+     *
+     * Since: 1.2
+     **/
+    obj_properties[PROP_LOCAL] = g_param_spec_string(NM_SETTING_IP_TUNNEL_LOCAL,
+                                                     "",
+                                                     "",
+                                                     NULL,
+                                                     G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE
+                                                         | G_PARAM_STATIC_STRINGS);
+
+    /**
+     * NMSettingIPTunnel:remote:
+     *
+     * The remote endpoint of the tunnel; the value must contain an IPv4 or IPv6
+     * address.
+     *
+     * Since: 1.2
+     **/
+    obj_properties[PROP_REMOTE] = g_param_spec_string(
+        NM_SETTING_IP_TUNNEL_REMOTE,
+        "",
+        "",
+        NULL,
+        G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS);
+
+    /**
+     * NMSettingIPTunnel:ttl
+     *
+     * The TTL to assign to tunneled packets. 0 is a special value meaning that
+     * packets inherit the TTL value.
+     *
+     * Since: 1.2
+     **/
+    obj_properties[PROP_TTL] =
+        g_param_spec_uint(NM_SETTING_IP_TUNNEL_TTL,
+                          "",
+                          "",
+                          0,
+                          255,
+                          0,
+                          G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS);
+
+    /**
+     * NMSettingIPTunnel:tos
+     *
+     * The type of service (IPv4) or traffic class (IPv6) field to be set on
+     * tunneled packets.
+     *
+     * Since: 1.2
+     **/
+    obj_properties[PROP_TOS] =
+        g_param_spec_uint(NM_SETTING_IP_TUNNEL_TOS,
+                          "",
+                          "",
+                          0,
+                          255,
+                          0,
+                          G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS);
+
+    /**
+     * NMSettingIPTunnel:path-mtu-discovery
+     *
+     * Whether to enable Path MTU Discovery on this tunnel.
+     *
+     * Since: 1.2
+     **/
+    obj_properties[PROP_PATH_MTU_DISCOVERY] = g_param_spec_boolean(
+        NM_SETTING_IP_TUNNEL_PATH_MTU_DISCOVERY,
+        "",
+        "",
+        TRUE,
+        G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS);
+
+    /**
+     * NMSettingIPTunnel:input-key:
+     *
+     * The key used for tunnel input packets; the property is valid only for
+     * certain tunnel modes (GRE, IP6GRE). If empty, no key is used.
+     *
+     * Since: 1.2
+     **/
+    obj_properties[PROP_INPUT_KEY] = g_param_spec_string(
+        NM_SETTING_IP_TUNNEL_INPUT_KEY,
+        "",
+        "",
+        NULL,
+        G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS);
+
+    /**
+     * NMSettingIPTunnel:output-key:
+     *
+     * The key used for tunnel output packets; the property is valid only for
+     * certain tunnel modes (GRE, IP6GRE). If empty, no key is used.
+     *
+     * Since: 1.2
+     **/
+    obj_properties[PROP_OUTPUT_KEY] = g_param_spec_string(
+        NM_SETTING_IP_TUNNEL_OUTPUT_KEY,
+        "",
+        "",
+        NULL,
+        G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS);
+
+    /**
+     * NMSettingIPTunnel:encapsulation-limit:
+     *
+     * How many additional levels of encapsulation are permitted to be prepended
+     * to packets. This property applies only to IPv6 tunnels.
+     *
+     * Since: 1.2
+     **/
+    obj_properties[PROP_ENCAPSULATION_LIMIT] =
+        g_param_spec_uint(NM_SETTING_IP_TUNNEL_ENCAPSULATION_LIMIT,
+                          "",
+                          "",
+                          0,
+                          255,
+                          0,
+                          G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS);
+
+    /**
+     * NMSettingIPTunnel:flow-label:
+     *
+     * The flow label to assign to tunnel packets. This property applies only to
+     * IPv6 tunnels.
+     *
+     * Since: 1.2
+     **/
+    obj_properties[PROP_FLOW_LABEL] =
+        g_param_spec_uint(NM_SETTING_IP_TUNNEL_FLOW_LABEL,
+                          "",
+                          "",
+                          0,
+                          (1 << 20) - 1,
+                          0,
+                          G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS);
+
+    /**
+     * NMSettingIPTunnel:mtu:
+     *
+     * If non-zero, only transmit packets of the specified size or smaller,
+     * breaking larger packets up into multiple fragments.
+     *
+     * Since: 1.2
+     **/
+    obj_properties[PROP_MTU] = g_param_spec_uint(NM_SETTING_IP_TUNNEL_MTU,
+                                                 "",
+                                                 "",
+                                                 0,
+                                                 G_MAXUINT32,
+                                                 0,
+                                                 G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE
+                                                     | G_PARAM_STATIC_STRINGS);
+
+    /**
+     * NMSettingIPTunnel:flags:
+     *
+     * Tunnel flags. Currently, the following values are supported:
+     * %NM_IP_TUNNEL_FLAG_IP6_IGN_ENCAP_LIMIT, %NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_TCLASS,
+     * %NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FLOWLABEL, %NM_IP_TUNNEL_FLAG_IP6_MIP6_DEV,
+     * %NM_IP_TUNNEL_FLAG_IP6_RCV_DSCP_COPY, %NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FWMARK.
+     * They are valid only for IPv6 tunnels.
+     *
+     * Since: 1.12
+     **/
+    obj_properties[PROP_FLAGS] = g_param_spec_uint(NM_SETTING_IP_TUNNEL_FLAGS,
+                                                   "",
+                                                   "",
+                                                   0,
+                                                   G_MAXUINT32,
+                                                   0,
+                                                   G_PARAM_READWRITE | NM_SETTING_PARAM_FUZZY_IGNORE
+                                                       | G_PARAM_STATIC_STRINGS);
+
+    g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+
+    _nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_IP_TUNNEL);
 }