summaryrefslogtreecommitdiffstats
path: root/lib/route
diff options
context:
space:
mode:
authorThomas Winter <Thomas.Winter@alliedtelesis.co.nz>2018-06-25 23:06:56 (GMT)
committerThomas Haller <thaller@redhat.com>2022-03-11 23:07:48 (GMT)
commit05a540d315938b22463f6789f4da139de38f977d (patch)
tree1553312f462e0ce9bb0d9c0f2b3e02dd2e3c4062 /lib/route
parent41e436548a4641c309c6fb80e8d47f8b65392f14 (diff)
downloadlibnl-05a540d315938b22463f6789f4da139de38f977d.zip
libnl-05a540d315938b22463f6789f4da139de38f977d.tar.gz
libnl-05a540d315938b22463f6789f4da139de38f977d.tar.bz2
ip6vti: 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>
Diffstat (limited to 'lib/route')
-rw-r--r--lib/route/link/ip6vti.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/lib/route/link/ip6vti.c b/lib/route/link/ip6vti.c
index 56f4485..d2582ae 100644
--- a/lib/route/link/ip6vti.c
+++ b/lib/route/link/ip6vti.c
@@ -35,6 +35,7 @@
#define IP6VTI_ATTR_OKEY (1 << 2)
#define IP6VTI_ATTR_LOCAL (1 << 3)
#define IP6VTI_ATTR_REMOTE (1 << 4)
+#define IP6VTI_ATTR_FWMARK (1 << 5)
struct ip6vti_info
{
@@ -43,6 +44,7 @@ struct ip6vti_info
uint32_t okey;
struct in6_addr local;
struct in6_addr remote;
+ uint32_t fwmark;
uint32_t ip6vti_mask;
};
@@ -52,6 +54,7 @@ static struct nla_policy ip6vti_policy[IFLA_VTI_MAX + 1] = {
[IFLA_VTI_OKEY] = { .type = NLA_U32 },
[IFLA_VTI_LOCAL] = { .minlen = sizeof(struct in6_addr) },
[IFLA_VTI_REMOTE] = { .minlen = sizeof(struct in6_addr) },
+ [IFLA_VTI_FWMARK] = { .type = NLA_U32 },
};
static int ip6vti_alloc(struct rtnl_link *link)
@@ -115,6 +118,11 @@ static int ip6vti_parse(struct rtnl_link *link, struct nlattr *data,
ip6vti->ip6vti_mask |= IP6VTI_ATTR_REMOTE;
}
+ if (tb[IFLA_VTI_FWMARK]) {
+ ip6vti->fwmark = nla_get_u32(tb[IFLA_VTI_FWMARK]);
+ ip6vti->ip6vti_mask |= IP6VTI_ATTR_FWMARK;
+ }
+
err = 0;
errout:
@@ -145,6 +153,9 @@ static int ip6vti_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
if (ip6vti->ip6vti_mask & IP6VTI_ATTR_REMOTE)
NLA_PUT(msg, IFLA_VTI_REMOTE, sizeof(struct in6_addr), &ip6vti->remote);
+ if (ip6vti->ip6vti_mask & IP6VTI_ATTR_FWMARK)
+ NLA_PUT_U32(msg, IFLA_VTI_FWMARK, ip6vti->fwmark);
+
nla_nest_end(msg, data);
nla_put_failure:
@@ -204,6 +215,11 @@ static void ip6vti_dump_details(struct rtnl_link *link, struct nl_dump_params *p
else
nl_dump_line(p, "%#x\n", ip6vti->remote);
}
+
+ if (ip6vti->ip6vti_mask & IP6VTI_ATTR_FWMARK) {
+ nl_dump(p, " fwmark ");
+ nl_dump_line(p, "%x\n", ip6vti->fwmark);
+ }
}
static int ip6vti_clone(struct rtnl_link *dst, struct rtnl_link *src)
@@ -498,6 +514,45 @@ int rtnl_link_ip6vti_get_remote(struct rtnl_link *link, struct in6_addr *remote)
return 0;
}
+/**
+ * Set IP6VTI tunnel fwmark
+ * @arg link Link object
+ * @arg fwmark fwmark
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ip6vti_set_fwmark(struct rtnl_link *link, uint32_t fwmark)
+{
+ struct ip6vti_info *ip6vti = link->l_info;
+
+ IS_IP6VTI_LINK_ASSERT(link);
+
+ ip6vti->fwmark = fwmark;
+ ip6vti->ip6vti_mask |= IP6VTI_ATTR_FWMARK;
+
+ return 0;
+}
+
+/**
+ * Get IP6VTI 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_ip6vti_get_fwmark(struct rtnl_link *link, uint32_t *fwmark)
+{
+ struct ip6vti_info *ip6vti = link->l_info;
+
+ IS_IP6VTI_LINK_ASSERT(link);
+
+ HAS_IP6VTI_ATTR_ASSERT(ip6vti, IP6VTI_ATTR_FWMARK);
+
+ *fwmark = ip6vti->fwmark;
+
+ return 0;
+}
+
static void __init ip6vti_init(void)
{
rtnl_link_register_info(&ip6vti_info_ops);