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.c31
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,
437static void tipc_node_link_down(struct tipc_node *n, int bearer_id, bool delete) 441static 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));
580exit: 593exit:
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;