[spp] [PATCH 1/4] spp_vf: fix to eliminate jansson package

Yasufumi Ogawa ogawa.yasufumi at lab.ntt.co.jp
Fri Jan 19 01:37:03 CET 2018


Hi Ferruh,

I reviewd patches for updating to 17.11 and it is OK. Could you merge it?

Acked-by: Yasufumi Ogawa <ogawa.yasufumi at lab.ntt.co.jp>

Thanks,
Yasufumi


On 2018/01/10 11:47, x-fn-spp at sl.ntt-tx.co.jp wrote:
> From: Hiroyuki Nakamura <nakamura.hioryuki at po.ntt-tx.co.jp>
> 
> * For ease of build, eliminate the use of Jansson package.
>    Command response message in JSON is generated by our own codes
>    in src/vf/command_proc.c.
> * Due to above changes, src/vf/spp_config.c and src/vf/spp_config.h
>    are deleted.
> 
> Signed-off-by: Kentaro Watanabe <watanabe.kentaro.z01 at as.ntt-tx.co.jp>
> Signed-off-by: Yasufum Ogawa <ogawa.yasufumi at lab.ntt.co.jp>
> ---
>   src/spp_vf.py           |   4 +-
>   src/vf/Makefile         |   1 -
>   src/vf/classifier_mac.c |   9 +-
>   src/vf/classifier_mac.h |   4 +-
>   src/vf/command_proc.c   | 865 +++++++++++++++++++++++++++++++-----------------
>   src/vf/spp_config.c     | 785 -------------------------------------------
>   src/vf/spp_config.h     | 126 -------
>   src/vf/spp_forward.c    |   7 +-
>   src/vf/spp_forward.h    |   5 +-
>   src/vf/spp_vf.c         |   6 +-
>   src/vf/spp_vf.h         |  10 +-
>   src/vf/string_buffer.c  |  17 +-
>   12 files changed, 595 insertions(+), 1244 deletions(-)
>   delete mode 100644 src/vf/spp_config.c
>   delete mode 100644 src/vf/spp_config.h
> 
> diff --git a/src/spp_vf.py b/src/spp_vf.py
> index a96b987..c0706c0 100755
> --- a/src/spp_vf.py
> +++ b/src/spp_vf.py
> @@ -41,6 +41,7 @@ def connectionthread(name, client_id, conn, m2s, s2m):
>   
>       cmd_str = 'hello'
>       recv_str = 'recv'
> +    recv_json = None
>   
>       #infinite loop so that function do not terminate and thread do not end.
>       while True:
> @@ -71,7 +72,8 @@ def connectionthread(name, client_id, conn, m2s, s2m):
>                   else:
>                       break
>               if len(recv_str) > 0:
> -                recv_str = "recv:" + str(conn.fileno()) + ":len:" + str(len(recv_str)) + ":\n{" + recv_str + "}\n"
> +                recv_json = json.loads(recv_str)
> +                recv_str = "recv:" + str(conn.fileno()) + ":len:" + str(len(recv_str)) + ":\n" + json.dumps(recv_json, indent=4) + "\n"
>   
>               if not data:
>                   s2m.put(recv_str + "closing:" + str(conn))
> diff --git a/src/vf/Makefile b/src/vf/Makefile
> index a2ac128..503b50b 100644
> --- a/src/vf/Makefile
> +++ b/src/vf/Makefile
> @@ -47,7 +47,6 @@ CFLAGS += -I$(SRCDIR)/../shared
>   #CFLAGS += -DSPP_DEMONIZE
>   #CFLAGS += -DSPP_RINGLATENCYSTATS_ENABLE
>   
> -LDLIBS += -ljansson
>   ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
>   LDLIBS += -lrte_pmd_ring
>   LDLIBS += -lrte_pmd_vhost
> diff --git a/src/vf/classifier_mac.c b/src/vf/classifier_mac.c
> index 333b581..b42c4ac 100644
> --- a/src/vf/classifier_mac.c
> +++ b/src/vf/classifier_mac.c
> @@ -589,7 +589,8 @@ spp_classifier_mac_do(int id)
>   
>   /* classifier iterate component information */
>   int
> -spp_classifier_component_info_iterate(unsigned int lcore_id, int id,
> +spp_classifier_get_component_status(
> +		unsigned int lcore_id, int id,
>   		struct spp_iterate_core_params *params)
>   {
>   	int ret = -1;
> @@ -629,7 +630,7 @@ spp_classifier_component_info_iterate(unsigned int lcore_id, int id,
>   
>   	/* Set the information with the function specified by the command. */
>   	ret = (*params->element_proc)(
> -		params->opaque, lcore_id,
> +		params, lcore_id,
>   		classifier_info->name, SPP_TYPE_CLASSIFIER_MAC_STR,
>   		num_rx, rx_ports, num_tx, tx_ports);
>   	if (unlikely(ret != 0))
> @@ -671,7 +672,7 @@ spp_classifier_mac_iterate_table(
>   			port.if_no   = (classified_data + classifier_info->default_classified)->if_no_global;
>   
>   			(*params->element_proc)(
> -					params->opaque,
> +					params,
>   					SPP_CLASSIFIER_TYPE_MAC,
>   					SPP_DEFAULT_CLASSIFIED_SPEC_STR,
>   					&port);
> @@ -692,7 +693,7 @@ spp_classifier_mac_iterate_table(
>   			port.if_no   = (classified_data + (long)data)->if_no_global;
>   
>   			(*params->element_proc)(
> -					params->opaque,
> +					params,
>   					SPP_CLASSIFIER_TYPE_MAC,
>   					mac_addr_str,
>   					&port);
> diff --git a/src/vf/classifier_mac.h b/src/vf/classifier_mac.h
> index b38ce70..b4e6715 100644
> --- a/src/vf/classifier_mac.h
> +++ b/src/vf/classifier_mac.h
> @@ -30,13 +30,13 @@ int spp_classifier_mac_update(struct spp_component_info *component_info);
>   int spp_classifier_mac_do(int id);
>   
>   /*
> - * classifier iterate component information
> + * classifier get component status
>    *
>    * @ret_val 0  succeeded.
>    * @ret_val -1 failed.
>    */
>   int
> -spp_classifier_component_info_iterate(unsigned int lcore_id, int id,
> +spp_classifier_get_component_status(unsigned int lcore_id, int id,
>   		struct spp_iterate_core_params *params);
>   
>   /**
> diff --git a/src/vf/command_proc.c b/src/vf/command_proc.c
> index ec2da51..214cb2e 100644
> --- a/src/vf/command_proc.c
> +++ b/src/vf/command_proc.c
> @@ -4,8 +4,6 @@
>   #include <rte_log.h>
>   #include <rte_branch_prediction.h>
>   
> -#include <jansson.h>
> -
>   #include "spp_vf.h"
>   #include "string_buffer.h"
>   #include "command_conn.h"
> @@ -15,7 +13,19 @@
>   #define RTE_LOGTYPE_SPP_COMMAND_PROC RTE_LOGTYPE_USER1
>   
>   /* request message initial size */
> +#define CMD_RES_ERR_MSG_SIZE  128
> +#define CMD_TAG_APPEND_SIZE   16
>   #define CMD_REQ_BUF_INIT_SIZE 2048
> +#define CMD_RES_BUF_INIT_SIZE 2048
> +
> +#define COMMAND_RESP_LIST_EMPTY { "", NULL }
> +
> +#define JSON_COMMA                ", "
> +#define JSON_APPEND_COMMA(flg)    ((flg)?JSON_COMMA:"")
> +#define JSON_APPEND_VALUE(format) "%s\"%s\": "format
> +#define JSON_APPEND_ARRAY         "%s\"%s\": [ %s ]"
> +#define JSON_APPEND_BLOCK         "%s\"%s\": { %s }"
> +#define JSON_APPEND_BLOCK_NONAME  "%s%s{ %s }"
>   
>   /* command execution result code */
>   enum command_result_code {
> @@ -27,8 +37,133 @@ enum command_result_code {
>   /* command execution result information */
>   struct command_result {
>   	int code;
> +	char result[SPP_CMD_NAME_BUFSZ];
> +	char error_message[CMD_RES_ERR_MSG_SIZE];
> +};
> +
> +/* command response list control structure */
> +struct command_response_list {
> +	char tag_name[SPP_CMD_NAME_BUFSZ];
> +	int (*func)(const char *name, char **output, void *tmp);
>   };
>   
> +/* append a comma for JSON format */
> +static int
> +append_json_comma(char **output)
> +{
> +	*output = spp_strbuf_append(*output, JSON_COMMA, strlen(JSON_COMMA));
> +	if (unlikely(*output == NULL)) {
> +		RTE_LOG(ERR, SPP_COMMAND_PROC, "JSON's comma failed to add.\n");
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +/* append data of unsigned integral type for JSON format */
> +static int
> +append_json_uint_value(const char *name, char **output, unsigned int value)
> +{
> +	int len = strlen(*output);
> +	/* extend the buffer */
> +	*output = spp_strbuf_append(*output, "",
> +			strlen(name) + CMD_TAG_APPEND_SIZE*2);
> +	if (unlikely(*output == NULL)) {
> +		RTE_LOG(ERR, SPP_COMMAND_PROC,
> +				"JSON's numeric format failed to add. (name = %s, uint = %u)\n",
> +				name, value);
> +		return -1;
> +	}
> +
> +	sprintf(&(*output)[len], JSON_APPEND_VALUE("%u"),
> +			JSON_APPEND_COMMA(len), name, value);
> +	return 0;
> +}
> +
> +/* append data of integral type for JSON format */
> +static int
> +append_json_int_value(const char *name, char **output, int value)
> +{
> +	int len = strlen(*output);
> +	/* extend the buffer */
> +	*output = spp_strbuf_append(*output, "",
> +			strlen(name) + CMD_TAG_APPEND_SIZE*2);
> +	if (unlikely(*output == NULL)) {
> +		RTE_LOG(ERR, SPP_COMMAND_PROC,
> +				"JSON's numeric format failed to add. (name = %s, int = %d)\n",
> +				name, value);
> +		return -1;
> +	}
> +
> +	sprintf(&(*output)[len], JSON_APPEND_VALUE("%d"),
> +			JSON_APPEND_COMMA(len), name, value);
> +	return 0;
> +}
> +
> +/* append data of string type for JSON format */
> +static int
> +append_json_str_value(const char *name, char **output, const char *str)
> +{
> +	int len = strlen(*output);
> +	/* extend the buffer */
> +	*output = spp_strbuf_append(*output, "",
> +			strlen(name) + strlen(str) + CMD_TAG_APPEND_SIZE);
> +	if (unlikely(*output == NULL)) {
> +		RTE_LOG(ERR, SPP_COMMAND_PROC,
> +				"JSON's string format failed to add. (name = %s, str = %s)\n",
> +				name, str);
> +		return -1;
> +	}
> +
> +	sprintf(&(*output)[len], JSON_APPEND_VALUE("\"%s\""),
> +			JSON_APPEND_COMMA(len), name, str);
> +	return 0;
> +}
> +
> +/* append brackets of the array for JSON format */
> +static int
> +append_json_array_brackets(const char *name, char **output, const char *str)
> +{
> +	int len = strlen(*output);
> +	/* extend the buffer */
> +	*output = spp_strbuf_append(*output, "",
> +			strlen(name) + strlen(str) + CMD_TAG_APPEND_SIZE);
> +	if (unlikely(*output == NULL)) {
> +		RTE_LOG(ERR, SPP_COMMAND_PROC,
> +				"JSON's square bracket failed to add. (name = %s, str = %s)\n",
> +				name, str);
> +		return -1;
> +	}
> +
> +	sprintf(&(*output)[len], JSON_APPEND_ARRAY,
> +			JSON_APPEND_COMMA(len), name, str);
> +	return 0;
> +}
> +
> +/* append brackets of the blocks for JSON format */
> +static int
> +append_json_block_brackets(const char *name, char **output, const char *str)
> +{
> +	int len = strlen(*output);
> +	/* extend the buffer */
> +	*output = spp_strbuf_append(*output, "",
> +			strlen(name) + strlen(str) + CMD_TAG_APPEND_SIZE);
> +	if (unlikely(*output == NULL)) {
> +		RTE_LOG(ERR, SPP_COMMAND_PROC,
> +				"JSON's curly bracket failed to add. (name = %s, str = %s)\n",
> +				name, str);
> +		return -1;
> +	}
> +
> +	if (name[0] == '\0')
> +		sprintf(&(*output)[len], JSON_APPEND_BLOCK_NONAME,
> +				JSON_APPEND_COMMA(len), name, str);
> +	else
> +		sprintf(&(*output)[len], JSON_APPEND_BLOCK,
> +				JSON_APPEND_COMMA(len), name, str);
> +	return 0;
> +}
> +
>   /* execute one command */
>   static int
>   execute_command(const struct spp_command *command)
> @@ -111,452 +246,539 @@ make_decode_error_message(const struct spp_command_decode_error *decode_error, c
>   	return message;
>   }
>   
> -/* create error result object form decode error information */
> -inline json_t *
> -create_result_object(const char* res_str)
> -{
> -	return json_pack("{ss}", "result", res_str);
> -}
> -
> -/* create error result object form decode error information */
> -inline json_t *
> -create_error_result_object(const char* err_msg)
> +/* set the command result */
> +static inline void
> +set_command_results(struct command_result *result,
> +		int code, const char *error_messege)
>   {
> -	return json_pack("{sss{ss}}", "result", "error", "error_details",
> -			"message", err_msg);
> +	result->code = code;
> +	switch (code) {
> +	case CRES_SUCCESS:
> +		strcpy(result->result, "success");
> +		memset(result->error_message, 0x00, CMD_RES_ERR_MSG_SIZE);
> +		break;
> +	case CRES_FAILURE:
> +		strcpy(result->result, "error");
> +		strcpy(result->error_message, error_messege);
> +		break;
> +	case CRES_INVALID: /* FALLTHROUGH */
> +	default:
> +		strcpy(result->result, "invalid");
> +		memset(result->error_message, 0x00, CMD_RES_ERR_MSG_SIZE);
> +		break;
> +	}
> +	return;
>   }
>   
> -/* append decode result array object to specified object */
> -static int
> -append_response_decode_results_object(json_t *parent_obj,
> +/* set decode error to command result */
> +static void
> +set_decode_error_to_results(struct command_result *results,
>   		const struct spp_command_request *request,
>   		const struct spp_command_decode_error *decode_error)
>   {
> -	int ret = -1;
>   	int i;
> -	json_t *results_obj;
> -	char err_msg[128];
> +	const char *tmp_buff;
> +	char error_messege[CMD_RES_ERR_MSG_SIZE];
>   
> -	results_obj = json_array();
> -	if (unlikely(results_obj == NULL))
> -		return -1;
> -
> -	if (unlikely(decode_error->code == SPP_CMD_DERR_BAD_FORMAT)) {
> -		/* create & append bad message format result */
> -		ret = json_array_append_new(results_obj,
> -				create_error_result_object(
> -				make_decode_error_message(decode_error, err_msg)));
> -		if (unlikely(ret != 0)) {
> -			json_decref(results_obj);
> -			return -1;
> -		}
> -	} else {
> -		/* create & append results */
> -		for (i = 0; i < request->num_command; ++i) {
> -			ret = json_array_append_new(results_obj, create_result_object("invalid"));
> -			if (unlikely(ret != 0)) {
> -				json_decref(results_obj);
> -				return -1;
> -			}
> -		}
> -
> -		/* create & rewrite error result */
> -		if (unlikely(request->num_command != request->num_valid_command)) {
> -			ret = json_array_set_new(results_obj,
> -					request->num_valid_command,
> -					create_error_result_object(
> -					make_decode_error_message(decode_error, err_msg)));
> -			if (unlikely(ret != 0)) {
> -				json_decref(results_obj);
> -				return -1;
> -			}
> -		}
> +	for (i = 0; i < request->num_command; i++) {
> +		if (decode_error->code == 0)
> +			set_command_results(&results[i], CRES_SUCCESS, "");
> +		else
> +			set_command_results(&results[i], CRES_INVALID, "");
>   	}
>   
> -	/* set results object in parent object */
> -	ret = json_object_set_new(parent_obj, "results", results_obj);
> -	if (unlikely(ret != 0))
> -		return -1;
> -
> -	return 0;
> +	if (decode_error->code != 0) {
> +		tmp_buff = make_decode_error_message(decode_error,
> +				error_messege);
> +		set_command_results(&results[request->num_valid_command],
> +				CRES_FAILURE, tmp_buff);
> +	}
>   }
>   
> -/* append command execution result array object to specified object */
> +/* append a command result for JSON format */
>   static int
> -append_response_command_results_object(json_t *parent_obj,
> -		const struct spp_command_request *request,
> -		const struct command_result *results)
> +append_result_value(const char *name, char **output, void *tmp)
>   {
> -	int ret = -1;
> -	int i;
> -	json_t *results_obj, *res_obj;
> -
> -	results_obj = json_array();
> -	if (unlikely(results_obj == NULL))
> -		return -1;
> -
> -	/* create & append results */
> -	for (i = 0; i < request->num_command; ++i) {
> -		switch (results[i].code) {
> -		case CRES_SUCCESS:
> -			res_obj = create_result_object("success");
> -			break;
> -		case CRES_FAILURE:
> -			res_obj = create_error_result_object("error occur");
> -			break;
> -		case CRES_INVALID: /* FALLTHROUGH */
> -		default:
> -			res_obj = create_result_object("invalid");
> -			break;
> -		}
> -
> -		ret = json_array_append_new(results_obj, res_obj);
> -		if (unlikely(ret != 0)) {
> -			json_decref(results_obj);
> -			return -1;
> -		}
> -	}
> -
> -	/* set results object in parent object */
> -	ret = json_object_set_new(parent_obj, "results", results_obj);
> -	if (unlikely(ret != 0))
> -		return -1;
> -
> -	return 0;
> +	const struct command_result *result = tmp;
> +	return append_json_str_value(name, output, result->result);
>   }
>   
> -/* append client id value to specified json object */
> +/* append error details for JSON format */
>   static int
> -append_response_client_id_value(json_t *parent_obj)
> +append_error_details_value(const char *name, char **output, void *tmp)
>   {
>   	int ret = -1;
> -	json_t *proc_obj;
> +	const struct command_result *result = tmp;
> +	char *tmp_buff;
> +	/* string is empty, except for errors */
> +	if (result->error_message[0] == '\0')
> +		return 0;
>   
> -	proc_obj = json_integer(spp_get_client_id());
> -	if (unlikely(proc_obj == NULL))
> +	tmp_buff = spp_strbuf_allocate(CMD_RES_BUF_INIT_SIZE);
> +	if (unlikely(tmp_buff == NULL)) {
> +		RTE_LOG(ERR, SPP_COMMAND_PROC,
> +				"allocate error. (name = %s)\n",
> +				name);
>   		return -1;
> +	}
>   
> -	ret = json_object_set_new(parent_obj, "client_id", proc_obj);
> -	if (unlikely(ret != 0))
> +	ret = append_json_str_value("message", &tmp_buff,
> +			result->error_message);
> +	if (unlikely(ret < 0)) {
> +		spp_strbuf_free(tmp_buff);
>   		return -1;
> +	}
>   
> -	return 0;
> +	ret = append_json_block_brackets(name, output, tmp_buff);
> +	spp_strbuf_free(tmp_buff);
> +	return ret;
>   }
>   
> -/* append client-id value */
> +/* append a client id for JSON format */
>   static int
> -append_client_id_value(json_t *parent_obj)
> +append_client_id_value(const char *name, char **output,
> +		void *tmp __attribute__ ((unused)))
>   {
> -	int ret = -1;
> -	ret = json_object_set_new(parent_obj, "client-id",
> -			json_integer(spp_get_client_id()));
> -	if (unlikely(ret != 0))
> -		return -1;
> -
> -	return 0;
> +	return append_json_int_value(name, output, spp_get_client_id());
>   }
>   
> -/* append interface array */
> +/* append a list of interface numbers */
>   static int
> -append_interface_array(json_t *parent_obj, const char *name,
> -		const enum port_type type)
> +append_interface_array(char **output, const enum port_type type)
>   {
> -	int ret = -1;
> -	int i = 0;
> -	json_t *array_obj;
> -	array_obj = json_array();
> -	if (unlikely(array_obj == NULL))
> -		return -1;
> +	int i, port_cnt = 0;
> +	char tmp_str[CMD_TAG_APPEND_SIZE];
>   
>   	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
>   		if (!spp_check_flush_port(type, i))
>   			continue;
>   
> -		ret = json_array_append_new(array_obj, json_integer(i));
> -		if (unlikely(ret != 0)) {
> -			json_decref(array_obj);
> +		sprintf(tmp_str, "%s%d", JSON_APPEND_COMMA(i), i);
> +
> +		*output = spp_strbuf_append(*output, tmp_str, strlen(tmp_str));
> +		if (unlikely(*output == NULL)) {
> +			RTE_LOG(ERR, SPP_COMMAND_PROC,
> +					"Interface number failed to add. (type = %d)\n",
> +					type);
>   			return -1;
>   		}
> -	}
>   
> -	ret = json_object_set_new(parent_obj, name, array_obj);
> -	if (unlikely(ret != 0)) {
> -		json_decref(array_obj);
> -		return -1;
> +		port_cnt++;
>   	}
>   
>   	return 0;
>   }
>   
> -/* append interface value */
> +/* append a list of interface numbers for JSON format */
>   static int
> -append_interface_value(json_t *parent_obj)
> +append_interface_value(const char *name, char **output,
> +		void *tmp __attribute__ ((unused)))
>   {
>   	int ret = -1;
> -	ret = append_interface_array(parent_obj, "phy", PHY);
> -	if (unlikely(ret != 0))
> +	char *tmp_buff = spp_strbuf_allocate(CMD_RES_BUF_INIT_SIZE);
> +	if (unlikely(tmp_buff == NULL)) {
> +		RTE_LOG(ERR, SPP_COMMAND_PROC,
> +				"allocate error. (name = %s)\n",
> +				name);
>   		return -1;
> +	}
>   
> -	ret = append_interface_array(parent_obj, "vhost", VHOST);
> -	if (unlikely(ret != 0))
> -		return -1;
> +	if (strcmp(name, SPP_IFTYPE_NIC_STR) == 0)
> +		ret = append_interface_array(&tmp_buff, PHY);
>   
> -	ret = append_interface_array(parent_obj, "ring", RING);
> -	if (unlikely(ret != 0))
> +	else if (strcmp(name, SPP_IFTYPE_VHOST_STR) == 0)
> +		ret = append_interface_array(&tmp_buff, VHOST);
> +
> +	else if (strcmp(name, SPP_IFTYPE_RING_STR) == 0)
> +		ret = append_interface_array(&tmp_buff, RING);
> +
> +	if (unlikely(ret < 0)) {
> +		spp_strbuf_free(tmp_buff);
>   		return -1;
> +	}
>   
> -	return 0;
> +	ret = append_json_array_brackets(name, output, tmp_buff);
> +	spp_strbuf_free(tmp_buff);
> +	return ret;
>   }
>   
> -/* append port array */
> +/* append a list of port numbers for JSON format */
>   static int
> -apeend_port_array(json_t *parent_obj, const char *name,
> +apeend_port_array(const char *name, char **output,
>   		const int num, const struct spp_port_index *ports)
>   {
>   	int ret = -1;
>   	int i = 0;
> -	char port_str[64];
> -	json_t *array_obj;
> -	array_obj = json_array();
> -	if (unlikely(array_obj == NULL))
> +	char port_str[CMD_TAG_APPEND_SIZE];
> +	char append_str[CMD_TAG_APPEND_SIZE];
> +	char *tmp_buff = spp_strbuf_allocate(CMD_RES_BUF_INIT_SIZE);
> +	if (unlikely(tmp_buff == NULL)) {
> +		RTE_LOG(ERR, SPP_COMMAND_PROC,
> +				"allocate error. (name = %s)\n",
> +				name);
>   		return -1;
> +	}
>   
>   	for (i = 0; i < num; i++) {
>   		spp_format_port_string(port_str, ports[i].if_type,
>   				ports[i].if_no);
> -		ret = json_array_append_new(array_obj, json_string(port_str));
> -		if (unlikely(ret != 0)) {
> -			json_decref(array_obj);
> -			return -1;
> -		}
> -	}
>   
> -	ret = json_object_set_new(parent_obj, name, array_obj);
> -	if (unlikely(ret != 0)) {
> -		json_decref(array_obj);
> -		return -1;
> +		sprintf(append_str, "%s\"%s\"", JSON_APPEND_COMMA(i), port_str);
> +
> +		tmp_buff = spp_strbuf_append(tmp_buff, append_str,
> +				strlen(append_str));
> +		if (unlikely(tmp_buff == NULL))
> +			return -1;
>   	}
>   
> -	return 0;
> +	ret = append_json_array_brackets(name, output, tmp_buff);
> +	spp_strbuf_free(tmp_buff);
> +	return ret;
>   }
>   
> -/* append core element value */
> +/* append one element of core information for JSON format */
>   static int
>   append_core_element_value(
> -		void *opaque, const unsigned int lcore_id,
> +		struct spp_iterate_core_params *params,
> +		const unsigned int lcore_id,
>   		const char *name, const char *type,
>   		const int num_rx, const struct spp_port_index *rx_ports,
>   		const int num_tx, const struct spp_port_index *tx_ports)
>   {
>   	int ret = -1;
>   	int unuse_flg = 0;
> -	json_t *parent_obj = (json_t *)opaque;
> -	json_t *tab_obj;
> -
> -	tab_obj = json_object();
> -	if (unlikely(tab_obj == NULL))
> -		return -1;
> +	char *buff, *tmp_buff;
> +	buff = params->output;
> +	tmp_buff = spp_strbuf_allocate(CMD_RES_BUF_INIT_SIZE);
> +	if (unlikely(tmp_buff == NULL)) {
> +		RTE_LOG(ERR, SPP_COMMAND_PROC,
> +				"allocate error. (name = %s)\n",
> +				name);
> +		return ret;
> +	}
>   
> +	/* there is unnecessary data when "unuse" by type */
>   	unuse_flg = strcmp(type, SPP_TYPE_UNUSE_STR);
>   
> -	ret = json_object_set_new(tab_obj, "core", json_integer(lcore_id));
> -	if (unlikely(ret != 0)) {
> -		json_decref(tab_obj);
> -		return -1;
> -	}
> +	ret = append_json_uint_value("core", &tmp_buff, lcore_id);
> +	if (unlikely(ret < 0))
> +		return ret;
>   
>   	if (unuse_flg) {
> -		ret = json_object_set_new(tab_obj, "name", json_string(name));
> -		if (unlikely(ret != 0)) {
> -			json_decref(tab_obj);
> -			return -1;
> -		}
> +		ret = append_json_str_value("name", &tmp_buff, name);
> +		if (unlikely(ret < 0))
> +			return ret;
>   	}
>   
> -	ret = json_object_set_new(tab_obj, "type", json_string(type));
> -	if (unlikely(ret != 0)) {
> -		json_decref(tab_obj);
> -		return -1;
> -	}
> +	ret = append_json_str_value("type", &tmp_buff, type);
> +	if (unlikely(ret < 0))
> +		return ret;
>   
>   	if (unuse_flg) {
> -		ret = apeend_port_array(tab_obj, "rx_port", num_rx, rx_ports);
> -		if (unlikely(ret != 0)) {
> -			json_decref(tab_obj);
> -			return -1;
> -		}
> -
> -		ret = apeend_port_array(tab_obj, "tx_port", num_tx, tx_ports);
> -		if (unlikely(ret != 0)) {
> -			json_decref(tab_obj);
> -			return -1;
> -		}
> -	}
> +		ret = apeend_port_array("rx_port", &tmp_buff,
> +				num_rx, rx_ports);
> +		if (unlikely(ret < 0))
> +			return ret;
>   
> -	ret = json_array_append_new(parent_obj, tab_obj);
> -	if (unlikely(ret != 0)) {
> -		json_decref(tab_obj);
> -		return -1;
> +		ret = apeend_port_array("tx_port", &tmp_buff,
> +				num_tx, tx_ports);
> +		if (unlikely(ret < 0))
> +			return ret;
>   	}
>   
> -	return 0;
> +	ret = append_json_block_brackets("", &buff, tmp_buff);
> +	spp_strbuf_free(tmp_buff);
> +	params->output = buff;
> +	return ret;
>   }
>   
> -/* append core value */
> +/* append a list of core information for JSON format */
>   static int
> -append_response_core_value(json_t *parent_obj)
> +append_core_value(const char *name, char **output,
> +		void *tmp __attribute__ ((unused)))
>   {
>   	int ret = -1;
> -	json_t *tab_obj;
>   	struct spp_iterate_core_params itr_params;
> -
> -	tab_obj = json_array();
> -	if (unlikely(tab_obj == NULL))
> +	char *tmp_buff = spp_strbuf_allocate(CMD_RES_BUF_INIT_SIZE);
> +	if (unlikely(tmp_buff == NULL)) {
> +		RTE_LOG(ERR, SPP_COMMAND_PROC,
> +				"allocate error. (name = %s)\n",
> +				name);
>   		return -1;
> +	}
>   
> -	itr_params.opaque = tab_obj;
> +	itr_params.output = tmp_buff;
>   	itr_params.element_proc = append_core_element_value;
>   
>   	ret = spp_iterate_core_info(&itr_params);
>   	if (unlikely(ret != 0)) {
> -		json_decref(tab_obj);
> -		return -1;
> -	}
> -
> -	ret = json_object_set_new(parent_obj, "core", tab_obj);
> -	if (unlikely(ret != 0)) {
> -		json_decref(tab_obj);
> +		spp_strbuf_free(itr_params.output);
>   		return -1;
>   	}
>   
> -	return 0;
> +	ret = append_json_array_brackets(name, output, itr_params.output);
> +	spp_strbuf_free(itr_params.output);
> +	return ret;
>   }
>   
> -/* append classifier element value */
> +/* append one element of classifier table for JSON format */
>   static int
>   append_classifier_element_value(
> -		void *opaque,
> +		struct spp_iterate_classifier_table_params *params,
>   		__rte_unused enum spp_classifier_type type,
>   		const char *data,
>   		const struct spp_port_index *port)
>   {
> -	json_t *parent_obj = (json_t *)opaque;
> +	int ret = -1;
> +	char *buff, *tmp_buff;
> +	char port_str[CMD_TAG_APPEND_SIZE];
> +	buff = params->output;
> +	tmp_buff = spp_strbuf_allocate(CMD_RES_BUF_INIT_SIZE);
> +	if (unlikely(tmp_buff == NULL)) {
> +		RTE_LOG(ERR, SPP_COMMAND_PROC,
> +				"allocate error. (name = classifier_table)\n");
> +		return ret;
> +	}
>   
> -	char port_str[64];
>   	spp_format_port_string(port_str, port->if_type, port->if_no);
>   
> -	json_array_append_new(parent_obj, json_pack(
> -			"{ssssss}",
> -			"type", "mac",
> -			"value", data,
> -			"port", port_str));
> +	ret = append_json_str_value("type", &tmp_buff, "mac");
> +	if (unlikely(ret < 0))
> +		return ret;
>   
> -	return 0;
> +	ret = append_json_str_value("value", &tmp_buff, data);
> +	if (unlikely(ret < 0))
> +		return ret;
> +
> +	ret = append_json_str_value("port", &tmp_buff, port_str);
> +	if (unlikely(ret < 0))
> +		return ret;
> +
> +	ret = append_json_block_brackets("", &buff, tmp_buff);
> +	spp_strbuf_free(tmp_buff);
> +	params->output = buff;
> +	return ret;
>   }
>   
> -/* append classifier_table value */
> -static int
> -append_response_classifier_value(json_t *parent_obj)
> +/* append a list of classifier table for JSON format */
> +static int
> +append_classifier_table_value(const char *name, char **output,
> +		void *tmp __attribute__ ((unused)))
>   {
>   	int ret = -1;
> -	json_t *tab_obj;
>   	struct spp_iterate_classifier_table_params itr_params;
> -
> -	/* create classifier_table array */
> -	tab_obj = json_array();
> -	if (unlikely(tab_obj == NULL))
> +	char *tmp_buff = spp_strbuf_allocate(CMD_RES_BUF_INIT_SIZE);
> +	if (unlikely(tmp_buff == NULL)) {
> +		RTE_LOG(ERR, SPP_COMMAND_PROC,
> +				"allocate error. (name = %s)\n",
> +				name);
>   		return -1;
> +	}
>   
> -	itr_params.opaque = tab_obj;
> +	itr_params.output = tmp_buff;
>   	itr_params.element_proc = append_classifier_element_value;
>   
>   	ret = spp_iterate_classifier_table(&itr_params);
>   	if (unlikely(ret != 0)) {
> -		json_decref(tab_obj);
> +		spp_strbuf_free(itr_params.output);
>   		return -1;
>   	}
>   
> -	ret = json_object_set_new(parent_obj, "classifier_table", tab_obj);
> -	if (unlikely(ret != 0)) {
> -		json_decref(tab_obj);
> +	ret = append_json_array_brackets(name, output, itr_params.output);
> +	spp_strbuf_free(itr_params.output);
> +	return ret;
> +}
> +
> +/* append string of command response list for JSON format */
> +static int
> +append_response_list_value(char **output,
> +		struct command_response_list *list,
> +		void *tmp)
> +{
> +	int ret = -1;
> +	int i;
> +	char *tmp_buff;
> +	tmp_buff = spp_strbuf_allocate(CMD_RES_BUF_INIT_SIZE);
> +	if (unlikely(tmp_buff == NULL)) {
> +		RTE_LOG(ERR, SPP_COMMAND_PROC,
> +				"allocate error. (name = response_list)\n");
>   		return -1;
>   	}
>   
> +	for (i = 0; list[i].tag_name[0] != '\0'; i++) {
> +		tmp_buff[0] = '\0';
> +		ret = list[i].func(list[i].tag_name, &tmp_buff, tmp);
> +		if (unlikely(ret < 0)) {
> +			spp_strbuf_free(tmp_buff);
> +			RTE_LOG(ERR, SPP_COMMAND_PROC,
> +					"Failed to get reply string. (tag = %s)\n",
> +					list[i].tag_name);
> +			return -1;
> +		}
> +
> +		if (tmp_buff[0] == '\0')
> +			continue;
> +
> +		if ((*output)[0] != '\0') {
> +			ret = append_json_comma(output);
> +			if (unlikely(ret < 0)) {
> +				spp_strbuf_free(tmp_buff);
> +				RTE_LOG(ERR, SPP_COMMAND_PROC,
> +						"Failed to add commas. (tag = %s)\n",
> +						list[i].tag_name);
> +				return -1;
> +			}
> +		}
> +
> +		*output = spp_strbuf_append(*output, tmp_buff,
> +				strlen(tmp_buff));
> +		if (unlikely(*output == NULL)) {
> +			spp_strbuf_free(tmp_buff);
> +			RTE_LOG(ERR, SPP_COMMAND_PROC,
> +					"Failed to add reply string. (tag = %s)\n",
> +					list[i].tag_name);
> +			return -1;
> +		}
> +	}
> +
> +	spp_strbuf_free(tmp_buff);
>   	return 0;
>   }
>   
> -/* append info value(status response) to specified json object */
> -static int
> -append_response_info_value(json_t *parent_obj)
> -{
> -	int ret = -1;
> -	json_t *info_obj;
> +/* termination constant of command response list */
> +#define COMMAND_RESP_TAG_LIST_EMPTY { "", NULL }
>   
> -	/* set classifier_table object in info object */
> -	info_obj = json_object();
> -	if (unlikely(info_obj == NULL))
> -		return -1;
> +/* command response result string list */
> +struct command_response_list response_result_list[] = {
> +	{ "result",        append_result_value },
> +	{ "error_details", append_error_details_value },
> +	COMMAND_RESP_TAG_LIST_EMPTY
> +};
>   
> -	ret = append_client_id_value(info_obj);
> -	if (unlikely(ret != 0)) {
> -		json_decref(info_obj);
> +/* command response status information string list */
> +struct command_response_list response_info_list[] = {
> +	{ "client-id",        append_client_id_value },
> +	{ "phy",              append_interface_value },
> +	{ "vhost",            append_interface_value },
> +	{ "ring",             append_interface_value },
> +	{ "core",             append_core_value },
> +	{ "classifier_table", append_classifier_table_value },
> +	COMMAND_RESP_TAG_LIST_EMPTY
> +};
> +
> +/* append a list of command results for JSON format. */
> +static int
> +append_command_results_value(const char *name, char **output,
> +		int num, struct command_result *results)
> +{
> +	int ret = -1;
> +	int i;
> +	char *tmp_buff1, *tmp_buff2;
> +	tmp_buff1 = spp_strbuf_allocate(CMD_RES_BUF_INIT_SIZE);
> +	if (unlikely(tmp_buff1 == NULL)) {
> +		RTE_LOG(ERR, SPP_COMMAND_PROC,
> +				"allocate error. (name = %s, buff=1)\n",
> +				name);
>   		return -1;
>   	}
>   
> -	ret = append_interface_value(info_obj);
> -	if (unlikely(ret != 0)) {
> -		json_decref(info_obj);
> +	tmp_buff2 = spp_strbuf_allocate(CMD_RES_BUF_INIT_SIZE);
> +	if (unlikely(tmp_buff2 == NULL)) {
> +		spp_strbuf_free(tmp_buff1);
> +		RTE_LOG(ERR, SPP_COMMAND_PROC,
> +				"allocate error. (name = %s, buff=2)\n",
> +				name);
>   		return -1;
>   	}
>   
> -	ret = append_response_core_value(info_obj);
> -	if (unlikely(ret != 0)) {
> -		json_decref(info_obj);
> -		return -1;
> +	for (i = 0; i < num; i++) {
> +		tmp_buff1[0] = '\0';
> +		ret = append_response_list_value(&tmp_buff1,
> +				response_result_list, &results[i]);
> +		if (unlikely(ret < 0)) {
> +			spp_strbuf_free(tmp_buff1);
> +			spp_strbuf_free(tmp_buff2);
> +			return -1;
> +		}
> +
> +		ret = append_json_block_brackets("", &tmp_buff2, tmp_buff1);
> +		if (unlikely(ret < 0)) {
> +			spp_strbuf_free(tmp_buff1);
> +			spp_strbuf_free(tmp_buff2);
> +			return -1;
> +		}
> +
>   	}
>   
> -	ret = append_response_classifier_value(info_obj);
> -	if (unlikely(ret != 0)) {
> -		json_decref(info_obj);
> +	ret = append_json_array_brackets(name, output, tmp_buff2);
> +	spp_strbuf_free(tmp_buff1);
> +	spp_strbuf_free(tmp_buff2);
> +	return ret;
> +}
> +
> +/* append a list of status information for JSON format. */
> +static int
> +append_info_value(const char *name, char **output)
> +{
> +	int ret = -1;
> +	char *tmp_buff = spp_strbuf_allocate(CMD_RES_BUF_INIT_SIZE);
> +	if (unlikely(tmp_buff == NULL)) {
> +		RTE_LOG(ERR, SPP_COMMAND_PROC,
> +				"allocate error. (name = %s)\n",
> +				name);
>   		return -1;
>   	}
>   
> -	/* set info object in parent object */
> -	ret = json_object_set_new(parent_obj, "info", info_obj);
> -	if (unlikely(ret != 0)) {
> -		json_decref(info_obj);
> +	ret = append_response_list_value(&tmp_buff,
> +			response_info_list, NULL);
> +	if (unlikely(ret < 0)) {
> +		spp_strbuf_free(tmp_buff);
>   		return -1;
>   	}
>   
> -	return 0;
> +	ret = append_json_block_brackets(name, output, tmp_buff);
> +	spp_strbuf_free(tmp_buff);
> +	return ret;
>   }
>   
>   /* send response for decode error */
>   static void
>   send_decode_error_response(int *sock, const struct spp_command_request *request,
> -		const struct spp_command_decode_error *decode_error)
> +		struct command_result *command_results)
>   {
>   	int ret = -1;
> -	char *msg;
> -	json_t *top_obj;
> -
> -	top_obj = json_object();
> -	if (unlikely(top_obj == NULL)) {
> -		RTE_LOG(ERR, SPP_COMMAND_PROC, "Failed to make decode error response.");
> +	char *msg, *tmp_buff;
> +	tmp_buff = spp_strbuf_allocate(CMD_RES_BUF_INIT_SIZE);
> +	if (unlikely(tmp_buff == NULL)) {
> +		RTE_LOG(ERR, SPP_COMMAND_PROC,
> +				"allocate error. (name = decode_error_response)\n");
>   		return;
>   	}
>   
>   	/* create & append result array */
> -	ret = append_response_decode_results_object(top_obj, request, decode_error);
> -	if (unlikely(ret != 0)) {
> -		RTE_LOG(ERR, SPP_COMMAND_PROC, "Failed to make decode error response.");
> -		json_decref(top_obj);
> +	ret = append_command_results_value("results", &tmp_buff,
> +			request->num_command, command_results);
> +	if (unlikely(ret < 0)) {
> +		spp_strbuf_free(tmp_buff);
> +		RTE_LOG(ERR, SPP_COMMAND_PROC, "Failed to make command result response.\n");
>   		return;
>   	}
>   
> -	/* serialize */
> -	msg = json_dumps(top_obj, JSON_INDENT(2) | JSON_PRESERVE_ORDER);
> -	json_decref(top_obj);
> +	msg = spp_strbuf_allocate(CMD_RES_BUF_INIT_SIZE);
> +	if (unlikely(msg == NULL)) {
> +		spp_strbuf_free(tmp_buff);
> +		RTE_LOG(ERR, SPP_COMMAND_PROC,
> +				"allocate error. (name = decode_error_response)\n");
> +		return;
> +	}
> +	ret = append_json_block_brackets("", &msg, tmp_buff);
> +	spp_strbuf_free(tmp_buff);
> +	if (unlikely(ret < 0)) {
> +		spp_strbuf_free(msg);
> +		RTE_LOG(ERR, SPP_COMMAND_PROC,
> +				"allocate error. (name = result_response)\n");
> +		return;
> +	}
>   
>   	RTE_LOG(DEBUG, SPP_COMMAND_PROC, "Make command response (decode error). "
>   			"response_str=\n%s\n", msg);
> @@ -564,59 +786,72 @@ send_decode_error_response(int *sock, const struct spp_command_request *request,
>   	/* send response to requester */
>   	ret = spp_send_message(sock, msg, strlen(msg));
>   	if (unlikely(ret != 0)) {
> -		RTE_LOG(ERR, SPP_COMMAND_PROC, "Failed to send decode error response.");
> +		RTE_LOG(ERR, SPP_COMMAND_PROC, "Failed to send decode error response.\n");
>   		/* not return */
>   	}
>   
> -	free(msg);
> +	spp_strbuf_free(msg);
> +	return;
>   }
>   
>   /* send response for command execution result */
>   static void
>   send_command_result_response(int *sock, const struct spp_command_request *request,
> -		const struct command_result *command_results)
> +		struct command_result *command_results)
>   {
>   	int ret = -1;
> -	char *msg;
> -	json_t *top_obj;
> -
> -	top_obj = json_object();
> -	if (unlikely(top_obj == NULL)) {
> -		RTE_LOG(ERR, SPP_COMMAND_PROC, "Failed to make command result response.");
> +	char *msg, *tmp_buff;
> +	tmp_buff = spp_strbuf_allocate(CMD_RES_BUF_INIT_SIZE);
> +	if (unlikely(tmp_buff == NULL)) {
> +		RTE_LOG(ERR, SPP_COMMAND_PROC,
> +				"allocate error. (name = result_response)\n");
>   		return;
>   	}
>   
>   	/* create & append result array */
> -	ret = append_response_command_results_object(top_obj, request, command_results);
> -	if (unlikely(ret != 0)) {
> -		RTE_LOG(ERR, SPP_COMMAND_PROC, "Failed to make command result response.");
> -		json_decref(top_obj);
> +	ret = append_command_results_value("results", &tmp_buff,
> +			request->num_command, command_results);
> +	if (unlikely(ret < 0)) {
> +		spp_strbuf_free(tmp_buff);
> +		RTE_LOG(ERR, SPP_COMMAND_PROC, "Failed to make command result response.\n");
>   		return;
>   	}
>   
>   	/* append client id information value */
>   	if (request->is_requested_client_id) {
> -		ret = append_response_client_id_value(top_obj);
> -		if (unlikely(ret != 0)) {
> -			RTE_LOG(ERR, SPP_COMMAND_PROC, "Failed to make command result response.");
> -			json_decref(top_obj);
> +		ret = append_client_id_value("client_id", &tmp_buff, NULL);
> +		if (unlikely(ret < 0)) {
> +			spp_strbuf_free(tmp_buff);
> +			RTE_LOG(ERR, SPP_COMMAND_PROC, "Failed to make client id response.\n");
>   			return;
>   		}
>   	}
>   
>   	/* append info value */
>   	if (request->is_requested_status) {
> -		ret = append_response_info_value(top_obj);
> -		if (unlikely(ret != 0)) {
> -			RTE_LOG(ERR, SPP_COMMAND_PROC, "Failed to make command result response.");
> -			json_decref(top_obj);
> +		ret = append_info_value("info", &tmp_buff);
> +		if (unlikely(ret < 0)) {
> +			spp_strbuf_free(tmp_buff);
> +			RTE_LOG(ERR, SPP_COMMAND_PROC, "Failed to make status response.\n");
>   			return;
>   		}
>   	}
>   
> -	/* serialize */
> -	msg = json_dumps(top_obj, JSON_INDENT(2) | JSON_PRESERVE_ORDER);
> -	json_decref(top_obj);
> +	msg = spp_strbuf_allocate(CMD_RES_BUF_INIT_SIZE);
> +	if (unlikely(msg == NULL)) {
> +		spp_strbuf_free(tmp_buff);
> +		RTE_LOG(ERR, SPP_COMMAND_PROC,
> +				"allocate error. (name = result_response)\n");
> +		return;
> +	}
> +	ret = append_json_block_brackets("", &msg, tmp_buff);
> +	spp_strbuf_free(tmp_buff);
> +	if (unlikely(ret < 0)) {
> +		spp_strbuf_free(msg);
> +		RTE_LOG(ERR, SPP_COMMAND_PROC,
> +				"allocate error. (name = result_response)\n");
> +		return;
> +	}
>   
>   	RTE_LOG(DEBUG, SPP_COMMAND_PROC, "Make command response (command result). "
>   			"response_str=\n%s\n", msg);
> @@ -624,11 +859,12 @@ send_command_result_response(int *sock, const struct spp_command_request *reques
>   	/* send response to requester */
>   	ret = spp_send_message(sock, msg, strlen(msg));
>   	if (unlikely(ret != 0)) {
> -		RTE_LOG(ERR, SPP_COMMAND_PROC, "Failed to send command result response.");
> +		RTE_LOG(ERR, SPP_COMMAND_PROC, "Failed to send command result response.\n");
>   		/* not return */
>   	}
>   
> -	free(msg);
> +	spp_strbuf_free(msg);
> +	return;
>   }
>   
>   /* process command request from no-null-terminated string */
> @@ -654,7 +890,9 @@ process_request(int *sock, const char *request_str, size_t request_str_len)
>   			&request, request_str, request_str_len, &decode_error);
>   	if (unlikely(ret != 0)) {
>   		/* send error response */
> -		send_decode_error_response(sock, &request, &decode_error);
> +		set_decode_error_to_results(command_results, &request,
> +				&decode_error);
> +		send_decode_error_response(sock, &request, command_results);
>   		RTE_LOG(DEBUG, SPP_COMMAND_PROC, "End command request processing.\n");
>   		return 0;
>   	}
> @@ -667,21 +905,24 @@ process_request(int *sock, const char *request_str, size_t request_str_len)
>   	for (i = 0; i < request.num_command ; ++i) {
>   		ret = execute_command(request.commands + i);
>   		if (unlikely(ret != 0)) {
> -			command_results[i].code = CRES_FAILURE;
> +			set_command_results(&command_results[i], CRES_FAILURE,
> +					"error occur");
>   
>   			/* not execute remaining commands */
>   			for (++i; i < request.num_command ; ++i)
> -				command_results[i].code = CRES_INVALID;
> +				set_command_results(&command_results[i],
> +					CRES_INVALID, "");
> +
>   			break;
>   		}
>   
> -		command_results[i].code = CRES_SUCCESS;
> +		set_command_results(&command_results[i], CRES_SUCCESS, "");
>   	}
>   
>   	if (request.is_requested_exit) {
>   		/* Terminated by process exit command.                       */
>   		/* Other route is normal end because it responds to command. */
> -		RTE_LOG(INFO, SPP_COMMAND_PROC, "No response with process exit command.");
> +		RTE_LOG(INFO, SPP_COMMAND_PROC, "No response with process exit command.\n");
>   		return -1;
>   	}
>   
> diff --git a/src/vf/spp_config.c b/src/vf/spp_config.c
> deleted file mode 100644
> index 9170281..0000000
> --- a/src/vf/spp_config.c
> +++ /dev/null
> @@ -1,785 +0,0 @@
> -#include <sys/types.h>
> -#include <jansson.h>
> -
> -#include <rte_log.h>
> -
> -#include "spp_config.h"
> -
> -#define CONFIG_CORE_TYPE_CLASSIFIER_MAC "classifier_mac"
> -#define CONFIG_CORE_TYPE_MERGE          "merge"
> -#define CONFIG_CORE_TYPE_FORWARD        "forward"
> -
> -#define JSONPATH_CLASSIFIER_TABLE "$.classifier_table"
> -#define JSONPATH_PROC_TABLE "$.vfs"
> -#define JSONPATH_NAME       "$.name"
> -#define JSONPATH_TABLE      "$.table"
> -#define JSONPATH_MAC        "$.mac"
> -#define JSONPATH_PORT       "$.port"
> -#define JSONPATH_NUM_VHOST  "$.num_vhost"
> -#define JSONPATH_NUM_RING   "$.num_ring"
> -#define JSONPATH_FUNCTIONS  "$.functions"
> -#define JSONPATH_CORE_NO    "$.core"
> -#define JSONPATH_CORE_TYPE  "$.type"
> -#define JSONPATH_RX_PORT    "$.rx_port"
> -#define JSONPATH_TX_PORT    "$.tx_port"
> -#define JSONPATH_TX_TABLE   "$.tx_port_table"
> -
> -/**
> - * Instead of json_path_get
> - *
> - * TODO(yasufum) confirm, add instead of what
> - * TODO(yasufum) confirm, add reason why this function is needed
> - * TODO(yasufum) confirm, add roles of obj, new_obj to make it more understandable
> - */
> -json_t *
> -spp_config_get_path_obj(const json_t *json, const char *path)
> -{
> -	const json_t *obj, *array_obj;
> -	json_t *new_obj = NULL;
> -	char buf[SPP_CONFIG_PATH_LEN];
> -	char *str, *token, *bracket, *endptr;
> -	int index = 0;
> -
> -	if (unlikely(path[0] != '$') || unlikely(path[1] != '.') ||
> -			unlikely(strlen(path) >= SPP_CONFIG_PATH_LEN))
> -		return NULL;
> -
> -	strcpy(buf, path);
> -	obj = json;
> -	str = buf+1;
> -	while(str != NULL) {
> -		token = str+1;
> -		str = strpbrk(token, ".");
> -		if (str != NULL)
> -			*str = '\0';
> -
> -		bracket = strpbrk(token, "[");
> -		if (bracket != NULL)
> -			*bracket = '\0';
> -
> -		new_obj = json_object_get(obj, token);
> -		if (new_obj == NULL)
> -			return NULL;
> -
> -		if (bracket != NULL) {
> -			index = strtol(bracket+1, &endptr, 0);
> -			if (unlikely(bracket+1 == endptr) || unlikely(*endptr != ']'))
> -				return NULL;
> -
> -			array_obj = new_obj;
> -			new_obj = json_array_get(array_obj, index);
> -			if (new_obj == NULL)
> -				return NULL;
> -		}
> -
> -		obj = new_obj;
> -	}
> -
> -	return new_obj;
> -}
> -
> -/**
> - * Get integer data from config
> - *
> - * If target is found, the result is assigned to argument 'value' and
> - * it reutrns 0, or returns -1 if not found.
> - */
> -static int
> -config_get_int_value(const json_t *obj, const char *path, int *value)
> -{
> -	/* Use tmp to get target value of integer */
> -	json_t *tmp_obj = spp_config_get_path_obj(obj, path);
> -	if (unlikely(tmp_obj == NULL)) {
> -		/* For debugging, logging a case of null */
> -		RTE_LOG(DEBUG, APP, "No parameter. (path = %s)\n", path);
> -		return -1;
> -	}
> -
> -	if (unlikely(!json_is_integer(tmp_obj))) {
> -		/* For debugging, logging for other than target type */
> -		RTE_LOG(DEBUG, APP, "Not an integer. (path = %s)\n", path);
> -		return -1;
> -	}
> -
> -	*value = json_integer_value(tmp_obj);
> -	RTE_LOG(DEBUG, APP, "get value = %d\n", *value);
> -	return 0;
> -}
> -
> -/*
> - * Get string data from config
> - *
> - * If target is found, the result is assigned to argument 'value' and
> - * it reutrns 0, or returns -1 if not found.
> - */
> -static int
> -config_get_str_value(const json_t *obj, const char *path, char *value)
> -{
> -	json_t *tmp_obj = spp_config_get_path_obj(obj, path);
> -	if (unlikely(tmp_obj == NULL)) {
> -		RTE_LOG(DEBUG, APP, "No parameter. (path = %s)\n", path);
> -		return -1;
> -	}
> -
> -	if (unlikely(!json_is_string(tmp_obj))) {
> -		/* For debugging, logging for other than target type */
> -		RTE_LOG(DEBUG, APP, "Not a string. (path = %s)\n", path);
> -		return -1;
> -	}
> -
> -	strcpy(value, json_string_value(tmp_obj));
> -	RTE_LOG(DEBUG, APP, "get value = %s\n", value);
> -	return 0;
> -}
> -
> -/* TODO(yasufum) change function name to be realized doing init, for instance, init_config_area()  */
> -static void
> -config_init_data(struct spp_config_area *config)
> -{
> -	/* Clear config area with zero */
> -	memset(config, 0x00, sizeof(struct spp_config_area));
> -	int core_cnt, port_cnt, table_cnt;
> -
> -	/* Set all of interface type of ports and mac tables to UNDEF */
> -	for (core_cnt = 0; core_cnt < SPP_CONFIG_CORE_MAX; core_cnt++) {
> -		for (port_cnt = 0; port_cnt < RTE_MAX_ETHPORTS; port_cnt++) {
> -			config->proc.functions[core_cnt].rx_ports[port_cnt].if_type = UNDEF;
> -			config->proc.functions[core_cnt].tx_ports[port_cnt].if_type = UNDEF;
> -		}
> -	}
> -	for (table_cnt = 0; table_cnt < SPP_CONFIG_MAC_TABLE_MAX; table_cnt++) {
> -		config->classifier_table.mac_tables[table_cnt].port.if_type = UNDEF;
> -	}
> -
> -	return;
> -}
> -
> -/**
> - * Sepeparate port id of combination of iface type and number and
> - * assign to given argment, if_type and if_no.
> - *
> - * For instance, 'ring:0' is separated to 'ring' and '0'.
> - *
> - * TODO(yasufum) change if to iface
> - */
> -int
> -spp_config_get_if_info(const char *port, enum port_type *if_type, int *if_no)
> -{
> -	enum port_type type = UNDEF;
> -	const char *no_str = NULL;
> -	char *endptr = NULL;
> -
> -	/* Find out which type of interface from port */
> -	if (strncmp(port, SPP_CONFIG_IFTYPE_NIC ":", strlen(SPP_CONFIG_IFTYPE_NIC)+1) == 0) {
> -		/* NIC */
> -		type = PHY;
> -		no_str = &port[strlen(SPP_CONFIG_IFTYPE_NIC)+1];
> -	} else if (strncmp(port, SPP_CONFIG_IFTYPE_VHOST ":", strlen(SPP_CONFIG_IFTYPE_VHOST)+1) == 0) {
> -		/* VHOST */
> -		type = VHOST;
> -		no_str = &port[strlen(SPP_CONFIG_IFTYPE_VHOST)+1];
> -	} else if (strncmp(port, SPP_CONFIG_IFTYPE_RING ":", strlen(SPP_CONFIG_IFTYPE_RING)+1) == 0) {
> -		/* RING */
> -		type = RING;
> -		no_str = &port[strlen(SPP_CONFIG_IFTYPE_RING)+1];
> -	} else {
> -		/* OTHER */
> -		RTE_LOG(ERR, APP, "Unknown interface type. (port = %s)\n", port);
> -		return -1;
> -	}
> -
> -	/* Change type of number of interface */
> -	int ret_no = strtol(no_str, &endptr, 0);
> -	if (unlikely(no_str == endptr) || unlikely(*endptr != '\0')) {
> -		/* No IF number */
> -		RTE_LOG(ERR, APP, "No interface number. (port = %s)\n", port);
> -		return -1;
> -	}
> -
> -	*if_type = type;
> -	*if_no = ret_no;
> -
> -	RTE_LOG(DEBUG, APP, "Port = %s => Type = %d No = %d\n",
> -			port, *if_type, *if_no);
> -	return 0;
> -}
> -
> -/**
> - * Generate a formatted string of conbination from interface type and
> - * number and assign to given 'port'
> - */
> -int spp_config_format_port_string(char *port, enum port_type if_type, int if_no)
> -{
> -	const char* if_type_str;
> -
> -	switch (if_type) {
> -	case PHY:
> -		if_type_str = SPP_CONFIG_IFTYPE_NIC;
> -		break;
> -	case RING:
> -		if_type_str = SPP_CONFIG_IFTYPE_RING;
> -		break;
> -	case VHOST:
> -		if_type_str = SPP_CONFIG_IFTYPE_VHOST;
> -		break;
> -	default:
> -		return -1;
> -	}
> -
> -	sprintf(port, "%s:%d", if_type_str, if_no);
> -
> -	return 0;
> -}
> -
> -/**
> - * Change mac address of 'aa:bb:cc:dd:ee:ff' to int64 and return it
> - */
> -int64_t
> -spp_config_change_mac_str_to_int64(const char *mac)
> -{
> -	int64_t ret_mac = 0;
> -	int64_t token_val = 0;
> -	int token_cnt = 0;
> -	char tmp_mac[SPP_CONFIG_STR_LEN];
> -	char *str = tmp_mac;
> -	char *saveptr = NULL;
> -	char *endptr = NULL;
> -
> -	RTE_LOG(DEBUG, APP, "MAC address change. (mac = %s)\n", mac);
> -
> -	strcpy(tmp_mac, mac);
> -	while(1) {
> -		/* Split by clolon(':') */
> -		char *ret_tok = strtok_r(str, ":", &saveptr);
> -		if (unlikely(ret_tok == NULL)) {
> -			break;
> -		}
> -
> -		/* Convert string to hex value */
> -		int ret_tol = strtol(ret_tok, &endptr, 16);
> -		if (unlikely(ret_tok == endptr) || unlikely(*endptr != '\0')) {
> -			break;
> -		}
> -
> -		/* Append separated value to the result */
> -		token_val = (int64_t)ret_tol;
> -		ret_mac |= token_val << (token_cnt * 8);
> -		token_cnt++;
> -		str = NULL;
> -	}
> -
> -	/* Check for mal-formatted address */
> -	if (unlikely(token_cnt != ETHER_ADDR_LEN)) {
> -		RTE_LOG(ERR, APP, "MAC address format error. (mac = %s)\n",
> -				 mac);
> -		return -1;
> -	}
> -
> -	RTE_LOG(DEBUG, APP, "MAC address change. (mac = %s => 0x%08lx)\n",
> -			 mac, ret_mac);
> -	return ret_mac;
> -}
> -
> -static int
> -config_load_classifier_table(const json_t *obj,
> -		struct spp_config_classifier_table *classifier_table)
> -{
> -	json_t *classifier_obj = spp_config_get_path_obj(obj, JSONPATH_CLASSIFIER_TABLE);
> -	if (unlikely(classifier_obj == NULL)) {
> -		RTE_LOG(INFO, APP, "No classifier table.\n");
> -		return 0;
> -	}
> -
> -	/* Name of classifier table */
> -	int ret_name = config_get_str_value(classifier_obj, JSONPATH_NAME,
> -			classifier_table->name);
> -	if (unlikely(ret_name != 0)) {
> -		RTE_LOG(ERR, APP, "Classifier table name get failed.\n");
> -		return -1;
> -	}
> -
> -	/* Setup classifier as an array */
> -	json_t *array_obj = spp_config_get_path_obj(classifier_obj, JSONPATH_TABLE);
> -	if (unlikely(!array_obj)) {
> -		RTE_LOG(ERR, APP, "Json object get failed. (path = %s)\n",
> -				JSONPATH_TABLE);
> -		return -1;
> -	}
> -	if (unlikely(!json_is_array(array_obj))) {
> -		RTE_LOG(ERR, APP, "Not an array. (path = %s)\n",
> -				JSONPATH_TABLE);
> -		return -1;
> -	}
> -
> -	/* Get the number of tables to set an attribute of classifier_table */
> -	int array_num = json_array_size(array_obj);
> -	if (unlikely(array_num <= 0) ||
> -			unlikely(array_num > SPP_CONFIG_MAC_TABLE_MAX)) {
> -		RTE_LOG(ERR, APP, "Table size out of range. (path = %s, size = %d)\n",
> -				JSONPATH_TABLE, array_num);
> -		return -1;
> -	}
> -	classifier_table->num_table = array_num;
> -
> -	/* Setup for each of mac tables */
> -	struct spp_config_mac_table_element *tmp_table = NULL;
> -	char if_str[SPP_CONFIG_STR_LEN];
> -	int table_cnt = 0;
> -	for (table_cnt = 0; table_cnt < array_num; table_cnt++) {
> -		tmp_table = &classifier_table->mac_tables[table_cnt];
> -
> -		/* Get contents from the table */
> -		json_t *elements_obj = json_array_get(array_obj, table_cnt);
> -		if (unlikely(elements_obj == NULL)) {
> -			RTE_LOG(ERR, APP,
> -				"Element get failed. (No = %d, path = %s)\n",
> -				table_cnt, JSONPATH_TABLE);
> -			return -1;
> -		}
> -
> -		int ret_mac = config_get_str_value(elements_obj, JSONPATH_MAC,
> -				tmp_table->mac_addr_str);
> -		if (unlikely(ret_mac != 0)) {
> -			RTE_LOG(ERR, APP,
> -				"MAC address get failed. (No = %d, path = %s)\n",
> -				table_cnt, JSONPATH_MAC);
> -			return -1;
> -		}
> -
> -		/**
> -		  * If mac address is set to 'default', replace it to reserved
> -		  * dummy address for validation.
> -		  */
> -		if (unlikely(strcmp(tmp_table->mac_addr_str,
> -				SPP_CONFIG_DEFAULT_CLASSIFIED_SPEC_STR) == 0))
> -			strcpy(tmp_table->mac_addr_str,
> -					SPP_CONFIG_DEFAULT_CLASSIFIED_DMY_ADDR_STR);
> -
> -		/* Convert mac address to integer */
> -		int64_t ret_mac64 = spp_config_change_mac_str_to_int64(
> -				tmp_table->mac_addr_str);
> -		if (unlikely(ret_mac64 == -1)) {
> -			RTE_LOG(ERR, APP,
> -				"MAC address change failed. (No = %d, mac = %s)\n",
> -				table_cnt, tmp_table->mac_addr_str);
> -			return -1;
> -		}
> -		tmp_table->mac_addr = ret_mac64;
> -
> -		/* Extract a set of port type and number of interface */
> -		int ret_if_str = config_get_str_value(elements_obj,
> -				JSONPATH_PORT, if_str);
> -		if (unlikely(ret_if_str != 0)) {
> -			RTE_LOG(ERR, APP,
> -				"Interface get failed. (No = %d, path = %s)\n",
> -				table_cnt, JSONPATH_PORT);
> -			return -1;
> -		}
> -		/* And separate it to type and number */
> -		int ret_if = spp_config_get_if_info(if_str, &tmp_table->port.if_type,
> -				&tmp_table->port.if_no);
> -		if (unlikely(ret_if != 0)) {
> -			RTE_LOG(ERR, APP,
> -				"Interface change failed. (No = %d, IF = %s)\n",
> -				table_cnt, if_str);
> -			return -1;
> -		}
> -	}
> -
> -	return 0;
> -}
> -
> -/**
> - * Return the type of forwarder as a member of enum of spp_core_type
> - */
> -static enum spp_core_type
> -config_change_core_type(const char *core_type)
> -{
> -	if(strncmp(core_type, CONFIG_CORE_TYPE_CLASSIFIER_MAC,
> -			 strlen(CONFIG_CORE_TYPE_CLASSIFIER_MAC)+1) == 0) {
> -		/* Classifier */
> -		return SPP_CONFIG_CLASSIFIER_MAC;
> -	} else if (strncmp(core_type, CONFIG_CORE_TYPE_MERGE,
> -			 strlen(CONFIG_CORE_TYPE_MERGE)+1) == 0) {
> -		/* Merger */
> -		return SPP_CONFIG_MERGE;
> -	} else if (strncmp(core_type, CONFIG_CORE_TYPE_FORWARD,
> -			 strlen(CONFIG_CORE_TYPE_FORWARD)+1) == 0) {
> -		/* Forwarder */
> -		return SPP_CONFIG_FORWARD;
> -	}
> -	return SPP_CONFIG_UNUSE;
> -}
> -
> -/* Set behavior of rx port for forwarder, merger or classifier */
> -static int
> -config_set_rx_port(enum spp_core_type type, json_t *obj,
> -		struct spp_config_functions *functions)
> -{
> -	struct spp_config_port_info *tmp_rx_port = NULL;
> -	char if_str[SPP_CONFIG_STR_LEN];
> -	if (type == SPP_CONFIG_MERGE) {
> -		/* Merger */
> -		json_t *array_obj = spp_config_get_path_obj(obj, JSONPATH_RX_PORT);
> -		if (unlikely(!array_obj)) {
> -			RTE_LOG(ERR, APP, "Json object get failed. (path = %s, route = merge)\n",
> -				JSONPATH_RX_PORT);
> -			return -1;
> -		}
> -
> -		if (unlikely(!json_is_array(array_obj))) {
> -			RTE_LOG(ERR, APP, "Not an array. (path = %s, route = merge)\n",
> -				JSONPATH_TABLE);
> -			return -1;
> -		}
> -
> -		/* Check if the size of array is not over RTE_MAX_ETHPORTS */
> -		int port_num = json_array_size(array_obj);
> -		if (unlikely(port_num <= 0) ||
> -				unlikely(port_num > RTE_MAX_ETHPORTS)) {
> -			RTE_LOG(ERR, APP, "RX port out of range. (path = %s, port = %d, route = merge)\n",
> -					JSONPATH_RX_PORT, port_num);
> -			return -1;
> -		}
> -		functions->num_rx_port = port_num;
> -
> -		/* Get interface type and number of each of entries for merging */
> -		int array_cnt = 0;
> -		for (array_cnt = 0; array_cnt < port_num; array_cnt++) {
> -			tmp_rx_port = &functions->rx_ports[array_cnt];
> -
> -			json_t *elements_obj = json_array_get(array_obj, array_cnt);
> -			if (unlikely(elements_obj == NULL)) {
> -				RTE_LOG(ERR, APP,
> -					"Element get failed. (No = %d, path = %s, route = merge)\n",
> -					array_cnt, JSONPATH_RX_PORT);
> -				return -1;
> -			}
> -
> -			if (unlikely(!json_is_string(elements_obj))) {
> -				RTE_LOG(ERR, APP, "Not a string. (path = %s, No = %d, route = merge)\n",
> -						JSONPATH_RX_PORT, array_cnt);
> -				return -1;
> -			}
> -			strcpy(if_str, json_string_value(elements_obj));
> -
> -			/* Separate combination of interface type and number to each */
> -			int ret_if = spp_config_get_if_info(if_str, &tmp_rx_port->if_type,
> -					&tmp_rx_port->if_no);
> -			if (unlikely(ret_if != 0)) {
> -				RTE_LOG(ERR, APP,
> -					"Interface change failed. (No = %d, port = %s, route = merge)\n",
> -					array_cnt, if_str);
> -				return -1;
> -			}
> -		}
> -	} else {
> -		/* Classifier or forwarder */
> -		tmp_rx_port = &functions->rx_ports[0];
> -		functions->num_rx_port = 1;
> -
> -		/* Get receiving port */
> -		int ret_rx_port = config_get_str_value(obj, JSONPATH_RX_PORT, if_str);
> -		if (unlikely(ret_rx_port != 0)) {
> -			RTE_LOG(ERR, APP, "RX port get failed.\n");
> -			return -1;
> -		}
> -
> -		/* Separate it to interface type and number */
> -		int ret_if = spp_config_get_if_info(if_str, &tmp_rx_port->if_type,
> -				&tmp_rx_port->if_no);
> -		if (unlikely(ret_if != 0)) {
> -			RTE_LOG(ERR, APP,
> -				"Interface change failed. (port = %s)\n", if_str);
> -			return -1;
> -		}
> -	}
> -
> -	return 0;
> -}
> -
> -/* Set behavior of tx port for forwarder, merger or classifier */
> -static int
> -config_set_tx_port(enum spp_core_type type, json_t *obj,
> -		struct spp_config_functions *functions,
> -		struct spp_config_classifier_table *classifier_table)
> -{
> -	int cnt = 0;
> -	struct spp_config_port_info *tmp_tx_port = NULL;
> -	char if_str[SPP_CONFIG_STR_LEN];
> -	if ((type == SPP_CONFIG_MERGE) || (type == SPP_CONFIG_FORWARD)) {
> -		/* Merger or forwarder */
> -		tmp_tx_port = &functions->tx_ports[0];
> -		functions->num_tx_port = 1;
> -
> -		/* Get receiving port */
> -		int ret_tx_port = config_get_str_value(obj,
> -				JSONPATH_TX_PORT, if_str);
> -		if (unlikely(ret_tx_port != 0)) {
> -			RTE_LOG(ERR, APP, "TX port get failed.\n");
> -			return -1;
> -		}
> -
> -		/* Separate it to interface type and number */
> -		int ret_if = spp_config_get_if_info(if_str, &tmp_tx_port->if_type,
> -				&tmp_tx_port->if_no);
> -		if (unlikely(ret_if != 0)) {
> -			RTE_LOG(ERR, APP,
> -				"Interface change failed. (port = %s)\n",
> -				if_str);
> -			return -1;
> -		}
> -	} else {
> -		/* Classifier */
> -		json_t *table_obj = spp_config_get_path_obj(obj, JSONPATH_TX_TABLE);
> -		if (unlikely(table_obj != NULL)) {
> -			functions->num_tx_port = classifier_table->num_table;
> -			struct spp_config_mac_table_element *tmp_mac_table = NULL;
> -			for (cnt = 0; cnt < classifier_table->num_table; cnt++) {
> -				tmp_tx_port = &functions->tx_ports[cnt];
> -				tmp_mac_table = &classifier_table->mac_tables[cnt];
> -
> -				tmp_tx_port->if_type = tmp_mac_table->port.if_type;
> -				tmp_tx_port->if_no   = tmp_mac_table->port.if_no;
> -			}
> -		} else {
> -			/* Get sending ports if table_obj is NULL */
> -			json_t *array_obj = spp_config_get_path_obj(obj, JSONPATH_TX_PORT);
> -			if (unlikely(array_obj == NULL)) {
> -				RTE_LOG(ERR, APP, "Json object get failed. (path = %s, route = classifier)\n",
> -					JSONPATH_TX_PORT);
> -				return -1;
> -			}
> -
> -			if (unlikely(!json_is_array(array_obj))) {
> -				RTE_LOG(ERR, APP, "Not an array. (path = %s, route = classifier)\n",
> -					JSONPATH_TX_PORT);
> -				return -1;
> -			}
> -
> -			/* Check if the size of array is not over RTE_MAX_ETHPORTS */
> -			int port_num = json_array_size(array_obj);
> -			if (unlikely(port_num <= 0) ||
> -					unlikely(port_num > RTE_MAX_ETHPORTS)) {
> -				RTE_LOG(ERR, APP, "TX port out of range. (path = %s, port = %d, route = classifier)\n",
> -						JSONPATH_TX_PORT, port_num);
> -				return -1;
> -			}
> -			functions->num_tx_port = port_num;
> -
> -			int array_cnt = 0;
> -			for (array_cnt = 0; array_cnt < port_num; array_cnt++) {
> -				tmp_tx_port = &functions->tx_ports[array_cnt];
> -
> -				json_t *elements_obj = json_array_get(array_obj, array_cnt);
> -				if (unlikely(elements_obj == NULL)) {
> -					RTE_LOG(ERR, APP,
> -						"Element get failed. (No = %d, path = %s, route = classifier)\n",
> -						array_cnt, JSONPATH_TX_PORT);
> -					return -1;
> -				}
> -
> -				/* Get sending port */
> -				if (unlikely(!json_is_string(elements_obj))) {
> -					RTE_LOG(ERR, APP, "Not a string. (path = %s, No = %d, route = classifier)\n",
> -							JSONPATH_TX_PORT, array_cnt);
> -					return -1;
> -				}
> -				strcpy(if_str, json_string_value(elements_obj));
> -
> -				/* Separate it to interface type and number */
> -				int ret_if = spp_config_get_if_info(if_str, &tmp_tx_port->if_type,
> -						&tmp_tx_port->if_no);
> -				if (unlikely(ret_if != 0)) {
> -					RTE_LOG(ERR, APP,
> -						"Interface change failed. (No = %d, port = %s, route = classifier)\n",
> -						array_cnt, if_str);
> -					return -1;
> -				}
> -			}
> -		}
> -	}
> -
> -	return 0;
> -}
> -
> -static int
> -config_load_proc_info(const json_t *obj, int node_id, struct spp_config_area *config)
> -{
> -	struct spp_config_proc_info *proc = &config->proc;
> -	struct spp_config_classifier_table *classifier_table = &config->classifier_table;
> -
> -	/* TODO(yasufum) add comment after updating definition of the function in spp_config.c */
> -	json_t *proc_table_obj = spp_config_get_path_obj(obj, JSONPATH_PROC_TABLE);
> -	if (unlikely(proc_table_obj == NULL)) {
> -		RTE_LOG(ERR, APP, "Json object get failed. (path = %s)\n",
> -				JSONPATH_PROC_TABLE);
> -		return -1;
> -	}
> -
> -	/* Return error code if it is not an array_obj */
> -	if (unlikely(!json_is_array(proc_table_obj))) {
> -		RTE_LOG(ERR, APP, "Not an array. (path = %s)\n",
> -				JSONPATH_TABLE);
> -		return -1;
> -	}
> -
> -	/* Check if the size of array is not over node_id */
> -	int proc_table_num = json_array_size(proc_table_obj);
> -	if (unlikely(proc_table_num < node_id)) {
> -		RTE_LOG(ERR, APP, "No process data. (Size = %d, Node = %d)\n",
> -			proc_table_num, node_id);
> -		return -1;
> -	}
> -
> -	/* Get proc_obj for attributes */
> -	json_t *proc_obj = json_array_get(proc_table_obj, node_id);
> -	if (unlikely(proc_obj == NULL)) {
> -		RTE_LOG(ERR, APP, "Process data get failed. (Node = %d)\n",
> -				node_id);
> -		return -1;
> -	}
> -
> -	/* Name of proc */
> -	int ret_name = config_get_str_value(proc_obj, JSONPATH_NAME, proc->name);
> -	if (unlikely(ret_name != 0)) {
> -		RTE_LOG(ERR, APP, "Process name get failed.\n");
> -		return -1;
> -	}
> -
> -	/* Number of vhost interfaces of proc */
> -	int ret_vhost = config_get_int_value(proc_obj, JSONPATH_NUM_VHOST,
> -			&proc->num_vhost);
> -	if (unlikely(ret_vhost != 0)) {
> -		RTE_LOG(ERR, APP, "VHOST number get failed.\n");
> -		return -1;
> -	}
> -
> -	/* Number of ring interfaces of proc */
> -	int ret_ring = config_get_int_value(proc_obj, JSONPATH_NUM_RING,
> -			&proc->num_ring);
> -	if (unlikely(ret_ring != 0)) {
> -		RTE_LOG(ERR, APP, "RING number get failed.\n");
> -		return -1;
> -	}
> -
> -	/* Get the number of operator functions */
> -	json_t *array_obj = spp_config_get_path_obj(proc_obj, JSONPATH_FUNCTIONS);
> -	if (unlikely(!array_obj)) {
> -		RTE_LOG(ERR, APP, "Json object get failed. (path = %s)\n",
> -				JSONPATH_FUNCTIONS);
> -		return -1;
> -	}
> -
> -	if (unlikely(!json_is_array(array_obj))) {
> -		RTE_LOG(ERR, APP, "Not an array. (path = %s)\n",
> -				JSONPATH_FUNCTIONS);
> -		return -1;
> -	}
> -
> -	int array_num = json_array_size(array_obj);
> -	if (unlikely(array_num <= 0) ||
> -			unlikely(array_num > SPP_CONFIG_CORE_MAX)) {
> -		RTE_LOG(ERR, APP, "Functions size out of range. (path = %s, size = %d)\n",
> -				JSONPATH_TABLE, array_num);
> -		return -1;
> -	}
> -	proc->num_func = array_num;
> -
> -	/* Get each of operator functions */
> -	struct spp_config_functions *tmp_functions = NULL;
> -	char core_type_str[SPP_CONFIG_STR_LEN];
> -	int array_cnt = 0;
> -	for (array_cnt = 0; array_cnt < array_num; array_cnt++) {
> -		tmp_functions = &proc->functions[array_cnt];
> -
> -		json_t *elements_obj = json_array_get(array_obj, array_cnt);
> -		if (unlikely(elements_obj == NULL)) {
> -			RTE_LOG(ERR, APP,
> -				"Element get failed. (No = %d, path = %s)\n",
> -				array_cnt, JSONPATH_FUNCTIONS);
> -			return -1;
> -		}
> -
> -		/* Get number and type of the core */
> -		int ret_core = config_get_int_value(elements_obj, JSONPATH_CORE_NO,
> -				&tmp_functions->core_no);
> -		if (unlikely(ret_core != 0)) {
> -			RTE_LOG(ERR, APP, "Core number get failed. (No = %d)\n",
> -					array_cnt);
> -			return -1;
> -		}
> -
> -		int ret_core_type = config_get_str_value(elements_obj,
> -				 JSONPATH_CORE_TYPE, core_type_str);
> -		if (unlikely(ret_core_type != 0)) {
> -			RTE_LOG(ERR, APP, "Core type get failed. (No = %d)\n",
> -					array_cnt);
> -			return -1;
> -		}
> -
> -		/* Convert the type of core to a member of enum spp_core_type */
> -		enum spp_core_type core_type = config_change_core_type(core_type_str);
> -		if (unlikely(core_type == SPP_CONFIG_UNUSE)) {
> -			RTE_LOG(ERR, APP,
> -				"Unknown core type. (No = %d, type = %s)\n",
> -				array_cnt, core_type_str);
> -			return -1;
> -		}
> -		tmp_functions->type = core_type;
> -
> -		/* Get rx and tx ports */
> -		int ret_rx_port = config_set_rx_port(core_type, elements_obj,
> -				tmp_functions);
> -		if (unlikely(ret_rx_port != 0)) {
> -			RTE_LOG(ERR, APP, "RX port set failure. (No = %d)\n",
> -					array_cnt);
> -			return -1;
> -		}
> -
> -		int ret_tx_port = config_set_tx_port(core_type, elements_obj,
> -				tmp_functions, classifier_table);
> -		if (unlikely(ret_tx_port != 0)) {
> -			RTE_LOG(ERR, APP, "TX port set failure. (No = %d)\n",
> -					array_cnt);
> -			return -1;
> -		}
> -	}
> -
> -	return 0;
> -}
> -
> -int
> -spp_config_load_file(const char* config_file_path, int node_id, struct spp_config_area *config)
> -{
> -	config_init_data(config);
> -
> -	json_error_t json_error;
> -	json_t *conf_obj = json_load_file(config_file_path, 0, &json_error);
> -	if (unlikely(conf_obj == NULL)) {
> -		/* Load error */
> -		RTE_LOG(ERR, APP, "Config load failed. (path = %s, text = %s)\n",
> -				 config_file_path, json_error.text);
> -		return -1;
> -	}
> -
> -	int ret_classifier = config_load_classifier_table(conf_obj,
> -			&config->classifier_table);
> -	if (unlikely(ret_classifier != 0)) {
> -		RTE_LOG(ERR, APP, "Classifier table load failed.\n");
> -		json_decref(conf_obj);
> -		return -1;
> -	}
> -
> -	int ret_proc = config_load_proc_info(conf_obj, node_id, config);
> -	if (unlikely(ret_proc != 0)) {
> -		RTE_LOG(ERR, APP, "Process table load failed.\n");
> -		json_decref(conf_obj);
> -		return -1;
> -	}
> -
> -	/* Finally, release config object */
> -	json_decref(conf_obj);
> -
> -	return 0;
> -}
> diff --git a/src/vf/spp_config.h b/src/vf/spp_config.h
> deleted file mode 100644
> index 5722afd..0000000
> --- a/src/vf/spp_config.h
> +++ /dev/null
> @@ -1,126 +0,0 @@
> -#ifndef __SPP_CONFIG_H__
> -#define __SPP_CONFIG_H__
> -
> -#include <jansson.h>
> -#include "common.h"
> -
> -#define SPP_CONFIG_FILE_PATH "/usr/local/etc/spp/spp.json"
> -
> -#define SPP_CONFIG_IFTYPE_NIC   "phy"
> -#define SPP_CONFIG_IFTYPE_VHOST "vhost"
> -#define SPP_CONFIG_IFTYPE_RING  "ring"
> -
> -#define SPP_CONFIG_STR_LEN 32
> -#define SPP_CONFIG_MAC_TABLE_MAX 16
> -#define SPP_CONFIG_CORE_MAX 128
> -#define SPP_CONFIG_PATH_LEN 1024
> -
> -#define SPP_CONFIG_DEFAULT_CLASSIFIED_SPEC_STR     "default"
> -#define SPP_CONFIG_DEFAULT_CLASSIFIED_DMY_ADDR_STR "00:00:00:00:00:01"
> -#define SPP_CONFIG_DEFAULT_CLASSIFIED_DMY_ADDR     0x010000000000
> -
> -/*
> - * Process type for each CORE
> - */
> -enum spp_core_type {
> -	SPP_CONFIG_UNUSE,
> -	SPP_CONFIG_CLASSIFIER_MAC,
> -	SPP_CONFIG_MERGE,
> -	SPP_CONFIG_FORWARD,
> -};
> -
> -/*
> - * Interface information structure
> - */
> -struct spp_config_port_info {
> -	enum port_type	if_type;
> -	int		if_no;
> -};
> -
> -/*
> - * MAC Table information structure
> - */
> -struct spp_config_mac_table_element {
> -	struct		spp_config_port_info port;
> -	char		mac_addr_str[SPP_CONFIG_STR_LEN];
> -	uint64_t	mac_addr;
> -};
> -
> -/*
> - * Classifier Table information structure
> - */
> -struct spp_config_classifier_table {
> -	char	name[SPP_CONFIG_STR_LEN];
> -	int	num_table;
> -	struct spp_config_mac_table_element mac_tables[SPP_CONFIG_MAC_TABLE_MAX];
> -};
> -
> -/*
> - * Functions information structure
> - */
> -struct spp_config_functions {
> -	int	core_no;
> -	enum	spp_core_type type;
> -	int	num_rx_port;
> -	int	num_tx_port;
> -	struct spp_config_port_info rx_ports[RTE_MAX_ETHPORTS];
> -	struct spp_config_port_info tx_ports[RTE_MAX_ETHPORTS];
> -};
> -
> -/*
> - * Process information structure
> - */
> -struct spp_config_proc_info {
> -	char	name[SPP_CONFIG_STR_LEN];
> -	int	num_vhost;
> -	int	num_ring;
> -	int	num_func;
> -	struct spp_config_functions functions[SPP_CONFIG_CORE_MAX];
> -};
> -
> -/*
> - * Config information structure
> - */
> -struct spp_config_area {
> -	struct spp_config_proc_info proc;
> -	struct spp_config_classifier_table classifier_table;
> -};
> -
> -/*
> - * Instead of json_path_get
> - * OK : Json object address
> - * NG : NULL
> - */
> -json_t *spp_config_get_path_obj(const json_t *json, const char *path);
> -
> -/*
> - * Change mac address string to int64
> - * OK : int64 that store mac address
> - * NG : -1
> - */
> -int64_t spp_config_change_mac_str_to_int64(const char *mac);
> -
> -/*
> - * Extract if-type/if-number from port string
> - *
> - * OK : 0
> - * NG : -1
> - */
> -int spp_config_get_if_info(const char *port, enum port_type *if_type, int *if_no);
> -
> -/*
> - * Format port string form if-type/if-number
> - *
> - * OK : 0
> - * NG : -1
> - */
> -int spp_config_format_port_string(char *port, enum port_type if_type, int if_no);
> -
> -/*
> - * Load config file
> - * OK : 0
> - * NG : -1
> - */
> -int spp_config_load_file(const char* config_file_path, int node_id, struct spp_config_area *config);
> -
> -#endif /* __SPP_CONFIG_H__ */
> diff --git a/src/vf/spp_forward.c b/src/vf/spp_forward.c
> index dbe96dc..3fbfaa5 100644
> --- a/src/vf/spp_forward.c
> +++ b/src/vf/spp_forward.c
> @@ -165,9 +165,10 @@ spp_forward(int id)
>   	return 0;
>   }
>   
> -/* Merge/Forward iterate component information */
> +/* Merge/Forward get component status */
>   int
> -spp_forward_core_info_iterate(unsigned int lcore_id, int id,
> +spp_forward_get_component_status(
> +		unsigned int lcore_id, int id,
>   		struct spp_iterate_core_params *params)
>   {
>   	int ret = -1;
> @@ -203,7 +204,7 @@ spp_forward_core_info_iterate(unsigned int lcore_id, int id,
>   
>   	/* Set the information with the function specified by the command. */
>   	ret = (*params->element_proc)(
> -		params->opaque, lcore_id,
> +		params, lcore_id,
>   		path->name, component_type,
>   		path->num, rx_ports, num_tx, tx_ports);
>   	if (unlikely(ret != 0))
> diff --git a/src/vf/spp_forward.h b/src/vf/spp_forward.h
> index ed0744d..5e5cf0f 100644
> --- a/src/vf/spp_forward.h
> +++ b/src/vf/spp_forward.h
> @@ -15,8 +15,9 @@ int spp_forward_update(struct spp_component_info *component);
>    */
>   int spp_forward(int id);
>   
> -/* Merge/Forward iterate component information */
> -int spp_forward_core_info_iterate(unsigned int lcore_id, int id,
> +/* Merge/Forward get component status */
> +int spp_forward_get_component_status(
> +		unsigned int lcore_id, int id,
>   		struct spp_iterate_core_params *params);
>   
>   #endif /* __SPP_FORWARD_H__ */
> diff --git a/src/vf/spp_vf.c b/src/vf/spp_vf.c
> index 7626ba7..b809807 100644
> --- a/src/vf/spp_vf.c
> +++ b/src/vf/spp_vf.c
> @@ -1348,7 +1348,7 @@ spp_iterate_core_info(struct spp_iterate_core_params *params)
>   		core = get_core_info(lcore_id);
>   		if (core->num == 0) {
>   			ret = (*params->element_proc)(
> -				params->opaque, lcore_id,
> +				params, lcore_id,
>   				"", SPP_TYPE_UNUSE_STR,
>   				0, NULL, 0, NULL);
>   			if (unlikely(ret != 0)) {
> @@ -1362,12 +1362,12 @@ spp_iterate_core_info(struct spp_iterate_core_params *params)
>   
>   		for (cnt = 0; cnt < core->num; cnt++) {
>   			if (core->type == SPP_COMPONENT_CLASSIFIER_MAC) {
> -				ret = spp_classifier_component_info_iterate(
> +				ret = spp_classifier_get_component_status(
>   						lcore_id,
>   						core->id[cnt],
>   						params);
>   			} else {
> -				ret = spp_forward_core_info_iterate(
> +				ret = spp_forward_get_component_status(
>   						lcore_id,
>   						core->id[cnt],
>   						params);
> diff --git a/src/vf/spp_vf.h b/src/vf/spp_vf.h
> index ea2baf1..442fb0e 100644
> --- a/src/vf/spp_vf.h
> +++ b/src/vf/spp_vf.h
> @@ -168,8 +168,9 @@ int spp_update_port(
>   int spp_flush(void);
>   
>   /* definition of iterated core element procedure function */
> +struct spp_iterate_core_params;
>   typedef int (*spp_iterate_core_element_proc)(
> -		void *opaque,
> +		struct spp_iterate_core_params *params,
>   		const unsigned int lcore_id,
>   		const char *name,
>   		const char *type,
> @@ -180,7 +181,7 @@ typedef int (*spp_iterate_core_element_proc)(
>   
>   /* iterate core information  parameters */
>   struct spp_iterate_core_params {
> -	void *opaque;
> +	char *output;
>   	spp_iterate_core_element_proc element_proc;
>   };
>   
> @@ -188,15 +189,16 @@ struct spp_iterate_core_params {
>   int spp_iterate_core_info(struct spp_iterate_core_params *params);
>   
>   /* definition of iterated classifier element procedure function */
> +struct spp_iterate_classifier_table_params;
>   typedef int (*spp_iterate_classifier_element_proc)(
> -		void *opaque,
> +		struct spp_iterate_classifier_table_params *params,
>   		enum spp_classifier_type type,
>   		const char *data,
>   		const struct spp_port_index *port);
>   
>   /* iterate classifier table parameters */
>   struct spp_iterate_classifier_table_params {
> -	void *opaque;
> +	void *output;
>   	spp_iterate_classifier_element_proc element_proc;
>   };
>   
> diff --git a/src/vf/string_buffer.c b/src/vf/string_buffer.c
> index 535d050..07ba8cc 100644
> --- a/src/vf/string_buffer.c
> +++ b/src/vf/string_buffer.c
> @@ -1,10 +1,13 @@
>   #include <stdlib.h>
>   #include <string.h>
>   
> +#include <rte_log.h>
>   #include <rte_branch_prediction.h>
>   
>   #include "string_buffer.h"
>   
> +#define RTE_LOGTYPE_SPP_STRING_BUFF RTE_LOGTYPE_USER1
> +
>   /* get message buffer capacity */
>   inline size_t
>   strbuf_get_capacity(const char *strbuf)
> @@ -42,6 +45,9 @@ spp_strbuf_allocate(size_t capacity)
>   
>   	memset(buf, 0x00, capacity + sizeof(size_t));
>   	*((size_t *)buf) = capacity;
> +	RTE_LOG(DEBUG, SPP_STRING_BUFF,
> +			";alloc  ; addr=%p; size=%lu; str= ; len=0;\n",
> +			buf + sizeof(size_t), capacity);
>   
>   	return buf + sizeof(size_t);
>   }
> @@ -50,8 +56,13 @@ spp_strbuf_allocate(size_t capacity)
>   void
>   spp_strbuf_free(char* strbuf)
>   {
> -	if (likely(strbuf != NULL))
> +	if (likely(strbuf != NULL)) {
> +		RTE_LOG(DEBUG, SPP_STRING_BUFF,
> +				";free   ; addr=%p; size=%lu; str=%s; len=%lu;\n",
> +				strbuf, strbuf_get_capacity(strbuf),
> +				strbuf, strlen(strbuf));
>   		free(strbuf - sizeof(size_t));
> +	}
>   }
>   
>   /* append message to buffer */
> @@ -70,6 +81,10 @@ spp_strbuf_append(char *strbuf, const char *append, size_t append_len)
>   
>   	memcpy(new_strbuf + len, append, append_len);
>   	*(new_strbuf + len + append_len) = '\0';
> +	RTE_LOG(DEBUG, SPP_STRING_BUFF,
> +			";append ; addr=%p; size=%lu; str=%s; len=%lu;\n",
> +			new_strbuf, strbuf_get_capacity(new_strbuf),
> +			new_strbuf, strlen(new_strbuf));
>   
>   	return new_strbuf;
>   }
> 


-- 
Yasufumi Ogawa
NTT Network Service Systems Labs



More information about the spp mailing list