Skip to content

Commit 232d07b

Browse files
Jon Maloydavem330
authored andcommitted
tipc: improve groupcast scope handling
When a member joins a group, it also indicates a binding scope. This makes it possible to create both node local groups, invisible to other nodes, as well as cluster global groups, visible everywhere. In order to avoid that different members end up having permanently differing views of group size and memberhip, we must inhibit locally and globally bound members from joining the same group. We do this by using the binding scope as an additional separator between groups. I.e., a member must ignore all membership events from sockets using a different scope than itself, and all lookups for message destinations must require an exact match between the message's lookup scope and the potential target's binding scope. Apart from making it possible to create local groups using the same identity on different nodes, a side effect of this is that it now also becomes possible to create a cluster global group with the same identity across the same nodes, without interfering with the local groups. Acked-by: Ying Xue <[email protected]> Signed-off-by: Jon Maloy <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 8348500 commit 232d07b

File tree

9 files changed

+99
-75
lines changed

9 files changed

+99
-75
lines changed

include/uapi/linux/tipc.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,9 @@ static inline unsigned int tipc_node(__u32 addr)
117117
/*
118118
* Publication scopes when binding port names and port name sequences
119119
*/
120-
121-
#define TIPC_ZONE_SCOPE 1
122-
#define TIPC_CLUSTER_SCOPE 2
123-
#define TIPC_NODE_SCOPE 3
120+
#define TIPC_ZONE_SCOPE 1
121+
#define TIPC_CLUSTER_SCOPE 2
122+
#define TIPC_NODE_SCOPE 3
124123

125124
/*
126125
* Limiting values for messages

net/tipc/group.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ struct tipc_group {
8787
int subid;
8888
u32 type;
8989
u32 instance;
90-
u32 domain;
9190
u32 scope;
9291
u32 portid;
9392
u16 member_cnt;
@@ -158,6 +157,8 @@ int tipc_group_size(struct tipc_group *grp)
158157
struct tipc_group *tipc_group_create(struct net *net, u32 portid,
159158
struct tipc_group_req *mreq)
160159
{
160+
u32 filter = TIPC_SUB_PORTS | TIPC_SUB_NO_STATUS;
161+
bool global = mreq->scope != TIPC_NODE_SCOPE;
161162
struct tipc_group *grp;
162163
u32 type = mreq->type;
163164

@@ -171,15 +172,14 @@ struct tipc_group *tipc_group_create(struct net *net, u32 portid,
171172
grp->members = RB_ROOT;
172173
grp->net = net;
173174
grp->portid = portid;
174-
grp->domain = addr_domain(net, mreq->scope);
175175
grp->type = type;
176176
grp->instance = mreq->instance;
177177
grp->scope = mreq->scope;
178178
grp->loopback = mreq->flags & TIPC_GROUP_LOOPBACK;
179179
grp->events = mreq->flags & TIPC_GROUP_MEMBER_EVTS;
180-
if (tipc_topsrv_kern_subscr(net, portid, type,
181-
TIPC_SUB_PORTS | TIPC_SUB_NO_STATUS,
182-
0, ~0, &grp->subid))
180+
filter |= global ? TIPC_SUB_CLUSTER_SCOPE : TIPC_SUB_NODE_SCOPE;
181+
if (tipc_topsrv_kern_subscr(net, portid, type, 0, ~0,
182+
filter, &grp->subid))
183183
return grp;
184184
kfree(grp);
185185
return NULL;
@@ -732,6 +732,9 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup,
732732
if (!grp)
733733
return;
734734

735+
if (grp->scope == TIPC_NODE_SCOPE && node != tipc_own_addr(grp->net))
736+
return;
737+
735738
m = tipc_group_find_member(grp, node, port);
736739

737740
switch (msg_type(hdr)) {

net/tipc/name_table.c

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,8 @@ static struct publication *tipc_nameseq_insert_publ(struct net *net,
328328
list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) {
329329
tipc_subscrp_report_overlap(s, publ->lower, publ->upper,
330330
TIPC_PUBLISHED, publ->ref,
331-
publ->node, created_subseq);
331+
publ->node, publ->scope,
332+
created_subseq);
332333
}
333334
return publ;
334335
}
@@ -398,7 +399,8 @@ static struct publication *tipc_nameseq_remove_publ(struct net *net,
398399
list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) {
399400
tipc_subscrp_report_overlap(s, publ->lower, publ->upper,
400401
TIPC_WITHDRAWN, publ->ref,
401-
publ->node, removed_subseq);
402+
publ->node, publ->scope,
403+
removed_subseq);
402404
}
403405

404406
return publ;
@@ -435,6 +437,7 @@ static void tipc_nameseq_subscribe(struct name_seq *nseq,
435437
sseq->upper,
436438
TIPC_PUBLISHED,
437439
crs->ref, crs->node,
440+
crs->scope,
438441
must_report);
439442
must_report = 0;
440443
}
@@ -598,7 +601,7 @@ u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance,
598601
return ref;
599602
}
600603

601-
bool tipc_nametbl_lookup(struct net *net, u32 type, u32 instance, u32 domain,
604+
bool tipc_nametbl_lookup(struct net *net, u32 type, u32 instance, u32 scope,
602605
struct list_head *dsts, int *dstcnt, u32 exclude,
603606
bool all)
604607
{
@@ -608,9 +611,6 @@ bool tipc_nametbl_lookup(struct net *net, u32 type, u32 instance, u32 domain,
608611
struct name_seq *seq;
609612
struct sub_seq *sseq;
610613

611-
if (!tipc_in_scope(domain, self))
612-
return false;
613-
614614
*dstcnt = 0;
615615
rcu_read_lock();
616616
seq = nametbl_find_seq(net, type);
@@ -621,7 +621,7 @@ bool tipc_nametbl_lookup(struct net *net, u32 type, u32 instance, u32 domain,
621621
if (likely(sseq)) {
622622
info = sseq->info;
623623
list_for_each_entry(publ, &info->zone_list, zone_list) {
624-
if (!tipc_in_scope(domain, publ->node))
624+
if (publ->scope != scope)
625625
continue;
626626
if (publ->ref == exclude && publ->node == self)
627627
continue;
@@ -639,13 +639,14 @@ bool tipc_nametbl_lookup(struct net *net, u32 type, u32 instance, u32 domain,
639639
return !list_empty(dsts);
640640
}
641641

642-
int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper,
643-
u32 limit, struct list_head *dports)
642+
int tipc_nametbl_mc_lookup(struct net *net, u32 type, u32 lower, u32 upper,
643+
u32 scope, bool exact, struct list_head *dports)
644644
{
645-
struct name_seq *seq;
646-
struct sub_seq *sseq;
647645
struct sub_seq *sseq_stop;
648646
struct name_info *info;
647+
struct publication *p;
648+
struct name_seq *seq;
649+
struct sub_seq *sseq;
649650
int res = 0;
650651

651652
rcu_read_lock();
@@ -657,15 +658,12 @@ int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper,
657658
sseq = seq->sseqs + nameseq_locate_subseq(seq, lower);
658659
sseq_stop = seq->sseqs + seq->first_free;
659660
for (; sseq != sseq_stop; sseq++) {
660-
struct publication *publ;
661-
662661
if (sseq->lower > upper)
663662
break;
664-
665663
info = sseq->info;
666-
list_for_each_entry(publ, &info->node_list, node_list) {
667-
if (publ->scope <= limit)
668-
tipc_dest_push(dports, 0, publ->ref);
664+
list_for_each_entry(p, &info->node_list, node_list) {
665+
if (p->scope == scope || (!exact && p->scope < scope))
666+
tipc_dest_push(dports, 0, p->ref);
669667
}
670668

671669
if (info->cluster_list_size != info->node_list_size)
@@ -682,7 +680,7 @@ int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper,
682680
* - Determines if any node local ports overlap
683681
*/
684682
void tipc_nametbl_lookup_dst_nodes(struct net *net, u32 type, u32 lower,
685-
u32 upper, u32 domain,
683+
u32 upper, u32 scope,
686684
struct tipc_nlist *nodes)
687685
{
688686
struct sub_seq *sseq, *stop;
@@ -701,7 +699,7 @@ void tipc_nametbl_lookup_dst_nodes(struct net *net, u32 type, u32 lower,
701699
for (; sseq != stop && sseq->lower <= upper; sseq++) {
702700
info = sseq->info;
703701
list_for_each_entry(publ, &info->zone_list, zone_list) {
704-
if (tipc_in_scope(domain, publ->node))
702+
if (publ->scope == scope)
705703
tipc_nlist_add(nodes, publ->node);
706704
}
707705
}
@@ -713,7 +711,7 @@ void tipc_nametbl_lookup_dst_nodes(struct net *net, u32 type, u32 lower,
713711
/* tipc_nametbl_build_group - build list of communication group members
714712
*/
715713
void tipc_nametbl_build_group(struct net *net, struct tipc_group *grp,
716-
u32 type, u32 domain)
714+
u32 type, u32 scope)
717715
{
718716
struct sub_seq *sseq, *stop;
719717
struct name_info *info;
@@ -731,7 +729,7 @@ void tipc_nametbl_build_group(struct net *net, struct tipc_group *grp,
731729
for (; sseq != stop; sseq++) {
732730
info = sseq->info;
733731
list_for_each_entry(p, &info->zone_list, zone_list) {
734-
if (!tipc_in_scope(domain, p->node))
732+
if (p->scope != scope)
735733
continue;
736734
tipc_group_add_member(grp, p->node, p->ref, p->lower);
737735
}

net/tipc/name_table.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ struct name_table {
100100
int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb);
101101

102102
u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, u32 *node);
103-
int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper,
104-
u32 limit, struct list_head *dports);
103+
int tipc_nametbl_mc_lookup(struct net *net, u32 type, u32 lower, u32 upper,
104+
u32 scope, bool exact, struct list_head *dports);
105105
void tipc_nametbl_build_group(struct net *net, struct tipc_group *grp,
106106
u32 type, u32 domain);
107107
void tipc_nametbl_lookup_dst_nodes(struct net *net, u32 type, u32 lower,

net/tipc/server.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -489,8 +489,8 @@ void tipc_conn_terminate(struct tipc_server *s, int conid)
489489
}
490490
}
491491

492-
bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type,
493-
u32 filter, u32 lower, u32 upper, int *conid)
492+
bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower,
493+
u32 upper, u32 filter, int *conid)
494494
{
495495
struct tipc_subscriber *scbr;
496496
struct tipc_subscr sub;

net/tipc/server.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
#include <net/net_namespace.h>
4242

4343
#define TIPC_SERVER_NAME_LEN 32
44+
#define TIPC_SUB_CLUSTER_SCOPE 0x20
45+
#define TIPC_SUB_NODE_SCOPE 0x40
4446
#define TIPC_SUB_NO_STATUS 0x80
4547

4648
/**
@@ -84,8 +86,8 @@ struct tipc_server {
8486
int tipc_conn_sendmsg(struct tipc_server *s, int conid,
8587
struct sockaddr_tipc *addr, void *data, size_t len);
8688

87-
bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type,
88-
u32 filter, u32 lower, u32 upper, int *conid);
89+
bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower,
90+
u32 upper, u32 filter, int *conid);
8991
void tipc_topsrv_kern_unsubscr(struct net *net, int conid);
9092

9193
/**

0 commit comments

Comments
 (0)