/*
* firewall3 - 3rd OpenWrt UCI firewall implementation
*
- * Copyright (C) 2013 Jo-Philipp Wich <jow@openwrt.org>
+ * Copyright (C) 2013 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
{ }
};
+static bool
+check_include(struct fw3_state *state, struct fw3_include *include, struct uci_element *e)
+{
+ if (!include->enabled)
+ return false;
+
+ if (!include->path)
+ {
+ warn_section("include", include, e, "must specify a path");
+ return false;
+ }
+
+ if (include->type == FW3_INC_TYPE_RESTORE && !include->family)
+ warn_section("include", include, e, "does not specify a family, include will get"
+ "loaded with both iptables-restore and ip6tables-restore!");
+
+ return true;
+}
+
+static struct fw3_include *
+fw3_alloc_include(struct fw3_state *state)
+{
+ struct fw3_include *include;
+
+ include = calloc(1, sizeof(*include));
+ if (!include)
+ return NULL;
+
+ include->enabled = true;
+
+ list_add_tail(&include->list, &state->includes);
+
+ return include;
+}
void
-fw3_load_includes(struct fw3_state *state, struct uci_package *p)
+fw3_load_includes(struct fw3_state *state, struct uci_package *p,
+ struct blob_attr *a)
{
struct uci_section *s;
struct uci_element *e;
struct fw3_include *include;
+ struct blob_attr *entry;
+ unsigned rem;
INIT_LIST_HEAD(&state->includes);
- uci_foreach_element(&p->sections, e)
+ blob_for_each_attr(entry, a, rem)
{
- s = uci_to_section(e);
+ const char *type;
+ const char *name = "ubus include";
- if (strcmp(s->type, "include"))
+ if (!fw3_attr_parse_name_type(entry, &name, &type))
continue;
- include = malloc(sizeof(*include));
+ if (strcmp(type, "script") && strcmp(type, "restore"))
+ continue;
+ include = fw3_alloc_include(state);
if (!include)
continue;
- memset(include, 0, sizeof(*include));
-
- include->name = e->name;
- include->enabled = true;
-
- fw3_parse_options(include, fw3_include_opts, s);
-
- if (!include->enabled)
+ if (!fw3_parse_blob_options(include, fw3_include_opts, entry, name))
{
+ warn_section("include", include, NULL, "skipped due to invalid options");
fw3_free_include(include);
continue;
}
- if (!include->path)
- {
- warn_elem(e, "must specify a path");
+ if (!check_include(state, include, NULL))
fw3_free_include(include);
+ }
+
+ uci_foreach_element(&p->sections, e)
+ {
+ s = uci_to_section(e);
+
+ if (strcmp(s->type, "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!");
+ include = fw3_alloc_include(state);
+ if (!include)
+ continue;
+
+ include->name = e->name;
- list_add_tail(&include->list, &state->includes);
- continue;
+ if (!fw3_parse_options(include, fw3_include_opts, s))
+ warn_elem(e, "has invalid options");
+
+ if (!check_include(state, include, e))
+ fw3_free_include(include);
}
}
static void
-print_include(struct fw3_include *include, enum fw3_family family)
+print_include(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")))
}
while (fgets(line, sizeof(line), f))
- fw3_pr(line);
+ fw3_pr("%s", line);
fclose(f);
}
{
struct fw3_include *include;
+ bool exec = false;
+ const char *restore = "iptables-restore";
+
+ if (family == FW3_FAMILY_V6)
+ restore = "ip6tables-restore";
+
list_for_each_entry(include, &state->includes, list)
{
if (reload && !include->reload)
continue;
- if (include->type == FW3_INC_TYPE_RESTORE)
- print_include(include, family);
+ if (include->type != FW3_INC_TYPE_RESTORE)
+ continue;
+
+ if (!fw3_is_family(include, family))
+ continue;
+
+ if (!exec)
+ {
+ exec = fw3_command_pipe(false, restore, "--noflush");
+
+ if (!exec)
+ return;
+ }
+
+ print_include(include);
}
+
+ if (exec)
+ fw3_command_close();
}
+#define TEMPLATE "config() { echo \"You cannot use UCI in firewall includes!\" >&2; exit 1; }; . %s"
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)];
+ char buf[PATH_MAX + sizeof(TEMPLATE)];
info(" * Running script '%s'", include->path);
return;
}
- snprintf(buf, sizeof(buf), tmpl, include->path);
+ snprintf(buf, sizeof(buf), TEMPLATE, include->path);
rv = system(buf);
if (rv)