aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/group.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/group.c')
-rw-r--r--net/tipc/group.c100
1 files changed, 62 insertions, 38 deletions
diff --git a/net/tipc/group.c b/net/tipc/group.c
index bdc54be9c07e..6ca07f0da60c 100644
--- a/net/tipc/group.c
+++ b/net/tipc/group.c
@@ -49,7 +49,6 @@
49#define ADV_ACTIVE (ADV_UNIT * 12) 49#define ADV_ACTIVE (ADV_UNIT * 12)
50 50
51enum mbr_state { 51enum mbr_state {
52 MBR_DISCOVERED,
53 MBR_JOINING, 52 MBR_JOINING,
54 MBR_PUBLISHED, 53 MBR_PUBLISHED,
55 MBR_JOINED, 54 MBR_JOINED,
@@ -141,7 +140,7 @@ static bool tipc_group_is_receiver(struct tipc_member *m)
141 140
142static bool tipc_group_is_sender(struct tipc_member *m) 141static bool tipc_group_is_sender(struct tipc_member *m)
143{ 142{
144 return m && m->state >= MBR_JOINED; 143 return m && m->state != MBR_JOINING && m->state != MBR_PUBLISHED;
145} 144}
146 145
147u32 tipc_group_exclude(struct tipc_group *grp) 146u32 tipc_group_exclude(struct tipc_group *grp)
@@ -184,6 +183,21 @@ struct tipc_group *tipc_group_create(struct net *net, u32 portid,
184 return NULL; 183 return NULL;
185} 184}
186 185
186void tipc_group_join(struct net *net, struct tipc_group *grp, int *sk_rcvbuf)
187{
188 struct rb_root *tree = &grp->members;
189 struct tipc_member *m, *tmp;
190 struct sk_buff_head xmitq;
191
192 skb_queue_head_init(&xmitq);
193 rbtree_postorder_for_each_entry_safe(m, tmp, tree, tree_node) {
194 tipc_group_proto_xmit(grp, m, GRP_JOIN_MSG, &xmitq);
195 tipc_group_update_member(m, 0);
196 }
197 tipc_node_distr_xmit(net, &xmitq);
198 *sk_rcvbuf = tipc_group_rcvbuf_limit(grp);
199}
200
187void tipc_group_delete(struct net *net, struct tipc_group *grp) 201void tipc_group_delete(struct net *net, struct tipc_group *grp)
188{ 202{
189 struct rb_root *tree = &grp->members; 203 struct rb_root *tree = &grp->members;
@@ -274,7 +288,7 @@ static void tipc_group_add_to_tree(struct tipc_group *grp,
274 288
275static struct tipc_member *tipc_group_create_member(struct tipc_group *grp, 289static struct tipc_member *tipc_group_create_member(struct tipc_group *grp,
276 u32 node, u32 port, 290 u32 node, u32 port,
277 int state) 291 u32 instance, int state)
278{ 292{
279 struct tipc_member *m; 293 struct tipc_member *m;
280 294
@@ -287,6 +301,7 @@ static struct tipc_member *tipc_group_create_member(struct tipc_group *grp,
287 m->group = grp; 301 m->group = grp;
288 m->node = node; 302 m->node = node;
289 m->port = port; 303 m->port = port;
304 m->instance = instance;
290 m->bc_acked = grp->bc_snd_nxt - 1; 305 m->bc_acked = grp->bc_snd_nxt - 1;
291 grp->member_cnt++; 306 grp->member_cnt++;
292 tipc_group_add_to_tree(grp, m); 307 tipc_group_add_to_tree(grp, m);
@@ -295,9 +310,10 @@ static struct tipc_member *tipc_group_create_member(struct tipc_group *grp,
295 return m; 310 return m;
296} 311}
297 312
298void tipc_group_add_member(struct tipc_group *grp, u32 node, u32 port) 313void tipc_group_add_member(struct tipc_group *grp, u32 node,
314 u32 port, u32 instance)
299{ 315{
300 tipc_group_create_member(grp, node, port, MBR_DISCOVERED); 316 tipc_group_create_member(grp, node, port, instance, MBR_PUBLISHED);
301} 317}
302 318
303static void tipc_group_delete_member(struct tipc_group *grp, 319static void tipc_group_delete_member(struct tipc_group *grp,
@@ -623,7 +639,6 @@ void tipc_group_update_rcv_win(struct tipc_group *grp, int blks, u32 node,
623 tipc_group_proto_xmit(grp, pm, GRP_ADV_MSG, xmitq); 639 tipc_group_proto_xmit(grp, pm, GRP_ADV_MSG, xmitq);
624 break; 640 break;
625 case MBR_RECLAIMING: 641 case MBR_RECLAIMING:
626 case MBR_DISCOVERED:
627 case MBR_JOINING: 642 case MBR_JOINING:
628 case MBR_LEAVING: 643 case MBR_LEAVING:
629 default: 644 default:
@@ -721,26 +736,26 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup,
721 case GRP_JOIN_MSG: 736 case GRP_JOIN_MSG:
722 if (!m) 737 if (!m)
723 m = tipc_group_create_member(grp, node, port, 738 m = tipc_group_create_member(grp, node, port,
724 MBR_JOINING); 739 0, MBR_JOINING);
725 if (!m) 740 if (!m)
726 return; 741 return;
727 m->bc_syncpt = msg_grp_bc_syncpt(hdr); 742 m->bc_syncpt = msg_grp_bc_syncpt(hdr);
728 m->bc_rcv_nxt = m->bc_syncpt; 743 m->bc_rcv_nxt = m->bc_syncpt;
729 m->window += msg_adv_win(hdr); 744 m->window += msg_adv_win(hdr);
730 745
731 /* Wait until PUBLISH event is received */ 746 /* Wait until PUBLISH event is received if necessary */
732 if (m->state == MBR_DISCOVERED) { 747 if (m->state != MBR_PUBLISHED)
733 m->state = MBR_JOINING; 748 return;
734 } else if (m->state == MBR_PUBLISHED) { 749
735 m->state = MBR_JOINED; 750 /* Member can be taken into service */
736 *usr_wakeup = true; 751 m->state = MBR_JOINED;
737 m->usr_pending = false; 752 *usr_wakeup = true;
738 tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); 753 m->usr_pending = false;
739 tipc_group_create_event(grp, m, TIPC_PUBLISHED,
740 m->bc_syncpt, inputq);
741 }
742 list_del_init(&m->small_win); 754 list_del_init(&m->small_win);
743 tipc_group_update_member(m, 0); 755 tipc_group_update_member(m, 0);
756 tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq);
757 tipc_group_create_event(grp, m, TIPC_PUBLISHED,
758 m->bc_syncpt, inputq);
744 return; 759 return;
745 case GRP_LEAVE_MSG: 760 case GRP_LEAVE_MSG:
746 if (!m) 761 if (!m)
@@ -844,30 +859,36 @@ void tipc_group_member_evt(struct tipc_group *grp,
844 859
845 m = tipc_group_find_member(grp, node, port); 860 m = tipc_group_find_member(grp, node, port);
846 861
847 if (event == TIPC_PUBLISHED) { 862 switch (event) {
848 if (!m) 863 case TIPC_PUBLISHED:
849 m = tipc_group_create_member(grp, node, port, 864 /* Send and wait for arrival of JOIN message if necessary */
850 MBR_DISCOVERED); 865 if (!m) {
851 if (!m) 866 m = tipc_group_create_member(grp, node, port, instance,
852 return; 867 MBR_PUBLISHED);
868 if (!m)
869 break;
870 tipc_group_update_member(m, 0);
871 tipc_group_proto_xmit(grp, m, GRP_JOIN_MSG, xmitq);
872 break;
873 }
853 874
854 m->instance = instance; 875 if (m->state != MBR_JOINING)
876 break;
855 877
856 /* Hold back event if JOIN message not yet received */ 878 /* Member can be taken into service */
857 if (m->state == MBR_DISCOVERED) { 879 m->instance = instance;
858 m->state = MBR_PUBLISHED; 880 m->state = MBR_JOINED;
859 } else { 881 *usr_wakeup = true;
860 tipc_group_create_event(grp, m, TIPC_PUBLISHED, 882 m->usr_pending = false;
861 m->bc_syncpt, inputq); 883 list_del_init(&m->small_win);
862 m->state = MBR_JOINED;
863 *usr_wakeup = true;
864 m->usr_pending = false;
865 }
866 tipc_group_proto_xmit(grp, m, GRP_JOIN_MSG, xmitq);
867 tipc_group_update_member(m, 0); 884 tipc_group_update_member(m, 0);
868 } else if (event == TIPC_WITHDRAWN) { 885 tipc_group_proto_xmit(grp, m, GRP_JOIN_MSG, xmitq);
886 tipc_group_create_event(grp, m, TIPC_PUBLISHED,
887 m->bc_syncpt, inputq);
888 break;
889 case TIPC_WITHDRAWN:
869 if (!m) 890 if (!m)
870 return; 891 break;
871 892
872 *usr_wakeup = true; 893 *usr_wakeup = true;
873 m->usr_pending = false; 894 m->usr_pending = false;
@@ -880,6 +901,9 @@ void tipc_group_member_evt(struct tipc_group *grp,
880 if (!tipc_node_is_up(net, node)) 901 if (!tipc_node_is_up(net, node))
881 tipc_group_create_event(grp, m, TIPC_WITHDRAWN, 902 tipc_group_create_event(grp, m, TIPC_WITHDRAWN,
882 m->bc_rcv_nxt, inputq); 903 m->bc_rcv_nxt, inputq);
904 break;
905 default:
906 break;
883 } 907 }
884 *sk_rcvbuf = tipc_group_rcvbuf_limit(grp); 908 *sk_rcvbuf = tipc_group_rcvbuf_limit(grp);
885} 909}