Reapply SNAT/MASQUERADE rules on firewall reloads
[project/firewall3.git] / options.c
index 5a7a901..4c42be0 100644 (file)
--- a/options.c
+++ b/options.c
@@ -1,7 +1,7 @@
 /*
  * firewall3 - 3rd OpenWrt UCI firewall implementation
  *
- *   Copyright (C) 2013 Jo-Philipp Wich <jow@openwrt.org>
+ *   Copyright (C) 2013-2014 Jo-Philipp Wich <jow@openwrt.org>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -78,6 +78,7 @@ const char *fw3_flag_names[__FW3_FLAG_MAX] = {
        "MARK",
        "DNAT",
        "SNAT",
+       "MASQUERADE",
 
        "ACCEPT",
        "REJECT",
@@ -142,9 +143,10 @@ fw3_parse_bool(void *ptr, const char *val, bool is_list)
 bool
 fw3_parse_int(void *ptr, const char *val, bool is_list)
 {
-       int n = strtol(val, NULL, 0);
+       char *e;
+       int n = strtol(val, &e, 0);
 
-       if (errno == ERANGE || errno == EINVAL)
+       if (e == val || *e)
                return false;
 
        *((int *)ptr) = n;
@@ -163,7 +165,7 @@ bool
 fw3_parse_target(void *ptr, const char *val, bool is_list)
 {
        return parse_enum(ptr, val, &fw3_flag_names[FW3_FLAG_ACCEPT],
-                         FW3_FLAG_ACCEPT, FW3_FLAG_SNAT);
+                         FW3_FLAG_ACCEPT, FW3_FLAG_MASQUERADE);
 }
 
 bool
@@ -518,6 +520,7 @@ fw3_parse_protocol(void *ptr, const char *val, bool is_list)
 {
        struct fw3_protocol proto = { };
        struct protoent *ent;
+       char *e;
 
        if (*val == '!')
        {
@@ -556,9 +559,9 @@ fw3_parse_protocol(void *ptr, const char *val, bool is_list)
                return true;
        }
 
-       proto.protocol = strtoul(val, NULL, 10);
+       proto.protocol = strtoul(val, &e, 10);
 
-       if (errno == ERANGE || errno == EINVAL)
+       if ((e == val) || (*e != 0))
                return false;
 
        put_value(ptr, &proto, sizeof(proto), is_list);
@@ -852,7 +855,7 @@ fw3_parse_setmatch(void *ptr, const char *val, bool is_list)
 }
 
 
-void
+bool
 fw3_parse_options(void *s, const struct fw3_option *opts,
                   struct uci_section *section)
 {
@@ -862,6 +865,7 @@ fw3_parse_options(void *s, const struct fw3_option *opts,
        struct uci_option *o;
        const struct fw3_option *opt;
        struct list_head *dest;
+       bool valid = true;
 
        uci_foreach_element(&section->options, e)
        {
@@ -881,6 +885,7 @@ fw3_parse_options(void *s, const struct fw3_option *opts,
                                if (!opt->elem_size)
                                {
                                        warn_elem(e, "must not be a list");
+                                       valid = false;
                                }
                                else
                                {
@@ -894,6 +899,7 @@ fw3_parse_options(void *s, const struct fw3_option *opts,
                                                if (!opt->parse(dest, l->name, true))
                                                {
                                                        warn_elem(e, "has invalid value '%s'", l->name);
+                                                       valid = false;
                                                        continue;
                                                }
                                        }
@@ -909,7 +915,10 @@ fw3_parse_options(void *s, const struct fw3_option *opts,
                                if (!opt->elem_size)
                                {
                                        if (!opt->parse((char *)s + opt->offset, o->v.string, false))
+                                       {
                                                warn_elem(e, "has invalid value '%s'", o->v.string);
+                                               valid = false;
+                                       }
                                }
                                else
                                {
@@ -920,6 +929,7 @@ fw3_parse_options(void *s, const struct fw3_option *opts,
                                                if (!opt->parse(dest, p, true))
                                                {
                                                        warn_elem(e, "has invalid value '%s'", p);
+                                                       valid = false;
                                                        continue;
                                                }
                                        }
@@ -933,6 +943,8 @@ fw3_parse_options(void *s, const struct fw3_option *opts,
                if (!known)
                        warn_elem(e, "is unknown");
        }
+
+       return valid;
 }