FD.io VPP  v20.01-48-g3e0dafb74
Vector Packet Processing
cli.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 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  * pg_cli.c: packet generator cli
17  *
18  * Copyright (c) 2008 Eliot Dresselhaus
19  *
20  * Permission is hereby granted, free of charge, to any person obtaining
21  * a copy of this software and associated documentation files (the
22  * "Software"), to deal in the Software without restriction, including
23  * without limitation the rights to use, copy, modify, merge, publish,
24  * distribute, sublicense, and/or sell copies of the Software, and to
25  * permit persons to whom the Software is furnished to do so, subject to
26  * the following conditions:
27  *
28  * The above copyright notice and this permission notice shall be
29  * included in all copies or substantial portions of the Software.
30  *
31  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38  */
39 
40 #include <sys/stat.h>
41 
42 #include <vnet/vnet.h>
43 #include <vnet/pg/pg.h>
44 
45 #include <strings.h>
46 #include <vppinfra/pcap.h>
47 
48 
49 /* Root of all packet generator cli commands. */
50 /* *INDENT-OFF* */
51 VLIB_CLI_COMMAND (vlib_cli_pg_command, static) = {
52  .path = "packet-generator",
53  .short_help = "Packet generator commands",
54 };
55 /* *INDENT-ON* */
56 
57 void
58 pg_enable_disable (u32 stream_index, int is_enable)
59 {
60  pg_main_t *pg = &pg_main;
61  pg_stream_t *s;
62 
63  if (stream_index == ~0)
64  {
65  /* No stream specified: enable/disable all streams. */
66  /* *INDENT-OFF* */
67  pool_foreach (s, pg->streams, ({
68  pg_stream_enable_disable (pg, s, is_enable);
69  }));
70  /* *INDENT-ON* */
71  }
72  else
73  {
74  /* enable/disable specified stream. */
75  s = pool_elt_at_index (pg->streams, stream_index);
76  pg_stream_enable_disable (pg, s, is_enable);
77  }
78 }
79 
82 {
83  pg_main_t *pg = &pg_main;
84  pg_interface_t *pi;
85 
86  if (a->is_enabled == 1)
87  {
88  struct stat sb;
89  if (stat ((char *) a->pcap_file_name, &sb) != -1)
90  return clib_error_return (0, "pcap file '%s' already exists.",
91  a->pcap_file_name);
92  }
93 
97  pcap_close (&pi->pcap_main);
98  clib_memset (&pi->pcap_main, 0, sizeof (pi->pcap_main));
99  pi->pcap_main.file_descriptor = -1;
100 
101  if (a->is_enabled == 0)
102  return 0;
103 
105  pi->pcap_main.file_name = (char *) pi->pcap_file_name;
107  pi->pcap_main.packet_type = PCAP_PACKET_TYPE_ethernet;
108 
109  return 0;
110 }
111 
112 static clib_error_t *
114  unformat_input_t * input, vlib_cli_command_t * cmd)
115 {
116  unformat_input_t _line_input, *line_input = &_line_input;
117  pg_main_t *pg = &pg_main;
118  int is_enable = cmd->function_arg != 0;
119  u32 stream_index = ~0;
120 
121  if (!unformat_user (input, unformat_line_input, line_input))
122  goto doit;
123 
124  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
125  {
126  if (unformat (line_input, "%U", unformat_hash_vec_string,
127  pg->stream_index_by_name, &stream_index))
128  ;
129  else
130  return clib_error_create ("unknown input `%U'",
131  format_unformat_error, line_input);
132  }
133  unformat_free (line_input);
134 
135 doit:
136  pg_enable_disable (stream_index, is_enable);
137 
138  return 0;
139 }
140 
141 /* *INDENT-OFF* */
142 VLIB_CLI_COMMAND (enable_streams_cli, static) = {
143  .path = "packet-generator enable-stream",
144  .short_help = "Enable packet generator streams",
145  .function = enable_disable_stream,
146  .function_arg = 1, /* is_enable */
147 };
148 /* *INDENT-ON* */
149 
150 /* *INDENT-OFF* */
151 VLIB_CLI_COMMAND (disable_streams_cli, static) = {
152  .path = "packet-generator disable-stream",
153  .short_help = "Disable packet generator streams",
154  .function = enable_disable_stream,
155  .function_arg = 0, /* is_enable */
156 };
157 /* *INDENT-ON* */
158 
159 static u8 *
160 format_pg_edit_group (u8 * s, va_list * va)
161 {
162  pg_edit_group_t *g = va_arg (*va, pg_edit_group_t *);
163 
164  s =
165  format (s, "hdr-size %d, offset %d, ", g->n_packet_bytes,
166  g->start_byte_offset);
167  if (g->edit_function)
168  {
169  u8 *function_name;
170  u8 *junk_after_name;
171  function_name = format (0, "%U%c", format_clib_elf_symbol_with_address,
172  g->edit_function, 0);
173  junk_after_name = function_name;
174  while (*junk_after_name && *junk_after_name != ' ')
175  junk_after_name++;
176  *junk_after_name = 0;
177  s = format (s, "edit-function %s, ", function_name);
178  vec_free (function_name);
179  }
180 
181  return s;
182 }
183 
184 static u8 *
185 format_pg_stream (u8 * s, va_list * va)
186 {
187  pg_stream_t *t = va_arg (*va, pg_stream_t *);
188  int verbose = va_arg (*va, int);
189 
190  if (!t)
191  return format (s, "%-16s%=12s%=16s%s",
192  "Name", "Enabled", "Count", "Parameters");
193 
194  s = format (s, "%-16v%=12s%=16Ld",
195  t->name,
196  pg_stream_is_enabled (t) ? "Yes" : "No",
198 
199  int indent = format_get_indent (s);
200 
201  s = format (s, "limit %Ld, ", t->n_packets_limit);
202  s = format (s, "rate %.2e pps, ", t->rate_packets_per_second);
203  s = format (s, "size %d%c%d, ",
204  t->min_packet_bytes,
205  t->packet_size_edit_type == PG_EDIT_RANDOM ? '+' : '-',
206  t->max_packet_bytes);
207  s = format (s, "buffer-size %d, ", t->buffer_bytes);
208  s = format (s, "worker %d, ", t->worker_index);
209 
210  if (verbose)
211  {
212  pg_edit_group_t *g;
213  /* *INDENT-OFF* */
214  vec_foreach (g, t->edit_groups)
215  {
216  s = format (s, "\n%U%U", format_white_space, indent, format_pg_edit_group, g);
217  }
218  /* *INDENT-ON* */
219  }
220 
221  return s;
222 }
223 
224 static clib_error_t *
226  unformat_input_t * input, vlib_cli_command_t * cmd)
227 {
228  pg_main_t *pg = &pg_main;
229  pg_stream_t *s;
230  int verbose = 0;
231 
233  {
234  if (unformat (input, "verbose"))
235  verbose = 1;
236  else
237  break;
238  }
239 
240  if (pool_elts (pg->streams) == 0)
241  {
242  vlib_cli_output (vm, "no streams currently defined");
243  goto done;
244  }
245 
246  vlib_cli_output (vm, "%U", format_pg_stream, 0, 0);
247  /* *INDENT-OFF* */
248  pool_foreach (s, pg->streams, ({
249  vlib_cli_output (vm, "%U", format_pg_stream, s, verbose);
250  }));
251  /* *INDENT-ON* */
252 
253 done:
254  return 0;
255 }
256 
257 /* *INDENT-OFF* */
258 VLIB_CLI_COMMAND (show_streams_cli, static) = {
259  .path = "show packet-generator ",
260  .short_help = "show packet-generator [verbose]",
261  .function = show_streams,
262 };
263 /* *INDENT-ON* */
264 
265 static clib_error_t *
266 pg_pcap_read (pg_stream_t * s, char *file_name)
267 {
268 #ifndef CLIB_UNIX
269  return clib_error_return (0, "no pcap support");
270 #else
271  pcap_main_t pm;
272  clib_error_t *error;
273  clib_memset (&pm, 0, sizeof (pm));
274  pm.file_name = file_name;
275  error = pcap_read (&pm);
281 
282  if (s->n_packets_limit == 0)
284 
285  return error;
286 #endif /* CLIB_UNIX */
287 }
288 
289 static uword
291 {
292  pg_stream_t *s = va_arg (*args, pg_stream_t *);
293  f64 x;
294 
295  if (unformat (input, "limit %f", &x))
296  s->n_packets_limit = x;
297 
298  else if (unformat (input, "rate %f", &x))
300 
301  else if (unformat (input, "size %d-%d", &s->min_packet_bytes,
302  &s->max_packet_bytes))
304 
305  else if (unformat (input, "size %d+%d", &s->min_packet_bytes,
306  &s->max_packet_bytes))
308 
309  else if (unformat (input, "buffer-size %d", &s->buffer_bytes))
310  ;
311 
312  else
313  return 0;
314 
315  return 1;
316 }
317 
318 static clib_error_t *
320 {
322  return clib_error_create ("max-size < min-size");
323 
324  u32 hdr_size = pg_edit_group_n_bytes (s, 0);
325  if (s->min_packet_bytes < hdr_size)
326  return clib_error_create ("min-size < total header size %d", hdr_size);
327  if (s->buffer_bytes == 0)
328  return clib_error_create ("buffer-size must be positive");
329 
330  if (s->rate_packets_per_second < 0)
331  return clib_error_create ("negative rate");
332 
333  return 0;
334 }
335 
336 static clib_error_t *
338  unformat_input_t * input, vlib_cli_command_t * cmd)
339 {
340  clib_error_t *error = 0;
341  u8 *tmp = 0;
342  u32 maxframe, hw_if_index;
343  unformat_input_t sub_input = { 0 };
344  int sub_input_given = 0;
345  vnet_main_t *vnm = vnet_get_main ();
346  pg_main_t *pg = &pg_main;
347  pg_stream_t s = { 0 };
348  char *pcap_file_name;
349 
350  s.sw_if_index[VLIB_RX] = s.sw_if_index[VLIB_TX] = ~0;
351  s.node_index = ~0;
354  s.if_id = 0;
356  pcap_file_name = 0;
357 
359  {
360  if (unformat (input, "name %v", &tmp))
361  {
362  if (s.name)
363  vec_free (s.name);
364  s.name = tmp;
365  }
366 
367  else if (unformat (input, "node %U",
368  unformat_vnet_hw_interface, vnm, &hw_if_index))
369  {
370  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
371 
374  }
375 
376  else if (unformat (input, "source pg%u", &s.if_id))
377  ;
378 
379  else if (unformat (input, "node %U",
381  ;
382  else if (unformat (input, "maxframe %u", &maxframe))
383  s.n_max_frame = s.n_max_frame < maxframe ? s.n_max_frame : maxframe;
384  else if (unformat (input, "worker %u", &s.worker_index))
385  ;
386 
387  else if (unformat (input, "interface %U",
389  &s.sw_if_index[VLIB_RX]))
390  ;
391  else if (unformat (input, "tx-interface %U",
393  &s.sw_if_index[VLIB_TX]))
394  ;
395 
396  else if (unformat (input, "pcap %s", &pcap_file_name))
397  ;
398 
399  else if (!sub_input_given
400  && unformat (input, "data %U", unformat_input, &sub_input))
401  sub_input_given++;
402 
403  else if (unformat_user (input, unformat_pg_stream_parameter, &s))
404  ;
405 
406  else
407  {
408  error = clib_error_create ("unknown input `%U'",
409  format_unformat_error, input);
410  goto done;
411  }
412  }
413 
414  if (!sub_input_given && !pcap_file_name)
415  {
416  error = clib_error_create ("no packet data given");
417  goto done;
418  }
419 
420  if (s.node_index == ~0)
421  {
422  if (pcap_file_name != 0)
423  {
424  vlib_node_t *n =
425  vlib_get_node_by_name (vm, (u8 *) "ethernet-input");
426  s.node_index = n->index;
427  }
428  else
429  {
430  error = clib_error_create ("output interface or node not given");
431  goto done;
432  }
433  }
434 
435  {
436  pg_node_t *n;
437 
438  if (s.node_index < vec_len (pg->nodes))
439  n = pg->nodes + s.node_index;
440  else
441  n = 0;
442 
443  if (s.worker_index >= vlib_num_workers ())
444  s.worker_index = 0;
445 
446  if (pcap_file_name != 0)
447  {
448  error = pg_pcap_read (&s, pcap_file_name);
449  if (error)
450  goto done;
451  vec_free (pcap_file_name);
452  }
453 
454  else if (n && n->unformat_edit
455  && unformat_user (&sub_input, n->unformat_edit, &s))
456  ;
457 
458  else if (!unformat_user (&sub_input, unformat_pg_payload, &s))
459  {
460  error = clib_error_create
461  ("failed to parse packet data from `%U'",
462  format_unformat_error, &sub_input);
463  goto done;
464  }
465  }
466 
467  error = validate_stream (&s);
468  if (error)
469  return error;
470 
471  pg_stream_add (pg, &s);
472  return 0;
473 
474 done:
475  pg_stream_free (&s);
476  unformat_free (&sub_input);
477  return error;
478 }
479 
480 /* *INDENT-OFF* */
481 VLIB_CLI_COMMAND (new_stream_cli, static) = {
482  .path = "packet-generator new",
483  .function = new_stream,
484  .short_help = "Create packet generator stream",
485  .long_help =
486  "Create packet generator stream\n"
487  "\n"
488  "Arguments:\n"
489  "\n"
490  "name STRING sets stream name\n"
491  "interface STRING interface for stream output \n"
492  "node NODE-NAME node for stream output\n"
493  "data STRING specifies packet data\n"
494  "pcap FILENAME read packet data from pcap file\n"
495  "rate PPS rate to transfer packet data\n"
496  "maxframe NPKTS maximum number of packets per frame\n",
497 };
498 /* *INDENT-ON* */
499 
500 static clib_error_t *
502  unformat_input_t * input, vlib_cli_command_t * cmd)
503 {
504  pg_main_t *pg = &pg_main;
505  u32 i;
506 
507  if (!unformat (input, "%U",
509  return clib_error_create ("expected stream name `%U'",
510  format_unformat_error, input);
511 
512  pg_stream_del (pg, i);
513  return 0;
514 }
515 
516 /* *INDENT-OFF* */
517 VLIB_CLI_COMMAND (del_stream_cli, static) = {
518  .path = "packet-generator delete",
519  .function = del_stream,
520  .short_help = "Delete stream with given name",
521 };
522 /* *INDENT-ON* */
523 
524 static clib_error_t *
526  unformat_input_t * input, vlib_cli_command_t * cmd)
527 {
528  pg_main_t *pg = &pg_main;
529  pg_stream_t *s, s_new;
530  u32 stream_index = ~0;
531  clib_error_t *error;
532 
533  if (unformat (input, "%U", unformat_hash_vec_string,
534  pg->stream_index_by_name, &stream_index))
535  ;
536  else
537  return clib_error_create ("expecting stream name; got `%U'",
538  format_unformat_error, input);
539 
540  s = pool_elt_at_index (pg->streams, stream_index);
541  s_new = s[0];
542 
544  {
545  if (unformat_user (input, unformat_pg_stream_parameter, &s_new))
546  ;
547 
548  else
549  return clib_error_create ("unknown input `%U'",
550  format_unformat_error, input);
551  }
552 
553  error = validate_stream (&s_new);
554  if (!error)
555  {
556  s[0] = s_new;
557  pg_stream_change (pg, s);
558  }
559 
560  return error;
561 }
562 
563 /* *INDENT-OFF* */
564 VLIB_CLI_COMMAND (change_stream_parameters_cli, static) = {
565  .path = "packet-generator configure",
566  .short_help = "Change packet generator stream parameters",
567  .function = change_stream_parameters,
568 };
569 /* *INDENT-ON* */
570 
571 static clib_error_t *
573  unformat_input_t * input, vlib_cli_command_t * cmd)
574 {
575  clib_error_t *error = 0;
576  vnet_main_t *vnm = vnet_get_main ();
577  unformat_input_t _line_input, *line_input = &_line_input;
578  vnet_hw_interface_t *hi = 0;
579  u8 *pcap_file_name = 0;
580  u32 hw_if_index;
581  u32 is_disable = 0;
582  u32 count = ~0;
583 
584  if (!unformat_user (input, unformat_line_input, line_input))
585  return 0;
586 
587  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
588  {
589  if (unformat (line_input, "%U",
590  unformat_vnet_hw_interface, vnm, &hw_if_index))
591  {
592  hi = vnet_get_hw_interface (vnm, hw_if_index);
593  }
594 
595  else if (unformat (line_input, "pcap %s", &pcap_file_name))
596  ;
597  else if (unformat (line_input, "count %u", &count))
598  ;
599  else if (unformat (line_input, "disable"))
600  is_disable = 1;
601 
602  else
603  {
604  error = clib_error_create ("unknown input `%U'",
605  format_unformat_error, line_input);
606  goto done;
607  }
608  }
609 
610  if (!hi)
611  {
612  error = clib_error_return (0, "Please specify interface name");
613  goto done;
614  }
615 
616  if (hi->dev_class_index != pg_dev_class.index)
617  {
618  error =
619  clib_error_return (0, "Please specify packet-generator interface");
620  goto done;
621  }
622 
623  if (!pcap_file_name && is_disable == 0)
624  {
625  error = clib_error_return (0, "Please specify pcap file name");
626  goto done;
627  }
628 
629 
630  pg_capture_args_t _a, *a = &_a;
631 
632  a->hw_if_index = hw_if_index;
633  a->dev_instance = hi->dev_instance;
634  a->is_enabled = !is_disable;
635  a->pcap_file_name = pcap_file_name;
636  a->count = count;
637 
638  error = pg_capture (a);
639 
640 done:
641  unformat_free (line_input);
642 
643  return error;
644 }
645 
646 /* *INDENT-OFF* */
647 VLIB_CLI_COMMAND (pg_capture_cmd, static) = {
648  .path = "packet-generator capture",
649  .short_help = "packet-generator capture <interface name> pcap <filename> [count <n>]",
650  .function = pg_capture_cmd_fn,
651 };
652 /* *INDENT-ON* */
653 
654 static clib_error_t *
656  unformat_input_t * input, vlib_cli_command_t * cmd)
657 {
658  pg_main_t *pg = &pg_main;
659  unformat_input_t _line_input, *line_input = &_line_input;
660  u32 if_id, gso_enabled = 0, gso_size = 0;
661  clib_error_t *error = NULL;
662 
663  if (!unformat_user (input, unformat_line_input, line_input))
664  return 0;
665 
666  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
667  {
668  if (unformat (line_input, "interface pg%u", &if_id))
669  ;
670  else if (unformat (line_input, "gso-enabled"))
671  {
672  gso_enabled = 1;
673  if (unformat (line_input, "gso-size %u", &gso_size))
674  ;
675  else
676  {
677  error = clib_error_create ("gso enabled but gso size missing");
678  goto done;
679  }
680  }
681  else
682  {
683  error = clib_error_create ("unknown input `%U'",
684  format_unformat_error, line_input);
685  goto done;
686  }
687  }
688 
689  pg_interface_add_or_get (pg, if_id, gso_enabled, gso_size);
690 
691 done:
692  unformat_free (line_input);
693 
694  return error;
695 }
696 
697 /* *INDENT-OFF* */
698 VLIB_CLI_COMMAND (create_pg_if_cmd, static) = {
699  .path = "create packet-generator",
700  .short_help = "create packet-generator interface <interface name> [gso-enabled gso-size <size>]",
701  .function = create_pg_if_cmd_fn,
702 };
703 /* *INDENT-ON* */
704 
705 /* Dummy init function so that we can be linked in. */
706 static clib_error_t *
708 {
709  return 0;
710 }
711 
713 
714 /*
715  * fd.io coding-style-patch-verification: ON
716  *
717  * Local Variables:
718  * eval: (c-set-style "gnu")
719  * End:
720  */
unformat_function_t unformat_vnet_hw_interface
u8 count
Definition: dhcp.api:208
static int pg_stream_is_enabled(pg_stream_t *s)
Definition: pg.h:219
clib_error_t * pg_capture(pg_capture_args_t *a)
Definition: cli.c:81
u64 n_packets_limit
Definition: pg.h:156
void pg_stream_add(pg_main_t *pg, pg_stream_t *s_init)
Definition: stream.c:392
char * file_name
File name of pcap output.
Definition: pcap.h:162
static u8 * format_pg_edit_group(u8 *s, va_list *va)
Definition: cli.c:160
u32 flags
flags
Definition: pcap.h:174
int file_descriptor
File descriptor for reading/writing.
Definition: pcap.h:178
a
Definition: bitmap.h:538
u32 n_packets_to_capture
Number of packets to capture.
Definition: pcap.h:165
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
Definition: pg.h:318
unformat_function_t unformat_input
Definition: format.h:277
pg_edit_group_t * edit_groups
Definition: pg.h:106
static clib_error_t * pg_cli_init(vlib_main_t *vm)
Definition: cli.c:707
#define NULL
Definition: clib.h:58
PCAP utility definitions.
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
u32 index
Definition: node.h:280
void(* edit_function)(struct pg_main_t *pg, struct pg_stream_t *s, struct pg_edit_group_t *g, u32 *buffers, u32 n_buffers)
Definition: pg.h:73
uword * stream_index_by_name
Definition: pg.h:327
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
u32 max_packet_bytes
Definition: pcap.h:193
u32 worker_index
Definition: pg.h:144
u32 n_max_frame
Definition: pg.h:159
int i
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
u32 hw_if_index
Definition: pg.h:379
static u32 format_get_indent(u8 *s)
Definition: format.h:72
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
unformat_function_t unformat_vnet_sw_interface
u32 pg_interface_add_or_get(pg_main_t *pg, uword stream_index, u8 gso_enabled, u32 gso_size)
Definition: stream.c:182
pg_edit_type_t packet_size_edit_type
Definition: pg.h:108
void pg_stream_del(pg_main_t *pg, uword index)
Definition: stream.c:476
unsigned char u8
Definition: types.h:56
u32 start_byte_offset
Definition: pg.h:67
double f64
Definition: types.h:142
PCAP main state data structure.
Definition: pcap.h:156
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:498
static uword unformat_pg_stream_parameter(unformat_input_t *input, va_list *args)
Definition: cli.c:290
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:129
uword unformat_pg_payload(unformat_input_t *input, va_list *args)
Definition: edit.c:127
static clib_error_t * del_stream(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:501
u32 n_packet_bytes
Definition: pg.h:70
#define clib_error_return(e, args...)
Definition: error.h:99
unsigned int u32
Definition: types.h:88
#define clib_error_create(args...)
Definition: error.h:96
static clib_error_t * new_stream(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:337
#define VLIB_FRAME_SIZE
Definition: node.h:378
static clib_error_t * enable_disable_stream(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:113
u8 * pcap_file_name
Definition: pg.h:382
unformat_function_t unformat_line_input
Definition: format.h:283
u32 buffer_bytes
Definition: pg.h:124
clib_error_t * pcap_close(pcap_main_t *pm)
Close PCAP file.
Definition: pcap.c:74
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:519
u8 * name
Definition: pg.h:97
struct _unformat_input_t unformat_input_t
static void pg_stream_free(pg_stream_t *s)
Definition: pg.h:194
pcap_main_t pcap_main
Definition: pg.h:307
pg_node_t * nodes
Definition: pg.h:337
unformat_function_t unformat_hash_vec_string
Definition: hash.h:718
vlib_main_t * vm
Definition: in2out_ed.c:1810
clib_error_t * pcap_read(pcap_main_t *pm)
Read PCAP file.
Definition: pcap.c:176
uword function_arg
Definition: cli.h:105
static_always_inline u32 vlib_buffer_get_default_data_size(vlib_main_t *vm)
Definition: buffer_funcs.h:96
static clib_error_t * create_pg_if_cmd_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:655
u8 * pcap_file_name
Definition: pg.h:308
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
u64 * replay_packet_timestamps
Definition: pg.h:172
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:342
u32 min_packet_bytes
Definition: pg.h:111
u32 max_packet_bytes
Definition: pg.h:111
static clib_error_t * pg_pcap_read(pg_stream_t *s, char *file_name)
Definition: cli.c:266
static uword pg_edit_group_n_bytes(pg_stream_t *s, u32 group_index)
Definition: pg.h:273
void pg_stream_change(pg_main_t *pg, pg_stream_t *s)
Definition: stream.c:496
unformat_function_t * unformat_edit
Definition: pg.h:315
static u8 * format_pg_stream(u8 *s, va_list *va)
Definition: cli.c:185
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
u8 ** replay_packet_templates
Definition: pg.h:171
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:152
pg_stream_t * streams
Definition: pg.h:321
static clib_error_t * validate_stream(pg_stream_t *s)
Definition: cli.c:319
static clib_error_t * pg_capture_cmd_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:572
#define PCAP_MAIN_INIT_DONE
Definition: pcap.h:175
void pg_enable_disable(u32 stream_index, int is_enable)
Definition: cli.c:58
void pg_stream_enable_disable(pg_main_t *pg, pg_stream_t *s, int is_enable)
Definition: stream.c:49
static clib_error_t * show_streams(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:225
Definition: pg.h:94
u32 min_packet_bytes
Min/Max Packet bytes.
Definition: pcap.h:193
vl_api_ip4_address_t hi
Definition: arp.api:37
u64 * timestamps
Timestamps.
Definition: pcap.h:190
pcap_packet_type_t packet_type
Packet type.
Definition: pcap.h:168
u32 node_index
Definition: pg.h:141
Definition: defs.h:47
u32 sw_if_index[VLIB_N_RX_TX]
Definition: pg.h:138
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u32 if_id
Definition: pg.h:149
u64 uword
Definition: types.h:112
static void unformat_free(unformat_input_t *i)
Definition: format.h:163
unformat_function_t unformat_vlib_node
Definition: node_funcs.h:1147
format_function_t format_clib_elf_symbol_with_address
Definition: elf_clib.h:134
u32 dev_instance
Definition: pg.h:380
f64 rate_packets_per_second
Definition: pg.h:163
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
static u32 vlib_num_workers()
Definition: threads.h:372
u64 n_packets_generated
Definition: pg.h:152
pg_main_t pg_main
Definition: init.c:44
u8 is_enabled
Definition: pg.h:381
#define vec_foreach(var, vec)
Vector iterator.
u8 ** packets_read
Packets read from file.
Definition: pcap.h:187
vnet_device_class_t pg_dev_class
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:689
static clib_error_t * change_stream_parameters(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:525
Definition: pg.h:312
pg_interface_t * interfaces
Definition: pg.h:330
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
Definition: defs.h:46
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:171
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128