summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2014-06-30 19:17:53 +0200
committerFelix Fietkau <nbd@openwrt.org>2014-06-30 20:52:21 +0200
commit92281eb747b56e748b7c3d754055919c23befdd4 (patch)
tree2053767b86be26faa1a4e7d5ca4297becba308e4
parenta9c694d5b6ea026a0c745e5b650993bf0f1c13dc (diff)
downloadfirewall3-92281eb747b56e748b7c3d754055919c23befdd4.tar.gz
make fw3_ubus_address take a list_head * argument instead of allocating & returning one
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-rw-r--r--options.c20
-rw-r--r--redirects.c27
-rw-r--r--ubus.c92
-rw-r--r--ubus.h2
-rw-r--r--zones.c17
5 files changed, 68 insertions, 90 deletions
diff --git a/options.c b/options.c
index 80e5542..e864db7 100644
--- a/options.c
+++ b/options.c
@@ -330,28 +330,20 @@ fw3_parse_network(void *ptr, const char *val, bool is_list)
{
struct fw3_device dev = { };
struct fw3_address *addr;
- struct list_head *addr_list;
+ LIST_HEAD(addr_list);
if (!fw3_parse_address(ptr, val, is_list))
{
if (!fw3_parse_device(&dev, val, false))
return false;
- addr_list = fw3_ubus_address(dev.name);
-
- if (addr_list)
+ fw3_ubus_address(&addr_list, dev.name);
+ list_for_each_entry(addr, &addr_list, list)
{
- list_for_each_entry(addr, addr_list, list)
- {
- addr->invert = dev.invert;
- addr->resolved = true;
-
- if (!put_value(ptr, addr, sizeof(*addr), is_list))
- break;
- }
-
- fw3_free_list(addr_list);
+ addr->invert = dev.invert;
+ addr->resolved = true;
}
+ list_splice_tail(&addr_list, ptr);
}
return true;
diff --git a/redirects.c b/redirects.c
index f1fa1f4..080e2c1 100644
--- a/redirects.c
+++ b/redirects.c
@@ -171,8 +171,7 @@ check_local(struct uci_element *e, struct fw3_redirect *redir,
{
struct fw3_zone *zone;
struct fw3_device *net;
- struct fw3_address *addr;
- struct list_head *addrs;
+ struct fw3_address *addr, *tmp;
if (redir->target != FW3_FLAG_DNAT)
return false;
@@ -187,25 +186,23 @@ check_local(struct uci_element *e, struct fw3_redirect *redir,
{
list_for_each_entry(net, &zone->networks, list)
{
- addrs = fw3_ubus_address(net->name);
-
- if (!addrs)
- continue;
+ LIST_HEAD(addrs);
- list_for_each_entry(addr, addrs, list)
+ fw3_ubus_address(&addrs, net->name);
+ list_for_each_entry_safe(addr, tmp, &addrs, list)
{
- if (!compare_addr(&redir->ip_redir, addr))
- continue;
+ if (compare_addr(&redir->ip_redir, addr)) {
+ warn_elem(e, "refers to a destination address on this router, "
+ "assuming port redirection");
- warn_elem(e, "refers to a destination address on this router, "
- "assuming port redirection");
+ redir->local = true;
+ continue;
+ }
- redir->local = true;
- break;
+ list_del(&addr->list);
+ free(addr);
}
- fw3_free_list(addrs);
-
if (redir->local)
return true;
}
diff --git a/ubus.c b/ubus.c
index 34e21b8..a5f3a65 100644
--- a/ubus.c
+++ b/ubus.c
@@ -90,12 +90,16 @@ parse_subnet(enum fw3_family family, struct blob_attr *dict, int rem)
static void
parse_subnets(struct list_head *head, enum fw3_family family,
- struct blob_attr *list, int rem)
+ struct blob_attr *list)
{
struct blob_attr *cur;
struct fw3_address *addr;
+ int rem;
- __blob_for_each_attr(cur, list, rem)
+ if (!list)
+ return;
+
+ blob_for_each_attr(cur, list, rem)
{
addr = parse_subnet(family, blobmsg_data(cur), blobmsg_data_len(cur));
@@ -104,11 +108,10 @@ parse_subnets(struct list_head *head, enum fw3_family family,
}
}
-static void *
-invoke_common(const char *net, bool device)
+struct fw3_device *
+fw3_ubus_device(const char *net)
{
struct fw3_device *dev = NULL;
- struct list_head *addr = NULL;
struct blob_attr *c, *cur;
unsigned r, rem;
char *data;
@@ -117,16 +120,9 @@ invoke_common(const char *net, bool device)
if (!net || !interfaces)
return NULL;
- if (device)
- dev = calloc(1, sizeof(*dev));
- else
- addr = malloc(sizeof(*addr));
-
- if ((device && !dev) || (!device && !addr))
- goto fail;
-
- if (!device)
- INIT_LIST_HEAD(addr);
+ dev = calloc(1, sizeof(*dev));
+ if (!dev)
+ return NULL;
blobmsg_for_each_attr(c, interfaces, r) {
matched = false;
@@ -140,47 +136,53 @@ invoke_common(const char *net, bool device)
blobmsg_for_each_attr(cur, c, rem) {
data = blobmsg_data(cur);
- if (dev && !strcmp(blobmsg_name(cur), "device") && !dev->name[0])
+ if (!strcmp(blobmsg_name(cur), "device") && !dev->name[0])
snprintf(dev->name, sizeof(dev->name), "%s", data);
- else if (dev && !strcmp(blobmsg_name(cur), "l3_device"))
+ else if (!strcmp(blobmsg_name(cur), "l3_device"))
snprintf(dev->name, sizeof(dev->name), "%s", data);
- else if (!dev && !strcmp(blobmsg_name(cur), "ipv4-address"))
- parse_subnets(addr, FW3_FAMILY_V4,
- blobmsg_data(cur), blobmsg_data_len(cur));
- else if (!dev && (!strcmp(blobmsg_name(cur), "ipv6-address") ||
- !strcmp(blobmsg_name(cur), "ipv6-prefix-assignment")))
- parse_subnets(addr, FW3_FAMILY_V6,
- blobmsg_data(cur), blobmsg_data_len(cur));
}
- if (dev)
- dev->set = !!dev->name[0];
-
- break;
- }
-
- if (device && dev->set)
+ dev->set = !!dev->name[0];
return dev;
- else if (!device && !list_empty(addr))
- return addr;
-
-fail:
- free(dev);
- free(addr);
+ }
return NULL;
}
-struct fw3_device *
-fw3_ubus_device(const char *net)
+void
+fw3_ubus_address(struct list_head *list, const char *net)
{
- return invoke_common(net, true);
-}
+ enum {
+ ADDR_INTERFACE,
+ ADDR_IPV4,
+ ADDR_IPV6,
+ ADDR_IPV6_PREFIX,
+ __ADDR_MAX
+ };
+ static const struct blobmsg_policy policy[__ADDR_MAX] = {
+ [ADDR_INTERFACE] = { "interface", BLOBMSG_TYPE_STRING },
+ [ADDR_IPV4] = { "ipv4-address", BLOBMSG_TYPE_ARRAY },
+ [ADDR_IPV6] = { "ipv6-address", BLOBMSG_TYPE_ARRAY },
+ [ADDR_IPV6_PREFIX] = { "ipv6-prefix-assignment", BLOBMSG_TYPE_ARRAY },
+ };
+ struct blob_attr *tb[__ADDR_MAX];
+ struct blob_attr *cur;
+ int rem;
-struct list_head *
-fw3_ubus_address(const char *net)
-{
- return invoke_common(net, false);
+ if (!net || !interfaces)
+ return;
+
+ blobmsg_for_each_attr(cur, interfaces, rem) {
+ blobmsg_parse(policy, __ADDR_MAX, tb, blobmsg_data(cur), blobmsg_len(cur));
+
+ if (!tb[ADDR_INTERFACE] ||
+ strcmp(blobmsg_data(tb[ADDR_INTERFACE]), net) != 0)
+ continue;
+
+ parse_subnets(list, FW3_FAMILY_V4, tb[ADDR_IPV4]);
+ parse_subnets(list, FW3_FAMILY_V6, tb[ADDR_IPV6]);
+ parse_subnets(list, FW3_FAMILY_V6, tb[ADDR_IPV6_PREFIX]);
+ }
}
void
diff --git a/ubus.h b/ubus.h
index 35eac90..58e598c 100644
--- a/ubus.h
+++ b/ubus.h
@@ -30,7 +30,7 @@ void fw3_ubus_disconnect(void);
struct fw3_device * fw3_ubus_device(const char *net);
-struct list_head * fw3_ubus_address(const char *net);
+void fw3_ubus_address(struct list_head *list, const char *net);
void fw3_ubus_zone_devices(struct fw3_zone *zone);
diff --git a/zones.c b/zones.c
index 53c6246..6ab3d12 100644
--- a/zones.c
+++ b/zones.c
@@ -678,7 +678,7 @@ fw3_resolve_zone_addresses(struct fw3_zone *zone)
{
struct fw3_device *net;
struct fw3_address *addr, *tmp;
- struct list_head *addrs, *all;
+ struct list_head *all;
all = calloc(1, sizeof(*all));
if (!all)
@@ -687,20 +687,7 @@ fw3_resolve_zone_addresses(struct fw3_zone *zone)
INIT_LIST_HEAD(all);
list_for_each_entry(net, &zone->networks, list)
- {
- addrs = fw3_ubus_address(net->name);
-
- if (!addrs)
- continue;
-
- list_for_each_entry_safe(addr, tmp, addrs, list)
- {
- list_del(&addr->list);
- list_add_tail(&addr->list, all);
- }
-
- free(addrs);
- }
+ fw3_ubus_address(all, net->name);
list_for_each_entry(addr, &zone->subnets, list)
{