Commit 5a68d5ee authored by Allan Stephens's avatar Allan Stephens Committed by David S. Miller

tipc: Prevent missing name table entries when link flip-flops rapidly

Ensure that TIPC does not re-establish communication with a
neighboring node until it has finished updating all data structures
containing information about that node to reflect the earlier loss of
contact.  Previously, it was possible for TIPC to perform its purge of
name table entries relating to the node once contact had already been
re-established, resulting in the unwanted removal of valid name table
entries.
Signed-off-by: default avatarAllan Stephens <allan.stephens@windriver.com>
Signed-off-by: default avatarPaul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 564e83b5
...@@ -203,6 +203,14 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr) ...@@ -203,6 +203,14 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr)
return; return;
} }
spin_lock_bh(&n_ptr->lock); spin_lock_bh(&n_ptr->lock);
/* Don't talk to neighbor during cleanup after last session */
if (n_ptr->cleanup_required) {
spin_unlock_bh(&n_ptr->lock);
return;
}
link = n_ptr->links[b_ptr->identity]; link = n_ptr->links[b_ptr->identity];
if (!link) { if (!link) {
dbg("creating link\n"); dbg("creating link\n");
......
...@@ -1869,13 +1869,22 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) ...@@ -1869,13 +1869,22 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
goto cont; goto cont;
} }
/* Locate unicast link endpoint that should handle message */ /* Locate neighboring node that sent message */
n_ptr = tipc_node_find(msg_prevnode(msg)); n_ptr = tipc_node_find(msg_prevnode(msg));
if (unlikely(!n_ptr)) if (unlikely(!n_ptr))
goto cont; goto cont;
tipc_node_lock(n_ptr); tipc_node_lock(n_ptr);
/* Don't talk to neighbor during cleanup after last session */
if (n_ptr->cleanup_required) {
tipc_node_unlock(n_ptr);
goto cont;
}
/* Locate unicast link endpoint that should handle message */
l_ptr = n_ptr->links[b_ptr->identity]; l_ptr = n_ptr->links[b_ptr->identity];
if (unlikely(!l_ptr)) { if (unlikely(!l_ptr)) {
tipc_node_unlock(n_ptr); tipc_node_unlock(n_ptr);
......
...@@ -383,6 +383,20 @@ static void node_established_contact(struct tipc_node *n_ptr) ...@@ -383,6 +383,20 @@ static void node_established_contact(struct tipc_node *n_ptr)
tipc_highest_allowed_slave); tipc_highest_allowed_slave);
} }
static void node_cleanup_finished(unsigned long node_addr)
{
struct tipc_node *n_ptr;
read_lock_bh(&tipc_net_lock);
n_ptr = tipc_node_find(node_addr);
if (n_ptr) {
tipc_node_lock(n_ptr);
n_ptr->cleanup_required = 0;
tipc_node_unlock(n_ptr);
}
read_unlock_bh(&tipc_net_lock);
}
static void node_lost_contact(struct tipc_node *n_ptr) static void node_lost_contact(struct tipc_node *n_ptr)
{ {
struct cluster *c_ptr; struct cluster *c_ptr;
...@@ -457,6 +471,11 @@ static void node_lost_contact(struct tipc_node *n_ptr) ...@@ -457,6 +471,11 @@ static void node_lost_contact(struct tipc_node *n_ptr)
tipc_k_signal((Handler)ns->handle_node_down, tipc_k_signal((Handler)ns->handle_node_down,
(unsigned long)ns->usr_handle); (unsigned long)ns->usr_handle);
} }
/* Prevent re-contact with node until all cleanup is done */
n_ptr->cleanup_required = 1;
tipc_k_signal((Handler)node_cleanup_finished, n_ptr->addr);
} }
/** /**
......
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
* @active_links: pointers to active links to node * @active_links: pointers to active links to node
* @links: pointers to all links to node * @links: pointers to all links to node
* @working_links: number of working links to node (both active and standby) * @working_links: number of working links to node (both active and standby)
* @cleanup_required: non-zero if cleaning up after a prior loss of contact
* @link_cnt: number of links to node * @link_cnt: number of links to node
* @permit_changeover: non-zero if node has redundant links to this system * @permit_changeover: non-zero if node has redundant links to this system
* @routers: bitmap (used for multicluster communication) * @routers: bitmap (used for multicluster communication)
...@@ -78,6 +79,7 @@ struct tipc_node { ...@@ -78,6 +79,7 @@ struct tipc_node {
struct link *links[MAX_BEARERS]; struct link *links[MAX_BEARERS];
int link_cnt; int link_cnt;
int working_links; int working_links;
int cleanup_required;
int permit_changeover; int permit_changeover;
u32 routers[512/32]; u32 routers[512/32];
int last_router; int last_router;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment