aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet')
-rw-r--r--src/vnet/tcp/tcp_test.c305
1 files changed, 246 insertions, 59 deletions
diff --git a/src/vnet/tcp/tcp_test.c b/src/vnet/tcp/tcp_test.c
index 12579632e3d..890e50b9b24 100644
--- a/src/vnet/tcp/tcp_test.c
+++ b/src/vnet/tcp/tcp_test.c
@@ -294,6 +294,34 @@ fifo_get_validate_pattern (vlib_main_t * vm, test_pattern_t * test_data,
return validate_pattern;
}
+static svm_fifo_t *
+fifo_prepare (u32 fifo_size)
+{
+ svm_fifo_t *f;
+ f = svm_fifo_create (fifo_size);
+
+ /* Paint fifo data vector with -1's */
+ memset (f->data, 0xFF, fifo_size);
+
+ return f;
+}
+
+static int
+compare_data (u8 * data1, u8 * data2, u32 start, u32 len, u32 * index)
+{
+ int i;
+
+ for (i = start; i < len; i++)
+ {
+ if (data1[i] != data2[i])
+ {
+ *index = i;
+ return 1;
+ }
+ }
+ return 0;
+}
+
int
tcp_test_fifo1 (vlib_main_t * vm, unformat_input_t * input)
{
@@ -302,9 +330,9 @@ tcp_test_fifo1 (vlib_main_t * vm, unformat_input_t * input)
u32 *test_data = 0;
u32 offset;
int i, rv, verbose = 0;
- u32 data_word, test_data_len;
+ u32 data_word, test_data_len, j;
ooo_segment_t *ooo_seg;
- u8 *data;
+ u8 *data, *s, *data_buf = 0;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
@@ -318,12 +346,11 @@ tcp_test_fifo1 (vlib_main_t * vm, unformat_input_t * input)
for (i = 0; i < vec_len (test_data); i++)
test_data[i] = i;
- f = svm_fifo_create (fifo_size);
-
- /* Paint fifo data vector with -1's */
- memset (f->data, 0xFF, test_data_len);
+ f = fifo_prepare (fifo_size);
- /* Enqueue an initial (un-dequeued) chunk */
+ /*
+ * Enqueue an initial (un-dequeued) chunk
+ */
rv = svm_fifo_enqueue_nowait (f, 0 /* pid */ ,
sizeof (u32), (u8 *) test_data);
TCP_TEST ((rv == sizeof (u32)), "enqueued %d", rv);
@@ -337,9 +364,7 @@ tcp_test_fifo1 (vlib_main_t * vm, unformat_input_t * input)
{
offset = (2 * i + 1) * sizeof (u32);
data = (u8 *) (test_data + (2 * i + 1));
- rv =
- svm_fifo_enqueue_with_offset (f, 0 /* pid */ , offset, sizeof (u32),
- data);
+ rv = svm_fifo_enqueue_with_offset (f, 0, offset, sizeof (u32), data);
if (verbose)
vlib_cli_output (vm, "add [%d] [%d, %d]", 2 * i + 1, offset,
offset + sizeof (u32));
@@ -352,16 +377,23 @@ tcp_test_fifo1 (vlib_main_t * vm, unformat_input_t * input)
if (verbose)
vlib_cli_output (vm, "fifo after odd segs: %U", format_svm_fifo, f, 1);
+
TCP_TEST ((f->tail == 8), "fifo tail %u", f->tail);
- /* Paint some of missing data backwards */
+ /*
+ * Make sure format functions are not buggy
+ */
+ s = format (0, "%U", format_svm_fifo, f, 2);
+ vec_free (s);
+
+ /*
+ * Paint some of missing data backwards
+ */
for (i = 3; i > 1; i--)
{
offset = (2 * i + 0) * sizeof (u32);
data = (u8 *) (test_data + (2 * i + 0));
- rv =
- svm_fifo_enqueue_with_offset (f, 0 /* pid */ , offset, sizeof (u32),
- data);
+ rv = svm_fifo_enqueue_with_offset (f, 0, offset, sizeof (u32), data);
if (verbose)
vlib_cli_output (vm, "add [%d] [%d, %d]", 2 * i, offset,
offset + sizeof (u32));
@@ -383,7 +415,9 @@ tcp_test_fifo1 (vlib_main_t * vm, unformat_input_t * input)
TCP_TEST ((ooo_seg->length == 16),
"first ooo seg length %u", ooo_seg->length);
- /* Enqueue the missing u32 */
+ /*
+ * Enqueue the missing u32
+ */
rv = svm_fifo_enqueue_nowait (f, 0 /* pid */ , sizeof (u32),
(u8 *) (test_data + 2));
if (verbose)
@@ -393,7 +427,9 @@ tcp_test_fifo1 (vlib_main_t * vm, unformat_input_t * input)
TCP_TEST ((svm_fifo_number_ooo_segments (f) == 0),
"number of ooo segments %u", svm_fifo_number_ooo_segments (f));
- /* Collect results */
+ /*
+ * Collect results
+ */
for (i = 0; i < 7; i++)
{
rv = svm_fifo_dequeue_nowait (f, 0 /* pid */ , sizeof (u32),
@@ -411,8 +447,77 @@ tcp_test_fifo1 (vlib_main_t * vm, unformat_input_t * input)
}
}
+ /*
+ * Test segment overlaps: last ooo segment overlaps all
+ */
+ svm_fifo_free (f);
+ f = fifo_prepare (fifo_size);
+
+ for (i = 0; i < 4; i++)
+ {
+ offset = (2 * i + 1) * sizeof (u32);
+ data = (u8 *) (test_data + (2 * i + 1));
+ rv = svm_fifo_enqueue_with_offset (f, 0, offset, sizeof (u32), data);
+ if (verbose)
+ vlib_cli_output (vm, "add [%d] [%d, %d]", 2 * i + 1, offset,
+ offset + sizeof (u32));
+ if (rv)
+ {
+ clib_warning ("enqueue returned %d", rv);
+ goto err;
+ }
+ }
+
+ rv = svm_fifo_enqueue_with_offset (f, 0, 8, 21, data);
+ TCP_TEST ((rv == 0), "ooo enqueued %u", rv);
+ TCP_TEST ((svm_fifo_number_ooo_segments (f) == 1),
+ "number of ooo segments %u", svm_fifo_number_ooo_segments (f));
+
+ vec_validate (data_buf, vec_len (data));
+ svm_fifo_peek (f, 0, 0, vec_len (data), data_buf);
+ if (compare_data (data_buf, data, 8, vec_len (data), &j))
+ {
+ TCP_TEST (0, "[%d] peeked %u expected %u", j, data_buf[j], data[j]);
+ }
+ vec_reset_length (data_buf);
+
+ /*
+ * Test segment overlaps: enqueue and overlap ooo segments
+ */
+ svm_fifo_free (f);
+ f = fifo_prepare (fifo_size);
+
+ for (i = 0; i < 4; i++)
+ {
+ offset = (2 * i + 1) * sizeof (u32);
+ data = (u8 *) (test_data + (2 * i + 1));
+ rv = svm_fifo_enqueue_with_offset (f, 0, offset, sizeof (u32), data);
+ if (verbose)
+ vlib_cli_output (vm, "add [%d] [%d, %d]", 2 * i + 1, offset,
+ offset + sizeof (u32));
+ if (rv)
+ {
+ clib_warning ("enqueue returned %d", rv);
+ goto err;
+ }
+ }
+
+ rv = svm_fifo_enqueue_nowait (f, 0, 29, data);
+ TCP_TEST ((rv == 32), "ooo enqueued %u", rv);
+ TCP_TEST ((svm_fifo_number_ooo_segments (f) == 0),
+ "number of ooo segments %u", svm_fifo_number_ooo_segments (f));
+
+ vec_validate (data_buf, vec_len (data));
+ svm_fifo_peek (f, 0, 0, vec_len (data), data_buf);
+ if (compare_data (data_buf, data, 0, vec_len (data), &j))
+ {
+ TCP_TEST (0, "[%d] peeked %u expected %u", j, data_buf[j], data[j]);
+ }
+
+ vec_free (data_buf);
svm_fifo_free (f);
vec_free (test_data);
+
return 0;
err:
@@ -437,10 +542,7 @@ tcp_test_fifo2 (vlib_main_t * vm)
vp = fifo_get_validate_pattern (vm, test_data, test_data_len);
/* Create a fifo */
- f = svm_fifo_create (fifo_size);
-
- /* Paint the fifo data vector with -1's */
- memset (f->data, 0xFF, 1 << 20);
+ f = fifo_prepare (fifo_size);
/*
* Try with sorted data
@@ -473,10 +575,7 @@ tcp_test_fifo2 (vlib_main_t * vm)
* Now try it again w/ unsorted data...
*/
- f = svm_fifo_create (fifo_size);
-
- /* Paint fifo data vector with -1's */
- memset (f->data, 0xFF, 1 << 20);
+ f = fifo_prepare (fifo_size);
for (i = 0; i < test_data_len; i++)
{
@@ -516,16 +615,13 @@ tcp_test_fifo3 (vlib_main_t * vm, unformat_input_t * input)
u32 fifo_size = 4 << 10;
u32 fifo_initial_offset = 0;
u32 total_size = 2 << 10;
- int overlap = 0;
- int i, rv;
- u8 *data_pattern = 0;
+ int overlap = 0, verbose = 0, randomize = 1, drop = 0, in_seq_all = 0;
+ u8 *data_pattern = 0, *data_buf = 0;
test_pattern_t *tp, *generate = 0;
- u32 nsegs = 2;
- u32 seg_size, length_so_far;
+ u32 nsegs = 2, seg_size, length_so_far;
u32 current_offset, offset_increment, len_this_chunk;
- u32 seed = 0xdeaddabe;
- int verbose = 0;
- int randomize = 1;
+ u32 seed = 0xdeaddabe, j;
+ int i, rv;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
@@ -545,6 +641,10 @@ tcp_test_fifo3 (vlib_main_t * vm, unformat_input_t * input)
;
else if (unformat (input, "no-randomize"))
randomize = 0;
+ else if (unformat (input, "in-seq-all"))
+ in_seq_all = 1;
+ else if (unformat (input, "drop"))
+ drop = 1;
else
{
clib_error_t *e = clib_error_return
@@ -554,6 +654,18 @@ tcp_test_fifo3 (vlib_main_t * vm, unformat_input_t * input)
}
}
+ if (total_size > fifo_size)
+ {
+ clib_warning ("total_size %d greater than fifo size %d", total_size,
+ fifo_size);
+ return -1;
+ }
+ if (overlap && randomize == 0)
+ {
+ clib_warning ("Can't enqueue in-order with overlap");
+ return -1;
+ }
+
/*
* Generate data
*/
@@ -561,9 +673,12 @@ tcp_test_fifo3 (vlib_main_t * vm, unformat_input_t * input)
for (i = 0; i < vec_len (data_pattern); i++)
data_pattern[i] = i & 0xff;
+ /*
+ * Generate segments
+ */
seg_size = total_size / nsegs;
length_so_far = 0;
- current_offset = 1;
+ current_offset = randomize;
while (length_so_far < total_size)
{
vec_add2 (generate, tp, 1);
@@ -616,51 +731,100 @@ tcp_test_fifo3 (vlib_main_t * vm, unformat_input_t * input)
generate[dst_index] = generate[src_index];
generate[src_index] = tmp[0];
}
- }
-
- if (verbose)
- {
- vlib_cli_output (vm, "randomized data pattern:");
- for (i = 0; i < vec_len (generate); i++)
+ if (verbose)
{
- vlib_cli_output (vm, "[%d] offset %u len %u", i,
- generate[i].offset, generate[i].len);
+ vlib_cli_output (vm, "randomized data pattern:");
+ for (i = 0; i < vec_len (generate); i++)
+ {
+ vlib_cli_output (vm, "[%d] offset %u len %u", i,
+ generate[i].offset, generate[i].len);
+ }
}
}
- /* Create a fifo */
- f = svm_fifo_create (fifo_size);
-
- /* Paint the fifo data vector with -1's */
- memset (f->data, 0xFF, fifo_size);
+ /*
+ * Create a fifo and add segments
+ */
+ f = fifo_prepare (fifo_size);
/* manually set head and tail pointers to validate modular arithmetic */
- f->head = fifo_initial_offset % fifo_size;
- f->tail = fifo_initial_offset % fifo_size;
+ fifo_initial_offset = fifo_initial_offset % fifo_size;
+ f->head = fifo_initial_offset;
+ f->tail = fifo_initial_offset;
for (i = 0; i < vec_len (generate); i++)
{
tp = generate + i;
- rv = svm_fifo_enqueue_with_offset (f, 0, tp->offset, tp->len,
+ rv = svm_fifo_enqueue_with_offset (f, 0, fifo_initial_offset
+ + tp->offset, tp->len,
(u8 *) data_pattern + tp->offset);
}
- /* Expected result: one big fat chunk at offset 1 */
+ /*
+ * Expected result: one big fat chunk at offset 1 if randomize == 1
+ */
if (verbose)
vlib_cli_output (vm, "fifo before missing link: %U",
format_svm_fifo, f, 1 /* verbose */ );
- rv = svm_fifo_enqueue_nowait (f, 0, 1 /* count */ , data_pattern + 0);
+ /*
+ * Add the missing byte if segments were randomized
+ */
+ if (randomize)
+ {
+ u32 bytes_to_enq = 1;
+ if (in_seq_all)
+ bytes_to_enq = total_size;
+ rv = svm_fifo_enqueue_nowait (f, 0, bytes_to_enq, data_pattern + 0);
+
+ if (verbose)
+ vlib_cli_output (vm, "in-order enqueue returned %d", rv);
- if (verbose)
- vlib_cli_output (vm, "in-order enqueue returned %d", rv);
+ TCP_TEST ((rv == total_size), "enqueued %u expected %u", rv,
+ total_size);
+
+ }
+
+ TCP_TEST ((svm_fifo_has_ooo_data (f) == 0), "number of ooo segments %u",
+ svm_fifo_number_ooo_segments (f));
+
+ /*
+ * Test if peeked data is the same as original data
+ */
+ vec_validate (data_buf, vec_len (data_pattern));
+ svm_fifo_peek (f, 0, 0, vec_len (data_pattern), data_buf);
+ if (compare_data (data_buf, data_pattern, 0, vec_len (data_pattern), &j))
+ {
+ TCP_TEST (0, "[%d] peeked %u expected %u", j, data_buf[j],
+ data_pattern[j]);
+ }
+ vec_reset_length (data_buf);
+
+ /*
+ * Dequeue or drop all data
+ */
+ if (drop)
+ {
+ svm_fifo_dequeue_drop (f, 0, vec_len (data_pattern));
+ }
+ else
+ {
+ svm_fifo_dequeue_nowait (f, 0, vec_len (data_pattern), data_buf);
+ if (compare_data
+ (data_buf, data_pattern, 0, vec_len (data_pattern), &j))
+ {
+ TCP_TEST (0, "[%d] dequeued %u expected %u", j, data_buf[j],
+ data_pattern[j]);
+ }
+ }
+
+ TCP_TEST ((svm_fifo_max_dequeue (f) == 0), "fifo has %d bytes",
+ svm_fifo_max_dequeue (f));
- TCP_TEST ((rv == total_size), "retrieved %u expected %u", rv, total_size);
- TCP_TEST ((svm_fifo_number_ooo_segments (f) == 0),
- "number of ooo segments %u", svm_fifo_number_ooo_segments (f));
svm_fifo_free (f);
vec_free (data_pattern);
+ vec_free (data_buf);
return 0;
}
@@ -669,6 +833,7 @@ static int
tcp_test_fifo (vlib_main_t * vm, unformat_input_t * input)
{
int res = 0;
+ char *str;
/* Run all tests */
if (unformat_check_input (input) == UNFORMAT_END_OF_INPUT)
@@ -681,13 +846,35 @@ tcp_test_fifo (vlib_main_t * vm, unformat_input_t * input)
if (res)
return res;
- /* Run a number of fifo3 configs */
- unformat_init_cstring (input, "nsegs 3 overlap seed 123");
+ /*
+ * Run a number of fifo3 configs
+ */
+ str = "nsegs 10 overlap seed 123";
+ unformat_init_cstring (input, str);
+ if (tcp_test_fifo3 (vm, input))
+ return -1;
+ unformat_free (input);
+
+ str = "nsegs 10 overlap seed 123 in-seq-all";
+ unformat_init_cstring (input, str);
+ if (tcp_test_fifo3 (vm, input))
+ return -1;
+ unformat_free (input);
+
+ str = "nsegs 10 overlap seed 123 initial-offset 3917";
+ unformat_init_cstring (input, str);
+ if (tcp_test_fifo3 (vm, input))
+ return -1;
+ unformat_free (input);
+
+ str = "nsegs 10 overlap seed 123 initial-offset 3917 drop";
+ unformat_init_cstring (input, str);
if (tcp_test_fifo3 (vm, input))
return -1;
unformat_free (input);
- unformat_init_cstring (input, "nsegs 10");
+ str = "nsegs 10 seed 123 initial-offset 3917 drop no-randomize";
+ unformat_init_cstring (input, str);
if (tcp_test_fifo3 (vm, input))
return -1;
unformat_free (input);