summaryrefslogtreecommitdiffstats
path: root/iptables/nft.c
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2019-09-25 18:48:07 +0200
committerPhil Sutter <phil@nwl.cc>2019-10-17 19:02:56 +0200
commit48a21d5c7af074bd502a4f6fa7d8a46cfa719732 (patch)
treeca0850393305d43edc86474edfc5bf6e055a3415 /iptables/nft.c
parent7b64c50904ae1ab6366a78e01a272532fac8af8f (diff)
nft: Support nft_is_table_compatible() per chain
When operating on a single chain only, compatibility checking causes unwanted overhead by checking all chains of the current table. Avoid this by accepting the current chain name as parameter and pass it along to nft_chain_list_get(). While being at it, introduce nft_assert_table_compatible() which calls xtables_error() in case compatibility check fails. If a chain name was given, include that in error message. Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'iptables/nft.c')
-rw-r--r--iptables/nft.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/iptables/nft.c b/iptables/nft.c
index 7e019d54..12cc423c 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -2192,12 +2192,10 @@ int nft_rule_list(struct nft_handle *h, const char *chain, const char *table,
bool found = false;
nft_xt_builtin_init(h, table);
+ nft_assert_table_compatible(h, table, chain);
ops = nft_family_ops_lookup(h->family);
- if (!nft_is_table_compatible(h, table))
- xtables_error(OTHER_PROBLEM, "table `%s' is incompatible, use 'nft' tool.\n", table);
-
list = nft_chain_list_get(h, table, chain);
if (!list)
return 0;
@@ -2295,9 +2293,7 @@ int nft_rule_list_save(struct nft_handle *h, const char *chain,
int ret = 0;
nft_xt_builtin_init(h, table);
-
- if (!nft_is_table_compatible(h, table))
- xtables_error(OTHER_PROBLEM, "table `%s' is incompatible, use 'nft' tool.\n", table);
+ nft_assert_table_compatible(h, table, chain);
list = nft_chain_list_get(h, table, chain);
if (!list)
@@ -3085,11 +3081,12 @@ static int nft_is_chain_compatible(struct nftnl_chain *c, void *data)
return 0;
}
-bool nft_is_table_compatible(struct nft_handle *h, const char *tablename)
+bool nft_is_table_compatible(struct nft_handle *h,
+ const char *table, const char *chain)
{
struct nftnl_chain_list *clist;
- clist = nft_chain_list_get(h, tablename, NULL);
+ clist = nft_chain_list_get(h, table, chain);
if (clist == NULL)
return false;
@@ -3098,3 +3095,22 @@ bool nft_is_table_compatible(struct nft_handle *h, const char *tablename)
return true;
}
+
+void nft_assert_table_compatible(struct nft_handle *h,
+ const char *table, const char *chain)
+{
+ const char *pfx = "", *sfx = "";
+
+ if (nft_is_table_compatible(h, table, chain))
+ return;
+
+ if (chain) {
+ pfx = "chain `";
+ sfx = "' in ";
+ } else {
+ chain = "";
+ }
+ xtables_error(OTHER_PROBLEM,
+ "%s%s%stable `%s' is incompatible, use 'nft' tool.\n",
+ pfx, chain, sfx, table);
+}