X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=ipsets.c;h=ba31e645a8618a3ffaf481ac87d2daf9c5ad4b2a;hb=12f6f143106257e0921c6ebbca2fe329cbeb3de6;hp=b73c3d28c64d99d7769f44ca9ad0da6a19241111;hpb=41c2ab5e5cf62a4c04707145c65d37e27d82d63f;p=project%2Ffirewall3.git diff --git a/ipsets.c b/ipsets.c index b73c3d2..ba31e64 100644 --- a/ipsets.c +++ b/ipsets.c @@ -16,11 +16,16 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include + #include "ipsets.h" const struct fw3_option fw3_ipset_opts[] = { FW3_OPT("enabled", bool, ipset, enabled), + FW3_OPT("reload_set", bool, ipset, reload_set), + FW3_OPT("counters", bool, ipset, counters), + FW3_OPT("comment", bool, ipset, comment), FW3_OPT("name", string, ipset, name), FW3_OPT("family", family, ipset, family), @@ -204,6 +209,10 @@ check_types(struct uci_element *e, struct fw3_ipset *ipset) static bool check_ipset(struct fw3_state *state, struct fw3_ipset *ipset, struct uci_element *e) { + if (!ipset->enabled) { + return false; + } + if (ipset->external) { if (!*ipset->external) @@ -252,8 +261,11 @@ fw3_alloc_ipset(struct fw3_state *state) INIT_LIST_HEAD(&ipset->datatypes); INIT_LIST_HEAD(&ipset->entries); - ipset->enabled = true; - ipset->family = FW3_FAMILY_V4; + ipset->comment = false; + ipset->counters = false; + ipset->enabled = true; + ipset->family = FW3_FAMILY_V4; + ipset->reload_set = false; list_add_tail(&ipset->list, &state->ipsets); @@ -327,6 +339,7 @@ load_file(struct fw3_ipset *ipset) { FILE *f; char line[128]; + char *p; if (!ipset->loadfile) return; @@ -340,8 +353,13 @@ load_file(struct fw3_ipset *ipset) return; } - while (fgets(line, sizeof(line), f)) - fw3_pr("add %s %s", ipset->name, line); + while (fgets(line, sizeof(line), f)) { + p = line; + while (isspace(*p)) + p++; + if (*p && *p != '#') + fw3_pr("add %s %s", ipset->name, line); + } fclose(f); } @@ -389,6 +407,12 @@ create_ipset(struct fw3_ipset *ipset, struct fw3_state *state) if (ipset->hashsize > 0) fw3_pr(" hashsize %u", ipset->hashsize); + if (ipset->counters) + fw3_pr(" counters"); + + if (ipset->comment) + fw3_pr(" comment"); + fw3_pr("\n"); list_for_each_entry(entry, &ipset->entries, list) @@ -398,9 +422,10 @@ create_ipset(struct fw3_ipset *ipset, struct fw3_state *state) } void -fw3_create_ipsets(struct fw3_state *state) +fw3_create_ipsets(struct fw3_state *state, enum fw3_family family, + bool reload_set) { - int tries; + unsigned int delay, tries; bool exec = false; struct fw3_ipset *ipset; @@ -410,9 +435,16 @@ fw3_create_ipsets(struct fw3_state *state) /* spawn ipsets */ list_for_each_entry(ipset, &state->ipsets, list) { + if (ipset->family != family) + continue; + if (ipset->external) continue; + if (fw3_check_ipset(ipset) && + (reload_set && !ipset->reload_set)) + continue; + if (!exec) { exec = fw3_command_pipe(false, "ipset", "-exist", "-"); @@ -430,27 +462,36 @@ fw3_create_ipsets(struct fw3_state *state) fw3_command_close(); } - /* wait for ipsets to appear */ + /* wait a little expontially for ipsets to appear */ list_for_each_entry(ipset, &state->ipsets, list) { if (ipset->external) continue; + delay = 5; for (tries = 0; !fw3_check_ipset(ipset) && tries < 10; tries++) - usleep(50000); + usleep(delay<<1); } } void -fw3_destroy_ipsets(struct fw3_state *state) +fw3_destroy_ipsets(struct fw3_state *state, enum fw3_family family, + bool reload_set) { - int tries; + unsigned int delay, tries; bool exec = false; struct fw3_ipset *ipset; + if (state->disable_ipsets) + return; + /* destroy ipsets */ list_for_each_entry(ipset, &state->ipsets, list) { + if (ipset->family != family || + (reload_set && !ipset->reload_set)) + continue; + if (!exec) { exec = fw3_command_pipe(false, "ipset", "-exist", "-"); @@ -477,8 +518,9 @@ fw3_destroy_ipsets(struct fw3_state *state) if (ipset->external) continue; + delay = 5; for (tries = 0; fw3_check_ipset(ipset) && tries < 10; tries++) - usleep(50000); + usleep(delay<<1); } } @@ -537,3 +579,43 @@ out: return rv; } + +void +fw3_ipsets_update_run_state(enum fw3_family family, struct fw3_state *run_state, + struct fw3_state *cfg_state) +{ + struct fw3_ipset *ipset_run, *ipset_cfg; + bool in_cfg; + + list_for_each_entry(ipset_run, &run_state->ipsets, list) { + if (ipset_run->family != family) + continue; + + in_cfg = false; + + list_for_each_entry(ipset_cfg, &cfg_state->ipsets, list) { + if (ipset_cfg->family != family) + continue; + + if (strlen(ipset_run->name) == + strlen(ipset_cfg->name) && + !strcmp(ipset_run->name, ipset_cfg->name)) { + in_cfg = true; + break; + } + } + + /* If a set is found in run_state, but not in cfg_state then the + * set has been deleted/renamed. Set reload_set to true to force + * the old set to be destroyed in the "stop" fase of the reload. + * If the set is found, then copy the reload_set value from the + * configuration state. This ensures that the elements are + * always updated according to the configuration, and not the + * runtime state (which the user might have forgotten). + */ + if (!in_cfg) + ipset_run->reload_set = true; + else + ipset_run->reload_set = ipset_cfg->reload_set; + } +}