diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2014-09-26 21:19:43 (GMT) |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2014-10-08 14:47:43 (GMT) |
commit | b0d0d339cd69834bd05cb5c704fbf06677f754eb (patch) | |
tree | ed1d8b920f98b8b70c8403d12f499efabad48d3c /lib/route | |
parent | e00395194597c6ed34aea5fefff42525e462a666 (diff) | |
download | libnl-b0d0d339cd69834bd05cb5c704fbf06677f754eb.zip libnl-b0d0d339cd69834bd05cb5c704fbf06677f754eb.tar.gz libnl-b0d0d339cd69834bd05cb5c704fbf06677f754eb.tar.bz2 |
link/inet6: add support for tokenized interface identifiers
http://tools.ietf.org/html/draft-chown-6man-tokenised-ipv6-identifiers-02
[thaller@redhat.com: Add OOM handling, fix whitespace issues]
https://github.com/thom311/libnl/pull/63
Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
Signed-off-by: Thomas Haller <thaller@redhat.com>
Diffstat (limited to 'lib/route')
-rw-r--r-- | lib/route/link/inet6.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/lib/route/link/inet6.c b/lib/route/link/inet6.c index 0f096fc..f5b1802 100644 --- a/lib/route/link/inet6.c +++ b/lib/route/link/inet6.c @@ -22,6 +22,7 @@ struct inet6_data uint32_t i6_flags; struct ifla_cacheinfo i6_cacheinfo; uint32_t i6_conf[DEVCONF_MAX]; + struct in6_addr i6_token; uint8_t i6_addr_gen_mode; }; @@ -57,6 +58,7 @@ static struct nla_policy inet6_policy[IFLA_INET6_MAX+1] = { [IFLA_INET6_CONF] = { .minlen = 4 }, [IFLA_INET6_STATS] = { .minlen = 8 }, [IFLA_INET6_ICMP6STATS] = { .minlen = 8 }, + [IFLA_INET6_TOKEN] = { .minlen = sizeof(struct in6_addr) }, [IFLA_INET6_ADDR_GEN_MODE] = { .type = NLA_U8 }, }; @@ -166,6 +168,10 @@ static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr, nla_memcpy(&i6->i6_conf, tb[IFLA_INET6_CONF], sizeof(i6->i6_conf)); + if (tb[IFLA_INET6_TOKEN]) + nla_memcpy(&i6->i6_token, tb[IFLA_INET6_TOKEN], + sizeof(struct in6_addr)); + if (tb[IFLA_INET6_ADDR_GEN_MODE]) i6->i6_addr_gen_mode = nla_get_u8 (tb[IFLA_INET6_ADDR_GEN_MODE]); @@ -306,6 +312,7 @@ static void inet6_dump_details(struct rtnl_link *link, struct nl_dump_params *p, void *data) { struct inet6_data *i6 = data; + struct nl_addr *addr; char buf[64], buf2[64]; int i, n = 0; @@ -323,6 +330,11 @@ static void inet6_dump_details(struct rtnl_link *link, nl_dump(p, " retrans-time %s\n", nl_msec2str(i6->i6_cacheinfo.retrans_time, buf, sizeof(buf))); + addr = nl_addr_build(AF_INET6, &i6->i6_token, sizeof(i6->i6_token)); + nl_dump(p, " token %s\n", + nl_addr2str(addr, buf, sizeof(buf))); + nl_addr_put(addr); + nl_dump(p, " link-local address mode %s\n", rtnl_link_inet6_addrgenmode2str(i6->i6_addr_gen_mode, buf, sizeof(buf))); @@ -521,6 +533,64 @@ static struct rtnl_link_af_ops inet6_ops = { }; /** + * Get IPv6 tokenized interface identifier + * @arg link Link object + * @arg token Tokenized interface identifier on success + * + * Returns the link's IPv6 tokenized interface identifier. + * + * @return 0 on success + * @return -NLE_NOMEM failure to allocate struct nl_addr result + * @return -NLE_NOATTR configuration setting not available + * @return -NLE_NOADDR tokenized interface identifier is not set + */ +int rtnl_link_inet6_get_token(struct rtnl_link *link, struct nl_addr **addr) +{ + struct inet6_data *id; + + if (!(id = rtnl_link_af_data(link, &inet6_ops))) + return -NLE_NOATTR; + + *addr = nl_addr_build(AF_INET6, &id->i6_token, sizeof(id->i6_token)); + if (!*addr) + return -NLE_NOMEM; + if (nl_addr_iszero(*addr)) { + nl_addr_put(*addr); + *addr = NULL; + return -NLE_NOADDR; + } + + return 0; +} + +/** + * Set IPv6 tokenized interface identifier + * @arg link Link object + * @arg token Tokenized interface identifier + * + * Sets the link's IPv6 tokenized interface identifier. + * + * @return 0 on success + * @return -NLE_NOMEM could not allocate inet6 data + * @return -NLE_INVAL addr is not a valid inet6 address + */ +int rtnl_link_inet6_set_token(struct rtnl_link *link, struct nl_addr *addr) +{ + struct inet6_data *id; + + if ((nl_addr_get_family(addr) != AF_INET6) || + (nl_addr_get_len(addr) != sizeof(id->i6_token))) + return -NLE_INVAL; + + if (!(id = rtnl_link_af_alloc(link, &inet6_ops))) + return -NLE_NOMEM; + + memcpy(&id->i6_token, nl_addr_get_binary_addr(addr), + sizeof(id->i6_token)); + return 0; +} + +/** * Get IPv6 link-local address generation mode * @arg link Link object * @arg mode Generation mode on success |