- patches.fixes/patch-2.6.11-rc1: 2.6.11-rc1.
[linux-flexiantxendom0-3.2.10.git] / net / ipv4 / netfilter / ip_nat_standalone.c
index 71bd2e0..0ef8eff 100644 (file)
@@ -128,16 +128,7 @@ ip_nat_fn(unsigned int hooknum,
                WRITE_LOCK(&ip_nat_lock);
                /* Seen it before?  This can happen for loopback, retrans,
                   or local packets.. */
-               if (!(info->initialized & (1 << maniptype))
-#ifndef CONFIG_IP_NF_NAT_LOCAL
-                   /* If this session has already been confirmed we must not
-                    * touch it again even if there is no mapping set up.
-                    * Can only happen on local->local traffic with
-                    * CONFIG_IP_NF_NAT_LOCAL disabled.
-                    */
-                   && !(ct->status & IPS_CONFIRMED)
-#endif
-                   ) {
+               if (!(info->initialized & (1 << maniptype))) {
                        unsigned int ret;
 
                        if (ct->master
@@ -146,15 +137,14 @@ ip_nat_fn(unsigned int hooknum,
                                ret = call_expect(master_ct(ct), pskb, 
                                                  hooknum, ct, info);
                        } else {
-#ifdef CONFIG_IP_NF_NAT_LOCAL
                                /* LOCAL_IN hook doesn't have a chain!  */
                                if (hooknum == NF_IP_LOCAL_IN)
                                        ret = alloc_null_binding(ct, info,
                                                                 hooknum);
                                else
-#endif
-                               ret = ip_nat_rule_find(pskb, hooknum, in, out,
-                                                      ct, info);
+                                       ret = ip_nat_rule_find(pskb, hooknum,
+                                                              in, out, ct,
+                                                              info);
                        }
 
                        if (ret != NF_ACCEPT) {
@@ -180,6 +170,29 @@ ip_nat_fn(unsigned int hooknum,
 }
 
 static unsigned int
+ip_nat_in(unsigned int hooknum,
+          struct sk_buff **pskb,
+          const struct net_device *in,
+          const struct net_device *out,
+          int (*okfn)(struct sk_buff *))
+{
+       u_int32_t saddr, daddr;
+       unsigned int ret;
+
+       saddr = (*pskb)->nh.iph->saddr;
+       daddr = (*pskb)->nh.iph->daddr;
+
+       ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
+       if (ret != NF_DROP && ret != NF_STOLEN
+           && ((*pskb)->nh.iph->saddr != saddr
+               || (*pskb)->nh.iph->daddr != daddr)) {
+               dst_release((*pskb)->dst);
+               (*pskb)->dst = NULL;
+       }
+       return ret;
+}
+
+static unsigned int
 ip_nat_out(unsigned int hooknum,
           struct sk_buff **pskb,
           const struct net_device *in,
@@ -211,7 +224,6 @@ ip_nat_out(unsigned int hooknum,
        return ip_nat_fn(hooknum, pskb, in, out, okfn);
 }
 
-#ifdef CONFIG_IP_NF_NAT_LOCAL
 static unsigned int
 ip_nat_local_fn(unsigned int hooknum,
                struct sk_buff **pskb,
@@ -237,13 +249,12 @@ ip_nat_local_fn(unsigned int hooknum,
                return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
        return ret;
 }
-#endif
 
 /* We must be after connection tracking and before packet filtering. */
 
 /* Before packet filtering, change destination */
 static struct nf_hook_ops ip_nat_in_ops = {
-       .hook           = ip_nat_fn,
+       .hook           = ip_nat_in,
        .owner          = THIS_MODULE,
        .pf             = PF_INET,
        .hooknum        = NF_IP_PRE_ROUTING,
@@ -259,7 +270,6 @@ static struct nf_hook_ops ip_nat_out_ops = {
        .priority       = NF_IP_PRI_NAT_SRC,
 };
 
-#ifdef CONFIG_IP_NF_NAT_LOCAL
 /* Before packet filtering, change destination */
 static struct nf_hook_ops ip_nat_local_out_ops = {
        .hook           = ip_nat_local_fn,
@@ -277,7 +287,6 @@ static struct nf_hook_ops ip_nat_local_in_ops = {
        .hooknum        = NF_IP_LOCAL_IN,
        .priority       = NF_IP_PRI_NAT_SRC,
 };
-#endif
 
 /* Protocol registration. */
 int ip_nat_protocol_register(struct ip_nat_protocol *proto)
@@ -334,7 +343,6 @@ static int init_or_cleanup(int init)
                printk("ip_nat_init: can't register out hook.\n");
                goto cleanup_inops;
        }
-#ifdef CONFIG_IP_NF_NAT_LOCAL
        ret = nf_register_hook(&ip_nat_local_out_ops);
        if (ret < 0) {
                printk("ip_nat_init: can't register local out hook.\n");
@@ -345,16 +353,13 @@ static int init_or_cleanup(int init)
                printk("ip_nat_init: can't register local in hook.\n");
                goto cleanup_localoutops;
        }
-#endif
        return ret;
 
  cleanup:
-#ifdef CONFIG_IP_NF_NAT_LOCAL
        nf_unregister_hook(&ip_nat_local_in_ops);
  cleanup_localoutops:
        nf_unregister_hook(&ip_nat_local_out_ops);
  cleanup_outops:
-#endif
        nf_unregister_hook(&ip_nat_out_ops);
  cleanup_inops:
        nf_unregister_hook(&ip_nat_in_ops);