tipc: make bearer list support net namespace
[linux-2.6-block.git] / net / tipc / link.c
CommitLineData
b97bf3fd
PL
1/*
2 * net/tipc/link.c: TIPC link code
c4307285 3 *
170b3927 4 * Copyright (c) 1996-2007, 2012-2014, Ericsson AB
198d73b8 5 * Copyright (c) 2004-2007, 2010-2013, 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"
b97bf3fd 38#include "link.h"
7be57fc6 39#include "bcast.h"
9816f061 40#include "socket.h"
b97bf3fd 41#include "name_distr.h"
b97bf3fd
PL
42#include "discover.h"
43#include "config.h"
0655f6a8 44#include "netlink.h"
b97bf3fd 45
796c75d0
YX
46#include <linux/pkt_sched.h>
47
2cf8aa19
EH
48/*
49 * Error message prefixes
50 */
51static const char *link_co_err = "Link changeover error, ";
52static const char *link_rst_msg = "Resetting link ";
53static const char *link_unk_evt = "Unknown link event ";
b97bf3fd 54
7be57fc6
RA
55static const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = {
56 [TIPC_NLA_LINK_UNSPEC] = { .type = NLA_UNSPEC },
57 [TIPC_NLA_LINK_NAME] = {
58 .type = NLA_STRING,
59 .len = TIPC_MAX_LINK_NAME
60 },
61 [TIPC_NLA_LINK_MTU] = { .type = NLA_U32 },
62 [TIPC_NLA_LINK_BROADCAST] = { .type = NLA_FLAG },
63 [TIPC_NLA_LINK_UP] = { .type = NLA_FLAG },
64 [TIPC_NLA_LINK_ACTIVE] = { .type = NLA_FLAG },
65 [TIPC_NLA_LINK_PROP] = { .type = NLA_NESTED },
66 [TIPC_NLA_LINK_STATS] = { .type = NLA_NESTED },
67 [TIPC_NLA_LINK_RX] = { .type = NLA_U32 },
68 [TIPC_NLA_LINK_TX] = { .type = NLA_U32 }
69};
70
0655f6a8
RA
71/* Properties valid for media, bearar and link */
72static const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = {
73 [TIPC_NLA_PROP_UNSPEC] = { .type = NLA_UNSPEC },
74 [TIPC_NLA_PROP_PRIO] = { .type = NLA_U32 },
75 [TIPC_NLA_PROP_TOL] = { .type = NLA_U32 },
76 [TIPC_NLA_PROP_WIN] = { .type = NLA_U32 }
77};
78
a686e685
AS
79/*
80 * Out-of-range value for link session numbers
81 */
a686e685
AS
82#define INVALID_SESSION 0x10000
83
c4307285
YH
84/*
85 * Link state events:
b97bf3fd 86 */
b97bf3fd
PL
87#define STARTING_EVT 856384768 /* link processing trigger */
88#define TRAFFIC_MSG_EVT 560815u /* rx'd ??? */
89#define TIMEOUT_EVT 560817u /* link timer expired */
90
c4307285
YH
91/*
92 * The following two 'message types' is really just implementation
93 * data conveniently stored in the message header.
b97bf3fd
PL
94 * They must not be considered part of the protocol
95 */
96#define OPEN_MSG 0
97#define CLOSED_MSG 1
98
c4307285 99/*
b97bf3fd
PL
100 * State value stored in 'exp_msg_count'
101 */
b97bf3fd
PL
102#define START_CHANGEOVER 100000u
103
c93d3baa
YX
104static void link_handle_out_of_seq_msg(struct net *net,
105 struct tipc_link *l_ptr,
b97bf3fd 106 struct sk_buff *buf);
c93d3baa
YX
107static void tipc_link_proto_rcv(struct net *net, struct tipc_link *l_ptr,
108 struct sk_buff *buf);
109static int tipc_link_tunnel_rcv(struct net *net, struct tipc_node *n_ptr,
170b3927 110 struct sk_buff **buf);
2f55c437 111static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tol);
a18c4bc3
PG
112static void link_state_event(struct tipc_link *l_ptr, u32 event);
113static void link_reset_statistics(struct tipc_link *l_ptr);
114static void link_print(struct tipc_link *l_ptr, const char *str);
247f0f3c
YX
115static void tipc_link_sync_xmit(struct tipc_link *l);
116static void tipc_link_sync_rcv(struct tipc_node *n, struct sk_buff *buf);
f2f9800d
YX
117static int tipc_link_input(struct net *net, struct tipc_link *l,
118 struct sk_buff *buf);
c93d3baa
YX
119static int tipc_link_prepare_input(struct net *net, struct tipc_link *l,
120 struct sk_buff **buf);
31e3c3f6 121
b97bf3fd 122/*
05790c64 123 * Simple link routines
b97bf3fd 124 */
05790c64 125static unsigned int align(unsigned int i)
b97bf3fd
PL
126{
127 return (i + 3) & ~3u;
128}
129
a18c4bc3 130static void link_init_max_pkt(struct tipc_link *l_ptr)
b97bf3fd 131{
7f9f95d9
YX
132 struct tipc_node *node = l_ptr->owner;
133 struct tipc_net *tn = net_generic(node->net, tipc_net_id);
7a2f7d18 134 struct tipc_bearer *b_ptr;
b97bf3fd 135 u32 max_pkt;
c4307285 136
7a2f7d18 137 rcu_read_lock();
7f9f95d9 138 b_ptr = rcu_dereference_rtnl(tn->bearer_list[l_ptr->bearer_id]);
7a2f7d18
YX
139 if (!b_ptr) {
140 rcu_read_unlock();
141 return;
142 }
143 max_pkt = (b_ptr->mtu & ~3);
144 rcu_read_unlock();
145
b97bf3fd
PL
146 if (max_pkt > MAX_MSG_SIZE)
147 max_pkt = MAX_MSG_SIZE;
148
c4307285 149 l_ptr->max_pkt_target = max_pkt;
b97bf3fd
PL
150 if (l_ptr->max_pkt_target < MAX_PKT_DEFAULT)
151 l_ptr->max_pkt = l_ptr->max_pkt_target;
c4307285 152 else
b97bf3fd
PL
153 l_ptr->max_pkt = MAX_PKT_DEFAULT;
154
c4307285 155 l_ptr->max_pkt_probes = 0;
b97bf3fd
PL
156}
157
b97bf3fd 158/*
05790c64 159 * Simple non-static link routines (i.e. referenced outside this file)
b97bf3fd 160 */
a18c4bc3 161int tipc_link_is_up(struct tipc_link *l_ptr)
b97bf3fd
PL
162{
163 if (!l_ptr)
164 return 0;
a02cec21 165 return link_working_working(l_ptr) || link_working_unknown(l_ptr);
b97bf3fd
PL
166}
167
a18c4bc3 168int tipc_link_is_active(struct tipc_link *l_ptr)
b97bf3fd 169{
a02cec21
ED
170 return (l_ptr->owner->active_links[0] == l_ptr) ||
171 (l_ptr->owner->active_links[1] == l_ptr);
b97bf3fd
PL
172}
173
b97bf3fd
PL
174/**
175 * link_timeout - handle expiration of link timer
176 * @l_ptr: pointer to link
b97bf3fd 177 */
2f55c437 178static void link_timeout(unsigned long data)
b97bf3fd 179{
2f55c437 180 struct tipc_link *l_ptr = (struct tipc_link *)data;
58dc55f2
YX
181 struct sk_buff *skb;
182
4323add6 183 tipc_node_lock(l_ptr->owner);
b97bf3fd
PL
184
185 /* update counters used in statistical profiling of send traffic */
58dc55f2 186 l_ptr->stats.accu_queue_sz += skb_queue_len(&l_ptr->outqueue);
b97bf3fd
PL
187 l_ptr->stats.queue_sz_counts++;
188
58dc55f2
YX
189 skb = skb_peek(&l_ptr->outqueue);
190 if (skb) {
191 struct tipc_msg *msg = buf_msg(skb);
b97bf3fd
PL
192 u32 length = msg_size(msg);
193
f64f9e71
JP
194 if ((msg_user(msg) == MSG_FRAGMENTER) &&
195 (msg_type(msg) == FIRST_FRAGMENT)) {
b97bf3fd
PL
196 length = msg_size(msg_get_wrapped(msg));
197 }
198 if (length) {
199 l_ptr->stats.msg_lengths_total += length;
200 l_ptr->stats.msg_length_counts++;
201 if (length <= 64)
202 l_ptr->stats.msg_length_profile[0]++;
203 else if (length <= 256)
204 l_ptr->stats.msg_length_profile[1]++;
205 else if (length <= 1024)
206 l_ptr->stats.msg_length_profile[2]++;
207 else if (length <= 4096)
208 l_ptr->stats.msg_length_profile[3]++;
209 else if (length <= 16384)
210 l_ptr->stats.msg_length_profile[4]++;
211 else if (length <= 32768)
212 l_ptr->stats.msg_length_profile[5]++;
213 else
214 l_ptr->stats.msg_length_profile[6]++;
215 }
216 }
217
218 /* do all other link processing performed on a periodic basis */
b97bf3fd
PL
219 link_state_event(l_ptr, TIMEOUT_EVT);
220
221 if (l_ptr->next_out)
47b4c9a8 222 tipc_link_push_packets(l_ptr);
b97bf3fd 223
4323add6 224 tipc_node_unlock(l_ptr->owner);
b97bf3fd
PL
225}
226
2f55c437 227static void link_set_timer(struct tipc_link *link, unsigned long time)
b97bf3fd 228{
2f55c437 229 mod_timer(&link->timer, jiffies + time);
b97bf3fd
PL
230}
231
232/**
4323add6 233 * tipc_link_create - create a new link
37b9c08a 234 * @n_ptr: pointer to associated node
b97bf3fd 235 * @b_ptr: pointer to associated bearer
b97bf3fd 236 * @media_addr: media address to use when sending messages over link
c4307285 237 *
b97bf3fd
PL
238 * Returns pointer to link.
239 */
a18c4bc3 240struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
c61dd61d
YX
241 struct tipc_bearer *b_ptr,
242 const struct tipc_media_addr *media_addr)
b97bf3fd 243{
a18c4bc3 244 struct tipc_link *l_ptr;
b97bf3fd
PL
245 struct tipc_msg *msg;
246 char *if_name;
37b9c08a
AS
247 char addr_string[16];
248 u32 peer = n_ptr->addr;
249
0372bf5c 250 if (n_ptr->link_cnt >= MAX_BEARERS) {
37b9c08a 251 tipc_addr_string_fill(addr_string, n_ptr->addr);
0372bf5c
HB
252 pr_err("Attempt to establish %uth link to %s. Max %u allowed.\n",
253 n_ptr->link_cnt, addr_string, MAX_BEARERS);
37b9c08a
AS
254 return NULL;
255 }
256
257 if (n_ptr->links[b_ptr->identity]) {
258 tipc_addr_string_fill(addr_string, n_ptr->addr);
2cf8aa19
EH
259 pr_err("Attempt to establish second link on <%s> to %s\n",
260 b_ptr->name, addr_string);
37b9c08a
AS
261 return NULL;
262 }
b97bf3fd 263
0da974f4 264 l_ptr = kzalloc(sizeof(*l_ptr), GFP_ATOMIC);
b97bf3fd 265 if (!l_ptr) {
2cf8aa19 266 pr_warn("Link creation failed, no memory\n");
b97bf3fd
PL
267 return NULL;
268 }
b97bf3fd
PL
269
270 l_ptr->addr = peer;
2d627b92 271 if_name = strchr(b_ptr->name, ':') + 1;
062b4c99 272 sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:unknown",
b97bf3fd 273 tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr),
c4307285 274 tipc_node(tipc_own_addr),
b97bf3fd
PL
275 if_name,
276 tipc_zone(peer), tipc_cluster(peer), tipc_node(peer));
062b4c99 277 /* note: peer i/f name is updated by reset/activate message */
b97bf3fd 278 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr));
37b9c08a 279 l_ptr->owner = n_ptr;
b97bf3fd 280 l_ptr->checkpoint = 1;
f882cb76 281 l_ptr->peer_session = INVALID_SESSION;
7a2f7d18 282 l_ptr->bearer_id = b_ptr->identity;
5c216e1d 283 link_set_supervision_props(l_ptr, b_ptr->tolerance);
b97bf3fd
PL
284 l_ptr->state = RESET_UNKNOWN;
285
286 l_ptr->pmsg = (struct tipc_msg *)&l_ptr->proto_msg;
287 msg = l_ptr->pmsg;
c68ca7b7 288 tipc_msg_init(msg, LINK_PROTOCOL, RESET_MSG, INT_H_SIZE, l_ptr->addr);
b97bf3fd 289 msg_set_size(msg, sizeof(l_ptr->proto_msg));
a686e685 290 msg_set_session(msg, (tipc_random & 0xffff));
b97bf3fd
PL
291 msg_set_bearer_id(msg, b_ptr->identity);
292 strcpy((char *)msg_data(msg), if_name);
293
294 l_ptr->priority = b_ptr->priority;
5c216e1d 295 tipc_link_set_queue_limits(l_ptr, b_ptr->window);
b97bf3fd 296
7a2f7d18 297 l_ptr->net_plane = b_ptr->net_plane;
b97bf3fd
PL
298 link_init_max_pkt(l_ptr);
299
300 l_ptr->next_out_no = 1;
58dc55f2 301 __skb_queue_head_init(&l_ptr->outqueue);
bc6fecd4 302 __skb_queue_head_init(&l_ptr->deferred_queue);
340b6e59 303 skb_queue_head_init(&l_ptr->waiting_sks);
b97bf3fd
PL
304
305 link_reset_statistics(l_ptr);
306
37b9c08a 307 tipc_node_attach_link(n_ptr, l_ptr);
b97bf3fd 308
2f55c437 309 setup_timer(&l_ptr->timer, link_timeout, (unsigned long)l_ptr);
581465fa
JPM
310
311 link_state_event(l_ptr, STARTING_EVT);
b97bf3fd 312
b97bf3fd
PL
313 return l_ptr;
314}
315
f2f9800d
YX
316void tipc_link_delete_list(struct net *net, unsigned int bearer_id,
317 bool shutting_down)
8d8439b6 318{
f2f9800d 319 struct tipc_net *tn = net_generic(net, tipc_net_id);
8d8439b6 320 struct tipc_link *l_ptr;
c61dd61d 321 struct tipc_node *n_ptr;
8d8439b6 322
6c7a762e 323 rcu_read_lock();
f2f9800d 324 list_for_each_entry_rcu(n_ptr, &tn->node_list, list) {
5356f3d7 325 tipc_node_lock(n_ptr);
c61dd61d
YX
326 l_ptr = n_ptr->links[bearer_id];
327 if (l_ptr) {
328 tipc_link_reset(l_ptr);
7d33939f
JPM
329 if (shutting_down || !tipc_node_is_up(n_ptr)) {
330 tipc_node_detach_link(l_ptr->owner, l_ptr);
331 tipc_link_reset_fragments(l_ptr);
5356f3d7 332 tipc_node_unlock(n_ptr);
7d33939f
JPM
333
334 /* Nobody else can access this link now: */
335 del_timer_sync(&l_ptr->timer);
336 kfree(l_ptr);
337 } else {
338 /* Detach/delete when failover is finished: */
339 l_ptr->flags |= LINK_STOPPED;
5356f3d7 340 tipc_node_unlock(n_ptr);
7d33939f
JPM
341 del_timer_sync(&l_ptr->timer);
342 }
c61dd61d
YX
343 continue;
344 }
5356f3d7 345 tipc_node_unlock(n_ptr);
8d8439b6 346 }
6c7a762e 347 rcu_read_unlock();
8d8439b6 348}
b97bf3fd
PL
349
350/**
50100a5e
JPM
351 * link_schedule_user - schedule user for wakeup after congestion
352 * @link: congested link
353 * @oport: sending port
354 * @chain_sz: size of buffer chain that was attempted sent
355 * @imp: importance of message attempted sent
356 * Create pseudo msg to send back to user when congestion abates
b97bf3fd 357 */
50100a5e
JPM
358static bool link_schedule_user(struct tipc_link *link, u32 oport,
359 uint chain_sz, uint imp)
b97bf3fd 360{
50100a5e
JPM
361 struct sk_buff *buf;
362
363 buf = tipc_msg_create(SOCK_WAKEUP, 0, INT_H_SIZE, 0, tipc_own_addr,
364 tipc_own_addr, oport, 0, 0);
365 if (!buf)
366 return false;
367 TIPC_SKB_CB(buf)->chain_sz = chain_sz;
368 TIPC_SKB_CB(buf)->chain_imp = imp;
340b6e59 369 skb_queue_tail(&link->waiting_sks, buf);
50100a5e
JPM
370 link->stats.link_congs++;
371 return true;
b97bf3fd
PL
372}
373
50100a5e
JPM
374/**
375 * link_prepare_wakeup - prepare users for wakeup after congestion
376 * @link: congested link
377 * Move a number of waiting users, as permitted by available space in
378 * the send queue, from link wait queue to node wait queue for wakeup
379 */
380static void link_prepare_wakeup(struct tipc_link *link)
b97bf3fd 381{
58dc55f2 382 uint pend_qsz = skb_queue_len(&link->outqueue);
58d78b32 383 struct sk_buff *skb, *tmp;
50100a5e 384
58d78b32
YX
385 skb_queue_walk_safe(&link->waiting_sks, skb, tmp) {
386 if (pend_qsz >= link->queue_limit[TIPC_SKB_CB(skb)->chain_imp])
b97bf3fd 387 break;
58d78b32 388 pend_qsz += TIPC_SKB_CB(skb)->chain_sz;
340b6e59
RA
389 skb_unlink(skb, &link->waiting_sks);
390 skb_queue_tail(&link->owner->waiting_sks, skb);
b97bf3fd 391 }
b97bf3fd
PL
392}
393
b97bf3fd 394/**
4323add6 395 * tipc_link_reset_fragments - purge link's inbound message fragments queue
b97bf3fd
PL
396 * @l_ptr: pointer to link
397 */
a18c4bc3 398void tipc_link_reset_fragments(struct tipc_link *l_ptr)
b97bf3fd 399{
37e22164
JPM
400 kfree_skb(l_ptr->reasm_buf);
401 l_ptr->reasm_buf = NULL;
b97bf3fd
PL
402}
403
c4307285 404/**
581465fa 405 * tipc_link_purge_queues - purge all pkt queues associated with link
b97bf3fd
PL
406 * @l_ptr: pointer to link
407 */
581465fa 408void tipc_link_purge_queues(struct tipc_link *l_ptr)
b97bf3fd 409{
bc6fecd4 410 __skb_queue_purge(&l_ptr->deferred_queue);
58dc55f2 411 __skb_queue_purge(&l_ptr->outqueue);
4323add6 412 tipc_link_reset_fragments(l_ptr);
b97bf3fd
PL
413}
414
a18c4bc3 415void tipc_link_reset(struct tipc_link *l_ptr)
b97bf3fd 416{
b97bf3fd
PL
417 u32 prev_state = l_ptr->state;
418 u32 checkpoint = l_ptr->next_in_no;
5392d646 419 int was_active_link = tipc_link_is_active(l_ptr);
50100a5e 420 struct tipc_node *owner = l_ptr->owner;
c4307285 421
a686e685 422 msg_set_session(l_ptr->pmsg, ((msg_session(l_ptr->pmsg) + 1) & 0xffff));
b97bf3fd 423
a686e685
AS
424 /* Link is down, accept any session */
425 l_ptr->peer_session = INVALID_SESSION;
b97bf3fd 426
c4307285 427 /* Prepare for max packet size negotiation */
b97bf3fd 428 link_init_max_pkt(l_ptr);
c4307285 429
b97bf3fd 430 l_ptr->state = RESET_UNKNOWN;
b97bf3fd
PL
431
432 if ((prev_state == RESET_UNKNOWN) || (prev_state == RESET_RESET))
433 return;
434
4323add6 435 tipc_node_link_down(l_ptr->owner, l_ptr);
7f9f95d9 436 tipc_bearer_remove_dest(owner->net, l_ptr->bearer_id, l_ptr->addr);
7368ddf1 437
b9d4c339 438 if (was_active_link && tipc_node_active_links(l_ptr->owner)) {
b97bf3fd
PL
439 l_ptr->reset_checkpoint = checkpoint;
440 l_ptr->exp_msg_count = START_CHANGEOVER;
441 }
442
443 /* Clean up all queues: */
58dc55f2 444 __skb_queue_purge(&l_ptr->outqueue);
bc6fecd4 445 __skb_queue_purge(&l_ptr->deferred_queue);
50100a5e
JPM
446 if (!skb_queue_empty(&l_ptr->waiting_sks)) {
447 skb_queue_splice_init(&l_ptr->waiting_sks, &owner->waiting_sks);
448 owner->action_flags |= TIPC_WAKEUP_USERS;
449 }
b97bf3fd
PL
450 l_ptr->next_out = NULL;
451 l_ptr->unacked_window = 0;
452 l_ptr->checkpoint = 1;
453 l_ptr->next_out_no = 1;
b97bf3fd
PL
454 l_ptr->fsm_msg_cnt = 0;
455 l_ptr->stale_count = 0;
456 link_reset_statistics(l_ptr);
b97bf3fd
PL
457}
458
f2f9800d 459void tipc_link_reset_list(struct net *net, unsigned int bearer_id)
e0ca2c30 460{
f2f9800d 461 struct tipc_net *tn = net_generic(net, tipc_net_id);
e0ca2c30 462 struct tipc_link *l_ptr;
c61dd61d 463 struct tipc_node *n_ptr;
e0ca2c30 464
6c7a762e 465 rcu_read_lock();
f2f9800d 466 list_for_each_entry_rcu(n_ptr, &tn->node_list, list) {
5356f3d7 467 tipc_node_lock(n_ptr);
c61dd61d
YX
468 l_ptr = n_ptr->links[bearer_id];
469 if (l_ptr)
470 tipc_link_reset(l_ptr);
5356f3d7 471 tipc_node_unlock(n_ptr);
e0ca2c30 472 }
6c7a762e 473 rcu_read_unlock();
e0ca2c30 474}
b97bf3fd 475
7f9f95d9 476static void link_activate(struct tipc_link *link)
b97bf3fd 477{
7f9f95d9
YX
478 struct tipc_node *node = link->owner;
479
480 link->next_in_no = 1;
481 link->stats.recv_info = 1;
482 tipc_node_link_up(node, link);
483 tipc_bearer_add_dest(node->net, link->bearer_id, link->addr);
b97bf3fd
PL
484}
485
486/**
487 * link_state_event - link finite state machine
488 * @l_ptr: pointer to link
489 * @event: state machine event to process
490 */
95c96174 491static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
b97bf3fd 492{
a18c4bc3 493 struct tipc_link *other;
2f55c437 494 unsigned long cont_intv = l_ptr->cont_intv;
b97bf3fd 495
7d33939f
JPM
496 if (l_ptr->flags & LINK_STOPPED)
497 return;
498
135daee6 499 if (!(l_ptr->flags & LINK_STARTED) && (event != STARTING_EVT))
b97bf3fd
PL
500 return; /* Not yet. */
501
77a7e07a
YX
502 /* Check whether changeover is going on */
503 if (l_ptr->exp_msg_count) {
a016892c 504 if (event == TIMEOUT_EVT)
b97bf3fd 505 link_set_timer(l_ptr, cont_intv);
77a7e07a 506 return;
b97bf3fd 507 }
b97bf3fd
PL
508
509 switch (l_ptr->state) {
510 case WORKING_WORKING:
b97bf3fd
PL
511 switch (event) {
512 case TRAFFIC_MSG_EVT:
b97bf3fd 513 case ACTIVATE_MSG:
b97bf3fd
PL
514 break;
515 case TIMEOUT_EVT:
b97bf3fd
PL
516 if (l_ptr->next_in_no != l_ptr->checkpoint) {
517 l_ptr->checkpoint = l_ptr->next_in_no;
4323add6 518 if (tipc_bclink_acks_missing(l_ptr->owner)) {
247f0f3c
YX
519 tipc_link_proto_xmit(l_ptr, STATE_MSG,
520 0, 0, 0, 0, 0);
b97bf3fd
PL
521 l_ptr->fsm_msg_cnt++;
522 } else if (l_ptr->max_pkt < l_ptr->max_pkt_target) {
247f0f3c
YX
523 tipc_link_proto_xmit(l_ptr, STATE_MSG,
524 1, 0, 0, 0, 0);
b97bf3fd
PL
525 l_ptr->fsm_msg_cnt++;
526 }
527 link_set_timer(l_ptr, cont_intv);
528 break;
529 }
b97bf3fd
PL
530 l_ptr->state = WORKING_UNKNOWN;
531 l_ptr->fsm_msg_cnt = 0;
247f0f3c 532 tipc_link_proto_xmit(l_ptr, STATE_MSG, 1, 0, 0, 0, 0);
b97bf3fd
PL
533 l_ptr->fsm_msg_cnt++;
534 link_set_timer(l_ptr, cont_intv / 4);
535 break;
536 case RESET_MSG:
2cf8aa19
EH
537 pr_info("%s<%s>, requested by peer\n", link_rst_msg,
538 l_ptr->name);
4323add6 539 tipc_link_reset(l_ptr);
b97bf3fd
PL
540 l_ptr->state = RESET_RESET;
541 l_ptr->fsm_msg_cnt = 0;
247f0f3c
YX
542 tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG,
543 0, 0, 0, 0, 0);
b97bf3fd
PL
544 l_ptr->fsm_msg_cnt++;
545 link_set_timer(l_ptr, cont_intv);
546 break;
547 default:
2cf8aa19 548 pr_err("%s%u in WW state\n", link_unk_evt, event);
b97bf3fd
PL
549 }
550 break;
551 case WORKING_UNKNOWN:
b97bf3fd
PL
552 switch (event) {
553 case TRAFFIC_MSG_EVT:
b97bf3fd 554 case ACTIVATE_MSG:
b97bf3fd
PL
555 l_ptr->state = WORKING_WORKING;
556 l_ptr->fsm_msg_cnt = 0;
557 link_set_timer(l_ptr, cont_intv);
558 break;
559 case RESET_MSG:
2cf8aa19
EH
560 pr_info("%s<%s>, requested by peer while probing\n",
561 link_rst_msg, l_ptr->name);
4323add6 562 tipc_link_reset(l_ptr);
b97bf3fd
PL
563 l_ptr->state = RESET_RESET;
564 l_ptr->fsm_msg_cnt = 0;
247f0f3c
YX
565 tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG,
566 0, 0, 0, 0, 0);
b97bf3fd
PL
567 l_ptr->fsm_msg_cnt++;
568 link_set_timer(l_ptr, cont_intv);
569 break;
570 case TIMEOUT_EVT:
b97bf3fd 571 if (l_ptr->next_in_no != l_ptr->checkpoint) {
b97bf3fd
PL
572 l_ptr->state = WORKING_WORKING;
573 l_ptr->fsm_msg_cnt = 0;
574 l_ptr->checkpoint = l_ptr->next_in_no;
4323add6 575 if (tipc_bclink_acks_missing(l_ptr->owner)) {
247f0f3c
YX
576 tipc_link_proto_xmit(l_ptr, STATE_MSG,
577 0, 0, 0, 0, 0);
b97bf3fd
PL
578 l_ptr->fsm_msg_cnt++;
579 }
580 link_set_timer(l_ptr, cont_intv);
581 } else if (l_ptr->fsm_msg_cnt < l_ptr->abort_limit) {
247f0f3c
YX
582 tipc_link_proto_xmit(l_ptr, STATE_MSG,
583 1, 0, 0, 0, 0);
b97bf3fd
PL
584 l_ptr->fsm_msg_cnt++;
585 link_set_timer(l_ptr, cont_intv / 4);
586 } else { /* Link has failed */
2cf8aa19
EH
587 pr_warn("%s<%s>, peer not responding\n",
588 link_rst_msg, l_ptr->name);
4323add6 589 tipc_link_reset(l_ptr);
b97bf3fd
PL
590 l_ptr->state = RESET_UNKNOWN;
591 l_ptr->fsm_msg_cnt = 0;
247f0f3c
YX
592 tipc_link_proto_xmit(l_ptr, RESET_MSG,
593 0, 0, 0, 0, 0);
b97bf3fd
PL
594 l_ptr->fsm_msg_cnt++;
595 link_set_timer(l_ptr, cont_intv);
596 }
597 break;
598 default:
2cf8aa19 599 pr_err("%s%u in WU state\n", link_unk_evt, event);
b97bf3fd
PL
600 }
601 break;
602 case RESET_UNKNOWN:
b97bf3fd
PL
603 switch (event) {
604 case TRAFFIC_MSG_EVT:
b97bf3fd
PL
605 break;
606 case ACTIVATE_MSG:
607 other = l_ptr->owner->active_links[0];
8d64a5ba 608 if (other && link_working_unknown(other))
b97bf3fd 609 break;
b97bf3fd
PL
610 l_ptr->state = WORKING_WORKING;
611 l_ptr->fsm_msg_cnt = 0;
612 link_activate(l_ptr);
247f0f3c 613 tipc_link_proto_xmit(l_ptr, STATE_MSG, 1, 0, 0, 0, 0);
b97bf3fd 614 l_ptr->fsm_msg_cnt++;
c64f7a6a 615 if (l_ptr->owner->working_links == 1)
247f0f3c 616 tipc_link_sync_xmit(l_ptr);
b97bf3fd
PL
617 link_set_timer(l_ptr, cont_intv);
618 break;
619 case RESET_MSG:
b97bf3fd
PL
620 l_ptr->state = RESET_RESET;
621 l_ptr->fsm_msg_cnt = 0;
247f0f3c
YX
622 tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG,
623 1, 0, 0, 0, 0);
b97bf3fd
PL
624 l_ptr->fsm_msg_cnt++;
625 link_set_timer(l_ptr, cont_intv);
626 break;
627 case STARTING_EVT:
135daee6 628 l_ptr->flags |= LINK_STARTED;
b97bf3fd
PL
629 /* fall through */
630 case TIMEOUT_EVT:
247f0f3c 631 tipc_link_proto_xmit(l_ptr, RESET_MSG, 0, 0, 0, 0, 0);
b97bf3fd
PL
632 l_ptr->fsm_msg_cnt++;
633 link_set_timer(l_ptr, cont_intv);
634 break;
635 default:
2cf8aa19 636 pr_err("%s%u in RU state\n", link_unk_evt, event);
b97bf3fd
PL
637 }
638 break;
639 case RESET_RESET:
b97bf3fd
PL
640 switch (event) {
641 case TRAFFIC_MSG_EVT:
b97bf3fd
PL
642 case ACTIVATE_MSG:
643 other = l_ptr->owner->active_links[0];
8d64a5ba 644 if (other && link_working_unknown(other))
b97bf3fd 645 break;
b97bf3fd
PL
646 l_ptr->state = WORKING_WORKING;
647 l_ptr->fsm_msg_cnt = 0;
648 link_activate(l_ptr);
247f0f3c 649 tipc_link_proto_xmit(l_ptr, STATE_MSG, 1, 0, 0, 0, 0);
b97bf3fd 650 l_ptr->fsm_msg_cnt++;
c64f7a6a 651 if (l_ptr->owner->working_links == 1)
247f0f3c 652 tipc_link_sync_xmit(l_ptr);
b97bf3fd
PL
653 link_set_timer(l_ptr, cont_intv);
654 break;
655 case RESET_MSG:
b97bf3fd
PL
656 break;
657 case TIMEOUT_EVT:
247f0f3c
YX
658 tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG,
659 0, 0, 0, 0, 0);
b97bf3fd
PL
660 l_ptr->fsm_msg_cnt++;
661 link_set_timer(l_ptr, cont_intv);
b97bf3fd
PL
662 break;
663 default:
2cf8aa19 664 pr_err("%s%u in RR state\n", link_unk_evt, event);
b97bf3fd
PL
665 }
666 break;
667 default:
2cf8aa19 668 pr_err("Unknown link state %u/%u\n", l_ptr->state, event);
b97bf3fd
PL
669 }
670}
671
4f1688b2
JPM
672/* tipc_link_cong: determine return value and how to treat the
673 * sent buffer during link congestion.
674 * - For plain, errorless user data messages we keep the buffer and
675 * return -ELINKONG.
676 * - For all other messages we discard the buffer and return -EHOSTUNREACH
677 * - For TIPC internal messages we also reset the link
678 */
a6ca1094 679static int tipc_link_cong(struct tipc_link *link, struct sk_buff_head *list)
4f1688b2 680{
a6ca1094
YX
681 struct sk_buff *skb = skb_peek(list);
682 struct tipc_msg *msg = buf_msg(skb);
4f1688b2
JPM
683 uint imp = tipc_msg_tot_importance(msg);
684 u32 oport = msg_tot_origport(msg);
685
50100a5e 686 if (unlikely(imp > TIPC_CRITICAL_IMPORTANCE)) {
4f1688b2
JPM
687 pr_warn("%s<%s>, send queue full", link_rst_msg, link->name);
688 tipc_link_reset(link);
50100a5e 689 goto drop;
4f1688b2 690 }
50100a5e
JPM
691 if (unlikely(msg_errcode(msg)))
692 goto drop;
693 if (unlikely(msg_reroute_cnt(msg)))
694 goto drop;
a6ca1094 695 if (TIPC_SKB_CB(skb)->wakeup_pending)
50100a5e 696 return -ELINKCONG;
a6ca1094 697 if (link_schedule_user(link, oport, skb_queue_len(list), imp))
50100a5e
JPM
698 return -ELINKCONG;
699drop:
a6ca1094 700 __skb_queue_purge(list);
4f1688b2
JPM
701 return -EHOSTUNREACH;
702}
703
704/**
9fbfb8b1 705 * __tipc_link_xmit(): same as tipc_link_xmit, but destlink is known & locked
4f1688b2 706 * @link: link to use
a6ca1094
YX
707 * @list: chain of buffers containing message
708 *
4f1688b2
JPM
709 * Consumes the buffer chain, except when returning -ELINKCONG
710 * Returns 0 if success, otherwise errno: -ELINKCONG, -EMSGSIZE (plain socket
711 * user data messages) or -EHOSTUNREACH (all other messages/senders)
712 * Only the socket functions tipc_send_stream() and tipc_send_packet() need
713 * to act on the return value, since they may need to do more send attempts.
714 */
7f9f95d9
YX
715int __tipc_link_xmit(struct net *net, struct tipc_link *link,
716 struct sk_buff_head *list)
4f1688b2 717{
a6ca1094 718 struct tipc_msg *msg = buf_msg(skb_peek(list));
4f1688b2 719 uint psz = msg_size(msg);
4f1688b2
JPM
720 uint sndlim = link->queue_limit[0];
721 uint imp = tipc_msg_tot_importance(msg);
722 uint mtu = link->max_pkt;
723 uint ack = mod(link->next_in_no - 1);
724 uint seqno = link->next_out_no;
725 uint bc_last_in = link->owner->bclink.last_in;
726 struct tipc_media_addr *addr = &link->media_addr;
58dc55f2 727 struct sk_buff_head *outqueue = &link->outqueue;
a6ca1094 728 struct sk_buff *skb, *tmp;
4f1688b2
JPM
729
730 /* Match queue limits against msg importance: */
58dc55f2 731 if (unlikely(skb_queue_len(outqueue) >= link->queue_limit[imp]))
a6ca1094 732 return tipc_link_cong(link, list);
4f1688b2
JPM
733
734 /* Has valid packet limit been used ? */
735 if (unlikely(psz > mtu)) {
a6ca1094 736 __skb_queue_purge(list);
4f1688b2
JPM
737 return -EMSGSIZE;
738 }
739
740 /* Prepare each packet for sending, and add to outqueue: */
a6ca1094
YX
741 skb_queue_walk_safe(list, skb, tmp) {
742 __skb_unlink(skb, list);
58dc55f2 743 msg = buf_msg(skb);
4f1688b2
JPM
744 msg_set_word(msg, 2, ((ack << 16) | mod(seqno)));
745 msg_set_bcast_ack(msg, bc_last_in);
746
58dc55f2
YX
747 if (skb_queue_len(outqueue) < sndlim) {
748 __skb_queue_tail(outqueue, skb);
7f9f95d9
YX
749 tipc_bearer_send(net, link->bearer_id,
750 skb, addr);
58dc55f2
YX
751 link->next_out = NULL;
752 link->unacked_window = 0;
753 } else if (tipc_msg_bundle(outqueue, skb, mtu)) {
4f1688b2 754 link->stats.sent_bundled++;
4f1688b2 755 continue;
58dc55f2
YX
756 } else if (tipc_msg_make_bundle(outqueue, skb, mtu,
757 link->addr)) {
4f1688b2
JPM
758 link->stats.sent_bundled++;
759 link->stats.sent_bundles++;
4f1688b2 760 if (!link->next_out)
58dc55f2 761 link->next_out = skb_peek_tail(outqueue);
4f1688b2 762 } else {
58dc55f2 763 __skb_queue_tail(outqueue, skb);
4f1688b2 764 if (!link->next_out)
58dc55f2 765 link->next_out = skb;
4f1688b2
JPM
766 }
767 seqno++;
4f1688b2
JPM
768 }
769 link->next_out_no = seqno;
4f1688b2
JPM
770 return 0;
771}
772
a6ca1094
YX
773static void skb2list(struct sk_buff *skb, struct sk_buff_head *list)
774{
775 __skb_queue_head_init(list);
776 __skb_queue_tail(list, skb);
777}
778
779static int __tipc_link_xmit_skb(struct tipc_link *link, struct sk_buff *skb)
780{
781 struct sk_buff_head head;
782
783 skb2list(skb, &head);
7f9f95d9 784 return __tipc_link_xmit(link->owner->net, link, &head);
a6ca1094
YX
785}
786
f2f9800d
YX
787int tipc_link_xmit_skb(struct net *net, struct sk_buff *skb, u32 dnode,
788 u32 selector)
a6ca1094
YX
789{
790 struct sk_buff_head head;
791
792 skb2list(skb, &head);
f2f9800d 793 return tipc_link_xmit(net, &head, dnode, selector);
a6ca1094
YX
794}
795
4f1688b2 796/**
9fbfb8b1 797 * tipc_link_xmit() is the general link level function for message sending
f2f9800d 798 * @net: the applicable net namespace
a6ca1094 799 * @list: chain of buffers containing message
4f1688b2
JPM
800 * @dsz: amount of user data to be sent
801 * @dnode: address of destination node
802 * @selector: a number used for deterministic link selection
803 * Consumes the buffer chain, except when returning -ELINKCONG
804 * Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE
805 */
f2f9800d
YX
806int tipc_link_xmit(struct net *net, struct sk_buff_head *list, u32 dnode,
807 u32 selector)
4f1688b2
JPM
808{
809 struct tipc_link *link = NULL;
810 struct tipc_node *node;
811 int rc = -EHOSTUNREACH;
812
f2f9800d 813 node = tipc_node_find(net, dnode);
4f1688b2
JPM
814 if (node) {
815 tipc_node_lock(node);
816 link = node->active_links[selector & 1];
817 if (link)
7f9f95d9 818 rc = __tipc_link_xmit(net, link, list);
4f1688b2
JPM
819 tipc_node_unlock(node);
820 }
821
822 if (link)
823 return rc;
824
a6ca1094
YX
825 if (likely(in_own_node(dnode))) {
826 /* As a node local message chain never contains more than one
827 * buffer, we just need to dequeue one SKB buffer from the
828 * head list.
829 */
f2f9800d 830 return tipc_sk_rcv(net, __skb_dequeue(list));
a6ca1094
YX
831 }
832 __skb_queue_purge(list);
4f1688b2 833
4f1688b2
JPM
834 return rc;
835}
836
c64f7a6a 837/*
247f0f3c 838 * tipc_link_sync_xmit - synchronize broadcast link endpoints.
c64f7a6a
JM
839 *
840 * Give a newly added peer node the sequence number where it should
841 * start receiving and acking broadcast packets.
842 *
843 * Called with node locked
844 */
25b660c7 845static void tipc_link_sync_xmit(struct tipc_link *link)
c64f7a6a 846{
a6ca1094 847 struct sk_buff *skb;
c64f7a6a
JM
848 struct tipc_msg *msg;
849
a6ca1094
YX
850 skb = tipc_buf_acquire(INT_H_SIZE);
851 if (!skb)
c64f7a6a
JM
852 return;
853
a6ca1094 854 msg = buf_msg(skb);
25b660c7
JPM
855 tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG, INT_H_SIZE, link->addr);
856 msg_set_last_bcast(msg, link->owner->bclink.acked);
a6ca1094 857 __tipc_link_xmit_skb(link, skb);
c64f7a6a
JM
858}
859
860/*
247f0f3c 861 * tipc_link_sync_rcv - synchronize broadcast link endpoints.
c64f7a6a
JM
862 * Receive the sequence number where we should start receiving and
863 * acking broadcast packets from a newly added peer node, and open
864 * up for reception of such packets.
865 *
866 * Called with node locked
867 */
247f0f3c 868static void tipc_link_sync_rcv(struct tipc_node *n, struct sk_buff *buf)
c64f7a6a
JM
869{
870 struct tipc_msg *msg = buf_msg(buf);
871
872 n->bclink.last_sent = n->bclink.last_in = msg_last_bcast(msg);
873 n->bclink.recv_permitted = true;
874 kfree_skb(buf);
875}
876
58dc55f2
YX
877struct sk_buff *tipc_skb_queue_next(const struct sk_buff_head *list,
878 const struct sk_buff *skb)
879{
880 if (skb_queue_is_last(list, skb))
881 return NULL;
882 return skb->next;
883}
884
c4307285 885/*
47b4c9a8
YX
886 * tipc_link_push_packets - push unsent packets to bearer
887 *
888 * Push out the unsent messages of a link where congestion
889 * has abated. Node is locked.
890 *
891 * Called with node locked
b97bf3fd 892 */
47b4c9a8 893void tipc_link_push_packets(struct tipc_link *l_ptr)
b97bf3fd 894{
58dc55f2
YX
895 struct sk_buff_head *outqueue = &l_ptr->outqueue;
896 struct sk_buff *skb = l_ptr->next_out;
47b4c9a8
YX
897 struct tipc_msg *msg;
898 u32 next, first;
b97bf3fd 899
58dc55f2 900 skb_queue_walk_from(outqueue, skb) {
47b4c9a8
YX
901 msg = buf_msg(skb);
902 next = msg_seqno(msg);
58dc55f2 903 first = buf_seqno(skb_peek(outqueue));
b97bf3fd
PL
904
905 if (mod(next - first) < l_ptr->queue_limit[0]) {
906 msg_set_ack(msg, mod(l_ptr->next_in_no - 1));
c4307285 907 msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
3c294cb3 908 if (msg_user(msg) == MSG_BUNDLER)
58311d16 909 TIPC_SKB_CB(skb)->bundling = false;
7f9f95d9
YX
910 tipc_bearer_send(l_ptr->owner->net,
911 l_ptr->bearer_id, skb,
47b4c9a8 912 &l_ptr->media_addr);
58dc55f2 913 l_ptr->next_out = tipc_skb_queue_next(outqueue, skb);
47b4c9a8
YX
914 } else {
915 break;
b97bf3fd
PL
916 }
917 }
b97bf3fd
PL
918}
919
3f5a12bd 920void tipc_link_reset_all(struct tipc_node *node)
d356eeba 921{
d356eeba
AS
922 char addr_string[16];
923 u32 i;
924
3f5a12bd 925 tipc_node_lock(node);
d356eeba 926
2cf8aa19 927 pr_warn("Resetting all links to %s\n",
3f5a12bd 928 tipc_addr_string_fill(addr_string, node->addr));
d356eeba
AS
929
930 for (i = 0; i < MAX_BEARERS; i++) {
3f5a12bd
YX
931 if (node->links[i]) {
932 link_print(node->links[i], "Resetting link\n");
933 tipc_link_reset(node->links[i]);
d356eeba
AS
934 }
935 }
936
3f5a12bd 937 tipc_node_unlock(node);
d356eeba
AS
938}
939
a18c4bc3 940static void link_retransmit_failure(struct tipc_link *l_ptr,
ae8509c4 941 struct sk_buff *buf)
d356eeba
AS
942{
943 struct tipc_msg *msg = buf_msg(buf);
944
2cf8aa19 945 pr_warn("Retransmission failure on link <%s>\n", l_ptr->name);
d356eeba
AS
946
947 if (l_ptr->addr) {
d356eeba 948 /* Handle failure on standard link */
8d64a5ba 949 link_print(l_ptr, "Resetting link\n");
d356eeba
AS
950 tipc_link_reset(l_ptr);
951
952 } else {
d356eeba 953 /* Handle failure on broadcast link */
6c00055a 954 struct tipc_node *n_ptr;
d356eeba
AS
955 char addr_string[16];
956
2cf8aa19
EH
957 pr_info("Msg seq number: %u, ", msg_seqno(msg));
958 pr_cont("Outstanding acks: %lu\n",
959 (unsigned long) TIPC_SKB_CB(buf)->handle);
617dbeaa 960
01d83edd 961 n_ptr = tipc_bclink_retransmit_to();
d356eeba
AS
962 tipc_node_lock(n_ptr);
963
c68ca7b7 964 tipc_addr_string_fill(addr_string, n_ptr->addr);
2cf8aa19 965 pr_info("Broadcast link info for %s\n", addr_string);
389dd9bc
YX
966 pr_info("Reception permitted: %d, Acked: %u\n",
967 n_ptr->bclink.recv_permitted,
2cf8aa19
EH
968 n_ptr->bclink.acked);
969 pr_info("Last in: %u, Oos state: %u, Last sent: %u\n",
970 n_ptr->bclink.last_in,
971 n_ptr->bclink.oos_state,
972 n_ptr->bclink.last_sent);
d356eeba 973
d356eeba
AS
974 tipc_node_unlock(n_ptr);
975
3f5a12bd 976 tipc_bclink_set_flags(TIPC_BCLINK_RESET);
d356eeba
AS
977 l_ptr->stale_count = 0;
978 }
979}
980
58dc55f2 981void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *skb,
4323add6 982 u32 retransmits)
b97bf3fd
PL
983{
984 struct tipc_msg *msg;
985
58dc55f2 986 if (!skb)
d356eeba
AS
987 return;
988
58dc55f2 989 msg = buf_msg(skb);
c4307285 990
512137ee
EH
991 /* Detect repeated retransmit failures */
992 if (l_ptr->last_retransmitted == msg_seqno(msg)) {
993 if (++l_ptr->stale_count > 100) {
58dc55f2 994 link_retransmit_failure(l_ptr, skb);
512137ee 995 return;
d356eeba
AS
996 }
997 } else {
512137ee
EH
998 l_ptr->last_retransmitted = msg_seqno(msg);
999 l_ptr->stale_count = 1;
b97bf3fd 1000 }
d356eeba 1001
58dc55f2
YX
1002 skb_queue_walk_from(&l_ptr->outqueue, skb) {
1003 if (!retransmits || skb == l_ptr->next_out)
1004 break;
1005 msg = buf_msg(skb);
b97bf3fd 1006 msg_set_ack(msg, mod(l_ptr->next_in_no - 1));
c4307285 1007 msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
7f9f95d9
YX
1008 tipc_bearer_send(l_ptr->owner->net, l_ptr->bearer_id, skb,
1009 &l_ptr->media_addr);
3c294cb3
YX
1010 retransmits--;
1011 l_ptr->stats.retransmitted++;
b97bf3fd 1012 }
b97bf3fd
PL
1013}
1014
f03273f1
YX
1015static void link_retrieve_defq(struct tipc_link *link,
1016 struct sk_buff_head *list)
b97bf3fd
PL
1017{
1018 u32 seq_no;
1019
f03273f1
YX
1020 if (skb_queue_empty(&link->deferred_queue))
1021 return;
1022
1023 seq_no = buf_seqno(skb_peek(&link->deferred_queue));
1024 if (seq_no == mod(link->next_in_no))
1025 skb_queue_splice_tail_init(&link->deferred_queue, list);
b97bf3fd
PL
1026}
1027
85035568
AS
1028/**
1029 * link_recv_buf_validate - validate basic format of received message
1030 *
1031 * This routine ensures a TIPC message has an acceptable header, and at least
1032 * as much data as the header indicates it should. The routine also ensures
1033 * that the entire message header is stored in the main fragment of the message
1034 * buffer, to simplify future access to message header fields.
1035 *
1036 * Note: Having extra info present in the message header or data areas is OK.
1037 * TIPC will ignore the excess, under the assumption that it is optional info
1038 * introduced by a later release of the protocol.
1039 */
85035568
AS
1040static int link_recv_buf_validate(struct sk_buff *buf)
1041{
1042 static u32 min_data_hdr_size[8] = {
741d9eb7 1043 SHORT_H_SIZE, MCAST_H_SIZE, NAMED_H_SIZE, BASIC_H_SIZE,
85035568
AS
1044 MAX_H_SIZE, MAX_H_SIZE, MAX_H_SIZE, MAX_H_SIZE
1045 };
1046
1047 struct tipc_msg *msg;
1048 u32 tipc_hdr[2];
1049 u32 size;
1050 u32 hdr_size;
1051 u32 min_hdr_size;
1052
64380a04
EH
1053 /* If this packet comes from the defer queue, the skb has already
1054 * been validated
1055 */
1056 if (unlikely(TIPC_SKB_CB(buf)->deferred))
1057 return 1;
1058
85035568
AS
1059 if (unlikely(buf->len < MIN_H_SIZE))
1060 return 0;
1061
1062 msg = skb_header_pointer(buf, 0, sizeof(tipc_hdr), tipc_hdr);
1063 if (msg == NULL)
1064 return 0;
1065
1066 if (unlikely(msg_version(msg) != TIPC_VERSION))
1067 return 0;
1068
1069 size = msg_size(msg);
1070 hdr_size = msg_hdr_sz(msg);
1071 min_hdr_size = msg_isdata(msg) ?
1072 min_data_hdr_size[msg_type(msg)] : INT_H_SIZE;
1073
1074 if (unlikely((hdr_size < min_hdr_size) ||
1075 (size < hdr_size) ||
1076 (buf->len < size) ||
1077 (size - hdr_size > TIPC_MAX_USER_MSG_SIZE)))
1078 return 0;
1079
1080 return pskb_may_pull(buf, hdr_size);
1081}
1082
b02b69c8 1083/**
170b3927 1084 * tipc_rcv - process TIPC packets/messages arriving from off-node
f2f9800d 1085 * @net: the applicable net namespace
f03273f1 1086 * @skb: TIPC packet
7a2f7d18 1087 * @b_ptr: pointer to bearer message arrived on
b02b69c8
AS
1088 *
1089 * Invoked with no locks held. Bearer pointer must point to a valid bearer
1090 * structure (i.e. cannot be NULL), but bearer can be inactive.
1091 */
c93d3baa 1092void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr)
b97bf3fd 1093{
f03273f1
YX
1094 struct sk_buff_head head;
1095 struct tipc_node *n_ptr;
1096 struct tipc_link *l_ptr;
1097 struct sk_buff *skb1, *tmp;
1098 struct tipc_msg *msg;
1099 u32 seq_no;
1100 u32 ackd;
1101 u32 released;
b97bf3fd 1102
a6ca1094 1103 skb2list(skb, &head);
85035568 1104
f03273f1 1105 while ((skb = __skb_dequeue(&head))) {
85035568 1106 /* Ensure message is well-formed */
f03273f1 1107 if (unlikely(!link_recv_buf_validate(skb)))
3af390e2 1108 goto discard;
b97bf3fd 1109
fe13dda2 1110 /* Ensure message data is a single contiguous unit */
f03273f1 1111 if (unlikely(skb_linearize(skb)))
3af390e2 1112 goto discard;
fe13dda2 1113
85035568 1114 /* Handle arrival of a non-unicast link message */
f03273f1 1115 msg = buf_msg(skb);
85035568 1116
b97bf3fd 1117 if (unlikely(msg_non_seq(msg))) {
1265a021 1118 if (msg_user(msg) == LINK_CONFIG)
c93d3baa 1119 tipc_disc_rcv(net, skb, b_ptr);
1265a021 1120 else
c93d3baa 1121 tipc_bclink_rcv(net, skb);
b97bf3fd
PL
1122 continue;
1123 }
c4307285 1124
ed33a9c4 1125 /* Discard unicast link messages destined for another node */
26008247
AS
1126 if (unlikely(!msg_short(msg) &&
1127 (msg_destnode(msg) != tipc_own_addr)))
3af390e2 1128 goto discard;
c4307285 1129
5a68d5ee 1130 /* Locate neighboring node that sent message */
f2f9800d 1131 n_ptr = tipc_node_find(net, msg_prevnode(msg));
b97bf3fd 1132 if (unlikely(!n_ptr))
3af390e2 1133 goto discard;
4323add6 1134 tipc_node_lock(n_ptr);
85035568 1135
b4b56102 1136 /* Locate unicast link endpoint that should handle message */
b4b56102 1137 l_ptr = n_ptr->links[b_ptr->identity];
3af390e2
YX
1138 if (unlikely(!l_ptr))
1139 goto unlock_discard;
5a68d5ee 1140
b4b56102 1141 /* Verify that communication with node is currently allowed */
aecb9bb8 1142 if ((n_ptr->action_flags & TIPC_WAIT_PEER_LINKS_DOWN) &&
10f465c4
YX
1143 msg_user(msg) == LINK_PROTOCOL &&
1144 (msg_type(msg) == RESET_MSG ||
1145 msg_type(msg) == ACTIVATE_MSG) &&
1146 !msg_redundant_link(msg))
aecb9bb8 1147 n_ptr->action_flags &= ~TIPC_WAIT_PEER_LINKS_DOWN;
10f465c4
YX
1148
1149 if (tipc_node_blocked(n_ptr))
3af390e2 1150 goto unlock_discard;
85035568
AS
1151
1152 /* Validate message sequence number info */
85035568
AS
1153 seq_no = msg_seqno(msg);
1154 ackd = msg_ack(msg);
1155
1156 /* Release acked messages */
389dd9bc 1157 if (n_ptr->bclink.recv_permitted)
36559591 1158 tipc_bclink_acknowledge(n_ptr, msg_bcast_ack(msg));
b97bf3fd 1159
58dc55f2
YX
1160 released = 0;
1161 skb_queue_walk_safe(&l_ptr->outqueue, skb1, tmp) {
1162 if (skb1 == l_ptr->next_out ||
1163 more(buf_seqno(skb1), ackd))
1164 break;
1165 __skb_unlink(skb1, &l_ptr->outqueue);
1166 kfree_skb(skb1);
1167 released = 1;
b97bf3fd 1168 }
85035568
AS
1169
1170 /* Try sending any messages link endpoint has pending */
b97bf3fd 1171 if (unlikely(l_ptr->next_out))
47b4c9a8 1172 tipc_link_push_packets(l_ptr);
a5377831 1173
50100a5e
JPM
1174 if (released && !skb_queue_empty(&l_ptr->waiting_sks)) {
1175 link_prepare_wakeup(l_ptr);
1176 l_ptr->owner->action_flags |= TIPC_WAKEUP_USERS;
1177 }
a5377831 1178
a5377831 1179 /* Process the incoming packet */
3af390e2
YX
1180 if (unlikely(!link_working_working(l_ptr))) {
1181 if (msg_user(msg) == LINK_PROTOCOL) {
c93d3baa 1182 tipc_link_proto_rcv(net, l_ptr, skb);
f03273f1 1183 link_retrieve_defq(l_ptr, &head);
4323add6 1184 tipc_node_unlock(n_ptr);
b97bf3fd
PL
1185 continue;
1186 }
3af390e2
YX
1187
1188 /* Traffic message. Conditionally activate link */
1189 link_state_event(l_ptr, TRAFFIC_MSG_EVT);
1190
1191 if (link_working_working(l_ptr)) {
1192 /* Re-insert buffer in front of queue */
f03273f1 1193 __skb_queue_head(&head, skb);
3af390e2
YX
1194 tipc_node_unlock(n_ptr);
1195 continue;
1196 }
1197 goto unlock_discard;
1198 }
1199
1200 /* Link is now in state WORKING_WORKING */
1201 if (unlikely(seq_no != mod(l_ptr->next_in_no))) {
c93d3baa 1202 link_handle_out_of_seq_msg(net, l_ptr, skb);
f03273f1 1203 link_retrieve_defq(l_ptr, &head);
4323add6 1204 tipc_node_unlock(n_ptr);
b97bf3fd
PL
1205 continue;
1206 }
3af390e2 1207 l_ptr->next_in_no++;
bc6fecd4 1208 if (unlikely(!skb_queue_empty(&l_ptr->deferred_queue)))
f03273f1 1209 link_retrieve_defq(l_ptr, &head);
a5377831 1210
3f53bd8f
EH
1211 if (unlikely(++l_ptr->unacked_window >= TIPC_MIN_LINK_WIN)) {
1212 l_ptr->stats.sent_acks++;
1213 tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0, 0, 0, 0);
1214 }
1215
c93d3baa 1216 if (tipc_link_prepare_input(net, l_ptr, &skb)) {
3af390e2 1217 tipc_node_unlock(n_ptr);
3af390e2 1218 continue;
b97bf3fd 1219 }
4323add6 1220 tipc_node_unlock(n_ptr);
f03273f1 1221
f2f9800d 1222 if (tipc_link_input(net, l_ptr, skb) != 0)
7ae934be 1223 goto discard;
3af390e2
YX
1224 continue;
1225unlock_discard:
3af390e2
YX
1226 tipc_node_unlock(n_ptr);
1227discard:
f03273f1 1228 kfree_skb(skb);
b97bf3fd 1229 }
b97bf3fd
PL
1230}
1231
7ae934be
EH
1232/**
1233 * tipc_link_prepare_input - process TIPC link messages
1234 *
1235 * returns nonzero if the message was consumed
1236 *
1237 * Node lock must be held
1238 */
c93d3baa
YX
1239static int tipc_link_prepare_input(struct net *net, struct tipc_link *l,
1240 struct sk_buff **buf)
7ae934be
EH
1241{
1242 struct tipc_node *n;
1243 struct tipc_msg *msg;
1244 int res = -EINVAL;
1245
1246 n = l->owner;
1247 msg = buf_msg(*buf);
1248 switch (msg_user(msg)) {
1249 case CHANGEOVER_PROTOCOL:
c93d3baa 1250 if (tipc_link_tunnel_rcv(net, n, buf))
7ae934be
EH
1251 res = 0;
1252 break;
1253 case MSG_FRAGMENTER:
1254 l->stats.recv_fragments++;
1255 if (tipc_buf_append(&l->reasm_buf, buf)) {
1256 l->stats.recv_fragmented++;
1257 res = 0;
1258 } else if (!l->reasm_buf) {
1259 tipc_link_reset(l);
1260 }
1261 break;
1262 case MSG_BUNDLER:
1263 l->stats.recv_bundles++;
1264 l->stats.recv_bundled += msg_msgcnt(msg);
1265 res = 0;
1266 break;
1267 case NAME_DISTRIBUTOR:
1268 n->bclink.recv_permitted = true;
1269 res = 0;
1270 break;
1271 case BCAST_PROTOCOL:
1272 tipc_link_sync_rcv(n, *buf);
1273 break;
1274 default:
1275 res = 0;
1276 }
1277 return res;
1278}
1279/**
1280 * tipc_link_input - Deliver message too higher layers
1281 */
f2f9800d
YX
1282static int tipc_link_input(struct net *net, struct tipc_link *l,
1283 struct sk_buff *buf)
7ae934be
EH
1284{
1285 struct tipc_msg *msg = buf_msg(buf);
1286 int res = 0;
1287
1288 switch (msg_user(msg)) {
1289 case TIPC_LOW_IMPORTANCE:
1290 case TIPC_MEDIUM_IMPORTANCE:
1291 case TIPC_HIGH_IMPORTANCE:
1292 case TIPC_CRITICAL_IMPORTANCE:
1293 case CONN_MANAGER:
f2f9800d 1294 tipc_sk_rcv(net, buf);
7ae934be
EH
1295 break;
1296 case NAME_DISTRIBUTOR:
f2f9800d 1297 tipc_named_rcv(net, buf);
7ae934be
EH
1298 break;
1299 case MSG_BUNDLER:
f2f9800d 1300 tipc_link_bundle_rcv(net, buf);
7ae934be
EH
1301 break;
1302 default:
1303 res = -EINVAL;
1304 }
1305 return res;
1306}
1307
2c53040f 1308/**
8809b255
AS
1309 * tipc_link_defer_pkt - Add out-of-sequence message to deferred reception queue
1310 *
1311 * Returns increase in queue length (i.e. 0 or 1)
b97bf3fd 1312 */
bc6fecd4 1313u32 tipc_link_defer_pkt(struct sk_buff_head *list, struct sk_buff *skb)
b97bf3fd 1314{
bc6fecd4
YX
1315 struct sk_buff *skb1;
1316 u32 seq_no = buf_seqno(skb);
b97bf3fd
PL
1317
1318 /* Empty queue ? */
bc6fecd4
YX
1319 if (skb_queue_empty(list)) {
1320 __skb_queue_tail(list, skb);
b97bf3fd
PL
1321 return 1;
1322 }
1323
1324 /* Last ? */
bc6fecd4
YX
1325 if (less(buf_seqno(skb_peek_tail(list)), seq_no)) {
1326 __skb_queue_tail(list, skb);
b97bf3fd
PL
1327 return 1;
1328 }
1329
8809b255 1330 /* Locate insertion point in queue, then insert; discard if duplicate */
bc6fecd4
YX
1331 skb_queue_walk(list, skb1) {
1332 u32 curr_seqno = buf_seqno(skb1);
b97bf3fd 1333
8809b255 1334 if (seq_no == curr_seqno) {
bc6fecd4 1335 kfree_skb(skb);
8809b255 1336 return 0;
b97bf3fd 1337 }
8809b255
AS
1338
1339 if (less(seq_no, curr_seqno))
b97bf3fd 1340 break;
8809b255 1341 }
b97bf3fd 1342
bc6fecd4 1343 __skb_queue_before(list, skb1, skb);
8809b255 1344 return 1;
b97bf3fd
PL
1345}
1346
8809b255 1347/*
b97bf3fd
PL
1348 * link_handle_out_of_seq_msg - handle arrival of out-of-sequence packet
1349 */
c93d3baa
YX
1350static void link_handle_out_of_seq_msg(struct net *net,
1351 struct tipc_link *l_ptr,
b97bf3fd
PL
1352 struct sk_buff *buf)
1353{
f905730c 1354 u32 seq_no = buf_seqno(buf);
b97bf3fd
PL
1355
1356 if (likely(msg_user(buf_msg(buf)) == LINK_PROTOCOL)) {
c93d3baa 1357 tipc_link_proto_rcv(net, l_ptr, buf);
b97bf3fd
PL
1358 return;
1359 }
1360
b97bf3fd 1361 /* Record OOS packet arrival (force mismatch on next timeout) */
b97bf3fd
PL
1362 l_ptr->checkpoint--;
1363
c4307285 1364 /*
b97bf3fd
PL
1365 * Discard packet if a duplicate; otherwise add it to deferred queue
1366 * and notify peer of gap as per protocol specification
1367 */
b97bf3fd
PL
1368 if (less(seq_no, mod(l_ptr->next_in_no))) {
1369 l_ptr->stats.duplicates++;
5f6d9123 1370 kfree_skb(buf);
b97bf3fd
PL
1371 return;
1372 }
1373
bc6fecd4 1374 if (tipc_link_defer_pkt(&l_ptr->deferred_queue, buf)) {
b97bf3fd 1375 l_ptr->stats.deferred_recv++;
64380a04 1376 TIPC_SKB_CB(buf)->deferred = true;
bc6fecd4 1377 if ((skb_queue_len(&l_ptr->deferred_queue) % 16) == 1)
247f0f3c 1378 tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0, 0, 0, 0);
bc6fecd4 1379 } else {
b97bf3fd 1380 l_ptr->stats.duplicates++;
bc6fecd4 1381 }
b97bf3fd
PL
1382}
1383
1384/*
1385 * Send protocol message to the other endpoint.
1386 */
247f0f3c
YX
1387void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int probe_msg,
1388 u32 gap, u32 tolerance, u32 priority, u32 ack_mtu)
b97bf3fd 1389{
1fc54d8f 1390 struct sk_buff *buf = NULL;
b97bf3fd 1391 struct tipc_msg *msg = l_ptr->pmsg;
c4307285 1392 u32 msg_size = sizeof(l_ptr->proto_msg);
75f0aa49 1393 int r_flag;
b97bf3fd 1394
77a7e07a
YX
1395 /* Don't send protocol message during link changeover */
1396 if (l_ptr->exp_msg_count)
b97bf3fd 1397 return;
b4b56102
AS
1398
1399 /* Abort non-RESET send if communication with node is prohibited */
10f465c4 1400 if ((tipc_node_blocked(l_ptr->owner)) && (msg_typ != RESET_MSG))
b4b56102
AS
1401 return;
1402
92d2c905 1403 /* Create protocol message with "out-of-sequence" sequence number */
b97bf3fd 1404 msg_set_type(msg, msg_typ);
7a2f7d18 1405 msg_set_net_plane(msg, l_ptr->net_plane);
7a54d4a9 1406 msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
4323add6 1407 msg_set_last_bcast(msg, tipc_bclink_get_last_sent());
b97bf3fd
PL
1408
1409 if (msg_typ == STATE_MSG) {
1410 u32 next_sent = mod(l_ptr->next_out_no);
1411
4323add6 1412 if (!tipc_link_is_up(l_ptr))
b97bf3fd
PL
1413 return;
1414 if (l_ptr->next_out)
f905730c 1415 next_sent = buf_seqno(l_ptr->next_out);
b97bf3fd 1416 msg_set_next_sent(msg, next_sent);
bc6fecd4
YX
1417 if (!skb_queue_empty(&l_ptr->deferred_queue)) {
1418 u32 rec = buf_seqno(skb_peek(&l_ptr->deferred_queue));
b97bf3fd
PL
1419 gap = mod(rec - mod(l_ptr->next_in_no));
1420 }
1421 msg_set_seq_gap(msg, gap);
1422 if (gap)
1423 l_ptr->stats.sent_nacks++;
1424 msg_set_link_tolerance(msg, tolerance);
1425 msg_set_linkprio(msg, priority);
1426 msg_set_max_pkt(msg, ack_mtu);
1427 msg_set_ack(msg, mod(l_ptr->next_in_no - 1));
1428 msg_set_probe(msg, probe_msg != 0);
c4307285 1429 if (probe_msg) {
b97bf3fd
PL
1430 u32 mtu = l_ptr->max_pkt;
1431
c4307285 1432 if ((mtu < l_ptr->max_pkt_target) &&
b97bf3fd
PL
1433 link_working_working(l_ptr) &&
1434 l_ptr->fsm_msg_cnt) {
1435 msg_size = (mtu + (l_ptr->max_pkt_target - mtu)/2 + 2) & ~3;
c4307285
YH
1436 if (l_ptr->max_pkt_probes == 10) {
1437 l_ptr->max_pkt_target = (msg_size - 4);
1438 l_ptr->max_pkt_probes = 0;
b97bf3fd 1439 msg_size = (mtu + (l_ptr->max_pkt_target - mtu)/2 + 2) & ~3;
c4307285 1440 }
b97bf3fd 1441 l_ptr->max_pkt_probes++;
c4307285 1442 }
b97bf3fd
PL
1443
1444 l_ptr->stats.sent_probes++;
c4307285 1445 }
b97bf3fd
PL
1446 l_ptr->stats.sent_states++;
1447 } else { /* RESET_MSG or ACTIVATE_MSG */
1448 msg_set_ack(msg, mod(l_ptr->reset_checkpoint - 1));
1449 msg_set_seq_gap(msg, 0);
1450 msg_set_next_sent(msg, 1);
f23d9bf2 1451 msg_set_probe(msg, 0);
b97bf3fd
PL
1452 msg_set_link_tolerance(msg, l_ptr->tolerance);
1453 msg_set_linkprio(msg, l_ptr->priority);
1454 msg_set_max_pkt(msg, l_ptr->max_pkt_target);
1455 }
1456
75f0aa49
AS
1457 r_flag = (l_ptr->owner->working_links > tipc_link_is_up(l_ptr));
1458 msg_set_redundant_link(msg, r_flag);
b97bf3fd 1459 msg_set_linkprio(msg, l_ptr->priority);
92d2c905 1460 msg_set_size(msg, msg_size);
b97bf3fd
PL
1461
1462 msg_set_seqno(msg, mod(l_ptr->next_out_no + (0xffff/2)));
1463
31e3c3f6 1464 buf = tipc_buf_acquire(msg_size);
b97bf3fd
PL
1465 if (!buf)
1466 return;
1467
27d7ff46 1468 skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg));
796c75d0 1469 buf->priority = TC_PRIO_CONTROL;
b97bf3fd 1470
7f9f95d9
YX
1471 tipc_bearer_send(l_ptr->owner->net, l_ptr->bearer_id, buf,
1472 &l_ptr->media_addr);
92d2c905 1473 l_ptr->unacked_window = 0;
5f6d9123 1474 kfree_skb(buf);
b97bf3fd
PL
1475}
1476
1477/*
1478 * Receive protocol message :
c4307285
YH
1479 * Note that network plane id propagates through the network, and may
1480 * change at any time. The node with lowest address rules
b97bf3fd 1481 */
c93d3baa
YX
1482static void tipc_link_proto_rcv(struct net *net, struct tipc_link *l_ptr,
1483 struct sk_buff *buf)
b97bf3fd
PL
1484{
1485 u32 rec_gap = 0;
1486 u32 max_pkt_info;
c4307285 1487 u32 max_pkt_ack;
b97bf3fd
PL
1488 u32 msg_tol;
1489 struct tipc_msg *msg = buf_msg(buf);
1490
77a7e07a
YX
1491 /* Discard protocol message during link changeover */
1492 if (l_ptr->exp_msg_count)
b97bf3fd
PL
1493 goto exit;
1494
7a2f7d18 1495 if (l_ptr->net_plane != msg_net_plane(msg))
b97bf3fd 1496 if (tipc_own_addr > msg_prevnode(msg))
7a2f7d18 1497 l_ptr->net_plane = msg_net_plane(msg);
b97bf3fd 1498
b97bf3fd 1499 switch (msg_type(msg)) {
c4307285 1500
b97bf3fd 1501 case RESET_MSG:
a686e685
AS
1502 if (!link_working_unknown(l_ptr) &&
1503 (l_ptr->peer_session != INVALID_SESSION)) {
641c218d
AS
1504 if (less_eq(msg_session(msg), l_ptr->peer_session))
1505 break; /* duplicate or old reset: ignore */
b97bf3fd 1506 }
b4b56102
AS
1507
1508 if (!msg_redundant_link(msg) && (link_working_working(l_ptr) ||
1509 link_working_unknown(l_ptr))) {
1510 /*
1511 * peer has lost contact -- don't allow peer's links
1512 * to reactivate before we recognize loss & clean up
1513 */
ca9cf06a 1514 l_ptr->owner->action_flags |= TIPC_WAIT_OWN_LINKS_DOWN;
b4b56102
AS
1515 }
1516
47361c87
AS
1517 link_state_event(l_ptr, RESET_MSG);
1518
b97bf3fd
PL
1519 /* fall thru' */
1520 case ACTIVATE_MSG:
1521 /* Update link settings according other endpoint's values */
b97bf3fd
PL
1522 strcpy((strrchr(l_ptr->name, ':') + 1), (char *)msg_data(msg));
1523
2db9983a
AS
1524 msg_tol = msg_link_tolerance(msg);
1525 if (msg_tol > l_ptr->tolerance)
b97bf3fd
PL
1526 link_set_supervision_props(l_ptr, msg_tol);
1527
1528 if (msg_linkprio(msg) > l_ptr->priority)
1529 l_ptr->priority = msg_linkprio(msg);
1530
1531 max_pkt_info = msg_max_pkt(msg);
c4307285 1532 if (max_pkt_info) {
b97bf3fd
PL
1533 if (max_pkt_info < l_ptr->max_pkt_target)
1534 l_ptr->max_pkt_target = max_pkt_info;
1535 if (l_ptr->max_pkt > l_ptr->max_pkt_target)
1536 l_ptr->max_pkt = l_ptr->max_pkt_target;
1537 } else {
c4307285 1538 l_ptr->max_pkt = l_ptr->max_pkt_target;
b97bf3fd 1539 }
b97bf3fd 1540
4d75313c 1541 /* Synchronize broadcast link info, if not done previously */
7a54d4a9
AS
1542 if (!tipc_node_is_up(l_ptr->owner)) {
1543 l_ptr->owner->bclink.last_sent =
1544 l_ptr->owner->bclink.last_in =
1545 msg_last_bcast(msg);
1546 l_ptr->owner->bclink.oos_state = 0;
1547 }
4d75313c 1548
b97bf3fd
PL
1549 l_ptr->peer_session = msg_session(msg);
1550 l_ptr->peer_bearer_id = msg_bearer_id(msg);
47361c87
AS
1551
1552 if (msg_type(msg) == ACTIVATE_MSG)
1553 link_state_event(l_ptr, ACTIVATE_MSG);
b97bf3fd
PL
1554 break;
1555 case STATE_MSG:
1556
2db9983a
AS
1557 msg_tol = msg_link_tolerance(msg);
1558 if (msg_tol)
b97bf3fd 1559 link_set_supervision_props(l_ptr, msg_tol);
c4307285
YH
1560
1561 if (msg_linkprio(msg) &&
b97bf3fd 1562 (msg_linkprio(msg) != l_ptr->priority)) {
2cf8aa19
EH
1563 pr_warn("%s<%s>, priority change %u->%u\n",
1564 link_rst_msg, l_ptr->name, l_ptr->priority,
1565 msg_linkprio(msg));
b97bf3fd 1566 l_ptr->priority = msg_linkprio(msg);
4323add6 1567 tipc_link_reset(l_ptr); /* Enforce change to take effect */
b97bf3fd
PL
1568 break;
1569 }
ec37dcd3
JPM
1570
1571 /* Record reception; force mismatch at next timeout: */
1572 l_ptr->checkpoint--;
1573
b97bf3fd
PL
1574 link_state_event(l_ptr, TRAFFIC_MSG_EVT);
1575 l_ptr->stats.recv_states++;
1576 if (link_reset_unknown(l_ptr))
1577 break;
1578
1579 if (less_eq(mod(l_ptr->next_in_no), msg_next_sent(msg))) {
c4307285 1580 rec_gap = mod(msg_next_sent(msg) -
b97bf3fd
PL
1581 mod(l_ptr->next_in_no));
1582 }
1583
1584 max_pkt_ack = msg_max_pkt(msg);
c4307285 1585 if (max_pkt_ack > l_ptr->max_pkt) {
c4307285
YH
1586 l_ptr->max_pkt = max_pkt_ack;
1587 l_ptr->max_pkt_probes = 0;
1588 }
b97bf3fd
PL
1589
1590 max_pkt_ack = 0;
c4307285 1591 if (msg_probe(msg)) {
b97bf3fd 1592 l_ptr->stats.recv_probes++;
a016892c 1593 if (msg_size(msg) > sizeof(l_ptr->proto_msg))
c4307285 1594 max_pkt_ack = msg_size(msg);
c4307285 1595 }
b97bf3fd
PL
1596
1597 /* Protocol message before retransmits, reduce loss risk */
389dd9bc 1598 if (l_ptr->owner->bclink.recv_permitted)
c93d3baa 1599 tipc_bclink_update_link_state(net, l_ptr->owner,
7a54d4a9 1600 msg_last_bcast(msg));
b97bf3fd
PL
1601
1602 if (rec_gap || (msg_probe(msg))) {
247f0f3c
YX
1603 tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, rec_gap, 0,
1604 0, max_pkt_ack);
b97bf3fd
PL
1605 }
1606 if (msg_seq_gap(msg)) {
b97bf3fd 1607 l_ptr->stats.recv_nacks++;
58dc55f2 1608 tipc_link_retransmit(l_ptr, skb_peek(&l_ptr->outqueue),
4323add6 1609 msg_seq_gap(msg));
b97bf3fd
PL
1610 }
1611 break;
b97bf3fd
PL
1612 }
1613exit:
5f6d9123 1614 kfree_skb(buf);
b97bf3fd
PL
1615}
1616
1617
170b3927
JPM
1618/* tipc_link_tunnel_xmit(): Tunnel one packet via a link belonging to
1619 * a different bearer. Owner node is locked.
b97bf3fd 1620 */
170b3927
JPM
1621static void tipc_link_tunnel_xmit(struct tipc_link *l_ptr,
1622 struct tipc_msg *tunnel_hdr,
1623 struct tipc_msg *msg,
1624 u32 selector)
b97bf3fd 1625{
a18c4bc3 1626 struct tipc_link *tunnel;
a6ca1094 1627 struct sk_buff *skb;
b97bf3fd
PL
1628 u32 length = msg_size(msg);
1629
1630 tunnel = l_ptr->owner->active_links[selector & 1];
5392d646 1631 if (!tipc_link_is_up(tunnel)) {
2cf8aa19 1632 pr_warn("%stunnel link no longer available\n", link_co_err);
b97bf3fd 1633 return;
5392d646 1634 }
b97bf3fd 1635 msg_set_size(tunnel_hdr, length + INT_H_SIZE);
a6ca1094
YX
1636 skb = tipc_buf_acquire(length + INT_H_SIZE);
1637 if (!skb) {
2cf8aa19 1638 pr_warn("%sunable to send tunnel msg\n", link_co_err);
b97bf3fd 1639 return;
5392d646 1640 }
a6ca1094
YX
1641 skb_copy_to_linear_data(skb, tunnel_hdr, INT_H_SIZE);
1642 skb_copy_to_linear_data_offset(skb, INT_H_SIZE, msg, length);
1643 __tipc_link_xmit_skb(tunnel, skb);
b97bf3fd
PL
1644}
1645
1646
170b3927
JPM
1647/* tipc_link_failover_send_queue(): A link has gone down, but a second
1648 * link is still active. We can do failover. Tunnel the failing link's
1649 * whole send queue via the remaining link. This way, we don't lose
1650 * any packets, and sequence order is preserved for subsequent traffic
1651 * sent over the remaining link. Owner node is locked.
b97bf3fd 1652 */
170b3927 1653void tipc_link_failover_send_queue(struct tipc_link *l_ptr)
b97bf3fd 1654{
58dc55f2 1655 u32 msgcount = skb_queue_len(&l_ptr->outqueue);
a18c4bc3 1656 struct tipc_link *tunnel = l_ptr->owner->active_links[0];
b97bf3fd 1657 struct tipc_msg tunnel_hdr;
58dc55f2 1658 struct sk_buff *skb;
5392d646 1659 int split_bundles;
b97bf3fd
PL
1660
1661 if (!tunnel)
1662 return;
1663
c68ca7b7 1664 tipc_msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL,
75715217 1665 ORIGINAL_MSG, INT_H_SIZE, l_ptr->addr);
b97bf3fd
PL
1666 msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id);
1667 msg_set_msgcnt(&tunnel_hdr, msgcount);
f131072c 1668
58dc55f2
YX
1669 if (skb_queue_empty(&l_ptr->outqueue)) {
1670 skb = tipc_buf_acquire(INT_H_SIZE);
1671 if (skb) {
1672 skb_copy_to_linear_data(skb, &tunnel_hdr, INT_H_SIZE);
b97bf3fd 1673 msg_set_size(&tunnel_hdr, INT_H_SIZE);
a6ca1094 1674 __tipc_link_xmit_skb(tunnel, skb);
b97bf3fd 1675 } else {
2cf8aa19
EH
1676 pr_warn("%sunable to send changeover msg\n",
1677 link_co_err);
b97bf3fd
PL
1678 }
1679 return;
1680 }
f131072c 1681
c4307285 1682 split_bundles = (l_ptr->owner->active_links[0] !=
5392d646
AS
1683 l_ptr->owner->active_links[1]);
1684
58dc55f2
YX
1685 skb_queue_walk(&l_ptr->outqueue, skb) {
1686 struct tipc_msg *msg = buf_msg(skb);
b97bf3fd
PL
1687
1688 if ((msg_user(msg) == MSG_BUNDLER) && split_bundles) {
b97bf3fd 1689 struct tipc_msg *m = msg_get_wrapped(msg);
0e65967e 1690 unchar *pos = (unchar *)m;
b97bf3fd 1691
d788d805 1692 msgcount = msg_msgcnt(msg);
b97bf3fd 1693 while (msgcount--) {
0e65967e 1694 msg_set_seqno(m, msg_seqno(msg));
170b3927
JPM
1695 tipc_link_tunnel_xmit(l_ptr, &tunnel_hdr, m,
1696 msg_link_selector(m));
b97bf3fd
PL
1697 pos += align(msg_size(m));
1698 m = (struct tipc_msg *)pos;
1699 }
1700 } else {
170b3927
JPM
1701 tipc_link_tunnel_xmit(l_ptr, &tunnel_hdr, msg,
1702 msg_link_selector(msg));
b97bf3fd 1703 }
b97bf3fd
PL
1704 }
1705}
1706
247f0f3c 1707/* tipc_link_dup_queue_xmit(): A second link has become active. Tunnel a
170b3927
JPM
1708 * duplicate of the first link's send queue via the new link. This way, we
1709 * are guaranteed that currently queued packets from a socket are delivered
1710 * before future traffic from the same socket, even if this is using the
1711 * new link. The last arriving copy of each duplicate packet is dropped at
1712 * the receiving end by the regular protocol check, so packet cardinality
1713 * and sequence order is preserved per sender/receiver socket pair.
1714 * Owner node is locked.
1715 */
247f0f3c 1716void tipc_link_dup_queue_xmit(struct tipc_link *l_ptr,
170b3927 1717 struct tipc_link *tunnel)
b97bf3fd 1718{
58dc55f2 1719 struct sk_buff *skb;
b97bf3fd
PL
1720 struct tipc_msg tunnel_hdr;
1721
c68ca7b7 1722 tipc_msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL,
75715217 1723 DUPLICATE_MSG, INT_H_SIZE, l_ptr->addr);
58dc55f2 1724 msg_set_msgcnt(&tunnel_hdr, skb_queue_len(&l_ptr->outqueue));
b97bf3fd 1725 msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id);
58dc55f2
YX
1726 skb_queue_walk(&l_ptr->outqueue, skb) {
1727 struct sk_buff *outskb;
1728 struct tipc_msg *msg = buf_msg(skb);
b97bf3fd
PL
1729 u32 length = msg_size(msg);
1730
1731 if (msg_user(msg) == MSG_BUNDLER)
1732 msg_set_type(msg, CLOSED_MSG);
1733 msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); /* Update */
c4307285 1734 msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
b97bf3fd 1735 msg_set_size(&tunnel_hdr, length + INT_H_SIZE);
58dc55f2
YX
1736 outskb = tipc_buf_acquire(length + INT_H_SIZE);
1737 if (outskb == NULL) {
2cf8aa19
EH
1738 pr_warn("%sunable to send duplicate msg\n",
1739 link_co_err);
b97bf3fd
PL
1740 return;
1741 }
58dc55f2
YX
1742 skb_copy_to_linear_data(outskb, &tunnel_hdr, INT_H_SIZE);
1743 skb_copy_to_linear_data_offset(outskb, INT_H_SIZE, skb->data,
27d7ff46 1744 length);
a6ca1094 1745 __tipc_link_xmit_skb(tunnel, outskb);
4323add6 1746 if (!tipc_link_is_up(l_ptr))
b97bf3fd 1747 return;
b97bf3fd
PL
1748 }
1749}
1750
b97bf3fd
PL
1751/**
1752 * buf_extract - extracts embedded TIPC message from another message
1753 * @skb: encapsulating message buffer
1754 * @from_pos: offset to extract from
1755 *
c4307285 1756 * Returns a new message buffer containing an embedded message. The
b97bf3fd
PL
1757 * encapsulating message itself is left unchanged.
1758 */
b97bf3fd
PL
1759static struct sk_buff *buf_extract(struct sk_buff *skb, u32 from_pos)
1760{
1761 struct tipc_msg *msg = (struct tipc_msg *)(skb->data + from_pos);
1762 u32 size = msg_size(msg);
1763 struct sk_buff *eb;
1764
31e3c3f6 1765 eb = tipc_buf_acquire(size);
b97bf3fd 1766 if (eb)
27d7ff46 1767 skb_copy_to_linear_data(eb, msg, size);
b97bf3fd
PL
1768 return eb;
1769}
1770
1dab3d5a
JPM
1771
1772
1773/* tipc_link_dup_rcv(): Receive a tunnelled DUPLICATE_MSG packet.
1774 * Owner node is locked.
1775 */
c93d3baa 1776static void tipc_link_dup_rcv(struct net *net, struct tipc_link *l_ptr,
1dab3d5a
JPM
1777 struct sk_buff *t_buf)
1778{
1779 struct sk_buff *buf;
1780
1781 if (!tipc_link_is_up(l_ptr))
1782 return;
1783
1784 buf = buf_extract(t_buf, INT_H_SIZE);
1785 if (buf == NULL) {
1786 pr_warn("%sfailed to extract inner dup pkt\n", link_co_err);
1787 return;
1788 }
1789
1790 /* Add buffer to deferred queue, if applicable: */
c93d3baa 1791 link_handle_out_of_seq_msg(net, l_ptr, buf);
1dab3d5a
JPM
1792}
1793
f006c9c7
JPM
1794/* tipc_link_failover_rcv(): Receive a tunnelled ORIGINAL_MSG packet
1795 * Owner node is locked.
1796 */
1797static struct sk_buff *tipc_link_failover_rcv(struct tipc_link *l_ptr,
1798 struct sk_buff *t_buf)
1799{
1800 struct tipc_msg *t_msg = buf_msg(t_buf);
1801 struct sk_buff *buf = NULL;
1802 struct tipc_msg *msg;
1803
1804 if (tipc_link_is_up(l_ptr))
1805 tipc_link_reset(l_ptr);
1806
1807 /* First failover packet? */
1808 if (l_ptr->exp_msg_count == START_CHANGEOVER)
1809 l_ptr->exp_msg_count = msg_msgcnt(t_msg);
1810
1811 /* Should there be an inner packet? */
1812 if (l_ptr->exp_msg_count) {
1813 l_ptr->exp_msg_count--;
1814 buf = buf_extract(t_buf, INT_H_SIZE);
1815 if (buf == NULL) {
1816 pr_warn("%sno inner failover pkt\n", link_co_err);
1817 goto exit;
1818 }
1819 msg = buf_msg(buf);
1820
1821 if (less(msg_seqno(msg), l_ptr->reset_checkpoint)) {
1822 kfree_skb(buf);
1823 buf = NULL;
1824 goto exit;
1825 }
1826 if (msg_user(msg) == MSG_FRAGMENTER) {
1827 l_ptr->stats.recv_fragments++;
37e22164 1828 tipc_buf_append(&l_ptr->reasm_buf, &buf);
f006c9c7
JPM
1829 }
1830 }
f006c9c7 1831exit:
7d33939f
JPM
1832 if ((l_ptr->exp_msg_count == 0) && (l_ptr->flags & LINK_STOPPED)) {
1833 tipc_node_detach_link(l_ptr->owner, l_ptr);
1834 kfree(l_ptr);
1835 }
f006c9c7
JPM
1836 return buf;
1837}
1838
1dab3d5a 1839/* tipc_link_tunnel_rcv(): Receive a tunnelled packet, sent
170b3927
JPM
1840 * via other link as result of a failover (ORIGINAL_MSG) or
1841 * a new active link (DUPLICATE_MSG). Failover packets are
1842 * returned to the active link for delivery upwards.
1843 * Owner node is locked.
b97bf3fd 1844 */
c93d3baa 1845static int tipc_link_tunnel_rcv(struct net *net, struct tipc_node *n_ptr,
170b3927 1846 struct sk_buff **buf)
b97bf3fd 1847{
02842f71
JPM
1848 struct sk_buff *t_buf = *buf;
1849 struct tipc_link *l_ptr;
1850 struct tipc_msg *t_msg = buf_msg(t_buf);
1851 u32 bearer_id = msg_bearer_id(t_msg);
b97bf3fd 1852
1e9d47a9
JPM
1853 *buf = NULL;
1854
cb4b102f
DC
1855 if (bearer_id >= MAX_BEARERS)
1856 goto exit;
1dab3d5a 1857
02842f71
JPM
1858 l_ptr = n_ptr->links[bearer_id];
1859 if (!l_ptr)
b97bf3fd 1860 goto exit;
b97bf3fd 1861
02842f71 1862 if (msg_type(t_msg) == DUPLICATE_MSG)
c93d3baa 1863 tipc_link_dup_rcv(net, l_ptr, t_buf);
02842f71
JPM
1864 else if (msg_type(t_msg) == ORIGINAL_MSG)
1865 *buf = tipc_link_failover_rcv(l_ptr, t_buf);
1e9d47a9
JPM
1866 else
1867 pr_warn("%sunknown tunnel pkt received\n", link_co_err);
b97bf3fd 1868exit:
02842f71 1869 kfree_skb(t_buf);
1e9d47a9 1870 return *buf != NULL;
b97bf3fd
PL
1871}
1872
1873/*
1874 * Bundler functionality:
1875 */
f2f9800d 1876void tipc_link_bundle_rcv(struct net *net, struct sk_buff *buf)
b97bf3fd
PL
1877{
1878 u32 msgcount = msg_msgcnt(buf_msg(buf));
1879 u32 pos = INT_H_SIZE;
1880 struct sk_buff *obuf;
ec8a2e56 1881 struct tipc_msg *omsg;
b97bf3fd 1882
b97bf3fd
PL
1883 while (msgcount--) {
1884 obuf = buf_extract(buf, pos);
1885 if (obuf == NULL) {
2cf8aa19 1886 pr_warn("Link unable to unbundle message(s)\n");
a10bd924 1887 break;
3ff50b79 1888 }
ec8a2e56
JPM
1889 omsg = buf_msg(obuf);
1890 pos += align(msg_size(omsg));
643566d4
JPM
1891 if (msg_isdata(omsg)) {
1892 if (unlikely(msg_type(omsg) == TIPC_MCAST_MSG))
f2f9800d 1893 tipc_sk_mcast_rcv(net, obuf);
643566d4 1894 else
f2f9800d 1895 tipc_sk_rcv(net, obuf);
643566d4 1896 } else if (msg_user(omsg) == CONN_MANAGER) {
f2f9800d 1897 tipc_sk_rcv(net, obuf);
ec8a2e56 1898 } else if (msg_user(omsg) == NAME_DISTRIBUTOR) {
f2f9800d 1899 tipc_named_rcv(net, obuf);
ec8a2e56
JPM
1900 } else {
1901 pr_warn("Illegal bundled msg: %u\n", msg_user(omsg));
1902 kfree_skb(obuf);
1903 }
b97bf3fd 1904 }
5f6d9123 1905 kfree_skb(buf);
b97bf3fd
PL
1906}
1907
2f55c437 1908static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tol)
b97bf3fd 1909{
2f55c437
YX
1910 unsigned long intv = ((tol / 4) > 500) ? 500 : tol / 4;
1911
1912 if ((tol < TIPC_MIN_LINK_TOL) || (tol > TIPC_MAX_LINK_TOL))
5413b4c6
AS
1913 return;
1914
2f55c437
YX
1915 l_ptr->tolerance = tol;
1916 l_ptr->cont_intv = msecs_to_jiffies(intv);
1917 l_ptr->abort_limit = tol / (jiffies_to_msecs(l_ptr->cont_intv) / 4);
b97bf3fd
PL
1918}
1919
a18c4bc3 1920void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window)
b97bf3fd
PL
1921{
1922 /* Data messages from this node, inclusive FIRST_FRAGM */
06d82c91
AS
1923 l_ptr->queue_limit[TIPC_LOW_IMPORTANCE] = window;
1924 l_ptr->queue_limit[TIPC_MEDIUM_IMPORTANCE] = (window / 3) * 4;
1925 l_ptr->queue_limit[TIPC_HIGH_IMPORTANCE] = (window / 3) * 5;
1926 l_ptr->queue_limit[TIPC_CRITICAL_IMPORTANCE] = (window / 3) * 6;
b97bf3fd 1927 /* Transiting data messages,inclusive FIRST_FRAGM */
06d82c91
AS
1928 l_ptr->queue_limit[TIPC_LOW_IMPORTANCE + 4] = 300;
1929 l_ptr->queue_limit[TIPC_MEDIUM_IMPORTANCE + 4] = 600;
1930 l_ptr->queue_limit[TIPC_HIGH_IMPORTANCE + 4] = 900;
1931 l_ptr->queue_limit[TIPC_CRITICAL_IMPORTANCE + 4] = 1200;
b97bf3fd 1932 l_ptr->queue_limit[CONN_MANAGER] = 1200;
b97bf3fd
PL
1933 l_ptr->queue_limit[CHANGEOVER_PROTOCOL] = 2500;
1934 l_ptr->queue_limit[NAME_DISTRIBUTOR] = 3000;
1935 /* FRAGMENT and LAST_FRAGMENT packets */
1936 l_ptr->queue_limit[MSG_FRAGMENTER] = 4000;
1937}
1938
e099e86c 1939/* tipc_link_find_owner - locate owner node of link by link's name
f2f9800d 1940 * @net: the applicable net namespace
e099e86c
JPM
1941 * @name: pointer to link name string
1942 * @bearer_id: pointer to index in 'node->links' array where the link was found.
c4307285 1943 *
e099e86c 1944 * Returns pointer to node owning the link, or 0 if no matching link is found.
b97bf3fd 1945 */
f2f9800d
YX
1946static struct tipc_node *tipc_link_find_owner(struct net *net,
1947 const char *link_name,
e099e86c 1948 unsigned int *bearer_id)
b97bf3fd 1949{
f2f9800d 1950 struct tipc_net *tn = net_generic(net, tipc_net_id);
a18c4bc3 1951 struct tipc_link *l_ptr;
bbfbe47c 1952 struct tipc_node *n_ptr;
886eaa1f 1953 struct tipc_node *found_node = NULL;
bbfbe47c 1954 int i;
b97bf3fd 1955
e099e86c 1956 *bearer_id = 0;
6c7a762e 1957 rcu_read_lock();
f2f9800d 1958 list_for_each_entry_rcu(n_ptr, &tn->node_list, list) {
a11607f5 1959 tipc_node_lock(n_ptr);
bbfbe47c
EH
1960 for (i = 0; i < MAX_BEARERS; i++) {
1961 l_ptr = n_ptr->links[i];
e099e86c
JPM
1962 if (l_ptr && !strcmp(l_ptr->name, link_name)) {
1963 *bearer_id = i;
1964 found_node = n_ptr;
1965 break;
1966 }
bbfbe47c 1967 }
a11607f5 1968 tipc_node_unlock(n_ptr);
e099e86c
JPM
1969 if (found_node)
1970 break;
bbfbe47c 1971 }
6c7a762e
YX
1972 rcu_read_unlock();
1973
e099e86c 1974 return found_node;
b97bf3fd
PL
1975}
1976
5c216e1d
AS
1977/**
1978 * link_value_is_valid -- validate proposed link tolerance/priority/window
1979 *
2c53040f
BH
1980 * @cmd: value type (TIPC_CMD_SET_LINK_*)
1981 * @new_value: the new value
5c216e1d
AS
1982 *
1983 * Returns 1 if value is within range, 0 if not.
1984 */
5c216e1d
AS
1985static int link_value_is_valid(u16 cmd, u32 new_value)
1986{
1987 switch (cmd) {
1988 case TIPC_CMD_SET_LINK_TOL:
1989 return (new_value >= TIPC_MIN_LINK_TOL) &&
1990 (new_value <= TIPC_MAX_LINK_TOL);
1991 case TIPC_CMD_SET_LINK_PRI:
1992 return (new_value <= TIPC_MAX_LINK_PRI);
1993 case TIPC_CMD_SET_LINK_WINDOW:
1994 return (new_value >= TIPC_MIN_LINK_WIN) &&
1995 (new_value <= TIPC_MAX_LINK_WIN);
1996 }
1997 return 0;
1998}
1999
5c216e1d
AS
2000/**
2001 * link_cmd_set_value - change priority/tolerance/window for link/bearer/media
f2f9800d 2002 * @net: the applicable net namespace
2c53040f
BH
2003 * @name: ptr to link, bearer, or media name
2004 * @new_value: new value of link, bearer, or media setting
2005 * @cmd: which link, bearer, or media attribute to set (TIPC_CMD_SET_LINK_*)
5c216e1d 2006 *
7216cd94 2007 * Caller must hold RTNL lock to ensure link/bearer/media is not deleted.
5c216e1d
AS
2008 *
2009 * Returns 0 if value updated and negative value on error.
2010 */
f2f9800d
YX
2011static int link_cmd_set_value(struct net *net, const char *name, u32 new_value,
2012 u16 cmd)
5c216e1d
AS
2013{
2014 struct tipc_node *node;
a18c4bc3 2015 struct tipc_link *l_ptr;
5c216e1d 2016 struct tipc_bearer *b_ptr;
358a0d1c 2017 struct tipc_media *m_ptr;
e099e86c 2018 int bearer_id;
636c0371 2019 int res = 0;
5c216e1d 2020
f2f9800d 2021 node = tipc_link_find_owner(net, name, &bearer_id);
e099e86c 2022 if (node) {
5c216e1d 2023 tipc_node_lock(node);
e099e86c
JPM
2024 l_ptr = node->links[bearer_id];
2025
2026 if (l_ptr) {
2027 switch (cmd) {
2028 case TIPC_CMD_SET_LINK_TOL:
2029 link_set_supervision_props(l_ptr, new_value);
247f0f3c
YX
2030 tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0,
2031 new_value, 0, 0);
e099e86c
JPM
2032 break;
2033 case TIPC_CMD_SET_LINK_PRI:
2034 l_ptr->priority = new_value;
247f0f3c
YX
2035 tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0,
2036 0, new_value, 0);
e099e86c
JPM
2037 break;
2038 case TIPC_CMD_SET_LINK_WINDOW:
2039 tipc_link_set_queue_limits(l_ptr, new_value);
2040 break;
2041 default:
2042 res = -EINVAL;
2043 break;
2044 }
5c216e1d
AS
2045 }
2046 tipc_node_unlock(node);
636c0371 2047 return res;
5c216e1d
AS
2048 }
2049
7f9f95d9 2050 b_ptr = tipc_bearer_find(net, name);
5c216e1d
AS
2051 if (b_ptr) {
2052 switch (cmd) {
2053 case TIPC_CMD_SET_LINK_TOL:
2054 b_ptr->tolerance = new_value;
636c0371 2055 break;
5c216e1d
AS
2056 case TIPC_CMD_SET_LINK_PRI:
2057 b_ptr->priority = new_value;
636c0371 2058 break;
5c216e1d
AS
2059 case TIPC_CMD_SET_LINK_WINDOW:
2060 b_ptr->window = new_value;
636c0371
YX
2061 break;
2062 default:
2063 res = -EINVAL;
2064 break;
5c216e1d 2065 }
636c0371 2066 return res;
5c216e1d
AS
2067 }
2068
2069 m_ptr = tipc_media_find(name);
2070 if (!m_ptr)
2071 return -ENODEV;
2072 switch (cmd) {
2073 case TIPC_CMD_SET_LINK_TOL:
2074 m_ptr->tolerance = new_value;
636c0371 2075 break;
5c216e1d
AS
2076 case TIPC_CMD_SET_LINK_PRI:
2077 m_ptr->priority = new_value;
636c0371 2078 break;
5c216e1d
AS
2079 case TIPC_CMD_SET_LINK_WINDOW:
2080 m_ptr->window = new_value;
636c0371
YX
2081 break;
2082 default:
2083 res = -EINVAL;
2084 break;
5c216e1d 2085 }
636c0371 2086 return res;
5c216e1d
AS
2087}
2088
f2f9800d
YX
2089struct sk_buff *tipc_link_cmd_config(struct net *net, const void *req_tlv_area,
2090 int req_tlv_space, u16 cmd)
b97bf3fd
PL
2091{
2092 struct tipc_link_config *args;
c4307285 2093 u32 new_value;
c4307285 2094 int res;
b97bf3fd
PL
2095
2096 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_CONFIG))
4323add6 2097 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
b97bf3fd
PL
2098
2099 args = (struct tipc_link_config *)TLV_DATA(req_tlv_area);
2100 new_value = ntohl(args->value);
2101
5c216e1d
AS
2102 if (!link_value_is_valid(cmd, new_value))
2103 return tipc_cfg_reply_error_string(
2104 "cannot change, value invalid");
2105
4323add6 2106 if (!strcmp(args->name, tipc_bclink_name)) {
b97bf3fd 2107 if ((cmd == TIPC_CMD_SET_LINK_WINDOW) &&
4323add6
PL
2108 (tipc_bclink_set_queue_limits(new_value) == 0))
2109 return tipc_cfg_reply_none();
c4307285 2110 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
4323add6 2111 " (cannot change setting on broadcast link)");
b97bf3fd
PL
2112 }
2113
f2f9800d 2114 res = link_cmd_set_value(net, args->name, new_value, cmd);
b97bf3fd 2115 if (res)
c4307285 2116 return tipc_cfg_reply_error_string("cannot change link setting");
b97bf3fd 2117
4323add6 2118 return tipc_cfg_reply_none();
b97bf3fd
PL
2119}
2120
2121/**
2122 * link_reset_statistics - reset link statistics
2123 * @l_ptr: pointer to link
2124 */
a18c4bc3 2125static void link_reset_statistics(struct tipc_link *l_ptr)
b97bf3fd
PL
2126{
2127 memset(&l_ptr->stats, 0, sizeof(l_ptr->stats));
2128 l_ptr->stats.sent_info = l_ptr->next_out_no;
2129 l_ptr->stats.recv_info = l_ptr->next_in_no;
2130}
2131
f2f9800d
YX
2132struct sk_buff *tipc_link_cmd_reset_stats(struct net *net,
2133 const void *req_tlv_area,
2134 int req_tlv_space)
b97bf3fd
PL
2135{
2136 char *link_name;
a18c4bc3 2137 struct tipc_link *l_ptr;
6c00055a 2138 struct tipc_node *node;
e099e86c 2139 unsigned int bearer_id;
b97bf3fd
PL
2140
2141 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME))
4323add6 2142 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
b97bf3fd
PL
2143
2144 link_name = (char *)TLV_DATA(req_tlv_area);
4323add6
PL
2145 if (!strcmp(link_name, tipc_bclink_name)) {
2146 if (tipc_bclink_reset_stats())
2147 return tipc_cfg_reply_error_string("link not found");
2148 return tipc_cfg_reply_none();
b97bf3fd 2149 }
f2f9800d 2150 node = tipc_link_find_owner(net, link_name, &bearer_id);
7216cd94 2151 if (!node)
e099e86c 2152 return tipc_cfg_reply_error_string("link not found");
7216cd94 2153
a11607f5 2154 tipc_node_lock(node);
e099e86c 2155 l_ptr = node->links[bearer_id];
b97bf3fd 2156 if (!l_ptr) {
e099e86c 2157 tipc_node_unlock(node);
4323add6 2158 return tipc_cfg_reply_error_string("link not found");
b97bf3fd 2159 }
b97bf3fd 2160 link_reset_statistics(l_ptr);
4323add6 2161 tipc_node_unlock(node);
4323add6 2162 return tipc_cfg_reply_none();
b97bf3fd
PL
2163}
2164
2165/**
2166 * percent - convert count to a percentage of total (rounding up or down)
2167 */
b97bf3fd
PL
2168static u32 percent(u32 count, u32 total)
2169{
2170 return (count * 100 + (total / 2)) / total;
2171}
2172
2173/**
4323add6 2174 * tipc_link_stats - print link statistics
f2f9800d 2175 * @net: the applicable net namespace
b97bf3fd
PL
2176 * @name: link name
2177 * @buf: print buffer area
2178 * @buf_size: size of print buffer area
c4307285 2179 *
b97bf3fd
PL
2180 * Returns length of print buffer data string (or 0 if error)
2181 */
f2f9800d
YX
2182static int tipc_link_stats(struct net *net, const char *name, char *buf,
2183 const u32 buf_size)
b97bf3fd 2184{
dc1aed37
EH
2185 struct tipc_link *l;
2186 struct tipc_stats *s;
6c00055a 2187 struct tipc_node *node;
b97bf3fd
PL
2188 char *status;
2189 u32 profile_total = 0;
e099e86c 2190 unsigned int bearer_id;
dc1aed37 2191 int ret;
b97bf3fd 2192
4323add6
PL
2193 if (!strcmp(name, tipc_bclink_name))
2194 return tipc_bclink_stats(buf, buf_size);
b97bf3fd 2195
f2f9800d 2196 node = tipc_link_find_owner(net, name, &bearer_id);
7216cd94 2197 if (!node)
b97bf3fd 2198 return 0;
7216cd94 2199
4323add6 2200 tipc_node_lock(node);
e099e86c
JPM
2201
2202 l = node->links[bearer_id];
2203 if (!l) {
2204 tipc_node_unlock(node);
e099e86c
JPM
2205 return 0;
2206 }
2207
dc1aed37 2208 s = &l->stats;
b97bf3fd 2209
dc1aed37 2210 if (tipc_link_is_active(l))
b97bf3fd 2211 status = "ACTIVE";
dc1aed37 2212 else if (tipc_link_is_up(l))
b97bf3fd
PL
2213 status = "STANDBY";
2214 else
2215 status = "DEFUNCT";
dc1aed37
EH
2216
2217 ret = tipc_snprintf(buf, buf_size, "Link <%s>\n"
2218 " %s MTU:%u Priority:%u Tolerance:%u ms"
2219 " Window:%u packets\n",
2220 l->name, status, l->max_pkt, l->priority,
2221 l->tolerance, l->queue_limit[0]);
2222
2223 ret += tipc_snprintf(buf + ret, buf_size - ret,
2224 " RX packets:%u fragments:%u/%u bundles:%u/%u\n",
2225 l->next_in_no - s->recv_info, s->recv_fragments,
2226 s->recv_fragmented, s->recv_bundles,
2227 s->recv_bundled);
2228
2229 ret += tipc_snprintf(buf + ret, buf_size - ret,
2230 " TX packets:%u fragments:%u/%u bundles:%u/%u\n",
2231 l->next_out_no - s->sent_info, s->sent_fragments,
2232 s->sent_fragmented, s->sent_bundles,
2233 s->sent_bundled);
2234
2235 profile_total = s->msg_length_counts;
b97bf3fd
PL
2236 if (!profile_total)
2237 profile_total = 1;
dc1aed37
EH
2238
2239 ret += tipc_snprintf(buf + ret, buf_size - ret,
2240 " TX profile sample:%u packets average:%u octets\n"
2241 " 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% "
2242 "-16384:%u%% -32768:%u%% -66000:%u%%\n",
2243 s->msg_length_counts,
2244 s->msg_lengths_total / profile_total,
2245 percent(s->msg_length_profile[0], profile_total),
2246 percent(s->msg_length_profile[1], profile_total),
2247 percent(s->msg_length_profile[2], profile_total),
2248 percent(s->msg_length_profile[3], profile_total),
2249 percent(s->msg_length_profile[4], profile_total),
2250 percent(s->msg_length_profile[5], profile_total),
2251 percent(s->msg_length_profile[6], profile_total));
2252
2253 ret += tipc_snprintf(buf + ret, buf_size - ret,
2254 " RX states:%u probes:%u naks:%u defs:%u"
2255 " dups:%u\n", s->recv_states, s->recv_probes,
2256 s->recv_nacks, s->deferred_recv, s->duplicates);
2257
2258 ret += tipc_snprintf(buf + ret, buf_size - ret,
2259 " TX states:%u probes:%u naks:%u acks:%u"
2260 " dups:%u\n", s->sent_states, s->sent_probes,
2261 s->sent_nacks, s->sent_acks, s->retransmitted);
2262
2263 ret += tipc_snprintf(buf + ret, buf_size - ret,
3c294cb3
YX
2264 " Congestion link:%u Send queue"
2265 " max:%u avg:%u\n", s->link_congs,
dc1aed37
EH
2266 s->max_queue_sz, s->queue_sz_counts ?
2267 (s->accu_queue_sz / s->queue_sz_counts) : 0);
b97bf3fd 2268
4323add6 2269 tipc_node_unlock(node);
dc1aed37 2270 return ret;
b97bf3fd
PL
2271}
2272
f2f9800d
YX
2273struct sk_buff *tipc_link_cmd_show_stats(struct net *net,
2274 const void *req_tlv_area,
2275 int req_tlv_space)
b97bf3fd
PL
2276{
2277 struct sk_buff *buf;
2278 struct tlv_desc *rep_tlv;
2279 int str_len;
dc1aed37
EH
2280 int pb_len;
2281 char *pb;
b97bf3fd
PL
2282
2283 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME))
4323add6 2284 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
b97bf3fd 2285
dc1aed37 2286 buf = tipc_cfg_reply_alloc(TLV_SPACE(ULTRA_STRING_MAX_LEN));
b97bf3fd
PL
2287 if (!buf)
2288 return NULL;
2289
2290 rep_tlv = (struct tlv_desc *)buf->data;
dc1aed37
EH
2291 pb = TLV_DATA(rep_tlv);
2292 pb_len = ULTRA_STRING_MAX_LEN;
f2f9800d 2293 str_len = tipc_link_stats(net, (char *)TLV_DATA(req_tlv_area),
dc1aed37 2294 pb, pb_len);
b97bf3fd 2295 if (!str_len) {
5f6d9123 2296 kfree_skb(buf);
c4307285 2297 return tipc_cfg_reply_error_string("link not found");
b97bf3fd 2298 }
dc1aed37 2299 str_len += 1; /* for "\0" */
b97bf3fd
PL
2300 skb_put(buf, TLV_SPACE(str_len));
2301 TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len);
2302
2303 return buf;
2304}
2305
a18c4bc3 2306static void link_print(struct tipc_link *l_ptr, const char *str)
b97bf3fd 2307{
7f9f95d9 2308 struct tipc_net *tn = net_generic(l_ptr->owner->net, tipc_net_id);
7a2f7d18
YX
2309 struct tipc_bearer *b_ptr;
2310
2311 rcu_read_lock();
7f9f95d9 2312 b_ptr = rcu_dereference_rtnl(tn->bearer_list[l_ptr->bearer_id]);
7a2f7d18
YX
2313 if (b_ptr)
2314 pr_info("%s Link %x<%s>:", str, l_ptr->addr, b_ptr->name);
2315 rcu_read_unlock();
8d64a5ba 2316
b97bf3fd 2317 if (link_working_unknown(l_ptr))
5deedde9 2318 pr_cont(":WU\n");
8d64a5ba 2319 else if (link_reset_reset(l_ptr))
5deedde9 2320 pr_cont(":RR\n");
8d64a5ba 2321 else if (link_reset_unknown(l_ptr))
5deedde9 2322 pr_cont(":RU\n");
8d64a5ba 2323 else if (link_working_working(l_ptr))
5deedde9
PG
2324 pr_cont(":WW\n");
2325 else
2326 pr_cont("\n");
b97bf3fd 2327}
0655f6a8
RA
2328
2329/* Parse and validate nested (link) properties valid for media, bearer and link
2330 */
2331int tipc_nl_parse_link_prop(struct nlattr *prop, struct nlattr *props[])
2332{
2333 int err;
2334
2335 err = nla_parse_nested(props, TIPC_NLA_PROP_MAX, prop,
2336 tipc_nl_prop_policy);
2337 if (err)
2338 return err;
2339
2340 if (props[TIPC_NLA_PROP_PRIO]) {
2341 u32 prio;
2342
2343 prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
2344 if (prio > TIPC_MAX_LINK_PRI)
2345 return -EINVAL;
2346 }
2347
2348 if (props[TIPC_NLA_PROP_TOL]) {
2349 u32 tol;
2350
2351 tol = nla_get_u32(props[TIPC_NLA_PROP_TOL]);
2352 if ((tol < TIPC_MIN_LINK_TOL) || (tol > TIPC_MAX_LINK_TOL))
2353 return -EINVAL;
2354 }
2355
2356 if (props[TIPC_NLA_PROP_WIN]) {
2357 u32 win;
2358
2359 win = nla_get_u32(props[TIPC_NLA_PROP_WIN]);
2360 if ((win < TIPC_MIN_LINK_WIN) || (win > TIPC_MAX_LINK_WIN))
2361 return -EINVAL;
2362 }
2363
2364 return 0;
2365}
7be57fc6 2366
f96ce7a2
RA
2367int tipc_nl_link_set(struct sk_buff *skb, struct genl_info *info)
2368{
2369 int err;
2370 int res = 0;
2371 int bearer_id;
2372 char *name;
2373 struct tipc_link *link;
2374 struct tipc_node *node;
2375 struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1];
f2f9800d 2376 struct net *net = genl_info_net(info);
f96ce7a2
RA
2377
2378 if (!info->attrs[TIPC_NLA_LINK])
2379 return -EINVAL;
2380
2381 err = nla_parse_nested(attrs, TIPC_NLA_LINK_MAX,
2382 info->attrs[TIPC_NLA_LINK],
2383 tipc_nl_link_policy);
2384 if (err)
2385 return err;
2386
2387 if (!attrs[TIPC_NLA_LINK_NAME])
2388 return -EINVAL;
2389
2390 name = nla_data(attrs[TIPC_NLA_LINK_NAME]);
2391
f2f9800d 2392 node = tipc_link_find_owner(net, name, &bearer_id);
f96ce7a2
RA
2393 if (!node)
2394 return -EINVAL;
2395
2396 tipc_node_lock(node);
2397
2398 link = node->links[bearer_id];
2399 if (!link) {
2400 res = -EINVAL;
2401 goto out;
2402 }
2403
2404 if (attrs[TIPC_NLA_LINK_PROP]) {
2405 struct nlattr *props[TIPC_NLA_PROP_MAX + 1];
2406
2407 err = tipc_nl_parse_link_prop(attrs[TIPC_NLA_LINK_PROP],
2408 props);
2409 if (err) {
2410 res = err;
2411 goto out;
2412 }
2413
2414 if (props[TIPC_NLA_PROP_TOL]) {
2415 u32 tol;
2416
2417 tol = nla_get_u32(props[TIPC_NLA_PROP_TOL]);
2418 link_set_supervision_props(link, tol);
2419 tipc_link_proto_xmit(link, STATE_MSG, 0, 0, tol, 0, 0);
2420 }
2421 if (props[TIPC_NLA_PROP_PRIO]) {
2422 u32 prio;
2423
2424 prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
2425 link->priority = prio;
2426 tipc_link_proto_xmit(link, STATE_MSG, 0, 0, 0, prio, 0);
2427 }
2428 if (props[TIPC_NLA_PROP_WIN]) {
2429 u32 win;
2430
2431 win = nla_get_u32(props[TIPC_NLA_PROP_WIN]);
2432 tipc_link_set_queue_limits(link, win);
2433 }
2434 }
2435
2436out:
2437 tipc_node_unlock(node);
2438
2439 return res;
2440}
d8182804
RA
2441
2442static int __tipc_nl_add_stats(struct sk_buff *skb, struct tipc_stats *s)
7be57fc6
RA
2443{
2444 int i;
2445 struct nlattr *stats;
2446
2447 struct nla_map {
2448 u32 key;
2449 u32 val;
2450 };
2451
2452 struct nla_map map[] = {
2453 {TIPC_NLA_STATS_RX_INFO, s->recv_info},
2454 {TIPC_NLA_STATS_RX_FRAGMENTS, s->recv_fragments},
2455 {TIPC_NLA_STATS_RX_FRAGMENTED, s->recv_fragmented},
2456 {TIPC_NLA_STATS_RX_BUNDLES, s->recv_bundles},
2457 {TIPC_NLA_STATS_RX_BUNDLED, s->recv_bundled},
2458 {TIPC_NLA_STATS_TX_INFO, s->sent_info},
2459 {TIPC_NLA_STATS_TX_FRAGMENTS, s->sent_fragments},
2460 {TIPC_NLA_STATS_TX_FRAGMENTED, s->sent_fragmented},
2461 {TIPC_NLA_STATS_TX_BUNDLES, s->sent_bundles},
2462 {TIPC_NLA_STATS_TX_BUNDLED, s->sent_bundled},
2463 {TIPC_NLA_STATS_MSG_PROF_TOT, (s->msg_length_counts) ?
2464 s->msg_length_counts : 1},
2465 {TIPC_NLA_STATS_MSG_LEN_CNT, s->msg_length_counts},
2466 {TIPC_NLA_STATS_MSG_LEN_TOT, s->msg_lengths_total},
2467 {TIPC_NLA_STATS_MSG_LEN_P0, s->msg_length_profile[0]},
2468 {TIPC_NLA_STATS_MSG_LEN_P1, s->msg_length_profile[1]},
2469 {TIPC_NLA_STATS_MSG_LEN_P2, s->msg_length_profile[2]},
2470 {TIPC_NLA_STATS_MSG_LEN_P3, s->msg_length_profile[3]},
2471 {TIPC_NLA_STATS_MSG_LEN_P4, s->msg_length_profile[4]},
2472 {TIPC_NLA_STATS_MSG_LEN_P5, s->msg_length_profile[5]},
2473 {TIPC_NLA_STATS_MSG_LEN_P6, s->msg_length_profile[6]},
2474 {TIPC_NLA_STATS_RX_STATES, s->recv_states},
2475 {TIPC_NLA_STATS_RX_PROBES, s->recv_probes},
2476 {TIPC_NLA_STATS_RX_NACKS, s->recv_nacks},
2477 {TIPC_NLA_STATS_RX_DEFERRED, s->deferred_recv},
2478 {TIPC_NLA_STATS_TX_STATES, s->sent_states},
2479 {TIPC_NLA_STATS_TX_PROBES, s->sent_probes},
2480 {TIPC_NLA_STATS_TX_NACKS, s->sent_nacks},
2481 {TIPC_NLA_STATS_TX_ACKS, s->sent_acks},
2482 {TIPC_NLA_STATS_RETRANSMITTED, s->retransmitted},
2483 {TIPC_NLA_STATS_DUPLICATES, s->duplicates},
2484 {TIPC_NLA_STATS_LINK_CONGS, s->link_congs},
2485 {TIPC_NLA_STATS_MAX_QUEUE, s->max_queue_sz},
2486 {TIPC_NLA_STATS_AVG_QUEUE, s->queue_sz_counts ?
2487 (s->accu_queue_sz / s->queue_sz_counts) : 0}
2488 };
2489
2490 stats = nla_nest_start(skb, TIPC_NLA_LINK_STATS);
2491 if (!stats)
2492 return -EMSGSIZE;
2493
2494 for (i = 0; i < ARRAY_SIZE(map); i++)
2495 if (nla_put_u32(skb, map[i].key, map[i].val))
2496 goto msg_full;
2497
2498 nla_nest_end(skb, stats);
2499
2500 return 0;
2501msg_full:
2502 nla_nest_cancel(skb, stats);
2503
2504 return -EMSGSIZE;
2505}
2506
2507/* Caller should hold appropriate locks to protect the link */
d8182804 2508static int __tipc_nl_add_link(struct tipc_nl_msg *msg, struct tipc_link *link)
7be57fc6
RA
2509{
2510 int err;
2511 void *hdr;
2512 struct nlattr *attrs;
2513 struct nlattr *prop;
2514
2515 hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_v2_family,
2516 NLM_F_MULTI, TIPC_NL_LINK_GET);
2517 if (!hdr)
2518 return -EMSGSIZE;
2519
2520 attrs = nla_nest_start(msg->skb, TIPC_NLA_LINK);
2521 if (!attrs)
2522 goto msg_full;
2523
2524 if (nla_put_string(msg->skb, TIPC_NLA_LINK_NAME, link->name))
2525 goto attr_msg_full;
2526 if (nla_put_u32(msg->skb, TIPC_NLA_LINK_DEST,
2527 tipc_cluster_mask(tipc_own_addr)))
2528 goto attr_msg_full;
2529 if (nla_put_u32(msg->skb, TIPC_NLA_LINK_MTU, link->max_pkt))
2530 goto attr_msg_full;
2531 if (nla_put_u32(msg->skb, TIPC_NLA_LINK_RX, link->next_in_no))
2532 goto attr_msg_full;
2533 if (nla_put_u32(msg->skb, TIPC_NLA_LINK_TX, link->next_out_no))
2534 goto attr_msg_full;
2535
2536 if (tipc_link_is_up(link))
2537 if (nla_put_flag(msg->skb, TIPC_NLA_LINK_UP))
2538 goto attr_msg_full;
2539 if (tipc_link_is_active(link))
2540 if (nla_put_flag(msg->skb, TIPC_NLA_LINK_ACTIVE))
2541 goto attr_msg_full;
2542
2543 prop = nla_nest_start(msg->skb, TIPC_NLA_LINK_PROP);
2544 if (!prop)
2545 goto attr_msg_full;
2546 if (nla_put_u32(msg->skb, TIPC_NLA_PROP_PRIO, link->priority))
2547 goto prop_msg_full;
2548 if (nla_put_u32(msg->skb, TIPC_NLA_PROP_TOL, link->tolerance))
2549 goto prop_msg_full;
2550 if (nla_put_u32(msg->skb, TIPC_NLA_PROP_WIN,
2551 link->queue_limit[TIPC_LOW_IMPORTANCE]))
2552 goto prop_msg_full;
2553 if (nla_put_u32(msg->skb, TIPC_NLA_PROP_PRIO, link->priority))
2554 goto prop_msg_full;
2555 nla_nest_end(msg->skb, prop);
2556
2557 err = __tipc_nl_add_stats(msg->skb, &link->stats);
2558 if (err)
2559 goto attr_msg_full;
2560
2561 nla_nest_end(msg->skb, attrs);
2562 genlmsg_end(msg->skb, hdr);
2563
2564 return 0;
2565
2566prop_msg_full:
2567 nla_nest_cancel(msg->skb, prop);
2568attr_msg_full:
2569 nla_nest_cancel(msg->skb, attrs);
2570msg_full:
2571 genlmsg_cancel(msg->skb, hdr);
2572
2573 return -EMSGSIZE;
2574}
2575
2576/* Caller should hold node lock */
d8182804
RA
2577static int __tipc_nl_add_node_links(struct tipc_nl_msg *msg,
2578 struct tipc_node *node,
2579 u32 *prev_link)
7be57fc6
RA
2580{
2581 u32 i;
2582 int err;
2583
2584 for (i = *prev_link; i < MAX_BEARERS; i++) {
2585 *prev_link = i;
2586
2587 if (!node->links[i])
2588 continue;
2589
2590 err = __tipc_nl_add_link(msg, node->links[i]);
2591 if (err)
2592 return err;
2593 }
2594 *prev_link = 0;
2595
2596 return 0;
2597}
2598
2599int tipc_nl_link_dump(struct sk_buff *skb, struct netlink_callback *cb)
2600{
f2f9800d
YX
2601 struct net *net = sock_net(skb->sk);
2602 struct tipc_net *tn = net_generic(net, tipc_net_id);
7be57fc6
RA
2603 struct tipc_node *node;
2604 struct tipc_nl_msg msg;
2605 u32 prev_node = cb->args[0];
2606 u32 prev_link = cb->args[1];
2607 int done = cb->args[2];
2608 int err;
2609
2610 if (done)
2611 return 0;
2612
2613 msg.skb = skb;
2614 msg.portid = NETLINK_CB(cb->skb).portid;
2615 msg.seq = cb->nlh->nlmsg_seq;
2616
2617 rcu_read_lock();
2618
2619 if (prev_node) {
f2f9800d 2620 node = tipc_node_find(net, prev_node);
7be57fc6
RA
2621 if (!node) {
2622 /* We never set seq or call nl_dump_check_consistent()
2623 * this means that setting prev_seq here will cause the
2624 * consistence check to fail in the netlink callback
2625 * handler. Resulting in the last NLMSG_DONE message
2626 * having the NLM_F_DUMP_INTR flag set.
2627 */
2628 cb->prev_seq = 1;
2629 goto out;
2630 }
2631
f2f9800d
YX
2632 list_for_each_entry_continue_rcu(node, &tn->node_list,
2633 list) {
7be57fc6
RA
2634 tipc_node_lock(node);
2635 err = __tipc_nl_add_node_links(&msg, node, &prev_link);
2636 tipc_node_unlock(node);
2637 if (err)
2638 goto out;
2639
2640 prev_node = node->addr;
2641 }
2642 } else {
2643 err = tipc_nl_add_bc_link(&msg);
2644 if (err)
2645 goto out;
2646
f2f9800d 2647 list_for_each_entry_rcu(node, &tn->node_list, list) {
7be57fc6
RA
2648 tipc_node_lock(node);
2649 err = __tipc_nl_add_node_links(&msg, node, &prev_link);
2650 tipc_node_unlock(node);
2651 if (err)
2652 goto out;
2653
2654 prev_node = node->addr;
2655 }
2656 }
2657 done = 1;
2658out:
2659 rcu_read_unlock();
2660
2661 cb->args[0] = prev_node;
2662 cb->args[1] = prev_link;
2663 cb->args[2] = done;
2664
2665 return skb->len;
2666}
2667
2668int tipc_nl_link_get(struct sk_buff *skb, struct genl_info *info)
2669{
f2f9800d 2670 struct net *net = genl_info_net(info);
7be57fc6
RA
2671 struct sk_buff *ans_skb;
2672 struct tipc_nl_msg msg;
2673 struct tipc_link *link;
2674 struct tipc_node *node;
2675 char *name;
2676 int bearer_id;
2677 int err;
2678
2679 if (!info->attrs[TIPC_NLA_LINK_NAME])
2680 return -EINVAL;
2681
2682 name = nla_data(info->attrs[TIPC_NLA_LINK_NAME]);
f2f9800d 2683 node = tipc_link_find_owner(net, name, &bearer_id);
7be57fc6
RA
2684 if (!node)
2685 return -EINVAL;
2686
2687 ans_skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
2688 if (!ans_skb)
2689 return -ENOMEM;
2690
2691 msg.skb = ans_skb;
2692 msg.portid = info->snd_portid;
2693 msg.seq = info->snd_seq;
2694
2695 tipc_node_lock(node);
2696 link = node->links[bearer_id];
2697 if (!link) {
2698 err = -EINVAL;
2699 goto err_out;
2700 }
2701
2702 err = __tipc_nl_add_link(&msg, link);
2703 if (err)
2704 goto err_out;
2705
2706 tipc_node_unlock(node);
2707
2708 return genlmsg_reply(ans_skb, info);
2709
2710err_out:
2711 tipc_node_unlock(node);
2712 nlmsg_free(ans_skb);
2713
2714 return err;
2715}
ae36342b
RA
2716
2717int tipc_nl_link_reset_stats(struct sk_buff *skb, struct genl_info *info)
2718{
2719 int err;
2720 char *link_name;
2721 unsigned int bearer_id;
2722 struct tipc_link *link;
2723 struct tipc_node *node;
2724 struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1];
f2f9800d 2725 struct net *net = genl_info_net(info);
ae36342b
RA
2726
2727 if (!info->attrs[TIPC_NLA_LINK])
2728 return -EINVAL;
2729
2730 err = nla_parse_nested(attrs, TIPC_NLA_LINK_MAX,
2731 info->attrs[TIPC_NLA_LINK],
2732 tipc_nl_link_policy);
2733 if (err)
2734 return err;
2735
2736 if (!attrs[TIPC_NLA_LINK_NAME])
2737 return -EINVAL;
2738
2739 link_name = nla_data(attrs[TIPC_NLA_LINK_NAME]);
2740
2741 if (strcmp(link_name, tipc_bclink_name) == 0) {
2742 err = tipc_bclink_reset_stats();
2743 if (err)
2744 return err;
2745 return 0;
2746 }
2747
f2f9800d 2748 node = tipc_link_find_owner(net, link_name, &bearer_id);
ae36342b
RA
2749 if (!node)
2750 return -EINVAL;
2751
2752 tipc_node_lock(node);
2753
2754 link = node->links[bearer_id];
2755 if (!link) {
2756 tipc_node_unlock(node);
2757 return -EINVAL;
2758 }
2759
2760 link_reset_statistics(link);
2761
2762 tipc_node_unlock(node);
2763
2764 return 0;
2765}