examples/ip_pipeline: clean config parser

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>
This commit is contained in:
Fan Zhang 2016-02-17 11:14:11 +00:00 committed by Thomas Monjalon
parent 3cdf882614
commit 1a33c5ea2f
8 changed files with 1121 additions and 588 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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

View 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;

View 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;
}

View 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,

View 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;
}

View 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;
}

View 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