aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/server.c44
-rw-r--r--net/tipc/socket.c83
-rw-r--r--net/tipc/socket.h4
3 files changed, 39 insertions, 92 deletions
diff --git a/net/tipc/server.c b/net/tipc/server.c
index eadd4ed45905..a57c8407cbf3 100644
--- a/net/tipc/server.c
+++ b/net/tipc/server.c
@@ -37,11 +37,13 @@
37#include "core.h" 37#include "core.h"
38#include "socket.h" 38#include "socket.h"
39#include <net/sock.h> 39#include <net/sock.h>
40#include <linux/module.h>
40 41
41/* Number of messages to send before rescheduling */ 42/* Number of messages to send before rescheduling */
42#define MAX_SEND_MSG_COUNT 25 43#define MAX_SEND_MSG_COUNT 25
43#define MAX_RECV_MSG_COUNT 25 44#define MAX_RECV_MSG_COUNT 25
44#define CF_CONNECTED 1 45#define CF_CONNECTED 1
46#define CF_SERVER 2
45 47
46#define sock2con(x) ((struct tipc_conn *)(x)->sk_user_data) 48#define sock2con(x) ((struct tipc_conn *)(x)->sk_user_data)
47 49
@@ -88,9 +90,16 @@ static void tipc_clean_outqueues(struct tipc_conn *con);
88static void tipc_conn_kref_release(struct kref *kref) 90static void tipc_conn_kref_release(struct kref *kref)
89{ 91{
90 struct tipc_conn *con = container_of(kref, struct tipc_conn, kref); 92 struct tipc_conn *con = container_of(kref, struct tipc_conn, kref);
93 struct socket *sock = con->sock;
94 struct sock *sk;
91 95
92 if (con->sock) { 96 if (sock) {
93 tipc_sock_release_local(con->sock); 97 sk = sock->sk;
98 if (test_bit(CF_SERVER, &con->flags)) {
99 __module_get(sock->ops->owner);
100 __module_get(sk->sk_prot_creator->owner);
101 }
102 sk_release_kernel(sk);
94 con->sock = NULL; 103 con->sock = NULL;
95 } 104 }
96 105
@@ -281,7 +290,7 @@ static int tipc_accept_from_sock(struct tipc_conn *con)
281 struct tipc_conn *newcon; 290 struct tipc_conn *newcon;
282 int ret; 291 int ret;
283 292
284 ret = tipc_sock_accept_local(sock, &newsock, O_NONBLOCK); 293 ret = kernel_accept(sock, &newsock, O_NONBLOCK);
285 if (ret < 0) 294 if (ret < 0)
286 return ret; 295 return ret;
287 296
@@ -309,9 +318,12 @@ static struct socket *tipc_create_listen_sock(struct tipc_conn *con)
309 struct socket *sock = NULL; 318 struct socket *sock = NULL;
310 int ret; 319 int ret;
311 320
312 ret = tipc_sock_create_local(s->net, s->type, &sock); 321 ret = sock_create_kern(AF_TIPC, SOCK_SEQPACKET, 0, &sock);
313 if (ret < 0) 322 if (ret < 0)
314 return NULL; 323 return NULL;
324
325 sk_change_net(sock->sk, s->net);
326
315 ret = kernel_setsockopt(sock, SOL_TIPC, TIPC_IMPORTANCE, 327 ret = kernel_setsockopt(sock, SOL_TIPC, TIPC_IMPORTANCE,
316 (char *)&s->imp, sizeof(s->imp)); 328 (char *)&s->imp, sizeof(s->imp));
317 if (ret < 0) 329 if (ret < 0)
@@ -337,11 +349,31 @@ static struct socket *tipc_create_listen_sock(struct tipc_conn *con)
337 pr_err("Unknown socket type %d\n", s->type); 349 pr_err("Unknown socket type %d\n", s->type);
338 goto create_err; 350 goto create_err;
339 } 351 }
352
353 /* As server's listening socket owner and creator is the same module,
354 * we have to decrease TIPC module reference count to guarantee that
355 * it remains zero after the server socket is created, otherwise,
356 * executing "rmmod" command is unable to make TIPC module deleted
357 * after TIPC module is inserted successfully.
358 *
359 * However, the reference count is ever increased twice in
360 * sock_create_kern(): one is to increase the reference count of owner
361 * of TIPC socket's proto_ops struct; another is to increment the
362 * reference count of owner of TIPC proto struct. Therefore, we must
363 * decrement the module reference count twice to ensure that it keeps
364 * zero after server's listening socket is created. Of course, we
365 * must bump the module reference count twice as well before the socket
366 * is closed.
367 */
368 module_put(sock->ops->owner);
369 module_put(sock->sk->sk_prot_creator->owner);
370 set_bit(CF_SERVER, &con->flags);
371
340 return sock; 372 return sock;
341 373
342create_err: 374create_err:
343 sock_release(sock); 375 kernel_sock_shutdown(sock, SHUT_RDWR);
344 con->sock = NULL; 376 sk_release_kernel(sock->sk);
345 return NULL; 377 return NULL;
346} 378}
347 379
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 934947f038b6..813847d25a49 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -121,9 +121,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz);
121static const struct proto_ops packet_ops; 121static const struct proto_ops packet_ops;
122static const struct proto_ops stream_ops; 122static const struct proto_ops stream_ops;
123static const struct proto_ops msg_ops; 123static const struct proto_ops msg_ops;
124
125static struct proto tipc_proto; 124static struct proto tipc_proto;
126static struct proto tipc_proto_kern;
127 125
128static const struct nla_policy tipc_nl_sock_policy[TIPC_NLA_SOCK_MAX + 1] = { 126static const struct nla_policy tipc_nl_sock_policy[TIPC_NLA_SOCK_MAX + 1] = {
129 [TIPC_NLA_SOCK_UNSPEC] = { .type = NLA_UNSPEC }, 127 [TIPC_NLA_SOCK_UNSPEC] = { .type = NLA_UNSPEC },
@@ -341,11 +339,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
341 } 339 }
342 340
343 /* Allocate socket's protocol area */ 341 /* Allocate socket's protocol area */
344 if (!kern) 342 sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto);
345 sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto);
346 else
347 sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto_kern);
348
349 if (sk == NULL) 343 if (sk == NULL)
350 return -ENOMEM; 344 return -ENOMEM;
351 345
@@ -383,75 +377,6 @@ static int tipc_sk_create(struct net *net, struct socket *sock,
383 return 0; 377 return 0;
384} 378}
385 379
386/**
387 * tipc_sock_create_local - create TIPC socket from inside TIPC module
388 * @type: socket type - SOCK_RDM or SOCK_SEQPACKET
389 *
390 * We cannot use sock_creat_kern here because it bumps module user count.
391 * Since socket owner and creator is the same module we must make sure
392 * that module count remains zero for module local sockets, otherwise
393 * we cannot do rmmod.
394 *
395 * Returns 0 on success, errno otherwise
396 */
397int tipc_sock_create_local(struct net *net, int type, struct socket **res)
398{
399 int rc;
400
401 rc = sock_create_lite(AF_TIPC, type, 0, res);
402 if (rc < 0) {
403 pr_err("Failed to create kernel socket\n");
404 return rc;
405 }
406 tipc_sk_create(net, *res, 0, 1);
407
408 return 0;
409}
410
411/**
412 * tipc_sock_release_local - release socket created by tipc_sock_create_local
413 * @sock: the socket to be released.
414 *
415 * Module reference count is not incremented when such sockets are created,
416 * so we must keep it from being decremented when they are released.
417 */
418void tipc_sock_release_local(struct socket *sock)
419{
420 tipc_release(sock);
421 sock->ops = NULL;
422 sock_release(sock);
423}
424
425/**
426 * tipc_sock_accept_local - accept a connection on a socket created
427 * with tipc_sock_create_local. Use this function to avoid that
428 * module reference count is inadvertently incremented.
429 *
430 * @sock: the accepting socket
431 * @newsock: reference to the new socket to be created
432 * @flags: socket flags
433 */
434
435int tipc_sock_accept_local(struct socket *sock, struct socket **newsock,
436 int flags)
437{
438 struct sock *sk = sock->sk;
439 int ret;
440
441 ret = sock_create_lite(sk->sk_family, sk->sk_type,
442 sk->sk_protocol, newsock);
443 if (ret < 0)
444 return ret;
445
446 ret = tipc_accept(sock, *newsock, flags);
447 if (ret < 0) {
448 sock_release(*newsock);
449 return ret;
450 }
451 (*newsock)->ops = sock->ops;
452 return ret;
453}
454
455static void tipc_sk_callback(struct rcu_head *head) 380static void tipc_sk_callback(struct rcu_head *head)
456{ 381{
457 struct tipc_sock *tsk = container_of(head, struct tipc_sock, rcu); 382 struct tipc_sock *tsk = container_of(head, struct tipc_sock, rcu);
@@ -2608,12 +2533,6 @@ static struct proto tipc_proto = {
2608 .sysctl_rmem = sysctl_tipc_rmem 2533 .sysctl_rmem = sysctl_tipc_rmem
2609}; 2534};
2610 2535
2611static struct proto tipc_proto_kern = {
2612 .name = "TIPC",
2613 .obj_size = sizeof(struct tipc_sock),
2614 .sysctl_rmem = sysctl_tipc_rmem
2615};
2616
2617/** 2536/**
2618 * tipc_socket_init - initialize TIPC socket interface 2537 * tipc_socket_init - initialize TIPC socket interface
2619 * 2538 *
diff --git a/net/tipc/socket.h b/net/tipc/socket.h
index 238f1b7bd9bd..bf6551389522 100644
--- a/net/tipc/socket.h
+++ b/net/tipc/socket.h
@@ -44,10 +44,6 @@
44 SKB_TRUESIZE(TIPC_MAX_USER_MSG_SIZE)) 44 SKB_TRUESIZE(TIPC_MAX_USER_MSG_SIZE))
45int tipc_socket_init(void); 45int tipc_socket_init(void);
46void tipc_socket_stop(void); 46void tipc_socket_stop(void);
47int tipc_sock_create_local(struct net *net, int type, struct socket **res);
48void tipc_sock_release_local(struct socket *sock);
49int tipc_sock_accept_local(struct socket *sock, struct socket **newsock,
50 int flags);
51int tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq); 47int tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq);
52void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq, 48void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq,
53 struct sk_buff_head *inputq); 49 struct sk_buff_head *inputq);