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