From bb6873d86322a66bc01fc4195512ba5d2c78bddb Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Wed, 20 Feb 2013 00:58:02 +0100 Subject: [PATCH] rework ipset removal logic to only purge sets that are not in use by any family --- ipsets.c | 58 +++++++++++++++++++++++++++++++++++++++++++------------- ipsets.h | 5 ++--- main.c | 9 +++------ utils.c | 3 +++ 4 files changed, 53 insertions(+), 22 deletions(-) diff --git a/ipsets.c b/ipsets.c index ab86133..5e0d61f 100644 --- a/ipsets.c +++ b/ipsets.c @@ -266,7 +266,7 @@ create_ipset(struct fw3_ipset *ipset) if (ipset->external && *ipset->external) return; - info(" * %s", ipset->name); + info("Creating ipset %s", ipset->name); first = true; fw3_pr("create %s %s", ipset->name, methods[ipset->method]); @@ -328,37 +328,69 @@ create_ipset(struct fw3_ipset *ipset) fw3_pr("\n"); } +static bool +ipset_loaded(struct list_head *statefile, const char *name) +{ + struct fw3_statefile_entry *e; + int mask = (1 << FW3_FAMILY_V4) | (1 << FW3_FAMILY_V6); + + if (!statefile) + return false; + + list_for_each_entry(e, statefile, list) + { + if (e->type != FW3_TYPE_IPSET) + continue; + + if (!strcmp(e->name, name) && (e->flags[0] & mask)) + return true; + } + + return false; +} + void -fw3_create_ipsets(struct fw3_state *state) +fw3_create_ipsets(struct fw3_state *state, struct list_head *statefile) { struct fw3_ipset *ipset; if (state->disable_ipsets) return; - info("Initializing ipsets ..."); - list_for_each_entry(ipset, &state->ipsets, list) - create_ipset(ipset); + if (!ipset_loaded(statefile, ipset->name)) + create_ipset(ipset); fw3_pr("quit\n"); } void -fw3_destroy_ipsets(struct list_head *statefile) +fw3_destroy_ipsets(struct fw3_state *state, struct list_head *statefile) { + struct fw3_ipset *s; struct fw3_statefile_entry *e; + int mask = (1 << FW3_FAMILY_V4) | (1 << FW3_FAMILY_V6); + + if (!statefile) + return; - if (statefile) + list_for_each_entry(e, statefile, list) { - info("Destroying ipsets ..."); + if (e->type != FW3_TYPE_IPSET) + continue; - list_for_each_entry(e, statefile, list) - { - if (e->type != FW3_TYPE_IPSET) - continue; + if (!hasbit(state->defaults.flags, FW3_FAMILY_V4)) + delbit(e->flags[0], FW3_FAMILY_V4); + + if (!hasbit(state->defaults.flags, FW3_FAMILY_V6)) + delbit(e->flags[0], FW3_FAMILY_V6); - info(" * %s", e->name); + if ((s = fw3_lookup_ipset(state, e->name)) != NULL) + s->flags = e->flags[0]; + + if (!(e->flags[0] & mask)) + { + info("Deleting ipset %s", e->name); fw3_pr("flush %s\n", e->name); fw3_pr("destroy %s\n", e->name); diff --git a/ipsets.h b/ipsets.h index 49c6e66..a169979 100644 --- a/ipsets.h +++ b/ipsets.h @@ -39,9 +39,8 @@ struct fw3_ipset_settype { }; void fw3_load_ipsets(struct fw3_state *state, struct uci_package *p); -void fw3_create_ipsets(struct fw3_state *state); - -void fw3_destroy_ipsets(struct list_head *statefile); +void fw3_create_ipsets(struct fw3_state *state, struct list_head *statefile); +void fw3_destroy_ipsets(struct fw3_state *state, struct list_head *statefile); void fw3_free_ipset(struct fw3_ipset *ipset); diff --git a/main.c b/main.c index 3ef7243..23c1497 100644 --- a/main.c +++ b/main.c @@ -220,12 +220,9 @@ stop(struct fw3_state *state, bool complete, bool restart) rv = 0; } - if (!restart && - !family_loaded(state, FW3_FAMILY_V4) && - !family_loaded(state, FW3_FAMILY_V6) && - fw3_command_pipe(false, "ipset", "-exist", "-")) + if (!restart && fw3_command_pipe(false, "ipset", "-exist", "-")) { - fw3_destroy_ipsets(statefile); + fw3_destroy_ipsets(state, statefile); fw3_command_close(); } @@ -249,7 +246,7 @@ start(struct fw3_state *state, bool restart) if (!print_rules && !restart && fw3_command_pipe(false, "ipset", "-exist", "-")) { - fw3_create_ipsets(state); + fw3_create_ipsets(state, statefile); fw3_command_close(); } diff --git a/utils.c b/utils.c index 9b62789..1ba25fd 100644 --- a/utils.c +++ b/utils.c @@ -435,6 +435,9 @@ fw3_write_statefile(void *state) if (i->external && *i->external) continue; + if (!i->flags) + continue; + fprintf(sf, "%u %s %u\n", FW3_TYPE_IPSET, i->name, i->flags); } -- 2.25.1