FD.io VPP  v16.09
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-gre/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 #if RTE_VERSION >= RTE_VERSION_NUM(16, 7, 0, 0)
173  unsigned count = rte_mempool_avail_count (rmp);
174  unsigned free_count = rte_mempool_in_use_count (rmp);
175 #else
176  unsigned count = rte_mempool_count (rmp);
177  unsigned free_count = rte_mempool_free_count (rmp);
178 #endif
179 
180  vlib_cli_output (vm,
181  "name=\"%s\" available = %7d allocated = %7d total = %7d\n",
182  rmp->name, (u32) count, (u32) free_count,
183  (u32) (count + free_count));
184  }
185  else
186  {
187  vlib_cli_output (vm, "rte_mempool is NULL (!)\n");
188  }
189  }
190  return 0;
191 }
192 
193 /* *INDENT-OFF* */
194 VLIB_CLI_COMMAND (cmd_show_dpdk_bufferr,static) = {
195  .path = "show dpdk buffer",
196  .short_help = "show dpdk buffer state",
197  .function = show_dpdk_buffer,
198  .is_mp_safe = 1,
199 };
200 /* *INDENT-ON* */
201 
202 static clib_error_t *
204  vlib_cli_command_t * cmd)
205 {
206  static u32 *allocated_buffers;
207  u32 n_alloc = 0;
208  u32 n_free = 0;
209  u32 first, actual_alloc;
210 
212  {
213  if (unformat (input, "allocate %d", &n_alloc))
214  ;
215  else if (unformat (input, "free %d", &n_free))
216  ;
217  else
218  break;
219  }
220 
221  if (n_free)
222  {
223  if (vec_len (allocated_buffers) < n_free)
224  return clib_error_return (0, "Can't free %d, only %d allocated",
225  n_free, vec_len (allocated_buffers));
226 
227  first = vec_len (allocated_buffers) - n_free;
228  vlib_buffer_free (vm, allocated_buffers + first, n_free);
229  _vec_len (allocated_buffers) = first;
230  }
231  if (n_alloc)
232  {
233  first = vec_len (allocated_buffers);
234  vec_validate (allocated_buffers,
235  vec_len (allocated_buffers) + n_alloc - 1);
236 
237  actual_alloc = vlib_buffer_alloc (vm, allocated_buffers + first,
238  n_alloc);
239  _vec_len (allocated_buffers) = first + actual_alloc;
240 
241  if (actual_alloc < n_alloc)
242  vlib_cli_output (vm, "WARNING: only allocated %d buffers",
243  actual_alloc);
244  }
245 
246  vlib_cli_output (vm, "Currently %d buffers allocated",
247  vec_len (allocated_buffers));
248 
249  if (allocated_buffers && vec_len (allocated_buffers) == 0)
250  vec_free (allocated_buffers);
251 
252  return 0;
253 }
254 
255 /* *INDENT-OFF* */
256 VLIB_CLI_COMMAND (cmd_test_dpdk_buffer,static) = {
257  .path = "test dpdk buffer",
258  .short_help = "test dpdk buffer [allocate <nn>][free <nn>]",
259  .function = test_dpdk_buffer,
260  .is_mp_safe = 1,
261 };
262 /* *INDENT-ON* */
263 
264 static void
266 {
267  vlib_cli_output (vm,
268  "device_index %d\n"
269  " last_burst_sz %d\n"
270  " max_burst_sz %d\n"
271  " full_frames_cnt %u\n"
272  " consec_full_frames_cnt %u\n"
273  " congestion_cnt %d\n"
274  " last_poll_time %llu\n"
275  " max_poll_delay %llu\n"
276  " discard_cnt %u\n"
277  " total_packet_cnt %u\n",
278  xd->device_index,
287 
288  u32 device_queue_sz = rte_eth_rx_queue_count (xd->device_index,
289  0 /* queue_id */ );
290  vlib_cli_output (vm, " device_queue_sz %u\n", device_queue_sz);
291 }
292 
293 static void
295 {
297  dpdk_main_t *dm = &dpdk_main;
298 
299  vlib_cli_output (vm,
300  "dpdk: (0x%04x) enabled:%d monitor:%d drop_all:%d\n"
301  " dpdk_queue_hi_thresh %d\n"
302  " consec_full_frames_hi_thresh %d\n"
303  "---------\n"
304  "worker: (0x%04x) enabled:%d monitor:%d\n"
305  " worker_queue_hi_thresh %d\n",
306  dm->efd.enabled,
307  ((dm->efd.enabled & DPDK_EFD_DISCARD_ENABLED) ? 1 : 0),
308  ((dm->efd.enabled & DPDK_EFD_MONITOR_ENABLED) ? 1 : 0),
309  ((dm->efd.enabled & DPDK_EFD_DROPALL_ENABLED) ? 1 : 0),
310  dm->efd.queue_hi_thresh,
312  tm->efd.enabled,
313  ((tm->efd.enabled & VLIB_EFD_DISCARD_ENABLED) ? 1 : 0),
314  ((dm->efd.enabled & VLIB_EFD_MONITOR_ENABLED) ? 1 : 0),
315  tm->efd.queue_hi_thresh);
316  vlib_cli_output (vm,
317  "---------\n"
318  "ip_prec_bitmap 0x%02x\n"
319  "mpls_exp_bitmap 0x%02x\n"
320  "vlan_cos_bitmap 0x%02x\n",
321  tm->efd.ip_prec_bitmap,
323 }
324 
325 static clib_error_t *
327  unformat_input_t * input, vlib_cli_command_t * cmd)
328 {
329 
330  if (unformat (input, "config"))
331  {
332  show_efd_config (vm);
333  }
334  else if (unformat (input, "dpdk"))
335  {
336  dpdk_main_t *dm = &dpdk_main;
337  dpdk_device_t *xd;
338  u32 device_id = ~0;
339 
340  (void) unformat (input, "device %d", &device_id);
341  /* *INDENT-OFF* */
342  vec_foreach (xd, dm->devices)
343  {
344  if ((xd->device_index == device_id) || (device_id == ~0))
345  {
346  show_dpdk_device_stats(vm, xd);
347  }
348  }
349  /* *INDENT-ON* */
350  }
351  else if (unformat (input, "worker"))
352  {
354  vlib_frame_queue_t *fq;
356  int thread_id;
357  u32 num_workers = 0;
358  u32 first_worker_index = 0;
359  uword *p;
360 
361  p = hash_get_mem (tm->thread_registrations_by_name, "workers");
362  ASSERT (p);
363  tr = (vlib_thread_registration_t *) p[0];
364  if (tr)
365  {
366  num_workers = tr->count;
367  first_worker_index = tr->first_index;
368  }
369 
370  vlib_cli_output (vm,
371  "num_workers %d\n"
372  "first_worker_index %d\n"
373  "vlib_frame_queues[%d]:\n",
374  num_workers, first_worker_index, tm->n_vlib_mains);
375 
376  for (thread_id = 0; thread_id < tm->n_vlib_mains; thread_id++)
377  {
378  fq = vlib_frame_queues[thread_id];
379  if (fq)
380  {
381  vlib_cli_output (vm,
382  "%2d: frames_queued %u\n"
383  " frames_queued_hint %u\n"
384  " enqueue_full_events %u\n"
385  " enqueue_efd_discards %u\n",
386  thread_id,
387  (fq->tail - fq->head),
388  (fq->tail - fq->head_hint),
391  }
392  }
393  }
394  else if (unformat (input, "help"))
395  {
396  vlib_cli_output (vm, "Usage: show efd config | "
397  "dpdk [device <id>] | worker\n");
398  }
399  else
400  {
401  show_efd_config (vm);
402  }
403 
404  return 0;
405 }
406 
407 /* *INDENT-OFF* */
408 VLIB_CLI_COMMAND (show_efd_command, static) = {
409  .path = "show efd",
410  .short_help = "Show efd [device <id>] | [config]",
411  .function = show_efd,
412 };
413 /* *INDENT-ON* */
414 
415 static clib_error_t *
417  unformat_input_t * input, vlib_cli_command_t * cmd)
418 {
419  dpdk_main_t *dm = &dpdk_main;
420  dpdk_device_t *xd;
422  vlib_frame_queue_t *fq;
423  int thread_id;
424 
425  /* *INDENT-OFF* */
426  vec_foreach (xd, dm->devices)
427  {
428  xd->efd_agent.last_burst_sz = 0;
429  xd->efd_agent.max_burst_sz = 0;
430  xd->efd_agent.full_frames_cnt = 0;
432  xd->efd_agent.congestion_cnt = 0;
433  xd->efd_agent.last_poll_time = 0;
434  xd->efd_agent.max_poll_delay = 0;
435  xd->efd_agent.discard_cnt = 0;
436  xd->efd_agent.total_packet_cnt = 0;
437  }
438  /* *INDENT-ON* */
439 
440  for (thread_id = 0; thread_id < tm->n_vlib_mains; thread_id++)
441  {
442  fq = vlib_frame_queues[thread_id];
443  if (fq)
444  {
445  fq->enqueue_full_events = 0;
446  fq->enqueue_efd_discards = 0;
447  }
448  }
449 
450  return 0;
451 }
452 
453 /* *INDENT-OFF* */
454 VLIB_CLI_COMMAND (clear_efd_command,static) = {
455  .path = "clear efd",
456  .short_help = "Clear early-fast-discard counters",
457  .function = clear_efd,
458 };
459 /* *INDENT-ON* */
460 
461 static clib_error_t *
463  vlib_cli_command_t * cmd,
464  char *prec_type, u8 * prec_bitmap)
465 {
466  clib_error_t *error = NULL;
467  u8 op = 0;
468  u8 prec = 0;
469 
470  if (unformat (input, "ge"))
471  {
473  }
474  else if (unformat (input, "lt"))
475  {
477  }
478  else if (unformat (input, "help"))
479  {
480  vlib_cli_output (vm, "enter operation [ge | lt] and precedence <0-7>)");
481  return (error);
482  }
483  else
484  {
485  return clib_error_return (0, "unknown input `%U'",
486  format_unformat_error, input);
487  }
488 
489  if (unformat (input, "%u", &prec))
490  {
491  if (prec > 7)
492  {
493  return clib_error_return (0, "precedence %d is out of range <0-7>",
494  prec);
495  }
496  }
497  else
498  {
499  return clib_error_return (0, "unknown input `%U'",
500  format_unformat_error, input);
501  }
502 
503  set_efd_bitmap (prec_bitmap, prec, op);
504 
505  vlib_cli_output (vm,
506  "EFD will be set for %s precedence %s%u%s.",
507  prec_type,
508  (op == EFD_OPERATION_LESS_THAN) ? "less than " : "",
509  prec,
510  (op ==
511  EFD_OPERATION_GREATER_OR_EQUAL) ? " and greater" : "");
512 
513  return (error);
514 }
515 
516 
517 static clib_error_t *
519 {
520  dpdk_main_t *dm = &dpdk_main;
522  clib_error_t *error = NULL;
524 
525  if (unformat (input, "enable"))
526  {
527  if (unformat (input, "dpdk"))
528  {
530  }
531  else if (unformat (input, "worker"))
532  {
534  }
535  else if (unformat (input, "monitor"))
536  {
539  }
540  else if (unformat (input, "drop_all"))
541  {
543  }
544  else if (unformat (input, "default"))
545  {
550  }
551  else
552  {
553  return clib_error_return (0, "Usage: set efd enable [dpdk | "
554  "worker | monitor | drop_all | default]");
555  }
556  }
557  else if (unformat (input, "disable"))
558  {
559  if (unformat (input, "dpdk"))
560  {
562  }
563  else if (unformat (input, "worker"))
564  {
566  }
567  else if (unformat (input, "monitor"))
568  {
571  }
572  else if (unformat (input, "drop_all"))
573  {
575  }
576  else if (unformat (input, "all"))
577  {
578  dm->efd.enabled = 0;
579  tm->efd.enabled = 0;
580  }
581  else
582  {
583  return clib_error_return (0, "Usage: set efd disable [dpdk | "
584  "worker | monitor | drop_all | all]");
585  }
586  }
587  else if (unformat (input, "worker_queue_hi_thresh"))
588  {
589  u32 mark;
590  if (unformat (input, "%u", &mark))
591  {
592  tm->efd.queue_hi_thresh = mark;
593  }
594  else
595  {
596  return clib_error_return (0, "unknown input `%U'",
597  format_unformat_error, input);
598  }
599  }
600  else if (unformat (input, "dpdk_device_hi_thresh"))
601  {
602  u32 thresh;
603  if (unformat (input, "%u", &thresh))
604  {
605  dm->efd.queue_hi_thresh = thresh;
606  }
607  else
608  {
609  return clib_error_return (0, "unknown input `%U'",
610  format_unformat_error, input);
611  }
612  }
613  else if (unformat (input, "consec_full_frames_hi_thresh"))
614  {
615  u32 thresh;
616  if (unformat (input, "%u", &thresh))
617  {
618  dm->efd.consec_full_frames_hi_thresh = thresh;
619  }
620  else
621  {
622  return clib_error_return (0, "unknown input `%U'",
623  format_unformat_error, input);
624  }
625  }
626  else if (unformat (input, "ip-prec"))
627  {
628  return (parse_op_and_prec (vm, input, cmd,
629  "ip", &tm->efd.ip_prec_bitmap));
630  }
631  else if (unformat (input, "mpls-exp"))
632  {
633  return (parse_op_and_prec (vm, input, cmd,
634  "mpls", &tm->efd.mpls_exp_bitmap));
635  }
636  else if (unformat (input, "vlan-cos"))
637  {
638  return (parse_op_and_prec (vm, input, cmd,
639  "vlan", &tm->efd.vlan_cos_bitmap));
640  }
641  else if (unformat (input, "help"))
642  {
643  vlib_cli_output (vm,
644  "Usage:\n"
645  " set efd enable <dpdk | worker | monitor | drop_all | default> |\n"
646  " set efd disable <dpdk | worker | monitor | drop_all | all> |\n"
647  " set efd <ip-prec | mpls-exp | vlan-cos> <ge | lt> <0-7>\n"
648  " set efd worker_queue_hi_thresh <0-32> |\n"
649  " set efd dpdk_device_hi_thresh <0-%d> |\n"
650  " set efd consec_full_frames_hi_thresh <count> |\n",
652  }
653  else
654  {
655  return clib_error_return (0, "unknown input `%U'",
656  format_unformat_error, input);
657  }
658 
659  if (dm->efd.enabled)
661  else if (dm->use_rss)
663  else
665 
666  return error;
667 }
668 
669 /* *INDENT-OFF* */
670 VLIB_CLI_COMMAND (cmd_set_efd,static) = {
671  .path = "set efd",
672  .short_help = "set early-fast-discard commands",
673  .function = set_efd,
674 };
675 /* *INDENT-ON* */
676 
677 static clib_error_t *
679  vlib_cli_command_t * cmd)
680 {
681  unformat_input_t _line_input, *line_input = &_line_input;
682  dpdk_main_t *dm = &dpdk_main;
684  dpdk_device_t *xd;
685  u32 hw_if_index = (u32) ~ 0;
686  u32 nb_rx_desc = (u32) ~ 0;
687  u32 nb_tx_desc = (u32) ~ 0;
688  clib_error_t *rv;
689 
690  if (!unformat_user (input, unformat_line_input, line_input))
691  return 0;
692 
693  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
694  {
695  if (unformat
696  (line_input, "%U", unformat_vnet_hw_interface, dm->vnet_main,
697  &hw_if_index))
698  ;
699  else if (unformat (line_input, "tx %d", &nb_tx_desc))
700  ;
701  else if (unformat (line_input, "rx %d", &nb_rx_desc))
702  ;
703  else
704  return clib_error_return (0, "parse error: '%U'",
705  format_unformat_error, line_input);
706  }
707 
708  unformat_free (line_input);
709 
710  if (hw_if_index == (u32) ~ 0)
711  return clib_error_return (0, "please specify valid interface name");
712 
713  hw = vnet_get_hw_interface (dm->vnet_main, hw_if_index);
714  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
715 
716  if (xd->dev_type != VNET_DPDK_DEV_ETH)
717  return clib_error_return (0, "number of descriptors can be set only for "
718  "physical devices");
719 
720  if ((nb_rx_desc == (u32) ~ 0 || nb_rx_desc == xd->nb_rx_desc) &&
721  (nb_tx_desc == (u32) ~ 0 || nb_tx_desc == xd->nb_tx_desc))
722  return clib_error_return (0, "nothing changed");
723 
724  if (nb_rx_desc != (u32) ~ 0)
725  xd->nb_rx_desc = nb_rx_desc;
726 
727  if (nb_tx_desc != (u32) ~ 0)
728  xd->nb_rx_desc = nb_rx_desc;
729 
730  rv = dpdk_port_setup (dm, xd);
731 
732  return rv;
733 }
734 
735 /* *INDENT-OFF* */
736 VLIB_CLI_COMMAND (cmd_set_dpdk_if_desc,static) = {
737  .path = "set dpdk interface descriptors",
738  .short_help = "set dpdk interface descriptors <if-name> [rx <n>] [tx <n>]",
739  .function = set_dpdk_if_desc,
740 };
741 /* *INDENT-ON* */
742 
743 static clib_error_t *
745  vlib_cli_command_t * cmd)
746 {
748  dpdk_main_t *dm = &dpdk_main;
750  int cpu;
751 
752  if (tm->n_vlib_mains == 1)
753  vlib_cli_output (vm, "All interfaces are handled by main thread");
754 
755  for (cpu = 0; cpu < vec_len (dm->devices_by_cpu); cpu++)
756  {
757  if (vec_len (dm->devices_by_cpu[cpu]))
758  vlib_cli_output (vm, "Thread %u (%s at lcore %u):", cpu,
759  vlib_worker_threads[cpu].name,
760  vlib_worker_threads[cpu].dpdk_lcore_id);
761 
762  /* *INDENT-OFF* */
763  vec_foreach(dq, dm->devices_by_cpu[cpu])
764  {
765  u32 hw_if_index = dm->devices[dq->device].vlib_hw_if_index;
767  vlib_cli_output(vm, " %v queue %u", hi->name, dq->queue_id);
768  }
769  /* *INDENT-ON* */
770  }
771  return 0;
772 }
773 
774 /* *INDENT-OFF* */
775 VLIB_CLI_COMMAND (cmd_show_dpdk_if_placement,static) = {
776  .path = "show dpdk interface placement",
777  .short_help = "show dpdk interface placement",
778  .function = show_dpdk_if_placement,
779 };
780 /* *INDENT-ON* */
781 
782 static int
783 dpdk_device_queue_sort (void *a1, void *a2)
784 {
785  dpdk_device_and_queue_t *dq1 = a1;
786  dpdk_device_and_queue_t *dq2 = a2;
787 
788  if (dq1->device > dq2->device)
789  return 1;
790  else if (dq1->device < dq2->device)
791  return -1;
792  else if (dq1->queue_id > dq2->queue_id)
793  return 1;
794  else if (dq1->queue_id < dq2->queue_id)
795  return -1;
796  else
797  return 0;
798 }
799 
800 static clib_error_t *
802  vlib_cli_command_t * cmd)
803 {
804  unformat_input_t _line_input, *line_input = &_line_input;
805  dpdk_main_t *dm = &dpdk_main;
808  dpdk_device_t *xd;
809  u32 hw_if_index = (u32) ~ 0;
810  u32 queue = (u32) 0;
811  u32 cpu = (u32) ~ 0;
812  int i;
813 
814  if (!unformat_user (input, unformat_line_input, line_input))
815  return 0;
816 
817  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
818  {
819  if (unformat
820  (line_input, "%U", unformat_vnet_hw_interface, dm->vnet_main,
821  &hw_if_index))
822  ;
823  else if (unformat (line_input, "queue %d", &queue))
824  ;
825  else if (unformat (line_input, "thread %d", &cpu))
826  ;
827  else
828  return clib_error_return (0, "parse error: '%U'",
829  format_unformat_error, line_input);
830  }
831 
832  unformat_free (line_input);
833 
834  if (hw_if_index == (u32) ~ 0)
835  return clib_error_return (0, "please specify valid interface name");
836 
837  if (cpu < dm->input_cpu_first_index ||
838  cpu >= (dm->input_cpu_first_index + dm->input_cpu_count))
839  return clib_error_return (0, "please specify valid thread id");
840 
841  hw = vnet_get_hw_interface (dm->vnet_main, hw_if_index);
842  xd = vec_elt_at_index (dm->devices, hw->dev_instance);
843 
844  for (i = 0; i < vec_len (dm->devices_by_cpu); i++)
845  {
846  /* *INDENT-OFF* */
847  vec_foreach(dq, dm->devices_by_cpu[i])
848  {
849  if (hw_if_index == dm->devices[dq->device].vlib_hw_if_index &&
850  queue == dq->queue_id)
851  {
852  if (cpu == i) /* nothing to do */
853  return 0;
854 
855  vec_del1(dm->devices_by_cpu[i], dq - dm->devices_by_cpu[i]);
856  vec_add2(dm->devices_by_cpu[cpu], dq, 1);
857  dq->queue_id = queue;
858  dq->device = xd->device_index;
859  xd->cpu_socket_id_by_queue[queue] =
860  rte_lcore_to_socket_id(vlib_worker_threads[cpu].dpdk_lcore_id);
861 
864 
867 
868  if (vec_len(dm->devices_by_cpu[i]) == 0)
870  VLIB_NODE_STATE_DISABLED);
871 
872  if (vec_len(dm->devices_by_cpu[cpu]) == 1)
874  VLIB_NODE_STATE_POLLING);
875 
876  return 0;
877  }
878  }
879  /* *INDENT-ON* */
880  }
881 
882  return clib_error_return (0, "not found");
883 }
884 
885 /* *INDENT-OFF* */
886 VLIB_CLI_COMMAND (cmd_set_dpdk_if_placement,static) = {
887  .path = "set dpdk interface placement",
888  .short_help = "set dpdk interface placement <if-name> [queue <n>] thread <n>",
889  .function = set_dpdk_if_placement,
890 };
891 /* *INDENT-ON* */
892 
893 clib_error_t *
895 {
896  return 0;
897 }
898 
900 
901 /*
902  * fd.io coding-style-patch-verification: ON
903  *
904  * Local Variables:
905  * eval: (c-set-style "gnu")
906  * End:
907  */
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
u16 enabled
Definition: dpdk.h:306
char * file_name
File name of pcap output.
Definition: pcap.h:124
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:966
static void show_dpdk_device_stats(vlib_main_t *vm, dpdk_device_t *xd)
Definition: cli.c:265
u32 n_packets_to_capture
Number of packets to capture.
Definition: pcap.h:127
u16 max_burst_sz
Definition: dpdk.h:135
dpdk_main_t dpdk_main
Definition: dpdk.h:443
static clib_error_t * show_dpdk_if_placement(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:744
#define VLIB_EFD_DISCARD_ENABLED
Definition: threads.h:244
u8 use_rss
Definition: dpdk.h:424
u64 last_poll_time
Definition: dpdk.h:139
static clib_error_t * set_dpdk_if_placement(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:801
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
#define NULL
Definition: clib.h:55
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
#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
static clib_error_t * parse_op_and_prec(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd, char *prec_type, u8 *prec_bitmap)
Definition: cli.c:462
vlib_buffer_main_t * buffer_main
Definition: main.h:104
vlib_worker_thread_t * vlib_worker_threads
Definition: threads.h:110
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
u32 congestion_cnt
Definition: dpdk.h:138
u8 * pcap_filename
Definition: dpdk.h:403
clib_error_t * dpdk_port_setup(dpdk_main_t *dm, dpdk_device_t *xd)
Definition: init.c:65
u8 mpls_exp_bitmap
Definition: threads.h:255
void * dpdk_input_efd_multiarch_select()
vlib_node_function_t * function
Definition: node.h:415
#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:787
u32 pcap_pkts_to_capture
Definition: dpdk.h:405
u16 queue_hi_thresh
Definition: threads.h:253
int input_cpu_first_index
Definition: dpdk.h:427
#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
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:977
vlib_frame_queue_t ** vlib_frame_queues
Definition: threads.h:142
u32 device_index
Definition: dpdk.h:199
#define VLIB_EFD_MONITOR_ENABLED
Definition: threads.h:245
void * dpdk_input_multiarch_select()
static heap_elt_t * first(heap_header_t *h)
Definition: heap.c:59
u32 pcap_sw_if_index
Definition: dpdk.h:404
u16 consec_full_frames_hi_thresh
Definition: dpdk.h:308
vlib_main_t ** vlib_mains
Definition: dpdk_buffer.c:157
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
volatile u64 head
Definition: threads.h:124
dpdk_device_and_queue_t ** devices_by_cpu
Definition: dpdk.h:379
u64 max_poll_delay
Definition: dpdk.h:140
static clib_error_t * clear_efd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:416
u32 consec_full_frames_cnt
Definition: dpdk.h:137
u32 vlib_hw_if_index
Definition: dpdk.h:201
#define DPDK_EFD_DISCARD_ENABLED
Definition: dpdk.h:297
pcap_main_t pcap_main
Definition: dpdk.h:402
u16 last_burst_sz
Definition: dpdk.h:134
#define DPDK_EFD_MONITOR_ENABLED
Definition: dpdk.h:298
#define vec_del1(v, i)
Delete the element at index I.
Definition: vec.h:765
u32 full_frames_cnt
Definition: dpdk.h:136
int input_cpu_count
Definition: dpdk.h:428
u16 nb_rx_desc
Definition: dpdk.h:231
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:575
struct rte_mempool ** pktmbuf_pools
Definition: buffer.h:321
volatile u64 tail
Definition: threads.h:115
dpdk_device_t * devices
Definition: dpdk.h:378
u8 ip_prec_bitmap
Definition: threads.h:254
u16 * cpu_socket_id_by_queue
Definition: dpdk.h:233
#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:203
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
u16 queue_hi_thresh
Definition: dpdk.h:307
u8 vlan_cos_bitmap
Definition: threads.h:256
static vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Get node runtime by node index.
Definition: node_funcs.h:88
static int dpdk_device_queue_sort(void *a1, void *a2)
Definition: cli.c:783
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:678
#define EFD_OPERATION_GREATER_OR_EQUAL
Definition: dpdk.h:568
u32 discard_cnt
Definition: dpdk.h:141
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
void * dpdk_input_rss_multiarch_select()
u8 * format(u8 *s, char *fmt,...)
Definition: format.c:418
dpdk_efd_t efd
Definition: dpdk.h:416
void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
Definition: dpdk_buffer.c:766
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:144
uword * thread_registrations_by_name
Definition: threads.h:268
u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
Definition: dpdk_buffer.c:643
#define DPDK_NB_RX_DESC_10GE
Definition: dpdk_priv.h:20
u64 uword
Definition: types.h:112
static clib_error_t * show_efd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:326
pcap_packet_type_t packet_type
Packet type.
Definition: pcap.h:130
u32 enqueue_full_events
Definition: threads.h:119
VLIB_CLI_COMMAND(set_interface_ip_source_and_port_range_check_command, static)
static clib_error_t * set_efd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:518
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
dpdk_device_type_t dev_type
Definition: dpdk.h:217
unsigned char u8
Definition: types.h:56
dpdk_efd_agent_t efd_agent
Definition: dpdk.h:268
#define DPDK_EFD_DROPALL_ENABLED
Definition: dpdk.h:299
void set_efd_bitmap(u8 *bitmap, u32 value, u32 op)
Definition: node.c:854
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:900
u32 enqueue_efd_discards
Definition: threads.h:120
volatile u64 head_hint
Definition: threads.h:133
#define hash_get_mem(h, key)
Definition: hash.h:268
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
#define vec_foreach(var, vec)
Vector iterator.
#define EFD_OPERATION_LESS_THAN
Definition: dpdk.h:567
u32 total_packet_cnt
Definition: dpdk.h:142
#define clib_error_return(e, args...)
Definition: error.h:111
struct _unformat_input_t unformat_input_t
int tx_pcap_enable
Definition: dpdk.h:401
vnet_main_t * vnet_main
Definition: dpdk.h:439
u16 nb_tx_desc
Definition: dpdk.h:232
unformat_function_t unformat_line_input
Definition: format.h:281
static void show_efd_config(vlib_main_t *vm)
Definition: cli.c:294
u32 n_packets_captured
Number of packets currently captured.
Definition: pcap.h:133
u16 enabled
Definition: threads.h:252
vlib_efd_t efd
Definition: threads.h:305
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:894