dpdk plugin: blacklist PCI devices by type
[vpp.git] / src / plugins / dpdk / device / init.c
index d67540c..c0a927a 100644 (file)
@@ -206,9 +206,7 @@ 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)
-  return ! !(xd->port_conf.rxmode.hw_strip_crc);
-#elif RTE_VERSION < RTE_VERSION_NUM(18, 11, 0, 0)
+#if RTE_VERSION < RTE_VERSION_NUM(18, 11, 0, 0)
   return ! !(xd->port_conf.rxmode.offloads & DEV_RX_OFFLOAD_CRC_STRIP);
 #else
   return !(xd->port_conf.rxmode.offloads & DEV_RX_OFFLOAD_KEEP_CRC);
@@ -320,10 +318,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 +325,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)
        {
@@ -371,27 +373,15 @@ dpdk_lib_init (dpdk_main_t * dm)
 
       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;
        }
 
@@ -466,13 +456,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;
@@ -492,29 +477,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;
-#elif RTE_VERSION < RTE_VERSION_NUM(18, 11, 0, 0)
+#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;
-#elif RTE_VERSION < RTE_VERSION_NUM(18, 11, 0, 0)
+#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:
@@ -532,9 +516,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;
-#elif RTE_VERSION < RTE_VERSION_NUM(18, 11, 0, 0)
+#if RTE_VERSION < RTE_VERSION_NUM(18, 11, 0, 0)
              xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_CRC_STRIP;
 #endif
              break;
@@ -549,11 +531,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:
@@ -811,14 +789,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
@@ -854,6 +828,7 @@ dpdk_bind_devices_to_uio (dpdk_config_main_t * conf)
   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* */
@@ -882,11 +857,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 ||
@@ -1015,6 +1020,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))
        ;
@@ -1119,6 +1126,7 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
   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);
@@ -1195,6 +1203,17 @@ 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);
+       }
 
 #define _(a)                                    \
       else if (unformat(input, #a))             \
@@ -1811,10 +1830,10 @@ dpdk_init (vlib_main_t * vm)
   vec_add1 (dm->conf->eal_init_args, (u8 *) "vnet");
 
   /* 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;