summaryrefslogtreecommitdiffstats
path: root/src/hash.c
diff options
context:
space:
mode:
authorLaura Garcia Liebana <nevola@gmail.com>2017-02-28 18:42:50 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2017-03-06 18:25:05 +0100
commit3a86406729782ee2671ec7161c76529c2e4a44e4 (patch)
tree931f8f89b8ab46e248830aaf4d99570d32beb6a6 /src/hash.c
parent24091fb6d084890ce167364ac78fed8ceb94ae85 (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.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/src/hash.c b/src/hash.c
index d26b2eda..a7a96122 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -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;
}