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