diff options
Diffstat (limited to 'net/tipc/bcast.c')
-rw-r--r-- | net/tipc/bcast.c | 87 |
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 | ||
143 | uint tipc_bclink_get_mtu(void) | ||
144 | { | ||
145 | return MAX_PKT_DEFAULT_MCAST; | ||
146 | } | ||
147 | |||
141 | void tipc_bclink_set_flags(unsigned int flags) | 148 | void 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 | */ |
388 | int tipc_bclink_xmit(struct sk_buff *buf) | 398 | int 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 | } |
406 | exit: | 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 | ||