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.c85
1 files changed, 78 insertions, 7 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 7b0c99347406..4a95c8c155c6 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -115,6 +115,7 @@ struct tipc_node {
115 u16 capabilities; 115 u16 capabilities;
116 u32 signature; 116 u32 signature;
117 u32 link_id; 117 u32 link_id;
118 u8 peer_id[16];
118 struct list_head publ_list; 119 struct list_head publ_list;
119 struct list_head conn_sks; 120 struct list_head conn_sks;
120 unsigned long keepalive_intv; 121 unsigned long keepalive_intv;
@@ -156,6 +157,7 @@ static void tipc_node_delete(struct tipc_node *node);
156static void tipc_node_timeout(struct timer_list *t); 157static void tipc_node_timeout(struct timer_list *t);
157static void tipc_node_fsm_evt(struct tipc_node *n, int evt); 158static void tipc_node_fsm_evt(struct tipc_node *n, int evt);
158static struct tipc_node *tipc_node_find(struct net *net, u32 addr); 159static struct tipc_node *tipc_node_find(struct net *net, u32 addr);
160static struct tipc_node *tipc_node_find_by_id(struct net *net, u8 *id);
159static void tipc_node_put(struct tipc_node *node); 161static void tipc_node_put(struct tipc_node *node);
160static bool node_is_up(struct tipc_node *n); 162static bool node_is_up(struct tipc_node *n);
161 163
@@ -245,6 +247,30 @@ static struct tipc_node *tipc_node_find(struct net *net, u32 addr)
245 return node; 247 return node;
246} 248}
247 249
250/* tipc_node_find_by_id - locate specified node object by its 128-bit id
251 * Note: this function is called only when a discovery request failed
252 * to find the node by its 32-bit id, and is not time critical
253 */
254static struct tipc_node *tipc_node_find_by_id(struct net *net, u8 *id)
255{
256 struct tipc_net *tn = tipc_net(net);
257 struct tipc_node *n;
258 bool found = false;
259
260 rcu_read_lock();
261 list_for_each_entry_rcu(n, &tn->node_list, list) {
262 read_lock_bh(&n->lock);
263 if (!memcmp(id, n->peer_id, 16) &&
264 kref_get_unless_zero(&n->kref))
265 found = true;
266 read_unlock_bh(&n->lock);
267 if (found)
268 break;
269 }
270 rcu_read_unlock();
271 return found ? n : NULL;
272}
273
248static void tipc_node_read_lock(struct tipc_node *n) 274static void tipc_node_read_lock(struct tipc_node *n)
249{ 275{
250 read_lock_bh(&n->lock); 276 read_lock_bh(&n->lock);
@@ -307,7 +333,8 @@ static void tipc_node_write_unlock(struct tipc_node *n)
307 } 333 }
308} 334}
309 335
310struct tipc_node *tipc_node_create(struct net *net, u32 addr, u16 capabilities) 336struct tipc_node *tipc_node_create(struct net *net, u32 addr,
337 u8 *peer_id, u16 capabilities)
311{ 338{
312 struct tipc_net *tn = net_generic(net, tipc_net_id); 339 struct tipc_net *tn = net_generic(net, tipc_net_id);
313 struct tipc_node *n, *temp_node; 340 struct tipc_node *n, *temp_node;
@@ -326,6 +353,7 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr, u16 capabilities)
326 goto exit; 353 goto exit;
327 } 354 }
328 n->addr = addr; 355 n->addr = addr;
356 memcpy(&n->peer_id, peer_id, 16);
329 n->net = net; 357 n->net = net;
330 n->capabilities = capabilities; 358 n->capabilities = capabilities;
331 kref_init(&n->kref); 359 kref_init(&n->kref);
@@ -344,8 +372,8 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr, u16 capabilities)
344 n->signature = INVALID_NODE_SIG; 372 n->signature = INVALID_NODE_SIG;
345 n->active_links[0] = INVALID_BEARER_ID; 373 n->active_links[0] = INVALID_BEARER_ID;
346 n->active_links[1] = INVALID_BEARER_ID; 374 n->active_links[1] = INVALID_BEARER_ID;
347 if (!tipc_link_bc_create(net, tipc_own_addr(net), n->addr, 375 if (!tipc_link_bc_create(net, tipc_own_addr(net),
348 U16_MAX, 376 addr, U16_MAX,
349 tipc_link_window(tipc_bc_sndlink(net)), 377 tipc_link_window(tipc_bc_sndlink(net)),
350 n->capabilities, 378 n->capabilities,
351 &n->bc_entry.inputq1, 379 &n->bc_entry.inputq1,
@@ -735,8 +763,51 @@ bool tipc_node_is_up(struct net *net, u32 addr)
735 return retval; 763 return retval;
736} 764}
737 765
738void tipc_node_check_dest(struct net *net, u32 onode, 766static u32 tipc_node_suggest_addr(struct net *net, u32 addr)
739 struct tipc_bearer *b, 767{
768 struct tipc_node *n;
769
770 addr ^= tipc_net(net)->random;
771 while ((n = tipc_node_find(net, addr))) {
772 tipc_node_put(n);
773 addr++;
774 }
775 return addr;
776}
777
778/* tipc_node_try_addr(): Check if addr can be used by peer, suggest other if not
779 */
780u32 tipc_node_try_addr(struct net *net, u8 *id, u32 addr)
781{
782 struct tipc_net *tn = tipc_net(net);
783 struct tipc_node *n;
784
785 /* Suggest new address if some other peer is using this one */
786 n = tipc_node_find(net, addr);
787 if (n) {
788 if (!memcmp(n->peer_id, id, NODE_ID_LEN))
789 addr = 0;
790 tipc_node_put(n);
791 if (!addr)
792 return 0;
793 return tipc_node_suggest_addr(net, addr);
794 }
795
796 /* Suggest previously used address if peer is known */
797 n = tipc_node_find_by_id(net, id);
798 if (n) {
799 addr = n->addr;
800 tipc_node_put(n);
801 }
802 /* Even this node may be in trial phase */
803 if (tn->trial_addr == addr)
804 return tipc_node_suggest_addr(net, addr);
805
806 return addr;
807}
808
809void tipc_node_check_dest(struct net *net, u32 addr,
810 u8 *peer_id, struct tipc_bearer *b,
740 u16 capabilities, u32 signature, 811 u16 capabilities, u32 signature,
741 struct tipc_media_addr *maddr, 812 struct tipc_media_addr *maddr,
742 bool *respond, bool *dupl_addr) 813 bool *respond, bool *dupl_addr)
@@ -755,7 +826,7 @@ void tipc_node_check_dest(struct net *net, u32 onode,
755 *dupl_addr = false; 826 *dupl_addr = false;
756 *respond = false; 827 *respond = false;
757 828
758 n = tipc_node_create(net, onode, capabilities); 829 n = tipc_node_create(net, addr, peer_id, capabilities);
759 if (!n) 830 if (!n)
760 return; 831 return;
761 832
@@ -840,7 +911,7 @@ void tipc_node_check_dest(struct net *net, u32 onode,
840 if (!tipc_link_create(net, if_name, b->identity, b->tolerance, 911 if (!tipc_link_create(net, if_name, b->identity, b->tolerance,
841 b->net_plane, b->mtu, b->priority, 912 b->net_plane, b->mtu, b->priority,
842 b->window, mod(tipc_net(net)->random), 913 b->window, mod(tipc_net(net)->random),
843 tipc_own_addr(net), onode, 914 tipc_own_addr(net), addr, peer_id,
844 n->capabilities, 915 n->capabilities,
845 tipc_bc_sndlink(n->net), n->bc_entry.link, 916 tipc_bc_sndlink(n->net), n->bc_entry.link,
846 &le->inputq, 917 &le->inputq,