aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/group.c100
-rw-r--r--net/tipc/group.h4
-rw-r--r--net/tipc/name_table.c2
-rw-r--r--net/tipc/socket.c4
4 files changed, 68 insertions, 42 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}
diff --git a/net/tipc/group.h b/net/tipc/group.h
index 5ffffd0121a2..dee79477d499 100644
--- a/net/tipc/group.h
+++ b/net/tipc/group.h
@@ -44,8 +44,10 @@ struct tipc_msg;
44 44
45struct tipc_group *tipc_group_create(struct net *net, u32 portid, 45struct tipc_group *tipc_group_create(struct net *net, u32 portid,
46 struct tipc_group_req *mreq); 46 struct tipc_group_req *mreq);
47void tipc_group_join(struct net *net, struct tipc_group *grp, int *sk_rcv_buf);
47void tipc_group_delete(struct net *net, struct tipc_group *grp); 48void tipc_group_delete(struct net *net, struct tipc_group *grp);
48void tipc_group_add_member(struct tipc_group *grp, u32 node, u32 port); 49void tipc_group_add_member(struct tipc_group *grp, u32 node,
50 u32 port, u32 instance);
49struct tipc_nlist *tipc_group_dests(struct tipc_group *grp); 51struct tipc_nlist *tipc_group_dests(struct tipc_group *grp);
50void tipc_group_self(struct tipc_group *grp, struct tipc_name_seq *seq, 52void tipc_group_self(struct tipc_group *grp, struct tipc_name_seq *seq,
51 int *scope); 53 int *scope);
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index b3829bcf63c7..e04ab72f313c 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -732,7 +732,7 @@ void tipc_nametbl_build_group(struct net *net, struct tipc_group *grp,
732 list_for_each_entry(p, &info->zone_list, zone_list) { 732 list_for_each_entry(p, &info->zone_list, zone_list) {
733 if (!tipc_in_scope(domain, p->node)) 733 if (!tipc_in_scope(domain, p->node))
734 continue; 734 continue;
735 tipc_group_add_member(grp, p->node, p->ref); 735 tipc_group_add_member(grp, p->node, p->ref, p->lower);
736 } 736 }
737 } 737 }
738 spin_unlock_bh(&seq->lock); 738 spin_unlock_bh(&seq->lock);
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 36744ebef74f..e3a02f1fcab5 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -2757,10 +2757,10 @@ static int tipc_sk_join(struct tipc_sock *tsk, struct tipc_group_req *mreq)
2757 tipc_group_delete(net, grp); 2757 tipc_group_delete(net, grp);
2758 tsk->group = NULL; 2758 tsk->group = NULL;
2759 } 2759 }
2760 2760 /* Eliminate any risk that a broadcast overtakes sent JOINs */
2761 /* Eliminate any risk that a broadcast overtakes the sent JOIN */
2762 tsk->mc_method.rcast = true; 2761 tsk->mc_method.rcast = true;
2763 tsk->mc_method.mandatory = true; 2762 tsk->mc_method.mandatory = true;
2763 tipc_group_join(net, grp, &tsk->sk.sk_rcvbuf);
2764 return rc; 2764 return rc;
2765} 2765}
2766 2766