* 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. */
| 1119 | * the packet on that devices RX queue. If not then return. |
| 1120 | */ |
| 1121 | static __rte_always_inline int |
| 1122 | virtio_tx_local(struct vhost_dev *vdev, struct rte_mbuf *m) |
| 1123 | { |
| 1124 | struct rte_ether_hdr *pkt_hdr; |
| 1125 | struct vhost_dev *dst_vdev; |
| 1126 | struct vhost_bufftable *vhost_txq; |
| 1127 | uint16_t lcore_id = rte_lcore_id(); |
| 1128 | pkt_hdr = rte_pktmbuf_mtod(m, struct rte_ether_hdr *); |
| 1129 | |
| 1130 | dst_vdev = find_vhost_dev(&pkt_hdr->dst_addr); |
| 1131 | if (!dst_vdev) |
| 1132 | return -1; |
| 1133 | |
| 1134 | if (vdev->vid == dst_vdev->vid) { |
| 1135 | RTE_LOG_DP(DEBUG, VHOST_DATA, |
| 1136 | "(%d) TX: src and dst MAC is same. Dropping packet.\n", |
| 1137 | vdev->vid); |
| 1138 | return 0; |
| 1139 | } |
| 1140 | |
| 1141 | RTE_LOG_DP(DEBUG, VHOST_DATA, |
| 1142 | "(%d) TX: MAC address is local\n", dst_vdev->vid); |
| 1143 | |
| 1144 | if (unlikely(dst_vdev->remove)) { |
| 1145 | RTE_LOG_DP(DEBUG, VHOST_DATA, |
| 1146 | "(%d) device is marked for removal\n", dst_vdev->vid); |
| 1147 | return 0; |
| 1148 | } |
| 1149 | |
| 1150 | vhost_txq = vhost_txbuff[lcore_id * RTE_MAX_VHOST_DEVICE + dst_vdev->vid]; |
| 1151 | vhost_txq->m_table[vhost_txq->len++] = m; |
| 1152 | |
| 1153 | if (enable_stats) { |
| 1154 | vdev->stats.tx_total++; |
| 1155 | vdev->stats.tx++; |
| 1156 | } |
| 1157 | |
| 1158 | if (unlikely(vhost_txq->len == MAX_PKT_BURST)) { |
| 1159 | drain_vhost(dst_vdev); |
| 1160 | vhost_txq->len = 0; |
| 1161 | vhost_txq->pre_tsc = rte_rdtsc(); |
| 1162 | } |
| 1163 | return 0; |
| 1164 | } |
| 1165 | |
| 1166 | /* |
| 1167 | * Check if the destination MAC of a packet is one local VM, |
no test coverage detected