]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: add netmap support
authorPablo Neira Ayuso <pablo@netfilter.org>
Fri, 24 Apr 2020 19:56:51 +0000 (21:56 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 28 Apr 2020 15:32:35 +0000 (17:32 +0200)
This patch allows you to specify an interval of IP address in maps.

 table ip x {
        chain y {
                type nat hook postrouting priority srcnat; policy accept;
                snat ip prefix to ip saddr map { 10.141.11.0/24 : 192.168.2.0/24 }
        }
 }

The example above performs SNAT to packets that comes from
10.141.11.0/24 using the prefix 192.168.2.0/24, e.g. 10.141.11.4 is
mangled to 192.168.2.4.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/linux/netfilter/nf_nat.h
include/statement.h
src/netlink_delinearize.c
src/parser_bison.y
src/statement.c

index 4a95c0db14d4ffdd2030beba3d5572e462907f70..a64586e77b2401418c733c005e2ec281c9d4a486 100644 (file)
@@ -11,6 +11,7 @@
 #define NF_NAT_RANGE_PERSISTENT                        (1 << 3)
 #define NF_NAT_RANGE_PROTO_RANDOM_FULLY                (1 << 4)
 #define NF_NAT_RANGE_PROTO_OFFSET              (1 << 5)
+#define NF_NAT_RANGE_NETMAP                    (1 << 6)
 
 #define NF_NAT_RANGE_PROTO_RANDOM_ALL          \
        (NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PROTO_RANDOM_FULLY)
@@ -18,7 +19,8 @@
 #define NF_NAT_RANGE_MASK                                      \
        (NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED |  \
         NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PERSISTENT |  \
-        NF_NAT_RANGE_PROTO_RANDOM_FULLY | NF_NAT_RANGE_PROTO_OFFSET)
+        NF_NAT_RANGE_PROTO_RANDOM_FULLY | NF_NAT_RANGE_PROTO_OFFSET | \
+        NF_NAT_RANGE_NETMAP)
 
 struct nf_nat_ipv4_range {
        unsigned int                    flags;
index 8427f47e4071bf411ac1021c57cf23fe095f0bb6..01fe416c415a5ad1b406c992b7e2a196b3743633 100644 (file)
@@ -121,6 +121,7 @@ extern const char *nat_etype2str(enum nft_nat_etypes type);
 
 enum {
        STMT_NAT_F_INTERVAL     = (1 << 0),
+       STMT_NAT_F_PREFIX       = (1 << 1),
 };
 
 struct nat_stmt {
index f41223a8e24adb5cbc24302ce99ac67c2ee683ee..b039a1e3c7ac75dab6c5f263ab6ff360fc80692e 100644 (file)
@@ -15,6 +15,7 @@
 #include <limits.h>
 #include <linux/netfilter/nf_tables.h>
 #include <arpa/inet.h>
+#include <linux/netfilter/nf_nat.h>
 #include <linux/netfilter.h>
 #include <net/ethernet.h>
 #include <netlink.h>
@@ -1060,6 +1061,9 @@ static void netlink_parse_nat(struct netlink_parse_ctx *ctx,
        if (nftnl_expr_is_set(nle, NFTNL_EXPR_NAT_FLAGS))
                stmt->nat.flags = nftnl_expr_get_u32(nle, NFTNL_EXPR_NAT_FLAGS);
 
+       if (stmt->nat.flags & NF_NAT_RANGE_NETMAP)
+               stmt->nat.type_flags |= STMT_NAT_F_PREFIX;
+
        addr = NULL;
        reg1 = netlink_parse_register(nle, NFTNL_EXPR_NAT_REG_ADDR_MIN);
        if (reg1) {
index 731a5b3ecdf49592d8d060464579d83fa17bdde4..3b470cc63235d93f7985663e5890c3ea50e0b7c4 100644 (file)
@@ -3205,6 +3205,23 @@ nat_stmt_args            :       stmt_expr
                                $<stmt>0->nat.addr = $3;
                                $<stmt>0->nat.type_flags = STMT_NAT_F_INTERVAL;
                        }
+                       |       nf_key_proto PREFIX TO  stmt_expr
+                       {
+                               $<stmt>0->nat.family = $1;
+                               $<stmt>0->nat.addr = $4;
+                               $<stmt>0->nat.type_flags =
+                                               STMT_NAT_F_PREFIX |
+                                               STMT_NAT_F_INTERVAL;
+                               $<stmt>0->nat.flags |= NF_NAT_RANGE_NETMAP;
+                       }
+                       |       PREFIX TO       stmt_expr
+                       {
+                               $<stmt>0->nat.addr = $3;
+                               $<stmt>0->nat.type_flags =
+                                               STMT_NAT_F_PREFIX |
+                                               STMT_NAT_F_INTERVAL;
+                               $<stmt>0->nat.flags |= NF_NAT_RANGE_NETMAP;
+                       }
                        ;
 
 masq_stmt              :       masq_stmt_alloc         masq_stmt_args
index 5bbc054055bc3547a70b244f756a67de1d5c6333..8a1cd6e04f618a3a2cd94a1b8970fee657ca80f2 100644 (file)
@@ -609,6 +609,8 @@ static void nat_stmt_print(const struct stmt *stmt, struct output_ctx *octx)
 
                if (stmt->nat.ipportmap)
                        nft_print(octx, " addr . port");
+               else if (stmt->nat.type_flags & STMT_NAT_F_PREFIX)
+                       nft_print(octx, " prefix");
                else if (stmt->nat.type_flags & STMT_NAT_F_INTERVAL)
                        nft_print(octx, " interval");