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]); } }
/* * This function takes a packet and routes it as per the flow table. */ static void switch_packet(struct rte_mbuf *pkt, uint8_t in_port) { int pos = 0; struct dpdk_upcall info = {0}; flow_key_extract(pkt, in_port, &info.key); pos = rte_hash_lookup(handle, &info.key); if (pos < 0) { /* flow table miss, send unmatched packet to the daemon */ info.cmd = PACKET_CMD_MISS; send_packet_to_vswitchd(pkt, &info); } else { flow_table_update_stats(pos, pkt); action_execute(pos, pkt); } }
/* * This function takes a packet and routes it as per the flow table. */ void switch_packet(struct rte_mbuf *pkt, uint8_t in_port) { int ret = 0; struct dpdk_upcall info = {0}; struct action action = {0}; flow_key_extract(pkt, in_port, &info.key); ret = flow_table_get_flow(&info.key, &action, NULL); if (ret >= 0) { flow_table_update_stats(&info.key, pkt); action_execute(&action, pkt); } else { /* flow table miss, send unmatched packet to the daemon */ info.cmd = PACKET_CMD_MISS; send_packet_to_vswitchd(pkt, &info); } }