|
@@ -607,15 +607,18 @@ static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net,
|
|
|
packet->total_data_buflen);
|
|
|
|
|
|
skb->protocol = eth_type_trans(skb, net);
|
|
|
- if (csum_info) {
|
|
|
- /* We only look at the IP checksum here.
|
|
|
- * Should we be dropping the packet if checksum
|
|
|
- * failed? How do we deal with other checksums - TCP/UDP?
|
|
|
- */
|
|
|
- if (csum_info->receive.ip_checksum_succeeded)
|
|
|
+
|
|
|
+ /* skb is already created with CHECKSUM_NONE */
|
|
|
+ skb_checksum_none_assert(skb);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * In Linux, the IP checksum is always checked.
|
|
|
+ * Do L4 checksum offload if enabled and present.
|
|
|
+ */
|
|
|
+ if (csum_info && (net->features & NETIF_F_RXCSUM)) {
|
|
|
+ if (csum_info->receive.tcp_checksum_succeeded ||
|
|
|
+ csum_info->receive.udp_checksum_succeeded)
|
|
|
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
|
|
- else
|
|
|
- skb->ip_summed = CHECKSUM_NONE;
|
|
|
}
|
|
|
|
|
|
if (vlan_tci & VLAN_TAG_PRESENT)
|