aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tun.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r--drivers/net/tun.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 782e38bfc1ee..ecec8029c5e8 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -348,7 +348,8 @@ unlock:
348 * different rxq no. here. If we could not get rxhash, then we would 348 * different rxq no. here. If we could not get rxhash, then we would
349 * hope the rxq no. may help here. 349 * hope the rxq no. may help here.
350 */ 350 */
351static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb) 351static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb,
352 void *accel_priv)
352{ 353{
353 struct tun_struct *tun = netdev_priv(dev); 354 struct tun_struct *tun = netdev_priv(dev);
354 struct tun_flow_entry *e; 355 struct tun_flow_entry *e;
@@ -1184,7 +1185,7 @@ static ssize_t tun_put_user(struct tun_struct *tun,
1184{ 1185{
1185 struct tun_pi pi = { 0, skb->protocol }; 1186 struct tun_pi pi = { 0, skb->protocol };
1186 ssize_t total = 0; 1187 ssize_t total = 0;
1187 int vlan_offset = 0; 1188 int vlan_offset = 0, copied;
1188 1189
1189 if (!(tun->flags & TUN_NO_PI)) { 1190 if (!(tun->flags & TUN_NO_PI)) {
1190 if ((len -= sizeof(pi)) < 0) 1191 if ((len -= sizeof(pi)) < 0)
@@ -1248,6 +1249,8 @@ static ssize_t tun_put_user(struct tun_struct *tun,
1248 total += tun->vnet_hdr_sz; 1249 total += tun->vnet_hdr_sz;
1249 } 1250 }
1250 1251
1252 copied = total;
1253 total += skb->len;
1251 if (!vlan_tx_tag_present(skb)) { 1254 if (!vlan_tx_tag_present(skb)) {
1252 len = min_t(int, skb->len, len); 1255 len = min_t(int, skb->len, len);
1253 } else { 1256 } else {
@@ -1262,24 +1265,24 @@ static ssize_t tun_put_user(struct tun_struct *tun,
1262 1265
1263 vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); 1266 vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto);
1264 len = min_t(int, skb->len + VLAN_HLEN, len); 1267 len = min_t(int, skb->len + VLAN_HLEN, len);
1268 total += VLAN_HLEN;
1265 1269
1266 copy = min_t(int, vlan_offset, len); 1270 copy = min_t(int, vlan_offset, len);
1267 ret = skb_copy_datagram_const_iovec(skb, 0, iv, total, copy); 1271 ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy);
1268 len -= copy; 1272 len -= copy;
1269 total += copy; 1273 copied += copy;
1270 if (ret || !len) 1274 if (ret || !len)
1271 goto done; 1275 goto done;
1272 1276
1273 copy = min_t(int, sizeof(veth), len); 1277 copy = min_t(int, sizeof(veth), len);
1274 ret = memcpy_toiovecend(iv, (void *)&veth, total, copy); 1278 ret = memcpy_toiovecend(iv, (void *)&veth, copied, copy);
1275 len -= copy; 1279 len -= copy;
1276 total += copy; 1280 copied += copy;
1277 if (ret || !len) 1281 if (ret || !len)
1278 goto done; 1282 goto done;
1279 } 1283 }
1280 1284
1281 skb_copy_datagram_const_iovec(skb, vlan_offset, iv, total, len); 1285 skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len);
1282 total += len;
1283 1286
1284done: 1287done:
1285 tun->dev->stats.tx_packets++; 1288 tun->dev->stats.tx_packets++;
@@ -1356,6 +1359,8 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
1356 ret = tun_do_read(tun, tfile, iocb, iv, len, 1359 ret = tun_do_read(tun, tfile, iocb, iv, len,
1357 file->f_flags & O_NONBLOCK); 1360 file->f_flags & O_NONBLOCK);
1358 ret = min_t(ssize_t, ret, len); 1361 ret = min_t(ssize_t, ret, len);
1362 if (ret > 0)
1363 iocb->ki_pos = ret;
1359out: 1364out:
1360 tun_put(tun); 1365 tun_put(tun);
1361 return ret; 1366 return ret;