From 7df42800cf89e994b5179200825592d9b95c5fab Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 4 Jun 2019 12:02:18 +0200 Subject: src: single cache_update() call to build cache before evaluation This patch allows us to make one single cache_update() call. Thus, there is not need to rebuild an incomplete cache from the middle of the batch processing. Note that nft_run_cmd_from_filename() does not need a full netlink dump to build the cache anymore, this should speed nft -f with incremental updates and very large rulesets. cache_evaluate() calculates the netlink dump to populate the cache that this batch needs. Signed-off-by: Pablo Neira Ayuso --- src/cache.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 src/cache.c (limited to 'src/cache.c') diff --git a/src/cache.c b/src/cache.c new file mode 100644 index 00000000..2a0f04d1 --- /dev/null +++ b/src/cache.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2019 Pablo Neira Ayuso + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 (or any + * later) as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include + +static unsigned int evaluate_cache_add(struct cmd *cmd) +{ + unsigned int completeness = CMD_INVALID; + + switch (cmd->obj) { + case CMD_OBJ_SETELEM: + case CMD_OBJ_SET: + case CMD_OBJ_CHAIN: + case CMD_OBJ_FLOWTABLE: + completeness = cmd->op; + break; + case CMD_OBJ_RULE: + /* XXX index is set to zero unless this handle_merge() call is + * invoked, this handle_merge() call is done from the + * evaluation, which is too late. + */ + handle_merge(&cmd->rule->handle, &cmd->handle); + + if (cmd->rule->handle.index.id) + completeness = CMD_LIST; + break; + default: + break; + } + + return completeness; +} + +static unsigned int evaluate_cache_del(struct cmd *cmd) +{ + unsigned int completeness = CMD_INVALID; + + switch (cmd->obj) { + case CMD_OBJ_SETELEM: + completeness = cmd->op; + break; + default: + break; + } + + return completeness; +} + +static unsigned int evaluate_cache_flush(struct cmd *cmd) +{ + unsigned int completeness = CMD_INVALID; + + switch (cmd->obj) { + case CMD_OBJ_SET: + case CMD_OBJ_MAP: + case CMD_OBJ_METER: + completeness = cmd->op; + break; + default: + break; + } + + return completeness; +} + +static unsigned int evaluate_cache_rename(struct cmd *cmd) +{ + unsigned int completeness = CMD_INVALID; + + switch (cmd->obj) { + case CMD_OBJ_CHAIN: + completeness = cmd->op; + break; + default: + break; + } + + return completeness; +} + +int cache_evaluate(struct nft_ctx *nft, struct list_head *cmds) +{ + unsigned int echo_completeness = CMD_INVALID; + unsigned int completeness = CMD_INVALID; + struct cmd *cmd; + + list_for_each_entry(cmd, cmds, list) { + switch (cmd->op) { + case CMD_ADD: + case CMD_INSERT: + case CMD_REPLACE: + if (nft_output_echo(&nft->output)) + echo_completeness = cmd->op; + + /* Fall through */ + case CMD_CREATE: + completeness = evaluate_cache_add(cmd); + break; + case CMD_DELETE: + completeness = evaluate_cache_del(cmd); + break; + case CMD_GET: + case CMD_LIST: + case CMD_RESET: + case CMD_EXPORT: + case CMD_MONITOR: + completeness = cmd->op; + break; + case CMD_FLUSH: + completeness = evaluate_cache_flush(cmd); + break; + case CMD_RENAME: + completeness = evaluate_cache_rename(cmd); + break; + case CMD_DESCRIBE: + case CMD_IMPORT: + break; + default: + break; + } + } + + return max(completeness, echo_completeness); +} -- cgit v1.2.3