Jon, I remembered I had ever given an ack for the series. Probably i forgot to send my ack. Anyway, I had spent time looking at all patches, as a result, no any issue was found during the review. This is very nice indeed. Thanks!
Sent from my iPhone > On 17 Jan 2017, at 11:06 PM, Jon Maloy <jon.ma...@ericsson.com> wrote: > > Thanks Partha. Any viewpoints form Ying? Otherwise I'll send it in tomorrow. > > ///jon > > >> -----Original Message----- >> From: Parthasarathy Bhuvaragan >> Sent: Tuesday, 17 January, 2017 09:35 >> To: Jon Maloy <jon.ma...@ericsson.com>; >> tipc-discussion@lists.sourceforge.net; >> Ying Xue <ying....@windriver.com> >> Subject: Re: [tipc-discussion] [net-next v3 3/4] tipc: introduce replicast as >> transport option for multicast >> >>> On 01/16/2017 03:13 PM, Jon Maloy wrote: >>> >>> >>>> -----Original Message----- >>>> From: Parthasarathy Bhuvaragan >>>> Sent: Monday, 16 January, 2017 05:20 >>>> To: Jon Maloy <jon.ma...@ericsson.com>; tipc- >> discuss...@lists.sourceforge.net; >>>> Ying Xue <ying....@windriver.com> >>>> Subject: Re: [tipc-discussion] [net-next v3 3/4] tipc: introduce replicast >>>> as >>>> transport option for multicast >>>> >>>>> On 01/13/2017 04:18 PM, Jon Maloy wrote: >>>>> >>>>> >>>>>> -----Original Message----- >>>>>> From: Parthasarathy Bhuvaragan >>>>>> Sent: Friday, 13 January, 2017 04:24 >>>>>> To: Jon Maloy <jon.ma...@ericsson.com>; tipc- >>>> discuss...@lists.sourceforge.net; >>>>>> Ying Xue <ying....@windriver.com> >>>>>> Subject: Re: [tipc-discussion] [net-next v3 3/4] tipc: introduce >>>>>> replicast as >>>>>> transport option for multicast >>>>>> >>>>>>> On 01/04/2017 06:05 PM, Parthasarathy Bhuvaragan wrote: >>>>>>> Hi Jon, >>>>>>> >>>>>>> Added some minor comments inline in this patch, apart from that the >>>>>>> major concern is the following: >>>>>>> >>>>>>> All my tests which passed before this patch, fails while sending >>>>>>> multicast to a receiver on own node. >>>>>>> >>>>>>> With this patch, we increase the likelyhood of receive buffer overflow >>>>>>> if the sender & receivers are running on the same host as we bypass the >>>>>>> link layer completely. I confirmed this with some traces in >>>>>>> filter_rcv(). >>>>>>> >>>>>>> If I add another multicast listener running on another node, this >>>>>>> pacifies the sender (put the sender to sleep at link congestion) and >>>>>>> relatively slow link layer reduces the buffer overflow. >>>>>>> >>>>>>> We need to find a way reduce the aggressiveness of the sender. >>>>>>> We want users to be transparent about the location of the services, so >>>>>>> we should to provide similar charecteristics regardless of the service >>>>>>> location. >>>>>>> >>>>>> Jon, running ptts sever and client on a standalone node without your >>>>>> updates failed. So in that aspect, iam ok with this patch. >>>>>> >>>>>> If the ethernet bearer lacks broadcast ability, then neighbor discovery >>>>>> will not work. So do we intend to introduce support to add ethernet >>>>>> peers manually as we do for udp bearers? otherwise we can never use >>>>>> replicast for non udp bearers. >>>>> >>>>> I believe all Ethernet implementations, even overlay networks, provide >> some >>>> form of broadcast, or in lack thereof, an emulated broadcast. >>>>> So, discovery should work, but it will be very inefficient when we do link >>>> broadcast, because tipc will think that genuine Ethernet broadcast is >> supported. >>>>> We actually need some way to find out what kind of "Ethernet" we are >>>> attached to, e.g. VXLAN, so that the "bcast supported" flag can be set >> correctly. >>>>> I wonder if that if possible, or if it has to be configured. >>>>> >>>> I assumed that, but thanks for the clarification. I infer from your >>>> statement that its the User, who shall configure this per socket in case >>>> tipc is running over some kind of overlay networks. Tipc has no >>>> knowledge about the tunnel mechanisms used under the exposed bearers. >>> >>> No, I don't think that is a good option. I think it will be in only very >>> special cases >> the user will want to enforce replicast, (e.g., security, or if he know >> there will >> always be very few destinations), and those would not be related to the >> deployment. >>> >>>> >>>> In that case, its more logical if we set this as a node attribute and >>>> the sockets inherit them? >>>> Since the applications itself usually are agnostic of the deployment >>>> environments, it's not correct to place the platform specific logic >>>> inside the application. >>> >>> I was thinking more of setting this as a configured bearer attribute, >>> unless we >> find a way to deduce it from the interface attributes. I just didn't see >> this as part >> of this series, but it should be done. >>> >>>> >>>> I think you need to rephrase the commit message. I read the commit >>>> message as if we are introducing a complete link level broadcast service >>>> replacement. But that's incorrect, as still broadcast link for neighbor >>>> discovery. >>> >>> Yes. This is only an optimization for broadcast traffic, nit neighbor >>> discovery. >>> >> Thanks Jon for the clarification. You may add my tag for the entire >> series if you want to. >> Reviewed-by: Parthasarathy Bhuvaragan >> <parthasarathy.bhuvara...@ericsson.com> >> >> /Partha >>> ///jon >>> >>>> >>>> Thanks for your patience, probably its just me getting confused with the >>>> purpose of the change-sets. >>>> >>>> /Partha >>>> >>>>> ///jon >>>>> >>>>>> >>>>>> /Partha >>>>>> >>>>>>> /Partha >>>>>>> >>>>>>>> On 01/02/2017 03:34 PM, Parthasarathy Bhuvaragan wrote: >>>>>>>> Hi jon, >>>>>>>> >>>>>>>> When I include this patch, ptts case 12 (multicast) fails when the >>>>>>>> client and server are running on the same node. >>>>>>>> >>>>>>>> /Partha >>>>>>>> >>>>>>>>> On 12/22/2016 04:15 PM, Jon Maloy wrote: >>>>>>>>> TIPC multicast messages are currently carried over a reliable >>>>>>>>> 'broadcast link', making use of the underlying media's ability to >>>>>>>>> transport packets as L2 broadcast or IP multicast to all nodes in >>>>>>>>> the cluster. >>>>>>>>> >>>>>>>>> When the used bearer is lacking that ability, we can instead emulate >>>>>>>>> the broadcast service by relicating and sending the packets over as >>>>>>>>> many unicast links as needed to reach all identified destinations. >>>>>>>>> We now introduce a new TIPC link-level 'replicast' service that does >>>>>>>>> this. >>>>>>>>> >>>>>>>>> Signed-off-by: Jon Maloy <jon.ma...@ericsson.com> >>>>>>>>> --- >>>>>>>>> net/tipc/bcast.c | 105 >>>>>> ++++++++++++++++++++++++++++++++++++++++++------------ >>>>>>>>> net/tipc/bcast.h | 3 +- >>>>>>>>> net/tipc/link.c | 8 ++++- >>>>>>>>> net/tipc/msg.c | 17 +++++++++ >>>>>>>>> net/tipc/msg.h | 9 +++-- >>>>>>>>> net/tipc/node.c | 27 +++++++++----- >>>>>>>>> net/tipc/socket.c | 27 +++++++++----- >>>>>>>>> 7 files changed, 149 insertions(+), 47 deletions(-) >>>>>>>>> >>>>>>>>> diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c >>>>>>>>> index 412d335..672e6ef 100644 >>>>>>>>> --- a/net/tipc/bcast.c >>>>>>>>> +++ b/net/tipc/bcast.c >>>>>>>>> @@ -70,7 +70,7 @@ static struct tipc_bc_base *tipc_bc_base(struct net >>>>>> *net) >>>>>>>>> >>>>>>>>> int tipc_bcast_get_mtu(struct net *net) >>>>>>>>> { >>>>>>>>> - return tipc_link_mtu(tipc_bc_sndlink(net)); >>>>>>>>> + return tipc_link_mtu(tipc_bc_sndlink(net)) - INT_H_SIZE; >>>>>>>>> } >>>>>>>>> >>>>>>>>> /* tipc_bcbase_select_primary(): find a bearer with links to all >>>> destinations, >>>>>>>>> @@ -175,42 +175,101 @@ static void tipc_bcbase_xmit(struct net *net, >>>>>> struct sk_buff_head *xmitq) >>>>>>>>> __skb_queue_purge(&_xmitq); >>>>>>>>> } >>>>>>>>> >>>>>>>>> -/* tipc_bcast_xmit - deliver buffer chain to all nodes in cluster >>>>>>>>> - * and to identified node local sockets >>>>>>>>> +/* tipc_bcast_xmit - broadcast the buffer chain to all external nodes >>>>>>>>> * @net: the applicable net namespace >>>>>>>>> - * @list: chain of buffers containing message >>>>>>>>> + * @pkts: chain of buffers containing message >>>>>>>>> + * @cong_link_cnt: set to 1 if broadcast link is congested, >>>>>>>>> otherwise 0 >>>>>>>>> * Consumes the buffer chain. >>>>>>>>> - * Returns 0 if success, otherwise errno: -ELINKCONG,- >> EHOSTUNREACH,- >>>>>> EMSGSIZE >>>>>>>>> + * Returns 0 if success, otherwise errno: -EHOSTUNREACH,-EMSGSIZE >>>>>>>>> */ >>>>>>>>> -int tipc_bcast_xmit(struct net *net, struct sk_buff_head *list) >>>>>>>>> +static int tipc_bcast_xmit(struct net *net, struct sk_buff_head >>>>>>>>> *pkts, >>>>>>>>> + u16 *cong_link_cnt) >>>>>>>>> { >>>>>>>>> struct tipc_link *l = tipc_bc_sndlink(net); >>>>>>>>> - struct sk_buff_head xmitq, inputq, rcvq; >>>>>>>>> + struct sk_buff_head xmitq; >>>>>>>>> int rc = 0; >>>>>>>>> >>>>>>>>> - __skb_queue_head_init(&rcvq); >>>>>>>>> __skb_queue_head_init(&xmitq); >>>>>>>>> - skb_queue_head_init(&inputq); >>>>>>>>> - >>>>>>>>> - /* Prepare message clone for local node */ >>>>>>>>> - if (unlikely(!tipc_msg_reassemble(list, &rcvq))) >>>>>>>>> - return -EHOSTUNREACH; >>>>>>>>> - >>>>>>>>> tipc_bcast_lock(net); >>>>>>>>> if (tipc_link_bc_peers(l)) >>>>>>>>> - rc = tipc_link_xmit(l, list, &xmitq); >>>>>>>>> + rc = tipc_link_xmit(l, pkts, &xmitq); >>>>>>>>> tipc_bcast_unlock(net); >>>>>>>>> + tipc_bcbase_xmit(net, &xmitq); >>>>>>>>> + __skb_queue_purge(pkts); >>>>>>>>> + if (rc == -ELINKCONG) { >>>>>>>>> + *cong_link_cnt = 1; >>>>>>>>> + rc = 0; >>>>>>>>> + } >>>>>>>>> + return rc; >>>>>>>>> +} >>>>>>>>> >>>>>>>>> - /* Don't send to local node if adding to link failed */ >>>>>>>>> - if (unlikely(rc && (rc != -ELINKCONG))) { >>>>>>>>> - __skb_queue_purge(&rcvq); >>>>>>>>> - return rc; >>>>>>>>> +/* tipc_rcast_xmit - replicate and send a message to given >>>>>>>>> destination >>>>>> nodes >>>>>>>>> + * @net: the applicable net namespace >>>>>>>>> + * @pkts: chain of buffers containing message >>>>>>>>> + * @dests: list of destination nodes >>>>>>>>> + * @cong_link_cnt: returns number of congested links >>>>>>>>> + * @cong_links: returns identities of congested links >>>>>>> remove @cong_links >>>>>>>>> + * Returns 0 if success, otherwise errno >>>>>>>>> + */ >>>>>>>>> +static int tipc_rcast_xmit(struct net *net, struct sk_buff_head >>>>>>>>> *pkts, >>>>>>>>> + struct tipc_nlist *dests, u16 *cong_link_cnt) >>>>>>>>> +{ >>>>>>>>> + struct sk_buff_head _pkts; >>>>>>>>> + struct u32_item *n, *tmp; >>>>>>>>> + u32 dst, selector; >>>>>>>>> + >>>>>>>>> + selector = msg_link_selector(buf_msg(skb_peek(pkts))); >>>>>>>>> + __skb_queue_head_init(&_pkts); >>>>>>>>> + >>>>>>>>> + list_for_each_entry_safe(n, tmp, &dests->list, list) { >>>>>>>>> + dst = n->value; >>>>>>>>> + if (!tipc_msg_pskb_copy(dst, pkts, &_pkts)) >>>>>>>>> + return -ENOMEM; >>>>>>>>> + >>>>>>>>> + /* Any other return value than -ELINKCONG is ignored */ >>>>>>>>> + if (tipc_node_xmit(net, &_pkts, dst, selector) == >>>>>>>>> -ELINKCONG) >>>>>>>>> + (*cong_link_cnt)++; >>>>>>>>> } >>>>>>>>> + return 0; >>>>>>>>> +} >>>>>>>>> >>>>>>>>> - /* Broadcast to all nodes, inluding local node */ >>>>>>>>> - tipc_bcbase_xmit(net, &xmitq); >>>>>>>>> - tipc_sk_mcast_rcv(net, &rcvq, &inputq); >>>>>>>>> - __skb_queue_purge(list); >>>>>>>>> +/* tipc_mcast_xmit - deliver message to indicated destination nodes >>>>>>>>> + * and to identified node local sockets >>>>>>>>> + * @net: the applicable net namespace >>>>>>>>> + * @pkts: chain of buffers containing message >>>>>>>>> + * @dests: destination nodes for message. Not consumed. >>>>>>>>> + * @cong_link_cnt: returns number of encountered congested >>>> destination >>>>>> links >>>>>>>>> + * @cong_links: returns identities of congested links >>>>>>> remove @cong_links >>>>>>>>> + * Consumes buffer chain. >>>>>>>>> + * Returns 0 if success, otherwise errno >>>>>>>>> + */ >>>>>>>>> +int tipc_mcast_xmit(struct net *net, struct sk_buff_head *pkts, >>>>>>>>> + struct tipc_nlist *dests, u16 *cong_link_cnt) >>>>>>>>> +{ >>>>>>>>> + struct tipc_bc_base *bb = tipc_bc_base(net); >>>>>>>>> + struct sk_buff_head inputq, localq; >>>>>>>>> + int rc = 0; >>>>>>>>> + >>>>>>>>> + skb_queue_head_init(&inputq); >>>>>>>>> + skb_queue_head_init(&localq); >>>>>>>>> + >>>>>>>>> + /* Clone packets before they are consumed by next call */ >>>>>>>>> + if (dests->local && !tipc_msg_reassemble(pkts, &localq)) { >>>>>>>>> + rc = -ENOMEM; >>>>>>>>> + goto exit; >>>>>>>>> + } >>>>>>>>> + >>>>>>>>> + if (dests->remote) { >>>>>>>>> + if (!bb->bcast_support) >>>>>>>>> + rc = tipc_rcast_xmit(net, pkts, dests, >>>>>>>>> cong_link_cnt); >>>>>>>>> + else >>>>>>>>> + rc = tipc_bcast_xmit(net, pkts, cong_link_cnt); >>>>>>>>> + } >>>>>>>>> + >>>>>>>>> + if (dests->local) >>>>>>>>> + tipc_sk_mcast_rcv(net, &localq, &inputq); >>>>>>>>> +exit: >>>>>>>>> + __skb_queue_purge(pkts); >>>>>>>>> return rc; >>>>>>>>> } >>>>>>>>> >>>>>>>>> diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h >>>>>>>>> index 18f3791..dd772e6 100644 >>>>>>>>> --- a/net/tipc/bcast.h >>>>>>>>> +++ b/net/tipc/bcast.h >>>>>>>>> @@ -66,7 +66,8 @@ void tipc_bcast_remove_peer(struct net *net, >> struct >>>>>> tipc_link *rcv_bcl); >>>>>>>>> void tipc_bcast_inc_bearer_dst_cnt(struct net *net, int bearer_id); >>>>>>>>> void tipc_bcast_dec_bearer_dst_cnt(struct net *net, int bearer_id); >>>>>>>>> int tipc_bcast_get_mtu(struct net *net); >>>>>>>>> -int tipc_bcast_xmit(struct net *net, struct sk_buff_head *list); >>>>>>>>> +int tipc_mcast_xmit(struct net *net, struct sk_buff_head *pkts, >>>>>>>>> + struct tipc_nlist *dests, u16 *cong_link_cnt); >>>>>>>>> int tipc_bcast_rcv(struct net *net, struct tipc_link *l, struct >>>>>>>>> sk_buff >> *skb); >>>>>>>>> void tipc_bcast_ack_rcv(struct net *net, struct tipc_link *l, >>>>>>>>> struct tipc_msg *hdr); >>>>>>>>> diff --git a/net/tipc/link.c b/net/tipc/link.c >>>>>>>>> index b758ca8..d1766ce 100644 >>>>>>>>> --- a/net/tipc/link.c >>>>>>>>> +++ b/net/tipc/link.c >>>>>>>>> @@ -1032,11 +1032,17 @@ int tipc_link_retrans(struct tipc_link *l, u16 >>>> from, >>>>>> u16 to, >>>>>>>>> static bool tipc_data_input(struct tipc_link *l, struct sk_buff *skb, >>>>>>>>> struct sk_buff_head *inputq) >>>>>>>>> { >>>>>>>>> - switch (msg_user(buf_msg(skb))) { >>>>>>>>> + struct tipc_msg *hdr = buf_msg(skb); >>>>>>>>> + >>>>>>>>> + switch (msg_user(hdr)) { >>>>>>>>> case TIPC_LOW_IMPORTANCE: >>>>>>>>> case TIPC_MEDIUM_IMPORTANCE: >>>>>>>>> case TIPC_HIGH_IMPORTANCE: >>>>>>>>> case TIPC_CRITICAL_IMPORTANCE: >>>>>>>>> + if (unlikely(msg_type(hdr) == TIPC_MCAST_MSG)) { >>>>>>>>> + skb_queue_tail(l->bc_rcvlink->inputq, skb); >>>>>>>>> + return true; >>>>>>>>> + } >>>>>>>>> case CONN_MANAGER: >>>>>>>>> skb_queue_tail(inputq, skb); >>>>>>>>> return true; >>>>>>>>> diff --git a/net/tipc/msg.c b/net/tipc/msg.c >>>>>>>>> index 17201aa..f4e6197 100644 >>>>>>>>> --- a/net/tipc/msg.c >>>>>>>>> +++ b/net/tipc/msg.c >>>>>>>>> @@ -607,6 +607,23 @@ bool tipc_msg_reassemble(struct >> sk_buff_head >>>>>> *list, struct sk_buff_head *rcvq) >>>>>>>>> return false; >>>>>>>>> } >>>>>>>>> >>>>>>>>> +bool tipc_msg_pskb_copy(u32 dst, struct sk_buff_head *msg, >>>>>>>>> + struct sk_buff_head *cpy) >>>>>>>>> +{ >>>>>>>>> + struct sk_buff *skb, *_skb; >>>>>>>>> + >>>>>>>>> + skb_queue_walk(msg, skb) { >>>>>>>>> + _skb = pskb_copy(skb, GFP_ATOMIC); >>>>>>>>> + if (!_skb) { >>>>>>>>> + __skb_queue_purge(cpy); >>>>>>>>> + return false; >>>>>>>>> + } >>>>>>>>> + msg_set_destnode(buf_msg(_skb), dst); >>>>>>>>> + __skb_queue_tail(cpy, _skb); >>>>>>>>> + } >>>>>>>>> + return true; >>>>>>>>> +} >>>>>>>>> + >>>>>>>>> /* tipc_skb_queue_sorted(); sort pkt into list according to sequence >>>>>> number >>>>>>>>> * @list: list to be appended to >>>>>>>>> * @seqno: sequence number of buffer to add >>>>>>>>> diff --git a/net/tipc/msg.h b/net/tipc/msg.h >>>>>>>>> index 850ae0e..295e477 100644 >>>>>>>>> --- a/net/tipc/msg.h >>>>>>>>> +++ b/net/tipc/msg.h >>>>>>>>> @@ -631,14 +631,11 @@ static inline void msg_set_bc_netid(struct >>>> tipc_msg >>>>>> *m, u32 id) >>>>>>>>> >>>>>>>>> static inline u32 msg_link_selector(struct tipc_msg *m) >>>>>>>>> { >>>>>>>>> + if (msg_user(m) == MSG_FRAGMENTER) >>>>>>>>> + m = (void *)msg_data(m); >>>>>>>>> return msg_bits(m, 4, 0, 1); >>>>>>>>> } >>>>>>>>> >>>>>>>>> -static inline void msg_set_link_selector(struct tipc_msg *m, u32 n) >>>>>>>>> -{ >>>>>>>>> - msg_set_bits(m, 4, 0, 1, n); >>>>>>>>> -} >>>>>>>>> - >>>>>>>>> /* >>>>>>>>> * Word 5 >>>>>>>>> */ >>>>>>>>> @@ -835,6 +832,8 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct >>>>>> msghdr *m, >>>>>>>>> int offset, int dsz, int mtu, struct sk_buff_head *list); >>>>>>>>> bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb, int >>>> *err); >>>>>>>>> bool tipc_msg_reassemble(struct sk_buff_head *list, struct >>>> sk_buff_head >>>>>> *rcvq); >>>>>>>>> +bool tipc_msg_pskb_copy(u32 dst, struct sk_buff_head *msg, >>>>>>>>> + struct sk_buff_head *cpy); >>>>>>>>> void __tipc_skb_queue_sorted(struct sk_buff_head *list, u16 seqno, >>>>>>>>> struct sk_buff *skb); >>>>>>>>> >>>>>>>>> diff --git a/net/tipc/node.c b/net/tipc/node.c >>>>>>>>> index 2883f6a..f96dacf 100644 >>>>>>>>> --- a/net/tipc/node.c >>>>>>>>> +++ b/net/tipc/node.c >>>>>>>>> @@ -1257,6 +1257,19 @@ void tipc_node_broadcast(struct net *net, >>>> struct >>>>>> sk_buff *skb) >>>>>>>>> kfree_skb(skb); >>>>>>>>> } >>>>>>>>> >>>>>>>>> +static void tipc_node_mcast_rcv(struct tipc_node *n) >>>>>>>>> +{ >>>>>>>>> + struct tipc_bclink_entry *be = &n->bc_entry; >>>>>>>>> + >>>>>>>>> + /* 'arrvq' is under inputq2's lock protection */ >>>>>>>>> + spin_lock_bh(&be->inputq2.lock); >>>>>>>>> + spin_lock_bh(&be->inputq1.lock); >>>>>>>>> + skb_queue_splice_tail_init(&be->inputq1, &be->arrvq); >>>>>>>>> + spin_unlock_bh(&be->inputq1.lock); >>>>>>>>> + spin_unlock_bh(&be->inputq2.lock); >>>>>>>>> + tipc_sk_mcast_rcv(n->net, &be->arrvq, &be->inputq2); >>>>>>>>> +} >>>>>>>>> + >>>>>>>>> static void tipc_node_bc_sync_rcv(struct tipc_node *n, struct tipc_msg >>>>>> *hdr, >>>>>>>>> int bearer_id, struct sk_buff_head *xmitq) >>>>>>>>> { >>>>>>>>> @@ -1330,15 +1343,8 @@ static void tipc_node_bc_rcv(struct net *net, >>>>>> struct sk_buff *skb, int bearer_id >>>>>>>>> if (!skb_queue_empty(&xmitq)) >>>>>>>>> tipc_bearer_xmit(net, bearer_id, &xmitq, &le->maddr); >>>>>>>>> >>>>>>>>> - /* Deliver. 'arrvq' is under inputq2's lock protection */ >>>>>>>>> - if (!skb_queue_empty(&be->inputq1)) { >>>>>>>>> - spin_lock_bh(&be->inputq2.lock); >>>>>>>>> - spin_lock_bh(&be->inputq1.lock); >>>>>>>>> - skb_queue_splice_tail_init(&be->inputq1, &be->arrvq); >>>>>>>>> - spin_unlock_bh(&be->inputq1.lock); >>>>>>>>> - spin_unlock_bh(&be->inputq2.lock); >>>>>>>>> - tipc_sk_mcast_rcv(net, &be->arrvq, &be->inputq2); >>>>>>>>> - } >>>>>>>>> + if (!skb_queue_empty(&be->inputq1)) >>>>>>>>> + tipc_node_mcast_rcv(n); >>>>>>>>> >>>>>>>>> if (rc & TIPC_LINK_DOWN_EVT) { >>>>>>>>> /* Reception reassembly failure => reset all links to peer */ >>>>>>>>> @@ -1565,6 +1571,9 @@ void tipc_rcv(struct net *net, struct sk_buff >>>> *skb, >>>>>> struct tipc_bearer *b) >>>>>>>>> if (unlikely(!skb_queue_empty(&n->bc_entry.namedq))) >>>>>>>>> tipc_named_rcv(net, &n->bc_entry.namedq); >>>>>>>>> >>>>>>>>> + if (unlikely(!skb_queue_empty(&n->bc_entry.inputq1))) >>>>>>>>> + tipc_node_mcast_rcv(n); >>>>>>>>> + >>>>>>>>> if (!skb_queue_empty(&le->inputq)) >>>>>>>>> tipc_sk_rcv(net, &le->inputq); >>>>>>>>> >>>>>>>>> diff --git a/net/tipc/socket.c b/net/tipc/socket.c >>>>>>>>> index b456265..1f948e6 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, >>>>>>>>> struct tipc_msg *hdr = &tsk->phdr; >>>>>>>>> struct net *net = sock_net(sk); >>>>>>>>> int mtu = tipc_bcast_get_mtu(net); >>>>>>>>> + u32 domain = addr_domain(net, TIPC_CLUSTER_SCOPE); >>>>>>>>> struct sk_buff_head pkts; >>>>>>>>> + struct tipc_nlist dsts; >>>>>>>>> int rc; >>>>>>>>> >>>>>>>>> + /* Block or return if any destination link is congested */ >>>>>>>>> rc = tipc_wait_for_cond(sock, &timeout, !tsk->cong_link_cnt); >>>>>>>>> if (unlikely(rc)) >>>>>>>>> return rc; >>>>>>>>> >>>>>>>>> + /* Lookup destination nodes */ >>>>>>>>> + tipc_nlist_init(&dsts, tipc_own_addr(net)); >>>>>>>>> + tipc_nametbl_lookup_dst_nodes(net, seq->type, seq->lower, >>>>>>>>> + seq->upper, domain, &dsts); >>>>>>>>> + if (!dsts.local && !dsts.remote) >>>>>>>>> + return -EHOSTUNREACH; >>>>>>>>> + >>>>>>>>> + /* Build message header */ >>>>>>>>> msg_set_type(hdr, TIPC_MCAST_MSG); >>>>>>>>> + msg_set_hdr_sz(hdr, MCAST_H_SIZE); >>>>>>>>> msg_set_lookup_scope(hdr, TIPC_CLUSTER_SCOPE); >>>>>>>>> msg_set_destport(hdr, 0); >>>>>>>>> msg_set_destnode(hdr, 0); >>>>>>>>> msg_set_nametype(hdr, seq->type); >>>>>>>>> msg_set_namelower(hdr, seq->lower); >>>>>>>>> msg_set_nameupper(hdr, seq->upper); >>>>>>>>> - msg_set_hdr_sz(hdr, MCAST_H_SIZE); >>>>>>>>> >>>>>>>>> + /* Build message as chain of buffers */ >>>>>>>>> skb_queue_head_init(&pkts); >>>>>>>>> rc = tipc_msg_build(hdr, msg, 0, dlen, mtu, &pkts); >>>>>>>>> - if (unlikely(rc != dlen)) >>>>>>> if(likely(rc == dlen)) >>>>>>>>> - return rc; >>>>>>>>> >>>>>>>>> - rc = tipc_bcast_xmit(net, &pkts); >>>>>>>>> - if (unlikely(rc == -ELINKCONG)) { >>>>>>>>> - tsk->cong_link_cnt = 1; >>>>>>>>> - rc = 0; >>>>>>>>> - } >>>>>>>>> + /* Send message if build was successful */ >>>>>>>>> + if (unlikely(rc == dlen)) >>>>>>>>> + rc = tipc_mcast_xmit(net, &pkts, &dsts, >>>>>>>>> + &tsk->cong_link_cnt); >>>>>>>>> + >>>>>>>>> + tipc_nlist_purge(&dsts); >>>>>>>>> >>>>>>>>> return rc ? rc : dlen; >>>>>>>>> } >>>>>>>>> >>>>>>>> >>>>>>>> ------------------------------------------------------------------------------ >>>>>>>> Check out the vibrant tech community on one of the world's most >>>>>>>> engaging tech sites, SlashDot.org! http://sdm.link/slashdot >>>>>>>> _______________________________________________ >>>>>>>> tipc-discussion mailing list >>>>>>>> tipc-discussion@lists.sourceforge.net >>>>>>>> https://lists.sourceforge.net/lists/listinfo/tipc-discussion >>>>>>>> >>>>>>> >>>>>>> ------------------------------------------------------------------------------ >>>>>>> Check out the vibrant tech community on one of the world's most >>>>>>> engaging tech sites, SlashDot.org! http://sdm.link/slashdot >>>>>>> _______________________________________________ >>>>>>> tipc-discussion mailing list >>>>>>> tipc-discussion@lists.sourceforge.net >>>>>>> https://lists.sourceforge.net/lists/listinfo/tipc-discussion >>>>>>> ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot _______________________________________________ tipc-discussion mailing list tipc-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tipc-discussion