linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH hyperv-fixes] hv_netvsc: Fix IP header checksum for coalesced packets
@ 2019-02-22 18:25 Haiyang Zhang
  2019-02-23 16:46 ` Stephen Hemminger
  2019-02-26 22:45 ` David Miller
  0 siblings, 2 replies; 4+ messages in thread
From: Haiyang Zhang @ 2019-02-22 18:25 UTC (permalink / raw)
  To: sashal, linux-hyperv
  Cc: haiyangz, kys, sthemmin, olaf, vkuznets, davem, netdev, linux-kernel

From: Haiyang Zhang <haiyangz@microsoft.com>

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: Haiyang Zhang <haiyangz@microsoft.com>
---
 drivers/net/hyperv/netvsc_drv.c | 22 +++++++++++++++++++---
 1 file 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,
 	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,
 					     struct netvsc_channel *nvchan)
 {
@@ -770,9 +778,17 @@ static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net,
 	/* 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.
+	/* Incoming packets may have IP header checksum verified by the host.
+	 * They may not have IP header checksum computed after coalescing.
+	 * 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->receive.tcp_checksum_succeeded ||
-- 
2.19.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH hyperv-fixes] hv_netvsc: Fix IP header checksum for coalesced packets
  2019-02-22 18:25 [PATCH hyperv-fixes] hv_netvsc: Fix IP header checksum for coalesced packets Haiyang Zhang
@ 2019-02-23 16:46 ` Stephen Hemminger
  2019-02-23 17:29   ` Haiyang Zhang
  2019-02-26 22:45 ` David Miller
  1 sibling, 1 reply; 4+ messages in thread
From: Stephen Hemminger @ 2019-02-23 16:46 UTC (permalink / raw)
  To: Haiyang Zhang
  Cc: haiyangz, sashal, linux-hyperv, kys, sthemmin, olaf, vkuznets,
	davem, netdev, linux-kernel

On Fri, 22 Feb 2019 18:25:03 +0000
Haiyang Zhang <haiyangz@linuxonhyperv.com> wrote:

> From: Haiyang Zhang <haiyangz@microsoft.com>
> 
> 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: Haiyang Zhang <haiyangz@microsoft.com>
> ---
>  drivers/net/hyperv/netvsc_drv.c | 22 +++++++++++++++++++---
>  1 file 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,
>  	schedule_delayed_work(&ndev_ctx->dwork, 0);
>  }
>  
> +static void netvsc_comp_ipcsum(struct sk_buff *skb)
> +{
> +	struct iphdr *iph = (struct iphdr *)skb->data;

Can you use iphdr(skb) here?

> +
> +	iph->check = 0;
> +	iph->check = ip_fast_csum(iph, iph->ihl);
> +}
> +
>  static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net,
>  					     struct netvsc_channel *nvchan)
>  {
> @@ -770,9 +778,17 @@ static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net,
>  	/* 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.
> +	/* Incoming packets may have IP header checksum verified by the host.
> +	 * They may not have IP header checksum computed after coalescing.
> +	 * 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);

Does this still handle for coalesced and non-coalesced packets
which are received with bad IP checksum?  My concern is that you are
potentially correcting the checksum for a packet whose received checksum was bad.


> +	/* Do L4 checksum offload if enabled and present.
>  	 */
>  	if (csum_info && (net->features & NETIF_F_RXCSUM)) {
>  		if (csum_info->receive.tcp_checksum_succeeded ||


^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: [PATCH hyperv-fixes] hv_netvsc: Fix IP header checksum for coalesced packets
  2019-02-23 16:46 ` Stephen Hemminger
@ 2019-02-23 17:29   ` Haiyang Zhang
  0 siblings, 0 replies; 4+ messages in thread
From: Haiyang Zhang @ 2019-02-23 17:29 UTC (permalink / raw)
  To: Stephen Hemminger, Haiyang Zhang
  Cc: sashal, linux-hyperv, KY Srinivasan, Stephen Hemminger, olaf,
	vkuznets, davem, netdev, linux-kernel



> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Saturday, February 23, 2019 11:46 AM
> To: Haiyang Zhang <haiyangz@linuxonhyperv.com>
> Cc: Haiyang Zhang <haiyangz@microsoft.com>; sashal@kernel.org; linux-
> hyperv@vger.kernel.org; KY Srinivasan <kys@microsoft.com>; Stephen
> Hemminger <sthemmin@microsoft.com>; olaf@aepfle.de; vkuznets
> <vkuznets@redhat.com>; davem@davemloft.net; netdev@vger.kernel.org;
> linux-kernel@vger.kernel.org
> Subject: Re: [PATCH hyperv-fixes] hv_netvsc: Fix IP header checksum for
> coalesced packets
> 
> On Fri, 22 Feb 2019 18:25:03 +0000
> Haiyang Zhang <haiyangz@linuxonhyperv.com> wrote:
> 
> > From: Haiyang Zhang <haiyangz@microsoft.com>
> >
> > 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: Haiyang Zhang <haiyangz@microsoft.com>
> > ---
> >  drivers/net/hyperv/netvsc_drv.c | 22 +++++++++++++++++++---
> >  1 file 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,
> >  	schedule_delayed_work(&ndev_ctx->dwork, 0);  }
> >
> > +static void netvsc_comp_ipcsum(struct sk_buff *skb) {
> > +	struct iphdr *iph = (struct iphdr *)skb->data;
> 
> Can you use iphdr(skb) here?
This skb is just allocated by netvsc, the skb->network_header is not set yet.

> 
> > +
> > +	iph->check = 0;
> > +	iph->check = ip_fast_csum(iph, iph->ihl); }
> > +
> >  static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net,
> >  					     struct netvsc_channel *nvchan)
> { @@ -770,9 +778,17 @@
> > static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net,
> >  	/* 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.
> > +	/* Incoming packets may have IP header checksum verified by the
> host.
> > +	 * They may not have IP header checksum computed after coalescing.
> > +	 * 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);
> 
> Does this still handle for coalesced and non-coalesced packets which are
> received with bad IP checksum?  My concern is that you are potentially
> correcting the checksum for a packet whose received checksum was bad.

Windows networking team told me that the flags above indicate host side 
already verified the checksum. Online doc is here:
https://docs.microsoft.com/en-us/windows-hardware/drivers/network/indicating-coalesced-segments
If the NIC or miniport driver validates the TCP and IPv4 checksums but does not recompute them for the coalesced segment, it must set the TcpChecksumValueInvalid and IpChecksumValueInvalid flags in the NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO structure. Additionally, in this case the NIC or miniport driver may optionally zero out the TCP and IPv4 header checksum values in the segment.

The NIC and miniport driver must always set the IpChecksumSucceeded and TcpChecksumSucceeded flags in the NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO structure before indicating the coalesced segment.

Thanks,
- Haiyang


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH hyperv-fixes] hv_netvsc: Fix IP header checksum for coalesced packets
  2019-02-22 18:25 [PATCH hyperv-fixes] hv_netvsc: Fix IP header checksum for coalesced packets Haiyang Zhang
  2019-02-23 16:46 ` Stephen Hemminger
@ 2019-02-26 22:45 ` David Miller
  1 sibling, 0 replies; 4+ messages in thread
From: David Miller @ 2019-02-26 22:45 UTC (permalink / raw)
  To: haiyangz, haiyangz
  Cc: sashal, linux-hyperv, kys, sthemmin, olaf, vkuznets, netdev,
	linux-kernel

From: Haiyang Zhang <haiyangz@linuxonhyperv.com>
Date: Fri, 22 Feb 2019 18:25:03 +0000

> From: Haiyang Zhang <haiyangz@microsoft.com>
> 
> 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: Haiyang Zhang <haiyangz@microsoft.com>

Applied and queued up for -stable.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-02-26 22:45 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-22 18:25 [PATCH hyperv-fixes] hv_netvsc: Fix IP header checksum for coalesced packets Haiyang Zhang
2019-02-23 16:46 ` Stephen Hemminger
2019-02-23 17:29   ` Haiyang Zhang
2019-02-26 22:45 ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).