static inline void *skb_gro_mac_header(struct sk_buff *skb)
 {
-       return skb_headlen(skb) ? skb_mac_header(skb) :
+       return skb_mac_header(skb) < skb->data ? skb_mac_header(skb) :
               page_address(skb_shinfo(skb)->frags[0].page) +
               skb_shinfo(skb)->frags[0].page_offset;
 }
        napi->gro_list = skb;
        ret = GRO_HELD;
 
+pull:
+       if (unlikely(!pskb_may_pull(skb, skb_gro_offset(skb)))) {
+               if (napi->gro_list == skb)
+                       napi->gro_list = skb->next;
+               ret = GRO_DROP;
+       }
+
 ok:
        return ret;
 
 normal:
-       return GRO_NORMAL;
+       ret = GRO_NORMAL;
+       goto pull;
 }
 EXPORT_SYMBOL(dev_gro_receive);
 
 int napi_frags_finish(struct napi_struct *napi, struct sk_buff *skb, int ret)
 {
        int err = NET_RX_SUCCESS;
-       int may;
 
        switch (ret) {
        case GRO_NORMAL:
        case GRO_HELD:
-               may = pskb_may_pull(skb, skb_gro_offset(skb));
-               BUG_ON(!may);
-
                skb->protocol = eth_type_trans(skb, napi->dev);
 
                if (ret == GRO_NORMAL)