int rte_event_eth_rx_adapter_stats_reset(uint8_t id) { struct rte_event_eth_rx_adapter *rx_adapter; struct rte_eventdev *dev; struct eth_device_info *dev_info; uint32_t i; RTE_EVENT_ETH_RX_ADAPTER_ID_VALID_OR_ERR_RET(id, -EINVAL); rx_adapter = id_to_rx_adapter(id); if (rx_adapter == NULL) return -EINVAL; dev = &rte_eventdevs[rx_adapter->eventdev_id]; for (i = 0; i < rte_eth_dev_count(); i++) { dev_info = &rx_adapter->eth_devices[i]; if (dev_info->internal_event_port == 0 || dev->dev_ops->eth_rx_adapter_stats_reset == NULL) continue; (*dev->dev_ops->eth_rx_adapter_stats_reset)(dev, &rte_eth_devices[i]); } memset(&rx_adapter->stats, 0, sizeof(rx_adapter->stats)); return 0; }
char* pcap_lookupdev(char* errbuf) { int port = 0; struct rte_eth_dev_info info; if (globalInit(errbuf) != DPDKPCAP_OK) { return NULL; } int portsNumber = rte_eth_dev_count(); if (portsNumber < 1) { snprintf (errbuf, PCAP_ERRBUF_SIZE, "No devices found"); return NULL; } if (deviceInit(port, errbuf) == DPDKPCAP_FAILURE) { return NULL; } rte_eth_dev_info_get(port, &info); snprintf(ifName, DPDKPCAP_IF_NAMESIZE, "enp%us%u", info.pci_dev->addr.bus, info.pci_dev->addr.devid); deviceNames[port] = ifName; return ifName; }
static int globalinit(struct virtif_user *viu) { int rv; if ((rv = rte_eal_init(sizeof(ealargs)/sizeof(ealargs[0]), /*UNCONST*/(void *)(uintptr_t)ealargs)) < 0) OUT("eal init\n"); /* disable mempool cache due to DPDK bug, not thread safe */ if ((mbpool = rte_mempool_create("mbuf_pool", NMBUF, MBSIZE, 0/*MBCACHE*/, sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL, 0, 0)) == NULL) { rv = -EINVAL; OUT("mbuf pool\n"); } if ((rv = PMD_INIT()) < 0) OUT("pmd init\n"); if ((rv = rte_eal_pci_probe()) < 0) OUT("PCI probe\n"); if (rte_eth_dev_count() == 0) { rv = -1; OUT("no ports\n"); } rv = 0; out: return rv; }
/* Callback for request of configuring network interface up/down */ static int kni_config_network_interface(uint8_t port_id, uint8_t if_up) { int ret = 0; RTE_LOG(INFO, KNI, "---- kni_config_network_interface\n"); if (port_id >= rte_eth_dev_count() || port_id >= RTE_MAX_ETHPORTS) { RTE_LOG(ERR, KNI, "Invalid port id %d\n", port_id); return -EINVAL; } RTE_LOG(INFO, KNI, "Configure network interface of %d %s\n", port_id, if_up ? "up" : "down"); if (if_up != 0) { /* Configure network interface up */ rte_eth_dev_stop(port_id); ret = rte_eth_dev_start(port_id); kni_port_rdy[port_id]++; } else /* Configure network interface down */ rte_eth_dev_stop(port_id); if (ret < 0) RTE_LOG(ERR, KNI, "Failed to start port %d\n", port_id); RTE_LOG(INFO, KNI, "finished kni_config_network_interface\n"); return ret; }
/* * Parse the command line arguments passed to the application. */ int parse_args(int argc, char** argv, app_params* p) { // initialize the environment int ret = rte_eal_init(argc, argv); if (ret < 0) { rte_exit(EXIT_FAILURE, "Failed to initialize EAL: %i\n", ret); } // advance past the environmental settings argc -= ret; argv += ret; // parse arguments to the application ret = parse_app_args(argc, argv, p); if (ret < 0) { rte_exit(EXIT_FAILURE, "\n"); } p->nb_ports = rte_eth_dev_count(); p->nb_rx_workers = p->nb_rx_queue; p->nb_tx_workers = (rte_lcore_count() - 1) - p->nb_rx_workers; // validate the number of workers if(p->nb_tx_workers < p->nb_rx_workers) { rte_exit(EXIT_FAILURE, "Additional lcore(s) required; found=%u, required=%u \n", rte_lcore_count(), (p->nb_rx_queue*2) + 1); } return 0; }
static int dpdk_helper_link_status_get(dpdk_helper_ctx_t *phc) { dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(phc); /* get Link Status values from DPDK */ uint8_t nb_ports = rte_eth_dev_count(); if (nb_ports == 0) { DPDK_CHILD_LOG("dpdkevent-helper: No DPDK ports available. " "Check bound devices to DPDK driver.\n"); return -ENODEV; } ec->nb_ports = nb_ports > RTE_MAX_ETHPORTS ? RTE_MAX_ETHPORTS : nb_ports; for (int i = 0; i < ec->nb_ports; i++) { if (ec->config.link_status.enabled_port_mask & (1 << i)) { struct rte_eth_link link; ec->link_info[i].read_time = cdtime(); rte_eth_link_get_nowait(i, &link); if ((link.link_status == ETH_LINK_NA) || (link.link_status != ec->link_info[i].link_status)) { ec->link_info[i].link_status = link.link_status; ec->link_info[i].status_updated = 1; DPDK_CHILD_LOG(" === PORT %d Link Status: %s\n", i, link.link_status ? "UP" : "DOWN"); } } } return 0; }
/* Callback for request of configuring network interface up/down */ static int kni_config_network_interface(uint8_t port_id, uint8_t if_up) { #if 0 int ret = 0; if (port_id >= rte_eth_dev_count() || port_id >= RTE_MAX_ETHPORTS) { RTE_LOG(ERR, APP, "Invalid port id %d\n", port_id); return -EINVAL; } RTE_LOG(INFO, APP, "Configure network interface of %d %s\n", port_id, if_up ? "up" : "down"); if (if_up != 0) { /* Configure network interface up */ rte_eth_dev_stop(port_id); ret = rte_eth_dev_start(port_id); } else /* Configure network interface down */ rte_eth_dev_stop(port_id); if (ret < 0) RTE_LOG(ERR, APP, "Failed to start port %d\n", port_id); return ret; #endif return 0; }
static int globalinit(struct virtif_user *viu) { int rv; if ((rv = rte_eal_init(sizeof(ealargs)/sizeof(ealargs[0]), /*UNCONST*/(void *)(uintptr_t)ealargs)) < 0) OUT("eal init"); if ((mbpool_tx = rte_mempool_create("mbuf_pool_tx", NMBUF_TX, MBSIZE, 0/*MBCACHE*/, sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL, 0, 0)) == NULL) { rv = -EINVAL; OUT("mbuf pool tx"); } if ((mbpool_rx = rte_mempool_create("mbuf_pool_rx", NMBUF_RX, MBSIZE, 0/*MBCACHE*/, sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL, 0, 0)) == NULL) { rv = -EINVAL; OUT("mbuf pool tx"); } if (rte_eth_dev_count() == 0) { rv = -1; OUT("no ports"); } rv = 0; out: return rv; }
static void l2sw_main_process(struct lcore_env *env) { struct rte_mbuf *pkt_burst[MAX_PKT_BURST]; uint8_t n_ports = rte_eth_dev_count(); unsigned lcore_id = rte_lcore_id(); uint64_t prev_tsc, diff_tsc, cur_tsc, timer_tsc; const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * BURST_TX_DRAIN_US; //RTE_LOG(INFO, MARIO, "[%u] Starting main processing.\n", lcore_id); prev_tsc = 0; timer_tsc = 0; while(1) { cur_tsc = rte_rdtsc(); diff_tsc = cur_tsc - prev_tsc; if (unlikely(diff_tsc > drain_tsc)) { uint8_t port_id; for(port_id = 0; port_id < n_ports; port_id++) { if (env->tx_mbufs[port_id].len == 0) continue; l2sw_send_burst(env, port_id, env->tx_mbufs[port_id].len); env->tx_mbufs[port_id].len = 0; } /* if timer is enabled */ if (timer_period > 0) { /* advance the timer */ timer_tsc += diff_tsc; /* if timer has reached its timeout */ if (unlikely(timer_tsc >= (uint64_t) timer_period)) { /* do this only on master core */ if (lcore_id == rte_get_master_lcore()) { //print_stats(env); /* reset the timer */ timer_tsc = 0; } } } prev_tsc = cur_tsc; } /* RX */ uint8_t port_id; for (port_id = 0; port_id < n_ports; port_id++) { unsigned n_rx = rte_eth_rx_burst(port_id, lcore_id, pkt_burst, MAX_PKT_BURST); if (n_rx != 0) //RTE_LOG(INFO, MARIO, "[%u-%u] %u packet(s) came.\n", // lcore_id, port_id, n_rx); __sync_fetch_and_add(&port_statistics[port_id].rx, n_rx); ether_in(env, pkt_burst, n_rx, port_id); } } return ; }
static int globalinit(void) { int rv; if (rte_eal_init(sizeof(ealargs)/sizeof(ealargs[0]), /*UNCONST*/(void *)(uintptr_t)ealargs) < 0) OUT("eal init\n"); if ((mbpool = rte_mempool_create("mbuf_pool", NMBUF, MBSIZE, MBALIGN, sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL, 0, 0)) == NULL) OUT("mbuf pool\n"); if (PMD_INIT() < 0) OUT("wm driver\n"); if (rte_eal_pci_probe() < 0) OUT("PCI probe\n"); if (rte_eth_dev_count() == 0) OUT("no ports\n"); rv = 0; out: return rv; }
/** * @brief Initialize all DPDK devices * * @return true on success */ bool DPDKAdapter::initializeDevs() { if(rte_eal_pci_probe() < 0) { qCritical("Cannot probe PCI"); return false; } nPortCount = rte_eth_dev_count(); if(nPortCount < 1) { qCritical("No ports found"); return false; } //Limit devices count if(nPortCount > RTE_MAX_ETHPORTS) nPortCount = RTE_MAX_ETHPORTS; for(u_int8_t portId; portId < nPortCount; ++portId) { if(!initDevRxTxMPool(portId)) { qCritical("TX/RX pools could not been allocated : port %u", portId); return false; } } return true; }
static int start_loop(int verbose) { struct pg_error *error = NULL; struct pg_brick *nic_tmp, *switch_east, *print_tmp; uint16_t port_count = rte_eth_dev_count(); GList *nic_manager = NULL; GList *manager = NULL; g_assert(port_count > 1); /* * Here is an ascii graph of the links: * * [NIC-X] - [PRINT-X] --\ * \ * [NIC-X+1] - [PRINT-X+1] } -- [SWITCH] * / * [NIC-X+2] - [PRINT-X+2] / * .... */ switch_east = pg_switch_new("switch", 20, 20, &error); CHECK_ERROR(error); PG_BM_ADD(manager, switch_east); for (int i = 0; i < port_count; ++i) { nic_tmp = pg_nic_new_by_id("nic", 1, 1, WEST_SIDE, i, &error); CHECK_ERROR(error); print_tmp = pg_print_new("print", 1, 1, NULL, PG_PRINT_FLAG_MAX, NULL, &error); CHECK_ERROR(error); if (!verbose) pg_brick_chained_links(&error, nic_tmp, switch_east); else pg_brick_chained_links(&error, nic_tmp, print_tmp, switch_east); CHECK_ERROR(error); PG_BM_ADD(nic_manager, nic_tmp); PG_BM_ADD(manager, print_tmp); } while (1) { uint64_t tot_send_pkts = 0; for (int i = 0; i < 100000; ++i) { uint16_t nb_send_pkts; PG_BM_GET_NEXT(nic_manager, nic_tmp); pg_brick_poll(nic_tmp, &nb_send_pkts, &error); tot_send_pkts += nb_send_pkts; CHECK_ERROR(error); usleep(1); } printf("poll pkts: %lu\n", tot_send_pkts); } nic_manager = g_list_first(nic_manager); PG_BM_DESTROY(manager); PG_BM_DESTROY(nic_manager); return 0; }
/* Parse the argument given in the command line of the application */ static int smp_parse_args(int argc, char **argv) { int opt, ret; char **argvopt; int option_index; unsigned i, port_mask = 0; char *prgname = argv[0]; static struct option lgopts[] = { {PARAM_NUM_PROCS, 1, 0, 0}, {PARAM_PROC_ID, 1, 0, 0}, {NULL, 0, 0, 0} }; argvopt = argv; while ((opt = getopt_long(argc, argvopt, "p:", \ lgopts, &option_index)) != EOF) { switch (opt) { case 'p': port_mask = strtoull(optarg, NULL, 16); break; /* long options */ case 0: if (strncmp(lgopts[option_index].name, PARAM_NUM_PROCS, 8) == 0) num_procs = atoi(optarg); else if (strncmp(lgopts[option_index].name, PARAM_PROC_ID, 7) == 0) proc_id = atoi(optarg); break; default: smp_usage(prgname, "Cannot parse all command-line arguments\n"); } } if (optind >= 0) argv[optind-1] = prgname; if (proc_id < 0) smp_usage(prgname, "Invalid or missing proc-id parameter\n"); if (rte_eal_process_type() == RTE_PROC_PRIMARY && num_procs == 0) smp_usage(prgname, "Invalid or missing num-procs parameter\n"); if (port_mask == 0) smp_usage(prgname, "Invalid or missing port mask\n"); /* get the port numbers from the port mask */ for(i = 0; i < rte_eth_dev_count(); i++) if(port_mask & (1 << i)) ports[num_ports++] = (uint8_t)i; ret = optind-1; optind = 0; /* reset getopt lib */ return (ret); }
/** * Main init function for the multi-process server app, * calls subfunctions to do each stage of the initialisation. */ int init(int argc, char *argv[]) { int retval; const struct rte_memzone *mz; uint8_t i, total_ports; /* init EAL, parsing EAL args */ retval = rte_eal_init(argc, argv); if (retval < 0) return -1; argc -= retval; argv += retval; /* initialise the nic drivers */ retval = init_drivers(); if (retval != 0) rte_exit(EXIT_FAILURE, "Cannot initialise drivers\n"); /* get total number of ports */ total_ports = rte_eth_dev_count(); /* set up array for port data */ mz = rte_memzone_reserve(MZ_PORT_INFO, sizeof(*ports), rte_socket_id(), NO_FLAGS); if (mz == NULL) rte_exit(EXIT_FAILURE, "Cannot reserve memory zone for port information\n"); memset(mz->addr, 0, sizeof(*ports)); ports = mz->addr; /* parse additional, application arguments */ retval = parse_app_args(total_ports, argc, argv); if (retval != 0) return -1; /* initialise mbuf pools */ retval = init_mbuf_pools(); if (retval != 0) rte_exit(EXIT_FAILURE, "Cannot create needed mbuf pools\n"); /* now initialise the ports we will use */ for (i = 0; i < ports->num_ports; i++) { retval = init_port(ports->id[i]); if (retval != 0) rte_exit(EXIT_FAILURE, "Cannot initialise port %u\n", (unsigned)i); } check_all_ports_link_status(ports->num_ports, (~0x0)); /* initialise the client queues/rings for inter-eu comms */ init_shm_rings(); return 0; }
/* Main function */ int main(int argc, char **argv) { int ret; int i; /* Create handler for SIGINT for CTRL + C closing and SIGALRM to print stats*/ signal(SIGINT, sig_handler); signal(SIGALRM, alarm_routine); /* Initialize DPDK enviroment with args, then shift argc and argv to get application parameters */ ret = rte_eal_init(argc, argv); if (ret < 0) FATAL_ERROR("Cannot init EAL\n"); argc -= ret; argv += ret; /* Check if this application can use 1 core*/ ret = rte_lcore_count (); if (ret != 2) FATAL_ERROR("This application needs exactly 2 cores."); /* Parse arguments */ parse_args(argc, argv); if (ret < 0) FATAL_ERROR("Wrong arguments\n"); /* Probe PCI bus for ethernet devices, mandatory only in DPDK < 1.8.0 */ #if RTE_VER_MAJOR == 1 && RTE_VER_MINOR < 8 ret = rte_eal_pci_probe(); if (ret < 0) FATAL_ERROR("Cannot probe PCI\n"); #endif /* Get number of ethernet devices */ nb_sys_ports = rte_eth_dev_count(); if (nb_sys_ports <= 0) FATAL_ERROR("Cannot find ETH devices\n"); /* Create a mempool with per-core cache, initializing every element for be used as mbuf, and allocating on the current NUMA node */ pktmbuf_pool = rte_mempool_create(MEMPOOL_NAME, buffer_size-1, MEMPOOL_ELEM_SZ, MEMPOOL_CACHE_SZ, sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,rte_socket_id(), 0); if (pktmbuf_pool == NULL) FATAL_ERROR("Cannot create cluster_mem_pool. Errno: %d [ENOMEM: %d, ENOSPC: %d, E_RTE_NO_TAILQ: %d, E_RTE_NO_CONFIG: %d, E_RTE_SECONDARY: %d, EINVAL: %d, EEXIST: %d]\n", rte_errno, ENOMEM, ENOSPC, E_RTE_NO_TAILQ, E_RTE_NO_CONFIG, E_RTE_SECONDARY, EINVAL, EEXIST ); /* Create a ring for exchanging packets between cores, and allocating on the current NUMA node */ intermediate_ring = rte_ring_create (RING_NAME, buffer_size, rte_socket_id(), RING_F_SP_ENQ | RING_F_SC_DEQ ); if (intermediate_ring == NULL ) FATAL_ERROR("Cannot create ring"); /* Operations needed for each ethernet device */ for(i=0; i < nb_sys_ports; i++) init_port(i); /* Start consumer and producer routine on 2 different cores: producer launched first... */ ret = rte_eal_mp_remote_launch (main_loop_producer, NULL, SKIP_MASTER); if (ret != 0) FATAL_ERROR("Cannot start consumer thread\n"); /* ... and then loop in consumer */ main_loop_consumer ( NULL ); return 0; }
static inline int port_init(uint16_t port, struct rte_mempool *mbuf_pool) { struct rte_eth_conf port_conf = port_conf_default; const uint16_t rx_rings = 1, tx_rings = 1; int retval; uint16_t q; if (port >= rte_eth_dev_count()) return -1; /* Configure the Ethernet device. */ retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf); if (retval != 0) return retval; /* Allocate and set up 1 RX queue per Ethernet port. */ for (q = 0; q < rx_rings; q++) { retval = rte_eth_rx_queue_setup(port, q, RX_RING_SIZE, rte_eth_dev_socket_id(port), NULL, mbuf_pool); if (retval < 0) return retval; } /* Allocate and set up 1 TX queue per Ethernet port. */ for (q = 0; q < tx_rings; q++) { retval = rte_eth_tx_queue_setup(port, q, TX_RING_SIZE, rte_eth_dev_socket_id(port), NULL); if (retval < 0) return retval; } /* Start the Ethernet port. */ retval = rte_eth_dev_start(port); if (retval < 0) return retval; /* Display the port MAC address. */ struct ether_addr addr; rte_eth_macaddr_get(port, &addr); printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n", (unsigned int)port, addr.addr_bytes[0], addr.addr_bytes[1], addr.addr_bytes[2], addr.addr_bytes[3], addr.addr_bytes[4], addr.addr_bytes[5]); /* Enable RX in promiscuous mode for the Ethernet device. */ rte_eth_promiscuous_enable(port); return 0; }
/***************************************************************************** * tlkp_udp_lcore_init() ****************************************************************************/ void tlkp_udp_lcore_init(uint32_t lcore_id) { unsigned int i; RTE_PER_LCORE(tlkp_ucb_hash_table) = rte_zmalloc_socket("udp_hash_table", rte_eth_dev_count() * TPG_HASH_BUCKET_SIZE * sizeof(tlkp_hash_bucket_t), RTE_CACHE_LINE_SIZE, rte_lcore_to_socket_id(lcore_id)); if (RTE_PER_LCORE(tlkp_ucb_hash_table) == NULL) { TPG_ERROR_ABORT("[%d]: Failed to allocate per lcore udp htable!\n", rte_lcore_index(lcore_id)); } for (i = 0; i < (rte_eth_dev_count() * TPG_HASH_BUCKET_SIZE); i++) { /* * Initialize all list headers. */ LIST_INIT((&RTE_PER_LCORE(tlkp_ucb_hash_table)[i])); } }
int valid_port_id(uint8_t port_id) { /* Verify that port id is valid */ int ethdev_count = rte_eth_dev_count(); if (port_id >= ethdev_count) { RTE_BOND_LOG(ERR, "Port Id %d is greater than rte_eth_dev_count %d", port_id, ethdev_count); return -1; } return 0; }
static int kni_config_network_interface(uint8_t port_id, uint8_t if_up) { int ret = 0; if (port_id >= rte_eth_dev_count()) return -EINVAL; ret = (if_up) ? rte_eth_dev_set_link_up(port_id) : rte_eth_dev_set_link_down(port_id); return ret; }
/* * Initialises a given port using global settings and with the rx buffers * coming from the mbuf_pool passed as parameter */ static inline int port_init(uint8_t port, struct rte_mempool *mbuf_pool) { struct rte_eth_conf port_conf; const uint16_t rxRings = ETH_VMDQ_DCB_NUM_QUEUES, txRings = (uint16_t)rte_lcore_count(); const uint16_t rxRingSize = 128, txRingSize = 512; int retval; uint16_t q; retval = get_eth_conf(&port_conf, num_pools); if (retval < 0) return retval; if (port >= rte_eth_dev_count()) return -1; retval = rte_eth_dev_configure(port, rxRings, txRings, &port_conf); if (retval != 0) return retval; for (q = 0; q < rxRings; q ++) { retval = rte_eth_rx_queue_setup(port, q, rxRingSize, rte_eth_dev_socket_id(port), NULL, mbuf_pool); if (retval < 0) return retval; } for (q = 0; q < txRings; q ++) { retval = rte_eth_tx_queue_setup(port, q, txRingSize, rte_eth_dev_socket_id(port), NULL); if (retval < 0) return retval; } retval = rte_eth_dev_start(port); if (retval < 0) return retval; struct ether_addr addr; rte_eth_macaddr_get(port, &addr); printf("Port %u MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8 " %02"PRIx8" %02"PRIx8" %02"PRIx8"\n", (unsigned)port, addr.addr_bytes[0], addr.addr_bytes[1], addr.addr_bytes[2], addr.addr_bytes[3], addr.addr_bytes[4], addr.addr_bytes[5]); return 0; }
/* * The lcore main. This is the main thread that does the work, reading from * an input port and writing to an output port. */ static __attribute__((noreturn)) void lcore_main(void) { const uint8_t nb_ports = rte_eth_dev_count(); uint8_t port; /* * Check that the port is on the same NUMA node as the polling thread * for best performance. */ for (port = 0; port < nb_ports; port++) if (rte_eth_dev_socket_id(port) > 0 && rte_eth_dev_socket_id(port) != (int)rte_socket_id()) printf("WARNING, port %u is on remote NUMA node to " "polling thread.\n\tPerformance will " "not be optimal.\n", port); printf("\nCore %u forwarding packets. [Ctrl+C to quit]\n", rte_lcore_id()); /* Run until the application is quit or killed. */ for (;;) { /* * Receive packets on a port and forward them on the paired * port. The mapping is 0 -> 1, 1 -> 0, 2 -> 3, 3 -> 2, etc. */ for (port = 0; port < nb_ports; port++) { /* Get burst of RX packets, from first port of pair. */ struct rte_mbuf *bufs[BURST_SIZE]; const uint16_t nb_rx = rte_eth_rx_burst(port, 0, bufs, BURST_SIZE); if (unlikely(nb_rx == 0)) continue; /* Send burst of TX packets, to second port of pair. */ const uint16_t nb_tx = rte_eth_tx_burst(port ^ 1, 0, bufs, nb_rx); /* Free any unsent packets. */ if (unlikely(nb_tx < nb_rx)) { uint16_t buf; for (buf = nb_tx; buf < nb_rx; buf++) rte_pktmbuf_free(bufs[buf]); } } } }
static inline int find_port_id_by_dev_name(const char *name) { unsigned i; for (i = 0; i < rte_eth_dev_count(); i++) { if (rte_eth_devices[i].data == NULL) continue; if (strcmp(rte_eth_devices[i].device->name, name) == 0) return i; } return -1; }
int32_t interfaceSetup(void) { uint8_t portIndex = 0, portCount = rte_eth_dev_count(); int32_t ret = 0, socket_id = -1; struct rte_eth_link link; for (portIndex = 0; portIndex < portCount; portIndex++) { /* fetch the socket Id to which the port the mapped */ for (ret = 0; ret < GTP_MAX_NUMANODE; ret++) { if (numaNodeInfo[ret].intfTotal) { if (numaNodeInfo[ret].intfAvail & (1 << portIndex)) { socket_id = ret; break; } } } memset(&link, 0x00, sizeof(struct rte_eth_link)); ret = rte_eth_dev_configure(portIndex, 1, 1, &portConf); if (unlikely(ret < 0)) { rte_panic("ERROR: Dev Configure\n"); return -1; } ret = rte_eth_rx_queue_setup(portIndex, 0, RTE_TEST_RX_DESC_DEFAULT, 0, NULL, numaNodeInfo[socket_id].rx[0]); if (unlikely(ret < 0)) { rte_panic("ERROR: Rx Queue Setup\n"); return -2; } ret = rte_eth_tx_queue_setup(portIndex, 0, RTE_TEST_TX_DESC_DEFAULT, 0, NULL); if (unlikely(ret < 0)) { rte_panic("ERROR: Tx Queue Setup\n"); return -3; } rte_eth_promiscuous_enable(portIndex); rte_eth_dev_start(portIndex); } return 0; }
/* initialize rte devices and check the number of available ports */ static uint8_t init_rte_dev(void) { uint8_t nb_ports; struct rte_eth_dev_info dev_info; /* initialize driver(s) */ TGEN_PANIC(rte_ixgbe_pmd_init() < 0, "\tError: Cannot init ixgbe pmd\n"); if (tgen_cfg.flags & TGSF_USE_VF) { TGEN_PANIC(rte_ixgbevf_pmd_init() < 0, "\tError: cannot init ixgbevf pmd\n"); } TGEN_PANIC(rte_eal_pci_probe() < 0, "\tError: Cannot probe PCI\n"); /* get available ports configuration */ nb_ports = rte_eth_dev_count(); TGEN_PANIC(nb_ports == 0, "\tError: DPDK could not find any port\n"); mprintf("\tDPDK has found %u ports\n", nb_ports); if (nb_ports > TGEN_MAX_PORTS) { mprintf("\tWarning: I can deal with at most %u ports." " Please update TGEN_MAX_PORTS and recompile.\n", TGEN_MAX_PORTS); nb_ports = TGEN_MAX_PORTS; } TGEN_PANIC(tgen_used_port_mask & ~((1U << nb_ports) - 1), "\tError: invalid port(s) specified, used port mask is %#10x\n", tgen_used_port_mask); /* read max TX queues per port */ for (uint8_t port_id = 0; port_id < nb_ports; ++port_id) { /* skip ports that are not enabled */ if ((tgen_used_port_mask & (1U << port_id)) == 0) { continue; } rte_eth_dev_info_get(port_id, &dev_info); tgen_port_conf[port_id].max_tx_queue = dev_info.max_tx_queues; mprintf("\tPort %u, Max TX queue = %u\n", port_id, dev_info.max_tx_queues); if (strcmp(dev_info.driver_name, "rte_ixgbe_pmd") == 0) { tgen_port_conf[port_id].type = PORT_IXGBE; } else { tgen_port_conf[port_id].type = PORT_IGB; } } return nb_ports; }
static void slave_port_init(uint16_t portid, struct rte_mempool *mbuf_pool) { int retval; uint16_t nb_rxd = RTE_RX_DESC_DEFAULT; uint16_t nb_txd = RTE_TX_DESC_DEFAULT; if (portid >= rte_eth_dev_count()) rte_exit(EXIT_FAILURE, "Invalid port\n"); retval = rte_eth_dev_configure(portid, 1, 1, &port_conf); if (retval != 0) rte_exit(EXIT_FAILURE, "port %u: configuration failed (res=%d)\n", portid, retval); retval = rte_eth_dev_adjust_nb_rx_tx_desc(portid, &nb_rxd, &nb_txd); if (retval != 0) rte_exit(EXIT_FAILURE, "port %u: rte_eth_dev_adjust_nb_rx_tx_desc " "failed (res=%d)\n", portid, retval); /* RX setup */ retval = rte_eth_rx_queue_setup(portid, 0, nb_rxd, rte_eth_dev_socket_id(portid), NULL, mbuf_pool); if (retval < 0) rte_exit(retval, " port %u: RX queue 0 setup failed (res=%d)", portid, retval); /* TX setup */ retval = rte_eth_tx_queue_setup(portid, 0, nb_txd, rte_eth_dev_socket_id(portid), NULL); if (retval < 0) rte_exit(retval, "port %u: TX queue 0 setup failed (res=%d)", portid, retval); retval = rte_eth_dev_start(portid); if (retval < 0) rte_exit(retval, "Start port %d failed (res=%d)", portid, retval); struct ether_addr addr; rte_eth_macaddr_get(portid, &addr); printf("Port %u MAC: ", portid); PRINT_MAC(addr); printf("\n"); }
/* * The main function, which does initialization and calls the per-lcore * functions. */ int main(int argc, char *argv[]) { struct rte_mempool *mbuf_pool; unsigned nb_ports; uint8_t portid; /* Initialize the Environment Abstraction Layer (EAL). */ int ret = rte_eal_init(argc, argv); if (ret < 0) rte_exit(EXIT_FAILURE, "Error with EAL initialization\n"); argc -= ret; argv += ret; /* Check that there is an even number of ports to send/receive on. */ nb_ports = rte_eth_dev_count(); if (nb_ports < 2 || (nb_ports & 1)) rte_exit(EXIT_FAILURE, "Error: number of ports must be even\n"); /* Creates a new mempool in memory to hold the mbufs. */ mbuf_pool = rte_mempool_create("MBUF_POOL", NUM_MBUFS * nb_ports, MBUF_SIZE, MBUF_CACHE_SIZE, sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL, rte_socket_id(), 0); if (mbuf_pool == NULL) rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n"); /* Initialize all ports. */ for (portid = 0; portid < nb_ports; portid++) if (port_init(portid, mbuf_pool) != 0) rte_exit(EXIT_FAILURE, "Cannot init port %"PRIu8 "\n", portid); if (rte_lcore_count() > 1) printf("\nWARNING: Too many lcores enabled. Only 1 used.\n"); /* Call lcore_main on the master core only. */ lcore_main(); return 0; }
static int setup_and_bond_ports(struct rte_mempool *mp) { int portid, queueid; int ret; int pl_idx; int nb_queue; nb_queue = rte_lcore_count(); nb_port = rte_eth_dev_count(); memset(lcore_args, 0, sizeof(struct lcore_arg_t) * RTE_MAX_LCORE); for(portid = 0; portid < nb_port; portid++) { ret = rte_eth_dev_configure(portid, nb_queue, nb_queue, &port_conf); if(unlikely(ret < 0)) { rte_exit(EINVAL, "port %d configure failed!\n", portid); } for(queueid = 0; queueid < nb_queue; queueid++) { ret = rte_eth_rx_queue_setup(portid, queueid, NB_RXD, rte_socket_id(), NULL, mp); if(unlikely(ret < 0)) { rte_exit(EINVAL, "port %d rx queue %d setup failed!\n", portid, queueid); } ret = rte_eth_tx_queue_setup(portid, queueid, NB_TXD, rte_socket_id(), NULL); if(unlikely(ret < 0)) { rte_exit(EINVAL, "port %d tx queue %d setup failed!\n", portid, queueid); } pl_idx = lcore_args[queueid].pl_len; lcore_args[queueid].pl[pl_idx].portid = portid; lcore_args[queueid].pl[pl_idx].queueid = queueid; lcore_args[queueid].mp = mp; lcore_args[queueid].pl_len = pl_idx + 1; } ret = rte_eth_dev_start(portid); if(unlikely(ret < 0)) { rte_exit(EINVAL, "port %d start failed!\n", portid); } rte_eth_promiscuous_enable(portid); } return 0; }
/* * Initialises a given port using global settings and with the rx buffers * coming from the mbuf_pool passed as parameter */ static inline int port_init(uint8_t port, struct rte_mempool *mbuf_pool) { struct rte_eth_conf port_conf = port_conf_default; const uint16_t rx_rings = 1, tx_rings = 1; int retval; uint16_t q; if (port >= rte_eth_dev_count()) return -1; retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf); if (retval != 0) return retval; for (q = 0; q < rx_rings; q++) { retval = rte_eth_rx_queue_setup(port, q, RX_RING_SIZE, rte_eth_dev_socket_id(port), NULL, mbuf_pool); if (retval < 0) return retval; } for (q = 0; q < tx_rings; q++) { retval = rte_eth_tx_queue_setup(port, q, TX_RING_SIZE, rte_eth_dev_socket_id(port), NULL); if (retval < 0) return retval; } retval = rte_eth_dev_start(port); if (retval < 0) return retval; struct ether_addr addr; rte_eth_macaddr_get(port, &addr); printf("Port %u MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8 " %02"PRIx8" %02"PRIx8" %02"PRIx8"\n", (unsigned)port, addr.addr_bytes[0], addr.addr_bytes[1], addr.addr_bytes[2], addr.addr_bytes[3], addr.addr_bytes[4], addr.addr_bytes[5]); rte_eth_promiscuous_enable(port); return 0; }
static inline int configure_eth_port(uint8_t port_id) { struct ether_addr addr; const uint16_t rxRings = 1, txRings = 1; const uint8_t nb_ports = rte_eth_dev_count(); int ret; uint16_t q; if (port_id > nb_ports) return -1; ret = rte_eth_dev_configure(port_id, rxRings, txRings, &port_conf_default); if (ret != 0) return ret; for (q = 0; q < rxRings; q++) { ret = rte_eth_rx_queue_setup(port_id, q, RX_DESC_PER_QUEUE, rte_eth_dev_socket_id(port_id), NULL, mbuf_pool); if (ret < 0) return ret; } for (q = 0; q < txRings; q++) { ret = rte_eth_tx_queue_setup(port_id, q, TX_DESC_PER_QUEUE, rte_eth_dev_socket_id(port_id), NULL); if (ret < 0) return ret; } ret = rte_eth_dev_start(port_id); if (ret < 0) return ret; rte_eth_macaddr_get(port_id, &addr); printf("Port %u MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8 " %02"PRIx8" %02"PRIx8" %02"PRIx8"\n", (unsigned)port_id, addr.addr_bytes[0], addr.addr_bytes[1], addr.addr_bytes[2], addr.addr_bytes[3], addr.addr_bytes[4], addr.addr_bytes[5]); rte_eth_promiscuous_enable(port_id); return 0; }
/* Callback for request of changing MTU */ static int kni_change_mtu(uint8_t port_id, unsigned new_mtu) { int ret; uint16_t nb_rx_queue; struct rte_eth_conf conf; if (port_id >= rte_eth_dev_count()) { RTE_LOG(ERR, KNI, "Invalid port id %d\n", port_id); return -EINVAL; } RTE_LOG(INFO, KNI, "-----------------Change MTU of port %d to %u\n", port_id, new_mtu); /* Stop specific port */ rte_eth_dev_stop(port_id); memcpy(&conf, &port_conf, sizeof(conf)); /* Set new MTU */ if (new_mtu > ETHER_MAX_LEN) conf.rxmode.jumbo_frame = 1; else conf.rxmode.jumbo_frame = 0; /* mtu + length of header + length of FCS = max pkt length */ conf.rxmode.max_rx_pkt_len = new_mtu + KNI_ENET_HEADER_SIZE + KNI_ENET_FCS_SIZE; nb_rx_queue = get_port_n_rx_queues(port_id); // XXX nb_rx_queue +1 for the kni ret = rte_eth_dev_configure(port_id, nb_rx_queue, nb_rx_queue + 1, &conf); if (ret < 0) { RTE_LOG(ERR, KNI, "Fail to reconfigure port %d\n", port_id); return ret; } /* Restart specific port */ ret = rte_eth_dev_start(port_id); if (ret < 0) { RTE_LOG(ERR, KNI, "Fail to restart port %d\n", port_id); return ret; } return 0; }