diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2017-12-22 10:24:25 +0100 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2018-01-03 15:30:45 +0100 |
commit | 269e7c624ba5bbdf990d8b36604f658ea7695b32 (patch) | |
tree | 228d5da028cf8f49f483d2660603e006f75ac8fc | |
parent | b936ccd2837199d5851388122c2e44951bf20012 (diff) | |
download | NetworkManager-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.c | 10 | ||||
-rw-r--r-- | clients/common/settings-docs.c.in | 1 | ||||
-rw-r--r-- | introspection/org.freedesktop.NetworkManager.Device.IPTunnel.xml | 7 | ||||
-rw-r--r-- | libnm-core/nm-setting-ip-tunnel.c | 67 | ||||
-rw-r--r-- | libnm-core/nm-setting-ip-tunnel.h | 28 | ||||
-rw-r--r-- | libnm/libnm.ver | 2 | ||||
-rw-r--r-- | src/devices/nm-device-ip-tunnel.c | 19 | ||||
-rw-r--r-- | src/devices/nm-device-ip-tunnel.h | 1 | ||||
-rw-r--r-- | src/platform/nm-linux-platform.c | 47 | ||||
-rw-r--r-- | src/platform/nm-platform.c | 4 | ||||
-rw-r--r-- | src/platform/nm-platform.h | 2 | ||||
-rw-r--r-- | src/platform/tests/test-common.c | 13 | ||||
-rw-r--r-- | src/platform/tests/test-link.c | 64 |
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); |