diff options
author | David S. Miller <davem@davemloft.net> | 2013-12-05 19:45:14 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-12-05 19:45:14 -0500 |
commit | 426e1fa31e0d8e982891e801c80b84b74f209f10 (patch) | |
tree | bc53409418ffa918fb3f175639bc5c9245c4219f /net/socket.c | |
parent | e1ca87bb1b64b044163e686ff3bb71405156c561 (diff) | |
parent | a4bcc795e9cc84902b86edbfbb755ecb38d11f91 (diff) |
Merge branch 'siocghwtstamp' of git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc-next
Ben Hutchings says:
====================
SIOCGHWTSTAMP ioctl
1. Add the SIOCGHWTSTAMP ioctl and update the timestamping
documentation.
2. Implement SIOCGHWTSTAMP in most drivers that support SIOCSHWTSTAMP.
3. Add a test program to exercise SIOC{G,S}HWTSTAMP.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/socket.c')
-rw-r--r-- | net/socket.c | 57 |
1 files changed, 9 insertions, 48 deletions
diff --git a/net/socket.c b/net/socket.c index e83c416708af..cd38a785f7d2 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -2968,11 +2968,8 @@ static int bond_ioctl(struct net *net, unsigned int cmd, | |||
2968 | struct compat_ifreq __user *ifr32) | 2968 | struct compat_ifreq __user *ifr32) |
2969 | { | 2969 | { |
2970 | struct ifreq kifr; | 2970 | struct ifreq kifr; |
2971 | struct ifreq __user *uifr; | ||
2972 | mm_segment_t old_fs; | 2971 | mm_segment_t old_fs; |
2973 | int err; | 2972 | int err; |
2974 | u32 data; | ||
2975 | void __user *datap; | ||
2976 | 2973 | ||
2977 | switch (cmd) { | 2974 | switch (cmd) { |
2978 | case SIOCBONDENSLAVE: | 2975 | case SIOCBONDENSLAVE: |
@@ -2989,26 +2986,13 @@ static int bond_ioctl(struct net *net, unsigned int cmd, | |||
2989 | set_fs(old_fs); | 2986 | set_fs(old_fs); |
2990 | 2987 | ||
2991 | return err; | 2988 | return err; |
2992 | case SIOCBONDSLAVEINFOQUERY: | ||
2993 | case SIOCBONDINFOQUERY: | ||
2994 | uifr = compat_alloc_user_space(sizeof(*uifr)); | ||
2995 | if (copy_in_user(&uifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ)) | ||
2996 | return -EFAULT; | ||
2997 | |||
2998 | if (get_user(data, &ifr32->ifr_ifru.ifru_data)) | ||
2999 | return -EFAULT; | ||
3000 | |||
3001 | datap = compat_ptr(data); | ||
3002 | if (put_user(datap, &uifr->ifr_ifru.ifru_data)) | ||
3003 | return -EFAULT; | ||
3004 | |||
3005 | return dev_ioctl(net, cmd, uifr); | ||
3006 | default: | 2989 | default: |
3007 | return -ENOIOCTLCMD; | 2990 | return -ENOIOCTLCMD; |
3008 | } | 2991 | } |
3009 | } | 2992 | } |
3010 | 2993 | ||
3011 | static int siocdevprivate_ioctl(struct net *net, unsigned int cmd, | 2994 | /* Handle ioctls that use ifreq::ifr_data and just need struct ifreq converted */ |
2995 | static int compat_ifr_data_ioctl(struct net *net, unsigned int cmd, | ||
3012 | struct compat_ifreq __user *u_ifreq32) | 2996 | struct compat_ifreq __user *u_ifreq32) |
3013 | { | 2997 | { |
3014 | struct ifreq __user *u_ifreq64; | 2998 | struct ifreq __user *u_ifreq64; |
@@ -3019,19 +3003,16 @@ static int siocdevprivate_ioctl(struct net *net, unsigned int cmd, | |||
3019 | if (copy_from_user(&tmp_buf[0], &(u_ifreq32->ifr_ifrn.ifrn_name[0]), | 3003 | if (copy_from_user(&tmp_buf[0], &(u_ifreq32->ifr_ifrn.ifrn_name[0]), |
3020 | IFNAMSIZ)) | 3004 | IFNAMSIZ)) |
3021 | return -EFAULT; | 3005 | return -EFAULT; |
3022 | if (__get_user(data32, &u_ifreq32->ifr_ifru.ifru_data)) | 3006 | if (get_user(data32, &u_ifreq32->ifr_ifru.ifru_data)) |
3023 | return -EFAULT; | 3007 | return -EFAULT; |
3024 | data64 = compat_ptr(data32); | 3008 | data64 = compat_ptr(data32); |
3025 | 3009 | ||
3026 | u_ifreq64 = compat_alloc_user_space(sizeof(*u_ifreq64)); | 3010 | u_ifreq64 = compat_alloc_user_space(sizeof(*u_ifreq64)); |
3027 | 3011 | ||
3028 | /* Don't check these user accesses, just let that get trapped | ||
3029 | * in the ioctl handler instead. | ||
3030 | */ | ||
3031 | if (copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0], | 3012 | if (copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0], |
3032 | IFNAMSIZ)) | 3013 | IFNAMSIZ)) |
3033 | return -EFAULT; | 3014 | return -EFAULT; |
3034 | if (__put_user(data64, &u_ifreq64->ifr_ifru.ifru_data)) | 3015 | if (put_user(data64, &u_ifreq64->ifr_ifru.ifru_data)) |
3035 | return -EFAULT; | 3016 | return -EFAULT; |
3036 | 3017 | ||
3037 | return dev_ioctl(net, cmd, u_ifreq64); | 3018 | return dev_ioctl(net, cmd, u_ifreq64); |
@@ -3111,27 +3092,6 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd, | |||
3111 | return err; | 3092 | return err; |
3112 | } | 3093 | } |
3113 | 3094 | ||
3114 | static int compat_siocshwtstamp(struct net *net, struct compat_ifreq __user *uifr32) | ||
3115 | { | ||
3116 | void __user *uptr; | ||
3117 | compat_uptr_t uptr32; | ||
3118 | struct ifreq __user *uifr; | ||
3119 | |||
3120 | uifr = compat_alloc_user_space(sizeof(*uifr)); | ||
3121 | if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq))) | ||
3122 | return -EFAULT; | ||
3123 | |||
3124 | if (get_user(uptr32, &uifr32->ifr_data)) | ||
3125 | return -EFAULT; | ||
3126 | |||
3127 | uptr = compat_ptr(uptr32); | ||
3128 | |||
3129 | if (put_user(uptr, &uifr->ifr_data)) | ||
3130 | return -EFAULT; | ||
3131 | |||
3132 | return dev_ioctl(net, SIOCSHWTSTAMP, uifr); | ||
3133 | } | ||
3134 | |||
3135 | struct rtentry32 { | 3095 | struct rtentry32 { |
3136 | u32 rt_pad1; | 3096 | u32 rt_pad1; |
3137 | struct sockaddr rt_dst; /* target address */ | 3097 | struct sockaddr rt_dst; /* target address */ |
@@ -3243,7 +3203,7 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock, | |||
3243 | struct net *net = sock_net(sk); | 3203 | struct net *net = sock_net(sk); |
3244 | 3204 | ||
3245 | if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) | 3205 | if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) |
3246 | return siocdevprivate_ioctl(net, cmd, argp); | 3206 | return compat_ifr_data_ioctl(net, cmd, argp); |
3247 | 3207 | ||
3248 | switch (cmd) { | 3208 | switch (cmd) { |
3249 | case SIOCSIFBR: | 3209 | case SIOCSIFBR: |
@@ -3263,8 +3223,6 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock, | |||
3263 | case SIOCBONDENSLAVE: | 3223 | case SIOCBONDENSLAVE: |
3264 | case SIOCBONDRELEASE: | 3224 | case SIOCBONDRELEASE: |
3265 | case SIOCBONDSETHWADDR: | 3225 | case SIOCBONDSETHWADDR: |
3266 | case SIOCBONDSLAVEINFOQUERY: | ||
3267 | case SIOCBONDINFOQUERY: | ||
3268 | case SIOCBONDCHANGEACTIVE: | 3226 | case SIOCBONDCHANGEACTIVE: |
3269 | return bond_ioctl(net, cmd, argp); | 3227 | return bond_ioctl(net, cmd, argp); |
3270 | case SIOCADDRT: | 3228 | case SIOCADDRT: |
@@ -3274,8 +3232,11 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock, | |||
3274 | return do_siocgstamp(net, sock, cmd, argp); | 3232 | return do_siocgstamp(net, sock, cmd, argp); |
3275 | case SIOCGSTAMPNS: | 3233 | case SIOCGSTAMPNS: |
3276 | return do_siocgstampns(net, sock, cmd, argp); | 3234 | return do_siocgstampns(net, sock, cmd, argp); |
3235 | case SIOCBONDSLAVEINFOQUERY: | ||
3236 | case SIOCBONDINFOQUERY: | ||
3277 | case SIOCSHWTSTAMP: | 3237 | case SIOCSHWTSTAMP: |
3278 | return compat_siocshwtstamp(net, argp); | 3238 | case SIOCGHWTSTAMP: |
3239 | return compat_ifr_data_ioctl(net, cmd, argp); | ||
3279 | 3240 | ||
3280 | case FIOSETOWN: | 3241 | case FIOSETOWN: |
3281 | case SIOCSPGRP: | 3242 | case SIOCSPGRP: |