FD.io VPP  v20.05-21-gb1500e9ff
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 (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, "buffer-flags %U",
381  ;
382 
383  else if (unformat (input, "node %U",
385  ;
386  else if (unformat (input, "maxframe %u", &maxframe))
387  s.n_max_frame = s.n_max_frame < maxframe ? s.n_max_frame : maxframe;
388  else if (unformat (input, "worker %u", &s.worker_index))
389  ;
390 
391  else if (unformat (input, "interface %U",
393  &s.sw_if_index[VLIB_RX]))
394  ;
395  else if (unformat (input, "tx-interface %U",
397  &s.sw_if_index[VLIB_TX]))
398  ;
399 
400  else if (unformat (input, "pcap %s", &pcap_file_name))
401  ;
402 
403  else if (!sub_input_given
404  && unformat (input, "data %U", unformat_input, &sub_input))
405  sub_input_given++;
406 
407  else if (unformat_user (input, unformat_pg_stream_parameter, &s))
408  ;
409 
410  else
411  {
412  error = clib_error_create ("unknown input `%U'",
413  format_unformat_error, input);
414  goto done;
415  }
416  }
417 
418  if (!sub_input_given && !pcap_file_name)
419  {
420  error = clib_error_create ("no packet data given");
421  goto done;
422  }
423 
424  if (s.node_index == ~0)
425  {
426  if (pcap_file_name != 0)
427  {
428  vlib_node_t *n =
429  vlib_get_node_by_name (vm, (u8 *) "ethernet-input");
430  s.node_index = n->index;
431  }
432  else
433  {
434  error = clib_error_create ("output interface or node not given");
435  goto done;
436  }
437  }
438 
439  {
440  pg_node_t *n;
441 
442  if (s.node_index < vec_len (pg->nodes))
443  n = pg->nodes + s.node_index;
444  else
445  n = 0;
446 
447  if (s.worker_index >= vlib_num_workers ())
448  s.worker_index = 0;
449 
450  if (pcap_file_name != 0)
451  {
452  error = pg_pcap_read (&s, pcap_file_name);
453  if (error)
454  goto done;
455  vec_free (pcap_file_name);
456  }
457 
458  else if (n && n->unformat_edit
459  && unformat_user (&sub_input, n->unformat_edit, &s))
460  ;
461 
462  else if (!unformat_user (&sub_input, unformat_pg_payload, &s))
463  {
464  error = clib_error_create
465  ("failed to parse packet data from `%U'",
466  format_unformat_error, &sub_input);
467  goto done;
468  }
469  }
470 
471  error = validate_stream (&s);
472  if (error)
473  return error;
474 
475  pg_stream_add (pg, &s);
476  return 0;
477 
478 done:
479  pg_stream_free (&s);
480  unformat_free (&sub_input);
481  return error;
482 }
483 
484 /* *INDENT-OFF* */
485 VLIB_CLI_COMMAND (new_stream_cli, static) = {
486  .path = "packet-generator new",
487  .function = new_stream,
488  .short_help = "Create packet generator stream",
489  .long_help =
490  "Create packet generator stream\n"
491  "\n"
492  "Arguments:\n"
493  "\n"
494  "name STRING sets stream name\n"
495  "interface STRING interface for stream output \n"
496  "node NODE-NAME node for stream output\n"
497  "data STRING specifies packet data\n"
498  "pcap FILENAME read packet data from pcap file\n"
499  "rate PPS rate to transfer packet data\n"
500  "maxframe NPKTS maximum number of packets per frame\n",
501 };
502 /* *INDENT-ON* */
503 
504 static clib_error_t *
506  unformat_input_t * input, vlib_cli_command_t * cmd)
507 {
508  pg_main_t *pg = &pg_main;
509  u32 i;
510 
511  if (!unformat (input, "%U",
513  return clib_error_create ("expected stream name `%U'",
514  format_unformat_error, input);
515 
516  pg_stream_del (pg, i);
517  return 0;
518 }
519 
520 /* *INDENT-OFF* */
521 VLIB_CLI_COMMAND (del_stream_cli, static) = {
522  .path = "packet-generator delete",
523  .function = del_stream,
524  .short_help = "Delete stream with given name",
525 };
526 /* *INDENT-ON* */
527 
528 static clib_error_t *
530  unformat_input_t * input, vlib_cli_command_t * cmd)
531 {
532  pg_main_t *pg = &pg_main;
533  pg_stream_t *s, s_new;
534  u32 stream_index = ~0;
535  clib_error_t *error;
536 
537  if (unformat (input, "%U", unformat_hash_vec_string,
538  pg->stream_index_by_name, &stream_index))
539  ;
540  else
541  return clib_error_create ("expecting stream name; got `%U'",
542  format_unformat_error, input);
543 
544  s = pool_elt_at_index (pg->streams, stream_index);
545  s_new = s[0];
546 
548  {
549  if (unformat_user (input, unformat_pg_stream_parameter, &s_new))
550  ;
551 
552  else
553  return clib_error_create ("unknown input `%U'",
554  format_unformat_error, input);
555  }
556 
557  error = validate_stream (&s_new);
558  if (!error)
559  {
560  s[0] = s_new;
561  pg_stream_change (pg, s);
562  }
563 
564  return error;
565 }
566 
567 /* *INDENT-OFF* */
568 VLIB_CLI_COMMAND (change_stream_parameters_cli, static) = {
569  .path = "packet-generator configure",
570  .short_help = "Change packet generator stream parameters",
571  .function = change_stream_parameters,
572 };
573 /* *INDENT-ON* */
574 
575 static clib_error_t *
577  unformat_input_t * input, vlib_cli_command_t * cmd)
578 {
579  clib_error_t *error = 0;
580  vnet_main_t *vnm = vnet_get_main ();
581  unformat_input_t _line_input, *line_input = &_line_input;
582  vnet_hw_interface_t *hi = 0;
583  u8 *pcap_file_name = 0;
584  u32 hw_if_index;
585  u32 is_disable = 0;
586  u32 count = ~0;
587 
588  if (!unformat_user (input, unformat_line_input, line_input))
589  return 0;
590 
591  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
592  {
593  if (unformat (line_input, "%U",
594  unformat_vnet_hw_interface, vnm, &hw_if_index))
595  {
596  hi = vnet_get_hw_interface (vnm, hw_if_index);
597  }
598 
599  else if (unformat (line_input, "pcap %s", &pcap_file_name))
600  ;
601  else if (unformat (line_input, "count %u", &count))
602  ;
603  else if (unformat (line_input, "disable"))
604  is_disable = 1;
605 
606  else
607  {
608  error = clib_error_create ("unknown input `%U'",
609  format_unformat_error, line_input);
610  goto done;
611  }
612  }
613 
614  if (!hi)
615  {
616  error = clib_error_return (0, "Please specify interface name");
617  goto done;
618  }
619 
620  if (hi->dev_class_index != pg_dev_class.index)
621  {
622  error =
623  clib_error_return (0, "Please specify packet-generator interface");
624  goto done;
625  }
626 
627  if (!pcap_file_name && is_disable == 0)
628  {
629  error = clib_error_return (0, "Please specify pcap file name");
630  goto done;
631  }
632 
633 
634  pg_capture_args_t _a, *a = &_a;
635 
636  a->hw_if_index = hw_if_index;
637  a->dev_instance = hi->dev_instance;
638  a->is_enabled = !is_disable;
639  a->pcap_file_name = (char *) pcap_file_name;
640  a->count = count;
641 
642  error = pg_capture (a);
643 
644 done:
645  unformat_free (line_input);
646 
647  return error;
648 }
649 
650 /* *INDENT-OFF* */
651 VLIB_CLI_COMMAND (pg_capture_cmd, static) = {
652  .path = "packet-generator capture",
653  .short_help = "packet-generator capture <interface name> pcap <filename> [count <n>]",
654  .function = pg_capture_cmd_fn,
655 };
656 /* *INDENT-ON* */
657 
658 static clib_error_t *
660  unformat_input_t * input, vlib_cli_command_t * cmd)
661 {
662  pg_main_t *pg = &pg_main;
663  unformat_input_t _line_input, *line_input = &_line_input;
664  u32 if_id, gso_enabled = 0, gso_size = 0;
665  clib_error_t *error = NULL;
666 
667  if (!unformat_user (input, unformat_line_input, line_input))
668  return 0;
669 
670  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
671  {
672  if (unformat (line_input, "interface pg%u", &if_id))
673  ;
674  else if (unformat (line_input, "gso-enabled"))
675  {
676  gso_enabled = 1;
677  if (unformat (line_input, "gso-size %u", &gso_size))
678  ;
679  else
680  {
681  error = clib_error_create ("gso enabled but gso size missing");
682  goto done;
683  }
684  }
685  else
686  {
687  error = clib_error_create ("unknown input `%U'",
688  format_unformat_error, line_input);
689  goto done;
690  }
691  }
692 
693  pg_interface_add_or_get (pg, if_id, gso_enabled, gso_size);
694 
695 done:
696  unformat_free (line_input);
697 
698  return error;
699 }
700 
701 /* *INDENT-OFF* */
702 VLIB_CLI_COMMAND (create_pg_if_cmd, static) = {
703  .path = "create packet-generator",
704  .short_help = "create packet-generator interface <interface name> [gso-enabled gso-size <size>]",
705  .function = create_pg_if_cmd_fn,
706 };
707 /* *INDENT-ON* */
708 
709 /* Dummy init function so that we can be linked in. */
710 static clib_error_t *
712 {
713  return 0;
714 }
715 
717 
718 /*
719  * fd.io coding-style-patch-verification: ON
720  *
721  * Local Variables:
722  * eval: (c-set-style "gnu")
723  * End:
724  */
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:222
u64 n_packets_limit
Definition: pg.h:159
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 clib_error_t * show_streams(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:225
static clib_error_t * del_stream(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:505
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:321
unformat_function_t unformat_input
Definition: format.h:277
pg_edit_group_t * edit_groups
Definition: pg.h:106
char * pcap_file_name
Definition: pg.h:385
PCAP utility definitions.
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
u32 index
Definition: node.h:282
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:330
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:147
u32 n_max_frame
Definition: pg.h:162
char * pcap_file_name
Definition: pg.h:311
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
u32 hw_if_index
Definition: pg.h:382
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:513
#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 * pg_pcap_read(pg_stream_t *s, char *file_name)
Definition: cli.c:266
u32 n_packet_bytes
Definition: pg.h:70
#define clib_error_return(e, args...)
Definition: error.h:99
static u8 * format_pg_stream(u8 *s, va_list *va)
Definition: cli.c:185
unsigned int u32
Definition: types.h:88
#define clib_error_create(args...)
Definition: error.h:96
#define VLIB_FRAME_SIZE
Definition: node.h:380
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:534
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
u8 * name
Definition: pg.h:97
struct _unformat_input_t unformat_input_t
unformat_function_t unformat_vnet_buffer_flags
static void pg_stream_free(pg_stream_t *s)
Definition: pg.h:197
pcap_main_t pcap_main
Definition: pg.h:310
clib_error_t * pg_capture(pg_capture_args_t *a)
Definition: cli.c:81
pg_node_t * nodes
Definition: pg.h:340
unformat_function_t unformat_hash_vec_string
Definition: hash.h:718
vlib_main_t * vm
Definition: in2out_ed.c:1599
clib_error_t * pcap_read(pcap_main_t *pm)
Read PCAP file.
Definition: pcap.c:176
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:659
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
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
static clib_error_t * enable_disable_stream(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:113
u64 * replay_packet_timestamps
Definition: pg.h:175
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
u32 min_packet_bytes
Definition: pg.h:111
u32 max_packet_bytes
Definition: pg.h:111
static uword pg_edit_group_n_bytes(pg_stream_t *s, u32 group_index)
Definition: pg.h:276
void pg_stream_change(pg_main_t *pg, pg_stream_t *s)
Definition: stream.c:496
unformat_function_t * unformat_edit
Definition: pg.h:318
static uword unformat_pg_stream_parameter(unformat_input_t *input, va_list *args)
Definition: cli.c:290
u8 ** replay_packet_templates
Definition: pg.h:174
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:152
pg_stream_t * streams
Definition: pg.h:324
static clib_error_t * pg_capture_cmd_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:576
#define PCAP_MAIN_INIT_DONE
Definition: pcap.h:175
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:689
static clib_error_t * validate_stream(pg_stream_t *s)
Definition: cli.c:319
void pg_stream_enable_disable(pg_main_t *pg, pg_stream_t *s, int is_enable)
Definition: stream.c:49
static clib_error_t * new_stream(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:337
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:144
Definition: defs.h:47
u32 sw_if_index[VLIB_N_RX_TX]
Definition: pg.h:141
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u32 if_id
Definition: pg.h:152
u64 uword
Definition: types.h:112
static void unformat_free(unformat_input_t *i)
Definition: format.h:163
static clib_error_t * change_stream_parameters(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:529
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:383
f64 rate_packets_per_second
Definition: pg.h:166
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
u32 buffer_flags
Definition: pg.h:127
static clib_error_t * pg_cli_init(vlib_main_t *vm)
Definition: cli.c:711
static u32 vlib_num_workers()
Definition: threads.h:376
u64 n_packets_generated
Definition: pg.h:155
pg_main_t pg_main
Definition: init.c:44
u8 is_enabled
Definition: pg.h:384
#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
static u8 * format_pg_edit_group(u8 *s, va_list *va)
Definition: cli.c:160
void pg_enable_disable(u32 stream_index, int is_enable)
Definition: cli.c:58
Definition: pg.h:315
pg_interface_t * interfaces
Definition: pg.h:333
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