X-Git-Url: http://git.archive.openwrt.org/?p=project%2Ffirewall3.git;a=blobdiff_plain;f=ipsets.c;h=eb37d0a82e6a831462ca19bf4825640b07c2b02a;hp=f4253c7bab64b467a5ca59d0a2813678084029ce;hb=b64f6ca3d43dabc651b829fc7c71d95ed791aee2;hpb=5b051a66fad3c208380d69b4b13d09929fcfe101 diff --git a/ipsets.c b/ipsets.c index f4253c7..eb37d0a 100644 --- a/ipsets.c +++ b/ipsets.c @@ -19,14 +19,16 @@ #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), @@ -35,6 +37,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 +46,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 +137,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) && - 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"); @@ -184,6 +202,25 @@ check_types(struct uci_element *e, struct fw3_ipset *ipset) return false; } +struct fw3_ipset * +fw3_alloc_ipset(void) +{ + struct fw3_ipset *ipset; + + ipset = malloc(sizeof(*ipset)); + + if (!ipset) + return NULL; + + memset(ipset, 0, sizeof(*ipset)); + + INIT_LIST_HEAD(&ipset->datatypes); + + ipset->enabled = true; + + return ipset; +} + void fw3_load_ipsets(struct fw3_state *state, struct uci_package *p) { @@ -203,17 +240,12 @@ fw3_load_ipsets(struct fw3_state *state, struct uci_package *p) if (strcmp(s->type, "ipset")) continue; - ipset = malloc(sizeof(*ipset)); + ipset = fw3_alloc_ipset(); if (!ipset) continue; - memset(ipset, 0, sizeof(*ipset)); - - INIT_LIST_HEAD(&ipset->datatypes); - INIT_LIST_HEAD(&ipset->iprange); - - fw3_parse_options(ipset, ipset_opts, ARRAY_SIZE(ipset_opts), s); + fw3_parse_options(ipset, fw3_ipset_opts, s); if (!ipset->name || !*ipset->name) { @@ -239,13 +271,11 @@ fw3_load_ipsets(struct fw3_state *state, struct uci_package *p) static void -create_ipset(struct fw3_ipset *ipset) +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)", @@ -263,16 +293,10 @@ create_ipset(struct fw3_ipset *ipset) "set", }; - const char *families[] = { - "(bug)", - "inet", - "inet6", - }; - if (ipset->external && *ipset->external) return; - info(" * %s", ipset->name); + info(" * Creating ipset %s", ipset->name); first = true; fw3_pr("create %s %s", ipset->name, methods[ipset->method]); @@ -283,32 +307,9 @@ create_ipset(struct fw3_ipset *ipset) 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) { @@ -317,7 +318,7 @@ create_ipset(struct fw3_ipset *ipset) } if (ipset->family != FW3_FAMILY_ANY) - fw3_pr(" family %s", families[ipset->family]); + fw3_pr(" family inet%s", (ipset->family == FW3_FAMILY_V4) ? "" : "6"); if (ipset->timeout > 0) fw3_pr(" timeout %u", ipset->timeout); @@ -342,56 +343,43 @@ fw3_create_ipsets(struct fw3_state *state) if (state->disable_ipsets) return; - info("Initializing ipsets ..."); - list_for_each_entry(ipset, &state->ipsets, list) - create_ipset(ipset); + create_ipset(ipset, state); fw3_pr("quit\n"); } void -fw3_destroy_ipsets(struct list_head *statefile) +fw3_destroy_ipsets(struct fw3_state *state) { - struct fw3_statefile_entry *e; + struct fw3_ipset *s; - if (statefile) + list_for_each_entry(s, &state->ipsets, list) { - info("Destroying ipsets ..."); - - list_for_each_entry(e, statefile, list) - { - if (e->type != FW3_TYPE_IPSET) - continue; - - info(" * %s", e->name); + info(" * Deleting ipset %s", s->name); - fw3_pr("flush %s\n", e->name); - fw3_pr("destroy %s\n", e->name); - } + fw3_pr("flush %s\n", s->name); + fw3_pr("destroy %s\n", s->name); } -} - -void -fw3_free_ipset(struct fw3_ipset *ipset) -{ - fw3_free_list(&ipset->datatypes); - fw3_free_list(&ipset->iprange); - free(ipset); + fw3_pr("quit\n"); } struct fw3_ipset * fw3_lookup_ipset(struct fw3_state *state, const char *name) { - struct fw3_ipset *ipset; + struct fw3_ipset *s; if (list_empty(&state->ipsets)) return NULL; - list_for_each_entry(ipset, &state->ipsets, list) - if (!strcmp(ipset->name, name)) - return ipset; + list_for_each_entry(s, &state->ipsets, list) + { + if (strcmp(s->name, name)) + continue; + + return s; + } return NULL; }