Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[cascardo/linux.git] / net / core / skbuff.c
index 4007c14..3ab989b 100644 (file)
@@ -519,7 +519,7 @@ static void skb_release_data(struct sk_buff *skb)
 
                        uarg = skb_shinfo(skb)->destructor_arg;
                        if (uarg->callback)
-                               uarg->callback(uarg);
+                               uarg->callback(uarg, true);
                }
 
                if (skb_has_frag_list(skb))
@@ -634,6 +634,26 @@ void kfree_skb(struct sk_buff *skb)
 }
 EXPORT_SYMBOL(kfree_skb);
 
+/**
+ *     skb_tx_error - report an sk_buff xmit error
+ *     @skb: buffer that triggered an error
+ *
+ *     Report xmit error if a device callback is tracking this skb.
+ *     skb must be freed afterwards.
+ */
+void skb_tx_error(struct sk_buff *skb)
+{
+       if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) {
+               struct ubuf_info *uarg;
+
+               uarg = skb_shinfo(skb)->destructor_arg;
+               if (uarg->callback)
+                       uarg->callback(uarg, false);
+               skb_shinfo(skb)->tx_flags &= ~SKBTX_DEV_ZEROCOPY;
+       }
+}
+EXPORT_SYMBOL(skb_tx_error);
+
 /**
  *     consume_skb - free an skbuff
  *     @skb: buffer to free
@@ -662,11 +682,14 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
        new->transport_header   = old->transport_header;
        new->network_header     = old->network_header;
        new->mac_header         = old->mac_header;
+       new->inner_transport_header = old->inner_transport_header;
+       new->inner_network_header = old->inner_transport_header;
        skb_dst_copy(new, old);
        new->rxhash             = old->rxhash;
        new->ooo_okay           = old->ooo_okay;
        new->l4_rxhash          = old->l4_rxhash;
        new->no_fcs             = old->no_fcs;
+       new->encapsulation      = old->encapsulation;
 #ifdef CONFIG_XFRM
        new->sp                 = secpath_get(old->sp);
 #endif
@@ -797,7 +820,7 @@ int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask)
        for (i = 0; i < num_frags; i++)
                skb_frag_unref(skb, i);
 
-       uarg->callback(uarg);
+       uarg->callback(uarg, false);
 
        /* skb frags point to kernel buffers */
        for (i = num_frags - 1; i >= 0; i--) {
@@ -872,6 +895,8 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
        new->network_header   += offset;
        if (skb_mac_header_was_set(new))
                new->mac_header       += offset;
+       new->inner_transport_header += offset;
+       new->inner_network_header   += offset;
 #endif
        skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size;
        skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs;
@@ -1069,6 +1094,8 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
        skb->network_header   += off;
        if (skb_mac_header_was_set(skb))
                skb->mac_header += off;
+       skb->inner_transport_header += off;
+       skb->inner_network_header += off;
        /* Only adjust this if it actually is csum_start rather than csum */
        if (skb->ip_summed == CHECKSUM_PARTIAL)
                skb->csum_start += nhead;
@@ -1168,6 +1195,8 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
        n->network_header   += off;
        if (skb_mac_header_was_set(skb))
                n->mac_header += off;
+       n->inner_transport_header += off;
+       n->inner_network_header    += off;
 #endif
 
        return n;
@@ -2999,12 +3028,11 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
        memcpy(skb_mac_header(nskb), skb_mac_header(p),
               p->data - skb_mac_header(p));
 
-       *NAPI_GRO_CB(nskb) = *NAPI_GRO_CB(p);
        skb_shinfo(nskb)->frag_list = p;
        skb_shinfo(nskb)->gso_size = pinfo->gso_size;
        pinfo->gso_size = 0;
        skb_header_release(p);
-       nskb->prev = p;
+       NAPI_GRO_CB(nskb)->last = p;
 
        nskb->data_len += p->len;
        nskb->truesize += p->truesize;
@@ -3030,8 +3058,8 @@ merge:
 
        __skb_pull(skb, offset);
 
-       p->prev->next = skb;
-       p->prev = skb;
+       NAPI_GRO_CB(p)->last->next = skb;
+       NAPI_GRO_CB(p)->last = skb;
        skb_header_release(skb);
 
 done: