diff options
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r-- | drivers/net/tun.c | 67 |
1 files changed, 52 insertions, 15 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 94622e5fb936..4cda69b6b28c 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -865,6 +865,52 @@ static struct proto tun_proto = { | |||
865 | .obj_size = sizeof(struct tun_sock), | 865 | .obj_size = sizeof(struct tun_sock), |
866 | }; | 866 | }; |
867 | 867 | ||
868 | static int tun_flags(struct tun_struct *tun) | ||
869 | { | ||
870 | int flags = 0; | ||
871 | |||
872 | if (tun->flags & TUN_TUN_DEV) | ||
873 | flags |= IFF_TUN; | ||
874 | else | ||
875 | flags |= IFF_TAP; | ||
876 | |||
877 | if (tun->flags & TUN_NO_PI) | ||
878 | flags |= IFF_NO_PI; | ||
879 | |||
880 | if (tun->flags & TUN_ONE_QUEUE) | ||
881 | flags |= IFF_ONE_QUEUE; | ||
882 | |||
883 | if (tun->flags & TUN_VNET_HDR) | ||
884 | flags |= IFF_VNET_HDR; | ||
885 | |||
886 | return flags; | ||
887 | } | ||
888 | |||
889 | static ssize_t tun_show_flags(struct device *dev, struct device_attribute *attr, | ||
890 | char *buf) | ||
891 | { | ||
892 | struct tun_struct *tun = netdev_priv(to_net_dev(dev)); | ||
893 | return sprintf(buf, "0x%x\n", tun_flags(tun)); | ||
894 | } | ||
895 | |||
896 | static ssize_t tun_show_owner(struct device *dev, struct device_attribute *attr, | ||
897 | char *buf) | ||
898 | { | ||
899 | struct tun_struct *tun = netdev_priv(to_net_dev(dev)); | ||
900 | return sprintf(buf, "%d\n", tun->owner); | ||
901 | } | ||
902 | |||
903 | static ssize_t tun_show_group(struct device *dev, struct device_attribute *attr, | ||
904 | char *buf) | ||
905 | { | ||
906 | struct tun_struct *tun = netdev_priv(to_net_dev(dev)); | ||
907 | return sprintf(buf, "%d\n", tun->group); | ||
908 | } | ||
909 | |||
910 | static DEVICE_ATTR(tun_flags, 0444, tun_show_flags, NULL); | ||
911 | static DEVICE_ATTR(owner, 0444, tun_show_owner, NULL); | ||
912 | static DEVICE_ATTR(group, 0444, tun_show_group, NULL); | ||
913 | |||
868 | static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | 914 | static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) |
869 | { | 915 | { |
870 | struct sock *sk; | 916 | struct sock *sk; |
@@ -950,6 +996,11 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
950 | if (err < 0) | 996 | if (err < 0) |
951 | goto err_free_sk; | 997 | goto err_free_sk; |
952 | 998 | ||
999 | if (device_create_file(&tun->dev->dev, &dev_attr_tun_flags) || | ||
1000 | device_create_file(&tun->dev->dev, &dev_attr_owner) || | ||
1001 | device_create_file(&tun->dev->dev, &dev_attr_group)) | ||
1002 | printk(KERN_ERR "Failed to create tun sysfs files\n"); | ||
1003 | |||
953 | sk->sk_destruct = tun_sock_destruct; | 1004 | sk->sk_destruct = tun_sock_destruct; |
954 | 1005 | ||
955 | err = tun_attach(tun, file); | 1006 | err = tun_attach(tun, file); |
@@ -1002,21 +1053,7 @@ static int tun_get_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
1002 | 1053 | ||
1003 | strcpy(ifr->ifr_name, tun->dev->name); | 1054 | strcpy(ifr->ifr_name, tun->dev->name); |
1004 | 1055 | ||
1005 | ifr->ifr_flags = 0; | 1056 | ifr->ifr_flags = tun_flags(tun); |
1006 | |||
1007 | if (ifr->ifr_flags & TUN_TUN_DEV) | ||
1008 | ifr->ifr_flags |= IFF_TUN; | ||
1009 | else | ||
1010 | ifr->ifr_flags |= IFF_TAP; | ||
1011 | |||
1012 | if (tun->flags & TUN_NO_PI) | ||
1013 | ifr->ifr_flags |= IFF_NO_PI; | ||
1014 | |||
1015 | if (tun->flags & TUN_ONE_QUEUE) | ||
1016 | ifr->ifr_flags |= IFF_ONE_QUEUE; | ||
1017 | |||
1018 | if (tun->flags & TUN_VNET_HDR) | ||
1019 | ifr->ifr_flags |= IFF_VNET_HDR; | ||
1020 | 1057 | ||
1021 | tun_put(tun); | 1058 | tun_put(tun); |
1022 | return 0; | 1059 | return 0; |