* limitations under the License.
*/
#include <vnet/tcp/tcp.h>
+#include <vnet/tcp/tcp_inlines.h>
#define TCP_TEST_I(_cond, _comment, _args...) \
({ \
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);
* Add new block
*/
tc->flags = 0;
+ tc->rcv_opts.flags |= TCP_OPTS_FLAG_SACK;
vec_reset_length (tc->rcv_opts.sacks);
block.start = 1200;
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
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");
+ /*
+ * Restart
+ */
+ scoreboard_clear (sb);
+ vec_reset_length (tc->rcv_opts.sacks);
+
+ /*
+ * Inject [100 500]
+ */
+
+ tc->flags |= TCP_CONN_FAST_RECOVERY | TCP_CONN_RECOVERY;
+ tc->snd_una = 0;
+ tc->snd_una_max = 1000;
+ tc->snd_nxt = 1000;
+ sb->high_rxt = 0;
+
+ block.start = 100;
+ block.end = 500;
+ vec_add1 (tc->rcv_opts.sacks, block);
+ tc->rcv_opts.n_sack_blocks = vec_len (tc->rcv_opts.sacks);
+
+ tcp_rcv_sacks (tc, 0);
+
+ TCP_TEST ((sb->sacked_bytes == 400), "sacked bytes %d", sb->sacked_bytes);
+ TCP_TEST ((sb->last_sacked_bytes == 400), "last sacked bytes %d",
+ sb->last_sacked_bytes);
+ TCP_TEST ((!sb->is_reneging), "is not reneging");
+
+ /*
+ * Renege, sack all of the remaining bytes and cover some rxt bytes
+ */
+ sb->high_rxt = 700;
+ tc->rcv_opts.sacks[0].start = 500;
+ tc->rcv_opts.sacks[0].end = 1000;
+
+ tcp_rcv_sacks (tc, 100);
+
+ TCP_TEST ((sb->sacked_bytes == 900), "sacked bytes %d", sb->sacked_bytes);
+ TCP_TEST ((sb->last_sacked_bytes == 500), "last sacked bytes %d",
+ sb->last_sacked_bytes);
+ TCP_TEST (sb->is_reneging, "is reneging");
+ 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;
}
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;
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;
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;
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;
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;
{
int res = 0;
+ vnet_session_enable_disable (vm, 1);
+
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
if (unformat (input, "sack"))