static struct rte_eth_conf port_conf = {
.rxmode = {
- .mq_mode = ETH_MQ_RX_RSS,
- .max_rx_pkt_len = RTE_ETHER_MAX_LEN,
+ .mq_mode = RTE_ETH_MQ_RX_RSS,
.split_hdr_size = 0,
},
.rx_adv_conf = {
.rss_conf = {
.rss_key = NULL,
- .rss_hf = ETH_RSS_IP,
+ .rss_hf = RTE_ETH_RSS_IP,
},
},
.txmode = {
- .mq_mode = ETH_MQ_TX_NONE,
+ .mq_mode = RTE_ETH_MQ_TX_NONE,
},
};
+static uint32_t max_pkt_len;
+
static struct rte_mempool *pktmbuf_pool[RTE_MAX_ETHPORTS][NB_SOCKETS];
static struct rte_node_ethdev_config ethdev_conf[RTE_MAX_ETHPORTS];
return -1;
}
- if (lcore == rte_get_master_lcore()) {
- printf("Error: lcore %u is master lcore\n", lcore);
+ if (lcore == rte_get_main_lcore()) {
+ printf("Error: lcore %u is main lcore\n", lcore);
return -1;
}
socketid = rte_lcore_to_socket_id(lcore);
" [-P]"
" --config (port,queue,lcore)[,(port,queue,lcore)]"
" [--eth-dest=X,MM:MM:MM:MM:MM:MM]"
- " [--enable-jumbo [--max-pkt-len PKTLEN]]"
+ " [--max-pkt-len PKTLEN]"
" [--no-numa]"
" [--per-port-pool]\n\n"
" --config (port,queue,lcore): Rx queue configuration\n"
" --eth-dest=X,MM:MM:MM:MM:MM:MM: Ethernet destination for "
"port X\n"
- " --enable-jumbo: Enable jumbo frames\n"
- " --max-pkt-len: Under the premise of enabling jumbo,\n"
- " maximum packet length in decimal (64-9600)\n"
+ " --max-pkt-len PKTLEN: maximum packet length in decimal (64-9600)\n"
" --no-numa: Disable numa awareness\n"
" --per-port-pool: Use separate buffer pool per port\n\n",
prgname);
/* Parse hexadecimal string */
pm = strtoul(portmask, &end, 16);
if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0'))
- return -1;
-
- if (pm == 0)
- return -1;
+ return 0;
return pm;
}
#define CMD_LINE_OPT_CONFIG "config"
#define CMD_LINE_OPT_ETH_DEST "eth-dest"
#define CMD_LINE_OPT_NO_NUMA "no-numa"
-#define CMD_LINE_OPT_ENABLE_JUMBO "enable-jumbo"
+#define CMD_LINE_OPT_MAX_PKT_LEN "max-pkt-len"
#define CMD_LINE_OPT_PER_PORT_POOL "per-port-pool"
enum {
/* Long options mapped to a short option */
CMD_LINE_OPT_CONFIG_NUM,
CMD_LINE_OPT_ETH_DEST_NUM,
CMD_LINE_OPT_NO_NUMA_NUM,
- CMD_LINE_OPT_ENABLE_JUMBO_NUM,
+ CMD_LINE_OPT_MAX_PKT_LEN_NUM,
CMD_LINE_OPT_PARSE_PER_PORT_POOL,
};
{CMD_LINE_OPT_CONFIG, 1, 0, CMD_LINE_OPT_CONFIG_NUM},
{CMD_LINE_OPT_ETH_DEST, 1, 0, CMD_LINE_OPT_ETH_DEST_NUM},
{CMD_LINE_OPT_NO_NUMA, 0, 0, CMD_LINE_OPT_NO_NUMA_NUM},
- {CMD_LINE_OPT_ENABLE_JUMBO, 0, 0, CMD_LINE_OPT_ENABLE_JUMBO_NUM},
+ {CMD_LINE_OPT_MAX_PKT_LEN, 1, 0, CMD_LINE_OPT_MAX_PKT_LEN_NUM},
{CMD_LINE_OPT_PER_PORT_POOL, 0, 0, CMD_LINE_OPT_PARSE_PER_PORT_POOL},
{NULL, 0, 0, 0},
};
numa_on = 0;
break;
- case CMD_LINE_OPT_ENABLE_JUMBO_NUM: {
- const struct option lenopts = {"max-pkt-len",
- required_argument, 0, 0};
-
- port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME;
- port_conf.txmode.offloads |= DEV_TX_OFFLOAD_MULTI_SEGS;
-
- /*
- * if no max-pkt-len set, use the default
- * value RTE_ETHER_MAX_LEN.
- */
- if (getopt_long(argc, argvopt, "", &lenopts,
- &option_index) == 0) {
- ret = parse_max_pkt_len(optarg);
- if (ret < 64 || ret > MAX_JUMBO_PKT_LEN) {
- fprintf(stderr, "Invalid maximum "
- "packet length\n");
- print_usage(prgname);
- return -1;
- }
- port_conf.rxmode.max_rx_pkt_len = ret;
- }
+ case CMD_LINE_OPT_MAX_PKT_LEN_NUM: {
+ max_pkt_len = parse_max_pkt_len(optarg);
break;
}
uint8_t count, all_ports_up, print_flag = 0;
struct rte_eth_link link;
uint16_t portid;
+ int ret;
+ char link_status_text[RTE_ETH_LINK_MAX_STR_LEN];
printf("\nChecking link status");
fflush(stdout);
if ((port_mask & (1 << portid)) == 0)
continue;
memset(&link, 0, sizeof(link));
- rte_eth_link_get_nowait(portid, &link);
+ ret = rte_eth_link_get_nowait(portid, &link);
+ if (ret < 0) {
+ all_ports_up = 0;
+ if (print_flag == 1)
+ printf("Port %u link get failed: %s\n",
+ portid, rte_strerror(-ret));
+ continue;
+ }
/* Print link status if flag set */
if (print_flag == 1) {
- if (link.link_status)
- printf("Port%d Link Up. Speed %u Mbps "
- "-%s\n",
- portid, link.link_speed,
- (link.link_duplex ==
- ETH_LINK_FULL_DUPLEX)
- ? ("full-duplex")
- : ("half-duplex\n"));
- else
- printf("Port %d Link Down\n", portid);
+ rte_eth_link_to_str(link_status_text,
+ sizeof(link_status_text), &link);
+ printf("Port %d %s\n", portid,
+ link_status_text);
continue;
}
/* Clear all_ports_up flag if any link down */
- if (link.link_status == ETH_LINK_DOWN) {
+ if (link.link_status == RTE_ETH_LINK_DOWN) {
all_ports_up = 0;
break;
}
rte_graph_cluster_stats_destroy(stats);
}
-/* Main processing loop */
+/* Main processing loop. 8< */
static int
graph_main_loop(void *conf)
{
return 0;
}
+/* >8 End of main processing loop. */
+
+static uint32_t
+eth_dev_get_overhead_len(uint32_t max_rx_pktlen, uint16_t max_mtu)
+{
+ uint32_t overhead_len;
+
+ if (max_mtu != UINT16_MAX && max_rx_pktlen > max_mtu)
+ overhead_len = max_rx_pktlen - max_mtu;
+ else
+ overhead_len = RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN;
+
+ return overhead_len;
+}
+
+static int
+config_port_max_pkt_len(struct rte_eth_conf *conf,
+ struct rte_eth_dev_info *dev_info)
+{
+ uint32_t overhead_len;
+
+ if (max_pkt_len == 0)
+ return 0;
+
+ if (max_pkt_len < RTE_ETHER_MIN_LEN || max_pkt_len > MAX_JUMBO_PKT_LEN)
+ return -1;
+
+ overhead_len = eth_dev_get_overhead_len(dev_info->max_rx_pktlen,
+ dev_info->max_mtu);
+ conf->rxmode.mtu = max_pkt_len - overhead_len;
+
+ if (conf->rxmode.mtu > RTE_ETHER_MTU)
+ conf->txmode.offloads |= RTE_ETH_TX_OFFLOAD_MULTI_SEGS;
+
+ return 0;
+}
int
main(int argc, char **argv)
{
/* Rewrite data of src and dst ether addr */
uint8_t rewrite_data[2 * sizeof(struct rte_ether_addr)];
+ /* Graph initialization. 8< */
static const char * const default_patterns[] = {
"ip4*",
"ethdev_tx-*",
nb_ports = rte_eth_dev_count_avail();
nb_lcores = rte_lcore_count();
- /* Initialize all ports */
+ /* Initialize all ports. 8< */
RTE_ETH_FOREACH_DEV(portid)
{
struct rte_eth_conf local_port_conf = port_conf;
nb_rx_queue, n_tx_queue);
rte_eth_dev_info_get(portid, &dev_info);
- if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
+
+ ret = config_port_max_pkt_len(&local_port_conf, &dev_info);
+ if (ret != 0)
+ rte_exit(EXIT_FAILURE,
+ "Invalid max packet length: %u (port %u)\n",
+ max_pkt_len, portid);
+
+ if (dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE)
local_port_conf.txmode.offloads |=
- DEV_TX_OFFLOAD_MBUF_FAST_FREE;
+ RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;
local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
dev_info.flow_type_rss_offloads;
/* Ethdev node config, skip rx queue mapping */
ret = rte_node_eth_config(ethdev_conf, nb_conf, nb_graphs);
+ /* >8 End of graph creation. */
if (ret)
rte_exit(EXIT_FAILURE, "rte_node_eth_config: err=%d\n", ret);
qconf->graph_id = graph_id;
qconf->graph = rte_graph_lookup(qconf->name);
+ /* >8 End of graph initialization. */
if (!qconf->graph)
rte_exit(EXIT_FAILURE,
"rte_graph_lookup(): graph %s not found\n",
memset(&rewrite_data, 0, sizeof(rewrite_data));
rewrite_len = sizeof(rewrite_data);
- /* Add route to ip4 graph infra */
+ /* Add route to ip4 graph infra. 8< */
for (i = 0; i < IPV4_L3FWD_LPM_NUM_ROUTES; i++) {
char route_str[INET6_ADDRSTRLEN * 4];
char abuf[INET6_ADDRSTRLEN];
RTE_LOG(INFO, L3FWD_GRAPH, "Added route %s, next_hop %u\n",
route_str, i);
}
+ /* >8 End of adding route to ip4 graph infa. */
- /* Launch per-lcore init on every slave lcore */
- rte_eal_mp_remote_launch(graph_main_loop, NULL, SKIP_MASTER);
+ /* Launch per-lcore init on every worker lcore */
+ rte_eal_mp_remote_launch(graph_main_loop, NULL, SKIP_MAIN);
- /* Accumulate and print stats on master until exit */
+ /* Accumulate and print stats on main until exit */
if (rte_graph_has_stats_feature())
print_stats();
- /* Wait for slave cores to exit */
+ /* Wait for worker cores to exit */
ret = 0;
- RTE_LCORE_FOREACH_SLAVE(lcore_id) {
+ RTE_LCORE_FOREACH_WORKER(lcore_id) {
ret = rte_eal_wait_lcore(lcore_id);
/* Destroy graph */
if (ret < 0 || rte_graph_destroy(
if ((enabled_port_mask & (1 << portid)) == 0)
continue;
printf("Closing port %d...", portid);
- rte_eth_dev_stop(portid);
+ ret = rte_eth_dev_stop(portid);
+ if (ret != 0)
+ printf("Failed to stop port %u: %s\n",
+ portid, rte_strerror(-ret));
rte_eth_dev_close(portid);
printf(" Done\n");
}
+
+ /* clean up the EAL */
+ rte_eal_cleanup();
printf("Bye...\n");
return ret;