From 5df8137ebc5db2bc9c6e71b2d154a5f77679d9d8 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Thu, 21 Feb 2013 18:49:56 +0100 Subject: [PATCH] unify object freeing --- defaults.c | 7 +++--- defaults.h | 2 ++ forwards.c | 6 +++-- forwards.h | 5 +++- ipsets.c | 71 +++++++++++++++++++++++++++++------------------------ ipsets.h | 21 +++------------- options.c | 12 +++------ options.h | 2 +- redirects.c | 14 +++-------- redirects.h | 5 +++- rules.c | 23 +++-------------- rules.h | 5 +++- utils.c | 12 +++++++++ utils.h | 2 ++ zones.c | 19 +++----------- zones.h | 5 +++- 16 files changed, 100 insertions(+), 111 deletions(-) diff --git a/defaults.c b/defaults.c index 0992f58..e1710c2 100644 --- a/defaults.c +++ b/defaults.c @@ -60,7 +60,7 @@ static const struct chain toplevel_rules[] = { C(ANY, RAW, UNSPEC, "PREROUTING -j notrack"), }; -static struct fw3_option default_opts[] = { +const struct fw3_option fw3_default_opts[] = { FW3_OPT("input", target, defaults, policy_input), FW3_OPT("forward", target, defaults, policy_forward), FW3_OPT("output", target, defaults, policy_output), @@ -82,6 +82,8 @@ static struct fw3_option default_opts[] = { FW3_OPT("custom_chains", bool, defaults, custom_chains), FW3_OPT("disable_ipv6", bool, defaults, disable_ipv6), + + { } }; @@ -157,8 +159,7 @@ fw3_load_defaults(struct fw3_state *state, struct uci_package *p) continue; } - fw3_parse_options(&state->defaults, - default_opts, ARRAY_SIZE(default_opts), s); + fw3_parse_options(&state->defaults, fw3_default_opts, s); check_policy(e, &defs->policy_input, "input"); check_policy(e, &defs->policy_output, "output"); diff --git a/defaults.h b/defaults.h index 72f3eef..562b895 100644 --- a/defaults.h +++ b/defaults.h @@ -21,6 +21,8 @@ #include "options.h" +extern const struct fw3_option fw3_default_opts[]; + void fw3_load_defaults(struct fw3_state *state, struct uci_package *p); void fw3_print_default_chains(enum fw3_table table, enum fw3_family family, diff --git a/forwards.c b/forwards.c index 9abe4bf..9f658fc 100644 --- a/forwards.c +++ b/forwards.c @@ -19,12 +19,14 @@ #include "forwards.h" -static struct fw3_option forward_opts[] = { +const struct fw3_option fw3_forward_opts[] = { FW3_OPT("name", string, forward, name), FW3_OPT("family", family, forward, family), FW3_OPT("src", device, forward, src), FW3_OPT("dest", device, forward, dest), + + { } }; @@ -51,7 +53,7 @@ fw3_load_forwards(struct fw3_state *state, struct uci_package *p) memset(forward, 0, sizeof(*forward)); - fw3_parse_options(forward, forward_opts, ARRAY_SIZE(forward_opts), s); + fw3_parse_options(forward, fw3_forward_opts, s); if (forward->src.invert || forward->dest.invert) { diff --git a/forwards.h b/forwards.h index c3caff9..f512bb1 100644 --- a/forwards.h +++ b/forwards.h @@ -23,10 +23,13 @@ #include "zones.h" #include "utils.h" +extern const struct fw3_option fw3_forward_opts[]; + void fw3_load_forwards(struct fw3_state *state, struct uci_package *p); void fw3_print_forwards(enum fw3_table table, enum fw3_family family, struct fw3_state *state); -#define fw3_free_forward(forward) free(forward) +#define fw3_free_forward(forward) \ + fw3_free_object(forward, fw3_forward_opts) #endif diff --git a/ipsets.c b/ipsets.c index 62ed131..e2c8575 100644 --- a/ipsets.c +++ b/ipsets.c @@ -19,7 +19,7 @@ #include "ipsets.h" -static struct fw3_option ipset_opts[] = { +const struct fw3_option fw3_ipset_opts[] = { FW3_OPT("name", string, ipset, name), FW3_OPT("family", family, ipset, family), @@ -35,6 +35,8 @@ static struct fw3_option ipset_opts[] = { FW3_OPT("timeout", int, ipset, timeout), FW3_OPT("external", string, ipset, external), + + { } }; #define T(m, t1, t2, t3, r, o) \ @@ -42,27 +44,41 @@ static struct fw3_option ipset_opts[] = { FW3_IPSET_TYPE_##t1 | (FW3_IPSET_TYPE_##t2 << 8) | (FW3_IPSET_TYPE_##t3 << 16), \ r, o } -static struct fw3_ipset_settype ipset_types[] = { - T(BITMAP, IP, UNSPEC, UNSPEC, FW3_IPSET_OPT_IPRANGE, - FW3_IPSET_OPT_NETMASK), - T(BITMAP, IP, MAC, UNSPEC, FW3_IPSET_OPT_IPRANGE, 0), - T(BITMAP, PORT, UNSPEC, UNSPEC, FW3_IPSET_OPT_PORTRANGE, 0), +enum ipset_optflag { + OPT_IPRANGE = (1 << 0), + OPT_PORTRANGE = (1 << 1), + OPT_NETMASK = (1 << 2), + OPT_HASHSIZE = (1 << 3), + OPT_MAXELEM = (1 << 4), + OPT_FAMILY = (1 << 5), +}; + +struct ipset_type { + enum fw3_ipset_method method; + uint32_t types; + uint8_t required; + uint8_t optional; +}; + +static struct ipset_type ipset_types[] = { + T(BITMAP, IP, UNSPEC, UNSPEC, OPT_IPRANGE, OPT_NETMASK), + T(BITMAP, IP, MAC, UNSPEC, OPT_IPRANGE, 0), + T(BITMAP, PORT, UNSPEC, UNSPEC, OPT_PORTRANGE, 0), T(HASH, IP, UNSPEC, UNSPEC, 0, - FW3_IPSET_OPT_FAMILY | FW3_IPSET_OPT_HASHSIZE | FW3_IPSET_OPT_MAXELEM | - FW3_IPSET_OPT_NETMASK), + OPT_FAMILY | OPT_HASHSIZE | OPT_MAXELEM | OPT_NETMASK), T(HASH, NET, UNSPEC, UNSPEC, 0, - FW3_IPSET_OPT_FAMILY | FW3_IPSET_OPT_HASHSIZE | FW3_IPSET_OPT_MAXELEM), + OPT_FAMILY | OPT_HASHSIZE | OPT_MAXELEM), T(HASH, IP, PORT, UNSPEC, 0, - FW3_IPSET_OPT_FAMILY | FW3_IPSET_OPT_HASHSIZE | FW3_IPSET_OPT_MAXELEM), + OPT_FAMILY | OPT_HASHSIZE | OPT_MAXELEM), T(HASH, NET, PORT, UNSPEC, 0, - FW3_IPSET_OPT_FAMILY | FW3_IPSET_OPT_HASHSIZE | FW3_IPSET_OPT_MAXELEM), + OPT_FAMILY | OPT_HASHSIZE | OPT_MAXELEM), T(HASH, IP, PORT, IP, 0, - FW3_IPSET_OPT_FAMILY | FW3_IPSET_OPT_HASHSIZE | FW3_IPSET_OPT_MAXELEM), + OPT_FAMILY | OPT_HASHSIZE | OPT_MAXELEM), T(HASH, IP, PORT, NET, 0, - FW3_IPSET_OPT_FAMILY | FW3_IPSET_OPT_HASHSIZE | FW3_IPSET_OPT_MAXELEM), + OPT_FAMILY | OPT_HASHSIZE | OPT_MAXELEM), - T(LIST, SET, UNSPEC, UNSPEC, 0, FW3_IPSET_OPT_MAXELEM), + T(LIST, SET, UNSPEC, UNSPEC, 0, OPT_MAXELEM), }; @@ -119,56 +135,56 @@ check_types(struct uci_element *e, struct fw3_ipset *ipset) { if (!ipset->external || !*ipset->external) { - if ((ipset_types[i].required & FW3_IPSET_OPT_IPRANGE) && + if ((ipset_types[i].required & OPT_IPRANGE) && list_empty(&ipset->iprange)) { warn_elem(e, "requires an ip range"); return false; } - if ((ipset_types[i].required & FW3_IPSET_OPT_PORTRANGE) && + if ((ipset_types[i].required & OPT_PORTRANGE) && !ipset->portrange.set) { warn_elem(e, "requires a port range"); return false; } - if (!(ipset_types[i].required & FW3_IPSET_OPT_IPRANGE) && + if (!(ipset_types[i].required & OPT_IPRANGE) && !list_empty(&ipset->iprange)) { warn_elem(e, "iprange ignored"); fw3_free_list(&ipset->iprange); } - if (!(ipset_types[i].required & FW3_IPSET_OPT_PORTRANGE) && + if (!(ipset_types[i].required & OPT_PORTRANGE) && ipset->portrange.set) { warn_elem(e, "portrange ignored"); memset(&ipset->portrange, 0, sizeof(ipset->portrange)); } - if (!(ipset_types[i].optional & FW3_IPSET_OPT_NETMASK) && + if (!(ipset_types[i].optional & OPT_NETMASK) && ipset->netmask > 0) { warn_elem(e, "netmask ignored"); ipset->netmask = 0; } - if (!(ipset_types[i].optional & FW3_IPSET_OPT_HASHSIZE) && + if (!(ipset_types[i].optional & OPT_HASHSIZE) && ipset->hashsize > 0) { warn_elem(e, "hashsize ignored"); ipset->hashsize = 0; } - if (!(ipset_types[i].optional & FW3_IPSET_OPT_MAXELEM) && + if (!(ipset_types[i].optional & OPT_MAXELEM) && ipset->maxelem > 0) { warn_elem(e, "maxelem ignored"); ipset->maxelem = 0; } - if (!(ipset_types[i].optional & FW3_IPSET_OPT_FAMILY) && + if (!(ipset_types[i].optional & OPT_FAMILY) && ipset->family != FW3_FAMILY_ANY) { warn_elem(e, "family ignored"); @@ -226,7 +242,7 @@ fw3_load_ipsets(struct fw3_state *state, struct uci_package *p) if (!ipset) continue; - fw3_parse_options(ipset, ipset_opts, ARRAY_SIZE(ipset_opts), s); + fw3_parse_options(ipset, fw3_ipset_opts, s); if (!ipset->name || !*ipset->name) { @@ -384,15 +400,6 @@ fw3_destroy_ipsets(struct fw3_state *state) } } -void -fw3_free_ipset(struct fw3_ipset *ipset) -{ - fw3_free_list(&ipset->datatypes); - fw3_free_list(&ipset->iprange); - - free(ipset); -} - struct fw3_ipset * fw3_lookup_ipset(struct fw3_state *state, const char *name, bool running) { diff --git a/ipsets.h b/ipsets.h index 410c712..debe0e8 100644 --- a/ipsets.h +++ b/ipsets.h @@ -22,30 +22,17 @@ #include "options.h" #include "utils.h" -enum fw3_ipset_opts { - FW3_IPSET_OPT_IPRANGE = (1 << 0), - FW3_IPSET_OPT_PORTRANGE = (1 << 1), - FW3_IPSET_OPT_NETMASK = (1 << 2), - FW3_IPSET_OPT_HASHSIZE = (1 << 3), - FW3_IPSET_OPT_MAXELEM = (1 << 4), - FW3_IPSET_OPT_FAMILY = (1 << 5), -}; - -struct fw3_ipset_settype { - enum fw3_ipset_method method; - uint32_t types; - uint8_t required; - uint8_t optional; -}; +extern const struct fw3_option fw3_ipset_opts[]; struct fw3_ipset * fw3_alloc_ipset(void); 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 fw3_state *state); -void fw3_free_ipset(struct fw3_ipset *ipset); - struct fw3_ipset * fw3_lookup_ipset(struct fw3_state *state, const char *name, bool running); +#define fw3_free_ipset(ipset) \ + fw3_free_object(ipset, fw3_ipset_opts) + #endif diff --git a/options.c b/options.c index 1f10050..0de4775 100644 --- a/options.c +++ b/options.c @@ -498,16 +498,14 @@ fw3_parse_ipset_datatype(void *ptr, const char *val) void -fw3_parse_options(void *s, - struct fw3_option *opts, int n, +fw3_parse_options(void *s, const struct fw3_option *opts, struct uci_section *section) { - int i; char *p; bool known; struct uci_element *e, *l; struct uci_option *o; - struct fw3_option *opt; + const struct fw3_option *opt; struct list_head *item; struct list_head *dest; @@ -516,11 +514,9 @@ fw3_parse_options(void *s, o = uci_to_option(e); known = false; - for (i = 0; i < n; i++) + for (opt = opts; opt->name; opt++) { - opt = &opts[i]; - - if (!opt->parse || !opt->name) + if (!opt->parse) continue; if (strcmp(opt->name, e->name)) diff --git a/options.h b/options.h index c45a9d4..8115afc 100644 --- a/options.h +++ b/options.h @@ -413,7 +413,7 @@ bool fw3_parse_protocol(void *ptr, const char *val); bool fw3_parse_ipset_method(void *ptr, const char *val); bool fw3_parse_ipset_datatype(void *ptr, const char *val); -void fw3_parse_options(void *s, struct fw3_option *opts, int n, +void fw3_parse_options(void *s, const struct fw3_option *opts, struct uci_section *section); void fw3_format_in_out(struct fw3_device *in, struct fw3_device *out); diff --git a/redirects.c b/redirects.c index 627438b..51c764f 100644 --- a/redirects.c +++ b/redirects.c @@ -19,7 +19,7 @@ #include "redirects.h" -static struct fw3_option redirect_opts[] = { +const struct fw3_option fw3_redirect_opts[] = { FW3_OPT("name", string, redirect, name), FW3_OPT("family", family, redirect, family), @@ -45,6 +45,8 @@ static struct fw3_option redirect_opts[] = { FW3_OPT("reflection", bool, redirect, reflection), FW3_OPT("target", target, redirect, target), + + { } }; @@ -123,7 +125,7 @@ fw3_load_redirects(struct fw3_state *state, struct uci_package *p) redir->reflection = true; - fw3_parse_options(redir, redirect_opts, ARRAY_SIZE(redirect_opts), s); + fw3_parse_options(redir, fw3_redirect_opts, s); if (redir->src.invert) { @@ -465,11 +467,3 @@ fw3_print_redirects(enum fw3_table table, enum fw3_family family, list_for_each_entry(redir, &state->redirects, list) print_redirect(table, family, redir, num++); } - -void -fw3_free_redirect(struct fw3_redirect *redir) -{ - fw3_free_list(&redir->proto); - fw3_free_list(&redir->mac_src); - free(redir); -} diff --git a/redirects.h b/redirects.h index e8da040..4436f52 100644 --- a/redirects.h +++ b/redirects.h @@ -24,10 +24,13 @@ #include "ipsets.h" #include "ubus.h" +extern const struct fw3_option fw3_redirect_opts[]; + void fw3_load_redirects(struct fw3_state *state, struct uci_package *p); void fw3_print_redirects(enum fw3_table table, enum fw3_family family, struct fw3_state *state); -void fw3_free_redirect(struct fw3_redirect *redir); +#define fw3_free_redirect(redir) \ + fw3_free_object(redir, fw3_redirect_opts) #endif diff --git a/rules.c b/rules.c index 1979340..ab094bb 100644 --- a/rules.c +++ b/rules.c @@ -19,7 +19,7 @@ #include "rules.h" -static struct fw3_option rule_opts[] = { +const struct fw3_option fw3_rule_opts[] = { FW3_OPT("name", string, rule, name), FW3_OPT("family", family, rule, family), @@ -44,6 +44,8 @@ static struct fw3_option rule_opts[] = { FW3_OPT("limit_burst", int, rule, limit.burst), FW3_OPT("target", target, rule, target), + + { } }; @@ -81,7 +83,7 @@ fw3_load_rules(struct fw3_state *state, struct uci_package *p) INIT_LIST_HEAD(&rule->icmp_type); - fw3_parse_options(rule, rule_opts, ARRAY_SIZE(rule_opts), s); + fw3_parse_options(rule, fw3_rule_opts, s); if (rule->src.invert || rule->dest.invert) { @@ -331,20 +333,3 @@ fw3_print_rules(enum fw3_table table, enum fw3_family family, list_for_each_entry(rule, &state->rules, list) expand_rule(table, family, rule, num++); } - -void -fw3_free_rule(struct fw3_rule *rule) -{ - fw3_free_list(&rule->proto); - - fw3_free_list(&rule->ip_src); - fw3_free_list(&rule->mac_src); - fw3_free_list(&rule->port_dest); - - fw3_free_list(&rule->ip_dest); - fw3_free_list(&rule->port_dest); - - fw3_free_list(&rule->icmp_type); - - free(rule); -} diff --git a/rules.h b/rules.h index db93220..38d0df7 100644 --- a/rules.h +++ b/rules.h @@ -24,10 +24,13 @@ #include "ipsets.h" #include "utils.h" +extern const struct fw3_option fw3_rule_opts[]; + void fw3_load_rules(struct fw3_state *state, struct uci_package *p); void fw3_print_rules(enum fw3_table table, enum fw3_family family, struct fw3_state *state); -void fw3_free_rule(struct fw3_rule *rule); +#define fw3_free_rule(rule) \ + fw3_free_object(rule, fw3_rule_opts) #endif diff --git a/utils.c b/utils.c index c9ca206..f01ba73 100644 --- a/utils.c +++ b/utils.c @@ -483,3 +483,15 @@ fw3_set_running(void *object, struct list_head *dest) else if (!dest && o->running_list.next) list_del(&o->running_list); } + +void +fw3_free_object(void *obj, const void *opts) +{ + const struct fw3_option *ol; + + for (ol = opts; ol->name; ol++) + if (ol->elem_size) + fw3_free_list((struct list_head *)((char *)obj + ol->offset)); + + free(obj); +} diff --git a/utils.h b/utils.h index f157daf..43e2a22 100644 --- a/utils.h +++ b/utils.h @@ -92,4 +92,6 @@ void fw3_write_statefile(void *state); void fw3_set_running(void *object, struct list_head *dest); +void fw3_free_object(void *obj, const void *opts); + #endif diff --git a/zones.c b/zones.c index 317acc8..576ad42 100644 --- a/zones.c +++ b/zones.c @@ -51,7 +51,7 @@ static const struct chain dst_chains[] = { C(ANY, RAW, NOTRACK, "zone_%s_notrack"), }; -static struct fw3_option zone_opts[] = { +const struct fw3_option fw3_zone_opts[] = { FW3_OPT("name", string, zone, name), FW3_OPT("family", family, zone, family), @@ -77,6 +77,8 @@ static struct fw3_option zone_opts[] = { FW3_OPT("log", bool, zone, log), FW3_OPT("log_limit", limit, zone, log_limit), + + { } }; @@ -189,7 +191,7 @@ fw3_load_zones(struct fw3_state *state, struct uci_package *p) if (!zone) continue; - fw3_parse_options(zone, zone_opts, ARRAY_SIZE(zone_opts), s); + fw3_parse_options(zone, fw3_zone_opts, s); if (!zone->extra_dest) zone->extra_dest = zone->extra_src; @@ -520,16 +522,3 @@ fw3_lookup_zone(struct fw3_state *state, const char *name, bool running) return NULL; } - -void -fw3_free_zone(struct fw3_zone *zone) -{ - fw3_free_list(&zone->networks); - fw3_free_list(&zone->devices); - fw3_free_list(&zone->subnets); - - fw3_free_list(&zone->masq_src); - fw3_free_list(&zone->masq_dest); - - free(zone); -} diff --git a/zones.h b/zones.h index c462ea8..84619c2 100644 --- a/zones.h +++ b/zones.h @@ -21,6 +21,8 @@ #include "options.h" +extern const struct fw3_option fw3_zone_opts[]; + struct fw3_zone * fw3_alloc_zone(void); void fw3_load_zones(struct fw3_state *state, struct uci_package *p); @@ -37,6 +39,7 @@ void fw3_flush_zones(enum fw3_table table, enum fw3_family family, struct fw3_zone * fw3_lookup_zone(struct fw3_state *state, const char *name, bool running); -void fw3_free_zone(struct fw3_zone *zone); +#define fw3_free_zone(zone) \ + fw3_free_object(zone, fw3_zone_opts) #endif -- 2.25.1