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 | |||