Use nft_is_table_compatible instead as only helper to a 'skip' decision.

Custom tables, tables that have extra base chains that iptables
syntax doesn't allow or rules that have special constructs line nftables
set lookups or verdict maps are not listed, but a message is provided
to show that such table exists.

Signed-off-by: Florian Westphal <f...@strlen.de>
---
 iptables/nft.c          | 62 +++++++++++++++++++++----------------------------
 iptables/nft.h          |  1 -
 iptables/xtables-save.c |  7 ------
 iptables/xtables.c      |  6 -----
 4 files changed, 27 insertions(+), 49 deletions(-)

diff --git a/iptables/nft.c b/iptables/nft.c
index 5204112c786e..b6426a96de18 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -2069,6 +2069,11 @@ int nft_rule_list(struct nft_handle *h, const char 
*chain, const char *table,
 
        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);
+               return 0;
+       }
+
        if (chain && rulenum) {
                __nft_rule_list(h, chain, table,
                                rulenum, format, ops->print_firewall);
@@ -2741,15 +2746,15 @@ static int nft_is_expr_compatible(const char *name)
        return 1;
 }
 
-static int nft_is_rule_compatible(struct nftnl_rule *rule)
+static bool nft_is_rule_compatible(struct nftnl_rule *rule)
 {
        struct nftnl_expr_iter *iter;
        struct nftnl_expr *expr;
-       int ret = 0;
+       bool compatible = false;
 
        iter = nftnl_expr_iter_create(rule);
        if (iter == NULL)
-               return -1;
+               return false;
 
        expr = nftnl_expr_iter_next(iter);
        while (expr != NULL) {
@@ -2760,12 +2765,12 @@ static int nft_is_rule_compatible(struct nftnl_rule 
*rule)
                        continue;
                }
 
-               ret = 1;
+               compatible = true;
                break;
        }
 
        nftnl_expr_iter_destroy(iter);
-       return ret;
+       return compatible;
 }
 
 static int nft_is_chain_compatible(const struct nft_handle *h,
@@ -2804,14 +2809,14 @@ static int nft_is_chain_compatible(const struct 
nft_handle *h,
        return 1;
 }
 
-static int nft_are_chains_compatible(struct nft_handle *h)
+static int nft_are_chains_compatible(struct nft_handle *h, const char 
*tablename)
 {
        struct nftnl_chain_list *list;
        struct nftnl_chain_list_iter *iter;
        struct nftnl_chain *chain;
        int ret = 0;
 
-       list = nftnl_chain_list_get(h, NULL);
+       list = nftnl_chain_list_get(h, tablename);
        if (list == NULL)
                return -1;
 
@@ -2821,10 +2826,7 @@ static int nft_are_chains_compatible(struct nft_handle 
*h)
 
        chain = nftnl_chain_list_iter_next(iter);
        while (chain != NULL) {
-               const char *table = nftnl_chain_get(chain, NFTNL_CHAIN_TABLE);
-
-               if (!nft_chain_builtin(chain) ||
-                   !nft_is_table_compatible(h, table))
+               if (!nft_chain_builtin(chain))
                        goto next;
 
                ret = nft_is_chain_compatible(h, chain);
@@ -2839,51 +2841,41 @@ next:
        return ret;
 }
 
-bool nft_is_table_compatible(struct nft_handle *h, const char *name)
+bool nft_is_table_compatible(struct nft_handle *h, const char *tablename)
 {
-       int i;
+       struct nftnl_rule_list *list;
+       struct nftnl_rule_list_iter *iter;
+       struct nftnl_rule *rule;
+       int ret = 0, i;
 
        for (i = 0; i < TABLES_MAX; i++) {
-               if (strcmp(h->tables[i].name, name) == 0)
-                       return true;
+               if (strcmp(h->tables[i].name, tablename) == 0)
+                       break;
        }
 
-       return false;
-}
-
-int nft_is_ruleset_compatible(struct nft_handle *h)
-{
-
-       struct nftnl_rule_list *list;
-       struct nftnl_rule_list_iter *iter;
-       struct nftnl_rule *rule;
-       int ret = 0;
+       if (i == TABLES_MAX)
+               return false;
 
-       ret = nft_are_chains_compatible(h);
+       ret = nft_are_chains_compatible(h, tablename);
        if (ret != 0)
-               return ret;
+               return false;
 
        list = nft_rule_list_get(h);
        if (list == NULL)
-               return -1;
+               return true;
 
        iter = nftnl_rule_list_iter_create(list);
        if (iter == NULL)
-               return -1;
+               return true;
 
        rule = nftnl_rule_list_iter_next(iter);
        while (rule != NULL) {
-               if (!nft_is_table_compatible(h,
-                    nftnl_rule_get_str(rule, NFTA_RULE_TABLE)))
-                       goto next;
-
                ret = nft_is_rule_compatible(rule);
                if (ret != 0)
                        break;
-next:
                rule = nftnl_rule_list_iter_next(iter);
        }
 
        nftnl_rule_list_iter_destroy(iter);
-       return ret;
+       return ret == 0;
 }
diff --git a/iptables/nft.h b/iptables/nft.h
index af229233025c..5d0576c8ee45 100644
--- a/iptables/nft.h
+++ b/iptables/nft.h
@@ -182,7 +182,6 @@ 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);
 
-int nft_is_ruleset_compatible(struct nft_handle *h);
 bool nft_is_table_compatible(struct nft_handle *h, const char *name);
 
 #endif
diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c
index 2305e878d1ea..be98b8350aaa 100644
--- a/iptables/xtables-save.c
+++ b/iptables/xtables-save.c
@@ -182,13 +182,6 @@ xtables_save_main(int family, const char *progname, int 
argc, char *argv[])
                exit(EXIT_FAILURE);
        }
 
-
-       ret = nft_is_ruleset_compatible(&h);
-       if (ret) {
-               printf("ERROR: You're using nft features that cannot be mapped 
to iptables, please keep using nft.\n");
-               exit(EXIT_FAILURE);
-       }
-
        if (dump) {
                do_output(&h, tablename, show_counters);
                exit(0);
diff --git a/iptables/xtables.c b/iptables/xtables.c
index 5410952a385e..7476c974451a 100644
--- a/iptables/xtables.c
+++ b/iptables/xtables.c
@@ -1225,12 +1225,6 @@ int do_commandx(struct nft_handle *h, int argc, char 
*argv[], char **table,
        case CMD_LIST:
        case CMD_LIST|CMD_ZERO:
        case CMD_LIST|CMD_ZERO_NUM:
-               ret = nft_is_ruleset_compatible(h);
-               if (ret) {
-                       printf("ERROR: You're using nft features that cannot be 
mapped to iptables, please keep using nft.\n");
-                       exit(EXIT_FAILURE);
-               }
-
                ret = list_entries(h, p.chain, p.table, p.rulenum,
                                   cs.options & OPT_VERBOSE,
                                   cs.options & OPT_NUMERIC,
-- 
2.16.1

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to