From d0b7da8afa079ffe018ab3e92879b7138977fc8f Mon Sep 17 00:00:00 2001 From: Zhi Yong Wu Date: Fri, 6 Dec 2013 14:16:51 +0800 Subject: tun: update file current position Signed-off-by: Zhi Yong Wu Signed-off-by: David S. Miller --- drivers/net/tun.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net/tun.c') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 782e38b..e26cbea 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1356,6 +1356,8 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv, ret = tun_do_read(tun, tfile, iocb, iv, len, file->f_flags & O_NONBLOCK); ret = min_t(ssize_t, ret, len); + if (ret > 0) + iocb->ki_pos = ret; out: tun_put(tun); return ret; -- cgit v1.1 From 923347bb83c67c3a572b04decb5875c3adb0d306 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Mon, 9 Dec 2013 18:25:16 +0800 Subject: tun: unbreak truncated packet signalling Commit 6680ec68eff47d36f67b4351bc9836fd6cba9532 (tuntap: hardware vlan tx support) breaks the truncated packet signal by never return a length greater than iov length in tun_put_user(). This patch fixes this by always return the length of packet plus possible vlan header. Caller can detect the truncated packet by comparing the return value and the size of iov length. Reported-by: Vlad Yasevich Cc: Vlad Yasevich Cc: Zhi Yong Wu Signed-off-by: Jason Wang Signed-off-by: David S. Miller --- drivers/net/tun.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'drivers/net/tun.c') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index e26cbea..dd1bd7a 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1183,7 +1183,11 @@ static ssize_t tun_put_user(struct tun_struct *tun, const struct iovec *iv, int len) { struct tun_pi pi = { 0, skb->protocol }; - ssize_t total = 0; + struct { + __be16 h_vlan_proto; + __be16 h_vlan_TCI; + } veth; + ssize_t total = 0, off = 0; int vlan_offset = 0; if (!(tun->flags & TUN_NO_PI)) { @@ -1248,14 +1252,11 @@ static ssize_t tun_put_user(struct tun_struct *tun, total += tun->vnet_hdr_sz; } + off = total; if (!vlan_tx_tag_present(skb)) { len = min_t(int, skb->len, len); } else { int copy, ret; - struct { - __be16 h_vlan_proto; - __be16 h_vlan_TCI; - } veth; veth.h_vlan_proto = skb->vlan_proto; veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb)); @@ -1264,22 +1265,22 @@ static ssize_t tun_put_user(struct tun_struct *tun, len = min_t(int, skb->len + VLAN_HLEN, len); copy = min_t(int, vlan_offset, len); - ret = skb_copy_datagram_const_iovec(skb, 0, iv, total, copy); + ret = skb_copy_datagram_const_iovec(skb, 0, iv, off, copy); len -= copy; - total += copy; + off += copy; if (ret || !len) goto done; copy = min_t(int, sizeof(veth), len); - ret = memcpy_toiovecend(iv, (void *)&veth, total, copy); + ret = memcpy_toiovecend(iv, (void *)&veth, off, copy); len -= copy; - total += copy; + off += copy; if (ret || !len) goto done; } - skb_copy_datagram_const_iovec(skb, vlan_offset, iv, total, len); - total += len; + skb_copy_datagram_const_iovec(skb, vlan_offset, iv, off, len); + total += skb->len + (vlan_offset ? sizeof(veth) : 0); done: tun->dev->stats.tx_packets++; -- cgit v1.1 From bbd37626e6be9500e74aa244a3be1a69b6645ea0 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 10 Dec 2013 22:10:21 -0500 Subject: net: Revert macvtap/tun truncation signalling changes. Jason Wang and Michael S. Tsirkin are still discussing how to properly fix this. Signed-off-by: David S. Miller --- drivers/net/tun.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'drivers/net/tun.c') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index dd1bd7a..e26cbea 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1183,11 +1183,7 @@ static ssize_t tun_put_user(struct tun_struct *tun, const struct iovec *iv, int len) { struct tun_pi pi = { 0, skb->protocol }; - struct { - __be16 h_vlan_proto; - __be16 h_vlan_TCI; - } veth; - ssize_t total = 0, off = 0; + ssize_t total = 0; int vlan_offset = 0; if (!(tun->flags & TUN_NO_PI)) { @@ -1252,11 +1248,14 @@ static ssize_t tun_put_user(struct tun_struct *tun, total += tun->vnet_hdr_sz; } - off = total; if (!vlan_tx_tag_present(skb)) { len = min_t(int, skb->len, len); } else { int copy, ret; + struct { + __be16 h_vlan_proto; + __be16 h_vlan_TCI; + } veth; veth.h_vlan_proto = skb->vlan_proto; veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb)); @@ -1265,22 +1264,22 @@ static ssize_t tun_put_user(struct tun_struct *tun, len = min_t(int, skb->len + VLAN_HLEN, len); copy = min_t(int, vlan_offset, len); - ret = skb_copy_datagram_const_iovec(skb, 0, iv, off, copy); + ret = skb_copy_datagram_const_iovec(skb, 0, iv, total, copy); len -= copy; - off += copy; + total += copy; if (ret || !len) goto done; copy = min_t(int, sizeof(veth), len); - ret = memcpy_toiovecend(iv, (void *)&veth, off, copy); + ret = memcpy_toiovecend(iv, (void *)&veth, total, copy); len -= copy; - off += copy; + total += copy; if (ret || !len) goto done; } - skb_copy_datagram_const_iovec(skb, vlan_offset, iv, off, len); - total += skb->len + (vlan_offset ? sizeof(veth) : 0); + skb_copy_datagram_const_iovec(skb, vlan_offset, iv, total, len); + total += len; done: tun->dev->stats.tx_packets++; -- cgit v1.1 From e6fd07c899cd719bb5517bc7f32ce03a62220351 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Wed, 11 Dec 2013 13:08:33 +0800 Subject: tun: unbreak truncated packet signalling Commit 6680ec68eff47d36f67b4351bc9836fd6cba9532 (tuntap: hardware vlan tx support) breaks the truncated packet signal by nev return a length greater than iov length in tun_put_user(). This patch fixes by always return the length of packet plus possible vlan header. Caller can detect the truncated packet by comparing the return value and the size of io length. Cc: Zhi Yong Wu Cc: Michael S. Tsirkin Signed-off-by: Vlad Yasevich Signed-off-by: Jason Wang Acked-by: Michael S. Tsirkin Signed-off-by: David S. Miller --- drivers/net/tun.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers/net/tun.c') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index e26cbea..7c8343a 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1184,7 +1184,7 @@ 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; + int vlan_offset = 0, copied; if (!(tun->flags & TUN_NO_PI)) { if ((len -= sizeof(pi)) < 0) @@ -1248,6 +1248,8 @@ static ssize_t tun_put_user(struct tun_struct *tun, total += tun->vnet_hdr_sz; } + copied = total; + total += skb->len; if (!vlan_tx_tag_present(skb)) { len = min_t(int, skb->len, len); } else { @@ -1262,24 +1264,24 @@ static ssize_t tun_put_user(struct tun_struct *tun, 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, total, copy); + ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy); len -= copy; - total += copy; + copied += copy; if (ret || !len) goto done; copy = min_t(int, sizeof(veth), len); - ret = memcpy_toiovecend(iv, (void *)&veth, total, copy); + ret = memcpy_toiovecend(iv, (void *)&veth, copied, copy); len -= copy; - total += copy; + copied += copy; if (ret || !len) goto done; } - skb_copy_datagram_const_iovec(skb, vlan_offset, iv, total, len); - total += len; + skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len); done: tun->dev->stats.tx_packets++; -- cgit v1.1