aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark McLoughlin <markmc@redhat.com>2008-08-15 18:09:56 -0400
committerDavid S. Miller <davem@davemloft.net>2008-08-15 22:52:19 -0400
commite3b99556975907530aeb9745e7b3945a0da48f17 (patch)
tree97f764e5c8587efcba64ad8d0edce9fee094e143
parent04a0551c87363f100b04d28d7a15a632b70e18e7 (diff)
tun: TUNGETIFF interface to query name and flags
Add a TUNGETIFF interface so that userspace can query a tun/tap descriptor for its name and flags. This is needed because it is common for one app to create a tap interface, exec another app and pass it the file descriptor for the interface. Without TUNGETIFF the spawned app has no way of detecting wheter the interface has e.g. IFF_VNET_HDR set. Signed-off-by: Mark McLoughlin <markmc@redhat.com> Acked-by: Max Krasnyansky <maxk@qualcomm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/tun.c39
-rw-r--r--include/linux/if_tun.h1
2 files changed, 40 insertions, 0 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index e6bbc639c2d0..95931a5a9883 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -748,6 +748,36 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
748 return err; 748 return err;
749} 749}
750 750
751static int tun_get_iff(struct net *net, struct file *file, struct ifreq *ifr)
752{
753 struct tun_struct *tun = file->private_data;
754
755 if (!tun)
756 return -EBADFD;
757
758 DBG(KERN_INFO "%s: tun_get_iff\n", tun->dev->name);
759
760 strcpy(ifr->ifr_name, tun->dev->name);
761
762 ifr->ifr_flags = 0;
763
764 if (ifr->ifr_flags & TUN_TUN_DEV)
765 ifr->ifr_flags |= IFF_TUN;
766 else
767 ifr->ifr_flags |= IFF_TAP;
768
769 if (tun->flags & TUN_NO_PI)
770 ifr->ifr_flags |= IFF_NO_PI;
771
772 if (tun->flags & TUN_ONE_QUEUE)
773 ifr->ifr_flags |= IFF_ONE_QUEUE;
774
775 if (tun->flags & TUN_VNET_HDR)
776 ifr->ifr_flags |= IFF_VNET_HDR;
777
778 return 0;
779}
780
751/* This is like a cut-down ethtool ops, except done via tun fd so no 781/* This is like a cut-down ethtool ops, except done via tun fd so no
752 * privs required. */ 782 * privs required. */
753static int set_offload(struct net_device *dev, unsigned long arg) 783static int set_offload(struct net_device *dev, unsigned long arg)
@@ -833,6 +863,15 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
833 DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->dev->name, cmd); 863 DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->dev->name, cmd);
834 864
835 switch (cmd) { 865 switch (cmd) {
866 case TUNGETIFF:
867 ret = tun_get_iff(current->nsproxy->net_ns, file, &ifr);
868 if (ret)
869 return ret;
870
871 if (copy_to_user(argp, &ifr, sizeof(ifr)))
872 return -EFAULT;
873 break;
874
836 case TUNSETNOCSUM: 875 case TUNSETNOCSUM:
837 /* Disable/Enable checksum */ 876 /* Disable/Enable checksum */
838 if (arg) 877 if (arg)
diff --git a/include/linux/if_tun.h b/include/linux/if_tun.h
index 4c6307ad9fdb..8529f57ba263 100644
--- a/include/linux/if_tun.h
+++ b/include/linux/if_tun.h
@@ -45,6 +45,7 @@
45#define TUNGETFEATURES _IOR('T', 207, unsigned int) 45#define TUNGETFEATURES _IOR('T', 207, unsigned int)
46#define TUNSETOFFLOAD _IOW('T', 208, unsigned int) 46#define TUNSETOFFLOAD _IOW('T', 208, unsigned int)
47#define TUNSETTXFILTER _IOW('T', 209, unsigned int) 47#define TUNSETTXFILTER _IOW('T', 209, unsigned int)
48#define TUNGETIFF _IOR('T', 210, unsigned int)
48 49
49/* TUNSETIFF ifr flags */ 50/* TUNSETIFF ifr flags */
50#define IFF_TUN 0x0001 51#define IFF_TUN 0x0001