Overlap detection for interval sets needs a content dump because kernel overlap detection is incomplete. This patch removes this set content dump. Thus, NFT_CACHE_SETELEM_MAYBE only fetches the set content if the auto-merge flag is set on. set_overlap() still remain in place because this can be used from error path to provide better error reporting at the cost of dumping the set content. This patch requires kernel patches to complete the overlap detection for interval sets. Signed-off-by: Pablo Neira Ayuso --- Do not apply, set_overlap() still needs to be used from error path, this is to test the posted interval set kernel patches for overlap detection. include/intervals.h | 1 + src/cache.c | 3 ++- src/evaluate.c | 2 +- src/intervals.c | 14 ++++++++++++-- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/include/intervals.h b/include/intervals.h index 2366c295ca08..aa1514df727d 100644 --- a/include/intervals.h +++ b/include/intervals.h @@ -5,6 +5,7 @@ int set_automerge(struct list_head *msgs, struct cmd *cmd, struct set *set, struct expr *init, unsigned int debug_mask); int set_delete(struct list_head *msgs, struct cmd *cmd, struct set *set, struct expr *init, unsigned int debug_mask); +int set_add(struct list_head *msgs, struct set *set, struct expr *init); int set_overlap(struct list_head *msgs, struct set *set, struct expr *init); int set_to_intervals(const struct set *set, struct expr *init, bool add); int setelem_to_interval(const struct set *set, struct expr *elem, diff --git a/src/cache.c b/src/cache.c index bb005c10f999..93f2c59ef60d 100644 --- a/src/cache.c +++ b/src/cache.c @@ -1188,7 +1188,8 @@ static int cache_init_objects(struct netlink_ctx *ctx, unsigned int flags, if (cache_filter_find(filter, &set->handle)) continue; - if (!set_is_non_concat_range(set)) + if (!set_is_non_concat_range(set) || + !set->automerge) continue; ret = netlink_list_setelems(ctx, &set->handle, diff --git a/src/evaluate.c b/src/evaluate.c index 4be5299274d2..41385a805065 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -2041,7 +2041,7 @@ static int interval_set_eval(struct eval_ctx *ctx, struct set *set, ret = set_automerge(ctx->msgs, ctx->cmd, set, init, ctx->nft->debug_mask); } else { - ret = set_overlap(ctx->msgs, set, init); + ret = set_add(ctx->msgs, set, init); } break; case CMD_DELETE: diff --git a/src/intervals.c b/src/intervals.c index 40ab42832fd9..6462ee49500d 100644 --- a/src/intervals.c +++ b/src/intervals.c @@ -504,8 +504,10 @@ int set_delete(struct list_head *msgs, struct cmd *cmd, struct set *set, int err; set_to_range(init); - if (set->automerge) - automerge_delete(msgs, set, init, debug_mask); + if (!set->automerge) + return 0; + + automerge_delete(msgs, set, init, debug_mask); if (existing_set->init) { set_to_range(existing_set->init); @@ -629,6 +631,14 @@ err_out: return err; } +int set_add(struct list_head *msgs, struct set *set, struct expr *init) +{ + set_to_range(init); + list_expr_sort(&expr_set(init)->expressions); + + return 0; +} + /* overlap detection for intervals already exists in Linux kernels >= 5.7. */ int set_overlap(struct list_head *msgs, struct set *set, struct expr *init) { -- 2.47.3