diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/evaluate.c | 3 | ||||
-rw-r--r-- | src/libnftables.c | 1 | ||||
-rw-r--r-- | src/netlink.c | 11 | ||||
-rw-r--r-- | src/parser_bison.y | 6 | ||||
-rw-r--r-- | src/rule.c | 9 | ||||
-rw-r--r-- | src/scanner.l | 1 |
6 files changed, 27 insertions, 4 deletions
diff --git a/src/evaluate.c b/src/evaluate.c index 2da589c0..bcdd2dfd 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -2846,6 +2846,9 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set) return cmd_error(ctx, "Could not process rule: Table '%s' does not exist", ctx->cmd->handle.table); + if (!(set->flags & NFT_SET_INTERVAL) && set->automerge) + return set_error(ctx, set, "auto-merge only works with interval sets"); + type = set->flags & NFT_SET_MAP ? "map" : "set"; if (set->key == NULL) diff --git a/src/libnftables.c b/src/libnftables.c index 8a18bb78..c86d8947 100644 --- a/src/libnftables.c +++ b/src/libnftables.c @@ -43,7 +43,6 @@ static int nft_netlink(struct nft_ctx *nft, ctx.nf_sock = nf_sock; ctx.cache = &nft->cache; ctx.debug_mask = nft->debug_mask; - ctx.range_merge = nft->range_merge; init_list_head(&ctx.list); ret = do_command(&ctx, cmd); if (ret < 0) diff --git a/src/netlink.c b/src/netlink.c index 23f92443..488ae6f3 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -1052,6 +1052,7 @@ static int set_parse_udata_cb(const struct nftnl_udata *attr, void *data) switch (type) { case UDATA_SET_KEYBYTEORDER: case UDATA_SET_DATABYTEORDER: + case UDATA_SET_MERGE_ELEMENTS: if (len != sizeof(uint32_t)) return -1; break; @@ -1070,6 +1071,7 @@ static struct set *netlink_delinearize_set(struct netlink_ctx *ctx, enum byteorder keybyteorder = BYTEORDER_INVALID; enum byteorder databyteorder = BYTEORDER_INVALID; const struct datatype *keytype, *datatype; + bool automerge = false; const char *udata; struct set *set; uint32_t ulen; @@ -1087,6 +1089,9 @@ static struct set *netlink_delinearize_set(struct netlink_ctx *ctx, if (ud[UDATA_SET_DATABYTEORDER]) databyteorder = nftnl_udata_get_u32(ud[UDATA_SET_DATABYTEORDER]); + if (ud[UDATA_SET_MERGE_ELEMENTS]) + automerge = + nftnl_udata_get_u32(ud[UDATA_SET_MERGE_ELEMENTS]); } key = nftnl_set_get_u32(nls, NFTNL_SET_KEY_TYPE); @@ -1119,6 +1124,7 @@ static struct set *netlink_delinearize_set(struct netlink_ctx *ctx, set->handle.family = nftnl_set_get_u32(nls, NFTNL_SET_FAMILY); set->handle.table = xstrdup(nftnl_set_get_str(nls, NFTNL_SET_TABLE)); set->handle.set = xstrdup(nftnl_set_get_str(nls, NFTNL_SET_NAME)); + set->automerge = automerge; set->key = constant_expr_alloc(&netlink_location, set_datatype_alloc(keytype, keybyteorder), @@ -1238,6 +1244,11 @@ static int netlink_add_set_batch(struct netlink_ctx *ctx, set->datatype->byteorder)) memory_allocation_error(); + if (set->automerge && + !nftnl_udata_put_u32(udbuf, UDATA_SET_MERGE_ELEMENTS, + set->automerge)) + memory_allocation_error(); + nftnl_set_set_data(nls, NFTNL_SET_USERDATA, nftnl_udata_buf_data(udbuf), nftnl_udata_buf_len(udbuf)); nftnl_udata_buf_free(udbuf); diff --git a/src/parser_bison.y b/src/parser_bison.y index 009b801f..2e79109f 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -234,6 +234,7 @@ int nft_lex(void *, void *, void *); %token CONSTANT "constant" %token INTERVAL "interval" +%token AUTOMERGE "auto-merge" %token TIMEOUT "timeout" %token GC_INTERVAL "gc-interval" %token ELEMENTS "elements" @@ -1407,6 +1408,11 @@ set_block : /* empty */ { $$ = $<set>-1; } $1->init = $4; $$ = $1; } + | set_block AUTOMERGE + { + $1->automerge = true; + $$ = $1; + } | set_block set_mechanism stmt_separator ; @@ -344,6 +344,9 @@ static void set_print_declaration(const struct set *set, } nft_print(octx, "%s", opts->stmt_separator); } + if (set->automerge) + nft_print(octx, "%s%sauto-merge%s", opts->tab, opts->tab, + opts->stmt_separator); if (set->timeout) { nft_print(octx, "%s%stimeout ", opts->tab, opts->tab); @@ -998,7 +1001,7 @@ static int do_add_setelems(struct netlink_ctx *ctx, const struct handle *h, if (set->flags & NFT_SET_INTERVAL && set_to_intervals(ctx->msgs, set, init, true, - ctx->debug_mask, ctx->range_merge) < 0) + ctx->debug_mask, set->automerge) < 0) return -1; return __do_add_setelems(ctx, h, set, init, flags); @@ -1010,7 +1013,7 @@ static int do_add_set(struct netlink_ctx *ctx, const struct handle *h, if (set->init != NULL) { if (set->flags & NFT_SET_INTERVAL && set_to_intervals(ctx->msgs, set, set->init, true, - ctx->debug_mask, ctx->range_merge) < 0) + ctx->debug_mask, set->automerge) < 0) return -1; } if (netlink_add_set(ctx, h, set, flags) < 0) @@ -1110,7 +1113,7 @@ static int do_delete_setelems(struct netlink_ctx *ctx, const struct handle *h, if (set->flags & NFT_SET_INTERVAL && set_to_intervals(ctx->msgs, set, expr, false, - ctx->debug_mask, ctx->range_merge) < 0) + ctx->debug_mask, set->automerge) < 0) return -1; if (netlink_delete_setelems(ctx, h, expr) < 0) diff --git a/src/scanner.l b/src/scanner.l index 5402be1c..c3992a78 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -283,6 +283,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) "constant" { return CONSTANT; } "interval" { return INTERVAL; } +"auto-merge" { return AUTOMERGE; } "timeout" { return TIMEOUT; } "gc-interval" { return GC_INTERVAL; } "elements" { return ELEMENTS; } |