/* Check for decapsulation and pass packets directly to VIRTIO device */ int vxlan_rx_pkts(struct virtio_net *dev, struct rte_mbuf **pkts_burst, uint32_t rx_count) { uint32_t i = 0; uint32_t count = 0; int ret; struct rte_mbuf *pkts_valid[rx_count]; for (i = 0; i < rx_count; i++) { if (enable_stats) { rte_atomic64_add( &dev_statistics[dev->device_fh].rx_bad_ip_csum, (pkts_burst[i]->ol_flags & PKT_RX_IP_CKSUM_BAD) != 0); rte_atomic64_add( &dev_statistics[dev->device_fh].rx_bad_ip_csum, (pkts_burst[i]->ol_flags & PKT_RX_L4_CKSUM_BAD) != 0); } ret = vxlan_rx_process(pkts_burst[i]); if (unlikely(ret < 0)) continue; pkts_valid[count] = pkts_burst[i]; count++; } ret = rte_vhost_enqueue_burst(dev, VIRTIO_RXQ, pkts_valid, count); return ret; }
/* functional description: layer-2 decapsulate to decide which mod should recv it, input mod:any output mod: RX_MOD_ARP RX_MOD_IP RX_MOD_IPv6 RX_MOD_DROP:we do not deal with other kind of pkt mod stack pos:first module date :2014-05-10 author:jzheng */ dbg_local enum RX_MOD_INDEX rx_module_l2decap(dbg_local struct rte_mbuf* pktbuf,dbg_local enum RX_MOD_INDEX imodid) { enum RX_MOD_INDEX nextmodid=RX_MOD_DROP;//default mod is droping struct ether_hdr*eh; uint16_t eth_type; int iport_in;//for RX statistic iport_in=pktbuf->pkt.in_port; rte_atomic64_inc(&gPortParaConf[iport_in].sd_port.ui_cnt_rx); rte_atomic64_add(&gPortParaConf[iport_in].sd_port.ui_byte_rx,pktbuf->pkt.pkt_len-sizeof(struct ether_hdr)); rte_atomic64_add(&gPortParaConf[iport_in].sd_port.ui_cnt_timer_rx,pktbuf->pkt.pkt_len-sizeof(struct ether_hdr)); eh=rte_pktmbuf_mtod(pktbuf,struct ether_hdr*); eth_type=HTONS(eh->ether_type); if(eth_type==ETH_TYPE_ARP) nextmodid=RX_MOD_ARP; else if(eth_type==ETH_TYPE_IP) nextmodid=RX_MOD_IP; else if(eth_type==ETH_TYPE_IPV6) nextmodid=RX_MOD_IPv6; else nextmodid=RX_MOD_DROP; //printf("flag:%d %04x\n",nextmodid,eth_type); return nextmodid; }
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; }