4 * Copyright(c) 2010-2016 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.
46 #include <rte_errno.h>
47 #include <rte_cfgfile.h>
48 #include <rte_string_fns.h>
54 * Default config values
57 static struct app_params app_params_default = {
58 .config_file = "./config/ip_pipeline.cfg",
59 .log_level = APP_LOG_LEVEL_HIGH,
67 static const struct app_mempool_params mempool_params_default = {
69 .buffer_size = 2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM,
70 .pool_size = 32 * 1024,
75 static const struct app_link_params link_params_default = {
86 .rss_proto_ipv4 = ETH_RSS_IPV4,
87 .rss_proto_ipv6 = ETH_RSS_IPV6,
98 .mq_mode = ETH_MQ_RX_NONE,
100 .header_split = 0, /* Header split */
101 .hw_ip_checksum = 0, /* IP checksum offload */
102 .hw_vlan_filter = 0, /* VLAN filtering */
103 .hw_vlan_strip = 0, /* VLAN strip */
104 .hw_vlan_extend = 0, /* Extended VLAN */
105 .jumbo_frame = 0, /* Jumbo frame support */
106 .hw_strip_crc = 1, /* CRC strip by HW */
107 .enable_scatter = 0, /* Scattered packets RX handler */
109 .max_rx_pkt_len = 9000, /* Jumbo frame max packet len */
110 .split_hdr_size = 0, /* Header split buffer size */
120 .mq_mode = ETH_MQ_TX_NONE,
128 static const struct app_pktq_hwq_in_params default_hwq_in_params = {
140 .rx_free_thresh = 64,
142 .rx_deferred_start = 0,
146 static const struct app_pktq_hwq_out_params default_hwq_out_params = {
161 .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS |
162 ETH_TXQ_FLAGS_NOOFFLOADS,
163 .tx_deferred_start = 0,
167 static const struct app_pktq_swq_params default_swq_params = {
181 .mempool_direct_id = 0,
182 .mempool_indirect_id = 0,
185 struct app_pktq_tm_params default_tm_params = {
187 .file_name = "./config/tm_profile.cfg",
192 struct app_pktq_tap_params default_tap_params = {
201 struct app_pktq_kni_params default_kni_params = {
215 struct app_pktq_source_params default_source_params = {
219 .file_name = "./config/packets.pcap",
220 .n_bytes_per_pkt = 0,
223 struct app_pktq_sink_params default_sink_params = {
229 struct app_msgq_params default_msgq_params = {
235 struct app_pipeline_params default_pipeline_params = {
248 static const char app_usage[] =
249 "Usage: %s [-f CONFIG_FILE] [-s SCRIPT_FILE] [-p PORT_MASK] "
250 "[-l LOG_LEVEL] [--preproc PREPROCESSOR] [--preproc-args ARGS]\n"
253 "\t-f CONFIG_FILE: Default config file is %s\n"
254 "\t-p PORT_MASK: Mask of NIC port IDs in hex format (generated from "
255 "config file when not provided)\n"
256 "\t-s SCRIPT_FILE: No CLI script file is run when not specified\n"
257 "\t-l LOG_LEVEL: 0 = NONE, 1 = HIGH PRIO (default), 2 = LOW PRIO\n"
258 "\t--preproc PREPROCESSOR: Configuration file pre-processor\n"
259 "\t--preproc-args ARGS: Arguments to be passed to pre-processor\n"
263 app_print_usage(char *prgname)
265 rte_exit(0, app_usage, prgname, app_params_default.config_file);
268 #define APP_PARAM_ADD(set, key) \
270 ssize_t pos = APP_PARAM_FIND(set, key); \
271 ssize_t size = RTE_DIM(set); \
274 for (pos = 0; pos < size; pos++) { \
275 if (!APP_PARAM_VALID(&((set)[pos]))) \
279 APP_CHECK((pos < size), \
280 "Parse error: size of %s is limited to %u elements",\
281 #set, (uint32_t) size); \
283 (set)[pos].name = strdup(key); \
284 APP_CHECK(((set)[pos].name), \
285 "Parse error: no free memory"); \
290 #define APP_PARAM_ADD_LINK_FOR_RXQ(app, rxq_name) \
292 char link_name[APP_PARAM_NAME_SIZE]; \
293 ssize_t link_param_pos; \
294 uint32_t link_id, queue_id; \
296 sscanf((rxq_name), "RXQ%" SCNu32 ".%" SCNu32, &link_id, &queue_id);\
297 sprintf(link_name, "LINK%" PRIu32, link_id); \
298 link_param_pos = APP_PARAM_ADD((app)->link_params, link_name); \
302 #define APP_PARAM_ADD_LINK_FOR_TXQ(app, txq_name) \
304 char link_name[APP_PARAM_NAME_SIZE]; \
305 ssize_t link_param_pos; \
306 uint32_t link_id, queue_id; \
308 sscanf((txq_name), "TXQ%" SCNu32 ".%" SCNu32, &link_id, &queue_id);\
309 sprintf(link_name, "LINK%" PRIu32, link_id); \
310 link_param_pos = APP_PARAM_ADD((app)->link_params, link_name); \
314 #define APP_PARAM_ADD_LINK_FOR_TM(app, tm_name) \
316 char link_name[APP_PARAM_NAME_SIZE]; \
317 ssize_t link_param_pos; \
320 sscanf((tm_name), "TM%" SCNu32, &link_id); \
321 sprintf(link_name, "LINK%" PRIu32, link_id); \
322 link_param_pos = APP_PARAM_ADD((app)->link_params, link_name); \
326 #define APP_PARAM_ADD_LINK_FOR_KNI(app, kni_name) \
328 char link_name[APP_PARAM_NAME_SIZE]; \
329 ssize_t link_param_pos; \
332 sscanf((kni_name), "KNI%" SCNu32, &link_id); \
333 sprintf(link_name, "LINK%" PRIu32, link_id); \
334 link_param_pos = APP_PARAM_ADD((app)->link_params, link_name); \
338 #define PARSE_CHECK_DUPLICATE_SECTION(obj) \
340 APP_CHECK(((obj)->parsed == 0), \
341 "Parse error: duplicate \"%s\" section", (obj)->name); \
345 #define PARSE_CHECK_DUPLICATE_SECTION_EAL(obj) \
347 APP_CHECK(((obj)->parsed == 0), \
348 "Parse error: duplicate \"%s\" section", "EAL"); \
352 #define PARSE_ERROR(exp, section, entry) \
353 APP_CHECK(exp, "Parse error in section \"%s\": entry \"%s\"", section, entry)
355 #define PARSE_ERROR_MESSAGE(exp, section, entry, message) \
356 APP_CHECK(exp, "Parse error in section \"%s\", entry \"%s\": %s", \
357 section, entry, message)
359 #define PARSE_ERROR_NO_ELEMENTS(exp, section, entry) \
360 APP_CHECK(exp, "Parse error in section \"%s\", entry \"%s\": " \
361 "no elements detected", \
364 #define PARSE_ERROR_TOO_MANY_ELEMENTS(exp, section, entry, max) \
365 APP_CHECK(exp, "Parse error in section \"%s\", entry \"%s\": " \
366 "maximum number of elements allowed is %u", \
369 #define PARSE_ERROR_INVALID_ELEMENT(exp, section, entry, value) \
370 APP_CHECK(exp, "Parse error in section \"%s\", entry \"%s\": " \
371 "Invalid element value \"%s\"", \
372 section, entry, value)
374 #define PARSE_ERROR_MALLOC(exp) \
375 APP_CHECK(exp, "Parse error: no free memory")
377 #define PARSE_ERROR_SECTION(exp, section) \
378 APP_CHECK(exp, "Parse error in section \"%s\"", section)
380 #define PARSE_ERROR_SECTION_NO_ENTRIES(exp, section) \
381 APP_CHECK(exp, "Parse error in section \"%s\": no entries", section)
383 #define PARSE_WARNING_IGNORED(exp, section, entry) \
386 fprintf(stderr, "Parse warning in section \"%s\": " \
387 "entry \"%s\" is ignored", section, entry); \
390 #define PARSE_ERROR_INVALID(exp, section, entry) \
391 APP_CHECK(exp, "Parse error in section \"%s\": unrecognized entry \"%s\"",\
394 #define PARSE_ERROR_DUPLICATE(exp, section, entry) \
395 APP_CHECK(exp, "Parse error in section \"%s\": duplicate entry \"%s\"", \
399 validate_name(const char *name, const char *prefix, int num)
403 for (i = 0; (name[i] != '\0') && (prefix[i] != '\0'); i++) {
404 if (name[i] != prefix[i])
408 if (prefix[i] != '\0')
419 j = skip_digits(&name[i]);
421 if ((j == 0) || (name[i] != '.'))
427 j = skip_digits(&name[i]);
429 if ((j == 0) || (name[i] != '\0'))
437 parse_eal(struct app_params *app,
438 const char *section_name,
439 struct rte_cfgfile *cfg)
441 struct app_eal_params *p = &app->eal_params;
442 struct rte_cfgfile_entry *entries;
445 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
446 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
448 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
449 PARSE_ERROR_MALLOC(entries != NULL);
451 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
453 PARSE_CHECK_DUPLICATE_SECTION_EAL(p);
455 for (i = 0; i < n_entries; i++) {
456 struct rte_cfgfile_entry *entry = &entries[i];
459 if (strcmp(entry->name, "c") == 0) {
460 PARSE_WARNING_IGNORED(0, section_name, entry->name);
465 if (strcmp(entry->name, "l") == 0) {
466 PARSE_WARNING_IGNORED(0, section_name, entry->name);
471 if (strcmp(entry->name, "lcores") == 0) {
472 PARSE_ERROR_DUPLICATE((p->coremap == NULL),
475 p->coremap = strdup(entry->value);
480 if (strcmp(entry->name, "master_lcore") == 0) {
483 PARSE_ERROR_DUPLICATE((p->master_lcore_present == 0),
486 p->master_lcore_present = 1;
488 status = parser_read_uint32(&p->master_lcore,
490 PARSE_ERROR((status == 0), section_name, entry->name);
495 if (strcmp(entry->name, "n") == 0) {
498 PARSE_ERROR_DUPLICATE((p->channels_present == 0),
501 p->channels_present = 1;
503 status = parser_read_uint32(&p->channels, entry->value);
504 PARSE_ERROR((status == 0), section_name, entry->name);
509 if (strcmp(entry->name, "m") == 0) {
512 PARSE_ERROR_DUPLICATE((p->memory_present == 0),
515 p->memory_present = 1;
517 status = parser_read_uint32(&p->memory, entry->value);
518 PARSE_ERROR((status == 0), section_name, entry->name);
523 if (strcmp(entry->name, "r") == 0) {
526 PARSE_ERROR_DUPLICATE((p->ranks_present == 0),
529 p->ranks_present = 1;
531 status = parser_read_uint32(&p->ranks, entry->value);
532 PARSE_ERROR((status == 0), section_name, entry->name);
537 if ((strcmp(entry->name, "pci_blacklist") == 0) ||
538 (strcmp(entry->name, "b") == 0)) {
541 for (i = 0; i < APP_MAX_LINKS; i++) {
542 if (p->pci_blacklist[i])
545 p->pci_blacklist[i] =
546 strdup(entry->value);
547 PARSE_ERROR_MALLOC(p->pci_blacklist[i]);
552 PARSE_ERROR_MESSAGE((i < APP_MAX_LINKS),
553 section_name, entry->name,
554 "too many elements");
559 if ((strcmp(entry->name, "pci_whitelist") == 0) ||
560 (strcmp(entry->name, "w") == 0)) {
563 PARSE_ERROR_MESSAGE((app->port_mask != 0),
564 section_name, entry->name, "entry to be "
565 "generated by the application (port_mask "
568 for (i = 0; i < APP_MAX_LINKS; i++) {
569 if (p->pci_whitelist[i])
572 p->pci_whitelist[i] = strdup(entry->value);
573 PARSE_ERROR_MALLOC(p->pci_whitelist[i]);
578 PARSE_ERROR_MESSAGE((i < APP_MAX_LINKS),
579 section_name, entry->name,
580 "too many elements");
585 if (strcmp(entry->name, "vdev") == 0) {
588 for (i = 0; i < APP_MAX_LINKS; i++) {
592 p->vdev[i] = strdup(entry->value);
593 PARSE_ERROR_MALLOC(p->vdev[i]);
598 PARSE_ERROR_MESSAGE((i < APP_MAX_LINKS),
599 section_name, entry->name,
600 "too many elements");
605 if (strcmp(entry->name, "vmware_tsc_map") == 0) {
608 PARSE_ERROR_DUPLICATE((p->vmware_tsc_map_present == 0),
611 p->vmware_tsc_map_present = 1;
613 val = parser_read_arg_bool(entry->value);
614 PARSE_ERROR((val >= 0), section_name, entry->name);
615 p->vmware_tsc_map = val;
620 if (strcmp(entry->name, "proc_type") == 0) {
621 PARSE_ERROR_DUPLICATE((p->proc_type == NULL),
624 p->proc_type = strdup(entry->value);
629 if (strcmp(entry->name, "syslog") == 0) {
630 PARSE_ERROR_DUPLICATE((p->syslog == NULL),
633 p->syslog = strdup(entry->value);
638 if (strcmp(entry->name, "log_level") == 0) {
641 PARSE_ERROR_DUPLICATE((p->log_level_present == 0),
644 p->log_level_present = 1;
646 status = parser_read_uint32(&p->log_level,
648 PARSE_ERROR((status == 0), section_name, entry->name);
653 if (strcmp(entry->name, "v") == 0) {
656 PARSE_ERROR_DUPLICATE((p->version_present == 0),
659 p->version_present = 1;
661 val = parser_read_arg_bool(entry->value);
662 PARSE_ERROR((val >= 0), section_name, entry->name);
668 if ((strcmp(entry->name, "help") == 0) ||
669 (strcmp(entry->name, "h") == 0)) {
672 PARSE_ERROR_DUPLICATE((p->help_present == 0),
677 val = parser_read_arg_bool(entry->value);
678 PARSE_ERROR((val >= 0), section_name, entry->name);
684 if (strcmp(entry->name, "no_huge") == 0) {
687 PARSE_ERROR_DUPLICATE((p->no_huge_present == 0),
690 p->no_huge_present = 1;
692 val = parser_read_arg_bool(entry->value);
693 PARSE_ERROR((val >= 0), section_name, entry->name);
699 if (strcmp(entry->name, "no_pci") == 0) {
702 PARSE_ERROR_DUPLICATE((p->no_pci_present == 0),
705 p->no_pci_present = 1;
707 val = parser_read_arg_bool(entry->value);
708 PARSE_ERROR((val >= 0), section_name, entry->name);
714 if (strcmp(entry->name, "no_hpet") == 0) {
717 PARSE_ERROR_DUPLICATE((p->no_hpet_present == 0),
720 p->no_hpet_present = 1;
722 val = parser_read_arg_bool(entry->value);
723 PARSE_ERROR((val >= 0), section_name, entry->name);
729 if (strcmp(entry->name, "no_shconf") == 0) {
732 PARSE_ERROR_DUPLICATE((p->no_shconf_present == 0),
735 p->no_shconf_present = 1;
737 val = parser_read_arg_bool(entry->value);
738 PARSE_ERROR((val >= 0), section_name, entry->name);
744 if (strcmp(entry->name, "d") == 0) {
745 PARSE_ERROR_DUPLICATE((p->add_driver == NULL),
748 p->add_driver = strdup(entry->value);
753 if (strcmp(entry->name, "socket_mem") == 0) {
754 PARSE_ERROR_DUPLICATE((p->socket_mem == NULL),
757 p->socket_mem = strdup(entry->value);
762 if (strcmp(entry->name, "huge_dir") == 0) {
763 PARSE_ERROR_DUPLICATE((p->huge_dir == NULL),
766 p->huge_dir = strdup(entry->value);
771 if (strcmp(entry->name, "file_prefix") == 0) {
772 PARSE_ERROR_DUPLICATE((p->file_prefix == NULL),
775 p->file_prefix = strdup(entry->value);
780 if (strcmp(entry->name, "base_virtaddr") == 0) {
781 PARSE_ERROR_DUPLICATE((p->base_virtaddr == NULL),
784 p->base_virtaddr = strdup(entry->value);
789 if (strcmp(entry->name, "create_uio_dev") == 0) {
792 PARSE_ERROR_DUPLICATE((p->create_uio_dev_present == 0),
795 p->create_uio_dev_present = 1;
797 val = parser_read_arg_bool(entry->value);
798 PARSE_ERROR((val >= 0), section_name, entry->name);
799 p->create_uio_dev = val;
804 if (strcmp(entry->name, "vfio_intr") == 0) {
805 PARSE_ERROR_DUPLICATE((p->vfio_intr == NULL),
808 p->vfio_intr = strdup(entry->value);
813 PARSE_ERROR_INVALID(0, section_name, entry->name);
820 parse_pipeline_pktq_in(struct app_params *app,
821 struct app_pipeline_params *p,
827 enum app_pktq_in_type type;
829 char *name = strtok_r(value, PARSE_DELIMITER, &value);
834 PARSE_ERROR_TOO_MANY_ELEMENTS(
835 (p->n_pktq_in < RTE_DIM(p->pktq_in)),
836 p->name, "pktq_in", (uint32_t)RTE_DIM(p->pktq_in));
838 if (validate_name(name, "RXQ", 2) == 0) {
839 type = APP_PKTQ_IN_HWQ;
840 id = APP_PARAM_ADD(app->hwq_in_params, name);
841 APP_PARAM_ADD_LINK_FOR_RXQ(app, name);
842 } else if (validate_name(name, "SWQ", 1) == 0) {
843 type = APP_PKTQ_IN_SWQ;
844 id = APP_PARAM_ADD(app->swq_params, name);
845 } else if (validate_name(name, "TM", 1) == 0) {
846 type = APP_PKTQ_IN_TM;
847 id = APP_PARAM_ADD(app->tm_params, name);
848 APP_PARAM_ADD_LINK_FOR_TM(app, name);
849 } else if (validate_name(name, "TAP", 1) == 0) {
850 type = APP_PKTQ_IN_TAP;
851 id = APP_PARAM_ADD(app->tap_params, name);
852 } else if (validate_name(name, "KNI", 1) == 0) {
853 type = APP_PKTQ_IN_KNI;
854 id = APP_PARAM_ADD(app->kni_params, name);
855 APP_PARAM_ADD_LINK_FOR_KNI(app, name);
856 } else if (validate_name(name, "SOURCE", 1) == 0) {
857 type = APP_PKTQ_IN_SOURCE;
858 id = APP_PARAM_ADD(app->source_params, name);
860 PARSE_ERROR_INVALID_ELEMENT(0,
861 p->name, "pktq_in", name);
863 p->pktq_in[p->n_pktq_in].type = type;
864 p->pktq_in[p->n_pktq_in].id = (uint32_t) id;
868 PARSE_ERROR_NO_ELEMENTS((p->n_pktq_in > 0), p->name, "pktq_in");
872 parse_pipeline_pktq_out(struct app_params *app,
873 struct app_pipeline_params *p,
879 enum app_pktq_out_type type;
881 char *name = strtok_r(value, PARSE_DELIMITER, &value);
886 PARSE_ERROR_TOO_MANY_ELEMENTS(
887 (p->n_pktq_out < RTE_DIM(p->pktq_out)),
888 p->name, "pktq_out", (uint32_t)RTE_DIM(p->pktq_out));
890 if (validate_name(name, "TXQ", 2) == 0) {
891 type = APP_PKTQ_OUT_HWQ;
892 id = APP_PARAM_ADD(app->hwq_out_params, name);
893 APP_PARAM_ADD_LINK_FOR_TXQ(app, name);
894 } else if (validate_name(name, "SWQ", 1) == 0) {
895 type = APP_PKTQ_OUT_SWQ;
896 id = APP_PARAM_ADD(app->swq_params, name);
897 } else if (validate_name(name, "TM", 1) == 0) {
898 type = APP_PKTQ_OUT_TM;
899 id = APP_PARAM_ADD(app->tm_params, name);
900 APP_PARAM_ADD_LINK_FOR_TM(app, name);
901 } else if (validate_name(name, "TAP", 1) == 0) {
902 type = APP_PKTQ_OUT_TAP;
903 id = APP_PARAM_ADD(app->tap_params, name);
904 } else if (validate_name(name, "KNI", 1) == 0) {
905 type = APP_PKTQ_OUT_KNI;
906 id = APP_PARAM_ADD(app->kni_params, name);
907 APP_PARAM_ADD_LINK_FOR_KNI(app, name);
908 } else if (validate_name(name, "SINK", 1) == 0) {
909 type = APP_PKTQ_OUT_SINK;
910 id = APP_PARAM_ADD(app->sink_params, name);
912 PARSE_ERROR_INVALID_ELEMENT(0,
913 p->name, "pktq_out", name);
915 p->pktq_out[p->n_pktq_out].type = type;
916 p->pktq_out[p->n_pktq_out].id = id;
920 PARSE_ERROR_NO_ELEMENTS((p->n_pktq_out > 0), p->name, "pktq_out");
924 parse_pipeline_msgq_in(struct app_params *app,
925 struct app_pipeline_params *p,
932 char *name = strtok_r(value, PARSE_DELIMITER, &value);
937 PARSE_ERROR_TOO_MANY_ELEMENTS(
938 (p->n_msgq_in < RTE_DIM(p->msgq_in)),
939 p->name, "msgq_in", (uint32_t)(RTE_DIM(p->msgq_in)));
941 PARSE_ERROR_INVALID_ELEMENT(
942 (validate_name(name, "MSGQ", 1) == 0),
943 p->name, "msgq_in", name);
945 idx = APP_PARAM_ADD(app->msgq_params, name);
946 p->msgq_in[p->n_msgq_in] = idx;
950 PARSE_ERROR_NO_ELEMENTS((p->n_msgq_in > 0), p->name, "msgq_in");
954 parse_pipeline_msgq_out(struct app_params *app,
955 struct app_pipeline_params *p,
962 char *name = strtok_r(value, PARSE_DELIMITER, &value);
967 PARSE_ERROR_TOO_MANY_ELEMENTS(
968 (p->n_msgq_out < RTE_DIM(p->msgq_out)),
969 p->name, "msgq_out", (uint32_t)RTE_DIM(p->msgq_out));
971 PARSE_ERROR_INVALID_ELEMENT(
972 (validate_name(name, "MSGQ", 1) == 0),
973 p->name, "msgq_out", name);
975 idx = APP_PARAM_ADD(app->msgq_params, name);
976 p->msgq_out[p->n_msgq_out] = idx;
980 PARSE_ERROR_NO_ELEMENTS((p->n_msgq_out > 0), p->name, "msgq_out");
984 parse_pipeline(struct app_params *app,
985 const char *section_name,
986 struct rte_cfgfile *cfg)
988 char name[CFG_NAME_LEN];
989 struct app_pipeline_params *param;
990 struct rte_cfgfile_entry *entries;
994 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
995 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
997 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
998 PARSE_ERROR_MALLOC(entries != NULL);
1000 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1002 param_idx = APP_PARAM_ADD(app->pipeline_params, section_name);
1003 param = &app->pipeline_params[param_idx];
1004 PARSE_CHECK_DUPLICATE_SECTION(param);
1006 for (i = 0; i < n_entries; i++) {
1007 struct rte_cfgfile_entry *ent = &entries[i];
1009 if (strcmp(ent->name, "type") == 0) {
1010 int w_size = snprintf(param->type, RTE_DIM(param->type),
1013 PARSE_ERROR(((w_size > 0) &&
1014 (w_size < (int)RTE_DIM(param->type))),
1020 if (strcmp(ent->name, "core") == 0) {
1021 int status = parse_pipeline_core(
1022 ¶m->socket_id, ¶m->core_id,
1023 ¶m->hyper_th_id, ent->value);
1025 PARSE_ERROR((status == 0), section_name,
1030 if (strcmp(ent->name, "pktq_in") == 0) {
1031 parse_pipeline_pktq_in(app, param, ent->value);
1036 if (strcmp(ent->name, "pktq_out") == 0) {
1037 parse_pipeline_pktq_out(app, param, ent->value);
1042 if (strcmp(ent->name, "msgq_in") == 0) {
1043 parse_pipeline_msgq_in(app, param, ent->value);
1048 if (strcmp(ent->name, "msgq_out") == 0) {
1049 parse_pipeline_msgq_out(app, param, ent->value);
1054 if (strcmp(ent->name, "timer_period") == 0) {
1055 int status = parser_read_uint32(
1056 ¶m->timer_period,
1059 PARSE_ERROR((status == 0), section_name,
1064 /* pipeline type specific items */
1065 APP_CHECK((param->n_args < APP_MAX_PIPELINE_ARGS),
1066 "Parse error in section \"%s\": too many "
1067 "pipeline specified parameters", section_name);
1069 param->args_name[param->n_args] = strdup(ent->name);
1070 param->args_value[param->n_args] = strdup(ent->value);
1072 APP_CHECK((param->args_name[param->n_args] != NULL) &&
1073 (param->args_value[param->n_args] != NULL),
1074 "Parse error: no free memory");
1079 snprintf(name, sizeof(name), "MSGQ-REQ-%s", section_name);
1080 param_idx = APP_PARAM_ADD(app->msgq_params, name);
1081 app->msgq_params[param_idx].cpu_socket_id = param->socket_id;
1082 param->msgq_in[param->n_msgq_in++] = param_idx;
1084 snprintf(name, sizeof(name), "MSGQ-RSP-%s", section_name);
1085 param_idx = APP_PARAM_ADD(app->msgq_params, name);
1086 app->msgq_params[param_idx].cpu_socket_id = param->socket_id;
1087 param->msgq_out[param->n_msgq_out++] = param_idx;
1089 snprintf(name, sizeof(name), "MSGQ-REQ-CORE-s%" PRIu32 "c%" PRIu32 "%s",
1092 (param->hyper_th_id) ? "h" : "");
1093 param_idx = APP_PARAM_ADD(app->msgq_params, name);
1094 app->msgq_params[param_idx].cpu_socket_id = param->socket_id;
1096 snprintf(name, sizeof(name), "MSGQ-RSP-CORE-s%" PRIu32 "c%" PRIu32 "%s",
1099 (param->hyper_th_id) ? "h" : "");
1100 param_idx = APP_PARAM_ADD(app->msgq_params, name);
1101 app->msgq_params[param_idx].cpu_socket_id = param->socket_id;
1107 parse_mempool(struct app_params *app,
1108 const char *section_name,
1109 struct rte_cfgfile *cfg)
1111 struct app_mempool_params *param;
1112 struct rte_cfgfile_entry *entries;
1116 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1117 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1119 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1120 PARSE_ERROR_MALLOC(entries != NULL);
1122 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1124 param_idx = APP_PARAM_ADD(app->mempool_params, section_name);
1125 param = &app->mempool_params[param_idx];
1126 PARSE_CHECK_DUPLICATE_SECTION(param);
1128 for (i = 0; i < n_entries; i++) {
1129 struct rte_cfgfile_entry *ent = &entries[i];
1131 if (strcmp(ent->name, "buffer_size") == 0) {
1132 int status = parser_read_uint32(
1133 ¶m->buffer_size, ent->value);
1135 PARSE_ERROR((status == 0), section_name,
1140 if (strcmp(ent->name, "pool_size") == 0) {
1141 int status = parser_read_uint32(
1142 ¶m->pool_size, ent->value);
1144 PARSE_ERROR((status == 0), section_name,
1149 if (strcmp(ent->name, "cache_size") == 0) {
1150 int status = parser_read_uint32(
1151 ¶m->cache_size, ent->value);
1153 PARSE_ERROR((status == 0), section_name,
1158 if (strcmp(ent->name, "cpu") == 0) {
1159 int status = parser_read_uint32(
1160 ¶m->cpu_socket_id, ent->value);
1162 PARSE_ERROR((status == 0), section_name,
1168 PARSE_ERROR_INVALID(0, section_name, ent->name);
1175 parse_link_rss_qs(struct app_link_params *p,
1181 char *token = strtok_r(value, PARSE_DELIMITER, &value);
1186 if (p->n_rss_qs == RTE_DIM(p->rss_qs))
1189 if (parser_read_uint32(&p->rss_qs[p->n_rss_qs++], token))
1197 parse_link_rss_proto_ipv4(struct app_link_params *p,
1203 char *token = strtok_r(value, PARSE_DELIMITER, &value);
1208 if (strcmp(token, "IP") == 0) {
1209 mask |= ETH_RSS_IPV4;
1212 if (strcmp(token, "FRAG") == 0) {
1213 mask |= ETH_RSS_FRAG_IPV4;
1216 if (strcmp(token, "TCP") == 0) {
1217 mask |= ETH_RSS_NONFRAG_IPV4_TCP;
1220 if (strcmp(token, "UDP") == 0) {
1221 mask |= ETH_RSS_NONFRAG_IPV4_UDP;
1224 if (strcmp(token, "SCTP") == 0) {
1225 mask |= ETH_RSS_NONFRAG_IPV4_SCTP;
1228 if (strcmp(token, "OTHER") == 0) {
1229 mask |= ETH_RSS_NONFRAG_IPV4_OTHER;
1235 p->rss_proto_ipv4 = mask;
1240 parse_link_rss_proto_ipv6(struct app_link_params *p,
1246 char *token = strtok_r(value, PARSE_DELIMITER, &value);
1251 if (strcmp(token, "IP") == 0) {
1252 mask |= ETH_RSS_IPV6;
1255 if (strcmp(token, "FRAG") == 0) {
1256 mask |= ETH_RSS_FRAG_IPV6;
1259 if (strcmp(token, "TCP") == 0) {
1260 mask |= ETH_RSS_NONFRAG_IPV6_TCP;
1263 if (strcmp(token, "UDP") == 0) {
1264 mask |= ETH_RSS_NONFRAG_IPV6_UDP;
1267 if (strcmp(token, "SCTP") == 0) {
1268 mask |= ETH_RSS_NONFRAG_IPV6_SCTP;
1271 if (strcmp(token, "OTHER") == 0) {
1272 mask |= ETH_RSS_NONFRAG_IPV6_OTHER;
1275 if (strcmp(token, "IP_EX") == 0) {
1276 mask |= ETH_RSS_IPV6_EX;
1279 if (strcmp(token, "TCP_EX") == 0) {
1280 mask |= ETH_RSS_IPV6_TCP_EX;
1283 if (strcmp(token, "UDP_EX") == 0) {
1284 mask |= ETH_RSS_IPV6_UDP_EX;
1290 p->rss_proto_ipv6 = mask;
1295 parse_link_rss_proto_l2(struct app_link_params *p,
1301 char *token = strtok_r(value, PARSE_DELIMITER, &value);
1306 if (strcmp(token, "L2") == 0) {
1307 mask |= ETH_RSS_L2_PAYLOAD;
1313 p->rss_proto_l2 = mask;
1318 parse_link(struct app_params *app,
1319 const char *section_name,
1320 struct rte_cfgfile *cfg)
1322 struct app_link_params *param;
1323 struct rte_cfgfile_entry *entries;
1325 int rss_qs_present = 0;
1326 int rss_proto_ipv4_present = 0;
1327 int rss_proto_ipv6_present = 0;
1328 int rss_proto_l2_present = 0;
1329 int pci_bdf_present = 0;
1332 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1333 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1335 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1336 PARSE_ERROR_MALLOC(entries != NULL);
1338 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1340 param_idx = APP_PARAM_ADD(app->link_params, section_name);
1341 param = &app->link_params[param_idx];
1342 PARSE_CHECK_DUPLICATE_SECTION(param);
1344 for (i = 0; i < n_entries; i++) {
1345 struct rte_cfgfile_entry *ent = &entries[i];
1347 if (strcmp(ent->name, "promisc") == 0) {
1348 int status = parser_read_arg_bool(ent->value);
1350 PARSE_ERROR((status != -EINVAL), section_name,
1352 param->promisc = status;
1356 if (strcmp(ent->name, "arp_q") == 0) {
1357 int status = parser_read_uint32(¶m->arp_q,
1360 PARSE_ERROR((status == 0), section_name,
1365 if (strcmp(ent->name, "tcp_syn_q") == 0) {
1366 int status = parser_read_uint32(
1367 ¶m->tcp_syn_q, ent->value);
1369 PARSE_ERROR((status == 0), section_name, ent->name);
1373 if (strcmp(ent->name, "ip_local_q") == 0) {
1374 int status = parser_read_uint32(
1375 ¶m->ip_local_q, ent->value);
1377 PARSE_ERROR((status == 0), section_name,
1382 if (strcmp(ent->name, "tcp_local_q") == 0) {
1383 int status = parser_read_uint32(
1384 ¶m->tcp_local_q, ent->value);
1386 PARSE_ERROR((status == 0), section_name,
1391 if (strcmp(ent->name, "udp_local_q") == 0) {
1392 int status = parser_read_uint32(
1393 ¶m->udp_local_q, ent->value);
1395 PARSE_ERROR((status == 0), section_name,
1400 if (strcmp(ent->name, "sctp_local_q") == 0) {
1401 int status = parser_read_uint32(
1402 ¶m->sctp_local_q, ent->value);
1404 PARSE_ERROR((status == 0), section_name,
1409 if (strcmp(ent->name, "rss_qs") == 0) {
1410 int status = parse_link_rss_qs(param, ent->value);
1412 PARSE_ERROR((status == 0), section_name,
1418 if (strcmp(ent->name, "rss_proto_ipv4") == 0) {
1420 parse_link_rss_proto_ipv4(param, ent->value);
1422 PARSE_ERROR((status != -EINVAL), section_name,
1424 rss_proto_ipv4_present = 1;
1428 if (strcmp(ent->name, "rss_proto_ipv6") == 0) {
1430 parse_link_rss_proto_ipv6(param, ent->value);
1432 PARSE_ERROR((status != -EINVAL), section_name,
1434 rss_proto_ipv6_present = 1;
1438 if (strcmp(ent->name, "rss_proto_l2") == 0) {
1439 int status = parse_link_rss_proto_l2(param, ent->value);
1441 PARSE_ERROR((status != -EINVAL), section_name,
1443 rss_proto_l2_present = 1;
1447 if (strcmp(ent->name, "pci_bdf") == 0) {
1448 PARSE_ERROR_DUPLICATE((pci_bdf_present == 0),
1449 section_name, ent->name);
1451 snprintf(param->pci_bdf, APP_LINK_PCI_BDF_SIZE,
1453 pci_bdf_present = 1;
1458 PARSE_ERROR_INVALID(0, section_name, ent->name);
1461 /* Check for mandatory fields */
1463 PARSE_ERROR_MESSAGE((pci_bdf_present == 0),
1464 section_name, "pci_bdf",
1465 "entry not allowed (port_mask is provided)");
1467 PARSE_ERROR_MESSAGE((pci_bdf_present),
1468 section_name, "pci_bdf",
1469 "this entry is mandatory (port_mask is not "
1472 if (rss_proto_ipv4_present)
1473 PARSE_ERROR_MESSAGE((rss_qs_present),
1474 section_name, "rss_proto_ipv4",
1475 "entry not allowed (rss_qs entry is not provided)");
1476 if (rss_proto_ipv6_present)
1477 PARSE_ERROR_MESSAGE((rss_qs_present),
1478 section_name, "rss_proto_ipv6",
1479 "entry not allowed (rss_qs entry is not provided)");
1480 if (rss_proto_l2_present)
1481 PARSE_ERROR_MESSAGE((rss_qs_present),
1482 section_name, "rss_proto_l2",
1483 "entry not allowed (rss_qs entry is not provided)");
1484 if (rss_proto_ipv4_present |
1485 rss_proto_ipv6_present |
1486 rss_proto_l2_present){
1487 if (rss_proto_ipv4_present == 0)
1488 param->rss_proto_ipv4 = 0;
1489 if (rss_proto_ipv6_present == 0)
1490 param->rss_proto_ipv6 = 0;
1491 if (rss_proto_l2_present == 0)
1492 param->rss_proto_l2 = 0;
1499 parse_rxq(struct app_params *app,
1500 const char *section_name,
1501 struct rte_cfgfile *cfg)
1503 struct app_pktq_hwq_in_params *param;
1504 struct rte_cfgfile_entry *entries;
1508 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1509 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1511 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1512 PARSE_ERROR_MALLOC(entries != NULL);
1514 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1516 param_idx = APP_PARAM_ADD(app->hwq_in_params, section_name);
1517 param = &app->hwq_in_params[param_idx];
1518 PARSE_CHECK_DUPLICATE_SECTION(param);
1520 APP_PARAM_ADD_LINK_FOR_RXQ(app, section_name);
1522 for (i = 0; i < n_entries; i++) {
1523 struct rte_cfgfile_entry *ent = &entries[i];
1525 if (strcmp(ent->name, "mempool") == 0) {
1526 int status = validate_name(ent->value,
1530 PARSE_ERROR((status == 0), section_name,
1533 idx = APP_PARAM_ADD(app->mempool_params, ent->value);
1534 param->mempool_id = idx;
1538 if (strcmp(ent->name, "size") == 0) {
1539 int status = parser_read_uint32(¶m->size,
1542 PARSE_ERROR((status == 0), section_name,
1547 if (strcmp(ent->name, "burst") == 0) {
1548 int status = parser_read_uint32(¶m->burst,
1551 PARSE_ERROR((status == 0), section_name,
1557 PARSE_ERROR_INVALID(0, section_name, ent->name);
1564 parse_txq(struct app_params *app,
1565 const char *section_name,
1566 struct rte_cfgfile *cfg)
1568 struct app_pktq_hwq_out_params *param;
1569 struct rte_cfgfile_entry *entries;
1573 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1574 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1576 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1577 PARSE_ERROR_MALLOC(entries != NULL);
1579 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1581 param_idx = APP_PARAM_ADD(app->hwq_out_params, section_name);
1582 param = &app->hwq_out_params[param_idx];
1583 PARSE_CHECK_DUPLICATE_SECTION(param);
1585 APP_PARAM_ADD_LINK_FOR_TXQ(app, section_name);
1587 for (i = 0; i < n_entries; i++) {
1588 struct rte_cfgfile_entry *ent = &entries[i];
1590 if (strcmp(ent->name, "size") == 0) {
1591 int status = parser_read_uint32(¶m->size,
1594 PARSE_ERROR((status == 0), section_name,
1599 if (strcmp(ent->name, "burst") == 0) {
1600 int status = parser_read_uint32(¶m->burst,
1603 PARSE_ERROR((status == 0), section_name,
1608 if (strcmp(ent->name, "dropless") == 0) {
1609 int status = parser_read_arg_bool(ent->value);
1612 PARSE_ERROR((status != -EINVAL), section_name,
1614 param->dropless = status;
1618 if (strcmp(ent->name, "n_retries") == 0) {
1619 int status = parser_read_uint64(¶m->n_retries,
1622 PARSE_ERROR((status == 0), section_name,
1628 PARSE_ERROR_INVALID(0, section_name, ent->name);
1635 parse_swq(struct app_params *app,
1636 const char *section_name,
1637 struct rte_cfgfile *cfg)
1639 struct app_pktq_swq_params *param;
1640 struct rte_cfgfile_entry *entries;
1642 uint32_t mtu_present = 0;
1643 uint32_t metadata_size_present = 0;
1644 uint32_t mempool_direct_present = 0;
1645 uint32_t mempool_indirect_present = 0;
1649 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1650 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1652 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1653 PARSE_ERROR_MALLOC(entries != NULL);
1655 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1657 param_idx = APP_PARAM_ADD(app->swq_params, section_name);
1658 param = &app->swq_params[param_idx];
1659 PARSE_CHECK_DUPLICATE_SECTION(param);
1661 for (i = 0; i < n_entries; i++) {
1662 struct rte_cfgfile_entry *ent = &entries[i];
1664 if (strcmp(ent->name, "size") == 0) {
1665 int status = parser_read_uint32(¶m->size,
1668 PARSE_ERROR((status == 0), section_name,
1673 if (strcmp(ent->name, "burst_read") == 0) {
1674 int status = parser_read_uint32(&
1675 param->burst_read, ent->value);
1677 PARSE_ERROR((status == 0), section_name,
1682 if (strcmp(ent->name, "burst_write") == 0) {
1683 int status = parser_read_uint32(
1684 ¶m->burst_write, ent->value);
1686 PARSE_ERROR((status == 0), section_name,
1691 if (strcmp(ent->name, "dropless") == 0) {
1692 int status = parser_read_arg_bool(ent->value);
1694 PARSE_ERROR((status != -EINVAL), section_name,
1696 param->dropless = status;
1700 if (strcmp(ent->name, "n_retries") == 0) {
1701 int status = parser_read_uint64(¶m->n_retries,
1704 PARSE_ERROR((status == 0), section_name,
1709 if (strcmp(ent->name, "cpu") == 0) {
1710 int status = parser_read_uint32(
1711 ¶m->cpu_socket_id, ent->value);
1713 PARSE_ERROR((status == 0), section_name, ent->name);
1717 if (strcmp(ent->name, "ipv4_frag") == 0) {
1718 int status = parser_read_arg_bool(ent->value);
1720 PARSE_ERROR((status != -EINVAL), section_name,
1723 param->ipv4_frag = status;
1724 if (param->mtu == 0)
1730 if (strcmp(ent->name, "ipv6_frag") == 0) {
1731 int status = parser_read_arg_bool(ent->value);
1733 PARSE_ERROR((status != -EINVAL), section_name,
1735 param->ipv6_frag = status;
1736 if (param->mtu == 0)
1741 if (strcmp(ent->name, "ipv4_ras") == 0) {
1742 int status = parser_read_arg_bool(ent->value);
1744 PARSE_ERROR((status != -EINVAL), section_name,
1746 param->ipv4_ras = status;
1750 if (strcmp(ent->name, "ipv6_ras") == 0) {
1751 int status = parser_read_arg_bool(ent->value);
1753 PARSE_ERROR((status != -EINVAL), section_name,
1755 param->ipv6_ras = status;
1759 if (strcmp(ent->name, "mtu") == 0) {
1760 int status = parser_read_uint32(¶m->mtu,
1763 PARSE_ERROR((status == 0), section_name,
1769 if (strcmp(ent->name, "metadata_size") == 0) {
1770 int status = parser_read_uint32(
1771 ¶m->metadata_size, ent->value);
1773 PARSE_ERROR((status == 0), section_name,
1775 metadata_size_present = 1;
1779 if (strcmp(ent->name, "mempool_direct") == 0) {
1780 int status = validate_name(ent->value,
1784 PARSE_ERROR((status == 0), section_name,
1787 idx = APP_PARAM_ADD(app->mempool_params, ent->value);
1788 param->mempool_direct_id = idx;
1790 mempool_direct_present = 1;
1794 if (strcmp(ent->name, "mempool_indirect") == 0) {
1795 int status = validate_name(ent->value,
1799 PARSE_ERROR((status == 0), section_name,
1802 idx = APP_PARAM_ADD(app->mempool_params, ent->value);
1803 param->mempool_indirect_id = idx;
1805 mempool_indirect_present = 1;
1810 PARSE_ERROR_INVALID(0, section_name, ent->name);
1813 APP_CHECK(((mtu_present == 0) ||
1814 ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))),
1815 "Parse error in section \"%s\": IPv4/IPv6 fragmentation "
1816 "is off, therefore entry \"mtu\" is not allowed",
1819 APP_CHECK(((metadata_size_present == 0) ||
1820 ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))),
1821 "Parse error in section \"%s\": IPv4/IPv6 fragmentation "
1822 "is off, therefore entry \"metadata_size\" is "
1823 "not allowed", section_name);
1825 APP_CHECK(((mempool_direct_present == 0) ||
1826 ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))),
1827 "Parse error in section \"%s\": IPv4/IPv6 fragmentation "
1828 "is off, therefore entry \"mempool_direct\" is "
1829 "not allowed", section_name);
1831 APP_CHECK(((mempool_indirect_present == 0) ||
1832 ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))),
1833 "Parse error in section \"%s\": IPv4/IPv6 fragmentation "
1834 "is off, therefore entry \"mempool_indirect\" is "
1835 "not allowed", section_name);
1841 parse_tm(struct app_params *app,
1842 const char *section_name,
1843 struct rte_cfgfile *cfg)
1845 struct app_pktq_tm_params *param;
1846 struct rte_cfgfile_entry *entries;
1850 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1851 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1853 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1854 PARSE_ERROR_MALLOC(entries != NULL);
1856 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1858 param_idx = APP_PARAM_ADD(app->tm_params, section_name);
1859 param = &app->tm_params[param_idx];
1860 PARSE_CHECK_DUPLICATE_SECTION(param);
1862 APP_PARAM_ADD_LINK_FOR_TM(app, section_name);
1864 for (i = 0; i < n_entries; i++) {
1865 struct rte_cfgfile_entry *ent = &entries[i];
1867 if (strcmp(ent->name, "cfg") == 0) {
1868 param->file_name = strdup(ent->value);
1869 PARSE_ERROR_MALLOC(param->file_name != NULL);
1873 if (strcmp(ent->name, "burst_read") == 0) {
1874 int status = parser_read_uint32(
1875 ¶m->burst_read, ent->value);
1877 PARSE_ERROR((status == 0), section_name,
1882 if (strcmp(ent->name, "burst_write") == 0) {
1883 int status = parser_read_uint32(
1884 ¶m->burst_write, ent->value);
1886 PARSE_ERROR((status == 0), section_name,
1892 PARSE_ERROR_INVALID(0, section_name, ent->name);
1899 parse_tap(struct app_params *app,
1900 const char *section_name,
1901 struct rte_cfgfile *cfg)
1903 struct app_pktq_tap_params *param;
1904 struct rte_cfgfile_entry *entries;
1908 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1909 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1911 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1912 PARSE_ERROR_MALLOC(entries != NULL);
1914 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1916 param_idx = APP_PARAM_ADD(app->tap_params, section_name);
1917 param = &app->tap_params[param_idx];
1918 PARSE_CHECK_DUPLICATE_SECTION(param);
1920 for (i = 0; i < n_entries; i++) {
1921 struct rte_cfgfile_entry *ent = &entries[i];
1923 if (strcmp(ent->name, "burst_read") == 0) {
1924 int status = parser_read_uint32(
1925 ¶m->burst_read, ent->value);
1927 PARSE_ERROR((status == 0), section_name,
1932 if (strcmp(ent->name, "burst_write") == 0) {
1933 int status = parser_read_uint32(
1934 ¶m->burst_write, ent->value);
1936 PARSE_ERROR((status == 0), section_name,
1941 if (strcmp(ent->name, "dropless") == 0) {
1942 int status = parser_read_arg_bool(ent->value);
1944 PARSE_ERROR((status != -EINVAL), section_name,
1946 param->dropless = status;
1950 if (strcmp(ent->name, "n_retries") == 0) {
1951 int status = parser_read_uint64(¶m->n_retries,
1954 PARSE_ERROR((status == 0), section_name,
1959 if (strcmp(ent->name, "mempool") == 0) {
1960 int status = validate_name(ent->value,
1964 PARSE_ERROR((status == 0), section_name,
1967 idx = APP_PARAM_ADD(app->mempool_params, ent->value);
1968 param->mempool_id = idx;
1974 PARSE_ERROR_INVALID(0, section_name, ent->name);
1981 parse_kni(struct app_params *app,
1982 const char *section_name,
1983 struct rte_cfgfile *cfg)
1985 struct app_pktq_kni_params *param;
1986 struct rte_cfgfile_entry *entries;
1990 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1991 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1993 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1994 PARSE_ERROR_MALLOC(entries != NULL);
1996 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1998 param_idx = APP_PARAM_ADD(app->kni_params, section_name);
1999 param = &app->kni_params[param_idx];
2000 PARSE_CHECK_DUPLICATE_SECTION(param);
2002 APP_PARAM_ADD_LINK_FOR_KNI(app, section_name);
2004 for (i = 0; i < n_entries; i++) {
2005 struct rte_cfgfile_entry *ent = &entries[i];
2007 if (strcmp(ent->name, "core") == 0) {
2008 int status = parse_pipeline_core(
2011 ¶m->hyper_th_id,
2014 PARSE_ERROR((status == 0), section_name,
2016 param->force_bind = 1;
2020 if (strcmp(ent->name, "mempool") == 0) {
2021 int status = validate_name(ent->value,
2025 PARSE_ERROR((status == 0), section_name,
2028 idx = APP_PARAM_ADD(app->mempool_params, ent->value);
2029 param->mempool_id = idx;
2033 if (strcmp(ent->name, "burst_read") == 0) {
2034 int status = parser_read_uint32(¶m->burst_read,
2037 PARSE_ERROR((status == 0), section_name,
2042 if (strcmp(ent->name, "burst_write") == 0) {
2043 int status = parser_read_uint32(¶m->burst_write,
2046 PARSE_ERROR((status == 0), section_name,
2051 if (strcmp(ent->name, "dropless") == 0) {
2052 int status = parser_read_arg_bool(ent->value);
2054 PARSE_ERROR((status != -EINVAL), section_name,
2056 param->dropless = status;
2060 if (strcmp(ent->name, "n_retries") == 0) {
2061 int status = parser_read_uint64(¶m->n_retries,
2064 PARSE_ERROR((status == 0), section_name,
2070 PARSE_ERROR_INVALID(0, section_name, ent->name);
2077 parse_source(struct app_params *app,
2078 const char *section_name,
2079 struct rte_cfgfile *cfg)
2081 struct app_pktq_source_params *param;
2082 struct rte_cfgfile_entry *entries;
2085 uint32_t pcap_file_present = 0;
2086 uint32_t pcap_size_present = 0;
2088 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
2089 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
2091 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
2092 PARSE_ERROR_MALLOC(entries != NULL);
2094 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
2096 param_idx = APP_PARAM_ADD(app->source_params, section_name);
2097 param = &app->source_params[param_idx];
2098 PARSE_CHECK_DUPLICATE_SECTION(param);
2100 for (i = 0; i < n_entries; i++) {
2101 struct rte_cfgfile_entry *ent = &entries[i];
2103 if (strcmp(ent->name, "mempool") == 0) {
2104 int status = validate_name(ent->value,
2108 PARSE_ERROR((status == 0), section_name,
2111 idx = APP_PARAM_ADD(app->mempool_params, ent->value);
2112 param->mempool_id = idx;
2116 if (strcmp(ent->name, "burst") == 0) {
2117 int status = parser_read_uint32(¶m->burst,
2120 PARSE_ERROR((status == 0), section_name,
2125 if (strcmp(ent->name, "pcap_file_rd") == 0) {
2126 PARSE_ERROR_DUPLICATE((pcap_file_present == 0),
2127 section_name, ent->name);
2129 param->file_name = strdup(ent->value);
2131 PARSE_ERROR_MALLOC(param->file_name != NULL);
2132 pcap_file_present = 1;
2137 if (strcmp(ent->name, "pcap_bytes_rd_per_pkt") == 0) {
2140 PARSE_ERROR_DUPLICATE((pcap_size_present == 0),
2141 section_name, ent->name);
2143 status = parser_read_uint32(
2144 ¶m->n_bytes_per_pkt, ent->value);
2146 PARSE_ERROR((status == 0), section_name,
2148 pcap_size_present = 1;
2154 PARSE_ERROR_INVALID(0, section_name, ent->name);
2161 parse_sink(struct app_params *app,
2162 const char *section_name,
2163 struct rte_cfgfile *cfg)
2165 struct app_pktq_sink_params *param;
2166 struct rte_cfgfile_entry *entries;
2169 uint32_t pcap_file_present = 0;
2170 uint32_t pcap_n_pkt_present = 0;
2172 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
2173 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
2175 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
2176 PARSE_ERROR_MALLOC(entries != NULL);
2178 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
2180 param_idx = APP_PARAM_ADD(app->sink_params, section_name);
2181 param = &app->sink_params[param_idx];
2182 PARSE_CHECK_DUPLICATE_SECTION(param);
2184 for (i = 0; i < n_entries; i++) {
2185 struct rte_cfgfile_entry *ent = &entries[i];
2187 if (strcmp(ent->name, "pcap_file_wr") == 0) {
2188 PARSE_ERROR_DUPLICATE((pcap_file_present == 0),
2189 section_name, ent->name);
2191 param->file_name = strdup(ent->value);
2193 PARSE_ERROR_MALLOC((param->file_name != NULL));
2198 if (strcmp(ent->name, "pcap_n_pkt_wr") == 0) {
2201 PARSE_ERROR_DUPLICATE((pcap_n_pkt_present == 0),
2202 section_name, ent->name);
2204 status = parser_read_uint32(
2205 ¶m->n_pkts_to_dump, ent->value);
2207 PARSE_ERROR((status == 0), section_name,
2214 PARSE_ERROR_INVALID(0, section_name, ent->name);
2221 parse_msgq_req_pipeline(struct app_params *app,
2222 const char *section_name,
2223 struct rte_cfgfile *cfg)
2225 struct app_msgq_params *param;
2226 struct rte_cfgfile_entry *entries;
2230 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
2231 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
2233 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
2234 PARSE_ERROR_MALLOC(entries != NULL);
2236 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
2238 param_idx = APP_PARAM_ADD(app->msgq_params, section_name);
2239 param = &app->msgq_params[param_idx];
2240 PARSE_CHECK_DUPLICATE_SECTION(param);
2242 for (i = 0; i < n_entries; i++) {
2243 struct rte_cfgfile_entry *ent = &entries[i];
2245 if (strcmp(ent->name, "size") == 0) {
2246 int status = parser_read_uint32(¶m->size,
2249 PARSE_ERROR((status == 0), section_name,
2255 PARSE_ERROR_INVALID(0, section_name, ent->name);
2262 parse_msgq_rsp_pipeline(struct app_params *app,
2263 const char *section_name,
2264 struct rte_cfgfile *cfg)
2266 struct app_msgq_params *param;
2267 struct rte_cfgfile_entry *entries;
2271 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
2272 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
2274 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
2275 PARSE_ERROR_MALLOC(entries != NULL);
2277 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
2279 param_idx = APP_PARAM_ADD(app->msgq_params, section_name);
2280 param = &app->msgq_params[param_idx];
2281 PARSE_CHECK_DUPLICATE_SECTION(param);
2283 for (i = 0; i < n_entries; i++) {
2284 struct rte_cfgfile_entry *ent = &entries[i];
2286 if (strcmp(ent->name, "size") == 0) {
2287 int status = parser_read_uint32(¶m->size,
2290 PARSE_ERROR((status == 0), section_name,
2296 PARSE_ERROR_INVALID(0, section_name, ent->name);
2303 parse_msgq(struct app_params *app,
2304 const char *section_name,
2305 struct rte_cfgfile *cfg)
2307 struct app_msgq_params *param;
2308 struct rte_cfgfile_entry *entries;
2312 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
2313 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
2315 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
2316 PARSE_ERROR_MALLOC(entries != NULL);
2318 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
2320 param_idx = APP_PARAM_ADD(app->msgq_params, section_name);
2321 param = &app->msgq_params[param_idx];
2322 PARSE_CHECK_DUPLICATE_SECTION(param);
2324 for (i = 0; i < n_entries; i++) {
2325 struct rte_cfgfile_entry *ent = &entries[i];
2327 if (strcmp(ent->name, "size") == 0) {
2328 int status = parser_read_uint32(¶m->size,
2331 PARSE_ERROR((status == 0), section_name,
2336 if (strcmp(ent->name, "cpu") == 0) {
2337 int status = parser_read_uint32(
2338 ¶m->cpu_socket_id, ent->value);
2340 PARSE_ERROR((status == 0), section_name,
2346 PARSE_ERROR_INVALID(0, section_name, ent->name);
2352 typedef void (*config_section_load)(struct app_params *p,
2353 const char *section_name,
2354 struct rte_cfgfile *cfg);
2356 struct config_section {
2357 const char prefix[CFG_NAME_LEN];
2359 config_section_load load;
2362 static const struct config_section cfg_file_scheme[] = {
2363 {"EAL", 0, parse_eal},
2364 {"PIPELINE", 1, parse_pipeline},
2365 {"MEMPOOL", 1, parse_mempool},
2366 {"LINK", 1, parse_link},
2367 {"RXQ", 2, parse_rxq},
2368 {"TXQ", 2, parse_txq},
2369 {"SWQ", 1, parse_swq},
2370 {"TM", 1, parse_tm},
2371 {"TAP", 1, parse_tap},
2372 {"KNI", 1, parse_kni},
2373 {"SOURCE", 1, parse_source},
2374 {"SINK", 1, parse_sink},
2375 {"MSGQ-REQ-PIPELINE", 1, parse_msgq_req_pipeline},
2376 {"MSGQ-RSP-PIPELINE", 1, parse_msgq_rsp_pipeline},
2377 {"MSGQ", 1, parse_msgq},
2381 create_implicit_mempools(struct app_params *app)
2383 APP_PARAM_ADD(app->mempool_params, "MEMPOOL0");
2387 create_implicit_links_from_port_mask(struct app_params *app,
2390 uint32_t pmd_id, link_id;
2393 for (pmd_id = 0; pmd_id < RTE_MAX_ETHPORTS; pmd_id++) {
2394 char name[APP_PARAM_NAME_SIZE];
2397 if ((port_mask & (1LLU << pmd_id)) == 0)
2400 snprintf(name, sizeof(name), "LINK%" PRIu32, link_id);
2401 idx = APP_PARAM_ADD(app->link_params, name);
2403 app->link_params[idx].pmd_id = pmd_id;
2409 assign_link_pmd_id_from_pci_bdf(struct app_params *app)
2413 for (i = 0; i < app->n_links; i++) {
2414 struct app_link_params *link = &app->link_params[i];
2416 APP_CHECK((strlen(link->pci_bdf)),
2417 "Parse error: %s pci_bdf is not configured "
2418 "(port_mask is not provided)",
2426 app_config_parse(struct app_params *app, const char *file_name)
2428 struct rte_cfgfile *cfg;
2429 char **section_names;
2430 int i, j, sect_count;
2432 /* Implicit mempools */
2433 create_implicit_mempools(app);
2437 create_implicit_links_from_port_mask(app, app->port_mask);
2439 /* Load application configuration file */
2440 cfg = rte_cfgfile_load(file_name, 0);
2441 APP_CHECK((cfg != NULL), "Parse error: Unable to load config "
2442 "file %s", file_name);
2444 sect_count = rte_cfgfile_num_sections(cfg, NULL, 0);
2445 APP_CHECK((sect_count > 0), "Parse error: number of sections "
2446 "in file \"%s\" return %d", file_name,
2449 section_names = malloc(sect_count * sizeof(char *));
2450 PARSE_ERROR_MALLOC(section_names != NULL);
2452 for (i = 0; i < sect_count; i++)
2453 section_names[i] = malloc(CFG_NAME_LEN);
2455 rte_cfgfile_sections(cfg, section_names, sect_count);
2457 for (i = 0; i < sect_count; i++) {
2458 const struct config_section *sch_s;
2459 int len, cfg_name_len;
2461 cfg_name_len = strlen(section_names[i]);
2463 /* Find section type */
2464 for (j = 0; j < (int)RTE_DIM(cfg_file_scheme); j++) {
2465 sch_s = &cfg_file_scheme[j];
2466 len = strlen(sch_s->prefix);
2468 if (cfg_name_len < len)
2471 /* After section name we expect only '\0' or digit or
2472 * digit dot digit, so protect against false matching,
2473 * for example: "ABC" should match section name
2474 * "ABC0.0", but it should not match section_name
2477 if ((section_names[i][len] != '\0') &&
2478 !isdigit(section_names[i][len]))
2481 if (strncmp(sch_s->prefix, section_names[i], len) == 0)
2485 APP_CHECK(j < (int)RTE_DIM(cfg_file_scheme),
2486 "Parse error: unknown section %s",
2489 APP_CHECK(validate_name(section_names[i],
2491 sch_s->numbers) == 0,
2492 "Parse error: invalid section name \"%s\"",
2495 sch_s->load(app, section_names[i], cfg);
2498 for (i = 0; i < sect_count; i++)
2499 free(section_names[i]);
2501 free(section_names);
2503 rte_cfgfile_close(cfg);
2505 APP_PARAM_COUNT(app->mempool_params, app->n_mempools);
2506 APP_PARAM_COUNT(app->link_params, app->n_links);
2507 APP_PARAM_COUNT(app->hwq_in_params, app->n_pktq_hwq_in);
2508 APP_PARAM_COUNT(app->hwq_out_params, app->n_pktq_hwq_out);
2509 APP_PARAM_COUNT(app->swq_params, app->n_pktq_swq);
2510 APP_PARAM_COUNT(app->tm_params, app->n_pktq_tm);
2511 APP_PARAM_COUNT(app->tap_params, app->n_pktq_tap);
2512 APP_PARAM_COUNT(app->kni_params, app->n_pktq_kni);
2513 APP_PARAM_COUNT(app->source_params, app->n_pktq_source);
2514 APP_PARAM_COUNT(app->sink_params, app->n_pktq_sink);
2515 APP_PARAM_COUNT(app->msgq_params, app->n_msgq);
2516 APP_PARAM_COUNT(app->pipeline_params, app->n_pipelines);
2518 if (app->port_mask == 0)
2519 assign_link_pmd_id_from_pci_bdf(app);
2521 /* Save configuration to output file */
2522 app_config_save(app, app->output_file);
2524 /* Load TM configuration files */
2525 app_config_parse_tm(app);
2531 save_eal_params(struct app_params *app, FILE *f)
2533 struct app_eal_params *p = &app->eal_params;
2536 fprintf(f, "[EAL]\n");
2539 fprintf(f, "%s = %s\n", "lcores", p->coremap);
2541 if (p->master_lcore_present)
2542 fprintf(f, "%s = %" PRIu32 "\n",
2543 "master_lcore", p->master_lcore);
2545 fprintf(f, "%s = %" PRIu32 "\n", "n", p->channels);
2547 if (p->memory_present)
2548 fprintf(f, "%s = %" PRIu32 "\n", "m", p->memory);
2550 if (p->ranks_present)
2551 fprintf(f, "%s = %" PRIu32 "\n", "r", p->ranks);
2553 for (i = 0; i < APP_MAX_LINKS; i++) {
2554 if (p->pci_blacklist[i] == NULL)
2557 fprintf(f, "%s = %s\n", "pci_blacklist",
2558 p->pci_blacklist[i]);
2561 for (i = 0; i < APP_MAX_LINKS; i++) {
2562 if (p->pci_whitelist[i] == NULL)
2565 fprintf(f, "%s = %s\n", "pci_whitelist",
2566 p->pci_whitelist[i]);
2569 for (i = 0; i < APP_MAX_LINKS; i++) {
2570 if (p->vdev[i] == NULL)
2573 fprintf(f, "%s = %s\n", "vdev",
2577 if (p->vmware_tsc_map_present)
2578 fprintf(f, "%s = %s\n", "vmware_tsc_map",
2579 (p->vmware_tsc_map) ? "yes" : "no");
2582 fprintf(f, "%s = %s\n", "proc_type", p->proc_type);
2585 fprintf(f, "%s = %s\n", "syslog", p->syslog);
2587 if (p->log_level_present)
2588 fprintf(f, "%s = %" PRIu32 "\n", "log_level", p->log_level);
2590 if (p->version_present)
2591 fprintf(f, "%s = %s\n", "v", (p->version) ? "yes" : "no");
2593 if (p->help_present)
2594 fprintf(f, "%s = %s\n", "help", (p->help) ? "yes" : "no");
2596 if (p->no_huge_present)
2597 fprintf(f, "%s = %s\n", "no_huge", (p->no_huge) ? "yes" : "no");
2599 if (p->no_pci_present)
2600 fprintf(f, "%s = %s\n", "no_pci", (p->no_pci) ? "yes" : "no");
2602 if (p->no_hpet_present)
2603 fprintf(f, "%s = %s\n", "no_hpet", (p->no_hpet) ? "yes" : "no");
2605 if (p->no_shconf_present)
2606 fprintf(f, "%s = %s\n", "no_shconf",
2607 (p->no_shconf) ? "yes" : "no");
2610 fprintf(f, "%s = %s\n", "d", p->add_driver);
2613 fprintf(f, "%s = %s\n", "socket_mem", p->socket_mem);
2616 fprintf(f, "%s = %s\n", "huge_dir", p->huge_dir);
2619 fprintf(f, "%s = %s\n", "file_prefix", p->file_prefix);
2621 if (p->base_virtaddr)
2622 fprintf(f, "%s = %s\n", "base_virtaddr", p->base_virtaddr);
2624 if (p->create_uio_dev_present)
2625 fprintf(f, "%s = %s\n", "create_uio_dev",
2626 (p->create_uio_dev) ? "yes" : "no");
2629 fprintf(f, "%s = %s\n", "vfio_intr", p->vfio_intr);
2635 save_mempool_params(struct app_params *app, FILE *f)
2637 struct app_mempool_params *p;
2640 count = RTE_DIM(app->mempool_params);
2641 for (i = 0; i < count; i++) {
2642 p = &app->mempool_params[i];
2643 if (!APP_PARAM_VALID(p))
2646 fprintf(f, "[%s]\n", p->name);
2647 fprintf(f, "%s = %" PRIu32 "\n", "buffer_size", p->buffer_size);
2648 fprintf(f, "%s = %" PRIu32 "\n", "pool_size", p->pool_size);
2649 fprintf(f, "%s = %" PRIu32 "\n", "cache_size", p->cache_size);
2650 fprintf(f, "%s = %" PRIu32 "\n", "cpu", p->cpu_socket_id);
2657 save_links_params(struct app_params *app, FILE *f)
2659 struct app_link_params *p;
2662 count = RTE_DIM(app->link_params);
2663 for (i = 0; i < count; i++) {
2664 p = &app->link_params[i];
2665 if (!APP_PARAM_VALID(p))
2668 fprintf(f, "[%s]\n", p->name);
2669 fprintf(f, "; %s = %" PRIu32 "\n", "pmd_id", p->pmd_id);
2670 fprintf(f, "%s = %s\n", "promisc", p->promisc ? "yes" : "no");
2671 fprintf(f, "%s = %" PRIu32 "\n", "arp_q", p->arp_q);
2672 fprintf(f, "%s = %" PRIu32 "\n", "tcp_syn_q",
2674 fprintf(f, "%s = %" PRIu32 "\n", "ip_local_q", p->ip_local_q);
2675 fprintf(f, "%s = %" PRIu32 "\n", "tcp_local_q", p->tcp_local_q);
2676 fprintf(f, "%s = %" PRIu32 "\n", "udp_local_q", p->udp_local_q);
2677 fprintf(f, "%s = %" PRIu32 "\n", "sctp_local_q",
2684 fprintf(f, "rss_qs = ");
2685 for (j = 0; j < p->n_rss_qs; j++)
2686 fprintf(f, "%" PRIu32 " ", p->rss_qs[j]);
2689 /* rss_proto_ipv4 */
2690 if (p->rss_proto_ipv4) {
2691 fprintf(f, "rss_proto_ipv4 = ");
2692 if (p->rss_proto_ipv4 & ETH_RSS_IPV4)
2694 if (p->rss_proto_ipv4 & ETH_RSS_FRAG_IPV4)
2695 fprintf(f, "FRAG ");
2696 if (p->rss_proto_ipv4 &
2697 ETH_RSS_NONFRAG_IPV4_TCP)
2699 if (p->rss_proto_ipv4 &
2700 ETH_RSS_NONFRAG_IPV4_UDP)
2702 if (p->rss_proto_ipv4 &
2703 ETH_RSS_NONFRAG_IPV4_SCTP)
2704 fprintf(f, "SCTP ");
2705 if (p->rss_proto_ipv4 &
2706 ETH_RSS_NONFRAG_IPV4_OTHER)
2707 fprintf(f, "OTHER ");
2710 fprintf(f, "; rss_proto_ipv4 = <NONE>\n");
2712 /* rss_proto_ipv6 */
2713 if (p->rss_proto_ipv6) {
2714 fprintf(f, "rss_proto_ipv6 = ");
2715 if (p->rss_proto_ipv6 & ETH_RSS_IPV6)
2717 if (p->rss_proto_ipv6 & ETH_RSS_FRAG_IPV6)
2718 fprintf(f, "FRAG ");
2719 if (p->rss_proto_ipv6 &
2720 ETH_RSS_NONFRAG_IPV6_TCP)
2722 if (p->rss_proto_ipv6 &
2723 ETH_RSS_NONFRAG_IPV6_UDP)
2725 if (p->rss_proto_ipv6 &
2726 ETH_RSS_NONFRAG_IPV6_SCTP)
2727 fprintf(f, "SCTP ");
2728 if (p->rss_proto_ipv6 &
2729 ETH_RSS_NONFRAG_IPV6_OTHER)
2730 fprintf(f, "OTHER ");
2731 if (p->rss_proto_ipv6 & ETH_RSS_IPV6_EX)
2732 fprintf(f, "IP_EX ");
2733 if (p->rss_proto_ipv6 &
2734 ETH_RSS_IPV6_TCP_EX)
2735 fprintf(f, "TCP_EX ");
2736 if (p->rss_proto_ipv6 &
2737 ETH_RSS_IPV6_UDP_EX)
2738 fprintf(f, "UDP_EX ");
2741 fprintf(f, "; rss_proto_ipv6 = <NONE>\n");
2744 if (p->rss_proto_l2) {
2745 fprintf(f, "rss_proto_l2 = ");
2746 if (p->rss_proto_l2 & ETH_RSS_L2_PAYLOAD)
2750 fprintf(f, "; rss_proto_l2 = <NONE>\n");
2752 fprintf(f, "; rss_qs = <NONE>\n");
2753 fprintf(f, "; rss_proto_ipv4 = <NONE>\n");
2754 fprintf(f, "; rss_proto_ipv6 = <NONE>\n");
2755 fprintf(f, "; rss_proto_l2 = <NONE>\n");
2758 if (strlen(p->pci_bdf))
2759 fprintf(f, "%s = %s\n", "pci_bdf", p->pci_bdf);
2766 save_rxq_params(struct app_params *app, FILE *f)
2768 struct app_pktq_hwq_in_params *p;
2771 count = RTE_DIM(app->hwq_in_params);
2772 for (i = 0; i < count; i++) {
2773 p = &app->hwq_in_params[i];
2774 if (!APP_PARAM_VALID(p))
2777 fprintf(f, "[%s]\n", p->name);
2778 fprintf(f, "%s = %s\n",
2780 app->mempool_params[p->mempool_id].name);
2781 fprintf(f, "%s = %" PRIu32 "\n", "size", p->size);
2782 fprintf(f, "%s = %" PRIu32 "\n", "burst", p->burst);
2789 save_txq_params(struct app_params *app, FILE *f)
2791 struct app_pktq_hwq_out_params *p;
2794 count = RTE_DIM(app->hwq_out_params);
2795 for (i = 0; i < count; i++) {
2796 p = &app->hwq_out_params[i];
2797 if (!APP_PARAM_VALID(p))
2800 fprintf(f, "[%s]\n", p->name);
2801 fprintf(f, "%s = %" PRIu32 "\n", "size", p->size);
2802 fprintf(f, "%s = %" PRIu32 "\n", "burst", p->burst);
2803 fprintf(f, "%s = %s\n",
2805 p->dropless ? "yes" : "no");
2806 fprintf(f, "%s = %" PRIu64 "\n", "n_retries", p->n_retries);
2813 save_swq_params(struct app_params *app, FILE *f)
2815 struct app_pktq_swq_params *p;
2818 count = RTE_DIM(app->swq_params);
2819 for (i = 0; i < count; i++) {
2820 p = &app->swq_params[i];
2821 if (!APP_PARAM_VALID(p))
2824 fprintf(f, "[%s]\n", p->name);
2825 fprintf(f, "%s = %" PRIu32 "\n", "size", p->size);
2826 fprintf(f, "%s = %" PRIu32 "\n", "burst_read", p->burst_read);
2827 fprintf(f, "%s = %" PRIu32 "\n", "burst_write", p->burst_write);
2828 fprintf(f, "%s = %s\n", "dropless", p->dropless ? "yes" : "no");
2829 fprintf(f, "%s = %" PRIu64 "\n", "n_retries", p->n_retries);
2830 fprintf(f, "%s = %" PRIu32 "\n", "cpu", p->cpu_socket_id);
2831 fprintf(f, "%s = %s\n", "ipv4_frag", p->ipv4_frag ? "yes" : "no");
2832 fprintf(f, "%s = %s\n", "ipv6_frag", p->ipv6_frag ? "yes" : "no");
2833 fprintf(f, "%s = %s\n", "ipv4_ras", p->ipv4_ras ? "yes" : "no");
2834 fprintf(f, "%s = %s\n", "ipv6_ras", p->ipv6_ras ? "yes" : "no");
2835 if ((p->ipv4_frag == 1) || (p->ipv6_frag == 1)) {
2836 fprintf(f, "%s = %" PRIu32 "\n", "mtu", p->mtu);
2837 fprintf(f, "%s = %" PRIu32 "\n", "metadata_size", p->metadata_size);
2838 fprintf(f, "%s = %s\n",
2840 app->mempool_params[p->mempool_direct_id].name);
2841 fprintf(f, "%s = %s\n",
2843 app->mempool_params[p->mempool_indirect_id].name);
2851 save_tm_params(struct app_params *app, FILE *f)
2853 struct app_pktq_tm_params *p;
2856 count = RTE_DIM(app->tm_params);
2857 for (i = 0; i < count; i++) {
2858 p = &app->tm_params[i];
2859 if (!APP_PARAM_VALID(p))
2862 fprintf(f, "[%s]\n", p->name);
2863 fprintf(f, "%s = %s\n", "cfg", p->file_name);
2864 fprintf(f, "%s = %" PRIu32 "\n", "burst_read", p->burst_read);
2865 fprintf(f, "%s = %" PRIu32 "\n", "burst_write", p->burst_write);
2872 save_tap_params(struct app_params *app, FILE *f)
2874 struct app_pktq_tap_params *p;
2877 count = RTE_DIM(app->tap_params);
2878 for (i = 0; i < count; i++) {
2879 p = &app->tap_params[i];
2880 if (!APP_PARAM_VALID(p))
2883 fprintf(f, "[%s]\n", p->name);
2884 fprintf(f, "%s = %" PRIu32 "\n", "burst_read", p->burst_read);
2885 fprintf(f, "%s = %" PRIu32 "\n", "burst_write", p->burst_write);
2886 fprintf(f, "%s = %s\n", "dropless", p->dropless ? "yes" : "no");
2887 fprintf(f, "%s = %" PRIu64 "\n", "n_retries", p->n_retries);
2888 fprintf(f, "%s = %s\n", "mempool",
2889 app->mempool_params[p->mempool_id].name);
2896 save_kni_params(struct app_params *app, FILE *f)
2898 struct app_pktq_kni_params *p;
2901 count = RTE_DIM(app->kni_params);
2902 for (i = 0; i < count; i++) {
2903 p = &app->kni_params[i];
2904 if (!APP_PARAM_VALID(p))
2908 fprintf(f, "[%s]\n", p->name);
2911 if (p->force_bind) {
2912 fprintf(f, "; force_bind = 1\n");
2913 fprintf(f, "core = s%" PRIu32 "c%" PRIu32 "%s\n",
2916 (p->hyper_th_id) ? "h" : "");
2918 fprintf(f, "; force_bind = 0\n");
2921 fprintf(f, "%s = %s\n", "mempool",
2922 app->mempool_params[p->mempool_id].name);
2925 fprintf(f, "%s = %" PRIu32 "\n", "burst_read", p->burst_read);
2928 fprintf(f, "%s = %" PRIu32 "\n", "burst_write", p->burst_write);
2931 fprintf(f, "%s = %s\n",
2933 p->dropless ? "yes" : "no");
2936 fprintf(f, "%s = %" PRIu64 "\n", "n_retries", p->n_retries);
2943 save_source_params(struct app_params *app, FILE *f)
2945 struct app_pktq_source_params *p;
2948 count = RTE_DIM(app->source_params);
2949 for (i = 0; i < count; i++) {
2950 p = &app->source_params[i];
2951 if (!APP_PARAM_VALID(p))
2954 fprintf(f, "[%s]\n", p->name);
2955 fprintf(f, "%s = %s\n",
2957 app->mempool_params[p->mempool_id].name);
2958 fprintf(f, "%s = %" PRIu32 "\n", "burst", p->burst);
2959 fprintf(f, "%s = %s\n", "pcap_file_rd", p->file_name);
2960 fprintf(f, "%s = %" PRIu32 "\n", "pcap_bytes_rd_per_pkt",
2961 p->n_bytes_per_pkt);
2967 save_sink_params(struct app_params *app, FILE *f)
2969 struct app_pktq_sink_params *p;
2972 count = RTE_DIM(app->sink_params);
2973 for (i = 0; i < count; i++) {
2974 p = &app->sink_params[i];
2975 if (!APP_PARAM_VALID(p))
2978 fprintf(f, "[%s]\n", p->name);
2979 fprintf(f, "%s = %s\n", "pcap_file_wr", p->file_name);
2980 fprintf(f, "%s = %" PRIu32 "\n",
2981 "pcap_n_pkt_wr", p->n_pkts_to_dump);
2987 save_msgq_params(struct app_params *app, FILE *f)
2989 struct app_msgq_params *p;
2992 count = RTE_DIM(app->msgq_params);
2993 for (i = 0; i < count; i++) {
2994 p = &app->msgq_params[i];
2995 if (!APP_PARAM_VALID(p))
2998 fprintf(f, "[%s]\n", p->name);
2999 fprintf(f, "%s = %" PRIu32 "\n", "size", p->size);
3000 fprintf(f, "%s = %" PRIu32 "\n", "cpu", p->cpu_socket_id);
3007 save_pipeline_params(struct app_params *app, FILE *f)
3011 count = RTE_DIM(app->pipeline_params);
3012 for (i = 0; i < count; i++) {
3013 struct app_pipeline_params *p = &app->pipeline_params[i];
3015 if (!APP_PARAM_VALID(p))
3019 fprintf(f, "[%s]\n", p->name);
3022 fprintf(f, "type = %s\n", p->type);
3025 fprintf(f, "core = s%" PRIu32 "c%" PRIu32 "%s\n",
3028 (p->hyper_th_id) ? "h" : "");
3034 fprintf(f, "pktq_in =");
3035 for (j = 0; j < p->n_pktq_in; j++) {
3036 struct app_pktq_in_params *pp = &p->pktq_in[j];
3040 case APP_PKTQ_IN_HWQ:
3041 name = app->hwq_in_params[pp->id].name;
3043 case APP_PKTQ_IN_SWQ:
3044 name = app->swq_params[pp->id].name;
3046 case APP_PKTQ_IN_TM:
3047 name = app->tm_params[pp->id].name;
3049 case APP_PKTQ_IN_TAP:
3050 name = app->tap_params[pp->id].name;
3052 case APP_PKTQ_IN_KNI:
3053 name = app->kni_params[pp->id].name;
3055 case APP_PKTQ_IN_SOURCE:
3056 name = app->source_params[pp->id].name;
3059 APP_CHECK(0, "System error "
3060 "occurred while saving "
3061 "parameter to file");
3064 fprintf(f, " %s", name);
3070 if (p->n_pktq_out) {
3073 fprintf(f, "pktq_out =");
3074 for (j = 0; j < p->n_pktq_out; j++) {
3075 struct app_pktq_out_params *pp =
3080 case APP_PKTQ_OUT_HWQ:
3081 name = app->hwq_out_params[pp->id].name;
3083 case APP_PKTQ_OUT_SWQ:
3084 name = app->swq_params[pp->id].name;
3086 case APP_PKTQ_OUT_TM:
3087 name = app->tm_params[pp->id].name;
3089 case APP_PKTQ_OUT_TAP:
3090 name = app->tap_params[pp->id].name;
3092 case APP_PKTQ_OUT_KNI:
3093 name = app->kni_params[pp->id].name;
3095 case APP_PKTQ_OUT_SINK:
3096 name = app->sink_params[pp->id].name;
3099 APP_CHECK(0, "System error "
3100 "occurred while saving "
3101 "parameter to file");
3104 fprintf(f, " %s", name);
3113 fprintf(f, "msgq_in =");
3114 for (j = 0; j < p->n_msgq_in; j++) {
3115 uint32_t id = p->msgq_in[j];
3116 char *name = app->msgq_params[id].name;
3118 fprintf(f, " %s", name);
3124 if (p->n_msgq_out) {
3127 fprintf(f, "msgq_out =");
3128 for (j = 0; j < p->n_msgq_out; j++) {
3129 uint32_t id = p->msgq_out[j];
3130 char *name = app->msgq_params[id].name;
3132 fprintf(f, " %s", name);
3138 fprintf(f, "timer_period = %" PRIu32 "\n", p->timer_period);
3144 for (j = 0; j < p->n_args; j++)
3145 fprintf(f, "%s = %s\n", p->args_name[j],
3154 app_config_save(struct app_params *app, const char *file_name)
3157 char *name, *dir_name;
3160 name = strdup(file_name);
3161 dir_name = dirname(name);
3162 status = access(dir_name, W_OK);
3163 APP_CHECK((status == 0),
3164 "Error: need write access privilege to directory "
3165 "\"%s\" to save configuration\n", dir_name);
3167 file = fopen(file_name, "w");
3168 APP_CHECK((file != NULL),
3169 "Error: failed to save configuration to file \"%s\"",
3172 save_eal_params(app, file);
3173 save_pipeline_params(app, file);
3174 save_mempool_params(app, file);
3175 save_links_params(app, file);
3176 save_rxq_params(app, file);
3177 save_txq_params(app, file);
3178 save_swq_params(app, file);
3179 save_tm_params(app, file);
3180 save_tap_params(app, file);
3181 save_kni_params(app, file);
3182 save_source_params(app, file);
3183 save_sink_params(app, file);
3184 save_msgq_params(app, file);
3191 app_config_init(struct app_params *app)
3195 memcpy(app, &app_params_default, sizeof(struct app_params));
3197 for (i = 0; i < RTE_DIM(app->mempool_params); i++)
3198 memcpy(&app->mempool_params[i],
3199 &mempool_params_default,
3200 sizeof(struct app_mempool_params));
3202 for (i = 0; i < RTE_DIM(app->link_params); i++)
3203 memcpy(&app->link_params[i],
3204 &link_params_default,
3205 sizeof(struct app_link_params));
3207 for (i = 0; i < RTE_DIM(app->hwq_in_params); i++)
3208 memcpy(&app->hwq_in_params[i],
3209 &default_hwq_in_params,
3210 sizeof(default_hwq_in_params));
3212 for (i = 0; i < RTE_DIM(app->hwq_out_params); i++)
3213 memcpy(&app->hwq_out_params[i],
3214 &default_hwq_out_params,
3215 sizeof(default_hwq_out_params));
3217 for (i = 0; i < RTE_DIM(app->swq_params); i++)
3218 memcpy(&app->swq_params[i],
3219 &default_swq_params,
3220 sizeof(default_swq_params));
3222 for (i = 0; i < RTE_DIM(app->tm_params); i++)
3223 memcpy(&app->tm_params[i],
3225 sizeof(default_tm_params));
3227 for (i = 0; i < RTE_DIM(app->tap_params); i++)
3228 memcpy(&app->tap_params[i],
3229 &default_tap_params,
3230 sizeof(default_tap_params));
3232 for (i = 0; i < RTE_DIM(app->kni_params); i++)
3233 memcpy(&app->kni_params[i],
3234 &default_kni_params,
3235 sizeof(default_kni_params));
3237 for (i = 0; i < RTE_DIM(app->source_params); i++)
3238 memcpy(&app->source_params[i],
3239 &default_source_params,
3240 sizeof(default_source_params));
3242 for (i = 0; i < RTE_DIM(app->sink_params); i++)
3243 memcpy(&app->sink_params[i],
3244 &default_sink_params,
3245 sizeof(default_sink_params));
3247 for (i = 0; i < RTE_DIM(app->msgq_params); i++)
3248 memcpy(&app->msgq_params[i],
3249 &default_msgq_params,
3250 sizeof(default_msgq_params));
3252 for (i = 0; i < RTE_DIM(app->pipeline_params); i++)
3253 memcpy(&app->pipeline_params[i],
3254 &default_pipeline_params,
3255 sizeof(default_pipeline_params));
3261 filenamedup(const char *filename, const char *suffix)
3263 char *s = malloc(strlen(filename) + strlen(suffix) + 1);
3268 sprintf(s, "%s%s", filename, suffix);
3273 app_config_args(struct app_params *app, int argc, char **argv)
3275 const char *optname;
3276 int opt, option_index;
3277 int f_present, s_present, p_present, l_present;
3278 int preproc_present, preproc_params_present;
3281 static struct option lgopts[] = {
3282 { "preproc", 1, 0, 0 },
3283 { "preproc-args", 1, 0, 0 },
3287 /* Copy application name */
3288 strncpy(app->app_name, argv[0], APP_APPNAME_SIZE - 1);
3294 preproc_present = 0;
3295 preproc_params_present = 0;
3297 while ((opt = getopt_long(argc, argv, "f:s:p:l:", lgopts,
3298 &option_index)) != EOF)
3302 rte_panic("Error: Config file is provided "
3303 "more than once\n");
3306 if (!strlen(optarg))
3307 rte_panic("Error: Config file name is null\n");
3309 app->config_file = strdup(optarg);
3310 if (app->config_file == NULL)
3311 rte_panic("Error: Memory allocation failure\n");
3317 rte_panic("Error: Script file is provided "
3318 "more than once\n");
3321 if (!strlen(optarg))
3322 rte_panic("Error: Script file name is null\n");
3324 app->script_file = strdup(optarg);
3325 if (app->script_file == NULL)
3326 rte_panic("Error: Memory allocation failure\n");
3332 rte_panic("Error: PORT_MASK is provided "
3333 "more than once\n");
3336 if ((sscanf(optarg, "%" SCNx64 "%n", &app->port_mask,
3338 ((size_t) scaned != strlen(optarg)))
3339 rte_panic("Error: PORT_MASK is not "
3340 "a hexadecimal integer\n");
3342 if (app->port_mask == 0)
3343 rte_panic("Error: PORT_MASK is null\n");
3349 rte_panic("Error: LOG_LEVEL is provided "
3350 "more than once\n");
3353 if ((sscanf(optarg, "%" SCNu32 "%n", &app->log_level,
3355 ((size_t) scaned != strlen(optarg)) ||
3356 (app->log_level >= APP_LOG_LEVELS))
3357 rte_panic("Error: LOG_LEVEL invalid value\n");
3362 optname = lgopts[option_index].name;
3364 if (strcmp(optname, "preproc") == 0) {
3365 if (preproc_present)
3366 rte_panic("Error: Preprocessor argument "
3367 "is provided more than once\n");
3368 preproc_present = 1;
3370 app->preproc = strdup(optarg);
3374 if (strcmp(optname, "preproc-args") == 0) {
3375 if (preproc_params_present)
3376 rte_panic("Error: Preprocessor args "
3377 "are provided more than once\n");
3378 preproc_params_present = 1;
3380 app->preproc_args = strdup(optarg);
3384 app_print_usage(argv[0]);
3388 app_print_usage(argv[0]);
3391 optind = 1; /* reset getopt lib */
3393 /* Check dependencies between args */
3394 if (preproc_params_present && (preproc_present == 0))
3395 rte_panic("Error: Preprocessor args specified while "
3396 "preprocessor is not defined\n");
3398 app->parser_file = preproc_present ?
3399 filenamedup(app->config_file, ".preproc") :
3400 strdup(app->config_file);
3401 app->output_file = filenamedup(app->config_file, ".out");
3407 app_config_preproc(struct app_params *app)
3412 if (app->preproc == NULL)
3415 status = access(app->config_file, F_OK | R_OK);
3416 APP_CHECK((status == 0), "Error: Unable to open file %s",
3419 snprintf(buffer, sizeof(buffer), "%s %s %s > %s",
3421 app->preproc_args ? app->preproc_args : "",
3425 status = system(buffer);
3426 APP_CHECK((WIFEXITED(status) && (WEXITSTATUS(status) == 0)),
3427 "Error occurred while pre-processing file \"%s\"\n",