summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2020-03-17 14:14:05 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2020-03-17 14:14:27 +0100
commitc76d36a1a2805c49bf5c9ceeedb0d86f6c06e1eb (patch)
tree2a2fbe70126535af9533cc7bca9fb6bf266baea7
parent92705574380f7ffd9f244b4cb69422a85269ab41 (diff)
set: support for NFTNL_SET_EXPR
This patch adds support for the NFTA_SET_EXPR netlink attribute. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--include/libnftnl/set.h1
-rw-r--r--include/libnftnl/udata.h1
-rw-r--r--include/linux/netfilter/nf_tables.h2
-rw-r--r--include/set.h1
-rw-r--r--src/set.c27
5 files changed, 32 insertions, 0 deletions
diff --git a/include/libnftnl/set.h b/include/libnftnl/set.h
index 6843adf..5138bb9 100644
--- a/include/libnftnl/set.h
+++ b/include/libnftnl/set.h
@@ -30,6 +30,7 @@ enum nftnl_set_attr {
NFTNL_SET_OBJ_TYPE,
NFTNL_SET_HANDLE,
NFTNL_SET_DESC_CONCAT,
+ NFTNL_SET_EXPR,
__NFTNL_SET_MAX
};
#define NFTNL_SET_MAX (__NFTNL_SET_MAX - 1)
diff --git a/include/libnftnl/udata.h b/include/libnftnl/udata.h
index 8044041..1d57bc3 100644
--- a/include/libnftnl/udata.h
+++ b/include/libnftnl/udata.h
@@ -24,6 +24,7 @@ enum nftnl_udata_set_types {
NFTNL_UDATA_SET_MERGE_ELEMENTS,
NFTNL_UDATA_SET_KEY_TYPEOF,
NFTNL_UDATA_SET_DATA_TYPEOF,
+ NFTNL_UDATA_SET_EXPR,
__NFTNL_UDATA_SET_MAX
};
#define NFTNL_UDATA_SET_MAX (__NFTNL_UDATA_SET_MAX - 1)
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 57e83e1..2d291f6 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -342,6 +342,7 @@ enum nft_set_field_attributes {
* @NFTA_SET_USERDATA: user data (NLA_BINARY)
* @NFTA_SET_OBJ_TYPE: stateful object type (NLA_U32: NFT_OBJECT_*)
* @NFTA_SET_HANDLE: set handle (NLA_U64)
+ * @NFTA_SET_EXPR: set expression (NLA_NESTED: nft_expr_attributes)
*/
enum nft_set_attributes {
NFTA_SET_UNSPEC,
@@ -361,6 +362,7 @@ enum nft_set_attributes {
NFTA_SET_PAD,
NFTA_SET_OBJ_TYPE,
NFTA_SET_HANDLE,
+ NFTA_SET_EXPR,
__NFTA_SET_MAX
};
#define NFTA_SET_MAX (__NFTA_SET_MAX - 1)
diff --git a/include/set.h b/include/set.h
index 895ffdb..66ac129 100644
--- a/include/set.h
+++ b/include/set.h
@@ -33,6 +33,7 @@ struct nftnl_set {
uint32_t flags;
uint32_t gc_interval;
uint64_t timeout;
+ struct nftnl_expr *expr;
};
struct nftnl_set_list;
diff --git a/src/set.c b/src/set.c
index 651dcfa..15fa29d 100644
--- a/src/set.c
+++ b/src/set.c
@@ -51,6 +51,8 @@ void nftnl_set_free(const struct nftnl_set *s)
xfree(s->name);
if (s->flags & (1 << NFTNL_SET_USERDATA))
xfree(s->user.data);
+ if (s->flags & (1 << NFTNL_SET_EXPR))
+ nftnl_expr_free(s->expr);
list_for_each_entry_safe(elem, tmp, &s->element_list, head) {
list_del(&elem->head);
@@ -96,6 +98,9 @@ void nftnl_set_unset(struct nftnl_set *s, uint16_t attr)
case NFTNL_SET_USERDATA:
xfree(s->user.data);
break;
+ case NFTNL_SET_EXPR:
+ nftnl_expr_free(s->expr);
+ break;
default:
return;
}
@@ -195,6 +200,12 @@ int nftnl_set_set_data(struct nftnl_set *s, uint16_t attr, const void *data,
memcpy(s->user.data, data, data_len);
s->user.len = data_len;
break;
+ case NFTNL_SET_EXPR:
+ if (s->flags & (1 << NFTNL_SET_EXPR))
+ nftnl_expr_free(s->expr);
+
+ s->expr = (void *)data;
+ break;
}
s->flags |= (1 << attr);
return 0;
@@ -283,6 +294,8 @@ const void *nftnl_set_get_data(const struct nftnl_set *s, uint16_t attr,
case NFTNL_SET_USERDATA:
*data_len = s->user.len;
return s->user.data;
+ case NFTNL_SET_EXPR:
+ return s->expr;
}
return NULL;
}
@@ -432,6 +445,13 @@ void nftnl_set_nlmsg_build_payload(struct nlmsghdr *nlh, struct nftnl_set *s)
mnl_attr_put_u32(nlh, NFTA_SET_GC_INTERVAL, htonl(s->gc_interval));
if (s->flags & (1 << NFTNL_SET_USERDATA))
mnl_attr_put(nlh, NFTA_SET_USERDATA, s->user.len, s->user.data);
+ if (s->flags & (1 << NFTNL_SET_EXPR)) {
+ struct nlattr *nest1;
+
+ nest1 = mnl_attr_nest_start(nlh, NFTA_SET_EXPR);
+ nftnl_expr_build_payload(nlh, s->expr);
+ mnl_attr_nest_end(nlh, nest1);
+ }
}
@@ -635,6 +655,13 @@ int nftnl_set_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_set *s)
if (ret < 0)
return ret;
}
+ if (tb[NFTA_SET_EXPR]) {
+ s->expr = nftnl_expr_parse(tb[NFTA_SET_EXPR]);
+ if (!s->expr)
+ return -1;
+
+ s->flags |= (1 << NFTNL_SET_EXPR);
+ }
s->family = nfg->nfgen_family;
s->flags |= (1 << NFTNL_SET_FAMILY);