diff options
Diffstat (limited to 'net/tipc/bcast.c')
| -rw-r--r-- | net/tipc/bcast.c | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 2655c9f4ecad..e5f3da507823 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c | |||
| @@ -584,8 +584,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf, | |||
| 584 | { | 584 | { |
| 585 | int bp_index; | 585 | int bp_index; |
| 586 | 586 | ||
| 587 | /* | 587 | /* Prepare broadcast link message for reliable transmission, |
| 588 | * Prepare broadcast link message for reliable transmission, | ||
| 589 | * if first time trying to send it; | 588 | * if first time trying to send it; |
| 590 | * preparation is skipped for broadcast link protocol messages | 589 | * preparation is skipped for broadcast link protocol messages |
| 591 | * since they are sent in an unreliable manner and don't need it | 590 | * since they are sent in an unreliable manner and don't need it |
| @@ -611,30 +610,43 @@ static int tipc_bcbearer_send(struct sk_buff *buf, | |||
| 611 | for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) { | 610 | for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) { |
| 612 | struct tipc_bearer *p = bcbearer->bpairs[bp_index].primary; | 611 | struct tipc_bearer *p = bcbearer->bpairs[bp_index].primary; |
| 613 | struct tipc_bearer *s = bcbearer->bpairs[bp_index].secondary; | 612 | struct tipc_bearer *s = bcbearer->bpairs[bp_index].secondary; |
| 613 | struct tipc_bearer *b = p; | ||
| 614 | struct sk_buff *tbuf; | ||
| 614 | 615 | ||
| 615 | if (!p) | 616 | if (!p) |
| 616 | break; /* no more bearers to try */ | 617 | break; /* No more bearers to try */ |
| 618 | |||
| 619 | if (tipc_bearer_blocked(p)) { | ||
| 620 | if (!s || tipc_bearer_blocked(s)) | ||
| 621 | continue; /* Can't use either bearer */ | ||
| 622 | b = s; | ||
| 623 | } | ||
| 617 | 624 | ||
| 618 | tipc_nmap_diff(&bcbearer->remains, &p->nodes, &bcbearer->remains_new); | 625 | tipc_nmap_diff(&bcbearer->remains, &b->nodes, |
| 626 | &bcbearer->remains_new); | ||
| 619 | if (bcbearer->remains_new.count == bcbearer->remains.count) | 627 | if (bcbearer->remains_new.count == bcbearer->remains.count) |
| 620 | continue; /* bearer pair doesn't add anything */ | 628 | continue; /* Nothing added by bearer pair */ |
| 621 | 629 | ||
| 622 | if (!tipc_bearer_blocked(p)) | 630 | if (bp_index == 0) { |
| 623 | tipc_bearer_send(p, buf, &p->media->bcast_addr); | 631 | /* Use original buffer for first bearer */ |
| 624 | else if (s && !tipc_bearer_blocked(s)) | 632 | tipc_bearer_send(b, buf, &b->bcast_addr); |
| 625 | /* unable to send on primary bearer */ | 633 | } else { |
| 626 | tipc_bearer_send(s, buf, &s->media->bcast_addr); | 634 | /* Avoid concurrent buffer access */ |
| 627 | else | 635 | tbuf = pskb_copy(buf, GFP_ATOMIC); |
| 628 | /* unable to send on either bearer */ | 636 | if (!tbuf) |
| 629 | continue; | 637 | break; |
| 638 | tipc_bearer_send(b, tbuf, &b->bcast_addr); | ||
| 639 | kfree_skb(tbuf); /* Bearer keeps a clone */ | ||
| 640 | } | ||
| 630 | 641 | ||
| 642 | /* Swap bearers for next packet */ | ||
| 631 | if (s) { | 643 | if (s) { |
| 632 | bcbearer->bpairs[bp_index].primary = s; | 644 | bcbearer->bpairs[bp_index].primary = s; |
| 633 | bcbearer->bpairs[bp_index].secondary = p; | 645 | bcbearer->bpairs[bp_index].secondary = p; |
| 634 | } | 646 | } |
| 635 | 647 | ||
| 636 | if (bcbearer->remains_new.count == 0) | 648 | if (bcbearer->remains_new.count == 0) |
| 637 | break; /* all targets reached */ | 649 | break; /* All targets reached */ |
| 638 | 650 | ||
| 639 | bcbearer->remains = bcbearer->remains_new; | 651 | bcbearer->remains = bcbearer->remains_new; |
| 640 | } | 652 | } |
