summaryrefslogtreecommitdiffstats
path: root/net/tipc/discover.c
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2015-02-03 08:59:19 -0500
committerDavid S. Miller <davem@davemloft.net>2015-02-04 19:09:31 -0500
commitb45db71b525d75e520d7ef46c796f49c5d26c07c (patch)
treee19c1c7f6bc27d63e28a1315b7b19ce1d099e02d /net/tipc/discover.c
parent7d24dcdb3f3132e0ec36f19c49bd004bc874b8aa (diff)
tipc: eliminate race during node creation
Instances of struct node are created in the function tipc_disc_rcv() under the assumption that there is no race between received discovery messages arriving from the same node. This assumption is wrong. When we use more than one bearer, it is possible that discovery messages from the same node arrive at the same moment, resulting in creation of two instances of struct tipc_node. This may later cause confusion during link establishment, and may result in one of the links never becoming activated. We fix this by making lookup and potential creation of nodes atomic. Instead of first looking up the node, and in case of failure, create it, we now start with looking up the node inside node_link_create(), and return a reference to that one if found. Otherwise, we go ahead and create the node as we did before. Reviewed-by: Erik Hugne <erik.hugne@ericsson.com> Reviewed-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/discover.c')
-rw-r--r--net/tipc/discover.c9
1 files changed, 2 insertions, 7 deletions
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index 5b40cb89ff0a..a580a40d0208 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * net/tipc/discover.c 2 * net/tipc/discover.c
3 * 3 *
4 * Copyright (c) 2003-2006, 2014, Ericsson AB 4 * Copyright (c) 2003-2006, 2014-2015, Ericsson AB
5 * Copyright (c) 2005-2006, 2010-2011, Wind River Systems 5 * Copyright (c) 2005-2006, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
@@ -47,7 +47,6 @@
47/* indicates no timer in use */ 47/* indicates no timer in use */
48#define TIPC_LINK_REQ_INACTIVE 0xffffffff 48#define TIPC_LINK_REQ_INACTIVE 0xffffffff
49 49
50
51/** 50/**
52 * struct tipc_link_req - information about an ongoing link setup request 51 * struct tipc_link_req - information about an ongoing link setup request
53 * @bearer_id: identity of bearer issuing requests 52 * @bearer_id: identity of bearer issuing requests
@@ -163,13 +162,9 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *buf,
163 if (!tipc_in_scope(bearer->domain, onode)) 162 if (!tipc_in_scope(bearer->domain, onode))
164 return; 163 return;
165 164
166 /* Locate, or if necessary, create, node: */ 165 node = tipc_node_create(net, onode);
167 node = tipc_node_find(net, onode);
168 if (!node)
169 node = tipc_node_create(net, onode);
170 if (!node) 166 if (!node)
171 return; 167 return;
172
173 tipc_node_lock(node); 168 tipc_node_lock(node);
174 link = node->links[bearer->identity]; 169 link = node->links[bearer->identity];
175 170