#include "ipsets.h"
-static struct fw3_option ipset_opts[] = {
+const struct fw3_option fw3_ipset_opts[] = {
+ FW3_OPT("enabled", bool, ipset, enabled),
+
FW3_OPT("name", string, ipset, name),
FW3_OPT("family", family, ipset, family),
FW3_OPT("storage", ipset_method, ipset, method),
FW3_LIST("match", ipset_datatype, ipset, datatypes),
- FW3_LIST("iprange", address, ipset, iprange),
+ FW3_OPT("iprange", address, ipset, iprange),
FW3_OPT("portrange", port, ipset, portrange),
FW3_OPT("netmask", int, ipset, netmask),
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) &&
- list_empty(&ipset->iprange))
+ if ((ipset_types[i].required & OPT_IPRANGE) &&
+ !ipset->iprange.set)
{
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) &&
- !list_empty(&ipset->iprange))
+ if (!(ipset_types[i].required & OPT_IPRANGE) &&
+ ipset->iprange.set)
{
warn_elem(e, "iprange ignored");
- fw3_free_list(&ipset->iprange);
+ ipset->iprange.set = false;
}
- 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 = false;
}
- 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");
memset(ipset, 0, sizeof(*ipset));
INIT_LIST_HEAD(&ipset->datatypes);
- INIT_LIST_HEAD(&ipset->iprange);
return ipset;
}
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)
{
create_ipset(struct fw3_ipset *ipset, struct fw3_state *state)
{
bool first = true;
- char s[INET6_ADDRSTRLEN];
struct fw3_ipset_datatype *type;
- struct fw3_address *a1, *a2;
const char *methods[] = {
"(bug)",
if (ipset->external && *ipset->external)
return;
- info("Creating ipset %s", ipset->name);
+ info(" * Creating ipset %s", ipset->name);
first = true;
fw3_pr("create %s %s", ipset->name, methods[ipset->method]);
first = false;
}
- if (!list_empty(&ipset->iprange))
+ if (ipset->iprange.set)
{
- a1 = list_first_entry(&ipset->iprange, struct fw3_address, list);
- a2 = list_last_entry(&ipset->iprange, struct fw3_address, list);
-
- if (a1 == a2)
- {
- inet_ntop(a1->family == FW3_FAMILY_V4 ? AF_INET : AF_INET6,
- &a1->address.v6, s, sizeof(s));
-
- fw3_pr(" range %s/%u", s, a1->mask);
- }
- else if (a1->family == a2->family &&
- fw3_is_family(ipset, a1->family) &&
- fw3_is_family(ipset, a2->family))
- {
- inet_ntop(a1->family == FW3_FAMILY_V4 ? AF_INET : AF_INET6,
- &a1->address.v6, s, sizeof(s));
-
- fw3_pr(" range %s", s);
-
- inet_ntop(a2->family == FW3_FAMILY_V4 ? AF_INET : AF_INET6,
- &a2->address.v6, s, sizeof(s));
-
- fw3_pr("-%s", s);
- }
+ fw3_pr(" range %s", fw3_address_to_string(&ipset->iprange, false));
}
else if (ipset->portrange.set)
{
fw3_pr(" hashsize %u", ipset->hashsize);
fw3_pr("\n");
-
- fw3_set_running(ipset, &state->running_ipsets);
}
void
return;
list_for_each_entry(ipset, &state->ipsets, list)
- if (!fw3_lookup_ipset(state, ipset->name, true))
- create_ipset(ipset, state);
+ create_ipset(ipset, state);
fw3_pr("quit\n");
}
void
-fw3_destroy_ipsets(struct fw3_state *state)
+fw3_destroy_ipsets(struct fw3_state *state, enum fw3_family family)
{
struct fw3_ipset *s, *tmp;
- int mask = (1 << FW3_FAMILY_V4) | (1 << FW3_FAMILY_V6);
- list_for_each_entry_safe(s, tmp, &state->running_ipsets, running_list)
+ list_for_each_entry_safe(s, tmp, &state->ipsets, list)
{
- if (!hasbit(state->defaults.flags, FW3_FAMILY_V4))
- delbit(s->flags, FW3_FAMILY_V4);
-
- if (!hasbit(state->defaults.flags, FW3_FAMILY_V6))
- delbit(s->flags, FW3_FAMILY_V6);
+ del(s->flags, family, family);
- if (!(s->flags & mask))
+ if (fw3_no_family(s->flags[family == FW3_FAMILY_V6]))
{
- info("Deleting ipset %s", s->name);
+ info(" * Deleting ipset %s", s->name);
fw3_pr("flush %s\n", s->name);
fw3_pr("destroy %s\n", s->name);
-
- fw3_set_running(s, NULL);
}
}
}
-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)
+fw3_lookup_ipset(struct fw3_state *state, const char *name)
{
struct fw3_ipset *s;
if (strcmp(s->name, name))
continue;
- if (!running || s->running_list.next)
- return s;
-
- break;
+ return s;
}
return NULL;