]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: add masquerade support
authorArturo Borrero <arturo.borrero.glez@gmail.com>
Mon, 6 Oct 2014 19:51:24 +0000 (21:51 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Thu, 9 Oct 2014 16:46:36 +0000 (18:46 +0200)
This patch adds masquerade support for nft.

The syntax is:

 % nft add rule nat postrouting masquerade [flags]

Currently, flags are:
 random, random-fully, persistent

Example:
 % nft add rule nat postrouting masquerade random,persistent

Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/statement.h
src/evaluate.c
src/netlink_delinearize.c
src/netlink_linearize.c
src/parser.y
src/scanner.l
src/statement.c

index e523254288b5049660e7e6a38e01e419b659cd89..35c1b7ae44304a02842a6109d325f4cb5809d5ec 100644 (file)
@@ -73,6 +73,12 @@ struct nat_stmt {
 
 extern struct stmt *nat_stmt_alloc(const struct location *loc);
 
+struct masq_stmt {
+       uint32_t                flags;
+};
+
+extern struct stmt *masq_stmt_alloc(const struct location *loc);
+
 struct queue_stmt {
        struct expr             *queue;
        uint16_t                flags;
@@ -103,6 +109,7 @@ extern struct stmt *ct_stmt_alloc(const struct location *loc,
  * @STMT_LOG:          log statement
  * @STMT_REJECT:       REJECT statement
  * @STMT_NAT:          NAT statement
+ * @STMT_MASQ:         masquerade statement
  * @STMT_QUEUE:                QUEUE statement
  * @STMT_CT:           conntrack statement
  */
@@ -116,6 +123,7 @@ enum stmt_types {
        STMT_LOG,
        STMT_REJECT,
        STMT_NAT,
+       STMT_MASQ,
        STMT_QUEUE,
        STMT_CT,
 };
@@ -163,6 +171,7 @@ struct stmt {
                struct limit_stmt       limit;
                struct reject_stmt      reject;
                struct nat_stmt         nat;
+               struct masq_stmt        masq;
                struct queue_stmt       queue;
                struct ct_stmt          ct;
        };
index 83ef749829413a9cf4694fa0868b4f9f8eea404d..108248a7c12efd262b8e3e5c47a3e66f0c109f1a 100644 (file)
@@ -1350,6 +1350,31 @@ static int stmt_evaluate_nat(struct eval_ctx *ctx, struct stmt *stmt)
        return 0;
 }
 
+static int stmt_evaluate_masq(struct eval_ctx *ctx, struct stmt *stmt)
+{
+       struct proto_ctx *pctx = &ctx->pctx;
+
+       if (!pctx)
+               goto out;
+
+       switch (pctx->family) {
+       case AF_INET:
+               expr_set_context(&ctx->ectx, &ipaddr_type,
+                               4 * BITS_PER_BYTE);
+               break;
+       case AF_INET6:
+               expr_set_context(&ctx->ectx, &ip6addr_type,
+                                16 * BITS_PER_BYTE);
+               break;
+       default:
+               return stmt_error(ctx, stmt, "ip and ip6 support only");
+       }
+
+out:
+       stmt->flags |= STMT_F_TERMINAL;
+       return 0;
+}
+
 static int stmt_evaluate_ct(struct eval_ctx *ctx, struct stmt *stmt)
 {
        expr_set_context(&ctx->ectx, stmt->ct.tmpl->dtype,
@@ -1410,6 +1435,8 @@ int stmt_evaluate(struct eval_ctx *ctx, struct stmt *stmt)
                return stmt_evaluate_reject(ctx, stmt);
        case STMT_NAT:
                return stmt_evaluate_nat(ctx, stmt);
+       case STMT_MASQ:
+               return stmt_evaluate_masq(ctx, stmt);
        case STMT_QUEUE:
                return stmt_evaluate_queue(ctx, stmt);
        case STMT_CT:
index 4bb4697cf11c5ab67dc5bbf7f79813afb09d50b6..38618ee88caa0b7fb4130d705dc5fffe10b12c73 100644 (file)
@@ -568,6 +568,21 @@ static void netlink_parse_nat(struct netlink_parse_ctx *ctx,
        list_add_tail(&stmt->list, &ctx->rule->stmts);
 }
 
+static void netlink_parse_masq(struct netlink_parse_ctx *ctx,
+                              const struct location *loc,
+                              const struct nft_rule_expr *nle)
+{
+       struct stmt *stmt;
+
+       stmt = masq_stmt_alloc(loc);
+
+       if (nft_rule_expr_is_set(nle, NFT_EXPR_MASQ_FLAGS))
+               stmt->masq.flags = nft_rule_expr_get_u32(nle,
+                                                        NFT_EXPR_MASQ_FLAGS);
+
+       list_add_tail(&stmt->list, &ctx->rule->stmts);
+}
+
 static void netlink_parse_queue(struct netlink_parse_ctx *ctx,
                              const struct location *loc,
                              const struct nft_rule_expr *nle)
@@ -614,6 +629,7 @@ static const struct {
        { .name = "limit",      .parse = netlink_parse_limit },
        { .name = "reject",     .parse = netlink_parse_reject },
        { .name = "nat",        .parse = netlink_parse_nat },
+       { .name = "masq",       .parse = netlink_parse_masq },
        { .name = "queue",      .parse = netlink_parse_queue },
 };
 
index 895cfa995e4c34c85d1b3b0de48f1dd1f61c4360..62155cc3d453e4abfb2b6357c9798e24cd5a5aff 100644 (file)
@@ -688,6 +688,19 @@ static void netlink_gen_nat_stmt(struct netlink_linearize_ctx *ctx,
        nft_rule_add_expr(ctx->nlr, nle);
 }
 
+static void netlink_gen_masq_stmt(struct netlink_linearize_ctx *ctx,
+                                 const struct stmt *stmt)
+{
+       struct nft_rule_expr *nle;
+
+       nle = alloc_nft_expr("masq");
+       if (stmt->masq.flags != 0)
+               nft_rule_expr_set_u32(nle, NFT_EXPR_MASQ_FLAGS,
+                                     stmt->masq.flags);
+
+       nft_rule_add_expr(ctx->nlr, nle);
+}
+
 static void netlink_gen_queue_stmt(struct netlink_linearize_ctx *ctx,
                                 const struct stmt *stmt)
 {
@@ -752,6 +765,8 @@ static void netlink_gen_stmt(struct netlink_linearize_ctx *ctx,
                return netlink_gen_reject_stmt(ctx, stmt);
        case STMT_NAT:
                return netlink_gen_nat_stmt(ctx, stmt);
+       case STMT_MASQ:
+               return netlink_gen_masq_stmt(ctx, stmt);
        case STMT_QUEUE:
                return netlink_gen_queue_stmt(ctx, stmt);
        case STMT_CT:
index e813b258dde1a99ef014b918d3f2606f4354dc45..9e9a83935728f5ecb77645abf57bb8bc8837e0ed 100644 (file)
@@ -374,6 +374,7 @@ static void location_update(struct location *loc, struct location *rhs, int n)
 
 %token SNAT                    "snat"
 %token DNAT                    "dnat"
+%token MASQUERADE              "masquerade"
 %token RANDOM                  "random"
 %token RANDOM_FULLY            "random-fully"
 %token PERSISTENT              "persistent"
@@ -439,8 +440,8 @@ static void location_update(struct location *loc, struct location *rhs, int n)
 %type <val>                    time_unit
 %type <stmt>                   reject_stmt reject_stmt_alloc
 %destructor { stmt_free($$); } reject_stmt reject_stmt_alloc
-%type <stmt>                   nat_stmt nat_stmt_alloc
-%destructor { stmt_free($$); } nat_stmt nat_stmt_alloc
+%type <stmt>                   nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc
+%destructor { stmt_free($$); } nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc
 %type <val>                    nf_nat_flags nf_nat_flag
 %type <stmt>                   queue_stmt queue_stmt_alloc
 %destructor { stmt_free($$); } queue_stmt queue_stmt_alloc
@@ -1184,6 +1185,7 @@ stmt                      :       verdict_stmt
                        |       nat_stmt
                        |       queue_stmt
                        |       ct_stmt
+                       |       masq_stmt
                        ;
 
 verdict_stmt           :       verdict_expr
@@ -1407,6 +1409,17 @@ nat_stmt_args            :       expr
                        }
                        ;
 
+masq_stmt              :       masq_stmt_alloc
+                       |       masq_stmt_alloc nf_nat_flags
+                       {
+                               $$ = $1;
+                               $$->masq.flags = $2;
+                       }
+                       ;
+
+masq_stmt_alloc                :       MASQUERADE      { $$ = masq_stmt_alloc(&@$); }
+                       ;
+
 nf_nat_flags           :       nf_nat_flag
                        |       nf_nat_flags    COMMA   nf_nat_flag
                        {
index b5d7d4f9afeac95ec514a5b8ac017e8890e55b2b..32e59d98f2780912b73b02e47ddae143540a3725 100644 (file)
@@ -316,6 +316,7 @@ addrstring  ({macaddr}|{ip4addr}|{ip6addr})
 
 "snat"                 { return SNAT; }
 "dnat"                 { return DNAT; }
+"masquerade"           { return MASQUERADE; }
 "random"               { return RANDOM; }
 "random-fully"         { return RANDOM_FULLY; }
 "persistent"           { return PERSISTENT; }
index f1d83fcbe972c3d2089ecff053a1f4a370b22550..0ae616a83a536ae3450e15a1aba385ffa06f01aa 100644 (file)
@@ -330,3 +330,21 @@ struct stmt *nat_stmt_alloc(const struct location *loc)
 {
        return stmt_alloc(loc, &nat_stmt_ops);
 }
+
+static void masq_stmt_print(const struct stmt *stmt)
+{
+       printf("masquerade");
+
+       print_nf_nat_flags(stmt->masq.flags);
+}
+
+static const struct stmt_ops masq_stmt_ops = {
+       .type           = STMT_MASQ,
+       .name           = "masq",
+       .print          = masq_stmt_print,
+};
+
+struct stmt *masq_stmt_alloc(const struct location *loc)
+{
+       return stmt_alloc(loc, &masq_stmt_ops);
+}