dpdk: switch to in-memory mode, deprecate use of socket-mem
[vpp.git] / src / plugins / dpdk / device / init.c
index dd2b405..df1a823 100644 (file)
@@ -24,6 +24,7 @@
 #include <vnet/ethernet/ethernet.h>
 #include <dpdk/device/dpdk.h>
 #include <vlib/pci/pci.h>
+#include <vlib/vmbus/vmbus.h>
 
 #include <rte_ring.h>
 
@@ -145,7 +146,7 @@ dpdk_device_lock_init (dpdk_device_t * xd)
     {
       xd->lockp[q] = clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES,
                                             CLIB_CACHE_LINE_BYTES);
-      memset ((void *) xd->lockp[q], 0, CLIB_CACHE_LINE_BYTES);
+      clib_memset ((void *) xd->lockp[q], 0, CLIB_CACHE_LINE_BYTES);
     }
 }
 
@@ -206,13 +207,11 @@ dpdk_ring_alloc (struct rte_mempool *mp)
 static int
 dpdk_port_crc_strip_enabled (dpdk_device_t * xd)
 {
-#if RTE_VERSION < RTE_VERSION_NUM(18, 8, 0, 0)
-  if (xd->port_conf.rxmode.hw_strip_crc)
+#if RTE_VERSION < RTE_VERSION_NUM(18, 11, 0, 0)
+  return ! !(xd->port_conf.rxmode.offloads & DEV_RX_OFFLOAD_CRC_STRIP);
 #else
-  if (xd->port_conf.rxmode.offloads & DEV_RX_OFFLOAD_CRC_STRIP)
+  return !(xd->port_conf.rxmode.offloads & DEV_RX_OFFLOAD_KEEP_CRC);
 #endif
-    return 1;
-  return 0;
 }
 
 static clib_error_t *
@@ -320,10 +319,6 @@ dpdk_lib_init (dpdk_main_t * dm)
                        pci_addr.as_u32);
        }
 
-      if (p)
-       devconf = pool_elt_at_index (dm->conf->dev_confs, p[0]);
-      else
-       devconf = &dm->conf->default_devconf;
 
       /* Create vnet interface */
       vec_add2_aligned (dm->devices, xd, 1, CLIB_CACHE_LINE_BYTES);
@@ -331,6 +326,14 @@ dpdk_lib_init (dpdk_main_t * dm)
       xd->nb_tx_desc = DPDK_NB_TX_DESC_DEFAULT;
       xd->cpu_socket = (i8) rte_eth_dev_socket_id (i);
 
+      if (p)
+       {
+         devconf = pool_elt_at_index (dm->conf->dev_confs, p[0]);
+         xd->name = devconf->name;
+       }
+      else
+       devconf = &dm->conf->default_devconf;
+
       /* Handle interface naming for devices with multiple ports sharing same PCI ID */
       if (pci_dev)
        {
@@ -363,29 +366,23 @@ dpdk_lib_init (dpdk_main_t * dm)
       clib_memcpy (&xd->tx_conf, &dev_info.default_txconf,
                   sizeof (struct rte_eth_txconf));
 
+      if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_IPV4_CKSUM)
+       {
+         xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_IPV4_CKSUM;
+         xd->flags |= DPDK_DEVICE_FLAG_RX_IP4_CKSUM;
+       }
+
       if (dm->conf->no_multi_seg)
        {
-#if RTE_VERSION < RTE_VERSION_NUM(18, 8, 0, 0)
-         xd->tx_conf.txq_flags |= ETH_TXQ_FLAGS_NOMULTSEGS;
-         xd->port_conf.rxmode.jumbo_frame = 0;
-         xd->port_conf.rxmode.enable_scatter = 0;
-#else
          xd->port_conf.txmode.offloads &= ~DEV_TX_OFFLOAD_MULTI_SEGS;
          xd->port_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_JUMBO_FRAME;
          xd->port_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_SCATTER;
-#endif
        }
       else
        {
-#if RTE_VERSION < RTE_VERSION_NUM(18, 8, 0, 0)
-         xd->tx_conf.txq_flags &= ~ETH_TXQ_FLAGS_NOMULTSEGS;
-         xd->port_conf.rxmode.jumbo_frame = 1;
-         xd->port_conf.rxmode.enable_scatter = 1;
-#else
          xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_MULTI_SEGS;
          xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME;
          xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_SCATTER;
-#endif
          xd->flags |= DPDK_DEVICE_FLAG_MAYBE_MULTISEG;
        }
 
@@ -460,13 +457,8 @@ dpdk_lib_init (dpdk_main_t * dm)
 
              if (dm->conf->no_tx_checksum_offload == 0)
                {
-#if RTE_VERSION < RTE_VERSION_NUM(18, 8, 0, 0)
-                 xd->tx_conf.txq_flags &= ~(ETH_TXQ_FLAGS_NOXSUMUDP |
-                                                    ETH_TXQ_FLAGS_NOXSUMTCP);
-#else
                  xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_CKSUM;
                  xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_UDP_CKSUM;
-#endif
                  xd->flags |=
                    DPDK_DEVICE_FLAG_TX_OFFLOAD |
                    DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM;
@@ -486,29 +478,28 @@ dpdk_lib_init (dpdk_main_t * dm)
            case VNET_DPDK_PMD_IXGBEVF:
            case VNET_DPDK_PMD_I40EVF:
              xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF;
-#if RTE_VERSION < RTE_VERSION_NUM(18, 8, 0, 0)
-             xd->port_conf.rxmode.hw_strip_crc = 1;
-#else
+#if RTE_VERSION < RTE_VERSION_NUM(18, 11, 0, 0)
              xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
 #endif
              break;
 
            case VNET_DPDK_PMD_THUNDERX:
              xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF;
-#if RTE_VERSION < RTE_VERSION_NUM(18, 8, 0, 0)
-             xd->port_conf.rxmode.hw_strip_crc = 1;
-#else
+#if RTE_VERSION < RTE_VERSION_NUM(18, 11, 0, 0)
              xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
 #endif
+
+             if (dm->conf->no_tx_checksum_offload == 0)
+               {
+                 xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_CKSUM;
+                 xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_UDP_CKSUM;
+                 xd->flags |= DPDK_DEVICE_FLAG_TX_OFFLOAD;
+               }
              break;
 
            case VNET_DPDK_PMD_ENA:
              xd->port_type = VNET_DPDK_PORT_TYPE_ETH_VF;
-#if RTE_VERSION < RTE_VERSION_NUM(18, 8, 0, 0)
-             xd->port_conf.rxmode.enable_scatter = 0;
-#else
              xd->port_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_SCATTER;
-#endif
              break;
 
            case VNET_DPDK_PMD_DPAA2:
@@ -526,9 +517,7 @@ dpdk_lib_init (dpdk_main_t * dm)
              /* Intel Red Rock Canyon */
            case VNET_DPDK_PMD_FM10K:
              xd->port_type = VNET_DPDK_PORT_TYPE_ETH_SWITCH;
-#if RTE_VERSION < RTE_VERSION_NUM(18, 8, 0, 0)
-             xd->port_conf.rxmode.hw_strip_crc = 1;
-#else
+#if RTE_VERSION < RTE_VERSION_NUM(18, 11, 0, 0)
              xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
 #endif
              break;
@@ -543,11 +532,7 @@ dpdk_lib_init (dpdk_main_t * dm)
              /* vmxnet3 */
            case VNET_DPDK_PMD_VMXNET3:
              xd->port_type = VNET_DPDK_PORT_TYPE_ETH_1G;
-#if RTE_VERSION < RTE_VERSION_NUM(18, 8, 0, 0)
-             xd->tx_conf.txq_flags |= ETH_TXQ_FLAGS_NOMULTSEGS;
-#else
              xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_MULTI_SEGS;
-#endif
              break;
 
            case VNET_DPDK_PMD_AF_PACKET:
@@ -805,14 +790,10 @@ dpdk_lib_init (dpdk_main_t * dm)
          int vlan_off;
          vlan_off = rte_eth_dev_get_vlan_offload (xd->port_id);
          vlan_off |= ETH_VLAN_STRIP_OFFLOAD;
-#if RTE_VERSION < RTE_VERSION_NUM(18, 8, 0, 0)
-         xd->port_conf.rxmode.hw_vlan_strip = vlan_off;
-#else
           if (vlan_off)
            xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_VLAN_STRIP;
          else
            xd->port_conf.rxmode.offloads &= ~DEV_RX_OFFLOAD_VLAN_STRIP;
-#endif
          if (rte_eth_dev_set_vlan_offload (xd->port_id, vlan_off) == 0)
            dpdk_log_info ("VLAN strip enabled for interface\n");
          else
@@ -842,11 +823,13 @@ dpdk_lib_init (dpdk_main_t * dm)
 static void
 dpdk_bind_devices_to_uio (dpdk_config_main_t * conf)
 {
+  vlib_main_t *vm = vlib_get_main ();
   clib_error_t *error;
   u8 *pci_addr = 0;
   int num_whitelisted = vec_len (conf->dev_confs);
   vlib_pci_device_info_t *d = 0;
   vlib_pci_addr_t *addr = 0, *addrs;
+  int i;
 
   addrs = vlib_pci_get_all_dev_addrs ();
   /* *INDENT-OFF* */
@@ -860,7 +843,7 @@ dpdk_bind_devices_to_uio (dpdk_config_main_t * conf)
       vlib_pci_free_device_info (d);
       d = 0;
       }
-    d = vlib_pci_get_device_info (addr, &error);
+    d = vlib_pci_get_device_info (vm, addr, &error);
     if (error)
     {
       clib_error_report (error);
@@ -875,11 +858,41 @@ dpdk_bind_devices_to_uio (dpdk_config_main_t * conf)
        uword * p = hash_get (conf->device_config_index_by_pci_addr, addr->as_u32);
 
        if (!p)
-         continue;
+          {
+          skipped:
+            continue;
+          }
 
        devconf = pool_elt_at_index (conf->dev_confs, p[0]);
       }
 
+    /* Enforce Device blacklist by vendor and device */
+    for (i = 0; i < vec_len (conf->blacklist_by_pci_vendor_and_device); i++)
+      {
+        u16 vendor, device;
+        vendor = (u16)(conf->blacklist_by_pci_vendor_and_device[i] >> 16);
+        device = (u16)(conf->blacklist_by_pci_vendor_and_device[i] & 0xFFFF);
+        if (d->vendor_id == vendor && d->device_id == device)
+          {
+            /*
+             * Expected case: device isn't whitelisted,
+             * so blacklist it...
+             */
+            if (devconf == 0)
+              {
+                /* Device is blacklisted */
+                pool_get (conf->dev_confs, devconf);
+                hash_set (conf->device_config_index_by_pci_addr, addr->as_u32,
+                          devconf - conf->dev_confs);
+                devconf->pci_addr.as_u32 = addr->as_u32;
+                devconf->is_blacklisted = 1;
+                goto skipped;
+              }
+            else /* explicitly whitelisted, ignore the device blacklist  */
+              break;
+          }
+      }
+
     /* virtio */
     if (d->vendor_id == 0x1af4 &&
             (d->device_id == VIRTIO_PCI_LEGACY_DEVICEID_NET ||
@@ -887,7 +900,20 @@ dpdk_bind_devices_to_uio (dpdk_config_main_t * conf)
       ;
     /* vmxnet3 */
     else if (d->vendor_id == 0x15ad && d->device_id == 0x07b0)
-      ;
+      {
+       /*
+        * For vmxnet3 PCI, unless it is explicitly specified in the whitelist,
+        * the default is to put it in the blacklist.
+        */
+       if (devconf == 0)
+         {
+           pool_get (conf->dev_confs, devconf);
+           hash_set (conf->device_config_index_by_pci_addr, addr->as_u32,
+                     devconf - conf->dev_confs);
+           devconf->pci_addr.as_u32 = addr->as_u32;
+           devconf->is_blacklisted = 1;
+         }
+      }
     /* all Intel network devices */
     else if (d->vendor_id == 0x8086 && d->device_class == PCI_CLASS_NETWORK_ETHERNET)
       ;
@@ -928,7 +954,7 @@ dpdk_bind_devices_to_uio (dpdk_config_main_t * conf)
         continue;
       }
 
-    error = vlib_pci_bind_to_uio (addr, (char *) conf->uio_driver_name);
+    error = vlib_pci_bind_to_uio (vm, addr, (char *) conf->uio_driver_name);
 
     if (error)
       {
@@ -948,6 +974,27 @@ dpdk_bind_devices_to_uio (dpdk_config_main_t * conf)
   vlib_pci_free_device_info (d);
 }
 
+static void
+dpdk_bind_vmbus_devices_to_uio (dpdk_config_main_t * conf)
+{
+  clib_error_t *error;
+  vlib_vmbus_addr_t *addrs, *addr = 0;
+
+  addrs = vlib_vmbus_get_all_dev_addrs ();
+
+  /* *INDENT-OFF* */
+  vec_foreach (addr, addrs)
+    {
+      error = vlib_vmbus_bind_to_uio (addr);
+
+      if (error)
+       {
+         clib_error_report (error);
+       }
+    }
+  /* *INDENT-ON* */
+}
+
 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)
@@ -995,6 +1042,8 @@ dpdk_device_config (dpdk_config_main_t * conf, vlib_pci_addr_t pci_addr,
        ;
       else if (unformat (input, "num-tx-desc %u", &devconf->num_tx_desc))
        ;
+      else if (unformat (input, "name %s", &devconf->name))
+       ;
       else if (unformat (input, "workers %U", unformat_bitmap_list,
                         &devconf->workers))
        ;
@@ -1088,17 +1137,17 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
   dpdk_device_config_t *devconf;
   vlib_pci_addr_t pci_addr;
   unformat_input_t sub_input;
-  uword x;
+  uword default_hugepage_sz, x;
   u8 *s, *tmp = 0;
   u32 log_level;
   int ret, i;
   int num_whitelisted = 0;
   u8 no_pci = 0;
-  u8 no_huge = 0;
-  u8 huge_dir = 0;
+  u8 no_vmbus = 0;
   u8 file_prefix = 0;
   u8 *socket_mem = 0;
   u8 *huge_dir_path = 0;
+  u32 vendor, device;
 
   huge_dir_path =
     format (0, "%s/hugepages%c", vlib_unix_get_runtime_dir (), 0);
@@ -1112,7 +1161,6 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
       if (unformat (input, "no-hugetlb"))
        {
          vec_add1 (conf->eal_init_args, (u8 *) "--no-huge");
-         no_huge = 1;
        }
 
       else if (unformat (input, "enable-tcp-udp-checksum"))
@@ -1175,6 +1223,23 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
          tmp = format (0, "--no-pci%c", 0);
          vec_add1 (conf->eal_init_args, tmp);
        }
+      else if (unformat (input, "blacklist %x:%x", &vendor, &device))
+       {
+         u32 blacklist_entry;
+         if (vendor > 0xFFFF)
+           return clib_error_return (0, "blacklist PCI vendor out of range");
+         if (device > 0xFFFF)
+           return clib_error_return (0, "blacklist PCI device out of range");
+         blacklist_entry = (vendor << 16) | (device & 0xffff);
+         vec_add1 (conf->blacklist_by_pci_vendor_and_device,
+                   blacklist_entry);
+       }
+      else if (unformat (input, "no-vmbus"))
+       {
+         no_vmbus = 1;
+         tmp = format (0, "--no-vmbus%c", 0);
+         vec_add1 (conf->eal_init_args, tmp);
+       }
 
 #define _(a)                                    \
       else if (unformat(input, #a))             \
@@ -1187,9 +1252,7 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
 #define _(a)                                          \
        else if (unformat(input, #a " %s", &s))       \
          {                                           \
-            if (!strncmp(#a, "huge-dir", 8))          \
-              huge_dir = 1;                           \
-            else if (!strncmp(#a, "file-prefix", 11)) \
+            if (!strncmp(#a, "file-prefix", 11)) \
               file_prefix = 1;                        \
            tmp = format (0, "--%s%c", #a, 0);        \
            vec_add1 (conf->eal_init_args, tmp);      \
@@ -1238,104 +1301,29 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
   if (!conf->uio_driver_name)
     conf->uio_driver_name = format (0, "auto%c", 0);
 
-  /*
-   * Use 1G huge pages if available.
-   */
-  if (!no_huge && !huge_dir)
-    {
-      u32 x, *mem_by_socket = 0;
-      uword c = 0;
-      int rv;
-
-      umount ((char *) huge_dir_path);
-
-      /* Process "socket-mem" parameter value */
-      if (vec_len (socket_mem))
-       {
-         unformat_input_t in;
-         unformat_init_vector (&in, socket_mem);
-         while (unformat_check_input (&in) != UNFORMAT_END_OF_INPUT)
-           {
-             if (unformat (&in, "%u,", &x))
-               ;
-             else if (unformat (&in, "%u", &x))
-               ;
-             else if (unformat (&in, ","))
-               x = 0;
-             else
-               break;
-
-             vec_add1 (mem_by_socket, x);
-           }
-         /* Note: unformat_free vec_frees(in.buffer), aka socket_mem... */
-         unformat_free (&in);
-         socket_mem = 0;
-       }
-      else
-       {
-         /* *INDENT-OFF* */
-         clib_bitmap_foreach (c, tm->cpu_socket_bitmap, (
-           {
-             vec_validate(mem_by_socket, c);
-             mem_by_socket[c] = 64; /* default per-socket mem */
-           }
-         ));
-         /* *INDENT-ON* */
-       }
-
-      /* *INDENT-OFF* */
-      clib_bitmap_foreach (c, tm->cpu_socket_bitmap, (
-        {
-         clib_error_t *e;
+  default_hugepage_sz = clib_mem_get_default_hugepage_size ();
 
-         vec_validate(mem_by_socket, c);
-
-         e = clib_sysfs_prealloc_hugepages(c, 2 << 10, mem_by_socket[c] / 2);
-         if (e)
-           clib_error_report (e);
-      }));
-      /* *INDENT-ON* */
-
-      if (mem_by_socket == 0)
-       {
-         error = clib_error_return (0, "mem_by_socket NULL");
-         goto done;
-       }
-      _vec_len (mem_by_socket) = c + 1;
-
-      /* regenerate socket_mem string */
-      vec_foreach_index (x, mem_by_socket)
-       socket_mem = format (socket_mem, "%s%u",
-                            socket_mem ? "," : "", mem_by_socket[x]);
-      socket_mem = format (socket_mem, "%c", 0);
-
-      vec_free (mem_by_socket);
-
-      error = vlib_unix_recursive_mkdir ((char *) huge_dir_path);
-      if (error)
-       {
-         goto done;
-       }
-
-      rv = mount ("none", (char *) huge_dir_path, "hugetlbfs", 0, NULL);
-
-      if (rv)
-       {
-         error = clib_error_return (0, "mount failed %d", errno);
-         goto done;
-       }
+  /* *INDENT-OFF* */
+  clib_bitmap_foreach (x, tm->cpu_socket_bitmap, (
+    {
+      clib_error_t *e;
+      uword n_pages;
+      /* preallocate at least 16MB of hugepages per socket,
+        if more is needed it is up to consumer to preallocate more */
+      n_pages = round_pow2 ((uword) 16 << 20, default_hugepage_sz);
+      n_pages /= default_hugepage_sz;
+
+      if ((e = clib_sysfs_prealloc_hugepages(x, 0, n_pages)))
+       clib_error_report (e);
+  }));
+  /* *INDENT-ON* */
 
-      tmp = format (0, "--huge-dir%c", 0);
+  if (!file_prefix)
+    {
+      tmp = format (0, "--file-prefix%c", 0);
       vec_add1 (conf->eal_init_args, tmp);
-      tmp = format (0, "%s%c", huge_dir_path, 0);
+      tmp = format (0, "vpp%c", 0);
       vec_add1 (conf->eal_init_args, tmp);
-      if (!file_prefix)
-       {
-         tmp = format (0, "--file-prefix%c", 0);
-         vec_add1 (conf->eal_init_args, tmp);
-         tmp = format (0, "vpp%c", 0);
-         vec_add1 (conf->eal_init_args, tmp);
-       }
     }
 
   if (error)
@@ -1375,6 +1363,9 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
   if (no_pci == 0 && geteuid () == 0)
     dpdk_bind_devices_to_uio (conf);
 
+  if (no_vmbus == 0 && geteuid () == 0)
+    dpdk_bind_vmbus_devices_to_uio (conf);
+
 #define _(x) \
     if (devconf->x == 0 && conf->default_devconf.x > 0) \
       devconf->x = conf->default_devconf.x ;
@@ -1411,14 +1402,9 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
   tmp = format (0, "%u%c", tm->main_lcore, 0);
   vec_add1 (conf->eal_init_args, tmp);
 
-  /* set socket-mem */
-  if (!no_huge)
-    {
-      tmp = format (0, "--socket-mem%c", 0);
-      vec_add1 (conf->eal_init_args, tmp);
-      tmp = format (0, "%s%c", socket_mem, 0);
-      vec_add1 (conf->eal_init_args, tmp);
-    }
+
+  if (socket_mem)
+    clib_warning ("socket-mem argument is deprecated");
 
   /* NULL terminate the "argv" vector, in case of stupidity */
   vec_add1 (conf->eal_init_args, 0);
@@ -1517,7 +1503,7 @@ dpdk_update_link_state (dpdk_device_t * xd, f64 now)
     return;
 
   xd->time_last_link_update = now ? now : xd->time_last_link_update;
-  memset (&xd->link, 0, sizeof (xd->link));
+  clib_memset (&xd->link, 0, sizeof (xd->link));
   rte_eth_link_get_nowait (xd->port_id, &xd->link);
 
   if (LINK_STATE_ELOGS)
@@ -1567,54 +1553,10 @@ dpdk_update_link_state (dpdk_device_t * xd, f64 now)
          break;
        }
     }
-  if (hw_flags_chg || (xd->link.link_speed != prev_link.link_speed))
-    {
-      hw_flags_chg = 1;
-      switch (xd->link.link_speed)
-       {
-       case ETH_SPEED_NUM_10M:
-         hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_10M;
-         break;
-       case ETH_SPEED_NUM_100M:
-         hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_100M;
-         break;
-       case ETH_SPEED_NUM_1G:
-         hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_1G;
-         break;
-       case ETH_SPEED_NUM_2_5G:
-         hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_2_5G;
-         break;
-       case ETH_SPEED_NUM_5G:
-         hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_5G;
-         break;
-       case ETH_SPEED_NUM_10G:
-         hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_10G;
-         break;
-       case ETH_SPEED_NUM_20G:
-         hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_20G;
-         break;
-       case ETH_SPEED_NUM_25G:
-         hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_25G;
-         break;
-       case ETH_SPEED_NUM_40G:
-         hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_40G;
-         break;
-       case ETH_SPEED_NUM_50G:
-         hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_50G;
-         break;
-       case ETH_SPEED_NUM_56G:
-         hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_56G;
-         break;
-       case ETH_SPEED_NUM_100G:
-         hw_flags |= VNET_HW_INTERFACE_FLAG_SPEED_100G;
-         break;
-       case 0:
-         break;
-       default:
-         dpdk_log_warn ("unknown link speed %d", xd->link.link_speed);
-         break;
-       }
-    }
+  if (xd->link.link_speed != prev_link.link_speed)
+    vnet_hw_interface_set_link_speed (vnm, xd->hw_if_index,
+                                     xd->link.link_speed * 1000);
+
   if (hw_flags_chg)
     {
       if (LINK_STATE_ELOGS)
@@ -1830,12 +1772,13 @@ dpdk_init (vlib_main_t * vm)
   dm->conf->nchannels = 4;
   dm->conf->num_mbufs = dm->conf->num_mbufs ? dm->conf->num_mbufs : NB_MBUF;
   vec_add1 (dm->conf->eal_init_args, (u8 *) "vnet");
+  vec_add1 (dm->conf->eal_init_args, (u8 *) "--in-memory");
 
   /* Default vlib_buffer_t flags, DISABLES tcp/udp checksumming... */
-  dm->buffer_flags_template =
-    (VLIB_BUFFER_TOTAL_LENGTH_VALID | VLIB_BUFFER_EXT_HDR_VALID
-     | VNET_BUFFER_F_L4_CHECKSUM_COMPUTED |
-     VNET_BUFFER_F_L4_CHECKSUM_CORRECT | VNET_BUFFER_F_L2_HDR_OFFSET_VALID);
+  dm->buffer_flags_template = (VLIB_BUFFER_TOTAL_LENGTH_VALID |
+                              VLIB_BUFFER_EXT_HDR_VALID |
+                              VNET_BUFFER_F_L4_CHECKSUM_COMPUTED |
+                              VNET_BUFFER_F_L4_CHECKSUM_CORRECT);
 
   dm->stat_poll_interval = DPDK_STATS_POLL_INTERVAL;
   dm->link_state_poll_interval = DPDK_LINK_POLL_INTERVAL;