examples: no more bare metal environment
[dpdk.git] / examples / vhost / main.c
index cc945f1..1e38453 100644 (file)
 /* mask of enabled ports */
 static uint32_t enabled_port_mask = 0;
 
+/* Promiscuous mode */
+static uint32_t promiscuous;
+
 /*Number of switching cores enabled*/
 static uint32_t num_switching_cores = 0;
 
 /* number of devices/queues to support*/
 static uint32_t num_queues = 0;
-uint32_t num_devices = 0;
+static uint32_t num_devices;
 
 /*
  * Enable zero copy, pkts buffer will directly dma to hw descriptor,
@@ -364,13 +367,15 @@ static inline int
 get_eth_conf(struct rte_eth_conf *eth_conf, uint32_t num_devices)
 {
        struct rte_eth_vmdq_rx_conf conf;
+       struct rte_eth_vmdq_rx_conf *def_conf =
+               &vmdq_conf_default.rx_adv_conf.vmdq_rx_conf;
        unsigned i;
 
        memset(&conf, 0, sizeof(conf));
        conf.nb_queue_pools = (enum rte_eth_nb_pools)num_devices;
        conf.nb_pool_maps = num_devices;
-       conf.enable_loop_back =
-               vmdq_conf_default.rx_adv_conf.vmdq_rx_conf.enable_loop_back;
+       conf.enable_loop_back = def_conf->enable_loop_back;
+       conf.rx_mode = def_conf->rx_mode;
 
        for (i = 0; i < conf.nb_pool_maps; i++) {
                conf.pool_map[i].vlan_id = vlan_tags[ i ];
@@ -468,6 +473,9 @@ port_init(uint8_t port)
                return retval;
        }
 
+       if (promiscuous)
+               rte_eth_promiscuous_enable(port);
+
        rte_eth_macaddr_get(port, &vmdq_ports_eth_addr[port]);
        RTE_LOG(INFO, VHOST_PORT, "Max virtio devices supported: %u\n", num_devices);
        RTE_LOG(INFO, VHOST_PORT, "Port %u MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8
@@ -598,7 +606,8 @@ us_vhost_parse_args(int argc, char **argv)
        };
 
        /* Parse command line */
-       while ((opt = getopt_long(argc, argv, "p:",long_option, &option_index)) != EOF) {
+       while ((opt = getopt_long(argc, argv, "p:P",
+                       long_option, &option_index)) != EOF) {
                switch (opt) {
                /* Portmask */
                case 'p':
@@ -610,6 +619,15 @@ us_vhost_parse_args(int argc, char **argv)
                        }
                        break;
 
+               case 'P':
+                       promiscuous = 1;
+                       vmdq_conf_default.rx_adv_conf.vmdq_rx_conf.rx_mode =
+                               ETH_VMDQ_ACCEPT_BROADCAST |
+                               ETH_VMDQ_ACCEPT_MULTICAST;
+                       rte_vhost_feature_enable(1ULL << VIRTIO_NET_F_CTRL_RX);
+
+                       break;
+
                case 0:
                        /* Enable/disable vm2vm comms. */
                        if (!strncmp(long_option[option_index].name, "vm2vm",
@@ -984,7 +1002,7 @@ unlink_vmdq(struct vhost_dev *vdev)
  * Check if the packet destination MAC address is for a local device. If so then put
  * the packet on that devices RX queue. If not then return.
  */
-static inline unsigned __attribute__((always_inline))
+static inline int __attribute__((always_inline))
 virtio_tx_local(struct vhost_dev *vdev, struct rte_mbuf *m)
 {
        struct virtio_net_data_ll *dev_ll;
@@ -1039,6 +1057,57 @@ virtio_tx_local(struct vhost_dev *vdev, struct rte_mbuf *m)
        return -1;
 }
 
+/*
+ * Check if the destination MAC of a packet is one local VM,
+ * and get its vlan tag, and offset if it is.
+ */
+static inline int __attribute__((always_inline))
+find_local_dest(struct virtio_net *dev, struct rte_mbuf *m,
+       uint32_t *offset, uint16_t *vlan_tag)
+{
+       struct virtio_net_data_ll *dev_ll = ll_root_used;
+       struct ether_hdr *pkt_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+
+       while (dev_ll != NULL) {
+               if ((dev_ll->vdev->ready == DEVICE_RX)
+                       && ether_addr_cmp(&(pkt_hdr->d_addr),
+               &dev_ll->vdev->mac_address)) {
+                       /*
+                        * Drop the packet if the TX packet is
+                        * destined for the TX device.
+                        */
+                       if (dev_ll->vdev->dev->device_fh == dev->device_fh) {
+                               LOG_DEBUG(VHOST_DATA,
+                               "(%"PRIu64") TX: Source and destination"
+                               " MAC addresses are the same. Dropping "
+                               "packet.\n",
+                               dev_ll->vdev->dev->device_fh);
+                               return -1;
+                       }
+
+                       /*
+                        * HW vlan strip will reduce the packet length
+                        * by minus length of vlan tag, so need restore
+                        * the packet length by plus it.
+                        */
+                       *offset = VLAN_HLEN;
+                       *vlan_tag =
+                       (uint16_t)
+                       vlan_tags[(uint16_t)dev_ll->vdev->dev->device_fh];
+
+                       LOG_DEBUG(VHOST_DATA,
+                       "(%"PRIu64") TX: pkt to local VM device id:"
+                       "(%"PRIu64") vlan tag: %d.\n",
+                       dev->device_fh, dev_ll->vdev->dev->device_fh,
+                       vlan_tag);
+
+                       break;
+               }
+               dev_ll = dev_ll->next;
+       }
+       return 0;
+}
+
 /*
  * This function routes the TX packet to the correct interface. This may be a local device
  * or the physical port.
@@ -1050,8 +1119,6 @@ virtio_tx_route(struct vhost_dev *vdev, struct rte_mbuf *m, uint16_t vlan_tag)
        struct rte_mbuf **m_table;
        unsigned len, ret, offset = 0;
        const uint16_t lcore_id = rte_lcore_id();
-       struct virtio_net_data_ll *dev_ll = ll_root_used;
-       struct ether_hdr *pkt_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
        struct virtio_net *dev = vdev->dev;
 
        /*check if destination is local VM*/
@@ -1061,37 +1128,10 @@ virtio_tx_route(struct vhost_dev *vdev, struct rte_mbuf *m, uint16_t vlan_tag)
        }
 
        if (vm2vm_mode == VM2VM_HARDWARE) {
-               while (dev_ll != NULL) {
-                       if ((dev_ll->vdev->ready == DEVICE_RX)
-                               && ether_addr_cmp(&(pkt_hdr->d_addr),
-                               &dev_ll->vdev->mac_address)) {
-                               /*
-                                * Drop the packet if the TX packet is
-                                * destined for the TX device.
-                                */
-                               if (dev_ll->vdev->dev->device_fh == dev->device_fh) {
-                                       LOG_DEBUG(VHOST_DATA,
-                                       "(%"PRIu64") TX: Source and destination"
-                                       " MAC addresses are the same. Dropping "
-                                       "packet.\n",
-                                       dev_ll->vdev->dev->device_fh);
-                                       rte_pktmbuf_free(m);
-                                       return;
-                               }
-                               offset = 4;
-                               vlan_tag =
-                               (uint16_t)
-                               vlan_tags[(uint16_t)dev_ll->vdev->dev->device_fh];
-
-                               LOG_DEBUG(VHOST_DATA,
-                               "(%"PRIu64") TX: pkt to local VM device id:"
-                               "(%"PRIu64") vlan tag: %d.\n",
-                               dev->device_fh, dev_ll->vdev->dev->device_fh,
-                               vlan_tag);
-
-                               break;
-                       }
-                       dev_ll = dev_ll->next;
+               if (find_local_dest(dev, m, &offset, &vlan_tag) != 0 ||
+                       offset > rte_pktmbuf_tailroom(m)) {
+                       rte_pktmbuf_free(m);
+                       return;
                }
        }
 
@@ -1102,8 +1142,10 @@ virtio_tx_route(struct vhost_dev *vdev, struct rte_mbuf *m, uint16_t vlan_tag)
        len = tx_q->len;
 
        m->ol_flags = PKT_TX_VLAN_PKT;
-       /*FIXME: offset*/
+
        m->data_len += offset;
+       m->pkt_len += offset;
+
        m->vlan_tci = vlan_tag;
 
        tx_q->m_table[len] = m;
@@ -1718,8 +1760,6 @@ virtio_tx_route_zcp(struct virtio_net *dev, struct rte_mbuf *m,
        struct rte_mbuf *mbuf = NULL;
        unsigned len, ret, offset = 0;
        struct vpool *vpool;
-       struct virtio_net_data_ll *dev_ll = ll_root_used;
-       struct ether_hdr *pkt_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
        uint16_t vlan_tag = (uint16_t)vlan_tags[(uint16_t)dev->device_fh];
        uint16_t vmdq_rx_q = ((struct vhost_dev *)dev->priv)->vmdq_rx_q;
 
@@ -1748,46 +1788,10 @@ virtio_tx_route_zcp(struct virtio_net *dev, struct rte_mbuf *m,
                 * such a ambiguous situation, so pkt will lost.
                 */
                vlan_tag = external_pkt_default_vlan_tag;
-               while (dev_ll != NULL) {
-                       if (likely(dev_ll->vdev->ready == DEVICE_RX) &&
-                               ether_addr_cmp(&(pkt_hdr->d_addr),
-                               &dev_ll->vdev->mac_address)) {
-
-                               /*
-                                * Drop the packet if the TX packet is destined
-                                * for the TX device.
-                                */
-                               if (unlikely(dev_ll->vdev->dev->device_fh
-                                       == dev->device_fh)) {
-                                       LOG_DEBUG(VHOST_DATA,
-                                       "(%"PRIu64") TX: Source and destination"
-                                       "MAC addresses are the same. Dropping "
-                                       "packet.\n",
-                                       dev_ll->vdev->dev->device_fh);
-                                       MBUF_HEADROOM_UINT32(mbuf)
-                                               = (uint32_t)desc_idx;
-                                       __rte_mbuf_raw_free(mbuf);
-                                       return;
-                               }
-
-                               /*
-                                * Packet length offset 4 bytes for HW vlan
-                                * strip when L2 switch back.
-                                */
-                               offset = 4;
-                               vlan_tag =
-                               (uint16_t)
-                               vlan_tags[(uint16_t)dev_ll->vdev->dev->device_fh];
-
-                               LOG_DEBUG(VHOST_DATA,
-                               "(%"PRIu64") TX: pkt to local VM device id:"
-                               "(%"PRIu64") vlan tag: %d.\n",
-                               dev->device_fh, dev_ll->vdev->dev->device_fh,
-                               vlan_tag);
-
-                               break;
-                       }
-                       dev_ll = dev_ll->next;
+               if (find_local_dest(dev, m, &offset, &vlan_tag) != 0) {
+                       MBUF_HEADROOM_UINT32(mbuf) = (uint32_t)desc_idx;
+                       __rte_mbuf_raw_free(mbuf);
+                       return;
                }
        }
 
@@ -1911,7 +1915,9 @@ virtio_dev_tx_zcp(struct virtio_net *dev)
 
                /* Buffer address translation. */
                buff_addr = gpa_to_vva(dev, desc->addr);
-               phys_addr = gpa_to_hpa(vdev, desc->addr, desc->len, &addr_type);
+               /* Need check extra VLAN_HLEN size for inserting VLAN tag */
+               phys_addr = gpa_to_hpa(vdev, desc->addr, desc->len + VLAN_HLEN,
+                       &addr_type);
 
                if (likely(packet_success < (free_entries - 1)))
                        /* Prefetch descriptor index. */
@@ -2702,8 +2708,7 @@ new_device (struct virtio_net *dev)
                }
        }
        /* Add device to lcore ll */
-       ll_dev->dev->coreid = core_add;
-       ll_dev = get_data_ll_free_entry(&lcore_info[ll_dev->dev->coreid].lcore_ll->ll_root_free);
+       ll_dev = get_data_ll_free_entry(&lcore_info[core_add].lcore_ll->ll_root_free);
        if (ll_dev == NULL) {
                RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") Failed to add device to data core\n", dev->device_fh);
                vdev->ready = DEVICE_SAFE_REMOVE;
@@ -2716,7 +2721,7 @@ new_device (struct virtio_net *dev)
        ll_dev->vdev = vdev;
        vdev->coreid = core_add;
 
-       add_data_ll_entry(&lcore_info[ll_dev->dev->coreid].lcore_ll->ll_root_used, ll_dev);
+       add_data_ll_entry(&lcore_info[vdev->coreid].lcore_ll->ll_root_used, ll_dev);
 
        /* Initialize device stats */
        memset(&dev_statistics[dev->device_fh], 0, sizeof(struct device_statistics));
@@ -2844,7 +2849,7 @@ setup_mempool_tbl(int socket, uint32_t index, char *pool_name,
  * device is also registered here to handle the IOCTLs.
  */
 int
-MAIN(int argc, char *argv[])
+main(int argc, char *argv[])
 {
        struct rte_mempool *mbuf_pool = NULL;
        unsigned lcore_id, core_id = 0;
@@ -2864,13 +2869,6 @@ MAIN(int argc, char *argv[])
        ret = us_vhost_parse_args(argc, argv);
        if (ret < 0)
                rte_exit(EXIT_FAILURE, "Invalid argument\n");
-#ifdef RTE_IXGBE_INC_VECTOR
-       if (mergeable == 1) {
-               rte_exit(EXIT_FAILURE,
-                       "sorry, mergeable feature doesn't work with vec sg recv, " \
-                       "please disable it in cfg as a workaround\n");
-       }
-#endif
 
        for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id ++)
                if (rte_lcore_is_enabled(lcore_id))
@@ -3022,10 +3020,10 @@ MAIN(int argc, char *argv[])
                        }
 
                        LOG_DEBUG(VHOST_CONFIG,
-                               "in MAIN: mbuf count in mempool at initial "
+                               "in main: mbuf count in mempool at initial "
                                "is: %d\n", count_in_mempool);
                        LOG_DEBUG(VHOST_CONFIG,
-                               "in MAIN: mbuf count in  ring at initial  is :"
+                               "in main: mbuf count in  ring at initial  is :"
                                " %d\n",
                                rte_ring_count(vpool_array[index].ring));
                }