• Home
  • Raw
  • Download

Lines Matching +full:sub +full:- +full:node

4  * Copyright (c) 2000-2006, 2014-2018, Ericsson AB
5 * Copyright (c) 2004-2008, 2010-2014, Wind River Systems
45 #include "node.h"
49 * struct service_range - container for all bindings of a service range
53 * @local_publ: list of identical publications made from this node
55 * @all_publ: all publications identical to this one, whatever node and scope
56 * Used by round-robin lookup algorithm
67 * struct tipc_service - container for all published instances of a service type
86 return x & (TIPC_NAMETBL_SIZE - 1); in hash()
90 * tipc_publ_create - create a publication structure
93 u32 scope, u32 node, u32 port, in tipc_publ_create() argument
101 publ->type = type; in tipc_publ_create()
102 publ->lower = lower; in tipc_publ_create()
103 publ->upper = upper; in tipc_publ_create()
104 publ->scope = scope; in tipc_publ_create()
105 publ->node = node; in tipc_publ_create()
106 publ->port = port; in tipc_publ_create()
107 publ->key = key; in tipc_publ_create()
108 INIT_LIST_HEAD(&publ->binding_sock); in tipc_publ_create()
109 INIT_LIST_HEAD(&publ->binding_node); in tipc_publ_create()
110 INIT_LIST_HEAD(&publ->local_publ); in tipc_publ_create()
111 INIT_LIST_HEAD(&publ->all_publ); in tipc_publ_create()
116 * tipc_service_create - create a service structure for the specified 'type'
129 spin_lock_init(&service->lock); in tipc_service_create()
130 service->type = type; in tipc_service_create()
131 service->ranges = RB_ROOT; in tipc_service_create()
132 INIT_HLIST_NODE(&service->service_list); in tipc_service_create()
133 INIT_LIST_HEAD(&service->subscriptions); in tipc_service_create()
134 hlist_add_head_rcu(&service->service_list, hd); in tipc_service_create()
139 * tipc_service_first_range - find first service range in tree matching instance
141 * Very time-critical, so binary search through range rb tree
146 struct rb_node *n = sc->ranges.rb_node; in tipc_service_first_range()
151 if (sr->lower > instance) in tipc_service_first_range()
152 n = n->rb_left; in tipc_service_first_range()
153 else if (sr->upper < instance) in tipc_service_first_range()
154 n = n->rb_right; in tipc_service_first_range()
161 /* tipc_service_find_range - find service range matching publication parameters
166 struct rb_node *n = sc->ranges.rb_node; in tipc_service_find_range()
174 for (n = &sr->tree_node; n; n = rb_next(n)) { in tipc_service_find_range()
176 if (sr->upper == upper) in tipc_service_find_range()
179 if (!n || sr->lower != lower || sr->upper != upper) in tipc_service_find_range()
191 n = &sc->ranges.rb_node; in tipc_service_create_range()
196 if (lower < tmp->lower) in tipc_service_create_range()
197 n = &(*n)->rb_left; in tipc_service_create_range()
198 else if (lower > tmp->lower) in tipc_service_create_range()
199 n = &(*n)->rb_right; in tipc_service_create_range()
200 else if (upper < tmp->upper) in tipc_service_create_range()
201 n = &(*n)->rb_left; in tipc_service_create_range()
202 else if (upper > tmp->upper) in tipc_service_create_range()
203 n = &(*n)->rb_right; in tipc_service_create_range()
210 sr->lower = lower; in tipc_service_create_range()
211 sr->upper = upper; in tipc_service_create_range()
212 INIT_LIST_HEAD(&sr->local_publ); in tipc_service_create_range()
213 INIT_LIST_HEAD(&sr->all_publ); in tipc_service_create_range()
214 rb_link_node(&sr->tree_node, parent, n); in tipc_service_create_range()
215 rb_insert_color(&sr->tree_node, &sc->ranges); in tipc_service_create_range()
223 u32 node, u32 port, in tipc_service_insert_publ() argument
226 struct tipc_subscription *sub, *tmp; in tipc_service_insert_publ() local
235 first = list_empty(&sr->all_publ); in tipc_service_insert_publ()
238 list_for_each_entry(p, &sr->all_publ, all_publ) { in tipc_service_insert_publ()
239 if (p->key == key && (!p->node || p->node == node)) in tipc_service_insert_publ()
244 p = tipc_publ_create(type, lower, upper, scope, node, port, key); in tipc_service_insert_publ()
247 if (in_own_node(net, node)) in tipc_service_insert_publ()
248 list_add(&p->local_publ, &sr->local_publ); in tipc_service_insert_publ()
249 list_add(&p->all_publ, &sr->all_publ); in tipc_service_insert_publ()
252 list_for_each_entry_safe(sub, tmp, &sc->subscriptions, service_list) { in tipc_service_insert_publ()
253 tipc_sub_report_overlap(sub, p->lower, p->upper, TIPC_PUBLISHED, in tipc_service_insert_publ()
254 p->port, p->node, p->scope, first); in tipc_service_insert_publ()
263 * tipc_service_remove_publ - remove a publication from a service
266 u32 node, u32 key) in tipc_service_remove_publ() argument
270 list_for_each_entry(p, &sr->all_publ, all_publ) { in tipc_service_remove_publ()
271 if (p->key != key || (node && node != p->node)) in tipc_service_remove_publ()
273 list_del(&p->all_publ); in tipc_service_remove_publ()
274 list_del(&p->local_publ); in tipc_service_remove_publ()
281 * tipc_service_subscribe - attach a subscription, and optionally
286 struct tipc_subscription *sub) in tipc_service_subscribe() argument
288 struct tipc_subscr *sb = &sub->evt.s; in tipc_service_subscribe()
299 tipc_sub_get(sub); in tipc_service_subscribe()
300 list_add(&sub->service_list, &service->subscriptions); in tipc_service_subscribe()
305 for (n = rb_first(&service->ranges); n; n = rb_next(n)) { in tipc_service_subscribe()
307 if (sr->lower > ns.upper) in tipc_service_subscribe()
309 if (!tipc_sub_check_overlap(&ns, sr->lower, sr->upper)) in tipc_service_subscribe()
313 list_for_each_entry(p, &sr->all_publ, all_publ) { in tipc_service_subscribe()
314 tipc_sub_report_overlap(sub, sr->lower, sr->upper, in tipc_service_subscribe()
315 TIPC_PUBLISHED, p->port, in tipc_service_subscribe()
316 p->node, p->scope, first); in tipc_service_subscribe()
328 service_head = &nt->services[hash(type)]; in tipc_service_find()
330 if (service->type == type) in tipc_service_find()
338 u32 scope, u32 node, in tipc_nametbl_insert_publ() argument
352 sc = tipc_service_create(type, &nt->services[hash(type)]); in tipc_nametbl_insert_publ()
356 spin_lock_bh(&sc->lock); in tipc_nametbl_insert_publ()
358 scope, node, port, key); in tipc_nametbl_insert_publ()
359 spin_unlock_bh(&sc->lock); in tipc_nametbl_insert_publ()
365 u32 node, u32 key) in tipc_nametbl_remove_publ() argument
368 struct tipc_subscription *sub, *tmp; in tipc_nametbl_remove_publ() local
376 spin_lock_bh(&sc->lock); in tipc_nametbl_remove_publ()
380 p = tipc_service_remove_publ(sr, node, key); in tipc_nametbl_remove_publ()
385 last = list_empty(&sr->all_publ); in tipc_nametbl_remove_publ()
386 list_for_each_entry_safe(sub, tmp, &sc->subscriptions, service_list) { in tipc_nametbl_remove_publ()
387 tipc_sub_report_overlap(sub, lower, upper, TIPC_WITHDRAWN, in tipc_nametbl_remove_publ()
388 p->port, node, p->scope, last); in tipc_nametbl_remove_publ()
392 if (list_empty(&sr->all_publ)) { in tipc_nametbl_remove_publ()
393 rb_erase(&sr->tree_node, &sc->ranges); in tipc_nametbl_remove_publ()
398 if (RB_EMPTY_ROOT(&sc->ranges) && list_empty(&sc->subscriptions)) { in tipc_nametbl_remove_publ()
399 hlist_del_init_rcu(&sc->service_list); in tipc_nametbl_remove_publ()
403 spin_unlock_bh(&sc->lock); in tipc_nametbl_remove_publ()
408 * tipc_nametbl_translate - perform service instance to socket translation
413 * - if translation is deferred to another node, leave 'dnode' unchanged and
415 * - if translation is attempted and succeeds, set 'dnode' to the publishing
416 * node and return the published (non-zero) port number
417 * - if translation is attempted and fails, set 'dnode' to 0 and return 0
419 * Note that for legacy users (node configured with Z.C.N address format) the
420 * 'closest-first' lookup algorithm must be maintained, i.e., if dnode is 0
426 bool legacy = tn->legacy_addr_format; in tipc_nametbl_translate()
433 u32 node = 0; in tipc_nametbl_translate() local
443 spin_lock_bh(&sc->lock); in tipc_nametbl_translate()
448 /* Select lookup algorithm: local, closest-first or round-robin */ in tipc_nametbl_translate()
450 list = &sr->local_publ; in tipc_nametbl_translate()
454 list_move_tail(&p->local_publ, &sr->local_publ); in tipc_nametbl_translate()
455 } else if (legacy && !*dnode && !list_empty(&sr->local_publ)) { in tipc_nametbl_translate()
456 list = &sr->local_publ; in tipc_nametbl_translate()
458 list_move_tail(&p->local_publ, &sr->local_publ); in tipc_nametbl_translate()
460 list = &sr->all_publ; in tipc_nametbl_translate()
462 list_move_tail(&p->all_publ, &sr->all_publ); in tipc_nametbl_translate()
464 port = p->port; in tipc_nametbl_translate()
465 node = p->node; in tipc_nametbl_translate()
467 spin_unlock_bh(&sc->lock); in tipc_nametbl_translate()
470 *dnode = node; in tipc_nametbl_translate()
489 spin_lock_bh(&sc->lock); in tipc_nametbl_lookup()
495 list_for_each_entry(p, &sr->all_publ, all_publ) { in tipc_nametbl_lookup()
496 if (p->scope != scope) in tipc_nametbl_lookup()
498 if (p->port == exclude && p->node == self) in tipc_nametbl_lookup()
500 tipc_dest_push(dsts, p->node, p->port); in tipc_nametbl_lookup()
504 list_move_tail(&p->all_publ, &sr->all_publ); in tipc_nametbl_lookup()
508 spin_unlock_bh(&sc->lock); in tipc_nametbl_lookup()
527 spin_lock_bh(&sc->lock); in tipc_nametbl_mc_lookup()
529 for (n = rb_first(&sc->ranges); n; n = rb_next(n)) { in tipc_nametbl_mc_lookup()
531 if (sr->upper < lower) in tipc_nametbl_mc_lookup()
533 if (sr->lower > upper) in tipc_nametbl_mc_lookup()
535 list_for_each_entry(p, &sr->local_publ, local_publ) { in tipc_nametbl_mc_lookup()
536 if (p->scope == scope || (!exact && p->scope < scope)) in tipc_nametbl_mc_lookup()
537 tipc_dest_push(dports, 0, p->port); in tipc_nametbl_mc_lookup()
540 spin_unlock_bh(&sc->lock); in tipc_nametbl_mc_lookup()
545 /* tipc_nametbl_lookup_dst_nodes - find broadcast destination nodes
546 * - Creates list of nodes that overlap the given multicast address
547 * - Determines if any node local destinations overlap
562 spin_lock_bh(&sc->lock); in tipc_nametbl_lookup_dst_nodes()
564 for (n = rb_first(&sc->ranges); n; n = rb_next(n)) { in tipc_nametbl_lookup_dst_nodes()
566 if (sr->upper < lower) in tipc_nametbl_lookup_dst_nodes()
568 if (sr->lower > upper) in tipc_nametbl_lookup_dst_nodes()
570 list_for_each_entry(p, &sr->all_publ, all_publ) { in tipc_nametbl_lookup_dst_nodes()
571 tipc_nlist_add(nodes, p->node); in tipc_nametbl_lookup_dst_nodes()
574 spin_unlock_bh(&sc->lock); in tipc_nametbl_lookup_dst_nodes()
579 /* tipc_nametbl_build_group - build list of communication group members
594 spin_lock_bh(&sc->lock); in tipc_nametbl_build_group()
595 for (n = rb_first(&sc->ranges); n; n = rb_next(n)) { in tipc_nametbl_build_group()
597 list_for_each_entry(p, &sr->all_publ, all_publ) { in tipc_nametbl_build_group()
598 if (p->scope != scope) in tipc_nametbl_build_group()
600 tipc_group_add_member(grp, p->node, p->port, p->lower); in tipc_nametbl_build_group()
603 spin_unlock_bh(&sc->lock); in tipc_nametbl_build_group()
608 /* tipc_nametbl_publish - add service binding to name table
619 spin_lock_bh(&tn->nametbl_lock); in tipc_nametbl_publish()
621 if (nt->local_publ_count >= TIPC_MAX_PUBL) { in tipc_nametbl_publish()
629 nt->local_publ_count++; in tipc_nametbl_publish()
633 spin_unlock_bh(&tn->nametbl_lock); in tipc_nametbl_publish()
641 * tipc_nametbl_withdraw - withdraw a service binding
652 spin_lock_bh(&tn->nametbl_lock); in tipc_nametbl_withdraw()
656 nt->local_publ_count--; in tipc_nametbl_withdraw()
658 list_del_init(&p->binding_sock); in tipc_nametbl_withdraw()
664 spin_unlock_bh(&tn->nametbl_lock); in tipc_nametbl_withdraw()
674 * tipc_nametbl_subscribe - add a subscription object to the name table
676 bool tipc_nametbl_subscribe(struct tipc_subscription *sub) in tipc_nametbl_subscribe() argument
678 struct name_table *nt = tipc_name_table(sub->net); in tipc_nametbl_subscribe()
679 struct tipc_net *tn = tipc_net(sub->net); in tipc_nametbl_subscribe()
680 struct tipc_subscr *s = &sub->evt.s; in tipc_nametbl_subscribe()
685 spin_lock_bh(&tn->nametbl_lock); in tipc_nametbl_subscribe()
686 sc = tipc_service_find(sub->net, type); in tipc_nametbl_subscribe()
688 sc = tipc_service_create(type, &nt->services[hash(type)]); in tipc_nametbl_subscribe()
690 spin_lock_bh(&sc->lock); in tipc_nametbl_subscribe()
691 tipc_service_subscribe(sc, sub); in tipc_nametbl_subscribe()
692 spin_unlock_bh(&sc->lock); in tipc_nametbl_subscribe()
699 spin_unlock_bh(&tn->nametbl_lock); in tipc_nametbl_subscribe()
704 * tipc_nametbl_unsubscribe - remove a subscription object from name table
706 void tipc_nametbl_unsubscribe(struct tipc_subscription *sub) in tipc_nametbl_unsubscribe() argument
708 struct tipc_net *tn = tipc_net(sub->net); in tipc_nametbl_unsubscribe()
709 struct tipc_subscr *s = &sub->evt.s; in tipc_nametbl_unsubscribe()
713 spin_lock_bh(&tn->nametbl_lock); in tipc_nametbl_unsubscribe()
714 sc = tipc_service_find(sub->net, type); in tipc_nametbl_unsubscribe()
718 spin_lock_bh(&sc->lock); in tipc_nametbl_unsubscribe()
719 list_del_init(&sub->service_list); in tipc_nametbl_unsubscribe()
720 tipc_sub_put(sub); in tipc_nametbl_unsubscribe()
723 if (RB_EMPTY_ROOT(&sc->ranges) && list_empty(&sc->subscriptions)) { in tipc_nametbl_unsubscribe()
724 hlist_del_init_rcu(&sc->service_list); in tipc_nametbl_unsubscribe()
727 spin_unlock_bh(&sc->lock); in tipc_nametbl_unsubscribe()
729 spin_unlock_bh(&tn->nametbl_lock); in tipc_nametbl_unsubscribe()
740 return -ENOMEM; in tipc_nametbl_init()
743 INIT_HLIST_HEAD(&nt->services[i]); in tipc_nametbl_init()
745 INIT_LIST_HEAD(&nt->node_scope); in tipc_nametbl_init()
746 INIT_LIST_HEAD(&nt->cluster_scope); in tipc_nametbl_init()
747 rwlock_init(&nt->cluster_scope_lock); in tipc_nametbl_init()
748 tn->nametbl = nt; in tipc_nametbl_init()
749 spin_lock_init(&tn->nametbl_lock); in tipc_nametbl_init()
754 * tipc_service_delete - purge all publications for a service and delete it
761 spin_lock_bh(&sc->lock); in tipc_service_delete()
762 rbtree_postorder_for_each_entry_safe(sr, tmpr, &sc->ranges, tree_node) { in tipc_service_delete()
763 list_for_each_entry_safe(p, tmp, &sr->all_publ, all_publ) { in tipc_service_delete()
764 tipc_service_remove_publ(sr, p->node, p->key); in tipc_service_delete()
767 rb_erase(&sr->tree_node, &sc->ranges); in tipc_service_delete()
770 hlist_del_init_rcu(&sc->service_list); in tipc_service_delete()
771 spin_unlock_bh(&sc->lock); in tipc_service_delete()
786 spin_lock_bh(&tn->nametbl_lock); in tipc_nametbl_stop()
788 if (hlist_empty(&nt->services[i])) in tipc_nametbl_stop()
790 service_head = &nt->services[i]; in tipc_nametbl_stop()
795 spin_unlock_bh(&tn->nametbl_lock); in tipc_nametbl_stop()
812 list_for_each_entry(p, &sr->all_publ, all_publ) in __tipc_nl_add_nametable_publ()
813 if (p->key == *last_key) in __tipc_nl_add_nametable_publ()
815 if (p->key != *last_key) in __tipc_nl_add_nametable_publ()
816 return -EPIPE; in __tipc_nl_add_nametable_publ()
818 p = list_first_entry(&sr->all_publ, in __tipc_nl_add_nametable_publ()
823 list_for_each_entry_from(p, &sr->all_publ, all_publ) { in __tipc_nl_add_nametable_publ()
824 *last_key = p->key; in __tipc_nl_add_nametable_publ()
826 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, in __tipc_nl_add_nametable_publ()
830 return -EMSGSIZE; in __tipc_nl_add_nametable_publ()
832 attrs = nla_nest_start(msg->skb, TIPC_NLA_NAME_TABLE); in __tipc_nl_add_nametable_publ()
836 b = nla_nest_start(msg->skb, TIPC_NLA_NAME_TABLE_PUBL); in __tipc_nl_add_nametable_publ()
840 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_TYPE, service->type)) in __tipc_nl_add_nametable_publ()
842 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_LOWER, sr->lower)) in __tipc_nl_add_nametable_publ()
844 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_UPPER, sr->upper)) in __tipc_nl_add_nametable_publ()
846 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_SCOPE, p->scope)) in __tipc_nl_add_nametable_publ()
848 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_NODE, p->node)) in __tipc_nl_add_nametable_publ()
850 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_REF, p->port)) in __tipc_nl_add_nametable_publ()
852 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_KEY, p->key)) in __tipc_nl_add_nametable_publ()
855 nla_nest_end(msg->skb, b); in __tipc_nl_add_nametable_publ()
856 nla_nest_end(msg->skb, attrs); in __tipc_nl_add_nametable_publ()
857 genlmsg_end(msg->skb, hdr); in __tipc_nl_add_nametable_publ()
864 nla_nest_cancel(msg->skb, b); in __tipc_nl_add_nametable_publ()
866 nla_nest_cancel(msg->skb, attrs); in __tipc_nl_add_nametable_publ()
868 genlmsg_cancel(msg->skb, hdr); in __tipc_nl_add_nametable_publ()
870 return -EMSGSIZE; in __tipc_nl_add_nametable_publ()
881 for (n = rb_first(&sc->ranges); n; n = rb_next(n)) { in __tipc_nl_service_range_list()
883 if (sr->lower < *last_lower) in __tipc_nl_service_range_list()
887 *last_lower = sr->lower; in __tipc_nl_service_range_list()
910 head = &tn->nametbl->services[i]; in tipc_nl_service_list()
916 return -EPIPE; in tipc_nl_service_list()
925 spin_lock_bh(&service->lock); in tipc_nl_service_list()
931 *last_type = service->type; in tipc_nl_service_list()
932 spin_unlock_bh(&service->lock); in tipc_nl_service_list()
935 spin_unlock_bh(&service->lock); in tipc_nl_service_list()
944 struct net *net = sock_net(skb->sk); in tipc_nl_name_table_dump()
945 u32 last_type = cb->args[0]; in tipc_nl_name_table_dump()
946 u32 last_lower = cb->args[1]; in tipc_nl_name_table_dump()
947 u32 last_key = cb->args[2]; in tipc_nl_name_table_dump()
948 int done = cb->args[3]; in tipc_nl_name_table_dump()
956 msg.portid = NETLINK_CB(cb->skb).portid; in tipc_nl_name_table_dump()
957 msg.seq = cb->nlh->nlmsg_seq; in tipc_nl_name_table_dump()
964 } else if (err != -EMSGSIZE) { in tipc_nl_name_table_dump()
971 cb->prev_seq = 1; in tipc_nl_name_table_dump()
975 cb->args[0] = last_type; in tipc_nl_name_table_dump()
976 cb->args[1] = last_lower; in tipc_nl_name_table_dump()
977 cb->args[2] = last_key; in tipc_nl_name_table_dump()
978 cb->args[3] = done; in tipc_nl_name_table_dump()
980 return skb->len; in tipc_nl_name_table_dump()
983 struct tipc_dest *tipc_dest_find(struct list_head *l, u32 node, u32 port) in tipc_dest_find() argument
988 if (dst->node == node && dst->port == port) in tipc_dest_find()
994 bool tipc_dest_push(struct list_head *l, u32 node, u32 port) in tipc_dest_push() argument
998 if (tipc_dest_find(l, node, port)) in tipc_dest_push()
1004 dst->node = node; in tipc_dest_push()
1005 dst->port = port; in tipc_dest_push()
1006 list_add(&dst->list, l); in tipc_dest_push()
1010 bool tipc_dest_pop(struct list_head *l, u32 *node, u32 *port) in tipc_dest_pop() argument
1018 *port = dst->port; in tipc_dest_pop()
1019 if (node) in tipc_dest_pop()
1020 *node = dst->node; in tipc_dest_pop()
1021 list_del(&dst->list); in tipc_dest_pop()
1026 bool tipc_dest_del(struct list_head *l, u32 node, u32 port) in tipc_dest_del() argument
1030 dst = tipc_dest_find(l, node, port); in tipc_dest_del()
1033 list_del(&dst->list); in tipc_dest_del()
1043 list_del(&dst->list); in tipc_dest_list_purge()