Merge branch 'misc' of master.kernel.org:/pub/scm/linux/kernel/git/galak/powerpc...
[pandora-kernel.git] / net / ipv4 / netfilter / ip_nat_standalone.c
index 92c5499..8f760b2 100644 (file)
@@ -200,20 +200,14 @@ ip_nat_in(unsigned int hooknum,
           const struct net_device *out,
           int (*okfn)(struct sk_buff *))
 {
-       struct ip_conntrack *ct;
-       enum ip_conntrack_info ctinfo;
        unsigned int ret;
+       u_int32_t daddr = (*pskb)->nh.iph->daddr;
 
        ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
        if (ret != NF_DROP && ret != NF_STOLEN
-           && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) {
-               enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
-
-               if (ct->tuplehash[dir].tuple.dst.ip !=
-                   ct->tuplehash[!dir].tuple.src.ip) {
-                       dst_release((*pskb)->dst);
-                       (*pskb)->dst = NULL;
-               }
+           && daddr != (*pskb)->nh.iph->daddr) {
+               dst_release((*pskb)->dst);
+               (*pskb)->dst = NULL;
        }
        return ret;
 }
@@ -235,19 +229,19 @@ ip_nat_out(unsigned int hooknum,
                return NF_ACCEPT;
 
        ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
+#ifdef CONFIG_XFRM
        if (ret != NF_DROP && ret != NF_STOLEN
            && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) {
                enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
 
                if (ct->tuplehash[dir].tuple.src.ip !=
                    ct->tuplehash[!dir].tuple.dst.ip
-#ifdef CONFIG_XFRM
                    || ct->tuplehash[dir].tuple.src.u.all !=
                       ct->tuplehash[!dir].tuple.dst.u.all
-#endif
                    )
-                       return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
+                       return ip_xfrm_me_harder(pskb) == 0 ? ret : NF_DROP;
        }
+#endif
        return ret;
 }
 
@@ -276,7 +270,7 @@ ip_nat_local_fn(unsigned int hooknum,
                    ct->tuplehash[!dir].tuple.src.ip
 #ifdef CONFIG_XFRM
                    || ct->tuplehash[dir].tuple.dst.u.all !=
-                      ct->tuplehash[dir].tuple.src.u.all
+                      ct->tuplehash[!dir].tuple.src.u.all
 #endif
                    )
                        return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
@@ -305,69 +299,63 @@ ip_nat_adjust(unsigned int hooknum,
 
 /* 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_in,
-       .owner          = THIS_MODULE,
-       .pf             = PF_INET,
-       .hooknum        = NF_IP_PRE_ROUTING,
-       .priority       = NF_IP_PRI_NAT_DST,
-};
-
-/* After packet filtering, change source */
-static struct nf_hook_ops ip_nat_out_ops = {
-       .hook           = ip_nat_out,
-       .owner          = THIS_MODULE,
-       .pf             = PF_INET,
-       .hooknum        = NF_IP_POST_ROUTING,
-       .priority       = NF_IP_PRI_NAT_SRC,
-};
-
-/* After conntrack, adjust sequence number */
-static struct nf_hook_ops ip_nat_adjust_out_ops = {
-       .hook           = ip_nat_adjust,
-       .owner          = THIS_MODULE,
-       .pf             = PF_INET,
-       .hooknum        = NF_IP_POST_ROUTING,
-       .priority       = NF_IP_PRI_NAT_SEQ_ADJUST,
-};
-
-/* Before packet filtering, change destination */
-static struct nf_hook_ops ip_nat_local_out_ops = {
-       .hook           = ip_nat_local_fn,
-       .owner          = THIS_MODULE,
-       .pf             = PF_INET,
-       .hooknum        = NF_IP_LOCAL_OUT,
-       .priority       = NF_IP_PRI_NAT_DST,
-};
-
-/* After packet filtering, change source for reply packets of LOCAL_OUT DNAT */
-static struct nf_hook_ops ip_nat_local_in_ops = {
-       .hook           = ip_nat_fn,
-       .owner          = THIS_MODULE,
-       .pf             = PF_INET,
-       .hooknum        = NF_IP_LOCAL_IN,
-       .priority       = NF_IP_PRI_NAT_SRC,
-};
-
-/* After conntrack, adjust sequence number */
-static struct nf_hook_ops ip_nat_adjust_in_ops = {
-       .hook           = ip_nat_adjust,
-       .owner          = THIS_MODULE,
-       .pf             = PF_INET,
-       .hooknum        = NF_IP_LOCAL_IN,
-       .priority       = NF_IP_PRI_NAT_SEQ_ADJUST,
+static struct nf_hook_ops ip_nat_ops[] = {
+       /* Before packet filtering, change destination */
+       {
+               .hook           = ip_nat_in,
+               .owner          = THIS_MODULE,
+               .pf             = PF_INET,
+               .hooknum        = NF_IP_PRE_ROUTING,
+               .priority       = NF_IP_PRI_NAT_DST,
+       },
+       /* After packet filtering, change source */
+       {
+               .hook           = ip_nat_out,
+               .owner          = THIS_MODULE,
+               .pf             = PF_INET,
+               .hooknum        = NF_IP_POST_ROUTING,
+               .priority       = NF_IP_PRI_NAT_SRC,
+       },
+       /* After conntrack, adjust sequence number */
+       {
+               .hook           = ip_nat_adjust,
+               .owner          = THIS_MODULE,
+               .pf             = PF_INET,
+               .hooknum        = NF_IP_POST_ROUTING,
+               .priority       = NF_IP_PRI_NAT_SEQ_ADJUST,
+       },
+       /* Before packet filtering, change destination */
+       {
+               .hook           = ip_nat_local_fn,
+               .owner          = THIS_MODULE,
+               .pf             = PF_INET,
+               .hooknum        = NF_IP_LOCAL_OUT,
+               .priority       = NF_IP_PRI_NAT_DST,
+       },
+       /* After packet filtering, change source */
+       {
+               .hook           = ip_nat_fn,
+               .owner          = THIS_MODULE,
+               .pf             = PF_INET,
+               .hooknum        = NF_IP_LOCAL_IN,
+               .priority       = NF_IP_PRI_NAT_SRC,
+       },
+       /* After conntrack, adjust sequence number */
+       {
+               .hook           = ip_nat_adjust,
+               .owner          = THIS_MODULE,
+               .pf             = PF_INET,
+               .hooknum        = NF_IP_LOCAL_IN,
+               .priority       = NF_IP_PRI_NAT_SEQ_ADJUST,
+       },
 };
 
-
-static int init_or_cleanup(int init)
+static int __init ip_nat_standalone_init(void)
 {
        int ret = 0;
 
        need_conntrack();
 
-       if (!init) goto cleanup;
-
 #ifdef CONFIG_XFRM
        BUG_ON(ip_nat_decode_session != NULL);
        ip_nat_decode_session = nat_decode_session;
@@ -377,50 +365,13 @@ static int init_or_cleanup(int init)
                printk("ip_nat_init: can't setup rules.\n");
                goto cleanup_decode_session;
        }
-       ret = nf_register_hook(&ip_nat_in_ops);
+       ret = nf_register_hooks(ip_nat_ops, ARRAY_SIZE(ip_nat_ops));
        if (ret < 0) {
-               printk("ip_nat_init: can't register in hook.\n");
+               printk("ip_nat_init: can't register hooks.\n");
                goto cleanup_rule_init;
        }
-       ret = nf_register_hook(&ip_nat_out_ops);
-       if (ret < 0) {
-               printk("ip_nat_init: can't register out hook.\n");
-               goto cleanup_inops;
-       }
-       ret = nf_register_hook(&ip_nat_adjust_in_ops);
-       if (ret < 0) {
-               printk("ip_nat_init: can't register adjust in hook.\n");
-               goto cleanup_outops;
-       }
-       ret = nf_register_hook(&ip_nat_adjust_out_ops);
-       if (ret < 0) {
-               printk("ip_nat_init: can't register adjust out hook.\n");
-               goto cleanup_adjustin_ops;
-       }
-       ret = nf_register_hook(&ip_nat_local_out_ops);
-       if (ret < 0) {
-               printk("ip_nat_init: can't register local out hook.\n");
-               goto cleanup_adjustout_ops;;
-       }
-       ret = nf_register_hook(&ip_nat_local_in_ops);
-       if (ret < 0) {
-               printk("ip_nat_init: can't register local in hook.\n");
-               goto cleanup_localoutops;
-       }
        return ret;
 
- cleanup:
-       nf_unregister_hook(&ip_nat_local_in_ops);
- cleanup_localoutops:
-       nf_unregister_hook(&ip_nat_local_out_ops);
- cleanup_adjustout_ops:
-       nf_unregister_hook(&ip_nat_adjust_out_ops);
- cleanup_adjustin_ops:
-       nf_unregister_hook(&ip_nat_adjust_in_ops);
- cleanup_outops:
-       nf_unregister_hook(&ip_nat_out_ops);
- cleanup_inops:
-       nf_unregister_hook(&ip_nat_in_ops);
  cleanup_rule_init:
        ip_nat_rule_cleanup();
  cleanup_decode_session:
@@ -431,17 +382,17 @@ static int init_or_cleanup(int init)
        return ret;
 }
 
-static int __init init(void)
-{
-       return init_or_cleanup(1);
-}
-
-static void __exit fini(void)
+static void __exit ip_nat_standalone_fini(void)
 {
-       init_or_cleanup(0);
+       nf_unregister_hooks(ip_nat_ops, ARRAY_SIZE(ip_nat_ops));
+       ip_nat_rule_cleanup();
+#ifdef CONFIG_XFRM
+       ip_nat_decode_session = NULL;
+       synchronize_net();
+#endif
 }
 
-module_init(init);
-module_exit(fini);
+module_init(ip_nat_standalone_init);
+module_exit(ip_nat_standalone_fini);
 
 MODULE_LICENSE("GPL");