]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
libxt_hashlimit: use a more obvious expiry value by default
authorJan Engelhardt <jengelh@medozas.de>
Wed, 22 Jun 2011 09:18:19 +0000 (11:18 +0200)
committerJan Engelhardt <jengelh@medozas.de>
Wed, 22 Jun 2011 10:00:07 +0000 (12:00 +0200)
Due to the previous default expiry of 10 sec, "--hashlimit 1/min"
would allow matching up to 6/min if a properly timed. To do what the
user expects, the minimum expiry must equal the selected time quantum
however.

Cc: Jan Rovner <jan.rovner@diadema.cz>
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
extensions/libxt_hashlimit.c
tests/options-most.rules

index e683f9ad770e50bcc74ad53971ea633d1a7d3d4b..a838680cba12dc4e47068f68578c80357cd4e6e9 100644 (file)
 #define XT_HASHLIMIT_GCINTERVAL        1000
 #define XT_HASHLIMIT_EXPIRE    10000
 
+struct hashlimit_mt_udata {
+       uint32_t mult;
+};
+
 static void hashlimit_help(void)
 {
        printf(
@@ -56,8 +60,9 @@ enum {
        O_HTABLE_MAX,
        O_HTABLE_GCINT,
        O_HTABLE_EXPIRE,
-       F_UPTO  = 1 << O_UPTO,
-       F_ABOVE = 1 << O_ABOVE,
+       F_UPTO          = 1 << O_UPTO,
+       F_ABOVE         = 1 << O_ABOVE,
+       F_HTABLE_EXPIRE = 1 << O_HTABLE_EXPIRE,
 };
 
 static void hashlimit_mt_help(void)
@@ -141,25 +146,25 @@ static const struct xt_option_entry hashlimit_mt_opts[] = {
 #undef s
 
 static
-int parse_rate(const char *rate, uint32_t *val)
+int parse_rate(const char *rate, uint32_t *val, struct hashlimit_mt_udata *ud)
 {
        const char *delim;
        uint32_t r;
-       uint32_t mult = 1;  /* Seconds by default. */
 
+       ud->mult = 1;  /* Seconds by default. */
        delim = strchr(rate, '/');
        if (delim) {
                if (strlen(delim+1) == 0)
                        return 0;
 
                if (strncasecmp(delim+1, "second", strlen(delim+1)) == 0)
-                       mult = 1;
+                       ud->mult = 1;
                else if (strncasecmp(delim+1, "minute", strlen(delim+1)) == 0)
-                       mult = 60;
+                       ud->mult = 60;
                else if (strncasecmp(delim+1, "hour", strlen(delim+1)) == 0)
-                       mult = 60*60;
+                       ud->mult = 60*60;
                else if (strncasecmp(delim+1, "day", strlen(delim+1)) == 0)
-                       mult = 24*60*60;
+                       ud->mult = 24*60*60;
                else
                        return 0;
        }
@@ -169,10 +174,10 @@ int parse_rate(const char *rate, uint32_t *val)
 
        /* This would get mapped to infinite (1/day is minimum they
            can specify, so we're ok at that end). */
-       if (r / mult > XT_HASHLIMIT_SCALE)
+       if (r / ud->mult > XT_HASHLIMIT_SCALE)
                xtables_error(PARAMETER_PROBLEM, "Rate too fast \"%s\"\n", rate);
 
-       *val = XT_HASHLIMIT_SCALE * mult / r;
+       *val = XT_HASHLIMIT_SCALE * ud->mult / r;
        return 1;
 }
 
@@ -248,14 +253,14 @@ static void hashlimit_parse(struct xt_option_call *cb)
        case O_UPTO:
                if (cb->invert)
                        info->cfg.mode |= XT_HASHLIMIT_INVERT;
-               if (!parse_rate(cb->arg, &info->cfg.avg))
+               if (!parse_rate(cb->arg, &info->cfg.avg, cb->udata))
                        xtables_param_act(XTF_BAD_VALUE, "hashlimit",
                                  "--hashlimit-upto", cb->arg);
                break;
        case O_ABOVE:
                if (!cb->invert)
                        info->cfg.mode |= XT_HASHLIMIT_INVERT;
-               if (!parse_rate(cb->arg, &info->cfg.avg))
+               if (!parse_rate(cb->arg, &info->cfg.avg, cb->udata))
                        xtables_param_act(XTF_BAD_VALUE, "hashlimit",
                                  "--hashlimit-above", cb->arg);
                break;
@@ -276,14 +281,14 @@ static void hashlimit_mt_parse(struct xt_option_call *cb)
        case O_UPTO:
                if (cb->invert)
                        info->cfg.mode |= XT_HASHLIMIT_INVERT;
-               if (!parse_rate(cb->arg, &info->cfg.avg))
+               if (!parse_rate(cb->arg, &info->cfg.avg, cb->udata))
                        xtables_param_act(XTF_BAD_VALUE, "hashlimit",
                                  "--hashlimit-upto", cb->arg);
                break;
        case O_ABOVE:
                if (!cb->invert)
                        info->cfg.mode |= XT_HASHLIMIT_INVERT;
-               if (!parse_rate(cb->arg, &info->cfg.avg))
+               if (!parse_rate(cb->arg, &info->cfg.avg, cb->udata))
                        xtables_param_act(XTF_BAD_VALUE, "hashlimit",
                                  "--hashlimit-above", cb->arg);
                break;
@@ -303,9 +308,26 @@ static void hashlimit_mt_parse(struct xt_option_call *cb)
 
 static void hashlimit_check(struct xt_fcheck_call *cb)
 {
+       const struct hashlimit_mt_udata *udata = cb->udata;
+       struct xt_hashlimit_info *info = cb->data;
+
        if (!(cb->xflags & (F_UPTO | F_ABOVE)))
                xtables_error(PARAMETER_PROBLEM,
                                "You have to specify --hashlimit");
+       if (!(cb->xflags & F_HTABLE_EXPIRE))
+               info->cfg.expire = udata->mult;
+}
+
+static void hashlimit_mt_check(struct xt_fcheck_call *cb)
+{
+       const struct hashlimit_mt_udata *udata = cb->udata;
+       struct xt_hashlimit_mtinfo1 *info = cb->data;
+
+       if (!(cb->xflags & (F_UPTO | F_ABOVE)))
+               xtables_error(PARAMETER_PROBLEM,
+                               "You have to specify --hashlimit");
+       if (!(cb->xflags & F_HTABLE_EXPIRE))
+               info->cfg.expire = udata->mult;
 }
 
 static const struct rates
@@ -508,6 +530,7 @@ static struct xtables_match hashlimit_mt_reg[] = {
                .print         = hashlimit_print,
                .save          = hashlimit_save,
                .x6_options    = hashlimit_mt_opts,
+               .udata_size    = sizeof(struct hashlimit_mt_udata),
        },
        {
                .version       = XTABLES_VERSION,
@@ -519,10 +542,11 @@ static struct xtables_match hashlimit_mt_reg[] = {
                .help          = hashlimit_mt_help,
                .init          = hashlimit_mt4_init,
                .x6_parse      = hashlimit_mt_parse,
-               .x6_fcheck     = hashlimit_check,
+               .x6_fcheck     = hashlimit_mt_check,
                .print         = hashlimit_mt4_print,
                .save          = hashlimit_mt4_save,
                .x6_options    = hashlimit_mt_opts,
+               .udata_size    = sizeof(struct hashlimit_mt_udata),
        },
        {
                .version       = XTABLES_VERSION,
@@ -534,10 +558,11 @@ static struct xtables_match hashlimit_mt_reg[] = {
                .help          = hashlimit_mt_help,
                .init          = hashlimit_mt6_init,
                .x6_parse      = hashlimit_mt_parse,
-               .x6_fcheck     = hashlimit_check,
+               .x6_fcheck     = hashlimit_mt_check,
                .print         = hashlimit_mt6_print,
                .save          = hashlimit_mt6_save,
                .x6_options    = hashlimit_mt_opts,
+               .udata_size    = sizeof(struct hashlimit_mt_udata),
        },
 };
 
index 2b419e574a047b01c18d72444da8d984baad11a8..7298a1f97450671b5fb8ae97988e68eaf7b9003d 100644 (file)
 -A matches
 -A matches -p esp -m esp --espspi 5:4294967295
 -A matches
+-A matches -m hashlimit --hashlimit-upto 1/sec --hashlimit-burst 1 --hashlimit-name mini1
+-A matches -m hashlimit --hashlimit-upto 1/min --hashlimit-burst 1 --hashlimit-name mini2
+-A matches -m hashlimit --hashlimit-upto 1/hour --hashlimit-burst 1 --hashlimit-name mini3
+-A matches -m hashlimit --hashlimit-upto 1/day --hashlimit-burst 1 --hashlimit-name mini4
+-A matches
 -A matches -m ipvs --vaddr fe80::/64 --vport 1 --vdir REPLY --vmethod GATE --vportctl 21
 -A matches
 -A matches -m length --length 1