All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Fix macvtap checksum errors in bridge mode
@ 2014-04-23 16:51 Vlad Yasevich
  2014-04-23 16:51 ` [PATCH 1/2] mactap: Fix checksum errors for non-gso packets " Vlad Yasevich
  2014-04-23 16:51 ` [PATCH 2/2] Revert "macvlan : fix checksums error when we are in bridge mode" Vlad Yasevich
  0 siblings, 2 replies; 9+ messages in thread
From: Vlad Yasevich @ 2014-04-23 16:51 UTC (permalink / raw)
  To: netdev
  Cc: daniel.lezcano, nightnord, kaber, eric.dumazet, mst, jasowang,
	Vlad Yasevich

The following is a problematic configuration:

 VM1: virtio-net device connected to macvtap0@eth0
 VM2: e1000 device connect to macvtap1@eth0

The problem is is that virtio-net supports checksum offloading
and thus sends the packets to the host with CHECKSUM_PARTIAL set.
On the other hand, e1000 does not support any acceleration.

For small TCP packets (and this includes the 3-way handshake),
e1000 end up receiving packets that only have a partial checksum
set.  This causes TCP to fail checksum validation and to drop
packets.  As a result tcp connections can not be established.

The following 2 patches resolve this issue. The first patch adds
a check to the non-gso code path to see if the checksum needs to
be computed.  The second patch reverts an old commit that set
ip_summed to CHECKSUM_UNNECESSARY.  Proper checksum update is
necessary under certain circumstances.

I wend through the old thread
  http://comments.gmane.org/gmane.linux.kernel.containers.lxc.general/1459
and tried the reproducers listed there, but could not cause
invalid checksum to trigger with this series.
Daniel and Andrian, if you have the time please try this patch
set to see if you still see the old checksum issues.

Vlad Yasevich (2):
  mactap: Fix checksum errors for non-gso packets in bridge mode
  Revert "macvlan : fix checksums error when we are in bridge mode"

 drivers/net/macvlan.c | 3 ---
 drivers/net/macvtap.c | 7 +++++++
 2 files changed, 7 insertions(+), 3 deletions(-)

-- 
1.9.0

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

* [PATCH 1/2] mactap: Fix checksum errors for non-gso packets in bridge mode
  2014-04-23 16:51 [PATCH 0/2] Fix macvtap checksum errors in bridge mode Vlad Yasevich
@ 2014-04-23 16:51 ` Vlad Yasevich
  2014-04-23 19:20   ` Michael S. Tsirkin
  2014-04-23 16:51 ` [PATCH 2/2] Revert "macvlan : fix checksums error when we are in bridge mode" Vlad Yasevich
  1 sibling, 1 reply; 9+ messages in thread
From: Vlad Yasevich @ 2014-04-23 16:51 UTC (permalink / raw)
  To: netdev
  Cc: daniel.lezcano, nightnord, kaber, eric.dumazet, mst, jasowang,
	Vlad Yasevich

The following is a problematic configuration:

 VM1: virtio-net device connected to macvtap0@eth0
 VM2: e1000 device connect to macvtap1@eth0

The problem is is that virtio-net supports checksum offloading
and thus sends the packets to the host with CHECKSUM_PARTIAL set.
On the other hand, e1000 does not support any acceleration.

For small TCP packets (and this includes the 3-way handshake),
e1000 ends up receiving packets that only have a partial checksum
set.  This causes TCP to fail checksum validation and to drop
packets.  As a result tcp connections can not be established.

Commit 3e4f8b787370978733ca6cae452720a4f0c296b8
	macvtap: Perform GSO on forwarding path.
fixes this issue for large packets wthat will end up undergoing GSO.
This commit adds a check for the non-GSO case and attempts to
compute the checksum for partially checksummed packets in the
non-GSO case.

CC: Daniel Lezcano <daniel.lezcano@free.fr>
CC: Patrick McHardy <kaber@trash.net>
CC: Andrian Nord <nightnord@gmail.com>
CC: Eric Dumazet <eric.dumazet@gmail.com>
CC: Michael S. Tsirkin <mst@redhat.com>
CC: Jason Wang <jasowang@redhat.com>
Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
---
 drivers/net/macvtap.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index ff111a8..ba91084 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -322,6 +322,13 @@ static rx_handler_result_t macvtap_handle_frame(struct sk_buff **pskb)
 			segs = nskb;
 		}
 	} else {
+		/* If we receive a partial checksum and the tap side
+		 * doesn't support checksum offload, compute the checksum.
+		 */
+		if (skb->ip_summed == CHECKSUM_PARTIAL &&
+		    !(features & NETIF_F_ALL_CSUM) &&
+		    skb_checksum_help(skb))
+			goto drop;
 		skb_queue_tail(&q->sk.sk_receive_queue, skb);
 	}
 
-- 
1.9.0

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

* [PATCH 2/2] Revert "macvlan : fix checksums error when we are in bridge mode"
  2014-04-23 16:51 [PATCH 0/2] Fix macvtap checksum errors in bridge mode Vlad Yasevich
  2014-04-23 16:51 ` [PATCH 1/2] mactap: Fix checksum errors for non-gso packets " Vlad Yasevich
@ 2014-04-23 16:51 ` Vlad Yasevich
  1 sibling, 0 replies; 9+ messages in thread
From: Vlad Yasevich @ 2014-04-23 16:51 UTC (permalink / raw)
  To: netdev
  Cc: daniel.lezcano, nightnord, kaber, eric.dumazet, mst, jasowang,
	Vlad Yasevich

This reverts commit 12a2856b604476c27d85a5f9a57ae1661fc46019.
The commit above doesn't appear to be necessary any more as the
checksums appear to be correctly computed/validated.

Additionally the above commit breaks kvm configurations where
one VM is using a device that support checksum offload (virtio) and
the other VM does not.
In this case, packets leaving virtio device will have CHECKSUM_PARTIAL
set.  The packets is forwarded to a macvtap that has offload features
turned off.  Since we use CHECKSUM_UNNECESSARY, the host does does not
update the checksum and thus a bad checksum is passed up to
the guest.

CC: Daniel Lezcano <daniel.lezcano@free.fr>
CC: Patrick McHardy <kaber@trash.net>
CC: Andrian Nord <nightnord@gmail.com>
CC: Eric Dumazet <eric.dumazet@gmail.com>
CC: Michael S. Tsirkin <mst@redhat.com>
CC: Jason Wang <jasowang@redhat.com>
Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
---
 drivers/net/macvlan.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 1831fb7..33b6cf8 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -263,11 +263,9 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)
 	const struct macvlan_dev *vlan = netdev_priv(dev);
 	const struct macvlan_port *port = vlan->port;
 	const struct macvlan_dev *dest;
-	__u8 ip_summed = skb->ip_summed;
 
 	if (vlan->mode == MACVLAN_MODE_BRIDGE) {
 		const struct ethhdr *eth = (void *)skb->data;
-		skb->ip_summed = CHECKSUM_UNNECESSARY;
 
 		/* send to other bridge ports directly */
 		if (is_multicast_ether_addr(eth->h_dest)) {
@@ -285,7 +283,6 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 
 xmit_world:
-	skb->ip_summed = ip_summed;
 	skb->dev = vlan->lowerdev;
 	return dev_queue_xmit(skb);
 }
-- 
1.9.0

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

* Re: [PATCH 1/2] mactap: Fix checksum errors for non-gso packets in bridge mode
  2014-04-23 16:51 ` [PATCH 1/2] mactap: Fix checksum errors for non-gso packets " Vlad Yasevich
@ 2014-04-23 19:20   ` Michael S. Tsirkin
  2014-04-23 19:39     ` Vlad Yasevich
  0 siblings, 1 reply; 9+ messages in thread
From: Michael S. Tsirkin @ 2014-04-23 19:20 UTC (permalink / raw)
  To: Vlad Yasevich
  Cc: netdev, daniel.lezcano, nightnord, kaber, eric.dumazet, jasowang

On Wed, Apr 23, 2014 at 12:51:40PM -0400, Vlad Yasevich wrote:
> The following is a problematic configuration:
> 
>  VM1: virtio-net device connected to macvtap0@eth0
>  VM2: e1000 device connect to macvtap1@eth0
> 
> The problem is is that virtio-net supports checksum offloading
> and thus sends the packets to the host with CHECKSUM_PARTIAL set.
> On the other hand, e1000 does not support any acceleration.
> 
> For small TCP packets (and this includes the 3-way handshake),
> e1000 ends up receiving packets that only have a partial checksum
> set.  This causes TCP to fail checksum validation and to drop
> packets.  As a result tcp connections can not be established.
> 
> Commit 3e4f8b787370978733ca6cae452720a4f0c296b8
> 	macvtap: Perform GSO on forwarding path.
> fixes this issue for large packets wthat will end up undergoing GSO.
> This commit adds a check for the non-GSO case and attempts to
> compute the checksum for partially checksummed packets in the
> non-GSO case.
> 
> CC: Daniel Lezcano <daniel.lezcano@free.fr>
> CC: Patrick McHardy <kaber@trash.net>
> CC: Andrian Nord <nightnord@gmail.com>
> CC: Eric Dumazet <eric.dumazet@gmail.com>
> CC: Michael S. Tsirkin <mst@redhat.com>
> CC: Jason Wang <jasowang@redhat.com>
> Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
> ---
>  drivers/net/macvtap.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
> index ff111a8..ba91084 100644
> --- a/drivers/net/macvtap.c
> +++ b/drivers/net/macvtap.c
> @@ -322,6 +322,13 @@ static rx_handler_result_t macvtap_handle_frame(struct sk_buff **pskb)
>  			segs = nskb;
>  		}
>  	} else {
> +		/* If we receive a partial checksum and the tap side
> +		 * doesn't support checksum offload, compute the checksum.
> +		 */
> +		if (skb->ip_summed == CHECKSUM_PARTIAL &&
> +		    !(features & NETIF_F_ALL_CSUM) &&
> +		    skb_checksum_help(skb))
> +			goto drop;

Hmm confused by NETIF_F_ALL_CSUM here.

features come from here:
                feature_mask = NETIF_F_HW_CSUM;

                if (arg & (TUN_F_TSO4 | TUN_F_TSO6)) {
                        if (arg & TUN_F_TSO_ECN)
                                feature_mask |= NETIF_F_TSO_ECN;
                        if (arg & TUN_F_TSO4)
                                feature_mask |= NETIF_F_TSO;
                        if (arg & TUN_F_TSO6)
                                feature_mask |= NETIF_F_TSO6;
                }

                if (arg & TUN_F_UFO)
                        feature_mask |= NETIF_F_UFO;


okay so why not just check that NETIF_F_HW_CSUM is set?

Also does it matter whether specific offloads are enabled?


>  		skb_queue_tail(&q->sk.sk_receive_queue, skb);
>  	}
>  
> -- 
> 1.9.0

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

* Re: [PATCH 1/2] mactap: Fix checksum errors for non-gso packets in bridge mode
  2014-04-23 19:20   ` Michael S. Tsirkin
@ 2014-04-23 19:39     ` Vlad Yasevich
  2014-04-23 20:10       ` Michael S. Tsirkin
  0 siblings, 1 reply; 9+ messages in thread
From: Vlad Yasevich @ 2014-04-23 19:39 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: netdev, daniel.lezcano, nightnord, kaber, eric.dumazet, jasowang

On 04/23/2014 03:20 PM, Michael S. Tsirkin wrote:
> On Wed, Apr 23, 2014 at 12:51:40PM -0400, Vlad Yasevich wrote:
>> The following is a problematic configuration:
>>
>>  VM1: virtio-net device connected to macvtap0@eth0
>>  VM2: e1000 device connect to macvtap1@eth0
>>
>> The problem is is that virtio-net supports checksum offloading
>> and thus sends the packets to the host with CHECKSUM_PARTIAL set.
>> On the other hand, e1000 does not support any acceleration.
>>
>> For small TCP packets (and this includes the 3-way handshake),
>> e1000 ends up receiving packets that only have a partial checksum
>> set.  This causes TCP to fail checksum validation and to drop
>> packets.  As a result tcp connections can not be established.
>>
>> Commit 3e4f8b787370978733ca6cae452720a4f0c296b8
>> 	macvtap: Perform GSO on forwarding path.
>> fixes this issue for large packets wthat will end up undergoing GSO.
>> This commit adds a check for the non-GSO case and attempts to
>> compute the checksum for partially checksummed packets in the
>> non-GSO case.
>>
>> CC: Daniel Lezcano <daniel.lezcano@free.fr>
>> CC: Patrick McHardy <kaber@trash.net>
>> CC: Andrian Nord <nightnord@gmail.com>
>> CC: Eric Dumazet <eric.dumazet@gmail.com>
>> CC: Michael S. Tsirkin <mst@redhat.com>
>> CC: Jason Wang <jasowang@redhat.com>
>> Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
>> ---
>>  drivers/net/macvtap.c | 7 +++++++
>>  1 file changed, 7 insertions(+)
>>
>> diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
>> index ff111a8..ba91084 100644
>> --- a/drivers/net/macvtap.c
>> +++ b/drivers/net/macvtap.c
>> @@ -322,6 +322,13 @@ static rx_handler_result_t macvtap_handle_frame(struct sk_buff **pskb)
>>  			segs = nskb;
>>  		}
>>  	} else {
>> +		/* If we receive a partial checksum and the tap side
>> +		 * doesn't support checksum offload, compute the checksum.
>> +		 */
>> +		if (skb->ip_summed == CHECKSUM_PARTIAL &&
>> +		    !(features & NETIF_F_ALL_CSUM) &&
>> +		    skb_checksum_help(skb))
>> +			goto drop;
> 
> Hmm confused by NETIF_F_ALL_CSUM here.
> 
> features come from here:
>                 feature_mask = NETIF_F_HW_CSUM;
> 
>                 if (arg & (TUN_F_TSO4 | TUN_F_TSO6)) {
>                         if (arg & TUN_F_TSO_ECN)
>                                 feature_mask |= NETIF_F_TSO_ECN;
>                         if (arg & TUN_F_TSO4)
>                                 feature_mask |= NETIF_F_TSO;
>                         if (arg & TUN_F_TSO6)
>                                 feature_mask |= NETIF_F_TSO6;
>                 }
> 
>                 if (arg & TUN_F_UFO)
>                         feature_mask |= NETIF_F_UFO;
> 
> 
> okay so why not just check that NETIF_F_HW_CSUM is set?

We can do that, but it doesn't make much difference.

> 
> Also does it matter whether specific offloads are enabled?
> 

No it doesn't matter at all.  The packet is not a GSO packet
so no other acceleration is used.
Also, other offloads are dependent on checksum.

-vlad

> 
>>  		skb_queue_tail(&q->sk.sk_receive_queue, skb);
>>  	}
>>  
>> -- 
>> 1.9.0

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

* Re: [PATCH 1/2] mactap: Fix checksum errors for non-gso packets in bridge mode
  2014-04-23 19:39     ` Vlad Yasevich
@ 2014-04-23 20:10       ` Michael S. Tsirkin
  2014-04-23 20:30         ` Vlad Yasevich
  0 siblings, 1 reply; 9+ messages in thread
From: Michael S. Tsirkin @ 2014-04-23 20:10 UTC (permalink / raw)
  To: Vlad Yasevich
  Cc: netdev, daniel.lezcano, nightnord, kaber, eric.dumazet, jasowang

On Wed, Apr 23, 2014 at 03:39:44PM -0400, Vlad Yasevich wrote:
> On 04/23/2014 03:20 PM, Michael S. Tsirkin wrote:
> > On Wed, Apr 23, 2014 at 12:51:40PM -0400, Vlad Yasevich wrote:
> >> The following is a problematic configuration:
> >>
> >>  VM1: virtio-net device connected to macvtap0@eth0
> >>  VM2: e1000 device connect to macvtap1@eth0
> >>
> >> The problem is is that virtio-net supports checksum offloading
> >> and thus sends the packets to the host with CHECKSUM_PARTIAL set.
> >> On the other hand, e1000 does not support any acceleration.
> >>
> >> For small TCP packets (and this includes the 3-way handshake),
> >> e1000 ends up receiving packets that only have a partial checksum
> >> set.  This causes TCP to fail checksum validation and to drop
> >> packets.  As a result tcp connections can not be established.
> >>
> >> Commit 3e4f8b787370978733ca6cae452720a4f0c296b8
> >> 	macvtap: Perform GSO on forwarding path.
> >> fixes this issue for large packets wthat will end up undergoing GSO.
> >> This commit adds a check for the non-GSO case and attempts to
> >> compute the checksum for partially checksummed packets in the
> >> non-GSO case.
> >>
> >> CC: Daniel Lezcano <daniel.lezcano@free.fr>
> >> CC: Patrick McHardy <kaber@trash.net>
> >> CC: Andrian Nord <nightnord@gmail.com>
> >> CC: Eric Dumazet <eric.dumazet@gmail.com>
> >> CC: Michael S. Tsirkin <mst@redhat.com>
> >> CC: Jason Wang <jasowang@redhat.com>
> >> Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
> >> ---
> >>  drivers/net/macvtap.c | 7 +++++++
> >>  1 file changed, 7 insertions(+)
> >>
> >> diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
> >> index ff111a8..ba91084 100644
> >> --- a/drivers/net/macvtap.c
> >> +++ b/drivers/net/macvtap.c
> >> @@ -322,6 +322,13 @@ static rx_handler_result_t macvtap_handle_frame(struct sk_buff **pskb)
> >>  			segs = nskb;
> >>  		}
> >>  	} else {
> >> +		/* If we receive a partial checksum and the tap side
> >> +		 * doesn't support checksum offload, compute the checksum.
> >> +		 */
> >> +		if (skb->ip_summed == CHECKSUM_PARTIAL &&
> >> +		    !(features & NETIF_F_ALL_CSUM) &&
> >> +		    skb_checksum_help(skb))
> >> +			goto drop;
> > 
> > Hmm confused by NETIF_F_ALL_CSUM here.
> > 
> > features come from here:
> >                 feature_mask = NETIF_F_HW_CSUM;
> > 
> >                 if (arg & (TUN_F_TSO4 | TUN_F_TSO6)) {
> >                         if (arg & TUN_F_TSO_ECN)
> >                                 feature_mask |= NETIF_F_TSO_ECN;
> >                         if (arg & TUN_F_TSO4)
> >                                 feature_mask |= NETIF_F_TSO;
> >                         if (arg & TUN_F_TSO6)
> >                                 feature_mask |= NETIF_F_TSO6;
> >                 }
> > 
> >                 if (arg & TUN_F_UFO)
> >                         feature_mask |= NETIF_F_UFO;
> > 
> > 
> > okay so why not just check that NETIF_F_HW_CSUM is set?
> 
> We can do that, but it doesn't make much difference.

Seems cleaner to test a single bit otherwise one is left
wondering what happens if only one bit matches.

> > 
> > Also does it matter whether specific offloads are enabled?
> > 
> 
> No it doesn't matter at all.  The packet is not a GSO packet
> so no other acceleration is used.

Hmm how do we know it's not a gso packet?
All I see is need_gso test which means it needs segmentation.


> Also, other offloads are dependent on checksum.
> 
> -vlad

Right so what if checksum is on, but segmentation is off?
Not the case with e1000 today but can be with other userspace.


> > 
> >>  		skb_queue_tail(&q->sk.sk_receive_queue, skb);
> >>  	}
> >>  
> >> -- 
> >> 1.9.0

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

* Re: [PATCH 1/2] mactap: Fix checksum errors for non-gso packets in bridge mode
  2014-04-23 20:10       ` Michael S. Tsirkin
@ 2014-04-23 20:30         ` Vlad Yasevich
  2014-04-24  7:26           ` Michael S. Tsirkin
  0 siblings, 1 reply; 9+ messages in thread
From: Vlad Yasevich @ 2014-04-23 20:30 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: netdev, daniel.lezcano, nightnord, kaber, eric.dumazet, jasowang

On 04/23/2014 04:10 PM, Michael S. Tsirkin wrote:
> On Wed, Apr 23, 2014 at 03:39:44PM -0400, Vlad Yasevich wrote:
>> On 04/23/2014 03:20 PM, Michael S. Tsirkin wrote:
>>> On Wed, Apr 23, 2014 at 12:51:40PM -0400, Vlad Yasevich wrote:
>>>> The following is a problematic configuration:
>>>>
>>>>  VM1: virtio-net device connected to macvtap0@eth0
>>>>  VM2: e1000 device connect to macvtap1@eth0
>>>>
>>>> The problem is is that virtio-net supports checksum offloading
>>>> and thus sends the packets to the host with CHECKSUM_PARTIAL set.
>>>> On the other hand, e1000 does not support any acceleration.
>>>>
>>>> For small TCP packets (and this includes the 3-way handshake),
>>>> e1000 ends up receiving packets that only have a partial checksum
>>>> set.  This causes TCP to fail checksum validation and to drop
>>>> packets.  As a result tcp connections can not be established.
>>>>
>>>> Commit 3e4f8b787370978733ca6cae452720a4f0c296b8
>>>> 	macvtap: Perform GSO on forwarding path.
>>>> fixes this issue for large packets wthat will end up undergoing GSO.
>>>> This commit adds a check for the non-GSO case and attempts to
>>>> compute the checksum for partially checksummed packets in the
>>>> non-GSO case.
>>>>
>>>> CC: Daniel Lezcano <daniel.lezcano@free.fr>
>>>> CC: Patrick McHardy <kaber@trash.net>
>>>> CC: Andrian Nord <nightnord@gmail.com>
>>>> CC: Eric Dumazet <eric.dumazet@gmail.com>
>>>> CC: Michael S. Tsirkin <mst@redhat.com>
>>>> CC: Jason Wang <jasowang@redhat.com>
>>>> Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
>>>> ---
>>>>  drivers/net/macvtap.c | 7 +++++++
>>>>  1 file changed, 7 insertions(+)
>>>>
>>>> diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
>>>> index ff111a8..ba91084 100644
>>>> --- a/drivers/net/macvtap.c
>>>> +++ b/drivers/net/macvtap.c
>>>> @@ -322,6 +322,13 @@ static rx_handler_result_t macvtap_handle_frame(struct sk_buff **pskb)
>>>>  			segs = nskb;
>>>>  		}
>>>>  	} else {
>>>> +		/* If we receive a partial checksum and the tap side
>>>> +		 * doesn't support checksum offload, compute the checksum.
>>>> +		 */
>>>> +		if (skb->ip_summed == CHECKSUM_PARTIAL &&
>>>> +		    !(features & NETIF_F_ALL_CSUM) &&
>>>> +		    skb_checksum_help(skb))
>>>> +			goto drop;
>>>
>>> Hmm confused by NETIF_F_ALL_CSUM here.
>>>
>>> features come from here:
>>>                 feature_mask = NETIF_F_HW_CSUM;
>>>
>>>                 if (arg & (TUN_F_TSO4 | TUN_F_TSO6)) {
>>>                         if (arg & TUN_F_TSO_ECN)
>>>                                 feature_mask |= NETIF_F_TSO_ECN;
>>>                         if (arg & TUN_F_TSO4)
>>>                                 feature_mask |= NETIF_F_TSO;
>>>                         if (arg & TUN_F_TSO6)
>>>                                 feature_mask |= NETIF_F_TSO6;
>>>                 }
>>>
>>>                 if (arg & TUN_F_UFO)
>>>                         feature_mask |= NETIF_F_UFO;
>>>
>>>
>>> okay so why not just check that NETIF_F_HW_CSUM is set?
>>
>> We can do that, but it doesn't make much difference.
> 
> Seems cleaner to test a single bit otherwise one is left
> wondering what happens if only one bit matches.

I can certainly do a single test, but if we ever change it,
this will be another palace that would have to change.

The above is also what dev_start_hard_xmit() does.

> 
>>>
>>> Also does it matter whether specific offloads are enabled?
>>>
>>
>> No it doesn't matter at all.  The packet is not a GSO packet
>> so no other acceleration is used.
> 
> Hmm how do we know it's not a gso packet?
> All I see is need_gso test which means it needs segmentation.

Part of netif_needs_gso() is a test for skb_is_gso().  So it
it's gso and doesn't need segmentation (meaning the guest can
receive large packets), then partial checksum is OK.

> 
> 
>> Also, other offloads are dependent on checksum.
>>
>> -vlad
> 
> Right so what if checksum is on, but segmentation is off?
> Not the case with e1000 today but can be with other userspace.
> 

In this case, the skb will be in need to segmentation and will take
a different branch.

-vlad
> 
>>>
>>>>  		skb_queue_tail(&q->sk.sk_receive_queue, skb);
>>>>  	}
>>>>  
>>>> -- 
>>>> 1.9.0

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

* Re: [PATCH 1/2] mactap: Fix checksum errors for non-gso packets in bridge mode
  2014-04-23 20:30         ` Vlad Yasevich
@ 2014-04-24  7:26           ` Michael S. Tsirkin
  2014-04-24 14:05             ` Vlad Yasevich
  0 siblings, 1 reply; 9+ messages in thread
From: Michael S. Tsirkin @ 2014-04-24  7:26 UTC (permalink / raw)
  To: Vlad Yasevich
  Cc: netdev, daniel.lezcano, nightnord, kaber, eric.dumazet, jasowang

On Wed, Apr 23, 2014 at 04:30:22PM -0400, Vlad Yasevich wrote:
> On 04/23/2014 04:10 PM, Michael S. Tsirkin wrote:
> > On Wed, Apr 23, 2014 at 03:39:44PM -0400, Vlad Yasevich wrote:
> >> On 04/23/2014 03:20 PM, Michael S. Tsirkin wrote:
> >>> On Wed, Apr 23, 2014 at 12:51:40PM -0400, Vlad Yasevich wrote:
> >>>> The following is a problematic configuration:
> >>>>
> >>>>  VM1: virtio-net device connected to macvtap0@eth0
> >>>>  VM2: e1000 device connect to macvtap1@eth0
> >>>>
> >>>> The problem is is that virtio-net supports checksum offloading
> >>>> and thus sends the packets to the host with CHECKSUM_PARTIAL set.
> >>>> On the other hand, e1000 does not support any acceleration.
> >>>>
> >>>> For small TCP packets (and this includes the 3-way handshake),
> >>>> e1000 ends up receiving packets that only have a partial checksum
> >>>> set.  This causes TCP to fail checksum validation and to drop
> >>>> packets.  As a result tcp connections can not be established.
> >>>>
> >>>> Commit 3e4f8b787370978733ca6cae452720a4f0c296b8
> >>>> 	macvtap: Perform GSO on forwarding path.
> >>>> fixes this issue for large packets wthat will end up undergoing GSO.
> >>>> This commit adds a check for the non-GSO case and attempts to
> >>>> compute the checksum for partially checksummed packets in the
> >>>> non-GSO case.
> >>>>
> >>>> CC: Daniel Lezcano <daniel.lezcano@free.fr>
> >>>> CC: Patrick McHardy <kaber@trash.net>
> >>>> CC: Andrian Nord <nightnord@gmail.com>
> >>>> CC: Eric Dumazet <eric.dumazet@gmail.com>
> >>>> CC: Michael S. Tsirkin <mst@redhat.com>
> >>>> CC: Jason Wang <jasowang@redhat.com>
> >>>> Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
> >>>> ---
> >>>>  drivers/net/macvtap.c | 7 +++++++
> >>>>  1 file changed, 7 insertions(+)
> >>>>
> >>>> diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
> >>>> index ff111a8..ba91084 100644
> >>>> --- a/drivers/net/macvtap.c
> >>>> +++ b/drivers/net/macvtap.c
> >>>> @@ -322,6 +322,13 @@ static rx_handler_result_t macvtap_handle_frame(struct sk_buff **pskb)
> >>>>  			segs = nskb;
> >>>>  		}
> >>>>  	} else {
> >>>> +		/* If we receive a partial checksum and the tap side
> >>>> +		 * doesn't support checksum offload, compute the checksum.
> >>>> +		 */
> >>>> +		if (skb->ip_summed == CHECKSUM_PARTIAL &&
> >>>> +		    !(features & NETIF_F_ALL_CSUM) &&
> >>>> +		    skb_checksum_help(skb))
> >>>> +			goto drop;
> >>>
> >>> Hmm confused by NETIF_F_ALL_CSUM here.
> >>>
> >>> features come from here:
> >>>                 feature_mask = NETIF_F_HW_CSUM;
> >>>
> >>>                 if (arg & (TUN_F_TSO4 | TUN_F_TSO6)) {
> >>>                         if (arg & TUN_F_TSO_ECN)
> >>>                                 feature_mask |= NETIF_F_TSO_ECN;
> >>>                         if (arg & TUN_F_TSO4)
> >>>                                 feature_mask |= NETIF_F_TSO;
> >>>                         if (arg & TUN_F_TSO6)
> >>>                                 feature_mask |= NETIF_F_TSO6;
> >>>                 }
> >>>
> >>>                 if (arg & TUN_F_UFO)
> >>>                         feature_mask |= NETIF_F_UFO;
> >>>
> >>>
> >>> okay so why not just check that NETIF_F_HW_CSUM is set?
> >>
> >> We can do that, but it doesn't make much difference.
> > 
> > Seems cleaner to test a single bit otherwise one is left
> > wondering what happens if only one bit matches.
> 
> I can certainly do a single test, but if we ever change it,
> this will be another palace that would have to change.

Hmm change what exactly? Add support for selectively
disabling checksum for specific protocols?

> The above is also what dev_start_hard_xmit() does.

Yes and I was wondering about that too, but check it out: that one
calls: netif_skb_dev_features which in turn calls harmonize_features.
And there we have:
        if (skb->ip_summed != CHECKSUM_NONE &&
            !can_checksum_protocol(features, skb_network_protocol(skb, &tmp))) {
                features &= ~NETIF_F_ALL_CSUM;
        } else if (illegal_highdma(dev, skb)) {
                features &= ~NETIF_F_SG;
        }       

So NETIF_F_HW_CSUM is tested because it's cleared by a per-protocol
handling here which is not there in your patch.

Your patch is still correct - the reason harmonize_features is not
necessary is because tap either sets HW_CSUM or nothing,
can_checksum_protocol is always true or always false. But since we rely
on this anyway, isn't it better to make this explicit?

Alternatively let's clarify the comment here:

> >>>> +		/* If we receive a partial checksum and the tap side
> >>>> +		 * doesn't support checksum offload, compute the checksum.

Add:

       +                 * Note: it doesn't matter which checksum feature to
       +                 * check, we either support them all or none.

> >>>> +		 */

Fine?

> > 
> >>>
> >>> Also does it matter whether specific offloads are enabled?
> >>>
> >>
> >> No it doesn't matter at all.  The packet is not a GSO packet
> >> so no other acceleration is used.
> > 
> > Hmm how do we know it's not a gso packet?
> > All I see is need_gso test which means it needs segmentation.
> 
> Part of netif_needs_gso() is a test for skb_is_gso().  So it
> it's gso and doesn't need segmentation (meaning the guest can
> receive large packets), then partial checksum is OK.

That is correct- thanks for the clarification.


> > 
> > 
> >> Also, other offloads are dependent on checksum.
> >>
> >> -vlad
> > 
> > Right so what if checksum is on, but segmentation is off?
> > Not the case with e1000 today but can be with other userspace.
> > 
> 
> In this case, the skb will be in need to segmentation and will take
> a different branch.
> 
> -vlad
> > 
> >>>
> >>>>  		skb_queue_tail(&q->sk.sk_receive_queue, skb);
> >>>>  	}
> >>>>  
> >>>> -- 
> >>>> 1.9.0

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

* Re: [PATCH 1/2] mactap: Fix checksum errors for non-gso packets in bridge mode
  2014-04-24  7:26           ` Michael S. Tsirkin
@ 2014-04-24 14:05             ` Vlad Yasevich
  0 siblings, 0 replies; 9+ messages in thread
From: Vlad Yasevich @ 2014-04-24 14:05 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: netdev, daniel.lezcano, nightnord, kaber, eric.dumazet, jasowang

On 04/24/2014 03:26 AM, Michael S. Tsirkin wrote:
> On Wed, Apr 23, 2014 at 04:30:22PM -0400, Vlad Yasevich wrote:
>> On 04/23/2014 04:10 PM, Michael S. Tsirkin wrote:
>>> On Wed, Apr 23, 2014 at 03:39:44PM -0400, Vlad Yasevich wrote:
>>>> On 04/23/2014 03:20 PM, Michael S. Tsirkin wrote:
>>>>> On Wed, Apr 23, 2014 at 12:51:40PM -0400, Vlad Yasevich wrote:
>>>>>> The following is a problematic configuration:
>>>>>>
>>>>>>  VM1: virtio-net device connected to macvtap0@eth0
>>>>>>  VM2: e1000 device connect to macvtap1@eth0
>>>>>>
>>>>>> The problem is is that virtio-net supports checksum offloading
>>>>>> and thus sends the packets to the host with CHECKSUM_PARTIAL set.
>>>>>> On the other hand, e1000 does not support any acceleration.
>>>>>>
>>>>>> For small TCP packets (and this includes the 3-way handshake),
>>>>>> e1000 ends up receiving packets that only have a partial checksum
>>>>>> set.  This causes TCP to fail checksum validation and to drop
>>>>>> packets.  As a result tcp connections can not be established.
>>>>>>
>>>>>> Commit 3e4f8b787370978733ca6cae452720a4f0c296b8
>>>>>> 	macvtap: Perform GSO on forwarding path.
>>>>>> fixes this issue for large packets wthat will end up undergoing GSO.
>>>>>> This commit adds a check for the non-GSO case and attempts to
>>>>>> compute the checksum for partially checksummed packets in the
>>>>>> non-GSO case.
>>>>>>
>>>>>> CC: Daniel Lezcano <daniel.lezcano@free.fr>
>>>>>> CC: Patrick McHardy <kaber@trash.net>
>>>>>> CC: Andrian Nord <nightnord@gmail.com>
>>>>>> CC: Eric Dumazet <eric.dumazet@gmail.com>
>>>>>> CC: Michael S. Tsirkin <mst@redhat.com>
>>>>>> CC: Jason Wang <jasowang@redhat.com>
>>>>>> Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
>>>>>> ---
>>>>>>  drivers/net/macvtap.c | 7 +++++++
>>>>>>  1 file changed, 7 insertions(+)
>>>>>>
>>>>>> diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
>>>>>> index ff111a8..ba91084 100644
>>>>>> --- a/drivers/net/macvtap.c
>>>>>> +++ b/drivers/net/macvtap.c
>>>>>> @@ -322,6 +322,13 @@ static rx_handler_result_t macvtap_handle_frame(struct sk_buff **pskb)
>>>>>>  			segs = nskb;
>>>>>>  		}
>>>>>>  	} else {
>>>>>> +		/* If we receive a partial checksum and the tap side
>>>>>> +		 * doesn't support checksum offload, compute the checksum.
>>>>>> +		 */
>>>>>> +		if (skb->ip_summed == CHECKSUM_PARTIAL &&
>>>>>> +		    !(features & NETIF_F_ALL_CSUM) &&
>>>>>> +		    skb_checksum_help(skb))
>>>>>> +			goto drop;
>>>>>
>>>>> Hmm confused by NETIF_F_ALL_CSUM here.
>>>>>
>>>>> features come from here:
>>>>>                 feature_mask = NETIF_F_HW_CSUM;
>>>>>
>>>>>                 if (arg & (TUN_F_TSO4 | TUN_F_TSO6)) {
>>>>>                         if (arg & TUN_F_TSO_ECN)
>>>>>                                 feature_mask |= NETIF_F_TSO_ECN;
>>>>>                         if (arg & TUN_F_TSO4)
>>>>>                                 feature_mask |= NETIF_F_TSO;
>>>>>                         if (arg & TUN_F_TSO6)
>>>>>                                 feature_mask |= NETIF_F_TSO6;
>>>>>                 }
>>>>>
>>>>>                 if (arg & TUN_F_UFO)
>>>>>                         feature_mask |= NETIF_F_UFO;
>>>>>
>>>>>
>>>>> okay so why not just check that NETIF_F_HW_CSUM is set?
>>>>
>>>> We can do that, but it doesn't make much difference.
>>>
>>> Seems cleaner to test a single bit otherwise one is left
>>> wondering what happens if only one bit matches.
>>
>> I can certainly do a single test, but if we ever change it,
>> this will be another palace that would have to change.
> 
> Hmm change what exactly? Add support for selectively
> disabling checksum for specific protocols?

Yes.  Right now, we kind-of lump them all together, but there
are some protocols that are not accounted for in HW_CSUM.

For instance, I am looking to add SCTP checksum offload.  It
would be very useful if the host has SCTP-capable nic.

> 
>> The above is also what dev_start_hard_xmit() does.
> 
> Yes and I was wondering about that too, but check it out: that one
> calls: netif_skb_dev_features which in turn calls harmonize_features.
> And there we have:
>         if (skb->ip_summed != CHECKSUM_NONE &&
>             !can_checksum_protocol(features, skb_network_protocol(skb, &tmp))) {
>                 features &= ~NETIF_F_ALL_CSUM;
>         } else if (illegal_highdma(dev, skb)) {
>                 features &= ~NETIF_F_SG;
>         }       
> 
> So NETIF_F_HW_CSUM is tested because it's cleared by a per-protocol
> handling here which is not there in your patch.
> 
> Your patch is still correct - the reason harmonize_features is not
> necessary is because tap either sets HW_CSUM or nothing,
> can_checksum_protocol is always true or always false. But since we rely
> on this anyway, isn't it better to make this explicit?
> 
> Alternatively let's clarify the comment here:
> 
>>>>>> +		/* If we receive a partial checksum and the tap side
>>>>>> +		 * doesn't support checksum offload, compute the checksum.
> 
> Add:
> 
>        +                 * Note: it doesn't matter which checksum feature to
>        +                 * check, we either support them all or none.
> 
>>>>>> +		 */
> 
> Fine?

Looks good to me.  I'll update and re-submit.

Thanks
-vlad

> 
>>>
>>>>>
>>>>> Also does it matter whether specific offloads are enabled?
>>>>>
>>>>
>>>> No it doesn't matter at all.  The packet is not a GSO packet
>>>> so no other acceleration is used.
>>>
>>> Hmm how do we know it's not a gso packet?
>>> All I see is need_gso test which means it needs segmentation.
>>
>> Part of netif_needs_gso() is a test for skb_is_gso().  So it
>> it's gso and doesn't need segmentation (meaning the guest can
>> receive large packets), then partial checksum is OK.
> 
> That is correct- thanks for the clarification.
> 
> 
>>>
>>>
>>>> Also, other offloads are dependent on checksum.
>>>>
>>>> -vlad
>>>
>>> Right so what if checksum is on, but segmentation is off?
>>> Not the case with e1000 today but can be with other userspace.
>>>
>>
>> In this case, the skb will be in need to segmentation and will take
>> a different branch.
>>
>> -vlad
>>>
>>>>>
>>>>>>  		skb_queue_tail(&q->sk.sk_receive_queue, skb);
>>>>>>  	}
>>>>>>  
>>>>>> -- 
>>>>>> 1.9.0

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

end of thread, other threads:[~2014-04-24 14:05 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-23 16:51 [PATCH 0/2] Fix macvtap checksum errors in bridge mode Vlad Yasevich
2014-04-23 16:51 ` [PATCH 1/2] mactap: Fix checksum errors for non-gso packets " Vlad Yasevich
2014-04-23 19:20   ` Michael S. Tsirkin
2014-04-23 19:39     ` Vlad Yasevich
2014-04-23 20:10       ` Michael S. Tsirkin
2014-04-23 20:30         ` Vlad Yasevich
2014-04-24  7:26           ` Michael S. Tsirkin
2014-04-24 14:05             ` Vlad Yasevich
2014-04-23 16:51 ` [PATCH 2/2] Revert "macvlan : fix checksums error when we are in bridge mode" Vlad Yasevich

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.