Commit bf48648d authored by Haiyang Zhang's avatar Haiyang Zhang Committed by David S. Miller

hv_netvsc: Fix IP header checksum for coalesced packets

Incoming packets may have IP header checksum verified by the host.
They may not have IP header checksum computed after coalescing.
This patch re-compute the checksum when necessary, otherwise the
packets may be dropped, because Linux network stack always checks it.
Signed-off-by: default avatarHaiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d8e96745
...@@ -744,6 +744,14 @@ void netvsc_linkstatus_callback(struct net_device *net, ...@@ -744,6 +744,14 @@ void netvsc_linkstatus_callback(struct net_device *net,
schedule_delayed_work(&ndev_ctx->dwork, 0); schedule_delayed_work(&ndev_ctx->dwork, 0);
} }
static void netvsc_comp_ipcsum(struct sk_buff *skb)
{
struct iphdr *iph = (struct iphdr *)skb->data;
iph->check = 0;
iph->check = ip_fast_csum(iph, iph->ihl);
}
static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net, static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net,
struct netvsc_channel *nvchan) struct netvsc_channel *nvchan)
{ {
...@@ -770,9 +778,17 @@ static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net, ...@@ -770,9 +778,17 @@ static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net,
/* skb is already created with CHECKSUM_NONE */ /* skb is already created with CHECKSUM_NONE */
skb_checksum_none_assert(skb); skb_checksum_none_assert(skb);
/* /* Incoming packets may have IP header checksum verified by the host.
* In Linux, the IP checksum is always checked. * They may not have IP header checksum computed after coalescing.
* Do L4 checksum offload if enabled and present. * We compute it here if the flags are set, because on Linux, the IP
* checksum is always checked.
*/
if (csum_info && csum_info->receive.ip_checksum_value_invalid &&
csum_info->receive.ip_checksum_succeeded &&
skb->protocol == htons(ETH_P_IP))
netvsc_comp_ipcsum(skb);
/* Do L4 checksum offload if enabled and present.
*/ */
if (csum_info && (net->features & NETIF_F_RXCSUM)) { if (csum_info && (net->features & NETIF_F_RXCSUM)) {
if (csum_info->receive.tcp_checksum_succeeded || if (csum_info->receive.tcp_checksum_succeeded ||
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment