1 /* 2 * net/tipc/name_table.c: TIPC name table code 3 * 4 * Copyright (c) 2000-2006, Ericsson AB 5 * Copyright (c) 2004-2005, 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 "dbg.h" 40 #include "name_table.h" 41 #include "name_distr.h" 42 #include "addr.h" 43 #include "node_subscr.h" 44 #include "subscr.h" 45 #include "port.h" 46 #include "cluster.h" 47 #include "bcast.h" 48 49 static int tipc_nametbl_size = 1024; /* must be a power of 2 */ 50 51 /** 52 * struct sub_seq - container for all published instances of a name sequence 53 * @lower: name sequence lower bound 54 * @upper: name sequence upper bound 55 * @node_list: circular list of matching publications with >= node scope 56 * @cluster_list: circular list of matching publications with >= cluster scope 57 * @zone_list: circular list of matching publications with >= zone scope 58 */ 59 60 struct sub_seq { 61 u32 lower; 62 u32 upper; 63 struct publication *node_list; 64 struct publication *cluster_list; 65 struct publication *zone_list; 66 }; 67 68 /** 69 * struct name_seq - container for all published instances of a name type 70 * @type: 32 bit 'type' value for name sequence 71 * @sseq: pointer to dynamically-sized array of sub-sequences of this 'type'; 72 * sub-sequences are sorted in ascending order 73 * @alloc: number of sub-sequences currently in array 74 * @first_free: array index of first unused sub-sequence entry 75 * @ns_list: links to adjacent name sequences in hash chain 76 * @subscriptions: list of subscriptions for this 'type' 77 * @lock: spinlock controlling access to name sequence structure 78 */ 79 80 struct name_seq { 81 u32 type; 82 struct sub_seq *sseqs; 83 u32 alloc; 84 u32 first_free; 85 struct hlist_node ns_list; 86 struct list_head subscriptions; 87 spinlock_t lock; 88 }; 89 90 /** 91 * struct name_table - table containing all existing port name publications 92 * @types: pointer to fixed-sized array of name sequence lists, 93 * accessed via hashing on 'type'; name sequence lists are *not* sorted 94 * @local_publ_count: number of publications issued by this node 95 */ 96 97 struct name_table { 98 struct hlist_head *types; 99 u32 local_publ_count; 100 }; 101 102 static struct name_table table = { NULL } ; 103 static atomic_t rsv_publ_ok = ATOMIC_INIT(0); 104 DEFINE_RWLOCK(tipc_nametbl_lock); 105 106 107 static int hash(int x) 108 { 109 return(x & (tipc_nametbl_size - 1)); 110 } 111 112 /** 113 * publ_create - create a publication structure 114 */ 115 116 static struct publication *publ_create(u32 type, u32 lower, u32 upper, 117 u32 scope, u32 node, u32 port_ref, 118 u32 key) 119 { 120 struct publication *publ = kzalloc(sizeof(*publ), GFP_ATOMIC); 121 if (publ == NULL) { 122 warn("Publication creation failure, no memory\n"); 123 return NULL; 124 } 125 126 publ->type = type; 127 publ->lower = lower; 128 publ->upper = upper; 129 publ->scope = scope; 130 publ->node = node; 131 publ->ref = port_ref; 132 publ->key = key; 133 INIT_LIST_HEAD(&publ->local_list); 134 INIT_LIST_HEAD(&publ->pport_list); 135 INIT_LIST_HEAD(&publ->subscr.nodesub_list); 136 return publ; 137 } 138 139 /** 140 * tipc_subseq_alloc - allocate a specified number of sub-sequence structures 141 */ 142 143 static struct sub_seq *tipc_subseq_alloc(u32 cnt) 144 { 145 struct sub_seq *sseq = kcalloc(cnt, sizeof(struct sub_seq), GFP_ATOMIC); 146 return sseq; 147 } 148 149 /** 150 * tipc_nameseq_create - create a name sequence structure for the specified 'type' 151 * 152 * Allocates a single sub-sequence structure and sets it to all 0's. 153 */ 154 155 static struct name_seq *tipc_nameseq_create(u32 type, struct hlist_head *seq_head) 156 { 157 struct name_seq *nseq = kzalloc(sizeof(*nseq), GFP_ATOMIC); 158 struct sub_seq *sseq = tipc_subseq_alloc(1); 159 160 if (!nseq || !sseq) { 161 warn("Name sequence creation failed, no memory\n"); 162 kfree(nseq); 163 kfree(sseq); 164 return NULL; 165 } 166 167 spin_lock_init(&nseq->lock); 168 nseq->type = type; 169 nseq->sseqs = sseq; 170 dbg("tipc_nameseq_create(): nseq = %p, type %u, ssseqs %p, ff: %u\n", 171 nseq, type, nseq->sseqs, nseq->first_free); 172 nseq->alloc = 1; 173 INIT_HLIST_NODE(&nseq->ns_list); 174 INIT_LIST_HEAD(&nseq->subscriptions); 175 hlist_add_head(&nseq->ns_list, seq_head); 176 return nseq; 177 } 178 179 /** 180 * nameseq_find_subseq - find sub-sequence (if any) matching a name instance 181 * 182 * Very time-critical, so binary searches through sub-sequence array. 183 */ 184 185 static struct sub_seq *nameseq_find_subseq(struct name_seq *nseq, 186 u32 instance) 187 { 188 struct sub_seq *sseqs = nseq->sseqs; 189 int low = 0; 190 int high = nseq->first_free - 1; 191 int mid; 192 193 while (low <= high) { 194 mid = (low + high) / 2; 195 if (instance < sseqs[mid].lower) 196 high = mid - 1; 197 else if (instance > sseqs[mid].upper) 198 low = mid + 1; 199 else 200 return &sseqs[mid]; 201 } 202 return NULL; 203 } 204 205 /** 206 * nameseq_locate_subseq - determine position of name instance in sub-sequence 207 * 208 * Returns index in sub-sequence array of the entry that contains the specified 209 * instance value; if no entry contains that value, returns the position 210 * where a new entry for it would be inserted in the array. 211 * 212 * Note: Similar to binary search code for locating a sub-sequence. 213 */ 214 215 static u32 nameseq_locate_subseq(struct name_seq *nseq, u32 instance) 216 { 217 struct sub_seq *sseqs = nseq->sseqs; 218 int low = 0; 219 int high = nseq->first_free - 1; 220 int mid; 221 222 while (low <= high) { 223 mid = (low + high) / 2; 224 if (instance < sseqs[mid].lower) 225 high = mid - 1; 226 else if (instance > sseqs[mid].upper) 227 low = mid + 1; 228 else 229 return mid; 230 } 231 return low; 232 } 233 234 /** 235 * tipc_nameseq_insert_publ - 236 */ 237 238 static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, 239 u32 type, u32 lower, u32 upper, 240 u32 scope, u32 node, u32 port, u32 key) 241 { 242 struct subscription *s; 243 struct subscription *st; 244 struct publication *publ; 245 struct sub_seq *sseq; 246 int created_subseq = 0; 247 248 sseq = nameseq_find_subseq(nseq, lower); 249 dbg("nameseq_ins: for seq %p, {%u,%u}, found sseq %p\n", 250 nseq, type, lower, sseq); 251 if (sseq) { 252 253 /* Lower end overlaps existing entry => need an exact match */ 254 255 if ((sseq->lower != lower) || (sseq->upper != upper)) { 256 warn("Cannot publish {%u,%u,%u}, overlap error\n", 257 type, lower, upper); 258 return NULL; 259 } 260 } else { 261 u32 inspos; 262 struct sub_seq *freesseq; 263 264 /* Find where lower end should be inserted */ 265 266 inspos = nameseq_locate_subseq(nseq, lower); 267 268 /* Fail if upper end overlaps into an existing entry */ 269 270 if ((inspos < nseq->first_free) && 271 (upper >= nseq->sseqs[inspos].lower)) { 272 warn("Cannot publish {%u,%u,%u}, overlap error\n", 273 type, lower, upper); 274 return NULL; 275 } 276 277 /* Ensure there is space for new sub-sequence */ 278 279 if (nseq->first_free == nseq->alloc) { 280 struct sub_seq *sseqs = tipc_subseq_alloc(nseq->alloc * 2); 281 282 if (!sseqs) { 283 warn("Cannot publish {%u,%u,%u}, no memory\n", 284 type, lower, upper); 285 return NULL; 286 } 287 dbg("Allocated %u more sseqs\n", nseq->alloc); 288 memcpy(sseqs, nseq->sseqs, 289 nseq->alloc * sizeof(struct sub_seq)); 290 kfree(nseq->sseqs); 291 nseq->sseqs = sseqs; 292 nseq->alloc *= 2; 293 } 294 dbg("Have %u sseqs for type %u\n", nseq->alloc, type); 295 296 /* Insert new sub-sequence */ 297 298 dbg("ins in pos %u, ff = %u\n", inspos, nseq->first_free); 299 sseq = &nseq->sseqs[inspos]; 300 freesseq = &nseq->sseqs[nseq->first_free]; 301 memmove(sseq + 1, sseq, (freesseq - sseq) * sizeof (*sseq)); 302 memset(sseq, 0, sizeof (*sseq)); 303 nseq->first_free++; 304 sseq->lower = lower; 305 sseq->upper = upper; 306 created_subseq = 1; 307 } 308 dbg("inserting {%u,%u,%u} from <0x%x:%u> into sseq %p(%u,%u) of seq %p\n", 309 type, lower, upper, node, port, sseq, 310 sseq->lower, sseq->upper, nseq); 311 312 /* Insert a publication: */ 313 314 publ = publ_create(type, lower, upper, scope, node, port, key); 315 if (!publ) 316 return NULL; 317 dbg("inserting publ %p, node=0x%x publ->node=0x%x, subscr->node=%p\n", 318 publ, node, publ->node, publ->subscr.node); 319 320 if (!sseq->zone_list) 321 sseq->zone_list = publ->zone_list_next = publ; 322 else { 323 publ->zone_list_next = sseq->zone_list->zone_list_next; 324 sseq->zone_list->zone_list_next = publ; 325 } 326 327 if (in_own_cluster(node)) { 328 if (!sseq->cluster_list) 329 sseq->cluster_list = publ->cluster_list_next = publ; 330 else { 331 publ->cluster_list_next = 332 sseq->cluster_list->cluster_list_next; 333 sseq->cluster_list->cluster_list_next = publ; 334 } 335 } 336 337 if (node == tipc_own_addr) { 338 if (!sseq->node_list) 339 sseq->node_list = publ->node_list_next = publ; 340 else { 341 publ->node_list_next = sseq->node_list->node_list_next; 342 sseq->node_list->node_list_next = publ; 343 } 344 } 345 346 /* 347 * Any subscriptions waiting for notification? 348 */ 349 list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) { 350 dbg("calling report_overlap()\n"); 351 tipc_subscr_report_overlap(s, 352 publ->lower, 353 publ->upper, 354 TIPC_PUBLISHED, 355 publ->ref, 356 publ->node, 357 created_subseq); 358 } 359 return publ; 360 } 361 362 /** 363 * tipc_nameseq_remove_publ - 364 * 365 * NOTE: There may be cases where TIPC is asked to remove a publication 366 * that is not in the name table. For example, if another node issues a 367 * publication for a name sequence that overlaps an existing name sequence 368 * the publication will not be recorded, which means the publication won't 369 * be found when the name sequence is later withdrawn by that node. 370 * A failed withdraw request simply returns a failure indication and lets the 371 * caller issue any error or warning messages associated with such a problem. 372 */ 373 374 static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 inst, 375 u32 node, u32 ref, u32 key) 376 { 377 struct publication *publ; 378 struct publication *curr; 379 struct publication *prev; 380 struct sub_seq *sseq = nameseq_find_subseq(nseq, inst); 381 struct sub_seq *free; 382 struct subscription *s, *st; 383 int removed_subseq = 0; 384 385 if (!sseq) 386 return NULL; 387 388 dbg("tipc_nameseq_remove_publ: seq: %p, sseq %p, {%u,%u}, key %u\n", 389 nseq, sseq, nseq->type, inst, key); 390 391 /* Remove publication from zone scope list */ 392 393 prev = sseq->zone_list; 394 publ = sseq->zone_list->zone_list_next; 395 while ((publ->key != key) || (publ->ref != ref) || 396 (publ->node && (publ->node != node))) { 397 prev = publ; 398 publ = publ->zone_list_next; 399 if (prev == sseq->zone_list) { 400 401 /* Prevent endless loop if publication not found */ 402 403 return NULL; 404 } 405 } 406 if (publ != sseq->zone_list) 407 prev->zone_list_next = publ->zone_list_next; 408 else if (publ->zone_list_next != publ) { 409 prev->zone_list_next = publ->zone_list_next; 410 sseq->zone_list = publ->zone_list_next; 411 } else { 412 sseq->zone_list = NULL; 413 } 414 415 /* Remove publication from cluster scope list, if present */ 416 417 if (in_own_cluster(node)) { 418 prev = sseq->cluster_list; 419 curr = sseq->cluster_list->cluster_list_next; 420 while (curr != publ) { 421 prev = curr; 422 curr = curr->cluster_list_next; 423 if (prev == sseq->cluster_list) { 424 425 /* Prevent endless loop for malformed list */ 426 427 err("Unable to de-list cluster publication\n" 428 "{%u%u}, node=0x%x, ref=%u, key=%u)\n", 429 publ->type, publ->lower, publ->node, 430 publ->ref, publ->key); 431 goto end_cluster; 432 } 433 } 434 if (publ != sseq->cluster_list) 435 prev->cluster_list_next = publ->cluster_list_next; 436 else if (publ->cluster_list_next != publ) { 437 prev->cluster_list_next = publ->cluster_list_next; 438 sseq->cluster_list = publ->cluster_list_next; 439 } else { 440 sseq->cluster_list = NULL; 441 } 442 } 443 end_cluster: 444 445 /* Remove publication from node scope list, if present */ 446 447 if (node == tipc_own_addr) { 448 prev = sseq->node_list; 449 curr = sseq->node_list->node_list_next; 450 while (curr != publ) { 451 prev = curr; 452 curr = curr->node_list_next; 453 if (prev == sseq->node_list) { 454 455 /* Prevent endless loop for malformed list */ 456 457 err("Unable to de-list node publication\n" 458 "{%u%u}, node=0x%x, ref=%u, key=%u)\n", 459 publ->type, publ->lower, publ->node, 460 publ->ref, publ->key); 461 goto end_node; 462 } 463 } 464 if (publ != sseq->node_list) 465 prev->node_list_next = publ->node_list_next; 466 else if (publ->node_list_next != publ) { 467 prev->node_list_next = publ->node_list_next; 468 sseq->node_list = publ->node_list_next; 469 } else { 470 sseq->node_list = NULL; 471 } 472 } 473 end_node: 474 475 /* Contract subseq list if no more publications for that subseq */ 476 477 if (!sseq->zone_list) { 478 free = &nseq->sseqs[nseq->first_free--]; 479 memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof (*sseq)); 480 removed_subseq = 1; 481 } 482 483 /* Notify any waiting subscriptions */ 484 485 list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) { 486 tipc_subscr_report_overlap(s, 487 publ->lower, 488 publ->upper, 489 TIPC_WITHDRAWN, 490 publ->ref, 491 publ->node, 492 removed_subseq); 493 } 494 495 return publ; 496 } 497 498 /** 499 * tipc_nameseq_subscribe: attach a subscription, and issue 500 * the prescribed number of events if there is any sub- 501 * sequence overlapping with the requested sequence 502 */ 503 504 static void tipc_nameseq_subscribe(struct name_seq *nseq, struct subscription *s) 505 { 506 struct sub_seq *sseq = nseq->sseqs; 507 508 list_add(&s->nameseq_list, &nseq->subscriptions); 509 510 if (!sseq) 511 return; 512 513 while (sseq != &nseq->sseqs[nseq->first_free]) { 514 struct publication *zl = sseq->zone_list; 515 if (zl && tipc_subscr_overlap(s,sseq->lower,sseq->upper)) { 516 struct publication *crs = zl; 517 int must_report = 1; 518 519 do { 520 tipc_subscr_report_overlap(s, 521 sseq->lower, 522 sseq->upper, 523 TIPC_PUBLISHED, 524 crs->ref, 525 crs->node, 526 must_report); 527 must_report = 0; 528 crs = crs->zone_list_next; 529 } while (crs != zl); 530 } 531 sseq++; 532 } 533 } 534 535 static struct name_seq *nametbl_find_seq(u32 type) 536 { 537 struct hlist_head *seq_head; 538 struct hlist_node *seq_node; 539 struct name_seq *ns; 540 541 dbg("find_seq %u,(%u,0x%x) table = %p, hash[type] = %u\n", 542 type, ntohl(type), type, table.types, hash(type)); 543 544 seq_head = &table.types[hash(type)]; 545 hlist_for_each_entry(ns, seq_node, seq_head, ns_list) { 546 if (ns->type == type) { 547 dbg("found %p\n", ns); 548 return ns; 549 } 550 } 551 552 return NULL; 553 }; 554 555 struct publication *tipc_nametbl_insert_publ(u32 type, u32 lower, u32 upper, 556 u32 scope, u32 node, u32 port, u32 key) 557 { 558 struct name_seq *seq = nametbl_find_seq(type); 559 560 dbg("tipc_nametbl_insert_publ: {%u,%u,%u} found %p\n", type, lower, upper, seq); 561 if (lower > upper) { 562 warn("Failed to publish illegal {%u,%u,%u}\n", 563 type, lower, upper); 564 return NULL; 565 } 566 567 dbg("Publishing {%u,%u,%u} from 0x%x\n", type, lower, upper, node); 568 if (!seq) { 569 seq = tipc_nameseq_create(type, &table.types[hash(type)]); 570 dbg("tipc_nametbl_insert_publ: created %p\n", seq); 571 } 572 if (!seq) 573 return NULL; 574 575 return tipc_nameseq_insert_publ(seq, type, lower, upper, 576 scope, node, port, key); 577 } 578 579 struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower, 580 u32 node, u32 ref, u32 key) 581 { 582 struct publication *publ; 583 struct name_seq *seq = nametbl_find_seq(type); 584 585 if (!seq) 586 return NULL; 587 588 dbg("Withdrawing {%u,%u} from 0x%x\n", type, lower, node); 589 publ = tipc_nameseq_remove_publ(seq, lower, node, ref, key); 590 591 if (!seq->first_free && list_empty(&seq->subscriptions)) { 592 hlist_del_init(&seq->ns_list); 593 kfree(seq->sseqs); 594 kfree(seq); 595 } 596 return publ; 597 } 598 599 /* 600 * tipc_nametbl_translate(): Translate tipc_name -> tipc_portid. 601 * Very time-critical. 602 * 603 * Note: on entry 'destnode' is the search domain used during translation; 604 * on exit it passes back the node address of the matching port (if any) 605 */ 606 607 u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode) 608 { 609 struct sub_seq *sseq; 610 struct publication *publ = NULL; 611 struct name_seq *seq; 612 u32 ref; 613 614 if (!in_scope(*destnode, tipc_own_addr)) 615 return 0; 616 617 read_lock_bh(&tipc_nametbl_lock); 618 seq = nametbl_find_seq(type); 619 if (unlikely(!seq)) 620 goto not_found; 621 sseq = nameseq_find_subseq(seq, instance); 622 if (unlikely(!sseq)) 623 goto not_found; 624 spin_lock_bh(&seq->lock); 625 626 /* Closest-First Algorithm: */ 627 if (likely(!*destnode)) { 628 publ = sseq->node_list; 629 if (publ) { 630 sseq->node_list = publ->node_list_next; 631 found: 632 ref = publ->ref; 633 *destnode = publ->node; 634 spin_unlock_bh(&seq->lock); 635 read_unlock_bh(&tipc_nametbl_lock); 636 return ref; 637 } 638 publ = sseq->cluster_list; 639 if (publ) { 640 sseq->cluster_list = publ->cluster_list_next; 641 goto found; 642 } 643 publ = sseq->zone_list; 644 if (publ) { 645 sseq->zone_list = publ->zone_list_next; 646 goto found; 647 } 648 } 649 650 /* Round-Robin Algorithm: */ 651 else if (*destnode == tipc_own_addr) { 652 publ = sseq->node_list; 653 if (publ) { 654 sseq->node_list = publ->node_list_next; 655 goto found; 656 } 657 } else if (in_own_cluster(*destnode)) { 658 publ = sseq->cluster_list; 659 if (publ) { 660 sseq->cluster_list = publ->cluster_list_next; 661 goto found; 662 } 663 } else { 664 publ = sseq->zone_list; 665 if (publ) { 666 sseq->zone_list = publ->zone_list_next; 667 goto found; 668 } 669 } 670 spin_unlock_bh(&seq->lock); 671 not_found: 672 *destnode = 0; 673 read_unlock_bh(&tipc_nametbl_lock); 674 return 0; 675 } 676 677 /** 678 * tipc_nametbl_mc_translate - find multicast destinations 679 * 680 * Creates list of all local ports that overlap the given multicast address; 681 * also determines if any off-node ports overlap. 682 * 683 * Note: Publications with a scope narrower than 'limit' are ignored. 684 * (i.e. local node-scope publications mustn't receive messages arriving 685 * from another node, even if the multcast link brought it here) 686 * 687 * Returns non-zero if any off-node ports overlap 688 */ 689 690 int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit, 691 struct port_list *dports) 692 { 693 struct name_seq *seq; 694 struct sub_seq *sseq; 695 struct sub_seq *sseq_stop; 696 int res = 0; 697 698 read_lock_bh(&tipc_nametbl_lock); 699 seq = nametbl_find_seq(type); 700 if (!seq) 701 goto exit; 702 703 spin_lock_bh(&seq->lock); 704 705 sseq = seq->sseqs + nameseq_locate_subseq(seq, lower); 706 sseq_stop = seq->sseqs + seq->first_free; 707 for (; sseq != sseq_stop; sseq++) { 708 struct publication *publ; 709 710 if (sseq->lower > upper) 711 break; 712 publ = sseq->cluster_list; 713 if (publ && (publ->scope <= limit)) 714 do { 715 if (publ->node == tipc_own_addr) 716 tipc_port_list_add(dports, publ->ref); 717 else 718 res = 1; 719 publ = publ->cluster_list_next; 720 } while (publ != sseq->cluster_list); 721 } 722 723 spin_unlock_bh(&seq->lock); 724 exit: 725 read_unlock_bh(&tipc_nametbl_lock); 726 return res; 727 } 728 729 /** 730 * tipc_nametbl_publish_rsv - publish port name using a reserved name type 731 */ 732 733 int tipc_nametbl_publish_rsv(u32 ref, unsigned int scope, 734 struct tipc_name_seq const *seq) 735 { 736 int res; 737 738 atomic_inc(&rsv_publ_ok); 739 res = tipc_publish(ref, scope, seq); 740 atomic_dec(&rsv_publ_ok); 741 return res; 742 } 743 744 /** 745 * tipc_nametbl_publish - add name publication to network name tables 746 */ 747 748 struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper, 749 u32 scope, u32 port_ref, u32 key) 750 { 751 struct publication *publ; 752 753 if (table.local_publ_count >= tipc_max_publications) { 754 warn("Publication failed, local publication limit reached (%u)\n", 755 tipc_max_publications); 756 return NULL; 757 } 758 if ((type < TIPC_RESERVED_TYPES) && !atomic_read(&rsv_publ_ok)) { 759 warn("Publication failed, reserved name {%u,%u,%u}\n", 760 type, lower, upper); 761 return NULL; 762 } 763 764 write_lock_bh(&tipc_nametbl_lock); 765 table.local_publ_count++; 766 publ = tipc_nametbl_insert_publ(type, lower, upper, scope, 767 tipc_own_addr, port_ref, key); 768 if (publ && (scope != TIPC_NODE_SCOPE)) { 769 tipc_named_publish(publ); 770 } 771 write_unlock_bh(&tipc_nametbl_lock); 772 return publ; 773 } 774 775 /** 776 * tipc_nametbl_withdraw - withdraw name publication from network name tables 777 */ 778 779 int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key) 780 { 781 struct publication *publ; 782 783 dbg("tipc_nametbl_withdraw: {%u,%u}, key=%u\n", type, lower, key); 784 write_lock_bh(&tipc_nametbl_lock); 785 publ = tipc_nametbl_remove_publ(type, lower, tipc_own_addr, ref, key); 786 if (likely(publ)) { 787 table.local_publ_count--; 788 if (publ->scope != TIPC_NODE_SCOPE) 789 tipc_named_withdraw(publ); 790 write_unlock_bh(&tipc_nametbl_lock); 791 list_del_init(&publ->pport_list); 792 kfree(publ); 793 return 1; 794 } 795 write_unlock_bh(&tipc_nametbl_lock); 796 err("Unable to remove local publication\n" 797 "(type=%u, lower=%u, ref=%u, key=%u)\n", 798 type, lower, ref, key); 799 return 0; 800 } 801 802 /** 803 * tipc_nametbl_subscribe - add a subscription object to the name table 804 */ 805 806 void tipc_nametbl_subscribe(struct subscription *s) 807 { 808 u32 type = s->seq.type; 809 struct name_seq *seq; 810 811 write_lock_bh(&tipc_nametbl_lock); 812 seq = nametbl_find_seq(type); 813 if (!seq) { 814 seq = tipc_nameseq_create(type, &table.types[hash(type)]); 815 } 816 if (seq){ 817 spin_lock_bh(&seq->lock); 818 dbg("tipc_nametbl_subscribe:found %p for {%u,%u,%u}\n", 819 seq, type, s->seq.lower, s->seq.upper); 820 tipc_nameseq_subscribe(seq, s); 821 spin_unlock_bh(&seq->lock); 822 } else { 823 warn("Failed to create subscription for {%u,%u,%u}\n", 824 s->seq.type, s->seq.lower, s->seq.upper); 825 } 826 write_unlock_bh(&tipc_nametbl_lock); 827 } 828 829 /** 830 * tipc_nametbl_unsubscribe - remove a subscription object from name table 831 */ 832 833 void tipc_nametbl_unsubscribe(struct subscription *s) 834 { 835 struct name_seq *seq; 836 837 write_lock_bh(&tipc_nametbl_lock); 838 seq = nametbl_find_seq(s->seq.type); 839 if (seq != NULL){ 840 spin_lock_bh(&seq->lock); 841 list_del_init(&s->nameseq_list); 842 spin_unlock_bh(&seq->lock); 843 if ((seq->first_free == 0) && list_empty(&seq->subscriptions)) { 844 hlist_del_init(&seq->ns_list); 845 kfree(seq->sseqs); 846 kfree(seq); 847 } 848 } 849 write_unlock_bh(&tipc_nametbl_lock); 850 } 851 852 853 /** 854 * subseq_list: print specified sub-sequence contents into the given buffer 855 */ 856 857 static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth, 858 u32 index) 859 { 860 char portIdStr[27]; 861 char *scopeStr; 862 struct publication *publ = sseq->zone_list; 863 864 tipc_printf(buf, "%-10u %-10u ", sseq->lower, sseq->upper); 865 866 if (depth == 2 || !publ) { 867 tipc_printf(buf, "\n"); 868 return; 869 } 870 871 do { 872 sprintf (portIdStr, "<%u.%u.%u:%u>", 873 tipc_zone(publ->node), tipc_cluster(publ->node), 874 tipc_node(publ->node), publ->ref); 875 tipc_printf(buf, "%-26s ", portIdStr); 876 if (depth > 3) { 877 if (publ->node != tipc_own_addr) 878 scopeStr = ""; 879 else if (publ->scope == TIPC_NODE_SCOPE) 880 scopeStr = "node"; 881 else if (publ->scope == TIPC_CLUSTER_SCOPE) 882 scopeStr = "cluster"; 883 else 884 scopeStr = "zone"; 885 tipc_printf(buf, "%-10u %s", publ->key, scopeStr); 886 } 887 888 publ = publ->zone_list_next; 889 if (publ == sseq->zone_list) 890 break; 891 892 tipc_printf(buf, "\n%33s", " "); 893 } while (1); 894 895 tipc_printf(buf, "\n"); 896 } 897 898 /** 899 * nameseq_list: print specified name sequence contents into the given buffer 900 */ 901 902 static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth, 903 u32 type, u32 lowbound, u32 upbound, u32 index) 904 { 905 struct sub_seq *sseq; 906 char typearea[11]; 907 908 sprintf(typearea, "%-10u", seq->type); 909 910 if (depth == 1) { 911 tipc_printf(buf, "%s\n", typearea); 912 return; 913 } 914 915 for (sseq = seq->sseqs; sseq != &seq->sseqs[seq->first_free]; sseq++) { 916 if ((lowbound <= sseq->upper) && (upbound >= sseq->lower)) { 917 tipc_printf(buf, "%s ", typearea); 918 subseq_list(sseq, buf, depth, index); 919 sprintf(typearea, "%10s", " "); 920 } 921 } 922 } 923 924 /** 925 * nametbl_header - print name table header into the given buffer 926 */ 927 928 static void nametbl_header(struct print_buf *buf, u32 depth) 929 { 930 tipc_printf(buf, "Type "); 931 932 if (depth > 1) 933 tipc_printf(buf, "Lower Upper "); 934 if (depth > 2) 935 tipc_printf(buf, "Port Identity "); 936 if (depth > 3) 937 tipc_printf(buf, "Publication"); 938 939 tipc_printf(buf, "\n-----------"); 940 941 if (depth > 1) 942 tipc_printf(buf, "--------------------- "); 943 if (depth > 2) 944 tipc_printf(buf, "-------------------------- "); 945 if (depth > 3) 946 tipc_printf(buf, "------------------"); 947 948 tipc_printf(buf, "\n"); 949 } 950 951 /** 952 * nametbl_list - print specified name table contents into the given buffer 953 */ 954 955 static void nametbl_list(struct print_buf *buf, u32 depth_info, 956 u32 type, u32 lowbound, u32 upbound) 957 { 958 struct hlist_head *seq_head; 959 struct hlist_node *seq_node; 960 struct name_seq *seq; 961 int all_types; 962 u32 depth; 963 u32 i; 964 965 all_types = (depth_info & TIPC_NTQ_ALLTYPES); 966 depth = (depth_info & ~TIPC_NTQ_ALLTYPES); 967 968 if (depth == 0) 969 return; 970 971 if (all_types) { 972 /* display all entries in name table to specified depth */ 973 nametbl_header(buf, depth); 974 lowbound = 0; 975 upbound = ~0; 976 for (i = 0; i < tipc_nametbl_size; i++) { 977 seq_head = &table.types[i]; 978 hlist_for_each_entry(seq, seq_node, seq_head, ns_list) { 979 nameseq_list(seq, buf, depth, seq->type, 980 lowbound, upbound, i); 981 } 982 } 983 } else { 984 /* display only the sequence that matches the specified type */ 985 if (upbound < lowbound) { 986 tipc_printf(buf, "invalid name sequence specified\n"); 987 return; 988 } 989 nametbl_header(buf, depth); 990 i = hash(type); 991 seq_head = &table.types[i]; 992 hlist_for_each_entry(seq, seq_node, seq_head, ns_list) { 993 if (seq->type == type) { 994 nameseq_list(seq, buf, depth, type, 995 lowbound, upbound, i); 996 break; 997 } 998 } 999 } 1000 } 1001 1002 #if 0 1003 void tipc_nametbl_print(struct print_buf *buf, const char *str) 1004 { 1005 tipc_printf(buf, str); 1006 read_lock_bh(&tipc_nametbl_lock); 1007 nametbl_list(buf, 0, 0, 0, 0); 1008 read_unlock_bh(&tipc_nametbl_lock); 1009 } 1010 #endif 1011 1012 #define MAX_NAME_TBL_QUERY 32768 1013 1014 struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space) 1015 { 1016 struct sk_buff *buf; 1017 struct tipc_name_table_query *argv; 1018 struct tlv_desc *rep_tlv; 1019 struct print_buf b; 1020 int str_len; 1021 1022 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NAME_TBL_QUERY)) 1023 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 1024 1025 buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_NAME_TBL_QUERY)); 1026 if (!buf) 1027 return NULL; 1028 1029 rep_tlv = (struct tlv_desc *)buf->data; 1030 tipc_printbuf_init(&b, TLV_DATA(rep_tlv), MAX_NAME_TBL_QUERY); 1031 argv = (struct tipc_name_table_query *)TLV_DATA(req_tlv_area); 1032 read_lock_bh(&tipc_nametbl_lock); 1033 nametbl_list(&b, ntohl(argv->depth), ntohl(argv->type), 1034 ntohl(argv->lowbound), ntohl(argv->upbound)); 1035 read_unlock_bh(&tipc_nametbl_lock); 1036 str_len = tipc_printbuf_validate(&b); 1037 1038 skb_put(buf, TLV_SPACE(str_len)); 1039 TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); 1040 1041 return buf; 1042 } 1043 1044 #if 0 1045 void tipc_nametbl_dump(void) 1046 { 1047 nametbl_list(TIPC_CONS, 0, 0, 0, 0); 1048 } 1049 #endif 1050 1051 int tipc_nametbl_init(void) 1052 { 1053 int array_size = sizeof(struct hlist_head) * tipc_nametbl_size; 1054 1055 table.types = kzalloc(array_size, GFP_ATOMIC); 1056 if (!table.types) 1057 return -ENOMEM; 1058 1059 write_lock_bh(&tipc_nametbl_lock); 1060 table.local_publ_count = 0; 1061 write_unlock_bh(&tipc_nametbl_lock); 1062 return 0; 1063 } 1064 1065 void tipc_nametbl_stop(void) 1066 { 1067 u32 i; 1068 1069 if (!table.types) 1070 return; 1071 1072 /* Verify name table is empty, then release it */ 1073 1074 write_lock_bh(&tipc_nametbl_lock); 1075 for (i = 0; i < tipc_nametbl_size; i++) { 1076 if (!hlist_empty(&table.types[i])) 1077 err("tipc_nametbl_stop(): hash chain %u is non-null\n", i); 1078 } 1079 kfree(table.types); 1080 table.types = NULL; 1081 write_unlock_bh(&tipc_nametbl_lock); 1082 } 1083 1084