Commit 66996b6c47ed7f6bbb01a768e23fae262c7db8e0

Authored by Jon Paul Maloy
Committed by David S. Miller
1 parent 655fb243b8

tipc: extend node FSM

In the next commit, we will move link synch/failover orchestration to
the link aggregation level. In order to do this, we first need to extend
the node FSM with two more states, NODE_SYNCHING and NODE_FAILINGOVER,
plus four new events to enter and leave those states.

This commit introduces this change, without yet making use of it.
The node FSM now looks as follows:

                           +-----------------------------------------+
                           |                            PEER_DOWN_EVT|
                           |                                         |
  +------------------------+----------------+                        |
  |SELF_DOWN_EVT           |                |                        |
  |                        |                |                        |
  |              +-----------+          +-----------+                |
  |              |NODE_      |          |NODE_      |                |
  |   +----------|FAILINGOVER|<---------|SYNCHING   |------------+   |
  |   |SELF_     +-----------+ FAILOVER_+-----------+    PEER_   |   |
  |   |DOWN_EVT   |         A  BEGIN_EVT A         |     DOWN_EVT|   |
  |   |           |         |            |         |             |   |
  |   |           |         |            |         |             |   |
  |   |           |FAILOVER_|FAILOVER_   |SYNCH_   |SYNCH_       |   |
  |   |           |END_EVT  |BEGIN_EVT   |BEGIN_EVT|END_EVT      |   |
  |   |           |         |            |         |             |   |
  |   |           |         |            |         |             |   |
  |   |           |        +--------------+        |             |   |
  |   |           +------->|   SELF_UP_   |<-------+             |   |
  |   |   +----------------|   PEER_UP    |------------------+   |   |
  |   |   |SELF_DOWN_EVT   +--------------+     PEER_DOWN_EVT|   |   |
  |   |   |                   A          A                   |   |   |
  |   |   |                   |          |                   |   |   |
  |   |   |        PEER_UP_EVT|          |SELF_UP_EVT        |   |   |
  |   |   |                   |          |                   |   |   |
  V   V   V                   |          |                   V   V   V
+------------+       +-----------+    +-----------+       +------------+
|SELF_DOWN_  |       |SELF_UP_   |    |PEER_UP_   |       |PEER_DOWN   |
|PEER_LEAVING|<------|PEER_COMING|    |SELF_COMING|------>|SELF_LEAVING|
+------------+ SELF_ +-----------+    +-----------+ PEER_ +------------+
       |       DOWN_EVT       A          A          DOWN_EVT     |
       |                      |          |                       |
       |                      |          |                       |
       |           SELF_UP_EVT|          |PEER_UP_EVT            |
       |                      |          |                       |
       |                      |          |                       |
       |PEER_DOWN_EVT       +--------------+        SELF_DOWN_EVT|
       +------------------->|  SELF_DOWN_  |<--------------------+
                            |  PEER_DOWN   |
                            +--------------+

Tested-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>

Showing 2 changed files with 92 additions and 11 deletions Inline Diff

1 /* 1 /*
2 * net/tipc/node.c: TIPC node management routines 2 * net/tipc/node.c: TIPC node management routines
3 * 3 *
4 * Copyright (c) 2000-2006, 2012-2015, Ericsson AB 4 * Copyright (c) 2000-2006, 2012-2015, Ericsson AB
5 * Copyright (c) 2005-2006, 2010-2014, Wind River Systems 5 * Copyright (c) 2005-2006, 2010-2014, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met: 9 * modification, are permitted provided that the following conditions are met:
10 * 10 *
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the names of the copyright holders nor the names of its 16 * 3. Neither the names of the copyright holders nor the names of its
17 * contributors may be used to endorse or promote products derived from 17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission. 18 * this software without specific prior written permission.
19 * 19 *
20 * Alternatively, this software may be distributed under the terms of the 20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free 21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation. 22 * Software Foundation.
23 * 23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37 #include "core.h" 37 #include "core.h"
38 #include "link.h" 38 #include "link.h"
39 #include "node.h" 39 #include "node.h"
40 #include "name_distr.h" 40 #include "name_distr.h"
41 #include "socket.h" 41 #include "socket.h"
42 #include "bcast.h" 42 #include "bcast.h"
43 #include "discover.h" 43 #include "discover.h"
44 44
45 static void node_lost_contact(struct tipc_node *n_ptr); 45 static void node_lost_contact(struct tipc_node *n_ptr);
46 static void node_established_contact(struct tipc_node *n_ptr); 46 static void node_established_contact(struct tipc_node *n_ptr);
47 static void tipc_node_delete(struct tipc_node *node); 47 static void tipc_node_delete(struct tipc_node *node);
48 static void tipc_node_timeout(unsigned long data); 48 static void tipc_node_timeout(unsigned long data);
49 static void tipc_node_fsm_evt(struct tipc_node *n, int evt); 49 static void tipc_node_fsm_evt(struct tipc_node *n, int evt);
50 50
51 struct tipc_sock_conn { 51 struct tipc_sock_conn {
52 u32 port; 52 u32 port;
53 u32 peer_port; 53 u32 peer_port;
54 u32 peer_node; 54 u32 peer_node;
55 struct list_head list; 55 struct list_head list;
56 }; 56 };
57 57
58 static const struct nla_policy tipc_nl_node_policy[TIPC_NLA_NODE_MAX + 1] = { 58 static const struct nla_policy tipc_nl_node_policy[TIPC_NLA_NODE_MAX + 1] = {
59 [TIPC_NLA_NODE_UNSPEC] = { .type = NLA_UNSPEC }, 59 [TIPC_NLA_NODE_UNSPEC] = { .type = NLA_UNSPEC },
60 [TIPC_NLA_NODE_ADDR] = { .type = NLA_U32 }, 60 [TIPC_NLA_NODE_ADDR] = { .type = NLA_U32 },
61 [TIPC_NLA_NODE_UP] = { .type = NLA_FLAG } 61 [TIPC_NLA_NODE_UP] = { .type = NLA_FLAG }
62 }; 62 };
63 63
64 /* 64 /*
65 * A trivial power-of-two bitmask technique is used for speed, since this 65 * A trivial power-of-two bitmask technique is used for speed, since this
66 * operation is done for every incoming TIPC packet. The number of hash table 66 * operation is done for every incoming TIPC packet. The number of hash table
67 * entries has been chosen so that no hash chain exceeds 8 nodes and will 67 * entries has been chosen so that no hash chain exceeds 8 nodes and will
68 * usually be much smaller (typically only a single node). 68 * usually be much smaller (typically only a single node).
69 */ 69 */
70 static unsigned int tipc_hashfn(u32 addr) 70 static unsigned int tipc_hashfn(u32 addr)
71 { 71 {
72 return addr & (NODE_HTABLE_SIZE - 1); 72 return addr & (NODE_HTABLE_SIZE - 1);
73 } 73 }
74 74
75 static void tipc_node_kref_release(struct kref *kref) 75 static void tipc_node_kref_release(struct kref *kref)
76 { 76 {
77 struct tipc_node *node = container_of(kref, struct tipc_node, kref); 77 struct tipc_node *node = container_of(kref, struct tipc_node, kref);
78 78
79 tipc_node_delete(node); 79 tipc_node_delete(node);
80 } 80 }
81 81
82 void tipc_node_put(struct tipc_node *node) 82 void tipc_node_put(struct tipc_node *node)
83 { 83 {
84 kref_put(&node->kref, tipc_node_kref_release); 84 kref_put(&node->kref, tipc_node_kref_release);
85 } 85 }
86 86
87 static void tipc_node_get(struct tipc_node *node) 87 static void tipc_node_get(struct tipc_node *node)
88 { 88 {
89 kref_get(&node->kref); 89 kref_get(&node->kref);
90 } 90 }
91 91
92 /* 92 /*
93 * tipc_node_find - locate specified node object, if it exists 93 * tipc_node_find - locate specified node object, if it exists
94 */ 94 */
95 struct tipc_node *tipc_node_find(struct net *net, u32 addr) 95 struct tipc_node *tipc_node_find(struct net *net, u32 addr)
96 { 96 {
97 struct tipc_net *tn = net_generic(net, tipc_net_id); 97 struct tipc_net *tn = net_generic(net, tipc_net_id);
98 struct tipc_node *node; 98 struct tipc_node *node;
99 99
100 if (unlikely(!in_own_cluster_exact(net, addr))) 100 if (unlikely(!in_own_cluster_exact(net, addr)))
101 return NULL; 101 return NULL;
102 102
103 rcu_read_lock(); 103 rcu_read_lock();
104 hlist_for_each_entry_rcu(node, &tn->node_htable[tipc_hashfn(addr)], 104 hlist_for_each_entry_rcu(node, &tn->node_htable[tipc_hashfn(addr)],
105 hash) { 105 hash) {
106 if (node->addr == addr) { 106 if (node->addr == addr) {
107 tipc_node_get(node); 107 tipc_node_get(node);
108 rcu_read_unlock(); 108 rcu_read_unlock();
109 return node; 109 return node;
110 } 110 }
111 } 111 }
112 rcu_read_unlock(); 112 rcu_read_unlock();
113 return NULL; 113 return NULL;
114 } 114 }
115 115
116 struct tipc_node *tipc_node_create(struct net *net, u32 addr) 116 struct tipc_node *tipc_node_create(struct net *net, u32 addr)
117 { 117 {
118 struct tipc_net *tn = net_generic(net, tipc_net_id); 118 struct tipc_net *tn = net_generic(net, tipc_net_id);
119 struct tipc_node *n_ptr, *temp_node; 119 struct tipc_node *n_ptr, *temp_node;
120 120
121 spin_lock_bh(&tn->node_list_lock); 121 spin_lock_bh(&tn->node_list_lock);
122 n_ptr = tipc_node_find(net, addr); 122 n_ptr = tipc_node_find(net, addr);
123 if (n_ptr) 123 if (n_ptr)
124 goto exit; 124 goto exit;
125 n_ptr = kzalloc(sizeof(*n_ptr), GFP_ATOMIC); 125 n_ptr = kzalloc(sizeof(*n_ptr), GFP_ATOMIC);
126 if (!n_ptr) { 126 if (!n_ptr) {
127 pr_warn("Node creation failed, no memory\n"); 127 pr_warn("Node creation failed, no memory\n");
128 goto exit; 128 goto exit;
129 } 129 }
130 n_ptr->addr = addr; 130 n_ptr->addr = addr;
131 n_ptr->net = net; 131 n_ptr->net = net;
132 kref_init(&n_ptr->kref); 132 kref_init(&n_ptr->kref);
133 spin_lock_init(&n_ptr->lock); 133 spin_lock_init(&n_ptr->lock);
134 INIT_HLIST_NODE(&n_ptr->hash); 134 INIT_HLIST_NODE(&n_ptr->hash);
135 INIT_LIST_HEAD(&n_ptr->list); 135 INIT_LIST_HEAD(&n_ptr->list);
136 INIT_LIST_HEAD(&n_ptr->publ_list); 136 INIT_LIST_HEAD(&n_ptr->publ_list);
137 INIT_LIST_HEAD(&n_ptr->conn_sks); 137 INIT_LIST_HEAD(&n_ptr->conn_sks);
138 skb_queue_head_init(&n_ptr->bclink.namedq); 138 skb_queue_head_init(&n_ptr->bclink.namedq);
139 __skb_queue_head_init(&n_ptr->bclink.deferdq); 139 __skb_queue_head_init(&n_ptr->bclink.deferdq);
140 hlist_add_head_rcu(&n_ptr->hash, &tn->node_htable[tipc_hashfn(addr)]); 140 hlist_add_head_rcu(&n_ptr->hash, &tn->node_htable[tipc_hashfn(addr)]);
141 list_for_each_entry_rcu(temp_node, &tn->node_list, list) { 141 list_for_each_entry_rcu(temp_node, &tn->node_list, list) {
142 if (n_ptr->addr < temp_node->addr) 142 if (n_ptr->addr < temp_node->addr)
143 break; 143 break;
144 } 144 }
145 list_add_tail_rcu(&n_ptr->list, &temp_node->list); 145 list_add_tail_rcu(&n_ptr->list, &temp_node->list);
146 n_ptr->state = SELF_DOWN_PEER_LEAVING; 146 n_ptr->state = SELF_DOWN_PEER_LEAVING;
147 n_ptr->signature = INVALID_NODE_SIG; 147 n_ptr->signature = INVALID_NODE_SIG;
148 n_ptr->active_links[0] = INVALID_BEARER_ID; 148 n_ptr->active_links[0] = INVALID_BEARER_ID;
149 n_ptr->active_links[1] = INVALID_BEARER_ID; 149 n_ptr->active_links[1] = INVALID_BEARER_ID;
150 tipc_node_get(n_ptr); 150 tipc_node_get(n_ptr);
151 setup_timer(&n_ptr->timer, tipc_node_timeout, (unsigned long)n_ptr); 151 setup_timer(&n_ptr->timer, tipc_node_timeout, (unsigned long)n_ptr);
152 n_ptr->keepalive_intv = U32_MAX; 152 n_ptr->keepalive_intv = U32_MAX;
153 exit: 153 exit:
154 spin_unlock_bh(&tn->node_list_lock); 154 spin_unlock_bh(&tn->node_list_lock);
155 return n_ptr; 155 return n_ptr;
156 } 156 }
157 157
158 static void tipc_node_calculate_timer(struct tipc_node *n, struct tipc_link *l) 158 static void tipc_node_calculate_timer(struct tipc_node *n, struct tipc_link *l)
159 { 159 {
160 unsigned long tol = l->tolerance; 160 unsigned long tol = l->tolerance;
161 unsigned long intv = ((tol / 4) > 500) ? 500 : tol / 4; 161 unsigned long intv = ((tol / 4) > 500) ? 500 : tol / 4;
162 unsigned long keepalive_intv = msecs_to_jiffies(intv); 162 unsigned long keepalive_intv = msecs_to_jiffies(intv);
163 163
164 /* Link with lowest tolerance determines timer interval */ 164 /* Link with lowest tolerance determines timer interval */
165 if (keepalive_intv < n->keepalive_intv) 165 if (keepalive_intv < n->keepalive_intv)
166 n->keepalive_intv = keepalive_intv; 166 n->keepalive_intv = keepalive_intv;
167 167
168 /* Ensure link's abort limit corresponds to current interval */ 168 /* Ensure link's abort limit corresponds to current interval */
169 l->abort_limit = l->tolerance / jiffies_to_msecs(n->keepalive_intv); 169 l->abort_limit = l->tolerance / jiffies_to_msecs(n->keepalive_intv);
170 } 170 }
171 171
172 static void tipc_node_delete(struct tipc_node *node) 172 static void tipc_node_delete(struct tipc_node *node)
173 { 173 {
174 list_del_rcu(&node->list); 174 list_del_rcu(&node->list);
175 hlist_del_rcu(&node->hash); 175 hlist_del_rcu(&node->hash);
176 kfree_rcu(node, rcu); 176 kfree_rcu(node, rcu);
177 } 177 }
178 178
179 void tipc_node_stop(struct net *net) 179 void tipc_node_stop(struct net *net)
180 { 180 {
181 struct tipc_net *tn = net_generic(net, tipc_net_id); 181 struct tipc_net *tn = net_generic(net, tipc_net_id);
182 struct tipc_node *node, *t_node; 182 struct tipc_node *node, *t_node;
183 183
184 spin_lock_bh(&tn->node_list_lock); 184 spin_lock_bh(&tn->node_list_lock);
185 list_for_each_entry_safe(node, t_node, &tn->node_list, list) { 185 list_for_each_entry_safe(node, t_node, &tn->node_list, list) {
186 if (del_timer(&node->timer)) 186 if (del_timer(&node->timer))
187 tipc_node_put(node); 187 tipc_node_put(node);
188 tipc_node_put(node); 188 tipc_node_put(node);
189 } 189 }
190 spin_unlock_bh(&tn->node_list_lock); 190 spin_unlock_bh(&tn->node_list_lock);
191 } 191 }
192 192
193 int tipc_node_add_conn(struct net *net, u32 dnode, u32 port, u32 peer_port) 193 int tipc_node_add_conn(struct net *net, u32 dnode, u32 port, u32 peer_port)
194 { 194 {
195 struct tipc_node *node; 195 struct tipc_node *node;
196 struct tipc_sock_conn *conn; 196 struct tipc_sock_conn *conn;
197 int err = 0; 197 int err = 0;
198 198
199 if (in_own_node(net, dnode)) 199 if (in_own_node(net, dnode))
200 return 0; 200 return 0;
201 201
202 node = tipc_node_find(net, dnode); 202 node = tipc_node_find(net, dnode);
203 if (!node) { 203 if (!node) {
204 pr_warn("Connecting sock to node 0x%x failed\n", dnode); 204 pr_warn("Connecting sock to node 0x%x failed\n", dnode);
205 return -EHOSTUNREACH; 205 return -EHOSTUNREACH;
206 } 206 }
207 conn = kmalloc(sizeof(*conn), GFP_ATOMIC); 207 conn = kmalloc(sizeof(*conn), GFP_ATOMIC);
208 if (!conn) { 208 if (!conn) {
209 err = -EHOSTUNREACH; 209 err = -EHOSTUNREACH;
210 goto exit; 210 goto exit;
211 } 211 }
212 conn->peer_node = dnode; 212 conn->peer_node = dnode;
213 conn->port = port; 213 conn->port = port;
214 conn->peer_port = peer_port; 214 conn->peer_port = peer_port;
215 215
216 tipc_node_lock(node); 216 tipc_node_lock(node);
217 list_add_tail(&conn->list, &node->conn_sks); 217 list_add_tail(&conn->list, &node->conn_sks);
218 tipc_node_unlock(node); 218 tipc_node_unlock(node);
219 exit: 219 exit:
220 tipc_node_put(node); 220 tipc_node_put(node);
221 return err; 221 return err;
222 } 222 }
223 223
224 void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port) 224 void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port)
225 { 225 {
226 struct tipc_node *node; 226 struct tipc_node *node;
227 struct tipc_sock_conn *conn, *safe; 227 struct tipc_sock_conn *conn, *safe;
228 228
229 if (in_own_node(net, dnode)) 229 if (in_own_node(net, dnode))
230 return; 230 return;
231 231
232 node = tipc_node_find(net, dnode); 232 node = tipc_node_find(net, dnode);
233 if (!node) 233 if (!node)
234 return; 234 return;
235 235
236 tipc_node_lock(node); 236 tipc_node_lock(node);
237 list_for_each_entry_safe(conn, safe, &node->conn_sks, list) { 237 list_for_each_entry_safe(conn, safe, &node->conn_sks, list) {
238 if (port != conn->port) 238 if (port != conn->port)
239 continue; 239 continue;
240 list_del(&conn->list); 240 list_del(&conn->list);
241 kfree(conn); 241 kfree(conn);
242 } 242 }
243 tipc_node_unlock(node); 243 tipc_node_unlock(node);
244 tipc_node_put(node); 244 tipc_node_put(node);
245 } 245 }
246 246
247 /* tipc_node_timeout - handle expiration of node timer 247 /* tipc_node_timeout - handle expiration of node timer
248 */ 248 */
249 static void tipc_node_timeout(unsigned long data) 249 static void tipc_node_timeout(unsigned long data)
250 { 250 {
251 struct tipc_node *n = (struct tipc_node *)data; 251 struct tipc_node *n = (struct tipc_node *)data;
252 struct sk_buff_head xmitq; 252 struct sk_buff_head xmitq;
253 struct tipc_link *l; 253 struct tipc_link *l;
254 struct tipc_media_addr *maddr; 254 struct tipc_media_addr *maddr;
255 int bearer_id; 255 int bearer_id;
256 int rc = 0; 256 int rc = 0;
257 257
258 __skb_queue_head_init(&xmitq); 258 __skb_queue_head_init(&xmitq);
259 259
260 for (bearer_id = 0; bearer_id < MAX_BEARERS; bearer_id++) { 260 for (bearer_id = 0; bearer_id < MAX_BEARERS; bearer_id++) {
261 tipc_node_lock(n); 261 tipc_node_lock(n);
262 l = n->links[bearer_id].link; 262 l = n->links[bearer_id].link;
263 if (l) { 263 if (l) {
264 /* Link tolerance may change asynchronously: */ 264 /* Link tolerance may change asynchronously: */
265 tipc_node_calculate_timer(n, l); 265 tipc_node_calculate_timer(n, l);
266 rc = tipc_link_timeout(l, &xmitq); 266 rc = tipc_link_timeout(l, &xmitq);
267 if (rc & TIPC_LINK_DOWN_EVT) 267 if (rc & TIPC_LINK_DOWN_EVT)
268 tipc_node_link_down(n, bearer_id); 268 tipc_node_link_down(n, bearer_id);
269 } 269 }
270 tipc_node_unlock(n); 270 tipc_node_unlock(n);
271 maddr = &n->links[bearer_id].maddr; 271 maddr = &n->links[bearer_id].maddr;
272 tipc_bearer_xmit(n->net, bearer_id, &xmitq, maddr); 272 tipc_bearer_xmit(n->net, bearer_id, &xmitq, maddr);
273 } 273 }
274 if (!mod_timer(&n->timer, jiffies + n->keepalive_intv)) 274 if (!mod_timer(&n->timer, jiffies + n->keepalive_intv))
275 tipc_node_get(n); 275 tipc_node_get(n);
276 tipc_node_put(n); 276 tipc_node_put(n);
277 } 277 }
278 278
279 /** 279 /**
280 * tipc_node_link_up - handle addition of link 280 * tipc_node_link_up - handle addition of link
281 * 281 *
282 * Link becomes active (alone or shared) or standby, depending on its priority. 282 * Link becomes active (alone or shared) or standby, depending on its priority.
283 */ 283 */
284 void tipc_node_link_up(struct tipc_node *n, int bearer_id) 284 void tipc_node_link_up(struct tipc_node *n, int bearer_id)
285 { 285 {
286 int *slot0 = &n->active_links[0]; 286 int *slot0 = &n->active_links[0];
287 int *slot1 = &n->active_links[1]; 287 int *slot1 = &n->active_links[1];
288 struct tipc_link_entry *links = n->links; 288 struct tipc_link_entry *links = n->links;
289 struct tipc_link *l = n->links[bearer_id].link; 289 struct tipc_link *l = n->links[bearer_id].link;
290 290
291 /* Leave room for tunnel header when returning 'mtu' to users: */ 291 /* Leave room for tunnel header when returning 'mtu' to users: */
292 links[bearer_id].mtu = l->mtu - INT_H_SIZE; 292 links[bearer_id].mtu = l->mtu - INT_H_SIZE;
293 293
294 n->working_links++; 294 n->working_links++;
295 n->action_flags |= TIPC_NOTIFY_LINK_UP; 295 n->action_flags |= TIPC_NOTIFY_LINK_UP;
296 n->link_id = l->peer_bearer_id << 16 | l->bearer_id; 296 n->link_id = l->peer_bearer_id << 16 | l->bearer_id;
297 297
298 tipc_bearer_add_dest(n->net, bearer_id, n->addr); 298 tipc_bearer_add_dest(n->net, bearer_id, n->addr);
299 299
300 pr_debug("Established link <%s> on network plane %c\n", 300 pr_debug("Established link <%s> on network plane %c\n",
301 l->name, l->net_plane); 301 l->name, l->net_plane);
302 302
303 /* No active links ? => take both active slots */ 303 /* No active links ? => take both active slots */
304 if (!tipc_node_is_up(n)) { 304 if (!tipc_node_is_up(n)) {
305 *slot0 = bearer_id; 305 *slot0 = bearer_id;
306 *slot1 = bearer_id; 306 *slot1 = bearer_id;
307 node_established_contact(n); 307 node_established_contact(n);
308 return; 308 return;
309 } 309 }
310 310
311 /* Lower prio than current active ? => no slot */ 311 /* Lower prio than current active ? => no slot */
312 if (l->priority < links[*slot0].link->priority) { 312 if (l->priority < links[*slot0].link->priority) {
313 pr_debug("New link <%s> becomes standby\n", l->name); 313 pr_debug("New link <%s> becomes standby\n", l->name);
314 return; 314 return;
315 } 315 }
316 tipc_link_dup_queue_xmit(links[*slot0].link, l); 316 tipc_link_dup_queue_xmit(links[*slot0].link, l);
317 317
318 /* Same prio as current active ? => take one slot */ 318 /* Same prio as current active ? => take one slot */
319 if (l->priority == links[*slot0].link->priority) { 319 if (l->priority == links[*slot0].link->priority) {
320 *slot0 = bearer_id; 320 *slot0 = bearer_id;
321 return; 321 return;
322 } 322 }
323 323
324 /* Higher prio than current active => take both active slots */ 324 /* Higher prio than current active => take both active slots */
325 pr_debug("Old link <%s> now standby\n", links[*slot0].link->name); 325 pr_debug("Old link <%s> now standby\n", links[*slot0].link->name);
326 *slot0 = bearer_id; 326 *slot0 = bearer_id;
327 *slot1 = bearer_id; 327 *slot1 = bearer_id;
328 } 328 }
329 329
330 /** 330 /**
331 * tipc_node_link_down - handle loss of link 331 * tipc_node_link_down - handle loss of link
332 */ 332 */
333 void tipc_node_link_down(struct tipc_node *n, int bearer_id) 333 void tipc_node_link_down(struct tipc_node *n, int bearer_id)
334 { 334 {
335 int *slot0 = &n->active_links[0]; 335 int *slot0 = &n->active_links[0];
336 int *slot1 = &n->active_links[1]; 336 int *slot1 = &n->active_links[1];
337 int i, highest = 0; 337 int i, highest = 0;
338 struct tipc_link *l, *_l; 338 struct tipc_link *l, *_l;
339 339
340 l = n->links[bearer_id].link; 340 l = n->links[bearer_id].link;
341 if (!l || !tipc_link_is_up(l)) 341 if (!l || !tipc_link_is_up(l))
342 return; 342 return;
343 343
344 n->working_links--; 344 n->working_links--;
345 n->action_flags |= TIPC_NOTIFY_LINK_DOWN; 345 n->action_flags |= TIPC_NOTIFY_LINK_DOWN;
346 n->link_id = l->peer_bearer_id << 16 | l->bearer_id; 346 n->link_id = l->peer_bearer_id << 16 | l->bearer_id;
347 347
348 tipc_bearer_remove_dest(n->net, l->bearer_id, n->addr); 348 tipc_bearer_remove_dest(n->net, l->bearer_id, n->addr);
349 349
350 pr_debug("Lost link <%s> on network plane %c\n", 350 pr_debug("Lost link <%s> on network plane %c\n",
351 l->name, l->net_plane); 351 l->name, l->net_plane);
352 352
353 /* Select new active link if any available */ 353 /* Select new active link if any available */
354 *slot0 = INVALID_BEARER_ID; 354 *slot0 = INVALID_BEARER_ID;
355 *slot1 = INVALID_BEARER_ID; 355 *slot1 = INVALID_BEARER_ID;
356 for (i = 0; i < MAX_BEARERS; i++) { 356 for (i = 0; i < MAX_BEARERS; i++) {
357 _l = n->links[i].link; 357 _l = n->links[i].link;
358 if (!_l || !tipc_link_is_up(_l)) 358 if (!_l || !tipc_link_is_up(_l))
359 continue; 359 continue;
360 if (_l == l) 360 if (_l == l)
361 continue; 361 continue;
362 if (_l->priority < highest) 362 if (_l->priority < highest)
363 continue; 363 continue;
364 if (_l->priority > highest) { 364 if (_l->priority > highest) {
365 highest = _l->priority; 365 highest = _l->priority;
366 *slot0 = i; 366 *slot0 = i;
367 *slot1 = i; 367 *slot1 = i;
368 continue; 368 continue;
369 } 369 }
370 *slot1 = i; 370 *slot1 = i;
371 } 371 }
372 372
373 if (tipc_node_is_up(n)) 373 if (tipc_node_is_up(n))
374 tipc_link_failover_send_queue(l); 374 tipc_link_failover_send_queue(l);
375 375
376 tipc_link_reset(l); 376 tipc_link_reset(l);
377 377
378 if (!tipc_node_is_up(n)) 378 if (!tipc_node_is_up(n))
379 node_lost_contact(n); 379 node_lost_contact(n);
380 } 380 }
381 381
382 bool tipc_node_is_up(struct tipc_node *n) 382 bool tipc_node_is_up(struct tipc_node *n)
383 { 383 {
384 return n->active_links[0] != INVALID_BEARER_ID; 384 return n->active_links[0] != INVALID_BEARER_ID;
385 } 385 }
386 386
387 void tipc_node_check_dest(struct tipc_node *n, struct tipc_bearer *b, 387 void tipc_node_check_dest(struct tipc_node *n, struct tipc_bearer *b,
388 bool *link_up, bool *addr_match, 388 bool *link_up, bool *addr_match,
389 struct tipc_media_addr *maddr) 389 struct tipc_media_addr *maddr)
390 { 390 {
391 struct tipc_link *l = n->links[b->identity].link; 391 struct tipc_link *l = n->links[b->identity].link;
392 struct tipc_media_addr *curr = &n->links[b->identity].maddr; 392 struct tipc_media_addr *curr = &n->links[b->identity].maddr;
393 393
394 *link_up = l && tipc_link_is_up(l); 394 *link_up = l && tipc_link_is_up(l);
395 *addr_match = l && !memcmp(curr, maddr, sizeof(*maddr)); 395 *addr_match = l && !memcmp(curr, maddr, sizeof(*maddr));
396 } 396 }
397 397
398 bool tipc_node_update_dest(struct tipc_node *n, struct tipc_bearer *b, 398 bool tipc_node_update_dest(struct tipc_node *n, struct tipc_bearer *b,
399 struct tipc_media_addr *maddr) 399 struct tipc_media_addr *maddr)
400 { 400 {
401 struct tipc_link *l = n->links[b->identity].link; 401 struct tipc_link *l = n->links[b->identity].link;
402 struct tipc_media_addr *curr = &n->links[b->identity].maddr; 402 struct tipc_media_addr *curr = &n->links[b->identity].maddr;
403 struct sk_buff_head *inputq = &n->links[b->identity].inputq; 403 struct sk_buff_head *inputq = &n->links[b->identity].inputq;
404 404
405 if (!l) { 405 if (!l) {
406 l = tipc_link_create(n, b, maddr, inputq, &n->bclink.namedq); 406 l = tipc_link_create(n, b, maddr, inputq, &n->bclink.namedq);
407 if (!l) 407 if (!l)
408 return false; 408 return false;
409 tipc_node_calculate_timer(n, l); 409 tipc_node_calculate_timer(n, l);
410 if (n->link_cnt == 1) { 410 if (n->link_cnt == 1) {
411 if (!mod_timer(&n->timer, jiffies + n->keepalive_intv)) 411 if (!mod_timer(&n->timer, jiffies + n->keepalive_intv))
412 tipc_node_get(n); 412 tipc_node_get(n);
413 } 413 }
414 } 414 }
415 memcpy(&l->media_addr, maddr, sizeof(*maddr)); 415 memcpy(&l->media_addr, maddr, sizeof(*maddr));
416 memcpy(curr, maddr, sizeof(*maddr)); 416 memcpy(curr, maddr, sizeof(*maddr));
417 tipc_node_link_down(n, b->identity); 417 tipc_node_link_down(n, b->identity);
418 return true; 418 return true;
419 } 419 }
420 420
421 void tipc_node_delete_links(struct net *net, int bearer_id) 421 void tipc_node_delete_links(struct net *net, int bearer_id)
422 { 422 {
423 struct tipc_net *tn = net_generic(net, tipc_net_id); 423 struct tipc_net *tn = net_generic(net, tipc_net_id);
424 struct tipc_link *l; 424 struct tipc_link *l;
425 struct tipc_node *n; 425 struct tipc_node *n;
426 426
427 rcu_read_lock(); 427 rcu_read_lock();
428 list_for_each_entry_rcu(n, &tn->node_list, list) { 428 list_for_each_entry_rcu(n, &tn->node_list, list) {
429 tipc_node_lock(n); 429 tipc_node_lock(n);
430 l = n->links[bearer_id].link; 430 l = n->links[bearer_id].link;
431 if (l) { 431 if (l) {
432 tipc_node_link_down(n, bearer_id); 432 tipc_node_link_down(n, bearer_id);
433 n->links[bearer_id].link = NULL; 433 n->links[bearer_id].link = NULL;
434 n->link_cnt--; 434 n->link_cnt--;
435 } 435 }
436 tipc_node_unlock(n); 436 tipc_node_unlock(n);
437 kfree(l); 437 kfree(l);
438 } 438 }
439 rcu_read_unlock(); 439 rcu_read_unlock();
440 } 440 }
441 441
442 static void tipc_node_reset_links(struct tipc_node *n) 442 static void tipc_node_reset_links(struct tipc_node *n)
443 { 443 {
444 char addr_string[16]; 444 char addr_string[16];
445 u32 i; 445 u32 i;
446 446
447 tipc_node_lock(n); 447 tipc_node_lock(n);
448 448
449 pr_warn("Resetting all links to %s\n", 449 pr_warn("Resetting all links to %s\n",
450 tipc_addr_string_fill(addr_string, n->addr)); 450 tipc_addr_string_fill(addr_string, n->addr));
451 451
452 for (i = 0; i < MAX_BEARERS; i++) { 452 for (i = 0; i < MAX_BEARERS; i++) {
453 if (!n->links[i].link) 453 if (!n->links[i].link)
454 continue; 454 continue;
455 tipc_node_link_down(n, i); 455 tipc_node_link_down(n, i);
456 } 456 }
457 tipc_node_unlock(n); 457 tipc_node_unlock(n);
458 } 458 }
459 459
460 void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr) 460 void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
461 { 461 {
462 n_ptr->links[l_ptr->bearer_id].link = l_ptr; 462 n_ptr->links[l_ptr->bearer_id].link = l_ptr;
463 n_ptr->link_cnt++; 463 n_ptr->link_cnt++;
464 } 464 }
465 465
466 void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr) 466 void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
467 { 467 {
468 int i; 468 int i;
469 469
470 for (i = 0; i < MAX_BEARERS; i++) { 470 for (i = 0; i < MAX_BEARERS; i++) {
471 if (l_ptr != n_ptr->links[i].link) 471 if (l_ptr != n_ptr->links[i].link)
472 continue; 472 continue;
473 n_ptr->links[i].link = NULL; 473 n_ptr->links[i].link = NULL;
474 n_ptr->link_cnt--; 474 n_ptr->link_cnt--;
475 } 475 }
476 } 476 }
477 477
478 /* tipc_node_fsm_evt - node finite state machine 478 /* tipc_node_fsm_evt - node finite state machine
479 * Determines when contact is allowed with peer node 479 * Determines when contact is allowed with peer node
480 */ 480 */
481 static void tipc_node_fsm_evt(struct tipc_node *n, int evt) 481 static void tipc_node_fsm_evt(struct tipc_node *n, int evt)
482 { 482 {
483 int state = n->state; 483 int state = n->state;
484 484
485 switch (state) { 485 switch (state) {
486 case SELF_DOWN_PEER_DOWN: 486 case SELF_DOWN_PEER_DOWN:
487 switch (evt) { 487 switch (evt) {
488 case SELF_ESTABL_CONTACT_EVT: 488 case SELF_ESTABL_CONTACT_EVT:
489 state = SELF_UP_PEER_COMING; 489 state = SELF_UP_PEER_COMING;
490 break; 490 break;
491 case PEER_ESTABL_CONTACT_EVT: 491 case PEER_ESTABL_CONTACT_EVT:
492 state = SELF_COMING_PEER_UP; 492 state = SELF_COMING_PEER_UP;
493 break; 493 break;
494 case SELF_LOST_CONTACT_EVT: 494 case SELF_LOST_CONTACT_EVT:
495 case PEER_LOST_CONTACT_EVT: 495 case PEER_LOST_CONTACT_EVT:
496 break; 496 break;
497 case NODE_SYNCH_END_EVT:
498 case NODE_SYNCH_BEGIN_EVT:
499 case NODE_FAILOVER_BEGIN_EVT:
500 case NODE_FAILOVER_END_EVT:
497 default: 501 default:
498 pr_err("Unknown node fsm evt %x/%x\n", state, evt); 502 goto illegal_evt;
499 } 503 }
500 break; 504 break;
501 case SELF_UP_PEER_UP: 505 case SELF_UP_PEER_UP:
502 switch (evt) { 506 switch (evt) {
503 case SELF_LOST_CONTACT_EVT: 507 case SELF_LOST_CONTACT_EVT:
504 state = SELF_DOWN_PEER_LEAVING; 508 state = SELF_DOWN_PEER_LEAVING;
505 break; 509 break;
506 case PEER_LOST_CONTACT_EVT: 510 case PEER_LOST_CONTACT_EVT:
507 state = SELF_LEAVING_PEER_DOWN; 511 state = SELF_LEAVING_PEER_DOWN;
508 break; 512 break;
513 case NODE_SYNCH_BEGIN_EVT:
514 state = NODE_SYNCHING;
515 break;
516 case NODE_FAILOVER_BEGIN_EVT:
517 state = NODE_FAILINGOVER;
518 break;
509 case SELF_ESTABL_CONTACT_EVT: 519 case SELF_ESTABL_CONTACT_EVT:
510 case PEER_ESTABL_CONTACT_EVT: 520 case PEER_ESTABL_CONTACT_EVT:
521 case NODE_SYNCH_END_EVT:
522 case NODE_FAILOVER_END_EVT:
511 break; 523 break;
512 default: 524 default:
513 pr_err("Unknown node fsm evt %x/%x\n", state, evt); 525 goto illegal_evt;
514 } 526 }
515 break; 527 break;
516 case SELF_DOWN_PEER_LEAVING: 528 case SELF_DOWN_PEER_LEAVING:
517 switch (evt) { 529 switch (evt) {
518 case PEER_LOST_CONTACT_EVT: 530 case PEER_LOST_CONTACT_EVT:
519 state = SELF_DOWN_PEER_DOWN; 531 state = SELF_DOWN_PEER_DOWN;
520 break; 532 break;
521 case SELF_ESTABL_CONTACT_EVT: 533 case SELF_ESTABL_CONTACT_EVT:
522 case PEER_ESTABL_CONTACT_EVT: 534 case PEER_ESTABL_CONTACT_EVT:
523 case SELF_LOST_CONTACT_EVT: 535 case SELF_LOST_CONTACT_EVT:
524 break; 536 break;
537 case NODE_SYNCH_END_EVT:
538 case NODE_SYNCH_BEGIN_EVT:
539 case NODE_FAILOVER_BEGIN_EVT:
540 case NODE_FAILOVER_END_EVT:
525 default: 541 default:
526 pr_err("Unknown node fsm evt %x/%x\n", state, evt); 542 goto illegal_evt;
527 } 543 }
528 break; 544 break;
529 case SELF_UP_PEER_COMING: 545 case SELF_UP_PEER_COMING:
530 switch (evt) { 546 switch (evt) {
531 case PEER_ESTABL_CONTACT_EVT: 547 case PEER_ESTABL_CONTACT_EVT:
532 state = SELF_UP_PEER_UP; 548 state = SELF_UP_PEER_UP;
533 break; 549 break;
534 case SELF_LOST_CONTACT_EVT: 550 case SELF_LOST_CONTACT_EVT:
535 state = SELF_DOWN_PEER_LEAVING; 551 state = SELF_DOWN_PEER_LEAVING;
536 break; 552 break;
537 case SELF_ESTABL_CONTACT_EVT: 553 case SELF_ESTABL_CONTACT_EVT:
538 case PEER_LOST_CONTACT_EVT: 554 case PEER_LOST_CONTACT_EVT:
539 break; 555 break;
556 case NODE_SYNCH_END_EVT:
557 case NODE_SYNCH_BEGIN_EVT:
558 case NODE_FAILOVER_BEGIN_EVT:
559 case NODE_FAILOVER_END_EVT:
540 default: 560 default:
541 pr_err("Unknown node fsm evt %x/%x\n", state, evt); 561 goto illegal_evt;
542 } 562 }
543 break; 563 break;
544 case SELF_COMING_PEER_UP: 564 case SELF_COMING_PEER_UP:
545 switch (evt) { 565 switch (evt) {
546 case SELF_ESTABL_CONTACT_EVT: 566 case SELF_ESTABL_CONTACT_EVT:
547 state = SELF_UP_PEER_UP; 567 state = SELF_UP_PEER_UP;
548 break; 568 break;
549 case PEER_LOST_CONTACT_EVT: 569 case PEER_LOST_CONTACT_EVT:
550 state = SELF_LEAVING_PEER_DOWN; 570 state = SELF_LEAVING_PEER_DOWN;
551 break; 571 break;
552 case SELF_LOST_CONTACT_EVT: 572 case SELF_LOST_CONTACT_EVT:
553 case PEER_ESTABL_CONTACT_EVT: 573 case PEER_ESTABL_CONTACT_EVT:
554 break; 574 break;
575 case NODE_SYNCH_END_EVT:
576 case NODE_SYNCH_BEGIN_EVT:
577 case NODE_FAILOVER_BEGIN_EVT:
578 case NODE_FAILOVER_END_EVT:
555 default: 579 default:
556 pr_err("Unknown node fsm evt %x/%x\n", state, evt); 580 goto illegal_evt;
557 } 581 }
558 break; 582 break;
559 case SELF_LEAVING_PEER_DOWN: 583 case SELF_LEAVING_PEER_DOWN:
560 switch (evt) { 584 switch (evt) {
561 case SELF_LOST_CONTACT_EVT: 585 case SELF_LOST_CONTACT_EVT:
562 state = SELF_DOWN_PEER_DOWN; 586 state = SELF_DOWN_PEER_DOWN;
563 break; 587 break;
564 case SELF_ESTABL_CONTACT_EVT: 588 case SELF_ESTABL_CONTACT_EVT:
565 case PEER_ESTABL_CONTACT_EVT: 589 case PEER_ESTABL_CONTACT_EVT:
566 case PEER_LOST_CONTACT_EVT: 590 case PEER_LOST_CONTACT_EVT:
567 break; 591 break;
592 case NODE_SYNCH_END_EVT:
593 case NODE_SYNCH_BEGIN_EVT:
594 case NODE_FAILOVER_BEGIN_EVT:
595 case NODE_FAILOVER_END_EVT:
568 default: 596 default:
569 pr_err("Unknown node fsm evt %x/%x\n", state, evt); 597 goto illegal_evt;
570 } 598 }
571 break; 599 break;
600 case NODE_FAILINGOVER:
601 switch (evt) {
602 case SELF_LOST_CONTACT_EVT:
603 state = SELF_DOWN_PEER_LEAVING;
604 break;
605 case PEER_LOST_CONTACT_EVT:
606 state = SELF_LEAVING_PEER_DOWN;
607 break;
608 case NODE_FAILOVER_END_EVT:
609 state = SELF_UP_PEER_UP;
610 break;
611 case NODE_FAILOVER_BEGIN_EVT:
612 case SELF_ESTABL_CONTACT_EVT:
613 case PEER_ESTABL_CONTACT_EVT:
614 break;
615 case NODE_SYNCH_BEGIN_EVT:
616 case NODE_SYNCH_END_EVT:
617 default:
618 goto illegal_evt;
619 }
620 break;
621 case NODE_SYNCHING:
622 switch (evt) {
623 case SELF_LOST_CONTACT_EVT:
624 state = SELF_DOWN_PEER_LEAVING;
625 break;
626 case PEER_LOST_CONTACT_EVT:
627 state = SELF_LEAVING_PEER_DOWN;
628 break;
629 case NODE_SYNCH_END_EVT:
630 state = SELF_UP_PEER_UP;
631 break;
632 case NODE_FAILOVER_BEGIN_EVT:
633 state = NODE_FAILINGOVER;
634 break;
635 case NODE_SYNCH_BEGIN_EVT:
636 case SELF_ESTABL_CONTACT_EVT:
637 case PEER_ESTABL_CONTACT_EVT:
638 break;
639 case NODE_FAILOVER_END_EVT:
640 default:
641 goto illegal_evt;
642 }
643 break;
572 default: 644 default:
573 pr_err("Unknown node fsm state %x\n", state); 645 pr_err("Unknown node fsm state %x\n", state);
574 break; 646 break;
575 } 647 }
576
577 n->state = state; 648 n->state = state;
649 return;
650
651 illegal_evt:
652 pr_err("Illegal node fsm evt %x in state %x\n", evt, state);
578 } 653 }
579 654
580 bool tipc_node_filter_skb(struct tipc_node *n, struct tipc_link *l, 655 bool tipc_node_filter_skb(struct tipc_node *n, struct tipc_link *l,
581 struct tipc_msg *hdr) 656 struct tipc_msg *hdr)
582 { 657 {
583 int state = n->state; 658 int state = n->state;
584 659
585 if (likely(state == SELF_UP_PEER_UP)) 660 if (likely(state == SELF_UP_PEER_UP))
586 return true; 661 return true;
587 662
588 if (state == SELF_DOWN_PEER_DOWN) 663 if (state == SELF_DOWN_PEER_DOWN)
589 return true; 664 return true;
590 665
591 if (state == SELF_UP_PEER_COMING) { 666 if (state == SELF_UP_PEER_COMING) {
592 /* If not traffic msg, peer may still be ESTABLISHING */ 667 /* If not traffic msg, peer may still be ESTABLISHING */
593 if (tipc_link_is_up(l) && msg_is_traffic(hdr)) 668 if (tipc_link_is_up(l) && msg_is_traffic(hdr))
594 tipc_node_fsm_evt(n, PEER_ESTABL_CONTACT_EVT); 669 tipc_node_fsm_evt(n, PEER_ESTABL_CONTACT_EVT);
595 return true; 670 return true;
596 } 671 }
597 672
598 if (state == SELF_COMING_PEER_UP) 673 if (state == SELF_COMING_PEER_UP)
599 return true; 674 return true;
600 675
601 if (state == SELF_LEAVING_PEER_DOWN) 676 if (state == SELF_LEAVING_PEER_DOWN)
602 return false; 677 return false;
603 678
604 if (state == SELF_DOWN_PEER_LEAVING) { 679 if (state == SELF_DOWN_PEER_LEAVING) {
605 if (msg_peer_is_up(hdr)) 680 if (msg_peer_is_up(hdr))
606 return false; 681 return false;
607 tipc_node_fsm_evt(n, PEER_LOST_CONTACT_EVT); 682 tipc_node_fsm_evt(n, PEER_LOST_CONTACT_EVT);
608 return true; 683 return true;
609 } 684 }
610 return false; 685 return false;
611 } 686 }
612 687
613 static void node_established_contact(struct tipc_node *n_ptr) 688 static void node_established_contact(struct tipc_node *n_ptr)
614 { 689 {
615 tipc_node_fsm_evt(n_ptr, SELF_ESTABL_CONTACT_EVT); 690 tipc_node_fsm_evt(n_ptr, SELF_ESTABL_CONTACT_EVT);
616 n_ptr->action_flags |= TIPC_NOTIFY_NODE_UP; 691 n_ptr->action_flags |= TIPC_NOTIFY_NODE_UP;
617 n_ptr->bclink.oos_state = 0; 692 n_ptr->bclink.oos_state = 0;
618 n_ptr->bclink.acked = tipc_bclink_get_last_sent(n_ptr->net); 693 n_ptr->bclink.acked = tipc_bclink_get_last_sent(n_ptr->net);
619 tipc_bclink_add_node(n_ptr->net, n_ptr->addr); 694 tipc_bclink_add_node(n_ptr->net, n_ptr->addr);
620 } 695 }
621 696
622 static void node_lost_contact(struct tipc_node *n_ptr) 697 static void node_lost_contact(struct tipc_node *n_ptr)
623 { 698 {
624 char addr_string[16]; 699 char addr_string[16];
625 struct tipc_sock_conn *conn, *safe; 700 struct tipc_sock_conn *conn, *safe;
626 struct list_head *conns = &n_ptr->conn_sks; 701 struct list_head *conns = &n_ptr->conn_sks;
627 struct sk_buff *skb; 702 struct sk_buff *skb;
628 struct tipc_net *tn = net_generic(n_ptr->net, tipc_net_id); 703 struct tipc_net *tn = net_generic(n_ptr->net, tipc_net_id);
629 uint i; 704 uint i;
630 705
631 pr_debug("Lost contact with %s\n", 706 pr_debug("Lost contact with %s\n",
632 tipc_addr_string_fill(addr_string, n_ptr->addr)); 707 tipc_addr_string_fill(addr_string, n_ptr->addr));
633 708
634 /* Flush broadcast link info associated with lost node */ 709 /* Flush broadcast link info associated with lost node */
635 if (n_ptr->bclink.recv_permitted) { 710 if (n_ptr->bclink.recv_permitted) {
636 __skb_queue_purge(&n_ptr->bclink.deferdq); 711 __skb_queue_purge(&n_ptr->bclink.deferdq);
637 712
638 if (n_ptr->bclink.reasm_buf) { 713 if (n_ptr->bclink.reasm_buf) {
639 kfree_skb(n_ptr->bclink.reasm_buf); 714 kfree_skb(n_ptr->bclink.reasm_buf);
640 n_ptr->bclink.reasm_buf = NULL; 715 n_ptr->bclink.reasm_buf = NULL;
641 } 716 }
642 717
643 tipc_bclink_remove_node(n_ptr->net, n_ptr->addr); 718 tipc_bclink_remove_node(n_ptr->net, n_ptr->addr);
644 tipc_bclink_acknowledge(n_ptr, INVALID_LINK_SEQ); 719 tipc_bclink_acknowledge(n_ptr, INVALID_LINK_SEQ);
645 720
646 n_ptr->bclink.recv_permitted = false; 721 n_ptr->bclink.recv_permitted = false;
647 } 722 }
648 723
649 /* Abort any ongoing link failover */ 724 /* Abort any ongoing link failover */
650 for (i = 0; i < MAX_BEARERS; i++) { 725 for (i = 0; i < MAX_BEARERS; i++) {
651 struct tipc_link *l_ptr = n_ptr->links[i].link; 726 struct tipc_link *l_ptr = n_ptr->links[i].link;
652 if (!l_ptr) 727 if (!l_ptr)
653 continue; 728 continue;
654 l_ptr->exec_mode = TIPC_LINK_OPEN; 729 l_ptr->exec_mode = TIPC_LINK_OPEN;
655 l_ptr->failover_checkpt = 0; 730 l_ptr->failover_checkpt = 0;
656 l_ptr->failover_pkts = 0; 731 l_ptr->failover_pkts = 0;
657 kfree_skb(l_ptr->failover_skb); 732 kfree_skb(l_ptr->failover_skb);
658 l_ptr->failover_skb = NULL; 733 l_ptr->failover_skb = NULL;
659 tipc_link_reset_fragments(l_ptr); 734 tipc_link_reset_fragments(l_ptr);
660 } 735 }
661 /* Prevent re-contact with node until cleanup is done */ 736 /* Prevent re-contact with node until cleanup is done */
662 tipc_node_fsm_evt(n_ptr, SELF_LOST_CONTACT_EVT); 737 tipc_node_fsm_evt(n_ptr, SELF_LOST_CONTACT_EVT);
663 738
664 /* Notify publications from this node */ 739 /* Notify publications from this node */
665 n_ptr->action_flags |= TIPC_NOTIFY_NODE_DOWN; 740 n_ptr->action_flags |= TIPC_NOTIFY_NODE_DOWN;
666 741
667 /* Notify sockets connected to node */ 742 /* Notify sockets connected to node */
668 list_for_each_entry_safe(conn, safe, conns, list) { 743 list_for_each_entry_safe(conn, safe, conns, list) {
669 skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG, 744 skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
670 SHORT_H_SIZE, 0, tn->own_addr, 745 SHORT_H_SIZE, 0, tn->own_addr,
671 conn->peer_node, conn->port, 746 conn->peer_node, conn->port,
672 conn->peer_port, TIPC_ERR_NO_NODE); 747 conn->peer_port, TIPC_ERR_NO_NODE);
673 if (likely(skb)) { 748 if (likely(skb)) {
674 skb_queue_tail(n_ptr->inputq, skb); 749 skb_queue_tail(n_ptr->inputq, skb);
675 n_ptr->action_flags |= TIPC_MSG_EVT; 750 n_ptr->action_flags |= TIPC_MSG_EVT;
676 } 751 }
677 list_del(&conn->list); 752 list_del(&conn->list);
678 kfree(conn); 753 kfree(conn);
679 } 754 }
680 } 755 }
681 756
682 /** 757 /**
683 * tipc_node_get_linkname - get the name of a link 758 * tipc_node_get_linkname - get the name of a link
684 * 759 *
685 * @bearer_id: id of the bearer 760 * @bearer_id: id of the bearer
686 * @node: peer node address 761 * @node: peer node address
687 * @linkname: link name output buffer 762 * @linkname: link name output buffer
688 * 763 *
689 * Returns 0 on success 764 * Returns 0 on success
690 */ 765 */
691 int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 addr, 766 int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 addr,
692 char *linkname, size_t len) 767 char *linkname, size_t len)
693 { 768 {
694 struct tipc_link *link; 769 struct tipc_link *link;
695 int err = -EINVAL; 770 int err = -EINVAL;
696 struct tipc_node *node = tipc_node_find(net, addr); 771 struct tipc_node *node = tipc_node_find(net, addr);
697 772
698 if (!node) 773 if (!node)
699 return err; 774 return err;
700 775
701 if (bearer_id >= MAX_BEARERS) 776 if (bearer_id >= MAX_BEARERS)
702 goto exit; 777 goto exit;
703 778
704 tipc_node_lock(node); 779 tipc_node_lock(node);
705 link = node->links[bearer_id].link; 780 link = node->links[bearer_id].link;
706 if (link) { 781 if (link) {
707 strncpy(linkname, link->name, len); 782 strncpy(linkname, link->name, len);
708 err = 0; 783 err = 0;
709 } 784 }
710 exit: 785 exit:
711 tipc_node_unlock(node); 786 tipc_node_unlock(node);
712 tipc_node_put(node); 787 tipc_node_put(node);
713 return err; 788 return err;
714 } 789 }
715 790
716 void tipc_node_unlock(struct tipc_node *node) 791 void tipc_node_unlock(struct tipc_node *node)
717 { 792 {
718 struct net *net = node->net; 793 struct net *net = node->net;
719 u32 addr = 0; 794 u32 addr = 0;
720 u32 flags = node->action_flags; 795 u32 flags = node->action_flags;
721 u32 link_id = 0; 796 u32 link_id = 0;
722 struct list_head *publ_list; 797 struct list_head *publ_list;
723 struct sk_buff_head *inputq = node->inputq; 798 struct sk_buff_head *inputq = node->inputq;
724 struct sk_buff_head *namedq; 799 struct sk_buff_head *namedq;
725 800
726 if (likely(!flags || (flags == TIPC_MSG_EVT))) { 801 if (likely(!flags || (flags == TIPC_MSG_EVT))) {
727 node->action_flags = 0; 802 node->action_flags = 0;
728 spin_unlock_bh(&node->lock); 803 spin_unlock_bh(&node->lock);
729 if (flags == TIPC_MSG_EVT) 804 if (flags == TIPC_MSG_EVT)
730 tipc_sk_rcv(net, inputq); 805 tipc_sk_rcv(net, inputq);
731 return; 806 return;
732 } 807 }
733 808
734 addr = node->addr; 809 addr = node->addr;
735 link_id = node->link_id; 810 link_id = node->link_id;
736 namedq = node->namedq; 811 namedq = node->namedq;
737 publ_list = &node->publ_list; 812 publ_list = &node->publ_list;
738 813
739 node->action_flags &= ~(TIPC_MSG_EVT | 814 node->action_flags &= ~(TIPC_MSG_EVT |
740 TIPC_NOTIFY_NODE_DOWN | TIPC_NOTIFY_NODE_UP | 815 TIPC_NOTIFY_NODE_DOWN | TIPC_NOTIFY_NODE_UP |
741 TIPC_NOTIFY_LINK_DOWN | TIPC_NOTIFY_LINK_UP | 816 TIPC_NOTIFY_LINK_DOWN | TIPC_NOTIFY_LINK_UP |
742 TIPC_WAKEUP_BCAST_USERS | TIPC_BCAST_MSG_EVT | 817 TIPC_WAKEUP_BCAST_USERS | TIPC_BCAST_MSG_EVT |
743 TIPC_NAMED_MSG_EVT | TIPC_BCAST_RESET); 818 TIPC_NAMED_MSG_EVT | TIPC_BCAST_RESET);
744 819
745 spin_unlock_bh(&node->lock); 820 spin_unlock_bh(&node->lock);
746 821
747 if (flags & TIPC_NOTIFY_NODE_DOWN) 822 if (flags & TIPC_NOTIFY_NODE_DOWN)
748 tipc_publ_notify(net, publ_list, addr); 823 tipc_publ_notify(net, publ_list, addr);
749 824
750 if (flags & TIPC_WAKEUP_BCAST_USERS) 825 if (flags & TIPC_WAKEUP_BCAST_USERS)
751 tipc_bclink_wakeup_users(net); 826 tipc_bclink_wakeup_users(net);
752 827
753 if (flags & TIPC_NOTIFY_NODE_UP) 828 if (flags & TIPC_NOTIFY_NODE_UP)
754 tipc_named_node_up(net, addr); 829 tipc_named_node_up(net, addr);
755 830
756 if (flags & TIPC_NOTIFY_LINK_UP) 831 if (flags & TIPC_NOTIFY_LINK_UP)
757 tipc_nametbl_publish(net, TIPC_LINK_STATE, addr, addr, 832 tipc_nametbl_publish(net, TIPC_LINK_STATE, addr, addr,
758 TIPC_NODE_SCOPE, link_id, addr); 833 TIPC_NODE_SCOPE, link_id, addr);
759 834
760 if (flags & TIPC_NOTIFY_LINK_DOWN) 835 if (flags & TIPC_NOTIFY_LINK_DOWN)
761 tipc_nametbl_withdraw(net, TIPC_LINK_STATE, addr, 836 tipc_nametbl_withdraw(net, TIPC_LINK_STATE, addr,
762 link_id, addr); 837 link_id, addr);
763 838
764 if (flags & TIPC_MSG_EVT) 839 if (flags & TIPC_MSG_EVT)
765 tipc_sk_rcv(net, inputq); 840 tipc_sk_rcv(net, inputq);
766 841
767 if (flags & TIPC_NAMED_MSG_EVT) 842 if (flags & TIPC_NAMED_MSG_EVT)
768 tipc_named_rcv(net, namedq); 843 tipc_named_rcv(net, namedq);
769 844
770 if (flags & TIPC_BCAST_MSG_EVT) 845 if (flags & TIPC_BCAST_MSG_EVT)
771 tipc_bclink_input(net); 846 tipc_bclink_input(net);
772 847
773 if (flags & TIPC_BCAST_RESET) 848 if (flags & TIPC_BCAST_RESET)
774 tipc_node_reset_links(node); 849 tipc_node_reset_links(node);
775 } 850 }
776 851
777 /* Caller should hold node lock for the passed node */ 852 /* Caller should hold node lock for the passed node */
778 static int __tipc_nl_add_node(struct tipc_nl_msg *msg, struct tipc_node *node) 853 static int __tipc_nl_add_node(struct tipc_nl_msg *msg, struct tipc_node *node)
779 { 854 {
780 void *hdr; 855 void *hdr;
781 struct nlattr *attrs; 856 struct nlattr *attrs;
782 857
783 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, 858 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
784 NLM_F_MULTI, TIPC_NL_NODE_GET); 859 NLM_F_MULTI, TIPC_NL_NODE_GET);
785 if (!hdr) 860 if (!hdr)
786 return -EMSGSIZE; 861 return -EMSGSIZE;
787 862
788 attrs = nla_nest_start(msg->skb, TIPC_NLA_NODE); 863 attrs = nla_nest_start(msg->skb, TIPC_NLA_NODE);
789 if (!attrs) 864 if (!attrs)
790 goto msg_full; 865 goto msg_full;
791 866
792 if (nla_put_u32(msg->skb, TIPC_NLA_NODE_ADDR, node->addr)) 867 if (nla_put_u32(msg->skb, TIPC_NLA_NODE_ADDR, node->addr))
793 goto attr_msg_full; 868 goto attr_msg_full;
794 if (tipc_node_is_up(node)) 869 if (tipc_node_is_up(node))
795 if (nla_put_flag(msg->skb, TIPC_NLA_NODE_UP)) 870 if (nla_put_flag(msg->skb, TIPC_NLA_NODE_UP))
796 goto attr_msg_full; 871 goto attr_msg_full;
797 872
798 nla_nest_end(msg->skb, attrs); 873 nla_nest_end(msg->skb, attrs);
799 genlmsg_end(msg->skb, hdr); 874 genlmsg_end(msg->skb, hdr);
800 875
801 return 0; 876 return 0;
802 877
803 attr_msg_full: 878 attr_msg_full:
804 nla_nest_cancel(msg->skb, attrs); 879 nla_nest_cancel(msg->skb, attrs);
805 msg_full: 880 msg_full:
806 genlmsg_cancel(msg->skb, hdr); 881 genlmsg_cancel(msg->skb, hdr);
807 882
808 return -EMSGSIZE; 883 return -EMSGSIZE;
809 } 884 }
810 885
811 static struct tipc_link *tipc_node_select_link(struct tipc_node *n, int sel, 886 static struct tipc_link *tipc_node_select_link(struct tipc_node *n, int sel,
812 int *bearer_id, 887 int *bearer_id,
813 struct tipc_media_addr **maddr) 888 struct tipc_media_addr **maddr)
814 { 889 {
815 int id = n->active_links[sel & 1]; 890 int id = n->active_links[sel & 1];
816 891
817 if (unlikely(id < 0)) 892 if (unlikely(id < 0))
818 return NULL; 893 return NULL;
819 894
820 *bearer_id = id; 895 *bearer_id = id;
821 *maddr = &n->links[id].maddr; 896 *maddr = &n->links[id].maddr;
822 return n->links[id].link; 897 return n->links[id].link;
823 } 898 }
824 899
825 /** 900 /**
826 * tipc_node_xmit() is the general link level function for message sending 901 * tipc_node_xmit() is the general link level function for message sending
827 * @net: the applicable net namespace 902 * @net: the applicable net namespace
828 * @list: chain of buffers containing message 903 * @list: chain of buffers containing message
829 * @dnode: address of destination node 904 * @dnode: address of destination node
830 * @selector: a number used for deterministic link selection 905 * @selector: a number used for deterministic link selection
831 * Consumes the buffer chain, except when returning -ELINKCONG 906 * Consumes the buffer chain, except when returning -ELINKCONG
832 * Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE 907 * Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE
833 */ 908 */
834 int tipc_node_xmit(struct net *net, struct sk_buff_head *list, 909 int tipc_node_xmit(struct net *net, struct sk_buff_head *list,
835 u32 dnode, int selector) 910 u32 dnode, int selector)
836 { 911 {
837 struct tipc_link *l = NULL; 912 struct tipc_link *l = NULL;
838 struct tipc_node *n; 913 struct tipc_node *n;
839 struct sk_buff_head xmitq; 914 struct sk_buff_head xmitq;
840 struct tipc_media_addr *maddr; 915 struct tipc_media_addr *maddr;
841 int bearer_id; 916 int bearer_id;
842 int rc = -EHOSTUNREACH; 917 int rc = -EHOSTUNREACH;
843 918
844 __skb_queue_head_init(&xmitq); 919 __skb_queue_head_init(&xmitq);
845 n = tipc_node_find(net, dnode); 920 n = tipc_node_find(net, dnode);
846 if (likely(n)) { 921 if (likely(n)) {
847 tipc_node_lock(n); 922 tipc_node_lock(n);
848 l = tipc_node_select_link(n, selector, &bearer_id, &maddr); 923 l = tipc_node_select_link(n, selector, &bearer_id, &maddr);
849 if (likely(l)) 924 if (likely(l))
850 rc = tipc_link_xmit(l, list, &xmitq); 925 rc = tipc_link_xmit(l, list, &xmitq);
851 if (unlikely(rc == -ENOBUFS)) 926 if (unlikely(rc == -ENOBUFS))
852 tipc_node_link_down(n, bearer_id); 927 tipc_node_link_down(n, bearer_id);
853 tipc_node_unlock(n); 928 tipc_node_unlock(n);
854 tipc_node_put(n); 929 tipc_node_put(n);
855 } 930 }
856 if (likely(!rc)) { 931 if (likely(!rc)) {
857 tipc_bearer_xmit(net, bearer_id, &xmitq, maddr); 932 tipc_bearer_xmit(net, bearer_id, &xmitq, maddr);
858 return 0; 933 return 0;
859 } 934 }
860 if (likely(in_own_node(net, dnode))) { 935 if (likely(in_own_node(net, dnode))) {
861 tipc_sk_rcv(net, list); 936 tipc_sk_rcv(net, list);
862 return 0; 937 return 0;
863 } 938 }
864 return rc; 939 return rc;
865 } 940 }
866 941
867 /* tipc_node_xmit_skb(): send single buffer to destination 942 /* tipc_node_xmit_skb(): send single buffer to destination
868 * Buffers sent via this functon are generally TIPC_SYSTEM_IMPORTANCE 943 * Buffers sent via this functon are generally TIPC_SYSTEM_IMPORTANCE
869 * messages, which will not be rejected 944 * messages, which will not be rejected
870 * The only exception is datagram messages rerouted after secondary 945 * The only exception is datagram messages rerouted after secondary
871 * lookup, which are rare and safe to dispose of anyway. 946 * lookup, which are rare and safe to dispose of anyway.
872 * TODO: Return real return value, and let callers use 947 * TODO: Return real return value, and let callers use
873 * tipc_wait_for_sendpkt() where applicable 948 * tipc_wait_for_sendpkt() where applicable
874 */ 949 */
875 int tipc_node_xmit_skb(struct net *net, struct sk_buff *skb, u32 dnode, 950 int tipc_node_xmit_skb(struct net *net, struct sk_buff *skb, u32 dnode,
876 u32 selector) 951 u32 selector)
877 { 952 {
878 struct sk_buff_head head; 953 struct sk_buff_head head;
879 int rc; 954 int rc;
880 955
881 skb_queue_head_init(&head); 956 skb_queue_head_init(&head);
882 __skb_queue_tail(&head, skb); 957 __skb_queue_tail(&head, skb);
883 rc = tipc_node_xmit(net, &head, dnode, selector); 958 rc = tipc_node_xmit(net, &head, dnode, selector);
884 if (rc == -ELINKCONG) 959 if (rc == -ELINKCONG)
885 kfree_skb(skb); 960 kfree_skb(skb);
886 return 0; 961 return 0;
887 } 962 }
888 963
889 /* tipc_node_tnl_init(): handle a received TUNNEL_PROTOCOL packet, 964 /* tipc_node_tnl_init(): handle a received TUNNEL_PROTOCOL packet,
890 * in order to control parallel link failover or synchronization 965 * in order to control parallel link failover or synchronization
891 */ 966 */
892 static void tipc_node_tnl_init(struct tipc_node *n, int bearer_id, 967 static void tipc_node_tnl_init(struct tipc_node *n, int bearer_id,
893 struct sk_buff *skb) 968 struct sk_buff *skb)
894 { 969 {
895 struct tipc_link *tnl, *pl; 970 struct tipc_link *tnl, *pl;
896 struct tipc_msg *hdr = buf_msg(skb); 971 struct tipc_msg *hdr = buf_msg(skb);
897 u16 oseqno = msg_seqno(hdr); 972 u16 oseqno = msg_seqno(hdr);
898 int pb_id = msg_bearer_id(hdr); 973 int pb_id = msg_bearer_id(hdr);
899 974
900 if (pb_id >= MAX_BEARERS) 975 if (pb_id >= MAX_BEARERS)
901 return; 976 return;
902 977
903 tnl = n->links[bearer_id].link; 978 tnl = n->links[bearer_id].link;
904 if (!tnl) 979 if (!tnl)
905 return; 980 return;
906 981
907 /* Ignore if duplicate */ 982 /* Ignore if duplicate */
908 if (less(oseqno, tnl->rcv_nxt)) 983 if (less(oseqno, tnl->rcv_nxt))
909 return; 984 return;
910 985
911 pl = n->links[pb_id].link; 986 pl = n->links[pb_id].link;
912 if (!pl) 987 if (!pl)
913 return; 988 return;
914 989
915 if (msg_type(hdr) == FAILOVER_MSG) { 990 if (msg_type(hdr) == FAILOVER_MSG) {
916 if (tipc_link_is_up(pl)) { 991 if (tipc_link_is_up(pl)) {
917 tipc_node_link_down(n, pb_id); 992 tipc_node_link_down(n, pb_id);
918 pl->exec_mode = TIPC_LINK_BLOCKED; 993 pl->exec_mode = TIPC_LINK_BLOCKED;
919 } 994 }
920 } 995 }
921 } 996 }
922 997
923 /** 998 /**
924 * tipc_rcv - process TIPC packets/messages arriving from off-node 999 * tipc_rcv - process TIPC packets/messages arriving from off-node
925 * @net: the applicable net namespace 1000 * @net: the applicable net namespace
926 * @skb: TIPC packet 1001 * @skb: TIPC packet
927 * @bearer: pointer to bearer message arrived on 1002 * @bearer: pointer to bearer message arrived on
928 * 1003 *
929 * Invoked with no locks held. Bearer pointer must point to a valid bearer 1004 * Invoked with no locks held. Bearer pointer must point to a valid bearer
930 * structure (i.e. cannot be NULL), but bearer can be inactive. 1005 * structure (i.e. cannot be NULL), but bearer can be inactive.
931 */ 1006 */
932 void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) 1007 void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b)
933 { 1008 {
934 struct sk_buff_head xmitq; 1009 struct sk_buff_head xmitq;
935 struct tipc_node *n; 1010 struct tipc_node *n;
936 struct tipc_link *l; 1011 struct tipc_link *l;
937 struct tipc_msg *hdr; 1012 struct tipc_msg *hdr;
938 struct tipc_media_addr *maddr; 1013 struct tipc_media_addr *maddr;
939 int bearer_id = b->identity; 1014 int bearer_id = b->identity;
940 int rc = 0; 1015 int rc = 0;
941 int usr; 1016 int usr;
942 1017
943 __skb_queue_head_init(&xmitq); 1018 __skb_queue_head_init(&xmitq);
944 1019
945 /* Ensure message is well-formed */ 1020 /* Ensure message is well-formed */
946 if (unlikely(!tipc_msg_validate(skb))) 1021 if (unlikely(!tipc_msg_validate(skb)))
947 goto discard; 1022 goto discard;
948 1023
949 /* Handle arrival of a non-unicast link packet */ 1024 /* Handle arrival of a non-unicast link packet */
950 hdr = buf_msg(skb); 1025 hdr = buf_msg(skb);
951 usr = msg_user(hdr); 1026 usr = msg_user(hdr);
952 if (unlikely(msg_non_seq(hdr))) { 1027 if (unlikely(msg_non_seq(hdr))) {
953 if (usr == LINK_CONFIG) 1028 if (usr == LINK_CONFIG)
954 tipc_disc_rcv(net, skb, b); 1029 tipc_disc_rcv(net, skb, b);
955 else 1030 else
956 tipc_bclink_rcv(net, skb); 1031 tipc_bclink_rcv(net, skb);
957 return; 1032 return;
958 } 1033 }
959 1034
960 /* Locate neighboring node that sent packet */ 1035 /* Locate neighboring node that sent packet */
961 n = tipc_node_find(net, msg_prevnode(hdr)); 1036 n = tipc_node_find(net, msg_prevnode(hdr));
962 if (unlikely(!n)) 1037 if (unlikely(!n))
963 goto discard; 1038 goto discard;
964 tipc_node_lock(n); 1039 tipc_node_lock(n);
965 1040
966 /* Prepare links for tunneled reception if applicable */ 1041 /* Prepare links for tunneled reception if applicable */
967 if (unlikely(usr == TUNNEL_PROTOCOL)) 1042 if (unlikely(usr == TUNNEL_PROTOCOL))
968 tipc_node_tnl_init(n, bearer_id, skb); 1043 tipc_node_tnl_init(n, bearer_id, skb);
969 1044
970 /* Locate link endpoint that should handle packet */ 1045 /* Locate link endpoint that should handle packet */
971 l = n->links[bearer_id].link; 1046 l = n->links[bearer_id].link;
972 if (unlikely(!l)) 1047 if (unlikely(!l))
973 goto unlock; 1048 goto unlock;
974 1049
975 /* Is reception of this packet permitted at the moment ? */ 1050 /* Is reception of this packet permitted at the moment ? */
976 if (unlikely(n->state != SELF_UP_PEER_UP)) 1051 if (unlikely(n->state != SELF_UP_PEER_UP))
977 if (!tipc_node_filter_skb(n, l, hdr)) 1052 if (!tipc_node_filter_skb(n, l, hdr))
978 goto unlock; 1053 goto unlock;
979 1054
980 if (unlikely(usr == LINK_PROTOCOL)) 1055 if (unlikely(usr == LINK_PROTOCOL))
981 tipc_bclink_sync_state(n, hdr); 1056 tipc_bclink_sync_state(n, hdr);
982 1057
983 /* Release acked broadcast messages */ 1058 /* Release acked broadcast messages */
984 if (unlikely(n->bclink.acked != msg_bcast_ack(hdr))) 1059 if (unlikely(n->bclink.acked != msg_bcast_ack(hdr)))
985 tipc_bclink_acknowledge(n, msg_bcast_ack(hdr)); 1060 tipc_bclink_acknowledge(n, msg_bcast_ack(hdr));
986 1061
987 /* Check protocol and update link state */ 1062 /* Check protocol and update link state */
988 rc = tipc_link_rcv(l, skb, &xmitq); 1063 rc = tipc_link_rcv(l, skb, &xmitq);
989 1064
990 if (unlikely(rc & TIPC_LINK_UP_EVT)) 1065 if (unlikely(rc & TIPC_LINK_UP_EVT))
991 tipc_node_link_up(n, bearer_id); 1066 tipc_node_link_up(n, bearer_id);
992 if (unlikely(rc & TIPC_LINK_DOWN_EVT)) 1067 if (unlikely(rc & TIPC_LINK_DOWN_EVT))
993 tipc_node_link_down(n, bearer_id); 1068 tipc_node_link_down(n, bearer_id);
994 skb = NULL; 1069 skb = NULL;
995 unlock: 1070 unlock:
996 tipc_node_unlock(n); 1071 tipc_node_unlock(n);
997 tipc_sk_rcv(net, &n->links[bearer_id].inputq); 1072 tipc_sk_rcv(net, &n->links[bearer_id].inputq);
998 maddr = &n->links[bearer_id].maddr; 1073 maddr = &n->links[bearer_id].maddr;
999 tipc_bearer_xmit(net, bearer_id, &xmitq, maddr); 1074 tipc_bearer_xmit(net, bearer_id, &xmitq, maddr);
1000 tipc_node_put(n); 1075 tipc_node_put(n);
1001 discard: 1076 discard:
1002 kfree_skb(skb); 1077 kfree_skb(skb);
1003 } 1078 }
1004 1079
1005 int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb) 1080 int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb)
1006 { 1081 {
1007 int err; 1082 int err;
1008 struct net *net = sock_net(skb->sk); 1083 struct net *net = sock_net(skb->sk);
1009 struct tipc_net *tn = net_generic(net, tipc_net_id); 1084 struct tipc_net *tn = net_generic(net, tipc_net_id);
1010 int done = cb->args[0]; 1085 int done = cb->args[0];
1011 int last_addr = cb->args[1]; 1086 int last_addr = cb->args[1];
1012 struct tipc_node *node; 1087 struct tipc_node *node;
1013 struct tipc_nl_msg msg; 1088 struct tipc_nl_msg msg;
1014 1089
1015 if (done) 1090 if (done)
1016 return 0; 1091 return 0;
1017 1092
1018 msg.skb = skb; 1093 msg.skb = skb;
1019 msg.portid = NETLINK_CB(cb->skb).portid; 1094 msg.portid = NETLINK_CB(cb->skb).portid;
1020 msg.seq = cb->nlh->nlmsg_seq; 1095 msg.seq = cb->nlh->nlmsg_seq;
1021 1096
1022 rcu_read_lock(); 1097 rcu_read_lock();
1023 if (last_addr) { 1098 if (last_addr) {
1024 node = tipc_node_find(net, last_addr); 1099 node = tipc_node_find(net, last_addr);
1025 if (!node) { 1100 if (!node) {
1026 rcu_read_unlock(); 1101 rcu_read_unlock();
1027 /* We never set seq or call nl_dump_check_consistent() 1102 /* We never set seq or call nl_dump_check_consistent()
1028 * this means that setting prev_seq here will cause the 1103 * this means that setting prev_seq here will cause the
1029 * consistence check to fail in the netlink callback 1104 * consistence check to fail in the netlink callback
1030 * handler. Resulting in the NLMSG_DONE message having 1105 * handler. Resulting in the NLMSG_DONE message having
1031 * the NLM_F_DUMP_INTR flag set if the node state 1106 * the NLM_F_DUMP_INTR flag set if the node state
1032 * changed while we released the lock. 1107 * changed while we released the lock.
1033 */ 1108 */
1034 cb->prev_seq = 1; 1109 cb->prev_seq = 1;
1035 return -EPIPE; 1110 return -EPIPE;
1036 } 1111 }
1037 tipc_node_put(node); 1112 tipc_node_put(node);
1038 } 1113 }
1039 1114
1040 list_for_each_entry_rcu(node, &tn->node_list, list) { 1115 list_for_each_entry_rcu(node, &tn->node_list, list) {
1041 if (last_addr) { 1116 if (last_addr) {
1042 if (node->addr == last_addr) 1117 if (node->addr == last_addr)
1043 last_addr = 0; 1118 last_addr = 0;
1044 else 1119 else
1045 continue; 1120 continue;
1046 } 1121 }
1047 1122
1048 tipc_node_lock(node); 1123 tipc_node_lock(node);
1049 err = __tipc_nl_add_node(&msg, node); 1124 err = __tipc_nl_add_node(&msg, node);
1050 if (err) { 1125 if (err) {
1051 last_addr = node->addr; 1126 last_addr = node->addr;
1052 tipc_node_unlock(node); 1127 tipc_node_unlock(node);
1053 goto out; 1128 goto out;
1054 } 1129 }
1055 1130
1056 tipc_node_unlock(node); 1131 tipc_node_unlock(node);
1057 } 1132 }
1058 done = 1; 1133 done = 1;
1059 out: 1134 out:
1060 cb->args[0] = done; 1135 cb->args[0] = done;
1061 cb->args[1] = last_addr; 1136 cb->args[1] = last_addr;
1062 rcu_read_unlock(); 1137 rcu_read_unlock();
1063 1138
1064 return skb->len; 1139 return skb->len;
1065 } 1140 }
1 /* 1 /*
2 * net/tipc/node.h: Include file for TIPC node management routines 2 * net/tipc/node.h: Include file for TIPC node management routines
3 * 3 *
4 * Copyright (c) 2000-2006, 2014-2015, Ericsson AB 4 * Copyright (c) 2000-2006, 2014-2015, Ericsson AB
5 * Copyright (c) 2005, 2010-2014, Wind River Systems 5 * Copyright (c) 2005, 2010-2014, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met: 9 * modification, are permitted provided that the following conditions are met:
10 * 10 *
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the names of the copyright holders nor the names of its 16 * 3. Neither the names of the copyright holders nor the names of its
17 * contributors may be used to endorse or promote products derived from 17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission. 18 * this software without specific prior written permission.
19 * 19 *
20 * Alternatively, this software may be distributed under the terms of the 20 * Alternatively, this software may be distributed under the terms of the
21 * GNU General Public License ("GPL") version 2 as published by the Free 21 * GNU General Public License ("GPL") version 2 as published by the Free
22 * Software Foundation. 22 * Software Foundation.
23 * 23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37 #ifndef _TIPC_NODE_H 37 #ifndef _TIPC_NODE_H
38 #define _TIPC_NODE_H 38 #define _TIPC_NODE_H
39 39
40 #include "addr.h" 40 #include "addr.h"
41 #include "net.h" 41 #include "net.h"
42 #include "bearer.h" 42 #include "bearer.h"
43 #include "msg.h" 43 #include "msg.h"
44 44
45 /* Out-of-range value for node signature */ 45 /* Out-of-range value for node signature */
46 #define INVALID_NODE_SIG 0x10000 46 #define INVALID_NODE_SIG 0x10000
47 47
48 #define INVALID_BEARER_ID -1 48 #define INVALID_BEARER_ID -1
49 49
50 /* Node FSM states and events: 50 /* Node FSM states and events:
51 */ 51 */
52 enum { 52 enum {
53 SELF_DOWN_PEER_DOWN = 0xdd, 53 SELF_DOWN_PEER_DOWN = 0xdd,
54 SELF_UP_PEER_UP = 0xaa, 54 SELF_UP_PEER_UP = 0xaa,
55 SELF_DOWN_PEER_LEAVING = 0xd1, 55 SELF_DOWN_PEER_LEAVING = 0xd1,
56 SELF_UP_PEER_COMING = 0xac, 56 SELF_UP_PEER_COMING = 0xac,
57 SELF_COMING_PEER_UP = 0xca, 57 SELF_COMING_PEER_UP = 0xca,
58 SELF_LEAVING_PEER_DOWN = 0x1d, 58 SELF_LEAVING_PEER_DOWN = 0x1d,
59 NODE_FAILINGOVER = 0xf0,
60 NODE_SYNCHING = 0xcc
59 }; 61 };
60 62
61 enum { 63 enum {
62 SELF_ESTABL_CONTACT_EVT = 0xec, 64 SELF_ESTABL_CONTACT_EVT = 0xece,
63 SELF_LOST_CONTACT_EVT = 0x1c, 65 SELF_LOST_CONTACT_EVT = 0x1ce,
64 PEER_ESTABL_CONTACT_EVT = 0xfec, 66 PEER_ESTABL_CONTACT_EVT = 0xfece,
65 PEER_LOST_CONTACT_EVT = 0xf1c 67 PEER_LOST_CONTACT_EVT = 0xf1ce,
68 NODE_FAILOVER_BEGIN_EVT = 0xfbe,
69 NODE_FAILOVER_END_EVT = 0xfee,
70 NODE_SYNCH_BEGIN_EVT = 0xcbe,
71 NODE_SYNCH_END_EVT = 0xcee
66 }; 72 };
67 73
68 /* Flags used to take different actions according to flag type 74 /* Flags used to take different actions according to flag type
69 * TIPC_WAIT_PEER_LINKS_DOWN: wait to see that peer's links are down 75 * TIPC_WAIT_PEER_LINKS_DOWN: wait to see that peer's links are down
70 * TIPC_WAIT_OWN_LINKS_DOWN: wait until peer node is declared down 76 * TIPC_WAIT_OWN_LINKS_DOWN: wait until peer node is declared down
71 * TIPC_NOTIFY_NODE_DOWN: notify node is down 77 * TIPC_NOTIFY_NODE_DOWN: notify node is down
72 * TIPC_NOTIFY_NODE_UP: notify node is up 78 * TIPC_NOTIFY_NODE_UP: notify node is up
73 * TIPC_DISTRIBUTE_NAME: publish or withdraw link state name type 79 * TIPC_DISTRIBUTE_NAME: publish or withdraw link state name type
74 */ 80 */
75 enum { 81 enum {
76 TIPC_MSG_EVT = 1, 82 TIPC_MSG_EVT = 1,
77 TIPC_NOTIFY_NODE_DOWN = (1 << 3), 83 TIPC_NOTIFY_NODE_DOWN = (1 << 3),
78 TIPC_NOTIFY_NODE_UP = (1 << 4), 84 TIPC_NOTIFY_NODE_UP = (1 << 4),
79 TIPC_WAKEUP_BCAST_USERS = (1 << 5), 85 TIPC_WAKEUP_BCAST_USERS = (1 << 5),
80 TIPC_NOTIFY_LINK_UP = (1 << 6), 86 TIPC_NOTIFY_LINK_UP = (1 << 6),
81 TIPC_NOTIFY_LINK_DOWN = (1 << 7), 87 TIPC_NOTIFY_LINK_DOWN = (1 << 7),
82 TIPC_NAMED_MSG_EVT = (1 << 8), 88 TIPC_NAMED_MSG_EVT = (1 << 8),
83 TIPC_BCAST_MSG_EVT = (1 << 9), 89 TIPC_BCAST_MSG_EVT = (1 << 9),
84 TIPC_BCAST_RESET = (1 << 10) 90 TIPC_BCAST_RESET = (1 << 10)
85 }; 91 };
86 92
87 /** 93 /**
88 * struct tipc_node_bclink - TIPC node bclink structure 94 * struct tipc_node_bclink - TIPC node bclink structure
89 * @acked: sequence # of last outbound b'cast message acknowledged by node 95 * @acked: sequence # of last outbound b'cast message acknowledged by node
90 * @last_in: sequence # of last in-sequence b'cast message received from node 96 * @last_in: sequence # of last in-sequence b'cast message received from node
91 * @last_sent: sequence # of last b'cast message sent by node 97 * @last_sent: sequence # of last b'cast message sent by node
92 * @oos_state: state tracker for handling OOS b'cast messages 98 * @oos_state: state tracker for handling OOS b'cast messages
93 * @deferred_queue: deferred queue saved OOS b'cast message received from node 99 * @deferred_queue: deferred queue saved OOS b'cast message received from node
94 * @reasm_buf: broadcast reassembly queue head from node 100 * @reasm_buf: broadcast reassembly queue head from node
95 * @inputq_map: bitmap indicating which inqueues should be kicked 101 * @inputq_map: bitmap indicating which inqueues should be kicked
96 * @recv_permitted: true if node is allowed to receive b'cast messages 102 * @recv_permitted: true if node is allowed to receive b'cast messages
97 */ 103 */
98 struct tipc_node_bclink { 104 struct tipc_node_bclink {
99 u32 acked; 105 u32 acked;
100 u32 last_in; 106 u32 last_in;
101 u32 last_sent; 107 u32 last_sent;
102 u32 oos_state; 108 u32 oos_state;
103 u32 deferred_size; 109 u32 deferred_size;
104 struct sk_buff_head deferdq; 110 struct sk_buff_head deferdq;
105 struct sk_buff *reasm_buf; 111 struct sk_buff *reasm_buf;
106 struct sk_buff_head namedq; 112 struct sk_buff_head namedq;
107 bool recv_permitted; 113 bool recv_permitted;
108 }; 114 };
109 115
110 struct tipc_link_entry { 116 struct tipc_link_entry {
111 struct tipc_link *link; 117 struct tipc_link *link;
112 u32 mtu; 118 u32 mtu;
113 struct sk_buff_head inputq; 119 struct sk_buff_head inputq;
114 struct tipc_media_addr maddr; 120 struct tipc_media_addr maddr;
115 }; 121 };
116 122
117 /** 123 /**
118 * struct tipc_node - TIPC node structure 124 * struct tipc_node - TIPC node structure
119 * @addr: network address of node 125 * @addr: network address of node
120 * @ref: reference counter to node object 126 * @ref: reference counter to node object
121 * @lock: spinlock governing access to structure 127 * @lock: spinlock governing access to structure
122 * @net: the applicable net namespace 128 * @net: the applicable net namespace
123 * @hash: links to adjacent nodes in unsorted hash chain 129 * @hash: links to adjacent nodes in unsorted hash chain
124 * @inputq: pointer to input queue containing messages for msg event 130 * @inputq: pointer to input queue containing messages for msg event
125 * @namedq: pointer to name table input queue with name table messages 131 * @namedq: pointer to name table input queue with name table messages
126 * @active_links: bearer ids of active links, used as index into links[] array 132 * @active_links: bearer ids of active links, used as index into links[] array
127 * @links: array containing references to all links to node 133 * @links: array containing references to all links to node
128 * @action_flags: bit mask of different types of node actions 134 * @action_flags: bit mask of different types of node actions
129 * @bclink: broadcast-related info 135 * @bclink: broadcast-related info
130 * @list: links to adjacent nodes in sorted list of cluster's nodes 136 * @list: links to adjacent nodes in sorted list of cluster's nodes
131 * @working_links: number of working links to node (both active and standby) 137 * @working_links: number of working links to node (both active and standby)
132 * @link_cnt: number of links to node 138 * @link_cnt: number of links to node
133 * @capabilities: bitmap, indicating peer node's functional capabilities 139 * @capabilities: bitmap, indicating peer node's functional capabilities
134 * @signature: node instance identifier 140 * @signature: node instance identifier
135 * @link_id: local and remote bearer ids of changing link, if any 141 * @link_id: local and remote bearer ids of changing link, if any
136 * @publ_list: list of publications 142 * @publ_list: list of publications
137 * @rcu: rcu struct for tipc_node 143 * @rcu: rcu struct for tipc_node
138 */ 144 */
139 struct tipc_node { 145 struct tipc_node {
140 u32 addr; 146 u32 addr;
141 struct kref kref; 147 struct kref kref;
142 spinlock_t lock; 148 spinlock_t lock;
143 struct net *net; 149 struct net *net;
144 struct hlist_node hash; 150 struct hlist_node hash;
145 struct sk_buff_head *inputq; 151 struct sk_buff_head *inputq;
146 struct sk_buff_head *namedq; 152 struct sk_buff_head *namedq;
147 int active_links[2]; 153 int active_links[2];
148 struct tipc_link_entry links[MAX_BEARERS]; 154 struct tipc_link_entry links[MAX_BEARERS];
149 int action_flags; 155 int action_flags;
150 struct tipc_node_bclink bclink; 156 struct tipc_node_bclink bclink;
151 struct list_head list; 157 struct list_head list;
152 int state; 158 int state;
153 int link_cnt; 159 int link_cnt;
154 u16 working_links; 160 u16 working_links;
155 u16 capabilities; 161 u16 capabilities;
156 u32 signature; 162 u32 signature;
157 u32 link_id; 163 u32 link_id;
158 struct list_head publ_list; 164 struct list_head publ_list;
159 struct list_head conn_sks; 165 struct list_head conn_sks;
160 unsigned long keepalive_intv; 166 unsigned long keepalive_intv;
161 struct timer_list timer; 167 struct timer_list timer;
162 struct rcu_head rcu; 168 struct rcu_head rcu;
163 }; 169 };
164 170
165 struct tipc_node *tipc_node_find(struct net *net, u32 addr); 171 struct tipc_node *tipc_node_find(struct net *net, u32 addr);
166 void tipc_node_put(struct tipc_node *node); 172 void tipc_node_put(struct tipc_node *node);
167 struct tipc_node *tipc_node_create(struct net *net, u32 addr); 173 struct tipc_node *tipc_node_create(struct net *net, u32 addr);
168 void tipc_node_stop(struct net *net); 174 void tipc_node_stop(struct net *net);
169 void tipc_node_check_dest(struct tipc_node *n, struct tipc_bearer *bearer, 175 void tipc_node_check_dest(struct tipc_node *n, struct tipc_bearer *bearer,
170 bool *link_up, bool *addr_match, 176 bool *link_up, bool *addr_match,
171 struct tipc_media_addr *maddr); 177 struct tipc_media_addr *maddr);
172 bool tipc_node_update_dest(struct tipc_node *n, struct tipc_bearer *bearer, 178 bool tipc_node_update_dest(struct tipc_node *n, struct tipc_bearer *bearer,
173 struct tipc_media_addr *maddr); 179 struct tipc_media_addr *maddr);
174 void tipc_node_delete_links(struct net *net, int bearer_id); 180 void tipc_node_delete_links(struct net *net, int bearer_id);
175 void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr); 181 void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr);
176 void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr); 182 void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr);
177 void tipc_node_link_down(struct tipc_node *n_ptr, int bearer_id); 183 void tipc_node_link_down(struct tipc_node *n_ptr, int bearer_id);
178 void tipc_node_link_up(struct tipc_node *n_ptr, int bearer_id); 184 void tipc_node_link_up(struct tipc_node *n_ptr, int bearer_id);
179 bool tipc_node_is_up(struct tipc_node *n); 185 bool tipc_node_is_up(struct tipc_node *n);
180 int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 node, 186 int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 node,
181 char *linkname, size_t len); 187 char *linkname, size_t len);
182 void tipc_node_unlock(struct tipc_node *node); 188 void tipc_node_unlock(struct tipc_node *node);
183 int tipc_node_xmit(struct net *net, struct sk_buff_head *list, u32 dnode, 189 int tipc_node_xmit(struct net *net, struct sk_buff_head *list, u32 dnode,
184 int selector); 190 int selector);
185 int tipc_node_xmit_skb(struct net *net, struct sk_buff *skb, u32 dest, 191 int tipc_node_xmit_skb(struct net *net, struct sk_buff *skb, u32 dest,
186 u32 selector); 192 u32 selector);
187 int tipc_node_add_conn(struct net *net, u32 dnode, u32 port, u32 peer_port); 193 int tipc_node_add_conn(struct net *net, u32 dnode, u32 port, u32 peer_port);
188 void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port); 194 void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port);
189 int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb); 195 int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb);
190 196
191 static inline void tipc_node_lock(struct tipc_node *node) 197 static inline void tipc_node_lock(struct tipc_node *node)
192 { 198 {
193 spin_lock_bh(&node->lock); 199 spin_lock_bh(&node->lock);
194 } 200 }
195 201
196 static inline struct tipc_link *node_active_link(struct tipc_node *n, int sel) 202 static inline struct tipc_link *node_active_link(struct tipc_node *n, int sel)
197 { 203 {
198 int bearer_id = n->active_links[sel & 1]; 204 int bearer_id = n->active_links[sel & 1];
199 205
200 if (unlikely(bearer_id == INVALID_BEARER_ID)) 206 if (unlikely(bearer_id == INVALID_BEARER_ID))
201 return NULL; 207 return NULL;
202 208
203 return n->links[bearer_id].link; 209 return n->links[bearer_id].link;
204 } 210 }
205 211
206 static inline unsigned int tipc_node_get_mtu(struct net *net, u32 addr, u32 sel) 212 static inline unsigned int tipc_node_get_mtu(struct net *net, u32 addr, u32 sel)
207 { 213 {
208 struct tipc_node *n; 214 struct tipc_node *n;
209 int bearer_id; 215 int bearer_id;
210 unsigned int mtu = MAX_MSG_SIZE; 216 unsigned int mtu = MAX_MSG_SIZE;
211 217
212 n = tipc_node_find(net, addr); 218 n = tipc_node_find(net, addr);
213 if (unlikely(!n)) 219 if (unlikely(!n))
214 return mtu; 220 return mtu;
215 221
216 bearer_id = n->active_links[sel & 1]; 222 bearer_id = n->active_links[sel & 1];
217 if (likely(bearer_id != INVALID_BEARER_ID)) 223 if (likely(bearer_id != INVALID_BEARER_ID))
218 mtu = n->links[bearer_id].mtu; 224 mtu = n->links[bearer_id].mtu;
219 tipc_node_put(n); 225 tipc_node_put(n);
220 return mtu; 226 return mtu;
221 } 227 }
222 228
223 #endif 229 #endif
224 230