diff options
author | Jo-Philipp Wich <jow@openwrt.org> | 2015-01-08 14:17:16 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jow@openwrt.org> | 2015-01-08 14:17:16 +0100 |
commit | b59934331c4b9271ceb5e30b793a552618299d39 (patch) | |
tree | eb447598fc1e90c49f062bf3da8420b8e3bd8514 | |
parent | 50e97c52e75bdfd325cf20d43b32d294ff84d92f (diff) | |
download | firewall3-b59934331c4b9271ceb5e30b793a552618299d39.tar.gz |
redirects: respect src_dip option for reflection rules
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
-rw-r--r-- | redirects.c | 6 | ||||
-rw-r--r-- | zones.c | 33 | ||||
-rw-r--r-- | zones.h | 3 |
3 files changed, 28 insertions, 14 deletions
diff --git a/redirects.c b/redirects.c index 89b3ad9..a30c540 100644 --- a/redirects.c +++ b/redirects.c @@ -136,7 +136,7 @@ resolve_dest(struct uci_element *e, struct fw3_redirect *redir, list_for_each_entry(zone, &state->zones, list) { - addrs = fw3_resolve_zone_addresses(zone); + addrs = fw3_resolve_zone_addresses(zone, NULL); if (!addrs) continue; @@ -593,8 +593,8 @@ expand_redirect(struct fw3_ipt_handle *handle, struct fw3_state *state, if (!redir->_dest || !redir->_src->masq) return; - ext_addrs = fw3_resolve_zone_addresses(redir->_src); - int_addrs = fw3_resolve_zone_addresses(redir->_dest); + ext_addrs = fw3_resolve_zone_addresses(redir->_src, &redir->ip_dest); + int_addrs = fw3_resolve_zone_addresses(redir->_dest, NULL); if (!ext_addrs || !int_addrs) goto out; @@ -678,10 +678,10 @@ fw3_lookup_zone(struct fw3_state *state, const char *name) } struct list_head * -fw3_resolve_zone_addresses(struct fw3_zone *zone) +fw3_resolve_zone_addresses(struct fw3_zone *zone, struct fw3_address *addr) { struct fw3_device *net; - struct fw3_address *addr, *tmp; + struct fw3_address *cur, *tmp; struct list_head *all; all = calloc(1, sizeof(*all)); @@ -690,18 +690,31 @@ fw3_resolve_zone_addresses(struct fw3_zone *zone) INIT_LIST_HEAD(all); - list_for_each_entry(net, &zone->networks, list) - fw3_ubus_address(all, net->name); - - list_for_each_entry(addr, &zone->subnets, list) + if (addr && addr->set) { tmp = malloc(sizeof(*tmp)); - if (!tmp) - continue; + if (tmp) + { + *tmp = *addr; + list_add_tail(&tmp->list, all); + } + } + else + { + list_for_each_entry(net, &zone->networks, list) + fw3_ubus_address(all, net->name); + + list_for_each_entry(cur, &zone->subnets, list) + { + tmp = malloc(sizeof(*tmp)); - memcpy(tmp, addr, sizeof(*tmp)); - list_add_tail(&tmp->list, all); + if (!tmp) + continue; + + *tmp = *cur; + list_add_tail(&tmp->list, all); + } } return all; @@ -44,7 +44,8 @@ void fw3_hotplug_zones(struct fw3_state *state, bool add); struct fw3_zone * fw3_lookup_zone(struct fw3_state *state, const char *name); -struct list_head * fw3_resolve_zone_addresses(struct fw3_zone *zone); +struct list_head * fw3_resolve_zone_addresses(struct fw3_zone *zone, + struct fw3_address *addr); #define fw3_free_zone(zone) \ fw3_free_object(zone, fw3_zone_opts) |