diff options
author | Petri Savolainen <petri.savolainen@linaro.org> | 2018-05-16 09:56:19 +0300 |
---|---|---|
committer | Petri Savolainen <petri.savolainen@linaro.org> | 2018-05-16 09:56:19 +0300 |
commit | a0f68377b5123e6195f68dcfaf358798429a7ee6 (patch) | |
tree | 9e65b8629542ea3730ad02174eb5e13ec3359e6c | |
parent | c484446b4930b5398e958f855917d54a97e6f2c7 (diff) | |
parent | 0ee8255c2555ed68721ea5e7679f26a2e53bd8b8 (diff) |
Merge branch 'master' of https://github.com/Linaro/odp into odp-dpdk
34 files changed, 620 insertions, 384 deletions
diff --git a/example/classifier/odp_classifier.c b/example/classifier/odp_classifier.c index ddb934bed..3afe7645b 100644 --- a/example/classifier/odp_classifier.c +++ b/example/classifier/odp_classifier.c @@ -805,9 +805,7 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) static const char *shortopts = "+c:t:i:p:m:t:h"; /* let helper collect its own arguments (e.g. --odph_proc) */ - odph_parse_options(argc, argv, shortopts, longopts); - - opterr = 0; /* do not issue errors on helper options */ + argc = odph_parse_options(argc, argv); while (1) { opt = getopt_long(argc, argv, shortopts, diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index 9b62d1457..4392fe5e1 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -1492,7 +1492,7 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) static const char *shortopts = "+I:a:b:s:d:p:i:m:n:t:w:c:x:he:f:yr:z"; /* let helper collect its own arguments (e.g. --odph_proc) */ - odph_parse_options(argc, argv, shortopts, longopts); + argc = odph_parse_options(argc, argv); appl_args->mode = -1; /* Invalid, must be changed by parsing */ appl_args->number = -1; @@ -1506,8 +1506,6 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) appl_args->csum = 0; appl_args->sched = 0; - opterr = 0; /* do not issue errors on helper options */ - while (1) { opt = getopt_long(argc, argv, shortopts, longopts, &long_index); if (opt == -1) diff --git a/example/ipsec/odp_ipsec.c b/example/ipsec/odp_ipsec.c index 9f7efcaa2..05001a5eb 100644 --- a/example/ipsec/odp_ipsec.c +++ b/example/ipsec/odp_ipsec.c @@ -1366,14 +1366,12 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) static const char *shortopts = "+c:i:m:h:r:p:a:e:t:s:"; /* let helper collect its own arguments (e.g. --odph_proc) */ - odph_parse_options(argc, argv, shortopts, longopts); + argc = odph_parse_options(argc, argv); printf("\nParsing command line options\n"); appl_args->mode = 0; /* turn off async crypto API by default */ - opterr = 0; /* do not issue errors on helper options */ - while (!rc) { opt = getopt_long(argc, argv, shortopts, longopts, &long_index); diff --git a/example/ipsec_api/odp_ipsec.c b/example/ipsec_api/odp_ipsec.c index c428927df..8cd4caa96 100644 --- a/example/ipsec_api/odp_ipsec.c +++ b/example/ipsec_api/odp_ipsec.c @@ -1059,12 +1059,10 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) static const char *shortopts = "+c:i:h:lm:r:p:a:e:t:s:"; /* let helper collect its own arguments (e.g. --odph_proc) */ - odph_parse_options(argc, argv, shortopts, longopts); + argc = odph_parse_options(argc, argv); printf("\nParsing command line options\n"); - opterr = 0; /* do not issue errors on helper options */ - while (!rc) { opt = getopt_long(argc, argv, shortopts, longopts, &long_index); diff --git a/example/l2fwd_simple/odp_l2fwd_simple.c b/example/l2fwd_simple/odp_l2fwd_simple.c index 36b76ee1c..8fca73072 100644 --- a/example/l2fwd_simple/odp_l2fwd_simple.c +++ b/example/l2fwd_simple/odp_l2fwd_simple.c @@ -143,31 +143,15 @@ int main(int argc, char **argv) odph_odpthread_t thd[MAX_WORKERS]; odp_instance_t instance; odph_odpthread_params_t thr_params; - int opt; - int long_index; odph_ethaddr_t correct_src; uint32_t mtu1, mtu2; - static const struct option longopts[] = { {NULL, 0, NULL, 0} }; - static const char *shortopts = ""; - /* let helper collect its own arguments (e.g. --odph_proc) */ - odph_parse_options(argc, argv, shortopts, longopts); - - /* - * parse own options: currentely none, but this will move optind - * to the first non-option argument. (in case there where helprt args) - */ - opterr = 0; /* do not issue errors on helper options */ - while (1) { - opt = getopt_long(argc, argv, shortopts, longopts, &long_index); - if (-1 == opt) - break; /* No more options */ - } + argc = odph_parse_options(argc, argv); - if (argc != optind + 4 || - odph_eth_addr_parse(&global.dst, argv[optind + 2]) != 0 || - odph_eth_addr_parse(&global.src, argv[optind + 3]) != 0) { + if (argc != 5 || + odph_eth_addr_parse(&global.dst, argv[3]) != 0 || + odph_eth_addr_parse(&global.src, argv[4]) != 0) { printf("Usage: odp_l2fwd_simple eth0 eth1 01:02:03:04:05:06" " 07:08:09:0a:0b:0c\n"); printf("Where eth0 and eth1 are the used interfaces" @@ -201,10 +185,8 @@ int main(int argc, char **argv) exit(1); } - global.if0 = create_pktio(argv[optind], pool, &global.if0in, - &global.if0out); - global.if1 = create_pktio(argv[optind + 1], pool, &global.if1in, - &global.if1out); + global.if0 = create_pktio(argv[1], pool, &global.if0in, &global.if0out); + global.if1 = create_pktio(argv[2], pool, &global.if1in, &global.if1out); /* Do some operations to increase code coverage in tests */ if (odp_pktio_mac_addr(global.if0, &correct_src, sizeof(correct_src)) diff --git a/example/packet/odp_pktio.c b/example/packet/odp_pktio.c index caf82b7b2..fcce92b10 100644 --- a/example/packet/odp_pktio.c +++ b/example/packet/odp_pktio.c @@ -570,13 +570,11 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) static const char *shortopts = "+c:i:+m:t:h"; /* let helper collect its own arguments (e.g. --odph_proc) */ - odph_parse_options(argc, argv, shortopts, longopts); + argc = odph_parse_options(argc, argv); appl_args->mode = APPL_MODE_PKT_SCHED; appl_args->time = 0; /**< loop forever */ - opterr = 0; /* do not issue errors on helper options */ - while (1) { opt = getopt_long(argc, argv, shortopts, longopts, &long_index); diff --git a/example/switch/odp_switch.c b/example/switch/odp_switch.c index cc28eb6ca..26fcbbccc 100644 --- a/example/switch/odp_switch.c +++ b/example/switch/odp_switch.c @@ -760,13 +760,11 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) static const char *shortopts = "+c:+t:+a:i:h"; /* let helper collect its own arguments (e.g. --odph_proc) */ - odph_parse_options(argc, argv, shortopts, longopts); + argc = odph_parse_options(argc, argv); appl_args->time = 0; /* loop forever if time to run is 0 */ appl_args->accuracy = 10; /* get and print pps stats second */ - opterr = 0; /* do not issue errors on helper options */ - while (1) { opt = getopt_long(argc, argv, shortopts, longopts, &long_index); diff --git a/example/time/time_global_test.c b/example/time/time_global_test.c index a879745d3..317f9a270 100644 --- a/example/time/time_global_test.c +++ b/example/time/time_global_test.c @@ -259,7 +259,7 @@ int main(int argc, char *argv[]) odph_odpthread_params_t thr_params; /* let helper collect its own arguments (e.g. --odph_proc) */ - odph_parse_options(argc, argv, NULL, NULL); + argc = odph_parse_options(argc, argv); printf("\nODP global time test starts\n"); diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c index 1b0645a84..45eea7921 100644 --- a/example/timer/odp_timer_test.c +++ b/example/timer/odp_timer_test.c @@ -275,7 +275,7 @@ static void parse_args(int argc, char *argv[], test_args_t *args) static const char *shortopts = "+c:r:m:x:p:t:h"; /* let helper collect its own arguments (e.g. --odph_proc) */ - odph_parse_options(argc, argv, shortopts, longopts); + argc = odph_parse_options(argc, argv); /* defaults */ odp_timer_capability(ODP_CLOCK_CPU, &timer_capa); @@ -289,8 +289,6 @@ static void parse_args(int argc, char *argv[], test_args_t *args) args->period_us = 1000000; args->tmo_count = 30; - opterr = 0; /* do not issue errors on helper options */ - while (1) { opt = getopt_long(argc, argv, shortopts, longopts, &long_index); diff --git a/helper/include/odp/helper/threads.h b/helper/include/odp/helper/threads.h index ed7d7f39a..9d03c7192 100644 --- a/helper/include/odp/helper/threads.h +++ b/helper/include/odp/helper/threads.h @@ -146,74 +146,19 @@ int odph_odpthread_setaffinity(const int cpu); int odph_odpthread_getaffinity(void); /** - * Merge getopt options - * - * Given two sets of getopt options (each containing possibly both short - * options -a string- and long options -a option array-) this function - * return a single set (i.e. a string for short and an array for long) - * being the concatenation of the two given sets. - * Due to the fact that the size of these arrays is unknown at compilation - * time, this function actually mallocs the the resulting arrays. - * The fourth and fith parameters are actually pointers where these malloc'ed - * areas are returned. - * This means that the caller of this function has to free the two returned - * areas! - * - * @param shortopts1 first set of short options (a string) - * @param shortopts2 second set of short options (a string) - * @param longopts1 first set of long options (a getopt option array) - * @param longopts2 second set of long options (a getopt option array) - * @param shortopts a pointer where the address of the short options list - * (a string) is returned. It contains the concatenation of - * the two given short option strings. - * @param longopts a pointer where the address of the long options list - * (a getopt option array) is returned. - * It contains the concatenation of the two given long - * option arrays. - * if any of shortopts1, shortopts2, longopts1, longopts2 is NULL, the - * corresponding list as assumed to be empty. - * if any of shortopts, longopts is NULL, the corresponding malloc is not - * performed. - * - * @return On success: 0 : both shortopts and longopts are returned (assuming - * the given pointer where not null), possibly - * pointing to an empty string or an empty option array. - * On success, the caller is due to free these areas. - * On failure: -1: Nothing is malloc'ed. - */ -int odph_merge_getopt_options(const char *shortopts1, - const char *shortopts2, - const struct option *longopts1, - const struct option *longopts2, - char **shortopts, - struct option **longopts); - -/** * Parse linux helper options * - * Parse the command line options. Pick up options meant for the helper itself. - * If the caller is also having a set of option to parse, it should include - * their description here (shortopts desribes the short options and longopts - * describes the long options, as for getopt_long()). - * This function will issue errors on unknown arguments, so callers failing - * to pass their own command line options description here will see their - * options rejected. - * (the caller wants to set opterr to zero when parsing its own stuff - * with getopts to avoid reacting on helper's options). - * - * @param argc argument count - * @param argv argument values - * @param caller_shortopts caller's set of short options (string). or NULL. - * @param caller_longopts caller's set of long options (getopt option array). - * or NULL. - * - * @return On success: 0 - * On failure: -1 failure occurs if a value passed for a helper - * option is invalid, or on meeting unknown options. + * Parse the command line options. Pick up (--odph_ prefixed) options meant for + * the helper itself. When helper options are found, those are removed from + * argv[] and remaining options are packed to the beginning of the array. + * + * @param argc Argument count + * @param argv Argument vector + * + * @return New argument count. Original argument count decremented by + * the number of removed helper options. */ -int odph_parse_options(int argc, char *argv[], - const char *caller_shortopts, - const struct option *caller_longopts); +int odph_parse_options(int argc, char *argv[]); /** * @} diff --git a/helper/test/odpthreads.c b/helper/test/odpthreads.c index aa61e6352..ad48ec2d5 100644 --- a/helper/test/odpthreads.c +++ b/helper/test/odpthreads.c @@ -73,7 +73,7 @@ int main(int argc, char *argv[]) char cpumaskstr[ODP_CPUMASK_STR_SIZE]; /* let helper collect its own arguments (e.g. --odph_proc) */ - odph_parse_options(argc, argv, NULL, NULL); + argc = odph_parse_options(argc, argv); if (odp_init_global(&odp_instance, NULL, NULL)) { ODPH_ERR("Error: ODP global init failed.\n"); diff --git a/helper/threads.c b/helper/threads.c index f9216c7ed..86d6bf7be 100644 --- a/helper/threads.c +++ b/helper/threads.c @@ -330,129 +330,26 @@ int odph_odpthread_getaffinity(void) return -1; } -/* - * return the number of elements in an array of getopt options, excluding the - * terminating {0,0,0,0} - */ -static int get_getopt_options_length(const struct option *longopts) +int odph_parse_options(int argc, char *argv[]) { - int l = 0; - - if (!longopts) - return 0; - - while (longopts[l].name) - l++; - - return l; -} - -/* Merge getopt options */ -int odph_merge_getopt_options(const char *shortopts1, - const char *shortopts2, - const struct option *longopts1, - const struct option *longopts2, - char **shortopts, - struct option **longopts) -{ - int shortopts1_len; - int shortopts2_len; - int longopts1_len; - int longopts2_len; - int index; - int res_index = 0; - struct option termination = {0, 0, 0, 0}; - - /* merge short options: */ - if (shortopts) { - shortopts1_len = (shortopts1) ? strlen(shortopts1) : 0; - shortopts2_len = (shortopts2) ? strlen(shortopts2) : 0; - *shortopts = malloc(shortopts1_len + shortopts2_len + 1); - if (!*shortopts) - return -1; - - (*shortopts)[0] = 0; - - if (shortopts1) - strcpy((*shortopts), shortopts1); - if (shortopts2) - strcat((*shortopts), shortopts2); - } - - /* merge long options */ - if (!longopts) - return 0; - - longopts1_len = get_getopt_options_length(longopts1); - longopts2_len = get_getopt_options_length(longopts2); - *longopts = malloc(sizeof(struct option) * - (longopts1_len + longopts2_len + 1)); - if (!*longopts) { - if (shortopts) - free(*shortopts); - return -1; - } + int i, j; - for (index = 0; (longopts1) && (longopts1[index].name); index++) - (*longopts)[res_index++] = longopts1[index]; + helper_options.proc = 0; - for (index = 0; (longopts2) && (longopts2[index].name); index++) - (*longopts)[res_index++] = longopts2[index]; + /* Find and remove option */ + for (i = 0; i < argc;) { + if (strcmp(argv[i], "--odph_proc") == 0) { + helper_options.proc = 1; - (*longopts)[res_index] = termination; + for (j = i; j < argc - 1; j++) + argv[j] = argv[j + 1]; - return 0; -} - -/* - * Parse command line options to extract options affecting helpers. - */ -int odph_parse_options(int argc, char *argv[], - const char *caller_shortopts, - const struct option *caller_longopts) -{ - int c; - char *shortopts; - struct option *longopts; - int res = 0; - - static struct option helper_long_options[] = { - /* These options set a flag. */ - {"odph_proc", no_argument, &helper_options.proc, 1}, - {0, 0, 0, 0} - }; - - static const char *helper_short_options = ""; - - /* defaults: */ - helper_options.proc = false; - - /* merge caller's command line options descriptions with helper's: */ - if (odph_merge_getopt_options(caller_shortopts, helper_short_options, - caller_longopts, helper_long_options, - &shortopts, &longopts) < 0) - return -1; - - while (1) { - /* getopt_long stores the option index here. */ - int option_index = 0; - - c = getopt_long (argc, argv, - shortopts, longopts, &option_index); - - /* Detect the end of the options. */ - if (c == -1) - break; + argc--; + continue; + } - /* check for unknown options or missing arguments */ - if (c == '?' || c == ':') - res = -1; + i++; } - optind = 0; /* caller expects this to be zero if it parses too*/ - - free(shortopts); - free(longopts); - - return res; + return argc; } diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index f9e99afd6..b904877cd 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -201,6 +201,7 @@ __LIB__libodp_linux_la_SOURCES = \ odp_version.c \ odp_weak.c \ pktio/dpdk.c \ + pktio/dpdk_parse.c \ pktio/ethtool.c \ pktio/io_ops.c \ pktio/ipc.c \ diff --git a/platform/linux-generic/include/odp_classification_internal.h b/platform/linux-generic/include/odp_classification_internal.h index 47f80dc25..84d605e6b 100644 --- a/platform/linux-generic/include/odp_classification_internal.h +++ b/platform/linux-generic/include/odp_classification_internal.h @@ -39,7 +39,7 @@ selects destination queue and packet pool based on selected PMR and CoS. **/ int cls_classify_packet(pktio_entry_t *entry, const uint8_t *base, uint16_t pkt_len, uint32_t seg_len, odp_pool_t *pool, - odp_packet_hdr_t *pkt_hdr); + odp_packet_hdr_t *pkt_hdr, odp_bool_t parse); /** Packet IO classifier init diff --git a/platform/linux-generic/include/odp_packet_dpdk.h b/platform/linux-generic/include/odp_packet_dpdk.h index 7600b57e7..020c2b976 100644 --- a/platform/linux-generic/include/odp_packet_dpdk.h +++ b/platform/linux-generic/include/odp_packet_dpdk.h @@ -72,4 +72,24 @@ typedef struct ODP_ALIGNED_CACHE { dpdk_opt_t opt; } pkt_dpdk_t; +/** Packet parser using DPDK interface */ +int dpdk_packet_parse_common(packet_parser_t *pkt_hdr, + const uint8_t *ptr, + uint32_t pkt_len, + uint32_t seg_len, + struct rte_mbuf *mbuf, + int layer, + odp_pktin_config_opt_t pktin_cfg); + +static inline int dpdk_packet_parse_layer(odp_packet_hdr_t *pkt_hdr, + struct rte_mbuf *mbuf, + odp_pktio_parser_layer_t layer, + odp_pktin_config_opt_t pktin_cfg) +{ + uint32_t seg_len = pkt_hdr->buf_hdr.seg[0].len; + void *base = pkt_hdr->buf_hdr.seg[0].data; + + return dpdk_packet_parse_common(&pkt_hdr->p, base, pkt_hdr->frame_len, + seg_len, mbuf, layer, pktin_cfg); +} #endif diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index 14720924c..46fcf67ee 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -987,17 +987,19 @@ static uint32_t packet_rss_hash(odp_packet_hdr_t *pkt_hdr, */ int cls_classify_packet(pktio_entry_t *entry, const uint8_t *base, uint16_t pkt_len, uint32_t seg_len, odp_pool_t *pool, - odp_packet_hdr_t *pkt_hdr) + odp_packet_hdr_t *pkt_hdr, odp_bool_t parse) { cos_t *cos; uint32_t tbl_index; uint32_t hash; - packet_parse_reset(pkt_hdr); - packet_set_len(pkt_hdr, pkt_len); + if (parse) { + packet_parse_reset(pkt_hdr); + packet_set_len(pkt_hdr, pkt_len); - packet_parse_common(&pkt_hdr->p, base, pkt_len, seg_len, - ODP_PROTO_LAYER_ALL); + packet_parse_common(&pkt_hdr->p, base, pkt_len, seg_len, + ODP_PROTO_LAYER_ALL); + } cos = cls_select_cos(entry, base, pkt_hdr); if (cos == NULL) diff --git a/platform/linux-generic/pktio/dpdk.c b/platform/linux-generic/pktio/dpdk.c index 14d59d8e0..206a6a458 100644 --- a/platform/linux-generic/pktio/dpdk.c +++ b/platform/linux-generic/pktio/dpdk.c @@ -418,74 +418,6 @@ static struct rte_mempool_ops ops_stack = { MEMPOOL_REGISTER_OPS(ops_stack); -#define IP4_CSUM_RESULT(m) (m->ol_flags & PKT_RX_IP_CKSUM_MASK) -#define L4_CSUM_RESULT(m) (m->ol_flags & PKT_RX_L4_CKSUM_MASK) -#define HAS_L4_PROTO(m, proto) ((m->packet_type & RTE_PTYPE_L4_MASK) == proto) -#define UDP4_CSUM(_p) (((_odp_udphdr_t *)_odp_packet_l4_ptr(_p, NULL))->chksum) - -#define PKTIN_CSUM_BITS 0x1C - -static inline int pkt_set_ol_rx(odp_pktin_config_opt_t *pktin_cfg, - odp_packet_hdr_t *pkt_hdr, - struct rte_mbuf *mbuf) -{ - uint64_t packet_csum_result; - - if (pktin_cfg->bit.ipv4_chksum && - RTE_ETH_IS_IPV4_HDR(mbuf->packet_type)) { - packet_csum_result = IP4_CSUM_RESULT(mbuf); - - if (packet_csum_result == PKT_RX_IP_CKSUM_GOOD) { - pkt_hdr->p.input_flags.l3_chksum_done = 1; - } else if (packet_csum_result != PKT_RX_IP_CKSUM_UNKNOWN) { - if (pktin_cfg->bit.drop_ipv4_err) - return -1; - - pkt_hdr->p.input_flags.l3_chksum_done = 1; - pkt_hdr->p.flags.ip_err = 1; - pkt_hdr->p.flags.l3_chksum_err = 1; - } - } - - if (pktin_cfg->bit.udp_chksum && - HAS_L4_PROTO(mbuf, RTE_PTYPE_L4_UDP)) { - packet_csum_result = L4_CSUM_RESULT(mbuf); - - if (packet_csum_result == PKT_RX_L4_CKSUM_GOOD) { - pkt_hdr->p.input_flags.l4_chksum_done = 1; - } else if (packet_csum_result != PKT_RX_L4_CKSUM_UNKNOWN) { - if (pkt_hdr->p.input_flags.ipv4 && - pkt_hdr->p.input_flags.udp && - !UDP4_CSUM(packet_handle(pkt_hdr))) { - pkt_hdr->p.input_flags.l4_chksum_done = 1; - return 0; - } - if (pktin_cfg->bit.drop_udp_err) - return -1; - - pkt_hdr->p.input_flags.l4_chksum_done = 1; - pkt_hdr->p.flags.udp_err = 1; - pkt_hdr->p.flags.l4_chksum_err = 1; - } - } else if (pktin_cfg->bit.tcp_chksum && - HAS_L4_PROTO(mbuf, RTE_PTYPE_L4_TCP)) { - packet_csum_result = L4_CSUM_RESULT(mbuf); - - if (packet_csum_result == PKT_RX_L4_CKSUM_GOOD) { - pkt_hdr->p.input_flags.l4_chksum_done = 1; - } else if (packet_csum_result != PKT_RX_L4_CKSUM_UNKNOWN) { - if (pktin_cfg->bit.drop_tcp_err) - return -1; - - pkt_hdr->p.input_flags.l4_chksum_done = 1; - pkt_hdr->p.flags.tcp_err = 1; - pkt_hdr->p.flags.l4_chksum_err = 1; - } - } - - return 0; -} - static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry, odp_packet_t pkt_table[], struct rte_mbuf *mbuf_table[], @@ -500,7 +432,7 @@ static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry, int nb_pkts = 0; int alloc_len, num; odp_pool_t pool = pktio_entry->s.pkt_dpdk.pool; - odp_pktin_config_opt_t *pktin_cfg = &pktio_entry->s.config.pktin; + odp_pktin_config_opt_t pktin_cfg = pktio_entry->s.config.pktin; odp_proto_layer_t parse_layer = pktio_entry->s.config.parser.layer; odp_pktio_t input = pktio_entry->s.handle; @@ -530,10 +462,20 @@ static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry, pkt_len = rte_pktmbuf_pkt_len(mbuf); if (pktio_cls_enabled(pktio_entry)) { + packet_parse_reset(&parsed_hdr); + packet_set_len(&parsed_hdr, pkt_len); + if (dpdk_packet_parse_common(&parsed_hdr.p, data, + pkt_len, pkt_len, mbuf, + ODP_PROTO_LAYER_ALL, + pktin_cfg)) { + odp_packet_free(pkt_table[i]); + rte_pktmbuf_free(mbuf); + continue; + } if (cls_classify_packet(pktio_entry, (const uint8_t *)data, pkt_len, pkt_len, &pool, - &parsed_hdr)) + &parsed_hdr, false)) goto fail; } @@ -549,21 +491,18 @@ static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry, if (pktio_cls_enabled(pktio_entry)) copy_packet_cls_metadata(&parsed_hdr, pkt_hdr); else if (parse_layer != ODP_PROTO_LAYER_NONE) - packet_parse_layer(pkt_hdr, parse_layer); + if (dpdk_packet_parse_layer(pkt_hdr, mbuf, parse_layer, + pktin_cfg)) { + odp_packet_free(pkt); + rte_pktmbuf_free(mbuf); + continue; + } if (mbuf->ol_flags & PKT_RX_RSS_HASH) packet_set_flow_hash(pkt_hdr, mbuf->hash.rss); packet_set_ts(pkt_hdr, ts); - if (pktin_cfg->all_bits & PKTIN_CSUM_BITS) { - if (pkt_set_ol_rx(pktin_cfg, pkt_hdr, mbuf)) { - odp_packet_free(pkt); - rte_pktmbuf_free(mbuf); - continue; - } - } - pkt_table[nb_pkts++] = pkt; rte_pktmbuf_free(mbuf); @@ -752,7 +691,7 @@ static inline int mbuf_to_pkt_zero(pktio_entry_t *pktio_entry, int i; int nb_pkts = 0; odp_pool_t pool = pktio_entry->s.pkt_dpdk.pool; - odp_pktin_config_opt_t *pktin_cfg = &pktio_entry->s.config.pktin; + odp_pktin_config_opt_t pktin_cfg = pktio_entry->s.config.pktin; odp_proto_layer_t parse_layer = pktio_entry->s.config.parser.layer; odp_pktio_t input = pktio_entry->s.handle; @@ -775,13 +714,23 @@ static inline int mbuf_to_pkt_zero(pktio_entry_t *pktio_entry, pkt_hdr = packet_hdr(pkt); if (pktio_cls_enabled(pktio_entry)) { + packet_parse_reset(&parsed_hdr); + packet_set_len(&parsed_hdr, pkt_len); + if (dpdk_packet_parse_common(&parsed_hdr.p, data, + pkt_len, pkt_len, mbuf, + ODP_PROTO_LAYER_ALL, + pktin_cfg)) { + rte_pktmbuf_free(mbuf); + continue; + } if (cls_classify_packet(pktio_entry, (const uint8_t *)data, pkt_len, pkt_len, &pool, - &parsed_hdr)) + &parsed_hdr, false)) { ODP_ERR("Unable to classify packet\n"); rte_pktmbuf_free(mbuf); continue; + } } /* Init buffer segments. Currently, only single segment packets @@ -794,20 +743,17 @@ static inline int mbuf_to_pkt_zero(pktio_entry_t *pktio_entry, if (pktio_cls_enabled(pktio_entry)) copy_packet_cls_metadata(&parsed_hdr, pkt_hdr); else if (parse_layer != ODP_PROTO_LAYER_NONE) - packet_parse_layer(pkt_hdr, parse_layer); + if (dpdk_packet_parse_layer(pkt_hdr, mbuf, parse_layer, + pktin_cfg)) { + rte_pktmbuf_free(mbuf); + continue; + } if (mbuf->ol_flags & PKT_RX_RSS_HASH) packet_set_flow_hash(pkt_hdr, mbuf->hash.rss); packet_set_ts(pkt_hdr, ts); - if (pktin_cfg->all_bits & PKTIN_CSUM_BITS) { - if (pkt_set_ol_rx(pktin_cfg, pkt_hdr, mbuf)) { - rte_pktmbuf_free(mbuf); - continue; - } - } - pkt_table[nb_pkts++] = pkt; } diff --git a/platform/linux-generic/pktio/dpdk_parse.c b/platform/linux-generic/pktio/dpdk_parse.c new file mode 100644 index 000000000..155c68326 --- /dev/null +++ b/platform/linux-generic/pktio/dpdk_parse.c @@ -0,0 +1,492 @@ +/* Copyright (c) 2018, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "config.h" + +#ifdef ODP_PKTIO_DPDK + +#include <odp_packet_io_internal.h> +#include <odp_packet_dpdk.h> +#include <odp/api/byteorder.h> +#include <odp/api/plat/byteorder_inlines.h> + +#include <protocols/eth.h> +#include <protocols/udp.h> +#include <protocols/tcp.h> + +#include <rte_config.h> +#include <rte_mbuf.h> + +#define IP4_CSUM_RESULT(ol_flags) (ol_flags & PKT_RX_IP_CKSUM_MASK) +#define L4_CSUM_RESULT(ol_flags) (ol_flags & PKT_RX_L4_CKSUM_MASK) + +/** Parser helper function for Ethernet packets */ +static inline uint16_t dpdk_parse_eth(packet_parser_t *prs, + const uint8_t **parseptr, + uint32_t *offset, uint32_t frame_len, + uint32_t mbuf_packet_type) +{ + uint16_t ethtype; + const _odp_ethhdr_t *eth; + uint16_t macaddr0, macaddr2, macaddr4; + const _odp_vlanhdr_t *vlan; + _odp_packet_input_flags_t input_flags; + uint32_t l2_packet_type; + + input_flags.all = 0; + input_flags.l2 = 1; + input_flags.eth = 1; + + eth = (const _odp_ethhdr_t *)*parseptr; + + /* Detect jumbo frames */ + if (odp_unlikely(frame_len > _ODP_ETH_LEN_MAX)) + input_flags.jumbo = 1; + + /* Handle Ethernet broadcast/multicast addresses */ + macaddr0 = _odp_be_to_cpu_16(*((const uint16_t *)(const void *)eth)); + if (odp_unlikely((macaddr0 & 0x0100) == 0x0100)) + input_flags.eth_mcast = 1; + + if (odp_unlikely(macaddr0 == 0xffff)) { + macaddr2 = + _odp_be_to_cpu_16(*((const uint16_t *) + (const void *)eth + 1)); + macaddr4 = + _odp_be_to_cpu_16(*((const uint16_t *) + (const void *)eth + 2)); + + if ((macaddr2 == 0xffff) && (macaddr4 == 0xffff)) + input_flags.eth_bcast = 1; + } + + /* Get Ethertype */ + l2_packet_type = mbuf_packet_type & RTE_PTYPE_L2_MASK; + switch (l2_packet_type) { + case RTE_PTYPE_L2_ETHER: + if (RTE_ETH_IS_IPV4_HDR(mbuf_packet_type)) + ethtype = _ODP_ETHTYPE_IPV4; + else if (RTE_ETH_IS_IPV6_HDR(mbuf_packet_type)) + ethtype = _ODP_ETHTYPE_IPV6; + else + ethtype = _odp_be_to_cpu_16(eth->type); + break; + case RTE_PTYPE_L2_ETHER_VLAN: + ethtype = _ODP_ETHTYPE_VLAN; + break; + default: + ethtype = _odp_be_to_cpu_16(eth->type); + } + + *offset += sizeof(*eth); + *parseptr += sizeof(*eth); + + /* Check for SNAP vs. DIX */ + if (odp_unlikely(ethtype < _ODP_ETH_LEN_MAX)) { + input_flags.snap = 1; + if (ethtype > frame_len - *offset) { + prs->flags.snap_len_err = 1; + ethtype = 0; + goto error; + } + ethtype = _odp_be_to_cpu_16(*((const uint16_t *)(uintptr_t) + (parseptr + 6))); + *offset += 8; + *parseptr += 8; + } + + /* Parse the VLAN header(s), if present */ + if (odp_unlikely(ethtype == _ODP_ETHTYPE_VLAN_OUTER)) { + input_flags.vlan_qinq = 1; + input_flags.vlan = 1; + + vlan = (const _odp_vlanhdr_t *)*parseptr; + ethtype = _odp_be_to_cpu_16(vlan->type); + *offset += sizeof(_odp_vlanhdr_t); + *parseptr += sizeof(_odp_vlanhdr_t); + } + + if (ethtype == _ODP_ETHTYPE_VLAN) { + input_flags.vlan = 1; + vlan = (const _odp_vlanhdr_t *)*parseptr; + ethtype = _odp_be_to_cpu_16(vlan->type); + *offset += sizeof(_odp_vlanhdr_t); + *parseptr += sizeof(_odp_vlanhdr_t); + } + +error: + prs->input_flags.all |= input_flags.all; + + return ethtype; +} + +/** + * Parser helper function for IPv4 + */ +static inline uint8_t dpdk_parse_ipv4(packet_parser_t *prs, + const uint8_t **parseptr, + uint32_t *offset, uint32_t frame_len, + uint32_t mbuf_packet_type, + uint64_t mbuf_ol, + uint32_t do_csum) +{ + const _odp_ipv4hdr_t *ipv4 = (const _odp_ipv4hdr_t *)*parseptr; + uint32_t dstaddr = _odp_be_to_cpu_32(ipv4->dst_addr); + uint32_t l3_len = _odp_be_to_cpu_16(ipv4->tot_len); + uint8_t ver = _ODP_IPV4HDR_VER(ipv4->ver_ihl); + uint8_t ihl = _ODP_IPV4HDR_IHL(ipv4->ver_ihl); + uint32_t l4_packet_type = mbuf_packet_type & RTE_PTYPE_L4_MASK; + uint16_t frag_offset; + uint8_t proto; + + if (odp_unlikely(ihl < _ODP_IPV4HDR_IHL_MIN || + ver != 4 || + (l3_len > frame_len - *offset))) { + prs->flags.ip_err = 1; + return 0; + } + + *offset += ihl * 4; + *parseptr += ihl * 4; + + if (do_csum) { + uint64_t packet_csum_result = IP4_CSUM_RESULT(mbuf_ol); + + if (packet_csum_result == PKT_RX_IP_CKSUM_GOOD) { + prs->input_flags.l3_chksum_done = 1; + } else if (packet_csum_result != PKT_RX_IP_CKSUM_UNKNOWN) { + prs->input_flags.l3_chksum_done = 1; + prs->flags.ip_err = 1; + prs->flags.l3_chksum_err = 1; + } + } + + if (odp_unlikely(ihl > _ODP_IPV4HDR_IHL_MIN)) + prs->input_flags.ipopt = 1; + + if (l4_packet_type == RTE_PTYPE_L4_UDP) { + proto = _ODP_IPPROTO_UDP; + } else if (l4_packet_type == RTE_PTYPE_L4_TCP) { + proto = _ODP_IPPROTO_TCP; + } else { + proto = ipv4->proto; + frag_offset = _odp_be_to_cpu_16(ipv4->frag_offset); + + /* A packet is a fragment if: + * "more fragments" flag is set (all fragments except the last) + * OR + * "fragment offset" field is nonzero (all fragments except + * the first) + */ + if (odp_unlikely(l4_packet_type == RTE_PTYPE_L4_FRAG || + _ODP_IPV4HDR_IS_FRAGMENT(frag_offset))) + prs->input_flags.ipfrag = 1; + } + + /**/ + /* Handle IPv4 broadcast / multicast */ + if (odp_unlikely(dstaddr == 0xffffffff)) + prs->input_flags.ip_bcast = 1; + + if (odp_unlikely((dstaddr >> 28) == 0xe)) + prs->input_flags.ip_mcast = 1; + + return proto; +} + +static inline uint8_t dpdk_parse_ipv6(packet_parser_t *prs, + const uint8_t **parseptr, + uint32_t *offset, uint32_t frame_len, + uint32_t seg_len, + uint32_t mbuf_packet_type) +{ + const _odp_ipv6hdr_t *ipv6 = (const _odp_ipv6hdr_t *)*parseptr; + const _odp_ipv6hdr_ext_t *ipv6ext; + uint32_t dstaddr0 = _odp_be_to_cpu_32(ipv6->dst_addr.u8[0]); + uint32_t l3_len = _odp_be_to_cpu_16(ipv6->payload_len) + + _ODP_IPV6HDR_LEN; + uint32_t l4_packet_type = mbuf_packet_type & RTE_PTYPE_L4_MASK; + + /* Basic sanity checks on IPv6 header */ + if ((_odp_be_to_cpu_32(ipv6->ver_tc_flow) >> 28) != 6 || + l3_len > frame_len - *offset) { + prs->flags.ip_err = 1; + return 0; + } + + /* IPv6 broadcast / multicast flags */ + prs->input_flags.ip_mcast = (dstaddr0 & 0xff000000) == 0xff000000; + prs->input_flags.ip_bcast = 0; + + /* Skip past IPv6 header */ + *offset += sizeof(_odp_ipv6hdr_t); + *parseptr += sizeof(_odp_ipv6hdr_t); + + if (l4_packet_type == RTE_PTYPE_L4_UDP) + return _ODP_IPPROTO_UDP; + else if (l4_packet_type == RTE_PTYPE_L4_TCP) + return _ODP_IPPROTO_TCP; + + /* Skip past any IPv6 extension headers */ + if (ipv6->next_hdr == _ODP_IPPROTO_HOPOPTS || + ipv6->next_hdr == _ODP_IPPROTO_ROUTE) { + prs->input_flags.ipopt = 1; + + do { + ipv6ext = (const _odp_ipv6hdr_ext_t *)*parseptr; + uint16_t extlen = 8 + ipv6ext->ext_len * 8; + + *offset += extlen; + *parseptr += extlen; + } while ((ipv6ext->next_hdr == _ODP_IPPROTO_HOPOPTS || + ipv6ext->next_hdr == _ODP_IPPROTO_ROUTE) && + *offset < seg_len); + + if (*offset >= prs->l3_offset + + _odp_be_to_cpu_16(ipv6->payload_len)) { + prs->flags.ip_err = 1; + return 0; + } + + if (ipv6ext->next_hdr == _ODP_IPPROTO_FRAG) + prs->input_flags.ipfrag = 1; + + return ipv6ext->next_hdr; + } + + if (odp_unlikely(ipv6->next_hdr == _ODP_IPPROTO_FRAG)) { + prs->input_flags.ipopt = 1; + prs->input_flags.ipfrag = 1; + } + + return ipv6->next_hdr; +} + +/** + * Parser helper function for TCP + */ +static inline void dpdk_parse_tcp(packet_parser_t *prs, + const uint8_t **parseptr, + uint64_t mbuf_ol, + uint32_t do_csum) +{ + const _odp_tcphdr_t *tcp = (const _odp_tcphdr_t *)*parseptr; + uint32_t len = tcp->hl * 4; + + if (odp_unlikely(tcp->hl < sizeof(_odp_tcphdr_t) / sizeof(uint32_t))) + prs->flags.tcp_err = 1; + + if (do_csum) { + uint64_t packet_csum_result = L4_CSUM_RESULT(mbuf_ol); + + if (packet_csum_result == PKT_RX_L4_CKSUM_GOOD) { + prs->input_flags.l4_chksum_done = 1; + } else if (packet_csum_result != PKT_RX_L4_CKSUM_UNKNOWN) { + prs->input_flags.l4_chksum_done = 1; + prs->flags.tcp_err = 1; + prs->flags.l4_chksum_err = 1; + } + } + + *parseptr += len; +} + +/** + * Parser helper function for UDP + */ +static inline void dpdk_parse_udp(packet_parser_t *prs, + const uint8_t **parseptr, + uint64_t mbuf_ol, + uint32_t do_csum) +{ + const _odp_udphdr_t *udp = (const _odp_udphdr_t *)*parseptr; + uint32_t udplen = _odp_be_to_cpu_16(udp->length); + uint16_t ipsec_port = _odp_cpu_to_be_16(_ODP_UDP_IPSEC_PORT); + + if (odp_unlikely(udplen < sizeof(_odp_udphdr_t))) + prs->flags.udp_err = 1; + + if (do_csum) { + uint64_t packet_csum_result = L4_CSUM_RESULT(mbuf_ol); + + if (packet_csum_result == PKT_RX_L4_CKSUM_GOOD) { + prs->input_flags.l4_chksum_done = 1; + } else if (packet_csum_result != PKT_RX_L4_CKSUM_UNKNOWN) { + if (prs->input_flags.ipv4 && !udp->chksum) { + prs->input_flags.l4_chksum_done = 1; + } else { + prs->input_flags.l4_chksum_done = 1; + prs->flags.udp_err = 1; + prs->flags.l4_chksum_err = 1; + } + } + } + + if (odp_unlikely(ipsec_port == udp->dst_port && udplen > 4)) { + uint32_t val; + + memcpy(&val, udp + 1, 4); + if (val != 0) { + prs->input_flags.ipsec = 1; + prs->input_flags.ipsec_udp = 1; + } + } + + *parseptr += sizeof(_odp_udphdr_t); +} + +static inline +int dpdk_packet_parse_common_l3_l4(packet_parser_t *prs, + const uint8_t *parseptr, + uint32_t offset, + uint32_t frame_len, uint32_t seg_len, + int layer, uint16_t ethtype, + uint32_t mbuf_packet_type, + uint64_t mbuf_ol, + odp_pktin_config_opt_t pktin_cfg) +{ + uint8_t ip_proto; + + prs->l3_offset = offset; + + if (odp_unlikely(layer <= ODP_PROTO_LAYER_L2)) + return 0; + + /* Set l3 flag only for known ethtypes */ + prs->input_flags.l3 = 1; + + /* Parse Layer 3 headers */ + switch (ethtype) { + case _ODP_ETHTYPE_IPV4: + prs->input_flags.ipv4 = 1; + ip_proto = dpdk_parse_ipv4(prs, &parseptr, &offset, frame_len, + mbuf_packet_type, mbuf_ol, + pktin_cfg.bit.ipv4_chksum); + prs->l4_offset = offset; + if (prs->flags.ip_err && pktin_cfg.bit.drop_ipv4_err) + return -1; /* drop */ + break; + + case _ODP_ETHTYPE_IPV6: + prs->input_flags.ipv6 = 1; + ip_proto = dpdk_parse_ipv6(prs, &parseptr, &offset, frame_len, + seg_len, mbuf_packet_type); + prs->l4_offset = offset; + if (prs->flags.ip_err && pktin_cfg.bit.drop_ipv6_err) + return -1; /* drop */ + break; + + case _ODP_ETHTYPE_ARP: + prs->input_flags.arp = 1; + ip_proto = 255; /* Reserved invalid by IANA */ + break; + + default: + prs->input_flags.l3 = 0; + ip_proto = 255; /* Reserved invalid by IANA */ + } + + if (layer == ODP_PROTO_LAYER_L3) + return 0; + + /* Set l4 flag only for known ip_proto */ + prs->input_flags.l4 = 1; + + /* Parse Layer 4 headers */ + switch (ip_proto) { + case _ODP_IPPROTO_ICMPV4: + /* Fall through */ + + case _ODP_IPPROTO_ICMPV6: + prs->input_flags.icmp = 1; + break; + + case _ODP_IPPROTO_IPIP: + /* Do nothing */ + break; + + case _ODP_IPPROTO_TCP: + if (odp_unlikely(offset + _ODP_TCPHDR_LEN > seg_len)) + return -1; /* drop */ + prs->input_flags.tcp = 1; + dpdk_parse_tcp(prs, &parseptr, mbuf_ol, + pktin_cfg.bit.tcp_chksum); + if (prs->flags.tcp_err && pktin_cfg.bit.drop_tcp_err) + return -1; /* drop */ + break; + + case _ODP_IPPROTO_UDP: + if (odp_unlikely(offset + _ODP_UDPHDR_LEN > seg_len)) + return -1; /* drop */ + prs->input_flags.udp = 1; + dpdk_parse_udp(prs, &parseptr, mbuf_ol, + pktin_cfg.bit.udp_chksum); + if (prs->flags.udp_err && pktin_cfg.bit.drop_udp_err) + return -1; /* drop */ + break; + + case _ODP_IPPROTO_AH: + prs->input_flags.ipsec = 1; + prs->input_flags.ipsec_ah = 1; + break; + + case _ODP_IPPROTO_ESP: + prs->input_flags.ipsec = 1; + prs->input_flags.ipsec_esp = 1; + break; + + case _ODP_IPPROTO_SCTP: + prs->input_flags.sctp = 1; + break; + + case _ODP_IPPROTO_NO_NEXT: + prs->input_flags.no_next_hdr = 1; + break; + + default: + prs->input_flags.l4 = 0; + break; + } + + return 0; +} + +/** + * DPDK packet parser + */ +int dpdk_packet_parse_common(packet_parser_t *prs, const uint8_t *ptr, + uint32_t frame_len, uint32_t seg_len, + struct rte_mbuf *mbuf, int layer, + odp_pktin_config_opt_t pktin_cfg) +{ + uint32_t offset; + uint16_t ethtype; + const uint8_t *parseptr; + uint32_t mbuf_packet_type; + uint64_t mbuf_ol; + + parseptr = ptr; + offset = 0; + + if (odp_unlikely(layer == ODP_PROTO_LAYER_NONE)) + return 0; + + mbuf_packet_type = mbuf->packet_type; + mbuf_ol = mbuf->ol_flags; + + /* Assume valid L2 header, no CRC/FCS check in SW */ + prs->l2_offset = offset; + + ethtype = dpdk_parse_eth(prs, &parseptr, &offset, frame_len, + mbuf_packet_type); + + return dpdk_packet_parse_common_l3_l4(prs, parseptr, offset, frame_len, + seg_len, layer, ethtype, + mbuf_packet_type, mbuf_ol, + pktin_cfg); +} + +#endif /* ODP_PKTIO_DPDK */ diff --git a/platform/linux-generic/pktio/loop.c b/platform/linux-generic/pktio/loop.c index fc80e8019..779e4c62b 100644 --- a/platform/linux-generic/pktio/loop.c +++ b/platform/linux-generic/pktio/loop.c @@ -131,7 +131,7 @@ static int loopback_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED, ret = cls_classify_packet(pktio_entry, pkt_addr, pkt_len, seg_len, - &new_pool, pkt_hdr); + &new_pool, pkt_hdr, true); if (ret) { failed++; odp_packet_free(pkt); diff --git a/platform/linux-generic/pktio/netmap.c b/platform/linux-generic/pktio/netmap.c index 835d81ebb..567bc9f95 100644 --- a/platform/linux-generic/pktio/netmap.c +++ b/platform/linux-generic/pktio/netmap.c @@ -705,7 +705,7 @@ static inline int netmap_pkt_to_odp(pktio_entry_t *pktio_entry, if (pktio_cls_enabled(pktio_entry)) { if (cls_classify_packet(pktio_entry, (const uint8_t *)slot.buf, len, - len, &pool, &parsed_hdr)) + len, &pool, &parsed_hdr, true)) goto fail; } diff --git a/platform/linux-generic/pktio/socket.c b/platform/linux-generic/pktio/socket.c index f6f3288c2..8b7200e6f 100644 --- a/platform/linux-generic/pktio/socket.c +++ b/platform/linux-generic/pktio/socket.c @@ -655,7 +655,8 @@ static int sock_mmsg_recv(pktio_entry_t *pktio_entry, int index ODP_UNUSED, seg_len = msgvec[i].msg_hdr.msg_iov->iov_len; if (cls_classify_packet(pktio_entry, base, pkt_len, - seg_len, &pool, pkt_hdr)) { + seg_len, &pool, pkt_hdr, + true)) { ODP_ERR("cls_classify_packet failed"); odp_packet_free(pkt); continue; diff --git a/platform/linux-generic/pktio/socket_mmap.c b/platform/linux-generic/pktio/socket_mmap.c index deaa6da15..847eb71ad 100644 --- a/platform/linux-generic/pktio/socket_mmap.c +++ b/platform/linux-generic/pktio/socket_mmap.c @@ -228,7 +228,8 @@ static inline unsigned pkt_mmap_v2_rx(pktio_entry_t *pktio_entry, if (pktio_cls_enabled(pktio_entry)) { if (cls_classify_packet(pktio_entry, pkt_buf, pkt_len, - pkt_len, &pool, &parsed_hdr)) { + pkt_len, &pool, &parsed_hdr, + true)) { mmap_rx_user_ready(ppd.raw); /* drop */ frame_num = next_frame_num; continue; diff --git a/platform/linux-generic/pktio/tap.c b/platform/linux-generic/pktio/tap.c index 56f90b31b..af766e0de 100644 --- a/platform/linux-generic/pktio/tap.c +++ b/platform/linux-generic/pktio/tap.c @@ -264,7 +264,7 @@ static odp_packet_t pack_odp_pkt(pktio_entry_t *pktio_entry, const void *data, if (pktio_cls_enabled(pktio_entry)) { if (cls_classify_packet(pktio_entry, data, len, len, &pktio_entry->s.pkt_tap.pool, - &parsed_hdr)) { + &parsed_hdr, true)) { return ODP_PACKET_INVALID; } } diff --git a/platform/linux-generic/test/mmap_vlan_ins/mmap_vlan_ins.c b/platform/linux-generic/test/mmap_vlan_ins/mmap_vlan_ins.c index 678978bee..cf3d6d932 100644 --- a/platform/linux-generic/test/mmap_vlan_ins/mmap_vlan_ins.c +++ b/platform/linux-generic/test/mmap_vlan_ins/mmap_vlan_ins.c @@ -137,36 +137,14 @@ int main(int argc, char **argv) odph_odpthread_t thd[MAX_WORKERS]; odp_instance_t instance; odph_odpthread_params_t thr_params; - int opt; - int long_index; - - static const struct option longopts[] = { {NULL, 0, NULL, 0} }; - static const char *shortopts = ""; /* let helper collect its own arguments (e.g. --odph_proc) */ - odph_parse_options(argc, argv, shortopts, longopts); + argc = odph_parse_options(argc, argv); - /* - * parse own options: currentely none, but this will move optind - * to the first non-option argument. (in case there where helprt args) - */ - opterr = 0; /* do not issue errors on helper options */ - while (1) { - opt = getopt_long(argc, argv, shortopts, longopts, &long_index); - if (-1 == opt) - break; /* No more options */ - } - - if (argc != optind + 4 || - odph_eth_addr_parse(&global.dst, argv[optind + 2]) != 0 || - odph_eth_addr_parse(&global.src, argv[optind + 3]) != 0) { - printf("Usage: odp_l2fwd_simple eth0 eth1 01:02:03:04:05:06" - " 07:08:09:0a:0b:0c\n"); - printf("Where eth0 and eth1 are the used interfaces" - " (must have 2 of them)\n"); - printf("And the hexadecimal numbers are destination MAC address" - " and source MAC address\n"); - exit(1); + if (argc < 3) { + printf("Too few arguments (%i).\n" + "Two interface names needed as arguments.\n", argc); + exit(0); } if (odp_init_global(&instance, NULL, NULL)) { @@ -193,10 +171,8 @@ int main(int argc, char **argv) exit(1); } - global.if0 = create_pktio(argv[optind], pool, &global.if0in, - &global.if0out); - global.if1 = create_pktio(argv[optind + 1], pool, &global.if1in, - &global.if1out); + global.if0 = create_pktio(argv[1], pool, &global.if0in, &global.if0out); + global.if1 = create_pktio(argv[2], pool, &global.if1in, &global.if1out); odp_cpumask_default_worker(&cpumask, MAX_WORKERS); diff --git a/test/common/odp_cunit_common.c b/test/common/odp_cunit_common.c index 79c3df1ef..f7c9af43b 100644 --- a/test/common/odp_cunit_common.c +++ b/test/common/odp_cunit_common.c @@ -394,5 +394,6 @@ int odp_cunit_register(odp_suiteinfo_t testsuites[]) int odp_cunit_parse_options(int argc, char *argv[]) { progname = argv[0]; - return odph_parse_options(argc, argv, NULL, NULL); + odph_parse_options(argc, argv); + return 0; } diff --git a/test/performance/odp_bench_packet.c b/test/performance/odp_bench_packet.c index df41b41f4..b4f1905a9 100644 --- a/test/performance/odp_bench_packet.c +++ b/test/performance/odp_bench_packet.c @@ -1318,9 +1318,7 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) static const char *shortopts = "b:i:h"; /* Let helper collect its own arguments (e.g. --odph_proc) */ - odph_parse_options(argc, argv, shortopts, longopts); - - opterr = 0; /* Do not issue errors on helper options */ + argc = odph_parse_options(argc, argv); appl_args->bench_idx = 0; /* Run all benchmarks */ appl_args->burst_size = TEST_DEF_BURST; diff --git a/test/performance/odp_crypto.c b/test/performance/odp_crypto.c index 0404aca25..61da80e8a 100644 --- a/test/performance/odp_crypto.c +++ b/test/performance/odp_crypto.c @@ -1197,7 +1197,7 @@ static void parse_args(int argc, char *argv[], crypto_args_t *cargs) static const char *shortopts = "+a:c:df:hi:m:nl:spr"; /* let helper collect its own arguments (e.g. --odph_proc) */ - odph_parse_options(argc, argv, shortopts, longopts); + argc = odph_parse_options(argc, argv); cargs->in_place = 0; cargs->in_flight = 1; @@ -1208,8 +1208,6 @@ static void parse_args(int argc, char *argv[], crypto_args_t *cargs) cargs->reuse_packet = 0; cargs->schedule = 0; - opterr = 0; /* do not issue errors on helper options */ - while (1) { opt = getopt_long(argc, argv, shortopts, longopts, &long_index); diff --git a/test/performance/odp_ipsec.c b/test/performance/odp_ipsec.c index 587293dbe..551c021af 100644 --- a/test/performance/odp_ipsec.c +++ b/test/performance/odp_ipsec.c @@ -929,7 +929,7 @@ static void parse_args(int argc, char *argv[], ipsec_args_t *cargs) static const char *shortopts = "+a:c:df:hi:m:nl:sptu"; /* let helper collect its own arguments (e.g. --odph_proc) */ - odph_parse_options(argc, argv, shortopts, longopts); + argc = odph_parse_options(argc, argv); cargs->in_place = 0; cargs->in_flight = 1; @@ -940,8 +940,6 @@ static void parse_args(int argc, char *argv[], ipsec_args_t *cargs) cargs->schedule = 0; cargs->ah = 0; - opterr = 0; /* do not issue errors on helper options */ - while (1) { opt = getopt_long(argc, argv, shortopts, longopts, &long_index); diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c index 2859000d5..ff14ab2f8 100644 --- a/test/performance/odp_l2fwd.c +++ b/test/performance/odp_l2fwd.c @@ -1184,7 +1184,7 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) static const char *shortopts = "+c:+t:+a:i:m:o:r:d:s:e:k:g:vh"; /* let helper collect its own arguments (e.g. --odph_proc) */ - odph_parse_options(argc, argv, shortopts, longopts); + argc = odph_parse_options(argc, argv); appl_args->time = 0; /* loop forever if time to run is 0 */ appl_args->accuracy = 1; /* get and print pps stats second */ @@ -1195,8 +1195,6 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) appl_args->verbose = 0; appl_args->chksum = 0; /* don't use checksum offload by default */ - opterr = 0; /* do not issue errors on helper options */ - while (1) { opt = getopt_long(argc, argv, shortopts, longopts, &long_index); diff --git a/test/performance/odp_pktio_ordered.c b/test/performance/odp_pktio_ordered.c index 5647b1eb5..ec6c4faa3 100644 --- a/test/performance/odp_pktio_ordered.c +++ b/test/performance/odp_pktio_ordered.c @@ -868,7 +868,7 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) static const char *shortopts = "+c:+t:+a:i:m:d:r:f:e:h"; /* let helper collect its own arguments (e.g. --odph_proc) */ - odph_parse_options(argc, argv, shortopts, longopts); + argc = odph_parse_options(argc, argv); appl_args->time = 0; /* loop forever if time to run is 0 */ appl_args->accuracy = DEF_STATS_INT; @@ -876,8 +876,6 @@ static void parse_args(int argc, char *argv[], appl_args_t *appl_args) appl_args->num_flows = DEF_NUM_FLOWS; appl_args->extra_rounds = DEF_EXTRA_ROUNDS; - opterr = 0; /* do not issue errors on helper options */ - while (1) { opt = getopt_long(argc, argv, shortopts, longopts, &long_index); diff --git a/test/performance/odp_pktio_perf.c b/test/performance/odp_pktio_perf.c index 75f4abf24..2791856aa 100644 --- a/test/performance/odp_pktio_perf.c +++ b/test/performance/odp_pktio_perf.c @@ -961,7 +961,7 @@ static void parse_args(int argc, char *argv[], test_args_t *args) static const char *shortopts = "+c:t:b:pR:l:r:i:d:vh"; /* let helper collect its own arguments (e.g. --odph_proc) */ - odph_parse_options(argc, argv, shortopts, longopts); + argc = odph_parse_options(argc, argv); args->cpu_count = 0; /* all CPUs */ args->num_tx_workers = 0; /* defaults to cpu_count+1/2 */ @@ -973,8 +973,6 @@ static void parse_args(int argc, char *argv[], test_args_t *args) args->schedule = 1; args->verbose = 0; - opterr = 0; /* do not issue errors on helper options */ - while (1) { opt = getopt_long(argc, argv, shortopts, longopts, &long_index); diff --git a/test/performance/odp_sched_latency.c b/test/performance/odp_sched_latency.c index ca7201193..7e98db184 100644 --- a/test/performance/odp_sched_latency.c +++ b/test/performance/odp_sched_latency.c @@ -550,7 +550,7 @@ static void parse_args(int argc, char *argv[], test_args_t *args) static const char *shortopts = "+c:s:l:t:m:n:o:p:rh"; /* Let helper collect its own arguments (e.g. --odph_proc) */ - odph_parse_options(argc, argv, shortopts, longopts); + argc = odph_parse_options(argc, argv); args->sync_type = ODP_SCHED_SYNC_PARALLEL; args->sample_per_prio = SAMPLE_EVENT_PER_PRIO; @@ -561,7 +561,6 @@ static void parse_args(int argc, char *argv[], test_args_t *args) args->prio[LO_PRIO].events_per_queue = EVENTS_PER_LO_PRIO_QUEUE; args->prio[HI_PRIO].events_per_queue = EVENTS_PER_HI_PRIO_QUEUE; - opterr = 0; /* Do not issue errors on helper options */ while (1) { opt = getopt_long(argc, argv, shortopts, longopts, &long_index); diff --git a/test/performance/odp_sched_pktio.c b/test/performance/odp_sched_pktio.c index 46a08c925..109ae87e2 100644 --- a/test/performance/odp_sched_pktio.c +++ b/test/performance/odp_sched_pktio.c @@ -364,7 +364,7 @@ static int parse_options(int argc, char *argv[], test_options_t *test_options) test_options->num_pktio_queue = 0; /* let helper collect its own arguments (e.g. --odph_proc) */ - odph_parse_options(argc, argv, shortopts, longopts); + argc = odph_parse_options(argc, argv); while (1) { opt = getopt_long(argc, argv, shortopts, longopts, &long_index); diff --git a/test/performance/odp_scheduling.c b/test/performance/odp_scheduling.c index 6b7cff77c..8dd86c3c3 100644 --- a/test/performance/odp_scheduling.c +++ b/test/performance/odp_scheduling.c @@ -761,9 +761,8 @@ static void parse_args(int argc, char *argv[], test_args_t *args) static const char *shortopts = "+c:fh"; /* let helper collect its own arguments (e.g. --odph_proc) */ - odph_parse_options(argc, argv, shortopts, longopts); + argc = odph_parse_options(argc, argv); - opterr = 0; /* do not issue errors on helper options */ while (1) { opt = getopt_long(argc, argv, shortopts, longopts, &long_index); |