13998e2a0SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 29510dd1fSConor Walsh * Copyright(c) 2010-2021 Intel Corporation 3af75078fSIntel */ 4af75078fSIntel 5af75078fSIntel #include <stdio.h> 6af75078fSIntel #include <stdlib.h> 7af75078fSIntel #include <stdint.h> 8af75078fSIntel #include <inttypes.h> 9af75078fSIntel #include <sys/types.h> 10af75078fSIntel #include <string.h> 11af75078fSIntel #include <sys/queue.h> 12af75078fSIntel #include <stdarg.h> 13af75078fSIntel #include <errno.h> 14af75078fSIntel #include <getopt.h> 15308df2bfSZhihong Wang #include <signal.h> 16308df2bfSZhihong Wang #include <stdbool.h> 17d5c4897eSJie Hai #include <assert.h> 18af75078fSIntel 19af75078fSIntel #include <rte_common.h> 201e496d6fSKonstantin Ananyev #include <rte_vect.h> 21af75078fSIntel #include <rte_byteorder.h> 22af75078fSIntel #include <rte_log.h> 23e2de1f7bSSunil Kumar Kori #include <rte_malloc.h> 24af75078fSIntel #include <rte_memory.h> 25af75078fSIntel #include <rte_memcpy.h> 26af75078fSIntel #include <rte_eal.h> 27af75078fSIntel #include <rte_launch.h> 28af75078fSIntel #include <rte_cycles.h> 29af75078fSIntel #include <rte_prefetch.h> 30af75078fSIntel #include <rte_lcore.h> 31af75078fSIntel #include <rte_per_lcore.h> 32af75078fSIntel #include <rte_branch_prediction.h> 33af75078fSIntel #include <rte_interrupts.h> 34af75078fSIntel #include <rte_random.h> 35af75078fSIntel #include <rte_debug.h> 36af75078fSIntel #include <rte_ether.h> 37af75078fSIntel #include <rte_mempool.h> 38af75078fSIntel #include <rte_mbuf.h> 39af75078fSIntel #include <rte_ip.h> 40af75078fSIntel #include <rte_tcp.h> 41af75078fSIntel #include <rte_udp.h> 42af75078fSIntel #include <rte_string_fns.h> 43268888b5SRavi Kerur #include <rte_cpuflags.h> 44af75078fSIntel 45bd785f6fSAndrey Chilikin #include <cmdline_parse.h> 46bd785f6fSAndrey Chilikin #include <cmdline_parse_etheraddr.h> 47bd785f6fSAndrey Chilikin 48268888b5SRavi Kerur #include "l3fwd.h" 49e2de1f7bSSunil Kumar Kori #include "l3fwd_event.h" 50da796d27SConor Walsh #include "l3fwd_route.h" 5196ff4453SKonstantin Ananyev 5288256ed8SHarman Kalra #define MAX_TX_QUEUE_PER_PORT RTE_MAX_LCORE 53af75078fSIntel #define MAX_RX_QUEUE_PER_PORT 128 54af75078fSIntel 55af75078fSIntel #define MAX_LCORE_PARAMS 1024 56268888b5SRavi Kerur 57d5c4897eSJie Hai static_assert(MEMPOOL_CACHE_SIZE >= MAX_PKT_BURST, "MAX_PKT_BURST should be at most MEMPOOL_CACHE_SIZE"); 584ed89049SDavid Marchand uint16_t nb_rxd = RX_DESC_DEFAULT; 594ed89049SDavid Marchand uint16_t nb_txd = TX_DESC_DEFAULT; 60d5c4897eSJie Hai uint32_t nb_pkt_per_burst = DEFAULT_PKT_BURST; 61*d9f26e52SJie Hai uint32_t mb_mempool_cache_size = MEMPOOL_CACHE_SIZE; 62268888b5SRavi Kerur 63268888b5SRavi Kerur /**< Ports set in promiscuous mode off by default. */ 64268888b5SRavi Kerur static int promiscuous_on; 65268888b5SRavi Kerur 666de0ea50SSean Morrissey /* Select Longest-Prefix, Exact match, Forwarding Information Base or Access Control. */ 679510dd1fSConor Walsh enum L3FWD_LOOKUP_MODE { 689510dd1fSConor Walsh L3FWD_LOOKUP_DEFAULT, 699510dd1fSConor Walsh L3FWD_LOOKUP_LPM, 709510dd1fSConor Walsh L3FWD_LOOKUP_EM, 716de0ea50SSean Morrissey L3FWD_LOOKUP_FIB, 726de0ea50SSean Morrissey L3FWD_LOOKUP_ACL 739510dd1fSConor Walsh }; 749510dd1fSConor Walsh static enum L3FWD_LOOKUP_MODE lookup_mode; 75268888b5SRavi Kerur 76f0a26885SShreyansh Jain /* Global variables. */ 77268888b5SRavi Kerur static int numa_on = 1; /**< NUMA is enabled by default. */ 7871a7e242SJianfeng Tan static int parse_ptype; /**< Parse packet type using rx callback, and */ 7971a7e242SJianfeng Tan /**< disabled by default */ 80f9800c32STrevor Tao static int disable_rss; /**< Disable RSS mode */ 814b01cabfSTrevor Tao static int relax_rx_offload; /**< Relax Rx offload mode, disabled by default */ 82f0a26885SShreyansh Jain static int per_port_pool; /**< Use separate buffer pools per port; disabled */ 83f0a26885SShreyansh Jain /**< by default */ 84268888b5SRavi Kerur 85268888b5SRavi Kerur volatile bool force_quit; 86268888b5SRavi Kerur 87268888b5SRavi Kerur /* ethernet addresses of ports */ 88268888b5SRavi Kerur uint64_t dest_eth_addr[RTE_MAX_ETHPORTS]; 896d13ea8eSOlivier Matz struct rte_ether_addr ports_eth_addr[RTE_MAX_ETHPORTS]; 90268888b5SRavi Kerur 9164d3955dSMaciej Czekaj xmm_t val_eth[RTE_MAX_ETHPORTS]; 92268888b5SRavi Kerur 93268888b5SRavi Kerur /* mask of enabled ports */ 94268888b5SRavi Kerur uint32_t enabled_port_mask; 95268888b5SRavi Kerur 96268888b5SRavi Kerur /* Used only in exact match mode. */ 97268888b5SRavi Kerur int ipv6; /**< ipv6 is false by default. */ 98268888b5SRavi Kerur 99268888b5SRavi Kerur struct lcore_conf lcore_conf[RTE_MAX_LCORE]; 100268888b5SRavi Kerur 10152def963SSean Morrissey struct parm_cfg parm_config; 10252def963SSean Morrissey 1037e06c0deSTyler Retzlaff struct __rte_cache_aligned lcore_params { 104f8244c63SZhiyong Yang uint16_t port_id; 105b23c5bd7SSivaprasad Tummala uint16_t queue_id; 1064b978938SSivaprasad Tummala uint32_t lcore_id; 1077e06c0deSTyler Retzlaff }; 108af75078fSIntel 109af75078fSIntel static struct lcore_params lcore_params_array[MAX_LCORE_PARAMS]; 110af75078fSIntel static struct lcore_params lcore_params_array_default[] = { 111af75078fSIntel {0, 0, 2}, 112af75078fSIntel {0, 1, 2}, 113af75078fSIntel {0, 2, 2}, 114af75078fSIntel {1, 0, 2}, 115af75078fSIntel {1, 1, 2}, 116af75078fSIntel {1, 2, 2}, 117af75078fSIntel {2, 0, 2}, 118af75078fSIntel {3, 0, 3}, 119af75078fSIntel {3, 1, 3}, 120af75078fSIntel }; 121af75078fSIntel 122af75078fSIntel static struct lcore_params * lcore_params = lcore_params_array_default; 123af75078fSIntel static uint16_t nb_lcore_params = sizeof(lcore_params_array_default) / 124af75078fSIntel sizeof(lcore_params_array_default[0]); 125af75078fSIntel 126af75078fSIntel static struct rte_eth_conf port_conf = { 127af75078fSIntel .rxmode = { 128295968d1SFerruh Yigit .mq_mode = RTE_ETH_MQ_RX_RSS, 129295968d1SFerruh Yigit .offloads = RTE_ETH_RX_OFFLOAD_CHECKSUM, 130af75078fSIntel }, 131af75078fSIntel .rx_adv_conf = { 132af75078fSIntel .rss_conf = { 133af75078fSIntel .rss_key = NULL, 134295968d1SFerruh Yigit .rss_hf = RTE_ETH_RSS_IP, 135af75078fSIntel }, 136af75078fSIntel }, 137af75078fSIntel .txmode = { 138295968d1SFerruh Yigit .mq_mode = RTE_ETH_MQ_TX_NONE, 139af75078fSIntel }, 140af75078fSIntel }; 141af75078fSIntel 1423f045555SNithin Dabilpuram uint32_t max_pkt_len; 1431bb4a528SFerruh Yigit 144ef827078SBruce Richardson #ifdef RTE_LIB_EVENTDEV 145e8adca19SShijith Thotton static struct rte_mempool *vector_pool[RTE_MAX_ETHPORTS]; 146ef827078SBruce Richardson #endif 147ef827078SBruce Richardson static struct rte_mempool *pktmbuf_pool[RTE_MAX_ETHPORTS][NB_SOCKETS]; 148f0a26885SShreyansh Jain static uint8_t lkp_per_socket[NB_SOCKETS]; 149af75078fSIntel 150268888b5SRavi Kerur struct l3fwd_lkp_mode { 15152def963SSean Morrissey void (*read_config_files)(void); 152268888b5SRavi Kerur void (*setup)(int); 15371a7e242SJianfeng Tan int (*check_ptype)(int); 15471a7e242SJianfeng Tan rte_rx_callback_fn cb_parse_ptype; 155268888b5SRavi Kerur int (*main_loop)(void *); 156268888b5SRavi Kerur void* (*get_ipv4_lookup_struct)(int); 157268888b5SRavi Kerur void* (*get_ipv6_lookup_struct)(int); 15852def963SSean Morrissey void (*free_routes)(void); 159997ee890SIntel }; 160997ee890SIntel 161268888b5SRavi Kerur static struct l3fwd_lkp_mode l3fwd_lkp; 162997ee890SIntel 163268888b5SRavi Kerur static struct l3fwd_lkp_mode l3fwd_em_lkp = { 16452def963SSean Morrissey .read_config_files = read_config_files_em, 165268888b5SRavi Kerur .setup = setup_hash, 16671a7e242SJianfeng Tan .check_ptype = em_check_ptype, 16771a7e242SJianfeng Tan .cb_parse_ptype = em_cb_parse_ptype, 168268888b5SRavi Kerur .main_loop = em_main_loop, 169268888b5SRavi Kerur .get_ipv4_lookup_struct = em_get_ipv4_l3fwd_lookup_struct, 170268888b5SRavi Kerur .get_ipv6_lookup_struct = em_get_ipv6_l3fwd_lookup_struct, 17152def963SSean Morrissey .free_routes = em_free_routes, 172997ee890SIntel }; 173997ee890SIntel 174268888b5SRavi Kerur static struct l3fwd_lkp_mode l3fwd_lpm_lkp = { 17552def963SSean Morrissey .read_config_files = read_config_files_lpm, 176268888b5SRavi Kerur .setup = setup_lpm, 17771a7e242SJianfeng Tan .check_ptype = lpm_check_ptype, 17871a7e242SJianfeng Tan .cb_parse_ptype = lpm_cb_parse_ptype, 179268888b5SRavi Kerur .main_loop = lpm_main_loop, 180268888b5SRavi Kerur .get_ipv4_lookup_struct = lpm_get_ipv4_l3fwd_lookup_struct, 181268888b5SRavi Kerur .get_ipv6_lookup_struct = lpm_get_ipv6_l3fwd_lookup_struct, 18252def963SSean Morrissey .free_routes = lpm_free_routes, 183af75078fSIntel }; 184af75078fSIntel 1859510dd1fSConor Walsh static struct l3fwd_lkp_mode l3fwd_fib_lkp = { 18652def963SSean Morrissey .read_config_files = read_config_files_lpm, 1879510dd1fSConor Walsh .setup = setup_fib, 1889510dd1fSConor Walsh .check_ptype = lpm_check_ptype, 1899510dd1fSConor Walsh .cb_parse_ptype = lpm_cb_parse_ptype, 1909510dd1fSConor Walsh .main_loop = fib_main_loop, 1919510dd1fSConor Walsh .get_ipv4_lookup_struct = fib_get_ipv4_l3fwd_lookup_struct, 1929510dd1fSConor Walsh .get_ipv6_lookup_struct = fib_get_ipv6_l3fwd_lookup_struct, 19352def963SSean Morrissey .free_routes = lpm_free_routes, 1949510dd1fSConor Walsh }; 1959510dd1fSConor Walsh 1966de0ea50SSean Morrissey static struct l3fwd_lkp_mode l3fwd_acl_lkp = { 1976de0ea50SSean Morrissey .read_config_files = read_config_files_acl, 1986de0ea50SSean Morrissey .setup = setup_acl, 1996de0ea50SSean Morrissey .check_ptype = em_check_ptype, 2006de0ea50SSean Morrissey .cb_parse_ptype = em_cb_parse_ptype, 2016de0ea50SSean Morrissey .main_loop = acl_main_loop, 2026de0ea50SSean Morrissey .get_ipv4_lookup_struct = acl_get_ipv4_l3fwd_lookup_struct, 2036de0ea50SSean Morrissey .get_ipv6_lookup_struct = acl_get_ipv6_l3fwd_lookup_struct, 2046de0ea50SSean Morrissey .free_routes = acl_free_routes, 2056de0ea50SSean Morrissey }; 2066de0ea50SSean Morrissey 20796ff4453SKonstantin Ananyev /* 208da796d27SConor Walsh * 198.18.0.0/16 are set aside for RFC2544 benchmarking (RFC5735). 209cb94a679SPavan Nikhilesh * 198.18.{0-15}.0/24 = Port {0-15} 210da796d27SConor Walsh */ 211da796d27SConor Walsh const struct ipv4_l3fwd_route ipv4_l3fwd_route_array[] = { 212da796d27SConor Walsh {RTE_IPV4(198, 18, 0, 0), 24, 0}, 213da796d27SConor Walsh {RTE_IPV4(198, 18, 1, 0), 24, 1}, 214da796d27SConor Walsh {RTE_IPV4(198, 18, 2, 0), 24, 2}, 215da796d27SConor Walsh {RTE_IPV4(198, 18, 3, 0), 24, 3}, 216da796d27SConor Walsh {RTE_IPV4(198, 18, 4, 0), 24, 4}, 217da796d27SConor Walsh {RTE_IPV4(198, 18, 5, 0), 24, 5}, 218da796d27SConor Walsh {RTE_IPV4(198, 18, 6, 0), 24, 6}, 219da796d27SConor Walsh {RTE_IPV4(198, 18, 7, 0), 24, 7}, 220cb94a679SPavan Nikhilesh {RTE_IPV4(198, 18, 8, 0), 24, 8}, 221cb94a679SPavan Nikhilesh {RTE_IPV4(198, 18, 9, 0), 24, 9}, 222cb94a679SPavan Nikhilesh {RTE_IPV4(198, 18, 10, 0), 24, 10}, 223cb94a679SPavan Nikhilesh {RTE_IPV4(198, 18, 11, 0), 24, 11}, 224cb94a679SPavan Nikhilesh {RTE_IPV4(198, 18, 12, 0), 24, 12}, 225cb94a679SPavan Nikhilesh {RTE_IPV4(198, 18, 13, 0), 24, 13}, 226cb94a679SPavan Nikhilesh {RTE_IPV4(198, 18, 14, 0), 24, 14}, 227cb94a679SPavan Nikhilesh {RTE_IPV4(198, 18, 15, 0), 24, 15}, 228da796d27SConor Walsh }; 229da796d27SConor Walsh 230da796d27SConor Walsh /* 231da796d27SConor Walsh * 2001:200::/48 is IANA reserved range for IPv6 benchmarking (RFC5180). 232cb94a679SPavan Nikhilesh * 2001:200:0:{0-f}::/64 = Port {0-15} 233da796d27SConor Walsh */ 234da796d27SConor Walsh const struct ipv6_l3fwd_route ipv6_l3fwd_route_array[] = { 235e1a06e39SRobin Jarry {RTE_IPV6(0x2001, 0x0200, 0, 0x0, 0, 0, 0, 0), 64, 0}, 236e1a06e39SRobin Jarry {RTE_IPV6(0x2001, 0x0200, 0, 0x1, 0, 0, 0, 0), 64, 1}, 237e1a06e39SRobin Jarry {RTE_IPV6(0x2001, 0x0200, 0, 0x2, 0, 0, 0, 0), 64, 2}, 238e1a06e39SRobin Jarry {RTE_IPV6(0x2001, 0x0200, 0, 0x3, 0, 0, 0, 0), 64, 3}, 239e1a06e39SRobin Jarry {RTE_IPV6(0x2001, 0x0200, 0, 0x4, 0, 0, 0, 0), 64, 4}, 240e1a06e39SRobin Jarry {RTE_IPV6(0x2001, 0x0200, 0, 0x5, 0, 0, 0, 0), 64, 5}, 241e1a06e39SRobin Jarry {RTE_IPV6(0x2001, 0x0200, 0, 0x6, 0, 0, 0, 0), 64, 6}, 242e1a06e39SRobin Jarry {RTE_IPV6(0x2001, 0x0200, 0, 0x7, 0, 0, 0, 0), 64, 7}, 243e1a06e39SRobin Jarry {RTE_IPV6(0x2001, 0x0200, 0, 0x8, 0, 0, 0, 0), 64, 8}, 244e1a06e39SRobin Jarry {RTE_IPV6(0x2001, 0x0200, 0, 0x9, 0, 0, 0, 0), 64, 9}, 245e1a06e39SRobin Jarry {RTE_IPV6(0x2001, 0x0200, 0, 0xa, 0, 0, 0, 0), 64, 10}, 246e1a06e39SRobin Jarry {RTE_IPV6(0x2001, 0x0200, 0, 0xb, 0, 0, 0, 0), 64, 11}, 247e1a06e39SRobin Jarry {RTE_IPV6(0x2001, 0x0200, 0, 0xc, 0, 0, 0, 0), 64, 12}, 248e1a06e39SRobin Jarry {RTE_IPV6(0x2001, 0x0200, 0, 0xd, 0, 0, 0, 0), 64, 13}, 249e1a06e39SRobin Jarry {RTE_IPV6(0x2001, 0x0200, 0, 0xe, 0, 0, 0, 0), 64, 14}, 250e1a06e39SRobin Jarry {RTE_IPV6(0x2001, 0x0200, 0, 0xf, 0, 0, 0, 0), 64, 15}, 251da796d27SConor Walsh }; 252da796d27SConor Walsh 253da796d27SConor Walsh /* 25452def963SSean Morrissey * API's called during initialization to setup ACL/EM/LPM rules. 25552def963SSean Morrissey */ 2566de0ea50SSean Morrissey void 25752def963SSean Morrissey l3fwd_set_rule_ipv4_name(const char *optarg) 25852def963SSean Morrissey { 25952def963SSean Morrissey parm_config.rule_ipv4_name = optarg; 26052def963SSean Morrissey } 26152def963SSean Morrissey 2626de0ea50SSean Morrissey void 26352def963SSean Morrissey l3fwd_set_rule_ipv6_name(const char *optarg) 26452def963SSean Morrissey { 26552def963SSean Morrissey parm_config.rule_ipv6_name = optarg; 26652def963SSean Morrissey } 26752def963SSean Morrissey 2686de0ea50SSean Morrissey void 2696de0ea50SSean Morrissey l3fwd_set_alg(const char *optarg) 2706de0ea50SSean Morrissey { 2716de0ea50SSean Morrissey parm_config.alg = parse_acl_alg(optarg); 2726de0ea50SSean Morrissey } 2736de0ea50SSean Morrissey 27452def963SSean Morrissey /* 275268888b5SRavi Kerur * Setup lookup methods for forwarding. 2769510dd1fSConor Walsh * Currently exact-match, longest-prefix-match and forwarding information 2779510dd1fSConor Walsh * base are the supported ones. 27896ff4453SKonstantin Ananyev */ 279268888b5SRavi Kerur static void 280268888b5SRavi Kerur setup_l3fwd_lookup_tables(void) 281af75078fSIntel { 282268888b5SRavi Kerur /* Setup HASH lookup functions. */ 2839510dd1fSConor Walsh if (lookup_mode == L3FWD_LOOKUP_EM) 284268888b5SRavi Kerur l3fwd_lkp = l3fwd_em_lkp; 2859510dd1fSConor Walsh /* Setup FIB lookup functions. */ 2869510dd1fSConor Walsh else if (lookup_mode == L3FWD_LOOKUP_FIB) 2879510dd1fSConor Walsh l3fwd_lkp = l3fwd_fib_lkp; 2886de0ea50SSean Morrissey /* Setup ACL lookup functions. */ 2896de0ea50SSean Morrissey else if (lookup_mode == L3FWD_LOOKUP_ACL) 2906de0ea50SSean Morrissey l3fwd_lkp = l3fwd_acl_lkp; 291268888b5SRavi Kerur /* Setup LPM lookup functions. */ 292268888b5SRavi Kerur else 293268888b5SRavi Kerur l3fwd_lkp = l3fwd_lpm_lkp; 294af75078fSIntel } 295af75078fSIntel 296af75078fSIntel static int 297af75078fSIntel check_lcore_params(void) 298af75078fSIntel { 299b23c5bd7SSivaprasad Tummala uint16_t queue, i; 3004b978938SSivaprasad Tummala uint32_t lcore; 301af75078fSIntel int socketid; 302af75078fSIntel 303af75078fSIntel for (i = 0; i < nb_lcore_params; ++i) { 304af75078fSIntel queue = lcore_params[i].queue_id; 305af75078fSIntel if (queue >= MAX_RX_QUEUE_PER_PORT) { 306b23c5bd7SSivaprasad Tummala printf("invalid queue number: %" PRIu16 "\n", queue); 307af75078fSIntel return -1; 308af75078fSIntel } 309af75078fSIntel lcore = lcore_params[i].lcore_id; 310af75078fSIntel if (!rte_lcore_is_enabled(lcore)) { 3114b978938SSivaprasad Tummala printf("error: lcore %u is not enabled in lcore mask\n", lcore); 312af75078fSIntel return -1; 313af75078fSIntel } 314af75078fSIntel if ((socketid = rte_lcore_to_socket_id(lcore) != 0) && 315af75078fSIntel (numa_on == 0)) { 3164b978938SSivaprasad Tummala printf("warning: lcore %u is on socket %d with numa off\n", 317af75078fSIntel lcore, socketid); 318af75078fSIntel } 319af75078fSIntel } 320af75078fSIntel return 0; 321af75078fSIntel } 322af75078fSIntel 323af75078fSIntel static int 324a9dbe180SThomas Monjalon check_port_config(void) 325af75078fSIntel { 326f8244c63SZhiyong Yang uint16_t portid; 327af75078fSIntel uint16_t i; 328af75078fSIntel 329af75078fSIntel for (i = 0; i < nb_lcore_params; ++i) { 330af75078fSIntel portid = lcore_params[i].port_id; 331af75078fSIntel if ((enabled_port_mask & (1 << portid)) == 0) { 332af75078fSIntel printf("port %u is not enabled in port mask\n", portid); 333af75078fSIntel return -1; 334af75078fSIntel } 335a9dbe180SThomas Monjalon if (!rte_eth_dev_is_valid_port(portid)) { 336af75078fSIntel printf("port %u is not present on the board\n", portid); 337af75078fSIntel return -1; 338af75078fSIntel } 339af75078fSIntel } 340af75078fSIntel return 0; 341af75078fSIntel } 342af75078fSIntel 343b23c5bd7SSivaprasad Tummala static uint16_t 344f8244c63SZhiyong Yang get_port_n_rx_queues(const uint16_t port) 345af75078fSIntel { 346af75078fSIntel int queue = -1; 347af75078fSIntel uint16_t i; 348af75078fSIntel 349af75078fSIntel for (i = 0; i < nb_lcore_params; ++i) { 350a6b45080SReshma Pattan if (lcore_params[i].port_id == port) { 351a6b45080SReshma Pattan if (lcore_params[i].queue_id == queue+1) 352af75078fSIntel queue = lcore_params[i].queue_id; 353a6b45080SReshma Pattan else 354a6b45080SReshma Pattan rte_exit(EXIT_FAILURE, "queue ids of the port %d must be" 355a6b45080SReshma Pattan " in sequence and must start with 0\n", 356a6b45080SReshma Pattan lcore_params[i].port_id); 357a6b45080SReshma Pattan } 358af75078fSIntel } 359b23c5bd7SSivaprasad Tummala return (uint16_t)(++queue); 360af75078fSIntel } 361af75078fSIntel 362af75078fSIntel static int 363af75078fSIntel init_lcore_rx_queues(void) 364af75078fSIntel { 365af75078fSIntel uint16_t i, nb_rx_queue; 3664b978938SSivaprasad Tummala uint32_t lcore; 367af75078fSIntel 368af75078fSIntel for (i = 0; i < nb_lcore_params; ++i) { 369af75078fSIntel lcore = lcore_params[i].lcore_id; 370af75078fSIntel nb_rx_queue = lcore_conf[lcore].n_rx_queue; 371af75078fSIntel if (nb_rx_queue >= MAX_RX_QUEUE_PER_LCORE) { 372af75078fSIntel printf("error: too many queues (%u) for lcore: %u\n", 3734b978938SSivaprasad Tummala (unsigned int)nb_rx_queue + 1, lcore); 374af75078fSIntel return -1; 375af75078fSIntel } else { 376af75078fSIntel lcore_conf[lcore].rx_queue_list[nb_rx_queue].port_id = 377af75078fSIntel lcore_params[i].port_id; 378af75078fSIntel lcore_conf[lcore].rx_queue_list[nb_rx_queue].queue_id = 379af75078fSIntel lcore_params[i].queue_id; 380af75078fSIntel lcore_conf[lcore].n_rx_queue++; 381af75078fSIntel } 382af75078fSIntel } 383af75078fSIntel return 0; 384af75078fSIntel } 385af75078fSIntel 386af75078fSIntel /* display usage */ 387af75078fSIntel static void 388af75078fSIntel print_usage(const char *prgname) 389af75078fSIntel { 3906de0ea50SSean Morrissey char alg[PATH_MAX]; 3916de0ea50SSean Morrissey 3926de0ea50SSean Morrissey usage_acl_alg(alg, sizeof(alg)); 393c53a5fafSStephen Hemminger fprintf(stderr, "%s [EAL options] --" 39454659744SBeilei Xing " -p PORTMASK" 39552def963SSean Morrissey " --rule_ipv4=FILE" 39652def963SSean Morrissey " --rule_ipv6=FILE" 39754659744SBeilei Xing " [-P]" 3989510dd1fSConor Walsh " [--lookup]" 39954659744SBeilei Xing " --config (port,queue,lcore)[,(port,queue,lcore)]" 4008efffaecSHonnappa Nagarahalli " [--rx-queue-size NPKTS]" 4018efffaecSHonnappa Nagarahalli " [--tx-queue-size NPKTS]" 402d5c4897eSJie Hai " [--burst NPKTS]" 403*d9f26e52SJie Hai " [--mbcache CACHESZ]" 40454659744SBeilei Xing " [--eth-dest=X,MM:MM:MM:MM:MM:MM]" 4051bb4a528SFerruh Yigit " [--max-pkt-len PKTLEN]" 40654659744SBeilei Xing " [--no-numa]" 40754659744SBeilei Xing " [--ipv6]" 408f0a26885SShreyansh Jain " [--parse-ptype]" 409e2de1f7bSSunil Kumar Kori " [--per-port-pool]" 410e2de1f7bSSunil Kumar Kori " [--mode]" 411ef827078SBruce Richardson #ifdef RTE_LIB_EVENTDEV 4129510dd1fSConor Walsh " [--eventq-sched]" 413e8adca19SShijith Thotton " [--event-vector [--event-vector-size SIZE] [--event-vector-tmo NS]]" 414ef827078SBruce Richardson #endif 4159510dd1fSConor Walsh " [-E]" 4169510dd1fSConor Walsh " [-L]\n\n" 41754659744SBeilei Xing 41854659744SBeilei Xing " -p PORTMASK: Hexadecimal bitmask of ports to configure\n" 41954659744SBeilei Xing " -P : Enable promiscuous mode\n" 4209510dd1fSConor Walsh " --lookup: Select the lookup method\n" 4219510dd1fSConor Walsh " Default: lpm\n" 4226de0ea50SSean Morrissey " Accepted: em (Exact Match), lpm (Longest Prefix Match), fib (Forwarding Information Base),\n" 4236de0ea50SSean Morrissey " acl (Access Control List)\n" 42454659744SBeilei Xing " --config (port,queue,lcore): Rx queue configuration\n" 4258efffaecSHonnappa Nagarahalli " --rx-queue-size NPKTS: Rx queue size in decimal\n" 4268efffaecSHonnappa Nagarahalli " Default: %d\n" 4278efffaecSHonnappa Nagarahalli " --tx-queue-size NPKTS: Tx queue size in decimal\n" 4288efffaecSHonnappa Nagarahalli " Default: %d\n" 429d5c4897eSJie Hai " --burst NPKTS: Burst size in decimal\n" 430d5c4897eSJie Hai " Default: %d\n" 431*d9f26e52SJie Hai " --mbcache CACHESZ: Mbuf cache size in decimal\n" 432*d9f26e52SJie Hai " Default: %d\n" 43354659744SBeilei Xing " --eth-dest=X,MM:MM:MM:MM:MM:MM: Ethernet destination for port X\n" 4341bb4a528SFerruh Yigit " --max-pkt-len PKTLEN: maximum packet length in decimal (64-9600)\n" 43554659744SBeilei Xing " --no-numa: Disable numa awareness\n" 43654659744SBeilei Xing " --ipv6: Set if running ipv6 packets\n" 437f0a26885SShreyansh Jain " --parse-ptype: Set to use software to analyze packet type\n" 438e2de1f7bSSunil Kumar Kori " --per-port-pool: Use separate buffer pool per port\n" 439e2de1f7bSSunil Kumar Kori " --mode: Packet transfer mode for I/O, poll or eventdev\n" 440e2de1f7bSSunil Kumar Kori " Default mode = poll\n" 441ef827078SBruce Richardson #ifdef RTE_LIB_EVENTDEV 442e2de1f7bSSunil Kumar Kori " --eventq-sched: Event queue synchronization method\n" 443e2de1f7bSSunil Kumar Kori " ordered, atomic or parallel.\n" 444e2de1f7bSSunil Kumar Kori " Default: atomic\n" 445e2de1f7bSSunil Kumar Kori " Valid only if --mode=eventdev\n" 446e2de1f7bSSunil Kumar Kori " --event-eth-rxqs: Number of ethernet RX queues per device.\n" 447e2de1f7bSSunil Kumar Kori " Default: 1\n" 4489510dd1fSConor Walsh " Valid only if --mode=eventdev\n" 449e8adca19SShijith Thotton " --event-vector: Enable event vectorization.\n" 450e8adca19SShijith Thotton " --event-vector-size: Max vector size if event vectorization is enabled.\n" 451e8adca19SShijith Thotton " --event-vector-tmo: Max timeout to form vector in nanoseconds if event vectorization is enabled\n" 452ef827078SBruce Richardson #endif 4539510dd1fSConor Walsh " -E : Enable exact match, legacy flag please use --lookup=em instead\n" 45452def963SSean Morrissey " -L : Enable longest prefix match, legacy flag please use --lookup=lpm instead\n" 45552def963SSean Morrissey " --rule_ipv4=FILE: Specify the ipv4 rules entries file.\n" 45652def963SSean Morrissey " Each rule occupies one line.\n" 4576de0ea50SSean Morrissey " 2 kinds of rules are supported.\n" 4586de0ea50SSean Morrissey " One is ACL entry at while line leads with character '%c',\n" 4596de0ea50SSean Morrissey " another is route entry at while line leads with character '%c'.\n" 4606de0ea50SSean Morrissey " --rule_ipv6=FILE: Specify the ipv6 rules entries file.\n" 4616de0ea50SSean Morrissey " --alg: ACL classify method to use, one of: %s.\n\n", 462*d9f26e52SJie Hai prgname, RX_DESC_DEFAULT, TX_DESC_DEFAULT, DEFAULT_PKT_BURST, MEMPOOL_CACHE_SIZE, 4636de0ea50SSean Morrissey ACL_LEAD_CHAR, ROUTE_LEAD_CHAR, alg); 464af75078fSIntel } 465af75078fSIntel 466268888b5SRavi Kerur static int 467268888b5SRavi Kerur parse_max_pkt_len(const char *pktlen) 468f68aad79SIntel { 469f68aad79SIntel char *end = NULL; 470f68aad79SIntel unsigned long len; 471f68aad79SIntel 472f68aad79SIntel /* parse decimal string */ 473f68aad79SIntel len = strtoul(pktlen, &end, 10); 474f68aad79SIntel if ((pktlen[0] == '\0') || (end == NULL) || (*end != '\0')) 475f68aad79SIntel return -1; 476f68aad79SIntel 477f68aad79SIntel if (len == 0) 478f68aad79SIntel return -1; 479f68aad79SIntel 480f68aad79SIntel return len; 481f68aad79SIntel } 482f68aad79SIntel 483af75078fSIntel static int 484af75078fSIntel parse_portmask(const char *portmask) 485af75078fSIntel { 486af75078fSIntel char *end = NULL; 487af75078fSIntel unsigned long pm; 488af75078fSIntel 489af75078fSIntel /* parse hexadecimal string */ 490af75078fSIntel pm = strtoul(portmask, &end, 16); 491af75078fSIntel if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0')) 492ce6b8c31SSarosh Arif return 0; 493af75078fSIntel 494af75078fSIntel return pm; 495af75078fSIntel } 496af75078fSIntel 497997ee890SIntel static int 498af75078fSIntel parse_config(const char *q_arg) 499af75078fSIntel { 500af75078fSIntel char s[256]; 501af75078fSIntel const char *p, *p0 = q_arg; 502af75078fSIntel char *end; 503af75078fSIntel enum fieldnames { 504af75078fSIntel FLD_PORT = 0, 505af75078fSIntel FLD_QUEUE, 506af75078fSIntel FLD_LCORE, 507af75078fSIntel _NUM_FLD 508af75078fSIntel }; 509af75078fSIntel unsigned long int_fld[_NUM_FLD]; 510af75078fSIntel char *str_fld[_NUM_FLD]; 511af75078fSIntel int i; 512af75078fSIntel unsigned size; 5134b978938SSivaprasad Tummala uint16_t max_fld[_NUM_FLD] = { 514548de909SSivaprasad Tummala RTE_MAX_ETHPORTS, 5154b978938SSivaprasad Tummala RTE_MAX_QUEUES_PER_PORT, 5164b978938SSivaprasad Tummala RTE_MAX_LCORE 5174b978938SSivaprasad Tummala }; 518af75078fSIntel 519af75078fSIntel nb_lcore_params = 0; 520af75078fSIntel 521af75078fSIntel while ((p = strchr(p0,'(')) != NULL) { 522af75078fSIntel ++p; 523af75078fSIntel if((p0 = strchr(p,')')) == NULL) 524af75078fSIntel return -1; 525af75078fSIntel 526af75078fSIntel size = p0 - p; 527af75078fSIntel if(size >= sizeof(s)) 528af75078fSIntel return -1; 529af75078fSIntel 5306f41fe75SStephen Hemminger snprintf(s, sizeof(s), "%.*s", size, p); 531af75078fSIntel if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != _NUM_FLD) 532af75078fSIntel return -1; 533af75078fSIntel for (i = 0; i < _NUM_FLD; i++){ 534af75078fSIntel errno = 0; 535af75078fSIntel int_fld[i] = strtoul(str_fld[i], &end, 0); 536b23c5bd7SSivaprasad Tummala if (errno != 0 || end == str_fld[i] || int_fld[i] > max_fld[i]) 537af75078fSIntel return -1; 538af75078fSIntel } 539af75078fSIntel if (nb_lcore_params >= MAX_LCORE_PARAMS) { 540af75078fSIntel printf("exceeded max number of lcore params: %hu\n", 541af75078fSIntel nb_lcore_params); 542af75078fSIntel return -1; 543af75078fSIntel } 544268888b5SRavi Kerur lcore_params_array[nb_lcore_params].port_id = 545548de909SSivaprasad Tummala (uint16_t)int_fld[FLD_PORT]; 546268888b5SRavi Kerur lcore_params_array[nb_lcore_params].queue_id = 547b23c5bd7SSivaprasad Tummala (uint16_t)int_fld[FLD_QUEUE]; 548268888b5SRavi Kerur lcore_params_array[nb_lcore_params].lcore_id = 5494b978938SSivaprasad Tummala (uint32_t)int_fld[FLD_LCORE]; 550af75078fSIntel ++nb_lcore_params; 551af75078fSIntel } 552af75078fSIntel lcore_params = lcore_params_array; 553af75078fSIntel return 0; 554af75078fSIntel } 555af75078fSIntel 556bd785f6fSAndrey Chilikin static void 557bd785f6fSAndrey Chilikin parse_eth_dest(const char *optarg) 558bd785f6fSAndrey Chilikin { 559f8244c63SZhiyong Yang uint16_t portid; 560bd785f6fSAndrey Chilikin char *port_end; 561bd785f6fSAndrey Chilikin uint8_t c, *dest, peer_addr[6]; 562bd785f6fSAndrey Chilikin 563bd785f6fSAndrey Chilikin errno = 0; 564bd785f6fSAndrey Chilikin portid = strtoul(optarg, &port_end, 10); 565bd785f6fSAndrey Chilikin if (errno != 0 || port_end == optarg || *port_end++ != ',') 566bd785f6fSAndrey Chilikin rte_exit(EXIT_FAILURE, 567bd785f6fSAndrey Chilikin "Invalid eth-dest: %s", optarg); 568bd785f6fSAndrey Chilikin if (portid >= RTE_MAX_ETHPORTS) 569bd785f6fSAndrey Chilikin rte_exit(EXIT_FAILURE, 570bd785f6fSAndrey Chilikin "eth-dest: port %d >= RTE_MAX_ETHPORTS(%d)\n", 571bd785f6fSAndrey Chilikin portid, RTE_MAX_ETHPORTS); 572bd785f6fSAndrey Chilikin 573bd785f6fSAndrey Chilikin if (cmdline_parse_etheraddr(NULL, port_end, 574bd785f6fSAndrey Chilikin &peer_addr, sizeof(peer_addr)) < 0) 575bd785f6fSAndrey Chilikin rte_exit(EXIT_FAILURE, 576bd785f6fSAndrey Chilikin "Invalid ethernet address: %s\n", 577bd785f6fSAndrey Chilikin port_end); 578bd785f6fSAndrey Chilikin dest = (uint8_t *)&dest_eth_addr[portid]; 579bd785f6fSAndrey Chilikin for (c = 0; c < 6; c++) 580bd785f6fSAndrey Chilikin dest[c] = peer_addr[c]; 581bd785f6fSAndrey Chilikin *(uint64_t *)(val_eth + portid) = dest_eth_addr[portid]; 582bd785f6fSAndrey Chilikin } 583bd785f6fSAndrey Chilikin 584e2de1f7bSSunil Kumar Kori static void 585ef827078SBruce Richardson parse_mode(const char *optarg __rte_unused) 586e2de1f7bSSunil Kumar Kori { 587ef827078SBruce Richardson #ifdef RTE_LIB_EVENTDEV 588e2de1f7bSSunil Kumar Kori struct l3fwd_event_resources *evt_rsrc = l3fwd_get_eventdev_rsrc(); 589e2de1f7bSSunil Kumar Kori 590e2de1f7bSSunil Kumar Kori if (!strcmp(optarg, "poll")) 591e2de1f7bSSunil Kumar Kori evt_rsrc->enabled = false; 592e2de1f7bSSunil Kumar Kori else if (!strcmp(optarg, "eventdev")) 593e2de1f7bSSunil Kumar Kori evt_rsrc->enabled = true; 594ef827078SBruce Richardson #endif 595e2de1f7bSSunil Kumar Kori } 596e2de1f7bSSunil Kumar Kori 597e2de1f7bSSunil Kumar Kori static void 5988efffaecSHonnappa Nagarahalli parse_queue_size(const char *queue_size_arg, uint16_t *queue_size, int rx) 5998efffaecSHonnappa Nagarahalli { 6008efffaecSHonnappa Nagarahalli char *end = NULL; 6018efffaecSHonnappa Nagarahalli unsigned long value; 6028efffaecSHonnappa Nagarahalli 6038efffaecSHonnappa Nagarahalli /* parse decimal string */ 6048efffaecSHonnappa Nagarahalli value = strtoul(queue_size_arg, &end, 10); 6058efffaecSHonnappa Nagarahalli if ((queue_size_arg[0] == '\0') || (end == NULL) || 6068efffaecSHonnappa Nagarahalli (*end != '\0') || (value == 0)) { 6078efffaecSHonnappa Nagarahalli if (rx == 1) 6088efffaecSHonnappa Nagarahalli rte_exit(EXIT_FAILURE, "Invalid rx-queue-size\n"); 6098efffaecSHonnappa Nagarahalli else 6108efffaecSHonnappa Nagarahalli rte_exit(EXIT_FAILURE, "Invalid tx-queue-size\n"); 6118efffaecSHonnappa Nagarahalli 6128efffaecSHonnappa Nagarahalli return; 6138efffaecSHonnappa Nagarahalli } 6148efffaecSHonnappa Nagarahalli 6158efffaecSHonnappa Nagarahalli if (value > UINT16_MAX) { 6168efffaecSHonnappa Nagarahalli if (rx == 1) 6178efffaecSHonnappa Nagarahalli rte_exit(EXIT_FAILURE, "rx-queue-size %lu > %d\n", 6188efffaecSHonnappa Nagarahalli value, UINT16_MAX); 6198efffaecSHonnappa Nagarahalli else 6208efffaecSHonnappa Nagarahalli rte_exit(EXIT_FAILURE, "tx-queue-size %lu > %d\n", 6218efffaecSHonnappa Nagarahalli value, UINT16_MAX); 6228efffaecSHonnappa Nagarahalli 6238efffaecSHonnappa Nagarahalli return; 6248efffaecSHonnappa Nagarahalli } 6258efffaecSHonnappa Nagarahalli 6268efffaecSHonnappa Nagarahalli *queue_size = value; 6278efffaecSHonnappa Nagarahalli } 6288efffaecSHonnappa Nagarahalli 629ef827078SBruce Richardson #ifdef RTE_LIB_EVENTDEV 6308efffaecSHonnappa Nagarahalli static void 631e2de1f7bSSunil Kumar Kori parse_eventq_sched(const char *optarg) 632e2de1f7bSSunil Kumar Kori { 633e2de1f7bSSunil Kumar Kori struct l3fwd_event_resources *evt_rsrc = l3fwd_get_eventdev_rsrc(); 634e2de1f7bSSunil Kumar Kori 635e2de1f7bSSunil Kumar Kori if (!strcmp(optarg, "ordered")) 636e2de1f7bSSunil Kumar Kori evt_rsrc->sched_type = RTE_SCHED_TYPE_ORDERED; 637e2de1f7bSSunil Kumar Kori if (!strcmp(optarg, "atomic")) 638e2de1f7bSSunil Kumar Kori evt_rsrc->sched_type = RTE_SCHED_TYPE_ATOMIC; 639e2de1f7bSSunil Kumar Kori if (!strcmp(optarg, "parallel")) 640e2de1f7bSSunil Kumar Kori evt_rsrc->sched_type = RTE_SCHED_TYPE_PARALLEL; 641e2de1f7bSSunil Kumar Kori } 642e2de1f7bSSunil Kumar Kori 643e2de1f7bSSunil Kumar Kori static void 644e2de1f7bSSunil Kumar Kori parse_event_eth_rx_queues(const char *eth_rx_queues) 645e2de1f7bSSunil Kumar Kori { 646e2de1f7bSSunil Kumar Kori struct l3fwd_event_resources *evt_rsrc = l3fwd_get_eventdev_rsrc(); 647e2de1f7bSSunil Kumar Kori char *end = NULL; 648b23c5bd7SSivaprasad Tummala uint16_t num_eth_rx_queues; 649e2de1f7bSSunil Kumar Kori 650e2de1f7bSSunil Kumar Kori /* parse decimal string */ 651e2de1f7bSSunil Kumar Kori num_eth_rx_queues = strtoul(eth_rx_queues, &end, 10); 652e2de1f7bSSunil Kumar Kori if ((eth_rx_queues[0] == '\0') || (end == NULL) || (*end != '\0')) 653e2de1f7bSSunil Kumar Kori return; 654e2de1f7bSSunil Kumar Kori 655e2de1f7bSSunil Kumar Kori if (num_eth_rx_queues == 0) 656e2de1f7bSSunil Kumar Kori return; 657e2de1f7bSSunil Kumar Kori 658e2de1f7bSSunil Kumar Kori evt_rsrc->eth_rx_queues = num_eth_rx_queues; 659e2de1f7bSSunil Kumar Kori } 660ef827078SBruce Richardson #endif 661e2de1f7bSSunil Kumar Kori 6629510dd1fSConor Walsh static int 6639510dd1fSConor Walsh parse_lookup(const char *optarg) 6649510dd1fSConor Walsh { 6659510dd1fSConor Walsh if (!strcmp(optarg, "em")) 6669510dd1fSConor Walsh lookup_mode = L3FWD_LOOKUP_EM; 6679510dd1fSConor Walsh else if (!strcmp(optarg, "lpm")) 6689510dd1fSConor Walsh lookup_mode = L3FWD_LOOKUP_LPM; 6699510dd1fSConor Walsh else if (!strcmp(optarg, "fib")) 6709510dd1fSConor Walsh lookup_mode = L3FWD_LOOKUP_FIB; 6716de0ea50SSean Morrissey else if (!strcmp(optarg, "acl")) 6726de0ea50SSean Morrissey lookup_mode = L3FWD_LOOKUP_ACL; 6739510dd1fSConor Walsh else { 6746de0ea50SSean Morrissey fprintf(stderr, "Invalid lookup option! Accepted options: acl, em, lpm, fib\n"); 6759510dd1fSConor Walsh return -1; 6769510dd1fSConor Walsh } 6779510dd1fSConor Walsh return 0; 6789510dd1fSConor Walsh } 6799510dd1fSConor Walsh 680d5c4897eSJie Hai static void 681*d9f26e52SJie Hai parse_mbcache_size(const char *optarg) 682*d9f26e52SJie Hai { 683*d9f26e52SJie Hai unsigned long mb_cache_size; 684*d9f26e52SJie Hai char *end = NULL; 685*d9f26e52SJie Hai 686*d9f26e52SJie Hai mb_cache_size = strtoul(optarg, &end, 10); 687*d9f26e52SJie Hai if ((optarg[0] == '\0') || (end == NULL) || (*end != '\0')) 688*d9f26e52SJie Hai return; 689*d9f26e52SJie Hai if (mb_cache_size <= RTE_MEMPOOL_CACHE_MAX_SIZE) 690*d9f26e52SJie Hai mb_mempool_cache_size = (uint32_t)mb_cache_size; 691*d9f26e52SJie Hai else 692*d9f26e52SJie Hai rte_exit(EXIT_FAILURE, "mbcache must be >= 0 and <= %d\n", 693*d9f26e52SJie Hai RTE_MEMPOOL_CACHE_MAX_SIZE); 694*d9f26e52SJie Hai } 695*d9f26e52SJie Hai 696*d9f26e52SJie Hai static void 697d5c4897eSJie Hai parse_pkt_burst(const char *optarg) 698d5c4897eSJie Hai { 699d5c4897eSJie Hai struct rte_eth_dev_info dev_info; 700d5c4897eSJie Hai unsigned long pkt_burst; 701d5c4897eSJie Hai uint16_t burst_size; 702d5c4897eSJie Hai char *end = NULL; 703d5c4897eSJie Hai int ret; 704d5c4897eSJie Hai 705d5c4897eSJie Hai /* parse decimal string */ 706d5c4897eSJie Hai pkt_burst = strtoul(optarg, &end, 10); 707d5c4897eSJie Hai if ((optarg[0] == '\0') || (end == NULL) || (*end != '\0')) 708d5c4897eSJie Hai return; 709d5c4897eSJie Hai 710d5c4897eSJie Hai if (pkt_burst > MAX_PKT_BURST) { 711d5c4897eSJie Hai RTE_LOG(INFO, L3FWD, "User provided burst must be <= %d. Using default value %d\n", 712d5c4897eSJie Hai MAX_PKT_BURST, nb_pkt_per_burst); 713d5c4897eSJie Hai return; 714d5c4897eSJie Hai } else if (pkt_burst > 0) { 715d5c4897eSJie Hai nb_pkt_per_burst = (uint32_t)pkt_burst; 716d5c4897eSJie Hai return; 717d5c4897eSJie Hai } 718d5c4897eSJie Hai 719d5c4897eSJie Hai /* If user gives a value of zero, query the PMD for its recommended Rx burst size. */ 720d5c4897eSJie Hai ret = rte_eth_dev_info_get(0, &dev_info); 721d5c4897eSJie Hai if (ret != 0) 722d5c4897eSJie Hai return; 723d5c4897eSJie Hai burst_size = dev_info.default_rxportconf.burst_size; 724d5c4897eSJie Hai if (burst_size == 0) { 725d5c4897eSJie Hai RTE_LOG(INFO, L3FWD, "PMD does not recommend a burst size. Using default value %d. " 726d5c4897eSJie Hai "User provided value must be in [1, %d]\n", 727d5c4897eSJie Hai nb_pkt_per_burst, MAX_PKT_BURST); 728d5c4897eSJie Hai return; 729d5c4897eSJie Hai } else if (burst_size > MAX_PKT_BURST) { 730d5c4897eSJie Hai RTE_LOG(INFO, L3FWD, "PMD recommended burst size %d exceeds maximum value %d. " 731d5c4897eSJie Hai "Using default value %d\n", 732d5c4897eSJie Hai burst_size, MAX_PKT_BURST, nb_pkt_per_burst); 733d5c4897eSJie Hai return; 734d5c4897eSJie Hai } 735d5c4897eSJie Hai nb_pkt_per_burst = burst_size; 736d5c4897eSJie Hai RTE_LOG(INFO, L3FWD, "Using PMD-provided burst value %d\n", burst_size); 737d5c4897eSJie Hai } 738d5c4897eSJie Hai 739268888b5SRavi Kerur #define MAX_JUMBO_PKT_LEN 9600 740268888b5SRavi Kerur 74188617471SOlivier Matz static const char short_options[] = 74288617471SOlivier Matz "p:" /* portmask */ 74388617471SOlivier Matz "P" /* promiscuous */ 7449510dd1fSConor Walsh "L" /* legacy enable long prefix match */ 7459510dd1fSConor Walsh "E" /* legacy enable exact match */ 74688617471SOlivier Matz ; 74788617471SOlivier Matz 748997ee890SIntel #define CMD_LINE_OPT_CONFIG "config" 7498efffaecSHonnappa Nagarahalli #define CMD_LINE_OPT_RX_QUEUE_SIZE "rx-queue-size" 7508efffaecSHonnappa Nagarahalli #define CMD_LINE_OPT_TX_QUEUE_SIZE "tx-queue-size" 751bd785f6fSAndrey Chilikin #define CMD_LINE_OPT_ETH_DEST "eth-dest" 752997ee890SIntel #define CMD_LINE_OPT_NO_NUMA "no-numa" 753997ee890SIntel #define CMD_LINE_OPT_IPV6 "ipv6" 7541bb4a528SFerruh Yigit #define CMD_LINE_OPT_MAX_PKT_LEN "max-pkt-len" 755997ee890SIntel #define CMD_LINE_OPT_HASH_ENTRY_NUM "hash-entry-num" 75671a7e242SJianfeng Tan #define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype" 757f9800c32STrevor Tao #define CMD_LINE_OPT_DISABLE_RSS "disable-rss" 7584b01cabfSTrevor Tao #define CMD_LINE_OPT_RELAX_RX_OFFLOAD "relax-rx-offload" 759f0a26885SShreyansh Jain #define CMD_LINE_OPT_PER_PORT_POOL "per-port-pool" 760e2de1f7bSSunil Kumar Kori #define CMD_LINE_OPT_MODE "mode" 761e2de1f7bSSunil Kumar Kori #define CMD_LINE_OPT_EVENTQ_SYNC "eventq-sched" 762e2de1f7bSSunil Kumar Kori #define CMD_LINE_OPT_EVENT_ETH_RX_QUEUES "event-eth-rxqs" 7639510dd1fSConor Walsh #define CMD_LINE_OPT_LOOKUP "lookup" 764e8adca19SShijith Thotton #define CMD_LINE_OPT_ENABLE_VECTOR "event-vector" 765e8adca19SShijith Thotton #define CMD_LINE_OPT_VECTOR_SIZE "event-vector-size" 766e8adca19SShijith Thotton #define CMD_LINE_OPT_VECTOR_TMO_NS "event-vector-tmo" 76752def963SSean Morrissey #define CMD_LINE_OPT_RULE_IPV4 "rule_ipv4" 76852def963SSean Morrissey #define CMD_LINE_OPT_RULE_IPV6 "rule_ipv6" 7696de0ea50SSean Morrissey #define CMD_LINE_OPT_ALG "alg" 770d5c4897eSJie Hai #define CMD_LINE_OPT_PKT_BURST "burst" 771*d9f26e52SJie Hai #define CMD_LINE_OPT_MB_CACHE_SIZE "mbcache" 772e8adca19SShijith Thotton 77388617471SOlivier Matz enum { 77488617471SOlivier Matz /* long options mapped to a short option */ 77588617471SOlivier Matz 77688617471SOlivier Matz /* first long only option value must be >= 256, so that we won't 77788617471SOlivier Matz * conflict with short options */ 77888617471SOlivier Matz CMD_LINE_OPT_MIN_NUM = 256, 77988617471SOlivier Matz CMD_LINE_OPT_CONFIG_NUM, 7808efffaecSHonnappa Nagarahalli CMD_LINE_OPT_RX_QUEUE_SIZE_NUM, 7818efffaecSHonnappa Nagarahalli CMD_LINE_OPT_TX_QUEUE_SIZE_NUM, 78288617471SOlivier Matz CMD_LINE_OPT_ETH_DEST_NUM, 78388617471SOlivier Matz CMD_LINE_OPT_NO_NUMA_NUM, 78488617471SOlivier Matz CMD_LINE_OPT_IPV6_NUM, 7851bb4a528SFerruh Yigit CMD_LINE_OPT_MAX_PKT_LEN_NUM, 78688617471SOlivier Matz CMD_LINE_OPT_HASH_ENTRY_NUM_NUM, 78788617471SOlivier Matz CMD_LINE_OPT_PARSE_PTYPE_NUM, 788f9800c32STrevor Tao CMD_LINE_OPT_DISABLE_RSS_NUM, 7894b01cabfSTrevor Tao CMD_LINE_OPT_RELAX_RX_OFFLOAD_NUM, 79052def963SSean Morrissey CMD_LINE_OPT_RULE_IPV4_NUM, 79152def963SSean Morrissey CMD_LINE_OPT_RULE_IPV6_NUM, 7926de0ea50SSean Morrissey CMD_LINE_OPT_ALG_NUM, 793f0a26885SShreyansh Jain CMD_LINE_OPT_PARSE_PER_PORT_POOL, 794e2de1f7bSSunil Kumar Kori CMD_LINE_OPT_MODE_NUM, 795e2de1f7bSSunil Kumar Kori CMD_LINE_OPT_EVENTQ_SYNC_NUM, 796e2de1f7bSSunil Kumar Kori CMD_LINE_OPT_EVENT_ETH_RX_QUEUES_NUM, 7979510dd1fSConor Walsh CMD_LINE_OPT_LOOKUP_NUM, 798e8adca19SShijith Thotton CMD_LINE_OPT_ENABLE_VECTOR_NUM, 799e8adca19SShijith Thotton CMD_LINE_OPT_VECTOR_SIZE_NUM, 800d5c4897eSJie Hai CMD_LINE_OPT_VECTOR_TMO_NS_NUM, 801d5c4897eSJie Hai CMD_LINE_OPT_PKT_BURST_NUM, 802*d9f26e52SJie Hai CMD_LINE_OPT_MB_CACHE_SIZE_NUM, 80388617471SOlivier Matz }; 80488617471SOlivier Matz 80588617471SOlivier Matz static const struct option lgopts[] = { 80688617471SOlivier Matz {CMD_LINE_OPT_CONFIG, 1, 0, CMD_LINE_OPT_CONFIG_NUM}, 8078efffaecSHonnappa Nagarahalli {CMD_LINE_OPT_RX_QUEUE_SIZE, 1, 0, CMD_LINE_OPT_RX_QUEUE_SIZE_NUM}, 8088efffaecSHonnappa Nagarahalli {CMD_LINE_OPT_TX_QUEUE_SIZE, 1, 0, CMD_LINE_OPT_TX_QUEUE_SIZE_NUM}, 80988617471SOlivier Matz {CMD_LINE_OPT_ETH_DEST, 1, 0, CMD_LINE_OPT_ETH_DEST_NUM}, 81088617471SOlivier Matz {CMD_LINE_OPT_NO_NUMA, 0, 0, CMD_LINE_OPT_NO_NUMA_NUM}, 81188617471SOlivier Matz {CMD_LINE_OPT_IPV6, 0, 0, CMD_LINE_OPT_IPV6_NUM}, 8121bb4a528SFerruh Yigit {CMD_LINE_OPT_MAX_PKT_LEN, 1, 0, CMD_LINE_OPT_MAX_PKT_LEN_NUM}, 81388617471SOlivier Matz {CMD_LINE_OPT_HASH_ENTRY_NUM, 1, 0, CMD_LINE_OPT_HASH_ENTRY_NUM_NUM}, 81488617471SOlivier Matz {CMD_LINE_OPT_PARSE_PTYPE, 0, 0, CMD_LINE_OPT_PARSE_PTYPE_NUM}, 8154b01cabfSTrevor Tao {CMD_LINE_OPT_RELAX_RX_OFFLOAD, 0, 0, CMD_LINE_OPT_RELAX_RX_OFFLOAD_NUM}, 816f9800c32STrevor Tao {CMD_LINE_OPT_DISABLE_RSS, 0, 0, CMD_LINE_OPT_DISABLE_RSS_NUM}, 817f0a26885SShreyansh Jain {CMD_LINE_OPT_PER_PORT_POOL, 0, 0, CMD_LINE_OPT_PARSE_PER_PORT_POOL}, 818e2de1f7bSSunil Kumar Kori {CMD_LINE_OPT_MODE, 1, 0, CMD_LINE_OPT_MODE_NUM}, 819e2de1f7bSSunil Kumar Kori {CMD_LINE_OPT_EVENTQ_SYNC, 1, 0, CMD_LINE_OPT_EVENTQ_SYNC_NUM}, 820e2de1f7bSSunil Kumar Kori {CMD_LINE_OPT_EVENT_ETH_RX_QUEUES, 1, 0, 821e2de1f7bSSunil Kumar Kori CMD_LINE_OPT_EVENT_ETH_RX_QUEUES_NUM}, 8229510dd1fSConor Walsh {CMD_LINE_OPT_LOOKUP, 1, 0, CMD_LINE_OPT_LOOKUP_NUM}, 823e8adca19SShijith Thotton {CMD_LINE_OPT_ENABLE_VECTOR, 0, 0, CMD_LINE_OPT_ENABLE_VECTOR_NUM}, 824e8adca19SShijith Thotton {CMD_LINE_OPT_VECTOR_SIZE, 1, 0, CMD_LINE_OPT_VECTOR_SIZE_NUM}, 825e8adca19SShijith Thotton {CMD_LINE_OPT_VECTOR_TMO_NS, 1, 0, CMD_LINE_OPT_VECTOR_TMO_NS_NUM}, 82652def963SSean Morrissey {CMD_LINE_OPT_RULE_IPV4, 1, 0, CMD_LINE_OPT_RULE_IPV4_NUM}, 82752def963SSean Morrissey {CMD_LINE_OPT_RULE_IPV6, 1, 0, CMD_LINE_OPT_RULE_IPV6_NUM}, 8286de0ea50SSean Morrissey {CMD_LINE_OPT_ALG, 1, 0, CMD_LINE_OPT_ALG_NUM}, 829d5c4897eSJie Hai {CMD_LINE_OPT_PKT_BURST, 1, 0, CMD_LINE_OPT_PKT_BURST_NUM}, 830*d9f26e52SJie Hai {CMD_LINE_OPT_MB_CACHE_SIZE, 1, 0, CMD_LINE_OPT_MB_CACHE_SIZE_NUM}, 83188617471SOlivier Matz {NULL, 0, 0, 0} 83288617471SOlivier Matz }; 833997ee890SIntel 834268888b5SRavi Kerur /* 835268888b5SRavi Kerur * This expression is used to calculate the number of mbufs needed 836268888b5SRavi Kerur * depending on user input, taking into account memory for rx and 837268888b5SRavi Kerur * tx hardware rings, cache per lcore and mtable per port per lcore. 838268888b5SRavi Kerur * RTE_MAX is used to ensure that NB_MBUF never goes below a minimum 839268888b5SRavi Kerur * value of 8192 840268888b5SRavi Kerur */ 841f0a26885SShreyansh Jain #define NB_MBUF(nports) RTE_MAX( \ 842f0a26885SShreyansh Jain (nports*nb_rx_queue*nb_rxd + \ 843f0a26885SShreyansh Jain nports*nb_lcores*MAX_PKT_BURST + \ 844f0a26885SShreyansh Jain nports*n_tx_queue*nb_txd + \ 845268888b5SRavi Kerur nb_lcores*MEMPOOL_CACHE_SIZE), \ 846268888b5SRavi Kerur (unsigned)8192) 847268888b5SRavi Kerur 848af75078fSIntel /* Parse the argument given in the command line of the application */ 849af75078fSIntel static int 850af75078fSIntel parse_args(int argc, char **argv) 851af75078fSIntel { 852af75078fSIntel int opt, ret; 853af75078fSIntel char **argvopt; 854af75078fSIntel int option_index; 855af75078fSIntel char *prgname = argv[0]; 856e2de1f7bSSunil Kumar Kori uint8_t lcore_params = 0; 857ef827078SBruce Richardson #ifdef RTE_LIB_EVENTDEV 858e2de1f7bSSunil Kumar Kori uint8_t eventq_sched = 0; 859e2de1f7bSSunil Kumar Kori uint8_t eth_rx_q = 0; 860e2de1f7bSSunil Kumar Kori struct l3fwd_event_resources *evt_rsrc = l3fwd_get_eventdev_rsrc(); 861ef827078SBruce Richardson #endif 862af75078fSIntel 863af75078fSIntel argvopt = argv; 864af75078fSIntel 865268888b5SRavi Kerur /* Error or normal output strings. */ 86688617471SOlivier Matz while ((opt = getopt_long(argc, argvopt, short_options, 867af75078fSIntel lgopts, &option_index)) != EOF) { 868af75078fSIntel 869af75078fSIntel switch (opt) { 870af75078fSIntel /* portmask */ 871af75078fSIntel case 'p': 872af75078fSIntel enabled_port_mask = parse_portmask(optarg); 873af75078fSIntel if (enabled_port_mask == 0) { 874c53a5fafSStephen Hemminger fprintf(stderr, "Invalid portmask\n"); 875af75078fSIntel print_usage(prgname); 876af75078fSIntel return -1; 877af75078fSIntel } 878af75078fSIntel break; 87988617471SOlivier Matz 880af75078fSIntel case 'P': 881af75078fSIntel promiscuous_on = 1; 882af75078fSIntel break; 883af75078fSIntel 884268888b5SRavi Kerur case 'E': 8859510dd1fSConor Walsh if (lookup_mode != L3FWD_LOOKUP_DEFAULT) { 8869510dd1fSConor Walsh fprintf(stderr, "Only one lookup mode is allowed at a time!\n"); 8879510dd1fSConor Walsh return -1; 8889510dd1fSConor Walsh } 8899510dd1fSConor Walsh lookup_mode = L3FWD_LOOKUP_EM; 890268888b5SRavi Kerur break; 891268888b5SRavi Kerur 892268888b5SRavi Kerur case 'L': 8939510dd1fSConor Walsh if (lookup_mode != L3FWD_LOOKUP_DEFAULT) { 8949510dd1fSConor Walsh fprintf(stderr, "Only one lookup mode is allowed at a time!\n"); 8959510dd1fSConor Walsh return -1; 8969510dd1fSConor Walsh } 8979510dd1fSConor Walsh lookup_mode = L3FWD_LOOKUP_LPM; 898268888b5SRavi Kerur break; 899268888b5SRavi Kerur 900af75078fSIntel /* long options */ 90188617471SOlivier Matz case CMD_LINE_OPT_CONFIG_NUM: 902af75078fSIntel ret = parse_config(optarg); 903af75078fSIntel if (ret) { 904c53a5fafSStephen Hemminger fprintf(stderr, "Invalid config\n"); 905af75078fSIntel print_usage(prgname); 906af75078fSIntel return -1; 907af75078fSIntel } 908e2de1f7bSSunil Kumar Kori lcore_params = 1; 90988617471SOlivier Matz break; 910af75078fSIntel 9118efffaecSHonnappa Nagarahalli case CMD_LINE_OPT_RX_QUEUE_SIZE_NUM: 9128efffaecSHonnappa Nagarahalli parse_queue_size(optarg, &nb_rxd, 1); 9138efffaecSHonnappa Nagarahalli break; 9148efffaecSHonnappa Nagarahalli 9158efffaecSHonnappa Nagarahalli case CMD_LINE_OPT_TX_QUEUE_SIZE_NUM: 9168efffaecSHonnappa Nagarahalli parse_queue_size(optarg, &nb_txd, 0); 9178efffaecSHonnappa Nagarahalli break; 9188efffaecSHonnappa Nagarahalli 919d5c4897eSJie Hai case CMD_LINE_OPT_PKT_BURST_NUM: 920d5c4897eSJie Hai parse_pkt_burst(optarg); 921d5c4897eSJie Hai break; 922d5c4897eSJie Hai 923*d9f26e52SJie Hai case CMD_LINE_OPT_MB_CACHE_SIZE_NUM: 924*d9f26e52SJie Hai parse_mbcache_size(optarg); 925*d9f26e52SJie Hai break; 926*d9f26e52SJie Hai 92788617471SOlivier Matz case CMD_LINE_OPT_ETH_DEST_NUM: 928bd785f6fSAndrey Chilikin parse_eth_dest(optarg); 92988617471SOlivier Matz break; 930bd785f6fSAndrey Chilikin 93188617471SOlivier Matz case CMD_LINE_OPT_NO_NUMA_NUM: 932af75078fSIntel numa_on = 0; 93388617471SOlivier Matz break; 934f68aad79SIntel 93588617471SOlivier Matz case CMD_LINE_OPT_IPV6_NUM: 936997ee890SIntel ipv6 = 1; 93788617471SOlivier Matz break; 938997ee890SIntel 9391bb4a528SFerruh Yigit case CMD_LINE_OPT_MAX_PKT_LEN_NUM: 9401bb4a528SFerruh Yigit max_pkt_len = parse_max_pkt_len(optarg); 94188617471SOlivier Matz break; 942268888b5SRavi Kerur 94388617471SOlivier Matz case CMD_LINE_OPT_HASH_ENTRY_NUM_NUM: 944f5251734SKamalakshitha Aligeri fprintf(stderr, "Hash entry number will be ignored\n"); 94588617471SOlivier Matz break; 94671a7e242SJianfeng Tan 94788617471SOlivier Matz case CMD_LINE_OPT_PARSE_PTYPE_NUM: 94871a7e242SJianfeng Tan printf("soft parse-ptype is enabled\n"); 94971a7e242SJianfeng Tan parse_ptype = 1; 950af75078fSIntel break; 951af75078fSIntel 9524b01cabfSTrevor Tao case CMD_LINE_OPT_RELAX_RX_OFFLOAD_NUM: 9534b01cabfSTrevor Tao printf("Rx offload is relaxed\n"); 9544b01cabfSTrevor Tao relax_rx_offload = 1; 9554b01cabfSTrevor Tao break; 9564b01cabfSTrevor Tao 957f9800c32STrevor Tao case CMD_LINE_OPT_DISABLE_RSS_NUM: 958f9800c32STrevor Tao printf("RSS is disabled\n"); 959f9800c32STrevor Tao disable_rss = 1; 960f9800c32STrevor Tao break; 961f9800c32STrevor Tao 962f0a26885SShreyansh Jain case CMD_LINE_OPT_PARSE_PER_PORT_POOL: 963f0a26885SShreyansh Jain printf("per port buffer pool is enabled\n"); 964f0a26885SShreyansh Jain per_port_pool = 1; 965f0a26885SShreyansh Jain break; 966f0a26885SShreyansh Jain 967e2de1f7bSSunil Kumar Kori case CMD_LINE_OPT_MODE_NUM: 968e2de1f7bSSunil Kumar Kori parse_mode(optarg); 969e2de1f7bSSunil Kumar Kori break; 970e2de1f7bSSunil Kumar Kori 971ef827078SBruce Richardson #ifdef RTE_LIB_EVENTDEV 972e2de1f7bSSunil Kumar Kori case CMD_LINE_OPT_EVENTQ_SYNC_NUM: 973e2de1f7bSSunil Kumar Kori parse_eventq_sched(optarg); 974e2de1f7bSSunil Kumar Kori eventq_sched = 1; 975e2de1f7bSSunil Kumar Kori break; 976e2de1f7bSSunil Kumar Kori 977e2de1f7bSSunil Kumar Kori case CMD_LINE_OPT_EVENT_ETH_RX_QUEUES_NUM: 978e2de1f7bSSunil Kumar Kori parse_event_eth_rx_queues(optarg); 979e2de1f7bSSunil Kumar Kori eth_rx_q = 1; 980e2de1f7bSSunil Kumar Kori break; 981e2de1f7bSSunil Kumar Kori 982ef827078SBruce Richardson case CMD_LINE_OPT_ENABLE_VECTOR_NUM: 983ef827078SBruce Richardson printf("event vectorization is enabled\n"); 984ef827078SBruce Richardson evt_rsrc->vector_enabled = 1; 985ef827078SBruce Richardson break; 986ef827078SBruce Richardson 987ef827078SBruce Richardson case CMD_LINE_OPT_VECTOR_SIZE_NUM: 988ef827078SBruce Richardson evt_rsrc->vector_size = strtol(optarg, NULL, 10); 989ef827078SBruce Richardson break; 990ef827078SBruce Richardson 991ef827078SBruce Richardson case CMD_LINE_OPT_VECTOR_TMO_NS_NUM: 992ef827078SBruce Richardson evt_rsrc->vector_tmo_ns = strtoull(optarg, NULL, 10); 993ef827078SBruce Richardson break; 994ef827078SBruce Richardson #endif 995ef827078SBruce Richardson 9969510dd1fSConor Walsh case CMD_LINE_OPT_LOOKUP_NUM: 9979510dd1fSConor Walsh if (lookup_mode != L3FWD_LOOKUP_DEFAULT) { 9989510dd1fSConor Walsh fprintf(stderr, "Only one lookup mode is allowed at a time!\n"); 9999510dd1fSConor Walsh return -1; 10009510dd1fSConor Walsh } 10019510dd1fSConor Walsh ret = parse_lookup(optarg); 10029510dd1fSConor Walsh /* 10039510dd1fSConor Walsh * If parse_lookup was passed an invalid lookup type 10049510dd1fSConor Walsh * then return -1. Error log included within 10059510dd1fSConor Walsh * parse_lookup for simplicity. 10069510dd1fSConor Walsh */ 10079510dd1fSConor Walsh if (ret) 10089510dd1fSConor Walsh return -1; 10099510dd1fSConor Walsh break; 10109510dd1fSConor Walsh 101152def963SSean Morrissey case CMD_LINE_OPT_RULE_IPV4_NUM: 101252def963SSean Morrissey l3fwd_set_rule_ipv4_name(optarg); 101352def963SSean Morrissey break; 101452def963SSean Morrissey case CMD_LINE_OPT_RULE_IPV6_NUM: 101552def963SSean Morrissey l3fwd_set_rule_ipv6_name(optarg); 101652def963SSean Morrissey break; 10176de0ea50SSean Morrissey case CMD_LINE_OPT_ALG_NUM: 10186de0ea50SSean Morrissey l3fwd_set_alg(optarg); 10196de0ea50SSean Morrissey break; 1020af75078fSIntel default: 1021af75078fSIntel print_usage(prgname); 1022af75078fSIntel return -1; 1023af75078fSIntel } 1024af75078fSIntel } 1025af75078fSIntel 1026ef827078SBruce Richardson RTE_SET_USED(lcore_params); /* needed if no eventdev block */ 1027ef827078SBruce Richardson #ifdef RTE_LIB_EVENTDEV 1028e2de1f7bSSunil Kumar Kori if (evt_rsrc->enabled && lcore_params) { 1029e2de1f7bSSunil Kumar Kori fprintf(stderr, "lcore config is not valid when event mode is selected\n"); 1030e2de1f7bSSunil Kumar Kori return -1; 1031e2de1f7bSSunil Kumar Kori } 1032e2de1f7bSSunil Kumar Kori 1033e2de1f7bSSunil Kumar Kori if (!evt_rsrc->enabled && eth_rx_q) { 1034e2de1f7bSSunil Kumar Kori fprintf(stderr, "eth_rx_queues is valid only when event mode is selected\n"); 1035e2de1f7bSSunil Kumar Kori return -1; 1036e2de1f7bSSunil Kumar Kori } 1037e2de1f7bSSunil Kumar Kori 1038e2de1f7bSSunil Kumar Kori if (!evt_rsrc->enabled && eventq_sched) { 1039e2de1f7bSSunil Kumar Kori fprintf(stderr, "eventq_sched is valid only when event mode is selected\n"); 1040e2de1f7bSSunil Kumar Kori return -1; 1041e2de1f7bSSunil Kumar Kori } 1042e2de1f7bSSunil Kumar Kori 1043e8adca19SShijith Thotton if (evt_rsrc->vector_enabled && !evt_rsrc->vector_size) { 1044e8adca19SShijith Thotton evt_rsrc->vector_size = VECTOR_SIZE_DEFAULT; 1045e8adca19SShijith Thotton fprintf(stderr, "vector size set to default (%" PRIu16 ")\n", 1046e8adca19SShijith Thotton evt_rsrc->vector_size); 1047e8adca19SShijith Thotton } 1048e8adca19SShijith Thotton 1049e8adca19SShijith Thotton if (evt_rsrc->vector_enabled && !evt_rsrc->vector_tmo_ns) { 1050e8adca19SShijith Thotton evt_rsrc->vector_tmo_ns = VECTOR_TMO_NS_DEFAULT; 1051e8adca19SShijith Thotton fprintf(stderr, 1052e8adca19SShijith Thotton "vector timeout set to default (%" PRIu64 " ns)\n", 1053e8adca19SShijith Thotton evt_rsrc->vector_tmo_ns); 1054e8adca19SShijith Thotton } 1055ef827078SBruce Richardson #endif 1056e8adca19SShijith Thotton 1057268888b5SRavi Kerur /* 1058268888b5SRavi Kerur * Nothing is selected, pick longest-prefix match 1059268888b5SRavi Kerur * as default match. 1060268888b5SRavi Kerur */ 10619510dd1fSConor Walsh if (lookup_mode == L3FWD_LOOKUP_DEFAULT) { 10626de0ea50SSean Morrissey fprintf(stderr, "Neither ACL, LPM, EM, or FIB selected, defaulting to LPM\n"); 10639510dd1fSConor Walsh lookup_mode = L3FWD_LOOKUP_LPM; 1064268888b5SRavi Kerur } 1065268888b5SRavi Kerur 10666de0ea50SSean Morrissey /* For ACL, update port config rss hash filter */ 10676de0ea50SSean Morrissey if (lookup_mode == L3FWD_LOOKUP_ACL) { 10686de0ea50SSean Morrissey port_conf.rx_adv_conf.rss_conf.rss_hf |= 10696de0ea50SSean Morrissey RTE_ETH_RSS_UDP | RTE_ETH_RSS_TCP | RTE_ETH_RSS_SCTP; 10706de0ea50SSean Morrissey } 10716de0ea50SSean Morrissey 1072af75078fSIntel if (optind >= 0) 1073af75078fSIntel argv[optind-1] = prgname; 1074af75078fSIntel 1075af75078fSIntel ret = optind-1; 10769d5ca532SKeith Wiles optind = 1; /* reset getopt lib */ 1077af75078fSIntel return ret; 1078af75078fSIntel } 1079af75078fSIntel 1080af75078fSIntel static void 10816d13ea8eSOlivier Matz print_ethaddr(const char *name, const struct rte_ether_addr *eth_addr) 1082af75078fSIntel { 108335b2d13fSOlivier Matz char buf[RTE_ETHER_ADDR_FMT_SIZE]; 108435b2d13fSOlivier Matz rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, eth_addr); 1085ec3d82dbSCunming Liang printf("%s%s", name, buf); 1086af75078fSIntel } 1087af75078fSIntel 1088a65bf3d7SSunil Kumar Kori int 1089f0a26885SShreyansh Jain init_mem(uint16_t portid, unsigned int nb_mbuf) 1090af75078fSIntel { 1091ef827078SBruce Richardson #ifdef RTE_LIB_EVENTDEV 1092e8adca19SShijith Thotton struct l3fwd_event_resources *evt_rsrc = l3fwd_get_eventdev_rsrc(); 1093ef827078SBruce Richardson #endif 1094af75078fSIntel struct lcore_conf *qconf; 1095af75078fSIntel int socketid; 1096af75078fSIntel unsigned lcore_id; 1097af75078fSIntel char s[64]; 1098af75078fSIntel 1099af75078fSIntel for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { 1100af75078fSIntel if (rte_lcore_is_enabled(lcore_id) == 0) 1101af75078fSIntel continue; 1102af75078fSIntel 1103af75078fSIntel if (numa_on) 1104af75078fSIntel socketid = rte_lcore_to_socket_id(lcore_id); 1105af75078fSIntel else 1106af75078fSIntel socketid = 0; 1107af75078fSIntel 1108af75078fSIntel if (socketid >= NB_SOCKETS) { 1109268888b5SRavi Kerur rte_exit(EXIT_FAILURE, 1110268888b5SRavi Kerur "Socket %d of lcore %u is out of range %d\n", 1111af75078fSIntel socketid, lcore_id, NB_SOCKETS); 1112af75078fSIntel } 1113268888b5SRavi Kerur 1114f0a26885SShreyansh Jain if (pktmbuf_pool[portid][socketid] == NULL) { 1115f0a26885SShreyansh Jain snprintf(s, sizeof(s), "mbuf_pool_%d:%d", 1116f0a26885SShreyansh Jain portid, socketid); 1117f0a26885SShreyansh Jain pktmbuf_pool[portid][socketid] = 1118ea0c20eaSOlivier Matz rte_pktmbuf_pool_create(s, nb_mbuf, 1119*d9f26e52SJie Hai mb_mempool_cache_size, 0, 1120824cb29cSKonstantin Ananyev RTE_MBUF_DEFAULT_BUF_SIZE, socketid); 1121f0a26885SShreyansh Jain if (pktmbuf_pool[portid][socketid] == NULL) 1122af75078fSIntel rte_exit(EXIT_FAILURE, 1123268888b5SRavi Kerur "Cannot init mbuf pool on socket %d\n", 1124268888b5SRavi Kerur socketid); 1125af75078fSIntel else 1126268888b5SRavi Kerur printf("Allocated mbuf pool on socket %d\n", 1127268888b5SRavi Kerur socketid); 1128af75078fSIntel 11296de0ea50SSean Morrissey /* Setup ACL, LPM, EM(f.e Hash) or FIB. But, only once per 1130f0a26885SShreyansh Jain * available socket. 1131f0a26885SShreyansh Jain */ 1132f0a26885SShreyansh Jain if (!lkp_per_socket[socketid]) { 1133268888b5SRavi Kerur l3fwd_lkp.setup(socketid); 1134f0a26885SShreyansh Jain lkp_per_socket[socketid] = 1; 1135f0a26885SShreyansh Jain } 1136af75078fSIntel } 1137e8adca19SShijith Thotton 1138ef827078SBruce Richardson #ifdef RTE_LIB_EVENTDEV 1139e8adca19SShijith Thotton if (evt_rsrc->vector_enabled && vector_pool[portid] == NULL) { 1140e8adca19SShijith Thotton unsigned int nb_vec; 1141e8adca19SShijith Thotton 1142e8adca19SShijith Thotton nb_vec = (nb_mbuf + evt_rsrc->vector_size - 1) / 1143e8adca19SShijith Thotton evt_rsrc->vector_size; 114431edfc4aSPavan Nikhilesh nb_vec = RTE_MAX(512U, nb_vec); 114531edfc4aSPavan Nikhilesh nb_vec += rte_lcore_count() * 32; 1146e8adca19SShijith Thotton snprintf(s, sizeof(s), "vector_pool_%d", portid); 1147e8adca19SShijith Thotton vector_pool[portid] = rte_event_vector_pool_create( 114831edfc4aSPavan Nikhilesh s, nb_vec, 32, evt_rsrc->vector_size, socketid); 1149e8adca19SShijith Thotton if (vector_pool[portid] == NULL) 1150e8adca19SShijith Thotton rte_exit(EXIT_FAILURE, 1151e8adca19SShijith Thotton "Failed to create vector pool for port %d\n", 1152e8adca19SShijith Thotton portid); 1153e8adca19SShijith Thotton else 1154e8adca19SShijith Thotton printf("Allocated vector pool for port %d\n", 1155e8adca19SShijith Thotton portid); 1156e8adca19SShijith Thotton } 1157ef827078SBruce Richardson #endif 1158e8adca19SShijith Thotton 1159af75078fSIntel qconf = &lcore_conf[lcore_id]; 1160268888b5SRavi Kerur qconf->ipv4_lookup_struct = 1161268888b5SRavi Kerur l3fwd_lkp.get_ipv4_lookup_struct(socketid); 1162268888b5SRavi Kerur qconf->ipv6_lookup_struct = 1163268888b5SRavi Kerur l3fwd_lkp.get_ipv6_lookup_struct(socketid); 1164af75078fSIntel } 1165af75078fSIntel return 0; 1166af75078fSIntel } 1167af75078fSIntel 1168d3641ae8SIntel /* Check the link status of all ports in up to 9s, and print them finally */ 1169d3641ae8SIntel static void 11708728ccf3SThomas Monjalon check_all_ports_link_status(uint32_t port_mask) 1171d3641ae8SIntel { 1172d3641ae8SIntel #define CHECK_INTERVAL 100 /* 100ms */ 1173d3641ae8SIntel #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ 1174f8244c63SZhiyong Yang uint16_t portid; 1175f8244c63SZhiyong Yang uint8_t count, all_ports_up, print_flag = 0; 1176d3641ae8SIntel struct rte_eth_link link; 117722e5c73bSIgor Romanov int ret; 1178db4e8135SIvan Dyukov char link_status_text[RTE_ETH_LINK_MAX_STR_LEN]; 1179d3641ae8SIntel 1180d3641ae8SIntel printf("\nChecking link status"); 1181d3641ae8SIntel fflush(stdout); 1182d3641ae8SIntel for (count = 0; count <= MAX_CHECK_TIME; count++) { 1183308df2bfSZhihong Wang if (force_quit) 1184308df2bfSZhihong Wang return; 1185d3641ae8SIntel all_ports_up = 1; 11868728ccf3SThomas Monjalon RTE_ETH_FOREACH_DEV(portid) { 1187308df2bfSZhihong Wang if (force_quit) 1188308df2bfSZhihong Wang return; 1189d3641ae8SIntel if ((port_mask & (1 << portid)) == 0) 1190d3641ae8SIntel continue; 1191d3641ae8SIntel memset(&link, 0, sizeof(link)); 119222e5c73bSIgor Romanov ret = rte_eth_link_get_nowait(portid, &link); 119322e5c73bSIgor Romanov if (ret < 0) { 119422e5c73bSIgor Romanov all_ports_up = 0; 119522e5c73bSIgor Romanov if (print_flag == 1) 119622e5c73bSIgor Romanov printf("Port %u link get failed: %s\n", 119722e5c73bSIgor Romanov portid, rte_strerror(-ret)); 119822e5c73bSIgor Romanov continue; 119922e5c73bSIgor Romanov } 1200d3641ae8SIntel /* print link status if flag set */ 1201d3641ae8SIntel if (print_flag == 1) { 1202db4e8135SIvan Dyukov rte_eth_link_to_str(link_status_text, 1203db4e8135SIvan Dyukov sizeof(link_status_text), &link); 1204db4e8135SIvan Dyukov printf("Port %d %s\n", portid, 1205db4e8135SIvan Dyukov link_status_text); 1206d3641ae8SIntel continue; 1207d3641ae8SIntel } 1208d3641ae8SIntel /* clear all_ports_up flag if any link down */ 1209295968d1SFerruh Yigit if (link.link_status == RTE_ETH_LINK_DOWN) { 1210d3641ae8SIntel all_ports_up = 0; 1211d3641ae8SIntel break; 1212d3641ae8SIntel } 1213d3641ae8SIntel } 1214d3641ae8SIntel /* after finally printing all link status, get out */ 1215d3641ae8SIntel if (print_flag == 1) 1216d3641ae8SIntel break; 1217d3641ae8SIntel 1218d3641ae8SIntel if (all_ports_up == 0) { 1219d3641ae8SIntel printf("."); 1220d3641ae8SIntel fflush(stdout); 1221d3641ae8SIntel rte_delay_ms(CHECK_INTERVAL); 1222d3641ae8SIntel } 1223d3641ae8SIntel 1224d3641ae8SIntel /* set the print_flag if all ports up or timeout */ 1225d3641ae8SIntel if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) { 1226d3641ae8SIntel print_flag = 1; 1227d3641ae8SIntel printf("done\n"); 1228d3641ae8SIntel } 1229d3641ae8SIntel } 1230d3641ae8SIntel } 1231d3641ae8SIntel 1232308df2bfSZhihong Wang static void 1233308df2bfSZhihong Wang signal_handler(int signum) 1234308df2bfSZhihong Wang { 1235308df2bfSZhihong Wang if (signum == SIGINT || signum == SIGTERM) { 1236308df2bfSZhihong Wang printf("\n\nSignal %d received, preparing to exit...\n", 1237308df2bfSZhihong Wang signum); 1238308df2bfSZhihong Wang force_quit = true; 1239308df2bfSZhihong Wang } 1240308df2bfSZhihong Wang } 1241308df2bfSZhihong Wang 124271a7e242SJianfeng Tan static int 1243f8244c63SZhiyong Yang prepare_ptype_parser(uint16_t portid, uint16_t queueid) 124471a7e242SJianfeng Tan { 124571a7e242SJianfeng Tan if (parse_ptype) { 124671a7e242SJianfeng Tan printf("Port %d: softly parse packet type info\n", portid); 124771a7e242SJianfeng Tan if (rte_eth_add_rx_callback(portid, queueid, 124871a7e242SJianfeng Tan l3fwd_lkp.cb_parse_ptype, 124971a7e242SJianfeng Tan NULL)) 125071a7e242SJianfeng Tan return 1; 125171a7e242SJianfeng Tan 125271a7e242SJianfeng Tan printf("Failed to add rx callback: port=%d\n", portid); 125371a7e242SJianfeng Tan return 0; 125471a7e242SJianfeng Tan } 125571a7e242SJianfeng Tan 125671a7e242SJianfeng Tan if (l3fwd_lkp.check_ptype(portid)) 125771a7e242SJianfeng Tan return 1; 125871a7e242SJianfeng Tan 125971a7e242SJianfeng Tan printf("port %d cannot parse packet type, please add --%s\n", 126071a7e242SJianfeng Tan portid, CMD_LINE_OPT_PARSE_PTYPE); 126171a7e242SJianfeng Tan return 0; 126271a7e242SJianfeng Tan } 126371a7e242SJianfeng Tan 12641bb4a528SFerruh Yigit static uint32_t 12651bb4a528SFerruh Yigit eth_dev_get_overhead_len(uint32_t max_rx_pktlen, uint16_t max_mtu) 12661bb4a528SFerruh Yigit { 12671bb4a528SFerruh Yigit uint32_t overhead_len; 12681bb4a528SFerruh Yigit 12691bb4a528SFerruh Yigit if (max_mtu != UINT16_MAX && max_rx_pktlen > max_mtu) 12701bb4a528SFerruh Yigit overhead_len = max_rx_pktlen - max_mtu; 12711bb4a528SFerruh Yigit else 12721bb4a528SFerruh Yigit overhead_len = RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN; 12731bb4a528SFerruh Yigit 12741bb4a528SFerruh Yigit return overhead_len; 12751bb4a528SFerruh Yigit } 12761bb4a528SFerruh Yigit 12773f045555SNithin Dabilpuram int 12781bb4a528SFerruh Yigit config_port_max_pkt_len(struct rte_eth_conf *conf, 12791bb4a528SFerruh Yigit struct rte_eth_dev_info *dev_info) 12801bb4a528SFerruh Yigit { 12811bb4a528SFerruh Yigit uint32_t overhead_len; 12821bb4a528SFerruh Yigit 12831bb4a528SFerruh Yigit if (max_pkt_len == 0) 12841bb4a528SFerruh Yigit return 0; 12851bb4a528SFerruh Yigit 12861bb4a528SFerruh Yigit if (max_pkt_len < RTE_ETHER_MIN_LEN || max_pkt_len > MAX_JUMBO_PKT_LEN) 12871bb4a528SFerruh Yigit return -1; 12881bb4a528SFerruh Yigit 12891bb4a528SFerruh Yigit overhead_len = eth_dev_get_overhead_len(dev_info->max_rx_pktlen, 12901bb4a528SFerruh Yigit dev_info->max_mtu); 12911bb4a528SFerruh Yigit conf->rxmode.mtu = max_pkt_len - overhead_len; 12921bb4a528SFerruh Yigit 1293b563c142SFerruh Yigit if (conf->rxmode.mtu > RTE_ETHER_MTU) 1294295968d1SFerruh Yigit conf->txmode.offloads |= RTE_ETH_TX_OFFLOAD_MULTI_SEGS; 12951bb4a528SFerruh Yigit 12961bb4a528SFerruh Yigit return 0; 12971bb4a528SFerruh Yigit } 12981bb4a528SFerruh Yigit 12998bd537e9SPavan Nikhilesh static void 13008bd537e9SPavan Nikhilesh l3fwd_poll_resource_setup(void) 1301af75078fSIntel { 1302b23c5bd7SSivaprasad Tummala uint8_t socketid; 1303b23c5bd7SSivaprasad Tummala uint16_t nb_rx_queue, queue; 13048bd537e9SPavan Nikhilesh struct rte_eth_dev_info dev_info; 13058bd537e9SPavan Nikhilesh uint32_t n_tx_queue, nb_lcores; 13068bd537e9SPavan Nikhilesh struct rte_eth_txconf *txconf; 13078bd537e9SPavan Nikhilesh struct lcore_conf *qconf; 13088bd537e9SPavan Nikhilesh uint16_t queueid, portid; 13098bd537e9SPavan Nikhilesh unsigned int nb_ports; 13108bd537e9SPavan Nikhilesh unsigned int lcore_id; 13118bd537e9SPavan Nikhilesh int ret; 1312e2de1f7bSSunil Kumar Kori 1313af75078fSIntel if (check_lcore_params() < 0) 1314af75078fSIntel rte_exit(EXIT_FAILURE, "check_lcore_params failed\n"); 1315af75078fSIntel 1316af75078fSIntel ret = init_lcore_rx_queues(); 1317af75078fSIntel if (ret < 0) 1318af75078fSIntel rte_exit(EXIT_FAILURE, "init_lcore_rx_queues failed\n"); 1319af75078fSIntel 1320d9a42a69SThomas Monjalon nb_ports = rte_eth_dev_count_avail(); 1321af75078fSIntel 1322a9dbe180SThomas Monjalon if (check_port_config() < 0) 1323af75078fSIntel rte_exit(EXIT_FAILURE, "check_port_config failed\n"); 1324af75078fSIntel 1325af75078fSIntel nb_lcores = rte_lcore_count(); 1326af75078fSIntel 1327af75078fSIntel /* initialize all ports */ 13288728ccf3SThomas Monjalon RTE_ETH_FOREACH_DEV(portid) { 13291ef9600bSShahaf Shuler struct rte_eth_conf local_port_conf = port_conf; 13301ef9600bSShahaf Shuler 1331af75078fSIntel /* skip ports that are not enabled */ 1332af75078fSIntel if ((enabled_port_mask & (1 << portid)) == 0) { 1333af75078fSIntel printf("\nSkipping disabled port %d\n", portid); 1334af75078fSIntel continue; 1335af75078fSIntel } 1336af75078fSIntel 1337af75078fSIntel /* init port */ 1338af75078fSIntel printf("Initializing port %d ... ", portid ); 1339af75078fSIntel fflush(stdout); 1340af75078fSIntel 1341af75078fSIntel nb_rx_queue = get_port_n_rx_queues(portid); 1342af75078fSIntel n_tx_queue = nb_lcores; 1343af75078fSIntel if (n_tx_queue > MAX_TX_QUEUE_PER_PORT) 1344af75078fSIntel n_tx_queue = MAX_TX_QUEUE_PER_PORT; 1345af75078fSIntel printf("Creating queues: nb_rxq=%d nb_txq=%u... ", 1346af75078fSIntel nb_rx_queue, (unsigned)n_tx_queue ); 13471ef9600bSShahaf Shuler 1348089e5ed7SIvan Ilchenko ret = rte_eth_dev_info_get(portid, &dev_info); 1349089e5ed7SIvan Ilchenko if (ret != 0) 1350089e5ed7SIvan Ilchenko rte_exit(EXIT_FAILURE, 1351089e5ed7SIvan Ilchenko "Error during getting device (port %u) info: %s\n", 1352089e5ed7SIvan Ilchenko portid, strerror(-ret)); 1353089e5ed7SIvan Ilchenko 13541bb4a528SFerruh Yigit ret = config_port_max_pkt_len(&local_port_conf, &dev_info); 13551bb4a528SFerruh Yigit if (ret != 0) 13561bb4a528SFerruh Yigit rte_exit(EXIT_FAILURE, 13571bb4a528SFerruh Yigit "Invalid max packet length: %u (port %u)\n", 13581bb4a528SFerruh Yigit max_pkt_len, portid); 13591bb4a528SFerruh Yigit 1360295968d1SFerruh Yigit if (dev_info.tx_offload_capa & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) 13611ef9600bSShahaf Shuler local_port_conf.txmode.offloads |= 1362295968d1SFerruh Yigit RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE; 13634f5701f2SFerruh Yigit 13644f5701f2SFerruh Yigit local_port_conf.rx_adv_conf.rss_conf.rss_hf &= 13654f5701f2SFerruh Yigit dev_info.flow_type_rss_offloads; 136697986fa5SChaoyong He 1367f9800c32STrevor Tao if (disable_rss == 1 || dev_info.max_rx_queues == 1) 1368295968d1SFerruh Yigit local_port_conf.rxmode.mq_mode = RTE_ETH_MQ_RX_NONE; 136997986fa5SChaoyong He 13704f5701f2SFerruh Yigit if (local_port_conf.rx_adv_conf.rss_conf.rss_hf != 13714f5701f2SFerruh Yigit port_conf.rx_adv_conf.rss_conf.rss_hf) { 13724f5701f2SFerruh Yigit printf("Port %u modified RSS hash function based on hardware support," 13734f5701f2SFerruh Yigit "requested:%#"PRIx64" configured:%#"PRIx64"\n", 13744f5701f2SFerruh Yigit portid, 13754f5701f2SFerruh Yigit port_conf.rx_adv_conf.rss_conf.rss_hf, 13764f5701f2SFerruh Yigit local_port_conf.rx_adv_conf.rss_conf.rss_hf); 13774f5701f2SFerruh Yigit } 13784f5701f2SFerruh Yigit 13794b01cabfSTrevor Tao /* Relax Rx offload requirement */ 13804b01cabfSTrevor Tao if ((local_port_conf.rxmode.offloads & dev_info.rx_offload_capa) != 13814b01cabfSTrevor Tao local_port_conf.rxmode.offloads) { 13824b01cabfSTrevor Tao printf("Port %u requested Rx offloads 0x%"PRIx64 13834b01cabfSTrevor Tao " does not match Rx offloads capabilities 0x%"PRIx64"\n", 13844b01cabfSTrevor Tao portid, local_port_conf.rxmode.offloads, 13854b01cabfSTrevor Tao dev_info.rx_offload_capa); 13864b01cabfSTrevor Tao if (relax_rx_offload) { 13874b01cabfSTrevor Tao local_port_conf.rxmode.offloads &= dev_info.rx_offload_capa; 13884b01cabfSTrevor Tao printf("Warning: modified Rx offload to 0x%"PRIx64 13894b01cabfSTrevor Tao " based on device capability\n", 13904b01cabfSTrevor Tao local_port_conf.rxmode.offloads); 13914b01cabfSTrevor Tao } 13924b01cabfSTrevor Tao } 13934b01cabfSTrevor Tao 1394af75078fSIntel ret = rte_eth_dev_configure(portid, nb_rx_queue, 13951ef9600bSShahaf Shuler (uint16_t)n_tx_queue, &local_port_conf); 1396af75078fSIntel if (ret < 0) 1397268888b5SRavi Kerur rte_exit(EXIT_FAILURE, 1398268888b5SRavi Kerur "Cannot configure device: err=%d, port=%d\n", 1399af75078fSIntel ret, portid); 1400af75078fSIntel 140160efb44fSRoman Zhukov ret = rte_eth_dev_adjust_nb_rx_tx_desc(portid, &nb_rxd, 140260efb44fSRoman Zhukov &nb_txd); 140360efb44fSRoman Zhukov if (ret < 0) 140460efb44fSRoman Zhukov rte_exit(EXIT_FAILURE, 140560efb44fSRoman Zhukov "Cannot adjust number of descriptors: err=%d, " 140660efb44fSRoman Zhukov "port=%d\n", ret, portid); 140760efb44fSRoman Zhukov 140870febdcfSIgor Romanov ret = rte_eth_macaddr_get(portid, &ports_eth_addr[portid]); 140970febdcfSIgor Romanov if (ret < 0) 141070febdcfSIgor Romanov rte_exit(EXIT_FAILURE, 141170febdcfSIgor Romanov "Cannot get MAC address: err=%d, port=%d\n", 141270febdcfSIgor Romanov ret, portid); 141370febdcfSIgor Romanov 1414af75078fSIntel print_ethaddr(" Address:", &ports_eth_addr[portid]); 1415af75078fSIntel printf(", "); 1416bd785f6fSAndrey Chilikin print_ethaddr("Destination:", 14176d13ea8eSOlivier Matz (const struct rte_ether_addr *)&dest_eth_addr[portid]); 1418bd785f6fSAndrey Chilikin printf(", "); 1419af75078fSIntel 142096ff4453SKonstantin Ananyev /* 1421bd785f6fSAndrey Chilikin * prepare src MACs for each port. 142296ff4453SKonstantin Ananyev */ 1423538da7a1SOlivier Matz rte_ether_addr_copy(&ports_eth_addr[portid], 14246d13ea8eSOlivier Matz (struct rte_ether_addr *)(val_eth + portid) + 1); 142596ff4453SKonstantin Ananyev 1426f68aad79SIntel /* init memory */ 1427f0a26885SShreyansh Jain if (!per_port_pool) { 1428f0a26885SShreyansh Jain /* portid = 0; this is *not* signifying the first port, 1429f0a26885SShreyansh Jain * rather, it signifies that portid is ignored. 1430f0a26885SShreyansh Jain */ 1431f0a26885SShreyansh Jain ret = init_mem(0, NB_MBUF(nb_ports)); 1432f0a26885SShreyansh Jain } else { 1433f0a26885SShreyansh Jain ret = init_mem(portid, NB_MBUF(1)); 1434f0a26885SShreyansh Jain } 1435f68aad79SIntel if (ret < 0) 1436f68aad79SIntel rte_exit(EXIT_FAILURE, "init_mem failed\n"); 1437af75078fSIntel 1438af75078fSIntel /* init one TX queue per couple (lcore,port) */ 1439af75078fSIntel queueid = 0; 1440af75078fSIntel for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { 1441af75078fSIntel if (rte_lcore_is_enabled(lcore_id) == 0) 1442af75078fSIntel continue; 1443af75078fSIntel 1444af75078fSIntel if (numa_on) 1445268888b5SRavi Kerur socketid = 1446268888b5SRavi Kerur (uint8_t)rte_lcore_to_socket_id(lcore_id); 1447af75078fSIntel else 1448af75078fSIntel socketid = 0; 1449af75078fSIntel 1450af75078fSIntel printf("txq=%u,%d,%d ", lcore_id, queueid, socketid); 1451af75078fSIntel fflush(stdout); 145281f7ecd9SPablo de Lara 145381f7ecd9SPablo de Lara txconf = &dev_info.default_txconf; 14541ef9600bSShahaf Shuler txconf->offloads = local_port_conf.txmode.offloads; 1455af75078fSIntel ret = rte_eth_tx_queue_setup(portid, queueid, nb_txd, 145681f7ecd9SPablo de Lara socketid, txconf); 1457af75078fSIntel if (ret < 0) 1458268888b5SRavi Kerur rte_exit(EXIT_FAILURE, 1459268888b5SRavi Kerur "rte_eth_tx_queue_setup: err=%d, " 1460af75078fSIntel "port=%d\n", ret, portid); 1461af75078fSIntel 1462af75078fSIntel qconf = &lcore_conf[lcore_id]; 1463af75078fSIntel qconf->tx_queue_id[portid] = queueid; 1464af75078fSIntel queueid++; 146552c97adcSTomasz Kulasek 146652c97adcSTomasz Kulasek qconf->tx_port_id[qconf->n_tx_port] = portid; 14679d203b76STomasz Kulasek qconf->n_tx_port++; 1468af75078fSIntel } 1469af75078fSIntel printf("\n"); 1470af75078fSIntel } 1471af75078fSIntel 1472af75078fSIntel for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { 1473af75078fSIntel if (rte_lcore_is_enabled(lcore_id) == 0) 1474af75078fSIntel continue; 1475af75078fSIntel qconf = &lcore_conf[lcore_id]; 1476af75078fSIntel printf("\nInitializing rx queues on lcore %u ... ", lcore_id ); 1477af75078fSIntel fflush(stdout); 1478af75078fSIntel /* init RX queues */ 1479af75078fSIntel for(queue = 0; queue < qconf->n_rx_queue; ++queue) { 14807015f232SKamil Vojanec struct rte_eth_conf local_conf; 14811ef9600bSShahaf Shuler struct rte_eth_rxconf rxq_conf; 14821ef9600bSShahaf Shuler 1483af75078fSIntel portid = qconf->rx_queue_list[queue].port_id; 1484af75078fSIntel queueid = qconf->rx_queue_list[queue].queue_id; 1485af75078fSIntel 1486af75078fSIntel if (numa_on) 1487268888b5SRavi Kerur socketid = 1488268888b5SRavi Kerur (uint8_t)rte_lcore_to_socket_id(lcore_id); 1489af75078fSIntel else 1490af75078fSIntel socketid = 0; 1491af75078fSIntel 1492af75078fSIntel printf("rxq=%d,%d,%d ", portid, queueid, socketid); 1493af75078fSIntel fflush(stdout); 1494af75078fSIntel 1495089e5ed7SIvan Ilchenko ret = rte_eth_dev_info_get(portid, &dev_info); 1496089e5ed7SIvan Ilchenko if (ret != 0) 1497089e5ed7SIvan Ilchenko rte_exit(EXIT_FAILURE, 1498089e5ed7SIvan Ilchenko "Error during getting device (port %u) info: %s\n", 1499089e5ed7SIvan Ilchenko portid, strerror(-ret)); 1500089e5ed7SIvan Ilchenko 15017015f232SKamil Vojanec ret = rte_eth_dev_conf_get(portid, &local_conf); 15027015f232SKamil Vojanec if (ret != 0) 15037015f232SKamil Vojanec rte_exit(EXIT_FAILURE, 15047015f232SKamil Vojanec "Error during getting device (port %u) configuration: %s\n", 15057015f232SKamil Vojanec portid, strerror(-ret)); 15067015f232SKamil Vojanec 15071ef9600bSShahaf Shuler rxq_conf = dev_info.default_rxconf; 15087015f232SKamil Vojanec rxq_conf.offloads = local_conf.rxmode.offloads; 1509f0a26885SShreyansh Jain if (!per_port_pool) 1510f0a26885SShreyansh Jain ret = rte_eth_rx_queue_setup(portid, queueid, 1511f0a26885SShreyansh Jain nb_rxd, socketid, 15121ef9600bSShahaf Shuler &rxq_conf, 1513f0a26885SShreyansh Jain pktmbuf_pool[0][socketid]); 1514f0a26885SShreyansh Jain else 1515f0a26885SShreyansh Jain ret = rte_eth_rx_queue_setup(portid, queueid, 1516f0a26885SShreyansh Jain nb_rxd, socketid, 1517f0a26885SShreyansh Jain &rxq_conf, 1518f0a26885SShreyansh Jain pktmbuf_pool[portid][socketid]); 1519af75078fSIntel if (ret < 0) 1520268888b5SRavi Kerur rte_exit(EXIT_FAILURE, 1521268888b5SRavi Kerur "rte_eth_rx_queue_setup: err=%d, port=%d\n", 1522268888b5SRavi Kerur ret, portid); 1523af75078fSIntel } 1524af75078fSIntel } 15258bd537e9SPavan Nikhilesh } 15268bd537e9SPavan Nikhilesh 15278bd537e9SPavan Nikhilesh static inline int 15288bd537e9SPavan Nikhilesh l3fwd_service_enable(uint32_t service_id) 15298bd537e9SPavan Nikhilesh { 15308bd537e9SPavan Nikhilesh uint8_t min_service_count = UINT8_MAX; 15318bd537e9SPavan Nikhilesh uint32_t slcore_array[RTE_MAX_LCORE]; 15328bd537e9SPavan Nikhilesh unsigned int slcore = 0; 15338bd537e9SPavan Nikhilesh uint8_t service_count; 15348bd537e9SPavan Nikhilesh int32_t slcore_count; 15358bd537e9SPavan Nikhilesh 15368bd537e9SPavan Nikhilesh if (!rte_service_lcore_count()) 15378bd537e9SPavan Nikhilesh return -ENOENT; 15388bd537e9SPavan Nikhilesh 15398bd537e9SPavan Nikhilesh slcore_count = rte_service_lcore_list(slcore_array, RTE_MAX_LCORE); 15408bd537e9SPavan Nikhilesh if (slcore_count < 0) 15418bd537e9SPavan Nikhilesh return -ENOENT; 15428bd537e9SPavan Nikhilesh /* Get the core which has least number of services running. */ 15438bd537e9SPavan Nikhilesh while (slcore_count--) { 15448bd537e9SPavan Nikhilesh /* Reset default mapping */ 1545c1c48e76SPavan Nikhilesh if (rte_service_map_lcore_set(service_id, 1546c1c48e76SPavan Nikhilesh slcore_array[slcore_count], 0) != 0) 1547c1c48e76SPavan Nikhilesh return -ENOENT; 15488bd537e9SPavan Nikhilesh service_count = rte_service_lcore_count_services( 15498bd537e9SPavan Nikhilesh slcore_array[slcore_count]); 15508bd537e9SPavan Nikhilesh if (service_count < min_service_count) { 15518bd537e9SPavan Nikhilesh slcore = slcore_array[slcore_count]; 15528bd537e9SPavan Nikhilesh min_service_count = service_count; 15538bd537e9SPavan Nikhilesh } 15548bd537e9SPavan Nikhilesh } 15558bd537e9SPavan Nikhilesh if (rte_service_map_lcore_set(service_id, slcore, 1)) 15568bd537e9SPavan Nikhilesh return -ENOENT; 15578bd537e9SPavan Nikhilesh rte_service_lcore_start(slcore); 15588bd537e9SPavan Nikhilesh 15598bd537e9SPavan Nikhilesh return 0; 15608bd537e9SPavan Nikhilesh } 15618bd537e9SPavan Nikhilesh 1562ef827078SBruce Richardson #ifdef RTE_LIB_EVENTDEV 15638bd537e9SPavan Nikhilesh static void 15648bd537e9SPavan Nikhilesh l3fwd_event_service_setup(void) 15658bd537e9SPavan Nikhilesh { 15668bd537e9SPavan Nikhilesh struct l3fwd_event_resources *evt_rsrc = l3fwd_get_eventdev_rsrc(); 15678bd537e9SPavan Nikhilesh struct rte_event_dev_info evdev_info; 15688bd537e9SPavan Nikhilesh uint32_t service_id, caps; 15698bd537e9SPavan Nikhilesh int ret, i; 15708bd537e9SPavan Nikhilesh 15718bd537e9SPavan Nikhilesh rte_event_dev_info_get(evt_rsrc->event_d_id, &evdev_info); 15728bd537e9SPavan Nikhilesh if (!(evdev_info.event_dev_cap & RTE_EVENT_DEV_CAP_DISTRIBUTED_SCHED)) { 15738bd537e9SPavan Nikhilesh ret = rte_event_dev_service_id_get(evt_rsrc->event_d_id, 15748bd537e9SPavan Nikhilesh &service_id); 15758bd537e9SPavan Nikhilesh if (ret != -ESRCH && ret != 0) 15768bd537e9SPavan Nikhilesh rte_exit(EXIT_FAILURE, 15778bd537e9SPavan Nikhilesh "Error in starting eventdev service\n"); 15788bd537e9SPavan Nikhilesh l3fwd_service_enable(service_id); 15798bd537e9SPavan Nikhilesh } 15808bd537e9SPavan Nikhilesh 15818bd537e9SPavan Nikhilesh for (i = 0; i < evt_rsrc->rx_adptr.nb_rx_adptr; i++) { 15828bd537e9SPavan Nikhilesh ret = rte_event_eth_rx_adapter_caps_get(evt_rsrc->event_d_id, 15838bd537e9SPavan Nikhilesh evt_rsrc->rx_adptr.rx_adptr[i], &caps); 15848bd537e9SPavan Nikhilesh if (ret < 0) 15858bd537e9SPavan Nikhilesh rte_exit(EXIT_FAILURE, 15868bd537e9SPavan Nikhilesh "Failed to get Rx adapter[%d] caps\n", 15878bd537e9SPavan Nikhilesh evt_rsrc->rx_adptr.rx_adptr[i]); 15888bd537e9SPavan Nikhilesh ret = rte_event_eth_rx_adapter_service_id_get( 15898bd537e9SPavan Nikhilesh evt_rsrc->event_d_id, 15908bd537e9SPavan Nikhilesh &service_id); 15918bd537e9SPavan Nikhilesh if (ret != -ESRCH && ret != 0) 15928bd537e9SPavan Nikhilesh rte_exit(EXIT_FAILURE, 15938bd537e9SPavan Nikhilesh "Error in starting Rx adapter[%d] service\n", 15948bd537e9SPavan Nikhilesh evt_rsrc->rx_adptr.rx_adptr[i]); 15958bd537e9SPavan Nikhilesh l3fwd_service_enable(service_id); 15968bd537e9SPavan Nikhilesh } 15978bd537e9SPavan Nikhilesh 15988bd537e9SPavan Nikhilesh for (i = 0; i < evt_rsrc->tx_adptr.nb_tx_adptr; i++) { 15998bd537e9SPavan Nikhilesh ret = rte_event_eth_tx_adapter_caps_get(evt_rsrc->event_d_id, 16008bd537e9SPavan Nikhilesh evt_rsrc->tx_adptr.tx_adptr[i], &caps); 16018bd537e9SPavan Nikhilesh if (ret < 0) 16028bd537e9SPavan Nikhilesh rte_exit(EXIT_FAILURE, 16038bd537e9SPavan Nikhilesh "Failed to get Rx adapter[%d] caps\n", 16048bd537e9SPavan Nikhilesh evt_rsrc->tx_adptr.tx_adptr[i]); 16058bd537e9SPavan Nikhilesh ret = rte_event_eth_tx_adapter_service_id_get( 16068bd537e9SPavan Nikhilesh evt_rsrc->event_d_id, 16078bd537e9SPavan Nikhilesh &service_id); 16088bd537e9SPavan Nikhilesh if (ret != -ESRCH && ret != 0) 16098bd537e9SPavan Nikhilesh rte_exit(EXIT_FAILURE, 16108bd537e9SPavan Nikhilesh "Error in starting Rx adapter[%d] service\n", 16118bd537e9SPavan Nikhilesh evt_rsrc->tx_adptr.tx_adptr[i]); 16128bd537e9SPavan Nikhilesh l3fwd_service_enable(service_id); 16138bd537e9SPavan Nikhilesh } 16148bd537e9SPavan Nikhilesh } 1615ef827078SBruce Richardson #endif 16168bd537e9SPavan Nikhilesh 16178bd537e9SPavan Nikhilesh int 16188bd537e9SPavan Nikhilesh main(int argc, char **argv) 16198bd537e9SPavan Nikhilesh { 1620ef827078SBruce Richardson #ifdef RTE_LIB_EVENTDEV 16218bd537e9SPavan Nikhilesh struct l3fwd_event_resources *evt_rsrc; 1622ef827078SBruce Richardson int i; 1623ef827078SBruce Richardson #endif 16248bd537e9SPavan Nikhilesh struct lcore_conf *qconf; 16258bd537e9SPavan Nikhilesh uint16_t queueid, portid; 16268bd537e9SPavan Nikhilesh unsigned int lcore_id; 1627b23c5bd7SSivaprasad Tummala uint16_t queue; 1628ef827078SBruce Richardson int ret; 16298bd537e9SPavan Nikhilesh 16308bd537e9SPavan Nikhilesh /* init EAL */ 16318bd537e9SPavan Nikhilesh ret = rte_eal_init(argc, argv); 16328bd537e9SPavan Nikhilesh if (ret < 0) 16338bd537e9SPavan Nikhilesh rte_exit(EXIT_FAILURE, "Invalid EAL parameters\n"); 16348bd537e9SPavan Nikhilesh argc -= ret; 16358bd537e9SPavan Nikhilesh argv += ret; 16368bd537e9SPavan Nikhilesh 16378bd537e9SPavan Nikhilesh force_quit = false; 16388bd537e9SPavan Nikhilesh signal(SIGINT, signal_handler); 16398bd537e9SPavan Nikhilesh signal(SIGTERM, signal_handler); 16408bd537e9SPavan Nikhilesh 16418bd537e9SPavan Nikhilesh /* pre-init dst MACs for all ports to 02:00:00:00:00:xx */ 16428bd537e9SPavan Nikhilesh for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) { 16438bd537e9SPavan Nikhilesh dest_eth_addr[portid] = 16448bd537e9SPavan Nikhilesh RTE_ETHER_LOCAL_ADMIN_ADDR + ((uint64_t)portid << 40); 16458bd537e9SPavan Nikhilesh *(uint64_t *)(val_eth + portid) = dest_eth_addr[portid]; 16468bd537e9SPavan Nikhilesh } 16478bd537e9SPavan Nikhilesh 1648ef827078SBruce Richardson #ifdef RTE_LIB_EVENTDEV 16498bd537e9SPavan Nikhilesh evt_rsrc = l3fwd_get_eventdev_rsrc(); 1650ef827078SBruce Richardson #endif 16518bd537e9SPavan Nikhilesh /* parse application arguments (after the EAL ones) */ 16528bd537e9SPavan Nikhilesh ret = parse_args(argc, argv); 16538bd537e9SPavan Nikhilesh if (ret < 0) 16548bd537e9SPavan Nikhilesh rte_exit(EXIT_FAILURE, "Invalid L3FWD parameters\n"); 16558bd537e9SPavan Nikhilesh 16568bd537e9SPavan Nikhilesh /* Setup function pointers for lookup method. */ 16578bd537e9SPavan Nikhilesh setup_l3fwd_lookup_tables(); 16588bd537e9SPavan Nikhilesh 165952def963SSean Morrissey /* Add the config file rules */ 166052def963SSean Morrissey l3fwd_lkp.read_config_files(); 166152def963SSean Morrissey 1662ef827078SBruce Richardson #ifdef RTE_LIB_EVENTDEV 16638bd537e9SPavan Nikhilesh evt_rsrc->per_port_pool = per_port_pool; 16648bd537e9SPavan Nikhilesh evt_rsrc->pkt_pool = pktmbuf_pool; 1665e8adca19SShijith Thotton evt_rsrc->vec_pool = vector_pool; 16668bd537e9SPavan Nikhilesh evt_rsrc->port_mask = enabled_port_mask; 16678bd537e9SPavan Nikhilesh /* Configure eventdev parameters if user has requested */ 16688bd537e9SPavan Nikhilesh if (evt_rsrc->enabled) { 16698bd537e9SPavan Nikhilesh l3fwd_event_resource_setup(&port_conf); 16709510dd1fSConor Walsh if (lookup_mode == L3FWD_LOOKUP_EM) 1671a434a02dSPavan Nikhilesh l3fwd_lkp.main_loop = evt_rsrc->ops.em_event_loop; 16729510dd1fSConor Walsh else if (lookup_mode == L3FWD_LOOKUP_FIB) 16739510dd1fSConor Walsh l3fwd_lkp.main_loop = evt_rsrc->ops.fib_event_loop; 1674a434a02dSPavan Nikhilesh else 167599fc91d1SPavan Nikhilesh l3fwd_lkp.main_loop = evt_rsrc->ops.lpm_event_loop; 16768bd537e9SPavan Nikhilesh } else 1677ef827078SBruce Richardson #endif 16788bd537e9SPavan Nikhilesh l3fwd_poll_resource_setup(); 1679af75078fSIntel 1680af75078fSIntel /* start ports */ 16818728ccf3SThomas Monjalon RTE_ETH_FOREACH_DEV(portid) { 1682af75078fSIntel if ((enabled_port_mask & (1 << portid)) == 0) { 1683af75078fSIntel continue; 1684af75078fSIntel } 1685af75078fSIntel /* Start device */ 1686af75078fSIntel ret = rte_eth_dev_start(portid); 1687af75078fSIntel if (ret < 0) 1688268888b5SRavi Kerur rte_exit(EXIT_FAILURE, 1689268888b5SRavi Kerur "rte_eth_dev_start: err=%d, port=%d\n", 1690af75078fSIntel ret, portid); 1691af75078fSIntel 1692af75078fSIntel /* 1693af75078fSIntel * If enabled, put device in promiscuous mode. 1694af75078fSIntel * This allows IO forwarding mode to forward packets 1695af75078fSIntel * to itself through 2 cross-connected ports of the 1696af75078fSIntel * target machine. 1697af75078fSIntel */ 1698f430bbceSIvan Ilchenko if (promiscuous_on) { 1699f430bbceSIvan Ilchenko ret = rte_eth_promiscuous_enable(portid); 1700f430bbceSIvan Ilchenko if (ret != 0) 1701f430bbceSIvan Ilchenko rte_exit(EXIT_FAILURE, 1702f430bbceSIvan Ilchenko "rte_eth_promiscuous_enable: err=%s, port=%u\n", 1703f430bbceSIvan Ilchenko rte_strerror(-ret), portid); 1704f430bbceSIvan Ilchenko } 1705af75078fSIntel } 1706af75078fSIntel 1707495709d3SKonstantin Ananyev #ifdef RTE_LIB_EVENTDEV 1708495709d3SKonstantin Ananyev if (evt_rsrc->enabled) 1709495709d3SKonstantin Ananyev l3fwd_event_service_setup(); 1710495709d3SKonstantin Ananyev #endif 1711495709d3SKonstantin Ananyev 171271a7e242SJianfeng Tan printf("\n"); 171371a7e242SJianfeng Tan 171471a7e242SJianfeng Tan for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { 171571a7e242SJianfeng Tan if (rte_lcore_is_enabled(lcore_id) == 0) 171671a7e242SJianfeng Tan continue; 171771a7e242SJianfeng Tan qconf = &lcore_conf[lcore_id]; 171871a7e242SJianfeng Tan for (queue = 0; queue < qconf->n_rx_queue; ++queue) { 171971a7e242SJianfeng Tan portid = qconf->rx_queue_list[queue].port_id; 172071a7e242SJianfeng Tan queueid = qconf->rx_queue_list[queue].queue_id; 172171a7e242SJianfeng Tan if (prepare_ptype_parser(portid, queueid) == 0) 172271a7e242SJianfeng Tan rte_exit(EXIT_FAILURE, "ptype check fails\n"); 172371a7e242SJianfeng Tan } 172471a7e242SJianfeng Tan } 172571a7e242SJianfeng Tan 17268728ccf3SThomas Monjalon check_all_ports_link_status(enabled_port_mask); 1727d3641ae8SIntel 1728308df2bfSZhihong Wang ret = 0; 1729af75078fSIntel /* launch per-lcore init on every lcore */ 1730cb056611SStephen Hemminger rte_eal_mp_remote_launch(l3fwd_lkp.main_loop, NULL, CALL_MAIN); 1731ef827078SBruce Richardson 1732ef827078SBruce Richardson #ifdef RTE_LIB_EVENTDEV 1733af76ee50SPavan Nikhilesh if (evt_rsrc->enabled) { 1734af76ee50SPavan Nikhilesh for (i = 0; i < evt_rsrc->rx_adptr.nb_rx_adptr; i++) 1735af76ee50SPavan Nikhilesh rte_event_eth_rx_adapter_stop( 1736af76ee50SPavan Nikhilesh evt_rsrc->rx_adptr.rx_adptr[i]); 1737af76ee50SPavan Nikhilesh for (i = 0; i < evt_rsrc->tx_adptr.nb_tx_adptr; i++) 1738af76ee50SPavan Nikhilesh rte_event_eth_tx_adapter_stop( 1739af76ee50SPavan Nikhilesh evt_rsrc->tx_adptr.tx_adptr[i]); 1740af76ee50SPavan Nikhilesh 1741af76ee50SPavan Nikhilesh RTE_ETH_FOREACH_DEV(portid) { 1742af76ee50SPavan Nikhilesh if ((enabled_port_mask & (1 << portid)) == 0) 1743af76ee50SPavan Nikhilesh continue; 1744b55efbabSIvan Ilchenko ret = rte_eth_dev_stop(portid); 1745b55efbabSIvan Ilchenko if (ret != 0) 1746b55efbabSIvan Ilchenko printf("rte_eth_dev_stop: err=%d, port=%u\n", 1747b55efbabSIvan Ilchenko ret, portid); 1748af75078fSIntel } 1749af75078fSIntel 1750af76ee50SPavan Nikhilesh rte_eal_mp_wait_lcore(); 1751af76ee50SPavan Nikhilesh RTE_ETH_FOREACH_DEV(portid) { 1752af76ee50SPavan Nikhilesh if ((enabled_port_mask & (1 << portid)) == 0) 1753af76ee50SPavan Nikhilesh continue; 1754af76ee50SPavan Nikhilesh rte_eth_dev_close(portid); 1755af76ee50SPavan Nikhilesh } 1756af76ee50SPavan Nikhilesh 1757af76ee50SPavan Nikhilesh rte_event_dev_stop(evt_rsrc->event_d_id); 1758af76ee50SPavan Nikhilesh rte_event_dev_close(evt_rsrc->event_d_id); 1759af76ee50SPavan Nikhilesh 1760ef827078SBruce Richardson } else 1761ef827078SBruce Richardson #endif 1762ef827078SBruce Richardson { 1763af76ee50SPavan Nikhilesh rte_eal_mp_wait_lcore(); 1764af76ee50SPavan Nikhilesh 17658728ccf3SThomas Monjalon RTE_ETH_FOREACH_DEV(portid) { 1766308df2bfSZhihong Wang if ((enabled_port_mask & (1 << portid)) == 0) 1767308df2bfSZhihong Wang continue; 1768308df2bfSZhihong Wang printf("Closing port %d...", portid); 1769b55efbabSIvan Ilchenko ret = rte_eth_dev_stop(portid); 1770b55efbabSIvan Ilchenko if (ret != 0) 1771b55efbabSIvan Ilchenko printf("rte_eth_dev_stop: err=%d, port=%u\n", 1772b55efbabSIvan Ilchenko ret, portid); 1773308df2bfSZhihong Wang rte_eth_dev_close(portid); 1774308df2bfSZhihong Wang printf(" Done\n"); 1775308df2bfSZhihong Wang } 1776af76ee50SPavan Nikhilesh } 177710aa3757SChengchang Tang 177852def963SSean Morrissey /* clean up config file routes */ 177952def963SSean Morrissey l3fwd_lkp.free_routes(); 178052def963SSean Morrissey 178110aa3757SChengchang Tang /* clean up the EAL */ 178210aa3757SChengchang Tang rte_eal_cleanup(); 178310aa3757SChengchang Tang 1784308df2bfSZhihong Wang printf("Bye...\n"); 1785308df2bfSZhihong Wang 1786308df2bfSZhihong Wang return ret; 1787af75078fSIntel } 1788