summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2016-04-19 14:17:00 (GMT)
committerThomas Haller <thaller@redhat.com>2016-04-19 14:17:23 (GMT)
commitfc8accf640d412d50c41881692c62ab7789383a4 (patch)
tree3c427ad9652a4f0bc96beb0d1a6007ec1570c4de
parenteec318f0260f4f081355e802aaa4844b07557d5b (diff)
parent207dc0352779af46121a83fb4758cdd3155d9001 (diff)
downloadlibnl-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.h14
-rw-r--r--lib/route/link/sit.c298
-rw-r--r--libnl-route-3.sym8
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;