diff options
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 146 |
1 files changed, 116 insertions, 30 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 515ce38e4f4c..ce8249c76827 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * net/tipc/socket.c: TIPC socket API | 2 | * net/tipc/socket.c: TIPC socket API |
3 | * | 3 | * |
4 | * Copyright (c) 2001-2007, 2012 Ericsson AB | 4 | * Copyright (c) 2001-2007, 2012 Ericsson AB |
5 | * Copyright (c) 2004-2008, 2010-2012, Wind River Systems | 5 | * Copyright (c) 2004-2008, 2010-2013, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
@@ -43,8 +43,6 @@ | |||
43 | #define SS_LISTENING -1 /* socket is listening */ | 43 | #define SS_LISTENING -1 /* socket is listening */ |
44 | #define SS_READY -2 /* socket is connectionless */ | 44 | #define SS_READY -2 /* socket is connectionless */ |
45 | 45 | ||
46 | #define CONN_OVERLOAD_LIMIT ((TIPC_FLOW_CONTROL_WIN * 2 + 1) * \ | ||
47 | SKB_TRUESIZE(TIPC_MAX_USER_MSG_SIZE)) | ||
48 | #define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ | 46 | #define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ |
49 | 47 | ||
50 | struct tipc_sock { | 48 | struct tipc_sock { |
@@ -65,12 +63,15 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf); | |||
65 | static void wakeupdispatch(struct tipc_port *tport); | 63 | static void wakeupdispatch(struct tipc_port *tport); |
66 | static void tipc_data_ready(struct sock *sk, int len); | 64 | static void tipc_data_ready(struct sock *sk, int len); |
67 | static void tipc_write_space(struct sock *sk); | 65 | static void tipc_write_space(struct sock *sk); |
66 | static int release(struct socket *sock); | ||
67 | static int accept(struct socket *sock, struct socket *new_sock, int flags); | ||
68 | 68 | ||
69 | static const struct proto_ops packet_ops; | 69 | static const struct proto_ops packet_ops; |
70 | static const struct proto_ops stream_ops; | 70 | static const struct proto_ops stream_ops; |
71 | static const struct proto_ops msg_ops; | 71 | static const struct proto_ops msg_ops; |
72 | 72 | ||
73 | static struct proto tipc_proto; | 73 | static struct proto tipc_proto; |
74 | static struct proto tipc_proto_kern; | ||
74 | 75 | ||
75 | static int sockets_enabled; | 76 | static int sockets_enabled; |
76 | 77 | ||
@@ -143,7 +144,7 @@ static void reject_rx_queue(struct sock *sk) | |||
143 | } | 144 | } |
144 | 145 | ||
145 | /** | 146 | /** |
146 | * tipc_create - create a TIPC socket | 147 | * tipc_sk_create - create a TIPC socket |
147 | * @net: network namespace (must be default network) | 148 | * @net: network namespace (must be default network) |
148 | * @sock: pre-allocated socket structure | 149 | * @sock: pre-allocated socket structure |
149 | * @protocol: protocol indicator (must be 0) | 150 | * @protocol: protocol indicator (must be 0) |
@@ -154,8 +155,8 @@ static void reject_rx_queue(struct sock *sk) | |||
154 | * | 155 | * |
155 | * Returns 0 on success, errno otherwise | 156 | * Returns 0 on success, errno otherwise |
156 | */ | 157 | */ |
157 | static int tipc_create(struct net *net, struct socket *sock, int protocol, | 158 | static int tipc_sk_create(struct net *net, struct socket *sock, int protocol, |
158 | int kern) | 159 | int kern) |
159 | { | 160 | { |
160 | const struct proto_ops *ops; | 161 | const struct proto_ops *ops; |
161 | socket_state state; | 162 | socket_state state; |
@@ -185,13 +186,17 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol, | |||
185 | } | 186 | } |
186 | 187 | ||
187 | /* Allocate socket's protocol area */ | 188 | /* Allocate socket's protocol area */ |
188 | sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto); | 189 | if (!kern) |
190 | sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto); | ||
191 | else | ||
192 | sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto_kern); | ||
193 | |||
189 | if (sk == NULL) | 194 | if (sk == NULL) |
190 | return -ENOMEM; | 195 | return -ENOMEM; |
191 | 196 | ||
192 | /* Allocate TIPC port for socket to use */ | 197 | /* Allocate TIPC port for socket to use */ |
193 | tp_ptr = tipc_createport_raw(sk, &dispatch, &wakeupdispatch, | 198 | tp_ptr = tipc_createport(sk, &dispatch, &wakeupdispatch, |
194 | TIPC_LOW_IMPORTANCE); | 199 | TIPC_LOW_IMPORTANCE); |
195 | if (unlikely(!tp_ptr)) { | 200 | if (unlikely(!tp_ptr)) { |
196 | sk_free(sk); | 201 | sk_free(sk); |
197 | return -ENOMEM; | 202 | return -ENOMEM; |
@@ -203,6 +208,7 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol, | |||
203 | 208 | ||
204 | sock_init_data(sock, sk); | 209 | sock_init_data(sock, sk); |
205 | sk->sk_backlog_rcv = backlog_rcv; | 210 | sk->sk_backlog_rcv = backlog_rcv; |
211 | sk->sk_rcvbuf = sysctl_tipc_rmem[1]; | ||
206 | sk->sk_data_ready = tipc_data_ready; | 212 | sk->sk_data_ready = tipc_data_ready; |
207 | sk->sk_write_space = tipc_write_space; | 213 | sk->sk_write_space = tipc_write_space; |
208 | tipc_sk(sk)->p = tp_ptr; | 214 | tipc_sk(sk)->p = tp_ptr; |
@@ -220,6 +226,78 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol, | |||
220 | } | 226 | } |
221 | 227 | ||
222 | /** | 228 | /** |
229 | * tipc_sock_create_local - create TIPC socket from inside TIPC module | ||
230 | * @type: socket type - SOCK_RDM or SOCK_SEQPACKET | ||
231 | * | ||
232 | * We cannot use sock_creat_kern here because it bumps module user count. | ||
233 | * Since socket owner and creator is the same module we must make sure | ||
234 | * that module count remains zero for module local sockets, otherwise | ||
235 | * we cannot do rmmod. | ||
236 | * | ||
237 | * Returns 0 on success, errno otherwise | ||
238 | */ | ||
239 | int tipc_sock_create_local(int type, struct socket **res) | ||
240 | { | ||
241 | int rc; | ||
242 | struct sock *sk; | ||
243 | |||
244 | rc = sock_create_lite(AF_TIPC, type, 0, res); | ||
245 | if (rc < 0) { | ||
246 | pr_err("Failed to create kernel socket\n"); | ||
247 | return rc; | ||
248 | } | ||
249 | tipc_sk_create(&init_net, *res, 0, 1); | ||
250 | |||
251 | sk = (*res)->sk; | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | /** | ||
257 | * tipc_sock_release_local - release socket created by tipc_sock_create_local | ||
258 | * @sock: the socket to be released. | ||
259 | * | ||
260 | * Module reference count is not incremented when such sockets are created, | ||
261 | * so we must keep it from being decremented when they are released. | ||
262 | */ | ||
263 | void tipc_sock_release_local(struct socket *sock) | ||
264 | { | ||
265 | release(sock); | ||
266 | sock->ops = NULL; | ||
267 | sock_release(sock); | ||
268 | } | ||
269 | |||
270 | /** | ||
271 | * tipc_sock_accept_local - accept a connection on a socket created | ||
272 | * with tipc_sock_create_local. Use this function to avoid that | ||
273 | * module reference count is inadvertently incremented. | ||
274 | * | ||
275 | * @sock: the accepting socket | ||
276 | * @newsock: reference to the new socket to be created | ||
277 | * @flags: socket flags | ||
278 | */ | ||
279 | |||
280 | int tipc_sock_accept_local(struct socket *sock, struct socket **newsock, | ||
281 | int flags) | ||
282 | { | ||
283 | struct sock *sk = sock->sk; | ||
284 | int ret; | ||
285 | |||
286 | ret = sock_create_lite(sk->sk_family, sk->sk_type, | ||
287 | sk->sk_protocol, newsock); | ||
288 | if (ret < 0) | ||
289 | return ret; | ||
290 | |||
291 | ret = accept(sock, *newsock, flags); | ||
292 | if (ret < 0) { | ||
293 | sock_release(*newsock); | ||
294 | return ret; | ||
295 | } | ||
296 | (*newsock)->ops = sock->ops; | ||
297 | return ret; | ||
298 | } | ||
299 | |||
300 | /** | ||
223 | * release - destroy a TIPC socket | 301 | * release - destroy a TIPC socket |
224 | * @sock: socket to destroy | 302 | * @sock: socket to destroy |
225 | * | 303 | * |
@@ -324,7 +402,9 @@ static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len) | |||
324 | else if (addr->addrtype != TIPC_ADDR_NAMESEQ) | 402 | else if (addr->addrtype != TIPC_ADDR_NAMESEQ) |
325 | return -EAFNOSUPPORT; | 403 | return -EAFNOSUPPORT; |
326 | 404 | ||
327 | if (addr->addr.nameseq.type < TIPC_RESERVED_TYPES) | 405 | if ((addr->addr.nameseq.type < TIPC_RESERVED_TYPES) && |
406 | (addr->addr.nameseq.type != TIPC_TOP_SRV) && | ||
407 | (addr->addr.nameseq.type != TIPC_CFG_SRV)) | ||
328 | return -EACCES; | 408 | return -EACCES; |
329 | 409 | ||
330 | return (addr->scope > 0) ? | 410 | return (addr->scope > 0) ? |
@@ -519,8 +599,7 @@ static int send_msg(struct kiocb *iocb, struct socket *sock, | |||
519 | res = -EISCONN; | 599 | res = -EISCONN; |
520 | goto exit; | 600 | goto exit; |
521 | } | 601 | } |
522 | if ((tport->published) || | 602 | if (tport->published) { |
523 | ((sock->type == SOCK_STREAM) && (total_len != 0))) { | ||
524 | res = -EOPNOTSUPP; | 603 | res = -EOPNOTSUPP; |
525 | goto exit; | 604 | goto exit; |
526 | } | 605 | } |
@@ -810,7 +889,7 @@ static void set_orig_addr(struct msghdr *m, struct tipc_msg *msg) | |||
810 | * Returns 0 if successful, otherwise errno | 889 | * Returns 0 if successful, otherwise errno |
811 | */ | 890 | */ |
812 | static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg, | 891 | static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg, |
813 | struct tipc_port *tport) | 892 | struct tipc_port *tport) |
814 | { | 893 | { |
815 | u32 anc_data[3]; | 894 | u32 anc_data[3]; |
816 | u32 err; | 895 | u32 err; |
@@ -1011,8 +1090,7 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock, | |||
1011 | 1090 | ||
1012 | lock_sock(sk); | 1091 | lock_sock(sk); |
1013 | 1092 | ||
1014 | if (unlikely((sock->state == SS_UNCONNECTED) || | 1093 | if (unlikely((sock->state == SS_UNCONNECTED))) { |
1015 | (sock->state == SS_CONNECTING))) { | ||
1016 | res = -ENOTCONN; | 1094 | res = -ENOTCONN; |
1017 | goto exit; | 1095 | goto exit; |
1018 | } | 1096 | } |
@@ -1233,10 +1311,10 @@ static u32 filter_connect(struct tipc_sock *tsock, struct sk_buff **buf) | |||
1233 | * For all connectionless messages, by default new queue limits are | 1311 | * For all connectionless messages, by default new queue limits are |
1234 | * as belows: | 1312 | * as belows: |
1235 | * | 1313 | * |
1236 | * TIPC_LOW_IMPORTANCE (5MB) | 1314 | * TIPC_LOW_IMPORTANCE (4 MB) |
1237 | * TIPC_MEDIUM_IMPORTANCE (10MB) | 1315 | * TIPC_MEDIUM_IMPORTANCE (8 MB) |
1238 | * TIPC_HIGH_IMPORTANCE (20MB) | 1316 | * TIPC_HIGH_IMPORTANCE (16 MB) |
1239 | * TIPC_CRITICAL_IMPORTANCE (40MB) | 1317 | * TIPC_CRITICAL_IMPORTANCE (32 MB) |
1240 | * | 1318 | * |
1241 | * Returns overload limit according to corresponding message importance | 1319 | * Returns overload limit according to corresponding message importance |
1242 | */ | 1320 | */ |
@@ -1246,9 +1324,10 @@ static unsigned int rcvbuf_limit(struct sock *sk, struct sk_buff *buf) | |||
1246 | unsigned int limit; | 1324 | unsigned int limit; |
1247 | 1325 | ||
1248 | if (msg_connected(msg)) | 1326 | if (msg_connected(msg)) |
1249 | limit = CONN_OVERLOAD_LIMIT; | 1327 | limit = sysctl_tipc_rmem[2]; |
1250 | else | 1328 | else |
1251 | limit = sk->sk_rcvbuf << (msg_importance(msg) + 5); | 1329 | limit = sk->sk_rcvbuf >> TIPC_CRITICAL_IMPORTANCE << |
1330 | msg_importance(msg); | ||
1252 | return limit; | 1331 | return limit; |
1253 | } | 1332 | } |
1254 | 1333 | ||
@@ -1327,7 +1406,7 @@ static int backlog_rcv(struct sock *sk, struct sk_buff *buf) | |||
1327 | */ | 1406 | */ |
1328 | static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf) | 1407 | static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf) |
1329 | { | 1408 | { |
1330 | struct sock *sk = (struct sock *)tport->usr_handle; | 1409 | struct sock *sk = tport->sk; |
1331 | u32 res; | 1410 | u32 res; |
1332 | 1411 | ||
1333 | /* | 1412 | /* |
@@ -1358,7 +1437,7 @@ static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf) | |||
1358 | */ | 1437 | */ |
1359 | static void wakeupdispatch(struct tipc_port *tport) | 1438 | static void wakeupdispatch(struct tipc_port *tport) |
1360 | { | 1439 | { |
1361 | struct sock *sk = (struct sock *)tport->usr_handle; | 1440 | struct sock *sk = tport->sk; |
1362 | 1441 | ||
1363 | sk->sk_write_space(sk); | 1442 | sk->sk_write_space(sk); |
1364 | } | 1443 | } |
@@ -1531,7 +1610,7 @@ static int accept(struct socket *sock, struct socket *new_sock, int flags) | |||
1531 | 1610 | ||
1532 | buf = skb_peek(&sk->sk_receive_queue); | 1611 | buf = skb_peek(&sk->sk_receive_queue); |
1533 | 1612 | ||
1534 | res = tipc_create(sock_net(sock->sk), new_sock, 0, 0); | 1613 | res = tipc_sk_create(sock_net(sock->sk), new_sock, 0, 1); |
1535 | if (res) | 1614 | if (res) |
1536 | goto exit; | 1615 | goto exit; |
1537 | 1616 | ||
@@ -1657,8 +1736,8 @@ restart: | |||
1657 | * | 1736 | * |
1658 | * Returns 0 on success, errno otherwise | 1737 | * Returns 0 on success, errno otherwise |
1659 | */ | 1738 | */ |
1660 | static int setsockopt(struct socket *sock, | 1739 | static int setsockopt(struct socket *sock, int lvl, int opt, char __user *ov, |
1661 | int lvl, int opt, char __user *ov, unsigned int ol) | 1740 | unsigned int ol) |
1662 | { | 1741 | { |
1663 | struct sock *sk = sock->sk; | 1742 | struct sock *sk = sock->sk; |
1664 | struct tipc_port *tport = tipc_sk_port(sk); | 1743 | struct tipc_port *tport = tipc_sk_port(sk); |
@@ -1716,8 +1795,8 @@ static int setsockopt(struct socket *sock, | |||
1716 | * | 1795 | * |
1717 | * Returns 0 on success, errno otherwise | 1796 | * Returns 0 on success, errno otherwise |
1718 | */ | 1797 | */ |
1719 | static int getsockopt(struct socket *sock, | 1798 | static int getsockopt(struct socket *sock, int lvl, int opt, char __user *ov, |
1720 | int lvl, int opt, char __user *ov, int __user *ol) | 1799 | int __user *ol) |
1721 | { | 1800 | { |
1722 | struct sock *sk = sock->sk; | 1801 | struct sock *sk = sock->sk; |
1723 | struct tipc_port *tport = tipc_sk_port(sk); | 1802 | struct tipc_port *tport = tipc_sk_port(sk); |
@@ -1841,13 +1920,20 @@ static const struct proto_ops stream_ops = { | |||
1841 | static const struct net_proto_family tipc_family_ops = { | 1920 | static const struct net_proto_family tipc_family_ops = { |
1842 | .owner = THIS_MODULE, | 1921 | .owner = THIS_MODULE, |
1843 | .family = AF_TIPC, | 1922 | .family = AF_TIPC, |
1844 | .create = tipc_create | 1923 | .create = tipc_sk_create |
1845 | }; | 1924 | }; |
1846 | 1925 | ||
1847 | static struct proto tipc_proto = { | 1926 | static struct proto tipc_proto = { |
1848 | .name = "TIPC", | 1927 | .name = "TIPC", |
1849 | .owner = THIS_MODULE, | 1928 | .owner = THIS_MODULE, |
1850 | .obj_size = sizeof(struct tipc_sock) | 1929 | .obj_size = sizeof(struct tipc_sock), |
1930 | .sysctl_rmem = sysctl_tipc_rmem | ||
1931 | }; | ||
1932 | |||
1933 | static struct proto tipc_proto_kern = { | ||
1934 | .name = "TIPC", | ||
1935 | .obj_size = sizeof(struct tipc_sock), | ||
1936 | .sysctl_rmem = sysctl_tipc_rmem | ||
1851 | }; | 1937 | }; |
1852 | 1938 | ||
1853 | /** | 1939 | /** |