diff options
-rw-r--r-- | include/rule.h | 1 | ||||
-rw-r--r-- | src/mnl.c | 17 | ||||
-rw-r--r-- | src/netlink.c | 32 | ||||
-rw-r--r-- | src/parser_bison.y | 4 | ||||
-rw-r--r-- | src/rule.c | 5 | ||||
-rwxr-xr-x | tests/shell/testcases/optionals/comments_table_0 | 5 | ||||
-rw-r--r-- | tests/shell/testcases/optionals/dumps/comments_table_0.nft | 3 |
7 files changed, 65 insertions, 2 deletions
diff --git a/include/rule.h b/include/rule.h index 62d25be2..56f1951f 100644 --- a/include/rule.h +++ b/include/rule.h @@ -162,6 +162,7 @@ struct table { struct list_head chain_bindings; enum table_flags flags; unsigned int refcnt; + const char *comment; }; extern struct table *table_alloc(void); @@ -830,6 +830,7 @@ err: int mnl_nft_table_add(struct netlink_ctx *ctx, struct cmd *cmd, unsigned int flags) { + struct nftnl_udata_buf *udbuf; struct nftnl_table *nlt; struct nlmsghdr *nlh; @@ -838,10 +839,22 @@ int mnl_nft_table_add(struct netlink_ctx *ctx, struct cmd *cmd, 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 0db5e175..a107f492 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -537,10 +537,32 @@ struct chain *netlink_delinearize_chain(struct netlink_ctx *ctx, return chain; } +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) { + const struct nftnl_udata *ud[NFTNL_UDATA_TABLE_MAX + 1] = {}; struct table *table; + const char *udata; + uint32_t ulen; table = table_alloc(); table->handle.family = nftnl_table_get_u32(nlt, NFTNL_TABLE_FAMILY); @@ -548,6 +570,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 d4e99417..95adc48f 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; } @@ -1324,6 +1324,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) @@ -1422,6 +1424,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..a0dfd749 --- /dev/null +++ b/tests/shell/testcases/optionals/comments_table_0 @@ -0,0 +1,5 @@ +#!/bin/bash + +# comments are shown + +$NFT add table test { comment \"test_comment\"\; } 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..32ae3c2d --- /dev/null +++ b/tests/shell/testcases/optionals/dumps/comments_table_0.nft @@ -0,0 +1,3 @@ +table ip test { + comment "test_comment" +} |