diff options
author | Thomas Haller <thaller@redhat.com> | 2016-04-19 14:17:00 (GMT) |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2016-04-19 14:17:23 (GMT) |
commit | fc8accf640d412d50c41881692c62ab7789383a4 (patch) | |
tree | 3c427ad9652a4f0bc96beb0d1a6007ec1570c4de | |
parent | eec318f0260f4f081355e802aaa4844b07557d5b (diff) | |
parent | 207dc0352779af46121a83fb4758cdd3155d9001 (diff) | |
download | libnl-fc8accf640d412d50c41881692c62ab7789383a4.zip libnl-fc8accf640d412d50c41881692c62ab7789383a4.tar.gz libnl-fc8accf640d412d50c41881692c62ab7789383a4.tar.bz2 |
sit: merge branch 'sit-ip6rd'
http://lists.infradead.org/pipermail/libnl/2016-February/002086.html
Signed-off-by: Thomas Haller <thaller@redhat.com>
-rw-r--r-- | include/netlink/route/link/sit.h | 14 | ||||
-rw-r--r-- | lib/route/link/sit.c | 298 | ||||
-rw-r--r-- | libnl-route-3.sym | 8 |
3 files changed, 264 insertions, 56 deletions
diff --git a/include/netlink/route/link/sit.h b/include/netlink/route/link/sit.h index 84dc44a..8f58d0a 100644 --- a/include/netlink/route/link/sit.h +++ b/include/netlink/route/link/sit.h @@ -44,7 +44,19 @@ extern "C" { extern uint16_t rtnl_link_sit_get_flags(struct rtnl_link *link); int rtnl_link_sit_set_proto(struct rtnl_link *link, uint8_t proto); - uint8_t rtnl_link_get_proto(struct rtnl_link *link); + uint8_t rtnl_link_sit_get_proto(struct rtnl_link *link); + + int rtnl_link_sit_set_ip6rd_prefix(struct rtnl_link *link, const struct in6_addr *prefix); + int rtnl_link_sit_get_ip6rd_prefix(const struct rtnl_link *link, struct in6_addr *prefix); + + int rtnl_link_sit_set_ip6rd_prefixlen(struct rtnl_link *link, uint16_t prefixlen); + int rtnl_link_sit_get_ip6rd_prefixlen(struct rtnl_link *link, uint16_t *prefixlen); + + int rtnl_link_sit_set_ip6rd_relay_prefix(struct rtnl_link *link, uint32_t prefix); + int rtnl_link_sit_get_ip6rd_relay_prefix(const struct rtnl_link *link, uint32_t *prefix); + + int rtnl_link_sit_set_ip6rd_relay_prefixlen(struct rtnl_link *link, uint16_t prefix); + int rtnl_link_sit_get_ip6rd_relay_prefixlen(struct rtnl_link *link, uint16_t *prefix); #ifdef _cplusplus } diff --git a/lib/route/link/sit.c b/lib/route/link/sit.c index 6e6a09a..c64cbf5 100644 --- a/lib/route/link/sit.c +++ b/lib/route/link/sit.c @@ -40,6 +40,10 @@ #define SIT_ATTR_PMTUDISC (1 << 5) #define SIT_ATTR_FLAGS (1 << 6) #define SIT_ATTR_PROTO (1 << 7) +#define SIT_ATTR_6RD_PREFIX (1 << 8) +#define SIT_ATTR_6RD_RELAY_PREFIX (1 << 9) +#define SIT_ATTR_6RD_PREFIXLEN (1 << 10) +#define SIT_ATTR_6RD_RELAY_PREFIXLEN (1 << 11) struct sit_info { @@ -51,6 +55,10 @@ struct sit_info uint32_t link; uint32_t local; uint32_t remote; + struct in6_addr ip6rd_prefix; + uint32_t ip6rd_relay_prefix; + uint16_t ip6rd_prefixlen; + uint16_t ip6rd_relay_prefixlen; uint32_t sit_mask; }; @@ -63,6 +71,10 @@ static struct nla_policy sit_policy[IFLA_IPTUN_MAX + 1] = { [IFLA_IPTUN_PMTUDISC] = { .type = NLA_U8 }, [IFLA_IPTUN_FLAGS] = { .type = NLA_U16 }, [IFLA_IPTUN_PROTO] = { .type = NLA_U8 }, + [IFLA_IPTUN_6RD_PREFIX] = { .minlen = sizeof(struct in6_addr) }, + [IFLA_IPTUN_6RD_RELAY_PREFIX] = { .type = NLA_U32 }, + [IFLA_IPTUN_6RD_PREFIXLEN] = { .type = NLA_U16 }, + [IFLA_IPTUN_6RD_RELAY_PREFIXLEN] = { .type = NLA_U16 }, }; static int sit_alloc(struct rtnl_link *link) @@ -141,6 +153,27 @@ static int sit_parse(struct rtnl_link *link, struct nlattr *data, sit->sit_mask |= SIT_ATTR_PROTO; } + if (tb[IFLA_IPTUN_6RD_PREFIX]) { + nla_memcpy(&sit->ip6rd_prefix, tb[IFLA_IPTUN_6RD_PREFIX], + sizeof(struct in6_addr)); + sit->sit_mask |= SIT_ATTR_6RD_PREFIX; + } + + if (tb[IFLA_IPTUN_6RD_RELAY_PREFIX]) { + sit->ip6rd_relay_prefix = nla_get_u32(tb[IFLA_IPTUN_6RD_RELAY_PREFIX]); + sit->sit_mask |= SIT_ATTR_6RD_RELAY_PREFIX; + } + + if (tb[IFLA_IPTUN_6RD_PREFIXLEN]) { + sit->ip6rd_prefixlen = nla_get_u16(tb[IFLA_IPTUN_6RD_PREFIXLEN]); + sit->sit_mask |= SIT_ATTR_6RD_PREFIXLEN; + } + + if (tb[IFLA_IPTUN_6RD_RELAY_PREFIXLEN]) { + sit->ip6rd_relay_prefixlen = nla_get_u16(tb[IFLA_IPTUN_6RD_RELAY_PREFIXLEN]); + sit->sit_mask |= SIT_ATTR_6RD_RELAY_PREFIXLEN; + } + err = 0; errout: @@ -180,6 +213,18 @@ static int sit_put_attrs(struct nl_msg *msg, struct rtnl_link *link) if (sit->sit_mask & SIT_ATTR_PROTO) NLA_PUT_U8(msg, IFLA_IPTUN_PROTO, sit->proto); + if (sit->sit_mask & SIT_ATTR_6RD_PREFIX) + NLA_PUT(msg, IFLA_IPTUN_6RD_PREFIX, sizeof(struct in6_addr), &sit->ip6rd_prefix); + + if (sit->sit_mask & SIT_ATTR_6RD_RELAY_PREFIX) + NLA_PUT_U32(msg, IFLA_IPTUN_6RD_RELAY_PREFIX, sit->ip6rd_relay_prefix); + + if (sit->sit_mask & SIT_ATTR_6RD_PREFIXLEN) + NLA_PUT_U16(msg, IFLA_IPTUN_6RD_PREFIXLEN, sit->ip6rd_prefixlen); + + if (sit->sit_mask & SIT_ATTR_6RD_RELAY_PREFIXLEN) + NLA_PUT_U16(msg, IFLA_IPTUN_6RD_RELAY_PREFIXLEN, sit->ip6rd_relay_prefixlen); + nla_nest_end(msg, data); nla_put_failure: @@ -203,7 +248,7 @@ static void sit_dump_line(struct rtnl_link *link, struct nl_dump_params *p) 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]; + char *name, addr[INET_ADDRSTRLEN], addr6[INET6_ADDRSTRLEN]; struct rtnl_link *parent; if (sit->sit_mask & SIT_ATTR_LINK) { @@ -252,9 +297,35 @@ static void sit_dump_details(struct rtnl_link *link, struct nl_dump_params *p) } if (sit->sit_mask & SIT_ATTR_PROTO) { - nl_dump(p, " proto "); + nl_dump(p, " proto "); nl_dump_line(p, " (%x)\n", sit->proto); } + + if (sit->sit_mask & SIT_ATTR_6RD_PREFIX) { + nl_dump(p, " 6rd_prefix "); + if(inet_ntop(AF_INET6, &sit->ip6rd_prefix, addr6, INET6_ADDRSTRLEN)) + nl_dump_line(p, "%s\n", addr6); + else + nl_dump_line(p, "[unknown]\n"); + } + + if (sit->sit_mask & SIT_ATTR_6RD_RELAY_PREFIX) { + nl_dump(p, " 6rd_relay_prefix "); + if(inet_ntop(AF_INET, &sit->ip6rd_relay_prefix, addr, sizeof(addr))) + nl_dump_line(p, "%s\n", addr); + else + nl_dump_line(p, "[unknown]\n"); + } + + if (sit->sit_mask & SIT_ATTR_6RD_PREFIXLEN) { + nl_dump(p, " 6rd_prefixlen "); + nl_dump_line(p, "%d\n", sit->ip6rd_prefixlen); + } + + if (sit->sit_mask & SIT_ATTR_6RD_RELAY_PREFIXLEN) { + nl_dump(p, " 6rd_relay_prefixlen "); + nl_dump_line(p, "%d\n", sit->ip6rd_relay_prefixlen); + } } static int sit_clone(struct rtnl_link *dst, struct rtnl_link *src) @@ -291,11 +362,16 @@ static struct rtnl_link_info_ops sit_info_ops = { .io_free = sit_free, }; -#define IS_SIT_LINK_ASSERT(link) \ - if ((link)->l_info_ops != &sit_info_ops) { \ - APPBUG("Link is not a sit link. set type \"sit\" first."); \ - return -NLE_OPNOTSUPP; \ - } +#define IS_SIT_LINK_ASSERT(link, sit) \ + struct sit_info *sit; \ + do { \ + const struct rtnl_link *_link = (link); \ + if (!_link || _link->l_info_ops != &sit_info_ops) { \ + APPBUG("Link is not a sit link. set type \"sit\" first."); \ + return -NLE_OPNOTSUPP; \ + } \ + (sit) = _link->l_info; \ + } while (0) struct rtnl_link *rtnl_link_sit_alloc(void) { @@ -361,9 +437,7 @@ int rtnl_link_sit_add(struct nl_sock *sk, const char *name) */ int rtnl_link_sit_set_link(struct rtnl_link *link, uint32_t index) { - struct sit_info *sit = link->l_info; - - IS_SIT_LINK_ASSERT(link); + IS_SIT_LINK_ASSERT(link, sit); sit->link = index; sit->sit_mask |= SIT_ATTR_LINK; @@ -379,9 +453,7 @@ int rtnl_link_sit_set_link(struct rtnl_link *link, uint32_t index) */ uint32_t rtnl_link_sit_get_link(struct rtnl_link *link) { - struct sit_info *sit = link->l_info; - - IS_SIT_LINK_ASSERT(link); + IS_SIT_LINK_ASSERT(link, sit); return sit->link; } @@ -395,9 +467,7 @@ uint32_t rtnl_link_sit_get_link(struct rtnl_link *link) */ int rtnl_link_sit_set_local(struct rtnl_link *link, uint32_t addr) { - struct sit_info *sit = link->l_info; - - IS_SIT_LINK_ASSERT(link); + IS_SIT_LINK_ASSERT(link, sit); sit->local = addr; sit->sit_mask |= SIT_ATTR_LOCAL; @@ -413,9 +483,7 @@ int rtnl_link_sit_set_local(struct rtnl_link *link, uint32_t addr) */ uint32_t rtnl_link_sit_get_local(struct rtnl_link *link) { - struct sit_info *sit = link->l_info; - - IS_SIT_LINK_ASSERT(link); + IS_SIT_LINK_ASSERT(link, sit); return sit->local; } @@ -429,9 +497,7 @@ uint32_t rtnl_link_sit_get_local(struct rtnl_link *link) */ int rtnl_link_sit_set_remote(struct rtnl_link *link, uint32_t addr) { - struct sit_info *sit = link->l_info; - - IS_SIT_LINK_ASSERT(link); + IS_SIT_LINK_ASSERT(link, sit); sit->remote = addr; sit->sit_mask |= SIT_ATTR_REMOTE; @@ -447,9 +513,7 @@ int rtnl_link_sit_set_remote(struct rtnl_link *link, uint32_t addr) */ uint32_t rtnl_link_sit_get_remote(struct rtnl_link *link) { - struct sit_info *sit = link->l_info; - - IS_SIT_LINK_ASSERT(link); + IS_SIT_LINK_ASSERT(link, sit); return sit->remote; } @@ -463,9 +527,7 @@ uint32_t rtnl_link_sit_get_remote(struct rtnl_link *link) */ int rtnl_link_sit_set_ttl(struct rtnl_link *link, uint8_t ttl) { - struct sit_info *sit = link->l_info; - - IS_SIT_LINK_ASSERT(link); + IS_SIT_LINK_ASSERT(link, sit); sit->ttl = ttl; sit->sit_mask |= SIT_ATTR_TTL; @@ -481,9 +543,7 @@ int rtnl_link_sit_set_ttl(struct rtnl_link *link, uint8_t ttl) */ uint8_t rtnl_link_sit_get_ttl(struct rtnl_link *link) { - struct sit_info *sit = link->l_info; - - IS_SIT_LINK_ASSERT(link); + IS_SIT_LINK_ASSERT(link, sit); return sit->ttl; } @@ -497,9 +557,7 @@ uint8_t rtnl_link_sit_get_ttl(struct rtnl_link *link) */ int rtnl_link_sit_set_tos(struct rtnl_link *link, uint8_t tos) { - struct sit_info *sit = link->l_info; - - IS_SIT_LINK_ASSERT(link); + IS_SIT_LINK_ASSERT(link, sit); sit->tos = tos; sit->sit_mask |= SIT_ATTR_TOS; @@ -515,9 +573,7 @@ int rtnl_link_sit_set_tos(struct rtnl_link *link, uint8_t tos) */ uint8_t rtnl_link_sit_get_tos(struct rtnl_link *link) { - struct sit_info *sit = link->l_info; - - IS_SIT_LINK_ASSERT(link); + IS_SIT_LINK_ASSERT(link, sit); return sit->tos; } @@ -531,9 +587,7 @@ uint8_t rtnl_link_sit_get_tos(struct rtnl_link *link) */ int rtnl_link_sit_set_pmtudisc(struct rtnl_link *link, uint8_t pmtudisc) { - struct sit_info *sit = link->l_info; - - IS_SIT_LINK_ASSERT(link); + IS_SIT_LINK_ASSERT(link, sit); sit->pmtudisc = pmtudisc; sit->sit_mask |= SIT_ATTR_PMTUDISC; @@ -549,9 +603,7 @@ int rtnl_link_sit_set_pmtudisc(struct rtnl_link *link, uint8_t pmtudisc) */ uint8_t rtnl_link_sit_get_pmtudisc(struct rtnl_link *link) { - struct sit_info *sit = link->l_info; - - IS_SIT_LINK_ASSERT(link); + IS_SIT_LINK_ASSERT(link, sit); return sit->pmtudisc; } @@ -565,9 +617,7 @@ uint8_t rtnl_link_sit_get_pmtudisc(struct rtnl_link *link) */ int rtnl_link_sit_set_flags(struct rtnl_link *link, uint16_t flags) { - struct sit_info *sit = link->l_info; - - IS_SIT_LINK_ASSERT(link); + IS_SIT_LINK_ASSERT(link, sit); sit->flags = flags; sit->sit_mask |= SIT_ATTR_FLAGS; @@ -583,9 +633,7 @@ int rtnl_link_sit_set_flags(struct rtnl_link *link, uint16_t flags) */ uint16_t rtnl_link_sit_get_flags(struct rtnl_link *link) { - struct sit_info *sit = link->l_info; - - IS_SIT_LINK_ASSERT(link); + IS_SIT_LINK_ASSERT(link, sit); return sit->flags; } @@ -599,9 +647,7 @@ uint16_t rtnl_link_sit_get_flags(struct rtnl_link *link) */ int rtnl_link_sit_set_proto(struct rtnl_link *link, uint8_t proto) { - struct sit_info *sit = link->l_info; - - IS_SIT_LINK_ASSERT(link); + IS_SIT_LINK_ASSERT(link, sit); sit->proto = proto; sit->sit_mask |= SIT_ATTR_PROTO; @@ -617,13 +663,155 @@ int rtnl_link_sit_set_proto(struct rtnl_link *link, uint8_t proto) */ uint8_t rtnl_link_sit_get_proto(struct rtnl_link *link) { - struct sit_info *sit = link->l_info; - - IS_SIT_LINK_ASSERT(link); + IS_SIT_LINK_ASSERT(link, sit); return sit->proto; } +/** + * Set ip6rd prefix + * @arg link Link object + * @arg prefix The IPv6 prefix + * + * @return 0 on success or an error code. + */ +int rtnl_link_sit_set_ip6rd_prefix(struct rtnl_link *link, const struct in6_addr *prefix) +{ + IS_SIT_LINK_ASSERT(link, sit); + + sit->ip6rd_prefix = *prefix; + sit->sit_mask |= SIT_ATTR_6RD_PREFIX; + return 0; +} + +/** + * Get ip6rd prefix + * @arg link Link object + * @arg prefix The output IPv6 prefix + * + * @return 0 on success or an error code. If the property is unset, + * this call fails too. + */ +int rtnl_link_sit_get_ip6rd_prefix(const struct rtnl_link *link, struct in6_addr *prefix) +{ + IS_SIT_LINK_ASSERT(link, sit); + + if (!(sit->sit_mask & SIT_ATTR_6RD_PREFIX)) + return -NLE_NOATTR; + + if (prefix) + *prefix = sit->ip6rd_prefix; + return 0; +} + +/** + * Set ip6rd prefix length + * @arg link Link object + * @arg prefixlen The IPv6 prefix length + * + * @return 0 on success or an error code. + */ +int rtnl_link_sit_set_ip6rd_prefixlen(struct rtnl_link *link, uint16_t prefixlen) +{ + IS_SIT_LINK_ASSERT(link, sit); + + sit->sit_mask |= SIT_ATTR_6RD_PREFIXLEN; + sit->ip6rd_prefixlen = prefixlen; + return 0; +} + +/** + * Get ip6rd prefix length + * @arg link Link object + * @arg prefixlen Output pointer for the prefix length + * + * @return 0 on success or an error code. If the property is unset, + * this call fails. + */ +int rtnl_link_sit_get_ip6rd_prefixlen(struct rtnl_link *link, uint16_t *prefixlen) +{ + IS_SIT_LINK_ASSERT(link, sit); + + if (!(sit->sit_mask & SIT_ATTR_6RD_PREFIXLEN)) + return -NLE_NOATTR; + + if (prefixlen) + *prefixlen = sit->ip6rd_prefixlen; + return 0; +} + +/** + * Set ip6rd relay prefix + * @arg link Link object + * @arg prefix The IPv6 prefix length + * + * @return 0 on success or an error code. + */ +int rtnl_link_sit_set_ip6rd_relay_prefix(struct rtnl_link *link, uint32_t prefix) +{ + IS_SIT_LINK_ASSERT(link, sit); + + sit->sit_mask |= SIT_ATTR_6RD_RELAY_PREFIX; + sit->ip6rd_relay_prefix = prefix; + return 0; +} + +/** + * Get ip6rd prefix length + * @arg link Link object + * @arg prefixlen Output pointer for the prefix length + * + * @return 0 on success or an error code. If the property is unset, + * this call fails. + */ +int rtnl_link_sit_get_ip6rd_relay_prefix(const struct rtnl_link *link, uint32_t *prefix) +{ + IS_SIT_LINK_ASSERT(link, sit); + + if (!(sit->sit_mask & SIT_ATTR_6RD_RELAY_PREFIX)) + return -NLE_NOATTR; + + if (prefix) + *prefix = sit->ip6rd_relay_prefix; + return 0; +} + +/** + * Set ip6rd relay prefix length + * @arg link Link object + * @arg prefixlen The IPv6 prefix length + * + * @return 0 on success or an error code. + */ +int rtnl_link_sit_set_ip6rd_relay_prefixlen(struct rtnl_link *link, uint16_t prefixlen) +{ + IS_SIT_LINK_ASSERT(link, sit); + + sit->sit_mask |= SIT_ATTR_6RD_RELAY_PREFIXLEN; + sit->ip6rd_relay_prefixlen = prefixlen; + return 0; +} + +/** + * Get ip6rd relay prefix length + * @arg link Link object + * @arg prefixlen Output pointer for the prefix length + * + * @return 0 on success or an error code. If the property is unset, + * this call fails. + */ +int rtnl_link_sit_get_ip6rd_relay_prefixlen(struct rtnl_link *link, uint16_t *prefixlen) +{ + IS_SIT_LINK_ASSERT(link, sit); + + if (!(sit->sit_mask & SIT_ATTR_6RD_RELAY_PREFIX)) + return -NLE_NOATTR; + + if (prefixlen) + *prefixlen = sit->ip6rd_relay_prefixlen; + return 0; +} + static void __init sit_init(void) { rtnl_link_register_info(&sit_info_ops); diff --git a/libnl-route-3.sym b/libnl-route-3.sym index cd2b824..2c72498 100644 --- a/libnl-route-3.sym +++ b/libnl-route-3.sym @@ -905,6 +905,14 @@ global: rtnl_link_macvtap_str2flags; rtnl_link_macvtap_str2mode; rtnl_link_macvtap_unset_flags; + rtnl_link_sit_get_ip6rd_prefix; + rtnl_link_sit_get_ip6rd_prefixlen; + rtnl_link_sit_get_ip6rd_relay_prefix; + rtnl_link_sit_get_ip6rd_relay_prefixlen; + rtnl_link_sit_set_ip6rd_prefix; + rtnl_link_sit_set_ip6rd_prefixlen; + rtnl_link_sit_set_ip6rd_relay_prefix; + rtnl_link_sit_set_ip6rd_relay_prefixlen; rtnl_link_vrf_alloc; rtnl_link_vrf_get_tableid; rtnl_link_vrf_set_tableid; |