2 * firewall3 - 3rd OpenWrt UCI firewall implementation
4 * Copyright (C) 2013 Jo-Philipp Wich <jo@mein.io>
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 const struct fw3_option fw3_include_opts[] = {
23 FW3_OPT("enabled", bool, include, enabled),
25 FW3_OPT("path", string, include, path),
26 FW3_OPT("type", include_type, include, type),
27 FW3_OPT("family", family, include, family),
28 FW3_OPT("reload", bool, include, reload),
34 check_include(struct fw3_state *state, struct fw3_include *include, struct uci_element *e)
36 if (!include->enabled)
41 warn_section("include", include, e, "must specify a path");
45 if (include->type == FW3_INC_TYPE_RESTORE && !include->family)
46 warn_section("include", include, e, "does not specify a family, include will get"
47 "loaded with both iptables-restore and ip6tables-restore!");
52 static struct fw3_include *
53 fw3_alloc_include(struct fw3_state *state)
55 struct fw3_include *include;
57 include = calloc(1, sizeof(*include));
61 include->enabled = true;
63 list_add_tail(&include->list, &state->includes);
69 fw3_load_includes(struct fw3_state *state, struct uci_package *p,
72 struct uci_section *s;
73 struct uci_element *e;
74 struct fw3_include *include;
75 struct blob_attr *entry;
78 INIT_LIST_HEAD(&state->includes);
80 blob_for_each_attr(entry, a, rem)
83 const char *name = "ubus include";
85 if (!fw3_attr_parse_name_type(entry, &name, &type))
88 if (strcmp(type, "script") && strcmp(type, "restore"))
91 include = fw3_alloc_include(state);
95 if (!fw3_parse_blob_options(include, fw3_include_opts, entry, name))
97 warn_section("include", include, NULL, "skipped due to invalid options");
98 fw3_free_include(include);
102 if (!check_include(state, include, NULL))
103 fw3_free_include(include);
106 uci_foreach_element(&p->sections, e)
108 s = uci_to_section(e);
110 if (strcmp(s->type, "include"))
113 include = fw3_alloc_include(state);
117 include->name = e->name;
119 if (!fw3_parse_options(include, fw3_include_opts, s))
120 warn_elem(e, "has invalid options");
122 if (!check_include(state, include, e))
123 fw3_free_include(include);
129 print_include(struct fw3_include *include)
134 info(" * Loading include '%s'", include->path);
136 if (!(f = fopen(include->path, "r")))
138 info(" ! Skipping due to open error: %s", strerror(errno));
142 while (fgets(line, sizeof(line), f))
149 fw3_print_includes(struct fw3_state *state, enum fw3_family family, bool reload)
151 struct fw3_include *include;
154 const char *restore = "iptables-restore";
156 if (family == FW3_FAMILY_V6)
157 restore = "ip6tables-restore";
159 list_for_each_entry(include, &state->includes, list)
161 if (reload && !include->reload)
164 if (include->type != FW3_INC_TYPE_RESTORE)
167 if (!fw3_is_family(include, family))
172 exec = fw3_command_pipe(false, restore, "--noflush");
178 print_include(include);
185 #define TEMPLATE "config() { echo \"You cannot use UCI in firewall includes!\" >&2; exit 1; }; . %s"
188 run_include(struct fw3_include *include)
192 char buf[PATH_MAX + sizeof(TEMPLATE)];
194 info(" * Running script '%s'", include->path);
196 if (stat(include->path, &s))
198 info(" ! Skipping due to path error: %s", strerror(errno));
202 snprintf(buf, sizeof(buf), TEMPLATE, include->path);
206 info(" ! Failed with exit code %u", WEXITSTATUS(rv));
210 fw3_run_includes(struct fw3_state *state, bool reload)
212 struct fw3_include *include;
214 list_for_each_entry(include, &state->includes, list)
216 if (reload && !include->reload)
219 if (include->type == FW3_INC_TYPE_SCRIPT)
220 run_include(include);