iptables: fix regression with unintended free in need_protomatch
[project/firewall3.git] / main.c
diff --git a/main.c b/main.c
index b95302050286d1d840caea0cc74313da0c46599d..7deb6361287f1d3e3d091b29c2c276c6889311ad 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1,7 +1,7 @@
 /*
  * firewall3 - 3rd OpenWrt UCI firewall implementation
  *
- *   Copyright (C) 2013-2014 Jo-Philipp Wich <jow@openwrt.org>
+ *   Copyright (C) 2013-2014 Jo-Philipp Wich <jo@mein.io>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -30,6 +30,7 @@
 #include "includes.h"
 #include "ubus.h"
 #include "iptables.h"
+#include "helpers.h"
 
 
 static enum fw3_family print_family = FW3_FAMILY_ANY;
@@ -79,7 +80,7 @@ build_state(bool runtime)
        else
        {
                if (!fw3_ubus_connect())
-                       error("Failed to connect to ubus");
+                       warn("Failed to connect to ubus");
 
                if (uci_load(state->uci, "firewall", &p))
                {
@@ -101,13 +102,14 @@ build_state(bool runtime)
        fw3_ubus_rules(&b);
 
        fw3_load_defaults(state, p);
-       fw3_load_ipsets(state, p);
+       fw3_load_cthelpers(state, p);
+       fw3_load_ipsets(state, p, b.head);
        fw3_load_zones(state, p);
        fw3_load_rules(state, p, b.head);
-       fw3_load_redirects(state, p);
+       fw3_load_redirects(state, p, b.head);
        fw3_load_snats(state, p, b.head);
-       fw3_load_forwards(state, p);
-       fw3_load_includes(state, p);
+       fw3_load_forwards(state, p, b.head);
+       fw3_load_includes(state, p, b.head);
 
        return true;
 }
@@ -138,6 +140,9 @@ free_state(struct fw3_state *state)
        list_for_each_safe(cur, tmp, &state->includes)
                fw3_free_include((struct fw3_include *)cur);
 
+       list_for_each_safe(cur, tmp, &state->cthelpers)
+               fw3_free_cthelper((struct fw3_cthelper *)cur);
+
        uci_free_context(state->uci);
 
        free(state);
@@ -190,9 +195,6 @@ stop(bool complete)
 
                for (table = FW3_TABLE_FILTER; table <= FW3_TABLE_RAW; table++)
                {
-                       if (!fw3_has_table(family == FW3_FAMILY_V6, fw3_flag_names[table]))
-                               continue;
-
                        if (!(handle = fw3_ipt_open(family, table)))
                                continue;
 
@@ -219,8 +221,10 @@ stop(bool complete)
                rv = 0;
        }
 
-       if (run_state)
-               fw3_destroy_ipsets(run_state);
+       if (run_state) {
+               for (family = FW3_FAMILY_V4; family <= FW3_FAMILY_V6; family++)
+                       fw3_destroy_ipsets(run_state, family, false);
+       }
 
        if (complete)
                fw3_flush_conntrack(NULL);
@@ -239,11 +243,11 @@ start(void)
        enum fw3_table table;
        struct fw3_ipt_handle *handle;
 
-       if (!print_family)
-               fw3_create_ipsets(cfg_state);
-
        for (family = FW3_FAMILY_V4; family <= FW3_FAMILY_V6; family++)
        {
+               if (!print_family)
+                       fw3_create_ipsets(cfg_state, family, false);
+
                if (family == FW3_FAMILY_V6 && cfg_state->defaults.disable_ipv6)
                        continue;
 
@@ -261,9 +265,6 @@ start(void)
 
                for (table = FW3_TABLE_FILTER; table <= FW3_TABLE_RAW; table++)
                {
-                       if (!fw3_has_table(family == FW3_FAMILY_V6, fw3_flag_names[table]))
-                               continue;
-
                        if (!(handle = fw3_ipt_open(family, table)))
                                continue;
 
@@ -332,9 +333,6 @@ reload(void)
 
                for (table = FW3_TABLE_FILTER; table <= FW3_TABLE_RAW; table++)
                {
-                       if (!fw3_has_table(family == FW3_FAMILY_V6, fw3_flag_names[table]))
-                               continue;
-
                        if (!(handle = fw3_ipt_open(family, table)))
                                continue;
 
@@ -347,6 +345,9 @@ reload(void)
                        fw3_ipt_close(handle);
                }
 
+               fw3_ipsets_update_run_state(family, run_state, cfg_state);
+               fw3_destroy_ipsets(run_state, family, true);
+
                family_set(run_state, family, false);
                family_set(cfg_state, family, false);
 
@@ -354,11 +355,10 @@ start:
                if (family == FW3_FAMILY_V6 && cfg_state->defaults.disable_ipv6)
                        continue;
 
+               fw3_create_ipsets(cfg_state, family, true);
+
                for (table = FW3_TABLE_FILTER; table <= FW3_TABLE_RAW; table++)
                {
-                       if (!fw3_has_table(family == FW3_FAMILY_V6, fw3_flag_names[table]))
-                               continue;
-
                        if (!(handle = fw3_ipt_open(family, table)))
                                continue;
 
@@ -414,9 +414,6 @@ gc(void)
 
                for (table = FW3_TABLE_FILTER; table <= FW3_TABLE_RAW; table++)
                {
-                       if (!fw3_has_table(family == FW3_FAMILY_V6, fw3_flag_names[table]))
-                               continue;
-
                        if (!(handle = fw3_ipt_open(family, table)))
                                continue;
 
@@ -546,7 +543,6 @@ int main(int argc, char **argv)
        }
 
        build_state(false);
-       build_state(true);
        defs = &cfg_state->defaults;
 
        if (optind >= argc)
@@ -577,12 +573,18 @@ int main(int argc, char **argv)
                print_family = family;
                fw3_pr_debug = true;
 
-               rv = start();
+               if (fw3_lock())
+               {
+                       build_state(true);
+                       rv = start();
+                       fw3_unlock();
+               }
        }
        else if (!strcmp(argv[optind], "start"))
        {
                if (fw3_lock())
                {
+                       build_state(true);
                        rv = start();
                        fw3_unlock();
                }
@@ -591,6 +593,7 @@ int main(int argc, char **argv)
        {
                if (fw3_lock())
                {
+                       build_state(true);
                        rv = stop(false);
                        fw3_unlock();
                }
@@ -599,6 +602,7 @@ int main(int argc, char **argv)
        {
                if (fw3_lock())
                {
+                       build_state(true);
                        rv = stop(true);
                        fw3_unlock();
                }
@@ -607,6 +611,7 @@ int main(int argc, char **argv)
        {
                if (fw3_lock())
                {
+                       build_state(true);
                        stop(true);
                        rv = start();
                        fw3_unlock();
@@ -616,6 +621,7 @@ int main(int argc, char **argv)
        {
                if (fw3_lock())
                {
+                       build_state(true);
                        rv = reload();
                        fw3_unlock();
                }