diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /net/tipc/link.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r-- | net/tipc/link.c | 789 |
1 files changed, 251 insertions, 538 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c index a3616b99529b..5ed4b4f7452d 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * net/tipc/link.c: TIPC link code | 2 | * net/tipc/link.c: TIPC link code |
3 | * | 3 | * |
4 | * Copyright (c) 1996-2007, Ericsson AB | 4 | * Copyright (c) 1996-2007, Ericsson AB |
5 | * Copyright (c) 2004-2007, Wind River Systems | 5 | * Copyright (c) 2004-2007, 2010-2011, Wind River Systems |
6 | * All rights reserved. | 6 | * All rights reserved. |
7 | * | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
@@ -35,19 +35,11 @@ | |||
35 | */ | 35 | */ |
36 | 36 | ||
37 | #include "core.h" | 37 | #include "core.h" |
38 | #include "dbg.h" | ||
39 | #include "link.h" | 38 | #include "link.h" |
40 | #include "net.h" | ||
41 | #include "node.h" | ||
42 | #include "port.h" | 39 | #include "port.h" |
43 | #include "addr.h" | ||
44 | #include "node_subscr.h" | ||
45 | #include "name_distr.h" | 40 | #include "name_distr.h" |
46 | #include "bearer.h" | ||
47 | #include "name_table.h" | ||
48 | #include "discover.h" | 41 | #include "discover.h" |
49 | #include "config.h" | 42 | #include "config.h" |
50 | #include "bcast.h" | ||
51 | 43 | ||
52 | 44 | ||
53 | /* | 45 | /* |
@@ -57,12 +49,6 @@ | |||
57 | #define INVALID_SESSION 0x10000 | 49 | #define INVALID_SESSION 0x10000 |
58 | 50 | ||
59 | /* | 51 | /* |
60 | * Limit for deferred reception queue: | ||
61 | */ | ||
62 | |||
63 | #define DEF_QUEUE_LIMIT 256u | ||
64 | |||
65 | /* | ||
66 | * Link state events: | 52 | * Link state events: |
67 | */ | 53 | */ |
68 | 54 | ||
@@ -99,99 +85,21 @@ struct link_name { | |||
99 | char if_peer[TIPC_MAX_IF_NAME]; | 85 | char if_peer[TIPC_MAX_IF_NAME]; |
100 | }; | 86 | }; |
101 | 87 | ||
102 | #if 0 | ||
103 | |||
104 | /* LINK EVENT CODE IS NOT SUPPORTED AT PRESENT */ | ||
105 | |||
106 | /** | ||
107 | * struct link_event - link up/down event notification | ||
108 | */ | ||
109 | |||
110 | struct link_event { | ||
111 | u32 addr; | ||
112 | int up; | ||
113 | void (*fcn)(u32, char *, int); | ||
114 | char name[TIPC_MAX_LINK_NAME]; | ||
115 | }; | ||
116 | |||
117 | #endif | ||
118 | |||
119 | static void link_handle_out_of_seq_msg(struct link *l_ptr, | 88 | static void link_handle_out_of_seq_msg(struct link *l_ptr, |
120 | struct sk_buff *buf); | 89 | struct sk_buff *buf); |
121 | static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf); | 90 | static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf); |
122 | static int link_recv_changeover_msg(struct link **l_ptr, struct sk_buff **buf); | 91 | static int link_recv_changeover_msg(struct link **l_ptr, struct sk_buff **buf); |
123 | static void link_set_supervision_props(struct link *l_ptr, u32 tolerance); | 92 | static void link_set_supervision_props(struct link *l_ptr, u32 tolerance); |
124 | static int link_send_sections_long(struct port *sender, | 93 | static int link_send_sections_long(struct tipc_port *sender, |
125 | struct iovec const *msg_sect, | 94 | struct iovec const *msg_sect, |
126 | u32 num_sect, u32 destnode); | 95 | u32 num_sect, unsigned int total_len, |
96 | u32 destnode); | ||
127 | static void link_check_defragm_bufs(struct link *l_ptr); | 97 | static void link_check_defragm_bufs(struct link *l_ptr); |
128 | static void link_state_event(struct link *l_ptr, u32 event); | 98 | static void link_state_event(struct link *l_ptr, u32 event); |
129 | static void link_reset_statistics(struct link *l_ptr); | 99 | static void link_reset_statistics(struct link *l_ptr); |
130 | static void link_print(struct link *l_ptr, struct print_buf *buf, | 100 | static void link_print(struct link *l_ptr, const char *str); |
131 | const char *str); | 101 | static void link_start(struct link *l_ptr); |
132 | 102 | static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf); | |
133 | /* | ||
134 | * Debugging code used by link routines only | ||
135 | * | ||
136 | * When debugging link problems on a system that has multiple links, | ||
137 | * the standard TIPC debugging routines may not be useful since they | ||
138 | * allow the output from multiple links to be intermixed. For this reason | ||
139 | * routines of the form "dbg_link_XXX()" have been created that will capture | ||
140 | * debug info into a link's personal print buffer, which can then be dumped | ||
141 | * into the TIPC system log (TIPC_LOG) upon request. | ||
142 | * | ||
143 | * To enable per-link debugging, use LINK_LOG_BUF_SIZE to specify the size | ||
144 | * of the print buffer used by each link. If LINK_LOG_BUF_SIZE is set to 0, | ||
145 | * the dbg_link_XXX() routines simply send their output to the standard | ||
146 | * debug print buffer (DBG_OUTPUT), if it has been defined; this can be useful | ||
147 | * when there is only a single link in the system being debugged. | ||
148 | * | ||
149 | * Notes: | ||
150 | * - When enabled, LINK_LOG_BUF_SIZE should be set to at least TIPC_PB_MIN_SIZE | ||
151 | * - "l_ptr" must be valid when using dbg_link_XXX() macros | ||
152 | */ | ||
153 | |||
154 | #define LINK_LOG_BUF_SIZE 0 | ||
155 | |||
156 | #define dbg_link(fmt, arg...) \ | ||
157 | do { \ | ||
158 | if (LINK_LOG_BUF_SIZE) \ | ||
159 | tipc_printf(&l_ptr->print_buf, fmt, ## arg); \ | ||
160 | } while (0) | ||
161 | #define dbg_link_msg(msg, txt) \ | ||
162 | do { \ | ||
163 | if (LINK_LOG_BUF_SIZE) \ | ||
164 | tipc_msg_dbg(&l_ptr->print_buf, msg, txt); \ | ||
165 | } while (0) | ||
166 | #define dbg_link_state(txt) \ | ||
167 | do { \ | ||
168 | if (LINK_LOG_BUF_SIZE) \ | ||
169 | link_print(l_ptr, &l_ptr->print_buf, txt); \ | ||
170 | } while (0) | ||
171 | #define dbg_link_dump() do { \ | ||
172 | if (LINK_LOG_BUF_SIZE) { \ | ||
173 | tipc_printf(LOG, "\n\nDumping link <%s>:\n", l_ptr->name); \ | ||
174 | tipc_printbuf_move(LOG, &l_ptr->print_buf); \ | ||
175 | } \ | ||
176 | } while (0) | ||
177 | |||
178 | static void dbg_print_link(struct link *l_ptr, const char *str) | ||
179 | { | ||
180 | if (DBG_OUTPUT != TIPC_NULL) | ||
181 | link_print(l_ptr, DBG_OUTPUT, str); | ||
182 | } | ||
183 | |||
184 | static void dbg_print_buf_chain(struct sk_buff *root_buf) | ||
185 | { | ||
186 | if (DBG_OUTPUT != TIPC_NULL) { | ||
187 | struct sk_buff *buf = root_buf; | ||
188 | |||
189 | while (buf) { | ||
190 | msg_dbg(buf_msg(buf), "In chain: "); | ||
191 | buf = buf->next; | ||
192 | } | ||
193 | } | ||
194 | } | ||
195 | 103 | ||
196 | /* | 104 | /* |
197 | * Simple link routines | 105 | * Simple link routines |
@@ -206,7 +114,7 @@ static void link_init_max_pkt(struct link *l_ptr) | |||
206 | { | 114 | { |
207 | u32 max_pkt; | 115 | u32 max_pkt; |
208 | 116 | ||
209 | max_pkt = (l_ptr->b_ptr->publ.mtu & ~3); | 117 | max_pkt = (l_ptr->b_ptr->mtu & ~3); |
210 | if (max_pkt > MAX_MSG_SIZE) | 118 | if (max_pkt > MAX_MSG_SIZE) |
211 | max_pkt = MAX_MSG_SIZE; | 119 | max_pkt = MAX_MSG_SIZE; |
212 | 120 | ||
@@ -239,13 +147,13 @@ int tipc_link_is_up(struct link *l_ptr) | |||
239 | { | 147 | { |
240 | if (!l_ptr) | 148 | if (!l_ptr) |
241 | return 0; | 149 | return 0; |
242 | return (link_working_working(l_ptr) || link_working_unknown(l_ptr)); | 150 | return link_working_working(l_ptr) || link_working_unknown(l_ptr); |
243 | } | 151 | } |
244 | 152 | ||
245 | int tipc_link_is_active(struct link *l_ptr) | 153 | int tipc_link_is_active(struct link *l_ptr) |
246 | { | 154 | { |
247 | return ((l_ptr->owner->active_links[0] == l_ptr) || | 155 | return (l_ptr->owner->active_links[0] == l_ptr) || |
248 | (l_ptr->owner->active_links[1] == l_ptr)); | 156 | (l_ptr->owner->active_links[1] == l_ptr); |
249 | } | 157 | } |
250 | 158 | ||
251 | /** | 159 | /** |
@@ -280,14 +188,17 @@ static int link_name_validate(const char *name, struct link_name *name_parts) | |||
280 | /* ensure all component parts of link name are present */ | 188 | /* ensure all component parts of link name are present */ |
281 | 189 | ||
282 | addr_local = name_copy; | 190 | addr_local = name_copy; |
283 | if ((if_local = strchr(addr_local, ':')) == NULL) | 191 | if_local = strchr(addr_local, ':'); |
192 | if (if_local == NULL) | ||
284 | return 0; | 193 | return 0; |
285 | *(if_local++) = 0; | 194 | *(if_local++) = 0; |
286 | if ((addr_peer = strchr(if_local, '-')) == NULL) | 195 | addr_peer = strchr(if_local, '-'); |
196 | if (addr_peer == NULL) | ||
287 | return 0; | 197 | return 0; |
288 | *(addr_peer++) = 0; | 198 | *(addr_peer++) = 0; |
289 | if_local_len = addr_peer - if_local; | 199 | if_local_len = addr_peer - if_local; |
290 | if ((if_peer = strchr(addr_peer, ':')) == NULL) | 200 | if_peer = strchr(addr_peer, ':'); |
201 | if (if_peer == NULL) | ||
291 | return 0; | 202 | return 0; |
292 | *(if_peer++) = 0; | 203 | *(if_peer++) = 0; |
293 | if_peer_len = strlen(if_peer) + 1; | 204 | if_peer_len = strlen(if_peer) + 1; |
@@ -336,9 +247,6 @@ static void link_timeout(struct link *l_ptr) | |||
336 | l_ptr->stats.accu_queue_sz += l_ptr->out_queue_size; | 247 | l_ptr->stats.accu_queue_sz += l_ptr->out_queue_size; |
337 | l_ptr->stats.queue_sz_counts++; | 248 | l_ptr->stats.queue_sz_counts++; |
338 | 249 | ||
339 | if (l_ptr->out_queue_size > l_ptr->stats.max_queue_sz) | ||
340 | l_ptr->stats.max_queue_sz = l_ptr->out_queue_size; | ||
341 | |||
342 | if (l_ptr->first_out) { | 250 | if (l_ptr->first_out) { |
343 | struct tipc_msg *msg = buf_msg(l_ptr->first_out); | 251 | struct tipc_msg *msg = buf_msg(l_ptr->first_out); |
344 | u32 length = msg_size(msg); | 252 | u32 length = msg_size(msg); |
@@ -386,39 +294,44 @@ static void link_set_timer(struct link *l_ptr, u32 time) | |||
386 | 294 | ||
387 | /** | 295 | /** |
388 | * tipc_link_create - create a new link | 296 | * tipc_link_create - create a new link |
297 | * @n_ptr: pointer to associated node | ||
389 | * @b_ptr: pointer to associated bearer | 298 | * @b_ptr: pointer to associated bearer |
390 | * @peer: network address of node at other end of link | ||
391 | * @media_addr: media address to use when sending messages over link | 299 | * @media_addr: media address to use when sending messages over link |
392 | * | 300 | * |
393 | * Returns pointer to link. | 301 | * Returns pointer to link. |
394 | */ | 302 | */ |
395 | 303 | ||
396 | struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer, | 304 | struct link *tipc_link_create(struct tipc_node *n_ptr, |
305 | struct tipc_bearer *b_ptr, | ||
397 | const struct tipc_media_addr *media_addr) | 306 | const struct tipc_media_addr *media_addr) |
398 | { | 307 | { |
399 | struct link *l_ptr; | 308 | struct link *l_ptr; |
400 | struct tipc_msg *msg; | 309 | struct tipc_msg *msg; |
401 | char *if_name; | 310 | char *if_name; |
311 | char addr_string[16]; | ||
312 | u32 peer = n_ptr->addr; | ||
402 | 313 | ||
403 | l_ptr = kzalloc(sizeof(*l_ptr), GFP_ATOMIC); | 314 | if (n_ptr->link_cnt >= 2) { |
404 | if (!l_ptr) { | 315 | tipc_addr_string_fill(addr_string, n_ptr->addr); |
405 | warn("Link creation failed, no memory\n"); | 316 | err("Attempt to establish third link to %s\n", addr_string); |
406 | return NULL; | 317 | return NULL; |
407 | } | 318 | } |
408 | 319 | ||
409 | if (LINK_LOG_BUF_SIZE) { | 320 | if (n_ptr->links[b_ptr->identity]) { |
410 | char *pb = kmalloc(LINK_LOG_BUF_SIZE, GFP_ATOMIC); | 321 | tipc_addr_string_fill(addr_string, n_ptr->addr); |
322 | err("Attempt to establish second link on <%s> to %s\n", | ||
323 | b_ptr->name, addr_string); | ||
324 | return NULL; | ||
325 | } | ||
411 | 326 | ||
412 | if (!pb) { | 327 | l_ptr = kzalloc(sizeof(*l_ptr), GFP_ATOMIC); |
413 | kfree(l_ptr); | 328 | if (!l_ptr) { |
414 | warn("Link creation failed, no memory for print buffer\n"); | 329 | warn("Link creation failed, no memory\n"); |
415 | return NULL; | 330 | return NULL; |
416 | } | ||
417 | tipc_printbuf_init(&l_ptr->print_buf, pb, LINK_LOG_BUF_SIZE); | ||
418 | } | 331 | } |
419 | 332 | ||
420 | l_ptr->addr = peer; | 333 | l_ptr->addr = peer; |
421 | if_name = strchr(b_ptr->publ.name, ':') + 1; | 334 | if_name = strchr(b_ptr->name, ':') + 1; |
422 | sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:", | 335 | sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:", |
423 | tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr), | 336 | tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr), |
424 | tipc_node(tipc_own_addr), | 337 | tipc_node(tipc_own_addr), |
@@ -426,6 +339,7 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer, | |||
426 | tipc_zone(peer), tipc_cluster(peer), tipc_node(peer)); | 339 | tipc_zone(peer), tipc_cluster(peer), tipc_node(peer)); |
427 | /* note: peer i/f is appended to link name by reset/activate */ | 340 | /* note: peer i/f is appended to link name by reset/activate */ |
428 | memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr)); | 341 | memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr)); |
342 | l_ptr->owner = n_ptr; | ||
429 | l_ptr->checkpoint = 1; | 343 | l_ptr->checkpoint = 1; |
430 | l_ptr->b_ptr = b_ptr; | 344 | l_ptr->b_ptr = b_ptr; |
431 | link_set_supervision_props(l_ptr, b_ptr->media->tolerance); | 345 | link_set_supervision_props(l_ptr, b_ptr->media->tolerance); |
@@ -449,20 +363,11 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer, | |||
449 | 363 | ||
450 | link_reset_statistics(l_ptr); | 364 | link_reset_statistics(l_ptr); |
451 | 365 | ||
452 | l_ptr->owner = tipc_node_attach_link(l_ptr); | 366 | tipc_node_attach_link(n_ptr, l_ptr); |
453 | if (!l_ptr->owner) { | ||
454 | if (LINK_LOG_BUF_SIZE) | ||
455 | kfree(l_ptr->print_buf.buf); | ||
456 | kfree(l_ptr); | ||
457 | return NULL; | ||
458 | } | ||
459 | 367 | ||
460 | k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr); | 368 | k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr); |
461 | list_add_tail(&l_ptr->link_list, &b_ptr->links); | 369 | list_add_tail(&l_ptr->link_list, &b_ptr->links); |
462 | tipc_k_signal((Handler)tipc_link_start, (unsigned long)l_ptr); | 370 | tipc_k_signal((Handler)link_start, (unsigned long)l_ptr); |
463 | |||
464 | dbg("tipc_link_create(): tolerance = %u,cont intv = %u, abort_limit = %u\n", | ||
465 | l_ptr->tolerance, l_ptr->continuity_interval, l_ptr->abort_limit); | ||
466 | 371 | ||
467 | return l_ptr; | 372 | return l_ptr; |
468 | } | 373 | } |
@@ -483,8 +388,6 @@ void tipc_link_delete(struct link *l_ptr) | |||
483 | return; | 388 | return; |
484 | } | 389 | } |
485 | 390 | ||
486 | dbg("tipc_link_delete()\n"); | ||
487 | |||
488 | k_cancel_timer(&l_ptr->timer); | 391 | k_cancel_timer(&l_ptr->timer); |
489 | 392 | ||
490 | tipc_node_lock(l_ptr->owner); | 393 | tipc_node_lock(l_ptr->owner); |
@@ -492,17 +395,16 @@ void tipc_link_delete(struct link *l_ptr) | |||
492 | tipc_node_detach_link(l_ptr->owner, l_ptr); | 395 | tipc_node_detach_link(l_ptr->owner, l_ptr); |
493 | tipc_link_stop(l_ptr); | 396 | tipc_link_stop(l_ptr); |
494 | list_del_init(&l_ptr->link_list); | 397 | list_del_init(&l_ptr->link_list); |
495 | if (LINK_LOG_BUF_SIZE) | ||
496 | kfree(l_ptr->print_buf.buf); | ||
497 | tipc_node_unlock(l_ptr->owner); | 398 | tipc_node_unlock(l_ptr->owner); |
498 | k_term_timer(&l_ptr->timer); | 399 | k_term_timer(&l_ptr->timer); |
499 | kfree(l_ptr); | 400 | kfree(l_ptr); |
500 | } | 401 | } |
501 | 402 | ||
502 | void tipc_link_start(struct link *l_ptr) | 403 | static void link_start(struct link *l_ptr) |
503 | { | 404 | { |
504 | dbg("tipc_link_start %x\n", l_ptr); | 405 | tipc_node_lock(l_ptr->owner); |
505 | link_state_event(l_ptr, STARTING_EVT); | 406 | link_state_event(l_ptr, STARTING_EVT); |
407 | tipc_node_unlock(l_ptr->owner); | ||
506 | } | 408 | } |
507 | 409 | ||
508 | /** | 410 | /** |
@@ -517,7 +419,7 @@ void tipc_link_start(struct link *l_ptr) | |||
517 | 419 | ||
518 | static int link_schedule_port(struct link *l_ptr, u32 origport, u32 sz) | 420 | static int link_schedule_port(struct link *l_ptr, u32 origport, u32 sz) |
519 | { | 421 | { |
520 | struct port *p_ptr; | 422 | struct tipc_port *p_ptr; |
521 | 423 | ||
522 | spin_lock_bh(&tipc_port_list_lock); | 424 | spin_lock_bh(&tipc_port_list_lock); |
523 | p_ptr = tipc_port_lock(origport); | 425 | p_ptr = tipc_port_lock(origport); |
@@ -526,7 +428,7 @@ static int link_schedule_port(struct link *l_ptr, u32 origport, u32 sz) | |||
526 | goto exit; | 428 | goto exit; |
527 | if (!list_empty(&p_ptr->wait_list)) | 429 | if (!list_empty(&p_ptr->wait_list)) |
528 | goto exit; | 430 | goto exit; |
529 | p_ptr->publ.congested = 1; | 431 | p_ptr->congested = 1; |
530 | p_ptr->waiting_pkts = 1 + ((sz - 1) / l_ptr->max_pkt); | 432 | p_ptr->waiting_pkts = 1 + ((sz - 1) / l_ptr->max_pkt); |
531 | list_add_tail(&p_ptr->wait_list, &l_ptr->waiting_ports); | 433 | list_add_tail(&p_ptr->wait_list, &l_ptr->waiting_ports); |
532 | l_ptr->stats.link_congs++; | 434 | l_ptr->stats.link_congs++; |
@@ -539,8 +441,8 @@ exit: | |||
539 | 441 | ||
540 | void tipc_link_wakeup_ports(struct link *l_ptr, int all) | 442 | void tipc_link_wakeup_ports(struct link *l_ptr, int all) |
541 | { | 443 | { |
542 | struct port *p_ptr; | 444 | struct tipc_port *p_ptr; |
543 | struct port *temp_p_ptr; | 445 | struct tipc_port *temp_p_ptr; |
544 | int win = l_ptr->queue_limit[0] - l_ptr->out_queue_size; | 446 | int win = l_ptr->queue_limit[0] - l_ptr->out_queue_size; |
545 | 447 | ||
546 | if (all) | 448 | if (all) |
@@ -556,11 +458,11 @@ void tipc_link_wakeup_ports(struct link *l_ptr, int all) | |||
556 | if (win <= 0) | 458 | if (win <= 0) |
557 | break; | 459 | break; |
558 | list_del_init(&p_ptr->wait_list); | 460 | list_del_init(&p_ptr->wait_list); |
559 | spin_lock_bh(p_ptr->publ.lock); | 461 | spin_lock_bh(p_ptr->lock); |
560 | p_ptr->publ.congested = 0; | 462 | p_ptr->congested = 0; |
561 | p_ptr->wakeup(&p_ptr->publ); | 463 | p_ptr->wakeup(p_ptr); |
562 | win -= p_ptr->waiting_pkts; | 464 | win -= p_ptr->waiting_pkts; |
563 | spin_unlock_bh(p_ptr->publ.lock); | 465 | spin_unlock_bh(p_ptr->lock); |
564 | } | 466 | } |
565 | 467 | ||
566 | exit: | 468 | exit: |
@@ -634,39 +536,9 @@ void tipc_link_stop(struct link *l_ptr) | |||
634 | l_ptr->proto_msg_queue = NULL; | 536 | l_ptr->proto_msg_queue = NULL; |
635 | } | 537 | } |
636 | 538 | ||
637 | #if 0 | ||
638 | |||
639 | /* LINK EVENT CODE IS NOT SUPPORTED AT PRESENT */ | 539 | /* LINK EVENT CODE IS NOT SUPPORTED AT PRESENT */ |
640 | |||
641 | static void link_recv_event(struct link_event *ev) | ||
642 | { | ||
643 | ev->fcn(ev->addr, ev->name, ev->up); | ||
644 | kfree(ev); | ||
645 | } | ||
646 | |||
647 | static void link_send_event(void (*fcn)(u32 a, char *n, int up), | ||
648 | struct link *l_ptr, int up) | ||
649 | { | ||
650 | struct link_event *ev; | ||
651 | |||
652 | ev = kmalloc(sizeof(*ev), GFP_ATOMIC); | ||
653 | if (!ev) { | ||
654 | warn("Link event allocation failure\n"); | ||
655 | return; | ||
656 | } | ||
657 | ev->addr = l_ptr->addr; | ||
658 | ev->up = up; | ||
659 | ev->fcn = fcn; | ||
660 | memcpy(ev->name, l_ptr->name, TIPC_MAX_LINK_NAME); | ||
661 | tipc_k_signal((Handler)link_recv_event, (unsigned long)ev); | ||
662 | } | ||
663 | |||
664 | #else | ||
665 | |||
666 | #define link_send_event(fcn, l_ptr, up) do { } while (0) | 540 | #define link_send_event(fcn, l_ptr, up) do { } while (0) |
667 | 541 | ||
668 | #endif | ||
669 | |||
670 | void tipc_link_reset(struct link *l_ptr) | 542 | void tipc_link_reset(struct link *l_ptr) |
671 | { | 543 | { |
672 | struct sk_buff *buf; | 544 | struct sk_buff *buf; |
@@ -683,18 +555,14 @@ void tipc_link_reset(struct link *l_ptr) | |||
683 | link_init_max_pkt(l_ptr); | 555 | link_init_max_pkt(l_ptr); |
684 | 556 | ||
685 | l_ptr->state = RESET_UNKNOWN; | 557 | l_ptr->state = RESET_UNKNOWN; |
686 | dbg_link_state("Resetting Link\n"); | ||
687 | 558 | ||
688 | if ((prev_state == RESET_UNKNOWN) || (prev_state == RESET_RESET)) | 559 | if ((prev_state == RESET_UNKNOWN) || (prev_state == RESET_RESET)) |
689 | return; | 560 | return; |
690 | 561 | ||
691 | tipc_node_link_down(l_ptr->owner, l_ptr); | 562 | tipc_node_link_down(l_ptr->owner, l_ptr); |
692 | tipc_bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr); | 563 | tipc_bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr); |
693 | #if 0 | 564 | |
694 | tipc_printf(TIPC_CONS, "\nReset link <%s>\n", l_ptr->name); | 565 | if (was_active_link && tipc_node_active_links(l_ptr->owner) && |
695 | dbg_link_dump(); | ||
696 | #endif | ||
697 | if (was_active_link && tipc_node_has_active_links(l_ptr->owner) && | ||
698 | l_ptr->owner->permit_changeover) { | 566 | l_ptr->owner->permit_changeover) { |
699 | l_ptr->reset_checkpoint = checkpoint; | 567 | l_ptr->reset_checkpoint = checkpoint; |
700 | l_ptr->exp_msg_count = START_CHANGEOVER; | 568 | l_ptr->exp_msg_count = START_CHANGEOVER; |
@@ -760,25 +628,18 @@ static void link_state_event(struct link *l_ptr, unsigned event) | |||
760 | return; /* Not yet. */ | 628 | return; /* Not yet. */ |
761 | 629 | ||
762 | if (link_blocked(l_ptr)) { | 630 | if (link_blocked(l_ptr)) { |
763 | if (event == TIMEOUT_EVT) { | 631 | if (event == TIMEOUT_EVT) |
764 | link_set_timer(l_ptr, cont_intv); | 632 | link_set_timer(l_ptr, cont_intv); |
765 | } | ||
766 | return; /* Changeover going on */ | 633 | return; /* Changeover going on */ |
767 | } | 634 | } |
768 | dbg_link("STATE_EV: <%s> ", l_ptr->name); | ||
769 | 635 | ||
770 | switch (l_ptr->state) { | 636 | switch (l_ptr->state) { |
771 | case WORKING_WORKING: | 637 | case WORKING_WORKING: |
772 | dbg_link("WW/"); | ||
773 | switch (event) { | 638 | switch (event) { |
774 | case TRAFFIC_MSG_EVT: | 639 | case TRAFFIC_MSG_EVT: |
775 | dbg_link("TRF-"); | ||
776 | /* fall through */ | ||
777 | case ACTIVATE_MSG: | 640 | case ACTIVATE_MSG: |
778 | dbg_link("ACT\n"); | ||
779 | break; | 641 | break; |
780 | case TIMEOUT_EVT: | 642 | case TIMEOUT_EVT: |
781 | dbg_link("TIM "); | ||
782 | if (l_ptr->next_in_no != l_ptr->checkpoint) { | 643 | if (l_ptr->next_in_no != l_ptr->checkpoint) { |
783 | l_ptr->checkpoint = l_ptr->next_in_no; | 644 | l_ptr->checkpoint = l_ptr->next_in_no; |
784 | if (tipc_bclink_acks_missing(l_ptr->owner)) { | 645 | if (tipc_bclink_acks_missing(l_ptr->owner)) { |
@@ -793,7 +654,6 @@ static void link_state_event(struct link *l_ptr, unsigned event) | |||
793 | link_set_timer(l_ptr, cont_intv); | 654 | link_set_timer(l_ptr, cont_intv); |
794 | break; | 655 | break; |
795 | } | 656 | } |
796 | dbg_link(" -> WU\n"); | ||
797 | l_ptr->state = WORKING_UNKNOWN; | 657 | l_ptr->state = WORKING_UNKNOWN; |
798 | l_ptr->fsm_msg_cnt = 0; | 658 | l_ptr->fsm_msg_cnt = 0; |
799 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0); | 659 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0); |
@@ -801,7 +661,6 @@ static void link_state_event(struct link *l_ptr, unsigned event) | |||
801 | link_set_timer(l_ptr, cont_intv / 4); | 661 | link_set_timer(l_ptr, cont_intv / 4); |
802 | break; | 662 | break; |
803 | case RESET_MSG: | 663 | case RESET_MSG: |
804 | dbg_link("RES -> RR\n"); | ||
805 | info("Resetting link <%s>, requested by peer\n", | 664 | info("Resetting link <%s>, requested by peer\n", |
806 | l_ptr->name); | 665 | l_ptr->name); |
807 | tipc_link_reset(l_ptr); | 666 | tipc_link_reset(l_ptr); |
@@ -816,18 +675,14 @@ static void link_state_event(struct link *l_ptr, unsigned event) | |||
816 | } | 675 | } |
817 | break; | 676 | break; |
818 | case WORKING_UNKNOWN: | 677 | case WORKING_UNKNOWN: |
819 | dbg_link("WU/"); | ||
820 | switch (event) { | 678 | switch (event) { |
821 | case TRAFFIC_MSG_EVT: | 679 | case TRAFFIC_MSG_EVT: |
822 | dbg_link("TRF-"); | ||
823 | case ACTIVATE_MSG: | 680 | case ACTIVATE_MSG: |
824 | dbg_link("ACT -> WW\n"); | ||
825 | l_ptr->state = WORKING_WORKING; | 681 | l_ptr->state = WORKING_WORKING; |
826 | l_ptr->fsm_msg_cnt = 0; | 682 | l_ptr->fsm_msg_cnt = 0; |
827 | link_set_timer(l_ptr, cont_intv); | 683 | link_set_timer(l_ptr, cont_intv); |
828 | break; | 684 | break; |
829 | case RESET_MSG: | 685 | case RESET_MSG: |
830 | dbg_link("RES -> RR\n"); | ||
831 | info("Resetting link <%s>, requested by peer " | 686 | info("Resetting link <%s>, requested by peer " |
832 | "while probing\n", l_ptr->name); | 687 | "while probing\n", l_ptr->name); |
833 | tipc_link_reset(l_ptr); | 688 | tipc_link_reset(l_ptr); |
@@ -838,9 +693,7 @@ static void link_state_event(struct link *l_ptr, unsigned event) | |||
838 | link_set_timer(l_ptr, cont_intv); | 693 | link_set_timer(l_ptr, cont_intv); |
839 | break; | 694 | break; |
840 | case TIMEOUT_EVT: | 695 | case TIMEOUT_EVT: |
841 | dbg_link("TIM "); | ||
842 | if (l_ptr->next_in_no != l_ptr->checkpoint) { | 696 | if (l_ptr->next_in_no != l_ptr->checkpoint) { |
843 | dbg_link("-> WW\n"); | ||
844 | l_ptr->state = WORKING_WORKING; | 697 | l_ptr->state = WORKING_WORKING; |
845 | l_ptr->fsm_msg_cnt = 0; | 698 | l_ptr->fsm_msg_cnt = 0; |
846 | l_ptr->checkpoint = l_ptr->next_in_no; | 699 | l_ptr->checkpoint = l_ptr->next_in_no; |
@@ -851,16 +704,11 @@ static void link_state_event(struct link *l_ptr, unsigned event) | |||
851 | } | 704 | } |
852 | link_set_timer(l_ptr, cont_intv); | 705 | link_set_timer(l_ptr, cont_intv); |
853 | } else if (l_ptr->fsm_msg_cnt < l_ptr->abort_limit) { | 706 | } else if (l_ptr->fsm_msg_cnt < l_ptr->abort_limit) { |
854 | dbg_link("Probing %u/%u,timer = %u ms)\n", | ||
855 | l_ptr->fsm_msg_cnt, l_ptr->abort_limit, | ||
856 | cont_intv / 4); | ||
857 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, | 707 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, |
858 | 1, 0, 0, 0, 0); | 708 | 1, 0, 0, 0, 0); |
859 | l_ptr->fsm_msg_cnt++; | 709 | l_ptr->fsm_msg_cnt++; |
860 | link_set_timer(l_ptr, cont_intv / 4); | 710 | link_set_timer(l_ptr, cont_intv / 4); |
861 | } else { /* Link has failed */ | 711 | } else { /* Link has failed */ |
862 | dbg_link("-> RU (%u probes unanswered)\n", | ||
863 | l_ptr->fsm_msg_cnt); | ||
864 | warn("Resetting link <%s>, peer not responding\n", | 712 | warn("Resetting link <%s>, peer not responding\n", |
865 | l_ptr->name); | 713 | l_ptr->name); |
866 | tipc_link_reset(l_ptr); | 714 | tipc_link_reset(l_ptr); |
@@ -877,18 +725,13 @@ static void link_state_event(struct link *l_ptr, unsigned event) | |||
877 | } | 725 | } |
878 | break; | 726 | break; |
879 | case RESET_UNKNOWN: | 727 | case RESET_UNKNOWN: |
880 | dbg_link("RU/"); | ||
881 | switch (event) { | 728 | switch (event) { |
882 | case TRAFFIC_MSG_EVT: | 729 | case TRAFFIC_MSG_EVT: |
883 | dbg_link("TRF-\n"); | ||
884 | break; | 730 | break; |
885 | case ACTIVATE_MSG: | 731 | case ACTIVATE_MSG: |
886 | other = l_ptr->owner->active_links[0]; | 732 | other = l_ptr->owner->active_links[0]; |
887 | if (other && link_working_unknown(other)) { | 733 | if (other && link_working_unknown(other)) |
888 | dbg_link("ACT\n"); | ||
889 | break; | 734 | break; |
890 | } | ||
891 | dbg_link("ACT -> WW\n"); | ||
892 | l_ptr->state = WORKING_WORKING; | 735 | l_ptr->state = WORKING_WORKING; |
893 | l_ptr->fsm_msg_cnt = 0; | 736 | l_ptr->fsm_msg_cnt = 0; |
894 | link_activate(l_ptr); | 737 | link_activate(l_ptr); |
@@ -897,8 +740,6 @@ static void link_state_event(struct link *l_ptr, unsigned event) | |||
897 | link_set_timer(l_ptr, cont_intv); | 740 | link_set_timer(l_ptr, cont_intv); |
898 | break; | 741 | break; |
899 | case RESET_MSG: | 742 | case RESET_MSG: |
900 | dbg_link("RES\n"); | ||
901 | dbg_link(" -> RR\n"); | ||
902 | l_ptr->state = RESET_RESET; | 743 | l_ptr->state = RESET_RESET; |
903 | l_ptr->fsm_msg_cnt = 0; | 744 | l_ptr->fsm_msg_cnt = 0; |
904 | tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 1, 0, 0, 0, 0); | 745 | tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 1, 0, 0, 0, 0); |
@@ -906,11 +747,9 @@ static void link_state_event(struct link *l_ptr, unsigned event) | |||
906 | link_set_timer(l_ptr, cont_intv); | 747 | link_set_timer(l_ptr, cont_intv); |
907 | break; | 748 | break; |
908 | case STARTING_EVT: | 749 | case STARTING_EVT: |
909 | dbg_link("START-"); | ||
910 | l_ptr->started = 1; | 750 | l_ptr->started = 1; |
911 | /* fall through */ | 751 | /* fall through */ |
912 | case TIMEOUT_EVT: | 752 | case TIMEOUT_EVT: |
913 | dbg_link("TIM\n"); | ||
914 | tipc_link_send_proto_msg(l_ptr, RESET_MSG, 0, 0, 0, 0, 0); | 753 | tipc_link_send_proto_msg(l_ptr, RESET_MSG, 0, 0, 0, 0, 0); |
915 | l_ptr->fsm_msg_cnt++; | 754 | l_ptr->fsm_msg_cnt++; |
916 | link_set_timer(l_ptr, cont_intv); | 755 | link_set_timer(l_ptr, cont_intv); |
@@ -920,18 +759,12 @@ static void link_state_event(struct link *l_ptr, unsigned event) | |||
920 | } | 759 | } |
921 | break; | 760 | break; |
922 | case RESET_RESET: | 761 | case RESET_RESET: |
923 | dbg_link("RR/ "); | ||
924 | switch (event) { | 762 | switch (event) { |
925 | case TRAFFIC_MSG_EVT: | 763 | case TRAFFIC_MSG_EVT: |
926 | dbg_link("TRF-"); | ||
927 | /* fall through */ | ||
928 | case ACTIVATE_MSG: | 764 | case ACTIVATE_MSG: |
929 | other = l_ptr->owner->active_links[0]; | 765 | other = l_ptr->owner->active_links[0]; |
930 | if (other && link_working_unknown(other)) { | 766 | if (other && link_working_unknown(other)) |
931 | dbg_link("ACT\n"); | ||
932 | break; | 767 | break; |
933 | } | ||
934 | dbg_link("ACT -> WW\n"); | ||
935 | l_ptr->state = WORKING_WORKING; | 768 | l_ptr->state = WORKING_WORKING; |
936 | l_ptr->fsm_msg_cnt = 0; | 769 | l_ptr->fsm_msg_cnt = 0; |
937 | link_activate(l_ptr); | 770 | link_activate(l_ptr); |
@@ -940,14 +773,11 @@ static void link_state_event(struct link *l_ptr, unsigned event) | |||
940 | link_set_timer(l_ptr, cont_intv); | 773 | link_set_timer(l_ptr, cont_intv); |
941 | break; | 774 | break; |
942 | case RESET_MSG: | 775 | case RESET_MSG: |
943 | dbg_link("RES\n"); | ||
944 | break; | 776 | break; |
945 | case TIMEOUT_EVT: | 777 | case TIMEOUT_EVT: |
946 | dbg_link("TIM\n"); | ||
947 | tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 0, 0, 0, 0, 0); | 778 | tipc_link_send_proto_msg(l_ptr, ACTIVATE_MSG, 0, 0, 0, 0, 0); |
948 | l_ptr->fsm_msg_cnt++; | 779 | l_ptr->fsm_msg_cnt++; |
949 | link_set_timer(l_ptr, cont_intv); | 780 | link_set_timer(l_ptr, cont_intv); |
950 | dbg_link("fsm_msg_cnt %u\n", l_ptr->fsm_msg_cnt); | ||
951 | break; | 781 | break; |
952 | default: | 782 | default: |
953 | err("Unknown link event %u in RR state\n", event); | 783 | err("Unknown link event %u in RR state\n", event); |
@@ -987,9 +817,6 @@ static int link_bundle_buf(struct link *l_ptr, | |||
987 | skb_copy_to_linear_data_offset(bundler, to_pos, buf->data, size); | 817 | skb_copy_to_linear_data_offset(bundler, to_pos, buf->data, size); |
988 | msg_set_size(bundler_msg, to_pos + size); | 818 | msg_set_size(bundler_msg, to_pos + size); |
989 | msg_set_msgcnt(bundler_msg, msg_msgcnt(bundler_msg) + 1); | 819 | msg_set_msgcnt(bundler_msg, msg_msgcnt(bundler_msg) + 1); |
990 | dbg("Packed msg # %u(%u octets) into pos %u in buf(#%u)\n", | ||
991 | msg_msgcnt(bundler_msg), size, to_pos, msg_seqno(bundler_msg)); | ||
992 | msg_dbg(msg, "PACKD:"); | ||
993 | buf_discard(buf); | 820 | buf_discard(buf); |
994 | l_ptr->stats.sent_bundled++; | 821 | l_ptr->stats.sent_bundled++; |
995 | return 1; | 822 | return 1; |
@@ -1010,7 +837,29 @@ static void link_add_to_outqueue(struct link *l_ptr, | |||
1010 | l_ptr->last_out = buf; | 837 | l_ptr->last_out = buf; |
1011 | } else | 838 | } else |
1012 | l_ptr->first_out = l_ptr->last_out = buf; | 839 | l_ptr->first_out = l_ptr->last_out = buf; |
840 | |||
1013 | l_ptr->out_queue_size++; | 841 | l_ptr->out_queue_size++; |
842 | if (l_ptr->out_queue_size > l_ptr->stats.max_queue_sz) | ||
843 | l_ptr->stats.max_queue_sz = l_ptr->out_queue_size; | ||
844 | } | ||
845 | |||
846 | static void link_add_chain_to_outqueue(struct link *l_ptr, | ||
847 | struct sk_buff *buf_chain, | ||
848 | u32 long_msgno) | ||
849 | { | ||
850 | struct sk_buff *buf; | ||
851 | struct tipc_msg *msg; | ||
852 | |||
853 | if (!l_ptr->next_out) | ||
854 | l_ptr->next_out = buf_chain; | ||
855 | while (buf_chain) { | ||
856 | buf = buf_chain; | ||
857 | buf_chain = buf_chain->next; | ||
858 | |||
859 | msg = buf_msg(buf); | ||
860 | msg_set_long_msgno(msg, long_msgno); | ||
861 | link_add_to_outqueue(l_ptr, buf, msg); | ||
862 | } | ||
1014 | } | 863 | } |
1015 | 864 | ||
1016 | /* | 865 | /* |
@@ -1035,10 +884,10 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf) | |||
1035 | 884 | ||
1036 | if (unlikely(queue_size >= queue_limit)) { | 885 | if (unlikely(queue_size >= queue_limit)) { |
1037 | if (imp <= TIPC_CRITICAL_IMPORTANCE) { | 886 | if (imp <= TIPC_CRITICAL_IMPORTANCE) { |
1038 | return link_schedule_port(l_ptr, msg_origport(msg), | 887 | link_schedule_port(l_ptr, msg_origport(msg), size); |
1039 | size); | 888 | buf_discard(buf); |
889 | return -ELINKCONG; | ||
1040 | } | 890 | } |
1041 | msg_dbg(msg, "TIPC: Congestion, throwing away\n"); | ||
1042 | buf_discard(buf); | 891 | buf_discard(buf); |
1043 | if (imp > CONN_MANAGER) { | 892 | if (imp > CONN_MANAGER) { |
1044 | warn("Resetting link <%s>, send queue full", l_ptr->name); | 893 | warn("Resetting link <%s>, send queue full", l_ptr->name); |
@@ -1050,13 +899,10 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf) | |||
1050 | /* Fragmentation needed ? */ | 899 | /* Fragmentation needed ? */ |
1051 | 900 | ||
1052 | if (size > max_packet) | 901 | if (size > max_packet) |
1053 | return tipc_link_send_long_buf(l_ptr, buf); | 902 | return link_send_long_buf(l_ptr, buf); |
1054 | 903 | ||
1055 | /* Packet can be queued or sent: */ | 904 | /* Packet can be queued or sent: */ |
1056 | 905 | ||
1057 | if (queue_size > l_ptr->stats.max_queue_sz) | ||
1058 | l_ptr->stats.max_queue_sz = queue_size; | ||
1059 | |||
1060 | if (likely(!tipc_bearer_congested(l_ptr->b_ptr, l_ptr) && | 906 | if (likely(!tipc_bearer_congested(l_ptr->b_ptr, l_ptr) && |
1061 | !link_congested(l_ptr))) { | 907 | !link_congested(l_ptr))) { |
1062 | link_add_to_outqueue(l_ptr, buf, msg); | 908 | link_add_to_outqueue(l_ptr, buf, msg); |
@@ -1086,7 +932,7 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf) | |||
1086 | /* Try creating a new bundle */ | 932 | /* Try creating a new bundle */ |
1087 | 933 | ||
1088 | if (size <= max_packet * 2 / 3) { | 934 | if (size <= max_packet * 2 / 3) { |
1089 | struct sk_buff *bundler = buf_acquire(max_packet); | 935 | struct sk_buff *bundler = tipc_buf_acquire(max_packet); |
1090 | struct tipc_msg bundler_hdr; | 936 | struct tipc_msg bundler_hdr; |
1091 | 937 | ||
1092 | if (bundler) { | 938 | if (bundler) { |
@@ -1122,22 +968,16 @@ int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector) | |||
1122 | int res = -ELINKCONG; | 968 | int res = -ELINKCONG; |
1123 | 969 | ||
1124 | read_lock_bh(&tipc_net_lock); | 970 | read_lock_bh(&tipc_net_lock); |
1125 | n_ptr = tipc_node_select(dest, selector); | 971 | n_ptr = tipc_node_find(dest); |
1126 | if (n_ptr) { | 972 | if (n_ptr) { |
1127 | tipc_node_lock(n_ptr); | 973 | tipc_node_lock(n_ptr); |
1128 | l_ptr = n_ptr->active_links[selector & 1]; | 974 | l_ptr = n_ptr->active_links[selector & 1]; |
1129 | if (l_ptr) { | 975 | if (l_ptr) |
1130 | dbg("tipc_link_send: found link %x for dest %x\n", l_ptr, dest); | ||
1131 | res = tipc_link_send_buf(l_ptr, buf); | 976 | res = tipc_link_send_buf(l_ptr, buf); |
1132 | } else { | 977 | else |
1133 | dbg("Attempt to send msg to unreachable node:\n"); | ||
1134 | msg_dbg(buf_msg(buf),">>>"); | ||
1135 | buf_discard(buf); | 978 | buf_discard(buf); |
1136 | } | ||
1137 | tipc_node_unlock(n_ptr); | 979 | tipc_node_unlock(n_ptr); |
1138 | } else { | 980 | } else { |
1139 | dbg("Attempt to send msg to unknown node:\n"); | ||
1140 | msg_dbg(buf_msg(buf),">>>"); | ||
1141 | buf_discard(buf); | 981 | buf_discard(buf); |
1142 | } | 982 | } |
1143 | read_unlock_bh(&tipc_net_lock); | 983 | read_unlock_bh(&tipc_net_lock); |
@@ -1164,17 +1004,14 @@ static int link_send_buf_fast(struct link *l_ptr, struct sk_buff *buf, | |||
1164 | if (likely(tipc_bearer_send(l_ptr->b_ptr, buf, | 1004 | if (likely(tipc_bearer_send(l_ptr->b_ptr, buf, |
1165 | &l_ptr->media_addr))) { | 1005 | &l_ptr->media_addr))) { |
1166 | l_ptr->unacked_window = 0; | 1006 | l_ptr->unacked_window = 0; |
1167 | msg_dbg(msg,"SENT_FAST:"); | ||
1168 | return res; | 1007 | return res; |
1169 | } | 1008 | } |
1170 | dbg("failed sent fast...\n"); | ||
1171 | tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); | 1009 | tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); |
1172 | l_ptr->stats.bearer_congs++; | 1010 | l_ptr->stats.bearer_congs++; |
1173 | l_ptr->next_out = buf; | 1011 | l_ptr->next_out = buf; |
1174 | return res; | 1012 | return res; |
1175 | } | 1013 | } |
1176 | } | 1014 | } else |
1177 | else | ||
1178 | *used_max_pkt = l_ptr->max_pkt; | 1015 | *used_max_pkt = l_ptr->max_pkt; |
1179 | } | 1016 | } |
1180 | return tipc_link_send_buf(l_ptr, buf); /* All other cases */ | 1017 | return tipc_link_send_buf(l_ptr, buf); /* All other cases */ |
@@ -1198,12 +1035,10 @@ int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode) | |||
1198 | return tipc_port_recv_msg(buf); | 1035 | return tipc_port_recv_msg(buf); |
1199 | 1036 | ||
1200 | read_lock_bh(&tipc_net_lock); | 1037 | read_lock_bh(&tipc_net_lock); |
1201 | n_ptr = tipc_node_select(destnode, selector); | 1038 | n_ptr = tipc_node_find(destnode); |
1202 | if (likely(n_ptr)) { | 1039 | if (likely(n_ptr)) { |
1203 | tipc_node_lock(n_ptr); | 1040 | tipc_node_lock(n_ptr); |
1204 | l_ptr = n_ptr->active_links[selector]; | 1041 | l_ptr = n_ptr->active_links[selector]; |
1205 | dbg("send_fast: buf %x selected %x, destnode = %x\n", | ||
1206 | buf, l_ptr, destnode); | ||
1207 | if (likely(l_ptr)) { | 1042 | if (likely(l_ptr)) { |
1208 | res = link_send_buf_fast(l_ptr, buf, &dummy); | 1043 | res = link_send_buf_fast(l_ptr, buf, &dummy); |
1209 | tipc_node_unlock(n_ptr); | 1044 | tipc_node_unlock(n_ptr); |
@@ -1225,12 +1060,13 @@ int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode) | |||
1225 | * except for total message length. | 1060 | * except for total message length. |
1226 | * Returns user data length or errno. | 1061 | * Returns user data length or errno. |
1227 | */ | 1062 | */ |
1228 | int tipc_link_send_sections_fast(struct port *sender, | 1063 | int tipc_link_send_sections_fast(struct tipc_port *sender, |
1229 | struct iovec const *msg_sect, | 1064 | struct iovec const *msg_sect, |
1230 | const u32 num_sect, | 1065 | const u32 num_sect, |
1066 | unsigned int total_len, | ||
1231 | u32 destaddr) | 1067 | u32 destaddr) |
1232 | { | 1068 | { |
1233 | struct tipc_msg *hdr = &sender->publ.phdr; | 1069 | struct tipc_msg *hdr = &sender->phdr; |
1234 | struct link *l_ptr; | 1070 | struct link *l_ptr; |
1235 | struct sk_buff *buf; | 1071 | struct sk_buff *buf; |
1236 | struct tipc_node *node; | 1072 | struct tipc_node *node; |
@@ -1243,20 +1079,18 @@ again: | |||
1243 | * (Must not hold any locks while building message.) | 1079 | * (Must not hold any locks while building message.) |
1244 | */ | 1080 | */ |
1245 | 1081 | ||
1246 | res = tipc_msg_build(hdr, msg_sect, num_sect, sender->publ.max_pkt, | 1082 | res = tipc_msg_build(hdr, msg_sect, num_sect, total_len, |
1247 | !sender->user_port, &buf); | 1083 | sender->max_pkt, !sender->user_port, &buf); |
1248 | 1084 | ||
1249 | read_lock_bh(&tipc_net_lock); | 1085 | read_lock_bh(&tipc_net_lock); |
1250 | node = tipc_node_select(destaddr, selector); | 1086 | node = tipc_node_find(destaddr); |
1251 | if (likely(node)) { | 1087 | if (likely(node)) { |
1252 | tipc_node_lock(node); | 1088 | tipc_node_lock(node); |
1253 | l_ptr = node->active_links[selector]; | 1089 | l_ptr = node->active_links[selector]; |
1254 | if (likely(l_ptr)) { | 1090 | if (likely(l_ptr)) { |
1255 | if (likely(buf)) { | 1091 | if (likely(buf)) { |
1256 | res = link_send_buf_fast(l_ptr, buf, | 1092 | res = link_send_buf_fast(l_ptr, buf, |
1257 | &sender->publ.max_pkt); | 1093 | &sender->max_pkt); |
1258 | if (unlikely(res < 0)) | ||
1259 | buf_discard(buf); | ||
1260 | exit: | 1094 | exit: |
1261 | tipc_node_unlock(node); | 1095 | tipc_node_unlock(node); |
1262 | read_unlock_bh(&tipc_net_lock); | 1096 | read_unlock_bh(&tipc_net_lock); |
@@ -1273,7 +1107,7 @@ exit: | |||
1273 | if (link_congested(l_ptr) || | 1107 | if (link_congested(l_ptr) || |
1274 | !list_empty(&l_ptr->b_ptr->cong_links)) { | 1108 | !list_empty(&l_ptr->b_ptr->cong_links)) { |
1275 | res = link_schedule_port(l_ptr, | 1109 | res = link_schedule_port(l_ptr, |
1276 | sender->publ.ref, res); | 1110 | sender->ref, res); |
1277 | goto exit; | 1111 | goto exit; |
1278 | } | 1112 | } |
1279 | 1113 | ||
@@ -1282,16 +1116,17 @@ exit: | |||
1282 | * then re-try fast path or fragment the message | 1116 | * then re-try fast path or fragment the message |
1283 | */ | 1117 | */ |
1284 | 1118 | ||
1285 | sender->publ.max_pkt = l_ptr->max_pkt; | 1119 | sender->max_pkt = l_ptr->max_pkt; |
1286 | tipc_node_unlock(node); | 1120 | tipc_node_unlock(node); |
1287 | read_unlock_bh(&tipc_net_lock); | 1121 | read_unlock_bh(&tipc_net_lock); |
1288 | 1122 | ||
1289 | 1123 | ||
1290 | if ((msg_hdr_sz(hdr) + res) <= sender->publ.max_pkt) | 1124 | if ((msg_hdr_sz(hdr) + res) <= sender->max_pkt) |
1291 | goto again; | 1125 | goto again; |
1292 | 1126 | ||
1293 | return link_send_sections_long(sender, msg_sect, | 1127 | return link_send_sections_long(sender, msg_sect, |
1294 | num_sect, destaddr); | 1128 | num_sect, total_len, |
1129 | destaddr); | ||
1295 | } | 1130 | } |
1296 | tipc_node_unlock(node); | 1131 | tipc_node_unlock(node); |
1297 | } | 1132 | } |
@@ -1303,7 +1138,7 @@ exit: | |||
1303 | return tipc_reject_msg(buf, TIPC_ERR_NO_NODE); | 1138 | return tipc_reject_msg(buf, TIPC_ERR_NO_NODE); |
1304 | if (res >= 0) | 1139 | if (res >= 0) |
1305 | return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect, | 1140 | return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect, |
1306 | TIPC_ERR_NO_NODE); | 1141 | total_len, TIPC_ERR_NO_NODE); |
1307 | return res; | 1142 | return res; |
1308 | } | 1143 | } |
1309 | 1144 | ||
@@ -1321,26 +1156,27 @@ exit: | |||
1321 | * | 1156 | * |
1322 | * Returns user data length or errno. | 1157 | * Returns user data length or errno. |
1323 | */ | 1158 | */ |
1324 | static int link_send_sections_long(struct port *sender, | 1159 | static int link_send_sections_long(struct tipc_port *sender, |
1325 | struct iovec const *msg_sect, | 1160 | struct iovec const *msg_sect, |
1326 | u32 num_sect, | 1161 | u32 num_sect, |
1162 | unsigned int total_len, | ||
1327 | u32 destaddr) | 1163 | u32 destaddr) |
1328 | { | 1164 | { |
1329 | struct link *l_ptr; | 1165 | struct link *l_ptr; |
1330 | struct tipc_node *node; | 1166 | struct tipc_node *node; |
1331 | struct tipc_msg *hdr = &sender->publ.phdr; | 1167 | struct tipc_msg *hdr = &sender->phdr; |
1332 | u32 dsz = msg_data_sz(hdr); | 1168 | u32 dsz = total_len; |
1333 | u32 max_pkt,fragm_sz,rest; | 1169 | u32 max_pkt, fragm_sz, rest; |
1334 | struct tipc_msg fragm_hdr; | 1170 | struct tipc_msg fragm_hdr; |
1335 | struct sk_buff *buf,*buf_chain,*prev; | 1171 | struct sk_buff *buf, *buf_chain, *prev; |
1336 | u32 fragm_crs,fragm_rest,hsz,sect_rest; | 1172 | u32 fragm_crs, fragm_rest, hsz, sect_rest; |
1337 | const unchar *sect_crs; | 1173 | const unchar *sect_crs; |
1338 | int curr_sect; | 1174 | int curr_sect; |
1339 | u32 fragm_no; | 1175 | u32 fragm_no; |
1340 | 1176 | ||
1341 | again: | 1177 | again: |
1342 | fragm_no = 1; | 1178 | fragm_no = 1; |
1343 | max_pkt = sender->publ.max_pkt - INT_H_SIZE; | 1179 | max_pkt = sender->max_pkt - INT_H_SIZE; |
1344 | /* leave room for tunnel header in case of link changeover */ | 1180 | /* leave room for tunnel header in case of link changeover */ |
1345 | fragm_sz = max_pkt - INT_H_SIZE; | 1181 | fragm_sz = max_pkt - INT_H_SIZE; |
1346 | /* leave room for fragmentation header in each fragment */ | 1182 | /* leave room for fragmentation header in each fragment */ |
@@ -1353,23 +1189,20 @@ again: | |||
1353 | 1189 | ||
1354 | /* Prepare reusable fragment header: */ | 1190 | /* Prepare reusable fragment header: */ |
1355 | 1191 | ||
1356 | msg_dbg(hdr, ">FRAGMENTING>"); | ||
1357 | tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, | 1192 | tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, |
1358 | INT_H_SIZE, msg_destnode(hdr)); | 1193 | INT_H_SIZE, msg_destnode(hdr)); |
1359 | msg_set_link_selector(&fragm_hdr, sender->publ.ref); | ||
1360 | msg_set_size(&fragm_hdr, max_pkt); | 1194 | msg_set_size(&fragm_hdr, max_pkt); |
1361 | msg_set_fragm_no(&fragm_hdr, 1); | 1195 | msg_set_fragm_no(&fragm_hdr, 1); |
1362 | 1196 | ||
1363 | /* Prepare header of first fragment: */ | 1197 | /* Prepare header of first fragment: */ |
1364 | 1198 | ||
1365 | buf_chain = buf = buf_acquire(max_pkt); | 1199 | buf_chain = buf = tipc_buf_acquire(max_pkt); |
1366 | if (!buf) | 1200 | if (!buf) |
1367 | return -ENOMEM; | 1201 | return -ENOMEM; |
1368 | buf->next = NULL; | 1202 | buf->next = NULL; |
1369 | skb_copy_to_linear_data(buf, &fragm_hdr, INT_H_SIZE); | 1203 | skb_copy_to_linear_data(buf, &fragm_hdr, INT_H_SIZE); |
1370 | hsz = msg_hdr_sz(hdr); | 1204 | hsz = msg_hdr_sz(hdr); |
1371 | skb_copy_to_linear_data_offset(buf, INT_H_SIZE, hdr, hsz); | 1205 | skb_copy_to_linear_data_offset(buf, INT_H_SIZE, hdr, hsz); |
1372 | msg_dbg(buf_msg(buf), ">BUILD>"); | ||
1373 | 1206 | ||
1374 | /* Chop up message: */ | 1207 | /* Chop up message: */ |
1375 | 1208 | ||
@@ -1412,14 +1245,14 @@ error: | |||
1412 | /* Initiate new fragment: */ | 1245 | /* Initiate new fragment: */ |
1413 | if (rest <= fragm_sz) { | 1246 | if (rest <= fragm_sz) { |
1414 | fragm_sz = rest; | 1247 | fragm_sz = rest; |
1415 | msg_set_type(&fragm_hdr,LAST_FRAGMENT); | 1248 | msg_set_type(&fragm_hdr, LAST_FRAGMENT); |
1416 | } else { | 1249 | } else { |
1417 | msg_set_type(&fragm_hdr, FRAGMENT); | 1250 | msg_set_type(&fragm_hdr, FRAGMENT); |
1418 | } | 1251 | } |
1419 | msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE); | 1252 | msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE); |
1420 | msg_set_fragm_no(&fragm_hdr, ++fragm_no); | 1253 | msg_set_fragm_no(&fragm_hdr, ++fragm_no); |
1421 | prev = buf; | 1254 | prev = buf; |
1422 | buf = buf_acquire(fragm_sz + INT_H_SIZE); | 1255 | buf = tipc_buf_acquire(fragm_sz + INT_H_SIZE); |
1423 | if (!buf) | 1256 | if (!buf) |
1424 | goto error; | 1257 | goto error; |
1425 | 1258 | ||
@@ -1428,25 +1261,23 @@ error: | |||
1428 | skb_copy_to_linear_data(buf, &fragm_hdr, INT_H_SIZE); | 1261 | skb_copy_to_linear_data(buf, &fragm_hdr, INT_H_SIZE); |
1429 | fragm_crs = INT_H_SIZE; | 1262 | fragm_crs = INT_H_SIZE; |
1430 | fragm_rest = fragm_sz; | 1263 | fragm_rest = fragm_sz; |
1431 | msg_dbg(buf_msg(buf)," >BUILD>"); | ||
1432 | } | 1264 | } |
1433 | } | 1265 | } while (rest > 0); |
1434 | while (rest > 0); | ||
1435 | 1266 | ||
1436 | /* | 1267 | /* |
1437 | * Now we have a buffer chain. Select a link and check | 1268 | * Now we have a buffer chain. Select a link and check |
1438 | * that packet size is still OK | 1269 | * that packet size is still OK |
1439 | */ | 1270 | */ |
1440 | node = tipc_node_select(destaddr, sender->publ.ref & 1); | 1271 | node = tipc_node_find(destaddr); |
1441 | if (likely(node)) { | 1272 | if (likely(node)) { |
1442 | tipc_node_lock(node); | 1273 | tipc_node_lock(node); |
1443 | l_ptr = node->active_links[sender->publ.ref & 1]; | 1274 | l_ptr = node->active_links[sender->ref & 1]; |
1444 | if (!l_ptr) { | 1275 | if (!l_ptr) { |
1445 | tipc_node_unlock(node); | 1276 | tipc_node_unlock(node); |
1446 | goto reject; | 1277 | goto reject; |
1447 | } | 1278 | } |
1448 | if (l_ptr->max_pkt < max_pkt) { | 1279 | if (l_ptr->max_pkt < max_pkt) { |
1449 | sender->publ.max_pkt = l_ptr->max_pkt; | 1280 | sender->max_pkt = l_ptr->max_pkt; |
1450 | tipc_node_unlock(node); | 1281 | tipc_node_unlock(node); |
1451 | for (; buf_chain; buf_chain = buf) { | 1282 | for (; buf_chain; buf_chain = buf) { |
1452 | buf = buf_chain->next; | 1283 | buf = buf_chain->next; |
@@ -1461,29 +1292,15 @@ reject: | |||
1461 | buf_discard(buf_chain); | 1292 | buf_discard(buf_chain); |
1462 | } | 1293 | } |
1463 | return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect, | 1294 | return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect, |
1464 | TIPC_ERR_NO_NODE); | 1295 | total_len, TIPC_ERR_NO_NODE); |
1465 | } | 1296 | } |
1466 | 1297 | ||
1467 | /* Append whole chain to send queue: */ | 1298 | /* Append chain of fragments to send queue & send them */ |
1468 | 1299 | ||
1469 | buf = buf_chain; | 1300 | l_ptr->long_msg_seq_no++; |
1470 | l_ptr->long_msg_seq_no = mod(l_ptr->long_msg_seq_no + 1); | 1301 | link_add_chain_to_outqueue(l_ptr, buf_chain, l_ptr->long_msg_seq_no); |
1471 | if (!l_ptr->next_out) | 1302 | l_ptr->stats.sent_fragments += fragm_no; |
1472 | l_ptr->next_out = buf_chain; | ||
1473 | l_ptr->stats.sent_fragmented++; | 1303 | l_ptr->stats.sent_fragmented++; |
1474 | while (buf) { | ||
1475 | struct sk_buff *next = buf->next; | ||
1476 | struct tipc_msg *msg = buf_msg(buf); | ||
1477 | |||
1478 | l_ptr->stats.sent_fragments++; | ||
1479 | msg_set_long_msgno(msg, l_ptr->long_msg_seq_no); | ||
1480 | link_add_to_outqueue(l_ptr, buf, msg); | ||
1481 | msg_dbg(msg, ">ADD>"); | ||
1482 | buf = next; | ||
1483 | } | ||
1484 | |||
1485 | /* Send it, if possible: */ | ||
1486 | |||
1487 | tipc_link_push_queue(l_ptr); | 1304 | tipc_link_push_queue(l_ptr); |
1488 | tipc_node_unlock(node); | 1305 | tipc_node_unlock(node); |
1489 | return dsz; | 1306 | return dsz; |
@@ -1520,14 +1337,12 @@ u32 tipc_link_push_packet(struct link *l_ptr) | |||
1520 | msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); | 1337 | msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); |
1521 | msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in); | 1338 | msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in); |
1522 | if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { | 1339 | if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { |
1523 | msg_dbg(buf_msg(buf), ">DEF-RETR>"); | ||
1524 | l_ptr->retransm_queue_head = mod(++r_q_head); | 1340 | l_ptr->retransm_queue_head = mod(++r_q_head); |
1525 | l_ptr->retransm_queue_size = --r_q_size; | 1341 | l_ptr->retransm_queue_size = --r_q_size; |
1526 | l_ptr->stats.retransmitted++; | 1342 | l_ptr->stats.retransmitted++; |
1527 | return 0; | 1343 | return 0; |
1528 | } else { | 1344 | } else { |
1529 | l_ptr->stats.bearer_congs++; | 1345 | l_ptr->stats.bearer_congs++; |
1530 | msg_dbg(buf_msg(buf), "|>DEF-RETR>"); | ||
1531 | return PUSH_FAILED; | 1346 | return PUSH_FAILED; |
1532 | } | 1347 | } |
1533 | } | 1348 | } |
@@ -1537,15 +1352,13 @@ u32 tipc_link_push_packet(struct link *l_ptr) | |||
1537 | buf = l_ptr->proto_msg_queue; | 1352 | buf = l_ptr->proto_msg_queue; |
1538 | if (buf) { | 1353 | if (buf) { |
1539 | msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); | 1354 | msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); |
1540 | msg_set_bcast_ack(buf_msg(buf),l_ptr->owner->bclink.last_in); | 1355 | msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in); |
1541 | if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { | 1356 | if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { |
1542 | msg_dbg(buf_msg(buf), ">DEF-PROT>"); | ||
1543 | l_ptr->unacked_window = 0; | 1357 | l_ptr->unacked_window = 0; |
1544 | buf_discard(buf); | 1358 | buf_discard(buf); |
1545 | l_ptr->proto_msg_queue = NULL; | 1359 | l_ptr->proto_msg_queue = NULL; |
1546 | return 0; | 1360 | return 0; |
1547 | } else { | 1361 | } else { |
1548 | msg_dbg(buf_msg(buf), "|>DEF-PROT>"); | ||
1549 | l_ptr->stats.bearer_congs++; | 1362 | l_ptr->stats.bearer_congs++; |
1550 | return PUSH_FAILED; | 1363 | return PUSH_FAILED; |
1551 | } | 1364 | } |
@@ -1565,11 +1378,9 @@ u32 tipc_link_push_packet(struct link *l_ptr) | |||
1565 | if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { | 1378 | if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { |
1566 | if (msg_user(msg) == MSG_BUNDLER) | 1379 | if (msg_user(msg) == MSG_BUNDLER) |
1567 | msg_set_type(msg, CLOSED_MSG); | 1380 | msg_set_type(msg, CLOSED_MSG); |
1568 | msg_dbg(msg, ">PUSH-DATA>"); | ||
1569 | l_ptr->next_out = buf->next; | 1381 | l_ptr->next_out = buf->next; |
1570 | return 0; | 1382 | return 0; |
1571 | } else { | 1383 | } else { |
1572 | msg_dbg(msg, "|PUSH-DATA|"); | ||
1573 | l_ptr->stats.bearer_congs++; | 1384 | l_ptr->stats.bearer_congs++; |
1574 | return PUSH_FAILED; | 1385 | return PUSH_FAILED; |
1575 | } | 1386 | } |
@@ -1617,8 +1428,7 @@ static void link_reset_all(unsigned long addr) | |||
1617 | 1428 | ||
1618 | for (i = 0; i < MAX_BEARERS; i++) { | 1429 | for (i = 0; i < MAX_BEARERS; i++) { |
1619 | if (n_ptr->links[i]) { | 1430 | if (n_ptr->links[i]) { |
1620 | link_print(n_ptr->links[i], TIPC_OUTPUT, | 1431 | link_print(n_ptr->links[i], "Resetting link\n"); |
1621 | "Resetting link\n"); | ||
1622 | tipc_link_reset(n_ptr->links[i]); | 1432 | tipc_link_reset(n_ptr->links[i]); |
1623 | } | 1433 | } |
1624 | } | 1434 | } |
@@ -1632,13 +1442,12 @@ static void link_retransmit_failure(struct link *l_ptr, struct sk_buff *buf) | |||
1632 | struct tipc_msg *msg = buf_msg(buf); | 1442 | struct tipc_msg *msg = buf_msg(buf); |
1633 | 1443 | ||
1634 | warn("Retransmission failure on link <%s>\n", l_ptr->name); | 1444 | warn("Retransmission failure on link <%s>\n", l_ptr->name); |
1635 | tipc_msg_dbg(TIPC_OUTPUT, msg, ">RETR-FAIL>"); | ||
1636 | 1445 | ||
1637 | if (l_ptr->addr) { | 1446 | if (l_ptr->addr) { |
1638 | 1447 | ||
1639 | /* Handle failure on standard link */ | 1448 | /* Handle failure on standard link */ |
1640 | 1449 | ||
1641 | link_print(l_ptr, TIPC_OUTPUT, "Resetting link\n"); | 1450 | link_print(l_ptr, "Resetting link\n"); |
1642 | tipc_link_reset(l_ptr); | 1451 | tipc_link_reset(l_ptr); |
1643 | 1452 | ||
1644 | } else { | 1453 | } else { |
@@ -1648,21 +1457,21 @@ static void link_retransmit_failure(struct link *l_ptr, struct sk_buff *buf) | |||
1648 | struct tipc_node *n_ptr; | 1457 | struct tipc_node *n_ptr; |
1649 | char addr_string[16]; | 1458 | char addr_string[16]; |
1650 | 1459 | ||
1651 | tipc_printf(TIPC_OUTPUT, "Msg seq number: %u, ", msg_seqno(msg)); | 1460 | info("Msg seq number: %u, ", msg_seqno(msg)); |
1652 | tipc_printf(TIPC_OUTPUT, "Outstanding acks: %lu\n", | 1461 | info("Outstanding acks: %lu\n", |
1653 | (unsigned long) TIPC_SKB_CB(buf)->handle); | 1462 | (unsigned long) TIPC_SKB_CB(buf)->handle); |
1654 | 1463 | ||
1655 | n_ptr = l_ptr->owner->next; | 1464 | n_ptr = tipc_bclink_retransmit_to(); |
1656 | tipc_node_lock(n_ptr); | 1465 | tipc_node_lock(n_ptr); |
1657 | 1466 | ||
1658 | tipc_addr_string_fill(addr_string, n_ptr->addr); | 1467 | tipc_addr_string_fill(addr_string, n_ptr->addr); |
1659 | tipc_printf(TIPC_OUTPUT, "Multicast link info for %s\n", addr_string); | 1468 | info("Multicast link info for %s\n", addr_string); |
1660 | tipc_printf(TIPC_OUTPUT, "Supported: %d, ", n_ptr->bclink.supported); | 1469 | info("Supported: %d, ", n_ptr->bclink.supported); |
1661 | tipc_printf(TIPC_OUTPUT, "Acked: %u\n", n_ptr->bclink.acked); | 1470 | info("Acked: %u\n", n_ptr->bclink.acked); |
1662 | tipc_printf(TIPC_OUTPUT, "Last in: %u, ", n_ptr->bclink.last_in); | 1471 | info("Last in: %u, ", n_ptr->bclink.last_in); |
1663 | tipc_printf(TIPC_OUTPUT, "Gap after: %u, ", n_ptr->bclink.gap_after); | 1472 | info("Gap after: %u, ", n_ptr->bclink.gap_after); |
1664 | tipc_printf(TIPC_OUTPUT, "Gap to: %u\n", n_ptr->bclink.gap_to); | 1473 | info("Gap to: %u\n", n_ptr->bclink.gap_to); |
1665 | tipc_printf(TIPC_OUTPUT, "Nack sync: %u\n\n", n_ptr->bclink.nack_sync); | 1474 | info("Nack sync: %u\n\n", n_ptr->bclink.nack_sync); |
1666 | 1475 | ||
1667 | tipc_k_signal((Handler)link_reset_all, (unsigned long)n_ptr->addr); | 1476 | tipc_k_signal((Handler)link_reset_all, (unsigned long)n_ptr->addr); |
1668 | 1477 | ||
@@ -1682,12 +1491,8 @@ void tipc_link_retransmit(struct link *l_ptr, struct sk_buff *buf, | |||
1682 | 1491 | ||
1683 | msg = buf_msg(buf); | 1492 | msg = buf_msg(buf); |
1684 | 1493 | ||
1685 | dbg("Retransmitting %u in link %x\n", retransmits, l_ptr); | ||
1686 | |||
1687 | if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) { | 1494 | if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) { |
1688 | if (l_ptr->retransm_queue_size == 0) { | 1495 | if (l_ptr->retransm_queue_size == 0) { |
1689 | msg_dbg(msg, ">NO_RETR->BCONG>"); | ||
1690 | dbg_print_link(l_ptr, " "); | ||
1691 | l_ptr->retransm_queue_head = msg_seqno(msg); | 1496 | l_ptr->retransm_queue_head = msg_seqno(msg); |
1692 | l_ptr->retransm_queue_size = retransmits; | 1497 | l_ptr->retransm_queue_size = retransmits; |
1693 | } else { | 1498 | } else { |
@@ -1714,7 +1519,6 @@ void tipc_link_retransmit(struct link *l_ptr, struct sk_buff *buf, | |||
1714 | msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); | 1519 | msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); |
1715 | msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); | 1520 | msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); |
1716 | if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { | 1521 | if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { |
1717 | msg_dbg(buf_msg(buf), ">RETR>"); | ||
1718 | buf = buf->next; | 1522 | buf = buf->next; |
1719 | retransmits--; | 1523 | retransmits--; |
1720 | l_ptr->stats.retransmitted++; | 1524 | l_ptr->stats.retransmitted++; |
@@ -1802,11 +1606,19 @@ static int link_recv_buf_validate(struct sk_buff *buf) | |||
1802 | return pskb_may_pull(buf, hdr_size); | 1606 | return pskb_may_pull(buf, hdr_size); |
1803 | } | 1607 | } |
1804 | 1608 | ||
1805 | void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) | 1609 | /** |
1610 | * tipc_recv_msg - process TIPC messages arriving from off-node | ||
1611 | * @head: pointer to message buffer chain | ||
1612 | * @tb_ptr: pointer to bearer message arrived on | ||
1613 | * | ||
1614 | * Invoked with no locks held. Bearer pointer must point to a valid bearer | ||
1615 | * structure (i.e. cannot be NULL), but bearer can be inactive. | ||
1616 | */ | ||
1617 | |||
1618 | void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr) | ||
1806 | { | 1619 | { |
1807 | read_lock_bh(&tipc_net_lock); | 1620 | read_lock_bh(&tipc_net_lock); |
1808 | while (head) { | 1621 | while (head) { |
1809 | struct bearer *b_ptr = (struct bearer *)tb_ptr; | ||
1810 | struct tipc_node *n_ptr; | 1622 | struct tipc_node *n_ptr; |
1811 | struct link *l_ptr; | 1623 | struct link *l_ptr; |
1812 | struct sk_buff *crs; | 1624 | struct sk_buff *crs; |
@@ -1819,6 +1631,11 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) | |||
1819 | 1631 | ||
1820 | head = head->next; | 1632 | head = head->next; |
1821 | 1633 | ||
1634 | /* Ensure bearer is still enabled */ | ||
1635 | |||
1636 | if (unlikely(!b_ptr->active)) | ||
1637 | goto cont; | ||
1638 | |||
1822 | /* Ensure message is well-formed */ | 1639 | /* Ensure message is well-formed */ |
1823 | 1640 | ||
1824 | if (unlikely(!link_recv_buf_validate(buf))) | 1641 | if (unlikely(!link_recv_buf_validate(buf))) |
@@ -1826,9 +1643,8 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) | |||
1826 | 1643 | ||
1827 | /* Ensure message data is a single contiguous unit */ | 1644 | /* Ensure message data is a single contiguous unit */ |
1828 | 1645 | ||
1829 | if (unlikely(buf_linearize(buf))) { | 1646 | if (unlikely(buf_linearize(buf))) |
1830 | goto cont; | 1647 | goto cont; |
1831 | } | ||
1832 | 1648 | ||
1833 | /* Handle arrival of a non-unicast link message */ | 1649 | /* Handle arrival of a non-unicast link message */ |
1834 | 1650 | ||
@@ -1855,13 +1671,22 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) | |||
1855 | goto cont; | 1671 | goto cont; |
1856 | } | 1672 | } |
1857 | 1673 | ||
1858 | /* Locate unicast link endpoint that should handle message */ | 1674 | /* Locate neighboring node that sent message */ |
1859 | 1675 | ||
1860 | n_ptr = tipc_node_find(msg_prevnode(msg)); | 1676 | n_ptr = tipc_node_find(msg_prevnode(msg)); |
1861 | if (unlikely(!n_ptr)) | 1677 | if (unlikely(!n_ptr)) |
1862 | goto cont; | 1678 | goto cont; |
1863 | tipc_node_lock(n_ptr); | 1679 | tipc_node_lock(n_ptr); |
1864 | 1680 | ||
1681 | /* Don't talk to neighbor during cleanup after last session */ | ||
1682 | |||
1683 | if (n_ptr->cleanup_required) { | ||
1684 | tipc_node_unlock(n_ptr); | ||
1685 | goto cont; | ||
1686 | } | ||
1687 | |||
1688 | /* Locate unicast link endpoint that should handle message */ | ||
1689 | |||
1865 | l_ptr = n_ptr->links[b_ptr->identity]; | 1690 | l_ptr = n_ptr->links[b_ptr->identity]; |
1866 | if (unlikely(!l_ptr)) { | 1691 | if (unlikely(!l_ptr)) { |
1867 | tipc_node_unlock(n_ptr); | 1692 | tipc_node_unlock(n_ptr); |
@@ -1929,10 +1754,6 @@ deliver: | |||
1929 | tipc_node_unlock(n_ptr); | 1754 | tipc_node_unlock(n_ptr); |
1930 | tipc_link_recv_bundle(buf); | 1755 | tipc_link_recv_bundle(buf); |
1931 | continue; | 1756 | continue; |
1932 | case ROUTE_DISTRIBUTOR: | ||
1933 | tipc_node_unlock(n_ptr); | ||
1934 | tipc_cltr_recv_routing_table(buf); | ||
1935 | continue; | ||
1936 | case NAME_DISTRIBUTOR: | 1757 | case NAME_DISTRIBUTOR: |
1937 | tipc_node_unlock(n_ptr); | 1758 | tipc_node_unlock(n_ptr); |
1938 | tipc_named_recv(buf); | 1759 | tipc_named_recv(buf); |
@@ -1959,6 +1780,10 @@ deliver: | |||
1959 | goto protocol_check; | 1780 | goto protocol_check; |
1960 | } | 1781 | } |
1961 | break; | 1782 | break; |
1783 | default: | ||
1784 | buf_discard(buf); | ||
1785 | buf = NULL; | ||
1786 | break; | ||
1962 | } | 1787 | } |
1963 | } | 1788 | } |
1964 | tipc_node_unlock(n_ptr); | 1789 | tipc_node_unlock(n_ptr); |
@@ -1977,12 +1802,10 @@ deliver: | |||
1977 | tipc_node_unlock(n_ptr); | 1802 | tipc_node_unlock(n_ptr); |
1978 | continue; | 1803 | continue; |
1979 | } | 1804 | } |
1980 | msg_dbg(msg,"NSEQ<REC<"); | ||
1981 | link_state_event(l_ptr, TRAFFIC_MSG_EVT); | 1805 | link_state_event(l_ptr, TRAFFIC_MSG_EVT); |
1982 | 1806 | ||
1983 | if (link_working_working(l_ptr)) { | 1807 | if (link_working_working(l_ptr)) { |
1984 | /* Re-insert in front of queue */ | 1808 | /* Re-insert in front of queue */ |
1985 | msg_dbg(msg,"RECV-REINS:"); | ||
1986 | buf->next = head; | 1809 | buf->next = head; |
1987 | head = buf; | 1810 | head = buf; |
1988 | tipc_node_unlock(n_ptr); | 1811 | tipc_node_unlock(n_ptr); |
@@ -2036,13 +1859,11 @@ u32 tipc_link_defer_pkt(struct sk_buff **head, | |||
2036 | *head = buf; | 1859 | *head = buf; |
2037 | return 1; | 1860 | return 1; |
2038 | } | 1861 | } |
2039 | if (seq_no == msg_seqno(msg)) { | 1862 | if (seq_no == msg_seqno(msg)) |
2040 | break; | 1863 | break; |
2041 | } | ||
2042 | prev = crs; | 1864 | prev = crs; |
2043 | crs = crs->next; | 1865 | crs = crs->next; |
2044 | } | 1866 | } while (crs); |
2045 | while (crs); | ||
2046 | 1867 | ||
2047 | /* Message is a duplicate of an existing message */ | 1868 | /* Message is a duplicate of an existing message */ |
2048 | 1869 | ||
@@ -2064,9 +1885,6 @@ static void link_handle_out_of_seq_msg(struct link *l_ptr, | |||
2064 | return; | 1885 | return; |
2065 | } | 1886 | } |
2066 | 1887 | ||
2067 | dbg("rx OOS msg: seq_no %u, expecting %u (%u)\n", | ||
2068 | seq_no, mod(l_ptr->next_in_no), l_ptr->next_in_no); | ||
2069 | |||
2070 | /* Record OOS packet arrival (force mismatch on next timeout) */ | 1888 | /* Record OOS packet arrival (force mismatch on next timeout) */ |
2071 | 1889 | ||
2072 | l_ptr->checkpoint--; | 1890 | l_ptr->checkpoint--; |
@@ -2101,6 +1919,7 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg, | |||
2101 | struct sk_buff *buf = NULL; | 1919 | struct sk_buff *buf = NULL; |
2102 | struct tipc_msg *msg = l_ptr->pmsg; | 1920 | struct tipc_msg *msg = l_ptr->pmsg; |
2103 | u32 msg_size = sizeof(l_ptr->proto_msg); | 1921 | u32 msg_size = sizeof(l_ptr->proto_msg); |
1922 | int r_flag; | ||
2104 | 1923 | ||
2105 | if (link_blocked(l_ptr)) | 1924 | if (link_blocked(l_ptr)) |
2106 | return; | 1925 | return; |
@@ -2151,16 +1970,14 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg, | |||
2151 | msg_set_ack(msg, mod(l_ptr->reset_checkpoint - 1)); | 1970 | msg_set_ack(msg, mod(l_ptr->reset_checkpoint - 1)); |
2152 | msg_set_seq_gap(msg, 0); | 1971 | msg_set_seq_gap(msg, 0); |
2153 | msg_set_next_sent(msg, 1); | 1972 | msg_set_next_sent(msg, 1); |
1973 | msg_set_probe(msg, 0); | ||
2154 | msg_set_link_tolerance(msg, l_ptr->tolerance); | 1974 | msg_set_link_tolerance(msg, l_ptr->tolerance); |
2155 | msg_set_linkprio(msg, l_ptr->priority); | 1975 | msg_set_linkprio(msg, l_ptr->priority); |
2156 | msg_set_max_pkt(msg, l_ptr->max_pkt_target); | 1976 | msg_set_max_pkt(msg, l_ptr->max_pkt_target); |
2157 | } | 1977 | } |
2158 | 1978 | ||
2159 | if (tipc_node_has_redundant_links(l_ptr->owner)) { | 1979 | r_flag = (l_ptr->owner->working_links > tipc_link_is_up(l_ptr)); |
2160 | msg_set_redundant_link(msg); | 1980 | msg_set_redundant_link(msg, r_flag); |
2161 | } else { | ||
2162 | msg_clear_redundant_link(msg); | ||
2163 | } | ||
2164 | msg_set_linkprio(msg, l_ptr->priority); | 1981 | msg_set_linkprio(msg, l_ptr->priority); |
2165 | 1982 | ||
2166 | /* Ensure sequence number will not fit : */ | 1983 | /* Ensure sequence number will not fit : */ |
@@ -2172,7 +1989,7 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg, | |||
2172 | if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) { | 1989 | if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) { |
2173 | if (!l_ptr->proto_msg_queue) { | 1990 | if (!l_ptr->proto_msg_queue) { |
2174 | l_ptr->proto_msg_queue = | 1991 | l_ptr->proto_msg_queue = |
2175 | buf_acquire(sizeof(l_ptr->proto_msg)); | 1992 | tipc_buf_acquire(sizeof(l_ptr->proto_msg)); |
2176 | } | 1993 | } |
2177 | buf = l_ptr->proto_msg_queue; | 1994 | buf = l_ptr->proto_msg_queue; |
2178 | if (!buf) | 1995 | if (!buf) |
@@ -2180,13 +1997,10 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg, | |||
2180 | skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg)); | 1997 | skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg)); |
2181 | return; | 1998 | return; |
2182 | } | 1999 | } |
2183 | msg_set_timestamp(msg, jiffies_to_msecs(jiffies)); | ||
2184 | 2000 | ||
2185 | /* Message can be sent */ | 2001 | /* Message can be sent */ |
2186 | 2002 | ||
2187 | msg_dbg(msg, ">>"); | 2003 | buf = tipc_buf_acquire(msg_size); |
2188 | |||
2189 | buf = buf_acquire(msg_size); | ||
2190 | if (!buf) | 2004 | if (!buf) |
2191 | return; | 2005 | return; |
2192 | 2006 | ||
@@ -2219,8 +2033,6 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf) | |||
2219 | u32 msg_tol; | 2033 | u32 msg_tol; |
2220 | struct tipc_msg *msg = buf_msg(buf); | 2034 | struct tipc_msg *msg = buf_msg(buf); |
2221 | 2035 | ||
2222 | dbg("AT(%u):", jiffies_to_msecs(jiffies)); | ||
2223 | msg_dbg(msg, "<<"); | ||
2224 | if (link_blocked(l_ptr)) | 2036 | if (link_blocked(l_ptr)) |
2225 | goto exit; | 2037 | goto exit; |
2226 | 2038 | ||
@@ -2239,11 +2051,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf) | |||
2239 | case RESET_MSG: | 2051 | case RESET_MSG: |
2240 | if (!link_working_unknown(l_ptr) && | 2052 | if (!link_working_unknown(l_ptr) && |
2241 | (l_ptr->peer_session != INVALID_SESSION)) { | 2053 | (l_ptr->peer_session != INVALID_SESSION)) { |
2242 | if (msg_session(msg) == l_ptr->peer_session) { | 2054 | if (msg_session(msg) == l_ptr->peer_session) |
2243 | dbg("Duplicate RESET: %u<->%u\n", | ||
2244 | msg_session(msg), l_ptr->peer_session); | ||
2245 | break; /* duplicate: ignore */ | 2055 | break; /* duplicate: ignore */ |
2246 | } | ||
2247 | } | 2056 | } |
2248 | /* fall thru' */ | 2057 | /* fall thru' */ |
2249 | case ACTIVATE_MSG: | 2058 | case ACTIVATE_MSG: |
@@ -2251,8 +2060,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf) | |||
2251 | 2060 | ||
2252 | strcpy((strrchr(l_ptr->name, ':') + 1), (char *)msg_data(msg)); | 2061 | strcpy((strrchr(l_ptr->name, ':') + 1), (char *)msg_data(msg)); |
2253 | 2062 | ||
2254 | if ((msg_tol = msg_link_tolerance(msg)) && | 2063 | msg_tol = msg_link_tolerance(msg); |
2255 | (msg_tol > l_ptr->tolerance)) | 2064 | if (msg_tol > l_ptr->tolerance) |
2256 | link_set_supervision_props(l_ptr, msg_tol); | 2065 | link_set_supervision_props(l_ptr, msg_tol); |
2257 | 2066 | ||
2258 | if (msg_linkprio(msg) > l_ptr->priority) | 2067 | if (msg_linkprio(msg) > l_ptr->priority) |
@@ -2275,13 +2084,13 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf) | |||
2275 | l_ptr->peer_bearer_id = msg_bearer_id(msg); | 2084 | l_ptr->peer_bearer_id = msg_bearer_id(msg); |
2276 | 2085 | ||
2277 | /* Synchronize broadcast sequence numbers */ | 2086 | /* Synchronize broadcast sequence numbers */ |
2278 | if (!tipc_node_has_redundant_links(l_ptr->owner)) { | 2087 | if (!tipc_node_redundant_links(l_ptr->owner)) |
2279 | l_ptr->owner->bclink.last_in = mod(msg_last_bcast(msg)); | 2088 | l_ptr->owner->bclink.last_in = mod(msg_last_bcast(msg)); |
2280 | } | ||
2281 | break; | 2089 | break; |
2282 | case STATE_MSG: | 2090 | case STATE_MSG: |
2283 | 2091 | ||
2284 | if ((msg_tol = msg_link_tolerance(msg))) | 2092 | msg_tol = msg_link_tolerance(msg); |
2093 | if (msg_tol) | ||
2285 | link_set_supervision_props(l_ptr, msg_tol); | 2094 | link_set_supervision_props(l_ptr, msg_tol); |
2286 | 2095 | ||
2287 | if (msg_linkprio(msg) && | 2096 | if (msg_linkprio(msg) && |
@@ -2304,8 +2113,6 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf) | |||
2304 | 2113 | ||
2305 | max_pkt_ack = msg_max_pkt(msg); | 2114 | max_pkt_ack = msg_max_pkt(msg); |
2306 | if (max_pkt_ack > l_ptr->max_pkt) { | 2115 | if (max_pkt_ack > l_ptr->max_pkt) { |
2307 | dbg("Link <%s> updated MTU %u -> %u\n", | ||
2308 | l_ptr->name, l_ptr->max_pkt, max_pkt_ack); | ||
2309 | l_ptr->max_pkt = max_pkt_ack; | 2116 | l_ptr->max_pkt = max_pkt_ack; |
2310 | l_ptr->max_pkt_probes = 0; | 2117 | l_ptr->max_pkt_probes = 0; |
2311 | } | 2118 | } |
@@ -2313,9 +2120,8 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf) | |||
2313 | max_pkt_ack = 0; | 2120 | max_pkt_ack = 0; |
2314 | if (msg_probe(msg)) { | 2121 | if (msg_probe(msg)) { |
2315 | l_ptr->stats.recv_probes++; | 2122 | l_ptr->stats.recv_probes++; |
2316 | if (msg_size(msg) > sizeof(l_ptr->proto_msg)) { | 2123 | if (msg_size(msg) > sizeof(l_ptr->proto_msg)) |
2317 | max_pkt_ack = msg_size(msg); | 2124 | max_pkt_ack = msg_size(msg); |
2318 | } | ||
2319 | } | 2125 | } |
2320 | 2126 | ||
2321 | /* Protocol message before retransmits, reduce loss risk */ | 2127 | /* Protocol message before retransmits, reduce loss risk */ |
@@ -2327,14 +2133,11 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf) | |||
2327 | 0, rec_gap, 0, 0, max_pkt_ack); | 2133 | 0, rec_gap, 0, 0, max_pkt_ack); |
2328 | } | 2134 | } |
2329 | if (msg_seq_gap(msg)) { | 2135 | if (msg_seq_gap(msg)) { |
2330 | msg_dbg(msg, "With Gap:"); | ||
2331 | l_ptr->stats.recv_nacks++; | 2136 | l_ptr->stats.recv_nacks++; |
2332 | tipc_link_retransmit(l_ptr, l_ptr->first_out, | 2137 | tipc_link_retransmit(l_ptr, l_ptr->first_out, |
2333 | msg_seq_gap(msg)); | 2138 | msg_seq_gap(msg)); |
2334 | } | 2139 | } |
2335 | break; | 2140 | break; |
2336 | default: | ||
2337 | msg_dbg(buf_msg(buf), "<DISCARDING UNKNOWN<"); | ||
2338 | } | 2141 | } |
2339 | exit: | 2142 | exit: |
2340 | buf_discard(buf); | 2143 | buf_discard(buf); |
@@ -2345,10 +2148,10 @@ exit: | |||
2345 | * tipc_link_tunnel(): Send one message via a link belonging to | 2148 | * tipc_link_tunnel(): Send one message via a link belonging to |
2346 | * another bearer. Owner node is locked. | 2149 | * another bearer. Owner node is locked. |
2347 | */ | 2150 | */ |
2348 | void tipc_link_tunnel(struct link *l_ptr, | 2151 | static void tipc_link_tunnel(struct link *l_ptr, |
2349 | struct tipc_msg *tunnel_hdr, | 2152 | struct tipc_msg *tunnel_hdr, |
2350 | struct tipc_msg *msg, | 2153 | struct tipc_msg *msg, |
2351 | u32 selector) | 2154 | u32 selector) |
2352 | { | 2155 | { |
2353 | struct link *tunnel; | 2156 | struct link *tunnel; |
2354 | struct sk_buff *buf; | 2157 | struct sk_buff *buf; |
@@ -2361,7 +2164,7 @@ void tipc_link_tunnel(struct link *l_ptr, | |||
2361 | return; | 2164 | return; |
2362 | } | 2165 | } |
2363 | msg_set_size(tunnel_hdr, length + INT_H_SIZE); | 2166 | msg_set_size(tunnel_hdr, length + INT_H_SIZE); |
2364 | buf = buf_acquire(length + INT_H_SIZE); | 2167 | buf = tipc_buf_acquire(length + INT_H_SIZE); |
2365 | if (!buf) { | 2168 | if (!buf) { |
2366 | warn("Link changeover error, " | 2169 | warn("Link changeover error, " |
2367 | "unable to send tunnel msg\n"); | 2170 | "unable to send tunnel msg\n"); |
@@ -2369,8 +2172,6 @@ void tipc_link_tunnel(struct link *l_ptr, | |||
2369 | } | 2172 | } |
2370 | skb_copy_to_linear_data(buf, tunnel_hdr, INT_H_SIZE); | 2173 | skb_copy_to_linear_data(buf, tunnel_hdr, INT_H_SIZE); |
2371 | skb_copy_to_linear_data_offset(buf, INT_H_SIZE, msg, length); | 2174 | skb_copy_to_linear_data_offset(buf, INT_H_SIZE, msg, length); |
2372 | dbg("%c->%c:", l_ptr->b_ptr->net_plane, tunnel->b_ptr->net_plane); | ||
2373 | msg_dbg(buf_msg(buf), ">SEND>"); | ||
2374 | tipc_link_send_buf(tunnel, buf); | 2175 | tipc_link_send_buf(tunnel, buf); |
2375 | } | 2176 | } |
2376 | 2177 | ||
@@ -2402,18 +2203,14 @@ void tipc_link_changeover(struct link *l_ptr) | |||
2402 | ORIGINAL_MSG, INT_H_SIZE, l_ptr->addr); | 2203 | ORIGINAL_MSG, INT_H_SIZE, l_ptr->addr); |
2403 | msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); | 2204 | msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); |
2404 | msg_set_msgcnt(&tunnel_hdr, msgcount); | 2205 | msg_set_msgcnt(&tunnel_hdr, msgcount); |
2405 | dbg("Link changeover requires %u tunnel messages\n", msgcount); | ||
2406 | 2206 | ||
2407 | if (!l_ptr->first_out) { | 2207 | if (!l_ptr->first_out) { |
2408 | struct sk_buff *buf; | 2208 | struct sk_buff *buf; |
2409 | 2209 | ||
2410 | buf = buf_acquire(INT_H_SIZE); | 2210 | buf = tipc_buf_acquire(INT_H_SIZE); |
2411 | if (buf) { | 2211 | if (buf) { |
2412 | skb_copy_to_linear_data(buf, &tunnel_hdr, INT_H_SIZE); | 2212 | skb_copy_to_linear_data(buf, &tunnel_hdr, INT_H_SIZE); |
2413 | msg_set_size(&tunnel_hdr, INT_H_SIZE); | 2213 | msg_set_size(&tunnel_hdr, INT_H_SIZE); |
2414 | dbg("%c->%c:", l_ptr->b_ptr->net_plane, | ||
2415 | tunnel->b_ptr->net_plane); | ||
2416 | msg_dbg(&tunnel_hdr, "EMPTY>SEND>"); | ||
2417 | tipc_link_send_buf(tunnel, buf); | 2214 | tipc_link_send_buf(tunnel, buf); |
2418 | } else { | 2215 | } else { |
2419 | warn("Link changeover error, " | 2216 | warn("Link changeover error, " |
@@ -2430,11 +2227,11 @@ void tipc_link_changeover(struct link *l_ptr) | |||
2430 | 2227 | ||
2431 | if ((msg_user(msg) == MSG_BUNDLER) && split_bundles) { | 2228 | if ((msg_user(msg) == MSG_BUNDLER) && split_bundles) { |
2432 | struct tipc_msg *m = msg_get_wrapped(msg); | 2229 | struct tipc_msg *m = msg_get_wrapped(msg); |
2433 | unchar* pos = (unchar*)m; | 2230 | unchar *pos = (unchar *)m; |
2434 | 2231 | ||
2435 | msgcount = msg_msgcnt(msg); | 2232 | msgcount = msg_msgcnt(msg); |
2436 | while (msgcount--) { | 2233 | while (msgcount--) { |
2437 | msg_set_seqno(m,msg_seqno(msg)); | 2234 | msg_set_seqno(m, msg_seqno(msg)); |
2438 | tipc_link_tunnel(l_ptr, &tunnel_hdr, m, | 2235 | tipc_link_tunnel(l_ptr, &tunnel_hdr, m, |
2439 | msg_link_selector(m)); | 2236 | msg_link_selector(m)); |
2440 | pos += align(msg_size(m)); | 2237 | pos += align(msg_size(m)); |
@@ -2468,7 +2265,7 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *tunnel) | |||
2468 | msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); /* Update */ | 2265 | msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); /* Update */ |
2469 | msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); | 2266 | msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); |
2470 | msg_set_size(&tunnel_hdr, length + INT_H_SIZE); | 2267 | msg_set_size(&tunnel_hdr, length + INT_H_SIZE); |
2471 | outbuf = buf_acquire(length + INT_H_SIZE); | 2268 | outbuf = tipc_buf_acquire(length + INT_H_SIZE); |
2472 | if (outbuf == NULL) { | 2269 | if (outbuf == NULL) { |
2473 | warn("Link changeover error, " | 2270 | warn("Link changeover error, " |
2474 | "unable to send duplicate msg\n"); | 2271 | "unable to send duplicate msg\n"); |
@@ -2477,9 +2274,6 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *tunnel) | |||
2477 | skb_copy_to_linear_data(outbuf, &tunnel_hdr, INT_H_SIZE); | 2274 | skb_copy_to_linear_data(outbuf, &tunnel_hdr, INT_H_SIZE); |
2478 | skb_copy_to_linear_data_offset(outbuf, INT_H_SIZE, iter->data, | 2275 | skb_copy_to_linear_data_offset(outbuf, INT_H_SIZE, iter->data, |
2479 | length); | 2276 | length); |
2480 | dbg("%c->%c:", l_ptr->b_ptr->net_plane, | ||
2481 | tunnel->b_ptr->net_plane); | ||
2482 | msg_dbg(buf_msg(outbuf), ">SEND>"); | ||
2483 | tipc_link_send_buf(tunnel, outbuf); | 2277 | tipc_link_send_buf(tunnel, outbuf); |
2484 | if (!tipc_link_is_up(l_ptr)) | 2278 | if (!tipc_link_is_up(l_ptr)) |
2485 | return; | 2279 | return; |
@@ -2504,7 +2298,7 @@ static struct sk_buff *buf_extract(struct sk_buff *skb, u32 from_pos) | |||
2504 | u32 size = msg_size(msg); | 2298 | u32 size = msg_size(msg); |
2505 | struct sk_buff *eb; | 2299 | struct sk_buff *eb; |
2506 | 2300 | ||
2507 | eb = buf_acquire(size); | 2301 | eb = tipc_buf_acquire(size); |
2508 | if (eb) | 2302 | if (eb) |
2509 | skb_copy_to_linear_data(eb, msg, size); | 2303 | skb_copy_to_linear_data(eb, msg, size); |
2510 | return eb; | 2304 | return eb; |
@@ -2526,31 +2320,24 @@ static int link_recv_changeover_msg(struct link **l_ptr, | |||
2526 | u32 msg_count = msg_msgcnt(tunnel_msg); | 2320 | u32 msg_count = msg_msgcnt(tunnel_msg); |
2527 | 2321 | ||
2528 | dest_link = (*l_ptr)->owner->links[msg_bearer_id(tunnel_msg)]; | 2322 | dest_link = (*l_ptr)->owner->links[msg_bearer_id(tunnel_msg)]; |
2529 | if (!dest_link) { | 2323 | if (!dest_link) |
2530 | msg_dbg(tunnel_msg, "NOLINK/<REC<"); | ||
2531 | goto exit; | 2324 | goto exit; |
2532 | } | ||
2533 | if (dest_link == *l_ptr) { | 2325 | if (dest_link == *l_ptr) { |
2534 | err("Unexpected changeover message on link <%s>\n", | 2326 | err("Unexpected changeover message on link <%s>\n", |
2535 | (*l_ptr)->name); | 2327 | (*l_ptr)->name); |
2536 | goto exit; | 2328 | goto exit; |
2537 | } | 2329 | } |
2538 | dbg("%c<-%c:", dest_link->b_ptr->net_plane, | ||
2539 | (*l_ptr)->b_ptr->net_plane); | ||
2540 | *l_ptr = dest_link; | 2330 | *l_ptr = dest_link; |
2541 | msg = msg_get_wrapped(tunnel_msg); | 2331 | msg = msg_get_wrapped(tunnel_msg); |
2542 | 2332 | ||
2543 | if (msg_typ == DUPLICATE_MSG) { | 2333 | if (msg_typ == DUPLICATE_MSG) { |
2544 | if (less(msg_seqno(msg), mod(dest_link->next_in_no))) { | 2334 | if (less(msg_seqno(msg), mod(dest_link->next_in_no))) |
2545 | msg_dbg(tunnel_msg, "DROP/<REC<"); | ||
2546 | goto exit; | 2335 | goto exit; |
2547 | } | 2336 | *buf = buf_extract(tunnel_buf, INT_H_SIZE); |
2548 | *buf = buf_extract(tunnel_buf,INT_H_SIZE); | ||
2549 | if (*buf == NULL) { | 2337 | if (*buf == NULL) { |
2550 | warn("Link changeover error, duplicate msg dropped\n"); | 2338 | warn("Link changeover error, duplicate msg dropped\n"); |
2551 | goto exit; | 2339 | goto exit; |
2552 | } | 2340 | } |
2553 | msg_dbg(tunnel_msg, "TNL<REC<"); | ||
2554 | buf_discard(tunnel_buf); | 2341 | buf_discard(tunnel_buf); |
2555 | return 1; | 2342 | return 1; |
2556 | } | 2343 | } |
@@ -2558,18 +2345,14 @@ static int link_recv_changeover_msg(struct link **l_ptr, | |||
2558 | /* First original message ?: */ | 2345 | /* First original message ?: */ |
2559 | 2346 | ||
2560 | if (tipc_link_is_up(dest_link)) { | 2347 | if (tipc_link_is_up(dest_link)) { |
2561 | msg_dbg(tunnel_msg, "UP/FIRST/<REC<"); | ||
2562 | info("Resetting link <%s>, changeover initiated by peer\n", | 2348 | info("Resetting link <%s>, changeover initiated by peer\n", |
2563 | dest_link->name); | 2349 | dest_link->name); |
2564 | tipc_link_reset(dest_link); | 2350 | tipc_link_reset(dest_link); |
2565 | dest_link->exp_msg_count = msg_count; | 2351 | dest_link->exp_msg_count = msg_count; |
2566 | dbg("Expecting %u tunnelled messages\n", msg_count); | ||
2567 | if (!msg_count) | 2352 | if (!msg_count) |
2568 | goto exit; | 2353 | goto exit; |
2569 | } else if (dest_link->exp_msg_count == START_CHANGEOVER) { | 2354 | } else if (dest_link->exp_msg_count == START_CHANGEOVER) { |
2570 | msg_dbg(tunnel_msg, "BLK/FIRST/<REC<"); | ||
2571 | dest_link->exp_msg_count = msg_count; | 2355 | dest_link->exp_msg_count = msg_count; |
2572 | dbg("Expecting %u tunnelled messages\n", msg_count); | ||
2573 | if (!msg_count) | 2356 | if (!msg_count) |
2574 | goto exit; | 2357 | goto exit; |
2575 | } | 2358 | } |
@@ -2579,18 +2362,14 @@ static int link_recv_changeover_msg(struct link **l_ptr, | |||
2579 | if (dest_link->exp_msg_count == 0) { | 2362 | if (dest_link->exp_msg_count == 0) { |
2580 | warn("Link switchover error, " | 2363 | warn("Link switchover error, " |
2581 | "got too many tunnelled messages\n"); | 2364 | "got too many tunnelled messages\n"); |
2582 | msg_dbg(tunnel_msg, "OVERDUE/DROP/<REC<"); | ||
2583 | dbg_print_link(dest_link, "LINK:"); | ||
2584 | goto exit; | 2365 | goto exit; |
2585 | } | 2366 | } |
2586 | dest_link->exp_msg_count--; | 2367 | dest_link->exp_msg_count--; |
2587 | if (less(msg_seqno(msg), dest_link->reset_checkpoint)) { | 2368 | if (less(msg_seqno(msg), dest_link->reset_checkpoint)) { |
2588 | msg_dbg(tunnel_msg, "DROP/DUPL/<REC<"); | ||
2589 | goto exit; | 2369 | goto exit; |
2590 | } else { | 2370 | } else { |
2591 | *buf = buf_extract(tunnel_buf, INT_H_SIZE); | 2371 | *buf = buf_extract(tunnel_buf, INT_H_SIZE); |
2592 | if (*buf != NULL) { | 2372 | if (*buf != NULL) { |
2593 | msg_dbg(tunnel_msg, "TNL<REC<"); | ||
2594 | buf_discard(tunnel_buf); | 2373 | buf_discard(tunnel_buf); |
2595 | return 1; | 2374 | return 1; |
2596 | } else { | 2375 | } else { |
@@ -2612,7 +2391,6 @@ void tipc_link_recv_bundle(struct sk_buff *buf) | |||
2612 | u32 pos = INT_H_SIZE; | 2391 | u32 pos = INT_H_SIZE; |
2613 | struct sk_buff *obuf; | 2392 | struct sk_buff *obuf; |
2614 | 2393 | ||
2615 | msg_dbg(buf_msg(buf), "<BNDL<: "); | ||
2616 | while (msgcount--) { | 2394 | while (msgcount--) { |
2617 | obuf = buf_extract(buf, pos); | 2395 | obuf = buf_extract(buf, pos); |
2618 | if (obuf == NULL) { | 2396 | if (obuf == NULL) { |
@@ -2620,7 +2398,6 @@ void tipc_link_recv_bundle(struct sk_buff *buf) | |||
2620 | break; | 2398 | break; |
2621 | } | 2399 | } |
2622 | pos += align(msg_size(buf_msg(obuf))); | 2400 | pos += align(msg_size(buf_msg(obuf))); |
2623 | msg_dbg(buf_msg(obuf), " /"); | ||
2624 | tipc_net_route_msg(obuf); | 2401 | tipc_net_route_msg(obuf); |
2625 | } | 2402 | } |
2626 | buf_discard(buf); | 2403 | buf_discard(buf); |
@@ -2632,12 +2409,14 @@ void tipc_link_recv_bundle(struct sk_buff *buf) | |||
2632 | 2409 | ||
2633 | 2410 | ||
2634 | /* | 2411 | /* |
2635 | * tipc_link_send_long_buf: Entry for buffers needing fragmentation. | 2412 | * link_send_long_buf: Entry for buffers needing fragmentation. |
2636 | * The buffer is complete, inclusive total message length. | 2413 | * The buffer is complete, inclusive total message length. |
2637 | * Returns user data length. | 2414 | * Returns user data length. |
2638 | */ | 2415 | */ |
2639 | int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) | 2416 | static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) |
2640 | { | 2417 | { |
2418 | struct sk_buff *buf_chain = NULL; | ||
2419 | struct sk_buff *buf_chain_tail = (struct sk_buff *)&buf_chain; | ||
2641 | struct tipc_msg *inmsg = buf_msg(buf); | 2420 | struct tipc_msg *inmsg = buf_msg(buf); |
2642 | struct tipc_msg fragm_hdr; | 2421 | struct tipc_msg fragm_hdr; |
2643 | u32 insize = msg_size(inmsg); | 2422 | u32 insize = msg_size(inmsg); |
@@ -2646,7 +2425,7 @@ int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) | |||
2646 | u32 rest = insize; | 2425 | u32 rest = insize; |
2647 | u32 pack_sz = l_ptr->max_pkt; | 2426 | u32 pack_sz = l_ptr->max_pkt; |
2648 | u32 fragm_sz = pack_sz - INT_H_SIZE; | 2427 | u32 fragm_sz = pack_sz - INT_H_SIZE; |
2649 | u32 fragm_no = 1; | 2428 | u32 fragm_no = 0; |
2650 | u32 destaddr; | 2429 | u32 destaddr; |
2651 | 2430 | ||
2652 | if (msg_short(inmsg)) | 2431 | if (msg_short(inmsg)) |
@@ -2654,17 +2433,10 @@ int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) | |||
2654 | else | 2433 | else |
2655 | destaddr = msg_destnode(inmsg); | 2434 | destaddr = msg_destnode(inmsg); |
2656 | 2435 | ||
2657 | if (msg_routed(inmsg)) | ||
2658 | msg_set_prevnode(inmsg, tipc_own_addr); | ||
2659 | |||
2660 | /* Prepare reusable fragment header: */ | 2436 | /* Prepare reusable fragment header: */ |
2661 | 2437 | ||
2662 | tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, | 2438 | tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, |
2663 | INT_H_SIZE, destaddr); | 2439 | INT_H_SIZE, destaddr); |
2664 | msg_set_link_selector(&fragm_hdr, msg_link_selector(inmsg)); | ||
2665 | msg_set_long_msgno(&fragm_hdr, mod(l_ptr->long_msg_seq_no++)); | ||
2666 | msg_set_fragm_no(&fragm_hdr, fragm_no); | ||
2667 | l_ptr->stats.sent_fragmented++; | ||
2668 | 2440 | ||
2669 | /* Chop up message: */ | 2441 | /* Chop up message: */ |
2670 | 2442 | ||
@@ -2675,29 +2447,39 @@ int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) | |||
2675 | fragm_sz = rest; | 2447 | fragm_sz = rest; |
2676 | msg_set_type(&fragm_hdr, LAST_FRAGMENT); | 2448 | msg_set_type(&fragm_hdr, LAST_FRAGMENT); |
2677 | } | 2449 | } |
2678 | fragm = buf_acquire(fragm_sz + INT_H_SIZE); | 2450 | fragm = tipc_buf_acquire(fragm_sz + INT_H_SIZE); |
2679 | if (fragm == NULL) { | 2451 | if (fragm == NULL) { |
2680 | warn("Link unable to fragment message\n"); | 2452 | buf_discard(buf); |
2681 | dsz = -ENOMEM; | 2453 | while (buf_chain) { |
2682 | goto exit; | 2454 | buf = buf_chain; |
2455 | buf_chain = buf_chain->next; | ||
2456 | buf_discard(buf); | ||
2457 | } | ||
2458 | return -ENOMEM; | ||
2683 | } | 2459 | } |
2684 | msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE); | 2460 | msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE); |
2461 | fragm_no++; | ||
2462 | msg_set_fragm_no(&fragm_hdr, fragm_no); | ||
2685 | skb_copy_to_linear_data(fragm, &fragm_hdr, INT_H_SIZE); | 2463 | skb_copy_to_linear_data(fragm, &fragm_hdr, INT_H_SIZE); |
2686 | skb_copy_to_linear_data_offset(fragm, INT_H_SIZE, crs, | 2464 | skb_copy_to_linear_data_offset(fragm, INT_H_SIZE, crs, |
2687 | fragm_sz); | 2465 | fragm_sz); |
2688 | /* Send queued messages first, if any: */ | 2466 | buf_chain_tail->next = fragm; |
2467 | buf_chain_tail = fragm; | ||
2689 | 2468 | ||
2690 | l_ptr->stats.sent_fragments++; | ||
2691 | tipc_link_send_buf(l_ptr, fragm); | ||
2692 | if (!tipc_link_is_up(l_ptr)) | ||
2693 | return dsz; | ||
2694 | msg_set_fragm_no(&fragm_hdr, ++fragm_no); | ||
2695 | rest -= fragm_sz; | 2469 | rest -= fragm_sz; |
2696 | crs += fragm_sz; | 2470 | crs += fragm_sz; |
2697 | msg_set_type(&fragm_hdr, FRAGMENT); | 2471 | msg_set_type(&fragm_hdr, FRAGMENT); |
2698 | } | 2472 | } |
2699 | exit: | ||
2700 | buf_discard(buf); | 2473 | buf_discard(buf); |
2474 | |||
2475 | /* Append chain of fragments to send queue & send them */ | ||
2476 | |||
2477 | l_ptr->long_msg_seq_no++; | ||
2478 | link_add_chain_to_outqueue(l_ptr, buf_chain, l_ptr->long_msg_seq_no); | ||
2479 | l_ptr->stats.sent_fragments += fragm_no; | ||
2480 | l_ptr->stats.sent_fragmented++; | ||
2481 | tipc_link_push_queue(l_ptr); | ||
2482 | |||
2701 | return dsz; | 2483 | return dsz; |
2702 | } | 2484 | } |
2703 | 2485 | ||
@@ -2705,7 +2487,7 @@ exit: | |||
2705 | * A pending message being re-assembled must store certain values | 2487 | * A pending message being re-assembled must store certain values |
2706 | * to handle subsequent fragments correctly. The following functions | 2488 | * to handle subsequent fragments correctly. The following functions |
2707 | * help storing these values in unused, available fields in the | 2489 | * help storing these values in unused, available fields in the |
2708 | * pending message. This makes dynamic memory allocation unecessary. | 2490 | * pending message. This makes dynamic memory allocation unnecessary. |
2709 | */ | 2491 | */ |
2710 | 2492 | ||
2711 | static void set_long_msg_seqno(struct sk_buff *buf, u32 seqno) | 2493 | static void set_long_msg_seqno(struct sk_buff *buf, u32 seqno) |
@@ -2757,7 +2539,6 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb, | |||
2757 | u32 long_msg_seq_no = msg_long_msgno(fragm); | 2539 | u32 long_msg_seq_no = msg_long_msgno(fragm); |
2758 | 2540 | ||
2759 | *fb = NULL; | 2541 | *fb = NULL; |
2760 | msg_dbg(fragm,"FRG<REC<"); | ||
2761 | 2542 | ||
2762 | /* Is there an incomplete message waiting for this fragment? */ | 2543 | /* Is there an incomplete message waiting for this fragment? */ |
2763 | 2544 | ||
@@ -2776,11 +2557,10 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb, | |||
2776 | if (msg_type(imsg) == TIPC_MCAST_MSG) | 2557 | if (msg_type(imsg) == TIPC_MCAST_MSG) |
2777 | max = TIPC_MAX_USER_MSG_SIZE + MCAST_H_SIZE; | 2558 | max = TIPC_MAX_USER_MSG_SIZE + MCAST_H_SIZE; |
2778 | if (msg_size(imsg) > max) { | 2559 | if (msg_size(imsg) > max) { |
2779 | msg_dbg(fragm,"<REC<Oversized: "); | ||
2780 | buf_discard(fbuf); | 2560 | buf_discard(fbuf); |
2781 | return 0; | 2561 | return 0; |
2782 | } | 2562 | } |
2783 | pbuf = buf_acquire(msg_size(imsg)); | 2563 | pbuf = tipc_buf_acquire(msg_size(imsg)); |
2784 | if (pbuf != NULL) { | 2564 | if (pbuf != NULL) { |
2785 | pbuf->next = *pending; | 2565 | pbuf->next = *pending; |
2786 | *pending = pbuf; | 2566 | *pending = pbuf; |
@@ -2789,8 +2569,8 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb, | |||
2789 | /* Prepare buffer for subsequent fragments. */ | 2569 | /* Prepare buffer for subsequent fragments. */ |
2790 | 2570 | ||
2791 | set_long_msg_seqno(pbuf, long_msg_seq_no); | 2571 | set_long_msg_seqno(pbuf, long_msg_seq_no); |
2792 | set_fragm_size(pbuf,fragm_sz); | 2572 | set_fragm_size(pbuf, fragm_sz); |
2793 | set_expected_frags(pbuf,exp_fragm_cnt - 1); | 2573 | set_expected_frags(pbuf, exp_fragm_cnt - 1); |
2794 | } else { | 2574 | } else { |
2795 | warn("Link unable to reassemble fragmented message\n"); | 2575 | warn("Link unable to reassemble fragmented message\n"); |
2796 | } | 2576 | } |
@@ -2817,13 +2597,9 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb, | |||
2817 | *m = buf_msg(pbuf); | 2597 | *m = buf_msg(pbuf); |
2818 | return 1; | 2598 | return 1; |
2819 | } | 2599 | } |
2820 | set_expected_frags(pbuf,exp_frags); | 2600 | set_expected_frags(pbuf, exp_frags); |
2821 | return 0; | 2601 | return 0; |
2822 | } | 2602 | } |
2823 | dbg(" Discarding orphan fragment %x\n",fbuf); | ||
2824 | msg_dbg(fragm,"ORPHAN:"); | ||
2825 | dbg("Pending long buffers:\n"); | ||
2826 | dbg_print_buf_chain(*pending); | ||
2827 | buf_discard(fbuf); | 2603 | buf_discard(fbuf); |
2828 | return 0; | 2604 | return 0; |
2829 | } | 2605 | } |
@@ -2851,11 +2627,6 @@ static void link_check_defragm_bufs(struct link *l_ptr) | |||
2851 | incr_timer_cnt(buf); | 2627 | incr_timer_cnt(buf); |
2852 | prev = buf; | 2628 | prev = buf; |
2853 | } else { | 2629 | } else { |
2854 | dbg(" Discarding incomplete long buffer\n"); | ||
2855 | msg_dbg(buf_msg(buf), "LONG:"); | ||
2856 | dbg_print_link(l_ptr, "curr:"); | ||
2857 | dbg("Pending long buffers:\n"); | ||
2858 | dbg_print_buf_chain(l_ptr->defragm_buf); | ||
2859 | if (prev) | 2630 | if (prev) |
2860 | prev->next = buf->next; | 2631 | prev->next = buf->next; |
2861 | else | 2632 | else |
@@ -2870,6 +2641,9 @@ static void link_check_defragm_bufs(struct link *l_ptr) | |||
2870 | 2641 | ||
2871 | static void link_set_supervision_props(struct link *l_ptr, u32 tolerance) | 2642 | static void link_set_supervision_props(struct link *l_ptr, u32 tolerance) |
2872 | { | 2643 | { |
2644 | if ((tolerance < TIPC_MIN_LINK_TOL) || (tolerance > TIPC_MAX_LINK_TOL)) | ||
2645 | return; | ||
2646 | |||
2873 | l_ptr->tolerance = tolerance; | 2647 | l_ptr->tolerance = tolerance; |
2874 | l_ptr->continuity_interval = | 2648 | l_ptr->continuity_interval = |
2875 | ((tolerance / 4) > 500) ? 500 : tolerance / 4; | 2649 | ((tolerance / 4) > 500) ? 500 : tolerance / 4; |
@@ -2890,7 +2664,6 @@ void tipc_link_set_queue_limits(struct link *l_ptr, u32 window) | |||
2890 | l_ptr->queue_limit[TIPC_HIGH_IMPORTANCE + 4] = 900; | 2664 | l_ptr->queue_limit[TIPC_HIGH_IMPORTANCE + 4] = 900; |
2891 | l_ptr->queue_limit[TIPC_CRITICAL_IMPORTANCE + 4] = 1200; | 2665 | l_ptr->queue_limit[TIPC_CRITICAL_IMPORTANCE + 4] = 1200; |
2892 | l_ptr->queue_limit[CONN_MANAGER] = 1200; | 2666 | l_ptr->queue_limit[CONN_MANAGER] = 1200; |
2893 | l_ptr->queue_limit[ROUTE_DISTRIBUTOR] = 1200; | ||
2894 | l_ptr->queue_limit[CHANGEOVER_PROTOCOL] = 2500; | 2667 | l_ptr->queue_limit[CHANGEOVER_PROTOCOL] = 2500; |
2895 | l_ptr->queue_limit[NAME_DISTRIBUTOR] = 3000; | 2668 | l_ptr->queue_limit[NAME_DISTRIBUTOR] = 3000; |
2896 | /* FRAGMENT and LAST_FRAGMENT packets */ | 2669 | /* FRAGMENT and LAST_FRAGMENT packets */ |
@@ -2911,7 +2684,7 @@ void tipc_link_set_queue_limits(struct link *l_ptr, u32 window) | |||
2911 | static struct link *link_find_link(const char *name, struct tipc_node **node) | 2684 | static struct link *link_find_link(const char *name, struct tipc_node **node) |
2912 | { | 2685 | { |
2913 | struct link_name link_name_parts; | 2686 | struct link_name link_name_parts; |
2914 | struct bearer *b_ptr; | 2687 | struct tipc_bearer *b_ptr; |
2915 | struct link *l_ptr; | 2688 | struct link *l_ptr; |
2916 | 2689 | ||
2917 | if (!link_name_validate(name, &link_name_parts)) | 2690 | if (!link_name_validate(name, &link_name_parts)) |
@@ -3174,44 +2947,6 @@ struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, int req_tlv_s | |||
3174 | return buf; | 2947 | return buf; |
3175 | } | 2948 | } |
3176 | 2949 | ||
3177 | #if 0 | ||
3178 | int link_control(const char *name, u32 op, u32 val) | ||
3179 | { | ||
3180 | int res = -EINVAL; | ||
3181 | struct link *l_ptr; | ||
3182 | u32 bearer_id; | ||
3183 | struct tipc_node * node; | ||
3184 | u32 a; | ||
3185 | |||
3186 | a = link_name2addr(name, &bearer_id); | ||
3187 | read_lock_bh(&tipc_net_lock); | ||
3188 | node = tipc_node_find(a); | ||
3189 | if (node) { | ||
3190 | tipc_node_lock(node); | ||
3191 | l_ptr = node->links[bearer_id]; | ||
3192 | if (l_ptr) { | ||
3193 | if (op == TIPC_REMOVE_LINK) { | ||
3194 | struct bearer *b_ptr = l_ptr->b_ptr; | ||
3195 | spin_lock_bh(&b_ptr->publ.lock); | ||
3196 | tipc_link_delete(l_ptr); | ||
3197 | spin_unlock_bh(&b_ptr->publ.lock); | ||
3198 | } | ||
3199 | if (op == TIPC_CMD_BLOCK_LINK) { | ||
3200 | tipc_link_reset(l_ptr); | ||
3201 | l_ptr->blocked = 1; | ||
3202 | } | ||
3203 | if (op == TIPC_CMD_UNBLOCK_LINK) { | ||
3204 | l_ptr->blocked = 0; | ||
3205 | } | ||
3206 | res = 0; | ||
3207 | } | ||
3208 | tipc_node_unlock(node); | ||
3209 | } | ||
3210 | read_unlock_bh(&tipc_net_lock); | ||
3211 | return res; | ||
3212 | } | ||
3213 | #endif | ||
3214 | |||
3215 | /** | 2950 | /** |
3216 | * tipc_link_get_max_pkt - get maximum packet size to use when sending to destination | 2951 | * tipc_link_get_max_pkt - get maximum packet size to use when sending to destination |
3217 | * @dest: network address of destination node | 2952 | * @dest: network address of destination node |
@@ -3230,7 +2965,7 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector) | |||
3230 | return MAX_MSG_SIZE; | 2965 | return MAX_MSG_SIZE; |
3231 | 2966 | ||
3232 | read_lock_bh(&tipc_net_lock); | 2967 | read_lock_bh(&tipc_net_lock); |
3233 | n_ptr = tipc_node_select(dest, selector); | 2968 | n_ptr = tipc_node_find(dest); |
3234 | if (n_ptr) { | 2969 | if (n_ptr) { |
3235 | tipc_node_lock(n_ptr); | 2970 | tipc_node_lock(n_ptr); |
3236 | l_ptr = n_ptr->active_links[selector & 1]; | 2971 | l_ptr = n_ptr->active_links[selector & 1]; |
@@ -3242,49 +2977,22 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector) | |||
3242 | return res; | 2977 | return res; |
3243 | } | 2978 | } |
3244 | 2979 | ||
3245 | #if 0 | 2980 | static void link_print(struct link *l_ptr, const char *str) |
3246 | static void link_dump_rec_queue(struct link *l_ptr) | ||
3247 | { | 2981 | { |
3248 | struct sk_buff *crs; | 2982 | char print_area[256]; |
3249 | 2983 | struct print_buf pb; | |
3250 | if (!l_ptr->oldest_deferred_in) { | 2984 | struct print_buf *buf = &pb; |
3251 | info("Reception queue empty\n"); | ||
3252 | return; | ||
3253 | } | ||
3254 | info("Contents of Reception queue:\n"); | ||
3255 | crs = l_ptr->oldest_deferred_in; | ||
3256 | while (crs) { | ||
3257 | if (crs->data == (void *)0x0000a3a3) { | ||
3258 | info("buffer %x invalid\n", crs); | ||
3259 | return; | ||
3260 | } | ||
3261 | msg_dbg(buf_msg(crs), "In rec queue:\n"); | ||
3262 | crs = crs->next; | ||
3263 | } | ||
3264 | } | ||
3265 | #endif | ||
3266 | 2985 | ||
3267 | static void link_dump_send_queue(struct link *l_ptr) | 2986 | tipc_printbuf_init(buf, print_area, sizeof(print_area)); |
3268 | { | ||
3269 | if (l_ptr->next_out) { | ||
3270 | info("\nContents of unsent queue:\n"); | ||
3271 | dbg_print_buf_chain(l_ptr->next_out); | ||
3272 | } | ||
3273 | info("\nContents of send queue:\n"); | ||
3274 | if (l_ptr->first_out) { | ||
3275 | dbg_print_buf_chain(l_ptr->first_out); | ||
3276 | } | ||
3277 | info("Empty send queue\n"); | ||
3278 | } | ||
3279 | 2987 | ||
3280 | static void link_print(struct link *l_ptr, struct print_buf *buf, | ||
3281 | const char *str) | ||
3282 | { | ||
3283 | tipc_printf(buf, str); | 2988 | tipc_printf(buf, str); |
3284 | if (link_reset_reset(l_ptr) || link_reset_unknown(l_ptr)) | ||
3285 | return; | ||
3286 | tipc_printf(buf, "Link %x<%s>:", | 2989 | tipc_printf(buf, "Link %x<%s>:", |
3287 | l_ptr->addr, l_ptr->b_ptr->publ.name); | 2990 | l_ptr->addr, l_ptr->b_ptr->name); |
2991 | |||
2992 | #ifdef CONFIG_TIPC_DEBUG | ||
2993 | if (link_reset_reset(l_ptr) || link_reset_unknown(l_ptr)) | ||
2994 | goto print_state; | ||
2995 | |||
3288 | tipc_printf(buf, ": NXO(%u):", mod(l_ptr->next_out_no)); | 2996 | tipc_printf(buf, ": NXO(%u):", mod(l_ptr->next_out_no)); |
3289 | tipc_printf(buf, "NXI(%u):", mod(l_ptr->next_in_no)); | 2997 | tipc_printf(buf, "NXI(%u):", mod(l_ptr->next_in_no)); |
3290 | tipc_printf(buf, "SQUE"); | 2998 | tipc_printf(buf, "SQUE"); |
@@ -3299,10 +3007,9 @@ static void link_print(struct link *l_ptr, struct print_buf *buf, | |||
3299 | != (l_ptr->out_queue_size - 1)) || | 3007 | != (l_ptr->out_queue_size - 1)) || |
3300 | (l_ptr->last_out->next != NULL)) { | 3008 | (l_ptr->last_out->next != NULL)) { |
3301 | tipc_printf(buf, "\nSend queue inconsistency\n"); | 3009 | tipc_printf(buf, "\nSend queue inconsistency\n"); |
3302 | tipc_printf(buf, "first_out= %x ", l_ptr->first_out); | 3010 | tipc_printf(buf, "first_out= %p ", l_ptr->first_out); |
3303 | tipc_printf(buf, "next_out= %x ", l_ptr->next_out); | 3011 | tipc_printf(buf, "next_out= %p ", l_ptr->next_out); |
3304 | tipc_printf(buf, "last_out= %x ", l_ptr->last_out); | 3012 | tipc_printf(buf, "last_out= %p ", l_ptr->last_out); |
3305 | link_dump_send_queue(l_ptr); | ||
3306 | } | 3013 | } |
3307 | } else | 3014 | } else |
3308 | tipc_printf(buf, "[]"); | 3015 | tipc_printf(buf, "[]"); |
@@ -3316,14 +3023,20 @@ static void link_print(struct link *l_ptr, struct print_buf *buf, | |||
3316 | l_ptr->deferred_inqueue_sz); | 3023 | l_ptr->deferred_inqueue_sz); |
3317 | } | 3024 | } |
3318 | } | 3025 | } |
3026 | print_state: | ||
3027 | #endif | ||
3028 | |||
3319 | if (link_working_unknown(l_ptr)) | 3029 | if (link_working_unknown(l_ptr)) |
3320 | tipc_printf(buf, ":WU"); | 3030 | tipc_printf(buf, ":WU"); |
3321 | if (link_reset_reset(l_ptr)) | 3031 | else if (link_reset_reset(l_ptr)) |
3322 | tipc_printf(buf, ":RR"); | 3032 | tipc_printf(buf, ":RR"); |
3323 | if (link_reset_unknown(l_ptr)) | 3033 | else if (link_reset_unknown(l_ptr)) |
3324 | tipc_printf(buf, ":RU"); | 3034 | tipc_printf(buf, ":RU"); |
3325 | if (link_working_working(l_ptr)) | 3035 | else if (link_working_working(l_ptr)) |
3326 | tipc_printf(buf, ":WW"); | 3036 | tipc_printf(buf, ":WW"); |
3327 | tipc_printf(buf, "\n"); | 3037 | tipc_printf(buf, "\n"); |
3038 | |||
3039 | tipc_printbuf_validate(buf); | ||
3040 | info("%s", print_area); | ||
3328 | } | 3041 | } |
3329 | 3042 | ||