aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorAllan Stephens <allan.stephens@windriver.com>2011-10-27 16:31:26 -0400
committerPaul Gortmaker <paul.gortmaker@windriver.com>2012-02-06 16:59:19 -0500
commitb76b27cad5ade1d483d4b94df6b35976bccf1055 (patch)
tree1f7bd0490d6cdacff0411d3fc2ab5cfab11cf9ba /net/tipc
parent1ec2bb08407b377e5954b3f9479c2bf67fc925a9 (diff)
tipc: Prevent loss of fragmented messages over unicast links
Modifies unicast link endpoint logic so an incoming fragmented message is not lost if reassembly cannot begin because there is no buffer big enough to hold the entire reassembled message. The link endpoint now ignores the first fragment completely, which causes the sending node to retransmit the first fragment so that reassembly can be re-attempted. Previously, the sender would have had no reason to retransmit the 1st fragment, so we would never have a chance to re-try the allocation. Signed-off-by: Allan Stephens <allan.stephens@windriver.com>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/link.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index cce953723ddb..d8b0a22367b6 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1774,6 +1774,7 @@ protocol_check:
1774 head = link_insert_deferred_queue(l_ptr, 1774 head = link_insert_deferred_queue(l_ptr,
1775 head); 1775 head);
1776 if (likely(msg_is_dest(msg, tipc_own_addr))) { 1776 if (likely(msg_is_dest(msg, tipc_own_addr))) {
1777 int ret;
1777deliver: 1778deliver:
1778 if (likely(msg_isdata(msg))) { 1779 if (likely(msg_isdata(msg))) {
1779 tipc_node_unlock(n_ptr); 1780 tipc_node_unlock(n_ptr);
@@ -1798,11 +1799,15 @@ deliver:
1798 continue; 1799 continue;
1799 case MSG_FRAGMENTER: 1800 case MSG_FRAGMENTER:
1800 l_ptr->stats.recv_fragments++; 1801 l_ptr->stats.recv_fragments++;
1801 if (tipc_link_recv_fragment(&l_ptr->defragm_buf, 1802 ret = tipc_link_recv_fragment(
1802 &buf, &msg)) { 1803 &l_ptr->defragm_buf,
1804 &buf, &msg);
1805 if (ret == 1) {
1803 l_ptr->stats.recv_fragmented++; 1806 l_ptr->stats.recv_fragmented++;
1804 goto deliver; 1807 goto deliver;
1805 } 1808 }
1809 if (ret == -1)
1810 l_ptr->next_in_no--;
1806 break; 1811 break;
1807 case CHANGEOVER_PROTOCOL: 1812 case CHANGEOVER_PROTOCOL:
1808 type = msg_type(msg); 1813 type = msg_type(msg);
@@ -2632,7 +2637,9 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
2632 set_fragm_size(pbuf, fragm_sz); 2637 set_fragm_size(pbuf, fragm_sz);
2633 set_expected_frags(pbuf, exp_fragm_cnt - 1); 2638 set_expected_frags(pbuf, exp_fragm_cnt - 1);
2634 } else { 2639 } else {
2635 warn("Link unable to reassemble fragmented message\n"); 2640 dbg("Link unable to reassemble fragmented message\n");
2641 buf_discard(fbuf);
2642 return -1;
2636 } 2643 }
2637 buf_discard(fbuf); 2644 buf_discard(fbuf);
2638 return 0; 2645 return 0;