CLIB_MARCH_FN (svm_fifo_copy_from_chunk, void, svm_fifo_t * f, svm_fifo_chunk_t * c, u32 head_idx, u8 * dst, u32 len, svm_fifo_chunk_t ** last) { u32 n_chunk; ASSERT (head_idx >= c->start_byte && head_idx < c->start_byte + c->length); head_idx -= c->start_byte; n_chunk = c->length - head_idx; if (n_chunk <= len) { u32 to_copy = len; clib_memcpy_fast (dst, &c->data[head_idx], n_chunk); c = c->next; while ((to_copy -= n_chunk)) { n_chunk = clib_min (c->length, to_copy); clib_memcpy_fast (dst + (len - to_copy), &c->data[0], n_chunk); c = c->length <= to_copy ? c->next : c; } if (*last) *last = c; } else { clib_memcpy_fast (dst, &c->data[head_idx], len); } }
CLIB_MARCH_FN (svm_fifo_copy_to_chunk, void, svm_fifo_t * f, svm_fifo_chunk_t * c, u32 tail_idx, const u8 * src, u32 len, svm_fifo_chunk_t ** last) { u32 n_chunk; ASSERT (tail_idx >= c->start_byte && tail_idx < c->start_byte + c->length); tail_idx -= c->start_byte; n_chunk = c->length - tail_idx; if (n_chunk <= len) { u32 to_copy = len; clib_memcpy_fast (&c->data[tail_idx], src, n_chunk); c = c->next; while ((to_copy -= n_chunk)) { n_chunk = clib_min (c->length, to_copy); clib_memcpy_fast (&c->data[0], src + (len - to_copy), n_chunk); c = c->length <= to_copy ? c->next : c; } if (*last) *last = c; } else { clib_memcpy_fast (&c->data[tail_idx], src, len); } }
/* Allocates two pointers of given sizes and random characteristics (alignment, overlapping, relative-position). */ static void get_random_two_pointers (uword size1, uword size2, void ** ptr1, void ** ptr2, void ** to_free1, void ** to_free2) { uword do_align1, do_align2; uword align1, align2; uword overlap, two_less_that_one; uword min; do_align1 = bounded_random_u32 (&g_seed, 0, 1); align1 = (do_align1) ? bounded_random_u32 (&g_seed, 0, MAX_LOG2_ALIGN) : (0); do_align2 = bounded_random_u32 (&g_seed, 0, 1); align2 = (do_align2) ? bounded_random_u32 (&g_seed, 0, MAX_LOG2_ALIGN) : (0); overlap = bounded_random_u32 (&g_seed, 0, 1); two_less_that_one = (overlap) ? bounded_random_u32 (&g_seed, 0, 1) : (0); /* Pick random distance between pointers. */ if (overlap) { min = clib_min (size1, size2); overlap = bounded_random_u32 (&g_seed, 0, (min) ? (min - 1) : (0)); } get_two_pointers (size1, size2, align1, align2, overlap, two_less_that_one, ptr1, ptr2, to_free1, to_free2); VERBOSE3 ("size1 %u, size2 %u, align1 %u, align2 %u, overlap %u, " "two_less_that_one %u\n", size1, size2, align1, align2, overlap, two_less_that_one); VERBOSE3 ("p1 %U (%p)\n", format_u32_binary, *ptr1, *ptr1); VERBOSE3 ("p2 %U (%p)\n", format_u32_binary, *ptr2, *ptr2); }
clib_error_t * pcap_read (pcap_main_t * pm) { clib_error_t * error = 0; int fd, need_swap, n; pcap_file_header_t fh; pcap_packet_header_t ph; fd = open (pm->file_name, O_RDONLY); if (fd < 0) { error = clib_error_return_unix (0, "open `%s'", pm->file_name); goto done; } if (read (fd, &fh, sizeof (fh)) != sizeof (fh)) { error = clib_error_return_unix (0, "read file header `%s'", pm->file_name); goto done; } need_swap = 0; if (fh.magic == 0xd4c3b2a1) { need_swap = 1; #define _(t,f) fh.f = clib_byte_swap_##t (fh.f); foreach_pcap_file_header; #undef _ } if (fh.magic != 0xa1b2c3d4) { error = clib_error_return (0, "bad magic `%s'", pm->file_name); goto done; } pm->min_packet_bytes = 0; pm->max_packet_bytes = 0; while ((n = read (fd, &ph, sizeof (ph))) != 0) { u8 * data; if (need_swap) { #define _(t,f) ph.f = clib_byte_swap_##t (ph.f); foreach_pcap_packet_header; #undef _ } data = vec_new (u8, ph.n_bytes_in_packet); if (read (fd, data, ph.n_packet_bytes_stored_in_file) != ph.n_packet_bytes_stored_in_file) { error = clib_error_return (0, "short read `%s'", pm->file_name); goto done; } if (vec_len (pm->packets_read) == 0) pm->min_packet_bytes = pm->max_packet_bytes = ph.n_bytes_in_packet; else { pm->min_packet_bytes = clib_min (pm->min_packet_bytes, ph.n_bytes_in_packet); pm->max_packet_bytes = clib_max (pm->max_packet_bytes, ph.n_bytes_in_packet); } vec_add1 (pm->packets_read, data); } done: if (fd >= 0) close (fd); return error; }
static clib_error_t * catchup_socket_write_ready (unix_file_t * uf, int is_server) { unix_main_t * um = &unix_main; mc_socket_main_t *msm = (mc_socket_main_t *)uf->private_data; mc_socket_catchup_t *c = find_catchup_from_file_descriptor (msm, uf->file_descriptor); clib_error_t * error = 0; int n; if (c->connect_in_progress) { u32 len, value; c->connect_in_progress = 0; len = sizeof (value); if (getsockopt (c->socket, SOL_SOCKET, SO_ERROR, &value, &len) < 0) { error = clib_error_return_unix (0, "getsockopt SO_ERROR"); goto error_quit; } if (value != 0) { error = clib_error_return_code (0, value, CLIB_ERROR_ERRNO_VALID, "connect fails"); goto error_quit; } } while (1) { u32 n_this_write; n_this_write = clib_min (vec_len (c->output_vector) - c->output_vector_n_written, msm->rx_mtu_n_bytes - 64 /* ip + tcp + option allowance */); if (n_this_write <= 0) break; do { n = write (uf->file_descriptor, c->output_vector + c->output_vector_n_written, n_this_write); } while (n < 0 && errno == EAGAIN); if (n < 0) { error = clib_error_return_unix (0, "write"); goto error_quit; } c->output_vector_n_written += n; } if (c->output_vector_n_written >= vec_len (c->output_vector)) { if (! is_server) { uf->flags &= ~UNIX_FILE_DATA_AVAILABLE_TO_WRITE; unix_main.file_update (uf, UNIX_FILE_UPDATE_MODIFY); /* Send EOF to other side. */ shutdown (uf->file_descriptor, SHUT_WR); return error; } else { error_quit: catchup_cleanup (msm, c, um, uf); } } return error; }
int test_elog_main (unformat_input_t * input) { clib_error_t * error = 0; u32 i, n_iter, seed, max_events; elog_main_t _em, * em = &_em; u32 verbose; f64 min_sample_time; char * dump_file, * load_file, * merge_file, ** merge_files; u8 * tag, ** tags; n_iter = 100; max_events = 100000; seed = 1; verbose = 0; dump_file = 0; load_file = 0; merge_files = 0; tags = 0; min_sample_time = 2; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "iter %d", &n_iter)) ; else if (unformat (input, "seed %d", &seed)) ; else if (unformat (input, "dump %s", &dump_file)) ; else if (unformat (input, "load %s", &load_file)) ; else if (unformat (input, "tag %s", &tag)) vec_add1 (tags, tag); else if (unformat (input, "merge %s", &merge_file)) vec_add1 (merge_files, merge_file); else if (unformat (input, "verbose %=", &verbose, 1)) ; else if (unformat (input, "max-events %d", &max_events)) ; else if (unformat (input, "sample-time %f", &min_sample_time)) ; else { error = clib_error_create ("unknown input `%U'\n", format_unformat_error, input); goto done; } } #ifdef CLIB_UNIX if (load_file) { if ((error = elog_read_file (em, load_file))) goto done; } else if (merge_files) { uword i; elog_main_t * ems; vec_clone (ems, merge_files); elog_init (em, max_events); for (i = 0; i < vec_len (ems); i++) { if ((error = elog_read_file (i == 0 ? em : &ems[i], merge_files[i]))) goto done; if (i > 0) { elog_merge (em, tags[0], &ems[i], tags[i]); tags[0] = 0; } } } else #endif /* CLIB_UNIX */ { f64 t[2]; elog_init (em, max_events); elog_enable_disable (em, 1); t[0] = unix_time_now (); for (i = 0; i < n_iter; i++) { u32 j, n, sum; n = 1 + (random_u32 (&seed) % 128); sum = 0; for (j = 0; j < n; j++) sum += random_u32 (&seed); { ELOG_TYPE_XF (e); ELOG (em, e, sum); } { ELOG_TYPE_XF (e); ELOG (em, e, sum + 1); } { struct { u32 string_index; f32 f; } * d; ELOG_TYPE_DECLARE (e) = { .format = "fumble %s %.9f", .format_args = "t4f4", .n_enum_strings = 4, .enum_strings = { "string0", "string1", "string2", "string3", }, }; d = ELOG_DATA (em, e); d->string_index = sum & 3; d->f = (sum & 0xff) / 128.; } { ELOG_TYPE_DECLARE (e) = { .format = "bar %d.%d.%d.%d", .format_args = "i1i1i1i1", }; ELOG_TRACK (my_track); u8 * d = ELOG_TRACK_DATA (em, e, my_track); d[0] = i + 0; d[1] = i + 1; d[2] = i + 2; d[3] = i + 3; } { ELOG_TYPE_DECLARE (e) = { .format = "bar `%s'", .format_args = "s20", }; struct { char s[20]; } * d; u8 * v; d = ELOG_DATA (em, e); v = format (0, "foo %d%c", i, 0); memcpy (d->s, v, clib_min (vec_len (v), sizeof (d->s))); } { ELOG_TYPE_DECLARE (e) = { .format = "bar `%s'", .format_args = "T4", }; struct { u32 offset; } * d; d = ELOG_DATA (em, e); d->offset = elog_string (em, "string table %d", i); } } do { t[1] = unix_time_now (); } while (t[1] - t[0] < min_sample_time); } #ifdef CLIB_UNIX if (dump_file) { if ((error = elog_write_file (em, dump_file))) goto done; } #endif if (verbose) { elog_event_t * e, * es; es = elog_get_events (em); vec_foreach (e, es) { clib_warning ("%18.9f: %12U %U\n", e->time, format_elog_track, em, e, format_elog_event, em, e); } } done: if (error) clib_error_report (error); return 0; } #ifdef CLIB_UNIX int main (int argc, char * argv []) { unformat_input_t i; int r; unformat_init_command_line (&i, argv); r = test_elog_main (&i); unformat_free (&i); return r; }
uword vlib_error_drop_buffers (vlib_main_t * vm, vlib_node_runtime_t * node, u32 * buffers, u32 next_buffer_stride, u32 n_buffers, u32 next_index, u32 drop_error_node, u32 drop_error_code) { u32 n_left_this_frame, n_buffers_left, *args, n_args_left; vlib_error_t drop_error; drop_error = vlib_error_set (drop_error_node, drop_error_code); n_buffers_left = n_buffers; while (n_buffers_left > 0) { vlib_get_next_frame (vm, node, next_index, args, n_args_left); n_left_this_frame = clib_min (n_buffers_left, n_args_left); n_buffers_left -= n_left_this_frame; n_args_left -= n_left_this_frame; while (n_left_this_frame >= 4) { u32 bi0, bi1, bi2, bi3; vlib_buffer_t *b0, *b1, *b2, *b3; args[0] = bi0 = buffers[0]; args[1] = bi1 = buffers[1]; args[2] = bi2 = buffers[2]; args[3] = bi3 = buffers[3]; b0 = vlib_get_buffer (vm, bi0); b1 = vlib_get_buffer (vm, bi1); b2 = vlib_get_buffer (vm, bi2); b3 = vlib_get_buffer (vm, bi3); b0->error = drop_error; b1->error = drop_error; b2->error = drop_error; b3->error = drop_error; buffers += 4; args += 4; n_left_this_frame -= 4; } while (n_left_this_frame >= 1) { u32 bi0; vlib_buffer_t *b0; args[0] = bi0 = buffers[0]; b0 = vlib_get_buffer (vm, bi0); b0->error = drop_error; buffers += 1; args += 1; n_left_this_frame -= 1; } vlib_put_next_frame (vm, node, next_index, n_args_left); } return n_buffers; }