diff options
| author | Mark McLoughlin <markmc@redhat.com> | 2008-08-15 18:09:56 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2008-08-15 22:52:19 -0400 |
| commit | e3b99556975907530aeb9745e7b3945a0da48f17 (patch) | |
| tree | 97f764e5c8587efcba64ad8d0edce9fee094e143 | |
| parent | 04a0551c87363f100b04d28d7a15a632b70e18e7 (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.c | 39 | ||||
| -rw-r--r-- | include/linux/if_tun.h | 1 |
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 | ||
| 751 | static 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. */ |
| 753 | static int set_offload(struct net_device *dev, unsigned long arg) | 783 | static 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 |
