virtio_tx_local(struct virtio_net *dev, struct rte_mbuf *m) { struct virtio_net_data_ll *dev_ll; struct ether_hdr *pkt_hdr; uint64_t ret = 0; pkt_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *); /*get the used devices list*/ dev_ll = ll_root_used; while (dev_ll != NULL) { if (likely(dev_ll->dev->ready == DEVICE_READY) && ether_addr_cmp(&(pkt_hdr->d_addr), &dev_ll->dev->mac_address)) { /* Drop the packet if the TX packet is destined for the TX device. */ if (dev_ll->dev->device_fh == dev->device_fh) { RTE_LOG(DEBUG, VHOST_DATA, "(%" PRIu64 ") TX: " "Source and destination MAC addresses are the same. " "Dropping packet.\n", dev_ll->dev->device_fh); return 0; } RTE_LOG(DEBUG, VHOST_DATA, "(%" PRIu64 ") TX: " "MAC address is local\n", dev_ll->dev->device_fh); if (dev_ll->dev->remove) { /*drop the packet if the device is marked for removal*/ RTE_LOG(DEBUG, VHOST_DATA, "(%" PRIu64 ") " "Device is marked for removal\n", dev_ll->dev->device_fh); } else { /*send the packet to the local virtio device*/ ret = virtio_dev_rx(dev_ll->dev, &m, 1); if (enable_stats) { rte_atomic64_add(&dev_statistics[dev_ll->dev->device_fh].rx_total, 1); rte_atomic64_add(&dev_statistics[dev_ll->dev->device_fh].rx, ret); dev_statistics[dev->device_fh].tx_total++; dev_statistics[dev->device_fh].tx += ret; } } return 0; } dev_ll = dev_ll->next; } return -1; }
/* * This function registers mac along with a * vlan tag to a VMDQ. */ static int link_vmdq(struct virtio_net *dev) { int ret; struct virtio_net_data_ll *dev_ll; dev_ll = ll_root_used; while (dev_ll != NULL) { if ((dev != dev_ll->dev) && ether_addr_cmp(&dev->mac_address, &dev_ll->dev->mac_address)) { RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") WARNING: This device is using an existing MAC address and has not been registered.\n", dev->device_fh); return -1; } dev_ll = dev_ll->next; } /* vlan_tag currently uses the device_id. */ dev->vlan_tag = vlan_tags[dev->device_fh]; dev->vmdq_rx_q = dev->device_fh * (num_queues/num_devices); /* Print out VMDQ registration info. */ RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") MAC_ADDRESS %02x:%02x:%02x:%02x:%02x:%02x and VLAN_TAG %d registered\n", dev->device_fh, dev->mac_address.addr_bytes[0], dev->mac_address.addr_bytes[1], dev->mac_address.addr_bytes[2], dev->mac_address.addr_bytes[3], dev->mac_address.addr_bytes[4], dev->mac_address.addr_bytes[5], dev->vlan_tag); /* Register the MAC address. */ ret = rte_eth_dev_mac_addr_add(ports[0], &dev->mac_address, (uint32_t)dev->device_fh); if (ret) { RTE_LOG(ERR, VHOST_DATA, "(%"PRIu64") Failed to add device MAC address to VMDQ\n", dev->device_fh); return -1; } /* Enable stripping of the vlan tag as we handle routing. */ rte_eth_dev_set_vlan_strip_on_queue(ports[0], dev->vmdq_rx_q, 1); rte_compiler_barrier(); /* Set device as ready for RX. */ dev->ready = DEVICE_READY; return 0; }