diff options
Diffstat (limited to 'net/tipc/bcast.c')
-rw-r--r-- | net/tipc/bcast.c | 111 |
1 files changed, 52 insertions, 59 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 759b318b5ffb..28908f54459e 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include "link.h" | 39 | #include "link.h" |
40 | #include "port.h" | 40 | #include "port.h" |
41 | #include "bcast.h" | 41 | #include "bcast.h" |
42 | #include "name_distr.h" | ||
42 | 43 | ||
43 | #define MAX_PKT_DEFAULT_MCAST 1500 /* bcast link max packet size (fixed) */ | 44 | #define MAX_PKT_DEFAULT_MCAST 1500 /* bcast link max packet size (fixed) */ |
44 | 45 | ||
@@ -298,14 +299,9 @@ static void bclink_send_nack(struct tipc_node *n_ptr) | |||
298 | msg_set_bcgap_to(msg, n_ptr->bclink.gap_to); | 299 | msg_set_bcgap_to(msg, n_ptr->bclink.gap_to); |
299 | msg_set_bcast_tag(msg, tipc_own_tag); | 300 | msg_set_bcast_tag(msg, tipc_own_tag); |
300 | 301 | ||
301 | if (tipc_bearer_send(&bcbearer->bearer, buf, NULL)) { | 302 | tipc_bearer_send(&bcbearer->bearer, buf, NULL); |
302 | bcl->stats.sent_nacks++; | 303 | bcl->stats.sent_nacks++; |
303 | buf_discard(buf); | 304 | buf_discard(buf); |
304 | } else { | ||
305 | tipc_bearer_schedule(bcl->b_ptr, bcl); | ||
306 | bcl->proto_msg_queue = buf; | ||
307 | bcl->stats.bearer_congs++; | ||
308 | } | ||
309 | 305 | ||
310 | /* | 306 | /* |
311 | * Ensure we doesn't send another NACK msg to the node | 307 | * Ensure we doesn't send another NACK msg to the node |
@@ -426,20 +422,28 @@ int tipc_bclink_send_msg(struct sk_buff *buf) | |||
426 | void tipc_bclink_recv_pkt(struct sk_buff *buf) | 422 | void tipc_bclink_recv_pkt(struct sk_buff *buf) |
427 | { | 423 | { |
428 | struct tipc_msg *msg = buf_msg(buf); | 424 | struct tipc_msg *msg = buf_msg(buf); |
429 | struct tipc_node *node = tipc_node_find(msg_prevnode(msg)); | 425 | struct tipc_node *node; |
430 | u32 next_in; | 426 | u32 next_in; |
431 | u32 seqno; | 427 | u32 seqno; |
432 | struct sk_buff *deferred; | 428 | struct sk_buff *deferred; |
433 | 429 | ||
434 | if (unlikely(!node || !tipc_node_is_up(node) || !node->bclink.supported || | 430 | /* Screen out unwanted broadcast messages */ |
435 | (msg_mc_netid(msg) != tipc_net_id))) { | 431 | |
436 | buf_discard(buf); | 432 | if (msg_mc_netid(msg) != tipc_net_id) |
437 | return; | 433 | goto exit; |
438 | } | 434 | |
435 | node = tipc_node_find(msg_prevnode(msg)); | ||
436 | if (unlikely(!node)) | ||
437 | goto exit; | ||
438 | |||
439 | tipc_node_lock(node); | ||
440 | if (unlikely(!node->bclink.supported)) | ||
441 | goto unlock; | ||
439 | 442 | ||
440 | if (unlikely(msg_user(msg) == BCAST_PROTOCOL)) { | 443 | if (unlikely(msg_user(msg) == BCAST_PROTOCOL)) { |
444 | if (msg_type(msg) != STATE_MSG) | ||
445 | goto unlock; | ||
441 | if (msg_destnode(msg) == tipc_own_addr) { | 446 | if (msg_destnode(msg) == tipc_own_addr) { |
442 | tipc_node_lock(node); | ||
443 | tipc_bclink_acknowledge(node, msg_bcast_ack(msg)); | 447 | tipc_bclink_acknowledge(node, msg_bcast_ack(msg)); |
444 | tipc_node_unlock(node); | 448 | tipc_node_unlock(node); |
445 | spin_lock_bh(&bc_lock); | 449 | spin_lock_bh(&bc_lock); |
@@ -449,18 +453,18 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf) | |||
449 | msg_bcgap_to(msg)); | 453 | msg_bcgap_to(msg)); |
450 | spin_unlock_bh(&bc_lock); | 454 | spin_unlock_bh(&bc_lock); |
451 | } else { | 455 | } else { |
456 | tipc_node_unlock(node); | ||
452 | tipc_bclink_peek_nack(msg_destnode(msg), | 457 | tipc_bclink_peek_nack(msg_destnode(msg), |
453 | msg_bcast_tag(msg), | 458 | msg_bcast_tag(msg), |
454 | msg_bcgap_after(msg), | 459 | msg_bcgap_after(msg), |
455 | msg_bcgap_to(msg)); | 460 | msg_bcgap_to(msg)); |
456 | } | 461 | } |
457 | buf_discard(buf); | 462 | goto exit; |
458 | return; | ||
459 | } | 463 | } |
460 | 464 | ||
461 | tipc_node_lock(node); | 465 | /* Handle in-sequence broadcast message */ |
466 | |||
462 | receive: | 467 | receive: |
463 | deferred = node->bclink.deferred_head; | ||
464 | next_in = mod(node->bclink.last_in + 1); | 468 | next_in = mod(node->bclink.last_in + 1); |
465 | seqno = msg_seqno(msg); | 469 | seqno = msg_seqno(msg); |
466 | 470 | ||
@@ -474,7 +478,10 @@ receive: | |||
474 | } | 478 | } |
475 | if (likely(msg_isdata(msg))) { | 479 | if (likely(msg_isdata(msg))) { |
476 | tipc_node_unlock(node); | 480 | tipc_node_unlock(node); |
477 | tipc_port_recv_mcast(buf, NULL); | 481 | if (likely(msg_mcast(msg))) |
482 | tipc_port_recv_mcast(buf, NULL); | ||
483 | else | ||
484 | buf_discard(buf); | ||
478 | } else if (msg_user(msg) == MSG_BUNDLER) { | 485 | } else if (msg_user(msg) == MSG_BUNDLER) { |
479 | bcl->stats.recv_bundles++; | 486 | bcl->stats.recv_bundles++; |
480 | bcl->stats.recv_bundled += msg_msgcnt(msg); | 487 | bcl->stats.recv_bundled += msg_msgcnt(msg); |
@@ -487,18 +494,22 @@ receive: | |||
487 | bcl->stats.recv_fragmented++; | 494 | bcl->stats.recv_fragmented++; |
488 | tipc_node_unlock(node); | 495 | tipc_node_unlock(node); |
489 | tipc_net_route_msg(buf); | 496 | tipc_net_route_msg(buf); |
497 | } else if (msg_user(msg) == NAME_DISTRIBUTOR) { | ||
498 | tipc_node_unlock(node); | ||
499 | tipc_named_recv(buf); | ||
490 | } else { | 500 | } else { |
491 | tipc_node_unlock(node); | 501 | tipc_node_unlock(node); |
492 | tipc_net_route_msg(buf); | 502 | buf_discard(buf); |
493 | } | 503 | } |
504 | buf = NULL; | ||
505 | tipc_node_lock(node); | ||
506 | deferred = node->bclink.deferred_head; | ||
494 | if (deferred && (buf_seqno(deferred) == mod(next_in + 1))) { | 507 | if (deferred && (buf_seqno(deferred) == mod(next_in + 1))) { |
495 | tipc_node_lock(node); | ||
496 | buf = deferred; | 508 | buf = deferred; |
497 | msg = buf_msg(buf); | 509 | msg = buf_msg(buf); |
498 | node->bclink.deferred_head = deferred->next; | 510 | node->bclink.deferred_head = deferred->next; |
499 | goto receive; | 511 | goto receive; |
500 | } | 512 | } |
501 | return; | ||
502 | } else if (less(next_in, seqno)) { | 513 | } else if (less(next_in, seqno)) { |
503 | u32 gap_after = node->bclink.gap_after; | 514 | u32 gap_after = node->bclink.gap_after; |
504 | u32 gap_to = node->bclink.gap_to; | 515 | u32 gap_to = node->bclink.gap_to; |
@@ -513,6 +524,7 @@ receive: | |||
513 | else if (less(gap_after, seqno) && less(seqno, gap_to)) | 524 | else if (less(gap_after, seqno) && less(seqno, gap_to)) |
514 | node->bclink.gap_to = seqno; | 525 | node->bclink.gap_to = seqno; |
515 | } | 526 | } |
527 | buf = NULL; | ||
516 | if (bclink_ack_allowed(node->bclink.nack_sync)) { | 528 | if (bclink_ack_allowed(node->bclink.nack_sync)) { |
517 | if (gap_to != gap_after) | 529 | if (gap_to != gap_after) |
518 | bclink_send_nack(node); | 530 | bclink_send_nack(node); |
@@ -520,9 +532,11 @@ receive: | |||
520 | } | 532 | } |
521 | } else { | 533 | } else { |
522 | bcl->stats.duplicates++; | 534 | bcl->stats.duplicates++; |
523 | buf_discard(buf); | ||
524 | } | 535 | } |
536 | unlock: | ||
525 | tipc_node_unlock(node); | 537 | tipc_node_unlock(node); |
538 | exit: | ||
539 | buf_discard(buf); | ||
526 | } | 540 | } |
527 | 541 | ||
528 | u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr) | 542 | u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr) |
@@ -535,10 +549,11 @@ u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr) | |||
535 | /** | 549 | /** |
536 | * tipc_bcbearer_send - send a packet through the broadcast pseudo-bearer | 550 | * tipc_bcbearer_send - send a packet through the broadcast pseudo-bearer |
537 | * | 551 | * |
538 | * Send through as many bearers as necessary to reach all nodes | 552 | * Send packet over as many bearers as necessary to reach all nodes |
539 | * that support TIPC multicasting. | 553 | * that have joined the broadcast link. |
540 | * | 554 | * |
541 | * Returns 0 if packet sent successfully, non-zero if not | 555 | * Returns 0 (packet sent successfully) under all circumstances, |
556 | * since the broadcast link's pseudo-bearer never blocks | ||
542 | */ | 557 | */ |
543 | 558 | ||
544 | static int tipc_bcbearer_send(struct sk_buff *buf, | 559 | static int tipc_bcbearer_send(struct sk_buff *buf, |
@@ -547,7 +562,12 @@ static int tipc_bcbearer_send(struct sk_buff *buf, | |||
547 | { | 562 | { |
548 | int bp_index; | 563 | int bp_index; |
549 | 564 | ||
550 | /* Prepare buffer for broadcasting (if first time trying to send it) */ | 565 | /* |
566 | * Prepare broadcast link message for reliable transmission, | ||
567 | * if first time trying to send it; | ||
568 | * preparation is skipped for broadcast link protocol messages | ||
569 | * since they are sent in an unreliable manner and don't need it | ||
570 | */ | ||
551 | 571 | ||
552 | if (likely(!msg_non_seq(buf_msg(buf)))) { | 572 | if (likely(!msg_non_seq(buf_msg(buf)))) { |
553 | struct tipc_msg *msg; | 573 | struct tipc_msg *msg; |
@@ -596,18 +616,12 @@ static int tipc_bcbearer_send(struct sk_buff *buf, | |||
596 | } | 616 | } |
597 | 617 | ||
598 | if (bcbearer->remains_new.count == 0) | 618 | if (bcbearer->remains_new.count == 0) |
599 | return 0; | 619 | break; /* all targets reached */ |
600 | 620 | ||
601 | bcbearer->remains = bcbearer->remains_new; | 621 | bcbearer->remains = bcbearer->remains_new; |
602 | } | 622 | } |
603 | 623 | ||
604 | /* | 624 | return 0; |
605 | * Unable to reach all targets (indicate success, since currently | ||
606 | * there isn't code in place to properly block & unblock the | ||
607 | * pseudo-bearer used by the broadcast link) | ||
608 | */ | ||
609 | |||
610 | return TIPC_OK; | ||
611 | } | 625 | } |
612 | 626 | ||
613 | /** | 627 | /** |
@@ -667,27 +681,6 @@ void tipc_bcbearer_sort(void) | |||
667 | spin_unlock_bh(&bc_lock); | 681 | spin_unlock_bh(&bc_lock); |
668 | } | 682 | } |
669 | 683 | ||
670 | /** | ||
671 | * tipc_bcbearer_push - resolve bearer congestion | ||
672 | * | ||
673 | * Forces bclink to push out any unsent packets, until all packets are gone | ||
674 | * or congestion reoccurs. | ||
675 | * No locks set when function called | ||
676 | */ | ||
677 | |||
678 | void tipc_bcbearer_push(void) | ||
679 | { | ||
680 | struct tipc_bearer *b_ptr; | ||
681 | |||
682 | spin_lock_bh(&bc_lock); | ||
683 | b_ptr = &bcbearer->bearer; | ||
684 | if (b_ptr->blocked) { | ||
685 | b_ptr->blocked = 0; | ||
686 | tipc_bearer_lock_push(b_ptr); | ||
687 | } | ||
688 | spin_unlock_bh(&bc_lock); | ||
689 | } | ||
690 | |||
691 | 684 | ||
692 | int tipc_bclink_stats(char *buf, const u32 buf_size) | 685 | int tipc_bclink_stats(char *buf, const u32 buf_size) |
693 | { | 686 | { |
@@ -764,7 +757,7 @@ int tipc_bclink_init(void) | |||
764 | bcbearer = kzalloc(sizeof(*bcbearer), GFP_ATOMIC); | 757 | bcbearer = kzalloc(sizeof(*bcbearer), GFP_ATOMIC); |
765 | bclink = kzalloc(sizeof(*bclink), GFP_ATOMIC); | 758 | bclink = kzalloc(sizeof(*bclink), GFP_ATOMIC); |
766 | if (!bcbearer || !bclink) { | 759 | if (!bcbearer || !bclink) { |
767 | warn("Multicast link creation failed, no memory\n"); | 760 | warn("Broadcast link creation failed, no memory\n"); |
768 | kfree(bcbearer); | 761 | kfree(bcbearer); |
769 | bcbearer = NULL; | 762 | bcbearer = NULL; |
770 | kfree(bclink); | 763 | kfree(bclink); |
@@ -775,7 +768,7 @@ int tipc_bclink_init(void) | |||
775 | INIT_LIST_HEAD(&bcbearer->bearer.cong_links); | 768 | INIT_LIST_HEAD(&bcbearer->bearer.cong_links); |
776 | bcbearer->bearer.media = &bcbearer->media; | 769 | bcbearer->bearer.media = &bcbearer->media; |
777 | bcbearer->media.send_msg = tipc_bcbearer_send; | 770 | bcbearer->media.send_msg = tipc_bcbearer_send; |
778 | sprintf(bcbearer->media.name, "tipc-multicast"); | 771 | sprintf(bcbearer->media.name, "tipc-broadcast"); |
779 | 772 | ||
780 | bcl = &bclink->link; | 773 | bcl = &bclink->link; |
781 | INIT_LIST_HEAD(&bcl->waiting_ports); | 774 | INIT_LIST_HEAD(&bcl->waiting_ports); |