tcp: avoid rcv wnd more than RX fifo can enqueue 54/27654/4
authorRyujiro Shibuya <ryujiro.shibuya@owmobility.com>
Wed, 24 Jun 2020 07:36:14 +0000 (08:36 +0100)
committerFlorin Coras <florin.coras@gmail.com>
Tue, 30 Jun 2020 04:25:41 +0000 (04:25 +0000)
Type: fix

Signed-off-by: Ryujiro Shibuya <ryujiro.shibuya@owmobility.com>
Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: Ie358b731f8ecb1fcaebd6e79f5ce5c10802c2814

src/vnet/tcp/tcp_output.c
src/vppinfra/clib.h

index afc6520..3b1bbac 100644 (file)
@@ -120,6 +120,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;
@@ -135,7 +140,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
@@ -143,12 +148,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);
 }
 
index 6961d10..be21cad 100644 (file)
@@ -253,6 +253,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)
 {