platform: add IP6TNL links support
This commit is contained in:
@@ -91,6 +91,8 @@
|
||||
#define IFLA_IPTUN_REMOTE 3
|
||||
#define IFLA_IPTUN_TTL 4
|
||||
#define IFLA_IPTUN_TOS 5
|
||||
#define IFLA_IPTUN_ENCAP_LIMIT 6
|
||||
#define IFLA_IPTUN_FLOWINFO 7
|
||||
#define IFLA_IPTUN_FLAGS 8
|
||||
#define IFLA_IPTUN_PROTO 9
|
||||
#define IFLA_IPTUN_PMTUDISC 10
|
||||
@@ -103,6 +105,10 @@
|
||||
#define MACVLAN_FLAG_NOPROMISC 1
|
||||
#endif
|
||||
|
||||
#define IP6_FLOWINFO_TCLASS_MASK 0x0FF00000
|
||||
#define IP6_FLOWINFO_TCLASS_SHIFT 20
|
||||
#define IP6_FLOWINFO_FLOWLABEL_MASK 0x000FFFFF
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
#define _NMLOG_PREFIX_NAME "platform-linux"
|
||||
@@ -329,6 +335,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_IP6TNL, "ip6tnl", "ip6tnl", NULL },
|
||||
{ NM_LINK_TYPE_IPIP, "ipip", "ipip", NULL },
|
||||
{ NM_LINK_TYPE_LOOPBACK, "loopback", NULL, NULL },
|
||||
{ NM_LINK_TYPE_MACVLAN, "macvlan", "macvlan", NULL },
|
||||
@@ -630,6 +637,8 @@ _linktype_get_type (NMPlatform *platform,
|
||||
return NM_LINK_TYPE_INFINIBAND;
|
||||
else if (arptype == ARPHRD_SIT)
|
||||
return NM_LINK_TYPE_SIT;
|
||||
else if (arptype == ARPHRD_TUNNEL6)
|
||||
return NM_LINK_TYPE_IP6TNL;
|
||||
|
||||
if (ifname) {
|
||||
gs_free char *driver = NULL;
|
||||
@@ -915,6 +924,59 @@ _parse_lnk_infiniband (const char *kind, struct nlattr *info_data)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static NMPObject *
|
||||
_parse_lnk_ip6tnl (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_UNSPEC,
|
||||
.minlen = sizeof (struct in6_addr)},
|
||||
[IFLA_IPTUN_REMOTE] = { .type = NLA_UNSPEC,
|
||||
.minlen = sizeof (struct in6_addr)},
|
||||
[IFLA_IPTUN_TTL] = { .type = NLA_U8 },
|
||||
[IFLA_IPTUN_ENCAP_LIMIT] = { .type = NLA_U8 },
|
||||
[IFLA_IPTUN_FLOWINFO] = { .type = NLA_U32 },
|
||||
[IFLA_IPTUN_PROTO] = { .type = NLA_U8 },
|
||||
};
|
||||
struct nlattr *tb[IFLA_IPTUN_MAX + 1];
|
||||
int err;
|
||||
NMPObject *obj;
|
||||
NMPlatformLnkIp6Tnl *props;
|
||||
guint32 flowinfo;
|
||||
|
||||
if (!info_data || g_strcmp0 (kind, "ip6tnl"))
|
||||
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_IP6TNL, NULL);
|
||||
props = &obj->lnk_ip6tnl;
|
||||
|
||||
if (tb[IFLA_IPTUN_LINK])
|
||||
props->parent_ifindex = nla_get_u32 (tb[IFLA_IPTUN_LINK]);
|
||||
if (tb[IFLA_IPTUN_LOCAL])
|
||||
memcpy (&props->local, nla_data (tb[IFLA_IPTUN_LOCAL]), sizeof (props->local));
|
||||
if (tb[IFLA_IPTUN_REMOTE])
|
||||
memcpy (&props->remote, nla_data (tb[IFLA_IPTUN_REMOTE]), sizeof (props->remote));
|
||||
if (tb[IFLA_IPTUN_TTL])
|
||||
props->ttl = nla_get_u8 (tb[IFLA_IPTUN_TTL]);
|
||||
if (tb[IFLA_IPTUN_ENCAP_LIMIT])
|
||||
props->encap_limit = nla_get_u8 (tb[IFLA_IPTUN_ENCAP_LIMIT]);
|
||||
if (tb[IFLA_IPTUN_FLOWINFO]) {
|
||||
flowinfo = ntohl (nla_get_u32 (tb[IFLA_IPTUN_FLOWINFO]));
|
||||
props->flow_label = flowinfo & IP6_FLOWINFO_FLOWLABEL_MASK;
|
||||
props->tclass = (flowinfo & IP6_FLOWINFO_TCLASS_MASK) >> IP6_FLOWINFO_TCLASS_SHIFT;
|
||||
}
|
||||
if (tb[IFLA_IPTUN_PROTO])
|
||||
props->proto = nla_get_u8 (tb[IFLA_IPTUN_PROTO]);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static NMPObject *
|
||||
_parse_lnk_ipip (const char *kind, struct nlattr *info_data)
|
||||
{
|
||||
@@ -1424,6 +1486,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_IP6TNL:
|
||||
lnk_data = _parse_lnk_ip6tnl (nl_info_kind, nl_info_data);
|
||||
break;
|
||||
case NM_LINK_TYPE_IPIP:
|
||||
lnk_data = _parse_lnk_ipip (nl_info_kind, nl_info_data);
|
||||
break;
|
||||
@@ -2839,6 +2904,7 @@ cache_pre_hook (NMPCache *cache, const NMPObject *old, const NMPObject *new, NMP
|
||||
* For example https://bugzilla.redhat.com/show_bug.cgi?id=1284001 */
|
||||
switch (new->link.type) {
|
||||
case NM_LINK_TYPE_GRE:
|
||||
case NM_LINK_TYPE_IP6TNL:
|
||||
case NM_LINK_TYPE_INFINIBAND:
|
||||
case NM_LINK_TYPE_MACVLAN:
|
||||
case NM_LINK_TYPE_SIT:
|
||||
@@ -4195,6 +4261,67 @@ nla_put_failure:
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
static int
|
||||
link_ip6tnl_add (NMPlatform *platform,
|
||||
const char *name,
|
||||
NMPlatformLnkIp6Tnl *props,
|
||||
NMPlatformLink *out_link)
|
||||
{
|
||||
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
|
||||
struct nlattr *info;
|
||||
struct nlattr *data;
|
||||
char buffer[INET_ADDRSTRLEN];
|
||||
guint32 flowinfo;
|
||||
|
||||
_LOGD (LOG_FMT_IP_TUNNEL,
|
||||
"ip6tnl",
|
||||
name,
|
||||
props->parent_ifindex,
|
||||
nm_utils_inet6_ntop (&props->local, NULL),
|
||||
nm_utils_inet6_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, "ip6tnl");
|
||||
|
||||
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);
|
||||
|
||||
if (memcmp (&props->local, &in6addr_any, sizeof (in6addr_any)))
|
||||
NLA_PUT (nlmsg, IFLA_IPTUN_LOCAL, sizeof (props->local), &props->local);
|
||||
if (memcmp (&props->remote, &in6addr_any, sizeof (in6addr_any)))
|
||||
NLA_PUT (nlmsg, IFLA_IPTUN_REMOTE, sizeof (props->remote), &props->remote);
|
||||
|
||||
NLA_PUT_U8 (nlmsg, IFLA_IPTUN_TTL, props->ttl);
|
||||
NLA_PUT_U8 (nlmsg, IFLA_IPTUN_ENCAP_LIMIT, props->encap_limit);
|
||||
|
||||
flowinfo = props->flow_label & IP6_FLOWINFO_FLOWLABEL_MASK;
|
||||
flowinfo |= (props->tclass << IP6_FLOWINFO_TCLASS_SHIFT)
|
||||
& IP6_FLOWINFO_TCLASS_MASK;
|
||||
NLA_PUT_U32 (nlmsg, IFLA_IPTUN_FLOWINFO, htonl (flowinfo));
|
||||
NLA_PUT_U8 (nlmsg, IFLA_IPTUN_PROTO, props->proto);
|
||||
|
||||
nla_nest_end (nlmsg, data);
|
||||
nla_nest_end (nlmsg, info);
|
||||
|
||||
return do_add_link_with_lookup (platform, NM_LINK_TYPE_IP6TNL, name, nlmsg, out_link);
|
||||
nla_put_failure:
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
static int
|
||||
link_ipip_add (NMPlatform *platform,
|
||||
const char *name,
|
||||
@@ -5751,6 +5878,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_ip6tnl_add = link_ip6tnl_add;
|
||||
platform_class->link_ipip_add = link_ipip_add;
|
||||
platform_class->link_sit_add = link_sit_add;
|
||||
|
||||
|
Reference in New Issue
Block a user