mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-06 16:21:50 +00:00
ip-tunnel: add support for 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
This commit is contained in:
parent
686afe531a
commit
da4c9e51a0
|
@ -6149,6 +6149,14 @@ 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,
|
||||
),
|
||||
),
|
||||
),
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
|
@ -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.")
|
||||
|
|
|
@ -88,6 +88,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
|
||||
|
|
|
@ -27,4 +27,13 @@ typedef struct {
|
|||
guint32 to;
|
||||
} NMVlanQosMapping;
|
||||
|
||||
#define _NM_IP_TUNNEL_FLAG_ALL_IP6TNL \
|
||||
( 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 \
|
||||
)
|
||||
|
||||
#endif /* NM_CORE_TYPES_INTERNAL_H */
|
||||
|
|
|
@ -49,6 +49,7 @@ typedef struct {
|
|||
guint encapsulation_limit;
|
||||
guint flow_label;
|
||||
guint mtu;
|
||||
guint32 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
|
||||
**/
|
||||
NMIPTunnelFlags
|
||||
nm_setting_ip_tunnel_get_flags (NMSettingIPTunnel *setting)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
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;
|
||||
guint32 flags;
|
||||
|
||||
switch (priv->mode) {
|
||||
case NM_IP_TUNNEL_MODE_IPIP:
|
||||
|
@ -419,6 +440,20 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
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;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -491,6 +526,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 +579,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 +814,23 @@ 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_MAXUINT32, 0,
|
||||
G_PARAM_READWRITE |
|
||||
NM_SETTING_PARAM_FUZZY_IGNORE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
|
|
@ -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,33 @@ typedef struct {
|
|||
gpointer padding[4];
|
||||
} NMSettingIPTunnelClass;
|
||||
|
||||
/*
|
||||
* NMIPTunnelFlags:
|
||||
* @NM_IP_TUNNEL_FLAG_NONE: no flag
|
||||
* @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_NONE = 0x0,
|
||||
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 +125,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
|
||||
NMIPTunnelFlags nm_setting_ip_tunnel_get_flags (NMSettingIPTunnel *setting);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -1345,6 +1345,9 @@ global:
|
|||
nm_client_checkpoint_rollback_async;
|
||||
nm_client_checkpoint_rollback_finish;
|
||||
nm_client_get_checkpoints;
|
||||
nm_device_ip_tunnel_get_flags;
|
||||
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;
|
||||
|
|
|
@ -46,6 +46,7 @@ typedef struct {
|
|||
char *output_key;
|
||||
guint8 encap_limit;
|
||||
guint32 flow_label;
|
||||
guint32 flags;
|
||||
} NMDeviceIPTunnelPrivate;
|
||||
|
||||
enum {
|
||||
|
@ -61,6 +62,7 @@ enum {
|
|||
PROP_OUTPUT_KEY,
|
||||
PROP_ENCAPSULATION_LIMIT,
|
||||
PROP_FLOW_LABEL,
|
||||
PROP_FLAGS,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
@ -242,6 +244,22 @@ nm_device_ip_tunnel_get_flow_label (NMDeviceIPTunnel *device)
|
|||
return NM_DEVICE_IP_TUNNEL_GET_PRIVATE (device)->flow_label;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_device_ip_tunnel_get_flags:
|
||||
* @device: a #NMDeviceIPTunnel
|
||||
*
|
||||
* Returns: the tunnel flags
|
||||
*
|
||||
* Since: 1.12
|
||||
**/
|
||||
NMIPTunnelFlags
|
||||
nm_device_ip_tunnel_get_flags (NMDeviceIPTunnel *device)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_DEVICE_IP_TUNNEL (device), NM_IP_TUNNEL_FLAG_NONE);
|
||||
|
||||
return NM_DEVICE_IP_TUNNEL_GET_PRIVATE (device)->flags;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
|
||||
{
|
||||
|
@ -286,6 +304,7 @@ init_dbus (NMObject *object)
|
|||
{ NM_DEVICE_IP_TUNNEL_OUTPUT_KEY, &priv->output_key },
|
||||
{ NM_DEVICE_IP_TUNNEL_ENCAPSULATION_LIMIT, &priv->encap_limit },
|
||||
{ NM_DEVICE_IP_TUNNEL_FLOW_LABEL, &priv->flow_label },
|
||||
{ NM_DEVICE_IP_TUNNEL_FLAGS, &priv->flags },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
|
@ -352,6 +371,9 @@ get_property (GObject *object,
|
|||
case PROP_FLOW_LABEL:
|
||||
g_value_set_uint (value, nm_device_ip_tunnel_get_flow_label (device));
|
||||
break;
|
||||
case PROP_FLAGS:
|
||||
g_value_set_uint (value, nm_device_ip_tunnel_get_flags (device));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -536,4 +558,18 @@ nm_device_ip_tunnel_class_init (NMDeviceIPTunnelClass *bond_class)
|
|||
0, (1 << 20) - 1, 0,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* NMDeviceIPTunnel:flags:
|
||||
*
|
||||
* Tunnel flags.
|
||||
*
|
||||
* Since: 1.12
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_FLAGS,
|
||||
g_param_spec_uint (NM_DEVICE_IP_TUNNEL_FLAGS, "", "",
|
||||
0, G_MAXUINT32, 0,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#endif
|
||||
|
||||
#include "nm-device.h"
|
||||
#include "nm-setting-ip-tunnel.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
@ -47,6 +48,7 @@ G_BEGIN_DECLS
|
|||
#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"
|
||||
|
||||
/**
|
||||
* NMDeviceIPTunnel:
|
||||
|
@ -87,6 +89,8 @@ NM_AVAILABLE_IN_1_2
|
|||
guint8 nm_device_ip_tunnel_get_encapsulation_limit (NMDeviceIPTunnel *device);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
guint nm_device_ip_tunnel_get_flow_label (NMDeviceIPTunnel *device);
|
||||
NM_AVAILABLE_IN_1_12
|
||||
NMIPTunnelFlags nm_device_ip_tunnel_get_flags (NMDeviceIPTunnel *device);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
@ -86,6 +88,30 @@ G_DEFINE_TYPE (NMDeviceIPTunnel, nm_device_ip_tunnel, NM_TYPE_DEVICE)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static guint32
|
||||
ip6tnl_flags_setting_to_plat (NMIPTunnelFlags flags)
|
||||
{
|
||||
G_STATIC_ASSERT (NM_IP_TUNNEL_FLAG_IP6_IGN_ENCAP_LIMIT == IP6_TNL_F_IGN_ENCAP_LIMIT);
|
||||
G_STATIC_ASSERT (NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_TCLASS == IP6_TNL_F_USE_ORIG_TCLASS);
|
||||
G_STATIC_ASSERT (NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FLOWLABEL == IP6_TNL_F_USE_ORIG_FLOWLABEL);
|
||||
G_STATIC_ASSERT (NM_IP_TUNNEL_FLAG_IP6_MIP6_DEV == IP6_TNL_F_MIP6_DEV);
|
||||
G_STATIC_ASSERT (NM_IP_TUNNEL_FLAG_IP6_RCV_DSCP_COPY == IP6_TNL_F_RCV_DSCP_COPY);
|
||||
G_STATIC_ASSERT (NM_IP_TUNNEL_FLAG_IP6_USE_ORIG_FWMARK == IP6_TNL_F_USE_ORIG_FWMARK);
|
||||
|
||||
/* XXX: "accidentally", the numeric values correspond.
|
||||
* For flags added in the future, that might no longer
|
||||
* be the case. */
|
||||
return flags & _NM_IP_TUNNEL_FLAG_ALL_IP6TNL;
|
||||
}
|
||||
|
||||
static NMIPTunnelFlags
|
||||
ip6tnl_flags_plat_to_setting (guint32 flags)
|
||||
{
|
||||
return flags & ((guint32) _NM_IP_TUNNEL_FLAG_ALL_IP6TNL);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
address_equal_pp (int family, const char *a, const char *b)
|
||||
{
|
||||
|
@ -129,6 +155,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 = NM_IP_TUNNEL_FLAG_NONE;
|
||||
char *key;
|
||||
|
||||
if (ifindex <= 0) {
|
||||
|
@ -246,6 +273,7 @@ clear:
|
|||
tos = lnk->tclass;
|
||||
encap_limit = lnk->encap_limit;
|
||||
flow_label = lnk->flow_label;
|
||||
flags = ip6tnl_flags_plat_to_setting (lnk->flags);
|
||||
} else
|
||||
g_return_if_reached ();
|
||||
|
||||
|
@ -307,6 +335,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 +718,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 = ip6tnl_flags_setting_to_plat (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 +848,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 +996,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_MAXUINT32, 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),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
@ -1292,6 +1293,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 +1328,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 = nla_get_u32 (tb[IFLA_IPTUN_FLAGS]);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
@ -5386,6 +5390,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, props->flags);
|
||||
|
||||
nla_nest_end (nlmsg, data);
|
||||
nla_nest_end (nlmsg, info);
|
||||
|
|
|
@ -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 0x%x"
|
||||
"",
|
||||
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),
|
||||
(guint) lnk->flags);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
@ -5575,7 +5577,8 @@ nm_platform_lnk_ip6tnl_hash_update (const NMPlatformLnkIp6Tnl *obj, NMHashState
|
|||
obj->tclass,
|
||||
obj->encap_limit,
|
||||
obj->proto,
|
||||
obj->flow_label);
|
||||
obj->flow_label,
|
||||
obj->flags);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -5590,6 +5593,7 @@ nm_platform_lnk_ip6tnl_cmp (const NMPlatformLnkIp6Tnl *a, const NMPlatformLnkIp6
|
|||
NM_CMP_FIELD (a, b, encap_limit);
|
||||
NM_CMP_FIELD (a, b, flow_label);
|
||||
NM_CMP_FIELD (a, b, proto);
|
||||
NM_CMP_FIELD (a, b, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <linux/if.h>
|
||||
#include <linux/if_addr.h>
|
||||
#include <linux/if_link.h>
|
||||
#include <linux/ip6_tunnel.h>
|
||||
|
||||
#include "nm-dbus-interface.h"
|
||||
#include "nm-core-types-internal.h"
|
||||
|
@ -32,6 +33,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 +608,7 @@ typedef struct {
|
|||
guint8 encap_limit;
|
||||
guint8 proto;
|
||||
guint flow_label;
|
||||
guint32 flags;
|
||||
} NMPlatformLnkIp6Tnl;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -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, IP6_TNL_F_IGN_ENCAP_LIMIT);
|
||||
tclass_inherit = NM_FLAGS_HAS (lnk->flags, IP6_TNL_F_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);
|
||||
|
|
|
@ -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 = IP6_TNL_F_IGN_ENCAP_LIMIT | IP6_TNL_F_USE_ORIG_TCLASS;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!nmtstp_link_ip6tnl_add (NULL, ext, DEVICE_NAME, &lnk_ip6tnl)) {
|
||||
if (gracefully_skip) {
|
||||
|
@ -930,15 +944,31 @@ 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 & 0xFFFF, /* ignore kernel internal flags */
|
||||
==,
|
||||
IP6_TNL_F_IGN_ENCAP_LIMIT | IP6_TNL_F_USE_ORIG_TCLASS);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NM_LINK_TYPE_IPIP: {
|
||||
|
@ -2528,7 +2558,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);
|
||||
|
|
Loading…
Reference in a new issue