aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/node.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/node.c')
-rw-r--r--net/tipc/node.c70
1 files changed, 43 insertions, 27 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 64976f2e3c66..22aeb2b7ad00 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -44,9 +44,31 @@ static void node_established_contact(struct tipc_node *n_ptr);
44 44
45static DEFINE_SPINLOCK(node_create_lock); 45static DEFINE_SPINLOCK(node_create_lock);
46 46
47static struct hlist_head node_htable[NODE_HTABLE_SIZE];
48LIST_HEAD(tipc_node_list);
49static u32 tipc_num_nodes;
47u32 tipc_own_tag; 50u32 tipc_own_tag;
48 51
49/** 52/**
53 * tipc_node_find - locate specified node object, if it exists
54 */
55
56struct tipc_node *tipc_node_find(u32 addr)
57{
58 struct tipc_node *node;
59 struct hlist_node *pos;
60
61 if (unlikely(!in_own_cluster(addr)))
62 return NULL;
63
64 hlist_for_each_entry(node, pos, &node_htable[tipc_hashfn(addr)], hash) {
65 if (node->addr == addr)
66 return node;
67 }
68 return NULL;
69}
70
71/**
50 * tipc_node_create - create neighboring node 72 * tipc_node_create - create neighboring node
51 * 73 *
52 * Currently, this routine is called by neighbor discovery code, which holds 74 * Currently, this routine is called by neighbor discovery code, which holds
@@ -58,8 +80,7 @@ u32 tipc_own_tag;
58 80
59struct tipc_node *tipc_node_create(u32 addr) 81struct tipc_node *tipc_node_create(u32 addr)
60{ 82{
61 struct tipc_node *n_ptr; 83 struct tipc_node *n_ptr, *temp_node;
62 u32 n_num;
63 84
64 spin_lock_bh(&node_create_lock); 85 spin_lock_bh(&node_create_lock);
65 86
@@ -78,12 +99,19 @@ struct tipc_node *tipc_node_create(u32 addr)
78 99
79 n_ptr->addr = addr; 100 n_ptr->addr = addr;
80 spin_lock_init(&n_ptr->lock); 101 spin_lock_init(&n_ptr->lock);
102 INIT_HLIST_NODE(&n_ptr->hash);
103 INIT_LIST_HEAD(&n_ptr->list);
81 INIT_LIST_HEAD(&n_ptr->nsub); 104 INIT_LIST_HEAD(&n_ptr->nsub);
82 105
83 n_num = tipc_node(addr); 106 hlist_add_head(&n_ptr->hash, &node_htable[tipc_hashfn(addr)]);
84 tipc_nodes[n_num] = n_ptr; 107
85 if (n_num > tipc_highest_node) 108 list_for_each_entry(temp_node, &tipc_node_list, list) {
86 tipc_highest_node = n_num; 109 if (n_ptr->addr < temp_node->addr)
110 break;
111 }
112 list_add_tail(&n_ptr->list, &temp_node->list);
113
114 tipc_num_nodes++;
87 115
88 spin_unlock_bh(&node_create_lock); 116 spin_unlock_bh(&node_create_lock);
89 return n_ptr; 117 return n_ptr;
@@ -91,18 +119,11 @@ struct tipc_node *tipc_node_create(u32 addr)
91 119
92void tipc_node_delete(struct tipc_node *n_ptr) 120void tipc_node_delete(struct tipc_node *n_ptr)
93{ 121{
94 u32 n_num; 122 list_del(&n_ptr->list);
95 123 hlist_del(&n_ptr->hash);
96 if (!n_ptr)
97 return;
98
99 n_num = tipc_node(n_ptr->addr);
100 tipc_nodes[n_num] = NULL;
101 kfree(n_ptr); 124 kfree(n_ptr);
102 125
103 while (!tipc_nodes[tipc_highest_node]) 126 tipc_num_nodes--;
104 if (--tipc_highest_node == 0)
105 break;
106} 127}
107 128
108 129
@@ -379,7 +400,6 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
379 struct tipc_node *n_ptr; 400 struct tipc_node *n_ptr;
380 struct tipc_node_info node_info; 401 struct tipc_node_info node_info;
381 u32 payload_size; 402 u32 payload_size;
382 u32 n_num;
383 403
384 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) 404 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR))
385 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 405 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
@@ -390,15 +410,14 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
390 " (network address)"); 410 " (network address)");
391 411
392 read_lock_bh(&tipc_net_lock); 412 read_lock_bh(&tipc_net_lock);
393 if (!tipc_nodes) { 413 if (!tipc_num_nodes) {
394 read_unlock_bh(&tipc_net_lock); 414 read_unlock_bh(&tipc_net_lock);
395 return tipc_cfg_reply_none(); 415 return tipc_cfg_reply_none();
396 } 416 }
397 417
398 /* For now, get space for all other nodes */ 418 /* For now, get space for all other nodes */
399 419
400 payload_size = TLV_SPACE(sizeof(node_info)) * 420 payload_size = TLV_SPACE(sizeof(node_info)) * tipc_num_nodes;
401 (tipc_highest_node - 1);
402 if (payload_size > 32768u) { 421 if (payload_size > 32768u) {
403 read_unlock_bh(&tipc_net_lock); 422 read_unlock_bh(&tipc_net_lock);
404 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 423 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
@@ -412,9 +431,8 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
412 431
413 /* Add TLVs for all nodes in scope */ 432 /* Add TLVs for all nodes in scope */
414 433
415 for (n_num = 1; n_num <= tipc_highest_node; n_num++) { 434 list_for_each_entry(n_ptr, &tipc_node_list, list) {
416 n_ptr = tipc_nodes[n_num]; 435 if (!tipc_in_scope(domain, n_ptr->addr))
417 if (!n_ptr || !tipc_in_scope(domain, n_ptr->addr))
418 continue; 436 continue;
419 node_info.addr = htonl(n_ptr->addr); 437 node_info.addr = htonl(n_ptr->addr);
420 node_info.up = htonl(tipc_node_is_up(n_ptr)); 438 node_info.up = htonl(tipc_node_is_up(n_ptr));
@@ -433,7 +451,6 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
433 struct tipc_node *n_ptr; 451 struct tipc_node *n_ptr;
434 struct tipc_link_info link_info; 452 struct tipc_link_info link_info;
435 u32 payload_size; 453 u32 payload_size;
436 u32 n_num;
437 454
438 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) 455 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR))
439 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 456 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
@@ -472,11 +489,10 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
472 489
473 /* Add TLVs for any other links in scope */ 490 /* Add TLVs for any other links in scope */
474 491
475 for (n_num = 1; n_num <= tipc_highest_node; n_num++) { 492 list_for_each_entry(n_ptr, &tipc_node_list, list) {
476 u32 i; 493 u32 i;
477 494
478 n_ptr = tipc_nodes[n_num]; 495 if (!tipc_in_scope(domain, n_ptr->addr))
479 if (!n_ptr || !tipc_in_scope(domain, n_ptr->addr))
480 continue; 496 continue;
481 tipc_node_lock(n_ptr); 497 tipc_node_lock(n_ptr);
482 for (i = 0; i < MAX_BEARERS; i++) { 498 for (i = 0; i < MAX_BEARERS; i++) {