diff options
author | Jose M. Guisado Gomez <guigom@riseup.net> | 2020-08-21 18:40:30 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2020-08-28 19:48:20 +0200 |
commit | c156232a530b30b6668712eda22bc491b0900283 (patch) | |
tree | 96a5bbe49f6eb483dca2d57f743c95a5129cc082 /src | |
parent | fbd8fb09c50bcee3f046dce2281f25baa4e14927 (diff) |
src: add comment support when adding tables
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>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-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 |
4 files changed, 56 insertions, 2 deletions
@@ -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); |