summaryrefslogtreecommitdiff
path: root/snats.c
diff options
context:
space:
mode:
authorSteven Barth <steven@midlink.org>2014-04-13 18:48:39 +0200
committerSteven Barth <steven@midlink.org>2014-04-14 08:50:30 +0200
commite678dcbf0336c3ca10f9fe2fae8b19347b6c1d4d (patch)
treece8f3557625ba03d3b822c015d1f8bd77ca16522 /snats.c
parent2f392a3b91c25c94abfc9a7862d908c923f7bf2b (diff)
downloadfirewall3-e678dcbf0336c3ca10f9fe2fae8b19347b6c1d4d.tar.gz
Add support for netifd-generated rules
Signed-off-by: Steven Barth <steven@midlink.org>
Diffstat (limited to 'snats.c')
-rw-r--r--snats.c57
1 files changed, 44 insertions, 13 deletions
diff --git a/snats.c b/snats.c
index 1e01192..7dae2ee 100644
--- a/snats.c
+++ b/snats.c
@@ -104,32 +104,62 @@ check_families(struct uci_element *e, struct fw3_snat *r)
return true;
}
+
+static struct fw3_snat*
+alloc_snat(struct fw3_state *state)
+{
+ struct fw3_snat *snat = calloc(1, sizeof(*snat));
+
+ if (snat) {
+ INIT_LIST_HEAD(&snat->proto);
+ list_add_tail(&snat->list, &state->snats);
+ snat->enabled = true;
+ }
+
+ return snat;
+}
+
+
void
-fw3_load_snats(struct fw3_state *state, struct uci_package *p)
+fw3_load_snats(struct fw3_state *state, struct uci_package *p, struct blob_attr *a)
{
struct uci_section *s;
struct uci_element *e;
- struct fw3_snat *snat;
+ struct fw3_snat *snat, *n;
+ struct blob_attr *rule, *opt;
+ unsigned rem, orem;
INIT_LIST_HEAD(&state->snats);
- uci_foreach_element(&p->sections, e)
- {
- s = uci_to_section(e);
+ blob_for_each_attr(rule, a, rem) {
+ const char *type = NULL;
+ blobmsg_for_each_attr(opt, rule, orem)
+ if (!strcmp(blobmsg_name(opt), "type"))
+ type = blobmsg_get_string(opt);
- if (strcmp(s->type, "nat"))
+ if (!type || strcmp(type, "nat"))
continue;
- snat = malloc(sizeof(*snat));
+ if (!(snat = alloc_snat(state)))
+ continue;
- if (!snat)
+ if (!fw3_parse_blob_options(snat, fw3_snat_opts, rule))
+ {
+ fprintf(stderr, "ubus section skipped due to invalid options\n");
+ fw3_free_snat(snat);
continue;
+ }
+ }
- memset(snat, 0, sizeof(*snat));
+ uci_foreach_element(&p->sections, e)
+ {
+ s = uci_to_section(e);
- INIT_LIST_HEAD(&snat->proto);
+ if (strcmp(s->type, "nat"))
+ continue;
- snat->enabled = true;
+ if (!(snat = alloc_snat(state)))
+ continue;
if (!fw3_parse_options(snat, fw3_snat_opts, s))
{
@@ -137,7 +167,10 @@ fw3_load_snats(struct fw3_state *state, struct uci_package *p)
fw3_free_snat(snat);
continue;
}
+ }
+ list_for_each_entry_safe(snat, n, &state->snats, list)
+ {
if (!snat->enabled)
{
fw3_free_snat(snat);
@@ -220,8 +253,6 @@ fw3_load_snats(struct fw3_state *state, struct uci_package *p)
set(snat->_src->flags, FW3_FAMILY_V4, FW3_FLAG_SNAT);
snat->_src->conntrack = true;
}
-
- list_add_tail(&snat->list, &state->snats);
}
}