^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * net/tipc/name_table.c: TIPC name table code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2000-2006, 2014-2018, Ericsson AB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2004-2008, 2010-2014, Wind River Systems
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * modification, are permitted provided that the following conditions are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * 1. Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * notice, this list of conditions and the following disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * 2. Redistributions in binary form must reproduce the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * notice, this list of conditions and the following disclaimer in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * documentation and/or other materials provided with the distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * 3. Neither the names of the copyright holders nor the names of its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * contributors may be used to endorse or promote products derived from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * this software without specific prior written permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Alternatively, this software may be distributed under the terms of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * GNU General Public License ("GPL") version 2 as published by the Free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/list_sort.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/rbtree_augmented.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include "core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include "netlink.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include "name_table.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include "name_distr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include "subscr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include "bcast.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include "addr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include "node.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include "group.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * struct service_range - container for all bindings of a service range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * @lower: service range lower bound
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * @upper: service range upper bound
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * @tree_node: member of service range RB tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * @max: largest 'upper' in this node subtree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * @local_publ: list of identical publications made from this node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * Used by closest_first lookup and multicast lookup algorithm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * @all_publ: all publications identical to this one, whatever node and scope
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * Used by round-robin lookup algorithm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct service_range {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) u32 lower;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) u32 upper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct rb_node tree_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) u32 max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct list_head local_publ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct list_head all_publ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * struct tipc_service - container for all published instances of a service type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * @type: 32 bit 'type' value for service
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * @publ_cnt: increasing counter for publications in this service
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * @ranges: rb tree containing all service ranges for this service
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * @service_list: links to adjacent name ranges in hash chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * @subscriptions: list of subscriptions for this service type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * @lock: spinlock controlling access to pertaining service ranges/publications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * @rcu: RCU callback head used for deferred freeing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct tipc_service {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) u32 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) u32 publ_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct rb_root ranges;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct hlist_node service_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct list_head subscriptions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) spinlock_t lock; /* Covers service range list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct rcu_head rcu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define service_range_upper(sr) ((sr)->upper)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) RB_DECLARE_CALLBACKS_MAX(static, sr_callbacks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct service_range, tree_node, u32, max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) service_range_upper)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define service_range_entry(rbtree_node) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) (container_of(rbtree_node, struct service_range, tree_node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define service_range_overlap(sr, start, end) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ((sr)->lower <= (end) && (sr)->upper >= (start))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * service_range_foreach_match - iterate over tipc service rbtree for each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * range match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * @sr: the service range pointer as a loop cursor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * @sc: the pointer to tipc service which holds the service range rbtree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * @start, end: the range (end >= start) for matching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define service_range_foreach_match(sr, sc, start, end) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) for (sr = service_range_match_first((sc)->ranges.rb_node, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) start, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) end); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) sr; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) sr = service_range_match_next(&(sr)->tree_node, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) start, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) end))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * service_range_match_first - find first service range matching a range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * @n: the root node of service range rbtree for searching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * @start, end: the range (end >= start) for matching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * Return: the leftmost service range node in the rbtree that overlaps the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * specific range if any. Otherwise, returns NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static struct service_range *service_range_match_first(struct rb_node *n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) u32 start, u32 end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct service_range *sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct rb_node *l, *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /* Non overlaps in tree at all? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (!n || service_range_entry(n)->max < start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) while (n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) l = n->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (l && service_range_entry(l)->max >= start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* A leftmost overlap range node must be one in the left
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * subtree. If not, it has lower > end, then nodes on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * the right side cannot satisfy the condition either.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) n = l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* No one in the left subtree can match, return if this node is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * an overlap i.e. leftmost.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) sr = service_range_entry(n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (service_range_overlap(sr, start, end))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* Ok, try to lookup on the right side */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) r = n->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (sr->lower <= end &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) r && service_range_entry(r)->max >= start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) n = r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * service_range_match_next - find next service range matching a range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * @n: a node in service range rbtree from which the searching starts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * @start, end: the range (end >= start) for matching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * Return: the next service range node to the given node in the rbtree that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * overlaps the specific range if any. Otherwise, returns NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static struct service_range *service_range_match_next(struct rb_node *n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) u32 start, u32 end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct service_range *sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct rb_node *p, *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) while (n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) r = n->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (r && service_range_entry(r)->max >= start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* A next overlap range node must be one in the right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * subtree. If not, it has lower > end, then any next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * successor (- an ancestor) of this node cannot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * satisfy the condition either.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return service_range_match_first(r, start, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /* No one in the right subtree can match, go up to find an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * ancestor of this node which is parent of a left-hand child.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) while ((p = rb_parent(n)) && n == p->rb_right)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) n = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /* Return if this ancestor is an overlap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) sr = service_range_entry(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (service_range_overlap(sr, start, end))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /* Ok, try to lookup more from this ancestor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (sr->lower <= end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) n = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static int hash(int x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return x & (TIPC_NAMETBL_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * tipc_publ_create - create a publication structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static struct publication *tipc_publ_create(u32 type, u32 lower, u32 upper,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) u32 scope, u32 node, u32 port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) u32 key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct publication *publ = kzalloc(sizeof(*publ), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (!publ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) publ->type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) publ->lower = lower;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) publ->upper = upper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) publ->scope = scope;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) publ->node = node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) publ->port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) publ->key = key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) INIT_LIST_HEAD(&publ->binding_sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) INIT_LIST_HEAD(&publ->binding_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) INIT_LIST_HEAD(&publ->local_publ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) INIT_LIST_HEAD(&publ->all_publ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) INIT_LIST_HEAD(&publ->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return publ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * tipc_service_create - create a service structure for the specified 'type'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * Allocates a single range structure and sets it to all 0's.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static struct tipc_service *tipc_service_create(u32 type, struct hlist_head *hd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct tipc_service *service = kzalloc(sizeof(*service), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (!service) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) pr_warn("Service creation failed, no memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) spin_lock_init(&service->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) service->type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) service->ranges = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) INIT_HLIST_NODE(&service->service_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) INIT_LIST_HEAD(&service->subscriptions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) hlist_add_head_rcu(&service->service_list, hd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return service;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) /* tipc_service_find_range - find service range matching publication parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static struct service_range *tipc_service_find_range(struct tipc_service *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) u32 lower, u32 upper)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) struct service_range *sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) service_range_foreach_match(sr, sc, lower, upper) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /* Look for exact match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (sr->lower == lower && sr->upper == upper)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) static struct service_range *tipc_service_create_range(struct tipc_service *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) u32 lower, u32 upper)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) struct rb_node **n, *parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct service_range *sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) n = &sc->ranges.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) while (*n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) parent = *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) sr = service_range_entry(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (lower == sr->lower && upper == sr->upper)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (sr->max < upper)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) sr->max = upper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (lower <= sr->lower)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) n = &parent->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) n = &parent->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) sr = kzalloc(sizeof(*sr), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (!sr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) sr->lower = lower;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) sr->upper = upper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) sr->max = upper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) INIT_LIST_HEAD(&sr->local_publ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) INIT_LIST_HEAD(&sr->all_publ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) rb_link_node(&sr->tree_node, parent, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) rb_insert_augmented(&sr->tree_node, &sc->ranges, &sr_callbacks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static struct publication *tipc_service_insert_publ(struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct tipc_service *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) u32 type, u32 lower,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) u32 upper, u32 scope,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) u32 node, u32 port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) u32 key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) struct tipc_subscription *sub, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct service_range *sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct publication *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) bool first = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) sr = tipc_service_create_range(sc, lower, upper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (!sr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) first = list_empty(&sr->all_publ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /* Return if the publication already exists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) list_for_each_entry(p, &sr->all_publ, all_publ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (p->key == key && (!p->node || p->node == node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) /* Create and insert publication */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) p = tipc_publ_create(type, lower, upper, scope, node, port, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) /* Suppose there shouldn't be a huge gap btw publs i.e. >INT_MAX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) p->id = sc->publ_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (in_own_node(net, node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) list_add(&p->local_publ, &sr->local_publ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) list_add(&p->all_publ, &sr->all_publ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /* Any subscriptions waiting for notification? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) list_for_each_entry_safe(sub, tmp, &sc->subscriptions, service_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) tipc_sub_report_overlap(sub, p->lower, p->upper, TIPC_PUBLISHED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) p->port, p->node, p->scope, first);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) pr_warn("Failed to bind to %u,%u,%u, no memory\n", type, lower, upper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * tipc_service_remove_publ - remove a publication from a service
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static struct publication *tipc_service_remove_publ(struct service_range *sr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) u32 node, u32 key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) struct publication *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) list_for_each_entry(p, &sr->all_publ, all_publ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (p->key != key || (node && node != p->node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) list_del(&p->all_publ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) list_del(&p->local_publ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) * Code reused: time_after32() for the same purpose
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) #define publication_after(pa, pb) time_after32((pa)->id, (pb)->id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static int tipc_publ_sort(void *priv, struct list_head *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct list_head *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) struct publication *pa, *pb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) pa = container_of(a, struct publication, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) pb = container_of(b, struct publication, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return publication_after(pa, pb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * tipc_service_subscribe - attach a subscription, and optionally
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * issue the prescribed number of events if there is any service
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * range overlapping with the requested range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static void tipc_service_subscribe(struct tipc_service *service,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) struct tipc_subscription *sub)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct tipc_subscr *sb = &sub->evt.s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) struct publication *p, *first, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct list_head publ_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct service_range *sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct tipc_name_seq ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) u32 filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) ns.type = tipc_sub_read(sb, seq.type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) ns.lower = tipc_sub_read(sb, seq.lower);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) ns.upper = tipc_sub_read(sb, seq.upper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) filter = tipc_sub_read(sb, filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) tipc_sub_get(sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) list_add(&sub->service_list, &service->subscriptions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (filter & TIPC_SUB_NO_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) INIT_LIST_HEAD(&publ_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) service_range_foreach_match(sr, service, ns.lower, ns.upper) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) first = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) list_for_each_entry(p, &sr->all_publ, all_publ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (filter & TIPC_SUB_PORTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) list_add_tail(&p->list, &publ_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) else if (!first || publication_after(first, p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* Pick this range's *first* publication */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) first = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (first)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) list_add_tail(&first->list, &publ_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) /* Sort the publications before reporting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) list_sort(NULL, &publ_list, tipc_publ_sort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) list_for_each_entry_safe(p, tmp, &publ_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) tipc_sub_report_overlap(sub, p->lower, p->upper,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) TIPC_PUBLISHED, p->port, p->node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) p->scope, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) list_del_init(&p->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) static struct tipc_service *tipc_service_find(struct net *net, u32 type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) struct name_table *nt = tipc_name_table(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) struct hlist_head *service_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) struct tipc_service *service;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) service_head = &nt->services[hash(type)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) hlist_for_each_entry_rcu(service, service_head, service_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (service->type == type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return service;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct publication *tipc_nametbl_insert_publ(struct net *net, u32 type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) u32 lower, u32 upper,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) u32 scope, u32 node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) u32 port, u32 key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct name_table *nt = tipc_name_table(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) struct tipc_service *sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) struct publication *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (scope > TIPC_NODE_SCOPE || lower > upper) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) pr_debug("Failed to bind illegal {%u,%u,%u} with scope %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) type, lower, upper, scope);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) sc = tipc_service_find(net, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (!sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) sc = tipc_service_create(type, &nt->services[hash(type)]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (!sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) spin_lock_bh(&sc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) p = tipc_service_insert_publ(net, sc, type, lower, upper,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) scope, node, port, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) spin_unlock_bh(&sc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) u32 lower, u32 upper,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) u32 node, u32 key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) struct tipc_service *sc = tipc_service_find(net, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) struct tipc_subscription *sub, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) struct service_range *sr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) struct publication *p = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) bool last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (!sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) spin_lock_bh(&sc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) sr = tipc_service_find_range(sc, lower, upper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (!sr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) p = tipc_service_remove_publ(sr, node, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /* Notify any waiting subscriptions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) last = list_empty(&sr->all_publ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) list_for_each_entry_safe(sub, tmp, &sc->subscriptions, service_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) tipc_sub_report_overlap(sub, lower, upper, TIPC_WITHDRAWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) p->port, node, p->scope, last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) /* Remove service range item if this was its last publication */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (list_empty(&sr->all_publ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) rb_erase_augmented(&sr->tree_node, &sc->ranges, &sr_callbacks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) kfree(sr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) /* Delete service item if this no more publications and subscriptions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (RB_EMPTY_ROOT(&sc->ranges) && list_empty(&sc->subscriptions)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) hlist_del_init_rcu(&sc->service_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) kfree_rcu(sc, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) spin_unlock_bh(&sc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) * tipc_nametbl_translate - perform service instance to socket translation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) * On entry, 'dnode' is the search domain used during translation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) * On exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * - if translation is deferred to another node, leave 'dnode' unchanged and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * return 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * - if translation is attempted and succeeds, set 'dnode' to the publishing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * node and return the published (non-zero) port number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * - if translation is attempted and fails, set 'dnode' to 0 and return 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * Note that for legacy users (node configured with Z.C.N address format) the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * 'closest-first' lookup algorithm must be maintained, i.e., if dnode is 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * we must look in the local binding list first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, u32 *dnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) struct tipc_net *tn = tipc_net(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) bool legacy = tn->legacy_addr_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) u32 self = tipc_own_addr(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) struct service_range *sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) struct tipc_service *sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) struct list_head *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) struct publication *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) u32 port = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) u32 node = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (!tipc_in_scope(legacy, *dnode, self))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) sc = tipc_service_find(net, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (unlikely(!sc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) spin_lock_bh(&sc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) service_range_foreach_match(sr, sc, instance, instance) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) /* Select lookup algo: local, closest-first or round-robin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (*dnode == self) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) list = &sr->local_publ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (list_empty(list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) p = list_first_entry(list, struct publication,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) local_publ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) list_move_tail(&p->local_publ, &sr->local_publ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) } else if (legacy && !*dnode && !list_empty(&sr->local_publ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) list = &sr->local_publ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) p = list_first_entry(list, struct publication,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) local_publ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) list_move_tail(&p->local_publ, &sr->local_publ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) list = &sr->all_publ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) p = list_first_entry(list, struct publication,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) all_publ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) list_move_tail(&p->all_publ, &sr->all_publ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) port = p->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) node = p->node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) /* Todo: as for legacy, pick the first matching range only, a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) * "true" round-robin will be performed as needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) spin_unlock_bh(&sc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) *dnode = node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) bool tipc_nametbl_lookup(struct net *net, u32 type, u32 instance, u32 scope,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) struct list_head *dsts, int *dstcnt, u32 exclude,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) bool all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) u32 self = tipc_own_addr(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) struct service_range *sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) struct tipc_service *sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) struct publication *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) *dstcnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) sc = tipc_service_find(net, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (unlikely(!sc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) spin_lock_bh(&sc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) /* Todo: a full search i.e. service_range_foreach_match() instead? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) sr = service_range_match_first(sc->ranges.rb_node, instance, instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (!sr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) goto no_match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) list_for_each_entry(p, &sr->all_publ, all_publ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (p->scope != scope)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (p->port == exclude && p->node == self)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) tipc_dest_push(dsts, p->node, p->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) (*dstcnt)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) list_move_tail(&p->all_publ, &sr->all_publ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) no_match:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) spin_unlock_bh(&sc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return !list_empty(dsts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) void tipc_nametbl_mc_lookup(struct net *net, u32 type, u32 lower, u32 upper,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) u32 scope, bool exact, struct list_head *dports)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) struct service_range *sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) struct tipc_service *sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) struct publication *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) sc = tipc_service_find(net, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) if (!sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) spin_lock_bh(&sc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) service_range_foreach_match(sr, sc, lower, upper) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) list_for_each_entry(p, &sr->local_publ, local_publ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) if (p->scope == scope || (!exact && p->scope < scope))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) tipc_dest_push(dports, 0, p->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) spin_unlock_bh(&sc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) /* tipc_nametbl_lookup_dst_nodes - find broadcast destination nodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) * - Creates list of nodes that overlap the given multicast address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) * - Determines if any node local destinations overlap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) void tipc_nametbl_lookup_dst_nodes(struct net *net, u32 type, u32 lower,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) u32 upper, struct tipc_nlist *nodes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) struct service_range *sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) struct tipc_service *sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) struct publication *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) sc = tipc_service_find(net, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (!sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) spin_lock_bh(&sc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) service_range_foreach_match(sr, sc, lower, upper) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) list_for_each_entry(p, &sr->all_publ, all_publ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) tipc_nlist_add(nodes, p->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) spin_unlock_bh(&sc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) /* tipc_nametbl_build_group - build list of communication group members
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) void tipc_nametbl_build_group(struct net *net, struct tipc_group *grp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) u32 type, u32 scope)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) struct service_range *sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) struct tipc_service *sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) struct publication *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) struct rb_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) sc = tipc_service_find(net, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (!sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) spin_lock_bh(&sc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) for (n = rb_first(&sc->ranges); n; n = rb_next(n)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) sr = container_of(n, struct service_range, tree_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) list_for_each_entry(p, &sr->all_publ, all_publ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (p->scope != scope)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) tipc_group_add_member(grp, p->node, p->port, p->lower);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) spin_unlock_bh(&sc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) /* tipc_nametbl_publish - add service binding to name table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) struct publication *tipc_nametbl_publish(struct net *net, u32 type, u32 lower,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) u32 upper, u32 scope, u32 port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) u32 key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) struct name_table *nt = tipc_name_table(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) struct tipc_net *tn = tipc_net(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) struct publication *p = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) struct sk_buff *skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) u32 rc_dests;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) spin_lock_bh(&tn->nametbl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) if (nt->local_publ_count >= TIPC_MAX_PUBL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) pr_warn("Bind failed, max limit %u reached\n", TIPC_MAX_PUBL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) p = tipc_nametbl_insert_publ(net, type, lower, upper, scope,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) tipc_own_addr(net), port, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) nt->local_publ_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) skb = tipc_named_publish(net, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) rc_dests = nt->rc_dests;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) spin_unlock_bh(&tn->nametbl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) tipc_node_broadcast(net, skb, rc_dests);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) * tipc_nametbl_withdraw - withdraw a service binding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) u32 upper, u32 key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) struct name_table *nt = tipc_name_table(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) struct tipc_net *tn = tipc_net(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) u32 self = tipc_own_addr(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) struct sk_buff *skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) struct publication *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) u32 rc_dests;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) spin_lock_bh(&tn->nametbl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) p = tipc_nametbl_remove_publ(net, type, lower, upper, self, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) nt->local_publ_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) skb = tipc_named_withdraw(net, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) list_del_init(&p->binding_sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) kfree_rcu(p, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) pr_err("Failed to remove local publication {%u,%u,%u}/%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) type, lower, upper, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) rc_dests = nt->rc_dests;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) spin_unlock_bh(&tn->nametbl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) tipc_node_broadcast(net, skb, rc_dests);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) * tipc_nametbl_subscribe - add a subscription object to the name table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) bool tipc_nametbl_subscribe(struct tipc_subscription *sub)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) struct name_table *nt = tipc_name_table(sub->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) struct tipc_net *tn = tipc_net(sub->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) struct tipc_subscr *s = &sub->evt.s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) u32 type = tipc_sub_read(s, seq.type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) struct tipc_service *sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) bool res = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) spin_lock_bh(&tn->nametbl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) sc = tipc_service_find(sub->net, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (!sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) sc = tipc_service_create(type, &nt->services[hash(type)]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) if (sc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) spin_lock_bh(&sc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) tipc_service_subscribe(sc, sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) spin_unlock_bh(&sc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) pr_warn("Failed to subscribe for {%u,%u,%u}\n", type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) tipc_sub_read(s, seq.lower),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) tipc_sub_read(s, seq.upper));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) res = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) spin_unlock_bh(&tn->nametbl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) * tipc_nametbl_unsubscribe - remove a subscription object from name table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) void tipc_nametbl_unsubscribe(struct tipc_subscription *sub)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) struct tipc_net *tn = tipc_net(sub->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) struct tipc_subscr *s = &sub->evt.s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) u32 type = tipc_sub_read(s, seq.type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) struct tipc_service *sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) spin_lock_bh(&tn->nametbl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) sc = tipc_service_find(sub->net, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (!sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) spin_lock_bh(&sc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) list_del_init(&sub->service_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) tipc_sub_put(sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) /* Delete service item if no more publications and subscriptions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) if (RB_EMPTY_ROOT(&sc->ranges) && list_empty(&sc->subscriptions)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) hlist_del_init_rcu(&sc->service_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) kfree_rcu(sc, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) spin_unlock_bh(&sc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) spin_unlock_bh(&tn->nametbl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) int tipc_nametbl_init(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) struct tipc_net *tn = tipc_net(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) struct name_table *nt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) nt = kzalloc(sizeof(*nt), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (!nt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) for (i = 0; i < TIPC_NAMETBL_SIZE; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) INIT_HLIST_HEAD(&nt->services[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) INIT_LIST_HEAD(&nt->node_scope);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) INIT_LIST_HEAD(&nt->cluster_scope);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) rwlock_init(&nt->cluster_scope_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) tn->nametbl = nt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) spin_lock_init(&tn->nametbl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) * tipc_service_delete - purge all publications for a service and delete it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) static void tipc_service_delete(struct net *net, struct tipc_service *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) struct service_range *sr, *tmpr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) struct publication *p, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) spin_lock_bh(&sc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) rbtree_postorder_for_each_entry_safe(sr, tmpr, &sc->ranges, tree_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) list_for_each_entry_safe(p, tmp, &sr->all_publ, all_publ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) tipc_service_remove_publ(sr, p->node, p->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) kfree_rcu(p, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) rb_erase_augmented(&sr->tree_node, &sc->ranges, &sr_callbacks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) kfree(sr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) hlist_del_init_rcu(&sc->service_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) spin_unlock_bh(&sc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) kfree_rcu(sc, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) void tipc_nametbl_stop(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) struct name_table *nt = tipc_name_table(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) struct tipc_net *tn = tipc_net(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) struct hlist_head *service_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) struct tipc_service *service;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) /* Verify name table is empty and purge any lingering
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) * publications, then release the name table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) spin_lock_bh(&tn->nametbl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) for (i = 0; i < TIPC_NAMETBL_SIZE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) if (hlist_empty(&nt->services[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) service_head = &nt->services[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) hlist_for_each_entry_rcu(service, service_head, service_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) tipc_service_delete(net, service);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) spin_unlock_bh(&tn->nametbl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) synchronize_net();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) kfree(nt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) static int __tipc_nl_add_nametable_publ(struct tipc_nl_msg *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) struct tipc_service *service,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) struct service_range *sr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) u32 *last_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) struct publication *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) struct nlattr *attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) struct nlattr *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (*last_key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) list_for_each_entry(p, &sr->all_publ, all_publ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if (p->key == *last_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) if (list_entry_is_head(p, &sr->all_publ, all_publ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) return -EPIPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) p = list_first_entry(&sr->all_publ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) struct publication,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) all_publ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) list_for_each_entry_from(p, &sr->all_publ, all_publ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) *last_key = p->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) hdr = genlmsg_put(msg->skb, msg->portid, msg->seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) &tipc_genl_family, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) TIPC_NL_NAME_TABLE_GET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) attrs = nla_nest_start_noflag(msg->skb, TIPC_NLA_NAME_TABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (!attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) goto msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) b = nla_nest_start_noflag(msg->skb, TIPC_NLA_NAME_TABLE_PUBL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) if (!b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) goto attr_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_TYPE, service->type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) goto publ_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_LOWER, sr->lower))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) goto publ_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_UPPER, sr->upper))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) goto publ_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_SCOPE, p->scope))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) goto publ_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_NODE, p->node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) goto publ_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_REF, p->port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) goto publ_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_KEY, p->key))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) goto publ_msg_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) nla_nest_end(msg->skb, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) nla_nest_end(msg->skb, attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) genlmsg_end(msg->skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) *last_key = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) publ_msg_full:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) nla_nest_cancel(msg->skb, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) attr_msg_full:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) nla_nest_cancel(msg->skb, attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) msg_full:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) genlmsg_cancel(msg->skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) static int __tipc_nl_service_range_list(struct tipc_nl_msg *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) struct tipc_service *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) u32 *last_lower, u32 *last_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) struct service_range *sr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) struct rb_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) for (n = rb_first(&sc->ranges); n; n = rb_next(n)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) sr = container_of(n, struct service_range, tree_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) if (sr->lower < *last_lower)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) err = __tipc_nl_add_nametable_publ(msg, sc, sr, last_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) *last_lower = sr->lower;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) *last_lower = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) static int tipc_nl_service_list(struct net *net, struct tipc_nl_msg *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) u32 *last_type, u32 *last_lower, u32 *last_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) struct tipc_net *tn = tipc_net(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) struct tipc_service *service = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) struct hlist_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) if (*last_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) i = hash(*last_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) for (; i < TIPC_NAMETBL_SIZE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) head = &tn->nametbl->services[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if (*last_type ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) (!i && *last_key && (*last_lower == *last_key))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) service = tipc_service_find(net, *last_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) if (!service)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) return -EPIPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) hlist_for_each_entry_rcu(service, head, service_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (!service)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) hlist_for_each_entry_from_rcu(service, service_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) spin_lock_bh(&service->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) err = __tipc_nl_service_range_list(msg, service,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) last_lower,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) last_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) *last_type = service->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) spin_unlock_bh(&service->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) spin_unlock_bh(&service->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) *last_type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) struct net *net = sock_net(skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) u32 last_type = cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) u32 last_lower = cb->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) u32 last_key = cb->args[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) int done = cb->args[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) struct tipc_nl_msg msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) if (done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) msg.skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) msg.portid = NETLINK_CB(cb->skb).portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) msg.seq = cb->nlh->nlmsg_seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) err = tipc_nl_service_list(net, &msg, &last_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) &last_lower, &last_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) done = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) } else if (err != -EMSGSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) /* We never set seq or call nl_dump_check_consistent() this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) * means that setting prev_seq here will cause the consistence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) * check to fail in the netlink callback handler. Resulting in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) * the NLMSG_DONE message having the NLM_F_DUMP_INTR flag set if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) * we got an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) cb->prev_seq = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) cb->args[0] = last_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) cb->args[1] = last_lower;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) cb->args[2] = last_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) cb->args[3] = done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) return skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) struct tipc_dest *tipc_dest_find(struct list_head *l, u32 node, u32 port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) struct tipc_dest *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) list_for_each_entry(dst, l, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if (dst->node == node && dst->port == port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) return dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) bool tipc_dest_push(struct list_head *l, u32 node, u32 port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) struct tipc_dest *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (tipc_dest_find(l, node, port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) dst = kmalloc(sizeof(*dst), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (unlikely(!dst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) dst->node = node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) dst->port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) list_add(&dst->list, l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) bool tipc_dest_pop(struct list_head *l, u32 *node, u32 *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) struct tipc_dest *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if (list_empty(l))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) dst = list_first_entry(l, typeof(*dst), list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) if (port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) *port = dst->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) if (node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) *node = dst->node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) list_del(&dst->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) kfree(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) bool tipc_dest_del(struct list_head *l, u32 node, u32 port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) struct tipc_dest *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) dst = tipc_dest_find(l, node, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) if (!dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) list_del(&dst->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) kfree(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) void tipc_dest_list_purge(struct list_head *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) struct tipc_dest *dst, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) list_for_each_entry_safe(dst, tmp, l, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) list_del(&dst->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) kfree(dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) int tipc_dest_list_len(struct list_head *l)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) struct tipc_dest *dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) list_for_each_entry(dst, l, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) }