linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / net / ipv6 / ip6_input.c
index 25c2a9e..29f7359 100644 (file)
@@ -71,8 +71,6 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
                goto out;
        }
 
-       memset(IP6CB(skb), 0, sizeof(struct inet6_skb_parm));
-
        /*
         * Store incoming device index. When the packet will
         * be queued, we cannot refer to skb->dev anymore.
@@ -86,9 +84,14 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
         */
        IP6CB(skb)->iif = skb->dst ? ((struct rt6_info *)skb->dst)->rt6i_idev->dev->ifindex : dev->ifindex;
 
-       if (unlikely(!pskb_may_pull(skb, sizeof(*hdr))))
+       if (skb->len < sizeof(struct ipv6hdr))
                goto err;
 
+       if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) {
+               IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
+               goto drop;
+       }
+
        hdr = skb->nh.ipv6h;
 
        if (hdr->version != 6)
@@ -111,10 +114,11 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
        }
 
        if (hdr->nexthdr == NEXTHDR_HOP) {
-               if (ipv6_parse_hopopts(skb) < 0) {
+               if (ipv6_parse_hopopts(skb, IP6CB(skb)->nhoff) < 0) {
                        IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
                        return 0;
                }
+               hdr = skb->nh.ipv6h;
        }
 
        return NF_HOOK(PF_INET6,NF_IP6_PRE_ROUTING, skb, dev, NULL, ip6_rcv_finish);