summaryrefslogtreecommitdiffstats
path: root/src/netlink_delinearize.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2018-08-24 09:52:22 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2018-08-24 09:52:22 +0200
commita55ca1a24b7b216144dc737f621fb68f4a924e38 (patch)
treee104f4c5d5ad34b39f58a3b05b80aba85858d0c0 /src/netlink_delinearize.c
parent0e90798e98121abab274434ec60f0b873f510021 (diff)
src: integrate stateful expressions into sets and maps
The following example shows how to populate a set from the packet path using the destination IP address, for each entry there is a counter. The entry expires after the 1 hour timeout if no packets matching this entry are seen. table ip x { set xyz { type ipv4_addr size 65535 flags dynamic,timeout timeout 1h } chain y { type filter hook output priority filter; policy accept; update @xyz { ip daddr counter } counter } } Similar example, that creates a mapping better IP address and mark, where the mark is assigned using an incremental sequence generator from 0 to 1 inclusive. table ip x { map xyz { type ipv4_addr : mark size 65535 flags dynamic,timeout timeout 1h } chain y { type filter hook input priority filter; policy accept; update @xyz { ip saddr counter : numgen inc mod 2 } } } Supported stateful statements are: limit, quota, counter and connlimit. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/netlink_delinearize.c')
-rw-r--r--src/netlink_delinearize.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 898c737f..6c5188cd 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -1312,23 +1312,27 @@ static void netlink_parse_dynset(struct netlink_parse_ctx *ctx,
expr_data = netlink_get_register(ctx, loc, sreg_data);
}
- if (dstmt != NULL) {
- stmt = meter_stmt_alloc(loc);
- stmt->meter.set = set_ref_expr_alloc(loc, set);
- stmt->meter.key = expr;
- stmt->meter.stmt = dstmt;
- stmt->meter.size = set->desc.size;
- } else if (expr_data != NULL) {
+ if (expr_data != NULL) {
stmt = map_stmt_alloc(loc);
stmt->map.set = set_ref_expr_alloc(loc, set);
stmt->map.key = expr;
stmt->map.data = expr_data;
+ stmt->map.stmt = dstmt;
stmt->map.op = nftnl_expr_get_u32(nle, NFTNL_EXPR_DYNSET_OP);
} else {
- stmt = set_stmt_alloc(loc);
- stmt->set.set = set_ref_expr_alloc(loc, set);
- stmt->set.op = nftnl_expr_get_u32(nle, NFTNL_EXPR_DYNSET_OP);
- stmt->set.key = expr;
+ if (dstmt != NULL && set->flags & NFT_SET_ANONYMOUS) {
+ stmt = meter_stmt_alloc(loc);
+ stmt->meter.set = set_ref_expr_alloc(loc, set);
+ stmt->meter.key = expr;
+ stmt->meter.stmt = dstmt;
+ stmt->meter.size = set->desc.size;
+ } else {
+ stmt = set_stmt_alloc(loc);
+ stmt->set.set = set_ref_expr_alloc(loc, set);
+ stmt->set.op = nftnl_expr_get_u32(nle, NFTNL_EXPR_DYNSET_OP);
+ stmt->set.key = expr;
+ stmt->set.stmt = dstmt;
+ }
}
ctx->stmt = stmt;