]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - net/tipc/node.c
tipc: add sequence number check for link STATE messages
[mirror_ubuntu-jammy-kernel.git] / net / tipc / node.c
CommitLineData
b97bf3fd
PL
1/*
2 * net/tipc/node.c: TIPC node management routines
c4307285 3 *
60020e18 4 * Copyright (c) 2000-2006, 2012-2016, 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"
35c55c98 43#include "monitor.h"
d999297c 44#include "discover.h"
49cc66ea 45#include "netlink.h"
c8199300 46
5be9c086 47#define INVALID_NODE_SIG 0x10000
6a939f36 48#define NODE_CLEANUP_AFTER 300000
5be9c086 49
5be9c086
JPM
50/* Flags used to take different actions according to flag type
51 * TIPC_NOTIFY_NODE_DOWN: notify node is down
52 * TIPC_NOTIFY_NODE_UP: notify node is up
53 * TIPC_DISTRIBUTE_NAME: publish or withdraw link state name type
54 */
55enum {
56 TIPC_NOTIFY_NODE_DOWN = (1 << 3),
57 TIPC_NOTIFY_NODE_UP = (1 << 4),
58 TIPC_NOTIFY_LINK_UP = (1 << 6),
59 TIPC_NOTIFY_LINK_DOWN = (1 << 7)
60};
61
62struct tipc_link_entry {
63 struct tipc_link *link;
64 spinlock_t lock; /* per link */
65 u32 mtu;
66 struct sk_buff_head inputq;
67 struct tipc_media_addr maddr;
68};
69
70struct tipc_bclink_entry {
71 struct tipc_link *link;
72 struct sk_buff_head inputq1;
73 struct sk_buff_head arrvq;
74 struct sk_buff_head inputq2;
75 struct sk_buff_head namedq;
76};
77
78/**
79 * struct tipc_node - TIPC node structure
80 * @addr: network address of node
81 * @ref: reference counter to node object
82 * @lock: rwlock governing access to structure
83 * @net: the applicable net namespace
84 * @hash: links to adjacent nodes in unsorted hash chain
85 * @inputq: pointer to input queue containing messages for msg event
86 * @namedq: pointer to name table input queue with name table messages
87 * @active_links: bearer ids of active links, used as index into links[] array
88 * @links: array containing references to all links to node
89 * @action_flags: bit mask of different types of node actions
90 * @state: connectivity state vs peer node
91 * @sync_point: sequence number where synch/failover is finished
92 * @list: links to adjacent nodes in sorted list of cluster's nodes
93 * @working_links: number of working links to node (both active and standby)
94 * @link_cnt: number of links to node
95 * @capabilities: bitmap, indicating peer node's functional capabilities
96 * @signature: node instance identifier
97 * @link_id: local and remote bearer ids of changing link, if any
98 * @publ_list: list of publications
99 * @rcu: rcu struct for tipc_node
6a939f36 100 * @delete_at: indicates the time for deleting a down node
5be9c086
JPM
101 */
102struct tipc_node {
103 u32 addr;
104 struct kref kref;
105 rwlock_t lock;
106 struct net *net;
107 struct hlist_node hash;
108 int active_links[2];
109 struct tipc_link_entry links[MAX_BEARERS];
110 struct tipc_bclink_entry bc_entry;
111 int action_flags;
112 struct list_head list;
113 int state;
114 u16 sync_point;
115 int link_cnt;
116 u16 working_links;
117 u16 capabilities;
118 u32 signature;
119 u32 link_id;
25b0b9c4 120 u8 peer_id[16];
5be9c086
JPM
121 struct list_head publ_list;
122 struct list_head conn_sks;
123 unsigned long keepalive_intv;
124 struct timer_list timer;
125 struct rcu_head rcu;
6a939f36 126 unsigned long delete_at;
5be9c086
JPM
127};
128
6e498158
JPM
129/* Node FSM states and events:
130 */
131enum {
132 SELF_DOWN_PEER_DOWN = 0xdd,
133 SELF_UP_PEER_UP = 0xaa,
134 SELF_DOWN_PEER_LEAVING = 0xd1,
135 SELF_UP_PEER_COMING = 0xac,
136 SELF_COMING_PEER_UP = 0xca,
137 SELF_LEAVING_PEER_DOWN = 0x1d,
138 NODE_FAILINGOVER = 0xf0,
139 NODE_SYNCHING = 0xcc
140};
141
142enum {
143 SELF_ESTABL_CONTACT_EVT = 0xece,
144 SELF_LOST_CONTACT_EVT = 0x1ce,
145 PEER_ESTABL_CONTACT_EVT = 0x9ece,
146 PEER_LOST_CONTACT_EVT = 0x91ce,
147 NODE_FAILOVER_BEGIN_EVT = 0xfbe,
148 NODE_FAILOVER_END_EVT = 0xfee,
149 NODE_SYNCH_BEGIN_EVT = 0xcbe,
150 NODE_SYNCH_END_EVT = 0xcee
151};
152
598411d7
JPM
153static void __tipc_node_link_down(struct tipc_node *n, int *bearer_id,
154 struct sk_buff_head *xmitq,
155 struct tipc_media_addr **maddr);
156static void tipc_node_link_down(struct tipc_node *n, int bearer_id,
157 bool delete);
158static void node_lost_contact(struct tipc_node *n, struct sk_buff_head *inputq);
8a0f6ebe 159static void tipc_node_delete(struct tipc_node *node);
31b102bb 160static void tipc_node_timeout(struct timer_list *t);
d999297c 161static void tipc_node_fsm_evt(struct tipc_node *n, int evt);
5be9c086 162static struct tipc_node *tipc_node_find(struct net *net, u32 addr);
25b0b9c4 163static struct tipc_node *tipc_node_find_by_id(struct net *net, u8 *id);
5be9c086 164static void tipc_node_put(struct tipc_node *node);
38077b8e 165static bool node_is_up(struct tipc_node *n);
6a939f36 166static void tipc_node_delete_from_list(struct tipc_node *node);
b97bf3fd 167
02be61a9
JPM
168struct tipc_sock_conn {
169 u32 port;
170 u32 peer_port;
171 u32 peer_node;
172 struct list_head list;
173};
174
5be9c086
JPM
175static struct tipc_link *node_active_link(struct tipc_node *n, int sel)
176{
177 int bearer_id = n->active_links[sel & 1];
178
179 if (unlikely(bearer_id == INVALID_BEARER_ID))
180 return NULL;
181
182 return n->links[bearer_id].link;
183}
184
185int tipc_node_get_mtu(struct net *net, u32 addr, u32 sel)
186{
187 struct tipc_node *n;
188 int bearer_id;
189 unsigned int mtu = MAX_MSG_SIZE;
190
191 n = tipc_node_find(net, addr);
192 if (unlikely(!n))
193 return mtu;
194
195 bearer_id = n->active_links[sel & 1];
196 if (likely(bearer_id != INVALID_BEARER_ID))
197 mtu = n->links[bearer_id].mtu;
198 tipc_node_put(n);
199 return mtu;
200}
60020e18 201
3e5cf362
JM
202bool tipc_node_get_id(struct net *net, u32 addr, u8 *id)
203{
204 u8 *own_id = tipc_own_id(net);
205 struct tipc_node *n;
206
207 if (!own_id)
208 return true;
209
210 if (addr == tipc_own_addr(net)) {
211 memcpy(id, own_id, TIPC_NODEID_LEN);
212 return true;
213 }
214 n = tipc_node_find(net, addr);
215 if (!n)
216 return false;
217
218 memcpy(id, &n->peer_id, TIPC_NODEID_LEN);
219 tipc_node_put(n);
220 return true;
221}
222
60020e18
JPM
223u16 tipc_node_get_capabilities(struct net *net, u32 addr)
224{
225 struct tipc_node *n;
226 u16 caps;
227
228 n = tipc_node_find(net, addr);
229 if (unlikely(!n))
230 return TIPC_NODE_CAPABILITIES;
231 caps = n->capabilities;
232 tipc_node_put(n);
233 return caps;
234}
235
8a0f6ebe
YX
236static void tipc_node_kref_release(struct kref *kref)
237{
d25a0125 238 struct tipc_node *n = container_of(kref, struct tipc_node, kref);
8a0f6ebe 239
d25a0125
JPM
240 kfree(n->bc_entry.link);
241 kfree_rcu(n, rcu);
8a0f6ebe
YX
242}
243
5be9c086 244static void tipc_node_put(struct tipc_node *node)
8a0f6ebe
YX
245{
246 kref_put(&node->kref, tipc_node_kref_release);
247}
248
249static void tipc_node_get(struct tipc_node *node)
250{
251 kref_get(&node->kref);
252}
253
1ec2bb08 254/*
672d99e1
AS
255 * tipc_node_find - locate specified node object, if it exists
256 */
5be9c086 257static struct tipc_node *tipc_node_find(struct net *net, u32 addr)
672d99e1 258{
b170997a 259 struct tipc_net *tn = tipc_net(net);
672d99e1 260 struct tipc_node *node;
b170997a 261 unsigned int thash = tipc_hashfn(addr);
672d99e1 262
6c7a762e 263 rcu_read_lock();
b170997a
JPM
264 hlist_for_each_entry_rcu(node, &tn->node_htable[thash], hash) {
265 if (node->addr != addr)
266 continue;
267 if (!kref_get_unless_zero(&node->kref))
268 node = NULL;
269 break;
672d99e1 270 }
6c7a762e 271 rcu_read_unlock();
b170997a 272 return node;
672d99e1
AS
273}
274
25b0b9c4
JM
275/* tipc_node_find_by_id - locate specified node object by its 128-bit id
276 * Note: this function is called only when a discovery request failed
277 * to find the node by its 32-bit id, and is not time critical
278 */
279static struct tipc_node *tipc_node_find_by_id(struct net *net, u8 *id)
280{
281 struct tipc_net *tn = tipc_net(net);
282 struct tipc_node *n;
283 bool found = false;
284
285 rcu_read_lock();
286 list_for_each_entry_rcu(n, &tn->node_list, list) {
287 read_lock_bh(&n->lock);
288 if (!memcmp(id, n->peer_id, 16) &&
289 kref_get_unless_zero(&n->kref))
290 found = true;
291 read_unlock_bh(&n->lock);
292 if (found)
293 break;
294 }
295 rcu_read_unlock();
296 return found ? n : NULL;
297}
298
5be9c086 299static void tipc_node_read_lock(struct tipc_node *n)
5405ff6e
JPM
300{
301 read_lock_bh(&n->lock);
302}
303
5be9c086 304static void tipc_node_read_unlock(struct tipc_node *n)
5405ff6e
JPM
305{
306 read_unlock_bh(&n->lock);
307}
308
309static void tipc_node_write_lock(struct tipc_node *n)
310{
311 write_lock_bh(&n->lock);
312}
313
93f955aa
PB
314static void tipc_node_write_unlock_fast(struct tipc_node *n)
315{
316 write_unlock_bh(&n->lock);
317}
318
5405ff6e
JPM
319static void tipc_node_write_unlock(struct tipc_node *n)
320{
321 struct net *net = n->net;
322 u32 addr = 0;
323 u32 flags = n->action_flags;
324 u32 link_id = 0;
35c55c98 325 u32 bearer_id;
5405ff6e
JPM
326 struct list_head *publ_list;
327
328 if (likely(!flags)) {
329 write_unlock_bh(&n->lock);
330 return;
331 }
332
333 addr = n->addr;
334 link_id = n->link_id;
35c55c98 335 bearer_id = link_id & 0xffff;
5405ff6e
JPM
336 publ_list = &n->publ_list;
337
338 n->action_flags &= ~(TIPC_NOTIFY_NODE_DOWN | TIPC_NOTIFY_NODE_UP |
339 TIPC_NOTIFY_LINK_DOWN | TIPC_NOTIFY_LINK_UP);
340
341 write_unlock_bh(&n->lock);
342
343 if (flags & TIPC_NOTIFY_NODE_DOWN)
344 tipc_publ_notify(net, publ_list, addr);
345
346 if (flags & TIPC_NOTIFY_NODE_UP)
347 tipc_named_node_up(net, addr);
348
35c55c98
JPM
349 if (flags & TIPC_NOTIFY_LINK_UP) {
350 tipc_mon_peer_up(net, addr, bearer_id);
5405ff6e 351 tipc_nametbl_publish(net, TIPC_LINK_STATE, addr, addr,
218527fe 352 TIPC_NODE_SCOPE, link_id, link_id);
35c55c98
JPM
353 }
354 if (flags & TIPC_NOTIFY_LINK_DOWN) {
355 tipc_mon_peer_down(net, addr, bearer_id);
5405ff6e 356 tipc_nametbl_withdraw(net, TIPC_LINK_STATE, addr,
37922ea4 357 addr, link_id);
35c55c98 358 }
5405ff6e
JPM
359}
360
e1a22d13
WY
361static struct tipc_node *tipc_node_create(struct net *net, u32 addr,
362 u8 *peer_id, u16 capabilities)
b97bf3fd 363{
f2f9800d 364 struct tipc_net *tn = net_generic(net, tipc_net_id);
1a90632d 365 struct tipc_node *n, *temp_node;
9012de50
JM
366 struct tipc_link *l;
367 int bearer_id;
5405ff6e 368 int i;
b97bf3fd 369
f2f9800d 370 spin_lock_bh(&tn->node_list_lock);
1a90632d 371 n = tipc_node_find(net, addr);
60020e18
JPM
372 if (n) {
373 /* Same node may come back with new capabilities */
374 n->capabilities = capabilities;
9012de50
JM
375 for (bearer_id = 0; bearer_id < MAX_BEARERS; bearer_id++) {
376 l = n->links[bearer_id].link;
377 if (l)
378 tipc_link_update_caps(l, capabilities);
379 }
b45db71b 380 goto exit;
60020e18 381 }
1a90632d
JPM
382 n = kzalloc(sizeof(*n), GFP_ATOMIC);
383 if (!n) {
2cf8aa19 384 pr_warn("Node creation failed, no memory\n");
b45db71b 385 goto exit;
a10bd924 386 }
1a90632d 387 n->addr = addr;
25b0b9c4 388 memcpy(&n->peer_id, peer_id, 16);
1a90632d
JPM
389 n->net = net;
390 n->capabilities = capabilities;
391 kref_init(&n->kref);
392 rwlock_init(&n->lock);
393 INIT_HLIST_NODE(&n->hash);
394 INIT_LIST_HEAD(&n->list);
395 INIT_LIST_HEAD(&n->publ_list);
396 INIT_LIST_HEAD(&n->conn_sks);
397 skb_queue_head_init(&n->bc_entry.namedq);
398 skb_queue_head_init(&n->bc_entry.inputq1);
399 __skb_queue_head_init(&n->bc_entry.arrvq);
400 skb_queue_head_init(&n->bc_entry.inputq2);
5405ff6e 401 for (i = 0; i < MAX_BEARERS; i++)
1a90632d 402 spin_lock_init(&n->links[i].lock);
1a90632d 403 n->state = SELF_DOWN_PEER_LEAVING;
6a939f36 404 n->delete_at = jiffies + msecs_to_jiffies(NODE_CLEANUP_AFTER);
1a90632d
JPM
405 n->signature = INVALID_NODE_SIG;
406 n->active_links[0] = INVALID_BEARER_ID;
407 n->active_links[1] = INVALID_BEARER_ID;
25b0b9c4
JM
408 if (!tipc_link_bc_create(net, tipc_own_addr(net),
409 addr, U16_MAX,
38206d59 410 tipc_link_window(tipc_bc_sndlink(net)),
1a90632d
JPM
411 n->capabilities,
412 &n->bc_entry.inputq1,
413 &n->bc_entry.namedq,
52666986 414 tipc_bc_sndlink(net),
1a90632d 415 &n->bc_entry.link)) {
52666986 416 pr_warn("Broadcast rcv link creation failed, no memory\n");
1a90632d
JPM
417 kfree(n);
418 n = NULL;
52666986
JPM
419 goto exit;
420 }
1a90632d 421 tipc_node_get(n);
31b102bb 422 timer_setup(&n->timer, tipc_node_timeout, 0);
1a90632d 423 n->keepalive_intv = U32_MAX;
d5c91fb7
JPM
424 hlist_add_head_rcu(&n->hash, &tn->node_htable[tipc_hashfn(addr)]);
425 list_for_each_entry_rcu(temp_node, &tn->node_list, list) {
426 if (n->addr < temp_node->addr)
427 break;
428 }
429 list_add_tail_rcu(&n->list, &temp_node->list);
b45db71b 430exit:
f2f9800d 431 spin_unlock_bh(&tn->node_list_lock);
1a90632d 432 return n;
b97bf3fd
PL
433}
434
8a1577c9
JPM
435static void tipc_node_calculate_timer(struct tipc_node *n, struct tipc_link *l)
436{
38206d59 437 unsigned long tol = tipc_link_tolerance(l);
8a1577c9 438 unsigned long intv = ((tol / 4) > 500) ? 500 : tol / 4;
8a1577c9
JPM
439
440 /* Link with lowest tolerance determines timer interval */
5ca509fc
JPM
441 if (intv < n->keepalive_intv)
442 n->keepalive_intv = intv;
8a1577c9 443
5ca509fc
JPM
444 /* Ensure link's abort limit corresponds to current tolerance */
445 tipc_link_set_abort_limit(l, tol / n->keepalive_intv);
8a1577c9
JPM
446}
447
6a939f36 448static void tipc_node_delete_from_list(struct tipc_node *node)
b97bf3fd 449{
8a0f6ebe
YX
450 list_del_rcu(&node->list);
451 hlist_del_rcu(&node->hash);
d25a0125 452 tipc_node_put(node);
6a939f36
GM
453}
454
455static void tipc_node_delete(struct tipc_node *node)
456{
457 tipc_node_delete_from_list(node);
d25a0125
JPM
458
459 del_timer_sync(&node->timer);
460 tipc_node_put(node);
b97bf3fd
PL
461}
462
f2f9800d 463void tipc_node_stop(struct net *net)
46651c59 464{
d25a0125 465 struct tipc_net *tn = tipc_net(net);
46651c59
YX
466 struct tipc_node *node, *t_node;
467
f2f9800d 468 spin_lock_bh(&tn->node_list_lock);
d25a0125
JPM
469 list_for_each_entry_safe(node, t_node, &tn->node_list, list)
470 tipc_node_delete(node);
f2f9800d 471 spin_unlock_bh(&tn->node_list_lock);
46651c59
YX
472}
473
1d7e1c25
JPM
474void tipc_node_subscribe(struct net *net, struct list_head *subscr, u32 addr)
475{
476 struct tipc_node *n;
477
478 if (in_own_node(net, addr))
479 return;
480
481 n = tipc_node_find(net, addr);
482 if (!n) {
483 pr_warn("Node subscribe rejected, unknown node 0x%x\n", addr);
484 return;
485 }
5405ff6e 486 tipc_node_write_lock(n);
1d7e1c25 487 list_add_tail(subscr, &n->publ_list);
93f955aa 488 tipc_node_write_unlock_fast(n);
1d7e1c25
JPM
489 tipc_node_put(n);
490}
491
492void tipc_node_unsubscribe(struct net *net, struct list_head *subscr, u32 addr)
493{
494 struct tipc_node *n;
495
496 if (in_own_node(net, addr))
497 return;
498
499 n = tipc_node_find(net, addr);
500 if (!n) {
501 pr_warn("Node unsubscribe rejected, unknown node 0x%x\n", addr);
502 return;
503 }
5405ff6e 504 tipc_node_write_lock(n);
1d7e1c25 505 list_del_init(subscr);
93f955aa 506 tipc_node_write_unlock_fast(n);
1d7e1c25
JPM
507 tipc_node_put(n);
508}
509
f2f9800d 510int tipc_node_add_conn(struct net *net, u32 dnode, u32 port, u32 peer_port)
02be61a9
JPM
511{
512 struct tipc_node *node;
513 struct tipc_sock_conn *conn;
8a0f6ebe 514 int err = 0;
02be61a9 515
34747539 516 if (in_own_node(net, dnode))
02be61a9
JPM
517 return 0;
518
f2f9800d 519 node = tipc_node_find(net, dnode);
02be61a9
JPM
520 if (!node) {
521 pr_warn("Connecting sock to node 0x%x failed\n", dnode);
522 return -EHOSTUNREACH;
523 }
524 conn = kmalloc(sizeof(*conn), GFP_ATOMIC);
8a0f6ebe
YX
525 if (!conn) {
526 err = -EHOSTUNREACH;
527 goto exit;
528 }
02be61a9
JPM
529 conn->peer_node = dnode;
530 conn->port = port;
531 conn->peer_port = peer_port;
532
5405ff6e 533 tipc_node_write_lock(node);
02be61a9 534 list_add_tail(&conn->list, &node->conn_sks);
5405ff6e 535 tipc_node_write_unlock(node);
8a0f6ebe
YX
536exit:
537 tipc_node_put(node);
538 return err;
02be61a9
JPM
539}
540
f2f9800d 541void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port)
02be61a9
JPM
542{
543 struct tipc_node *node;
544 struct tipc_sock_conn *conn, *safe;
545
34747539 546 if (in_own_node(net, dnode))
02be61a9
JPM
547 return;
548
f2f9800d 549 node = tipc_node_find(net, dnode);
02be61a9
JPM
550 if (!node)
551 return;
552
5405ff6e 553 tipc_node_write_lock(node);
02be61a9
JPM
554 list_for_each_entry_safe(conn, safe, &node->conn_sks, list) {
555 if (port != conn->port)
556 continue;
557 list_del(&conn->list);
558 kfree(conn);
559 }
5405ff6e 560 tipc_node_write_unlock(node);
8a0f6ebe 561 tipc_node_put(node);
02be61a9
JPM
562}
563
6a939f36
GM
564static void tipc_node_clear_links(struct tipc_node *node)
565{
566 int i;
567
568 for (i = 0; i < MAX_BEARERS; i++) {
569 struct tipc_link_entry *le = &node->links[i];
570
571 if (le->link) {
572 kfree(le->link);
573 le->link = NULL;
574 node->link_cnt--;
575 }
576 }
577}
578
579/* tipc_node_cleanup - delete nodes that does not
580 * have active links for NODE_CLEANUP_AFTER time
581 */
582static int tipc_node_cleanup(struct tipc_node *peer)
583{
584 struct tipc_net *tn = tipc_net(peer->net);
585 bool deleted = false;
586
587 spin_lock_bh(&tn->node_list_lock);
588 tipc_node_write_lock(peer);
589
590 if (!node_is_up(peer) && time_after(jiffies, peer->delete_at)) {
591 tipc_node_clear_links(peer);
592 tipc_node_delete_from_list(peer);
593 deleted = true;
594 }
595 tipc_node_write_unlock(peer);
596 spin_unlock_bh(&tn->node_list_lock);
597 return deleted;
598}
599
8a1577c9
JPM
600/* tipc_node_timeout - handle expiration of node timer
601 */
31b102bb 602static void tipc_node_timeout(struct timer_list *t)
8a1577c9 603{
31b102bb 604 struct tipc_node *n = from_timer(n, t, timer);
598411d7 605 struct tipc_link_entry *le;
8a1577c9 606 struct sk_buff_head xmitq;
759f29b6 607 int remains = n->link_cnt;
8a1577c9
JPM
608 int bearer_id;
609 int rc = 0;
610
6a939f36
GM
611 if (!node_is_up(n) && tipc_node_cleanup(n)) {
612 /*Removing the reference of Timer*/
613 tipc_node_put(n);
614 return;
615 }
616
8a1577c9
JPM
617 __skb_queue_head_init(&xmitq);
618
759f29b6 619 for (bearer_id = 0; remains && (bearer_id < MAX_BEARERS); bearer_id++) {
5405ff6e 620 tipc_node_read_lock(n);
598411d7
JPM
621 le = &n->links[bearer_id];
622 if (le->link) {
759f29b6 623 spin_lock_bh(&le->lock);
8a1577c9 624 /* Link tolerance may change asynchronously: */
598411d7
JPM
625 tipc_node_calculate_timer(n, le->link);
626 rc = tipc_link_timeout(le->link, &xmitq);
759f29b6
TN
627 spin_unlock_bh(&le->lock);
628 remains--;
8a1577c9 629 }
5405ff6e 630 tipc_node_read_unlock(n);
598411d7
JPM
631 tipc_bearer_xmit(n->net, bearer_id, &xmitq, &le->maddr);
632 if (rc & TIPC_LINK_DOWN_EVT)
633 tipc_node_link_down(n, bearer_id, false);
8a1577c9 634 }
5ca509fc 635 mod_timer(&n->timer, jiffies + msecs_to_jiffies(n->keepalive_intv));
8a1577c9
JPM
636}
637
b97bf3fd 638/**
598411d7
JPM
639 * __tipc_node_link_up - handle addition of link
640 * Node lock must be held by caller
b97bf3fd
PL
641 * Link becomes active (alone or shared) or standby, depending on its priority.
642 */
598411d7
JPM
643static void __tipc_node_link_up(struct tipc_node *n, int bearer_id,
644 struct sk_buff_head *xmitq)
b97bf3fd 645{
36e78a46
JPM
646 int *slot0 = &n->active_links[0];
647 int *slot1 = &n->active_links[1];
6e498158
JPM
648 struct tipc_link *ol = node_active_link(n, 0);
649 struct tipc_link *nl = n->links[bearer_id].link;
9d13ec65 650
e7142c34 651 if (!nl || tipc_link_is_up(nl))
73f646ce
JPM
652 return;
653
654 tipc_link_fsm_evt(nl, LINK_ESTABLISH_EVT);
655 if (!tipc_link_is_up(nl))
598411d7
JPM
656 return;
657
9d13ec65
JPM
658 n->working_links++;
659 n->action_flags |= TIPC_NOTIFY_LINK_UP;
38206d59 660 n->link_id = tipc_link_id(nl);
6e498158
JPM
661
662 /* Leave room for tunnel header when returning 'mtu' to users: */
38206d59 663 n->links[bearer_id].mtu = tipc_link_mtu(nl) - INT_H_SIZE;
7b8613e0 664
cbeb83ca 665 tipc_bearer_add_dest(n->net, bearer_id, n->addr);
b06b281e 666 tipc_bcast_inc_bearer_dst_cnt(n->net, bearer_id);
cbeb83ca 667
3fa9cacd 668 pr_debug("Established link <%s> on network plane %c\n",
38206d59 669 tipc_link_name(nl), tipc_link_plane(nl));
c4307285 670
34b9cd64
JPM
671 /* Ensure that a STATE message goes first */
672 tipc_link_build_state_msg(nl, xmitq);
673
6e498158
JPM
674 /* First link? => give it both slots */
675 if (!ol) {
36e78a46
JPM
676 *slot0 = bearer_id;
677 *slot1 = bearer_id;
52666986
JPM
678 tipc_node_fsm_evt(n, SELF_ESTABL_CONTACT_EVT);
679 n->action_flags |= TIPC_NOTIFY_NODE_UP;
def22c47 680 tipc_link_set_active(nl, true);
b06b281e 681 tipc_bcast_add_peer(n->net, nl, xmitq);
9d13ec65 682 return;
b97bf3fd 683 }
36e78a46 684
6e498158 685 /* Second link => redistribute slots */
38206d59
JPM
686 if (tipc_link_prio(nl) > tipc_link_prio(ol)) {
687 pr_debug("Old link <%s> becomes standby\n", tipc_link_name(ol));
36e78a46 688 *slot0 = bearer_id;
6e498158 689 *slot1 = bearer_id;
c72fa872
JPM
690 tipc_link_set_active(nl, true);
691 tipc_link_set_active(ol, false);
38206d59 692 } else if (tipc_link_prio(nl) == tipc_link_prio(ol)) {
c72fa872 693 tipc_link_set_active(nl, true);
c49a0a84 694 *slot1 = bearer_id;
6e498158 695 } else {
38206d59 696 pr_debug("New link <%s> is standby\n", tipc_link_name(nl));
b97bf3fd 697 }
b97bf3fd 698
6e498158
JPM
699 /* Prepare synchronization with first link */
700 tipc_link_tnl_prepare(ol, nl, SYNCH_MSG, xmitq);
b97bf3fd
PL
701}
702
703/**
598411d7
JPM
704 * tipc_node_link_up - handle addition of link
705 *
706 * Link becomes active (alone or shared) or standby, depending on its priority.
b97bf3fd 707 */
598411d7
JPM
708static void tipc_node_link_up(struct tipc_node *n, int bearer_id,
709 struct sk_buff_head *xmitq)
b97bf3fd 710{
de7e07f9
JPM
711 struct tipc_media_addr *maddr;
712
5405ff6e 713 tipc_node_write_lock(n);
598411d7 714 __tipc_node_link_up(n, bearer_id, xmitq);
de7e07f9
JPM
715 maddr = &n->links[bearer_id].maddr;
716 tipc_bearer_xmit(n->net, bearer_id, xmitq, maddr);
5405ff6e 717 tipc_node_write_unlock(n);
598411d7
JPM
718}
719
720/**
721 * __tipc_node_link_down - handle loss of link
722 */
723static void __tipc_node_link_down(struct tipc_node *n, int *bearer_id,
724 struct sk_buff_head *xmitq,
725 struct tipc_media_addr **maddr)
726{
727 struct tipc_link_entry *le = &n->links[*bearer_id];
36e78a46
JPM
728 int *slot0 = &n->active_links[0];
729 int *slot1 = &n->active_links[1];
38206d59 730 int i, highest = 0, prio;
6e498158 731 struct tipc_link *l, *_l, *tnl;
b97bf3fd 732
598411d7 733 l = n->links[*bearer_id].link;
662921cd 734 if (!l || tipc_link_is_reset(l))
655fb243
JPM
735 return;
736
9d13ec65
JPM
737 n->working_links--;
738 n->action_flags |= TIPC_NOTIFY_LINK_DOWN;
38206d59 739 n->link_id = tipc_link_id(l);
5392d646 740
598411d7 741 tipc_bearer_remove_dest(n->net, *bearer_id, n->addr);
655fb243 742
3fa9cacd 743 pr_debug("Lost link <%s> on network plane %c\n",
38206d59 744 tipc_link_name(l), tipc_link_plane(l));
16e166b8 745
36e78a46
JPM
746 /* Select new active link if any available */
747 *slot0 = INVALID_BEARER_ID;
748 *slot1 = INVALID_BEARER_ID;
749 for (i = 0; i < MAX_BEARERS; i++) {
750 _l = n->links[i].link;
751 if (!_l || !tipc_link_is_up(_l))
752 continue;
655fb243
JPM
753 if (_l == l)
754 continue;
38206d59
JPM
755 prio = tipc_link_prio(_l);
756 if (prio < highest)
36e78a46 757 continue;
38206d59
JPM
758 if (prio > highest) {
759 highest = prio;
36e78a46
JPM
760 *slot0 = i;
761 *slot1 = i;
762 continue;
763 }
764 *slot1 = i;
765 }
655fb243 766
38077b8e 767 if (!node_is_up(n)) {
c8199300
JPM
768 if (tipc_link_peer_is_down(l))
769 tipc_node_fsm_evt(n, PEER_LOST_CONTACT_EVT);
770 tipc_node_fsm_evt(n, SELF_LOST_CONTACT_EVT);
771 tipc_link_fsm_evt(l, LINK_RESET_EVT);
6e498158 772 tipc_link_reset(l);
282b3a05
JPM
773 tipc_link_build_reset_msg(l, xmitq);
774 *maddr = &n->links[*bearer_id].maddr;
598411d7 775 node_lost_contact(n, &le->inputq);
b06b281e 776 tipc_bcast_dec_bearer_dst_cnt(n->net, *bearer_id);
6e498158
JPM
777 return;
778 }
b06b281e 779 tipc_bcast_dec_bearer_dst_cnt(n->net, *bearer_id);
655fb243 780
6e498158 781 /* There is still a working link => initiate failover */
38206d59
JPM
782 *bearer_id = n->active_links[0];
783 tnl = n->links[*bearer_id].link;
5ae2f8e6
JPM
784 tipc_link_fsm_evt(tnl, LINK_SYNCH_END_EVT);
785 tipc_node_fsm_evt(n, NODE_SYNCH_END_EVT);
38206d59 786 n->sync_point = tipc_link_rcv_nxt(tnl) + (U16_MAX / 2 - 1);
598411d7 787 tipc_link_tnl_prepare(l, tnl, FAILOVER_MSG, xmitq);
655fb243 788 tipc_link_reset(l);
c8199300 789 tipc_link_fsm_evt(l, LINK_RESET_EVT);
662921cd 790 tipc_link_fsm_evt(l, LINK_FAILOVER_BEGIN_EVT);
598411d7 791 tipc_node_fsm_evt(n, NODE_FAILOVER_BEGIN_EVT);
38206d59 792 *maddr = &n->links[*bearer_id].maddr;
598411d7
JPM
793}
794
795static void tipc_node_link_down(struct tipc_node *n, int bearer_id, bool delete)
796{
797 struct tipc_link_entry *le = &n->links[bearer_id];
73f646ce 798 struct tipc_link *l = le->link;
598411d7
JPM
799 struct tipc_media_addr *maddr;
800 struct sk_buff_head xmitq;
35c55c98 801 int old_bearer_id = bearer_id;
598411d7 802
73f646ce
JPM
803 if (!l)
804 return;
805
598411d7
JPM
806 __skb_queue_head_init(&xmitq);
807
5405ff6e 808 tipc_node_write_lock(n);
73f646ce
JPM
809 if (!tipc_link_is_establishing(l)) {
810 __tipc_node_link_down(n, &bearer_id, &xmitq, &maddr);
811 if (delete) {
812 kfree(l);
813 le->link = NULL;
814 n->link_cnt--;
815 }
816 } else {
817 /* Defuse pending tipc_node_link_up() */
818 tipc_link_fsm_evt(l, LINK_RESET_EVT);
598411d7 819 }
5405ff6e 820 tipc_node_write_unlock(n);
35c55c98
JPM
821 if (delete)
822 tipc_mon_remove_peer(n->net, n->addr, old_bearer_id);
598411d7
JPM
823 tipc_bearer_xmit(n->net, bearer_id, &xmitq, maddr);
824 tipc_sk_rcv(n->net, &le->inputq);
b97bf3fd
PL
825}
826
38077b8e 827static bool node_is_up(struct tipc_node *n)
b97bf3fd 828{
36e78a46 829 return n->active_links[0] != INVALID_BEARER_ID;
b97bf3fd
PL
830}
831
38077b8e
JM
832bool tipc_node_is_up(struct net *net, u32 addr)
833{
834 struct tipc_node *n;
835 bool retval = false;
836
837 if (in_own_node(net, addr))
838 return true;
839
840 n = tipc_node_find(net, addr);
841 if (!n)
842 return false;
843 retval = node_is_up(n);
844 tipc_node_put(n);
845 return retval;
846}
847
25b0b9c4
JM
848static u32 tipc_node_suggest_addr(struct net *net, u32 addr)
849{
850 struct tipc_node *n;
851
852 addr ^= tipc_net(net)->random;
853 while ((n = tipc_node_find(net, addr))) {
854 tipc_node_put(n);
855 addr++;
856 }
857 return addr;
858}
859
860/* tipc_node_try_addr(): Check if addr can be used by peer, suggest other if not
861 */
862u32 tipc_node_try_addr(struct net *net, u8 *id, u32 addr)
863{
864 struct tipc_net *tn = tipc_net(net);
865 struct tipc_node *n;
866
867 /* Suggest new address if some other peer is using this one */
868 n = tipc_node_find(net, addr);
869 if (n) {
870 if (!memcmp(n->peer_id, id, NODE_ID_LEN))
871 addr = 0;
872 tipc_node_put(n);
873 if (!addr)
874 return 0;
875 return tipc_node_suggest_addr(net, addr);
876 }
877
878 /* Suggest previously used address if peer is known */
879 n = tipc_node_find_by_id(net, id);
880 if (n) {
881 addr = n->addr;
882 tipc_node_put(n);
883 }
884 /* Even this node may be in trial phase */
885 if (tn->trial_addr == addr)
886 return tipc_node_suggest_addr(net, addr);
887
888 return addr;
889}
890
891void tipc_node_check_dest(struct net *net, u32 addr,
892 u8 *peer_id, struct tipc_bearer *b,
cf148816
JPM
893 u16 capabilities, u32 signature,
894 struct tipc_media_addr *maddr,
895 bool *respond, bool *dupl_addr)
d3a43b90 896{
cf148816
JPM
897 struct tipc_node *n;
898 struct tipc_link *l;
440d8963 899 struct tipc_link_entry *le;
cf148816
JPM
900 bool addr_match = false;
901 bool sign_match = false;
902 bool link_up = false;
903 bool accept_addr = false;
598411d7 904 bool reset = true;
0e05498e 905 char *if_name;
5ca509fc 906 unsigned long intv;
440d8963 907
cf148816
JPM
908 *dupl_addr = false;
909 *respond = false;
910
25b0b9c4 911 n = tipc_node_create(net, addr, peer_id, capabilities);
cf148816
JPM
912 if (!n)
913 return;
d3a43b90 914
5405ff6e 915 tipc_node_write_lock(n);
cf148816 916
440d8963 917 le = &n->links[b->identity];
cf148816
JPM
918
919 /* Prepare to validate requesting node's signature and media address */
440d8963 920 l = le->link;
cf148816 921 link_up = l && tipc_link_is_up(l);
440d8963 922 addr_match = l && !memcmp(&le->maddr, maddr, sizeof(*maddr));
cf148816
JPM
923 sign_match = (signature == n->signature);
924
925 /* These three flags give us eight permutations: */
926
927 if (sign_match && addr_match && link_up) {
928 /* All is fine. Do nothing. */
598411d7 929 reset = false;
cf148816
JPM
930 } else if (sign_match && addr_match && !link_up) {
931 /* Respond. The link will come up in due time */
932 *respond = true;
933 } else if (sign_match && !addr_match && link_up) {
934 /* Peer has changed i/f address without rebooting.
935 * If so, the link will reset soon, and the next
936 * discovery will be accepted. So we can ignore it.
937 * It may also be an cloned or malicious peer having
938 * chosen the same node address and signature as an
939 * existing one.
940 * Ignore requests until the link goes down, if ever.
941 */
942 *dupl_addr = true;
943 } else if (sign_match && !addr_match && !link_up) {
944 /* Peer link has changed i/f address without rebooting.
945 * It may also be a cloned or malicious peer; we can't
946 * distinguish between the two.
947 * The signature is correct, so we must accept.
948 */
949 accept_addr = true;
950 *respond = true;
951 } else if (!sign_match && addr_match && link_up) {
952 /* Peer node rebooted. Two possibilities:
953 * - Delayed re-discovery; this link endpoint has already
954 * reset and re-established contact with the peer, before
955 * receiving a discovery message from that node.
956 * (The peer happened to receive one from this node first).
957 * - The peer came back so fast that our side has not
958 * discovered it yet. Probing from this side will soon
959 * reset the link, since there can be no working link
960 * endpoint at the peer end, and the link will re-establish.
961 * Accept the signature, since it comes from a known peer.
962 */
963 n->signature = signature;
964 } else if (!sign_match && addr_match && !link_up) {
965 /* The peer node has rebooted.
966 * Accept signature, since it is a known peer.
967 */
968 n->signature = signature;
969 *respond = true;
970 } else if (!sign_match && !addr_match && link_up) {
971 /* Peer rebooted with new address, or a new/duplicate peer.
972 * Ignore until the link goes down, if ever.
973 */
974 *dupl_addr = true;
975 } else if (!sign_match && !addr_match && !link_up) {
976 /* Peer rebooted with new address, or it is a new peer.
977 * Accept signature and address.
978 */
979 n->signature = signature;
980 accept_addr = true;
981 *respond = true;
982 }
d3a43b90 983
cf148816
JPM
984 if (!accept_addr)
985 goto exit;
d3a43b90 986
cf148816 987 /* Now create new link if not already existing */
8a1577c9 988 if (!l) {
20263641 989 if (n->link_cnt == 2)
440d8963 990 goto exit;
20263641 991
0e05498e 992 if_name = strchr(b->name, ':') + 1;
c72fa872 993 if (!tipc_link_create(net, if_name, b->identity, b->tolerance,
0e05498e
JPM
994 b->net_plane, b->mtu, b->priority,
995 b->window, mod(tipc_net(net)->random),
25b0b9c4 996 tipc_own_addr(net), addr, peer_id,
2af5ae37 997 n->capabilities,
52666986
JPM
998 tipc_bc_sndlink(n->net), n->bc_entry.link,
999 &le->inputq,
1000 &n->bc_entry.namedq, &l)) {
cf148816
JPM
1001 *respond = false;
1002 goto exit;
1003 }
440d8963 1004 tipc_link_reset(l);
c8199300 1005 tipc_link_fsm_evt(l, LINK_RESET_EVT);
17b20630
JPM
1006 if (n->state == NODE_FAILINGOVER)
1007 tipc_link_fsm_evt(l, LINK_FAILOVER_BEGIN_EVT);
440d8963
JPM
1008 le->link = l;
1009 n->link_cnt++;
8a1577c9 1010 tipc_node_calculate_timer(n, l);
5ca509fc
JPM
1011 if (n->link_cnt == 1) {
1012 intv = jiffies + msecs_to_jiffies(n->keepalive_intv);
1013 if (!mod_timer(&n->timer, intv))
8a1577c9 1014 tipc_node_get(n);
5ca509fc 1015 }
8a1577c9 1016 }
440d8963 1017 memcpy(&le->maddr, maddr, sizeof(*maddr));
cf148816 1018exit:
5405ff6e 1019 tipc_node_write_unlock(n);
2837f39c 1020 if (reset && l && !tipc_link_is_reset(l))
598411d7 1021 tipc_node_link_down(n, b->identity, false);
cf148816 1022 tipc_node_put(n);
d3a43b90
JPM
1023}
1024
6144a996
JPM
1025void tipc_node_delete_links(struct net *net, int bearer_id)
1026{
1027 struct tipc_net *tn = net_generic(net, tipc_net_id);
6144a996
JPM
1028 struct tipc_node *n;
1029
1030 rcu_read_lock();
1031 list_for_each_entry_rcu(n, &tn->node_list, list) {
598411d7 1032 tipc_node_link_down(n, bearer_id, true);
6144a996
JPM
1033 }
1034 rcu_read_unlock();
1035}
1036
1037static void tipc_node_reset_links(struct tipc_node *n)
1038{
598411d7 1039 int i;
6144a996 1040
d50ccc2d 1041 pr_warn("Resetting all links to %x\n", n->addr);
6144a996
JPM
1042
1043 for (i = 0; i < MAX_BEARERS; i++) {
598411d7 1044 tipc_node_link_down(n, i, false);
6144a996 1045 }
6144a996
JPM
1046}
1047
1a20cc25
JPM
1048/* tipc_node_fsm_evt - node finite state machine
1049 * Determines when contact is allowed with peer node
1050 */
d999297c 1051static void tipc_node_fsm_evt(struct tipc_node *n, int evt)
1a20cc25
JPM
1052{
1053 int state = n->state;
1054
1055 switch (state) {
1056 case SELF_DOWN_PEER_DOWN:
1057 switch (evt) {
1058 case SELF_ESTABL_CONTACT_EVT:
1059 state = SELF_UP_PEER_COMING;
1060 break;
1061 case PEER_ESTABL_CONTACT_EVT:
1062 state = SELF_COMING_PEER_UP;
1063 break;
1064 case SELF_LOST_CONTACT_EVT:
1065 case PEER_LOST_CONTACT_EVT:
1066 break;
66996b6c
JPM
1067 case NODE_SYNCH_END_EVT:
1068 case NODE_SYNCH_BEGIN_EVT:
1069 case NODE_FAILOVER_BEGIN_EVT:
1070 case NODE_FAILOVER_END_EVT:
1a20cc25 1071 default:
66996b6c 1072 goto illegal_evt;
1a20cc25
JPM
1073 }
1074 break;
1075 case SELF_UP_PEER_UP:
1076 switch (evt) {
1077 case SELF_LOST_CONTACT_EVT:
1078 state = SELF_DOWN_PEER_LEAVING;
1079 break;
1080 case PEER_LOST_CONTACT_EVT:
1081 state = SELF_LEAVING_PEER_DOWN;
1082 break;
66996b6c
JPM
1083 case NODE_SYNCH_BEGIN_EVT:
1084 state = NODE_SYNCHING;
1085 break;
1086 case NODE_FAILOVER_BEGIN_EVT:
1087 state = NODE_FAILINGOVER;
1088 break;
1a20cc25
JPM
1089 case SELF_ESTABL_CONTACT_EVT:
1090 case PEER_ESTABL_CONTACT_EVT:
66996b6c
JPM
1091 case NODE_SYNCH_END_EVT:
1092 case NODE_FAILOVER_END_EVT:
1a20cc25
JPM
1093 break;
1094 default:
66996b6c 1095 goto illegal_evt;
1a20cc25
JPM
1096 }
1097 break;
1098 case SELF_DOWN_PEER_LEAVING:
1099 switch (evt) {
1100 case PEER_LOST_CONTACT_EVT:
1101 state = SELF_DOWN_PEER_DOWN;
1102 break;
1103 case SELF_ESTABL_CONTACT_EVT:
1104 case PEER_ESTABL_CONTACT_EVT:
1105 case SELF_LOST_CONTACT_EVT:
1106 break;
66996b6c
JPM
1107 case NODE_SYNCH_END_EVT:
1108 case NODE_SYNCH_BEGIN_EVT:
1109 case NODE_FAILOVER_BEGIN_EVT:
1110 case NODE_FAILOVER_END_EVT:
1a20cc25 1111 default:
66996b6c 1112 goto illegal_evt;
1a20cc25
JPM
1113 }
1114 break;
1115 case SELF_UP_PEER_COMING:
1116 switch (evt) {
1117 case PEER_ESTABL_CONTACT_EVT:
1118 state = SELF_UP_PEER_UP;
1119 break;
1120 case SELF_LOST_CONTACT_EVT:
c4282ca7 1121 state = SELF_DOWN_PEER_DOWN;
1a20cc25
JPM
1122 break;
1123 case SELF_ESTABL_CONTACT_EVT:
1124 case PEER_LOST_CONTACT_EVT:
66996b6c 1125 case NODE_SYNCH_END_EVT:
66996b6c 1126 case NODE_FAILOVER_BEGIN_EVT:
73f646ce
JPM
1127 break;
1128 case NODE_SYNCH_BEGIN_EVT:
66996b6c 1129 case NODE_FAILOVER_END_EVT:
1a20cc25 1130 default:
66996b6c 1131 goto illegal_evt;
1a20cc25
JPM
1132 }
1133 break;
1134 case SELF_COMING_PEER_UP:
1135 switch (evt) {
1136 case SELF_ESTABL_CONTACT_EVT:
1137 state = SELF_UP_PEER_UP;
1138 break;
1139 case PEER_LOST_CONTACT_EVT:
c4282ca7 1140 state = SELF_DOWN_PEER_DOWN;
1a20cc25
JPM
1141 break;
1142 case SELF_LOST_CONTACT_EVT:
1143 case PEER_ESTABL_CONTACT_EVT:
1144 break;
66996b6c
JPM
1145 case NODE_SYNCH_END_EVT:
1146 case NODE_SYNCH_BEGIN_EVT:
1147 case NODE_FAILOVER_BEGIN_EVT:
1148 case NODE_FAILOVER_END_EVT:
1a20cc25 1149 default:
66996b6c 1150 goto illegal_evt;
1a20cc25
JPM
1151 }
1152 break;
1153 case SELF_LEAVING_PEER_DOWN:
1154 switch (evt) {
1155 case SELF_LOST_CONTACT_EVT:
1156 state = SELF_DOWN_PEER_DOWN;
1157 break;
1158 case SELF_ESTABL_CONTACT_EVT:
1159 case PEER_ESTABL_CONTACT_EVT:
1160 case PEER_LOST_CONTACT_EVT:
1161 break;
66996b6c
JPM
1162 case NODE_SYNCH_END_EVT:
1163 case NODE_SYNCH_BEGIN_EVT:
1164 case NODE_FAILOVER_BEGIN_EVT:
1165 case NODE_FAILOVER_END_EVT:
1166 default:
1167 goto illegal_evt;
1168 }
1169 break;
1170 case NODE_FAILINGOVER:
1171 switch (evt) {
1172 case SELF_LOST_CONTACT_EVT:
1173 state = SELF_DOWN_PEER_LEAVING;
1174 break;
1175 case PEER_LOST_CONTACT_EVT:
1176 state = SELF_LEAVING_PEER_DOWN;
1177 break;
1178 case NODE_FAILOVER_END_EVT:
1179 state = SELF_UP_PEER_UP;
1180 break;
1181 case NODE_FAILOVER_BEGIN_EVT:
1182 case SELF_ESTABL_CONTACT_EVT:
1183 case PEER_ESTABL_CONTACT_EVT:
1184 break;
1185 case NODE_SYNCH_BEGIN_EVT:
1186 case NODE_SYNCH_END_EVT:
1a20cc25 1187 default:
66996b6c
JPM
1188 goto illegal_evt;
1189 }
1190 break;
1191 case NODE_SYNCHING:
1192 switch (evt) {
1193 case SELF_LOST_CONTACT_EVT:
1194 state = SELF_DOWN_PEER_LEAVING;
1195 break;
1196 case PEER_LOST_CONTACT_EVT:
1197 state = SELF_LEAVING_PEER_DOWN;
1198 break;
1199 case NODE_SYNCH_END_EVT:
1200 state = SELF_UP_PEER_UP;
1201 break;
1202 case NODE_FAILOVER_BEGIN_EVT:
1203 state = NODE_FAILINGOVER;
1204 break;
1205 case NODE_SYNCH_BEGIN_EVT:
1206 case SELF_ESTABL_CONTACT_EVT:
1207 case PEER_ESTABL_CONTACT_EVT:
1208 break;
1209 case NODE_FAILOVER_END_EVT:
1210 default:
1211 goto illegal_evt;
1a20cc25
JPM
1212 }
1213 break;
1214 default:
1215 pr_err("Unknown node fsm state %x\n", state);
1216 break;
1217 }
1a20cc25 1218 n->state = state;
66996b6c
JPM
1219 return;
1220
1221illegal_evt:
1222 pr_err("Illegal node fsm evt %x in state %x\n", evt, state);
1a20cc25
JPM
1223}
1224
52666986 1225static void node_lost_contact(struct tipc_node *n,
598411d7 1226 struct sk_buff_head *inputq)
b97bf3fd 1227{
708ac32c 1228 struct tipc_sock_conn *conn, *safe;
598411d7 1229 struct tipc_link *l;
52666986 1230 struct list_head *conns = &n->conn_sks;
708ac32c 1231 struct sk_buff *skb;
708ac32c 1232 uint i;
b97bf3fd 1233
d50ccc2d 1234 pr_debug("Lost contact with %x\n", n->addr);
6a939f36 1235 n->delete_at = jiffies + msecs_to_jiffies(NODE_CLEANUP_AFTER);
c5bd4d85 1236
52666986 1237 /* Clean up broadcast state */
b06b281e 1238 tipc_bcast_remove_peer(n->net, n->bc_entry.link);
b97bf3fd 1239
dff29b1a 1240 /* Abort any ongoing link failover */
b97bf3fd 1241 for (i = 0; i < MAX_BEARERS; i++) {
52666986 1242 l = n->links[i].link;
598411d7
JPM
1243 if (l)
1244 tipc_link_fsm_evt(l, LINK_FAILOVER_END_EVT);
b97bf3fd 1245 }
598411d7 1246
708ac32c 1247 /* Notify publications from this node */
52666986 1248 n->action_flags |= TIPC_NOTIFY_NODE_DOWN;
708ac32c
JPM
1249
1250 /* Notify sockets connected to node */
1251 list_for_each_entry_safe(conn, safe, conns, list) {
1252 skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
52666986 1253 SHORT_H_SIZE, 0, tipc_own_addr(n->net),
708ac32c
JPM
1254 conn->peer_node, conn->port,
1255 conn->peer_port, TIPC_ERR_NO_NODE);
23d8335d 1256 if (likely(skb))
598411d7 1257 skb_queue_tail(inputq, skb);
708ac32c
JPM
1258 list_del(&conn->list);
1259 kfree(conn);
1260 }
b97bf3fd
PL
1261}
1262
78acb1f9
EH
1263/**
1264 * tipc_node_get_linkname - get the name of a link
1265 *
1266 * @bearer_id: id of the bearer
1267 * @node: peer node address
1268 * @linkname: link name output buffer
1269 *
1270 * Returns 0 on success
1271 */
f2f9800d
YX
1272int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 addr,
1273 char *linkname, size_t len)
78acb1f9
EH
1274{
1275 struct tipc_link *link;
8a0f6ebe 1276 int err = -EINVAL;
f2f9800d 1277 struct tipc_node *node = tipc_node_find(net, addr);
78acb1f9 1278
8a0f6ebe
YX
1279 if (!node)
1280 return err;
1281
1282 if (bearer_id >= MAX_BEARERS)
1283 goto exit;
1284
5405ff6e 1285 tipc_node_read_lock(node);
9d13ec65 1286 link = node->links[bearer_id].link;
78acb1f9 1287 if (link) {
38206d59 1288 strncpy(linkname, tipc_link_name(link), len);
8a0f6ebe 1289 err = 0;
78acb1f9 1290 }
5405ff6e 1291 tipc_node_read_unlock(node);
991ca84d 1292exit:
8a0f6ebe
YX
1293 tipc_node_put(node);
1294 return err;
78acb1f9 1295}
9db9fdd1 1296
3e4b6ab5 1297/* Caller should hold node lock for the passed node */
d8182804 1298static int __tipc_nl_add_node(struct tipc_nl_msg *msg, struct tipc_node *node)
3e4b6ab5
RA
1299{
1300 void *hdr;
1301 struct nlattr *attrs;
1302
bfb3e5dd 1303 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
3e4b6ab5
RA
1304 NLM_F_MULTI, TIPC_NL_NODE_GET);
1305 if (!hdr)
1306 return -EMSGSIZE;
1307
1308 attrs = nla_nest_start(msg->skb, TIPC_NLA_NODE);
1309 if (!attrs)
1310 goto msg_full;
1311
1312 if (nla_put_u32(msg->skb, TIPC_NLA_NODE_ADDR, node->addr))
1313 goto attr_msg_full;
38077b8e 1314 if (node_is_up(node))
3e4b6ab5
RA
1315 if (nla_put_flag(msg->skb, TIPC_NLA_NODE_UP))
1316 goto attr_msg_full;
1317
1318 nla_nest_end(msg->skb, attrs);
1319 genlmsg_end(msg->skb, hdr);
1320
1321 return 0;
1322
1323attr_msg_full:
1324 nla_nest_cancel(msg->skb, attrs);
1325msg_full:
1326 genlmsg_cancel(msg->skb, hdr);
1327
1328 return -EMSGSIZE;
1329}
1330
af9b028e
JPM
1331/**
1332 * tipc_node_xmit() is the general link level function for message sending
1333 * @net: the applicable net namespace
1334 * @list: chain of buffers containing message
1335 * @dnode: address of destination node
1336 * @selector: a number used for deterministic link selection
365ad353 1337 * Consumes the buffer chain.
4952cd3e 1338 * Returns 0 if success, otherwise: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE,-ENOBUF
af9b028e
JPM
1339 */
1340int tipc_node_xmit(struct net *net, struct sk_buff_head *list,
1341 u32 dnode, int selector)
1342{
5405ff6e 1343 struct tipc_link_entry *le = NULL;
af9b028e
JPM
1344 struct tipc_node *n;
1345 struct sk_buff_head xmitq;
4952cd3e
RA
1346 int bearer_id;
1347 int rc;
1348
1349 if (in_own_node(net, dnode)) {
1350 tipc_sk_rcv(net, list);
1351 return 0;
1352 }
af9b028e 1353
af9b028e 1354 n = tipc_node_find(net, dnode);
4952cd3e
RA
1355 if (unlikely(!n)) {
1356 skb_queue_purge(list);
1357 return -EHOSTUNREACH;
1358 }
1359
1360 tipc_node_read_lock(n);
1361 bearer_id = n->active_links[selector & 1];
1362 if (unlikely(bearer_id == INVALID_BEARER_ID)) {
5405ff6e 1363 tipc_node_read_unlock(n);
af9b028e 1364 tipc_node_put(n);
4952cd3e
RA
1365 skb_queue_purge(list);
1366 return -EHOSTUNREACH;
af9b028e 1367 }
5405ff6e 1368
4952cd3e
RA
1369 __skb_queue_head_init(&xmitq);
1370 le = &n->links[bearer_id];
1371 spin_lock_bh(&le->lock);
1372 rc = tipc_link_xmit(le->link, list, &xmitq);
1373 spin_unlock_bh(&le->lock);
1374 tipc_node_read_unlock(n);
1375
365ad353 1376 if (unlikely(rc == -ENOBUFS))
4952cd3e 1377 tipc_node_link_down(n, bearer_id, false);
365ad353
JPM
1378 else
1379 tipc_bearer_xmit(net, bearer_id, &xmitq, &le->maddr);
4952cd3e
RA
1380
1381 tipc_node_put(n);
1382
dc8d1eb3 1383 return rc;
af9b028e
JPM
1384}
1385
1386/* tipc_node_xmit_skb(): send single buffer to destination
1387 * Buffers sent via this functon are generally TIPC_SYSTEM_IMPORTANCE
1388 * messages, which will not be rejected
1389 * The only exception is datagram messages rerouted after secondary
1390 * lookup, which are rare and safe to dispose of anyway.
af9b028e
JPM
1391 */
1392int tipc_node_xmit_skb(struct net *net, struct sk_buff *skb, u32 dnode,
1393 u32 selector)
1394{
1395 struct sk_buff_head head;
af9b028e
JPM
1396
1397 skb_queue_head_init(&head);
1398 __skb_queue_tail(&head, skb);
365ad353 1399 tipc_node_xmit(net, &head, dnode, selector);
af9b028e
JPM
1400 return 0;
1401}
1402
f70d37b7
JM
1403/* tipc_node_distr_xmit(): send single buffer msgs to individual destinations
1404 * Note: this is only for SYSTEM_IMPORTANCE messages, which cannot be rejected
1405 */
1406int tipc_node_distr_xmit(struct net *net, struct sk_buff_head *xmitq)
1407{
1408 struct sk_buff *skb;
1409 u32 selector, dnode;
1410
1411 while ((skb = __skb_dequeue(xmitq))) {
1412 selector = msg_origport(buf_msg(skb));
1413 dnode = msg_destnode(buf_msg(skb));
1414 tipc_node_xmit_skb(net, skb, dnode, selector);
1415 }
1416 return 0;
1417}
1418
1d7e1c25
JPM
1419void tipc_node_broadcast(struct net *net, struct sk_buff *skb)
1420{
1421 struct sk_buff *txskb;
1422 struct tipc_node *n;
1423 u32 dst;
1424
1425 rcu_read_lock();
1426 list_for_each_entry_rcu(n, tipc_nodes(net), list) {
1427 dst = n->addr;
1428 if (in_own_node(net, dst))
1429 continue;
38077b8e 1430 if (!node_is_up(n))
1d7e1c25
JPM
1431 continue;
1432 txskb = pskb_copy(skb, GFP_ATOMIC);
1433 if (!txskb)
1434 break;
1435 msg_set_destnode(buf_msg(txskb), dst);
1436 tipc_node_xmit_skb(net, txskb, dst, 0);
1437 }
1438 rcu_read_unlock();
1439
1440 kfree_skb(skb);
1441}
1442
a853e4c6
JPM
1443static void tipc_node_mcast_rcv(struct tipc_node *n)
1444{
1445 struct tipc_bclink_entry *be = &n->bc_entry;
1446
1447 /* 'arrvq' is under inputq2's lock protection */
1448 spin_lock_bh(&be->inputq2.lock);
1449 spin_lock_bh(&be->inputq1.lock);
1450 skb_queue_splice_tail_init(&be->inputq1, &be->arrvq);
1451 spin_unlock_bh(&be->inputq1.lock);
1452 spin_unlock_bh(&be->inputq2.lock);
1453 tipc_sk_mcast_rcv(n->net, &be->arrvq, &be->inputq2);
1454}
1455
02d11ca2
JPM
1456static void tipc_node_bc_sync_rcv(struct tipc_node *n, struct tipc_msg *hdr,
1457 int bearer_id, struct sk_buff_head *xmitq)
1458{
1459 struct tipc_link *ucl;
1460 int rc;
1461
1462 rc = tipc_bcast_sync_rcv(n->net, n->bc_entry.link, hdr);
1463
1464 if (rc & TIPC_LINK_DOWN_EVT) {
40501f90 1465 tipc_node_reset_links(n);
02d11ca2
JPM
1466 return;
1467 }
1468
1469 if (!(rc & TIPC_LINK_SND_STATE))
1470 return;
1471
1472 /* If probe message, a STATE response will be sent anyway */
1473 if (msg_probe(hdr))
1474 return;
1475
1476 /* Produce a STATE message carrying broadcast NACK */
1477 tipc_node_read_lock(n);
1478 ucl = n->links[bearer_id].link;
1479 if (ucl)
1480 tipc_link_build_state_msg(ucl, xmitq);
1481 tipc_node_read_unlock(n);
1482}
1483
52666986
JPM
1484/**
1485 * tipc_node_bc_rcv - process TIPC broadcast packet arriving from off-node
1486 * @net: the applicable net namespace
1487 * @skb: TIPC packet
1488 * @bearer_id: id of bearer message arrived on
1489 *
1490 * Invoked with no locks held.
1491 */
742e0383 1492static void tipc_node_bc_rcv(struct net *net, struct sk_buff *skb, int bearer_id)
52666986
JPM
1493{
1494 int rc;
1495 struct sk_buff_head xmitq;
1496 struct tipc_bclink_entry *be;
1497 struct tipc_link_entry *le;
1498 struct tipc_msg *hdr = buf_msg(skb);
1499 int usr = msg_user(hdr);
1500 u32 dnode = msg_destnode(hdr);
1501 struct tipc_node *n;
1502
1503 __skb_queue_head_init(&xmitq);
1504
1505 /* If NACK for other node, let rcv link for that node peek into it */
1506 if ((usr == BCAST_PROTOCOL) && (dnode != tipc_own_addr(net)))
1507 n = tipc_node_find(net, dnode);
1508 else
1509 n = tipc_node_find(net, msg_prevnode(hdr));
1510 if (!n) {
1511 kfree_skb(skb);
1512 return;
1513 }
1514 be = &n->bc_entry;
1515 le = &n->links[bearer_id];
1516
1517 rc = tipc_bcast_rcv(net, be->link, skb);
1518
52666986 1519 /* Broadcast ACKs are sent on a unicast link */
02d11ca2 1520 if (rc & TIPC_LINK_SND_STATE) {
5405ff6e 1521 tipc_node_read_lock(n);
34b9cd64 1522 tipc_link_build_state_msg(le->link, &xmitq);
5405ff6e 1523 tipc_node_read_unlock(n);
52666986
JPM
1524 }
1525
1526 if (!skb_queue_empty(&xmitq))
1527 tipc_bearer_xmit(net, bearer_id, &xmitq, &le->maddr);
1528
a853e4c6
JPM
1529 if (!skb_queue_empty(&be->inputq1))
1530 tipc_node_mcast_rcv(n);
1fc07f3e 1531
40501f90
JPM
1532 /* If reassembly or retransmission failure => reset all links to peer */
1533 if (rc & TIPC_LINK_DOWN_EVT)
1534 tipc_node_reset_links(n);
1fc07f3e 1535
52666986
JPM
1536 tipc_node_put(n);
1537}
1538
6e498158
JPM
1539/**
1540 * tipc_node_check_state - check and if necessary update node state
1541 * @skb: TIPC packet
1542 * @bearer_id: identity of bearer delivering the packet
1543 * Returns true if state is ok, otherwise consumes buffer and returns false
6144a996 1544 */
6e498158 1545static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb,
662921cd 1546 int bearer_id, struct sk_buff_head *xmitq)
6144a996 1547{
6144a996 1548 struct tipc_msg *hdr = buf_msg(skb);
6e498158
JPM
1549 int usr = msg_user(hdr);
1550 int mtyp = msg_type(hdr);
6144a996 1551 u16 oseqno = msg_seqno(hdr);
6e498158
JPM
1552 u16 iseqno = msg_seqno(msg_get_wrapped(hdr));
1553 u16 exp_pkts = msg_msgcnt(hdr);
38206d59 1554 u16 rcv_nxt, syncpt, dlv_nxt, inputq_len;
6e498158 1555 int state = n->state;
2be80c2d 1556 struct tipc_link *l, *tnl, *pl = NULL;
598411d7 1557 struct tipc_media_addr *maddr;
38206d59 1558 int pb_id;
6144a996 1559
6e498158
JPM
1560 l = n->links[bearer_id].link;
1561 if (!l)
1562 return false;
38206d59 1563 rcv_nxt = tipc_link_rcv_nxt(l);
6144a996 1564
6144a996 1565
6e498158
JPM
1566 if (likely((state == SELF_UP_PEER_UP) && (usr != TUNNEL_PROTOCOL)))
1567 return true;
6144a996 1568
6e498158 1569 /* Find parallel link, if any */
38206d59
JPM
1570 for (pb_id = 0; pb_id < MAX_BEARERS; pb_id++) {
1571 if ((pb_id != bearer_id) && n->links[pb_id].link) {
1572 pl = n->links[pb_id].link;
6e498158
JPM
1573 break;
1574 }
1575 }
6144a996 1576
5405ff6e 1577 /* Check and update node accesibility if applicable */
6e498158
JPM
1578 if (state == SELF_UP_PEER_COMING) {
1579 if (!tipc_link_is_up(l))
1580 return true;
1581 if (!msg_peer_link_is_up(hdr))
1582 return true;
1583 tipc_node_fsm_evt(n, PEER_ESTABL_CONTACT_EVT);
1584 }
1585
1586 if (state == SELF_DOWN_PEER_LEAVING) {
1587 if (msg_peer_node_is_up(hdr))
1588 return false;
1589 tipc_node_fsm_evt(n, PEER_LOST_CONTACT_EVT);
5c10e979 1590 return true;
6e498158
JPM
1591 }
1592
5405ff6e
JPM
1593 if (state == SELF_LEAVING_PEER_DOWN)
1594 return false;
1595
6e498158 1596 /* Ignore duplicate packets */
0f8b8e28 1597 if ((usr != LINK_PROTOCOL) && less(oseqno, rcv_nxt))
6e498158
JPM
1598 return true;
1599
1600 /* Initiate or update failover mode if applicable */
1601 if ((usr == TUNNEL_PROTOCOL) && (mtyp == FAILOVER_MSG)) {
1602 syncpt = oseqno + exp_pkts - 1;
598411d7 1603 if (pl && tipc_link_is_up(pl)) {
598411d7 1604 __tipc_node_link_down(n, &pb_id, xmitq, &maddr);
38206d59
JPM
1605 tipc_skb_queue_splice_tail_init(tipc_link_inputq(pl),
1606 tipc_link_inputq(l));
598411d7 1607 }
6e498158
JPM
1608 /* If pkts arrive out of order, use lowest calculated syncpt */
1609 if (less(syncpt, n->sync_point))
1610 n->sync_point = syncpt;
1611 }
1612
1613 /* Open parallel link when tunnel link reaches synch point */
17b20630 1614 if ((n->state == NODE_FAILINGOVER) && tipc_link_is_up(l)) {
662921cd
JPM
1615 if (!more(rcv_nxt, n->sync_point))
1616 return true;
6e498158
JPM
1617 tipc_node_fsm_evt(n, NODE_FAILOVER_END_EVT);
1618 if (pl)
662921cd 1619 tipc_link_fsm_evt(pl, LINK_FAILOVER_END_EVT);
6e498158
JPM
1620 return true;
1621 }
1622
5ae2f8e6
JPM
1623 /* No synching needed if only one link */
1624 if (!pl || !tipc_link_is_up(pl))
1625 return true;
1626
0f8b8e28
JPM
1627 /* Initiate synch mode if applicable */
1628 if ((usr == TUNNEL_PROTOCOL) && (mtyp == SYNCH_MSG) && (oseqno == 1)) {
6e498158 1629 syncpt = iseqno + exp_pkts - 1;
ed43594a 1630 if (!tipc_link_is_up(l))
598411d7 1631 __tipc_node_link_up(n, bearer_id, xmitq);
6e498158
JPM
1632 if (n->state == SELF_UP_PEER_UP) {
1633 n->sync_point = syncpt;
662921cd 1634 tipc_link_fsm_evt(l, LINK_SYNCH_BEGIN_EVT);
6e498158
JPM
1635 tipc_node_fsm_evt(n, NODE_SYNCH_BEGIN_EVT);
1636 }
6144a996 1637 }
6e498158
JPM
1638
1639 /* Open tunnel link when parallel link reaches synch point */
5c10e979 1640 if (n->state == NODE_SYNCHING) {
2be80c2d
JPM
1641 if (tipc_link_is_synching(l)) {
1642 tnl = l;
1643 } else {
1644 tnl = pl;
1645 pl = l;
1646 }
38206d59
JPM
1647 inputq_len = skb_queue_len(tipc_link_inputq(pl));
1648 dlv_nxt = tipc_link_rcv_nxt(pl) - inputq_len;
5ae2f8e6 1649 if (more(dlv_nxt, n->sync_point)) {
2be80c2d 1650 tipc_link_fsm_evt(tnl, LINK_SYNCH_END_EVT);
6e498158 1651 tipc_node_fsm_evt(n, NODE_SYNCH_END_EVT);
6e498158
JPM
1652 return true;
1653 }
2be80c2d
JPM
1654 if (l == pl)
1655 return true;
6e498158
JPM
1656 if ((usr == TUNNEL_PROTOCOL) && (mtyp == SYNCH_MSG))
1657 return true;
1658 if (usr == LINK_PROTOCOL)
1659 return true;
1660 return false;
1661 }
1662 return true;
6144a996
JPM
1663}
1664
d999297c
JPM
1665/**
1666 * tipc_rcv - process TIPC packets/messages arriving from off-node
1667 * @net: the applicable net namespace
1668 * @skb: TIPC packet
1669 * @bearer: pointer to bearer message arrived on
1670 *
1671 * Invoked with no locks held. Bearer pointer must point to a valid bearer
1672 * structure (i.e. cannot be NULL), but bearer can be inactive.
1673 */
1674void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b)
1675{
1676 struct sk_buff_head xmitq;
1677 struct tipc_node *n;
681a55d7 1678 struct tipc_msg *hdr;
d999297c 1679 int bearer_id = b->identity;
6e498158 1680 struct tipc_link_entry *le;
efe79050 1681 u32 self = tipc_own_addr(net);
681a55d7
JPM
1682 int usr, rc = 0;
1683 u16 bc_ack;
d999297c
JPM
1684
1685 __skb_queue_head_init(&xmitq);
1686
681a55d7 1687 /* Ensure message is well-formed before touching the header */
d618d09a 1688 if (unlikely(!tipc_msg_validate(&skb)))
d999297c 1689 goto discard;
681a55d7
JPM
1690 hdr = buf_msg(skb);
1691 usr = msg_user(hdr);
1692 bc_ack = msg_bcast_ack(hdr);
d999297c 1693
52666986 1694 /* Handle arrival of discovery or broadcast packet */
d999297c 1695 if (unlikely(msg_non_seq(hdr))) {
52666986
JPM
1696 if (unlikely(usr == LINK_CONFIG))
1697 return tipc_disc_rcv(net, skb, b);
d999297c 1698 else
52666986 1699 return tipc_node_bc_rcv(net, skb, bearer_id);
d999297c
JPM
1700 }
1701
efe79050
HM
1702 /* Discard unicast link messages destined for another node */
1703 if (unlikely(!msg_short(hdr) && (msg_destnode(hdr) != self)))
1704 goto discard;
1705
d999297c
JPM
1706 /* Locate neighboring node that sent packet */
1707 n = tipc_node_find(net, msg_prevnode(hdr));
1708 if (unlikely(!n))
1709 goto discard;
6e498158 1710 le = &n->links[bearer_id];
d999297c 1711
52666986
JPM
1712 /* Ensure broadcast reception is in synch with peer's send state */
1713 if (unlikely(usr == LINK_PROTOCOL))
02d11ca2 1714 tipc_node_bc_sync_rcv(n, hdr, bearer_id, &xmitq);
38206d59 1715 else if (unlikely(tipc_link_acked(n->bc_entry.link) != bc_ack))
06bd2b1e 1716 tipc_bcast_ack_rcv(net, n->bc_entry.link, hdr);
52666986 1717
5405ff6e
JPM
1718 /* Receive packet directly if conditions permit */
1719 tipc_node_read_lock(n);
1720 if (likely((n->state == SELF_UP_PEER_UP) && (usr != TUNNEL_PROTOCOL))) {
2312bf61 1721 spin_lock_bh(&le->lock);
5405ff6e
JPM
1722 if (le->link) {
1723 rc = tipc_link_rcv(le->link, skb, &xmitq);
1724 skb = NULL;
1725 }
2312bf61 1726 spin_unlock_bh(&le->lock);
6e498158 1727 }
5405ff6e
JPM
1728 tipc_node_read_unlock(n);
1729
1730 /* Check/update node state before receiving */
1731 if (unlikely(skb)) {
27163138
PB
1732 if (unlikely(skb_linearize(skb)))
1733 goto discard;
5405ff6e
JPM
1734 tipc_node_write_lock(n);
1735 if (tipc_node_check_state(n, skb, bearer_id, &xmitq)) {
1736 if (le->link) {
1737 rc = tipc_link_rcv(le->link, skb, &xmitq);
1738 skb = NULL;
1739 }
1740 }
1741 tipc_node_write_unlock(n);
1742 }
d999297c
JPM
1743
1744 if (unlikely(rc & TIPC_LINK_UP_EVT))
6e498158
JPM
1745 tipc_node_link_up(n, bearer_id, &xmitq);
1746
d999297c 1747 if (unlikely(rc & TIPC_LINK_DOWN_EVT))
598411d7 1748 tipc_node_link_down(n, bearer_id, false);
6e498158 1749
52666986
JPM
1750 if (unlikely(!skb_queue_empty(&n->bc_entry.namedq)))
1751 tipc_named_rcv(net, &n->bc_entry.namedq);
23d8335d 1752
a853e4c6
JPM
1753 if (unlikely(!skb_queue_empty(&n->bc_entry.inputq1)))
1754 tipc_node_mcast_rcv(n);
1755
6e498158
JPM
1756 if (!skb_queue_empty(&le->inputq))
1757 tipc_sk_rcv(net, &le->inputq);
1758
1759 if (!skb_queue_empty(&xmitq))
1760 tipc_bearer_xmit(net, bearer_id, &xmitq, &le->maddr);
1761
d999297c
JPM
1762 tipc_node_put(n);
1763discard:
1764 kfree_skb(skb);
1765}
1766
682cd3cf
GM
1767void tipc_node_apply_property(struct net *net, struct tipc_bearer *b,
1768 int prop)
37c64cf6
JM
1769{
1770 struct tipc_net *tn = tipc_net(net);
1771 int bearer_id = b->identity;
1772 struct sk_buff_head xmitq;
1773 struct tipc_link_entry *e;
1774 struct tipc_node *n;
1775
1776 __skb_queue_head_init(&xmitq);
1777
1778 rcu_read_lock();
1779
1780 list_for_each_entry_rcu(n, &tn->node_list, list) {
1781 tipc_node_write_lock(n);
1782 e = &n->links[bearer_id];
682cd3cf
GM
1783 if (e->link) {
1784 if (prop == TIPC_NLA_PROP_TOL)
1785 tipc_link_set_tolerance(e->link, b->tolerance,
1786 &xmitq);
1787 else if (prop == TIPC_NLA_PROP_MTU)
1788 tipc_link_set_mtu(e->link, b->mtu);
1789 }
37c64cf6
JM
1790 tipc_node_write_unlock(n);
1791 tipc_bearer_xmit(net, bearer_id, &xmitq, &e->maddr);
1792 }
1793
1794 rcu_read_unlock();
1795}
1796
b3404022
RA
1797int tipc_nl_peer_rm(struct sk_buff *skb, struct genl_info *info)
1798{
1799 struct net *net = sock_net(skb->sk);
1800 struct tipc_net *tn = net_generic(net, tipc_net_id);
1801 struct nlattr *attrs[TIPC_NLA_NET_MAX + 1];
1802 struct tipc_node *peer;
1803 u32 addr;
1804 int err;
b3404022
RA
1805
1806 /* We identify the peer by its net */
1807 if (!info->attrs[TIPC_NLA_NET])
1808 return -EINVAL;
1809
1810 err = nla_parse_nested(attrs, TIPC_NLA_NET_MAX,
fceb6435 1811 info->attrs[TIPC_NLA_NET], tipc_nl_net_policy,
fe52145f 1812 info->extack);
b3404022
RA
1813 if (err)
1814 return err;
1815
1816 if (!attrs[TIPC_NLA_NET_ADDR])
1817 return -EINVAL;
1818
1819 addr = nla_get_u32(attrs[TIPC_NLA_NET_ADDR]);
1820
1821 if (in_own_node(net, addr))
1822 return -ENOTSUPP;
1823
1824 spin_lock_bh(&tn->node_list_lock);
1825 peer = tipc_node_find(net, addr);
1826 if (!peer) {
1827 spin_unlock_bh(&tn->node_list_lock);
1828 return -ENXIO;
1829 }
1830
1831 tipc_node_write_lock(peer);
1832 if (peer->state != SELF_DOWN_PEER_DOWN &&
1833 peer->state != SELF_DOWN_PEER_LEAVING) {
1834 tipc_node_write_unlock(peer);
1835 err = -EBUSY;
1836 goto err_out;
1837 }
1838
6a939f36 1839 tipc_node_clear_links(peer);
b3404022
RA
1840 tipc_node_write_unlock(peer);
1841 tipc_node_delete(peer);
1842
1843 err = 0;
1844err_out:
1845 tipc_node_put(peer);
1846 spin_unlock_bh(&tn->node_list_lock);
1847
1848 return err;
1849}
1850
3e4b6ab5
RA
1851int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb)
1852{
1853 int err;
f2f9800d
YX
1854 struct net *net = sock_net(skb->sk);
1855 struct tipc_net *tn = net_generic(net, tipc_net_id);
3e4b6ab5
RA
1856 int done = cb->args[0];
1857 int last_addr = cb->args[1];
1858 struct tipc_node *node;
1859 struct tipc_nl_msg msg;
1860
1861 if (done)
1862 return 0;
1863
1864 msg.skb = skb;
1865 msg.portid = NETLINK_CB(cb->skb).portid;
1866 msg.seq = cb->nlh->nlmsg_seq;
1867
1868 rcu_read_lock();
8a0f6ebe
YX
1869 if (last_addr) {
1870 node = tipc_node_find(net, last_addr);
1871 if (!node) {
1872 rcu_read_unlock();
1873 /* We never set seq or call nl_dump_check_consistent()
1874 * this means that setting prev_seq here will cause the
1875 * consistence check to fail in the netlink callback
1876 * handler. Resulting in the NLMSG_DONE message having
1877 * the NLM_F_DUMP_INTR flag set if the node state
1878 * changed while we released the lock.
1879 */
1880 cb->prev_seq = 1;
1881 return -EPIPE;
1882 }
1883 tipc_node_put(node);
3e4b6ab5
RA
1884 }
1885
f2f9800d 1886 list_for_each_entry_rcu(node, &tn->node_list, list) {
3e4b6ab5
RA
1887 if (last_addr) {
1888 if (node->addr == last_addr)
1889 last_addr = 0;
1890 else
1891 continue;
1892 }
1893
5405ff6e 1894 tipc_node_read_lock(node);
3e4b6ab5
RA
1895 err = __tipc_nl_add_node(&msg, node);
1896 if (err) {
1897 last_addr = node->addr;
5405ff6e 1898 tipc_node_read_unlock(node);
3e4b6ab5
RA
1899 goto out;
1900 }
1901
5405ff6e 1902 tipc_node_read_unlock(node);
3e4b6ab5
RA
1903 }
1904 done = 1;
1905out:
1906 cb->args[0] = done;
1907 cb->args[1] = last_addr;
1908 rcu_read_unlock();
1909
1910 return skb->len;
1911}
5be9c086 1912
38206d59 1913/* tipc_node_find_by_name - locate owner node of link by link's name
5be9c086
JPM
1914 * @net: the applicable net namespace
1915 * @name: pointer to link name string
1916 * @bearer_id: pointer to index in 'node->links' array where the link was found.
1917 *
1918 * Returns pointer to node owning the link, or 0 if no matching link is found.
1919 */
38206d59
JPM
1920static struct tipc_node *tipc_node_find_by_name(struct net *net,
1921 const char *link_name,
1922 unsigned int *bearer_id)
5be9c086
JPM
1923{
1924 struct tipc_net *tn = net_generic(net, tipc_net_id);
38206d59
JPM
1925 struct tipc_link *l;
1926 struct tipc_node *n;
5be9c086
JPM
1927 struct tipc_node *found_node = NULL;
1928 int i;
1929
1930 *bearer_id = 0;
1931 rcu_read_lock();
38206d59
JPM
1932 list_for_each_entry_rcu(n, &tn->node_list, list) {
1933 tipc_node_read_lock(n);
5be9c086 1934 for (i = 0; i < MAX_BEARERS; i++) {
38206d59
JPM
1935 l = n->links[i].link;
1936 if (l && !strcmp(tipc_link_name(l), link_name)) {
5be9c086 1937 *bearer_id = i;
38206d59 1938 found_node = n;
5be9c086
JPM
1939 break;
1940 }
1941 }
38206d59 1942 tipc_node_read_unlock(n);
5be9c086
JPM
1943 if (found_node)
1944 break;
1945 }
1946 rcu_read_unlock();
1947
1948 return found_node;
1949}
1950
1951int tipc_nl_node_set_link(struct sk_buff *skb, struct genl_info *info)
1952{
1953 int err;
1954 int res = 0;
1955 int bearer_id;
1956 char *name;
1957 struct tipc_link *link;
1958 struct tipc_node *node;
d01332f1 1959 struct sk_buff_head xmitq;
5be9c086
JPM
1960 struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1];
1961 struct net *net = sock_net(skb->sk);
1962
d01332f1
RA
1963 __skb_queue_head_init(&xmitq);
1964
5be9c086
JPM
1965 if (!info->attrs[TIPC_NLA_LINK])
1966 return -EINVAL;
1967
1968 err = nla_parse_nested(attrs, TIPC_NLA_LINK_MAX,
1969 info->attrs[TIPC_NLA_LINK],
fe52145f 1970 tipc_nl_link_policy, info->extack);
5be9c086
JPM
1971 if (err)
1972 return err;
1973
1974 if (!attrs[TIPC_NLA_LINK_NAME])
1975 return -EINVAL;
1976
1977 name = nla_data(attrs[TIPC_NLA_LINK_NAME]);
1978
1979 if (strcmp(name, tipc_bclink_name) == 0)
1980 return tipc_nl_bc_link_set(net, attrs);
1981
38206d59 1982 node = tipc_node_find_by_name(net, name, &bearer_id);
5be9c086
JPM
1983 if (!node)
1984 return -EINVAL;
1985
1986 tipc_node_read_lock(node);
1987
1988 link = node->links[bearer_id].link;
1989 if (!link) {
1990 res = -EINVAL;
1991 goto out;
1992 }
1993
1994 if (attrs[TIPC_NLA_LINK_PROP]) {
1995 struct nlattr *props[TIPC_NLA_PROP_MAX + 1];
1996
1997 err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_LINK_PROP],
1998 props);
1999 if (err) {
2000 res = err;
2001 goto out;
2002 }
2003
2004 if (props[TIPC_NLA_PROP_TOL]) {
2005 u32 tol;
2006
2007 tol = nla_get_u32(props[TIPC_NLA_PROP_TOL]);
d01332f1 2008 tipc_link_set_tolerance(link, tol, &xmitq);
5be9c086
JPM
2009 }
2010 if (props[TIPC_NLA_PROP_PRIO]) {
2011 u32 prio;
2012
2013 prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
d01332f1 2014 tipc_link_set_prio(link, prio, &xmitq);
5be9c086
JPM
2015 }
2016 if (props[TIPC_NLA_PROP_WIN]) {
2017 u32 win;
2018
2019 win = nla_get_u32(props[TIPC_NLA_PROP_WIN]);
2020 tipc_link_set_queue_limits(link, win);
2021 }
2022 }
2023
2024out:
2025 tipc_node_read_unlock(node);
d01332f1 2026 tipc_bearer_xmit(net, bearer_id, &xmitq, &node->links[bearer_id].maddr);
5be9c086
JPM
2027 return res;
2028}
2029
2030int tipc_nl_node_get_link(struct sk_buff *skb, struct genl_info *info)
2031{
2032 struct net *net = genl_info_net(info);
94f6a80c 2033 struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1];
5be9c086
JPM
2034 struct tipc_nl_msg msg;
2035 char *name;
2036 int err;
2037
2038 msg.portid = info->snd_portid;
2039 msg.seq = info->snd_seq;
2040
94f6a80c 2041 if (!info->attrs[TIPC_NLA_LINK])
5be9c086 2042 return -EINVAL;
94f6a80c
YX
2043
2044 err = nla_parse_nested(attrs, TIPC_NLA_LINK_MAX,
2045 info->attrs[TIPC_NLA_LINK],
2046 tipc_nl_link_policy, info->extack);
2047 if (err)
2048 return err;
2049
2050 if (!attrs[TIPC_NLA_LINK_NAME])
2051 return -EINVAL;
2052
2053 name = nla_data(attrs[TIPC_NLA_LINK_NAME]);
5be9c086
JPM
2054
2055 msg.skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
2056 if (!msg.skb)
2057 return -ENOMEM;
2058
2059 if (strcmp(name, tipc_bclink_name) == 0) {
2060 err = tipc_nl_add_bc_link(net, &msg);
59b36613
CW
2061 if (err)
2062 goto err_free;
5be9c086
JPM
2063 } else {
2064 int bearer_id;
2065 struct tipc_node *node;
2066 struct tipc_link *link;
2067
38206d59 2068 node = tipc_node_find_by_name(net, name, &bearer_id);
59b36613
CW
2069 if (!node) {
2070 err = -EINVAL;
2071 goto err_free;
2072 }
5be9c086
JPM
2073
2074 tipc_node_read_lock(node);
2075 link = node->links[bearer_id].link;
2076 if (!link) {
2077 tipc_node_read_unlock(node);
59b36613
CW
2078 err = -EINVAL;
2079 goto err_free;
5be9c086
JPM
2080 }
2081
2082 err = __tipc_nl_add_link(net, &msg, link, 0);
2083 tipc_node_read_unlock(node);
59b36613
CW
2084 if (err)
2085 goto err_free;
5be9c086
JPM
2086 }
2087
2088 return genlmsg_reply(msg.skb, info);
59b36613
CW
2089
2090err_free:
2091 nlmsg_free(msg.skb);
2092 return err;
5be9c086
JPM
2093}
2094
2095int tipc_nl_node_reset_link_stats(struct sk_buff *skb, struct genl_info *info)
2096{
2097 int err;
2098 char *link_name;
2099 unsigned int bearer_id;
2100 struct tipc_link *link;
2101 struct tipc_node *node;
2102 struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1];
2103 struct net *net = sock_net(skb->sk);
2104 struct tipc_link_entry *le;
2105
2106 if (!info->attrs[TIPC_NLA_LINK])
2107 return -EINVAL;
2108
2109 err = nla_parse_nested(attrs, TIPC_NLA_LINK_MAX,
2110 info->attrs[TIPC_NLA_LINK],
fe52145f 2111 tipc_nl_link_policy, info->extack);
5be9c086
JPM
2112 if (err)
2113 return err;
2114
2115 if (!attrs[TIPC_NLA_LINK_NAME])
2116 return -EINVAL;
2117
2118 link_name = nla_data(attrs[TIPC_NLA_LINK_NAME]);
2119
2120 if (strcmp(link_name, tipc_bclink_name) == 0) {
2121 err = tipc_bclink_reset_stats(net);
2122 if (err)
2123 return err;
2124 return 0;
2125 }
2126
38206d59 2127 node = tipc_node_find_by_name(net, link_name, &bearer_id);
5be9c086
JPM
2128 if (!node)
2129 return -EINVAL;
2130
2131 le = &node->links[bearer_id];
2132 tipc_node_read_lock(node);
2133 spin_lock_bh(&le->lock);
2134 link = node->links[bearer_id].link;
2135 if (!link) {
2136 spin_unlock_bh(&le->lock);
2137 tipc_node_read_unlock(node);
2138 return -EINVAL;
2139 }
38206d59 2140 tipc_link_reset_stats(link);
5be9c086
JPM
2141 spin_unlock_bh(&le->lock);
2142 tipc_node_read_unlock(node);
2143 return 0;
2144}
2145
2146/* Caller should hold node lock */
2147static int __tipc_nl_add_node_links(struct net *net, struct tipc_nl_msg *msg,
2148 struct tipc_node *node, u32 *prev_link)
2149{
2150 u32 i;
2151 int err;
2152
2153 for (i = *prev_link; i < MAX_BEARERS; i++) {
2154 *prev_link = i;
2155
2156 if (!node->links[i].link)
2157 continue;
2158
2159 err = __tipc_nl_add_link(net, msg,
2160 node->links[i].link, NLM_F_MULTI);
2161 if (err)
2162 return err;
2163 }
2164 *prev_link = 0;
2165
2166 return 0;
2167}
2168
38206d59 2169int tipc_nl_node_dump_link(struct sk_buff *skb, struct netlink_callback *cb)
5be9c086
JPM
2170{
2171 struct net *net = sock_net(skb->sk);
2172 struct tipc_net *tn = net_generic(net, tipc_net_id);
2173 struct tipc_node *node;
2174 struct tipc_nl_msg msg;
2175 u32 prev_node = cb->args[0];
2176 u32 prev_link = cb->args[1];
2177 int done = cb->args[2];
2178 int err;
2179
2180 if (done)
2181 return 0;
2182
2183 msg.skb = skb;
2184 msg.portid = NETLINK_CB(cb->skb).portid;
2185 msg.seq = cb->nlh->nlmsg_seq;
2186
2187 rcu_read_lock();
2188 if (prev_node) {
2189 node = tipc_node_find(net, prev_node);
2190 if (!node) {
2191 /* We never set seq or call nl_dump_check_consistent()
2192 * this means that setting prev_seq here will cause the
2193 * consistence check to fail in the netlink callback
2194 * handler. Resulting in the last NLMSG_DONE message
2195 * having the NLM_F_DUMP_INTR flag set.
2196 */
2197 cb->prev_seq = 1;
2198 goto out;
2199 }
2200 tipc_node_put(node);
2201
2202 list_for_each_entry_continue_rcu(node, &tn->node_list,
2203 list) {
2204 tipc_node_read_lock(node);
2205 err = __tipc_nl_add_node_links(net, &msg, node,
2206 &prev_link);
2207 tipc_node_read_unlock(node);
2208 if (err)
2209 goto out;
2210
2211 prev_node = node->addr;
2212 }
2213 } else {
2214 err = tipc_nl_add_bc_link(net, &msg);
2215 if (err)
2216 goto out;
2217
2218 list_for_each_entry_rcu(node, &tn->node_list, list) {
2219 tipc_node_read_lock(node);
2220 err = __tipc_nl_add_node_links(net, &msg, node,
2221 &prev_link);
2222 tipc_node_read_unlock(node);
2223 if (err)
2224 goto out;
2225
2226 prev_node = node->addr;
2227 }
2228 }
2229 done = 1;
2230out:
2231 rcu_read_unlock();
2232
2233 cb->args[0] = prev_node;
2234 cb->args[1] = prev_link;
2235 cb->args[2] = done;
2236
2237 return skb->len;
2238}
7b3f5229
PB
2239
2240int tipc_nl_node_set_monitor(struct sk_buff *skb, struct genl_info *info)
2241{
2242 struct nlattr *attrs[TIPC_NLA_MON_MAX + 1];
2243 struct net *net = sock_net(skb->sk);
2244 int err;
2245
2246 if (!info->attrs[TIPC_NLA_MON])
2247 return -EINVAL;
2248
2249 err = nla_parse_nested(attrs, TIPC_NLA_MON_MAX,
2250 info->attrs[TIPC_NLA_MON],
fe52145f 2251 tipc_nl_monitor_policy, info->extack);
7b3f5229
PB
2252 if (err)
2253 return err;
2254
2255 if (attrs[TIPC_NLA_MON_ACTIVATION_THRESHOLD]) {
2256 u32 val;
2257
2258 val = nla_get_u32(attrs[TIPC_NLA_MON_ACTIVATION_THRESHOLD]);
2259 err = tipc_nl_monitor_set_threshold(net, val);
2260 if (err)
2261 return err;
2262 }
2263
2264 return 0;
2265}
bf1035b2
PB
2266
2267static int __tipc_nl_add_monitor_prop(struct net *net, struct tipc_nl_msg *msg)
2268{
2269 struct nlattr *attrs;
2270 void *hdr;
2271 u32 val;
2272
2273 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
2274 0, TIPC_NL_MON_GET);
2275 if (!hdr)
2276 return -EMSGSIZE;
2277
2278 attrs = nla_nest_start(msg->skb, TIPC_NLA_MON);
2279 if (!attrs)
2280 goto msg_full;
2281
2282 val = tipc_nl_monitor_get_threshold(net);
2283
2284 if (nla_put_u32(msg->skb, TIPC_NLA_MON_ACTIVATION_THRESHOLD, val))
2285 goto attr_msg_full;
2286
2287 nla_nest_end(msg->skb, attrs);
2288 genlmsg_end(msg->skb, hdr);
2289
2290 return 0;
2291
2292attr_msg_full:
2293 nla_nest_cancel(msg->skb, attrs);
2294msg_full:
2295 genlmsg_cancel(msg->skb, hdr);
2296
2297 return -EMSGSIZE;
2298}
2299
2300int tipc_nl_node_get_monitor(struct sk_buff *skb, struct genl_info *info)
2301{
2302 struct net *net = sock_net(skb->sk);
2303 struct tipc_nl_msg msg;
2304 int err;
2305
2306 msg.skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
78302fd4
PB
2307 if (!msg.skb)
2308 return -ENOMEM;
bf1035b2
PB
2309 msg.portid = info->snd_portid;
2310 msg.seq = info->snd_seq;
2311
2312 err = __tipc_nl_add_monitor_prop(net, &msg);
2313 if (err) {
2314 nlmsg_free(msg.skb);
2315 return err;
2316 }
2317
2318 return genlmsg_reply(msg.skb, info);
2319}
cf6f7e1d
PB
2320
2321int tipc_nl_node_dump_monitor(struct sk_buff *skb, struct netlink_callback *cb)
2322{
2323 struct net *net = sock_net(skb->sk);
2324 u32 prev_bearer = cb->args[0];
2325 struct tipc_nl_msg msg;
36a50a98 2326 int bearer_id;
cf6f7e1d 2327 int err;
cf6f7e1d
PB
2328
2329 if (prev_bearer == MAX_BEARERS)
2330 return 0;
2331
2332 msg.skb = skb;
2333 msg.portid = NETLINK_CB(cb->skb).portid;
2334 msg.seq = cb->nlh->nlmsg_seq;
2335
2336 rtnl_lock();
36a50a98 2337 for (bearer_id = prev_bearer; bearer_id < MAX_BEARERS; bearer_id++) {
7dbc73e6 2338 err = __tipc_nl_add_monitor(net, &msg, bearer_id);
cf6f7e1d 2339 if (err)
36a50a98 2340 break;
cf6f7e1d 2341 }
cf6f7e1d 2342 rtnl_unlock();
36a50a98 2343 cb->args[0] = bearer_id;
cf6f7e1d
PB
2344
2345 return skb->len;
2346}
2347
2348int tipc_nl_node_dump_monitor_peer(struct sk_buff *skb,
2349 struct netlink_callback *cb)
2350{
2351 struct net *net = sock_net(skb->sk);
2352 u32 prev_node = cb->args[1];
2353 u32 bearer_id = cb->args[2];
2354 int done = cb->args[0];
2355 struct tipc_nl_msg msg;
2356 int err;
2357
2358 if (!prev_node) {
2359 struct nlattr **attrs;
2360 struct nlattr *mon[TIPC_NLA_MON_MAX + 1];
2361
2362 err = tipc_nlmsg_parse(cb->nlh, &attrs);
2363 if (err)
2364 return err;
2365
2366 if (!attrs[TIPC_NLA_MON])
2367 return -EINVAL;
2368
2369 err = nla_parse_nested(mon, TIPC_NLA_MON_MAX,
2370 attrs[TIPC_NLA_MON],
fceb6435 2371 tipc_nl_monitor_policy, NULL);
cf6f7e1d
PB
2372 if (err)
2373 return err;
2374
2375 if (!mon[TIPC_NLA_MON_REF])
2376 return -EINVAL;
2377
2378 bearer_id = nla_get_u32(mon[TIPC_NLA_MON_REF]);
2379
2380 if (bearer_id >= MAX_BEARERS)
2381 return -EINVAL;
2382 }
2383
2384 if (done)
2385 return 0;
2386
2387 msg.skb = skb;
2388 msg.portid = NETLINK_CB(cb->skb).portid;
2389 msg.seq = cb->nlh->nlmsg_seq;
2390
2391 rtnl_lock();
2392 err = tipc_nl_add_monitor_peer(net, &msg, bearer_id, &prev_node);
2393 if (!err)
2394 done = 1;
2395
2396 rtnl_unlock();
2397 cb->args[0] = done;
2398 cb->args[1] = prev_node;
2399 cb->args[2] = bearer_id;
2400
2401 return skb->len;
2402}