diff options
author | Thomas Haller <thaller@redhat.com> | 2015-11-19 16:40:32 (GMT) |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2015-11-19 16:41:31 (GMT) |
commit | c96455b869442552c06d820c8d4cda6e8234873b (patch) | |
tree | b9d5040e8e7487a92bfdeaba7dc2fafdc16676e7 | |
parent | 3f231213c7c586b5a5e8ce6b1ea9c1d3b24d74c0 (diff) | |
parent | 2e68fb5b02304fa6a3e6429c4fdabb084e61b501 (diff) | |
download | libnl-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.h | 1 | ||||
-rw-r--r-- | lib/route/link.c | 11 | ||||
-rw-r--r-- | lib/route/link/ip6tnl.c | 8 | ||||
-rw-r--r-- | lib/route/link/ipgre.c | 8 | ||||
-rw-r--r-- | lib/route/link/ipip.c | 8 | ||||
-rw-r--r-- | lib/route/link/ipvti.c | 8 | ||||
-rw-r--r-- | lib/route/link/sit.c | 8 | ||||
-rw-r--r-- | lib/route/link/vxlan.c | 107 |
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; } |