summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2015-11-11 18:41:48 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2015-11-12 17:31:08 +0100
commitf81209812fe522595349d12ad495bfa881f93156 (patch)
treea2927b22a84bf659d8adcc15bb0c0cdbb0ffda36
parent2ebee315e3982a5cc6fce43363801493a157d570 (diff)
downloadNetworkManager-f81209812fe522595349d12ad495bfa881f93156.tar.gz
platform: add basic SIT support
-rw-r--r--src/nm-types.h2
-rw-r--r--src/platform/nm-linux-platform.c107
-rw-r--r--src/platform/nm-platform.c97
-rw-r--r--src/platform/nm-platform.h18
-rw-r--r--src/platform/nmp-object.c9
-rw-r--r--src/platform/nmp-object.h7
6 files changed, 240 insertions, 0 deletions
diff --git a/src/nm-types.h b/src/nm-types.h
index 6dbd3b3b45..63efd6438b 100644
--- a/src/nm-types.h
+++ b/src/nm-types.h
@@ -108,6 +108,7 @@ typedef enum {
NM_LINK_TYPE_GRE,
NM_LINK_TYPE_GRETAP,
NM_LINK_TYPE_IFB,
+ NM_LINK_TYPE_SIT,
NM_LINK_TYPE_LOOPBACK,
NM_LINK_TYPE_MACVLAN,
NM_LINK_TYPE_MACVTAP,
@@ -134,6 +135,7 @@ typedef enum {
NMP_OBJECT_TYPE_IP6_ROUTE,
NMP_OBJECT_TYPE_LNK_GRE,
+ NMP_OBJECT_TYPE_LNK_SIT,
NMP_OBJECT_TYPE_LNK_INFINIBAND,
NMP_OBJECT_TYPE_LNK_MACVLAN,
NMP_OBJECT_TYPE_LNK_VLAN,
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index f03ab575b2..7452800a80 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -85,6 +85,19 @@
#define IFLA_MACVLAN_FLAGS 2
#define __IFLA_MACVLAN_MAX 3
+#define IFLA_IPTUN_LINK 1
+#define IFLA_IPTUN_LOCAL 2
+#define IFLA_IPTUN_REMOTE 3
+#define IFLA_IPTUN_TTL 4
+#define IFLA_IPTUN_TOS 5
+#define IFLA_IPTUN_FLAGS 8
+#define IFLA_IPTUN_PROTO 9
+#define IFLA_IPTUN_PMTUDISC 10
+#define __IFLA_IPTUN_MAX 19
+#ifndef IFLA_IPTUN_MAX
+#define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1)
+#endif
+
#ifndef MACVLAN_FLAG_NOPROMISC
#define MACVLAN_FLAG_NOPROMISC 1
#endif
@@ -313,6 +326,7 @@ static const LinkDesc linktypes[] = {
{ NM_LINK_TYPE_DUMMY, "dummy", "dummy", NULL },
{ NM_LINK_TYPE_GRE, "gre", "gre", NULL },
{ NM_LINK_TYPE_GRETAP, "gretap", "gretap", NULL },
+ { NM_LINK_TYPE_SIT, "sit", "sit", NULL },
{ NM_LINK_TYPE_IFB, "ifb", "ifb", NULL },
{ NM_LINK_TYPE_LOOPBACK, "loopback", NULL, NULL },
{ NM_LINK_TYPE_MACVLAN, "macvlan", "macvlan", NULL },
@@ -836,6 +850,48 @@ _parse_lnk_gre (const char *kind, struct nlattr *info_data)
/*****************************************************************************/
+static NMPObject *
+_parse_lnk_sit (const char *kind, struct nlattr *info_data)
+{
+ static struct nla_policy policy[IFLA_IPTUN_MAX + 1] = {
+ [IFLA_IPTUN_LINK] = { .type = NLA_U32 },
+ [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_FLAGS] = { .type = NLA_U16 },
+ [IFLA_IPTUN_PROTO] = { .type = NLA_U8 },
+ };
+ struct nlattr *tb[IFLA_IPTUN_MAX + 1];
+ int err;
+ NMPObject *obj;
+ NMPlatformLnkSit *props;
+
+ if (!info_data || g_strcmp0 (kind, "sit"))
+ return NULL;
+
+ err = nla_parse_nested (tb, IFLA_IPTUN_MAX, info_data, policy);
+ if (err < 0)
+ return NULL;
+
+ obj = nmp_object_new (NMP_OBJECT_TYPE_LNK_SIT, NULL);
+ props = &obj->lnk_sit;
+
+ props->parent_ifindex = tb[IFLA_IPTUN_LINK] ? nla_get_u32 (tb[IFLA_IPTUN_LINK]) : 0;
+ props->local = tb[IFLA_IPTUN_LOCAL] ? nla_get_u32 (tb[IFLA_IPTUN_LOCAL]) : 0;
+ props->remote = tb[IFLA_IPTUN_REMOTE] ? nla_get_u32 (tb[IFLA_IPTUN_REMOTE]) : 0;
+ props->tos = tb[IFLA_IPTUN_TOS] ? nla_get_u8 (tb[IFLA_IPTUN_TOS]) : 0;
+ props->ttl = tb[IFLA_IPTUN_TTL] ? nla_get_u8 (tb[IFLA_IPTUN_TTL]) : 0;
+ props->path_mtu_discovery = !tb[IFLA_IPTUN_PMTUDISC] || !!nla_get_u8 (tb[IFLA_IPTUN_PMTUDISC]);
+ props->flags = tb[IFLA_IPTUN_FLAGS] ? nla_get_u16 (tb[IFLA_IPTUN_FLAGS]) : 0;
+ props->proto = tb[IFLA_IPTUN_PROTO] ? nla_get_u8 (tb[IFLA_IPTUN_PROTO]) : 0;
+
+ return obj;
+}
+
+/*****************************************************************************/
+
/* IFLA_IPOIB_* were introduced in the 3.7 kernel, but the kernel headers
* we're building against might not have those properties even though the
* running kernel might.
@@ -1322,6 +1378,9 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
case NM_LINK_TYPE_GRE:
lnk_data = _parse_lnk_gre (nl_info_kind, nl_info_data);
break;
+ case NM_LINK_TYPE_SIT:
+ lnk_data = _parse_lnk_sit (nl_info_kind, nl_info_data);
+ break;
case NM_LINK_TYPE_INFINIBAND:
lnk_data = _parse_lnk_infiniband (nl_info_kind, nl_info_data);
break;
@@ -4116,6 +4175,53 @@ nla_put_failure:
g_return_val_if_reached (FALSE);
}
+static int
+sit_add (NMPlatform *platform,
+ const char *name,
+ NMPlatformLnkSit *lnk_gre,
+ NMPlatformLink *out_link)
+{
+ nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
+ struct nlattr *info;
+ struct nlattr *data;
+ char buffer[INET_ADDRSTRLEN];
+
+ _LOGD ("link: add sit '%s', local %s, remote %s",
+ name,
+ nm_utils_inet4_ntop (lnk_gre->local, NULL),
+ nm_utils_inet4_ntop (lnk_gre->remote, buffer));
+
+ nlmsg = _nl_msg_new_link (RTM_NEWLINK,
+ NLM_F_CREATE,
+ 0,
+ name,
+ 0,
+ 0);
+ if (!nlmsg)
+ return FALSE;
+
+ if (!(info = nla_nest_start (nlmsg, IFLA_LINKINFO)))
+ goto nla_put_failure;
+
+ NLA_PUT_STRING (nlmsg, IFLA_INFO_KIND, "sit");
+
+ if (!(data = nla_nest_start (nlmsg, IFLA_INFO_DATA)))
+ goto nla_put_failure;
+
+ NLA_PUT_U32 (nlmsg, IFLA_IPTUN_LOCAL, lnk_gre->local);
+ NLA_PUT_U32 (nlmsg, IFLA_IPTUN_REMOTE, lnk_gre->remote);
+ NLA_PUT_U8 (nlmsg, IFLA_IPTUN_TTL, lnk_gre->ttl);
+ NLA_PUT_U8 (nlmsg, IFLA_IPTUN_TOS, lnk_gre->tos);
+ NLA_PUT_U8 (nlmsg, IFLA_IPTUN_PMTUDISC, !!lnk_gre->path_mtu_discovery);
+
+ nla_nest_end (nlmsg, data);
+ nla_nest_end (nlmsg, info);
+
+ return do_add_link_with_lookup (platform, NM_LINK_TYPE_SIT, name, nlmsg, out_link);
+nla_put_failure:
+ g_return_val_if_reached (FALSE);
+}
+
static void
_vlan_change_vlan_qos_mapping_create (gboolean is_ingress_map,
gboolean reset_all,
@@ -5513,6 +5619,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
platform_class->mesh_set_ssid = mesh_set_ssid;
platform_class->gre_add = gre_add;
+ platform_class->sit_add = sit_add;
platform_class->ip4_address_get = ip4_address_get;
platform_class->ip6_address_get = ip6_address_get;
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
index ceef133373..e12d33f42f 100644
--- a/src/platform/nm-platform.c
+++ b/src/platform/nm-platform.c
@@ -1419,6 +1419,12 @@ nm_platform_link_get_lnk_gre (NMPlatform *self, int ifindex, const NMPlatformLin
return _link_get_lnk (self, ifindex, NM_LINK_TYPE_GRE, out_link);
}
+const NMPlatformLnkSit *
+nm_platform_link_get_lnk_sit (NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
+{
+ return _link_get_lnk (self, ifindex, NM_LINK_TYPE_SIT, out_link);
+}
+
const NMPlatformLnkInfiniband *
nm_platform_link_get_lnk_infiniband (NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
{
@@ -1707,6 +1713,44 @@ nm_platform_gre_add (NMPlatform *self,
return NM_PLATFORM_ERROR_SUCCESS;
}
+/**
+ * nm_platform_sit_add:
+ * @self: platform instance
+ * @name: name of the new interface
+ * @lnk_sit: interface properties
+ * @out_link: on success, the link object
+ *
+ * Create a software SIT device.
+ */
+NMPlatformError
+nm_platform_sit_add (NMPlatform *self,
+ const char *name,
+ NMPlatformLnkSit *lnk_sit,
+ NMPlatformLink *out_link)
+{
+ NMPlatformError plerr;
+ char buffer[INET_ADDRSTRLEN];
+
+ _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG);
+
+ g_return_val_if_fail (lnk_sit, NM_PLATFORM_ERROR_BUG);
+ g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG);
+ g_return_val_if_fail (klass->sit_add, NM_PLATFORM_ERROR_BUG);
+
+ plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_SIT, out_link);
+ if (plerr != NM_PLATFORM_ERROR_SUCCESS)
+ return plerr;
+
+ _LOGD ("link: adding sit '%s' local %s remote %s",
+ name,
+ nm_utils_inet4_ntop (lnk_sit->local, NULL),
+ nm_utils_inet4_ntop (lnk_sit->remote, buffer));
+
+ if (!klass->sit_add (self, name, lnk_sit, out_link))
+ return NM_PLATFORM_ERROR_UNSPECIFIED;
+ return NM_PLATFORM_ERROR_SUCCESS;
+}
+
NMPlatformError
nm_platform_infiniband_partition_add (NMPlatform *self, int parent, int p_key, NMPlatformLink *out_link)
{
@@ -2788,6 +2832,44 @@ nm_platform_lnk_gre_to_string (const NMPlatformLnkGre *lnk, char *buf, gsize len
}
const char *
+nm_platform_lnk_sit_to_string (const NMPlatformLnkSit *lnk, char *buf, gsize len)
+{
+ char str_local[30];
+ char str_local1[NM_UTILS_INET_ADDRSTRLEN];
+ char str_remote[30];
+ char str_remote1[NM_UTILS_INET_ADDRSTRLEN];
+ char str_ttl[30];
+ char str_tos[30];
+ char str_flags[30];
+ char str_proto[30];
+ char str_parent_ifindex[30];
+
+ if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len))
+ return buf;
+
+ g_snprintf (buf, len,
+ "sit"
+ "%s" /* remote */
+ "%s" /* local */
+ "%s" /* parent_ifindex */
+ "%s" /* ttl */
+ "%s" /* tos */
+ "%s" /* path_mtu_discovery */
+ "%s" /* flags */
+ "%s" /* proto */
+ "",
+ lnk->remote ? nm_sprintf_buf (str_remote, " remote %s", nm_utils_inet4_ntop (lnk->remote, str_remote1)) : "",
+ lnk->local ? nm_sprintf_buf (str_local, " local %s", nm_utils_inet4_ntop (lnk->local, str_local1)) : "",
+ lnk->parent_ifindex ? nm_sprintf_buf (str_parent_ifindex, " dev %d", lnk->parent_ifindex) : "",
+ lnk->ttl ? nm_sprintf_buf (str_ttl, " ttl %u", lnk->ttl) : " ttl inherit",
+ lnk->tos ? (lnk->tos == 1 ? " tos inherit" : nm_sprintf_buf (str_tos, " tos 0x%x", lnk->tos)) : "",
+ lnk->path_mtu_discovery ? "" : " nopmtudisc",
+ lnk->flags ? nm_sprintf_buf (str_flags, " flags 0x%x", lnk->flags) : "",
+ lnk->proto ? nm_sprintf_buf (str_proto, " proto 0x%x", lnk->proto) : "");
+ return buf;
+}
+
+const char *
nm_platform_lnk_infiniband_to_string (const NMPlatformLnkInfiniband *lnk, char *buf, gsize len)
{
char str_p_key[64];
@@ -3353,6 +3435,21 @@ nm_platform_lnk_gre_cmp (const NMPlatformLnkGre *a, const NMPlatformLnkGre *b)
}
int
+nm_platform_lnk_sit_cmp (const NMPlatformLnkSit *a, const NMPlatformLnkSit *b)
+{
+ _CMP_SELF (a, b);
+ _CMP_FIELD (a, b, parent_ifindex);
+ _CMP_FIELD (a, b, local);
+ _CMP_FIELD (a, b, remote);
+ _CMP_FIELD (a, b, ttl);
+ _CMP_FIELD (a, b, tos);
+ _CMP_FIELD_BOOL (a, b, path_mtu_discovery);
+ _CMP_FIELD (a, b, flags);
+ _CMP_FIELD (a, b, proto);
+ return 0;
+}
+
+int
nm_platform_lnk_infiniband_cmp (const NMPlatformLnkInfiniband *a, const NMPlatformLnkInfiniband *b)
{
_CMP_SELF (a, b);
diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h
index 77fc10b328..8ab6435578 100644
--- a/src/platform/nm-platform.h
+++ b/src/platform/nm-platform.h
@@ -370,6 +370,17 @@ typedef struct {
} NMPlatformLnkGre;
typedef struct {
+ int parent_ifindex;
+ in_addr_t local;
+ in_addr_t remote;
+ guint8 ttl;
+ guint8 tos;
+ gboolean path_mtu_discovery;
+ guint16 flags;
+ guint8 proto;
+} NMPlatformLnkSit;
+
+typedef struct {
int p_key;
const char *mode;
} NMPlatformLnkInfiniband;
@@ -525,6 +536,8 @@ typedef struct {
gboolean (*gre_add) (NMPlatform *, const char *name, NMPlatformLnkGre *lnk_gre,
NMPlatformLink *out_link);
+ gboolean (*sit_add) (NMPlatform *, const char *name, NMPlatformLnkSit *lnk_sit,
+ NMPlatformLink *out_link);
gboolean (*infiniband_partition_add) (NMPlatform *, int parent, int p_key, NMPlatformLink *out_link);
@@ -711,6 +724,7 @@ char *nm_platform_slave_get_option (NMPlatform *self, int ifindex, const char *o
const NMPObject *nm_platform_link_get_lnk (NMPlatform *self, int ifindex, NMLinkType link_type, const NMPlatformLink **out_link);
const NMPlatformLnkGre *nm_platform_link_get_lnk_gre (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
+const NMPlatformLnkSit *nm_platform_link_get_lnk_sit (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
const NMPlatformLnkInfiniband *nm_platform_link_get_lnk_infiniband (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
const NMPlatformLnkMacvlan *nm_platform_link_get_lnk_macvlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
const NMPlatformLnkVlan *nm_platform_link_get_lnk_vlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
@@ -761,6 +775,8 @@ const NMPlatformIP4Address *nm_platform_ip4_address_get (NMPlatform *self, int i
NMPlatformError nm_platform_gre_add (NMPlatform *self, const char *name, NMPlatformLnkGre *lnk_gre,
NMPlatformLink *out_link);
+NMPlatformError nm_platform_sit_add (NMPlatform *self, const char *name, NMPlatformLnkSit *lnk_sit,
+ NMPlatformLink *out_link);
const NMPlatformIP6Address *nm_platform_ip6_address_get (NMPlatform *self, int ifindex, struct in6_addr address, int plen);
GArray *nm_platform_ip4_address_get_all (NMPlatform *self, int ifindex);
@@ -802,6 +818,7 @@ gboolean nm_platform_ip6_route_delete (NMPlatform *self, int ifindex, struct in6
const char *nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len);
const char *nm_platform_lnk_gre_to_string (const NMPlatformLnkGre *lnk, char *buf, gsize len);
+const char *nm_platform_lnk_sit_to_string (const NMPlatformLnkSit *lnk, char *buf, gsize len);
const char *nm_platform_lnk_infiniband_to_string (const NMPlatformLnkInfiniband *lnk, char *buf, gsize len);
const char *nm_platform_lnk_macvlan_to_string (const NMPlatformLnkMacvlan *lnk, char *buf, gsize len);
const char *nm_platform_lnk_vlan_to_string (const NMPlatformLnkVlan *lnk, char *buf, gsize len);
@@ -819,6 +836,7 @@ const char *nm_platform_vlan_qos_mapping_to_string (const char *name,
int nm_platform_link_cmp (const NMPlatformLink *a, const NMPlatformLink *b);
int nm_platform_lnk_gre_cmp (const NMPlatformLnkGre *a, const NMPlatformLnkGre *b);
+int nm_platform_lnk_sit_cmp (const NMPlatformLnkSit *a, const NMPlatformLnkSit *b);
int nm_platform_lnk_infiniband_cmp (const NMPlatformLnkInfiniband *a, const NMPlatformLnkInfiniband *b);
int nm_platform_lnk_macvlan_cmp (const NMPlatformLnkMacvlan *a, const NMPlatformLnkMacvlan *b);
int nm_platform_lnk_vlan_cmp (const NMPlatformLnkVlan *a, const NMPlatformLnkVlan *b);
diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c
index 2264c9cd62..768eab1797 100644
--- a/src/platform/nmp-object.c
+++ b/src/platform/nmp-object.c
@@ -2031,6 +2031,15 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
.cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_gre_to_string,
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_gre_cmp,
},
+ [NMP_OBJECT_TYPE_LNK_SIT - 1] = {
+ .obj_type = NMP_OBJECT_TYPE_LNK_SIT,
+ .sizeof_data = sizeof (NMPObjectLnkSit),
+ .sizeof_public = sizeof (NMPlatformLnkSit),
+ .obj_type_name = "sit",
+ .lnk_link_type = NM_LINK_TYPE_SIT,
+ .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_sit_to_string,
+ .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_sit_cmp,
+ },
[NMP_OBJECT_TYPE_LNK_INFINIBAND - 1] = {
.obj_type = NMP_OBJECT_TYPE_LNK_INFINIBAND,
.sizeof_data = sizeof (NMPObjectLnkInfiniband),
diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h
index e49d358675..ca28887084 100644
--- a/src/platform/nmp-object.h
+++ b/src/platform/nmp-object.h
@@ -165,6 +165,10 @@ typedef struct {
} NMPObjectLnkGre;
typedef struct {
+ NMPlatformLnkSit _public;
+} NMPObjectLnkSit;
+
+typedef struct {
NMPlatformLnkInfiniband _public;
} NMPObjectLnkInfiniband;
@@ -214,6 +218,9 @@ struct _NMPObject {
NMPlatformLnkGre lnk_gre;
NMPObjectLnkGre _lnk_gre;
+ NMPlatformLnkSit lnk_sit;
+ NMPObjectLnkSit _lnk_sit;
+
NMPlatformLnkInfiniband lnk_infiniband;
NMPObjectLnkInfiniband _lnk_infiniband;