summaryrefslogtreecommitdiffstats
path: root/net/tipc/node.c
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2015-07-30 18:24:22 -0400
committerDavid S. Miller <davem@davemloft.net>2015-07-30 20:25:14 -0400
commitcf148816acb6def45474001302368eb472995e62 (patch)
tree1960bba9cffec1d73c8c5108e270cfe03580d940 /net/tipc/node.c
parent662921cd0a53db4504838dfbb7d996f9e6e94001 (diff)
tipc: move received discovery data evaluation inside node.c
The node lock is currently grabbed and and released in the function tipc_disc_rcv() in the file discover.c. As a preparation for the next commits, we need to move this node lock handling, along with the code area it is covering, to node.c. This commit introduces this change. Tested-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/node.c')
-rw-r--r--net/tipc/node.c123
1 files changed, 102 insertions, 21 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c
index a3ceeda2a80a..d03e88f2273b 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -138,7 +138,7 @@ struct tipc_node *tipc_node_find(struct net *net, u32 addr)
138 return NULL; 138 return NULL;
139} 139}
140 140
141struct tipc_node *tipc_node_create(struct net *net, u32 addr) 141struct tipc_node *tipc_node_create(struct net *net, u32 addr, u16 capabilities)
142{ 142{
143 struct tipc_net *tn = net_generic(net, tipc_net_id); 143 struct tipc_net *tn = net_generic(net, tipc_net_id);
144 struct tipc_node *n_ptr, *temp_node; 144 struct tipc_node *n_ptr, *temp_node;
@@ -154,6 +154,7 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr)
154 } 154 }
155 n_ptr->addr = addr; 155 n_ptr->addr = addr;
156 n_ptr->net = net; 156 n_ptr->net = net;
157 n_ptr->capabilities = capabilities;
157 kref_init(&n_ptr->kref); 158 kref_init(&n_ptr->kref);
158 spin_lock_init(&n_ptr->lock); 159 spin_lock_init(&n_ptr->lock);
159 INIT_HLIST_NODE(&n_ptr->hash); 160 INIT_HLIST_NODE(&n_ptr->hash);
@@ -422,38 +423,118 @@ bool tipc_node_is_up(struct tipc_node *n)
422 return n->active_links[0] != INVALID_BEARER_ID; 423 return n->active_links[0] != INVALID_BEARER_ID;
423} 424}
424 425
425void tipc_node_check_dest(struct tipc_node *n, struct tipc_bearer *b, 426void tipc_node_check_dest(struct net *net, u32 onode,
426 bool *link_up, bool *addr_match, 427 struct tipc_bearer *b,
427 struct tipc_media_addr *maddr) 428 u16 capabilities, u32 signature,
429 struct tipc_media_addr *maddr,
430 bool *respond, bool *dupl_addr)
428{ 431{
429 struct tipc_link *l = n->links[b->identity].link; 432 struct tipc_node *n;
430 struct tipc_media_addr *curr = &n->links[b->identity].maddr; 433 struct tipc_link *l;
434 struct tipc_media_addr *curr_maddr;
435 struct sk_buff_head *inputq;
436 bool addr_match = false;
437 bool sign_match = false;
438 bool link_up = false;
439 bool accept_addr = false;
440
441 *dupl_addr = false;
442 *respond = false;
443
444 n = tipc_node_create(net, onode, capabilities);
445 if (!n)
446 return;
431 447
432 *link_up = l && tipc_link_is_up(l); 448 tipc_node_lock(n);
433 *addr_match = l && !memcmp(curr, maddr, sizeof(*maddr));
434}
435 449
436bool tipc_node_update_dest(struct tipc_node *n, struct tipc_bearer *b, 450 curr_maddr = &n->links[b->identity].maddr;
437 struct tipc_media_addr *maddr) 451 inputq = &n->links[b->identity].inputq;
438{ 452
439 struct tipc_link *l = n->links[b->identity].link; 453 /* Prepare to validate requesting node's signature and media address */
440 struct tipc_media_addr *curr = &n->links[b->identity].maddr; 454 l = n->links[b->identity].link;
441 struct sk_buff_head *inputq = &n->links[b->identity].inputq; 455 link_up = l && tipc_link_is_up(l);
456 addr_match = l && !memcmp(curr_maddr, maddr, sizeof(*maddr));
457 sign_match = (signature == n->signature);
458
459 /* These three flags give us eight permutations: */
460
461 if (sign_match && addr_match && link_up) {
462 /* All is fine. Do nothing. */
463 } else if (sign_match && addr_match && !link_up) {
464 /* Respond. The link will come up in due time */
465 *respond = true;
466 } else if (sign_match && !addr_match && link_up) {
467 /* Peer has changed i/f address without rebooting.
468 * If so, the link will reset soon, and the next
469 * discovery will be accepted. So we can ignore it.
470 * It may also be an cloned or malicious peer having
471 * chosen the same node address and signature as an
472 * existing one.
473 * Ignore requests until the link goes down, if ever.
474 */
475 *dupl_addr = true;
476 } else if (sign_match && !addr_match && !link_up) {
477 /* Peer link has changed i/f address without rebooting.
478 * It may also be a cloned or malicious peer; we can't
479 * distinguish between the two.
480 * The signature is correct, so we must accept.
481 */
482 accept_addr = true;
483 *respond = true;
484 } else if (!sign_match && addr_match && link_up) {
485 /* Peer node rebooted. Two possibilities:
486 * - Delayed re-discovery; this link endpoint has already
487 * reset and re-established contact with the peer, before
488 * receiving a discovery message from that node.
489 * (The peer happened to receive one from this node first).
490 * - The peer came back so fast that our side has not
491 * discovered it yet. Probing from this side will soon
492 * reset the link, since there can be no working link
493 * endpoint at the peer end, and the link will re-establish.
494 * Accept the signature, since it comes from a known peer.
495 */
496 n->signature = signature;
497 } else if (!sign_match && addr_match && !link_up) {
498 /* The peer node has rebooted.
499 * Accept signature, since it is a known peer.
500 */
501 n->signature = signature;
502 *respond = true;
503 } else if (!sign_match && !addr_match && link_up) {
504 /* Peer rebooted with new address, or a new/duplicate peer.
505 * Ignore until the link goes down, if ever.
506 */
507 *dupl_addr = true;
508 } else if (!sign_match && !addr_match && !link_up) {
509 /* Peer rebooted with new address, or it is a new peer.
510 * Accept signature and address.
511 */
512 n->signature = signature;
513 accept_addr = true;
514 *respond = true;
515 }
516
517 if (!accept_addr)
518 goto exit;
442 519
520 /* Now create new link if not already existing */
443 if (!l) { 521 if (!l) {
444 l = tipc_link_create(n, b, maddr, inputq, &n->bclink.namedq); 522 l = tipc_link_create(n, b, maddr, inputq, &n->bclink.namedq);
445 if (!l) 523 if (!l) {
446 return false; 524 *respond = false;
525 goto exit;
526 }
447 tipc_node_calculate_timer(n, l); 527 tipc_node_calculate_timer(n, l);
448 if (n->link_cnt == 1) { 528 if (n->link_cnt == 1)
449 if (!mod_timer(&n->timer, jiffies + n->keepalive_intv)) 529 if (!mod_timer(&n->timer, jiffies + n->keepalive_intv))
450 tipc_node_get(n); 530 tipc_node_get(n);
451 }
452 } 531 }
453 memcpy(&l->media_addr, maddr, sizeof(*maddr)); 532 memcpy(&l->media_addr, maddr, sizeof(*maddr));
454 memcpy(curr, maddr, sizeof(*maddr)); 533 memcpy(curr_maddr, maddr, sizeof(*maddr));
455 tipc_node_link_down(n, b->identity); 534 tipc_node_link_down(n, b->identity);
456 return true; 535exit:
536 tipc_node_unlock(n);
537 tipc_node_put(n);
457} 538}
458 539
459void tipc_node_delete_links(struct net *net, int bearer_id) 540void tipc_node_delete_links(struct net *net, int bearer_id)