@@ -144,6 +144,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file)
144144 err = 0 ;
145145 tfile -> tun = tun ;
146146 tun -> tfile = tfile ;
147+ tun -> socket .file = file ;
147148 dev_hold (tun -> dev );
148149 sock_hold (tun -> socket .sk );
149150 atomic_inc (& tfile -> count );
@@ -158,6 +159,7 @@ static void __tun_detach(struct tun_struct *tun)
158159 /* Detach from net device */
159160 netif_tx_lock_bh (tun -> dev );
160161 tun -> tfile = NULL ;
162+ tun -> socket .file = NULL ;
161163 netif_tx_unlock_bh (tun -> dev );
162164
163165 /* Drop read queue */
@@ -387,7 +389,8 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
387389 /* Notify and wake up reader process */
388390 if (tun -> flags & TUN_FASYNC )
389391 kill_fasync (& tun -> fasync , SIGIO , POLL_IN );
390- wake_up_interruptible (& tun -> socket .wait );
392+ wake_up_interruptible_poll (& tun -> socket .wait , POLLIN |
393+ POLLRDNORM | POLLRDBAND );
391394 return NETDEV_TX_OK ;
392395
393396drop :
@@ -743,42 +746,31 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
743746 len = min_t (int , skb -> len , len );
744747
745748 skb_copy_datagram_const_iovec (skb , 0 , iv , total , len );
746- total += len ;
749+ total += skb -> len ;
747750
748751 tun -> dev -> stats .tx_packets ++ ;
749752 tun -> dev -> stats .tx_bytes += len ;
750753
751754 return total ;
752755}
753756
754- static ssize_t tun_chr_aio_read (struct kiocb * iocb , const struct iovec * iv ,
755- unsigned long count , loff_t pos )
757+ static ssize_t tun_do_read (struct tun_struct * tun ,
758+ struct kiocb * iocb , const struct iovec * iv ,
759+ ssize_t len , int noblock )
756760{
757- struct file * file = iocb -> ki_filp ;
758- struct tun_file * tfile = file -> private_data ;
759- struct tun_struct * tun = __tun_get (tfile );
760761 DECLARE_WAITQUEUE (wait , current );
761762 struct sk_buff * skb ;
762- ssize_t len , ret = 0 ;
763-
764- if (!tun )
765- return - EBADFD ;
763+ ssize_t ret = 0 ;
766764
767765 DBG (KERN_INFO "%s: tun_chr_read\n" , tun -> dev -> name );
768766
769- len = iov_length (iv , count );
770- if (len < 0 ) {
771- ret = - EINVAL ;
772- goto out ;
773- }
774-
775767 add_wait_queue (& tun -> socket .wait , & wait );
776768 while (len ) {
777769 current -> state = TASK_INTERRUPTIBLE ;
778770
779771 /* Read frames from the queue */
780772 if (!(skb = skb_dequeue (& tun -> socket .sk -> sk_receive_queue ))) {
781- if (file -> f_flags & O_NONBLOCK ) {
773+ if (noblock ) {
782774 ret = - EAGAIN ;
783775 break ;
784776 }
@@ -805,6 +797,27 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
805797 current -> state = TASK_RUNNING ;
806798 remove_wait_queue (& tun -> socket .wait , & wait );
807799
800+ return ret ;
801+ }
802+
803+ static ssize_t tun_chr_aio_read (struct kiocb * iocb , const struct iovec * iv ,
804+ unsigned long count , loff_t pos )
805+ {
806+ struct file * file = iocb -> ki_filp ;
807+ struct tun_file * tfile = file -> private_data ;
808+ struct tun_struct * tun = __tun_get (tfile );
809+ ssize_t len , ret ;
810+
811+ if (!tun )
812+ return - EBADFD ;
813+ len = iov_length (iv , count );
814+ if (len < 0 ) {
815+ ret = - EINVAL ;
816+ goto out ;
817+ }
818+
819+ ret = tun_do_read (tun , iocb , iv , len , file -> f_flags & O_NONBLOCK );
820+ ret = min_t (ssize_t , ret , len );
808821out :
809822 tun_put (tun );
810823 return ret ;
@@ -847,7 +860,8 @@ static void tun_sock_write_space(struct sock *sk)
847860 return ;
848861
849862 if (sk -> sk_sleep && waitqueue_active (sk -> sk_sleep ))
850- wake_up_interruptible_sync (sk -> sk_sleep );
863+ wake_up_interruptible_sync_poll (sk -> sk_sleep , POLLOUT |
864+ POLLWRNORM | POLLWRBAND );
851865
852866 tun = tun_sk (sk )-> tun ;
853867 kill_fasync (& tun -> fasync , SIGIO , POLL_OUT );
@@ -858,6 +872,37 @@ static void tun_sock_destruct(struct sock *sk)
858872 free_netdev (tun_sk (sk )-> tun -> dev );
859873}
860874
875+ static int tun_sendmsg (struct kiocb * iocb , struct socket * sock ,
876+ struct msghdr * m , size_t total_len )
877+ {
878+ struct tun_struct * tun = container_of (sock , struct tun_struct , socket );
879+ return tun_get_user (tun , m -> msg_iov , total_len ,
880+ m -> msg_flags & MSG_DONTWAIT );
881+ }
882+
883+ static int tun_recvmsg (struct kiocb * iocb , struct socket * sock ,
884+ struct msghdr * m , size_t total_len ,
885+ int flags )
886+ {
887+ struct tun_struct * tun = container_of (sock , struct tun_struct , socket );
888+ int ret ;
889+ if (flags & ~(MSG_DONTWAIT |MSG_TRUNC ))
890+ return - EINVAL ;
891+ ret = tun_do_read (tun , iocb , m -> msg_iov , total_len ,
892+ flags & MSG_DONTWAIT );
893+ if (ret > total_len ) {
894+ m -> msg_flags |= MSG_TRUNC ;
895+ ret = flags & MSG_TRUNC ? ret : total_len ;
896+ }
897+ return ret ;
898+ }
899+
900+ /* Ops structure to mimic raw sockets with tun */
901+ static const struct proto_ops tun_socket_ops = {
902+ .sendmsg = tun_sendmsg ,
903+ .recvmsg = tun_recvmsg ,
904+ };
905+
861906static struct proto tun_proto = {
862907 .name = "tun" ,
863908 .owner = THIS_MODULE ,
@@ -986,6 +1031,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
9861031 goto err_free_dev ;
9871032
9881033 init_waitqueue_head (& tun -> socket .wait );
1034+ tun -> socket .ops = & tun_socket_ops ;
9891035 sock_init_data (& tun -> socket , sk );
9901036 sk -> sk_write_space = tun_sock_write_space ;
9911037 sk -> sk_sndbuf = INT_MAX ;
@@ -1525,6 +1571,23 @@ static void tun_cleanup(void)
15251571 rtnl_link_unregister (& tun_link_ops );
15261572}
15271573
1574+ /* Get an underlying socket object from tun file. Returns error unless file is
1575+ * attached to a device. The returned object works like a packet socket, it
1576+ * can be used for sock_sendmsg/sock_recvmsg. The caller is responsible for
1577+ * holding a reference to the file for as long as the socket is in use. */
1578+ struct socket * tun_get_socket (struct file * file )
1579+ {
1580+ struct tun_struct * tun ;
1581+ if (file -> f_op != & tun_fops )
1582+ return ERR_PTR (- EINVAL );
1583+ tun = tun_get (file );
1584+ if (!tun )
1585+ return ERR_PTR (- EBADFD );
1586+ tun_put (tun );
1587+ return & tun -> socket ;
1588+ }
1589+ EXPORT_SYMBOL_GPL (tun_get_socket );
1590+
15281591module_init (tun_init );
15291592module_exit (tun_cleanup );
15301593MODULE_DESCRIPTION (DRV_DESCRIPTION );
0 commit comments