aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tun.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-14 13:37:28 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-14 13:37:28 -0400
commitd7e9660ad9d5e0845f52848bce31bcf5cdcdea6b (patch)
treec6c67d145771187b194d79d603742b31090a59d6 /drivers/net/tun.c
parentb8cb48aae1b8c50b37dcb7710363aa69a7a0d9ca (diff)
parent13af7a6ea502fcdd4c0e3d7de6e332b102309491 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1623 commits) netxen: update copyright netxen: fix tx timeout recovery netxen: fix file firmware leak netxen: improve pci memory access netxen: change firmware write size tg3: Fix return ring size breakage netxen: build fix for INET=n cdc-phonet: autoconfigure Phonet address Phonet: back-end for autoconfigured addresses Phonet: fix netlink address dump error handling ipv6: Add IFA_F_DADFAILED flag net: Add DEVTYPE support for Ethernet based devices mv643xx_eth.c: remove unused txq_set_wrr() ucc_geth: Fix hangs after switching from full to half duplex ucc_geth: Rearrange some code to avoid forward declarations phy/marvell: Make non-aneg speed/duplex forcing work for 88E1111 PHYs drivers/net/phy: introduce missing kfree drivers/net/wan: introduce missing kfree net: force bridge module(s) to be GPL Subject: [PATCH] appletalk: Fix skb leak when ipddp interface is not loaded ... Fixed up trivial conflicts: - arch/x86/include/asm/socket.h converted to <asm-generic/socket.h> in the x86 tree. The generic header has the same new #define's, so that works out fine. - drivers/net/tun.c fix conflict between 89f56d1e9 ("tun: reuse struct sock fields") that switched over to using 'tun->socket.sk' instead of the redundantly available (and thus removed) 'tun->sk', and 2b980dbd ("lsm: Add hooks to the TUN driver") which added a new 'tun->sk' use. Noted in 'next' by Stephen Rothwell.
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r--drivers/net/tun.c52
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
154out: 151out:
@@ -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 */
354static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev) 351static 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
396drop: 393drop:
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
402static void tun_net_mclist(struct net_device *dev) 399static 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);