linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / net / ipv4 / netfilter / ip_nat_standalone.c
index 67e6767..ab1f88f 100644 (file)
@@ -219,10 +219,8 @@ ip_nat_out(unsigned int hooknum,
           const struct net_device *out,
           int (*okfn)(struct sk_buff *))
 {
-#ifdef CONFIG_XFRM
        struct ip_conntrack *ct;
        enum ip_conntrack_info ctinfo;
-#endif
        unsigned int ret;
 
        /* root is playing with raw sockets. */
@@ -301,63 +299,69 @@ ip_nat_adjust(unsigned int hooknum,
 
 /* We must be after connection tracking and before packet filtering. */
 
-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,
-       },
+/* 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,
 };
 
-static int __init ip_nat_standalone_init(void)
+/* 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 int init_or_cleanup(int init)
 {
        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;
@@ -367,13 +371,50 @@ static int __init ip_nat_standalone_init(void)
                printk("ip_nat_init: can't setup rules.\n");
                goto cleanup_decode_session;
        }
-       ret = nf_register_hooks(ip_nat_ops, ARRAY_SIZE(ip_nat_ops));
+       ret = nf_register_hook(&ip_nat_in_ops);
        if (ret < 0) {
-               printk("ip_nat_init: can't register hooks.\n");
+               printk("ip_nat_init: can't register in hook.\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:
@@ -384,17 +425,17 @@ static int __init ip_nat_standalone_init(void)
        return ret;
 }
 
-static void __exit ip_nat_standalone_fini(void)
+static int __init init(void)
 {
-       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
+       return init_or_cleanup(1);
+}
+
+static void __exit fini(void)
+{
+       init_or_cleanup(0);
 }
 
-module_init(ip_nat_standalone_init);
-module_exit(ip_nat_standalone_fini);
+module_init(init);
+module_exit(fini);
 
 MODULE_LICENSE("GPL");