diff options
author | Laura Garcia Liebana <nevola@gmail.com> | 2017-02-28 18:42:50 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2017-03-06 18:25:05 +0100 |
commit | 3a86406729782ee2671ec7161c76529c2e4a44e4 (patch) | |
tree | 931f8f89b8ab46e248830aaf4d99570d32beb6a6 /src/hash.c | |
parent | 24091fb6d084890ce167364ac78fed8ceb94ae85 (diff) |
src: hash: support of symmetric hash
This patch provides symmetric hash support according to source
ip address and port, and destination ip address and port.
The new attribute NFTA_HASH_TYPE has been included to support
different types of hashing functions. Currently supported
NFT_HASH_JENKINS through jhash and NFT_HASH_SYM through symhash.
The main difference between both types are:
- jhash requires an expression with sreg, symhash doesn't.
- symhash supports modulus and offset, but not seed.
Examples:
nft add rule ip nat prerouting ct mark set jhash ip saddr mod 2
nft add rule ip nat prerouting ct mark set symhash mod 2
Signed-off-by: Laura Garcia Liebana <laura.garcia@zevenet.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/hash.c')
-rw-r--r-- | src/hash.c | 28 |
1 files changed, 21 insertions, 7 deletions
@@ -17,10 +17,18 @@ static void hash_expr_print(const struct expr *expr) { - printf("jhash "); - expr_print(expr->hash.expr); + switch (expr->hash.type) { + case NFT_HASH_SYM: + printf("symhash"); + break; + case NFT_HASH_JENKINS: + default: + printf("jhash "); + expr_print(expr->hash.expr); + } + printf(" mod %u", expr->hash.mod); - if (expr->hash.seed) + if (expr->hash.type & NFT_HASH_JENKINS && expr->hash.seed) printf(" seed 0x%x", expr->hash.seed); if (expr->hash.offset) printf(" offset %u", expr->hash.offset); @@ -28,18 +36,22 @@ static void hash_expr_print(const struct expr *expr) static bool hash_expr_cmp(const struct expr *e1, const struct expr *e2) { - return expr_cmp(e1->hash.expr, e2->hash.expr) && + return (e1->hash.expr || + expr_cmp(e1->hash.expr, e2->hash.expr)) && e1->hash.mod == e2->hash.mod && e1->hash.seed == e2->hash.seed && - e1->hash.offset == e2->hash.offset; + e1->hash.offset == e2->hash.offset && + e1->hash.type == e2->hash.type; } static void hash_expr_clone(struct expr *new, const struct expr *expr) { - new->hash.expr = expr_clone(expr->hash.expr); + if (expr->hash.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; + new->hash.type = expr->hash.type; } static const struct expr_ops hash_expr_ops = { @@ -51,7 +63,8 @@ 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 offset) + uint32_t seed, uint32_t offset, + enum nft_hash_types type) { struct expr *expr; @@ -60,6 +73,7 @@ struct expr *hash_expr_alloc(const struct location *loc, uint32_t mod, expr->hash.mod = mod; expr->hash.seed = seed; expr->hash.offset = offset; + expr->hash.type = type; return expr; } |