summaryrefslogtreecommitdiffstats
path: root/src/statement.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2015-08-03 15:50:03 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2015-09-23 12:16:13 +0200
commit6615676d825e02d271fe7a9ca78a77ac3773ab93 (patch)
tree4b87a754e50301cb2f8c6c47e44670cc6a27356f /src/statement.c
parent5174b6850291b67769ebd018e5c90837897969c2 (diff)
src: add per-bytes limit
This example show how to accept packets below the ratelimit: ... limit rate 1024 mbytes/second counter accept You need a Linux kernel >= 4.3-rc1. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/statement.c')
-rw-r--r--src/statement.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/src/statement.c b/src/statement.c
index 9ebc5938..ba7b8be2 100644
--- a/src/statement.c
+++ b/src/statement.c
@@ -185,10 +185,49 @@ static const char *get_unit(uint64_t u)
return "error";
}
+static const char *data_unit[] = {
+ "bytes",
+ "kbytes",
+ "mbytes",
+ NULL
+};
+
+static const char *get_rate(uint64_t byte_rate, uint64_t *rate)
+{
+ uint64_t res, prev, rest;
+ int i;
+
+ res = prev = byte_rate;
+ for (i = 0;; i++) {
+ rest = res % 1024;
+ res /= 1024;
+ if (res <= 1 && rest != 0)
+ break;
+ if (data_unit[i + 1] == NULL)
+ break;
+ prev = res;
+ }
+ *rate = prev;
+ return data_unit[i];
+}
+
static void limit_stmt_print(const struct stmt *stmt)
{
- printf("limit rate %" PRIu64 "/%s",
- stmt->limit.rate, get_unit(stmt->limit.unit));
+ const char *data_unit;
+ uint64_t rate;
+
+ switch (stmt->limit.type) {
+ case NFT_LIMIT_PKTS:
+ printf("limit rate %" PRIu64 "/%s",
+ stmt->limit.rate, get_unit(stmt->limit.unit));
+ break;
+ case NFT_LIMIT_PKT_BYTES:
+ data_unit = get_rate(stmt->limit.rate, &rate);
+
+ printf("limit rate %" PRIu64 " %s/%s",
+ rate, data_unit, get_unit(stmt->limit.unit));
+ break;
+ }
}
static const struct stmt_ops limit_stmt_ops = {