diff options
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 274 |
1 files changed, 102 insertions, 172 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index f73e975af80b..ee90d74d7516 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -35,7 +35,6 @@ | |||
35 | */ | 35 | */ |
36 | 36 | ||
37 | #include <linux/rhashtable.h> | 37 | #include <linux/rhashtable.h> |
38 | #include <linux/jhash.h> | ||
39 | #include "core.h" | 38 | #include "core.h" |
40 | #include "name_table.h" | 39 | #include "name_table.h" |
41 | #include "node.h" | 40 | #include "node.h" |
@@ -74,6 +73,7 @@ | |||
74 | * @link_cong: non-zero if owner must sleep because of link congestion | 73 | * @link_cong: non-zero if owner must sleep because of link congestion |
75 | * @sent_unacked: # messages sent by socket, and not yet acked by peer | 74 | * @sent_unacked: # messages sent by socket, and not yet acked by peer |
76 | * @rcv_unacked: # messages read by user, but not yet acked back to peer | 75 | * @rcv_unacked: # messages read by user, but not yet acked back to peer |
76 | * @remote: 'connected' peer for dgram/rdm | ||
77 | * @node: hash table node | 77 | * @node: hash table node |
78 | * @rcu: rcu struct for tipc_sock | 78 | * @rcu: rcu struct for tipc_sock |
79 | */ | 79 | */ |
@@ -96,6 +96,7 @@ struct tipc_sock { | |||
96 | bool link_cong; | 96 | bool link_cong; |
97 | uint sent_unacked; | 97 | uint sent_unacked; |
98 | uint rcv_unacked; | 98 | uint rcv_unacked; |
99 | struct sockaddr_tipc remote; | ||
99 | struct rhash_head node; | 100 | struct rhash_head node; |
100 | struct rcu_head rcu; | 101 | struct rcu_head rcu; |
101 | }; | 102 | }; |
@@ -114,13 +115,14 @@ static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope, | |||
114 | static struct tipc_sock *tipc_sk_lookup(struct net *net, u32 portid); | 115 | static struct tipc_sock *tipc_sk_lookup(struct net *net, u32 portid); |
115 | static int tipc_sk_insert(struct tipc_sock *tsk); | 116 | static int tipc_sk_insert(struct tipc_sock *tsk); |
116 | static void tipc_sk_remove(struct tipc_sock *tsk); | 117 | static void tipc_sk_remove(struct tipc_sock *tsk); |
118 | static int __tipc_send_stream(struct socket *sock, struct msghdr *m, | ||
119 | size_t dsz); | ||
120 | static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz); | ||
117 | 121 | ||
118 | static const struct proto_ops packet_ops; | 122 | static const struct proto_ops packet_ops; |
119 | static const struct proto_ops stream_ops; | 123 | static const struct proto_ops stream_ops; |
120 | static const struct proto_ops msg_ops; | 124 | static const struct proto_ops msg_ops; |
121 | |||
122 | static struct proto tipc_proto; | 125 | static struct proto tipc_proto; |
123 | static struct proto tipc_proto_kern; | ||
124 | 126 | ||
125 | static const struct nla_policy tipc_nl_sock_policy[TIPC_NLA_SOCK_MAX + 1] = { | 127 | static const struct nla_policy tipc_nl_sock_policy[TIPC_NLA_SOCK_MAX + 1] = { |
126 | [TIPC_NLA_SOCK_UNSPEC] = { .type = NLA_UNSPEC }, | 128 | [TIPC_NLA_SOCK_UNSPEC] = { .type = NLA_UNSPEC }, |
@@ -130,6 +132,8 @@ static const struct nla_policy tipc_nl_sock_policy[TIPC_NLA_SOCK_MAX + 1] = { | |||
130 | [TIPC_NLA_SOCK_HAS_PUBL] = { .type = NLA_FLAG } | 132 | [TIPC_NLA_SOCK_HAS_PUBL] = { .type = NLA_FLAG } |
131 | }; | 133 | }; |
132 | 134 | ||
135 | static const struct rhashtable_params tsk_rht_params; | ||
136 | |||
133 | /* | 137 | /* |
134 | * Revised TIPC socket locking policy: | 138 | * Revised TIPC socket locking policy: |
135 | * | 139 | * |
@@ -338,11 +342,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock, | |||
338 | } | 342 | } |
339 | 343 | ||
340 | /* Allocate socket's protocol area */ | 344 | /* Allocate socket's protocol area */ |
341 | if (!kern) | 345 | sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto); |
342 | sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto); | ||
343 | else | ||
344 | sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto_kern); | ||
345 | |||
346 | if (sk == NULL) | 346 | if (sk == NULL) |
347 | return -ENOMEM; | 347 | return -ENOMEM; |
348 | 348 | ||
@@ -380,75 +380,6 @@ static int tipc_sk_create(struct net *net, struct socket *sock, | |||
380 | return 0; | 380 | return 0; |
381 | } | 381 | } |
382 | 382 | ||
383 | /** | ||
384 | * tipc_sock_create_local - create TIPC socket from inside TIPC module | ||
385 | * @type: socket type - SOCK_RDM or SOCK_SEQPACKET | ||
386 | * | ||
387 | * We cannot use sock_creat_kern here because it bumps module user count. | ||
388 | * Since socket owner and creator is the same module we must make sure | ||
389 | * that module count remains zero for module local sockets, otherwise | ||
390 | * we cannot do rmmod. | ||
391 | * | ||
392 | * Returns 0 on success, errno otherwise | ||
393 | */ | ||
394 | int tipc_sock_create_local(struct net *net, int type, struct socket **res) | ||
395 | { | ||
396 | int rc; | ||
397 | |||
398 | rc = sock_create_lite(AF_TIPC, type, 0, res); | ||
399 | if (rc < 0) { | ||
400 | pr_err("Failed to create kernel socket\n"); | ||
401 | return rc; | ||
402 | } | ||
403 | tipc_sk_create(net, *res, 0, 1); | ||
404 | |||
405 | return 0; | ||
406 | } | ||
407 | |||
408 | /** | ||
409 | * tipc_sock_release_local - release socket created by tipc_sock_create_local | ||
410 | * @sock: the socket to be released. | ||
411 | * | ||
412 | * Module reference count is not incremented when such sockets are created, | ||
413 | * so we must keep it from being decremented when they are released. | ||
414 | */ | ||
415 | void tipc_sock_release_local(struct socket *sock) | ||
416 | { | ||
417 | tipc_release(sock); | ||
418 | sock->ops = NULL; | ||
419 | sock_release(sock); | ||
420 | } | ||
421 | |||
422 | /** | ||
423 | * tipc_sock_accept_local - accept a connection on a socket created | ||
424 | * with tipc_sock_create_local. Use this function to avoid that | ||
425 | * module reference count is inadvertently incremented. | ||
426 | * | ||
427 | * @sock: the accepting socket | ||
428 | * @newsock: reference to the new socket to be created | ||
429 | * @flags: socket flags | ||
430 | */ | ||
431 | |||
432 | int tipc_sock_accept_local(struct socket *sock, struct socket **newsock, | ||
433 | int flags) | ||
434 | { | ||
435 | struct sock *sk = sock->sk; | ||
436 | int ret; | ||
437 | |||
438 | ret = sock_create_lite(sk->sk_family, sk->sk_type, | ||
439 | sk->sk_protocol, newsock); | ||
440 | if (ret < 0) | ||
441 | return ret; | ||
442 | |||
443 | ret = tipc_accept(sock, *newsock, flags); | ||
444 | if (ret < 0) { | ||
445 | sock_release(*newsock); | ||
446 | return ret; | ||
447 | } | ||
448 | (*newsock)->ops = sock->ops; | ||
449 | return ret; | ||
450 | } | ||
451 | |||
452 | static void tipc_sk_callback(struct rcu_head *head) | 383 | static void tipc_sk_callback(struct rcu_head *head) |
453 | { | 384 | { |
454 | struct tipc_sock *tsk = container_of(head, struct tipc_sock, rcu); | 385 | struct tipc_sock *tsk = container_of(head, struct tipc_sock, rcu); |
@@ -892,7 +823,6 @@ static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p) | |||
892 | 823 | ||
893 | /** | 824 | /** |
894 | * tipc_sendmsg - send message in connectionless manner | 825 | * tipc_sendmsg - send message in connectionless manner |
895 | * @iocb: if NULL, indicates that socket lock is already held | ||
896 | * @sock: socket structure | 826 | * @sock: socket structure |
897 | * @m: message to send | 827 | * @m: message to send |
898 | * @dsz: amount of user data to be sent | 828 | * @dsz: amount of user data to be sent |
@@ -904,9 +834,21 @@ static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p) | |||
904 | * | 834 | * |
905 | * Returns the number of bytes sent on success, or errno otherwise | 835 | * Returns the number of bytes sent on success, or errno otherwise |
906 | */ | 836 | */ |
907 | static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, | 837 | static int tipc_sendmsg(struct socket *sock, |
908 | struct msghdr *m, size_t dsz) | 838 | struct msghdr *m, size_t dsz) |
909 | { | 839 | { |
840 | struct sock *sk = sock->sk; | ||
841 | int ret; | ||
842 | |||
843 | lock_sock(sk); | ||
844 | ret = __tipc_sendmsg(sock, m, dsz); | ||
845 | release_sock(sk); | ||
846 | |||
847 | return ret; | ||
848 | } | ||
849 | |||
850 | static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz) | ||
851 | { | ||
910 | DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name); | 852 | DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name); |
911 | struct sock *sk = sock->sk; | 853 | struct sock *sk = sock->sk; |
912 | struct tipc_sock *tsk = tipc_sk(sk); | 854 | struct tipc_sock *tsk = tipc_sk(sk); |
@@ -915,49 +857,40 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
915 | u32 dnode, dport; | 857 | u32 dnode, dport; |
916 | struct sk_buff_head *pktchain = &sk->sk_write_queue; | 858 | struct sk_buff_head *pktchain = &sk->sk_write_queue; |
917 | struct sk_buff *skb; | 859 | struct sk_buff *skb; |
918 | struct tipc_name_seq *seq = &dest->addr.nameseq; | 860 | struct tipc_name_seq *seq; |
919 | struct iov_iter save; | 861 | struct iov_iter save; |
920 | u32 mtu; | 862 | u32 mtu; |
921 | long timeo; | 863 | long timeo; |
922 | int rc; | 864 | int rc; |
923 | 865 | ||
924 | if (unlikely(!dest)) | ||
925 | return -EDESTADDRREQ; | ||
926 | |||
927 | if (unlikely((m->msg_namelen < sizeof(*dest)) || | ||
928 | (dest->family != AF_TIPC))) | ||
929 | return -EINVAL; | ||
930 | |||
931 | if (dsz > TIPC_MAX_USER_MSG_SIZE) | 866 | if (dsz > TIPC_MAX_USER_MSG_SIZE) |
932 | return -EMSGSIZE; | 867 | return -EMSGSIZE; |
933 | 868 | if (unlikely(!dest)) { | |
934 | if (iocb) | 869 | if (tsk->connected && sock->state == SS_READY) |
935 | lock_sock(sk); | 870 | dest = &tsk->remote; |
936 | 871 | else | |
872 | return -EDESTADDRREQ; | ||
873 | } else if (unlikely(m->msg_namelen < sizeof(*dest)) || | ||
874 | dest->family != AF_TIPC) { | ||
875 | return -EINVAL; | ||
876 | } | ||
937 | if (unlikely(sock->state != SS_READY)) { | 877 | if (unlikely(sock->state != SS_READY)) { |
938 | if (sock->state == SS_LISTENING) { | 878 | if (sock->state == SS_LISTENING) |
939 | rc = -EPIPE; | 879 | return -EPIPE; |
940 | goto exit; | 880 | if (sock->state != SS_UNCONNECTED) |
941 | } | 881 | return -EISCONN; |
942 | if (sock->state != SS_UNCONNECTED) { | 882 | if (tsk->published) |
943 | rc = -EISCONN; | 883 | return -EOPNOTSUPP; |
944 | goto exit; | ||
945 | } | ||
946 | if (tsk->published) { | ||
947 | rc = -EOPNOTSUPP; | ||
948 | goto exit; | ||
949 | } | ||
950 | if (dest->addrtype == TIPC_ADDR_NAME) { | 884 | if (dest->addrtype == TIPC_ADDR_NAME) { |
951 | tsk->conn_type = dest->addr.name.name.type; | 885 | tsk->conn_type = dest->addr.name.name.type; |
952 | tsk->conn_instance = dest->addr.name.name.instance; | 886 | tsk->conn_instance = dest->addr.name.name.instance; |
953 | } | 887 | } |
954 | } | 888 | } |
955 | 889 | seq = &dest->addr.nameseq; | |
956 | timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); | 890 | timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); |
957 | 891 | ||
958 | if (dest->addrtype == TIPC_ADDR_MCAST) { | 892 | if (dest->addrtype == TIPC_ADDR_MCAST) { |
959 | rc = tipc_sendmcast(sock, seq, m, dsz, timeo); | 893 | return tipc_sendmcast(sock, seq, m, dsz, timeo); |
960 | goto exit; | ||
961 | } else if (dest->addrtype == TIPC_ADDR_NAME) { | 894 | } else if (dest->addrtype == TIPC_ADDR_NAME) { |
962 | u32 type = dest->addr.name.name.type; | 895 | u32 type = dest->addr.name.name.type; |
963 | u32 inst = dest->addr.name.name.instance; | 896 | u32 inst = dest->addr.name.name.instance; |
@@ -972,10 +905,8 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
972 | dport = tipc_nametbl_translate(net, type, inst, &dnode); | 905 | dport = tipc_nametbl_translate(net, type, inst, &dnode); |
973 | msg_set_destnode(mhdr, dnode); | 906 | msg_set_destnode(mhdr, dnode); |
974 | msg_set_destport(mhdr, dport); | 907 | msg_set_destport(mhdr, dport); |
975 | if (unlikely(!dport && !dnode)) { | 908 | if (unlikely(!dport && !dnode)) |
976 | rc = -EHOSTUNREACH; | 909 | return -EHOSTUNREACH; |
977 | goto exit; | ||
978 | } | ||
979 | } else if (dest->addrtype == TIPC_ADDR_ID) { | 910 | } else if (dest->addrtype == TIPC_ADDR_ID) { |
980 | dnode = dest->addr.id.node; | 911 | dnode = dest->addr.id.node; |
981 | msg_set_type(mhdr, TIPC_DIRECT_MSG); | 912 | msg_set_type(mhdr, TIPC_DIRECT_MSG); |
@@ -990,7 +921,7 @@ new_mtu: | |||
990 | mtu = tipc_node_get_mtu(net, dnode, tsk->portid); | 921 | mtu = tipc_node_get_mtu(net, dnode, tsk->portid); |
991 | rc = tipc_msg_build(mhdr, m, 0, dsz, mtu, pktchain); | 922 | rc = tipc_msg_build(mhdr, m, 0, dsz, mtu, pktchain); |
992 | if (rc < 0) | 923 | if (rc < 0) |
993 | goto exit; | 924 | return rc; |
994 | 925 | ||
995 | do { | 926 | do { |
996 | skb = skb_peek(pktchain); | 927 | skb = skb_peek(pktchain); |
@@ -1013,9 +944,6 @@ new_mtu: | |||
1013 | if (rc) | 944 | if (rc) |
1014 | __skb_queue_purge(pktchain); | 945 | __skb_queue_purge(pktchain); |
1015 | } while (!rc); | 946 | } while (!rc); |
1016 | exit: | ||
1017 | if (iocb) | ||
1018 | release_sock(sk); | ||
1019 | 947 | ||
1020 | return rc; | 948 | return rc; |
1021 | } | 949 | } |
@@ -1052,7 +980,6 @@ static int tipc_wait_for_sndpkt(struct socket *sock, long *timeo_p) | |||
1052 | 980 | ||
1053 | /** | 981 | /** |
1054 | * tipc_send_stream - send stream-oriented data | 982 | * tipc_send_stream - send stream-oriented data |
1055 | * @iocb: (unused) | ||
1056 | * @sock: socket structure | 983 | * @sock: socket structure |
1057 | * @m: data to send | 984 | * @m: data to send |
1058 | * @dsz: total length of data to be transmitted | 985 | * @dsz: total length of data to be transmitted |
@@ -1062,8 +989,19 @@ static int tipc_wait_for_sndpkt(struct socket *sock, long *timeo_p) | |||
1062 | * Returns the number of bytes sent on success (or partial success), | 989 | * Returns the number of bytes sent on success (or partial success), |
1063 | * or errno if no data sent | 990 | * or errno if no data sent |
1064 | */ | 991 | */ |
1065 | static int tipc_send_stream(struct kiocb *iocb, struct socket *sock, | 992 | static int tipc_send_stream(struct socket *sock, struct msghdr *m, size_t dsz) |
1066 | struct msghdr *m, size_t dsz) | 993 | { |
994 | struct sock *sk = sock->sk; | ||
995 | int ret; | ||
996 | |||
997 | lock_sock(sk); | ||
998 | ret = __tipc_send_stream(sock, m, dsz); | ||
999 | release_sock(sk); | ||
1000 | |||
1001 | return ret; | ||
1002 | } | ||
1003 | |||
1004 | static int __tipc_send_stream(struct socket *sock, struct msghdr *m, size_t dsz) | ||
1067 | { | 1005 | { |
1068 | struct sock *sk = sock->sk; | 1006 | struct sock *sk = sock->sk; |
1069 | struct net *net = sock_net(sk); | 1007 | struct net *net = sock_net(sk); |
@@ -1080,7 +1018,7 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock, | |||
1080 | 1018 | ||
1081 | /* Handle implied connection establishment */ | 1019 | /* Handle implied connection establishment */ |
1082 | if (unlikely(dest)) { | 1020 | if (unlikely(dest)) { |
1083 | rc = tipc_sendmsg(iocb, sock, m, dsz); | 1021 | rc = __tipc_sendmsg(sock, m, dsz); |
1084 | if (dsz && (dsz == rc)) | 1022 | if (dsz && (dsz == rc)) |
1085 | tsk->sent_unacked = 1; | 1023 | tsk->sent_unacked = 1; |
1086 | return rc; | 1024 | return rc; |
@@ -1088,15 +1026,11 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock, | |||
1088 | if (dsz > (uint)INT_MAX) | 1026 | if (dsz > (uint)INT_MAX) |
1089 | return -EMSGSIZE; | 1027 | return -EMSGSIZE; |
1090 | 1028 | ||
1091 | if (iocb) | ||
1092 | lock_sock(sk); | ||
1093 | |||
1094 | if (unlikely(sock->state != SS_CONNECTED)) { | 1029 | if (unlikely(sock->state != SS_CONNECTED)) { |
1095 | if (sock->state == SS_DISCONNECTING) | 1030 | if (sock->state == SS_DISCONNECTING) |
1096 | rc = -EPIPE; | 1031 | return -EPIPE; |
1097 | else | 1032 | else |
1098 | rc = -ENOTCONN; | 1033 | return -ENOTCONN; |
1099 | goto exit; | ||
1100 | } | 1034 | } |
1101 | 1035 | ||
1102 | timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); | 1036 | timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT); |
@@ -1108,7 +1042,7 @@ next: | |||
1108 | send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE); | 1042 | send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE); |
1109 | rc = tipc_msg_build(mhdr, m, sent, send, mtu, pktchain); | 1043 | rc = tipc_msg_build(mhdr, m, sent, send, mtu, pktchain); |
1110 | if (unlikely(rc < 0)) | 1044 | if (unlikely(rc < 0)) |
1111 | goto exit; | 1045 | return rc; |
1112 | do { | 1046 | do { |
1113 | if (likely(!tsk_conn_cong(tsk))) { | 1047 | if (likely(!tsk_conn_cong(tsk))) { |
1114 | rc = tipc_link_xmit(net, pktchain, dnode, portid); | 1048 | rc = tipc_link_xmit(net, pktchain, dnode, portid); |
@@ -1133,15 +1067,12 @@ next: | |||
1133 | if (rc) | 1067 | if (rc) |
1134 | __skb_queue_purge(pktchain); | 1068 | __skb_queue_purge(pktchain); |
1135 | } while (!rc); | 1069 | } while (!rc); |
1136 | exit: | 1070 | |
1137 | if (iocb) | ||
1138 | release_sock(sk); | ||
1139 | return sent ? sent : rc; | 1071 | return sent ? sent : rc; |
1140 | } | 1072 | } |
1141 | 1073 | ||
1142 | /** | 1074 | /** |
1143 | * tipc_send_packet - send a connection-oriented message | 1075 | * tipc_send_packet - send a connection-oriented message |
1144 | * @iocb: if NULL, indicates that socket lock is already held | ||
1145 | * @sock: socket structure | 1076 | * @sock: socket structure |
1146 | * @m: message to send | 1077 | * @m: message to send |
1147 | * @dsz: length of data to be transmitted | 1078 | * @dsz: length of data to be transmitted |
@@ -1150,13 +1081,12 @@ exit: | |||
1150 | * | 1081 | * |
1151 | * Returns the number of bytes sent on success, or errno otherwise | 1082 | * Returns the number of bytes sent on success, or errno otherwise |
1152 | */ | 1083 | */ |
1153 | static int tipc_send_packet(struct kiocb *iocb, struct socket *sock, | 1084 | static int tipc_send_packet(struct socket *sock, struct msghdr *m, size_t dsz) |
1154 | struct msghdr *m, size_t dsz) | ||
1155 | { | 1085 | { |
1156 | if (dsz > TIPC_MAX_USER_MSG_SIZE) | 1086 | if (dsz > TIPC_MAX_USER_MSG_SIZE) |
1157 | return -EMSGSIZE; | 1087 | return -EMSGSIZE; |
1158 | 1088 | ||
1159 | return tipc_send_stream(iocb, sock, m, dsz); | 1089 | return tipc_send_stream(sock, m, dsz); |
1160 | } | 1090 | } |
1161 | 1091 | ||
1162 | /* tipc_sk_finish_conn - complete the setup of a connection | 1092 | /* tipc_sk_finish_conn - complete the setup of a connection |
@@ -1317,12 +1247,12 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) | |||
1317 | err = 0; | 1247 | err = 0; |
1318 | if (!skb_queue_empty(&sk->sk_receive_queue)) | 1248 | if (!skb_queue_empty(&sk->sk_receive_queue)) |
1319 | break; | 1249 | break; |
1320 | err = sock_intr_errno(timeo); | ||
1321 | if (signal_pending(current)) | ||
1322 | break; | ||
1323 | err = -EAGAIN; | 1250 | err = -EAGAIN; |
1324 | if (!timeo) | 1251 | if (!timeo) |
1325 | break; | 1252 | break; |
1253 | err = sock_intr_errno(timeo); | ||
1254 | if (signal_pending(current)) | ||
1255 | break; | ||
1326 | } | 1256 | } |
1327 | finish_wait(sk_sleep(sk), &wait); | 1257 | finish_wait(sk_sleep(sk), &wait); |
1328 | *timeop = timeo; | 1258 | *timeop = timeo; |
@@ -1331,7 +1261,6 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) | |||
1331 | 1261 | ||
1332 | /** | 1262 | /** |
1333 | * tipc_recvmsg - receive packet-oriented message | 1263 | * tipc_recvmsg - receive packet-oriented message |
1334 | * @iocb: (unused) | ||
1335 | * @m: descriptor for message info | 1264 | * @m: descriptor for message info |
1336 | * @buf_len: total size of user buffer area | 1265 | * @buf_len: total size of user buffer area |
1337 | * @flags: receive flags | 1266 | * @flags: receive flags |
@@ -1341,8 +1270,8 @@ static int tipc_wait_for_rcvmsg(struct socket *sock, long *timeop) | |||
1341 | * | 1270 | * |
1342 | * Returns size of returned message data, errno otherwise | 1271 | * Returns size of returned message data, errno otherwise |
1343 | */ | 1272 | */ |
1344 | static int tipc_recvmsg(struct kiocb *iocb, struct socket *sock, | 1273 | static int tipc_recvmsg(struct socket *sock, struct msghdr *m, size_t buf_len, |
1345 | struct msghdr *m, size_t buf_len, int flags) | 1274 | int flags) |
1346 | { | 1275 | { |
1347 | struct sock *sk = sock->sk; | 1276 | struct sock *sk = sock->sk; |
1348 | struct tipc_sock *tsk = tipc_sk(sk); | 1277 | struct tipc_sock *tsk = tipc_sk(sk); |
@@ -1426,7 +1355,6 @@ exit: | |||
1426 | 1355 | ||
1427 | /** | 1356 | /** |
1428 | * tipc_recv_stream - receive stream-oriented data | 1357 | * tipc_recv_stream - receive stream-oriented data |
1429 | * @iocb: (unused) | ||
1430 | * @m: descriptor for message info | 1358 | * @m: descriptor for message info |
1431 | * @buf_len: total size of user buffer area | 1359 | * @buf_len: total size of user buffer area |
1432 | * @flags: receive flags | 1360 | * @flags: receive flags |
@@ -1436,8 +1364,8 @@ exit: | |||
1436 | * | 1364 | * |
1437 | * Returns size of returned message data, errno otherwise | 1365 | * Returns size of returned message data, errno otherwise |
1438 | */ | 1366 | */ |
1439 | static int tipc_recv_stream(struct kiocb *iocb, struct socket *sock, | 1367 | static int tipc_recv_stream(struct socket *sock, struct msghdr *m, |
1440 | struct msghdr *m, size_t buf_len, int flags) | 1368 | size_t buf_len, int flags) |
1441 | { | 1369 | { |
1442 | struct sock *sk = sock->sk; | 1370 | struct sock *sk = sock->sk; |
1443 | struct tipc_sock *tsk = tipc_sk(sk); | 1371 | struct tipc_sock *tsk = tipc_sk(sk); |
@@ -1909,17 +1837,26 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest, | |||
1909 | int destlen, int flags) | 1837 | int destlen, int flags) |
1910 | { | 1838 | { |
1911 | struct sock *sk = sock->sk; | 1839 | struct sock *sk = sock->sk; |
1840 | struct tipc_sock *tsk = tipc_sk(sk); | ||
1912 | struct sockaddr_tipc *dst = (struct sockaddr_tipc *)dest; | 1841 | struct sockaddr_tipc *dst = (struct sockaddr_tipc *)dest; |
1913 | struct msghdr m = {NULL,}; | 1842 | struct msghdr m = {NULL,}; |
1914 | long timeout = (flags & O_NONBLOCK) ? 0 : tipc_sk(sk)->conn_timeout; | 1843 | long timeout = (flags & O_NONBLOCK) ? 0 : tsk->conn_timeout; |
1915 | socket_state previous; | 1844 | socket_state previous; |
1916 | int res; | 1845 | int res = 0; |
1917 | 1846 | ||
1918 | lock_sock(sk); | 1847 | lock_sock(sk); |
1919 | 1848 | ||
1920 | /* For now, TIPC does not allow use of connect() with DGRAM/RDM types */ | 1849 | /* DGRAM/RDM connect(), just save the destaddr */ |
1921 | if (sock->state == SS_READY) { | 1850 | if (sock->state == SS_READY) { |
1922 | res = -EOPNOTSUPP; | 1851 | if (dst->family == AF_UNSPEC) { |
1852 | memset(&tsk->remote, 0, sizeof(struct sockaddr_tipc)); | ||
1853 | tsk->connected = 0; | ||
1854 | } else if (destlen != sizeof(struct sockaddr_tipc)) { | ||
1855 | res = -EINVAL; | ||
1856 | } else { | ||
1857 | memcpy(&tsk->remote, dest, destlen); | ||
1858 | tsk->connected = 1; | ||
1859 | } | ||
1923 | goto exit; | 1860 | goto exit; |
1924 | } | 1861 | } |
1925 | 1862 | ||
@@ -1947,7 +1884,7 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest, | |||
1947 | if (!timeout) | 1884 | if (!timeout) |
1948 | m.msg_flags = MSG_DONTWAIT; | 1885 | m.msg_flags = MSG_DONTWAIT; |
1949 | 1886 | ||
1950 | res = tipc_sendmsg(NULL, sock, &m, 0); | 1887 | res = __tipc_sendmsg(sock, &m, 0); |
1951 | if ((res < 0) && (res != -EWOULDBLOCK)) | 1888 | if ((res < 0) && (res != -EWOULDBLOCK)) |
1952 | goto exit; | 1889 | goto exit; |
1953 | 1890 | ||
@@ -2027,12 +1964,12 @@ static int tipc_wait_for_accept(struct socket *sock, long timeo) | |||
2027 | err = -EINVAL; | 1964 | err = -EINVAL; |
2028 | if (sock->state != SS_LISTENING) | 1965 | if (sock->state != SS_LISTENING) |
2029 | break; | 1966 | break; |
2030 | err = sock_intr_errno(timeo); | ||
2031 | if (signal_pending(current)) | ||
2032 | break; | ||
2033 | err = -EAGAIN; | 1967 | err = -EAGAIN; |
2034 | if (!timeo) | 1968 | if (!timeo) |
2035 | break; | 1969 | break; |
1970 | err = sock_intr_errno(timeo); | ||
1971 | if (signal_pending(current)) | ||
1972 | break; | ||
2036 | } | 1973 | } |
2037 | finish_wait(sk_sleep(sk), &wait); | 1974 | finish_wait(sk_sleep(sk), &wait); |
2038 | return err; | 1975 | return err; |
@@ -2103,7 +2040,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags) | |||
2103 | struct msghdr m = {NULL,}; | 2040 | struct msghdr m = {NULL,}; |
2104 | 2041 | ||
2105 | tsk_advance_rx_queue(sk); | 2042 | tsk_advance_rx_queue(sk); |
2106 | tipc_send_packet(NULL, new_sock, &m, 0); | 2043 | __tipc_send_stream(new_sock, &m, 0); |
2107 | } else { | 2044 | } else { |
2108 | __skb_dequeue(&sk->sk_receive_queue); | 2045 | __skb_dequeue(&sk->sk_receive_queue); |
2109 | __skb_queue_head(&new_sk->sk_receive_queue, buf); | 2046 | __skb_queue_head(&new_sk->sk_receive_queue, buf); |
@@ -2154,7 +2091,6 @@ restart: | |||
2154 | TIPC_CONN_SHUTDOWN)) | 2091 | TIPC_CONN_SHUTDOWN)) |
2155 | tipc_link_xmit_skb(net, skb, dnode, | 2092 | tipc_link_xmit_skb(net, skb, dnode, |
2156 | tsk->portid); | 2093 | tsk->portid); |
2157 | tipc_node_remove_conn(net, dnode, tsk->portid); | ||
2158 | } else { | 2094 | } else { |
2159 | dnode = tsk_peer_node(tsk); | 2095 | dnode = tsk_peer_node(tsk); |
2160 | 2096 | ||
@@ -2312,7 +2248,7 @@ static struct tipc_sock *tipc_sk_lookup(struct net *net, u32 portid) | |||
2312 | struct tipc_sock *tsk; | 2248 | struct tipc_sock *tsk; |
2313 | 2249 | ||
2314 | rcu_read_lock(); | 2250 | rcu_read_lock(); |
2315 | tsk = rhashtable_lookup(&tn->sk_rht, &portid); | 2251 | tsk = rhashtable_lookup_fast(&tn->sk_rht, &portid, tsk_rht_params); |
2316 | if (tsk) | 2252 | if (tsk) |
2317 | sock_hold(&tsk->sk); | 2253 | sock_hold(&tsk->sk); |
2318 | rcu_read_unlock(); | 2254 | rcu_read_unlock(); |
@@ -2334,7 +2270,8 @@ static int tipc_sk_insert(struct tipc_sock *tsk) | |||
2334 | portid = TIPC_MIN_PORT; | 2270 | portid = TIPC_MIN_PORT; |
2335 | tsk->portid = portid; | 2271 | tsk->portid = portid; |
2336 | sock_hold(&tsk->sk); | 2272 | sock_hold(&tsk->sk); |
2337 | if (rhashtable_lookup_insert(&tn->sk_rht, &tsk->node)) | 2273 | if (!rhashtable_lookup_insert_fast(&tn->sk_rht, &tsk->node, |
2274 | tsk_rht_params)) | ||
2338 | return 0; | 2275 | return 0; |
2339 | sock_put(&tsk->sk); | 2276 | sock_put(&tsk->sk); |
2340 | } | 2277 | } |
@@ -2347,28 +2284,27 @@ static void tipc_sk_remove(struct tipc_sock *tsk) | |||
2347 | struct sock *sk = &tsk->sk; | 2284 | struct sock *sk = &tsk->sk; |
2348 | struct tipc_net *tn = net_generic(sock_net(sk), tipc_net_id); | 2285 | struct tipc_net *tn = net_generic(sock_net(sk), tipc_net_id); |
2349 | 2286 | ||
2350 | if (rhashtable_remove(&tn->sk_rht, &tsk->node)) { | 2287 | if (!rhashtable_remove_fast(&tn->sk_rht, &tsk->node, tsk_rht_params)) { |
2351 | WARN_ON(atomic_read(&sk->sk_refcnt) == 1); | 2288 | WARN_ON(atomic_read(&sk->sk_refcnt) == 1); |
2352 | __sock_put(sk); | 2289 | __sock_put(sk); |
2353 | } | 2290 | } |
2354 | } | 2291 | } |
2355 | 2292 | ||
2293 | static const struct rhashtable_params tsk_rht_params = { | ||
2294 | .nelem_hint = 192, | ||
2295 | .head_offset = offsetof(struct tipc_sock, node), | ||
2296 | .key_offset = offsetof(struct tipc_sock, portid), | ||
2297 | .key_len = sizeof(u32), /* portid */ | ||
2298 | .max_size = 1048576, | ||
2299 | .min_size = 256, | ||
2300 | .automatic_shrinking = true, | ||
2301 | }; | ||
2302 | |||
2356 | int tipc_sk_rht_init(struct net *net) | 2303 | int tipc_sk_rht_init(struct net *net) |
2357 | { | 2304 | { |
2358 | struct tipc_net *tn = net_generic(net, tipc_net_id); | 2305 | struct tipc_net *tn = net_generic(net, tipc_net_id); |
2359 | struct rhashtable_params rht_params = { | ||
2360 | .nelem_hint = 192, | ||
2361 | .head_offset = offsetof(struct tipc_sock, node), | ||
2362 | .key_offset = offsetof(struct tipc_sock, portid), | ||
2363 | .key_len = sizeof(u32), /* portid */ | ||
2364 | .hashfn = jhash, | ||
2365 | .max_shift = 20, /* 1M */ | ||
2366 | .min_shift = 8, /* 256 */ | ||
2367 | .grow_decision = rht_grow_above_75, | ||
2368 | .shrink_decision = rht_shrink_below_30, | ||
2369 | }; | ||
2370 | 2306 | ||
2371 | return rhashtable_init(&tn->sk_rht, &rht_params); | 2307 | return rhashtable_init(&tn->sk_rht, &tsk_rht_params); |
2372 | } | 2308 | } |
2373 | 2309 | ||
2374 | void tipc_sk_rht_destroy(struct net *net) | 2310 | void tipc_sk_rht_destroy(struct net *net) |
@@ -2611,12 +2547,6 @@ static struct proto tipc_proto = { | |||
2611 | .sysctl_rmem = sysctl_tipc_rmem | 2547 | .sysctl_rmem = sysctl_tipc_rmem |
2612 | }; | 2548 | }; |
2613 | 2549 | ||
2614 | static struct proto tipc_proto_kern = { | ||
2615 | .name = "TIPC", | ||
2616 | .obj_size = sizeof(struct tipc_sock), | ||
2617 | .sysctl_rmem = sysctl_tipc_rmem | ||
2618 | }; | ||
2619 | |||
2620 | /** | 2550 | /** |
2621 | * tipc_socket_init - initialize TIPC socket interface | 2551 | * tipc_socket_init - initialize TIPC socket interface |
2622 | * | 2552 | * |