]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: add comment support for set declarations
authorJose M. Guisado Gomez <guigom@riseup.net>
Tue, 11 Aug 2020 14:27:20 +0000 (16:27 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 12 Aug 2020 14:13:28 +0000 (16:13 +0200)
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@riseup.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/rule.h
src/json.c
src/mnl.c
src/netlink.c
src/parser_bison.y
src/rule.c
tests/shell/testcases/sets/0054comments_set_0 [new file with mode: 0755]
tests/shell/testcases/sets/dumps/0054comments_set_0.nft [new file with mode: 0644]

index 60eadfa3c9a26e8fa1d8fb627c2d0654c9c0478d..caca63d0f6485a1a989d3b380294c3610c0ca711 100644 (file)
@@ -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];
index 888cb371e971d122aa8b4b30935c3d386755cb6e..a9f5000fe6d7cb2a992713466c5c64a8d5766340 100644 (file)
@@ -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));
 
index e5e88f3bd990a3a5ec06c0bee23a5fb7eff2e811..388eff8fa4ccb5eae08789760caabbae3fd62dfa 100644 (file)
--- 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);
index 2f1dbe179ed590b0447cf0530859f4e9ca71bf70..20b3cdf5e46928d1cbe3042a54f46d94e1e463fb 100644 (file)
@@ -661,6 +661,7 @@ void netlink_dump_set(const struct nftnl_set *nls, struct netlink_ctx *ctx)
 
 static int set_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);
@@ -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;
        }
@@ -751,11 +756,11 @@ struct set *netlink_delinearize_set(struct netlink_ctx *ctx,
        enum byteorder databyteorder = BYTEORDER_INVALID;
        const struct datatype *keytype, *datatype = NULL;
        struct expr *typeof_expr_key, *typeof_expr_data;
+       const char *udata, *comment = NULL;
        uint32_t flags, key, objtype = 0;
        const struct datatype *dtype;
        uint32_t data_interval = 0;
        bool automerge = false;
-       const char *udata;
        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;
index 167c315810ed5194b8a3fd1c2a6c74611b4fe848..7e094ff60eac805dd4effbf7e686f8583b7f8e66 100644 (file)
@@ -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
index 8dc1792b4e5a235b838959474098c8a71ae849d5..2b5685c23e54b6634017bc26460473b78683b37d 100644 (file)
@@ -367,6 +367,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);
@@ -584,6 +586,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 (executable)
index 0000000..93a73f0
--- /dev/null
@@ -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 (file)
index 0000000..2ad8400
--- /dev/null
@@ -0,0 +1,7 @@
+table ip t {
+       set s {
+               type ipv4_addr
+               flags interval
+               comment "test"
+       }
+}