Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6-block.git] / net / core / skbuff.c
index 1e556d31211742d41acb39cbc2c1cd8460e2d3b0..7c571560e9d2f411726590a9ab0f9586464306fd 100644 (file)
@@ -4,8 +4,6 @@
  *     Authors:        Alan Cox <iiitac@pyr.swan.ac.uk>
  *                     Florian La Roche <rzsfl@rz.uni-sb.de>
  *
- *     Version:        $Id: skbuff.c,v 1.90 2001/11/07 05:56:19 davem Exp $
- *
  *     Fixes:
  *             Alan Cox        :       Fixed the worst of the load
  *                                     balancer bugs.
@@ -1292,12 +1290,14 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
 {
        unsigned int nr_pages = spd->nr_pages;
        unsigned int poff, plen, len, toff, tlen;
-       int headlen, seg;
+       int headlen, seg, error = 0;
 
        toff = *offset;
        tlen = *total_len;
-       if (!tlen)
+       if (!tlen) {
+               error = 1;
                goto err;
+       }
 
        /*
         * if the offset is greater than the linear part, go directly to
@@ -1339,7 +1339,8 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
                 * just jump directly to update and return, no point
                 * in going over fragments when the output is full.
                 */
-               if (spd_fill_page(spd, virt_to_page(p), plen, poff, skb))
+               error = spd_fill_page(spd, virt_to_page(p), plen, poff, skb);
+               if (error)
                        goto done;
 
                tlen -= plen;
@@ -1369,7 +1370,8 @@ map_frag:
                if (!plen)
                        break;
 
-               if (spd_fill_page(spd, f->page, plen, poff, skb))
+               error = spd_fill_page(spd, f->page, plen, poff, skb);
+               if (error)
                        break;
 
                tlen -= plen;
@@ -1382,7 +1384,10 @@ done:
                return 0;
        }
 err:
-       return 1;
+       /* update the offset to reflect the linear part skip, if any */
+       if (!error)
+               *offset = toff;
+       return error;
 }
 
 /*
@@ -2585,6 +2590,13 @@ bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off)
        return true;
 }
 
+void __skb_warn_lro_forwarding(const struct sk_buff *skb)
+{
+       if (net_ratelimit())
+               pr_warning("%s: received packets cannot be forwarded"
+                          " while LRO is enabled\n", skb->dev->name);
+}
+
 EXPORT_SYMBOL(___pskb_trim);
 EXPORT_SYMBOL(__kfree_skb);
 EXPORT_SYMBOL(kfree_skb);
@@ -2618,6 +2630,7 @@ EXPORT_SYMBOL(skb_seq_read);
 EXPORT_SYMBOL(skb_abort_seq_read);
 EXPORT_SYMBOL(skb_find_text);
 EXPORT_SYMBOL(skb_append_datato_frags);
+EXPORT_SYMBOL(__skb_warn_lro_forwarding);
 
 EXPORT_SYMBOL_GPL(skb_to_sgvec);
 EXPORT_SYMBOL_GPL(skb_cow_data);