aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-03-31 22:19:59 -0400
committerDavid S. Miller <davem@davemloft.net>2018-03-31 22:19:59 -0400
commit6851cf28db1c4becc25a2906ecd080c0022a9f11 (patch)
treec1905f23eaf0b2aeb7195a78ca378bcb94414251
parent24197ee2102359b59044234347dd3504302fa97d (diff)
parent7494cfa6d36d1556f17baa012dd93833620783db (diff)
Merge branch 'tipc-slim-down-name-table'
Jon Maloy says: ==================== tipc: slim down name table We clean up and improve the name binding table: - Replace the memory consuming 'sub_sequence/service range' array with an RB tree. - Introduce support for overlapping service sequences/ranges v2: #1: Fixed a missing initialization reported by David Miller #4: Obsoleted and replaced a few more macros to get a consistent terminology in the API. #5: Added new commit to fix a potential string overflow bug (it is still only in net-next) reported by Arnd Bergmann ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/uapi/linux/tipc.h59
-rw-r--r--net/tipc/core.h1
-rw-r--r--net/tipc/link.c5
-rw-r--r--net/tipc/name_distr.c90
-rw-r--r--net/tipc/name_distr.h1
-rw-r--r--net/tipc/name_table.c1075
-rw-r--r--net/tipc/name_table.h10
-rw-r--r--net/tipc/net.c2
-rw-r--r--net/tipc/node.c4
-rw-r--r--net/tipc/socket.c4
-rw-r--r--net/tipc/subscr.h4
11 files changed, 556 insertions, 699 deletions
diff --git a/include/uapi/linux/tipc.h b/include/uapi/linux/tipc.h
index 4ac9f1f02b06..bf6d28677cfe 100644
--- a/include/uapi/linux/tipc.h
+++ b/include/uapi/linux/tipc.h
@@ -45,33 +45,33 @@
45 * TIPC addressing primitives 45 * TIPC addressing primitives
46 */ 46 */
47 47
48struct tipc_portid { 48struct tipc_socket_addr {
49 __u32 ref; 49 __u32 ref;
50 __u32 node; 50 __u32 node;
51}; 51};
52 52
53struct tipc_name { 53struct tipc_service_addr {
54 __u32 type; 54 __u32 type;
55 __u32 instance; 55 __u32 instance;
56}; 56};
57 57
58struct tipc_name_seq { 58struct tipc_service_range {
59 __u32 type; 59 __u32 type;
60 __u32 lower; 60 __u32 lower;
61 __u32 upper; 61 __u32 upper;
62}; 62};
63 63
64/* 64/*
65 * Application-accessible port name types 65 * Application-accessible service types
66 */ 66 */
67 67
68#define TIPC_CFG_SRV 0 /* configuration service name type */ 68#define TIPC_NODE_STATE 0 /* node state service type */
69#define TIPC_TOP_SRV 1 /* topology service name type */ 69#define TIPC_TOP_SRV 1 /* topology server service type */
70#define TIPC_LINK_STATE 2 /* link state name type */ 70#define TIPC_LINK_STATE 2 /* link state service type */
71#define TIPC_RESERVED_TYPES 64 /* lowest user-publishable name type */ 71#define TIPC_RESERVED_TYPES 64 /* lowest user-allowed service type */
72 72
73/* 73/*
74 * Publication scopes when binding port names and port name sequences 74 * Publication scopes when binding service / service range
75 */ 75 */
76enum tipc_scope { 76enum tipc_scope {
77 TIPC_CLUSTER_SCOPE = 2, /* 0 can also be used */ 77 TIPC_CLUSTER_SCOPE = 2, /* 0 can also be used */
@@ -108,28 +108,28 @@ enum tipc_scope {
108 * TIPC topology subscription service definitions 108 * TIPC topology subscription service definitions
109 */ 109 */
110 110
111#define TIPC_SUB_PORTS 0x01 /* filter for port availability */ 111#define TIPC_SUB_PORTS 0x01 /* filter: evt at each match */
112#define TIPC_SUB_SERVICE 0x02 /* filter for service availability */ 112#define TIPC_SUB_SERVICE 0x02 /* filter: evt at first up/last down */
113#define TIPC_SUB_CANCEL 0x04 /* cancel a subscription */ 113#define TIPC_SUB_CANCEL 0x04 /* filter: cancel a subscription */
114 114
115#define TIPC_WAIT_FOREVER (~0) /* timeout for permanent subscription */ 115#define TIPC_WAIT_FOREVER (~0) /* timeout for permanent subscription */
116 116
117struct tipc_subscr { 117struct tipc_subscr {
118 struct tipc_name_seq seq; /* name sequence of interest */ 118 struct tipc_service_range seq; /* range of interest */
119 __u32 timeout; /* subscription duration (in ms) */ 119 __u32 timeout; /* subscription duration (in ms) */
120 __u32 filter; /* bitmask of filter options */ 120 __u32 filter; /* bitmask of filter options */
121 char usr_handle[8]; /* available for subscriber use */ 121 char usr_handle[8]; /* available for subscriber use */
122}; 122};
123 123
124#define TIPC_PUBLISHED 1 /* publication event */ 124#define TIPC_PUBLISHED 1 /* publication event */
125#define TIPC_WITHDRAWN 2 /* withdraw event */ 125#define TIPC_WITHDRAWN 2 /* withdrawal event */
126#define TIPC_SUBSCR_TIMEOUT 3 /* subscription timeout event */ 126#define TIPC_SUBSCR_TIMEOUT 3 /* subscription timeout event */
127 127
128struct tipc_event { 128struct tipc_event {
129 __u32 event; /* event type */ 129 __u32 event; /* event type */
130 __u32 found_lower; /* matching name seq instances */ 130 __u32 found_lower; /* matching range */
131 __u32 found_upper; /* " " " " */ 131 __u32 found_upper; /* " " */
132 struct tipc_portid port; /* associated port */ 132 struct tipc_socket_addr port; /* associated socket */
133 struct tipc_subscr s; /* associated subscription */ 133 struct tipc_subscr s; /* associated subscription */
134}; 134};
135 135
@@ -149,20 +149,20 @@ struct tipc_event {
149#define SOL_TIPC 271 149#define SOL_TIPC 271
150#endif 150#endif
151 151
152#define TIPC_ADDR_NAMESEQ 1 152#define TIPC_ADDR_MCAST 1
153#define TIPC_ADDR_MCAST 1 153#define TIPC_SERVICE_RANGE 1
154#define TIPC_ADDR_NAME 2 154#define TIPC_SERVICE_ADDR 2
155#define TIPC_ADDR_ID 3 155#define TIPC_SOCKET_ADDR 3
156 156
157struct sockaddr_tipc { 157struct sockaddr_tipc {
158 unsigned short family; 158 unsigned short family;
159 unsigned char addrtype; 159 unsigned char addrtype;
160 signed char scope; 160 signed char scope;
161 union { 161 union {
162 struct tipc_portid id; 162 struct tipc_socket_addr id;
163 struct tipc_name_seq nameseq; 163 struct tipc_service_range nameseq;
164 struct { 164 struct {
165 struct tipc_name name; 165 struct tipc_service_addr name;
166 __u32 domain; 166 __u32 domain;
167 } name; 167 } name;
168 } addr; 168 } addr;
@@ -216,7 +216,7 @@ struct tipc_group_req {
216#define TIPC_MAX_MEDIA_NAME 16 216#define TIPC_MAX_MEDIA_NAME 16
217#define TIPC_MAX_IF_NAME 16 217#define TIPC_MAX_IF_NAME 16
218#define TIPC_MAX_BEARER_NAME 32 218#define TIPC_MAX_BEARER_NAME 32
219#define TIPC_MAX_LINK_NAME 60 219#define TIPC_MAX_LINK_NAME 68
220 220
221#define SIOCGETLINKNAME SIOCPROTOPRIVATE 221#define SIOCGETLINKNAME SIOCPROTOPRIVATE
222 222
@@ -230,8 +230,13 @@ struct tipc_sioc_ln_req {
230/* The macros and functions below are deprecated: 230/* The macros and functions below are deprecated:
231 */ 231 */
232 232
233#define TIPC_CFG_SRV 0
233#define TIPC_ZONE_SCOPE 1 234#define TIPC_ZONE_SCOPE 1
234 235
236#define TIPC_ADDR_NAMESEQ 1
237#define TIPC_ADDR_NAME 2
238#define TIPC_ADDR_ID 3
239
235#define TIPC_NODE_BITS 12 240#define TIPC_NODE_BITS 12
236#define TIPC_CLUSTER_BITS 12 241#define TIPC_CLUSTER_BITS 12
237#define TIPC_ZONE_BITS 8 242#define TIPC_ZONE_BITS 8
@@ -250,6 +255,10 @@ struct tipc_sioc_ln_req {
250 255
251#define TIPC_ZONE_CLUSTER_MASK (TIPC_ZONE_MASK | TIPC_CLUSTER_MASK) 256#define TIPC_ZONE_CLUSTER_MASK (TIPC_ZONE_MASK | TIPC_CLUSTER_MASK)
252 257
258#define tipc_portid tipc_socket_addr
259#define tipc_name tipc_service_addr
260#define tipc_name_seq tipc_service_range
261
253static inline __u32 tipc_addr(unsigned int zone, 262static inline __u32 tipc_addr(unsigned int zone,
254 unsigned int cluster, 263 unsigned int cluster,
255 unsigned int node) 264 unsigned int node)
diff --git a/net/tipc/core.h b/net/tipc/core.h
index d0f64ca62d02..8020a6c360ff 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -58,6 +58,7 @@
58#include <linux/etherdevice.h> 58#include <linux/etherdevice.h>
59#include <net/netns/generic.h> 59#include <net/netns/generic.h>
60#include <linux/rhashtable.h> 60#include <linux/rhashtable.h>
61#include <net/genetlink.h>
61 62
62struct tipc_node; 63struct tipc_node;
63struct tipc_bearer; 64struct tipc_bearer;
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 1289b4ba404f..695acb783969 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -462,7 +462,8 @@ bool tipc_link_create(struct net *net, char *if_name, int bearer_id,
462 sprintf(peer_str, "%x", peer); 462 sprintf(peer_str, "%x", peer);
463 } 463 }
464 /* Peer i/f name will be completed by reset/activate message */ 464 /* Peer i/f name will be completed by reset/activate message */
465 sprintf(l->name, "%s:%s-%s:unknown", self_str, if_name, peer_str); 465 snprintf(l->name, sizeof(l->name), "%s:%s-%s:unknown",
466 self_str, if_name, peer_str);
466 467
467 strcpy(l->if_name, if_name); 468 strcpy(l->if_name, if_name);
468 l->addr = peer; 469 l->addr = peer;
@@ -1810,7 +1811,7 @@ int tipc_link_bc_nack_rcv(struct tipc_link *l, struct sk_buff *skb,
1810 1811
1811void tipc_link_set_queue_limits(struct tipc_link *l, u32 win) 1812void tipc_link_set_queue_limits(struct tipc_link *l, u32 win)
1812{ 1813{
1813 int max_bulk = TIPC_MAX_PUBLICATIONS / (l->mtu / ITEM_SIZE); 1814 int max_bulk = TIPC_MAX_PUBL / (l->mtu / ITEM_SIZE);
1814 1815
1815 l->window = win; 1816 l->window = win;
1816 l->backlog[TIPC_LOW_IMPORTANCE].limit = max_t(u16, 50, win); 1817 l->backlog[TIPC_LOW_IMPORTANCE].limit = max_t(u16, 50, win);
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index 8240a85b0d0c..51b4b96f89db 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -204,12 +204,12 @@ void tipc_named_node_up(struct net *net, u32 dnode)
204 */ 204 */
205static void tipc_publ_purge(struct net *net, struct publication *publ, u32 addr) 205static void tipc_publ_purge(struct net *net, struct publication *publ, u32 addr)
206{ 206{
207 struct tipc_net *tn = net_generic(net, tipc_net_id); 207 struct tipc_net *tn = tipc_net(net);
208 struct publication *p; 208 struct publication *p;
209 209
210 spin_lock_bh(&tn->nametbl_lock); 210 spin_lock_bh(&tn->nametbl_lock);
211 p = tipc_nametbl_remove_publ(net, publ->type, publ->lower, 211 p = tipc_nametbl_remove_publ(net, publ->type, publ->lower, publ->upper,
212 publ->node, publ->port, publ->key); 212 publ->node, publ->key);
213 if (p) 213 if (p)
214 tipc_node_unsubscribe(net, &p->binding_node, addr); 214 tipc_node_unsubscribe(net, &p->binding_node, addr);
215 spin_unlock_bh(&tn->nametbl_lock); 215 spin_unlock_bh(&tn->nametbl_lock);
@@ -261,28 +261,31 @@ void tipc_publ_notify(struct net *net, struct list_head *nsub_list, u32 addr)
261static bool tipc_update_nametbl(struct net *net, struct distr_item *i, 261static bool tipc_update_nametbl(struct net *net, struct distr_item *i,
262 u32 node, u32 dtype) 262 u32 node, u32 dtype)
263{ 263{
264 struct publication *publ = NULL; 264 struct publication *p = NULL;
265 u32 lower = ntohl(i->lower);
266 u32 upper = ntohl(i->upper);
267 u32 type = ntohl(i->type);
268 u32 port = ntohl(i->port);
269 u32 key = ntohl(i->key);
265 270
266 if (dtype == PUBLICATION) { 271 if (dtype == PUBLICATION) {
267 publ = tipc_nametbl_insert_publ(net, ntohl(i->type), 272 p = tipc_nametbl_insert_publ(net, type, lower, upper,
268 ntohl(i->lower), 273 TIPC_CLUSTER_SCOPE, node,
269 ntohl(i->upper), 274 port, key);
270 TIPC_CLUSTER_SCOPE, node, 275 if (p) {
271 ntohl(i->port), ntohl(i->key)); 276 tipc_node_subscribe(net, &p->binding_node, node);
272 if (publ) {
273 tipc_node_subscribe(net, &publ->binding_node, node);
274 return true; 277 return true;
275 } 278 }
276 } else if (dtype == WITHDRAWAL) { 279 } else if (dtype == WITHDRAWAL) {
277 publ = tipc_nametbl_remove_publ(net, ntohl(i->type), 280 p = tipc_nametbl_remove_publ(net, type, lower,
278 ntohl(i->lower), 281 upper, node, key);
279 node, ntohl(i->port), 282 if (p) {
280 ntohl(i->key)); 283 tipc_node_unsubscribe(net, &p->binding_node, node);
281 if (publ) { 284 kfree_rcu(p, rcu);
282 tipc_node_unsubscribe(net, &publ->binding_node, node);
283 kfree_rcu(publ, rcu);
284 return true; 285 return true;
285 } 286 }
287 pr_warn_ratelimited("Failed to remove binding %u,%u from %x\n",
288 type, lower, node);
286 } else { 289 } else {
287 pr_warn("Unrecognized name table message received\n"); 290 pr_warn("Unrecognized name table message received\n");
288 } 291 }
@@ -290,53 +293,6 @@ static bool tipc_update_nametbl(struct net *net, struct distr_item *i,
290} 293}
291 294
292/** 295/**
293 * tipc_named_add_backlog - add a failed name table update to the backlog
294 *
295 */
296static void tipc_named_add_backlog(struct net *net, struct distr_item *i,
297 u32 type, u32 node)
298{
299 struct distr_queue_item *e;
300 struct tipc_net *tn = net_generic(net, tipc_net_id);
301 unsigned long now = get_jiffies_64();
302
303 e = kzalloc(sizeof(*e), GFP_ATOMIC);
304 if (!e)
305 return;
306 e->dtype = type;
307 e->node = node;
308 e->expires = now + msecs_to_jiffies(sysctl_tipc_named_timeout);
309 memcpy(e, i, sizeof(*i));
310 list_add_tail(&e->next, &tn->dist_queue);
311}
312
313/**
314 * tipc_named_process_backlog - try to process any pending name table updates
315 * from the network.
316 */
317void tipc_named_process_backlog(struct net *net)
318{
319 struct distr_queue_item *e, *tmp;
320 struct tipc_net *tn = net_generic(net, tipc_net_id);
321 unsigned long now = get_jiffies_64();
322
323 list_for_each_entry_safe(e, tmp, &tn->dist_queue, next) {
324 if (time_after(e->expires, now)) {
325 if (!tipc_update_nametbl(net, &e->i, e->node, e->dtype))
326 continue;
327 } else {
328 pr_warn_ratelimited("Dropping name table update (%d) of {%u, %u, %u} from %x key=%u\n",
329 e->dtype, ntohl(e->i.type),
330 ntohl(e->i.lower),
331 ntohl(e->i.upper),
332 e->node, ntohl(e->i.key));
333 }
334 list_del(&e->next);
335 kfree(e);
336 }
337}
338
339/**
340 * tipc_named_rcv - process name table update messages sent by another node 296 * tipc_named_rcv - process name table update messages sent by another node
341 */ 297 */
342void tipc_named_rcv(struct net *net, struct sk_buff_head *inputq) 298void tipc_named_rcv(struct net *net, struct sk_buff_head *inputq)
@@ -358,12 +314,10 @@ void tipc_named_rcv(struct net *net, struct sk_buff_head *inputq)
358 count = msg_data_sz(msg) / ITEM_SIZE; 314 count = msg_data_sz(msg) / ITEM_SIZE;
359 node = msg_orignode(msg); 315 node = msg_orignode(msg);
360 while (count--) { 316 while (count--) {
361 if (!tipc_update_nametbl(net, item, node, mtype)) 317 tipc_update_nametbl(net, item, node, mtype);
362 tipc_named_add_backlog(net, item, mtype, node);
363 item++; 318 item++;
364 } 319 }
365 kfree_skb(skb); 320 kfree_skb(skb);
366 tipc_named_process_backlog(net);
367 } 321 }
368 spin_unlock_bh(&tn->nametbl_lock); 322 spin_unlock_bh(&tn->nametbl_lock);
369} 323}
diff --git a/net/tipc/name_distr.h b/net/tipc/name_distr.h
index 4753e628d7c4..63fc73e0fa6c 100644
--- a/net/tipc/name_distr.h
+++ b/net/tipc/name_distr.h
@@ -72,7 +72,6 @@ struct sk_buff *tipc_named_withdraw(struct net *net, struct publication *publ);
72void tipc_named_node_up(struct net *net, u32 dnode); 72void tipc_named_node_up(struct net *net, u32 dnode);
73void tipc_named_rcv(struct net *net, struct sk_buff_head *msg_queue); 73void tipc_named_rcv(struct net *net, struct sk_buff_head *msg_queue);
74void tipc_named_reinit(struct net *net); 74void tipc_named_reinit(struct net *net);
75void tipc_named_process_backlog(struct net *net);
76void tipc_publ_notify(struct net *net, struct list_head *nsub_list, u32 addr); 75void tipc_publ_notify(struct net *net, struct list_head *nsub_list, u32 addr);
77 76
78#endif 77#endif
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 4359605b1bec..b1fe20972aa9 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -44,52 +44,40 @@
44#include "addr.h" 44#include "addr.h"
45#include "node.h" 45#include "node.h"
46#include "group.h" 46#include "group.h"
47#include <net/genetlink.h>
48
49#define TIPC_NAMETBL_SIZE 1024 /* must be a power of 2 */
50 47
51/** 48/**
52 * struct name_info - name sequence publication info 49 * struct service_range - container for all bindings of a service range
53 * @node_list: list of publications on own node of this <type,lower,upper> 50 * @lower: service range lower bound
54 * @all_publ: list of all publications of this <type,lower,upper> 51 * @upper: service range upper bound
52 * @tree_node: member of service range RB tree
53 * @local_publ: list of identical publications made from this node
54 * Used by closest_first lookup and multicast lookup algorithm
55 * @all_publ: all publications identical to this one, whatever node and scope
56 * Used by round-robin lookup algorithm
55 */ 57 */
56struct name_info { 58struct service_range {
57 struct list_head local_publ;
58 struct list_head all_publ;
59};
60
61/**
62 * struct sub_seq - container for all published instances of a name sequence
63 * @lower: name sequence lower bound
64 * @upper: name sequence upper bound
65 * @info: pointer to name sequence publication info
66 */
67struct sub_seq {
68 u32 lower; 59 u32 lower;
69 u32 upper; 60 u32 upper;
70 struct name_info *info; 61 struct rb_node tree_node;
62 struct list_head local_publ;
63 struct list_head all_publ;
71}; 64};
72 65
73/** 66/**
74 * struct name_seq - container for all published instances of a name type 67 * struct tipc_service - container for all published instances of a service type
75 * @type: 32 bit 'type' value for name sequence 68 * @type: 32 bit 'type' value for service
76 * @sseq: pointer to dynamically-sized array of sub-sequences of this 'type'; 69 * @ranges: rb tree containing all service ranges for this service
77 * sub-sequences are sorted in ascending order 70 * @service_list: links to adjacent name ranges in hash chain
78 * @alloc: number of sub-sequences currently in array 71 * @subscriptions: list of subscriptions for this service type
79 * @first_free: array index of first unused sub-sequence entry 72 * @lock: spinlock controlling access to pertaining service ranges/publications
80 * @ns_list: links to adjacent name sequences in hash chain
81 * @subscriptions: list of subscriptions for this 'type'
82 * @lock: spinlock controlling access to publication lists of all sub-sequences
83 * @rcu: RCU callback head used for deferred freeing 73 * @rcu: RCU callback head used for deferred freeing
84 */ 74 */
85struct name_seq { 75struct tipc_service {
86 u32 type; 76 u32 type;
87 struct sub_seq *sseqs; 77 struct rb_root ranges;
88 u32 alloc; 78 struct hlist_node service_list;
89 u32 first_free;
90 struct hlist_node ns_list;
91 struct list_head subscriptions; 79 struct list_head subscriptions;
92 spinlock_t lock; 80 spinlock_t lock; /* Covers service range list */
93 struct rcu_head rcu; 81 struct rcu_head rcu;
94}; 82};
95 83
@@ -99,17 +87,16 @@ static int hash(int x)
99} 87}
100 88
101/** 89/**
102 * publ_create - create a publication structure 90 * tipc_publ_create - create a publication structure
103 */ 91 */
104static struct publication *publ_create(u32 type, u32 lower, u32 upper, 92static struct publication *tipc_publ_create(u32 type, u32 lower, u32 upper,
105 u32 scope, u32 node, u32 port, 93 u32 scope, u32 node, u32 port,
106 u32 key) 94 u32 key)
107{ 95{
108 struct publication *publ = kzalloc(sizeof(*publ), GFP_ATOMIC); 96 struct publication *publ = kzalloc(sizeof(*publ), GFP_ATOMIC);
109 if (publ == NULL) { 97
110 pr_warn("Publication creation failure, no memory\n"); 98 if (!publ)
111 return NULL; 99 return NULL;
112 }
113 100
114 publ->type = type; 101 publ->type = type;
115 publ->lower = lower; 102 publ->lower = lower;
@@ -119,446 +106,360 @@ static struct publication *publ_create(u32 type, u32 lower, u32 upper,
119 publ->port = port; 106 publ->port = port;
120 publ->key = key; 107 publ->key = key;
121 INIT_LIST_HEAD(&publ->binding_sock); 108 INIT_LIST_HEAD(&publ->binding_sock);
109 INIT_LIST_HEAD(&publ->binding_node);
110 INIT_LIST_HEAD(&publ->local_publ);
111 INIT_LIST_HEAD(&publ->all_publ);
122 return publ; 112 return publ;
123} 113}
124 114
125/** 115/**
126 * tipc_subseq_alloc - allocate a specified number of sub-sequence structures 116 * tipc_service_create - create a service structure for the specified 'type'
127 */
128static struct sub_seq *tipc_subseq_alloc(u32 cnt)
129{
130 return kcalloc(cnt, sizeof(struct sub_seq), GFP_ATOMIC);
131}
132
133/**
134 * tipc_nameseq_create - create a name sequence structure for the specified 'type'
135 * 117 *
136 * Allocates a single sub-sequence structure and sets it to all 0's. 118 * Allocates a single range structure and sets it to all 0's.
137 */ 119 */
138static struct name_seq *tipc_nameseq_create(u32 type, struct hlist_head *seq_head) 120static struct tipc_service *tipc_service_create(u32 type, struct hlist_head *hd)
139{ 121{
140 struct name_seq *nseq = kzalloc(sizeof(*nseq), GFP_ATOMIC); 122 struct tipc_service *service = kzalloc(sizeof(*service), GFP_ATOMIC);
141 struct sub_seq *sseq = tipc_subseq_alloc(1);
142 123
143 if (!nseq || !sseq) { 124 if (!service) {
144 pr_warn("Name sequence creation failed, no memory\n"); 125 pr_warn("Service creation failed, no memory\n");
145 kfree(nseq);
146 kfree(sseq);
147 return NULL; 126 return NULL;
148 } 127 }
149 128
150 spin_lock_init(&nseq->lock); 129 spin_lock_init(&service->lock);
151 nseq->type = type; 130 service->type = type;
152 nseq->sseqs = sseq; 131 service->ranges = RB_ROOT;
153 nseq->alloc = 1; 132 INIT_HLIST_NODE(&service->service_list);
154 INIT_HLIST_NODE(&nseq->ns_list); 133 INIT_LIST_HEAD(&service->subscriptions);
155 INIT_LIST_HEAD(&nseq->subscriptions); 134 hlist_add_head_rcu(&service->service_list, hd);
156 hlist_add_head_rcu(&nseq->ns_list, seq_head); 135 return service;
157 return nseq;
158} 136}
159 137
160/** 138/**
161 * nameseq_find_subseq - find sub-sequence (if any) matching a name instance 139 * tipc_service_find_range - find service range matching a service instance
162 * 140 *
163 * Very time-critical, so binary searches through sub-sequence array. 141 * Very time-critical, so binary search through range rb tree
164 */ 142 */
165static struct sub_seq *nameseq_find_subseq(struct name_seq *nseq, 143static struct service_range *tipc_service_find_range(struct tipc_service *sc,
166 u32 instance) 144 u32 instance)
167{ 145{
168 struct sub_seq *sseqs = nseq->sseqs; 146 struct rb_node *n = sc->ranges.rb_node;
169 int low = 0; 147 struct service_range *sr;
170 int high = nseq->first_free - 1; 148
171 int mid; 149 while (n) {
172 150 sr = container_of(n, struct service_range, tree_node);
173 while (low <= high) { 151 if (sr->lower > instance)
174 mid = (low + high) / 2; 152 n = n->rb_left;
175 if (instance < sseqs[mid].lower) 153 else if (sr->upper < instance)
176 high = mid - 1; 154 n = n->rb_right;
177 else if (instance > sseqs[mid].upper)
178 low = mid + 1;
179 else 155 else
180 return &sseqs[mid]; 156 return sr;
181 } 157 }
182 return NULL; 158 return NULL;
183} 159}
184 160
185/** 161static struct service_range *tipc_service_create_range(struct tipc_service *sc,
186 * nameseq_locate_subseq - determine position of name instance in sub-sequence 162 u32 lower, u32 upper)
187 *
188 * Returns index in sub-sequence array of the entry that contains the specified
189 * instance value; if no entry contains that value, returns the position
190 * where a new entry for it would be inserted in the array.
191 *
192 * Note: Similar to binary search code for locating a sub-sequence.
193 */
194static u32 nameseq_locate_subseq(struct name_seq *nseq, u32 instance)
195{ 163{
196 struct sub_seq *sseqs = nseq->sseqs; 164 struct rb_node **n, *parent = NULL;
197 int low = 0; 165 struct service_range *sr, *tmp;
198 int high = nseq->first_free - 1; 166
199 int mid; 167 n = &sc->ranges.rb_node;
200 168 while (*n) {
201 while (low <= high) { 169 tmp = container_of(*n, struct service_range, tree_node);
202 mid = (low + high) / 2; 170 parent = *n;
203 if (instance < sseqs[mid].lower) 171 tmp = container_of(parent, struct service_range, tree_node);
204 high = mid - 1; 172 if (lower < tmp->lower)
205 else if (instance > sseqs[mid].upper) 173 n = &(*n)->rb_left;
206 low = mid + 1; 174 else if (lower > tmp->lower)
175 n = &(*n)->rb_right;
176 else if (upper < tmp->upper)
177 n = &(*n)->rb_left;
178 else if (upper > tmp->upper)
179 n = &(*n)->rb_right;
207 else 180 else
208 return mid; 181 return tmp;
209 } 182 }
210 return low; 183 sr = kzalloc(sizeof(*sr), GFP_ATOMIC);
184 if (!sr)
185 return NULL;
186 sr->lower = lower;
187 sr->upper = upper;
188 INIT_LIST_HEAD(&sr->local_publ);
189 INIT_LIST_HEAD(&sr->all_publ);
190 rb_link_node(&sr->tree_node, parent, n);
191 rb_insert_color(&sr->tree_node, &sc->ranges);
192 return sr;
211} 193}
212 194
213/** 195static struct publication *tipc_service_insert_publ(struct net *net,
214 * tipc_nameseq_insert_publ 196 struct tipc_service *sc,
215 */
216static struct publication *tipc_nameseq_insert_publ(struct net *net,
217 struct name_seq *nseq,
218 u32 type, u32 lower, 197 u32 type, u32 lower,
219 u32 upper, u32 scope, 198 u32 upper, u32 scope,
220 u32 node, u32 port, u32 key) 199 u32 node, u32 port,
200 u32 key)
221{ 201{
222 struct tipc_subscription *s; 202 struct tipc_subscription *sub, *tmp;
223 struct tipc_subscription *st; 203 struct service_range *sr;
224 struct publication *publ; 204 struct publication *p;
225 struct sub_seq *sseq; 205 bool first = false;
226 struct name_info *info;
227 int created_subseq = 0;
228
229 sseq = nameseq_find_subseq(nseq, lower);
230 if (sseq) {
231
232 /* Lower end overlaps existing entry => need an exact match */
233 if ((sseq->lower != lower) || (sseq->upper != upper)) {
234 return NULL;
235 }
236
237 info = sseq->info;
238 206
239 /* Check if an identical publication already exists */ 207 sr = tipc_service_create_range(sc, lower, upper);
240 list_for_each_entry(publ, &info->all_publ, all_publ) { 208 if (!sr)
241 if (publ->port == port && publ->key == key && 209 goto err;
242 (!publ->node || publ->node == node))
243 return NULL;
244 }
245 } else {
246 u32 inspos;
247 struct sub_seq *freesseq;
248 210
249 /* Find where lower end should be inserted */ 211 first = list_empty(&sr->all_publ);
250 inspos = nameseq_locate_subseq(nseq, lower);
251 212
252 /* Fail if upper end overlaps into an existing entry */ 213 /* Return if the publication already exists */
253 if ((inspos < nseq->first_free) && 214 list_for_each_entry(p, &sr->all_publ, all_publ) {
254 (upper >= nseq->sseqs[inspos].lower)) { 215 if (p->key == key && (!p->node || p->node == node))
255 return NULL; 216 return NULL;
256 }
257
258 /* Ensure there is space for new sub-sequence */
259 if (nseq->first_free == nseq->alloc) {
260 struct sub_seq *sseqs = tipc_subseq_alloc(nseq->alloc * 2);
261
262 if (!sseqs) {
263 pr_warn("Cannot publish {%u,%u,%u}, no memory\n",
264 type, lower, upper);
265 return NULL;
266 }
267 memcpy(sseqs, nseq->sseqs,
268 nseq->alloc * sizeof(struct sub_seq));
269 kfree(nseq->sseqs);
270 nseq->sseqs = sseqs;
271 nseq->alloc *= 2;
272 }
273
274 info = kzalloc(sizeof(*info), GFP_ATOMIC);
275 if (!info) {
276 pr_warn("Cannot publish {%u,%u,%u}, no memory\n",
277 type, lower, upper);
278 return NULL;
279 }
280
281 INIT_LIST_HEAD(&info->local_publ);
282 INIT_LIST_HEAD(&info->all_publ);
283
284 /* Insert new sub-sequence */
285 sseq = &nseq->sseqs[inspos];
286 freesseq = &nseq->sseqs[nseq->first_free];
287 memmove(sseq + 1, sseq, (freesseq - sseq) * sizeof(*sseq));
288 memset(sseq, 0, sizeof(*sseq));
289 nseq->first_free++;
290 sseq->lower = lower;
291 sseq->upper = upper;
292 sseq->info = info;
293 created_subseq = 1;
294 } 217 }
295 218
296 /* Insert a publication */ 219 /* Create and insert publication */
297 publ = publ_create(type, lower, upper, scope, node, port, key); 220 p = tipc_publ_create(type, lower, upper, scope, node, port, key);
298 if (!publ) 221 if (!p)
299 return NULL; 222 goto err;
300
301 list_add(&publ->all_publ, &info->all_publ);
302
303 if (in_own_node(net, node)) 223 if (in_own_node(net, node))
304 list_add(&publ->local_publ, &info->local_publ); 224 list_add(&p->local_publ, &sr->local_publ);
225 list_add(&p->all_publ, &sr->all_publ);
305 226
306 /* Any subscriptions waiting for notification? */ 227 /* Any subscriptions waiting for notification? */
307 list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) { 228 list_for_each_entry_safe(sub, tmp, &sc->subscriptions, service_list) {
308 tipc_sub_report_overlap(s, publ->lower, publ->upper, 229 tipc_sub_report_overlap(sub, p->lower, p->upper, TIPC_PUBLISHED,
309 TIPC_PUBLISHED, publ->port, 230 p->port, p->node, p->scope, first);
310 publ->node, publ->scope,
311 created_subseq);
312 } 231 }
313 return publ; 232 return p;
233err:
234 pr_warn("Failed to bind to %u,%u,%u, no memory\n", type, lower, upper);
235 return NULL;
314} 236}
315 237
316/** 238/**
317 * tipc_nameseq_remove_publ 239 * tipc_service_remove_publ - remove a publication from a service
318 *
319 * NOTE: There may be cases where TIPC is asked to remove a publication
320 * that is not in the name table. For example, if another node issues a
321 * publication for a name sequence that overlaps an existing name sequence
322 * the publication will not be recorded, which means the publication won't
323 * be found when the name sequence is later withdrawn by that node.
324 * A failed withdraw request simply returns a failure indication and lets the
325 * caller issue any error or warning messages associated with such a problem.
326 */ 240 */
327static struct publication *tipc_nameseq_remove_publ(struct net *net, 241static struct publication *tipc_service_remove_publ(struct net *net,
328 struct name_seq *nseq, 242 struct tipc_service *sc,
329 u32 inst, u32 node, 243 u32 lower, u32 upper,
330 u32 port, u32 key) 244 u32 node, u32 key)
331{ 245{
332 struct publication *publ; 246 struct tipc_subscription *sub, *tmp;
333 struct sub_seq *sseq = nameseq_find_subseq(nseq, inst); 247 struct service_range *sr;
334 struct name_info *info; 248 struct publication *p;
335 struct sub_seq *free; 249 bool found = false;
336 struct tipc_subscription *s, *st; 250 bool last = false;
337 int removed_subseq = 0; 251 struct rb_node *n;
338 252
339 if (!sseq) 253 sr = tipc_service_find_range(sc, lower);
254 if (!sr)
340 return NULL; 255 return NULL;
341 256
342 info = sseq->info; 257 /* Find exact matching service range */
258 for (n = &sr->tree_node; n; n = rb_next(n)) {
259 sr = container_of(n, struct service_range, tree_node);
260 if (sr->upper == upper)
261 break;
262 }
263 if (!n || sr->lower != lower || sr->upper != upper)
264 return NULL;
343 265
344 /* Locate publication, if it exists */ 266 /* Find publication, if it exists */
345 list_for_each_entry(publ, &info->all_publ, all_publ) { 267 list_for_each_entry(p, &sr->all_publ, all_publ) {
346 if (publ->key == key && publ->port == port && 268 if (p->key != key || (node && node != p->node))
347 (!publ->node || publ->node == node)) 269 continue;
348 goto found; 270 found = true;
271 break;
349 } 272 }
350 return NULL; 273 if (!found)
274 return NULL;
351 275
352found: 276 list_del(&p->all_publ);
353 list_del(&publ->all_publ); 277 list_del(&p->local_publ);
354 if (in_own_node(net, node)) 278
355 list_del(&publ->local_publ); 279 /* Remove service range item if this was its last publication */
356 280 if (list_empty(&sr->all_publ)) {
357 /* Contract subseq list if no more publications for that subseq */ 281 last = true;
358 if (list_empty(&info->all_publ)) { 282 rb_erase(&sr->tree_node, &sc->ranges);
359 kfree(info); 283 kfree(sr);
360 free = &nseq->sseqs[nseq->first_free--];
361 memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof(*sseq));
362 removed_subseq = 1;
363 } 284 }
364 285
365 /* Notify any waiting subscriptions */ 286 /* Notify any waiting subscriptions */
366 list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) { 287 list_for_each_entry_safe(sub, tmp, &sc->subscriptions, service_list) {
367 tipc_sub_report_overlap(s, publ->lower, publ->upper, 288 tipc_sub_report_overlap(sub, p->lower, p->upper, TIPC_WITHDRAWN,
368 TIPC_WITHDRAWN, publ->port, 289 p->port, p->node, p->scope, last);
369 publ->node, publ->scope,
370 removed_subseq);
371 } 290 }
372 291 return p;
373 return publ;
374} 292}
375 293
376/** 294/**
377 * tipc_nameseq_subscribe - attach a subscription, and optionally 295 * tipc_service_subscribe - attach a subscription, and optionally
378 * issue the prescribed number of events if there is any sub- 296 * issue the prescribed number of events if there is any service
379 * sequence overlapping with the requested sequence 297 * range overlapping with the requested range
380 */ 298 */
381static void tipc_nameseq_subscribe(struct name_seq *nseq, 299static void tipc_service_subscribe(struct tipc_service *service,
382 struct tipc_subscription *sub) 300 struct tipc_subscription *sub)
383{ 301{
384 struct sub_seq *sseq = nseq->sseqs; 302 struct tipc_subscr *sb = &sub->evt.s;
303 struct service_range *sr;
385 struct tipc_name_seq ns; 304 struct tipc_name_seq ns;
386 struct tipc_subscr *s = &sub->evt.s; 305 struct publication *p;
387 bool no_status; 306 struct rb_node *n;
307 bool first;
388 308
389 ns.type = tipc_sub_read(s, seq.type); 309 ns.type = tipc_sub_read(sb, seq.type);
390 ns.lower = tipc_sub_read(s, seq.lower); 310 ns.lower = tipc_sub_read(sb, seq.lower);
391 ns.upper = tipc_sub_read(s, seq.upper); 311 ns.upper = tipc_sub_read(sb, seq.upper);
392 no_status = tipc_sub_read(s, filter) & TIPC_SUB_NO_STATUS;
393 312
394 tipc_sub_get(sub); 313 tipc_sub_get(sub);
395 list_add(&sub->nameseq_list, &nseq->subscriptions); 314 list_add(&sub->service_list, &service->subscriptions);
396 315
397 if (no_status || !sseq) 316 if (tipc_sub_read(sb, filter) & TIPC_SUB_NO_STATUS)
398 return; 317 return;
399 318
400 while (sseq != &nseq->sseqs[nseq->first_free]) { 319 for (n = rb_first(&service->ranges); n; n = rb_next(n)) {
401 if (tipc_sub_check_overlap(&ns, sseq->lower, sseq->upper)) { 320 sr = container_of(n, struct service_range, tree_node);
402 struct publication *crs; 321 if (sr->lower > ns.upper)
403 struct name_info *info = sseq->info; 322 break;
404 int must_report = 1; 323 if (!tipc_sub_check_overlap(&ns, sr->lower, sr->upper))
405 324 continue;
406 list_for_each_entry(crs, &info->all_publ, all_publ) { 325 first = true;
407 tipc_sub_report_overlap(sub, sseq->lower, 326
408 sseq->upper, 327 list_for_each_entry(p, &sr->all_publ, all_publ) {
409 TIPC_PUBLISHED, 328 tipc_sub_report_overlap(sub, sr->lower, sr->upper,
410 crs->port, 329 TIPC_PUBLISHED, p->port,
411 crs->node, 330 p->node, p->scope, first);
412 crs->scope, 331 first = false;
413 must_report);
414 must_report = 0;
415 }
416 } 332 }
417 sseq++;
418 } 333 }
419} 334}
420 335
421static struct name_seq *nametbl_find_seq(struct net *net, u32 type) 336static struct tipc_service *tipc_service_find(struct net *net, u32 type)
422{ 337{
423 struct tipc_net *tn = net_generic(net, tipc_net_id); 338 struct name_table *nt = tipc_name_table(net);
424 struct hlist_head *seq_head; 339 struct hlist_head *service_head;
425 struct name_seq *ns; 340 struct tipc_service *service;
426 341
427 seq_head = &tn->nametbl->seq_hlist[hash(type)]; 342 service_head = &nt->services[hash(type)];
428 hlist_for_each_entry_rcu(ns, seq_head, ns_list) { 343 hlist_for_each_entry_rcu(service, service_head, service_list) {
429 if (ns->type == type) 344 if (service->type == type)
430 return ns; 345 return service;
431 } 346 }
432
433 return NULL; 347 return NULL;
434}; 348};
435 349
436struct publication *tipc_nametbl_insert_publ(struct net *net, u32 type, 350struct publication *tipc_nametbl_insert_publ(struct net *net, u32 type,
437 u32 lower, u32 upper, u32 scope, 351 u32 lower, u32 upper,
438 u32 node, u32 port, u32 key) 352 u32 scope, u32 node,
353 u32 port, u32 key)
439{ 354{
440 struct tipc_net *tn = net_generic(net, tipc_net_id); 355 struct name_table *nt = tipc_name_table(net);
441 struct publication *publ; 356 struct tipc_service *sc;
442 struct name_seq *seq = nametbl_find_seq(net, type); 357 struct publication *p;
443 int index = hash(type);
444 358
445 if (scope > TIPC_NODE_SCOPE || lower > upper) { 359 if (scope > TIPC_NODE_SCOPE || lower > upper) {
446 pr_debug("Failed to publish illegal {%u,%u,%u} with scope %u\n", 360 pr_debug("Failed to bind illegal {%u,%u,%u} with scope %u\n",
447 type, lower, upper, scope); 361 type, lower, upper, scope);
448 return NULL; 362 return NULL;
449 } 363 }
450 364 sc = tipc_service_find(net, type);
451 if (!seq) 365 if (!sc)
452 seq = tipc_nameseq_create(type, &tn->nametbl->seq_hlist[index]); 366 sc = tipc_service_create(type, &nt->services[hash(type)]);
453 if (!seq) 367 if (!sc)
454 return NULL; 368 return NULL;
455 369
456 spin_lock_bh(&seq->lock); 370 spin_lock_bh(&sc->lock);
457 publ = tipc_nameseq_insert_publ(net, seq, type, lower, upper, 371 p = tipc_service_insert_publ(net, sc, type, lower, upper,
458 scope, node, port, key); 372 scope, node, port, key);
459 spin_unlock_bh(&seq->lock); 373 spin_unlock_bh(&sc->lock);
460 return publ; 374 return p;
461} 375}
462 376
463struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type, 377struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type,
464 u32 lower, u32 node, u32 port, 378 u32 lower, u32 upper,
465 u32 key) 379 u32 node, u32 key)
466{ 380{
467 struct publication *publ; 381 struct tipc_service *sc = tipc_service_find(net, type);
468 struct name_seq *seq = nametbl_find_seq(net, type); 382 struct publication *p = NULL;
469 383
470 if (!seq) 384 if (!sc)
471 return NULL; 385 return NULL;
472 386
473 spin_lock_bh(&seq->lock); 387 spin_lock_bh(&sc->lock);
474 publ = tipc_nameseq_remove_publ(net, seq, lower, node, port, key); 388 p = tipc_service_remove_publ(net, sc, lower, upper, node, key);
475 if (!seq->first_free && list_empty(&seq->subscriptions)) { 389
476 hlist_del_init_rcu(&seq->ns_list); 390 /* Delete service item if this no more publications and subscriptions */
477 kfree(seq->sseqs); 391 if (RB_EMPTY_ROOT(&sc->ranges) && list_empty(&sc->subscriptions)) {
478 spin_unlock_bh(&seq->lock); 392 hlist_del_init_rcu(&sc->service_list);
479 kfree_rcu(seq, rcu); 393 kfree_rcu(sc, rcu);
480 return publ;
481 } 394 }
482 spin_unlock_bh(&seq->lock); 395 spin_unlock_bh(&sc->lock);
483 return publ; 396 return p;
484} 397}
485 398
486/** 399/**
487 * tipc_nametbl_translate - perform name translation 400 * tipc_nametbl_translate - perform service instance to socket translation
488 * 401 *
489 * On entry, 'destnode' is the search domain used during translation. 402 * On entry, 'dnode' is the search domain used during translation.
490 * 403 *
491 * On exit: 404 * On exit:
492 * - if name translation is deferred to another node/cluster/zone, 405 * - if translation is deferred to another node, leave 'dnode' unchanged and
493 * leaves 'destnode' unchanged (will be non-zero) and returns 0 406 * return 0
494 * - if name translation is attempted and succeeds, sets 'destnode' 407 * - if translation is attempted and succeeds, set 'dnode' to the publishing
495 * to publishing node and returns port reference (will be non-zero) 408 * node and return the published (non-zero) port number
496 * - if name translation is attempted and fails, sets 'destnode' to 0 409 * - if translation is attempted and fails, set 'dnode' to 0 and return 0
497 * and returns 0 410 *
411 * Note that for legacy users (node configured with Z.C.N address format) the
412 * 'closest-first' lookup algorithm must be maintained, i.e., if dnode is 0
413 * we must look in the local binding list first
498 */ 414 */
499u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, 415u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, u32 *dnode)
500 u32 *destnode)
501{ 416{
502 struct tipc_net *tn = tipc_net(net); 417 struct tipc_net *tn = tipc_net(net);
503 bool legacy = tn->legacy_addr_format; 418 bool legacy = tn->legacy_addr_format;
504 u32 self = tipc_own_addr(net); 419 u32 self = tipc_own_addr(net);
505 struct sub_seq *sseq; 420 struct service_range *sr;
506 struct name_info *info; 421 struct tipc_service *sc;
507 struct publication *publ; 422 struct list_head *list;
508 struct name_seq *seq; 423 struct publication *p;
509 u32 port = 0; 424 u32 port = 0;
510 u32 node = 0; 425 u32 node = 0;
511 426
512 if (!tipc_in_scope(legacy, *destnode, self)) 427 if (!tipc_in_scope(legacy, *dnode, self))
513 return 0; 428 return 0;
514 429
515 rcu_read_lock(); 430 rcu_read_lock();
516 seq = nametbl_find_seq(net, type); 431 sc = tipc_service_find(net, type);
517 if (unlikely(!seq)) 432 if (unlikely(!sc))
518 goto not_found; 433 goto not_found;
519 spin_lock_bh(&seq->lock); 434
520 sseq = nameseq_find_subseq(seq, instance); 435 spin_lock_bh(&sc->lock);
521 if (unlikely(!sseq)) 436 sr = tipc_service_find_range(sc, instance);
437 if (unlikely(!sr))
522 goto no_match; 438 goto no_match;
523 info = sseq->info;
524
525 /* Closest-First Algorithm */
526 if (legacy && !*destnode) {
527 if (!list_empty(&info->local_publ)) {
528 publ = list_first_entry(&info->local_publ,
529 struct publication,
530 local_publ);
531 list_move_tail(&publ->local_publ,
532 &info->local_publ);
533 } else {
534 publ = list_first_entry(&info->all_publ,
535 struct publication,
536 all_publ);
537 list_move_tail(&publ->all_publ,
538 &info->all_publ);
539 }
540 }
541 439
542 /* Round-Robin Algorithm */ 440 /* Select lookup algorithm: local, closest-first or round-robin */
543 else if (*destnode == tipc_own_addr(net)) { 441 if (*dnode == self) {
544 if (list_empty(&info->local_publ)) 442 list = &sr->local_publ;
443 if (list_empty(list))
545 goto no_match; 444 goto no_match;
546 publ = list_first_entry(&info->local_publ, struct publication, 445 p = list_first_entry(list, struct publication, local_publ);
547 local_publ); 446 list_move_tail(&p->local_publ, &sr->local_publ);
548 list_move_tail(&publ->local_publ, &info->local_publ); 447 } else if (legacy && !*dnode && !list_empty(&sr->local_publ)) {
448 list = &sr->local_publ;
449 p = list_first_entry(list, struct publication, local_publ);
450 list_move_tail(&p->local_publ, &sr->local_publ);
549 } else { 451 } else {
550 publ = list_first_entry(&info->all_publ, struct publication, 452 list = &sr->all_publ;
551 all_publ); 453 p = list_first_entry(list, struct publication, all_publ);
552 list_move_tail(&publ->all_publ, &info->all_publ); 454 list_move_tail(&p->all_publ, &sr->all_publ);
553 } 455 }
554 456 port = p->port;
555 port = publ->port; 457 node = p->node;
556 node = publ->node;
557no_match: 458no_match:
558 spin_unlock_bh(&seq->lock); 459 spin_unlock_bh(&sc->lock);
559not_found: 460not_found:
560 rcu_read_unlock(); 461 rcu_read_unlock();
561 *destnode = node; 462 *dnode = node;
562 return port; 463 return port;
563} 464}
564 465
@@ -567,34 +468,36 @@ bool tipc_nametbl_lookup(struct net *net, u32 type, u32 instance, u32 scope,
567 bool all) 468 bool all)
568{ 469{
569 u32 self = tipc_own_addr(net); 470 u32 self = tipc_own_addr(net);
570 struct publication *publ; 471 struct service_range *sr;
571 struct name_info *info; 472 struct tipc_service *sc;
572 struct name_seq *seq; 473 struct publication *p;
573 struct sub_seq *sseq;
574 474
575 *dstcnt = 0; 475 *dstcnt = 0;
576 rcu_read_lock(); 476 rcu_read_lock();
577 seq = nametbl_find_seq(net, type); 477 sc = tipc_service_find(net, type);
578 if (unlikely(!seq)) 478 if (unlikely(!sc))
579 goto exit; 479 goto exit;
580 spin_lock_bh(&seq->lock); 480
581 sseq = nameseq_find_subseq(seq, instance); 481 spin_lock_bh(&sc->lock);
582 if (likely(sseq)) { 482
583 info = sseq->info; 483 sr = tipc_service_find_range(sc, instance);
584 list_for_each_entry(publ, &info->all_publ, all_publ) { 484 if (!sr)
585 if (publ->scope != scope) 485 goto no_match;
586 continue; 486
587 if (publ->port == exclude && publ->node == self) 487 list_for_each_entry(p, &sr->all_publ, all_publ) {
588 continue; 488 if (p->scope != scope)
589 tipc_dest_push(dsts, publ->node, publ->port); 489 continue;
590 (*dstcnt)++; 490 if (p->port == exclude && p->node == self)
591 if (all) 491 continue;
592 continue; 492 tipc_dest_push(dsts, p->node, p->port);
593 list_move_tail(&publ->all_publ, &info->all_publ); 493 (*dstcnt)++;
594 break; 494 if (all)
595 } 495 continue;
496 list_move_tail(&p->all_publ, &sr->all_publ);
497 break;
596 } 498 }
597 spin_unlock_bh(&seq->lock); 499no_match:
500 spin_unlock_bh(&sc->lock);
598exit: 501exit:
599 rcu_read_unlock(); 502 rcu_read_unlock();
600 return !list_empty(dsts); 503 return !list_empty(dsts);
@@ -603,61 +506,64 @@ exit:
603void tipc_nametbl_mc_lookup(struct net *net, u32 type, u32 lower, u32 upper, 506void tipc_nametbl_mc_lookup(struct net *net, u32 type, u32 lower, u32 upper,
604 u32 scope, bool exact, struct list_head *dports) 507 u32 scope, bool exact, struct list_head *dports)
605{ 508{
606 struct sub_seq *sseq_stop; 509 struct service_range *sr;
607 struct name_info *info; 510 struct tipc_service *sc;
608 struct publication *p; 511 struct publication *p;
609 struct name_seq *seq; 512 struct rb_node *n;
610 struct sub_seq *sseq;
611 513
612 rcu_read_lock(); 514 rcu_read_lock();
613 seq = nametbl_find_seq(net, type); 515 sc = tipc_service_find(net, type);
614 if (!seq) 516 if (!sc)
615 goto exit; 517 goto exit;
616 518
617 spin_lock_bh(&seq->lock); 519 spin_lock_bh(&sc->lock);
618 sseq = seq->sseqs + nameseq_locate_subseq(seq, lower); 520
619 sseq_stop = seq->sseqs + seq->first_free; 521 for (n = rb_first(&sc->ranges); n; n = rb_next(n)) {
620 for (; sseq != sseq_stop; sseq++) { 522 sr = container_of(n, struct service_range, tree_node);
621 if (sseq->lower > upper) 523 if (sr->upper < lower)
524 continue;
525 if (sr->lower > upper)
622 break; 526 break;
623 info = sseq->info; 527 list_for_each_entry(p, &sr->local_publ, local_publ) {
624 list_for_each_entry(p, &info->local_publ, local_publ) {
625 if (p->scope == scope || (!exact && p->scope < scope)) 528 if (p->scope == scope || (!exact && p->scope < scope))
626 tipc_dest_push(dports, 0, p->port); 529 tipc_dest_push(dports, 0, p->port);
627 } 530 }
628 } 531 }
629 spin_unlock_bh(&seq->lock); 532 spin_unlock_bh(&sc->lock);
630exit: 533exit:
631 rcu_read_unlock(); 534 rcu_read_unlock();
632} 535}
633 536
634/* tipc_nametbl_lookup_dst_nodes - find broadcast destination nodes 537/* tipc_nametbl_lookup_dst_nodes - find broadcast destination nodes
635 * - Creates list of nodes that overlap the given multicast address 538 * - Creates list of nodes that overlap the given multicast address
636 * - Determines if any node local ports overlap 539 * - Determines if any node local destinations overlap
637 */ 540 */
638void tipc_nametbl_lookup_dst_nodes(struct net *net, u32 type, u32 lower, 541void tipc_nametbl_lookup_dst_nodes(struct net *net, u32 type, u32 lower,
639 u32 upper, struct tipc_nlist *nodes) 542 u32 upper, struct tipc_nlist *nodes)
640{ 543{
641 struct sub_seq *sseq, *stop; 544 struct service_range *sr;
642 struct publication *publ; 545 struct tipc_service *sc;
643 struct name_info *info; 546 struct publication *p;
644 struct name_seq *seq; 547 struct rb_node *n;
645 548
646 rcu_read_lock(); 549 rcu_read_lock();
647 seq = nametbl_find_seq(net, type); 550 sc = tipc_service_find(net, type);
648 if (!seq) 551 if (!sc)
649 goto exit; 552 goto exit;
650 553
651 spin_lock_bh(&seq->lock); 554 spin_lock_bh(&sc->lock);
652 sseq = seq->sseqs + nameseq_locate_subseq(seq, lower); 555
653 stop = seq->sseqs + seq->first_free; 556 for (n = rb_first(&sc->ranges); n; n = rb_next(n)) {
654 for (; sseq != stop && sseq->lower <= upper; sseq++) { 557 sr = container_of(n, struct service_range, tree_node);
655 info = sseq->info; 558 if (sr->upper < lower)
656 list_for_each_entry(publ, &info->all_publ, all_publ) { 559 continue;
657 tipc_nlist_add(nodes, publ->node); 560 if (sr->lower > upper)
561 break;
562 list_for_each_entry(p, &sr->all_publ, all_publ) {
563 tipc_nlist_add(nodes, p->node);
658 } 564 }
659 } 565 }
660 spin_unlock_bh(&seq->lock); 566 spin_unlock_bh(&sc->lock);
661exit: 567exit:
662 rcu_read_unlock(); 568 rcu_read_unlock();
663} 569}
@@ -667,90 +573,85 @@ exit:
667void tipc_nametbl_build_group(struct net *net, struct tipc_group *grp, 573void tipc_nametbl_build_group(struct net *net, struct tipc_group *grp,
668 u32 type, u32 scope) 574 u32 type, u32 scope)
669{ 575{
670 struct sub_seq *sseq, *stop; 576 struct service_range *sr;
671 struct name_info *info; 577 struct tipc_service *sc;
672 struct publication *p; 578 struct publication *p;
673 struct name_seq *seq; 579 struct rb_node *n;
674 580
675 rcu_read_lock(); 581 rcu_read_lock();
676 seq = nametbl_find_seq(net, type); 582 sc = tipc_service_find(net, type);
677 if (!seq) 583 if (!sc)
678 goto exit; 584 goto exit;
679 585
680 spin_lock_bh(&seq->lock); 586 spin_lock_bh(&sc->lock);
681 sseq = seq->sseqs; 587 for (n = rb_first(&sc->ranges); n; n = rb_next(n)) {
682 stop = seq->sseqs + seq->first_free; 588 sr = container_of(n, struct service_range, tree_node);
683 for (; sseq != stop; sseq++) { 589 list_for_each_entry(p, &sr->all_publ, all_publ) {
684 info = sseq->info;
685 list_for_each_entry(p, &info->all_publ, all_publ) {
686 if (p->scope != scope) 590 if (p->scope != scope)
687 continue; 591 continue;
688 tipc_group_add_member(grp, p->node, p->port, p->lower); 592 tipc_group_add_member(grp, p->node, p->port, p->lower);
689 } 593 }
690 } 594 }
691 spin_unlock_bh(&seq->lock); 595 spin_unlock_bh(&sc->lock);
692exit: 596exit:
693 rcu_read_unlock(); 597 rcu_read_unlock();
694} 598}
695 599
696/* 600/* tipc_nametbl_publish - add service binding to name table
697 * tipc_nametbl_publish - add name publication to network name tables
698 */ 601 */
699struct publication *tipc_nametbl_publish(struct net *net, u32 type, u32 lower, 602struct publication *tipc_nametbl_publish(struct net *net, u32 type, u32 lower,
700 u32 upper, u32 scope, u32 port_ref, 603 u32 upper, u32 scope, u32 port,
701 u32 key) 604 u32 key)
702{ 605{
703 struct publication *publ; 606 struct name_table *nt = tipc_name_table(net);
704 struct sk_buff *buf = NULL; 607 struct tipc_net *tn = tipc_net(net);
705 struct tipc_net *tn = net_generic(net, tipc_net_id); 608 struct publication *p = NULL;
609 struct sk_buff *skb = NULL;
706 610
707 spin_lock_bh(&tn->nametbl_lock); 611 spin_lock_bh(&tn->nametbl_lock);
708 if (tn->nametbl->local_publ_count >= TIPC_MAX_PUBLICATIONS) { 612
709 pr_warn("Publication failed, local publication limit reached (%u)\n", 613 if (nt->local_publ_count >= TIPC_MAX_PUBL) {
710 TIPC_MAX_PUBLICATIONS); 614 pr_warn("Bind failed, max limit %u reached\n", TIPC_MAX_PUBL);
711 spin_unlock_bh(&tn->nametbl_lock); 615 goto exit;
712 return NULL;
713 } 616 }
714 617
715 publ = tipc_nametbl_insert_publ(net, type, lower, upper, scope, 618 p = tipc_nametbl_insert_publ(net, type, lower, upper, scope,
716 tipc_own_addr(net), port_ref, key); 619 tipc_own_addr(net), port, key);
717 if (likely(publ)) { 620 if (p) {
718 tn->nametbl->local_publ_count++; 621 nt->local_publ_count++;
719 buf = tipc_named_publish(net, publ); 622 skb = tipc_named_publish(net, p);
720 /* Any pending external events? */
721 tipc_named_process_backlog(net);
722 } 623 }
624exit:
723 spin_unlock_bh(&tn->nametbl_lock); 625 spin_unlock_bh(&tn->nametbl_lock);
724 626
725 if (buf) 627 if (skb)
726 tipc_node_broadcast(net, buf); 628 tipc_node_broadcast(net, skb);
727 return publ; 629 return p;
728} 630}
729 631
730/** 632/**
731 * tipc_nametbl_withdraw - withdraw name publication from network name tables 633 * tipc_nametbl_withdraw - withdraw a service binding
732 */ 634 */
733int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower, u32 port, 635int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower,
734 u32 key) 636 u32 upper, u32 key)
735{ 637{
736 struct publication *publ; 638 struct name_table *nt = tipc_name_table(net);
639 struct tipc_net *tn = tipc_net(net);
640 u32 self = tipc_own_addr(net);
737 struct sk_buff *skb = NULL; 641 struct sk_buff *skb = NULL;
738 struct tipc_net *tn = net_generic(net, tipc_net_id); 642 struct publication *p;
739 643
740 spin_lock_bh(&tn->nametbl_lock); 644 spin_lock_bh(&tn->nametbl_lock);
741 publ = tipc_nametbl_remove_publ(net, type, lower, tipc_own_addr(net), 645
742 port, key); 646 p = tipc_nametbl_remove_publ(net, type, lower, upper, self, key);
743 if (likely(publ)) { 647 if (p) {
744 tn->nametbl->local_publ_count--; 648 nt->local_publ_count--;
745 skb = tipc_named_withdraw(net, publ); 649 skb = tipc_named_withdraw(net, p);
746 /* Any pending external events? */ 650 list_del_init(&p->binding_sock);
747 tipc_named_process_backlog(net); 651 kfree_rcu(p, rcu);
748 list_del_init(&publ->binding_sock);
749 kfree_rcu(publ, rcu);
750 } else { 652 } else {
751 pr_err("Unable to remove local publication\n" 653 pr_err("Failed to remove local publication {%u,%u,%u}/%u\n",
752 "(type=%u, lower=%u, port=%u, key=%u)\n", 654 type, lower, upper, key);
753 type, lower, port, key);
754 } 655 }
755 spin_unlock_bh(&tn->nametbl_lock); 656 spin_unlock_bh(&tn->nametbl_lock);
756 657
@@ -766,27 +667,24 @@ int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower, u32 port,
766 */ 667 */
767void tipc_nametbl_subscribe(struct tipc_subscription *sub) 668void tipc_nametbl_subscribe(struct tipc_subscription *sub)
768{ 669{
670 struct name_table *nt = tipc_name_table(sub->net);
769 struct tipc_net *tn = tipc_net(sub->net); 671 struct tipc_net *tn = tipc_net(sub->net);
770 struct tipc_subscr *s = &sub->evt.s; 672 struct tipc_subscr *s = &sub->evt.s;
771 u32 type = tipc_sub_read(s, seq.type); 673 u32 type = tipc_sub_read(s, seq.type);
772 int index = hash(type); 674 struct tipc_service *sc;
773 struct name_seq *seq;
774 struct tipc_name_seq ns;
775 675
776 spin_lock_bh(&tn->nametbl_lock); 676 spin_lock_bh(&tn->nametbl_lock);
777 seq = nametbl_find_seq(sub->net, type); 677 sc = tipc_service_find(sub->net, type);
778 if (!seq) 678 if (!sc)
779 seq = tipc_nameseq_create(type, &tn->nametbl->seq_hlist[index]); 679 sc = tipc_service_create(type, &nt->services[hash(type)]);
780 if (seq) { 680 if (sc) {
781 spin_lock_bh(&seq->lock); 681 spin_lock_bh(&sc->lock);
782 tipc_nameseq_subscribe(seq, sub); 682 tipc_service_subscribe(sc, sub);
783 spin_unlock_bh(&seq->lock); 683 spin_unlock_bh(&sc->lock);
784 } else { 684 } else {
785 ns.type = tipc_sub_read(s, seq.type); 685 pr_warn("Failed to subscribe for {%u,%u,%u}\n", type,
786 ns.lower = tipc_sub_read(s, seq.lower); 686 tipc_sub_read(s, seq.lower),
787 ns.upper = tipc_sub_read(s, seq.upper); 687 tipc_sub_read(s, seq.upper));
788 pr_warn("Failed to create subscription for {%u,%u,%u}\n",
789 ns.type, ns.lower, ns.upper);
790 } 688 }
791 spin_unlock_bh(&tn->nametbl_lock); 689 spin_unlock_bh(&tn->nametbl_lock);
792} 690}
@@ -796,124 +694,122 @@ void tipc_nametbl_subscribe(struct tipc_subscription *sub)
796 */ 694 */
797void tipc_nametbl_unsubscribe(struct tipc_subscription *sub) 695void tipc_nametbl_unsubscribe(struct tipc_subscription *sub)
798{ 696{
799 struct tipc_subscr *s = &sub->evt.s;
800 struct tipc_net *tn = tipc_net(sub->net); 697 struct tipc_net *tn = tipc_net(sub->net);
801 struct name_seq *seq; 698 struct tipc_subscr *s = &sub->evt.s;
802 u32 type = tipc_sub_read(s, seq.type); 699 u32 type = tipc_sub_read(s, seq.type);
700 struct tipc_service *sc;
803 701
804 spin_lock_bh(&tn->nametbl_lock); 702 spin_lock_bh(&tn->nametbl_lock);
805 seq = nametbl_find_seq(sub->net, type); 703 sc = tipc_service_find(sub->net, type);
806 if (seq != NULL) { 704 if (!sc)
807 spin_lock_bh(&seq->lock); 705 goto exit;
808 list_del_init(&sub->nameseq_list); 706
809 tipc_sub_put(sub); 707 spin_lock_bh(&sc->lock);
810 if (!seq->first_free && list_empty(&seq->subscriptions)) { 708 list_del_init(&sub->service_list);
811 hlist_del_init_rcu(&seq->ns_list); 709 tipc_sub_put(sub);
812 kfree(seq->sseqs); 710
813 spin_unlock_bh(&seq->lock); 711 /* Delete service item if no more publications and subscriptions */
814 kfree_rcu(seq, rcu); 712 if (RB_EMPTY_ROOT(&sc->ranges) && list_empty(&sc->subscriptions)) {
815 } else { 713 hlist_del_init_rcu(&sc->service_list);
816 spin_unlock_bh(&seq->lock); 714 kfree_rcu(sc, rcu);
817 }
818 } 715 }
716 spin_unlock_bh(&sc->lock);
717exit:
819 spin_unlock_bh(&tn->nametbl_lock); 718 spin_unlock_bh(&tn->nametbl_lock);
820} 719}
821 720
822int tipc_nametbl_init(struct net *net) 721int tipc_nametbl_init(struct net *net)
823{ 722{
824 struct tipc_net *tn = net_generic(net, tipc_net_id); 723 struct tipc_net *tn = tipc_net(net);
825 struct name_table *tipc_nametbl; 724 struct name_table *nt;
826 int i; 725 int i;
827 726
828 tipc_nametbl = kzalloc(sizeof(*tipc_nametbl), GFP_ATOMIC); 727 nt = kzalloc(sizeof(*nt), GFP_ATOMIC);
829 if (!tipc_nametbl) 728 if (!nt)
830 return -ENOMEM; 729 return -ENOMEM;
831 730
832 for (i = 0; i < TIPC_NAMETBL_SIZE; i++) 731 for (i = 0; i < TIPC_NAMETBL_SIZE; i++)
833 INIT_HLIST_HEAD(&tipc_nametbl->seq_hlist[i]); 732 INIT_HLIST_HEAD(&nt->services[i]);
834 733
835 INIT_LIST_HEAD(&tipc_nametbl->node_scope); 734 INIT_LIST_HEAD(&nt->node_scope);
836 INIT_LIST_HEAD(&tipc_nametbl->cluster_scope); 735 INIT_LIST_HEAD(&nt->cluster_scope);
837 tn->nametbl = tipc_nametbl; 736 tn->nametbl = nt;
838 spin_lock_init(&tn->nametbl_lock); 737 spin_lock_init(&tn->nametbl_lock);
839 return 0; 738 return 0;
840} 739}
841 740
842/** 741/**
843 * tipc_purge_publications - remove all publications for a given type 742 * tipc_service_delete - purge all publications for a service and delete it
844 *
845 * tipc_nametbl_lock must be held when calling this function
846 */ 743 */
847static void tipc_purge_publications(struct net *net, struct name_seq *seq) 744static void tipc_service_delete(struct net *net, struct tipc_service *sc)
848{ 745{
849 struct publication *publ, *safe; 746 struct service_range *sr, *tmpr;
850 struct sub_seq *sseq; 747 struct publication *p, *tmpb;
851 struct name_info *info; 748
852 749 spin_lock_bh(&sc->lock);
853 spin_lock_bh(&seq->lock); 750 rbtree_postorder_for_each_entry_safe(sr, tmpr, &sc->ranges, tree_node) {
854 sseq = seq->sseqs; 751 list_for_each_entry_safe(p, tmpb,
855 info = sseq->info; 752 &sr->all_publ, all_publ) {
856 list_for_each_entry_safe(publ, safe, &info->all_publ, all_publ) { 753 tipc_service_remove_publ(net, sc, p->lower, p->upper,
857 tipc_nameseq_remove_publ(net, seq, publ->lower, publ->node, 754 p->node, p->key);
858 publ->port, publ->key); 755 kfree_rcu(p, rcu);
859 kfree_rcu(publ, rcu); 756 }
860 } 757 }
861 hlist_del_init_rcu(&seq->ns_list); 758 hlist_del_init_rcu(&sc->service_list);
862 kfree(seq->sseqs); 759 spin_unlock_bh(&sc->lock);
863 spin_unlock_bh(&seq->lock); 760 kfree_rcu(sc, rcu);
864
865 kfree_rcu(seq, rcu);
866} 761}
867 762
868void tipc_nametbl_stop(struct net *net) 763void tipc_nametbl_stop(struct net *net)
869{ 764{
765 struct name_table *nt = tipc_name_table(net);
766 struct tipc_net *tn = tipc_net(net);
767 struct hlist_head *service_head;
768 struct tipc_service *service;
870 u32 i; 769 u32 i;
871 struct name_seq *seq;
872 struct hlist_head *seq_head;
873 struct tipc_net *tn = net_generic(net, tipc_net_id);
874 struct name_table *tipc_nametbl = tn->nametbl;
875 770
876 /* Verify name table is empty and purge any lingering 771 /* Verify name table is empty and purge any lingering
877 * publications, then release the name table 772 * publications, then release the name table
878 */ 773 */
879 spin_lock_bh(&tn->nametbl_lock); 774 spin_lock_bh(&tn->nametbl_lock);
880 for (i = 0; i < TIPC_NAMETBL_SIZE; i++) { 775 for (i = 0; i < TIPC_NAMETBL_SIZE; i++) {
881 if (hlist_empty(&tipc_nametbl->seq_hlist[i])) 776 if (hlist_empty(&nt->services[i]))
882 continue; 777 continue;
883 seq_head = &tipc_nametbl->seq_hlist[i]; 778 service_head = &nt->services[i];
884 hlist_for_each_entry_rcu(seq, seq_head, ns_list) { 779 hlist_for_each_entry_rcu(service, service_head, service_list) {
885 tipc_purge_publications(net, seq); 780 tipc_service_delete(net, service);
886 } 781 }
887 } 782 }
888 spin_unlock_bh(&tn->nametbl_lock); 783 spin_unlock_bh(&tn->nametbl_lock);
889 784
890 synchronize_net(); 785 synchronize_net();
891 kfree(tipc_nametbl); 786 kfree(nt);
892
893} 787}
894 788
895static int __tipc_nl_add_nametable_publ(struct tipc_nl_msg *msg, 789static int __tipc_nl_add_nametable_publ(struct tipc_nl_msg *msg,
896 struct name_seq *seq, 790 struct tipc_service *service,
897 struct sub_seq *sseq, u32 *last_publ) 791 struct service_range *sr,
792 u32 *last_key)
898{ 793{
899 void *hdr;
900 struct nlattr *attrs;
901 struct nlattr *publ;
902 struct publication *p; 794 struct publication *p;
795 struct nlattr *attrs;
796 struct nlattr *b;
797 void *hdr;
903 798
904 if (*last_publ) { 799 if (*last_key) {
905 list_for_each_entry(p, &sseq->info->all_publ, all_publ) 800 list_for_each_entry(p, &sr->all_publ, all_publ)
906 if (p->key == *last_publ) 801 if (p->key == *last_key)
907 break; 802 break;
908 if (p->key != *last_publ) 803 if (p->key != *last_key)
909 return -EPIPE; 804 return -EPIPE;
910 } else { 805 } else {
911 p = list_first_entry(&sseq->info->all_publ, struct publication, 806 p = list_first_entry(&sr->all_publ,
807 struct publication,
912 all_publ); 808 all_publ);
913 } 809 }
914 810
915 list_for_each_entry_from(p, &sseq->info->all_publ, all_publ) { 811 list_for_each_entry_from(p, &sr->all_publ, all_publ) {
916 *last_publ = p->key; 812 *last_key = p->key;
917 813
918 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, 814 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq,
919 &tipc_genl_family, NLM_F_MULTI, 815 &tipc_genl_family, NLM_F_MULTI,
@@ -925,15 +821,15 @@ static int __tipc_nl_add_nametable_publ(struct tipc_nl_msg *msg,
925 if (!attrs) 821 if (!attrs)
926 goto msg_full; 822 goto msg_full;
927 823
928 publ = nla_nest_start(msg->skb, TIPC_NLA_NAME_TABLE_PUBL); 824 b = nla_nest_start(msg->skb, TIPC_NLA_NAME_TABLE_PUBL);
929 if (!publ) 825 if (!b)
930 goto attr_msg_full; 826 goto attr_msg_full;
931 827
932 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_TYPE, seq->type)) 828 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_TYPE, service->type))
933 goto publ_msg_full; 829 goto publ_msg_full;
934 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_LOWER, sseq->lower)) 830 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_LOWER, sr->lower))
935 goto publ_msg_full; 831 goto publ_msg_full;
936 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_UPPER, sseq->upper)) 832 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_UPPER, sr->upper))
937 goto publ_msg_full; 833 goto publ_msg_full;
938 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_SCOPE, p->scope)) 834 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_SCOPE, p->scope))
939 goto publ_msg_full; 835 goto publ_msg_full;
@@ -944,16 +840,16 @@ static int __tipc_nl_add_nametable_publ(struct tipc_nl_msg *msg,
944 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_KEY, p->key)) 840 if (nla_put_u32(msg->skb, TIPC_NLA_PUBL_KEY, p->key))
945 goto publ_msg_full; 841 goto publ_msg_full;
946 842
947 nla_nest_end(msg->skb, publ); 843 nla_nest_end(msg->skb, b);
948 nla_nest_end(msg->skb, attrs); 844 nla_nest_end(msg->skb, attrs);
949 genlmsg_end(msg->skb, hdr); 845 genlmsg_end(msg->skb, hdr);
950 } 846 }
951 *last_publ = 0; 847 *last_key = 0;
952 848
953 return 0; 849 return 0;
954 850
955publ_msg_full: 851publ_msg_full:
956 nla_nest_cancel(msg->skb, publ); 852 nla_nest_cancel(msg->skb, b);
957attr_msg_full: 853attr_msg_full:
958 nla_nest_cancel(msg->skb, attrs); 854 nla_nest_cancel(msg->skb, attrs);
959msg_full: 855msg_full:
@@ -962,39 +858,34 @@ msg_full:
962 return -EMSGSIZE; 858 return -EMSGSIZE;
963} 859}
964 860
965static int __tipc_nl_subseq_list(struct tipc_nl_msg *msg, struct name_seq *seq, 861static int __tipc_nl_service_range_list(struct tipc_nl_msg *msg,
966 u32 *last_lower, u32 *last_publ) 862 struct tipc_service *sc,
863 u32 *last_lower, u32 *last_key)
967{ 864{
968 struct sub_seq *sseq; 865 struct service_range *sr;
969 struct sub_seq *sseq_start; 866 struct rb_node *n;
970 int err; 867 int err;
971 868
972 if (*last_lower) { 869 for (n = rb_first(&sc->ranges); n; n = rb_next(n)) {
973 sseq_start = nameseq_find_subseq(seq, *last_lower); 870 sr = container_of(n, struct service_range, tree_node);
974 if (!sseq_start) 871 if (sr->lower < *last_lower)
975 return -EPIPE; 872 continue;
976 } else { 873 err = __tipc_nl_add_nametable_publ(msg, sc, sr, last_key);
977 sseq_start = seq->sseqs;
978 }
979
980 for (sseq = sseq_start; sseq != &seq->sseqs[seq->first_free]; sseq++) {
981 err = __tipc_nl_add_nametable_publ(msg, seq, sseq, last_publ);
982 if (err) { 874 if (err) {
983 *last_lower = sseq->lower; 875 *last_lower = sr->lower;
984 return err; 876 return err;
985 } 877 }
986 } 878 }
987 *last_lower = 0; 879 *last_lower = 0;
988
989 return 0; 880 return 0;
990} 881}
991 882
992static int tipc_nl_seq_list(struct net *net, struct tipc_nl_msg *msg, 883static int tipc_nl_service_list(struct net *net, struct tipc_nl_msg *msg,
993 u32 *last_type, u32 *last_lower, u32 *last_publ) 884 u32 *last_type, u32 *last_lower, u32 *last_key)
994{ 885{
995 struct tipc_net *tn = net_generic(net, tipc_net_id); 886 struct tipc_net *tn = tipc_net(net);
996 struct hlist_head *seq_head; 887 struct tipc_service *service = NULL;
997 struct name_seq *seq = NULL; 888 struct hlist_head *head;
998 int err; 889 int err;
999 int i; 890 int i;
1000 891
@@ -1004,30 +895,31 @@ static int tipc_nl_seq_list(struct net *net, struct tipc_nl_msg *msg,
1004 i = 0; 895 i = 0;
1005 896
1006 for (; i < TIPC_NAMETBL_SIZE; i++) { 897 for (; i < TIPC_NAMETBL_SIZE; i++) {
1007 seq_head = &tn->nametbl->seq_hlist[i]; 898 head = &tn->nametbl->services[i];
1008 899
1009 if (*last_type) { 900 if (*last_type) {
1010 seq = nametbl_find_seq(net, *last_type); 901 service = tipc_service_find(net, *last_type);
1011 if (!seq) 902 if (!service)
1012 return -EPIPE; 903 return -EPIPE;
1013 } else { 904 } else {
1014 hlist_for_each_entry_rcu(seq, seq_head, ns_list) 905 hlist_for_each_entry_rcu(service, head, service_list)
1015 break; 906 break;
1016 if (!seq) 907 if (!service)
1017 continue; 908 continue;
1018 } 909 }
1019 910
1020 hlist_for_each_entry_from_rcu(seq, ns_list) { 911 hlist_for_each_entry_from_rcu(service, service_list) {
1021 spin_lock_bh(&seq->lock); 912 spin_lock_bh(&service->lock);
1022 err = __tipc_nl_subseq_list(msg, seq, last_lower, 913 err = __tipc_nl_service_range_list(msg, service,
1023 last_publ); 914 last_lower,
915 last_key);
1024 916
1025 if (err) { 917 if (err) {
1026 *last_type = seq->type; 918 *last_type = service->type;
1027 spin_unlock_bh(&seq->lock); 919 spin_unlock_bh(&service->lock);
1028 return err; 920 return err;
1029 } 921 }
1030 spin_unlock_bh(&seq->lock); 922 spin_unlock_bh(&service->lock);
1031 } 923 }
1032 *last_type = 0; 924 *last_type = 0;
1033 } 925 }
@@ -1036,13 +928,13 @@ static int tipc_nl_seq_list(struct net *net, struct tipc_nl_msg *msg,
1036 928
1037int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb) 929int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb)
1038{ 930{
1039 int err; 931 struct net *net = sock_net(skb->sk);
1040 int done = cb->args[3];
1041 u32 last_type = cb->args[0]; 932 u32 last_type = cb->args[0];
1042 u32 last_lower = cb->args[1]; 933 u32 last_lower = cb->args[1];
1043 u32 last_publ = cb->args[2]; 934 u32 last_key = cb->args[2];
1044 struct net *net = sock_net(skb->sk); 935 int done = cb->args[3];
1045 struct tipc_nl_msg msg; 936 struct tipc_nl_msg msg;
937 int err;
1046 938
1047 if (done) 939 if (done)
1048 return 0; 940 return 0;
@@ -1052,7 +944,8 @@ int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb)
1052 msg.seq = cb->nlh->nlmsg_seq; 944 msg.seq = cb->nlh->nlmsg_seq;
1053 945
1054 rcu_read_lock(); 946 rcu_read_lock();
1055 err = tipc_nl_seq_list(net, &msg, &last_type, &last_lower, &last_publ); 947 err = tipc_nl_service_list(net, &msg, &last_type,
948 &last_lower, &last_key);
1056 if (!err) { 949 if (!err) {
1057 done = 1; 950 done = 1;
1058 } else if (err != -EMSGSIZE) { 951 } else if (err != -EMSGSIZE) {
@@ -1068,7 +961,7 @@ int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb)
1068 961
1069 cb->args[0] = last_type; 962 cb->args[0] = last_type;
1070 cb->args[1] = last_lower; 963 cb->args[1] = last_lower;
1071 cb->args[2] = last_publ; 964 cb->args[2] = last_key;
1072 cb->args[3] = done; 965 cb->args[3] = done;
1073 966
1074 return skb->len; 967 return skb->len;
diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h
index 34a4ccb907aa..4b14fc28d9e2 100644
--- a/net/tipc/name_table.h
+++ b/net/tipc/name_table.h
@@ -97,7 +97,7 @@ struct publication {
97 * @local_publ_count: number of publications issued by this node 97 * @local_publ_count: number of publications issued by this node
98 */ 98 */
99struct name_table { 99struct name_table {
100 struct hlist_head seq_hlist[TIPC_NAMETBL_SIZE]; 100 struct hlist_head services[TIPC_NAMETBL_SIZE];
101 struct list_head node_scope; 101 struct list_head node_scope;
102 struct list_head cluster_scope; 102 struct list_head cluster_scope;
103 u32 local_publ_count; 103 u32 local_publ_count;
@@ -116,16 +116,16 @@ bool tipc_nametbl_lookup(struct net *net, u32 type, u32 instance, u32 domain,
116 struct list_head *dsts, int *dstcnt, u32 exclude, 116 struct list_head *dsts, int *dstcnt, u32 exclude,
117 bool all); 117 bool all);
118struct publication *tipc_nametbl_publish(struct net *net, u32 type, u32 lower, 118struct publication *tipc_nametbl_publish(struct net *net, u32 type, u32 lower,
119 u32 upper, u32 scope, u32 port_ref, 119 u32 upper, u32 scope, u32 port,
120 u32 key); 120 u32 key);
121int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower, u32 ref, 121int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower, u32 upper,
122 u32 key); 122 u32 key);
123struct publication *tipc_nametbl_insert_publ(struct net *net, u32 type, 123struct publication *tipc_nametbl_insert_publ(struct net *net, u32 type,
124 u32 lower, u32 upper, u32 scope, 124 u32 lower, u32 upper, u32 scope,
125 u32 node, u32 ref, u32 key); 125 u32 node, u32 ref, u32 key);
126struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type, 126struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type,
127 u32 lower, u32 node, u32 ref, 127 u32 lower, u32 upper,
128 u32 key); 128 u32 node, u32 key);
129void tipc_nametbl_subscribe(struct tipc_subscription *s); 129void tipc_nametbl_subscribe(struct tipc_subscription *s);
130void tipc_nametbl_unsubscribe(struct tipc_subscription *s); 130void tipc_nametbl_unsubscribe(struct tipc_subscription *s);
131int tipc_nametbl_init(struct net *net); 131int tipc_nametbl_init(struct net *net);
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 29538dc00857..856f9e97ea29 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -136,7 +136,7 @@ void tipc_net_stop(struct net *net)
136 if (!self) 136 if (!self)
137 return; 137 return;
138 138
139 tipc_nametbl_withdraw(net, TIPC_CFG_SRV, self, 0, self); 139 tipc_nametbl_withdraw(net, TIPC_CFG_SRV, self, self, self);
140 rtnl_lock(); 140 rtnl_lock();
141 tipc_bearer_stop(net); 141 tipc_bearer_stop(net);
142 tipc_node_stop(net); 142 tipc_node_stop(net);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 4fb4327311bb..c77dd2f3c589 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -324,12 +324,12 @@ static void tipc_node_write_unlock(struct tipc_node *n)
324 if (flags & TIPC_NOTIFY_LINK_UP) { 324 if (flags & TIPC_NOTIFY_LINK_UP) {
325 tipc_mon_peer_up(net, addr, bearer_id); 325 tipc_mon_peer_up(net, addr, bearer_id);
326 tipc_nametbl_publish(net, TIPC_LINK_STATE, addr, addr, 326 tipc_nametbl_publish(net, TIPC_LINK_STATE, addr, addr,
327 TIPC_NODE_SCOPE, link_id, addr); 327 TIPC_NODE_SCOPE, link_id, link_id);
328 } 328 }
329 if (flags & TIPC_NOTIFY_LINK_DOWN) { 329 if (flags & TIPC_NOTIFY_LINK_DOWN) {
330 tipc_mon_peer_down(net, addr, bearer_id); 330 tipc_mon_peer_down(net, addr, bearer_id);
331 tipc_nametbl_withdraw(net, TIPC_LINK_STATE, addr, 331 tipc_nametbl_withdraw(net, TIPC_LINK_STATE, addr,
332 link_id, addr); 332 addr, link_id);
333 } 333 }
334} 334}
335 335
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 275b666f6231..3e5eba30865e 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -2634,12 +2634,12 @@ static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope,
2634 if (publ->upper != seq->upper) 2634 if (publ->upper != seq->upper)
2635 break; 2635 break;
2636 tipc_nametbl_withdraw(net, publ->type, publ->lower, 2636 tipc_nametbl_withdraw(net, publ->type, publ->lower,
2637 publ->port, publ->key); 2637 publ->upper, publ->key);
2638 rc = 0; 2638 rc = 0;
2639 break; 2639 break;
2640 } 2640 }
2641 tipc_nametbl_withdraw(net, publ->type, publ->lower, 2641 tipc_nametbl_withdraw(net, publ->type, publ->lower,
2642 publ->port, publ->key); 2642 publ->upper, publ->key);
2643 rc = 0; 2643 rc = 0;
2644 } 2644 }
2645 if (list_empty(&tsk->publications)) 2645 if (list_empty(&tsk->publications))
diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h
index 8b2d22b18f22..d793b4343885 100644
--- a/net/tipc/subscr.h
+++ b/net/tipc/subscr.h
@@ -40,7 +40,7 @@
40#include "topsrv.h" 40#include "topsrv.h"
41 41
42#define TIPC_MAX_SUBSCR 65535 42#define TIPC_MAX_SUBSCR 65535
43#define TIPC_MAX_PUBLICATIONS 65535 43#define TIPC_MAX_PUBL 65535
44 44
45struct tipc_subscription; 45struct tipc_subscription;
46struct tipc_conn; 46struct tipc_conn;
@@ -58,7 +58,7 @@ struct tipc_subscription {
58 struct kref kref; 58 struct kref kref;
59 struct net *net; 59 struct net *net;
60 struct timer_list timer; 60 struct timer_list timer;
61 struct list_head nameseq_list; 61 struct list_head service_list;
62 struct list_head sub_list; 62 struct list_head sub_list;
63 struct tipc_event evt; 63 struct tipc_event evt;
64 int conid; 64 int conid;