platform: add IPIP links support

This commit is contained in:
Beniamino Galvani
2015-11-27 14:01:56 +01:00
parent 0754280b9f
commit 30e648f981
6 changed files with 218 additions and 0 deletions

View File

@@ -108,6 +108,7 @@ typedef enum {
NM_LINK_TYPE_GRE,
NM_LINK_TYPE_GRETAP,
NM_LINK_TYPE_IFB,
NM_LINK_TYPE_IPIP,
NM_LINK_TYPE_LOOPBACK,
NM_LINK_TYPE_MACVLAN,
NM_LINK_TYPE_MACVTAP,
@@ -136,6 +137,7 @@ typedef enum {
NMP_OBJECT_TYPE_LNK_GRE,
NMP_OBJECT_TYPE_LNK_INFINIBAND,
NMP_OBJECT_TYPE_LNK_IPIP,
NMP_OBJECT_TYPE_LNK_MACVLAN,
NMP_OBJECT_TYPE_LNK_SIT,
NMP_OBJECT_TYPE_LNK_VLAN,

View File

@@ -329,6 +329,7 @@ static const LinkDesc linktypes[] = {
{ NM_LINK_TYPE_GRE, "gre", "gre", NULL },
{ NM_LINK_TYPE_GRETAP, "gretap", "gretap", NULL },
{ NM_LINK_TYPE_IFB, "ifb", "ifb", NULL },
{ NM_LINK_TYPE_IPIP, "ipip", "ipip", NULL },
{ NM_LINK_TYPE_LOOPBACK, "loopback", NULL, NULL },
{ NM_LINK_TYPE_MACVLAN, "macvlan", "macvlan", NULL },
{ NM_LINK_TYPE_MACVTAP, "macvtap", "macvtap", NULL },
@@ -914,6 +915,44 @@ _parse_lnk_infiniband (const char *kind, struct nlattr *info_data)
/*****************************************************************************/
static NMPObject *
_parse_lnk_ipip (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 },
};
struct nlattr *tb[IFLA_IPTUN_MAX + 1];
int err;
NMPObject *obj;
NMPlatformLnkIpIp *props;
if (!info_data || g_strcmp0 (kind, "ipip"))
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_IPIP, NULL);
props = &obj->lnk_ipip;
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]);
return obj;
}
/*****************************************************************************/
static NMPObject *
_parse_lnk_macvlan (const char *kind, struct nlattr *info_data)
{
@@ -1385,6 +1424,9 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
case NM_LINK_TYPE_INFINIBAND:
lnk_data = _parse_lnk_infiniband (nl_info_kind, nl_info_data);
break;
case NM_LINK_TYPE_IPIP:
lnk_data = _parse_lnk_ipip (nl_info_kind, nl_info_data);
break;
case NM_LINK_TYPE_MACVLAN:
lnk_data = _parse_lnk_macvlan (nl_info_kind, nl_info_data);
break;
@@ -4153,6 +4195,57 @@ nla_put_failure:
g_return_val_if_reached (FALSE);
}
static int
link_ipip_add (NMPlatform *platform,
const char *name,
NMPlatformLnkIpIp *props,
NMPlatformLink *out_link)
{
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
struct nlattr *info;
struct nlattr *data;
char buffer[INET_ADDRSTRLEN];
_LOGD (LOG_FMT_IP_TUNNEL,
"ipip",
name,
props->parent_ifindex,
nm_utils_inet4_ntop (props->local, NULL),
nm_utils_inet4_ntop (props->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, "ipip");
if (!(data = nla_nest_start (nlmsg, IFLA_INFO_DATA)))
goto nla_put_failure;
if (props->parent_ifindex)
NLA_PUT_U32 (nlmsg, IFLA_IPTUN_LINK, props->parent_ifindex);
NLA_PUT_U32 (nlmsg, IFLA_IPTUN_LOCAL, props->local);
NLA_PUT_U32 (nlmsg, IFLA_IPTUN_REMOTE, props->remote);
NLA_PUT_U8 (nlmsg, IFLA_IPTUN_TTL, props->ttl);
NLA_PUT_U8 (nlmsg, IFLA_IPTUN_TOS, props->tos);
NLA_PUT_U8 (nlmsg, IFLA_IPTUN_PMTUDISC, !!props->path_mtu_discovery);
nla_nest_end (nlmsg, data);
nla_nest_end (nlmsg, info);
return do_add_link_with_lookup (platform, NM_LINK_TYPE_IPIP, name, nlmsg, out_link);
nla_put_failure:
g_return_val_if_reached (FALSE);
}
static int
link_sit_add (NMPlatform *platform,
const char *name,
@@ -5658,6 +5751,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
platform_class->mesh_set_ssid = mesh_set_ssid;
platform_class->link_gre_add = link_gre_add;
platform_class->link_ipip_add = link_ipip_add;
platform_class->link_sit_add = link_sit_add;
platform_class->ip4_address_get = ip4_address_get;

View File

@@ -1429,6 +1429,12 @@ nm_platform_link_get_lnk_infiniband (NMPlatform *self, int ifindex, const NMPlat
return _link_get_lnk (self, ifindex, NM_LINK_TYPE_INFINIBAND, out_link);
}
const NMPlatformLnkIpIp *
nm_platform_link_get_lnk_ipip (NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
{
return _link_get_lnk (self, ifindex, NM_LINK_TYPE_IPIP, out_link);
}
const NMPlatformLnkMacvlan *
nm_platform_link_get_lnk_macvlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
{
@@ -1853,6 +1859,45 @@ nm_platform_infiniband_get_properties (NMPlatform *self,
return TRUE;
}
/**
* nm_platform_ipip_add:
* @self: platform instance
* @name: name of the new interface
* @props: interface properties
* @out_link: on success, the link object
*
* Create an IPIP tunnel.
*/
NMPlatformError
nm_platform_link_ipip_add (NMPlatform *self,
const char *name,
NMPlatformLnkIpIp *props,
NMPlatformLink *out_link)
{
NMPlatformError plerr;
char buffer[INET_ADDRSTRLEN];
_CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG);
g_return_val_if_fail (props, NM_PLATFORM_ERROR_BUG);
g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG);
plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_IPIP, out_link);
if (plerr != NM_PLATFORM_ERROR_SUCCESS)
return plerr;
_LOGD (LOG_FMT_IP_TUNNEL,
"ipip",
name,
props->parent_ifindex,
nm_utils_inet4_ntop (props->local, NULL),
nm_utils_inet4_ntop (props->remote, buffer));
if (!klass->link_ipip_add (self, name, props, out_link))
return NM_PLATFORM_ERROR_UNSPECIFIED;
return NM_PLATFORM_ERROR_SUCCESS;
}
/**
* nm_platform_sit_add:
* @self: platform instance
@@ -2891,6 +2936,38 @@ nm_platform_lnk_infiniband_to_string (const NMPlatformLnkInfiniband *lnk, char *
return buf;
}
const char *
nm_platform_lnk_ipip_to_string (const NMPlatformLnkIpIp *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_parent_ifindex[30];
if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len))
return buf;
g_snprintf (buf, len,
"ipip"
"%s" /* remote */
"%s" /* local */
"%s" /* parent_ifindex */
"%s" /* ttl */
"%s" /* tos */
"%s" /* path_mtu_discovery */
"",
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");
return buf;
}
const char *
nm_platform_lnk_macvlan_to_string (const NMPlatformLnkMacvlan *lnk, char *buf, gsize len)
{
@@ -3484,6 +3561,19 @@ nm_platform_lnk_infiniband_cmp (const NMPlatformLnkInfiniband *a, const NMPlatfo
return 0;
}
int
nm_platform_lnk_ipip_cmp (const NMPlatformLnkIpIp *a, const NMPlatformLnkIpIp *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);
return 0;
}
int
nm_platform_lnk_macvlan_cmp (const NMPlatformLnkMacvlan *a, const NMPlatformLnkMacvlan *b)
{

View File

@@ -378,6 +378,15 @@ typedef struct {
const char *mode;
} NMPlatformLnkInfiniband;
typedef struct {
int parent_ifindex;
in_addr_t local;
in_addr_t remote;
guint8 ttl;
guint8 tos;
gboolean path_mtu_discovery;
} NMPlatformLnkIpIp;
typedef struct {
const char *mode;
gboolean no_promisc;
@@ -540,6 +549,8 @@ typedef struct {
gboolean (*link_gre_add) (NMPlatform *, const char *name, NMPlatformLnkGre *props,
NMPlatformLink *out_link);
gboolean (*link_ipip_add) (NMPlatform *, const char *name, NMPlatformLnkIpIp *props,
NMPlatformLink *out_link);
gboolean (*link_sit_add) (NMPlatform *, const char *name, NMPlatformLnkSit *props,
NMPlatformLink *out_link);
@@ -732,6 +743,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 NMPlatformLnkInfiniband *nm_platform_link_get_lnk_infiniband (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
const NMPlatformLnkIpIp *nm_platform_link_get_lnk_ipip (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 NMPlatformLnkSit *nm_platform_link_get_lnk_sit (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
const NMPlatformLnkVlan *nm_platform_link_get_lnk_vlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
@@ -785,6 +797,8 @@ const NMPlatformIP4Address *nm_platform_ip4_address_get (NMPlatform *self, int i
NMPlatformError nm_platform_link_gre_add (NMPlatform *self, const char *name, NMPlatformLnkGre *props,
NMPlatformLink *out_link);
NMPlatformError nm_platform_link_ipip_add (NMPlatform *self, const char *name, NMPlatformLnkIpIp *props,
NMPlatformLink *out_link);
NMPlatformError nm_platform_link_sit_add (NMPlatform *self, const char *name, NMPlatformLnkSit *props,
NMPlatformLink *out_link);
@@ -829,6 +843,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_infiniband_to_string (const NMPlatformLnkInfiniband *lnk, char *buf, gsize len);
const char *nm_platform_lnk_ipip_to_string (const NMPlatformLnkIpIp *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_sit_to_string (const NMPlatformLnkSit *lnk, char *buf, gsize len);
const char *nm_platform_lnk_vlan_to_string (const NMPlatformLnkVlan *lnk, char *buf, gsize len);
@@ -847,6 +862,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_infiniband_cmp (const NMPlatformLnkInfiniband *a, const NMPlatformLnkInfiniband *b);
int nm_platform_lnk_ipip_cmp (const NMPlatformLnkIpIp *a, const NMPlatformLnkIpIp *b);
int nm_platform_lnk_macvlan_cmp (const NMPlatformLnkMacvlan *a, const NMPlatformLnkMacvlan *b);
int nm_platform_lnk_sit_cmp (const NMPlatformLnkSit *a, const NMPlatformLnkSit *b);
int nm_platform_lnk_vlan_cmp (const NMPlatformLnkVlan *a, const NMPlatformLnkVlan *b);

View File

@@ -2045,6 +2045,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_infiniband_to_string,
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_infiniband_cmp,
},
[NMP_OBJECT_TYPE_LNK_IPIP - 1] = {
.obj_type = NMP_OBJECT_TYPE_LNK_IPIP,
.sizeof_data = sizeof (NMPObjectLnkIpIp),
.sizeof_public = sizeof (NMPlatformLnkIpIp),
.obj_type_name = "ipip",
.lnk_link_type = NM_LINK_TYPE_IPIP,
.cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_ipip_to_string,
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_ipip_cmp,
},
[NMP_OBJECT_TYPE_LNK_MACVLAN - 1] = {
.obj_type = NMP_OBJECT_TYPE_LNK_MACVLAN,
.sizeof_data = sizeof (NMPObjectLnkMacvlan),

View File

@@ -169,6 +169,10 @@ typedef struct {
NMPlatformLnkInfiniband _public;
} NMPObjectLnkInfiniband;
typedef struct {
NMPlatformLnkIpIp _public;
} NMPObjectLnkIpIp;
typedef struct {
NMPlatformLnkMacvlan _public;
} NMPObjectLnkMacvlan;
@@ -222,6 +226,9 @@ struct _NMPObject {
NMPlatformLnkInfiniband lnk_infiniband;
NMPObjectLnkInfiniband _lnk_infiniband;
NMPlatformLnkIpIp lnk_ipip;
NMPObjectLnkIpIp _lnk_ipip;
NMPlatformLnkMacvlan lnk_macvlan;
NMPObjectLnkMacvlan _lnk_macvlan;