diff options
Diffstat (limited to 'net')
-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: |