From: Laura Garcia Liebana <nevola@gmail.com>
To: netfilter-devel@vger.kernel.org
Subject: [PATCH v2 nft 2/4] src: add offset attribute for hash expression
Date: Tue, 1 Nov 2016 16:04:01 +0100 [thread overview]
Message-ID: <20161101150358.GA6930@sonyv> (raw)
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 <nevola@gmail.com>
---
Changes in v2:
- Adapt the code to the repository changes.
- Include test payload.
- 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 | 1 +
tests/py/ip/hash.t.payload | 7 +++++++
9 files changed, 28 insertions(+), 9 deletions(-)
diff --git a/include/expression.h b/include/expression.h
index 3a52a45..71e9c43 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -307,6 +307,7 @@ struct expr {
struct expr *expr;
uint32_t mod;
uint32_t seed;
+ uint32_t offset;
} hash;
struct {
/* EXPR_FIB */
diff --git a/include/hash.h b/include/hash.h
index 6d6badd..420a367 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -14,6 +14,7 @@
#endif
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 */
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index c6567ac..0fb63fe 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -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)
diff --git a/src/hash.c b/src/hash.c
index 125b320..d26b2ed 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -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;
}
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index f0df884..434089b 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -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);
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index b5967d4..a72a3d2 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -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);
}
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 6a24bec..9a6ce90 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -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, selrandom());
+ $$ = hash_expr_alloc(&@$, $4, selrandom(), $5);
$$->hash.expr = $2;
}
;
diff --git a/tests/py/ip/hash.t b/tests/py/ip/hash.t
index 6dfa965..802e0df 100644
--- a/tests/py/ip/hash.t
+++ b/tests/py/ip/hash.t
@@ -2,4 +2,5 @@
*ip;test-ip4;pre
ct mark set jhash ip saddr . ip daddr mod 2 seed 0xdeadbeef;ok
+ct mark set jhash ip saddr . ip daddr mod 2 seed 0xdeadbeef offset 100;ok
dnat to jhash ip saddr mod 2 seed 0xdeadbeef map { 0 : 192.168.20.100, 1 : 192.168.30.100 };ok
diff --git a/tests/py/ip/hash.t.payload b/tests/py/ip/hash.t.payload
index d9a22eb..1c464d6 100644
--- a/tests/py/ip/hash.t.payload
+++ b/tests/py/ip/hash.t.payload
@@ -5,6 +5,13 @@ ip test-ip4 pre
[ hash reg 1 = jhash(reg 2, 8, 0xdeadbeef) % 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 ]
+
# 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
--
2.9.3
reply other threads:[~2016-11-01 15:04 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20161101150358.GA6930@sonyv \
--to=nevola@gmail.com \
--cc=netfilter-devel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.