* [PATCH nft 0/3] memory reduction in concatenation and maps
@ 2025-06-16 21:57 Pablo Neira Ayuso
2025-06-16 21:57 ` [PATCH nft 1/3,v2] src: use constant range expression for interval+concatenation sets Pablo Neira Ayuso
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Pablo Neira Ayuso @ 2025-06-16 21:57 UTC (permalink / raw)
To: netfilter-devel
Hi,
This series uses EXPR_RANGE_VALUE in maps to reduce memory usage:
Patch #1 reduces memory footprint in concatenation of intervals,
with the following 100k example set:
table inet x {
set y {
typeof ip saddr . tcp dport
flags interval
elements = {
0.1.2.0-0.1.2.240 . 0-1,
... # 100k-1 entries more
}
}
}
Before: 123.80 Mbytes
After: 80.19 Mbytes (-35.23%)
Patch #2 remove EXPR_F_SINGLETON in EXPR_RANGE_VALUE that is required
by next patch.
Patch #3 reduces memory footprint in maps.
With 100k map with concatenations:
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 concatenations:
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%)
This is passing tests/shell.
Pablo Neira Ayuso (3):
src: use constant range expression for interval+concatenation sets
expression: constant range is not a singleton
src: use EXPR_RANGE_VALUE in interval maps
src/evaluate.c | 8 ++++---
src/expression.c | 2 +-
src/netlink.c | 61 ++++++++++++++++++++++++++++++++++++++++++------
src/optimize.c | 3 +++
4 files changed, 63 insertions(+), 11 deletions(-)
--
2.30.2
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH nft 1/3,v2] src: use constant range expression for interval+concatenation sets
2025-06-16 21:57 [PATCH nft 0/3] memory reduction in concatenation and maps Pablo Neira Ayuso
@ 2025-06-16 21:57 ` Pablo Neira Ayuso
2025-06-16 21:57 ` [PATCH nft 2/3] expression: constant range is not a singleton Pablo Neira Ayuso
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Pablo Neira Ayuso @ 2025-06-16 21:57 UTC (permalink / raw)
To: netfilter-devel
Expand 347039f64509 ("src: add symbol range expression to further
compact intervals") to use constant range expression for elements with
concatenation of intervals.
Ruleset with 100k elements of this type:
table inet x {
set y {
typeof ip saddr . tcp dport
flags interval
elements = {
0.1.2.0-0.1.2.240 . 0-1,
...
}
}
}
Memory consumption for this set:
Before: 123.80 Mbytes
After: 80.19 Mbytes (-35.23%)
This patch keeps the workaround 2fbade3cd990 ("netlink: bogus
concatenated set ranges with netlink message overrun") in place.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
v2: fix error hint when flags interval is missing in set declaration
src/evaluate.c | 5 +++--
src/netlink.c | 11 +++++++++++
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/evaluate.c b/src/evaluate.c
index 9c7f23cb080e..b157a9c9d935 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1879,6 +1879,7 @@ static int expr_evaluate_set_elem(struct eval_ctx *ctx, struct expr **expr)
switch (elem->key->etype) {
case EXPR_PREFIX:
case EXPR_RANGE:
+ case EXPR_RANGE_VALUE:
key = elem->key;
goto err_missing_flag;
case EXPR_CONCAT:
@@ -1886,6 +1887,7 @@ static int expr_evaluate_set_elem(struct eval_ctx *ctx, struct expr **expr)
switch (key->etype) {
case EXPR_PREFIX:
case EXPR_RANGE:
+ case EXPR_RANGE_VALUE:
goto err_missing_flag;
default:
break;
@@ -2366,9 +2368,8 @@ static int expr_evaluate_symbol_range(struct eval_ctx *ctx, struct expr **exprp)
left = range->left;
right = range->right;
- /* concatenation and maps need more work to use constant_range_expr. */
+ /* maps need more work to use constant_range_expr. */
if (ctx->set && !set_is_map(ctx->set->flags) &&
- set_is_non_concat_range(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 73fe579a477c..94cf177213fd 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -285,6 +285,17 @@ static int __netlink_gen_concat_key(uint32_t flags, const struct expr *i,
byteorder_switch_expr_value(value, expr);
i = expr;
+ break;
+ case EXPR_RANGE_VALUE:
+ if (flags & EXPR_F_INTERVAL_END)
+ mpz_init_set(value, i->range.high);
+ else
+ mpz_init_set(value, i->range.low);
+
+ if (expr_basetype(i)->type == TYPE_INTEGER &&
+ i->byteorder == BYTEORDER_HOST_ENDIAN)
+ byteorder_switch_expr_value(value, i);
+
break;
case EXPR_PREFIX:
if (flags & EXPR_F_INTERVAL_END) {
--
2.30.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH nft 2/3] expression: constant range is not a singleton
2025-06-16 21:57 [PATCH nft 0/3] memory reduction in concatenation and maps Pablo Neira Ayuso
2025-06-16 21:57 ` [PATCH nft 1/3,v2] src: use constant range expression for interval+concatenation sets Pablo Neira Ayuso
@ 2025-06-16 21:57 ` Pablo Neira Ayuso
2025-06-16 21:57 ` [PATCH nft 3/3] src: use EXPR_RANGE_VALUE in interval maps Pablo Neira Ayuso
2025-06-23 17:08 ` [PATCH nft 0/3] memory reduction in concatenation and maps Pablo Neira Ayuso
3 siblings, 0 replies; 5+ messages in thread
From: Pablo Neira Ayuso @ 2025-06-16 21:57 UTC (permalink / raw)
To: netfilter-devel
Remove the EXPR_F_SINGLETON flag in EXPR_RANGE_VALUE so it can be used
in maps.
expr_evaluate_set() does not toggle NFT_SET_INTERVAL for anonymous sets
because a singleton is assumed to be place, leading to this BUG:
BUG: invalid data expression type range_value
nft: src/netlink.c:577: netlink_gen_key: Assertion `0' failed.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
src/expression.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/expression.c b/src/expression.c
index dc9a44677b28..aa97413d0794 100644
--- a/src/expression.c
+++ b/src/expression.c
@@ -612,7 +612,7 @@ struct expr *constant_range_expr_alloc(const struct location *loc,
struct expr *expr;
expr = expr_alloc(loc, EXPR_RANGE_VALUE, dtype, byteorder, len);
- expr->flags = EXPR_F_CONSTANT | EXPR_F_SINGLETON;
+ expr->flags = EXPR_F_CONSTANT;
mpz_init_set(expr->range.low, low);
mpz_init_set(expr->range.high, high);
--
2.30.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH nft 3/3] src: use EXPR_RANGE_VALUE in interval maps
2025-06-16 21:57 [PATCH nft 0/3] memory reduction in concatenation and maps Pablo Neira Ayuso
2025-06-16 21:57 ` [PATCH nft 1/3,v2] src: use constant range expression for interval+concatenation sets Pablo Neira Ayuso
2025-06-16 21:57 ` [PATCH nft 2/3] expression: constant range is not a singleton Pablo Neira Ayuso
@ 2025-06-16 21:57 ` Pablo Neira Ayuso
2025-06-23 17:08 ` [PATCH nft 0/3] memory reduction in concatenation and maps Pablo Neira Ayuso
3 siblings, 0 replies; 5+ messages in thread
From: Pablo Neira Ayuso @ 2025-06-16 21:57 UTC (permalink / raw)
To: netfilter-devel
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>
---
src/evaluate.c | 5 +++--
src/netlink.c | 50 +++++++++++++++++++++++++++++++++++++++++++-------
src/optimize.c | 3 +++
3 files changed, 49 insertions(+), 9 deletions(-)
diff --git a/src/evaluate.c b/src/evaluate.c
index b157a9c9d935..fac6c657dcbb 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -2268,6 +2268,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;
@@ -2276,6 +2277,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;
}
@@ -2368,8 +2370,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 94cf177213fd..c07cbe6a0476 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -217,6 +217,7 @@ struct nftnl_set_elem *alloc_nftnl_setelem(const struct expr *set,
case EXPR_VALUE:
case EXPR_RANGE:
case EXPR_PREFIX:
+ case EXPR_RANGE_VALUE:
nftnl_set_elem_set(nlse, NFTNL_SET_ELEM_DATA,
nld.value, nld.len);
break;
@@ -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)
{
@@ -558,6 +592,8 @@ static void __netlink_gen_data(const struct expr *expr,
return netlink_gen_range(expr, data);
case EXPR_PREFIX:
return netlink_gen_prefix(expr, data);
+ case EXPR_RANGE_VALUE:
+ return netlink_gen_range_value(expr, data);
default:
BUG("invalid data expression type %s\n", expr_name(expr));
}
diff --git a/src/optimize.c b/src/optimize.c
index 5b7b0ab62fbc..89ba0d9dee6a 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:
--
2.30.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH nft 0/3] memory reduction in concatenation and maps
2025-06-16 21:57 [PATCH nft 0/3] memory reduction in concatenation and maps Pablo Neira Ayuso
` (2 preceding siblings ...)
2025-06-16 21:57 ` [PATCH nft 3/3] src: use EXPR_RANGE_VALUE in interval maps Pablo Neira Ayuso
@ 2025-06-23 17:08 ` Pablo Neira Ayuso
3 siblings, 0 replies; 5+ messages in thread
From: Pablo Neira Ayuso @ 2025-06-23 17:08 UTC (permalink / raw)
To: netfilter-devel
On Mon, Jun 16, 2025 at 11:57:20PM +0200, Pablo Neira Ayuso wrote:
> Hi,
>
> This series uses EXPR_RANGE_VALUE in maps to reduce memory usage:
Pushed out.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-06-23 17:08 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-16 21:57 [PATCH nft 0/3] memory reduction in concatenation and maps Pablo Neira Ayuso
2025-06-16 21:57 ` [PATCH nft 1/3,v2] src: use constant range expression for interval+concatenation sets Pablo Neira Ayuso
2025-06-16 21:57 ` [PATCH nft 2/3] expression: constant range is not a singleton Pablo Neira Ayuso
2025-06-16 21:57 ` [PATCH nft 3/3] src: use EXPR_RANGE_VALUE in interval maps Pablo Neira Ayuso
2025-06-23 17:08 ` [PATCH nft 0/3] memory reduction in concatenation and maps Pablo Neira Ayuso
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.