Lines Matching +full:sub +full:- +full:group

4  * Copyright (c) 2000-2006, 2014-2018, Ericsson AB
5 * Copyright (c) 2004-2008, 2010-2014, Wind River Systems
6 * Copyright (c) 2020-2021, Red Hat Inc
49 #include "group.h"
52 * struct service_range - container for all bindings of a service range
60 * Used by round-robin lookup algorithm
72 * struct tipc_service - container for all published instances of a service type
91 #define service_range_upper(sr) ((sr)->upper)
100 ((sr)->lower <= (end) && (sr)->upper >= (start)) in RB_DECLARE_CALLBACKS_MAX()
103 * service_range_foreach_match - iterate over tipc service rbtree for each in RB_DECLARE_CALLBACKS_MAX()
111 for (sr = service_range_match_first((sc)->ranges.rb_node, \ in RB_DECLARE_CALLBACKS_MAX()
115 sr = service_range_match_next(&(sr)->tree_node, \
120 * service_range_match_first - find first service range matching a range
135 if (!n || service_range_entry(n)->max < start)
139 l = n->rb_left;
140 if (l && service_range_entry(l)->max >= start) {
157 r = n->rb_right;
158 if (sr->lower <= end &&
159 r && service_range_entry(r)->max >= start) {
170 * service_range_match_next - find next service range matching a range
185 r = n->rb_right; in service_range_match_next()
186 if (r && service_range_entry(r)->max >= start) in service_range_match_next()
189 * successor (- an ancestor) of this node cannot in service_range_match_next()
195 * ancestor of this node which is parent of a left-hand child. in service_range_match_next()
197 while ((p = rb_parent(n)) && n == p->rb_right) in service_range_match_next()
208 if (sr->lower <= end) { in service_range_match_next()
220 return x & (TIPC_NAMETBL_SIZE - 1); in hash()
224 * tipc_publ_create - create a publication structure
238 p->sr = ua->sr; in tipc_publ_create()
239 p->sk = *sk; in tipc_publ_create()
240 p->scope = ua->scope; in tipc_publ_create()
241 p->key = key; in tipc_publ_create()
242 INIT_LIST_HEAD(&p->binding_sock); in tipc_publ_create()
243 INIT_LIST_HEAD(&p->binding_node); in tipc_publ_create()
244 INIT_LIST_HEAD(&p->local_publ); in tipc_publ_create()
245 INIT_LIST_HEAD(&p->all_publ); in tipc_publ_create()
246 INIT_LIST_HEAD(&p->list); in tipc_publ_create()
251 * tipc_service_create - create a service structure for the specified 'type'
270 spin_lock_init(&service->lock); in tipc_service_create()
271 service->type = ua->sr.type; in tipc_service_create()
272 service->ranges = RB_ROOT; in tipc_service_create()
273 INIT_HLIST_NODE(&service->service_list); in tipc_service_create()
274 INIT_LIST_HEAD(&service->subscriptions); in tipc_service_create()
275 hd = &nt->services[hash(ua->sr.type)]; in tipc_service_create()
276 hlist_add_head_rcu(&service->service_list, hd); in tipc_service_create()
280 /* tipc_service_find_range - find service range matching publication parameters
287 service_range_foreach_match(sr, sc, ua->sr.lower, ua->sr.upper) { in tipc_service_find_range()
289 if (sr->lower == ua->sr.lower && sr->upper == ua->sr.upper) in tipc_service_find_range()
301 u32 lower = p->sr.lower; in tipc_service_create_range()
302 u32 upper = p->sr.upper; in tipc_service_create_range()
304 n = &sc->ranges.rb_node; in tipc_service_create_range()
308 if (lower == sr->lower && upper == sr->upper) in tipc_service_create_range()
310 if (sr->max < upper) in tipc_service_create_range()
311 sr->max = upper; in tipc_service_create_range()
312 if (lower <= sr->lower) in tipc_service_create_range()
313 n = &parent->rb_left; in tipc_service_create_range()
315 n = &parent->rb_right; in tipc_service_create_range()
320 sr->lower = lower; in tipc_service_create_range()
321 sr->upper = upper; in tipc_service_create_range()
322 sr->max = upper; in tipc_service_create_range()
323 INIT_LIST_HEAD(&sr->local_publ); in tipc_service_create_range()
324 INIT_LIST_HEAD(&sr->all_publ); in tipc_service_create_range()
325 rb_link_node(&sr->tree_node, parent, n); in tipc_service_create_range()
326 rb_insert_augmented(&sr->tree_node, &sc->ranges, &sr_callbacks); in tipc_service_create_range()
334 struct tipc_subscription *sub, *tmp; in tipc_service_insert_publ() local
337 u32 node = p->sk.node; in tipc_service_insert_publ()
340 u32 key = p->key; in tipc_service_insert_publ()
342 spin_lock_bh(&sc->lock); in tipc_service_insert_publ()
347 first = list_empty(&sr->all_publ); in tipc_service_insert_publ()
350 list_for_each_entry(_p, &sr->all_publ, all_publ) { in tipc_service_insert_publ()
351 if (_p->key == key && (!_p->sk.node || _p->sk.node == node)) { in tipc_service_insert_publ()
353 p->sr.type, p->sr.lower, p->sr.upper, in tipc_service_insert_publ()
354 node, p->sk.ref, key); in tipc_service_insert_publ()
359 if (in_own_node(net, p->sk.node)) in tipc_service_insert_publ()
360 list_add(&p->local_publ, &sr->local_publ); in tipc_service_insert_publ()
361 list_add(&p->all_publ, &sr->all_publ); in tipc_service_insert_publ()
362 p->id = sc->publ_cnt++; in tipc_service_insert_publ()
365 list_for_each_entry_safe(sub, tmp, &sc->subscriptions, service_list) { in tipc_service_insert_publ()
366 tipc_sub_report_overlap(sub, p, TIPC_PUBLISHED, first); in tipc_service_insert_publ()
372 p->sr.type, p->sr.lower, p->sr.upper); in tipc_service_insert_publ()
373 spin_unlock_bh(&sc->lock); in tipc_service_insert_publ()
378 * tipc_service_remove_publ - remove a publication from a service
388 u32 node = sk->node; in tipc_service_remove_publ()
390 list_for_each_entry(p, &r->all_publ, all_publ) { in tipc_service_remove_publ()
391 if (p->key != key || (node && node != p->sk.node)) in tipc_service_remove_publ()
393 list_del(&p->all_publ); in tipc_service_remove_publ()
394 list_del(&p->local_publ); in tipc_service_remove_publ()
403 #define publication_after(pa, pb) time_after32((pa)->id, (pb)->id)
415 * tipc_service_subscribe - attach a subscription, and optionally
418 * @service: the tipc_service to attach the @sub to
419 * @sub: the subscription to attach
422 struct tipc_subscription *sub) in tipc_service_subscribe() argument
429 filter = sub->s.filter; in tipc_service_subscribe()
430 lower = sub->s.seq.lower; in tipc_service_subscribe()
431 upper = sub->s.seq.upper; in tipc_service_subscribe()
433 tipc_sub_get(sub); in tipc_service_subscribe()
434 list_add(&sub->service_list, &service->subscriptions); in tipc_service_subscribe()
442 list_for_each_entry(p, &sr->all_publ, all_publ) { in tipc_service_subscribe()
444 list_add_tail(&p->list, &publ_list); in tipc_service_subscribe()
450 list_add_tail(&first->list, &publ_list); in tipc_service_subscribe()
456 tipc_sub_report_overlap(sub, p, TIPC_PUBLISHED, true); in tipc_service_subscribe()
457 list_del_init(&p->list); in tipc_service_subscribe()
468 service_head = &nt->services[hash(ua->sr.type)]; in tipc_service_find()
470 if (service->type == ua->sr.type) in tipc_service_find()
502 struct tipc_subscription *sub, *tmp; in tipc_nametbl_remove_publ() local
512 spin_lock_bh(&sc->lock); in tipc_nametbl_remove_publ()
521 last = list_empty(&sr->all_publ); in tipc_nametbl_remove_publ()
522 list_for_each_entry_safe(sub, tmp, &sc->subscriptions, service_list) { in tipc_nametbl_remove_publ()
523 tipc_sub_report_overlap(sub, p, TIPC_WITHDRAWN, last); in tipc_nametbl_remove_publ()
527 if (list_empty(&sr->all_publ)) { in tipc_nametbl_remove_publ()
528 rb_erase_augmented(&sr->tree_node, &sc->ranges, &sr_callbacks); in tipc_nametbl_remove_publ()
533 if (RB_EMPTY_ROOT(&sc->ranges) && list_empty(&sc->subscriptions)) { in tipc_nametbl_remove_publ()
534 hlist_del_init_rcu(&sc->service_list); in tipc_nametbl_remove_publ()
538 spin_unlock_bh(&sc->lock); in tipc_nametbl_remove_publ()
542 ua->sr.type, ua->sr.lower, ua->sr.upper, in tipc_nametbl_remove_publ()
543 sk->node, sk->ref, key); in tipc_nametbl_remove_publ()
549 * tipc_nametbl_lookup_anycast - perform service instance to socket translation
554 * On entry, a non-zero 'sk->node' indicates the node where we want lookup to be
559 * - If lookup is deferred to another node, leave 'sk->node' unchanged and
561 * - If lookup is successful, set the 'sk->node' and 'sk->ref' (== portid) which
563 * - If lookup fails, return 'false'
566 * 'closest-first' lookup algorithm must be maintained, i.e., if sk.node is 0
574 bool legacy = tn->legacy_addr_format; in tipc_nametbl_lookup_anycast()
576 u32 inst = ua->sa.instance; in tipc_nametbl_lookup_anycast()
583 if (!tipc_in_scope(legacy, sk->node, self)) in tipc_nametbl_lookup_anycast()
591 spin_lock_bh(&sc->lock); in tipc_nametbl_lookup_anycast()
593 /* Select lookup algo: local, closest-first or round-robin */ in tipc_nametbl_lookup_anycast()
594 if (sk->node == self) { in tipc_nametbl_lookup_anycast()
595 l = &r->local_publ; in tipc_nametbl_lookup_anycast()
599 list_move_tail(&p->local_publ, &r->local_publ); in tipc_nametbl_lookup_anycast()
600 } else if (legacy && !sk->node && !list_empty(&r->local_publ)) { in tipc_nametbl_lookup_anycast()
601 l = &r->local_publ; in tipc_nametbl_lookup_anycast()
603 list_move_tail(&p->local_publ, &r->local_publ); in tipc_nametbl_lookup_anycast()
605 l = &r->all_publ; in tipc_nametbl_lookup_anycast()
607 list_move_tail(&p->all_publ, &r->all_publ); in tipc_nametbl_lookup_anycast()
609 *sk = p->sk; in tipc_nametbl_lookup_anycast()
612 * "true" round-robin will be performed as needed. in tipc_nametbl_lookup_anycast()
616 spin_unlock_bh(&sc->lock); in tipc_nametbl_lookup_anycast()
623 /* tipc_nametbl_lookup_group(): lookup destinaton(s) in a communication group
624 * Returns a list of one (== group anycast) or more (== group multicast)
633 u32 inst = ua->sa.instance; in tipc_nametbl_lookup_group()
644 spin_lock_bh(&sc->lock); in tipc_nametbl_lookup_group()
647 sr = service_range_match_first(sc->ranges.rb_node, inst, inst); in tipc_nametbl_lookup_group()
651 list_for_each_entry(p, &sr->all_publ, all_publ) { in tipc_nametbl_lookup_group()
652 if (p->scope != ua->scope) in tipc_nametbl_lookup_group()
654 if (p->sk.ref == exclude && p->sk.node == self) in tipc_nametbl_lookup_group()
656 tipc_dest_push(dsts, p->sk.node, p->sk.ref); in tipc_nametbl_lookup_group()
660 list_move_tail(&p->all_publ, &sr->all_publ); in tipc_nametbl_lookup_group()
664 spin_unlock_bh(&sc->lock); in tipc_nametbl_lookup_group()
681 u8 scope = ua->scope; in tipc_nametbl_lookup_mcast_sockets()
688 spin_lock_bh(&sc->lock); in tipc_nametbl_lookup_mcast_sockets()
689 service_range_foreach_match(sr, sc, ua->sr.lower, ua->sr.upper) { in tipc_nametbl_lookup_mcast_sockets()
690 list_for_each_entry(p, &sr->local_publ, local_publ) { in tipc_nametbl_lookup_mcast_sockets()
691 if (scope == p->scope || scope == TIPC_ANY_SCOPE) in tipc_nametbl_lookup_mcast_sockets()
692 tipc_dest_push(dports, 0, p->sk.ref); in tipc_nametbl_lookup_mcast_sockets()
695 spin_unlock_bh(&sc->lock); in tipc_nametbl_lookup_mcast_sockets()
717 spin_lock_bh(&sc->lock); in tipc_nametbl_lookup_mcast_nodes()
718 service_range_foreach_match(sr, sc, ua->sr.lower, ua->sr.upper) { in tipc_nametbl_lookup_mcast_nodes()
719 list_for_each_entry(p, &sr->all_publ, all_publ) { in tipc_nametbl_lookup_mcast_nodes()
720 tipc_nlist_add(nodes, p->sk.node); in tipc_nametbl_lookup_mcast_nodes()
723 spin_unlock_bh(&sc->lock); in tipc_nametbl_lookup_mcast_nodes()
728 /* tipc_nametbl_build_group - build list of communication group members
743 spin_lock_bh(&sc->lock); in tipc_nametbl_build_group()
744 for (n = rb_first(&sc->ranges); n; n = rb_next(n)) { in tipc_nametbl_build_group()
746 list_for_each_entry(p, &sr->all_publ, all_publ) { in tipc_nametbl_build_group()
747 if (p->scope != ua->scope) in tipc_nametbl_build_group()
749 tipc_group_add_member(grp, p->sk.node, p->sk.ref, in tipc_nametbl_build_group()
750 p->sr.lower); in tipc_nametbl_build_group()
753 spin_unlock_bh(&sc->lock); in tipc_nametbl_build_group()
758 /* tipc_nametbl_publish - add service binding to name table
769 spin_lock_bh(&tn->nametbl_lock); in tipc_nametbl_publish()
771 if (nt->local_publ_count >= TIPC_MAX_PUBL) { in tipc_nametbl_publish()
778 nt->local_publ_count++; in tipc_nametbl_publish()
781 rc_dests = nt->rc_dests; in tipc_nametbl_publish()
783 spin_unlock_bh(&tn->nametbl_lock); in tipc_nametbl_publish()
792 * tipc_nametbl_withdraw - withdraw a service binding
807 spin_lock_bh(&tn->nametbl_lock); in tipc_nametbl_withdraw()
811 nt->local_publ_count--; in tipc_nametbl_withdraw()
813 list_del_init(&p->binding_sock); in tipc_nametbl_withdraw()
816 rc_dests = nt->rc_dests; in tipc_nametbl_withdraw()
817 spin_unlock_bh(&tn->nametbl_lock); in tipc_nametbl_withdraw()
824 * tipc_nametbl_subscribe - add a subscription object to the name table
825 * @sub: subscription to add
827 bool tipc_nametbl_subscribe(struct tipc_subscription *sub) in tipc_nametbl_subscribe() argument
829 struct tipc_net *tn = tipc_net(sub->net); in tipc_nametbl_subscribe()
830 u32 type = sub->s.seq.type; in tipc_nametbl_subscribe()
836 sub->s.seq.lower, sub->s.seq.upper); in tipc_nametbl_subscribe()
837 spin_lock_bh(&tn->nametbl_lock); in tipc_nametbl_subscribe()
838 sc = tipc_service_find(sub->net, &ua); in tipc_nametbl_subscribe()
840 sc = tipc_service_create(sub->net, &ua); in tipc_nametbl_subscribe()
842 spin_lock_bh(&sc->lock); in tipc_nametbl_subscribe()
843 tipc_service_subscribe(sc, sub); in tipc_nametbl_subscribe()
844 spin_unlock_bh(&sc->lock); in tipc_nametbl_subscribe()
847 type, sub->s.seq.lower, sub->s.seq.upper); in tipc_nametbl_subscribe()
850 spin_unlock_bh(&tn->nametbl_lock); in tipc_nametbl_subscribe()
855 * tipc_nametbl_unsubscribe - remove a subscription object from name table
856 * @sub: subscription to remove
858 void tipc_nametbl_unsubscribe(struct tipc_subscription *sub) in tipc_nametbl_unsubscribe() argument
860 struct tipc_net *tn = tipc_net(sub->net); in tipc_nametbl_unsubscribe()
865 sub->s.seq.type, sub->s.seq.lower, sub->s.seq.upper); in tipc_nametbl_unsubscribe()
866 spin_lock_bh(&tn->nametbl_lock); in tipc_nametbl_unsubscribe()
867 sc = tipc_service_find(sub->net, &ua); in tipc_nametbl_unsubscribe()
871 spin_lock_bh(&sc->lock); in tipc_nametbl_unsubscribe()
872 list_del_init(&sub->service_list); in tipc_nametbl_unsubscribe()
873 tipc_sub_put(sub); in tipc_nametbl_unsubscribe()
876 if (RB_EMPTY_ROOT(&sc->ranges) && list_empty(&sc->subscriptions)) { in tipc_nametbl_unsubscribe()
877 hlist_del_init_rcu(&sc->service_list); in tipc_nametbl_unsubscribe()
880 spin_unlock_bh(&sc->lock); in tipc_nametbl_unsubscribe()
882 spin_unlock_bh(&tn->nametbl_lock); in tipc_nametbl_unsubscribe()
893 return -ENOMEM; in tipc_nametbl_init()
896 INIT_HLIST_HEAD(&nt->services[i]); in tipc_nametbl_init()
898 INIT_LIST_HEAD(&nt->node_scope); in tipc_nametbl_init()
899 INIT_LIST_HEAD(&nt->cluster_scope); in tipc_nametbl_init()
900 rwlock_init(&nt->cluster_scope_lock); in tipc_nametbl_init()
901 tn->nametbl = nt; in tipc_nametbl_init()
902 spin_lock_init(&tn->nametbl_lock); in tipc_nametbl_init()
907 * tipc_service_delete - purge all publications for a service and delete it
916 spin_lock_bh(&sc->lock); in tipc_service_delete()
917 rbtree_postorder_for_each_entry_safe(sr, tmpr, &sc->ranges, tree_node) { in tipc_service_delete()
918 list_for_each_entry_safe(p, tmp, &sr->all_publ, all_publ) { in tipc_service_delete()
919 tipc_service_remove_publ(sr, &p->sk, p->key); in tipc_service_delete()
922 rb_erase_augmented(&sr->tree_node, &sc->ranges, &sr_callbacks); in tipc_service_delete()
925 hlist_del_init_rcu(&sc->service_list); in tipc_service_delete()
926 spin_unlock_bh(&sc->lock); in tipc_service_delete()
941 spin_lock_bh(&tn->nametbl_lock); in tipc_nametbl_stop()
943 if (hlist_empty(&nt->services[i])) in tipc_nametbl_stop()
945 service_head = &nt->services[i]; in tipc_nametbl_stop()
950 spin_unlock_bh(&tn->nametbl_lock); in tipc_nametbl_stop()
967 list_for_each_entry(p, &sr->all_publ, all_publ) in __tipc_nl_add_nametable_publ()
968 if (p->key == *last_key) in __tipc_nl_add_nametable_publ()
970 if (list_entry_is_head(p, &sr->all_publ, all_publ)) in __tipc_nl_add_nametable_publ()
971 return -EPIPE; in __tipc_nl_add_nametable_publ()
973 p = list_first_entry(&sr->all_publ, in __tipc_nl_add_nametable_publ()
978 list_for_each_entry_from(p, &sr->all_publ, all_publ) { in __tipc_nl_add_nametable_publ()
979 *last_key = p->key; in __tipc_nl_add_nametable_publ()
981 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, in __tipc_nl_add_nametable_publ()
985 return -EMSGSIZE; in __tipc_nl_add_nametable_publ()
987 attrs = nla_nest_start_noflag(msg->skb, TIPC_NLA_NAME_TABLE); in __tipc_nl_add_nametable_publ()
991 b = nla_nest_start_noflag(msg->skb, TIPC_NLA_NAME_TABLE_PUBL); in __tipc_nl_add_nametable_publ()
995 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_TYPE, service->type)) in __tipc_nl_add_nametable_publ()
997 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_LOWER, sr->lower)) in __tipc_nl_add_nametable_publ()
999 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_UPPER, sr->upper)) in __tipc_nl_add_nametable_publ()
1001 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_SCOPE, p->scope)) in __tipc_nl_add_nametable_publ()
1003 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_NODE, p->sk.node)) in __tipc_nl_add_nametable_publ()
1005 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_REF, p->sk.ref)) in __tipc_nl_add_nametable_publ()
1007 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_KEY, p->key)) in __tipc_nl_add_nametable_publ()
1010 nla_nest_end(msg->skb, b); in __tipc_nl_add_nametable_publ()
1011 nla_nest_end(msg->skb, attrs); in __tipc_nl_add_nametable_publ()
1012 genlmsg_end(msg->skb, hdr); in __tipc_nl_add_nametable_publ()
1019 nla_nest_cancel(msg->skb, b); in __tipc_nl_add_nametable_publ()
1021 nla_nest_cancel(msg->skb, attrs); in __tipc_nl_add_nametable_publ()
1023 genlmsg_cancel(msg->skb, hdr); in __tipc_nl_add_nametable_publ()
1025 return -EMSGSIZE; in __tipc_nl_add_nametable_publ()
1036 for (n = rb_first(&sc->ranges); n; n = rb_next(n)) { in __tipc_nl_service_range_list()
1038 if (sr->lower < *last_lower) in __tipc_nl_service_range_list()
1042 *last_lower = sr->lower; in __tipc_nl_service_range_list()
1066 head = &tn->nametbl->services[i]; in tipc_nl_service_list()
1074 return -EPIPE; in tipc_nl_service_list()
1083 spin_lock_bh(&service->lock); in tipc_nl_service_list()
1089 *last_type = service->type; in tipc_nl_service_list()
1090 spin_unlock_bh(&service->lock); in tipc_nl_service_list()
1093 spin_unlock_bh(&service->lock); in tipc_nl_service_list()
1102 struct net *net = sock_net(skb->sk); in tipc_nl_name_table_dump()
1103 u32 last_type = cb->args[0]; in tipc_nl_name_table_dump()
1104 u32 last_lower = cb->args[1]; in tipc_nl_name_table_dump()
1105 u32 last_key = cb->args[2]; in tipc_nl_name_table_dump()
1106 int done = cb->args[3]; in tipc_nl_name_table_dump()
1114 msg.portid = NETLINK_CB(cb->skb).portid; in tipc_nl_name_table_dump()
1115 msg.seq = cb->nlh->nlmsg_seq; in tipc_nl_name_table_dump()
1122 } else if (err != -EMSGSIZE) { in tipc_nl_name_table_dump()
1129 cb->prev_seq = 1; in tipc_nl_name_table_dump()
1133 cb->args[0] = last_type; in tipc_nl_name_table_dump()
1134 cb->args[1] = last_lower; in tipc_nl_name_table_dump()
1135 cb->args[2] = last_key; in tipc_nl_name_table_dump()
1136 cb->args[3] = done; in tipc_nl_name_table_dump()
1138 return skb->len; in tipc_nl_name_table_dump()
1146 if (dst->node == node && dst->port == port) in tipc_dest_find()
1162 dst->node = node; in tipc_dest_push()
1163 dst->port = port; in tipc_dest_push()
1164 list_add(&dst->list, l); in tipc_dest_push()
1176 *port = dst->port; in tipc_dest_pop()
1178 *node = dst->node; in tipc_dest_pop()
1179 list_del(&dst->list); in tipc_dest_pop()
1191 list_del(&dst->list); in tipc_dest_del()
1201 list_del(&dst->list); in tipc_dest_list_purge()