summaryrefslogtreecommitdiffstats
path: root/net/tipc/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r--net/tipc/socket.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index d2f353934f82..93b6ae3154c9 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -740,32 +740,43 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq,
740 struct tipc_msg *hdr = &tsk->phdr; 740 struct tipc_msg *hdr = &tsk->phdr;
741 struct net *net = sock_net(sk); 741 struct net *net = sock_net(sk);
742 int mtu = tipc_bcast_get_mtu(net); 742 int mtu = tipc_bcast_get_mtu(net);
743 u32 domain = addr_domain(net, TIPC_CLUSTER_SCOPE);
743 struct sk_buff_head pkts; 744 struct sk_buff_head pkts;
745 struct tipc_nlist dsts;
744 int rc; 746 int rc;
745 747
748 /* Block or return if any destination link is congested */
746 rc = tipc_wait_for_cond(sock, &timeout, !tsk->cong_link_cnt); 749 rc = tipc_wait_for_cond(sock, &timeout, !tsk->cong_link_cnt);
747 if (unlikely(rc)) 750 if (unlikely(rc))
748 return rc; 751 return rc;
749 752
753 /* Lookup destination nodes */
754 tipc_nlist_init(&dsts, tipc_own_addr(net));
755 tipc_nametbl_lookup_dst_nodes(net, seq->type, seq->lower,
756 seq->upper, domain, &dsts);
757 if (!dsts.local && !dsts.remote)
758 return -EHOSTUNREACH;
759
760 /* Build message header */
750 msg_set_type(hdr, TIPC_MCAST_MSG); 761 msg_set_type(hdr, TIPC_MCAST_MSG);
762 msg_set_hdr_sz(hdr, MCAST_H_SIZE);
751 msg_set_lookup_scope(hdr, TIPC_CLUSTER_SCOPE); 763 msg_set_lookup_scope(hdr, TIPC_CLUSTER_SCOPE);
752 msg_set_destport(hdr, 0); 764 msg_set_destport(hdr, 0);
753 msg_set_destnode(hdr, 0); 765 msg_set_destnode(hdr, 0);
754 msg_set_nametype(hdr, seq->type); 766 msg_set_nametype(hdr, seq->type);
755 msg_set_namelower(hdr, seq->lower); 767 msg_set_namelower(hdr, seq->lower);
756 msg_set_nameupper(hdr, seq->upper); 768 msg_set_nameupper(hdr, seq->upper);
757 msg_set_hdr_sz(hdr, MCAST_H_SIZE);
758 769
770 /* Build message as chain of buffers */
759 skb_queue_head_init(&pkts); 771 skb_queue_head_init(&pkts);
760 rc = tipc_msg_build(hdr, msg, 0, dlen, mtu, &pkts); 772 rc = tipc_msg_build(hdr, msg, 0, dlen, mtu, &pkts);
761 if (unlikely(rc != dlen))
762 return rc;
763 773
764 rc = tipc_bcast_xmit(net, &pkts); 774 /* Send message if build was successful */
765 if (unlikely(rc == -ELINKCONG)) { 775 if (unlikely(rc == dlen))
766 tsk->cong_link_cnt = 1; 776 rc = tipc_mcast_xmit(net, &pkts, &dsts,
767 rc = 0; 777 &tsk->cong_link_cnt);
768 } 778
779 tipc_nlist_purge(&dsts);
769 780
770 return rc ? rc : dlen; 781 return rc ? rc : dlen;
771} 782}