]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/ipv4/netfilter/ip_nat_standalone.c
[SK_BUFF]: Introduce skb_set_transport_header
[linux-2.6-omap-h63xx.git] / net / ipv4 / netfilter / ip_nat_standalone.c
index 67e676783da9bd9cdf46fea59fcc287d5f9cf277..32f7bf661fc8a343db0434aad8b7db6733874616 100644 (file)
@@ -18,7 +18,6 @@
  *     - now capable of multiple expectations for one master
  * */
 
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/icmp.h>
 #include <linux/ip.h>
@@ -31,9 +30,6 @@
 #include <net/checksum.h>
 #include <linux/spinlock.h>
 
-#define ASSERT_READ_LOCK(x)
-#define ASSERT_WRITE_LOCK(x)
-
 #include <linux/netfilter_ipv4/ip_nat.h>
 #include <linux/netfilter_ipv4/ip_nat_rule.h>
 #include <linux/netfilter_ipv4/ip_nat_protocol.h>
@@ -41,7 +37,6 @@
 #include <linux/netfilter_ipv4/ip_nat_helper.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
 #include <linux/netfilter_ipv4/ip_conntrack_core.h>
-#include <linux/netfilter_ipv4/listhelp.h>
 
 #if 0
 #define DEBUGP printk
 #define DEBUGP(format, args...)
 #endif
 
-#define HOOKNAME(hooknum) ((hooknum) == NF_IP_POST_ROUTING ? "POST_ROUTING"  \
-                          : ((hooknum) == NF_IP_PRE_ROUTING ? "PRE_ROUTING" \
-                             : ((hooknum) == NF_IP_LOCAL_OUT ? "LOCAL_OUT"  \
-                                : ((hooknum) == NF_IP_LOCAL_IN ? "LOCAL_IN"  \
-                                   : "*ERROR*")))
-
 #ifdef CONFIG_XFRM
 static void nat_decode_session(struct sk_buff *skb, struct flowi *fl)
 {
@@ -92,7 +81,7 @@ static void nat_decode_session(struct sk_buff *skb, struct flowi *fl)
        }
 }
 #endif
-               
+
 static unsigned int
 ip_nat_fn(unsigned int hooknum,
          struct sk_buff **pskb,
@@ -108,14 +97,9 @@ ip_nat_fn(unsigned int hooknum,
 
        /* We never see fragments: conntrack defrags on pre-routing
           and local-out, and ip_nat_out protects post-routing. */
-       IP_NF_ASSERT(!((*pskb)->nh.iph->frag_off
+       IP_NF_ASSERT(!(ip_hdr(*pskb)->frag_off
                       & htons(IP_MF|IP_OFFSET)));
 
-       /* If we had a hardware checksum before, it's now invalid */
-       if ((*pskb)->ip_summed == CHECKSUM_HW)
-               if (skb_checksum_help(*pskb, (out == NULL)))
-                       return NF_DROP;
-
        ct = ip_conntrack_get(*pskb, &ctinfo);
        /* Can't track?  It's not due to stress, or conntrack would
           have dropped it.  Hence it's the user's responsibilty to
@@ -123,13 +107,12 @@ ip_nat_fn(unsigned int hooknum,
           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 ((*pskb)->nh.iph->protocol == IPPROTO_ICMP) {
+                  hash table yet).  We must not let this through, in
+                  case we're doing NAT to the same network. */
+               if (ip_hdr(*pskb)->protocol == IPPROTO_ICMP) {
                        struct icmphdr _hdr, *hp;
 
-                       hp = skb_header_pointer(*pskb,
-                                               (*pskb)->nh.iph->ihl*4,
+                       hp = skb_header_pointer(*pskb, ip_hdrlen(*pskb),
                                                sizeof(_hdr), &_hdr);
                        if (hp != NULL &&
                            hp->type == ICMP_REDIRECT)
@@ -145,9 +128,9 @@ ip_nat_fn(unsigned int hooknum,
        switch (ctinfo) {
        case IP_CT_RELATED:
        case IP_CT_RELATED+IP_CT_IS_REPLY:
-               if ((*pskb)->nh.iph->protocol == IPPROTO_ICMP) {
-                       if (!ip_nat_icmp_reply_translation(pskb, ct, maniptype,
-                                                          CTINFO2DIR(ctinfo)))
+               if (ip_hdr(*pskb)->protocol == IPPROTO_ICMP) {
+                       if (!ip_nat_icmp_reply_translation(ct, ctinfo,
+                                                          hooknum, pskb))
                                return NF_DROP;
                        else
                                return NF_ACCEPT;
@@ -164,7 +147,7 @@ ip_nat_fn(unsigned int hooknum,
                        if (unlikely(is_confirmed(ct)))
                                /* NAT module was loaded late */
                                ret = alloc_null_binding_confirmed(ct, info,
-                                                                  hooknum);
+                                                                  hooknum);
                        else if (hooknum == NF_IP_LOCAL_IN)
                                /* LOCAL_IN hook doesn't have a chain!  */
                                ret = alloc_null_binding(ct, info, hooknum);
@@ -195,17 +178,17 @@ 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 *))
+         struct sk_buff **pskb,
+         const struct net_device *in,
+         const struct net_device *out,
+         int (*okfn)(struct sk_buff *))
 {
        unsigned int ret;
-       u_int32_t daddr = (*pskb)->nh.iph->daddr;
+       __be32 daddr = ip_hdr(*pskb)->daddr;
 
        ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
        if (ret != NF_DROP && ret != NF_STOLEN
-           && daddr != (*pskb)->nh.iph->daddr) {
+           && daddr != ip_hdr(*pskb)->daddr) {
                dst_release((*pskb)->dst);
                (*pskb)->dst = NULL;
        }
@@ -227,7 +210,7 @@ ip_nat_out(unsigned int hooknum,
 
        /* root is playing with raw sockets. */
        if ((*pskb)->len < sizeof(struct iphdr)
-           || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
+           || ip_hdrlen(*pskb) < sizeof(struct iphdr))
                return NF_ACCEPT;
 
        ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
@@ -260,7 +243,7 @@ ip_nat_local_fn(unsigned int hooknum,
 
        /* root is playing with raw sockets. */
        if ((*pskb)->len < sizeof(struct iphdr)
-           || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
+           || ip_hdrlen(*pskb) < sizeof(struct iphdr))
                return NF_ACCEPT;
 
        ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
@@ -269,13 +252,17 @@ ip_nat_local_fn(unsigned int hooknum,
                enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
 
                if (ct->tuplehash[dir].tuple.dst.ip !=
-                   ct->tuplehash[!dir].tuple.src.ip
+                   ct->tuplehash[!dir].tuple.src.ip) {
+                       if (ip_route_me_harder(pskb, RTN_UNSPEC))
+                               ret = NF_DROP;
+               }
 #ifdef CONFIG_XFRM
-                   || ct->tuplehash[dir].tuple.dst.u.all !=
-                      ct->tuplehash[!dir].tuple.src.u.all
+               else if (ct->tuplehash[dir].tuple.dst.u.all !=
+                        ct->tuplehash[!dir].tuple.src.u.all)
+                       if (ip_xfrm_me_harder(pskb))
+                               ret = NF_DROP;
 #endif
-                   )
-                       return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
+
        }
        return ret;
 }
@@ -292,9 +279,9 @@ ip_nat_adjust(unsigned int hooknum,
 
        ct = ip_conntrack_get(*pskb, &ctinfo);
        if (ct && test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) {
-               DEBUGP("ip_nat_standalone: adjusting sequence number\n");
-               if (!ip_nat_seq_adjust(pskb, ct, ctinfo))
-                       return NF_DROP;
+               DEBUGP("ip_nat_standalone: adjusting sequence number\n");
+               if (!ip_nat_seq_adjust(pskb, ct, ctinfo))
+                       return NF_DROP;
        }
        return NF_ACCEPT;
 }