summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2015-09-14 17:38:16 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2015-09-14 17:38:55 +0200
commit214434e1cba32d0a0b1751545a82c699f5cfadd7 (patch)
treeb6ca349cfb1362322df5ba7a444b40815fe496af
parentf48345d6e9ac6dd2cdb91e31c2cd7b59339b6752 (diff)
downloadNetworkManager-bg/create-sw-devices-bgo749369-v3.tar.gz
device: support creation of IP tunnel devices (wip)bg/create-sw-devices-bgo749369-v3
-rw-r--r--libnm-core/nm-connection.c3
-rw-r--r--src/devices/nm-device-ip-tunnel.c328
-rw-r--r--src/devices/nm-device-ip-tunnel.h2
-rw-r--r--src/nm-types.h3
-rw-r--r--src/platform/nm-linux-platform.c37
-rw-r--r--src/platform/nm-platform.c8
-rw-r--r--src/platform/nm-platform.h4
7 files changed, 326 insertions, 59 deletions
diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c
index d1b944c276..fdef73b708 100644
--- a/libnm-core/nm-connection.c
+++ b/libnm-core/nm-connection.c
@@ -1564,7 +1564,8 @@ nm_connection_is_virtual (NMConnection *connection)
if ( !strcmp (type, NM_SETTING_BOND_SETTING_NAME)
|| !strcmp (type, NM_SETTING_TEAM_SETTING_NAME)
|| !strcmp (type, NM_SETTING_BRIDGE_SETTING_NAME)
- || !strcmp (type, NM_SETTING_VLAN_SETTING_NAME))
+ || !strcmp (type, NM_SETTING_VLAN_SETTING_NAME)
+ || !strcmp (type, NM_SETTING_IP_TUNNEL_SETTING_NAME))
return TRUE;
if (!strcmp (type, NM_SETTING_INFINIBAND_SETTING_NAME)) {
diff --git a/src/devices/nm-device-ip-tunnel.c b/src/devices/nm-device-ip-tunnel.c
index d46ff30d06..523b2d690a 100644
--- a/src/devices/nm-device-ip-tunnel.c
+++ b/src/devices/nm-device-ip-tunnel.c
@@ -29,6 +29,7 @@
#include "nm-default.h"
#include "nm-manager.h"
#include "nm-platform.h"
+#include "nm-setting-ip-tunnel.h"
#include "nmdbus-device-ip-tunnel.h"
@@ -39,14 +40,36 @@ G_DEFINE_TYPE (NMDeviceIPTunnel, nm_device_ip_tunnel, NM_TYPE_DEVICE)
#define NM_DEVICE_IP_TUNNEL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_IP_TUNNEL, NMDeviceIPTunnelPrivate))
+struct {
+ NMSettingIPTunnelMode mode;
+ NMLinkType type;
+ gint encap;
+} tunnel_types[] = {
+ { NM_SETTING_IP_TUNNEL_MODE_IPIP, NM_LINK_TYPE_IPIP, AF_INET },
+ { NM_SETTING_IP_TUNNEL_MODE_GRE, NM_LINK_TYPE_GRE, AF_INET },
+ { NM_SETTING_IP_TUNNEL_MODE_SIT, NM_LINK_TYPE_SIT, AF_INET },
+ { NM_SETTING_IP_TUNNEL_MODE_IPIP6, NM_LINK_TYPE_IP6TNL, AF_INET6 },
+ { NM_SETTING_IP_TUNNEL_MODE_IP6IP6, NM_LINK_TYPE_IP6TNL, AF_INET6 },
+ { NM_SETTING_IP_TUNNEL_MODE_IP6GRE, NM_LINK_TYPE_IP6GRE, AF_INET6 },
+};
+
typedef struct {
int parent_ifindex;
- char *local;
- char *remote;
+ union {
+ in_addr_t local4;
+ struct in6_addr local6;
+ };
+ union {
+ in_addr_t remote4;
+ struct in6_addr remote6;
+ };
guint8 ttl;
guint8 tos;
gboolean path_mtu_discovery;
+
+ NMSettingIPTunnelMode mode;
NMLinkType link_type;
+ gint encap;
} NMDeviceIPTunnelPrivate;
enum {
@@ -66,7 +89,6 @@ update_properties (NMDeviceIPTunnel *self)
NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (self);
GObject *object = G_OBJECT (self);
NMPlatformIPTunnelProperties props;
- char buf[INET6_ADDRSTRLEN];
if (!nm_platform_ip_tunnel_get_properties (NM_PLATFORM_GET, priv->link_type,
nm_device_get_ifindex (NM_DEVICE (self)),
@@ -75,6 +97,7 @@ update_properties (NMDeviceIPTunnel *self)
return;
}
+ g_assert (props.encap == priv->encap);
g_object_freeze_notify (object);
if (priv->parent_ifindex != props.parent_ifindex) {
@@ -82,24 +105,24 @@ update_properties (NMDeviceIPTunnel *self)
g_object_notify (object, NM_DEVICE_IP_TUNNEL_PARENT);
}
- if (props.encap == AF_INET)
- inet_ntop (AF_INET, &props.local4, buf, sizeof (buf));
- else
- inet_ntop (AF_INET6, &props.local6, buf, sizeof (buf));
-
- if (!g_strcmp0 (priv->local, buf)) {
- g_free (priv->local);
- g_object_notify (object, NM_DEVICE_IP_TUNNEL_LOCAL);
- }
-
- if (props.encap == AF_INET)
- inet_ntop (AF_INET, &props.remote4, buf, sizeof (buf));
- else
- inet_ntop (AF_INET6, &props.remote6, buf, sizeof (buf));
-
- if (!g_strcmp0 (priv->remote, buf)) {
- g_free (priv->remote);
- g_object_notify (object, NM_DEVICE_IP_TUNNEL_REMOTE);
+ if (props.encap == AF_INET) {
+ if (priv->local4 != props.local4) {
+ priv->local4 = props.local4;
+ g_object_notify (object, NM_DEVICE_IP_TUNNEL_LOCAL);
+ }
+ if (priv->remote4 != props.remote4) {
+ priv->remote4 = props.remote4;
+ g_object_notify (object, NM_DEVICE_IP_TUNNEL_REMOTE);
+ }
+ } else if (props.encap == AF_INET6) {
+ if (!memcmp (&priv->local6, &props.local6, sizeof (struct in6_addr))) {
+ memcpy (&priv->local6, &props.local6, sizeof (struct in6_addr));
+ g_object_notify (object, NM_DEVICE_IP_TUNNEL_LOCAL);
+ }
+ if (!memcmp (&priv->remote6, &props.remote6, sizeof (struct in6_addr))) {
+ memcpy (&priv->remote6, &props.remote6, sizeof (struct in6_addr));
+ g_object_notify (object, NM_DEVICE_IP_TUNNEL_REMOTE);
+ }
}
if (priv->ttl != props.ttl) {
@@ -120,30 +143,247 @@ update_properties (NMDeviceIPTunnel *self)
g_object_thaw_notify (object);
}
+static gboolean
+create_and_realize (NMDevice *device,
+ NMConnection *connection,
+ NMDevice *parent,
+ NMPlatformLink *out_plink,
+ GError **error)
+{
+ NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (device);
+ const char *iface = nm_device_get_iface (device);
+ NMSettingIPTunnel *s_tunnel;
+ NMPlatformError plerr;
+ const char *str;
+
+ s_tunnel = nm_connection_get_setting_ip_tunnel (connection);
+ g_assert (s_tunnel);
+ g_assert (out_plink);
+
+ if (priv->encap == AF_INET) {
+ in_addr_t local = 0, remote = 0;
+
+ str = nm_setting_ip_tunnel_get_local (s_tunnel);
+ if (str)
+ inet_pton (AF_INET, str, &local);
+
+ str = nm_setting_ip_tunnel_get_remote (s_tunnel);
+ g_assert (str);
+ inet_pton (AF_INET, str, &remote);
+
+ plerr = nm_platform_ip4_tunnel_add (NM_PLATFORM_GET, priv->link_type, iface, local, remote,
+ nm_setting_ip_tunnel_get_ttl (s_tunnel), out_plink);
+ } else {
+ struct in6_addr local = { }, remote = { };
+
+ str = nm_setting_ip_tunnel_get_local (s_tunnel);
+ if (str)
+ inet_pton (AF_INET6, str, &local);
+
+ str = nm_setting_ip_tunnel_get_remote (s_tunnel);
+ g_assert (str);
+ inet_pton (AF_INET6, str, &remote);
+
+ plerr = nm_platform_ip6_tunnel_add (NM_PLATFORM_GET, /* FIXME */ IPPROTO_IP, iface, &local, &remote,
+ nm_setting_ip_tunnel_get_ttl (s_tunnel), out_plink);
+ }
+
+ if (plerr != NM_PLATFORM_ERROR_SUCCESS && plerr != NM_PLATFORM_ERROR_EXISTS) {
+ g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
+ "Failed to create IP tunnel interface '%s' for '%s': %s",
+ iface,
+ nm_connection_get_id (connection),
+ nm_platform_error_to_string (plerr));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+complete_connection (NMDevice *device,
+ NMConnection *connection,
+ const char *specific_object,
+ const GSList *existing_connections,
+ GError **error)
+{
+ NMSettingIPTunnel *s_tunnel;
+
+ nm_utils_complete_generic (connection,
+ NM_SETTING_IP_TUNNEL_SETTING_NAME,
+ existing_connections,
+ NULL,
+ _("IP Tunnel connection"),
+ NULL,
+ TRUE);
+
+ s_tunnel = nm_connection_get_setting_ip_tunnel (connection);
+ if (!s_tunnel) {
+ g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION,
+ "A 'ip-tunnel' setting is required.");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static inline gboolean
+ipv6_addr_any(const struct in6_addr *a)
+{
+ return a->__in6_u.__u6_addr32[0] == 0
+ && a->__in6_u.__u6_addr32[1] == 0
+ && a->__in6_u.__u6_addr32[2] == 0
+ && a->__in6_u.__u6_addr32[3] == 0;
+}
+
+
static void
-link_changed (NMDevice *device, NMPlatformLink *info)
+update_connection (NMDevice *device, NMConnection *connection)
{
- update_properties (NM_DEVICE_IP_TUNNEL (device));
+ NMDeviceIPTunnel *self = NM_DEVICE_IP_TUNNEL (device);
+ NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (self);
+ NMSettingIPTunnel *s_tunnel = nm_connection_get_setting_ip_tunnel (connection);
+ in_addr_t addr4;
+ struct in6_addr addr6;
+ const char *str;
+
+ if (!s_tunnel) {
+ s_tunnel = (NMSettingIPTunnel *) nm_setting_ip_tunnel_new ();
+ nm_connection_add_setting (connection, (NMSetting *) s_tunnel);
+ }
+
+ update_properties (self);
+
+ if (nm_setting_ip_tunnel_get_mode (s_tunnel) != priv->mode) {
+ priv->mode = nm_setting_ip_tunnel_get_mode (s_tunnel);
+ g_object_notify (G_OBJECT (s_tunnel), NM_SETTING_IP_TUNNEL_MODE);
+ }
+
+ if (priv->encap == AF_INET) {
+ str = nm_setting_ip_tunnel_get_local (s_tunnel);
+ if (!str) {
+ if (priv->local4) {
+ priv->local4 = 0;
+ g_object_notify (G_OBJECT (s_tunnel), NM_SETTING_IP_TUNNEL_LOCAL);
+ }
+ } else {
+ inet_pton (AF_INET, str, &addr4);
+ if (priv->local4 != addr4) {
+ priv->local4 = addr4;
+ g_object_notify (G_OBJECT (s_tunnel), NM_SETTING_IP_TUNNEL_LOCAL);
+ }
+ }
+
+ str = nm_setting_ip_tunnel_get_remote (s_tunnel);
+ if (!str) {
+ if (priv->remote4) {
+ priv->remote4 = 0;
+ g_object_notify (G_OBJECT (s_tunnel), NM_SETTING_IP_TUNNEL_REMOTE);
+ }
+ } else {
+ inet_pton (AF_INET, str, &addr4);
+ if (priv->remote4 != addr4) {
+ priv->remote4 = addr4;
+ g_object_notify (G_OBJECT (s_tunnel), NM_SETTING_IP_TUNNEL_REMOTE);
+ }
+ }
+ } else {
+ str = nm_setting_ip_tunnel_get_local (s_tunnel);
+ if (!str) {
+ if (!ipv6_addr_any (&priv->local6)) {
+ memset (&priv->local6, 0, sizeof (struct in6_addr));
+ g_object_notify (G_OBJECT (s_tunnel), NM_SETTING_IP_TUNNEL_LOCAL);
+ }
+ } else {
+ inet_pton (AF_INET6, str, &addr6);
+ if (memcmp (&priv->local6, &addr6, sizeof (struct in6_addr))) {
+ memcpy (&priv->local6, &addr6, sizeof (struct in6_addr));
+ g_object_notify (G_OBJECT (s_tunnel), NM_SETTING_IP_TUNNEL_LOCAL);
+ }
+ }
+
+ str = nm_setting_ip_tunnel_get_remote (s_tunnel);
+ if (!str) {
+ if (!ipv6_addr_any (&priv->remote6)) {
+ memset (&priv->remote6, 0, sizeof (struct in6_addr));
+ g_object_notify (G_OBJECT (s_tunnel), NM_SETTING_IP_TUNNEL_LOCAL);
+ }
+ } else {
+ inet_pton (AF_INET6, str, &addr6);
+ if (memcmp (&priv->remote6, &addr6, sizeof (struct in6_addr))) {
+ memcpy (&priv->remote6, &addr6, sizeof (struct in6_addr));
+ g_object_notify (G_OBJECT (s_tunnel), NM_SETTING_IP_TUNNEL_REMOTE);
+ }
+ }
+ }
+
+ if (nm_setting_ip_tunnel_get_ttl (s_tunnel) != priv->ttl) {
+ priv->ttl = nm_setting_ip_tunnel_get_ttl (s_tunnel);
+ g_object_notify (G_OBJECT (s_tunnel), NM_SETTING_IP_TUNNEL_TTL);
+ }
+}
+
+static gboolean
+addr_match (gint family, const char *str, void *addr)
+{
+ char buf[sizeof (struct in6_addr)] = { };
+
+ if (str)
+ inet_pton (family, str, buf);
+
+ return !memcmp (buf, addr, family == AF_INET ? sizeof (in_addr_t) : sizeof (struct in6_addr));
+}
+
+static gboolean
+check_connection_compatible (NMDevice *device, NMConnection *connection)
+{
+ NMDeviceIPTunnel *self = NM_DEVICE_IP_TUNNEL (device);
+ NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (self);
+ NMSettingIPTunnel *s_tunnel;
+
+ update_properties (self);
+
+ if (!NM_DEVICE_CLASS (nm_device_ip_tunnel_parent_class)->check_connection_compatible (device, connection))
+ return FALSE;
+
+ s_tunnel = nm_connection_get_setting_ip_tunnel (connection);
+ if (!s_tunnel)
+ return FALSE;
+
+ if (nm_setting_ip_tunnel_get_mode (s_tunnel) != priv->mode)
+ return FALSE;
+
+ if (!addr_match (priv->encap, nm_setting_ip_tunnel_get_local (s_tunnel), &priv->local4))
+ return FALSE;
+
+ if (!addr_match (priv->encap, nm_setting_ip_tunnel_get_remote (s_tunnel), &priv->remote4))
+ return FALSE;
+
+ if (nm_setting_ip_tunnel_get_ttl (s_tunnel) != priv->ttl)
+ return FALSE;
+
+ return TRUE;
}
static void
-nm_device_ip_tunnel_init (NMDeviceIPTunnel *self)
+link_changed (NMDevice *device, NMPlatformLink *info)
{
+ update_properties (NM_DEVICE_IP_TUNNEL (device));
}
static void
-constructed (GObject *object)
+nm_device_ip_tunnel_init (NMDeviceIPTunnel *self)
{
- update_properties (NM_DEVICE_IP_TUNNEL (object));
- G_OBJECT_CLASS (nm_device_ip_tunnel_parent_class)->constructed (object);
}
+
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (object);
NMDevice *parent;
+ char buf[INET6_ADDRSTRLEN];
switch (prop_id) {
case PROP_PARENT:
@@ -151,10 +391,10 @@ get_property (GObject *object, guint prop_id,
nm_utils_g_value_set_object_path (value, parent);
break;
case PROP_LOCAL:
- g_value_set_string (value, priv->local);
+ g_value_set_string (value, inet_ntop (priv->encap, &priv->local4, buf, sizeof (buf)));
break;
case PROP_REMOTE:
- g_value_set_string (value, priv->remote);
+ g_value_set_string (value, inet_ntop (priv->encap, &priv->remote4, buf, sizeof (buf)));
break;
case PROP_TTL:
g_value_set_uchar (value, priv->ttl);
@@ -179,10 +419,13 @@ nm_device_ip_tunnel_class_init (NMDeviceIPTunnelClass *klass)
g_type_class_add_private (klass, sizeof (NMDeviceIPTunnelPrivate));
- object_class->constructed = constructed;
object_class->get_property = get_property;
device_class->link_changed = link_changed;
+ device_class->create_and_realize = create_and_realize;
+ device_class->complete_connection = complete_connection;
+ device_class->update_connection = update_connection;
+ device_class->check_connection_compatible = check_connection_compatible;
/* properties */
g_object_class_install_property
@@ -244,6 +487,8 @@ create_device (NMDeviceFactory *factory,
{
NMDeviceIPTunnel *self;
NMDeviceIPTunnelPrivate *priv;
+ NMSettingIPTunnel *s_ip_tunnel = NULL;
+ gint i, mode = -1;
self = g_object_new (NM_TYPE_DEVICE_IP_TUNNEL,
NM_DEVICE_IFACE, iface,
@@ -252,12 +497,31 @@ create_device (NMDeviceFactory *factory,
NULL);
priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (self);
- priv->link_type = plink->type;
+
+ if (connection) {
+ s_ip_tunnel = nm_connection_get_setting_ip_tunnel (connection);
+ if (s_ip_tunnel)
+ mode = nm_setting_ip_tunnel_get_mode (s_ip_tunnel);
+ }
+
+ for (i = 0; i < G_N_ELEMENTS (tunnel_types); i++) {
+ if ( (plink && plink->type == tunnel_types[i].type)
+ || (mode > NM_SETTING_IP_TUNNEL_MODE_UNKNOWN && mode == tunnel_types[i].mode)) {
+ priv->mode = tunnel_types[i].mode;
+ priv->link_type = tunnel_types[i].type;
+ priv->encap = tunnel_types[i].encap;
+ break;
+ }
+ }
+
+ g_assert (i < G_N_ELEMENTS (tunnel_types));
return (NMDevice *) self;
}
NM_DEVICE_FACTORY_DEFINE_INTERNAL (IP_TUNNEL, IPTunnel, ip_tunnel,
- NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_IPIP, NM_LINK_TYPE_GRE, NM_LINK_TYPE_SIT, NM_LINK_TYPE_IPIP6, NM_LINK_TYPE_IP6IP6),
+ NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_IPIP, NM_LINK_TYPE_GRE, NM_LINK_TYPE_SIT, NM_LINK_TYPE_IP6TNL)
+ NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_IP_TUNNEL_SETTING_NAME),
factory_iface->create_device = create_device;
)
+
diff --git a/src/devices/nm-device-ip-tunnel.h b/src/devices/nm-device-ip-tunnel.h
index 911151f57f..1084ecc11c 100644
--- a/src/devices/nm-device-ip-tunnel.h
+++ b/src/devices/nm-device-ip-tunnel.h
@@ -21,7 +21,7 @@
#ifndef __NETWORKMANAGER_DEVICE_IP_TUNNEL_H__
#define __NETWORKMANAGER_DEVICE_IP_TUNNEL_H__
-#include "nm-device-generic.h"
+#include "nm-device.h"
G_BEGIN_DECLS
diff --git a/src/nm-types.h b/src/nm-types.h
index e1acb08680..2ac1349351 100644
--- a/src/nm-types.h
+++ b/src/nm-types.h
@@ -105,8 +105,7 @@ typedef enum {
NM_LINK_TYPE_GRE,
NM_LINK_TYPE_SIT,
NM_LINK_TYPE_ISATAP,
- NM_LINK_TYPE_IP6IP6,
- NM_LINK_TYPE_IPIP6,
+ NM_LINK_TYPE_IP6TNL,
NM_LINK_TYPE_IP6GRE,
NM_LINK_TYPE_GRETAP,
NM_LINK_TYPE_IFB,
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index 14a6369f56..cbd2c75d67 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -677,7 +677,10 @@ static const LinkDesc linktypes[] = {
{ NM_LINK_TYPE_WIMAX, "wimax", "wimax", "wimax" },
{ NM_LINK_TYPE_DUMMY, "dummy", "dummy", NULL },
+ { NM_LINK_TYPE_IPIP, "ipip", "ipip", NULL },
{ NM_LINK_TYPE_GRE, "gre", "gre", NULL },
+ { NM_LINK_TYPE_SIT, "sit", "sit", NULL },
+ { NM_LINK_TYPE_IP6TNL, "ip6tnl", "ip6tnl", NULL },
{ NM_LINK_TYPE_GRETAP, "gretap", "gretap", NULL },
{ NM_LINK_TYPE_IFB, "ifb", "ifb", NULL },
{ NM_LINK_TYPE_LOOPBACK, "loopback", NULL, NULL },
@@ -3248,7 +3251,7 @@ ip4_tunnel_add (NMPlatform *platform,
static int
ip6_tunnel_add (NMPlatform *platform,
- NMLinkType type,
+ int proto,
const char *name,
struct in6_addr *local,
struct in6_addr *remote,
@@ -3257,20 +3260,16 @@ ip6_tunnel_add (NMPlatform *platform,
{
auto_nl_object struct rtnl_link *rtnllink;
- _LOGD ("link: add ip6 tunnel '%s' type %d", name, (int) type);
-
- if (type == NM_LINK_TYPE_IP6GRE) {
- _LOGW ("link: IP6GRE creation not supported");
- return FALSE;
- }
+ _LOGD ("link: add ip6 tunnel '%s' proto %d", name, proto);
- rtnllink = (struct rtnl_link *) build_rtnl_link (0, name, type);
+ rtnllink = _nl_rtnl_link_alloc (0, name);
+ rtnl_link_set_type (rtnllink, "ip6tnl");
rtnl_link_ip6_tnl_set_local (rtnllink, local);
rtnl_link_ip6_tnl_set_remote (rtnllink, remote);
rtnl_link_ip6_tnl_set_ttl (rtnllink, ttl);
- rtnl_link_ip6_tnl_set_proto (rtnllink, type == NM_LINK_TYPE_IPIP6 ? IPPROTO_IPIP : IPPROTO_IPV6);
+ rtnl_link_ip6_tnl_set_proto (rtnllink, proto);
- return do_add_link_with_lookup (platform, name, rtnllink, type, out_link);
+ return do_add_link_with_lookup (platform, name, rtnllink, NM_LINK_TYPE_IP6TNL, out_link);
}
static gboolean
@@ -3855,6 +3854,10 @@ static const struct nla_policy ip4_tunnel_info_policy[IFLA_IPTUN_MAX + 1] = {
[IFLA_IPTUN_TTL] = { .type = NLA_U8 },
[IFLA_IPTUN_TOS] = { .type = NLA_U8 },
[IFLA_IPTUN_PMTUDISC] = { .type = NLA_U8 },
+ [IFLA_IPTUN_ENCAP_TYPE] = { .type = NLA_U16 },
+ [IFLA_IPTUN_ENCAP_FLAGS] = { .type = NLA_U16 },
+ [IFLA_IPTUN_ENCAP_SPORT] = { .type = NLA_U16 },
+ [IFLA_IPTUN_ENCAP_DPORT] = { .type = NLA_U16 },
};
static int
@@ -3865,7 +3868,7 @@ ip4_tunnel_info_data_parser (struct nlattr *info_data, gpointer parser_data)
int err;
err = nla_parse_nested (tb, IFLA_IPTUN_MAX, info_data,
- (struct nla_policy *) gre_info_policy);
+ (struct nla_policy *) ip4_tunnel_info_policy);
if (err < 0)
return err;
@@ -3885,8 +3888,11 @@ static const struct nla_policy ip6_tunnel_info_policy[IFLA_IPTUN_MAX + 1] = {
[IFLA_IPTUN_LOCAL] = { .type = NLA_U32 },
[IFLA_IPTUN_REMOTE] = { .type = NLA_U32 },
[IFLA_IPTUN_TTL] = { .type = NLA_U8 },
- [IFLA_IPTUN_TOS] = { .type = NLA_U8 },
- [IFLA_IPTUN_PMTUDISC] = { .type = NLA_U8 },
+
+ [IFLA_IPTUN_ENCAP_LIMIT] = { .type = NLA_U8 },
+ [IFLA_IPTUN_FLOWINFO] = { .type = NLA_U32 },
+ [IFLA_IPTUN_FLAGS] = { .type = NLA_U32 },
+ [IFLA_IPTUN_PROTO] = { .type = NLA_U8 },
};
static int
@@ -3905,9 +3911,7 @@ ip6_tunnel_info_data_parser (struct nlattr *info_data, gpointer parser_data)
nla_memcpy(&props->local6, tb[IFLA_IPTUN_LOCAL], sizeof(struct in6_addr));
nla_memcpy(&props->remote6, tb[IFLA_IPTUN_REMOTE], sizeof(struct in6_addr));
props->encap = AF_INET6;
- props->tos = nla_get_u8 (tb[IFLA_IPTUN_TOS]);
props->ttl = nla_get_u8 (tb[IFLA_IPTUN_TTL]);
- props->path_mtu_discovery = !!nla_get_u8 (tb[IFLA_IPTUN_PMTUDISC]);
return 0;
}
@@ -3926,8 +3930,7 @@ ip_tunnel_get_properties (NMPlatform *platform, NMLinkType type, int ifindex, NM
case NM_LINK_TYPE_IPIP:
err = _nl_link_parse_info_data (priv->nlh, ifindex, ip4_tunnel_info_data_parser, props);
break;
- case NM_LINK_TYPE_IPIP6:
- case NM_LINK_TYPE_IP6IP6:
+ case NM_LINK_TYPE_IP6TNL:
err = _nl_link_parse_info_data (priv->nlh, ifindex, ip6_tunnel_info_data_parser, props);
break;
default:
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
index d7f8236eed..637b95aba1 100644
--- a/src/platform/nm-platform.c
+++ b/src/platform/nm-platform.c
@@ -1610,7 +1610,7 @@ nm_platform_ip4_tunnel_add (NMPlatform *self,
*/
NMPlatformError
nm_platform_ip6_tunnel_add (NMPlatform *self,
- NMLinkType type,
+ int proto,
const char *name,
struct in6_addr *local,
struct in6_addr *remote,
@@ -1625,12 +1625,12 @@ nm_platform_ip6_tunnel_add (NMPlatform *self,
g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG);
g_return_val_if_fail (klass->ip6_tunnel_add, NM_PLATFORM_ERROR_BUG);
- plerr = _link_add_check_existing (self, name, type, out_link);
+ plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_IP6TNL, out_link);
if (plerr != NM_PLATFORM_ERROR_SUCCESS)
return plerr;
- _LOGD ("link: adding ip6 tunnel '%s' type %d", name, type);
- if (!klass->ip6_tunnel_add (self, type, name, local, remote, ttl, out_link))
+ _LOGD ("link: adding ip6 tunnel '%s' proto %d", name, proto);
+ if (!klass->ip6_tunnel_add (self, proto, name, local, remote, ttl, out_link))
return NM_PLATFORM_ERROR_UNSPECIFIED;
return NM_PLATFORM_ERROR_SUCCESS;
}
diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h
index c7b2ca5b15..19242ca4cb 100644
--- a/src/platform/nm-platform.h
+++ b/src/platform/nm-platform.h
@@ -491,7 +491,7 @@ typedef struct {
gboolean (*ip4_tunnel_add) (NMPlatform *, NMLinkType type, const char *name, in_addr_t local, in_addr_t remote, guint8 ttl,
NMPlatformLink *out_link);
- gboolean (*ip6_tunnel_add) (NMPlatform *, NMLinkType type, const char *name, struct in6_addr *local, struct in6_addr *remote, guint8 ttl,
+ gboolean (*ip6_tunnel_add) (NMPlatform *, int proto, const char *name, struct in6_addr *local, struct in6_addr *remote, guint8 ttl,
NMPlatformLink *out_link);
gboolean (*infiniband_partition_add) (NMPlatform *, int parent, int p_key, NMPlatformLink *out_link);
@@ -710,7 +710,7 @@ gboolean nm_platform_mesh_set_ssid (NMPlatform *self, int ifindex, co
NMPlatformError nm_platform_ip4_tunnel_add (NMPlatform *self, NMLinkType type, const char *name, in_addr_t local, in_addr_t remote,
guint8 ttl, NMPlatformLink *out_link);
-NMPlatformError nm_platform_ip6_tunnel_add (NMPlatform *self, NMLinkType type, const char *name,
+NMPlatformError nm_platform_ip6_tunnel_add (NMPlatform *self, int proto, const char *name,
struct in6_addr *local, struct in6_addr *remote,
guint8 ttl, NMPlatformLink *out_link);