4 * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 #include <rte_errno.h>
45 #include <rte_cfgfile.h>
46 #include <rte_string_fns.h>
51 * Default config values
54 static struct app_params app_params_default = {
55 .config_file = "./config/ip_pipeline.cfg",
56 .log_level = APP_LOG_LEVEL_HIGH,
63 static const struct app_mempool_params mempool_params_default = {
65 .buffer_size = 2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM,
66 .pool_size = 32 * 1024,
71 static const struct app_link_params link_params_default = {
89 .mq_mode = ETH_MQ_RX_NONE,
91 .header_split = 0, /* Header split */
92 .hw_ip_checksum = 0, /* IP checksum offload */
93 .hw_vlan_filter = 0, /* VLAN filtering */
94 .hw_vlan_strip = 0, /* VLAN strip */
95 .hw_vlan_extend = 0, /* Extended VLAN */
96 .jumbo_frame = 0, /* Jumbo frame support */
97 .hw_strip_crc = 0, /* CRC strip by HW */
98 .enable_scatter = 0, /* Scattered packets RX handler */
100 .max_rx_pkt_len = 9000, /* Jumbo frame max packet len */
101 .split_hdr_size = 0, /* Header split buffer size */
104 .mq_mode = ETH_MQ_TX_NONE,
112 static const struct app_pktq_hwq_in_params default_hwq_in_params = {
124 .rx_free_thresh = 64,
126 .rx_deferred_start = 0,
130 static const struct app_pktq_hwq_out_params default_hwq_out_params = {
145 .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS |
146 ETH_TXQ_FLAGS_NOOFFLOADS,
147 .tx_deferred_start = 0,
151 static const struct app_pktq_swq_params default_swq_params = {
165 .mempool_direct_id = 0,
166 .mempool_indirect_id = 0,
169 struct app_pktq_tm_params default_tm_params = {
171 .file_name = "./config/tm_profile.cfg",
176 struct app_pktq_source_params default_source_params = {
182 struct app_pktq_sink_params default_sink_params = {
186 struct app_msgq_params default_msgq_params = {
192 struct app_pipeline_params default_pipeline_params = {
205 static const char app_usage[] =
206 "Usage: %s [-f CONFIG_FILE] [-s SCRIPT_FILE] -p PORT_MASK "
207 "[-l LOG_LEVEL] [--preproc PREPROCESSOR] [--preproc-args ARGS]\n"
210 "\t-f CONFIG_FILE: Default config file is %s\n"
211 "\t-p PORT_MASK: Mask of NIC port IDs in hexadecimal format\n"
212 "\t-s SCRIPT_FILE: No CLI script file is run when not specified\n"
213 "\t-l LOG_LEVEL: 0 = NONE, 1 = HIGH PRIO (default), 2 = LOW PRIO\n"
214 "\t--preproc PREPROCESSOR: Configuration file pre-processor\n"
215 "\t--preproc-args ARGS: Arguments to be passed to pre-processor\n"
219 app_print_usage(char *prgname)
221 rte_exit(0, app_usage, prgname, app_params_default.config_file);
224 #define skip_white_spaces(pos) \
226 __typeof__(pos) _p = (pos); \
227 for ( ; isspace(*_p); _p++); \
231 #define PARSER_IMPLICIT_PARAM_ADD_CHECK(result, section_name) \
233 APP_CHECK((result != -EINVAL), \
234 "CFG: [%s] name too long", section_name); \
235 APP_CHECK(result != -ENOMEM, \
236 "CFG: [%s] too much sections", section_name); \
237 APP_CHECK(result >= 0, \
238 "CFG: [%s] Unknown error while adding '%s'", \
239 section_name, section_name); \
242 #define PARSER_PARAM_ADD_CHECK(result, params_array, section_name) \
244 APP_CHECK((result != -EINVAL), \
245 "CFG: [%s] name too long", section_name); \
246 APP_CHECK((result != -ENOMEM), \
247 "CFG: [%s] too much sections", section_name); \
248 APP_CHECK(((result >= 0) && (params_array)[result].parsed == 0),\
249 "CFG: [%s] duplicate section", section_name); \
250 APP_CHECK((result >= 0), \
251 "CFG: [%s] Unknown error while adding '%s'", \
252 section_name, section_name); \
256 parser_read_arg_bool(const char *p)
258 p = skip_white_spaces(p);
259 int result = -EINVAL;
261 if (((p[0] == 'y') && (p[1] == 'e') && (p[2] == 's')) ||
262 ((p[0] == 'Y') && (p[1] == 'E') && (p[2] == 'S'))) {
267 if (((p[0] == 'o') && (p[1] == 'n')) ||
268 ((p[0] == 'O') && (p[1] == 'N'))) {
273 if (((p[0] == 'n') && (p[1] == 'o')) ||
274 ((p[0] == 'N') && (p[1] == 'O'))) {
279 if (((p[0] == 'o') && (p[1] == 'f') && (p[2] == 'f')) ||
280 ((p[0] == 'O') && (p[1] == 'F') && (p[2] == 'F'))) {
285 p = skip_white_spaces(p);
293 #define PARSE_ERROR(exp, section, entry) \
294 APP_CHECK(exp, "Parse error in section \"%s\": entry \"%s\"\n", section, entry)
296 #define PARSE_ERROR_MALLOC(exp) \
297 APP_CHECK(exp, "Parse error: no free memory\n")
299 #define PARSE_ERROR_SECTION(exp, section) \
300 APP_CHECK(exp, "Parse error in section \"%s\"", section)
302 #define PARSE_ERROR_SECTION_NO_ENTRIES(exp, section) \
303 APP_CHECK(exp, "Parse error in section \"%s\": no entries\n", section)
305 #define PARSE_WARNING_IGNORED(exp, section, entry) \
308 fprintf(stderr, "Parse warning in section \"%s\": " \
309 "entry \"%s\" is ignored\n", section, entry); \
312 #define PARSE_ERROR_INVALID(exp, section, entry) \
313 APP_CHECK(exp, "Parse error in section \"%s\": unrecognized entry \"%s\"\n",\
316 #define PARSE_ERROR_DUPLICATE(exp, section, entry) \
317 APP_CHECK(exp, "Parse error in section \"%s\": duplicate entry \"%s\"\n",\
321 parser_read_uint64(uint64_t *value, const char *p)
326 p = skip_white_spaces(p);
330 val = strtoul(p, &next, 10);
352 p = skip_white_spaces(p);
361 parser_read_uint32(uint32_t *value, const char *p)
364 int ret = parser_read_uint64(&val, p);
368 else if (val > UINT32_MAX)
376 parse_pipeline_core(uint32_t *socket,
384 uint32_t s = 0, c = 0, h = 0, val;
385 uint8_t s_parsed = 0, c_parsed = 0, h_parsed = 0;
386 const char *next = skip_white_spaces(entry);
389 /* Expect <CORE> or [sX][cY][h]. At least one parameter is required. */
390 while (*next != '\0') {
391 /* If everything parsed nothing should left */
392 if (s_parsed && c_parsed && h_parsed)
399 if (s_parsed || c_parsed || h_parsed)
406 if (c_parsed || h_parsed)
419 /* If it start from digit it must be only core id. */
420 if (!isdigit(*next) || s_parsed || c_parsed || h_parsed)
426 for (num_len = 0; *next != '\0'; next++, num_len++) {
427 if (num_len == RTE_DIM(num))
433 num[num_len] = *next;
436 if (num_len == 0 && type != 'h' && type != 'H')
439 if (num_len != 0 && (type == 'h' || type == 'H'))
443 val = strtol(num, NULL, 10);
472 case '0': case '1': case '2': case '3': case '4': case '5':
473 case '6': case '7': case '8': case '9':
475 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
477 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
485 parse_hex_string(char *src, uint8_t *dst, uint32_t *size)
490 /* Check input parameters */
498 if (((len & 3) != 0) ||
503 for (c = src; *c != 0; c++) {
504 if ((((*c) >= '0') && ((*c) <= '9')) ||
505 (((*c) >= 'A') && ((*c) <= 'F')) ||
506 (((*c) >= 'a') && ((*c) <= 'f')))
512 /* Convert chars to bytes */
513 for (i = 0; i < *size; i++)
514 dst[i] = get_hex_val(src[2 * i]) * 16 +
515 get_hex_val(src[2 * i + 1]);
521 skip_digits(const char *src)
525 for (i = 0; isdigit(src[i]); i++);
531 validate_name(const char *name, const char *prefix, int num)
535 for (i = 0; (name[i] != '\0') && (prefix[i] != '\0'); i++) {
536 if (name[i] != prefix[i])
540 if (prefix[i] != '\0')
551 j = skip_digits(&name[i]);
553 if ((j == 0) || (name[i] != '.'))
559 j = skip_digits(&name[i]);
561 if ((j == 0) || (name[i] != '\0'))
569 parse_eal(struct app_params *app,
570 const char *section_name,
571 struct rte_cfgfile *cfg)
573 struct app_eal_params *p = &app->eal_params;
574 struct rte_cfgfile_entry *entries;
577 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
578 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
580 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
581 PARSE_ERROR_MALLOC(entries != NULL);
583 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
585 for (i = 0; i < n_entries; i++) {
586 struct rte_cfgfile_entry *entry = &entries[i];
589 if (strcmp(entry->name, "c") == 0) {
590 PARSE_WARNING_IGNORED(0, section_name, entry->name);
595 if (strcmp(entry->name, "l") == 0) {
596 PARSE_WARNING_IGNORED(0, section_name, entry->name);
601 if (strcmp(entry->name, "lcores") == 0) {
602 PARSE_ERROR_DUPLICATE((p->coremap == NULL),
605 p->coremap = strdup(entry->value);
610 if (strcmp(entry->name, "master_lcore") == 0) {
613 PARSE_ERROR_DUPLICATE((p->master_lcore_present == 0),
616 p->master_lcore_present = 1;
618 status = parser_read_uint32(&p->master_lcore,
620 PARSE_ERROR((status == 0), section_name, entry->name);
625 if (strcmp(entry->name, "n") == 0) {
628 PARSE_ERROR_DUPLICATE((p->channels_present == 0),
631 p->channels_present = 1;
633 status = parser_read_uint32(&p->channels, entry->value);
634 PARSE_ERROR((status == 0), section_name, entry->name);
639 if (strcmp(entry->name, "m") == 0) {
642 PARSE_ERROR_DUPLICATE((p->memory_present == 0),
645 p->memory_present = 1;
647 status = parser_read_uint32(&p->memory, entry->value);
648 PARSE_ERROR((status == 0), section_name, entry->name);
653 if (strcmp(entry->name, "r") == 0) {
656 PARSE_ERROR_DUPLICATE((p->ranks_present == 0),
659 p->ranks_present = 1;
661 status = parser_read_uint32(&p->ranks, entry->value);
662 PARSE_ERROR((status == 0), section_name, entry->name);
667 if ((strcmp(entry->name, "pci_blacklist") == 0) ||
668 (strcmp(entry->name, "b") == 0)) {
669 PARSE_ERROR_DUPLICATE((p->pci_blacklist == NULL),
672 p->pci_blacklist = strdup(entry->value);
677 if ((strcmp(entry->name, "pci_whitelist") == 0) ||
678 (strcmp(entry->name, "w") == 0)) {
679 PARSE_ERROR_DUPLICATE((p->pci_whitelist == NULL),
682 p->pci_whitelist = strdup(entry->value);
687 if (strcmp(entry->name, "vdev") == 0) {
688 PARSE_ERROR_DUPLICATE((p->vdev == NULL),
691 p->vdev = strdup(entry->value);
696 if (strcmp(entry->name, "vmware_tsc_map") == 0) {
699 PARSE_ERROR_DUPLICATE((p->vmware_tsc_map_present == 0),
702 p->vmware_tsc_map_present = 1;
704 val = parser_read_arg_bool(entry->value);
705 PARSE_ERROR((val >= 0), section_name, entry->name);
706 p->vmware_tsc_map = val;
711 if (strcmp(entry->name, "proc_type") == 0) {
712 PARSE_ERROR_DUPLICATE((p->proc_type == NULL),
715 p->proc_type = strdup(entry->value);
720 if (strcmp(entry->name, "syslog") == 0) {
721 PARSE_ERROR_DUPLICATE((p->syslog == NULL),
724 p->syslog = strdup(entry->value);
729 if (strcmp(entry->name, "log_level") == 0) {
732 PARSE_ERROR_DUPLICATE((p->log_level_present == 0),
735 p->log_level_present = 1;
737 status = parser_read_uint32(&p->log_level,
739 PARSE_ERROR((status == 0), section_name, entry->name);
744 if (strcmp(entry->name, "v") == 0) {
747 PARSE_ERROR_DUPLICATE((p->version_present == 0),
750 p->version_present = 1;
752 val = parser_read_arg_bool(entry->value);
753 PARSE_ERROR((val >= 0), section_name, entry->name);
759 if ((strcmp(entry->name, "help") == 0) ||
760 (strcmp(entry->name, "h") == 0)) {
763 PARSE_ERROR_DUPLICATE((p->help_present == 0),
768 val = parser_read_arg_bool(entry->value);
769 PARSE_ERROR((val >= 0), section_name, entry->name);
775 if (strcmp(entry->name, "no_huge") == 0) {
778 PARSE_ERROR_DUPLICATE((p->no_huge_present == 0),
781 p->no_huge_present = 1;
783 val = parser_read_arg_bool(entry->value);
784 PARSE_ERROR((val >= 0), section_name, entry->name);
790 if (strcmp(entry->name, "no_pci") == 0) {
793 PARSE_ERROR_DUPLICATE((p->no_pci_present == 0),
796 p->no_pci_present = 1;
798 val = parser_read_arg_bool(entry->value);
799 PARSE_ERROR((val >= 0), section_name, entry->name);
805 if (strcmp(entry->name, "no_hpet") == 0) {
808 PARSE_ERROR_DUPLICATE((p->no_hpet_present == 0),
811 p->no_hpet_present = 1;
813 val = parser_read_arg_bool(entry->value);
814 PARSE_ERROR((val >= 0), section_name, entry->name);
820 if (strcmp(entry->name, "no_shconf") == 0) {
823 PARSE_ERROR_DUPLICATE((p->no_shconf_present == 0),
826 p->no_shconf_present = 1;
828 val = parser_read_arg_bool(entry->value);
829 PARSE_ERROR((val >= 0), section_name, entry->name);
835 if (strcmp(entry->name, "d") == 0) {
836 PARSE_ERROR_DUPLICATE((p->add_driver == NULL),
839 p->add_driver = strdup(entry->value);
844 if (strcmp(entry->name, "socket_mem") == 0) {
845 PARSE_ERROR_DUPLICATE((p->socket_mem == NULL),
848 p->socket_mem = strdup(entry->value);
853 if (strcmp(entry->name, "huge_dir") == 0) {
854 PARSE_ERROR_DUPLICATE((p->huge_dir == NULL),
857 p->huge_dir = strdup(entry->value);
862 if (strcmp(entry->name, "file_prefix") == 0) {
863 PARSE_ERROR_DUPLICATE((p->file_prefix == NULL),
866 p->file_prefix = strdup(entry->value);
871 if (strcmp(entry->name, "base_virtaddr") == 0) {
872 PARSE_ERROR_DUPLICATE((p->base_virtaddr == NULL),
875 p->base_virtaddr = strdup(entry->value);
880 if (strcmp(entry->name, "create_uio_dev") == 0) {
883 PARSE_ERROR_DUPLICATE((p->create_uio_dev_present == 0),
886 p->create_uio_dev_present = 1;
888 val = parser_read_arg_bool(entry->value);
889 PARSE_ERROR((val >= 0), section_name, entry->name);
890 p->create_uio_dev = val;
895 if (strcmp(entry->name, "vfio_intr") == 0) {
896 PARSE_ERROR_DUPLICATE((p->vfio_intr == NULL),
899 p->vfio_intr = strdup(entry->value);
904 if (strcmp(entry->name, "xen_dom0") == 0) {
907 PARSE_ERROR_DUPLICATE((p->xen_dom0_present == 0),
910 p->xen_dom0_present = 1;
912 val = parser_read_arg_bool(entry->value);
913 PARSE_ERROR((val >= 0), section_name, entry->name);
919 PARSE_ERROR_INVALID(0, section_name, entry->name);
926 parse_pipeline_pktq_in(struct app_params *app,
927 struct app_pipeline_params *p,
930 const char *next = value;
932 char name[APP_PARAM_NAME_SIZE];
935 while (*next != '\0') {
936 enum app_pktq_in_type type;
939 end = strchr(next, ' ');
941 name_len = strlen(next);
943 name_len = end - next;
945 if (name_len == 0 || name_len == sizeof(name))
948 strncpy(name, next, name_len);
949 name[name_len] = '\0';
954 if (validate_name(name, "RXQ", 2) == 0) {
955 type = APP_PKTQ_IN_HWQ;
956 id = APP_PARAM_ADD(app->hwq_in_params, name);
957 } else if (validate_name(name, "SWQ", 1) == 0) {
958 type = APP_PKTQ_IN_SWQ;
959 id = APP_PARAM_ADD(app->swq_params, name);
960 } else if (validate_name(name, "TM", 1) == 0) {
961 type = APP_PKTQ_IN_TM;
962 id = APP_PARAM_ADD(app->tm_params, name);
963 } else if (validate_name(name, "SOURCE", 1) == 0) {
964 type = APP_PKTQ_IN_SOURCE;
965 id = APP_PARAM_ADD(app->source_params, name);
972 p->pktq_in[p->n_pktq_in].type = type;
973 p->pktq_in[p->n_pktq_in].id = (uint32_t) id;
981 parse_pipeline_pktq_out(struct app_params *app,
982 struct app_pipeline_params *p,
985 const char *next = value;
987 char name[APP_PARAM_NAME_SIZE];
990 while (*next != '\0') {
991 enum app_pktq_out_type type;
994 end = strchr(next, ' ');
996 name_len = strlen(next);
998 name_len = end - next;
1000 if (name_len == 0 || name_len == sizeof(name))
1003 strncpy(name, next, name_len);
1004 name[name_len] = '\0';
1009 if (validate_name(name, "TXQ", 2) == 0) {
1010 type = APP_PKTQ_OUT_HWQ;
1011 id = APP_PARAM_ADD(app->hwq_out_params, name);
1012 } else if (validate_name(name, "SWQ", 1) == 0) {
1013 type = APP_PKTQ_OUT_SWQ;
1014 id = APP_PARAM_ADD(app->swq_params, name);
1015 } else if (validate_name(name, "TM", 1) == 0) {
1016 type = APP_PKTQ_OUT_TM;
1017 id = APP_PARAM_ADD(app->tm_params, name);
1018 } else if (validate_name(name, "SINK", 1) == 0) {
1019 type = APP_PKTQ_OUT_SINK;
1020 id = APP_PARAM_ADD(app->sink_params, name);
1027 p->pktq_out[p->n_pktq_out].type = type;
1028 p->pktq_out[p->n_pktq_out].id = id;
1036 parse_pipeline_msgq_in(struct app_params *app,
1037 struct app_pipeline_params *p,
1040 const char *next = value;
1042 char name[APP_PARAM_NAME_SIZE];
1046 while (*next != '\0') {
1047 end = strchr(next, ' ');
1049 name_len = strlen(next);
1051 name_len = end - next;
1053 if (name_len == 0 || name_len == sizeof(name))
1056 strncpy(name, next, name_len);
1057 name[name_len] = '\0';
1062 if (validate_name(name, "MSGQ", 1) != 0)
1065 idx = APP_PARAM_ADD(app->msgq_params, name);
1069 p->msgq_in[p->n_msgq_in] = idx;
1077 parse_pipeline_msgq_out(struct app_params *app,
1078 struct app_pipeline_params *p,
1081 const char *next = value;
1083 char name[APP_PARAM_NAME_SIZE];
1087 while (*next != '\0') {
1088 end = strchr(next, ' ');
1090 name_len = strlen(next);
1092 name_len = end - next;
1094 if (name_len == 0 || name_len == sizeof(name))
1097 strncpy(name, next, name_len);
1098 name[name_len] = '\0';
1103 if (validate_name(name, "MSGQ", 1) != 0)
1106 idx = APP_PARAM_ADD(app->msgq_params, name);
1110 p->msgq_out[p->n_msgq_out] = idx;
1119 parse_pipeline(struct app_params *app,
1120 const char *section_name,
1121 struct rte_cfgfile *cfg)
1123 char name[CFG_NAME_LEN];
1124 struct app_pipeline_params *param;
1125 struct rte_cfgfile_entry *entries;
1127 int n_entries, ret, i;
1129 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1130 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1132 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1133 PARSE_ERROR_MALLOC(entries != NULL);
1135 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1137 param_idx = APP_PARAM_ADD(app->pipeline_params, section_name);
1138 PARSER_PARAM_ADD_CHECK(param_idx, app->pipeline_params, section_name);
1140 param = &app->pipeline_params[param_idx];
1143 for (i = 0; i < n_entries; i++) {
1144 struct rte_cfgfile_entry *ent = &entries[i];
1146 if (strcmp(ent->name, "type") == 0) {
1147 ret = snprintf(param->type,
1148 RTE_DIM(param->type),
1151 if ((ret > 0) && (ret < (int)RTE_DIM(param->type)))
1155 } else if (strcmp(ent->name, "core") == 0)
1156 ret = parse_pipeline_core(¶m->socket_id,
1158 ¶m->hyper_th_id,
1160 else if (strcmp(ent->name, "pktq_in") == 0)
1161 ret = parse_pipeline_pktq_in(app, param, ent->value);
1162 else if (strcmp(ent->name, "pktq_out") == 0)
1163 ret = parse_pipeline_pktq_out(app, param, ent->value);
1164 else if (strcmp(ent->name, "msgq_in") == 0)
1165 ret = parse_pipeline_msgq_in(app, param, ent->value);
1166 else if (strcmp(ent->name, "msgq_out") == 0)
1167 ret = parse_pipeline_msgq_out(app, param, ent->value);
1168 else if (strcmp(ent->name, "timer_period") == 0)
1169 ret = parser_read_uint32(¶m->timer_period,
1172 APP_CHECK((param->n_args < APP_MAX_PIPELINE_ARGS),
1173 "CFG: [%s] out of memory",
1176 param->args_name[param->n_args] = strdup(ent->name);
1177 param->args_value[param->n_args] = strdup(ent->value);
1179 APP_CHECK((param->args_name[param->n_args] != NULL) &&
1180 (param->args_value[param->n_args] != NULL),
1181 "CFG: [%s] out of memory",
1189 "CFG: [%s] entry '%s': Invalid value '%s'\n",
1195 snprintf(name, sizeof(name), "MSGQ-REQ-%s", section_name);
1196 param_idx = APP_PARAM_ADD(app->msgq_params, name);
1197 PARSER_IMPLICIT_PARAM_ADD_CHECK(param_idx, name);
1198 app->msgq_params[param_idx].cpu_socket_id = param->socket_id;
1199 param->msgq_in[param->n_msgq_in++] = param_idx;
1201 snprintf(name, sizeof(name), "MSGQ-RSP-%s", section_name);
1202 param_idx = APP_PARAM_ADD(app->msgq_params, name);
1203 PARSER_IMPLICIT_PARAM_ADD_CHECK(param_idx, name);
1204 app->msgq_params[param_idx].cpu_socket_id = param->socket_id;
1205 param->msgq_out[param->n_msgq_out++] = param_idx;
1207 snprintf(name, sizeof(name), "MSGQ-REQ-CORE-s%" PRIu32 "c%" PRIu32 "%s",
1210 (param->hyper_th_id) ? "h" : "");
1211 param_idx = APP_PARAM_ADD(app->msgq_params, name);
1212 PARSER_IMPLICIT_PARAM_ADD_CHECK(param_idx, name);
1213 app->msgq_params[param_idx].cpu_socket_id = param->socket_id;
1215 snprintf(name, sizeof(name), "MSGQ-RSP-CORE-s%" PRIu32 "c%" PRIu32 "%s",
1218 (param->hyper_th_id) ? "h" : "");
1219 param_idx = APP_PARAM_ADD(app->msgq_params, name);
1220 PARSER_IMPLICIT_PARAM_ADD_CHECK(param_idx, name);
1221 app->msgq_params[param_idx].cpu_socket_id = param->socket_id;
1227 parse_mempool(struct app_params *app,
1228 const char *section_name,
1229 struct rte_cfgfile *cfg)
1231 struct app_mempool_params *param;
1232 struct rte_cfgfile_entry *entries;
1234 int n_entries, ret, i;
1236 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1237 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1239 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1240 PARSE_ERROR_MALLOC(entries != NULL);
1242 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1244 param_idx = APP_PARAM_ADD(app->mempool_params, section_name);
1245 PARSER_PARAM_ADD_CHECK(param_idx, app->mempool_params, section_name);
1247 param = &app->mempool_params[param_idx];
1250 for (i = 0; i < n_entries; i++) {
1251 struct rte_cfgfile_entry *ent = &entries[i];
1254 if (strcmp(ent->name, "buffer_size") == 0)
1255 ret = parser_read_uint32(¶m->buffer_size,
1257 else if (strcmp(ent->name, "pool_size") == 0)
1258 ret = parser_read_uint32(¶m->pool_size,
1260 else if (strcmp(ent->name, "cache_size") == 0)
1261 ret = parser_read_uint32(¶m->cache_size,
1263 else if (strcmp(ent->name, "cpu") == 0)
1264 ret = parser_read_uint32(¶m->cpu_socket_id,
1267 APP_CHECK(ret != -ESRCH,
1268 "CFG: [%s] entry '%s': unknown entry\n",
1272 "CFG: [%s] entry '%s': Invalid value '%s'\n",
1282 parse_link(struct app_params *app,
1283 const char *section_name,
1284 struct rte_cfgfile *cfg)
1286 struct app_link_params *param;
1287 struct rte_cfgfile_entry *entries;
1288 int n_entries, ret, i;
1291 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1292 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1294 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1295 PARSE_ERROR_MALLOC(entries != NULL);
1297 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1299 param_idx = APP_PARAM_ADD(app->link_params, section_name);
1300 PARSER_PARAM_ADD_CHECK(param_idx, app->link_params, section_name);
1302 param = &app->link_params[param_idx];
1305 for (i = 0; i < n_entries; i++) {
1306 struct rte_cfgfile_entry *ent = &entries[i];
1309 if (strcmp(ent->name, "promisc") == 0) {
1310 ret = parser_read_arg_bool(ent->value);
1312 param->promisc = ret;
1315 } else if (strcmp(ent->name, "arp_q") == 0)
1316 ret = parser_read_uint32(¶m->arp_q,
1318 else if (strcmp(ent->name, "tcp_syn_q") == 0)
1319 ret = parser_read_uint32(¶m->tcp_syn_local_q,
1321 else if (strcmp(ent->name, "ip_local_q") == 0)
1322 ret = parser_read_uint32(¶m->ip_local_q,
1324 else if (strcmp(ent->name, "tcp_local_q") == 0)
1325 ret = parser_read_uint32(¶m->tcp_local_q,
1327 else if (strcmp(ent->name, "udp_local_q") == 0)
1328 ret = parser_read_uint32(¶m->udp_local_q,
1330 else if (strcmp(ent->name, "sctp_local_q") == 0)
1331 ret = parser_read_uint32(¶m->sctp_local_q,
1334 APP_CHECK(ret != -ESRCH,
1335 "CFG: [%s] entry '%s': unknown entry\n",
1339 "CFG: [%s] entry '%s': Invalid value '%s'\n",
1349 parse_rxq(struct app_params *app,
1350 const char *section_name,
1351 struct rte_cfgfile *cfg)
1353 struct app_pktq_hwq_in_params *param;
1354 struct rte_cfgfile_entry *entries;
1355 int n_entries, ret, i;
1358 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1359 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1361 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1362 PARSE_ERROR_MALLOC(entries != NULL);
1364 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1366 param_idx = APP_PARAM_ADD(app->hwq_in_params, section_name);
1367 PARSER_PARAM_ADD_CHECK(param_idx, app->hwq_in_params, section_name);
1369 param = &app->hwq_in_params[param_idx];
1372 for (i = 0; i < n_entries; i++) {
1373 struct rte_cfgfile_entry *ent = &entries[i];
1376 if (strcmp(ent->name, "mempool") == 0) {
1377 int status = validate_name(ent->value, "MEMPOOL", 1);
1380 APP_CHECK((status == 0),
1381 "CFG: [%s] entry '%s': invalid mempool\n",
1385 idx = APP_PARAM_ADD(app->mempool_params, ent->value);
1386 PARSER_IMPLICIT_PARAM_ADD_CHECK(idx, section_name);
1387 param->mempool_id = idx;
1389 } else if (strcmp(ent->name, "size") == 0)
1390 ret = parser_read_uint32(¶m->size,
1392 else if (strcmp(ent->name, "burst") == 0)
1393 ret = parser_read_uint32(¶m->burst,
1396 APP_CHECK(ret != -ESRCH,
1397 "CFG: [%s] entry '%s': unknown entry\n",
1401 "CFG: [%s] entry '%s': Invalid value '%s'\n",
1411 parse_txq(struct app_params *app,
1412 const char *section_name,
1413 struct rte_cfgfile *cfg)
1415 struct app_pktq_hwq_out_params *param;
1416 struct rte_cfgfile_entry *entries;
1417 int n_entries, ret, i;
1420 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1421 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1423 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1424 PARSE_ERROR_MALLOC(entries != NULL);
1426 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1428 param_idx = APP_PARAM_ADD(app->hwq_out_params, section_name);
1429 PARSER_PARAM_ADD_CHECK(param_idx, app->hwq_out_params, section_name);
1431 param = &app->hwq_out_params[param_idx];
1434 for (i = 0; i < n_entries; i++) {
1435 struct rte_cfgfile_entry *ent = &entries[i];
1438 if (strcmp(ent->name, "size") == 0)
1439 ret = parser_read_uint32(¶m->size, ent->value);
1440 else if (strcmp(ent->name, "burst") == 0)
1441 ret = parser_read_uint32(¶m->burst, ent->value);
1442 else if (strcmp(ent->name, "dropless") == 0) {
1443 ret = parser_read_arg_bool(ent->value);
1445 param->dropless = ret;
1450 APP_CHECK(ret != -ESRCH,
1451 "CFG: [%s] entry '%s': unknown entry\n",
1455 "CFG: [%s] entry '%s': Invalid value '%s'\n",
1465 parse_swq(struct app_params *app,
1466 const char *section_name,
1467 struct rte_cfgfile *cfg)
1469 struct app_pktq_swq_params *param;
1470 struct rte_cfgfile_entry *entries;
1471 int n_entries, ret, i;
1472 unsigned frag_entries = 0;
1475 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1476 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1478 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1479 PARSE_ERROR_MALLOC(entries != NULL);
1481 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1483 param_idx = APP_PARAM_ADD(app->swq_params, section_name);
1484 PARSER_PARAM_ADD_CHECK(param_idx, app->swq_params, section_name);
1486 param = &app->swq_params[param_idx];
1489 for (i = 0; i < n_entries; i++) {
1490 struct rte_cfgfile_entry *ent = &entries[i];
1493 if (strcmp(ent->name, "size") == 0)
1494 ret = parser_read_uint32(¶m->size,
1496 else if (strcmp(ent->name, "burst_read") == 0)
1497 ret = parser_read_uint32(¶m->burst_read,
1499 else if (strcmp(ent->name, "burst_write") == 0)
1500 ret = parser_read_uint32(¶m->burst_write,
1502 else if (strcmp(ent->name, "dropless") == 0) {
1503 ret = parser_read_arg_bool(ent->value);
1505 param->dropless = ret;
1508 } else if (strcmp(ent->name, "n_retries") == 0)
1509 ret = parser_read_uint64(¶m->n_retries,
1511 else if (strcmp(ent->name, "cpu") == 0)
1512 ret = parser_read_uint32(¶m->cpu_socket_id,
1514 else if (strcmp(ent->name, "ipv4_frag") == 0) {
1515 ret = parser_read_arg_bool(ent->value);
1517 param->ipv4_frag = ret;
1518 if (param->mtu == 0)
1522 } else if (strcmp(ent->name, "ipv6_frag") == 0) {
1523 ret = parser_read_arg_bool(ent->value);
1525 param->ipv6_frag = ret;
1526 if (param->mtu == 0)
1530 } else if (strcmp(ent->name, "ipv4_ras") == 0) {
1531 ret = parser_read_arg_bool(ent->value);
1533 param->ipv4_ras = ret;
1536 } else if (strcmp(ent->name, "ipv6_ras") == 0) {
1537 ret = parser_read_arg_bool(ent->value);
1539 param->ipv6_ras = ret;
1542 } else if (strcmp(ent->name, "mtu") == 0) {
1544 ret = parser_read_uint32(¶m->mtu,
1546 } else if (strcmp(ent->name, "metadata_size") == 0) {
1548 ret = parser_read_uint32(¶m->metadata_size,
1550 } else if (strcmp(ent->name, "mempool_direct") == 0) {
1551 int status = validate_name(ent->value, "MEMPOOL", 1);
1554 APP_CHECK((status == 0),
1555 "CFG: [%s] entry '%s': invalid mempool\n",
1559 idx = APP_PARAM_ADD(app->mempool_params, ent->value);
1560 PARSER_IMPLICIT_PARAM_ADD_CHECK(idx, section_name);
1561 param->mempool_direct_id = idx;
1564 } else if (strcmp(ent->name, "mempool_indirect") == 0) {
1565 int status = validate_name(ent->value, "MEMPOOL", 1);
1568 APP_CHECK((status == 0),
1569 "CFG: [%s] entry '%s': invalid mempool\n",
1573 idx = APP_PARAM_ADD(app->mempool_params, ent->value);
1574 PARSER_IMPLICIT_PARAM_ADD_CHECK(idx, section_name);
1575 param->mempool_indirect_id = idx;
1580 APP_CHECK(ret != -ESRCH,
1581 "CFG: [%s] entry '%s': unknown entry\n",
1585 "CFG: [%s] entry '%s': Invalid value '%s'\n",
1591 if (frag_entries == 1) {
1592 APP_CHECK(((param->ipv4_frag == 1) || (param->ipv6_frag == 1)),
1593 "CFG: [%s] ipv4/ipv6 frag is off : unsupported entries on this"
1602 parse_tm(struct app_params *app,
1603 const char *section_name,
1604 struct rte_cfgfile *cfg)
1606 struct app_pktq_tm_params *param;
1607 struct rte_cfgfile_entry *entries;
1608 int n_entries, ret, i;
1611 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1612 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1614 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1615 PARSE_ERROR_MALLOC(entries != NULL);
1617 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1619 param_idx = APP_PARAM_ADD(app->tm_params, section_name);
1620 PARSER_PARAM_ADD_CHECK(param_idx, app->tm_params, section_name);
1622 param = &app->tm_params[param_idx];
1625 for (i = 0; i < n_entries; i++) {
1626 struct rte_cfgfile_entry *ent = &entries[i];
1629 if (strcmp(ent->name, "cfg") == 0) {
1630 param->file_name = strdup(ent->value);
1631 if (param->file_name == NULL)
1635 } else if (strcmp(ent->name, "burst_read") == 0)
1636 ret = parser_read_uint32(¶m->burst_read,
1638 else if (strcmp(ent->name, "burst_write") == 0)
1639 ret = parser_read_uint32(¶m->burst_write,
1642 APP_CHECK(ret != -ESRCH,
1643 "CFG: [%s] entry '%s': unknown entry\n",
1646 APP_CHECK(ret != -EBADF,
1647 "CFG: [%s] entry '%s': TM cfg parse error '%s'\n",
1652 "CFG: [%s] entry '%s': Invalid value '%s'\n",
1662 parse_source(struct app_params *app,
1663 const char *section_name,
1664 struct rte_cfgfile *cfg)
1666 struct app_pktq_source_params *param;
1667 struct rte_cfgfile_entry *entries;
1668 int n_entries, ret, i;
1671 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1672 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1674 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1675 PARSE_ERROR_MALLOC(entries != NULL);
1677 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1679 param_idx = APP_PARAM_ADD(app->source_params, section_name);
1680 PARSER_PARAM_ADD_CHECK(param_idx, app->source_params, section_name);
1682 param = &app->source_params[param_idx];
1685 for (i = 0; i < n_entries; i++) {
1686 struct rte_cfgfile_entry *ent = &entries[i];
1689 if (strcmp(ent->name, "mempool") == 0) {
1690 int status = validate_name(ent->value, "MEMPOOL", 1);
1693 APP_CHECK((status == 0),
1694 "CFG: [%s] entry '%s': invalid mempool\n",
1698 idx = APP_PARAM_ADD(app->mempool_params, ent->value);
1699 PARSER_IMPLICIT_PARAM_ADD_CHECK(idx, section_name);
1700 param->mempool_id = idx;
1702 } else if (strcmp(ent->name, "burst") == 0)
1703 ret = parser_read_uint32(¶m->burst, ent->value);
1705 APP_CHECK(ret != -ESRCH,
1706 "CFG: [%s] entry '%s': unknown entry\n",
1710 "CFG: [%s] entry '%s': Invalid value '%s'\n",
1720 parse_msgq_req_pipeline(struct app_params *app,
1721 const char *section_name,
1722 struct rte_cfgfile *cfg)
1724 struct app_msgq_params *param;
1725 struct rte_cfgfile_entry *entries;
1726 int n_entries, ret, i;
1729 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1730 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1732 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1733 PARSE_ERROR_MALLOC(entries != NULL);
1735 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1737 param_idx = APP_PARAM_ADD(app->msgq_params, section_name);
1738 PARSER_PARAM_ADD_CHECK(param_idx, app->msgq_params, section_name);
1740 param = &app->msgq_params[param_idx];
1743 for (i = 0; i < n_entries; i++) {
1744 struct rte_cfgfile_entry *ent = &entries[i];
1747 if (strcmp(ent->name, "size") == 0)
1748 ret = parser_read_uint32(¶m->size, ent->value);
1750 APP_CHECK(ret != -ESRCH,
1751 "CFG: [%s] entry '%s': unknown entry\n",
1755 "CFG: [%s] entry '%s': Invalid value '%s'\n",
1765 parse_msgq_rsp_pipeline(struct app_params *app,
1766 const char *section_name,
1767 struct rte_cfgfile *cfg)
1769 struct app_msgq_params *param;
1770 struct rte_cfgfile_entry *entries;
1771 int n_entries, ret, i;
1774 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1775 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1777 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1778 PARSE_ERROR_MALLOC(entries != NULL);
1780 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1782 param_idx = APP_PARAM_ADD(app->msgq_params, section_name);
1783 PARSER_PARAM_ADD_CHECK(param_idx, app->msgq_params, section_name);
1785 param = &app->msgq_params[param_idx];
1788 for (i = 0; i < n_entries; i++) {
1789 struct rte_cfgfile_entry *ent = &entries[i];
1792 if (strcmp(ent->name, "size") == 0)
1793 ret = parser_read_uint32(¶m->size, ent->value);
1795 APP_CHECK(ret != -ESRCH,
1796 "CFG: [%s] entry '%s': unknown entry\n",
1800 "CFG: [%s] entry '%s': Invalid value '%s'\n",
1810 parse_msgq(struct app_params *app,
1811 const char *section_name,
1812 struct rte_cfgfile *cfg)
1814 struct app_msgq_params *param;
1815 struct rte_cfgfile_entry *entries;
1816 int n_entries, ret, i;
1819 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1820 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1822 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1823 PARSE_ERROR_MALLOC(entries != NULL);
1825 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1827 param_idx = APP_PARAM_ADD(app->msgq_params, section_name);
1828 PARSER_PARAM_ADD_CHECK(param_idx, app->msgq_params, section_name);
1830 param = &app->msgq_params[param_idx];
1833 for (i = 0; i < n_entries; i++) {
1834 struct rte_cfgfile_entry *ent = &entries[i];
1837 if (strcmp(ent->name, "size") == 0)
1838 ret = parser_read_uint32(¶m->size,
1840 else if (strcmp(ent->name, "cpu") == 0)
1841 ret = parser_read_uint32(¶m->cpu_socket_id,
1844 APP_CHECK(ret != -ESRCH,
1845 "CFG: [%s] entry '%s': unknown entry\n",
1849 "CFG: [%s] entry '%s': Invalid value '%s'\n",
1858 typedef void (*config_section_load)(struct app_params *p,
1859 const char *section_name,
1860 struct rte_cfgfile *cfg);
1862 struct config_section {
1863 const char prefix[CFG_NAME_LEN];
1865 config_section_load load;
1868 static const struct config_section cfg_file_scheme[] = {
1869 {"EAL", 0, parse_eal},
1870 {"PIPELINE", 1, parse_pipeline},
1871 {"MEMPOOL", 1, parse_mempool},
1872 {"LINK", 1, parse_link},
1873 {"RXQ", 2, parse_rxq},
1874 {"TXQ", 2, parse_txq},
1875 {"SWQ", 1, parse_swq},
1876 {"TM", 1, parse_tm},
1877 {"SOURCE", 1, parse_source},
1878 {"MSGQ-REQ-PIPELINE", 1, parse_msgq_req_pipeline},
1879 {"MSGQ-RSP-PIPELINE", 1, parse_msgq_rsp_pipeline},
1880 {"MSGQ", 1, parse_msgq},
1884 create_implicit_mempools(struct app_params *app)
1888 idx = APP_PARAM_ADD(app->mempool_params, "MEMPOOL0");
1889 PARSER_IMPLICIT_PARAM_ADD_CHECK(idx, "start-up");
1893 parse_port_mask(struct app_params *app, uint64_t port_mask)
1895 uint32_t pmd_id, link_id;
1898 for (pmd_id = 0; pmd_id < RTE_MAX_ETHPORTS; pmd_id++) {
1899 char name[APP_PARAM_NAME_SIZE];
1902 if ((port_mask & (1LLU << pmd_id)) == 0)
1905 snprintf(name, sizeof(name), "LINK%" PRIu32, link_id);
1906 idx = APP_PARAM_ADD(app->link_params, name);
1907 PARSER_IMPLICIT_PARAM_ADD_CHECK(idx, name);
1909 app->link_params[idx].pmd_id = pmd_id;
1915 app_config_parse(struct app_params *app, const char *file_name)
1917 struct rte_cfgfile *cfg;
1918 char **section_names;
1919 int i, j, sect_count;
1921 /* Implicit mempools */
1922 create_implicit_mempools(app);
1925 parse_port_mask(app, app->port_mask);
1927 /* Load application configuration file */
1928 cfg = rte_cfgfile_load(file_name, 0);
1929 APP_CHECK(cfg != NULL, "Unable to load config file %s", file_name);
1931 sect_count = rte_cfgfile_num_sections(cfg, NULL, 0);
1932 section_names = malloc(sect_count * sizeof(char *));
1933 for (i = 0; i < sect_count; i++)
1934 section_names[i] = malloc(CFG_NAME_LEN);
1936 rte_cfgfile_sections(cfg, section_names, sect_count);
1938 for (i = 0; i < sect_count; i++) {
1939 const struct config_section *sch_s;
1940 int len, cfg_name_len;
1942 cfg_name_len = strlen(section_names[i]);
1944 /* Find section type */
1945 for (j = 0; j < (int)RTE_DIM(cfg_file_scheme); j++) {
1946 sch_s = &cfg_file_scheme[j];
1947 len = strlen(sch_s->prefix);
1949 if (cfg_name_len < len)
1952 /* After section name we expect only '\0' or digit or
1953 * digit dot digit, so protect against false matching,
1954 * for example: "ABC" should match section name
1955 * "ABC0.0", but it should not match section_name
1958 if ((section_names[i][len] != '\0') &&
1959 !isdigit(section_names[i][len]))
1962 if (strncmp(sch_s->prefix, section_names[i], len) == 0)
1966 APP_CHECK(j < (int)RTE_DIM(cfg_file_scheme),
1967 "Unknown section %s",
1970 APP_CHECK(validate_name(section_names[i],
1972 sch_s->numbers) == 0,
1973 "Invalid section name '%s'",
1976 sch_s->load(app, section_names[i], cfg);
1979 for (i = 0; i < sect_count; i++)
1980 free(section_names[i]);
1982 free(section_names);
1984 rte_cfgfile_close(cfg);
1986 APP_PARAM_COUNT(app->mempool_params, app->n_mempools);
1987 APP_PARAM_COUNT(app->link_params, app->n_links);
1988 APP_PARAM_COUNT(app->hwq_in_params, app->n_pktq_hwq_in);
1989 APP_PARAM_COUNT(app->hwq_out_params, app->n_pktq_hwq_out);
1990 APP_PARAM_COUNT(app->swq_params, app->n_pktq_swq);
1991 APP_PARAM_COUNT(app->tm_params, app->n_pktq_tm);
1992 APP_PARAM_COUNT(app->source_params, app->n_pktq_source);
1993 APP_PARAM_COUNT(app->sink_params, app->n_pktq_sink);
1994 APP_PARAM_COUNT(app->msgq_params, app->n_msgq);
1995 APP_PARAM_COUNT(app->pipeline_params, app->n_pipelines);
1997 /* Save configuration to output file */
1998 app_config_save(app, app->output_file);
2000 /* Load TM configuration files */
2001 app_config_parse_tm(app);
2007 save_eal_params(struct app_params *app, FILE *f)
2009 struct app_eal_params *p = &app->eal_params;
2011 fprintf(f, "[EAL]\n");
2014 fprintf(f, "%s = %s\n", "lcores", p->coremap);
2016 if (p->master_lcore_present)
2017 fprintf(f, "%s = %" PRIu32 "\n",
2018 "master_lcore", p->master_lcore);
2020 fprintf(f, "%s = %" PRIu32 "\n", "n", p->channels);
2022 if (p->memory_present)
2023 fprintf(f, "%s = %" PRIu32 "\n", "m", p->memory);
2025 if (p->ranks_present)
2026 fprintf(f, "%s = %" PRIu32 "\n", "r", p->ranks);
2028 if (p->pci_blacklist)
2029 fprintf(f, "%s = %s\n", "pci_blacklist", p->pci_blacklist);
2031 if (p->pci_whitelist)
2032 fprintf(f, "%s = %s\n", "pci_whitelist", p->pci_whitelist);
2035 fprintf(f, "%s = %s\n", "vdev", p->vdev);
2037 if (p->vmware_tsc_map_present)
2038 fprintf(f, "%s = %s\n", "vmware_tsc_map",
2039 (p->vmware_tsc_map) ? "yes" : "no");
2042 fprintf(f, "%s = %s\n", "proc_type", p->proc_type);
2045 fprintf(f, "%s = %s\n", "syslog", p->syslog);
2047 if (p->log_level_present)
2048 fprintf(f, "%s = %" PRIu32 "\n", "log_level", p->log_level);
2050 if (p->version_present)
2051 fprintf(f, "%s = %s\n", "v", (p->version) ? "yes" : "no");
2053 if (p->help_present)
2054 fprintf(f, "%s = %s\n", "help", (p->help) ? "yes" : "no");
2056 if (p->no_huge_present)
2057 fprintf(f, "%s = %s\n", "no_huge", (p->no_huge) ? "yes" : "no");
2059 if (p->no_pci_present)
2060 fprintf(f, "%s = %s\n", "no_pci", (p->no_pci) ? "yes" : "no");
2062 if (p->no_hpet_present)
2063 fprintf(f, "%s = %s\n", "no_hpet", (p->no_hpet) ? "yes" : "no");
2065 if (p->no_shconf_present)
2066 fprintf(f, "%s = %s\n", "no_shconf",
2067 (p->no_shconf) ? "yes" : "no");
2070 fprintf(f, "%s = %s\n", "d", p->add_driver);
2073 fprintf(f, "%s = %s\n", "socket_mem", p->socket_mem);
2076 fprintf(f, "%s = %s\n", "huge_dir", p->huge_dir);
2079 fprintf(f, "%s = %s\n", "file_prefix", p->file_prefix);
2081 if (p->base_virtaddr)
2082 fprintf(f, "%s = %s\n", "base_virtaddr", p->base_virtaddr);
2084 if (p->create_uio_dev_present)
2085 fprintf(f, "%s = %s\n", "create_uio_dev",
2086 (p->create_uio_dev) ? "yes" : "no");
2089 fprintf(f, "%s = %s\n", "vfio_intr", p->vfio_intr);
2091 if (p->xen_dom0_present)
2092 fprintf(f, "%s = %s\n", "xen_dom0",
2093 (p->xen_dom0) ? "yes" : "no");
2099 save_mempool_params(struct app_params *app, FILE *f)
2101 struct app_mempool_params *p;
2104 count = RTE_DIM(app->mempool_params);
2105 for (i = 0; i < count; i++) {
2106 p = &app->mempool_params[i];
2107 if (!APP_PARAM_VALID(p))
2110 fprintf(f, "[%s]\n", p->name);
2111 fprintf(f, "%s = %" PRIu32 "\n", "buffer_size", p->buffer_size);
2112 fprintf(f, "%s = %" PRIu32 "\n", "pool_size", p->pool_size);
2113 fprintf(f, "%s = %" PRIu32 "\n", "cache_size", p->cache_size);
2114 fprintf(f, "%s = %" PRIu32 "\n", "cpu", p->cpu_socket_id);
2121 save_links_params(struct app_params *app, FILE *f)
2123 struct app_link_params *p;
2126 count = RTE_DIM(app->link_params);
2127 for (i = 0; i < count; i++) {
2128 p = &app->link_params[i];
2129 if (!APP_PARAM_VALID(p))
2132 fprintf(f, "[%s]\n", p->name);
2133 fprintf(f, "; %s = %" PRIu32 "\n", "pmd_id", p->pmd_id);
2134 fprintf(f, "%s = %s\n", "promisc", p->promisc ? "yes" : "no");
2135 fprintf(f, "%s = %" PRIu32 "\n", "arp_q", p->arp_q);
2136 fprintf(f, "%s = %" PRIu32 "\n", "tcp_syn_local_q",
2137 p->tcp_syn_local_q);
2138 fprintf(f, "%s = %" PRIu32 "\n", "ip_local_q", p->ip_local_q);
2139 fprintf(f, "%s = %" PRIu32 "\n", "tcp_local_q", p->tcp_local_q);
2140 fprintf(f, "%s = %" PRIu32 "\n", "udp_local_q", p->udp_local_q);
2141 fprintf(f, "%s = %" PRIu32 "\n", "sctp_local_q",
2149 save_rxq_params(struct app_params *app, FILE *f)
2151 struct app_pktq_hwq_in_params *p;
2154 count = RTE_DIM(app->hwq_in_params);
2155 for (i = 0; i < count; i++) {
2156 p = &app->hwq_in_params[i];
2157 if (!APP_PARAM_VALID(p))
2160 fprintf(f, "[%s]\n", p->name);
2161 fprintf(f, "%s = %s\n",
2163 app->mempool_params[p->mempool_id].name);
2164 fprintf(f, "%s = %" PRIu32 "\n", "size", p->size);
2165 fprintf(f, "%s = %" PRIu32 "\n", "burst", p->burst);
2172 save_txq_params(struct app_params *app, FILE *f)
2174 struct app_pktq_hwq_out_params *p;
2177 count = RTE_DIM(app->hwq_out_params);
2178 for (i = 0; i < count; i++) {
2179 p = &app->hwq_out_params[i];
2180 if (!APP_PARAM_VALID(p))
2183 fprintf(f, "[%s]\n", p->name);
2184 fprintf(f, "%s = %" PRIu32 "\n", "size", p->size);
2185 fprintf(f, "%s = %" PRIu32 "\n", "burst", p->burst);
2186 fprintf(f, "%s = %s\n",
2188 p->dropless ? "yes" : "no");
2195 save_swq_params(struct app_params *app, FILE *f)
2197 struct app_pktq_swq_params *p;
2200 count = RTE_DIM(app->swq_params);
2201 for (i = 0; i < count; i++) {
2202 p = &app->swq_params[i];
2203 if (!APP_PARAM_VALID(p))
2206 fprintf(f, "[%s]\n", p->name);
2207 fprintf(f, "%s = %" PRIu32 "\n", "size", p->size);
2208 fprintf(f, "%s = %" PRIu32 "\n", "burst_read", p->burst_read);
2209 fprintf(f, "%s = %" PRIu32 "\n", "burst_write", p->burst_write);
2210 fprintf(f, "%s = %s\n", "dropless", p->dropless ? "yes" : "no");
2211 fprintf(f, "%s = %" PRIu64 "\n", "n_retries", p->n_retries);
2212 fprintf(f, "%s = %" PRIu32 "\n", "cpu", p->cpu_socket_id);
2213 fprintf(f, "%s = %s\n", "ipv4_frag", p->ipv4_frag ? "yes" : "no");
2214 fprintf(f, "%s = %s\n", "ipv6_frag", p->ipv6_frag ? "yes" : "no");
2215 fprintf(f, "%s = %s\n", "ipv4_ras", p->ipv4_ras ? "yes" : "no");
2216 fprintf(f, "%s = %s\n", "ipv6_ras", p->ipv6_ras ? "yes" : "no");
2217 if ((p->ipv4_frag == 1) || (p->ipv6_frag == 1)) {
2218 fprintf(f, "%s = %" PRIu32 "\n", "mtu", p->mtu);
2219 fprintf(f, "%s = %" PRIu32 "\n", "metadata_size", p->metadata_size);
2220 fprintf(f, "%s = %s\n",
2222 app->mempool_params[p->mempool_direct_id].name);
2223 fprintf(f, "%s = %s\n",
2225 app->mempool_params[p->mempool_indirect_id].name);
2233 save_tm_params(struct app_params *app, FILE *f)
2235 struct app_pktq_tm_params *p;
2238 count = RTE_DIM(app->tm_params);
2239 for (i = 0; i < count; i++) {
2240 p = &app->tm_params[i];
2241 if (!APP_PARAM_VALID(p))
2244 fprintf(f, "[%s]\n", p->name);
2245 fprintf(f, "%s = %s\n", "cfg", p->file_name);
2246 fprintf(f, "%s = %" PRIu32 "\n", "burst_read", p->burst_read);
2247 fprintf(f, "%s = %" PRIu32 "\n", "burst_write", p->burst_write);
2254 save_source_params(struct app_params *app, FILE *f)
2256 struct app_pktq_source_params *p;
2259 count = RTE_DIM(app->source_params);
2260 for (i = 0; i < count; i++) {
2261 p = &app->source_params[i];
2262 if (!APP_PARAM_VALID(p))
2265 fprintf(f, "[%s]\n", p->name);
2266 fprintf(f, "%s = %s\n",
2268 app->mempool_params[p->mempool_id].name);
2269 fprintf(f, "%s = %" PRIu32 "\n", "burst", p->burst);
2275 save_msgq_params(struct app_params *app, FILE *f)
2277 struct app_msgq_params *p;
2280 count = RTE_DIM(app->msgq_params);
2281 for (i = 0; i < count; i++) {
2282 p = &app->msgq_params[i];
2283 if (!APP_PARAM_VALID(p))
2286 fprintf(f, "[%s]\n", p->name);
2287 fprintf(f, "%s = %" PRIu32 "\n", "size", p->size);
2288 fprintf(f, "%s = %" PRIu32 "\n", "cpu", p->cpu_socket_id);
2295 save_pipeline_params(struct app_params *app, FILE *f)
2299 count = RTE_DIM(app->pipeline_params);
2300 for (i = 0; i < count; i++) {
2301 struct app_pipeline_params *p = &app->pipeline_params[i];
2303 if (!APP_PARAM_VALID(p))
2307 fprintf(f, "[%s]\n", p->name);
2310 fprintf(f, "type = %s\n", p->type);
2313 fprintf(f, "core = s%" PRIu32 "c%" PRIu32 "%s\n",
2316 (p->hyper_th_id) ? "h" : "");
2322 fprintf(f, "pktq_in =");
2323 for (j = 0; j < p->n_pktq_in; j++) {
2324 struct app_pktq_in_params *pp = &p->pktq_in[j];
2328 case APP_PKTQ_IN_HWQ:
2329 name = app->hwq_in_params[pp->id].name;
2331 case APP_PKTQ_IN_SWQ:
2332 name = app->swq_params[pp->id].name;
2334 case APP_PKTQ_IN_TM:
2335 name = app->tm_params[pp->id].name;
2337 case APP_PKTQ_IN_SOURCE:
2338 name = app->source_params[pp->id].name;
2341 APP_CHECK(0, "Error\n");
2344 fprintf(f, " %s", name);
2350 if (p->n_pktq_out) {
2353 fprintf(f, "pktq_out =");
2354 for (j = 0; j < p->n_pktq_out; j++) {
2355 struct app_pktq_out_params *pp =
2360 case APP_PKTQ_OUT_HWQ:
2361 name = app->hwq_out_params[pp->id].name;
2363 case APP_PKTQ_OUT_SWQ:
2364 name = app->swq_params[pp->id].name;
2366 case APP_PKTQ_OUT_TM:
2367 name = app->tm_params[pp->id].name;
2369 case APP_PKTQ_OUT_SINK:
2370 name = app->sink_params[pp->id].name;
2373 APP_CHECK(0, "Error\n");
2376 fprintf(f, " %s", name);
2385 fprintf(f, "msgq_in =");
2386 for (j = 0; j < p->n_msgq_in; j++) {
2387 uint32_t id = p->msgq_in[j];
2388 char *name = app->msgq_params[id].name;
2390 fprintf(f, " %s", name);
2399 fprintf(f, "msgq_out =");
2400 for (j = 0; j < p->n_msgq_out; j++) {
2401 uint32_t id = p->msgq_out[j];
2402 char *name = app->msgq_params[id].name;
2404 fprintf(f, " %s", name);
2410 fprintf(f, "timer_period = %" PRIu32 "\n", p->timer_period);
2416 for (j = 0; j < p->n_args; j++)
2417 fprintf(f, "%s = %s\n", p->args_name[j],
2426 app_config_save(struct app_params *app, const char *file_name)
2429 char *name, *dir_name;
2432 name = strdup(file_name);
2433 dir_name = dirname(name);
2434 status = access(dir_name, W_OK);
2435 APP_CHECK((status == 0),
2436 "Need write access to directory \"%s\" to save configuration\n",
2439 file = fopen(file_name, "w");
2440 APP_CHECK((file != NULL),
2441 "Failed to save configuration to file \"%s\"", file_name);
2443 save_eal_params(app, file);
2444 save_pipeline_params(app, file);
2445 save_mempool_params(app, file);
2446 save_links_params(app, file);
2447 save_rxq_params(app, file);
2448 save_txq_params(app, file);
2449 save_swq_params(app, file);
2450 save_tm_params(app, file);
2451 save_source_params(app, file);
2452 save_msgq_params(app, file);
2459 app_config_init(struct app_params *app)
2463 memcpy(app, &app_params_default, sizeof(struct app_params));
2465 for (i = 0; i < RTE_DIM(app->mempool_params); i++)
2466 memcpy(&app->mempool_params[i],
2467 &mempool_params_default,
2468 sizeof(struct app_mempool_params));
2470 for (i = 0; i < RTE_DIM(app->link_params); i++)
2471 memcpy(&app->link_params[i],
2472 &link_params_default,
2473 sizeof(struct app_link_params));
2475 for (i = 0; i < RTE_DIM(app->hwq_in_params); i++)
2476 memcpy(&app->hwq_in_params[i],
2477 &default_hwq_in_params,
2478 sizeof(default_hwq_in_params));
2480 for (i = 0; i < RTE_DIM(app->hwq_out_params); i++)
2481 memcpy(&app->hwq_out_params[i],
2482 &default_hwq_out_params,
2483 sizeof(default_hwq_out_params));
2485 for (i = 0; i < RTE_DIM(app->swq_params); i++)
2486 memcpy(&app->swq_params[i],
2487 &default_swq_params,
2488 sizeof(default_swq_params));
2490 for (i = 0; i < RTE_DIM(app->tm_params); i++)
2491 memcpy(&app->tm_params[i],
2493 sizeof(default_tm_params));
2495 for (i = 0; i < RTE_DIM(app->source_params); i++)
2496 memcpy(&app->source_params[i],
2497 &default_source_params,
2498 sizeof(default_source_params));
2500 for (i = 0; i < RTE_DIM(app->sink_params); i++)
2501 memcpy(&app->sink_params[i],
2502 &default_sink_params,
2503 sizeof(default_sink_params));
2505 for (i = 0; i < RTE_DIM(app->msgq_params); i++)
2506 memcpy(&app->msgq_params[i],
2507 &default_msgq_params,
2508 sizeof(default_msgq_params));
2510 for (i = 0; i < RTE_DIM(app->pipeline_params); i++)
2511 memcpy(&app->pipeline_params[i],
2512 &default_pipeline_params,
2513 sizeof(default_pipeline_params));
2519 filenamedup(const char *filename, const char *suffix)
2521 char *s = malloc(strlen(filename) + strlen(suffix) + 1);
2526 sprintf(s, "%s%s", filename, suffix);
2531 app_config_args(struct app_params *app, int argc, char **argv)
2533 const char *optname;
2534 int opt, option_index;
2535 int f_present, s_present, p_present, l_present;
2536 int preproc_present, preproc_params_present;
2539 static struct option lgopts[] = {
2540 { "preproc", 1, 0, 0 },
2541 { "preproc-args", 1, 0, 0 },
2545 /* Copy application name */
2546 strncpy(app->app_name, argv[0], APP_APPNAME_SIZE - 1);
2552 preproc_present = 0;
2553 preproc_params_present = 0;
2555 while ((opt = getopt_long(argc, argv, "f:s:p:l:", lgopts,
2556 &option_index)) != EOF)
2560 rte_panic("Error: Config file is provided "
2561 "more than once\n");
2564 if (!strlen(optarg))
2565 rte_panic("Error: Config file name is null\n");
2567 app->config_file = strdup(optarg);
2568 if (app->config_file == NULL)
2569 rte_panic("Error: Memory allocation failure\n");
2575 rte_panic("Error: Script file is provided "
2576 "more than once\n");
2579 if (!strlen(optarg))
2580 rte_panic("Error: Script file name is null\n");
2582 app->script_file = strdup(optarg);
2583 if (app->script_file == NULL)
2584 rte_panic("Error: Memory allocation failure\n");
2590 rte_panic("Error: PORT_MASK is provided "
2591 "more than once\n");
2594 if ((sscanf(optarg, "%" SCNx64 "%n", &app->port_mask,
2596 ((size_t) scaned != strlen(optarg)))
2597 rte_panic("Error: PORT_MASK is not "
2598 "a hexadecimal integer\n");
2600 if (app->port_mask == 0)
2601 rte_panic("Error: PORT_MASK is null\n");
2607 rte_panic("Error: LOG_LEVEL is provided "
2608 "more than once\n");
2611 if ((sscanf(optarg, "%" SCNu32 "%n", &app->log_level,
2613 ((size_t) scaned != strlen(optarg)) ||
2614 (app->log_level >= APP_LOG_LEVELS))
2615 rte_panic("Error: LOG_LEVEL invalid value\n");
2620 optname = lgopts[option_index].name;
2622 if (strcmp(optname, "preproc") == 0) {
2623 if (preproc_present)
2624 rte_panic("Error: Preprocessor argument "
2625 "is provided more than once\n");
2626 preproc_present = 1;
2628 app->preproc = strdup(optarg);
2632 if (strcmp(optname, "preproc-args") == 0) {
2633 if (preproc_params_present)
2634 rte_panic("Error: Preprocessor args "
2635 "are provided more than once\n");
2636 preproc_params_present = 1;
2638 app->preproc_args = strdup(optarg);
2642 app_print_usage(argv[0]);
2646 app_print_usage(argv[0]);
2649 optind = 0; /* reset getopt lib */
2651 /* Check that mandatory args have been provided */
2653 rte_panic("Error: PORT_MASK is not provided\n");
2655 /* Check dependencies between args */
2656 if (preproc_params_present && (preproc_present == 0))
2657 rte_panic("Error: Preprocessor args specified while "
2658 "preprocessor is not defined\n");
2660 app->parser_file = preproc_present ?
2661 filenamedup(app->config_file, ".preproc") :
2662 strdup(app->config_file);
2663 app->output_file = filenamedup(app->config_file, ".out");
2669 app_config_preproc(struct app_params *app)
2674 if (app->preproc == NULL)
2677 status = access(app->config_file, F_OK | R_OK);
2678 APP_CHECK((status == 0), "Unable to open file %s", app->config_file);
2680 snprintf(buffer, sizeof(buffer), "%s %s %s > %s",
2682 app->preproc_args ? app->preproc_args : "",
2686 status = system(buffer);
2687 APP_CHECK((WIFEXITED(status) && (WEXITSTATUS(status) == 0)),
2688 "Error while preprocessing file \"%s\"\n", app->config_file);