aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/skbuff.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/skbuff.c')
-rw-r--r--net/core/skbuff.c277
1 files changed, 262 insertions, 15 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 65f7757465bd..b8d0abb26433 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -501,7 +501,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
501 new->network_header = old->network_header; 501 new->network_header = old->network_header;
502 new->mac_header = old->mac_header; 502 new->mac_header = old->mac_header;
503 new->dst = dst_clone(old->dst); 503 new->dst = dst_clone(old->dst);
504#ifdef CONFIG_INET 504#ifdef CONFIG_XFRM
505 new->sp = secpath_get(old->sp); 505 new->sp = secpath_get(old->sp);
506#endif 506#endif
507 memcpy(new->cb, old->cb, sizeof(old->cb)); 507 memcpy(new->cb, old->cb, sizeof(old->cb));
@@ -556,6 +556,7 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb)
556 C(truesize); 556 C(truesize);
557#if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) 557#if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE)
558 C(do_not_encrypt); 558 C(do_not_encrypt);
559 C(requeue);
559#endif 560#endif
560 atomic_set(&n->users, 1); 561 atomic_set(&n->users, 1);
561 562
@@ -2017,6 +2018,148 @@ void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len)
2017 skb_split_no_header(skb, skb1, len, pos); 2018 skb_split_no_header(skb, skb1, len, pos);
2018} 2019}
2019 2020
2021/* Shifting from/to a cloned skb is a no-go.
2022 *
2023 * Caller cannot keep skb_shinfo related pointers past calling here!
2024 */
2025static int skb_prepare_for_shift(struct sk_buff *skb)
2026{
2027 return skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
2028}
2029
2030/**
2031 * skb_shift - Shifts paged data partially from skb to another
2032 * @tgt: buffer into which tail data gets added
2033 * @skb: buffer from which the paged data comes from
2034 * @shiftlen: shift up to this many bytes
2035 *
2036 * Attempts to shift up to shiftlen worth of bytes, which may be less than
2037 * the length of the skb, from tgt to skb. Returns number bytes shifted.
2038 * It's up to caller to free skb if everything was shifted.
2039 *
2040 * If @tgt runs out of frags, the whole operation is aborted.
2041 *
2042 * Skb cannot include anything else but paged data while tgt is allowed
2043 * to have non-paged data as well.
2044 *
2045 * TODO: full sized shift could be optimized but that would need
2046 * specialized skb free'er to handle frags without up-to-date nr_frags.
2047 */
2048int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen)
2049{
2050 int from, to, merge, todo;
2051 struct skb_frag_struct *fragfrom, *fragto;
2052
2053 BUG_ON(shiftlen > skb->len);
2054 BUG_ON(skb_headlen(skb)); /* Would corrupt stream */
2055
2056 todo = shiftlen;
2057 from = 0;
2058 to = skb_shinfo(tgt)->nr_frags;
2059 fragfrom = &skb_shinfo(skb)->frags[from];
2060
2061 /* Actual merge is delayed until the point when we know we can
2062 * commit all, so that we don't have to undo partial changes
2063 */
2064 if (!to ||
2065 !skb_can_coalesce(tgt, to, fragfrom->page, fragfrom->page_offset)) {
2066 merge = -1;
2067 } else {
2068 merge = to - 1;
2069
2070 todo -= fragfrom->size;
2071 if (todo < 0) {
2072 if (skb_prepare_for_shift(skb) ||
2073 skb_prepare_for_shift(tgt))
2074 return 0;
2075
2076 /* All previous frag pointers might be stale! */
2077 fragfrom = &skb_shinfo(skb)->frags[from];
2078 fragto = &skb_shinfo(tgt)->frags[merge];
2079
2080 fragto->size += shiftlen;
2081 fragfrom->size -= shiftlen;
2082 fragfrom->page_offset += shiftlen;
2083
2084 goto onlymerged;
2085 }
2086
2087 from++;
2088 }
2089
2090 /* Skip full, not-fitting skb to avoid expensive operations */
2091 if ((shiftlen == skb->len) &&
2092 (skb_shinfo(skb)->nr_frags - from) > (MAX_SKB_FRAGS - to))
2093 return 0;
2094
2095 if (skb_prepare_for_shift(skb) || skb_prepare_for_shift(tgt))
2096 return 0;
2097
2098 while ((todo > 0) && (from < skb_shinfo(skb)->nr_frags)) {
2099 if (to == MAX_SKB_FRAGS)
2100 return 0;
2101
2102 fragfrom = &skb_shinfo(skb)->frags[from];
2103 fragto = &skb_shinfo(tgt)->frags[to];
2104
2105 if (todo >= fragfrom->size) {
2106 *fragto = *fragfrom;
2107 todo -= fragfrom->size;
2108 from++;
2109 to++;
2110
2111 } else {
2112 get_page(fragfrom->page);
2113 fragto->page = fragfrom->page;
2114 fragto->page_offset = fragfrom->page_offset;
2115 fragto->size = todo;
2116
2117 fragfrom->page_offset += todo;
2118 fragfrom->size -= todo;
2119 todo = 0;
2120
2121 to++;
2122 break;
2123 }
2124 }
2125
2126 /* Ready to "commit" this state change to tgt */
2127 skb_shinfo(tgt)->nr_frags = to;
2128
2129 if (merge >= 0) {
2130 fragfrom = &skb_shinfo(skb)->frags[0];
2131 fragto = &skb_shinfo(tgt)->frags[merge];
2132
2133 fragto->size += fragfrom->size;
2134 put_page(fragfrom->page);
2135 }
2136
2137 /* Reposition in the original skb */
2138 to = 0;
2139 while (from < skb_shinfo(skb)->nr_frags)
2140 skb_shinfo(skb)->frags[to++] = skb_shinfo(skb)->frags[from++];
2141 skb_shinfo(skb)->nr_frags = to;
2142
2143 BUG_ON(todo > 0 && !skb_shinfo(skb)->nr_frags);
2144
2145onlymerged:
2146 /* Most likely the tgt won't ever need its checksum anymore, skb on
2147 * the other hand might need it if it needs to be resent
2148 */
2149 tgt->ip_summed = CHECKSUM_PARTIAL;
2150 skb->ip_summed = CHECKSUM_PARTIAL;
2151
2152 /* Yak, is it really working this way? Some helper please? */
2153 skb->len -= shiftlen;
2154 skb->data_len -= shiftlen;
2155 skb->truesize -= shiftlen;
2156 tgt->len += shiftlen;
2157 tgt->data_len += shiftlen;
2158 tgt->truesize += shiftlen;
2159
2160 return shiftlen;
2161}
2162
2020/** 2163/**
2021 * skb_prepare_seq_read - Prepare a sequential read of skb data 2164 * skb_prepare_seq_read - Prepare a sequential read of skb data
2022 * @skb: the buffer to read 2165 * @skb: the buffer to read
@@ -2285,6 +2428,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
2285{ 2428{
2286 struct sk_buff *segs = NULL; 2429 struct sk_buff *segs = NULL;
2287 struct sk_buff *tail = NULL; 2430 struct sk_buff *tail = NULL;
2431 struct sk_buff *fskb = skb_shinfo(skb)->frag_list;
2288 unsigned int mss = skb_shinfo(skb)->gso_size; 2432 unsigned int mss = skb_shinfo(skb)->gso_size;
2289 unsigned int doffset = skb->data - skb_mac_header(skb); 2433 unsigned int doffset = skb->data - skb_mac_header(skb);
2290 unsigned int offset = doffset; 2434 unsigned int offset = doffset;
@@ -2304,7 +2448,6 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
2304 struct sk_buff *nskb; 2448 struct sk_buff *nskb;
2305 skb_frag_t *frag; 2449 skb_frag_t *frag;
2306 int hsize; 2450 int hsize;
2307 int k;
2308 int size; 2451 int size;
2309 2452
2310 len = skb->len - offset; 2453 len = skb->len - offset;
@@ -2317,9 +2460,36 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
2317 if (hsize > len || !sg) 2460 if (hsize > len || !sg)
2318 hsize = len; 2461 hsize = len;
2319 2462
2320 nskb = alloc_skb(hsize + doffset + headroom, GFP_ATOMIC); 2463 if (!hsize && i >= nfrags) {
2321 if (unlikely(!nskb)) 2464 BUG_ON(fskb->len != len);
2322 goto err; 2465
2466 pos += len;
2467 nskb = skb_clone(fskb, GFP_ATOMIC);
2468 fskb = fskb->next;
2469
2470 if (unlikely(!nskb))
2471 goto err;
2472
2473 hsize = skb_end_pointer(nskb) - nskb->head;
2474 if (skb_cow_head(nskb, doffset + headroom)) {
2475 kfree_skb(nskb);
2476 goto err;
2477 }
2478
2479 nskb->truesize += skb_end_pointer(nskb) - nskb->head -
2480 hsize;
2481 skb_release_head_state(nskb);
2482 __skb_push(nskb, doffset);
2483 } else {
2484 nskb = alloc_skb(hsize + doffset + headroom,
2485 GFP_ATOMIC);
2486
2487 if (unlikely(!nskb))
2488 goto err;
2489
2490 skb_reserve(nskb, headroom);
2491 __skb_put(nskb, doffset);
2492 }
2323 2493
2324 if (segs) 2494 if (segs)
2325 tail->next = nskb; 2495 tail->next = nskb;
@@ -2330,13 +2500,15 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
2330 __copy_skb_header(nskb, skb); 2500 __copy_skb_header(nskb, skb);
2331 nskb->mac_len = skb->mac_len; 2501 nskb->mac_len = skb->mac_len;
2332 2502
2333 skb_reserve(nskb, headroom);
2334 skb_reset_mac_header(nskb); 2503 skb_reset_mac_header(nskb);
2335 skb_set_network_header(nskb, skb->mac_len); 2504 skb_set_network_header(nskb, skb->mac_len);
2336 nskb->transport_header = (nskb->network_header + 2505 nskb->transport_header = (nskb->network_header +
2337 skb_network_header_len(skb)); 2506 skb_network_header_len(skb));
2338 skb_copy_from_linear_data(skb, skb_put(nskb, doffset), 2507 skb_copy_from_linear_data(skb, nskb->data, doffset);
2339 doffset); 2508
2509 if (pos >= offset + len)
2510 continue;
2511
2340 if (!sg) { 2512 if (!sg) {
2341 nskb->ip_summed = CHECKSUM_NONE; 2513 nskb->ip_summed = CHECKSUM_NONE;
2342 nskb->csum = skb_copy_and_csum_bits(skb, offset, 2514 nskb->csum = skb_copy_and_csum_bits(skb, offset,
@@ -2346,14 +2518,11 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
2346 } 2518 }
2347 2519
2348 frag = skb_shinfo(nskb)->frags; 2520 frag = skb_shinfo(nskb)->frags;
2349 k = 0;
2350 2521
2351 skb_copy_from_linear_data_offset(skb, offset, 2522 skb_copy_from_linear_data_offset(skb, offset,
2352 skb_put(nskb, hsize), hsize); 2523 skb_put(nskb, hsize), hsize);
2353 2524
2354 while (pos < offset + len) { 2525 while (pos < offset + len && i < nfrags) {
2355 BUG_ON(i >= nfrags);
2356
2357 *frag = skb_shinfo(skb)->frags[i]; 2526 *frag = skb_shinfo(skb)->frags[i];
2358 get_page(frag->page); 2527 get_page(frag->page);
2359 size = frag->size; 2528 size = frag->size;
@@ -2363,20 +2532,39 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
2363 frag->size -= offset - pos; 2532 frag->size -= offset - pos;
2364 } 2533 }
2365 2534
2366 k++; 2535 skb_shinfo(nskb)->nr_frags++;
2367 2536
2368 if (pos + size <= offset + len) { 2537 if (pos + size <= offset + len) {
2369 i++; 2538 i++;
2370 pos += size; 2539 pos += size;
2371 } else { 2540 } else {
2372 frag->size -= pos + size - (offset + len); 2541 frag->size -= pos + size - (offset + len);
2373 break; 2542 goto skip_fraglist;
2374 } 2543 }
2375 2544
2376 frag++; 2545 frag++;
2377 } 2546 }
2378 2547
2379 skb_shinfo(nskb)->nr_frags = k; 2548 if (pos < offset + len) {
2549 struct sk_buff *fskb2 = fskb;
2550
2551 BUG_ON(pos + fskb->len != offset + len);
2552
2553 pos += fskb->len;
2554 fskb = fskb->next;
2555
2556 if (fskb2->next) {
2557 fskb2 = skb_clone(fskb2, GFP_ATOMIC);
2558 if (!fskb2)
2559 goto err;
2560 } else
2561 skb_get(fskb2);
2562
2563 BUG_ON(skb_shinfo(nskb)->frag_list);
2564 skb_shinfo(nskb)->frag_list = fskb2;
2565 }
2566
2567skip_fraglist:
2380 nskb->data_len = len - hsize; 2568 nskb->data_len = len - hsize;
2381 nskb->len += nskb->data_len; 2569 nskb->len += nskb->data_len;
2382 nskb->truesize += nskb->data_len; 2570 nskb->truesize += nskb->data_len;
@@ -2394,6 +2582,65 @@ err:
2394 2582
2395EXPORT_SYMBOL_GPL(skb_segment); 2583EXPORT_SYMBOL_GPL(skb_segment);
2396 2584
2585int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
2586{
2587 struct sk_buff *p = *head;
2588 struct sk_buff *nskb;
2589 unsigned int headroom;
2590 unsigned int hlen = p->data - skb_mac_header(p);
2591
2592 if (hlen + p->len + skb->len >= 65536)
2593 return -E2BIG;
2594
2595 if (skb_shinfo(p)->frag_list)
2596 goto merge;
2597
2598 headroom = skb_headroom(p);
2599 nskb = netdev_alloc_skb(p->dev, headroom);
2600 if (unlikely(!nskb))
2601 return -ENOMEM;
2602
2603 __copy_skb_header(nskb, p);
2604 nskb->mac_len = p->mac_len;
2605
2606 skb_reserve(nskb, headroom);
2607
2608 skb_set_mac_header(nskb, -hlen);
2609 skb_set_network_header(nskb, skb_network_offset(p));
2610 skb_set_transport_header(nskb, skb_transport_offset(p));
2611
2612 memcpy(skb_mac_header(nskb), skb_mac_header(p), hlen);
2613
2614 *NAPI_GRO_CB(nskb) = *NAPI_GRO_CB(p);
2615 skb_shinfo(nskb)->frag_list = p;
2616 skb_header_release(p);
2617 nskb->prev = p;
2618
2619 nskb->data_len += p->len;
2620 nskb->truesize += p->len;
2621 nskb->len += p->len;
2622
2623 *head = nskb;
2624 nskb->next = p->next;
2625 p->next = NULL;
2626
2627 p = nskb;
2628
2629merge:
2630 NAPI_GRO_CB(p)->count++;
2631 p->prev->next = skb;
2632 p->prev = skb;
2633 skb_header_release(skb);
2634
2635 p->data_len += skb->len;
2636 p->truesize += skb->len;
2637 p->len += skb->len;
2638
2639 NAPI_GRO_CB(skb)->same_flow = 1;
2640 return 0;
2641}
2642EXPORT_SYMBOL_GPL(skb_gro_receive);
2643
2397void __init skb_init(void) 2644void __init skb_init(void)
2398{ 2645{
2399 skbuff_head_cache = kmem_cache_create("skbuff_head_cache", 2646 skbuff_head_cache = kmem_cache_create("skbuff_head_cache",