]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: nat concatenation support with anonymous maps
authorPablo Neira Ayuso <pablo@netfilter.org>
Mon, 24 Feb 2020 12:28:34 +0000 (13:28 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 24 Feb 2020 18:18:45 +0000 (19:18 +0100)
This patch extends the parser to define the mapping datatypes, eg.

  ... dnat ip addr . port to ip saddr map { 1.1.1.1 : 2.2.2.2 . 30 }
  ... dnat ip addr . port to ip saddr map @y

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/evaluate.c
src/netlink_delinearize.c
src/parser_bison.y
src/scanner.l
src/statement.c

index 0afd0403d3a4c0453df0be341b0fef70df0a1ce0..2d4985c0d409bc2e1b6ab8e5960a0f07d69bef4c 100644 (file)
@@ -2853,15 +2853,32 @@ static int stmt_evaluate_nat_map(struct eval_ctx *ctx, struct stmt *stmt)
 {
        struct expr *one, *two, *data, *tmp;
        const struct datatype *dtype;
-       int err;
+       int addr_type, err;
 
-       dtype = get_addr_dtype(stmt->nat.family);
+       if (stmt->nat.ipportmap) {
+               switch (stmt->nat.family) {
+               case NFPROTO_IPV4:
+                       addr_type = TYPE_IPADDR;
+                       break;
+               case NFPROTO_IPV6:
+                       addr_type = TYPE_IP6ADDR;
+                       break;
+               default:
+                       return -1;
+               }
+               dtype = concat_type_alloc((addr_type << TYPE_BITS) |
+                                          TYPE_INET_SERVICE);
+       } else {
+               dtype = get_addr_dtype(stmt->nat.family);
+       }
 
        expr_set_context(&ctx->ectx, dtype, dtype->size);
        if (expr_evaluate(ctx, &stmt->nat.addr))
                return -1;
 
        data = stmt->nat.addr->mappings->set->data;
+       datatype_set(data, dtype);
+
        if (expr_ops(data)->type != EXPR_CONCAT)
                return __stmt_evaluate_arg(ctx, stmt, dtype, dtype->size,
                                           BYTEORDER_BIG_ENDIAN,
@@ -2875,6 +2892,7 @@ static int stmt_evaluate_nat_map(struct eval_ctx *ctx, struct stmt *stmt)
                                           BYTEORDER_BIG_ENDIAN,
                                           &stmt->nat.addr);
 
+       dtype = get_addr_dtype(stmt->nat.family);
        tmp = one;
        err = __stmt_evaluate_arg(ctx, stmt, dtype, dtype->size,
                                  BYTEORDER_BIG_ENDIAN,
@@ -2891,7 +2909,6 @@ static int stmt_evaluate_nat_map(struct eval_ctx *ctx, struct stmt *stmt)
        if (tmp != two)
                BUG("Internal error: Unexpected alteration of l4 expression");
 
-       stmt->nat.ipportmap = true;
        return err;
 }
 
index 6203a53c61540516ddd82ba40d460941475aa1ad..0058e2cfe42af7091b32fc082d91e5eba128489e 100644 (file)
@@ -1065,6 +1065,7 @@ static void netlink_parse_nat(struct netlink_parse_ctx *ctx,
        }
 
        if (is_nat_proto_map(addr, family)) {
+               stmt->nat.family = family;
                stmt->nat.ipportmap = true;
                ctx->stmt = stmt;
                return;
index fd00b40a104af0a11af4698cd6aae43722dc095c..4c27fcc635dcb3bca3131e0b2a10a048257a53cc 100644 (file)
@@ -373,6 +373,7 @@ int nft_lex(void *, void *, void *);
 %token FLAGS                   "flags"
 %token CPI                     "cpi"
 
+%token PORT                    "port"
 %token UDP                     "udp"
 %token SPORT                   "sport"
 %token DPORT                   "dport"
@@ -3141,6 +3142,12 @@ nat_stmt_args            :       stmt_expr
                        {
                                $<stmt>0->nat.flags = $2;
                        }
+                       |       nf_key_proto ADDR DOT   PORT    TO      stmt_expr
+                       {
+                               $<stmt>0->nat.family = $1;
+                               $<stmt>0->nat.addr = $6;
+                               $<stmt>0->nat.ipportmap = true;
+                       }
                        ;
 
 masq_stmt              :       masq_stmt_alloc         masq_stmt_args
index 3932883b9adee8039f95c8bc6458b4512dd7f418..45699c85d7d0d68fe0eda6ab05adb84ec73ec62d 100644 (file)
@@ -471,6 +471,7 @@ addrstring  ({macaddr}|{ip4addr}|{ip6addr})
 "udplite"              { return UDPLITE; }
 "sport"                        { return SPORT; }
 "dport"                        { return DPORT; }
+"port"                 { return PORT; }
 
 "tcp"                  { return TCP; }
 "ackseq"               { return ACKSEQ; }
index be35bceff19abc2c542f83e9c7446490711d12e2..182edac8f2ec5151b7978a49505ac9cc69e72f88 100644 (file)
@@ -607,6 +607,9 @@ static void nat_stmt_print(const struct stmt *stmt, struct output_ctx *octx)
                        break;
                }
 
+               if (stmt->nat.ipportmap)
+                       nft_print(octx, " addr . port");
+
                nft_print(octx, " to");
        }