X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=examples%2Fip_pipeline%2Fconfig_parse.c;h=e90499e781fcf9fb89925535e0f454be3f50c6a8;hb=2a5aa6e7a528b16db7da507c975ce3d169d232d4;hp=291dbfb3239c3cf5951eae9112c473fbee91e0ca;hpb=0e1e7d53ae8a0341ab6483bc6515854680c6835e;p=dpdk.git diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c index 291dbfb323..e90499e781 100644 --- a/examples/ip_pipeline/config_parse.c +++ b/examples/ip_pipeline/config_parse.c @@ -1,35 +1,7 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2016 Intel Corporation */ + #include #include #include @@ -80,6 +52,11 @@ static const struct app_link_params link_params_default = { .tcp_local_q = 0, .udp_local_q = 0, .sctp_local_q = 0, + .rss_qs = {0}, + .n_rss_qs = 0, + .rss_proto_ipv4 = ETH_RSS_IPV4, + .rss_proto_ipv6 = ETH_RSS_IPV6, + .rss_proto_l2 = 0, .state = 0, .ip = 0, .depth = 0, @@ -87,23 +64,23 @@ static const struct app_link_params link_params_default = { .pci_bdf = {0}, .conf = { - .link_speed = 0, - .link_duplex = 0, + .link_speeds = 0, .rxmode = { .mq_mode = ETH_MQ_RX_NONE, - .header_split = 0, /* Header split */ - .hw_ip_checksum = 0, /* IP checksum offload */ - .hw_vlan_filter = 0, /* VLAN filtering */ - .hw_vlan_strip = 0, /* VLAN strip */ - .hw_vlan_extend = 0, /* Extended VLAN */ - .jumbo_frame = 0, /* Jumbo frame support */ - .hw_strip_crc = 0, /* CRC strip by HW */ - .enable_scatter = 0, /* Scattered packets RX handler */ + .ignore_offload_bitfield = 1, + .offloads = DEV_RX_OFFLOAD_CRC_STRIP, .max_rx_pkt_len = 9000, /* Jumbo frame max packet len */ .split_hdr_size = 0, /* Header split buffer size */ }, + .rx_adv_conf = { + .rss_conf = { + .rss_key = NULL, + .rss_key_len = 40, + .rss_hf = 0, + }, + }, .txmode = { .mq_mode = ETH_MQ_TX_NONE, }, @@ -146,8 +123,7 @@ static const struct app_pktq_hwq_out_params default_hwq_out_params = { }, .tx_rs_thresh = 0, .tx_free_thresh = 0, - .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS | - ETH_TXQ_FLAGS_NOOFFLOADS, + .txq_flags = ETH_TXQ_FLAGS_IGNORE, .tx_deferred_start = 0, } }; @@ -173,20 +149,45 @@ static const struct app_pktq_swq_params default_swq_params = { struct app_pktq_tm_params default_tm_params = { .parsed = 0, .file_name = "./config/tm_profile.cfg", - .burst_read = 64, + .burst_read = 24, + .burst_write = 32, +}; + +struct app_pktq_tap_params default_tap_params = { + .parsed = 0, + .burst_read = 32, + .burst_write = 32, + .dropless = 0, + .n_retries = 0, + .mempool_id = 0, +}; + +struct app_pktq_kni_params default_kni_params = { + .parsed = 0, + .socket_id = 0, + .core_id = 0, + .hyper_th_id = 0, + .force_bind = 0, + + .mempool_id = 0, + .burst_read = 32, .burst_write = 32, + .dropless = 0, + .n_retries = 0, }; struct app_pktq_source_params default_source_params = { .parsed = 0, .mempool_id = 0, .burst = 32, - .file_name = NULL, + .file_name = "./config/packets.pcap", .n_bytes_per_pkt = 0, }; struct app_pktq_sink_params default_sink_params = { .parsed = 0, + .file_name = NULL, + .n_pkts_to_dump = 0, }; struct app_msgq_params default_msgq_params = { @@ -228,306 +229,136 @@ app_print_usage(char *prgname) rte_exit(0, app_usage, prgname, app_params_default.config_file); } -#define skip_white_spaces(pos) \ -({ \ - __typeof__(pos) _p = (pos); \ - for ( ; isspace(*_p); _p++); \ - _p; \ +#define APP_PARAM_ADD(set, key) \ +({ \ + ssize_t pos = APP_PARAM_FIND(set, key); \ + ssize_t size = RTE_DIM(set); \ + \ + if (pos < 0) { \ + for (pos = 0; pos < size; pos++) { \ + if (!APP_PARAM_VALID(&((set)[pos]))) \ + break; \ + } \ + \ + APP_CHECK((pos < size), \ + "Parse error: size of %s is limited to %u elements",\ + #set, (uint32_t) size); \ + \ + (set)[pos].name = strdup(key); \ + APP_CHECK(((set)[pos].name), \ + "Parse error: no free memory"); \ + } \ + pos; \ }) -#define PARSER_PARAM_ADD_CHECK(result, params_array, section_name) \ -do { \ - APP_CHECK((result != -EINVAL), \ - "Parse error: no free memory"); \ - APP_CHECK((result != -ENOMEM), \ - "Parse error: too many \"%s\" sections", section_name); \ - APP_CHECK(((result >= 0) && (params_array)[result].parsed == 0),\ - "Parse error: duplicate \"%s\" section", section_name); \ - APP_CHECK((result >= 0), \ - "Parse error in section \"%s\"", section_name); \ -} while (0) - -int -parser_read_arg_bool(const char *p) -{ - p = skip_white_spaces(p); - int result = -EINVAL; - - if (((p[0] == 'y') && (p[1] == 'e') && (p[2] == 's')) || - ((p[0] == 'Y') && (p[1] == 'E') && (p[2] == 'S'))) { - p += 3; - result = 1; - } - - if (((p[0] == 'o') && (p[1] == 'n')) || - ((p[0] == 'O') && (p[1] == 'N'))) { - p += 2; - result = 1; - } +#define APP_PARAM_ADD_LINK_FOR_RXQ(app, rxq_name) \ +({ \ + char link_name[APP_PARAM_NAME_SIZE]; \ + ssize_t link_param_pos; \ + uint32_t link_id, queue_id; \ + \ + sscanf((rxq_name), "RXQ%" SCNu32 ".%" SCNu32, &link_id, &queue_id);\ + sprintf(link_name, "LINK%" PRIu32, link_id); \ + link_param_pos = APP_PARAM_ADD((app)->link_params, link_name); \ + link_param_pos; \ +}) - if (((p[0] == 'n') && (p[1] == 'o')) || - ((p[0] == 'N') && (p[1] == 'O'))) { - p += 2; - result = 0; - } +#define APP_PARAM_ADD_LINK_FOR_TXQ(app, txq_name) \ +({ \ + char link_name[APP_PARAM_NAME_SIZE]; \ + ssize_t link_param_pos; \ + uint32_t link_id, queue_id; \ + \ + sscanf((txq_name), "TXQ%" SCNu32 ".%" SCNu32, &link_id, &queue_id);\ + sprintf(link_name, "LINK%" PRIu32, link_id); \ + link_param_pos = APP_PARAM_ADD((app)->link_params, link_name); \ + link_param_pos; \ +}) - if (((p[0] == 'o') && (p[1] == 'f') && (p[2] == 'f')) || - ((p[0] == 'O') && (p[1] == 'F') && (p[2] == 'F'))) { - p += 3; - result = 0; - } +#define APP_PARAM_ADD_LINK_FOR_TM(app, tm_name) \ +({ \ + char link_name[APP_PARAM_NAME_SIZE]; \ + ssize_t link_param_pos; \ + uint32_t link_id; \ + \ + sscanf((tm_name), "TM%" SCNu32, &link_id); \ + sprintf(link_name, "LINK%" PRIu32, link_id); \ + link_param_pos = APP_PARAM_ADD((app)->link_params, link_name); \ + link_param_pos; \ +}) - p = skip_white_spaces(p); +#define APP_PARAM_ADD_LINK_FOR_KNI(app, kni_name) \ +({ \ + char link_name[APP_PARAM_NAME_SIZE]; \ + ssize_t link_param_pos; \ + uint32_t link_id; \ + \ + sscanf((kni_name), "KNI%" SCNu32, &link_id); \ + sprintf(link_name, "LINK%" PRIu32, link_id); \ + link_param_pos = APP_PARAM_ADD((app)->link_params, link_name); \ + link_param_pos; \ +}) - if (p[0] != '\0') - return -EINVAL; +#define PARSE_CHECK_DUPLICATE_SECTION(obj) \ +do { \ + APP_CHECK(((obj)->parsed == 0), \ + "Parse error: duplicate \"%s\" section", (obj)->name); \ + (obj)->parsed++; \ +} while (0) - return result; -} +#define PARSE_CHECK_DUPLICATE_SECTION_EAL(obj) \ +do { \ + APP_CHECK(((obj)->parsed == 0), \ + "Parse error: duplicate \"%s\" section", "EAL"); \ + (obj)->parsed++; \ +} while (0) #define PARSE_ERROR(exp, section, entry) \ -APP_CHECK(exp, "Parse error in section \"%s\": entry \"%s\"\n", section, entry) +APP_CHECK(exp, "Parse error in section \"%s\": entry \"%s\"", section, entry) #define PARSE_ERROR_MESSAGE(exp, section, entry, message) \ -APP_CHECK(exp, "Parse error in section \"%s\", entry \"%s\": %s\n", \ +APP_CHECK(exp, "Parse error in section \"%s\", entry \"%s\": %s", \ section, entry, message) +#define PARSE_ERROR_NO_ELEMENTS(exp, section, entry) \ +APP_CHECK(exp, "Parse error in section \"%s\", entry \"%s\": " \ + "no elements detected", \ + section, entry) + +#define PARSE_ERROR_TOO_MANY_ELEMENTS(exp, section, entry, max) \ +APP_CHECK(exp, "Parse error in section \"%s\", entry \"%s\": " \ + "maximum number of elements allowed is %u", \ + section, entry, max) + +#define PARSE_ERROR_INVALID_ELEMENT(exp, section, entry, value) \ +APP_CHECK(exp, "Parse error in section \"%s\", entry \"%s\": " \ + "Invalid element value \"%s\"", \ + section, entry, value) #define PARSE_ERROR_MALLOC(exp) \ -APP_CHECK(exp, "Parse error: no free memory\n") +APP_CHECK(exp, "Parse error: no free memory") #define PARSE_ERROR_SECTION(exp, section) \ APP_CHECK(exp, "Parse error in section \"%s\"", section) #define PARSE_ERROR_SECTION_NO_ENTRIES(exp, section) \ -APP_CHECK(exp, "Parse error in section \"%s\": no entries\n", section) +APP_CHECK(exp, "Parse error in section \"%s\": no entries", section) #define PARSE_WARNING_IGNORED(exp, section, entry) \ do \ if (!(exp)) \ fprintf(stderr, "Parse warning in section \"%s\": " \ - "entry \"%s\" is ignored\n", section, entry); \ + "entry \"%s\" is ignored", section, entry); \ while (0) #define PARSE_ERROR_INVALID(exp, section, entry) \ -APP_CHECK(exp, "Parse error in section \"%s\": unrecognized entry \"%s\"\n",\ +APP_CHECK(exp, "Parse error in section \"%s\": unrecognized entry \"%s\"",\ section, entry) #define PARSE_ERROR_DUPLICATE(exp, section, entry) \ -APP_CHECK(exp, "Parse error in section \"%s\": duplicate entry \"%s\"\n",\ +APP_CHECK(exp, "Parse error in section \"%s\": duplicate entry \"%s\"", \ section, entry) -int -parser_read_uint64(uint64_t *value, const char *p) -{ - char *next; - uint64_t val; - - p = skip_white_spaces(p); - if (!isdigit(*p)) - return -EINVAL; - - val = strtoul(p, &next, 10); - if (p == next) - return -EINVAL; - - p = next; - switch (*p) { - case 'T': - val *= 1024ULL; - /* fall through */ - case 'G': - val *= 1024ULL; - /* fall through */ - case 'M': - val *= 1024ULL; - /* fall through */ - case 'k': - case 'K': - val *= 1024ULL; - p++; - break; - } - - p = skip_white_spaces(p); - if (*p != '\0') - return -EINVAL; - - *value = val; - return 0; -} - -int -parser_read_uint32(uint32_t *value, const char *p) -{ - uint64_t val = 0; - int ret = parser_read_uint64(&val, p); - - if (ret < 0) - return ret; - - if (val > UINT32_MAX) - return -ERANGE; - - *value = val; - return 0; -} - -int -parse_pipeline_core(uint32_t *socket, - uint32_t *core, - uint32_t *ht, - const char *entry) -{ - size_t num_len; - char num[8]; - - uint32_t s = 0, c = 0, h = 0, val; - uint8_t s_parsed = 0, c_parsed = 0, h_parsed = 0; - const char *next = skip_white_spaces(entry); - char type; - - /* Expect or [sX][cY][h]. At least one parameter is required. */ - while (*next != '\0') { - /* If everything parsed nothing should left */ - if (s_parsed && c_parsed && h_parsed) - return -EINVAL; - - type = *next; - switch (type) { - case 's': - case 'S': - if (s_parsed || c_parsed || h_parsed) - return -EINVAL; - s_parsed = 1; - next++; - break; - case 'c': - case 'C': - if (c_parsed || h_parsed) - return -EINVAL; - c_parsed = 1; - next++; - break; - case 'h': - case 'H': - if (h_parsed) - return -EINVAL; - h_parsed = 1; - next++; - break; - default: - /* If it start from digit it must be only core id. */ - if (!isdigit(*next) || s_parsed || c_parsed || h_parsed) - return -EINVAL; - - type = 'C'; - } - - for (num_len = 0; *next != '\0'; next++, num_len++) { - if (num_len == RTE_DIM(num)) - return -EINVAL; - - if (!isdigit(*next)) - break; - - num[num_len] = *next; - } - - if (num_len == 0 && type != 'h' && type != 'H') - return -EINVAL; - - if (num_len != 0 && (type == 'h' || type == 'H')) - return -EINVAL; - - num[num_len] = '\0'; - val = strtol(num, NULL, 10); - - h = 0; - switch (type) { - case 's': - case 'S': - s = val; - break; - case 'c': - case 'C': - c = val; - break; - case 'h': - case 'H': - h = 1; - break; - } - } - - *socket = s; - *core = c; - *ht = h; - return 0; -} - -static uint32_t -get_hex_val(char c) -{ - switch (c) { - case '0': case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - return c - '0'; - case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': - return c - 'A' + 10; - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - return c - 'a' + 10; - default: - return 0; - } -} - -int -parse_hex_string(char *src, uint8_t *dst, uint32_t *size) -{ - char *c; - uint32_t len, i; - - /* Check input parameters */ - if ((src == NULL) || - (dst == NULL) || - (size == NULL) || - (*size == 0)) - return -1; - - len = strlen(src); - if (((len & 3) != 0) || - (len > (*size) * 2)) - return -1; - *size = len / 2; - - for (c = src; *c != 0; c++) { - if ((((*c) >= '0') && ((*c) <= '9')) || - (((*c) >= 'A') && ((*c) <= 'F')) || - (((*c) >= 'a') && ((*c) <= 'f'))) - continue; - - return -1; - } - - /* Convert chars to bytes */ - for (i = 0; i < *size; i++) - dst[i] = get_hex_val(src[2 * i]) * 16 + - get_hex_val(src[2 * i + 1]); - - return 0; -} - -static size_t -skip_digits(const char *src) -{ - size_t i; - - for (i = 0; isdigit(src[i]); i++); - - return i; -} - static int validate_name(const char *name, const char *prefix, int num) { @@ -583,6 +414,8 @@ parse_eal(struct app_params *app, rte_cfgfile_section_entries(cfg, section_name, entries, n_entries); + PARSE_CHECK_DUPLICATE_SECTION_EAL(p); + for (i = 0; i < n_entries; i++) { struct rte_cfgfile_entry *entry = &entries[i]; @@ -676,6 +509,8 @@ parse_eal(struct app_params *app, p->pci_blacklist[i] = strdup(entry->value); PARSE_ERROR_MALLOC(p->pci_blacklist[i]); + + break; } PARSE_ERROR_MESSAGE((i < APP_MAX_LINKS), @@ -700,6 +535,8 @@ parse_eal(struct app_params *app, p->pci_whitelist[i] = strdup(entry->value); PARSE_ERROR_MALLOC(p->pci_whitelist[i]); + + break; } PARSE_ERROR_MESSAGE((i < APP_MAX_LINKS), @@ -718,6 +555,8 @@ parse_eal(struct app_params *app, p->vdev[i] = strdup(entry->value); PARSE_ERROR_MALLOC(p->vdev[i]); + + break; } PARSE_ERROR_MESSAGE((i < APP_MAX_LINKS), @@ -934,21 +773,6 @@ parse_eal(struct app_params *app, continue; } - /* xen_dom0 */ - if (strcmp(entry->name, "xen_dom0") == 0) { - int val; - - PARSE_ERROR_DUPLICATE((p->xen_dom0_present == 0), - section_name, - entry->name); - p->xen_dom0_present = 1; - - val = parser_read_arg_bool(entry->value); - PARSE_ERROR((val >= 0), section_name, entry->name); - p->xen_dom0 = val; - continue; - } - /* unrecognized */ PARSE_ERROR_INVALID(0, section_name, entry->name); } @@ -956,344 +780,168 @@ parse_eal(struct app_params *app, free(entries); } -static int -parse_pipeline_pcap_source(struct app_params *app, - struct app_pipeline_params *p, - const char *file_name, const char *cp_size) -{ - const char *next = NULL; - char *end; - uint32_t i; - int parse_file = 0; - - if (file_name && !cp_size) { - next = file_name; - parse_file = 1; /* parse file path */ - } else if (cp_size && !file_name) { - next = cp_size; - parse_file = 0; /* parse copy size */ - } else - return -EINVAL; - - char name[APP_PARAM_NAME_SIZE]; - size_t name_len; - - if (p->n_pktq_in == 0) - return -EINVAL; - - for (i = 0; i < p->n_pktq_in; i++) { - if (p->pktq_in[i].type != APP_PKTQ_IN_SOURCE) - return -EINVAL; - } - - i = 0; - while (*next != '\0') { - uint32_t id; - - if (i >= p->n_pktq_in) - return -EINVAL; - - id = p->pktq_in[i].id; - - end = strchr(next, ' '); - if (!end) - name_len = strlen(next); - else - name_len = end - next; - - if (name_len == 0 || name_len == sizeof(name)) - return -EINVAL; - - strncpy(name, next, name_len); - name[name_len] = '\0'; - next += name_len; - if (*next != '\0') - next++; - - if (parse_file) { - app->source_params[id].file_name = strdup(name); - if (app->source_params[id].file_name == NULL) - return -ENOMEM; - } else { - if (parser_read_uint32( - &app->source_params[id].n_bytes_per_pkt, - name) != 0) { - if (app->source_params[id]. - file_name != NULL) - free(app->source_params[id]. - file_name); - return -EINVAL; - } - } - - i++; - - if (i == p->n_pktq_in) - return 0; - } - - return -EINVAL; -} - -static int +static void parse_pipeline_pktq_in(struct app_params *app, struct app_pipeline_params *p, - const char *value) + char *value) { - const char *next = value; - char *end; - char name[APP_PARAM_NAME_SIZE]; - size_t name_len; + p->n_pktq_in = 0; - while (*next != '\0') { + while (1) { enum app_pktq_in_type type; int id; - char *end_space; - char *end_tab; + char *name = strtok_r(value, PARSE_DELIMITER, &value); - next = skip_white_spaces(next); - if (!next) + if (name == NULL) break; - end_space = strchr(next, ' '); - end_tab = strchr(next, ' '); - - if (end_space && (!end_tab)) - end = end_space; - else if ((!end_space) && end_tab) - end = end_tab; - else if (end_space && end_tab) - end = RTE_MIN(end_space, end_tab); - else - end = NULL; - - if (!end) - name_len = strlen(next); - else - name_len = end - next; - - if (name_len == 0 || name_len == sizeof(name)) - return -EINVAL; - - strncpy(name, next, name_len); - name[name_len] = '\0'; - next += name_len; - if (*next != '\0') - next++; + PARSE_ERROR_TOO_MANY_ELEMENTS( + (p->n_pktq_in < RTE_DIM(p->pktq_in)), + p->name, "pktq_in", (uint32_t)RTE_DIM(p->pktq_in)); if (validate_name(name, "RXQ", 2) == 0) { type = APP_PKTQ_IN_HWQ; id = APP_PARAM_ADD(app->hwq_in_params, name); + APP_PARAM_ADD_LINK_FOR_RXQ(app, name); } else if (validate_name(name, "SWQ", 1) == 0) { type = APP_PKTQ_IN_SWQ; id = APP_PARAM_ADD(app->swq_params, name); } else if (validate_name(name, "TM", 1) == 0) { type = APP_PKTQ_IN_TM; id = APP_PARAM_ADD(app->tm_params, name); + APP_PARAM_ADD_LINK_FOR_TM(app, name); + } else if (validate_name(name, "TAP", 1) == 0) { + type = APP_PKTQ_IN_TAP; + id = APP_PARAM_ADD(app->tap_params, name); + } else if (validate_name(name, "KNI", 1) == 0) { + type = APP_PKTQ_IN_KNI; + id = APP_PARAM_ADD(app->kni_params, name); + APP_PARAM_ADD_LINK_FOR_KNI(app, name); } else if (validate_name(name, "SOURCE", 1) == 0) { type = APP_PKTQ_IN_SOURCE; id = APP_PARAM_ADD(app->source_params, name); } else - return -EINVAL; - - if (id < 0) - return id; + PARSE_ERROR_INVALID_ELEMENT(0, + p->name, "pktq_in", name); p->pktq_in[p->n_pktq_in].type = type; p->pktq_in[p->n_pktq_in].id = (uint32_t) id; p->n_pktq_in++; } - return 0; + PARSE_ERROR_NO_ELEMENTS((p->n_pktq_in > 0), p->name, "pktq_in"); } -static int +static void parse_pipeline_pktq_out(struct app_params *app, struct app_pipeline_params *p, - const char *value) + char *value) { - const char *next = value; - char *end; - char name[APP_PARAM_NAME_SIZE]; - size_t name_len; + p->n_pktq_out = 0; - while (*next != '\0') { + while (1) { enum app_pktq_out_type type; int id; - char *end_space; - char *end_tab; + char *name = strtok_r(value, PARSE_DELIMITER, &value); - next = skip_white_spaces(next); - if (!next) + if (name == NULL) break; - end_space = strchr(next, ' '); - end_tab = strchr(next, ' '); - - if (end_space && (!end_tab)) - end = end_space; - else if ((!end_space) && end_tab) - end = end_tab; - else if (end_space && end_tab) - end = RTE_MIN(end_space, end_tab); - else - end = NULL; - - if (!end) - name_len = strlen(next); - else - name_len = end - next; - - if (name_len == 0 || name_len == sizeof(name)) - return -EINVAL; + PARSE_ERROR_TOO_MANY_ELEMENTS( + (p->n_pktq_out < RTE_DIM(p->pktq_out)), + p->name, "pktq_out", (uint32_t)RTE_DIM(p->pktq_out)); - strncpy(name, next, name_len); - name[name_len] = '\0'; - next += name_len; - if (*next != '\0') - next++; if (validate_name(name, "TXQ", 2) == 0) { type = APP_PKTQ_OUT_HWQ; id = APP_PARAM_ADD(app->hwq_out_params, name); + APP_PARAM_ADD_LINK_FOR_TXQ(app, name); } else if (validate_name(name, "SWQ", 1) == 0) { type = APP_PKTQ_OUT_SWQ; id = APP_PARAM_ADD(app->swq_params, name); } else if (validate_name(name, "TM", 1) == 0) { type = APP_PKTQ_OUT_TM; id = APP_PARAM_ADD(app->tm_params, name); + APP_PARAM_ADD_LINK_FOR_TM(app, name); + } else if (validate_name(name, "TAP", 1) == 0) { + type = APP_PKTQ_OUT_TAP; + id = APP_PARAM_ADD(app->tap_params, name); + } else if (validate_name(name, "KNI", 1) == 0) { + type = APP_PKTQ_OUT_KNI; + id = APP_PARAM_ADD(app->kni_params, name); + APP_PARAM_ADD_LINK_FOR_KNI(app, name); } else if (validate_name(name, "SINK", 1) == 0) { type = APP_PKTQ_OUT_SINK; id = APP_PARAM_ADD(app->sink_params, name); } else - return -EINVAL; - - if (id < 0) - return id; + PARSE_ERROR_INVALID_ELEMENT(0, + p->name, "pktq_out", name); p->pktq_out[p->n_pktq_out].type = type; p->pktq_out[p->n_pktq_out].id = id; p->n_pktq_out++; } - return 0; + PARSE_ERROR_NO_ELEMENTS((p->n_pktq_out > 0), p->name, "pktq_out"); } -static int +static void parse_pipeline_msgq_in(struct app_params *app, struct app_pipeline_params *p, - const char *value) + char *value) { - const char *next = value; - char *end; - char name[APP_PARAM_NAME_SIZE]; - size_t name_len; - ssize_t idx; - - while (*next != '\0') { - char *end_space; - char *end_tab; - - next = skip_white_spaces(next); - if (!next) - break; - - end_space = strchr(next, ' '); - end_tab = strchr(next, ' '); + p->n_msgq_in = 0; - if (end_space && (!end_tab)) - end = end_space; - else if ((!end_space) && end_tab) - end = end_tab; - else if (end_space && end_tab) - end = RTE_MIN(end_space, end_tab); - else - end = NULL; - - if (!end) - name_len = strlen(next); - else - name_len = end - next; + while (1) { + int idx; + char *name = strtok_r(value, PARSE_DELIMITER, &value); - if (name_len == 0 || name_len == sizeof(name)) - return -EINVAL; + if (name == NULL) + break; - strncpy(name, next, name_len); - name[name_len] = '\0'; - next += name_len; - if (*next != '\0') - next++; + PARSE_ERROR_TOO_MANY_ELEMENTS( + (p->n_msgq_in < RTE_DIM(p->msgq_in)), + p->name, "msgq_in", (uint32_t)(RTE_DIM(p->msgq_in))); - if (validate_name(name, "MSGQ", 1) != 0) - return -EINVAL; + PARSE_ERROR_INVALID_ELEMENT( + (validate_name(name, "MSGQ", 1) == 0), + p->name, "msgq_in", name); idx = APP_PARAM_ADD(app->msgq_params, name); - if (idx < 0) - return idx; - p->msgq_in[p->n_msgq_in] = idx; p->n_msgq_in++; } - return 0; + PARSE_ERROR_NO_ELEMENTS((p->n_msgq_in > 0), p->name, "msgq_in"); } -static int +static void parse_pipeline_msgq_out(struct app_params *app, struct app_pipeline_params *p, - const char *value) + char *value) { - const char *next = value; - char *end; - char name[APP_PARAM_NAME_SIZE]; - size_t name_len; - ssize_t idx; - - while (*next != '\0') { - char *end_space; - char *end_tab; - - next = skip_white_spaces(next); - if (!next) - break; - - end_space = strchr(next, ' '); - end_tab = strchr(next, ' '); + p->n_msgq_out = 0; - if (end_space && (!end_tab)) - end = end_space; - else if ((!end_space) && end_tab) - end = end_tab; - else if (end_space && end_tab) - end = RTE_MIN(end_space, end_tab); - else - end = NULL; - - if (!end) - name_len = strlen(next); - else - name_len = end - next; + while (1) { + int idx; + char *name = strtok_r(value, PARSE_DELIMITER, &value); - if (name_len == 0 || name_len == sizeof(name)) - return -EINVAL; + if (name == NULL) + break; - strncpy(name, next, name_len); - name[name_len] = '\0'; - next += name_len; - if (*next != '\0') - next++; + PARSE_ERROR_TOO_MANY_ELEMENTS( + (p->n_msgq_out < RTE_DIM(p->msgq_out)), + p->name, "msgq_out", (uint32_t)RTE_DIM(p->msgq_out)); - if (validate_name(name, "MSGQ", 1) != 0) - return -EINVAL; + PARSE_ERROR_INVALID_ELEMENT( + (validate_name(name, "MSGQ", 1) == 0), + p->name, "msgq_out", name); idx = APP_PARAM_ADD(app->msgq_params, name); - if (idx < 0) - return idx; - p->msgq_out[p->n_msgq_out] = idx; p->n_msgq_out++; } - return 0; + PARSE_ERROR_NO_ELEMENTS((p->n_msgq_out > 0), p->name, "msgq_out"); } static void @@ -1316,9 +964,8 @@ parse_pipeline(struct app_params *app, rte_cfgfile_section_entries(cfg, section_name, entries, n_entries); param_idx = APP_PARAM_ADD(app->pipeline_params, section_name); - PARSER_PARAM_ADD_CHECK(param_idx, app->pipeline_params, section_name); - param = &app->pipeline_params[param_idx]; + PARSE_CHECK_DUPLICATE_SECTION(param); for (i = 0; i < n_entries; i++) { struct rte_cfgfile_entry *ent = &entries[i]; @@ -1345,38 +992,26 @@ parse_pipeline(struct app_params *app, } if (strcmp(ent->name, "pktq_in") == 0) { - int status = parse_pipeline_pktq_in(app, param, - ent->value); + parse_pipeline_pktq_in(app, param, ent->value); - PARSE_ERROR((status == 0), section_name, - ent->name); continue; } if (strcmp(ent->name, "pktq_out") == 0) { - int status = parse_pipeline_pktq_out(app, param, - ent->value); + parse_pipeline_pktq_out(app, param, ent->value); - PARSE_ERROR((status == 0), section_name, - ent->name); continue; } if (strcmp(ent->name, "msgq_in") == 0) { - int status = parse_pipeline_msgq_in(app, param, - ent->value); + parse_pipeline_msgq_in(app, param, ent->value); - PARSE_ERROR((status == 0), section_name, - ent->name); continue; } if (strcmp(ent->name, "msgq_out") == 0) { - int status = parse_pipeline_msgq_out(app, param, - ent->value); + parse_pipeline_msgq_out(app, param, ent->value); - PARSE_ERROR((status == 0), section_name, - ent->name); continue; } @@ -1390,24 +1025,6 @@ parse_pipeline(struct app_params *app, continue; } - if (strcmp(ent->name, "pcap_file_rd") == 0) { - int status = parse_pipeline_pcap_source(app, - param, ent->value, NULL); - - PARSE_ERROR((status == 0), section_name, - ent->name); - continue; - } - - if (strcmp(ent->name, "pcap_bytes_rd_per_pkt") == 0) { - int status = parse_pipeline_pcap_source(app, - param, NULL, ent->value); - - PARSE_ERROR((status == 0), section_name, - ent->name); - continue; - } - /* pipeline type specific items */ APP_CHECK((param->n_args < APP_MAX_PIPELINE_ARGS), "Parse error in section \"%s\": too many " @@ -1423,17 +1040,13 @@ parse_pipeline(struct app_params *app, param->n_args++; } - param->parsed = 1; - snprintf(name, sizeof(name), "MSGQ-REQ-%s", section_name); param_idx = APP_PARAM_ADD(app->msgq_params, name); - PARSER_PARAM_ADD_CHECK(param_idx, app->msgq_params, name); app->msgq_params[param_idx].cpu_socket_id = param->socket_id; param->msgq_in[param->n_msgq_in++] = param_idx; snprintf(name, sizeof(name), "MSGQ-RSP-%s", section_name); param_idx = APP_PARAM_ADD(app->msgq_params, name); - PARSER_PARAM_ADD_CHECK(param_idx, app->msgq_params, name); app->msgq_params[param_idx].cpu_socket_id = param->socket_id; param->msgq_out[param->n_msgq_out++] = param_idx; @@ -1442,7 +1055,6 @@ parse_pipeline(struct app_params *app, param->core_id, (param->hyper_th_id) ? "h" : ""); param_idx = APP_PARAM_ADD(app->msgq_params, name); - PARSER_PARAM_ADD_CHECK(param_idx, app->msgq_params, name); app->msgq_params[param_idx].cpu_socket_id = param->socket_id; snprintf(name, sizeof(name), "MSGQ-RSP-CORE-s%" PRIu32 "c%" PRIu32 "%s", @@ -1450,7 +1062,6 @@ parse_pipeline(struct app_params *app, param->core_id, (param->hyper_th_id) ? "h" : ""); param_idx = APP_PARAM_ADD(app->msgq_params, name); - PARSER_PARAM_ADD_CHECK(param_idx, app->msgq_params, name); app->msgq_params[param_idx].cpu_socket_id = param->socket_id; free(entries); @@ -1475,9 +1086,8 @@ parse_mempool(struct app_params *app, rte_cfgfile_section_entries(cfg, section_name, entries, n_entries); param_idx = APP_PARAM_ADD(app->mempool_params, section_name); - PARSER_PARAM_ADD_CHECK(param_idx, app->mempool_params, section_name); - param = &app->mempool_params[param_idx]; + PARSE_CHECK_DUPLICATE_SECTION(param); for (i = 0; i < n_entries; i++) { struct rte_cfgfile_entry *ent = &entries[i]; @@ -1522,19 +1132,164 @@ parse_mempool(struct app_params *app, PARSE_ERROR_INVALID(0, section_name, ent->name); } - param->parsed = 1; - free(entries); } -static void -parse_link(struct app_params *app, +static int +parse_link_rss_qs(struct app_link_params *p, + char *value) +{ + p->n_rss_qs = 0; + + while (1) { + char *token = strtok_r(value, PARSE_DELIMITER, &value); + + if (token == NULL) + break; + + if (p->n_rss_qs == RTE_DIM(p->rss_qs)) + return -ENOMEM; + + if (parser_read_uint32(&p->rss_qs[p->n_rss_qs++], token)) + return -EINVAL; + } + + return 0; +} + +static int +parse_link_rss_proto_ipv4(struct app_link_params *p, + char *value) +{ + uint64_t mask = 0; + + while (1) { + char *token = strtok_r(value, PARSE_DELIMITER, &value); + + if (token == NULL) + break; + + if (strcmp(token, "IP") == 0) { + mask |= ETH_RSS_IPV4; + continue; + } + if (strcmp(token, "FRAG") == 0) { + mask |= ETH_RSS_FRAG_IPV4; + continue; + } + if (strcmp(token, "TCP") == 0) { + mask |= ETH_RSS_NONFRAG_IPV4_TCP; + continue; + } + if (strcmp(token, "UDP") == 0) { + mask |= ETH_RSS_NONFRAG_IPV4_UDP; + continue; + } + if (strcmp(token, "SCTP") == 0) { + mask |= ETH_RSS_NONFRAG_IPV4_SCTP; + continue; + } + if (strcmp(token, "OTHER") == 0) { + mask |= ETH_RSS_NONFRAG_IPV4_OTHER; + continue; + } + return -EINVAL; + } + + p->rss_proto_ipv4 = mask; + return 0; +} + +static int +parse_link_rss_proto_ipv6(struct app_link_params *p, + char *value) +{ + uint64_t mask = 0; + + while (1) { + char *token = strtok_r(value, PARSE_DELIMITER, &value); + + if (token == NULL) + break; + + if (strcmp(token, "IP") == 0) { + mask |= ETH_RSS_IPV6; + continue; + } + if (strcmp(token, "FRAG") == 0) { + mask |= ETH_RSS_FRAG_IPV6; + continue; + } + if (strcmp(token, "TCP") == 0) { + mask |= ETH_RSS_NONFRAG_IPV6_TCP; + continue; + } + if (strcmp(token, "UDP") == 0) { + mask |= ETH_RSS_NONFRAG_IPV6_UDP; + continue; + } + if (strcmp(token, "SCTP") == 0) { + mask |= ETH_RSS_NONFRAG_IPV6_SCTP; + continue; + } + if (strcmp(token, "OTHER") == 0) { + mask |= ETH_RSS_NONFRAG_IPV6_OTHER; + continue; + } + if (strcmp(token, "IP_EX") == 0) { + mask |= ETH_RSS_IPV6_EX; + continue; + } + if (strcmp(token, "TCP_EX") == 0) { + mask |= ETH_RSS_IPV6_TCP_EX; + continue; + } + if (strcmp(token, "UDP_EX") == 0) { + mask |= ETH_RSS_IPV6_UDP_EX; + continue; + } + return -EINVAL; + } + + p->rss_proto_ipv6 = mask; + return 0; +} + +static int +parse_link_rss_proto_l2(struct app_link_params *p, + char *value) +{ + uint64_t mask = 0; + + while (1) { + char *token = strtok_r(value, PARSE_DELIMITER, &value); + + if (token == NULL) + break; + + if (strcmp(token, "L2") == 0) { + mask |= ETH_RSS_L2_PAYLOAD; + continue; + } + return -EINVAL; + } + + p->rss_proto_l2 = mask; + return 0; +} + +static void +parse_link(struct app_params *app, const char *section_name, struct rte_cfgfile *cfg) { struct app_link_params *param; struct rte_cfgfile_entry *entries; int n_entries, i; + int rss_qs_present = 0; + int rss_proto_ipv4_present = 0; + int rss_proto_ipv6_present = 0; + int rss_proto_l2_present = 0; int pci_bdf_present = 0; ssize_t param_idx; @@ -1547,9 +1302,8 @@ parse_link(struct app_params *app, rte_cfgfile_section_entries(cfg, section_name, entries, n_entries); param_idx = APP_PARAM_ADD(app->link_params, section_name); - PARSER_PARAM_ADD_CHECK(param_idx, app->link_params, section_name); - param = &app->link_params[param_idx]; + PARSE_CHECK_DUPLICATE_SECTION(param); for (i = 0; i < n_entries; i++) { struct rte_cfgfile_entry *ent = &entries[i]; @@ -1589,7 +1343,6 @@ parse_link(struct app_params *app, continue; } - if (strcmp(ent->name, "tcp_local_q") == 0) { int status = parser_read_uint32( ¶m->tcp_local_q, ent->value); @@ -1617,6 +1370,44 @@ parse_link(struct app_params *app, continue; } + if (strcmp(ent->name, "rss_qs") == 0) { + int status = parse_link_rss_qs(param, ent->value); + + PARSE_ERROR((status == 0), section_name, + ent->name); + rss_qs_present = 1; + continue; + } + + if (strcmp(ent->name, "rss_proto_ipv4") == 0) { + int status = + parse_link_rss_proto_ipv4(param, ent->value); + + PARSE_ERROR((status != -EINVAL), section_name, + ent->name); + rss_proto_ipv4_present = 1; + continue; + } + + if (strcmp(ent->name, "rss_proto_ipv6") == 0) { + int status = + parse_link_rss_proto_ipv6(param, ent->value); + + PARSE_ERROR((status != -EINVAL), section_name, + ent->name); + rss_proto_ipv6_present = 1; + continue; + } + + if (strcmp(ent->name, "rss_proto_l2") == 0) { + int status = parse_link_rss_proto_l2(param, ent->value); + + PARSE_ERROR((status != -EINVAL), section_name, + ent->name); + rss_proto_l2_present = 1; + continue; + } + if (strcmp(ent->name, "pci_bdf") == 0) { PARSE_ERROR_DUPLICATE((pci_bdf_present == 0), section_name, ent->name); @@ -1642,7 +1433,28 @@ parse_link(struct app_params *app, "this entry is mandatory (port_mask is not " "provided)"); - param->parsed = 1; + if (rss_proto_ipv4_present) + PARSE_ERROR_MESSAGE((rss_qs_present), + section_name, "rss_proto_ipv4", + "entry not allowed (rss_qs entry is not provided)"); + if (rss_proto_ipv6_present) + PARSE_ERROR_MESSAGE((rss_qs_present), + section_name, "rss_proto_ipv6", + "entry not allowed (rss_qs entry is not provided)"); + if (rss_proto_l2_present) + PARSE_ERROR_MESSAGE((rss_qs_present), + section_name, "rss_proto_l2", + "entry not allowed (rss_qs entry is not provided)"); + if (rss_proto_ipv4_present | + rss_proto_ipv6_present | + rss_proto_l2_present){ + if (rss_proto_ipv4_present == 0) + param->rss_proto_ipv4 = 0; + if (rss_proto_ipv6_present == 0) + param->rss_proto_ipv6 = 0; + if (rss_proto_l2_present == 0) + param->rss_proto_l2 = 0; + } free(entries); } @@ -1666,9 +1478,10 @@ parse_rxq(struct app_params *app, rte_cfgfile_section_entries(cfg, section_name, entries, n_entries); param_idx = APP_PARAM_ADD(app->hwq_in_params, section_name); - PARSER_PARAM_ADD_CHECK(param_idx, app->hwq_in_params, section_name); - param = &app->hwq_in_params[param_idx]; + PARSE_CHECK_DUPLICATE_SECTION(param); + + APP_PARAM_ADD_LINK_FOR_RXQ(app, section_name); for (i = 0; i < n_entries; i++) { struct rte_cfgfile_entry *ent = &entries[i]; @@ -1680,10 +1493,8 @@ parse_rxq(struct app_params *app, PARSE_ERROR((status == 0), section_name, ent->name); - idx = APP_PARAM_ADD(app->mempool_params, - ent->value); - PARSER_PARAM_ADD_CHECK(idx, app->mempool_params, - section_name); + + idx = APP_PARAM_ADD(app->mempool_params, ent->value); param->mempool_id = idx; continue; } @@ -1710,8 +1521,6 @@ parse_rxq(struct app_params *app, PARSE_ERROR_INVALID(0, section_name, ent->name); } - param->parsed = 1; - free(entries); } @@ -1734,9 +1543,10 @@ parse_txq(struct app_params *app, rte_cfgfile_section_entries(cfg, section_name, entries, n_entries); param_idx = APP_PARAM_ADD(app->hwq_out_params, section_name); - PARSER_PARAM_ADD_CHECK(param_idx, app->hwq_out_params, section_name); - param = &app->hwq_out_params[param_idx]; + PARSE_CHECK_DUPLICATE_SECTION(param); + + APP_PARAM_ADD_LINK_FOR_TXQ(app, section_name); for (i = 0; i < n_entries; i++) { struct rte_cfgfile_entry *ent = &entries[i]; @@ -1769,12 +1579,19 @@ parse_txq(struct app_params *app, continue; } + if (strcmp(ent->name, "n_retries") == 0) { + int status = parser_read_uint64(¶m->n_retries, + ent->value); + + PARSE_ERROR((status == 0), section_name, + ent->name); + continue; + } + /* unrecognized */ PARSE_ERROR_INVALID(0, section_name, ent->name); } - param->parsed = 1; - free(entries); } @@ -1802,9 +1619,8 @@ parse_swq(struct app_params *app, rte_cfgfile_section_entries(cfg, section_name, entries, n_entries); param_idx = APP_PARAM_ADD(app->swq_params, section_name); - PARSER_PARAM_ADD_CHECK(param_idx, app->swq_params, section_name); - param = &app->swq_params[param_idx]; + PARSE_CHECK_DUPLICATE_SECTION(param); for (i = 0; i < n_entries; i++) { struct rte_cfgfile_entry *ent = &entries[i]; @@ -1895,65 +1711,226 @@ parse_swq(struct app_params *app, continue; } - if (strcmp(ent->name, "ipv6_ras") == 0) { - int status = parser_read_arg_bool(ent->value); + if (strcmp(ent->name, "ipv6_ras") == 0) { + int status = parser_read_arg_bool(ent->value); + + PARSE_ERROR((status != -EINVAL), section_name, + ent->name); + param->ipv6_ras = status; + continue; + } + + if (strcmp(ent->name, "mtu") == 0) { + int status = parser_read_uint32(¶m->mtu, + ent->value); + + PARSE_ERROR((status == 0), section_name, + ent->name); + mtu_present = 1; + continue; + } + + if (strcmp(ent->name, "metadata_size") == 0) { + int status = parser_read_uint32( + ¶m->metadata_size, ent->value); + + PARSE_ERROR((status == 0), section_name, + ent->name); + metadata_size_present = 1; + continue; + } + + if (strcmp(ent->name, "mempool_direct") == 0) { + int status = validate_name(ent->value, + "MEMPOOL", 1); + ssize_t idx; + + PARSE_ERROR((status == 0), section_name, + ent->name); + + idx = APP_PARAM_ADD(app->mempool_params, ent->value); + param->mempool_direct_id = idx; + + mempool_direct_present = 1; + continue; + } + + if (strcmp(ent->name, "mempool_indirect") == 0) { + int status = validate_name(ent->value, + "MEMPOOL", 1); + ssize_t idx; + + PARSE_ERROR((status == 0), section_name, + ent->name); + + idx = APP_PARAM_ADD(app->mempool_params, ent->value); + param->mempool_indirect_id = idx; + + mempool_indirect_present = 1; + continue; + } + + /* unrecognized */ + PARSE_ERROR_INVALID(0, section_name, ent->name); + } + + APP_CHECK(((mtu_present == 0) || + ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))), + "Parse error in section \"%s\": IPv4/IPv6 fragmentation " + "is off, therefore entry \"mtu\" is not allowed", + section_name); + + APP_CHECK(((metadata_size_present == 0) || + ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))), + "Parse error in section \"%s\": IPv4/IPv6 fragmentation " + "is off, therefore entry \"metadata_size\" is " + "not allowed", section_name); + + APP_CHECK(((mempool_direct_present == 0) || + ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))), + "Parse error in section \"%s\": IPv4/IPv6 fragmentation " + "is off, therefore entry \"mempool_direct\" is " + "not allowed", section_name); + + APP_CHECK(((mempool_indirect_present == 0) || + ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))), + "Parse error in section \"%s\": IPv4/IPv6 fragmentation " + "is off, therefore entry \"mempool_indirect\" is " + "not allowed", section_name); + + free(entries); +} + +static void +parse_tm(struct app_params *app, + const char *section_name, + struct rte_cfgfile *cfg) +{ + struct app_pktq_tm_params *param; + struct rte_cfgfile_entry *entries; + int n_entries, i; + ssize_t param_idx; + + n_entries = rte_cfgfile_section_num_entries(cfg, section_name); + PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name); + + entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry)); + PARSE_ERROR_MALLOC(entries != NULL); + + rte_cfgfile_section_entries(cfg, section_name, entries, n_entries); + + param_idx = APP_PARAM_ADD(app->tm_params, section_name); + param = &app->tm_params[param_idx]; + PARSE_CHECK_DUPLICATE_SECTION(param); + + APP_PARAM_ADD_LINK_FOR_TM(app, section_name); + + for (i = 0; i < n_entries; i++) { + struct rte_cfgfile_entry *ent = &entries[i]; + + if (strcmp(ent->name, "cfg") == 0) { + param->file_name = strdup(ent->value); + PARSE_ERROR_MALLOC(param->file_name != NULL); + continue; + } + + if (strcmp(ent->name, "burst_read") == 0) { + int status = parser_read_uint32( + ¶m->burst_read, ent->value); + + PARSE_ERROR((status == 0), section_name, + ent->name); + continue; + } + + if (strcmp(ent->name, "burst_write") == 0) { + int status = parser_read_uint32( + ¶m->burst_write, ent->value); + + PARSE_ERROR((status == 0), section_name, + ent->name); + continue; + } + + /* unrecognized */ + PARSE_ERROR_INVALID(0, section_name, ent->name); + } + + free(entries); +} + +static void +parse_tap(struct app_params *app, + const char *section_name, + struct rte_cfgfile *cfg) +{ + struct app_pktq_tap_params *param; + struct rte_cfgfile_entry *entries; + int n_entries, i; + ssize_t param_idx; + + n_entries = rte_cfgfile_section_num_entries(cfg, section_name); + PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name); + + entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry)); + PARSE_ERROR_MALLOC(entries != NULL); + + rte_cfgfile_section_entries(cfg, section_name, entries, n_entries); - PARSE_ERROR((status != -EINVAL), section_name, - ent->name); - param->ipv6_ras = status; - continue; - } + param_idx = APP_PARAM_ADD(app->tap_params, section_name); + param = &app->tap_params[param_idx]; + PARSE_CHECK_DUPLICATE_SECTION(param); - if (strcmp(ent->name, "mtu") == 0) { - int status = parser_read_uint32(¶m->mtu, - ent->value); + for (i = 0; i < n_entries; i++) { + struct rte_cfgfile_entry *ent = &entries[i]; + + if (strcmp(ent->name, "burst_read") == 0) { + int status = parser_read_uint32( + ¶m->burst_read, ent->value); PARSE_ERROR((status == 0), section_name, ent->name); - mtu_present = 1; continue; } - if (strcmp(ent->name, "metadata_size") == 0) { + if (strcmp(ent->name, "burst_write") == 0) { int status = parser_read_uint32( - ¶m->metadata_size, ent->value); + ¶m->burst_write, ent->value); PARSE_ERROR((status == 0), section_name, ent->name); - metadata_size_present = 1; continue; } - if (strcmp(ent->name, "mempool_direct") == 0) { - int status = validate_name(ent->value, - "MEMPOOL", 1); - ssize_t idx; + if (strcmp(ent->name, "dropless") == 0) { + int status = parser_read_arg_bool(ent->value); - PARSE_ERROR((status == 0), section_name, + PARSE_ERROR((status != -EINVAL), section_name, ent->name); + param->dropless = status; + continue; + } - idx = APP_PARAM_ADD(app->mempool_params, + if (strcmp(ent->name, "n_retries") == 0) { + int status = parser_read_uint64(¶m->n_retries, ent->value); - PARSER_PARAM_ADD_CHECK(idx, app->mempool_params, - section_name); - param->mempool_direct_id = idx; - mempool_direct_present = 1; + + PARSE_ERROR((status == 0), section_name, + ent->name); continue; } - if (strcmp(ent->name, "mempool_indirect") == 0) { + if (strcmp(ent->name, "mempool") == 0) { int status = validate_name(ent->value, "MEMPOOL", 1); ssize_t idx; PARSE_ERROR((status == 0), section_name, ent->name); - idx = APP_PARAM_ADD(app->mempool_params, - ent->value); - PARSER_PARAM_ADD_CHECK(idx, app->mempool_params, - section_name); - param->mempool_indirect_id = idx; - mempool_indirect_present = 1; + + idx = APP_PARAM_ADD(app->mempool_params, ent->value); + param->mempool_id = idx; + continue; } @@ -1961,41 +1938,15 @@ parse_swq(struct app_params *app, PARSE_ERROR_INVALID(0, section_name, ent->name); } - APP_CHECK(((mtu_present) && - ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))), - "Parse error in section \"%s\": IPv4/IPv6 fragmentation " - "is off, therefore entry \"mtu\" is not allowed", - section_name); - - APP_CHECK(((metadata_size_present) && - ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))), - "Parse error in section \"%s\": IPv4/IPv6 fragmentation " - "is off, therefore entry \"metadata_size\" is " - "not allowed", section_name); - - APP_CHECK(((mempool_direct_present) && - ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))), - "Parse error in section \"%s\": IPv4/IPv6 fragmentation " - "is off, therefore entry \"mempool_direct\" is " - "not allowed", section_name); - - APP_CHECK(((mempool_indirect_present) && - ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))), - "Parse error in section \"%s\": IPv4/IPv6 fragmentation " - "is off, therefore entry \"mempool_indirect\" is " - "not allowed", section_name); - - param->parsed = 1; - free(entries); } static void -parse_tm(struct app_params *app, - const char *section_name, - struct rte_cfgfile *cfg) +parse_kni(struct app_params *app, + const char *section_name, + struct rte_cfgfile *cfg) { - struct app_pktq_tm_params *param; + struct app_pktq_kni_params *param; struct rte_cfgfile_entry *entries; int n_entries, i; ssize_t param_idx; @@ -2008,35 +1959,74 @@ parse_tm(struct app_params *app, rte_cfgfile_section_entries(cfg, section_name, entries, n_entries); - param_idx = APP_PARAM_ADD(app->tm_params, section_name); - PARSER_PARAM_ADD_CHECK(param_idx, app->tm_params, section_name); + param_idx = APP_PARAM_ADD(app->kni_params, section_name); + param = &app->kni_params[param_idx]; + PARSE_CHECK_DUPLICATE_SECTION(param); - param = &app->tm_params[param_idx]; + APP_PARAM_ADD_LINK_FOR_KNI(app, section_name); for (i = 0; i < n_entries; i++) { struct rte_cfgfile_entry *ent = &entries[i]; - if (strcmp(ent->name, "cfg") == 0) { - param->file_name = strdup(ent->value); - PARSE_ERROR_MALLOC(param->file_name != NULL); + if (strcmp(ent->name, "core") == 0) { + int status = parse_pipeline_core( + ¶m->socket_id, + ¶m->core_id, + ¶m->hyper_th_id, + ent->value); + + PARSE_ERROR((status == 0), section_name, + ent->name); + param->force_bind = 1; + continue; + } + + if (strcmp(ent->name, "mempool") == 0) { + int status = validate_name(ent->value, + "MEMPOOL", 1); + ssize_t idx; + + PARSE_ERROR((status == 0), section_name, + ent->name); + + idx = APP_PARAM_ADD(app->mempool_params, ent->value); + param->mempool_id = idx; continue; } if (strcmp(ent->name, "burst_read") == 0) { - int status = parser_read_uint32( - ¶m->burst_read, ent->value); + int status = parser_read_uint32(¶m->burst_read, + ent->value); PARSE_ERROR((status == 0), section_name, - ent->name); + ent->name); continue; } if (strcmp(ent->name, "burst_write") == 0) { - int status = parser_read_uint32( - ¶m->burst_write, ent->value); + int status = parser_read_uint32(¶m->burst_write, + ent->value); PARSE_ERROR((status == 0), section_name, - ent->name); + ent->name); + continue; + } + + if (strcmp(ent->name, "dropless") == 0) { + int status = parser_read_arg_bool(ent->value); + + PARSE_ERROR((status != -EINVAL), section_name, + ent->name); + param->dropless = status; + continue; + } + + if (strcmp(ent->name, "n_retries") == 0) { + int status = parser_read_uint64(¶m->n_retries, + ent->value); + + PARSE_ERROR((status == 0), section_name, + ent->name); continue; } @@ -2044,8 +2034,6 @@ parse_tm(struct app_params *app, PARSE_ERROR_INVALID(0, section_name, ent->name); } - param->parsed = 1; - free(entries); } @@ -2058,6 +2046,8 @@ parse_source(struct app_params *app, struct rte_cfgfile_entry *entries; int n_entries, i; ssize_t param_idx; + uint32_t pcap_file_present = 0; + uint32_t pcap_size_present = 0; n_entries = rte_cfgfile_section_num_entries(cfg, section_name); PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name); @@ -2068,9 +2058,8 @@ parse_source(struct app_params *app, rte_cfgfile_section_entries(cfg, section_name, entries, n_entries); param_idx = APP_PARAM_ADD(app->source_params, section_name); - PARSER_PARAM_ADD_CHECK(param_idx, app->source_params, section_name); - param = &app->source_params[param_idx]; + PARSE_CHECK_DUPLICATE_SECTION(param); for (i = 0; i < n_entries; i++) { struct rte_cfgfile_entry *ent = &entries[i]; @@ -2082,10 +2071,8 @@ parse_source(struct app_params *app, PARSE_ERROR((status == 0), section_name, ent->name); - idx = APP_PARAM_ADD(app->mempool_params, - ent->value); - PARSER_PARAM_ADD_CHECK(idx, app->mempool_params, - section_name); + + idx = APP_PARAM_ADD(app->mempool_params, ent->value); param->mempool_id = idx; continue; } @@ -2099,26 +2086,97 @@ parse_source(struct app_params *app, continue; } - if (strcmp(ent->name, "pcap_file_rd")) { + if (strcmp(ent->name, "pcap_file_rd") == 0) { + PARSE_ERROR_DUPLICATE((pcap_file_present == 0), + section_name, ent->name); + param->file_name = strdup(ent->value); PARSE_ERROR_MALLOC(param->file_name != NULL); + pcap_file_present = 1; + continue; } if (strcmp(ent->name, "pcap_bytes_rd_per_pkt") == 0) { - int status = parser_read_uint32( + int status; + + PARSE_ERROR_DUPLICATE((pcap_size_present == 0), + section_name, ent->name); + + status = parser_read_uint32( ¶m->n_bytes_per_pkt, ent->value); PARSE_ERROR((status == 0), section_name, ent->name); + pcap_size_present = 1; + + continue; } /* unrecognized */ PARSE_ERROR_INVALID(0, section_name, ent->name); } - param->parsed = 1; + free(entries); +} + +static void +parse_sink(struct app_params *app, + const char *section_name, + struct rte_cfgfile *cfg) +{ + struct app_pktq_sink_params *param; + struct rte_cfgfile_entry *entries; + int n_entries, i; + ssize_t param_idx; + uint32_t pcap_file_present = 0; + uint32_t pcap_n_pkt_present = 0; + + n_entries = rte_cfgfile_section_num_entries(cfg, section_name); + PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name); + + entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry)); + PARSE_ERROR_MALLOC(entries != NULL); + + rte_cfgfile_section_entries(cfg, section_name, entries, n_entries); + + param_idx = APP_PARAM_ADD(app->sink_params, section_name); + param = &app->sink_params[param_idx]; + PARSE_CHECK_DUPLICATE_SECTION(param); + + for (i = 0; i < n_entries; i++) { + struct rte_cfgfile_entry *ent = &entries[i]; + + if (strcmp(ent->name, "pcap_file_wr") == 0) { + PARSE_ERROR_DUPLICATE((pcap_file_present == 0), + section_name, ent->name); + + param->file_name = strdup(ent->value); + + PARSE_ERROR_MALLOC((param->file_name != NULL)); + + continue; + } + + if (strcmp(ent->name, "pcap_n_pkt_wr") == 0) { + int status; + + PARSE_ERROR_DUPLICATE((pcap_n_pkt_present == 0), + section_name, ent->name); + + status = parser_read_uint32( + ¶m->n_pkts_to_dump, ent->value); + + PARSE_ERROR((status == 0), section_name, + ent->name); + + continue; + } + + /* unrecognized */ + PARSE_ERROR_INVALID(0, section_name, ent->name); + } free(entries); } @@ -2142,9 +2200,8 @@ parse_msgq_req_pipeline(struct app_params *app, rte_cfgfile_section_entries(cfg, section_name, entries, n_entries); param_idx = APP_PARAM_ADD(app->msgq_params, section_name); - PARSER_PARAM_ADD_CHECK(param_idx, app->msgq_params, section_name); - param = &app->msgq_params[param_idx]; + PARSE_CHECK_DUPLICATE_SECTION(param); for (i = 0; i < n_entries; i++) { struct rte_cfgfile_entry *ent = &entries[i]; @@ -2162,7 +2219,6 @@ parse_msgq_req_pipeline(struct app_params *app, PARSE_ERROR_INVALID(0, section_name, ent->name); } - param->parsed = 1; free(entries); } @@ -2185,9 +2241,8 @@ parse_msgq_rsp_pipeline(struct app_params *app, rte_cfgfile_section_entries(cfg, section_name, entries, n_entries); param_idx = APP_PARAM_ADD(app->msgq_params, section_name); - PARSER_PARAM_ADD_CHECK(param_idx, app->msgq_params, section_name); - param = &app->msgq_params[param_idx]; + PARSE_CHECK_DUPLICATE_SECTION(param); for (i = 0; i < n_entries; i++) { struct rte_cfgfile_entry *ent = &entries[i]; @@ -2205,8 +2260,6 @@ parse_msgq_rsp_pipeline(struct app_params *app, PARSE_ERROR_INVALID(0, section_name, ent->name); } - param->parsed = 1; - free(entries); } @@ -2229,9 +2282,8 @@ parse_msgq(struct app_params *app, rte_cfgfile_section_entries(cfg, section_name, entries, n_entries); param_idx = APP_PARAM_ADD(app->msgq_params, section_name); - PARSER_PARAM_ADD_CHECK(param_idx, app->msgq_params, section_name); - param = &app->msgq_params[param_idx]; + PARSE_CHECK_DUPLICATE_SECTION(param); for (i = 0; i < n_entries; i++) { struct rte_cfgfile_entry *ent = &entries[i]; @@ -2258,8 +2310,6 @@ parse_msgq(struct app_params *app, PARSE_ERROR_INVALID(0, section_name, ent->name); } - param->parsed = 1; - free(entries); } @@ -2282,7 +2332,10 @@ static const struct config_section cfg_file_scheme[] = { {"TXQ", 2, parse_txq}, {"SWQ", 1, parse_swq}, {"TM", 1, parse_tm}, + {"TAP", 1, parse_tap}, + {"KNI", 1, parse_kni}, {"SOURCE", 1, parse_source}, + {"SINK", 1, parse_sink}, {"MSGQ-REQ-PIPELINE", 1, parse_msgq_req_pipeline}, {"MSGQ-RSP-PIPELINE", 1, parse_msgq_rsp_pipeline}, {"MSGQ", 1, parse_msgq}, @@ -2291,10 +2344,7 @@ static const struct config_section cfg_file_scheme[] = { static void create_implicit_mempools(struct app_params *app) { - ssize_t idx; - - idx = APP_PARAM_ADD(app->mempool_params, "MEMPOOL0"); - PARSER_PARAM_ADD_CHECK(idx, app->mempool_params, "start-up"); + APP_PARAM_ADD(app->mempool_params, "MEMPOOL0"); } static void @@ -2313,7 +2363,6 @@ create_implicit_links_from_port_mask(struct app_params *app, snprintf(name, sizeof(name), "LINK%" PRIu32, link_id); idx = APP_PARAM_ADD(app->link_params, name); - PARSER_PARAM_ADD_CHECK(idx, app->link_params, name); app->link_params[idx].pmd_id = pmd_id; link_id++; @@ -2328,6 +2377,11 @@ assign_link_pmd_id_from_pci_bdf(struct app_params *app) for (i = 0; i < app->n_links; i++) { struct app_link_params *link = &app->link_params[i]; + APP_CHECK((strlen(link->pci_bdf)), + "Parse error: %s pci_bdf is not configured " + "(port_mask is not provided)", + link->name); + link->pmd_id = i; } } @@ -2418,6 +2472,8 @@ app_config_parse(struct app_params *app, const char *file_name) APP_PARAM_COUNT(app->hwq_out_params, app->n_pktq_hwq_out); APP_PARAM_COUNT(app->swq_params, app->n_pktq_swq); APP_PARAM_COUNT(app->tm_params, app->n_pktq_tm); + APP_PARAM_COUNT(app->tap_params, app->n_pktq_tap); + APP_PARAM_COUNT(app->kni_params, app->n_pktq_kni); APP_PARAM_COUNT(app->source_params, app->n_pktq_source); APP_PARAM_COUNT(app->sink_params, app->n_pktq_sink); APP_PARAM_COUNT(app->msgq_params, app->n_msgq); @@ -2536,10 +2592,6 @@ save_eal_params(struct app_params *app, FILE *f) if (p->vfio_intr) fprintf(f, "%s = %s\n", "vfio_intr", p->vfio_intr); - if (p->xen_dom0_present) - fprintf(f, "%s = %s\n", "xen_dom0", - (p->xen_dom0) ? "yes" : "no"); - fputc('\n', f); } @@ -2589,6 +2641,84 @@ save_links_params(struct app_params *app, FILE *f) fprintf(f, "%s = %" PRIu32 "\n", "sctp_local_q", p->sctp_local_q); + if (p->n_rss_qs) { + uint32_t j; + + /* rss_qs */ + fprintf(f, "rss_qs = "); + for (j = 0; j < p->n_rss_qs; j++) + fprintf(f, "%" PRIu32 " ", p->rss_qs[j]); + fputc('\n', f); + + /* rss_proto_ipv4 */ + if (p->rss_proto_ipv4) { + fprintf(f, "rss_proto_ipv4 = "); + if (p->rss_proto_ipv4 & ETH_RSS_IPV4) + fprintf(f, "IP "); + if (p->rss_proto_ipv4 & ETH_RSS_FRAG_IPV4) + fprintf(f, "FRAG "); + if (p->rss_proto_ipv4 & + ETH_RSS_NONFRAG_IPV4_TCP) + fprintf(f, "TCP "); + if (p->rss_proto_ipv4 & + ETH_RSS_NONFRAG_IPV4_UDP) + fprintf(f, "UDP "); + if (p->rss_proto_ipv4 & + ETH_RSS_NONFRAG_IPV4_SCTP) + fprintf(f, "SCTP "); + if (p->rss_proto_ipv4 & + ETH_RSS_NONFRAG_IPV4_OTHER) + fprintf(f, "OTHER "); + fprintf(f, "\n"); + } else + fprintf(f, "; rss_proto_ipv4 = \n"); + + /* rss_proto_ipv6 */ + if (p->rss_proto_ipv6) { + fprintf(f, "rss_proto_ipv6 = "); + if (p->rss_proto_ipv6 & ETH_RSS_IPV6) + fprintf(f, "IP "); + if (p->rss_proto_ipv6 & ETH_RSS_FRAG_IPV6) + fprintf(f, "FRAG "); + if (p->rss_proto_ipv6 & + ETH_RSS_NONFRAG_IPV6_TCP) + fprintf(f, "TCP "); + if (p->rss_proto_ipv6 & + ETH_RSS_NONFRAG_IPV6_UDP) + fprintf(f, "UDP "); + if (p->rss_proto_ipv6 & + ETH_RSS_NONFRAG_IPV6_SCTP) + fprintf(f, "SCTP "); + if (p->rss_proto_ipv6 & + ETH_RSS_NONFRAG_IPV6_OTHER) + fprintf(f, "OTHER "); + if (p->rss_proto_ipv6 & ETH_RSS_IPV6_EX) + fprintf(f, "IP_EX "); + if (p->rss_proto_ipv6 & + ETH_RSS_IPV6_TCP_EX) + fprintf(f, "TCP_EX "); + if (p->rss_proto_ipv6 & + ETH_RSS_IPV6_UDP_EX) + fprintf(f, "UDP_EX "); + fprintf(f, "\n"); + } else + fprintf(f, "; rss_proto_ipv6 = \n"); + + /* rss_proto_l2 */ + if (p->rss_proto_l2) { + fprintf(f, "rss_proto_l2 = "); + if (p->rss_proto_l2 & ETH_RSS_L2_PAYLOAD) + fprintf(f, "L2 "); + fprintf(f, "\n"); + } else + fprintf(f, "; rss_proto_l2 = \n"); + } else { + fprintf(f, "; rss_qs = \n"); + fprintf(f, "; rss_proto_ipv4 = \n"); + fprintf(f, "; rss_proto_ipv6 = \n"); + fprintf(f, "; rss_proto_l2 = \n"); + } + if (strlen(p->pci_bdf)) fprintf(f, "%s = %s\n", "pci_bdf", p->pci_bdf); @@ -2637,6 +2767,7 @@ save_txq_params(struct app_params *app, FILE *f) fprintf(f, "%s = %s\n", "dropless", p->dropless ? "yes" : "no"); + fprintf(f, "%s = %" PRIu64 "\n", "n_retries", p->n_retries); fputc('\n', f); } @@ -2701,6 +2832,77 @@ save_tm_params(struct app_params *app, FILE *f) } } +static void +save_tap_params(struct app_params *app, FILE *f) +{ + struct app_pktq_tap_params *p; + size_t i, count; + + count = RTE_DIM(app->tap_params); + for (i = 0; i < count; i++) { + p = &app->tap_params[i]; + if (!APP_PARAM_VALID(p)) + continue; + + fprintf(f, "[%s]\n", p->name); + fprintf(f, "%s = %" PRIu32 "\n", "burst_read", p->burst_read); + fprintf(f, "%s = %" PRIu32 "\n", "burst_write", p->burst_write); + fprintf(f, "%s = %s\n", "dropless", p->dropless ? "yes" : "no"); + fprintf(f, "%s = %" PRIu64 "\n", "n_retries", p->n_retries); + fprintf(f, "%s = %s\n", "mempool", + app->mempool_params[p->mempool_id].name); + + fputc('\n', f); + } +} + +static void +save_kni_params(struct app_params *app, FILE *f) +{ + struct app_pktq_kni_params *p; + size_t i, count; + + count = RTE_DIM(app->kni_params); + for (i = 0; i < count; i++) { + p = &app->kni_params[i]; + if (!APP_PARAM_VALID(p)) + continue; + + /* section name */ + fprintf(f, "[%s]\n", p->name); + + /* core */ + if (p->force_bind) { + fprintf(f, "; force_bind = 1\n"); + fprintf(f, "core = s%" PRIu32 "c%" PRIu32 "%s\n", + p->socket_id, + p->core_id, + (p->hyper_th_id) ? "h" : ""); + } else + fprintf(f, "; force_bind = 0\n"); + + /* mempool */ + fprintf(f, "%s = %s\n", "mempool", + app->mempool_params[p->mempool_id].name); + + /* burst_read */ + fprintf(f, "%s = %" PRIu32 "\n", "burst_read", p->burst_read); + + /* burst_write */ + fprintf(f, "%s = %" PRIu32 "\n", "burst_write", p->burst_write); + + /* dropless */ + fprintf(f, "%s = %s\n", + "dropless", + p->dropless ? "yes" : "no"); + + /* n_retries */ + fprintf(f, "%s = %" PRIu64 "\n", "n_retries", p->n_retries); + + fputc('\n', f); + } +} + static void save_source_params(struct app_params *app, FILE *f) { @@ -2725,6 +2927,26 @@ save_source_params(struct app_params *app, FILE *f) } } +static void +save_sink_params(struct app_params *app, FILE *f) +{ + struct app_pktq_sink_params *p; + size_t i, count; + + count = RTE_DIM(app->sink_params); + for (i = 0; i < count; i++) { + p = &app->sink_params[i]; + if (!APP_PARAM_VALID(p)) + continue; + + fprintf(f, "[%s]\n", p->name); + fprintf(f, "%s = %s\n", "pcap_file_wr", p->file_name); + fprintf(f, "%s = %" PRIu32 "\n", + "pcap_n_pkt_wr", p->n_pkts_to_dump); + fputc('\n', f); + } +} + static void save_msgq_params(struct app_params *app, FILE *f) { @@ -2788,6 +3010,12 @@ save_pipeline_params(struct app_params *app, FILE *f) case APP_PKTQ_IN_TM: name = app->tm_params[pp->id].name; break; + case APP_PKTQ_IN_TAP: + name = app->tap_params[pp->id].name; + break; + case APP_PKTQ_IN_KNI: + name = app->kni_params[pp->id].name; + break; case APP_PKTQ_IN_SOURCE: name = app->source_params[pp->id].name; break; @@ -2822,6 +3050,12 @@ save_pipeline_params(struct app_params *app, FILE *f) case APP_PKTQ_OUT_TM: name = app->tm_params[pp->id].name; break; + case APP_PKTQ_OUT_TAP: + name = app->tap_params[pp->id].name; + break; + case APP_PKTQ_OUT_KNI: + name = app->kni_params[pp->id].name; + break; case APP_PKTQ_OUT_SINK: name = app->sink_params[pp->id].name; break; @@ -2907,7 +3141,10 @@ app_config_save(struct app_params *app, const char *file_name) save_txq_params(app, file); save_swq_params(app, file); save_tm_params(app, file); + save_tap_params(app, file); + save_kni_params(app, file); save_source_params(app, file); + save_sink_params(app, file); save_msgq_params(app, file); fclose(file); @@ -2951,6 +3188,16 @@ app_config_init(struct app_params *app) &default_tm_params, sizeof(default_tm_params)); + for (i = 0; i < RTE_DIM(app->tap_params); i++) + memcpy(&app->tap_params[i], + &default_tap_params, + sizeof(default_tap_params)); + + for (i = 0; i < RTE_DIM(app->kni_params); i++) + memcpy(&app->kni_params[i], + &default_kni_params, + sizeof(default_kni_params)); + for (i = 0; i < RTE_DIM(app->source_params); i++) memcpy(&app->source_params[i], &default_source_params, @@ -3105,7 +3352,7 @@ app_config_args(struct app_params *app, int argc, char **argv) app_print_usage(argv[0]); } - optind = 0; /* reset getopt lib */ + optind = 1; /* reset getopt lib */ /* Check dependencies between args */ if (preproc_params_present && (preproc_present == 0))