]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: set on flags to request multi-statement support
authorPablo Neira Ayuso <pablo@netfilter.org>
Mon, 4 Jan 2021 20:24:47 +0000 (21:24 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 4 Jan 2021 20:24:47 +0000 (21:24 +0100)
Old kernel reject requests for element with multiple statements because
userspace sets on the flags for multi-statements.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/linux/netfilter/nf_tables.h
src/evaluate.c
src/netlink_linearize.c

index 0b5fd5d52bb6e26318774aaf84a475328d1abfb1..4ecf457f7317da28f75f67f01abfd8fb5b23d456 100644 (file)
@@ -279,6 +279,7 @@ enum nft_rule_compat_attributes {
  * @NFT_SET_EVAL: set can be updated from the evaluation path
  * @NFT_SET_OBJECT: set contains stateful objects
  * @NFT_SET_CONCAT: set contains a concatenation
+ * @NFT_SET_EXPR: set contains expressions
  */
 enum nft_set_flags {
        NFT_SET_ANONYMOUS               = 0x1,
@@ -289,6 +290,7 @@ enum nft_set_flags {
        NFT_SET_EVAL                    = 0x20,
        NFT_SET_OBJECT                  = 0x40,
        NFT_SET_CONCAT                  = 0x80,
+       NFT_SET_EXPR                    = 0x100,
 };
 
 /**
@@ -686,6 +688,7 @@ enum nft_dynset_ops {
 
 enum nft_dynset_flags {
        NFT_DYNSET_F_INV        = (1 << 0),
+       NFT_DYNSET_F_EXPR       = (1 << 1),
 };
 
 /**
index ab9357fa2ede4a8634f2f47465cac3f06b7c9842..38dbc33d7826bb5cb8c129e06706db834737cf5b 100644 (file)
@@ -3671,7 +3671,9 @@ static int set_key_data_error(struct eval_ctx *ctx, const struct set *set,
 
 static int set_evaluate(struct eval_ctx *ctx, struct set *set)
 {
+       unsigned int num_stmts = 0;
        struct table *table;
+       struct stmt *stmt;
        const char *type;
 
        table = table_lookup_global(ctx);
@@ -3732,6 +3734,12 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set)
        if (set->timeout)
                set->flags |= NFT_SET_TIMEOUT;
 
+       list_for_each_entry(stmt, &set->stmt_list, list)
+               num_stmts++;
+
+       if (num_stmts > 1)
+               set->flags |= NFT_SET_EXPR;
+
        if (set_is_anonymous(set->flags))
                return 0;
 
index 09d0c61cfcc066f304ad7bd9c073ad9b45b4c55e..f1b3ff6940eaaa8c011d0eda990ba2de6a8d0be2 100644 (file)
@@ -1429,6 +1429,8 @@ static void netlink_gen_set_stmt(struct netlink_linearize_ctx *ctx,
                        nftnl_expr_add_expr(nle, NFTNL_EXPR_DYNSET_EXPRESSIONS,
                                            netlink_gen_stmt_stateful(this));
                }
+               nftnl_expr_set_u32(nle, NFTNL_EXPR_DYNSET_FLAGS,
+                                  NFT_DYNSET_F_EXPR);
        }
 }