This patch is an attempt at improving the ipset support in firewall3. The following changes have been made:
* The enabled option did not work properly for ipsets, as it was not checked on create/destroy of a set. After this commit, sets are only created/destroyed if enabled is set to true. * Add support for reloading, or recreating, ipsets on firewall reload. By setting "reload_set" to true, the set will be destroyed and then re-created when the firewall is reloaded. My use-case for "reload_set" was to reset sets populated by dnsmasq, without having to restart the firewall or resort to scripts. * Add support for the counters and comment extensions. By setting "counters" or "comment" to true, then counters or comments are added to the set. Signed-off-by: Kristian Evensen <kristian.even...@gmail.com> --- ipsets.c | 35 +++++++++++++++++++++++++++++++++-- ipsets.h | 6 ++++-- main.c | 16 +++++++++++----- options.h | 4 ++++ utils.c | 5 +++++ 5 files changed, 57 insertions(+), 9 deletions(-) diff --git a/ipsets.c b/ipsets.c index b73c3d2..49ba672 100644 --- a/ipsets.c +++ b/ipsets.c @@ -21,6 +21,9 @@ 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), @@ -56,6 +59,8 @@ enum ipset_optflag { OPT_HASHSIZE = (1 << 3), OPT_MAXELEM = (1 << 4), OPT_FAMILY = (1 << 5), + OPT_COUNTERS = (1 << 6), + OPT_COMMENT = (1 << 7), }; struct ipset_type { @@ -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) @@ -253,6 +262,9 @@ fw3_alloc_ipset(struct fw3_state *state) INIT_LIST_HEAD(&ipset->entries); ipset->enabled = true; + ipset->reload_set = false; + ipset->counters = false; + ipset->comment = false; ipset->family = FW3_FAMILY_V4; list_add_tail(&ipset->list, &state->ipsets); @@ -389,6 +401,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,7 +416,8 @@ 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; bool exec = false; @@ -410,6 +429,10 @@ fw3_create_ipsets(struct fw3_state *state) /* spawn ipsets */ list_for_each_entry(ipset, &state->ipsets, list) { + if (ipset->family != family || + (reload_set && !ipset->reload_set)) + continue; + if (ipset->external) continue; @@ -442,15 +465,23 @@ fw3_create_ipsets(struct fw3_state *state) } void -fw3_destroy_ipsets(struct fw3_state *state) +fw3_destroy_ipsets(struct fw3_state *state, enum fw3_family family, + bool reload_set) { int 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", "-"); diff --git a/ipsets.h b/ipsets.h index 2ba862d..fec79f8 100644 --- a/ipsets.h +++ b/ipsets.h @@ -28,8 +28,10 @@ extern const struct fw3_option fw3_ipset_opts[]; void fw3_load_ipsets(struct fw3_state *state, struct uci_package *p, struct blob_attr *a); -void fw3_create_ipsets(struct fw3_state *state); -void fw3_destroy_ipsets(struct fw3_state *state); +void fw3_create_ipsets(struct fw3_state *state, enum fw3_family family, + bool reload_set); +void fw3_destroy_ipsets(struct fw3_state *state, enum fw3_family family, + bool reload_set); struct fw3_ipset * fw3_lookup_ipset(struct fw3_state *state, const char *name); diff --git a/main.c b/main.c index 1410fef..8d9a2e8 100644 --- a/main.c +++ b/main.c @@ -224,8 +224,10 @@ stop(bool complete) rv = 0; } - if (run_state) - fw3_destroy_ipsets(run_state); + if (run_state) { + for (family = FW3_FAMILY_V4; family <= FW3_FAMILY_V6; family++) + fw3_destroy_ipsets(run_state, family, false); + } if (complete) fw3_flush_conntrack(NULL); @@ -244,11 +246,11 @@ start(void) enum fw3_table table; struct fw3_ipt_handle *handle; - if (!print_family) - fw3_create_ipsets(cfg_state); - for (family = FW3_FAMILY_V4; family <= FW3_FAMILY_V6; family++) { + if (!print_family) + fw3_create_ipsets(cfg_state, family, false); + if (family == FW3_FAMILY_V6 && cfg_state->defaults.disable_ipv6) continue; @@ -352,6 +354,8 @@ reload(void) fw3_ipt_close(handle); } + fw3_destroy_ipsets(run_state, family, true); + family_set(run_state, family, false); family_set(cfg_state, family, false); @@ -359,6 +363,8 @@ start: if (family == FW3_FAMILY_V6 && cfg_state->defaults.disable_ipv6) continue; + fw3_create_ipsets(cfg_state, family, true); + for (table = FW3_TABLE_FILTER; table <= FW3_TABLE_RAW; table++) { if (!fw3_has_table(family == FW3_FAMILY_V6, fw3_flag_names[table])) diff --git a/options.h b/options.h index a75cfa3..cffc01c 100644 --- a/options.h +++ b/options.h @@ -501,6 +501,10 @@ struct fw3_ipset struct list_head list; bool enabled; + bool reload_set; + bool counters; + bool comment; + const char *name; enum fw3_family family; diff --git a/utils.c b/utils.c index 7f09787..cd5e7de 100644 --- a/utils.c +++ b/utils.c @@ -585,6 +585,11 @@ write_ipset_uci(struct uci_context *ctx, struct fw3_ipset *s, ptr.value = s->name; uci_set(ctx, &ptr); + ptr.o = NULL; + ptr.option = "reload_set"; + ptr.value = s->reload_set ? "true" : "false"; + uci_set(ctx, &ptr); + ptr.o = NULL; ptr.option = "storage"; ptr.value = fw3_ipset_method_names[s->method]; -- 2.19.1 _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel