FD.io VPP  v16.12-rc0-308-g931be3a
Vector Packet Processing
init.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/bitmap.h>
20 
21 #include <vnet/ethernet/ethernet.h>
22 #include <vnet/devices/dpdk/dpdk.h>
23 #include <vlib/unix/physmem.h>
24 #include <vlib/pci/pci.h>
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <sys/stat.h>
30 #include <sys/mount.h>
31 #include <string.h>
32 #include <fcntl.h>
33 
34 #include "dpdk_priv.h"
35 
37 
38 /* force linker to link functions used by vlib and declared weak */
40  &rte_pktmbuf_init,
41  &rte_pktmbuf_pool_init,
42 };
43 
44 #define LINK_STATE_ELOGS 0
45 
46 #define DEFAULT_HUGE_DIR "/run/vpp/hugepages"
47 #define VPP_RUN_DIR "/run/vpp"
48 
49 /* Port configuration, mildly modified Intel app values */
50 
51 static struct rte_eth_conf port_conf_template = {
52  .rxmode = {
53  .split_hdr_size = 0,
54  .header_split = 0, /**< Header Split disabled */
55  .hw_ip_checksum = 0, /**< IP checksum offload disabled */
56  .hw_vlan_filter = 0, /**< VLAN filtering disabled */
57  .hw_strip_crc = 0, /**< CRC stripped by hardware */
58  },
59  .txmode = {
60  .mq_mode = ETH_MQ_TX_NONE,
61  },
62 };
63 
66 {
67  vlib_main_t *vm = vlib_get_main ();
69  int rv;
70  int j;
71 
72  ASSERT (os_get_cpu_number () == 0);
73 
75  {
77  rte_eth_dev_stop (xd->device_index);
78  }
79 
80  rv = rte_eth_dev_configure (xd->device_index, xd->rx_q_used,
81  xd->tx_q_used, &xd->port_conf);
82 
83  if (rv < 0)
84  return clib_error_return (0, "rte_eth_dev_configure[%d]: err %d",
85  xd->device_index, rv);
86 
87  /* Set up one TX-queue per worker thread */
88  for (j = 0; j < xd->tx_q_used; j++)
89  {
90  rv = rte_eth_tx_queue_setup (xd->device_index, j, xd->nb_tx_desc,
91  xd->cpu_socket, &xd->tx_conf);
92 
93  /* retry with any other CPU socket */
94  if (rv < 0)
95  rv = rte_eth_tx_queue_setup (xd->device_index, j, xd->nb_tx_desc,
96  SOCKET_ID_ANY, &xd->tx_conf);
97  if (rv < 0)
98  break;
99  }
100 
101  if (rv < 0)
102  return clib_error_return (0, "rte_eth_tx_queue_setup[%d]: err %d",
103  xd->device_index, rv);
104 
105  for (j = 0; j < xd->rx_q_used; j++)
106  {
107 
108  rv = rte_eth_rx_queue_setup (xd->device_index, j, xd->nb_rx_desc,
109  xd->cpu_socket, 0,
110  bm->
111  pktmbuf_pools[xd->cpu_socket_id_by_queue
112  [j]]);
113 
114  /* retry with any other CPU socket */
115  if (rv < 0)
116  rv = rte_eth_rx_queue_setup (xd->device_index, j, xd->nb_rx_desc,
117  SOCKET_ID_ANY, 0,
118  bm->
119  pktmbuf_pools[xd->cpu_socket_id_by_queue
120  [j]]);
121  if (rv < 0)
122  return clib_error_return (0, "rte_eth_rx_queue_setup[%d]: err %d",
123  xd->device_index, rv);
124  }
125 
127  {
128  int rv;
129  rv = rte_eth_dev_start (xd->device_index);
130  if (rv < 0)
131  clib_warning ("rte_eth_dev_start %d returned %d",
132  xd->device_index, rv);
133  }
134  return 0;
135 }
136 
137 static u32
139 {
140  dpdk_main_t *dm = &dpdk_main;
142  u32 old = 0;
143 
145  {
146  old = (xd->flags & DPDK_DEVICE_FLAG_PROMISC) != 0;
147 
150  else
152 
154  {
156  rte_eth_promiscuous_enable (xd->device_index);
157  else
158  rte_eth_promiscuous_disable (xd->device_index);
159  }
160  }
161  else if (ETHERNET_INTERFACE_FLAG_CONFIG_MTU (flags))
162  {
163  /*
164  * DAW-FIXME: The Cisco VIC firmware does not provide an api for a
165  * driver to dynamically change the mtu. If/when the
166  * VIC firmware gets fixed, then this should be removed.
167  */
168  if (xd->pmd == VNET_DPDK_PMD_ENIC)
169  {
170  struct rte_eth_dev_info dev_info;
171 
172  /*
173  * Restore mtu to what has been set by CIMC in the firmware cfg.
174  */
175  rte_eth_dev_info_get (xd->device_index, &dev_info);
176  hi->max_packet_bytes = dev_info.max_rx_pktlen;
177 
179  "Cisco VIC mtu can only be changed "
180  "using CIMC then rebooting the server!");
181  }
182  else
183  {
184  int rv;
185 
186  xd->port_conf.rxmode.max_rx_pkt_len = hi->max_packet_bytes;
187 
189  rte_eth_dev_stop (xd->device_index);
190 
191  rv = rte_eth_dev_configure
192  (xd->device_index, xd->rx_q_used, xd->tx_q_used, &xd->port_conf);
193 
194  if (rv < 0)
196  "rte_eth_dev_configure[%d]: err %d",
197  xd->device_index, rv);
198 
199  rte_eth_dev_set_mtu (xd->device_index, hi->max_packet_bytes);
200 
202  {
203  int rv = rte_eth_dev_start (xd->device_index);
204  if (rv < 0)
205  clib_warning ("rte_eth_dev_start %d returned %d",
206  xd->device_index, rv);
207  }
208  }
209  }
210  return old;
211 }
212 
213 void
215 {
216  int q;
217  vec_validate (xd->lockp, xd->tx_q_used - 1);
218  for (q = 0; q < xd->tx_q_used; q++)
219  {
222  memset ((void *) xd->lockp[q], 0, CLIB_CACHE_LINE_BYTES);
223  }
224 }
225 
226 void
228 {
229  int q;
230 
231  for (q = 0; q < vec_len (xd->lockp); q++)
232  clib_mem_free ((void *) xd->lockp[q]);
233  vec_free (xd->lockp);
234  xd->lockp = 0;
235 }
236 
237 static clib_error_t *
239 {
240  u32 nports;
241  u32 nb_desc = 0;
242  int i;
243  clib_error_t *error;
244  vlib_main_t *vm = vlib_get_main ();
249  dpdk_device_t *xd;
250  vlib_pci_addr_t last_pci_addr;
251  u32 last_pci_addr_port = 0;
252  vlib_thread_registration_t *tr, *tr_hqos;
253  uword *p, *p_hqos;
254 
255  u32 next_cpu = 0, next_hqos_cpu = 0;
256  u8 af_packet_port_id = 0;
257  last_pci_addr.as_u32 = ~0;
258 
259  dm->input_cpu_first_index = 0;
260  dm->input_cpu_count = 1;
261 
262  rt = vlib_node_get_runtime (vm, dpdk_input_node.index);
264 
265  /* find out which cpus will be used for input */
266  p = hash_get_mem (tm->thread_registrations_by_name, "workers");
267  tr = p ? (vlib_thread_registration_t *) p[0] : 0;
268 
269  if (tr && tr->count > 0)
270  {
272  dm->input_cpu_count = tr->count;
273  }
274 
277 
280 
281  dm->hqos_cpu_first_index = 0;
282  dm->hqos_cpu_count = 0;
283 
284  /* find out which cpus will be used for I/O TX */
285  p_hqos = hash_get_mem (tm->thread_registrations_by_name, "hqos-threads");
286  tr_hqos = p_hqos ? (vlib_thread_registration_t *) p_hqos[0] : 0;
287 
288  if (tr_hqos && tr_hqos->count > 0)
289  {
290  dm->hqos_cpu_first_index = tr_hqos->first_index;
291  dm->hqos_cpu_count = tr_hqos->count;
292  }
293 
296 
299 
300 #ifdef NETMAP
301  if (rte_netmap_probe () < 0)
302  return clib_error_return (0, "rte netmap probe failed");
303 #endif
304 
305  nports = rte_eth_dev_count ();
306  if (nports < 1)
307  {
308  clib_warning ("DPDK drivers found no ports...");
309  }
310 
311  if (CLIB_DEBUG > 0)
312  clib_warning ("DPDK drivers found %d ports...", nports);
313 
314  /*
315  * All buffers are all allocated from the same rte_mempool.
316  * Thus they all have the same number of data bytes.
317  */
321  "dpdk rx");
322 
323  if (dm->conf->enable_tcp_udp_checksum)
326 
327  for (i = 0; i < nports; i++)
328  {
329  u8 addr[6];
330  u8 vlan_strip = 0;
331  int j;
332  struct rte_eth_dev_info dev_info;
333  clib_error_t *rv;
334  struct rte_eth_link l;
335  dpdk_device_config_t *devconf = 0;
336  vlib_pci_addr_t pci_addr;
337  uword *p = 0;
338 
339  rte_eth_dev_info_get (i, &dev_info);
340  if (dev_info.pci_dev) /* bonded interface has no pci info */
341  {
342  pci_addr.domain = dev_info.pci_dev->addr.domain;
343  pci_addr.bus = dev_info.pci_dev->addr.bus;
344  pci_addr.slot = dev_info.pci_dev->addr.devid;
345  pci_addr.function = dev_info.pci_dev->addr.function;
346  p =
348  pci_addr.as_u32);
349  }
350 
351  if (p)
352  devconf = pool_elt_at_index (dm->conf->dev_confs, p[0]);
353  else
354  devconf = &dm->conf->default_devconf;
355 
356  /* Create vnet interface */
360  xd->cpu_socket = (i8) rte_eth_dev_socket_id (i);
361 
362  /* Handle interface naming for devices with multiple ports sharing same PCI ID */
363  if (dev_info.pci_dev)
364  {
365  struct rte_eth_dev_info di = { 0 };
366  rte_eth_dev_info_get (i + 1, &di);
367  if (di.pci_dev && pci_addr.as_u32 != last_pci_addr.as_u32 &&
368  memcmp (&dev_info.pci_dev->addr, &di.pci_dev->addr,
369  sizeof (struct rte_pci_addr)) == 0)
370  {
371  xd->interface_name_suffix = format (0, "0");
372  last_pci_addr.as_u32 = pci_addr.as_u32;
373  last_pci_addr_port = i;
374  }
375  else if (pci_addr.as_u32 == last_pci_addr.as_u32)
376  {
378  format (0, "%u", i - last_pci_addr_port);
379  }
380  else
381  {
382  last_pci_addr.as_u32 = ~0;
383  }
384  }
385  else
386  last_pci_addr.as_u32 = ~0;
387 
388  clib_memcpy (&xd->tx_conf, &dev_info.default_txconf,
389  sizeof (struct rte_eth_txconf));
390  if (dm->conf->no_multi_seg)
391  {
392  xd->tx_conf.txq_flags |= ETH_TXQ_FLAGS_NOMULTSEGS;
393  port_conf_template.rxmode.jumbo_frame = 0;
394  }
395  else
396  {
397  xd->tx_conf.txq_flags &= ~ETH_TXQ_FLAGS_NOMULTSEGS;
398  port_conf_template.rxmode.jumbo_frame = 1;
399  }
400 
402  sizeof (struct rte_eth_conf));
403 
404  xd->tx_q_used = clib_min (dev_info.max_tx_queues, tm->n_vlib_mains);
405 
406  if (devconf->num_tx_queues > 0
407  && devconf->num_tx_queues < xd->tx_q_used)
408  xd->tx_q_used = clib_min (xd->tx_q_used, devconf->num_tx_queues);
409 
410  if (devconf->num_rx_queues > 1 && dm->use_rss == 0)
411  {
413  dm->use_rss = 1;
414  }
415 
416  if (devconf->num_rx_queues > 1
417  && dev_info.max_rx_queues >= devconf->num_rx_queues)
418  {
419  xd->rx_q_used = devconf->num_rx_queues;
420  xd->port_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
421  if (devconf->rss_fn == 0)
422  xd->port_conf.rx_adv_conf.rss_conf.rss_hf =
423  ETH_RSS_IP | ETH_RSS_UDP | ETH_RSS_TCP;
424  else
425  xd->port_conf.rx_adv_conf.rss_conf.rss_hf = devconf->rss_fn;
426  }
427  else
428  xd->rx_q_used = 1;
429 
431 
432  /* workaround for drivers not setting driver_name */
433  if ((!dev_info.driver_name) && (dev_info.pci_dev))
434 #if RTE_VERSION < RTE_VERSION_NUM(16, 11, 0, 0)
435  dev_info.driver_name = dev_info.pci_dev->driver->name;
436 #else
437  dev_info.driver_name = dev_info.pci_dev->driver->driver.name;
438 #endif
439  ASSERT (dev_info.driver_name);
440 
441  if (!xd->pmd)
442  {
443 
444 
445 #define _(s,f) else if (dev_info.driver_name && \
446  !strcmp(dev_info.driver_name, s)) \
447  xd->pmd = VNET_DPDK_PMD_##f;
448  if (0)
449  ;
451 #undef _
452  else
454 
455 
456  switch (xd->pmd)
457  {
458  /* 1G adapters */
459  case VNET_DPDK_PMD_E1000EM:
460  case VNET_DPDK_PMD_IGB:
461  case VNET_DPDK_PMD_IGBVF:
463  break;
464 
465  /* 10G adapters */
466  case VNET_DPDK_PMD_IXGBE:
467  case VNET_DPDK_PMD_IXGBEVF:
468  case VNET_DPDK_PMD_THUNDERX:
472  break;
473  case VNET_DPDK_PMD_DPAA2:
475  break;
476 
477  /* Cisco VIC */
478  case VNET_DPDK_PMD_ENIC:
479  rte_eth_link_get_nowait (i, &l);
481  if (l.link_speed == 40000)
482  {
485  }
486  else
487  {
490  }
491  break;
492 
493  /* Intel Fortville */
494  case VNET_DPDK_PMD_I40E:
495  case VNET_DPDK_PMD_I40EVF:
499 
500  switch (dev_info.pci_dev->id.device_id)
501  {
505  break;
506  case I40E_DEV_ID_QSFP_A:
507  case I40E_DEV_ID_QSFP_B:
508  case I40E_DEV_ID_QSFP_C:
510  break;
511  case I40E_DEV_ID_VF:
512  rte_eth_link_get_nowait (i, &l);
513  xd->port_type = l.link_speed == 10000 ?
515  break;
516  default:
518  }
519  break;
520 
521  case VNET_DPDK_PMD_CXGBE:
522  switch (dev_info.pci_dev->id.device_id)
523  {
524  case 0x540d: /* T580-CR */
525  case 0x5410: /* T580-LP-cr */
529  break;
530  case 0x5403: /* T540-CR */
534  break;
535  default:
539  }
540  break;
541 
542  /* Intel Red Rock Canyon */
543  case VNET_DPDK_PMD_FM10K:
547  break;
548 
549  /* virtio */
550  case VNET_DPDK_PMD_VIRTIO:
554  break;
555 
556  /* vmxnet3 */
557  case VNET_DPDK_PMD_VMXNET3:
559  xd->tx_conf.txq_flags |= ETH_TXQ_FLAGS_NOMULTSEGS;
560  break;
561 
562  case VNET_DPDK_PMD_AF_PACKET:
564  xd->af_packet_port_id = af_packet_port_id++;
565  break;
566 
567  case VNET_DPDK_PMD_BOND:
569  break;
570 
571  default:
573  }
574 
575  if (devconf->num_rx_desc)
576  xd->nb_rx_desc = devconf->num_rx_desc;
577 
578  if (devconf->num_tx_desc)
579  xd->nb_tx_desc = devconf->num_tx_desc;
580  }
581 
582  /*
583  * Ensure default mtu is not > the mtu read from the hardware.
584  * Otherwise rte_eth_dev_configure() will fail and the port will
585  * not be available.
586  */
587  if (ETHERNET_MAX_PACKET_BYTES > dev_info.max_rx_pktlen)
588  {
589  /*
590  * This device does not support the platforms's max frame
591  * size. Use it's advertised mru instead.
592  */
593  xd->port_conf.rxmode.max_rx_pkt_len = dev_info.max_rx_pktlen;
594  }
595  else
596  {
597  xd->port_conf.rxmode.max_rx_pkt_len = ETHERNET_MAX_PACKET_BYTES;
598 
599  /*
600  * Some platforms do not account for Ethernet FCS (4 bytes) in
601  * MTU calculations. To interop with them increase mru but only
602  * if the device's settings can support it.
603  */
604  if ((dev_info.max_rx_pktlen >= (ETHERNET_MAX_PACKET_BYTES + 4)) &&
605  xd->port_conf.rxmode.hw_strip_crc)
606  {
607  /*
608  * Allow additional 4 bytes (for Ethernet FCS). These bytes are
609  * stripped by h/w and so will not consume any buffer memory.
610  */
611  xd->port_conf.rxmode.max_rx_pkt_len += 4;
612  }
613  }
614 
615  if (xd->pmd == VNET_DPDK_PMD_AF_PACKET)
616  {
617  f64 now = vlib_time_now (vm);
618  u32 rnd;
619  rnd = (u32) (now * 1e6);
620  rnd = random_u32 (&rnd);
621  clib_memcpy (addr + 2, &rnd, sizeof (rnd));
622  addr[0] = 2;
623  addr[1] = 0xfe;
624  }
625  else
626  rte_eth_macaddr_get (i, (struct ether_addr *) addr);
627 
628  if (xd->tx_q_used < tm->n_vlib_mains)
630 
631  xd->device_index = xd - dm->devices;
632  ASSERT (i == xd->device_index);
633  xd->per_interface_next_index = ~0;
634 
635  /* assign interface to input thread */
637  int q;
638 
639  if (devconf->workers)
640  {
641  int i;
642  q = 0;
643  /* *INDENT-OFF* */
644  clib_bitmap_foreach (i, devconf->workers, ({
645  int cpu = dm->input_cpu_first_index + i;
646  unsigned lcore = vlib_worker_threads[cpu].lcore_id;
647  vec_validate(xd->cpu_socket_id_by_queue, q);
648  xd->cpu_socket_id_by_queue[q] = rte_lcore_to_socket_id(lcore);
649  vec_add2(dm->devices_by_cpu[cpu], dq, 1);
650  dq->device = xd->device_index;
651  dq->queue_id = q++;
652  }));
653  /* *INDENT-ON* */
654  }
655  else
656  for (q = 0; q < xd->rx_q_used; q++)
657  {
658  int cpu = dm->input_cpu_first_index + next_cpu;
659  unsigned lcore = vlib_worker_threads[cpu].lcore_id;
660 
661  /*
662  * numa node for worker thread handling this queue
663  * needed for taking buffers from the right mempool
664  */
666  xd->cpu_socket_id_by_queue[q] = rte_lcore_to_socket_id (lcore);
667 
668  /*
669  * construct vector of (device,queue) pairs for each worker thread
670  */
671  vec_add2 (dm->devices_by_cpu[cpu], dq, 1);
672  dq->device = xd->device_index;
673  dq->queue_id = q;
674 
675  next_cpu++;
676  if (next_cpu == dm->input_cpu_count)
677  next_cpu = 0;
678  }
679 
680 
681  if (devconf->hqos_enabled)
682  {
684 
685  if (devconf->hqos.hqos_thread_valid)
686  {
687  int cpu = dm->hqos_cpu_first_index + devconf->hqos.hqos_thread;
688 
689  if (devconf->hqos.hqos_thread >= dm->hqos_cpu_count)
690  return clib_error_return (0, "invalid HQoS thread index");
691 
692  vec_add2 (dm->devices_by_hqos_cpu[cpu], dq, 1);
693  dq->device = xd->device_index;
694  dq->queue_id = 0;
695  }
696  else
697  {
698  int cpu = dm->hqos_cpu_first_index + next_hqos_cpu;
699 
700  if (dm->hqos_cpu_count == 0)
701  return clib_error_return (0, "no HQoS threads available");
702 
703  vec_add2 (dm->devices_by_hqos_cpu[cpu], dq, 1);
704  dq->device = xd->device_index;
705  dq->queue_id = 0;
706 
707  next_hqos_cpu++;
708  if (next_hqos_cpu == dm->hqos_cpu_count)
709  next_hqos_cpu = 0;
710 
711  devconf->hqos.hqos_thread_valid = 1;
712  devconf->hqos.hqos_thread = cpu;
713  }
714  }
715 
718  for (j = 0; j < tm->n_vlib_mains; j++)
719  {
722  vec_reset_length (xd->tx_vectors[j]);
723  }
724 
727  for (j = 0; j < xd->rx_q_used; j++)
728  {
731  vec_reset_length (xd->rx_vectors[j]);
732  }
733 
734  rv = dpdk_port_setup (dm, xd);
735 
736  if (rv)
737  return rv;
738 
739  if (devconf->hqos_enabled)
740  {
741  rv = dpdk_port_setup_hqos (xd, &devconf->hqos);
742  if (rv < 0)
743  return rv;
744  }
745 
746  /* count the number of descriptors used for this device */
747  nb_desc += xd->nb_rx_desc + xd->nb_tx_desc * xd->tx_q_used;
748 
750  (dm->vnet_main, dpdk_device_class.index, xd->device_index,
751  /* ethernet address */ addr,
753  if (error)
754  return error;
755 
757  xd->vlib_sw_if_index = sw->sw_if_index;
759 
760  /*
761  * DAW-FIXME: The Cisco VIC firmware does not provide an api for a
762  * driver to dynamically change the mtu. If/when the
763  * VIC firmware gets fixed, then this should be removed.
764  */
765  if (xd->pmd == VNET_DPDK_PMD_ENIC)
766  {
767  /*
768  * Initialize mtu to what has been set by CIMC in the firmware cfg.
769  */
770  hi->max_packet_bytes = dev_info.max_rx_pktlen;
771  if (devconf->vlan_strip_offload != DPDK_DEVICE_VLAN_STRIP_OFF)
772  vlan_strip = 1; /* remove vlan tag from VIC port by default */
773  else
774  clib_warning ("VLAN strip disabled for interface\n");
775  }
776  else if (devconf->vlan_strip_offload == DPDK_DEVICE_VLAN_STRIP_ON)
777  vlan_strip = 1;
778 
779  if (vlan_strip)
780  {
781  int vlan_off;
782  vlan_off = rte_eth_dev_get_vlan_offload (xd->device_index);
783  vlan_off |= ETH_VLAN_STRIP_OFFLOAD;
784  if (rte_eth_dev_set_vlan_offload (xd->device_index, vlan_off) == 0)
785  clib_warning ("VLAN strip enabled for interface\n");
786  else
787  clib_warning ("VLAN strip cannot be supported by interface\n");
788  }
789 
791  xd->port_conf.rxmode.max_rx_pkt_len - sizeof (ethernet_header_t);
792 
793  rte_eth_dev_set_mtu (xd->device_index, hi->max_packet_bytes);
794  }
795 
796  if (nb_desc > dm->conf->num_mbufs)
797  clib_warning ("%d mbufs allocated but total rx/tx ring size is %d\n",
798  dm->conf->num_mbufs, nb_desc);
799 
800  return 0;
801 }
802 
803 static void
805 {
806  vlib_pci_main_t *pm = &pci_main;
807  clib_error_t *error;
809  u8 *pci_addr = 0;
810  int num_whitelisted = vec_len (conf->dev_confs);
811 
812  /* *INDENT-OFF* */
813  pool_foreach (d, pm->pci_devs, ({
814  dpdk_device_config_t * devconf = 0;
815  vec_reset_length (pci_addr);
816  pci_addr = format (pci_addr, "%U%c", format_vlib_pci_addr, &d->bus_address, 0);
817 
818  if (d->device_class != PCI_CLASS_NETWORK_ETHERNET)
819  continue;
820 
821  if (num_whitelisted)
822  {
823  uword * p = hash_get (conf->device_config_index_by_pci_addr, d->bus_address.as_u32);
824 
825  if (!p)
826  continue;
827 
828  devconf = pool_elt_at_index (conf->dev_confs, p[0]);
829  }
830 
831  /* virtio */
832  if (d->vendor_id == 0x1af4 && d->device_id == 0x1000)
833  ;
834  /* vmxnet3 */
835  else if (d->vendor_id == 0x15ad && d->device_id == 0x07b0)
836  ;
837  /* all Intel devices */
838  else if (d->vendor_id == 0x8086)
839  ;
840  /* Cisco VIC */
841  else if (d->vendor_id == 0x1137 && d->device_id == 0x0043)
842  ;
843  /* Chelsio T4/T5 */
844  else if (d->vendor_id == 0x1425 && (d->device_id & 0xe000) == 0x4000)
845  ;
846  else
847  {
848  clib_warning ("Unsupported Ethernet PCI device 0x%04x:0x%04x found "
849  "at PCI address %s\n", (u16) d->vendor_id, (u16) d->device_id,
850  pci_addr);
851  continue;
852  }
853 
854  error = vlib_pci_bind_to_uio (d, (char *) conf->uio_driver_name);
855 
856  if (error)
857  {
858  if (devconf == 0)
859  {
860  pool_get (conf->dev_confs, devconf);
862  devconf - conf->dev_confs);
863  devconf->pci_addr.as_u32 = d->bus_address.as_u32;
864  }
865  devconf->is_blacklisted = 1;
866  clib_error_report (error);
867  }
868  }));
869  /* *INDENT-ON* */
870  vec_free (pci_addr);
871 }
872 
873 static clib_error_t *
874 dpdk_device_config (dpdk_config_main_t * conf, vlib_pci_addr_t pci_addr,
875  unformat_input_t * input, u8 is_default)
876 {
877  clib_error_t *error = 0;
878  uword *p;
879  dpdk_device_config_t *devconf;
880  unformat_input_t sub_input;
881 
882  if (is_default)
883  {
884  devconf = &conf->default_devconf;
885  }
886  else
887  {
888  p = hash_get (conf->device_config_index_by_pci_addr, pci_addr.as_u32);
889 
890  if (!p)
891  {
892  pool_get (conf->dev_confs, devconf);
893  hash_set (conf->device_config_index_by_pci_addr, pci_addr.as_u32,
894  devconf - conf->dev_confs);
895  }
896  else
897  return clib_error_return (0,
898  "duplicate configuration for PCI address %U",
899  format_vlib_pci_addr, &pci_addr);
900  }
901 
902  devconf->pci_addr.as_u32 = pci_addr.as_u32;
903  devconf->hqos_enabled = 0;
905 
906  if (!input)
907  return 0;
908 
911  {
912  if (unformat (input, "num-rx-queues %u", &devconf->num_rx_queues))
913  ;
914  else if (unformat (input, "num-tx-queues %u", &devconf->num_tx_queues))
915  ;
916  else if (unformat (input, "num-rx-desc %u", &devconf->num_rx_desc))
917  ;
918  else if (unformat (input, "num-tx-desc %u", &devconf->num_tx_desc))
919  ;
920  else if (unformat (input, "workers %U", unformat_bitmap_list,
921  &devconf->workers))
922  ;
923  else
924  if (unformat
925  (input, "rss %U", unformat_vlib_cli_sub_input, &sub_input))
926  {
927  error = unformat_rss_fn (&sub_input, &devconf->rss_fn);
928  if (error)
929  break;
930  }
931  else if (unformat (input, "vlan-strip-offload off"))
933  else if (unformat (input, "vlan-strip-offload on"))
935  else
936  if (unformat
937  (input, "hqos %U", unformat_vlib_cli_sub_input, &sub_input))
938  {
939  devconf->hqos_enabled = 1;
940  error = unformat_hqos (&sub_input, &devconf->hqos);
941  if (error)
942  break;
943  }
944  else if (unformat (input, "hqos"))
945  {
946  devconf->hqos_enabled = 1;
947  }
948  else
949  {
950  error = clib_error_return (0, "unknown input `%U'",
951  format_unformat_error, input);
952  break;
953  }
954  }
955 
956  if (error)
957  return error;
958 
959  if (devconf->workers && devconf->num_rx_queues == 0)
960  devconf->num_rx_queues = clib_bitmap_count_set_bits (devconf->workers);
961  else if (devconf->workers &&
962  clib_bitmap_count_set_bits (devconf->workers) !=
963  devconf->num_rx_queues)
964  error =
966  "%U: number of worker threadds must be "
967  "equal to number of rx queues", format_vlib_pci_addr,
968  &pci_addr);
969 
970  return error;
971 }
972 
973 static clib_error_t *
975 {
976  clib_error_t *error = 0;
977  dpdk_main_t *dm = &dpdk_main;
980  dpdk_device_config_t *devconf;
981  vlib_pci_addr_t pci_addr;
982  unformat_input_t sub_input;
983  u8 *s, *tmp = 0;
984  u8 *rte_cmd = 0, *ethname = 0;
985  u32 log_level;
986  int ret, i;
987  int num_whitelisted = 0;
988  u8 no_pci = 0;
989  u8 no_huge = 0;
990  u8 huge_dir = 0;
991  u8 file_prefix = 0;
992  u8 *socket_mem = 0;
993 
994  conf->device_config_index_by_pci_addr = hash_create (0, sizeof (uword));
995 
997  {
998  /* Prime the pump */
999  if (unformat (input, "no-hugetlb"))
1000  {
1001  vec_add1 (conf->eal_init_args, (u8 *) "no-huge");
1002  no_huge = 1;
1003  }
1004 
1005  else if (unformat (input, "enable-tcp-udp-checksum"))
1006  conf->enable_tcp_udp_checksum = 1;
1007 
1008  else if (unformat (input, "decimal-interface-names"))
1010 
1011  else if (unformat (input, "no-multi-seg"))
1012  conf->no_multi_seg = 1;
1013 
1014  else if (unformat (input, "dev default %U", unformat_vlib_cli_sub_input,
1015  &sub_input))
1016  {
1017  error =
1018  dpdk_device_config (conf, (vlib_pci_addr_t) (u32) ~ 1, &sub_input,
1019  1);
1020 
1021  if (error)
1022  return error;
1023  }
1024  else
1025  if (unformat
1026  (input, "dev %U %U", unformat_vlib_pci_addr, &pci_addr,
1027  unformat_vlib_cli_sub_input, &sub_input))
1028  {
1029  error = dpdk_device_config (conf, pci_addr, &sub_input, 0);
1030 
1031  if (error)
1032  return error;
1033 
1034  num_whitelisted++;
1035  }
1036  else if (unformat (input, "dev %U", unformat_vlib_pci_addr, &pci_addr))
1037  {
1038  error = dpdk_device_config (conf, pci_addr, 0, 0);
1039 
1040  if (error)
1041  return error;
1042 
1043  num_whitelisted++;
1044  }
1045  else if (unformat (input, "num-mbufs %d", &conf->num_mbufs))
1046  ;
1047  else if (unformat (input, "kni %d", &conf->num_kni))
1048  ;
1049  else if (unformat (input, "uio-driver %s", &conf->uio_driver_name))
1050  ;
1051  else if (unformat (input, "socket-mem %s", &socket_mem))
1052  ;
1053  else if (unformat (input, "no-pci"))
1054  {
1055  no_pci = 1;
1056  tmp = format (0, "--no-pci%c", 0);
1057  vec_add1 (conf->eal_init_args, tmp);
1058  }
1059  else if (unformat (input, "poll-sleep %d", &dm->poll_sleep))
1060  ;
1061 
1062 #define _(a) \
1063  else if (unformat(input, #a)) \
1064  { \
1065  tmp = format (0, "--%s%c", #a, 0); \
1066  vec_add1 (conf->eal_init_args, tmp); \
1067  }
1069 #undef _
1070 #define _(a) \
1071  else if (unformat(input, #a " %s", &s)) \
1072  { \
1073  if (!strncmp(#a, "huge-dir", 8)) \
1074  huge_dir = 1; \
1075  else if (!strncmp(#a, "file-prefix", 11)) \
1076  file_prefix = 1; \
1077  tmp = format (0, "--%s%c", #a, 0); \
1078  vec_add1 (conf->eal_init_args, tmp); \
1079  vec_add1 (s, 0); \
1080  vec_add1 (conf->eal_init_args, s); \
1081  }
1083 #undef _
1084 #define _(a,b) \
1085  else if (unformat(input, #a " %s", &s)) \
1086  { \
1087  tmp = format (0, "-%s%c", #b, 0); \
1088  vec_add1 (conf->eal_init_args, tmp); \
1089  vec_add1 (s, 0); \
1090  vec_add1 (conf->eal_init_args, s); \
1091  }
1093 #undef _
1094 #define _(a,b) \
1095  else if (unformat(input, #a " %s", &s)) \
1096  { \
1097  tmp = format (0, "-%s%c", #b, 0); \
1098  vec_add1 (conf->eal_init_args, tmp); \
1099  vec_add1 (s, 0); \
1100  vec_add1 (conf->eal_init_args, s); \
1101  conf->a##_set_manually = 1; \
1102  }
1104 #undef _
1105  else if (unformat (input, "default"))
1106  ;
1107 
1108  else if (unformat_skip_white_space (input))
1109  ;
1110  else
1111  {
1112  error = clib_error_return (0, "unknown input `%U'",
1113  format_unformat_error, input);
1114  goto done;
1115  }
1116  }
1117 
1118  if (!conf->uio_driver_name)
1119  conf->uio_driver_name = format (0, "igb_uio%c", 0);
1120 
1121  /*
1122  * Use 1G huge pages if available.
1123  */
1124  if (!no_huge && !huge_dir)
1125  {
1126  u32 x, *mem_by_socket = 0;
1127  uword c = 0;
1128  u8 use_1g = 1;
1129  u8 use_2m = 1;
1130  u8 less_than_1g = 1;
1131  int rv;
1132 
1133  umount (DEFAULT_HUGE_DIR);
1134 
1135  /* Process "socket-mem" parameter value */
1136  if (vec_len (socket_mem))
1137  {
1138  unformat_input_t in;
1139  unformat_init_vector (&in, socket_mem);
1141  {
1142  if (unformat (&in, "%u,", &x))
1143  ;
1144  else if (unformat (&in, "%u", &x))
1145  ;
1146  else if (unformat (&in, ","))
1147  x = 0;
1148  else
1149  break;
1150 
1151  vec_add1 (mem_by_socket, x);
1152 
1153  if (x > 1023)
1154  less_than_1g = 0;
1155  }
1156  /* Note: unformat_free vec_frees(in.buffer), aka socket_mem... */
1157  unformat_free (&in);
1158  socket_mem = 0;
1159  }
1160  else
1161  {
1162  /* *INDENT-OFF* */
1164  {
1165  vec_validate(mem_by_socket, c);
1166  mem_by_socket[c] = 256; /* default per-socket mem */
1167  }
1168  ));
1169  /* *INDENT-ON* */
1170  }
1171 
1172  /* check if available enough 1GB pages for each socket */
1173  /* *INDENT-OFF* */
1175  {
1176  int pages_avail, page_size, mem;
1177 
1178  vec_validate(mem_by_socket, c);
1179  mem = mem_by_socket[c];
1180 
1181  page_size = 1024;
1182  pages_avail = vlib_sysfs_get_free_hugepages(c, page_size * 1024);
1183 
1184  if (pages_avail < 0 || page_size * pages_avail < mem)
1185  use_1g = 0;
1186 
1187  page_size = 2;
1188  pages_avail = vlib_sysfs_get_free_hugepages(c, page_size * 1024);
1189 
1190  if (pages_avail < 0 || page_size * pages_avail < mem)
1191  use_2m = 0;
1192  }));
1193  /* *INDENT-ON* */
1194 
1195  if (mem_by_socket == 0)
1196  {
1197  error = clib_error_return (0, "mem_by_socket NULL");
1198  goto done;
1199  }
1200  _vec_len (mem_by_socket) = c + 1;
1201 
1202  /* regenerate socket_mem string */
1203  vec_foreach_index (x, mem_by_socket)
1204  socket_mem = format (socket_mem, "%s%u",
1205  socket_mem ? "," : "", mem_by_socket[x]);
1206  socket_mem = format (socket_mem, "%c", 0);
1207 
1208  vec_free (mem_by_socket);
1209 
1210  rv = mkdir (VPP_RUN_DIR, 0755);
1211  if (rv && errno != EEXIST)
1212  {
1213  error = clib_error_return (0, "mkdir '%s' failed errno %d",
1214  VPP_RUN_DIR, errno);
1215  goto done;
1216  }
1217 
1218  rv = mkdir (DEFAULT_HUGE_DIR, 0755);
1219  if (rv && errno != EEXIST)
1220  {
1221  error = clib_error_return (0, "mkdir '%s' failed errno %d",
1222  DEFAULT_HUGE_DIR, errno);
1223  goto done;
1224  }
1225 
1226  if (use_1g && !(less_than_1g && use_2m))
1227  {
1228  rv =
1229  mount ("none", DEFAULT_HUGE_DIR, "hugetlbfs", 0, "pagesize=1G");
1230  }
1231  else if (use_2m)
1232  {
1233  rv = mount ("none", DEFAULT_HUGE_DIR, "hugetlbfs", 0, NULL);
1234  }
1235  else
1236  {
1237  return clib_error_return (0, "not enough free huge pages");
1238  }
1239 
1240  if (rv)
1241  {
1242  error = clib_error_return (0, "mount failed %d", errno);
1243  goto done;
1244  }
1245 
1246  tmp = format (0, "--huge-dir%c", 0);
1247  vec_add1 (conf->eal_init_args, tmp);
1248  tmp = format (0, "%s%c", DEFAULT_HUGE_DIR, 0);
1249  vec_add1 (conf->eal_init_args, tmp);
1250  if (!file_prefix)
1251  {
1252  tmp = format (0, "--file-prefix%c", 0);
1253  vec_add1 (conf->eal_init_args, tmp);
1254  tmp = format (0, "vpp%c", 0);
1255  vec_add1 (conf->eal_init_args, tmp);
1256  }
1257  }
1258 
1259  vec_free (rte_cmd);
1260  vec_free (ethname);
1261 
1262  if (error)
1263  return error;
1264 
1265  /* I'll bet that -c and -n must be the first and second args... */
1266  if (!conf->coremask_set_manually)
1267  {
1269  uword *coremask = 0;
1270  int i;
1271 
1272  /* main thread core */
1273  coremask = clib_bitmap_set (coremask, tm->main_lcore, 1);
1274 
1275  for (i = 0; i < vec_len (tm->registrations); i++)
1276  {
1277  tr = tm->registrations[i];
1278  coremask = clib_bitmap_or (coremask, tr->coremask);
1279  }
1280 
1281  vec_insert (conf->eal_init_args, 2, 1);
1282  conf->eal_init_args[1] = (u8 *) "-c";
1283  tmp = format (0, "%U%c", format_bitmap_hex, coremask, 0);
1284  conf->eal_init_args[2] = tmp;
1285  clib_bitmap_free (coremask);
1286  }
1287 
1288  if (!conf->nchannels_set_manually)
1289  {
1290  vec_insert (conf->eal_init_args, 2, 3);
1291  conf->eal_init_args[3] = (u8 *) "-n";
1292  tmp = format (0, "%d", conf->nchannels);
1293  conf->eal_init_args[4] = tmp;
1294  }
1295 
1296  if (no_pci == 0 && geteuid () == 0)
1297  dpdk_bind_devices_to_uio (conf);
1298 
1299 #define _(x) \
1300  if (devconf->x == 0 && conf->default_devconf.x > 0) \
1301  devconf->x = conf->default_devconf.x ;
1302 
1303  /* *INDENT-OFF* */
1304  pool_foreach (devconf, conf->dev_confs, ({
1305 
1306  /* default per-device config items */
1307  foreach_dpdk_device_config_item
1308 
1309  /* add DPDK EAL whitelist/blacklist entry */
1310  if (num_whitelisted > 0 && devconf->is_blacklisted == 0)
1311  {
1312  tmp = format (0, "-w%c", 0);
1313  vec_add1 (conf->eal_init_args, tmp);
1314  tmp = format (0, "%U%c", format_vlib_pci_addr, &devconf->pci_addr, 0);
1315  vec_add1 (conf->eal_init_args, tmp);
1316  }
1317  else if (num_whitelisted == 0 && devconf->is_blacklisted != 0)
1318  {
1319  tmp = format (0, "-b%c", 0);
1320  vec_add1 (conf->eal_init_args, tmp);
1321  tmp = format (0, "%U%c", format_vlib_pci_addr, &devconf->pci_addr, 0);
1322  vec_add1 (conf->eal_init_args, tmp);
1323  }
1324  }));
1325  /* *INDENT-ON* */
1326 
1327 #undef _
1328 
1329  /* set master-lcore */
1330  tmp = format (0, "--master-lcore%c", 0);
1331  vec_add1 (conf->eal_init_args, tmp);
1332  tmp = format (0, "%u%c", tm->main_lcore, 0);
1333  vec_add1 (conf->eal_init_args, tmp);
1334 
1335  /* set socket-mem */
1336  tmp = format (0, "--socket-mem%c", 0);
1337  vec_add1 (conf->eal_init_args, tmp);
1338  tmp = format (0, "%s%c", socket_mem, 0);
1339  vec_add1 (conf->eal_init_args, tmp);
1340 
1341  /* NULL terminate the "argv" vector, in case of stupidity */
1342  vec_add1 (conf->eal_init_args, 0);
1343  _vec_len (conf->eal_init_args) -= 1;
1344 
1345  /* Set up DPDK eal and packet mbuf pool early. */
1346 
1347  log_level = (CLIB_DEBUG > 0) ? RTE_LOG_DEBUG : RTE_LOG_NOTICE;
1348 
1349  rte_set_log_level (log_level);
1350 
1351  vm = vlib_get_main ();
1352 
1353  /* make copy of args as rte_eal_init tends to mess up with arg array */
1354  for (i = 1; i < vec_len (conf->eal_init_args); i++)
1355  conf->eal_init_args_str = format (conf->eal_init_args_str, "%s ",
1356  conf->eal_init_args[i]);
1357 
1358  ret =
1359  rte_eal_init (vec_len (conf->eal_init_args),
1360  (char **) conf->eal_init_args);
1361 
1362  /* lazy umount hugepages */
1363  umount2 (DEFAULT_HUGE_DIR, MNT_DETACH);
1364 
1365  if (ret < 0)
1366  return clib_error_return (0, "rte_eal_init returned %d", ret);
1367 
1368  /* Dump the physical memory layout prior to creating the mbuf_pool */
1369  fprintf (stdout, "DPDK physical memory layout:\n");
1370  rte_dump_physmem_layout (stdout);
1371 
1372  /* main thread 1st */
1373  error = vlib_buffer_pool_create (vm, conf->num_mbufs, rte_socket_id ());
1374  if (error)
1375  return error;
1376 
1377  for (i = 0; i < RTE_MAX_LCORE; i++)
1378  {
1379  error = vlib_buffer_pool_create (vm, conf->num_mbufs,
1380  rte_lcore_to_socket_id (i));
1381  if (error)
1382  return error;
1383  }
1384 
1385 done:
1386  return error;
1387 }
1388 
1390 
1391 void
1393 {
1394  vnet_main_t *vnm = vnet_get_main ();
1395  struct rte_eth_link prev_link = xd->link;
1396  u32 hw_flags = 0;
1397  u8 hw_flags_chg = 0;
1398 
1399  /* only update link state for PMD interfaces */
1400  if ((xd->flags & DPDK_DEVICE_FLAG_PMD) == 0)
1401  return;
1402 
1403  xd->time_last_link_update = now ? now : xd->time_last_link_update;
1404  memset (&xd->link, 0, sizeof (xd->link));
1405  rte_eth_link_get_nowait (xd->device_index, &xd->link);
1406 
1407  if (LINK_STATE_ELOGS)
1408  {
1409  vlib_main_t *vm = vlib_get_main ();
1410  ELOG_TYPE_DECLARE (e) =
1411  {
1412  .format =
1413  "update-link-state: sw_if_index %d, admin_up %d,"
1414  "old link_state %d new link_state %d",.format_args = "i4i1i1i1",};
1415 
1416  struct
1417  {
1418  u32 sw_if_index;
1419  u8 admin_up;
1420  u8 old_link_state;
1421  u8 new_link_state;
1422  } *ed;
1423  ed = ELOG_DATA (&vm->elog_main, e);
1424  ed->sw_if_index = xd->vlib_sw_if_index;
1425  ed->admin_up = (xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP) != 0;
1426  ed->old_link_state = (u8)
1428  ed->new_link_state = (u8) xd->link.link_status;
1429  }
1430 
1431  if ((xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP) &&
1432  ((xd->link.link_status != 0) ^
1434  {
1435  hw_flags_chg = 1;
1436  hw_flags |= (xd->link.link_status ? VNET_HW_INTERFACE_FLAG_LINK_UP : 0);
1437  }
1438 
1439  if (hw_flags_chg || (xd->link.link_duplex != prev_link.link_duplex))
1440  {
1441  hw_flags_chg = 1;
1442  switch (xd->link.link_duplex)
1443  {
1444  case ETH_LINK_HALF_DUPLEX:
1446  break;
1447  case ETH_LINK_FULL_DUPLEX:
1449  break;
1450  default:
1451  break;
1452  }
1453  }
1454  if (hw_flags_chg || (xd->link.link_speed != prev_link.link_speed))
1455  {
1456  hw_flags_chg = 1;
1457  switch (xd->link.link_speed)
1458  {
1459  case ETH_SPEED_NUM_10M:
1461  break;
1462  case ETH_SPEED_NUM_100M:
1464  break;
1465  case ETH_SPEED_NUM_1G:
1466  hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_1G;
1467  break;
1468  case ETH_SPEED_NUM_10G:
1470  break;
1471  case ETH_SPEED_NUM_40G:
1473  break;
1474  case 0:
1475  break;
1476  default:
1477  clib_warning ("unknown link speed %d", xd->link.link_speed);
1478  break;
1479  }
1480  }
1481  if (hw_flags_chg)
1482  {
1483  if (LINK_STATE_ELOGS)
1484  {
1485  vlib_main_t *vm = vlib_get_main ();
1486 
1487  ELOG_TYPE_DECLARE (e) =
1488  {
1489  .format =
1490  "update-link-state: sw_if_index %d, new flags %d",.format_args
1491  = "i4i4",};
1492 
1493  struct
1494  {
1495  u32 sw_if_index;
1496  u32 flags;
1497  } *ed;
1498  ed = ELOG_DATA (&vm->elog_main, e);
1499  ed->sw_if_index = xd->vlib_sw_if_index;
1500  ed->flags = hw_flags;
1501  }
1502  vnet_hw_interface_set_flags (vnm, xd->vlib_hw_if_index, hw_flags);
1503  }
1504 }
1505 
1506 static uword
1508 {
1509  clib_error_t *error;
1510  vnet_main_t *vnm = vnet_get_main ();
1511  dpdk_main_t *dm = &dpdk_main;
1513  dpdk_device_t *xd;
1515  int i;
1516 
1517  error = dpdk_lib_init (dm);
1518 
1519  /*
1520  * Turn on the input node if we found some devices to drive
1521  * and we're not running worker threads or i/o threads
1522  */
1523 
1524  if (error == 0 && vec_len (dm->devices) > 0)
1525  {
1526  if (tm->n_vlib_mains == 1)
1528  VLIB_NODE_STATE_POLLING);
1529  else
1530  for (i = 0; i < tm->n_vlib_mains; i++)
1531  if (vec_len (dm->devices_by_cpu[i]) > 0)
1533  VLIB_NODE_STATE_POLLING);
1534  }
1535 
1536  if (error)
1537  clib_error_report (error);
1538 
1539  tm->worker_thread_release = 1;
1540 
1541  f64 now = vlib_time_now (vm);
1542  vec_foreach (xd, dm->devices)
1543  {
1544  dpdk_update_link_state (xd, now);
1545  }
1546 
1547  {
1548  /*
1549  * Extra set up for bond interfaces:
1550  * 1. Setup MACs for bond interfaces and their slave links which was set
1551  * in dpdk_port_setup() but needs to be done again here to take effect.
1552  * 2. Set up info for bond interface related CLI support.
1553  */
1554  int nports = rte_eth_dev_count ();
1555  if (nports > 0)
1556  {
1557  for (i = 0; i < nports; i++)
1558  {
1559  struct rte_eth_dev_info dev_info;
1560  rte_eth_dev_info_get (i, &dev_info);
1561  if (!dev_info.driver_name)
1562 #if RTE_VERSION < RTE_VERSION_NUM(16, 11, 0, 0)
1563  dev_info.driver_name = dev_info.pci_dev->driver->name;
1564 #else
1565  dev_info.driver_name = dev_info.pci_dev->driver->driver.name;
1566 #endif
1567  ASSERT (dev_info.driver_name);
1568  if (strncmp (dev_info.driver_name, "rte_bond_pmd", 12) == 0)
1569  {
1570  u8 addr[6];
1571  u8 slink[16];
1572  int nlink = rte_eth_bond_slaves_get (i, slink, 16);
1573  if (nlink > 0)
1574  {
1575  vnet_hw_interface_t *bhi;
1576  ethernet_interface_t *bei;
1577  int rv;
1578 
1579  /* Get MAC of 1st slave link */
1580  rte_eth_macaddr_get (slink[0],
1581  (struct ether_addr *) addr);
1582  /* Set MAC of bounded interface to that of 1st slave link */
1583  rv =
1584  rte_eth_bond_mac_address_set (i,
1585  (struct ether_addr *)
1586  addr);
1587  if (rv < 0)
1588  clib_warning ("Failed to set MAC address");
1589 
1590  /* Populate MAC of bonded interface in VPP hw tables */
1591  bhi =
1592  vnet_get_hw_interface (vnm,
1593  dm->devices[i].vlib_hw_if_index);
1594  bei =
1596  clib_memcpy (bhi->hw_address, addr, 6);
1597  clib_memcpy (bei->address, addr, 6);
1598  /* Init l3 packet size allowed on bonded interface */
1603  while (nlink >= 1)
1604  { /* for all slave links */
1605  int slave = slink[--nlink];
1606  dpdk_device_t *sdev = &dm->devices[slave];
1607  vnet_hw_interface_t *shi;
1608  vnet_sw_interface_t *ssi;
1609  /* Add MAC to all slave links except the first one */
1610  if (nlink)
1611  rte_eth_dev_mac_addr_add (slave,
1612  (struct ether_addr *)
1613  addr, 0);
1614  /* Set slaves bitmap for bonded interface */
1615  bhi->bond_info =
1616  clib_bitmap_set (bhi->bond_info,
1617  sdev->vlib_hw_if_index, 1);
1618  /* Set slave link flags on slave interface */
1619  shi =
1621  ssi =
1625 
1626  /* Set l3 packet size allowed as the lowest of slave */
1627  if (bhi->max_l3_packet_bytes[VLIB_RX] >
1632 
1633  /* Set max packet size allowed as the lowest of slave */
1634  if (bhi->max_packet_bytes > shi->max_packet_bytes)
1635  bhi->max_packet_bytes = shi->max_packet_bytes;
1636  }
1637  }
1638  }
1639  }
1640  }
1641  }
1642 
1643  while (1)
1644  {
1645  /*
1646  * check each time through the loop in case intervals are changed
1647  */
1648  f64 min_wait = dm->link_state_poll_interval < dm->stat_poll_interval ?
1650 
1651  vlib_process_wait_for_event_or_clock (vm, min_wait);
1652 
1654  /* skip the poll if an admin up down is in progress (on any interface) */
1655  continue;
1656 
1657  vec_foreach (xd, dm->devices)
1658  {
1659  f64 now = vlib_time_now (vm);
1660  if ((now - xd->time_last_stats_update) >= dm->stat_poll_interval)
1661  dpdk_update_counters (xd, now);
1662  if ((now - xd->time_last_link_update) >= dm->link_state_poll_interval)
1663  dpdk_update_link_state (xd, now);
1664 
1665  }
1666  }
1667 
1668  return 0;
1669 }
1670 
1671 /* *INDENT-OFF* */
1673  .function = dpdk_process,
1674  .type = VLIB_NODE_TYPE_PROCESS,
1675  .name = "dpdk-process",
1676  .process_log2_n_stack_bytes = 17,
1677 };
1678 /* *INDENT-ON* */
1679 
1680 int
1682 {
1683  if (interval < DPDK_MIN_STATS_POLL_INTERVAL)
1684  return (VNET_API_ERROR_INVALID_VALUE);
1685 
1686  dpdk_main.stat_poll_interval = interval;
1687 
1688  return 0;
1689 }
1690 
1691 int
1693 {
1694  if (interval < DPDK_MIN_LINK_POLL_INTERVAL)
1695  return (VNET_API_ERROR_INVALID_VALUE);
1696 
1697  dpdk_main.link_state_poll_interval = interval;
1698 
1699  return 0;
1700 }
1701 
1702 clib_error_t *
1704 {
1705  dpdk_main_t *dm = &dpdk_main;
1706  vlib_node_t *ei;
1707  clib_error_t *error = 0;
1709 
1710  /* verify that structs are cacheline aligned */
1711  STATIC_ASSERT (offsetof (dpdk_device_t, cacheline0) == 0,
1712  "Cache line marker must be 1st element in dpdk_device_t");
1713  STATIC_ASSERT (offsetof (dpdk_device_t, cacheline1) ==
1715  "Data in cache line 0 is bigger than cache line size");
1716  STATIC_ASSERT (offsetof (dpdk_worker_t, cacheline0) == 0,
1717  "Cache line marker must be 1st element in dpdk_worker_t");
1718  STATIC_ASSERT (offsetof (frame_queue_trace_t, cacheline0) == 0,
1719  "Cache line marker must be 1st element in frame_queue_trace_t");
1720 
1721  dm->vlib_main = vm;
1722  dm->vnet_main = vnet_get_main ();
1723  dm->conf = &dpdk_config_main;
1724 
1725  ei = vlib_get_node_by_name (vm, (u8 *) "ethernet-input");
1726  if (ei == 0)
1727  return clib_error_return (0, "ethernet-input node AWOL");
1728 
1729  dm->ethernet_input_node_index = ei->index;
1730 
1731  dm->conf->nchannels = 4;
1732  dm->conf->num_mbufs = dm->conf->num_mbufs ? dm->conf->num_mbufs : NB_MBUF;
1733  vec_add1 (dm->conf->eal_init_args, (u8 *) "vnet");
1734 
1735  dm->dpdk_device_by_kni_port_id = hash_create (0, sizeof (uword));
1736  dm->vu_sw_if_index_by_listener_fd = hash_create (0, sizeof (uword));
1737  dm->vu_sw_if_index_by_sock_fd = hash_create (0, sizeof (uword));
1738 
1739  /* $$$ use n_thread_stacks since it's known-good at this point */
1740  vec_validate (dm->recycle, tm->n_thread_stacks - 1);
1741 
1742  /* initialize EFD (early fast discard) default settings */
1745  DPDK_NB_RX_DESC_10GE) / 100);
1748 
1749  /* Default vlib_buffer_t flags, DISABLES tcp/udp checksumming... */
1750  dm->buffer_flags_template =
1753 
1756 
1757  /* init CLI */
1758  if ((error = vlib_call_init_function (vm, dpdk_cli_init)))
1759  return error;
1760 
1761  return error;
1762 }
1763 
1765 
1766 
1767 /*
1768  * fd.io coding-style-patch-verification: ON
1769  *
1770  * Local Variables:
1771  * eval: (c-set-style "gnu")
1772  * End:
1773  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:396
#define DPDK_DEVICE_FLAG_PROMISC
Definition: dpdk.h:217
#define DPDK_NB_TX_DESC_10GE
Definition: dpdk_priv.h:21
f64 time_last_link_update
Definition: dpdk.h:247
vmrglw vmrglh hi
void unformat_init_vector(unformat_input_t *input, u8 *vector_string)
Definition: unformat.c:1025
static u8 * format_bitmap_hex(u8 *s, va_list *args)
Format a bitmap as a string of hex bytes.
Definition: bitmap.h:744
format_function_t format_vlib_pci_addr
Definition: pci.h:237
#define vec_foreach_index(var, v)
Iterate over vector indices.
u16 enabled
Definition: dpdk.h:299
#define hash_set(h, key, value)
Definition: hash.h:254
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
#define clib_min(x, y)
Definition: clib.h:326
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:966
u32 vlib_buffer_get_or_create_free_list(vlib_main_t *vm, u32 n_data_bytes, char *fmt,...)
Definition: dpdk_buffer.c:383
#define VNET_HW_INTERFACE_FLAG_SPEED_1G
Definition: interface.h:361
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Definition: interface.c:522
static f64 vlib_process_wait_for_event_or_clock(vlib_main_t *vm, f64 dt)
Suspend a cooperative multi-tasking thread Waits for an event, or for the indicated number of seconds...
Definition: node_funcs.h:684
u8 interface_name_format_decimal
Definition: dpdk.h:391
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
#define NB_MBUF
Definition: dpdk.h:63
static clib_error_t * dpdk_lib_init(dpdk_main_t *dm)
Definition: init.c:238
u8 use_rss
Definition: dpdk.h:453
vnet_device_class_t dpdk_device_class
static u32 dpdk_flag_change(vnet_main_t *vnm, vnet_hw_interface_t *hi, u32 flags)
Definition: init.c:138
#define DPDK_DEVICE_VLAN_STRIP_OFF
Definition: dpdk.h:358
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
#define I40E_DEV_ID_QSFP_B
Definition: dpdk_priv.h:28
#define NULL
Definition: clib.h:55
u32 index
Definition: node.h:237
clib_error_t * vlib_pci_bind_to_uio(vlib_pci_device_t *d, char *uio_driver_name)
Definition: linux_pci.c:95
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:182
#define vec_add2_aligned(V, P, N, A)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:533
static uword * clib_bitmap_or(uword *ai, uword *bi)
Logical operator across two bitmaps.
uword unformat_vlib_cli_sub_input(unformat_input_t *i, va_list *args)
Definition: cli.c:149
u16 flags
Definition: dpdk.h:215
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
unsigned rte_socket_id()
#define DPDK_EFD_DISABLED
Definition: dpdk.h:289
dpdk_device_and_queue_t ** devices_by_hqos_cpu
Definition: dpdk.h:408
#define DPDK_NB_RX_DESC_VIRTIO
Definition: dpdk_priv.h:18
#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
#define DPDK_DEVICE_FLAG_HQOS
Definition: dpdk.h:221
vlib_buffer_main_t * buffer_main
Definition: main.h:104
u32 per_interface_next_index
Definition: dpdk.h:203
u8 enable_tcp_udp_checksum
Definition: dpdk.h:377
vlib_worker_thread_t * vlib_worker_threads
Definition: threads.h:112
static uword * clib_bitmap_set(uword *ai, uword i, uword value)
Sets the ith bit of a bitmap to new_value Removes trailing zeros from the bitmap. ...
Definition: bitmap.h:167
#define DPDK_DEVICE_VLAN_STRIP_ON
Definition: dpdk.h:359
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
static clib_error_t * dpdk_config(vlib_main_t *vm, unformat_input_t *input)
Definition: init.c:974
#define DPDK_NB_TX_DESC_DEFAULT
Definition: dpdk_priv.h:17
#define clib_error_report(e)
Definition: error.h:125
#define foreach_eal_double_hyphen_predicate_arg
Definition: dpdk_priv.h:34
unformat_function_t unformat_vlib_pci_addr
Definition: pci.h:236
#define VNET_HW_INTERFACE_FLAG_LINK_UP
Definition: interface.h:348
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:407
u16 device_id
Definition: pci.h:80
dpdk_device_config_hqos_t hqos
Definition: dpdk.h:366
dpdk_main_t dpdk_main
Definition: init.c:36
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:200
vlib_pci_addr_t bus_address
Definition: pci.h:58
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
#define DPDK_DEVICE_FLAG_PMD
Definition: dpdk.h:218
clib_error_t * vlib_buffer_pool_create(vlib_main_t *vm, unsigned num_mbufs, unsigned socket_id)
Definition: dpdk_buffer.c:968
#define I40E_DEV_ID_QSFP_A
Definition: dpdk_priv.h:27
static vnet_sw_interface_t * vnet_get_hw_sw_interface(vnet_main_t *vnm, u32 hw_if_index)
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
#define I40E_DEV_ID_SFP_XL710
Definition: dpdk_priv.h:26
#define LINK_STATE_ELOGS
Definition: init.c:44
struct rte_mbuf *** tx_vectors
Definition: dpdk.h:206
foreach_dpdk_device_config_item clib_bitmap_t * workers
Definition: dpdk.h:364
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:348
vlib_node_function_t * function
Definition: node.h:416
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
dpdk_config_main_t dpdk_config_main
Definition: dpdk.h:400
#define I40E_DEV_ID_QSFP_C
Definition: dpdk_priv.h:29
#define VPP_RUN_DIR
Definition: init.c:47
vlib_node_registration_t dpdk_input_node
(constructor) VLIB_REGISTER_NODE (dpdk_input_node)
Definition: node.c:707
dpdk_device_config_t default_devconf
Definition: dpdk.h:394
f64 stat_poll_interval
Definition: dpdk.h:465
#define IP_BUFFER_L4_CHECKSUM_CORRECT
Definition: buffer.h:50
int input_cpu_first_index
Definition: dpdk.h:456
char i8
Definition: types.h:45
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
u16 rx_q_used
Definition: dpdk.h:233
static void unformat_free(unformat_input_t *i)
Definition: format.h:161
#define clib_warning(format, args...)
Definition: error.h:59
u16 vendor_id
Definition: pci.h:79
#define vlib_call_init_function(vm, x)
Definition: init.h:161
clib_error_t * unformat_rss_fn(unformat_input_t *input, uword *rss_fn)
Definition: format.c:765
#define DPDK_NB_TX_DESC_VIRTIO
Definition: dpdk_priv.h:19
u32 device_index
Definition: dpdk.h:197
struct rte_eth_conf port_conf
Definition: dpdk.h:236
dpdk_worker_t * workers
Definition: dpdk.h:423
void * dpdk_input_multiarch_select()
#define DPDK_NB_TX_DESC_40GE
Definition: dpdk_priv.h:23
#define I40E_DEV_ID_10G_BASE_T
Definition: dpdk_priv.h:30
f64 time_last_stats_update
Definition: dpdk.h:254
u16 consec_full_frames_hi_thresh
Definition: dpdk.h:301
vlib_main_t ** vlib_mains
Definition: dpdk_buffer.c:157
ethernet_main_t ethernet_main
Definition: init.c:45
dpdk_hqos_thread_t * hqos_threads
Definition: dpdk.h:426
static struct rte_eth_conf port_conf_template
Definition: init.c:51
clib_error_t * dpdk_init(vlib_main_t *vm)
Definition: init.c:1703
u32 vlib_sw_if_index
Definition: dpdk.h:200
struct rte_eth_txconf tx_conf
Definition: dpdk.h:237
#define hash_get(h, key)
Definition: hash.h:248
#define clib_bitmap_foreach(i, ai, body)
Macro to iterate across set bits in a bitmap.
Definition: bitmap.h:361
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:369
#define vec_insert(V, N, M)
Insert N vector elements starting at element M, initialize new elements to zero (no header...
Definition: vec.h:646
vlib_pci_addr_t pci_addr
Definition: dpdk.h:354
#define foreach_eal_double_hyphen_arg
Definition: dpdk_priv.h:50
#define VLIB_BUFFER_DEFAULT_FREE_LIST_BYTES
Definition: buffer.h:307
dpdk_device_and_queue_t ** devices_by_cpu
Definition: dpdk.h:407
#define ETHERNET_INTERFACE_FLAG_CONFIG_MTU(flags)
Definition: ethernet.h:119
u8 ** eal_init_args
Definition: dpdk.h:373
#define VNET_HW_INTERFACE_FLAG_SPEED_10M
Definition: interface.h:359
u32 vlib_hw_if_index
Definition: dpdk.h:199
uword unformat_skip_white_space(unformat_input_t *input)
Definition: unformat.c:809
#define VNET_SW_INTERFACE_FLAG_BOND_SLAVE
Definition: interface.h:499
#define foreach_eal_single_hyphen_mandatory_arg
Definition: dpdk_priv.h:40
vlib_pci_device_t * pci_devs
Definition: pci.h:116
int dpdk_set_link_state_poll_interval(f64 interval)
Definition: init.c:1692
#define VNET_HW_INTERFACE_FLAG_HALF_DUPLEX
Definition: interface.h:351
uword os_get_cpu_number(void)
Definition: unix-misc.c:224
static vlib_node_registration_t dpdk_process_node
(constructor) VLIB_REGISTER_NODE (dpdk_process_node)
Definition: init.c:1672
#define foreach_dpdk_pmd
Definition: dpdk.h:70
#define ELOG_DATA(em, f)
Definition: elog.h:392
dpdk_port_type_t port_type
Definition: dpdk.h:255
static uword dpdk_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: init.c:1507
#define VLIB_CONFIG_FUNCTION(x, n,...)
Definition: init.h:118
#define DPDK_MIN_STATS_POLL_INTERVAL
Definition: dpdk.h:261
int input_cpu_count
Definition: dpdk.h:457
#define VLIB_FRAME_SIZE
Definition: node.h:328
void * vlib_weakly_linked_functions[]
Definition: init.c:39
u16 tx_q_used
Definition: dpdk.h:232
u16 nb_rx_desc
Definition: dpdk.h:234
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:575
static clib_error_t * dpdk_device_config(dpdk_config_main_t *conf, vlib_pci_addr_t pci_addr, unformat_input_t *input, u8 is_default)
Definition: init.c:874
#define DPDK_DEVICE_FLAG_ADMIN_UP
Definition: dpdk.h:216
u32 ** recycle
Definition: dpdk.h:411
#define VNET_HW_INTERFACE_BOND_INFO_SLAVE
Definition: interface.h:434
#define foreach_eal_single_hyphen_arg
Definition: dpdk_priv.h:44
int dpdk_set_stat_poll_interval(f64 interval)
Definition: init.c:1681
#define DPDK_NB_RX_DESC_DEFAULT
Definition: dpdk_priv.h:16
svmdb_client_t * c
dpdk_device_t * devices
Definition: dpdk.h:406
static void dpdk_update_counters(dpdk_device_t *xd, f64 now)
Definition: dpdk_priv.h:80
u8 nchannels_set_manually
Definition: dpdk.h:381
u16 * cpu_socket_id_by_queue
Definition: dpdk.h:235
#define DPDK_EFD_DEFAULT_DEVICE_QUEUE_HI_THRESH_PCT
Definition: dpdk.h:294
vlib_pci_main_t pci_main
Definition: pci.c:53
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:300
volatile u32 ** lockp
Definition: dpdk.h:194
dpdk_device_config_t * dev_confs
Definition: dpdk.h:395
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
struct rte_mbuf *** rx_vectors
Definition: dpdk.h:207
void dpdk_device_lock_free(dpdk_device_t *xd)
Definition: init.c:227
u16 queue_hi_thresh
Definition: dpdk.h:300
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
#define clib_memcpy(a, b, c)
Definition: string.h:64
#define DPDK_NB_RX_DESC_ENIC
Definition: dpdk_priv.h:24
dpdk_pmd_t pmd
Definition: dpdk.h:212
#define VLIB_BUFFER_TOTAL_LENGTH_VALID
Definition: buffer.h:99
elog_main_t elog_main
Definition: main.h:141
static void dpdk_bind_devices_to_uio(dpdk_config_main_t *conf)
Definition: init.c:804
#define ETHERNET_INTERFACE_FLAG_ACCEPT_ALL
Definition: ethernet.h:113
u8 coremask_set_manually
Definition: dpdk.h:380
#define ELOG_TYPE_DECLARE(f)
Definition: elog.h:350
#define DEFAULT_HUGE_DIR
Definition: init.c:46
clib_error_t * dpdk_port_setup(dpdk_main_t *dm, dpdk_device_t *xd)
Definition: init.c:65
#define VNET_HW_INTERFACE_FLAG_SPEED_10G
Definition: interface.h:362
#define vec_validate_ha(V, I, H, A)
Make sure vector is long enough for given index (general version).
Definition: vec.h:376
u8 * interface_name_suffix
Definition: dpdk.h:226
void dpdk_update_link_state(dpdk_device_t *xd, f64 now)
Definition: init.c:1392
#define hash_create(elts, value_bytes)
Definition: hash.h:658
#define VNET_HW_INTERFACE_FLAG_FULL_DUPLEX
Definition: interface.h:352
u32 max_l3_packet_bytes[VLIB_N_RX_TX]
Definition: interface.h:420
#define ASSERT(truth)
void dpdk_device_config_hqos_default(dpdk_device_config_hqos_t *hqos)
Definition: hqos.c:208
unsigned int u32
Definition: types.h:88
int hqos_cpu_count
Definition: dpdk.h:461
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
u32 poll_sleep
Definition: dpdk.h:468
void * dpdk_input_rss_multiarch_select()
dpdk_efd_t efd
Definition: dpdk.h:445
#define DPDK_EFD_DEFAULT_CONSEC_FULL_FRAMES_HI_THRESH
Definition: dpdk.h:295
u8 af_packet_port_id
Definition: dpdk.h:244
#define I40E_DEV_ID_VF
Definition: dpdk_priv.h:31
static void clib_mem_free(void *p)
Definition: mem.h:176
Bitmaps built as vectors of machine words.
clib_error_t * ethernet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, u8 *address, u32 *hw_if_index_return, ethernet_flag_change_function_t flag_change)
Definition: interface.c:205
#define clib_bitmap_free(v)
Free a bitmap.
Definition: bitmap.h:92
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
#define DPDK_LINK_POLL_INTERVAL
Definition: dpdk.h:263
uword * thread_registrations_by_name
Definition: threads.h:285
struct rte_eth_link link
Definition: dpdk.h:246
#define DPDK_NB_RX_DESC_10GE
Definition: dpdk_priv.h:20
clib_error_t * dpdk_port_setup_hqos(dpdk_device_t *xd, dpdk_device_config_hqos_t *hqos)
Definition: hqos.c:250
u64 uword
Definition: types.h:112
static uword clib_bitmap_count_set_bits(uword *ai)
Return the number of set bits in a bitmap.
Definition: bitmap.h:441
#define IP_BUFFER_L4_CHECKSUM_COMPUTED
Definition: buffer.h:49
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
Definition: defs.h:47
#define DPDK_STATS_POLL_INTERVAL
Definition: dpdk.h:260
#define VNET_HW_INTERFACE_FLAG_SPEED_100M
Definition: interface.h:360
u32 ethernet_input_node_index
Definition: dpdk.h:429
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
double f64
Definition: types.h:142
unsigned char u8
Definition: types.h:56
#define STATIC_ASSERT(truth,...)
static uword unformat_bitmap_list(unformat_input_t *input, va_list *va)
unformat a list of bit ranges into a bitmap (eg "0-3,5-7,11" )
Definition: bitmap.h:693
void dpdk_device_lock_init(dpdk_device_t *xd)
Definition: init.c:214
#define DPDK_MIN_LINK_POLL_INTERVAL
Definition: dpdk.h:264
#define hash_get_mem(h, key)
Definition: hash.h:268
u32 buffer_flags_template
Definition: dpdk.h:414
static void * clib_mem_alloc_aligned(uword size, uword align)
Definition: mem.h:117
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
static u32 random_u32(u32 *seed)
32-bit random number generator
Definition: random.h:69
#define VNET_HW_INTERFACE_FLAG_SPEED_40G
Definition: interface.h:363
u32 vlib_buffer_free_list_index
Definition: dpdk.h:420
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:143
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
u32 dpdk_get_admin_up_down_in_progress(void)
Definition: device.c:995
int hqos_cpu_first_index
Definition: dpdk.h:460
#define ETHERNET_MAX_PACKET_BYTES
Definition: ethernet.h:106
#define vec_foreach(var, vec)
Vector iterator.
i8 cpu_socket
Definition: dpdk.h:213
#define ETHERNET_INTERFACE_FLAG_CONFIG_PROMISC(flags)
Definition: ethernet.h:114
uword * cpu_socket_bitmap
Definition: threads.h:320
vhost_vring_addr_t addr
Definition: vhost-user.h:81
#define clib_error_return(e, args...)
Definition: error.h:111
struct _unformat_input_t unformat_input_t
u8 * uio_driver_name
Definition: dpdk.h:375
vlib_thread_registration_t ** registrations
Definition: threads.h:283
u32 flags
Definition: vhost-user.h:75
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
ethernet_interface_t * interfaces
Definition: ethernet.h:243
vnet_main_t * vnet_main
Definition: dpdk.h:472
u16 nb_tx_desc
Definition: dpdk.h:223
clib_error_t * unformat_hqos(unformat_input_t *input, dpdk_device_config_hqos_t *hqos)
Definition: format.c:788
uword * device_config_index_by_pci_addr
Definition: dpdk.h:396
static uword vnet_hw_interface_is_link_up(vnet_main_t *vnm, u32 hw_if_index)
volatile u32 worker_thread_release
Definition: threads.h:332
#define DPDK_NB_RX_DESC_40GE
Definition: dpdk_priv.h:22
uword * dpdk_device_by_kni_port_id
Definition: dpdk.h:439
Definition: defs.h:46
uword * vu_sw_if_index_by_listener_fd
Definition: dpdk.h:440
f64 link_state_poll_interval
Definition: dpdk.h:464
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:1564
dpdk_config_main_t * conf
Definition: dpdk.h:473
uword * vu_sw_if_index_by_sock_fd
Definition: dpdk.h:441
vlib_main_t * vlib_main
Definition: dpdk.h:471