net: skb->dst accessors
[pandora-kernel.git] / net / ipv4 / netfilter / nf_nat_standalone.c
index 7db76ea..5567bd0 100644 (file)
@@ -30,8 +30,8 @@
 #ifdef CONFIG_XFRM
 static void nat_decode_session(struct sk_buff *skb, struct flowi *fl)
 {
-       struct nf_conn *ct;
-       struct nf_conntrack_tuple *t;
+       const struct nf_conn *ct;
+       const struct nf_conntrack_tuple *t;
        enum ip_conntrack_info ctinfo;
        enum ip_conntrack_dir dir;
        unsigned long statusbit;
@@ -50,7 +50,10 @@ static void nat_decode_session(struct sk_buff *skb, struct flowi *fl)
        if (ct->status & statusbit) {
                fl->fl4_dst = t->dst.u3.ip;
                if (t->dst.protonum == IPPROTO_TCP ||
-                   t->dst.protonum == IPPROTO_UDP)
+                   t->dst.protonum == IPPROTO_UDP ||
+                   t->dst.protonum == IPPROTO_UDPLITE ||
+                   t->dst.protonum == IPPROTO_DCCP ||
+                   t->dst.protonum == IPPROTO_SCTP)
                        fl->fl_ip_dport = t->dst.u.tcp.port;
        }
 
@@ -59,7 +62,10 @@ static void nat_decode_session(struct sk_buff *skb, struct flowi *fl)
        if (ct->status & statusbit) {
                fl->fl4_src = t->src.u3.ip;
                if (t->dst.protonum == IPPROTO_TCP ||
-                   t->dst.protonum == IPPROTO_UDP)
+                   t->dst.protonum == IPPROTO_UDP ||
+                   t->dst.protonum == IPPROTO_UDPLITE ||
+                   t->dst.protonum == IPPROTO_DCCP ||
+                   t->dst.protonum == IPPROTO_SCTP)
                        fl->fl_ip_sport = t->src.u.tcp.port;
        }
 }
@@ -87,21 +93,8 @@ nf_nat_fn(unsigned int hooknum,
           have dropped it.  Hence it's the user's responsibilty to
           packet filter it out, or implement conntrack/NAT for that
           protocol. 8) --RR */
-       if (!ct) {
-               /* Exception: ICMP redirect to new connection (not in
-                  hash table yet).  We must not let this through, in
-                  case we're doing NAT to the same network. */
-               if (ip_hdr(skb)->protocol == IPPROTO_ICMP) {
-                       struct icmphdr _hdr, *hp;
-
-                       hp = skb_header_pointer(skb, ip_hdrlen(skb),
-                                               sizeof(_hdr), &_hdr);
-                       if (hp != NULL &&
-                           hp->type == ICMP_REDIRECT)
-                               return NF_DROP;
-               }
+       if (!ct)
                return NF_ACCEPT;
-       }
 
        /* Don't try to NAT if this packet is not conntracked */
        if (ct == &nf_conntrack_untracked)
@@ -109,6 +102,9 @@ nf_nat_fn(unsigned int hooknum,
 
        nat = nfct_nat(ct);
        if (!nat) {
+               /* NAT module was loaded late. */
+               if (nf_ct_is_confirmed(ct))
+                       return NF_ACCEPT;
                nat = nf_ct_ext_add(ct, NF_CT_EXT_NAT, GFP_ATOMIC);
                if (nat == NULL) {
                        pr_debug("failed to add NAT extension\n");
@@ -134,10 +130,7 @@ nf_nat_fn(unsigned int hooknum,
                if (!nf_nat_initialized(ct, maniptype)) {
                        unsigned int ret;
 
-                       if (unlikely(nf_ct_is_confirmed(ct)))
-                               /* NAT module was loaded late */
-                               ret = alloc_null_binding_confirmed(ct, hooknum);
-                       else if (hooknum == NF_IP_LOCAL_IN)
+                       if (hooknum == NF_INET_LOCAL_IN)
                                /* LOCAL_IN hook doesn't have a chain!  */
                                ret = alloc_null_binding(ct, hooknum);
                        else
@@ -174,10 +167,9 @@ nf_nat_in(unsigned int hooknum,
 
        ret = nf_nat_fn(hooknum, skb, in, out, okfn);
        if (ret != NF_DROP && ret != NF_STOLEN &&
-           daddr != ip_hdr(skb)->daddr) {
-               dst_release(skb->dst);
-               skb->dst = NULL;
-       }
+           daddr != ip_hdr(skb)->daddr)
+               skb_dst_drop(skb);
+
        return ret;
 }
 
@@ -189,7 +181,7 @@ nf_nat_out(unsigned int hooknum,
           int (*okfn)(struct sk_buff *))
 {
 #ifdef CONFIG_XFRM
-       struct nf_conn *ct;
+       const struct nf_conn *ct;
        enum ip_conntrack_info ctinfo;
 #endif
        unsigned int ret;
@@ -223,7 +215,7 @@ nf_nat_local_fn(unsigned int hooknum,
                const struct net_device *out,
                int (*okfn)(struct sk_buff *))
 {
-       struct nf_conn *ct;
+       const struct nf_conn *ct;
        enum ip_conntrack_info ctinfo;
        unsigned int ret;
 
@@ -252,34 +244,15 @@ nf_nat_local_fn(unsigned int hooknum,
        return ret;
 }
 
-static unsigned int
-nf_nat_adjust(unsigned int hooknum,
-             struct sk_buff *skb,
-             const struct net_device *in,
-             const struct net_device *out,
-             int (*okfn)(struct sk_buff *))
-{
-       struct nf_conn *ct;
-       enum ip_conntrack_info ctinfo;
-
-       ct = nf_ct_get(skb, &ctinfo);
-       if (ct && test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) {
-               pr_debug("nf_nat_standalone: adjusting sequence number\n");
-               if (!nf_nat_seq_adjust(skb, ct, ctinfo))
-                       return NF_DROP;
-       }
-       return NF_ACCEPT;
-}
-
 /* We must be after connection tracking and before packet filtering. */
 
-static struct nf_hook_ops nf_nat_ops[] = {
+static struct nf_hook_ops nf_nat_ops[] __read_mostly = {
        /* Before packet filtering, change destination */
        {
                .hook           = nf_nat_in,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_PRE_ROUTING,
+               .hooknum        = NF_INET_PRE_ROUTING,
                .priority       = NF_IP_PRI_NAT_DST,
        },
        /* After packet filtering, change source */
@@ -287,23 +260,15 @@ static struct nf_hook_ops nf_nat_ops[] = {
                .hook           = nf_nat_out,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_POST_ROUTING,
+               .hooknum        = NF_INET_POST_ROUTING,
                .priority       = NF_IP_PRI_NAT_SRC,
        },
-       /* After conntrack, adjust sequence number */
-       {
-               .hook           = nf_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           = nf_nat_local_fn,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_LOCAL_OUT,
+               .hooknum        = NF_INET_LOCAL_OUT,
                .priority       = NF_IP_PRI_NAT_DST,
        },
        /* After packet filtering, change source */
@@ -311,17 +276,9 @@ static struct nf_hook_ops nf_nat_ops[] = {
                .hook           = nf_nat_fn,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_LOCAL_IN,
+               .hooknum        = NF_INET_LOCAL_IN,
                .priority       = NF_IP_PRI_NAT_SRC,
        },
-       /* After conntrack, adjust sequence number */
-       {
-               .hook           = nf_nat_adjust,
-               .owner          = THIS_MODULE,
-               .pf             = PF_INET,
-               .hooknum        = NF_IP_LOCAL_IN,
-               .priority       = NF_IP_PRI_NAT_SEQ_ADJUST,
-       },
 };
 
 static int __init nf_nat_standalone_init(void)
@@ -332,7 +289,7 @@ static int __init nf_nat_standalone_init(void)
 
 #ifdef CONFIG_XFRM
        BUG_ON(ip_nat_decode_session != NULL);
-       ip_nat_decode_session = nat_decode_session;
+       rcu_assign_pointer(ip_nat_decode_session, nat_decode_session);
 #endif
        ret = nf_nat_rule_init();
        if (ret < 0) {
@@ -350,7 +307,7 @@ static int __init nf_nat_standalone_init(void)
        nf_nat_rule_cleanup();
  cleanup_decode_session:
 #ifdef CONFIG_XFRM
-       ip_nat_decode_session = NULL;
+       rcu_assign_pointer(ip_nat_decode_session, NULL);
        synchronize_net();
 #endif
        return ret;
@@ -361,7 +318,7 @@ static void __exit nf_nat_standalone_fini(void)
        nf_unregister_hooks(nf_nat_ops, ARRAY_SIZE(nf_nat_ops));
        nf_nat_rule_cleanup();
 #ifdef CONFIG_XFRM
-       ip_nat_decode_session = NULL;
+       rcu_assign_pointer(ip_nat_decode_session, NULL);
        synchronize_net();
 #endif
        /* Conntrack caches are unregistered in nf_conntrack_cleanup */