aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tun.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/tun.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r--drivers/net/tun.c197
1 files changed, 163 insertions, 34 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 4fdfa2ae5418..43265207d463 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -44,7 +44,6 @@
44#include <linux/kernel.h> 44#include <linux/kernel.h>
45#include <linux/major.h> 45#include <linux/major.h>
46#include <linux/slab.h> 46#include <linux/slab.h>
47#include <linux/smp_lock.h>
48#include <linux/poll.h> 47#include <linux/poll.h>
49#include <linux/fcntl.h> 48#include <linux/fcntl.h>
50#include <linux/init.h> 49#include <linux/init.h>
@@ -54,6 +53,7 @@
54#include <linux/miscdevice.h> 53#include <linux/miscdevice.h>
55#include <linux/ethtool.h> 54#include <linux/ethtool.h>
56#include <linux/rtnetlink.h> 55#include <linux/rtnetlink.h>
56#include <linux/compat.h>
57#include <linux/if.h> 57#include <linux/if.h>
58#include <linux/if_arp.h> 58#include <linux/if_arp.h>
59#include <linux/if_ether.h> 59#include <linux/if_ether.h>
@@ -61,6 +61,7 @@
61#include <linux/crc32.h> 61#include <linux/crc32.h>
62#include <linux/nsproxy.h> 62#include <linux/nsproxy.h>
63#include <linux/virtio_net.h> 63#include <linux/virtio_net.h>
64#include <linux/rcupdate.h>
64#include <net/net_namespace.h> 65#include <net/net_namespace.h>
65#include <net/netns/generic.h> 66#include <net/netns/generic.h>
66#include <net/rtnetlink.h> 67#include <net/rtnetlink.h>
@@ -144,6 +145,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file)
144 err = 0; 145 err = 0;
145 tfile->tun = tun; 146 tfile->tun = tun;
146 tun->tfile = tfile; 147 tun->tfile = tfile;
148 tun->socket.file = file;
147 dev_hold(tun->dev); 149 dev_hold(tun->dev);
148 sock_hold(tun->socket.sk); 150 sock_hold(tun->socket.sk);
149 atomic_inc(&tfile->count); 151 atomic_inc(&tfile->count);
@@ -158,6 +160,7 @@ static void __tun_detach(struct tun_struct *tun)
158 /* Detach from net device */ 160 /* Detach from net device */
159 netif_tx_lock_bh(tun->dev); 161 netif_tx_lock_bh(tun->dev);
160 tun->tfile = NULL; 162 tun->tfile = NULL;
163 tun->socket.file = NULL;
161 netif_tx_unlock_bh(tun->dev); 164 netif_tx_unlock_bh(tun->dev);
162 165
163 /* Drop read queue */ 166 /* Drop read queue */
@@ -364,6 +367,10 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
364 if (!check_filter(&tun->txflt, skb)) 367 if (!check_filter(&tun->txflt, skb))
365 goto drop; 368 goto drop;
366 369
370 if (tun->socket.sk->sk_filter &&
371 sk_filter(tun->socket.sk, skb))
372 goto drop;
373
367 if (skb_queue_len(&tun->socket.sk->sk_receive_queue) >= dev->tx_queue_len) { 374 if (skb_queue_len(&tun->socket.sk->sk_receive_queue) >= dev->tx_queue_len) {
368 if (!(tun->flags & TUN_ONE_QUEUE)) { 375 if (!(tun->flags & TUN_ONE_QUEUE)) {
369 /* Normal queueing mode. */ 376 /* Normal queueing mode. */
@@ -380,6 +387,10 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
380 } 387 }
381 } 388 }
382 389
390 /* Orphan the skb - required as we might hang on to it
391 * for indefinite time. */
392 skb_orphan(skb);
393
383 /* Enqueue packet */ 394 /* Enqueue packet */
384 skb_queue_tail(&tun->socket.sk->sk_receive_queue, skb); 395 skb_queue_tail(&tun->socket.sk->sk_receive_queue, skb);
385 dev->trans_start = jiffies; 396 dev->trans_start = jiffies;
@@ -387,7 +398,8 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
387 /* Notify and wake up reader process */ 398 /* Notify and wake up reader process */
388 if (tun->flags & TUN_FASYNC) 399 if (tun->flags & TUN_FASYNC)
389 kill_fasync(&tun->fasync, SIGIO, POLL_IN); 400 kill_fasync(&tun->fasync, SIGIO, POLL_IN);
390 wake_up_interruptible(&tun->socket.wait); 401 wake_up_interruptible_poll(&tun->socket.wait, POLLIN |
402 POLLRDNORM | POLLRDBAND);
391 return NETDEV_TX_OK; 403 return NETDEV_TX_OK;
392 404
393drop: 405drop:
@@ -743,7 +755,7 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
743 len = min_t(int, skb->len, len); 755 len = min_t(int, skb->len, len);
744 756
745 skb_copy_datagram_const_iovec(skb, 0, iv, total, len); 757 skb_copy_datagram_const_iovec(skb, 0, iv, total, len);
746 total += len; 758 total += skb->len;
747 759
748 tun->dev->stats.tx_packets++; 760 tun->dev->stats.tx_packets++;
749 tun->dev->stats.tx_bytes += len; 761 tun->dev->stats.tx_bytes += len;
@@ -751,34 +763,23 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
751 return total; 763 return total;
752} 764}
753 765
754static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv, 766static ssize_t tun_do_read(struct tun_struct *tun,
755 unsigned long count, loff_t pos) 767 struct kiocb *iocb, const struct iovec *iv,
768 ssize_t len, int noblock)
756{ 769{
757 struct file *file = iocb->ki_filp;
758 struct tun_file *tfile = file->private_data;
759 struct tun_struct *tun = __tun_get(tfile);
760 DECLARE_WAITQUEUE(wait, current); 770 DECLARE_WAITQUEUE(wait, current);
761 struct sk_buff *skb; 771 struct sk_buff *skb;
762 ssize_t len, ret = 0; 772 ssize_t ret = 0;
763
764 if (!tun)
765 return -EBADFD;
766 773
767 DBG(KERN_INFO "%s: tun_chr_read\n", tun->dev->name); 774 DBG(KERN_INFO "%s: tun_chr_read\n", tun->dev->name);
768 775
769 len = iov_length(iv, count);
770 if (len < 0) {
771 ret = -EINVAL;
772 goto out;
773 }
774
775 add_wait_queue(&tun->socket.wait, &wait); 776 add_wait_queue(&tun->socket.wait, &wait);
776 while (len) { 777 while (len) {
777 current->state = TASK_INTERRUPTIBLE; 778 current->state = TASK_INTERRUPTIBLE;
778 779
779 /* Read frames from the queue */ 780 /* Read frames from the queue */
780 if (!(skb=skb_dequeue(&tun->socket.sk->sk_receive_queue))) { 781 if (!(skb=skb_dequeue(&tun->socket.sk->sk_receive_queue))) {
781 if (file->f_flags & O_NONBLOCK) { 782 if (noblock) {
782 ret = -EAGAIN; 783 ret = -EAGAIN;
783 break; 784 break;
784 } 785 }
@@ -805,6 +806,27 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
805 current->state = TASK_RUNNING; 806 current->state = TASK_RUNNING;
806 remove_wait_queue(&tun->socket.wait, &wait); 807 remove_wait_queue(&tun->socket.wait, &wait);
807 808
809 return ret;
810}
811
812static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
813 unsigned long count, loff_t pos)
814{
815 struct file *file = iocb->ki_filp;
816 struct tun_file *tfile = file->private_data;
817 struct tun_struct *tun = __tun_get(tfile);
818 ssize_t len, ret;
819
820 if (!tun)
821 return -EBADFD;
822 len = iov_length(iv, count);
823 if (len < 0) {
824 ret = -EINVAL;
825 goto out;
826 }
827
828 ret = tun_do_read(tun, iocb, iv, len, file->f_flags & O_NONBLOCK);
829 ret = min_t(ssize_t, ret, len);
808out: 830out:
809 tun_put(tun); 831 tun_put(tun);
810 return ret; 832 return ret;
@@ -847,17 +869,49 @@ static void tun_sock_write_space(struct sock *sk)
847 return; 869 return;
848 870
849 if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) 871 if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
850 wake_up_interruptible_sync(sk->sk_sleep); 872 wake_up_interruptible_sync_poll(sk->sk_sleep, POLLOUT |
873 POLLWRNORM | POLLWRBAND);
851 874
852 tun = container_of(sk, struct tun_sock, sk)->tun; 875 tun = tun_sk(sk)->tun;
853 kill_fasync(&tun->fasync, SIGIO, POLL_OUT); 876 kill_fasync(&tun->fasync, SIGIO, POLL_OUT);
854} 877}
855 878
856static void tun_sock_destruct(struct sock *sk) 879static void tun_sock_destruct(struct sock *sk)
857{ 880{
858 free_netdev(container_of(sk, struct tun_sock, sk)->tun->dev); 881 free_netdev(tun_sk(sk)->tun->dev);
882}
883
884static int tun_sendmsg(struct kiocb *iocb, struct socket *sock,
885 struct msghdr *m, size_t total_len)
886{
887 struct tun_struct *tun = container_of(sock, struct tun_struct, socket);
888 return tun_get_user(tun, m->msg_iov, total_len,
889 m->msg_flags & MSG_DONTWAIT);
890}
891
892static int tun_recvmsg(struct kiocb *iocb, struct socket *sock,
893 struct msghdr *m, size_t total_len,
894 int flags)
895{
896 struct tun_struct *tun = container_of(sock, struct tun_struct, socket);
897 int ret;
898 if (flags & ~(MSG_DONTWAIT|MSG_TRUNC))
899 return -EINVAL;
900 ret = tun_do_read(tun, iocb, m->msg_iov, total_len,
901 flags & MSG_DONTWAIT);
902 if (ret > total_len) {
903 m->msg_flags |= MSG_TRUNC;
904 ret = flags & MSG_TRUNC ? ret : total_len;
905 }
906 return ret;
859} 907}
860 908
909/* Ops structure to mimic raw sockets with tun */
910static const struct proto_ops tun_socket_ops = {
911 .sendmsg = tun_sendmsg,
912 .recvmsg = tun_recvmsg,
913};
914
861static struct proto tun_proto = { 915static struct proto tun_proto = {
862 .name = "tun", 916 .name = "tun",
863 .owner = THIS_MODULE, 917 .owner = THIS_MODULE,
@@ -986,11 +1040,12 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
986 goto err_free_dev; 1040 goto err_free_dev;
987 1041
988 init_waitqueue_head(&tun->socket.wait); 1042 init_waitqueue_head(&tun->socket.wait);
1043 tun->socket.ops = &tun_socket_ops;
989 sock_init_data(&tun->socket, sk); 1044 sock_init_data(&tun->socket, sk);
990 sk->sk_write_space = tun_sock_write_space; 1045 sk->sk_write_space = tun_sock_write_space;
991 sk->sk_sndbuf = INT_MAX; 1046 sk->sk_sndbuf = INT_MAX;
992 1047
993 container_of(sk, struct tun_sock, sk)->tun = tun; 1048 tun_sk(sk)->tun = tun;
994 1049
995 security_tun_dev_post_create(sk); 1050 security_tun_dev_post_create(sk);
996 1051
@@ -1110,18 +1165,19 @@ static int set_offload(struct net_device *dev, unsigned long arg)
1110 return 0; 1165 return 0;
1111} 1166}
1112 1167
1113static long tun_chr_ioctl(struct file *file, unsigned int cmd, 1168static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
1114 unsigned long arg) 1169 unsigned long arg, int ifreq_len)
1115{ 1170{
1116 struct tun_file *tfile = file->private_data; 1171 struct tun_file *tfile = file->private_data;
1117 struct tun_struct *tun; 1172 struct tun_struct *tun;
1118 void __user* argp = (void __user*)arg; 1173 void __user* argp = (void __user*)arg;
1174 struct sock_fprog fprog;
1119 struct ifreq ifr; 1175 struct ifreq ifr;
1120 int sndbuf; 1176 int sndbuf;
1121 int ret; 1177 int ret;
1122 1178
1123 if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89) 1179 if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89)
1124 if (copy_from_user(&ifr, argp, sizeof ifr)) 1180 if (copy_from_user(&ifr, argp, ifreq_len))
1125 return -EFAULT; 1181 return -EFAULT;
1126 1182
1127 if (cmd == TUNGETFEATURES) { 1183 if (cmd == TUNGETFEATURES) {
@@ -1144,7 +1200,7 @@ static long tun_chr_ioctl(struct file *file, unsigned int cmd,
1144 if (ret) 1200 if (ret)
1145 goto unlock; 1201 goto unlock;
1146 1202
1147 if (copy_to_user(argp, &ifr, sizeof(ifr))) 1203 if (copy_to_user(argp, &ifr, ifreq_len))
1148 ret = -EFAULT; 1204 ret = -EFAULT;
1149 goto unlock; 1205 goto unlock;
1150 } 1206 }
@@ -1162,7 +1218,7 @@ static long tun_chr_ioctl(struct file *file, unsigned int cmd,
1162 if (ret) 1218 if (ret)
1163 break; 1219 break;
1164 1220
1165 if (copy_to_user(argp, &ifr, sizeof(ifr))) 1221 if (copy_to_user(argp, &ifr, ifreq_len))
1166 ret = -EFAULT; 1222 ret = -EFAULT;
1167 break; 1223 break;
1168 1224
@@ -1236,7 +1292,7 @@ static long tun_chr_ioctl(struct file *file, unsigned int cmd,
1236 /* Get hw addres */ 1292 /* Get hw addres */
1237 memcpy(ifr.ifr_hwaddr.sa_data, tun->dev->dev_addr, ETH_ALEN); 1293 memcpy(ifr.ifr_hwaddr.sa_data, tun->dev->dev_addr, ETH_ALEN);
1238 ifr.ifr_hwaddr.sa_family = tun->dev->type; 1294 ifr.ifr_hwaddr.sa_family = tun->dev->type;
1239 if (copy_to_user(argp, &ifr, sizeof ifr)) 1295 if (copy_to_user(argp, &ifr, ifreq_len))
1240 ret = -EFAULT; 1296 ret = -EFAULT;
1241 break; 1297 break;
1242 1298
@@ -1263,6 +1319,26 @@ static long tun_chr_ioctl(struct file *file, unsigned int cmd,
1263 tun->socket.sk->sk_sndbuf = sndbuf; 1319 tun->socket.sk->sk_sndbuf = sndbuf;
1264 break; 1320 break;
1265 1321
1322 case TUNATTACHFILTER:
1323 /* Can be set only for TAPs */
1324 ret = -EINVAL;
1325 if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV)
1326 break;
1327 ret = -EFAULT;
1328 if (copy_from_user(&fprog, argp, sizeof(fprog)))
1329 break;
1330
1331 ret = sk_attach_filter(&fprog, tun->socket.sk);
1332 break;
1333
1334 case TUNDETACHFILTER:
1335 /* Can be set only for TAPs */
1336 ret = -EINVAL;
1337 if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV)
1338 break;
1339 ret = sk_detach_filter(tun->socket.sk);
1340 break;
1341
1266 default: 1342 default:
1267 ret = -EINVAL; 1343 ret = -EINVAL;
1268 break; 1344 break;
@@ -1275,6 +1351,41 @@ unlock:
1275 return ret; 1351 return ret;
1276} 1352}
1277 1353
1354static long tun_chr_ioctl(struct file *file,
1355 unsigned int cmd, unsigned long arg)
1356{
1357 return __tun_chr_ioctl(file, cmd, arg, sizeof (struct ifreq));
1358}
1359
1360#ifdef CONFIG_COMPAT
1361static long tun_chr_compat_ioctl(struct file *file,
1362 unsigned int cmd, unsigned long arg)
1363{
1364 switch (cmd) {
1365 case TUNSETIFF:
1366 case TUNGETIFF:
1367 case TUNSETTXFILTER:
1368 case TUNGETSNDBUF:
1369 case TUNSETSNDBUF:
1370 case SIOCGIFHWADDR:
1371 case SIOCSIFHWADDR:
1372 arg = (unsigned long)compat_ptr(arg);
1373 break;
1374 default:
1375 arg = (compat_ulong_t)arg;
1376 break;
1377 }
1378
1379 /*
1380 * compat_ifreq is shorter than ifreq, so we must not access beyond
1381 * the end of that structure. All fields that are used in this
1382 * driver are compatible though, we don't need to convert the
1383 * contents.
1384 */
1385 return __tun_chr_ioctl(file, cmd, arg, sizeof(struct compat_ifreq));
1386}
1387#endif /* CONFIG_COMPAT */
1388
1278static int tun_chr_fasync(int fd, struct file *file, int on) 1389static int tun_chr_fasync(int fd, struct file *file, int on)
1279{ 1390{
1280 struct tun_struct *tun = tun_get(file); 1391 struct tun_struct *tun = tun_get(file);
@@ -1285,7 +1396,6 @@ static int tun_chr_fasync(int fd, struct file *file, int on)
1285 1396
1286 DBG(KERN_INFO "%s: tun_chr_fasync %d\n", tun->dev->name, on); 1397 DBG(KERN_INFO "%s: tun_chr_fasync %d\n", tun->dev->name, on);
1287 1398
1288 lock_kernel();
1289 if ((ret = fasync_helper(fd, file, on, &tun->fasync)) < 0) 1399 if ((ret = fasync_helper(fd, file, on, &tun->fasync)) < 0)
1290 goto out; 1400 goto out;
1291 1401
@@ -1298,7 +1408,6 @@ static int tun_chr_fasync(int fd, struct file *file, int on)
1298 tun->flags &= ~TUN_FASYNC; 1408 tun->flags &= ~TUN_FASYNC;
1299 ret = 0; 1409 ret = 0;
1300out: 1410out:
1301 unlock_kernel();
1302 tun_put(tun); 1411 tun_put(tun);
1303 return ret; 1412 return ret;
1304} 1413}
@@ -1306,7 +1415,7 @@ out:
1306static int tun_chr_open(struct inode *inode, struct file * file) 1415static int tun_chr_open(struct inode *inode, struct file * file)
1307{ 1416{
1308 struct tun_file *tfile; 1417 struct tun_file *tfile;
1309 cycle_kernel_lock(); 1418
1310 DBG1(KERN_INFO "tunX: tun_chr_open\n"); 1419 DBG1(KERN_INFO "tunX: tun_chr_open\n");
1311 1420
1312 tfile = kmalloc(sizeof(*tfile), GFP_KERNEL); 1421 tfile = kmalloc(sizeof(*tfile), GFP_KERNEL);
@@ -1332,7 +1441,7 @@ static int tun_chr_close(struct inode *inode, struct file *file)
1332 1441
1333 __tun_detach(tun); 1442 __tun_detach(tun);
1334 1443
1335 /* If desireable, unregister the netdevice. */ 1444 /* If desirable, unregister the netdevice. */
1336 if (!(tun->flags & TUN_PERSIST)) { 1445 if (!(tun->flags & TUN_PERSIST)) {
1337 rtnl_lock(); 1446 rtnl_lock();
1338 if (dev->reg_state == NETREG_REGISTERED) 1447 if (dev->reg_state == NETREG_REGISTERED)
@@ -1359,7 +1468,10 @@ static const struct file_operations tun_fops = {
1359 .write = do_sync_write, 1468 .write = do_sync_write,
1360 .aio_write = tun_chr_aio_write, 1469 .aio_write = tun_chr_aio_write,
1361 .poll = tun_chr_poll, 1470 .poll = tun_chr_poll,
1362 .unlocked_ioctl = tun_chr_ioctl, 1471 .unlocked_ioctl = tun_chr_ioctl,
1472#ifdef CONFIG_COMPAT
1473 .compat_ioctl = tun_chr_compat_ioctl,
1474#endif
1363 .open = tun_chr_open, 1475 .open = tun_chr_open,
1364 .release = tun_chr_close, 1476 .release = tun_chr_close,
1365 .fasync = tun_chr_fasync 1477 .fasync = tun_chr_fasync
@@ -1489,6 +1601,23 @@ static void tun_cleanup(void)
1489 rtnl_link_unregister(&tun_link_ops); 1601 rtnl_link_unregister(&tun_link_ops);
1490} 1602}
1491 1603
1604/* Get an underlying socket object from tun file. Returns error unless file is
1605 * attached to a device. The returned object works like a packet socket, it
1606 * can be used for sock_sendmsg/sock_recvmsg. The caller is responsible for
1607 * holding a reference to the file for as long as the socket is in use. */
1608struct socket *tun_get_socket(struct file *file)
1609{
1610 struct tun_struct *tun;
1611 if (file->f_op != &tun_fops)
1612 return ERR_PTR(-EINVAL);
1613 tun = tun_get(file);
1614 if (!tun)
1615 return ERR_PTR(-EBADFD);
1616 tun_put(tun);
1617 return &tun->socket;
1618}
1619EXPORT_SYMBOL_GPL(tun_get_socket);
1620
1492module_init(tun_init); 1621module_init(tun_init);
1493module_exit(tun_cleanup); 1622module_exit(tun_cleanup);
1494MODULE_DESCRIPTION(DRV_DESCRIPTION); 1623MODULE_DESCRIPTION(DRV_DESCRIPTION);