Added new config option for redirect, which accespts a list of zones, from which reflection rules shall be created. Example: zones: wan lan devices servers
config redirect ... option target 'DNAT' option src 'wan' option dest 'servers' option proto 'tcp' option src_dport '443' option dest_port '443' option name 'HTTPS' option reflection_src 'extern' ... Old behaviour would only add a reflection rule from the servers zone. By adding a config option option reflection_zones 'lan devices servers' reflection rules will get added for all and only the given zones. Reflection is therefore also possible like this option reflection_zones 'lan devices' Which enables to create a redirection to zone servers, without a reflection rule for that zone. Not setting that option results in the old behaviour. Tested on x86 master and 18.06. Signed-off-by: Anton Engelhardt <engelhardt.an...@gmail.com> --- options.h | 2 ++ redirects.c | 58 ++++++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/options.h b/options.h index a75cfa3..2804f98 100644 --- a/options.h +++ b/options.h @@ -441,6 +441,8 @@ struct fw3_redirect bool local; bool reflection; enum fw3_reflection_source reflection_src; + struct list_head reflection_zones; + struct list_head *_reflection_zones; }; struct fw3_snat diff --git a/redirects.c b/redirects.c index 6cd09f1..2f899a3 100644 --- a/redirects.c +++ b/redirects.c @@ -61,6 +61,7 @@ const struct fw3_option fw3_redirect_opts[] = { FW3_OPT("reflection", bool, redirect, reflection), FW3_OPT("reflection_src", reflection_source, redirect, reflection_src), + FW3_LIST("reflection_zones", device, redirect, reflection_zones), FW3_OPT("target", target, redirect, target), @@ -367,6 +368,7 @@ fw3_alloc_redirect(struct fw3_state *state) INIT_LIST_HEAD(&redir->proto); INIT_LIST_HEAD(&redir->mac_src); + INIT_LIST_HEAD(&redir->reflection_zones); redir->enabled = true; redir->reflection = true; @@ -612,7 +614,7 @@ static void print_reflection(struct fw3_ipt_handle *h, struct fw3_state *state, struct fw3_redirect *redir, int num, struct fw3_protocol *proto, struct fw3_address *ra, - struct fw3_address *ia, struct fw3_address *ea) + struct fw3_address *ia, struct fw3_address *ea, struct fw3_device *rz) { struct fw3_ipt_rule *r; @@ -625,7 +627,7 @@ print_reflection(struct fw3_ipt_handle *h, struct fw3_state *state, fw3_ipt_rule_time(r, &redir->time); set_comment(r, redir->name, num, "reflection"); set_snat_dnat(r, FW3_FLAG_DNAT, &redir->ip_redir, &redir->port_redir); - fw3_ipt_rule_replace(r, "zone_%s_prerouting", redir->dest.name); + fw3_ipt_rule_replace(r, "zone_%s_prerouting", rz->name); r = fw3_ipt_rule_create(h, proto, NULL, NULL, ia, &redir->ip_redir); fw3_ipt_rule_sport_dport(r, NULL, &redir->port_redir); @@ -633,7 +635,7 @@ print_reflection(struct fw3_ipt_handle *h, struct fw3_state *state, fw3_ipt_rule_time(r, &redir->time); set_comment(r, redir->name, num, "reflection"); set_snat_dnat(r, FW3_FLAG_SNAT, ra, NULL); - fw3_ipt_rule_replace(r, "zone_%s_postrouting", redir->dest.name); + fw3_ipt_rule_replace(r, "zone_%s_postrouting", rz->name); break; default: @@ -649,6 +651,7 @@ expand_redirect(struct fw3_ipt_handle *handle, struct fw3_state *state, struct fw3_address *ext_addr, *int_addr, ref_addr; struct fw3_protocol *proto; struct fw3_mac *mac; + struct fw3_device *reflection_zone; if (redir->name) info(" * Redirect '%s'", redir->name); @@ -698,6 +701,18 @@ expand_redirect(struct fw3_ipt_handle *handle, struct fw3_state *state, print_redirect(handle, state, redir, num, proto, mac); /* reflection rules */ + // use reflection_zones if set, else the redirection dest zone for reflection + struct fw3_device *dest; + if(list_empty(&redir->reflection_zones)) { + redir->_reflection_zones = calloc(1, sizeof(struct list_head)); + INIT_LIST_HEAD(redir->_reflection_zones); + dest = calloc(1, sizeof(struct fw3_device)); + memcpy((void *)dest, (void *)&redir->dest, sizeof(struct fw3_device)); + list_add(&(dest->list), redir->_reflection_zones); + } else { + redir->_reflection_zones = &redir->reflection_zones; + } + if (redir->target != FW3_FLAG_DNAT || !redir->reflection || redir->local) return; @@ -705,9 +720,8 @@ expand_redirect(struct fw3_ipt_handle *handle, struct fw3_state *state, return; 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) + if (!ext_addrs) goto out; list_for_each_entry(ext_addr, ext_addrs, list) @@ -715,26 +729,34 @@ expand_redirect(struct fw3_ipt_handle *handle, struct fw3_state *state, if (!fw3_is_family(ext_addr, handle->family)) continue; - list_for_each_entry(int_addr, int_addrs, list) + list_for_each_entry(reflection_zone, redir->_reflection_zones, list) { - if (!fw3_is_family(int_addr, handle->family)) + struct fw3_zone *zone = fw3_lookup_zone(state, reflection_zone->name); + if (!zone) continue; - - fw3_foreach(proto, &redir->proto) + + int_addrs = fw3_resolve_zone_addresses(zone, NULL); + list_for_each_entry(int_addr, int_addrs, list) { - if (!proto) + if (!fw3_is_family(int_addr, handle->family)) continue; - if (redir->reflection_src == FW3_REFLECTION_INTERNAL) - ref_addr = *int_addr; - else - ref_addr = *ext_addr; + fw3_foreach(proto, &redir->proto) + { + if (!proto) + continue; + + if (redir->reflection_src == FW3_REFLECTION_INTERNAL) + ref_addr = *int_addr; + else + ref_addr = *ext_addr; - ref_addr.mask.v4.s_addr = 0xFFFFFFFF; - ext_addr->mask.v4.s_addr = 0xFFFFFFFF; + ref_addr.mask.v4.s_addr = 0xFFFFFFFF; + ext_addr->mask.v4.s_addr = 0xFFFFFFFF; - print_reflection(handle, state, redir, num, proto, - &ref_addr, int_addr, ext_addr); + print_reflection(handle, state, redir, num, proto, + &ref_addr, int_addr, ext_addr, reflection_zone); + } } } } -- 2.7.4 _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel