summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hash.c11
-rw-r--r--src/netlink_delinearize.c4
-rw-r--r--src/netlink_linearize.c3
-rw-r--r--src/parser_bison.y17
4 files changed, 22 insertions, 13 deletions
diff --git a/src/hash.c b/src/hash.c
index bec1684e..c738d0b6 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -28,7 +28,7 @@ static void hash_expr_print(const struct expr *expr)
}
printf(" mod %u", expr->hash.mod);
- if ((expr->hash.type == NFT_HASH_JENKINS) && expr->hash.seed)
+ if (expr->hash.seed_set)
printf(" seed 0x%x", expr->hash.seed);
if (expr->hash.offset)
printf(" offset %u", expr->hash.offset);
@@ -39,6 +39,7 @@ static bool hash_expr_cmp(const struct expr *e1, const struct expr *e2)
return (e1->hash.expr ||
expr_cmp(e1->hash.expr, e2->hash.expr)) &&
e1->hash.mod == e2->hash.mod &&
+ e1->hash.seed_set == e2->hash.seed_set &&
e1->hash.seed == e2->hash.seed &&
e1->hash.offset == e2->hash.offset &&
e1->hash.type == e2->hash.type;
@@ -49,6 +50,7 @@ static void hash_expr_clone(struct expr *new, const struct expr *expr)
if (expr->hash.expr)
new->hash.expr = expr_clone(expr->hash.expr);
new->hash.mod = expr->hash.mod;
+ new->hash.seed_set = expr->hash.seed_set;
new->hash.seed = expr->hash.seed;
new->hash.offset = expr->hash.offset;
new->hash.type = expr->hash.type;
@@ -62,8 +64,10 @@ static const struct expr_ops hash_expr_ops = {
.clone = hash_expr_clone,
};
-struct expr *hash_expr_alloc(const struct location *loc, uint32_t mod,
- uint32_t seed, uint32_t offset,
+struct expr *hash_expr_alloc(const struct location *loc,
+ uint32_t mod,
+ bool seed_set, uint32_t seed,
+ uint32_t offset,
enum nft_hash_types type)
{
struct expr *expr;
@@ -71,6 +75,7 @@ struct expr *hash_expr_alloc(const struct location *loc, uint32_t mod,
expr = expr_alloc(loc, &hash_expr_ops, &integer_type,
BYTEORDER_HOST_ENDIAN, 4 * BITS_PER_BYTE);
expr->hash.mod = mod;
+ expr->hash.seed_set = seed_set;
expr->hash.seed = seed;
expr->hash.offset = offset;
expr->hash.type = type;
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 9ad1e2c6..4a0b8dcc 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -525,13 +525,15 @@ static void netlink_parse_hash(struct netlink_parse_ctx *ctx,
struct expr *expr, *hexpr;
uint32_t mod, seed, len, offset;
enum nft_hash_types type;
+ bool seed_set;
type = nftnl_expr_get_u32(nle, NFTNL_EXPR_HASH_TYPE);
offset = nftnl_expr_get_u32(nle, NFTNL_EXPR_HASH_OFFSET);
+ seed_set = nftnl_expr_is_set(nle, NFTNL_EXPR_HASH_SEED);
seed = nftnl_expr_get_u32(nle, NFTNL_EXPR_HASH_SEED);
mod = nftnl_expr_get_u32(nle, NFTNL_EXPR_HASH_MODULUS);
- expr = hash_expr_alloc(loc, mod, seed, offset, type);
+ expr = hash_expr_alloc(loc, mod, seed_set, seed, offset, type);
if (type != NFT_HASH_SYM) {
sreg = netlink_parse_register(nle, NFTNL_EXPR_HASH_SREG);
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index b2f27b7a..3d684569 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -139,7 +139,8 @@ static void netlink_gen_hash(struct netlink_linearize_ctx *ctx,
}
netlink_put_register(nle, NFTNL_EXPR_HASH_DREG, dreg);
nftnl_expr_set_u32(nle, NFTNL_EXPR_HASH_MODULUS, expr->hash.mod);
- nftnl_expr_set_u32(nle, NFTNL_EXPR_HASH_SEED, expr->hash.seed);
+ if (expr->hash.seed_set)
+ 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_expr_set_u32(nle, NFTNL_EXPR_HASH_TYPE, expr->hash.type);
nftnl_rule_add_expr(ctx->nlr, nle);
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 9f993fd3..8db887a4 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -520,7 +520,7 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%destructor { stmt_free($$); } reject_stmt reject_stmt_alloc
%type <stmt> nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc redir_stmt redir_stmt_alloc
%destructor { stmt_free($$); } nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc redir_stmt redir_stmt_alloc
-%type <val> nf_nat_flags nf_nat_flag offset_opt seed_opt
+%type <val> nf_nat_flags nf_nat_flag offset_opt
%type <stmt> queue_stmt queue_stmt_alloc
%destructor { stmt_free($$); } queue_stmt queue_stmt_alloc
%type <val> queue_stmt_flags queue_stmt_flag
@@ -3092,18 +3092,19 @@ numgen_expr : NUMGEN numgen_type MOD NUM offset_opt
}
;
-seed_opt : /* empty */ { $$ = 0; }
- | SEED NUM { $$ = $2; }
- ;
-
-hash_expr : JHASH expr MOD NUM seed_opt offset_opt
+hash_expr : JHASH expr MOD NUM SEED NUM offset_opt
+ {
+ $$ = hash_expr_alloc(&@$, $4, true, $6, $7, NFT_HASH_JENKINS);
+ $$->hash.expr = $2;
+ }
+ | JHASH expr MOD NUM offset_opt
{
- $$ = hash_expr_alloc(&@$, $4, $5, $6, NFT_HASH_JENKINS);
+ $$ = hash_expr_alloc(&@$, $4, false, 0, $5, NFT_HASH_JENKINS);
$$->hash.expr = $2;
}
| SYMHASH MOD NUM offset_opt
{
- $$ = hash_expr_alloc(&@$, $3, 0, $4, NFT_HASH_SYM);
+ $$ = hash_expr_alloc(&@$, $3, false, 0, $4, NFT_HASH_SYM);
}
;