tcp: avoid rcv wnd more than RX fifo can enqueue

Type: fix

Signed-off-by: Ryujiro Shibuya <ryujiro.shibuya@owmobility.com>
Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: Ie358b731f8ecb1fcaebd6e79f5ce5c10802c2814
(cherry picked from commit cc1085647b)
This commit is contained in:
Ryujiro Shibuya
2020-06-24 08:36:14 +01:00
committed by Andrew Yourtchenko
parent 347a225866
commit 1ff8a6c32a
2 changed files with 12 additions and 7 deletions

View File

@@ -121,6 +121,11 @@ tcp_update_rcv_wnd (tcp_connection_t * tc)
* Figure out how much space we have available
*/
available_space = transport_max_rx_enqueue (&tc->connection);
/* Make sure we have a multiple of 1 << rcv_wscale. We round down to
* avoid advertising a window larger than what can be buffered */
available_space = round_down_pow2 (available_space, 1 << tc->rcv_wscale);
if (PREDICT_FALSE (available_space < tc->rcv_opts.mss))
{
tc->rcv_wnd = 0;
@@ -136,7 +141,7 @@ tcp_update_rcv_wnd (tcp_connection_t * tc)
/* Bad. Thou shalt not shrink */
if (PREDICT_FALSE ((i32) available_space < observed_wnd))
{
wnd = clib_max (observed_wnd, 0);
wnd = round_pow2 (clib_max (observed_wnd, 0), 1 << tc->rcv_wscale);
TCP_EVT (TCP_EVT_RCV_WND_SHRUNK, tc, observed_wnd, available_space);
}
else
@@ -144,12 +149,6 @@ tcp_update_rcv_wnd (tcp_connection_t * tc)
wnd = available_space;
}
/* Make sure we have a multiple of 1 << rcv_wscale. We round up to
* avoid advertising a window less than mss which could happen if
* 1 << rcv_wscale < mss */
if (wnd && tc->rcv_wscale)
wnd = round_pow2 (wnd, 1 << tc->rcv_wscale);
tc->rcv_wnd = clib_min (wnd, TCP_WND_MAX << tc->rcv_wscale);
}

View File

@@ -237,6 +237,12 @@ is_pow2 (uword x)
return 0 == (x & (x - 1));
}
always_inline uword
round_down_pow2 (uword x, uword pow2)
{
return (x) & ~(pow2 - 1);
}
always_inline uword
round_pow2 (uword x, uword pow2)
{