netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] libnftnl updates
@ 2014-02-26  1:51 Pablo Neira Ayuso
  2014-02-26  1:51 ` [PATCH 1/7] src: early attribute type validation in nft_*_attr_set Pablo Neira Ayuso
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Pablo Neira Ayuso @ 2014-02-26  1:51 UTC (permalink / raw)
  To: netfilter-devel; +Cc: kaber

This batch contains updates for libnftnl:

* add implicit bugtrap for undefined set operations. Gcc will spot a
  compilation warning if attribute is not defined in the switch in
  nft_*_attr_set.

* add assertion infrastructure to validate attribute size.

* Add nft_*_attr_{set|get}_data to allow setting data of variable length.
  This includes validation of the attribute size. This new interface
  supersedes nft_*_attr_{set|get}. It is required by the per-rule
  userdata infrastructure.

* Fix wrong family attribute type uncovered by the validation added +
  existing test infrastructure.

* Get in sync with current linux kernel header (as of 3.14-rc).

* Simplify the overly complicated nft-rule-add example. This should help
  to merge the nft-rule-insert example into nft-rule-add.

* add support for NFT_RULE_ATTR_USERDATA, which allows nft to attach
  human-readable comments.

Pablo Neira Ayuso (7):
  src: early attribute type validation in nft_*_attr_set
  src: add assertion infrastructure to validate attribute types
  src: add nft_*_attr_{set|get}_data interface
  src: fix wrong type in NFT_ATTR_*_FAMILY
  include: get linux/netfilter/nf_tables.h in sync with kernel header
  example: nft-rule-add: simplify example
  rule: add NFT_RULE_ATTR_USERDATA support

 Make_global.am			     |	  2 +-
 examples/nft-rule-add.c	     |	 86 ++++++++----------------
 include/libnftnl/chain.h	     |	  6 ++
 include/libnftnl/expr.h	     |	  2 +
 include/libnftnl/rule.h	     |	  7 ++
 include/libnftnl/set.h		     |	  6 ++
 include/libnftnl/table.h	     |	  6 ++
 include/linux/netfilter/nf_tables.h |	  8 ++-
 src/chain.c			     |	 83 ++++++++++++++++++-----
 src/internal.h			     |	 13 ++++
 src/libnftnl.map		     |	 11 +++
 src/rule.c			     |	125 +++++++++++++++++++++++++++++++----
 src/set.c			     |	 47 +++++++++++--
 src/table.c			     |	 50 ++++++++++----
 src/utils.c			     |	  7 ++
 tests/nft-chain-test.c		     |	  6 +-
 tests/nft-expr_ct-test.c	     |	  6 +-
 tests/nft-expr_exthdr-test.c	     |	  6 +-
 tests/nft-expr_meta-test.c	     |	  4 +-
 tests/nft-table-test.c		     |	  6 +-
 20 files changed, 368 insertions(+), 119 deletions(-)

--
1.7.10.4


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

* [PATCH 1/7] src: early attribute type validation in nft_*_attr_set
  2014-02-26  1:51 [PATCH 0/7] libnftnl updates Pablo Neira Ayuso
@ 2014-02-26  1:51 ` Pablo Neira Ayuso
  2014-02-26  1:51 ` [PATCH 2/7] src: add assertion infrastructure to validate attribute types Pablo Neira Ayuso
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Pablo Neira Ayuso @ 2014-02-26  1:51 UTC (permalink / raw)
  To: netfilter-devel; +Cc: kaber

This allows us to remove the default case in the switch, which
show help to spot missing attribute support since gcc will spot
a compilation warning.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/libnftnl/chain.h |    2 ++
 include/libnftnl/rule.h  |    2 ++
 include/libnftnl/set.h   |    2 ++
 include/libnftnl/table.h |    2 ++
 src/chain.c              |    5 +++--
 src/rule.c               |    5 +++--
 src/set.c                |    5 +++--
 src/table.c              |   11 ++++++-----
 8 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/include/libnftnl/chain.h b/include/libnftnl/chain.h
index 66626d8..27de302 100644
--- a/include/libnftnl/chain.h
+++ b/include/libnftnl/chain.h
@@ -29,7 +29,9 @@ enum {
 	NFT_CHAIN_ATTR_PACKETS	= 8,
 	NFT_CHAIN_ATTR_HANDLE,
 	NFT_CHAIN_ATTR_TYPE,
+	__NFT_CHAIN_ATTR_MAX
 };
+#define NFT_CHAIN_ATTR_MAX (__NFT_CHAIN_ATTR_MAX - 1)
 
 bool nft_chain_attr_is_set(const struct nft_chain *c, uint16_t attr);
 void nft_chain_attr_unset(struct nft_chain *c, uint16_t attr);
diff --git a/include/libnftnl/rule.h b/include/libnftnl/rule.h
index 4033d3c..13e6c14 100644
--- a/include/libnftnl/rule.h
+++ b/include/libnftnl/rule.h
@@ -26,7 +26,9 @@ enum {
 	NFT_RULE_ATTR_COMPAT_PROTO,
 	NFT_RULE_ATTR_COMPAT_FLAGS,
 	NFT_RULE_ATTR_POSITION,
+	__NFT_RULE_ATTR_MAX
 };
+#define NFT_RULE_ATTR_MAX (__NFT_RULE_ATTR_MAX - 1)
 
 void nft_rule_attr_unset(struct nft_rule *r, uint16_t attr);
 bool nft_rule_attr_is_set(const struct nft_rule *r, uint16_t attr);
diff --git a/include/libnftnl/set.h b/include/libnftnl/set.h
index 7fa9fb2..ba11315 100644
--- a/include/libnftnl/set.h
+++ b/include/libnftnl/set.h
@@ -17,7 +17,9 @@ enum {
 	NFT_SET_ATTR_DATA_TYPE,
 	NFT_SET_ATTR_DATA_LEN,
 	NFT_SET_ATTR_FAMILY,
+	__NFT_SET_ATTR_MAX
 };
+#define NFT_SET_ATTR_MAX (__NFT_SET_ATTR_MAX - 1)
 
 struct nft_set;
 
diff --git a/include/libnftnl/table.h b/include/libnftnl/table.h
index 56e7e35..96f2668 100644
--- a/include/libnftnl/table.h
+++ b/include/libnftnl/table.h
@@ -22,7 +22,9 @@ enum {
 	NFT_TABLE_ATTR_FAMILY,
 	NFT_TABLE_ATTR_FLAGS,
 	NFT_TABLE_ATTR_USE,
+	__NFT_TABLE_ATTR_MAX
 };
+#define NFT_TABLE_ATTR_MAX (__NFT_TABLE_ATTR_MAX - 1)
 
 bool nft_table_attr_is_set(const struct nft_table *t, uint16_t attr);
 void nft_table_attr_unset(struct nft_table *t, uint16_t attr);
diff --git a/src/chain.c b/src/chain.c
index 34eb91d..19e7950 100644
--- a/src/chain.c
+++ b/src/chain.c
@@ -142,6 +142,9 @@ EXPORT_SYMBOL(nft_chain_attr_unset);
 
 void nft_chain_attr_set(struct nft_chain *c, uint16_t attr, const void *data)
 {
+	if (attr > NFT_CHAIN_ATTR_MAX)
+		return;
+
 	switch(attr) {
 	case NFT_CHAIN_ATTR_NAME:
 		strncpy(c->name, data, NFT_CHAIN_MAXNAMELEN);
@@ -182,8 +185,6 @@ void nft_chain_attr_set(struct nft_chain *c, uint16_t attr, const void *data)
 
 		c->type = strdup(data);
 		break;
-	default:
-		return;
 	}
 	c->flags |= (1 << attr);
 }
diff --git a/src/rule.c b/src/rule.c
index 53d2ebf..5e149c7 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -115,6 +115,9 @@ EXPORT_SYMBOL(nft_rule_attr_unset);
 
 void nft_rule_attr_set(struct nft_rule *r, uint16_t attr, const void *data)
 {
+	if (attr > NFT_RULE_ATTR_MAX)
+		return;
+
 	switch(attr) {
 	case NFT_RULE_ATTR_TABLE:
 		if (r->table)
@@ -143,8 +146,6 @@ void nft_rule_attr_set(struct nft_rule *r, uint16_t attr, const void *data)
 	case NFT_RULE_ATTR_POSITION:
 		r->position = *((uint64_t *)data);
 		break;
-	default:
-		return;
 	}
 	r->flags |= (1 << attr);
 }
diff --git a/src/set.c b/src/set.c
index c3a7fae..c8b5ccf 100644
--- a/src/set.c
+++ b/src/set.c
@@ -98,6 +98,9 @@ EXPORT_SYMBOL(nft_set_attr_unset);
 
 void nft_set_attr_set(struct nft_set *s, uint16_t attr, const void *data)
 {
+	if (attr > NFT_SET_ATTR_MAX)
+		return;
+
 	switch(attr) {
 	case NFT_SET_ATTR_TABLE:
 		if (s->table)
@@ -129,8 +132,6 @@ void nft_set_attr_set(struct nft_set *s, uint16_t attr, const void *data)
 	case NFT_SET_ATTR_FAMILY:
 		s->family = *((uint32_t *)data);
 		break;
-	default:
-		return;
 	}
 	s->flags |= (1 << attr);
 }
diff --git a/src/table.c b/src/table.c
index c834a4e..af4b13c 100644
--- a/src/table.c
+++ b/src/table.c
@@ -81,26 +81,27 @@ EXPORT_SYMBOL(nft_table_attr_unset);
 
 void nft_table_attr_set(struct nft_table *t, uint16_t attr, const void *data)
 {
+	if (attr > NFT_TABLE_ATTR_MAX)
+		return;
+
 	switch (attr) {
 	case NFT_TABLE_ATTR_NAME:
 		if (t->name)
 			xfree(t->name);
 
 		t->name = strdup(data);
-		t->flags |= (1 << NFT_TABLE_ATTR_NAME);
 		break;
 	case NFT_TABLE_ATTR_FLAGS:
 		t->table_flags = *((uint32_t *)data);
-		t->flags |= (1 << NFT_TABLE_ATTR_FLAGS);
 		break;
 	case NFT_TABLE_ATTR_FAMILY:
 		t->family = *((uint8_t *)data);
-		t->flags |= (1 << NFT_TABLE_ATTR_FAMILY);
 		break;
 	case NFT_TABLE_ATTR_USE:
-		/* Cannot be unset, ignoring it */
-		break;
+		/* Cannot be set, ignoring it */
+		return;
 	}
+	t->flags |= (1 << attr);
 }
 EXPORT_SYMBOL(nft_table_attr_set);
 
-- 
1.7.10.4


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

* [PATCH 2/7] src: add assertion infrastructure to validate attribute types
  2014-02-26  1:51 [PATCH 0/7] libnftnl updates Pablo Neira Ayuso
  2014-02-26  1:51 ` [PATCH 1/7] src: early attribute type validation in nft_*_attr_set Pablo Neira Ayuso
@ 2014-02-26  1:51 ` Pablo Neira Ayuso
  2014-02-26  1:51 ` [PATCH 3/7] src: add nft_*_attr_{set|get}_data interface Pablo Neira Ayuso
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Pablo Neira Ayuso @ 2014-02-26  1:51 UTC (permalink / raw)
  To: netfilter-devel; +Cc: kaber

This will be used to validate that the size is correct according
to the expected attribute size.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/internal.h |   13 +++++++++++++
 src/utils.c    |    7 +++++++
 2 files changed, 20 insertions(+)

diff --git a/src/internal.h b/src/internal.h
index a3fc46f..3216bc6 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -187,4 +187,17 @@ struct nft_set_elem {
 
 #define __init __attribute__((constructor))
 
+void __nft_assert_fail(uint16_t attr, const char *filename, int line);
+
+#define nft_assert(attr, expr)				\
+  ((expr)						\
+   ? (void)0						\
+   : __nft_assert_fail(attr, __FILE__, __LINE__))
+
+#define nft_assert_validate(_validate_array, _attr, _data_len)		\
+({									\
+	if (_validate_array[_attr])					\
+		nft_assert(attr, _validate_array[_attr] == _data_len);	\
+})
+
 #endif
diff --git a/src/utils.c b/src/utils.c
index 9691c4c..18917f5 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -211,3 +211,10 @@ int nft_fprintf(FILE *fp, void *obj, uint32_t type, uint32_t flags,
 
 	return ret;
 }
+
+void __nft_assert_fail(uint16_t attr, const char *filename, int line)
+{
+	fprintf(stderr, "libnftnl: attribute %d assertion failed in %s:%d\n",
+		attr, filename, line);
+	exit(EXIT_FAILURE);
+}
-- 
1.7.10.4


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

* [PATCH 3/7] src: add nft_*_attr_{set|get}_data interface
  2014-02-26  1:51 [PATCH 0/7] libnftnl updates Pablo Neira Ayuso
  2014-02-26  1:51 ` [PATCH 1/7] src: early attribute type validation in nft_*_attr_set Pablo Neira Ayuso
  2014-02-26  1:51 ` [PATCH 2/7] src: add assertion infrastructure to validate attribute types Pablo Neira Ayuso
@ 2014-02-26  1:51 ` Pablo Neira Ayuso
  2014-02-26  1:51 ` [PATCH 4/7] src: fix wrong type in NFT_ATTR_*_FAMILY Pablo Neira Ayuso
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Pablo Neira Ayuso @ 2014-02-26  1:51 UTC (permalink / raw)
  To: netfilter-devel; +Cc: kaber

This patch adds two functions that allows you to validate the size
of the attribute. This new functions provide a replacement for
nft_rule_attr_set and nft_rule_attr_get.

The data_len parameter was already passed to the {_set|_get} funcion
in expressions. For consistency, add nft_rule_expr_{set|get}_data
alias.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 Make_global.am           |    2 +-
 include/libnftnl/chain.h |    4 +++
 include/libnftnl/expr.h  |    2 ++
 include/libnftnl/rule.h  |    4 +++
 include/libnftnl/set.h   |    4 +++
 include/libnftnl/table.h |    4 +++
 src/chain.c              |   74 +++++++++++++++++++++++++++++++++++++++-------
 src/libnftnl.map         |   11 +++++++
 src/rule.c               |   58 +++++++++++++++++++++++++++++++-----
 src/set.c                |   42 ++++++++++++++++++++++++--
 src/table.c              |   35 ++++++++++++++++++----
 11 files changed, 212 insertions(+), 28 deletions(-)

diff --git a/Make_global.am b/Make_global.am
index 8205938..5bbcf9c 100644
--- a/Make_global.am
+++ b/Make_global.am
@@ -18,7 +18,7 @@
 # set age to 0.
 # </snippet>
 #
-LIBVERSION=0:0:0
+LIBVERSION=1:0:1
 
 AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_srcdir}/include ${LIBMNL_CFLAGS} ${LIBMXML_CFLAGS}
 AM_CFLAGS = ${regular_CFLAGS} ${GCC_FVISIBILITY_HIDDEN}
diff --git a/include/libnftnl/chain.h b/include/libnftnl/chain.h
index 27de302..c11cb5e 100644
--- a/include/libnftnl/chain.h
+++ b/include/libnftnl/chain.h
@@ -36,6 +36,8 @@ enum {
 bool nft_chain_attr_is_set(const struct nft_chain *c, uint16_t attr);
 void nft_chain_attr_unset(struct nft_chain *c, uint16_t attr);
 void nft_chain_attr_set(struct nft_chain *t, uint16_t attr, const void *data);
+void nft_chain_attr_set_data(struct nft_chain *t, uint16_t attr,
+			     const void *data, uint32_t data_len);
 void nft_chain_attr_set_u8(struct nft_chain *t, uint16_t attr, uint8_t data);
 void nft_chain_attr_set_u32(struct nft_chain *t, uint16_t attr, uint32_t data);
 void nft_chain_attr_set_s32(struct nft_chain *t, uint16_t attr, int32_t data);
@@ -43,6 +45,8 @@ void nft_chain_attr_set_u64(struct nft_chain *t, uint16_t attr, uint64_t data);
 void nft_chain_attr_set_str(struct nft_chain *t, uint16_t attr, const char *str);
 
 const void *nft_chain_attr_get(struct nft_chain *c, uint16_t attr);
+const void *nft_chain_attr_get_data(struct nft_chain *c, uint16_t attr,
+				    uint32_t *data_len);
 const char *nft_chain_attr_get_str(struct nft_chain *c, uint16_t attr);
 uint8_t nft_chain_attr_get_u8(struct nft_chain *c, uint16_t attr);
 uint32_t nft_chain_attr_get_u32(struct nft_chain *c, uint16_t attr);
diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index 6ec05a6..2cfb4dc 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -21,6 +21,7 @@ void nft_rule_expr_free(struct nft_rule_expr *expr);
 
 bool nft_rule_expr_is_set(const struct nft_rule_expr *expr, uint16_t type);
 void nft_rule_expr_set(struct nft_rule_expr *expr, uint16_t type, const void *data, uint32_t data_len);
+#define nft_rule_expr_set_data nft_rule_expr_set
 void nft_rule_expr_set_u8(struct nft_rule_expr *expr, uint16_t type, uint8_t data);
 void nft_rule_expr_set_u16(struct nft_rule_expr *expr, uint16_t type, uint16_t data);
 void nft_rule_expr_set_u32(struct nft_rule_expr *expr, uint16_t type, uint32_t data);
@@ -28,6 +29,7 @@ void nft_rule_expr_set_u64(struct nft_rule_expr *expr, uint16_t type, uint64_t d
 void nft_rule_expr_set_str(struct nft_rule_expr *expr, uint16_t type, const char *str);
 
 const void *nft_rule_expr_get(const struct nft_rule_expr *expr, uint16_t type, uint32_t *data_len);
+#define nft_rule_expr_get_data nft_rule_expr_get
 uint8_t nft_rule_expr_get_u8(const struct nft_rule_expr *expr, uint16_t type);
 uint16_t nft_rule_expr_get_u16(const struct nft_rule_expr *expr, uint16_t type);
 uint32_t nft_rule_expr_get_u32(const struct nft_rule_expr *expr, uint16_t type);
diff --git a/include/libnftnl/rule.h b/include/libnftnl/rule.h
index 13e6c14..9e6efaf 100644
--- a/include/libnftnl/rule.h
+++ b/include/libnftnl/rule.h
@@ -33,11 +33,15 @@ enum {
 void nft_rule_attr_unset(struct nft_rule *r, uint16_t attr);
 bool nft_rule_attr_is_set(const struct nft_rule *r, uint16_t attr);
 void nft_rule_attr_set(struct nft_rule *r, uint16_t attr, const void *data);
+void nft_rule_attr_set_data(struct nft_rule *r, uint16_t attr,
+			    const void *data, uint32_t data_len);
 void nft_rule_attr_set_u32(struct nft_rule *r, uint16_t attr, uint32_t val);
 void nft_rule_attr_set_u64(struct nft_rule *r, uint16_t attr, uint64_t val);
 void nft_rule_attr_set_str(struct nft_rule *r, uint16_t attr, const char *str);
 
 const void *nft_rule_attr_get(const struct nft_rule *r, uint16_t attr);
+const void *nft_rule_attr_get_data(const struct nft_rule *r, uint16_t attr,
+				   uint32_t *data_len);
 const char *nft_rule_attr_get_str(const struct nft_rule *r, uint16_t attr);
 uint8_t nft_rule_attr_get_u8(const struct nft_rule *r, uint16_t attr);
 uint32_t nft_rule_attr_get_u32(const struct nft_rule *r, uint16_t attr);
diff --git a/include/libnftnl/set.h b/include/libnftnl/set.h
index ba11315..fcb1a7e 100644
--- a/include/libnftnl/set.h
+++ b/include/libnftnl/set.h
@@ -29,10 +29,14 @@ void nft_set_free(struct nft_set *s);
 bool nft_set_attr_is_set(const struct nft_set *s, uint16_t attr);
 void nft_set_attr_unset(struct nft_set *s, uint16_t attr);
 void nft_set_attr_set(struct nft_set *s, uint16_t attr, const void *data);
+void nft_set_attr_set_data(struct nft_set *s, uint16_t attr, const void *data,
+			   uint32_t data_len);
 void nft_set_attr_set_u32(struct nft_set *s, uint16_t attr, uint32_t val);
 void nft_set_attr_set_str(struct nft_set *s, uint16_t attr, const char *str);
 
 const void *nft_set_attr_get(struct nft_set *s, uint16_t attr);
+const void *nft_set_attr_get_data(struct nft_set *s, uint16_t attr,
+				  uint32_t *data_len);
 const char *nft_set_attr_get_str(struct nft_set *s, uint16_t attr);
 uint32_t nft_set_attr_get_u32(struct nft_set *s, uint16_t attr);
 
diff --git a/include/libnftnl/table.h b/include/libnftnl/table.h
index 96f2668..fac79e7 100644
--- a/include/libnftnl/table.h
+++ b/include/libnftnl/table.h
@@ -29,7 +29,11 @@ enum {
 bool nft_table_attr_is_set(const struct nft_table *t, uint16_t attr);
 void nft_table_attr_unset(struct nft_table *t, uint16_t attr);
 void nft_table_attr_set(struct nft_table *t, uint16_t attr, const void *data);
+void nft_table_attr_set_data(struct nft_table *t, uint16_t attr,
+			     const void *data, uint32_t data_len);
 const void *nft_table_attr_get(struct nft_table *t, uint16_t attr);
+const void *nft_table_attr_get_data(struct nft_table *t, uint16_t attr,
+				    uint32_t *data_len);
 
 void nft_table_attr_set_u8(struct nft_table *t, uint16_t attr, uint8_t data);
 void nft_table_attr_set_u32(struct nft_table *t, uint16_t attr, uint32_t data);
diff --git a/src/chain.c b/src/chain.c
index 19e7950..a704502 100644
--- a/src/chain.c
+++ b/src/chain.c
@@ -140,11 +140,24 @@ void nft_chain_attr_unset(struct nft_chain *c, uint16_t attr)
 }
 EXPORT_SYMBOL(nft_chain_attr_unset);
 
-void nft_chain_attr_set(struct nft_chain *c, uint16_t attr, const void *data)
+static uint32_t nft_chain_attr_validate[NFT_CHAIN_ATTR_MAX + 1] = {
+	[NFT_CHAIN_ATTR_HOOKNUM]	= sizeof(uint32_t),
+	[NFT_CHAIN_ATTR_PRIO]		= sizeof(int32_t),
+	[NFT_CHAIN_ATTR_POLICY]		= sizeof(uint32_t),
+	[NFT_CHAIN_ATTR_BYTES]		= sizeof(uint64_t),
+	[NFT_CHAIN_ATTR_PACKETS]	= sizeof(uint64_t),
+	[NFT_CHAIN_ATTR_HANDLE]		= sizeof(uint64_t),
+	[NFT_CHAIN_ATTR_FAMILY]		= sizeof(uint8_t),
+};
+
+void nft_chain_attr_set_data(struct nft_chain *c, uint16_t attr,
+			     const void *data, uint32_t data_len)
 {
 	if (attr > NFT_CHAIN_ATTR_MAX)
 		return;
 
+	nft_assert_validate(nft_chain_attr_validate, attr, data_len);
+
 	switch(attr) {
 	case NFT_CHAIN_ATTR_NAME:
 		strncpy(c->name, data, NFT_CHAIN_MAXNAMELEN);
@@ -188,39 +201,46 @@ void nft_chain_attr_set(struct nft_chain *c, uint16_t attr, const void *data)
 	}
 	c->flags |= (1 << attr);
 }
+EXPORT_SYMBOL(nft_chain_attr_set_data);
+
+void nft_chain_attr_set(struct nft_chain *c, uint16_t attr, const void *data)
+{
+	nft_chain_attr_set_data(c, attr, data, nft_chain_attr_validate[attr]);
+}
 EXPORT_SYMBOL(nft_chain_attr_set);
 
 void nft_chain_attr_set_u32(struct nft_chain *c, uint16_t attr, uint32_t data)
 {
-	nft_chain_attr_set(c, attr, &data);
+	nft_chain_attr_set_data(c, attr, &data, sizeof(uint32_t));
 }
 EXPORT_SYMBOL(nft_chain_attr_set_u32);
 
 void nft_chain_attr_set_s32(struct nft_chain *c, uint16_t attr, int32_t data)
 {
-	nft_chain_attr_set(c, attr, &data);
+	nft_chain_attr_set_data(c, attr, &data, sizeof(int32_t));
 }
 EXPORT_SYMBOL(nft_chain_attr_set_s32);
 
 void nft_chain_attr_set_u64(struct nft_chain *c, uint16_t attr, uint64_t data)
 {
-	nft_chain_attr_set(c, attr, &data);
+	nft_chain_attr_set_data(c, attr, &data, sizeof(uint64_t));
 }
 EXPORT_SYMBOL(nft_chain_attr_set_u64);
 
 void nft_chain_attr_set_u8(struct nft_chain *c, uint16_t attr, uint8_t data)
 {
-	nft_chain_attr_set(c, attr, &data);
+	nft_chain_attr_set_data(c, attr, &data, sizeof(uint8_t));
 }
 EXPORT_SYMBOL(nft_chain_attr_set_u8);
 
 void nft_chain_attr_set_str(struct nft_chain *c, uint16_t attr, const char *str)
 {
-	nft_chain_attr_set(c, attr, str);
+	nft_chain_attr_set_data(c, attr, str, strlen(str));
 }
 EXPORT_SYMBOL(nft_chain_attr_set_str);
 
-const void *nft_chain_attr_get(struct nft_chain *c, uint16_t attr)
+const void *nft_chain_attr_get_data(struct nft_chain *c, uint16_t attr,
+				    uint32_t *data_len)
 {
 	if (!(c->flags & (1 << attr)))
 		return NULL;
@@ -231,26 +251,42 @@ const void *nft_chain_attr_get(struct nft_chain *c, uint16_t attr)
 	case NFT_CHAIN_ATTR_TABLE:
 		return c->table;
 	case NFT_CHAIN_ATTR_HOOKNUM:
+		*data_len = sizeof(uint32_t);
 		return &c->hooknum;
 	case NFT_CHAIN_ATTR_PRIO:
+		*data_len = sizeof(int32_t);
 		return &c->prio;
 	case NFT_CHAIN_ATTR_POLICY:
+		*data_len = sizeof(uint32_t);
 		return &c->policy;
 	case NFT_CHAIN_ATTR_USE:
+		*data_len = sizeof(uint32_t);
 		return &c->use;
 	case NFT_CHAIN_ATTR_BYTES:
+		*data_len = sizeof(uint64_t);
 		return &c->bytes;
 	case NFT_CHAIN_ATTR_PACKETS:
+		*data_len = sizeof(uint64_t);
 		return &c->packets;
 	case NFT_CHAIN_ATTR_HANDLE:
+		*data_len = sizeof(uint64_t);
 		return &c->handle;
 	case NFT_CHAIN_ATTR_FAMILY:
+		*data_len = sizeof(uint8_t);
 		return &c->family;
 	case NFT_CHAIN_ATTR_TYPE:
+		*data_len = sizeof(uint32_t);
 		return c->type;
 	}
 	return NULL;
 }
+EXPORT_SYMBOL(nft_chain_attr_get_data);
+
+const void *nft_chain_attr_get(struct nft_chain *c, uint16_t attr)
+{
+	uint32_t data_len;
+	return nft_chain_attr_get_data(c, attr, &data_len);
+}
 EXPORT_SYMBOL(nft_chain_attr_get);
 
 const char *nft_chain_attr_get_str(struct nft_chain *c, uint16_t attr)
@@ -261,28 +297,44 @@ EXPORT_SYMBOL(nft_chain_attr_get_str);
 
 uint32_t nft_chain_attr_get_u32(struct nft_chain *c, uint16_t attr)
 {
-	const uint32_t *val = nft_chain_attr_get(c, attr);
+	uint32_t data_len;
+	const uint32_t *val = nft_chain_attr_get_data(c, attr, &data_len);
+
+	nft_assert(attr, data_len == sizeof(uint32_t));
+
 	return val ? *val : 0;
 }
 EXPORT_SYMBOL(nft_chain_attr_get_u32);
 
 int32_t nft_chain_attr_get_s32(struct nft_chain *c, uint16_t attr)
 {
-	const int32_t *val = nft_chain_attr_get(c, attr);
+	uint32_t data_len;
+	const int32_t *val = nft_chain_attr_get_data(c, attr, &data_len);
+
+	nft_assert(attr, data_len == sizeof(int32_t));
+
 	return val ? *val : 0;
 }
 EXPORT_SYMBOL(nft_chain_attr_get_s32);
 
 uint64_t nft_chain_attr_get_u64(struct nft_chain *c, uint16_t attr)
 {
-	const uint64_t *val = nft_chain_attr_get(c, attr);
+	uint32_t data_len;
+	const uint64_t *val = nft_chain_attr_get_data(c, attr, &data_len);
+
+	nft_assert(attr, data_len == sizeof(int64_t));
+
 	return val ? *val : 0;
 }
 EXPORT_SYMBOL(nft_chain_attr_get_u64);
 
 uint8_t nft_chain_attr_get_u8(struct nft_chain *c, uint16_t attr)
 {
-	const uint8_t *val = nft_chain_attr_get(c, attr);
+	uint32_t data_len;
+	const uint8_t *val = nft_chain_attr_get_data(c, attr, &data_len);
+
+	nft_assert(attr, data_len == sizeof(int8_t));
+
 	return val ? *val : 0;
 }
 EXPORT_SYMBOL(nft_chain_attr_get_u8);
diff --git a/src/libnftnl.map b/src/libnftnl.map
index 43378ed..7c4e6ca 100644
--- a/src/libnftnl.map
+++ b/src/libnftnl.map
@@ -196,3 +196,14 @@ global:
 
 local: *;
 };
+
+LIBNFTNL_1.1 {
+  nft_table_attr_set_data;
+  nft_table_attr_get_data;
+  nft_chain_attr_set_data;
+  nft_chain_attr_get_data;
+  nft_rule_attr_set_data;
+  nft_rule_attr_get_data;
+  nft_set_attr_set_data;
+  nft_set_attr_get_data;
+} LIBNFTNL_1.0;
diff --git a/src/rule.c b/src/rule.c
index 5e149c7..ca4235b 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -113,11 +113,22 @@ void nft_rule_attr_unset(struct nft_rule *r, uint16_t attr)
 }
 EXPORT_SYMBOL(nft_rule_attr_unset);
 
-void nft_rule_attr_set(struct nft_rule *r, uint16_t attr, const void *data)
+static uint32_t nft_rule_attr_validate[NFT_RULE_ATTR_MAX + 1] = {
+	[NFT_RULE_ATTR_HANDLE]		= sizeof(uint64_t),
+	[NFT_RULE_ATTR_COMPAT_PROTO]	= sizeof(uint32_t),
+	[NFT_RULE_ATTR_COMPAT_FLAGS]	= sizeof(uint32_t),
+	[NFT_RULE_ATTR_FAMILY]		= sizeof(uint8_t),
+	[NFT_RULE_ATTR_POSITION]	= sizeof(uint64_t),
+};
+
+void nft_rule_attr_set_data(struct nft_rule *r, uint16_t attr,
+			    const void *data, uint32_t data_len)
 {
 	if (attr > NFT_RULE_ATTR_MAX)
 		return;
 
+	nft_assert_validate(nft_rule_attr_validate, attr, data_len);
+
 	switch(attr) {
 	case NFT_RULE_ATTR_TABLE:
 		if (r->table)
@@ -149,49 +160,68 @@ void nft_rule_attr_set(struct nft_rule *r, uint16_t attr, const void *data)
 	}
 	r->flags |= (1 << attr);
 }
+EXPORT_SYMBOL(nft_rule_attr_set_data);
+
+void nft_rule_attr_set(struct nft_rule *r, uint16_t attr, const void *data)
+{
+	nft_rule_attr_set_data(r, attr, data, nft_rule_attr_validate[attr]);
+}
 EXPORT_SYMBOL(nft_rule_attr_set);
 
 void nft_rule_attr_set_u32(struct nft_rule *r, uint16_t attr, uint32_t val)
 {
-	nft_rule_attr_set(r, attr, &val);
+	nft_rule_attr_set_data(r, attr, &val, sizeof(uint32_t));
 }
 EXPORT_SYMBOL(nft_rule_attr_set_u32);
 
 void nft_rule_attr_set_u64(struct nft_rule *r, uint16_t attr, uint64_t val)
 {
-	nft_rule_attr_set(r, attr, &val);
+	nft_rule_attr_set_data(r, attr, &val, sizeof(uint64_t));
 }
 EXPORT_SYMBOL(nft_rule_attr_set_u64);
 
 void nft_rule_attr_set_str(struct nft_rule *r, uint16_t attr, const char *str)
 {
-	nft_rule_attr_set(r, attr, str);
+	nft_rule_attr_set_data(r, attr, str, strlen(str));
 }
 EXPORT_SYMBOL(nft_rule_attr_set_str);
 
-const void *nft_rule_attr_get(const struct nft_rule *r, uint16_t attr)
+const void *nft_rule_attr_get_data(const struct nft_rule *r, uint16_t attr,
+				   uint32_t *data_len)
 {
 	if (!(r->flags & (1 << attr)))
 		return NULL;
 
 	switch(attr) {
 	case NFT_RULE_ATTR_FAMILY:
+		*data_len = sizeof(uint8_t);
 		return &r->family;
 	case NFT_RULE_ATTR_TABLE:
 		return r->table;
 	case NFT_RULE_ATTR_CHAIN:
 		return r->chain;
 	case NFT_RULE_ATTR_HANDLE:
+		*data_len = sizeof(uint64_t);
 		return &r->handle;
 	case NFT_RULE_ATTR_COMPAT_PROTO:
+		*data_len = sizeof(uint32_t);
 		return &r->compat.proto;
 	case NFT_RULE_ATTR_COMPAT_FLAGS:
+		*data_len = sizeof(uint32_t);
 		return &r->compat.flags;
 	case NFT_RULE_ATTR_POSITION:
+		*data_len = sizeof(uint64_t);
 		return &r->position;
 	}
 	return NULL;
 }
+EXPORT_SYMBOL(nft_rule_attr_get_data);
+
+const void *nft_rule_attr_get(const struct nft_rule *r, uint16_t attr)
+{
+	uint32_t data_len;
+	return nft_rule_attr_get_data(r, attr, &data_len);
+}
 EXPORT_SYMBOL(nft_rule_attr_get);
 
 const char *nft_rule_attr_get_str(const struct nft_rule *r, uint16_t attr)
@@ -202,21 +232,33 @@ EXPORT_SYMBOL(nft_rule_attr_get_str);
 
 uint32_t nft_rule_attr_get_u32(const struct nft_rule *r, uint16_t attr)
 {
-	const uint32_t *val = nft_rule_attr_get(r, attr);
+	uint32_t data_len;
+	const uint32_t *val = nft_rule_attr_get_data(r, attr, &data_len);
+
+	nft_assert(attr, data_len == sizeof(uint32_t));
+
 	return val ? *val : 0;
 }
 EXPORT_SYMBOL(nft_rule_attr_get_u32);
 
 uint64_t nft_rule_attr_get_u64(const struct nft_rule *r, uint16_t attr)
 {
-	const uint64_t *val = nft_rule_attr_get(r, attr);
+	uint32_t data_len;
+	const uint64_t *val = nft_rule_attr_get_data(r, attr, &data_len);
+
+	nft_assert(attr, data_len == sizeof(uint64_t));
+
 	return val ? *val : 0;
 }
 EXPORT_SYMBOL(nft_rule_attr_get_u64);
 
 uint8_t nft_rule_attr_get_u8(const struct nft_rule *r, uint16_t attr)
 {
-	const uint8_t *val = nft_rule_attr_get(r, attr);
+	uint32_t data_len;
+	const uint8_t *val = nft_rule_attr_get_data(r, attr, &data_len);
+
+	nft_assert(attr, data_len == sizeof(uint8_t));
+
 	return val ? *val : 0;
 }
 EXPORT_SYMBOL(nft_rule_attr_get_u8);
diff --git a/src/set.c b/src/set.c
index c8b5ccf..ef10af5 100644
--- a/src/set.c
+++ b/src/set.c
@@ -96,11 +96,23 @@ void nft_set_attr_unset(struct nft_set *s, uint16_t attr)
 }
 EXPORT_SYMBOL(nft_set_attr_unset);
 
-void nft_set_attr_set(struct nft_set *s, uint16_t attr, const void *data)
+static uint32_t nft_set_attr_validate[NFT_SET_ATTR_MAX + 1] = {
+	[NFT_SET_ATTR_FLAGS]		= sizeof(uint32_t),
+	[NFT_SET_ATTR_KEY_TYPE]		= sizeof(uint32_t),
+	[NFT_SET_ATTR_KEY_LEN]		= sizeof(uint32_t),
+	[NFT_SET_ATTR_DATA_TYPE]	= sizeof(uint32_t),
+	[NFT_SET_ATTR_DATA_LEN]		= sizeof(uint32_t),
+	[NFT_SET_ATTR_FAMILY]		= sizeof(uint32_t),
+};
+
+void nft_set_attr_set_data(struct nft_set *s, uint16_t attr, const void *data,
+			   uint32_t data_len)
 {
 	if (attr > NFT_SET_ATTR_MAX)
 		return;
 
+	nft_assert_validate(nft_set_attr_validate, attr, data_len);
+
 	switch(attr) {
 	case NFT_SET_ATTR_TABLE:
 		if (s->table)
@@ -135,6 +147,12 @@ void nft_set_attr_set(struct nft_set *s, uint16_t attr, const void *data)
 	}
 	s->flags |= (1 << attr);
 }
+EXPORT_SYMBOL(nft_set_attr_set_data);
+
+void nft_set_attr_set(struct nft_set *s, uint16_t attr, const void *data)
+{
+	nft_set_attr_set_data(s, attr, data, nft_set_attr_validate[attr]);
+}
 EXPORT_SYMBOL(nft_set_attr_set);
 
 void nft_set_attr_set_u32(struct nft_set *s, uint16_t attr, uint32_t val)
@@ -149,7 +167,8 @@ void nft_set_attr_set_str(struct nft_set *s, uint16_t attr, const char *str)
 }
 EXPORT_SYMBOL(nft_set_attr_set_str);
 
-const void *nft_set_attr_get(struct nft_set *s, uint16_t attr)
+const void *nft_set_attr_get_data(struct nft_set *s, uint16_t attr,
+				  uint32_t *data_len)
 {
 	if (!(s->flags & (1 << attr)))
 		return NULL;
@@ -160,20 +179,33 @@ const void *nft_set_attr_get(struct nft_set *s, uint16_t attr)
 	case NFT_SET_ATTR_NAME:
 		return s->name;
 	case NFT_SET_ATTR_FLAGS:
+		*data_len = sizeof(uint32_t);
 		return &s->set_flags;
 	case NFT_SET_ATTR_KEY_TYPE:
+		*data_len = sizeof(uint32_t);
 		return &s->key_type;
 	case NFT_SET_ATTR_KEY_LEN:
+		*data_len = sizeof(uint32_t);
 		return &s->key_len;
 	case NFT_SET_ATTR_DATA_TYPE:
+		*data_len = sizeof(uint32_t);
 		return &s->data_type;
 	case NFT_SET_ATTR_DATA_LEN:
+		*data_len = sizeof(uint32_t);
 		return &s->data_len;
 	case NFT_SET_ATTR_FAMILY:
+		*data_len = sizeof(uint32_t);
 		return &s->family;
 	}
 	return NULL;
 }
+EXPORT_SYMBOL(nft_set_attr_get_data);
+
+const void *nft_set_attr_get(struct nft_set *s, uint16_t attr)
+{
+	uint32_t data_len;
+	return nft_set_attr_get_data(s, attr, &data_len);
+}
 EXPORT_SYMBOL(nft_set_attr_get);
 
 const char *nft_set_attr_get_str(struct nft_set *s, uint16_t attr)
@@ -184,7 +216,11 @@ EXPORT_SYMBOL(nft_set_attr_get_str);
 
 uint32_t nft_set_attr_get_u32(struct nft_set *s, uint16_t attr)
 {
-	const uint32_t *val = nft_set_attr_get(s, attr);
+	uint32_t data_len;
+	const uint32_t *val = nft_set_attr_get_data(s, attr, &data_len);
+
+	nft_assert(attr, data_len == sizeof(uint32_t));
+
 	return val ? *val : 0;
 }
 EXPORT_SYMBOL(nft_set_attr_get_u32);
diff --git a/src/table.c b/src/table.c
index af4b13c..33d6a8d 100644
--- a/src/table.c
+++ b/src/table.c
@@ -79,11 +79,19 @@ void nft_table_attr_unset(struct nft_table *t, uint16_t attr)
 }
 EXPORT_SYMBOL(nft_table_attr_unset);
 
-void nft_table_attr_set(struct nft_table *t, uint16_t attr, const void *data)
+static uint32_t nft_table_attr_validate[NFT_TABLE_ATTR_MAX + 1] = {
+	[NFT_TABLE_ATTR_FLAGS]	= sizeof(uint32_t),
+	[NFT_TABLE_ATTR_FAMILY]	= sizeof(uint8_t),
+};
+
+void nft_table_attr_set_data(struct nft_table *t, uint16_t attr,
+			     const void *data, uint32_t data_len)
 {
 	if (attr > NFT_TABLE_ATTR_MAX)
 		return;
 
+	nft_assert_validate(nft_table_attr_validate, attr, data_len);
+
 	switch (attr) {
 	case NFT_TABLE_ATTR_NAME:
 		if (t->name)
@@ -103,27 +111,34 @@ void nft_table_attr_set(struct nft_table *t, uint16_t attr, const void *data)
 	}
 	t->flags |= (1 << attr);
 }
+EXPORT_SYMBOL(nft_table_attr_set_data);
+
+void nft_table_attr_set(struct nft_table *t, uint16_t attr, const void *data)
+{
+	nft_table_attr_set_data(t, attr, data, nft_table_attr_validate[attr]);
+}
 EXPORT_SYMBOL(nft_table_attr_set);
 
 void nft_table_attr_set_u32(struct nft_table *t, uint16_t attr, uint32_t val)
 {
-	nft_table_attr_set(t, attr, &val);
+	nft_table_attr_set_data(t, attr, &val, sizeof(uint32_t));
 }
 EXPORT_SYMBOL(nft_table_attr_set_u32);
 
 void nft_table_attr_set_u8(struct nft_table *t, uint16_t attr, uint8_t val)
 {
-	nft_table_attr_set(t, attr, &val);
+	nft_table_attr_set_data(t, attr, &val, sizeof(uint8_t));
 }
 EXPORT_SYMBOL(nft_table_attr_set_u8);
 
 void nft_table_attr_set_str(struct nft_table *t, uint16_t attr, const char *str)
 {
-	nft_table_attr_set(t, attr, str);
+	nft_table_attr_set_data(t, attr, str, 0);
 }
 EXPORT_SYMBOL(nft_table_attr_set_str);
 
-const void *nft_table_attr_get(struct nft_table *t, uint16_t attr)
+const void *nft_table_attr_get_data(struct nft_table *t, uint16_t attr,
+				    uint32_t *data_len)
 {
 	if (!(t->flags & (1 << attr)))
 		return NULL;
@@ -132,14 +147,24 @@ const void *nft_table_attr_get(struct nft_table *t, uint16_t attr)
 	case NFT_TABLE_ATTR_NAME:
 		return t->name;
 	case NFT_TABLE_ATTR_FLAGS:
+		*data_len = sizeof(uint32_t);
 		return &t->table_flags;
 	case NFT_TABLE_ATTR_FAMILY:
+		*data_len = sizeof(uint8_t);
 		return &t->family;
 	case NFT_TABLE_ATTR_USE:
+		*data_len = sizeof(uint32_t);
 		return &t->use;
 	}
 	return NULL;
 }
+EXPORT_SYMBOL(nft_table_attr_get_data);
+
+const void *nft_table_attr_get(struct nft_table *t, uint16_t attr)
+{
+	uint32_t data_len;
+	return nft_table_attr_get_data(t, attr, &data_len);
+}
 EXPORT_SYMBOL(nft_table_attr_get);
 
 uint32_t nft_table_attr_get_u32(struct nft_table *t, uint16_t attr)
-- 
1.7.10.4


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

* [PATCH 4/7] src: fix wrong type in NFT_ATTR_*_FAMILY
  2014-02-26  1:51 [PATCH 0/7] libnftnl updates Pablo Neira Ayuso
                   ` (2 preceding siblings ...)
  2014-02-26  1:51 ` [PATCH 3/7] src: add nft_*_attr_{set|get}_data interface Pablo Neira Ayuso
@ 2014-02-26  1:51 ` Pablo Neira Ayuso
  2014-02-26  1:51 ` [PATCH 5/7] include: get linux/netfilter/nf_tables.h in sync with kernel header Pablo Neira Ayuso
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Pablo Neira Ayuso @ 2014-02-26  1:51 UTC (permalink / raw)
  To: netfilter-devel; +Cc: kaber

This fixes assertions in the test files.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/chain.c                  |    8 ++++----
 src/rule.c                   |    8 ++++----
 src/table.c                  |    8 ++++----
 tests/nft-chain-test.c       |    6 +++---
 tests/nft-expr_ct-test.c     |    6 +++---
 tests/nft-expr_exthdr-test.c |    6 +++---
 tests/nft-expr_meta-test.c   |    4 ++--
 tests/nft-table-test.c       |    6 +++---
 8 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/src/chain.c b/src/chain.c
index a704502..33540b1 100644
--- a/src/chain.c
+++ b/src/chain.c
@@ -34,7 +34,7 @@ struct nft_chain {
 	char		name[NFT_CHAIN_MAXNAMELEN];
 	const char	*type;
 	const char	*table;
-	uint8_t		family;
+	uint32_t	family;
 	uint32_t	policy;
 	uint32_t	hooknum;
 	int32_t		prio;
@@ -147,7 +147,7 @@ static uint32_t nft_chain_attr_validate[NFT_CHAIN_ATTR_MAX + 1] = {
 	[NFT_CHAIN_ATTR_BYTES]		= sizeof(uint64_t),
 	[NFT_CHAIN_ATTR_PACKETS]	= sizeof(uint64_t),
 	[NFT_CHAIN_ATTR_HANDLE]		= sizeof(uint64_t),
-	[NFT_CHAIN_ATTR_FAMILY]		= sizeof(uint8_t),
+	[NFT_CHAIN_ATTR_FAMILY]		= sizeof(uint32_t),
 };
 
 void nft_chain_attr_set_data(struct nft_chain *c, uint16_t attr,
@@ -190,7 +190,7 @@ void nft_chain_attr_set_data(struct nft_chain *c, uint16_t attr,
 		c->handle = *((uint64_t *)data);
 		break;
 	case NFT_CHAIN_ATTR_FAMILY:
-		c->family = *((uint8_t *)data);
+		c->family = *((uint32_t *)data);
 		break;
 	case NFT_CHAIN_ATTR_TYPE:
 		if (c->type)
@@ -272,7 +272,7 @@ const void *nft_chain_attr_get_data(struct nft_chain *c, uint16_t attr,
 		*data_len = sizeof(uint64_t);
 		return &c->handle;
 	case NFT_CHAIN_ATTR_FAMILY:
-		*data_len = sizeof(uint8_t);
+		*data_len = sizeof(uint32_t);
 		return &c->family;
 	case NFT_CHAIN_ATTR_TYPE:
 		*data_len = sizeof(uint32_t);
diff --git a/src/rule.c b/src/rule.c
index ca4235b..adb7426 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -34,9 +34,9 @@ struct nft_rule {
 	struct list_head head;
 
 	uint32_t	flags;
+	uint32_t	family;
 	const char	*table;
 	const char	*chain;
-	uint8_t		family;
 	uint64_t	handle;
 	uint64_t	position;
 	struct {
@@ -117,7 +117,7 @@ static uint32_t nft_rule_attr_validate[NFT_RULE_ATTR_MAX + 1] = {
 	[NFT_RULE_ATTR_HANDLE]		= sizeof(uint64_t),
 	[NFT_RULE_ATTR_COMPAT_PROTO]	= sizeof(uint32_t),
 	[NFT_RULE_ATTR_COMPAT_FLAGS]	= sizeof(uint32_t),
-	[NFT_RULE_ATTR_FAMILY]		= sizeof(uint8_t),
+	[NFT_RULE_ATTR_FAMILY]		= sizeof(uint32_t),
 	[NFT_RULE_ATTR_POSITION]	= sizeof(uint64_t),
 };
 
@@ -152,7 +152,7 @@ void nft_rule_attr_set_data(struct nft_rule *r, uint16_t attr,
 		r->compat.flags = *((uint32_t *)data);
 		break;
 	case NFT_RULE_ATTR_FAMILY:
-		r->family = *((uint8_t *)data);
+		r->family = *((uint32_t *)data);
 		break;
 	case NFT_RULE_ATTR_POSITION:
 		r->position = *((uint64_t *)data);
@@ -194,7 +194,7 @@ const void *nft_rule_attr_get_data(const struct nft_rule *r, uint16_t attr,
 
 	switch(attr) {
 	case NFT_RULE_ATTR_FAMILY:
-		*data_len = sizeof(uint8_t);
+		*data_len = sizeof(uint32_t);
 		return &r->family;
 	case NFT_RULE_ATTR_TABLE:
 		return r->table;
diff --git a/src/table.c b/src/table.c
index 33d6a8d..0299209 100644
--- a/src/table.c
+++ b/src/table.c
@@ -29,7 +29,7 @@ struct nft_table {
 	struct list_head head;
 
 	const char	*name;
-	uint8_t		family;
+	uint32_t	family;
 	uint32_t	table_flags;
 	uint32_t	use;
 	uint32_t	flags;
@@ -81,7 +81,7 @@ EXPORT_SYMBOL(nft_table_attr_unset);
 
 static uint32_t nft_table_attr_validate[NFT_TABLE_ATTR_MAX + 1] = {
 	[NFT_TABLE_ATTR_FLAGS]	= sizeof(uint32_t),
-	[NFT_TABLE_ATTR_FAMILY]	= sizeof(uint8_t),
+	[NFT_TABLE_ATTR_FAMILY]	= sizeof(uint32_t),
 };
 
 void nft_table_attr_set_data(struct nft_table *t, uint16_t attr,
@@ -103,7 +103,7 @@ void nft_table_attr_set_data(struct nft_table *t, uint16_t attr,
 		t->table_flags = *((uint32_t *)data);
 		break;
 	case NFT_TABLE_ATTR_FAMILY:
-		t->family = *((uint8_t *)data);
+		t->family = *((uint32_t *)data);
 		break;
 	case NFT_TABLE_ATTR_USE:
 		/* Cannot be set, ignoring it */
@@ -150,7 +150,7 @@ const void *nft_table_attr_get_data(struct nft_table *t, uint16_t attr,
 		*data_len = sizeof(uint32_t);
 		return &t->table_flags;
 	case NFT_TABLE_ATTR_FAMILY:
-		*data_len = sizeof(uint8_t);
+		*data_len = sizeof(uint32_t);
 		return &t->family;
 	case NFT_TABLE_ATTR_USE:
 		*data_len = sizeof(uint32_t);
diff --git a/tests/nft-chain-test.c b/tests/nft-chain-test.c
index 125562a..1ff8334 100644
--- a/tests/nft-chain-test.c
+++ b/tests/nft-chain-test.c
@@ -32,8 +32,8 @@ static void cmp_nft_chain(struct nft_chain *a, struct nft_chain *b)
 	if (strcmp(nft_chain_attr_get_str(a, NFT_CHAIN_ATTR_TABLE),
 		   nft_chain_attr_get_str(b, NFT_CHAIN_ATTR_TABLE)) != 0)
 		print_err("Chain table mismatches");
-	if (nft_chain_attr_get_u8(a, NFT_CHAIN_ATTR_FAMILY) !=
-	    nft_chain_attr_get_u8(b, NFT_CHAIN_ATTR_FAMILY))
+	if (nft_chain_attr_get_u32(a, NFT_CHAIN_ATTR_FAMILY) !=
+	    nft_chain_attr_get_u32(b, NFT_CHAIN_ATTR_FAMILY))
 		print_err("Chain family mismatches");
 	if (nft_chain_attr_get_u32(a, NFT_CHAIN_ATTR_POLICY) !=
 	    nft_chain_attr_get_u32(b, NFT_CHAIN_ATTR_POLICY))
@@ -73,7 +73,7 @@ int main(int argc, char *argv[])
 		print_err("OOM");
 
 	nft_chain_attr_set_str(a, NFT_CHAIN_ATTR_NAME, "test");
-	nft_chain_attr_set_u8(a, NFT_CHAIN_ATTR_FAMILY, AF_INET);
+	nft_chain_attr_set_u32(a, NFT_CHAIN_ATTR_FAMILY, AF_INET);
 	nft_chain_attr_set_str(a, NFT_CHAIN_ATTR_TABLE, "Table");
 	nft_chain_attr_set_u32(a, NFT_CHAIN_ATTR_POLICY,0x12345678);
 	nft_chain_attr_set_u32(a, NFT_CHAIN_ATTR_HOOKNUM, 0x12345678);
diff --git a/tests/nft-expr_ct-test.c b/tests/nft-expr_ct-test.c
index 341d9e6..dd07854 100644
--- a/tests/nft-expr_ct-test.c
+++ b/tests/nft-expr_ct-test.c
@@ -32,8 +32,8 @@ static void cmp_nft_rule_expr(struct nft_rule_expr *rule_a,
 	if (nft_rule_expr_get_u32(rule_a, NFT_EXPR_CT_KEY) !=
 	    nft_rule_expr_get_u32(rule_b, NFT_EXPR_CT_KEY))
 		print_err("Expr CT_KEY mismatches");
-	if (nft_rule_expr_get_u8(rule_a, NFT_EXPR_CT_DIR) !=
-	    nft_rule_expr_get_u8(rule_b, NFT_EXPR_CT_DIR))
+	if (nft_rule_expr_get_u32(rule_a, NFT_EXPR_CT_DIR) !=
+	    nft_rule_expr_get_u32(rule_b, NFT_EXPR_CT_DIR))
 		print_err("Expr CT_DIR mismatches");
 	if (nft_rule_expr_get_u32(rule_a, NFT_EXPR_CT_DREG) !=
 	    nft_rule_expr_get_u32(rule_b, NFT_EXPR_CT_DREG))
@@ -57,7 +57,7 @@ int main(int argc, char *argv[])
 		print_err("OOM");
 
 	nft_rule_expr_set_u32(ex, NFT_EXPR_CT_KEY, 0x1234568);
-	nft_rule_expr_set_u8(ex, NFT_EXPR_CT_DIR, 0x12);
+	nft_rule_expr_set_u32(ex, NFT_EXPR_CT_DIR, 0x12);
 	nft_rule_expr_set_u32(ex, NFT_EXPR_CT_DREG, 0x12345678);
 
 	nft_rule_add_expr(a, ex);
diff --git a/tests/nft-expr_exthdr-test.c b/tests/nft-expr_exthdr-test.c
index a712903..c0dc609 100644
--- a/tests/nft-expr_exthdr-test.c
+++ b/tests/nft-expr_exthdr-test.c
@@ -33,8 +33,8 @@ static void cmp_nft_rule_expr(struct nft_rule_expr *rule_a,
 	if (nft_rule_expr_get_u32(rule_a, NFT_EXPR_EXTHDR_DREG) !=
 	    nft_rule_expr_get_u32(rule_b, NFT_EXPR_EXTHDR_DREG))
 		print_err("Expr NFT_EXPR_EXTHDR_DREG mismatches");
-	if (nft_rule_expr_get_u8(rule_a, NFT_EXPR_EXTHDR_TYPE) !=
-	    nft_rule_expr_get_u8(rule_b, NFT_EXPR_EXTHDR_TYPE))
+	if (nft_rule_expr_get_u32(rule_a, NFT_EXPR_EXTHDR_TYPE) !=
+	    nft_rule_expr_get_u32(rule_b, NFT_EXPR_EXTHDR_TYPE))
 		print_err("Expr NFT_EXPR_EXTHDR_TYPE mismatches");
 	if (nft_rule_expr_get_u32(rule_a, NFT_EXPR_EXTHDR_OFFSET) !=
 	    nft_rule_expr_get_u32(rule_b, NFT_EXPR_EXTHDR_OFFSET))
@@ -62,7 +62,7 @@ int main(int argc, char *argv[])
 		print_err("OOM");
 
 	nft_rule_expr_set_u32(ex, NFT_EXPR_EXTHDR_DREG, 0x12345678);
-	nft_rule_expr_set_u8(ex, NFT_EXPR_EXTHDR_TYPE, 0x12);
+	nft_rule_expr_set_u32(ex, NFT_EXPR_EXTHDR_TYPE, 0x12);
 	nft_rule_expr_set_u32(ex, NFT_EXPR_EXTHDR_OFFSET, 0x12345678);
 	nft_rule_expr_set_u32(ex, NFT_EXPR_EXTHDR_LEN, 0x12345678);
 
diff --git a/tests/nft-expr_meta-test.c b/tests/nft-expr_meta-test.c
index 9196f9c..d9569ec 100644
--- a/tests/nft-expr_meta-test.c
+++ b/tests/nft-expr_meta-test.c
@@ -33,8 +33,8 @@ static void cmp_nft_rule_expr(struct nft_rule_expr *rule_a,
 	if (nft_rule_expr_get_u32(rule_a, NFT_EXPR_META_KEY) !=
 	    nft_rule_expr_get_u32(rule_b, NFT_EXPR_META_KEY))
 		print_err("Expr NFT_EXPR_META_KEY mismatches");
-	if (nft_rule_expr_get_u8(rule_a, NFT_EXPR_META_DREG) !=
-	    nft_rule_expr_get_u8(rule_b, NFT_EXPR_META_DREG))
+	if (nft_rule_expr_get_u32(rule_a, NFT_EXPR_META_DREG) !=
+	    nft_rule_expr_get_u32(rule_b, NFT_EXPR_META_DREG))
 		print_err("Expr NFT_EXPR_META_DREG mismatches");
 }
 
diff --git a/tests/nft-table-test.c b/tests/nft-table-test.c
index 051163b..2096ea5 100644
--- a/tests/nft-table-test.c
+++ b/tests/nft-table-test.c
@@ -32,8 +32,8 @@ static void cmp_nft_table(struct nft_table *a, struct nft_table *b)
 	if (nft_table_attr_get_u32(a, NFT_TABLE_ATTR_FLAGS) !=
 	    nft_table_attr_get_u32(b, NFT_TABLE_ATTR_FLAGS))
 		print_err("table flags mismatches");
-	if (nft_table_attr_get_u8(a, NFT_TABLE_ATTR_FAMILY) !=
-	    nft_table_attr_get_u8(b, NFT_TABLE_ATTR_FAMILY))
+	if (nft_table_attr_get_u32(a, NFT_TABLE_ATTR_FAMILY) !=
+	    nft_table_attr_get_u32(b, NFT_TABLE_ATTR_FAMILY))
 		print_err("tabke family mismatches");
 }
 
@@ -51,7 +51,7 @@ int main(int argc, char *argv[])
 		print_err("OOM");
 
 	nft_table_attr_set_str(a, NFT_TABLE_ATTR_NAME, "test");
-	nft_table_attr_set_u8(a, NFT_TABLE_ATTR_FAMILY, AF_INET);
+	nft_table_attr_set_u32(a, NFT_TABLE_ATTR_FAMILY, AF_INET);
 	nft_table_attr_set_u32(a, NFT_TABLE_ATTR_FLAGS, 0);
 
 	/* cmd extracted from include/linux/netfilter/nf_tables.h */
-- 
1.7.10.4


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

* [PATCH 5/7] include: get linux/netfilter/nf_tables.h in sync with kernel header
  2014-02-26  1:51 [PATCH 0/7] libnftnl updates Pablo Neira Ayuso
                   ` (3 preceding siblings ...)
  2014-02-26  1:51 ` [PATCH 4/7] src: fix wrong type in NFT_ATTR_*_FAMILY Pablo Neira Ayuso
@ 2014-02-26  1:51 ` Pablo Neira Ayuso
  2014-02-26  1:51 ` [PATCH 6/7] example: nft-rule-add: simplify example Pablo Neira Ayuso
  2014-02-26  1:51 ` [PATCH 7/7] rule: add NFT_RULE_ATTR_USERDATA support Pablo Neira Ayuso
  6 siblings, 0 replies; 8+ messages in thread
From: Pablo Neira Ayuso @ 2014-02-26  1:51 UTC (permalink / raw)
  To: netfilter-devel; +Cc: kaber

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/linux/netfilter/nf_tables.h |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 31ddd06..83c985a 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -110,6 +110,7 @@ enum nft_table_flags {
  *
  * @NFTA_TABLE_NAME: name of the table (NLA_STRING)
  * @NFTA_TABLE_FLAGS: bitmask of enum nft_table_flags (NLA_U32)
+ * @NFTA_TABLE_USE: number of chains in this table (NLA_U32)
  */
 enum nft_table_attributes {
 	NFTA_TABLE_UNSPEC,
@@ -557,7 +558,7 @@ enum nft_meta_keys {
  * enum nft_meta_attributes - nf_tables meta expression netlink attributes
  *
  * @NFTA_META_DREG: destination register (NLA_U32)
- * @NFTA_META_KEY: meta data item to load or set (NLA_U32: nft_meta_keys)
+ * @NFTA_META_KEY: meta data item to load (NLA_U32: nft_meta_keys)
  * @NFTA_META_SREG: source register (NLA_U32)
  */
 enum nft_meta_attributes {
-- 
1.7.10.4


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

* [PATCH 6/7] example: nft-rule-add: simplify example
  2014-02-26  1:51 [PATCH 0/7] libnftnl updates Pablo Neira Ayuso
                   ` (4 preceding siblings ...)
  2014-02-26  1:51 ` [PATCH 5/7] include: get linux/netfilter/nf_tables.h in sync with kernel header Pablo Neira Ayuso
@ 2014-02-26  1:51 ` Pablo Neira Ayuso
  2014-02-26  1:51 ` [PATCH 7/7] rule: add NFT_RULE_ATTR_USERDATA support Pablo Neira Ayuso
  6 siblings, 0 replies; 8+ messages in thread
From: Pablo Neira Ayuso @ 2014-02-26  1:51 UTC (permalink / raw)
  To: netfilter-devel; +Cc: kaber

The nft_mnl_batch_talk() is overly complicated for a simple example
that just adds one single rule. Simplify this to prepare the merge
of nft-rule-insert, which looks very similar.
---
 examples/nft-rule-add.c |   86 ++++++++++++++++-------------------------------
 1 file changed, 29 insertions(+), 57 deletions(-)

diff --git a/examples/nft-rule-add.c b/examples/nft-rule-add.c
index dbe93f5..21b3bf8 100644
--- a/examples/nft-rule-add.c
+++ b/examples/nft-rule-add.c
@@ -111,68 +111,20 @@ static struct nft_rule *setup_rule(uint8_t family, const char *table,
 	return r;
 }
 
-static int seq;
-
-static void nft_mnl_batch_put(struct mnl_nlmsg_batch *batch, int type)
+static void nft_mnl_batch_put(char *buf, uint16_t type, uint32_t seq)
 {
 	struct nlmsghdr *nlh;
 	struct nfgenmsg *nfg;
 
-	nlh = mnl_nlmsg_put_header(mnl_nlmsg_batch_current(batch));
+	nlh = mnl_nlmsg_put_header(buf);
 	nlh->nlmsg_type = type;
 	nlh->nlmsg_flags = NLM_F_REQUEST;
-	nlh->nlmsg_seq = seq++;
+	nlh->nlmsg_seq = seq;
 
 	nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
 	nfg->nfgen_family = AF_INET;
 	nfg->version = NFNETLINK_V0;
 	nfg->res_id = NFNL_SUBSYS_NFTABLES;
-
-	mnl_nlmsg_batch_next(batch);
-}
-
-static int nft_mnl_batch_talk(struct mnl_socket *nl, struct mnl_nlmsg_batch *b)
-{
-	int ret, fd = mnl_socket_get_fd(nl);
-	char rcv_buf[MNL_SOCKET_BUFFER_SIZE];
-	fd_set readfds;
-	struct timeval tv = {
-		.tv_sec		= 0,
-		.tv_usec	= 0
-	};
-
-	ret = mnl_socket_sendto(nl, mnl_nlmsg_batch_head(b),
-				mnl_nlmsg_batch_size(b));
-	if (ret == -1)
-		goto err;
-
-	FD_ZERO(&readfds);
-	FD_SET(fd, &readfds);
-
-	/* receive and digest all the acknowledgments from the kernel. */
-	ret = select(fd+1, &readfds, NULL, NULL, &tv);
-	if (ret == -1)
-		goto err;
-
-	while (ret > 0 && FD_ISSET(fd, &readfds)) {
-		ret = mnl_socket_recvfrom(nl, rcv_buf, sizeof(rcv_buf));
-		if (ret == -1)
-			goto err;
-
-		ret = mnl_cb_run(rcv_buf, ret, 0, mnl_socket_get_portid(nl),
-				 NULL, NULL);
-		if (ret < 0)
-			goto err;
-
-		ret = select(fd+1, &readfds, NULL, NULL, &tv);
-		if (ret == -1)
-			goto err;
-
-		FD_ZERO(&readfds);
-		FD_SET(fd, &readfds);
-	}
-err:
-	return ret;
 }
 
 int main(int argc, char *argv[])
@@ -182,7 +134,9 @@ int main(int argc, char *argv[])
 	struct nlmsghdr *nlh;
 	struct mnl_nlmsg_batch *batch;
 	uint8_t family;
-	char buf[4096];
+	char buf[MNL_SOCKET_BUFFER_SIZE];
+	uint32_t seq = time(NULL);
+	int ret;
 
 	if (argc != 4) {
 		fprintf(stderr, "Usage: %s <family> <table> <chain>\n", argv[0]);
@@ -213,26 +167,44 @@ int main(int argc, char *argv[])
 
 	batch = mnl_nlmsg_batch_start(buf, sizeof(buf));
 
-	nft_mnl_batch_put(batch, NFNL_MSG_BATCH_BEGIN);
+	nft_mnl_batch_put(mnl_nlmsg_batch_current(batch),
+			  NFNL_MSG_BATCH_BEGIN, seq++);
+	mnl_nlmsg_batch_next(batch);
 
 	nlh = nft_rule_nlmsg_build_hdr(mnl_nlmsg_batch_current(batch),
 			NFT_MSG_NEWRULE,
 			nft_rule_attr_get_u32(r, NFT_RULE_ATTR_FAMILY),
-			NLM_F_APPEND|NLM_F_CREATE, seq);
+			NLM_F_APPEND|NLM_F_CREATE|NLM_F_ACK, seq++);
 
 	nft_rule_nlmsg_build_payload(nlh, r);
 	nft_rule_free(r);
 	mnl_nlmsg_batch_next(batch);
 
-	nft_mnl_batch_put(batch, NFNL_MSG_BATCH_END);
+	nft_mnl_batch_put(mnl_nlmsg_batch_current(batch), NFNL_MSG_BATCH_END,
+			 seq++);
+	mnl_nlmsg_batch_next(batch);
 
-	if (nft_mnl_batch_talk(nl, batch) < 0) {
-		perror("Netlink problem");
+	ret = mnl_socket_sendto(nl, mnl_nlmsg_batch_head(batch),
+				mnl_nlmsg_batch_size(batch));
+	if (ret == -1) {
+		perror("mnl_socket_sendto");
 		exit(EXIT_FAILURE);
 	}
 
 	mnl_nlmsg_batch_stop(batch);
 
+	ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
+	if (ret == -1) {
+		perror("mnl_socket_recvfrom");
+		exit(EXIT_FAILURE);
+	}
+
+	ret = mnl_cb_run(buf, ret, 0, mnl_socket_get_portid(nl), NULL, NULL);
+	if (ret < 0) {
+		perror("mnl_cb_run");
+		exit(EXIT_FAILURE);
+	}
+
 	mnl_socket_close(nl);
 
 	return EXIT_SUCCESS;
-- 
1.7.10.4


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

* [PATCH 7/7] rule: add NFT_RULE_ATTR_USERDATA support
  2014-02-26  1:51 [PATCH 0/7] libnftnl updates Pablo Neira Ayuso
                   ` (5 preceding siblings ...)
  2014-02-26  1:51 ` [PATCH 6/7] example: nft-rule-add: simplify example Pablo Neira Ayuso
@ 2014-02-26  1:51 ` Pablo Neira Ayuso
  6 siblings, 0 replies; 8+ messages in thread
From: Pablo Neira Ayuso @ 2014-02-26  1:51 UTC (permalink / raw)
  To: netfilter-devel; +Cc: kaber

This allows us to manipulate the user data area of the rule.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/libnftnl/rule.h             |    1 +
 include/linux/netfilter/nf_tables.h |    5 ++-
 src/rule.c                          |   58 ++++++++++++++++++++++++++++++++++-
 3 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/include/libnftnl/rule.h b/include/libnftnl/rule.h
index 9e6efaf..62dba59 100644
--- a/include/libnftnl/rule.h
+++ b/include/libnftnl/rule.h
@@ -26,6 +26,7 @@ enum {
 	NFT_RULE_ATTR_COMPAT_PROTO,
 	NFT_RULE_ATTR_COMPAT_FLAGS,
 	NFT_RULE_ATTR_POSITION,
+	NFT_RULE_ATTR_USERDATA,
 	__NFT_RULE_ATTR_MAX
 };
 #define NFT_RULE_ATTR_MAX (__NFT_RULE_ATTR_MAX - 1)
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 83c985a..d22c7c1 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -1,7 +1,8 @@
 #ifndef _LINUX_NF_TABLES_H
 #define _LINUX_NF_TABLES_H
 
-#define NFT_CHAIN_MAXNAMELEN 32
+#define NFT_CHAIN_MAXNAMELEN	32
+#define NFT_USERDATA_MAXLEN	128
 
 enum nft_registers {
 	NFT_REG_VERDICT,
@@ -156,6 +157,7 @@ enum nft_chain_attributes {
  * @NFTA_RULE_EXPRESSIONS: list of expressions (NLA_NESTED: nft_expr_attributes)
  * @NFTA_RULE_COMPAT: compatibility specifications of the rule (NLA_NESTED: nft_rule_compat_attributes)
  * @NFTA_RULE_POSITION: numeric handle of the previous rule (NLA_U64)
+ * @NFTA_RULE_USERDATA: user data (NLA_BINARY, NFT_USERDATA_MAXLEN long)
  */
 enum nft_rule_attributes {
 	NFTA_RULE_UNSPEC,
@@ -165,6 +167,7 @@ enum nft_rule_attributes {
 	NFTA_RULE_EXPRESSIONS,
 	NFTA_RULE_COMPAT,
 	NFTA_RULE_POSITION,
+	NFTA_RULE_USERDATA,
 	__NFTA_RULE_MAX
 };
 #define NFTA_RULE_MAX		(__NFTA_RULE_MAX - 1)
diff --git a/src/rule.c b/src/rule.c
index adb7426..30ae71c 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -19,6 +19,7 @@
 #include <netinet/in.h>
 #include <errno.h>
 #include <inttypes.h>
+#include <ctype.h>
 
 #include <libmnl/libmnl.h>
 #include <linux/netfilter/nfnetlink.h>
@@ -40,6 +41,10 @@ struct nft_rule {
 	uint64_t	handle;
 	uint64_t	position;
 	struct {
+			void		*data;
+			uint32_t	len;
+	} user;
+	struct {
 			uint32_t	flags;
 			uint32_t	proto;
 	} compat;
@@ -106,6 +111,7 @@ void nft_rule_attr_unset(struct nft_rule *r, uint16_t attr)
 	case NFT_RULE_ATTR_COMPAT_FLAGS:
 	case NFT_RULE_ATTR_POSITION:
 	case NFT_RULE_ATTR_FAMILY:
+	case NFT_RULE_ATTR_USERDATA:
 		break;
 	}
 
@@ -157,6 +163,10 @@ void nft_rule_attr_set_data(struct nft_rule *r, uint16_t attr,
 	case NFT_RULE_ATTR_POSITION:
 		r->position = *((uint64_t *)data);
 		break;
+	case NFT_RULE_ATTR_USERDATA:
+		r->user.data = (void *)data;
+		r->user.len = data_len;
+		break;
 	}
 	r->flags |= (1 << attr);
 }
@@ -212,6 +222,9 @@ const void *nft_rule_attr_get_data(const struct nft_rule *r, uint16_t attr,
 	case NFT_RULE_ATTR_POSITION:
 		*data_len = sizeof(uint64_t);
 		return &r->position;
+	case NFT_RULE_ATTR_USERDATA:
+		*data_len = r->user.len;
+		return r->user.data;
 	}
 	return NULL;
 }
@@ -276,6 +289,10 @@ void nft_rule_nlmsg_build_payload(struct nlmsghdr *nlh, struct nft_rule *r)
 		mnl_attr_put_u64(nlh, NFTA_RULE_HANDLE, htobe64(r->handle));
 	if (r->flags & (1 << NFT_RULE_ATTR_POSITION))
 		mnl_attr_put_u64(nlh, NFTA_RULE_POSITION, htobe64(r->position));
+	if (r->flags & (1 << NFT_RULE_ATTR_USERDATA)) {
+		mnl_attr_put(nlh, NFTA_RULE_USERDATA, r->user.len,
+			     r->user.data);
+	}
 
 	if (!list_empty(&r->expr_list)) {
 		nest = mnl_attr_nest_start(nlh, NFTA_RULE_EXPRESSIONS);
@@ -338,6 +355,12 @@ static int nft_rule_parse_attr_cb(const struct nlattr *attr, void *data)
 			return MNL_CB_ERROR;
 		}
 		break;
+	case NFTA_RULE_USERDATA:
+		if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0) {
+			perror("mnl_attr_validate");
+			return MNL_CB_ERROR;
+		}
+		break;
 	}
 
 	tb[type] = attr;
@@ -476,6 +499,22 @@ int nft_rule_nlmsg_parse(const struct nlmsghdr *nlh, struct nft_rule *r)
 		r->position = be64toh(mnl_attr_get_u64(tb[NFTA_RULE_POSITION]));
 		r->flags |= (1 << NFT_RULE_ATTR_POSITION);
 	}
+	if (tb[NFTA_RULE_USERDATA]) {
+		const void *udata =
+			mnl_attr_get_payload(tb[NFTA_RULE_USERDATA]);
+
+		if (r->user.data)
+			xfree(r->user.data);
+
+		r->user.len = mnl_attr_get_payload_len(tb[NFTA_RULE_USERDATA]);
+
+		r->user.data = malloc(r->user.len);
+		if (r->user.data == NULL)
+			return -1;
+
+		memcpy(r->user.data, udata, r->user.len);
+		r->flags |= (1 << NFT_RULE_ATTR_USERDATA);
+	}
 
 	r->family = nfg->nfgen_family;
 	r->flags |= (1 << NFT_RULE_ATTR_FAMILY);
@@ -828,7 +867,7 @@ static int nft_rule_snprintf_default(char *buf, size_t size, struct nft_rule *r,
 				     uint32_t type, uint32_t flags)
 {
 	struct nft_rule_expr *expr;
-	int ret, len = size, offset = 0;
+	int ret, len = size, offset = 0, i;
 
 	ret = snprintf(buf, len, "%s %s %s %"PRIu64" %"PRIu64"\n",
 			nft_family2str(r->family), r->table, r->chain,
@@ -847,6 +886,23 @@ static int nft_rule_snprintf_default(char *buf, size_t size, struct nft_rule *r,
 		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 	}
 
+	if (r->user.len) {
+		ret = snprintf(buf+offset, len, "  userdata = { ");
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+		for (i = 0; i < r->user.len; i++) {
+			char *c = r->user.data;
+
+			ret = snprintf(buf+offset, len, "%c",
+				       isalnum(c[i]) ? c[i] : 0);
+			SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+		}
+
+		ret = snprintf(buf+offset, len, " }\n");
+		SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
+
+	}
+
 	return offset;
 }
 
-- 
1.7.10.4


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

end of thread, other threads:[~2014-02-26  1:52 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-02-26  1:51 [PATCH 0/7] libnftnl updates Pablo Neira Ayuso
2014-02-26  1:51 ` [PATCH 1/7] src: early attribute type validation in nft_*_attr_set Pablo Neira Ayuso
2014-02-26  1:51 ` [PATCH 2/7] src: add assertion infrastructure to validate attribute types Pablo Neira Ayuso
2014-02-26  1:51 ` [PATCH 3/7] src: add nft_*_attr_{set|get}_data interface Pablo Neira Ayuso
2014-02-26  1:51 ` [PATCH 4/7] src: fix wrong type in NFT_ATTR_*_FAMILY Pablo Neira Ayuso
2014-02-26  1:51 ` [PATCH 5/7] include: get linux/netfilter/nf_tables.h in sync with kernel header Pablo Neira Ayuso
2014-02-26  1:51 ` [PATCH 6/7] example: nft-rule-add: simplify example Pablo Neira Ayuso
2014-02-26  1:51 ` [PATCH 7/7] rule: add NFT_RULE_ATTR_USERDATA support Pablo Neira Ayuso

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).