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;