Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[firefly-linux-kernel-4.4.55.git] / net / tipc / name_table.c
1 /*
2  * net/tipc/name_table.c: TIPC name table code
3  *
4  * Copyright (c) 2000-2006, Ericsson AB
5  * Copyright (c) 2004-2008, 2010-2011, Wind River Systems
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the names of the copyright holders nor the names of its
17  *    contributors may be used to endorse or promote products derived from
18  *    this software without specific prior written permission.
19  *
20  * Alternatively, this software may be distributed under the terms of the
21  * GNU General Public License ("GPL") version 2 as published by the Free
22  * Software Foundation.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  */
36
37 #include "core.h"
38 #include "config.h"
39 #include "name_table.h"
40 #include "name_distr.h"
41 #include "subscr.h"
42 #include "port.h"
43
44 static int tipc_nametbl_size = 1024;            /* must be a power of 2 */
45
46 /**
47  * struct name_info - name sequence publication info
48  * @node_list: circular list of publications made by own node
49  * @cluster_list: circular list of publications made by own cluster
50  * @zone_list: circular list of publications made by own zone
51  * @node_list_size: number of entries in "node_list"
52  * @cluster_list_size: number of entries in "cluster_list"
53  * @zone_list_size: number of entries in "zone_list"
54  *
55  * Note: The zone list always contains at least one entry, since all
56  *       publications of the associated name sequence belong to it.
57  *       (The cluster and node lists may be empty.)
58  */
59
60 struct name_info {
61         struct list_head node_list;
62         struct list_head cluster_list;
63         struct list_head zone_list;
64         u32 node_list_size;
65         u32 cluster_list_size;
66         u32 zone_list_size;
67 };
68
69 /**
70  * struct sub_seq - container for all published instances of a name sequence
71  * @lower: name sequence lower bound
72  * @upper: name sequence upper bound
73  * @info: pointer to name sequence publication info
74  */
75
76 struct sub_seq {
77         u32 lower;
78         u32 upper;
79         struct name_info *info;
80 };
81
82 /**
83  * struct name_seq - container for all published instances of a name type
84  * @type: 32 bit 'type' value for name sequence
85  * @sseq: pointer to dynamically-sized array of sub-sequences of this 'type';
86  *        sub-sequences are sorted in ascending order
87  * @alloc: number of sub-sequences currently in array
88  * @first_free: array index of first unused sub-sequence entry
89  * @ns_list: links to adjacent name sequences in hash chain
90  * @subscriptions: list of subscriptions for this 'type'
91  * @lock: spinlock controlling access to publication lists of all sub-sequences
92  */
93
94 struct name_seq {
95         u32 type;
96         struct sub_seq *sseqs;
97         u32 alloc;
98         u32 first_free;
99         struct hlist_node ns_list;
100         struct list_head subscriptions;
101         spinlock_t lock;
102 };
103
104 /**
105  * struct name_table - table containing all existing port name publications
106  * @types: pointer to fixed-sized array of name sequence lists,
107  *         accessed via hashing on 'type'; name sequence lists are *not* sorted
108  * @local_publ_count: number of publications issued by this node
109  */
110
111 struct name_table {
112         struct hlist_head *types;
113         u32 local_publ_count;
114 };
115
116 static struct name_table table;
117 DEFINE_RWLOCK(tipc_nametbl_lock);
118
119 static int hash(int x)
120 {
121         return x & (tipc_nametbl_size - 1);
122 }
123
124 /**
125  * publ_create - create a publication structure
126  */
127
128 static struct publication *publ_create(u32 type, u32 lower, u32 upper,
129                                        u32 scope, u32 node, u32 port_ref,
130                                        u32 key)
131 {
132         struct publication *publ = kzalloc(sizeof(*publ), GFP_ATOMIC);
133         if (publ == NULL) {
134                 warn("Publication creation failure, no memory\n");
135                 return NULL;
136         }
137
138         publ->type = type;
139         publ->lower = lower;
140         publ->upper = upper;
141         publ->scope = scope;
142         publ->node = node;
143         publ->ref = port_ref;
144         publ->key = key;
145         INIT_LIST_HEAD(&publ->local_list);
146         INIT_LIST_HEAD(&publ->pport_list);
147         INIT_LIST_HEAD(&publ->subscr.nodesub_list);
148         return publ;
149 }
150
151 /**
152  * tipc_subseq_alloc - allocate a specified number of sub-sequence structures
153  */
154
155 static struct sub_seq *tipc_subseq_alloc(u32 cnt)
156 {
157         struct sub_seq *sseq = kcalloc(cnt, sizeof(struct sub_seq), GFP_ATOMIC);
158         return sseq;
159 }
160
161 /**
162  * tipc_nameseq_create - create a name sequence structure for the specified 'type'
163  *
164  * Allocates a single sub-sequence structure and sets it to all 0's.
165  */
166
167 static struct name_seq *tipc_nameseq_create(u32 type, struct hlist_head *seq_head)
168 {
169         struct name_seq *nseq = kzalloc(sizeof(*nseq), GFP_ATOMIC);
170         struct sub_seq *sseq = tipc_subseq_alloc(1);
171
172         if (!nseq || !sseq) {
173                 warn("Name sequence creation failed, no memory\n");
174                 kfree(nseq);
175                 kfree(sseq);
176                 return NULL;
177         }
178
179         spin_lock_init(&nseq->lock);
180         nseq->type = type;
181         nseq->sseqs = sseq;
182         nseq->alloc = 1;
183         INIT_HLIST_NODE(&nseq->ns_list);
184         INIT_LIST_HEAD(&nseq->subscriptions);
185         hlist_add_head(&nseq->ns_list, seq_head);
186         return nseq;
187 }
188
189 /**
190  * nameseq_find_subseq - find sub-sequence (if any) matching a name instance
191  *
192  * Very time-critical, so binary searches through sub-sequence array.
193  */
194
195 static struct sub_seq *nameseq_find_subseq(struct name_seq *nseq,
196                                            u32 instance)
197 {
198         struct sub_seq *sseqs = nseq->sseqs;
199         int low = 0;
200         int high = nseq->first_free - 1;
201         int mid;
202
203         while (low <= high) {
204                 mid = (low + high) / 2;
205                 if (instance < sseqs[mid].lower)
206                         high = mid - 1;
207                 else if (instance > sseqs[mid].upper)
208                         low = mid + 1;
209                 else
210                         return &sseqs[mid];
211         }
212         return NULL;
213 }
214
215 /**
216  * nameseq_locate_subseq - determine position of name instance in sub-sequence
217  *
218  * Returns index in sub-sequence array of the entry that contains the specified
219  * instance value; if no entry contains that value, returns the position
220  * where a new entry for it would be inserted in the array.
221  *
222  * Note: Similar to binary search code for locating a sub-sequence.
223  */
224
225 static u32 nameseq_locate_subseq(struct name_seq *nseq, u32 instance)
226 {
227         struct sub_seq *sseqs = nseq->sseqs;
228         int low = 0;
229         int high = nseq->first_free - 1;
230         int mid;
231
232         while (low <= high) {
233                 mid = (low + high) / 2;
234                 if (instance < sseqs[mid].lower)
235                         high = mid - 1;
236                 else if (instance > sseqs[mid].upper)
237                         low = mid + 1;
238                 else
239                         return mid;
240         }
241         return low;
242 }
243
244 /**
245  * tipc_nameseq_insert_publ -
246  */
247
248 static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
249                                                     u32 type, u32 lower, u32 upper,
250                                                     u32 scope, u32 node, u32 port, u32 key)
251 {
252         struct tipc_subscription *s;
253         struct tipc_subscription *st;
254         struct publication *publ;
255         struct sub_seq *sseq;
256         struct name_info *info;
257         int created_subseq = 0;
258
259         sseq = nameseq_find_subseq(nseq, lower);
260         if (sseq) {
261
262                 /* Lower end overlaps existing entry => need an exact match */
263
264                 if ((sseq->lower != lower) || (sseq->upper != upper)) {
265                         warn("Cannot publish {%u,%u,%u}, overlap error\n",
266                              type, lower, upper);
267                         return NULL;
268                 }
269
270                 info = sseq->info;
271
272                 /* Check if an identical publication already exists */
273                 list_for_each_entry(publ, &info->zone_list, zone_list) {
274                         if ((publ->ref == port) && (publ->key == key) &&
275                             (!publ->node || (publ->node == node)))
276                                 return NULL;
277                 }
278         } else {
279                 u32 inspos;
280                 struct sub_seq *freesseq;
281
282                 /* Find where lower end should be inserted */
283
284                 inspos = nameseq_locate_subseq(nseq, lower);
285
286                 /* Fail if upper end overlaps into an existing entry */
287
288                 if ((inspos < nseq->first_free) &&
289                     (upper >= nseq->sseqs[inspos].lower)) {
290                         warn("Cannot publish {%u,%u,%u}, overlap error\n",
291                              type, lower, upper);
292                         return NULL;
293                 }
294
295                 /* Ensure there is space for new sub-sequence */
296
297                 if (nseq->first_free == nseq->alloc) {
298                         struct sub_seq *sseqs = tipc_subseq_alloc(nseq->alloc * 2);
299
300                         if (!sseqs) {
301                                 warn("Cannot publish {%u,%u,%u}, no memory\n",
302                                      type, lower, upper);
303                                 return NULL;
304                         }
305                         memcpy(sseqs, nseq->sseqs,
306                                nseq->alloc * sizeof(struct sub_seq));
307                         kfree(nseq->sseqs);
308                         nseq->sseqs = sseqs;
309                         nseq->alloc *= 2;
310                 }
311
312                 info = kzalloc(sizeof(*info), GFP_ATOMIC);
313                 if (!info) {
314                         warn("Cannot publish {%u,%u,%u}, no memory\n",
315                              type, lower, upper);
316                         return NULL;
317                 }
318
319                 INIT_LIST_HEAD(&info->node_list);
320                 INIT_LIST_HEAD(&info->cluster_list);
321                 INIT_LIST_HEAD(&info->zone_list);
322
323                 /* Insert new sub-sequence */
324
325                 sseq = &nseq->sseqs[inspos];
326                 freesseq = &nseq->sseqs[nseq->first_free];
327                 memmove(sseq + 1, sseq, (freesseq - sseq) * sizeof(*sseq));
328                 memset(sseq, 0, sizeof(*sseq));
329                 nseq->first_free++;
330                 sseq->lower = lower;
331                 sseq->upper = upper;
332                 sseq->info = info;
333                 created_subseq = 1;
334         }
335
336         /* Insert a publication: */
337
338         publ = publ_create(type, lower, upper, scope, node, port, key);
339         if (!publ)
340                 return NULL;
341
342         list_add(&publ->zone_list, &info->zone_list);
343         info->zone_list_size++;
344
345         if (in_own_cluster(node)) {
346                 list_add(&publ->cluster_list, &info->cluster_list);
347                 info->cluster_list_size++;
348         }
349
350         if (in_own_node(node)) {
351                 list_add(&publ->node_list, &info->node_list);
352                 info->node_list_size++;
353         }
354
355         /*
356          * Any subscriptions waiting for notification?
357          */
358         list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) {
359                 tipc_subscr_report_overlap(s,
360                                            publ->lower,
361                                            publ->upper,
362                                            TIPC_PUBLISHED,
363                                            publ->ref,
364                                            publ->node,
365                                            created_subseq);
366         }
367         return publ;
368 }
369
370 /**
371  * tipc_nameseq_remove_publ -
372  *
373  * NOTE: There may be cases where TIPC is asked to remove a publication
374  * that is not in the name table.  For example, if another node issues a
375  * publication for a name sequence that overlaps an existing name sequence
376  * the publication will not be recorded, which means the publication won't
377  * be found when the name sequence is later withdrawn by that node.
378  * A failed withdraw request simply returns a failure indication and lets the
379  * caller issue any error or warning messages associated with such a problem.
380  */
381
382 static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 inst,
383                                                     u32 node, u32 ref, u32 key)
384 {
385         struct publication *publ;
386         struct sub_seq *sseq = nameseq_find_subseq(nseq, inst);
387         struct name_info *info;
388         struct sub_seq *free;
389         struct tipc_subscription *s, *st;
390         int removed_subseq = 0;
391
392         if (!sseq)
393                 return NULL;
394
395         info = sseq->info;
396
397         /* Locate publication, if it exists */
398
399         list_for_each_entry(publ, &info->zone_list, zone_list) {
400                 if ((publ->key == key) && (publ->ref == ref) &&
401                     (!publ->node || (publ->node == node)))
402                         goto found;
403         }
404         return NULL;
405
406 found:
407         /* Remove publication from zone scope list */
408
409         list_del(&publ->zone_list);
410         info->zone_list_size--;
411
412         /* Remove publication from cluster scope list, if present */
413
414         if (in_own_cluster(node)) {
415                 list_del(&publ->cluster_list);
416                 info->cluster_list_size--;
417         }
418
419         /* Remove publication from node scope list, if present */
420
421         if (in_own_node(node)) {
422                 list_del(&publ->node_list);
423                 info->node_list_size--;
424         }
425
426         /* Contract subseq list if no more publications for that subseq */
427
428         if (list_empty(&info->zone_list)) {
429                 kfree(info);
430                 free = &nseq->sseqs[nseq->first_free--];
431                 memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof(*sseq));
432                 removed_subseq = 1;
433         }
434
435         /* Notify any waiting subscriptions */
436
437         list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) {
438                 tipc_subscr_report_overlap(s,
439                                            publ->lower,
440                                            publ->upper,
441                                            TIPC_WITHDRAWN,
442                                            publ->ref,
443                                            publ->node,
444                                            removed_subseq);
445         }
446
447         return publ;
448 }
449
450 /**
451  * tipc_nameseq_subscribe: attach a subscription, and issue
452  * the prescribed number of events if there is any sub-
453  * sequence overlapping with the requested sequence
454  */
455
456 static void tipc_nameseq_subscribe(struct name_seq *nseq,
457                                         struct tipc_subscription *s)
458 {
459         struct sub_seq *sseq = nseq->sseqs;
460
461         list_add(&s->nameseq_list, &nseq->subscriptions);
462
463         if (!sseq)
464                 return;
465
466         while (sseq != &nseq->sseqs[nseq->first_free]) {
467                 if (tipc_subscr_overlap(s, sseq->lower, sseq->upper)) {
468                         struct publication *crs;
469                         struct name_info *info = sseq->info;
470                         int must_report = 1;
471
472                         list_for_each_entry(crs, &info->zone_list, zone_list) {
473                                 tipc_subscr_report_overlap(s,
474                                                            sseq->lower,
475                                                            sseq->upper,
476                                                            TIPC_PUBLISHED,
477                                                            crs->ref,
478                                                            crs->node,
479                                                            must_report);
480                                 must_report = 0;
481                         }
482                 }
483                 sseq++;
484         }
485 }
486
487 static struct name_seq *nametbl_find_seq(u32 type)
488 {
489         struct hlist_head *seq_head;
490         struct hlist_node *seq_node;
491         struct name_seq *ns;
492
493         seq_head = &table.types[hash(type)];
494         hlist_for_each_entry(ns, seq_node, seq_head, ns_list) {
495                 if (ns->type == type)
496                         return ns;
497         }
498
499         return NULL;
500 };
501
502 struct publication *tipc_nametbl_insert_publ(u32 type, u32 lower, u32 upper,
503                                              u32 scope, u32 node, u32 port, u32 key)
504 {
505         struct name_seq *seq = nametbl_find_seq(type);
506
507         if (lower > upper) {
508                 warn("Failed to publish illegal {%u,%u,%u}\n",
509                      type, lower, upper);
510                 return NULL;
511         }
512
513         if (!seq)
514                 seq = tipc_nameseq_create(type, &table.types[hash(type)]);
515         if (!seq)
516                 return NULL;
517
518         return tipc_nameseq_insert_publ(seq, type, lower, upper,
519                                         scope, node, port, key);
520 }
521
522 struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower,
523                                              u32 node, u32 ref, u32 key)
524 {
525         struct publication *publ;
526         struct name_seq *seq = nametbl_find_seq(type);
527
528         if (!seq)
529                 return NULL;
530
531         publ = tipc_nameseq_remove_publ(seq, lower, node, ref, key);
532
533         if (!seq->first_free && list_empty(&seq->subscriptions)) {
534                 hlist_del_init(&seq->ns_list);
535                 kfree(seq->sseqs);
536                 kfree(seq);
537         }
538         return publ;
539 }
540
541 /*
542  * tipc_nametbl_translate - perform name translation
543  *
544  * On entry, 'destnode' is the search domain used during translation.
545  *
546  * On exit:
547  * - if name translation is deferred to another node/cluster/zone,
548  *   leaves 'destnode' unchanged (will be non-zero) and returns 0
549  * - if name translation is attempted and succeeds, sets 'destnode'
550  *   to publishing node and returns port reference (will be non-zero)
551  * - if name translation is attempted and fails, sets 'destnode' to 0
552  *   and returns 0
553  */
554
555 u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode)
556 {
557         struct sub_seq *sseq;
558         struct name_info *info;
559         struct publication *publ;
560         struct name_seq *seq;
561         u32 ref = 0;
562         u32 node = 0;
563
564         if (!tipc_in_scope(*destnode, tipc_own_addr))
565                 return 0;
566
567         read_lock_bh(&tipc_nametbl_lock);
568         seq = nametbl_find_seq(type);
569         if (unlikely(!seq))
570                 goto not_found;
571         sseq = nameseq_find_subseq(seq, instance);
572         if (unlikely(!sseq))
573                 goto not_found;
574         spin_lock_bh(&seq->lock);
575         info = sseq->info;
576
577         /* Closest-First Algorithm: */
578         if (likely(!*destnode)) {
579                 if (!list_empty(&info->node_list)) {
580                         publ = list_first_entry(&info->node_list,
581                                                 struct publication,
582                                                 node_list);
583                         list_move_tail(&publ->node_list,
584                                        &info->node_list);
585                 } else if (!list_empty(&info->cluster_list)) {
586                         publ = list_first_entry(&info->cluster_list,
587                                                 struct publication,
588                                                 cluster_list);
589                         list_move_tail(&publ->cluster_list,
590                                        &info->cluster_list);
591                 } else {
592                         publ = list_first_entry(&info->zone_list,
593                                                 struct publication,
594                                                 zone_list);
595                         list_move_tail(&publ->zone_list,
596                                        &info->zone_list);
597                 }
598         }
599
600         /* Round-Robin Algorithm: */
601         else if (*destnode == tipc_own_addr) {
602                 if (list_empty(&info->node_list))
603                         goto no_match;
604                 publ = list_first_entry(&info->node_list, struct publication,
605                                         node_list);
606                 list_move_tail(&publ->node_list, &info->node_list);
607         } else if (in_own_cluster_exact(*destnode)) {
608                 if (list_empty(&info->cluster_list))
609                         goto no_match;
610                 publ = list_first_entry(&info->cluster_list, struct publication,
611                                         cluster_list);
612                 list_move_tail(&publ->cluster_list, &info->cluster_list);
613         } else {
614                 publ = list_first_entry(&info->zone_list, struct publication,
615                                         zone_list);
616                 list_move_tail(&publ->zone_list, &info->zone_list);
617         }
618
619         ref = publ->ref;
620         node = publ->node;
621 no_match:
622         spin_unlock_bh(&seq->lock);
623 not_found:
624         read_unlock_bh(&tipc_nametbl_lock);
625         *destnode = node;
626         return ref;
627 }
628
629 /**
630  * tipc_nametbl_mc_translate - find multicast destinations
631  *
632  * Creates list of all local ports that overlap the given multicast address;
633  * also determines if any off-node ports overlap.
634  *
635  * Note: Publications with a scope narrower than 'limit' are ignored.
636  * (i.e. local node-scope publications mustn't receive messages arriving
637  * from another node, even if the multcast link brought it here)
638  *
639  * Returns non-zero if any off-node ports overlap
640  */
641
642 int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit,
643                               struct tipc_port_list *dports)
644 {
645         struct name_seq *seq;
646         struct sub_seq *sseq;
647         struct sub_seq *sseq_stop;
648         struct name_info *info;
649         int res = 0;
650
651         read_lock_bh(&tipc_nametbl_lock);
652         seq = nametbl_find_seq(type);
653         if (!seq)
654                 goto exit;
655
656         spin_lock_bh(&seq->lock);
657
658         sseq = seq->sseqs + nameseq_locate_subseq(seq, lower);
659         sseq_stop = seq->sseqs + seq->first_free;
660         for (; sseq != sseq_stop; sseq++) {
661                 struct publication *publ;
662
663                 if (sseq->lower > upper)
664                         break;
665
666                 info = sseq->info;
667                 list_for_each_entry(publ, &info->node_list, node_list) {
668                         if (publ->scope <= limit)
669                                 tipc_port_list_add(dports, publ->ref);
670                 }
671
672                 if (info->cluster_list_size != info->node_list_size)
673                         res = 1;
674         }
675
676         spin_unlock_bh(&seq->lock);
677 exit:
678         read_unlock_bh(&tipc_nametbl_lock);
679         return res;
680 }
681
682 /*
683  * tipc_nametbl_publish - add name publication to network name tables
684  */
685
686 struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper,
687                                     u32 scope, u32 port_ref, u32 key)
688 {
689         struct publication *publ;
690
691         if (table.local_publ_count >= tipc_max_publications) {
692                 warn("Publication failed, local publication limit reached (%u)\n",
693                      tipc_max_publications);
694                 return NULL;
695         }
696
697         write_lock_bh(&tipc_nametbl_lock);
698         publ = tipc_nametbl_insert_publ(type, lower, upper, scope,
699                                    tipc_own_addr, port_ref, key);
700         if (likely(publ)) {
701                 table.local_publ_count++;
702                 tipc_named_publish(publ);
703         }
704         write_unlock_bh(&tipc_nametbl_lock);
705         return publ;
706 }
707
708 /**
709  * tipc_nametbl_withdraw - withdraw name publication from network name tables
710  */
711
712 int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key)
713 {
714         struct publication *publ;
715
716         write_lock_bh(&tipc_nametbl_lock);
717         publ = tipc_nametbl_remove_publ(type, lower, tipc_own_addr, ref, key);
718         if (likely(publ)) {
719                 table.local_publ_count--;
720                 tipc_named_withdraw(publ);
721                 write_unlock_bh(&tipc_nametbl_lock);
722                 list_del_init(&publ->pport_list);
723                 kfree(publ);
724                 return 1;
725         }
726         write_unlock_bh(&tipc_nametbl_lock);
727         err("Unable to remove local publication\n"
728             "(type=%u, lower=%u, ref=%u, key=%u)\n",
729             type, lower, ref, key);
730         return 0;
731 }
732
733 /**
734  * tipc_nametbl_subscribe - add a subscription object to the name table
735  */
736
737 void tipc_nametbl_subscribe(struct tipc_subscription *s)
738 {
739         u32 type = s->seq.type;
740         struct name_seq *seq;
741
742         write_lock_bh(&tipc_nametbl_lock);
743         seq = nametbl_find_seq(type);
744         if (!seq)
745                 seq = tipc_nameseq_create(type, &table.types[hash(type)]);
746         if (seq) {
747                 spin_lock_bh(&seq->lock);
748                 tipc_nameseq_subscribe(seq, s);
749                 spin_unlock_bh(&seq->lock);
750         } else {
751                 warn("Failed to create subscription for {%u,%u,%u}\n",
752                      s->seq.type, s->seq.lower, s->seq.upper);
753         }
754         write_unlock_bh(&tipc_nametbl_lock);
755 }
756
757 /**
758  * tipc_nametbl_unsubscribe - remove a subscription object from name table
759  */
760
761 void tipc_nametbl_unsubscribe(struct tipc_subscription *s)
762 {
763         struct name_seq *seq;
764
765         write_lock_bh(&tipc_nametbl_lock);
766         seq = nametbl_find_seq(s->seq.type);
767         if (seq != NULL) {
768                 spin_lock_bh(&seq->lock);
769                 list_del_init(&s->nameseq_list);
770                 spin_unlock_bh(&seq->lock);
771                 if ((seq->first_free == 0) && list_empty(&seq->subscriptions)) {
772                         hlist_del_init(&seq->ns_list);
773                         kfree(seq->sseqs);
774                         kfree(seq);
775                 }
776         }
777         write_unlock_bh(&tipc_nametbl_lock);
778 }
779
780
781 /**
782  * subseq_list: print specified sub-sequence contents into the given buffer
783  */
784
785 static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth,
786                         u32 index)
787 {
788         char portIdStr[27];
789         const char *scope_str[] = {"", " zone", " cluster", " node"};
790         struct publication *publ;
791         struct name_info *info;
792
793         tipc_printf(buf, "%-10u %-10u ", sseq->lower, sseq->upper);
794
795         if (depth == 2) {
796                 tipc_printf(buf, "\n");
797                 return;
798         }
799
800         info = sseq->info;
801
802         list_for_each_entry(publ, &info->zone_list, zone_list) {
803                 sprintf(portIdStr, "<%u.%u.%u:%u>",
804                          tipc_zone(publ->node), tipc_cluster(publ->node),
805                          tipc_node(publ->node), publ->ref);
806                 tipc_printf(buf, "%-26s ", portIdStr);
807                 if (depth > 3) {
808                         tipc_printf(buf, "%-10u %s", publ->key,
809                                     scope_str[publ->scope]);
810                 }
811                 if (!list_is_last(&publ->zone_list, &info->zone_list))
812                         tipc_printf(buf, "\n%33s", " ");
813         };
814
815         tipc_printf(buf, "\n");
816 }
817
818 /**
819  * nameseq_list: print specified name sequence contents into the given buffer
820  */
821
822 static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth,
823                          u32 type, u32 lowbound, u32 upbound, u32 index)
824 {
825         struct sub_seq *sseq;
826         char typearea[11];
827
828         if (seq->first_free == 0)
829                 return;
830
831         sprintf(typearea, "%-10u", seq->type);
832
833         if (depth == 1) {
834                 tipc_printf(buf, "%s\n", typearea);
835                 return;
836         }
837
838         for (sseq = seq->sseqs; sseq != &seq->sseqs[seq->first_free]; sseq++) {
839                 if ((lowbound <= sseq->upper) && (upbound >= sseq->lower)) {
840                         tipc_printf(buf, "%s ", typearea);
841                         spin_lock_bh(&seq->lock);
842                         subseq_list(sseq, buf, depth, index);
843                         spin_unlock_bh(&seq->lock);
844                         sprintf(typearea, "%10s", " ");
845                 }
846         }
847 }
848
849 /**
850  * nametbl_header - print name table header into the given buffer
851  */
852
853 static void nametbl_header(struct print_buf *buf, u32 depth)
854 {
855         const char *header[] = {
856                 "Type       ",
857                 "Lower      Upper      ",
858                 "Port Identity              ",
859                 "Publication Scope"
860         };
861
862         int i;
863
864         if (depth > 4)
865                 depth = 4;
866         for (i = 0; i < depth; i++)
867                 tipc_printf(buf, header[i]);
868         tipc_printf(buf, "\n");
869 }
870
871 /**
872  * nametbl_list - print specified name table contents into the given buffer
873  */
874
875 static void nametbl_list(struct print_buf *buf, u32 depth_info,
876                          u32 type, u32 lowbound, u32 upbound)
877 {
878         struct hlist_head *seq_head;
879         struct hlist_node *seq_node;
880         struct name_seq *seq;
881         int all_types;
882         u32 depth;
883         u32 i;
884
885         all_types = (depth_info & TIPC_NTQ_ALLTYPES);
886         depth = (depth_info & ~TIPC_NTQ_ALLTYPES);
887
888         if (depth == 0)
889                 return;
890
891         if (all_types) {
892                 /* display all entries in name table to specified depth */
893                 nametbl_header(buf, depth);
894                 lowbound = 0;
895                 upbound = ~0;
896                 for (i = 0; i < tipc_nametbl_size; i++) {
897                         seq_head = &table.types[i];
898                         hlist_for_each_entry(seq, seq_node, seq_head, ns_list) {
899                                 nameseq_list(seq, buf, depth, seq->type,
900                                              lowbound, upbound, i);
901                         }
902                 }
903         } else {
904                 /* display only the sequence that matches the specified type */
905                 if (upbound < lowbound) {
906                         tipc_printf(buf, "invalid name sequence specified\n");
907                         return;
908                 }
909                 nametbl_header(buf, depth);
910                 i = hash(type);
911                 seq_head = &table.types[i];
912                 hlist_for_each_entry(seq, seq_node, seq_head, ns_list) {
913                         if (seq->type == type) {
914                                 nameseq_list(seq, buf, depth, type,
915                                              lowbound, upbound, i);
916                                 break;
917                         }
918                 }
919         }
920 }
921
922 #define MAX_NAME_TBL_QUERY 32768
923
924 struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space)
925 {
926         struct sk_buff *buf;
927         struct tipc_name_table_query *argv;
928         struct tlv_desc *rep_tlv;
929         struct print_buf b;
930         int str_len;
931
932         if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NAME_TBL_QUERY))
933                 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
934
935         buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_NAME_TBL_QUERY));
936         if (!buf)
937                 return NULL;
938
939         rep_tlv = (struct tlv_desc *)buf->data;
940         tipc_printbuf_init(&b, TLV_DATA(rep_tlv), MAX_NAME_TBL_QUERY);
941         argv = (struct tipc_name_table_query *)TLV_DATA(req_tlv_area);
942         read_lock_bh(&tipc_nametbl_lock);
943         nametbl_list(&b, ntohl(argv->depth), ntohl(argv->type),
944                      ntohl(argv->lowbound), ntohl(argv->upbound));
945         read_unlock_bh(&tipc_nametbl_lock);
946         str_len = tipc_printbuf_validate(&b);
947
948         skb_put(buf, TLV_SPACE(str_len));
949         TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
950
951         return buf;
952 }
953
954 int tipc_nametbl_init(void)
955 {
956         table.types = kcalloc(tipc_nametbl_size, sizeof(struct hlist_head),
957                               GFP_ATOMIC);
958         if (!table.types)
959                 return -ENOMEM;
960
961         table.local_publ_count = 0;
962         return 0;
963 }
964
965 void tipc_nametbl_stop(void)
966 {
967         u32 i;
968
969         if (!table.types)
970                 return;
971
972         /* Verify name table is empty, then release it */
973
974         write_lock_bh(&tipc_nametbl_lock);
975         for (i = 0; i < tipc_nametbl_size; i++) {
976                 if (!hlist_empty(&table.types[i]))
977                         err("tipc_nametbl_stop(): hash chain %u is non-null\n", i);
978         }
979         kfree(table.types);
980         table.types = NULL;
981         write_unlock_bh(&tipc_nametbl_lock);
982 }
983