aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/msg.c
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2014-07-16 20:41:00 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-17 00:38:18 -0400
commit078bec826f7b73cf2a2397680537bcb7e075b492 (patch)
tree8b30dce59fa8512d15a53cbcc404962c09372047 /net/tipc/msg.c
parent25b660c7e202d533e4985380b24729fd12de2b5e (diff)
tipc: add new functions for multicast and broadcast distribution
We add a new broadcast link transmit function in bclink.c and a new receive function in socket.c. The purpose is to move the branching between external and internal destination down to the link layer, just as we have done with unicast in earlier commits. We also make use of the new link-independent fragmentation support that was introduced in an earlier commit series. This gives a shorter and simpler code path, and makes it possible to obtain copy-free buffer delivery to all node local destination sockets. The new transmission code is added in parallel with the existing one, and will be used by the socket multicast send function in the next commit in this series. Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Reviewed-by: Erik Hugne <erik.hugne@ericsson.com> Reviewed-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/msg.c')
-rw-r--r--net/tipc/msg.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index ce6d929d66d2..9682296f5e7c 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -417,3 +417,38 @@ int tipc_msg_eval(struct sk_buff *buf, u32 *dnode)
417 msg_set_destport(msg, dport); 417 msg_set_destport(msg, dport);
418 return TIPC_OK; 418 return TIPC_OK;
419} 419}
420
421/* tipc_msg_reassemble() - clone a buffer chain of fragments and
422 * reassemble the clones into one message
423 */
424struct sk_buff *tipc_msg_reassemble(struct sk_buff *chain)
425{
426 struct sk_buff *buf = chain;
427 struct sk_buff *frag = buf;
428 struct sk_buff *head = NULL;
429 int hdr_sz;
430
431 /* Copy header if single buffer */
432 if (!buf->next) {
433 hdr_sz = skb_headroom(buf) + msg_hdr_sz(buf_msg(buf));
434 return __pskb_copy(buf, hdr_sz, GFP_ATOMIC);
435 }
436
437 /* Clone all fragments and reassemble */
438 while (buf) {
439 frag = skb_clone(buf, GFP_ATOMIC);
440 if (!frag)
441 goto error;
442 frag->next = NULL;
443 if (tipc_buf_append(&head, &frag))
444 break;
445 if (!head)
446 goto error;
447 buf = buf->next;
448 }
449 return frag;
450error:
451 pr_warn("Failed do clone local mcast rcv buffer\n");
452 kfree_skb(head);
453 return NULL;
454}