X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=examples%2Fl3fwd%2Fmain.c;h=fd6605bffac004db2193c58b937ac3e3f1556285;hb=065a0cbaeb8b7308a0def85d42a69c179b5963f0;hp=97a1423d3de90a127b4d9bd5ba5ac1e83f671cb0;hpb=a6b450805ba18ae5768dd6f303843f8b6807e97d;p=dpdk.git diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c index 97a1423d3d..fd6605bffa 100644 --- a/examples/l3fwd/main.c +++ b/examples/l3fwd/main.c @@ -66,7 +66,6 @@ #include #include #include -#include #include #include #include @@ -103,6 +102,8 @@ static int l3fwd_lpm_on; static int l3fwd_em_on; static int numa_on = 1; /**< NUMA is enabled by default. */ +static int parse_ptype; /**< Parse packet type using rx callback, and */ + /**< disabled by default */ /* Global variables. */ @@ -155,7 +156,7 @@ static struct rte_eth_conf port_conf = { .hw_ip_checksum = 1, /**< IP checksum offload enabled */ .hw_vlan_filter = 0, /**< VLAN filtering disabled */ .jumbo_frame = 0, /**< Jumbo Frame Support disabled */ - .hw_strip_crc = 0, /**< CRC stripped by hardware */ + .hw_strip_crc = 1, /**< CRC stripped by hardware */ }, .rx_adv_conf = { .rss_conf = { @@ -172,6 +173,8 @@ static struct rte_mempool * pktmbuf_pool[NB_SOCKETS]; struct l3fwd_lkp_mode { void (*setup)(int); + int (*check_ptype)(int); + rte_rx_callback_fn cb_parse_ptype; int (*main_loop)(void *); void* (*get_ipv4_lookup_struct)(int); void* (*get_ipv6_lookup_struct)(int); @@ -181,6 +184,8 @@ static struct l3fwd_lkp_mode l3fwd_lkp; static struct l3fwd_lkp_mode l3fwd_em_lkp = { .setup = setup_hash, + .check_ptype = em_check_ptype, + .cb_parse_ptype = em_cb_parse_ptype, .main_loop = em_main_loop, .get_ipv4_lookup_struct = em_get_ipv4_l3fwd_lookup_struct, .get_ipv6_lookup_struct = em_get_ipv6_l3fwd_lookup_struct, @@ -188,6 +193,8 @@ static struct l3fwd_lkp_mode l3fwd_em_lkp = { static struct l3fwd_lkp_mode l3fwd_lpm_lkp = { .setup = setup_lpm, + .check_ptype = lpm_check_ptype, + .cb_parse_ptype = lpm_cb_parse_ptype, .main_loop = lpm_main_loop, .get_ipv4_lookup_struct = lpm_get_ipv4_l3fwd_lookup_struct, .get_ipv6_lookup_struct = lpm_get_ipv6_l3fwd_lookup_struct, @@ -303,20 +310,32 @@ init_lcore_rx_queues(void) static void print_usage(const char *prgname) { - printf ("%s [EAL options] -- -p PORTMASK -P" - " [--config (port,queue,lcore)[,(port,queue,lcore]]" - " [--enable-jumbo [--max-pkt-len PKTLEN]]\n" - " -p PORTMASK: hexadecimal bitmask of ports to configure\n" - " -P : enable promiscuous mode\n" - " -E : enable exact match\n" - " -L : enable longest prefix match\n" - " --config (port,queue,lcore): rx queues configuration\n" - " --eth-dest=X,MM:MM:MM:MM:MM:MM: optional, ethernet destination for port X\n" - " --no-numa: optional, disable numa awareness\n" - " --ipv6: optional, specify it if running ipv6 packets\n" - " --enable-jumbo: enable jumbo frame" - " which max packet len is PKTLEN in decimal (64-9600)\n" - " --hash-entry-num: specify the hash entry number in hexadecimal to be setup\n", + printf("%s [EAL options] --" + " -p PORTMASK" + " [-P]" + " [-E]" + " [-L]" + " --config (port,queue,lcore)[,(port,queue,lcore)]" + " [--eth-dest=X,MM:MM:MM:MM:MM:MM]" + " [--enable-jumbo [--max-pkt-len PKTLEN]]" + " [--no-numa]" + " [--hash-entry-num]" + " [--ipv6]" + " [--parse-ptype]\n\n" + + " -p PORTMASK: Hexadecimal bitmask of ports to configure\n" + " -P : Enable promiscuous mode\n" + " -E : Enable exact match\n" + " -L : Enable longest prefix match (default)\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" + " --no-numa: Disable numa awareness\n" + " --hash-entry-num: Specify the hash entry number in hexadecimal to be setup\n" + " --ipv6: Set if running ipv6 packets\n" + " --parse-ptype: Set to use software to analyze packet type\n\n", prgname); } @@ -455,12 +474,45 @@ parse_eth_dest(const char *optarg) #define MAX_JUMBO_PKT_LEN 9600 #define MEMPOOL_CACHE_SIZE 256 +static const char short_options[] = + "p:" /* portmask */ + "P" /* promiscuous */ + "L" /* enable long prefix match */ + "E" /* enable exact match */ + ; + #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_IPV6 "ipv6" #define CMD_LINE_OPT_ENABLE_JUMBO "enable-jumbo" #define CMD_LINE_OPT_HASH_ENTRY_NUM "hash-entry-num" +#define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype" +enum { + /* long options mapped to a short option */ + + /* first long only option value must be >= 256, so that we won't + * conflict with short options */ + CMD_LINE_OPT_MIN_NUM = 256, + CMD_LINE_OPT_CONFIG_NUM, + CMD_LINE_OPT_ETH_DEST_NUM, + CMD_LINE_OPT_NO_NUMA_NUM, + CMD_LINE_OPT_IPV6_NUM, + CMD_LINE_OPT_ENABLE_JUMBO_NUM, + CMD_LINE_OPT_HASH_ENTRY_NUM_NUM, + CMD_LINE_OPT_PARSE_PTYPE_NUM, +}; + +static const struct option lgopts[] = { + {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_IPV6, 0, 0, CMD_LINE_OPT_IPV6_NUM}, + {CMD_LINE_OPT_ENABLE_JUMBO, 0, 0, CMD_LINE_OPT_ENABLE_JUMBO_NUM}, + {CMD_LINE_OPT_HASH_ENTRY_NUM, 1, 0, CMD_LINE_OPT_HASH_ENTRY_NUM_NUM}, + {CMD_LINE_OPT_PARSE_PTYPE, 0, 0, CMD_LINE_OPT_PARSE_PTYPE_NUM}, + {NULL, 0, 0, 0} +}; /* * This expression is used to calculate the number of mbufs needed @@ -484,15 +536,6 @@ parse_args(int argc, char **argv) char **argvopt; int option_index; char *prgname = argv[0]; - static struct option lgopts[] = { - {CMD_LINE_OPT_CONFIG, 1, 0, 0}, - {CMD_LINE_OPT_ETH_DEST, 1, 0, 0}, - {CMD_LINE_OPT_NO_NUMA, 0, 0, 0}, - {CMD_LINE_OPT_IPV6, 0, 0, 0}, - {CMD_LINE_OPT_ENABLE_JUMBO, 0, 0, 0}, - {CMD_LINE_OPT_HASH_ENTRY_NUM, 1, 0, 0}, - {NULL, 0, 0, 0} - }; argvopt = argv; @@ -513,7 +556,7 @@ parse_args(int argc, char **argv) "L3FWD: LPM and EM are mutually exclusive, select only one"; const char *str13 = "L3FWD: LPM or EM none selected, default LPM on"; - while ((opt = getopt_long(argc, argvopt, "p:PLE", + while ((opt = getopt_long(argc, argvopt, short_options, lgopts, &option_index)) != EOF) { switch (opt) { @@ -526,6 +569,7 @@ parse_args(int argc, char **argv) return -1; } break; + case 'P': printf("%s\n", str2); promiscuous_on = 1; @@ -542,81 +586,71 @@ parse_args(int argc, char **argv) break; /* long options */ - case 0: - if (!strncmp(lgopts[option_index].name, - CMD_LINE_OPT_CONFIG, - sizeof(CMD_LINE_OPT_CONFIG))) { - - ret = parse_config(optarg); - if (ret) { - printf("%s\n", str5); - print_usage(prgname); - return -1; - } - } - - if (!strncmp(lgopts[option_index].name, - CMD_LINE_OPT_ETH_DEST, - sizeof(CMD_LINE_OPT_ETH_DEST))) { - parse_eth_dest(optarg); - } - - if (!strncmp(lgopts[option_index].name, - CMD_LINE_OPT_NO_NUMA, - sizeof(CMD_LINE_OPT_NO_NUMA))) { - printf("%s\n", str6); - numa_on = 0; + case CMD_LINE_OPT_CONFIG_NUM: + ret = parse_config(optarg); + if (ret) { + printf("%s\n", str5); + print_usage(prgname); + return -1; } + break; - if (!strncmp(lgopts[option_index].name, - CMD_LINE_OPT_IPV6, - sizeof(CMD_LINE_OPT_IPV6))) { - printf("%sn", str7); - ipv6 = 1; - } + case CMD_LINE_OPT_ETH_DEST_NUM: + parse_eth_dest(optarg); + break; - if (!strncmp(lgopts[option_index].name, - CMD_LINE_OPT_ENABLE_JUMBO, - sizeof(CMD_LINE_OPT_ENABLE_JUMBO))) { - struct option lenopts = { - "max-pkt-len", required_argument, 0, 0 - }; - - printf("%s\n", str8); - port_conf.rxmode.jumbo_frame = 1; - - /* - * if no max-pkt-len set, use the default - * value ETHER_MAX_LEN. - */ - if (0 == getopt_long(argc, argvopt, "", - &lenopts, &option_index)) { - ret = parse_max_pkt_len(optarg); - if ((ret < 64) || - (ret > MAX_JUMBO_PKT_LEN)) { - printf("%s\n", str9); - print_usage(prgname); - return -1; - } - port_conf.rxmode.max_rx_pkt_len = ret; - } - printf("%s %u\n", str10, - (unsigned int)port_conf.rxmode.max_rx_pkt_len); - } + case CMD_LINE_OPT_NO_NUMA_NUM: + printf("%s\n", str6); + numa_on = 0; + break; - if (!strncmp(lgopts[option_index].name, - CMD_LINE_OPT_HASH_ENTRY_NUM, - sizeof(CMD_LINE_OPT_HASH_ENTRY_NUM))) { + case CMD_LINE_OPT_IPV6_NUM: + printf("%sn", str7); + ipv6 = 1; + break; - ret = parse_hash_entry_number(optarg); - if ((ret > 0) && (ret <= L3FWD_HASH_ENTRIES)) { - hash_entry_number = ret; - } else { - printf("%s\n", str11); + case CMD_LINE_OPT_ENABLE_JUMBO_NUM: { + struct option lenopts = { + "max-pkt-len", required_argument, 0, 0 + }; + + printf("%s\n", str8); + port_conf.rxmode.jumbo_frame = 1; + + /* + * if no max-pkt-len set, use the default + * value 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)) { + printf("%s\n", str9); print_usage(prgname); return -1; } + port_conf.rxmode.max_rx_pkt_len = ret; } + printf("%s %u\n", str10, + (unsigned int)port_conf.rxmode.max_rx_pkt_len); + break; + } + + case CMD_LINE_OPT_HASH_ENTRY_NUM_NUM: + ret = parse_hash_entry_number(optarg); + if ((ret > 0) && (ret <= L3FWD_HASH_ENTRIES)) { + hash_entry_number = ret; + } else { + printf("%s\n", str11); + print_usage(prgname); + return -1; + } + break; + + case CMD_LINE_OPT_PARSE_PTYPE_NUM: + printf("soft parse-ptype is enabled\n"); + parse_ptype = 1; break; default: @@ -654,7 +688,7 @@ parse_args(int argc, char **argv) argv[optind-1] = prgname; ret = optind-1; - optind = 0; /* reset getopt lib */ + optind = 1; /* reset getopt lib */ return ret; } @@ -751,7 +785,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask) continue; } /* clear all_ports_up flag if any link down */ - if (link.link_status == 0) { + if (link.link_status == ETH_LINK_DOWN) { all_ports_up = 0; break; } @@ -784,6 +818,28 @@ signal_handler(int signum) } } +static int +prepare_ptype_parser(uint8_t portid, uint16_t queueid) +{ + if (parse_ptype) { + printf("Port %d: softly parse packet type info\n", portid); + if (rte_eth_add_rx_callback(portid, queueid, + l3fwd_lkp.cb_parse_ptype, + NULL)) + return 1; + + printf("Failed to add rx callback: port=%d\n", portid); + return 0; + } + + if (l3fwd_lkp.check_ptype(portid)) + return 1; + + printf("port %d cannot parse packet type, please add --%s\n", + portid, CMD_LINE_OPT_PARSE_PTYPE); + return 0; +} + int main(int argc, char **argv) { @@ -796,7 +852,6 @@ main(int argc, char **argv) unsigned lcore_id; uint32_t n_tx_queue, nb_lcores; uint8_t portid, nb_rx_queue, queue, socketid; - uint8_t nb_tx_port; /* init EAL */ ret = rte_eal_init(argc, argv); @@ -829,14 +884,11 @@ main(int argc, char **argv) rte_exit(EXIT_FAILURE, "init_lcore_rx_queues failed\n"); nb_ports = rte_eth_dev_count(); - if (nb_ports > RTE_MAX_ETHPORTS) - nb_ports = RTE_MAX_ETHPORTS; if (check_port_config(nb_ports) < 0) rte_exit(EXIT_FAILURE, "check_port_config failed\n"); nb_lcores = rte_lcore_count(); - nb_tx_port = 0; /* Setup function pointers for lookup method. */ setup_l3fwd_lookup_tables(); @@ -914,12 +966,10 @@ main(int argc, char **argv) qconf->tx_queue_id[portid] = queueid; queueid++; - qconf->n_tx_port = nb_tx_port; qconf->tx_port_id[qconf->n_tx_port] = portid; + qconf->n_tx_port++; } printf("\n"); - - nb_tx_port++; } for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { @@ -977,6 +1027,21 @@ main(int argc, char **argv) rte_eth_promiscuous_enable(portid); } + printf("\n"); + + for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) { + if (rte_lcore_is_enabled(lcore_id) == 0) + continue; + qconf = &lcore_conf[lcore_id]; + for (queue = 0; queue < qconf->n_rx_queue; ++queue) { + portid = qconf->rx_queue_list[queue].port_id; + queueid = qconf->rx_queue_list[queue].queue_id; + if (prepare_ptype_parser(portid, queueid) == 0) + rte_exit(EXIT_FAILURE, "ptype check fails\n"); + } + } + + check_all_ports_link_status((uint8_t)nb_ports, enabled_port_mask); ret = 0;