summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Winter <Thomas.Winter@alliedtelesis.co.nz>2018-06-25 23:02:16 (GMT)
committerThomas Haller <thaller@redhat.com>2022-03-11 23:07:48 (GMT)
commit41e436548a4641c309c6fb80e8d47f8b65392f14 (patch)
treeed6b8dd19f8c40ef9101be4ae9515f52579e2e07
parentebc7df3b50ed09a04f07a0ef1ee70f7b25b02b6f (diff)
downloadlibnl-41e436548a4641c309c6fb80e8d47f8b65392f14.zip
libnl-41e436548a4641c309c6fb80e8d47f8b65392f14.tar.gz
libnl-41e436548a4641c309c6fb80e8d47f8b65392f14.tar.bz2
ip6gre: Add fwmark API
This is a new option that was added in Linux v4.12. Signed-off-by: Thomas Winter <Thomas.Winter@alliedtelesis.co.nz>
-rw-r--r--doc/route.txt3
-rw-r--r--include/netlink/route/link/ip6gre.h3
-rw-r--r--lib/route/link/ip6gre.c55
-rw-r--r--libnl-route-3.sym2
4 files changed, 63 insertions, 0 deletions
diff --git a/doc/route.txt b/doc/route.txt
index 44e0434..7802060 100644
--- a/doc/route.txt
+++ b/doc/route.txt
@@ -1314,6 +1314,9 @@ extern int rtnl_link_ip6gre_get_flowinfo(struct rtnl_link *link, uint32_t *flowi
extern int rtnl_link_ip6gre_set_flags(struct rtnl_link *link, uint32_t flags);
extern int rtnl_link_ip6gre_get_flags(struct rtnl_link *link, uint32_t *flags);
+extern int rtnl_link_ip6gre_set_fwmark(struct rtnl_link *link, uint32_t fwmark);
+extern int rtnl_link_ip6gre_get_fwmark(struct rtnl_link *link, uint32_t *fwmark);
+
----
.Example: Add a ip6gre tunnel device
diff --git a/include/netlink/route/link/ip6gre.h b/include/netlink/route/link/ip6gre.h
index 97bcf06..2838592 100644
--- a/include/netlink/route/link/ip6gre.h
+++ b/include/netlink/route/link/ip6gre.h
@@ -48,6 +48,9 @@ extern "C" {
extern int rtnl_link_ip6gre_set_flags(struct rtnl_link *link, uint32_t flags);
extern int rtnl_link_ip6gre_get_flags(struct rtnl_link *link, uint32_t *flags);
+ extern int rtnl_link_ip6gre_set_fwmark(struct rtnl_link *link, uint32_t fwmark);
+ extern int rtnl_link_ip6gre_get_fwmark(struct rtnl_link *link, uint32_t *fwmark);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/route/link/ip6gre.c b/lib/route/link/ip6gre.c
index 8069329..8583a01 100644
--- a/lib/route/link/ip6gre.c
+++ b/lib/route/link/ip6gre.c
@@ -34,6 +34,7 @@
#define IP6GRE_ATTR_ENCAPLIMIT (1 << 8)
#define IP6GRE_ATTR_FLOWINFO (1 << 9)
#define IP6GRE_ATTR_FLAGS (1 << 10)
+#define IP6GRE_ATTR_FWMARK (1 << 11)
struct ip6gre_info
{
@@ -48,6 +49,7 @@ struct ip6gre_info
uint32_t flags;
struct in6_addr local;
struct in6_addr remote;
+ uint32_t fwmark;
uint32_t ip6gre_mask;
};
@@ -63,6 +65,7 @@ static struct nla_policy ip6gre_policy[IFLA_GRE_MAX + 1] = {
[IFLA_GRE_ENCAP_LIMIT] = { .type = NLA_U8 },
[IFLA_GRE_FLOWINFO] = { .type = NLA_U32 },
[IFLA_GRE_FLAGS] = { .type = NLA_U32 },
+ [IFLA_GRE_FWMARK] = { .type = NLA_U32 },
};
static int ip6gre_alloc(struct rtnl_link *link)
@@ -156,6 +159,11 @@ static int ip6gre_parse(struct rtnl_link *link, struct nlattr *data,
ip6gre->ip6gre_mask |= IP6GRE_ATTR_FLAGS;
}
+ if (tb[IFLA_GRE_FWMARK]) {
+ ip6gre->fwmark = nla_get_u32(tb[IFLA_GRE_FWMARK]);
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_FWMARK;
+ }
+
err = 0;
errout:
@@ -204,6 +212,9 @@ static int ip6gre_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
if (ip6gre->ip6gre_mask & IP6GRE_ATTR_FLAGS)
NLA_PUT_U32(msg, IFLA_GRE_FLAGS, ip6gre->flags);
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_FWMARK)
+ NLA_PUT_U32(msg, IFLA_GRE_FWMARK, ip6gre->fwmark);
+
nla_nest_end(msg, data);
nla_put_failure:
@@ -293,6 +304,11 @@ static void ip6gre_dump_details(struct rtnl_link *link, struct nl_dump_params *p
nl_dump(p, " flags ");
nl_dump_line(p, "%x\n", ip6gre->flags);
}
+
+ if (ip6gre->ip6gre_mask & IP6GRE_ATTR_FWMARK) {
+ nl_dump(p, " fwmark ");
+ nl_dump_line(p, "%x\n", ip6gre->fwmark);
+ }
}
static int ip6gre_clone(struct rtnl_link *dst, struct rtnl_link *src)
@@ -823,6 +839,45 @@ int rtnl_link_ip6gre_get_flags(struct rtnl_link *link, uint32_t *flags)
return 0;
}
+/**
+ * Set IP6GRE tunnel fwmark
+ * @arg link Link object
+ * @arg fwmark fwmark
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_set_fwmark(struct rtnl_link *link, uint32_t fwmark)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ ip6gre->fwmark = fwmark;
+ ip6gre->ip6gre_mask |= IP6GRE_ATTR_FWMARK;
+
+ return 0;
+}
+
+/**
+ * Get IP6GRE tunnel fwmark
+ * @arg link Link object
+ * @arg fwmark addr to fill in with the fwmark
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6gre_get_fwmark(struct rtnl_link *link, uint32_t *fwmark)
+{
+ struct ip6gre_info *ip6gre = link->l_info;
+
+ IS_IP6GRE_LINK_ASSERT(link);
+
+ HAS_IP6GRE_ATTR_ASSERT(ip6gre, IP6GRE_ATTR_FWMARK);
+
+ *fwmark = ip6gre->fwmark;
+
+ return 0;
+}
+
static void __init ip6gre_init(void)
{
rtnl_link_register_info(&ip6gre_info_ops);
diff --git a/libnl-route-3.sym b/libnl-route-3.sym
index f3c6714..020d5cd 100644
--- a/libnl-route-3.sym
+++ b/libnl-route-3.sym
@@ -1160,6 +1160,7 @@ global:
rtnl_link_ip6gre_get_encaplimit;
rtnl_link_ip6gre_get_flags;
rtnl_link_ip6gre_get_flowinfo;
+ rtnl_link_ip6gre_get_fwmark;
rtnl_link_ip6gre_get_iflags;
rtnl_link_ip6gre_get_ikey;
rtnl_link_ip6gre_get_link;
@@ -1171,6 +1172,7 @@ global:
rtnl_link_ip6gre_set_encaplimit;
rtnl_link_ip6gre_set_flags;
rtnl_link_ip6gre_set_flowinfo;
+ rtnl_link_ip6gre_set_fwmark;
rtnl_link_ip6gre_set_iflags;
rtnl_link_ip6gre_set_ikey;
rtnl_link_ip6gre_set_link;