aboutsummaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-08 10:55:01 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-08 10:55:01 -0500
commitd7fc02c7bae7b1cf69269992cf880a43a350cdaa (patch)
treea43d56fa72913a1cc98a0bbebe054d08581b3a7c /net/socket.c
parentee1262dbc65ce0b6234a915d8432171e8d77f518 (diff)
parent28b4d5cc17c20786848cdc07b7ea237a309776bb (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1815 commits) mac80211: fix reorder buffer release iwmc3200wifi: Enable wimax core through module parameter iwmc3200wifi: Add wifi-wimax coexistence mode as a module parameter iwmc3200wifi: Coex table command does not expect a response iwmc3200wifi: Update wiwi priority table iwlwifi: driver version track kernel version iwlwifi: indicate uCode type when fail dump error/event log iwl3945: remove duplicated event logging code b43: fix two warnings ipw2100: fix rebooting hang with driver loaded cfg80211: indent regulatory messages with spaces iwmc3200wifi: fix NULL pointer dereference in pmkid update mac80211: Fix TX status reporting for injected data frames ath9k: enable 2GHz band only if the device supports it airo: Fix integer overflow warning rt2x00: Fix padding bug on L2PAD devices. WE: Fix set events not propagated b43legacy: avoid PPC fault during resume b43: avoid PPC fault during resume tcp: fix a timewait refcnt race ... Fix up conflicts due to sysctl cleanups (dead sysctl_check code and CTL_UNNUMBERED removed) in kernel/sysctl_check.c net/ipv4/sysctl_net_ipv4.c net/ipv6/addrconf.c net/sctp/sysctl.c
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c843
1 files changed, 790 insertions, 53 deletions
diff --git a/net/socket.c b/net/socket.c
index 75655365b5fd..b94c3dd71015 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -97,6 +97,12 @@
97#include <net/sock.h> 97#include <net/sock.h>
98#include <linux/netfilter.h> 98#include <linux/netfilter.h>
99 99
100#include <linux/if_tun.h>
101#include <linux/ipv6_route.h>
102#include <linux/route.h>
103#include <linux/sockios.h>
104#include <linux/atalk.h>
105
100static int sock_no_open(struct inode *irrelevant, struct file *dontcare); 106static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
101static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, 107static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
102 unsigned long nr_segs, loff_t pos); 108 unsigned long nr_segs, loff_t pos);
@@ -668,10 +674,24 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
668 674
669EXPORT_SYMBOL_GPL(__sock_recv_timestamp); 675EXPORT_SYMBOL_GPL(__sock_recv_timestamp);
670 676
671static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock, 677inline void sock_recv_drops(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
672 struct msghdr *msg, size_t size, int flags) 678{
679 if (sock_flag(sk, SOCK_RXQ_OVFL) && skb && skb->dropcount)
680 put_cmsg(msg, SOL_SOCKET, SO_RXQ_OVFL,
681 sizeof(__u32), &skb->dropcount);
682}
683
684void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
685 struct sk_buff *skb)
686{
687 sock_recv_timestamp(msg, sk, skb);
688 sock_recv_drops(msg, sk, skb);
689}
690EXPORT_SYMBOL_GPL(sock_recv_ts_and_drops);
691
692static inline int __sock_recvmsg_nosec(struct kiocb *iocb, struct socket *sock,
693 struct msghdr *msg, size_t size, int flags)
673{ 694{
674 int err;
675 struct sock_iocb *si = kiocb_to_siocb(iocb); 695 struct sock_iocb *si = kiocb_to_siocb(iocb);
676 696
677 si->sock = sock; 697 si->sock = sock;
@@ -680,13 +700,17 @@ static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock,
680 si->size = size; 700 si->size = size;
681 si->flags = flags; 701 si->flags = flags;
682 702
683 err = security_socket_recvmsg(sock, msg, size, flags);
684 if (err)
685 return err;
686
687 return sock->ops->recvmsg(iocb, sock, msg, size, flags); 703 return sock->ops->recvmsg(iocb, sock, msg, size, flags);
688} 704}
689 705
706static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock,
707 struct msghdr *msg, size_t size, int flags)
708{
709 int err = security_socket_recvmsg(sock, msg, size, flags);
710
711 return err ?: __sock_recvmsg_nosec(iocb, sock, msg, size, flags);
712}
713
690int sock_recvmsg(struct socket *sock, struct msghdr *msg, 714int sock_recvmsg(struct socket *sock, struct msghdr *msg,
691 size_t size, int flags) 715 size_t size, int flags)
692{ 716{
@@ -702,6 +726,21 @@ int sock_recvmsg(struct socket *sock, struct msghdr *msg,
702 return ret; 726 return ret;
703} 727}
704 728
729static int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg,
730 size_t size, int flags)
731{
732 struct kiocb iocb;
733 struct sock_iocb siocb;
734 int ret;
735
736 init_sync_kiocb(&iocb, NULL);
737 iocb.private = &siocb;
738 ret = __sock_recvmsg_nosec(&iocb, sock, msg, size, flags);
739 if (-EIOCBQUEUED == ret)
740 ret = wait_on_sync_kiocb(&iocb);
741 return ret;
742}
743
705int kernel_recvmsg(struct socket *sock, struct msghdr *msg, 744int kernel_recvmsg(struct socket *sock, struct msghdr *msg,
706 struct kvec *vec, size_t num, size_t size, int flags) 745 struct kvec *vec, size_t num, size_t size, int flags)
707{ 746{
@@ -886,6 +925,24 @@ void dlci_ioctl_set(int (*hook) (unsigned int, void __user *))
886 925
887EXPORT_SYMBOL(dlci_ioctl_set); 926EXPORT_SYMBOL(dlci_ioctl_set);
888 927
928static long sock_do_ioctl(struct net *net, struct socket *sock,
929 unsigned int cmd, unsigned long arg)
930{
931 int err;
932 void __user *argp = (void __user *)arg;
933
934 err = sock->ops->ioctl(sock, cmd, arg);
935
936 /*
937 * If this ioctl is unknown try to hand it down
938 * to the NIC driver.
939 */
940 if (err == -ENOIOCTLCMD)
941 err = dev_ioctl(net, cmd, argp);
942
943 return err;
944}
945
889/* 946/*
890 * With an ioctl, arg may well be a user mode pointer, but we don't know 947 * With an ioctl, arg may well be a user mode pointer, but we don't know
891 * what to do with it - that's up to the protocol still. 948 * what to do with it - that's up to the protocol still.
@@ -905,11 +962,11 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
905 if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) { 962 if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
906 err = dev_ioctl(net, cmd, argp); 963 err = dev_ioctl(net, cmd, argp);
907 } else 964 } else
908#ifdef CONFIG_WIRELESS_EXT 965#ifdef CONFIG_WEXT_CORE
909 if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) { 966 if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
910 err = dev_ioctl(net, cmd, argp); 967 err = dev_ioctl(net, cmd, argp);
911 } else 968 } else
912#endif /* CONFIG_WIRELESS_EXT */ 969#endif
913 switch (cmd) { 970 switch (cmd) {
914 case FIOSETOWN: 971 case FIOSETOWN:
915 case SIOCSPGRP: 972 case SIOCSPGRP:
@@ -959,14 +1016,7 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
959 mutex_unlock(&dlci_ioctl_mutex); 1016 mutex_unlock(&dlci_ioctl_mutex);
960 break; 1017 break;
961 default: 1018 default:
962 err = sock->ops->ioctl(sock, cmd, arg); 1019 err = sock_do_ioctl(net, sock, cmd, arg);
963
964 /*
965 * If this ioctl is unknown try to hand it down
966 * to the NIC driver.
967 */
968 if (err == -ENOIOCTLCMD)
969 err = dev_ioctl(net, cmd, argp);
970 break; 1020 break;
971 } 1021 }
972 return err; 1022 return err;
@@ -1100,11 +1150,14 @@ static int sock_fasync(int fd, struct file *filp, int on)
1100 fna->fa_next = sock->fasync_list; 1150 fna->fa_next = sock->fasync_list;
1101 write_lock_bh(&sk->sk_callback_lock); 1151 write_lock_bh(&sk->sk_callback_lock);
1102 sock->fasync_list = fna; 1152 sock->fasync_list = fna;
1153 sock_set_flag(sk, SOCK_FASYNC);
1103 write_unlock_bh(&sk->sk_callback_lock); 1154 write_unlock_bh(&sk->sk_callback_lock);
1104 } else { 1155 } else {
1105 if (fa != NULL) { 1156 if (fa != NULL) {
1106 write_lock_bh(&sk->sk_callback_lock); 1157 write_lock_bh(&sk->sk_callback_lock);
1107 *prev = fa->fa_next; 1158 *prev = fa->fa_next;
1159 if (!sock->fasync_list)
1160 sock_reset_flag(sk, SOCK_FASYNC);
1108 write_unlock_bh(&sk->sk_callback_lock); 1161 write_unlock_bh(&sk->sk_callback_lock);
1109 kfree(fa); 1162 kfree(fa);
1110 } 1163 }
@@ -1216,7 +1269,7 @@ static int __sock_create(struct net *net, int family, int type, int protocol,
1216 /* Now protected by module ref count */ 1269 /* Now protected by module ref count */
1217 rcu_read_unlock(); 1270 rcu_read_unlock();
1218 1271
1219 err = pf->create(net, sock, protocol); 1272 err = pf->create(net, sock, protocol, kern);
1220 if (err < 0) 1273 if (err < 0)
1221 goto out_module_put; 1274 goto out_module_put;
1222 1275
@@ -1965,22 +2018,15 @@ out:
1965 return err; 2018 return err;
1966} 2019}
1967 2020
1968/* 2021static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
1969 * BSD recvmsg interface 2022 struct msghdr *msg_sys, unsigned flags, int nosec)
1970 */
1971
1972SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
1973 unsigned int, flags)
1974{ 2023{
1975 struct compat_msghdr __user *msg_compat = 2024 struct compat_msghdr __user *msg_compat =
1976 (struct compat_msghdr __user *)msg; 2025 (struct compat_msghdr __user *)msg;
1977 struct socket *sock;
1978 struct iovec iovstack[UIO_FASTIOV]; 2026 struct iovec iovstack[UIO_FASTIOV];
1979 struct iovec *iov = iovstack; 2027 struct iovec *iov = iovstack;
1980 struct msghdr msg_sys;
1981 unsigned long cmsg_ptr; 2028 unsigned long cmsg_ptr;
1982 int err, iov_size, total_len, len; 2029 int err, iov_size, total_len, len;
1983 int fput_needed;
1984 2030
1985 /* kernel mode address */ 2031 /* kernel mode address */
1986 struct sockaddr_storage addr; 2032 struct sockaddr_storage addr;
@@ -1990,27 +2036,23 @@ SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
1990 int __user *uaddr_len; 2036 int __user *uaddr_len;
1991 2037
1992 if (MSG_CMSG_COMPAT & flags) { 2038 if (MSG_CMSG_COMPAT & flags) {
1993 if (get_compat_msghdr(&msg_sys, msg_compat)) 2039 if (get_compat_msghdr(msg_sys, msg_compat))
1994 return -EFAULT; 2040 return -EFAULT;
1995 } 2041 }
1996 else if (copy_from_user(&msg_sys, msg, sizeof(struct msghdr))) 2042 else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr)))
1997 return -EFAULT; 2043 return -EFAULT;
1998 2044
1999 sock = sockfd_lookup_light(fd, &err, &fput_needed);
2000 if (!sock)
2001 goto out;
2002
2003 err = -EMSGSIZE; 2045 err = -EMSGSIZE;
2004 if (msg_sys.msg_iovlen > UIO_MAXIOV) 2046 if (msg_sys->msg_iovlen > UIO_MAXIOV)
2005 goto out_put; 2047 goto out;
2006 2048
2007 /* Check whether to allocate the iovec area */ 2049 /* Check whether to allocate the iovec area */
2008 err = -ENOMEM; 2050 err = -ENOMEM;
2009 iov_size = msg_sys.msg_iovlen * sizeof(struct iovec); 2051 iov_size = msg_sys->msg_iovlen * sizeof(struct iovec);
2010 if (msg_sys.msg_iovlen > UIO_FASTIOV) { 2052 if (msg_sys->msg_iovlen > UIO_FASTIOV) {
2011 iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL); 2053 iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
2012 if (!iov) 2054 if (!iov)
2013 goto out_put; 2055 goto out;
2014 } 2056 }
2015 2057
2016 /* 2058 /*
@@ -2018,46 +2060,47 @@ SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
2018 * kernel msghdr to use the kernel address space) 2060 * kernel msghdr to use the kernel address space)
2019 */ 2061 */
2020 2062
2021 uaddr = (__force void __user *)msg_sys.msg_name; 2063 uaddr = (__force void __user *)msg_sys->msg_name;
2022 uaddr_len = COMPAT_NAMELEN(msg); 2064 uaddr_len = COMPAT_NAMELEN(msg);
2023 if (MSG_CMSG_COMPAT & flags) { 2065 if (MSG_CMSG_COMPAT & flags) {
2024 err = verify_compat_iovec(&msg_sys, iov, 2066 err = verify_compat_iovec(msg_sys, iov,
2025 (struct sockaddr *)&addr, 2067 (struct sockaddr *)&addr,
2026 VERIFY_WRITE); 2068 VERIFY_WRITE);
2027 } else 2069 } else
2028 err = verify_iovec(&msg_sys, iov, 2070 err = verify_iovec(msg_sys, iov,
2029 (struct sockaddr *)&addr, 2071 (struct sockaddr *)&addr,
2030 VERIFY_WRITE); 2072 VERIFY_WRITE);
2031 if (err < 0) 2073 if (err < 0)
2032 goto out_freeiov; 2074 goto out_freeiov;
2033 total_len = err; 2075 total_len = err;
2034 2076
2035 cmsg_ptr = (unsigned long)msg_sys.msg_control; 2077 cmsg_ptr = (unsigned long)msg_sys->msg_control;
2036 msg_sys.msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT); 2078 msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT);
2037 2079
2038 if (sock->file->f_flags & O_NONBLOCK) 2080 if (sock->file->f_flags & O_NONBLOCK)
2039 flags |= MSG_DONTWAIT; 2081 flags |= MSG_DONTWAIT;
2040 err = sock_recvmsg(sock, &msg_sys, total_len, flags); 2082 err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys,
2083 total_len, flags);
2041 if (err < 0) 2084 if (err < 0)
2042 goto out_freeiov; 2085 goto out_freeiov;
2043 len = err; 2086 len = err;
2044 2087
2045 if (uaddr != NULL) { 2088 if (uaddr != NULL) {
2046 err = move_addr_to_user((struct sockaddr *)&addr, 2089 err = move_addr_to_user((struct sockaddr *)&addr,
2047 msg_sys.msg_namelen, uaddr, 2090 msg_sys->msg_namelen, uaddr,
2048 uaddr_len); 2091 uaddr_len);
2049 if (err < 0) 2092 if (err < 0)
2050 goto out_freeiov; 2093 goto out_freeiov;
2051 } 2094 }
2052 err = __put_user((msg_sys.msg_flags & ~MSG_CMSG_COMPAT), 2095 err = __put_user((msg_sys->msg_flags & ~MSG_CMSG_COMPAT),
2053 COMPAT_FLAGS(msg)); 2096 COMPAT_FLAGS(msg));
2054 if (err) 2097 if (err)
2055 goto out_freeiov; 2098 goto out_freeiov;
2056 if (MSG_CMSG_COMPAT & flags) 2099 if (MSG_CMSG_COMPAT & flags)
2057 err = __put_user((unsigned long)msg_sys.msg_control - cmsg_ptr, 2100 err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
2058 &msg_compat->msg_controllen); 2101 &msg_compat->msg_controllen);
2059 else 2102 else
2060 err = __put_user((unsigned long)msg_sys.msg_control - cmsg_ptr, 2103 err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr,
2061 &msg->msg_controllen); 2104 &msg->msg_controllen);
2062 if (err) 2105 if (err)
2063 goto out_freeiov; 2106 goto out_freeiov;
@@ -2066,21 +2109,162 @@ SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
2066out_freeiov: 2109out_freeiov:
2067 if (iov != iovstack) 2110 if (iov != iovstack)
2068 sock_kfree_s(sock->sk, iov, iov_size); 2111 sock_kfree_s(sock->sk, iov, iov_size);
2069out_put: 2112out:
2113 return err;
2114}
2115
2116/*
2117 * BSD recvmsg interface
2118 */
2119
2120SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
2121 unsigned int, flags)
2122{
2123 int fput_needed, err;
2124 struct msghdr msg_sys;
2125 struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed);
2126
2127 if (!sock)
2128 goto out;
2129
2130 err = __sys_recvmsg(sock, msg, &msg_sys, flags, 0);
2131
2070 fput_light(sock->file, fput_needed); 2132 fput_light(sock->file, fput_needed);
2071out: 2133out:
2072 return err; 2134 return err;
2073} 2135}
2074 2136
2075#ifdef __ARCH_WANT_SYS_SOCKETCALL 2137/*
2138 * Linux recvmmsg interface
2139 */
2140
2141int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
2142 unsigned int flags, struct timespec *timeout)
2143{
2144 int fput_needed, err, datagrams;
2145 struct socket *sock;
2146 struct mmsghdr __user *entry;
2147 struct compat_mmsghdr __user *compat_entry;
2148 struct msghdr msg_sys;
2149 struct timespec end_time;
2150
2151 if (timeout &&
2152 poll_select_set_timeout(&end_time, timeout->tv_sec,
2153 timeout->tv_nsec))
2154 return -EINVAL;
2076 2155
2156 datagrams = 0;
2157
2158 sock = sockfd_lookup_light(fd, &err, &fput_needed);
2159 if (!sock)
2160 return err;
2161
2162 err = sock_error(sock->sk);
2163 if (err)
2164 goto out_put;
2165
2166 entry = mmsg;
2167 compat_entry = (struct compat_mmsghdr __user *)mmsg;
2168
2169 while (datagrams < vlen) {
2170 /*
2171 * No need to ask LSM for more than the first datagram.
2172 */
2173 if (MSG_CMSG_COMPAT & flags) {
2174 err = __sys_recvmsg(sock, (struct msghdr __user *)compat_entry,
2175 &msg_sys, flags, datagrams);
2176 if (err < 0)
2177 break;
2178 err = __put_user(err, &compat_entry->msg_len);
2179 ++compat_entry;
2180 } else {
2181 err = __sys_recvmsg(sock, (struct msghdr __user *)entry,
2182 &msg_sys, flags, datagrams);
2183 if (err < 0)
2184 break;
2185 err = put_user(err, &entry->msg_len);
2186 ++entry;
2187 }
2188
2189 if (err)
2190 break;
2191 ++datagrams;
2192
2193 if (timeout) {
2194 ktime_get_ts(timeout);
2195 *timeout = timespec_sub(end_time, *timeout);
2196 if (timeout->tv_sec < 0) {
2197 timeout->tv_sec = timeout->tv_nsec = 0;
2198 break;
2199 }
2200
2201 /* Timeout, return less than vlen datagrams */
2202 if (timeout->tv_nsec == 0 && timeout->tv_sec == 0)
2203 break;
2204 }
2205
2206 /* Out of band data, return right away */
2207 if (msg_sys.msg_flags & MSG_OOB)
2208 break;
2209 }
2210
2211out_put:
2212 fput_light(sock->file, fput_needed);
2213
2214 if (err == 0)
2215 return datagrams;
2216
2217 if (datagrams != 0) {
2218 /*
2219 * We may return less entries than requested (vlen) if the
2220 * sock is non block and there aren't enough datagrams...
2221 */
2222 if (err != -EAGAIN) {
2223 /*
2224 * ... or if recvmsg returns an error after we
2225 * received some datagrams, where we record the
2226 * error to return on the next call or if the
2227 * app asks about it using getsockopt(SO_ERROR).
2228 */
2229 sock->sk->sk_err = -err;
2230 }
2231
2232 return datagrams;
2233 }
2234
2235 return err;
2236}
2237
2238SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg,
2239 unsigned int, vlen, unsigned int, flags,
2240 struct timespec __user *, timeout)
2241{
2242 int datagrams;
2243 struct timespec timeout_sys;
2244
2245 if (!timeout)
2246 return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL);
2247
2248 if (copy_from_user(&timeout_sys, timeout, sizeof(timeout_sys)))
2249 return -EFAULT;
2250
2251 datagrams = __sys_recvmmsg(fd, mmsg, vlen, flags, &timeout_sys);
2252
2253 if (datagrams > 0 &&
2254 copy_to_user(timeout, &timeout_sys, sizeof(timeout_sys)))
2255 datagrams = -EFAULT;
2256
2257 return datagrams;
2258}
2259
2260#ifdef __ARCH_WANT_SYS_SOCKETCALL
2077/* Argument list sizes for sys_socketcall */ 2261/* Argument list sizes for sys_socketcall */
2078#define AL(x) ((x) * sizeof(unsigned long)) 2262#define AL(x) ((x) * sizeof(unsigned long))
2079static const unsigned char nargs[19]={ 2263static const unsigned char nargs[20] = {
2080 AL(0),AL(3),AL(3),AL(3),AL(2),AL(3), 2264 AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
2081 AL(3),AL(3),AL(4),AL(4),AL(4),AL(6), 2265 AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
2082 AL(6),AL(2),AL(5),AL(5),AL(3),AL(3), 2266 AL(6),AL(2),AL(5),AL(5),AL(3),AL(3),
2083 AL(4) 2267 AL(4),AL(5)
2084}; 2268};
2085 2269
2086#undef AL 2270#undef AL
@@ -2100,7 +2284,7 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
2100 int err; 2284 int err;
2101 unsigned int len; 2285 unsigned int len;
2102 2286
2103 if (call < 1 || call > SYS_ACCEPT4) 2287 if (call < 1 || call > SYS_RECVMMSG)
2104 return -EINVAL; 2288 return -EINVAL;
2105 2289
2106 len = nargs[call]; 2290 len = nargs[call];
@@ -2178,6 +2362,10 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
2178 case SYS_RECVMSG: 2362 case SYS_RECVMSG:
2179 err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]); 2363 err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]);
2180 break; 2364 break;
2365 case SYS_RECVMMSG:
2366 err = sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3],
2367 (struct timespec __user *)a[4]);
2368 break;
2181 case SYS_ACCEPT4: 2369 case SYS_ACCEPT4:
2182 err = sys_accept4(a0, (struct sockaddr __user *)a1, 2370 err = sys_accept4(a0, (struct sockaddr __user *)a1,
2183 (int __user *)a[2], a[3]); 2371 (int __user *)a[2], a[3]);
@@ -2300,6 +2488,552 @@ void socket_seq_show(struct seq_file *seq)
2300#endif /* CONFIG_PROC_FS */ 2488#endif /* CONFIG_PROC_FS */
2301 2489
2302#ifdef CONFIG_COMPAT 2490#ifdef CONFIG_COMPAT
2491static int do_siocgstamp(struct net *net, struct socket *sock,
2492 unsigned int cmd, struct compat_timeval __user *up)
2493{
2494 mm_segment_t old_fs = get_fs();
2495 struct timeval ktv;
2496 int err;
2497
2498 set_fs(KERNEL_DS);
2499 err = sock_do_ioctl(net, sock, cmd, (unsigned long)&ktv);
2500 set_fs(old_fs);
2501 if (!err) {
2502 err = put_user(ktv.tv_sec, &up->tv_sec);
2503 err |= __put_user(ktv.tv_usec, &up->tv_usec);
2504 }
2505 return err;
2506}
2507
2508static int do_siocgstampns(struct net *net, struct socket *sock,
2509 unsigned int cmd, struct compat_timespec __user *up)
2510{
2511 mm_segment_t old_fs = get_fs();
2512 struct timespec kts;
2513 int err;
2514
2515 set_fs(KERNEL_DS);
2516 err = sock_do_ioctl(net, sock, cmd, (unsigned long)&kts);
2517 set_fs(old_fs);
2518 if (!err) {
2519 err = put_user(kts.tv_sec, &up->tv_sec);
2520 err |= __put_user(kts.tv_nsec, &up->tv_nsec);
2521 }
2522 return err;
2523}
2524
2525static int dev_ifname32(struct net *net, struct compat_ifreq __user *uifr32)
2526{
2527 struct ifreq __user *uifr;
2528 int err;
2529
2530 uifr = compat_alloc_user_space(sizeof(struct ifreq));
2531 if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq)))
2532 return -EFAULT;
2533
2534 err = dev_ioctl(net, SIOCGIFNAME, uifr);
2535 if (err)
2536 return err;
2537
2538 if (copy_in_user(uifr32, uifr, sizeof(struct compat_ifreq)))
2539 return -EFAULT;
2540
2541 return 0;
2542}
2543
2544static int dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32)
2545{
2546 struct compat_ifconf ifc32;
2547 struct ifconf ifc;
2548 struct ifconf __user *uifc;
2549 struct compat_ifreq __user *ifr32;
2550 struct ifreq __user *ifr;
2551 unsigned int i, j;
2552 int err;
2553
2554 if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf)))
2555 return -EFAULT;
2556
2557 if (ifc32.ifcbuf == 0) {
2558 ifc32.ifc_len = 0;
2559 ifc.ifc_len = 0;
2560 ifc.ifc_req = NULL;
2561 uifc = compat_alloc_user_space(sizeof(struct ifconf));
2562 } else {
2563 size_t len =((ifc32.ifc_len / sizeof (struct compat_ifreq)) + 1) *
2564 sizeof (struct ifreq);
2565 uifc = compat_alloc_user_space(sizeof(struct ifconf) + len);
2566 ifc.ifc_len = len;
2567 ifr = ifc.ifc_req = (void __user *)(uifc + 1);
2568 ifr32 = compat_ptr(ifc32.ifcbuf);
2569 for (i = 0; i < ifc32.ifc_len; i += sizeof (struct compat_ifreq)) {
2570 if (copy_in_user(ifr, ifr32, sizeof(struct compat_ifreq)))
2571 return -EFAULT;
2572 ifr++;
2573 ifr32++;
2574 }
2575 }
2576 if (copy_to_user(uifc, &ifc, sizeof(struct ifconf)))
2577 return -EFAULT;
2578
2579 err = dev_ioctl(net, SIOCGIFCONF, uifc);
2580 if (err)
2581 return err;
2582
2583 if (copy_from_user(&ifc, uifc, sizeof(struct ifconf)))
2584 return -EFAULT;
2585
2586 ifr = ifc.ifc_req;
2587 ifr32 = compat_ptr(ifc32.ifcbuf);
2588 for (i = 0, j = 0;
2589 i + sizeof (struct compat_ifreq) <= ifc32.ifc_len && j < ifc.ifc_len;
2590 i += sizeof (struct compat_ifreq), j += sizeof (struct ifreq)) {
2591 if (copy_in_user(ifr32, ifr, sizeof (struct compat_ifreq)))
2592 return -EFAULT;
2593 ifr32++;
2594 ifr++;
2595 }
2596
2597 if (ifc32.ifcbuf == 0) {
2598 /* Translate from 64-bit structure multiple to
2599 * a 32-bit one.
2600 */
2601 i = ifc.ifc_len;
2602 i = ((i / sizeof(struct ifreq)) * sizeof(struct compat_ifreq));
2603 ifc32.ifc_len = i;
2604 } else {
2605 ifc32.ifc_len = i;
2606 }
2607 if (copy_to_user(uifc32, &ifc32, sizeof(struct compat_ifconf)))
2608 return -EFAULT;
2609
2610 return 0;
2611}
2612
2613static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
2614{
2615 struct ifreq __user *ifr;
2616 u32 data;
2617 void __user *datap;
2618
2619 ifr = compat_alloc_user_space(sizeof(*ifr));
2620
2621 if (copy_in_user(&ifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ))
2622 return -EFAULT;
2623
2624 if (get_user(data, &ifr32->ifr_ifru.ifru_data))
2625 return -EFAULT;
2626
2627 datap = compat_ptr(data);
2628 if (put_user(datap, &ifr->ifr_ifru.ifru_data))
2629 return -EFAULT;
2630
2631 return dev_ioctl(net, SIOCETHTOOL, ifr);
2632}
2633
2634static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32)
2635{
2636 void __user *uptr;
2637 compat_uptr_t uptr32;
2638 struct ifreq __user *uifr;
2639
2640 uifr = compat_alloc_user_space(sizeof (*uifr));
2641 if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq)))
2642 return -EFAULT;
2643
2644 if (get_user(uptr32, &uifr32->ifr_settings.ifs_ifsu))
2645 return -EFAULT;
2646
2647 uptr = compat_ptr(uptr32);
2648
2649 if (put_user(uptr, &uifr->ifr_settings.ifs_ifsu.raw_hdlc))
2650 return -EFAULT;
2651
2652 return dev_ioctl(net, SIOCWANDEV, uifr);
2653}
2654
2655static int bond_ioctl(struct net *net, unsigned int cmd,
2656 struct compat_ifreq __user *ifr32)
2657{
2658 struct ifreq kifr;
2659 struct ifreq __user *uifr;
2660 mm_segment_t old_fs;
2661 int err;
2662 u32 data;
2663 void __user *datap;
2664
2665 switch (cmd) {
2666 case SIOCBONDENSLAVE:
2667 case SIOCBONDRELEASE:
2668 case SIOCBONDSETHWADDR:
2669 case SIOCBONDCHANGEACTIVE:
2670 if (copy_from_user(&kifr, ifr32, sizeof(struct compat_ifreq)))
2671 return -EFAULT;
2672
2673 old_fs = get_fs();
2674 set_fs (KERNEL_DS);
2675 err = dev_ioctl(net, cmd, &kifr);
2676 set_fs (old_fs);
2677
2678 return err;
2679 case SIOCBONDSLAVEINFOQUERY:
2680 case SIOCBONDINFOQUERY:
2681 uifr = compat_alloc_user_space(sizeof(*uifr));
2682 if (copy_in_user(&uifr->ifr_name, &ifr32->ifr_name, IFNAMSIZ))
2683 return -EFAULT;
2684
2685 if (get_user(data, &ifr32->ifr_ifru.ifru_data))
2686 return -EFAULT;
2687
2688 datap = compat_ptr(data);
2689 if (put_user(datap, &uifr->ifr_ifru.ifru_data))
2690 return -EFAULT;
2691
2692 return dev_ioctl(net, cmd, uifr);
2693 default:
2694 return -EINVAL;
2695 };
2696}
2697
2698static int siocdevprivate_ioctl(struct net *net, unsigned int cmd,
2699 struct compat_ifreq __user *u_ifreq32)
2700{
2701 struct ifreq __user *u_ifreq64;
2702 char tmp_buf[IFNAMSIZ];
2703 void __user *data64;
2704 u32 data32;
2705
2706 if (copy_from_user(&tmp_buf[0], &(u_ifreq32->ifr_ifrn.ifrn_name[0]),
2707 IFNAMSIZ))
2708 return -EFAULT;
2709 if (__get_user(data32, &u_ifreq32->ifr_ifru.ifru_data))
2710 return -EFAULT;
2711 data64 = compat_ptr(data32);
2712
2713 u_ifreq64 = compat_alloc_user_space(sizeof(*u_ifreq64));
2714
2715 /* Don't check these user accesses, just let that get trapped
2716 * in the ioctl handler instead.
2717 */
2718 if (copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0],
2719 IFNAMSIZ))
2720 return -EFAULT;
2721 if (__put_user(data64, &u_ifreq64->ifr_ifru.ifru_data))
2722 return -EFAULT;
2723
2724 return dev_ioctl(net, cmd, u_ifreq64);
2725}
2726
2727static int dev_ifsioc(struct net *net, struct socket *sock,
2728 unsigned int cmd, struct compat_ifreq __user *uifr32)
2729{
2730 struct ifreq __user *uifr;
2731 int err;
2732
2733 uifr = compat_alloc_user_space(sizeof(*uifr));
2734 if (copy_in_user(uifr, uifr32, sizeof(*uifr32)))
2735 return -EFAULT;
2736
2737 err = sock_do_ioctl(net, sock, cmd, (unsigned long)uifr);
2738
2739 if (!err) {
2740 switch (cmd) {
2741 case SIOCGIFFLAGS:
2742 case SIOCGIFMETRIC:
2743 case SIOCGIFMTU:
2744 case SIOCGIFMEM:
2745 case SIOCGIFHWADDR:
2746 case SIOCGIFINDEX:
2747 case SIOCGIFADDR:
2748 case SIOCGIFBRDADDR:
2749 case SIOCGIFDSTADDR:
2750 case SIOCGIFNETMASK:
2751 case SIOCGIFPFLAGS:
2752 case SIOCGIFTXQLEN:
2753 case SIOCGMIIPHY:
2754 case SIOCGMIIREG:
2755 if (copy_in_user(uifr32, uifr, sizeof(*uifr32)))
2756 err = -EFAULT;
2757 break;
2758 }
2759 }
2760 return err;
2761}
2762
2763static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
2764 struct compat_ifreq __user *uifr32)
2765{
2766 struct ifreq ifr;
2767 struct compat_ifmap __user *uifmap32;
2768 mm_segment_t old_fs;
2769 int err;
2770
2771 uifmap32 = &uifr32->ifr_ifru.ifru_map;
2772 err = copy_from_user(&ifr, uifr32, sizeof(ifr.ifr_name));
2773 err |= __get_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
2774 err |= __get_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
2775 err |= __get_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
2776 err |= __get_user(ifr.ifr_map.irq, &uifmap32->irq);
2777 err |= __get_user(ifr.ifr_map.dma, &uifmap32->dma);
2778 err |= __get_user(ifr.ifr_map.port, &uifmap32->port);
2779 if (err)
2780 return -EFAULT;
2781
2782 old_fs = get_fs();
2783 set_fs (KERNEL_DS);
2784 err = dev_ioctl(net, cmd, (void __user *)&ifr);
2785 set_fs (old_fs);
2786
2787 if (cmd == SIOCGIFMAP && !err) {
2788 err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name));
2789 err |= __put_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
2790 err |= __put_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
2791 err |= __put_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
2792 err |= __put_user(ifr.ifr_map.irq, &uifmap32->irq);
2793 err |= __put_user(ifr.ifr_map.dma, &uifmap32->dma);
2794 err |= __put_user(ifr.ifr_map.port, &uifmap32->port);
2795 if (err)
2796 err = -EFAULT;
2797 }
2798 return err;
2799}
2800
2801static int compat_siocshwtstamp(struct net *net, struct compat_ifreq __user *uifr32)
2802{
2803 void __user *uptr;
2804 compat_uptr_t uptr32;
2805 struct ifreq __user *uifr;
2806
2807 uifr = compat_alloc_user_space(sizeof (*uifr));
2808 if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq)))
2809 return -EFAULT;
2810
2811 if (get_user(uptr32, &uifr32->ifr_data))
2812 return -EFAULT;
2813
2814 uptr = compat_ptr(uptr32);
2815
2816 if (put_user(uptr, &uifr->ifr_data))
2817 return -EFAULT;
2818
2819 return dev_ioctl(net, SIOCSHWTSTAMP, uifr);
2820}
2821
2822struct rtentry32 {
2823 u32 rt_pad1;
2824 struct sockaddr rt_dst; /* target address */
2825 struct sockaddr rt_gateway; /* gateway addr (RTF_GATEWAY) */
2826 struct sockaddr rt_genmask; /* target network mask (IP) */
2827 unsigned short rt_flags;
2828 short rt_pad2;
2829 u32 rt_pad3;
2830 unsigned char rt_tos;
2831 unsigned char rt_class;
2832 short rt_pad4;
2833 short rt_metric; /* +1 for binary compatibility! */
2834 /* char * */ u32 rt_dev; /* forcing the device at add */
2835 u32 rt_mtu; /* per route MTU/Window */
2836 u32 rt_window; /* Window clamping */
2837 unsigned short rt_irtt; /* Initial RTT */
2838};
2839
2840struct in6_rtmsg32 {
2841 struct in6_addr rtmsg_dst;
2842 struct in6_addr rtmsg_src;
2843 struct in6_addr rtmsg_gateway;
2844 u32 rtmsg_type;
2845 u16 rtmsg_dst_len;
2846 u16 rtmsg_src_len;
2847 u32 rtmsg_metric;
2848 u32 rtmsg_info;
2849 u32 rtmsg_flags;
2850 s32 rtmsg_ifindex;
2851};
2852
2853static int routing_ioctl(struct net *net, struct socket *sock,
2854 unsigned int cmd, void __user *argp)
2855{
2856 int ret;
2857 void *r = NULL;
2858 struct in6_rtmsg r6;
2859 struct rtentry r4;
2860 char devname[16];
2861 u32 rtdev;
2862 mm_segment_t old_fs = get_fs();
2863
2864 if (sock && sock->sk && sock->sk->sk_family == AF_INET6) { /* ipv6 */
2865 struct in6_rtmsg32 __user *ur6 = argp;
2866 ret = copy_from_user (&r6.rtmsg_dst, &(ur6->rtmsg_dst),
2867 3 * sizeof(struct in6_addr));
2868 ret |= __get_user (r6.rtmsg_type, &(ur6->rtmsg_type));
2869 ret |= __get_user (r6.rtmsg_dst_len, &(ur6->rtmsg_dst_len));
2870 ret |= __get_user (r6.rtmsg_src_len, &(ur6->rtmsg_src_len));
2871 ret |= __get_user (r6.rtmsg_metric, &(ur6->rtmsg_metric));
2872 ret |= __get_user (r6.rtmsg_info, &(ur6->rtmsg_info));
2873 ret |= __get_user (r6.rtmsg_flags, &(ur6->rtmsg_flags));
2874 ret |= __get_user (r6.rtmsg_ifindex, &(ur6->rtmsg_ifindex));
2875
2876 r = (void *) &r6;
2877 } else { /* ipv4 */
2878 struct rtentry32 __user *ur4 = argp;
2879 ret = copy_from_user (&r4.rt_dst, &(ur4->rt_dst),
2880 3 * sizeof(struct sockaddr));
2881 ret |= __get_user (r4.rt_flags, &(ur4->rt_flags));
2882 ret |= __get_user (r4.rt_metric, &(ur4->rt_metric));
2883 ret |= __get_user (r4.rt_mtu, &(ur4->rt_mtu));
2884 ret |= __get_user (r4.rt_window, &(ur4->rt_window));
2885 ret |= __get_user (r4.rt_irtt, &(ur4->rt_irtt));
2886 ret |= __get_user (rtdev, &(ur4->rt_dev));
2887 if (rtdev) {
2888 ret |= copy_from_user (devname, compat_ptr(rtdev), 15);
2889 r4.rt_dev = devname; devname[15] = 0;
2890 } else
2891 r4.rt_dev = NULL;
2892
2893 r = (void *) &r4;
2894 }
2895
2896 if (ret) {
2897 ret = -EFAULT;
2898 goto out;
2899 }
2900
2901 set_fs (KERNEL_DS);
2902 ret = sock_do_ioctl(net, sock, cmd, (unsigned long) r);
2903 set_fs (old_fs);
2904
2905out:
2906 return ret;
2907}
2908
2909/* Since old style bridge ioctl's endup using SIOCDEVPRIVATE
2910 * for some operations; this forces use of the newer bridge-utils that
2911 * use compatiable ioctls
2912 */
2913static int old_bridge_ioctl(compat_ulong_t __user *argp)
2914{
2915 compat_ulong_t tmp;
2916
2917 if (get_user(tmp, argp))
2918 return -EFAULT;
2919 if (tmp == BRCTL_GET_VERSION)
2920 return BRCTL_VERSION + 1;
2921 return -EINVAL;
2922}
2923
2924static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
2925 unsigned int cmd, unsigned long arg)
2926{
2927 void __user *argp = compat_ptr(arg);
2928 struct sock *sk = sock->sk;
2929 struct net *net = sock_net(sk);
2930
2931 if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))
2932 return siocdevprivate_ioctl(net, cmd, argp);
2933
2934 switch (cmd) {
2935 case SIOCSIFBR:
2936 case SIOCGIFBR:
2937 return old_bridge_ioctl(argp);
2938 case SIOCGIFNAME:
2939 return dev_ifname32(net, argp);
2940 case SIOCGIFCONF:
2941 return dev_ifconf(net, argp);
2942 case SIOCETHTOOL:
2943 return ethtool_ioctl(net, argp);
2944 case SIOCWANDEV:
2945 return compat_siocwandev(net, argp);
2946 case SIOCGIFMAP:
2947 case SIOCSIFMAP:
2948 return compat_sioc_ifmap(net, cmd, argp);
2949 case SIOCBONDENSLAVE:
2950 case SIOCBONDRELEASE:
2951 case SIOCBONDSETHWADDR:
2952 case SIOCBONDSLAVEINFOQUERY:
2953 case SIOCBONDINFOQUERY:
2954 case SIOCBONDCHANGEACTIVE:
2955 return bond_ioctl(net, cmd, argp);
2956 case SIOCADDRT:
2957 case SIOCDELRT:
2958 return routing_ioctl(net, sock, cmd, argp);
2959 case SIOCGSTAMP:
2960 return do_siocgstamp(net, sock, cmd, argp);
2961 case SIOCGSTAMPNS:
2962 return do_siocgstampns(net, sock, cmd, argp);
2963 case SIOCSHWTSTAMP:
2964 return compat_siocshwtstamp(net, argp);
2965
2966 case FIOSETOWN:
2967 case SIOCSPGRP:
2968 case FIOGETOWN:
2969 case SIOCGPGRP:
2970 case SIOCBRADDBR:
2971 case SIOCBRDELBR:
2972 case SIOCGIFVLAN:
2973 case SIOCSIFVLAN:
2974 case SIOCADDDLCI:
2975 case SIOCDELDLCI:
2976 return sock_ioctl(file, cmd, arg);
2977
2978 case SIOCGIFFLAGS:
2979 case SIOCSIFFLAGS:
2980 case SIOCGIFMETRIC:
2981 case SIOCSIFMETRIC:
2982 case SIOCGIFMTU:
2983 case SIOCSIFMTU:
2984 case SIOCGIFMEM:
2985 case SIOCSIFMEM:
2986 case SIOCGIFHWADDR:
2987 case SIOCSIFHWADDR:
2988 case SIOCADDMULTI:
2989 case SIOCDELMULTI:
2990 case SIOCGIFINDEX:
2991 case SIOCGIFADDR:
2992 case SIOCSIFADDR:
2993 case SIOCSIFHWBROADCAST:
2994 case SIOCDIFADDR:
2995 case SIOCGIFBRDADDR:
2996 case SIOCSIFBRDADDR:
2997 case SIOCGIFDSTADDR:
2998 case SIOCSIFDSTADDR:
2999 case SIOCGIFNETMASK:
3000 case SIOCSIFNETMASK:
3001 case SIOCSIFPFLAGS:
3002 case SIOCGIFPFLAGS:
3003 case SIOCGIFTXQLEN:
3004 case SIOCSIFTXQLEN:
3005 case SIOCBRADDIF:
3006 case SIOCBRDELIF:
3007 case SIOCSIFNAME:
3008 case SIOCGMIIPHY:
3009 case SIOCGMIIREG:
3010 case SIOCSMIIREG:
3011 return dev_ifsioc(net, sock, cmd, argp);
3012
3013 case SIOCSARP:
3014 case SIOCGARP:
3015 case SIOCDARP:
3016 case SIOCATMARK:
3017 return sock_do_ioctl(net, sock, cmd, arg);
3018 }
3019
3020 /* Prevent warning from compat_sys_ioctl, these always
3021 * result in -EINVAL in the native case anyway. */
3022 switch (cmd) {
3023 case SIOCRTMSG:
3024 case SIOCGIFCOUNT:
3025 case SIOCSRARP:
3026 case SIOCGRARP:
3027 case SIOCDRARP:
3028 case SIOCSIFLINK:
3029 case SIOCGIFSLAVE:
3030 case SIOCSIFSLAVE:
3031 return -EINVAL;
3032 }
3033
3034 return -ENOIOCTLCMD;
3035}
3036
2303static long compat_sock_ioctl(struct file *file, unsigned cmd, 3037static long compat_sock_ioctl(struct file *file, unsigned cmd,
2304 unsigned long arg) 3038 unsigned long arg)
2305{ 3039{
@@ -2318,6 +3052,9 @@ static long compat_sock_ioctl(struct file *file, unsigned cmd,
2318 (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST)) 3052 (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST))
2319 ret = compat_wext_handle_ioctl(net, cmd, arg); 3053 ret = compat_wext_handle_ioctl(net, cmd, arg);
2320 3054
3055 if (ret == -ENOIOCTLCMD)
3056 ret = compat_sock_ioctl_trans(file, sock, cmd, arg);
3057
2321 return ret; 3058 return ret;
2322} 3059}
2323#endif 3060#endif