summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-11-19 16:40:32 (GMT)
committerThomas Haller <thaller@redhat.com>2015-11-19 16:41:31 (GMT)
commitc96455b869442552c06d820c8d4cda6e8234873b (patch)
treeb9d5040e8e7487a92bfdeaba7dc2fafdc16676e7
parent3f231213c7c586b5a5e8ce6b1ea9c1d3b24d74c0 (diff)
parent2e68fb5b02304fa6a3e6429c4fdabb084e61b501 (diff)
downloadlibnl-c96455b869442552c06d820c8d4cda6e8234873b.zip
libnl-c96455b869442552c06d820c8d4cda6e8234873b.tar.gz
libnl-c96455b869442552c06d820c8d4cda6e8234873b.tar.bz2
route/link: merge branch 'bg/vxlan-ipv6'
http://lists.infradead.org/pipermail/libnl/2015-October/001981.html Signed-off-by: Thomas Haller <thaller@redhat.com>
-rw-r--r--include/netlink-private/netlink.h1
-rw-r--r--lib/route/link.c11
-rw-r--r--lib/route/link/ip6tnl.c8
-rw-r--r--lib/route/link/ipgre.c8
-rw-r--r--lib/route/link/ipip.c8
-rw-r--r--lib/route/link/ipvti.c8
-rw-r--r--lib/route/link/sit.c8
-rw-r--r--lib/route/link/vxlan.c107
8 files changed, 132 insertions, 27 deletions
diff --git a/include/netlink-private/netlink.h b/include/netlink-private/netlink.h
index b06df8b..6d40ea5 100644
--- a/include/netlink-private/netlink.h
+++ b/include/netlink-private/netlink.h
@@ -136,6 +136,7 @@ extern char *__flags2str(int, char *, size_t, const struct trans_tbl *, size_t);
extern int __str2flags(const char *, const struct trans_tbl *, size_t);
extern void dump_from_ops(struct nl_object *, struct nl_dump_params *);
+extern struct rtnl_link *link_lookup(struct nl_cache *cache, int ifindex);
static inline int nl_cb_call(struct nl_cb *cb, int type, struct nl_msg *msg)
{
diff --git a/lib/route/link.c b/lib/route/link.c
index 6dc416b..8ef43b5 100644
--- a/lib/route/link.c
+++ b/lib/route/link.c
@@ -67,6 +67,17 @@ static struct nl_cache_ops rtnl_link_ops;
static struct nl_object_ops link_obj_ops;
/** @endcond */
+struct rtnl_link *link_lookup(struct nl_cache *cache, int ifindex)
+{
+ if (!cache) {
+ cache = __nl_cache_mngt_require("route/link");
+ if (!cache)
+ return NULL;
+ }
+
+ return rtnl_link_get(cache, ifindex);
+}
+
static struct rtnl_link_af_ops *af_lookup_and_alloc(struct rtnl_link *link,
int family)
{
diff --git a/lib/route/link/ip6tnl.c b/lib/route/link/ip6tnl.c
index 59b06b7..085bf66 100644
--- a/lib/route/link/ip6tnl.c
+++ b/lib/route/link/ip6tnl.c
@@ -218,10 +218,16 @@ static void ip6_tnl_dump_details(struct rtnl_link *link, struct nl_dump_params *
{
struct ip6_tnl_info *ip6_tnl = link->l_info;
char *name, addr[INET6_ADDRSTRLEN];
+ struct rtnl_link *parent;
if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_LINK) {
nl_dump(p, " link ");
- name = rtnl_link_get_name(link);
+
+ name = NULL;
+ parent = link_lookup(link->ce_cache, ip6_tnl->link);
+ if (parent)
+ name = rtnl_link_get_name(parent);
+
if (name)
nl_dump_line(p, "%s\n", name);
else
diff --git a/lib/route/link/ipgre.c b/lib/route/link/ipgre.c
index c39a5e7..7889d11 100644
--- a/lib/route/link/ipgre.c
+++ b/lib/route/link/ipgre.c
@@ -226,10 +226,16 @@ static void ipgre_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
{
struct ipgre_info *ipgre = link->l_info;
char *name, addr[INET_ADDRSTRLEN];
+ struct rtnl_link *parent;
if (ipgre->ipgre_mask & IPGRE_ATTR_LINK) {
nl_dump(p, " link ");
- name = rtnl_link_get_name(link);
+
+ name = NULL;
+ parent = link_lookup(link->ce_cache, ipgre->link);
+ if (parent)
+ name = rtnl_link_get_name(parent);
+
if (name)
nl_dump_line(p, "%s\n", name);
else
diff --git a/lib/route/link/ipip.c b/lib/route/link/ipip.c
index 5ded380..593d409 100644
--- a/lib/route/link/ipip.c
+++ b/lib/route/link/ipip.c
@@ -180,10 +180,16 @@ static void ipip_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
{
struct ipip_info *ipip = link->l_info;
char *name, addr[INET_ADDRSTRLEN];
+ struct rtnl_link *parent;
if (ipip->ipip_mask & IPIP_ATTR_LINK) {
nl_dump(p, " link ");
- name = rtnl_link_get_name(link);
+
+ name = NULL;
+ parent = link_lookup(link->ce_cache, ipip->link);
+ if (parent)
+ name = rtnl_link_get_name(parent);
+
if (name)
nl_dump_line(p, "%s\n", name);
else
diff --git a/lib/route/link/ipvti.c b/lib/route/link/ipvti.c
index d627a8e..7021a94 100644
--- a/lib/route/link/ipvti.c
+++ b/lib/route/link/ipvti.c
@@ -170,10 +170,16 @@ static void ipvti_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
{
struct ipvti_info *ipvti = link->l_info;
char *name, addr[INET_ADDRSTRLEN];
+ struct rtnl_link *parent;
if (ipvti->ipvti_mask & IPVTI_ATTR_LINK) {
nl_dump(p, " link ");
- name = rtnl_link_get_name(link);
+
+ name = NULL;
+ parent = link_lookup(link->ce_cache, ipvti->link);
+ if (parent)
+ name = rtnl_link_get_name(parent);
+
if (name)
nl_dump_line(p, "%s\n", name);
else
diff --git a/lib/route/link/sit.c b/lib/route/link/sit.c
index 75987b9..6e6a09a 100644
--- a/lib/route/link/sit.c
+++ b/lib/route/link/sit.c
@@ -204,10 +204,16 @@ static void sit_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
{
struct sit_info *sit = link->l_info;
char *name, addr[INET_ADDRSTRLEN];
+ struct rtnl_link *parent;
if (sit->sit_mask & SIT_ATTR_LINK) {
nl_dump(p, " link ");
- name = rtnl_link_get_name(link);
+
+ name = NULL;
+ parent = link_lookup(link->ce_cache, sit->link);
+ if (parent)
+ name = rtnl_link_get_name(parent);
+
if (name)
nl_dump_line(p, "%s\n", name);
else
diff --git a/lib/route/link/vxlan.c b/lib/route/link/vxlan.c
index 127d2dd..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,21 +237,33 @@ 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) {
nl_dump(p, " link ");
- name = rtnl_link_get_name(link);
+
+ name = NULL;
+ parent = link_lookup(link->ce_cache, vxi->vxi_link);
+ if (parent)
+ name = rtnl_link_get_name(parent);
+
if (name)
nl_dump_line(p, "%s\n", name);
else
@@ -240,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)
@@ -356,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);
@@ -517,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;
}
@@ -544,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;
}
@@ -608,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;
}
@@ -635,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;
}