From 9d07514ac5c7a27ec72df5a81bf067073d63bd99 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 6 Jan 2020 13:20:14 +0100 Subject: nft: calculate cache requirements from list of commands This patch uses the new list of commands to calculate the cache requirements, the rationale after this updates is the following: #1 Parsing, that builds the list of commands and it also calculates cache level requirements. #2 Cache building. #3 Translate commands to jobs #4 Translate jobs to netlink This patch removes the pre-parsing code in xtables-restore.c to calculate the cache. After this patch, cache is calculated only once, there is no need to cancel and refetch for an in-transit transaction. Signed-off-by: Pablo Neira Ayuso Signed-off-by: Phil Sutter --- iptables/nft-cmd.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'iptables/nft-cmd.c') diff --git a/iptables/nft-cmd.c b/iptables/nft-cmd.c index 96887c01..8bf361a6 100644 --- a/iptables/nft-cmd.c +++ b/iptables/nft-cmd.c @@ -71,12 +71,33 @@ void nft_cmd_free(struct nft_cmd *cmd) free(cmd); } +static void nft_cmd_rule_bridge(struct nft_handle *h, const char *chain, + const char *table) +{ + const struct builtin_table *t; + + t = nft_table_builtin_find(h, table); + if (!t) + return; + + /* Since ebtables user-defined chain policies are implemented as last + * rule in nftables, rule cache is required here to treat them right. + */ + if (h->family == NFPROTO_BRIDGE && + !nft_chain_builtin_find(t, chain)) + nft_cache_level_set(h, NFT_CL_RULES); + else + nft_cache_level_set(h, NFT_CL_CHAINS); +} + int nft_cmd_rule_append(struct nft_handle *h, const char *chain, const char *table, struct iptables_command_state *state, void *ref, bool verbose) { struct nft_cmd *cmd; + nft_cmd_rule_bridge(h, chain, table); + cmd = nft_cmd_new(h, NFT_COMPAT_RULE_APPEND, table, chain, state, -1, verbose); if (!cmd) @@ -91,11 +112,18 @@ int nft_cmd_rule_insert(struct nft_handle *h, const char *chain, { struct nft_cmd *cmd; + nft_cmd_rule_bridge(h, chain, table); + cmd = nft_cmd_new(h, NFT_COMPAT_RULE_INSERT, table, chain, state, rulenum, verbose); if (!cmd) return 0; + if (cmd->rulenum > 0) + nft_cache_level_set(h, NFT_CL_RULES); + else + nft_cache_level_set(h, NFT_CL_CHAINS); + return 1; } @@ -110,6 +138,8 @@ int nft_cmd_rule_delete(struct nft_handle *h, const char *chain, if (!cmd) return 0; + nft_cache_level_set(h, NFT_CL_RULES); + return 1; } @@ -123,6 +153,8 @@ int nft_cmd_rule_delete_num(struct nft_handle *h, const char *chain, if (!cmd) return 0; + nft_cache_level_set(h, NFT_CL_RULES); + return 1; } @@ -136,6 +168,8 @@ int nft_cmd_rule_flush(struct nft_handle *h, const char *chain, if (!cmd) return 0; + nft_cache_level_set(h, NFT_CL_CHAINS); + return 1; } @@ -149,6 +183,8 @@ int nft_cmd_chain_zero_counters(struct nft_handle *h, const char *chain, if (!cmd) return 0; + nft_cache_level_set(h, NFT_CL_CHAINS); + return 1; } @@ -162,6 +198,8 @@ int nft_cmd_chain_user_add(struct nft_handle *h, const char *chain, if (!cmd) return 0; + nft_cache_level_set(h, NFT_CL_CHAINS); + return 1; } @@ -175,6 +213,14 @@ int nft_cmd_chain_user_del(struct nft_handle *h, const char *chain, if (!cmd) return 0; + /* This triggers nft_bridge_chain_postprocess() when fetching the + * rule cache. + */ + if (h->family == NFPROTO_BRIDGE) + nft_cache_level_set(h, NFT_CL_RULES); + else + nft_cache_level_set(h, NFT_CL_CHAINS); + return 1; } @@ -190,6 +236,8 @@ int nft_cmd_chain_user_rename(struct nft_handle *h,const char *chain, cmd->rename = strdup(newname); + nft_cache_level_set(h, NFT_CL_CHAINS); + return 1; } @@ -205,6 +253,8 @@ int nft_cmd_rule_list(struct nft_handle *h, const char *chain, cmd->format = format; + nft_cache_level_set(h, NFT_CL_RULES); + return 1; } @@ -219,6 +269,8 @@ int nft_cmd_rule_replace(struct nft_handle *h, const char *chain, if (!cmd) return 0; + nft_cache_level_set(h, NFT_CL_RULES); + return 1; } @@ -232,6 +284,8 @@ int nft_cmd_rule_check(struct nft_handle *h, const char *chain, if (!cmd) return 0; + nft_cache_level_set(h, NFT_CL_RULES); + return 1; } @@ -250,6 +304,8 @@ int nft_cmd_chain_set(struct nft_handle *h, const char *table, if (counters) cmd->counters = *counters; + nft_cache_level_set(h, NFT_CL_CHAINS); + return 1; } @@ -262,6 +318,8 @@ int nft_cmd_table_flush(struct nft_handle *h, const char *table) if (!cmd) return 0; + nft_cache_level_set(h, NFT_CL_TABLES); + return 1; } @@ -275,6 +333,8 @@ int nft_cmd_chain_restore(struct nft_handle *h, const char *chain, if (!cmd) return 0; + nft_cache_level_set(h, NFT_CL_CHAINS); + return 1; } @@ -288,6 +348,8 @@ int nft_cmd_rule_zero_counters(struct nft_handle *h, const char *chain, if (!cmd) return 0; + nft_cache_level_set(h, NFT_CL_RULES); + return 1; } @@ -303,6 +365,8 @@ int nft_cmd_rule_list_save(struct nft_handle *h, const char *chain, cmd->counters_save = counters; + nft_cache_level_set(h, NFT_CL_RULES); + return 1; } @@ -318,6 +382,8 @@ int ebt_cmd_user_chain_policy(struct nft_handle *h, const char *table, cmd->policy = strdup(policy); + nft_cache_level_set(h, NFT_CL_RULES); + return 1; } -- cgit v1.2.3