]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: add offset attribute for numgen expression
authorLaura Garcia Liebana <nevola@gmail.com>
Sat, 22 Oct 2016 21:36:07 +0000 (23:36 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Thu, 27 Oct 2016 19:46:43 +0000 (21:46 +0200)
Add support to add an offset to the numgen generated value.

Example:

 ct mark set numgen inc mod 2 offset 100

This will generate marks with serie like 100, 101, 100, ...

Signed-off-by: Laura Garcia Liebana <nevola@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/expression.h
include/linux/netfilter/nf_tables.h
include/numgen.h
src/netlink_delinearize.c
src/netlink_linearize.c
src/numgen.c
src/parser_bison.y
tests/py/ip/numgen.t

index 13ca315cb9e72adc147c6b1bb8109e63b2bcf227..eda3d98f8cf003a9871c50a4e101a367644beb1c 100644 (file)
@@ -291,6 +291,7 @@ struct expr {
                        /* EXPR_NUMGEN */
                        enum nft_ng_types       type;
                        uint32_t                mod;
+                       uint32_t                offset;
                } numgen;
                struct {
                        /* EXPR_HASH */
index b21a844cf5d51a873013cf310df8d02b232aca53..e84a9f5b401fb73ca4f76a253651148f36c2f186 100644 (file)
@@ -1157,12 +1157,14 @@ enum nft_trace_types {
  * @NFTA_NG_DREG: destination register (NLA_U32)
  * @NFTA_NG_MODULUS: maximum counter value (NLA_U32)
  * @NFTA_NG_TYPE: operation type (NLA_U32)
+ * @NFTA_NG_OFFSET: offset value (NLA_U32)
  */
 enum nft_ng_attributes {
        NFTA_NG_UNSPEC,
        NFTA_NG_DREG,
        NFTA_NG_MODULUS,
        NFTA_NG_TYPE,
+       NFTA_NG_OFFSET,
        __NFTA_NG_MAX
 };
 #define NFTA_NG_MAX    (__NFTA_NG_MAX - 1)
index bec18e5a6f22798cfe25ce56ea071c22dfc9b2e1..b230620095150c4fdd7fb3a66dcca1b1f844d1bd 100644 (file)
@@ -2,6 +2,7 @@
 #define NFTABLES_NUMGEN_H
 
 extern struct expr *numgen_expr_alloc(const struct location *loc,
-                                     enum nft_ng_types type, uint32_t until);
+                                     enum nft_ng_types type, uint32_t until,
+                                     uint32_t offset);
 
 #endif /* NFTABLES_NUMGEN_H */
index d8d1d7d7aaa71a2ca62113853e6349e1e11200f9..c3b0b2788ab37e11c0cd73253db9fbf737f73574 100644 (file)
@@ -590,13 +590,14 @@ static void netlink_parse_numgen(struct netlink_parse_ctx *ctx,
                                 const struct nftnl_expr *nle)
 {
        enum nft_registers dreg;
-       uint32_t type, until;
+       uint32_t type, until, offset;
        struct expr *expr;
 
        type  = nftnl_expr_get_u32(nle, NFTNL_EXPR_NG_TYPE);
        until = nftnl_expr_get_u32(nle, NFTNL_EXPR_NG_MODULUS);
+       offset = nftnl_expr_get_u32(nle, NFTNL_EXPR_NG_OFFSET);
 
-       expr = numgen_expr_alloc(loc, type, until);
+       expr = numgen_expr_alloc(loc, type, until, offset);
        dreg = netlink_parse_register(nle, NFTNL_EXPR_NG_DREG);
        netlink_set_register(ctx, dreg, expr);
 }
index 0072dca091ea1b3626a9fa2c3c81c28994bebf59..80199318365fe9311015e39a92d72a8d8ca8bf30 100644 (file)
@@ -182,6 +182,7 @@ static void netlink_gen_numgen(struct netlink_linearize_ctx *ctx,
        netlink_put_register(nle, NFTNL_EXPR_NG_DREG, dreg);
        netlink_put_register(nle, NFTNL_EXPR_NG_TYPE, expr->numgen.type);
        nftnl_expr_set_u32(nle, NFTNL_EXPR_NG_MODULUS, expr->numgen.mod);
+       nftnl_expr_set_u32(nle, NFTNL_EXPR_NG_OFFSET, expr->numgen.offset);
        nftnl_rule_add_expr(ctx->nlr, nle);
 }
 
index d9a43aa075c4f797dfcd52e60f9b9fa32080f418..5c1d00a0613e73bb7393d07ab8dc071b521e6084 100644 (file)
@@ -32,18 +32,22 @@ static void numgen_expr_print(const struct expr *expr)
 {
        printf("numgen %s mod %u", numgen_type_str(expr->numgen.type),
               expr->numgen.mod);
+       if (expr->numgen.offset)
+               printf(" offset %u", expr->numgen.offset);
 }
 
 static bool numgen_expr_cmp(const struct expr *e1, const struct expr *e2)
 {
        return e1->numgen.type == e2->numgen.type &&
-              e1->numgen.mod == e2->numgen.mod;
+              e1->numgen.mod == e2->numgen.mod &&
+              e1->numgen.offset == e2->numgen.offset;
 }
 
 static void numgen_expr_clone(struct expr *new, const struct expr *expr)
 {
        new->numgen.type = expr->numgen.type;
        new->numgen.mod = expr->numgen.mod;
+       new->numgen.offset = expr->numgen.offset;
 }
 
 static const struct expr_ops numgen_expr_ops = {
@@ -55,7 +59,8 @@ static const struct expr_ops numgen_expr_ops = {
 };
 
 struct expr *numgen_expr_alloc(const struct location *loc,
-                              enum nft_ng_types type, uint32_t mod)
+                              enum nft_ng_types type, uint32_t mod,
+                              uint32_t offset)
 {
        struct expr *expr;
 
@@ -63,6 +68,7 @@ struct expr *numgen_expr_alloc(const struct location *loc,
                          BYTEORDER_HOST_ENDIAN, 4 * BITS_PER_BYTE);
        expr->numgen.type  = type;
        expr->numgen.mod   = mod;
+       expr->numgen.offset = offset;
 
        return expr;
 }
index f582221a089e76ce6960755eb8a010a35effe750..7377492baf8645d453d7efc1a57ce15375416528 100644 (file)
@@ -2490,9 +2490,9 @@ numgen_type               :       INC             { $$ = NFT_NG_INCREMENTAL; }
                        |       RANDOM          { $$ = NFT_NG_RANDOM; }
                        ;
 
-numgen_expr            :       NUMGEN  numgen_type     MOD     NUM
+numgen_expr            :       NUMGEN  numgen_type     MOD     NUM     offset_opt
                        {
-                               $$ = numgen_expr_alloc(&@$, $2, $4);
+                               $$ = numgen_expr_alloc(&@$, $2, $4, $5);
                        }
                        ;
 
index 9ce0c7147d0a75875f03a384fa85a68d3e1f61d1..29a6a105a0e0c3d8d93ad49162f8ae82cae52af9 100644 (file)
@@ -2,5 +2,6 @@
 *ip;test-ip4;pre
 
 ct mark set numgen inc mod 2;ok
+ct mark set numgen inc mod 2 offset 100;ok
 dnat to numgen inc mod 2 map { 0 : 192.168.10.100, 1 : 192.168.20.200 };ok
 dnat to numgen inc mod 10 map { 0-5 : 192.168.10.100, 6-9 : 192.168.20.200};ok