netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH libnftnl 0/5] concatenation and dynamic expression instantiation
@ 2015-04-14  7:00 Patrick McHardy
  2015-04-14  7:00 ` [PATCH libnftnl 1/5] headers: resync headers for new register definitions Patrick McHardy
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Patrick McHardy @ 2015-04-14  7:00 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

These patches add support for the concatenation and dynamic expression
instantiation features to libnftnl.


Patrick McHardy (5):
  headers: resync headers for new register definitions
  data: increase maximum possible data size
  expr: seperate expression parsing and building functions
  set_elem: support expressions attached to set elements
  dynset: support expression templates

 include/data_reg.h                  |  3 +-
 include/expr.h                      |  6 ++++
 include/libnftnl/expr.h             |  5 +---
 include/libnftnl/set.h              |  1 +
 include/linux/netfilter/nf_tables.h | 41 +++++++++++++++++++++++++-
 include/set_elem.h                  |  1 +
 src/expr.c                          | 56 ++++++++++++++++++++++++++++++++----
 src/expr/data_reg.c                 |  2 +-
 src/expr/dynset.c                   | 38 +++++++++++++++++++++++++
 src/libnftnl.map                    |  1 -
 src/rule.c                          | 57 ++++++-------------------------------
 src/set_elem.c                      | 20 +++++++++++++
 12 files changed, 169 insertions(+), 62 deletions(-)

-- 
2.1.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH libnftnl 1/5] headers: resync headers for new register definitions
  2015-04-14  7:00 [PATCH libnftnl 0/5] concatenation and dynamic expression instantiation Patrick McHardy
@ 2015-04-14  7:00 ` Patrick McHardy
  2015-04-14  7:00 ` [PATCH libnftnl 2/5] data: increase maximum possible data size Patrick McHardy
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Patrick McHardy @ 2015-04-14  7:00 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

Signed-off-by: Patrick McHardy <kaber@trash.net>
---
 include/linux/netfilter/nf_tables.h | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 0e96443..4221a6c 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -1,19 +1,49 @@
 #ifndef _LINUX_NF_TABLES_H
 #define _LINUX_NF_TABLES_H
 
+#define NFT_TABLE_MAXNAMELEN	32
 #define NFT_CHAIN_MAXNAMELEN	32
 #define NFT_USERDATA_MAXLEN	256
 
+/**
+ * enum nft_registers - nf_tables registers
+ *
+ * nf_tables used to have five registers: a verdict register and four data
+ * registers of size 16. The data registers have been changed to 16 registers
+ * of size 4. For compatibility reasons, the NFT_REG_[1-4] registers still
+ * map to areas of size 16, the 4 byte registers are addressed using
+ * NFT_REG32_00 - NFT_REG32_15.
+ */
 enum nft_registers {
 	NFT_REG_VERDICT,
 	NFT_REG_1,
 	NFT_REG_2,
 	NFT_REG_3,
 	NFT_REG_4,
-	__NFT_REG_MAX
+	__NFT_REG_MAX,
+
+	NFT_REG32_00	= 8,
+	MFT_REG32_01,
+	NFT_REG32_02,
+	NFT_REG32_03,
+	NFT_REG32_04,
+	NFT_REG32_05,
+	NFT_REG32_06,
+	NFT_REG32_07,
+	NFT_REG32_08,
+	NFT_REG32_09,
+	NFT_REG32_10,
+	NFT_REG32_11,
+	NFT_REG32_12,
+	NFT_REG32_13,
+	NFT_REG32_14,
+	NFT_REG32_15,
 };
 #define NFT_REG_MAX	(__NFT_REG_MAX - 1)
 
+#define NFT_REG_SIZE	16
+#define NFT_REG32_SIZE	4
+
 /**
  * enum nft_verdicts - nf_tables internal verdicts
  *
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH libnftnl 2/5] data: increase maximum possible data size
  2015-04-14  7:00 [PATCH libnftnl 0/5] concatenation and dynamic expression instantiation Patrick McHardy
  2015-04-14  7:00 ` [PATCH libnftnl 1/5] headers: resync headers for new register definitions Patrick McHardy
@ 2015-04-14  7:00 ` Patrick McHardy
  2015-04-14  7:00 ` [PATCH libnftnl 3/5] expr: seperate expression parsing and building functions Patrick McHardy
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Patrick McHardy @ 2015-04-14  7:00 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

Signed-off-by: Patrick McHardy <kaber@trash.net>
---
 include/data_reg.h                  | 3 ++-
 include/linux/netfilter/nf_tables.h | 3 +++
 src/expr/data_reg.c                 | 2 +-
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/include/data_reg.h b/include/data_reg.h
index e7375b8..cf14988 100644
--- a/include/data_reg.h
+++ b/include/data_reg.h
@@ -1,6 +1,7 @@
 #ifndef _DATA_H_
 #define _DATA_H_
 
+#include <linux/netfilter/nf_tables.h>
 #include <stdint.h>
 #include <unistd.h>
 
@@ -13,7 +14,7 @@ enum {
 
 union nft_data_reg {
 	struct {
-		uint32_t	val[4];
+		uint32_t	val[NFT_DATA_VALUE_MAXLEN / sizeof(uint32_t)];
 		uint32_t	len;
 	};
 	struct {
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 4221a6c..be8584c 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -388,6 +388,9 @@ enum nft_data_attributes {
 };
 #define NFTA_DATA_MAX		(__NFTA_DATA_MAX - 1)
 
+/* Maximum length of a value */
+#define NFT_DATA_VALUE_MAXLEN	64
+
 /**
  * enum nft_verdict_attributes - nf_tables verdict netlink attributes
  *
diff --git a/src/expr/data_reg.c b/src/expr/data_reg.c
index b4e553e..b5fbdf2 100644
--- a/src/expr/data_reg.c
+++ b/src/expr/data_reg.c
@@ -467,7 +467,7 @@ __nft_parse_data(union nft_data_reg *data, const struct nlattr *attr)
 	if (data_len == 0)
 		return -1;
 
-	if (data_len > sizeof(uint32_t) * 4)
+	if (data_len > sizeof(data->val))
 		return -1;
 
 	memcpy(data->val, orig, data_len);
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH libnftnl 3/5] expr: seperate expression parsing and building functions
  2015-04-14  7:00 [PATCH libnftnl 0/5] concatenation and dynamic expression instantiation Patrick McHardy
  2015-04-14  7:00 ` [PATCH libnftnl 1/5] headers: resync headers for new register definitions Patrick McHardy
  2015-04-14  7:00 ` [PATCH libnftnl 2/5] data: increase maximum possible data size Patrick McHardy
@ 2015-04-14  7:00 ` Patrick McHardy
  2015-04-14  7:00 ` [PATCH libnftnl 4/5] set_elem: support expressions attached to set elements Patrick McHardy
  2015-04-14  7:00 ` [PATCH libnftnl 5/5] dynset: support expression templates Patrick McHardy
  4 siblings, 0 replies; 6+ messages in thread
From: Patrick McHardy @ 2015-04-14  7:00 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

The expression build function currently assumes to be only used from
rule context and actually builds rule attributes. Fix that and only
build the expression. Also it seems to have been exported by accident,
undo that.

Additionally, move the expression parsing function from rule parsing
and also remove any assumptions about being used in rule context.

Signed-off-by: Patrick McHardy <kaber@trash.net>
---
 include/expr.h          |  6 ++++++
 include/libnftnl/expr.h |  4 ----
 src/expr.c              | 56 ++++++++++++++++++++++++++++++++++++++++++------
 src/libnftnl.map        |  1 -
 src/rule.c              | 57 ++++++++-----------------------------------------
 5 files changed, 65 insertions(+), 59 deletions(-)

diff --git a/include/expr.h b/include/expr.h
index ed41105..a4333c6 100644
--- a/include/expr.h
+++ b/include/expr.h
@@ -10,4 +10,10 @@ struct nft_rule_expr {
 	uint8_t			data[];
 };
 
+struct nlmsghdr;
+
+void nft_rule_expr_build_payload(struct nlmsghdr *nlh, struct nft_rule_expr *expr);
+struct nft_rule_expr *nft_rule_expr_parse(struct nlattr *attr);
+
+
 #endif
diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index 7bc0273..14daa83 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -36,10 +36,6 @@ uint32_t nft_rule_expr_get_u32(const struct nft_rule_expr *expr, uint16_t type);
 uint64_t nft_rule_expr_get_u64(const struct nft_rule_expr *expr, uint16_t type);
 const char *nft_rule_expr_get_str(const struct nft_rule_expr *expr, uint16_t type);
 
-struct nlmsghdr;
-
-void nft_rule_expr_build_payload(struct nlmsghdr *nlh, struct nft_rule_expr *expr);
-
 int nft_rule_expr_snprintf(char *buf, size_t buflen, struct nft_rule_expr *expr, uint32_t type, uint32_t flags);
 
 enum {
diff --git a/src/expr.c b/src/expr.c
index 79782fa..4109495 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -15,6 +15,7 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
+#include <errno.h>
 #include <netinet/in.h>
 
 #include <libmnl/libmnl.h>
@@ -205,18 +206,61 @@ EXPORT_SYMBOL(nft_rule_expr_get_str);
 void
 nft_rule_expr_build_payload(struct nlmsghdr *nlh, struct nft_rule_expr *expr)
 {
-	struct nlattr *nest1, *nest2;
+	struct nlattr *nest;
 
-	nest1 = mnl_attr_nest_start(nlh, NFTA_LIST_ELEM);
 	mnl_attr_put_strz(nlh, NFTA_EXPR_NAME, expr->ops->name);
 
-	nest2 = mnl_attr_nest_start(nlh, NFTA_EXPR_DATA);
+	nest = mnl_attr_nest_start(nlh, NFTA_EXPR_DATA);
 	expr->ops->build(nlh, expr);
-	mnl_attr_nest_end(nlh, nest2);
+	mnl_attr_nest_end(nlh, nest);
+}
+
+static int nft_rule_parse_expr_cb(const struct nlattr *attr, void *data)
+{
+	const struct nlattr **tb = data;
+	int type = mnl_attr_get_type(attr);
+
+	if (mnl_attr_type_valid(attr, NFTA_EXPR_MAX) < 0)
+		return MNL_CB_OK;
+
+	switch (type) {
+	case NFTA_EXPR_NAME:
+		if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
+			abi_breakage();
+		break;
+	case NFTA_EXPR_DATA:
+		if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
+			abi_breakage();
+		break;
+	}
+
+	tb[type] = attr;
+	return MNL_CB_OK;
+}
 
-	mnl_attr_nest_end(nlh, nest1);
+struct nft_rule_expr *nft_rule_expr_parse(struct nlattr *attr)
+{
+	struct nlattr *tb[NFTA_EXPR_MAX+1] = {};
+	struct nft_rule_expr *expr;
+
+	if (mnl_attr_parse_nested(attr, nft_rule_parse_expr_cb, tb) < 0)
+		goto err1;
+
+	expr = nft_rule_expr_alloc(mnl_attr_get_str(tb[NFTA_EXPR_NAME]));
+	if (expr == NULL)
+		goto err1;
+
+	if (tb[NFTA_EXPR_DATA] &&
+	    expr->ops->parse(expr, tb[NFTA_EXPR_DATA]) < 0)
+		goto err2;
+
+	return expr;
+
+err2:
+	xfree(expr);
+err1:
+	return NULL;
 }
-EXPORT_SYMBOL(nft_rule_expr_build_payload);
 
 int nft_rule_expr_snprintf(char *buf, size_t size, struct nft_rule_expr *expr,
 			   uint32_t type, uint32_t flags)
diff --git a/src/libnftnl.map b/src/libnftnl.map
index 01eba13..c2b9431 100644
--- a/src/libnftnl.map
+++ b/src/libnftnl.map
@@ -102,7 +102,6 @@ global:
   nft_rule_expr_get_u32;
   nft_rule_expr_get_u64;
   nft_rule_expr_get_str;
-  nft_rule_expr_build_payload;
   nft_rule_expr_snprintf;
   nft_rule_expr_free;
 
diff --git a/src/rule.c b/src/rule.c
index 3feb337..04088ed 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -277,7 +277,7 @@ EXPORT_SYMBOL(nft_rule_attr_get_u8);
 void nft_rule_nlmsg_build_payload(struct nlmsghdr *nlh, struct nft_rule *r)
 {
 	struct nft_rule_expr *expr;
-	struct nlattr *nest;
+	struct nlattr *nest, *nest2;
 
 	if (r->flags & (1 << NFT_RULE_ATTR_TABLE))
 		mnl_attr_put_strz(nlh, NFTA_RULE_TABLE, r->table);
@@ -295,7 +295,9 @@ void nft_rule_nlmsg_build_payload(struct nlmsghdr *nlh, struct nft_rule *r)
 	if (!list_empty(&r->expr_list)) {
 		nest = mnl_attr_nest_start(nlh, NFTA_RULE_EXPRESSIONS);
 		list_for_each_entry(expr, &r->expr_list, head) {
+			nest2 = mnl_attr_nest_start(nlh, NFTA_LIST_ELEM);
 			nft_rule_expr_build_payload(nlh, expr);
+			mnl_attr_nest_end(nlh, nest2);
 		}
 		mnl_attr_nest_end(nlh, nest);
 	}
@@ -355,61 +357,20 @@ static int nft_rule_parse_attr_cb(const struct nlattr *attr, void *data)
 	return MNL_CB_OK;
 }
 
-static int nft_rule_parse_expr_cb(const struct nlattr *attr, void *data)
-{
-	const struct nlattr **tb = data;
-	int type = mnl_attr_get_type(attr);
-
-	if (mnl_attr_type_valid(attr, NFTA_EXPR_MAX) < 0)
-		return MNL_CB_OK;
-
-	switch(type) {
-	case NFTA_EXPR_NAME:
-		if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
-			abi_breakage();
-		break;
-	case NFTA_EXPR_DATA:
-		if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
-			abi_breakage();
-		break;
-	}
-
-	tb[type] = attr;
-	return MNL_CB_OK;
-}
-
-static int nft_rule_parse_expr2(struct nlattr *attr, struct nft_rule *r)
-{
-	struct nlattr *tb[NFTA_EXPR_MAX+1] = {};
-	struct nft_rule_expr *expr;
-
-	if (mnl_attr_parse_nested(attr, nft_rule_parse_expr_cb, tb) < 0)
-		return -1;
-
-	expr = nft_rule_expr_alloc(mnl_attr_get_str(tb[NFTA_EXPR_NAME]));
-	if (expr == NULL)
-		return -1;
-
-	if (tb[NFTA_EXPR_DATA]) {
-		if (expr->ops->parse(expr, tb[NFTA_EXPR_DATA]) < 0) {
-			xfree(expr);
-			return -1;
-		}
-	}
-	list_add_tail(&expr->head, &r->expr_list);
-
-	return 0;
-}
-
 static int nft_rule_parse_expr(struct nlattr *nest, struct nft_rule *r)
 {
+	struct nft_rule_expr *expr;
 	struct nlattr *attr;
 
 	mnl_attr_for_each_nested(attr, nest) {
 		if (mnl_attr_get_type(attr) != NFTA_LIST_ELEM)
 			return -1;
 
-		nft_rule_parse_expr2(attr, r);
+		expr = nft_rule_expr_parse(attr);
+		if (expr == NULL)
+			return -1;
+
+		list_add_tail(&expr->head, &r->expr_list);
 	}
 	return 0;
 }
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH libnftnl 4/5] set_elem: support expressions attached to set elements
  2015-04-14  7:00 [PATCH libnftnl 0/5] concatenation and dynamic expression instantiation Patrick McHardy
                   ` (2 preceding siblings ...)
  2015-04-14  7:00 ` [PATCH libnftnl 3/5] expr: seperate expression parsing and building functions Patrick McHardy
@ 2015-04-14  7:00 ` Patrick McHardy
  2015-04-14  7:00 ` [PATCH libnftnl 5/5] dynset: support expression templates Patrick McHardy
  4 siblings, 0 replies; 6+ messages in thread
From: Patrick McHardy @ 2015-04-14  7:00 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

This patch supports attaching a struct nft_rule_expr to a set element
and adds netlink attribute encoding and decoding.

Signed-off-by: Patrick McHardy <kaber@trash.net>
---
 include/libnftnl/set.h              |  1 +
 include/linux/netfilter/nf_tables.h |  2 ++
 include/set_elem.h                  |  1 +
 src/set_elem.c                      | 20 ++++++++++++++++++++
 4 files changed, 24 insertions(+)

diff --git a/include/libnftnl/set.h b/include/libnftnl/set.h
index 9621853..4efc7d4 100644
--- a/include/libnftnl/set.h
+++ b/include/libnftnl/set.h
@@ -93,6 +93,7 @@ enum {
 	NFT_SET_ELEM_ATTR_TIMEOUT,
 	NFT_SET_ELEM_ATTR_EXPIRATION,
 	NFT_SET_ELEM_ATTR_USERDATA,
+	NFT_SET_ELEM_ATTR_EXPR,
 };
 
 struct nft_set_elem;
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index be8584c..f9c5af2 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -322,6 +322,7 @@ enum nft_set_elem_flags {
  * @NFTA_SET_ELEM_TIMEOUT: timeout value (NLA_U64)
  * @NFTA_SET_ELEM_EXPIRATION: expiration time (NLA_U64)
  * @NFTA_SET_ELEM_USERDATA: user data (NLA_BINARY)
+ * @NFTA_SET_ELEM_EXPR: expression (NLA_NESTED: nft_expr_attributes)
  */
 enum nft_set_elem_attributes {
 	NFTA_SET_ELEM_UNSPEC,
@@ -331,6 +332,7 @@ enum nft_set_elem_attributes {
 	NFTA_SET_ELEM_TIMEOUT,
 	NFTA_SET_ELEM_EXPIRATION,
 	NFTA_SET_ELEM_USERDATA,
+	NFTA_SET_ELEM_EXPR,
 	__NFTA_SET_ELEM_MAX
 };
 #define NFTA_SET_ELEM_MAX	(__NFTA_SET_ELEM_MAX - 1)
diff --git a/include/set_elem.h b/include/set_elem.h
index 5aaad20..bdefe4b 100644
--- a/include/set_elem.h
+++ b/include/set_elem.h
@@ -8,6 +8,7 @@ struct nft_set_elem {
 	uint32_t		set_elem_flags;
 	union nft_data_reg	key;
 	union nft_data_reg	data;
+	struct nft_rule_expr	*expr;
 	uint32_t		flags;
 	uint64_t		timeout;
 	uint64_t		expiration;
diff --git a/src/set_elem.c b/src/set_elem.c
index 2cf6528..3a799dc 100644
--- a/src/set_elem.c
+++ b/src/set_elem.c
@@ -25,6 +25,7 @@
 
 #include <libnftnl/set.h>
 #include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
 
 struct nft_set_elem *nft_set_elem_alloc(void)
 {
@@ -46,6 +47,10 @@ void nft_set_elem_free(struct nft_set_elem *s)
 			s->data.chain = NULL;
 		}
 	}
+
+	if (s->flags & (1 << NFT_SET_ELEM_ATTR_EXPR))
+		nft_rule_expr_free(s->expr);
+
 	xfree(s);
 }
 EXPORT_SYMBOL(nft_set_elem_free);
@@ -75,6 +80,12 @@ void nft_set_elem_attr_unset(struct nft_set_elem *s, uint16_t attr)
 	case NFT_SET_ELEM_ATTR_EXPIRATION:	/* NFTA_SET_ELEM_EXPIRATION */
 	case NFT_SET_ELEM_ATTR_USERDATA:	/* NFTA_SET_ELEM_USERDATA */
 		break;
+	case NFT_SET_ELEM_ATTR_EXPR:
+		if (s->flags & (1 << NFT_SET_ELEM_ATTR_EXPR)) {
+			nft_rule_expr_free(s->expr);
+			s->expr = NULL;
+		}
+		break;
 	default:
 		return;
 	}
@@ -164,6 +175,8 @@ const void *nft_set_elem_attr_get(struct nft_set_elem *s, uint16_t attr, uint32_
 	case NFT_SET_ELEM_ATTR_USERDATA:
 		*data_len = s->user.len;
 		return s->user.data;
+	case NFT_SET_ELEM_ATTR_EXPR:
+		return s->expr;
 	}
 	return NULL;
 }
@@ -305,6 +318,7 @@ static int nft_set_elem_parse_attr_cb(const struct nlattr *attr, void *data)
 		break;
 	case NFTA_SET_ELEM_KEY:
 	case NFTA_SET_ELEM_DATA:
+	case NFTA_SET_ELEM_EXPR:
 		if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
 			abi_breakage();
 		break;
@@ -365,6 +379,12 @@ static int nft_set_elems_parse2(struct nft_set *s, const struct nlattr *nest)
 			break;
 		}
         }
+	if (tb[NFTA_SET_ELEM_EXPR]) {
+		e->expr = nft_rule_expr_parse(tb[NFTA_SET_ELEM_EXPR]);
+		if (e->expr == NULL)
+			goto err;
+		e->flags |= (1 << NFT_SET_ELEM_ATTR_EXPR);
+	}
 	if (tb[NFTA_SET_ELEM_USERDATA]) {
 		const void *udata =
 			mnl_attr_get_payload(tb[NFTA_SET_ELEM_USERDATA]);
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH libnftnl 5/5] dynset: support expression templates
  2015-04-14  7:00 [PATCH libnftnl 0/5] concatenation and dynamic expression instantiation Patrick McHardy
                   ` (3 preceding siblings ...)
  2015-04-14  7:00 ` [PATCH libnftnl 4/5] set_elem: support expressions attached to set elements Patrick McHardy
@ 2015-04-14  7:00 ` Patrick McHardy
  4 siblings, 0 replies; 6+ messages in thread
From: Patrick McHardy @ 2015-04-14  7:00 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

Support expression templates for the dynset expression for dynamic
expression instantiation.

Signed-off-by: Patrick McHardy <kaber@trash.net>
---
 include/libnftnl/expr.h             |  1 +
 include/linux/netfilter/nf_tables.h |  4 ++++
 src/expr/dynset.c                   | 38 +++++++++++++++++++++++++++++++++++++
 3 files changed, 43 insertions(+)

diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index 14daa83..59ae2d7 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -113,6 +113,7 @@ enum {
 	NFT_EXPR_DYNSET_TIMEOUT,
 	NFT_EXPR_DYNSET_SET_NAME,
 	NFT_EXPR_DYNSET_SET_ID,
+	NFT_EXPR_DYNSET_EXPR,
 };
 
 enum {
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index f9c5af2..5fa1cd0 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -238,6 +238,7 @@ enum nft_rule_compat_attributes {
  * @NFT_SET_INTERVAL: set contains intervals
  * @NFT_SET_MAP: set is used as a dictionary
  * @NFT_SET_TIMEOUT: set uses timeouts
+ * @NFT_SET_EVAL: set contains expressions for evaluation
  */
 enum nft_set_flags {
 	NFT_SET_ANONYMOUS		= 0x1,
@@ -245,6 +246,7 @@ enum nft_set_flags {
 	NFT_SET_INTERVAL		= 0x4,
 	NFT_SET_MAP			= 0x8,
 	NFT_SET_TIMEOUT			= 0x10,
+	NFT_SET_EVAL			= 0x20,
 };
 
 /**
@@ -565,6 +567,7 @@ enum nft_dynset_ops {
  * @NFTA_DYNSET_SREG_KEY: source register of the key (NLA_U32)
  * @NFTA_DYNSET_SREG_DATA: source register of the data (NLA_U32)
  * @NFTA_DYNSET_TIMEOUT: timeout value for the new element (NLA_U64)
+ * @NFTA_DYNSET_EXPR: expression (NLA_NESTED: nft_expr_attributes)
  */
 enum nft_dynset_attributes {
 	NFTA_DYNSET_UNSPEC,
@@ -574,6 +577,7 @@ enum nft_dynset_attributes {
 	NFTA_DYNSET_SREG_KEY,
 	NFTA_DYNSET_SREG_DATA,
 	NFTA_DYNSET_TIMEOUT,
+	NFTA_DYNSET_EXPR,
 	__NFTA_DYNSET_MAX,
 };
 #define NFTA_DYNSET_MAX		(__NFTA_DYNSET_MAX - 1)
diff --git a/src/expr/dynset.c b/src/expr/dynset.c
index 034ef32..e3fecf5 100644
--- a/src/expr/dynset.c
+++ b/src/expr/dynset.c
@@ -31,6 +31,7 @@ struct nft_expr_dynset {
 	enum nft_registers	sreg_data;
 	enum nft_dynset_ops	op;
 	uint64_t		timeout;
+	struct nft_rule_expr	*expr;
 	char			set_name[IFNAMSIZ];
 	uint32_t		set_id;
 };
@@ -61,6 +62,9 @@ nft_rule_expr_dynset_set(struct nft_rule_expr *e, uint16_t type,
 	case NFT_EXPR_DYNSET_SET_ID:
 		dynset->set_id = *((uint32_t *)data);
 		break;
+	case NFT_EXPR_DYNSET_EXPR:
+		dynset->expr = (void *)data;
+		break;
 	default:
 		return -1;
 	}
@@ -90,6 +94,8 @@ nft_rule_expr_dynset_get(const struct nft_rule_expr *e, uint16_t type,
 		return dynset->set_name;
 	case NFT_EXPR_DYNSET_SET_ID:
 		return &dynset->set_id;
+	case NFT_EXPR_DYNSET_EXPR:
+		return dynset->expr;
 	}
 	return NULL;
 }
@@ -118,6 +124,10 @@ static int nft_rule_expr_dynset_cb(const struct nlattr *attr, void *data)
 		if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
 			abi_breakage();
 		break;
+	case NFTA_DYNSET_EXPR:
+		if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
+			abi_breakage();
+		break;
 	}
 
 	tb[type] = attr;
@@ -128,6 +138,7 @@ static void
 nft_rule_expr_dynset_build(struct nlmsghdr *nlh, struct nft_rule_expr *e)
 {
 	struct nft_expr_dynset *dynset = nft_expr_data(e);
+	struct nlattr *nest;
 
 	if (e->flags & (1 << NFT_EXPR_DYNSET_SREG_KEY))
 		mnl_attr_put_u32(nlh, NFTA_DYNSET_SREG_KEY, htonl(dynset->sreg_key));
@@ -141,6 +152,11 @@ nft_rule_expr_dynset_build(struct nlmsghdr *nlh, struct nft_rule_expr *e)
 		mnl_attr_put_strz(nlh, NFTA_DYNSET_SET_NAME, dynset->set_name);
 	if (e->flags & (1 << NFT_EXPR_DYNSET_SET_ID))
 		mnl_attr_put_u32(nlh, NFTA_DYNSET_SET_ID, htonl(dynset->set_id));
+	if (e->flags & (1 << NFT_EXPR_DYNSET_EXPR)) {
+		nest = mnl_attr_nest_start(nlh, NFTA_DYNSET_EXPR);
+		nft_rule_expr_build_payload(nlh, dynset->expr);
+		mnl_attr_nest_end(nlh, nest);
+	}
 }
 
 static int
@@ -177,6 +193,12 @@ nft_rule_expr_dynset_parse(struct nft_rule_expr *e, struct nlattr *attr)
 		dynset->set_id = ntohl(mnl_attr_get_u32(tb[NFTA_DYNSET_SET_ID]));
 		e->flags |= (1 << NFT_EXPR_DYNSET_SET_ID);
 	}
+	if (tb[NFTA_DYNSET_EXPR]) {
+		e->flags |= (1 << NFT_EXPR_DYNSET_EXPR);
+		dynset->expr = nft_rule_expr_parse(tb[NFTA_DYNSET_EXPR]);
+		if (dynset->expr == NULL)
+			return -1;
+	}
 
 	return ret;
 }
@@ -288,6 +310,7 @@ nft_rule_expr_dynset_snprintf_default(char *buf, size_t size,
 				      struct nft_rule_expr *e)
 {
 	struct nft_expr_dynset *dynset = nft_expr_data(e);
+	struct nft_rule_expr *expr;
 	int len = size, offset = 0, ret;
 
 	ret = snprintf(buf, len, "%s reg_key %u set %s ",
@@ -303,6 +326,21 @@ nft_rule_expr_dynset_snprintf_default(char *buf, size_t size,
 			       dynset->timeout);
 		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 	}
+	if (e->flags & (1 << NFT_EXPR_DYNSET_EXPR)) {
+		expr = dynset->expr;
+		ret = snprintf(buf+offset, len, "expr [ %s ",
+			       expr->ops->name);
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+		ret = nft_rule_expr_snprintf(buf+offset, len, expr,
+					     NFT_OUTPUT_DEFAULT,
+					     NFT_OF_EVENT_ANY);
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+		ret = snprintf(buf+offset, len, "] ");
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+	}
+
 	return offset;
 }
 
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2015-04-14  7:00 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-04-14  7:00 [PATCH libnftnl 0/5] concatenation and dynamic expression instantiation Patrick McHardy
2015-04-14  7:00 ` [PATCH libnftnl 1/5] headers: resync headers for new register definitions Patrick McHardy
2015-04-14  7:00 ` [PATCH libnftnl 2/5] data: increase maximum possible data size Patrick McHardy
2015-04-14  7:00 ` [PATCH libnftnl 3/5] expr: seperate expression parsing and building functions Patrick McHardy
2015-04-14  7:00 ` [PATCH libnftnl 4/5] set_elem: support expressions attached to set elements Patrick McHardy
2015-04-14  7:00 ` [PATCH libnftnl 5/5] dynset: support expression templates Patrick McHardy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).