aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/bcast.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/bcast.c')
-rw-r--r--net/tipc/bcast.c87
1 files changed, 53 insertions, 34 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 55c6c9d3e1ce..dd13bfa09333 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * net/tipc/bcast.c: TIPC broadcast code 2 * net/tipc/bcast.c: TIPC broadcast code
3 * 3 *
4 * Copyright (c) 2004-2006, Ericsson AB 4 * Copyright (c) 2004-2006, 2014, Ericsson AB
5 * Copyright (c) 2004, Intel Corporation. 5 * Copyright (c) 2004, Intel Corporation.
6 * Copyright (c) 2005, 2010-2011, Wind River Systems 6 * Copyright (c) 2005, 2010-2011, Wind River Systems
7 * All rights reserved. 7 * All rights reserved.
@@ -38,6 +38,8 @@
38#include "core.h" 38#include "core.h"
39#include "link.h" 39#include "link.h"
40#include "port.h" 40#include "port.h"
41#include "socket.h"
42#include "msg.h"
41#include "bcast.h" 43#include "bcast.h"
42#include "name_distr.h" 44#include "name_distr.h"
43 45
@@ -138,6 +140,11 @@ static void tipc_bclink_unlock(void)
138 tipc_link_reset_all(node); 140 tipc_link_reset_all(node);
139} 141}
140 142
143uint tipc_bclink_get_mtu(void)
144{
145 return MAX_PKT_DEFAULT_MCAST;
146}
147
141void tipc_bclink_set_flags(unsigned int flags) 148void tipc_bclink_set_flags(unsigned int flags)
142{ 149{
143 bclink->flags |= flags; 150 bclink->flags |= flags;
@@ -382,30 +389,50 @@ static void bclink_peek_nack(struct tipc_msg *msg)
382 tipc_node_unlock(n_ptr); 389 tipc_node_unlock(n_ptr);
383} 390}
384 391
385/* 392/* tipc_bclink_xmit - broadcast buffer chain to all nodes in cluster
386 * tipc_bclink_xmit - broadcast a packet to all nodes in cluster 393 * and to identified node local sockets
394 * @buf: chain of buffers containing message
395 * Consumes the buffer chain, except when returning -ELINKCONG
396 * Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE
387 */ 397 */
388int tipc_bclink_xmit(struct sk_buff *buf) 398int tipc_bclink_xmit(struct sk_buff *buf)
389{ 399{
390 int res; 400 int rc = 0;
401 int bc = 0;
402 struct sk_buff *clbuf;
391 403
392 tipc_bclink_lock(); 404 /* Prepare clone of message for local node */
393 405 clbuf = tipc_msg_reassemble(buf);
394 if (!bclink->bcast_nodes.count) { 406 if (unlikely(!clbuf)) {
395 res = msg_data_sz(buf_msg(buf)); 407 kfree_skb_list(buf);
396 kfree_skb(buf); 408 return -EHOSTUNREACH;
397 goto exit;
398 } 409 }
399 410
400 res = __tipc_link_xmit(bcl, buf); 411 /* Broadcast to all other nodes */
401 if (likely(res >= 0)) { 412 if (likely(bclink)) {
402 bclink_set_last_sent(); 413 tipc_bclink_lock();
403 bcl->stats.queue_sz_counts++; 414 if (likely(bclink->bcast_nodes.count)) {
404 bcl->stats.accu_queue_sz += bcl->out_queue_size; 415 rc = __tipc_link_xmit(bcl, buf);
416 if (likely(!rc)) {
417 bclink_set_last_sent();
418 bcl->stats.queue_sz_counts++;
419 bcl->stats.accu_queue_sz += bcl->out_queue_size;
420 }
421 bc = 1;
422 }
423 tipc_bclink_unlock();
405 } 424 }
406exit: 425
407 tipc_bclink_unlock(); 426 if (unlikely(!bc))
408 return res; 427 kfree_skb_list(buf);
428
429 /* Deliver message clone */
430 if (likely(!rc))
431 tipc_sk_mcast_rcv(clbuf);
432 else
433 kfree_skb(clbuf);
434
435 return rc;
409} 436}
410 437
411/** 438/**
@@ -443,7 +470,7 @@ void tipc_bclink_rcv(struct sk_buff *buf)
443 struct tipc_node *node; 470 struct tipc_node *node;
444 u32 next_in; 471 u32 next_in;
445 u32 seqno; 472 u32 seqno;
446 int deferred; 473 int deferred = 0;
447 474
448 /* Screen out unwanted broadcast messages */ 475 /* Screen out unwanted broadcast messages */
449 476
@@ -494,7 +521,7 @@ receive:
494 tipc_bclink_unlock(); 521 tipc_bclink_unlock();
495 tipc_node_unlock(node); 522 tipc_node_unlock(node);
496 if (likely(msg_mcast(msg))) 523 if (likely(msg_mcast(msg)))
497 tipc_port_mcast_rcv(buf, NULL); 524 tipc_sk_mcast_rcv(buf);
498 else 525 else
499 kfree_skb(buf); 526 kfree_skb(buf);
500 } else if (msg_user(msg) == MSG_BUNDLER) { 527 } else if (msg_user(msg) == MSG_BUNDLER) {
@@ -573,8 +600,7 @@ receive:
573 node->bclink.deferred_size += deferred; 600 node->bclink.deferred_size += deferred;
574 bclink_update_last_sent(node, seqno); 601 bclink_update_last_sent(node, seqno);
575 buf = NULL; 602 buf = NULL;
576 } else 603 }
577 deferred = 0;
578 604
579 tipc_bclink_lock(); 605 tipc_bclink_lock();
580 606
@@ -611,6 +637,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf, struct tipc_bearer *unused1,
611 struct tipc_media_addr *unused2) 637 struct tipc_media_addr *unused2)
612{ 638{
613 int bp_index; 639 int bp_index;
640 struct tipc_msg *msg = buf_msg(buf);
614 641
615 /* Prepare broadcast link message for reliable transmission, 642 /* Prepare broadcast link message for reliable transmission,
616 * if first time trying to send it; 643 * if first time trying to send it;
@@ -618,10 +645,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf, struct tipc_bearer *unused1,
618 * since they are sent in an unreliable manner and don't need it 645 * since they are sent in an unreliable manner and don't need it
619 */ 646 */
620 if (likely(!msg_non_seq(buf_msg(buf)))) { 647 if (likely(!msg_non_seq(buf_msg(buf)))) {
621 struct tipc_msg *msg;
622
623 bcbuf_set_acks(buf, bclink->bcast_nodes.count); 648 bcbuf_set_acks(buf, bclink->bcast_nodes.count);
624 msg = buf_msg(buf);
625 msg_set_non_seq(msg, 1); 649 msg_set_non_seq(msg, 1);
626 msg_set_mc_netid(msg, tipc_net_id); 650 msg_set_mc_netid(msg, tipc_net_id);
627 bcl->stats.sent_info++; 651 bcl->stats.sent_info++;
@@ -638,12 +662,14 @@ static int tipc_bcbearer_send(struct sk_buff *buf, struct tipc_bearer *unused1,
638 for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) { 662 for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) {
639 struct tipc_bearer *p = bcbearer->bpairs[bp_index].primary; 663 struct tipc_bearer *p = bcbearer->bpairs[bp_index].primary;
640 struct tipc_bearer *s = bcbearer->bpairs[bp_index].secondary; 664 struct tipc_bearer *s = bcbearer->bpairs[bp_index].secondary;
641 struct tipc_bearer *b = p; 665 struct tipc_bearer *bp[2] = {p, s};
666 struct tipc_bearer *b = bp[msg_link_selector(msg)];
642 struct sk_buff *tbuf; 667 struct sk_buff *tbuf;
643 668
644 if (!p) 669 if (!p)
645 break; /* No more bearers to try */ 670 break; /* No more bearers to try */
646 671 if (!b)
672 b = p;
647 tipc_nmap_diff(&bcbearer->remains, &b->nodes, 673 tipc_nmap_diff(&bcbearer->remains, &b->nodes,
648 &bcbearer->remains_new); 674 &bcbearer->remains_new);
649 if (bcbearer->remains_new.count == bcbearer->remains.count) 675 if (bcbearer->remains_new.count == bcbearer->remains.count)
@@ -660,13 +686,6 @@ static int tipc_bcbearer_send(struct sk_buff *buf, struct tipc_bearer *unused1,
660 tipc_bearer_send(b->identity, tbuf, &b->bcast_addr); 686 tipc_bearer_send(b->identity, tbuf, &b->bcast_addr);
661 kfree_skb(tbuf); /* Bearer keeps a clone */ 687 kfree_skb(tbuf); /* Bearer keeps a clone */
662 } 688 }
663
664 /* Swap bearers for next packet */
665 if (s) {
666 bcbearer->bpairs[bp_index].primary = s;
667 bcbearer->bpairs[bp_index].secondary = p;
668 }
669
670 if (bcbearer->remains_new.count == 0) 689 if (bcbearer->remains_new.count == 0)
671 break; /* All targets reached */ 690 break; /* All targets reached */
672 691