add support for includes
authorJo-Philipp Wich <jow@openwrt.org>
Fri, 22 Feb 2013 00:41:53 +0000 (01:41 +0100)
committerJo-Philipp Wich <jow@openwrt.org>
Fri, 22 Feb 2013 12:38:41 +0000 (13:38 +0100)
CMakeLists.txt
includes.c [new file with mode: 0644]
includes.h [new file with mode: 0644]
main.c
options.c
options.h

index e94494903f3877711c4fd6962a14e1a4233dda46..01d2c7c43cc10795373f5337abd4f7180f34cf04 100644 (file)
@@ -10,7 +10,7 @@ IF(APPLE)
   LINK_DIRECTORIES(/opt/local/lib)
 ENDIF()
 
-ADD_EXECUTABLE(firewall3 main.c options.c defaults.c zones.c forwards.c rules.c redirects.c utils.c ubus.c ipsets.c)
+ADD_EXECUTABLE(firewall3 main.c options.c defaults.c zones.c forwards.c rules.c redirects.c utils.c ubus.c ipsets.c includes.c)
 TARGET_LINK_LIBRARIES(firewall3 uci ubox ubus)
 
 SET(CMAKE_INSTALL_PREFIX /usr)
diff --git a/includes.c b/includes.c
new file mode 100644 (file)
index 0000000..40995ca
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * firewall3 - 3rd OpenWrt UCI firewall implementation
+ *
+ *   Copyright (C) 2013 Jo-Philipp Wich <jow@openwrt.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "includes.h"
+
+
+const struct fw3_option fw3_include_opts[] = {
+       FW3_OPT("path",                string,         include,     path),
+       FW3_OPT("type",                include_type,   include,     type),
+       FW3_OPT("family",              family,         include,     family),
+
+       { }
+};
+
+
+void
+fw3_load_includes(struct fw3_state *state, struct uci_package *p)
+{
+       struct uci_section *s;
+       struct uci_element *e;
+       struct fw3_include *include;
+
+       INIT_LIST_HEAD(&state->includes);
+
+       uci_foreach_element(&p->sections, e)
+       {
+               s = uci_to_section(e);
+
+               if (strcmp(s->type, "include"))
+                       continue;
+
+               include = malloc(sizeof(*include));
+
+               if (!include)
+                       continue;
+
+               memset(include, 0, sizeof(*include));
+               include->name = e->name;
+
+               fw3_parse_options(include, fw3_include_opts, s);
+
+               if (!include->path)
+               {
+                       warn_elem(e, "must specify a path");
+                       fw3_free_include(include);
+                       continue;
+               }
+
+               if (include->type == FW3_INC_TYPE_RESTORE && !include->family)
+                       warn_elem(e, "does not specify a family, include will get loaded "
+                                    "with both iptables-restore and ip6tables-restore!");
+
+               list_add_tail(&include->list, &state->includes);
+               continue;
+       }
+}
+
+
+static void
+print_include(enum fw3_family family, struct fw3_include *include)
+{
+       FILE *f;
+       char line[1024];
+
+       if (!fw3_is_family(include, family))
+               return;
+
+       info(" * Loading include '%s'", include->path);
+
+       if (!(f = fopen(include->path, "r")))
+       {
+               info("   ! Skipping due to open error: %s", strerror(errno));
+               return;
+       }
+
+       while (fgets(line, sizeof(line), f))
+               fw3_pr(line);
+
+       fclose(f);
+}
+
+void
+fw3_print_includes(enum fw3_family family, struct fw3_state *state)
+{
+       struct fw3_include *include;
+
+       list_for_each_entry(include, &state->includes, list)
+               if (include->type == FW3_INC_TYPE_RESTORE)
+                       print_include(family, include);
+}
+
+
+static void
+run_include(struct fw3_include *include)
+{
+       int rv;
+       struct stat s;
+       const char *tmpl =
+               "config() { "
+                       "echo \"You cannot use UCI in firewall includes!\" >&2; "
+                       "exit 1; "
+               "}; . %s";
+
+       char buf[PATH_MAX + sizeof(tmpl)];
+
+       info(" * Running script '%s'", include->path);
+
+       if (stat(include->path, &s))
+       {
+               info("   ! Skipping due to path error: %s", strerror(errno));
+               return;
+       }
+
+       snprintf(buf, sizeof(buf), tmpl, include->path);
+       rv = system(buf);
+
+       if (rv)
+               info("   ! Failed with exit code %u", WEXITSTATUS(rv));
+}
+
+void
+fw3_run_includes(struct fw3_state *state)
+{
+       struct fw3_include *include;
+
+       list_for_each_entry(include, &state->includes, list)
+               if (include->type == FW3_INC_TYPE_SCRIPT)
+                       run_include(include);
+}
diff --git a/includes.h b/includes.h
new file mode 100644 (file)
index 0000000..5c091b7
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * firewall3 - 3rd OpenWrt UCI firewall implementation
+ *
+ *   Copyright (C) 2013 Jo-Philipp Wich <jow@openwrt.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __FW3_INCLUDES_H
+#define __FW3_INCLUDES_H
+
+#include "options.h"
+#include "utils.h"
+
+extern const struct fw3_option fw3_include_opts[];
+
+void fw3_load_includes(struct fw3_state *state, struct uci_package *p);
+void fw3_print_includes(enum fw3_family family, struct fw3_state *state);
+void fw3_run_includes(struct fw3_state *state);
+
+#define fw3_free_include(include) \
+       fw3_free_object(include, fw3_include_opts)
+
+#endif
diff --git a/main.c b/main.c
index 62f51e1bbb30dd4a8e2fa6de2dad7f1ae77254cf..e5848276f420432cadf2d8c05a76d3c1f5a55a4e 100644 (file)
--- a/main.c
+++ b/main.c
@@ -26,6 +26,7 @@
 #include "redirects.h"
 #include "forwards.h"
 #include "ipsets.h"
+#include "includes.h"
 #include "ubus.h"
 
 
@@ -71,6 +72,7 @@ build_state(void)
        fw3_load_rules(state, p);
        fw3_load_redirects(state, p);
        fw3_load_forwards(state, p);
+       fw3_load_includes(state, p);
 
        state->statefile = fw3_read_statefile(state);
 
@@ -97,6 +99,9 @@ free_state(struct fw3_state *state)
        list_for_each_safe(cur, tmp, &state->ipsets)
                fw3_free_ipset((struct fw3_ipset *)cur);
 
+       list_for_each_safe(cur, tmp, &state->includes)
+               fw3_free_include((struct fw3_include *)cur);
+
        uci_free_context(state->uci);
 
        free(state);
index d924a2af33aa28b0555739eb10d213ad25942e67..3f8c977beabd490e201542a0e52d59a5e095c34e 100644 (file)
--- a/options.c
+++ b/options.c
@@ -672,6 +672,19 @@ fw3_parse_monthdays(void *ptr, const char *val)
        return true;
 }
 
+bool
+fw3_parse_include_type(void *ptr, const char *val)
+{
+       if (!strcmp(val, "script"))
+               *((enum fw3_include_type *)ptr) = FW3_INC_TYPE_SCRIPT;
+       else if (!strcmp(val, "restore"))
+               *((enum fw3_include_type *)ptr) = FW3_INC_TYPE_RESTORE;
+       else
+               return false;
+
+       return true;
+}
+
 
 void
 fw3_parse_options(void *s, const struct fw3_option *opts,
index fe9816e495e30b647696696728ab909fe6b7366e..a9257a3685ab1ab58635fa361d78b99d6cbf6a2d 100644 (file)
--- a/options.h
+++ b/options.h
@@ -110,6 +110,12 @@ enum fw3_ipset_type
        FW3_IPSET_TYPE_SET    = 5,
 };
 
+enum fw3_include_type
+{
+       FW3_INC_TYPE_SCRIPT   = 0,
+       FW3_INC_TYPE_RESTORE  = 1,
+};
+
 struct fw3_ipset_datatype
 {
        struct list_head list;
@@ -385,6 +391,18 @@ struct fw3_ipset
        uint16_t flags;
 };
 
+struct fw3_include
+{
+       struct list_head list;
+       struct list_head running_list;
+
+       const char *name;
+       enum fw3_family family;
+
+       const char *path;
+       enum fw3_include_type type;
+};
+
 struct fw3_state
 {
        struct uci_context *uci;
@@ -394,6 +412,7 @@ struct fw3_state
        struct list_head redirects;
        struct list_head forwards;
        struct list_head ipsets;
+       struct list_head includes;
 
        struct fw3_defaults running_defaults;
        struct list_head running_zones;
@@ -436,6 +455,8 @@ bool fw3_parse_protocol(void *ptr, const char *val);
 bool fw3_parse_ipset_method(void *ptr, const char *val);
 bool fw3_parse_ipset_datatype(void *ptr, const char *val);
 
+bool fw3_parse_include_type(void *ptr, const char *val);
+
 bool fw3_parse_date(void *ptr, const char *val);
 bool fw3_parse_time(void *ptr, const char *val);
 bool fw3_parse_weekdays(void *ptr, const char *val);