From 7d24dcdb3f3132e0ec36f19c49bd004bc874b8aa Mon Sep 17 00:00:00 2001 From: Jon Paul Maloy Date: Tue, 3 Feb 2015 08:59:18 -0500 Subject: [PATCH] tipc: avoid stale link after aborted failover During link failover it may happen that the remaining link goes down while it is still in the process of taking over traffic from a previously failed link. When this happens, we currently abort the failover procedure and reset the first failed link to non-failover mode, so that it will be ready to re-establish contact with its peer when it comes available. However, if the first link goes down because its bearer was manually disabled, it is not enough to reset it; it must also be deleted; which is supposed to happen when the failover procedure is finished. Otherwise it will remain a zombie link: attached to the owner node structure, in mode LINK_STOPPED, and permanently blocking any re- establishing of the link to the peer via the interface in question. We fix this by amending the failover abort procedure. Apart from resetting the link to non-failover state, we test if the link is also in LINK_STOPPED mode. If so, we delete it, using the conditional tipc_link_delete() function introduced in the previous commit. Reviewed-by: Erik Hugne Reviewed-by: Ying Xue Signed-off-by: Jon Maloy Signed-off-by: David S. Miller --- net/tipc/link.h | 1 + net/tipc/node.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/net/tipc/link.h b/net/tipc/link.h index f06b779c9f75..3e3432b3044e 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -202,6 +202,7 @@ struct tipc_port; struct tipc_link *tipc_link_create(struct tipc_node *n_ptr, struct tipc_bearer *b_ptr, const struct tipc_media_addr *media_addr); +void tipc_link_delete(struct tipc_link *link); void tipc_link_delete_list(struct net *net, unsigned int bearer_id, bool shutting_down); void tipc_link_failover_send_queue(struct tipc_link *l_ptr); diff --git a/net/tipc/node.c b/net/tipc/node.c index ee5d33cfcf80..d4cb8c127063 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -406,6 +406,10 @@ static void node_lost_contact(struct tipc_node *n_ptr) l_ptr->reset_checkpoint = l_ptr->next_in_no; l_ptr->exp_msg_count = 0; tipc_link_reset_fragments(l_ptr); + + /* Link marked for deletion after failover? => do it now */ + if (l_ptr->flags & LINK_STOPPED) + tipc_link_delete(l_ptr); } n_ptr->action_flags &= ~TIPC_WAIT_OWN_LINKS_DOWN; -- 2.20.1