We cannot assume iptables-restore files always come with explicit basechain definition, eg. :PREROUTING ACCEPT incremental ruleset updates may deliberately skip this. But loading basechains over and over again can take time, so do it just once per batch. Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> --- v2: skip inconditional initialization of basechains, do it just once. iptables/nft.c | 48 ++++++++++++++++++++++++++++-------------------- iptables/nft.h | 1 + 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/iptables/nft.c b/iptables/nft.c index 37aa0b2ee8c5..ba98230f1006 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -523,9 +523,6 @@ static int nft_table_builtin_add(struct nft_handle *h, ret = batch_table_add(h, NFT_COMPAT_TABLE_ADD, t); - if (ret == 0) - _t->initialized = true; - return ret; } @@ -623,22 +620,23 @@ static void nft_chain_builtin_init(struct nft_handle *h, static int nft_xt_builtin_init(struct nft_handle *h, const char *table) { - int ret = 0; struct builtin_table *t; t = nft_table_builtin_find(h, table); - if (t == NULL) { - ret = -1; - goto out; - } - if (nft_table_builtin_add(h, t) < 0) { - /* Built-in table already initialized, skip. */ - if (errno == EEXIST) - goto out; - } + if (t == NULL) + return -1; + + if (t->initialized) + return 0; + + if (nft_table_builtin_add(h, t) < 0) + return -1; + nft_chain_builtin_init(h, t); -out: - return ret; + + t->initialized = true; + + return 0; } static bool nft_chain_builtin(struct nftnl_chain *c) @@ -2539,8 +2537,8 @@ static void xtables_config_perror(uint32_t flags, const char *fmt, ...) va_end(args); } -int nft_xtables_config_load(struct nft_handle *h, const char *filename, - uint32_t flags) +static int __nft_xtables_config_load(struct nft_handle *h, const char *filename, + uint32_t flags) { struct nftnl_table_list *table_list = NULL; struct nftnl_chain_list *chain_list = NULL; @@ -2551,9 +2549,6 @@ int nft_xtables_config_load(struct nft_handle *h, const char *filename, uint32_t table_family, chain_family; bool found = false; - if (h->restore) - return 0; - table_list = nftnl_table_list_alloc(); chain_list = nftnl_chain_list_alloc(); @@ -2635,6 +2630,8 @@ int nft_xtables_config_load(struct nft_handle *h, const char *filename, nftnl_chain_list_iter_destroy(citer); nftnl_chain_list_free(chain_list); + h->config_done = 1; + return 0; err: @@ -2646,9 +2643,20 @@ err: if (citer != NULL) nftnl_chain_list_iter_destroy(citer); + h->config_done = -1; + return -1; } +int nft_xtables_config_load(struct nft_handle *h, const char *filename, + uint32_t flags) +{ + if (!h->config_done) + return __nft_xtables_config_load(h, filename, flags); + + return h->config_done; +} + int nft_chain_zero_counters(struct nft_handle *h, const char *chain, const char *table) { diff --git a/iptables/nft.h b/iptables/nft.h index 515832d7e37b..d4a78b088940 100644 --- a/iptables/nft.h +++ b/iptables/nft.h @@ -38,6 +38,7 @@ struct nft_handle { struct builtin_table *tables; struct nftnl_rule_list *rule_cache; bool restore; + int8_t config_done; }; extern struct builtin_table xtables_ipv4[TABLES_MAX]; -- 2.11.0 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html