diff options
Diffstat (limited to 'net/tipc/bcast.c')
| -rw-r--r-- | net/tipc/bcast.c | 149 |
1 files changed, 126 insertions, 23 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index a3bfd4064912..a008c6689305 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c | |||
| @@ -119,7 +119,7 @@ static struct bclink *bclink = NULL; | |||
| 119 | static struct link *bcl = NULL; | 119 | static struct link *bcl = NULL; |
| 120 | static DEFINE_SPINLOCK(bc_lock); | 120 | static DEFINE_SPINLOCK(bc_lock); |
| 121 | 121 | ||
| 122 | const char tipc_bclink_name[] = "multicast-link"; | 122 | const char tipc_bclink_name[] = "broadcast-link"; |
| 123 | 123 | ||
| 124 | 124 | ||
| 125 | static u32 buf_seqno(struct sk_buff *buf) | 125 | static u32 buf_seqno(struct sk_buff *buf) |
| @@ -275,7 +275,7 @@ static void bclink_send_nack(struct tipc_node *n_ptr) | |||
| 275 | buf = buf_acquire(INT_H_SIZE); | 275 | buf = buf_acquire(INT_H_SIZE); |
| 276 | if (buf) { | 276 | if (buf) { |
| 277 | msg = buf_msg(buf); | 277 | msg = buf_msg(buf); |
| 278 | msg_init(msg, BCAST_PROTOCOL, STATE_MSG, | 278 | tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG, |
| 279 | INT_H_SIZE, n_ptr->addr); | 279 | INT_H_SIZE, n_ptr->addr); |
| 280 | msg_set_mc_netid(msg, tipc_net_id); | 280 | msg_set_mc_netid(msg, tipc_net_id); |
| 281 | msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in)); | 281 | msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in)); |
| @@ -558,10 +558,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf, | |||
| 558 | struct tipc_bearer *unused1, | 558 | struct tipc_bearer *unused1, |
| 559 | struct tipc_media_addr *unused2) | 559 | struct tipc_media_addr *unused2) |
| 560 | { | 560 | { |
| 561 | static int send_count = 0; | ||
| 562 | |||
| 563 | int bp_index; | 561 | int bp_index; |
| 564 | int swap_time; | ||
| 565 | 562 | ||
| 566 | /* Prepare buffer for broadcasting (if first time trying to send it) */ | 563 | /* Prepare buffer for broadcasting (if first time trying to send it) */ |
| 567 | 564 | ||
| @@ -575,11 +572,6 @@ static int tipc_bcbearer_send(struct sk_buff *buf, | |||
| 575 | msg_set_mc_netid(msg, tipc_net_id); | 572 | msg_set_mc_netid(msg, tipc_net_id); |
| 576 | } | 573 | } |
| 577 | 574 | ||
| 578 | /* Determine if bearer pairs should be swapped following this attempt */ | ||
| 579 | |||
| 580 | if ((swap_time = (++send_count >= 10))) | ||
| 581 | send_count = 0; | ||
| 582 | |||
| 583 | /* Send buffer over bearers until all targets reached */ | 575 | /* Send buffer over bearers until all targets reached */ |
| 584 | 576 | ||
| 585 | bcbearer->remains = tipc_cltr_bcast_nodes; | 577 | bcbearer->remains = tipc_cltr_bcast_nodes; |
| @@ -595,21 +587,22 @@ static int tipc_bcbearer_send(struct sk_buff *buf, | |||
| 595 | if (bcbearer->remains_new.count == bcbearer->remains.count) | 587 | if (bcbearer->remains_new.count == bcbearer->remains.count) |
| 596 | continue; /* bearer pair doesn't add anything */ | 588 | continue; /* bearer pair doesn't add anything */ |
| 597 | 589 | ||
| 598 | if (!p->publ.blocked && | 590 | if (p->publ.blocked || |
| 599 | !p->media->send_msg(buf, &p->publ, &p->media->bcast_addr)) { | 591 | p->media->send_msg(buf, &p->publ, &p->media->bcast_addr)) { |
| 600 | if (swap_time && s && !s->publ.blocked) | 592 | /* unable to send on primary bearer */ |
| 601 | goto swap; | 593 | if (!s || s->publ.blocked || |
| 602 | else | 594 | s->media->send_msg(buf, &s->publ, |
| 603 | goto update; | 595 | &s->media->bcast_addr)) { |
| 596 | /* unable to send on either bearer */ | ||
| 597 | continue; | ||
| 598 | } | ||
| 599 | } | ||
| 600 | |||
| 601 | if (s) { | ||
| 602 | bcbearer->bpairs[bp_index].primary = s; | ||
| 603 | bcbearer->bpairs[bp_index].secondary = p; | ||
| 604 | } | 604 | } |
| 605 | 605 | ||
| 606 | if (!s || s->publ.blocked || | ||
| 607 | s->media->send_msg(buf, &s->publ, &s->media->bcast_addr)) | ||
| 608 | continue; /* unable to send using bearer pair */ | ||
| 609 | swap: | ||
| 610 | bcbearer->bpairs[bp_index].primary = s; | ||
| 611 | bcbearer->bpairs[bp_index].secondary = p; | ||
| 612 | update: | ||
| 613 | if (bcbearer->remains_new.count == 0) | 606 | if (bcbearer->remains_new.count == 0) |
| 614 | return 0; | 607 | return 0; |
| 615 | 608 | ||
| @@ -829,3 +822,113 @@ void tipc_bclink_stop(void) | |||
| 829 | spin_unlock_bh(&bc_lock); | 822 | spin_unlock_bh(&bc_lock); |
| 830 | } | 823 | } |
| 831 | 824 | ||
| 825 | |||
| 826 | /** | ||
| 827 | * tipc_nmap_add - add a node to a node map | ||
| 828 | */ | ||
| 829 | |||
| 830 | void tipc_nmap_add(struct tipc_node_map *nm_ptr, u32 node) | ||
| 831 | { | ||
| 832 | int n = tipc_node(node); | ||
| 833 | int w = n / WSIZE; | ||
| 834 | u32 mask = (1 << (n % WSIZE)); | ||
| 835 | |||
| 836 | if ((nm_ptr->map[w] & mask) == 0) { | ||
| 837 | nm_ptr->count++; | ||
| 838 | nm_ptr->map[w] |= mask; | ||
| 839 | } | ||
| 840 | } | ||
| 841 | |||
| 842 | /** | ||
| 843 | * tipc_nmap_remove - remove a node from a node map | ||
| 844 | */ | ||
| 845 | |||
| 846 | void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node) | ||
| 847 | { | ||
| 848 | int n = tipc_node(node); | ||
| 849 | int w = n / WSIZE; | ||
| 850 | u32 mask = (1 << (n % WSIZE)); | ||
| 851 | |||
| 852 | if ((nm_ptr->map[w] & mask) != 0) { | ||
| 853 | nm_ptr->map[w] &= ~mask; | ||
| 854 | nm_ptr->count--; | ||
| 855 | } | ||
| 856 | } | ||
| 857 | |||
| 858 | /** | ||
| 859 | * tipc_nmap_diff - find differences between node maps | ||
| 860 | * @nm_a: input node map A | ||
| 861 | * @nm_b: input node map B | ||
| 862 | * @nm_diff: output node map A-B (i.e. nodes of A that are not in B) | ||
| 863 | */ | ||
| 864 | |||
| 865 | void tipc_nmap_diff(struct tipc_node_map *nm_a, struct tipc_node_map *nm_b, | ||
| 866 | struct tipc_node_map *nm_diff) | ||
| 867 | { | ||
| 868 | int stop = ARRAY_SIZE(nm_a->map); | ||
| 869 | int w; | ||
| 870 | int b; | ||
| 871 | u32 map; | ||
| 872 | |||
| 873 | memset(nm_diff, 0, sizeof(*nm_diff)); | ||
| 874 | for (w = 0; w < stop; w++) { | ||
| 875 | map = nm_a->map[w] ^ (nm_a->map[w] & nm_b->map[w]); | ||
| 876 | nm_diff->map[w] = map; | ||
| 877 | if (map != 0) { | ||
| 878 | for (b = 0 ; b < WSIZE; b++) { | ||
| 879 | if (map & (1 << b)) | ||
| 880 | nm_diff->count++; | ||
| 881 | } | ||
| 882 | } | ||
| 883 | } | ||
| 884 | } | ||
| 885 | |||
| 886 | /** | ||
| 887 | * tipc_port_list_add - add a port to a port list, ensuring no duplicates | ||
| 888 | */ | ||
| 889 | |||
| 890 | void tipc_port_list_add(struct port_list *pl_ptr, u32 port) | ||
| 891 | { | ||
| 892 | struct port_list *item = pl_ptr; | ||
| 893 | int i; | ||
| 894 | int item_sz = PLSIZE; | ||
| 895 | int cnt = pl_ptr->count; | ||
| 896 | |||
| 897 | for (; ; cnt -= item_sz, item = item->next) { | ||
| 898 | if (cnt < PLSIZE) | ||
| 899 | item_sz = cnt; | ||
| 900 | for (i = 0; i < item_sz; i++) | ||
| 901 | if (item->ports[i] == port) | ||
| 902 | return; | ||
| 903 | if (i < PLSIZE) { | ||
| 904 | item->ports[i] = port; | ||
| 905 | pl_ptr->count++; | ||
| 906 | return; | ||
| 907 | } | ||
| 908 | if (!item->next) { | ||
| 909 | item->next = kmalloc(sizeof(*item), GFP_ATOMIC); | ||
| 910 | if (!item->next) { | ||
| 911 | warn("Incomplete multicast delivery, no memory\n"); | ||
| 912 | return; | ||
| 913 | } | ||
| 914 | item->next->next = NULL; | ||
| 915 | } | ||
| 916 | } | ||
| 917 | } | ||
| 918 | |||
| 919 | /** | ||
| 920 | * tipc_port_list_free - free dynamically created entries in port_list chain | ||
| 921 | * | ||
| 922 | */ | ||
| 923 | |||
| 924 | void tipc_port_list_free(struct port_list *pl_ptr) | ||
| 925 | { | ||
| 926 | struct port_list *item; | ||
| 927 | struct port_list *next; | ||
| 928 | |||
| 929 | for (item = pl_ptr->next; item; item = next) { | ||
| 930 | next = item->next; | ||
| 931 | kfree(item); | ||
| 932 | } | ||
| 933 | } | ||
| 934 | |||
