36 session->session_index = session - em->
sessions;
60 CHECK_SAME (ECHO_FAIL_TEST_ASSERT_ALL_SESSIONS_CLOSED,
62 "Some sessions are still open");
75 ECHO_FAIL (ECHO_FAIL_SEND_IO_EVT,
"app_send_io_evt_to_vpp errored %d",
98 ECHO_FAIL (ECHO_FAIL_SOCKET_CONNECT,
"socket connect failed");
104 ECHO_FAIL (ECHO_FAIL_INIT_SHM_API,
"init shm api failed");
112 ECHO_FAIL (ECHO_FAIL_SHMEM_CONNECT,
"shmem connect failed");
131 f64 deltat = start_evt_missing || end_evt_missing ? 0 :
134 if (start_evt_missing)
135 ECHO_FAIL (ECHO_FAIL_MISSING_START_EVENT,
136 "Expected event %v to happen, but it did not!", start_evt);
140 "Expected event %v to happen, but it did not!", end_evt);
142 fformat (stdout,
"vpp_echo JSON stats:\n{\n");
143 fformat (stdout,
" \"role\": \"%s\",\n",
145 fformat (stdout,
" \"time\": \"%.9f\",\n", deltat);
146 fformat (stdout,
" \"start_evt\": \"%v\",\n", start_evt);
147 fformat (stdout,
" \"start_evt_missing\": \"%s\",\n",
148 start_evt_missing ?
"True" :
"False");
149 fformat (stdout,
" \"end_evt\": \"%v\",\n", end_evt);
150 fformat (stdout,
" \"end_evt_missing\": \"%s\",\n",
151 end_evt_missing ?
"True" :
"False");
154 fformat (stdout,
" \"rx_bits_per_second\": %.1f,\n",
156 fformat (stdout,
" \"tx_bits_per_second\": %.1f,\n",
158 fformat (stdout,
" \"closing\": {\n");
159 fformat (stdout,
" \"reset\": { \"q\": %d, \"s\": %d },\n",
161 fformat (stdout,
" \"recv evt\": { \"q\": %d, \"s\": %d },\n",
163 fformat (stdout,
" \"send evt\": { \"q\": %d, \"s\": %d },\n",
165 fformat (stdout,
" \"clean\": { \"q\": %d, \"s\": %d },\n",
167 fformat (stdout,
" \"accepted\": { \"q\": %d, \"s\": %d },\n",
169 fformat (stdout,
" \"connected\": { \"q\": %d, \"s\": %d }\n",
172 fformat (stdout,
" \"results\": {\n");
192 f64 deltat = start_evt_missing || end_evt_missing ? 0 :
195 if (start_evt_missing)
196 ECHO_FAIL (ECHO_FAIL_MISSING_START_EVENT,
197 "Expected event %v to happen, but it did not!", start_evt);
201 "Expected event %v to happen, but it did not!", end_evt);
203 fformat (stdout,
"Timing %v:%v\n", start_evt, end_evt);
204 if (start_evt_missing)
205 fformat (stdout,
"Missing Start Timing Event (%v)!\n", start_evt);
207 fformat (stdout,
"Missing End Timing Event (%v)!\n", end_evt);
208 fformat (stdout,
"-------- TX --------\n");
209 fformat (stdout,
"%lld bytes (%lld mbytes, %lld gbytes) in %.6f seconds\n",
213 fformat (stdout,
"%.4f Gbit/second\n",
215 fformat (stdout,
"-------- RX --------\n");
216 fformat (stdout,
"%lld bytes (%lld mbytes, %lld gbytes) in %.6f seconds\n",
220 fformat (stdout,
"%.4f Gbit/second\n",
222 fformat (stdout,
"--------------------\n");
223 fformat (stdout,
"Received close on %d streams (and %d Quic conn)\n",
225 fformat (stdout,
"Received reset on %d streams (and %d Quic conn)\n",
227 fformat (stdout,
"Sent close on %d streams (and %d Quic conn)\n",
229 fformat (stdout,
"Discarded %d streams (and %d Quic conn)\n",
231 fformat (stdout,
"--------------------\n");
232 fformat (stdout,
"Got accept on %d streams (and %d Quic conn)\n",
234 fformat (stdout,
"Got connected on %d streams (and %d Quic conn)\n",
247 ECHO_LOG (2,
"[%lu/%lu] -> %U -> [%lu/%lu]",
263 u32 *session_indexes = 0, *session_index;
268 if (s->session_state == ECHO_SESSION_STATE_CLOSED)
269 vec_add1 (session_indexes, s->session_index);}
289 for (i = 0; i < n_read; i++)
294 ECHO_LOG (1,
"Session 0x%lx byte %lld was 0x%x expected 0x%x",
299 ECHO_LOG (1,
"Too many errors, hiding next ones");
301 ECHO_FAIL (ECHO_FAIL_TEST_BYTES_ERR,
"test-bytes errored");
318 s->bytes_received += n_read;
319 s->bytes_to_receive -= n_read;
331 if (!bytes_this_chunk)
337 s->bytes_to_send -= n_sent;
338 s->bytes_sent += n_sent;
347 while (n_sent < len && !em->time_to_stop)
359 ECHO_LOG (3,
"%U: listener_index == SESSION_INVALID_INDEX",
366 ECHO_LOG (3,
"%U: ls->session_state (%d) < " 367 "ECHO_SESSION_STATE_CLOSING (%d)",
385 int n_read, n_sent = 0;
422 if (n_sent || n_read)
429 ECHO_LOG (2,
"Idle FIFOs TX:%dB RX:%dB",
448 ECHO_LOG (2,
"Thread %u exiting, no sessions to care for", idx);
454 u32 n_closed_sessions = 0;
460 for (i = 0; !em->
time_to_stop; i = (i + 1) % thread_n_sessions)
462 n_closed_sessions = i == 0 ? 0 : n_closed_sessions;
467 switch (s->session_state)
491 if (n_closed_sessions == thread_n_sessions)
494 ECHO_LOG (2,
"Mission accomplished!");
521 clib_net_to_host_u32 (mp->
retval));
526 clib_net_to_host_u16 (mp->
lcl_port));
544 uword *segment_present;
545 ECHO_LOG (3,
"Check if segment mapped 0x%lx...", segment_handle);
549 if (segment_present != 0)
551 ECHO_LOG (2,
"Segment not mapped (0x%lx)", segment_handle);
566 ECHO_FAIL (ECHO_FAIL_SESSION_ACCEPTED_BAD_LISTENER,
572 ECHO_FAIL (ECHO_FAIL_ACCEPTED_WAIT_FOR_SEG_ALLOC,
573 "accepted wait_for_segment_allocation errored");
582 rx_fifo->client_session_index = session->session_index;
584 tx_fifo->client_session_index = session->session_index;
586 session->rx_fifo = rx_fifo;
587 session->tx_fifo = tx_fifo;
591 sizeof (ip46_address_t));
592 session->transport.is_ip4 = mp->
rmt.is_ip4;
593 session->transport.rmt_port = mp->
rmt.port;
595 sizeof (ip46_address_t));
605 ECHO_LOG (2,
"Accepted session 0x%lx S[%u] -> 0x%lx S[%u]",
606 mp->
handle, session->session_index,
641 ECHO_FAIL (ECHO_FAIL_CONNECTED_WAIT_FOR_SEG_ALLOC,
642 "connected wait_for_segment_allocation errored");
647 rx_fifo->client_session_index = session->session_index;
649 tx_fifo->client_session_index = session->session_index;
651 session->rx_fifo = rx_fifo;
652 session->tx_fifo = tx_fifo;
660 sizeof (ip46_address_t));
661 session->transport.is_ip4 = mp->
lcl.is_ip4;
662 session->transport.lcl_port = mp->
lcl.port;
664 sizeof (ip46_address_t));
669 session->session_index, 0 );
692 ECHO_LOG (2,
"%U: already in ECHO_SESSION_STATE_CLOSED",
742 if (mp->
fd_flags & SESSION_FD_F_MEMFD_SEGMENT)
748 "vl_socket_client_recv_fd_msg failed");
754 ECHO_FAIL (ECHO_FAIL_VL_API_SVM_FIFO_SEG_ATTACH,
755 "svm_fifo_segment_attach ('%s') " 756 "failed on SSVM_SEGMENT_MEMFD", seg_name);
769 ECHO_FAIL (ECHO_FAIL_VL_API_FIFO_SEG_ATTACH,
770 "fifo_segment_attach ('%s') failed", seg_name);
775 ECHO_LOG (2,
"Mapped segment 0x%lx", segment_handle);
801 switch (e->event_type)
829 ECHO_LOG (1,
"unhandled event %u", e->event_type);
863 if (delta < em->periodic_stats_delta)
901 ECHO_FAIL (ECHO_FAIL_APP_ATTACH,
"Application failed to attach");
923 for (i = 0; i <
vec_len (msg_vec); i++)
949 while (ipu8[l] == 0xf)
982 ip46_address_t _ip, *
ip = &_ip;
983 u32 *listen_session_index;
986 for (i = 0; i < em->
n_uris; i++)
1003 ECHO_FAIL (ECHO_FAIL_SERVER_DISCONNECT_TIMEOUT,
1004 "Timeout waiting for state disconnected");
1015 "Usage: vpp_echo [socket-name SOCKET] [client|server] [uri URI] [OPTIONS]\n" 1016 "Generates traffic and assert correct teardown of the hoststack\n" 1018 " socket-name PATH Specify the binary socket path to connect to VPP\n" 1019 " use-svm-api Use SVM API to connect to VPP\n" 1020 " test-bytes[:assert] Check data correctness when receiving (assert fails on first error)\n" 1021 " fifo-size N[K|M|G] Use N[K|M|G] fifos\n" 1022 " mq-size N Use mq with N slots for [vpp_echo->vpp] communication\n" 1023 " max-sim-connects N Do not allow more than N mq events inflight\n" 1024 " rx-buf N[K|M|G] Use N[Kb|Mb|GB] RX buffer\n" 1025 " tx-buf N[K|M|G] Use N[Kb|Mb|GB] TX test buffer\n" 1026 " appns NAMESPACE Use the namespace NAMESPACE\n" 1027 " all-scope all-scope option\n" 1028 " local-scope local-scope option\n" 1029 " global-scope global-scope option\n" 1030 " secret SECRET set namespace secret\n" 1031 " chroot prefix PATH Use PATH as memory root path\n" 1032 " sclose=[Y|N|W] When stream is done, send[Y]|nop[N]|wait[W] for close\n" 1033 " nuris N Cycle through N consecutive (src&dst) ips when creating connections\n" 1034 " lcl IP Set the local ip to use as a client (use with nuris to set first src ip)\n" 1036 " time START:END Time between evts START & END, events being :\n" 1037 " start - Start of the app\n" 1038 " qconnect - first Connection connect sent\n" 1039 " qconnected - last Connection connected\n" 1040 " sconnect - first Stream connect sent\n" 1041 " sconnected - last Stream got connected\n" 1042 " lastbyte - Last expected byte received\n" 1043 " exit - Exiting of the app\n" 1044 " rx-results-diff Rx results different to pass test\n" 1045 " tx-results-diff Tx results different to pass test\n" 1046 " json Output global stats in json\n" 1047 " stats N Output stats evry N secs\n" 1048 " log=N Set the log level to [0: no output, 1:errors, 2:log]\n" 1049 " crypto [engine] Set the crypto engine [openssl, vpp, picotls, mbedtls]\n" 1051 " nclients N Open N clients sending data\n" 1052 " nthreads N Use N busy loop threads for data [in addition to main & msg queue]\n" 1053 " TX=1337[K|M|G]|RX Send 1337 [K|M|G]bytes, use TX=RX to reflect the data\n" 1054 " RX=1337[K|M|G] Expect 1337 [K|M|G]bytes\n" "\n");
1061 fprintf (stderr,
"\nDefault configuration is :\n" 1062 " server nclients 1 [quic-streams 1] RX=64Kb TX=RX\n" 1063 " client nclients 1 [quic-streams 1] RX=64Kb TX=64Kb\n");
1064 exit (ECHO_FAIL_USAGE);
1101 u8 default_f_active;
1109 else if (
unformat (a,
"chroot prefix %s", &chroot_prefix))
1111 else if (
unformat (a,
"uri %s", &uri))
1121 else if (
unformat (a,
"test-bytes:assert"))
1123 else if (
unformat (a,
"test-bytes"))
1127 else if (
unformat (a,
"use-svm-api"))
1131 if (tmp >= 0x100000000ULL)
1134 "ERROR: fifo-size %ld (0x%lx) too large\n", tmp, tmp);
1160 else if (
unformat (a,
"all-scope"))
1161 em->
appns_flags |= (APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE
1162 | APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE);
1163 else if (
unformat (a,
"local-scope"))
1164 em->
appns_flags = APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
1165 else if (
unformat (a,
"global-scope"))
1166 em->
appns_flags = APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
1176 else if (
unformat (a,
"rx-results-diff"))
1178 else if (
unformat (a,
"tx-results-diff"))
1184 else if (
unformat (a,
"wait-for-gdb"))
1191 else if (
unformat (a,
"time %U:%U",
1234 volatile u64 nop = 0;
1261 ECHO_FAIL (ECHO_FAIL_INVALID_URI,
"Unable to process uri");
1266 static void __clib_constructor
1283 u32 rpc_queue_size = 256 << 10;
1311 em->
uri =
format (0,
"%s%c",
"tcp://0.0.0.0/1234", 0);
1322 ECHO_FAIL (ECHO_FAIL_PROTOCOL_NOT_SUPPORTED,
1323 "Protocol %U is not supported",
1349 cfg->consumer_pid = getpid ();
1351 cfg->q_nitems = rpc_queue_size;
1352 cfg->ring_cfgs = rc;
1360 app_name = em->i_am_master ?
"echo_server" :
"echo_client";
1364 ECHO_FAIL (ECHO_FAIL_CONNECT_TO_VPP,
"Couldn't connect to vpp");
1375 "Couldn't attach to vpp, did you run <session enable> ?");
1379 if (em->uri_elts.transport_proto != TRANSPORT_PROTO_QUIC
1380 && em->uri_elts.transport_proto != TRANSPORT_PROTO_TLS)
1390 "Couldn't add crypto context to vpp\n");
1395 if (pthread_create (&em->mq_thread_handle,
1398 ECHO_FAIL (ECHO_FAIL_PTHREAD_CREATE,
"pthread create errored");
1402 for (
i = 0;
i < em->n_rx_threads;
i++)
1403 if (pthread_create (&em->data_thread_handles[
i],
1407 "pthread create errored (index %d)",
i);
1410 if (em->i_am_master)
1419 ECHO_FAIL (ECHO_FAIL_DEL_CERT_KEY,
"Couldn't cleanup cert and key");
1426 ECHO_FAIL (ECHO_FAIL_DETACH,
"Couldn't detach from vpp");
1430 pthread_join (em->mq_thread_handle, (
void **) &rv);
1433 ECHO_FAIL (ECHO_FAIL_MQ_PTHREAD,
"mq pthread errored %d", rv);
1436 if (em->use_sock_api)
1443 if (em->output_json)
1448 vec_free (em->available_proto_cb_vft);
1449 exit (em->has_failed);
volatile u32 listen_session_cnt
echo_proto_cb_vft_t ** available_proto_cb_vft
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
static void echo_session_prealloc(echo_main_t *em)
#define CHECK_SAME(fail, expected, result, _fmt, _args...)
echo_stats_t last_stat_sampling
void * svm_msg_q_msg_data(svm_msg_q_t *mq, svm_msg_q_msg_t *msg)
Get data for message in queue.
teardown_stat_t clean_count
static_always_inline void clib_spinlock_unlock(clib_spinlock_t *p)
int vl_socket_client_init_shm(vl_api_shm_elem_config_t *config, int want_pthread)
static_always_inline void clib_spinlock_lock(clib_spinlock_t *p)
u8 * echo_format_timing_event(u8 *s, va_list *args)
int vl_client_connect_to_vlib(const char *svm_name, const char *client_name, int rx_queue_size)
u8 * echo_format_session(u8 *s, va_list *args)
#define clib_atomic_add_fetch(a, b)
echo_session_t * sessions
static void * echo_mq_thread_fn(void *arg)
clib_spinlock_t sid_vpp_handles_lock
static int echo_process_each_proto_opts(unformat_input_t *a)
static void echo_print_periodic_stats(echo_main_t *em)
void echo_send_del_cert_key(echo_main_t *em)
u8 use_sock_api
Flag that decides if socket, instead of svm, api is used to connect to vpp.
svm_queue_t * vl_input_queue
uword vpp_event_queue_address
int my_client_index
All VLIB-side message handlers use my_client_index to identify the queue / client.
#define clib_memcpy_fast(a, b, c)
static void echo_session_dequeue_notify(echo_session_t *s)
static void test_recv_bytes(echo_main_t *em, echo_session_t *s, u8 *rx_buf, u32 n_read)
static u8 * format_api_error(u8 *s, va_list *args)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
void echo_send_add_cert_key(echo_main_t *em)
void echo_process_uri(echo_main_t *em)
static int echo_segment_is_not_mapped(u64 segment_handle)
static f64 clib_time_now(clib_time_t *c)
static int mirror_data_chunk(echo_main_t *em, echo_session_t *s, u8 *tx_buf, u64 len)
uword echo_unformat_timing_event(unformat_input_t *input, va_list *args)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
static u8 svm_msg_q_is_empty(svm_msg_q_t *mq)
Check if message queue is empty.
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
static void print_global_json_stats(echo_main_t *em)
int vl_socket_client_connect(char *socket_path, char *client_name, u32 socket_buffer_size)
volatile connection_state_t state
uword echo_unformat_crypto_engine(unformat_input_t *input, va_list *args)
void(* reset_cb)(session_reset_msg_t *mp, echo_session_t *s)
volatile int max_sim_connects
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
static void echo_free_sessions(echo_main_t *em)
int wait_for_state_change(echo_main_t *em, connection_state_t state, f64 timeout)
static void session_accepted_handler(session_accepted_msg_t *mp)
foreach_app_session_field u64 vpp_session_handle
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
static void handle_mq_event(session_event_t *e)
void(* connected_cb)(session_connected_bundled_msg_t *mp, u32 session_index, u8 is_failed)
static void echo_check_closed_listener(echo_main_t *em, echo_session_t *s)
static void session_reset_handler(session_reset_msg_t *mp)
u8 * echo_format_session_state(u8 *s, va_list *args)
static void del_segment_handler(session_app_del_segment_msg_t *mp)
static void echo_process_rpcs(echo_main_t *em)
void svm_region_exit(void)
static void app_alloc_ctrl_evt_to_vpp(svm_msg_q_t *mq, app_session_evt_t *app_evt, u8 evt_type)
static int app_send(app_session_t *s, u8 *data, u32 len, u8 noblock)
void echo_send_attach(echo_main_t *em)
echo_session_t * echo_session_new(echo_main_t *em)
static void clib_mem_set_thread_index(void)
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
svm_msg_q_t * svm_msg_q_alloc(svm_msg_q_cfg_t *cfg)
Allocate message queue.
volatile u64 bytes_received
void echo_session_handle_add_del(echo_main_t *em, u64 handle, u32 sid)
static u32 svm_fifo_max_dequeue(svm_fifo_t *f)
Fifo max bytes to dequeue.
int main(int argc, char **argv)
static void clients_run(echo_main_t *em)
void echo_send_unbind(echo_main_t *em, echo_session_t *s)
static int app_send_io_evt_to_vpp(svm_msg_q_t *mq, u32 session_index, u8 evt_type, u8 noblock)
Send fifo io event to vpp worker thread.
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
clib_spinlock_t segment_handles_lock
void echo_send_disconnect_session(echo_main_t *em, void *args)
struct vl_shmem_hdr_ * shmem_hdr
Binary API shared-memory segment header pointer.
#define ECHO_FAIL(fail, _fmt, _args...)
#define SESSION_INVALID_HANDLE
char * segment_name
segment name
void(* echo_rpc_t)(echo_main_t *em, echo_rpc_args_t *arg)
static void clib_spinlock_init(clib_spinlock_t *p)
int fifo_segment_attach(fifo_segment_main_t *sm, fifo_segment_create_args_t *a)
Attach as slave to a fifo segment.
void vl_set_memory_root_path(const char *name)
static int app_recv(app_session_t *s, u8 *data, u32 len)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
void(* accepted_cb)(session_accepted_msg_t *mp, echo_session_t *session)
void(* cleanup_cb)(echo_session_t *s, u8 parent_died)
u8 * echo_format_bytes_per_sec(u8 *s, va_list *args)
teardown_stat_t accepted_count
#define pool_put(P, E)
Free an object E in pool P.
void echo_api_hookup(echo_main_t *em)
#define SESSION_INVALID_INDEX
uword vpp_event_queue_address
static void cleanup_handler(session_cleanup_msg_t *mp)
fifo_segment_main_t segment_main
void clib_time_init(clib_time_t *c)
void(* bound_uri_cb)(session_bound_msg_t *mp, echo_session_t *session)
data_source_t data_source
static void server_run(echo_main_t *em)
API main structure, used by both vpp and binary API clients.
format_function_t format_ip46_address
#define CHECK_DIFF(fail, expected, result, _fmt, _args...)
static void __clib_constructor vpp_echo_init()
static void app_send_ctrl_evt_to_vpp(svm_msg_q_t *mq, app_session_evt_t *app_evt)
u32 segment_size
size of the segment
static u8 svm_fifo_set_event(svm_fifo_t *f)
Set fifo event flag.
static void print_global_stats(echo_main_t *em)
int connect_to_vpp(char *name)
clib_error_t * vl_socket_client_recv_fd_msg(int fds[], int n_fds, u32 wait)
static u8 svm_fifo_needs_deq_ntf(svm_fifo_t *f, u32 n_last_deq)
Check if fifo needs dequeue notification.
void vl_socket_client_disconnect(void)
static void svm_msg_q_unlock(svm_msg_q_t *mq)
Unlock message queue.
static int svm_msg_q_timedwait(svm_msg_q_t *mq, double timeout)
Timed wait for message queue event.
sll srl srl sll sra u16x4 i
#define vec_free(V)
Free vector's memory (no header).
void fifo_segment_main_init(fifo_segment_main_t *sm, u64 baseva, u32 timeout_in_seconds)
uword * shared_segment_handles
#define clib_warning(format, args...)
#define ECHO_LOG(lvl, _fmt, _args...)
#define LOG_EVERY_N_IDLE_CYCLES
void echo_notify_event(echo_main_t *em, echo_test_evt_t e)
u32 *volatile data_thread_args
static void add_segment_handler(session_app_add_segment_msg_t *mp)
#define HIGH_SEGMENT_BASEVA
blocking call - best used in combination with condvars, for eventfds we don't yield the cpu ...
static void echo_handle_data(echo_main_t *em, echo_session_t *s, u8 *rx_buf)
svm_queue_t * vl_input_queue
u64 parent_session_handle
int echo_send_rpc(echo_main_t *em, void *fp, echo_rpc_args_t *args)
struct echo_main_t::@665 uri_elts
#define hash_create(elts, value_bytes)
#define uword_to_pointer(u, type)
static void print_usage_and_exit(void)
static uword hash_elts(void *v)
uword unformat_transport_proto(unformat_input_t *input, va_list *args)
static void session_bound_handler(session_bound_msg_t *mp)
void echo_segment_handle_add_del(echo_main_t *em, u64 segment_handle, u8 add)
static void echo_cycle_ip(echo_main_t *em, ip46_address_t *ip, ip46_address_t *src_ip, u32 i)
static void svm_fifo_clear_deq_ntf(svm_fifo_t *f)
Clear the want notification flag and set has notification.
echo_session_t * echo_get_session_from_handle(echo_main_t *em, u64 handle)
static void init_error_string_table(vat_main_t *vam)
teardown_stat_t close_count
void echo_update_count_on_session_close(echo_main_t *em, echo_session_t *s)
static void * echo_data_thread_fn(void *arg)
void(* set_defaults_before_opts_cb)(void)
#define clib_atomic_fetch_add(a, b)
static void echo_set_each_proto_defaults_before_opts(echo_main_t *em)
void echo_send_detach(echo_main_t *em)
int echo_ssvm_segment_attach(char *name, ssvm_segment_type_t type, int fd)
template key/value backing page structure
static void session_unlisten_handler(session_unlisten_reply_msg_t *mp)
void svm_msg_q_free_msg(svm_msg_q_t *mq, svm_msg_q_msg_t *msg)
Free message buffer.
static int recv_data_chunk(echo_main_t *em, echo_session_t *s, u8 *rx_buf)
volatile u64 bytes_to_receive
struct echo_main_t::@664 timing
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
void echo_process_opts(int argc, char **argv)
teardown_stat_t active_count
void(* print_usage_cb)(void)
void(* set_defaults_after_opts_cb)(void)
u32 * listen_session_indexes
uword * session_index_by_vpp_handles
static void echo_assert_test_suceeded(echo_main_t *em)
svm_msg_q_t * rpc_msq_queue
static void session_disconnected_handler(session_disconnected_msg_t *mp)
static api_main_t * vlibapi_get_main(void)
void vl_client_disconnect_from_vlib(void)
static u32 svm_msg_q_size(svm_msg_q_t *mq)
Check length of message queue.
echo_proto_cb_vft_t * proto_cb_vft
#define vec_foreach(var, vec)
Vector iterator.
void echo_send_listen(echo_main_t *em, ip46_address_t *ip)
teardown_stat_t connected_count
pthread_t * data_thread_handles
int(* process_opts_cb)(unformat_input_t *a)
f64 last_stat_sampling_ts
static int send_data_chunk(echo_session_t *s, u8 *tx_buf, int offset, int len)
void echo_send_connect(echo_main_t *em, void *args)
void * clib_mem_init_thread_safe(void *memory, uword memory_size)
static int svm_msg_q_lock(svm_msg_q_t *mq)
Lock, or block trying, the message queue.
static void session_connected_handler(session_connected_msg_t *mp)
struct _svm_fifo svm_fifo_t
u8 * echo_format_crypto_engine(u8 *s, va_list *args)
teardown_stat_t reset_count
u8 * format_transport_proto(u8 *s, va_list *args)
u8 send_stream_disconnects
uword echo_unformat_close(unformat_input_t *input, va_list *args)
void(* disconnected_cb)(session_disconnected_msg_t *mp, echo_session_t *s)
void svm_msg_q_sub_w_lock(svm_msg_q_t *mq, svm_msg_q_msg_t *msg)
Consumer dequeue one message from queue with mutex held.
static void stop_signal(int signum)