When iterating through the list of rules in a chain comparing against a sample, there is no point in carrying that sample as nftnl_rule object and converting into iptables_command_state object prior to each comparison. Just do it up front and adjust the callback accordingly. Signed-off-by: Phil Sutter <phil@xxxxxx> --- iptables/nft.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/iptables/nft.c b/iptables/nft.c index 8b1803181b207..88be5ede5171d 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -2392,25 +2392,22 @@ static int __nft_rule_del(struct nft_handle *h, struct nftnl_rule *r) } static bool nft_rule_cmp(struct nft_handle *h, struct nftnl_rule *r, - struct nftnl_rule *rule) + struct iptables_command_state *cs) { - struct iptables_command_state _cs = {}, this = {}, *cs = &_cs; - bool ret = false, ret_this, ret_that; + struct iptables_command_state this = {}; + bool ret = false, ret_this; - if (h->ops->init_cs) { + if (h->ops->init_cs) h->ops->init_cs(&this); - h->ops->init_cs(cs); - } ret_this = h->ops->rule_to_cs(h, r, &this); - ret_that = h->ops->rule_to_cs(h, rule, cs); - DEBUGP("comparing with... "); + DEBUGP("with ... "); #ifdef DEBUG_DEL nft_rule_print_save(h, r, NFT_RULE_APPEND, 0); #endif - if (!ret_this || !ret_that) - DEBUGP("Cannot convert rules: %d %d\n", ret_this, ret_that); + if (!ret_this) + DEBUGP("Cannot convert rule: %d\n", ret_this); if (!h->ops->is_same(cs, &this)) goto out; @@ -2434,7 +2431,6 @@ static bool nft_rule_cmp(struct nft_handle *h, struct nftnl_rule *r, ret = true; out: h->ops->clear_cs(&this); - h->ops->clear_cs(cs); return ret; } @@ -2442,6 +2438,7 @@ static struct nftnl_rule * nft_rule_find(struct nft_handle *h, struct nft_chain *nc, struct nftnl_rule *rule, int rulenum) { + struct iptables_command_state cs = {}; struct nftnl_chain *c = nc->nftnl; struct nftnl_rule *r; struct nftnl_rule_iter *iter; @@ -2455,9 +2452,20 @@ nft_rule_find(struct nft_handle *h, struct nft_chain *nc, if (iter == NULL) return 0; + if (h->ops->init_cs) + h->ops->init_cs(&cs); + + if (!h->ops->rule_to_cs(h, rule, &cs)) + return NULL; + + DEBUGP("comparing ... "); +#ifdef DEBUG_DEL + nft_rule_print_save(h, rule, NFT_RULE_APPEND, 0); +#endif + r = nftnl_rule_iter_next(iter); while (r != NULL) { - found = nft_rule_cmp(h, r, rule); + found = nft_rule_cmp(h, r, &cs); if (found) break; r = nftnl_rule_iter_next(iter); @@ -2465,6 +2473,8 @@ nft_rule_find(struct nft_handle *h, struct nft_chain *nc, nftnl_rule_iter_destroy(iter); + h->ops->clear_cs(&cs); + return found ? r : NULL; } -- 2.43.0