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("custom_chains", bool, defaults, custom_chains),
FW3_OPT("disable_ipv6", bool, defaults, disable_ipv6),
+
+ { }
};
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");
#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,
#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),
+
+ { }
};
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)
{
#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
#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("timeout", int, ipset, timeout),
FW3_OPT("external", string, ipset, external),
+
+ { }
};
#define T(m, t1, t2, t3, 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,
- 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),
};
{
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");
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)
{
}
}
-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)
{
#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
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;
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))
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);
#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("reflection", bool, redirect, reflection),
FW3_OPT("target", target, redirect, target),
+
+ { }
};
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)
{
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);
-}
#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
#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("limit_burst", int, rule, limit.burst),
FW3_OPT("target", target, rule, target),
+
+ { }
};
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)
{
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);
-}
#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
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);
+}
void fw3_set_running(void *object, struct list_head *dest);
+void fw3_free_object(void *obj, const void *opts);
+
#endif
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("log", bool, zone, log),
FW3_OPT("log_limit", limit, zone, log_limit),
+
+ { }
};
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;
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);
-}
#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_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