aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/dev.c')
-rw-r--r--net/core/dev.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index fec8cf27f75d..d23972f56fc7 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1155,7 +1155,7 @@ EXPORT_SYMBOL(netif_device_attach);
1155int skb_checksum_help(struct sk_buff *skb) 1155int skb_checksum_help(struct sk_buff *skb)
1156{ 1156{
1157 __wsum csum; 1157 __wsum csum;
1158 int ret = 0, offset = skb_transport_offset(skb); 1158 int ret = 0, offset;
1159 1159
1160 if (skb->ip_summed == CHECKSUM_COMPLETE) 1160 if (skb->ip_summed == CHECKSUM_COMPLETE)
1161 goto out_set_summed; 1161 goto out_set_summed;
@@ -1171,15 +1171,16 @@ int skb_checksum_help(struct sk_buff *skb)
1171 goto out; 1171 goto out;
1172 } 1172 }
1173 1173
1174 offset = skb->csum_start - skb_headroom(skb);
1174 BUG_ON(offset > (int)skb->len); 1175 BUG_ON(offset > (int)skb->len);
1175 csum = skb_checksum(skb, offset, skb->len-offset, 0); 1176 csum = skb_checksum(skb, offset, skb->len-offset, 0);
1176 1177
1177 offset = skb->tail - skb->transport_header; 1178 offset = skb_headlen(skb) - offset;
1178 BUG_ON(offset <= 0); 1179 BUG_ON(offset <= 0);
1179 BUG_ON(skb->csum_offset + 2 > offset); 1180 BUG_ON(skb->csum_offset + 2 > offset);
1180 1181
1181 *(__sum16 *)(skb_transport_header(skb) + 1182 *(__sum16 *)(skb->head + skb->csum_start + skb->csum_offset) =
1182 skb->csum_offset) = csum_fold(csum); 1183 csum_fold(csum);
1183out_set_summed: 1184out_set_summed:
1184 skb->ip_summed = CHECKSUM_NONE; 1185 skb->ip_summed = CHECKSUM_NONE;
1185out: 1186out:
@@ -1431,12 +1432,16 @@ int dev_queue_xmit(struct sk_buff *skb)
1431 /* If packet is not checksummed and device does not support 1432 /* If packet is not checksummed and device does not support
1432 * checksumming for this protocol, complete checksumming here. 1433 * checksumming for this protocol, complete checksumming here.
1433 */ 1434 */
1434 if (skb->ip_summed == CHECKSUM_PARTIAL && 1435 if (skb->ip_summed == CHECKSUM_PARTIAL) {
1435 (!(dev->features & NETIF_F_GEN_CSUM) && 1436 skb_set_transport_header(skb, skb->csum_start -
1436 (!(dev->features & NETIF_F_IP_CSUM) || 1437 skb_headroom(skb));
1437 skb->protocol != htons(ETH_P_IP)))) 1438
1438 if (skb_checksum_help(skb)) 1439 if (!(dev->features & NETIF_F_GEN_CSUM) &&
1439 goto out_kfree_skb; 1440 (!(dev->features & NETIF_F_IP_CSUM) ||
1441 skb->protocol != htons(ETH_P_IP)))
1442 if (skb_checksum_help(skb))
1443 goto out_kfree_skb;
1444 }
1440 1445
1441gso: 1446gso:
1442 spin_lock_prefetch(&dev->queue_lock); 1447 spin_lock_prefetch(&dev->queue_lock);