aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/net.h19
-rw-r--r--net/socket.c113
2 files changed, 132 insertions, 0 deletions
diff --git a/include/linux/net.h b/include/linux/net.h
index b20c53c74413..19da2c08d7b6 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -208,6 +208,25 @@ extern int kernel_recvmsg(struct socket *sock, struct msghdr *msg,
208 struct kvec *vec, size_t num, 208 struct kvec *vec, size_t num,
209 size_t len, int flags); 209 size_t len, int flags);
210 210
211extern int kernel_bind(struct socket *sock, struct sockaddr *addr,
212 int addrlen);
213extern int kernel_listen(struct socket *sock, int backlog);
214extern int kernel_accept(struct socket *sock, struct socket **newsock,
215 int flags);
216extern int kernel_connect(struct socket *sock, struct sockaddr *addr,
217 int addrlen, int flags);
218extern int kernel_getsockname(struct socket *sock, struct sockaddr *addr,
219 int *addrlen);
220extern int kernel_getpeername(struct socket *sock, struct sockaddr *addr,
221 int *addrlen);
222extern int kernel_getsockopt(struct socket *sock, int level, int optname,
223 char *optval, int *optlen);
224extern int kernel_setsockopt(struct socket *sock, int level, int optname,
225 char *optval, int optlen);
226extern int kernel_sendpage(struct socket *sock, struct page *page, int offset,
227 size_t size, int flags);
228extern int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg);
229
211#ifndef CONFIG_SMP 230#ifndef CONFIG_SMP
212#define SOCKOPS_WRAPPED(name) name 231#define SOCKOPS_WRAPPED(name) name
213#define SOCKOPS_WRAP(name, fam) 232#define SOCKOPS_WRAP(name, fam)
diff --git a/net/socket.c b/net/socket.c
index 6756e57e1ff0..2eaebf934a1a 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2170,6 +2170,109 @@ static long compat_sock_ioctl(struct file *file, unsigned cmd,
2170} 2170}
2171#endif 2171#endif
2172 2172
2173int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen)
2174{
2175 return sock->ops->bind(sock, addr, addrlen);
2176}
2177
2178int kernel_listen(struct socket *sock, int backlog)
2179{
2180 return sock->ops->listen(sock, backlog);
2181}
2182
2183int kernel_accept(struct socket *sock, struct socket **newsock, int flags)
2184{
2185 struct sock *sk = sock->sk;
2186 int err;
2187
2188 err = sock_create_lite(sk->sk_family, sk->sk_type, sk->sk_protocol,
2189 newsock);
2190 if (err < 0)
2191 goto done;
2192
2193 err = sock->ops->accept(sock, *newsock, flags);
2194 if (err < 0) {
2195 sock_release(*newsock);
2196 goto done;
2197 }
2198
2199 (*newsock)->ops = sock->ops;
2200
2201done:
2202 return err;
2203}
2204
2205int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen,
2206 int flags)
2207{
2208 return sock->ops->connect(sock, addr, addrlen, flags);
2209}
2210
2211int kernel_getsockname(struct socket *sock, struct sockaddr *addr,
2212 int *addrlen)
2213{
2214 return sock->ops->getname(sock, addr, addrlen, 0);
2215}
2216
2217int kernel_getpeername(struct socket *sock, struct sockaddr *addr,
2218 int *addrlen)
2219{
2220 return sock->ops->getname(sock, addr, addrlen, 1);
2221}
2222
2223int kernel_getsockopt(struct socket *sock, int level, int optname,
2224 char *optval, int *optlen)
2225{
2226 mm_segment_t oldfs = get_fs();
2227 int err;
2228
2229 set_fs(KERNEL_DS);
2230 if (level == SOL_SOCKET)
2231 err = sock_getsockopt(sock, level, optname, optval, optlen);
2232 else
2233 err = sock->ops->getsockopt(sock, level, optname, optval,
2234 optlen);
2235 set_fs(oldfs);
2236 return err;
2237}
2238
2239int kernel_setsockopt(struct socket *sock, int level, int optname,
2240 char *optval, int optlen)
2241{
2242 mm_segment_t oldfs = get_fs();
2243 int err;
2244
2245 set_fs(KERNEL_DS);
2246 if (level == SOL_SOCKET)
2247 err = sock_setsockopt(sock, level, optname, optval, optlen);
2248 else
2249 err = sock->ops->setsockopt(sock, level, optname, optval,
2250 optlen);
2251 set_fs(oldfs);
2252 return err;
2253}
2254
2255int kernel_sendpage(struct socket *sock, struct page *page, int offset,
2256 size_t size, int flags)
2257{
2258 if (sock->ops->sendpage)
2259 return sock->ops->sendpage(sock, page, offset, size, flags);
2260
2261 return sock_no_sendpage(sock, page, offset, size, flags);
2262}
2263
2264int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg)
2265{
2266 mm_segment_t oldfs = get_fs();
2267 int err;
2268
2269 set_fs(KERNEL_DS);
2270 err = sock->ops->ioctl(sock, cmd, arg);
2271 set_fs(oldfs);
2272
2273 return err;
2274}
2275
2173/* ABI emulation layers need these two */ 2276/* ABI emulation layers need these two */
2174EXPORT_SYMBOL(move_addr_to_kernel); 2277EXPORT_SYMBOL(move_addr_to_kernel);
2175EXPORT_SYMBOL(move_addr_to_user); 2278EXPORT_SYMBOL(move_addr_to_user);
@@ -2186,3 +2289,13 @@ EXPORT_SYMBOL(sock_wake_async);
2186EXPORT_SYMBOL(sockfd_lookup); 2289EXPORT_SYMBOL(sockfd_lookup);
2187EXPORT_SYMBOL(kernel_sendmsg); 2290EXPORT_SYMBOL(kernel_sendmsg);
2188EXPORT_SYMBOL(kernel_recvmsg); 2291EXPORT_SYMBOL(kernel_recvmsg);
2292EXPORT_SYMBOL(kernel_bind);
2293EXPORT_SYMBOL(kernel_listen);
2294EXPORT_SYMBOL(kernel_accept);
2295EXPORT_SYMBOL(kernel_connect);
2296EXPORT_SYMBOL(kernel_getsockname);
2297EXPORT_SYMBOL(kernel_getpeername);
2298EXPORT_SYMBOL(kernel_getsockopt);
2299EXPORT_SYMBOL(kernel_setsockopt);
2300EXPORT_SYMBOL(kernel_sendpage);
2301EXPORT_SYMBOL(kernel_sock_ioctl);