summaryrefslogtreecommitdiffstats
path: root/src/evaluate.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2023-08-23 12:13:28 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2023-08-23 19:16:50 +0200
commitf3769d2f5094c11ca59d83fba3f1decad8d00caf (patch)
tree7f3ce1dcda8222cb8ee261cf0040d1940837cff8 /src/evaluate.c
parent70d99ce8bf8bd3dab84ea0a6249812b04ec95b8c (diff)
evaluate: error out on meter overlap with an existing set/map declaration
One of the problems with meters is that they use the set/map infrastructure behind the scenes which might be confusing to users. This patch errors out in case user declares a meter whose name overlaps with an existing set/map: meter.nft:15:18-91: Error: File exists; meter ‘syn4-meter’ overlaps an existing set ‘syn4-meter’ in family inet tcp dport 22 meter syn4-meter { ip saddr . tcp dport timeout 5m limit rate 20/minute } counter accept ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ An old 5.10 kernel bails out simply with EEXIST, with this patch a better hint is provided. Dynamic sets are preferred over meters these days. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/evaluate.c')
-rw-r--r--src/evaluate.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/src/evaluate.c b/src/evaluate.c
index 8fc1ca7e..bdd3c651 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -3037,6 +3037,24 @@ static int stmt_evaluate_payload(struct eval_ctx *ctx, struct stmt *stmt)
static int stmt_evaluate_meter(struct eval_ctx *ctx, struct stmt *stmt)
{
struct expr *key, *set, *setref;
+ struct set *existing_set;
+ struct table *table;
+
+ table = table_cache_find(&ctx->nft->cache.table_cache,
+ ctx->cmd->handle.table.name,
+ ctx->cmd->handle.family);
+ if (table == NULL)
+ return table_not_found(ctx);
+
+ existing_set = set_cache_find(table, stmt->meter.name);
+ if (existing_set)
+ return cmd_error(ctx, &stmt->location,
+ "%s; meter ‘%s’ overlaps an existing %s ‘%s’ in family %s",
+ strerror(EEXIST),
+ stmt->meter.name,
+ set_is_map(existing_set->flags) ? "map" : "set",
+ existing_set->handle.set.name,
+ family2str(existing_set->handle.family));
expr_set_context(&ctx->ectx, NULL, 0);
if (expr_evaluate(ctx, &stmt->meter.key) < 0)