summaryrefslogtreecommitdiffstats
path: root/iptables/nft-cmd.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2020-01-06 13:20:14 +0100
committerPhil Sutter <phil@nwl.cc>2020-05-11 14:28:28 +0200
commit9d07514ac5c7a27ec72df5a81bf067073d63bd99 (patch)
tree129a8f08d7c132296c7d8131c540074995551bac /iptables/nft-cmd.c
parenta7f1e208cdf9c6392c99d3c52764701d004bdde7 (diff)
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 <pablo@netfilter.org> Signed-off-by: Phil Sutter <phil@nwl.cc>
Diffstat (limited to 'iptables/nft-cmd.c')
-rw-r--r--iptables/nft-cmd.c66
1 files changed, 66 insertions, 0 deletions
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;
}