name_table.c 27 KB

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