diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2020-03-17 14:50:38 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2020-03-20 13:13:40 +0100 |
commit | 6d80e0f154920b5d26aa764459ec0450a8a12b58 (patch) | |
tree | 97627d1a1935f051b83b8cb11751c92769261456 /src | |
parent | 6c84577b0d23d1f3fdafb4d74fd5868e891cc6af (diff) |
src: support for counter in set definition
This patch allows you to turn on counter for each element in the set.
table ip x {
set y {
typeof ip saddr
counter
elements = { 192.168.10.35, 192.168.10.101, 192.168.10.135 }
}
chain z {
type filter hook output priority filter; policy accept;
ip daddr @y
}
}
This example shows how to turn on counters globally in the set 'y'.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/evaluate.c | 9 | ||||
-rw-r--r-- | src/mnl.c | 5 | ||||
-rw-r--r-- | src/netlink.c | 7 | ||||
-rw-r--r-- | src/parser_bison.y | 5 | ||||
-rw-r--r-- | src/rule.c | 10 |
5 files changed, 36 insertions, 0 deletions
diff --git a/src/evaluate.c b/src/evaluate.c index d0e712dc..6325f52e 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -1307,8 +1307,17 @@ static int expr_evaluate_list(struct eval_ctx *ctx, struct expr **expr) static int expr_evaluate_set_elem(struct eval_ctx *ctx, struct expr **expr) { + struct set *set = ctx->set; struct expr *elem = *expr; + if (elem->stmt && set->stmt && set->stmt->ops != elem->stmt->ops) + return stmt_binary_error(ctx, set->stmt, elem, + "statement mismatch, element expects %s, " + "%s has type %s", + elem->stmt->ops->name, + set_is_map(set->flags) ? "map" : "set", + set->stmt->ops->name); + if (expr_evaluate(ctx, &elem->key) < 0) return -1; @@ -1026,6 +1026,11 @@ int mnl_nft_set_add(struct netlink_ctx *ctx, struct cmd *cmd, nftnl_udata_buf_len(udbuf)); nftnl_udata_buf_free(udbuf); + if (set->stmt) { + nftnl_set_set_data(nls, NFTNL_SET_EXPR, + netlink_gen_stmt_stateful(set->stmt), 0); + } + netlink_dump_set(nls, ctx); nlh = nftnl_nlmsg_build_hdr(nftnl_batch_buffer(ctx->batch), diff --git a/src/netlink.c b/src/netlink.c index e10af564..b254753f 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -766,6 +766,13 @@ struct set *netlink_delinearize_set(struct netlink_ctx *ctx, set->handle.set.name = xstrdup(nftnl_set_get_str(nls, NFTNL_SET_NAME)); set->automerge = automerge; + if (nftnl_set_is_set(nls, NFTNL_SET_EXPR)) { + const struct nftnl_expr *nle; + + nle = nftnl_set_get(nls, NFTNL_SET_EXPR); + set->stmt = netlink_parse_set_expr(set, &ctx->nft->cache, nle); + } + if (datatype) { dtype = set_datatype_alloc(datatype, databyteorder); klen = nftnl_set_get_u32(nls, NFTNL_SET_DATA_LEN) * BITS_PER_BYTE; diff --git a/src/parser_bison.y b/src/parser_bison.y index 3d65d208..e14118ca 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -1733,6 +1733,11 @@ set_block : /* empty */ { $$ = $<set>-1; } $1->gc_int = $3; $$ = $1; } + | set_block COUNTER stmt_separator + { + $1->stmt = counter_stmt_alloc(&@$); + $$ = $1; + } | set_block ELEMENTS '=' set_block_expr { $1->init = $4; @@ -355,6 +355,7 @@ void set_free(struct set *set) if (set->init != NULL) expr_free(set->init); handle_free(&set->handle); + stmt_free(set->stmt); expr_free(set->key); expr_free(set->data); xfree(set); @@ -544,6 +545,15 @@ static void set_print_declaration(const struct set *set, } nft_print(octx, "%s", opts->stmt_separator); } + + if (set->stmt) { + nft_print(octx, "%s%s", opts->tab, opts->tab); + octx->flags |= NFT_CTX_OUTPUT_STATELESS; + stmt_print(set->stmt, octx); + octx->flags &= ~NFT_CTX_OUTPUT_STATELESS; + nft_print(octx, "%s", opts->stmt_separator); + } + if (set->automerge) nft_print(octx, "%s%sauto-merge%s", opts->tab, opts->tab, opts->stmt_separator); |