diff options
Diffstat (limited to 'net/tipc/name_table.c')
| -rw-r--r-- | net/tipc/name_table.c | 180 |
1 files changed, 102 insertions, 78 deletions
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index c8df0223371a..ce09b863528c 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c | |||
| @@ -34,11 +34,13 @@ | |||
| 34 | * POSSIBILITY OF SUCH DAMAGE. | 34 | * POSSIBILITY OF SUCH DAMAGE. |
| 35 | */ | 35 | */ |
| 36 | 36 | ||
| 37 | #include <net/sock.h> | ||
| 37 | #include "core.h" | 38 | #include "core.h" |
| 38 | #include "config.h" | 39 | #include "config.h" |
| 39 | #include "name_table.h" | 40 | #include "name_table.h" |
| 40 | #include "name_distr.h" | 41 | #include "name_distr.h" |
| 41 | #include "subscr.h" | 42 | #include "subscr.h" |
| 43 | #include "bcast.h" | ||
| 42 | 44 | ||
| 43 | #define TIPC_NAMETBL_SIZE 1024 /* must be a power of 2 */ | 45 | #define TIPC_NAMETBL_SIZE 1024 /* must be a power of 2 */ |
| 44 | 46 | ||
| @@ -105,9 +107,6 @@ struct name_seq { | |||
| 105 | struct rcu_head rcu; | 107 | struct rcu_head rcu; |
| 106 | }; | 108 | }; |
| 107 | 109 | ||
| 108 | struct name_table *tipc_nametbl; | ||
| 109 | DEFINE_SPINLOCK(tipc_nametbl_lock); | ||
| 110 | |||
| 111 | static int hash(int x) | 110 | static int hash(int x) |
| 112 | { | 111 | { |
| 113 | return x & (TIPC_NAMETBL_SIZE - 1); | 112 | return x & (TIPC_NAMETBL_SIZE - 1); |
| @@ -228,9 +227,11 @@ static u32 nameseq_locate_subseq(struct name_seq *nseq, u32 instance) | |||
| 228 | /** | 227 | /** |
| 229 | * tipc_nameseq_insert_publ | 228 | * tipc_nameseq_insert_publ |
| 230 | */ | 229 | */ |
| 231 | static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | 230 | static struct publication *tipc_nameseq_insert_publ(struct net *net, |
| 232 | u32 type, u32 lower, u32 upper, | 231 | struct name_seq *nseq, |
| 233 | u32 scope, u32 node, u32 port, u32 key) | 232 | u32 type, u32 lower, |
| 233 | u32 upper, u32 scope, | ||
| 234 | u32 node, u32 port, u32 key) | ||
| 234 | { | 235 | { |
| 235 | struct tipc_subscription *s; | 236 | struct tipc_subscription *s; |
| 236 | struct tipc_subscription *st; | 237 | struct tipc_subscription *st; |
| @@ -315,12 +316,12 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
| 315 | list_add(&publ->zone_list, &info->zone_list); | 316 | list_add(&publ->zone_list, &info->zone_list); |
| 316 | info->zone_list_size++; | 317 | info->zone_list_size++; |
| 317 | 318 | ||
| 318 | if (in_own_cluster(node)) { | 319 | if (in_own_cluster(net, node)) { |
| 319 | list_add(&publ->cluster_list, &info->cluster_list); | 320 | list_add(&publ->cluster_list, &info->cluster_list); |
| 320 | info->cluster_list_size++; | 321 | info->cluster_list_size++; |
| 321 | } | 322 | } |
| 322 | 323 | ||
| 323 | if (in_own_node(node)) { | 324 | if (in_own_node(net, node)) { |
| 324 | list_add(&publ->node_list, &info->node_list); | 325 | list_add(&publ->node_list, &info->node_list); |
| 325 | info->node_list_size++; | 326 | info->node_list_size++; |
| 326 | } | 327 | } |
| @@ -349,8 +350,10 @@ static struct publication *tipc_nameseq_insert_publ(struct name_seq *nseq, | |||
| 349 | * A failed withdraw request simply returns a failure indication and lets the | 350 | * A failed withdraw request simply returns a failure indication and lets the |
| 350 | * caller issue any error or warning messages associated with such a problem. | 351 | * caller issue any error or warning messages associated with such a problem. |
| 351 | */ | 352 | */ |
| 352 | static struct publication *tipc_nameseq_remove_publ(struct name_seq *nseq, u32 inst, | 353 | static struct publication *tipc_nameseq_remove_publ(struct net *net, |
| 353 | u32 node, u32 ref, u32 key) | 354 | struct name_seq *nseq, |
| 355 | u32 inst, u32 node, | ||
| 356 | u32 ref, u32 key) | ||
| 354 | { | 357 | { |
| 355 | struct publication *publ; | 358 | struct publication *publ; |
| 356 | struct sub_seq *sseq = nameseq_find_subseq(nseq, inst); | 359 | struct sub_seq *sseq = nameseq_find_subseq(nseq, inst); |
| @@ -378,13 +381,13 @@ found: | |||
| 378 | info->zone_list_size--; | 381 | info->zone_list_size--; |
| 379 | 382 | ||
| 380 | /* Remove publication from cluster scope list, if present */ | 383 | /* Remove publication from cluster scope list, if present */ |
| 381 | if (in_own_cluster(node)) { | 384 | if (in_own_cluster(net, node)) { |
| 382 | list_del(&publ->cluster_list); | 385 | list_del(&publ->cluster_list); |
| 383 | info->cluster_list_size--; | 386 | info->cluster_list_size--; |
| 384 | } | 387 | } |
| 385 | 388 | ||
| 386 | /* Remove publication from node scope list, if present */ | 389 | /* Remove publication from node scope list, if present */ |
| 387 | if (in_own_node(node)) { | 390 | if (in_own_node(net, node)) { |
| 388 | list_del(&publ->node_list); | 391 | list_del(&publ->node_list); |
| 389 | info->node_list_size--; | 392 | info->node_list_size--; |
| 390 | } | 393 | } |
| @@ -447,12 +450,13 @@ static void tipc_nameseq_subscribe(struct name_seq *nseq, | |||
| 447 | } | 450 | } |
| 448 | } | 451 | } |
| 449 | 452 | ||
| 450 | static struct name_seq *nametbl_find_seq(u32 type) | 453 | static struct name_seq *nametbl_find_seq(struct net *net, u32 type) |
| 451 | { | 454 | { |
| 455 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
| 452 | struct hlist_head *seq_head; | 456 | struct hlist_head *seq_head; |
| 453 | struct name_seq *ns; | 457 | struct name_seq *ns; |
| 454 | 458 | ||
| 455 | seq_head = &tipc_nametbl->seq_hlist[hash(type)]; | 459 | seq_head = &tn->nametbl->seq_hlist[hash(type)]; |
| 456 | hlist_for_each_entry_rcu(ns, seq_head, ns_list) { | 460 | hlist_for_each_entry_rcu(ns, seq_head, ns_list) { |
| 457 | if (ns->type == type) | 461 | if (ns->type == type) |
| 458 | return ns; | 462 | return ns; |
| @@ -461,11 +465,13 @@ static struct name_seq *nametbl_find_seq(u32 type) | |||
| 461 | return NULL; | 465 | return NULL; |
| 462 | }; | 466 | }; |
| 463 | 467 | ||
| 464 | struct publication *tipc_nametbl_insert_publ(u32 type, u32 lower, u32 upper, | 468 | struct publication *tipc_nametbl_insert_publ(struct net *net, u32 type, |
| 465 | u32 scope, u32 node, u32 port, u32 key) | 469 | u32 lower, u32 upper, u32 scope, |
| 470 | u32 node, u32 port, u32 key) | ||
| 466 | { | 471 | { |
| 472 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
| 467 | struct publication *publ; | 473 | struct publication *publ; |
| 468 | struct name_seq *seq = nametbl_find_seq(type); | 474 | struct name_seq *seq = nametbl_find_seq(net, type); |
| 469 | int index = hash(type); | 475 | int index = hash(type); |
| 470 | 476 | ||
| 471 | if ((scope < TIPC_ZONE_SCOPE) || (scope > TIPC_NODE_SCOPE) || | 477 | if ((scope < TIPC_ZONE_SCOPE) || (scope > TIPC_NODE_SCOPE) || |
| @@ -476,29 +482,29 @@ struct publication *tipc_nametbl_insert_publ(u32 type, u32 lower, u32 upper, | |||
| 476 | } | 482 | } |
| 477 | 483 | ||
| 478 | if (!seq) | 484 | if (!seq) |
| 479 | seq = tipc_nameseq_create(type, | 485 | seq = tipc_nameseq_create(type, &tn->nametbl->seq_hlist[index]); |
| 480 | &tipc_nametbl->seq_hlist[index]); | ||
| 481 | if (!seq) | 486 | if (!seq) |
| 482 | return NULL; | 487 | return NULL; |
| 483 | 488 | ||
| 484 | spin_lock_bh(&seq->lock); | 489 | spin_lock_bh(&seq->lock); |
| 485 | publ = tipc_nameseq_insert_publ(seq, type, lower, upper, | 490 | publ = tipc_nameseq_insert_publ(net, seq, type, lower, upper, |
| 486 | scope, node, port, key); | 491 | scope, node, port, key); |
| 487 | spin_unlock_bh(&seq->lock); | 492 | spin_unlock_bh(&seq->lock); |
| 488 | return publ; | 493 | return publ; |
| 489 | } | 494 | } |
| 490 | 495 | ||
| 491 | struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower, | 496 | struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type, |
| 492 | u32 node, u32 ref, u32 key) | 497 | u32 lower, u32 node, u32 ref, |
| 498 | u32 key) | ||
| 493 | { | 499 | { |
| 494 | struct publication *publ; | 500 | struct publication *publ; |
| 495 | struct name_seq *seq = nametbl_find_seq(type); | 501 | struct name_seq *seq = nametbl_find_seq(net, type); |
| 496 | 502 | ||
| 497 | if (!seq) | 503 | if (!seq) |
| 498 | return NULL; | 504 | return NULL; |
| 499 | 505 | ||
| 500 | spin_lock_bh(&seq->lock); | 506 | spin_lock_bh(&seq->lock); |
| 501 | publ = tipc_nameseq_remove_publ(seq, lower, node, ref, key); | 507 | publ = tipc_nameseq_remove_publ(net, seq, lower, node, ref, key); |
| 502 | if (!seq->first_free && list_empty(&seq->subscriptions)) { | 508 | if (!seq->first_free && list_empty(&seq->subscriptions)) { |
| 503 | hlist_del_init_rcu(&seq->ns_list); | 509 | hlist_del_init_rcu(&seq->ns_list); |
| 504 | kfree(seq->sseqs); | 510 | kfree(seq->sseqs); |
| @@ -523,8 +529,10 @@ struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower, | |||
| 523 | * - if name translation is attempted and fails, sets 'destnode' to 0 | 529 | * - if name translation is attempted and fails, sets 'destnode' to 0 |
| 524 | * and returns 0 | 530 | * and returns 0 |
| 525 | */ | 531 | */ |
| 526 | u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode) | 532 | u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, |
| 533 | u32 *destnode) | ||
| 527 | { | 534 | { |
| 535 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
| 528 | struct sub_seq *sseq; | 536 | struct sub_seq *sseq; |
| 529 | struct name_info *info; | 537 | struct name_info *info; |
| 530 | struct publication *publ; | 538 | struct publication *publ; |
| @@ -532,11 +540,11 @@ u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode) | |||
| 532 | u32 ref = 0; | 540 | u32 ref = 0; |
| 533 | u32 node = 0; | 541 | u32 node = 0; |
| 534 | 542 | ||
| 535 | if (!tipc_in_scope(*destnode, tipc_own_addr)) | 543 | if (!tipc_in_scope(*destnode, tn->own_addr)) |
| 536 | return 0; | 544 | return 0; |
| 537 | 545 | ||
| 538 | rcu_read_lock(); | 546 | rcu_read_lock(); |
| 539 | seq = nametbl_find_seq(type); | 547 | seq = nametbl_find_seq(net, type); |
| 540 | if (unlikely(!seq)) | 548 | if (unlikely(!seq)) |
| 541 | goto not_found; | 549 | goto not_found; |
| 542 | spin_lock_bh(&seq->lock); | 550 | spin_lock_bh(&seq->lock); |
| @@ -569,13 +577,13 @@ u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode) | |||
| 569 | } | 577 | } |
| 570 | 578 | ||
| 571 | /* Round-Robin Algorithm */ | 579 | /* Round-Robin Algorithm */ |
| 572 | else if (*destnode == tipc_own_addr) { | 580 | else if (*destnode == tn->own_addr) { |
| 573 | if (list_empty(&info->node_list)) | 581 | if (list_empty(&info->node_list)) |
| 574 | goto no_match; | 582 | goto no_match; |
| 575 | publ = list_first_entry(&info->node_list, struct publication, | 583 | publ = list_first_entry(&info->node_list, struct publication, |
| 576 | node_list); | 584 | node_list); |
| 577 | list_move_tail(&publ->node_list, &info->node_list); | 585 | list_move_tail(&publ->node_list, &info->node_list); |
| 578 | } else if (in_own_cluster_exact(*destnode)) { | 586 | } else if (in_own_cluster_exact(net, *destnode)) { |
| 579 | if (list_empty(&info->cluster_list)) | 587 | if (list_empty(&info->cluster_list)) |
| 580 | goto no_match; | 588 | goto no_match; |
| 581 | publ = list_first_entry(&info->cluster_list, struct publication, | 589 | publ = list_first_entry(&info->cluster_list, struct publication, |
| @@ -609,8 +617,8 @@ not_found: | |||
| 609 | * | 617 | * |
| 610 | * Returns non-zero if any off-node ports overlap | 618 | * Returns non-zero if any off-node ports overlap |
| 611 | */ | 619 | */ |
| 612 | int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit, | 620 | int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper, |
| 613 | struct tipc_port_list *dports) | 621 | u32 limit, struct tipc_port_list *dports) |
| 614 | { | 622 | { |
| 615 | struct name_seq *seq; | 623 | struct name_seq *seq; |
| 616 | struct sub_seq *sseq; | 624 | struct sub_seq *sseq; |
| @@ -619,7 +627,7 @@ int tipc_nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit, | |||
| 619 | int res = 0; | 627 | int res = 0; |
| 620 | 628 | ||
| 621 | rcu_read_lock(); | 629 | rcu_read_lock(); |
| 622 | seq = nametbl_find_seq(type); | 630 | seq = nametbl_find_seq(net, type); |
| 623 | if (!seq) | 631 | if (!seq) |
| 624 | goto exit; | 632 | goto exit; |
| 625 | 633 | ||
| @@ -650,50 +658,55 @@ exit: | |||
| 650 | /* | 658 | /* |
| 651 | * tipc_nametbl_publish - add name publication to network name tables | 659 | * tipc_nametbl_publish - add name publication to network name tables |
| 652 | */ | 660 | */ |
| 653 | struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper, | 661 | struct publication *tipc_nametbl_publish(struct net *net, u32 type, u32 lower, |
| 654 | u32 scope, u32 port_ref, u32 key) | 662 | u32 upper, u32 scope, u32 port_ref, |
| 663 | u32 key) | ||
| 655 | { | 664 | { |
| 656 | struct publication *publ; | 665 | struct publication *publ; |
| 657 | struct sk_buff *buf = NULL; | 666 | struct sk_buff *buf = NULL; |
| 667 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
| 658 | 668 | ||
| 659 | spin_lock_bh(&tipc_nametbl_lock); | 669 | spin_lock_bh(&tn->nametbl_lock); |
| 660 | if (tipc_nametbl->local_publ_count >= TIPC_MAX_PUBLICATIONS) { | 670 | if (tn->nametbl->local_publ_count >= TIPC_MAX_PUBLICATIONS) { |
| 661 | pr_warn("Publication failed, local publication limit reached (%u)\n", | 671 | pr_warn("Publication failed, local publication limit reached (%u)\n", |
| 662 | TIPC_MAX_PUBLICATIONS); | 672 | TIPC_MAX_PUBLICATIONS); |
| 663 | spin_unlock_bh(&tipc_nametbl_lock); | 673 | spin_unlock_bh(&tn->nametbl_lock); |
| 664 | return NULL; | 674 | return NULL; |
| 665 | } | 675 | } |
| 666 | 676 | ||
| 667 | publ = tipc_nametbl_insert_publ(type, lower, upper, scope, | 677 | publ = tipc_nametbl_insert_publ(net, type, lower, upper, scope, |
| 668 | tipc_own_addr, port_ref, key); | 678 | tn->own_addr, port_ref, key); |
| 669 | if (likely(publ)) { | 679 | if (likely(publ)) { |
| 670 | tipc_nametbl->local_publ_count++; | 680 | tn->nametbl->local_publ_count++; |
| 671 | buf = tipc_named_publish(publ); | 681 | buf = tipc_named_publish(net, publ); |
| 672 | /* Any pending external events? */ | 682 | /* Any pending external events? */ |
| 673 | tipc_named_process_backlog(); | 683 | tipc_named_process_backlog(net); |
| 674 | } | 684 | } |
| 675 | spin_unlock_bh(&tipc_nametbl_lock); | 685 | spin_unlock_bh(&tn->nametbl_lock); |
| 676 | 686 | ||
| 677 | if (buf) | 687 | if (buf) |
| 678 | named_cluster_distribute(buf); | 688 | named_cluster_distribute(net, buf); |
| 679 | return publ; | 689 | return publ; |
| 680 | } | 690 | } |
| 681 | 691 | ||
| 682 | /** | 692 | /** |
| 683 | * tipc_nametbl_withdraw - withdraw name publication from network name tables | 693 | * tipc_nametbl_withdraw - withdraw name publication from network name tables |
| 684 | */ | 694 | */ |
| 685 | int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key) | 695 | int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower, u32 ref, |
| 696 | u32 key) | ||
| 686 | { | 697 | { |
| 687 | struct publication *publ; | 698 | struct publication *publ; |
| 688 | struct sk_buff *skb = NULL; | 699 | struct sk_buff *skb = NULL; |
| 700 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
| 689 | 701 | ||
| 690 | spin_lock_bh(&tipc_nametbl_lock); | 702 | spin_lock_bh(&tn->nametbl_lock); |
| 691 | publ = tipc_nametbl_remove_publ(type, lower, tipc_own_addr, ref, key); | 703 | publ = tipc_nametbl_remove_publ(net, type, lower, tn->own_addr, |
| 704 | ref, key); | ||
| 692 | if (likely(publ)) { | 705 | if (likely(publ)) { |
| 693 | tipc_nametbl->local_publ_count--; | 706 | tn->nametbl->local_publ_count--; |
| 694 | skb = tipc_named_withdraw(publ); | 707 | skb = tipc_named_withdraw(net, publ); |
| 695 | /* Any pending external events? */ | 708 | /* Any pending external events? */ |
| 696 | tipc_named_process_backlog(); | 709 | tipc_named_process_backlog(net); |
| 697 | list_del_init(&publ->pport_list); | 710 | list_del_init(&publ->pport_list); |
| 698 | kfree_rcu(publ, rcu); | 711 | kfree_rcu(publ, rcu); |
| 699 | } else { | 712 | } else { |
| @@ -701,10 +714,10 @@ int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key) | |||
| 701 | "(type=%u, lower=%u, ref=%u, key=%u)\n", | 714 | "(type=%u, lower=%u, ref=%u, key=%u)\n", |
| 702 | type, lower, ref, key); | 715 | type, lower, ref, key); |
| 703 | } | 716 | } |
| 704 | spin_unlock_bh(&tipc_nametbl_lock); | 717 | spin_unlock_bh(&tn->nametbl_lock); |
| 705 | 718 | ||
| 706 | if (skb) { | 719 | if (skb) { |
| 707 | named_cluster_distribute(skb); | 720 | named_cluster_distribute(net, skb); |
| 708 | return 1; | 721 | return 1; |
| 709 | } | 722 | } |
| 710 | return 0; | 723 | return 0; |
| @@ -715,15 +728,15 @@ int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key) | |||
| 715 | */ | 728 | */ |
| 716 | void tipc_nametbl_subscribe(struct tipc_subscription *s) | 729 | void tipc_nametbl_subscribe(struct tipc_subscription *s) |
| 717 | { | 730 | { |
| 731 | struct tipc_net *tn = net_generic(s->net, tipc_net_id); | ||
| 718 | u32 type = s->seq.type; | 732 | u32 type = s->seq.type; |
| 719 | int index = hash(type); | 733 | int index = hash(type); |
| 720 | struct name_seq *seq; | 734 | struct name_seq *seq; |
| 721 | 735 | ||
| 722 | spin_lock_bh(&tipc_nametbl_lock); | 736 | spin_lock_bh(&tn->nametbl_lock); |
| 723 | seq = nametbl_find_seq(type); | 737 | seq = nametbl_find_seq(s->net, type); |
| 724 | if (!seq) | 738 | if (!seq) |
| 725 | seq = tipc_nameseq_create(type, | 739 | seq = tipc_nameseq_create(type, &tn->nametbl->seq_hlist[index]); |
| 726 | &tipc_nametbl->seq_hlist[index]); | ||
| 727 | if (seq) { | 740 | if (seq) { |
| 728 | spin_lock_bh(&seq->lock); | 741 | spin_lock_bh(&seq->lock); |
| 729 | tipc_nameseq_subscribe(seq, s); | 742 | tipc_nameseq_subscribe(seq, s); |
| @@ -732,7 +745,7 @@ void tipc_nametbl_subscribe(struct tipc_subscription *s) | |||
| 732 | pr_warn("Failed to create subscription for {%u,%u,%u}\n", | 745 | pr_warn("Failed to create subscription for {%u,%u,%u}\n", |
| 733 | s->seq.type, s->seq.lower, s->seq.upper); | 746 | s->seq.type, s->seq.lower, s->seq.upper); |
| 734 | } | 747 | } |
| 735 | spin_unlock_bh(&tipc_nametbl_lock); | 748 | spin_unlock_bh(&tn->nametbl_lock); |
| 736 | } | 749 | } |
| 737 | 750 | ||
| 738 | /** | 751 | /** |
| @@ -740,10 +753,11 @@ void tipc_nametbl_subscribe(struct tipc_subscription *s) | |||
| 740 | */ | 753 | */ |
| 741 | void tipc_nametbl_unsubscribe(struct tipc_subscription *s) | 754 | void tipc_nametbl_unsubscribe(struct tipc_subscription *s) |
| 742 | { | 755 | { |
| 756 | struct tipc_net *tn = net_generic(s->net, tipc_net_id); | ||
| 743 | struct name_seq *seq; | 757 | struct name_seq *seq; |
| 744 | 758 | ||
| 745 | spin_lock_bh(&tipc_nametbl_lock); | 759 | spin_lock_bh(&tn->nametbl_lock); |
| 746 | seq = nametbl_find_seq(s->seq.type); | 760 | seq = nametbl_find_seq(s->net, s->seq.type); |
| 747 | if (seq != NULL) { | 761 | if (seq != NULL) { |
| 748 | spin_lock_bh(&seq->lock); | 762 | spin_lock_bh(&seq->lock); |
| 749 | list_del_init(&s->nameseq_list); | 763 | list_del_init(&s->nameseq_list); |
| @@ -756,7 +770,7 @@ void tipc_nametbl_unsubscribe(struct tipc_subscription *s) | |||
| 756 | spin_unlock_bh(&seq->lock); | 770 | spin_unlock_bh(&seq->lock); |
| 757 | } | 771 | } |
| 758 | } | 772 | } |
| 759 | spin_unlock_bh(&tipc_nametbl_lock); | 773 | spin_unlock_bh(&tn->nametbl_lock); |
| 760 | } | 774 | } |
| 761 | 775 | ||
| 762 | /** | 776 | /** |
| @@ -858,9 +872,10 @@ static int nametbl_header(char *buf, int len, u32 depth) | |||
| 858 | /** | 872 | /** |
| 859 | * nametbl_list - print specified name table contents into the given buffer | 873 | * nametbl_list - print specified name table contents into the given buffer |
| 860 | */ | 874 | */ |
| 861 | static int nametbl_list(char *buf, int len, u32 depth_info, | 875 | static int nametbl_list(struct net *net, char *buf, int len, u32 depth_info, |
| 862 | u32 type, u32 lowbound, u32 upbound) | 876 | u32 type, u32 lowbound, u32 upbound) |
| 863 | { | 877 | { |
| 878 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
| 864 | struct hlist_head *seq_head; | 879 | struct hlist_head *seq_head; |
| 865 | struct name_seq *seq; | 880 | struct name_seq *seq; |
| 866 | int all_types; | 881 | int all_types; |
| @@ -880,7 +895,7 @@ static int nametbl_list(char *buf, int len, u32 depth_info, | |||
| 880 | lowbound = 0; | 895 | lowbound = 0; |
| 881 | upbound = ~0; | 896 | upbound = ~0; |
| 882 | for (i = 0; i < TIPC_NAMETBL_SIZE; i++) { | 897 | for (i = 0; i < TIPC_NAMETBL_SIZE; i++) { |
| 883 | seq_head = &tipc_nametbl->seq_hlist[i]; | 898 | seq_head = &tn->nametbl->seq_hlist[i]; |
| 884 | hlist_for_each_entry_rcu(seq, seq_head, ns_list) { | 899 | hlist_for_each_entry_rcu(seq, seq_head, ns_list) { |
| 885 | ret += nameseq_list(seq, buf + ret, len - ret, | 900 | ret += nameseq_list(seq, buf + ret, len - ret, |
| 886 | depth, seq->type, | 901 | depth, seq->type, |
| @@ -896,7 +911,7 @@ static int nametbl_list(char *buf, int len, u32 depth_info, | |||
| 896 | } | 911 | } |
| 897 | ret += nametbl_header(buf + ret, len - ret, depth); | 912 | ret += nametbl_header(buf + ret, len - ret, depth); |
| 898 | i = hash(type); | 913 | i = hash(type); |
| 899 | seq_head = &tipc_nametbl->seq_hlist[i]; | 914 | seq_head = &tn->nametbl->seq_hlist[i]; |
| 900 | hlist_for_each_entry_rcu(seq, seq_head, ns_list) { | 915 | hlist_for_each_entry_rcu(seq, seq_head, ns_list) { |
| 901 | if (seq->type == type) { | 916 | if (seq->type == type) { |
| 902 | ret += nameseq_list(seq, buf + ret, len - ret, | 917 | ret += nameseq_list(seq, buf + ret, len - ret, |
| @@ -909,7 +924,8 @@ static int nametbl_list(char *buf, int len, u32 depth_info, | |||
| 909 | return ret; | 924 | return ret; |
| 910 | } | 925 | } |
| 911 | 926 | ||
| 912 | struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space) | 927 | struct sk_buff *tipc_nametbl_get(struct net *net, const void *req_tlv_area, |
| 928 | int req_tlv_space) | ||
| 913 | { | 929 | { |
| 914 | struct sk_buff *buf; | 930 | struct sk_buff *buf; |
| 915 | struct tipc_name_table_query *argv; | 931 | struct tipc_name_table_query *argv; |
| @@ -930,7 +946,7 @@ struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space) | |||
| 930 | pb_len = ULTRA_STRING_MAX_LEN; | 946 | pb_len = ULTRA_STRING_MAX_LEN; |
| 931 | argv = (struct tipc_name_table_query *)TLV_DATA(req_tlv_area); | 947 | argv = (struct tipc_name_table_query *)TLV_DATA(req_tlv_area); |
| 932 | rcu_read_lock(); | 948 | rcu_read_lock(); |
| 933 | str_len = nametbl_list(pb, pb_len, ntohl(argv->depth), | 949 | str_len = nametbl_list(net, pb, pb_len, ntohl(argv->depth), |
| 934 | ntohl(argv->type), | 950 | ntohl(argv->type), |
| 935 | ntohl(argv->lowbound), ntohl(argv->upbound)); | 951 | ntohl(argv->lowbound), ntohl(argv->upbound)); |
| 936 | rcu_read_unlock(); | 952 | rcu_read_unlock(); |
| @@ -941,8 +957,10 @@ struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space) | |||
| 941 | return buf; | 957 | return buf; |
| 942 | } | 958 | } |
| 943 | 959 | ||
| 944 | int tipc_nametbl_init(void) | 960 | int tipc_nametbl_init(struct net *net) |
| 945 | { | 961 | { |
| 962 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
| 963 | struct name_table *tipc_nametbl; | ||
| 946 | int i; | 964 | int i; |
| 947 | 965 | ||
| 948 | tipc_nametbl = kzalloc(sizeof(*tipc_nametbl), GFP_ATOMIC); | 966 | tipc_nametbl = kzalloc(sizeof(*tipc_nametbl), GFP_ATOMIC); |
| @@ -955,6 +973,8 @@ int tipc_nametbl_init(void) | |||
| 955 | INIT_LIST_HEAD(&tipc_nametbl->publ_list[TIPC_ZONE_SCOPE]); | 973 | INIT_LIST_HEAD(&tipc_nametbl->publ_list[TIPC_ZONE_SCOPE]); |
| 956 | INIT_LIST_HEAD(&tipc_nametbl->publ_list[TIPC_CLUSTER_SCOPE]); | 974 | INIT_LIST_HEAD(&tipc_nametbl->publ_list[TIPC_CLUSTER_SCOPE]); |
| 957 | INIT_LIST_HEAD(&tipc_nametbl->publ_list[TIPC_NODE_SCOPE]); | 975 | INIT_LIST_HEAD(&tipc_nametbl->publ_list[TIPC_NODE_SCOPE]); |
| 976 | tn->nametbl = tipc_nametbl; | ||
| 977 | spin_lock_init(&tn->nametbl_lock); | ||
| 958 | return 0; | 978 | return 0; |
| 959 | } | 979 | } |
| 960 | 980 | ||
| @@ -963,7 +983,7 @@ int tipc_nametbl_init(void) | |||
| 963 | * | 983 | * |
| 964 | * tipc_nametbl_lock must be held when calling this function | 984 | * tipc_nametbl_lock must be held when calling this function |
| 965 | */ | 985 | */ |
| 966 | static void tipc_purge_publications(struct name_seq *seq) | 986 | static void tipc_purge_publications(struct net *net, struct name_seq *seq) |
| 967 | { | 987 | { |
| 968 | struct publication *publ, *safe; | 988 | struct publication *publ, *safe; |
| 969 | struct sub_seq *sseq; | 989 | struct sub_seq *sseq; |
| @@ -973,8 +993,8 @@ static void tipc_purge_publications(struct name_seq *seq) | |||
| 973 | sseq = seq->sseqs; | 993 | sseq = seq->sseqs; |
| 974 | info = sseq->info; | 994 | info = sseq->info; |
| 975 | list_for_each_entry_safe(publ, safe, &info->zone_list, zone_list) { | 995 | list_for_each_entry_safe(publ, safe, &info->zone_list, zone_list) { |
| 976 | tipc_nametbl_remove_publ(publ->type, publ->lower, publ->node, | 996 | tipc_nametbl_remove_publ(net, publ->type, publ->lower, |
| 977 | publ->ref, publ->key); | 997 | publ->node, publ->ref, publ->key); |
| 978 | kfree_rcu(publ, rcu); | 998 | kfree_rcu(publ, rcu); |
| 979 | } | 999 | } |
| 980 | hlist_del_init_rcu(&seq->ns_list); | 1000 | hlist_del_init_rcu(&seq->ns_list); |
| @@ -984,25 +1004,27 @@ static void tipc_purge_publications(struct name_seq *seq) | |||
| 984 | kfree_rcu(seq, rcu); | 1004 | kfree_rcu(seq, rcu); |
| 985 | } | 1005 | } |
| 986 | 1006 | ||
| 987 | void tipc_nametbl_stop(void) | 1007 | void tipc_nametbl_stop(struct net *net) |
| 988 | { | 1008 | { |
| 989 | u32 i; | 1009 | u32 i; |
| 990 | struct name_seq *seq; | 1010 | struct name_seq *seq; |
| 991 | struct hlist_head *seq_head; | 1011 | struct hlist_head *seq_head; |
| 1012 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
| 1013 | struct name_table *tipc_nametbl = tn->nametbl; | ||
| 992 | 1014 | ||
| 993 | /* Verify name table is empty and purge any lingering | 1015 | /* Verify name table is empty and purge any lingering |
| 994 | * publications, then release the name table | 1016 | * publications, then release the name table |
| 995 | */ | 1017 | */ |
| 996 | spin_lock_bh(&tipc_nametbl_lock); | 1018 | spin_lock_bh(&tn->nametbl_lock); |
| 997 | for (i = 0; i < TIPC_NAMETBL_SIZE; i++) { | 1019 | for (i = 0; i < TIPC_NAMETBL_SIZE; i++) { |
| 998 | if (hlist_empty(&tipc_nametbl->seq_hlist[i])) | 1020 | if (hlist_empty(&tipc_nametbl->seq_hlist[i])) |
| 999 | continue; | 1021 | continue; |
| 1000 | seq_head = &tipc_nametbl->seq_hlist[i]; | 1022 | seq_head = &tipc_nametbl->seq_hlist[i]; |
| 1001 | hlist_for_each_entry_rcu(seq, seq_head, ns_list) { | 1023 | hlist_for_each_entry_rcu(seq, seq_head, ns_list) { |
| 1002 | tipc_purge_publications(seq); | 1024 | tipc_purge_publications(net, seq); |
| 1003 | } | 1025 | } |
| 1004 | } | 1026 | } |
| 1005 | spin_unlock_bh(&tipc_nametbl_lock); | 1027 | spin_unlock_bh(&tn->nametbl_lock); |
| 1006 | 1028 | ||
| 1007 | synchronize_net(); | 1029 | synchronize_net(); |
| 1008 | kfree(tipc_nametbl); | 1030 | kfree(tipc_nametbl); |
| @@ -1106,9 +1128,10 @@ static int __tipc_nl_subseq_list(struct tipc_nl_msg *msg, struct name_seq *seq, | |||
| 1106 | return 0; | 1128 | return 0; |
| 1107 | } | 1129 | } |
| 1108 | 1130 | ||
| 1109 | static int __tipc_nl_seq_list(struct tipc_nl_msg *msg, u32 *last_type, | 1131 | static int tipc_nl_seq_list(struct net *net, struct tipc_nl_msg *msg, |
| 1110 | u32 *last_lower, u32 *last_publ) | 1132 | u32 *last_type, u32 *last_lower, u32 *last_publ) |
| 1111 | { | 1133 | { |
| 1134 | struct tipc_net *tn = net_generic(net, tipc_net_id); | ||
| 1112 | struct hlist_head *seq_head; | 1135 | struct hlist_head *seq_head; |
| 1113 | struct name_seq *seq = NULL; | 1136 | struct name_seq *seq = NULL; |
| 1114 | int err; | 1137 | int err; |
| @@ -1120,10 +1143,10 @@ static int __tipc_nl_seq_list(struct tipc_nl_msg *msg, u32 *last_type, | |||
| 1120 | i = 0; | 1143 | i = 0; |
| 1121 | 1144 | ||
| 1122 | for (; i < TIPC_NAMETBL_SIZE; i++) { | 1145 | for (; i < TIPC_NAMETBL_SIZE; i++) { |
| 1123 | seq_head = &tipc_nametbl->seq_hlist[i]; | 1146 | seq_head = &tn->nametbl->seq_hlist[i]; |
| 1124 | 1147 | ||
| 1125 | if (*last_type) { | 1148 | if (*last_type) { |
| 1126 | seq = nametbl_find_seq(*last_type); | 1149 | seq = nametbl_find_seq(net, *last_type); |
| 1127 | if (!seq) | 1150 | if (!seq) |
| 1128 | return -EPIPE; | 1151 | return -EPIPE; |
| 1129 | } else { | 1152 | } else { |
| @@ -1157,6 +1180,7 @@ int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1157 | u32 last_type = cb->args[0]; | 1180 | u32 last_type = cb->args[0]; |
| 1158 | u32 last_lower = cb->args[1]; | 1181 | u32 last_lower = cb->args[1]; |
| 1159 | u32 last_publ = cb->args[2]; | 1182 | u32 last_publ = cb->args[2]; |
| 1183 | struct net *net = sock_net(skb->sk); | ||
| 1160 | struct tipc_nl_msg msg; | 1184 | struct tipc_nl_msg msg; |
| 1161 | 1185 | ||
| 1162 | if (done) | 1186 | if (done) |
| @@ -1167,7 +1191,7 @@ int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1167 | msg.seq = cb->nlh->nlmsg_seq; | 1191 | msg.seq = cb->nlh->nlmsg_seq; |
| 1168 | 1192 | ||
| 1169 | rcu_read_lock(); | 1193 | rcu_read_lock(); |
| 1170 | err = __tipc_nl_seq_list(&msg, &last_type, &last_lower, &last_publ); | 1194 | err = tipc_nl_seq_list(net, &msg, &last_type, &last_lower, &last_publ); |
| 1171 | if (!err) { | 1195 | if (!err) { |
| 1172 | done = 1; | 1196 | done = 1; |
| 1173 | } else if (err != -EMSGSIZE) { | 1197 | } else if (err != -EMSGSIZE) { |
