aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/socket.c
diff options
context:
space:
mode:
authorJon Maloy <jon.maloy@ericsson.com>2017-10-13 05:04:27 -0400
committerDavid S. Miller <davem@davemloft.net>2017-10-13 11:46:00 -0400
commit27bd9ec027f396457d1a147043c92ff22fc4c71e (patch)
tree70ab55c12326ac70a33e9650d9760c17072d01ff /net/tipc/socket.c
parentb7d42635517fde2b095deddd0fba37be2302a285 (diff)
tipc: introduce group unicast messaging
We now make it possible to send connectionless unicast messages within a communication group. To send a message, the sender can use either a direct port address, aka port identity, or an indirect port name to be looked up. This type of messages are subject to the same start synchronization and flow control mechanism as group broadcast messages. Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Acked-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r--net/tipc/socket.c112
1 files changed, 102 insertions, 10 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 50145c95ac96..e71c8d23acb9 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -818,6 +818,93 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq,
818} 818}
819 819
820/** 820/**
821 * tipc_send_group_msg - send a message to a member in the group
822 * @net: network namespace
823 * @m: message to send
824 * @mb: group member
825 * @dnode: destination node
826 * @dport: destination port
827 * @dlen: total length of message data
828 */
829static int tipc_send_group_msg(struct net *net, struct tipc_sock *tsk,
830 struct msghdr *m, struct tipc_member *mb,
831 u32 dnode, u32 dport, int dlen)
832{
833 int blks = tsk_blocks(GROUP_H_SIZE + dlen);
834 struct tipc_msg *hdr = &tsk->phdr;
835 struct sk_buff_head pkts;
836 int mtu, rc;
837
838 /* Complete message header */
839 msg_set_type(hdr, TIPC_GRP_UCAST_MSG);
840 msg_set_hdr_sz(hdr, GROUP_H_SIZE);
841 msg_set_destport(hdr, dport);
842 msg_set_destnode(hdr, dnode);
843
844 /* Build message as chain of buffers */
845 skb_queue_head_init(&pkts);
846 mtu = tipc_node_get_mtu(net, dnode, tsk->portid);
847 rc = tipc_msg_build(hdr, m, 0, dlen, mtu, &pkts);
848 if (unlikely(rc != dlen))
849 return rc;
850
851 /* Send message */
852 rc = tipc_node_xmit(net, &pkts, dnode, tsk->portid);
853 if (unlikely(rc == -ELINKCONG)) {
854 tipc_dest_push(&tsk->cong_links, dnode, 0);
855 tsk->cong_link_cnt++;
856 }
857
858 /* Update send window and sequence number */
859 tipc_group_update_member(mb, blks);
860
861 return dlen;
862}
863
864/**
865 * tipc_send_group_unicast - send message to a member in the group
866 * @sock: socket structure
867 * @m: message to send
868 * @dlen: total length of message data
869 * @timeout: timeout to wait for wakeup
870 *
871 * Called from function tipc_sendmsg(), which has done all sanity checks
872 * Returns the number of bytes sent on success, or errno
873 */
874static int tipc_send_group_unicast(struct socket *sock, struct msghdr *m,
875 int dlen, long timeout)
876{
877 struct sock *sk = sock->sk;
878 DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name);
879 int blks = tsk_blocks(GROUP_H_SIZE + dlen);
880 struct tipc_sock *tsk = tipc_sk(sk);
881 struct tipc_group *grp = tsk->group;
882 struct net *net = sock_net(sk);
883 struct tipc_member *mb = NULL;
884 u32 node, port;
885 int rc;
886
887 node = dest->addr.id.node;
888 port = dest->addr.id.ref;
889 if (!port && !node)
890 return -EHOSTUNREACH;
891
892 /* Block or return if destination link or member is congested */
893 rc = tipc_wait_for_cond(sock, &timeout,
894 !tipc_dest_find(&tsk->cong_links, node, 0) &&
895 !tipc_group_cong(grp, node, port, blks, &mb));
896 if (unlikely(rc))
897 return rc;
898
899 if (unlikely(!mb))
900 return -EHOSTUNREACH;
901
902 rc = tipc_send_group_msg(net, tsk, m, mb, node, port, dlen);
903
904 return rc ? rc : dlen;
905}
906
907/**
821 * tipc_send_group_bcast - send message to all members in communication group 908 * tipc_send_group_bcast - send message to all members in communication group
822 * @sk: socket structure 909 * @sk: socket structure
823 * @m: message to send 910 * @m: message to send
@@ -1030,8 +1117,20 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dlen)
1030 if (unlikely(dlen > TIPC_MAX_USER_MSG_SIZE)) 1117 if (unlikely(dlen > TIPC_MAX_USER_MSG_SIZE))
1031 return -EMSGSIZE; 1118 return -EMSGSIZE;
1032 1119
1033 if (unlikely(grp && !dest)) 1120 if (likely(dest)) {
1034 return tipc_send_group_bcast(sock, m, dlen, timeout); 1121 if (unlikely(m->msg_namelen < sizeof(*dest)))
1122 return -EINVAL;
1123 if (unlikely(dest->family != AF_TIPC))
1124 return -EINVAL;
1125 }
1126
1127 if (grp) {
1128 if (!dest)
1129 return tipc_send_group_bcast(sock, m, dlen, timeout);
1130 if (dest->addrtype == TIPC_ADDR_ID)
1131 return tipc_send_group_unicast(sock, m, dlen, timeout);
1132 return -EINVAL;
1133 }
1035 1134
1036 if (unlikely(!dest)) { 1135 if (unlikely(!dest)) {
1037 dest = &tsk->peer; 1136 dest = &tsk->peer;
@@ -1039,12 +1138,6 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dlen)
1039 return -EDESTADDRREQ; 1138 return -EDESTADDRREQ;
1040 } 1139 }
1041 1140
1042 if (unlikely(m->msg_namelen < sizeof(*dest)))
1043 return -EINVAL;
1044
1045 if (unlikely(dest->family != AF_TIPC))
1046 return -EINVAL;
1047
1048 if (unlikely(syn)) { 1141 if (unlikely(syn)) {
1049 if (sk->sk_state == TIPC_LISTEN) 1142 if (sk->sk_state == TIPC_LISTEN)
1050 return -EPIPE; 1143 return -EPIPE;
@@ -1077,7 +1170,6 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dlen)
1077 msg_set_destport(hdr, dport); 1170 msg_set_destport(hdr, dport);
1078 if (unlikely(!dport && !dnode)) 1171 if (unlikely(!dport && !dnode))
1079 return -EHOSTUNREACH; 1172 return -EHOSTUNREACH;
1080
1081 } else if (dest->addrtype == TIPC_ADDR_ID) { 1173 } else if (dest->addrtype == TIPC_ADDR_ID) {
1082 dnode = dest->addr.id.node; 1174 dnode = dest->addr.id.node;
1083 msg_set_type(hdr, TIPC_DIRECT_MSG); 1175 msg_set_type(hdr, TIPC_DIRECT_MSG);
@@ -1846,7 +1938,7 @@ static void tipc_sk_filter_rcv(struct sock *sk, struct sk_buff *skb,
1846 1938
1847 if (unlikely(!msg_isdata(hdr))) 1939 if (unlikely(!msg_isdata(hdr)))
1848 tipc_sk_proto_rcv(sk, &inputq, xmitq); 1940 tipc_sk_proto_rcv(sk, &inputq, xmitq);
1849 else if (unlikely(msg_type(hdr) > TIPC_GRP_BCAST_MSG)) 1941 else if (unlikely(msg_type(hdr) > TIPC_GRP_UCAST_MSG))
1850 return kfree_skb(skb); 1942 return kfree_skb(skb);
1851 1943
1852 if (unlikely(grp)) 1944 if (unlikely(grp))