]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
nft: Support nft_is_table_compatible() per chain
authorPhil Sutter <phil@nwl.cc>
Wed, 25 Sep 2019 16:48:07 +0000 (18:48 +0200)
committerPhil Sutter <phil@nwl.cc>
Thu, 17 Oct 2019 17:02:56 +0000 (19:02 +0200)
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>
iptables/nft.c
iptables/nft.h
iptables/xtables-save.c

index 7e019d54ee475d9c0e559c0e7fbd26cb47993578..12cc423c87bbb4210241ac4cec8bf3df5ac52edc 100644 (file)
@@ -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);
+}
index 9ae3122a1c515b903f328d90c1a37b6cb1e409b1..4b8b3033a56c0d4d4bc5478f37cd228b83c6a790 100644 (file)
@@ -206,7 +206,10 @@ int nft_arp_rule_insert(struct nft_handle *h, const char *chain,
 
 void nft_rule_to_arpt_entry(struct nftnl_rule *r, struct arpt_entry *fw);
 
-bool nft_is_table_compatible(struct nft_handle *h, const char *name);
+bool nft_is_table_compatible(struct nft_handle *h,
+                            const char *table, const char *chain);
+void nft_assert_table_compatible(struct nft_handle *h,
+                                const char *table, const char *chain);
 
 int ebt_set_user_chain_policy(struct nft_handle *h, const char *table,
                              const char *chain, const char *policy);
index e234425ded293408dbc971384bfa3bd39201b852..44687f998c91a1f3e1ddd705e85ada1e92896f82 100644 (file)
@@ -77,7 +77,7 @@ __do_output(struct nft_handle *h, const char *tablename, void *data)
        if (!nft_table_builtin_find(h, tablename))
                return 0;
 
-       if (!nft_is_table_compatible(h, tablename)) {
+       if (!nft_is_table_compatible(h, tablename, NULL)) {
                printf("# Table `%s' is incompatible, use 'nft' tool.\n",
                       tablename);
                return 0;