do_switch_packets(unsigned vportid, struct rte_mbuf **bufs, int rx_count) { int j; /* * Initialize array of keys to 0 to avoid overhead of * loading the full key in to cache at once later. */ struct flow_key key[PKT_BURST_SIZE] = {{0}}; /* Prefetch first packets */ for (j = 0; j < PREFETCH_OFFSET && j < rx_count; j++) rte_prefetch0(rte_pktmbuf_mtod(bufs[j], void *)); /* Prefetch new packets and forward already prefetched packets */ for (j = 0; j < (rx_count - PREFETCH_OFFSET); j++) { flow_key_extract(bufs[j], vportid, &key[j]); rte_prefetch0(rte_pktmbuf_mtod(bufs[j + PREFETCH_OFFSET], void *)); switch_packet(bufs[j], &key[j]); } /* Forward remaining prefetched packets */ for (; j < rx_count; j++) { flow_key_extract(bufs[j], vportid, &key[j]); switch_packet(bufs[j], &key[j]); } }
/* * Receive burst of packets from physical port. */ static void receive_from_port(unsigned vportid) { int j = 0; uint16_t rx_count = 0; struct rte_mbuf *buf[PKT_BURST_SIZE] = {0}; /* read a port */ rx_count = rte_eth_rx_burst(ports->id[vportid & PORT_MASK], 0, \ buf, PKT_BURST_SIZE); /* Now process the NIC packets read */ if (likely(rx_count > 0)) { vport_stats[vportid].rx += rx_count; /* Prefetch first packets */ for (j = 0; j < PREFETCH_OFFSET && j < rx_count; j++) { rte_prefetch0(rte_pktmbuf_mtod(buf[j], void *)); } /* Prefetch and forward already prefetched packets */ for (j = 0; j < (rx_count - PREFETCH_OFFSET); j++) { rte_prefetch0(rte_pktmbuf_mtod(buf[ j + PREFETCH_OFFSET], void *)); switch_packet(buf[j], vportid); } /* Forward remaining prefetched packets */ for (; j < rx_count; j++) { switch_packet(buf[j], vportid); } } }
static inline void do_port_switching(unsigned vportid) { int rx_count = 0; int j = 0; struct rte_mbuf *bufs[PKT_BURST_SIZE] = {0}; rx_count = receive_from_port(vportid, &bufs[0]); /* Prefetch first packets */ for (j = 0; j < PREFETCH_OFFSET && j < rx_count; j++) { rte_prefetch0(rte_pktmbuf_mtod(bufs[j], void *)); } /* Prefetch and forward already prefetched packets */ for (j = 0; j < (rx_count - PREFETCH_OFFSET); j++) { rte_prefetch0(rte_pktmbuf_mtod(bufs[ j + PREFETCH_OFFSET], void *)); switch_packet(bufs[j], vportid); } /* Forward remaining prefetched packets */ for (; j < rx_count; j++) { switch_packet(bufs[j], vportid); } flush_pkts(vportid); }
static inline void do_client_switching(void) { static unsigned client = CLIENT1; static unsigned kni_vportid = KNI0; int rx_count = 0; int j = 0; struct rte_mbuf *bufs[PKT_BURST_SIZE] = {0}; rx_count = receive_from_client(client, &bufs[0]); /* Prefetch first packets */ for (j = 0; j < PREFETCH_OFFSET && j < rx_count; j++) { rte_prefetch0(rte_pktmbuf_mtod(bufs[j], void *)); } /* Prefetch and forward already prefetched packets */ for (j = 0; j < (rx_count - PREFETCH_OFFSET); j++) { rte_prefetch0(rte_pktmbuf_mtod(bufs[ j + PREFETCH_OFFSET], void *)); switch_packet(bufs[j], client); } /* Forward remaining prefetched packets */ for (; j < rx_count; j++) { switch_packet(bufs[j], client); } /* move to next client and dont handle client 0*/ if (++client == num_clients) { client = 1; } rx_count = receive_from_kni(kni_vportid, &bufs[0]); /* Prefetch first packets */ for (j = 0; j < PREFETCH_OFFSET && j < rx_count; j++) { rte_prefetch0(rte_pktmbuf_mtod(bufs[j], void *)); } /* Prefetch and forward already prefetched packets */ for (j = 0; j < (rx_count - PREFETCH_OFFSET); j++) { rte_prefetch0(rte_pktmbuf_mtod(bufs[ j + PREFETCH_OFFSET], void *)); switch_packet(bufs[j], kni_vportid); } /* Forward remaining prefetched packets */ for (; j < rx_count; j++) { switch_packet(bufs[j], kni_vportid); } /* move to next kni port */ if (++kni_vportid == KNI0 + num_kni) { kni_vportid = KNI0; } }
/* * Receive burst of packets from client */ static void receive_from_client(uint16_t client) { int j = 0; uint16_t dq_pkt = PKT_BURST_SIZE; struct rte_mbuf *buf[PKT_BURST_SIZE] = {0}; struct client *cl = NULL; struct statistics *s = NULL; cl = &clients[client]; s = &vport_stats[client]; /* Attempt to dequeue maximum available number of mbufs from ring */ while (dq_pkt > 0 && unlikely(rte_ring_sc_dequeue_bulk( cl->tx_q, (void **)buf, dq_pkt) != 0)) dq_pkt = (uint16_t)RTE_MIN( rte_ring_count(cl->tx_q), PKT_BURST_SIZE); /* Update number of packets transmitted by client */ s->tx += dq_pkt; for (j = 0; j < dq_pkt; j++) { switch_packet(buf[j], client); } }
/* * Receive burst of packets from a KNI fifo */ static void receive_from_kni(uint8_t vportid) { int i = 0; int rslt = 0; struct rte_mbuf *buf[PKT_BURST_SIZE] = {0}; struct statistics *s = NULL; s = &vport_stats[vportid]; rslt = rte_kni_rx_burst(&rte_kni_list[vportid & KNI_MASK], buf, PKT_BURST_SIZE); if (rslt != 0) { s->tx += rslt; for (i = 0; i < rslt; i++) { switch_packet(buf[i], vportid); } } }