diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2005-01-16 22:01:26 -0800 |
---|---|---|
committer | David S. Miller <davem@nuts.davemloft.net> | 2005-01-16 22:01:26 -0800 |
commit | 8d5f3377d48c74df38990688f09e773887ba4eb5 (patch) | |
tree | 25465714cf5b26bd8ad9cddd402d6e42b6eb3c09 /net/ipv4/netfilter/ip_nat_rule.c | |
parent | cd79564003e1b16ebc4090d3a2055e30e08898fc (diff) | |
download | history-8d5f3377d48c74df38990688f09e773887ba4eb5.tar.gz |
[NETFILTER]: Remove manip array from conntrack entry
Original patch and multo bugfixes by Krisztian Kovacs.
Now NAT has been simplified, there is only one place to NAT each
packet. That means we can intuit what to do by looking at the
difference between this packet and the reply we expect, getting rid of
the manips[] array in the connection tracking structure, which is 72
bytes. Rework NAT to be based on 'change this packet to make src/dst
look like this tuple'.
1) Each protocol's manip_pkt takes a 'struct ip_conntrack_manip',
which is half (the source half) of a tuple. Hand the whole desired
tuple to the NAT code and have it use the 'maniptype' arg to decide
what part to copy.
2) Krisztian points out that we don't need the NAT lock to read the
NAT information (or the tuples) as they never change once set, and
while being set we have exclusive access. A lock is only needed to
deal with only remaining NAT list: the bysource hash.
3) We don't need to rehash for the bysource hash: it depends on the
incoming packet, which we can't change.
4) Many NAT functions only need the maniptype they are to perform, not
the actual hook, which makes the code clearer.
5) New status bits to indicate what NAT needs to be done. We can
always figure it out by inverting the tuple we expect in the other
direction and comparing it, but this is faster.
6) Rename 'do_bindings' to 'nat_packet'.
7) ICMP handing is vastly simplified: we unconditionally change to
look the way we want.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/netfilter/ip_nat_rule.c')
-rw-r--r-- | net/ipv4/netfilter/ip_nat_rule.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c index 80773588d8ad0..08d0fba85b85d 100644 --- a/net/ipv4/netfilter/ip_nat_rule.c +++ b/net/ipv4/netfilter/ip_nat_rule.c @@ -16,6 +16,7 @@ #include <linux/skbuff.h> #include <linux/proc_fs.h> #include <net/checksum.h> +#include <net/route.h> #include <linux/bitops.h> #define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock) @@ -120,6 +121,25 @@ static unsigned int ipt_snat_target(struct sk_buff **pskb, return ip_nat_setup_info(ct, &mr->range[0], hooknum); } +/* Before 2.6.11 we did implicit source NAT if required. Warn about change. */ +static void warn_if_extra_mangle(u32 dstip, u32 srcip) +{ + static int warned = 0; + struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dstip } } }; + struct rtable *rt; + + if (ip_route_output_key(&rt, &fl) != 0) + return; + + if (rt->rt_src != srcip && !warned) { + printk("NAT: no longer support implicit source local NAT\n"); + printk("NAT: packet src %u.%u.%u.%u -> dst %u.%u.%u.%u\n", + NIPQUAD(srcip), NIPQUAD(dstip)); + warned = 1; + } + ip_rt_put(rt); +} + static unsigned int ipt_dnat_target(struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, @@ -139,6 +159,11 @@ static unsigned int ipt_dnat_target(struct sk_buff **pskb, /* Connection must be valid and new. */ IP_NF_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)); + if (hooknum == NF_IP_LOCAL_OUT + && mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) + warn_if_extra_mangle((*pskb)->nh.iph->daddr, + mr->range[0].min_ip); + return ip_nat_setup_info(ct, &mr->range[0], hooknum); } |