summaryrefslogtreecommitdiffstats
path: root/src/expression.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2025-02-13 18:56:46 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2025-02-21 23:23:10 +0100
commit347039f64509e77ad5f6ef52ae70950c91886f8e (patch)
treee1d9857388672f1a08dccf6ab310c2a2b1ad8288 /src/expression.c
parentb15854ef81b4c22e4660d3876384f375554887b2 (diff)
src: add symbol range expression to further compact intervals
Update parser to use a new symbol range expression with smaller memory footprint than range expression + two symbol expressions. The evaluation step translates this into EXPR_RANGE_VALUE for interval sets. Note that maps or concatenations still use the less compact range expressions representation, those require more work to use this new symbol range expression. The parser also uses the classic range expression if variables are used. Testing with a 100k intervals, worst case scenario: no prefix or singleton elements. This shows a reduction from 49.58 Mbytes to 35.47 Mbytes (-29.56% memory footprint for this case). This follow up work to previous commits: 91dc281a82ea ("src: rework singleton interval transformation to reduce memory consumption") c9ee9032b0ee ("src: add EXPR_RANGE_VALUE expression and use it") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/expression.c')
-rw-r--r--src/expression.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/expression.c b/src/expression.c
index b98b3d96..53d4c521 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -620,6 +620,50 @@ struct expr *constant_range_expr_alloc(const struct location *loc,
return expr;
}
+static void symbol_range_expr_print(const struct expr *expr, struct output_ctx *octx)
+{
+ nft_print(octx, "%s", expr->identifier_range[0]);
+ nft_print(octx, "-");
+ nft_print(octx, "%s", expr->identifier_range[1]);
+}
+
+static void symbol_range_expr_clone(struct expr *new, const struct expr *expr)
+{
+ new->symtype = expr->symtype;
+ new->scope = expr->scope;
+ new->identifier_range[0] = xstrdup(expr->identifier_range[0]);
+ new->identifier_range[1] = xstrdup(expr->identifier_range[1]);
+}
+
+static void symbol_range_expr_destroy(struct expr *expr)
+{
+ free_const(expr->identifier_range[0]);
+ free_const(expr->identifier_range[1]);
+}
+
+static const struct expr_ops symbol_range_expr_ops = {
+ .type = EXPR_RANGE_SYMBOL,
+ .name = "range_symbol",
+ .print = symbol_range_expr_print,
+ .clone = symbol_range_expr_clone,
+ .destroy = symbol_range_expr_destroy,
+};
+
+struct expr *symbol_range_expr_alloc(const struct location *loc,
+ enum symbol_types type, const struct scope *scope,
+ const char *identifier_low, const char *identifier_high)
+{
+ struct expr *expr;
+
+ expr = expr_alloc(loc, EXPR_RANGE_SYMBOL, &invalid_type,
+ BYTEORDER_INVALID, 0);
+ expr->symtype = type;
+ expr->scope = scope;
+ expr->identifier_range[0] = xstrdup(identifier_low);
+ expr->identifier_range[1] = xstrdup(identifier_high);
+ return expr;
+}
+
/*
* Allocate a constant expression with a single bit set at position n.
*/
@@ -1699,6 +1743,7 @@ static const struct expr_ops *__expr_ops_by_type(enum expr_types etype)
case EXPR_SET_ELEM_CATCHALL: return &set_elem_catchall_expr_ops;
case EXPR_FLAGCMP: return &flagcmp_expr_ops;
case EXPR_RANGE_VALUE: return &constant_range_expr_ops;
+ case EXPR_RANGE_SYMBOL: return &symbol_range_expr_ops;
}
return NULL;