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

Reply via email to