]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - net/tipc/node.c
tipc: move received discovery data evaluation inside node.c
[mirror_ubuntu-jammy-kernel.git] / net / tipc / node.c
CommitLineData
b97bf3fd
PL
1/*
2 * net/tipc/node.c: TIPC node management routines
c4307285 3 *
dd3f9e70 4 * Copyright (c) 2000-2006, 2012-2015, Ericsson AB
46651c59 5 * Copyright (c) 2005-2006, 2010-2014, Wind River Systems
b97bf3fd
PL
6 * All rights reserved.
7 *
9ea1fd3c 8 * Redistribution and use in source and binary forms, with or without
b97bf3fd
PL
9 * modification, are permitted provided that the following conditions are met:
10 *
9ea1fd3c
PL
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
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
18 * this software without specific prior written permission.
b97bf3fd 19 *
9ea1fd3c
PL
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
22 * Software Foundation.
23 *
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
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
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
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
b97bf3fd
PL
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#include "core.h"
22ae7cff 38#include "link.h"
b97bf3fd 39#include "node.h"
b97bf3fd 40#include "name_distr.h"
50100a5e 41#include "socket.h"
a6bf70f7 42#include "bcast.h"
d999297c 43#include "discover.h"
b97bf3fd 44
6e498158
JPM
45/* Node FSM states and events:
46 */
47enum {
48 SELF_DOWN_PEER_DOWN = 0xdd,
49 SELF_UP_PEER_UP = 0xaa,
50 SELF_DOWN_PEER_LEAVING = 0xd1,
51 SELF_UP_PEER_COMING = 0xac,
52 SELF_COMING_PEER_UP = 0xca,
53 SELF_LEAVING_PEER_DOWN = 0x1d,
54 NODE_FAILINGOVER = 0xf0,
55 NODE_SYNCHING = 0xcc
56};
57
58enum {
59 SELF_ESTABL_CONTACT_EVT = 0xece,
60 SELF_LOST_CONTACT_EVT = 0x1ce,
61 PEER_ESTABL_CONTACT_EVT = 0x9ece,
62 PEER_LOST_CONTACT_EVT = 0x91ce,
63 NODE_FAILOVER_BEGIN_EVT = 0xfbe,
64 NODE_FAILOVER_END_EVT = 0xfee,
65 NODE_SYNCH_BEGIN_EVT = 0xcbe,
66 NODE_SYNCH_END_EVT = 0xcee
67};
68
69static void tipc_node_link_down(struct tipc_node *n, int bearer_id);
6c00055a
DM
70static void node_lost_contact(struct tipc_node *n_ptr);
71static void node_established_contact(struct tipc_node *n_ptr);
8a0f6ebe 72static void tipc_node_delete(struct tipc_node *node);
8a1577c9 73static void tipc_node_timeout(unsigned long data);
d999297c 74static void tipc_node_fsm_evt(struct tipc_node *n, int evt);
b97bf3fd 75
02be61a9
JPM
76struct tipc_sock_conn {
77 u32 port;
78 u32 peer_port;
79 u32 peer_node;
80 struct list_head list;
81};
82
3e4b6ab5
RA
83static const struct nla_policy tipc_nl_node_policy[TIPC_NLA_NODE_MAX + 1] = {
84 [TIPC_NLA_NODE_UNSPEC] = { .type = NLA_UNSPEC },
85 [TIPC_NLA_NODE_ADDR] = { .type = NLA_U32 },
86 [TIPC_NLA_NODE_UP] = { .type = NLA_FLAG }
87};
88
a635b46b
AS
89/*
90 * A trivial power-of-two bitmask technique is used for speed, since this
91 * operation is done for every incoming TIPC packet. The number of hash table
92 * entries has been chosen so that no hash chain exceeds 8 nodes and will
93 * usually be much smaller (typically only a single node).
94 */
872f24db 95static unsigned int tipc_hashfn(u32 addr)
a635b46b
AS
96{
97 return addr & (NODE_HTABLE_SIZE - 1);
98}
99
8a0f6ebe
YX
100static void tipc_node_kref_release(struct kref *kref)
101{
102 struct tipc_node *node = container_of(kref, struct tipc_node, kref);
103
104 tipc_node_delete(node);
105}
106
107void tipc_node_put(struct tipc_node *node)
108{
109 kref_put(&node->kref, tipc_node_kref_release);
110}
111
112static void tipc_node_get(struct tipc_node *node)
113{
114 kref_get(&node->kref);
115}
116
1ec2bb08 117/*
672d99e1
AS
118 * tipc_node_find - locate specified node object, if it exists
119 */
f2f9800d 120struct tipc_node *tipc_node_find(struct net *net, u32 addr)
672d99e1 121{
f2f9800d 122 struct tipc_net *tn = net_generic(net, tipc_net_id);
672d99e1 123 struct tipc_node *node;
672d99e1 124
34747539 125 if (unlikely(!in_own_cluster_exact(net, addr)))
672d99e1
AS
126 return NULL;
127
6c7a762e 128 rcu_read_lock();
f2f9800d
YX
129 hlist_for_each_entry_rcu(node, &tn->node_htable[tipc_hashfn(addr)],
130 hash) {
46651c59 131 if (node->addr == addr) {
8a0f6ebe 132 tipc_node_get(node);
6c7a762e 133 rcu_read_unlock();
672d99e1 134 return node;
46651c59 135 }
672d99e1 136 }
6c7a762e 137 rcu_read_unlock();
672d99e1
AS
138 return NULL;
139}
140
cf148816 141struct tipc_node *tipc_node_create(struct net *net, u32 addr, u16 capabilities)
b97bf3fd 142{
f2f9800d 143 struct tipc_net *tn = net_generic(net, tipc_net_id);
672d99e1 144 struct tipc_node *n_ptr, *temp_node;
b97bf3fd 145
f2f9800d 146 spin_lock_bh(&tn->node_list_lock);
b45db71b
JPM
147 n_ptr = tipc_node_find(net, addr);
148 if (n_ptr)
149 goto exit;
5af54792 150 n_ptr = kzalloc(sizeof(*n_ptr), GFP_ATOMIC);
a10bd924 151 if (!n_ptr) {
2cf8aa19 152 pr_warn("Node creation failed, no memory\n");
b45db71b 153 goto exit;
a10bd924 154 }
a10bd924 155 n_ptr->addr = addr;
f2f9800d 156 n_ptr->net = net;
cf148816 157 n_ptr->capabilities = capabilities;
8a0f6ebe 158 kref_init(&n_ptr->kref);
51a8e4de 159 spin_lock_init(&n_ptr->lock);
672d99e1
AS
160 INIT_HLIST_NODE(&n_ptr->hash);
161 INIT_LIST_HEAD(&n_ptr->list);
a8f48af5 162 INIT_LIST_HEAD(&n_ptr->publ_list);
02be61a9 163 INIT_LIST_HEAD(&n_ptr->conn_sks);
d39bbd44 164 skb_queue_head_init(&n_ptr->bclink.namedq);
05dcc5aa 165 __skb_queue_head_init(&n_ptr->bclink.deferdq);
f2f9800d 166 hlist_add_head_rcu(&n_ptr->hash, &tn->node_htable[tipc_hashfn(addr)]);
f2f9800d 167 list_for_each_entry_rcu(temp_node, &tn->node_list, list) {
672d99e1
AS
168 if (n_ptr->addr < temp_node->addr)
169 break;
170 }
6c7a762e 171 list_add_tail_rcu(&n_ptr->list, &temp_node->list);
d999297c 172 n_ptr->state = SELF_DOWN_PEER_LEAVING;
fc0eea69 173 n_ptr->signature = INVALID_NODE_SIG;
36e78a46
JPM
174 n_ptr->active_links[0] = INVALID_BEARER_ID;
175 n_ptr->active_links[1] = INVALID_BEARER_ID;
8a0f6ebe 176 tipc_node_get(n_ptr);
8a1577c9
JPM
177 setup_timer(&n_ptr->timer, tipc_node_timeout, (unsigned long)n_ptr);
178 n_ptr->keepalive_intv = U32_MAX;
b45db71b 179exit:
f2f9800d 180 spin_unlock_bh(&tn->node_list_lock);
b97bf3fd
PL
181 return n_ptr;
182}
183
8a1577c9
JPM
184static void tipc_node_calculate_timer(struct tipc_node *n, struct tipc_link *l)
185{
186 unsigned long tol = l->tolerance;
187 unsigned long intv = ((tol / 4) > 500) ? 500 : tol / 4;
188 unsigned long keepalive_intv = msecs_to_jiffies(intv);
189
190 /* Link with lowest tolerance determines timer interval */
191 if (keepalive_intv < n->keepalive_intv)
192 n->keepalive_intv = keepalive_intv;
193
194 /* Ensure link's abort limit corresponds to current interval */
195 l->abort_limit = l->tolerance / jiffies_to_msecs(n->keepalive_intv);
196}
197
8a0f6ebe 198static void tipc_node_delete(struct tipc_node *node)
b97bf3fd 199{
8a0f6ebe
YX
200 list_del_rcu(&node->list);
201 hlist_del_rcu(&node->hash);
202 kfree_rcu(node, rcu);
b97bf3fd
PL
203}
204
f2f9800d 205void tipc_node_stop(struct net *net)
46651c59 206{
f2f9800d 207 struct tipc_net *tn = net_generic(net, tipc_net_id);
46651c59
YX
208 struct tipc_node *node, *t_node;
209
f2f9800d 210 spin_lock_bh(&tn->node_list_lock);
8a1577c9
JPM
211 list_for_each_entry_safe(node, t_node, &tn->node_list, list) {
212 if (del_timer(&node->timer))
213 tipc_node_put(node);
8a0f6ebe 214 tipc_node_put(node);
8a1577c9 215 }
f2f9800d 216 spin_unlock_bh(&tn->node_list_lock);
46651c59
YX
217}
218
f2f9800d 219int tipc_node_add_conn(struct net *net, u32 dnode, u32 port, u32 peer_port)
02be61a9
JPM
220{
221 struct tipc_node *node;
222 struct tipc_sock_conn *conn;
8a0f6ebe 223 int err = 0;
02be61a9 224
34747539 225 if (in_own_node(net, dnode))
02be61a9
JPM
226 return 0;
227
f2f9800d 228 node = tipc_node_find(net, dnode);
02be61a9
JPM
229 if (!node) {
230 pr_warn("Connecting sock to node 0x%x failed\n", dnode);
231 return -EHOSTUNREACH;
232 }
233 conn = kmalloc(sizeof(*conn), GFP_ATOMIC);
8a0f6ebe
YX
234 if (!conn) {
235 err = -EHOSTUNREACH;
236 goto exit;
237 }
02be61a9
JPM
238 conn->peer_node = dnode;
239 conn->port = port;
240 conn->peer_port = peer_port;
241
242 tipc_node_lock(node);
243 list_add_tail(&conn->list, &node->conn_sks);
244 tipc_node_unlock(node);
8a0f6ebe
YX
245exit:
246 tipc_node_put(node);
247 return err;
02be61a9
JPM
248}
249
f2f9800d 250void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port)
02be61a9
JPM
251{
252 struct tipc_node *node;
253 struct tipc_sock_conn *conn, *safe;
254
34747539 255 if (in_own_node(net, dnode))
02be61a9
JPM
256 return;
257
f2f9800d 258 node = tipc_node_find(net, dnode);
02be61a9
JPM
259 if (!node)
260 return;
261
262 tipc_node_lock(node);
263 list_for_each_entry_safe(conn, safe, &node->conn_sks, list) {
264 if (port != conn->port)
265 continue;
266 list_del(&conn->list);
267 kfree(conn);
268 }
269 tipc_node_unlock(node);
8a0f6ebe 270 tipc_node_put(node);
02be61a9
JPM
271}
272
8a1577c9
JPM
273/* tipc_node_timeout - handle expiration of node timer
274 */
275static void tipc_node_timeout(unsigned long data)
276{
277 struct tipc_node *n = (struct tipc_node *)data;
278 struct sk_buff_head xmitq;
279 struct tipc_link *l;
280 struct tipc_media_addr *maddr;
281 int bearer_id;
282 int rc = 0;
283
284 __skb_queue_head_init(&xmitq);
285
286 for (bearer_id = 0; bearer_id < MAX_BEARERS; bearer_id++) {
287 tipc_node_lock(n);
288 l = n->links[bearer_id].link;
289 if (l) {
290 /* Link tolerance may change asynchronously: */
291 tipc_node_calculate_timer(n, l);
292 rc = tipc_link_timeout(l, &xmitq);
293 if (rc & TIPC_LINK_DOWN_EVT)
655fb243 294 tipc_node_link_down(n, bearer_id);
8a1577c9
JPM
295 }
296 tipc_node_unlock(n);
297 maddr = &n->links[bearer_id].maddr;
298 tipc_bearer_xmit(n->net, bearer_id, &xmitq, maddr);
299 }
300 if (!mod_timer(&n->timer, jiffies + n->keepalive_intv))
301 tipc_node_get(n);
302 tipc_node_put(n);
303}
304
b97bf3fd 305/**
4323add6 306 * tipc_node_link_up - handle addition of link
c4307285 307 *
b97bf3fd
PL
308 * Link becomes active (alone or shared) or standby, depending on its priority.
309 */
6e498158
JPM
310static void tipc_node_link_up(struct tipc_node *n, int bearer_id,
311 struct sk_buff_head *xmitq)
b97bf3fd 312{
36e78a46
JPM
313 int *slot0 = &n->active_links[0];
314 int *slot1 = &n->active_links[1];
6e498158
JPM
315 struct tipc_link *ol = node_active_link(n, 0);
316 struct tipc_link *nl = n->links[bearer_id].link;
9d13ec65 317
6e498158
JPM
318 if (n->working_links > 1) {
319 pr_warn("Attempt to establish 3rd link to %x\n", n->addr);
320 return;
321 }
9d13ec65
JPM
322 n->working_links++;
323 n->action_flags |= TIPC_NOTIFY_LINK_UP;
6e498158
JPM
324 n->link_id = nl->peer_bearer_id << 16 | bearer_id;
325
326 /* Leave room for tunnel header when returning 'mtu' to users: */
327 n->links[bearer_id].mtu = nl->mtu - INT_H_SIZE;
7b8613e0 328
cbeb83ca
JPM
329 tipc_bearer_add_dest(n->net, bearer_id, n->addr);
330
3fa9cacd 331 pr_debug("Established link <%s> on network plane %c\n",
6e498158 332 nl->name, nl->net_plane);
c4307285 333
6e498158
JPM
334 /* First link? => give it both slots */
335 if (!ol) {
36e78a46
JPM
336 *slot0 = bearer_id;
337 *slot1 = bearer_id;
5045f7b9 338 tipc_link_build_bcast_sync_msg(nl, xmitq);
9d13ec65
JPM
339 node_established_contact(n);
340 return;
b97bf3fd 341 }
36e78a46 342
6e498158
JPM
343 /* Second link => redistribute slots */
344 if (nl->priority > ol->priority) {
345 pr_debug("Old link <%s> becomes standby\n", ol->name);
36e78a46 346 *slot0 = bearer_id;
6e498158
JPM
347 *slot1 = bearer_id;
348 } else if (nl->priority == ol->priority) {
349 *slot0 = bearer_id;
350 } else {
351 pr_debug("New link <%s> is standby\n", nl->name);
b97bf3fd 352 }
b97bf3fd 353
6e498158
JPM
354 /* Prepare synchronization with first link */
355 tipc_link_tnl_prepare(ol, nl, SYNCH_MSG, xmitq);
b97bf3fd
PL
356}
357
358/**
4323add6 359 * tipc_node_link_down - handle loss of link
b97bf3fd 360 */
6e498158 361static void tipc_node_link_down(struct tipc_node *n, int bearer_id)
b97bf3fd 362{
36e78a46
JPM
363 int *slot0 = &n->active_links[0];
364 int *slot1 = &n->active_links[1];
6e498158 365 struct tipc_media_addr *maddr = &n->links[bearer_id].maddr;
36e78a46 366 int i, highest = 0;
6e498158
JPM
367 struct tipc_link *l, *_l, *tnl;
368 struct sk_buff_head xmitq;
b97bf3fd 369
36e78a46 370 l = n->links[bearer_id].link;
662921cd 371 if (!l || tipc_link_is_reset(l))
655fb243
JPM
372 return;
373
6e498158
JPM
374 __skb_queue_head_init(&xmitq);
375
9d13ec65
JPM
376 n->working_links--;
377 n->action_flags |= TIPC_NOTIFY_LINK_DOWN;
6e498158 378 n->link_id = l->peer_bearer_id << 16 | bearer_id;
5392d646 379
655fb243
JPM
380 tipc_bearer_remove_dest(n->net, l->bearer_id, n->addr);
381
3fa9cacd 382 pr_debug("Lost link <%s> on network plane %c\n",
9d13ec65 383 l->name, l->net_plane);
16e166b8 384
36e78a46
JPM
385 /* Select new active link if any available */
386 *slot0 = INVALID_BEARER_ID;
387 *slot1 = INVALID_BEARER_ID;
388 for (i = 0; i < MAX_BEARERS; i++) {
389 _l = n->links[i].link;
390 if (!_l || !tipc_link_is_up(_l))
391 continue;
655fb243
JPM
392 if (_l == l)
393 continue;
36e78a46
JPM
394 if (_l->priority < highest)
395 continue;
396 if (_l->priority > highest) {
397 highest = _l->priority;
398 *slot0 = i;
399 *slot1 = i;
400 continue;
401 }
402 *slot1 = i;
403 }
655fb243 404
6e498158
JPM
405 if (!tipc_node_is_up(n)) {
406 tipc_link_reset(l);
407 node_lost_contact(n);
408 return;
409 }
655fb243 410
6e498158
JPM
411 /* There is still a working link => initiate failover */
412 tnl = node_active_link(n, 0);
413 tipc_node_fsm_evt(n, NODE_FAILOVER_BEGIN_EVT);
414 n->sync_point = tnl->rcv_nxt + (U16_MAX / 2 - 1);
415 tipc_link_tnl_prepare(l, tnl, FAILOVER_MSG, &xmitq);
655fb243 416 tipc_link_reset(l);
662921cd 417 tipc_link_fsm_evt(l, LINK_FAILOVER_BEGIN_EVT);
6e498158 418 tipc_bearer_xmit(n->net, tnl->bearer_id, &xmitq, maddr);
b97bf3fd
PL
419}
420
9d13ec65 421bool tipc_node_is_up(struct tipc_node *n)
b97bf3fd 422{
36e78a46 423 return n->active_links[0] != INVALID_BEARER_ID;
b97bf3fd
PL
424}
425
cf148816
JPM
426void tipc_node_check_dest(struct net *net, u32 onode,
427 struct tipc_bearer *b,
428 u16 capabilities, u32 signature,
429 struct tipc_media_addr *maddr,
430 bool *respond, bool *dupl_addr)
d3a43b90 431{
cf148816
JPM
432 struct tipc_node *n;
433 struct tipc_link *l;
434 struct tipc_media_addr *curr_maddr;
435 struct sk_buff_head *inputq;
436 bool addr_match = false;
437 bool sign_match = false;
438 bool link_up = false;
439 bool accept_addr = false;
440
441 *dupl_addr = false;
442 *respond = false;
443
444 n = tipc_node_create(net, onode, capabilities);
445 if (!n)
446 return;
d3a43b90 447
cf148816
JPM
448 tipc_node_lock(n);
449
450 curr_maddr = &n->links[b->identity].maddr;
451 inputq = &n->links[b->identity].inputq;
452
453 /* Prepare to validate requesting node's signature and media address */
454 l = n->links[b->identity].link;
455 link_up = l && tipc_link_is_up(l);
456 addr_match = l && !memcmp(curr_maddr, maddr, sizeof(*maddr));
457 sign_match = (signature == n->signature);
458
459 /* These three flags give us eight permutations: */
460
461 if (sign_match && addr_match && link_up) {
462 /* All is fine. Do nothing. */
463 } else if (sign_match && addr_match && !link_up) {
464 /* Respond. The link will come up in due time */
465 *respond = true;
466 } else if (sign_match && !addr_match && link_up) {
467 /* Peer has changed i/f address without rebooting.
468 * If so, the link will reset soon, and the next
469 * discovery will be accepted. So we can ignore it.
470 * It may also be an cloned or malicious peer having
471 * chosen the same node address and signature as an
472 * existing one.
473 * Ignore requests until the link goes down, if ever.
474 */
475 *dupl_addr = true;
476 } else if (sign_match && !addr_match && !link_up) {
477 /* Peer link has changed i/f address without rebooting.
478 * It may also be a cloned or malicious peer; we can't
479 * distinguish between the two.
480 * The signature is correct, so we must accept.
481 */
482 accept_addr = true;
483 *respond = true;
484 } else if (!sign_match && addr_match && link_up) {
485 /* Peer node rebooted. Two possibilities:
486 * - Delayed re-discovery; this link endpoint has already
487 * reset and re-established contact with the peer, before
488 * receiving a discovery message from that node.
489 * (The peer happened to receive one from this node first).
490 * - The peer came back so fast that our side has not
491 * discovered it yet. Probing from this side will soon
492 * reset the link, since there can be no working link
493 * endpoint at the peer end, and the link will re-establish.
494 * Accept the signature, since it comes from a known peer.
495 */
496 n->signature = signature;
497 } else if (!sign_match && addr_match && !link_up) {
498 /* The peer node has rebooted.
499 * Accept signature, since it is a known peer.
500 */
501 n->signature = signature;
502 *respond = true;
503 } else if (!sign_match && !addr_match && link_up) {
504 /* Peer rebooted with new address, or a new/duplicate peer.
505 * Ignore until the link goes down, if ever.
506 */
507 *dupl_addr = true;
508 } else if (!sign_match && !addr_match && !link_up) {
509 /* Peer rebooted with new address, or it is a new peer.
510 * Accept signature and address.
511 */
512 n->signature = signature;
513 accept_addr = true;
514 *respond = true;
515 }
d3a43b90 516
cf148816
JPM
517 if (!accept_addr)
518 goto exit;
d3a43b90 519
cf148816 520 /* Now create new link if not already existing */
8a1577c9 521 if (!l) {
d39bbd44 522 l = tipc_link_create(n, b, maddr, inputq, &n->bclink.namedq);
cf148816
JPM
523 if (!l) {
524 *respond = false;
525 goto exit;
526 }
8a1577c9 527 tipc_node_calculate_timer(n, l);
cf148816 528 if (n->link_cnt == 1)
8a1577c9
JPM
529 if (!mod_timer(&n->timer, jiffies + n->keepalive_intv))
530 tipc_node_get(n);
8a1577c9 531 }
d3a43b90 532 memcpy(&l->media_addr, maddr, sizeof(*maddr));
cf148816 533 memcpy(curr_maddr, maddr, sizeof(*maddr));
655fb243 534 tipc_node_link_down(n, b->identity);
cf148816
JPM
535exit:
536 tipc_node_unlock(n);
537 tipc_node_put(n);
d3a43b90
JPM
538}
539
6144a996
JPM
540void tipc_node_delete_links(struct net *net, int bearer_id)
541{
542 struct tipc_net *tn = net_generic(net, tipc_net_id);
543 struct tipc_link *l;
544 struct tipc_node *n;
545
546 rcu_read_lock();
547 list_for_each_entry_rcu(n, &tn->node_list, list) {
548 tipc_node_lock(n);
549 l = n->links[bearer_id].link;
550 if (l) {
655fb243 551 tipc_node_link_down(n, bearer_id);
6144a996
JPM
552 n->links[bearer_id].link = NULL;
553 n->link_cnt--;
554 }
555 tipc_node_unlock(n);
556 kfree(l);
557 }
558 rcu_read_unlock();
559}
560
561static void tipc_node_reset_links(struct tipc_node *n)
562{
563 char addr_string[16];
564 u32 i;
565
566 tipc_node_lock(n);
567
568 pr_warn("Resetting all links to %s\n",
569 tipc_addr_string_fill(addr_string, n->addr));
570
571 for (i = 0; i < MAX_BEARERS; i++) {
655fb243
JPM
572 if (!n->links[i].link)
573 continue;
574 tipc_node_link_down(n, i);
6144a996
JPM
575 }
576 tipc_node_unlock(n);
577}
578
a18c4bc3 579void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
b97bf3fd 580{
9d13ec65 581 n_ptr->links[l_ptr->bearer_id].link = l_ptr;
37b9c08a 582 n_ptr->link_cnt++;
b97bf3fd
PL
583}
584
a18c4bc3 585void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
b97bf3fd 586{
7d33939f
JPM
587 int i;
588
589 for (i = 0; i < MAX_BEARERS; i++) {
9d13ec65 590 if (l_ptr != n_ptr->links[i].link)
074bb43e 591 continue;
9d13ec65 592 n_ptr->links[i].link = NULL;
074bb43e 593 n_ptr->link_cnt--;
7d33939f 594 }
b97bf3fd
PL
595}
596
1a20cc25
JPM
597/* tipc_node_fsm_evt - node finite state machine
598 * Determines when contact is allowed with peer node
599 */
d999297c 600static void tipc_node_fsm_evt(struct tipc_node *n, int evt)
1a20cc25
JPM
601{
602 int state = n->state;
603
604 switch (state) {
605 case SELF_DOWN_PEER_DOWN:
606 switch (evt) {
607 case SELF_ESTABL_CONTACT_EVT:
608 state = SELF_UP_PEER_COMING;
609 break;
610 case PEER_ESTABL_CONTACT_EVT:
611 state = SELF_COMING_PEER_UP;
612 break;
613 case SELF_LOST_CONTACT_EVT:
614 case PEER_LOST_CONTACT_EVT:
615 break;
66996b6c
JPM
616 case NODE_SYNCH_END_EVT:
617 case NODE_SYNCH_BEGIN_EVT:
618 case NODE_FAILOVER_BEGIN_EVT:
619 case NODE_FAILOVER_END_EVT:
1a20cc25 620 default:
66996b6c 621 goto illegal_evt;
1a20cc25
JPM
622 }
623 break;
624 case SELF_UP_PEER_UP:
625 switch (evt) {
626 case SELF_LOST_CONTACT_EVT:
627 state = SELF_DOWN_PEER_LEAVING;
628 break;
629 case PEER_LOST_CONTACT_EVT:
630 state = SELF_LEAVING_PEER_DOWN;
631 break;
66996b6c
JPM
632 case NODE_SYNCH_BEGIN_EVT:
633 state = NODE_SYNCHING;
634 break;
635 case NODE_FAILOVER_BEGIN_EVT:
636 state = NODE_FAILINGOVER;
637 break;
1a20cc25
JPM
638 case SELF_ESTABL_CONTACT_EVT:
639 case PEER_ESTABL_CONTACT_EVT:
66996b6c
JPM
640 case NODE_SYNCH_END_EVT:
641 case NODE_FAILOVER_END_EVT:
1a20cc25
JPM
642 break;
643 default:
66996b6c 644 goto illegal_evt;
1a20cc25
JPM
645 }
646 break;
647 case SELF_DOWN_PEER_LEAVING:
648 switch (evt) {
649 case PEER_LOST_CONTACT_EVT:
650 state = SELF_DOWN_PEER_DOWN;
651 break;
652 case SELF_ESTABL_CONTACT_EVT:
653 case PEER_ESTABL_CONTACT_EVT:
654 case SELF_LOST_CONTACT_EVT:
655 break;
66996b6c
JPM
656 case NODE_SYNCH_END_EVT:
657 case NODE_SYNCH_BEGIN_EVT:
658 case NODE_FAILOVER_BEGIN_EVT:
659 case NODE_FAILOVER_END_EVT:
1a20cc25 660 default:
66996b6c 661 goto illegal_evt;
1a20cc25
JPM
662 }
663 break;
664 case SELF_UP_PEER_COMING:
665 switch (evt) {
666 case PEER_ESTABL_CONTACT_EVT:
667 state = SELF_UP_PEER_UP;
668 break;
669 case SELF_LOST_CONTACT_EVT:
670 state = SELF_DOWN_PEER_LEAVING;
671 break;
672 case SELF_ESTABL_CONTACT_EVT:
673 case PEER_LOST_CONTACT_EVT:
674 break;
66996b6c
JPM
675 case NODE_SYNCH_END_EVT:
676 case NODE_SYNCH_BEGIN_EVT:
677 case NODE_FAILOVER_BEGIN_EVT:
678 case NODE_FAILOVER_END_EVT:
1a20cc25 679 default:
66996b6c 680 goto illegal_evt;
1a20cc25
JPM
681 }
682 break;
683 case SELF_COMING_PEER_UP:
684 switch (evt) {
685 case SELF_ESTABL_CONTACT_EVT:
686 state = SELF_UP_PEER_UP;
687 break;
688 case PEER_LOST_CONTACT_EVT:
689 state = SELF_LEAVING_PEER_DOWN;
690 break;
691 case SELF_LOST_CONTACT_EVT:
692 case PEER_ESTABL_CONTACT_EVT:
693 break;
66996b6c
JPM
694 case NODE_SYNCH_END_EVT:
695 case NODE_SYNCH_BEGIN_EVT:
696 case NODE_FAILOVER_BEGIN_EVT:
697 case NODE_FAILOVER_END_EVT:
1a20cc25 698 default:
66996b6c 699 goto illegal_evt;
1a20cc25
JPM
700 }
701 break;
702 case SELF_LEAVING_PEER_DOWN:
703 switch (evt) {
704 case SELF_LOST_CONTACT_EVT:
705 state = SELF_DOWN_PEER_DOWN;
706 break;
707 case SELF_ESTABL_CONTACT_EVT:
708 case PEER_ESTABL_CONTACT_EVT:
709 case PEER_LOST_CONTACT_EVT:
710 break;
66996b6c
JPM
711 case NODE_SYNCH_END_EVT:
712 case NODE_SYNCH_BEGIN_EVT:
713 case NODE_FAILOVER_BEGIN_EVT:
714 case NODE_FAILOVER_END_EVT:
715 default:
716 goto illegal_evt;
717 }
718 break;
719 case NODE_FAILINGOVER:
720 switch (evt) {
721 case SELF_LOST_CONTACT_EVT:
722 state = SELF_DOWN_PEER_LEAVING;
723 break;
724 case PEER_LOST_CONTACT_EVT:
725 state = SELF_LEAVING_PEER_DOWN;
726 break;
727 case NODE_FAILOVER_END_EVT:
728 state = SELF_UP_PEER_UP;
729 break;
730 case NODE_FAILOVER_BEGIN_EVT:
731 case SELF_ESTABL_CONTACT_EVT:
732 case PEER_ESTABL_CONTACT_EVT:
733 break;
734 case NODE_SYNCH_BEGIN_EVT:
735 case NODE_SYNCH_END_EVT:
1a20cc25 736 default:
66996b6c
JPM
737 goto illegal_evt;
738 }
739 break;
740 case NODE_SYNCHING:
741 switch (evt) {
742 case SELF_LOST_CONTACT_EVT:
743 state = SELF_DOWN_PEER_LEAVING;
744 break;
745 case PEER_LOST_CONTACT_EVT:
746 state = SELF_LEAVING_PEER_DOWN;
747 break;
748 case NODE_SYNCH_END_EVT:
749 state = SELF_UP_PEER_UP;
750 break;
751 case NODE_FAILOVER_BEGIN_EVT:
752 state = NODE_FAILINGOVER;
753 break;
754 case NODE_SYNCH_BEGIN_EVT:
755 case SELF_ESTABL_CONTACT_EVT:
756 case PEER_ESTABL_CONTACT_EVT:
757 break;
758 case NODE_FAILOVER_END_EVT:
759 default:
760 goto illegal_evt;
1a20cc25
JPM
761 }
762 break;
763 default:
764 pr_err("Unknown node fsm state %x\n", state);
765 break;
766 }
1a20cc25 767 n->state = state;
66996b6c
JPM
768 return;
769
770illegal_evt:
771 pr_err("Illegal node fsm evt %x in state %x\n", evt, state);
1a20cc25
JPM
772}
773
6e498158 774bool tipc_node_filter_pkt(struct tipc_node *n, struct tipc_msg *hdr)
1a20cc25
JPM
775{
776 int state = n->state;
777
778 if (likely(state == SELF_UP_PEER_UP))
779 return true;
d999297c 780
1a20cc25
JPM
781 if (state == SELF_LEAVING_PEER_DOWN)
782 return false;
d999297c
JPM
783
784 if (state == SELF_DOWN_PEER_LEAVING) {
6e498158 785 if (msg_peer_node_is_up(hdr))
d999297c 786 return false;
d999297c 787 }
6e498158
JPM
788
789 return true;
1a20cc25
JPM
790}
791
6c00055a 792static void node_established_contact(struct tipc_node *n_ptr)
b97bf3fd 793{
1a20cc25 794 tipc_node_fsm_evt(n_ptr, SELF_ESTABL_CONTACT_EVT);
aecb9bb8 795 n_ptr->action_flags |= TIPC_NOTIFY_NODE_UP;
c64f7a6a 796 n_ptr->bclink.oos_state = 0;
1da46568
YX
797 n_ptr->bclink.acked = tipc_bclink_get_last_sent(n_ptr->net);
798 tipc_bclink_add_node(n_ptr->net, n_ptr->addr);
b97bf3fd
PL
799}
800
6c00055a 801static void node_lost_contact(struct tipc_node *n_ptr)
b97bf3fd 802{
b97bf3fd 803 char addr_string[16];
708ac32c
JPM
804 struct tipc_sock_conn *conn, *safe;
805 struct list_head *conns = &n_ptr->conn_sks;
806 struct sk_buff *skb;
807 struct tipc_net *tn = net_generic(n_ptr->net, tipc_net_id);
808 uint i;
b97bf3fd 809
3fa9cacd
EH
810 pr_debug("Lost contact with %s\n",
811 tipc_addr_string_fill(addr_string, n_ptr->addr));
c5bd4d85
AS
812
813 /* Flush broadcast link info associated with lost node */
389dd9bc 814 if (n_ptr->bclink.recv_permitted) {
05dcc5aa 815 __skb_queue_purge(&n_ptr->bclink.deferdq);
c5bd4d85 816
37e22164
JPM
817 if (n_ptr->bclink.reasm_buf) {
818 kfree_skb(n_ptr->bclink.reasm_buf);
819 n_ptr->bclink.reasm_buf = NULL;
c5bd4d85
AS
820 }
821
1da46568 822 tipc_bclink_remove_node(n_ptr->net, n_ptr->addr);
36559591 823 tipc_bclink_acknowledge(n_ptr, INVALID_LINK_SEQ);
b97bf3fd 824
389dd9bc 825 n_ptr->bclink.recv_permitted = false;
c5bd4d85 826 }
b97bf3fd 827
dff29b1a 828 /* Abort any ongoing link failover */
b97bf3fd 829 for (i = 0; i < MAX_BEARERS; i++) {
9d13ec65 830 struct tipc_link *l_ptr = n_ptr->links[i].link;
c4307285 831 if (!l_ptr)
b97bf3fd 832 continue;
662921cd 833 tipc_link_fsm_evt(l_ptr, LINK_FAILOVER_END_EVT);
6e498158
JPM
834 kfree_skb(l_ptr->failover_reasm_skb);
835 l_ptr->failover_reasm_skb = NULL;
4323add6 836 tipc_link_reset_fragments(l_ptr);
b97bf3fd 837 }
708ac32c 838 /* Prevent re-contact with node until cleanup is done */
1a20cc25 839 tipc_node_fsm_evt(n_ptr, SELF_LOST_CONTACT_EVT);
708ac32c
JPM
840
841 /* Notify publications from this node */
842 n_ptr->action_flags |= TIPC_NOTIFY_NODE_DOWN;
843
844 /* Notify sockets connected to node */
845 list_for_each_entry_safe(conn, safe, conns, list) {
846 skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
847 SHORT_H_SIZE, 0, tn->own_addr,
848 conn->peer_node, conn->port,
849 conn->peer_port, TIPC_ERR_NO_NODE);
850 if (likely(skb)) {
851 skb_queue_tail(n_ptr->inputq, skb);
852 n_ptr->action_flags |= TIPC_MSG_EVT;
853 }
854 list_del(&conn->list);
855 kfree(conn);
856 }
b97bf3fd
PL
857}
858
78acb1f9
EH
859/**
860 * tipc_node_get_linkname - get the name of a link
861 *
862 * @bearer_id: id of the bearer
863 * @node: peer node address
864 * @linkname: link name output buffer
865 *
866 * Returns 0 on success
867 */
f2f9800d
YX
868int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 addr,
869 char *linkname, size_t len)
78acb1f9
EH
870{
871 struct tipc_link *link;
8a0f6ebe 872 int err = -EINVAL;
f2f9800d 873 struct tipc_node *node = tipc_node_find(net, addr);
78acb1f9 874
8a0f6ebe
YX
875 if (!node)
876 return err;
877
878 if (bearer_id >= MAX_BEARERS)
879 goto exit;
880
78acb1f9 881 tipc_node_lock(node);
9d13ec65 882 link = node->links[bearer_id].link;
78acb1f9
EH
883 if (link) {
884 strncpy(linkname, link->name, len);
8a0f6ebe 885 err = 0;
78acb1f9 886 }
8a0f6ebe 887exit:
78acb1f9 888 tipc_node_unlock(node);
8a0f6ebe
YX
889 tipc_node_put(node);
890 return err;
78acb1f9 891}
9db9fdd1
YX
892
893void tipc_node_unlock(struct tipc_node *node)
894{
f2f9800d 895 struct net *net = node->net;
ca0c4273 896 u32 addr = 0;
c637c103 897 u32 flags = node->action_flags;
7b8613e0 898 u32 link_id = 0;
708ac32c 899 struct list_head *publ_list;
c637c103 900 struct sk_buff_head *inputq = node->inputq;
708ac32c 901 struct sk_buff_head *namedq;
9db9fdd1 902
c637c103
JPM
903 if (likely(!flags || (flags == TIPC_MSG_EVT))) {
904 node->action_flags = 0;
9db9fdd1 905 spin_unlock_bh(&node->lock);
c637c103
JPM
906 if (flags == TIPC_MSG_EVT)
907 tipc_sk_rcv(net, inputq);
9db9fdd1
YX
908 return;
909 }
910
7b8613e0
YX
911 addr = node->addr;
912 link_id = node->link_id;
c637c103 913 namedq = node->namedq;
708ac32c 914 publ_list = &node->publ_list;
7b8613e0 915
cb1b7280
JPM
916 node->action_flags &= ~(TIPC_MSG_EVT |
917 TIPC_NOTIFY_NODE_DOWN | TIPC_NOTIFY_NODE_UP |
918 TIPC_NOTIFY_LINK_DOWN | TIPC_NOTIFY_LINK_UP |
919 TIPC_WAKEUP_BCAST_USERS | TIPC_BCAST_MSG_EVT |
b952b2be 920 TIPC_NAMED_MSG_EVT | TIPC_BCAST_RESET);
7b8613e0 921
9db9fdd1
YX
922 spin_unlock_bh(&node->lock);
923
708ac32c
JPM
924 if (flags & TIPC_NOTIFY_NODE_DOWN)
925 tipc_publ_notify(net, publ_list, addr);
50100a5e 926
908344cd 927 if (flags & TIPC_WAKEUP_BCAST_USERS)
f2f9800d 928 tipc_bclink_wakeup_users(net);
908344cd 929
7b8613e0 930 if (flags & TIPC_NOTIFY_NODE_UP)
f2f9800d 931 tipc_named_node_up(net, addr);
7b8613e0
YX
932
933 if (flags & TIPC_NOTIFY_LINK_UP)
f2f9800d 934 tipc_nametbl_publish(net, TIPC_LINK_STATE, addr, addr,
7b8613e0
YX
935 TIPC_NODE_SCOPE, link_id, addr);
936
937 if (flags & TIPC_NOTIFY_LINK_DOWN)
f2f9800d 938 tipc_nametbl_withdraw(net, TIPC_LINK_STATE, addr,
7b8613e0 939 link_id, addr);
c637c103
JPM
940
941 if (flags & TIPC_MSG_EVT)
942 tipc_sk_rcv(net, inputq);
943
944 if (flags & TIPC_NAMED_MSG_EVT)
945 tipc_named_rcv(net, namedq);
cb1b7280
JPM
946
947 if (flags & TIPC_BCAST_MSG_EVT)
948 tipc_bclink_input(net);
b952b2be
YX
949
950 if (flags & TIPC_BCAST_RESET)
6144a996 951 tipc_node_reset_links(node);
9db9fdd1 952}
3e4b6ab5
RA
953
954/* Caller should hold node lock for the passed node */
d8182804 955static int __tipc_nl_add_node(struct tipc_nl_msg *msg, struct tipc_node *node)
3e4b6ab5
RA
956{
957 void *hdr;
958 struct nlattr *attrs;
959
bfb3e5dd 960 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
3e4b6ab5
RA
961 NLM_F_MULTI, TIPC_NL_NODE_GET);
962 if (!hdr)
963 return -EMSGSIZE;
964
965 attrs = nla_nest_start(msg->skb, TIPC_NLA_NODE);
966 if (!attrs)
967 goto msg_full;
968
969 if (nla_put_u32(msg->skb, TIPC_NLA_NODE_ADDR, node->addr))
970 goto attr_msg_full;
971 if (tipc_node_is_up(node))
972 if (nla_put_flag(msg->skb, TIPC_NLA_NODE_UP))
973 goto attr_msg_full;
974
975 nla_nest_end(msg->skb, attrs);
976 genlmsg_end(msg->skb, hdr);
977
978 return 0;
979
980attr_msg_full:
981 nla_nest_cancel(msg->skb, attrs);
982msg_full:
983 genlmsg_cancel(msg->skb, hdr);
984
985 return -EMSGSIZE;
986}
987
af9b028e
JPM
988static struct tipc_link *tipc_node_select_link(struct tipc_node *n, int sel,
989 int *bearer_id,
990 struct tipc_media_addr **maddr)
991{
992 int id = n->active_links[sel & 1];
993
994 if (unlikely(id < 0))
995 return NULL;
996
997 *bearer_id = id;
998 *maddr = &n->links[id].maddr;
999 return n->links[id].link;
1000}
1001
1002/**
1003 * tipc_node_xmit() is the general link level function for message sending
1004 * @net: the applicable net namespace
1005 * @list: chain of buffers containing message
1006 * @dnode: address of destination node
1007 * @selector: a number used for deterministic link selection
1008 * Consumes the buffer chain, except when returning -ELINKCONG
1009 * Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE
1010 */
1011int tipc_node_xmit(struct net *net, struct sk_buff_head *list,
1012 u32 dnode, int selector)
1013{
1014 struct tipc_link *l = NULL;
1015 struct tipc_node *n;
1016 struct sk_buff_head xmitq;
1017 struct tipc_media_addr *maddr;
1018 int bearer_id;
1019 int rc = -EHOSTUNREACH;
1020
1021 __skb_queue_head_init(&xmitq);
1022 n = tipc_node_find(net, dnode);
1023 if (likely(n)) {
1024 tipc_node_lock(n);
1025 l = tipc_node_select_link(n, selector, &bearer_id, &maddr);
1026 if (likely(l))
1027 rc = tipc_link_xmit(l, list, &xmitq);
1028 if (unlikely(rc == -ENOBUFS))
655fb243 1029 tipc_node_link_down(n, bearer_id);
af9b028e
JPM
1030 tipc_node_unlock(n);
1031 tipc_node_put(n);
1032 }
1033 if (likely(!rc)) {
1034 tipc_bearer_xmit(net, bearer_id, &xmitq, maddr);
1035 return 0;
1036 }
1037 if (likely(in_own_node(net, dnode))) {
1038 tipc_sk_rcv(net, list);
1039 return 0;
1040 }
1041 return rc;
1042}
1043
1044/* tipc_node_xmit_skb(): send single buffer to destination
1045 * Buffers sent via this functon are generally TIPC_SYSTEM_IMPORTANCE
1046 * messages, which will not be rejected
1047 * The only exception is datagram messages rerouted after secondary
1048 * lookup, which are rare and safe to dispose of anyway.
1049 * TODO: Return real return value, and let callers use
1050 * tipc_wait_for_sendpkt() where applicable
1051 */
1052int tipc_node_xmit_skb(struct net *net, struct sk_buff *skb, u32 dnode,
1053 u32 selector)
1054{
1055 struct sk_buff_head head;
1056 int rc;
1057
1058 skb_queue_head_init(&head);
1059 __skb_queue_tail(&head, skb);
1060 rc = tipc_node_xmit(net, &head, dnode, selector);
1061 if (rc == -ELINKCONG)
1062 kfree_skb(skb);
1063 return 0;
1064}
1065
6e498158
JPM
1066/**
1067 * tipc_node_check_state - check and if necessary update node state
1068 * @skb: TIPC packet
1069 * @bearer_id: identity of bearer delivering the packet
1070 * Returns true if state is ok, otherwise consumes buffer and returns false
6144a996 1071 */
6e498158 1072static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb,
662921cd 1073 int bearer_id, struct sk_buff_head *xmitq)
6144a996 1074{
6144a996 1075 struct tipc_msg *hdr = buf_msg(skb);
6e498158
JPM
1076 int usr = msg_user(hdr);
1077 int mtyp = msg_type(hdr);
6144a996 1078 u16 oseqno = msg_seqno(hdr);
6e498158
JPM
1079 u16 iseqno = msg_seqno(msg_get_wrapped(hdr));
1080 u16 exp_pkts = msg_msgcnt(hdr);
1081 u16 rcv_nxt, syncpt, dlv_nxt;
1082 int state = n->state;
1083 struct tipc_link *l, *pl = NULL;
1084 struct sk_buff_head;
1085 int i;
6144a996 1086
6e498158
JPM
1087 l = n->links[bearer_id].link;
1088 if (!l)
1089 return false;
1090 rcv_nxt = l->rcv_nxt;
6144a996 1091
6144a996 1092
6e498158
JPM
1093 if (likely((state == SELF_UP_PEER_UP) && (usr != TUNNEL_PROTOCOL)))
1094 return true;
6144a996 1095
6e498158
JPM
1096 /* Find parallel link, if any */
1097 for (i = 0; i < MAX_BEARERS; i++) {
1098 if ((i != bearer_id) && n->links[i].link) {
1099 pl = n->links[i].link;
1100 break;
1101 }
1102 }
6144a996 1103
6e498158
JPM
1104 /* Update node accesibility if applicable */
1105 if (state == SELF_UP_PEER_COMING) {
1106 if (!tipc_link_is_up(l))
1107 return true;
1108 if (!msg_peer_link_is_up(hdr))
1109 return true;
1110 tipc_node_fsm_evt(n, PEER_ESTABL_CONTACT_EVT);
1111 }
1112
1113 if (state == SELF_DOWN_PEER_LEAVING) {
1114 if (msg_peer_node_is_up(hdr))
1115 return false;
1116 tipc_node_fsm_evt(n, PEER_LOST_CONTACT_EVT);
1117 }
1118
1119 /* Ignore duplicate packets */
1120 if (less(oseqno, rcv_nxt))
1121 return true;
1122
1123 /* Initiate or update failover mode if applicable */
1124 if ((usr == TUNNEL_PROTOCOL) && (mtyp == FAILOVER_MSG)) {
1125 syncpt = oseqno + exp_pkts - 1;
662921cd 1126 if (pl && tipc_link_is_up(pl))
6e498158 1127 tipc_node_link_down(n, pl->bearer_id);
662921cd 1128
6e498158
JPM
1129 /* If pkts arrive out of order, use lowest calculated syncpt */
1130 if (less(syncpt, n->sync_point))
1131 n->sync_point = syncpt;
1132 }
1133
1134 /* Open parallel link when tunnel link reaches synch point */
662921cd
JPM
1135 if ((n->state == NODE_FAILINGOVER) && !tipc_link_is_failingover(l)) {
1136 if (!more(rcv_nxt, n->sync_point))
1137 return true;
6e498158
JPM
1138 tipc_node_fsm_evt(n, NODE_FAILOVER_END_EVT);
1139 if (pl)
662921cd 1140 tipc_link_fsm_evt(pl, LINK_FAILOVER_END_EVT);
6e498158
JPM
1141 return true;
1142 }
1143
1144 /* Initiate or update synch mode if applicable */
1145 if ((usr == TUNNEL_PROTOCOL) && (mtyp == SYNCH_MSG)) {
1146 syncpt = iseqno + exp_pkts - 1;
662921cd
JPM
1147 if (!tipc_link_is_up(l)) {
1148 tipc_link_fsm_evt(l, LINK_ESTABLISH_EVT);
1149 tipc_node_link_up(n, bearer_id, xmitq);
1150 }
6e498158
JPM
1151 if (n->state == SELF_UP_PEER_UP) {
1152 n->sync_point = syncpt;
662921cd 1153 tipc_link_fsm_evt(l, LINK_SYNCH_BEGIN_EVT);
6e498158
JPM
1154 tipc_node_fsm_evt(n, NODE_SYNCH_BEGIN_EVT);
1155 }
6e498158
JPM
1156 if (less(syncpt, n->sync_point))
1157 n->sync_point = syncpt;
6144a996 1158 }
6e498158
JPM
1159
1160 /* Open tunnel link when parallel link reaches synch point */
662921cd 1161 if ((n->state == NODE_SYNCHING) && tipc_link_is_synching(l)) {
6e498158
JPM
1162 if (pl)
1163 dlv_nxt = mod(pl->rcv_nxt - skb_queue_len(pl->inputq));
1164 if (!pl || more(dlv_nxt, n->sync_point)) {
662921cd 1165 tipc_link_fsm_evt(l, LINK_SYNCH_END_EVT);
6e498158 1166 tipc_node_fsm_evt(n, NODE_SYNCH_END_EVT);
6e498158
JPM
1167 return true;
1168 }
1169 if ((usr == TUNNEL_PROTOCOL) && (mtyp == SYNCH_MSG))
1170 return true;
1171 if (usr == LINK_PROTOCOL)
1172 return true;
1173 return false;
1174 }
1175 return true;
6144a996
JPM
1176}
1177
d999297c
JPM
1178/**
1179 * tipc_rcv - process TIPC packets/messages arriving from off-node
1180 * @net: the applicable net namespace
1181 * @skb: TIPC packet
1182 * @bearer: pointer to bearer message arrived on
1183 *
1184 * Invoked with no locks held. Bearer pointer must point to a valid bearer
1185 * structure (i.e. cannot be NULL), but bearer can be inactive.
1186 */
1187void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b)
1188{
1189 struct sk_buff_head xmitq;
1190 struct tipc_node *n;
6e498158
JPM
1191 struct tipc_msg *hdr = buf_msg(skb);
1192 int usr = msg_user(hdr);
d999297c 1193 int bearer_id = b->identity;
6e498158 1194 struct tipc_link_entry *le;
d999297c
JPM
1195 int rc = 0;
1196
1197 __skb_queue_head_init(&xmitq);
1198
1199 /* Ensure message is well-formed */
1200 if (unlikely(!tipc_msg_validate(skb)))
1201 goto discard;
1202
1203 /* Handle arrival of a non-unicast link packet */
d999297c 1204 if (unlikely(msg_non_seq(hdr))) {
6144a996 1205 if (usr == LINK_CONFIG)
d999297c
JPM
1206 tipc_disc_rcv(net, skb, b);
1207 else
1208 tipc_bclink_rcv(net, skb);
1209 return;
1210 }
1211
1212 /* Locate neighboring node that sent packet */
1213 n = tipc_node_find(net, msg_prevnode(hdr));
1214 if (unlikely(!n))
1215 goto discard;
6e498158 1216 le = &n->links[bearer_id];
d999297c 1217
6e498158 1218 tipc_node_lock(n);
6144a996 1219
6e498158
JPM
1220 /* Is reception permitted at the moment ? */
1221 if (!tipc_node_filter_pkt(n, hdr))
d999297c
JPM
1222 goto unlock;
1223
6e498158 1224 if (unlikely(msg_user(hdr) == LINK_PROTOCOL))
d999297c
JPM
1225 tipc_bclink_sync_state(n, hdr);
1226
1227 /* Release acked broadcast messages */
1228 if (unlikely(n->bclink.acked != msg_bcast_ack(hdr)))
1229 tipc_bclink_acknowledge(n, msg_bcast_ack(hdr));
1230
6e498158 1231 /* Check and if necessary update node state */
662921cd 1232 if (likely(tipc_node_check_state(n, skb, bearer_id, &xmitq))) {
6e498158
JPM
1233 rc = tipc_link_rcv(le->link, skb, &xmitq);
1234 skb = NULL;
1235 }
d999297c
JPM
1236
1237 if (unlikely(rc & TIPC_LINK_UP_EVT))
6e498158
JPM
1238 tipc_node_link_up(n, bearer_id, &xmitq);
1239
d999297c 1240 if (unlikely(rc & TIPC_LINK_DOWN_EVT))
655fb243 1241 tipc_node_link_down(n, bearer_id);
d999297c
JPM
1242unlock:
1243 tipc_node_unlock(n);
6e498158
JPM
1244
1245 if (!skb_queue_empty(&le->inputq))
1246 tipc_sk_rcv(net, &le->inputq);
1247
1248 if (!skb_queue_empty(&xmitq))
1249 tipc_bearer_xmit(net, bearer_id, &xmitq, &le->maddr);
1250
d999297c
JPM
1251 tipc_node_put(n);
1252discard:
1253 kfree_skb(skb);
1254}
1255
3e4b6ab5
RA
1256int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb)
1257{
1258 int err;
f2f9800d
YX
1259 struct net *net = sock_net(skb->sk);
1260 struct tipc_net *tn = net_generic(net, tipc_net_id);
3e4b6ab5
RA
1261 int done = cb->args[0];
1262 int last_addr = cb->args[1];
1263 struct tipc_node *node;
1264 struct tipc_nl_msg msg;
1265
1266 if (done)
1267 return 0;
1268
1269 msg.skb = skb;
1270 msg.portid = NETLINK_CB(cb->skb).portid;
1271 msg.seq = cb->nlh->nlmsg_seq;
1272
1273 rcu_read_lock();
8a0f6ebe
YX
1274 if (last_addr) {
1275 node = tipc_node_find(net, last_addr);
1276 if (!node) {
1277 rcu_read_unlock();
1278 /* We never set seq or call nl_dump_check_consistent()
1279 * this means that setting prev_seq here will cause the
1280 * consistence check to fail in the netlink callback
1281 * handler. Resulting in the NLMSG_DONE message having
1282 * the NLM_F_DUMP_INTR flag set if the node state
1283 * changed while we released the lock.
1284 */
1285 cb->prev_seq = 1;
1286 return -EPIPE;
1287 }
1288 tipc_node_put(node);
3e4b6ab5
RA
1289 }
1290
f2f9800d 1291 list_for_each_entry_rcu(node, &tn->node_list, list) {
3e4b6ab5
RA
1292 if (last_addr) {
1293 if (node->addr == last_addr)
1294 last_addr = 0;
1295 else
1296 continue;
1297 }
1298
1299 tipc_node_lock(node);
1300 err = __tipc_nl_add_node(&msg, node);
1301 if (err) {
1302 last_addr = node->addr;
1303 tipc_node_unlock(node);
1304 goto out;
1305 }
1306
1307 tipc_node_unlock(node);
1308 }
1309 done = 1;
1310out:
1311 cb->args[0] = done;
1312 cb->args[1] = last_addr;
1313 rcu_read_unlock();
1314
1315 return skb->len;
1316}