rework runtime state tracking
[project/firewall3.git] / ipsets.c
index 3d659e2..62ed131 100644 (file)
--- a/ipsets.c
+++ b/ipsets.c
@@ -184,6 +184,24 @@ 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);
+       INIT_LIST_HEAD(&ipset->iprange);
+
+       return ipset;
+}
+
 void
 fw3_load_ipsets(struct fw3_state *state, struct uci_package *p)
 {
@@ -203,16 +221,11 @@ 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);
 
                if (!ipset->name || !*ipset->name)
@@ -239,7 +252,7 @@ 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];
@@ -263,16 +276,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]);
@@ -317,7 +324,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);
@@ -332,6 +339,8 @@ create_ipset(struct fw3_ipset *ipset)
                fw3_pr(" hashsize %u", ipset->hashsize);
 
        fw3_pr("\n");
+
+       fw3_set_running(ipset, &state->running_ipsets);
 }
 
 void
@@ -342,10 +351,9 @@ 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);
+               if (!fw3_lookup_ipset(state, ipset->name, true))
+                       create_ipset(ipset, state);
 
        fw3_pr("quit\n");
 }
@@ -353,25 +361,27 @@ fw3_create_ipsets(struct fw3_state *state)
 void
 fw3_destroy_ipsets(struct fw3_state *state)
 {
-       struct fw3_ipset *ipset;
+       struct fw3_ipset *s, *tmp;
+       int mask = (1 << FW3_FAMILY_V4) | (1 << FW3_FAMILY_V6);
 
-       if (state->disable_ipsets)
-               return;
+       list_for_each_entry_safe(s, tmp, &state->running_ipsets, running_list)
+       {
+               if (!hasbit(state->defaults.flags, FW3_FAMILY_V4))
+                       delbit(s->flags, FW3_FAMILY_V4);
 
-       info("Destroying ipsets ...");
+               if (!hasbit(state->defaults.flags, FW3_FAMILY_V6))
+                       delbit(s->flags, FW3_FAMILY_V6);
 
-       list_for_each_entry(ipset, &state->ipsets, list)
-       {
-               if (ipset->external && *ipset->external)
-                       continue;
+               if (!(s->flags & mask))
+               {
+                       info("Deleting ipset %s", s->name);
 
-               info(" * %s", ipset->name);
+                       fw3_pr("flush %s\n", s->name);
+                       fw3_pr("destroy %s\n", s->name);
 
-               fw3_pr("flush %s\n", ipset->name);
-               fw3_pr("destroy %s\n", ipset->name);
+                       fw3_set_running(s, NULL);
+               }
        }
-
-       fw3_pr("quit\n");
 }
 
 void
@@ -384,16 +394,23 @@ fw3_free_ipset(struct fw3_ipset *ipset)
 }
 
 struct fw3_ipset *
-fw3_lookup_ipset(struct fw3_state *state, const char *name)
+fw3_lookup_ipset(struct fw3_state *state, const char *name, bool running)
 {
-       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;
+
+               if (!running || s->running_list.next)
+                       return s;
+
+               break;
+       }
 
        return NULL;
 }