diff options
-rw-r--r-- | drivers/net/hyperv/netvsc_drv.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 256adbd044f5..cf4897043e83 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c | |||
@@ -744,6 +744,14 @@ void netvsc_linkstatus_callback(struct net_device *net, | |||
744 | schedule_delayed_work(&ndev_ctx->dwork, 0); | 744 | schedule_delayed_work(&ndev_ctx->dwork, 0); |
745 | } | 745 | } |
746 | 746 | ||
747 | static void netvsc_comp_ipcsum(struct sk_buff *skb) | ||
748 | { | ||
749 | struct iphdr *iph = (struct iphdr *)skb->data; | ||
750 | |||
751 | iph->check = 0; | ||
752 | iph->check = ip_fast_csum(iph, iph->ihl); | ||
753 | } | ||
754 | |||
747 | static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net, | 755 | static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net, |
748 | struct netvsc_channel *nvchan) | 756 | struct netvsc_channel *nvchan) |
749 | { | 757 | { |
@@ -770,9 +778,17 @@ static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net, | |||
770 | /* skb is already created with CHECKSUM_NONE */ | 778 | /* skb is already created with CHECKSUM_NONE */ |
771 | skb_checksum_none_assert(skb); | 779 | skb_checksum_none_assert(skb); |
772 | 780 | ||
773 | /* | 781 | /* Incoming packets may have IP header checksum verified by the host. |
774 | * In Linux, the IP checksum is always checked. | 782 | * They may not have IP header checksum computed after coalescing. |
775 | * Do L4 checksum offload if enabled and present. | 783 | * We compute it here if the flags are set, because on Linux, the IP |
784 | * checksum is always checked. | ||
785 | */ | ||
786 | if (csum_info && csum_info->receive.ip_checksum_value_invalid && | ||
787 | csum_info->receive.ip_checksum_succeeded && | ||
788 | skb->protocol == htons(ETH_P_IP)) | ||
789 | netvsc_comp_ipcsum(skb); | ||
790 | |||
791 | /* Do L4 checksum offload if enabled and present. | ||
776 | */ | 792 | */ |
777 | if (csum_info && (net->features & NETIF_F_RXCSUM)) { | 793 | if (csum_info && (net->features & NETIF_F_RXCSUM)) { |
778 | if (csum_info->receive.tcp_checksum_succeeded || | 794 | if (csum_info->receive.tcp_checksum_succeeded || |