netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [0/2] tun: Fix csum_start and TUN_PKT_STRIP
@ 2014-11-02 20:29 Herbert Xu
  2014-11-02 20:30 ` [PATCH 1/2] tun: Fix csum_start with VLAN acceleration Herbert Xu
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Herbert Xu @ 2014-11-02 20:29 UTC (permalink / raw)
  To: David S. Miller, netdev

Hi:

The first patch fixes a serious problem that breaks checksum offload
in VMs while the second patch fixes a problem that probably affects
no one.

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

* [PATCH 1/2] tun: Fix csum_start with VLAN acceleration
  2014-11-02 20:29 [0/2] tun: Fix csum_start and TUN_PKT_STRIP Herbert Xu
@ 2014-11-02 20:30 ` Herbert Xu
  2014-11-02 20:30 ` [PATCH 2/2] tun: Fix TUN_PKT_STRIP setting Herbert Xu
  2014-11-03 19:28 ` [0/2] tun: Fix csum_start and TUN_PKT_STRIP David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: Herbert Xu @ 2014-11-02 20:30 UTC (permalink / raw)
  To: David S. Miller, netdev

When VLAN acceleration is in use on the xmit path, we end up
setting csum_start to the wrong place.  The result is that the
whoever ends up doing the checksum setting will corrupt the packet
instead of writing the checksum to the expected location, usually
this means writing the checksum with an offset of -4.

This patch fixes this by adjusting csum_start when VLAN acceleration
is detected.

Fixes: 6680ec68eff4 ("tuntap: hardware vlan tx support")
Cc: stable@vger.kernel.org
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 drivers/net/tun.c |   16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 7302398..57e6bf7 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1235,6 +1235,10 @@ static ssize_t tun_put_user(struct tun_struct *tun,
 	struct tun_pi pi = { 0, skb->protocol };
 	ssize_t total = 0;
 	int vlan_offset = 0, copied;
+	int vlan_hlen = 0;
+
+	if (vlan_tx_tag_present(skb))
+		vlan_hlen = VLAN_HLEN;
 
 	if (!(tun->flags & TUN_NO_PI)) {
 		if ((len -= sizeof(pi)) < 0)
@@ -1284,7 +1288,8 @@ static ssize_t tun_put_user(struct tun_struct *tun,
 
 		if (skb->ip_summed == CHECKSUM_PARTIAL) {
 			gso.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
-			gso.csum_start = skb_checksum_start_offset(skb);
+			gso.csum_start = skb_checksum_start_offset(skb) +
+					 vlan_hlen;
 			gso.csum_offset = skb->csum_offset;
 		} else if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
 			gso.flags = VIRTIO_NET_HDR_F_DATA_VALID;
@@ -1297,10 +1302,9 @@ static ssize_t tun_put_user(struct tun_struct *tun,
 	}
 
 	copied = total;
-	total += skb->len;
-	if (!vlan_tx_tag_present(skb)) {
-		len = min_t(int, skb->len, len);
-	} else {
+	len = min_t(int, skb->len + vlan_hlen, len);
+	total += skb->len + vlan_hlen;
+	if (vlan_hlen) {
 		int copy, ret;
 		struct {
 			__be16 h_vlan_proto;
@@ -1311,8 +1315,6 @@ static ssize_t tun_put_user(struct tun_struct *tun,
 		veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb));
 
 		vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto);
-		len = min_t(int, skb->len + VLAN_HLEN, len);
-		total += VLAN_HLEN;
 
 		copy = min_t(int, vlan_offset, len);
 		ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy);

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

* [PATCH 2/2] tun: Fix TUN_PKT_STRIP setting
  2014-11-02 20:29 [0/2] tun: Fix csum_start and TUN_PKT_STRIP Herbert Xu
  2014-11-02 20:30 ` [PATCH 1/2] tun: Fix csum_start with VLAN acceleration Herbert Xu
@ 2014-11-02 20:30 ` Herbert Xu
  2014-11-03 19:28 ` [0/2] tun: Fix csum_start and TUN_PKT_STRIP David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: Herbert Xu @ 2014-11-02 20:30 UTC (permalink / raw)
  To: David S. Miller, netdev

We set the flag TUN_PKT_STRIP if the user buffer provided is too
small to contain the entire packet plus meta-data.  However, this
has been broken ever since we added GSO meta-data.  VLAN acceleration
also has the same problem.

This patch fixes this by taking both into account when setting the
TUN_PKT_STRIP flag.

The fact that this has been broken for six years without anyone
realising means that nobody actually uses this flag.

Fixes: f43798c27684 ("tun: Allow GSO using virtio_net_hdr")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 drivers/net/tun.c |   12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 57e6bf7..9dd3746 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1236,15 +1236,19 @@ static ssize_t tun_put_user(struct tun_struct *tun,
 	ssize_t total = 0;
 	int vlan_offset = 0, copied;
 	int vlan_hlen = 0;
+	int vnet_hdr_sz = 0;
 
 	if (vlan_tx_tag_present(skb))
 		vlan_hlen = VLAN_HLEN;
 
+	if (tun->flags & TUN_VNET_HDR)
+		vnet_hdr_sz = tun->vnet_hdr_sz;
+
 	if (!(tun->flags & TUN_NO_PI)) {
 		if ((len -= sizeof(pi)) < 0)
 			return -EINVAL;
 
-		if (len < skb->len) {
+		if (len < skb->len + vlan_hlen + vnet_hdr_sz) {
 			/* Packet will be striped */
 			pi.flags |= TUN_PKT_STRIP;
 		}
@@ -1254,9 +1258,9 @@ static ssize_t tun_put_user(struct tun_struct *tun,
 		total += sizeof(pi);
 	}
 
-	if (tun->flags & TUN_VNET_HDR) {
+	if (vnet_hdr_sz) {
 		struct virtio_net_hdr gso = { 0 }; /* no info leak */
-		if ((len -= tun->vnet_hdr_sz) < 0)
+		if ((len -= vnet_hdr_sz) < 0)
 			return -EINVAL;
 
 		if (skb_is_gso(skb)) {
@@ -1298,7 +1302,7 @@ static ssize_t tun_put_user(struct tun_struct *tun,
 		if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total,
 					       sizeof(gso))))
 			return -EFAULT;
-		total += tun->vnet_hdr_sz;
+		total += vnet_hdr_sz;
 	}
 
 	copied = total;

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

* Re: [0/2] tun: Fix csum_start and TUN_PKT_STRIP
  2014-11-02 20:29 [0/2] tun: Fix csum_start and TUN_PKT_STRIP Herbert Xu
  2014-11-02 20:30 ` [PATCH 1/2] tun: Fix csum_start with VLAN acceleration Herbert Xu
  2014-11-02 20:30 ` [PATCH 2/2] tun: Fix TUN_PKT_STRIP setting Herbert Xu
@ 2014-11-03 19:28 ` David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2014-11-03 19:28 UTC (permalink / raw)
  To: herbert; +Cc: netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Mon, 3 Nov 2014 04:29:30 +0800

> The first patch fixes a serious problem that breaks checksum offload
> in VMs while the second patch fixes a problem that probably affects
> no one.

Series applied, thanks Herbert.

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

end of thread, other threads:[~2014-11-03 19:29 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-11-02 20:29 [0/2] tun: Fix csum_start and TUN_PKT_STRIP Herbert Xu
2014-11-02 20:30 ` [PATCH 1/2] tun: Fix csum_start with VLAN acceleration Herbert Xu
2014-11-02 20:30 ` [PATCH 2/2] tun: Fix TUN_PKT_STRIP setting Herbert Xu
2014-11-03 19:28 ` [0/2] tun: Fix csum_start and TUN_PKT_STRIP 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).