/*
* firewall3 - 3rd OpenWrt UCI firewall implementation
*
- * Copyright (C) 2014 Jo-Philipp Wich <jow@openwrt.org>
+ * Copyright (C) 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
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;
+ const char *name = "ubus rule";
+ blobmsg_for_each_attr(opt, rule, orem)
+ if (!strcmp(blobmsg_name(opt), "type"))
+ type = blobmsg_get_string(opt);
+ else if (!strcmp(blobmsg_name(opt), "name"))
+ name = 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, name))
+ {
+ fprintf(stderr, "%s skipped due to invalid options\n", name);
+ 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))
{
fw3_free_snat(snat);
continue;
}
+ }
+ list_for_each_entry_safe(snat, n, &state->snats, list)
+ {
if (!snat->enabled)
{
fw3_free_snat(snat);
set(snat->_src->flags, FW3_FAMILY_V4, FW3_FLAG_SNAT);
snat->_src->conntrack = true;
}
-
- list_add_tail(&snat->list, &state->snats);
}
}
if (snat->_src)
fw3_ipt_rule_append(r, "zone_%s_postrouting", snat->src.name);
else
- fw3_ipt_rule_append(r, "delegate_postrouting");
+ fw3_ipt_rule_append(r, "POSTROUTING");
}
static void