diff options
author | Jon Paul Maloy <jon.maloy@ericsson.com> | 2015-07-30 18:24:22 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-07-30 20:25:14 -0400 |
commit | cf148816acb6def45474001302368eb472995e62 (patch) | |
tree | 1960bba9cffec1d73c8c5108e270cfe03580d940 /net/tipc/node.c | |
parent | 662921cd0a53db4504838dfbb7d996f9e6e94001 (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.c | 123 |
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 | ||
141 | struct tipc_node *tipc_node_create(struct net *net, u32 addr) | 141 | struct 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 | ||
425 | void tipc_node_check_dest(struct tipc_node *n, struct tipc_bearer *b, | 426 | void 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 | ||
436 | bool 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; | 535 | exit: |
536 | tipc_node_unlock(n); | ||
537 | tipc_node_put(n); | ||
457 | } | 538 | } |
458 | 539 | ||
459 | void tipc_node_delete_links(struct net *net, int bearer_id) | 540 | void tipc_node_delete_links(struct net *net, int bearer_id) |