Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[pandora-kernel.git] / net / ipv4 / ip_input.c
index 48e4ddc..18d7fad 100644 (file)
 #include <linux/sockios.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 
  *     SNMP management statistics
  */
 
-DEFINE_SNMP_STAT(struct ipstats_mib, ip_statistics);
+DEFINE_SNMP_STAT(struct ipstats_mib, ip_statistics) __read_mostly;
 
 /*
  *     Process Router Attention IP option
@@ -184,7 +185,6 @@ int ip_call_ra_chain(struct sk_buff *skb)
                                        raw_rcv(last, skb2);
                        }
                        last = sk;
-                       nf_reset(skb);
                }
        }
 
@@ -203,10 +203,6 @@ static inline int ip_local_deliver_finish(struct sk_buff *skb)
 
        __skb_pull(skb, ihl);
 
-       /* Free reference early: we don't need it any more, and it may
-           hold ip_conntrack module loaded indefinitely. */
-       nf_reset(skb);
-
         /* Point into the IP datagram, just past the header. */
         skb->h.raw = skb->data;
 
@@ -231,10 +227,12 @@ static inline int ip_local_deliver_finish(struct sk_buff *skb)
                if ((ipprot = rcu_dereference(inet_protos[hash])) != NULL) {
                        int ret;
 
-                       if (!ipprot->no_policy &&
-                           !xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
-                               kfree_skb(skb);
-                               goto out;
+                       if (!ipprot->no_policy) {
+                               if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
+                                       kfree_skb(skb);
+                                       goto out;
+                               }
+                               nf_reset(skb);
                        }
                        ret = ipprot->handler(skb);
                        if (ret < 0) {
@@ -333,16 +331,16 @@ drop:
 
 static inline int ip_rcv_finish(struct sk_buff *skb)
 {
-       struct net_device *dev = skb->dev;
        struct iphdr *iph = skb->nh.iph;
-       int err;
 
        /*
         *      Initialise the virtual path cache for the packet. It describes
         *      how the packet travels inside Linux networking.
         */ 
-       if (skb->dst == NULL) {
-               if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) {
+       if (likely(skb->dst == NULL)) {
+               int err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos,
+                                        skb->dev);
+               if (unlikely(err)) {
                        if (err == -EHOSTUNREACH)
                                IP_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
                        goto drop; 
@@ -350,7 +348,7 @@ static inline int ip_rcv_finish(struct sk_buff *skb)
        }
 
 #ifdef CONFIG_NET_CLS_ROUTE
-       if (skb->dst->tclassid) {
+       if (unlikely(skb->dst->tclassid)) {
                struct ip_rt_acct *st = ip_rt_acct + 256*smp_processor_id();
                u32 idx = skb->dst->tclassid;
                st[idx&0xFF].o_packets++;
@@ -442,5 +440,4 @@ out:
         return NET_RX_DROP;
 }
 
-EXPORT_SYMBOL(ip_rcv);
 EXPORT_SYMBOL(ip_statistics);