diff options
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 27 |
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 | } |