tcp: fix the tcp unittest to work
[vpp.git] / src / plugins / unittest / tcp_test.c
index 777e173..3e5ba9c 100644 (file)
@@ -13,6 +13,7 @@
  * limitations under the License.
  */
 #include <vnet/tcp/tcp.h>
+#include <vnet/tcp/tcp_inlines.h>
 
 #define TCP_TEST_I(_cond, _comment, _args...)                  \
 ({                                                             \
@@ -262,11 +263,44 @@ tcp_test_sack_rx (vlib_main_t * vm, unformat_input_t * input)
            sb->rxt_sacked);
 
   /*
-   * Sack all up to 1000
+   * Sack remaining bytes [990 1000]
    */
+  tc->rcv_opts.sacks[0].start = 990;
+  tc->rcv_opts.sacks[0].end = 1000;
+
+  tcp_rcv_sacks (tc, 960);
+
+  TCP_TEST ((sb->is_reneging), "is reneging");
+  TCP_TEST ((sb->sacked_bytes == 40), "sacked bytes %d", sb->sacked_bytes);
+  TCP_TEST ((sb->last_sacked_bytes == 10),
+           "last sacked bytes %d", sb->last_sacked_bytes);
+  TCP_TEST ((sb->rxt_sacked == 0), "last rxt sacked bytes %d",
+           sb->rxt_sacked);
+  TCP_TEST (pool_elts (sb->holes) == 0, "no holes left");
+
+  /*
+   * Ack up to 970 no sack blocks
+   */
+  vec_reset_length (tc->rcv_opts.sacks);
+  tc->rcv_opts.flags &= ~TCP_OPTS_FLAG_SACK;
+  tcp_rcv_sacks (tc, 970);
+
+  TCP_TEST ((sb->is_reneging), "is reneging");
+  TCP_TEST ((sb->sacked_bytes == 30), "sacked bytes %d", sb->sacked_bytes);
+  TCP_TEST ((sb->last_sacked_bytes == 0),
+           "last sacked bytes %d", sb->last_sacked_bytes);
+  TCP_TEST ((sb->rxt_sacked == 0), "last rxt sacked bytes %d",
+           sb->rxt_sacked);
+
+  /*
+   * Ack all up to 1000
+   */
+  tc->snd_una = 970;
   tcp_rcv_sacks (tc, 1000);
   TCP_TEST ((sb->high_sacked == 1000), "max sacked byte %u", sb->high_sacked);
   TCP_TEST ((sb->sacked_bytes == 0), "sacked bytes %d", sb->sacked_bytes);
+  TCP_TEST (sb->last_bytes_delivered == 30, "last bytes delivered %d",
+           sb->last_bytes_delivered);
   TCP_TEST ((sb->last_sacked_bytes == 0),
            "last sacked bytes %d", sb->last_sacked_bytes);
   TCP_TEST ((sb->lost_bytes == 0), "lost bytes %u", sb->lost_bytes);
@@ -276,6 +310,7 @@ tcp_test_sack_rx (vlib_main_t * vm, unformat_input_t * input)
    * Add new block
    */
   tc->flags = 0;
+  tc->rcv_opts.flags |= TCP_OPTS_FLAG_SACK;
   vec_reset_length (tc->rcv_opts.sacks);
 
   block.start = 1200;
@@ -470,7 +505,9 @@ tcp_test_sack_rx (vlib_main_t * vm, unformat_input_t * input)
            sb->last_sacked_bytes);
   TCP_TEST ((sb->last_bytes_delivered == 0), "last bytes delivered %d",
            sb->last_bytes_delivered);
+  /* Hole should be split in 2 lost holes that add up to 300 */
   TCP_TEST ((sb->lost_bytes == 300), "lost bytes %u", sb->lost_bytes);
+  TCP_TEST ((sb->reorder == 7), "reorder %u", sb->reorder);
 
   /*
    * Ack [100 300] in two steps
@@ -555,7 +592,9 @@ tcp_test_sack_rx (vlib_main_t * vm, unformat_input_t * input)
            sb->last_sacked_bytes);
   TCP_TEST ((sb->last_bytes_delivered == 0), "last bytes delivered %d",
            sb->last_bytes_delivered);
-  TCP_TEST ((sb->lost_bytes == 200), "lost bytes %u", sb->lost_bytes);
+  /* No bytes lost because of reorder */
+  TCP_TEST ((sb->lost_bytes == 0), "lost bytes %u", sb->lost_bytes);
+  TCP_TEST ((sb->reorder == 7), "reorder %u", sb->reorder);
   TCP_TEST ((!sb->is_reneging), "is not reneging");
 
   /*
@@ -602,6 +641,32 @@ tcp_test_sack_rx (vlib_main_t * vm, unformat_input_t * input)
   TCP_TEST ((sb->rxt_sacked == 300), "last rxt sacked bytes %d",
            sb->rxt_sacked);
 
+  /*
+   * Restart
+   */
+  scoreboard_clear (sb);
+  vec_reset_length (tc->rcv_opts.sacks);
+
+  /*
+   * Broken sacks:
+   * block.start > snd_nxt
+   * && block.start < blk.end
+   * && block.end <= snd_nxt
+   */
+  tc->flags = 0;
+  block.start = 2147483647;
+  block.end = 4294967295;
+  vec_add1 (tc->rcv_opts.sacks, block);
+  tc->snd_una = tc->snd_nxt = 1969067947;
+
+  tcp_rcv_sacks (tc, tc->snd_una);
+
+  /*
+   * Clear
+   */
+  scoreboard_clear (sb);
+  vec_reset_length (tc->rcv_opts.sacks);
+
   return 0;
 }
 
@@ -781,7 +846,6 @@ static int
 tcp_test_lookup (vlib_main_t * vm, unformat_input_t * input)
 {
   session_main_t *smm = &session_main;
-  tcp_main_t *tm = &tcp_main;
   transport_connection_t _tc1, *tc1 = &_tc1, _tc2, *tc2 = &_tc2, *tconn;
   tcp_connection_t *tc;
   session_t *s, *s1;
@@ -795,9 +859,7 @@ tcp_test_lookup (vlib_main_t * vm, unformat_input_t * input)
   clib_memset (s, 0, sizeof (*s));
   s->session_index = sidx = s - smm->wrk[0].sessions;
 
-  pool_get (tm->connections[0], tc);
-  clib_memset (tc, 0, sizeof (*tc));
-  tc->connection.c_index = tc - tm->connections[0];
+  tc = tcp_connection_alloc (0);
   tc->connection.s_index = s->session_index;
   s->connection_index = tc->connection.c_index;
 
@@ -816,9 +878,7 @@ tcp_test_lookup (vlib_main_t * vm, unformat_input_t * input)
   clib_memset (s, 0, sizeof (*s));
   s->session_index = s - smm->wrk[0].sessions;
 
-  pool_get (tm->connections[0], tc);
-  clib_memset (tc, 0, sizeof (*tc));
-  tc->connection.c_index = tc - tm->connections[0];
+  tc = tcp_connection_alloc (0);
   tc->connection.s_index = s->session_index;
   s->connection_index = tc->connection.c_index;
 
@@ -892,7 +952,6 @@ tcp_test_session (vlib_main_t * vm, unformat_input_t * input)
   tcp_connection_t *tc0;
   ip4_address_t local, remote;
   u16 local_port, remote_port;
-  tcp_main_t *tm = vnet_get_tcp_main ();
   int is_add = 1;
 
 
@@ -913,12 +972,10 @@ tcp_test_session (vlib_main_t * vm, unformat_input_t * input)
       local_port = clib_host_to_net_u16 (1234);
       remote_port = clib_host_to_net_u16 (11234);
 
-      pool_get (tm->connections[0], tc0);
-      clib_memset (tc0, 0, sizeof (*tc0));
+      tc0 = tcp_connection_alloc (0);
 
       tc0->state = TCP_STATE_ESTABLISHED;
       tc0->rcv_las = 1;
-      tc0->c_c_index = tc0 - tm->connections[0];
       tc0->c_lcl_port = local_port;
       tc0->c_rmt_port = remote_port;
       tc0->c_is_ip4 = 1;
@@ -1284,6 +1341,8 @@ tcp_test (vlib_main_t * vm,
 {
   int res = 0;
 
+  vnet_session_enable_disable (vm, 1);
+
   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
     {
       if (unformat (input, "sack"))