Blame view

net/tipc/name_table.c 25 KB
b97bf3fd8   Per Liden   [TIPC] Initial merge
1
2
  /*
   * net/tipc/name_table.c: TIPC name table code
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
3
   *
593a5f22d   Per Liden   [TIPC] More updat...
4
   * Copyright (c) 2000-2006, Ericsson AB
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
5
   * Copyright (c) 2004-2008, 2010-2011, Wind River Systems
b97bf3fd8   Per Liden   [TIPC] Initial merge
6
7
   * All rights reserved.
   *
9ea1fd3c1   Per Liden   [TIPC] License he...
8
   * Redistribution and use in source and binary forms, with or without
b97bf3fd8   Per Liden   [TIPC] Initial merge
9
10
   * modification, are permitted provided that the following conditions are met:
   *
9ea1fd3c1   Per Liden   [TIPC] License he...
11
12
13
14
15
16
17
18
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in the
   *    documentation and/or other materials provided with the distribution.
   * 3. Neither the names of the copyright holders nor the names of its
   *    contributors may be used to endorse or promote products derived from
   *    this software without specific prior written permission.
b97bf3fd8   Per Liden   [TIPC] Initial merge
19
   *
9ea1fd3c1   Per Liden   [TIPC] License he...
20
21
22
23
24
25
26
27
28
29
30
31
32
33
   * Alternatively, this software may be distributed under the terms of the
   * GNU General Public License ("GPL") version 2 as published by the Free
   * Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
b97bf3fd8   Per Liden   [TIPC] Initial merge
34
35
36
37
38
   * POSSIBILITY OF SUCH DAMAGE.
   */
  
  #include "core.h"
  #include "config.h"
b97bf3fd8   Per Liden   [TIPC] Initial merge
39
40
  #include "name_table.h"
  #include "name_distr.h"
b97bf3fd8   Per Liden   [TIPC] Initial merge
41
42
  #include "subscr.h"
  #include "port.h"
b97bf3fd8   Per Liden   [TIPC] Initial merge
43

988f088a8   Adrian Bunk   [TIPC]: Cleanups
44
  static int tipc_nametbl_size = 1024;		/* must be a power of 2 */
b97bf3fd8   Per Liden   [TIPC] Initial merge
45
46
  
  /**
b52124a50   Allan Stephens   tipc: Partition n...
47
   * struct name_info - name sequence publication info
968edbe1c   Allan Stephens   tipc: Optimizatio...
48
49
50
51
52
53
54
55
56
57
   * @node_list: circular list of publications made by own node
   * @cluster_list: circular list of publications made by own cluster
   * @zone_list: circular list of publications made by own zone
   * @node_list_size: number of entries in "node_list"
   * @cluster_list_size: number of entries in "cluster_list"
   * @zone_list_size: number of entries in "zone_list"
   *
   * Note: The zone list always contains at least one entry, since all
   *       publications of the associated name sequence belong to it.
   *       (The cluster and node lists may be empty.)
b97bf3fd8   Per Liden   [TIPC] Initial merge
58
   */
b52124a50   Allan Stephens   tipc: Partition n...
59
  struct name_info {
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
60
61
62
  	struct list_head node_list;
  	struct list_head cluster_list;
  	struct list_head zone_list;
968edbe1c   Allan Stephens   tipc: Optimizatio...
63
64
65
  	u32 node_list_size;
  	u32 cluster_list_size;
  	u32 zone_list_size;
b97bf3fd8   Per Liden   [TIPC] Initial merge
66
  };
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
67
  /**
b52124a50   Allan Stephens   tipc: Partition n...
68
69
70
71
72
73
74
75
76
77
78
79
80
   * struct sub_seq - container for all published instances of a name sequence
   * @lower: name sequence lower bound
   * @upper: name sequence upper bound
   * @info: pointer to name sequence publication info
   */
  
  struct sub_seq {
  	u32 lower;
  	u32 upper;
  	struct name_info *info;
  };
  
  /**
b97bf3fd8   Per Liden   [TIPC] Initial merge
81
82
83
84
85
   * struct name_seq - container for all published instances of a name type
   * @type: 32 bit 'type' value for name sequence
   * @sseq: pointer to dynamically-sized array of sub-sequences of this 'type';
   *        sub-sequences are sorted in ascending order
   * @alloc: number of sub-sequences currently in array
f131072c3   Allan Stephens   [TIPC]: First pha...
86
   * @first_free: array index of first unused sub-sequence entry
b97bf3fd8   Per Liden   [TIPC] Initial merge
87
88
   * @ns_list: links to adjacent name sequences in hash chain
   * @subscriptions: list of subscriptions for this 'type'
307fdf5e7   Allan Stephens   tipc: Add missing...
89
   * @lock: spinlock controlling access to publication lists of all sub-sequences
b97bf3fd8   Per Liden   [TIPC] Initial merge
90
91
92
93
94
95
96
97
98
99
100
101
102
103
   */
  
  struct name_seq {
  	u32 type;
  	struct sub_seq *sseqs;
  	u32 alloc;
  	u32 first_free;
  	struct hlist_node ns_list;
  	struct list_head subscriptions;
  	spinlock_t lock;
  };
  
  /**
   * struct name_table - table containing all existing port name publications
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
104
   * @types: pointer to fixed-sized array of name sequence lists,
b97bf3fd8   Per Liden   [TIPC] Initial merge
105
106
107
108
109
110
111
112
   *         accessed via hashing on 'type'; name sequence lists are *not* sorted
   * @local_publ_count: number of publications issued by this node
   */
  
  struct name_table {
  	struct hlist_head *types;
  	u32 local_publ_count;
  };
e3ec9c7d5   Allan Stephens   tipc: remove zero...
113
  static struct name_table table;
b97bf3fd8   Per Liden   [TIPC] Initial merge
114
  static atomic_t rsv_publ_ok = ATOMIC_INIT(0);
34af946a2   Ingo Molnar   [PATCH] spin/rwlo...
115
  DEFINE_RWLOCK(tipc_nametbl_lock);
b97bf3fd8   Per Liden   [TIPC] Initial merge
116

05790c645   Sam Ravnborg   [TIPC]: Remove in...
117
  static int hash(int x)
b97bf3fd8   Per Liden   [TIPC] Initial merge
118
  {
a02cec215   Eric Dumazet   net: return opera...
119
  	return x & (tipc_nametbl_size - 1);
b97bf3fd8   Per Liden   [TIPC] Initial merge
120
121
122
123
124
  }
  
  /**
   * publ_create - create a publication structure
   */
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
125
126
  static struct publication *publ_create(u32 type, u32 lower, u32 upper,
  				       u32 scope, u32 node, u32 port_ref,
b97bf3fd8   Per Liden   [TIPC] Initial merge
127
128
  				       u32 key)
  {
0da974f4f   Panagiotis Issaris   [NET]: Conversion...
129
  	struct publication *publ = kzalloc(sizeof(*publ), GFP_ATOMIC);
b97bf3fd8   Per Liden   [TIPC] Initial merge
130
  	if (publ == NULL) {
a10bd924a   Allan Stephens   [TIPC]: Enhanced ...
131
132
  		warn("Publication creation failure, no memory
  ");
1fc54d8f4   Sam Ravnborg   [TIPC]: Fix simpl...
133
  		return NULL;
b97bf3fd8   Per Liden   [TIPC] Initial merge
134
  	}
b97bf3fd8   Per Liden   [TIPC] Initial merge
135
136
137
138
139
140
141
142
143
144
145
146
147
148
  	publ->type = type;
  	publ->lower = lower;
  	publ->upper = upper;
  	publ->scope = scope;
  	publ->node = node;
  	publ->ref = port_ref;
  	publ->key = key;
  	INIT_LIST_HEAD(&publ->local_list);
  	INIT_LIST_HEAD(&publ->pport_list);
  	INIT_LIST_HEAD(&publ->subscr.nodesub_list);
  	return publ;
  }
  
  /**
4323add67   Per Liden   [TIPC] Avoid poll...
149
   * tipc_subseq_alloc - allocate a specified number of sub-sequence structures
b97bf3fd8   Per Liden   [TIPC] Initial merge
150
   */
988f088a8   Adrian Bunk   [TIPC]: Cleanups
151
  static struct sub_seq *tipc_subseq_alloc(u32 cnt)
b97bf3fd8   Per Liden   [TIPC] Initial merge
152
  {
0da974f4f   Panagiotis Issaris   [NET]: Conversion...
153
  	struct sub_seq *sseq = kcalloc(cnt, sizeof(struct sub_seq), GFP_ATOMIC);
b97bf3fd8   Per Liden   [TIPC] Initial merge
154
155
156
157
  	return sseq;
  }
  
  /**
4323add67   Per Liden   [TIPC] Avoid poll...
158
   * tipc_nameseq_create - create a name sequence structure for the specified 'type'
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
159
   *
b97bf3fd8   Per Liden   [TIPC] Initial merge
160
161
   * Allocates a single sub-sequence structure and sets it to all 0's.
   */
988f088a8   Adrian Bunk   [TIPC]: Cleanups
162
  static struct name_seq *tipc_nameseq_create(u32 type, struct hlist_head *seq_head)
b97bf3fd8   Per Liden   [TIPC] Initial merge
163
  {
0da974f4f   Panagiotis Issaris   [NET]: Conversion...
164
  	struct name_seq *nseq = kzalloc(sizeof(*nseq), GFP_ATOMIC);
4323add67   Per Liden   [TIPC] Avoid poll...
165
  	struct sub_seq *sseq = tipc_subseq_alloc(1);
b97bf3fd8   Per Liden   [TIPC] Initial merge
166
167
  
  	if (!nseq || !sseq) {
a10bd924a   Allan Stephens   [TIPC]: Enhanced ...
168
169
  		warn("Name sequence creation failed, no memory
  ");
b97bf3fd8   Per Liden   [TIPC] Initial merge
170
171
  		kfree(nseq);
  		kfree(sseq);
1fc54d8f4   Sam Ravnborg   [TIPC]: Fix simpl...
172
  		return NULL;
b97bf3fd8   Per Liden   [TIPC] Initial merge
173
  	}
34af946a2   Ingo Molnar   [PATCH] spin/rwlo...
174
  	spin_lock_init(&nseq->lock);
b97bf3fd8   Per Liden   [TIPC] Initial merge
175
176
  	nseq->type = type;
  	nseq->sseqs = sseq;
b97bf3fd8   Per Liden   [TIPC] Initial merge
177
178
179
180
181
182
183
184
185
  	nseq->alloc = 1;
  	INIT_HLIST_NODE(&nseq->ns_list);
  	INIT_LIST_HEAD(&nseq->subscriptions);
  	hlist_add_head(&nseq->ns_list, seq_head);
  	return nseq;
  }
  
  /**
   * nameseq_find_subseq - find sub-sequence (if any) matching a name instance
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
186
   *
b97bf3fd8   Per Liden   [TIPC] Initial merge
187
188
   * Very time-critical, so binary searches through sub-sequence array.
   */
05790c645   Sam Ravnborg   [TIPC]: Remove in...
189
190
  static struct sub_seq *nameseq_find_subseq(struct name_seq *nseq,
  					   u32 instance)
b97bf3fd8   Per Liden   [TIPC] Initial merge
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
  {
  	struct sub_seq *sseqs = nseq->sseqs;
  	int low = 0;
  	int high = nseq->first_free - 1;
  	int mid;
  
  	while (low <= high) {
  		mid = (low + high) / 2;
  		if (instance < sseqs[mid].lower)
  			high = mid - 1;
  		else if (instance > sseqs[mid].upper)
  			low = mid + 1;
  		else
  			return &sseqs[mid];
  	}
1fc54d8f4   Sam Ravnborg   [TIPC]: Fix simpl...
206
  	return NULL;
b97bf3fd8   Per Liden   [TIPC] Initial merge
207
208
209
210
  }
  
  /**
   * nameseq_locate_subseq - determine position of name instance in sub-sequence
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
211
   *
b97bf3fd8   Per Liden   [TIPC] Initial merge
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
   * Returns index in sub-sequence array of the entry that contains the specified
   * instance value; if no entry contains that value, returns the position
   * where a new entry for it would be inserted in the array.
   *
   * Note: Similar to binary search code for locating a sub-sequence.
   */
  
  static u32 nameseq_locate_subseq(struct name_seq *nseq, u32 instance)
  {
  	struct sub_seq *sseqs = nseq->sseqs;
  	int low = 0;
  	int high = nseq->first_free - 1;
  	int mid;
  
  	while (low <= high) {
  		mid = (low + high) / 2;
  		if (instance < sseqs[mid].lower)
  			high = mid - 1;
  		else if (instance > sseqs[mid].upper)
  			low = mid + 1;
  		else
  			return mid;
  	}
  	return low;
  }
  
  /**
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
239
   * tipc_nameseq_insert_publ -
b97bf3fd8   Per Liden   [TIPC] Initial merge
240
   */
988f088a8   Adrian Bunk   [TIPC]: Cleanups
241
242
243
  static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq,
  						    u32 type, u32 lower, u32 upper,
  						    u32 scope, u32 node, u32 port, u32 key)
b97bf3fd8   Per Liden   [TIPC] Initial merge
244
  {
fead39098   Paul Gortmaker   tipc: rename stru...
245
246
  	struct tipc_subscription *s;
  	struct tipc_subscription *st;
b97bf3fd8   Per Liden   [TIPC] Initial merge
247
248
  	struct publication *publ;
  	struct sub_seq *sseq;
b52124a50   Allan Stephens   tipc: Partition n...
249
  	struct name_info *info;
b97bf3fd8   Per Liden   [TIPC] Initial merge
250
  	int created_subseq = 0;
b97bf3fd8   Per Liden   [TIPC] Initial merge
251
  	sseq = nameseq_find_subseq(nseq, lower);
b97bf3fd8   Per Liden   [TIPC] Initial merge
252
253
254
255
256
  	if (sseq) {
  
  		/* Lower end overlaps existing entry => need an exact match */
  
  		if ((sseq->lower != lower) || (sseq->upper != upper)) {
f131072c3   Allan Stephens   [TIPC]: First pha...
257
258
259
  			warn("Cannot publish {%u,%u,%u}, overlap error
  ",
  			     type, lower, upper);
1fc54d8f4   Sam Ravnborg   [TIPC]: Fix simpl...
260
  			return NULL;
b97bf3fd8   Per Liden   [TIPC] Initial merge
261
  		}
b52124a50   Allan Stephens   tipc: Partition n...
262
263
  
  		info = sseq->info;
b97bf3fd8   Per Liden   [TIPC] Initial merge
264
265
266
267
268
269
270
271
272
273
274
275
  	} else {
  		u32 inspos;
  		struct sub_seq *freesseq;
  
  		/* Find where lower end should be inserted */
  
  		inspos = nameseq_locate_subseq(nseq, lower);
  
  		/* Fail if upper end overlaps into an existing entry */
  
  		if ((inspos < nseq->first_free) &&
  		    (upper >= nseq->sseqs[inspos].lower)) {
f131072c3   Allan Stephens   [TIPC]: First pha...
276
277
278
  			warn("Cannot publish {%u,%u,%u}, overlap error
  ",
  			     type, lower, upper);
1fc54d8f4   Sam Ravnborg   [TIPC]: Fix simpl...
279
  			return NULL;
b97bf3fd8   Per Liden   [TIPC] Initial merge
280
281
282
283
284
  		}
  
  		/* Ensure there is space for new sub-sequence */
  
  		if (nseq->first_free == nseq->alloc) {
9ab230f82   Allan Stephens   [TIPC]: Prevent n...
285
286
287
  			struct sub_seq *sseqs = tipc_subseq_alloc(nseq->alloc * 2);
  
  			if (!sseqs) {
f131072c3   Allan Stephens   [TIPC]: First pha...
288
289
290
  				warn("Cannot publish {%u,%u,%u}, no memory
  ",
  				     type, lower, upper);
1fc54d8f4   Sam Ravnborg   [TIPC]: Fix simpl...
291
  				return NULL;
b97bf3fd8   Per Liden   [TIPC] Initial merge
292
  			}
9ab230f82   Allan Stephens   [TIPC]: Prevent n...
293
294
295
296
297
  			memcpy(sseqs, nseq->sseqs,
  			       nseq->alloc * sizeof(struct sub_seq));
  			kfree(nseq->sseqs);
  			nseq->sseqs = sseqs;
  			nseq->alloc *= 2;
b97bf3fd8   Per Liden   [TIPC] Initial merge
298
  		}
b97bf3fd8   Per Liden   [TIPC] Initial merge
299

b52124a50   Allan Stephens   tipc: Partition n...
300
301
302
303
304
305
306
  		info = kzalloc(sizeof(*info), GFP_ATOMIC);
  		if (!info) {
  			warn("Cannot publish {%u,%u,%u}, no memory
  ",
  			     type, lower, upper);
  			return NULL;
  		}
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
307
308
309
  		INIT_LIST_HEAD(&info->node_list);
  		INIT_LIST_HEAD(&info->cluster_list);
  		INIT_LIST_HEAD(&info->zone_list);
b97bf3fd8   Per Liden   [TIPC] Initial merge
310
  		/* Insert new sub-sequence */
b97bf3fd8   Per Liden   [TIPC] Initial merge
311
312
  		sseq = &nseq->sseqs[inspos];
  		freesseq = &nseq->sseqs[nseq->first_free];
0e65967e3   Allan Stephens   tipc: cleanup var...
313
314
  		memmove(sseq + 1, sseq, (freesseq - sseq) * sizeof(*sseq));
  		memset(sseq, 0, sizeof(*sseq));
b97bf3fd8   Per Liden   [TIPC] Initial merge
315
316
317
  		nseq->first_free++;
  		sseq->lower = lower;
  		sseq->upper = upper;
b52124a50   Allan Stephens   tipc: Partition n...
318
  		sseq->info = info;
b97bf3fd8   Per Liden   [TIPC] Initial merge
319
320
  		created_subseq = 1;
  	}
b97bf3fd8   Per Liden   [TIPC] Initial merge
321
322
323
324
325
  
  	/* Insert a publication: */
  
  	publ = publ_create(type, lower, upper, scope, node, port, key);
  	if (!publ)
1fc54d8f4   Sam Ravnborg   [TIPC]: Fix simpl...
326
  		return NULL;
b97bf3fd8   Per Liden   [TIPC] Initial merge
327

f6f0a4d2d   Allan Stephens   tipc: Convert nam...
328
  	list_add(&publ->zone_list, &info->zone_list);
b52124a50   Allan Stephens   tipc: Partition n...
329
  	info->zone_list_size++;
b97bf3fd8   Per Liden   [TIPC] Initial merge
330
331
  
  	if (in_own_cluster(node)) {
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
332
  		list_add(&publ->cluster_list, &info->cluster_list);
b52124a50   Allan Stephens   tipc: Partition n...
333
  		info->cluster_list_size++;
b97bf3fd8   Per Liden   [TIPC] Initial merge
334
335
336
  	}
  
  	if (node == tipc_own_addr) {
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
337
  		list_add(&publ->node_list, &info->node_list);
b52124a50   Allan Stephens   tipc: Partition n...
338
  		info->node_list_size++;
b97bf3fd8   Per Liden   [TIPC] Initial merge
339
  	}
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
340
341
  	/*
  	 * Any subscriptions waiting for notification?
b97bf3fd8   Per Liden   [TIPC] Initial merge
342
343
  	 */
  	list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) {
4323add67   Per Liden   [TIPC] Avoid poll...
344
345
346
347
  		tipc_subscr_report_overlap(s,
  					   publ->lower,
  					   publ->upper,
  					   TIPC_PUBLISHED,
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
348
  					   publ->ref,
4323add67   Per Liden   [TIPC] Avoid poll...
349
350
  					   publ->node,
  					   created_subseq);
b97bf3fd8   Per Liden   [TIPC] Initial merge
351
352
353
354
355
  	}
  	return publ;
  }
  
  /**
4323add67   Per Liden   [TIPC] Avoid poll...
356
   * tipc_nameseq_remove_publ -
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
357
   *
f131072c3   Allan Stephens   [TIPC]: First pha...
358
359
360
361
362
363
364
   * NOTE: There may be cases where TIPC is asked to remove a publication
   * that is not in the name table.  For example, if another node issues a
   * publication for a name sequence that overlaps an existing name sequence
   * the publication will not be recorded, which means the publication won't
   * be found when the name sequence is later withdrawn by that node.
   * A failed withdraw request simply returns a failure indication and lets the
   * caller issue any error or warning messages associated with such a problem.
b97bf3fd8   Per Liden   [TIPC] Initial merge
365
   */
988f088a8   Adrian Bunk   [TIPC]: Cleanups
366
367
  static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 inst,
  						    u32 node, u32 ref, u32 key)
b97bf3fd8   Per Liden   [TIPC] Initial merge
368
369
  {
  	struct publication *publ;
b97bf3fd8   Per Liden   [TIPC] Initial merge
370
  	struct sub_seq *sseq = nameseq_find_subseq(nseq, inst);
b52124a50   Allan Stephens   tipc: Partition n...
371
  	struct name_info *info;
b97bf3fd8   Per Liden   [TIPC] Initial merge
372
  	struct sub_seq *free;
fead39098   Paul Gortmaker   tipc: rename stru...
373
  	struct tipc_subscription *s, *st;
b97bf3fd8   Per Liden   [TIPC] Initial merge
374
  	int removed_subseq = 0;
f131072c3   Allan Stephens   [TIPC]: First pha...
375
  	if (!sseq)
1fc54d8f4   Sam Ravnborg   [TIPC]: Fix simpl...
376
  		return NULL;
f131072c3   Allan Stephens   [TIPC]: First pha...
377

b52124a50   Allan Stephens   tipc: Partition n...
378
  	info = sseq->info;
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
379
  	/* Locate publication, if it exists */
f131072c3   Allan Stephens   [TIPC]: First pha...
380

f6f0a4d2d   Allan Stephens   tipc: Convert nam...
381
382
383
384
385
386
  	list_for_each_entry(publ, &info->zone_list, zone_list) {
  		if ((publ->key == key) && (publ->ref == ref) &&
  		    (!publ->node || (publ->node == node)))
  			goto found;
  	}
  	return NULL;
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
387

f6f0a4d2d   Allan Stephens   tipc: Convert nam...
388
389
  found:
  	/* Remove publication from zone scope list */
f131072c3   Allan Stephens   [TIPC]: First pha...
390

f6f0a4d2d   Allan Stephens   tipc: Convert nam...
391
  	list_del(&publ->zone_list);
b52124a50   Allan Stephens   tipc: Partition n...
392
  	info->zone_list_size--;
b97bf3fd8   Per Liden   [TIPC] Initial merge
393

f131072c3   Allan Stephens   [TIPC]: First pha...
394
  	/* Remove publication from cluster scope list, if present */
b97bf3fd8   Per Liden   [TIPC] Initial merge
395
  	if (in_own_cluster(node)) {
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
396
  		list_del(&publ->cluster_list);
b52124a50   Allan Stephens   tipc: Partition n...
397
  		info->cluster_list_size--;
b97bf3fd8   Per Liden   [TIPC] Initial merge
398
  	}
f131072c3   Allan Stephens   [TIPC]: First pha...
399
400
  
  	/* Remove publication from node scope list, if present */
b97bf3fd8   Per Liden   [TIPC] Initial merge
401
402
  
  	if (node == tipc_own_addr) {
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
403
  		list_del(&publ->node_list);
b52124a50   Allan Stephens   tipc: Partition n...
404
  		info->node_list_size--;
b97bf3fd8   Per Liden   [TIPC] Initial merge
405
  	}
b97bf3fd8   Per Liden   [TIPC] Initial merge
406

f131072c3   Allan Stephens   [TIPC]: First pha...
407
  	/* Contract subseq list if no more publications for that subseq */
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
408
  	if (list_empty(&info->zone_list)) {
b52124a50   Allan Stephens   tipc: Partition n...
409
  		kfree(info);
b97bf3fd8   Per Liden   [TIPC] Initial merge
410
  		free = &nseq->sseqs[nseq->first_free--];
0e65967e3   Allan Stephens   tipc: cleanup var...
411
  		memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof(*sseq));
b97bf3fd8   Per Liden   [TIPC] Initial merge
412
413
  		removed_subseq = 1;
  	}
f131072c3   Allan Stephens   [TIPC]: First pha...
414
  	/* Notify any waiting subscriptions */
b97bf3fd8   Per Liden   [TIPC] Initial merge
415
  	list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) {
4323add67   Per Liden   [TIPC] Avoid poll...
416
417
418
  		tipc_subscr_report_overlap(s,
  					   publ->lower,
  					   publ->upper,
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
419
420
  					   TIPC_WITHDRAWN,
  					   publ->ref,
4323add67   Per Liden   [TIPC] Avoid poll...
421
422
  					   publ->node,
  					   removed_subseq);
b97bf3fd8   Per Liden   [TIPC] Initial merge
423
  	}
f131072c3   Allan Stephens   [TIPC]: First pha...
424

b97bf3fd8   Per Liden   [TIPC] Initial merge
425
426
427
428
  	return publ;
  }
  
  /**
4323add67   Per Liden   [TIPC] Avoid poll...
429
   * tipc_nameseq_subscribe: attach a subscription, and issue
b97bf3fd8   Per Liden   [TIPC] Initial merge
430
431
432
   * the prescribed number of events if there is any sub-
   * sequence overlapping with the requested sequence
   */
fead39098   Paul Gortmaker   tipc: rename stru...
433
434
  static void tipc_nameseq_subscribe(struct name_seq *nseq,
  					struct tipc_subscription *s)
b97bf3fd8   Per Liden   [TIPC] Initial merge
435
436
437
438
439
440
441
442
443
  {
  	struct sub_seq *sseq = nseq->sseqs;
  
  	list_add(&s->nameseq_list, &nseq->subscriptions);
  
  	if (!sseq)
  		return;
  
  	while (sseq != &nseq->sseqs[nseq->first_free]) {
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
444
445
446
  		if (tipc_subscr_overlap(s, sseq->lower, sseq->upper)) {
  			struct publication *crs;
  			struct name_info *info = sseq->info;
b97bf3fd8   Per Liden   [TIPC] Initial merge
447
  			int must_report = 1;
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
448
  			list_for_each_entry(crs, &info->zone_list, zone_list) {
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
449
450
  				tipc_subscr_report_overlap(s,
  							   sseq->lower,
4323add67   Per Liden   [TIPC] Avoid poll...
451
452
453
454
455
  							   sseq->upper,
  							   TIPC_PUBLISHED,
  							   crs->ref,
  							   crs->node,
  							   must_report);
b97bf3fd8   Per Liden   [TIPC] Initial merge
456
  				must_report = 0;
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
457
  			}
b97bf3fd8   Per Liden   [TIPC] Initial merge
458
459
460
461
462
463
464
465
466
467
  		}
  		sseq++;
  	}
  }
  
  static struct name_seq *nametbl_find_seq(u32 type)
  {
  	struct hlist_head *seq_head;
  	struct hlist_node *seq_node;
  	struct name_seq *ns;
b97bf3fd8   Per Liden   [TIPC] Initial merge
468
469
  	seq_head = &table.types[hash(type)];
  	hlist_for_each_entry(ns, seq_node, seq_head, ns_list) {
b29f14284   Allan Stephens   tipc: remove call...
470
  		if (ns->type == type)
b97bf3fd8   Per Liden   [TIPC] Initial merge
471
  			return ns;
b97bf3fd8   Per Liden   [TIPC] Initial merge
472
  	}
1fc54d8f4   Sam Ravnborg   [TIPC]: Fix simpl...
473
  	return NULL;
b97bf3fd8   Per Liden   [TIPC] Initial merge
474
  };
4323add67   Per Liden   [TIPC] Avoid poll...
475
476
  struct publication *tipc_nametbl_insert_publ(u32 type, u32 lower, u32 upper,
  					     u32 scope, u32 node, u32 port, u32 key)
b97bf3fd8   Per Liden   [TIPC] Initial merge
477
478
  {
  	struct name_seq *seq = nametbl_find_seq(type);
b97bf3fd8   Per Liden   [TIPC] Initial merge
479
  	if (lower > upper) {
f131072c3   Allan Stephens   [TIPC]: First pha...
480
481
  		warn("Failed to publish illegal {%u,%u,%u}
  ",
b97bf3fd8   Per Liden   [TIPC] Initial merge
482
  		     type, lower, upper);
1fc54d8f4   Sam Ravnborg   [TIPC]: Fix simpl...
483
  		return NULL;
b97bf3fd8   Per Liden   [TIPC] Initial merge
484
  	}
b29f14284   Allan Stephens   tipc: remove call...
485
  	if (!seq)
4323add67   Per Liden   [TIPC] Avoid poll...
486
  		seq = tipc_nameseq_create(type, &table.types[hash(type)]);
b97bf3fd8   Per Liden   [TIPC] Initial merge
487
  	if (!seq)
1fc54d8f4   Sam Ravnborg   [TIPC]: Fix simpl...
488
  		return NULL;
b97bf3fd8   Per Liden   [TIPC] Initial merge
489

4323add67   Per Liden   [TIPC] Avoid poll...
490
491
  	return tipc_nameseq_insert_publ(seq, type, lower, upper,
  					scope, node, port, key);
b97bf3fd8   Per Liden   [TIPC] Initial merge
492
  }
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
493
  struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower,
4323add67   Per Liden   [TIPC] Avoid poll...
494
  					     u32 node, u32 ref, u32 key)
b97bf3fd8   Per Liden   [TIPC] Initial merge
495
496
497
498
499
  {
  	struct publication *publ;
  	struct name_seq *seq = nametbl_find_seq(type);
  
  	if (!seq)
1fc54d8f4   Sam Ravnborg   [TIPC]: Fix simpl...
500
  		return NULL;
b97bf3fd8   Per Liden   [TIPC] Initial merge
501

4323add67   Per Liden   [TIPC] Avoid poll...
502
  	publ = tipc_nameseq_remove_publ(seq, lower, node, ref, key);
b97bf3fd8   Per Liden   [TIPC] Initial merge
503
504
505
506
507
508
509
510
511
512
  
  	if (!seq->first_free && list_empty(&seq->subscriptions)) {
  		hlist_del_init(&seq->ns_list);
  		kfree(seq->sseqs);
  		kfree(seq);
  	}
  	return publ;
  }
  
  /*
5d9c54c1e   Allan Stephens   tipc: Minor optim...
513
   * tipc_nametbl_translate - translate name to port id
b97bf3fd8   Per Liden   [TIPC] Initial merge
514
515
516
517
   *
   * Note: on entry 'destnode' is the search domain used during translation;
   *       on exit it passes back the node address of the matching port (if any)
   */
4323add67   Per Liden   [TIPC] Avoid poll...
518
  u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode)
b97bf3fd8   Per Liden   [TIPC] Initial merge
519
520
  {
  	struct sub_seq *sseq;
b52124a50   Allan Stephens   tipc: Partition n...
521
  	struct name_info *info;
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
522
  	struct publication *publ;
b97bf3fd8   Per Liden   [TIPC] Initial merge
523
  	struct name_seq *seq;
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
524
  	u32 ref = 0;
b97bf3fd8   Per Liden   [TIPC] Initial merge
525

c68ca7b72   Allan Stephens   tipc: add tipc_ p...
526
  	if (!tipc_in_scope(*destnode, tipc_own_addr))
b97bf3fd8   Per Liden   [TIPC] Initial merge
527
  		return 0;
4323add67   Per Liden   [TIPC] Avoid poll...
528
  	read_lock_bh(&tipc_nametbl_lock);
b97bf3fd8   Per Liden   [TIPC] Initial merge
529
530
531
532
533
534
535
  	seq = nametbl_find_seq(type);
  	if (unlikely(!seq))
  		goto not_found;
  	sseq = nameseq_find_subseq(seq, instance);
  	if (unlikely(!sseq))
  		goto not_found;
  	spin_lock_bh(&seq->lock);
b52124a50   Allan Stephens   tipc: Partition n...
536
  	info = sseq->info;
b97bf3fd8   Per Liden   [TIPC] Initial merge
537
538
539
  
  	/* Closest-First Algorithm: */
  	if (likely(!*destnode)) {
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
540
541
542
543
544
545
546
547
548
549
550
551
  		if (!list_empty(&info->node_list)) {
  			publ = list_first_entry(&info->node_list,
  						struct publication,
  						node_list);
  			list_move_tail(&publ->node_list,
  				       &info->node_list);
  		} else if (!list_empty(&info->cluster_list)) {
  			publ = list_first_entry(&info->cluster_list,
  						struct publication,
  						cluster_list);
  			list_move_tail(&publ->cluster_list,
  				       &info->cluster_list);
8af4638a2   Allan Stephens   tipc: Eliminate c...
552
  		} else {
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
553
554
555
556
557
  			publ = list_first_entry(&info->zone_list,
  						struct publication,
  						zone_list);
  			list_move_tail(&publ->zone_list,
  				       &info->zone_list);
8af4638a2   Allan Stephens   tipc: Eliminate c...
558
  		}
b97bf3fd8   Per Liden   [TIPC] Initial merge
559
560
561
562
  	}
  
  	/* Round-Robin Algorithm: */
  	else if (*destnode == tipc_own_addr) {
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
563
564
565
566
567
  		if (list_empty(&info->node_list))
  			goto no_match;
  		publ = list_first_entry(&info->node_list, struct publication,
  					node_list);
  		list_move_tail(&publ->node_list, &info->node_list);
b97bf3fd8   Per Liden   [TIPC] Initial merge
568
  	} else if (in_own_cluster(*destnode)) {
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
569
570
571
572
573
  		if (list_empty(&info->cluster_list))
  			goto no_match;
  		publ = list_first_entry(&info->cluster_list, struct publication,
  					cluster_list);
  		list_move_tail(&publ->cluster_list, &info->cluster_list);
b97bf3fd8   Per Liden   [TIPC] Initial merge
574
  	} else {
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
575
576
577
  		publ = list_first_entry(&info->zone_list, struct publication,
  					zone_list);
  		list_move_tail(&publ->zone_list, &info->zone_list);
b97bf3fd8   Per Liden   [TIPC] Initial merge
578
  	}
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
579
580
581
582
  
  	ref = publ->ref;
  	*destnode = publ->node;
  no_match:
b97bf3fd8   Per Liden   [TIPC] Initial merge
583
584
  	spin_unlock_bh(&seq->lock);
  not_found:
4323add67   Per Liden   [TIPC] Avoid poll...
585
  	read_unlock_bh(&tipc_nametbl_lock);
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
586
  	return ref;
b97bf3fd8   Per Liden   [TIPC] Initial merge
587
588
589
  }
  
  /**
4323add67   Per Liden   [TIPC] Avoid poll...
590
   * tipc_nametbl_mc_translate - find multicast destinations
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
591
   *
b97bf3fd8   Per Liden   [TIPC] Initial merge
592
593
594
595
596
597
   * Creates list of all local ports that overlap the given multicast address;
   * also determines if any off-node ports overlap.
   *
   * Note: Publications with a scope narrower than 'limit' are ignored.
   * (i.e. local node-scope publications mustn't receive messages arriving
   * from another node, even if the multcast link brought it here)
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
598
   *
b97bf3fd8   Per Liden   [TIPC] Initial merge
599
600
   * Returns non-zero if any off-node ports overlap
   */
4323add67   Per Liden   [TIPC] Avoid poll...
601
  int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit,
4584310b4   Paul Gortmaker   tipc: rename stru...
602
  			      struct tipc_port_list *dports)
b97bf3fd8   Per Liden   [TIPC] Initial merge
603
604
605
606
  {
  	struct name_seq *seq;
  	struct sub_seq *sseq;
  	struct sub_seq *sseq_stop;
b52124a50   Allan Stephens   tipc: Partition n...
607
  	struct name_info *info;
b97bf3fd8   Per Liden   [TIPC] Initial merge
608
  	int res = 0;
4323add67   Per Liden   [TIPC] Avoid poll...
609
  	read_lock_bh(&tipc_nametbl_lock);
b97bf3fd8   Per Liden   [TIPC] Initial merge
610
611
612
613
614
615
616
617
618
619
620
621
622
  	seq = nametbl_find_seq(type);
  	if (!seq)
  		goto exit;
  
  	spin_lock_bh(&seq->lock);
  
  	sseq = seq->sseqs + nameseq_locate_subseq(seq, lower);
  	sseq_stop = seq->sseqs + seq->first_free;
  	for (; sseq != sseq_stop; sseq++) {
  		struct publication *publ;
  
  		if (sseq->lower > upper)
  			break;
968edbe1c   Allan Stephens   tipc: Optimizatio...
623

b52124a50   Allan Stephens   tipc: Partition n...
624
  		info = sseq->info;
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
625
626
627
  		list_for_each_entry(publ, &info->node_list, node_list) {
  			if (publ->scope <= limit)
  				tipc_port_list_add(dports, publ->ref);
968edbe1c   Allan Stephens   tipc: Optimizatio...
628
  		}
b52124a50   Allan Stephens   tipc: Partition n...
629
  		if (info->cluster_list_size != info->node_list_size)
968edbe1c   Allan Stephens   tipc: Optimizatio...
630
  			res = 1;
b97bf3fd8   Per Liden   [TIPC] Initial merge
631
632
633
634
  	}
  
  	spin_unlock_bh(&seq->lock);
  exit:
4323add67   Per Liden   [TIPC] Avoid poll...
635
  	read_unlock_bh(&tipc_nametbl_lock);
b97bf3fd8   Per Liden   [TIPC] Initial merge
636
637
638
639
  	return res;
  }
  
  /**
4323add67   Per Liden   [TIPC] Avoid poll...
640
   * tipc_nametbl_publish_rsv - publish port name using a reserved name type
b97bf3fd8   Per Liden   [TIPC] Initial merge
641
   */
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
642
  int tipc_nametbl_publish_rsv(u32 ref, unsigned int scope,
b97bf3fd8   Per Liden   [TIPC] Initial merge
643
644
645
646
647
648
649
650
651
652
653
  			struct tipc_name_seq const *seq)
  {
  	int res;
  
  	atomic_inc(&rsv_publ_ok);
  	res = tipc_publish(ref, scope, seq);
  	atomic_dec(&rsv_publ_ok);
  	return res;
  }
  
  /**
4323add67   Per Liden   [TIPC] Avoid poll...
654
   * tipc_nametbl_publish - add name publication to network name tables
b97bf3fd8   Per Liden   [TIPC] Initial merge
655
   */
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
656
  struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper,
b97bf3fd8   Per Liden   [TIPC] Initial merge
657
658
659
660
661
  				    u32 scope, u32 port_ref, u32 key)
  {
  	struct publication *publ;
  
  	if (table.local_publ_count >= tipc_max_publications) {
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
662
663
  		warn("Publication failed, local publication limit reached (%u)
  ",
b97bf3fd8   Per Liden   [TIPC] Initial merge
664
  		     tipc_max_publications);
1fc54d8f4   Sam Ravnborg   [TIPC]: Fix simpl...
665
  		return NULL;
b97bf3fd8   Per Liden   [TIPC] Initial merge
666
667
  	}
  	if ((type < TIPC_RESERVED_TYPES) && !atomic_read(&rsv_publ_ok)) {
f131072c3   Allan Stephens   [TIPC]: First pha...
668
669
  		warn("Publication failed, reserved name {%u,%u,%u}
  ",
b97bf3fd8   Per Liden   [TIPC] Initial merge
670
  		     type, lower, upper);
1fc54d8f4   Sam Ravnborg   [TIPC]: Fix simpl...
671
  		return NULL;
b97bf3fd8   Per Liden   [TIPC] Initial merge
672
  	}
4323add67   Per Liden   [TIPC] Avoid poll...
673
  	write_lock_bh(&tipc_nametbl_lock);
b97bf3fd8   Per Liden   [TIPC] Initial merge
674
  	table.local_publ_count++;
4323add67   Per Liden   [TIPC] Avoid poll...
675
  	publ = tipc_nametbl_insert_publ(type, lower, upper, scope,
b97bf3fd8   Per Liden   [TIPC] Initial merge
676
  				   tipc_own_addr, port_ref, key);
a016892cd   Allan Stephens   tipc: remove extr...
677
  	if (publ && (scope != TIPC_NODE_SCOPE))
4323add67   Per Liden   [TIPC] Avoid poll...
678
  		tipc_named_publish(publ);
4323add67   Per Liden   [TIPC] Avoid poll...
679
  	write_unlock_bh(&tipc_nametbl_lock);
b97bf3fd8   Per Liden   [TIPC] Initial merge
680
681
682
683
  	return publ;
  }
  
  /**
4323add67   Per Liden   [TIPC] Avoid poll...
684
   * tipc_nametbl_withdraw - withdraw name publication from network name tables
b97bf3fd8   Per Liden   [TIPC] Initial merge
685
   */
4323add67   Per Liden   [TIPC] Avoid poll...
686
  int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key)
b97bf3fd8   Per Liden   [TIPC] Initial merge
687
688
  {
  	struct publication *publ;
4323add67   Per Liden   [TIPC] Avoid poll...
689
690
  	write_lock_bh(&tipc_nametbl_lock);
  	publ = tipc_nametbl_remove_publ(type, lower, tipc_own_addr, ref, key);
f131072c3   Allan Stephens   [TIPC]: First pha...
691
  	if (likely(publ)) {
b97bf3fd8   Per Liden   [TIPC] Initial merge
692
693
  		table.local_publ_count--;
  		if (publ->scope != TIPC_NODE_SCOPE)
4323add67   Per Liden   [TIPC] Avoid poll...
694
695
  			tipc_named_withdraw(publ);
  		write_unlock_bh(&tipc_nametbl_lock);
b97bf3fd8   Per Liden   [TIPC] Initial merge
696
697
698
699
  		list_del_init(&publ->pport_list);
  		kfree(publ);
  		return 1;
  	}
4323add67   Per Liden   [TIPC] Avoid poll...
700
  	write_unlock_bh(&tipc_nametbl_lock);
f131072c3   Allan Stephens   [TIPC]: First pha...
701
702
703
704
705
  	err("Unable to remove local publication
  "
  	    "(type=%u, lower=%u, ref=%u, key=%u)
  ",
  	    type, lower, ref, key);
b97bf3fd8   Per Liden   [TIPC] Initial merge
706
707
708
709
  	return 0;
  }
  
  /**
4323add67   Per Liden   [TIPC] Avoid poll...
710
   * tipc_nametbl_subscribe - add a subscription object to the name table
b97bf3fd8   Per Liden   [TIPC] Initial merge
711
   */
fead39098   Paul Gortmaker   tipc: rename stru...
712
  void tipc_nametbl_subscribe(struct tipc_subscription *s)
b97bf3fd8   Per Liden   [TIPC] Initial merge
713
714
715
  {
  	u32 type = s->seq.type;
  	struct name_seq *seq;
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
716
  	write_lock_bh(&tipc_nametbl_lock);
b97bf3fd8   Per Liden   [TIPC] Initial merge
717
  	seq = nametbl_find_seq(type);
a016892cd   Allan Stephens   tipc: remove extr...
718
  	if (!seq)
4323add67   Per Liden   [TIPC] Avoid poll...
719
  		seq = tipc_nameseq_create(type, &table.types[hash(type)]);
0e65967e3   Allan Stephens   tipc: cleanup var...
720
  	if (seq) {
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
721
  		spin_lock_bh(&seq->lock);
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
722
723
724
  		tipc_nameseq_subscribe(seq, s);
  		spin_unlock_bh(&seq->lock);
  	} else {
f131072c3   Allan Stephens   [TIPC]: First pha...
725
726
727
  		warn("Failed to create subscription for {%u,%u,%u}
  ",
  		     s->seq.type, s->seq.lower, s->seq.upper);
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
728
729
  	}
  	write_unlock_bh(&tipc_nametbl_lock);
b97bf3fd8   Per Liden   [TIPC] Initial merge
730
731
732
  }
  
  /**
4323add67   Per Liden   [TIPC] Avoid poll...
733
   * tipc_nametbl_unsubscribe - remove a subscription object from name table
b97bf3fd8   Per Liden   [TIPC] Initial merge
734
   */
fead39098   Paul Gortmaker   tipc: rename stru...
735
  void tipc_nametbl_unsubscribe(struct tipc_subscription *s)
b97bf3fd8   Per Liden   [TIPC] Initial merge
736
737
  {
  	struct name_seq *seq;
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
738
739
  	write_lock_bh(&tipc_nametbl_lock);
  	seq = nametbl_find_seq(s->seq.type);
0e65967e3   Allan Stephens   tipc: cleanup var...
740
  	if (seq != NULL) {
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
741
742
743
744
745
746
747
748
749
750
  		spin_lock_bh(&seq->lock);
  		list_del_init(&s->nameseq_list);
  		spin_unlock_bh(&seq->lock);
  		if ((seq->first_free == 0) && list_empty(&seq->subscriptions)) {
  			hlist_del_init(&seq->ns_list);
  			kfree(seq->sseqs);
  			kfree(seq);
  		}
  	}
  	write_unlock_bh(&tipc_nametbl_lock);
b97bf3fd8   Per Liden   [TIPC] Initial merge
751
752
753
754
755
756
757
758
759
760
761
  }
  
  
  /**
   * subseq_list: print specified sub-sequence contents into the given buffer
   */
  
  static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth,
  			u32 index)
  {
  	char portIdStr[27];
c2de58140   Allan Stephens   tipc: Minor enhan...
762
  	const char *scope_str[] = {"", " zone", " cluster", " node"};
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
763
764
  	struct publication *publ;
  	struct name_info *info;
b97bf3fd8   Per Liden   [TIPC] Initial merge
765
766
  
  	tipc_printf(buf, "%-10u %-10u ", sseq->lower, sseq->upper);
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
767
  	if (depth == 2) {
b97bf3fd8   Per Liden   [TIPC] Initial merge
768
769
770
771
  		tipc_printf(buf, "
  ");
  		return;
  	}
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
772
773
774
  	info = sseq->info;
  
  	list_for_each_entry(publ, &info->zone_list, zone_list) {
0e65967e3   Allan Stephens   tipc: cleanup var...
775
  		sprintf(portIdStr, "<%u.%u.%u:%u>",
b97bf3fd8   Per Liden   [TIPC] Initial merge
776
777
778
779
  			 tipc_zone(publ->node), tipc_cluster(publ->node),
  			 tipc_node(publ->node), publ->ref);
  		tipc_printf(buf, "%-26s ", portIdStr);
  		if (depth > 3) {
c2de58140   Allan Stephens   tipc: Minor enhan...
780
781
  			tipc_printf(buf, "%-10u %s", publ->key,
  				    scope_str[publ->scope]);
b97bf3fd8   Per Liden   [TIPC] Initial merge
782
  		}
f6f0a4d2d   Allan Stephens   tipc: Convert nam...
783
784
785
786
  		if (!list_is_last(&publ->zone_list, &info->zone_list))
  			tipc_printf(buf, "
  %33s", " ");
  	};
b97bf3fd8   Per Liden   [TIPC] Initial merge
787
788
789
790
791
792
793
794
795
796
797
798
799
800
  
  	tipc_printf(buf, "
  ");
  }
  
  /**
   * nameseq_list: print specified name sequence contents into the given buffer
   */
  
  static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth,
  			 u32 type, u32 lowbound, u32 upbound, u32 index)
  {
  	struct sub_seq *sseq;
  	char typearea[11];
0f15d3645   Allan Stephens   tipc: Prevent dis...
801
802
  	if (seq->first_free == 0)
  		return;
b97bf3fd8   Per Liden   [TIPC] Initial merge
803
804
805
806
807
808
809
810
811
812
813
  	sprintf(typearea, "%-10u", seq->type);
  
  	if (depth == 1) {
  		tipc_printf(buf, "%s
  ", typearea);
  		return;
  	}
  
  	for (sseq = seq->sseqs; sseq != &seq->sseqs[seq->first_free]; sseq++) {
  		if ((lowbound <= sseq->upper) && (upbound >= sseq->lower)) {
  			tipc_printf(buf, "%s ", typearea);
307fdf5e7   Allan Stephens   tipc: Add missing...
814
  			spin_lock_bh(&seq->lock);
b97bf3fd8   Per Liden   [TIPC] Initial merge
815
  			subseq_list(sseq, buf, depth, index);
307fdf5e7   Allan Stephens   tipc: Add missing...
816
  			spin_unlock_bh(&seq->lock);
b97bf3fd8   Per Liden   [TIPC] Initial merge
817
818
819
820
821
822
823
824
825
826
827
  			sprintf(typearea, "%10s", " ");
  		}
  	}
  }
  
  /**
   * nametbl_header - print name table header into the given buffer
   */
  
  static void nametbl_header(struct print_buf *buf, u32 depth)
  {
c2de58140   Allan Stephens   tipc: Minor enhan...
828
829
830
831
832
833
834
835
836
837
838
839
840
  	const char *header[] = {
  		"Type       ",
  		"Lower      Upper      ",
  		"Port Identity              ",
  		"Publication Scope"
  	};
  
  	int i;
  
  	if (depth > 4)
  		depth = 4;
  	for (i = 0; i < depth; i++)
  		tipc_printf(buf, header[i]);
b97bf3fd8   Per Liden   [TIPC] Initial merge
841
842
843
844
845
846
847
  	tipc_printf(buf, "
  ");
  }
  
  /**
   * nametbl_list - print specified name table contents into the given buffer
   */
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
848
  static void nametbl_list(struct print_buf *buf, u32 depth_info,
b97bf3fd8   Per Liden   [TIPC] Initial merge
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
  			 u32 type, u32 lowbound, u32 upbound)
  {
  	struct hlist_head *seq_head;
  	struct hlist_node *seq_node;
  	struct name_seq *seq;
  	int all_types;
  	u32 depth;
  	u32 i;
  
  	all_types = (depth_info & TIPC_NTQ_ALLTYPES);
  	depth = (depth_info & ~TIPC_NTQ_ALLTYPES);
  
  	if (depth == 0)
  		return;
  
  	if (all_types) {
  		/* display all entries in name table to specified depth */
  		nametbl_header(buf, depth);
  		lowbound = 0;
  		upbound = ~0;
  		for (i = 0; i < tipc_nametbl_size; i++) {
  			seq_head = &table.types[i];
  			hlist_for_each_entry(seq, seq_node, seq_head, ns_list) {
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
872
  				nameseq_list(seq, buf, depth, seq->type,
b97bf3fd8   Per Liden   [TIPC] Initial merge
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
  					     lowbound, upbound, i);
  			}
  		}
  	} else {
  		/* display only the sequence that matches the specified type */
  		if (upbound < lowbound) {
  			tipc_printf(buf, "invalid name sequence specified
  ");
  			return;
  		}
  		nametbl_header(buf, depth);
  		i = hash(type);
  		seq_head = &table.types[i];
  		hlist_for_each_entry(seq, seq_node, seq_head, ns_list) {
  			if (seq->type == type) {
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
888
  				nameseq_list(seq, buf, depth, type,
b97bf3fd8   Per Liden   [TIPC] Initial merge
889
890
891
892
893
894
  					     lowbound, upbound, i);
  				break;
  			}
  		}
  	}
  }
b97bf3fd8   Per Liden   [TIPC] Initial merge
895
  #define MAX_NAME_TBL_QUERY 32768
4323add67   Per Liden   [TIPC] Avoid poll...
896
  struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space)
b97bf3fd8   Per Liden   [TIPC] Initial merge
897
898
899
900
901
902
903
904
  {
  	struct sk_buff *buf;
  	struct tipc_name_table_query *argv;
  	struct tlv_desc *rep_tlv;
  	struct print_buf b;
  	int str_len;
  
  	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NAME_TBL_QUERY))
4323add67   Per Liden   [TIPC] Avoid poll...
905
  		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
b97bf3fd8   Per Liden   [TIPC] Initial merge
906

4323add67   Per Liden   [TIPC] Avoid poll...
907
  	buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_NAME_TBL_QUERY));
b97bf3fd8   Per Liden   [TIPC] Initial merge
908
909
910
911
  	if (!buf)
  		return NULL;
  
  	rep_tlv = (struct tlv_desc *)buf->data;
4323add67   Per Liden   [TIPC] Avoid poll...
912
  	tipc_printbuf_init(&b, TLV_DATA(rep_tlv), MAX_NAME_TBL_QUERY);
b97bf3fd8   Per Liden   [TIPC] Initial merge
913
  	argv = (struct tipc_name_table_query *)TLV_DATA(req_tlv_area);
4323add67   Per Liden   [TIPC] Avoid poll...
914
  	read_lock_bh(&tipc_nametbl_lock);
c43072852   YOSHIFUJI Hideaki   [NET] TIPC: Fix w...
915
  	nametbl_list(&b, ntohl(argv->depth), ntohl(argv->type),
b97bf3fd8   Per Liden   [TIPC] Initial merge
916
  		     ntohl(argv->lowbound), ntohl(argv->upbound));
4323add67   Per Liden   [TIPC] Avoid poll...
917
918
  	read_unlock_bh(&tipc_nametbl_lock);
  	str_len = tipc_printbuf_validate(&b);
b97bf3fd8   Per Liden   [TIPC] Initial merge
919
920
921
922
923
924
  
  	skb_put(buf, TLV_SPACE(str_len));
  	TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
  
  	return buf;
  }
4323add67   Per Liden   [TIPC] Avoid poll...
925
  int tipc_nametbl_init(void)
b97bf3fd8   Per Liden   [TIPC] Initial merge
926
  {
4e3e6dcb4   Allan Stephens   tipc: Enhancement...
927
928
  	table.types = kcalloc(tipc_nametbl_size, sizeof(struct hlist_head),
  			      GFP_ATOMIC);
b97bf3fd8   Per Liden   [TIPC] Initial merge
929
930
  	if (!table.types)
  		return -ENOMEM;
b97bf3fd8   Per Liden   [TIPC] Initial merge
931
  	table.local_publ_count = 0;
b97bf3fd8   Per Liden   [TIPC] Initial merge
932
933
  	return 0;
  }
4323add67   Per Liden   [TIPC] Avoid poll...
934
  void tipc_nametbl_stop(void)
b97bf3fd8   Per Liden   [TIPC] Initial merge
935
  {
b97bf3fd8   Per Liden   [TIPC] Initial merge
936
937
938
939
  	u32 i;
  
  	if (!table.types)
  		return;
f131072c3   Allan Stephens   [TIPC]: First pha...
940
  	/* Verify name table is empty, then release it */
4323add67   Per Liden   [TIPC] Avoid poll...
941
  	write_lock_bh(&tipc_nametbl_lock);
b97bf3fd8   Per Liden   [TIPC] Initial merge
942
  	for (i = 0; i < tipc_nametbl_size; i++) {
f131072c3   Allan Stephens   [TIPC]: First pha...
943
944
945
  		if (!hlist_empty(&table.types[i]))
  			err("tipc_nametbl_stop(): hash chain %u is non-null
  ", i);
b97bf3fd8   Per Liden   [TIPC] Initial merge
946
947
948
  	}
  	kfree(table.types);
  	table.types = NULL;
4323add67   Per Liden   [TIPC] Avoid poll...
949
  	write_unlock_bh(&tipc_nametbl_lock);
b97bf3fd8   Per Liden   [TIPC] Initial merge
950
  }
f131072c3   Allan Stephens   [TIPC]: First pha...
951