* [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