aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorAllan Stephens <allan.stephens@windriver.com>2011-10-25 11:20:26 -0400
committerPaul Gortmaker <paul.gortmaker@windriver.com>2012-02-06 16:59:15 -0500
commit92d2c905b404d8d056ce35a0ce645e23529742c2 (patch)
tree39d447aa3323210fda1835de5290fe3b1e309734 /net/tipc
parent8809b255a9fca8c3179491d3bc9268c42e23ba97 (diff)
tipc: Prevent transmission of outdated link protocol messages
Ensures that a link endpoint discards any previously deferred link protocol message whenever it attempts to send a new one. Previously, it was possible for a link protocol message that was unsent due to congestion to be transmitted after newer protocol messages had been sent. The stale link protocol message might then cause the receiving link endpoint to malfunction because of its outdated conent. Thanks to Osamu Kaminuma [okaminum@avaya.com] for diagnosing the problem and contributing a prototype patch. Signed-off-by: Allan Stephens <allan.stephens@windriver.com> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/link.c53
1 files changed, 27 insertions, 26 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index c317abf74a78..bee316ce387c 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1954,6 +1954,13 @@ void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ,
1954 u32 msg_size = sizeof(l_ptr->proto_msg); 1954 u32 msg_size = sizeof(l_ptr->proto_msg);
1955 int r_flag; 1955 int r_flag;
1956 1956
1957 /* Discard any previous message that was deferred due to congestion */
1958
1959 if (l_ptr->proto_msg_queue) {
1960 buf_discard(l_ptr->proto_msg_queue);
1961 l_ptr->proto_msg_queue = NULL;
1962 }
1963
1957 if (link_blocked(l_ptr)) 1964 if (link_blocked(l_ptr))
1958 return; 1965 return;
1959 1966
@@ -1962,6 +1969,8 @@ void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ,
1962 if ((l_ptr->owner->block_setup) && (msg_typ != RESET_MSG)) 1969 if ((l_ptr->owner->block_setup) && (msg_typ != RESET_MSG))
1963 return; 1970 return;
1964 1971
1972 /* Create protocol message with "out-of-sequence" sequence number */
1973
1965 msg_set_type(msg, msg_typ); 1974 msg_set_type(msg, msg_typ);
1966 msg_set_net_plane(msg, l_ptr->b_ptr->net_plane); 1975 msg_set_net_plane(msg, l_ptr->b_ptr->net_plane);
1967 msg_set_bcast_ack(msg, mod(l_ptr->owner->bclink.last_in)); 1976 msg_set_bcast_ack(msg, mod(l_ptr->owner->bclink.last_in));
@@ -2018,44 +2027,36 @@ void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ,
2018 r_flag = (l_ptr->owner->working_links > tipc_link_is_up(l_ptr)); 2027 r_flag = (l_ptr->owner->working_links > tipc_link_is_up(l_ptr));
2019 msg_set_redundant_link(msg, r_flag); 2028 msg_set_redundant_link(msg, r_flag);
2020 msg_set_linkprio(msg, l_ptr->priority); 2029 msg_set_linkprio(msg, l_ptr->priority);
2021 2030 msg_set_size(msg, msg_size);
2022 /* Ensure sequence number will not fit : */
2023 2031
2024 msg_set_seqno(msg, mod(l_ptr->next_out_no + (0xffff/2))); 2032 msg_set_seqno(msg, mod(l_ptr->next_out_no + (0xffff/2)));
2025 2033
2026 /* Congestion? */
2027
2028 if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) {
2029 if (!l_ptr->proto_msg_queue) {
2030 l_ptr->proto_msg_queue =
2031 tipc_buf_acquire(sizeof(l_ptr->proto_msg));
2032 }
2033 buf = l_ptr->proto_msg_queue;
2034 if (!buf)
2035 return;
2036 skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg));
2037 return;
2038 }
2039
2040 /* Message can be sent */
2041
2042 buf = tipc_buf_acquire(msg_size); 2034 buf = tipc_buf_acquire(msg_size);
2043 if (!buf) 2035 if (!buf)
2044 return; 2036 return;
2045 2037
2046 skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg)); 2038 skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg));
2047 msg_set_size(buf_msg(buf), msg_size);
2048 2039
2049 if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { 2040 /* Defer message if bearer is already congested */
2050 l_ptr->unacked_window = 0; 2041
2051 buf_discard(buf); 2042 if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) {
2043 l_ptr->proto_msg_queue = buf;
2044 return;
2045 }
2046
2047 /* Defer message if attempting to send results in bearer congestion */
2048
2049 if (!tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) {
2050 tipc_bearer_schedule(l_ptr->b_ptr, l_ptr);
2051 l_ptr->proto_msg_queue = buf;
2052 l_ptr->stats.bearer_congs++;
2052 return; 2053 return;
2053 } 2054 }
2054 2055
2055 /* New congestion */ 2056 /* Discard message if it was sent successfully */
2056 tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); 2057
2057 l_ptr->proto_msg_queue = buf; 2058 l_ptr->unacked_window = 0;
2058 l_ptr->stats.bearer_congs++; 2059 buf_discard(buf);
2059} 2060}
2060 2061
2061/* 2062/*