]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: add offset attribute for hash expression
authorLaura Garcia Liebana <nevola@gmail.com>
Fri, 4 Nov 2016 13:01:12 +0000 (14:01 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 8 Nov 2016 23:21:39 +0000 (00:21 +0100)
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>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/expression.h
include/hash.h
include/linux/netfilter/nf_tables.h
src/hash.c
src/netlink_delinearize.c
src/netlink_linearize.c
src/parser_bison.y
tests/py/ip/hash.t
tests/py/ip/hash.t.payload

index 3a52a45c034f7b972ee014a03054225fe1cb545c..71e9c43ef0e1fa7b0a0900f8e091a546466b9304 100644 (file)
@@ -307,6 +307,7 @@ struct expr {
                        struct expr             *expr;
                        uint32_t                mod;
                        uint32_t                seed;
+                       uint32_t                offset;
                } hash;
                struct {
                        /* EXPR_FIB */
index bc8c86af71495b779db161e73f1ad9576b59b6e3..8bf53e2e2bfb2f20cdcdc317c71ed3960439f1c3 100644 (file)
@@ -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 */
index c6567aceb115465eea5cb7e7f89f2ae7c9573f89..0fb63fe03d1532940c0af03fdb070268bd9eebb4 100644 (file)
@@ -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)
index 125b3202cb91c4185ecb23232263d36124b3300e..d26b2eda84e9058ca3fedd51b5411c8e4304934c 100644 (file)
@@ -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;
 }
index f0df884818f077cf1e7dfafe95f63570d92ea695..434089b714dc2721e55b7e8e43fe9ff749cff969 100644 (file)
@@ -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);
index 0458af953fe66f6d391529104837350711c9cd9d..6c0f39bf40cff1df212e4147bdfc48f1da7ce845 100644 (file)
@@ -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);
 }
 
index 82fec99c92404f165be41b48da21757ace258b91..74f24a52549a14442c6e7ebc245bbb60236dfa9c 100644 (file)
@@ -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;
                        }
                        ;
index 306ebfd084999f43d5b05529f15d706d805be875..0d01a11dcedefcb935675c1fee4da9b56c416971 100644 (file)
@@ -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
index 1188a1b1d1aa7ea0ad3cbc5d7d0dd0a9a2d8b637..c410a8c67ef31ce958a2d953797606053344d2e4 100644 (file)
@@ -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