[PATCH nft] src: add comment support for set declarations

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Allow users to add a comment when declaring a named set.

Adds set output handling the comment in both nftables and json
format.

$ nft add table ip x
$ nft add set ip x s {type ipv4_addr\; comment "some_addrs"\; elements = {1.1.1.1, 1.2.3.4}}

$ nft list ruleset
table ip x {
	set s {
		type ipv4_addr;
		comment "some_addrs"
		elements = { 1.1.1.1, 1.2.3.4 }
	}
}

$ nft --json list ruleset
{
    "nftables": [
        {
            "metainfo": {
                "json_schema_version": 1,
                "release_name": "Capital Idea #2",
                "version": "0.9.6"
            }
        },
        {
            "table": {
                "family": "ip",
                "handle": 4857,
                "name": "x"
            }
        },
        {
            "set": {
                "comment": "some_addrs",
                "elem": [
                    "1.1.1.1",
                    "1.2.3.4"
                ],
                "family": "ip",
                "handle": 1,
                "name": "s",
                "table": "x",
                "type": "ipv4_addr"
            }
        }
    ]
}

Signed-off-by: Jose M. Guisado Gomez <guigom@xxxxxxxxxx>
---
 include/rule.h                                        |  2 ++
 src/json.c                                            |  3 +++
 src/mnl.c                                             |  5 +++++
 src/netlink.c                                         | 11 ++++++++++-
 src/parser_bison.y                                    |  5 +++++
 src/rule.c                                            |  9 +++++++++
 tests/shell/testcases/sets/0054comments_set_0         | 11 +++++++++++
 .../shell/testcases/sets/dumps/0054comments_set_0.nft |  7 +++++++
 8 files changed, 52 insertions(+), 1 deletion(-)
 create mode 100755 tests/shell/testcases/sets/0054comments_set_0
 create mode 100644 tests/shell/testcases/sets/dumps/0054comments_set_0.nft

diff --git a/include/rule.h b/include/rule.h
index 60eadfa3..caca63d0 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -309,6 +309,7 @@ void rule_stmt_insert_at(struct rule *rule, struct stmt *nstmt,
  * @rg_cache:	cached range element (left)
  * @policy:	set mechanism policy
  * @automerge:	merge adjacents and overlapping elements, if possible
+ * @comment:	comment
  * @desc.size:		count of set elements
  * @desc.field_len:	length of single concatenated fields, bytes
  * @desc.field_count:	count of concatenated fields
@@ -331,6 +332,7 @@ struct set {
 	bool			root;
 	bool			automerge;
 	bool			key_typeof_valid;
+	const char		*comment;
 	struct {
 		uint32_t	size;
 		uint8_t		field_len[NFT_REG32_COUNT];
diff --git a/src/json.c b/src/json.c
index 888cb371..a9f5000f 100644
--- a/src/json.c
+++ b/src/json.c
@@ -98,6 +98,9 @@ static json_t *set_print_json(struct output_ctx *octx, const struct set *set)
 			"table", set->handle.table.name,
 			"type", set_dtype_json(set->key),
 			"handle", set->handle.handle.id);
+
+	if (set->comment)
+		json_object_set_new(root, "comment", json_string(set->comment));
 	if (datatype_ext)
 		json_object_set_new(root, "map", json_string(datatype_ext));
 
diff --git a/src/mnl.c b/src/mnl.c
index e5e88f3b..5e2994c2 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -1042,6 +1042,11 @@ int mnl_nft_set_add(struct netlink_ctx *ctx, struct cmd *cmd,
 				   sizeof(set->desc.field_len[0]));
 	}
 
+	if (set->comment) {
+		if (!nftnl_udata_put_strz(udbuf, NFTNL_UDATA_SET_COMMENT, set->comment))
+				memory_allocation_error();
+	}
+
 	nftnl_set_set_data(nls, NFTNL_SET_USERDATA, nftnl_udata_buf_data(udbuf),
 			   nftnl_udata_buf_len(udbuf));
 	nftnl_udata_buf_free(udbuf);
diff --git a/src/netlink.c b/src/netlink.c
index 2f1dbe17..3afb3095 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -664,6 +664,7 @@ static int set_parse_udata_cb(const struct nftnl_udata *attr, void *data)
 	const struct nftnl_udata **tb = data;
 	uint8_t type = nftnl_udata_type(attr);
 	uint8_t len = nftnl_udata_len(attr);
+	unsigned char *value = nftnl_udata_get(attr);
 
 	switch (type) {
 	case NFTNL_UDATA_SET_KEYBYTEORDER:
@@ -678,6 +679,10 @@ static int set_parse_udata_cb(const struct nftnl_udata *attr, void *data)
 		if (len < 3)
 			return -1;
 		break;
+	case NFTNL_UDATA_SET_COMMENT:
+		if (value[len - 1] != '\0')
+			return -1;
+		break;
 	default:
 		return 0;
 	}
@@ -755,7 +760,7 @@ struct set *netlink_delinearize_set(struct netlink_ctx *ctx,
 	const struct datatype *dtype;
 	uint32_t data_interval = 0;
 	bool automerge = false;
-	const char *udata;
+	const char *udata, *comment = NULL;
 	struct set *set;
 	uint32_t ulen;
 	uint32_t klen;
@@ -783,6 +788,8 @@ struct set *netlink_delinearize_set(struct netlink_ctx *ctx,
 		typeof_expr_key = set_make_key(ud[NFTNL_UDATA_SET_KEY_TYPEOF]);
 		if (ud[NFTNL_UDATA_SET_DATA_TYPEOF])
 			typeof_expr_data = set_make_key(ud[NFTNL_UDATA_SET_DATA_TYPEOF]);
+		if (ud[NFTNL_UDATA_SET_COMMENT])
+			comment = xstrdup(nftnl_udata_get(ud[NFTNL_UDATA_SET_COMMENT]));
 	}
 
 	key = nftnl_set_get_u32(nls, NFTNL_SET_KEY_TYPE);
@@ -819,6 +826,8 @@ struct set *netlink_delinearize_set(struct netlink_ctx *ctx,
 	set->handle.table.name = xstrdup(nftnl_set_get_str(nls, NFTNL_SET_TABLE));
 	set->handle.set.name = xstrdup(nftnl_set_get_str(nls, NFTNL_SET_NAME));
 	set->automerge	   = automerge;
+	if (comment)
+		set->comment = comment;
 
 	if (nftnl_set_is_set(nls, NFTNL_SET_EXPR)) {
 		const struct nftnl_expr *nle;
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 167c3158..7e094ff6 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -1768,6 +1768,11 @@ set_block		:	/* empty */	{ $$ = $<set>-1; }
 				$$ = $1;
 			}
 			|	set_block	set_mechanism	stmt_separator
+			|	set_block	comment_spec	stmt_separator
+			{
+				$1->comment = $2;
+				$$ = $1;
+			}
 			;
 
 set_block_expr		:	set_expr
diff --git a/src/rule.c b/src/rule.c
index 6335aa21..e288c38c 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -361,6 +361,8 @@ void set_free(struct set *set)
 		return;
 	if (set->init != NULL)
 		expr_free(set->init);
+	if (set->comment)
+		xfree(set->comment);
 	handle_free(&set->handle);
 	stmt_free(set->stmt);
 	expr_free(set->key);
@@ -578,6 +580,13 @@ static void set_print_declaration(const struct set *set,
 		time_print(set->gc_int, octx);
 		nft_print(octx, "%s", opts->stmt_separator);
 	}
+
+	if (set->comment) {
+		nft_print(octx, "%s%scomment \"%s\"%s",
+			  opts->tab, opts->tab,
+			  set->comment,
+			  opts->stmt_separator);
+	}
 }
 
 static void do_set_print(const struct set *set, struct print_fmt_options *opts,
diff --git a/tests/shell/testcases/sets/0054comments_set_0 b/tests/shell/testcases/sets/0054comments_set_0
new file mode 100755
index 00000000..93a73f0d
--- /dev/null
+++ b/tests/shell/testcases/sets/0054comments_set_0
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+# Test that comments are added to sets
+
+$NFT add table t
+$NFT add set t s {type ipv4_addr \; flags interval \; comment "test" \;}
+if ! $NFT list ruleset | grep test >/dev/null ; then
+	echo "E: missing comment in set" >&2
+	exit 1
+fi
+
diff --git a/tests/shell/testcases/sets/dumps/0054comments_set_0.nft b/tests/shell/testcases/sets/dumps/0054comments_set_0.nft
new file mode 100644
index 00000000..2ad84003
--- /dev/null
+++ b/tests/shell/testcases/sets/dumps/0054comments_set_0.nft
@@ -0,0 +1,7 @@
+table ip t {
+	set s {
+		type ipv4_addr
+		flags interval
+		comment "test"
+	}
+}
-- 
2.27.0




[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux