* [PATCH 0/3] Add userdata and comment support for tables
@ 2020-08-20 8:19 Jose M. Guisado Gomez
2020-08-20 8:19 ` [PATCH nf-next 1/3] netfilter: nf_tables: add userdata attributes to nft_table Jose M. Guisado Gomez
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Jose M. Guisado Gomez @ 2020-08-20 8:19 UTC (permalink / raw)
To: netfilter-devel; +Cc: pablo
This patch series enables storing userdata for tables. In addition,
using this userdata to save an optional comment when declaring new tables.
* nf-next
netfilter: nf_tables: add userdata attributes to nft_table
include/net/netfilter/nf_tables.h | 2 ++
include/uapi/linux/netfilter/nf_tables.h | 2 ++
net/netfilter/nf_tables_api.c | 25 ++++++++++++++++++++++++
3 files changed, 29 insertions(+)
* libnftnlt
table: add userdata support
include/libnftnl/table.h | 1 +
include/libnftnl/udata.h | 6 ++++++
include/linux/netfilter/nf_tables.h | 1 +
src/table.c | 33 +++++++++++++++++++++++++++++
4 files changed, 41 insertions(+)
* nftables
src: add comment support when adding tables
include/rule.h | 1 +
src/mnl.c | 19 +++++++++--
src/netlink.c | 32 +++++++++++++++++++
src/parser_bison.y | 4 +++
src/rule.c | 5 +++
.../testcases/optionals/comments_table_0 | 0
.../testcases/optionals/comments_table_1 | 0
.../optionals/dumps/comments_table_0.nft | 0
.../optionals/dumps/comments_table_1.nft | 0
9 files changed, 59 insertions(+), 2 deletions(-)
create mode 100755 tests/shell/testcases/optionals/comments_table_0
create mode 100755 tests/shell/testcases/optionals/comments_table_1
create mode 100644 tests/shell/testcases/optionals/dumps/comments_table_0.nft
create mode 100644 tests/shell/testcases/optionals/dumps/comments_table_1.nft
--
2.27.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH nf-next 1/3] netfilter: nf_tables: add userdata attributes to nft_table
2020-08-20 8:19 [PATCH 0/3] Add userdata and comment support for tables Jose M. Guisado Gomez
@ 2020-08-20 8:19 ` Jose M. Guisado Gomez
2020-08-21 17:21 ` Pablo Neira Ayuso
2020-08-22 9:09 ` [PATCH nf-next v2 " Jose M. Guisado Gomez
2020-08-20 8:19 ` [PATCH libnftnl 2/3] table: add userdata support Jose M. Guisado Gomez
2020-08-20 8:19 ` [PATCH nftables 3/3] src: add comment support when adding tables Jose M. Guisado Gomez
2 siblings, 2 replies; 11+ messages in thread
From: Jose M. Guisado Gomez @ 2020-08-20 8:19 UTC (permalink / raw)
To: netfilter-devel; +Cc: pablo
Enables storing userdata for nft_table. Field udata points to user data
and udlen store its length.
Adds new attribute flag NFTA_TABLE_USERDATA
Signed-off-by: Jose M. Guisado Gomez <guigom@riseup.net>
---
include/net/netfilter/nf_tables.h | 2 ++
include/uapi/linux/netfilter/nf_tables.h | 2 ++
net/netfilter/nf_tables_api.c | 25 ++++++++++++++++++++++++
3 files changed, 29 insertions(+)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index bf9491b77d16..97a7e147a59a 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -1080,6 +1080,8 @@ struct nft_table {
flags:8,
genmask:2;
char *name;
+ u16 udlen;
+ u8 *udata;
};
void nft_register_chain_type(const struct nft_chain_type *);
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 42f351c1f5c5..aeb88cbd303e 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -172,6 +172,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)
+ * @NFTA_TABLE_USERDATA: user data (NLA_BINARY)
*/
enum nft_table_attributes {
NFTA_TABLE_UNSPEC,
@@ -180,6 +181,7 @@ enum nft_table_attributes {
NFTA_TABLE_USE,
NFTA_TABLE_HANDLE,
NFTA_TABLE_PAD,
+ NFTA_TABLE_USERDATA,
__NFTA_TABLE_MAX
};
#define NFTA_TABLE_MAX (__NFTA_TABLE_MAX - 1)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index d878e34e3354..ca240a990eea 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -650,6 +650,8 @@ static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = {
.len = NFT_TABLE_MAXNAMELEN - 1 },
[NFTA_TABLE_FLAGS] = { .type = NLA_U32 },
[NFTA_TABLE_HANDLE] = { .type = NLA_U64 },
+ [NFTA_TABLE_USERDATA] = { .type = NLA_BINARY,
+ .len = NFT_USERDATA_MAXLEN }
};
static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
@@ -676,6 +678,11 @@ static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
NFTA_TABLE_PAD))
goto nla_put_failure;
+ if (table->udata) {
+ if (nla_put(skb, NFTA_TABLE_USERDATA, table->udlen, table->udata))
+ goto nla_put_failure;
+ }
+
nlmsg_end(skb, nlh);
return 0;
@@ -980,6 +987,7 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk,
u32 flags = 0;
struct nft_ctx ctx;
int err;
+ u16 udlen = 0;
lockdep_assert_held(&net->nft.commit_mutex);
attr = nla[NFTA_TABLE_NAME];
@@ -1005,6 +1013,7 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk,
return -EINVAL;
}
+
err = -ENOMEM;
table = kzalloc(sizeof(*table), GFP_KERNEL);
if (table == NULL)
@@ -1014,6 +1023,20 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk,
if (table->name == NULL)
goto err_strdup;
+ if (nla[NFTA_TABLE_USERDATA]) {
+ udlen = nla_len(nla[NFTA_TABLE_USERDATA]);
+ table->udata = kzalloc(udlen, GFP_KERNEL);
+ if (table->udata == NULL)
+ goto err_table_udata;
+ } else {
+ table->udata = NULL;
+ }
+
+ if (udlen) {
+ nla_memcpy(table->udata, nla[NFTA_TABLE_USERDATA], udlen);
+ table->udlen = udlen;
+ }
+
err = rhltable_init(&table->chains_ht, &nft_chain_ht_params);
if (err)
goto err_chain_ht;
@@ -1036,6 +1059,8 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk,
err_trans:
rhltable_destroy(&table->chains_ht);
err_chain_ht:
+ kfree(table->udata);
+err_table_udata:
kfree(table->name);
err_strdup:
kfree(table);
--
2.27.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH libnftnl 2/3] table: add userdata support
2020-08-20 8:19 [PATCH 0/3] Add userdata and comment support for tables Jose M. Guisado Gomez
2020-08-20 8:19 ` [PATCH nf-next 1/3] netfilter: nf_tables: add userdata attributes to nft_table Jose M. Guisado Gomez
@ 2020-08-20 8:19 ` Jose M. Guisado Gomez
2020-08-28 17:33 ` Pablo Neira Ayuso
2020-08-20 8:19 ` [PATCH nftables 3/3] src: add comment support when adding tables Jose M. Guisado Gomez
2 siblings, 1 reply; 11+ messages in thread
From: Jose M. Guisado Gomez @ 2020-08-20 8:19 UTC (permalink / raw)
To: netfilter-devel; +Cc: pablo
Signed-off-by: Jose M. Guisado Gomez <guigom@riseup.net>
---
include/libnftnl/table.h | 1 +
include/libnftnl/udata.h | 6 ++++++
include/linux/netfilter/nf_tables.h | 1 +
src/table.c | 33 +++++++++++++++++++++++++++++
4 files changed, 41 insertions(+)
diff --git a/include/libnftnl/table.h b/include/libnftnl/table.h
index 5faec81..a37fba2 100644
--- a/include/libnftnl/table.h
+++ b/include/libnftnl/table.h
@@ -23,6 +23,7 @@ enum nftnl_table_attr {
NFTNL_TABLE_FLAGS,
NFTNL_TABLE_USE,
NFTNL_TABLE_HANDLE,
+ NFTNL_TABLE_USERDATA,
__NFTNL_TABLE_MAX
};
#define NFTNL_TABLE_MAX (__NFTNL_TABLE_MAX - 1)
diff --git a/include/libnftnl/udata.h b/include/libnftnl/udata.h
index efa3f76..ba6b3ab 100644
--- a/include/libnftnl/udata.h
+++ b/include/libnftnl/udata.h
@@ -9,6 +9,12 @@
extern "C" {
#endif
+enum nftnl_udata_table_types {
+ NFTNL_UDATA_TABLE_COMMENT,
+ __NFTNL_UDATA_TABLE_MAX
+};
+#define NFTNL_UDATA_TABLE_MAX (__NFTNL_UDATA_TABLE_MAX - 1)
+
enum nftnl_udata_rule_types {
NFTNL_UDATA_RULE_COMMENT,
NFTNL_UDATA_RULE_EBTABLES_POLICY,
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index d9b0daa..d508154 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -180,6 +180,7 @@ enum nft_table_attributes {
NFTA_TABLE_USE,
NFTA_TABLE_HANDLE,
NFTA_TABLE_PAD,
+ NFTA_TABLE_USERDATA,
__NFTA_TABLE_MAX
};
#define NFTA_TABLE_MAX (__NFTA_TABLE_MAX - 1)
diff --git a/src/table.c b/src/table.c
index 94d522b..731c818 100644
--- a/src/table.c
+++ b/src/table.c
@@ -34,6 +34,10 @@ struct nftnl_table {
uint64_t handle;
uint32_t use;
uint32_t flags;
+ struct {
+ void *data;
+ uint32_t len;
+ } user;
};
EXPORT_SYMBOL(nftnl_table_alloc);
@@ -47,6 +51,8 @@ void nftnl_table_free(const struct nftnl_table *t)
{
if (t->flags & (1 << NFTNL_TABLE_NAME))
xfree(t->name);
+ if (t->flags & (1 << NFTNL_TABLE_USERDATA))
+ xfree(t->user.data);
xfree(t);
}
@@ -111,6 +117,16 @@ int nftnl_table_set_data(struct nftnl_table *t, uint16_t attr,
case NFTNL_TABLE_USE:
memcpy(&t->use, data, sizeof(t->use));
break;
+ case NFTNL_TABLE_USERDATA:
+ if (t->flags & (1 << NFTNL_TABLE_USERDATA))
+ xfree(t->user.data);
+
+ t->user.data = malloc(data_len);
+ if (!t->user.data)
+ return -1;
+ memcpy(t->user.data, data, data_len);
+ t->user.len = data_len;
+ break;
}
t->flags |= (1 << attr);
return 0;
@@ -169,6 +185,9 @@ const void *nftnl_table_get_data(const struct nftnl_table *t, uint16_t attr,
case NFTNL_TABLE_USE:
*data_len = sizeof(uint32_t);
return &t->use;
+ case NFTNL_TABLE_USERDATA:
+ *data_len = t->user.len;
+ return t->user.data;
}
return NULL;
}
@@ -216,6 +235,8 @@ void nftnl_table_nlmsg_build_payload(struct nlmsghdr *nlh, const struct nftnl_ta
mnl_attr_put_u64(nlh, NFTA_TABLE_HANDLE, htobe64(t->handle));
if (t->flags & (1 << NFTNL_TABLE_FLAGS))
mnl_attr_put_u32(nlh, NFTA_TABLE_FLAGS, htonl(t->table_flags));
+ if (t->flags & (1 << NFTNL_TABLE_USERDATA))
+ mnl_attr_put(nlh, NFTA_TABLE_USERDATA, t->user.len, t->user.data);
}
static int nftnl_table_parse_attr_cb(const struct nlattr *attr, void *data)
@@ -240,6 +261,10 @@ static int nftnl_table_parse_attr_cb(const struct nlattr *attr, void *data)
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
abi_breakage();
break;
+ case NFTA_TABLE_USERDATA:
+ if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0)
+ abi_breakage();
+ break;
}
tb[type] = attr;
@@ -251,6 +276,7 @@ int nftnl_table_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_table *t)
{
struct nlattr *tb[NFTA_TABLE_MAX+1] = {};
struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
+ int ret;
if (mnl_attr_parse(nlh, sizeof(*nfg), nftnl_table_parse_attr_cb, tb) < 0)
return -1;
@@ -275,6 +301,13 @@ int nftnl_table_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_table *t)
t->handle = be64toh(mnl_attr_get_u64(tb[NFTA_TABLE_HANDLE]));
t->flags |= (1 << NFTNL_TABLE_HANDLE);
}
+ if (tb[NFTA_TABLE_USERDATA]) {
+ ret = nftnl_table_set_data(t, NFTNL_TABLE_USERDATA,
+ mnl_attr_get_payload(tb[NFTA_TABLE_USERDATA]),
+ mnl_attr_get_payload_len(tb[NFTA_TABLE_USERDATA]));
+ if (ret < 0)
+ return ret;
+ }
t->family = nfg->nfgen_family;
t->flags |= (1 << NFTNL_TABLE_FAMILY);
--
2.27.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH nftables 3/3] src: add comment support when adding tables
2020-08-20 8:19 [PATCH 0/3] Add userdata and comment support for tables Jose M. Guisado Gomez
2020-08-20 8:19 ` [PATCH nf-next 1/3] netfilter: nf_tables: add userdata attributes to nft_table Jose M. Guisado Gomez
2020-08-20 8:19 ` [PATCH libnftnl 2/3] table: add userdata support Jose M. Guisado Gomez
@ 2020-08-20 8:19 ` Jose M. Guisado Gomez
2020-08-21 16:40 ` [PATCH nftables v2 " Jose M. Guisado Gomez
2 siblings, 1 reply; 11+ messages in thread
From: Jose M. Guisado Gomez @ 2020-08-20 8:19 UTC (permalink / raw)
To: netfilter-devel; +Cc: pablo
Adds userdata building logic if a comment is specified when creating a
new table. Adds netlink userdata parsing callback function.
Relies on kernel supporting userdata for nft_table.
Example:
> nft add table ip x { comment "test"\; }
> nft list ruleset
table ip x {
comment "test"
}
Signed-off-by: Jose M. Guisado Gomez <guigom@riseup.net>
---
include/rule.h | 1 +
src/mnl.c | 19 +++++++++--
src/netlink.c | 32 +++++++++++++++++++
src/parser_bison.y | 4 +++
src/rule.c | 5 +++
| 0
| 0
| 0
| 0
9 files changed, 59 insertions(+), 2 deletions(-)
create mode 100755 tests/shell/testcases/optionals/comments_table_0
create mode 100755 tests/shell/testcases/optionals/comments_table_1
create mode 100644 tests/shell/testcases/optionals/dumps/comments_table_0.nft
create mode 100644 tests/shell/testcases/optionals/dumps/comments_table_1.nft
diff --git a/include/rule.h b/include/rule.h
index caca63d0..1167b1fb 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -159,6 +159,7 @@ struct table {
struct list_head chain_bindings;
enum table_flags flags;
unsigned int refcnt;
+ const char *comment;
};
extern struct table *table_alloc(void);
diff --git a/src/mnl.c b/src/mnl.c
index 388eff8f..3bf13991 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -832,22 +832,37 @@ int mnl_nft_table_add(struct netlink_ctx *ctx, struct cmd *cmd,
{
struct nftnl_table *nlt;
struct nlmsghdr *nlh;
+ struct nftnl_udata_buf *udbuf;
nlt = nftnl_table_alloc();
if (nlt == NULL)
memory_allocation_error();
nftnl_table_set_u32(nlt, NFTNL_TABLE_FAMILY, cmd->handle.family);
- if (cmd->table)
+ if (cmd->table) {
nftnl_table_set_u32(nlt, NFTNL_TABLE_FLAGS, cmd->table->flags);
- else
+
+ if (cmd->table->comment) {
+ udbuf = nftnl_udata_buf_alloc(NFT_USERDATA_MAXLEN);
+ if (!udbuf)
+ memory_allocation_error();
+ if (!nftnl_udata_put_strz(udbuf, NFTNL_UDATA_TABLE_COMMENT, cmd->table->comment))
+ memory_allocation_error();
+ nftnl_table_set_data(nlt, NFTNL_TABLE_USERDATA, nftnl_udata_buf_data(udbuf),
+ nftnl_udata_buf_len(udbuf));
+ nftnl_udata_buf_free(udbuf);
+ }
+ }
+ else {
nftnl_table_set_u32(nlt, NFTNL_TABLE_FLAGS, 0);
+ }
nlh = nftnl_nlmsg_build_hdr(nftnl_batch_buffer(ctx->batch),
NFT_MSG_NEWTABLE,
cmd->handle.family,
flags, ctx->seqnum);
+
cmd_add_loc(cmd, nlh->nlmsg_len, &cmd->handle.table.location);
mnl_attr_put_strz(nlh, NFTA_TABLE_NAME, cmd->handle.table.name);
nftnl_table_nlmsg_build_payload(nlh, nlt);
diff --git a/src/netlink.c b/src/netlink.c
index 20b3cdf5..813f33c1 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -583,10 +583,32 @@ int netlink_list_chains(struct netlink_ctx *ctx, const struct handle *h)
return 0;
}
+static int table_parse_udata_cb(const struct nftnl_udata *attr, void *data)
+{
+ unsigned char *value = nftnl_udata_get(attr);
+ const struct nftnl_udata **tb = data;
+ uint8_t type = nftnl_udata_type(attr);
+ uint8_t len = nftnl_udata_len(attr);
+
+ switch (type) {
+ case NFTNL_UDATA_TABLE_COMMENT:
+ if (value[len - 1] != '\0')
+ return -1;
+ break;
+ default:
+ return 0;
+ }
+ tb[type] = attr;
+ return 0;
+}
+
struct table *netlink_delinearize_table(struct netlink_ctx *ctx,
const struct nftnl_table *nlt)
{
struct table *table;
+ const struct nftnl_udata *ud[NFTNL_UDATA_TABLE_MAX + 1] = {};
+ const char *udata;
+ uint32_t ulen;
table = table_alloc();
table->handle.family = nftnl_table_get_u32(nlt, NFTNL_TABLE_FAMILY);
@@ -594,6 +616,16 @@ struct table *netlink_delinearize_table(struct netlink_ctx *ctx,
table->flags = nftnl_table_get_u32(nlt, NFTNL_TABLE_FLAGS);
table->handle.handle.id = nftnl_table_get_u64(nlt, NFTNL_TABLE_HANDLE);
+ if (nftnl_table_is_set(nlt, NFTNL_TABLE_USERDATA)) {
+ udata = nftnl_table_get_data(nlt, NFTNL_TABLE_USERDATA, &ulen);
+ if (nftnl_udata_parse(udata, ulen, table_parse_udata_cb, ud) < 0) {
+ netlink_io_error(ctx, NULL, "Cannot parse userdata");
+ return NULL;
+ }
+ if (ud[NFTNL_UDATA_TABLE_COMMENT])
+ table->comment = xstrdup(nftnl_udata_get(ud[NFTNL_UDATA_TABLE_COMMENT]));
+ }
+
return table;
}
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 7e094ff6..937468c1 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -1533,6 +1533,10 @@ table_options : FLAGS STRING
YYERROR;
}
}
+ | comment_spec
+ {
+ $<table>0->comment = $1;
+ }
;
table_block : /* empty */ { $$ = $<table>-1; }
diff --git a/src/rule.c b/src/rule.c
index 2b5685c2..775e05c2 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -1317,6 +1317,8 @@ void table_free(struct table *table)
if (--table->refcnt > 0)
return;
+ if (table->comment)
+ xfree(table->comment);
list_for_each_entry_safe(chain, next, &table->chains, list)
chain_free(chain);
list_for_each_entry_safe(chain, next, &table->chain_bindings, list)
@@ -1414,6 +1416,9 @@ static void table_print(const struct table *table, struct output_ctx *octx)
nft_print(octx, "\n");
table_print_options(table, &delim, octx);
+ if (table->comment)
+ nft_print(octx, "\tcomment \"%s\"\n", table->comment);
+
list_for_each_entry(obj, &table->objs, list) {
nft_print(octx, "%s", delim);
obj_print(obj, octx);
diff --git a/tests/shell/testcases/optionals/comments_table_0 b/tests/shell/testcases/optionals/comments_table_0
new file mode 100755
index 00000000..e69de29b
diff --git a/tests/shell/testcases/optionals/comments_table_1 b/tests/shell/testcases/optionals/comments_table_1
new file mode 100755
index 00000000..e69de29b
diff --git a/tests/shell/testcases/optionals/dumps/comments_table_0.nft b/tests/shell/testcases/optionals/dumps/comments_table_0.nft
new file mode 100644
index 00000000..e69de29b
diff --git a/tests/shell/testcases/optionals/dumps/comments_table_1.nft b/tests/shell/testcases/optionals/dumps/comments_table_1.nft
new file mode 100644
index 00000000..e69de29b
--
2.27.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH nftables v2 3/3] src: add comment support when adding tables
2020-08-20 8:19 ` [PATCH nftables 3/3] src: add comment support when adding tables Jose M. Guisado Gomez
@ 2020-08-21 16:40 ` Jose M. Guisado Gomez
2020-08-28 17:49 ` Pablo Neira Ayuso
0 siblings, 1 reply; 11+ messages in thread
From: Jose M. Guisado Gomez @ 2020-08-21 16:40 UTC (permalink / raw)
To: netfilter-devel; +Cc: pablo
Adds userdata building logic if a comment is specified when creating a
new table. Adds netlink userdata parsing callback function.
Relies on kernel supporting userdata for nft_table.
Example:
> nft add table ip x { comment "test"\; }
> nft list ruleset
table ip x {
comment "test"
}
Signed-off-by: Jose M. Guisado Gomez <guigom@riseup.net>
---
v2 does not include empty tests file as previous patch version
include/rule.h | 1 +
src/mnl.c | 18 +++++++++--
src/netlink.c | 32 +++++++++++++++++++
src/parser_bison.y | 4 +++
src/rule.c | 5 +++
| 6 ++++
| 3 ++
7 files changed, 67 insertions(+), 2 deletions(-)
create mode 100755 tests/shell/testcases/optionals/comments_table_0
create mode 100644 tests/shell/testcases/optionals/dumps/comments_table_0.nft
diff --git a/include/rule.h b/include/rule.h
index caca63d0..1167b1fb 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -159,6 +159,7 @@ struct table {
struct list_head chain_bindings;
enum table_flags flags;
unsigned int refcnt;
+ const char *comment;
};
extern struct table *table_alloc(void);
diff --git a/src/mnl.c b/src/mnl.c
index 388eff8f..c79d6c4f 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -832,16 +832,30 @@ int mnl_nft_table_add(struct netlink_ctx *ctx, struct cmd *cmd,
{
struct nftnl_table *nlt;
struct nlmsghdr *nlh;
+ struct nftnl_udata_buf *udbuf;
nlt = nftnl_table_alloc();
if (nlt == NULL)
memory_allocation_error();
nftnl_table_set_u32(nlt, NFTNL_TABLE_FAMILY, cmd->handle.family);
- if (cmd->table)
+ if (cmd->table) {
nftnl_table_set_u32(nlt, NFTNL_TABLE_FLAGS, cmd->table->flags);
- else
+
+ if (cmd->table->comment) {
+ udbuf = nftnl_udata_buf_alloc(NFT_USERDATA_MAXLEN);
+ if (!udbuf)
+ memory_allocation_error();
+ if (!nftnl_udata_put_strz(udbuf, NFTNL_UDATA_TABLE_COMMENT, cmd->table->comment))
+ memory_allocation_error();
+ nftnl_table_set_data(nlt, NFTNL_TABLE_USERDATA, nftnl_udata_buf_data(udbuf),
+ nftnl_udata_buf_len(udbuf));
+ nftnl_udata_buf_free(udbuf);
+ }
+ }
+ else {
nftnl_table_set_u32(nlt, NFTNL_TABLE_FLAGS, 0);
+ }
nlh = nftnl_nlmsg_build_hdr(nftnl_batch_buffer(ctx->batch),
NFT_MSG_NEWTABLE,
diff --git a/src/netlink.c b/src/netlink.c
index 20b3cdf5..813f33c1 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -583,10 +583,32 @@ int netlink_list_chains(struct netlink_ctx *ctx, const struct handle *h)
return 0;
}
+static int table_parse_udata_cb(const struct nftnl_udata *attr, void *data)
+{
+ unsigned char *value = nftnl_udata_get(attr);
+ const struct nftnl_udata **tb = data;
+ uint8_t type = nftnl_udata_type(attr);
+ uint8_t len = nftnl_udata_len(attr);
+
+ switch (type) {
+ case NFTNL_UDATA_TABLE_COMMENT:
+ if (value[len - 1] != '\0')
+ return -1;
+ break;
+ default:
+ return 0;
+ }
+ tb[type] = attr;
+ return 0;
+}
+
struct table *netlink_delinearize_table(struct netlink_ctx *ctx,
const struct nftnl_table *nlt)
{
struct table *table;
+ const struct nftnl_udata *ud[NFTNL_UDATA_TABLE_MAX + 1] = {};
+ const char *udata;
+ uint32_t ulen;
table = table_alloc();
table->handle.family = nftnl_table_get_u32(nlt, NFTNL_TABLE_FAMILY);
@@ -594,6 +616,16 @@ struct table *netlink_delinearize_table(struct netlink_ctx *ctx,
table->flags = nftnl_table_get_u32(nlt, NFTNL_TABLE_FLAGS);
table->handle.handle.id = nftnl_table_get_u64(nlt, NFTNL_TABLE_HANDLE);
+ if (nftnl_table_is_set(nlt, NFTNL_TABLE_USERDATA)) {
+ udata = nftnl_table_get_data(nlt, NFTNL_TABLE_USERDATA, &ulen);
+ if (nftnl_udata_parse(udata, ulen, table_parse_udata_cb, ud) < 0) {
+ netlink_io_error(ctx, NULL, "Cannot parse userdata");
+ return NULL;
+ }
+ if (ud[NFTNL_UDATA_TABLE_COMMENT])
+ table->comment = xstrdup(nftnl_udata_get(ud[NFTNL_UDATA_TABLE_COMMENT]));
+ }
+
return table;
}
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 7e094ff6..937468c1 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -1533,6 +1533,10 @@ table_options : FLAGS STRING
YYERROR;
}
}
+ | comment_spec
+ {
+ $<table>0->comment = $1;
+ }
;
table_block : /* empty */ { $$ = $<table>-1; }
diff --git a/src/rule.c b/src/rule.c
index 2b5685c2..775e05c2 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -1317,6 +1317,8 @@ void table_free(struct table *table)
if (--table->refcnt > 0)
return;
+ if (table->comment)
+ xfree(table->comment);
list_for_each_entry_safe(chain, next, &table->chains, list)
chain_free(chain);
list_for_each_entry_safe(chain, next, &table->chain_bindings, list)
@@ -1414,6 +1416,9 @@ static void table_print(const struct table *table, struct output_ctx *octx)
nft_print(octx, "\n");
table_print_options(table, &delim, octx);
+ if (table->comment)
+ nft_print(octx, "\tcomment \"%s\"\n", table->comment);
+
list_for_each_entry(obj, &table->objs, list) {
nft_print(octx, "%s", delim);
obj_print(obj, octx);
--git a/tests/shell/testcases/optionals/comments_table_0 b/tests/shell/testcases/optionals/comments_table_0
new file mode 100755
index 00000000..57d632e6
--- /dev/null
+++ b/tests/shell/testcases/optionals/comments_table_0
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+# comments are shown
+
+$NFT add table test { comment \"test_comment\"\; }
+$NFT -a list table test | grep '\"test_comment\"' >/dev/null
--git a/tests/shell/testcases/optionals/dumps/comments_table_0.nft b/tests/shell/testcases/optionals/dumps/comments_table_0.nft
new file mode 100644
index 00000000..32ae3c2d
--- /dev/null
+++ b/tests/shell/testcases/optionals/dumps/comments_table_0.nft
@@ -0,0 +1,3 @@
+table ip test {
+ comment "test_comment"
+}
--
2.27.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH nf-next 1/3] netfilter: nf_tables: add userdata attributes to nft_table
2020-08-20 8:19 ` [PATCH nf-next 1/3] netfilter: nf_tables: add userdata attributes to nft_table Jose M. Guisado Gomez
@ 2020-08-21 17:21 ` Pablo Neira Ayuso
2020-08-22 9:04 ` Jose M. Guisado
2020-08-22 9:09 ` [PATCH nf-next v2 " Jose M. Guisado Gomez
1 sibling, 1 reply; 11+ messages in thread
From: Pablo Neira Ayuso @ 2020-08-21 17:21 UTC (permalink / raw)
To: Jose M. Guisado Gomez; +Cc: netfilter-devel
On Thu, Aug 20, 2020 at 10:19:01AM +0200, Jose M. Guisado Gomez wrote:
> Enables storing userdata for nft_table. Field udata points to user data
> and udlen store its length.
>
> Adds new attribute flag NFTA_TABLE_USERDATA
>
> Signed-off-by: Jose M. Guisado Gomez <guigom@riseup.net>
> ---
> include/net/netfilter/nf_tables.h | 2 ++
> include/uapi/linux/netfilter/nf_tables.h | 2 ++
> net/netfilter/nf_tables_api.c | 25 ++++++++++++++++++++++++
> 3 files changed, 29 insertions(+)
>
> diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
> index bf9491b77d16..97a7e147a59a 100644
> --- a/include/net/netfilter/nf_tables.h
> +++ b/include/net/netfilter/nf_tables.h
> @@ -1080,6 +1080,8 @@ struct nft_table {
> flags:8,
> genmask:2;
> char *name;
> + u16 udlen;
> + u8 *udata;
> };
>
> void nft_register_chain_type(const struct nft_chain_type *);
> diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
> index 42f351c1f5c5..aeb88cbd303e 100644
> --- a/include/uapi/linux/netfilter/nf_tables.h
> +++ b/include/uapi/linux/netfilter/nf_tables.h
> @@ -172,6 +172,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)
> + * @NFTA_TABLE_USERDATA: user data (NLA_BINARY)
> */
> enum nft_table_attributes {
> NFTA_TABLE_UNSPEC,
> @@ -180,6 +181,7 @@ enum nft_table_attributes {
> NFTA_TABLE_USE,
> NFTA_TABLE_HANDLE,
> NFTA_TABLE_PAD,
> + NFTA_TABLE_USERDATA,
> __NFTA_TABLE_MAX
> };
> #define NFTA_TABLE_MAX (__NFTA_TABLE_MAX - 1)
> diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
> index d878e34e3354..ca240a990eea 100644
> --- a/net/netfilter/nf_tables_api.c
> +++ b/net/netfilter/nf_tables_api.c
> @@ -650,6 +650,8 @@ static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = {
> .len = NFT_TABLE_MAXNAMELEN - 1 },
> [NFTA_TABLE_FLAGS] = { .type = NLA_U32 },
> [NFTA_TABLE_HANDLE] = { .type = NLA_U64 },
> + [NFTA_TABLE_USERDATA] = { .type = NLA_BINARY,
> + .len = NFT_USERDATA_MAXLEN }
> };
>
> static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
> @@ -676,6 +678,11 @@ static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
> NFTA_TABLE_PAD))
> goto nla_put_failure;
>
> + if (table->udata) {
> + if (nla_put(skb, NFTA_TABLE_USERDATA, table->udlen, table->udata))
> + goto nla_put_failure;
> + }
> +
> nlmsg_end(skb, nlh);
> return 0;
>
> @@ -980,6 +987,7 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk,
> u32 flags = 0;
> struct nft_ctx ctx;
> int err;
> + u16 udlen = 0;
>
> lockdep_assert_held(&net->nft.commit_mutex);
> attr = nla[NFTA_TABLE_NAME];
> @@ -1005,6 +1013,7 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk,
> return -EINVAL;
> }
>
> +
> err = -ENOMEM;
> table = kzalloc(sizeof(*table), GFP_KERNEL);
> if (table == NULL)
> @@ -1014,6 +1023,20 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk,
> if (table->name == NULL)
> goto err_strdup;
>
> + if (nla[NFTA_TABLE_USERDATA]) {
> + udlen = nla_len(nla[NFTA_TABLE_USERDATA]);
> + table->udata = kzalloc(udlen, GFP_KERNEL);
> + if (table->udata == NULL)
> + goto err_table_udata;
> + } else {
> + table->udata = NULL;
> + }
> +
> + if (udlen) {
> + nla_memcpy(table->udata, nla[NFTA_TABLE_USERDATA], udlen);
> + table->udlen = udlen;
> + }
if (nla[NFTA_TABLE_USERDATA]) {
udlen = nla_len(nla[NFTA_TABLE_USERDATA]);
table->udata = kzalloc(udlen, GFP_KERNEL);
if (table->udata == NULL)
goto err_table_udata;
nla_memcpy(table->udata, nla[NFTA_TABLE_USERDATA], udlen);
table->udlen = udlen;
}
Probably this simplification instead? kzalloc() zeroes the table
object, so table->udata is NULL and ->udlen is zero.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH nf-next 1/3] netfilter: nf_tables: add userdata attributes to nft_table
2020-08-21 17:21 ` Pablo Neira Ayuso
@ 2020-08-22 9:04 ` Jose M. Guisado
0 siblings, 0 replies; 11+ messages in thread
From: Jose M. Guisado @ 2020-08-22 9:04 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
On 21/8/20 19:21, Pablo Neira Ayuso wrote:
> if (nla[NFTA_TABLE_USERDATA]) {
> udlen = nla_len(nla[NFTA_TABLE_USERDATA]);
> table->udata = kzalloc(udlen, GFP_KERNEL);
> if (table->udata == NULL)
> goto err_table_udata;
>
> nla_memcpy(table->udata, nla[NFTA_TABLE_USERDATA], udlen);
> table->udlen = udlen;
> }
>
> Probably this simplification instead? kzalloc() zeroes the table
> object, so table->udata is NULL and ->udlen is zero.
I see. The reason why I didn't simplify at first was because when using
other nf_tables_new* functions with userdata support as reference (like
newset or newrule), these are checking for userdata length obtained via
nla_len before calling nla_memcpy.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH nf-next v2 1/3] netfilter: nf_tables: add userdata attributes to nft_table
2020-08-20 8:19 ` [PATCH nf-next 1/3] netfilter: nf_tables: add userdata attributes to nft_table Jose M. Guisado Gomez
2020-08-21 17:21 ` Pablo Neira Ayuso
@ 2020-08-22 9:09 ` Jose M. Guisado Gomez
2020-08-28 17:25 ` Pablo Neira Ayuso
1 sibling, 1 reply; 11+ messages in thread
From: Jose M. Guisado Gomez @ 2020-08-22 9:09 UTC (permalink / raw)
To: netfilter-devel; +Cc: pablo
Enables storing userdata for nft_table. Field udata points to user data
and udlen store its length.
Adds new attribute flag NFTA_TABLE_USERDATA
Signed-off-by: Jose M. Guisado Gomez <guigom@riseup.net>
---
include/net/netfilter/nf_tables.h | 2 ++
include/uapi/linux/netfilter/nf_tables.h | 2 ++
net/netfilter/nf_tables_api.c | 20 ++++++++++++++++++++
3 files changed, 24 insertions(+)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index bf9491b77d16..97a7e147a59a 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -1080,6 +1080,8 @@ struct nft_table {
flags:8,
genmask:2;
char *name;
+ u16 udlen;
+ u8 *udata;
};
void nft_register_chain_type(const struct nft_chain_type *);
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 42f351c1f5c5..aeb88cbd303e 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -172,6 +172,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)
+ * @NFTA_TABLE_USERDATA: user data (NLA_BINARY)
*/
enum nft_table_attributes {
NFTA_TABLE_UNSPEC,
@@ -180,6 +181,7 @@ enum nft_table_attributes {
NFTA_TABLE_USE,
NFTA_TABLE_HANDLE,
NFTA_TABLE_PAD,
+ NFTA_TABLE_USERDATA,
__NFTA_TABLE_MAX
};
#define NFTA_TABLE_MAX (__NFTA_TABLE_MAX - 1)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index d878e34e3354..5e9d347780c1 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -650,6 +650,8 @@ static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = {
.len = NFT_TABLE_MAXNAMELEN - 1 },
[NFTA_TABLE_FLAGS] = { .type = NLA_U32 },
[NFTA_TABLE_HANDLE] = { .type = NLA_U64 },
+ [NFTA_TABLE_USERDATA] = { .type = NLA_BINARY,
+ .len = NFT_USERDATA_MAXLEN }
};
static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
@@ -676,6 +678,11 @@ static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
NFTA_TABLE_PAD))
goto nla_put_failure;
+ if (table->udata) {
+ if (nla_put(skb, NFTA_TABLE_USERDATA, table->udlen, table->udata))
+ goto nla_put_failure;
+ }
+
nlmsg_end(skb, nlh);
return 0;
@@ -980,6 +987,7 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk,
u32 flags = 0;
struct nft_ctx ctx;
int err;
+ u16 udlen = 0;
lockdep_assert_held(&net->nft.commit_mutex);
attr = nla[NFTA_TABLE_NAME];
@@ -1014,6 +1022,16 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk,
if (table->name == NULL)
goto err_strdup;
+ if (nla[NFTA_TABLE_USERDATA]) {
+ udlen = nla_len(nla[NFTA_TABLE_USERDATA]);
+ table->udata = kzalloc(udlen, GFP_KERNEL);
+ if (table->udata == NULL)
+ goto err_table_udata;
+
+ nla_memcpy(table->udata, nla[NFTA_TABLE_USERDATA], udlen);
+ table->udlen = udlen;
+ }
+
err = rhltable_init(&table->chains_ht, &nft_chain_ht_params);
if (err)
goto err_chain_ht;
@@ -1036,6 +1054,8 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk,
err_trans:
rhltable_destroy(&table->chains_ht);
err_chain_ht:
+ kfree(table->udata);
+err_table_udata:
kfree(table->name);
err_strdup:
kfree(table);
--
2.27.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH nf-next v2 1/3] netfilter: nf_tables: add userdata attributes to nft_table
2020-08-22 9:09 ` [PATCH nf-next v2 " Jose M. Guisado Gomez
@ 2020-08-28 17:25 ` Pablo Neira Ayuso
0 siblings, 0 replies; 11+ messages in thread
From: Pablo Neira Ayuso @ 2020-08-28 17:25 UTC (permalink / raw)
To: Jose M. Guisado Gomez; +Cc: netfilter-devel
On Sat, Aug 22, 2020 at 11:09:30AM +0200, Jose M. Guisado Gomez wrote:
> Enables storing userdata for nft_table. Field udata points to user data
> and udlen store its length.
>
> Adds new attribute flag NFTA_TABLE_USERDATA
Applied, thanks.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH libnftnl 2/3] table: add userdata support
2020-08-20 8:19 ` [PATCH libnftnl 2/3] table: add userdata support Jose M. Guisado Gomez
@ 2020-08-28 17:33 ` Pablo Neira Ayuso
0 siblings, 0 replies; 11+ messages in thread
From: Pablo Neira Ayuso @ 2020-08-28 17:33 UTC (permalink / raw)
To: Jose M. Guisado Gomez; +Cc: netfilter-devel
Applied, thanks.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH nftables v2 3/3] src: add comment support when adding tables
2020-08-21 16:40 ` [PATCH nftables v2 " Jose M. Guisado Gomez
@ 2020-08-28 17:49 ` Pablo Neira Ayuso
0 siblings, 0 replies; 11+ messages in thread
From: Pablo Neira Ayuso @ 2020-08-28 17:49 UTC (permalink / raw)
To: Jose M. Guisado Gomez; +Cc: netfilter-devel
On Fri, Aug 21, 2020 at 06:40:30PM +0200, Jose M. Guisado Gomez wrote:
> Adds userdata building logic if a comment is specified when creating a
> new table. Adds netlink userdata parsing callback function.
Applied, thanks.
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2020-08-28 17:49 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-20 8:19 [PATCH 0/3] Add userdata and comment support for tables Jose M. Guisado Gomez
2020-08-20 8:19 ` [PATCH nf-next 1/3] netfilter: nf_tables: add userdata attributes to nft_table Jose M. Guisado Gomez
2020-08-21 17:21 ` Pablo Neira Ayuso
2020-08-22 9:04 ` Jose M. Guisado
2020-08-22 9:09 ` [PATCH nf-next v2 " Jose M. Guisado Gomez
2020-08-28 17:25 ` Pablo Neira Ayuso
2020-08-20 8:19 ` [PATCH libnftnl 2/3] table: add userdata support Jose M. Guisado Gomez
2020-08-28 17:33 ` Pablo Neira Ayuso
2020-08-20 8:19 ` [PATCH nftables 3/3] src: add comment support when adding tables Jose M. Guisado Gomez
2020-08-21 16:40 ` [PATCH nftables v2 " Jose M. Guisado Gomez
2020-08-28 17:49 ` 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).