1ed2a80fdSPablo de Lara /*- 2ed2a80fdSPablo de Lara * BSD LICENSE 3ed2a80fdSPablo de Lara * 4ed2a80fdSPablo de Lara * Copyright(c) 2016-2017 Intel Corporation. All rights reserved. 5ed2a80fdSPablo de Lara * All rights reserved. 6ed2a80fdSPablo de Lara * 7ed2a80fdSPablo de Lara * Redistribution and use in source and binary forms, with or without 8ed2a80fdSPablo de Lara * modification, are permitted provided that the following conditions 9ed2a80fdSPablo de Lara * are met: 10ed2a80fdSPablo de Lara * 11ed2a80fdSPablo de Lara * * Redistributions of source code must retain the above copyright 12ed2a80fdSPablo de Lara * notice, this list of conditions and the following disclaimer. 13ed2a80fdSPablo de Lara * * Redistributions in binary form must reproduce the above copyright 14ed2a80fdSPablo de Lara * notice, this list of conditions and the following disclaimer in 15ed2a80fdSPablo de Lara * the documentation and/or other materials provided with the 16ed2a80fdSPablo de Lara * distribution. 17ed2a80fdSPablo de Lara * * Neither the name of Intel Corporation nor the names of its 18ed2a80fdSPablo de Lara * contributors may be used to endorse or promote products derived 19ed2a80fdSPablo de Lara * from this software without specific prior written permission. 20ed2a80fdSPablo de Lara * 21ed2a80fdSPablo de Lara * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22ed2a80fdSPablo de Lara * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23ed2a80fdSPablo de Lara * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24ed2a80fdSPablo de Lara * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25ed2a80fdSPablo de Lara * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26ed2a80fdSPablo de Lara * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27ed2a80fdSPablo de Lara * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28ed2a80fdSPablo de Lara * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29ed2a80fdSPablo de Lara * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30ed2a80fdSPablo de Lara * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31ed2a80fdSPablo de Lara * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32ed2a80fdSPablo de Lara */ 33ed2a80fdSPablo de Lara 34ed2a80fdSPablo de Lara #include <stdint.h> 35ed2a80fdSPablo de Lara #include <stdio.h> 36ed2a80fdSPablo de Lara #include <inttypes.h> 37ed2a80fdSPablo de Lara #include <stdarg.h> 38ed2a80fdSPablo de Lara #include <errno.h> 39ed2a80fdSPablo de Lara #include <sys/queue.h> 40ed2a80fdSPablo de Lara #include <stdlib.h> 41ed2a80fdSPablo de Lara #include <getopt.h> 42ed2a80fdSPablo de Lara #include <string.h> 43ed2a80fdSPablo de Lara 44ed2a80fdSPablo de Lara #include <rte_common.h> 45ed2a80fdSPablo de Lara #include <rte_malloc.h> 46ed2a80fdSPablo de Lara #include <rte_memory.h> 47ed2a80fdSPablo de Lara #include <rte_memzone.h> 48ed2a80fdSPablo de Lara #include <rte_eal.h> 49ed2a80fdSPablo de Lara #include <rte_atomic.h> 50ed2a80fdSPablo de Lara #include <rte_branch_prediction.h> 51ed2a80fdSPablo de Lara #include <rte_log.h> 52ed2a80fdSPablo de Lara #include <rte_per_lcore.h> 53ed2a80fdSPablo de Lara #include <rte_launch.h> 54ed2a80fdSPablo de Lara #include <rte_lcore.h> 55ed2a80fdSPablo de Lara #include <rte_ring.h> 56ed2a80fdSPablo de Lara #include <rte_debug.h> 57ed2a80fdSPablo de Lara #include <rte_mempool.h> 58ed2a80fdSPablo de Lara #include <rte_mbuf.h> 59ed2a80fdSPablo de Lara #include <rte_interrupts.h> 60ed2a80fdSPablo de Lara #include <rte_pci.h> 61ed2a80fdSPablo de Lara #include <rte_ether.h> 62ed2a80fdSPablo de Lara #include <rte_ethdev.h> 63ed2a80fdSPablo de Lara #include <rte_string_fns.h> 64ed2a80fdSPablo de Lara #include <rte_ip.h> 65ed2a80fdSPablo de Lara 66ed2a80fdSPablo de Lara #include "common.h" 67ed2a80fdSPablo de Lara 68ed2a80fdSPablo de Lara /* Number of packets to attempt to read from queue */ 69ed2a80fdSPablo de Lara #define PKT_READ_SIZE ((uint16_t)32) 70ed2a80fdSPablo de Lara 71ed2a80fdSPablo de Lara /* 72ed2a80fdSPablo de Lara * Our node id number - tells us which rx queue to read, and NIC TX 73ed2a80fdSPablo de Lara * queue to write to. 74ed2a80fdSPablo de Lara */ 75ed2a80fdSPablo de Lara static uint8_t node_id; 76ed2a80fdSPablo de Lara 77ed2a80fdSPablo de Lara #define MBQ_CAPACITY 32 78ed2a80fdSPablo de Lara 79ed2a80fdSPablo de Lara /* maps input ports to output ports for packets */ 80*47523597SZhiyong Yang static uint16_t output_ports[RTE_MAX_ETHPORTS]; 81ed2a80fdSPablo de Lara 82ed2a80fdSPablo de Lara /* buffers up a set of packet that are ready to send */ 83ed2a80fdSPablo de Lara struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS]; 84ed2a80fdSPablo de Lara 85ed2a80fdSPablo de Lara /* shared data from server. We update statistics here */ 86ed2a80fdSPablo de Lara static struct tx_stats *tx_stats; 87ed2a80fdSPablo de Lara 88ed2a80fdSPablo de Lara static struct filter_stats *filter_stats; 89ed2a80fdSPablo de Lara 90ed2a80fdSPablo de Lara /* 91ed2a80fdSPablo de Lara * print a usage message 92ed2a80fdSPablo de Lara */ 93ed2a80fdSPablo de Lara static void 94ed2a80fdSPablo de Lara usage(const char *progname) 95ed2a80fdSPablo de Lara { 96ed2a80fdSPablo de Lara printf("Usage: %s [EAL args] -- -n <node_id>\n\n", progname); 97ed2a80fdSPablo de Lara } 98ed2a80fdSPablo de Lara 99ed2a80fdSPablo de Lara /* 100ed2a80fdSPablo de Lara * Convert the node id number from a string to an int. 101ed2a80fdSPablo de Lara */ 102ed2a80fdSPablo de Lara static int 103ed2a80fdSPablo de Lara parse_node_num(const char *node) 104ed2a80fdSPablo de Lara { 105ed2a80fdSPablo de Lara char *end = NULL; 106ed2a80fdSPablo de Lara unsigned long temp; 107ed2a80fdSPablo de Lara 108ed2a80fdSPablo de Lara if (node == NULL || *node == '\0') 109ed2a80fdSPablo de Lara return -1; 110ed2a80fdSPablo de Lara 111ed2a80fdSPablo de Lara temp = strtoul(node, &end, 10); 112ed2a80fdSPablo de Lara if (end == NULL || *end != '\0') 113ed2a80fdSPablo de Lara return -1; 114ed2a80fdSPablo de Lara 115ed2a80fdSPablo de Lara node_id = (uint8_t)temp; 116ed2a80fdSPablo de Lara return 0; 117ed2a80fdSPablo de Lara } 118ed2a80fdSPablo de Lara 119ed2a80fdSPablo de Lara /* 120ed2a80fdSPablo de Lara * Parse the application arguments to the node app. 121ed2a80fdSPablo de Lara */ 122ed2a80fdSPablo de Lara static int 123ed2a80fdSPablo de Lara parse_app_args(int argc, char *argv[]) 124ed2a80fdSPablo de Lara { 125ed2a80fdSPablo de Lara int option_index, opt; 126ed2a80fdSPablo de Lara char **argvopt = argv; 127ed2a80fdSPablo de Lara const char *progname = NULL; 128ed2a80fdSPablo de Lara static struct option lgopts[] = { /* no long options */ 129ed2a80fdSPablo de Lara {NULL, 0, 0, 0 } 130ed2a80fdSPablo de Lara }; 131ed2a80fdSPablo de Lara progname = argv[0]; 132ed2a80fdSPablo de Lara 133ed2a80fdSPablo de Lara while ((opt = getopt_long(argc, argvopt, "n:", lgopts, 134ed2a80fdSPablo de Lara &option_index)) != EOF) { 135ed2a80fdSPablo de Lara switch (opt) { 136ed2a80fdSPablo de Lara case 'n': 137ed2a80fdSPablo de Lara if (parse_node_num(optarg) != 0) { 138ed2a80fdSPablo de Lara usage(progname); 139ed2a80fdSPablo de Lara return -1; 140ed2a80fdSPablo de Lara } 141ed2a80fdSPablo de Lara break; 142ed2a80fdSPablo de Lara default: 143ed2a80fdSPablo de Lara usage(progname); 144ed2a80fdSPablo de Lara return -1; 145ed2a80fdSPablo de Lara } 146ed2a80fdSPablo de Lara } 147ed2a80fdSPablo de Lara return 0; 148ed2a80fdSPablo de Lara } 149ed2a80fdSPablo de Lara 150ed2a80fdSPablo de Lara /* 151ed2a80fdSPablo de Lara * Tx buffer error callback 152ed2a80fdSPablo de Lara */ 153ed2a80fdSPablo de Lara static void 154ed2a80fdSPablo de Lara flush_tx_error_callback(struct rte_mbuf **unsent, uint16_t count, 155ed2a80fdSPablo de Lara void *userdata) { 156ed2a80fdSPablo de Lara int i; 157*47523597SZhiyong Yang uint16_t port_id = (uintptr_t)userdata; 158ed2a80fdSPablo de Lara 159ed2a80fdSPablo de Lara tx_stats->tx_drop[port_id] += count; 160ed2a80fdSPablo de Lara 161ed2a80fdSPablo de Lara /* free the mbufs which failed from transmit */ 162ed2a80fdSPablo de Lara for (i = 0; i < count; i++) 163ed2a80fdSPablo de Lara rte_pktmbuf_free(unsent[i]); 164ed2a80fdSPablo de Lara 165ed2a80fdSPablo de Lara } 166ed2a80fdSPablo de Lara 167ed2a80fdSPablo de Lara static void 168*47523597SZhiyong Yang configure_tx_buffer(uint16_t port_id, uint16_t size) 169ed2a80fdSPablo de Lara { 170ed2a80fdSPablo de Lara int ret; 171ed2a80fdSPablo de Lara 172ed2a80fdSPablo de Lara /* Initialize TX buffers */ 173ed2a80fdSPablo de Lara tx_buffer[port_id] = rte_zmalloc_socket("tx_buffer", 174ed2a80fdSPablo de Lara RTE_ETH_TX_BUFFER_SIZE(size), 0, 175ed2a80fdSPablo de Lara rte_eth_dev_socket_id(port_id)); 176ed2a80fdSPablo de Lara if (tx_buffer[port_id] == NULL) 177*47523597SZhiyong Yang rte_exit(EXIT_FAILURE, 178*47523597SZhiyong Yang "Cannot allocate buffer for tx on port %u\n", port_id); 179ed2a80fdSPablo de Lara 180ed2a80fdSPablo de Lara rte_eth_tx_buffer_init(tx_buffer[port_id], size); 181ed2a80fdSPablo de Lara 182ed2a80fdSPablo de Lara ret = rte_eth_tx_buffer_set_err_callback(tx_buffer[port_id], 183ed2a80fdSPablo de Lara flush_tx_error_callback, (void *)(intptr_t)port_id); 184ed2a80fdSPablo de Lara if (ret < 0) 185*47523597SZhiyong Yang rte_exit(EXIT_FAILURE, 186*47523597SZhiyong Yang "Cannot set error callback for tx buffer on port %u\n", 187*47523597SZhiyong Yang port_id); 188ed2a80fdSPablo de Lara } 189ed2a80fdSPablo de Lara 190ed2a80fdSPablo de Lara /* 191ed2a80fdSPablo de Lara * set up output ports so that all traffic on port gets sent out 192ed2a80fdSPablo de Lara * its paired port. Index using actual port numbers since that is 193ed2a80fdSPablo de Lara * what comes in the mbuf structure. 194ed2a80fdSPablo de Lara */ 195ed2a80fdSPablo de Lara static void 196ed2a80fdSPablo de Lara configure_output_ports(const struct shared_info *info) 197ed2a80fdSPablo de Lara { 198ed2a80fdSPablo de Lara int i; 199ed2a80fdSPablo de Lara 200ed2a80fdSPablo de Lara if (info->num_ports > RTE_MAX_ETHPORTS) 201ed2a80fdSPablo de Lara rte_exit(EXIT_FAILURE, "Too many ethernet ports. " 202ed2a80fdSPablo de Lara "RTE_MAX_ETHPORTS = %u\n", 203ed2a80fdSPablo de Lara (unsigned int)RTE_MAX_ETHPORTS); 204ed2a80fdSPablo de Lara for (i = 0; i < info->num_ports - 1; i += 2) { 205ed2a80fdSPablo de Lara uint8_t p1 = info->id[i]; 206ed2a80fdSPablo de Lara uint8_t p2 = info->id[i+1]; 207ed2a80fdSPablo de Lara 208ed2a80fdSPablo de Lara output_ports[p1] = p2; 209ed2a80fdSPablo de Lara output_ports[p2] = p1; 210ed2a80fdSPablo de Lara 211ed2a80fdSPablo de Lara configure_tx_buffer(p1, MBQ_CAPACITY); 212ed2a80fdSPablo de Lara configure_tx_buffer(p2, MBQ_CAPACITY); 213ed2a80fdSPablo de Lara 214ed2a80fdSPablo de Lara } 215ed2a80fdSPablo de Lara } 216ed2a80fdSPablo de Lara 217ed2a80fdSPablo de Lara /* 218ed2a80fdSPablo de Lara * Create the hash table that will contain the flows that 219ed2a80fdSPablo de Lara * the node will handle, which will be used to decide if packet 220ed2a80fdSPablo de Lara * is transmitted or dropped. 221ed2a80fdSPablo de Lara */ 222ed2a80fdSPablo de Lara static struct rte_hash * 223ed2a80fdSPablo de Lara create_hash_table(const struct shared_info *info) 224ed2a80fdSPablo de Lara { 225ed2a80fdSPablo de Lara uint32_t num_flows_node = info->num_flows / info->num_nodes; 226ed2a80fdSPablo de Lara char name[RTE_HASH_NAMESIZE]; 227ed2a80fdSPablo de Lara struct rte_hash *h; 228ed2a80fdSPablo de Lara 229ed2a80fdSPablo de Lara /* create table */ 230ed2a80fdSPablo de Lara struct rte_hash_parameters hash_params = { 231ed2a80fdSPablo de Lara .entries = num_flows_node * 2, /* table load = 50% */ 232ed2a80fdSPablo de Lara .key_len = sizeof(uint32_t), /* Store IPv4 dest IP address */ 233ed2a80fdSPablo de Lara .socket_id = rte_socket_id(), 234ed2a80fdSPablo de Lara .hash_func_init_val = 0, 235ed2a80fdSPablo de Lara }; 236ed2a80fdSPablo de Lara 237ed2a80fdSPablo de Lara snprintf(name, sizeof(name), "hash_table_%d", node_id); 238ed2a80fdSPablo de Lara hash_params.name = name; 239ed2a80fdSPablo de Lara h = rte_hash_create(&hash_params); 240ed2a80fdSPablo de Lara 241ed2a80fdSPablo de Lara if (h == NULL) 242ed2a80fdSPablo de Lara rte_exit(EXIT_FAILURE, 243ed2a80fdSPablo de Lara "Problem creating the hash table for node %d\n", 244ed2a80fdSPablo de Lara node_id); 245ed2a80fdSPablo de Lara return h; 246ed2a80fdSPablo de Lara } 247ed2a80fdSPablo de Lara 248ed2a80fdSPablo de Lara static void 249ed2a80fdSPablo de Lara populate_hash_table(const struct rte_hash *h, const struct shared_info *info) 250ed2a80fdSPablo de Lara { 251ed2a80fdSPablo de Lara unsigned int i; 252ed2a80fdSPablo de Lara int32_t ret; 253ed2a80fdSPablo de Lara uint32_t ip_dst; 254ed2a80fdSPablo de Lara uint32_t num_flows_node = 0; 255ed2a80fdSPablo de Lara uint64_t target_node; 256ed2a80fdSPablo de Lara 257ed2a80fdSPablo de Lara /* Add flows in table */ 258ed2a80fdSPablo de Lara for (i = 0; i < info->num_flows; i++) { 259ed2a80fdSPablo de Lara target_node = i % info->num_nodes; 260ed2a80fdSPablo de Lara if (target_node != node_id) 261ed2a80fdSPablo de Lara continue; 262ed2a80fdSPablo de Lara 263ed2a80fdSPablo de Lara ip_dst = rte_cpu_to_be_32(i); 264ed2a80fdSPablo de Lara 265ed2a80fdSPablo de Lara ret = rte_hash_add_key(h, (void *) &ip_dst); 266ed2a80fdSPablo de Lara if (ret < 0) 267ed2a80fdSPablo de Lara rte_exit(EXIT_FAILURE, "Unable to add entry %u " 268ed2a80fdSPablo de Lara "in hash table\n", i); 269ed2a80fdSPablo de Lara else 270ed2a80fdSPablo de Lara num_flows_node++; 271ed2a80fdSPablo de Lara 272ed2a80fdSPablo de Lara } 273ed2a80fdSPablo de Lara 274ed2a80fdSPablo de Lara printf("Hash table: Adding 0x%x keys\n", num_flows_node); 275ed2a80fdSPablo de Lara } 276ed2a80fdSPablo de Lara 277ed2a80fdSPablo de Lara /* 278ed2a80fdSPablo de Lara * This function performs routing of packets 279ed2a80fdSPablo de Lara * Just sends each input packet out an output port based solely on the input 280ed2a80fdSPablo de Lara * port it arrived on. 281ed2a80fdSPablo de Lara */ 282ed2a80fdSPablo de Lara static inline void 283ed2a80fdSPablo de Lara transmit_packet(struct rte_mbuf *buf) 284ed2a80fdSPablo de Lara { 285ed2a80fdSPablo de Lara int sent; 286*47523597SZhiyong Yang const uint16_t in_port = buf->port; 287*47523597SZhiyong Yang const uint16_t out_port = output_ports[in_port]; 288ed2a80fdSPablo de Lara struct rte_eth_dev_tx_buffer *buffer = tx_buffer[out_port]; 289ed2a80fdSPablo de Lara 290ed2a80fdSPablo de Lara sent = rte_eth_tx_buffer(out_port, node_id, buffer, buf); 291ed2a80fdSPablo de Lara if (sent) 292ed2a80fdSPablo de Lara tx_stats->tx[out_port] += sent; 293ed2a80fdSPablo de Lara 294ed2a80fdSPablo de Lara } 295ed2a80fdSPablo de Lara 296ed2a80fdSPablo de Lara static inline void 297ed2a80fdSPablo de Lara handle_packets(struct rte_hash *h, struct rte_mbuf **bufs, uint16_t num_packets) 298ed2a80fdSPablo de Lara { 299ed2a80fdSPablo de Lara struct ipv4_hdr *ipv4_hdr; 300ed2a80fdSPablo de Lara uint32_t ipv4_dst_ip[PKT_READ_SIZE]; 301ed2a80fdSPablo de Lara const void *key_ptrs[PKT_READ_SIZE]; 302ed2a80fdSPablo de Lara unsigned int i; 303ed2a80fdSPablo de Lara int32_t positions[PKT_READ_SIZE] = {0}; 304ed2a80fdSPablo de Lara 305ed2a80fdSPablo de Lara for (i = 0; i < num_packets; i++) { 306ed2a80fdSPablo de Lara /* Handle IPv4 header.*/ 307ed2a80fdSPablo de Lara ipv4_hdr = rte_pktmbuf_mtod_offset(bufs[i], struct ipv4_hdr *, 308ed2a80fdSPablo de Lara sizeof(struct ether_hdr)); 309ed2a80fdSPablo de Lara ipv4_dst_ip[i] = ipv4_hdr->dst_addr; 310ed2a80fdSPablo de Lara key_ptrs[i] = &ipv4_dst_ip[i]; 311ed2a80fdSPablo de Lara } 312ed2a80fdSPablo de Lara /* Check if packets belongs to any flows handled by this node */ 313ed2a80fdSPablo de Lara rte_hash_lookup_bulk(h, key_ptrs, num_packets, positions); 314ed2a80fdSPablo de Lara 315ed2a80fdSPablo de Lara for (i = 0; i < num_packets; i++) { 316ed2a80fdSPablo de Lara if (likely(positions[i] >= 0)) { 317ed2a80fdSPablo de Lara filter_stats->passed++; 318ed2a80fdSPablo de Lara transmit_packet(bufs[i]); 319ed2a80fdSPablo de Lara } else { 320ed2a80fdSPablo de Lara filter_stats->drop++; 321ed2a80fdSPablo de Lara /* Drop packet, as flow is not handled by this node */ 322ed2a80fdSPablo de Lara rte_pktmbuf_free(bufs[i]); 323ed2a80fdSPablo de Lara } 324ed2a80fdSPablo de Lara } 325ed2a80fdSPablo de Lara } 326ed2a80fdSPablo de Lara 327ed2a80fdSPablo de Lara /* 328ed2a80fdSPablo de Lara * Application main function - loops through 329ed2a80fdSPablo de Lara * receiving and processing packets. Never returns 330ed2a80fdSPablo de Lara */ 331ed2a80fdSPablo de Lara int 332ed2a80fdSPablo de Lara main(int argc, char *argv[]) 333ed2a80fdSPablo de Lara { 334ed2a80fdSPablo de Lara const struct rte_memzone *mz; 335ed2a80fdSPablo de Lara struct rte_ring *rx_ring; 336ed2a80fdSPablo de Lara struct rte_hash *h; 337ed2a80fdSPablo de Lara struct rte_mempool *mp; 338ed2a80fdSPablo de Lara struct shared_info *info; 339ed2a80fdSPablo de Lara int need_flush = 0; /* indicates whether we have unsent packets */ 340ed2a80fdSPablo de Lara int retval; 341ed2a80fdSPablo de Lara void *pkts[PKT_READ_SIZE]; 342ed2a80fdSPablo de Lara uint16_t sent; 343ed2a80fdSPablo de Lara 344ed2a80fdSPablo de Lara retval = rte_eal_init(argc, argv); 345ed2a80fdSPablo de Lara if (retval < 0) 346ed2a80fdSPablo de Lara return -1; 347ed2a80fdSPablo de Lara argc -= retval; 348ed2a80fdSPablo de Lara argv += retval; 349ed2a80fdSPablo de Lara 350ed2a80fdSPablo de Lara if (parse_app_args(argc, argv) < 0) 351ed2a80fdSPablo de Lara rte_exit(EXIT_FAILURE, "Invalid command-line arguments\n"); 352ed2a80fdSPablo de Lara 353ed2a80fdSPablo de Lara if (rte_eth_dev_count() == 0) 354ed2a80fdSPablo de Lara rte_exit(EXIT_FAILURE, "No Ethernet ports - bye\n"); 355ed2a80fdSPablo de Lara 356ed2a80fdSPablo de Lara rx_ring = rte_ring_lookup(get_rx_queue_name(node_id)); 357ed2a80fdSPablo de Lara if (rx_ring == NULL) 358ed2a80fdSPablo de Lara rte_exit(EXIT_FAILURE, "Cannot get RX ring - " 359ed2a80fdSPablo de Lara "is server process running?\n"); 360ed2a80fdSPablo de Lara 361ed2a80fdSPablo de Lara mp = rte_mempool_lookup(PKTMBUF_POOL_NAME); 362ed2a80fdSPablo de Lara if (mp == NULL) 363ed2a80fdSPablo de Lara rte_exit(EXIT_FAILURE, "Cannot get mempool for mbufs\n"); 364ed2a80fdSPablo de Lara 365ed2a80fdSPablo de Lara mz = rte_memzone_lookup(MZ_SHARED_INFO); 366ed2a80fdSPablo de Lara if (mz == NULL) 367ed2a80fdSPablo de Lara rte_exit(EXIT_FAILURE, "Cannot get port info structure\n"); 368ed2a80fdSPablo de Lara info = mz->addr; 369ed2a80fdSPablo de Lara tx_stats = &(info->tx_stats[node_id]); 370ed2a80fdSPablo de Lara filter_stats = &(info->filter_stats[node_id]); 371ed2a80fdSPablo de Lara 372ed2a80fdSPablo de Lara configure_output_ports(info); 373ed2a80fdSPablo de Lara 374ed2a80fdSPablo de Lara h = create_hash_table(info); 375ed2a80fdSPablo de Lara 376ed2a80fdSPablo de Lara populate_hash_table(h, info); 377ed2a80fdSPablo de Lara 378ed2a80fdSPablo de Lara RTE_LOG(INFO, APP, "Finished Process Init.\n"); 379ed2a80fdSPablo de Lara 380ed2a80fdSPablo de Lara printf("\nNode process %d handling packets\n", node_id); 381ed2a80fdSPablo de Lara printf("[Press Ctrl-C to quit ...]\n"); 382ed2a80fdSPablo de Lara 383ed2a80fdSPablo de Lara for (;;) { 384ed2a80fdSPablo de Lara uint16_t rx_pkts = PKT_READ_SIZE; 385*47523597SZhiyong Yang uint16_t port; 386ed2a80fdSPablo de Lara 387ed2a80fdSPablo de Lara /* 388ed2a80fdSPablo de Lara * Try dequeuing max possible packets first, if that fails, 389ed2a80fdSPablo de Lara * get the most we can. Loop body should only execute once, 390ed2a80fdSPablo de Lara * maximum 391ed2a80fdSPablo de Lara */ 392ed2a80fdSPablo de Lara while (rx_pkts > 0 && 393ed2a80fdSPablo de Lara unlikely(rte_ring_dequeue_bulk(rx_ring, pkts, 394ecaed092SBruce Richardson rx_pkts, NULL) == 0)) 395ed2a80fdSPablo de Lara rx_pkts = (uint16_t)RTE_MIN(rte_ring_count(rx_ring), 396ed2a80fdSPablo de Lara PKT_READ_SIZE); 397ed2a80fdSPablo de Lara 398ed2a80fdSPablo de Lara if (unlikely(rx_pkts == 0)) { 399ed2a80fdSPablo de Lara if (need_flush) 400ed2a80fdSPablo de Lara for (port = 0; port < info->num_ports; port++) { 401ed2a80fdSPablo de Lara sent = rte_eth_tx_buffer_flush( 402ed2a80fdSPablo de Lara info->id[port], 403ed2a80fdSPablo de Lara node_id, 404ed2a80fdSPablo de Lara tx_buffer[port]); 405ed2a80fdSPablo de Lara if (unlikely(sent)) 406ed2a80fdSPablo de Lara tx_stats->tx[port] += sent; 407ed2a80fdSPablo de Lara } 408ed2a80fdSPablo de Lara need_flush = 0; 409ed2a80fdSPablo de Lara continue; 410ed2a80fdSPablo de Lara } 411ed2a80fdSPablo de Lara 412ed2a80fdSPablo de Lara handle_packets(h, (struct rte_mbuf **)pkts, rx_pkts); 413ed2a80fdSPablo de Lara 414ed2a80fdSPablo de Lara need_flush = 1; 415ed2a80fdSPablo de Lara } 416ed2a80fdSPablo de Lara } 417