|
FD.io VPP
v21.06-3-gbb25fbf28
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 (
"Got a connection -- fd = %d (0x%08x) on listener fd = %d (0x%08x)",
335 conn->
fd, conn->
fd, listen_fd, listen_fd);
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);
353 fprintf (stderr,
"vcl_test_server [OPTIONS] <port>\n"
355 " -h Print this message and exit.\n"
357 " -w <num> Number of workers\n"
358 " -p <PROTO> Use <PROTO> transport layer\n"
359 " -D Use UDP transport layer\n"
360 " -L Use TLS transport layer\n"
361 " -S Incremental stats\n");
368 struct sockaddr_storage *servaddr = &vsm->
servaddr;
369 memset (servaddr, 0,
sizeof (*servaddr));
373 struct sockaddr_in6 *server_addr = (
struct sockaddr_in6 *) servaddr;
374 server_addr->sin6_family = AF_INET6;
375 server_addr->sin6_addr = in6addr_any;
380 struct sockaddr_in *server_addr = (
struct sockaddr_in *) servaddr;
381 server_addr->sin_family = AF_INET;
382 server_addr->sin_addr.s_addr = htonl (INADDR_ANY);
388 struct sockaddr_in6 *server_addr = (
struct sockaddr_in6 *) servaddr;
395 struct sockaddr_in *server_addr = (
struct sockaddr_in *) servaddr;
411 while ((
c = getopt (argc, argv,
"6DLsw:hp:S")) != -1)
420 vtwrn (
"Invalid vppcom protocol %s, defaulting to TCP", optarg);
436 vtwrn (
"Invalid number of workers %d", v);
449 vtwrn (
"Option `-%c' requires an argument.", optopt);
452 if (isprint (optopt))
453 vtwrn (
"Unknown option `-%c'.", optopt);
455 vtwrn (
"Unknown option character `\\x%x'.", optopt);
463 if (argc < (optind + 1))
465 fprintf (stderr,
"SERVER: ERROR: Insufficient number of arguments!\n");
469 if (sscanf (argv[optind],
"%d", &v) == 1)
473 fprintf (stderr,
"SERVER: ERROR: Invalid port (%s)!\n", argv[optind]);
486 vtinf (
"(fd %d): Received a cfg msg!", conn->
fd);
490 if (rx_bytes !=
sizeof (*rx_cfg))
492 vtinf (
"(fd %d): Invalid cfg msg size %d expected %lu!", conn->
fd,
493 rx_bytes, sizeof (*rx_cfg));
498 vtinf (
"(fd %d): Replying to cfg msg", conn->
fd);
501 conn->
write (conn, &conn->
cfg, sizeof (conn->
cfg));
505 switch (rx_cfg->
test)
518 vtinf (
"Ctrl session fd %d closing!", conn->
fd);
526 vtwrn (
"Unknown test type %d", rx_cfg->
test);
540 struct epoll_event listen_ev;
543 __wrk_index =
wrk->wrk_index;
545 vtinf (
"Initializing worker ...");
549 if (vppcom_worker_register ())
550 vtfail (
"vppcom_worker_register()", 1);
559 wrk->epfd = vppcom_epoll_create ();
561 vtfail (
"vppcom_epoll_create()",
wrk->epfd);
564 listen_ev.events = EPOLLIN;
567 vppcom_epoll_ctl (
wrk->epfd, EPOLL_CTL_ADD,
wrk->listener.fd, &listen_ev);
572 vtinf (
"Waiting for client data connections on port %d ...",
593 clock_gettime (CLOCK_REALTIME, &ts->
stats.
stop);
608 int i, rx_bytes, num_ev;
621 vterr (
"vppcom_epoll_wait()", num_ev);
624 else if (num_ev == 0)
628 for (
i = 0;
i < num_ev;
i++)
630 conn = &
wrk->conn_pool[ep_evts[
i].data.u32];
634 if (ep_evts[
i].
events & (EPOLLHUP | EPOLLRDHUP))
640 vtinf (
"All client connections closed\n");
654 vtwrn (
"ctrl already exists");
663 conn->
cfg = vsm->ctrl->cfg;
666 else if (vppcom_session_is_connectable_listener (conn->
fd))
676 if (!
wrk->wrk_index && conn->
fd == vsm->ctrl->fd)
685 vtinf (
"All client connections closed\n");
689 else if (isascii (conn->
rxbuf[0]))
695 vtwrn (
"FIFO not drained! extra bytes %d", rx_bytes);
704 if (EPOLLIN & ep_evts[
i].
events)
711 if (errno == ECONNRESET)
713 vtinf (
"Connection reset by remote peer.\n");
720 if (vppcom_session_attr (conn->
fd, VPPCOM_ATTR_GET_NREAD, 0, 0) >
723 if (vsm->incremental_stats)
729 vtwrn (
"Unhandled event");
736 vsm->worker_fails -= 1;
739 vppcom_session_close (
wrk->listener.fd);
742 vsm->active_workers -= 1;
750 struct epoll_event listen_ev;
753 vtinf (
"Initializing main ctrl session ...");
756 vppcom_session_create (VPPCOM_PROTO_TCP, 0 );
762 vtfail (
"vppcom_session_bind()",
rv);
766 vtfail (
"vppcom_session_listen()",
rv);
768 wrk->epfd = vppcom_epoll_create ();
770 vtfail (
"vppcom_epoll_create()",
wrk->epfd);
772 listen_ev.events = EPOLLIN;
779 vtinf (
"Waiting for client ctrl connection on port %d ...",
796 rv = vppcom_app_create (
"vcl_test_server");
822 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)
sll srl srl sll sra u16x4 i
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)
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