unify object freeing
authorJo-Philipp Wich <jow@openwrt.org>
Thu, 21 Feb 2013 17:49:56 +0000 (18:49 +0100)
committerJo-Philipp Wich <jow@openwrt.org>
Thu, 21 Feb 2013 18:12:01 +0000 (19:12 +0100)
16 files changed:
defaults.c
defaults.h
forwards.c
forwards.h
ipsets.c
ipsets.h
options.c
options.h
redirects.c
redirects.h
rules.c
rules.h
utils.c
utils.h
zones.c
zones.h

index 0992f58..e1710c2 100644 (file)
@@ -60,7 +60,7 @@ static const struct chain toplevel_rules[] = {
        C(ANY, RAW,    UNSPEC,        "PREROUTING -j notrack"),
 };
 
        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),
        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),
 
        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;
                }
 
                        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");
 
                check_policy(e, &defs->policy_input, "input");
                check_policy(e, &defs->policy_output, "output");
index 72f3eef..562b895 100644 (file)
@@ -21,6 +21,8 @@
 
 #include "options.h"
 
 
 #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,
 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,
index 9abe4bf..9f658fc 100644 (file)
 #include "forwards.h"
 
 
 #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),
        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));
 
 
                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)
                {
 
                if (forward->src.invert || forward->dest.invert)
                {
index c3caff9..f512bb1 100644 (file)
 #include "zones.h"
 #include "utils.h"
 
 #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);
 
 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
 
 #endif
index 62ed131..e2c8575 100644 (file)
--- a/ipsets.c
+++ b/ipsets.c
@@ -19,7 +19,7 @@
 #include "ipsets.h"
 
 
 #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),
 
        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),
        FW3_OPT("timeout",       int,            ipset,     timeout),
 
        FW3_OPT("external",      string,         ipset,     external),
+
+       { }
 };
 
 #define T(m, t1, t2, t3, r, o) \
 };
 
 #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 }
 
          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,
 
        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,
        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,
        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,
        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,
        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,
        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->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;
                                }
 
                                        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;
                                }
 
                                    !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);
                                }
 
                                    !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));
                                }
 
                                    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;
                                }
 
                                    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;
                                }
 
                                    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;
                                }
 
                                    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");
                                    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;
 
                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)
                {
 
                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)
 {
 struct fw3_ipset *
 fw3_lookup_ipset(struct fw3_state *state, const char *name, bool running)
 {
index 410c712..debe0e8 100644 (file)
--- a/ipsets.h
+++ b/ipsets.h
 #include "options.h"
 #include "utils.h"
 
 #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);
 
 
 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);
 
 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
 #endif
index 1f10050..0de4775 100644 (file)
--- a/options.c
+++ b/options.c
@@ -498,16 +498,14 @@ fw3_parse_ipset_datatype(void *ptr, const char *val)
 
 
 void
 
 
 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)
 {
                   struct uci_section *section)
 {
-       int i;
        char *p;
        bool known;
        struct uci_element *e, *l;
        struct uci_option *o;
        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;
 
        struct list_head *item;
        struct list_head *dest;
 
@@ -516,11 +514,9 @@ fw3_parse_options(void *s,
                o = uci_to_option(e);
                known = false;
 
                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))
                                continue;
 
                        if (strcmp(opt->name, e->name))
index c45a9d4..8115afc 100644 (file)
--- 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);
 
 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);
                        struct uci_section *section);
 
 void fw3_format_in_out(struct fw3_device *in, struct fw3_device *out);
index 627438b..51c764f 100644 (file)
@@ -19,7 +19,7 @@
 #include "redirects.h"
 
 
 #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),
 
        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),
        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;
 
 
                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)
                {
 
                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++);
 }
        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);
-}
index e8da040..4436f52 100644 (file)
 #include "ipsets.h"
 #include "ubus.h"
 
 #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_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
 
 #endif
diff --git a/rules.c b/rules.c
index 1979340..ab094bb 100644 (file)
--- a/rules.c
+++ b/rules.c
@@ -19,7 +19,7 @@
 #include "rules.h"
 
 
 #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),
 
        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),
        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);
 
 
                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)
                {
 
                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++);
 }
        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 (file)
--- a/rules.h
+++ b/rules.h
 #include "ipsets.h"
 #include "utils.h"
 
 #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_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
 
 #endif
diff --git a/utils.c b/utils.c
index c9ca206..f01ba73 100644 (file)
--- 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);
 }
        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 (file)
--- 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_set_running(void *object, struct list_head *dest);
 
+void fw3_free_object(void *obj, const void *opts);
+
 #endif
 #endif
diff --git a/zones.c b/zones.c
index 317acc8..576ad42 100644 (file)
--- a/zones.c
+++ b/zones.c
@@ -51,7 +51,7 @@ static const struct chain dst_chains[] = {
        C(ANY, RAW,    NOTRACK, "zone_%s_notrack"),
 };
 
        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),
 
        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),
 
        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;
 
                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;
 
                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;
 }
 
        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 (file)
--- a/zones.h
+++ b/zones.h
@@ -21,6 +21,8 @@
 
 #include "options.h"
 
 
 #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);
 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);
 
 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
 
 #endif