summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2025-06-16 22:48:04 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2025-06-23 18:55:27 +0200
commit833b06467e14da2a470a36ccf9b2d5ea92008655 (patch)
tree92ed553ff06959132e97f3196e7da7d20c4edb7f /src
parent674cd951ee642650586a719fda9f5e8c5fcab999 (diff)
src: use EXPR_RANGE_VALUE in interval maps
Remove the restriction on maps to use EXPR_RANGE_VALUE to reduce memory consumption. With 100k map with concatenation: table inet x { map y { typeof ip saddr . tcp dport : ip saddr flags interval elements = { 1.0.2.0-1.0.2.240 . 0-2 : 1.0.2.10, ... } } Before: 153.6 Mbytes After: 108.9 Mbytes (-29.11%) With 100k map without concatenation: table inet x { map y { typeof ip saddr : ip saddr flags interval elements = { 1.0.2.0-1.0.2.240 : 1.0.2.10, ... } } Before: 74.36 Mbytes After: 62.39 Mbytes (-16.10%) Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r--src/evaluate.c5
-rw-r--r--src/netlink.c50
-rw-r--r--src/optimize.c3
3 files changed, 49 insertions, 9 deletions
diff --git a/src/evaluate.c b/src/evaluate.c
index b00344a0..783a373b 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -2328,6 +2328,7 @@ static bool data_mapping_has_interval(struct expr *data)
struct expr *i;
if (data->etype == EXPR_RANGE ||
+ data->etype == EXPR_RANGE_VALUE ||
data->etype == EXPR_PREFIX)
return true;
@@ -2336,6 +2337,7 @@ static bool data_mapping_has_interval(struct expr *data)
list_for_each_entry(i, &data->expressions, list) {
if (i->etype == EXPR_RANGE ||
+ i->etype == EXPR_RANGE_VALUE ||
i->etype == EXPR_PREFIX)
return true;
}
@@ -2428,8 +2430,7 @@ static int expr_evaluate_symbol_range(struct eval_ctx *ctx, struct expr **exprp)
left = range->left;
right = range->right;
- /* maps need more work to use constant_range_expr. */
- if (ctx->set && !set_is_map(ctx->set->flags) &&
+ if (ctx->set &&
left->etype == EXPR_VALUE &&
right->etype == EXPR_VALUE) {
constant_range = constant_range_expr_alloc(&expr->location,
diff --git a/src/netlink.c b/src/netlink.c
index 31fe8b72..f3157d9d 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -216,6 +216,7 @@ struct nftnl_set_elem *alloc_nftnl_setelem(const struct expr *set,
/* fallthrough */
case EXPR_VALUE:
case EXPR_RANGE:
+ case EXPR_RANGE_VALUE:
case EXPR_PREFIX:
nftnl_set_elem_set(nlse, NFTNL_SET_ELEM_DATA,
nld.value, nld.len);
@@ -369,29 +370,46 @@ static void netlink_gen_concat_key(const struct expr *expr,
static int __netlink_gen_concat_data(int end, const struct expr *i,
unsigned char *data)
{
+ mpz_t value;
+ int ret;
+
switch (i->etype) {
case EXPR_RANGE:
- i = end ? i->right : i->left;
+ if (end)
+ i = i->right;
+ else
+ i = i->left;
+
+ mpz_init_set(value, i->value);
+ break;
+ case EXPR_RANGE_VALUE:
+ if (end)
+ mpz_init_set(value, i->range.high);
+ else
+ mpz_init_set(value, i->range.low);
break;
case EXPR_PREFIX:
if (end) {
int count;
- mpz_t v;
- mpz_init_bitmask(v, i->len - i->prefix_len);
- mpz_add(v, i->prefix->value, v);
- count = netlink_export_pad(data, v, i);
- mpz_clear(v);
+ mpz_init_bitmask(value, i->len - i->prefix_len);
+ mpz_add(value, i->prefix->value, value);
+ count = netlink_export_pad(data, value, i);
+ mpz_clear(value);
return count;
}
return netlink_export_pad(data, i->prefix->value, i);
case EXPR_VALUE:
+ mpz_init_set(value, i->value);
break;
default:
BUG("invalid expression type '%s' in set", expr_ops(i)->name);
}
- return netlink_export_pad(data, i->value, i);
+ ret = netlink_export_pad(data, value, i);
+ mpz_clear(value);
+
+ return ret;
}
static void __netlink_gen_concat_expand(const struct expr *expr,
@@ -507,6 +525,22 @@ static void netlink_gen_range(const struct expr *expr,
nft_data_memcpy(nld, data, len);
}
+static void netlink_gen_range_value(const struct expr *expr,
+ struct nft_data_linearize *nld)
+{
+ unsigned int len = (netlink_padded_len(expr->len) / BITS_PER_BYTE) * 2;
+ unsigned char data[NFT_MAX_EXPR_LEN_BYTES];
+ unsigned int offset;
+
+ if (len > sizeof(data))
+ BUG("Value export of %u bytes would overflow", len);
+
+ memset(data, 0, sizeof(data));
+ offset = netlink_export_pad(data, expr->range.low, expr);
+ netlink_export_pad(data + offset, expr->range.high, expr);
+ nft_data_memcpy(nld, data, len);
+}
+
static void netlink_gen_prefix(const struct expr *expr,
struct nft_data_linearize *nld)
{
@@ -556,6 +590,8 @@ static void __netlink_gen_data(const struct expr *expr,
return netlink_gen_verdict(expr, data);
case EXPR_RANGE:
return netlink_gen_range(expr, data);
+ case EXPR_RANGE_VALUE:
+ return netlink_gen_range_value(expr, data);
case EXPR_PREFIX:
return netlink_gen_prefix(expr, data);
default:
diff --git a/src/optimize.c b/src/optimize.c
index 5b7b0ab6..89ba0d9d 100644
--- a/src/optimize.c
+++ b/src/optimize.c
@@ -172,6 +172,7 @@ static bool stmt_expr_supported(const struct expr *expr)
case EXPR_SYMBOL:
case EXPR_RANGE_SYMBOL:
case EXPR_RANGE:
+ case EXPR_RANGE_VALUE:
case EXPR_PREFIX:
case EXPR_SET:
case EXPR_LIST:
@@ -667,6 +668,7 @@ static void __merge_concat(const struct optimize_ctx *ctx, uint32_t i,
case EXPR_PREFIX:
case EXPR_RANGE_SYMBOL:
case EXPR_RANGE:
+ case EXPR_RANGE_VALUE:
clone = expr_clone(stmt_a->expr->right);
compound_expr_add(concat, clone);
break;
@@ -778,6 +780,7 @@ static void build_verdict_map(struct expr *expr, struct stmt *verdict,
case EXPR_PREFIX:
case EXPR_RANGE_SYMBOL:
case EXPR_RANGE:
+ case EXPR_RANGE_VALUE:
case EXPR_VALUE:
case EXPR_SYMBOL:
case EXPR_CONCAT: