diff options
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r-- | drivers/net/tun.c | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 87214a257d2a..3f5d28851aa2 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -103,13 +103,10 @@ struct tun_struct { | |||
103 | uid_t owner; | 103 | uid_t owner; |
104 | gid_t group; | 104 | gid_t group; |
105 | 105 | ||
106 | struct sk_buff_head readq; | ||
107 | |||
108 | struct net_device *dev; | 106 | struct net_device *dev; |
109 | struct fasync_struct *fasync; | 107 | struct fasync_struct *fasync; |
110 | 108 | ||
111 | struct tap_filter txflt; | 109 | struct tap_filter txflt; |
112 | struct sock *sk; | ||
113 | struct socket socket; | 110 | struct socket socket; |
114 | 111 | ||
115 | #ifdef TUN_DEBUG | 112 | #ifdef TUN_DEBUG |
@@ -148,7 +145,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file) | |||
148 | tfile->tun = tun; | 145 | tfile->tun = tun; |
149 | tun->tfile = tfile; | 146 | tun->tfile = tfile; |
150 | dev_hold(tun->dev); | 147 | dev_hold(tun->dev); |
151 | sock_hold(tun->sk); | 148 | sock_hold(tun->socket.sk); |
152 | atomic_inc(&tfile->count); | 149 | atomic_inc(&tfile->count); |
153 | 150 | ||
154 | out: | 151 | out: |
@@ -164,7 +161,7 @@ static void __tun_detach(struct tun_struct *tun) | |||
164 | netif_tx_unlock_bh(tun->dev); | 161 | netif_tx_unlock_bh(tun->dev); |
165 | 162 | ||
166 | /* Drop read queue */ | 163 | /* Drop read queue */ |
167 | skb_queue_purge(&tun->readq); | 164 | skb_queue_purge(&tun->socket.sk->sk_receive_queue); |
168 | 165 | ||
169 | /* Drop the extra count on the net device */ | 166 | /* Drop the extra count on the net device */ |
170 | dev_put(tun->dev); | 167 | dev_put(tun->dev); |
@@ -333,7 +330,7 @@ static void tun_free_netdev(struct net_device *dev) | |||
333 | { | 330 | { |
334 | struct tun_struct *tun = netdev_priv(dev); | 331 | struct tun_struct *tun = netdev_priv(dev); |
335 | 332 | ||
336 | sock_put(tun->sk); | 333 | sock_put(tun->socket.sk); |
337 | } | 334 | } |
338 | 335 | ||
339 | /* Net device open. */ | 336 | /* Net device open. */ |
@@ -351,7 +348,7 @@ static int tun_net_close(struct net_device *dev) | |||
351 | } | 348 | } |
352 | 349 | ||
353 | /* Net device start xmit */ | 350 | /* Net device start xmit */ |
354 | static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev) | 351 | static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) |
355 | { | 352 | { |
356 | struct tun_struct *tun = netdev_priv(dev); | 353 | struct tun_struct *tun = netdev_priv(dev); |
357 | 354 | ||
@@ -367,7 +364,7 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev) | |||
367 | if (!check_filter(&tun->txflt, skb)) | 364 | if (!check_filter(&tun->txflt, skb)) |
368 | goto drop; | 365 | goto drop; |
369 | 366 | ||
370 | if (skb_queue_len(&tun->readq) >= dev->tx_queue_len) { | 367 | if (skb_queue_len(&tun->socket.sk->sk_receive_queue) >= dev->tx_queue_len) { |
371 | if (!(tun->flags & TUN_ONE_QUEUE)) { | 368 | if (!(tun->flags & TUN_ONE_QUEUE)) { |
372 | /* Normal queueing mode. */ | 369 | /* Normal queueing mode. */ |
373 | /* Packet scheduler handles dropping of further packets. */ | 370 | /* Packet scheduler handles dropping of further packets. */ |
@@ -384,19 +381,19 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev) | |||
384 | } | 381 | } |
385 | 382 | ||
386 | /* Enqueue packet */ | 383 | /* Enqueue packet */ |
387 | skb_queue_tail(&tun->readq, skb); | 384 | skb_queue_tail(&tun->socket.sk->sk_receive_queue, skb); |
388 | dev->trans_start = jiffies; | 385 | dev->trans_start = jiffies; |
389 | 386 | ||
390 | /* Notify and wake up reader process */ | 387 | /* Notify and wake up reader process */ |
391 | if (tun->flags & TUN_FASYNC) | 388 | if (tun->flags & TUN_FASYNC) |
392 | kill_fasync(&tun->fasync, SIGIO, POLL_IN); | 389 | kill_fasync(&tun->fasync, SIGIO, POLL_IN); |
393 | wake_up_interruptible(&tun->socket.wait); | 390 | wake_up_interruptible(&tun->socket.wait); |
394 | return 0; | 391 | return NETDEV_TX_OK; |
395 | 392 | ||
396 | drop: | 393 | drop: |
397 | dev->stats.tx_dropped++; | 394 | dev->stats.tx_dropped++; |
398 | kfree_skb(skb); | 395 | kfree_skb(skb); |
399 | return 0; | 396 | return NETDEV_TX_OK; |
400 | } | 397 | } |
401 | 398 | ||
402 | static void tun_net_mclist(struct net_device *dev) | 399 | static void tun_net_mclist(struct net_device *dev) |
@@ -485,13 +482,13 @@ static unsigned int tun_chr_poll(struct file *file, poll_table * wait) | |||
485 | if (!tun) | 482 | if (!tun) |
486 | return POLLERR; | 483 | return POLLERR; |
487 | 484 | ||
488 | sk = tun->sk; | 485 | sk = tun->socket.sk; |
489 | 486 | ||
490 | DBG(KERN_INFO "%s: tun_chr_poll\n", tun->dev->name); | 487 | DBG(KERN_INFO "%s: tun_chr_poll\n", tun->dev->name); |
491 | 488 | ||
492 | poll_wait(file, &tun->socket.wait, wait); | 489 | poll_wait(file, &tun->socket.wait, wait); |
493 | 490 | ||
494 | if (!skb_queue_empty(&tun->readq)) | 491 | if (!skb_queue_empty(&sk->sk_receive_queue)) |
495 | mask |= POLLIN | POLLRDNORM; | 492 | mask |= POLLIN | POLLRDNORM; |
496 | 493 | ||
497 | if (sock_writeable(sk) || | 494 | if (sock_writeable(sk) || |
@@ -512,7 +509,7 @@ static inline struct sk_buff *tun_alloc_skb(struct tun_struct *tun, | |||
512 | size_t prepad, size_t len, | 509 | size_t prepad, size_t len, |
513 | size_t linear, int noblock) | 510 | size_t linear, int noblock) |
514 | { | 511 | { |
515 | struct sock *sk = tun->sk; | 512 | struct sock *sk = tun->socket.sk; |
516 | struct sk_buff *skb; | 513 | struct sk_buff *skb; |
517 | int err; | 514 | int err; |
518 | 515 | ||
@@ -634,6 +631,9 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, | |||
634 | case VIRTIO_NET_HDR_GSO_TCPV6: | 631 | case VIRTIO_NET_HDR_GSO_TCPV6: |
635 | skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; | 632 | skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6; |
636 | break; | 633 | break; |
634 | case VIRTIO_NET_HDR_GSO_UDP: | ||
635 | skb_shinfo(skb)->gso_type = SKB_GSO_UDP; | ||
636 | break; | ||
637 | default: | 637 | default: |
638 | tun->dev->stats.rx_frame_errors++; | 638 | tun->dev->stats.rx_frame_errors++; |
639 | kfree_skb(skb); | 639 | kfree_skb(skb); |
@@ -719,6 +719,8 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun, | |||
719 | gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; | 719 | gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4; |
720 | else if (sinfo->gso_type & SKB_GSO_TCPV6) | 720 | else if (sinfo->gso_type & SKB_GSO_TCPV6) |
721 | gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6; | 721 | gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6; |
722 | else if (sinfo->gso_type & SKB_GSO_UDP) | ||
723 | gso.gso_type = VIRTIO_NET_HDR_GSO_UDP; | ||
722 | else | 724 | else |
723 | BUG(); | 725 | BUG(); |
724 | if (sinfo->gso_type & SKB_GSO_TCP_ECN) | 726 | if (sinfo->gso_type & SKB_GSO_TCP_ECN) |
@@ -775,7 +777,7 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv, | |||
775 | current->state = TASK_INTERRUPTIBLE; | 777 | current->state = TASK_INTERRUPTIBLE; |
776 | 778 | ||
777 | /* Read frames from the queue */ | 779 | /* Read frames from the queue */ |
778 | if (!(skb=skb_dequeue(&tun->readq))) { | 780 | if (!(skb=skb_dequeue(&tun->socket.sk->sk_receive_queue))) { |
779 | if (file->f_flags & O_NONBLOCK) { | 781 | if (file->f_flags & O_NONBLOCK) { |
780 | ret = -EAGAIN; | 782 | ret = -EAGAIN; |
781 | break; | 783 | break; |
@@ -812,8 +814,6 @@ static void tun_setup(struct net_device *dev) | |||
812 | { | 814 | { |
813 | struct tun_struct *tun = netdev_priv(dev); | 815 | struct tun_struct *tun = netdev_priv(dev); |
814 | 816 | ||
815 | skb_queue_head_init(&tun->readq); | ||
816 | |||
817 | tun->owner = -1; | 817 | tun->owner = -1; |
818 | tun->group = -1; | 818 | tun->group = -1; |
819 | 819 | ||
@@ -934,7 +934,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
934 | (tun->group != -1 && !in_egroup_p(tun->group))) && | 934 | (tun->group != -1 && !in_egroup_p(tun->group))) && |
935 | !capable(CAP_NET_ADMIN)) | 935 | !capable(CAP_NET_ADMIN)) |
936 | return -EPERM; | 936 | return -EPERM; |
937 | err = security_tun_dev_attach(tun->sk); | 937 | err = security_tun_dev_attach(tun->socket.sk); |
938 | if (err < 0) | 938 | if (err < 0) |
939 | return err; | 939 | return err; |
940 | 940 | ||
@@ -992,7 +992,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
992 | sk->sk_write_space = tun_sock_write_space; | 992 | sk->sk_write_space = tun_sock_write_space; |
993 | sk->sk_sndbuf = INT_MAX; | 993 | sk->sk_sndbuf = INT_MAX; |
994 | 994 | ||
995 | tun->sk = sk; | ||
996 | container_of(sk, struct tun_sock, sk)->tun = tun; | 995 | container_of(sk, struct tun_sock, sk)->tun = tun; |
997 | 996 | ||
998 | security_tun_dev_post_create(sk); | 997 | security_tun_dev_post_create(sk); |
@@ -1005,7 +1004,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
1005 | goto err_free_sk; | 1004 | goto err_free_sk; |
1006 | } | 1005 | } |
1007 | 1006 | ||
1008 | err = -EINVAL; | ||
1009 | err = register_netdevice(tun->dev); | 1007 | err = register_netdevice(tun->dev); |
1010 | if (err < 0) | 1008 | if (err < 0) |
1011 | goto err_free_sk; | 1009 | goto err_free_sk; |
@@ -1077,7 +1075,8 @@ static int set_offload(struct net_device *dev, unsigned long arg) | |||
1077 | old_features = dev->features; | 1075 | old_features = dev->features; |
1078 | /* Unset features, set them as we chew on the arg. */ | 1076 | /* Unset features, set them as we chew on the arg. */ |
1079 | features = (old_features & ~(NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST | 1077 | features = (old_features & ~(NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST |
1080 | |NETIF_F_TSO_ECN|NETIF_F_TSO|NETIF_F_TSO6)); | 1078 | |NETIF_F_TSO_ECN|NETIF_F_TSO|NETIF_F_TSO6 |
1079 | |NETIF_F_UFO)); | ||
1081 | 1080 | ||
1082 | if (arg & TUN_F_CSUM) { | 1081 | if (arg & TUN_F_CSUM) { |
1083 | features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; | 1082 | features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; |
@@ -1094,6 +1093,11 @@ static int set_offload(struct net_device *dev, unsigned long arg) | |||
1094 | features |= NETIF_F_TSO6; | 1093 | features |= NETIF_F_TSO6; |
1095 | arg &= ~(TUN_F_TSO4|TUN_F_TSO6); | 1094 | arg &= ~(TUN_F_TSO4|TUN_F_TSO6); |
1096 | } | 1095 | } |
1096 | |||
1097 | if (arg & TUN_F_UFO) { | ||
1098 | features |= NETIF_F_UFO; | ||
1099 | arg &= ~TUN_F_UFO; | ||
1100 | } | ||
1097 | } | 1101 | } |
1098 | 1102 | ||
1099 | /* This gives the user a way to test for new features in future by | 1103 | /* This gives the user a way to test for new features in future by |
@@ -1247,7 +1251,7 @@ static long tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
1247 | break; | 1251 | break; |
1248 | 1252 | ||
1249 | case TUNGETSNDBUF: | 1253 | case TUNGETSNDBUF: |
1250 | sndbuf = tun->sk->sk_sndbuf; | 1254 | sndbuf = tun->socket.sk->sk_sndbuf; |
1251 | if (copy_to_user(argp, &sndbuf, sizeof(sndbuf))) | 1255 | if (copy_to_user(argp, &sndbuf, sizeof(sndbuf))) |
1252 | ret = -EFAULT; | 1256 | ret = -EFAULT; |
1253 | break; | 1257 | break; |
@@ -1258,7 +1262,7 @@ static long tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
1258 | break; | 1262 | break; |
1259 | } | 1263 | } |
1260 | 1264 | ||
1261 | tun->sk->sk_sndbuf = sndbuf; | 1265 | tun->socket.sk->sk_sndbuf = sndbuf; |
1262 | break; | 1266 | break; |
1263 | 1267 | ||
1264 | default: | 1268 | default: |
@@ -1341,7 +1345,7 @@ static int tun_chr_close(struct inode *inode, struct file *file) | |||
1341 | 1345 | ||
1342 | tun = tfile->tun; | 1346 | tun = tfile->tun; |
1343 | if (tun) | 1347 | if (tun) |
1344 | sock_put(tun->sk); | 1348 | sock_put(tun->socket.sk); |
1345 | 1349 | ||
1346 | put_net(tfile->net); | 1350 | put_net(tfile->net); |
1347 | kfree(tfile); | 1351 | kfree(tfile); |