]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: add CMD_OBJ_SETELEMS
authorPablo Neira Ayuso <pablo@netfilter.org>
Fri, 8 May 2020 12:44:03 +0000 (14:44 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Thu, 14 May 2020 14:53:05 +0000 (16:53 +0200)
This new command type results from expanding the set definition in two
commands: One to add the set and another to add the elements. This
results in 1:1 mapping between the command object to the netlink API.
The command is then translated into a netlink message which gets a
unique sequence number. This sequence number allows to correlate the
netlink extended error reporting with the corresponding command.

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

index f0f7ee33a3ae31e737f4c01e59db927c446785ef..cfb76b8a0c10337b7cdb74bad444438d80f97906 100644 (file)
@@ -561,6 +561,7 @@ enum cmd_ops {
  * @CMD_OBJ_ELEMENTS:  set element(s)
  * @CMD_OBJ_SET:       set
  * @CMD_OBJ_SETS:      multiple sets
+ * @CMD_OBJ_SETELEMS:  set elements
  * @CMD_OBJ_RULE:      rule
  * @CMD_OBJ_CHAIN:     chain
  * @CMD_OBJ_CHAINS:    multiple chains
@@ -588,6 +589,7 @@ enum cmd_obj {
        CMD_OBJ_INVALID,
        CMD_OBJ_ELEMENTS,
        CMD_OBJ_SET,
+       CMD_OBJ_SETELEMS,
        CMD_OBJ_SETS,
        CMD_OBJ_RULE,
        CMD_OBJ_CHAIN,
index 227b9f30b91d9a4eaca59dcc48674eeb4011c0ae..1f56faeb5c3cf03484e783eac4c8cb5c2055b713 100644 (file)
@@ -1417,11 +1417,11 @@ void cmd_add_loc(struct cmd *cmd, uint16_t offset, struct location *loc)
 void nft_cmd_expand(struct cmd *cmd)
 {
        struct list_head new_cmds;
+       struct set *set, *newset;
        struct flowtable *ft;
        struct table *table;
        struct chain *chain;
        struct rule *rule;
-       struct set *set;
        struct obj *obj;
        struct cmd *new;
        struct handle h;
@@ -1477,6 +1477,18 @@ void nft_cmd_expand(struct cmd *cmd)
                }
                list_splice(&new_cmds, &cmd->list);
                break;
+       case CMD_OBJ_SET:
+               set = cmd->set;
+               memset(&h, 0, sizeof(h));
+               handle_merge(&h, &set->handle);
+               newset = set_clone(set);
+               newset->handle.set_id = set->handle.set_id;
+               newset->init = set->init;
+               set->init = NULL;
+               new = cmd_alloc(CMD_ADD, CMD_OBJ_SETELEMS, &h,
+                               &set->location, newset);
+               list_add(&new->list, &cmd->list);
+               break;
        default:
                break;
        }
@@ -1525,6 +1537,7 @@ void cmd_free(struct cmd *cmd)
                        expr_free(cmd->expr);
                        break;
                case CMD_OBJ_SET:
+               case CMD_OBJ_SETELEMS:
                        set_free(cmd->set);
                        break;
                case CMD_OBJ_RULE:
@@ -1610,7 +1623,7 @@ static int do_add_setelems(struct netlink_ctx *ctx, struct cmd *cmd,
 }
 
 static int do_add_set(struct netlink_ctx *ctx, struct cmd *cmd,
-                     uint32_t flags)
+                     uint32_t flags, bool add)
 {
        struct set *set = cmd->set;
 
@@ -1621,7 +1634,7 @@ static int do_add_set(struct netlink_ctx *ctx, struct cmd *cmd,
                                     &ctx->nft->output) < 0)
                        return -1;
        }
-       if (mnl_nft_set_add(ctx, cmd, flags) < 0)
+       if (add && mnl_nft_set_add(ctx, cmd, flags) < 0)
                return -1;
        if (set->init != NULL) {
                return __do_add_setelems(ctx, set, set->init, flags);
@@ -1644,7 +1657,9 @@ static int do_command_add(struct netlink_ctx *ctx, struct cmd *cmd, bool excl)
        case CMD_OBJ_RULE:
                return mnl_nft_rule_add(ctx, cmd, flags | NLM_F_APPEND);
        case CMD_OBJ_SET:
-               return do_add_set(ctx, cmd, flags);
+               return do_add_set(ctx, cmd, flags, true);
+       case CMD_OBJ_SETELEMS:
+               return do_add_set(ctx, cmd, flags, false);
        case CMD_OBJ_ELEMENTS:
                return do_add_setelems(ctx, cmd, flags);
        case CMD_OBJ_COUNTER: