summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2017-12-22 10:24:25 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2018-01-03 15:30:45 +0100
commit269e7c624ba5bbdf990d8b36604f658ea7695b32 (patch)
tree228d5da028cf8f49f483d2660603e006f75ac8fc
parentb936ccd2837199d5851388122c2e44951bf20012 (diff)
downloadNetworkManager-bg/ip-tunnel-flags.tar.gz
ip-tunnel: add support for tunnel flagsbg/ip-tunnel-flags
Implement support for IP tunnel flags. Currently only some IPv6 tunnel flags are supported. Example: # nmcli connection add type ip-tunnel mode ip6ip6 \ ip-tunnel.flags ip6-ign-encap-limit,ip6-use-orig-tclass \ ifname abc ip-tunnel.parent ens8 ipv4.method disabled \ ipv6.method manual ipv6.address ::8888 remote ::42 # ip -d l 61: abc@ens8: <NOARP,UP,LOWER_UP> mtu 1460 qdisc noqueue ... link/tunnel6 :: brd ::42 promiscuity 0 ip6tnl ip6ip6 remote ::42 local :: dev ens8 encaplimit none hoplimit 0 tclass inherit ... https://bugzilla.gnome.org/show_bug.cgi?id=791846
-rw-r--r--clients/common/nm-meta-setting-desc.c10
-rw-r--r--clients/common/settings-docs.c.in1
-rw-r--r--introspection/org.freedesktop.NetworkManager.Device.IPTunnel.xml7
-rw-r--r--libnm-core/nm-setting-ip-tunnel.c67
-rw-r--r--libnm-core/nm-setting-ip-tunnel.h28
-rw-r--r--libnm/libnm.ver2
-rw-r--r--src/devices/nm-device-ip-tunnel.c19
-rw-r--r--src/devices/nm-device-ip-tunnel.h1
-rw-r--r--src/platform/nm-linux-platform.c47
-rw-r--r--src/platform/nm-platform.c4
-rw-r--r--src/platform/nm-platform.h2
-rw-r--r--src/platform/tests/test-common.c13
-rw-r--r--src/platform/tests/test-link.c64
13 files changed, 244 insertions, 21 deletions
diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c
index b2e8b9b4a4..afbaceb2fa 100644
--- a/clients/common/nm-meta-setting-desc.c
+++ b/clients/common/nm-meta-setting-desc.c
@@ -6149,6 +6149,16 @@ static const NMMetaPropertyInfo *const property_infos_IP_TUNNEL[] = {
PROPERTY_INFO_WITH_DESC (NM_SETTING_IP_TUNNEL_MTU,
.property_type = &_pt_gobject_mtu,
),
+ PROPERTY_INFO_WITH_DESC (NM_SETTING_IP_TUNNEL_FLAGS,
+ .property_type = &_pt_gobject_enum,
+ .property_typ_data = DEFINE_PROPERTY_TYP_DATA (
+ PROPERTY_TYP_DATA_SUBTYPE (gobject_enum,
+ .get_gtype = nm_ip_tunnel_flags_get_type,
+ ),
+ .typ_flags = NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT
+ | NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PRETTY_TEXT,
+ ),
+ ),
NULL
};
diff --git a/clients/common/settings-docs.c.in b/clients/common/settings-docs.c.in
index 7725c7deaf..8f3a95763f 100644
--- a/clients/common/settings-docs.c.in
+++ b/clients/common/settings-docs.c.in
@@ -194,6 +194,7 @@
#define DESCRIBE_DOC_NM_SETTING_INFINIBAND_PARENT N_("The interface name of the parent device of this device. Normally NULL, but if the \"p_key\" property is set, then you must specify the base device by setting either this property or \"mac-address\".")
#define DESCRIBE_DOC_NM_SETTING_INFINIBAND_TRANSPORT_MODE N_("The IP-over-InfiniBand transport mode. Either \"datagram\" or \"connected\".")
#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_ENCAPSULATION_LIMIT N_("How many additional levels of encapsulation are permitted to be prepended to packets. This property applies only to IPv6 tunnels.")
+#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_FLAGS N_("Tunnel flags. Currently the following values are supported: NM_IP_TUNNEL_FLAG_IP6_IGN_ENCAP_LIMIT (0x1), NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_TCLASS (0x2), NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FLOWLABEL (0x4), NM_IP_TUNNEL_FLAG_IP6_MIP6_DEV (0x8), NM_IP_TUNNEL_FLAG_IP6_RCV_DSCP_COPY (0x10), NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FWMARK (0x20). They are valid only for IPv6 tunnels.")
#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_FLOW_LABEL N_("The flow label to assign to tunnel packets. This property applies only to IPv6 tunnels.")
#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_INPUT_KEY N_("The key used for tunnel input packets; the property is valid only for certain tunnel modes (GRE, IP6GRE). If empty, no key is used.")
#define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_LOCAL N_("The local endpoint of the tunnel; the value can be empty, otherwise it must contain an IPv4 or IPv6 address.")
diff --git a/introspection/org.freedesktop.NetworkManager.Device.IPTunnel.xml b/introspection/org.freedesktop.NetworkManager.Device.IPTunnel.xml
index ef92f3a992..7c464b9478 100644
--- a/introspection/org.freedesktop.NetworkManager.Device.IPTunnel.xml
+++ b/introspection/org.freedesktop.NetworkManager.Device.IPTunnel.xml
@@ -89,6 +89,13 @@
<property name="FlowLabel" type="u" access="read"/>
<!--
+ Flags:
+
+ Tunnel flags.
+ -->
+ <property name="Flags" type="u" access="read"/>
+
+ <!--
PropertiesChanged:
@properties: A dictionary mapping property names to variant boxed values
diff --git a/libnm-core/nm-setting-ip-tunnel.c b/libnm-core/nm-setting-ip-tunnel.c
index fa8d4a7a24..bf313d5237 100644
--- a/libnm-core/nm-setting-ip-tunnel.c
+++ b/libnm-core/nm-setting-ip-tunnel.c
@@ -49,6 +49,7 @@ typedef struct {
guint encapsulation_limit;
guint flow_label;
guint mtu;
+ guint flags;
} NMSettingIPTunnelPrivate;
enum {
@@ -65,6 +66,7 @@ enum {
PROP_ENCAPSULATION_LIMIT,
PROP_FLOW_LABEL,
PROP_MTU,
+ PROP_FLAGS,
LAST_PROP
};
@@ -285,6 +287,24 @@ nm_setting_ip_tunnel_get_mtu (NMSettingIPTunnel *setting)
return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->mtu;
}
+/*
+ * nm_setting_ip_tunnel_get_flags:
+ * @setting: the #NMSettingIPTunnel
+ *
+ * Returns the #NMSettingIPTunnel:flags property of the setting.
+ *
+ * Returns: the tunnel flags
+ *
+ * Since: 1.12
+ **/
+guint
+nm_setting_ip_tunnel_get_flags (NMSettingIPTunnel *setting)
+{
+ g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), 0);
+
+ return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->flags;
+}
+
/*****************************************************************************/
static gboolean
@@ -292,6 +312,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
{
NMSettingIPTunnelPrivate *priv = NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting);
int family = AF_UNSPEC;
+ guint flags;
switch (priv->mode) {
case NM_IP_TUNNEL_MODE_IPIP:
@@ -419,6 +440,26 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
return FALSE;
}
+ flags = priv->flags;
+ if (family == AF_INET6) {
+ flags &= ~( 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);
+ }
+ 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;
+ }
+
return TRUE;
}
@@ -491,6 +532,9 @@ set_property (GObject *object, guint prop_id,
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;
@@ -541,6 +585,9 @@ get_property (GObject *object, guint prop_id,
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;
@@ -773,4 +820,24 @@ nm_setting_ip_tunnel_class_init (NMSettingIPTunnelClass *setting_class)
G_PARAM_CONSTRUCT |
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
+ **/
+ g_object_class_install_property
+ (object_class, PROP_FLAGS,
+ g_param_spec_uint (NM_SETTING_IP_TUNNEL_FLAGS, "", "",
+ 0, G_MAXUINT, 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ NM_SETTING_PARAM_FUZZY_IGNORE |
+ G_PARAM_STATIC_STRINGS));
}
diff --git a/libnm-core/nm-setting-ip-tunnel.h b/libnm-core/nm-setting-ip-tunnel.h
index dfa6211685..c53dc0d71f 100644
--- a/libnm-core/nm-setting-ip-tunnel.h
+++ b/libnm-core/nm-setting-ip-tunnel.h
@@ -50,6 +50,7 @@ G_BEGIN_DECLS
#define NM_SETTING_IP_TUNNEL_ENCAPSULATION_LIMIT "encapsulation-limit"
#define NM_SETTING_IP_TUNNEL_FLOW_LABEL "flow-label"
#define NM_SETTING_IP_TUNNEL_MTU "mtu"
+#define NM_SETTING_IP_TUNNEL_FLAGS "flags"
/**
* NMSettingIPTunnel:
@@ -67,6 +68,31 @@ typedef struct {
gpointer padding[4];
} NMSettingIPTunnelClass;
+/*
+ * NMIPTunnelFlags:
+ * @NM_IP_TUNNEL_FLAG_IP6_IGN_ENCAP_LIMIT: don't add encapsulation limit
+ * if one isn't present in inner packet
+ * @NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_TCLASS: copy the traffic class field
+ * from the inner packet
+ * @NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FLOWLABEL: copy the flowlabel from the
+ * inner packet
+ * @NM_IP_TUNNEL_FLAG_IP6_MIP6_DEV: used for Mobile IPv6
+ * @NM_IP_TUNNEL_FLAG_IP6_RCV_DSCP_COPY: copy DSCP from the outer packet
+ * @NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FWMARK: copy fwmark from inner packet
+ *
+ * IP tunnel flags.
+ *
+ * Since: 1.12
+ */
+typedef enum { /*< flags, prefix=NM_IP_TUNNEL_FLAG >*/
+ NM_IP_TUNNEL_FLAG_IP6_IGN_ENCAP_LIMIT = 0x1,
+ NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_TCLASS = 0x2,
+ NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FLOWLABEL = 0x4,
+ NM_IP_TUNNEL_FLAG_IP6_MIP6_DEV = 0x8,
+ NM_IP_TUNNEL_FLAG_IP6_RCV_DSCP_COPY = 0x10,
+ NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FWMARK = 0x20,
+} NMIPTunnelFlags;
+
NM_AVAILABLE_IN_1_2
GType nm_setting_ip_tunnel_get_type (void);
@@ -97,6 +123,8 @@ NM_AVAILABLE_IN_1_2
guint nm_setting_ip_tunnel_get_flow_label (NMSettingIPTunnel *setting);
NM_AVAILABLE_IN_1_2
guint nm_setting_ip_tunnel_get_mtu (NMSettingIPTunnel *setting);
+NM_AVAILABLE_IN_1_12
+guint nm_setting_ip_tunnel_get_flags (NMSettingIPTunnel *setting);
G_END_DECLS
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index 2014a30a52..16f5731252 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -1345,6 +1345,8 @@ global:
nm_client_checkpoint_rollback_async;
nm_client_checkpoint_rollback_finish;
nm_client_get_checkpoints;
+ nm_ip_tunnel_flags_get_type;
+ nm_setting_ip_tunnel_get_flags;
nm_setting_vpn_get_data_keys;
nm_setting_vpn_get_secret_keys;
} libnm_1_10_0;
diff --git a/src/devices/nm-device-ip-tunnel.c b/src/devices/nm-device-ip-tunnel.c
index af3cfe4c98..e0f1b40566 100644
--- a/src/devices/nm-device-ip-tunnel.c
+++ b/src/devices/nm-device-ip-tunnel.c
@@ -55,6 +55,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceIPTunnel,
PROP_OUTPUT_KEY,
PROP_ENCAPSULATION_LIMIT,
PROP_FLOW_LABEL,
+ PROP_FLAGS,
);
typedef struct {
@@ -69,6 +70,7 @@ typedef struct {
char *output_key;
guint8 encap_limit;
guint32 flow_label;
+ NMIPTunnelFlags flags;
} NMDeviceIPTunnelPrivate;
struct _NMDeviceIPTunnel {
@@ -129,6 +131,7 @@ update_properties_from_ifindex (NMDevice *device, int ifindex)
guint8 ttl = 0, tos = 0, encap_limit = 0;
gboolean pmtud = FALSE;
guint32 flow_label = 0;
+ NMIPTunnelFlags flags = 0;
char *key;
if (ifindex <= 0) {
@@ -246,6 +249,7 @@ clear:
tos = lnk->tclass;
encap_limit = lnk->encap_limit;
flow_label = lnk->flow_label;
+ flags = lnk->flags;
} else
g_return_if_reached ();
@@ -307,6 +311,11 @@ out:
priv->flow_label = flow_label;
_notify (self, PROP_FLOW_LABEL);
}
+
+ if (priv->flags != flags) {
+ priv->flags = flags;
+ _notify (self, PROP_FLAGS);
+ }
}
static void
@@ -685,6 +694,7 @@ create_and_realize (NMDevice *device,
lnk_ip6tnl.encap_limit = nm_setting_ip_tunnel_get_encapsulation_limit (s_ip_tunnel);
lnk_ip6tnl.flow_label = nm_setting_ip_tunnel_get_flow_label (s_ip_tunnel);
lnk_ip6tnl.proto = nm_setting_ip_tunnel_get_mode (s_ip_tunnel) == NM_IP_TUNNEL_MODE_IPIP6 ? IPPROTO_IPIP : IPPROTO_IPV6;
+ lnk_ip6tnl.flags = nm_setting_ip_tunnel_get_flags (s_ip_tunnel);
plerr = nm_platform_link_ip6tnl_add (nm_device_get_platform (device), iface, &lnk_ip6tnl, out_plink);
if (plerr != NM_PLATFORM_ERROR_SUCCESS) {
@@ -814,6 +824,9 @@ get_property (GObject *object, guint prop_id,
case PROP_FLOW_LABEL:
g_value_set_uint (value, priv->flow_label);
break;
+ case PROP_FLAGS:
+ g_value_set_uint (value, priv->flags);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -959,6 +972,12 @@ nm_device_ip_tunnel_class_init (NMDeviceIPTunnelClass *klass)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
+ obj_properties[PROP_FLAGS] =
+ g_param_spec_uint (NM_DEVICE_IP_TUNNEL_FLAGS, "", "",
+ 0, G_MAXUINT, 0,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass),
diff --git a/src/devices/nm-device-ip-tunnel.h b/src/devices/nm-device-ip-tunnel.h
index 4bff6e33e8..6f1fcd756e 100644
--- a/src/devices/nm-device-ip-tunnel.h
+++ b/src/devices/nm-device-ip-tunnel.h
@@ -41,6 +41,7 @@
#define NM_DEVICE_IP_TUNNEL_OUTPUT_KEY "output-key"
#define NM_DEVICE_IP_TUNNEL_ENCAPSULATION_LIMIT "encapsulation-limit"
#define NM_DEVICE_IP_TUNNEL_FLOW_LABEL "flow-label"
+#define NM_DEVICE_IP_TUNNEL_FLAGS "flags"
/* defined in the parent class, but exposed on D-Bus by the subclass. */
#define NM_DEVICE_IP_TUNNEL_PARENT NM_DEVICE_PARENT
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index 76285dd7d7..8a45cf6fc4 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -36,6 +36,7 @@
#include <linux/if_link.h>
#include <linux/if_tun.h>
#include <linux/if_tunnel.h>
+#include <linux/ip6_tunnel.h>
#include <netlink/netlink.h>
#include <netlink/msg.h>
#include <libudev.h>
@@ -715,6 +716,48 @@ _addrtime_get_lifetimes (guint32 timestamp,
/*****************************************************************************/
+static const struct {
+ NMIPTunnelFlags s;
+ guint32 p;
+} ip6tnl_flags_map[] = {
+ { NM_IP_TUNNEL_FLAG_IP6_IGN_ENCAP_LIMIT, IP6_TNL_F_IGN_ENCAP_LIMIT },
+ { NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_TCLASS, IP6_TNL_F_USE_ORIG_TCLASS },
+ { NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FLOWLABEL, IP6_TNL_F_USE_ORIG_FLOWLABEL },
+ { NM_IP_TUNNEL_FLAG_IP6_MIP6_DEV, IP6_TNL_F_MIP6_DEV },
+ { NM_IP_TUNNEL_FLAG_IP6_RCV_DSCP_COPY, IP6_TNL_F_RCV_DSCP_COPY },
+ { NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FWMARK, IP6_TNL_F_USE_ORIG_FWMARK },
+};
+
+static guint32
+ip6tnl_flags_setting_to_plat (NMIPTunnelFlags flags)
+{
+ guint32 ret = 0;
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS (ip6tnl_flags_map); i++) {
+ if (NM_FLAGS_ANY (flags, ip6tnl_flags_map[i].s))
+ ret |= ip6tnl_flags_map[i].p;
+ }
+
+ return ret;
+}
+
+static NMIPTunnelFlags
+ip6tnl_flags_plat_to_setting (guint32 flags)
+{
+ NMIPTunnelFlags ret = 0;
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS (ip6tnl_flags_map); i++) {
+ if (NM_FLAGS_ANY (flags, ip6tnl_flags_map[i].p))
+ ret |= ip6tnl_flags_map[i].s;
+ }
+
+ return ret;
+}
+
+/*****************************************************************************/
+
static const NMPObject *
_lookup_cached_link (const NMPCache *cache, int ifindex, gboolean *completed_from_cache, const NMPObject **link_cached)
{
@@ -1292,6 +1335,7 @@ _parse_lnk_ip6tnl (const char *kind, struct nlattr *info_data)
[IFLA_IPTUN_ENCAP_LIMIT] = { .type = NLA_U8 },
[IFLA_IPTUN_FLOWINFO] = { .type = NLA_U32 },
[IFLA_IPTUN_PROTO] = { .type = NLA_U8 },
+ [IFLA_IPTUN_FLAGS] = { .type = NLA_U32 },
};
struct nlattr *tb[IFLA_IPTUN_MAX + 1];
int err;
@@ -1326,6 +1370,8 @@ _parse_lnk_ip6tnl (const char *kind, struct nlattr *info_data)
}
if (tb[IFLA_IPTUN_PROTO])
props->proto = nla_get_u8 (tb[IFLA_IPTUN_PROTO]);
+ if (tb[IFLA_IPTUN_FLAGS])
+ props->flags = ip6tnl_flags_plat_to_setting (nla_get_u32 (tb[IFLA_IPTUN_FLAGS]));
return obj;
}
@@ -5386,6 +5432,7 @@ link_ip6tnl_add (NMPlatform *platform,
& IP6_FLOWINFO_TCLASS_MASK;
NLA_PUT_U32 (nlmsg, IFLA_IPTUN_FLOWINFO, htonl (flowinfo));
NLA_PUT_U8 (nlmsg, IFLA_IPTUN_PROTO, props->proto);
+ NLA_PUT_U32 (nlmsg, IFLA_IPTUN_FLAGS, ip6tnl_flags_setting_to_plat (props->flags));
nla_nest_end (nlmsg, data);
nla_nest_end (nlmsg, info);
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
index d1f2e0d49a..2e30e4b86f 100644
--- a/src/platform/nm-platform.c
+++ b/src/platform/nm-platform.c
@@ -4751,6 +4751,7 @@ nm_platform_lnk_ip6tnl_to_string (const NMPlatformLnkIp6Tnl *lnk, char *buf, gsi
"%s" /* encap limit */
"%s" /* flow label */
"%s" /* proto */
+ " flags %s"
"",
nm_sprintf_buf (str_remote, " remote %s", nm_utils_inet6_ntop (&lnk->remote, str_remote1)),
nm_sprintf_buf (str_local, " local %s", nm_utils_inet6_ntop (&lnk->local, str_local1)),
@@ -4759,7 +4760,8 @@ nm_platform_lnk_ip6tnl_to_string (const NMPlatformLnkIp6Tnl *lnk, char *buf, gsi
lnk->tclass == 1 ? " tclass inherit" : nm_sprintf_buf (str_tclass, " tclass 0x%x", lnk->tclass),
nm_sprintf_buf (str_encap, " encap-limit %u", lnk->encap_limit),
nm_sprintf_buf (str_flow, " flow-label 0x05%x", lnk->flow_label),
- nm_sprintf_buf (str_proto, " proto %u", lnk->proto));
+ nm_sprintf_buf (str_proto, " proto %u", lnk->proto),
+ nm_utils_enum_to_str (nm_ip_tunnel_flags_get_type(), lnk->flags));
return buf;
}
diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h
index 3266558fb0..d69c1f9967 100644
--- a/src/platform/nm-platform.h
+++ b/src/platform/nm-platform.h
@@ -32,6 +32,7 @@
#include "nm-core-utils.h"
#include "nm-setting-vlan.h"
#include "nm-setting-wired.h"
+#include "nm-setting-ip-tunnel.h"
#define NM_TYPE_PLATFORM (nm_platform_get_type ())
#define NM_PLATFORM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_PLATFORM, NMPlatform))
@@ -606,6 +607,7 @@ typedef struct {
guint8 encap_limit;
guint8 proto;
guint flow_label;
+ NMIPTunnelFlags flags;
} NMPlatformLnkIp6Tnl;
typedef struct {
diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c
index df82e9163f..53a8d2dd17 100644
--- a/src/platform/tests/test-common.c
+++ b/src/platform/tests/test-common.c
@@ -1283,6 +1283,10 @@ nmtstp_link_ip6tnl_add (NMPlatform *platform,
const NMPlatformLink *pllink = NULL;
gboolean success;
char buffer[INET6_ADDRSTRLEN];
+ char encap[20];
+ char tclass[20];
+ gboolean encap_ignore;
+ gboolean tclass_inherit;
g_assert (nm_utils_is_valid_iface_name (name, NULL));
@@ -1308,15 +1312,18 @@ nmtstp_link_ip6tnl_add (NMPlatform *platform,
g_assert_not_reached ();
}
- success = !nmtstp_run_command ("ip -6 tunnel add %s mode %s %s local %s remote %s ttl %u tclass %02x encaplimit %u flowlabel %x",
+ encap_ignore = NM_FLAGS_HAS (lnk->flags, NM_IP_TUNNEL_FLAG_IP6_IGN_ENCAP_LIMIT);
+ tclass_inherit = NM_FLAGS_HAS (lnk->flags, NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_TCLASS);
+
+ success = !nmtstp_run_command ("ip -6 tunnel add %s mode %s %s local %s remote %s ttl %u tclass %s encaplimit %s flowlabel %x",
name,
mode,
dev,
nm_utils_inet6_ntop (&lnk->local, NULL),
nm_utils_inet6_ntop (&lnk->remote, buffer),
lnk->ttl,
- lnk->tclass,
- lnk->encap_limit,
+ tclass_inherit ? "inherit" : nm_sprintf_buf (tclass, "%02x", lnk->tclass),
+ encap_ignore ? "none" : nm_sprintf_buf (encap, "%u", lnk->encap_limit),
lnk->flow_label);
if (success)
pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_IP6TNL, 100);
diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c
index ad25ea577b..0ff5406e6f 100644
--- a/src/platform/tests/test-link.c
+++ b/src/platform/tests/test-link.c
@@ -760,13 +760,27 @@ test_software_detect (gconstpointer user_data)
gracefully_skip = nm_utils_modprobe (NULL, TRUE, "ip6_tunnel", NULL) != 0;
}
- lnk_ip6tnl.local = *nmtst_inet6_from_string ("fd01::15");
- lnk_ip6tnl.remote = *nmtst_inet6_from_string ("fd01::16");
- lnk_ip6tnl.parent_ifindex = ifindex_parent;
- lnk_ip6tnl.tclass = 20;
- lnk_ip6tnl.encap_limit = 6;
- lnk_ip6tnl.flow_label = 1337;
- lnk_ip6tnl.proto = IPPROTO_IPV6;
+ switch (test_data->test_mode) {
+ case 0:
+ lnk_ip6tnl.local = *nmtst_inet6_from_string ("fd01::15");
+ lnk_ip6tnl.remote = *nmtst_inet6_from_string ("fd01::16");
+ lnk_ip6tnl.parent_ifindex = ifindex_parent;
+ lnk_ip6tnl.tclass = 20;
+ lnk_ip6tnl.encap_limit = 6;
+ lnk_ip6tnl.flow_label = 1337;
+ lnk_ip6tnl.proto = IPPROTO_IPV6;
+ break;
+ case 1:
+ lnk_ip6tnl.local = *nmtst_inet6_from_string ("fd01::17");
+ lnk_ip6tnl.remote = *nmtst_inet6_from_string ("fd01::18");
+ lnk_ip6tnl.parent_ifindex = ifindex_parent;
+ lnk_ip6tnl.tclass = 0;
+ lnk_ip6tnl.encap_limit = 0;
+ lnk_ip6tnl.flow_label = 1338;
+ lnk_ip6tnl.proto = IPPROTO_IPV6;
+ lnk_ip6tnl.flags = NM_IP_TUNNEL_FLAG_IP6_IGN_ENCAP_LIMIT | NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_TCLASS;
+ break;
+ }
if (!nmtstp_link_ip6tnl_add (NULL, ext, DEVICE_NAME, &lnk_ip6tnl)) {
if (gracefully_skip) {
@@ -930,15 +944,30 @@ test_software_detect (gconstpointer user_data)
case NM_LINK_TYPE_IP6TNL: {
const NMPlatformLnkIp6Tnl *plnk = &lnk->lnk_ip6tnl;
- g_assert (plnk == nm_platform_link_get_lnk_ip6tnl (NM_PLATFORM_GET, ifindex, NULL));
- g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent);
- nmtst_assert_ip6_address (&plnk->local, "fd01::15");
- nmtst_assert_ip6_address (&plnk->remote, "fd01::16");
- g_assert_cmpint (plnk->ttl, ==, 0);
- g_assert_cmpint (plnk->tclass, ==, 20);
- g_assert_cmpint (plnk->encap_limit, ==, 6);
- g_assert_cmpint (plnk->flow_label, ==, 1337);
- g_assert_cmpint (plnk->proto, ==, IPPROTO_IPV6);
+ switch (test_data->test_mode) {
+ case 0:
+ g_assert (plnk == nm_platform_link_get_lnk_ip6tnl (NM_PLATFORM_GET, ifindex, NULL));
+ g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent);
+ nmtst_assert_ip6_address (&plnk->local, "fd01::15");
+ nmtst_assert_ip6_address (&plnk->remote, "fd01::16");
+ g_assert_cmpint (plnk->ttl, ==, 0);
+ g_assert_cmpint (plnk->tclass, ==, 20);
+ g_assert_cmpint (plnk->encap_limit, ==, 6);
+ g_assert_cmpint (plnk->flow_label, ==, 1337);
+ g_assert_cmpint (plnk->proto, ==, IPPROTO_IPV6);
+ break;
+ case 1:
+ g_assert (plnk == nm_platform_link_get_lnk_ip6tnl (NM_PLATFORM_GET, ifindex, NULL));
+ g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent);
+ nmtst_assert_ip6_address (&plnk->local, "fd01::17");
+ nmtst_assert_ip6_address (&plnk->remote, "fd01::18");
+ g_assert_cmpint (plnk->ttl, ==, 0);
+ g_assert_cmpint (plnk->flow_label, ==, 1338);
+ g_assert_cmpint (plnk->proto, ==, IPPROTO_IPV6);
+ g_assert_cmpint (plnk->flags, ==, NM_IP_TUNNEL_FLAG_IP6_IGN_ENCAP_LIMIT
+ | NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_TCLASS);
+ break;
+ }
break;
}
case NM_LINK_TYPE_IPIP: {
@@ -2528,7 +2557,8 @@ _nmtstp_setup_tests (void)
g_test_add_func ("/link/external", test_external);
test_software_detect_add ("/link/software/detect/gre", NM_LINK_TYPE_GRE, 0);
- test_software_detect_add ("/link/software/detect/ip6tnl", NM_LINK_TYPE_IP6TNL, 0);
+ test_software_detect_add ("/link/software/detect/ip6tnl/0", NM_LINK_TYPE_IP6TNL, 0);
+ test_software_detect_add ("/link/software/detect/ip6tnl/1", NM_LINK_TYPE_IP6TNL, 1);
test_software_detect_add ("/link/software/detect/ipip", NM_LINK_TYPE_IPIP, 0);
test_software_detect_add ("/link/software/detect/macvlan", NM_LINK_TYPE_MACVLAN, 0);
test_software_detect_add ("/link/software/detect/macvtap", NM_LINK_TYPE_MACVTAP, 0);