src: add offset attribute for hash expression
PATCH v3 2/4 src: add offset attribute for hash expression
Add support to add an offset to the hash generator, eg.
ct mark set hash ip saddr mod 10 offset 100
This will generate marks with series between 100-109.
Signed-off-by Laura Garcia Liebana <[email protected]>
---
Changes in v3:
- This patch depends on 1/4.
include/expression.h | 1 + include/hash.h | 3 ++- include/linux/netfilter/nf_tables.h | 2 ++ src/hash.c | 9 +++++++-- src/netlink_delinearize.c | 5 +++-- src/netlink_linearize.c | 1 + src/parser_bison.y | 8 ++++---- tests/py/ip/hash.t | 2 ++ tests/py/ip/hash.t.payload | 14 ++++++++++++++ 9 files changed, 36 insertions(+), 9 deletions(-)
include/expression.h +1 -0
@@ -307,6 +307,7 @@ struct expr {struct expr *expr;uint32_t mod;uint32_t seed; +uint32_t offset; } hash;struct {/* EXPR_FIB */
include/hash.h +2 -1
@@ -2,6 +2,7 @@#define NFTABLES_HASH_H extern struct expr *hash_expr_alloc (const struct location *loc, -uint32_t modulus,uint32_t seed); +uint32_t modulus,uint32_t seed, +uint32_t offset);#endif /* NFTABLES_HASH_H */
include/linux/netfilter/nf_tables.h +2 -0
@@ -773,6 +773,7 @@ enum nft_rt_keys {* @NFTA_HASH_LEN: source data length (NLA_U32) * @NFTA_HASH_MODULUS: modulus value (NLA_U32) * @NFTA_HASH_SEED: seed value (NLA_U32) +* @NFTA_HASH_OFFSET: offset value (NLA_U32) */ enum nft_hash_attributes {NFTA_HASH_UNSPEC ,
@@ -781,6 +782,7 @@ enum nft_hash_attributes {NFTA_HASH_LEN ,NFTA_HASH_MODULUS ,NFTA_HASH_SEED , +NFTA_HASH_OFFSET , __NFTA_HASH_MAX, };#define NFTA_HASH_MAX (__NFTA_HASH_MAX - 1)
src/hash.c +7 -2
@@ -22,13 +22,16 @@ static void hash_expr_print(const struct expr *expr)printf (" mod %u" , expr->hash.mod);if (expr->hash.seed)printf (" seed 0x%x" , expr->hash.seed); +if (expr->hash.offset) +printf (" offset %u" , expr->hash.offset); }static bool hash_expr_cmp (const struct expr *e1,const struct expr *e2) {return expr_cmp (e1->hash.expr, e2->hash.expr) && e1->hash.mod == e2->hash.mod && - e1->hash.seed == e2->hash.seed; + e1->hash.seed == e2->hash.seed && + e1->hash.offset == e2->hash.offset; }static void hash_expr_clone (struct expr *new,const struct expr *expr)
@@ -36,6 +39,7 @@ static void hash_expr_clone(struct expr *new, const struct expr *expr) new->hash.expr =expr_clone (expr->hash.expr); new->hash.mod = expr->hash.mod; new->hash.seed = expr->hash.seed; + new->hash.offset = expr->hash.offset; }static const struct expr_ops hash_expr_ops = {
@@ -47,7 +51,7 @@ static const struct expr_ops hash_expr_ops = { };struct expr *hash_expr_alloc (const struct location *loc,uint32_t mod, -uint32_t seed) +uint32_t seed,uint32_t offset) {struct expr *expr;
@@ -55,6 +59,7 @@ struct expr *hash_expr_alloc(const struct location *loc, uint32_t mod, BYTEORDER_HOST_ENDIAN, 4 * BITS_PER_BYTE); expr->hash.mod = mod; expr->hash.seed = seed; + expr->hash.offset = offset;return expr; }
src/netlink_delinearize.c +3 -2
@@ -513,7 +513,7 @@ static void netlink_parse_hash(struct netlink_parse_ctx *ctx, {enum nft_registers sreg, dreg;struct expr *expr, *hexpr; -uint32_t mod, seed, len; +uint32_t mod, seed, len, offset; sreg =netlink_parse_register (nle,NFTNL_EXPR_HASH_SREG ); hexpr =netlink_get_register (ctx, loc, sreg);
@@ -521,6 +521,7 @@ static void netlink_parse_hash(struct netlink_parse_ctx *ctx,return netlink_error (ctx, loc,"hash statement has no expression" ); + offset =nftnl_expr_get_u32 (nle,NFTNL_EXPR_HASH_OFFSET ); seed =nftnl_expr_get_u32 (nle,NFTNL_EXPR_HASH_SEED ); mod =nftnl_expr_get_u32 (nle,NFTNL_EXPR_HASH_MODULUS ); len =nftnl_expr_get_u32 (nle,NFTNL_EXPR_HASH_LEN ) *BITS_PER_BYTE ;
@@ -531,7 +532,7 @@ static void netlink_parse_hash(struct netlink_parse_ctx *ctx,return ; } - expr =hash_expr_alloc (loc, mod, seed); + expr =hash_expr_alloc (loc, mod, seed, offset); expr->hash.expr = hexpr; dreg =netlink_parse_register (nle,NFTNL_EXPR_HASH_DREG );
src/netlink_linearize.c +1 -0
@@ -136,6 +136,7 @@ static void netlink_gen_hash(struct netlink_linearize_ctx *ctx, div_round_up(expr->hash.expr->len, BITS_PER_BYTE));nftnl_expr_set_u32 (nle,NFTNL_EXPR_HASH_MODULUS , expr->hash.mod);nftnl_expr_set_u32 (nle,NFTNL_EXPR_HASH_SEED , expr->hash.seed); +nftnl_expr_set_u32 (nle,NFTNL_EXPR_HASH_OFFSET , expr->hash.offset);nftnl_rule_add_expr (ctx->nlr, nle); }
src/parser_bison.y +4 -4
@@ -2580,14 +2580,14 @@ numgen_expr : NUMGEN numgen_type MOD NUM offset_opt } ; -hash_expr : JHASH expr MOD NUM SEED NUM +hash_expr : JHASH expr MOD NUM SEED NUM offset_opt { - $$ = hash_expr_alloc(&@$, $4, $6); + $$ = hash_expr_alloc(&@$, $4, $6, $7); $$->hash.expr = $2; } - | JHASH expr MOD NUM + | JHASH expr MOD NUM offset_opt { - $$ = hash_expr_alloc(&@$, $4, 0); + $$ = hash_expr_alloc(&@$, $4, 0, $5); $$->hash.expr = $2; } ;
tests/py/ip/hash.t +2 -0
@@ -3,4 +3,6 @@ ct mark set jhash ip saddr . ip daddr mod 2 seed 0xdeadbeef;ok ct mark set jhash ip saddr . ip daddr mod 2;ok +ct mark set jhash ip saddr . ip daddr mod 2 seed 0xdeadbeef offset 100;ok +ct mark set jhash ip saddr . ip daddr mod 2 offset 100;ok dnat to jhash ip saddr mod 2 seed 0xdeadbeef map { 0 : 192.168.20.100, 1 : 192.168.30.100 };ok
tests/py/ip/hash.t.payload +14 -0
@@ -12,6 +12,20 @@ ip test-ip4 pre [ hash reg 1 = jhash(reg 2, 8, 0x0) % mod 2 ] [ ct set mark with reg 1 ] +# ct mark set jhash ip saddr . ip daddr mod 2 seed 0xdeadbeef offset 100 +ip test-ip4 pre + [ payload load 4b @ network header + 12 => reg 2 ] + [ payload load 4b @ network header + 16 => reg 13 ] + [ hash reg 1 = jhash(reg 2, 8, 0xdeadbeef) % mod 2 offset 100 ] + [ ct set mark with reg 1 ] + +# ct mark set jhash ip saddr . ip daddr mod 2 offset 100 +ip test-ip4 pre + [ payload load 4b @ network header + 12 => reg 2 ] + [ payload load 4b @ network header + 16 => reg 13 ] + [ hash reg 1 = jhash(reg 2, 8, 0x0) % mod 2 offset 100 ] + [ ct set mark with reg 1 ] + # dnat to jhash ip saddr mod 2 seed 0xdeadbeef map { 0 : 192.168.20.100, 1 : 192.168.30.100 } __map%d test-ip4 b __map%d test-ip4 0
Signature · 1 line
2.9.3
Pablo Neira Ayuso
maintainerQuoted 5 lines · Laura Garcia Liebana
Add support to add an offset to the hash generator, eg.
ct mark set hash ip saddr mod 10 offset 100
This will generate marks with series between 100-109.
Also applied, thanks.