diff mbox series

[nft] meter: enforce presence of a max size

Message ID 20180502125012.26847-1-fw@strlen.de
State Accepted
Delegated to: Pablo Neira
Headers show
Series [nft] meter: enforce presence of a max size | expand

Commit Message

Florian Westphal May 2, 2018, 12:50 p.m. UTC
meters are updated dynamically, so we don't know in advance
how large this structure can be.

Add a 'size' keyword to specifiy an upper limit and update
the old syntax to assume a default max value of 65535.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 Seems i forgot to send/apply this. :-/

 include/statement.h       |  1 +
 src/evaluate.c            |  1 +
 src/netlink_delinearize.c |  1 +
 src/parser_bison.y        | 10 ++++++++++
 src/statement.c           |  2 +-
 tests/py/ip/flowtable.t   |  2 +-
 tests/py/ip6/flowtable.t  |  4 ++--
 7 files changed, 17 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/include/statement.h b/include/statement.h
index fa0b5dfa4bf5..7315e7aeea8b 100644
--- a/include/statement.h
+++ b/include/statement.h
@@ -178,6 +178,7 @@  struct meter_stmt {
 	struct expr		*key;
 	struct stmt		*stmt;
 	const char		*name;
+	uint32_t		size;
 };
 
 extern struct stmt *meter_stmt_alloc(const struct location *loc);
diff --git a/src/evaluate.c b/src/evaluate.c
index 4384e2710176..55e6ad1e0b74 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1995,6 +1995,7 @@  static int stmt_evaluate_meter(struct eval_ctx *ctx, struct stmt *stmt)
 
 	setref = implicit_set_declaration(ctx, stmt->meter.name, key, set);
 
+	setref->set->desc.size = stmt->meter.size;
 	stmt->meter.set = setref;
 
 	if (stmt_evaluate(ctx, stmt->meter.stmt) < 0)
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 2126cf20c995..10b3e8cb1c1b 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -1201,6 +1201,7 @@  static void netlink_parse_dynset(struct netlink_parse_ctx *ctx,
 		stmt->meter.set  = set_ref_expr_alloc(loc, set);
 		stmt->meter.key  = expr;
 		stmt->meter.stmt = dstmt;
+		stmt->meter.size = set->desc.size;
 	} else if (expr_data != NULL) {
 		stmt = map_stmt_alloc(loc);
 		stmt->map.set	= set_ref_expr_alloc(loc, set);
diff --git a/src/parser_bison.y b/src/parser_bison.y
index f546b9edd42e..ee3600d702ce 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -2761,10 +2761,20 @@  meter_stmt_alloc	:	METER	identifier		'{' meter_key_expr stmt '}'
 			{
 				$$ = meter_stmt_alloc(&@$);
 				$$->meter.name = $2;
+				$$->meter.size = 0xffff;
 				$$->meter.key  = $4;
 				$$->meter.stmt = $5;
 				$$->location  = @$;
 			}
+			|	METER	identifier	SIZE	NUM	'{' meter_key_expr stmt '}'
+			{
+				$$ = meter_stmt_alloc(&@$);
+				$$->meter.name = $2;
+				$$->meter.size = $4;
+				$$->meter.key  = $6;
+				$$->meter.stmt = $7;
+				$$->location  = @$;
+			}
 			;
 
 match_stmt		:	relational_expr
diff --git a/src/statement.c b/src/statement.c
index fccf71c10b1d..19c30cf861c8 100644
--- a/src/statement.c
+++ b/src/statement.c
@@ -114,7 +114,7 @@  static void meter_stmt_print(const struct stmt *stmt, struct output_ctx *octx)
 		expr_print(stmt->meter.set, octx);
 		nft_print(octx, " ");
 	}
-	nft_print(octx, "{ ");
+	nft_print(octx, "size %u { ", stmt->meter.size);
 	expr_print(stmt->meter.key, octx);
 	nft_print(octx, " ");
 
diff --git a/tests/py/ip/flowtable.t b/tests/py/ip/flowtable.t
index 4427fab88eb8..7a68788a7df1 100644
--- a/tests/py/ip/flowtable.t
+++ b/tests/py/ip/flowtable.t
@@ -2,4 +2,4 @@ 
 
 *ip;test-ip;input
 
-meter xyz { ip saddr timeout 30s counter};ok
+meter xyz { ip saddr timeout 30s counter};ok;meter xyz size 65535 { ip saddr timeout 30s counter}
diff --git a/tests/py/ip6/flowtable.t b/tests/py/ip6/flowtable.t
index 5c048935d726..d89e90c3edc4 100644
--- a/tests/py/ip6/flowtable.t
+++ b/tests/py/ip6/flowtable.t
@@ -2,5 +2,5 @@ 
 
 *ip6;test-ip6;input
 
-meter acct_out { meta iif . ip6 saddr timeout 600s counter };ok;meter acct_out { iif . ip6 saddr timeout 10m counter}
-meter acct_out { ip6 saddr . meta iif timeout 600s counter };ok;meter acct_out { ip6 saddr . iif timeout 10m counter}
+meter acct_out { meta iif . ip6 saddr timeout 600s counter };ok;meter acct_out size 65535 { iif . ip6 saddr timeout 10m counter}
+meter acct_out { ip6 saddr . meta iif timeout 600s counter };ok;meter acct_out size 65535 { ip6 saddr . iif timeout 10m counter}