aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-12-16 11:19:49 -0500
committerDavid S. Miller <davem@davemloft.net>2014-12-16 11:19:49 -0500
commit772801ef7572f2b3e16bebceb707159ee3081ded (patch)
tree1b06c8e579574593753fc613550f00f28a22491a
parentc286bbaf4f56958db2591146145e248c7b9021c5 (diff)
parent9c6ab1931fd6198eab61d9d59aff9a1014637ace (diff)
Merge branch 'vnet_le'
Michael S. Tsirkin says: ==================== tun/macvtap: TUNSETIFF fixes Dan Carpenter reported the following: static checker warning: drivers/net/tun.c:1694 tun_set_iff() warn: 0x17100 is larger than 16 bits drivers/net/tun.c 1692 1693 tun->flags = (tun->flags & ~TUN_FEATURES) | 1694 (ifr->ifr_flags & TUN_FEATURES); 1695 It's complaining because the "ifr->ifr_flags" variable is a short (should it be unsigned?). The new define: #define IFF_VNET_LE 0x10000 doesn't fit in two bytes. Other suspect looking code could be: return __virtio16_to_cpu(q->flags & IFF_VNET_LE, val); And that's true: we have run out of IFF flags in tun. So let's not try to add more: add simple GET/SET ioctls instead. Easy to test, leads to clear semantics. Alternatively we'll have to revert the whole thing for 3.19, but that seems more work as this has dependencies in other places. While here, I noticed that macvtap was actually reading ifreq flags as a 32 bit field. Fix that up as well. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/macvtap.c30
-rw-r--r--drivers/net/tun.c26
-rw-r--r--include/uapi/linux/if_tun.h3
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
51static inline u16 macvtap16_to_cpu(struct macvtap_queue *q, __virtio16 val) 53static 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
56static inline __virtio16 cpu_to_macvtap16(struct macvtap_queue *q, u16 val) 58static 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
61static struct proto macvtap_proto = { 63static 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
209static inline u16 tun16_to_cpu(struct tun_struct *tun, __virtio16 val) 211static 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
214static inline __virtio16 cpu_to_tun16(struct tun_struct *tun, u16 val) 216static 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
219static inline u32 tun_hashfn(u32 rxhash) 221static 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