summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/rule.h1
-rw-r--r--src/mnl.c11
-rw-r--r--src/netlink.c32
-rw-r--r--src/parser_bison.y8
-rw-r--r--src/rule.c3
-rwxr-xr-xtests/shell/testcases/optionals/comments_chain_012
-rw-r--r--tests/shell/testcases/optionals/dumps/comments_chain_0.nft5
7 files changed, 72 insertions, 0 deletions
diff --git a/include/rule.h b/include/rule.h
index 837005b1..ffe8daab 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -225,6 +225,7 @@ struct chain {
struct location location;
unsigned int refcnt;
uint32_t flags;
+ const char *comment;
struct {
struct location loc;
struct prio_spec priority;
diff --git a/src/mnl.c b/src/mnl.c
index 6699b917..adb55d4d 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -601,6 +601,7 @@ err:
int mnl_nft_chain_add(struct netlink_ctx *ctx, struct cmd *cmd,
unsigned int flags)
{
+ struct nftnl_udata_buf *udbuf;
int priority, policy, i = 0;
struct nftnl_chain *nlc;
unsigned int ifname_len;
@@ -661,6 +662,16 @@ int mnl_nft_chain_add(struct netlink_ctx *ctx, struct cmd *cmd,
xfree(dev_array);
}
+ if (cmd->chain->comment) {
+ udbuf = nftnl_udata_buf_alloc(NFT_USERDATA_MAXLEN);
+ if (!udbuf)
+ memory_allocation_error();
+ if (!nftnl_udata_put_strz(udbuf, NFTNL_UDATA_CHAIN_COMMENT, cmd->chain->comment))
+ memory_allocation_error();
+ nftnl_chain_set_data(nlc, NFTNL_CHAIN_USERDATA, nftnl_udata_buf_data(udbuf),
+ nftnl_udata_buf_len(udbuf));
+ nftnl_udata_buf_free(udbuf);
+ }
}
netlink_dump_chain(nlc, ctx);
diff --git a/src/netlink.c b/src/netlink.c
index 6912b018..f8ac2b9e 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -472,12 +472,34 @@ void netlink_dump_chain(const struct nftnl_chain *nlc, struct netlink_ctx *ctx)
fprintf(fp, "\n");
}
+static int chain_parse_udata_cb(const struct nftnl_udata *attr, void *data)
+{
+ unsigned char *value = nftnl_udata_get(attr);
+ uint8_t type = nftnl_udata_type(attr);
+ const struct nftnl_udata **tb = data;
+ uint8_t len = nftnl_udata_len(attr);
+
+ switch (type) {
+ case NFTNL_UDATA_CHAIN_COMMENT:
+ if (value[len - 1] != '\0')
+ return -1;
+ break;
+ default:
+ return 0;
+ }
+ tb[type] = attr;
+ return 0;
+}
+
struct chain *netlink_delinearize_chain(struct netlink_ctx *ctx,
const struct nftnl_chain *nlc)
{
+ const struct nftnl_udata *ud[NFTNL_UDATA_OBJ_MAX + 1] = {};
int priority, policy, len = 0, i;
const char * const *dev_array;
struct chain *chain;
+ const char *udata;
+ uint32_t ulen;
chain = chain_alloc(nftnl_chain_get_str(nlc, NFTNL_CHAIN_NAME));
chain->handle.family =
@@ -534,6 +556,16 @@ struct chain *netlink_delinearize_chain(struct netlink_ctx *ctx,
chain->flags |= CHAIN_F_BASECHAIN;
}
+ if (nftnl_chain_is_set(nlc, NFTNL_CHAIN_USERDATA)) {
+ udata = nftnl_chain_get_data(nlc, NFTNL_CHAIN_USERDATA, &ulen);
+ if (nftnl_udata_parse(udata, ulen, chain_parse_udata_cb, ud) < 0) {
+ netlink_io_error(ctx, NULL, "Cannot parse userdata");
+ return NULL;
+ }
+ if (ud[NFTNL_UDATA_CHAIN_COMMENT])
+ chain->comment = xstrdup(nftnl_udata_get(ud[NFTNL_UDATA_CHAIN_COMMENT]));
+ }
+
return chain;
}
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 524903fd..9bf4f71f 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -1723,6 +1723,14 @@ chain_block : /* empty */ { $$ = $<chain>-1; }
list_add_tail(&$2->list, &$1->rules);
$$ = $1;
}
+ | chain_block comment_spec stmt_separator
+ {
+ if (already_set($1->comment, &@2, state)) {
+ xfree($2);
+ YYERROR;
+ }
+ $1->comment = $2;
+ }
;
subchain_block : /* empty */ { $$ = $<chain>-1; }
diff --git a/src/rule.c b/src/rule.c
index dabb3579..d75b36c4 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -929,6 +929,7 @@ void chain_free(struct chain *chain)
xfree(chain->dev_array);
expr_free(chain->priority.expr);
expr_free(chain->policy);
+ xfree(chain->comment);
xfree(chain);
}
@@ -1220,6 +1221,8 @@ static void chain_print_declaration(const struct chain *chain,
nft_print(octx, "\tchain %s {", chain->handle.chain.name);
if (nft_output_handle(octx))
nft_print(octx, " # handle %" PRIu64, chain->handle.handle.id);
+ if (chain->comment)
+ nft_print(octx, "\n\t\tcomment \"%s\"", chain->comment);
nft_print(octx, "\n");
if (chain->flags & CHAIN_F_BASECHAIN) {
nft_print(octx, "\t\ttype %s hook %s", chain->type,
diff --git a/tests/shell/testcases/optionals/comments_chain_0 b/tests/shell/testcases/optionals/comments_chain_0
new file mode 100755
index 00000000..fba961c7
--- /dev/null
+++ b/tests/shell/testcases/optionals/comments_chain_0
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+EXPECTED='table ip test_table {
+ chain test_chain {
+ comment "test"
+ }
+}
+'
+
+set -e
+
+$NFT -f - <<< "$EXPECTED"
diff --git a/tests/shell/testcases/optionals/dumps/comments_chain_0.nft b/tests/shell/testcases/optionals/dumps/comments_chain_0.nft
new file mode 100644
index 00000000..be3d8f33
--- /dev/null
+++ b/tests/shell/testcases/optionals/dumps/comments_chain_0.nft
@@ -0,0 +1,5 @@
+table ip test_table {
+ chain test_chain {
+ comment "test"
+ }
+}