|
|
8cce6c |
From 0318e0d123ebecbc98305284832774647d953859 Mon Sep 17 00:00:00 2001
|
|
|
8cce6c |
From: Phil Sutter <phil@nwl.cc>
|
|
|
8cce6c |
Date: Thu, 20 Dec 2018 16:09:05 +0100
|
|
|
8cce6c |
Subject: [PATCH] nft: Review is_*_compatible() routines
|
|
|
8cce6c |
|
|
|
8cce6c |
- Call to nft_table_builtin_find() in nft_is_table_compatible() is not
|
|
|
8cce6c |
needed, as it is repeated in the latter call to nft_chain_list_get()
|
|
|
8cce6c |
by nft_are_chains_compatible().
|
|
|
8cce6c |
|
|
|
8cce6c |
- Turn nft_is_chain_compatible(), nft_is_rule_compatible() and
|
|
|
8cce6c |
nft_is_expr_compatible() into callbacks for use with respective
|
|
|
8cce6c |
foreach functions.
|
|
|
8cce6c |
|
|
|
8cce6c |
- nft_are_chains_compatible() is not needed anymore due to foreach
|
|
|
8cce6c |
function use.
|
|
|
8cce6c |
|
|
|
8cce6c |
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
8cce6c |
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
8cce6c |
(cherry picked from commit e774b15299c271a4c7570899591cf1b7960477ea)
|
|
|
8cce6c |
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
|
8cce6c |
---
|
|
|
8cce6c |
iptables/nft.c | 153 ++++++++++++++++++-------------------------------
|
|
|
8cce6c |
1 file changed, 55 insertions(+), 98 deletions(-)
|
|
|
8cce6c |
|
|
|
8cce6c |
diff --git a/iptables/nft.c b/iptables/nft.c
|
|
|
8cce6c |
index 1fca1f17147f6..5032c718b33a9 100644
|
|
|
8cce6c |
--- a/iptables/nft.c
|
|
|
8cce6c |
+++ b/iptables/nft.c
|
|
|
8cce6c |
@@ -3115,7 +3115,7 @@ static const char *supported_exprs[NFT_COMPAT_EXPR_MAX] = {
|
|
|
8cce6c |
};
|
|
|
8cce6c |
|
|
|
8cce6c |
|
|
|
8cce6c |
-static int nft_is_expr_compatible(const struct nftnl_expr *expr)
|
|
|
8cce6c |
+static int nft_is_expr_compatible(struct nftnl_expr *expr, void *data)
|
|
|
8cce6c |
{
|
|
|
8cce6c |
const char *name = nftnl_expr_get_str(expr, NFTNL_EXPR_NAME);
|
|
|
8cce6c |
int i;
|
|
|
8cce6c |
@@ -3130,138 +3130,95 @@ static int nft_is_expr_compatible(const struct nftnl_expr *expr)
|
|
|
8cce6c |
nftnl_expr_get_u32(expr, NFTNL_EXPR_LIMIT_FLAGS) == 0)
|
|
|
8cce6c |
return 0;
|
|
|
8cce6c |
|
|
|
8cce6c |
- return 1;
|
|
|
8cce6c |
+ return -1;
|
|
|
8cce6c |
}
|
|
|
8cce6c |
|
|
|
8cce6c |
-static bool nft_is_rule_compatible(struct nftnl_rule *rule)
|
|
|
8cce6c |
-{
|
|
|
8cce6c |
- struct nftnl_expr_iter *iter;
|
|
|
8cce6c |
- struct nftnl_expr *expr;
|
|
|
8cce6c |
- bool compatible = false;
|
|
|
8cce6c |
-
|
|
|
8cce6c |
- iter = nftnl_expr_iter_create(rule);
|
|
|
8cce6c |
- if (iter == NULL)
|
|
|
8cce6c |
- return false;
|
|
|
8cce6c |
+struct nft_is_rule_compatible_data {
|
|
|
8cce6c |
+ const char *tablename;
|
|
|
8cce6c |
+};
|
|
|
8cce6c |
|
|
|
8cce6c |
- expr = nftnl_expr_iter_next(iter);
|
|
|
8cce6c |
- while (expr != NULL) {
|
|
|
8cce6c |
- if (nft_is_expr_compatible(expr) == 0) {
|
|
|
8cce6c |
- expr = nftnl_expr_iter_next(iter);
|
|
|
8cce6c |
- continue;
|
|
|
8cce6c |
- }
|
|
|
8cce6c |
+static int nft_is_rule_compatible(struct nftnl_rule *rule, void *data)
|
|
|
8cce6c |
+{
|
|
|
8cce6c |
+ const char *table = nftnl_rule_get_str(rule, NFTNL_RULE_TABLE);
|
|
|
8cce6c |
+ struct nft_is_rule_compatible_data *d = data;
|
|
|
8cce6c |
|
|
|
8cce6c |
- compatible = true;
|
|
|
8cce6c |
- break;
|
|
|
8cce6c |
- }
|
|
|
8cce6c |
+ /* ignore rules belonging to a different table */
|
|
|
8cce6c |
+ if (strcmp(table, d->tablename))
|
|
|
8cce6c |
+ return 0;
|
|
|
8cce6c |
|
|
|
8cce6c |
- nftnl_expr_iter_destroy(iter);
|
|
|
8cce6c |
- return compatible;
|
|
|
8cce6c |
+ return nftnl_expr_foreach(rule, nft_is_expr_compatible, NULL);
|
|
|
8cce6c |
}
|
|
|
8cce6c |
|
|
|
8cce6c |
-static int nft_is_chain_compatible(const struct nft_handle *h,
|
|
|
8cce6c |
- const struct nftnl_chain *chain)
|
|
|
8cce6c |
+static int nft_is_chain_compatible(struct nftnl_chain *c, void *data)
|
|
|
8cce6c |
{
|
|
|
8cce6c |
- const char *table, *name, *type, *cur_table;
|
|
|
8cce6c |
- const struct builtin_chain *chains;
|
|
|
8cce6c |
- int i, j, prio;
|
|
|
8cce6c |
+ const struct builtin_chain *chains = NULL, *chain = NULL;
|
|
|
8cce6c |
+ const char *table, *name, *type;
|
|
|
8cce6c |
+ struct nft_handle *h = data;
|
|
|
8cce6c |
enum nf_inet_hooks hook;
|
|
|
8cce6c |
+ int i, prio;
|
|
|
8cce6c |
|
|
|
8cce6c |
- table = nftnl_chain_get(chain, NFTNL_CHAIN_TABLE);
|
|
|
8cce6c |
- name = nftnl_chain_get(chain, NFTNL_CHAIN_NAME);
|
|
|
8cce6c |
- type = nftnl_chain_get(chain, NFTNL_CHAIN_TYPE);
|
|
|
8cce6c |
- prio = nftnl_chain_get_u32(chain, NFTNL_CHAIN_PRIO);
|
|
|
8cce6c |
- hook = nftnl_chain_get_u32(chain, NFTNL_CHAIN_HOOKNUM);
|
|
|
8cce6c |
+ if (!nft_chain_builtin(c))
|
|
|
8cce6c |
+ return 0;
|
|
|
8cce6c |
|
|
|
8cce6c |
+ /* find chain's table in builtin tables */
|
|
|
8cce6c |
+ table = nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE);
|
|
|
8cce6c |
for (i = 0; i < NFT_TABLE_MAX; i++) {
|
|
|
8cce6c |
- cur_table = h->tables[i].name;
|
|
|
8cce6c |
- chains = h->tables[i].chains;
|
|
|
8cce6c |
+ const char *cur_table = h->tables[i].name;
|
|
|
8cce6c |
|
|
|
8cce6c |
- if (!cur_table || strcmp(table, cur_table) != 0)
|
|
|
8cce6c |
+ if (!cur_table || strcmp(cur_table, table))
|
|
|
8cce6c |
continue;
|
|
|
8cce6c |
|
|
|
8cce6c |
- for (j = 0; j < NF_INET_NUMHOOKS && chains[j].name; j++) {
|
|
|
8cce6c |
- if (strcmp(name, chains[j].name) != 0)
|
|
|
8cce6c |
- continue;
|
|
|
8cce6c |
-
|
|
|
8cce6c |
- if (strcmp(type, chains[j].type) == 0 &&
|
|
|
8cce6c |
- prio == chains[j].prio &&
|
|
|
8cce6c |
- hook == chains[j].hook)
|
|
|
8cce6c |
- return 0;
|
|
|
8cce6c |
- break;
|
|
|
8cce6c |
- }
|
|
|
8cce6c |
+ chains = h->tables[i].chains;
|
|
|
8cce6c |
+ break;
|
|
|
8cce6c |
}
|
|
|
8cce6c |
-
|
|
|
8cce6c |
- return 1;
|
|
|
8cce6c |
-}
|
|
|
8cce6c |
-
|
|
|
8cce6c |
-static int nft_are_chains_compatible(struct nft_handle *h, const char *tablename)
|
|
|
8cce6c |
-{
|
|
|
8cce6c |
- struct nftnl_chain_list *list;
|
|
|
8cce6c |
- struct nftnl_chain_list_iter *iter;
|
|
|
8cce6c |
- struct nftnl_chain *chain;
|
|
|
8cce6c |
- int ret = 0;
|
|
|
8cce6c |
-
|
|
|
8cce6c |
- list = nft_chain_list_get(h, tablename);
|
|
|
8cce6c |
- if (list == NULL)
|
|
|
8cce6c |
- return -1;
|
|
|
8cce6c |
-
|
|
|
8cce6c |
- iter = nftnl_chain_list_iter_create(list);
|
|
|
8cce6c |
- if (iter == NULL)
|
|
|
8cce6c |
+ if (!chains)
|
|
|
8cce6c |
return -1;
|
|
|
8cce6c |
|
|
|
8cce6c |
- chain = nftnl_chain_list_iter_next(iter);
|
|
|
8cce6c |
- while (chain != NULL) {
|
|
|
8cce6c |
- if (!nft_chain_builtin(chain))
|
|
|
8cce6c |
- goto next;
|
|
|
8cce6c |
+ /* find chain in builtin chain list */
|
|
|
8cce6c |
+ name = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
|
|
|
8cce6c |
+ for (i = 0; i < NF_INET_NUMHOOKS && chains[i].name; i++) {
|
|
|
8cce6c |
+ if (strcmp(name, chains[i].name))
|
|
|
8cce6c |
+ continue;
|
|
|
8cce6c |
|
|
|
8cce6c |
- ret = nft_is_chain_compatible(h, chain);
|
|
|
8cce6c |
- if (ret != 0)
|
|
|
8cce6c |
- break;
|
|
|
8cce6c |
-next:
|
|
|
8cce6c |
- chain = nftnl_chain_list_iter_next(iter);
|
|
|
8cce6c |
+ chain = &chains[i];
|
|
|
8cce6c |
+ break;
|
|
|
8cce6c |
}
|
|
|
8cce6c |
+ if (!chain)
|
|
|
8cce6c |
+ return -1;
|
|
|
8cce6c |
|
|
|
8cce6c |
- nftnl_chain_list_iter_destroy(iter);
|
|
|
8cce6c |
+ /* compare properties */
|
|
|
8cce6c |
+ type = nftnl_chain_get_str(c, NFTNL_CHAIN_TYPE);
|
|
|
8cce6c |
+ prio = nftnl_chain_get_u32(c, NFTNL_CHAIN_PRIO);
|
|
|
8cce6c |
+ hook = nftnl_chain_get_u32(c, NFTNL_CHAIN_HOOKNUM);
|
|
|
8cce6c |
+ if (strcmp(type, chain->type) ||
|
|
|
8cce6c |
+ prio != chain->prio ||
|
|
|
8cce6c |
+ hook != chain->hook)
|
|
|
8cce6c |
+ return -1;
|
|
|
8cce6c |
|
|
|
8cce6c |
- return ret;
|
|
|
8cce6c |
+ return 0;
|
|
|
8cce6c |
}
|
|
|
8cce6c |
|
|
|
8cce6c |
bool nft_is_table_compatible(struct nft_handle *h, const char *tablename)
|
|
|
8cce6c |
{
|
|
|
8cce6c |
+ struct nft_is_rule_compatible_data rcd = {
|
|
|
8cce6c |
+ .tablename = tablename
|
|
|
8cce6c |
+ };
|
|
|
8cce6c |
+ struct nftnl_chain_list *clist;
|
|
|
8cce6c |
struct nftnl_rule_list *list;
|
|
|
8cce6c |
- struct nftnl_rule_list_iter *iter;
|
|
|
8cce6c |
- struct nftnl_rule *rule;
|
|
|
8cce6c |
- int ret = 0;
|
|
|
8cce6c |
|
|
|
8cce6c |
- if (!nft_table_builtin_find(h, tablename))
|
|
|
8cce6c |
+ clist = nft_chain_list_get(h, tablename);
|
|
|
8cce6c |
+ if (clist == NULL)
|
|
|
8cce6c |
return false;
|
|
|
8cce6c |
|
|
|
8cce6c |
- ret = nft_are_chains_compatible(h, tablename);
|
|
|
8cce6c |
- if (ret != 0)
|
|
|
8cce6c |
+ if (nftnl_chain_list_foreach(clist, nft_is_chain_compatible, h))
|
|
|
8cce6c |
return false;
|
|
|
8cce6c |
|
|
|
8cce6c |
list = nft_rule_list_get(h);
|
|
|
8cce6c |
if (list == NULL)
|
|
|
8cce6c |
return true;
|
|
|
8cce6c |
|
|
|
8cce6c |
- iter = nftnl_rule_list_iter_create(list);
|
|
|
8cce6c |
- if (iter == NULL)
|
|
|
8cce6c |
- return true;
|
|
|
8cce6c |
-
|
|
|
8cce6c |
- rule = nftnl_rule_list_iter_next(iter);
|
|
|
8cce6c |
- while (rule != NULL) {
|
|
|
8cce6c |
- const char *table = nftnl_rule_get_str(rule, NFTNL_RULE_TABLE);
|
|
|
8cce6c |
-
|
|
|
8cce6c |
- if (strcmp(table, tablename))
|
|
|
8cce6c |
- goto next_rule;
|
|
|
8cce6c |
-
|
|
|
8cce6c |
- ret = nft_is_rule_compatible(rule);
|
|
|
8cce6c |
- if (ret != 0)
|
|
|
8cce6c |
- break;
|
|
|
8cce6c |
-next_rule:
|
|
|
8cce6c |
- rule = nftnl_rule_list_iter_next(iter);
|
|
|
8cce6c |
- }
|
|
|
8cce6c |
+ if (nftnl_rule_list_foreach(list, nft_is_rule_compatible, &rcd))
|
|
|
8cce6c |
+ return false;
|
|
|
8cce6c |
|
|
|
8cce6c |
- nftnl_rule_list_iter_destroy(iter);
|
|
|
8cce6c |
- return ret == 0;
|
|
|
8cce6c |
+ return true;
|
|
|
8cce6c |
}
|
|
|
8cce6c |
--
|
|
|
8cce6c |
2.20.1
|
|
|
8cce6c |
|