On Thu, Dec 20, 2018 at 04:09:05PM +0100, Phil Sutter wrote:
[...]
> diff --git a/iptables/nft.c b/iptables/nft.c
> index 1fca1f17147f6..5ea24cca1d285 100644
> --- a/iptables/nft.c
> +++ b/iptables/nft.c
[...]
> +static int nft_is_chain_compatible(struct nftnl_chain *c, void *data)
> {
> - const char *table, *name, *type, *cur_table;
> - const struct builtin_chain *chains;
> - int i, j, prio;
> + const struct builtin_chain *chains = NULL, *chain = NULL;
> + const char *table, *name, *type;
> + struct nft_handle *h = data;
> enum nf_inet_hooks hook;
> + int i, prio;
>
> - table = nftnl_chain_get(chain, NFTNL_CHAIN_TABLE);
> - name = nftnl_chain_get(chain, NFTNL_CHAIN_NAME);
> - type = nftnl_chain_get(chain, NFTNL_CHAIN_TYPE);
> - prio = nftnl_chain_get_u32(chain, NFTNL_CHAIN_PRIO);
> - hook = nftnl_chain_get_u32(chain, NFTNL_CHAIN_HOOKNUM);
> + if (!nft_chain_builtin(c))
> + return 0;
>
> + /* find chain's table in builtin tables */
> + table = nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE);
We can probably use nft_table_builtin_find() here.
> for (i = 0; i < NFT_TABLE_MAX; i++) {
> - cur_table = h->tables[i].name;
> - chains = h->tables[i].chains;
> + const char *cur_table = h->tables[i].name;
>
> - if (!cur_table || strcmp(table, cur_table) != 0)
> + if (!cur_table || strcmp(cur_table, table))
> continue;
>
> - for (j = 0; j < NF_INET_NUMHOOKS && chains[j].name; j++) {
> - if (strcmp(name, chains[j].name) != 0)
> - continue;
> -
> - if (strcmp(type, chains[j].type) == 0 &&
> - prio == chains[j].prio &&
> - hook == chains[j].hook)
> - return 0;
> - break;
> - }
> + chains = h->tables[i].chains;
> + break;
> }
> -
> - return 1;
> -}
> -
> -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 = nft_chain_list_get(h, tablename);
> - if (list == NULL)
> - return -1;
> -
> - iter = nftnl_chain_list_iter_create(list);
> - if (iter == NULL)
> + if (!chains)
> return -1;
>
> - chain = nftnl_chain_list_iter_next(iter);
> - while (chain != NULL) {
> - if (!nft_chain_builtin(chain))
> - goto next;
> + /* find chain in builtin chain list */
nft_chain_builtin_find here too.
> + name = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
> + for (i = 0; i < NF_INET_NUMHOOKS && chains[i].name; i++) {
> + if (strcmp(name, chains[i].name))
> + continue;
>
> - ret = nft_is_chain_compatible(h, chain);
> - if (ret != 0)
> - break;
> -next:
> - chain = nftnl_chain_list_iter_next(iter);
> + chain = &chains[i];
> + break;
> }
> + if (!chain)
> + return -1;