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@xxxxxxxxxxxxx> --- include/rule.h | 2 ++ src/rule.c | 23 +++++++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/include/rule.h b/include/rule.h index f0f7ee33a3ae..cfb76b8a0c10 100644 --- a/include/rule.h +++ b/include/rule.h @@ -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, diff --git a/src/rule.c b/src/rule.c index 227b9f30b91d..1f56faeb5c3c 100644 --- a/src/rule.c +++ b/src/rule.c @@ -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: -- 2.20.1