FD.io VPP  v17.01.1-3-gc6833f8
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 #include <vnet/vnet.h>
16 #include <vppinfra/vec.h>
17 #include <vppinfra/error.h>
18 #include <vppinfra/format.h>
19 #include <vppinfra/xxhash.h>
20 
21 #include <vnet/ethernet/ethernet.h>
22 #include <vnet/devices/dpdk/dpdk.h>
24 #include <vnet/mpls/packet.h>
25 
26 #include "dpdk_priv.h"
27 
28 static clib_error_t *
30  unformat_input_t * input, vlib_cli_command_t * cmd)
31 {
32  dpdk_main_t *dm = &dpdk_main;
33  u8 *filename;
34  u32 max;
35  int matched = 0;
36  clib_error_t *error = 0;
37 
39  {
40  if (unformat (input, "on"))
41  {
42  if (dm->tx_pcap_enable == 0)
43  {
44  if (dm->pcap_filename == 0)
45  dm->pcap_filename = format (0, "/tmp/vpe.pcap%c", 0);
46 
47  memset (&dm->pcap_main, 0, sizeof (dm->pcap_main));
48  dm->pcap_main.file_name = (char *) dm->pcap_filename;
50  if (dm->pcap_pkts_to_capture)
52 
53  dm->pcap_main.packet_type = PCAP_PACKET_TYPE_ethernet;
54  dm->tx_pcap_enable = 1;
55  matched = 1;
56  vlib_cli_output (vm, "pcap tx capture on...");
57  }
58  else
59  {
60  vlib_cli_output (vm, "pcap tx capture already on...");
61  }
62  matched = 1;
63  }
64  else if (unformat (input, "off"))
65  {
66  if (dm->tx_pcap_enable)
67  {
68  vlib_cli_output (vm, "captured %d pkts...",
71  {
74  error = pcap_write (&dm->pcap_main);
75  if (error)
76  clib_error_report (error);
77  else
78  vlib_cli_output (vm, "saved to %s...", dm->pcap_filename);
79  }
80  }
81  else
82  {
83  vlib_cli_output (vm, "pcap tx capture already off...");
84  }
85 
86  dm->tx_pcap_enable = 0;
87  matched = 1;
88  }
89  else if (unformat (input, "max %d", &max))
90  {
91  dm->pcap_pkts_to_capture = max;
92  matched = 1;
93  }
94 
95  else if (unformat (input, "intfc %U",
97  &dm->pcap_sw_if_index))
98  matched = 1;
99  else if (unformat (input, "intfc any"))
100  {
101  dm->pcap_sw_if_index = 0;
102  matched = 1;
103  }
104  else if (unformat (input, "file %s", &filename))
105  {
106  u8 *chroot_filename;
107  /* Brain-police user path input */
108  if (strstr ((char *) filename, "..")
109  || index ((char *) filename, '/'))
110  {
111  vlib_cli_output (vm, "illegal characters in filename '%s'",
112  filename);
113  continue;
114  }
115 
116  chroot_filename = format (0, "/tmp/%s%c", filename, 0);
117  vec_free (filename);
118 
119  if (dm->pcap_filename)
120  vec_free (dm->pcap_filename);
121  vec_add1 (filename, 0);
122  dm->pcap_filename = chroot_filename;
123  matched = 1;
124  }
125  else if (unformat (input, "status"))
126  {
127  if (dm->tx_pcap_enable == 0)
128  {
129  vlib_cli_output (vm, "pcap tx capture is off...");
130  continue;
131  }
132 
133  vlib_cli_output (vm, "pcap tx capture: %d of %d pkts...",
136  matched = 1;
137  }
138 
139  else
140  break;
141  }
142 
143  if (matched == 0)
144  return clib_error_return (0, "unknown input `%U'",
145  format_unformat_error, input);
146 
147  return 0;
148 }
149 
150 /* *INDENT-OFF* */
151 VLIB_CLI_COMMAND (pcap_trace_command, static) = {
152  .path = "pcap tx trace",
153  .short_help =
154  "pcap tx trace on off max <nn> intfc <intfc> file <name> status",
155  .function = pcap_trace_command_fn,
156 };
157 /* *INDENT-ON* */
158 
159 
160 static clib_error_t *
162  vlib_cli_command_t * cmd)
163 {
164  struct rte_mempool *rmp;
165  int i;
166 
167  for (i = 0; i < vec_len (vm->buffer_main->pktmbuf_pools); i++)
168  {
169  rmp = vm->buffer_main->pktmbuf_pools[i];
170  if (rmp)
171  {
172  unsigned count = rte_mempool_avail_count (rmp);
173  unsigned free_count = rte_mempool_in_use_count (rmp);
174 
175  vlib_cli_output (vm,
176  "name=\"%s\" available = %7d allocated = %7d total = %7d\n",
177  rmp->name, (u32) count, (u32) free_count,
178  (u32) (count + free_count));
179  }
180  else
181  {
182  vlib_cli_output (vm, "rte_mempool is NULL (!)\n");
183  }
184  }
185  return 0;
186 }
187 
188 /* *INDENT-OFF* */
189 VLIB_CLI_COMMAND (cmd_show_dpdk_bufferr,static) = {
190  .path = "show dpdk buffer",
191  .short_help = "show dpdk buffer state",
192  .function = show_dpdk_buffer,
193  .is_mp_safe = 1,
194 };
195 /* *INDENT-ON* */
196 
197 static clib_error_t *
199  vlib_cli_command_t * cmd)
200 {
201  static u32 *allocated_buffers;
202  u32 n_alloc = 0;
203  u32 n_free = 0;
204  u32 first, actual_alloc;
205 
207  {
208  if (unformat (input, "allocate %d", &n_alloc))
209  ;
210  else if (unformat (input, "free %d", &n_free))
211  ;
212  else
213  break;
214  }
215 
216  if (n_free)
217  {
218  if (vec_len (allocated_buffers) < n_free)
219  return clib_error_return (0, "Can't free %d, only %d allocated",
220  n_free, vec_len (allocated_buffers));
221 
222  first = vec_len (allocated_buffers) - n_free;
223  vlib_buffer_free (vm, allocated_buffers + first, n_free);
224  _vec_len (allocated_buffers) = first;
225  }
226  if (n_alloc)
227  {
228  first = vec_len (allocated_buffers);
229  vec_validate (allocated_buffers,
230  vec_len (allocated_buffers) + n_alloc - 1);
231 
232  actual_alloc = vlib_buffer_alloc (vm, allocated_buffers + first,
233  n_alloc);
234  _vec_len (allocated_buffers) = first + actual_alloc;
235 
236  if (actual_alloc < n_alloc)
237  vlib_cli_output (vm, "WARNING: only allocated %d buffers",
238  actual_alloc);
239  }
240 
241  vlib_cli_output (vm, "Currently %d buffers allocated",
242  vec_len (allocated_buffers));
243 
244  if (allocated_buffers && vec_len (allocated_buffers) == 0)
245  vec_free (allocated_buffers);
246 
247  return 0;
248 }
249 
250 /* *INDENT-OFF* */
251 VLIB_CLI_COMMAND (cmd_test_dpdk_buffer,static) = {
252  .path = "test dpdk buffer",
253  .short_help = "test dpdk buffer [allocate <nn>][free <nn>]",
254  .function = test_dpdk_buffer,
255  .is_mp_safe = 1,
256 };
257 /* *INDENT-ON* */
258 
259 static clib_error_t *
261  vlib_cli_command_t * cmd)
262 {
263  unformat_input_t _line_input, *line_input = &_line_input;
264  dpdk_main_t *dm = &dpdk_main;
266  dpdk_device_t *xd;
267  u32 hw_if_index = (u32) ~ 0;
268  u32 nb_rx_desc = (u32) ~ 0;
269  u32 nb_tx_desc = (u32) ~ 0;
270  clib_error_t *rv;
271 
272  if (!unformat_user (input, unformat_line_input, line_input))
273  return 0;
274 
275  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
276  {
277  if (unformat
278  (line_input, "%U", unformat_vnet_hw_interface, dm->vnet_main,
279  &hw_if_index))
280  ;
281  else if (unformat (line_input, "tx %d", &nb_tx_desc))
282  ;
283  else if (unformat (line_input, "rx %d", &nb_rx_desc))
284  ;
285  else
286  return clib_error_return (0, "parse error: '%U'",
287  format_unformat_error, line_input);
288  }
289 
290  unformat_free (line_input);
291 
292  if (hw_if_index == (u32) ~ 0)
293  return clib_error_return (0, "please specify valid interface name");
294 
295  hw = vnet_get_hw_interface (dm->vnet_main, hw_if_index);
296  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
297 
298  if ((xd->flags & DPDK_DEVICE_FLAG_PMD) == 0)
299  return clib_error_return (0, "number of descriptors can be set only for "
300  "physical devices");
301 
302  if ((nb_rx_desc == (u32) ~ 0 || nb_rx_desc == xd->nb_rx_desc) &&
303  (nb_tx_desc == (u32) ~ 0 || nb_tx_desc == xd->nb_tx_desc))
304  return clib_error_return (0, "nothing changed");
305 
306  if (nb_rx_desc != (u32) ~ 0)
307  xd->nb_rx_desc = nb_rx_desc;
308 
309  if (nb_tx_desc != (u32) ~ 0)
310  xd->nb_tx_desc = nb_tx_desc;
311 
312  rv = dpdk_port_setup (dm, xd);
313 
314  return rv;
315 }
316 
317 /* *INDENT-OFF* */
318 VLIB_CLI_COMMAND (cmd_set_dpdk_if_desc,static) = {
319  .path = "set dpdk interface descriptors",
320  .short_help = "set dpdk interface descriptors <if-name> [rx <n>] [tx <n>]",
321  .function = set_dpdk_if_desc,
322 };
323 /* *INDENT-ON* */
324 
325 static clib_error_t *
327  vlib_cli_command_t * cmd)
328 {
330  dpdk_main_t *dm = &dpdk_main;
332  int cpu;
333 
334  if (tm->n_vlib_mains == 1)
335  vlib_cli_output (vm, "All interfaces are handled by main thread");
336 
337  for (cpu = 0; cpu < vec_len (dm->devices_by_cpu); cpu++)
338  {
339  if (vec_len (dm->devices_by_cpu[cpu]))
340  vlib_cli_output (vm, "Thread %u (%s at lcore %u):", cpu,
341  vlib_worker_threads[cpu].name,
342  vlib_worker_threads[cpu].lcore_id);
343 
344  /* *INDENT-OFF* */
345  vec_foreach(dq, dm->devices_by_cpu[cpu])
346  {
347  u32 hw_if_index = dm->devices[dq->device].vlib_hw_if_index;
349  vlib_cli_output(vm, " %v queue %u", hi->name, dq->queue_id);
350  }
351  /* *INDENT-ON* */
352  }
353  return 0;
354 }
355 
356 /* *INDENT-OFF* */
357 VLIB_CLI_COMMAND (cmd_show_dpdk_if_placement,static) = {
358  .path = "show dpdk interface placement",
359  .short_help = "show dpdk interface placement",
360  .function = show_dpdk_if_placement,
361 };
362 /* *INDENT-ON* */
363 
364 static int
365 dpdk_device_queue_sort (void *a1, void *a2)
366 {
367  dpdk_device_and_queue_t *dq1 = a1;
368  dpdk_device_and_queue_t *dq2 = a2;
369 
370  if (dq1->device > dq2->device)
371  return 1;
372  else if (dq1->device < dq2->device)
373  return -1;
374  else if (dq1->queue_id > dq2->queue_id)
375  return 1;
376  else if (dq1->queue_id < dq2->queue_id)
377  return -1;
378  else
379  return 0;
380 }
381 
382 static clib_error_t *
384  vlib_cli_command_t * cmd)
385 {
386  unformat_input_t _line_input, *line_input = &_line_input;
387  dpdk_main_t *dm = &dpdk_main;
390  dpdk_device_t *xd;
391  u32 hw_if_index = (u32) ~ 0;
392  u32 queue = (u32) 0;
393  u32 cpu = (u32) ~ 0;
394  int i;
395 
396  if (!unformat_user (input, unformat_line_input, line_input))
397  return 0;
398 
399  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
400  {
401  if (unformat
402  (line_input, "%U", unformat_vnet_hw_interface, dm->vnet_main,
403  &hw_if_index))
404  ;
405  else if (unformat (line_input, "queue %d", &queue))
406  ;
407  else if (unformat (line_input, "thread %d", &cpu))
408  ;
409  else
410  return clib_error_return (0, "parse error: '%U'",
411  format_unformat_error, line_input);
412  }
413 
414  unformat_free (line_input);
415 
416  if (hw_if_index == (u32) ~ 0)
417  return clib_error_return (0, "please specify valid interface name");
418 
419  if (cpu < dm->input_cpu_first_index ||
420  cpu >= (dm->input_cpu_first_index + dm->input_cpu_count))
421  return clib_error_return (0, "please specify valid thread id");
422 
423  hw = vnet_get_hw_interface (dm->vnet_main, hw_if_index);
424  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
425 
426  for (i = 0; i < vec_len (dm->devices_by_cpu); i++)
427  {
428  /* *INDENT-OFF* */
429  vec_foreach(dq, dm->devices_by_cpu[i])
430  {
431  if (hw_if_index == dm->devices[dq->device].vlib_hw_if_index &&
432  queue == dq->queue_id)
433  {
434  if (cpu == i) /* nothing to do */
435  return 0;
436 
437  vec_del1(dm->devices_by_cpu[i], dq - dm->devices_by_cpu[i]);
438  vec_add2(dm->devices_by_cpu[cpu], dq, 1);
439  dq->queue_id = queue;
440  dq->device = xd->device_index;
441  xd->cpu_socket_id_by_queue[queue] =
442  rte_lcore_to_socket_id(vlib_worker_threads[cpu].lcore_id);
443 
446 
449 
450  if (vec_len(dm->devices_by_cpu[i]) == 0)
452  VLIB_NODE_STATE_DISABLED);
453 
454  if (vec_len(dm->devices_by_cpu[cpu]) == 1)
456  VLIB_NODE_STATE_POLLING);
457 
458  return 0;
459  }
460  }
461  /* *INDENT-ON* */
462  }
463 
464  return clib_error_return (0, "not found");
465 }
466 
467 /* *INDENT-OFF* */
468 VLIB_CLI_COMMAND (cmd_set_dpdk_if_placement,static) = {
469  .path = "set dpdk interface placement",
470  .short_help = "set dpdk interface placement <if-name> [queue <n>] thread <n>",
471  .function = set_dpdk_if_placement,
472 };
473 /* *INDENT-ON* */
474 
475 static clib_error_t *
477  vlib_cli_command_t * cmd)
478 {
480  dpdk_main_t *dm = &dpdk_main;
482  int cpu;
483 
484  if (tm->n_vlib_mains == 1)
485  vlib_cli_output (vm, "All interfaces are handled by main thread");
486 
487  for (cpu = 0; cpu < vec_len (dm->devices_by_hqos_cpu); cpu++)
488  {
489  if (vec_len (dm->devices_by_hqos_cpu[cpu]))
490  vlib_cli_output (vm, "Thread %u (%s at lcore %u):", cpu,
491  vlib_worker_threads[cpu].name,
492  vlib_worker_threads[cpu].lcore_id);
493 
494  vec_foreach (dq, dm->devices_by_hqos_cpu[cpu])
495  {
496  u32 hw_if_index = dm->devices[dq->device].vlib_hw_if_index;
498  vnet_get_hw_interface (dm->vnet_main, hw_if_index);
499  vlib_cli_output (vm, " %v queue %u", hi->name, dq->queue_id);
500  }
501  }
502  return 0;
503 }
504 
505 /* *INDENT-OFF* */
506 VLIB_CLI_COMMAND (cmd_show_dpdk_if_hqos_placement, static) = {
507  .path = "show dpdk interface hqos placement",
508  .short_help = "show dpdk interface hqos placement",
509  .function = show_dpdk_if_hqos_placement,
510 };
511 /* *INDENT-ON* */
512 
513 static clib_error_t *
515  vlib_cli_command_t * cmd)
516 {
517  unformat_input_t _line_input, *line_input = &_line_input;
518  dpdk_main_t *dm = &dpdk_main;
521  dpdk_device_t *xd;
522  u32 hw_if_index = (u32) ~ 0;
523  u32 cpu = (u32) ~ 0;
524  int i;
525 
526  if (!unformat_user (input, unformat_line_input, line_input))
527  return 0;
528 
529  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
530  {
531  if (unformat
532  (line_input, "%U", unformat_vnet_hw_interface, dm->vnet_main,
533  &hw_if_index))
534  ;
535  else if (unformat (line_input, "thread %d", &cpu))
536  ;
537  else
538  return clib_error_return (0, "parse error: '%U'",
539  format_unformat_error, line_input);
540  }
541 
542  unformat_free (line_input);
543 
544  if (hw_if_index == (u32) ~ 0)
545  return clib_error_return (0, "please specify valid interface name");
546 
547  if (cpu < dm->hqos_cpu_first_index ||
548  cpu >= (dm->hqos_cpu_first_index + dm->hqos_cpu_count))
549  return clib_error_return (0, "please specify valid thread id");
550 
551  hw = vnet_get_hw_interface (dm->vnet_main, hw_if_index);
552  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
553 
554  for (i = 0; i < vec_len (dm->devices_by_hqos_cpu); i++)
555  {
556  vec_foreach (dq, dm->devices_by_hqos_cpu[i])
557  {
558  if (hw_if_index == dm->devices[dq->device].vlib_hw_if_index)
559  {
560  if (cpu == i) /* nothing to do */
561  return 0;
562 
564  dq - dm->devices_by_hqos_cpu[i]);
565  vec_add2 (dm->devices_by_hqos_cpu[cpu], dq, 1);
566  dq->queue_id = 0;
567  dq->device = xd->device_index;
568 
571 
574 
575  return 0;
576  }
577  }
578  }
579 
580  return clib_error_return (0, "not found");
581 }
582 
583 /* *INDENT-OFF* */
584 VLIB_CLI_COMMAND (cmd_set_dpdk_if_hqos_placement, static) = {
585  .path = "set dpdk interface hqos placement",
586  .short_help = "set dpdk interface hqos placement <if-name> thread <n>",
587  .function = set_dpdk_if_hqos_placement,
588 };
589 /* *INDENT-ON* */
590 
591 static clib_error_t *
593  vlib_cli_command_t * cmd)
594 {
595  unformat_input_t _line_input, *line_input = &_line_input;
596  dpdk_main_t *dm = &dpdk_main;
598  dpdk_device_t *xd;
599  u32 hw_if_index = (u32) ~ 0;
600  u32 subport_id = (u32) ~ 0;
601  u32 pipe_id = (u32) ~ 0;
602  u32 profile_id = (u32) ~ 0;
603  int rv;
604 
605  if (!unformat_user (input, unformat_line_input, line_input))
606  return 0;
607 
608  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
609  {
610  if (unformat
611  (line_input, "%U", unformat_vnet_hw_interface, dm->vnet_main,
612  &hw_if_index))
613  ;
614  else if (unformat (line_input, "subport %d", &subport_id))
615  ;
616  else if (unformat (line_input, "pipe %d", &pipe_id))
617  ;
618  else if (unformat (line_input, "profile %d", &profile_id))
619  ;
620  else
621  return clib_error_return (0, "parse error: '%U'",
622  format_unformat_error, line_input);
623  }
624 
625  unformat_free (line_input);
626 
627  if (hw_if_index == (u32) ~ 0)
628  return clib_error_return (0, "please specify valid interface name");
629 
630  hw = vnet_get_hw_interface (dm->vnet_main, hw_if_index);
631  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
632 
633  rv =
634  rte_sched_pipe_config (xd->hqos_ht->hqos, subport_id, pipe_id,
635  profile_id);
636  if (rv)
637  return clib_error_return (0, "pipe configuration failed");
638 
639  return 0;
640 }
641 
642 /* *INDENT-OFF* */
643 VLIB_CLI_COMMAND (cmd_set_dpdk_if_hqos_pipe, static) =
644 {
645  .path = "set dpdk interface hqos pipe",
646  .short_help = "set dpdk interface hqos pipe <if-name> subport <n> pipe <n> "
647  "profile <n>",
648  .function = set_dpdk_if_hqos_pipe,
649 };
650 /* *INDENT-ON* */
651 
652 static clib_error_t *
654  vlib_cli_command_t * cmd)
655 {
656  unformat_input_t _line_input, *line_input = &_line_input;
657  dpdk_main_t *dm = &dpdk_main;
659  dpdk_device_t *xd;
660  u32 hw_if_index = (u32) ~ 0;
661  u32 subport_id = (u32) ~ 0;
662  struct rte_sched_subport_params p = {
663  .tb_rate = 1250000000, /* 10GbE */
664  .tb_size = 1000000,
665  .tc_rate = {1250000000, 1250000000, 1250000000, 1250000000},
666  .tc_period = 10,
667  };
668  int rv;
669 
670  if (!unformat_user (input, unformat_line_input, line_input))
671  return 0;
672 
673  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
674  {
675  if (unformat
676  (line_input, "%U", unformat_vnet_hw_interface, dm->vnet_main,
677  &hw_if_index))
678  ;
679  else if (unformat (line_input, "subport %d", &subport_id))
680  ;
681  else if (unformat (line_input, "rate %d", &p.tb_rate))
682  {
683  p.tc_rate[0] = p.tb_rate;
684  p.tc_rate[1] = p.tb_rate;
685  p.tc_rate[2] = p.tb_rate;
686  p.tc_rate[3] = p.tb_rate;
687  }
688  else if (unformat (line_input, "bktsize %d", &p.tb_size))
689  ;
690  else if (unformat (line_input, "tc0 %d", &p.tc_rate[0]))
691  ;
692  else if (unformat (line_input, "tc1 %d", &p.tc_rate[1]))
693  ;
694  else if (unformat (line_input, "tc2 %d", &p.tc_rate[2]))
695  ;
696  else if (unformat (line_input, "tc3 %d", &p.tc_rate[3]))
697  ;
698  else if (unformat (line_input, "period %d", &p.tc_period))
699  ;
700  else
701  return clib_error_return (0, "parse error: '%U'",
702  format_unformat_error, line_input);
703  }
704 
705  unformat_free (line_input);
706 
707  if (hw_if_index == (u32) ~ 0)
708  return clib_error_return (0, "please specify valid interface name");
709 
710  hw = vnet_get_hw_interface (dm->vnet_main, hw_if_index);
711  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
712 
713  rv = rte_sched_subport_config (xd->hqos_ht->hqos, subport_id, &p);
714  if (rv)
715  return clib_error_return (0, "subport configuration failed");
716 
717  return 0;
718 }
719 
720 /* *INDENT-OFF* */
721 VLIB_CLI_COMMAND (cmd_set_dpdk_if_hqos_subport, static) = {
722  .path = "set dpdk interface hqos subport",
723  .short_help = "set dpdk interface hqos subport <if-name> subport <n> "
724  "[rate <n>] [bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] "
725  "[period <n>]",
726  .function = set_dpdk_if_hqos_subport,
727 };
728 /* *INDENT-ON* */
729 
730 static clib_error_t *
732  vlib_cli_command_t * cmd)
733 {
734  unformat_input_t _line_input, *line_input = &_line_input;
736  dpdk_main_t *dm = &dpdk_main;
738  dpdk_device_t *xd;
739  u32 hw_if_index = (u32) ~ 0;
740  u32 tc = (u32) ~ 0;
741  u32 queue = (u32) ~ 0;
742  u32 entry = (u32) ~ 0;
743  u32 val, i;
744 
745  if (!unformat_user (input, unformat_line_input, line_input))
746  return 0;
747 
748  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
749  {
750  if (unformat
751  (line_input, "%U", unformat_vnet_hw_interface, dm->vnet_main,
752  &hw_if_index))
753  ;
754  else if (unformat (line_input, "entry %d", &entry))
755  ;
756  else if (unformat (line_input, "tc %d", &tc))
757  ;
758  else if (unformat (line_input, "queue %d", &queue))
759  ;
760  else
761  return clib_error_return (0, "parse error: '%U'",
762  format_unformat_error, line_input);
763  }
764 
765  unformat_free (line_input);
766 
767  if (hw_if_index == (u32) ~ 0)
768  return clib_error_return (0, "please specify valid interface name");
769  if (entry >= 64)
770  return clib_error_return (0, "invalid entry");
771  if (tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE)
772  return clib_error_return (0, "invalid traffic class");
773  if (queue >= RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS)
774  return clib_error_return (0, "invalid traffic class");
775 
776  hw = vnet_get_hw_interface (dm->vnet_main, hw_if_index);
777  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
778 
779  /* Detect the set of worker threads */
780  uword *p = hash_get_mem (tm->thread_registrations_by_name, "workers");
781  /* Should never happen, shut up Coverity warning */
782  if (p == 0)
783  return clib_error_return (0, "no worker registrations?");
784 
786  int worker_thread_first = tr->first_index;
787  int worker_thread_count = tr->count;
788 
789  val = tc * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue;
790  for (i = 0; i < worker_thread_count; i++)
791  xd->hqos_wt[worker_thread_first + i].hqos_tc_table[entry] = val;
792 
793  return 0;
794 }
795 
796 /* *INDENT-OFF* */
797 VLIB_CLI_COMMAND (cmd_set_dpdk_if_hqos_tctbl, static) = {
798  .path = "set dpdk interface hqos tctbl",
799  .short_help = "set dpdk interface hqos tctbl <if-name> entry <n> tc <n> queue <n>",
800  .function = set_dpdk_if_hqos_tctbl,
801 };
802 /* *INDENT-ON* */
803 
804 static clib_error_t *
806  vlib_cli_command_t * cmd)
807 {
808  unformat_input_t _line_input, *line_input = &_line_input;
810  dpdk_main_t *dm = &dpdk_main;
811 
812  /* Device specific data */
813  struct rte_eth_dev_info dev_info;
814  dpdk_device_config_t *devconf = 0;
816  dpdk_device_t *xd;
817  u32 hw_if_index = (u32) ~ 0;
818 
819  /* Detect the set of worker threads */
820  uword *p = hash_get_mem (tm->thread_registrations_by_name, "workers");
821  /* Should never happen, shut up Coverity warning */
822  if (p == 0)
823  return clib_error_return (0, "no worker registrations?");
824 
826  int worker_thread_first = tr->first_index;
827  int worker_thread_count = tr->count;
828 
829  /* Packet field configuration */
830  u64 mask = (u64) ~ 0;
831  u32 id = (u32) ~ 0;
832  u32 offset = (u32) ~ 0;
833 
834  /* HQoS params */
835  u32 n_subports_per_port, n_pipes_per_subport, tctbl_size;
836 
837  u32 i;
838 
839  /* Parse input arguments */
840  if (!unformat_user (input, unformat_line_input, line_input))
841  return 0;
842 
843  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
844  {
845  if (unformat
846  (line_input, "%U", unformat_vnet_hw_interface, dm->vnet_main,
847  &hw_if_index))
848  ;
849  else if (unformat (line_input, "id %d", &id))
850  ;
851  else if (unformat (line_input, "offset %d", &offset))
852  ;
853  else if (unformat (line_input, "mask %llx", &mask))
854  ;
855  else
856  return clib_error_return (0, "parse error: '%U'",
857  format_unformat_error, line_input);
858  }
859 
860  unformat_free (line_input);
861 
862  /* Get interface */
863  if (hw_if_index == (u32) ~ 0)
864  return clib_error_return (0, "please specify valid interface name");
865 
866  hw = vnet_get_hw_interface (dm->vnet_main, hw_if_index);
867  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
868 
869  rte_eth_dev_info_get (xd->device_index, &dev_info);
870  if (dev_info.pci_dev)
871  { /* bonded interface has no pci info */
872  vlib_pci_addr_t pci_addr;
873 
874  pci_addr.domain = dev_info.pci_dev->addr.domain;
875  pci_addr.bus = dev_info.pci_dev->addr.bus;
876  pci_addr.slot = dev_info.pci_dev->addr.devid;
877  pci_addr.function = dev_info.pci_dev->addr.function;
878 
879  p =
880  hash_get (dm->conf->device_config_index_by_pci_addr, pci_addr.as_u32);
881  }
882 
883  if (p)
884  devconf = pool_elt_at_index (dm->conf->dev_confs, p[0]);
885  else
886  devconf = &dm->conf->default_devconf;
887 
888  if (devconf->hqos_enabled == 0)
889  {
890  vlib_cli_output (vm, "HQoS disabled for this interface");
891  return 0;
892  }
893 
894  n_subports_per_port = devconf->hqos.port.n_subports_per_port;
895  n_pipes_per_subport = devconf->hqos.port.n_pipes_per_subport;
896  tctbl_size = RTE_DIM (devconf->hqos.tc_table);
897 
898  /* Validate packet field configuration: id, offset and mask */
899  if (id >= 3)
900  return clib_error_return (0, "invalid packet field id");
901 
902  switch (id)
903  {
904  case 0:
905  if (dpdk_hqos_validate_mask (mask, n_subports_per_port) != 0)
906  return clib_error_return (0, "invalid subport ID mask "
907  "(n_subports_per_port = %u)",
908  n_subports_per_port);
909  break;
910  case 1:
911  if (dpdk_hqos_validate_mask (mask, n_pipes_per_subport) != 0)
912  return clib_error_return (0, "invalid pipe ID mask "
913  "(n_pipes_per_subport = %u)",
914  n_pipes_per_subport);
915  break;
916  case 2:
917  default:
918  if (dpdk_hqos_validate_mask (mask, tctbl_size) != 0)
919  return clib_error_return (0, "invalid TC table index mask "
920  "(TC table size = %u)", tctbl_size);
921  }
922 
923  /* Propagate packet field configuration to all workers */
924  for (i = 0; i < worker_thread_count; i++)
925  switch (id)
926  {
927  case 0:
928  xd->hqos_wt[worker_thread_first + i].hqos_field0_slabpos = offset;
929  xd->hqos_wt[worker_thread_first + i].hqos_field0_slabmask = mask;
930  xd->hqos_wt[worker_thread_first + i].hqos_field0_slabshr =
931  __builtin_ctzll (mask);
932  break;
933  case 1:
934  xd->hqos_wt[worker_thread_first + i].hqos_field1_slabpos = offset;
935  xd->hqos_wt[worker_thread_first + i].hqos_field1_slabmask = mask;
936  xd->hqos_wt[worker_thread_first + i].hqos_field1_slabshr =
937  __builtin_ctzll (mask);
938  break;
939  case 2:
940  default:
941  xd->hqos_wt[worker_thread_first + i].hqos_field2_slabpos = offset;
942  xd->hqos_wt[worker_thread_first + i].hqos_field2_slabmask = mask;
943  xd->hqos_wt[worker_thread_first + i].hqos_field2_slabshr =
944  __builtin_ctzll (mask);
945  }
946 
947  return 0;
948 }
949 
950 /* *INDENT-OFF* */
951 VLIB_CLI_COMMAND (cmd_set_dpdk_if_hqos_pktfield, static) = {
952  .path = "set dpdk interface hqos pktfield",
953  .short_help = "set dpdk interface hqos pktfield <if-name> id <n> offset <n> "
954  "mask <n>",
955  .function = set_dpdk_if_hqos_pktfield,
956 };
957 /* *INDENT-ON* */
958 
959 static clib_error_t *
961  vlib_cli_command_t * cmd)
962 {
963  unformat_input_t _line_input, *line_input = &_line_input;
965  dpdk_main_t *dm = &dpdk_main;
967  dpdk_device_t *xd;
971  u32 *tctbl;
972  u32 hw_if_index = (u32) ~ 0;
973  u32 profile_id, i;
974  struct rte_eth_dev_info dev_info;
975  dpdk_device_config_t *devconf = 0;
977  uword *p = 0;
978 
979  if (!unformat_user (input, unformat_line_input, line_input))
980  return 0;
981 
982  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
983  {
984  if (unformat
985  (line_input, "%U", unformat_vnet_hw_interface, dm->vnet_main,
986  &hw_if_index))
987  ;
988  else
989  return clib_error_return (0, "parse error: '%U'",
990  format_unformat_error, line_input);
991  }
992 
993  unformat_free (line_input);
994 
995  if (hw_if_index == (u32) ~ 0)
996  return clib_error_return (0, "please specify interface name!!");
997 
998  hw = vnet_get_hw_interface (dm->vnet_main, hw_if_index);
999  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
1000 
1001  rte_eth_dev_info_get (xd->device_index, &dev_info);
1002  if (dev_info.pci_dev)
1003  { /* bonded interface has no pci info */
1004  vlib_pci_addr_t pci_addr;
1005 
1006  pci_addr.domain = dev_info.pci_dev->addr.domain;
1007  pci_addr.bus = dev_info.pci_dev->addr.bus;
1008  pci_addr.slot = dev_info.pci_dev->addr.devid;
1009  pci_addr.function = dev_info.pci_dev->addr.function;
1010 
1011  p =
1012  hash_get (dm->conf->device_config_index_by_pci_addr, pci_addr.as_u32);
1013  }
1014 
1015  if (p)
1016  devconf = pool_elt_at_index (dm->conf->dev_confs, p[0]);
1017  else
1018  devconf = &dm->conf->default_devconf;
1019 
1020  if (devconf->hqos_enabled == 0)
1021  {
1022  vlib_cli_output (vm, "HQoS disabled for this interface");
1023  return 0;
1024  }
1025 
1026  /* Detect the set of worker threads */
1027  p = hash_get_mem (tm->thread_registrations_by_name, "workers");
1028 
1029  /* Should never happen, shut up Coverity warning */
1030  if (p == 0)
1031  return clib_error_return (0, "no worker registrations?");
1032 
1033  tr = (vlib_thread_registration_t *) p[0];
1034 
1035  cfg = &devconf->hqos;
1036  ht = xd->hqos_ht;
1037  wk = &xd->hqos_wt[tr->first_index];
1038  tctbl = wk->hqos_tc_table;
1039 
1040  vlib_cli_output (vm, " Thread:");
1041  vlib_cli_output (vm, " Input SWQ size = %u packets", cfg->swq_size);
1042  vlib_cli_output (vm, " Enqueue burst size = %u packets",
1043  ht->hqos_burst_enq);
1044  vlib_cli_output (vm, " Dequeue burst size = %u packets",
1045  ht->hqos_burst_deq);
1046 
1047  vlib_cli_output (vm,
1048  " Packet field 0: slab position = %4u, slab bitmask = 0x%016llx",
1050  vlib_cli_output (vm,
1051  " Packet field 1: slab position = %4u, slab bitmask = 0x%016llx",
1053  vlib_cli_output (vm,
1054  " Packet field 2: slab position = %4u, slab bitmask = 0x%016llx",
1056  vlib_cli_output (vm, " Packet field 2 translation table:");
1057  vlib_cli_output (vm, " [ 0 .. 15]: "
1058  "%2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u",
1059  tctbl[0], tctbl[1], tctbl[2], tctbl[3],
1060  tctbl[4], tctbl[5], tctbl[6], tctbl[7],
1061  tctbl[8], tctbl[9], tctbl[10], tctbl[11],
1062  tctbl[12], tctbl[13], tctbl[14], tctbl[15]);
1063  vlib_cli_output (vm, " [16 .. 31]: "
1064  "%2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u",
1065  tctbl[16], tctbl[17], tctbl[18], tctbl[19],
1066  tctbl[20], tctbl[21], tctbl[22], tctbl[23],
1067  tctbl[24], tctbl[25], tctbl[26], tctbl[27],
1068  tctbl[28], tctbl[29], tctbl[30], tctbl[31]);
1069  vlib_cli_output (vm, " [32 .. 47]: "
1070  "%2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u",
1071  tctbl[32], tctbl[33], tctbl[34], tctbl[35],
1072  tctbl[36], tctbl[37], tctbl[38], tctbl[39],
1073  tctbl[40], tctbl[41], tctbl[42], tctbl[43],
1074  tctbl[44], tctbl[45], tctbl[46], tctbl[47]);
1075  vlib_cli_output (vm, " [48 .. 63]: "
1076  "%2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u %2u",
1077  tctbl[48], tctbl[49], tctbl[50], tctbl[51],
1078  tctbl[52], tctbl[53], tctbl[54], tctbl[55],
1079  tctbl[56], tctbl[57], tctbl[58], tctbl[59],
1080  tctbl[60], tctbl[61], tctbl[62], tctbl[63]);
1081 
1082  vlib_cli_output (vm, " Port:");
1083  vlib_cli_output (vm, " Rate = %u bytes/second", cfg->port.rate);
1084  vlib_cli_output (vm, " MTU = %u bytes", cfg->port.mtu);
1085  vlib_cli_output (vm, " Frame overhead = %u bytes",
1086  cfg->port.frame_overhead);
1087  vlib_cli_output (vm, " Number of subports = %u",
1088  cfg->port.n_subports_per_port);
1089  vlib_cli_output (vm, " Number of pipes per subport = %u",
1090  cfg->port.n_pipes_per_subport);
1091  vlib_cli_output (vm,
1092  " Packet queue size: TC0 = %u, TC1 = %u, TC2 = %u, TC3 = %u packets",
1093  cfg->port.qsize[0], cfg->port.qsize[1], cfg->port.qsize[2],
1094  cfg->port.qsize[3]);
1095  vlib_cli_output (vm, " Number of pipe profiles = %u",
1096  cfg->port.n_pipe_profiles);
1097 
1098  for (profile_id = 0; profile_id < vec_len (cfg->pipe); profile_id++)
1099  {
1100  vlib_cli_output (vm, " Pipe profile %u:", profile_id);
1101  vlib_cli_output (vm, " Rate = %u bytes/second",
1102  cfg->pipe[profile_id].tb_rate);
1103  vlib_cli_output (vm, " Token bucket size = %u bytes",
1104  cfg->pipe[profile_id].tb_size);
1105  vlib_cli_output (vm,
1106  " Traffic class rate: TC0 = %u, TC1 = %u, TC2 = %u, TC3 = %u bytes/second",
1107  cfg->pipe[profile_id].tc_rate[0],
1108  cfg->pipe[profile_id].tc_rate[1],
1109  cfg->pipe[profile_id].tc_rate[2],
1110  cfg->pipe[profile_id].tc_rate[3]);
1111  vlib_cli_output (vm, " TC period = %u milliseconds",
1112  cfg->pipe[profile_id].tc_period);
1113 #ifdef RTE_SCHED_SUBPORT_TC_OV
1114  vlib_cli_output (vm, " TC3 oversubscription_weight = %u",
1115  cfg->pipe[profile_id].tc_ov_weight);
1116 #endif
1117 
1118  for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
1119  {
1120  vlib_cli_output (vm,
1121  " TC%u WRR weights: Q0 = %u, Q1 = %u, Q2 = %u, Q3 = %u",
1122  i, cfg->pipe[profile_id].wrr_weights[i * 4],
1123  cfg->pipe[profile_id].wrr_weights[i * 4 + 1],
1124  cfg->pipe[profile_id].wrr_weights[i * 4 + 2],
1125  cfg->pipe[profile_id].wrr_weights[i * 4 + 3]);
1126  }
1127  }
1128 
1129 #ifdef RTE_SCHED_RED
1130  vlib_cli_output (vm, " Weighted Random Early Detection (WRED):");
1131  for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
1132  {
1133  vlib_cli_output (vm, " TC%u min: G = %u, Y = %u, R = %u", i,
1134  cfg->port.red_params[i][e_RTE_METER_GREEN].min_th,
1135  cfg->port.red_params[i][e_RTE_METER_YELLOW].min_th,
1136  cfg->port.red_params[i][e_RTE_METER_RED].min_th);
1137 
1138  vlib_cli_output (vm, " TC%u max: G = %u, Y = %u, R = %u", i,
1139  cfg->port.red_params[i][e_RTE_METER_GREEN].max_th,
1140  cfg->port.red_params[i][e_RTE_METER_YELLOW].max_th,
1141  cfg->port.red_params[i][e_RTE_METER_RED].max_th);
1142 
1143  vlib_cli_output (vm,
1144  " TC%u inverted probability: G = %u, Y = %u, R = %u",
1145  i, cfg->port.red_params[i][e_RTE_METER_GREEN].maxp_inv,
1146  cfg->port.red_params[i][e_RTE_METER_YELLOW].maxp_inv,
1147  cfg->port.red_params[i][e_RTE_METER_RED].maxp_inv);
1148 
1149  vlib_cli_output (vm, " TC%u weight: R = %u, Y = %u, R = %u", i,
1150  cfg->port.red_params[i][e_RTE_METER_GREEN].wq_log2,
1151  cfg->port.red_params[i][e_RTE_METER_YELLOW].wq_log2,
1152  cfg->port.red_params[i][e_RTE_METER_RED].wq_log2);
1153  }
1154 #endif
1155 
1156  return 0;
1157 }
1158 
1159 /* *INDENT-OFF* */
1160 VLIB_CLI_COMMAND (cmd_show_dpdk_if_hqos, static) = {
1161  .path = "show dpdk interface hqos",
1162  .short_help = "show dpdk interface hqos <if-name>",
1163  .function = show_dpdk_if_hqos,
1164 };
1165 
1166 /* *INDENT-ON* */
1167 
1168 static clib_error_t *
1170  vlib_cli_command_t * cmd)
1171 {
1172  unformat_input_t _line_input, *line_input = &_line_input;
1173  dpdk_main_t *dm = &dpdk_main;
1174  u32 hw_if_index = (u32) ~ 0;
1175  u32 subport = (u32) ~ 0;
1176  u32 pipe = (u32) ~ 0;
1177  u32 tc = (u32) ~ 0;
1178  u32 tc_q = (u32) ~ 0;
1179  vnet_hw_interface_t *hw;
1180  dpdk_device_t *xd;
1181  uword *p = 0;
1182  struct rte_eth_dev_info dev_info;
1183  dpdk_device_config_t *devconf = 0;
1184  u32 qindex;
1185  struct rte_sched_queue_stats stats;
1186  u16 qlen;
1187 
1188  if (!unformat_user (input, unformat_line_input, line_input))
1189  return 0;
1190 
1191  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1192  {
1193  if (unformat
1194  (line_input, "%U", unformat_vnet_hw_interface, dm->vnet_main,
1195  &hw_if_index))
1196  ;
1197 
1198  else if (unformat (line_input, "subport %d", &subport))
1199  ;
1200 
1201  else if (unformat (line_input, "pipe %d", &pipe))
1202  ;
1203 
1204  else if (unformat (line_input, "tc %d", &tc))
1205  ;
1206 
1207  else if (unformat (line_input, "tc_q %d", &tc_q))
1208  ;
1209 
1210  else
1211  return clib_error_return (0, "parse error: '%U'",
1212  format_unformat_error, line_input);
1213  }
1214 
1215  unformat_free (line_input);
1216 
1217  if (hw_if_index == (u32) ~ 0)
1218  return clib_error_return (0, "please specify interface name!!");
1219 
1220  hw = vnet_get_hw_interface (dm->vnet_main, hw_if_index);
1221  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
1222 
1223  rte_eth_dev_info_get (xd->device_index, &dev_info);
1224  if (dev_info.pci_dev)
1225  { /* bonded interface has no pci info */
1226  vlib_pci_addr_t pci_addr;
1227 
1228  pci_addr.domain = dev_info.pci_dev->addr.domain;
1229  pci_addr.bus = dev_info.pci_dev->addr.bus;
1230  pci_addr.slot = dev_info.pci_dev->addr.devid;
1231  pci_addr.function = dev_info.pci_dev->addr.function;
1232 
1233  p =
1234  hash_get (dm->conf->device_config_index_by_pci_addr, pci_addr.as_u32);
1235  }
1236 
1237  if (p)
1238  devconf = pool_elt_at_index (dm->conf->dev_confs, p[0]);
1239  else
1240  devconf = &dm->conf->default_devconf;
1241 
1242  if (devconf->hqos_enabled == 0)
1243  {
1244  vlib_cli_output (vm, "HQoS disabled for this interface");
1245  return 0;
1246  }
1247 
1248  /*
1249  * Figure out which queue to query. cf rte_sched_port_qindex. (Not sure why
1250  * that method isn't made public by DPDK - how _should_ we get the queue ID?)
1251  */
1252  qindex = subport * devconf->hqos.port.n_pipes_per_subport + pipe;
1253  qindex = qindex * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE + tc;
1254  qindex = qindex * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + tc_q;
1255 
1256  if (rte_sched_queue_read_stats (xd->hqos_ht->hqos, qindex, &stats, &qlen) !=
1257  0)
1258  return clib_error_return (0, "failed to read stats");
1259 
1260  vlib_cli_output (vm, "%=24s%=16s", "Stats Parameter", "Value");
1261  vlib_cli_output (vm, "%=24s%=16d", "Packets", stats.n_pkts);
1262  vlib_cli_output (vm, "%=24s%=16d", "Packets dropped", stats.n_pkts_dropped);
1263 #ifdef RTE_SCHED_RED
1264  vlib_cli_output (vm, "%=24s%=16d", "Packets dropped (RED)",
1265  stats.n_pkts_red_dropped);
1266 #endif
1267  vlib_cli_output (vm, "%=24s%=16d", "Bytes", stats.n_bytes);
1268  vlib_cli_output (vm, "%=24s%=16d", "Bytes dropped", stats.n_bytes_dropped);
1269 
1270 
1271  return 0;
1272 }
1273 
1274 /* *INDENT-OFF* */
1275 VLIB_CLI_COMMAND (cmd_show_dpdk_hqos_queue_stats, static) = {
1276  .path = "show dpdk hqos queue",
1277  .short_help = "show dpdk hqos queue <if-name> subport <subport> pipe <pipe> tc <tc> tc_q <tc_q>",
1278  .function = show_dpdk_hqos_queue_stats,
1279 };
1280 /* *INDENT-ON* */
1281 
1282 clib_error_t *
1284 {
1285  return 0;
1286 }
1287 
1289 
1290 /*
1291  * fd.io coding-style-patch-verification: ON
1292  *
1293  * Local Variables:
1294  * eval: (c-set-style "gnu")
1295  * End:
1296  */
unformat_function_t unformat_vnet_hw_interface
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:396
vmrglw vmrglh hi
char * file_name
File name of pcap output.
Definition: pcap.h:124
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
static clib_error_t * show_dpdk_hqos_queue_stats(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:1169
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:966
u32 n_packets_to_capture
Number of packets to capture.
Definition: pcap.h:127
dpdk_main_t dpdk_main
Definition: dpdk.h:428
static clib_error_t * show_dpdk_if_placement(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:326
int dpdk_hqos_validate_mask(u64 mask, u32 n)
Definition: hqos.c:171
static clib_error_t * set_dpdk_if_placement(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:383
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
static clib_error_t * set_dpdk_if_hqos_placement(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:514
u16 flags
Definition: dpdk.h:191
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:482
dpdk_device_and_queue_t ** devices_by_hqos_cpu
Definition: dpdk.h:366
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:521
struct rte_sched_port_params port
Definition: dpdk.h:288
vlib_buffer_main_t * buffer_main
Definition: main.h:104
struct rte_sched_port * hqos
Definition: dpdk.h:159
unformat_function_t unformat_vnet_sw_interface
static clib_error_t * show_dpdk_buffer(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:161
#define clib_error_report(e)
Definition: error.h:125
u8 * pcap_filename
Definition: dpdk.h:389
#define DPDK_DEVICE_FLAG_PMD
Definition: dpdk.h:194
clib_error_t * dpdk_port_setup(dpdk_main_t *dm, dpdk_device_t *xd)
Definition: init.c:65
struct rte_sched_pipe_params * pipe
Definition: dpdk.h:290
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
vlib_node_registration_t dpdk_input_node
(constructor) VLIB_REGISTER_NODE (dpdk_input_node)
Definition: node.c:662
dpdk_device_config_t default_devconf
Definition: dpdk.h:352
u32 pcap_pkts_to_capture
Definition: dpdk.h:391
int input_cpu_first_index
Definition: dpdk.h:408
static clib_error_t * set_dpdk_if_hqos_subport(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:653
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
static void unformat_free(unformat_input_t *i)
Definition: format.h:161
unsigned long u64
Definition: types.h:89
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:977
u32 device_index
Definition: dpdk.h:173
static clib_error_t * show_dpdk_if_hqos(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:960
dpdk_device_hqos_per_worker_thread_t * hqos_wt
Definition: dpdk.h:217
static heap_elt_t * first(heap_header_t *h)
Definition: heap.c:59
u32 pcap_sw_if_index
Definition: dpdk.h:390
char * name
Definition: main.h:98
static clib_error_t * pcap_trace_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:29
vlib_worker_thread_t * vlib_worker_threads
Definition: threads.c:54
#define hash_get(h, key)
Definition: hash.h:248
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:369
dpdk_device_and_queue_t ** devices_by_cpu
Definition: dpdk.h:365
static clib_error_t * set_dpdk_if_hqos_pipe(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:592
u32 vlib_hw_if_index
Definition: dpdk.h:175
pcap_main_t pcap_main
Definition: dpdk.h:388
#define vec_del1(v, i)
Delete the element at index I.
Definition: vec.h:765
int input_cpu_count
Definition: dpdk.h:409
u16 nb_rx_desc
Definition: dpdk.h:211
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:576
static clib_error_t * set_dpdk_if_hqos_pktfield(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:805
struct rte_mempool ** pktmbuf_pools
Definition: buffer.h:328
dpdk_device_t * devices
Definition: dpdk.h:364
u16 * cpu_socket_id_by_queue
Definition: dpdk.h:212
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:300
static clib_error_t * test_dpdk_buffer(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:198
dpdk_device_config_t * dev_confs
Definition: dpdk.h:353
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
static int dpdk_device_queue_sort(void *a1, void *a2)
Definition: cli.c:365
clib_error_t * pcap_write(pcap_main_t *pm)
Write PCAP file.
Definition: pcap.c:89
static clib_error_t * set_dpdk_if_desc(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:260
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
unsigned int u32
Definition: types.h:88
int hqos_cpu_count
Definition: dpdk.h:413
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
static clib_error_t * show_dpdk_if_hqos_placement(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:476
void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
static clib_error_t * set_dpdk_if_hqos_tctbl(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:731
dpdk_device_hqos_per_hqos_thread_t * hqos_ht
Definition: dpdk.h:218
static void vlib_node_set_state(vlib_main_t *vm, u32 node_index, vlib_node_state_t new_state)
Set node dispatch state.
Definition: node_funcs.h:146
uword * thread_registrations_by_name
Definition: threads.h:274
u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
u64 uword
Definition: types.h:112
template key/value backing page structure
Definition: bihash_doc.h:44
pcap_packet_type_t packet_type
Packet type.
Definition: pcap.h:130
unsigned short u16
Definition: types.h:57
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:920
vlib_main_t ** vlib_mains
#define hash_get_mem(h, key)
Definition: hash.h:268
struct clib_bihash_value offset
template key/value backing page structure
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
int hqos_cpu_first_index
Definition: dpdk.h:412
#define vec_foreach(var, vec)
Vector iterator.
#define clib_error_return(e, args...)
Definition: error.h:111
struct _unformat_input_t unformat_input_t
int tx_pcap_enable
Definition: dpdk.h:387
vnet_main_t * vnet_main
Definition: dpdk.h:424
u16 nb_tx_desc
Definition: dpdk.h:200
unformat_function_t unformat_line_input
Definition: format.h:281
uword * device_config_index_by_pci_addr
Definition: dpdk.h:354
u32 n_packets_captured
Number of packets currently captured.
Definition: pcap.h:133
CLIB vectors are ubiquitous dynamically resized arrays with by user defined "headers".
clib_error_t * dpdk_cli_init(vlib_main_t *vm)
Definition: cli.c:1283
dpdk_config_main_t * conf
Definition: dpdk.h:425