aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/tun.c156
1 files changed, 104 insertions, 52 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 8743de9d2572..d3a665d2f7b8 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -87,9 +87,13 @@ struct tap_filter {
87 unsigned char addr[FLT_EXACT_COUNT][ETH_ALEN]; 87 unsigned char addr[FLT_EXACT_COUNT][ETH_ALEN];
88}; 88};
89 89
90struct tun_file {
91 struct tun_struct *tun;
92};
93
90struct tun_struct { 94struct tun_struct {
95 struct tun_file *tfile;
91 unsigned int flags; 96 unsigned int flags;
92 int attached;
93 uid_t owner; 97 uid_t owner;
94 gid_t group; 98 gid_t group;
95 99
@@ -108,14 +112,15 @@ struct tun_struct {
108 112
109static int tun_attach(struct tun_struct *tun, struct file *file) 113static int tun_attach(struct tun_struct *tun, struct file *file)
110{ 114{
115 struct tun_file *tfile = file->private_data;
111 const struct cred *cred = current_cred(); 116 const struct cred *cred = current_cred();
112 117
113 ASSERT_RTNL(); 118 ASSERT_RTNL();
114 119
115 if (file->private_data) 120 if (tfile->tun)
116 return -EINVAL; 121 return -EINVAL;
117 122
118 if (tun->attached) 123 if (tun->tfile)
119 return -EBUSY; 124 return -EBUSY;
120 125
121 /* Check permissions */ 126 /* Check permissions */
@@ -124,13 +129,41 @@ static int tun_attach(struct tun_struct *tun, struct file *file)
124 !capable(CAP_NET_ADMIN)) 129 !capable(CAP_NET_ADMIN))
125 return -EPERM; 130 return -EPERM;
126 131
127 file->private_data = tun; 132 tfile->tun = tun;
128 tun->attached = 1; 133 tun->tfile = tfile;
129 get_net(dev_net(tun->dev)); 134 get_net(dev_net(tun->dev));
130 135
131 return 0; 136 return 0;
132} 137}
133 138
139static void __tun_detach(struct tun_struct *tun)
140{
141 struct tun_file *tfile = tun->tfile;
142
143 /* Detach from net device */
144 tfile->tun = NULL;
145 tun->tfile = NULL;
146 put_net(dev_net(tun->dev));
147
148 /* Drop read queue */
149 skb_queue_purge(&tun->readq);
150}
151
152static struct tun_struct *__tun_get(struct tun_file *tfile)
153{
154 return tfile->tun;
155}
156
157static struct tun_struct *tun_get(struct file *file)
158{
159 return __tun_get(file->private_data);
160}
161
162static void tun_put(struct tun_struct *tun)
163{
164 /* Noop for now */
165}
166
134/* TAP filterting */ 167/* TAP filterting */
135static void addr_hash_set(u32 *mask, const u8 *addr) 168static void addr_hash_set(u32 *mask, const u8 *addr)
136{ 169{
@@ -261,7 +294,7 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
261 DBG(KERN_INFO "%s: tun_net_xmit %d\n", tun->dev->name, skb->len); 294 DBG(KERN_INFO "%s: tun_net_xmit %d\n", tun->dev->name, skb->len);
262 295
263 /* Drop packet if interface is not attached */ 296 /* Drop packet if interface is not attached */
264 if (!tun->attached) 297 if (!tun->tfile)
265 goto drop; 298 goto drop;
266 299
267 /* Drop if the filter does not like it. 300 /* Drop if the filter does not like it.
@@ -378,7 +411,7 @@ static void tun_net_init(struct net_device *dev)
378/* Poll */ 411/* Poll */
379static unsigned int tun_chr_poll(struct file *file, poll_table * wait) 412static unsigned int tun_chr_poll(struct file *file, poll_table * wait)
380{ 413{
381 struct tun_struct *tun = file->private_data; 414 struct tun_struct *tun = tun_get(file);
382 unsigned int mask = POLLOUT | POLLWRNORM; 415 unsigned int mask = POLLOUT | POLLWRNORM;
383 416
384 if (!tun) 417 if (!tun)
@@ -391,6 +424,7 @@ static unsigned int tun_chr_poll(struct file *file, poll_table * wait)
391 if (!skb_queue_empty(&tun->readq)) 424 if (!skb_queue_empty(&tun->readq))
392 mask |= POLLIN | POLLRDNORM; 425 mask |= POLLIN | POLLRDNORM;
393 426
427 tun_put(tun);
394 return mask; 428 return mask;
395} 429}
396 430
@@ -575,14 +609,18 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
575static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv, 609static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
576 unsigned long count, loff_t pos) 610 unsigned long count, loff_t pos)
577{ 611{
578 struct tun_struct *tun = iocb->ki_filp->private_data; 612 struct tun_struct *tun = tun_get(iocb->ki_filp);
613 ssize_t result;
579 614
580 if (!tun) 615 if (!tun)
581 return -EBADFD; 616 return -EBADFD;
582 617
583 DBG(KERN_INFO "%s: tun_chr_write %ld\n", tun->dev->name, count); 618 DBG(KERN_INFO "%s: tun_chr_write %ld\n", tun->dev->name, count);
584 619
585 return tun_get_user(tun, (struct iovec *) iv, iov_length(iv, count)); 620 result = tun_get_user(tun, (struct iovec *) iv, iov_length(iv, count));
621
622 tun_put(tun);
623 return result;
586} 624}
587 625
588/* Put packet to the user space buffer */ 626/* Put packet to the user space buffer */
@@ -655,7 +693,7 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
655 unsigned long count, loff_t pos) 693 unsigned long count, loff_t pos)
656{ 694{
657 struct file *file = iocb->ki_filp; 695 struct file *file = iocb->ki_filp;
658 struct tun_struct *tun = file->private_data; 696 struct tun_struct *tun = tun_get(file);
659 DECLARE_WAITQUEUE(wait, current); 697 DECLARE_WAITQUEUE(wait, current);
660 struct sk_buff *skb; 698 struct sk_buff *skb;
661 ssize_t len, ret = 0; 699 ssize_t len, ret = 0;
@@ -666,8 +704,10 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
666 DBG(KERN_INFO "%s: tun_chr_read\n", tun->dev->name); 704 DBG(KERN_INFO "%s: tun_chr_read\n", tun->dev->name);
667 705
668 len = iov_length(iv, count); 706 len = iov_length(iv, count);
669 if (len < 0) 707 if (len < 0) {
670 return -EINVAL; 708 ret = -EINVAL;
709 goto out;
710 }
671 711
672 add_wait_queue(&tun->read_wait, &wait); 712 add_wait_queue(&tun->read_wait, &wait);
673 while (len) { 713 while (len) {
@@ -698,6 +738,8 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
698 current->state = TASK_RUNNING; 738 current->state = TASK_RUNNING;
699 remove_wait_queue(&tun->read_wait, &wait); 739 remove_wait_queue(&tun->read_wait, &wait);
700 740
741out:
742 tun_put(tun);
701 return ret; 743 return ret;
702} 744}
703 745
@@ -822,7 +864,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
822 864
823static int tun_get_iff(struct net *net, struct file *file, struct ifreq *ifr) 865static int tun_get_iff(struct net *net, struct file *file, struct ifreq *ifr)
824{ 866{
825 struct tun_struct *tun = file->private_data; 867 struct tun_struct *tun = tun_get(file);
826 868
827 if (!tun) 869 if (!tun)
828 return -EBADFD; 870 return -EBADFD;
@@ -847,6 +889,7 @@ static int tun_get_iff(struct net *net, struct file *file, struct ifreq *ifr)
847 if (tun->flags & TUN_VNET_HDR) 889 if (tun->flags & TUN_VNET_HDR)
848 ifr->ifr_flags |= IFF_VNET_HDR; 890 ifr->ifr_flags |= IFF_VNET_HDR;
849 891
892 tun_put(tun);
850 return 0; 893 return 0;
851} 894}
852 895
@@ -893,7 +936,7 @@ static int set_offload(struct net_device *dev, unsigned long arg)
893static int tun_chr_ioctl(struct inode *inode, struct file *file, 936static int tun_chr_ioctl(struct inode *inode, struct file *file,
894 unsigned int cmd, unsigned long arg) 937 unsigned int cmd, unsigned long arg)
895{ 938{
896 struct tun_struct *tun = file->private_data; 939 struct tun_struct *tun;
897 void __user* argp = (void __user*)arg; 940 void __user* argp = (void __user*)arg;
898 struct ifreq ifr; 941 struct ifreq ifr;
899 int ret; 942 int ret;
@@ -902,6 +945,16 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
902 if (copy_from_user(&ifr, argp, sizeof ifr)) 945 if (copy_from_user(&ifr, argp, sizeof ifr))
903 return -EFAULT; 946 return -EFAULT;
904 947
948 if (cmd == TUNGETFEATURES) {
949 /* Currently this just means: "what IFF flags are valid?".
950 * This is needed because we never checked for invalid flags on
951 * TUNSETIFF. */
952 return put_user(IFF_TUN | IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE |
953 IFF_VNET_HDR,
954 (unsigned int __user*)argp);
955 }
956
957 tun = tun_get(file);
905 if (cmd == TUNSETIFF && !tun) { 958 if (cmd == TUNSETIFF && !tun) {
906 int err; 959 int err;
907 960
@@ -919,28 +972,21 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
919 return 0; 972 return 0;
920 } 973 }
921 974
922 if (cmd == TUNGETFEATURES) {
923 /* Currently this just means: "what IFF flags are valid?".
924 * This is needed because we never checked for invalid flags on
925 * TUNSETIFF. */
926 return put_user(IFF_TUN | IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE |
927 IFF_VNET_HDR,
928 (unsigned int __user*)argp);
929 }
930 975
931 if (!tun) 976 if (!tun)
932 return -EBADFD; 977 return -EBADFD;
933 978
934 DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->dev->name, cmd); 979 DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->dev->name, cmd);
935 980
981 ret = 0;
936 switch (cmd) { 982 switch (cmd) {
937 case TUNGETIFF: 983 case TUNGETIFF:
938 ret = tun_get_iff(current->nsproxy->net_ns, file, &ifr); 984 ret = tun_get_iff(current->nsproxy->net_ns, file, &ifr);
939 if (ret) 985 if (ret)
940 return ret; 986 break;
941 987
942 if (copy_to_user(argp, &ifr, sizeof(ifr))) 988 if (copy_to_user(argp, &ifr, sizeof(ifr)))
943 return -EFAULT; 989 ret = -EFAULT;
944 break; 990 break;
945 991
946 case TUNSETNOCSUM: 992 case TUNSETNOCSUM:
@@ -992,7 +1038,7 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
992 ret = 0; 1038 ret = 0;
993 } 1039 }
994 rtnl_unlock(); 1040 rtnl_unlock();
995 return ret; 1041 break;
996 1042
997#ifdef TUN_DEBUG 1043#ifdef TUN_DEBUG
998 case TUNSETDEBUG: 1044 case TUNSETDEBUG:
@@ -1003,24 +1049,25 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
1003 rtnl_lock(); 1049 rtnl_lock();
1004 ret = set_offload(tun->dev, arg); 1050 ret = set_offload(tun->dev, arg);
1005 rtnl_unlock(); 1051 rtnl_unlock();
1006 return ret; 1052 break;
1007 1053
1008 case TUNSETTXFILTER: 1054 case TUNSETTXFILTER:
1009 /* Can be set only for TAPs */ 1055 /* Can be set only for TAPs */
1056 ret = -EINVAL;
1010 if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV) 1057 if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV)
1011 return -EINVAL; 1058 break;
1012 rtnl_lock(); 1059 rtnl_lock();
1013 ret = update_filter(&tun->txflt, (void __user *)arg); 1060 ret = update_filter(&tun->txflt, (void __user *)arg);
1014 rtnl_unlock(); 1061 rtnl_unlock();
1015 return ret; 1062 break;
1016 1063
1017 case SIOCGIFHWADDR: 1064 case SIOCGIFHWADDR:
1018 /* Get hw addres */ 1065 /* Get hw addres */
1019 memcpy(ifr.ifr_hwaddr.sa_data, tun->dev->dev_addr, ETH_ALEN); 1066 memcpy(ifr.ifr_hwaddr.sa_data, tun->dev->dev_addr, ETH_ALEN);
1020 ifr.ifr_hwaddr.sa_family = tun->dev->type; 1067 ifr.ifr_hwaddr.sa_family = tun->dev->type;
1021 if (copy_to_user(argp, &ifr, sizeof ifr)) 1068 if (copy_to_user(argp, &ifr, sizeof ifr))
1022 return -EFAULT; 1069 ret = -EFAULT;
1023 return 0; 1070 break;
1024 1071
1025 case SIOCSIFHWADDR: 1072 case SIOCSIFHWADDR:
1026 /* Set hw address */ 1073 /* Set hw address */
@@ -1030,18 +1077,19 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
1030 rtnl_lock(); 1077 rtnl_lock();
1031 ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr); 1078 ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr);
1032 rtnl_unlock(); 1079 rtnl_unlock();
1033 return ret; 1080 break;
1034
1035 default: 1081 default:
1036 return -EINVAL; 1082 ret = -EINVAL;
1083 break;
1037 }; 1084 };
1038 1085
1039 return 0; 1086 tun_put(tun);
1087 return ret;
1040} 1088}
1041 1089
1042static int tun_chr_fasync(int fd, struct file *file, int on) 1090static int tun_chr_fasync(int fd, struct file *file, int on)
1043{ 1091{
1044 struct tun_struct *tun = file->private_data; 1092 struct tun_struct *tun = tun_get(file);
1045 int ret; 1093 int ret;
1046 1094
1047 if (!tun) 1095 if (!tun)
@@ -1063,40 +1111,44 @@ static int tun_chr_fasync(int fd, struct file *file, int on)
1063 ret = 0; 1111 ret = 0;
1064out: 1112out:
1065 unlock_kernel(); 1113 unlock_kernel();
1114 tun_put(tun);
1066 return ret; 1115 return ret;
1067} 1116}
1068 1117
1069static int tun_chr_open(struct inode *inode, struct file * file) 1118static int tun_chr_open(struct inode *inode, struct file * file)
1070{ 1119{
1120 struct tun_file *tfile;
1071 cycle_kernel_lock(); 1121 cycle_kernel_lock();
1072 DBG1(KERN_INFO "tunX: tun_chr_open\n"); 1122 DBG1(KERN_INFO "tunX: tun_chr_open\n");
1073 file->private_data = NULL; 1123
1124 tfile = kmalloc(sizeof(*tfile), GFP_KERNEL);
1125 if (!tfile)
1126 return -ENOMEM;
1127 tfile->tun = NULL;
1128 file->private_data = tfile;
1074 return 0; 1129 return 0;
1075} 1130}
1076 1131
1077static int tun_chr_close(struct inode *inode, struct file *file) 1132static int tun_chr_close(struct inode *inode, struct file *file)
1078{ 1133{
1079 struct tun_struct *tun = file->private_data; 1134 struct tun_file *tfile = file->private_data;
1080 1135 struct tun_struct *tun = __tun_get(tfile);
1081 if (!tun)
1082 return 0;
1083 1136
1084 DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name);
1085 1137
1086 rtnl_lock(); 1138 if (tun) {
1139 DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name);
1087 1140
1088 /* Detach from net device */ 1141 rtnl_lock();
1089 file->private_data = NULL; 1142 __tun_detach(tun);
1090 tun->attached = 0;
1091 put_net(dev_net(tun->dev));
1092 1143
1093 /* Drop read queue */ 1144 /* If desireable, unregister the netdevice. */
1094 skb_queue_purge(&tun->readq); 1145 if (!(tun->flags & TUN_PERSIST))
1146 unregister_netdevice(tun->dev);
1095 1147
1096 if (!(tun->flags & TUN_PERSIST)) 1148 rtnl_unlock();
1097 unregister_netdevice(tun->dev); 1149 }
1098 1150
1099 rtnl_unlock(); 1151 kfree(tfile);
1100 1152
1101 return 0; 1153 return 0;
1102} 1154}
@@ -1177,7 +1229,7 @@ static void tun_set_msglevel(struct net_device *dev, u32 value)
1177static u32 tun_get_link(struct net_device *dev) 1229static u32 tun_get_link(struct net_device *dev)
1178{ 1230{
1179 struct tun_struct *tun = netdev_priv(dev); 1231 struct tun_struct *tun = netdev_priv(dev);
1180 return tun->attached; 1232 return !!tun->tfile;
1181} 1233}
1182 1234
1183static u32 tun_get_rx_csum(struct net_device *dev) 1235static u32 tun_get_rx_csum(struct net_device *dev)