summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2009-04-16 18:33:01 +0200
committerPatrick McHardy <kaber@trash.net>2009-04-16 18:33:01 +0200
commit98d500d66cb7940747b424b245fc6a51ecfbf005 (patch)
tree0c5d745901be7aab151071829a8dc6fac193fb30
parentnetfilter: nf_conntrack: fix crash when unloading helpers (diff)
downloadlinux-98d500d66cb7940747b424b245fc6a51ecfbf005.tar.xz
linux-98d500d66cb7940747b424b245fc6a51ecfbf005.zip
netfilter: nf_nat: add support for persistent mappings
The removal of the SAME target accidentally removed one feature that is not available from the normal NAT targets so far, having multi-range mappings that use the same mapping for each connection from a single client. The current behaviour is to choose the address from the range based on source and destination IP, which breaks when communicating with sites having multiple addresses that require all connections to originate from the same IP address. Introduce a IP_NAT_RANGE_PERSISTENT option that controls whether the destination address is taken into account for selecting addresses. http://bugzilla.kernel.org/show_bug.cgi?id=12954 Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r--include/net/netfilter/nf_nat.h1
-rw-r--r--net/ipv4/netfilter/nf_nat_core.c3
2 files changed, 3 insertions, 1 deletions
diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h
index 9dc1039ff78b..8df0b7f7fc6e 100644
--- a/include/net/netfilter/nf_nat.h
+++ b/include/net/netfilter/nf_nat.h
@@ -18,6 +18,7 @@ enum nf_nat_manip_type
#define IP_NAT_RANGE_MAP_IPS 1
#define IP_NAT_RANGE_PROTO_SPECIFIED 2
#define IP_NAT_RANGE_PROTO_RANDOM 4
+#define IP_NAT_RANGE_PERSISTENT 8
/* NAT sequence number modifications */
struct nf_nat_seq {
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index fe65187810f0..3229e0a81ba6 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -211,7 +211,8 @@ find_best_ips_proto(struct nf_conntrack_tuple *tuple,
minip = ntohl(range->min_ip);
maxip = ntohl(range->max_ip);
j = jhash_2words((__force u32)tuple->src.u3.ip,
- (__force u32)tuple->dst.u3.ip, 0);
+ range->flags & IP_NAT_RANGE_PERSISTENT ?
+ (__force u32)tuple->dst.u3.ip : 0, 0);
j = ((u64)j * (maxip - minip + 1)) >> 32;
*var_ipp = htonl(minip + j);
}