]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: operational limit match
authorPhil Oester <kernel@linuxace.com>
Sat, 5 Oct 2013 16:44:56 +0000 (09:44 -0700)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 22 Oct 2013 08:52:32 +0000 (10:52 +0200)
The nft limit match currently does not work at all.  Below patches to nftables,
libnftables, and kernel address the issue.  A few notes on the implementation:

- Removed support for nano/micro/milli second limits.  These seem pointless,
  given we are using jiffies in the limit match, not a hpet.  And who really
  needs to limit items down to sub-second level??

- 'depth' member is removed as unnecessary.  All we need in the kernel is the
  rate and the unit.

- 'stamp' member becomes the time we need to next refresh the token bucket,
  instead of being updated on every packet which goes through the match.

This closes netfilter bugzilla #827, reported by Eric Leblond.

Signed-off-by: Phil Oester <kernel@linuxace.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/statement.h
src/netlink_delinearize.c
src/netlink_linearize.c
src/parser.y
src/statement.c

index 53702317b782a6a03afc79cc43644b09fb43618c..6ecbb18d1bb38055b678282d10ac00c5adef420b 100644 (file)
@@ -41,7 +41,6 @@ extern struct stmt *log_stmt_alloc(const struct location *loc);
 struct limit_stmt {
        uint64_t                rate;
        uint64_t                unit;
-       uint64_t                depth;
 };
 
 extern struct stmt *limit_stmt_alloc(const struct location *loc);
index d80fc78d35e8671df1f2866b4919f6b6abc25ac2..3bb143b8231bf08dd001fbb568fb501ecefc6db9 100644 (file)
@@ -385,8 +385,8 @@ static void netlink_parse_limit(struct netlink_parse_ctx *ctx,
        struct stmt *stmt;
 
        stmt = limit_stmt_alloc(loc);
-       stmt->limit.rate  = nft_rule_expr_get_u32(nle, NFT_EXPR_LIMIT_RATE);
-       stmt->limit.depth  = nft_rule_expr_get_u32(nle, NFT_EXPR_LIMIT_DEPTH);
+       stmt->limit.rate  = nft_rule_expr_get_u64(nle, NFT_EXPR_LIMIT_RATE);
+       stmt->limit.unit  = nft_rule_expr_get_u64(nle, NFT_EXPR_LIMIT_UNIT);
        list_add_tail(&stmt->list, &ctx->rule->stmts);
 }
 
index 72c59e5623f9dd02c144e490411c4b1278f4b202..fd91155bd9da47fc2a6ce1324fc9ef0284fd6dca 100644 (file)
@@ -551,8 +551,8 @@ static void netlink_gen_limit_stmt(struct netlink_linearize_ctx *ctx,
        struct nft_rule_expr *nle;
 
        nle = alloc_nft_expr("limit");
-       nft_rule_expr_set_u32(nle, NFT_EXPR_LIMIT_RATE, stmt->limit.rate);
-       nft_rule_expr_set_u32(nle, NFT_EXPR_LIMIT_DEPTH, stmt->limit.depth);
+       nft_rule_expr_set_u64(nle, NFT_EXPR_LIMIT_RATE, stmt->limit.rate);
+       nft_rule_expr_set_u64(nle, NFT_EXPR_LIMIT_UNIT, stmt->limit.unit);
        nft_rule_add_expr(ctx->nlr, nle);
 }
 
index 074f0758c31865567ba83203b8a70fd35f3c8498..cfe1e863a7bdc7d57fcc5252e567182c97050ba7 100644 (file)
@@ -1003,14 +1003,11 @@ limit_stmt              :       LIMIT   RATE    NUM     SLASH   time_unit
                        }
                        ;
 
-time_unit              :       NANOSECOND      { $$ = 1ULL; }
-                       |       MICROSECOND     { $$ = 1ULL * 1000; }
-                       |       MILLISECOND     { $$ = 1ULL * 1000 * 1000; }
-                       |       SECOND          { $$ = 1ULL * 1000 * 1000 * 1000; }
-                       |       MINUTE          { $$ = 1ULL * 1000 * 1000 * 1000 * 60; }
-                       |       HOUR            { $$ = 1ULL * 1000 * 1000 * 1000 * 60 * 60; }
-                       |       DAY             { $$ = 1ULL * 1000 * 1000 * 1000 * 60 * 60 * 24; }
-                       |       WEEK            { $$ = 1ULL * 1000 * 1000 * 1000 * 60 * 60 * 24 * 7; }
+time_unit              :       SECOND          { $$ = 1ULL; }
+                       |       MINUTE          { $$ = 1ULL * 60; }
+                       |       HOUR            { $$ = 1ULL * 60 * 60; }
+                       |       DAY             { $$ = 1ULL * 60 * 60 * 24; }
+                       |       WEEK            { $$ = 1ULL * 60 * 60 * 24 * 7; }
                        ;
 
 reject_stmt            :       _REJECT
index 69db48f61acde9cfdbba87aaeb393eab5777c2fa..658dc5fff5ee0ae0f6c9053a71d290bd69684db4 100644 (file)
@@ -144,8 +144,16 @@ struct stmt *log_stmt_alloc(const struct location *loc)
 
 static void limit_stmt_print(const struct stmt *stmt)
 {
-       printf("limit rate %" PRIu64 " depth %" PRIu64,
-              stmt->limit.rate, stmt->limit.depth);
+       static const char *units[] = {
+               [1]                     = "second",
+               [1 * 60]                = "minute",
+               [1 * 60 * 60]           = "hour",
+               [1 * 60 * 60 * 24]      = "day",
+               [1 * 60 * 60 * 24 * 7]  = "week",
+       };
+
+       printf("limit rate %" PRIu64 "/%s",
+              stmt->limit.rate, units[stmt->limit.unit]);
 }
 
 static const struct stmt_ops limit_stmt_ops = {