diff options
Diffstat (limited to 'net/tipc/node.c')
-rw-r--r-- | net/tipc/node.c | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c index 703875fd6cde..656b5791f1a5 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
@@ -317,7 +317,11 @@ static void __tipc_node_link_up(struct tipc_node *n, int bearer_id, | |||
317 | struct tipc_link *ol = node_active_link(n, 0); | 317 | struct tipc_link *ol = node_active_link(n, 0); |
318 | struct tipc_link *nl = n->links[bearer_id].link; | 318 | struct tipc_link *nl = n->links[bearer_id].link; |
319 | 319 | ||
320 | if (!nl || !tipc_link_is_up(nl)) | 320 | if (!nl) |
321 | return; | ||
322 | |||
323 | tipc_link_fsm_evt(nl, LINK_ESTABLISH_EVT); | ||
324 | if (!tipc_link_is_up(nl)) | ||
321 | return; | 325 | return; |
322 | 326 | ||
323 | n->working_links++; | 327 | n->working_links++; |
@@ -437,17 +441,26 @@ static void __tipc_node_link_down(struct tipc_node *n, int *bearer_id, | |||
437 | static void tipc_node_link_down(struct tipc_node *n, int bearer_id, bool delete) | 441 | static void tipc_node_link_down(struct tipc_node *n, int bearer_id, bool delete) |
438 | { | 442 | { |
439 | struct tipc_link_entry *le = &n->links[bearer_id]; | 443 | struct tipc_link_entry *le = &n->links[bearer_id]; |
444 | struct tipc_link *l = le->link; | ||
440 | struct tipc_media_addr *maddr; | 445 | struct tipc_media_addr *maddr; |
441 | struct sk_buff_head xmitq; | 446 | struct sk_buff_head xmitq; |
442 | 447 | ||
448 | if (!l) | ||
449 | return; | ||
450 | |||
443 | __skb_queue_head_init(&xmitq); | 451 | __skb_queue_head_init(&xmitq); |
444 | 452 | ||
445 | tipc_node_lock(n); | 453 | tipc_node_lock(n); |
446 | __tipc_node_link_down(n, &bearer_id, &xmitq, &maddr); | 454 | if (!tipc_link_is_establishing(l)) { |
447 | if (delete && le->link) { | 455 | __tipc_node_link_down(n, &bearer_id, &xmitq, &maddr); |
448 | kfree(le->link); | 456 | if (delete) { |
449 | le->link = NULL; | 457 | kfree(l); |
450 | n->link_cnt--; | 458 | le->link = NULL; |
459 | n->link_cnt--; | ||
460 | } | ||
461 | } else { | ||
462 | /* Defuse pending tipc_node_link_up() */ | ||
463 | tipc_link_fsm_evt(l, LINK_RESET_EVT); | ||
451 | } | 464 | } |
452 | tipc_node_unlock(n); | 465 | tipc_node_unlock(n); |
453 | 466 | ||
@@ -579,7 +592,7 @@ void tipc_node_check_dest(struct net *net, u32 onode, | |||
579 | memcpy(&le->maddr, maddr, sizeof(*maddr)); | 592 | memcpy(&le->maddr, maddr, sizeof(*maddr)); |
580 | exit: | 593 | exit: |
581 | tipc_node_unlock(n); | 594 | tipc_node_unlock(n); |
582 | if (reset) | 595 | if (reset && !tipc_link_is_reset(l)) |
583 | tipc_node_link_down(n, b->identity, false); | 596 | tipc_node_link_down(n, b->identity, false); |
584 | tipc_node_put(n); | 597 | tipc_node_put(n); |
585 | } | 598 | } |
@@ -686,10 +699,10 @@ static void tipc_node_fsm_evt(struct tipc_node *n, int evt) | |||
686 | break; | 699 | break; |
687 | case SELF_ESTABL_CONTACT_EVT: | 700 | case SELF_ESTABL_CONTACT_EVT: |
688 | case PEER_LOST_CONTACT_EVT: | 701 | case PEER_LOST_CONTACT_EVT: |
689 | break; | ||
690 | case NODE_SYNCH_END_EVT: | 702 | case NODE_SYNCH_END_EVT: |
691 | case NODE_SYNCH_BEGIN_EVT: | ||
692 | case NODE_FAILOVER_BEGIN_EVT: | 703 | case NODE_FAILOVER_BEGIN_EVT: |
704 | break; | ||
705 | case NODE_SYNCH_BEGIN_EVT: | ||
693 | case NODE_FAILOVER_END_EVT: | 706 | case NODE_FAILOVER_END_EVT: |
694 | default: | 707 | default: |
695 | goto illegal_evt; | 708 | goto illegal_evt; |