examples/ip_pipeline: clean config parser
authorFan Zhang <roy.fan.zhang@intel.com>
Wed, 17 Feb 2016 11:14:11 +0000 (11:14 +0000)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Mon, 7 Mar 2016 11:28:57 +0000 (12:28 +0100)
This patch updates the pipelne configuration file parser, cleans up nesting
if/else conditions, and add clearer error message display.

Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
examples/ip_pipeline/config_parse.c
examples/ip_pipeline/parser.h [new file with mode: 0644]
examples/ip_pipeline/pipeline/pipeline_firewall_be.c
examples/ip_pipeline/pipeline/pipeline_flow_actions_be.c
examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c
examples/ip_pipeline/pipeline/pipeline_passthrough_be.c
examples/ip_pipeline/pipeline/pipeline_routing_be.c
examples/ip_pipeline/pipeline_be.h

index 1bedbe4..5f72af9 100644 (file)
@@ -47,6 +47,7 @@
 #include <rte_string_fns.h>
 
 #include "app.h"
+#include "parser.h"
 
 /**
  * Default config values
@@ -229,31 +230,19 @@ app_print_usage(char *prgname)
        _p;                                     \
 })
 
-#define PARSER_IMPLICIT_PARAM_ADD_CHECK(result, section_name)          \
-do {                                                                   \
-       APP_CHECK((result != -EINVAL),                                  \
-               "CFG: [%s] name too long", section_name);               \
-       APP_CHECK(result != -ENOMEM,                                    \
-               "CFG: [%s] too much sections", section_name);           \
-       APP_CHECK(result >= 0,                                          \
-               "CFG: [%s] Unknown error while adding '%s'",            \
-               section_name, section_name);                            \
-} while (0)
-
 #define PARSER_PARAM_ADD_CHECK(result, params_array, section_name)     \
 do {                                                                   \
        APP_CHECK((result != -EINVAL),                                  \
-               "CFG: [%s] name too long", section_name);               \
+               "Parse error: no free memory");                         \
        APP_CHECK((result != -ENOMEM),                                  \
-               "CFG: [%s] too much sections", section_name);           \
+               "Parse error: too many \"%s\" sections", section_name); \
        APP_CHECK(((result >= 0) && (params_array)[result].parsed == 0),\
-               "CFG: [%s] duplicate section", section_name);           \
+               "Parse error: duplicate \"%s\" section", section_name); \
        APP_CHECK((result >= 0),                                        \
-               "CFG: [%s] Unknown error while adding '%s'",            \
-               section_name, section_name);                            \
+               "Parse error in section \"%s\"", section_name);         \
 } while (0)
 
-static int
+int
 parser_read_arg_bool(const char *p)
 {
        p = skip_white_spaces(p);
@@ -318,7 +307,7 @@ APP_CHECK(exp, "Parse error in section \"%s\": unrecognized entry \"%s\"\n",\
 APP_CHECK(exp, "Parse error in section \"%s\": duplicate entry \"%s\"\n",\
        section, entry)
 
-static int
+int
 parser_read_uint64(uint64_t *value, const char *p)
 {
        char *next;
@@ -336,13 +325,13 @@ parser_read_uint64(uint64_t *value, const char *p)
        switch (*p) {
        case 'T':
                val *= 1024ULL;
-               /* fall trought */
+               /* fall through */
        case 'G':
                val *= 1024ULL;
-               /* fall trought */
+               /* fall through */
        case 'M':
                val *= 1024ULL;
-               /* fall trought */
+               /* fall through */
        case 'k':
        case 'K':
                val *= 1024ULL;
@@ -358,7 +347,7 @@ parser_read_uint64(uint64_t *value, const char *p)
        return 0;
 }
 
-static int
+int
 parser_read_uint32(uint32_t *value, const char *p)
 {
        uint64_t val = 0;
@@ -366,7 +355,8 @@ parser_read_uint32(uint32_t *value, const char *p)
 
        if (ret < 0)
                return ret;
-       else if (val > UINT32_MAX)
+
+       if (val > UINT32_MAX)
                return -ERANGE;
 
        *value = val;
@@ -936,8 +926,25 @@ parse_pipeline_pktq_in(struct app_params *app,
        while (*next != '\0') {
                enum app_pktq_in_type type;
                int id;
+               char *end_space;
+               char *end_tab;
+
+               next = skip_white_spaces(next);
+               if (!next)
+                       break;
+
+               end_space = strchr(next, ' ');
+               end_tab = strchr(next, '        ');
+
+               if (end_space && (!end_tab))
+                       end = end_space;
+               else if ((!end_space) && end_tab)
+                       end = end_tab;
+               else if (end_space && end_tab)
+                       end = RTE_MIN(end_space, end_tab);
+               else
+                       end = NULL;
 
-               end = strchr(next, ' ');
                if (!end)
                        name_len = strlen(next);
                else
@@ -991,8 +998,25 @@ parse_pipeline_pktq_out(struct app_params *app,
        while (*next != '\0') {
                enum app_pktq_out_type type;
                int id;
+               char *end_space;
+               char *end_tab;
+
+               next = skip_white_spaces(next);
+               if (!next)
+                       break;
+
+               end_space = strchr(next, ' ');
+               end_tab = strchr(next, '        ');
+
+               if (end_space && (!end_tab))
+                       end = end_space;
+               else if ((!end_space) && end_tab)
+                       end = end_tab;
+               else if (end_space && end_tab)
+                       end = RTE_MIN(end_space, end_tab);
+               else
+                       end = NULL;
 
-               end = strchr(next, ' ');
                if (!end)
                        name_len = strlen(next);
                else
@@ -1006,7 +1030,6 @@ parse_pipeline_pktq_out(struct app_params *app,
                next += name_len;
                if (*next != '\0')
                        next++;
-
                if (validate_name(name, "TXQ", 2) == 0) {
                        type = APP_PKTQ_OUT_HWQ;
                        id = APP_PARAM_ADD(app->hwq_out_params, name);
@@ -1045,7 +1068,25 @@ parse_pipeline_msgq_in(struct app_params *app,
        ssize_t idx;
 
        while (*next != '\0') {
-               end = strchr(next, ' ');
+               char *end_space;
+               char *end_tab;
+
+               next = skip_white_spaces(next);
+               if (!next)
+                       break;
+
+               end_space = strchr(next, ' ');
+               end_tab = strchr(next, '        ');
+
+               if (end_space && (!end_tab))
+                       end = end_space;
+               else if ((!end_space) && end_tab)
+                       end = end_tab;
+               else if (end_space && end_tab)
+                       end = RTE_MIN(end_space, end_tab);
+               else
+                       end = NULL;
+
                if (!end)
                        name_len = strlen(next);
                else
@@ -1086,7 +1127,25 @@ parse_pipeline_msgq_out(struct app_params *app,
        ssize_t idx;
 
        while (*next != '\0') {
-               end = strchr(next, ' ');
+               char *end_space;
+               char *end_tab;
+
+               next = skip_white_spaces(next);
+               if (!next)
+                       break;
+
+               end_space = strchr(next, ' ');
+               end_tab = strchr(next, '        ');
+
+               if (end_space && (!end_tab))
+                       end = end_space;
+               else if ((!end_space) && end_tab)
+                       end = end_tab;
+               else if (end_space && end_tab)
+                       end = RTE_MIN(end_space, end_tab);
+               else
+                       end = NULL;
+
                if (!end)
                        name_len = strlen(next);
                else
@@ -1115,7 +1174,6 @@ parse_pipeline_msgq_out(struct app_params *app,
        return 0;
 }
 
-
 static void
 parse_pipeline(struct app_params *app,
        const char *section_name,
@@ -1125,7 +1183,7 @@ parse_pipeline(struct app_params *app,
        struct app_pipeline_params *param;
        struct rte_cfgfile_entry *entries;
        ssize_t param_idx;
-       int n_entries, ret, i;
+       int n_entries, i;
 
        n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
        PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
@@ -1139,69 +1197,103 @@ parse_pipeline(struct app_params *app,
        PARSER_PARAM_ADD_CHECK(param_idx, app->pipeline_params, section_name);
 
        param = &app->pipeline_params[param_idx];
-       param->parsed = 1;
 
        for (i = 0; i < n_entries; i++) {
                struct rte_cfgfile_entry *ent = &entries[i];
 
                if (strcmp(ent->name, "type") == 0) {
-                       ret = snprintf(param->type,
-                               RTE_DIM(param->type),
-                               "%s",
+                       int w_size = snprintf(param->type, RTE_DIM(param->type),
+                                       "%s", ent->value);
+
+                       PARSE_ERROR(((w_size > 0) &&
+                               (w_size < (int)RTE_DIM(param->type))),
+                               section_name,
+                               ent->name);
+                       continue;
+               }
+
+               if (strcmp(ent->name, "core") == 0) {
+                       int status = parse_pipeline_core(
+                               &param->socket_id, &param->core_id,
+                               &param->hyper_th_id, ent->value);
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               if (strcmp(ent->name, "pktq_in") == 0) {
+                       int status = parse_pipeline_pktq_in(app, param,
                                ent->value);
-                       if ((ret > 0) && (ret < (int)RTE_DIM(param->type)))
-                               ret = 0;
-                       else
-                               ret = -EINVAL;
-               } else if (strcmp(ent->name, "core") == 0)
-                       ret = parse_pipeline_core(&param->socket_id,
-                               &param->core_id,
-                               &param->hyper_th_id,
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               if (strcmp(ent->name, "pktq_out") == 0) {
+                       int status = parse_pipeline_pktq_out(app, param,
                                ent->value);
-               else if (strcmp(ent->name, "pktq_in") == 0)
-                       ret = parse_pipeline_pktq_in(app, param, ent->value);
-               else if (strcmp(ent->name, "pktq_out") == 0)
-                       ret = parse_pipeline_pktq_out(app, param, ent->value);
-               else if (strcmp(ent->name, "msgq_in") == 0)
-                       ret = parse_pipeline_msgq_in(app, param, ent->value);
-               else if (strcmp(ent->name, "msgq_out") == 0)
-                       ret = parse_pipeline_msgq_out(app, param, ent->value);
-               else if (strcmp(ent->name, "timer_period") == 0)
-                       ret = parser_read_uint32(&param->timer_period,
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               if (strcmp(ent->name, "msgq_in") == 0) {
+                       int status = parse_pipeline_msgq_in(app, param,
                                ent->value);
-               else {
-                       APP_CHECK((param->n_args < APP_MAX_PIPELINE_ARGS),
-                               "CFG: [%s] out of memory",
-                               section_name);
 
-                       param->args_name[param->n_args] = strdup(ent->name);
-                       param->args_value[param->n_args] = strdup(ent->value);
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
 
-                       APP_CHECK((param->args_name[param->n_args] != NULL) &&
-                               (param->args_value[param->n_args] != NULL),
-                               "CFG: [%s] out of memory",
-                               section_name);
+               if (strcmp(ent->name, "msgq_out") == 0) {
+                       int status = parse_pipeline_msgq_out(app, param,
+                               ent->value);
 
-                       param->n_args++;
-                       ret = 0;
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
                }
 
-               APP_CHECK(ret == 0,
-                       "CFG: [%s] entry '%s': Invalid value '%s'\n",
-                       section_name,
-                       ent->name,
-                       ent->value);
+               if (strcmp(ent->name, "timer_period") == 0) {
+                       int status = parser_read_uint32(
+                               &param->timer_period,
+                               ent->value);
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               /* pipeline type specific items */
+               APP_CHECK((param->n_args < APP_MAX_PIPELINE_ARGS),
+                       "Parse error in section \"%s\": too many "
+                       "pipeline specified parameters", section_name);
+
+               param->args_name[param->n_args] = strdup(ent->name);
+               param->args_value[param->n_args] = strdup(ent->value);
+
+               APP_CHECK((param->args_name[param->n_args] != NULL) &&
+                       (param->args_value[param->n_args] != NULL),
+                       "Parse error: no free memory");
+
+               param->n_args++;
        }
 
+       param->parsed = 1;
+
        snprintf(name, sizeof(name), "MSGQ-REQ-%s", section_name);
        param_idx = APP_PARAM_ADD(app->msgq_params, name);
-       PARSER_IMPLICIT_PARAM_ADD_CHECK(param_idx, name);
+       PARSER_PARAM_ADD_CHECK(param_idx, app->msgq_params, name);
        app->msgq_params[param_idx].cpu_socket_id = param->socket_id;
        param->msgq_in[param->n_msgq_in++] = param_idx;
 
        snprintf(name, sizeof(name), "MSGQ-RSP-%s", section_name);
        param_idx = APP_PARAM_ADD(app->msgq_params, name);
-       PARSER_IMPLICIT_PARAM_ADD_CHECK(param_idx, name);
+       PARSER_PARAM_ADD_CHECK(param_idx, app->msgq_params, name);
        app->msgq_params[param_idx].cpu_socket_id = param->socket_id;
        param->msgq_out[param->n_msgq_out++] = param_idx;
 
@@ -1210,7 +1302,7 @@ parse_pipeline(struct app_params *app,
                param->core_id,
                (param->hyper_th_id) ? "h" : "");
        param_idx = APP_PARAM_ADD(app->msgq_params, name);
-       PARSER_IMPLICIT_PARAM_ADD_CHECK(param_idx, name);
+       PARSER_PARAM_ADD_CHECK(param_idx, app->msgq_params, name);
        app->msgq_params[param_idx].cpu_socket_id = param->socket_id;
 
        snprintf(name, sizeof(name), "MSGQ-RSP-CORE-s%" PRIu32 "c%" PRIu32 "%s",
@@ -1218,7 +1310,7 @@ parse_pipeline(struct app_params *app,
                param->core_id,
                (param->hyper_th_id) ? "h" : "");
        param_idx = APP_PARAM_ADD(app->msgq_params, name);
-       PARSER_IMPLICIT_PARAM_ADD_CHECK(param_idx, name);
+       PARSER_PARAM_ADD_CHECK(param_idx, app->msgq_params, name);
        app->msgq_params[param_idx].cpu_socket_id = param->socket_id;
 
        free(entries);
@@ -1232,7 +1324,7 @@ parse_mempool(struct app_params *app,
        struct app_mempool_params *param;
        struct rte_cfgfile_entry *entries;
        ssize_t param_idx;
-       int n_entries, ret, i;
+       int n_entries, i;
 
        n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
        PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
@@ -1246,36 +1338,52 @@ parse_mempool(struct app_params *app,
        PARSER_PARAM_ADD_CHECK(param_idx, app->mempool_params, section_name);
 
        param = &app->mempool_params[param_idx];
-       param->parsed = 1;
 
        for (i = 0; i < n_entries; i++) {
                struct rte_cfgfile_entry *ent = &entries[i];
 
-               ret = -ESRCH;
-               if (strcmp(ent->name, "buffer_size") == 0)
-                       ret = parser_read_uint32(&param->buffer_size,
-                               ent->value);
-               else if (strcmp(ent->name, "pool_size") == 0)
-                       ret = parser_read_uint32(&param->pool_size,
-                               ent->value);
-               else if (strcmp(ent->name, "cache_size") == 0)
-                       ret = parser_read_uint32(&param->cache_size,
-                               ent->value);
-               else if (strcmp(ent->name, "cpu") == 0)
-                       ret = parser_read_uint32(&param->cpu_socket_id,
-                               ent->value);
+               if (strcmp(ent->name, "buffer_size") == 0) {
+                       int status = parser_read_uint32(
+                               &param->buffer_size, ent->value);
 
-               APP_CHECK(ret != -ESRCH,
-                       "CFG: [%s] entry '%s': unknown entry\n",
-                       section_name,
-                       ent->name);
-               APP_CHECK(ret == 0,
-                       "CFG: [%s] entry '%s': Invalid value '%s'\n",
-                       section_name,
-                       ent->name,
-                       ent->value);
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               if (strcmp(ent->name, "pool_size") == 0) {
+                       int status = parser_read_uint32(
+                               &param->pool_size, ent->value);
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               if (strcmp(ent->name, "cache_size") == 0) {
+                       int status = parser_read_uint32(
+                               &param->cache_size, ent->value);
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               if (strcmp(ent->name, "cpu") == 0) {
+                       int status = parser_read_uint32(
+                               &param->cpu_socket_id, ent->value);
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               /* unrecognized */
+               PARSE_ERROR_INVALID(0, section_name, ent->name);
        }
 
+       param->parsed = 1;
+
        free(entries);
 }
 
@@ -1286,7 +1394,7 @@ parse_link(struct app_params *app,
 {
        struct app_link_params *param;
        struct rte_cfgfile_entry *entries;
-       int n_entries, ret, i;
+       int n_entries, i;
        ssize_t param_idx;
 
        n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
@@ -1301,48 +1409,79 @@ parse_link(struct app_params *app,
        PARSER_PARAM_ADD_CHECK(param_idx, app->link_params, section_name);
 
        param = &app->link_params[param_idx];
-       param->parsed = 1;
 
        for (i = 0; i < n_entries; i++) {
                struct rte_cfgfile_entry *ent = &entries[i];
 
-               ret = -ESRCH;
                if (strcmp(ent->name, "promisc") == 0) {
-                       ret = parser_read_arg_bool(ent->value);
-                       if (ret >= 0) {
-                               param->promisc = ret;
-                               ret = 0;
-                       }
-               } else if (strcmp(ent->name, "arp_q") == 0)
-                       ret = parser_read_uint32(&param->arp_q,
-                               ent->value);
-               else if (strcmp(ent->name, "tcp_syn_q") == 0)
-                       ret = parser_read_uint32(&param->tcp_syn_local_q,
-                               ent->value);
-               else if (strcmp(ent->name, "ip_local_q") == 0)
-                       ret = parser_read_uint32(&param->ip_local_q,
-                               ent->value);
-               else if (strcmp(ent->name, "tcp_local_q") == 0)
-                       ret = parser_read_uint32(&param->tcp_local_q,
-                               ent->value);
-               else if (strcmp(ent->name, "udp_local_q") == 0)
-                       ret = parser_read_uint32(&param->udp_local_q,
-                               ent->value);
-               else if (strcmp(ent->name, "sctp_local_q") == 0)
-                       ret = parser_read_uint32(&param->sctp_local_q,
+                       int status = parser_read_arg_bool(ent->value);
+
+                       PARSE_ERROR((status != -EINVAL), section_name,
+                               ent->name);
+                       param->promisc = status;
+                       continue;
+               }
+
+               if (strcmp(ent->name, "arp_q") == 0) {
+                       int status = parser_read_uint32(&param->arp_q,
                                ent->value);
 
-               APP_CHECK(ret != -ESRCH,
-                       "CFG: [%s] entry '%s': unknown entry\n",
-                       section_name,
-                       ent->name);
-               APP_CHECK(ret == 0,
-                       "CFG: [%s] entry '%s': Invalid value '%s'\n",
-                       section_name,
-                       ent->name,
-                       ent->value);
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               if (strcmp(ent->name, "tcp_syn_q") == 0) {
+                       int status = parser_read_uint32(
+                               &param->tcp_syn_local_q, ent->value);
+
+                       PARSE_ERROR((status == 0), section_name, ent->name);
+                       continue;
+               }
+
+               if (strcmp(ent->name, "ip_local_q") == 0) {
+                       int status = parser_read_uint32(
+                               &param->ip_local_q, ent->value);
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+
+               if (strcmp(ent->name, "tcp_local_q") == 0) {
+                       int status = parser_read_uint32(
+                               &param->tcp_local_q, ent->value);
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               if (strcmp(ent->name, "udp_local_q") == 0) {
+                       int status = parser_read_uint32(
+                               &param->udp_local_q, ent->value);
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               if (strcmp(ent->name, "sctp_local_q") == 0) {
+                       int status = parser_read_uint32(
+                               &param->sctp_local_q, ent->value);
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               /* unrecognized */
+               PARSE_ERROR_INVALID(0, section_name, ent->name);
        }
 
+       param->parsed = 1;
+
        free(entries);
 }
 
@@ -1353,7 +1492,7 @@ parse_rxq(struct app_params *app,
 {
        struct app_pktq_hwq_in_params *param;
        struct rte_cfgfile_entry *entries;
-       int n_entries, ret, i;
+       int n_entries, i;
        ssize_t param_idx;
 
        n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
@@ -1368,43 +1507,49 @@ parse_rxq(struct app_params *app,
        PARSER_PARAM_ADD_CHECK(param_idx, app->hwq_in_params, section_name);
 
        param = &app->hwq_in_params[param_idx];
-       param->parsed = 1;
 
        for (i = 0; i < n_entries; i++) {
                struct rte_cfgfile_entry *ent = &entries[i];
 
-               ret = -ESRCH;
                if (strcmp(ent->name, "mempool") == 0) {
-                       int status = validate_name(ent->value, "MEMPOOL", 1);
+                       int status = validate_name(ent->value,
+                               "MEMPOOL", 1);
                        ssize_t idx;
 
-                       APP_CHECK((status == 0),
-                               "CFG: [%s] entry '%s': invalid mempool\n",
-                               section_name,
+                       PARSE_ERROR((status == 0), section_name,
                                ent->name);
-
-                       idx = APP_PARAM_ADD(app->mempool_params, ent->value);
-                       PARSER_IMPLICIT_PARAM_ADD_CHECK(idx, section_name);
+                       idx = APP_PARAM_ADD(app->mempool_params,
+                               ent->value);
+                       PARSER_PARAM_ADD_CHECK(idx, app->mempool_params,
+                               section_name);
                        param->mempool_id = idx;
-                       ret = 0;
-               } else if (strcmp(ent->name, "size") == 0)
-                       ret = parser_read_uint32(&param->size,
+                       continue;
+               }
+
+               if (strcmp(ent->name, "size") == 0) {
+                       int status = parser_read_uint32(&param->size,
                                ent->value);
-               else if (strcmp(ent->name, "burst") == 0)
-                       ret = parser_read_uint32(&param->burst,
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               if (strcmp(ent->name, "burst") == 0) {
+                       int status = parser_read_uint32(&param->burst,
                                ent->value);
 
-               APP_CHECK(ret != -ESRCH,
-                       "CFG: [%s] entry '%s': unknown entry\n",
-                       section_name,
-                       ent->name);
-               APP_CHECK(ret == 0,
-                       "CFG: [%s] entry '%s': Invalid value '%s'\n",
-                       section_name,
-                       ent->name,
-                       ent->value);
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               /* unrecognized */
+               PARSE_ERROR_INVALID(0, section_name, ent->name);
        }
 
+       param->parsed = 1;
+
        free(entries);
 }
 
@@ -1415,7 +1560,7 @@ parse_txq(struct app_params *app,
 {
        struct app_pktq_hwq_out_params *param;
        struct rte_cfgfile_entry *entries;
-       int n_entries, ret, i;
+       int n_entries, i;
        ssize_t param_idx;
 
        n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
@@ -1430,35 +1575,44 @@ parse_txq(struct app_params *app,
        PARSER_PARAM_ADD_CHECK(param_idx, app->hwq_out_params, section_name);
 
        param = &app->hwq_out_params[param_idx];
-       param->parsed = 1;
 
        for (i = 0; i < n_entries; i++) {
                struct rte_cfgfile_entry *ent = &entries[i];
 
-               ret = -ESRCH;
-               if (strcmp(ent->name, "size") == 0)
-                       ret = parser_read_uint32(&param->size, ent->value);
-               else if (strcmp(ent->name, "burst") == 0)
-                       ret = parser_read_uint32(&param->burst, ent->value);
-               else if (strcmp(ent->name, "dropless") == 0) {
-                       ret = parser_read_arg_bool(ent->value);
-                       if (ret >= 0) {
-                               param->dropless = ret;
-                               ret = 0;
-                       }
+               if (strcmp(ent->name, "size") == 0) {
+                       int status = parser_read_uint32(&param->size,
+                               ent->value);
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
                }
 
-               APP_CHECK(ret != -ESRCH,
-                       "CFG: [%s] entry '%s': unknown entry\n",
-                       section_name,
-                       ent->name);
-               APP_CHECK(ret == 0,
-                       "CFG: [%s] entry '%s': Invalid value '%s'\n",
-                       section_name,
-                       ent->name,
-                       ent->value);
+               if (strcmp(ent->name, "burst") == 0) {
+                       int status = parser_read_uint32(&param->burst,
+                               ent->value);
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               if (strcmp(ent->name, "dropless") == 0) {
+                       int status = parser_read_arg_bool(ent->value);
+
+
+                       PARSE_ERROR((status != -EINVAL), section_name,
+                               ent->name);
+                       param->dropless = status;
+                       continue;
+               }
+
+               /* unrecognized */
+               PARSE_ERROR_INVALID(0, section_name, ent->name);
        }
 
+       param->parsed = 1;
+
        free(entries);
 }
 
@@ -1469,8 +1623,12 @@ parse_swq(struct app_params *app,
 {
        struct app_pktq_swq_params *param;
        struct rte_cfgfile_entry *entries;
-       int n_entries, ret, i;
-       unsigned frag_entries = 0;
+       int n_entries, i;
+       uint32_t mtu_present = 0;
+       uint32_t metadata_size_present = 0;
+       uint32_t mempool_direct_present = 0;
+       uint32_t mempool_indirect_present = 0;
+
        ssize_t param_idx;
 
        n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
@@ -1485,117 +1643,188 @@ parse_swq(struct app_params *app,
        PARSER_PARAM_ADD_CHECK(param_idx, app->swq_params, section_name);
 
        param = &app->swq_params[param_idx];
-       param->parsed = 1;
 
        for (i = 0; i < n_entries; i++) {
                struct rte_cfgfile_entry *ent = &entries[i];
 
-               ret = -ESRCH;
-               if (strcmp(ent->name, "size") == 0)
-                       ret = parser_read_uint32(&param->size,
-                               ent->value);
-               else if (strcmp(ent->name, "burst_read") == 0)
-                       ret = parser_read_uint32(&param->burst_read,
+               if (strcmp(ent->name, "size") == 0) {
+                       int status = parser_read_uint32(&param->size,
                                ent->value);
-               else if (strcmp(ent->name, "burst_write") == 0)
-                       ret = parser_read_uint32(&param->burst_write,
-                               ent->value);
-               else if (strcmp(ent->name, "dropless") == 0) {
-                       ret = parser_read_arg_bool(ent->value);
-                       if (ret >= 0) {
-                               param->dropless = ret;
-                               ret = 0;
-                       }
-               } else if (strcmp(ent->name, "n_retries") == 0)
-                       ret = parser_read_uint64(&param->n_retries,
-                               ent->value);
-               else if (strcmp(ent->name, "cpu") == 0)
-                       ret = parser_read_uint32(&param->cpu_socket_id,
-                               ent->value);
-               else if (strcmp(ent->name, "ipv4_frag") == 0) {
-                       ret = parser_read_arg_bool(ent->value);
-                       if (ret >= 0) {
-                               param->ipv4_frag = ret;
-                               if (param->mtu == 0)
-                                       param->mtu = 1500;
-                               ret = 0;
-                       }
-               } else if (strcmp(ent->name, "ipv6_frag") == 0) {
-                       ret = parser_read_arg_bool(ent->value);
-                       if (ret >= 0) {
-                               param->ipv6_frag = ret;
-                               if (param->mtu == 0)
-                                       param->mtu = 1320;
-                               ret = 0;
-                       }
-               } else if (strcmp(ent->name, "ipv4_ras") == 0) {
-                       ret = parser_read_arg_bool(ent->value);
-                       if (ret >= 0) {
-                               param->ipv4_ras = ret;
-                               ret = 0;
-                       }
-               } else if (strcmp(ent->name, "ipv6_ras") == 0) {
-                       ret = parser_read_arg_bool(ent->value);
-                       if (ret >= 0) {
-                               param->ipv6_ras = ret;
-                               ret = 0;
-                       }
-               } else if (strcmp(ent->name, "mtu") == 0) {
-                       frag_entries = 1;
-                       ret = parser_read_uint32(&param->mtu,
-                               ent->value);
-               } else if (strcmp(ent->name, "metadata_size") == 0) {
-                       frag_entries = 1;
-                       ret = parser_read_uint32(&param->metadata_size,
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               if (strcmp(ent->name, "burst_read") == 0) {
+                       int status = parser_read_uint32(&
+                               param->burst_read, ent->value);
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               if (strcmp(ent->name, "burst_write") == 0) {
+                       int status = parser_read_uint32(
+                               &param->burst_write, ent->value);
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               if (strcmp(ent->name, "dropless") == 0) {
+                       int status = parser_read_arg_bool(ent->value);
+
+                       PARSE_ERROR((status != -EINVAL), section_name,
+                               ent->name);
+                       param->dropless = status;
+                       continue;
+               }
+
+               if (strcmp(ent->name, "n_retries") == 0) {
+                       int status = parser_read_uint64(&param->n_retries,
                                ent->value);
-               } else if (strcmp(ent->name, "mempool_direct") == 0) {
-                       int status = validate_name(ent->value, "MEMPOOL", 1);
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               if (strcmp(ent->name, "cpu") == 0) {
+                       int status = parser_read_uint32(
+                               &param->cpu_socket_id, ent->value);
+
+                       PARSE_ERROR((status == 0), section_name, ent->name);
+                       continue;
+               }
+
+               if (strcmp(ent->name, "ipv4_frag") == 0) {
+                       int status = parser_read_arg_bool(ent->value);
+
+                       PARSE_ERROR((status != -EINVAL), section_name,
+                               ent->name);
+
+                       param->ipv4_frag = status;
+                       if (param->mtu == 0)
+                               param->mtu = 1500;
+
+                       continue;
+               }
+
+               if (strcmp(ent->name, "ipv6_frag") == 0) {
+                       int status = parser_read_arg_bool(ent->value);
+
+                       PARSE_ERROR((status != -EINVAL), section_name,
+                               ent->name);
+                       param->ipv6_frag = status;
+                       if (param->mtu == 0)
+                               param->mtu = 1320;
+                       continue;
+               }
+
+               if (strcmp(ent->name, "ipv4_ras") == 0) {
+                       int status = parser_read_arg_bool(ent->value);
+
+                       PARSE_ERROR((status != -EINVAL), section_name,
+                               ent->name);
+                       param->ipv4_ras = status;
+                       continue;
+               }
+
+               if (strcmp(ent->name, "ipv6_ras") == 0) {
+                       int status = parser_read_arg_bool(ent->value);
+
+                       PARSE_ERROR((status != -EINVAL), section_name,
+                               ent->name);
+                       param->ipv6_ras = status;
+                       continue;
+               }
+
+               if (strcmp(ent->name, "mtu") == 0) {
+                       int status = parser_read_uint32(&param->mtu,
+                                       ent->value);
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       mtu_present = 1;
+                       continue;
+               }
+
+               if (strcmp(ent->name, "metadata_size") == 0) {
+                       int status = parser_read_uint32(
+                               &param->metadata_size, ent->value);
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       metadata_size_present = 1;
+                       continue;
+               }
+
+               if (strcmp(ent->name, "mempool_direct") == 0) {
+                       int status = validate_name(ent->value,
+                               "MEMPOOL", 1);
                        ssize_t idx;
 
-                       APP_CHECK((status == 0),
-                               "CFG: [%s] entry '%s': invalid mempool\n",
-                               section_name,
+                       PARSE_ERROR((status == 0), section_name,
                                ent->name);
 
-                       idx = APP_PARAM_ADD(app->mempool_params, ent->value);
-                       PARSER_IMPLICIT_PARAM_ADD_CHECK(idx, section_name);
+                       idx = APP_PARAM_ADD(app->mempool_params,
+                               ent->value);
+                       PARSER_PARAM_ADD_CHECK(idx, app->mempool_params,
+                               section_name);
                        param->mempool_direct_id = idx;
-                       frag_entries = 1;
-                       ret = 0;
-               } else if (strcmp(ent->name, "mempool_indirect") == 0) {
-                       int status = validate_name(ent->value, "MEMPOOL", 1);
+                       mempool_direct_present = 1;
+                       continue;
+               }
+
+               if (strcmp(ent->name, "mempool_indirect") == 0) {
+                       int status = validate_name(ent->value,
+                               "MEMPOOL", 1);
                        ssize_t idx;
 
-                       APP_CHECK((status == 0),
-                               "CFG: [%s] entry '%s': invalid mempool\n",
-                               section_name,
+                       PARSE_ERROR((status == 0), section_name,
                                ent->name);
-
-                       idx = APP_PARAM_ADD(app->mempool_params, ent->value);
-                       PARSER_IMPLICIT_PARAM_ADD_CHECK(idx, section_name);
+                       idx = APP_PARAM_ADD(app->mempool_params,
+                               ent->value);
+                       PARSER_PARAM_ADD_CHECK(idx, app->mempool_params,
+                               section_name);
                        param->mempool_indirect_id = idx;
-                       frag_entries = 1;
-                       ret = 0;
-               }
-
-               APP_CHECK(ret != -ESRCH,
-                       "CFG: [%s] entry '%s': unknown entry\n",
-                       section_name,
-                       ent->name);
-               APP_CHECK(ret == 0,
-                       "CFG: [%s] entry '%s': Invalid value '%s'\n",
-                       section_name,
-                       ent->name,
-                       ent->value);
-       }
+                       mempool_indirect_present = 1;
+                       continue;
+               }
 
-       if (frag_entries == 1) {
-               APP_CHECK(((param->ipv4_frag == 1) || (param->ipv6_frag == 1)),
-                       "CFG: [%s] ipv4/ipv6 frag is off : unsupported entries on this"
-                       " configuration\n",
-                       section_name);
+               /* unrecognized */
+               PARSE_ERROR_INVALID(0, section_name, ent->name);
        }
 
+       APP_CHECK(((mtu_present) &&
+               ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))),
+               "Parse error in section \"%s\": IPv4/IPv6 fragmentation "
+               "is off, therefore entry \"mtu\" is not allowed",
+               section_name);
+
+       APP_CHECK(((metadata_size_present) &&
+               ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))),
+               "Parse error in section \"%s\": IPv4/IPv6 fragmentation "
+               "is off, therefore entry \"metadata_size\" is "
+               "not allowed", section_name);
+
+       APP_CHECK(((mempool_direct_present) &&
+               ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))),
+               "Parse error in section \"%s\": IPv4/IPv6 fragmentation "
+               "is off, therefore entry \"mempool_direct\" is "
+               "not allowed", section_name);
+
+       APP_CHECK(((mempool_indirect_present) &&
+               ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))),
+               "Parse error in section \"%s\": IPv4/IPv6 fragmentation "
+               "is off, therefore entry \"mempool_indirect\" is "
+               "not allowed", section_name);
+
+       param->parsed = 1;
+
        free(entries);
 }
 
@@ -1606,7 +1835,7 @@ parse_tm(struct app_params *app,
 {
        struct app_pktq_tm_params *param;
        struct rte_cfgfile_entry *entries;
-       int n_entries, ret, i;
+       int n_entries, i;
        ssize_t param_idx;
 
        n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
@@ -1621,41 +1850,40 @@ parse_tm(struct app_params *app,
        PARSER_PARAM_ADD_CHECK(param_idx, app->tm_params, section_name);
 
        param = &app->tm_params[param_idx];
-       param->parsed = 1;
 
        for (i = 0; i < n_entries; i++) {
                struct rte_cfgfile_entry *ent = &entries[i];
 
-               ret = -ESRCH;
                if (strcmp(ent->name, "cfg") == 0) {
                        param->file_name = strdup(ent->value);
-                       if (param->file_name == NULL)
-                               ret = -EINVAL;
-                       else
-                               ret = 0;
-               } else if (strcmp(ent->name, "burst_read") == 0)
-                       ret = parser_read_uint32(&param->burst_read,
-                               ent->value);
-               else if (strcmp(ent->name, "burst_write") == 0)
-                       ret = parser_read_uint32(&param->burst_write,
-                               ent->value);
+                       PARSE_ERROR_MALLOC(param->file_name != NULL);
+                       continue;
+               }
+
+               if (strcmp(ent->name, "burst_read") == 0) {
+                       int status = parser_read_uint32(
+                               &param->burst_read, ent->value);
 
-               APP_CHECK(ret != -ESRCH,
-                       "CFG: [%s] entry '%s': unknown entry\n",
-                       section_name,
-                       ent->name);
-               APP_CHECK(ret != -EBADF,
-                       "CFG: [%s] entry '%s': TM cfg parse error '%s'\n",
-                       section_name,
-                       ent->name,
-                       ent->value);
-               APP_CHECK(ret == 0,
-                       "CFG: [%s] entry '%s': Invalid value '%s'\n",
-                       section_name,
-                       ent->name,
-                       ent->value);
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               if (strcmp(ent->name, "burst_write") == 0) {
+                       int status = parser_read_uint32(
+                               &param->burst_write, ent->value);
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               /* unrecognized */
+               PARSE_ERROR_INVALID(0, section_name, ent->name);
        }
 
+       param->parsed = 1;
+
        free(entries);
 }
 
@@ -1666,7 +1894,7 @@ parse_source(struct app_params *app,
 {
        struct app_pktq_source_params *param;
        struct rte_cfgfile_entry *entries;
-       int n_entries, ret, i;
+       int n_entries, i;
        ssize_t param_idx;
 
        n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
@@ -1681,39 +1909,40 @@ parse_source(struct app_params *app,
        PARSER_PARAM_ADD_CHECK(param_idx, app->source_params, section_name);
 
        param = &app->source_params[param_idx];
-       param->parsed = 1;
 
        for (i = 0; i < n_entries; i++) {
                struct rte_cfgfile_entry *ent = &entries[i];
 
-               ret = -ESRCH;
                if (strcmp(ent->name, "mempool") == 0) {
-                       int status = validate_name(ent->value, "MEMPOOL", 1);
+                       int status = validate_name(ent->value,
+                               "MEMPOOL", 1);
                        ssize_t idx;
 
-                       APP_CHECK((status == 0),
-                               "CFG: [%s] entry '%s': invalid mempool\n",
-                                       section_name,
-                                       ent->name);
-
-                       idx = APP_PARAM_ADD(app->mempool_params, ent->value);
-                       PARSER_IMPLICIT_PARAM_ADD_CHECK(idx, section_name);
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       idx = APP_PARAM_ADD(app->mempool_params,
+                               ent->value);
+                       PARSER_PARAM_ADD_CHECK(idx, app->mempool_params,
+                               section_name);
                        param->mempool_id = idx;
-                       ret = 0;
-               } else if (strcmp(ent->name, "burst") == 0)
-                       ret = parser_read_uint32(&param->burst, ent->value);
-
-               APP_CHECK(ret != -ESRCH,
-                       "CFG: [%s] entry '%s': unknown entry\n",
-                       section_name,
-                       ent->name);
-               APP_CHECK(ret == 0,
-                       "CFG: [%s] entry '%s': Invalid value '%s'\n",
-                       section_name,
-                       ent->name,
-                       ent->value);
+                       continue;
+               }
+
+               if (strcmp(ent->name, "burst") == 0) {
+                       int status = parser_read_uint32(&param->burst,
+                               ent->value);
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               /* unrecognized */
+               PARSE_ERROR_INVALID(0, section_name, ent->name);
        }
 
+       param->parsed = 1;
+
        free(entries);
 }
 
@@ -1724,7 +1953,7 @@ parse_msgq_req_pipeline(struct app_params *app,
 {
        struct app_msgq_params *param;
        struct rte_cfgfile_entry *entries;
-       int n_entries, ret, i;
+       int n_entries, i;
        ssize_t param_idx;
 
        n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
@@ -1739,26 +1968,24 @@ parse_msgq_req_pipeline(struct app_params *app,
        PARSER_PARAM_ADD_CHECK(param_idx, app->msgq_params, section_name);
 
        param = &app->msgq_params[param_idx];
-       param->parsed = 1;
 
        for (i = 0; i < n_entries; i++) {
                struct rte_cfgfile_entry *ent = &entries[i];
 
-               ret = -ESRCH;
-               if (strcmp(ent->name, "size") == 0)
-                       ret = parser_read_uint32(&param->size, ent->value);
-
-               APP_CHECK(ret != -ESRCH,
-                       "CFG: [%s] entry '%s': unknown entry\n",
-                       section_name,
-                       ent->name);
-               APP_CHECK(ret == 0,
-                       "CFG: [%s] entry '%s': Invalid value '%s'\n",
-                       section_name,
-                       ent->name,
-                       ent->value);
+               if (strcmp(ent->name, "size") == 0) {
+                       int status = parser_read_uint32(&param->size,
+                               ent->value);
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               /* unrecognized */
+               PARSE_ERROR_INVALID(0, section_name, ent->name);
        }
 
+       param->parsed = 1;
        free(entries);
 }
 
@@ -1769,7 +1996,7 @@ parse_msgq_rsp_pipeline(struct app_params *app,
 {
        struct app_msgq_params *param;
        struct rte_cfgfile_entry *entries;
-       int n_entries, ret, i;
+       int n_entries, i;
        ssize_t param_idx;
 
        n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
@@ -1784,26 +2011,25 @@ parse_msgq_rsp_pipeline(struct app_params *app,
        PARSER_PARAM_ADD_CHECK(param_idx, app->msgq_params, section_name);
 
        param = &app->msgq_params[param_idx];
-       param->parsed = 1;
 
        for (i = 0; i < n_entries; i++) {
                struct rte_cfgfile_entry *ent = &entries[i];
 
-               ret = -ESRCH;
-               if (strcmp(ent->name, "size") == 0)
-                       ret = parser_read_uint32(&param->size, ent->value);
-
-               APP_CHECK(ret != -ESRCH,
-                       "CFG: [%s] entry '%s': unknown entry\n",
-                       section_name,
-                       ent->name);
-               APP_CHECK(ret == 0,
-                       "CFG: [%s] entry '%s': Invalid value '%s'\n",
-                       section_name,
-                       ent->name,
-                       ent->value);
+               if (strcmp(ent->name, "size") == 0) {
+                       int status = parser_read_uint32(&param->size,
+                               ent->value);
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               /* unrecognized */
+               PARSE_ERROR_INVALID(0, section_name, ent->name);
        }
 
+       param->parsed = 1;
+
        free(entries);
 }
 
@@ -1814,7 +2040,7 @@ parse_msgq(struct app_params *app,
 {
        struct app_msgq_params *param;
        struct rte_cfgfile_entry *entries;
-       int n_entries, ret, i;
+       int n_entries, i;
        ssize_t param_idx;
 
        n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
@@ -1829,30 +2055,34 @@ parse_msgq(struct app_params *app,
        PARSER_PARAM_ADD_CHECK(param_idx, app->msgq_params, section_name);
 
        param = &app->msgq_params[param_idx];
-       param->parsed = 1;
 
        for (i = 0; i < n_entries; i++) {
                struct rte_cfgfile_entry *ent = &entries[i];
 
-               ret = -ESRCH;
-               if (strcmp(ent->name, "size") == 0)
-                       ret = parser_read_uint32(&param->size,
-                               ent->value);
-               else if (strcmp(ent->name, "cpu") == 0)
-                       ret = parser_read_uint32(&param->cpu_socket_id,
+               if (strcmp(ent->name, "size") == 0) {
+                       int status = parser_read_uint32(&param->size,
                                ent->value);
 
-               APP_CHECK(ret != -ESRCH,
-                       "CFG: [%s] entry '%s': unknown entry\n",
-                       section_name,
-                       ent->name);
-               APP_CHECK(ret == 0,
-                       "CFG: [%s] entry '%s': Invalid value '%s'\n",
-                       section_name,
-                       ent->name,
-                       ent->value);
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               if (strcmp(ent->name, "cpu") == 0) {
+                       int status = parser_read_uint32(
+                               &param->cpu_socket_id, ent->value);
+
+                       PARSE_ERROR((status == 0), section_name,
+                               ent->name);
+                       continue;
+               }
+
+               /* unrecognized */
+               PARSE_ERROR_INVALID(0, section_name, ent->name);
        }
 
+       param->parsed = 1;
+
        free(entries);
 }
 
@@ -1887,7 +2117,7 @@ create_implicit_mempools(struct app_params *app)
        ssize_t idx;
 
        idx = APP_PARAM_ADD(app->mempool_params, "MEMPOOL0");
-       PARSER_IMPLICIT_PARAM_ADD_CHECK(idx, "start-up");
+       PARSER_PARAM_ADD_CHECK(idx, app->mempool_params, "start-up");
 }
 
 static void
@@ -1905,7 +2135,7 @@ parse_port_mask(struct app_params *app, uint64_t port_mask)
 
                snprintf(name, sizeof(name), "LINK%" PRIu32, link_id);
                idx = APP_PARAM_ADD(app->link_params, name);
-               PARSER_IMPLICIT_PARAM_ADD_CHECK(idx, name);
+               PARSER_PARAM_ADD_CHECK(idx, app->link_params, name);
 
                app->link_params[idx].pmd_id = pmd_id;
                link_id++;
@@ -1927,13 +2157,16 @@ app_config_parse(struct app_params *app, const char *file_name)
 
        /* Load application configuration file */
        cfg = rte_cfgfile_load(file_name, 0);
-       APP_CHECK(cfg != NULL, "Unable to load config file %s", file_name);
+       APP_CHECK((cfg != NULL), "Parse error: Unable to load config "
+               "file %s", file_name);
 
        sect_count = rte_cfgfile_num_sections(cfg, NULL, 0);
-       APP_CHECK(sect_count > 0, "Number of sections return %d", sect_count);
+       APP_CHECK((sect_count > 0), "Parse error: number of sections "
+               "in file \"%s\" return %d", file_name,
+               sect_count);
 
        section_names = malloc(sect_count * sizeof(char *));
-       APP_CHECK(section_names != NULL, "Failed to allocate memory");
+       PARSE_ERROR_MALLOC(section_names != NULL);
 
        for (i = 0; i < sect_count; i++)
                section_names[i] = malloc(CFG_NAME_LEN);
@@ -1969,13 +2202,13 @@ app_config_parse(struct app_params *app, const char *file_name)
                }
 
                APP_CHECK(j < (int)RTE_DIM(cfg_file_scheme),
-                       "Unknown section %s",
+                       "Parse error: unknown section %s",
                        section_names[i]);
 
                APP_CHECK(validate_name(section_names[i],
                        sch_s->prefix,
                        sch_s->numbers) == 0,
-                       "Invalid section name '%s'",
+                       "Parse error: invalid section name \"%s\"",
                        section_names[i]);
 
                sch_s->load(app, section_names[i], cfg);
@@ -2343,7 +2576,9 @@ save_pipeline_params(struct app_params *app, FILE *f)
                                        name = app->source_params[pp->id].name;
                                        break;
                                default:
-                                       APP_CHECK(0, "Error\n");
+                                       APP_CHECK(0, "System error "
+                                               "occurred while saving "
+                                               "parameter to file");
                                }
 
                                fprintf(f, " %s", name);
@@ -2375,7 +2610,9 @@ save_pipeline_params(struct app_params *app, FILE *f)
                                        name = app->sink_params[pp->id].name;
                                        break;
                                default:
-                                       APP_CHECK(0, "Error\n");
+                                       APP_CHECK(0, "System error "
+                                               "occurred while saving "
+                                               "parameter to file");
                                }
 
                                fprintf(f, " %s", name);
@@ -2438,12 +2675,13 @@ app_config_save(struct app_params *app, const char *file_name)
        dir_name = dirname(name);
        status = access(dir_name, W_OK);
        APP_CHECK((status == 0),
-               "Need write access to directory \"%s\" to save configuration\n",
-               dir_name);
+               "Error: need write access privilege to directory "
+               "\"%s\" to save configuration\n", dir_name);
 
        file = fopen(file_name, "w");
        APP_CHECK((file != NULL),
-               "Failed to save configuration to file \"%s\"", file_name);
+               "Error: failed to save configuration to file \"%s\"",
+               file_name);
 
        save_eal_params(app, file);
        save_pipeline_params(app, file);
@@ -2680,7 +2918,8 @@ app_config_preproc(struct app_params *app)
                return 0;
 
        status = access(app->config_file, F_OK | R_OK);
-       APP_CHECK((status == 0), "Unable to open file %s", app->config_file);
+       APP_CHECK((status == 0), "Error: Unable to open file %s",
+               app->config_file);
 
        snprintf(buffer, sizeof(buffer), "%s %s %s > %s",
                app->preproc,
@@ -2690,7 +2929,8 @@ app_config_preproc(struct app_params *app)
 
        status = system(buffer);
        APP_CHECK((WIFEXITED(status) && (WEXITSTATUS(status) == 0)),
-               "Error while preprocessing file \"%s\"\n", app->config_file);
+               "Error occurred while pre-processing file \"%s\"\n",
+               app->config_file);
 
        return status;
 }
diff --git a/examples/ip_pipeline/parser.h b/examples/ip_pipeline/parser.h
new file mode 100644 (file)
index 0000000..58b59da
--- /dev/null
@@ -0,0 +1,50 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __INCLUDE_PARSER_H__
+#define __INCLUDE_PARSER_H__
+
+int
+parser_read_arg_bool(const char *p);
+
+int
+parser_read_uint64(uint64_t *value, const char *p);
+
+int
+parser_read_uint32(uint32_t *value, const char *p);
+
+int
+parse_hex_string(char *src, uint8_t *dst, uint32_t *size);
+
+#endif
+
index 1c376f7..1981cc7 100644 (file)
@@ -42,6 +42,7 @@
 #include <rte_table_acl.h>
 
 #include "pipeline_firewall_be.h"
+#include "parser.h"
 
 struct pipeline_firewall {
        struct pipeline p;
@@ -308,17 +309,26 @@ pipeline_firewall_parse_args(struct pipeline_firewall *p,
                char *arg_value = params->args_value[i];
 
                if (strcmp(arg_name, "n_rules") == 0) {
-                       if (n_rules_present)
-                               return -1;
+                       int status;
+
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               n_rules_present == 0, params->name,
+                               arg_name);
                        n_rules_present = 1;
 
-                       p->n_rules = atoi(arg_value);
+                       status = parser_read_uint32(&p->n_rules,
+                               arg_value);
+                       PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
+                               params->name, arg_name, arg_value);
+                       PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
+                               params->name, arg_name, arg_value);
                        continue;
                }
 
                if (strcmp(arg_name, "pkt_type") == 0) {
-                       if (pkt_type_present)
-                               return -1;
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               pkt_type_present == 0, params->name,
+                               arg_name);
                        pkt_type_present = 1;
 
                        /* ipv4 */
@@ -351,11 +361,12 @@ pipeline_firewall_parse_args(struct pipeline_firewall *p,
                        }
 
                        /* other */
-                       return -1;
+                       PIPELINE_PARSE_ERR_INV_VAL(0, params->name,
+                               arg_name, arg_value);
                }
 
                /* other */
-               return -1;
+               PIPELINE_PARSE_ERR_INV_ENT(0, params->name, arg_name);
        }
 
        return 0;
index ec149c8..0dfdb05 100644 (file)
@@ -42,6 +42,7 @@
 
 #include "pipeline_actions_common.h"
 #include "pipeline_flow_actions_be.h"
+#include "parser.h"
 #include "hash_func.h"
 
 int
@@ -415,80 +416,118 @@ pipeline_fa_parse_args(struct pipeline_fa_params *p,
 
                /* n_flows */
                if (strcmp(arg_name, "n_flows") == 0) {
-                       if (n_flows_present)
-                               return -1;
+                       int status;
 
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               n_flows_present == 0, params->name,
+                               arg_name);
                        n_flows_present = 1;
 
-                       p->n_flows = atoi(arg_value);
-                       if (p->n_flows == 0)
-                               return -1;
+                       status = parser_read_uint32(&p->n_flows,
+                               arg_value);
+                       PIPELINE_PARSE_ERR_INV_VAL(((status != -EINVAL) &&
+                               (p->n_flows != 0)), params->name,
+                               arg_name, arg_value);
+                       PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
+                               params->name, arg_name, arg_value);
 
                        continue;
                }
 
                /* n_meters_per_flow */
                if (strcmp(arg_name, "n_meters_per_flow") == 0) {
-                       if (n_meters_per_flow_present)
-                               return -1;
+                       int status;
 
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               n_meters_per_flow_present == 0,
+                               params->name, arg_name);
                        n_meters_per_flow_present = 1;
 
-                       p->n_meters_per_flow = atoi(arg_value);
-                       if ((p->n_meters_per_flow == 0) ||
-                               (p->n_meters_per_flow > PIPELINE_FA_N_TC_MAX))
-                               return -1;
+                       status = parser_read_uint32(&p->n_meters_per_flow,
+                               arg_value);
+                       PIPELINE_PARSE_ERR_INV_VAL(((status != -EINVAL) &&
+                               (p->n_meters_per_flow != 0)),
+                               params->name, arg_name, arg_value);
+                       PIPELINE_PARSE_ERR_OUT_RNG(((status != -ERANGE) &&
+                               (p->n_meters_per_flow <=
+                               PIPELINE_FA_N_TC_MAX)), params->name,
+                               arg_name, arg_value);
 
                        continue;
                }
 
                /* flow_id_offset */
                if (strcmp(arg_name, "flow_id_offset") == 0) {
-                       if (flow_id_offset_present)
-                               return -1;
+                       int status;
 
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               flow_id_offset_present == 0,
+                               params->name, arg_name);
                        flow_id_offset_present = 1;
 
-                       p->flow_id_offset = atoi(arg_value);
+                       status = parser_read_uint32(&p->flow_id_offset,
+                               arg_value);
+                       PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
+                               params->name, arg_name, arg_value);
+                       PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
+                               params->name, arg_name, arg_value);
 
                        continue;
                }
 
                /* ip_hdr_offset */
                if (strcmp(arg_name, "ip_hdr_offset") == 0) {
-                       if (ip_hdr_offset_present)
-                               return -1;
+                       int status;
 
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               ip_hdr_offset_present == 0,
+                               params->name, arg_name);
                        ip_hdr_offset_present = 1;
 
-                       p->ip_hdr_offset = atoi(arg_value);
+                       status = parser_read_uint32(&p->ip_hdr_offset,
+                               arg_value);
+                       PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
+                               params->name, arg_name, arg_value);
+                       PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
+                               params->name, arg_name, arg_value);
 
                        continue;
                }
 
                /* color_offset */
                if (strcmp(arg_name, "color_offset") == 0) {
-                       if (color_offset_present)
-                               return -1;
+                       int status;
 
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               color_offset_present == 0, params->name,
+                               arg_name);
                        color_offset_present = 1;
 
+                       status = parser_read_uint32(&p->color_offset,
+                               arg_value);
+                       PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
+                               params->name, arg_name, arg_value);
+                       PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
+                               params->name, arg_name, arg_value);
+
                        p->dscp_enabled = 1;
-                       p->color_offset = atoi(arg_value);
 
                        continue;
                }
 
                /* Unknown argument */
-               return -1;
+               PIPELINE_PARSE_ERR_INV_ENT(0, params->name, arg_name);
        }
 
        /* Check that mandatory arguments are present */
-       if ((n_flows_present == 0) ||
-               (flow_id_offset_present == 0) ||
-               (ip_hdr_offset_present == 0) ||
-               (color_offset_present == 0))
-               return -1;
+       PIPELINE_PARSE_ERR_MANDATORY((n_flows_present), params->name,
+               "n_flows");
+       PIPELINE_PARSE_ERR_MANDATORY((flow_id_offset_present),
+               params->name, "flow_id_offset");
+       PIPELINE_PARSE_ERR_MANDATORY((ip_hdr_offset_present),
+               params->name, "ip_hdr_offset");
+       PIPELINE_PARSE_ERR_MANDATORY((color_offset_present), params->name,
+               "color_offset");
 
        return 0;
 }
index ac80fc6..c528dfb 100644 (file)
@@ -41,6 +41,7 @@
 
 #include "pipeline_flow_classification_be.h"
 #include "pipeline_actions_common.h"
+#include "parser.h"
 #include "hash_func.h"
 
 struct pipeline_flow_classification {
@@ -53,7 +54,7 @@ struct pipeline_flow_classification {
 
        uint32_t key_offset;
        uint32_t hash_offset;
-       uint8_t *key_mask;
+       uint8_t key_mask[PIPELINE_FC_FLOW_KEY_MAX_SIZE];
        uint32_t flow_id_offset;
 
 } __rte_cache_aligned;
@@ -219,7 +220,7 @@ pipeline_fc_parse_args(struct pipeline_flow_classification *p,
        uint32_t flow_id_offset_present = 0;
 
        uint32_t i;
-       char *key_mask_str = NULL;
+       char key_mask_str[PIPELINE_FC_FLOW_KEY_MAX_SIZE * 2];
 
        p->hash_offset = 0;
 
@@ -232,110 +233,157 @@ pipeline_fc_parse_args(struct pipeline_flow_classification *p,
 
                /* n_flows */
                if (strcmp(arg_name, "n_flows") == 0) {
-                       if (n_flows_present)
-                               goto error_parse;
+                       int status;
+
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               n_flows_present == 0, params->name,
+                               arg_name);
                        n_flows_present = 1;
 
-                       p->n_flows = atoi(arg_value);
-                       if (p->n_flows == 0)
-                               goto error_parse;
+                       status = parser_read_uint32(&p->n_flows,
+                               arg_value);
+                       PIPELINE_PARSE_ERR_INV_VAL(((status != -EINVAL) &&
+                               (p->n_flows != 0)), params->name,
+                               arg_name, arg_value);
+                       PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
+                               params->name, arg_name, arg_value);
 
                        continue;
                }
 
                /* key_offset */
                if (strcmp(arg_name, "key_offset") == 0) {
-                       if (key_offset_present)
-                               goto error_parse;
+                       int status;
 
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               key_offset_present == 0, params->name,
+                               arg_name);
                        key_offset_present = 1;
 
-                       p->key_offset = atoi(arg_value);
+                       status = parser_read_uint32(&p->key_offset,
+                               arg_value);
+                       PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
+                               params->name, arg_name, arg_value);
+                       PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
+                               params->name, arg_name, arg_value);
 
                        continue;
                }
 
                /* key_size */
                if (strcmp(arg_name, "key_size") == 0) {
-                       if (key_size_present)
-                               goto error_parse;
+                       int status;
+
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               key_size_present == 0, params->name,
+                               arg_name);
                        key_size_present = 1;
 
-                       p->key_size = atoi(arg_value);
-                       if ((p->key_size == 0) ||
-                               (p->key_size > PIPELINE_FC_FLOW_KEY_MAX_SIZE) ||
-                               (p->key_size % 8))
-                               goto error_parse;
+                       status = parser_read_uint32(&p->key_size,
+                               arg_value);
+                       PIPELINE_PARSE_ERR_INV_VAL(((status != -EINVAL) &&
+                               (p->key_size != 0) &&
+                               (p->key_size % 8 == 0)),
+                               params->name, arg_name, arg_value);
+                       PIPELINE_PARSE_ERR_OUT_RNG(((status != -ERANGE) &&
+                               (p->key_size <=
+                               PIPELINE_FC_FLOW_KEY_MAX_SIZE)),
+                               params->name, arg_name, arg_value);
 
                        continue;
                }
 
                /* key_mask */
                if (strcmp(arg_name, "key_mask") == 0) {
-                       if (key_mask_present)
-                               goto error_parse;
-
-                       key_mask_str = strdup(arg_value);
-                       if (key_mask_str == NULL)
-                               goto error_parse;
+                       int mask_str_len = strlen(arg_value);
 
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               key_mask_present == 0,
+                               params->name, arg_name);
                        key_mask_present = 1;
 
+                       PIPELINE_ARG_CHECK((mask_str_len <
+                               (PIPELINE_FC_FLOW_KEY_MAX_SIZE * 2)),
+                               "Parse error in section \"%s\": entry "
+                               "\"%s\" is too long", params->name,
+                               arg_name);
+
+                       snprintf(key_mask_str, mask_str_len, "%s",
+                               arg_value);
+
                        continue;
                }
 
                /* hash_offset */
                if (strcmp(arg_name, "hash_offset") == 0) {
-                       if (hash_offset_present)
-                               goto error_parse;
+                       int status;
+
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               hash_offset_present == 0, params->name,
+                               arg_name);
                        hash_offset_present = 1;
 
-                       p->hash_offset = atoi(arg_value);
+                       status = parser_read_uint32(&p->hash_offset,
+                               arg_value);
+                       PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
+                               params->name, arg_name, arg_value);
+                       PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
+                               params->name, arg_name, arg_value);
 
                        continue;
                }
 
                /* flow_id_offset */
                if (strcmp(arg_name, "flowid_offset") == 0) {
-                       if (flow_id_offset_present)
-                               goto error_parse;
+                       int status;
+
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               flow_id_offset_present == 0, params->name,
+                               arg_name);
                        flow_id_offset_present = 1;
 
+                       status = parser_read_uint32(&p->flow_id_offset,
+                               arg_value);
+                       PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
+                               params->name, arg_name, arg_value);
+                       PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
+                               params->name, arg_name, arg_value);
+
                        p->flow_id = 1;
-                       p->flow_id_offset = atoi(arg_value);
 
                        continue;
                }
 
                /* Unknown argument */
-               goto error_parse;
+               PIPELINE_PARSE_ERR_INV_ENT(0, params->name, arg_name);
        }
 
        /* Check that mandatory arguments are present */
-       if ((n_flows_present == 0) ||
-               (key_offset_present == 0) ||
-               (key_size_present == 0))
-               goto error_parse;
+       PIPELINE_PARSE_ERR_MANDATORY((n_flows_present), params->name,
+               "n_flows");
+       PIPELINE_PARSE_ERR_MANDATORY((key_offset_present), params->name,
+               "key_offset");
+       PIPELINE_PARSE_ERR_MANDATORY((key_size_present), params->name,
+               "key_size");
 
        if (key_mask_present) {
-               p->key_mask = rte_malloc(NULL, p->key_size, 0);
-               if (p->key_mask == NULL)
-                       goto error_parse;
+               uint32_t key_size = p->key_size;
+               int status;
 
-               if (parse_hex_string(key_mask_str, p->key_mask, &p->key_size)
-                       != 0) {
-                       goto error_parse;
-               }
+               PIPELINE_ARG_CHECK((strlen(key_mask_str) ==
+                       (key_size * 2)), "Parse error in section "
+                       "\"%s\": key_mask should have exactly %u hex "
+                       "digits", params->name, (key_size * 2));
 
-               free(key_mask_str);
+               status = parse_hex_string(key_mask_str, p->key_mask,
+                       &p->key_size);
+
+               PIPELINE_PARSE_ERR_INV_VAL(((status == 0) &&
+                       (key_size == p->key_size)), params->name,
+                       "key_mask", key_mask_str);
        }
 
        return 0;
-
-error_parse:
-       free(key_mask_str);
-       free(p->key_mask);
-       return -1;
 }
 
 static void *pipeline_fc_init(struct pipeline_params *params,
index a898f7d..630de3b 100644 (file)
@@ -42,6 +42,7 @@
 
 #include "pipeline_passthrough_be.h"
 #include "pipeline_actions_common.h"
+#include "parser.h"
 #include "hash_func.h"
 
 struct pipeline_passthrough {
@@ -238,6 +239,7 @@ pipeline_passthrough_parse_args(struct pipeline_passthrough_params *p,
        uint32_t dma_size_present = 0;
        uint32_t dma_hash_offset_present = 0;
        uint32_t i;
+       char dma_mask_str[PIPELINE_PASSTHROUGH_DMA_SIZE_MAX * 2];
 
        /* default values */
        p->dma_enabled = 0;
@@ -250,11 +252,20 @@ pipeline_passthrough_parse_args(struct pipeline_passthrough_params *p,
 
                /* dma_dst_offset */
                if (strcmp(arg_name, "dma_dst_offset") == 0) {
-                       if (dma_dst_offset_present)
-                               return -1;
+                       int status;
+
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               dma_dst_offset_present == 0, params->name,
+                               arg_name);
                        dma_dst_offset_present = 1;
 
-                       p->dma_dst_offset = atoi(arg_value);
+                       status = parser_read_uint32(&p->dma_dst_offset,
+                               arg_value);
+                       PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
+                               params->name, arg_name, arg_value);
+                       PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
+                               params->name, arg_name, arg_value);
+
                        p->dma_enabled = 1;
 
                        continue;
@@ -262,11 +273,20 @@ pipeline_passthrough_parse_args(struct pipeline_passthrough_params *p,
 
                /* dma_src_offset */
                if (strcmp(arg_name, "dma_src_offset") == 0) {
-                       if (dma_src_offset_present)
-                               return -1;
+                       int status;
+
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               dma_src_offset_present == 0, params->name,
+                               arg_name);
                        dma_src_offset_present = 1;
 
-                       p->dma_src_offset = atoi(arg_value);
+                       status = parser_read_uint32(&p->dma_src_offset,
+                               arg_value);
+                       PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
+                               params->name, arg_name, arg_value);
+                       PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
+                               params->name, arg_name, arg_value);
+
                        p->dma_enabled = 1;
 
                        continue;
@@ -274,15 +294,23 @@ pipeline_passthrough_parse_args(struct pipeline_passthrough_params *p,
 
                /* dma_size */
                if (strcmp(arg_name, "dma_size") == 0) {
-                       if (dma_size_present)
-                               return -1;
+                       int status;
+
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               dma_size_present == 0, params->name,
+                               arg_name);
                        dma_size_present = 1;
 
-                       p->dma_size = atoi(arg_value);
-                       if ((p->dma_size == 0) ||
-                               (p->dma_size > PIPELINE_PASSTHROUGH_DMA_SIZE_MAX) ||
-                               ((p->dma_size % 8) != 0))
-                               return -1;
+                       status = parser_read_uint32(&p->dma_size,
+                               arg_value);
+                       PIPELINE_PARSE_ERR_INV_VAL(((status != -EINVAL) &&
+                               (p->dma_size != 0) &&
+                               ((p->dma_size % 8) == 0)),
+                               params->name, arg_name, arg_value);
+                       PIPELINE_PARSE_ERR_OUT_RNG(((status != -ERANGE) &&
+                               (p->dma_size <=
+                               PIPELINE_PASSTHROUGH_DMA_SIZE_MAX)),
+                               params->name, arg_name, arg_value);
 
                        p->dma_enabled = 1;
 
@@ -291,34 +319,22 @@ pipeline_passthrough_parse_args(struct pipeline_passthrough_params *p,
 
                /* dma_src_mask */
                if (strcmp(arg_name, "dma_src_mask") == 0) {
-                       uint32_t dma_size;
-                       int status;
+                       int mask_str_len = strlen(arg_value);
 
-                       if (dma_src_mask_present ||
-                               (dma_size_present == 0))
-                               return -1;
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               dma_src_mask_present == 0,
+                               params->name, arg_name);
                        dma_src_mask_present = 1;
 
-                       dma_size = p->dma_size;
-                       status = parse_hex_string(arg_value,
-                               p->dma_src_mask,
-                               &dma_size);
-                       if (status ||
-                               (dma_size != p->dma_size))
-                               return -1;
+                       PIPELINE_ARG_CHECK((mask_str_len <
+                               (PIPELINE_PASSTHROUGH_DMA_SIZE_MAX * 2)),
+                               "Parse error in section \"%s\": entry "
+                               "\"%s\" too long", params->name,
+                               arg_name);
 
-                       p->dma_enabled = 1;
+                       snprintf(dma_mask_str, mask_str_len + 1,
+                               "%s", arg_value);
 
-                       continue;
-               }
-
-               /* dma_dst_offset */
-               if (strcmp(arg_name, "dma_dst_offset") == 0) {
-                       if (dma_dst_offset_present)
-                               return -1;
-                       dma_dst_offset_present = 1;
-
-                       p->dma_dst_offset = atoi(arg_value);
                        p->dma_enabled = 1;
 
                        continue;
@@ -326,11 +342,20 @@ pipeline_passthrough_parse_args(struct pipeline_passthrough_params *p,
 
                /* dma_hash_offset */
                if (strcmp(arg_name, "dma_hash_offset") == 0) {
-                       if (dma_hash_offset_present)
-                               return -1;
+                       int status;
+
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               dma_hash_offset_present == 0,
+                               params->name, arg_name);
                        dma_hash_offset_present = 1;
 
-                       p->dma_hash_offset = atoi(arg_value);
+                       status = parser_read_uint32(&p->dma_hash_offset,
+                               arg_value);
+                       PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
+                               params->name, arg_name, arg_value);
+                       PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
+                               params->name, arg_name, arg_value);
+
                        p->dma_hash_enabled = 1;
                        p->dma_enabled = 1;
 
@@ -338,16 +363,39 @@ pipeline_passthrough_parse_args(struct pipeline_passthrough_params *p,
                }
 
                /* any other */
-               return -1;
+               PIPELINE_PARSE_ERR_INV_ENT(0, params->name, arg_name);
        }
 
        /* Check correlations between arguments */
-       if ((dma_dst_offset_present != p->dma_enabled) ||
-               (dma_src_offset_present != p->dma_enabled) ||
-               (dma_size_present != p->dma_enabled) ||
-               (dma_hash_offset_present != p->dma_hash_enabled) ||
-               (p->dma_hash_enabled > p->dma_enabled))
-               return -1;
+       PIPELINE_ARG_CHECK((dma_dst_offset_present == p->dma_enabled),
+               "Parse error in section \"%s\": missing entry "
+               "\"dma_dst_offset\"", params->name);
+       PIPELINE_ARG_CHECK((dma_src_offset_present == p->dma_enabled),
+               "Parse error in section \"%s\": missing entry "
+               "\"dma_src_offset\"", params->name);
+       PIPELINE_ARG_CHECK((dma_size_present == p->dma_enabled),
+               "Parse error in section \"%s\": missing entry "
+               "\"dma_size\"", params->name);
+       PIPELINE_ARG_CHECK((dma_hash_offset_present == p->dma_enabled),
+               "Parse error in section \"%s\": missing entry "
+               "\"dma_hash_offset\"", params->name);
+
+       if (dma_src_mask_present) {
+               uint32_t dma_size = p->dma_size;
+               int status;
+
+               PIPELINE_ARG_CHECK((strlen(dma_mask_str) ==
+                       (dma_size * 2)), "Parse error in section "
+                       "\"%s\": dma_src_mask should have exactly %u hex "
+                       "digits", params->name, (dma_size * 2));
+
+               status = parse_hex_string(dma_mask_str, p->dma_src_mask,
+                       &p->dma_size);
+
+               PIPELINE_PARSE_ERR_INV_VAL(((status == 0) &&
+                       (dma_size == p->dma_size)), params->name,
+                       "dma_src_mask", dma_mask_str);
+       }
 
        return 0;
 }
index 9baabd0..4fb6b59 100644 (file)
@@ -47,6 +47,7 @@
 
 #include "pipeline_routing_be.h"
 #include "pipeline_actions_common.h"
+#include "parser.h"
 #include "hash_func.h"
 
 #define MPLS_LABEL(label, exp, s, ttl)                                 \
@@ -940,21 +941,28 @@ pipeline_routing_parse_args(struct pipeline_routing_params *p,
 
                /* n_routes */
                if (strcmp(arg_name, "n_routes") == 0) {
-                       if (n_routes_present)
-                               return -1;
+                       int status;
+
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               n_routes_present == 0, params->name,
+                               arg_name);
                        n_routes_present = 1;
 
-                       p->n_routes = atoi(arg_value);
-                       if (p->n_routes == 0)
-                               return -1;
+                       status = parser_read_uint32(&p->n_routes,
+                               arg_value);
+                       PIPELINE_PARSE_ERR_INV_VAL(((status != -EINVAL) &&
+                               (p->n_routes != 0)), params->name,
+                               arg_name, arg_value);
+                       PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
+                               params->name, arg_name, arg_value);
 
                        continue;
                }
 
                /* encap */
                if (strcmp(arg_name, "encap") == 0) {
-                       if (encap_present)
-                               return -1;
+                       PIPELINE_PARSE_ERR_DUPLICATE(encap_present == 0,
+                               params->name, arg_name);
                        encap_present = 1;
 
                        /* ethernet */
@@ -976,140 +984,204 @@ pipeline_routing_parse_args(struct pipeline_routing_params *p,
                        }
 
                        /* any other */
-                       return -1;
+                       PIPELINE_PARSE_ERR_INV_VAL(0, params->name,
+                               arg_name, arg_value);
                }
 
                /* qinq_sched */
                if (strcmp(arg_name, "qinq_sched") == 0) {
-                       if (qinq_sched_present)
-                               return -1;
+                       int status;
 
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               qinq_sched_present == 0, params->name,
+                               arg_name);
                        qinq_sched_present = 1;
 
-                       if (strcmp(arg_value, "no") == 0)
-                               p->qinq_sched = 0;
-                       else if (strcmp(arg_value, "yes") == 0)
-                               p->qinq_sched = 1;
-                       else if (strcmp(arg_value, "test") == 0)
-                               p->qinq_sched = 2;
-                       else
-                               return -1;
+                       status = parser_read_arg_bool(arg_value);
+                       if (status == -EINVAL) {
+                               if (strcmp(arg_value, "test") == 0) {
+                                       p->qinq_sched = 2;
+                                       continue;
+                               }
+                       } else {
+                               p->qinq_sched = status;
+                               continue;
+                       }
 
-                       continue;
+                       PIPELINE_PARSE_ERR_INV_VAL(0, params->name,
+                               arg_name, arg_value);
                }
 
                /* mpls_color_mark */
                if (strcmp(arg_name, "mpls_color_mark") == 0) {
-                       if (mpls_color_mark_present)
-                               return -1;
+                       int status;
 
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               mpls_color_mark_present == 0,
+                               params->name, arg_name);
                        mpls_color_mark_present = 1;
 
-                       if (strcmp(arg_value, "no") == 0)
-                               p->mpls_color_mark = 0;
-                       else if (strcmp(arg_value, "yes") == 0)
-                               p->mpls_color_mark = 1;
-                       else
-                               return -1;
 
-                       continue;
+                       status = parser_read_arg_bool(arg_value);
+                       if (status >= 0) {
+                               p->mpls_color_mark = status;
+                               continue;
+                       }
+
+                       PIPELINE_PARSE_ERR_INV_VAL(0, params->name,
+                               arg_name, arg_value);
                }
 
                /* n_arp_entries */
                if (strcmp(arg_name, "n_arp_entries") == 0) {
-                       if (n_arp_entries_present)
-                               return -1;
+                       int status;
+
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               n_arp_entries_present == 0, params->name,
+                               arg_name);
                        n_arp_entries_present = 1;
 
-                       p->n_arp_entries = atoi(arg_value);
+                       status = parser_read_uint32(&p->n_arp_entries,
+                               arg_value);
+                       PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
+                               params->name, arg_name, arg_value);
+                       PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
+                               params->name, arg_name, arg_value);
 
                        continue;
                }
 
                /* ip_hdr_offset */
                if (strcmp(arg_name, "ip_hdr_offset") == 0) {
-                       if (ip_hdr_offset_present)
-                               return -1;
+                       int status;
+
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               ip_hdr_offset_present == 0, params->name,
+                               arg_name);
                        ip_hdr_offset_present = 1;
 
-                       p->ip_hdr_offset = atoi(arg_value);
+                       status = parser_read_uint32(&p->ip_hdr_offset,
+                               arg_value);
+                       PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
+                               params->name, arg_name, arg_value);
+                       PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
+                               params->name, arg_name, arg_value);
 
                        continue;
                }
 
                /* arp_key_offset */
                if (strcmp(arg_name, "arp_key_offset") == 0) {
-                       if (arp_key_offset_present)
-                               return -1;
+                       int status;
+
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               arp_key_offset_present == 0, params->name,
+                               arg_name);
                        arp_key_offset_present = 1;
 
-                       p->arp_key_offset = atoi(arg_value);
+                       status = parser_read_uint32(&p->arp_key_offset,
+                               arg_value);
+                       PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
+                               params->name, arg_name, arg_value);
+                       PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
+                               params->name, arg_name, arg_value);
 
                        continue;
                }
 
                /* color_offset */
                if (strcmp(arg_name, "color_offset") == 0) {
-                       if (color_offset_present)
-                               return -1;
+                       int status;
+
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               color_offset_present == 0, params->name,
+                               arg_name);
                        color_offset_present = 1;
 
-                       p->color_offset = atoi(arg_value);
+                       status = parser_read_uint32(&p->color_offset,
+                               arg_value);
+                       PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
+                               params->name, arg_name, arg_value);
+                       PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
+                               params->name, arg_name, arg_value);
 
                        continue;
                }
 
                /* debug */
                if (strcmp(arg_name, "dbg_ah_disable") == 0) {
-                       if (dbg_ah_disable_present)
-                               return -1;
+                       int status;
+
+                       PIPELINE_PARSE_ERR_DUPLICATE(
+                               dbg_ah_disable_present == 0, params->name,
+                               arg_name);
                        dbg_ah_disable_present = 1;
 
-                       if (strcmp(arg_value, "no") == 0)
-                               p->dbg_ah_disable = 0;
-                       else if (strcmp(arg_value, "yes") == 0)
-                               p->dbg_ah_disable = 1;
-                       else
-                               return -1;
+                       status = parser_read_arg_bool(arg_value);
+                       if (status >= 0) {
+                               p->dbg_ah_disable = status;
+                               continue;
+                       }
+
+                       PIPELINE_PARSE_ERR_INV_VAL(0, params->name,
+                               arg_name, arg_value);
 
                        continue;
                }
 
                /* any other */
-               return -1;
+               PIPELINE_PARSE_ERR_INV_ENT(0, params->name, arg_name);
        }
 
        /* Check that mandatory arguments are present */
-       if (ip_hdr_offset_present == 0)
-               return -1;
+       PIPELINE_PARSE_ERR_MANDATORY(ip_hdr_offset_present, params->name,
+               "ip_hdr_offset");
 
        /* Check relations between arguments */
        switch (p->encap) {
        case PIPELINE_ROUTING_ENCAP_ETHERNET:
-               if (p->qinq_sched ||
-                       p->mpls_color_mark ||
-                       color_offset_present)
-                       return -1;
+               PIPELINE_ARG_CHECK((!p->qinq_sched), "Parse error in "
+                       "section \"%s\": encap = ethernet, therefore "
+                       "qinq_sched = yes/test is not allowed",
+                       params->name);
+               PIPELINE_ARG_CHECK((!p->mpls_color_mark), "Parse error "
+                       "in section \"%s\": encap = ethernet, therefore "
+                       "mpls_color_mark = yes is not allowed",
+                       params->name);
+               PIPELINE_ARG_CHECK((!color_offset_present), "Parse error "
+                       "in section \"%s\": encap = ethernet, therefore "
+                       "color_offset is not allowed",
+                       params->name);
                break;
 
        case PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ:
-               if (p->mpls_color_mark ||
-                       color_offset_present)
-                       return -1;
+               PIPELINE_ARG_CHECK((!p->mpls_color_mark), "Parse error "
+                       "in section \"%s\": encap = ethernet_qinq, "
+                       "therefore mpls_color_mark = yes is not allowed",
+                       params->name);
+               PIPELINE_ARG_CHECK((!color_offset_present), "Parse error "
+                       "in section \"%s\": encap = ethernet_qinq, "
+                       "therefore color_offset is not allowed",
+                       params->name);
                break;
 
        case PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS:
-               if (p->qinq_sched)
-                       return -1;
+               PIPELINE_ARG_CHECK((!p->qinq_sched), "Parse error in "
+                       "section \"%s\": encap = ethernet_mpls, therefore "
+                       "qinq_sched  = yes/test is not allowed",
+                       params->name);
                break;
-
-       default:
-               return -1;
        }
 
-       if ((p->n_arp_entries && (arp_key_offset_present == 0)) ||
-               ((p->n_arp_entries == 0) && arp_key_offset_present))
-               return -1;
+       PIPELINE_ARG_CHECK((!(p->n_arp_entries &&
+               (!arp_key_offset_present))), "Parse error in section "
+                       "\"%s\": n_arp_entries is set while "
+                       "arp_key_offset is not set", params->name);
+
+       PIPELINE_ARG_CHECK((!((p->n_arp_entries == 0) &&
+               arp_key_offset_present)), "Parse error in section "
+                       "\"%s\": arp_key_offset present while "
+                       "n_arp_entries is not set", params->name);
 
        return 0;
 }
index 0ba00f6..d820435 100644 (file)
@@ -271,8 +271,33 @@ struct pipeline_be_ops {
        pipeline_be_op_track f_track;
 };
 
-/* Parse hex string to uint8_t array */
-int
-parse_hex_string(char *src, uint8_t *dst, uint32_t *size);
+/* Pipeline specific config parse error messages */
+#define PIPELINE_ARG_CHECK(exp, fmt, ...)                              \
+do {                                                                   \
+       if (!(exp)) {                                                   \
+               fprintf(stderr, fmt "\n", ## __VA_ARGS__);              \
+               return -1;                                              \
+       }                                                               \
+} while (0)
+
+#define PIPELINE_PARSE_ERR_INV_VAL(exp, section, entry, val)           \
+PIPELINE_ARG_CHECK(exp, "Parse error in section \"%s\": entry \"%s\" " \
+       "has invalid value (\"%s\")", section, entry, val)
+
+#define PIPELINE_PARSE_ERR_OUT_RNG(exp, section, entry, val)           \
+PIPELINE_ARG_CHECK(exp, "Parse error in section \"%s\": entry \"%s\" " \
+       "value is out of range (\"%s\")", section, entry, val)
+
+#define PIPELINE_PARSE_ERR_DUPLICATE(exp, section, entry)              \
+PIPELINE_ARG_CHECK(exp, "Parse error in section \"%s\": duplicated "   \
+       "entry \"%s\"", section, entry)
+
+#define PIPELINE_PARSE_ERR_INV_ENT(exp, section, entry)                        \
+PIPELINE_ARG_CHECK(exp, "Parse error in section \"%s\": invalid entry "        \
+       "\"%s\"", section, entry)
+
+#define PIPELINE_PARSE_ERR_MANDATORY(exp, section, entry)              \
+PIPELINE_ARG_CHECK(exp, "Parse error in section \"%s\": mandatory "    \
+       "entry \"%s\" is missing", section, entry)
 
 #endif