summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhil Oester <kernel@linuxace.com>2013-10-05 09:44:56 -0700
committerPablo Neira Ayuso <pablo@netfilter.org>2013-10-22 10:52:32 +0200
commitb259d1aca0db1bed5af3e4fe378f8aeb4d3ce645 (patch)
tree0dea304c654a8c4d107720b4c73a561f623b1468
parent2855909e46f4646f137a96892bd5c465fa1193f8 (diff)
src: operational limit match
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>
-rw-r--r--include/statement.h1
-rw-r--r--src/netlink_delinearize.c4
-rw-r--r--src/netlink_linearize.c4
-rw-r--r--src/parser.y13
-rw-r--r--src/statement.c12
5 files changed, 19 insertions, 15 deletions
diff --git a/include/statement.h b/include/statement.h
index 53702317..6ecbb18d 100644
--- a/include/statement.h
+++ b/include/statement.h
@@ -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);
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index d80fc78d..3bb143b8 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -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);
}
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 72c59e56..fd91155b 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -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);
}
diff --git a/src/parser.y b/src/parser.y
index 074f0758..cfe1e863 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -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
diff --git a/src/statement.c b/src/statement.c
index 69db48f6..658dc5ff 100644
--- a/src/statement.c
+++ b/src/statement.c
@@ -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 = {