FD.io VPP  v18.04-17-g3a0d853
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 #include <vppinfra/linux/sysfs.h>
21 #include <vlib/unix/unix.h>
22 
23 #include <vnet/ethernet/ethernet.h>
24 #include <dpdk/device/dpdk.h>
25 #include <vlib/pci/pci.h>
26 
27 #include <rte_ring.h>
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <sys/stat.h>
33 #include <sys/mount.h>
34 #include <string.h>
35 #include <fcntl.h>
36 
37 #include <dpdk/device/dpdk_priv.h>
38 
41 
42 #define LINK_STATE_ELOGS 0
43 
44 /* Port configuration, mildly modified Intel app values */
45 
46 static struct rte_eth_conf port_conf_template = {
47  .rxmode = {
48  .split_hdr_size = 0,
49  .header_split = 0, /**< Header Split disabled */
50  .hw_ip_checksum = 0, /**< IP checksum offload disabled */
51  .hw_vlan_filter = 0, /**< VLAN filtering disabled */
52  .hw_strip_crc = 0, /**< CRC stripped by hardware */
53  },
54  .txmode = {
55  .mq_mode = ETH_MQ_TX_NONE,
56  },
57 };
58 
59 static dpdk_port_type_t
60 port_type_from_speed_capa (struct rte_eth_dev_info *dev_info)
61 {
62 
63  if (dev_info->speed_capa & ETH_LINK_SPEED_100G)
65  else if (dev_info->speed_capa & ETH_LINK_SPEED_56G)
67  else if (dev_info->speed_capa & ETH_LINK_SPEED_50G)
69  else if (dev_info->speed_capa & ETH_LINK_SPEED_40G)
71  else if (dev_info->speed_capa & ETH_LINK_SPEED_25G)
73  else if (dev_info->speed_capa & ETH_LINK_SPEED_20G)
75  else if (dev_info->speed_capa & ETH_LINK_SPEED_10G)
77  else if (dev_info->speed_capa & ETH_LINK_SPEED_5G)
79  else if (dev_info->speed_capa & ETH_LINK_SPEED_2_5G)
81  else if (dev_info->speed_capa & ETH_LINK_SPEED_1G)
83 
85 }
86 
87 
88 static u32
90 {
91  dpdk_main_t *dm = &dpdk_main;
93  u32 old = 0;
94 
96  {
97  old = (xd->flags & DPDK_DEVICE_FLAG_PROMISC) != 0;
98 
101  else
103 
105  {
107  rte_eth_promiscuous_enable (xd->device_index);
108  else
109  rte_eth_promiscuous_disable (xd->device_index);
110  }
111  }
112  else if (ETHERNET_INTERFACE_FLAG_CONFIG_MTU (flags))
113  {
114  xd->port_conf.rxmode.max_rx_pkt_len = hi->max_packet_bytes;
115  dpdk_device_setup (xd);
116  }
117  return old;
118 }
119 
120 static void
122 {
123  int q;
124  vec_validate (xd->lockp, xd->tx_q_used - 1);
125  for (q = 0; q < xd->tx_q_used; q++)
126  {
129  memset ((void *) xd->lockp[q], 0, CLIB_CACHE_LINE_BYTES);
130  }
131 }
132 
133 static struct rte_mempool_ops *
134 get_ops_by_name (i8 * ops_name)
135 {
136  u32 i;
137 
138  for (i = 0; i < rte_mempool_ops_table.num_ops; i++)
139  {
140  if (!strcmp (ops_name, rte_mempool_ops_table.ops[i].name))
141  return &rte_mempool_ops_table.ops[i];
142  }
143 
144  return 0;
145 }
146 
147 static int
148 dpdk_ring_alloc (struct rte_mempool *mp)
149 {
150  u32 rg_flags = 0, count;
151  i32 ret;
152  i8 rg_name[RTE_RING_NAMESIZE];
153  struct rte_ring *r;
154 
155  ret = snprintf (rg_name, sizeof (rg_name), RTE_MEMPOOL_MZ_FORMAT, mp->name);
156  if (ret < 0 || ret >= (i32) sizeof (rg_name))
157  return -ENAMETOOLONG;
158 
159  /* ring flags */
160  if (mp->flags & MEMPOOL_F_SP_PUT)
161  rg_flags |= RING_F_SP_ENQ;
162  if (mp->flags & MEMPOOL_F_SC_GET)
163  rg_flags |= RING_F_SC_DEQ;
164 
165  count = rte_align32pow2 (mp->size + 1);
166  /*
167  * Allocate the ring that will be used to store objects.
168  * Ring functions will return appropriate errors if we are
169  * running as a secondary process etc., so no checks made
170  * in this function for that condition.
171  */
172  /* XXX can we get memory from the right socket? */
173  r = clib_mem_alloc_aligned (rte_ring_get_memsize (count),
175 
176  /* XXX rte_ring_lookup will not work */
177 
178  ret = rte_ring_init (r, rg_name, count, rg_flags);
179  if (ret)
180  return ret;
181 
182  mp->pool_data = r;
183 
184  return 0;
185 }
186 
187 static clib_error_t *
189 {
190  u32 nports;
191  u32 mtu, max_rx_frame;
192  u32 nb_desc = 0;
193  int i;
194  clib_error_t *error;
200  dpdk_device_t *xd;
201  vlib_pci_addr_t last_pci_addr;
202  u32 last_pci_addr_port = 0;
204  uword *p_hqos;
205 
206  u32 next_hqos_cpu = 0;
207  u8 af_packet_port_id = 0;
208  u8 bond_ether_port_id = 0;
209  last_pci_addr.as_u32 = ~0;
210 
211  dm->hqos_cpu_first_index = 0;
212  dm->hqos_cpu_count = 0;
213 
214  /* find out which cpus will be used for I/O TX */
215  p_hqos = hash_get_mem (tm->thread_registrations_by_name, "hqos-threads");
216  tr_hqos = p_hqos ? (vlib_thread_registration_t *) p_hqos[0] : 0;
217 
218  if (tr_hqos && tr_hqos->count > 0)
219  {
220  dm->hqos_cpu_first_index = tr_hqos->first_index;
221  dm->hqos_cpu_count = tr_hqos->count;
222  }
223 
226 
227  nports = rte_eth_dev_count ();
228  if (nports < 1)
229  {
230  clib_warning ("DPDK drivers found no ports...");
231  }
232 
233  if (CLIB_DEBUG > 0)
234  clib_warning ("DPDK drivers found %d ports...", nports);
235 
236  if (dm->conf->enable_tcp_udp_checksum)
237  dm->buffer_flags_template &= ~(VNET_BUFFER_F_L4_CHECKSUM_CORRECT
238  | VNET_BUFFER_F_L4_CHECKSUM_COMPUTED);
239 
240  /* vlib_buffer_t template */
243  for (i = 0; i < tm->n_vlib_mains; i++)
244  {
247  fl = vlib_buffer_get_free_list (vm,
250  bt->flags = dm->buffer_flags_template;
251  vnet_buffer (bt)->sw_if_index[VLIB_TX] = (u32) ~ 0;
252  }
253 
254  for (i = 0; i < nports; i++)
255  {
256  u8 addr[6];
257  u8 vlan_strip = 0;
258  int j;
259  struct rte_eth_dev_info dev_info;
260  struct rte_eth_link l;
261  dpdk_device_config_t *devconf = 0;
262  vlib_pci_addr_t pci_addr;
263  uword *p = 0;
264 
265  rte_eth_dev_info_get (i, &dev_info);
266  if (dev_info.pci_dev) /* bonded interface has no pci info */
267  {
268  pci_addr.domain = dev_info.pci_dev->addr.domain;
269  pci_addr.bus = dev_info.pci_dev->addr.bus;
270  pci_addr.slot = dev_info.pci_dev->addr.devid;
271  pci_addr.function = dev_info.pci_dev->addr.function;
272  p =
274  pci_addr.as_u32);
275  }
276 
277  if (p)
278  devconf = pool_elt_at_index (dm->conf->dev_confs, p[0]);
279  else
280  devconf = &dm->conf->default_devconf;
281 
282  /* Create vnet interface */
286  xd->cpu_socket = (i8) rte_eth_dev_socket_id (i);
287 
288  /* Handle interface naming for devices with multiple ports sharing same PCI ID */
289  if (dev_info.pci_dev)
290  {
291  struct rte_eth_dev_info di = { 0 };
292  rte_eth_dev_info_get (i + 1, &di);
293  if (di.pci_dev && pci_addr.as_u32 != last_pci_addr.as_u32 &&
294  memcmp (&dev_info.pci_dev->addr, &di.pci_dev->addr,
295  sizeof (struct rte_pci_addr)) == 0)
296  {
297  xd->interface_name_suffix = format (0, "0");
298  last_pci_addr.as_u32 = pci_addr.as_u32;
299  last_pci_addr_port = i;
300  }
301  else if (pci_addr.as_u32 == last_pci_addr.as_u32)
302  {
304  format (0, "%u", i - last_pci_addr_port);
305  }
306  else
307  {
308  last_pci_addr.as_u32 = ~0;
309  }
310  }
311  else
312  last_pci_addr.as_u32 = ~0;
313 
314  clib_memcpy (&xd->tx_conf, &dev_info.default_txconf,
315  sizeof (struct rte_eth_txconf));
316 
317  if (dm->conf->no_multi_seg)
318  {
319  xd->tx_conf.txq_flags |= ETH_TXQ_FLAGS_NOMULTSEGS;
320  port_conf_template.rxmode.jumbo_frame = 0;
321  port_conf_template.rxmode.enable_scatter = 0;
322  }
323  else
324  {
325  xd->tx_conf.txq_flags &= ~ETH_TXQ_FLAGS_NOMULTSEGS;
326  port_conf_template.rxmode.jumbo_frame = 1;
327  port_conf_template.rxmode.enable_scatter = 1;
329  }
330 
332  sizeof (struct rte_eth_conf));
333 
334  xd->tx_q_used = clib_min (dev_info.max_tx_queues, tm->n_vlib_mains);
335 
336  if (devconf->num_tx_queues > 0
337  && devconf->num_tx_queues < xd->tx_q_used)
338  xd->tx_q_used = clib_min (xd->tx_q_used, devconf->num_tx_queues);
339 
340  if (devconf->num_rx_queues > 1
341  && dev_info.max_rx_queues >= devconf->num_rx_queues)
342  {
343  xd->rx_q_used = devconf->num_rx_queues;
344  xd->port_conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
345  if (devconf->rss_fn == 0)
346  xd->port_conf.rx_adv_conf.rss_conf.rss_hf =
347  ETH_RSS_IP | ETH_RSS_UDP | ETH_RSS_TCP;
348  else
349  xd->port_conf.rx_adv_conf.rss_conf.rss_hf = devconf->rss_fn;
350  }
351  else
352  xd->rx_q_used = 1;
353 
355 
356  /* workaround for drivers not setting driver_name */
357  if ((!dev_info.driver_name) && (dev_info.pci_dev))
358  dev_info.driver_name = dev_info.pci_dev->driver->driver.name;
359 
360  ASSERT (dev_info.driver_name);
361 
362  if (!xd->pmd)
363  {
364 
365 
366 #define _(s,f) else if (dev_info.driver_name && \
367  !strcmp(dev_info.driver_name, s)) \
368  xd->pmd = VNET_DPDK_PMD_##f;
369  if (0)
370  ;
372 #undef _
373  else
375 
379 
380  switch (xd->pmd)
381  {
382  /* Drivers with valid speed_capa set */
383  case VNET_DPDK_PMD_E1000EM:
384  case VNET_DPDK_PMD_IGB:
385  case VNET_DPDK_PMD_IXGBE:
386  case VNET_DPDK_PMD_I40E:
387  xd->port_type = port_type_from_speed_capa (&dev_info);
388  if (dm->conf->no_tx_checksum_offload == 0)
389  {
390  xd->tx_conf.txq_flags &= ~ETH_TXQ_FLAGS_NOXSUMS;
391  xd->flags |=
394  }
395 
396 
397  break;
398  case VNET_DPDK_PMD_CXGBE:
399  case VNET_DPDK_PMD_MLX4:
400  case VNET_DPDK_PMD_MLX5:
401  xd->port_type = port_type_from_speed_capa (&dev_info);
402  break;
403 
404  /* SR-IOV VFs */
405  case VNET_DPDK_PMD_IGBVF:
406  case VNET_DPDK_PMD_IXGBEVF:
407  case VNET_DPDK_PMD_I40EVF:
409  xd->port_conf.rxmode.hw_strip_crc = 1;
410  break;
411 
412  case VNET_DPDK_PMD_THUNDERX:
414  xd->port_conf.rxmode.hw_strip_crc = 1;
415  break;
416 
417  case VNET_DPDK_PMD_ENA:
419  xd->port_conf.rxmode.enable_scatter = 0;
420  break;
421 
422  case VNET_DPDK_PMD_DPAA2:
424  break;
425 
426  /* Cisco VIC */
427  case VNET_DPDK_PMD_ENIC:
428  rte_eth_link_get_nowait (i, &l);
429  if (l.link_speed == 40000)
431  else
433  break;
434 
435  /* Intel Red Rock Canyon */
436  case VNET_DPDK_PMD_FM10K:
438  xd->port_conf.rxmode.hw_strip_crc = 1;
439  break;
440 
441  /* virtio */
442  case VNET_DPDK_PMD_VIRTIO:
446  break;
447 
448  /* vmxnet3 */
449  case VNET_DPDK_PMD_VMXNET3:
451  xd->tx_conf.txq_flags |= ETH_TXQ_FLAGS_NOMULTSEGS;
452  break;
453 
454  case VNET_DPDK_PMD_AF_PACKET:
456  xd->port_id = af_packet_port_id++;
457  break;
458 
459  case VNET_DPDK_PMD_BOND:
461  xd->port_id = bond_ether_port_id++;
462  break;
463 
464  case VNET_DPDK_PMD_VIRTIO_USER:
466  break;
467 
468  case VNET_DPDK_PMD_VHOST_ETHER:
470  break;
471 
472  default:
474  }
475 
476  if (devconf->num_rx_desc)
477  xd->nb_rx_desc = devconf->num_rx_desc;
478 
479  if (devconf->num_tx_desc)
480  xd->nb_tx_desc = devconf->num_tx_desc;
481  }
482 
483  if (xd->pmd == VNET_DPDK_PMD_AF_PACKET)
484  {
485  f64 now = vlib_time_now (vm);
486  u32 rnd;
487  rnd = (u32) (now * 1e6);
488  rnd = random_u32 (&rnd);
489  clib_memcpy (addr + 2, &rnd, sizeof (rnd));
490  addr[0] = 2;
491  addr[1] = 0xfe;
492  }
493  else
494  rte_eth_macaddr_get (i, (struct ether_addr *) addr);
495 
496  if (xd->tx_q_used < tm->n_vlib_mains)
498 
499  xd->device_index = xd - dm->devices;
500  ASSERT (i == xd->device_index);
501  xd->per_interface_next_index = ~0;
502 
503  /* assign interface to input thread */
504  int q;
505 
506  if (devconf->hqos_enabled)
507  {
509 
510  int cpu;
511  if (devconf->hqos.hqos_thread_valid)
512  {
513  if (devconf->hqos.hqos_thread >= dm->hqos_cpu_count)
514  return clib_error_return (0, "invalid HQoS thread index");
515 
516  cpu = dm->hqos_cpu_first_index + devconf->hqos.hqos_thread;
517  }
518  else
519  {
520  if (dm->hqos_cpu_count == 0)
521  return clib_error_return (0, "no HQoS threads available");
522 
523  cpu = dm->hqos_cpu_first_index + next_hqos_cpu;
524 
525  next_hqos_cpu++;
526  if (next_hqos_cpu == dm->hqos_cpu_count)
527  next_hqos_cpu = 0;
528 
529  devconf->hqos.hqos_thread_valid = 1;
530  devconf->hqos.hqos_thread = cpu;
531  }
532 
534  vec_add2 (dm->devices_by_hqos_cpu[cpu], dq, 1);
535  dq->device = xd->device_index;
536  dq->queue_id = 0;
537  }
538 
541  for (j = 0; j < tm->n_vlib_mains; j++)
542  {
545  vec_reset_length (xd->tx_vectors[j]);
546  }
547 
550  for (j = 0; j < xd->rx_q_used; j++)
551  {
554  vec_reset_length (xd->rx_vectors[j]);
555  }
556 
557  /* count the number of descriptors used for this device */
558  nb_desc += xd->nb_rx_desc + xd->nb_tx_desc * xd->tx_q_used;
559 
561  (dm->vnet_main, dpdk_device_class.index, xd->device_index,
562  /* ethernet address */ addr,
564  if (error)
565  return error;
566 
567  /*
568  * Ensure default mtu is not > the mtu read from the hardware.
569  * Otherwise rte_eth_dev_configure() will fail and the port will
570  * not be available.
571  * Calculate max_frame_size and mtu supported by NIC
572  */
573  if (ETHERNET_MAX_PACKET_BYTES > dev_info.max_rx_pktlen)
574  {
575  /*
576  * This device does not support the platforms's max frame
577  * size. Use it's advertised mru instead.
578  */
579  max_rx_frame = dev_info.max_rx_pktlen;
580  mtu = dev_info.max_rx_pktlen - sizeof (ethernet_header_t);
581  }
582  else
583  {
584  /* VPP treats MTU and max_rx_pktlen both equal to
585  * ETHERNET_MAX_PACKET_BYTES, if dev_info.max_rx_pktlen >=
586  * ETHERNET_MAX_PACKET_BYTES + sizeof(ethernet_header_t)
587  */
588  if (dev_info.max_rx_pktlen >= (ETHERNET_MAX_PACKET_BYTES +
589  sizeof (ethernet_header_t)))
590  {
592  max_rx_frame = ETHERNET_MAX_PACKET_BYTES;
593 
594  /*
595  * Some platforms do not account for Ethernet FCS (4 bytes) in
596  * MTU calculations. To interop with them increase mru but only
597  * if the device's settings can support it.
598  */
599  if (xd->port_conf.rxmode.hw_strip_crc &&
600  (dev_info.max_rx_pktlen >= (ETHERNET_MAX_PACKET_BYTES +
601  sizeof (ethernet_header_t) +
602  4)))
603  {
604  max_rx_frame += 4;
605  }
606  }
607  else
608  {
609  max_rx_frame = ETHERNET_MAX_PACKET_BYTES;
611 
612  if (xd->port_conf.rxmode.hw_strip_crc &&
613  (dev_info.max_rx_pktlen >= (ETHERNET_MAX_PACKET_BYTES + 4)))
614  {
615  max_rx_frame += 4;
616  }
617  }
618  }
619  /*Set port rxmode config */
620  xd->port_conf.rxmode.max_rx_pkt_len = max_rx_frame;
621 
623  xd->vlib_sw_if_index = sw->sw_if_index;
625  dpdk_input_node.index);
626 
627  if (devconf->workers)
628  {
629  int i;
630  q = 0;
631  /* *INDENT-OFF* */
632  clib_bitmap_foreach (i, devconf->workers, ({
633  vnet_hw_interface_assign_rx_thread (dm->vnet_main, xd->hw_if_index, q++,
634  vdm->first_worker_thread_index + i);
635  }));
636  /* *INDENT-ON* */
637  }
638  else
639  for (q = 0; q < xd->rx_q_used; q++)
640  {
642  ~1);
643  }
644 
645  /*Get vnet hardware interface */
647 
648  /*Override default max_packet_bytes and max_supported_bytes set in
649  * ethernet_register_interface() above*/
650  if (hi)
651  {
652  hi->max_packet_bytes = max_rx_frame;
653  hi->max_supported_packet_bytes = max_rx_frame;
654  }
655 
656  if (dm->conf->no_tx_checksum_offload == 0)
659 
660  dpdk_device_setup (xd);
661 
662  if (vec_len (xd->errors))
663  clib_warning ("setup failed for device %U. Errors:\n %U",
666 
667  if (devconf->hqos_enabled)
668  {
669  clib_error_t *rv;
670  rv = dpdk_port_setup_hqos (xd, &devconf->hqos);
671  if (rv)
672  return rv;
673  }
674 
675  /*
676  * For cisco VIC vNIC, set default to VLAN strip enabled, unless
677  * specified otherwise in the startup config.
678  * For other NICs default to VLAN strip disabled, unless specified
679  * otherwis in the startup config.
680  */
681  if (xd->pmd == VNET_DPDK_PMD_ENIC)
682  {
683  if (devconf->vlan_strip_offload != DPDK_DEVICE_VLAN_STRIP_OFF)
684  vlan_strip = 1; /* remove vlan tag from VIC port by default */
685  else
686  clib_warning ("VLAN strip disabled for interface\n");
687  }
688  else if (devconf->vlan_strip_offload == DPDK_DEVICE_VLAN_STRIP_ON)
689  vlan_strip = 1;
690 
691  if (vlan_strip)
692  {
693  int vlan_off;
694  vlan_off = rte_eth_dev_get_vlan_offload (xd->device_index);
695  vlan_off |= ETH_VLAN_STRIP_OFFLOAD;
696  xd->port_conf.rxmode.hw_vlan_strip = vlan_off;
697  if (rte_eth_dev_set_vlan_offload (xd->device_index, vlan_off) == 0)
698  clib_warning ("VLAN strip enabled for interface\n");
699  else
700  clib_warning ("VLAN strip cannot be supported by interface\n");
701  }
702 
703  if (hi)
705  xd->port_conf.rxmode.max_rx_pkt_len - sizeof (ethernet_header_t);
706  else
707  clib_warning ("hi NULL");
708 
709  rte_eth_dev_set_mtu (xd->device_index, mtu);
710  }
711 
712  if (nb_desc > dm->conf->num_mbufs)
713  clib_warning ("%d mbufs allocated but total rx/tx ring size is %d\n",
714  dm->conf->num_mbufs, nb_desc);
715 
716  return 0;
717 }
718 
719 static void
721 {
722  clib_error_t *error;
723  u8 *pci_addr = 0;
724  int num_whitelisted = vec_len (conf->dev_confs);
725  vlib_pci_device_info_t *d = 0;
726  vlib_pci_addr_t *addr = 0, *addrs;
727 
728  addrs = vlib_pci_get_all_dev_addrs ();
729  /* *INDENT-OFF* */
730  vec_foreach (addr, addrs)
731  {
732  dpdk_device_config_t * devconf = 0;
733  vec_reset_length (pci_addr);
734  pci_addr = format (pci_addr, "%U%c", format_vlib_pci_addr, addr, 0);
735  if (d)
736  {
738  d = 0;
739  }
740  d = vlib_pci_get_device_info (addr, &error);
741  if (error)
742  {
743  clib_error_report (error);
744  continue;
745  }
746 
748  continue;
749 
750  if (num_whitelisted)
751  {
752  uword * p = hash_get (conf->device_config_index_by_pci_addr, addr->as_u32);
753 
754  if (!p)
755  continue;
756 
757  devconf = pool_elt_at_index (conf->dev_confs, p[0]);
758  }
759 
760  /* virtio */
761  if (d->vendor_id == 0x1af4 &&
764  ;
765  /* vmxnet3 */
766  else if (d->vendor_id == 0x15ad && d->device_id == 0x07b0)
767  ;
768  /* all Intel network devices */
769  else if (d->vendor_id == 0x8086 && d->device_class == PCI_CLASS_NETWORK_ETHERNET)
770  ;
771  /* all Intel QAT devices VFs */
772  else if (d->vendor_id == 0x8086 && d->device_class == PCI_CLASS_PROCESSOR_CO &&
773  (d->device_id == 0x0443 || d->device_id == 0x37c9 || d->device_id == 0x19e3))
774  ;
775  /* Cisco VIC */
776  else if (d->vendor_id == 0x1137 && d->device_id == 0x0043)
777  ;
778  /* Chelsio T4/T5 */
779  else if (d->vendor_id == 0x1425 && (d->device_id & 0xe000) == 0x4000)
780  ;
781  /* Amazen Elastic Network Adapter */
782  else if (d->vendor_id == 0x1d0f && d->device_id >= 0xec20 && d->device_id <= 0xec21)
783  ;
784  /* Mellanox */
785  else if (d->vendor_id == 0x15b3 && d->device_id >= 0x1013 && d->device_id <= 0x101a)
786  {
787  continue;
788  }
789  else
790  {
791  clib_warning ("Unsupported PCI device 0x%04x:0x%04x found "
792  "at PCI address %s\n", (u16) d->vendor_id, (u16) d->device_id,
793  pci_addr);
794  continue;
795  }
796 
797  error = vlib_pci_bind_to_uio (addr, (char *) conf->uio_driver_name);
798 
799  if (error)
800  {
801  if (devconf == 0)
802  {
803  pool_get (conf->dev_confs, devconf);
804  hash_set (conf->device_config_index_by_pci_addr, addr->as_u32,
805  devconf - conf->dev_confs);
806  devconf->pci_addr.as_u32 = addr->as_u32;
807  }
808  devconf->is_blacklisted = 1;
809  clib_error_report (error);
810  }
811  }
812  /* *INDENT-ON* */
813  vec_free (pci_addr);
815 }
816 
817 static clib_error_t *
818 dpdk_device_config (dpdk_config_main_t * conf, vlib_pci_addr_t pci_addr,
819  unformat_input_t * input, u8 is_default)
820 {
821  clib_error_t *error = 0;
822  uword *p;
823  dpdk_device_config_t *devconf;
824  unformat_input_t sub_input;
825 
826  if (is_default)
827  {
828  devconf = &conf->default_devconf;
829  }
830  else
831  {
832  p = hash_get (conf->device_config_index_by_pci_addr, pci_addr.as_u32);
833 
834  if (!p)
835  {
836  pool_get (conf->dev_confs, devconf);
837  hash_set (conf->device_config_index_by_pci_addr, pci_addr.as_u32,
838  devconf - conf->dev_confs);
839  }
840  else
841  return clib_error_return (0,
842  "duplicate configuration for PCI address %U",
843  format_vlib_pci_addr, &pci_addr);
844  }
845 
846  devconf->pci_addr.as_u32 = pci_addr.as_u32;
847  devconf->hqos_enabled = 0;
849 
850  if (!input)
851  return 0;
852 
855  {
856  if (unformat (input, "num-rx-queues %u", &devconf->num_rx_queues))
857  ;
858  else if (unformat (input, "num-tx-queues %u", &devconf->num_tx_queues))
859  ;
860  else if (unformat (input, "num-rx-desc %u", &devconf->num_rx_desc))
861  ;
862  else if (unformat (input, "num-tx-desc %u", &devconf->num_tx_desc))
863  ;
864  else if (unformat (input, "workers %U", unformat_bitmap_list,
865  &devconf->workers))
866  ;
867  else
868  if (unformat
869  (input, "rss %U", unformat_vlib_cli_sub_input, &sub_input))
870  {
871  error = unformat_rss_fn (&sub_input, &devconf->rss_fn);
872  if (error)
873  break;
874  }
875  else if (unformat (input, "vlan-strip-offload off"))
877  else if (unformat (input, "vlan-strip-offload on"))
879  else
880  if (unformat
881  (input, "hqos %U", unformat_vlib_cli_sub_input, &sub_input))
882  {
883  devconf->hqos_enabled = 1;
884  error = unformat_hqos (&sub_input, &devconf->hqos);
885  if (error)
886  break;
887  }
888  else if (unformat (input, "hqos"))
889  {
890  devconf->hqos_enabled = 1;
891  }
892  else
893  {
894  error = clib_error_return (0, "unknown input `%U'",
895  format_unformat_error, input);
896  break;
897  }
898  }
899 
900  if (error)
901  return error;
902 
903  if (devconf->workers && devconf->num_rx_queues == 0)
904  devconf->num_rx_queues = clib_bitmap_count_set_bits (devconf->workers);
905  else if (devconf->workers &&
906  clib_bitmap_count_set_bits (devconf->workers) !=
907  devconf->num_rx_queues)
908  error =
910  "%U: number of worker threadds must be "
911  "equal to number of rx queues", format_vlib_pci_addr,
912  &pci_addr);
913 
914  return error;
915 }
916 
917 static clib_error_t *
919 {
920  clib_error_t *error = 0;
921  dpdk_main_t *dm = &dpdk_main;
924  dpdk_device_config_t *devconf;
925  vlib_pci_addr_t pci_addr;
926  unformat_input_t sub_input;
927  uword x;
928  u8 *s, *tmp = 0;
929  u8 *rte_cmd = 0, *ethname = 0;
930  u32 log_level;
931  int ret, i;
932  int num_whitelisted = 0;
933  u8 no_pci = 0;
934  u8 no_huge = 0;
935  u8 huge_dir = 0;
936  u8 file_prefix = 0;
937  u8 *socket_mem = 0;
938  u8 *huge_dir_path = 0;
939 
940  huge_dir_path =
941  format (0, "%s/hugepages%c", vlib_unix_get_runtime_dir (), 0);
942 
943  conf->device_config_index_by_pci_addr = hash_create (0, sizeof (uword));
944  log_level = RTE_LOG_NOTICE;
945 
947  {
948  /* Prime the pump */
949  if (unformat (input, "no-hugetlb"))
950  {
951  vec_add1 (conf->eal_init_args, (u8 *) "no-huge");
952  no_huge = 1;
953  }
954 
955  else if (unformat (input, "enable-tcp-udp-checksum"))
956  conf->enable_tcp_udp_checksum = 1;
957 
958  else if (unformat (input, "no-tx-checksum-offload"))
959  conf->no_tx_checksum_offload = 1;
960 
961  else if (unformat (input, "decimal-interface-names"))
963 
964  else if (unformat (input, "log-level %U", unformat_dpdk_log_level, &x))
965  log_level = x;
966 
967  else if (unformat (input, "no-multi-seg"))
968  conf->no_multi_seg = 1;
969 
970  else if (unformat (input, "dev default %U", unformat_vlib_cli_sub_input,
971  &sub_input))
972  {
973  error =
974  dpdk_device_config (conf, (vlib_pci_addr_t) (u32) ~ 1, &sub_input,
975  1);
976 
977  if (error)
978  return error;
979  }
980  else
981  if (unformat
982  (input, "dev %U %U", unformat_vlib_pci_addr, &pci_addr,
983  unformat_vlib_cli_sub_input, &sub_input))
984  {
985  error = dpdk_device_config (conf, pci_addr, &sub_input, 0);
986 
987  if (error)
988  return error;
989 
990  num_whitelisted++;
991  }
992  else if (unformat (input, "dev %U", unformat_vlib_pci_addr, &pci_addr))
993  {
994  error = dpdk_device_config (conf, pci_addr, 0, 0);
995 
996  if (error)
997  return error;
998 
999  num_whitelisted++;
1000  }
1001  else if (unformat (input, "num-mbufs %d", &conf->num_mbufs))
1002  ;
1003  else if (unformat (input, "uio-driver %s", &conf->uio_driver_name))
1004  ;
1005  else if (unformat (input, "socket-mem %s", &socket_mem))
1006  ;
1007  else if (unformat (input, "no-pci"))
1008  {
1009  no_pci = 1;
1010  tmp = format (0, "--no-pci%c", 0);
1011  vec_add1 (conf->eal_init_args, tmp);
1012  }
1013  else if (unformat (input, "poll-sleep %d", &dm->poll_sleep_usec))
1014  ;
1015 
1016 #define _(a) \
1017  else if (unformat(input, #a)) \
1018  { \
1019  tmp = format (0, "--%s%c", #a, 0); \
1020  vec_add1 (conf->eal_init_args, tmp); \
1021  }
1023 #undef _
1024 #define _(a) \
1025  else if (unformat(input, #a " %s", &s)) \
1026  { \
1027  if (!strncmp(#a, "huge-dir", 8)) \
1028  huge_dir = 1; \
1029  else if (!strncmp(#a, "file-prefix", 11)) \
1030  file_prefix = 1; \
1031  tmp = format (0, "--%s%c", #a, 0); \
1032  vec_add1 (conf->eal_init_args, tmp); \
1033  vec_add1 (s, 0); \
1034  if (!strncmp(#a, "vdev", 4)) \
1035  if (strstr((char*)s, "af_packet")) \
1036  clib_warning ("af_packet obsoleted. Use CLI 'create host-interface'."); \
1037  vec_add1 (conf->eal_init_args, s); \
1038  }
1040 #undef _
1041 #define _(a,b) \
1042  else if (unformat(input, #a " %s", &s)) \
1043  { \
1044  tmp = format (0, "-%s%c", #b, 0); \
1045  vec_add1 (conf->eal_init_args, tmp); \
1046  vec_add1 (s, 0); \
1047  vec_add1 (conf->eal_init_args, s); \
1048  }
1050 #undef _
1051 #define _(a,b) \
1052  else if (unformat(input, #a " %s", &s)) \
1053  { \
1054  tmp = format (0, "-%s%c", #b, 0); \
1055  vec_add1 (conf->eal_init_args, tmp); \
1056  vec_add1 (s, 0); \
1057  vec_add1 (conf->eal_init_args, s); \
1058  conf->a##_set_manually = 1; \
1059  }
1061 #undef _
1062  else if (unformat (input, "default"))
1063  ;
1064 
1065  else if (unformat_skip_white_space (input))
1066  ;
1067  else
1068  {
1069  error = clib_error_return (0, "unknown input `%U'",
1070  format_unformat_error, input);
1071  goto done;
1072  }
1073  }
1074 
1075  if (!conf->uio_driver_name)
1076  conf->uio_driver_name = format (0, "auto%c", 0);
1077 
1078  /*
1079  * Use 1G huge pages if available.
1080  */
1081  if (!no_huge && !huge_dir)
1082  {
1083  u32 x, *mem_by_socket = 0;
1084  uword c = 0;
1085  int rv;
1086 
1087  umount ((char *) huge_dir_path);
1088 
1089  /* Process "socket-mem" parameter value */
1090  if (vec_len (socket_mem))
1091  {
1092  unformat_input_t in;
1093  unformat_init_vector (&in, socket_mem);
1095  {
1096  if (unformat (&in, "%u,", &x))
1097  ;
1098  else if (unformat (&in, "%u", &x))
1099  ;
1100  else if (unformat (&in, ","))
1101  x = 0;
1102  else
1103  break;
1104 
1105  vec_add1 (mem_by_socket, x);
1106  }
1107  /* Note: unformat_free vec_frees(in.buffer), aka socket_mem... */
1108  unformat_free (&in);
1109  socket_mem = 0;
1110  }
1111  else
1112  {
1113  /* *INDENT-OFF* */
1115  {
1116  vec_validate(mem_by_socket, c);
1117  mem_by_socket[c] = 64; /* default per-socket mem */
1118  }
1119  ));
1120  /* *INDENT-ON* */
1121  }
1122 
1123  /* *INDENT-OFF* */
1125  {
1126  clib_error_t *e;
1127 
1128  vec_validate(mem_by_socket, c);
1129 
1130  e = clib_sysfs_prealloc_hugepages(c, 2 << 10, mem_by_socket[c] / 2);
1131  if (e)
1132  clib_error_report (e);
1133  }));
1134  /* *INDENT-ON* */
1135 
1136  if (mem_by_socket == 0)
1137  {
1138  error = clib_error_return (0, "mem_by_socket NULL");
1139  goto done;
1140  }
1141  _vec_len (mem_by_socket) = c + 1;
1142 
1143  /* regenerate socket_mem string */
1144  vec_foreach_index (x, mem_by_socket)
1145  socket_mem = format (socket_mem, "%s%u",
1146  socket_mem ? "," : "", mem_by_socket[x]);
1147  socket_mem = format (socket_mem, "%c", 0);
1148 
1149  vec_free (mem_by_socket);
1150 
1151  error = vlib_unix_recursive_mkdir ((char *) huge_dir_path);
1152  if (error)
1153  {
1154  goto done;
1155  }
1156 
1157  rv = mount ("none", (char *) huge_dir_path, "hugetlbfs", 0, NULL);
1158 
1159  if (rv)
1160  {
1161  error = clib_error_return (0, "mount failed %d", errno);
1162  goto done;
1163  }
1164 
1165  tmp = format (0, "--huge-dir%c", 0);
1166  vec_add1 (conf->eal_init_args, tmp);
1167  tmp = format (0, "%s%c", huge_dir_path, 0);
1168  vec_add1 (conf->eal_init_args, tmp);
1169  if (!file_prefix)
1170  {
1171  tmp = format (0, "--file-prefix%c", 0);
1172  vec_add1 (conf->eal_init_args, tmp);
1173  tmp = format (0, "vpp%c", 0);
1174  vec_add1 (conf->eal_init_args, tmp);
1175  }
1176  }
1177 
1178  vec_free (rte_cmd);
1179  vec_free (ethname);
1180 
1181  if (error)
1182  return error;
1183 
1184  /* I'll bet that -c and -n must be the first and second args... */
1185  if (!conf->coremask_set_manually)
1186  {
1188  uword *coremask = 0;
1189  int i;
1190 
1191  /* main thread core */
1192  coremask = clib_bitmap_set (coremask, tm->main_lcore, 1);
1193 
1194  for (i = 0; i < vec_len (tm->registrations); i++)
1195  {
1196  tr = tm->registrations[i];
1197  coremask = clib_bitmap_or (coremask, tr->coremask);
1198  }
1199 
1200  vec_insert (conf->eal_init_args, 2, 1);
1201  conf->eal_init_args[1] = (u8 *) "-c";
1202  tmp = format (0, "%U%c", format_bitmap_hex, coremask, 0);
1203  conf->eal_init_args[2] = tmp;
1204  clib_bitmap_free (coremask);
1205  }
1206 
1207  if (!conf->nchannels_set_manually)
1208  {
1209  vec_insert (conf->eal_init_args, 2, 3);
1210  conf->eal_init_args[3] = (u8 *) "-n";
1211  tmp = format (0, "%d", conf->nchannels);
1212  conf->eal_init_args[4] = tmp;
1213  }
1214 
1215  if (no_pci == 0 && geteuid () == 0)
1216  dpdk_bind_devices_to_uio (conf);
1217 
1218 #define _(x) \
1219  if (devconf->x == 0 && conf->default_devconf.x > 0) \
1220  devconf->x = conf->default_devconf.x ;
1221 
1222  /* *INDENT-OFF* */
1223  pool_foreach (devconf, conf->dev_confs, ({
1224 
1225  /* default per-device config items */
1226  foreach_dpdk_device_config_item
1227 
1228  /* add DPDK EAL whitelist/blacklist entry */
1229  if (num_whitelisted > 0 && devconf->is_blacklisted == 0)
1230  {
1231  tmp = format (0, "-w%c", 0);
1232  vec_add1 (conf->eal_init_args, tmp);
1233  tmp = format (0, "%U%c", format_vlib_pci_addr, &devconf->pci_addr, 0);
1234  vec_add1 (conf->eal_init_args, tmp);
1235  }
1236  else if (num_whitelisted == 0 && devconf->is_blacklisted != 0)
1237  {
1238  tmp = format (0, "-b%c", 0);
1239  vec_add1 (conf->eal_init_args, tmp);
1240  tmp = format (0, "%U%c", format_vlib_pci_addr, &devconf->pci_addr, 0);
1241  vec_add1 (conf->eal_init_args, tmp);
1242  }
1243  }));
1244  /* *INDENT-ON* */
1245 
1246 #undef _
1247 
1248  /* set master-lcore */
1249  tmp = format (0, "--master-lcore%c", 0);
1250  vec_add1 (conf->eal_init_args, tmp);
1251  tmp = format (0, "%u%c", tm->main_lcore, 0);
1252  vec_add1 (conf->eal_init_args, tmp);
1253 
1254  /* set socket-mem */
1255  tmp = format (0, "--socket-mem%c", 0);
1256  vec_add1 (conf->eal_init_args, tmp);
1257  tmp = format (0, "%s%c", socket_mem, 0);
1258  vec_add1 (conf->eal_init_args, tmp);
1259 
1260  /* NULL terminate the "argv" vector, in case of stupidity */
1261  vec_add1 (conf->eal_init_args, 0);
1262  _vec_len (conf->eal_init_args) -= 1;
1263 
1264  /* Set up DPDK eal and packet mbuf pool early. */
1265 
1266  rte_log_set_global_level (log_level);
1267 
1268  vm = vlib_get_main ();
1269 
1270  /* make copy of args as rte_eal_init tends to mess up with arg array */
1271  for (i = 1; i < vec_len (conf->eal_init_args); i++)
1272  conf->eal_init_args_str = format (conf->eal_init_args_str, "%s ",
1273  conf->eal_init_args[i]);
1274 
1275  clib_warning ("EAL init args: %s", conf->eal_init_args_str);
1276  ret =
1277  rte_eal_init (vec_len (conf->eal_init_args),
1278  (char **) conf->eal_init_args);
1279 
1280  /* lazy umount hugepages */
1281  umount2 ((char *) huge_dir_path, MNT_DETACH);
1282  rmdir ((char *) huge_dir_path);
1283  vec_free (huge_dir_path);
1284 
1285  if (ret < 0)
1286  return clib_error_return (0, "rte_eal_init returned %d", ret);
1287 
1288  /* Dump the physical memory layout prior to creating the mbuf_pool */
1289  fprintf (stdout, "DPDK physical memory layout:\n");
1290  rte_dump_physmem_layout (stdout);
1291 
1292  /* set custom ring memory allocator */
1293  {
1294  struct rte_mempool_ops *ops = NULL;
1295 
1296  ops = get_ops_by_name ("ring_sp_sc");
1297  ops->alloc = dpdk_ring_alloc;
1298 
1299  ops = get_ops_by_name ("ring_mp_sc");
1300  ops->alloc = dpdk_ring_alloc;
1301 
1302  ops = get_ops_by_name ("ring_sp_mc");
1303  ops->alloc = dpdk_ring_alloc;
1304 
1305  ops = get_ops_by_name ("ring_mp_mc");
1306  ops->alloc = dpdk_ring_alloc;
1307  }
1308 
1309  /* main thread 1st */
1310  error = dpdk_buffer_pool_create (vm, conf->num_mbufs, rte_socket_id ());
1311  if (error)
1312  return error;
1313 
1314  for (i = 0; i < RTE_MAX_LCORE; i++)
1315  {
1316  error = dpdk_buffer_pool_create (vm, conf->num_mbufs,
1317  rte_lcore_to_socket_id (i));
1318  if (error)
1319  return error;
1320  }
1321 
1322 done:
1323  return error;
1324 }
1325 
1327 
1328 void
1330 {
1331  vnet_main_t *vnm = vnet_get_main ();
1332  struct rte_eth_link prev_link = xd->link;
1333  u32 hw_flags = 0;
1334  u8 hw_flags_chg = 0;
1335 
1336  /* only update link state for PMD interfaces */
1337  if ((xd->flags & DPDK_DEVICE_FLAG_PMD) == 0)
1338  return;
1339 
1340  xd->time_last_link_update = now ? now : xd->time_last_link_update;
1341  memset (&xd->link, 0, sizeof (xd->link));
1342  rte_eth_link_get_nowait (xd->device_index, &xd->link);
1343 
1344  if (LINK_STATE_ELOGS)
1345  {
1347  ELOG_TYPE_DECLARE (e) =
1348  {
1349  .format =
1350  "update-link-state: sw_if_index %d, admin_up %d,"
1351  "old link_state %d new link_state %d",.format_args = "i4i1i1i1",};
1352 
1353  struct
1354  {
1355  u32 sw_if_index;
1356  u8 admin_up;
1357  u8 old_link_state;
1358  u8 new_link_state;
1359  } *ed;
1360  ed = ELOG_DATA (&vm->elog_main, e);
1361  ed->sw_if_index = xd->vlib_sw_if_index;
1362  ed->admin_up = (xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP) != 0;
1363  ed->old_link_state = (u8)
1365  ed->new_link_state = (u8) xd->link.link_status;
1366  }
1367 
1369  && ((xd->link.link_status != 0) ^
1371  {
1372  hw_flags_chg = 1;
1373  hw_flags |= (xd->link.link_status ? VNET_HW_INTERFACE_FLAG_LINK_UP : 0);
1374  }
1375 
1376  if (hw_flags_chg || (xd->link.link_duplex != prev_link.link_duplex))
1377  {
1378  hw_flags_chg = 1;
1379  switch (xd->link.link_duplex)
1380  {
1381  case ETH_LINK_HALF_DUPLEX:
1383  break;
1384  case ETH_LINK_FULL_DUPLEX:
1386  break;
1387  default:
1388  break;
1389  }
1390  }
1391  if (hw_flags_chg || (xd->link.link_speed != prev_link.link_speed))
1392  {
1393  hw_flags_chg = 1;
1394  switch (xd->link.link_speed)
1395  {
1396  case ETH_SPEED_NUM_10M:
1398  break;
1399  case ETH_SPEED_NUM_100M:
1401  break;
1402  case ETH_SPEED_NUM_1G:
1403  hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_1G;
1404  break;
1405  case ETH_SPEED_NUM_2_5G:
1407  break;
1408  case ETH_SPEED_NUM_5G:
1409  hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_5G;
1410  break;
1411  case ETH_SPEED_NUM_10G:
1413  break;
1414  case ETH_SPEED_NUM_20G:
1416  break;
1417  case ETH_SPEED_NUM_25G:
1419  break;
1420  case ETH_SPEED_NUM_40G:
1422  break;
1423  case ETH_SPEED_NUM_50G:
1425  break;
1426  case ETH_SPEED_NUM_56G:
1428  break;
1429  case ETH_SPEED_NUM_100G:
1431  break;
1432  case 0:
1433  break;
1434  default:
1435  clib_warning ("unknown link speed %d", xd->link.link_speed);
1436  break;
1437  }
1438  }
1439  if (hw_flags_chg)
1440  {
1441  if (LINK_STATE_ELOGS)
1442  {
1444 
1445  ELOG_TYPE_DECLARE (e) =
1446  {
1447  .format =
1448  "update-link-state: sw_if_index %d, new flags %d",.format_args
1449  = "i4i4",};
1450 
1451  struct
1452  {
1453  u32 sw_if_index;
1454  u32 flags;
1455  } *ed;
1456  ed = ELOG_DATA (&vm->elog_main, e);
1457  ed->sw_if_index = xd->vlib_sw_if_index;
1458  ed->flags = hw_flags;
1459  }
1460  vnet_hw_interface_set_flags (vnm, xd->hw_if_index, hw_flags);
1461  }
1462 }
1463 
1464 static uword
1466 {
1467  clib_error_t *error;
1468  vnet_main_t *vnm = vnet_get_main ();
1469  dpdk_main_t *dm = &dpdk_main;
1471  dpdk_device_t *xd;
1473  int i;
1474 
1475  error = dpdk_lib_init (dm);
1476 
1477  if (error)
1478  clib_error_report (error);
1479 
1480  tm->worker_thread_release = 1;
1481 
1482  f64 now = vlib_time_now (vm);
1483  vec_foreach (xd, dm->devices)
1484  {
1485  dpdk_update_link_state (xd, now);
1486  }
1487 
1488  {
1489  /*
1490  * Extra set up for bond interfaces:
1491  * 1. Setup MACs for bond interfaces and their slave links which was set
1492  * in dpdk_device_setup() but needs to be done again here to take
1493  * effect.
1494  * 2. Set up info and register slave link state change callback handling.
1495  * 3. Set up info for bond interface related CLI support.
1496  */
1497  int nports = rte_eth_dev_count ();
1498  if (nports > 0)
1499  {
1500  for (i = 0; i < nports; i++)
1501  {
1502  xd = &dm->devices[i];
1503  ASSERT (i == xd->device_index);
1504  if (xd->pmd == VNET_DPDK_PMD_BOND)
1505  {
1506  u8 addr[6];
1507  dpdk_portid_t slink[16];
1508  int nlink = rte_eth_bond_slaves_get (i, slink, 16);
1509  if (nlink > 0)
1510  {
1511  vnet_hw_interface_t *bhi;
1512  ethernet_interface_t *bei;
1513  int rv;
1514 
1515  /* Get MAC of 1st slave link */
1516  rte_eth_macaddr_get
1517  (slink[0], (struct ether_addr *) addr);
1518 
1519  /* Set MAC of bounded interface to that of 1st slave link */
1520  clib_warning ("Set MAC for bond port %d BondEthernet%d",
1521  i, xd->port_id);
1522  rv = rte_eth_bond_mac_address_set
1523  (i, (struct ether_addr *) addr);
1524  if (rv)
1525  clib_warning ("Set MAC addr failure rv=%d", rv);
1526 
1527  /* Populate MAC of bonded interface in VPP hw tables */
1528  bhi = vnet_get_hw_interface
1529  (vnm, dm->devices[i].hw_if_index);
1530  bei = pool_elt_at_index
1531  (em->interfaces, bhi->hw_instance);
1532  clib_memcpy (bhi->hw_address, addr, 6);
1533  clib_memcpy (bei->address, addr, 6);
1534 
1535  /* Init l3 packet size allowed on bonded interface */
1540  while (nlink >= 1)
1541  { /* for all slave links */
1542  int slave = slink[--nlink];
1543  dpdk_device_t *sdev = &dm->devices[slave];
1544  vnet_hw_interface_t *shi;
1545  vnet_sw_interface_t *ssi;
1546  ethernet_interface_t *sei;
1547  /* Add MAC to all slave links except the first one */
1548  if (nlink)
1549  {
1550  clib_warning ("Add MAC for slave port %d", slave);
1551  rv = rte_eth_dev_mac_addr_add
1552  (slave, (struct ether_addr *) addr, 0);
1553  if (rv)
1554  clib_warning ("Add MAC addr failure rv=%d", rv);
1555  }
1556  /* Setup slave link state change callback handling */
1557  rte_eth_dev_callback_register
1558  (slave, RTE_ETH_EVENT_INTR_LSC,
1560  dpdk_device_t *sxd = &dm->devices[slave];
1562  sxd->bond_port = i;
1563  /* Set slaves bitmap for bonded interface */
1564  bhi->bond_info = clib_bitmap_set
1565  (bhi->bond_info, sdev->hw_if_index, 1);
1566  /* Set MACs and slave link flags on slave interface */
1567  shi = vnet_get_hw_interface (vnm, sdev->hw_if_index);
1568  ssi = vnet_get_sw_interface
1569  (vnm, sdev->vlib_sw_if_index);
1570  sei = pool_elt_at_index
1571  (em->interfaces, shi->hw_instance);
1574  clib_memcpy (shi->hw_address, addr, 6);
1575  clib_memcpy (sei->address, addr, 6);
1576  /* Set l3 packet size allowed as the lowest of slave */
1577  if (bhi->max_l3_packet_bytes[VLIB_RX] >
1582  /* Set max packet size allowed as the lowest of slave */
1583  if (bhi->max_packet_bytes > shi->max_packet_bytes)
1584  bhi->max_packet_bytes = shi->max_packet_bytes;
1585  }
1586  }
1587  }
1588  }
1589  }
1590  }
1591 
1592  while (1)
1593  {
1594  /*
1595  * check each time through the loop in case intervals are changed
1596  */
1597  f64 min_wait = dm->link_state_poll_interval < dm->stat_poll_interval ?
1599 
1600  vlib_process_wait_for_event_or_clock (vm, min_wait);
1601 
1602  if (dm->admin_up_down_in_progress)
1603  /* skip the poll if an admin up down is in progress (on any interface) */
1604  continue;
1605 
1606  vec_foreach (xd, dm->devices)
1607  {
1608  f64 now = vlib_time_now (vm);
1609  if ((now - xd->time_last_stats_update) >= dm->stat_poll_interval)
1610  dpdk_update_counters (xd, now);
1611  if ((now - xd->time_last_link_update) >= dm->link_state_poll_interval)
1612  dpdk_update_link_state (xd, now);
1613 
1614  }
1615  }
1616 
1617  return 0;
1618 }
1619 
1620 /* *INDENT-OFF* */
1622  .function = dpdk_process,
1623  .type = VLIB_NODE_TYPE_PROCESS,
1624  .name = "dpdk-process",
1625  .process_log2_n_stack_bytes = 17,
1626 };
1627 /* *INDENT-ON* */
1628 
1629 static clib_error_t *
1631 {
1632  dpdk_main_t *dm = &dpdk_main;
1633  clib_error_t *error = 0;
1635 
1636  /* verify that structs are cacheline aligned */
1637  STATIC_ASSERT (offsetof (dpdk_device_t, cacheline0) == 0,
1638  "Cache line marker must be 1st element in dpdk_device_t");
1639  STATIC_ASSERT (offsetof (dpdk_device_t, cacheline1) ==
1641  "Data in cache line 0 is bigger than cache line size");
1642  STATIC_ASSERT (offsetof (frame_queue_trace_t, cacheline0) == 0,
1643  "Cache line marker must be 1st element in frame_queue_trace_t");
1644 
1645  dm->vlib_main = vm;
1646  dm->vnet_main = vnet_get_main ();
1647  dm->conf = &dpdk_config_main;
1648 
1649  dm->conf->nchannels = 4;
1650  dm->conf->num_mbufs = dm->conf->num_mbufs ? dm->conf->num_mbufs : NB_MBUF;
1651  vec_add1 (dm->conf->eal_init_args, (u8 *) "vnet");
1652 
1653  vec_validate (dm->recycle, tm->n_thread_stacks - 1);
1654 
1655  /* Default vlib_buffer_t flags, DISABLES tcp/udp checksumming... */
1656  dm->buffer_flags_template =
1657  (VLIB_BUFFER_TOTAL_LENGTH_VALID | VLIB_BUFFER_EXT_HDR_VALID
1658  | VNET_BUFFER_F_L4_CHECKSUM_COMPUTED |
1659  VNET_BUFFER_F_L4_CHECKSUM_CORRECT | VNET_BUFFER_F_L2_HDR_OFFSET_VALID);
1660 
1663 
1664  /* init CLI */
1665  if ((error = vlib_call_init_function (vm, dpdk_cli_init)))
1666  return error;
1667 
1668  return error;
1669 }
1670 
1672 
1673 
1674 /*
1675  * fd.io coding-style-patch-verification: ON
1676  *
1677  * Local Variables:
1678  * eval: (c-set-style "gnu")
1679  * End:
1680  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:434
#define DPDK_DEVICE_FLAG_PROMISC
Definition: dpdk.h:183
static void dpdk_bind_devices_to_uio(dpdk_config_main_t *conf)
Definition: init.c:720
f64 time_last_link_update
Definition: dpdk.h:223
vmrglw vmrglh hi
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:280
#define vec_foreach_index(var, v)
Iterate over vector indices.
#define hash_set(h, key, value)
Definition: hash.h:254
#define VIRTIO_PCI_MODERN_DEVICEID_NET
Definition: pci_config.h:169
#define clib_min(x, y)
Definition: clib.h:340
#define VNET_HW_INTERFACE_FLAG_SPEED_1G
Definition: interface.h:403
ethernet_main_t ethernet_main
Definition: init.c:45
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Definition: interface.c:554
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:699
#define VNET_HW_INTERFACE_FLAG_SPEED_50G
Definition: interface.h:410
u8 interface_name_format_decimal
Definition: dpdk.h:338
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
#define NB_MBUF
Definition: dpdk.h:55
vnet_device_class_t dpdk_device_class
#define DPDK_DEVICE_VLAN_STRIP_OFF
Definition: dpdk.h:305
#define DPDK_DEVICE_FLAG_TX_OFFLOAD
Definition: dpdk.h:191
#define NULL
Definition: clib.h:55
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:227
#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:571
static uword * clib_bitmap_or(uword *ai, uword *bi)
Logical operator across two bitmaps.
static u32 dpdk_flag_change(vnet_main_t *vnm, vnet_hw_interface_t *hi, u32 flags)
Definition: init.c:89
void dpdk_update_link_state(dpdk_device_t *xd, f64 now)
Definition: init.c:1329
vlib_pci_device_info_t * vlib_pci_get_device_info(vlib_pci_addr_t *addr, clib_error_t **error)
Definition: pci.c:162
u16 flags
Definition: dpdk.h:181
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define LINK_STATE_ELOGS
Definition: init.c:42
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:520
dpdk_device_and_queue_t ** devices_by_hqos_cpu
Definition: dpdk.h:354
#define DPDK_NB_RX_DESC_VIRTIO
Definition: dpdk_priv.h:21
clib_error_t * errors
Definition: dpdk.h:237
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:559
#define DPDK_DEVICE_FLAG_HQOS
Definition: dpdk.h:188
int i
u32 per_interface_next_index
Definition: dpdk.h:172
u8 enable_tcp_udp_checksum
Definition: dpdk.h:324
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:306
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
vlib_buffer_t * buffer_templates
Definition: dpdk.h:360
#define VNET_HW_INTERFACE_FLAG_SPEED_100G
Definition: interface.h:412
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
#define DPDK_NB_TX_DESC_DEFAULT
Definition: dpdk_priv.h:20
#define foreach_eal_double_hyphen_predicate_arg
Definition: dpdk_priv.h:32
unformat_function_t unformat_vlib_pci_addr
Definition: pci.h:279
#define VNET_HW_INTERFACE_FLAG_LINK_UP
Definition: interface.h:390
int dpdk_port_state_callback(dpdk_portid_t port_id, enum rte_eth_event_type type, void *param, void *ret_param)
Definition: common.c:304
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:445
dpdk_device_config_hqos_t hqos
Definition: dpdk.h:313
vlib_pci_addr_t * vlib_pci_get_all_dev_addrs()
Definition: pci.c:1242
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:227
dpdk_config_main_t dpdk_config_main
Definition: init.c:40
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
#define DPDK_DEVICE_FLAG_PMD
Definition: dpdk.h:184
static vnet_sw_interface_t * vnet_get_hw_sw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM
Definition: dpdk.h:192
#define VNET_HW_INTERFACE_FLAG_SPEED_2_5G
Definition: interface.h:404
struct rte_mbuf *** tx_vectors
Definition: dpdk.h:175
foreach_dpdk_device_config_item clib_bitmap_t * workers
Definition: dpdk.h:311
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:440
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
dpdk_portid_t port_id
Definition: dpdk.h:216
vlib_node_registration_t dpdk_input_node
(constructor) VLIB_REGISTER_NODE (dpdk_input_node)
Definition: node.c:608
dpdk_device_config_t default_devconf
Definition: dpdk.h:341
f64 stat_poll_interval
Definition: dpdk.h:384
static char * vlib_unix_get_runtime_dir(void)
Definition: unix.h:138
static dpdk_port_type_t port_type_from_speed_capa(struct rte_eth_dev_info *dev_info)
Definition: init.c:60
int i32
Definition: types.h:81
clib_error_t * vlib_pci_bind_to_uio(vlib_pci_addr_t *addr, char *uio_drv_name)
Definition: pci.c:345
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.
#define clib_error_return(e, args...)
Definition: error.h:99
u16 rx_q_used
Definition: dpdk.h:204
#define VNET_HW_INTERFACE_FLAG_SPEED_25G
Definition: interface.h:408
#define DPDK_DEVICE_FLAG_MAYBE_MULTISEG
Definition: dpdk.h:186
void dpdk_device_setup(dpdk_device_t *xd)
Definition: common.c:39
#define vlib_call_init_function(vm, x)
Definition: init.h:162
clib_error_t * unformat_rss_fn(unformat_input_t *input, uword *rss_fn)
Definition: format.c:769
#define VLIB_FRAME_SIZE
Definition: node.h:328
#define DPDK_NB_TX_DESC_VIRTIO
Definition: dpdk_priv.h:22
struct rte_eth_conf port_conf
Definition: dpdk.h:208
static clib_error_t * dpdk_init(vlib_main_t *vm)
Definition: init.c:1630
#define fl(x, y)
u32 max_supported_packet_bytes
Definition: interface.h:466
f64 time_last_stats_update
Definition: dpdk.h:230
u32 vlib_sw_if_index
Definition: dpdk.h:169
struct rte_eth_txconf tx_conf
Definition: dpdk.h:209
#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:461
#define vec_insert(V, N, M)
Insert N vector elements starting at element M, initialize new elements to zero (no header...
Definition: vec.h:684
vlib_pci_addr_t pci_addr
Definition: dpdk.h:301
clib_error_t * dpdk_buffer_pool_create(vlib_main_t *vm, unsigned num_mbufs, unsigned socket_id)
Definition: buffer.c:557
static clib_error_t * dpdk_config(vlib_main_t *vm, unformat_input_t *input)
Definition: init.c:918
#define foreach_eal_double_hyphen_arg
Definition: dpdk_priv.h:48
dpdk_portid_t bond_port
Definition: dpdk.h:220
#define ETHERNET_INTERFACE_FLAG_CONFIG_MTU(flags)
Definition: ethernet.h:153
u8 ** eal_init_args
Definition: dpdk.h:320
#define VNET_HW_INTERFACE_FLAG_SPEED_10M
Definition: interface.h:401
#define VNET_SW_INTERFACE_FLAG_BOND_SLAVE
Definition: interface.h:597
#define VNET_HW_INTERFACE_FLAG_SPEED_56G
Definition: interface.h:411
#define foreach_eal_single_hyphen_mandatory_arg
Definition: dpdk_priv.h:38
struct _unformat_input_t unformat_input_t
#define VNET_HW_INTERFACE_FLAG_HALF_DUPLEX
Definition: interface.h:393
#define foreach_dpdk_pmd
Definition: dpdk.h:60
#define VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX
Definition: buffer.h:446
#define ELOG_DATA(em, f)
Definition: elog.h:481
#define VIRTIO_PCI_LEGACY_DEVICEID_NET
Definition: pci_config.h:168
dpdk_port_type_t port_type
Definition: dpdk.h:231
#define VLIB_CONFIG_FUNCTION(x, n,...)
Definition: init.h:119
u16 tx_q_used
Definition: dpdk.h:203
u16 nb_rx_desc
Definition: dpdk.h:205
uint16_t dpdk_portid_t
Definition: dpdk.h:124
u32 hw_if_index
Definition: dpdk.h:168
void unformat_init_vector(unformat_input_t *input, u8 *vector_string)
Definition: unformat.c:1031
#define DPDK_DEVICE_FLAG_ADMIN_UP
Definition: dpdk.h:182
u32 ** recycle
Definition: dpdk.h:357
#define VNET_HW_INTERFACE_BOND_INFO_SLAVE
Definition: interface.h:494
#define foreach_eal_single_hyphen_arg
Definition: dpdk_priv.h:42
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:143
#define DPDK_NB_RX_DESC_DEFAULT
Definition: dpdk_priv.h:19
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
svmdb_client_t * c
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:818
dpdk_device_t * devices
Definition: dpdk.h:353
vlib_main_t * vm
Definition: buffer.c:294
static void dpdk_update_counters(dpdk_device_t *xd, f64 now)
Definition: dpdk_priv.h:88
u8 nchannels_set_manually
Definition: dpdk.h:329
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:336
volatile u32 ** lockp
Definition: dpdk.h:163
dpdk_device_config_t * dev_confs
Definition: dpdk.h:342
struct rte_mbuf *** rx_vectors
Definition: dpdk.h:176
#define clib_warning(format, args...)
Definition: error.h:59
#define clib_memcpy(a, b, c)
Definition: string.h:75
dpdk_pmd_t pmd
Definition: dpdk.h:178
format_function_t format_dpdk_device_errors
Definition: dpdk.h:453
elog_main_t elog_main
Definition: main.h:158
#define ETHERNET_INTERFACE_FLAG_ACCEPT_ALL
Definition: ethernet.h:147
#define VNET_HW_INTERFACE_FLAG_SUPPORTS_TX_L4_CKSUM_OFFLOAD
Definition: interface.h:431
u8 coremask_set_manually
Definition: dpdk.h:328
#define ELOG_TYPE_DECLARE(f)
Definition: elog.h:439
#define VNET_HW_INTERFACE_FLAG_SPEED_10G
Definition: interface.h:406
#define vec_validate_ha(V, I, H, A)
Make sure vector is long enough for given index (general version).
Definition: vec.h:412
static void dpdk_device_lock_init(dpdk_device_t *xd)
Definition: init.c:121
u8 * interface_name_suffix
Definition: dpdk.h:197
#define hash_create(elts, value_bytes)
Definition: hash.h:681
#define VNET_HW_INTERFACE_FLAG_FULL_DUPLEX
Definition: interface.h:394
u32 max_l3_packet_bytes[VLIB_N_RX_TX]
Definition: interface.h:480
#define ASSERT(truth)
void dpdk_device_config_hqos_default(dpdk_device_config_hqos_t *hqos)
Definition: hqos.c:205
format_function_t format_dpdk_device_name
Definition: dpdk.h:451
unsigned int u32
Definition: types.h:88
int hqos_cpu_count
Definition: dpdk.h:380
void vnet_hw_interface_assign_rx_thread(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id, uword thread_index)
Definition: devices.c:138
u32 poll_sleep_usec
Definition: dpdk.h:387
static uword dpdk_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: init.c:1465
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:273
#define clib_error_report(e)
Definition: error.h:113
#define clib_bitmap_free(v)
Free a bitmap.
Definition: bitmap.h:92
#define DPDK_LINK_POLL_INTERVAL
Definition: dpdk.h:243
size_t count
Definition: vapi.c:42
dpdk_main_t dpdk_main
Definition: init.c:39
uword * thread_registrations_by_name
Definition: threads.h:297
clib_error_t * dpdk_cli_init(vlib_main_t *vm)
Definition: cli.c:1942
dpdk_portid_t device_index
Definition: dpdk.h:166
struct rte_eth_link link
Definition: dpdk.h:222
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
clib_error_t * dpdk_port_setup_hqos(dpdk_device_t *xd, dpdk_device_config_hqos_t *hqos)
Definition: hqos.c:247
u64 uword
Definition: types.h:112
dpdk_port_type_t
Definition: dpdk.h:92
static uword clib_bitmap_count_set_bits(uword *ai)
Return the number of set bits in a bitmap.
Definition: bitmap.h:441
Definition: defs.h:47
clib_error_t * vlib_unix_recursive_mkdir(char *path)
Definition: util.c:103
#define DPDK_STATS_POLL_INTERVAL
Definition: dpdk.h:240
unsigned short u16
Definition: types.h:57
#define VNET_HW_INTERFACE_FLAG_SPEED_100M
Definition: interface.h:402
static vlib_node_registration_t dpdk_process_node
(constructor) VLIB_REGISTER_NODE (dpdk_process_node)
Definition: init.c:1621
#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
uword unformat_vlib_cli_sub_input(unformat_input_t *i, va_list *args)
Definition: cli.c:152
u8 admin_up_down_in_progress
Definition: dpdk.h:376
#define STATIC_ASSERT(truth,...)
#define VNET_HW_INTERFACE_FLAG_SPEED_5G
Definition: interface.h:405
static struct rte_eth_conf port_conf_template
Definition: init.c:46
u8 no_tx_checksum_offload
Definition: dpdk.h:325
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
static void unformat_free(unformat_input_t *i)
Definition: format.h:161
#define DPDK_DEVICE_FLAG_BOND_SLAVE
Definition: dpdk.h:189
static clib_error_t * dpdk_lib_init(dpdk_main_t *dm)
Definition: init.c:188
static struct rte_mempool_ops * get_ops_by_name(i8 *ops_name)
Definition: init.c:134
#define hash_get_mem(h, key)
Definition: hash.h:268
u32 buffer_flags_template
Definition: dpdk.h:363
static void * clib_mem_alloc_aligned(uword size, uword align)
Definition: mem.h:120
static void vlib_buffer_init_for_free_list(vlib_buffer_t *dst, vlib_buffer_free_list_t *fl)
Definition: buffer_funcs.h:915
#define vnet_buffer(b)
Definition: buffer.h:372
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:409
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
int hqos_cpu_first_index
Definition: dpdk.h:379
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
#define ETHERNET_MAX_PACKET_BYTES
Definition: ethernet.h:140
#define vec_foreach(var, vec)
Vector iterator.
i8 cpu_socket
Definition: dpdk.h:179
#define ETHERNET_INTERFACE_FLAG_CONFIG_PROMISC(flags)
Definition: ethernet.h:148
uword * cpu_socket_bitmap
Definition: threads.h:332
static int dpdk_ring_alloc(struct rte_mempool *mp)
Definition: init.c:148
vhost_vring_addr_t addr
Definition: vhost-user.h:83
static vlib_buffer_free_list_t * vlib_buffer_get_free_list(vlib_main_t *vm, vlib_buffer_free_list_index_t free_list_index)
Definition: buffer_funcs.h:519
u8 * uio_driver_name
Definition: dpdk.h:322
vlib_thread_registration_t ** registrations
Definition: threads.h:295
static void vlib_pci_free_device_info(vlib_pci_device_info_t *di)
Definition: pci.h:107
u32 flags
Definition: vhost-user.h:77
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
unformat_function_t unformat_dpdk_log_level
Definition: dpdk.h:458
ethernet_interface_t * interfaces
Definition: ethernet.h:278
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:111
vnet_main_t * vnet_main
Definition: dpdk.h:391
u16 nb_tx_desc
Definition: dpdk.h:194
clib_error_t * unformat_hqos(unformat_input_t *input, dpdk_device_config_hqos_t *hqos)
Definition: format.c:806
u16 device_class
Definition: pci.h:72
#define VNET_HW_INTERFACE_FLAG_SPEED_20G
Definition: interface.h:407
uword * device_config_index_by_pci_addr
Definition: dpdk.h:343
uword unformat_skip_white_space(unformat_input_t *input)
Definition: unformat.c:815
static uword vnet_hw_interface_is_link_up(vnet_main_t *vnm, u32 hw_if_index)
volatile u32 worker_thread_release
Definition: threads.h:338
static void vnet_hw_interface_set_input_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
Definition: devices.h:79
vnet_device_main_t vnet_device_main
Definition: devices.c:22
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
Definition: defs.h:46
f64 link_state_poll_interval
Definition: dpdk.h:383
CLIB vectors are ubiquitous dynamically resized arrays with by user defined "headers".
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
dpdk_config_main_t * conf
Definition: dpdk.h:392
vlib_main_t * vlib_main
Definition: dpdk.h:390