Thread (1 message) 1 message, 1 author, 2012-06-25
DORMANTno replies

[PATCH 6/6] tuntap: add ioctls to attach or detach a file form tuntap device

From: Jason Wang <hidden>
Date: 2012-06-25 12:07:27
Also in: lkml
Subsystem: networking drivers, the rest, tun/tap driver · Maintainers: Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds, Willem de Bruijn, Jason Wang

This patch introduces two new ioctls which is used to attach and detach a socket
from tuntap devices:

1) TUNATTACHQUEUE which is used to attach a socket to tuntap device.
2) TUNDETACHQUEUE which is used to detach a socket from tuntap device. It allows
                  a socket to be detached from the device temporarily and could
                  be re-attached again by TUNATTACHQUEUE.

Signed-off-by: Jason Wang <redacted>
---
 drivers/net/tun.c      |   25 ++++++++++++++++++++++---
 include/linux/if_tun.h |    3 +++
 2 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 37e62d3..25d5e1f 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1411,11 +1411,12 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
 {
 	struct tun_file *tfile = file->private_data;
 	struct tun_struct *tun;
+	struct net_device *dev = NULL;
 	void __user* argp = (void __user*)arg;
 	struct ifreq ifr;
 	int ret;
 
-	if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89)
+	if (cmd == TUNSETIFF || cmd == TUNATTACHQUEUE || _IOC_TYPE(cmd) == 0x89)
 		if (copy_from_user(&ifr, argp, ifreq_len))
 			return -EFAULT;
 
@@ -1424,7 +1425,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
 		 * This is needed because we never checked for invalid flags on
 		 * TUNSETIFF. */
 		return put_user(IFF_TUN | IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE |
-				IFF_VNET_HDR,
+				IFF_VNET_HDR | IFF_MULTI_QUEUE,
 				(unsigned int __user*)argp);
 	}
 
@@ -1440,6 +1441,8 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
 			return -EFAULT;
 		return ret;
 	}
+	if (cmd == TUNDETACHQUEUE)
+		return tun_detach(tfile, false);
 
 	rtnl_lock();
 
@@ -1447,7 +1450,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
 
 	ret = -EBADFD;
 	tun = rcu_dereference(tfile->tun);
-	if (!tun)
+	if (!tun && cmd != TUNATTACHQUEUE)
 		goto unlock;
 	else
 		ret = 0;
@@ -1463,6 +1466,22 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
 			ret = -EFAULT;
 		goto out;
 
+	case TUNATTACHQUEUE:
+		dev = __dev_get_by_name(tfile->net, ifr.ifr_name);
+		if (!dev || (dev->netdev_ops != &tap_netdev_ops &&
+				dev->netdev_ops != &tun_netdev_ops))
+			ret = -EINVAL;
+		else if (ifr.ifr_flags &
+			~(IFF_TAP | IFF_TUN | IFF_NO_PI | IFF_VNET_HDR)) {
+			/* ignore illegal flag */
+			ret = -EINVAL;
+		} else {
+			tun = netdev_priv(dev);
+			tfile->flags = tun->flags;
+			ret = tun_attach(tun, file);
+		}
+		break;
+
 	case TUNSETNOCSUM:
 		/* Disable/Enable checksum */
 
diff --git a/include/linux/if_tun.h b/include/linux/if_tun.h
index c92a291..d3f24d8 100644
--- a/include/linux/if_tun.h
+++ b/include/linux/if_tun.h
@@ -54,6 +54,9 @@
 #define TUNDETACHFILTER _IOW('T', 214, struct sock_fprog)
 #define TUNGETVNETHDRSZ _IOR('T', 215, int)
 #define TUNSETVNETHDRSZ _IOW('T', 216, int)
+#define TUNATTACHQUEUE  _IOW('T', 217, int)
+#define TUNDETACHQUEUE  _IOW('T', 218, int)
+
 
 /* TUNSETIFF ifr flags */
 #define IFF_TUN		0x0001
-- 
1.7.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help