From d4f9a8fb9e9acc09b0726e19e7c8e5faaa959803 Mon Sep 17 00:00:00 2001 From: Laura Garcia Liebana Date: Sat, 22 Oct 2016 23:36:07 +0200 Subject: src: add offset attribute for numgen expression Add support to add an offset to the numgen generated value. Example: ct mark set numgen inc mod 2 offset 100 This will generate marks with serie like 100, 101, 100, ... Signed-off-by: Laura Garcia Liebana Signed-off-by: Pablo Neira Ayuso --- include/expression.h | 1 + include/linux/netfilter/nf_tables.h | 2 ++ include/numgen.h | 3 ++- src/netlink_delinearize.c | 5 +++-- src/netlink_linearize.c | 1 + src/numgen.c | 10 ++++++++-- src/parser_bison.y | 4 ++-- tests/py/ip/numgen.t | 1 + 8 files changed, 20 insertions(+), 7 deletions(-) diff --git a/include/expression.h b/include/expression.h index 13ca315c..eda3d98f 100644 --- a/include/expression.h +++ b/include/expression.h @@ -291,6 +291,7 @@ struct expr { /* EXPR_NUMGEN */ enum nft_ng_types type; uint32_t mod; + uint32_t offset; } numgen; struct { /* EXPR_HASH */ diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index b21a844c..e84a9f5b 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h @@ -1157,12 +1157,14 @@ enum nft_trace_types { * @NFTA_NG_DREG: destination register (NLA_U32) * @NFTA_NG_MODULUS: maximum counter value (NLA_U32) * @NFTA_NG_TYPE: operation type (NLA_U32) + * @NFTA_NG_OFFSET: offset value (NLA_U32) */ enum nft_ng_attributes { NFTA_NG_UNSPEC, NFTA_NG_DREG, NFTA_NG_MODULUS, NFTA_NG_TYPE, + NFTA_NG_OFFSET, __NFTA_NG_MAX }; #define NFTA_NG_MAX (__NFTA_NG_MAX - 1) diff --git a/include/numgen.h b/include/numgen.h index bec18e5a..b2306200 100644 --- a/include/numgen.h +++ b/include/numgen.h @@ -2,6 +2,7 @@ #define NFTABLES_NUMGEN_H extern struct expr *numgen_expr_alloc(const struct location *loc, - enum nft_ng_types type, uint32_t until); + enum nft_ng_types type, uint32_t until, + uint32_t offset); #endif /* NFTABLES_NUMGEN_H */ diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index d8d1d7d7..c3b0b278 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -590,13 +590,14 @@ static void netlink_parse_numgen(struct netlink_parse_ctx *ctx, const struct nftnl_expr *nle) { enum nft_registers dreg; - uint32_t type, until; + uint32_t type, until, offset; struct expr *expr; type = nftnl_expr_get_u32(nle, NFTNL_EXPR_NG_TYPE); until = nftnl_expr_get_u32(nle, NFTNL_EXPR_NG_MODULUS); + offset = nftnl_expr_get_u32(nle, NFTNL_EXPR_NG_OFFSET); - expr = numgen_expr_alloc(loc, type, until); + expr = numgen_expr_alloc(loc, type, until, offset); dreg = netlink_parse_register(nle, NFTNL_EXPR_NG_DREG); netlink_set_register(ctx, dreg, expr); } diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c index 0072dca0..80199318 100644 --- a/src/netlink_linearize.c +++ b/src/netlink_linearize.c @@ -182,6 +182,7 @@ static void netlink_gen_numgen(struct netlink_linearize_ctx *ctx, netlink_put_register(nle, NFTNL_EXPR_NG_DREG, dreg); netlink_put_register(nle, NFTNL_EXPR_NG_TYPE, expr->numgen.type); nftnl_expr_set_u32(nle, NFTNL_EXPR_NG_MODULUS, expr->numgen.mod); + nftnl_expr_set_u32(nle, NFTNL_EXPR_NG_OFFSET, expr->numgen.offset); nftnl_rule_add_expr(ctx->nlr, nle); } diff --git a/src/numgen.c b/src/numgen.c index d9a43aa0..5c1d00a0 100644 --- a/src/numgen.c +++ b/src/numgen.c @@ -32,18 +32,22 @@ static void numgen_expr_print(const struct expr *expr) { printf("numgen %s mod %u", numgen_type_str(expr->numgen.type), expr->numgen.mod); + if (expr->numgen.offset) + printf(" offset %u", expr->numgen.offset); } static bool numgen_expr_cmp(const struct expr *e1, const struct expr *e2) { return e1->numgen.type == e2->numgen.type && - e1->numgen.mod == e2->numgen.mod; + e1->numgen.mod == e2->numgen.mod && + e1->numgen.offset == e2->numgen.offset; } static void numgen_expr_clone(struct expr *new, const struct expr *expr) { new->numgen.type = expr->numgen.type; new->numgen.mod = expr->numgen.mod; + new->numgen.offset = expr->numgen.offset; } static const struct expr_ops numgen_expr_ops = { @@ -55,7 +59,8 @@ static const struct expr_ops numgen_expr_ops = { }; struct expr *numgen_expr_alloc(const struct location *loc, - enum nft_ng_types type, uint32_t mod) + enum nft_ng_types type, uint32_t mod, + uint32_t offset) { struct expr *expr; @@ -63,6 +68,7 @@ struct expr *numgen_expr_alloc(const struct location *loc, BYTEORDER_HOST_ENDIAN, 4 * BITS_PER_BYTE); expr->numgen.type = type; expr->numgen.mod = mod; + expr->numgen.offset = offset; return expr; } diff --git a/src/parser_bison.y b/src/parser_bison.y index f582221a..7377492b 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -2490,9 +2490,9 @@ numgen_type : INC { $$ = NFT_NG_INCREMENTAL; } | RANDOM { $$ = NFT_NG_RANDOM; } ; -numgen_expr : NUMGEN numgen_type MOD NUM +numgen_expr : NUMGEN numgen_type MOD NUM offset_opt { - $$ = numgen_expr_alloc(&@$, $2, $4); + $$ = numgen_expr_alloc(&@$, $2, $4, $5); } ; diff --git a/tests/py/ip/numgen.t b/tests/py/ip/numgen.t index 9ce0c714..29a6a105 100644 --- a/tests/py/ip/numgen.t +++ b/tests/py/ip/numgen.t @@ -2,5 +2,6 @@ *ip;test-ip4;pre ct mark set numgen inc mod 2;ok +ct mark set numgen inc mod 2 offset 100;ok dnat to numgen inc mod 2 map { 0 : 192.168.10.100, 1 : 192.168.20.200 };ok dnat to numgen inc mod 10 map { 0-5 : 192.168.10.100, 6-9 : 192.168.20.200};ok -- cgit v1.2.3