FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
vcl_test_client.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017-2021 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <unistd.h>
17 #include <errno.h>
18 #include <stdlib.h>
19 #include <ctype.h>
20 #include <sys/types.h>
21 #include <sys/socket.h>
22 #include <stdio.h>
23 #include <time.h>
24 #include <arpa/inet.h>
25 #include <hs_apps/vcl/vcl_test.h>
26 #include <pthread.h>
27 #include <signal.h>
28 
29 typedef struct
30 {
33  uint32_t n_sessions;
34  uint32_t wrk_index;
35  fd_set wr_fdset;
36  fd_set rd_fdset;
38  pthread_t thread_handle;
41 
42 typedef struct
43 {
46  vppcom_endpt_t server_endpt;
47  uint32_t cfg_seq_num;
48  uint8_t dump_cfg;
50  uint8_t proto;
52  uint32_t n_workers;
53  volatile int active_workers;
54  volatile int test_running;
55  struct sockaddr_storage server_addr;
57 
59 
60 #define vtc_min(a, b) (a < b ? a : b)
61 #define vtc_max(a, b) (a > b ? a : b)
62 
64 
65 static int
67 {
68  vcl_test_cfg_t *rx_cfg = (vcl_test_cfg_t *) ts->rxbuf;
69  int rx_bytes, tx_bytes;
70 
71  vt_atomic_add (&ts->cfg.seq_num, 1);
72  if (ts->cfg.verbose)
73  {
74  vtinf ("(fd %d): Sending config to server.", ts->fd);
75  vcl_test_cfg_dump (&ts->cfg, 1 /* is_client */ );
76  }
77  tx_bytes = ts->write (ts, &ts->cfg, sizeof (ts->cfg));
78  if (tx_bytes < 0)
79  {
80  vtwrn ("(fd %d): write test cfg failed (%d)!", ts->fd, tx_bytes);
81  return tx_bytes;
82  }
83 
84  rx_bytes = ts->read (ts, ts->rxbuf, sizeof (vcl_test_cfg_t));
85  if (rx_bytes < 0)
86  return rx_bytes;
87 
88  if (rx_cfg->magic != VCL_TEST_CFG_CTRL_MAGIC)
89  {
90  vtwrn ("(fd %d): Bad server reply cfg -- aborting!", ts->fd);
91  return -1;
92  }
93  if ((rx_bytes != sizeof (vcl_test_cfg_t))
94  || !vcl_test_cfg_verify (rx_cfg, &ts->cfg))
95  {
96  vtwrn ("(fd %d): Invalid config received from server!", ts->fd);
97  if (rx_bytes != sizeof (vcl_test_cfg_t))
98  {
99  vtinf ("\tRx bytes %d != cfg size %lu", rx_bytes,
100  sizeof (vcl_test_cfg_t));
101  }
102  else
103  {
104  vcl_test_cfg_dump (rx_cfg, 1 /* is_client */ );
105  vtinf ("(fd %d): Valid config sent to server.", ts->fd);
106  vcl_test_cfg_dump (&ts->cfg, 1 /* is_client */ );
107  }
108  return -1;
109  }
110  if (ts->cfg.verbose)
111  {
112  vtinf ("(fd %d): Got config back from server.", ts->fd);
113  vcl_test_cfg_dump (rx_cfg, 1 /* is_client */ );
114  }
115 
116  return 0;
117 }
118 
119 static int
121 {
124  const vcl_test_proto_vft_t *tp;
125  vcl_test_session_t *ts;
126  uint32_t n_test_sessions;
127  int i, rv;
128 
129  n_test_sessions = wrk->cfg.num_test_sessions;
130  if (n_test_sessions < 1)
131  {
132  errno = EINVAL;
133  return -1;
134  }
135 
136  if (wrk->n_sessions >= n_test_sessions)
137  goto done;
138 
139  if (wrk->n_sessions)
141  n_test_sessions * sizeof (vcl_test_session_t));
142  else
143  wrk->sessions = calloc (n_test_sessions, sizeof (vcl_test_session_t));
144 
145  if (!wrk->sessions)
146  {
147  vterr ("failed to alloc sessions", -errno);
148  return errno;
149  }
150 
151  tp = vt->protos[vcm->proto];
152 
153  for (i = 0; i < n_test_sessions; i++)
154  {
155  ts = &wrk->sessions[i];
156  memset (ts, 0, sizeof (*ts));
157  ts->session_index = i;
158  ts->cfg = wrk->cfg;
160  rv = tp->open (&wrk->sessions[i], &vcm->server_endpt);
161  if (rv < 0)
162  return rv;
163  }
164  wrk->n_sessions = n_test_sessions;
165 
166 done:
167  vtinf ("All test sessions (%d) connected!", n_test_sessions);
168  return 0;
169 }
170 
171 static int
173 {
174  vcl_test_cfg_t *cfg = &wrk->cfg;
175  vcl_test_session_t *ts;
176  struct timespec now;
177  uint32_t sidx;
178  int i, j;
179 
180  FD_ZERO (&wrk->wr_fdset);
181  FD_ZERO (&wrk->rd_fdset);
182 
183  clock_gettime (CLOCK_REALTIME, &now);
184 
185  for (i = 0; i < cfg->num_test_sessions; i++)
186  {
187  ts = &wrk->sessions[i];
188  ts->old_stats.stop = now;
189 
190  switch (cfg->test)
191  {
192  case VCL_TEST_TYPE_UNI:
193  case VCL_TEST_TYPE_BI:
194  for (j = 0; j < ts->txbuf_size; j++)
195  ts->txbuf[j] = j & 0xff;
196  break;
197  default:
198  break;
199  }
200 
201  FD_SET (vppcom_session_index (ts->fd), &wrk->wr_fdset);
202  FD_SET (vppcom_session_index (ts->fd), &wrk->rd_fdset);
203  sidx = vppcom_session_index (ts->fd);
204  wrk->max_fd_index = vtc_max (sidx, wrk->max_fd_index);
205  }
206  wrk->max_fd_index += 1;
207 
208  return 0;
209 }
210 
211 static int
213 {
215  int rv;
216 
217  __wrk_index = wrk->wrk_index;
218 
219  vtinf ("Initializing worker %u ...", wrk->wrk_index);
220 
221  if (wrk->wrk_index)
222  {
223  if (vppcom_worker_register ())
224  {
225  vtwrn ("failed to register worker");
226  return -1;
227  }
228  vt_atomic_add (&vcm->active_workers, 1);
229  }
231  if (rv)
232  {
233  vterr ("vtc_connect_test_sessions ()", rv);
234  return rv;
235  }
236 
238  return -1;
239 
240  return 0;
241 }
242 
243 static int stats_lock = 0;
244 
245 static void
247  vcl_test_session_t * ctrl)
248 {
249  vcl_test_session_t *ts;
250  static char buf[64];
251  int i, show_rx = 0;
252 
253  while (__sync_lock_test_and_set (&stats_lock, 1))
254  ;
255 
256  if (ctrl->cfg.test == VCL_TEST_TYPE_BI
257  || ctrl->cfg.test == VCL_TEST_TYPE_ECHO)
258  show_rx = 1;
259 
260  for (i = 0; i < wrk->cfg.num_test_sessions; i++)
261  {
262  ts = &wrk->sessions[i];
263  ts->stats.start = ctrl->stats.start;
264 
265  if (ctrl->cfg.verbose > 1)
266  {
267  snprintf (buf, sizeof (buf), "CLIENT (fd %d) RESULTS", ts->fd);
268  vcl_test_stats_dump (buf, &ts->stats, show_rx, 1 /* show tx */ ,
269  ctrl->cfg.verbose);
270  }
271 
272  vcl_test_stats_accumulate (&ctrl->stats, &ts->stats);
273  if (vcl_comp_tspec (&ctrl->stats.stop, &ts->stats.stop) < 0)
274  ctrl->stats.stop = ts->stats.stop;
275  }
276 
277  __sync_lock_release (&stats_lock);
278 }
279 
280 static void
282 {
283  vcl_test_session_t *ts;
284  int i;
285 
286  for (i = 0; i < wrk->cfg.num_test_sessions; i++)
287  {
288  ts = &wrk->sessions[i];
289  vppcom_session_close (ts->fd);
291  }
292 
293  wrk->n_sessions = 0;
294 }
295 
296 static void
298 {
299  /* Avoid checking time too often because of syscall cost */
300  if (ts->stats.tx_bytes - ts->old_stats.tx_bytes < 1 << 20)
301  return;
302 
303  clock_gettime (CLOCK_REALTIME, &ts->stats.stop);
304  if (vcl_test_time_diff (&ts->old_stats.stop, &ts->stats.stop) > 1)
305  {
306  vcl_test_stats_dump_inc (ts, 0 /* is_rx */);
307  ts->old_stats = ts->stats;
308  }
309 }
310 
311 static void *
312 vtc_worker_loop (void *arg)
313 {
315  vcl_test_session_t *ctrl = &vcm->ctrl_session;
317  uint32_t n_active_sessions;
318  fd_set _wfdset, *wfdset = &_wfdset;
319  fd_set _rfdset, *rfdset = &_rfdset;
320  vcl_test_session_t *ts;
321  int i, rv, check_rx = 0;
322 
323  rv = vtc_worker_init (wrk);
324  if (rv)
325  {
326  vterr ("vtc_worker_init()", rv);
327  return 0;
328  }
329 
330  vtinf ("Starting test ...");
331 
332  if (wrk->wrk_index == 0)
333  clock_gettime (CLOCK_REALTIME, &ctrl->stats.start);
334 
335  check_rx = wrk->cfg.test != VCL_TEST_TYPE_UNI;
336  n_active_sessions = wrk->cfg.num_test_sessions;
337  while (n_active_sessions && vcm->test_running)
338  {
339  _wfdset = wrk->wr_fdset;
340  _rfdset = wrk->rd_fdset;
341 
342  rv = vppcom_select (wrk->max_fd_index, (unsigned long *) rfdset,
343  (unsigned long *) wfdset, NULL, 0);
344  if (rv < 0)
345  {
346  vterr ("vppcom_select()", rv);
347  goto exit;
348  }
349  else if (rv == 0)
350  continue;
351 
352  for (i = 0; i < wrk->cfg.num_test_sessions; i++)
353  {
354  ts = &wrk->sessions[i];
355  if (ts->is_done)
356  continue;
357 
358  if (FD_ISSET (vppcom_session_index (ts->fd), rfdset)
359  && ts->stats.rx_bytes < ts->cfg.total_bytes)
360  {
361  rv = ts->read (ts, ts->rxbuf, ts->rxbuf_size);
362  if (rv < 0)
363  goto exit;
364  }
365 
366  if (FD_ISSET (vppcom_session_index (ts->fd), wfdset)
367  && ts->stats.tx_bytes < ts->cfg.total_bytes)
368  {
369  rv = ts->write (ts, ts->txbuf, ts->cfg.txbuf_size);
370  if (rv < 0)
371  {
372  vtwrn ("vppcom_test_write (%d) failed -- aborting test",
373  ts->fd);
374  goto exit;
375  }
376  if (vcm->incremental_stats)
377  vtc_inc_stats_check (ts);
378  }
379  if ((!check_rx && ts->stats.tx_bytes >= ts->cfg.total_bytes)
380  || (check_rx && ts->stats.rx_bytes >= ts->cfg.total_bytes))
381  {
382  clock_gettime (CLOCK_REALTIME, &ts->stats.stop);
383  ts->is_done = 1;
384  n_active_sessions--;
385  }
386  }
387  }
388 exit:
389  vtinf ("Worker %d done ...", wrk->wrk_index);
390  vtc_accumulate_stats (wrk, ctrl);
393  if (wrk->wrk_index)
394  vt_atomic_add (&vcm->active_workers, -1);
395  return 0;
396 }
397 
398 static void
400 {
401  int is_echo = ctrl->cfg.test == VCL_TEST_TYPE_ECHO;
402  int show_rx = 0;
403  char buf[64];
404 
405  if (ctrl->cfg.test == VCL_TEST_TYPE_BI
406  || ctrl->cfg.test == VCL_TEST_TYPE_ECHO)
407  show_rx = 1;
408 
409  vcl_test_stats_dump ("CLIENT RESULTS", &ctrl->stats,
410  show_rx, 1 /* show tx */ ,
411  ctrl->cfg.verbose);
412  vcl_test_cfg_dump (&ctrl->cfg, 1 /* is_client */ );
413 
414  if (ctrl->cfg.verbose)
415  {
416  vtinf (" ctrl session info\n"
418  " fd: %d (0x%08x)\n"
419  " rxbuf: %p\n"
420  " rxbuf size: %u (0x%08x)\n"
421  " txbuf: %p\n"
422  " txbuf size: %u (0x%08x)\n"
424  ctrl->fd, (uint32_t) ctrl->fd,
425  ctrl->rxbuf, ctrl->rxbuf_size, ctrl->rxbuf_size,
426  ctrl->txbuf, ctrl->txbuf_size, ctrl->txbuf_size);
427  }
428 
429  if (is_echo)
430  snprintf (buf, sizeof (buf), "Echo");
431  else
432  snprintf (buf, sizeof (buf), "%s-directional Stream",
433  ctrl->cfg.test == VCL_TEST_TYPE_BI ? "Bi" : "Uni");
434 }
435 
436 static void
438 {
439  vcl_test_session_t *ctrl = &vcm->ctrl_session;
440  vcl_test_cfg_t *cfg = &ctrl->cfg;
441  int rv;
442 
443  cfg->total_bytes = strlen (ctrl->txbuf) + 1;
444  memset (&ctrl->stats, 0, sizeof (ctrl->stats));
445 
446  rv = ctrl->write (ctrl, ctrl->txbuf, cfg->total_bytes);
447  if (rv < 0)
448  {
449  vtwrn ("vppcom_test_write (%d) failed ", ctrl->fd);
450  return;
451  }
452 
453  (void) ctrl->read (ctrl, ctrl->rxbuf, ctrl->rxbuf_size);
454 }
455 
456 static void
458 {
459  vcl_test_session_t *ctrl = &vcm->ctrl_session;
460  vcl_test_cfg_t *cfg = &ctrl->cfg;
462  uint32_t i, n_conn, n_conn_per_wrk;
463 
464  vtinf ("%s-directional Stream Test Starting!",
465  ctrl->cfg.test == VCL_TEST_TYPE_BI ? "Bi" : "Uni");
466 
467  memset (&ctrl->stats, 0, sizeof (vcl_test_stats_t));
468  cfg->total_bytes = cfg->num_writes * cfg->txbuf_size;
469  cfg->ctrl_handle = ctrl->fd;
470 
471  n_conn = cfg->num_test_sessions;
472  n_conn_per_wrk = n_conn / vcm->n_workers;
473  for (i = 0; i < vcm->n_workers; i++)
474  {
475  wrk = &vcm->workers[i];
476  wrk->wrk_index = i;
477  wrk->cfg = ctrl->cfg;
478  wrk->cfg.num_test_sessions = vtc_min (n_conn_per_wrk, n_conn);
479  n_conn -= wrk->cfg.num_test_sessions;
480  }
481 
482  vcm->test_running = 1;
483  ctrl->cfg.cmd = VCL_TEST_CMD_START;
484  if (vtc_cfg_sync (ctrl))
485  {
486  vtwrn ("test cfg sync failed -- aborting!");
487  return;
488  }
489 
490  for (i = 1; i < vcm->n_workers; i++)
491  {
492  wrk = &vcm->workers[i];
493  pthread_create (&wrk->thread_handle, NULL, vtc_worker_loop,
494  (void *) wrk);
495  }
496  vtc_worker_loop (&vcm->workers[0]);
497 
498  while (vcm->active_workers > 0)
499  ;
500 
501  vtinf ("Sending config on ctrl session (fd %d) for stats...", ctrl->fd);
502  ctrl->cfg.cmd = VCL_TEST_CMD_STOP;
503  if (vtc_cfg_sync (ctrl))
504  {
505  vtwrn ("test cfg sync failed -- aborting!");
506  return;
507  }
508 
509  vtc_print_stats (ctrl);
510 
511  ctrl->cfg.cmd = VCL_TEST_CMD_SYNC;
512  ctrl->cfg.test = VCL_TEST_TYPE_ECHO;
513  ctrl->cfg.total_bytes = 0;
514  if (vtc_cfg_sync (ctrl))
515  vtwrn ("post-test cfg sync failed!");
516 }
517 
518 static void
520 {
522  vcl_test_session_t *ctrl = &vcm->ctrl_session;
523  char *p = ctrl->txbuf + strlen (VCL_TEST_TOKEN_TXBUF_SIZE);
524  uint64_t txbuf_size = strtoull ((const char *) p, NULL, 10);
525 
526  if (txbuf_size >= VCL_TEST_CFG_BUF_SIZE_MIN)
527  {
528  ctrl->cfg.txbuf_size = txbuf_size;
529  ctrl->cfg.total_bytes = ctrl->cfg.num_writes * ctrl->cfg.txbuf_size;
530  vcl_test_buf_alloc (&ctrl->cfg, 0 /* is_rxbuf */ ,
531  (uint8_t **) & ctrl->txbuf, &ctrl->txbuf_size);
532  vcl_test_cfg_dump (&ctrl->cfg, 1 /* is_client */ );
533  }
534  else
535  vtwrn ("Invalid txbuf size (%lu) < minimum buf size (%u)!",
536  txbuf_size, VCL_TEST_CFG_BUF_SIZE_MIN);
537 }
538 
539 static void
541 {
543  vcl_test_session_t *ctrl = &vcm->ctrl_session;
544  char *p = ctrl->txbuf + strlen (VCL_TEST_TOKEN_NUM_WRITES);
545  uint32_t num_writes = strtoul ((const char *) p, NULL, 10);
546 
547  if (num_writes > 0)
548  {
549  ctrl->cfg.num_writes = num_writes;
550  ctrl->cfg.total_bytes = ctrl->cfg.num_writes * ctrl->cfg.txbuf_size;
551  vcl_test_cfg_dump (&ctrl->cfg, 1 /* is_client */ );
552  }
553  else
554  {
555  vtwrn ("invalid num writes: %u", num_writes);
556  }
557 }
558 
559 static void
561 {
563  vcl_test_session_t *ctrl = &vcm->ctrl_session;
564  char *p = ctrl->txbuf + strlen (VCL_TEST_TOKEN_NUM_TEST_SESS);
565  uint32_t num_test_sessions = strtoul ((const char *) p, NULL, 10);
566 
567  if ((num_test_sessions > 0) &&
568  (num_test_sessions <= VCL_TEST_CFG_MAX_TEST_SESS))
569  {
570  ctrl->cfg.num_test_sessions = num_test_sessions;
571  vcl_test_cfg_dump (&ctrl->cfg, 1 /* is_client */ );
572  }
573  else
574  {
575  vtwrn ("invalid num test sessions: %u, (%d max)",
576  num_test_sessions, VCL_TEST_CFG_MAX_TEST_SESS);
577  }
578 }
579 
580 static void
582 {
584  vcl_test_session_t *ctrl = &vcm->ctrl_session;
585  char *p = ctrl->txbuf + strlen (VCL_TEST_TOKEN_RXBUF_SIZE);
586  uint64_t rxbuf_size = strtoull ((const char *) p, NULL, 10);
587 
588  if (rxbuf_size >= VCL_TEST_CFG_BUF_SIZE_MIN)
589  {
590  ctrl->cfg.rxbuf_size = rxbuf_size;
591  vcl_test_buf_alloc (&ctrl->cfg, 1 /* is_rxbuf */ ,
592  (uint8_t **) & ctrl->rxbuf, &ctrl->rxbuf_size);
593  vcl_test_cfg_dump (&ctrl->cfg, 1 /* is_client */ );
594  }
595  else
596  vtwrn ("Invalid rxbuf size (%lu) < minimum buf size (%u)!",
597  rxbuf_size, VCL_TEST_CFG_BUF_SIZE_MIN);
598 }
599 
600 static void
602 {
604  vcl_test_session_t *ctrl = &vcm->ctrl_session;
605 
606  ctrl->cfg.verbose = ctrl->cfg.verbose ? 0 : 1;
607  vcl_test_cfg_dump (&ctrl->cfg, 1 /* is_client */ );
608 
609 }
610 
611 static vcl_test_t
613 {
615  vcl_test_session_t *ctrl = &vcm->ctrl_session;
617 
618  if (!strncmp (VCL_TEST_TOKEN_EXIT, ctrl->txbuf,
619  strlen (VCL_TEST_TOKEN_EXIT)))
621 
622  else if (!strncmp (VCL_TEST_TOKEN_HELP, ctrl->txbuf,
623  strlen (VCL_TEST_TOKEN_HELP)))
624  dump_help ();
625 
626  else if (!strncmp (VCL_TEST_TOKEN_SHOW_CFG, ctrl->txbuf,
627  strlen (VCL_TEST_TOKEN_SHOW_CFG)))
628  vcm->dump_cfg = 1;
629 
630  else if (!strncmp (VCL_TEST_TOKEN_VERBOSE, ctrl->txbuf,
631  strlen (VCL_TEST_TOKEN_VERBOSE)))
633 
634  else if (!strncmp (VCL_TEST_TOKEN_TXBUF_SIZE, ctrl->txbuf,
635  strlen (VCL_TEST_TOKEN_TXBUF_SIZE)))
637 
638  else if (!strncmp (VCL_TEST_TOKEN_NUM_TEST_SESS, ctrl->txbuf,
641 
642  else if (!strncmp (VCL_TEST_TOKEN_NUM_WRITES, ctrl->txbuf,
643  strlen (VCL_TEST_TOKEN_NUM_WRITES)))
645 
646  else if (!strncmp (VCL_TEST_TOKEN_RXBUF_SIZE, ctrl->txbuf,
647  strlen (VCL_TEST_TOKEN_RXBUF_SIZE)))
649 
650  else if (!strncmp (VCL_TEST_TOKEN_RUN_UNI, ctrl->txbuf,
651  strlen (VCL_TEST_TOKEN_RUN_UNI)))
652  rv = ctrl->cfg.test = VCL_TEST_TYPE_UNI;
653 
654  else if (!strncmp (VCL_TEST_TOKEN_RUN_BI, ctrl->txbuf,
655  strlen (VCL_TEST_TOKEN_RUN_BI)))
656  rv = ctrl->cfg.test = VCL_TEST_TYPE_BI;
657 
658  else
660 
661  return rv;
662 }
663 
664 void
666 {
667  fprintf (
668  stderr,
669  "vcl_test_client [OPTIONS] <ipaddr> <port>\n"
670  " OPTIONS\n"
671  " -h Print this message and exit.\n"
672  " -6 Use IPv6\n"
673  " -c Print test config before test.\n"
674  " -w <dir> Write test results to <dir>.\n"
675  " -X Exit after running test.\n"
676  " -p <proto> Use <proto> transport layer\n"
677  " -D Use UDP transport layer\n"
678  " -L Use TLS transport layer\n"
679  " -E Run Echo test.\n"
680  " -N <num-writes> Test Cfg: number of writes.\n"
681  " -R <rxbuf-size> Test Cfg: rx buffer size.\n"
682  " -T <txbuf-size> Test Cfg: tx buffer size.\n"
683  " -U Run Uni-directional test.\n"
684  " -B Run Bi-directional test.\n"
685  " -V Verbose mode.\n"
686  " -I <N> Use N sessions.\n"
687  " -s <N> Use N sessions.\n"
688  " -S Print incremental stats per session.\n"
689  " -q <n> QUIC : use N Ssessions on top of n Qsessions\n");
690  exit (1);
691 }
692 
693 static void
694 vtc_process_opts (vcl_test_client_main_t * vcm, int argc, char **argv)
695 {
696  vcl_test_session_t *ctrl = &vcm->ctrl_session;
697  int c, v;
698 
699  opterr = 0;
700  while ((c = getopt (argc, argv, "chnp:w:XE:I:N:R:T:UBV6DLs:q:S")) != -1)
701  switch (c)
702  {
703  case 'c':
704  vcm->dump_cfg = 1;
705  break;
706 
707  case 'I': /* deprecated */
708  case 's':
709  if (sscanf (optarg, "0x%x", &ctrl->cfg.num_test_sessions) != 1)
710  if (sscanf (optarg, "%u", &ctrl->cfg.num_test_sessions) != 1)
711  {
712  vtwrn ("Invalid value for option -%c!", c);
714  }
715  if (!ctrl->cfg.num_test_sessions ||
717  {
718  vtwrn ("Invalid number of sessions (%d) specified for option -%c!"
719  "\n Valid range is 1 - %d",
720  ctrl->cfg.num_test_sessions, c,
723  }
724  break;
725 
726  case 'q':
727  if (sscanf (optarg, "0x%x", &ctrl->cfg.num_test_sessions_perq) != 1)
728  if (sscanf (optarg, "%u", &ctrl->cfg.num_test_sessions_perq) != 1)
729  {
730  vtwrn ("Invalid value for option -%c!", c);
732  }
733  if (!ctrl->cfg.num_test_sessions_perq ||
735  {
736  vtwrn ("Invalid number of Stream sessions (%d) per Qsession"
737  "for option -%c!\nValid range is 1 - %d",
741  }
742  break;
743 
744  case 'w':
745  if (sscanf (optarg, "%d", &v) != 1)
746  {
747  vtwrn ("Invalid value for option -%c!", c);
749  }
750  if (v > 1)
751  vcm->n_workers = v;
752  break;
753 
754  case 'X':
756  break;
757 
758  case 'E':
759  if (strlen (optarg) > ctrl->txbuf_size)
760  {
761  vtwrn ("Option -%c value larger than txbuf size (%d)!",
762  optopt, ctrl->txbuf_size);
764  }
765  strncpy (ctrl->txbuf, optarg, ctrl->txbuf_size);
766  ctrl->cfg.test = VCL_TEST_TYPE_ECHO;
767  break;
768 
769  case 'N':
770  if (sscanf (optarg, "0x%lx", &ctrl->cfg.num_writes) != 1)
771  if (sscanf (optarg, "%ld", &ctrl->cfg.num_writes) != 1)
772  {
773  vtwrn ("Invalid value for option -%c!", c);
775  }
776  ctrl->cfg.total_bytes = ctrl->cfg.num_writes * ctrl->cfg.txbuf_size;
777  break;
778 
779  case 'R':
780  if (sscanf (optarg, "0x%lx", &ctrl->cfg.rxbuf_size) != 1)
781  if (sscanf (optarg, "%ld", &ctrl->cfg.rxbuf_size) != 1)
782  {
783  vtwrn ("Invalid value for option -%c!", c);
785  }
787  {
788  ctrl->rxbuf_size = ctrl->cfg.rxbuf_size;
789  vcl_test_buf_alloc (&ctrl->cfg, 1 /* is_rxbuf */ ,
790  (uint8_t **) & ctrl->rxbuf,
791  &ctrl->rxbuf_size);
792  }
793  else
794  {
795  vtwrn ("rxbuf size (%lu) less than minumum (%u)",
798  }
799 
800  break;
801 
802  case 'T':
803  if (sscanf (optarg, "0x%lx", &ctrl->cfg.txbuf_size) != 1)
804  if (sscanf (optarg, "%ld", &ctrl->cfg.txbuf_size) != 1)
805  {
806  vtwrn ("Invalid value for option -%c!", c);
808  }
810  {
811  ctrl->txbuf_size = ctrl->cfg.txbuf_size;
812  vcl_test_buf_alloc (&ctrl->cfg, 0 /* is_rxbuf */ ,
813  (uint8_t **) & ctrl->txbuf,
814  &ctrl->txbuf_size);
815  ctrl->cfg.total_bytes =
816  ctrl->cfg.num_writes * ctrl->cfg.txbuf_size;
817  }
818  else
819  {
820  vtwrn ("txbuf size (%lu) less than minumum (%u)!",
823  }
824  break;
825 
826  case 'U':
827  ctrl->cfg.test = VCL_TEST_TYPE_UNI;
828  break;
829 
830  case 'B':
831  ctrl->cfg.test = VCL_TEST_TYPE_BI;
832  break;
833 
834  case 'V':
835  ctrl->cfg.verbose = 1;
836  break;
837 
838  case '6':
839  ctrl->cfg.address_ip6 = 1;
840  break;
841 
842  case 'p':
843  if (vppcom_unformat_proto (&vcm->proto, optarg))
844  vtwrn ("Invalid vppcom protocol %s, defaulting to TCP", optarg);
845  break;
846 
847  case 'D': /* deprecated */
848  vcm->proto = VPPCOM_PROTO_UDP;
849  break;
850 
851  case 'L': /* deprecated */
852  vcm->proto = VPPCOM_PROTO_TLS;
853  break;
854 
855  case 'S':
856  vcm->incremental_stats = 1;
857  break;
858 
859  case '?':
860  switch (optopt)
861  {
862  case 'E':
863  case 'I': /* deprecated */
864  case 'N':
865  case 'R':
866  case 'T':
867  case 'w':
868  case 'p':
869  case 'q':
870  vtwrn ("Option -%c requires an argument.", optopt);
871  break;
872 
873  default:
874  if (isprint (optopt))
875  vtwrn ("Unknown option `-%c'.", optopt);
876  else
877  vtwrn ("Unknown option character `\\x%x'.", optopt);
878  }
879  /* fall thru */
880  case 'h':
881  default:
883  }
884 
885  if (argc < (optind + 2))
886  {
887  vtwrn ("Insufficient number of arguments!");
889  }
890 
891  ctrl->cfg.num_test_qsessions = vcm->proto != VPPCOM_PROTO_QUIC ? 0 :
892  (ctrl->cfg.num_test_sessions + ctrl->cfg.num_test_sessions_perq - 1) /
894 
895  memset (&vcm->server_addr, 0, sizeof (vcm->server_addr));
896  if (ctrl->cfg.address_ip6)
897  {
898  struct sockaddr_in6 *sddr6 = (struct sockaddr_in6 *) &vcm->server_addr;
899  sddr6->sin6_family = AF_INET6;
900  inet_pton (AF_INET6, argv[optind++], &(sddr6->sin6_addr));
901  sddr6->sin6_port = htons (atoi (argv[optind]));
902 
903  vcm->server_endpt.is_ip4 = 0;
904  vcm->server_endpt.ip = (uint8_t *) & sddr6->sin6_addr;
905  vcm->server_endpt.port = (uint16_t) sddr6->sin6_port;
906  }
907  else
908  {
909  struct sockaddr_in *saddr4 = (struct sockaddr_in *) &vcm->server_addr;
910  saddr4->sin_family = AF_INET;
911  inet_pton (AF_INET, argv[optind++], &(saddr4->sin_addr));
912  saddr4->sin_port = htons (atoi (argv[optind]));
913 
914  vcm->server_endpt.is_ip4 = 1;
915  vcm->server_endpt.ip = (uint8_t *) & saddr4->sin_addr;
916  vcm->server_endpt.port = (uint16_t) saddr4->sin_port;
917  }
918 }
919 
920 static void
922 {
923  printf ("\nType some characters and hit <return>\n"
924  "('" VCL_TEST_TOKEN_HELP "' for help): ");
925 
926  if (fgets (ctrl->txbuf, ctrl->txbuf_size, stdin) != NULL)
927  {
928  if (strlen (ctrl->txbuf) == 1)
929  {
930  printf ("\nNothing to send! Please try again...\n");
931  return;
932  }
933  ctrl->txbuf[strlen (ctrl->txbuf) - 1] = 0; // chomp the newline.
934 
935  /* Parse input for keywords */
936  ctrl->cfg.test = parse_input ();
937  }
938 }
939 
940 static void
942 {
944  vcl_test_session_t *ctrl = &vcm->ctrl_session;
945  int verbose = ctrl->cfg.verbose;
946 
947  ctrl->cfg.test = VCL_TEST_TYPE_EXIT;
948  vtinf ("(fd %d): Sending exit cfg to server...", ctrl->fd);
949  if (verbose)
950  vcl_test_cfg_dump (&ctrl->cfg, 1 /* is_client */);
951  (void) vcl_test_write (ctrl, (uint8_t *) &ctrl->cfg, sizeof (ctrl->cfg));
952  sleep (1);
953 }
954 
955 static int
957 {
958  int rv;
959 
960  ctrl->fd = vppcom_session_create (VPPCOM_PROTO_TCP, 0 /* is_nonblocking */);
961  if (ctrl->fd < 0)
962  {
963  vterr ("vppcom_session_create()", ctrl->fd);
964  return ctrl->fd;
965  }
966 
967  vtinf ("Connecting to server...");
968  rv = vppcom_session_connect (ctrl->fd, &vcm->server_endpt);
969  if (rv)
970  {
971  vterr ("vppcom_session_connect()", rv);
972  return rv;
973  }
974  vtinf ("Control session (fd %d) connected.", ctrl->fd);
975 
976  ctrl->read = vcl_test_read;
977  ctrl->write = vcl_test_write;
978 
979  ctrl->cfg.cmd = VCL_TEST_CMD_SYNC;
980  rv = vtc_cfg_sync (ctrl);
981  if (rv)
982  {
983  vterr ("vtc_cfg_sync()", rv);
984  return rv;
985  }
986 
987  ctrl->cfg.ctrl_handle = ((vcl_test_cfg_t *) ctrl->rxbuf)->ctrl_handle;
988  memset (&ctrl->stats, 0, sizeof (ctrl->stats));
989 
990  return 0;
991 }
992 
993 static void
994 vt_sigs_handler (int signum, siginfo_t *si, void *uc)
995 {
997  vcl_test_session_t *ctrl = &vcm->ctrl_session;
998 
999  vcm->test_running = 0;
1000  clock_gettime (CLOCK_REALTIME, &ctrl->stats.stop);
1001 }
1002 
1003 static void
1005 {
1006  struct sigaction sa;
1007 
1008  memset (&sa, 0, sizeof (sa));
1009  sa.sa_sigaction = vt_sigs_handler;
1010  sa.sa_flags = SA_SIGINFO;
1011  if (sigaction (SIGINT, &sa, 0))
1012  {
1013  vtwrn ("couldn't intercept sigint");
1014  exit (-1);
1015  }
1016 }
1017 
1018 int
1019 main (int argc, char **argv)
1020 {
1022  vcl_test_session_t *ctrl = &vcm->ctrl_session;
1024  int rv;
1025 
1026  vcm->n_workers = 1;
1027  vcl_test_cfg_init (&ctrl->cfg);
1029  vtc_process_opts (vcm, argc, argv);
1030  vt_incercept_sigs ();
1031 
1032  vcm->workers = calloc (vcm->n_workers, sizeof (vcl_test_client_worker_t));
1033  vt->wrk = calloc (vcm->n_workers, sizeof (vcl_test_wrk_t));
1034 
1035  rv = vppcom_app_create ("vcl_test_client");
1036  if (rv < 0)
1037  vtfail ("vppcom_app_create()", rv);
1038 
1039  /* Protos like tls/dtls/quic need init */
1040  if (vt->protos[vcm->proto]->init)
1041  vt->protos[vcm->proto]->init (&ctrl->cfg);
1042 
1043  if ((rv = vtc_ctrl_session_init (vcm, ctrl)))
1044  vtfail ("vppcom_session_create() ctrl session", rv);
1045 
1046  /* Update ctrl port to data port */
1047  vcm->server_endpt.port += 1;
1048 
1049  while (ctrl->cfg.test != VCL_TEST_TYPE_EXIT)
1050  {
1051  if (vcm->dump_cfg)
1052  {
1053  vcl_test_cfg_dump (&ctrl->cfg, 1 /* is_client */ );
1054  vcm->dump_cfg = 0;
1055  }
1056 
1057  switch (ctrl->cfg.test)
1058  {
1059  case VCL_TEST_TYPE_ECHO:
1060  vtc_echo_client (vcm);
1061  break;
1062 
1063  case VCL_TEST_TYPE_UNI:
1064  case VCL_TEST_TYPE_BI:
1065  vtc_stream_client (vcm);
1066  break;
1067 
1068  case VCL_TEST_TYPE_EXIT:
1069  continue;
1070 
1071  case VCL_TEST_TYPE_NONE:
1072  default:
1073  break;
1074  }
1075  switch (vcm->post_test)
1076  {
1077  case VCL_TEST_TYPE_EXIT:
1078  switch (ctrl->cfg.test)
1079  {
1080  case VCL_TEST_TYPE_EXIT:
1081  case VCL_TEST_TYPE_UNI:
1082  case VCL_TEST_TYPE_BI:
1083  case VCL_TEST_TYPE_ECHO:
1084  ctrl->cfg.test = VCL_TEST_TYPE_EXIT;
1085  continue;
1086 
1087  case VCL_TEST_TYPE_NONE:
1088  default:
1089  break;
1090  }
1091  break;
1092 
1093  case VCL_TEST_TYPE_NONE:
1094  case VCL_TEST_TYPE_ECHO:
1095  case VCL_TEST_TYPE_UNI:
1096  case VCL_TEST_TYPE_BI:
1097  default:
1098  break;
1099  }
1100 
1101  memset (ctrl->txbuf, 0, ctrl->txbuf_size);
1102  memset (ctrl->rxbuf, 0, ctrl->rxbuf_size);
1103 
1104  vtc_read_user_input (ctrl);
1105  }
1106 
1108  vppcom_app_destroy ();
1109  free (vcm->workers);
1110  return 0;
1111 }
1112 
1113 /*
1114  * fd.io coding-style-patch-verification: ON
1115  *
1116  * Local Variables:
1117  * eval: (c-set-style "gnu")
1118  * End:
1119  */
vtc_cfg_sync
static int vtc_cfg_sync(vcl_test_session_t *ts)
Definition: vcl_test_client.c:66
vcl_test_cfg_t::seq_num
uint32_t seq_num
Definition: vcl_test.h:95
vcl_test_session::old_stats
vcl_test_stats_t old_stats
Definition: vcl_test.h:139
vcl_test_client_main_t
Definition: vcl_test_client.c:42
vcl_test_cfg_t::magic
uint32_t magic
Definition: vcl_test.h:94
vcl_test_client_main_t::ctrl_session
vcl_test_session_t ctrl_session
Definition: vcl_test_client.c:45
realloc
void * realloc(void *p, size_t size)
Definition: mem.c:67
VCL_TEST_TYPE_EXIT
@ VCL_TEST_TYPE_EXIT
Definition: vcl_test.h:82
vcl_test_session::session_index
int session_index
Definition: vcl_test.h:140
vcl_test_client_main_t::incremental_stats
uint8_t incremental_stats
Definition: vcl_test_client.c:51
vcl_test_client_main_t::proto
uint8_t proto
Definition: vcl_test_client.c:50
main
int main(int argc, char **argv)
Definition: vcl_test_client.c:1019
vtc_print_stats
static void vtc_print_stats(vcl_test_session_t *ctrl)
Definition: vcl_test_client.c:399
vtc_worker_init
static int vtc_worker_init(vcl_test_client_worker_t *wrk)
Definition: vcl_test_client.c:212
VCL_TEST_TYPE_NONE
@ VCL_TEST_TYPE_NONE
Definition: vcl_test.h:78
vtc_echo_client
static void vtc_echo_client(vcl_test_client_main_t *vcm)
Definition: vcl_test_client.c:437
vcl_test_cfg_t::address_ip6
uint32_t address_ip6
Definition: vcl_test.h:103
vcl_test_main_t
Definition: vcl_test.h:171
wrk
session_worker_t * wrk
Definition: application.c:490
print_usage_and_exit
void print_usage_and_exit(void)
Definition: vcl_test_client.c:665
vtc_inc_stats_check
static void vtc_inc_stats_check(vcl_test_session_t *ts)
Definition: vcl_test_client.c:297
cfg_rxbuf_size_set
static void cfg_rxbuf_size_set(void)
Definition: vcl_test_client.c:581
vcl_test_cfg_t::rxbuf_size
uint64_t rxbuf_size
Definition: vcl_test.h:105
vcl_test_client_worker_t::thread_handle
pthread_t thread_handle
Definition: vcl_test_client.c:38
vcl_client_main
vcl_test_client_main_t vcl_client_main
Definition: vcl_test_client.c:58
vcl_test_cfg_t::test
uint32_t test
Definition: vcl_test.h:96
vcl_test_client_worker_t::n_sessions
uint32_t n_sessions
Definition: vcl_test_client.c:33
vcl_test_time_diff
static double vcl_test_time_diff(struct timespec *old, struct timespec *new)
Definition: vcl_test.h:402
vcl_test_proto_vft_t::open
int(* open)(vcl_test_session_t *ts, vppcom_endpt_t *endpt)
Definition: vcl_test.h:158
VCL_TEST_TOKEN_NUM_WRITES
#define VCL_TEST_TOKEN_NUM_WRITES
Definition: vcl_test.h:54
cfg_num_writes_set
static void cfg_num_writes_set(void)
Definition: vcl_test_client.c:540
vcl_test_cfg_dump
static void vcl_test_cfg_dump(vcl_test_cfg_t *cfg, uint8_t is_client)
Definition: vcl_test.h:298
vtc_worker_loop
static void * vtc_worker_loop(void *arg)
Definition: vcl_test_client.c:312
VCL_TEST_TOKEN_TXBUF_SIZE
#define VCL_TEST_TOKEN_TXBUF_SIZE
Definition: vcl_test.h:52
vcl_test_cfg_t::ctrl_handle
uint32_t ctrl_handle
Definition: vcl_test.h:98
vcl_test_client_worker_t::rd_fdset
fd_set rd_fdset
Definition: vcl_test_client.c:36
vcl_test.h
vcl_test_session::rxbuf
char * rxbuf
Definition: vcl_test.h:136
vcl_test_client_main_t::post_test
vcl_test_t post_test
Definition: vcl_test_client.c:49
VCL_TEST_TOKEN_RUN_BI
#define VCL_TEST_TOKEN_RUN_BI
Definition: vcl_test.h:58
stats_lock
static int stats_lock
Definition: vcl_test_client.c:243
dump_help
static void dump_help(void)
Definition: vcl_test.h:566
vcl_test_stats_t::tx_bytes
uint64_t tx_bytes
Definition: vcl_test.h:118
VCL_TEST_TOKEN_HELP
#define VCL_TEST_TOKEN_HELP
Definition: vcl_test.h:49
parse_input
static vcl_test_t parse_input()
Definition: vcl_test_client.c:612
vcl_test_main_t::wrk
vcl_test_wrk_t * wrk
Definition: vcl_test.h:176
vcl_test_cfg_t::num_test_qsessions
uint32_t num_test_qsessions
Definition: vcl_test.h:101
VCL_TEST_TOKEN_SHOW_CFG
#define VCL_TEST_TOKEN_SHOW_CFG
Definition: vcl_test.h:56
vtc_worker_test_setup
static int vtc_worker_test_setup(vcl_test_client_worker_t *wrk)
Definition: vcl_test_client.c:172
cfg_num_test_sessions_set
static void cfg_num_test_sessions_set(void)
Definition: vcl_test_client.c:560
vcl_test_wrk_t
Definition: vcl_test.h:164
VCL_TEST_TYPE_ECHO
@ VCL_TEST_TYPE_ECHO
Definition: vcl_test.h:79
vcl_test_session
Definition: vcl_test.h:125
vcl_test_session::is_done
uint8_t is_done
Definition: vcl_test.h:129
vtc_connect_test_sessions
static int vtc_connect_test_sessions(vcl_test_client_worker_t *wrk)
Definition: vcl_test_client.c:120
vcl_test_stats_t::start
struct timespec start
Definition: vcl_test.h:121
vterr
#define vterr(_fn, _rv)
Definition: vcl_test.h:34
vcl_test_session_buf_alloc
static void vcl_test_session_buf_alloc(vcl_test_session_t *ts)
Definition: vcl_test.h:253
vtc_ctrl_session_init
static int vtc_ctrl_session_init(vcl_test_client_main_t *vcm, vcl_test_session_t *ctrl)
Definition: vcl_test_client.c:956
vcl_test_session::write
int(* write)(struct vcl_test_session *ts, void *buf, uint32_t buflen)
Definition: vcl_test.h:132
c
svmdb_client_t * c
Definition: vpp_get_metrics.c:48
vcl_test_buf_alloc
static void vcl_test_buf_alloc(vcl_test_cfg_t *cfg, uint8_t is_rxbuf, uint8_t **buf, uint32_t *bufsize)
Definition: vcl_test.h:230
vcl_test_stats_t::stop
struct timespec stop
Definition: vcl_test.h:122
vtc_min
#define vtc_min(a, b)
Definition: vcl_test_client.c:60
vcl_test_client_worker_t::qsessions
vcl_test_session_t * qsessions
Definition: vcl_test_client.c:32
vcl_test_session_buf_free
static void vcl_test_session_buf_free(vcl_test_session_t *ts)
Definition: vcl_test.h:264
vtc_stream_client
static void vtc_stream_client(vcl_test_client_main_t *vcm)
Definition: vcl_test_client.c:457
vcl_test_t
vcl_test_t
Definition: vcl_test.h:76
time.h
vcl_test_cfg_t::num_test_sessions_perq
uint32_t num_test_sessions_perq
Definition: vcl_test.h:100
vcl_test_client_main_t::active_workers
volatile int active_workers
Definition: vcl_test_client.c:53
vcl_test_stats_dump
static void vcl_test_stats_dump(char *header, vcl_test_stats_t *stats, uint8_t show_rx, uint8_t show_tx, uint8_t verbose)
Definition: vcl_test.h:336
vcl_test_client_worker_t::sessions
vcl_test_session_t * sessions
Definition: vcl_test_client.c:31
vcl_test_client_main_t::test_running
volatile int test_running
Definition: vcl_test_client.c:54
vcl_test_cfg_t::txbuf_size
uint64_t txbuf_size
Definition: vcl_test.h:106
VCL_TEST_TYPE_BI
@ VCL_TEST_TYPE_BI
Definition: vcl_test.h:81
vcl_test_client_worker_t
Definition: vcl_test_client.c:29
VCL_TEST_CMD_STOP
@ VCL_TEST_CMD_STOP
Definition: vcl_test.h:89
vcl_test_cfg_t::total_bytes
uint64_t total_bytes
Definition: vcl_test.h:108
vcl_test_session::read
int(* read)(struct vcl_test_session *ts, void *buf, uint32_t buflen)
Definition: vcl_test.h:131
vcl_test_client_main_t::server_endpt
vppcom_endpt_t server_endpt
Definition: vcl_test_client.c:46
VCL_TEST_CFG_BUF_SIZE_MIN
#define VCL_TEST_CFG_BUF_SIZE_MIN
Definition: vcl_test.h:67
vcl_test_main_t::protos
const vcl_test_proto_vft_t * protos[VPPCOM_PROTO_SRTP+1]
Definition: vcl_test.h:173
vcl_test_cfg_t::num_test_sessions
uint32_t num_test_sessions
Definition: vcl_test.h:99
vcl_test_session::txbuf
char * txbuf
Definition: vcl_test.h:135
vcl_test_cfg_t::verbose
uint32_t verbose
Definition: vcl_test.h:102
vcl_test_client_worker_t::cfg
vcl_test_cfg_t cfg
Definition: vcl_test_client.c:39
vt_incercept_sigs
static void vt_incercept_sigs(void)
Definition: vcl_test_client.c:1004
vtc_worker_sessions_exit
static void vtc_worker_sessions_exit(vcl_test_client_worker_t *wrk)
Definition: vcl_test_client.c:281
VCL_TEST_SEPARATOR_STRING
#define VCL_TEST_SEPARATOR_STRING
Definition: vcl_test.h:74
vcl_test_client_worker_t::wrk_index
uint32_t wrk_index
Definition: vcl_test_client.c:34
vcl_test_session::stats
vcl_test_stats_t stats
Definition: vcl_test.h:138
vcl_test_session::fd
int fd
Definition: vcl_test.h:130
vcl_test_client_main_t::dump_cfg
uint8_t dump_cfg
Definition: vcl_test_client.c:48
VCL_TEST_CFG_MAX_TEST_SESS
#define VCL_TEST_CFG_MAX_TEST_SESS
Definition: vcl_test.h:68
vcl_test_client_worker_t::max_fd_index
int max_fd_index
Definition: vcl_test_client.c:37
vcl_test_stats_dump_inc
static void vcl_test_stats_dump_inc(vcl_test_session_t *ts, int is_rx)
Definition: vcl_test.h:419
vt_sigs_handler
static void vt_sigs_handler(int signum, siginfo_t *si, void *uc)
Definition: vcl_test_client.c:994
vcl_test_session::rxbuf_size
uint32_t rxbuf_size
Definition: vcl_test.h:134
vcl_test_client_main_t::server_addr
struct sockaddr_storage server_addr
Definition: vcl_test_client.c:55
vcl_test_stats_t::rx_bytes
uint64_t rx_bytes
Definition: vcl_test.h:114
vtc_max
#define vtc_max(a, b)
Definition: vcl_test_client.c:61
vt_atomic_add
#define vt_atomic_add(_ptr, _val)
Definition: vcl_test.h:46
vcl_test_main
vcl_test_main_t vcl_test_main
Definition: vcl_test_client.c:63
cfg_txbuf_size_set
static void cfg_txbuf_size_set(void)
Definition: vcl_test_client.c:519
buf
u64 buf
Definition: application.c:493
vcl_test_client_worker_t::wr_fdset
fd_set wr_fdset
Definition: vcl_test_client.c:35
vcl_test_stats_accumulate
static void vcl_test_stats_accumulate(vcl_test_stats_t *accum, vcl_test_stats_t *incr)
Definition: vcl_test.h:188
vcl_test_cfg_verify
static int vcl_test_cfg_verify(vcl_test_cfg_t *cfg, vcl_test_cfg_t *valid_cfg)
Definition: vcl_test.h:216
si
vnet_sw_interface_t * si
Definition: interface_output.c:418
vtc_accumulate_stats
static void vtc_accumulate_stats(vcl_test_client_worker_t *wrk, vcl_test_session_t *ctrl)
Definition: vcl_test_client.c:246
vtwrn
#define vtwrn(_fmt, _args...)
Definition: vcl_test.h:40
VCL_TEST_TOKEN_EXIT
#define VCL_TEST_TOKEN_EXIT
Definition: vcl_test.h:50
vtc_read_user_input
static void vtc_read_user_input(vcl_test_session_t *ctrl)
Definition: vcl_test_client.c:921
now
f64 now
Definition: nat44_ei_out2in.c:710
VCL_TEST_TOKEN_VERBOSE
#define VCL_TEST_TOKEN_VERBOSE
Definition: vcl_test.h:51
session_worker_::sessions
session_t * sessions
Worker session pool.
Definition: session.h:92
vcl_test_client_main_t::workers
vcl_test_client_worker_t * workers
Definition: vcl_test_client.c:44
calloc
void * calloc(size_t nmemb, size_t size)
Definition: mem.c:54
VCL_TEST_TOKEN_RXBUF_SIZE
#define VCL_TEST_TOKEN_RXBUF_SIZE
Definition: vcl_test.h:55
vtinf
#define vtinf(_fmt, _args...)
Definition: vcl_test.h:43
vcl_test_client_main_t::n_workers
uint32_t n_workers
Definition: vcl_test_client.c:52
i
int i
Definition: flowhash_template.h:376
vtc_process_opts
static void vtc_process_opts(vcl_test_client_main_t *vcm, int argc, char **argv)
Definition: vcl_test_client.c:694
free
void free(void *p)
Definition: mem.c:42
VCL_TEST_CMD_SYNC
@ VCL_TEST_CMD_SYNC
Definition: vcl_test.h:87
VCL_TEST_CFG_CTRL_MAGIC
#define VCL_TEST_CFG_CTRL_MAGIC
Definition: vcl_test.h:63
vcl_test_cfg_init
static void vcl_test_cfg_init(vcl_test_cfg_t *cfg)
Definition: vcl_test.h:201
VCL_TEST_TOKEN_RUN_UNI
#define VCL_TEST_TOKEN_RUN_UNI
Definition: vcl_test.h:57
rv
int __clib_unused rv
Definition: application.c:491
vcl_test_session::cfg
vcl_test_cfg_t cfg
Definition: vcl_test.h:137
vcl_test_write
static int vcl_test_write(vcl_test_session_t *ts, void *buf, uint32_t nbytes)
Definition: vcl_test.h:530
vcl_test_cfg_t
Definition: vcl_test.h:92
cfg_verbose_toggle
static void cfg_verbose_toggle(void)
Definition: vcl_test_client.c:601
vcl_test_cfg_t::cmd
uint32_t cmd
Definition: vcl_test.h:97
vcl_comp_tspec
static int vcl_comp_tspec(struct timespec *a, struct timespec *b)
Definition: vcl_test.h:447
vcl_test_stats_t
Definition: vcl_test.h:111
vcl_test_proto_vft_t::init
int(* init)(vcl_test_cfg_t *cfg)
Definition: vcl_test.h:157
VCL_TEST_CMD_START
@ VCL_TEST_CMD_START
Definition: vcl_test.h:88
vcl_test_client_main_t::cfg_seq_num
uint32_t cfg_seq_num
Definition: vcl_test_client.c:47
vtc_ctrl_session_exit
static void vtc_ctrl_session_exit(void)
Definition: vcl_test_client.c:941
vcl_test_cfg_t::num_writes
uint64_t num_writes
Definition: vcl_test.h:107
vcl_test_session::txbuf_size
uint32_t txbuf_size
Definition: vcl_test.h:133
vtfail
#define vtfail(_fn, _rv)
Definition: vcl_test.h:26
vcl_test_proto_vft_t
Definition: vcl_test.h:155
VCL_TEST_TOKEN_NUM_TEST_SESS
#define VCL_TEST_TOKEN_NUM_TEST_SESS
Definition: vcl_test.h:53
vcl_test_read
static int vcl_test_read(vcl_test_session_t *ts, void *buf, uint32_t nbytes)
Definition: vcl_test.h:462
VCL_TEST_TYPE_UNI
@ VCL_TEST_TYPE_UNI
Definition: vcl_test.h:80
VCL_TEST_DELAY_DISCONNECT
#define VCL_TEST_DELAY_DISCONNECT
Definition: vcl_test.h:73