[PATCH 2/2] route/link: add ipv6 support to vxlan links
Beniamino Galvani
bgalvani at redhat.com
Fri Oct 16 02:21:26 PDT 2015
Extend vxlan links to support the IFLA_VXLAN_GROUP6 and
IFLA_VXLAN_LOCAL6 attributes used to represent IPv6 endpoints.
Signed-off-by: Beniamino Galvani <bgalvani at redhat.com>
---
lib/route/link/vxlan.c | 99 +++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 78 insertions(+), 21 deletions(-)
diff --git a/lib/route/link/vxlan.c b/lib/route/link/vxlan.c
index 8eb6db1..184373e 100644
--- a/lib/route/link/vxlan.c
+++ b/lib/route/link/vxlan.c
@@ -48,13 +48,17 @@
#define VXLAN_HAS_RSC (1<<11)
#define VXLAN_HAS_L2MISS (1<<12)
#define VXLAN_HAS_L3MISS (1<<13)
+#define VXLAN_HAS_GROUP6 (1<<14)
+#define VXLAN_HAS_LOCAL6 (1<<15)
struct vxlan_info
{
uint32_t vxi_id;
uint32_t vxi_group;
+ struct in6_addr vxi_group6;
uint32_t vxi_link;
uint32_t vxi_local;
+ struct in6_addr vxi_local6;
uint8_t vxi_ttl;
uint8_t vxi_tos;
uint8_t vxi_learning;
@@ -73,8 +77,10 @@ struct vxlan_info
static struct nla_policy vxlan_policy[IFLA_VXLAN_MAX+1] = {
[IFLA_VXLAN_ID] = { .type = NLA_U32 },
[IFLA_VXLAN_GROUP] = { .minlen = sizeof(uint32_t) },
+ [IFLA_VXLAN_GROUP6] = { .minlen = sizeof(struct in6_addr) },
[IFLA_VXLAN_LINK] = { .type = NLA_U32 },
[IFLA_VXLAN_LOCAL] = { .minlen = sizeof(uint32_t) },
+ [IFLA_VXLAN_LOCAL6] = { .minlen = sizeof(struct in6_addr) },
[IFLA_VXLAN_TTL] = { .type = NLA_U8 },
[IFLA_VXLAN_TOS] = { .type = NLA_U8 },
[IFLA_VXLAN_LEARNING] = { .type = NLA_U8 },
@@ -125,10 +131,17 @@ static int vxlan_parse(struct rtnl_link *link, struct nlattr *data,
vxi->vxi_mask |= VXLAN_HAS_ID;
}
+ if (tb[IFLA_VXLAN_GROUP6]) {
+ nla_memcpy(&vxi->vxi_group6, tb[IFLA_VXLAN_GROUP6],
+ sizeof(vxi->vxi_group6));
+ vxi->vxi_mask |= VXLAN_HAS_GROUP6;
+ }
+
if (tb[IFLA_VXLAN_GROUP]) {
nla_memcpy(&vxi->vxi_group, tb[IFLA_VXLAN_GROUP],
sizeof(vxi->vxi_group));
vxi->vxi_mask |= VXLAN_HAS_GROUP;
+ vxi->vxi_mask &= ~VXLAN_HAS_GROUP6;
}
if (tb[IFLA_VXLAN_LINK]) {
@@ -136,10 +149,17 @@ static int vxlan_parse(struct rtnl_link *link, struct nlattr *data,
vxi->vxi_mask |= VXLAN_HAS_LINK;
}
+ if (tb[IFLA_VXLAN_LOCAL6]) {
+ nla_memcpy(&vxi->vxi_local6, tb[IFLA_VXLAN_LOCAL6],
+ sizeof(vxi->vxi_local6));
+ vxi->vxi_mask |= VXLAN_HAS_LOCAL6;
+ }
+
if (tb[IFLA_VXLAN_LOCAL]) {
nla_memcpy(&vxi->vxi_local, tb[IFLA_VXLAN_LOCAL],
sizeof(vxi->vxi_local));
vxi->vxi_mask |= VXLAN_HAS_LOCAL;
+ vxi->vxi_mask &= ~VXLAN_HAS_LOCAL6;
}
if (tb[IFLA_VXLAN_TTL]) {
@@ -217,17 +237,23 @@ static void vxlan_dump_line(struct rtnl_link *link, struct nl_dump_params *p)
static void vxlan_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
{
struct vxlan_info *vxi = link->l_info;
- char *name, addr[INET_ADDRSTRLEN];
+ char *name, addr[INET6_ADDRSTRLEN];
struct rtnl_link *parent;
nl_dump_line(p, " vxlan-id %u\n", vxi->vxi_id);
if (vxi->vxi_mask & VXLAN_HAS_GROUP) {
nl_dump(p, " group ");
- if(inet_ntop(AF_INET, &vxi->vxi_group, addr, sizeof(addr)))
+ if (inet_ntop(AF_INET, &vxi->vxi_group, addr, sizeof(addr)))
nl_dump_line(p, "%s\n", addr);
else
nl_dump_line(p, "%#x\n", ntohs(vxi->vxi_group));
+ } else if (vxi->vxi_mask & VXLAN_HAS_GROUP6) {
+ nl_dump(p, " group ");
+ if (inet_ntop(AF_INET6, &vxi->vxi_group6, addr, sizeof(addr)))
+ nl_dump_line(p, "%s\n", addr);
+ else
+ nl_dump_line(p, "%#x\n", vxi->vxi_group6);
}
if (vxi->vxi_mask & VXLAN_HAS_LINK) {
@@ -246,12 +272,19 @@ static void vxlan_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
if (vxi->vxi_mask & VXLAN_HAS_LOCAL) {
nl_dump(p, " local ");
- if(inet_ntop(AF_INET, &vxi->vxi_local, addr, sizeof(addr)))
+ if (inet_ntop(AF_INET, &vxi->vxi_local, addr, sizeof(addr)))
nl_dump_line(p, "%s\n", addr);
else
nl_dump_line(p, "%#x\n", ntohs(vxi->vxi_local));
+ } else if (vxi->vxi_mask & VXLAN_HAS_LOCAL6) {
+ nl_dump(p, " local ");
+ if (inet_ntop(AF_INET6, &vxi->vxi_local6, addr, sizeof(addr)))
+ nl_dump_line(p, "%s\n", addr);
+ else
+ nl_dump_line(p, "%#x\n", vxi->vxi_local6);
}
+
if (vxi->vxi_mask & VXLAN_HAS_TTL) {
nl_dump(p, " ttl ");
if(vxi->vxi_ttl)
@@ -362,12 +395,18 @@ static int vxlan_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
if (vxi->vxi_mask & VXLAN_HAS_GROUP)
NLA_PUT(msg, IFLA_VXLAN_GROUP, sizeof(vxi->vxi_group), &vxi->vxi_group);
+ if (vxi->vxi_mask & VXLAN_HAS_GROUP6)
+ NLA_PUT(msg, IFLA_VXLAN_GROUP6, sizeof(vxi->vxi_group6), &vxi->vxi_group6);
+
if (vxi->vxi_mask & VXLAN_HAS_LINK)
NLA_PUT_U32(msg, IFLA_VXLAN_LINK, vxi->vxi_link);
if (vxi->vxi_mask & VXLAN_HAS_LOCAL)
NLA_PUT(msg, IFLA_VXLAN_LOCAL, sizeof(vxi->vxi_local), &vxi->vxi_local);
+ if (vxi->vxi_mask & VXLAN_HAS_LOCAL6)
+ NLA_PUT(msg, IFLA_VXLAN_LOCAL6, sizeof(vxi->vxi_local6), &vxi->vxi_local6);
+
if (vxi->vxi_mask & VXLAN_HAS_TTL)
NLA_PUT_U8(msg, IFLA_VXLAN_TTL, vxi->vxi_ttl);
@@ -523,14 +562,21 @@ int rtnl_link_vxlan_set_group(struct rtnl_link *link, struct nl_addr *addr)
IS_VXLAN_LINK_ASSERT(link);
- if ((nl_addr_get_family(addr) != AF_INET) ||
- (nl_addr_get_len(addr) != sizeof(vxi->vxi_group)))
+ if ((nl_addr_get_family(addr) == AF_INET) &&
+ (nl_addr_get_len(addr) == sizeof(vxi->vxi_group))) {
+ memcpy(&vxi->vxi_group, nl_addr_get_binary_addr(addr),
+ sizeof(vxi->vxi_group));
+ vxi->vxi_mask |= VXLAN_HAS_GROUP;
+ vxi->vxi_mask &= ~VXLAN_HAS_GROUP6;
+ } else if ((nl_addr_get_family(addr) == AF_INET6) &&
+ (nl_addr_get_len(addr) == sizeof(vxi->vxi_group6))) {
+ memcpy(&vxi->vxi_group6, nl_addr_get_binary_addr(addr),
+ sizeof(vxi->vxi_group6));
+ vxi->vxi_mask |= VXLAN_HAS_GROUP6;
+ vxi->vxi_mask &= ~VXLAN_HAS_GROUP;
+ } else
return -NLE_INVAL;
- memcpy(&vxi->vxi_group, nl_addr_get_binary_addr(addr),
- sizeof(vxi->vxi_group));
- vxi->vxi_mask |= VXLAN_HAS_GROUP;
-
return 0;
}
@@ -550,11 +596,13 @@ int rtnl_link_vxlan_get_group(struct rtnl_link *link, struct nl_addr **addr)
if (!addr)
return -NLE_INVAL;
- if (!(vxi->vxi_mask & VXLAN_HAS_GROUP))
+ if (vxi->vxi_mask & VXLAN_HAS_GROUP)
+ *addr = nl_addr_build(AF_INET, &vxi->vxi_group, sizeof(vxi->vxi_group));
+ else if (vxi->vxi_mask & VXLAN_HAS_GROUP6)
+ *addr = nl_addr_build(AF_INET6, &vxi->vxi_group6, sizeof(vxi->vxi_group6));
+ else
return -NLE_AGAIN;
- *addr = nl_addr_build(AF_INET, &vxi->vxi_group, sizeof(vxi->vxi_group));
-
return 0;
}
@@ -614,14 +662,21 @@ int rtnl_link_vxlan_set_local(struct rtnl_link *link, struct nl_addr *addr)
IS_VXLAN_LINK_ASSERT(link);
- if ((nl_addr_get_family(addr) != AF_INET) ||
- (nl_addr_get_len(addr) != sizeof(vxi->vxi_local)))
+ if ((nl_addr_get_family(addr) == AF_INET) &&
+ (nl_addr_get_len(addr) == sizeof(vxi->vxi_local))) {
+ memcpy(&vxi->vxi_local, nl_addr_get_binary_addr(addr),
+ sizeof(vxi->vxi_local));
+ vxi->vxi_mask |= VXLAN_HAS_LOCAL;
+ vxi->vxi_mask &= VXLAN_HAS_LOCAL6;
+ } else if ((nl_addr_get_family(addr) == AF_INET6) &&
+ (nl_addr_get_len(addr) == sizeof(vxi->vxi_local6))) {
+ memcpy(&vxi->vxi_local6, nl_addr_get_binary_addr(addr),
+ sizeof(vxi->vxi_local6));
+ vxi->vxi_mask |= VXLAN_HAS_LOCAL6;
+ vxi->vxi_mask &= ~VXLAN_HAS_LOCAL;
+ } else
return -NLE_INVAL;
- memcpy(&vxi->vxi_local, nl_addr_get_binary_addr(addr),
- sizeof(vxi->vxi_local));
- vxi->vxi_mask |= VXLAN_HAS_LOCAL;
-
return 0;
}
@@ -641,11 +696,13 @@ int rtnl_link_vxlan_get_local(struct rtnl_link *link, struct nl_addr **addr)
if (!addr)
return -NLE_INVAL;
- if (!(vxi->vxi_mask & VXLAN_HAS_LOCAL))
+ if (vxi->vxi_mask & VXLAN_HAS_LOCAL)
+ *addr = nl_addr_build(AF_INET, &vxi->vxi_local, sizeof(vxi->vxi_local));
+ else if (vxi->vxi_mask & VXLAN_HAS_LOCAL6)
+ *addr = nl_addr_build(AF_INET6, &vxi->vxi_local6, sizeof(vxi->vxi_local6));
+ else
return -NLE_AGAIN;
- *addr = nl_addr_build(AF_INET, &vxi->vxi_local, sizeof(vxi->vxi_local));
-
return 0;
}
--
2.4.3
More information about the libnl
mailing list