diff options
| -rw-r--r-- | net/core/dev.c | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 39aba4862f21..38b03da5c1ca 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -1362,22 +1362,21 @@ int skb_checksum_help(struct sk_buff *skb) | |||
| 1362 | goto out_set_summed; | 1362 | goto out_set_summed; |
| 1363 | } | 1363 | } |
| 1364 | 1364 | ||
| 1365 | if (skb_cloned(skb)) { | 1365 | offset = skb->csum_start - skb_headroom(skb); |
| 1366 | BUG_ON(offset >= skb_headlen(skb)); | ||
| 1367 | csum = skb_checksum(skb, offset, skb->len - offset, 0); | ||
| 1368 | |||
| 1369 | offset += skb->csum_offset; | ||
| 1370 | BUG_ON(offset + sizeof(__sum16) > skb_headlen(skb)); | ||
| 1371 | |||
| 1372 | if (skb_cloned(skb) && | ||
| 1373 | !skb_clone_writable(skb, offset + sizeof(__sum16))) { | ||
| 1366 | ret = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); | 1374 | ret = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); |
| 1367 | if (ret) | 1375 | if (ret) |
| 1368 | goto out; | 1376 | goto out; |
| 1369 | } | 1377 | } |
| 1370 | 1378 | ||
| 1371 | offset = skb->csum_start - skb_headroom(skb); | 1379 | *(__sum16 *)(skb->data + offset) = csum_fold(csum); |
| 1372 | BUG_ON(offset > (int)skb->len); | ||
| 1373 | csum = skb_checksum(skb, offset, skb->len-offset, 0); | ||
| 1374 | |||
| 1375 | offset = skb_headlen(skb) - offset; | ||
| 1376 | BUG_ON(offset <= 0); | ||
| 1377 | BUG_ON(skb->csum_offset + 2 > offset); | ||
| 1378 | |||
| 1379 | *(__sum16 *)(skb->head + skb->csum_start + skb->csum_offset) = | ||
| 1380 | csum_fold(csum); | ||
| 1381 | out_set_summed: | 1380 | out_set_summed: |
| 1382 | skb->ip_summed = CHECKSUM_NONE; | 1381 | skb->ip_summed = CHECKSUM_NONE; |
| 1383 | out: | 1382 | out: |
