diff options
Diffstat (limited to 'net/tipc/socket.c')
| -rw-r--r-- | net/tipc/socket.c | 277 | 
1 files changed, 104 insertions, 173 deletions
| diff --git a/net/tipc/socket.c b/net/tipc/socket.c index f73e975af80b..9074b5cede38 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); | 
| @@ -1836,13 +1764,14 @@ static int tipc_sk_enqueue(struct sk_buff_head *inputq, struct sock *sk, | |||
| 1836 | int tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq) | 1764 | int tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq) | 
| 1837 | { | 1765 | { | 
| 1838 | u32 dnode, dport = 0; | 1766 | u32 dnode, dport = 0; | 
| 1839 | int err = -TIPC_ERR_NO_PORT; | 1767 | int err; | 
| 1840 | struct sk_buff *skb; | 1768 | struct sk_buff *skb; | 
| 1841 | struct tipc_sock *tsk; | 1769 | struct tipc_sock *tsk; | 
| 1842 | struct tipc_net *tn; | 1770 | struct tipc_net *tn; | 
| 1843 | struct sock *sk; | 1771 | struct sock *sk; | 
| 1844 | 1772 | ||
| 1845 | while (skb_queue_len(inputq)) { | 1773 | while (skb_queue_len(inputq)) { | 
| 1774 | err = -TIPC_ERR_NO_PORT; | ||
| 1846 | skb = NULL; | 1775 | skb = NULL; | 
| 1847 | dport = tipc_skb_peek_port(inputq, dport); | 1776 | dport = tipc_skb_peek_port(inputq, dport); | 
| 1848 | tsk = tipc_sk_lookup(net, dport); | 1777 | tsk = tipc_sk_lookup(net, dport); | 
| @@ -1909,17 +1838,26 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest, | |||
| 1909 | int destlen, int flags) | 1838 | int destlen, int flags) | 
| 1910 | { | 1839 | { | 
| 1911 | struct sock *sk = sock->sk; | 1840 | struct sock *sk = sock->sk; | 
| 1841 | struct tipc_sock *tsk = tipc_sk(sk); | ||
| 1912 | struct sockaddr_tipc *dst = (struct sockaddr_tipc *)dest; | 1842 | struct sockaddr_tipc *dst = (struct sockaddr_tipc *)dest; | 
| 1913 | struct msghdr m = {NULL,}; | 1843 | struct msghdr m = {NULL,}; | 
| 1914 | long timeout = (flags & O_NONBLOCK) ? 0 : tipc_sk(sk)->conn_timeout; | 1844 | long timeout = (flags & O_NONBLOCK) ? 0 : tsk->conn_timeout; | 
| 1915 | socket_state previous; | 1845 | socket_state previous; | 
| 1916 | int res; | 1846 | int res = 0; | 
| 1917 | 1847 | ||
| 1918 | lock_sock(sk); | 1848 | lock_sock(sk); | 
| 1919 | 1849 | ||
| 1920 | /* For now, TIPC does not allow use of connect() with DGRAM/RDM types */ | 1850 | /* DGRAM/RDM connect(), just save the destaddr */ | 
| 1921 | if (sock->state == SS_READY) { | 1851 | if (sock->state == SS_READY) { | 
| 1922 | res = -EOPNOTSUPP; | 1852 | if (dst->family == AF_UNSPEC) { | 
| 1853 | memset(&tsk->remote, 0, sizeof(struct sockaddr_tipc)); | ||
| 1854 | tsk->connected = 0; | ||
| 1855 | } else if (destlen != sizeof(struct sockaddr_tipc)) { | ||
| 1856 | res = -EINVAL; | ||
| 1857 | } else { | ||
| 1858 | memcpy(&tsk->remote, dest, destlen); | ||
| 1859 | tsk->connected = 1; | ||
| 1860 | } | ||
| 1923 | goto exit; | 1861 | goto exit; | 
| 1924 | } | 1862 | } | 
| 1925 | 1863 | ||
| @@ -1947,7 +1885,7 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest, | |||
| 1947 | if (!timeout) | 1885 | if (!timeout) | 
| 1948 | m.msg_flags = MSG_DONTWAIT; | 1886 | m.msg_flags = MSG_DONTWAIT; | 
| 1949 | 1887 | ||
| 1950 | res = tipc_sendmsg(NULL, sock, &m, 0); | 1888 | res = __tipc_sendmsg(sock, &m, 0); | 
| 1951 | if ((res < 0) && (res != -EWOULDBLOCK)) | 1889 | if ((res < 0) && (res != -EWOULDBLOCK)) | 
| 1952 | goto exit; | 1890 | goto exit; | 
| 1953 | 1891 | ||
| @@ -2027,12 +1965,12 @@ static int tipc_wait_for_accept(struct socket *sock, long timeo) | |||
| 2027 | err = -EINVAL; | 1965 | err = -EINVAL; | 
| 2028 | if (sock->state != SS_LISTENING) | 1966 | if (sock->state != SS_LISTENING) | 
| 2029 | break; | 1967 | break; | 
| 2030 | err = sock_intr_errno(timeo); | ||
| 2031 | if (signal_pending(current)) | ||
| 2032 | break; | ||
| 2033 | err = -EAGAIN; | 1968 | err = -EAGAIN; | 
| 2034 | if (!timeo) | 1969 | if (!timeo) | 
| 2035 | break; | 1970 | break; | 
| 1971 | err = sock_intr_errno(timeo); | ||
| 1972 | if (signal_pending(current)) | ||
| 1973 | break; | ||
| 2036 | } | 1974 | } | 
| 2037 | finish_wait(sk_sleep(sk), &wait); | 1975 | finish_wait(sk_sleep(sk), &wait); | 
| 2038 | return err; | 1976 | return err; | 
| @@ -2103,7 +2041,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags) | |||
| 2103 | struct msghdr m = {NULL,}; | 2041 | struct msghdr m = {NULL,}; | 
| 2104 | 2042 | ||
| 2105 | tsk_advance_rx_queue(sk); | 2043 | tsk_advance_rx_queue(sk); | 
| 2106 | tipc_send_packet(NULL, new_sock, &m, 0); | 2044 | __tipc_send_stream(new_sock, &m, 0); | 
| 2107 | } else { | 2045 | } else { | 
| 2108 | __skb_dequeue(&sk->sk_receive_queue); | 2046 | __skb_dequeue(&sk->sk_receive_queue); | 
| 2109 | __skb_queue_head(&new_sk->sk_receive_queue, buf); | 2047 | __skb_queue_head(&new_sk->sk_receive_queue, buf); | 
| @@ -2154,7 +2092,6 @@ restart: | |||
| 2154 | TIPC_CONN_SHUTDOWN)) | 2092 | TIPC_CONN_SHUTDOWN)) | 
| 2155 | tipc_link_xmit_skb(net, skb, dnode, | 2093 | tipc_link_xmit_skb(net, skb, dnode, | 
| 2156 | tsk->portid); | 2094 | tsk->portid); | 
| 2157 | tipc_node_remove_conn(net, dnode, tsk->portid); | ||
| 2158 | } else { | 2095 | } else { | 
| 2159 | dnode = tsk_peer_node(tsk); | 2096 | dnode = tsk_peer_node(tsk); | 
| 2160 | 2097 | ||
| @@ -2312,7 +2249,7 @@ static struct tipc_sock *tipc_sk_lookup(struct net *net, u32 portid) | |||
| 2312 | struct tipc_sock *tsk; | 2249 | struct tipc_sock *tsk; | 
| 2313 | 2250 | ||
| 2314 | rcu_read_lock(); | 2251 | rcu_read_lock(); | 
| 2315 | tsk = rhashtable_lookup(&tn->sk_rht, &portid); | 2252 | tsk = rhashtable_lookup_fast(&tn->sk_rht, &portid, tsk_rht_params); | 
| 2316 | if (tsk) | 2253 | if (tsk) | 
| 2317 | sock_hold(&tsk->sk); | 2254 | sock_hold(&tsk->sk); | 
| 2318 | rcu_read_unlock(); | 2255 | rcu_read_unlock(); | 
| @@ -2334,7 +2271,8 @@ static int tipc_sk_insert(struct tipc_sock *tsk) | |||
| 2334 | portid = TIPC_MIN_PORT; | 2271 | portid = TIPC_MIN_PORT; | 
| 2335 | tsk->portid = portid; | 2272 | tsk->portid = portid; | 
| 2336 | sock_hold(&tsk->sk); | 2273 | sock_hold(&tsk->sk); | 
| 2337 | if (rhashtable_lookup_insert(&tn->sk_rht, &tsk->node)) | 2274 | if (!rhashtable_lookup_insert_fast(&tn->sk_rht, &tsk->node, | 
| 2275 | tsk_rht_params)) | ||
| 2338 | return 0; | 2276 | return 0; | 
| 2339 | sock_put(&tsk->sk); | 2277 | sock_put(&tsk->sk); | 
| 2340 | } | 2278 | } | 
| @@ -2347,28 +2285,27 @@ static void tipc_sk_remove(struct tipc_sock *tsk) | |||
| 2347 | struct sock *sk = &tsk->sk; | 2285 | struct sock *sk = &tsk->sk; | 
| 2348 | struct tipc_net *tn = net_generic(sock_net(sk), tipc_net_id); | 2286 | struct tipc_net *tn = net_generic(sock_net(sk), tipc_net_id); | 
| 2349 | 2287 | ||
| 2350 | if (rhashtable_remove(&tn->sk_rht, &tsk->node)) { | 2288 | if (!rhashtable_remove_fast(&tn->sk_rht, &tsk->node, tsk_rht_params)) { | 
| 2351 | WARN_ON(atomic_read(&sk->sk_refcnt) == 1); | 2289 | WARN_ON(atomic_read(&sk->sk_refcnt) == 1); | 
| 2352 | __sock_put(sk); | 2290 | __sock_put(sk); | 
| 2353 | } | 2291 | } | 
| 2354 | } | 2292 | } | 
| 2355 | 2293 | ||
| 2294 | static const struct rhashtable_params tsk_rht_params = { | ||
| 2295 | .nelem_hint = 192, | ||
| 2296 | .head_offset = offsetof(struct tipc_sock, node), | ||
| 2297 | .key_offset = offsetof(struct tipc_sock, portid), | ||
| 2298 | .key_len = sizeof(u32), /* portid */ | ||
| 2299 | .max_size = 1048576, | ||
| 2300 | .min_size = 256, | ||
| 2301 | .automatic_shrinking = true, | ||
| 2302 | }; | ||
| 2303 | |||
| 2356 | int tipc_sk_rht_init(struct net *net) | 2304 | int tipc_sk_rht_init(struct net *net) | 
| 2357 | { | 2305 | { | 
| 2358 | struct tipc_net *tn = net_generic(net, tipc_net_id); | 2306 | 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 | 2307 | ||
| 2371 | return rhashtable_init(&tn->sk_rht, &rht_params); | 2308 | return rhashtable_init(&tn->sk_rht, &tsk_rht_params); | 
| 2372 | } | 2309 | } | 
| 2373 | 2310 | ||
| 2374 | void tipc_sk_rht_destroy(struct net *net) | 2311 | void tipc_sk_rht_destroy(struct net *net) | 
| @@ -2611,12 +2548,6 @@ static struct proto tipc_proto = { | |||
| 2611 | .sysctl_rmem = sysctl_tipc_rmem | 2548 | .sysctl_rmem = sysctl_tipc_rmem | 
| 2612 | }; | 2549 | }; | 
| 2613 | 2550 | ||
| 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 | /** | 2551 | /** | 
| 2621 | * tipc_socket_init - initialize TIPC socket interface | 2552 | * tipc_socket_init - initialize TIPC socket interface | 
| 2622 | * | 2553 | * | 
