summaryrefslogtreecommitdiffstats
path: root/lib/route/link/ipvti.c
diff options
context:
space:
mode:
authorThomas Winter <Thomas.Winter@alliedtelesis.co.nz>2018-06-08 04:29:35 (GMT)
committerThomas Haller <thaller@redhat.com>2022-03-11 23:06:03 (GMT)
commitcdc6c0f321527e3aad06d11e16115daa82b54677 (patch)
tree31b5e11057711c3012ac36fbbeeeb949b984d9ec /lib/route/link/ipvti.c
parent2995710d3f13a95701e54fda33ce80eb5f811f8f (diff)
downloadlibnl-cdc6c0f321527e3aad06d11e16115daa82b54677.zip
libnl-cdc6c0f321527e3aad06d11e16115daa82b54677.tar.gz
libnl-cdc6c0f321527e3aad06d11e16115daa82b54677.tar.bz2
ipvti: 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/link/ipvti.c')
-rw-r--r--lib/route/link/ipvti.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/lib/route/link/ipvti.c b/lib/route/link/ipvti.c
index 03ee31b..9f9d3d6 100644
--- a/lib/route/link/ipvti.c
+++ b/lib/route/link/ipvti.c
@@ -31,6 +31,7 @@
#define IPVTI_ATTR_OKEY (1 << 2)
#define IPVTI_ATTR_LOCAL (1 << 3)
#define IPVTI_ATTR_REMOTE (1 << 4)
+#define IPVTI_ATTR_FWMARK (1 << 5)
struct ipvti_info
{
@@ -39,6 +40,7 @@ struct ipvti_info
uint32_t okey;
uint32_t local;
uint32_t remote;
+ uint32_t fwmark;
uint32_t ipvti_mask;
};
@@ -48,6 +50,7 @@ static struct nla_policy ipvti_policy[IFLA_VTI_MAX + 1] = {
[IFLA_VTI_OKEY] = { .type = NLA_U32 },
[IFLA_VTI_LOCAL] = { .type = NLA_U32 },
[IFLA_VTI_REMOTE] = { .type = NLA_U32 },
+ [IFLA_VTI_FWMARK] = { .type = NLA_U32 },
};
static int ipvti_alloc(struct rtnl_link *link)
@@ -111,6 +114,11 @@ static int ipvti_parse(struct rtnl_link *link, struct nlattr *data,
ipvti->ipvti_mask |= IPVTI_ATTR_REMOTE;
}
+ if (tb[IFLA_VTI_FWMARK]) {
+ ipvti->fwmark = nla_get_u32(tb[IFLA_VTI_FWMARK]);
+ ipvti->ipvti_mask |= IPVTI_ATTR_FWMARK;
+ }
+
err = 0;
errout:
@@ -141,6 +149,9 @@ static int ipvti_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
if (ipvti->ipvti_mask & IPVTI_ATTR_REMOTE)
NLA_PUT_U32(msg, IFLA_VTI_REMOTE, ipvti->remote);
+ if (ipvti->ipvti_mask & IPVTI_ATTR_FWMARK)
+ NLA_PUT_U32(msg, IFLA_VTI_FWMARK, ipvti->fwmark);
+
nla_nest_end(msg, data);
nla_put_failure:
@@ -206,6 +217,11 @@ static void ipvti_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
else
nl_dump_line(p, "%#x\n", ntohs(ipvti->remote));
}
+
+ if (ipvti->ipvti_mask & IPVTI_ATTR_FWMARK) {
+ nl_dump(p, " fwmark ");
+ nl_dump_line(p, "%x\n", ipvti->fwmark);
+ }
}
static int ipvti_clone(struct rtnl_link *dst, struct rtnl_link *src)
@@ -471,6 +487,46 @@ uint32_t rtnl_link_ipvti_get_remote(struct rtnl_link *link)
return ipvti->remote;
}
+/**
+ * Set IPVTI tunnel fwmark
+ * @arg link Link object
+ * @arg fwmark fwmark
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_ipvti_set_fwmark(struct rtnl_link *link, uint32_t fwmark)
+{
+ struct ipvti_info *ipvti = link->l_info;
+
+ IS_IPVTI_LINK_ASSERT(link);
+
+ ipvti->fwmark = fwmark;
+ ipvti->ipvti_mask |= IPVTI_ATTR_FWMARK;
+
+ return 0;
+}
+
+/**
+ * Get IPVTI 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_ipvti_get_fwmark(struct rtnl_link *link, uint32_t *fwmark)
+{
+ struct ipvti_info *ipvti = link->l_info;
+
+ IS_IPVTI_LINK_ASSERT(link);
+
+ if (!(ipvti->ipvti_mask & IPVTI_ATTR_FWMARK))
+ return -NLE_NOATTR;
+
+ *fwmark = ipvti->fwmark;
+
+ return 0;
+}
+
static void __init ipvti_init(void)
{
rtnl_link_register_info(&ipvti_info_ops);