|
FD.io VPP
v21.10.1-2-g0a485f517
Vector Packet Processing
|
Go to the documentation of this file.
18 #include <sys/types.h>
19 #include <sys/socket.h>
27 #include <sys/epoll.h>
57 struct sockaddr_storage servaddr;
72 size_t new_size =
wrk->conn_pool_size + expand_size;
75 conn_pool =
realloc (
wrk->conn_pool, new_size * sizeof (*
wrk->conn_pool));
78 for (
i =
wrk->conn_pool_size;
i < new_size;
i++)
81 memset (conn, 0,
sizeof (*conn));
84 wrk->conn_pool = conn_pool;
85 wrk->conn_pool_size = new_size;
89 vterr (
"conn_pool_expand()", -errno);
100 for (
i = 0;
i <
wrk->conn_pool_size;
i++)
102 if (!
wrk->conn_pool[
i].is_alloc)
104 conn = &
wrk->conn_pool[
i];
105 memset (conn, 0,
sizeof (*conn));
110 return (&
wrk->conn_pool[
i]);
120 vtwrn (
"Failed to allocate connection even after expand");
142 vtinf (
"(fd %d): Replying to cfg message!\n", conn->
fd);
160 vppcom_session_close (conn->
fd);
177 for (
i = 0;
i <
wrk->conn_pool_size;
i++)
179 conn = &
wrk->conn_pool[
i];
197 struct timespec stop;
198 clock_gettime (CLOCK_REALTIME, &stop);
203 vtinf (
"%u sessions are still open",
wrk->nfds - 1);
209 for (
i = 0;
i <
wrk->conn_pool_size;
i++)
211 tc = &
wrk->conn_pool[
i];
228 snprintf (
buf,
sizeof (
buf),
"SERVER (fd %d) RESULTS", conn->
fd);
245 memset (&conn->
stats, 0, sizeof (conn->
stats));
250 vtinf (
"Set control fd %d for test!", conn->
fd);
255 vtinf (
"Starting %s-directional Stream Test (fd %d)!",
256 is_bi ?
"Bi" :
"Uni", conn->
fd);
261 memset (&conn->
stats, 0, sizeof (conn->
stats));
262 clock_gettime (CLOCK_REALTIME, &conn->
stats.
start);
284 vppcom_session_free_segments (conn->
fd, rx_bytes);
287 clock_gettime (CLOCK_REALTIME, &conn->
stats.
stop);
293 int tx_bytes, nbytes, pos;
297 ((
char *) conn->
rxbuf)[pos] = 0;
298 vtinf (
"(fd %d): RX (%d bytes) - '%s'", conn->
fd, rx_bytes, conn->
rxbuf);
301 vtinf (
"(fd %d): Echoing back", conn->
fd);
303 nbytes = strlen ((
const char *) conn->
rxbuf) + 1;
304 tx_bytes = conn->
write (conn, conn->
rxbuf, nbytes);
306 vtinf (
"(fd %d): TX (%d bytes) - '%s'", conn->
fd, tx_bytes, conn->
rxbuf);
315 struct epoll_event ev;
321 vtwrn (
"No free connections!");
331 if (tp->
accept (listen_fd, conn))
334 vtinf (
"CTRL accepted fd = %d (0x%08x) on listener fd = %d (0x%08x)",
335 conn->
fd, conn->
fd, listen_fd, listen_fd);
337 ev.events = EPOLLET | EPOLLIN;
338 ev.data.u64 = conn -
wrk->conn_pool;
339 rv = vppcom_epoll_ctl (
wrk->epfd, EPOLL_CTL_ADD, conn->
fd, &ev);
342 vterr (
"vppcom_epoll_ctl()",
rv);
357 struct epoll_event ev;
363 vtwrn (
"No free connections!");
373 if (tp->
accept (listen_fd, conn))
376 vtinf (
"Got a connection -- fd = %d (0x%08x) on listener fd = %d (0x%08x)",
377 conn->
fd, conn->
fd, listen_fd, listen_fd);
379 ev.events = EPOLLET | EPOLLIN;
380 ev.data.u64 = conn -
wrk->conn_pool;
381 rv = vppcom_epoll_ctl (
wrk->epfd, EPOLL_CTL_ADD, conn->
fd, &ev);
384 vterr (
"vppcom_epoll_ctl()",
rv);
395 fprintf (stderr,
"vcl_test_server [OPTIONS] <port>\n"
397 " -h Print this message and exit.\n"
399 " -w <num> Number of workers\n"
400 " -p <PROTO> Use <PROTO> transport layer\n"
401 " -D Use UDP transport layer\n"
402 " -L Use TLS transport layer\n"
403 " -S Incremental stats\n");
410 struct sockaddr_storage *servaddr = &vsm->
servaddr;
411 memset (servaddr, 0,
sizeof (*servaddr));
415 struct sockaddr_in6 *server_addr = (
struct sockaddr_in6 *) servaddr;
416 server_addr->sin6_family = AF_INET6;
417 server_addr->sin6_addr = in6addr_any;
422 struct sockaddr_in *server_addr = (
struct sockaddr_in *) servaddr;
423 server_addr->sin_family = AF_INET;
424 server_addr->sin_addr.s_addr = htonl (INADDR_ANY);
430 struct sockaddr_in6 *server_addr = (
struct sockaddr_in6 *) servaddr;
437 struct sockaddr_in *server_addr = (
struct sockaddr_in *) servaddr;
453 while ((
c = getopt (argc, argv,
"6DLsw:hp:S")) != -1)
462 vtwrn (
"Invalid vppcom protocol %s, defaulting to TCP", optarg);
478 vtwrn (
"Invalid number of workers %d", v);
491 vtwrn (
"Option `-%c' requires an argument.", optopt);
494 if (isprint (optopt))
495 vtwrn (
"Unknown option `-%c'.", optopt);
497 vtwrn (
"Unknown option character `\\x%x'.", optopt);
505 if (argc < (optind + 1))
507 fprintf (stderr,
"SERVER: ERROR: Insufficient number of arguments!\n");
511 if (sscanf (argv[optind],
"%d", &v) == 1)
515 fprintf (stderr,
"SERVER: ERROR: Invalid port (%s)!\n", argv[optind]);
528 vtinf (
"(fd %d): Received a cfg msg!", conn->
fd);
532 if (rx_bytes !=
sizeof (*rx_cfg))
534 vtinf (
"(fd %d): Invalid cfg msg size %d expected %lu!", conn->
fd,
535 rx_bytes, sizeof (*rx_cfg));
540 vtinf (
"(fd %d): Replying to cfg msg", conn->
fd);
543 conn->
write (conn, &conn->
cfg, sizeof (conn->
cfg));
547 switch (rx_cfg->
test)
560 vtinf (
"Ctrl session fd %d closing!", conn->
fd);
568 vtwrn (
"Unknown test type %d", rx_cfg->
test);
582 struct epoll_event listen_ev;
585 __wrk_index =
wrk->wrk_index;
587 vtinf (
"Initializing worker ...");
591 if (vppcom_worker_register ())
592 vtfail (
"vppcom_worker_register()", 1);
601 wrk->epfd = vppcom_epoll_create ();
603 vtfail (
"vppcom_epoll_create()",
wrk->epfd);
606 listen_ev.events = EPOLLET | EPOLLIN;
609 vppcom_epoll_ctl (
wrk->epfd, EPOLL_CTL_ADD,
wrk->listener.fd, &listen_ev);
614 vtinf (
"Waiting for client data connections on port %d ...",
635 clock_gettime (CLOCK_REALTIME, &ts->
stats.
stop);
650 int i, rx_bytes, num_ev;
663 vterr (
"vppcom_epoll_wait()", num_ev);
666 else if (num_ev == 0)
670 for (
i = 0;
i < num_ev;
i++)
672 conn = &
wrk->conn_pool[ep_evts[
i].data.u32];
676 if (ep_evts[
i].
events & (EPOLLHUP | EPOLLRDHUP))
682 vtinf (
"All client connections closed\n");
696 vtwrn (
"ctrl already exists");
705 conn->
cfg = vsm->ctrl->cfg;
708 else if (vppcom_session_is_connectable_listener (conn->
fd))
718 if (!
wrk->wrk_index && conn->
fd == vsm->ctrl->fd)
727 vtinf (
"All client connections closed\n");
731 else if (isascii (conn->
rxbuf[0]))
737 vtwrn (
"FIFO not drained! extra bytes %d", rx_bytes);
746 if (EPOLLIN & ep_evts[
i].
events)
753 if (errno == ECONNRESET)
755 vtinf (
"Connection reset by remote peer.\n");
762 if (vppcom_session_attr (conn->
fd, VPPCOM_ATTR_GET_NREAD, 0, 0) >
765 if (vsm->incremental_stats)
771 vtwrn (
"Unhandled event");
778 vsm->worker_fails -= 1;
781 vppcom_session_close (
wrk->listener.fd);
784 vsm->active_workers -= 1;
792 struct epoll_event listen_ev;
795 vtinf (
"Initializing main ctrl session ...");
798 vppcom_session_create (VPPCOM_PROTO_TCP, 0 );
804 vtfail (
"vppcom_session_bind()",
rv);
808 vtfail (
"vppcom_session_listen()",
rv);
810 wrk->epfd = vppcom_epoll_create ();
812 vtfail (
"vppcom_epoll_create()",
wrk->epfd);
814 listen_ev.events = EPOLLET | EPOLLIN;
821 vtinf (
"Waiting for client ctrl connection on port %d ...",
838 rv = vppcom_app_create (
"vcl_test_server");
864 vppcom_app_destroy ();
vcl_test_stats_t old_stats
static int vcl_test_read_ds(vcl_test_session_t *ts)
static void sync_config_and_reply(vcl_test_session_t *conn, vcl_test_cfg_t *rx_cfg)
static void vts_server_echo(vcl_test_session_t *conn, int rx_bytes)
void * realloc(void *p, size_t size)
static void vts_server_process_rx(vcl_test_session_t *conn, int rx_bytes)
#define VCL_TEST_DATA_LISTENER
volatile int worker_fails
static void * vts_worker_loop(void *arg)
static double vcl_test_time_diff(struct timespec *old, struct timespec *new)
static void vcl_test_cfg_dump(vcl_test_cfg_t *cfg, uint8_t is_client)
struct sockaddr_storage servaddr
#define VCL_TEST_SERVER_PORT
int vts_handle_ctrl_cfg(vcl_test_server_worker_t *wrk, vcl_test_cfg_t *rx_cfg, vcl_test_session_t *conn, int rx_bytes)
static void vts_ctrl_session_init(vcl_test_server_worker_t *wrk)
static vcl_test_session_t * conn_pool_alloc(vcl_test_server_worker_t *wrk)
static void vts_inc_stats_check(vcl_test_session_t *ts)
#define VCL_TEST_CTRL_LISTENER
static void vts_session_cleanup(vcl_test_session_t *ts)
static void vcl_test_init_endpoint_addr(vcl_test_server_main_t *vsm)
static void vcl_test_session_buf_alloc(vcl_test_session_t *ts)
int(* write)(struct vcl_test_session *ts, void *buf, uint32_t buflen)
static void vcl_test_buf_alloc(vcl_test_cfg_t *cfg, uint8_t is_rxbuf, uint8_t **buf, uint32_t *bufsize)
static void print_usage_and_exit(void)
int(* accept)(int listen_fd, vcl_test_session_t *ts)
static void vcl_test_session_buf_free(vcl_test_session_t *ts)
if(node->flags &VLIB_NODE_FLAG_TRACE) vnet_interface_output_trace(vm
int(* close)(vcl_test_session_t *ts)
static void conn_pool_free(vcl_test_session_t *ts)
int(* listen)(vcl_test_session_t *ts, vppcom_endpt_t *endpt)
static void vcl_test_stats_dump(char *header, vcl_test_stats_t *stats, uint8_t show_rx, uint8_t show_tx, uint8_t verbose)
static perfmon_event_t events[]
static void vts_wrk_cleanup_all(vcl_test_server_worker_t *wrk)
static void vcl_test_server_process_opts(vcl_test_server_main_t *vsm, int argc, char **argv)
vcl_test_main_t vcl_test_main
static void vts_test_cmd(vcl_test_server_worker_t *wrk, vcl_test_session_t *conn, vcl_test_cfg_t *rx_cfg)
static vcl_test_session_t * vts_accept_ctrl(vcl_test_server_worker_t *wrk, int listen_fd)
int(* read)(struct vcl_test_session *ts, void *buf, uint32_t buflen)
const vcl_test_proto_vft_t * protos[VPPCOM_PROTO_SRTP+1]
static int vts_conn_read(vcl_test_session_t *conn)
vppcom_data_segment_t ds[2]
void * clib_mem_init_thread_safe(void *memory, uword memory_size)
int main(int argc, char **argv)
#define VCL_TEST_CFG_MAX_EPOLL_EVENTS
#define VCL_TEST_SEPARATOR_STRING
#define VCL_TEST_CFG_MAX_TEST_SESS
static void vts_worker_init(vcl_test_server_worker_t *wrk)
vcl_test_session_t listener
static void vcl_test_stats_dump_inc(vcl_test_session_t *ts, int is_rx)
vcl_test_session_t * conn_pool
vcl_test_server_worker_t * workers
static void vcl_test_stats_accumulate(vcl_test_stats_t *accum, vcl_test_stats_t *incr)
vcl_test_server_cfg_t server_cfg
#define vtwrn(_fmt, _args...)
void * calloc(size_t nmemb, size_t size)
vcl_test_session_t * ctrl
static vcl_test_session_t * vts_accept_client(vcl_test_server_worker_t *wrk, int listen_fd)
static vcl_test_server_main_t vcl_server_main
#define vtinf(_fmt, _args...)
#define VCL_TEST_CFG_CTRL_MAGIC
static void vcl_test_cfg_init(vcl_test_cfg_t *cfg)
static void vts_session_close(vcl_test_session_t *conn)
static void conn_pool_expand(vcl_test_server_worker_t *wrk, size_t expand_size)
static int vcl_test_write(vcl_test_session_t *ts, void *buf, uint32_t nbytes)
static int vcl_comp_tspec(struct timespec *a, struct timespec *b)
int(* init)(vcl_test_cfg_t *cfg)
volatile int active_workers
#define VCL_TEST_DELAY_DISCONNECT