diff options
Diffstat (limited to 'net/tipc/link.c')
| -rw-r--r-- | net/tipc/link.c | 232 |
1 files changed, 99 insertions, 133 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c index a79c755cb417..daa6080a2a0c 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 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, 2012, Ericsson AB |
| 5 | * Copyright (c) 2004-2007, 2010-2011, Wind River Systems | 5 | * Copyright (c) 2004-2007, 2010-2011, Wind River Systems |
| 6 | * All rights reserved. | 6 | * All rights reserved. |
| 7 | * | 7 | * |
| @@ -97,12 +97,13 @@ static int link_send_sections_long(struct tipc_port *sender, | |||
| 97 | struct iovec const *msg_sect, | 97 | struct iovec const *msg_sect, |
| 98 | u32 num_sect, unsigned int total_len, | 98 | u32 num_sect, unsigned int total_len, |
| 99 | u32 destnode); | 99 | u32 destnode); |
| 100 | static void link_check_defragm_bufs(struct tipc_link *l_ptr); | ||
| 101 | static void link_state_event(struct tipc_link *l_ptr, u32 event); | 100 | static void link_state_event(struct tipc_link *l_ptr, u32 event); |
| 102 | static void link_reset_statistics(struct tipc_link *l_ptr); | 101 | static void link_reset_statistics(struct tipc_link *l_ptr); |
| 103 | static void link_print(struct tipc_link *l_ptr, const char *str); | 102 | static void link_print(struct tipc_link *l_ptr, const char *str); |
| 104 | static void link_start(struct tipc_link *l_ptr); | 103 | static void link_start(struct tipc_link *l_ptr); |
| 105 | static int link_send_long_buf(struct tipc_link *l_ptr, struct sk_buff *buf); | 104 | static int link_send_long_buf(struct tipc_link *l_ptr, struct sk_buff *buf); |
| 105 | static void tipc_link_send_sync(struct tipc_link *l); | ||
| 106 | static void tipc_link_recv_sync(struct tipc_node *n, struct sk_buff *buf); | ||
| 106 | 107 | ||
| 107 | /* | 108 | /* |
| 108 | * Simple link routines | 109 | * Simple link routines |
| @@ -269,7 +270,6 @@ static void link_timeout(struct tipc_link *l_ptr) | |||
| 269 | } | 270 | } |
| 270 | 271 | ||
| 271 | /* do all other link processing performed on a periodic basis */ | 272 | /* do all other link processing performed on a periodic basis */ |
| 272 | link_check_defragm_bufs(l_ptr); | ||
| 273 | 273 | ||
| 274 | link_state_event(l_ptr, TIMEOUT_EVT); | 274 | link_state_event(l_ptr, TIMEOUT_EVT); |
| 275 | 275 | ||
| @@ -712,6 +712,8 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event) | |||
| 712 | link_activate(l_ptr); | 712 | link_activate(l_ptr); |
| 713 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0); | 713 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0); |
| 714 | l_ptr->fsm_msg_cnt++; | 714 | l_ptr->fsm_msg_cnt++; |
| 715 | if (l_ptr->owner->working_links == 1) | ||
| 716 | tipc_link_send_sync(l_ptr); | ||
| 715 | link_set_timer(l_ptr, cont_intv); | 717 | link_set_timer(l_ptr, cont_intv); |
| 716 | break; | 718 | break; |
| 717 | case RESET_MSG: | 719 | case RESET_MSG: |
| @@ -745,6 +747,8 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event) | |||
| 745 | link_activate(l_ptr); | 747 | link_activate(l_ptr); |
| 746 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0); | 748 | tipc_link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0); |
| 747 | l_ptr->fsm_msg_cnt++; | 749 | l_ptr->fsm_msg_cnt++; |
| 750 | if (l_ptr->owner->working_links == 1) | ||
| 751 | tipc_link_send_sync(l_ptr); | ||
| 748 | link_set_timer(l_ptr, cont_intv); | 752 | link_set_timer(l_ptr, cont_intv); |
| 749 | break; | 753 | break; |
| 750 | case RESET_MSG: | 754 | case RESET_MSG: |
| @@ -872,17 +876,12 @@ int tipc_link_send_buf(struct tipc_link *l_ptr, struct sk_buff *buf) | |||
| 872 | return link_send_long_buf(l_ptr, buf); | 876 | return link_send_long_buf(l_ptr, buf); |
| 873 | 877 | ||
| 874 | /* Packet can be queued or sent. */ | 878 | /* Packet can be queued or sent. */ |
| 875 | if (likely(!tipc_bearer_congested(l_ptr->b_ptr, l_ptr) && | 879 | if (likely(!tipc_bearer_blocked(l_ptr->b_ptr) && |
| 876 | !link_congested(l_ptr))) { | 880 | !link_congested(l_ptr))) { |
| 877 | link_add_to_outqueue(l_ptr, buf, msg); | 881 | link_add_to_outqueue(l_ptr, buf, msg); |
| 878 | 882 | ||
| 879 | if (likely(tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr))) { | 883 | tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr); |
| 880 | l_ptr->unacked_window = 0; | 884 | l_ptr->unacked_window = 0; |
| 881 | } else { | ||
| 882 | tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); | ||
| 883 | l_ptr->stats.bearer_congs++; | ||
| 884 | l_ptr->next_out = buf; | ||
| 885 | } | ||
| 886 | return dsz; | 885 | return dsz; |
| 887 | } | 886 | } |
| 888 | /* Congestion: can message be bundled ? */ | 887 | /* Congestion: can message be bundled ? */ |
| @@ -891,10 +890,8 @@ int tipc_link_send_buf(struct tipc_link *l_ptr, struct sk_buff *buf) | |||
| 891 | 890 | ||
| 892 | /* Try adding message to an existing bundle */ | 891 | /* Try adding message to an existing bundle */ |
| 893 | if (l_ptr->next_out && | 892 | if (l_ptr->next_out && |
| 894 | link_bundle_buf(l_ptr, l_ptr->last_out, buf)) { | 893 | link_bundle_buf(l_ptr, l_ptr->last_out, buf)) |
| 895 | tipc_bearer_resolve_congestion(l_ptr->b_ptr, l_ptr); | ||
| 896 | return dsz; | 894 | return dsz; |
| 897 | } | ||
| 898 | 895 | ||
| 899 | /* Try creating a new bundle */ | 896 | /* Try creating a new bundle */ |
| 900 | if (size <= max_packet * 2 / 3) { | 897 | if (size <= max_packet * 2 / 3) { |
| @@ -917,7 +914,6 @@ int tipc_link_send_buf(struct tipc_link *l_ptr, struct sk_buff *buf) | |||
| 917 | if (!l_ptr->next_out) | 914 | if (!l_ptr->next_out) |
| 918 | l_ptr->next_out = buf; | 915 | l_ptr->next_out = buf; |
| 919 | link_add_to_outqueue(l_ptr, buf, msg); | 916 | link_add_to_outqueue(l_ptr, buf, msg); |
| 920 | tipc_bearer_resolve_congestion(l_ptr->b_ptr, l_ptr); | ||
| 921 | return dsz; | 917 | return dsz; |
| 922 | } | 918 | } |
| 923 | 919 | ||
| @@ -949,7 +945,48 @@ int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector) | |||
| 949 | return res; | 945 | return res; |
| 950 | } | 946 | } |
| 951 | 947 | ||
| 952 | /** | 948 | /* |
| 949 | * tipc_link_send_sync - synchronize broadcast link endpoints. | ||
| 950 | * | ||
| 951 | * Give a newly added peer node the sequence number where it should | ||
| 952 | * start receiving and acking broadcast packets. | ||
| 953 | * | ||
| 954 | * Called with node locked | ||
| 955 | */ | ||
| 956 | static void tipc_link_send_sync(struct tipc_link *l) | ||
| 957 | { | ||
| 958 | struct sk_buff *buf; | ||
| 959 | struct tipc_msg *msg; | ||
| 960 | |||
| 961 | buf = tipc_buf_acquire(INT_H_SIZE); | ||
| 962 | if (!buf) | ||
| 963 | return; | ||
| 964 | |||
| 965 | msg = buf_msg(buf); | ||
| 966 | tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG, INT_H_SIZE, l->addr); | ||
| 967 | msg_set_last_bcast(msg, l->owner->bclink.acked); | ||
| 968 | link_add_chain_to_outqueue(l, buf, 0); | ||
| 969 | tipc_link_push_queue(l); | ||
| 970 | } | ||
| 971 | |||
| 972 | /* | ||
| 973 | * tipc_link_recv_sync - synchronize broadcast link endpoints. | ||
| 974 | * Receive the sequence number where we should start receiving and | ||
| 975 | * acking broadcast packets from a newly added peer node, and open | ||
| 976 | * up for reception of such packets. | ||
| 977 | * | ||
| 978 | * Called with node locked | ||
| 979 | */ | ||
| 980 | static void tipc_link_recv_sync(struct tipc_node *n, struct sk_buff *buf) | ||
| 981 | { | ||
| 982 | struct tipc_msg *msg = buf_msg(buf); | ||
| 983 | |||
| 984 | n->bclink.last_sent = n->bclink.last_in = msg_last_bcast(msg); | ||
| 985 | n->bclink.recv_permitted = true; | ||
| 986 | kfree_skb(buf); | ||
| 987 | } | ||
| 988 | |||
| 989 | /* | ||
| 953 | * tipc_link_send_names - send name table entries to new neighbor | 990 | * tipc_link_send_names - send name table entries to new neighbor |
| 954 | * | 991 | * |
| 955 | * Send routine for bulk delivery of name table messages when contact | 992 | * Send routine for bulk delivery of name table messages when contact |
| @@ -1006,16 +1043,11 @@ static int link_send_buf_fast(struct tipc_link *l_ptr, struct sk_buff *buf, | |||
| 1006 | 1043 | ||
| 1007 | if (likely(!link_congested(l_ptr))) { | 1044 | if (likely(!link_congested(l_ptr))) { |
| 1008 | if (likely(msg_size(msg) <= l_ptr->max_pkt)) { | 1045 | if (likely(msg_size(msg) <= l_ptr->max_pkt)) { |
| 1009 | if (likely(list_empty(&l_ptr->b_ptr->cong_links))) { | 1046 | if (likely(!tipc_bearer_blocked(l_ptr->b_ptr))) { |
| 1010 | link_add_to_outqueue(l_ptr, buf, msg); | 1047 | link_add_to_outqueue(l_ptr, buf, msg); |
| 1011 | if (likely(tipc_bearer_send(l_ptr->b_ptr, buf, | 1048 | tipc_bearer_send(l_ptr->b_ptr, buf, |
| 1012 | &l_ptr->media_addr))) { | 1049 | &l_ptr->media_addr); |
| 1013 | l_ptr->unacked_window = 0; | 1050 | l_ptr->unacked_window = 0; |
| 1014 | return res; | ||
| 1015 | } | ||
| 1016 | tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); | ||
| 1017 | l_ptr->stats.bearer_congs++; | ||
| 1018 | l_ptr->next_out = buf; | ||
| 1019 | return res; | 1051 | return res; |
| 1020 | } | 1052 | } |
| 1021 | } else | 1053 | } else |
| @@ -1106,7 +1138,7 @@ exit: | |||
| 1106 | 1138 | ||
| 1107 | /* Exit if link (or bearer) is congested */ | 1139 | /* Exit if link (or bearer) is congested */ |
| 1108 | if (link_congested(l_ptr) || | 1140 | if (link_congested(l_ptr) || |
| 1109 | !list_empty(&l_ptr->b_ptr->cong_links)) { | 1141 | tipc_bearer_blocked(l_ptr->b_ptr)) { |
| 1110 | res = link_schedule_port(l_ptr, | 1142 | res = link_schedule_port(l_ptr, |
| 1111 | sender->ref, res); | 1143 | sender->ref, res); |
| 1112 | goto exit; | 1144 | goto exit; |
| @@ -1329,15 +1361,11 @@ u32 tipc_link_push_packet(struct tipc_link *l_ptr) | |||
| 1329 | if (r_q_size && buf) { | 1361 | if (r_q_size && buf) { |
| 1330 | msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); | 1362 | msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); |
| 1331 | msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in); | 1363 | msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in); |
| 1332 | if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { | 1364 | tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr); |
| 1333 | l_ptr->retransm_queue_head = mod(++r_q_head); | 1365 | l_ptr->retransm_queue_head = mod(++r_q_head); |
| 1334 | l_ptr->retransm_queue_size = --r_q_size; | 1366 | l_ptr->retransm_queue_size = --r_q_size; |
| 1335 | l_ptr->stats.retransmitted++; | 1367 | l_ptr->stats.retransmitted++; |
| 1336 | return 0; | 1368 | return 0; |
| 1337 | } else { | ||
| 1338 | l_ptr->stats.bearer_congs++; | ||
| 1339 | return PUSH_FAILED; | ||
| 1340 | } | ||
| 1341 | } | 1369 | } |
| 1342 | 1370 | ||
| 1343 | /* Send deferred protocol message, if any: */ | 1371 | /* Send deferred protocol message, if any: */ |
| @@ -1345,15 +1373,11 @@ u32 tipc_link_push_packet(struct tipc_link *l_ptr) | |||
| 1345 | if (buf) { | 1373 | if (buf) { |
| 1346 | msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); | 1374 | msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); |
| 1347 | msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in); | 1375 | msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in); |
| 1348 | if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { | 1376 | tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr); |
| 1349 | l_ptr->unacked_window = 0; | 1377 | l_ptr->unacked_window = 0; |
| 1350 | kfree_skb(buf); | 1378 | kfree_skb(buf); |
| 1351 | l_ptr->proto_msg_queue = NULL; | 1379 | l_ptr->proto_msg_queue = NULL; |
| 1352 | return 0; | 1380 | return 0; |
| 1353 | } else { | ||
| 1354 | l_ptr->stats.bearer_congs++; | ||
| 1355 | return PUSH_FAILED; | ||
| 1356 | } | ||
| 1357 | } | 1381 | } |
| 1358 | 1382 | ||
| 1359 | /* Send one deferred data message, if send window not full: */ | 1383 | /* Send one deferred data message, if send window not full: */ |
| @@ -1366,18 +1390,14 @@ u32 tipc_link_push_packet(struct tipc_link *l_ptr) | |||
| 1366 | if (mod(next - first) < l_ptr->queue_limit[0]) { | 1390 | if (mod(next - first) < l_ptr->queue_limit[0]) { |
| 1367 | msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); | 1391 | msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); |
| 1368 | msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); | 1392 | msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); |
| 1369 | if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { | 1393 | tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr); |
| 1370 | if (msg_user(msg) == MSG_BUNDLER) | 1394 | if (msg_user(msg) == MSG_BUNDLER) |
| 1371 | msg_set_type(msg, CLOSED_MSG); | 1395 | msg_set_type(msg, CLOSED_MSG); |
| 1372 | l_ptr->next_out = buf->next; | 1396 | l_ptr->next_out = buf->next; |
| 1373 | return 0; | 1397 | return 0; |
| 1374 | } else { | ||
| 1375 | l_ptr->stats.bearer_congs++; | ||
| 1376 | return PUSH_FAILED; | ||
| 1377 | } | ||
| 1378 | } | 1398 | } |
| 1379 | } | 1399 | } |
| 1380 | return PUSH_FINISHED; | 1400 | return 1; |
| 1381 | } | 1401 | } |
| 1382 | 1402 | ||
| 1383 | /* | 1403 | /* |
| @@ -1388,15 +1408,12 @@ void tipc_link_push_queue(struct tipc_link *l_ptr) | |||
| 1388 | { | 1408 | { |
| 1389 | u32 res; | 1409 | u32 res; |
| 1390 | 1410 | ||
| 1391 | if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) | 1411 | if (tipc_bearer_blocked(l_ptr->b_ptr)) |
| 1392 | return; | 1412 | return; |
| 1393 | 1413 | ||
| 1394 | do { | 1414 | do { |
| 1395 | res = tipc_link_push_packet(l_ptr); | 1415 | res = tipc_link_push_packet(l_ptr); |
| 1396 | } while (!res); | 1416 | } while (!res); |
| 1397 | |||
| 1398 | if (res == PUSH_FAILED) | ||
| 1399 | tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); | ||
| 1400 | } | 1417 | } |
| 1401 | 1418 | ||
| 1402 | static void link_reset_all(unsigned long addr) | 1419 | static void link_reset_all(unsigned long addr) |
| @@ -1454,9 +1471,8 @@ static void link_retransmit_failure(struct tipc_link *l_ptr, | |||
| 1454 | 1471 | ||
| 1455 | tipc_addr_string_fill(addr_string, n_ptr->addr); | 1472 | tipc_addr_string_fill(addr_string, n_ptr->addr); |
| 1456 | pr_info("Broadcast link info for %s\n", addr_string); | 1473 | pr_info("Broadcast link info for %s\n", addr_string); |
| 1457 | pr_info("Supportable: %d, Supported: %d, Acked: %u\n", | 1474 | pr_info("Reception permitted: %d, Acked: %u\n", |
| 1458 | n_ptr->bclink.supportable, | 1475 | n_ptr->bclink.recv_permitted, |
| 1459 | n_ptr->bclink.supported, | ||
| 1460 | n_ptr->bclink.acked); | 1476 | n_ptr->bclink.acked); |
| 1461 | pr_info("Last in: %u, Oos state: %u, Last sent: %u\n", | 1477 | pr_info("Last in: %u, Oos state: %u, Last sent: %u\n", |
| 1462 | n_ptr->bclink.last_in, | 1478 | n_ptr->bclink.last_in, |
| @@ -1481,7 +1497,7 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *buf, | |||
| 1481 | 1497 | ||
| 1482 | msg = buf_msg(buf); | 1498 | msg = buf_msg(buf); |
| 1483 | 1499 | ||
| 1484 | if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) { | 1500 | if (tipc_bearer_blocked(l_ptr->b_ptr)) { |
| 1485 | if (l_ptr->retransm_queue_size == 0) { | 1501 | if (l_ptr->retransm_queue_size == 0) { |
| 1486 | l_ptr->retransm_queue_head = msg_seqno(msg); | 1502 | l_ptr->retransm_queue_head = msg_seqno(msg); |
| 1487 | l_ptr->retransm_queue_size = retransmits; | 1503 | l_ptr->retransm_queue_size = retransmits; |
| @@ -1491,7 +1507,7 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *buf, | |||
| 1491 | } | 1507 | } |
| 1492 | return; | 1508 | return; |
| 1493 | } else { | 1509 | } else { |
| 1494 | /* Detect repeated retransmit failures on uncongested bearer */ | 1510 | /* Detect repeated retransmit failures on unblocked bearer */ |
| 1495 | if (l_ptr->last_retransmitted == msg_seqno(msg)) { | 1511 | if (l_ptr->last_retransmitted == msg_seqno(msg)) { |
| 1496 | if (++l_ptr->stale_count > 100) { | 1512 | if (++l_ptr->stale_count > 100) { |
| 1497 | link_retransmit_failure(l_ptr, buf); | 1513 | link_retransmit_failure(l_ptr, buf); |
| @@ -1507,17 +1523,10 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *buf, | |||
| 1507 | msg = buf_msg(buf); | 1523 | msg = buf_msg(buf); |
| 1508 | msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); | 1524 | msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); |
| 1509 | msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); | 1525 | msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); |
| 1510 | if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { | 1526 | tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr); |
| 1511 | buf = buf->next; | 1527 | buf = buf->next; |
| 1512 | retransmits--; | 1528 | retransmits--; |
| 1513 | l_ptr->stats.retransmitted++; | 1529 | l_ptr->stats.retransmitted++; |
| 1514 | } else { | ||
| 1515 | tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); | ||
| 1516 | l_ptr->stats.bearer_congs++; | ||
| 1517 | l_ptr->retransm_queue_head = buf_seqno(buf); | ||
| 1518 | l_ptr->retransm_queue_size = retransmits; | ||
| 1519 | return; | ||
| 1520 | } | ||
| 1521 | } | 1530 | } |
| 1522 | 1531 | ||
| 1523 | l_ptr->retransm_queue_head = l_ptr->retransm_queue_size = 0; | 1532 | l_ptr->retransm_queue_head = l_ptr->retransm_queue_size = 0; |
| @@ -1676,7 +1685,7 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr) | |||
| 1676 | ackd = msg_ack(msg); | 1685 | ackd = msg_ack(msg); |
| 1677 | 1686 | ||
| 1678 | /* Release acked messages */ | 1687 | /* Release acked messages */ |
| 1679 | if (n_ptr->bclink.supported) | 1688 | if (n_ptr->bclink.recv_permitted) |
| 1680 | tipc_bclink_acknowledge(n_ptr, msg_bcast_ack(msg)); | 1689 | tipc_bclink_acknowledge(n_ptr, msg_bcast_ack(msg)); |
| 1681 | 1690 | ||
| 1682 | crs = l_ptr->first_out; | 1691 | crs = l_ptr->first_out; |
| @@ -1727,9 +1736,14 @@ deliver: | |||
| 1727 | tipc_link_recv_bundle(buf); | 1736 | tipc_link_recv_bundle(buf); |
| 1728 | continue; | 1737 | continue; |
| 1729 | case NAME_DISTRIBUTOR: | 1738 | case NAME_DISTRIBUTOR: |
| 1739 | n_ptr->bclink.recv_permitted = true; | ||
| 1730 | tipc_node_unlock(n_ptr); | 1740 | tipc_node_unlock(n_ptr); |
| 1731 | tipc_named_recv(buf); | 1741 | tipc_named_recv(buf); |
| 1732 | continue; | 1742 | continue; |
| 1743 | case BCAST_PROTOCOL: | ||
| 1744 | tipc_link_recv_sync(n_ptr, buf); | ||
| 1745 | tipc_node_unlock(n_ptr); | ||
| 1746 | continue; | ||
| 1733 | case CONN_MANAGER: | 1747 | case CONN_MANAGER: |
| 1734 | tipc_node_unlock(n_ptr); | 1748 | tipc_node_unlock(n_ptr); |
| 1735 | tipc_port_recv_proto_msg(buf); | 1749 | tipc_port_recv_proto_msg(buf); |
| @@ -1772,16 +1786,19 @@ deliver: | |||
| 1772 | continue; | 1786 | continue; |
| 1773 | } | 1787 | } |
| 1774 | 1788 | ||
| 1789 | /* Link is not in state WORKING_WORKING */ | ||
| 1775 | if (msg_user(msg) == LINK_PROTOCOL) { | 1790 | if (msg_user(msg) == LINK_PROTOCOL) { |
| 1776 | link_recv_proto_msg(l_ptr, buf); | 1791 | link_recv_proto_msg(l_ptr, buf); |
| 1777 | head = link_insert_deferred_queue(l_ptr, head); | 1792 | head = link_insert_deferred_queue(l_ptr, head); |
| 1778 | tipc_node_unlock(n_ptr); | 1793 | tipc_node_unlock(n_ptr); |
| 1779 | continue; | 1794 | continue; |
| 1780 | } | 1795 | } |
| 1796 | |||
| 1797 | /* Traffic message. Conditionally activate link */ | ||
| 1781 | link_state_event(l_ptr, TRAFFIC_MSG_EVT); | 1798 | link_state_event(l_ptr, TRAFFIC_MSG_EVT); |
| 1782 | 1799 | ||
| 1783 | if (link_working_working(l_ptr)) { | 1800 | if (link_working_working(l_ptr)) { |
| 1784 | /* Re-insert in front of queue */ | 1801 | /* Re-insert buffer in front of queue */ |
| 1785 | buf->next = head; | 1802 | buf->next = head; |
| 1786 | head = buf; | 1803 | head = buf; |
| 1787 | tipc_node_unlock(n_ptr); | 1804 | tipc_node_unlock(n_ptr); |
| @@ -1972,21 +1989,13 @@ void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ, | |||
| 1972 | 1989 | ||
| 1973 | skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg)); | 1990 | skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg)); |
| 1974 | 1991 | ||
| 1975 | /* Defer message if bearer is already congested */ | 1992 | /* Defer message if bearer is already blocked */ |
| 1976 | if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) { | 1993 | if (tipc_bearer_blocked(l_ptr->b_ptr)) { |
| 1977 | l_ptr->proto_msg_queue = buf; | ||
| 1978 | return; | ||
| 1979 | } | ||
| 1980 | |||
| 1981 | /* Defer message if attempting to send results in bearer congestion */ | ||
| 1982 | if (!tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { | ||
| 1983 | tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); | ||
| 1984 | l_ptr->proto_msg_queue = buf; | 1994 | l_ptr->proto_msg_queue = buf; |
| 1985 | l_ptr->stats.bearer_congs++; | ||
| 1986 | return; | 1995 | return; |
| 1987 | } | 1996 | } |
| 1988 | 1997 | ||
| 1989 | /* Discard message if it was sent successfully */ | 1998 | tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr); |
| 1990 | l_ptr->unacked_window = 0; | 1999 | l_ptr->unacked_window = 0; |
| 1991 | kfree_skb(buf); | 2000 | kfree_skb(buf); |
| 1992 | } | 2001 | } |
| @@ -2057,7 +2066,6 @@ static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf) | |||
| 2057 | } else { | 2066 | } else { |
| 2058 | l_ptr->max_pkt = l_ptr->max_pkt_target; | 2067 | l_ptr->max_pkt = l_ptr->max_pkt_target; |
| 2059 | } | 2068 | } |
| 2060 | l_ptr->owner->bclink.supportable = (max_pkt_info != 0); | ||
| 2061 | 2069 | ||
| 2062 | /* Synchronize broadcast link info, if not done previously */ | 2070 | /* Synchronize broadcast link info, if not done previously */ |
| 2063 | if (!tipc_node_is_up(l_ptr->owner)) { | 2071 | if (!tipc_node_is_up(l_ptr->owner)) { |
| @@ -2112,7 +2120,7 @@ static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf) | |||
| 2112 | } | 2120 | } |
| 2113 | 2121 | ||
| 2114 | /* Protocol message before retransmits, reduce loss risk */ | 2122 | /* Protocol message before retransmits, reduce loss risk */ |
| 2115 | if (l_ptr->owner->bclink.supported) | 2123 | if (l_ptr->owner->bclink.recv_permitted) |
| 2116 | tipc_bclink_update_link_state(l_ptr->owner, | 2124 | tipc_bclink_update_link_state(l_ptr->owner, |
| 2117 | msg_last_bcast(msg)); | 2125 | msg_last_bcast(msg)); |
| 2118 | 2126 | ||
| @@ -2487,16 +2495,6 @@ static void set_expected_frags(struct sk_buff *buf, u32 exp) | |||
| 2487 | msg_set_bcast_ack(buf_msg(buf), exp); | 2495 | msg_set_bcast_ack(buf_msg(buf), exp); |
| 2488 | } | 2496 | } |
| 2489 | 2497 | ||
| 2490 | static u32 get_timer_cnt(struct sk_buff *buf) | ||
| 2491 | { | ||
| 2492 | return msg_reroute_cnt(buf_msg(buf)); | ||
| 2493 | } | ||
| 2494 | |||
| 2495 | static void incr_timer_cnt(struct sk_buff *buf) | ||
| 2496 | { | ||
| 2497 | msg_incr_reroute_cnt(buf_msg(buf)); | ||
| 2498 | } | ||
| 2499 | |||
| 2500 | /* | 2498 | /* |
| 2501 | * tipc_link_recv_fragment(): Called with node lock on. Returns | 2499 | * tipc_link_recv_fragment(): Called with node lock on. Returns |
| 2502 | * the reassembled buffer if message is complete. | 2500 | * the reassembled buffer if message is complete. |
| @@ -2575,38 +2573,6 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb, | |||
| 2575 | return 0; | 2573 | return 0; |
| 2576 | } | 2574 | } |
| 2577 | 2575 | ||
| 2578 | /** | ||
| 2579 | * link_check_defragm_bufs - flush stale incoming message fragments | ||
| 2580 | * @l_ptr: pointer to link | ||
| 2581 | */ | ||
| 2582 | static void link_check_defragm_bufs(struct tipc_link *l_ptr) | ||
| 2583 | { | ||
| 2584 | struct sk_buff *prev = NULL; | ||
| 2585 | struct sk_buff *next = NULL; | ||
| 2586 | struct sk_buff *buf = l_ptr->defragm_buf; | ||
| 2587 | |||
| 2588 | if (!buf) | ||
| 2589 | return; | ||
| 2590 | if (!link_working_working(l_ptr)) | ||
| 2591 | return; | ||
| 2592 | while (buf) { | ||
| 2593 | u32 cnt = get_timer_cnt(buf); | ||
| 2594 | |||
| 2595 | next = buf->next; | ||
| 2596 | if (cnt < 4) { | ||
| 2597 | incr_timer_cnt(buf); | ||
| 2598 | prev = buf; | ||
| 2599 | } else { | ||
| 2600 | if (prev) | ||
| 2601 | prev->next = buf->next; | ||
| 2602 | else | ||
| 2603 | l_ptr->defragm_buf = buf->next; | ||
| 2604 | kfree_skb(buf); | ||
| 2605 | } | ||
| 2606 | buf = next; | ||
| 2607 | } | ||
| 2608 | } | ||
| 2609 | |||
| 2610 | static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tolerance) | 2576 | static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tolerance) |
| 2611 | { | 2577 | { |
| 2612 | if ((tolerance < TIPC_MIN_LINK_TOL) || (tolerance > TIPC_MAX_LINK_TOL)) | 2578 | if ((tolerance < TIPC_MIN_LINK_TOL) || (tolerance > TIPC_MAX_LINK_TOL)) |
| @@ -2937,8 +2903,8 @@ static int tipc_link_stats(const char *name, char *buf, const u32 buf_size) | |||
| 2937 | s->sent_nacks, s->sent_acks, s->retransmitted); | 2903 | s->sent_nacks, s->sent_acks, s->retransmitted); |
| 2938 | 2904 | ||
| 2939 | ret += tipc_snprintf(buf + ret, buf_size - ret, | 2905 | ret += tipc_snprintf(buf + ret, buf_size - ret, |
| 2940 | " Congestion bearer:%u link:%u Send queue" | 2906 | " Congestion link:%u Send queue" |
| 2941 | " max:%u avg:%u\n", s->bearer_congs, s->link_congs, | 2907 | " max:%u avg:%u\n", s->link_congs, |
| 2942 | s->max_queue_sz, s->queue_sz_counts ? | 2908 | s->max_queue_sz, s->queue_sz_counts ? |
| 2943 | (s->accu_queue_sz / s->queue_sz_counts) : 0); | 2909 | (s->accu_queue_sz / s->queue_sz_counts) : 0); |
| 2944 | 2910 | ||
