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 = 0, /* 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 if (strcmp(entry->name, "xen_dom0") == 0) {
816 PARSE_ERROR_DUPLICATE((p->xen_dom0_present == 0),
819 p->xen_dom0_present = 1;
821 val = parser_read_arg_bool(entry->value);
822 PARSE_ERROR((val >= 0), section_name, entry->name);
828 PARSE_ERROR_INVALID(0, section_name, entry->name);
835 parse_pipeline_pktq_in(struct app_params *app,
836 struct app_pipeline_params *p,
842 enum app_pktq_in_type type;
844 char *name = strtok_r(value, PARSE_DELIMITER, &value);
849 PARSE_ERROR_TOO_MANY_ELEMENTS(
850 (p->n_pktq_in < RTE_DIM(p->pktq_in)),
851 p->name, "pktq_in", (uint32_t)RTE_DIM(p->pktq_in));
853 if (validate_name(name, "RXQ", 2) == 0) {
854 type = APP_PKTQ_IN_HWQ;
855 id = APP_PARAM_ADD(app->hwq_in_params, name);
856 APP_PARAM_ADD_LINK_FOR_RXQ(app, name);
857 } else if (validate_name(name, "SWQ", 1) == 0) {
858 type = APP_PKTQ_IN_SWQ;
859 id = APP_PARAM_ADD(app->swq_params, name);
860 } else if (validate_name(name, "TM", 1) == 0) {
861 type = APP_PKTQ_IN_TM;
862 id = APP_PARAM_ADD(app->tm_params, name);
863 APP_PARAM_ADD_LINK_FOR_TM(app, name);
864 } else if (validate_name(name, "TAP", 1) == 0) {
865 type = APP_PKTQ_IN_TAP;
866 id = APP_PARAM_ADD(app->tap_params, name);
867 } else if (validate_name(name, "KNI", 1) == 0) {
868 type = APP_PKTQ_IN_KNI;
869 id = APP_PARAM_ADD(app->kni_params, name);
870 APP_PARAM_ADD_LINK_FOR_KNI(app, name);
871 } else if (validate_name(name, "SOURCE", 1) == 0) {
872 type = APP_PKTQ_IN_SOURCE;
873 id = APP_PARAM_ADD(app->source_params, name);
875 PARSE_ERROR_INVALID_ELEMENT(0,
876 p->name, "pktq_in", name);
878 p->pktq_in[p->n_pktq_in].type = type;
879 p->pktq_in[p->n_pktq_in].id = (uint32_t) id;
883 PARSE_ERROR_NO_ELEMENTS((p->n_pktq_in > 0), p->name, "pktq_in");
887 parse_pipeline_pktq_out(struct app_params *app,
888 struct app_pipeline_params *p,
894 enum app_pktq_out_type type;
896 char *name = strtok_r(value, PARSE_DELIMITER, &value);
901 PARSE_ERROR_TOO_MANY_ELEMENTS(
902 (p->n_pktq_out < RTE_DIM(p->pktq_out)),
903 p->name, "pktq_out", (uint32_t)RTE_DIM(p->pktq_out));
905 if (validate_name(name, "TXQ", 2) == 0) {
906 type = APP_PKTQ_OUT_HWQ;
907 id = APP_PARAM_ADD(app->hwq_out_params, name);
908 APP_PARAM_ADD_LINK_FOR_TXQ(app, name);
909 } else if (validate_name(name, "SWQ", 1) == 0) {
910 type = APP_PKTQ_OUT_SWQ;
911 id = APP_PARAM_ADD(app->swq_params, name);
912 } else if (validate_name(name, "TM", 1) == 0) {
913 type = APP_PKTQ_OUT_TM;
914 id = APP_PARAM_ADD(app->tm_params, name);
915 APP_PARAM_ADD_LINK_FOR_TM(app, name);
916 } else if (validate_name(name, "TAP", 1) == 0) {
917 type = APP_PKTQ_OUT_TAP;
918 id = APP_PARAM_ADD(app->tap_params, name);
919 } else if (validate_name(name, "KNI", 1) == 0) {
920 type = APP_PKTQ_OUT_KNI;
921 id = APP_PARAM_ADD(app->kni_params, name);
922 APP_PARAM_ADD_LINK_FOR_KNI(app, name);
923 } else if (validate_name(name, "SINK", 1) == 0) {
924 type = APP_PKTQ_OUT_SINK;
925 id = APP_PARAM_ADD(app->sink_params, name);
927 PARSE_ERROR_INVALID_ELEMENT(0,
928 p->name, "pktq_out", name);
930 p->pktq_out[p->n_pktq_out].type = type;
931 p->pktq_out[p->n_pktq_out].id = id;
935 PARSE_ERROR_NO_ELEMENTS((p->n_pktq_out > 0), p->name, "pktq_out");
939 parse_pipeline_msgq_in(struct app_params *app,
940 struct app_pipeline_params *p,
947 char *name = strtok_r(value, PARSE_DELIMITER, &value);
952 PARSE_ERROR_TOO_MANY_ELEMENTS(
953 (p->n_msgq_in < RTE_DIM(p->msgq_in)),
954 p->name, "msgq_in", (uint32_t)(RTE_DIM(p->msgq_in)));
956 PARSE_ERROR_INVALID_ELEMENT(
957 (validate_name(name, "MSGQ", 1) == 0),
958 p->name, "msgq_in", name);
960 idx = APP_PARAM_ADD(app->msgq_params, name);
961 p->msgq_in[p->n_msgq_in] = idx;
965 PARSE_ERROR_NO_ELEMENTS((p->n_msgq_in > 0), p->name, "msgq_in");
969 parse_pipeline_msgq_out(struct app_params *app,
970 struct app_pipeline_params *p,
977 char *name = strtok_r(value, PARSE_DELIMITER, &value);
982 PARSE_ERROR_TOO_MANY_ELEMENTS(
983 (p->n_msgq_out < RTE_DIM(p->msgq_out)),
984 p->name, "msgq_out", (uint32_t)RTE_DIM(p->msgq_out));
986 PARSE_ERROR_INVALID_ELEMENT(
987 (validate_name(name, "MSGQ", 1) == 0),
988 p->name, "msgq_out", name);
990 idx = APP_PARAM_ADD(app->msgq_params, name);
991 p->msgq_out[p->n_msgq_out] = idx;
995 PARSE_ERROR_NO_ELEMENTS((p->n_msgq_out > 0), p->name, "msgq_out");
999 parse_pipeline(struct app_params *app,
1000 const char *section_name,
1001 struct rte_cfgfile *cfg)
1003 char name[CFG_NAME_LEN];
1004 struct app_pipeline_params *param;
1005 struct rte_cfgfile_entry *entries;
1009 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1010 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1012 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1013 PARSE_ERROR_MALLOC(entries != NULL);
1015 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1017 param_idx = APP_PARAM_ADD(app->pipeline_params, section_name);
1018 param = &app->pipeline_params[param_idx];
1019 PARSE_CHECK_DUPLICATE_SECTION(param);
1021 for (i = 0; i < n_entries; i++) {
1022 struct rte_cfgfile_entry *ent = &entries[i];
1024 if (strcmp(ent->name, "type") == 0) {
1025 int w_size = snprintf(param->type, RTE_DIM(param->type),
1028 PARSE_ERROR(((w_size > 0) &&
1029 (w_size < (int)RTE_DIM(param->type))),
1035 if (strcmp(ent->name, "core") == 0) {
1036 int status = parse_pipeline_core(
1037 ¶m->socket_id, ¶m->core_id,
1038 ¶m->hyper_th_id, ent->value);
1040 PARSE_ERROR((status == 0), section_name,
1045 if (strcmp(ent->name, "pktq_in") == 0) {
1046 parse_pipeline_pktq_in(app, param, ent->value);
1051 if (strcmp(ent->name, "pktq_out") == 0) {
1052 parse_pipeline_pktq_out(app, param, ent->value);
1057 if (strcmp(ent->name, "msgq_in") == 0) {
1058 parse_pipeline_msgq_in(app, param, ent->value);
1063 if (strcmp(ent->name, "msgq_out") == 0) {
1064 parse_pipeline_msgq_out(app, param, ent->value);
1069 if (strcmp(ent->name, "timer_period") == 0) {
1070 int status = parser_read_uint32(
1071 ¶m->timer_period,
1074 PARSE_ERROR((status == 0), section_name,
1079 /* pipeline type specific items */
1080 APP_CHECK((param->n_args < APP_MAX_PIPELINE_ARGS),
1081 "Parse error in section \"%s\": too many "
1082 "pipeline specified parameters", section_name);
1084 param->args_name[param->n_args] = strdup(ent->name);
1085 param->args_value[param->n_args] = strdup(ent->value);
1087 APP_CHECK((param->args_name[param->n_args] != NULL) &&
1088 (param->args_value[param->n_args] != NULL),
1089 "Parse error: no free memory");
1094 snprintf(name, sizeof(name), "MSGQ-REQ-%s", section_name);
1095 param_idx = APP_PARAM_ADD(app->msgq_params, name);
1096 app->msgq_params[param_idx].cpu_socket_id = param->socket_id;
1097 param->msgq_in[param->n_msgq_in++] = param_idx;
1099 snprintf(name, sizeof(name), "MSGQ-RSP-%s", section_name);
1100 param_idx = APP_PARAM_ADD(app->msgq_params, name);
1101 app->msgq_params[param_idx].cpu_socket_id = param->socket_id;
1102 param->msgq_out[param->n_msgq_out++] = param_idx;
1104 snprintf(name, sizeof(name), "MSGQ-REQ-CORE-s%" PRIu32 "c%" PRIu32 "%s",
1107 (param->hyper_th_id) ? "h" : "");
1108 param_idx = APP_PARAM_ADD(app->msgq_params, name);
1109 app->msgq_params[param_idx].cpu_socket_id = param->socket_id;
1111 snprintf(name, sizeof(name), "MSGQ-RSP-CORE-s%" PRIu32 "c%" PRIu32 "%s",
1114 (param->hyper_th_id) ? "h" : "");
1115 param_idx = APP_PARAM_ADD(app->msgq_params, name);
1116 app->msgq_params[param_idx].cpu_socket_id = param->socket_id;
1122 parse_mempool(struct app_params *app,
1123 const char *section_name,
1124 struct rte_cfgfile *cfg)
1126 struct app_mempool_params *param;
1127 struct rte_cfgfile_entry *entries;
1131 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1132 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1134 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1135 PARSE_ERROR_MALLOC(entries != NULL);
1137 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1139 param_idx = APP_PARAM_ADD(app->mempool_params, section_name);
1140 param = &app->mempool_params[param_idx];
1141 PARSE_CHECK_DUPLICATE_SECTION(param);
1143 for (i = 0; i < n_entries; i++) {
1144 struct rte_cfgfile_entry *ent = &entries[i];
1146 if (strcmp(ent->name, "buffer_size") == 0) {
1147 int status = parser_read_uint32(
1148 ¶m->buffer_size, ent->value);
1150 PARSE_ERROR((status == 0), section_name,
1155 if (strcmp(ent->name, "pool_size") == 0) {
1156 int status = parser_read_uint32(
1157 ¶m->pool_size, ent->value);
1159 PARSE_ERROR((status == 0), section_name,
1164 if (strcmp(ent->name, "cache_size") == 0) {
1165 int status = parser_read_uint32(
1166 ¶m->cache_size, ent->value);
1168 PARSE_ERROR((status == 0), section_name,
1173 if (strcmp(ent->name, "cpu") == 0) {
1174 int status = parser_read_uint32(
1175 ¶m->cpu_socket_id, ent->value);
1177 PARSE_ERROR((status == 0), section_name,
1183 PARSE_ERROR_INVALID(0, section_name, ent->name);
1190 parse_link_rss_qs(struct app_link_params *p,
1196 char *token = strtok_r(value, PARSE_DELIMITER, &value);
1201 if (p->n_rss_qs == RTE_DIM(p->rss_qs))
1204 if (parser_read_uint32(&p->rss_qs[p->n_rss_qs++], token))
1212 parse_link_rss_proto_ipv4(struct app_link_params *p,
1218 char *token = strtok_r(value, PARSE_DELIMITER, &value);
1223 if (strcmp(token, "IP") == 0) {
1224 mask |= ETH_RSS_IPV4;
1227 if (strcmp(token, "FRAG") == 0) {
1228 mask |= ETH_RSS_FRAG_IPV4;
1231 if (strcmp(token, "TCP") == 0) {
1232 mask |= ETH_RSS_NONFRAG_IPV4_TCP;
1235 if (strcmp(token, "UDP") == 0) {
1236 mask |= ETH_RSS_NONFRAG_IPV4_UDP;
1239 if (strcmp(token, "SCTP") == 0) {
1240 mask |= ETH_RSS_NONFRAG_IPV4_SCTP;
1243 if (strcmp(token, "OTHER") == 0) {
1244 mask |= ETH_RSS_NONFRAG_IPV4_OTHER;
1250 p->rss_proto_ipv4 = mask;
1255 parse_link_rss_proto_ipv6(struct app_link_params *p,
1261 char *token = strtok_r(value, PARSE_DELIMITER, &value);
1266 if (strcmp(token, "IP") == 0) {
1267 mask |= ETH_RSS_IPV6;
1270 if (strcmp(token, "FRAG") == 0) {
1271 mask |= ETH_RSS_FRAG_IPV6;
1274 if (strcmp(token, "TCP") == 0) {
1275 mask |= ETH_RSS_NONFRAG_IPV6_TCP;
1278 if (strcmp(token, "UDP") == 0) {
1279 mask |= ETH_RSS_NONFRAG_IPV6_UDP;
1282 if (strcmp(token, "SCTP") == 0) {
1283 mask |= ETH_RSS_NONFRAG_IPV6_SCTP;
1286 if (strcmp(token, "OTHER") == 0) {
1287 mask |= ETH_RSS_NONFRAG_IPV6_OTHER;
1290 if (strcmp(token, "IP_EX") == 0) {
1291 mask |= ETH_RSS_IPV6_EX;
1294 if (strcmp(token, "TCP_EX") == 0) {
1295 mask |= ETH_RSS_IPV6_TCP_EX;
1298 if (strcmp(token, "UDP_EX") == 0) {
1299 mask |= ETH_RSS_IPV6_UDP_EX;
1305 p->rss_proto_ipv6 = mask;
1310 parse_link_rss_proto_l2(struct app_link_params *p,
1316 char *token = strtok_r(value, PARSE_DELIMITER, &value);
1321 if (strcmp(token, "L2") == 0) {
1322 mask |= ETH_RSS_L2_PAYLOAD;
1328 p->rss_proto_l2 = mask;
1333 parse_link(struct app_params *app,
1334 const char *section_name,
1335 struct rte_cfgfile *cfg)
1337 struct app_link_params *param;
1338 struct rte_cfgfile_entry *entries;
1340 int rss_qs_present = 0;
1341 int rss_proto_ipv4_present = 0;
1342 int rss_proto_ipv6_present = 0;
1343 int rss_proto_l2_present = 0;
1344 int pci_bdf_present = 0;
1347 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1348 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1350 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1351 PARSE_ERROR_MALLOC(entries != NULL);
1353 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1355 param_idx = APP_PARAM_ADD(app->link_params, section_name);
1356 param = &app->link_params[param_idx];
1357 PARSE_CHECK_DUPLICATE_SECTION(param);
1359 for (i = 0; i < n_entries; i++) {
1360 struct rte_cfgfile_entry *ent = &entries[i];
1362 if (strcmp(ent->name, "promisc") == 0) {
1363 int status = parser_read_arg_bool(ent->value);
1365 PARSE_ERROR((status != -EINVAL), section_name,
1367 param->promisc = status;
1371 if (strcmp(ent->name, "arp_q") == 0) {
1372 int status = parser_read_uint32(¶m->arp_q,
1375 PARSE_ERROR((status == 0), section_name,
1380 if (strcmp(ent->name, "tcp_syn_q") == 0) {
1381 int status = parser_read_uint32(
1382 ¶m->tcp_syn_q, ent->value);
1384 PARSE_ERROR((status == 0), section_name, ent->name);
1388 if (strcmp(ent->name, "ip_local_q") == 0) {
1389 int status = parser_read_uint32(
1390 ¶m->ip_local_q, ent->value);
1392 PARSE_ERROR((status == 0), section_name,
1397 if (strcmp(ent->name, "tcp_local_q") == 0) {
1398 int status = parser_read_uint32(
1399 ¶m->tcp_local_q, ent->value);
1401 PARSE_ERROR((status == 0), section_name,
1406 if (strcmp(ent->name, "udp_local_q") == 0) {
1407 int status = parser_read_uint32(
1408 ¶m->udp_local_q, ent->value);
1410 PARSE_ERROR((status == 0), section_name,
1415 if (strcmp(ent->name, "sctp_local_q") == 0) {
1416 int status = parser_read_uint32(
1417 ¶m->sctp_local_q, ent->value);
1419 PARSE_ERROR((status == 0), section_name,
1424 if (strcmp(ent->name, "rss_qs") == 0) {
1425 int status = parse_link_rss_qs(param, ent->value);
1427 PARSE_ERROR((status == 0), section_name,
1433 if (strcmp(ent->name, "rss_proto_ipv4") == 0) {
1435 parse_link_rss_proto_ipv4(param, ent->value);
1437 PARSE_ERROR((status != -EINVAL), section_name,
1439 rss_proto_ipv4_present = 1;
1443 if (strcmp(ent->name, "rss_proto_ipv6") == 0) {
1445 parse_link_rss_proto_ipv6(param, ent->value);
1447 PARSE_ERROR((status != -EINVAL), section_name,
1449 rss_proto_ipv6_present = 1;
1453 if (strcmp(ent->name, "rss_proto_l2") == 0) {
1454 int status = parse_link_rss_proto_l2(param, ent->value);
1456 PARSE_ERROR((status != -EINVAL), section_name,
1458 rss_proto_l2_present = 1;
1462 if (strcmp(ent->name, "pci_bdf") == 0) {
1463 PARSE_ERROR_DUPLICATE((pci_bdf_present == 0),
1464 section_name, ent->name);
1466 snprintf(param->pci_bdf, APP_LINK_PCI_BDF_SIZE,
1468 pci_bdf_present = 1;
1473 PARSE_ERROR_INVALID(0, section_name, ent->name);
1476 /* Check for mandatory fields */
1478 PARSE_ERROR_MESSAGE((pci_bdf_present == 0),
1479 section_name, "pci_bdf",
1480 "entry not allowed (port_mask is provided)");
1482 PARSE_ERROR_MESSAGE((pci_bdf_present),
1483 section_name, "pci_bdf",
1484 "this entry is mandatory (port_mask is not "
1487 if (rss_proto_ipv4_present)
1488 PARSE_ERROR_MESSAGE((rss_qs_present),
1489 section_name, "rss_proto_ipv4",
1490 "entry not allowed (rss_qs entry is not provided)");
1491 if (rss_proto_ipv6_present)
1492 PARSE_ERROR_MESSAGE((rss_qs_present),
1493 section_name, "rss_proto_ipv6",
1494 "entry not allowed (rss_qs entry is not provided)");
1495 if (rss_proto_l2_present)
1496 PARSE_ERROR_MESSAGE((rss_qs_present),
1497 section_name, "rss_proto_l2",
1498 "entry not allowed (rss_qs entry is not provided)");
1499 if (rss_proto_ipv4_present |
1500 rss_proto_ipv6_present |
1501 rss_proto_l2_present){
1502 if (rss_proto_ipv4_present == 0)
1503 param->rss_proto_ipv4 = 0;
1504 if (rss_proto_ipv6_present == 0)
1505 param->rss_proto_ipv6 = 0;
1506 if (rss_proto_l2_present == 0)
1507 param->rss_proto_l2 = 0;
1514 parse_rxq(struct app_params *app,
1515 const char *section_name,
1516 struct rte_cfgfile *cfg)
1518 struct app_pktq_hwq_in_params *param;
1519 struct rte_cfgfile_entry *entries;
1523 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1524 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1526 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1527 PARSE_ERROR_MALLOC(entries != NULL);
1529 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1531 param_idx = APP_PARAM_ADD(app->hwq_in_params, section_name);
1532 param = &app->hwq_in_params[param_idx];
1533 PARSE_CHECK_DUPLICATE_SECTION(param);
1535 APP_PARAM_ADD_LINK_FOR_RXQ(app, section_name);
1537 for (i = 0; i < n_entries; i++) {
1538 struct rte_cfgfile_entry *ent = &entries[i];
1540 if (strcmp(ent->name, "mempool") == 0) {
1541 int status = validate_name(ent->value,
1545 PARSE_ERROR((status == 0), section_name,
1548 idx = APP_PARAM_ADD(app->mempool_params, ent->value);
1549 param->mempool_id = idx;
1553 if (strcmp(ent->name, "size") == 0) {
1554 int status = parser_read_uint32(¶m->size,
1557 PARSE_ERROR((status == 0), section_name,
1562 if (strcmp(ent->name, "burst") == 0) {
1563 int status = parser_read_uint32(¶m->burst,
1566 PARSE_ERROR((status == 0), section_name,
1572 PARSE_ERROR_INVALID(0, section_name, ent->name);
1579 parse_txq(struct app_params *app,
1580 const char *section_name,
1581 struct rte_cfgfile *cfg)
1583 struct app_pktq_hwq_out_params *param;
1584 struct rte_cfgfile_entry *entries;
1588 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1589 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1591 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1592 PARSE_ERROR_MALLOC(entries != NULL);
1594 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1596 param_idx = APP_PARAM_ADD(app->hwq_out_params, section_name);
1597 param = &app->hwq_out_params[param_idx];
1598 PARSE_CHECK_DUPLICATE_SECTION(param);
1600 APP_PARAM_ADD_LINK_FOR_TXQ(app, section_name);
1602 for (i = 0; i < n_entries; i++) {
1603 struct rte_cfgfile_entry *ent = &entries[i];
1605 if (strcmp(ent->name, "size") == 0) {
1606 int status = parser_read_uint32(¶m->size,
1609 PARSE_ERROR((status == 0), section_name,
1614 if (strcmp(ent->name, "burst") == 0) {
1615 int status = parser_read_uint32(¶m->burst,
1618 PARSE_ERROR((status == 0), section_name,
1623 if (strcmp(ent->name, "dropless") == 0) {
1624 int status = parser_read_arg_bool(ent->value);
1627 PARSE_ERROR((status != -EINVAL), section_name,
1629 param->dropless = status;
1633 if (strcmp(ent->name, "n_retries") == 0) {
1634 int status = parser_read_uint64(¶m->n_retries,
1637 PARSE_ERROR((status == 0), section_name,
1643 PARSE_ERROR_INVALID(0, section_name, ent->name);
1650 parse_swq(struct app_params *app,
1651 const char *section_name,
1652 struct rte_cfgfile *cfg)
1654 struct app_pktq_swq_params *param;
1655 struct rte_cfgfile_entry *entries;
1657 uint32_t mtu_present = 0;
1658 uint32_t metadata_size_present = 0;
1659 uint32_t mempool_direct_present = 0;
1660 uint32_t mempool_indirect_present = 0;
1664 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1665 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1667 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1668 PARSE_ERROR_MALLOC(entries != NULL);
1670 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1672 param_idx = APP_PARAM_ADD(app->swq_params, section_name);
1673 param = &app->swq_params[param_idx];
1674 PARSE_CHECK_DUPLICATE_SECTION(param);
1676 for (i = 0; i < n_entries; i++) {
1677 struct rte_cfgfile_entry *ent = &entries[i];
1679 if (strcmp(ent->name, "size") == 0) {
1680 int status = parser_read_uint32(¶m->size,
1683 PARSE_ERROR((status == 0), section_name,
1688 if (strcmp(ent->name, "burst_read") == 0) {
1689 int status = parser_read_uint32(&
1690 param->burst_read, ent->value);
1692 PARSE_ERROR((status == 0), section_name,
1697 if (strcmp(ent->name, "burst_write") == 0) {
1698 int status = parser_read_uint32(
1699 ¶m->burst_write, ent->value);
1701 PARSE_ERROR((status == 0), section_name,
1706 if (strcmp(ent->name, "dropless") == 0) {
1707 int status = parser_read_arg_bool(ent->value);
1709 PARSE_ERROR((status != -EINVAL), section_name,
1711 param->dropless = status;
1715 if (strcmp(ent->name, "n_retries") == 0) {
1716 int status = parser_read_uint64(¶m->n_retries,
1719 PARSE_ERROR((status == 0), section_name,
1724 if (strcmp(ent->name, "cpu") == 0) {
1725 int status = parser_read_uint32(
1726 ¶m->cpu_socket_id, ent->value);
1728 PARSE_ERROR((status == 0), section_name, ent->name);
1732 if (strcmp(ent->name, "ipv4_frag") == 0) {
1733 int status = parser_read_arg_bool(ent->value);
1735 PARSE_ERROR((status != -EINVAL), section_name,
1738 param->ipv4_frag = status;
1739 if (param->mtu == 0)
1745 if (strcmp(ent->name, "ipv6_frag") == 0) {
1746 int status = parser_read_arg_bool(ent->value);
1748 PARSE_ERROR((status != -EINVAL), section_name,
1750 param->ipv6_frag = status;
1751 if (param->mtu == 0)
1756 if (strcmp(ent->name, "ipv4_ras") == 0) {
1757 int status = parser_read_arg_bool(ent->value);
1759 PARSE_ERROR((status != -EINVAL), section_name,
1761 param->ipv4_ras = status;
1765 if (strcmp(ent->name, "ipv6_ras") == 0) {
1766 int status = parser_read_arg_bool(ent->value);
1768 PARSE_ERROR((status != -EINVAL), section_name,
1770 param->ipv6_ras = status;
1774 if (strcmp(ent->name, "mtu") == 0) {
1775 int status = parser_read_uint32(¶m->mtu,
1778 PARSE_ERROR((status == 0), section_name,
1784 if (strcmp(ent->name, "metadata_size") == 0) {
1785 int status = parser_read_uint32(
1786 ¶m->metadata_size, ent->value);
1788 PARSE_ERROR((status == 0), section_name,
1790 metadata_size_present = 1;
1794 if (strcmp(ent->name, "mempool_direct") == 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_direct_id = idx;
1805 mempool_direct_present = 1;
1809 if (strcmp(ent->name, "mempool_indirect") == 0) {
1810 int status = validate_name(ent->value,
1814 PARSE_ERROR((status == 0), section_name,
1817 idx = APP_PARAM_ADD(app->mempool_params, ent->value);
1818 param->mempool_indirect_id = idx;
1820 mempool_indirect_present = 1;
1825 PARSE_ERROR_INVALID(0, section_name, ent->name);
1828 APP_CHECK(((mtu_present == 0) ||
1829 ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))),
1830 "Parse error in section \"%s\": IPv4/IPv6 fragmentation "
1831 "is off, therefore entry \"mtu\" is not allowed",
1834 APP_CHECK(((metadata_size_present == 0) ||
1835 ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))),
1836 "Parse error in section \"%s\": IPv4/IPv6 fragmentation "
1837 "is off, therefore entry \"metadata_size\" is "
1838 "not allowed", section_name);
1840 APP_CHECK(((mempool_direct_present == 0) ||
1841 ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))),
1842 "Parse error in section \"%s\": IPv4/IPv6 fragmentation "
1843 "is off, therefore entry \"mempool_direct\" is "
1844 "not allowed", section_name);
1846 APP_CHECK(((mempool_indirect_present == 0) ||
1847 ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))),
1848 "Parse error in section \"%s\": IPv4/IPv6 fragmentation "
1849 "is off, therefore entry \"mempool_indirect\" is "
1850 "not allowed", section_name);
1856 parse_tm(struct app_params *app,
1857 const char *section_name,
1858 struct rte_cfgfile *cfg)
1860 struct app_pktq_tm_params *param;
1861 struct rte_cfgfile_entry *entries;
1865 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1866 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1868 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1869 PARSE_ERROR_MALLOC(entries != NULL);
1871 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1873 param_idx = APP_PARAM_ADD(app->tm_params, section_name);
1874 param = &app->tm_params[param_idx];
1875 PARSE_CHECK_DUPLICATE_SECTION(param);
1877 APP_PARAM_ADD_LINK_FOR_TM(app, section_name);
1879 for (i = 0; i < n_entries; i++) {
1880 struct rte_cfgfile_entry *ent = &entries[i];
1882 if (strcmp(ent->name, "cfg") == 0) {
1883 param->file_name = strdup(ent->value);
1884 PARSE_ERROR_MALLOC(param->file_name != NULL);
1888 if (strcmp(ent->name, "burst_read") == 0) {
1889 int status = parser_read_uint32(
1890 ¶m->burst_read, ent->value);
1892 PARSE_ERROR((status == 0), section_name,
1897 if (strcmp(ent->name, "burst_write") == 0) {
1898 int status = parser_read_uint32(
1899 ¶m->burst_write, ent->value);
1901 PARSE_ERROR((status == 0), section_name,
1907 PARSE_ERROR_INVALID(0, section_name, ent->name);
1914 parse_tap(struct app_params *app,
1915 const char *section_name,
1916 struct rte_cfgfile *cfg)
1918 struct app_pktq_tap_params *param;
1919 struct rte_cfgfile_entry *entries;
1923 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
1924 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
1926 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
1927 PARSE_ERROR_MALLOC(entries != NULL);
1929 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
1931 param_idx = APP_PARAM_ADD(app->tap_params, section_name);
1932 param = &app->tap_params[param_idx];
1933 PARSE_CHECK_DUPLICATE_SECTION(param);
1935 for (i = 0; i < n_entries; i++) {
1936 struct rte_cfgfile_entry *ent = &entries[i];
1938 if (strcmp(ent->name, "burst_read") == 0) {
1939 int status = parser_read_uint32(
1940 ¶m->burst_read, ent->value);
1942 PARSE_ERROR((status == 0), section_name,
1947 if (strcmp(ent->name, "burst_write") == 0) {
1948 int status = parser_read_uint32(
1949 ¶m->burst_write, ent->value);
1951 PARSE_ERROR((status == 0), section_name,
1956 if (strcmp(ent->name, "dropless") == 0) {
1957 int status = parser_read_arg_bool(ent->value);
1959 PARSE_ERROR((status != -EINVAL), section_name,
1961 param->dropless = status;
1965 if (strcmp(ent->name, "n_retries") == 0) {
1966 int status = parser_read_uint64(¶m->n_retries,
1969 PARSE_ERROR((status == 0), section_name,
1974 if (strcmp(ent->name, "mempool") == 0) {
1975 int status = validate_name(ent->value,
1979 PARSE_ERROR((status == 0), section_name,
1982 idx = APP_PARAM_ADD(app->mempool_params, ent->value);
1983 param->mempool_id = idx;
1989 PARSE_ERROR_INVALID(0, section_name, ent->name);
1996 parse_kni(struct app_params *app,
1997 const char *section_name,
1998 struct rte_cfgfile *cfg)
2000 struct app_pktq_kni_params *param;
2001 struct rte_cfgfile_entry *entries;
2005 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
2006 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
2008 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
2009 PARSE_ERROR_MALLOC(entries != NULL);
2011 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
2013 param_idx = APP_PARAM_ADD(app->kni_params, section_name);
2014 param = &app->kni_params[param_idx];
2015 PARSE_CHECK_DUPLICATE_SECTION(param);
2017 APP_PARAM_ADD_LINK_FOR_KNI(app, section_name);
2019 for (i = 0; i < n_entries; i++) {
2020 struct rte_cfgfile_entry *ent = &entries[i];
2022 if (strcmp(ent->name, "core") == 0) {
2023 int status = parse_pipeline_core(
2026 ¶m->hyper_th_id,
2029 PARSE_ERROR((status == 0), section_name,
2031 param->force_bind = 1;
2035 if (strcmp(ent->name, "mempool") == 0) {
2036 int status = validate_name(ent->value,
2040 PARSE_ERROR((status == 0), section_name,
2043 idx = APP_PARAM_ADD(app->mempool_params, ent->value);
2044 param->mempool_id = idx;
2048 if (strcmp(ent->name, "burst_read") == 0) {
2049 int status = parser_read_uint32(¶m->burst_read,
2052 PARSE_ERROR((status == 0), section_name,
2057 if (strcmp(ent->name, "burst_write") == 0) {
2058 int status = parser_read_uint32(¶m->burst_write,
2061 PARSE_ERROR((status == 0), section_name,
2066 if (strcmp(ent->name, "dropless") == 0) {
2067 int status = parser_read_arg_bool(ent->value);
2069 PARSE_ERROR((status != -EINVAL), section_name,
2071 param->dropless = status;
2075 if (strcmp(ent->name, "n_retries") == 0) {
2076 int status = parser_read_uint64(¶m->n_retries,
2079 PARSE_ERROR((status == 0), section_name,
2085 PARSE_ERROR_INVALID(0, section_name, ent->name);
2092 parse_source(struct app_params *app,
2093 const char *section_name,
2094 struct rte_cfgfile *cfg)
2096 struct app_pktq_source_params *param;
2097 struct rte_cfgfile_entry *entries;
2100 uint32_t pcap_file_present = 0;
2101 uint32_t pcap_size_present = 0;
2103 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
2104 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
2106 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
2107 PARSE_ERROR_MALLOC(entries != NULL);
2109 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
2111 param_idx = APP_PARAM_ADD(app->source_params, section_name);
2112 param = &app->source_params[param_idx];
2113 PARSE_CHECK_DUPLICATE_SECTION(param);
2115 for (i = 0; i < n_entries; i++) {
2116 struct rte_cfgfile_entry *ent = &entries[i];
2118 if (strcmp(ent->name, "mempool") == 0) {
2119 int status = validate_name(ent->value,
2123 PARSE_ERROR((status == 0), section_name,
2126 idx = APP_PARAM_ADD(app->mempool_params, ent->value);
2127 param->mempool_id = idx;
2131 if (strcmp(ent->name, "burst") == 0) {
2132 int status = parser_read_uint32(¶m->burst,
2135 PARSE_ERROR((status == 0), section_name,
2140 if (strcmp(ent->name, "pcap_file_rd") == 0) {
2141 PARSE_ERROR_DUPLICATE((pcap_file_present == 0),
2142 section_name, ent->name);
2144 param->file_name = strdup(ent->value);
2146 PARSE_ERROR_MALLOC(param->file_name != NULL);
2147 pcap_file_present = 1;
2152 if (strcmp(ent->name, "pcap_bytes_rd_per_pkt") == 0) {
2155 PARSE_ERROR_DUPLICATE((pcap_size_present == 0),
2156 section_name, ent->name);
2158 status = parser_read_uint32(
2159 ¶m->n_bytes_per_pkt, ent->value);
2161 PARSE_ERROR((status == 0), section_name,
2163 pcap_size_present = 1;
2169 PARSE_ERROR_INVALID(0, section_name, ent->name);
2176 parse_sink(struct app_params *app,
2177 const char *section_name,
2178 struct rte_cfgfile *cfg)
2180 struct app_pktq_sink_params *param;
2181 struct rte_cfgfile_entry *entries;
2184 uint32_t pcap_file_present = 0;
2185 uint32_t pcap_n_pkt_present = 0;
2187 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
2188 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
2190 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
2191 PARSE_ERROR_MALLOC(entries != NULL);
2193 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
2195 param_idx = APP_PARAM_ADD(app->sink_params, section_name);
2196 param = &app->sink_params[param_idx];
2197 PARSE_CHECK_DUPLICATE_SECTION(param);
2199 for (i = 0; i < n_entries; i++) {
2200 struct rte_cfgfile_entry *ent = &entries[i];
2202 if (strcmp(ent->name, "pcap_file_wr") == 0) {
2203 PARSE_ERROR_DUPLICATE((pcap_file_present == 0),
2204 section_name, ent->name);
2206 param->file_name = strdup(ent->value);
2208 PARSE_ERROR_MALLOC((param->file_name != NULL));
2213 if (strcmp(ent->name, "pcap_n_pkt_wr") == 0) {
2216 PARSE_ERROR_DUPLICATE((pcap_n_pkt_present == 0),
2217 section_name, ent->name);
2219 status = parser_read_uint32(
2220 ¶m->n_pkts_to_dump, ent->value);
2222 PARSE_ERROR((status == 0), section_name,
2229 PARSE_ERROR_INVALID(0, section_name, ent->name);
2236 parse_msgq_req_pipeline(struct app_params *app,
2237 const char *section_name,
2238 struct rte_cfgfile *cfg)
2240 struct app_msgq_params *param;
2241 struct rte_cfgfile_entry *entries;
2245 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
2246 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
2248 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
2249 PARSE_ERROR_MALLOC(entries != NULL);
2251 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
2253 param_idx = APP_PARAM_ADD(app->msgq_params, section_name);
2254 param = &app->msgq_params[param_idx];
2255 PARSE_CHECK_DUPLICATE_SECTION(param);
2257 for (i = 0; i < n_entries; i++) {
2258 struct rte_cfgfile_entry *ent = &entries[i];
2260 if (strcmp(ent->name, "size") == 0) {
2261 int status = parser_read_uint32(¶m->size,
2264 PARSE_ERROR((status == 0), section_name,
2270 PARSE_ERROR_INVALID(0, section_name, ent->name);
2277 parse_msgq_rsp_pipeline(struct app_params *app,
2278 const char *section_name,
2279 struct rte_cfgfile *cfg)
2281 struct app_msgq_params *param;
2282 struct rte_cfgfile_entry *entries;
2286 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
2287 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
2289 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
2290 PARSE_ERROR_MALLOC(entries != NULL);
2292 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
2294 param_idx = APP_PARAM_ADD(app->msgq_params, section_name);
2295 param = &app->msgq_params[param_idx];
2296 PARSE_CHECK_DUPLICATE_SECTION(param);
2298 for (i = 0; i < n_entries; i++) {
2299 struct rte_cfgfile_entry *ent = &entries[i];
2301 if (strcmp(ent->name, "size") == 0) {
2302 int status = parser_read_uint32(¶m->size,
2305 PARSE_ERROR((status == 0), section_name,
2311 PARSE_ERROR_INVALID(0, section_name, ent->name);
2318 parse_msgq(struct app_params *app,
2319 const char *section_name,
2320 struct rte_cfgfile *cfg)
2322 struct app_msgq_params *param;
2323 struct rte_cfgfile_entry *entries;
2327 n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
2328 PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
2330 entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
2331 PARSE_ERROR_MALLOC(entries != NULL);
2333 rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
2335 param_idx = APP_PARAM_ADD(app->msgq_params, section_name);
2336 param = &app->msgq_params[param_idx];
2337 PARSE_CHECK_DUPLICATE_SECTION(param);
2339 for (i = 0; i < n_entries; i++) {
2340 struct rte_cfgfile_entry *ent = &entries[i];
2342 if (strcmp(ent->name, "size") == 0) {
2343 int status = parser_read_uint32(¶m->size,
2346 PARSE_ERROR((status == 0), section_name,
2351 if (strcmp(ent->name, "cpu") == 0) {
2352 int status = parser_read_uint32(
2353 ¶m->cpu_socket_id, ent->value);
2355 PARSE_ERROR((status == 0), section_name,
2361 PARSE_ERROR_INVALID(0, section_name, ent->name);
2367 typedef void (*config_section_load)(struct app_params *p,
2368 const char *section_name,
2369 struct rte_cfgfile *cfg);
2371 struct config_section {
2372 const char prefix[CFG_NAME_LEN];
2374 config_section_load load;
2377 static const struct config_section cfg_file_scheme[] = {
2378 {"EAL", 0, parse_eal},
2379 {"PIPELINE", 1, parse_pipeline},
2380 {"MEMPOOL", 1, parse_mempool},
2381 {"LINK", 1, parse_link},
2382 {"RXQ", 2, parse_rxq},
2383 {"TXQ", 2, parse_txq},
2384 {"SWQ", 1, parse_swq},
2385 {"TM", 1, parse_tm},
2386 {"TAP", 1, parse_tap},
2387 {"KNI", 1, parse_kni},
2388 {"SOURCE", 1, parse_source},
2389 {"SINK", 1, parse_sink},
2390 {"MSGQ-REQ-PIPELINE", 1, parse_msgq_req_pipeline},
2391 {"MSGQ-RSP-PIPELINE", 1, parse_msgq_rsp_pipeline},
2392 {"MSGQ", 1, parse_msgq},
2396 create_implicit_mempools(struct app_params *app)
2398 APP_PARAM_ADD(app->mempool_params, "MEMPOOL0");
2402 create_implicit_links_from_port_mask(struct app_params *app,
2405 uint32_t pmd_id, link_id;
2408 for (pmd_id = 0; pmd_id < RTE_MAX_ETHPORTS; pmd_id++) {
2409 char name[APP_PARAM_NAME_SIZE];
2412 if ((port_mask & (1LLU << pmd_id)) == 0)
2415 snprintf(name, sizeof(name), "LINK%" PRIu32, link_id);
2416 idx = APP_PARAM_ADD(app->link_params, name);
2418 app->link_params[idx].pmd_id = pmd_id;
2424 assign_link_pmd_id_from_pci_bdf(struct app_params *app)
2428 for (i = 0; i < app->n_links; i++) {
2429 struct app_link_params *link = &app->link_params[i];
2431 APP_CHECK((strlen(link->pci_bdf)),
2432 "Parse error: %s pci_bdf is not configured "
2433 "(port_mask is not provided)",
2441 app_config_parse(struct app_params *app, const char *file_name)
2443 struct rte_cfgfile *cfg;
2444 char **section_names;
2445 int i, j, sect_count;
2447 /* Implicit mempools */
2448 create_implicit_mempools(app);
2452 create_implicit_links_from_port_mask(app, app->port_mask);
2454 /* Load application configuration file */
2455 cfg = rte_cfgfile_load(file_name, 0);
2456 APP_CHECK((cfg != NULL), "Parse error: Unable to load config "
2457 "file %s", file_name);
2459 sect_count = rte_cfgfile_num_sections(cfg, NULL, 0);
2460 APP_CHECK((sect_count > 0), "Parse error: number of sections "
2461 "in file \"%s\" return %d", file_name,
2464 section_names = malloc(sect_count * sizeof(char *));
2465 PARSE_ERROR_MALLOC(section_names != NULL);
2467 for (i = 0; i < sect_count; i++)
2468 section_names[i] = malloc(CFG_NAME_LEN);
2470 rte_cfgfile_sections(cfg, section_names, sect_count);
2472 for (i = 0; i < sect_count; i++) {
2473 const struct config_section *sch_s;
2474 int len, cfg_name_len;
2476 cfg_name_len = strlen(section_names[i]);
2478 /* Find section type */
2479 for (j = 0; j < (int)RTE_DIM(cfg_file_scheme); j++) {
2480 sch_s = &cfg_file_scheme[j];
2481 len = strlen(sch_s->prefix);
2483 if (cfg_name_len < len)
2486 /* After section name we expect only '\0' or digit or
2487 * digit dot digit, so protect against false matching,
2488 * for example: "ABC" should match section name
2489 * "ABC0.0", but it should not match section_name
2492 if ((section_names[i][len] != '\0') &&
2493 !isdigit(section_names[i][len]))
2496 if (strncmp(sch_s->prefix, section_names[i], len) == 0)
2500 APP_CHECK(j < (int)RTE_DIM(cfg_file_scheme),
2501 "Parse error: unknown section %s",
2504 APP_CHECK(validate_name(section_names[i],
2506 sch_s->numbers) == 0,
2507 "Parse error: invalid section name \"%s\"",
2510 sch_s->load(app, section_names[i], cfg);
2513 for (i = 0; i < sect_count; i++)
2514 free(section_names[i]);
2516 free(section_names);
2518 rte_cfgfile_close(cfg);
2520 APP_PARAM_COUNT(app->mempool_params, app->n_mempools);
2521 APP_PARAM_COUNT(app->link_params, app->n_links);
2522 APP_PARAM_COUNT(app->hwq_in_params, app->n_pktq_hwq_in);
2523 APP_PARAM_COUNT(app->hwq_out_params, app->n_pktq_hwq_out);
2524 APP_PARAM_COUNT(app->swq_params, app->n_pktq_swq);
2525 APP_PARAM_COUNT(app->tm_params, app->n_pktq_tm);
2526 APP_PARAM_COUNT(app->tap_params, app->n_pktq_tap);
2527 APP_PARAM_COUNT(app->kni_params, app->n_pktq_kni);
2528 APP_PARAM_COUNT(app->source_params, app->n_pktq_source);
2529 APP_PARAM_COUNT(app->sink_params, app->n_pktq_sink);
2530 APP_PARAM_COUNT(app->msgq_params, app->n_msgq);
2531 APP_PARAM_COUNT(app->pipeline_params, app->n_pipelines);
2533 if (app->port_mask == 0)
2534 assign_link_pmd_id_from_pci_bdf(app);
2536 /* Save configuration to output file */
2537 app_config_save(app, app->output_file);
2539 /* Load TM configuration files */
2540 app_config_parse_tm(app);
2546 save_eal_params(struct app_params *app, FILE *f)
2548 struct app_eal_params *p = &app->eal_params;
2551 fprintf(f, "[EAL]\n");
2554 fprintf(f, "%s = %s\n", "lcores", p->coremap);
2556 if (p->master_lcore_present)
2557 fprintf(f, "%s = %" PRIu32 "\n",
2558 "master_lcore", p->master_lcore);
2560 fprintf(f, "%s = %" PRIu32 "\n", "n", p->channels);
2562 if (p->memory_present)
2563 fprintf(f, "%s = %" PRIu32 "\n", "m", p->memory);
2565 if (p->ranks_present)
2566 fprintf(f, "%s = %" PRIu32 "\n", "r", p->ranks);
2568 for (i = 0; i < APP_MAX_LINKS; i++) {
2569 if (p->pci_blacklist[i] == NULL)
2572 fprintf(f, "%s = %s\n", "pci_blacklist",
2573 p->pci_blacklist[i]);
2576 for (i = 0; i < APP_MAX_LINKS; i++) {
2577 if (p->pci_whitelist[i] == NULL)
2580 fprintf(f, "%s = %s\n", "pci_whitelist",
2581 p->pci_whitelist[i]);
2584 for (i = 0; i < APP_MAX_LINKS; i++) {
2585 if (p->vdev[i] == NULL)
2588 fprintf(f, "%s = %s\n", "vdev",
2592 if (p->vmware_tsc_map_present)
2593 fprintf(f, "%s = %s\n", "vmware_tsc_map",
2594 (p->vmware_tsc_map) ? "yes" : "no");
2597 fprintf(f, "%s = %s\n", "proc_type", p->proc_type);
2600 fprintf(f, "%s = %s\n", "syslog", p->syslog);
2602 if (p->log_level_present)
2603 fprintf(f, "%s = %" PRIu32 "\n", "log_level", p->log_level);
2605 if (p->version_present)
2606 fprintf(f, "%s = %s\n", "v", (p->version) ? "yes" : "no");
2608 if (p->help_present)
2609 fprintf(f, "%s = %s\n", "help", (p->help) ? "yes" : "no");
2611 if (p->no_huge_present)
2612 fprintf(f, "%s = %s\n", "no_huge", (p->no_huge) ? "yes" : "no");
2614 if (p->no_pci_present)
2615 fprintf(f, "%s = %s\n", "no_pci", (p->no_pci) ? "yes" : "no");
2617 if (p->no_hpet_present)
2618 fprintf(f, "%s = %s\n", "no_hpet", (p->no_hpet) ? "yes" : "no");
2620 if (p->no_shconf_present)
2621 fprintf(f, "%s = %s\n", "no_shconf",
2622 (p->no_shconf) ? "yes" : "no");
2625 fprintf(f, "%s = %s\n", "d", p->add_driver);
2628 fprintf(f, "%s = %s\n", "socket_mem", p->socket_mem);
2631 fprintf(f, "%s = %s\n", "huge_dir", p->huge_dir);
2634 fprintf(f, "%s = %s\n", "file_prefix", p->file_prefix);
2636 if (p->base_virtaddr)
2637 fprintf(f, "%s = %s\n", "base_virtaddr", p->base_virtaddr);
2639 if (p->create_uio_dev_present)
2640 fprintf(f, "%s = %s\n", "create_uio_dev",
2641 (p->create_uio_dev) ? "yes" : "no");
2644 fprintf(f, "%s = %s\n", "vfio_intr", p->vfio_intr);
2646 if (p->xen_dom0_present)
2647 fprintf(f, "%s = %s\n", "xen_dom0",
2648 (p->xen_dom0) ? "yes" : "no");
2654 save_mempool_params(struct app_params *app, FILE *f)
2656 struct app_mempool_params *p;
2659 count = RTE_DIM(app->mempool_params);
2660 for (i = 0; i < count; i++) {
2661 p = &app->mempool_params[i];
2662 if (!APP_PARAM_VALID(p))
2665 fprintf(f, "[%s]\n", p->name);
2666 fprintf(f, "%s = %" PRIu32 "\n", "buffer_size", p->buffer_size);
2667 fprintf(f, "%s = %" PRIu32 "\n", "pool_size", p->pool_size);
2668 fprintf(f, "%s = %" PRIu32 "\n", "cache_size", p->cache_size);
2669 fprintf(f, "%s = %" PRIu32 "\n", "cpu", p->cpu_socket_id);
2676 save_links_params(struct app_params *app, FILE *f)
2678 struct app_link_params *p;
2681 count = RTE_DIM(app->link_params);
2682 for (i = 0; i < count; i++) {
2683 p = &app->link_params[i];
2684 if (!APP_PARAM_VALID(p))
2687 fprintf(f, "[%s]\n", p->name);
2688 fprintf(f, "; %s = %" PRIu32 "\n", "pmd_id", p->pmd_id);
2689 fprintf(f, "%s = %s\n", "promisc", p->promisc ? "yes" : "no");
2690 fprintf(f, "%s = %" PRIu32 "\n", "arp_q", p->arp_q);
2691 fprintf(f, "%s = %" PRIu32 "\n", "tcp_syn_q",
2693 fprintf(f, "%s = %" PRIu32 "\n", "ip_local_q", p->ip_local_q);
2694 fprintf(f, "%s = %" PRIu32 "\n", "tcp_local_q", p->tcp_local_q);
2695 fprintf(f, "%s = %" PRIu32 "\n", "udp_local_q", p->udp_local_q);
2696 fprintf(f, "%s = %" PRIu32 "\n", "sctp_local_q",
2703 fprintf(f, "rss_qs = ");
2704 for (j = 0; j < p->n_rss_qs; j++)
2705 fprintf(f, "%" PRIu32 " ", p->rss_qs[j]);
2708 /* rss_proto_ipv4 */
2709 if (p->rss_proto_ipv4) {
2710 fprintf(f, "rss_proto_ipv4 = ");
2711 if (p->rss_proto_ipv4 & ETH_RSS_IPV4)
2713 if (p->rss_proto_ipv4 & ETH_RSS_FRAG_IPV4)
2714 fprintf(f, "FRAG ");
2715 if (p->rss_proto_ipv4 &
2716 ETH_RSS_NONFRAG_IPV4_TCP)
2718 if (p->rss_proto_ipv4 &
2719 ETH_RSS_NONFRAG_IPV4_UDP)
2721 if (p->rss_proto_ipv4 &
2722 ETH_RSS_NONFRAG_IPV4_SCTP)
2723 fprintf(f, "SCTP ");
2724 if (p->rss_proto_ipv4 &
2725 ETH_RSS_NONFRAG_IPV4_OTHER)
2726 fprintf(f, "OTHER ");
2729 fprintf(f, "; rss_proto_ipv4 = <NONE>\n");
2731 /* rss_proto_ipv6 */
2732 if (p->rss_proto_ipv6) {
2733 fprintf(f, "rss_proto_ipv6 = ");
2734 if (p->rss_proto_ipv6 & ETH_RSS_IPV6)
2736 if (p->rss_proto_ipv6 & ETH_RSS_FRAG_IPV6)
2737 fprintf(f, "FRAG ");
2738 if (p->rss_proto_ipv6 &
2739 ETH_RSS_NONFRAG_IPV6_TCP)
2741 if (p->rss_proto_ipv6 &
2742 ETH_RSS_NONFRAG_IPV6_UDP)
2744 if (p->rss_proto_ipv6 &
2745 ETH_RSS_NONFRAG_IPV6_SCTP)
2746 fprintf(f, "SCTP ");
2747 if (p->rss_proto_ipv6 &
2748 ETH_RSS_NONFRAG_IPV6_OTHER)
2749 fprintf(f, "OTHER ");
2750 if (p->rss_proto_ipv6 & ETH_RSS_IPV6_EX)
2751 fprintf(f, "IP_EX ");
2752 if (p->rss_proto_ipv6 &
2753 ETH_RSS_IPV6_TCP_EX)
2754 fprintf(f, "TCP_EX ");
2755 if (p->rss_proto_ipv6 &
2756 ETH_RSS_IPV6_UDP_EX)
2757 fprintf(f, "UDP_EX ");
2760 fprintf(f, "; rss_proto_ipv6 = <NONE>\n");
2763 if (p->rss_proto_l2) {
2764 fprintf(f, "rss_proto_l2 = ");
2765 if (p->rss_proto_l2 & ETH_RSS_L2_PAYLOAD)
2769 fprintf(f, "; rss_proto_l2 = <NONE>\n");
2771 fprintf(f, "; rss_qs = <NONE>\n");
2772 fprintf(f, "; rss_proto_ipv4 = <NONE>\n");
2773 fprintf(f, "; rss_proto_ipv6 = <NONE>\n");
2774 fprintf(f, "; rss_proto_l2 = <NONE>\n");
2777 if (strlen(p->pci_bdf))
2778 fprintf(f, "%s = %s\n", "pci_bdf", p->pci_bdf);
2785 save_rxq_params(struct app_params *app, FILE *f)
2787 struct app_pktq_hwq_in_params *p;
2790 count = RTE_DIM(app->hwq_in_params);
2791 for (i = 0; i < count; i++) {
2792 p = &app->hwq_in_params[i];
2793 if (!APP_PARAM_VALID(p))
2796 fprintf(f, "[%s]\n", p->name);
2797 fprintf(f, "%s = %s\n",
2799 app->mempool_params[p->mempool_id].name);
2800 fprintf(f, "%s = %" PRIu32 "\n", "size", p->size);
2801 fprintf(f, "%s = %" PRIu32 "\n", "burst", p->burst);
2808 save_txq_params(struct app_params *app, FILE *f)
2810 struct app_pktq_hwq_out_params *p;
2813 count = RTE_DIM(app->hwq_out_params);
2814 for (i = 0; i < count; i++) {
2815 p = &app->hwq_out_params[i];
2816 if (!APP_PARAM_VALID(p))
2819 fprintf(f, "[%s]\n", p->name);
2820 fprintf(f, "%s = %" PRIu32 "\n", "size", p->size);
2821 fprintf(f, "%s = %" PRIu32 "\n", "burst", p->burst);
2822 fprintf(f, "%s = %s\n",
2824 p->dropless ? "yes" : "no");
2825 fprintf(f, "%s = %" PRIu64 "\n", "n_retries", p->n_retries);
2832 save_swq_params(struct app_params *app, FILE *f)
2834 struct app_pktq_swq_params *p;
2837 count = RTE_DIM(app->swq_params);
2838 for (i = 0; i < count; i++) {
2839 p = &app->swq_params[i];
2840 if (!APP_PARAM_VALID(p))
2843 fprintf(f, "[%s]\n", p->name);
2844 fprintf(f, "%s = %" PRIu32 "\n", "size", p->size);
2845 fprintf(f, "%s = %" PRIu32 "\n", "burst_read", p->burst_read);
2846 fprintf(f, "%s = %" PRIu32 "\n", "burst_write", p->burst_write);
2847 fprintf(f, "%s = %s\n", "dropless", p->dropless ? "yes" : "no");
2848 fprintf(f, "%s = %" PRIu64 "\n", "n_retries", p->n_retries);
2849 fprintf(f, "%s = %" PRIu32 "\n", "cpu", p->cpu_socket_id);
2850 fprintf(f, "%s = %s\n", "ipv4_frag", p->ipv4_frag ? "yes" : "no");
2851 fprintf(f, "%s = %s\n", "ipv6_frag", p->ipv6_frag ? "yes" : "no");
2852 fprintf(f, "%s = %s\n", "ipv4_ras", p->ipv4_ras ? "yes" : "no");
2853 fprintf(f, "%s = %s\n", "ipv6_ras", p->ipv6_ras ? "yes" : "no");
2854 if ((p->ipv4_frag == 1) || (p->ipv6_frag == 1)) {
2855 fprintf(f, "%s = %" PRIu32 "\n", "mtu", p->mtu);
2856 fprintf(f, "%s = %" PRIu32 "\n", "metadata_size", p->metadata_size);
2857 fprintf(f, "%s = %s\n",
2859 app->mempool_params[p->mempool_direct_id].name);
2860 fprintf(f, "%s = %s\n",
2862 app->mempool_params[p->mempool_indirect_id].name);
2870 save_tm_params(struct app_params *app, FILE *f)
2872 struct app_pktq_tm_params *p;
2875 count = RTE_DIM(app->tm_params);
2876 for (i = 0; i < count; i++) {
2877 p = &app->tm_params[i];
2878 if (!APP_PARAM_VALID(p))
2881 fprintf(f, "[%s]\n", p->name);
2882 fprintf(f, "%s = %s\n", "cfg", p->file_name);
2883 fprintf(f, "%s = %" PRIu32 "\n", "burst_read", p->burst_read);
2884 fprintf(f, "%s = %" PRIu32 "\n", "burst_write", p->burst_write);
2891 save_tap_params(struct app_params *app, FILE *f)
2893 struct app_pktq_tap_params *p;
2896 count = RTE_DIM(app->tap_params);
2897 for (i = 0; i < count; i++) {
2898 p = &app->tap_params[i];
2899 if (!APP_PARAM_VALID(p))
2902 fprintf(f, "[%s]\n", p->name);
2903 fprintf(f, "%s = %" PRIu32 "\n", "burst_read", p->burst_read);
2904 fprintf(f, "%s = %" PRIu32 "\n", "burst_write", p->burst_write);
2905 fprintf(f, "%s = %s\n", "dropless", p->dropless ? "yes" : "no");
2906 fprintf(f, "%s = %" PRIu64 "\n", "n_retries", p->n_retries);
2907 fprintf(f, "%s = %s\n", "mempool",
2908 app->mempool_params[p->mempool_id].name);
2915 save_kni_params(struct app_params *app, FILE *f)
2917 struct app_pktq_kni_params *p;
2920 count = RTE_DIM(app->kni_params);
2921 for (i = 0; i < count; i++) {
2922 p = &app->kni_params[i];
2923 if (!APP_PARAM_VALID(p))
2927 fprintf(f, "[%s]\n", p->name);
2930 if (p->force_bind) {
2931 fprintf(f, "; force_bind = 1\n");
2932 fprintf(f, "core = s%" PRIu32 "c%" PRIu32 "%s\n",
2935 (p->hyper_th_id) ? "h" : "");
2937 fprintf(f, "; force_bind = 0\n");
2940 fprintf(f, "%s = %s\n", "mempool",
2941 app->mempool_params[p->mempool_id].name);
2944 fprintf(f, "%s = %" PRIu32 "\n", "burst_read", p->burst_read);
2947 fprintf(f, "%s = %" PRIu32 "\n", "burst_write", p->burst_write);
2950 fprintf(f, "%s = %s\n",
2952 p->dropless ? "yes" : "no");
2955 fprintf(f, "%s = %" PRIu64 "\n", "n_retries", p->n_retries);
2962 save_source_params(struct app_params *app, FILE *f)
2964 struct app_pktq_source_params *p;
2967 count = RTE_DIM(app->source_params);
2968 for (i = 0; i < count; i++) {
2969 p = &app->source_params[i];
2970 if (!APP_PARAM_VALID(p))
2973 fprintf(f, "[%s]\n", p->name);
2974 fprintf(f, "%s = %s\n",
2976 app->mempool_params[p->mempool_id].name);
2977 fprintf(f, "%s = %" PRIu32 "\n", "burst", p->burst);
2978 fprintf(f, "%s = %s\n", "pcap_file_rd", p->file_name);
2979 fprintf(f, "%s = %" PRIu32 "\n", "pcap_bytes_rd_per_pkt",
2980 p->n_bytes_per_pkt);
2986 save_sink_params(struct app_params *app, FILE *f)
2988 struct app_pktq_sink_params *p;
2991 count = RTE_DIM(app->sink_params);
2992 for (i = 0; i < count; i++) {
2993 p = &app->sink_params[i];
2994 if (!APP_PARAM_VALID(p))
2997 fprintf(f, "[%s]\n", p->name);
2998 fprintf(f, "%s = %s\n", "pcap_file_wr", p->file_name);
2999 fprintf(f, "%s = %" PRIu32 "\n",
3000 "pcap_n_pkt_wr", p->n_pkts_to_dump);
3006 save_msgq_params(struct app_params *app, FILE *f)
3008 struct app_msgq_params *p;
3011 count = RTE_DIM(app->msgq_params);
3012 for (i = 0; i < count; i++) {
3013 p = &app->msgq_params[i];
3014 if (!APP_PARAM_VALID(p))
3017 fprintf(f, "[%s]\n", p->name);
3018 fprintf(f, "%s = %" PRIu32 "\n", "size", p->size);
3019 fprintf(f, "%s = %" PRIu32 "\n", "cpu", p->cpu_socket_id);
3026 save_pipeline_params(struct app_params *app, FILE *f)
3030 count = RTE_DIM(app->pipeline_params);
3031 for (i = 0; i < count; i++) {
3032 struct app_pipeline_params *p = &app->pipeline_params[i];
3034 if (!APP_PARAM_VALID(p))
3038 fprintf(f, "[%s]\n", p->name);
3041 fprintf(f, "type = %s\n", p->type);
3044 fprintf(f, "core = s%" PRIu32 "c%" PRIu32 "%s\n",
3047 (p->hyper_th_id) ? "h" : "");
3053 fprintf(f, "pktq_in =");
3054 for (j = 0; j < p->n_pktq_in; j++) {
3055 struct app_pktq_in_params *pp = &p->pktq_in[j];
3059 case APP_PKTQ_IN_HWQ:
3060 name = app->hwq_in_params[pp->id].name;
3062 case APP_PKTQ_IN_SWQ:
3063 name = app->swq_params[pp->id].name;
3065 case APP_PKTQ_IN_TM:
3066 name = app->tm_params[pp->id].name;
3068 case APP_PKTQ_IN_TAP:
3069 name = app->tap_params[pp->id].name;
3071 case APP_PKTQ_IN_KNI:
3072 name = app->kni_params[pp->id].name;
3074 case APP_PKTQ_IN_SOURCE:
3075 name = app->source_params[pp->id].name;
3078 APP_CHECK(0, "System error "
3079 "occurred while saving "
3080 "parameter to file");
3083 fprintf(f, " %s", name);
3089 if (p->n_pktq_out) {
3092 fprintf(f, "pktq_out =");
3093 for (j = 0; j < p->n_pktq_out; j++) {
3094 struct app_pktq_out_params *pp =
3099 case APP_PKTQ_OUT_HWQ:
3100 name = app->hwq_out_params[pp->id].name;
3102 case APP_PKTQ_OUT_SWQ:
3103 name = app->swq_params[pp->id].name;
3105 case APP_PKTQ_OUT_TM:
3106 name = app->tm_params[pp->id].name;
3108 case APP_PKTQ_OUT_TAP:
3109 name = app->tap_params[pp->id].name;
3111 case APP_PKTQ_OUT_KNI:
3112 name = app->kni_params[pp->id].name;
3114 case APP_PKTQ_OUT_SINK:
3115 name = app->sink_params[pp->id].name;
3118 APP_CHECK(0, "System error "
3119 "occurred while saving "
3120 "parameter to file");
3123 fprintf(f, " %s", name);
3132 fprintf(f, "msgq_in =");
3133 for (j = 0; j < p->n_msgq_in; j++) {
3134 uint32_t id = p->msgq_in[j];
3135 char *name = app->msgq_params[id].name;
3137 fprintf(f, " %s", name);
3143 if (p->n_msgq_out) {
3146 fprintf(f, "msgq_out =");
3147 for (j = 0; j < p->n_msgq_out; j++) {
3148 uint32_t id = p->msgq_out[j];
3149 char *name = app->msgq_params[id].name;
3151 fprintf(f, " %s", name);
3157 fprintf(f, "timer_period = %" PRIu32 "\n", p->timer_period);
3163 for (j = 0; j < p->n_args; j++)
3164 fprintf(f, "%s = %s\n", p->args_name[j],
3173 app_config_save(struct app_params *app, const char *file_name)
3176 char *name, *dir_name;
3179 name = strdup(file_name);
3180 dir_name = dirname(name);
3181 status = access(dir_name, W_OK);
3182 APP_CHECK((status == 0),
3183 "Error: need write access privilege to directory "
3184 "\"%s\" to save configuration\n", dir_name);
3186 file = fopen(file_name, "w");
3187 APP_CHECK((file != NULL),
3188 "Error: failed to save configuration to file \"%s\"",
3191 save_eal_params(app, file);
3192 save_pipeline_params(app, file);
3193 save_mempool_params(app, file);
3194 save_links_params(app, file);
3195 save_rxq_params(app, file);
3196 save_txq_params(app, file);
3197 save_swq_params(app, file);
3198 save_tm_params(app, file);
3199 save_tap_params(app, file);
3200 save_kni_params(app, file);
3201 save_source_params(app, file);
3202 save_sink_params(app, file);
3203 save_msgq_params(app, file);
3210 app_config_init(struct app_params *app)
3214 memcpy(app, &app_params_default, sizeof(struct app_params));
3216 for (i = 0; i < RTE_DIM(app->mempool_params); i++)
3217 memcpy(&app->mempool_params[i],
3218 &mempool_params_default,
3219 sizeof(struct app_mempool_params));
3221 for (i = 0; i < RTE_DIM(app->link_params); i++)
3222 memcpy(&app->link_params[i],
3223 &link_params_default,
3224 sizeof(struct app_link_params));
3226 for (i = 0; i < RTE_DIM(app->hwq_in_params); i++)
3227 memcpy(&app->hwq_in_params[i],
3228 &default_hwq_in_params,
3229 sizeof(default_hwq_in_params));
3231 for (i = 0; i < RTE_DIM(app->hwq_out_params); i++)
3232 memcpy(&app->hwq_out_params[i],
3233 &default_hwq_out_params,
3234 sizeof(default_hwq_out_params));
3236 for (i = 0; i < RTE_DIM(app->swq_params); i++)
3237 memcpy(&app->swq_params[i],
3238 &default_swq_params,
3239 sizeof(default_swq_params));
3241 for (i = 0; i < RTE_DIM(app->tm_params); i++)
3242 memcpy(&app->tm_params[i],
3244 sizeof(default_tm_params));
3246 for (i = 0; i < RTE_DIM(app->tap_params); i++)
3247 memcpy(&app->tap_params[i],
3248 &default_tap_params,
3249 sizeof(default_tap_params));
3251 for (i = 0; i < RTE_DIM(app->kni_params); i++)
3252 memcpy(&app->kni_params[i],
3253 &default_kni_params,
3254 sizeof(default_kni_params));
3256 for (i = 0; i < RTE_DIM(app->source_params); i++)
3257 memcpy(&app->source_params[i],
3258 &default_source_params,
3259 sizeof(default_source_params));
3261 for (i = 0; i < RTE_DIM(app->sink_params); i++)
3262 memcpy(&app->sink_params[i],
3263 &default_sink_params,
3264 sizeof(default_sink_params));
3266 for (i = 0; i < RTE_DIM(app->msgq_params); i++)
3267 memcpy(&app->msgq_params[i],
3268 &default_msgq_params,
3269 sizeof(default_msgq_params));
3271 for (i = 0; i < RTE_DIM(app->pipeline_params); i++)
3272 memcpy(&app->pipeline_params[i],
3273 &default_pipeline_params,
3274 sizeof(default_pipeline_params));
3280 filenamedup(const char *filename, const char *suffix)
3282 char *s = malloc(strlen(filename) + strlen(suffix) + 1);
3287 sprintf(s, "%s%s", filename, suffix);
3292 app_config_args(struct app_params *app, int argc, char **argv)
3294 const char *optname;
3295 int opt, option_index;
3296 int f_present, s_present, p_present, l_present;
3297 int preproc_present, preproc_params_present;
3300 static struct option lgopts[] = {
3301 { "preproc", 1, 0, 0 },
3302 { "preproc-args", 1, 0, 0 },
3306 /* Copy application name */
3307 strncpy(app->app_name, argv[0], APP_APPNAME_SIZE - 1);
3313 preproc_present = 0;
3314 preproc_params_present = 0;
3316 while ((opt = getopt_long(argc, argv, "f:s:p:l:", lgopts,
3317 &option_index)) != EOF)
3321 rte_panic("Error: Config file is provided "
3322 "more than once\n");
3325 if (!strlen(optarg))
3326 rte_panic("Error: Config file name is null\n");
3328 app->config_file = strdup(optarg);
3329 if (app->config_file == NULL)
3330 rte_panic("Error: Memory allocation failure\n");
3336 rte_panic("Error: Script file is provided "
3337 "more than once\n");
3340 if (!strlen(optarg))
3341 rte_panic("Error: Script file name is null\n");
3343 app->script_file = strdup(optarg);
3344 if (app->script_file == NULL)
3345 rte_panic("Error: Memory allocation failure\n");
3351 rte_panic("Error: PORT_MASK is provided "
3352 "more than once\n");
3355 if ((sscanf(optarg, "%" SCNx64 "%n", &app->port_mask,
3357 ((size_t) scaned != strlen(optarg)))
3358 rte_panic("Error: PORT_MASK is not "
3359 "a hexadecimal integer\n");
3361 if (app->port_mask == 0)
3362 rte_panic("Error: PORT_MASK is null\n");
3368 rte_panic("Error: LOG_LEVEL is provided "
3369 "more than once\n");
3372 if ((sscanf(optarg, "%" SCNu32 "%n", &app->log_level,
3374 ((size_t) scaned != strlen(optarg)) ||
3375 (app->log_level >= APP_LOG_LEVELS))
3376 rte_panic("Error: LOG_LEVEL invalid value\n");
3381 optname = lgopts[option_index].name;
3383 if (strcmp(optname, "preproc") == 0) {
3384 if (preproc_present)
3385 rte_panic("Error: Preprocessor argument "
3386 "is provided more than once\n");
3387 preproc_present = 1;
3389 app->preproc = strdup(optarg);
3393 if (strcmp(optname, "preproc-args") == 0) {
3394 if (preproc_params_present)
3395 rte_panic("Error: Preprocessor args "
3396 "are provided more than once\n");
3397 preproc_params_present = 1;
3399 app->preproc_args = strdup(optarg);
3403 app_print_usage(argv[0]);
3407 app_print_usage(argv[0]);
3410 optind = 1; /* reset getopt lib */
3412 /* Check dependencies between args */
3413 if (preproc_params_present && (preproc_present == 0))
3414 rte_panic("Error: Preprocessor args specified while "
3415 "preprocessor is not defined\n");
3417 app->parser_file = preproc_present ?
3418 filenamedup(app->config_file, ".preproc") :
3419 strdup(app->config_file);
3420 app->output_file = filenamedup(app->config_file, ".out");
3426 app_config_preproc(struct app_params *app)
3431 if (app->preproc == NULL)
3434 status = access(app->config_file, F_OK | R_OK);
3435 APP_CHECK((status == 0), "Error: Unable to open file %s",
3438 snprintf(buffer, sizeof(buffer), "%s %s %s > %s",
3440 app->preproc_args ? app->preproc_args : "",
3444 status = system(buffer);
3445 APP_CHECK((WIFEXITED(status) && (WEXITSTATUS(status) == 0)),
3446 "Error occurred while pre-processing file \"%s\"\n",