diff options
-rw-r--r-- | drivers/net/macvtap.c | 30 | ||||
-rw-r--r-- | drivers/net/tun.c | 26 | ||||
-rw-r--r-- | include/uapi/linux/if_tun.h | 3 |
3 files changed, 49 insertions, 10 deletions
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 60f7ee5fafbe..7df221788cd4 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c | |||
@@ -46,16 +46,18 @@ struct macvtap_queue { | |||
46 | struct list_head next; | 46 | struct list_head next; |
47 | }; | 47 | }; |
48 | 48 | ||
49 | #define MACVTAP_FEATURES (IFF_VNET_HDR | IFF_VNET_LE | IFF_MULTI_QUEUE) | 49 | #define MACVTAP_FEATURES (IFF_VNET_HDR | IFF_MULTI_QUEUE) |
50 | |||
51 | #define MACVTAP_VNET_LE 0x80000000 | ||
50 | 52 | ||
51 | static inline u16 macvtap16_to_cpu(struct macvtap_queue *q, __virtio16 val) | 53 | static inline u16 macvtap16_to_cpu(struct macvtap_queue *q, __virtio16 val) |
52 | { | 54 | { |
53 | return __virtio16_to_cpu(q->flags & IFF_VNET_LE, val); | 55 | return __virtio16_to_cpu(q->flags & MACVTAP_VNET_LE, val); |
54 | } | 56 | } |
55 | 57 | ||
56 | static inline __virtio16 cpu_to_macvtap16(struct macvtap_queue *q, u16 val) | 58 | static inline __virtio16 cpu_to_macvtap16(struct macvtap_queue *q, u16 val) |
57 | { | 59 | { |
58 | return __cpu_to_virtio16(q->flags & IFF_VNET_LE, val); | 60 | return __cpu_to_virtio16(q->flags & MACVTAP_VNET_LE, val); |
59 | } | 61 | } |
60 | 62 | ||
61 | static struct proto macvtap_proto = { | 63 | static struct proto macvtap_proto = { |
@@ -999,7 +1001,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd, | |||
999 | void __user *argp = (void __user *)arg; | 1001 | void __user *argp = (void __user *)arg; |
1000 | struct ifreq __user *ifr = argp; | 1002 | struct ifreq __user *ifr = argp; |
1001 | unsigned int __user *up = argp; | 1003 | unsigned int __user *up = argp; |
1002 | unsigned int u; | 1004 | unsigned short u; |
1003 | int __user *sp = argp; | 1005 | int __user *sp = argp; |
1004 | int s; | 1006 | int s; |
1005 | int ret; | 1007 | int ret; |
@@ -1014,7 +1016,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd, | |||
1014 | if ((u & ~MACVTAP_FEATURES) != (IFF_NO_PI | IFF_TAP)) | 1016 | if ((u & ~MACVTAP_FEATURES) != (IFF_NO_PI | IFF_TAP)) |
1015 | ret = -EINVAL; | 1017 | ret = -EINVAL; |
1016 | else | 1018 | else |
1017 | q->flags = u; | 1019 | q->flags = (q->flags & ~MACVTAP_FEATURES) | u; |
1018 | 1020 | ||
1019 | return ret; | 1021 | return ret; |
1020 | 1022 | ||
@@ -1027,8 +1029,9 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd, | |||
1027 | } | 1029 | } |
1028 | 1030 | ||
1029 | ret = 0; | 1031 | ret = 0; |
1032 | u = q->flags; | ||
1030 | if (copy_to_user(&ifr->ifr_name, vlan->dev->name, IFNAMSIZ) || | 1033 | if (copy_to_user(&ifr->ifr_name, vlan->dev->name, IFNAMSIZ) || |
1031 | put_user(q->flags, &ifr->ifr_flags)) | 1034 | put_user(u, &ifr->ifr_flags)) |
1032 | ret = -EFAULT; | 1035 | ret = -EFAULT; |
1033 | macvtap_put_vlan(vlan); | 1036 | macvtap_put_vlan(vlan); |
1034 | rtnl_unlock(); | 1037 | rtnl_unlock(); |
@@ -1069,6 +1072,21 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd, | |||
1069 | q->vnet_hdr_sz = s; | 1072 | q->vnet_hdr_sz = s; |
1070 | return 0; | 1073 | return 0; |
1071 | 1074 | ||
1075 | case TUNGETVNETLE: | ||
1076 | s = !!(q->flags & MACVTAP_VNET_LE); | ||
1077 | if (put_user(s, sp)) | ||
1078 | return -EFAULT; | ||
1079 | return 0; | ||
1080 | |||
1081 | case TUNSETVNETLE: | ||
1082 | if (get_user(s, sp)) | ||
1083 | return -EFAULT; | ||
1084 | if (s) | ||
1085 | q->flags |= MACVTAP_VNET_LE; | ||
1086 | else | ||
1087 | q->flags &= ~MACVTAP_VNET_LE; | ||
1088 | return 0; | ||
1089 | |||
1072 | case TUNSETOFFLOAD: | 1090 | case TUNSETOFFLOAD: |
1073 | /* let the user check for future flags */ | 1091 | /* let the user check for future flags */ |
1074 | if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 | | 1092 | if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 | |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index a5cbf67517f0..8c8dc16839a7 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -110,9 +110,11 @@ do { \ | |||
110 | * overload it to mean fasync when stored there. | 110 | * overload it to mean fasync when stored there. |
111 | */ | 111 | */ |
112 | #define TUN_FASYNC IFF_ATTACH_QUEUE | 112 | #define TUN_FASYNC IFF_ATTACH_QUEUE |
113 | /* High bits in flags field are unused. */ | ||
114 | #define TUN_VNET_LE 0x80000000 | ||
113 | 115 | ||
114 | #define TUN_FEATURES (IFF_NO_PI | IFF_ONE_QUEUE | IFF_VNET_HDR | \ | 116 | #define TUN_FEATURES (IFF_NO_PI | IFF_ONE_QUEUE | IFF_VNET_HDR | \ |
115 | IFF_VNET_LE | IFF_MULTI_QUEUE) | 117 | IFF_MULTI_QUEUE) |
116 | #define GOODCOPY_LEN 128 | 118 | #define GOODCOPY_LEN 128 |
117 | 119 | ||
118 | #define FLT_EXACT_COUNT 8 | 120 | #define FLT_EXACT_COUNT 8 |
@@ -208,12 +210,12 @@ struct tun_struct { | |||
208 | 210 | ||
209 | static inline u16 tun16_to_cpu(struct tun_struct *tun, __virtio16 val) | 211 | static inline u16 tun16_to_cpu(struct tun_struct *tun, __virtio16 val) |
210 | { | 212 | { |
211 | return __virtio16_to_cpu(tun->flags & IFF_VNET_LE, val); | 213 | return __virtio16_to_cpu(tun->flags & TUN_VNET_LE, val); |
212 | } | 214 | } |
213 | 215 | ||
214 | static inline __virtio16 cpu_to_tun16(struct tun_struct *tun, u16 val) | 216 | static inline __virtio16 cpu_to_tun16(struct tun_struct *tun, u16 val) |
215 | { | 217 | { |
216 | return __cpu_to_virtio16(tun->flags & IFF_VNET_LE, val); | 218 | return __cpu_to_virtio16(tun->flags & TUN_VNET_LE, val); |
217 | } | 219 | } |
218 | 220 | ||
219 | static inline u32 tun_hashfn(u32 rxhash) | 221 | static inline u32 tun_hashfn(u32 rxhash) |
@@ -1843,6 +1845,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
1843 | int sndbuf; | 1845 | int sndbuf; |
1844 | int vnet_hdr_sz; | 1846 | int vnet_hdr_sz; |
1845 | unsigned int ifindex; | 1847 | unsigned int ifindex; |
1848 | int le; | ||
1846 | int ret; | 1849 | int ret; |
1847 | 1850 | ||
1848 | if (cmd == TUNSETIFF || cmd == TUNSETQUEUE || _IOC_TYPE(cmd) == 0x89) { | 1851 | if (cmd == TUNSETIFF || cmd == TUNSETQUEUE || _IOC_TYPE(cmd) == 0x89) { |
@@ -2042,6 +2045,23 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
2042 | tun->vnet_hdr_sz = vnet_hdr_sz; | 2045 | tun->vnet_hdr_sz = vnet_hdr_sz; |
2043 | break; | 2046 | break; |
2044 | 2047 | ||
2048 | case TUNGETVNETLE: | ||
2049 | le = !!(tun->flags & TUN_VNET_LE); | ||
2050 | if (put_user(le, (int __user *)argp)) | ||
2051 | ret = -EFAULT; | ||
2052 | break; | ||
2053 | |||
2054 | case TUNSETVNETLE: | ||
2055 | if (get_user(le, (int __user *)argp)) { | ||
2056 | ret = -EFAULT; | ||
2057 | break; | ||
2058 | } | ||
2059 | if (le) | ||
2060 | tun->flags |= TUN_VNET_LE; | ||
2061 | else | ||
2062 | tun->flags &= ~TUN_VNET_LE; | ||
2063 | break; | ||
2064 | |||
2045 | case TUNATTACHFILTER: | 2065 | case TUNATTACHFILTER: |
2046 | /* Can be set only for TAPs */ | 2066 | /* Can be set only for TAPs */ |
2047 | ret = -EINVAL; | 2067 | ret = -EINVAL; |
diff --git a/include/uapi/linux/if_tun.h b/include/uapi/linux/if_tun.h index 18b2403982f9..50ae24335444 100644 --- a/include/uapi/linux/if_tun.h +++ b/include/uapi/linux/if_tun.h | |||
@@ -48,6 +48,8 @@ | |||
48 | #define TUNSETQUEUE _IOW('T', 217, int) | 48 | #define TUNSETQUEUE _IOW('T', 217, int) |
49 | #define TUNSETIFINDEX _IOW('T', 218, unsigned int) | 49 | #define TUNSETIFINDEX _IOW('T', 218, unsigned int) |
50 | #define TUNGETFILTER _IOR('T', 219, struct sock_fprog) | 50 | #define TUNGETFILTER _IOR('T', 219, struct sock_fprog) |
51 | #define TUNSETVNETLE _IOW('T', 220, int) | ||
52 | #define TUNGETVNETLE _IOR('T', 221, int) | ||
51 | 53 | ||
52 | /* TUNSETIFF ifr flags */ | 54 | /* TUNSETIFF ifr flags */ |
53 | #define IFF_TUN 0x0001 | 55 | #define IFF_TUN 0x0001 |
@@ -57,7 +59,6 @@ | |||
57 | #define IFF_ONE_QUEUE 0x2000 | 59 | #define IFF_ONE_QUEUE 0x2000 |
58 | #define IFF_VNET_HDR 0x4000 | 60 | #define IFF_VNET_HDR 0x4000 |
59 | #define IFF_TUN_EXCL 0x8000 | 61 | #define IFF_TUN_EXCL 0x8000 |
60 | #define IFF_VNET_LE 0x10000 | ||
61 | #define IFF_MULTI_QUEUE 0x0100 | 62 | #define IFF_MULTI_QUEUE 0x0100 |
62 | #define IFF_ATTACH_QUEUE 0x0200 | 63 | #define IFF_ATTACH_QUEUE 0x0200 |
63 | #define IFF_DETACH_QUEUE 0x0400 | 64 | #define IFF_DETACH_QUEUE 0x0400 |