Add support for fwmark matches and targets
[project/firewall3.git] / options.c
index ef5eaa7..1f561d3 100644 (file)
--- a/options.c
+++ b/options.c
@@ -75,6 +75,7 @@ const char *fw3_flag_names[__FW3_FLAG_MAX] = {
        "REJECT",
        "DROP",
        "NOTRACK",
+       "MARK",
        "DNAT",
        "SNAT",
 
@@ -206,6 +207,7 @@ fw3_parse_device(void *ptr, const char *val, bool is_list)
        {
                dev.set = true;
                dev.any = true;
+               put_value(ptr, &dev, sizeof(dev), is_list);
                return true;
        }
 
@@ -516,6 +518,7 @@ fw3_parse_protocol(void *ptr, const char *val, bool is_list)
        if (!strcmp(val, "all"))
        {
                proto.any = true;
+               put_value(ptr, &proto, sizeof(proto), is_list);
                return true;
        }
        else if (!strcmp(val, "icmpv6"))
@@ -752,6 +755,44 @@ fw3_parse_reflection_source(void *ptr, const char *val, bool is_list)
                          FW3_REFLECTION_INTERNAL, FW3_REFLECTION_EXTERNAL);
 }
 
+bool
+fw3_parse_mark(void *ptr, const char *val, bool is_list)
+{
+       uint32_t n;
+       char *s, *e;
+       struct fw3_mark *m = ptr;
+
+       if (*val == '!')
+       {
+               m->invert = true;
+               while (isspace(*++val));
+       }
+
+       if ((s = strchr(val, '/')) != NULL)
+               *s++ = 0;
+
+       n = strtoul(val, &e, 0);
+
+       if (e == val || *e)
+               return false;
+
+       m->mark = n;
+       m->mask = 0xFFFFFFFF;
+
+       if (s)
+       {
+               n = strtoul(s, &e, 0);
+
+               if (e == s || *e)
+                       return false;
+
+               m->mask = n;
+       }
+
+       m->set = true;
+       return true;
+}
+
 
 void
 fw3_parse_options(void *s, const struct fw3_option *opts,
@@ -1097,6 +1138,18 @@ fw3_format_time(struct fw3_time *time)
 }
 
 void
+fw3_format_mark(struct fw3_mark *mark)
+{
+       if (!mark->set)
+               return;
+
+       fw3_pr(" -m mark %s--mark 0x%x", mark->invert ? "! " : "", mark->mark);
+
+       if (mark->mask < 0xFFFFFFFF)
+               fw3_pr("/0x%x", mark->mask);
+}
+
+void
 __fw3_format_comment(const char *comment, ...)
 {
        va_list ap;