From ac4b25b3ca045fbbed86773a91da52d9d7ee3091 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 28 Jul 2020 17:57:20 +0200 Subject: src: remove cache lookups after the evaluation phase This patch adds a new field to the cmd structure for elements to store a reference to the set. This saves an extra lookup in the netlink bytecode generation step. This patch also allows to incrementally update during the evaluation phase according to the command actions, which is required by the follow up ("evaluate: remove table from cache on delete table") bugfix patch. Signed-off-by: Pablo Neira Ayuso --- include/expression.h | 2 +- include/netlink.h | 2 +- include/rule.h | 4 ++++ src/evaluate.c | 13 ++++++++----- src/netlink.c | 4 ++-- src/rule.c | 44 ++++++++++++++++++-------------------------- src/segtree.c | 17 ++++++----------- 7 files changed, 40 insertions(+), 46 deletions(-) diff --git a/include/expression.h b/include/expression.h index 0210a3cb..130912a8 100644 --- a/include/expression.h +++ b/include/expression.h @@ -479,7 +479,7 @@ extern void interval_map_decompose(struct expr *set); extern struct expr *get_set_intervals(const struct set *set, const struct expr *init); struct table; -extern int get_set_decompose(struct table *table, struct set *set); +extern int get_set_decompose(struct set *cache_set, struct set *set); extern struct expr *mapping_expr_alloc(const struct location *loc, struct expr *from, struct expr *to); diff --git a/include/netlink.h b/include/netlink.h index 14fcec16..1077096e 100644 --- a/include/netlink.h +++ b/include/netlink.h @@ -149,7 +149,7 @@ extern struct stmt *netlink_parse_set_expr(const struct set *set, extern int netlink_list_setelems(struct netlink_ctx *ctx, const struct handle *h, struct set *set); extern int netlink_get_setelem(struct netlink_ctx *ctx, const struct handle *h, - const struct location *loc, struct table *table, + const struct location *loc, struct set *cache_set, struct set *set, struct expr *init); extern int netlink_delinearize_setelem(struct nftnl_set_elem *nlse, struct set *set, diff --git a/include/rule.h b/include/rule.h index 4de7a0d9..60eadfa3 100644 --- a/include/rule.h +++ b/include/rule.h @@ -683,6 +683,10 @@ struct cmd { void *data; struct expr *expr; struct set *set; + struct { + struct expr *expr; /* same offset as cmd->expr */ + struct set *set; + } elem; struct rule *rule; struct chain *chain; struct table *table; diff --git a/src/evaluate.c b/src/evaluate.c index bb504962..26d73959 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -3560,7 +3560,7 @@ int stmt_evaluate(struct eval_ctx *ctx, struct stmt *stmt) } } -static int setelem_evaluate(struct eval_ctx *ctx, struct expr **expr) +static int setelem_evaluate(struct eval_ctx *ctx, struct cmd *cmd) { struct table *table; struct set *set; @@ -3576,9 +3576,12 @@ static int setelem_evaluate(struct eval_ctx *ctx, struct expr **expr) ctx->set = set; expr_set_context(&ctx->ectx, set->key->dtype, set->key->len); - if (expr_evaluate(ctx, expr) < 0) + if (expr_evaluate(ctx, &cmd->expr) < 0) return -1; ctx->set = NULL; + + cmd->elem.set = set_get(set); + return 0; } @@ -4141,7 +4144,7 @@ static int cmd_evaluate_add(struct eval_ctx *ctx, struct cmd *cmd) { switch (cmd->obj) { case CMD_OBJ_ELEMENTS: - return setelem_evaluate(ctx, &cmd->expr); + return setelem_evaluate(ctx, cmd); case CMD_OBJ_SET: handle_merge(&cmd->set->handle, &cmd->handle); return set_evaluate(ctx, cmd->set); @@ -4173,7 +4176,7 @@ static int cmd_evaluate_delete(struct eval_ctx *ctx, struct cmd *cmd) { switch (cmd->obj) { case CMD_OBJ_ELEMENTS: - return setelem_evaluate(ctx, &cmd->expr); + return setelem_evaluate(ctx, cmd); case CMD_OBJ_SET: case CMD_OBJ_RULE: case CMD_OBJ_CHAIN: @@ -4197,7 +4200,7 @@ static int cmd_evaluate_get(struct eval_ctx *ctx, struct cmd *cmd) { switch (cmd->obj) { case CMD_OBJ_ELEMENTS: - return setelem_evaluate(ctx, &cmd->expr); + return setelem_evaluate(ctx, cmd); default: BUG("invalid command object type %u\n", cmd->obj); } diff --git a/src/netlink.c b/src/netlink.c index b57e1c55..2f1dbe17 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -1228,7 +1228,7 @@ int netlink_list_setelems(struct netlink_ctx *ctx, const struct handle *h, } int netlink_get_setelem(struct netlink_ctx *ctx, const struct handle *h, - const struct location *loc, struct table *table, + const struct location *loc, struct set *cache_set, struct set *set, struct expr *init) { struct nftnl_set *nls, *nls_out = NULL; @@ -1261,7 +1261,7 @@ int netlink_get_setelem(struct netlink_ctx *ctx, const struct handle *h, if (set->flags & NFT_SET_INTERVAL && set->desc.field_count > 1) concat_range_aggregate(set->init); else if (set->flags & NFT_SET_INTERVAL) - err = get_set_decompose(table, set); + err = get_set_decompose(cache_set, set); else list_expr_sort(&ctx->set->init->expressions); diff --git a/src/rule.c b/src/rule.c index 65973ccb..fed9e123 100644 --- a/src/rule.c +++ b/src/rule.c @@ -1577,6 +1577,8 @@ void cmd_free(struct cmd *cmd) switch (cmd->obj) { case CMD_OBJ_ELEMENTS: expr_free(cmd->expr); + if (cmd->elem.set) + set_free(cmd->elem.set); break; case CMD_OBJ_SET: case CMD_OBJ_SETELEMS: @@ -1647,13 +1649,8 @@ static int __do_add_setelems(struct netlink_ctx *ctx, struct set *set, static int do_add_setelems(struct netlink_ctx *ctx, struct cmd *cmd, uint32_t flags) { - struct handle *h = &cmd->handle; struct expr *init = cmd->expr; - struct table *table; - struct set *set; - - table = table_lookup(h, &ctx->nft->cache); - set = set_lookup(table, h->set.name); + struct set *set = cmd->elem.set; if (set_is_non_concat_range(set) && set_to_intervals(ctx->msgs, set, init, true, @@ -1750,13 +1747,8 @@ static int do_command_insert(struct netlink_ctx *ctx, struct cmd *cmd) static int do_delete_setelems(struct netlink_ctx *ctx, struct cmd *cmd) { - struct handle *h = &cmd->handle; - struct expr *expr = cmd->expr; - struct table *table; - struct set *set; - - table = table_lookup(h, &ctx->nft->cache); - set = set_lookup(table, h->set.name); + struct expr *expr = cmd->elem.expr; + struct set *set = cmd->elem.set; if (set_is_non_concat_range(set) && set_to_intervals(ctx->msgs, set, expr, false, @@ -2521,9 +2513,15 @@ static int do_list_chains(struct netlink_ctx *ctx, struct cmd *cmd) } static void __do_list_set(struct netlink_ctx *ctx, struct cmd *cmd, - struct table *table, struct set *set) + struct set *set) { + struct table *table = table_alloc(); + + table->handle.table.name = xstrdup(cmd->handle.table.name); + table->handle.family = cmd->handle.family; table_print_declaration(table, &ctx->nft->output); + table_free(table); + set_print(set, &ctx->nft->output); nft_print(&ctx->nft->output, "}\n"); } @@ -2537,7 +2535,7 @@ static int do_list_set(struct netlink_ctx *ctx, struct cmd *cmd, if (set == NULL) return -1; - __do_list_set(ctx, cmd, table, set); + __do_list_set(ctx, cmd, set); return 0; } @@ -2608,14 +2606,13 @@ static int do_command_list(struct netlink_ctx *ctx, struct cmd *cmd) return 0; } -static int do_get_setelems(struct netlink_ctx *ctx, struct cmd *cmd, - struct table *table) +static int do_get_setelems(struct netlink_ctx *ctx, struct cmd *cmd) { struct set *set, *new_set; struct expr *init; int err; - set = set_lookup(table, cmd->handle.set.name); + set = cmd->elem.set; /* Create a list of elements based of what we got from command line. */ if (set_is_non_concat_range(set)) @@ -2627,9 +2624,9 @@ static int do_get_setelems(struct netlink_ctx *ctx, struct cmd *cmd, /* Fetch from kernel the elements that have been requested .*/ err = netlink_get_setelem(ctx, &cmd->handle, &cmd->location, - table, new_set, init); + cmd->elem.set, new_set, init); if (err >= 0) - __do_list_set(ctx, cmd, table, new_set); + __do_list_set(ctx, cmd, new_set); if (set_is_non_concat_range(set)) expr_free(init); @@ -2641,14 +2638,9 @@ static int do_get_setelems(struct netlink_ctx *ctx, struct cmd *cmd, static int do_command_get(struct netlink_ctx *ctx, struct cmd *cmd) { - struct table *table = NULL; - - if (cmd->handle.table.name != NULL) - table = table_lookup(&cmd->handle, &ctx->nft->cache); - switch (cmd->obj) { case CMD_OBJ_ELEMENTS: - return do_get_setelems(ctx, cmd, table); + return do_get_setelems(ctx, cmd); default: BUG("invalid command object type %u\n", cmd->obj); } diff --git a/src/segtree.c b/src/segtree.c index 49169e73..a9b4b1bd 100644 --- a/src/segtree.c +++ b/src/segtree.c @@ -687,17 +687,15 @@ struct expr *get_set_intervals(const struct set *set, const struct expr *init) return new_init; } -static struct expr *get_set_interval_find(const struct table *table, - const char *set_name, +static struct expr *get_set_interval_find(const struct set *cache_set, struct expr *left, struct expr *right) { + const struct set *set = cache_set; struct expr *range = NULL; - struct set *set; struct expr *i; mpz_t val; - set = set_lookup(table, set_name); mpz_init2(val, set->key->len); list_for_each_entry(i, &set->init->expressions, list) { @@ -724,7 +722,7 @@ out: return range; } -int get_set_decompose(struct table *table, struct set *set) +int get_set_decompose(struct set *cache_set, struct set *set) { struct expr *i, *next, *range; struct expr *left = NULL; @@ -737,8 +735,7 @@ int get_set_decompose(struct table *table, struct set *set) list_del(&left->list); list_del(&i->list); mpz_sub_ui(i->key->value, i->key->value, 1); - range = get_set_interval_find(table, set->handle.set.name, - left, i); + range = get_set_interval_find(cache_set, left, i); if (!range) { expr_free(new_init); errno = ENOENT; @@ -751,8 +748,7 @@ int get_set_decompose(struct table *table, struct set *set) left = NULL; } else { if (left) { - range = get_set_interval_find(table, - set->handle.set.name, + range = get_set_interval_find(cache_set, left, NULL); if (range) compound_expr_add(new_init, range); @@ -764,8 +760,7 @@ int get_set_decompose(struct table *table, struct set *set) } } if (left) { - range = get_set_interval_find(table, set->handle.set.name, - left, NULL); + range = get_set_interval_find(cache_set, left, NULL); if (range) compound_expr_add(new_init, range); else -- cgit v1.2.3