Soft Patch Panel
 help / color / mirror / Atom feed
* [spp] Patches for spp_vf on DPDK17.11
@ 2018-01-10  2:46 x-fn-spp
  2018-01-10  2:47 ` [spp] [PATCH 1/4] spp_vf: fix to eliminate jansson package x-fn-spp
                   ` (5 more replies)
  0 siblings, 6 replies; 11+ messages in thread
From: x-fn-spp @ 2018-01-10  2:46 UTC (permalink / raw)
  To: spp

Hi everyone,

Last year, we've sent some patches for spp_vf on DPDK17.08.
In addition to these patches, we are now ready to contribute
the patches for spp_vf on DPDK17.11.

Code changes will be posted in the following emails.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [spp] [PATCH 1/4] spp_vf: fix to eliminate jansson package
  2018-01-10  2:46 [spp] Patches for spp_vf on DPDK17.11 x-fn-spp
@ 2018-01-10  2:47 ` x-fn-spp
  2018-01-19  0:37   ` Yasufumi Ogawa
  2018-01-10  2:47 ` [spp] [PATCH 2/4] spp_vf: support cancel command x-fn-spp
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 11+ messages in thread
From: x-fn-spp @ 2018-01-10  2:47 UTC (permalink / raw)
  To: spp

From: Hiroyuki Nakamura <nakamura.hioryuki@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@as.ntt-tx.co.jp>
Signed-off-by: Yasufum Ogawa <ogawa.yasufumi@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;
 }
-- 
1.9.1

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [spp] [PATCH 2/4] spp_vf: support cancel command
  2018-01-10  2:46 [spp] Patches for spp_vf on DPDK17.11 x-fn-spp
  2018-01-10  2:47 ` [spp] [PATCH 1/4] spp_vf: fix to eliminate jansson package x-fn-spp
@ 2018-01-10  2:47 ` x-fn-spp
  2018-01-10  2:48 ` [spp] [PATCH 3/4] spp_vf: change type of port_id to uint16_t x-fn-spp
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: x-fn-spp @ 2018-01-10  2:47 UTC (permalink / raw)
  To: spp

From: Hiroyuki Nakamura <nakamura.hioryuki@po.ntt-tx.co.jp>

Newly support 'cancel' command.
* 'cancel' command provides the cancel function for the unflushed
  'component', 'port' and 'classifier_table' commands.
* Also add a debug log functions for the data being canceled by
  the command.

Signed-off-by: Kentaro Watanabe <watanabe.kentaro.z01@as.ntt-tx.co.jp>
Signed-off-by: Yasufum Ogawa <ogawa.yasufumi@lab.ntt.co.jp>
---
 src/vf/command_dec.c  |  12 +--
 src/vf/command_dec.h  |   1 +
 src/vf/command_proc.c |   5 ++
 src/vf/spp_vf.c       | 239 ++++++++++++++++++++++++++++++++++++++++++++++++--
 src/vf/spp_vf.h       |   5 ++
 5 files changed, 251 insertions(+), 11 deletions(-)

diff --git a/src/vf/command_dec.c b/src/vf/command_dec.c
index 56360e9..9576c6f 100644
--- a/src/vf/command_dec.c
+++ b/src/vf/command_dec.c
@@ -524,6 +524,7 @@ static struct decode_parameter_list parameter_list[][SPP_CMD_MAX_PARAMETERS] = {
 		},
 		DECODE_PARAMETER_LIST_EMPTY,
 	},
+	{ DECODE_PARAMETER_LIST_EMPTY }, /* cancel           */
 	{ DECODE_PARAMETER_LIST_EMPTY }, /* termination      */
 };
 
@@ -562,13 +563,14 @@ struct decode_command_list {
 /* command list */
 static struct decode_command_list command_list[] = {
 	{ "classifier_table", 5, 5, decode_comand_parameter_in_list }, /* classifier_table */
-	{ "flush",            1, 1, NULL                            }, /* flush            */
-	{ "_get_client_id",   1, 1, NULL                            }, /* _get_client_id   */
-	{ "status",           1, 1, NULL                            }, /* status           */
-	{ "exit",             1, 1, NULL                            }, /* exit             */
+	{ "flush",            1, 1, NULL },	/* flush            */
+	{ "_get_client_id",   1, 1, NULL },	/* _get_client_id   */
+	{ "status",           1, 1, NULL },	/* status           */
+	{ "exit",             1, 1, NULL },	/* exit             */
 	{ "component",        3, 5, decode_comand_parameter_in_list }, /* component        */
 	{ "port",             5, 5, decode_comand_parameter_in_list }, /* port             */
-	{ "",                 0, 0, NULL                            }  /* termination      */
+	{ "cancel",           1, 1, NULL },	/* cancel           */
+	{ "",                 0, 0, NULL }	/* termination      */
 };
 
 /* Decode command line parameters */
diff --git a/src/vf/command_dec.h b/src/vf/command_dec.h
index 359f5e5..1ab2e43 100644
--- a/src/vf/command_dec.h
+++ b/src/vf/command_dec.h
@@ -38,6 +38,7 @@ enum spp_command_type {
 	SPP_CMDTYPE_EXIT,
 	SPP_CMDTYPE_COMPONENT,
 	SPP_CMDTYPE_PORT,
+	SPP_CMDTYPE_CANCEL,
 };
 
 /* "classifier_table" command specific parameters */
diff --git a/src/vf/command_proc.c b/src/vf/command_proc.c
index 214cb2e..d7fbded 100644
--- a/src/vf/command_proc.c
+++ b/src/vf/command_proc.c
@@ -204,6 +204,11 @@ execute_command(const struct spp_command *command)
 				command->spec.port.name);
 		break;
 
+	case SPP_CMDTYPE_CANCEL:
+		RTE_LOG(INFO, SPP_COMMAND_PROC, "Execute cancel command.\n");
+		spp_cancel();
+		break;
+
 	default:
 		RTE_LOG(INFO, SPP_COMMAND_PROC, "Execute other command. type=%d\n", command->type);
 		/* nothing to do here */
diff --git a/src/vf/spp_vf.c b/src/vf/spp_vf.c
index b809807..feb7f4d 100644
--- a/src/vf/spp_vf.c
+++ b/src/vf/spp_vf.c
@@ -31,6 +31,13 @@ enum SPP_LONGOPT_RETVAL {
 	SPP_LONGOPT_RETVAL_VHOST_CLIENT
 };
 
+/* Flag of processing type to copy management information */
+enum copy_mng_flg {
+	COPY_MNG_FLG_NONE,
+	COPY_MNG_FLG_UPDCOPY,
+	COPY_MNG_FLG_ALLCOPY,
+};
+
 /* Manage given options as global variable */
 struct startup_param {
 	int client_id;
@@ -65,6 +72,13 @@ struct core_mng_info {
 	struct core_info core[SPP_INFO_AREA_MAX];
 };
 
+/* Manage data to be backup */
+struct cancel_backup_info {
+	struct core_mng_info core[RTE_MAX_LCORE];
+	struct spp_component_info component[RTE_MAX_LCORE];
+	struct if_info interface;
+};
+
 /* Declare global variables */
 static unsigned int g_main_lcore_id = 0xffffffff;
 static struct startup_param		g_startup_param;
@@ -75,6 +89,8 @@ static struct core_mng_info		g_core_info[RTE_MAX_LCORE];
 static int 				g_change_core[RTE_MAX_LCORE];  /* TODO(yasufum) add desc how it is used and why changed component is kept */
 static int 				g_change_component[RTE_MAX_LCORE];
 
+static struct cancel_backup_info	g_backup_info;
+
 /* Print help message */
 static void
 usage(const char *progname)
@@ -89,6 +105,34 @@ usage(const char *progname)
 			, progname);
 }
 
+/* Make a hexdump of an array data in every 4 byte */
+static void
+dump_buff(const char *name, const void *addr, const size_t size)
+{
+	size_t cnt = 0;
+	size_t max = (size / sizeof(unsigned int)) +
+			((size % sizeof(unsigned int)) != 0);
+	const uint32_t *buff = addr;
+
+	if ((name != NULL) && (name[0] != '\0'))
+		RTE_LOG(DEBUG, APP, "dump buff. (%s)\n", name);
+
+	for (cnt = 0; cnt < max; cnt += 16) {
+		RTE_LOG(DEBUG, APP, "[%p]"
+				" %08x %08x %08x %08x %08x %08x %08x %08x"
+				" %08x %08x %08x %08x %08x %08x %08x %08x",
+				&buff[cnt],
+				buff[cnt+0], buff[cnt+1],
+				buff[cnt+2], buff[cnt+3],
+				buff[cnt+4], buff[cnt+5],
+				buff[cnt+6], buff[cnt+7],
+				buff[cnt+8], buff[cnt+9],
+				buff[cnt+10], buff[cnt+11],
+				buff[cnt+12], buff[cnt+13],
+				buff[cnt+14], buff[cnt+15]);
+	}
+}
+
 static int
 add_ring_pmd(int ring_id)
 {
@@ -417,6 +461,183 @@ get_if_area(enum port_type if_type, int if_no)
 	}
 }
 
+/* Dump of core information */
+static void
+dump_core_info(const struct core_mng_info *core_info)
+{
+	char str[SPP_NAME_STR_LEN];
+	const struct core_mng_info *info = NULL;
+	unsigned int lcore_id = 0;
+	RTE_LCORE_FOREACH_SLAVE(lcore_id) {
+		info = &core_info[lcore_id];
+		RTE_LOG(DEBUG, APP, "core[%d] status=%d, ref=%d, upd=%d\n",
+				lcore_id, info->status,
+				info->ref_index, info->upd_index);
+
+		sprintf(str, "core[%d]-0 type=%d, num=%d", lcore_id,
+				info->core[0].type, info->core[0].num);
+		dump_buff(str, info->core[0].id, sizeof(int)*info->core[0].num);
+
+		sprintf(str, "core[%d]-1 type=%d, num=%d", lcore_id,
+				info->core[1].type, info->core[1].num);
+		dump_buff(str, info->core[1].id, sizeof(int)*info->core[1].num);
+	}
+}
+
+/* Dump of component information */
+static void
+dump_component_info(const struct spp_component_info *component_info)
+{
+	char str[SPP_NAME_STR_LEN];
+	const struct spp_component_info *component = NULL;
+	int cnt = 0;
+	for (cnt = 0; cnt < RTE_MAX_LCORE; cnt++) {
+		component = &component_info[cnt];
+		if (component->type == SPP_COMPONENT_UNUSE)
+			continue;
+
+		RTE_LOG(DEBUG, APP, "component[%d] name=%s, type=%d, core=%u, index=%d\n",
+				cnt, component->name, component->type,
+				component->lcore_id, component->component_id);
+
+		sprintf(str, "component[%d] rx=%d", cnt,
+				component->num_rx_port);
+		dump_buff(str, component->rx_ports,
+			sizeof(struct spp_port_info *)*component->num_rx_port);
+
+		sprintf(str, "component[%d] tx=%d", cnt,
+				component->num_tx_port);
+		dump_buff(str, component->tx_ports,
+			sizeof(struct spp_port_info *)*component->num_tx_port);
+	}
+}
+
+/* Dump of interface information */
+static void
+dump_interface_info(const struct if_info *if_info)
+{
+	const struct spp_port_info *port = NULL;
+	int cnt = 0;
+	RTE_LOG(DEBUG, APP, "interface phy=%d, vhost=%d, ring=%d\n",
+			if_info->num_nic,
+			if_info->num_vhost,
+			if_info->num_ring);
+	for (cnt = 0; cnt < RTE_MAX_ETHPORTS; cnt++) {
+		port = &if_info->nic[cnt];
+		if (port->if_type == UNDEF)
+			continue;
+
+		RTE_LOG(DEBUG, APP, "phy  [%d] type=%d, no=%d, port=%d, "
+				"mac=%08lx(%s)\n",
+				cnt, port->if_type, port->if_no,
+				port->dpdk_port,
+				port->mac_addr, port->mac_addr_str);
+	}
+	for (cnt = 0; cnt < RTE_MAX_ETHPORTS; cnt++) {
+		port = &if_info->vhost[cnt];
+		if (port->if_type == UNDEF)
+			continue;
+
+		RTE_LOG(DEBUG, APP, "vhost[%d] type=%d, no=%d, port=%d, "
+				"mac=%08lx(%s)\n",
+				cnt, port->if_type, port->if_no,
+				port->dpdk_port,
+				port->mac_addr, port->mac_addr_str);
+	}
+	for (cnt = 0; cnt < RTE_MAX_ETHPORTS; cnt++) {
+		port = &if_info->ring[cnt];
+		if (port->if_type == UNDEF)
+			continue;
+
+		RTE_LOG(DEBUG, APP, "ring [%d] type=%d, no=%d, port=%d, "
+				"mac=%08lx(%s)\n",
+				cnt, port->if_type, port->if_no,
+				port->dpdk_port,
+				port->mac_addr, port->mac_addr_str);
+	}
+}
+
+/* Dump of all management information */
+static void
+dump_all_mng_info(
+		const struct core_mng_info *core,
+		const struct spp_component_info *component,
+		const struct if_info *interface)
+{
+	if (rte_log_get_global_level() < RTE_LOG_DEBUG)
+		return;
+
+	dump_core_info(core);
+	dump_component_info(component);
+	dump_interface_info(interface);
+}
+
+/* Copy management information */
+static void
+copy_mng_info(
+		struct core_mng_info *dst_core,
+		struct spp_component_info *dst_component,
+		struct if_info *dst_interface,
+		const struct core_mng_info *src_core,
+		const struct spp_component_info *src_component,
+		const struct if_info *src_interface,
+		enum copy_mng_flg flg)
+{
+	int upd_index = 0;
+	unsigned int lcore_id = 0;
+
+	switch (flg) {
+	case COPY_MNG_FLG_UPDCOPY:
+		RTE_LCORE_FOREACH_SLAVE(lcore_id) {
+			upd_index = src_core[lcore_id].upd_index;
+			memcpy(&dst_core[lcore_id].core[upd_index],
+					&src_core[lcore_id].core[upd_index],
+					sizeof(struct core_info));
+		}
+		break;
+	default:
+		/*
+		 * Even if the flag is set to None,
+		 * copying of core is necessary,
+		 * so we will treat all copies as default.
+		 */
+		memcpy(dst_core, src_core,
+				sizeof(struct core_mng_info)*RTE_MAX_LCORE);
+		break;
+	}
+
+	memcpy(dst_component, src_component,
+			sizeof(struct spp_component_info)*RTE_MAX_LCORE);
+	memcpy(dst_interface, src_interface,
+			sizeof(struct if_info));
+}
+
+/* Backup the management information */
+static void
+backup_mng_info(struct cancel_backup_info *backup)
+{
+	dump_all_mng_info(g_core_info, g_component_info, &g_if_info);
+	copy_mng_info(backup->core, backup->component, &backup->interface,
+			g_core_info, g_component_info, &g_if_info,
+			COPY_MNG_FLG_ALLCOPY);
+	dump_all_mng_info(backup->core, backup->component, &backup->interface);
+	memset(g_change_core, 0x00, sizeof(g_change_core));
+	memset(g_change_component, 0x00, sizeof(g_change_component));
+}
+
+/* Cancel update of management information */
+static void
+cancel_mng_info(struct cancel_backup_info *backup)
+{
+	dump_all_mng_info(backup->core, backup->component, &backup->interface);
+	copy_mng_info(g_core_info, g_component_info, &g_if_info,
+			backup->core, backup->component, &backup->interface,
+			COPY_MNG_FLG_ALLCOPY);
+	dump_all_mng_info(g_core_info, g_component_info, &g_if_info);
+	memset(g_change_core, 0x00, sizeof(g_change_core));
+	memset(g_change_component, 0x00, sizeof(g_change_component));
+}
+
 /**
  * Initialize g_if_info
  *
@@ -764,6 +985,9 @@ ut_main(int argc, char *argv[])
 		RTE_LOG(INFO, APP, "My ID %d start handling message\n", 0);
 		RTE_LOG(INFO, APP, "[Press Ctrl-C to quit ...]\n");
 
+		/* Backup the management information after initialization */
+		backup_mng_info(&g_backup_info);
+
 		/* Enter loop for accepting commands */
 		int ret_do = 0;
 #ifndef USE_UT_SPP_VF
@@ -1321,16 +1545,19 @@ spp_flush(void)
 
 	/* Flush of core index. */
 	flush_core();
-	memset(g_change_core, 0x00, sizeof(g_change_core));
 
 	/* Flush of component */
 	ret = flush_component();
-	if (ret < 0)
-		return ret;
 
-	/* Finally, zero-clear g_change_core */
-	memset(g_change_component, 0x00, sizeof(g_change_component));
-	return SPP_RET_OK;
+	backup_mng_info(&g_backup_info);
+	return ret;
+}
+
+/* Cancel data that is not flushing */
+void
+spp_cancel(void)
+{
+	cancel_mng_info(&g_backup_info);
 }
 
 /* Iterate core infomartion */
diff --git a/src/vf/spp_vf.h b/src/vf/spp_vf.h
index 442fb0e..3c1f586 100644
--- a/src/vf/spp_vf.h
+++ b/src/vf/spp_vf.h
@@ -167,6 +167,11 @@ int spp_update_port(
  */
 int spp_flush(void);
 
+/*
+ * Cancel data that is not flushing
+ */
+void spp_cancel(void);
+
 /* definition of iterated core element procedure function */
 struct spp_iterate_core_params;
 typedef int (*spp_iterate_core_element_proc)(
-- 
1.9.1

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [spp] [PATCH 3/4] spp_vf: change type of port_id to uint16_t
  2018-01-10  2:46 [spp] Patches for spp_vf on DPDK17.11 x-fn-spp
  2018-01-10  2:47 ` [spp] [PATCH 1/4] spp_vf: fix to eliminate jansson package x-fn-spp
  2018-01-10  2:47 ` [spp] [PATCH 2/4] spp_vf: support cancel command x-fn-spp
@ 2018-01-10  2:48 ` x-fn-spp
  2018-01-10  2:48 ` [spp] [PATCH 4/4] spp_vf: fix bug of status command x-fn-spp
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: x-fn-spp @ 2018-01-10  2:48 UTC (permalink / raw)
  To: spp

From: Hiroyuki Nakamura <nakamura.hioryuki@po.ntt-tx.co.jp>

In SPP, type of port_id is int while it is changed from uint8_t to
uint16_t in DPDK 17.11. It causes compile errors for incompatible
pointer type.

Signed-off-by: Daiki Yamashita <yamashita.daiki.z01@as.ntt-tx.co.jp>
Signed-off-by: Yasufumi Ogawa <ogawa.yasufumi@lab.ntt.co.jp>
---
 src/vf/classifier_mac.c | 6 +++---
 src/vf/spp_vf.c         | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/vf/classifier_mac.c b/src/vf/classifier_mac.c
index b42c4ac..2e502a5 100644
--- a/src/vf/classifier_mac.c
+++ b/src/vf/classifier_mac.c
@@ -68,7 +68,7 @@ struct classified_data {
 	enum port_type  if_type;              /* interface type (see "enum port_type") */
 	int             if_no;                /* index of ports handled by classifier  */
 	int             if_no_global;         /* id for interface generated by spp_vf  */
-	uint8_t         port;                 /* id for port generated by DPDK         */
+	uint16_t        port;                 /* port id generated by DPDK */
 	uint16_t        num_pkt;              /* the number of packets in pkts[]       */
 	struct rte_mbuf *pkts[MAX_PKT_BURST]; /* packet array to be classified         */
 };
@@ -310,7 +310,7 @@ transmit_packet(struct classified_data *classified_data)
 		for (i = n_tx; i < classified_data->num_pkt; i++)
 			rte_pktmbuf_free(classified_data->pkts[i]);
 		RTE_LOG(DEBUG, SPP_CLASSIFIER_MAC,
-				"drop packets(tx). num=%hu, dpdk_port=%hhu\n",
+				"drop packets(tx). num=%hu, dpdk_port=%hu\n",
 				classified_data->num_pkt - n_tx, classified_data->port);
 	}
 
@@ -348,7 +348,7 @@ push_packet(struct rte_mbuf *pkt, struct classified_data *classified_data)
 	if (unlikely(classified_data->num_pkt == MAX_PKT_BURST)) {
 		RTE_LOG(DEBUG, SPP_CLASSIFIER_MAC,
 				"transimit packets (buffer is filled). "
-				"if_type=%d, if_no={%d,%d}, tx_port=%hhd, num_pkt=%hu\n",
+				"if_type=%d, if_no={%d,%d}, tx_port=%hu, num_pkt=%hu\n",
 				classified_data->if_type,
 				classified_data->if_no_global,
 				classified_data->if_no,
diff --git a/src/vf/spp_vf.c b/src/vf/spp_vf.c
index feb7f4d..3613d46 100644
--- a/src/vf/spp_vf.c
+++ b/src/vf/spp_vf.c
@@ -161,7 +161,7 @@ add_vhost_pmd(int index, int client)
 		.rxmode = { .max_rx_pkt_len = ETHER_MAX_LEN }
 	};
 	struct rte_mempool *mp;
-	uint8_t vhost_port_id;
+	uint16_t vhost_port_id;
 	int nr_queues = 1;
 	const char *name;
 	char devargs[64];
-- 
1.9.1

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [spp] [PATCH 4/4] spp_vf: fix bug of status command
  2018-01-10  2:46 [spp] Patches for spp_vf on DPDK17.11 x-fn-spp
                   ` (2 preceding siblings ...)
  2018-01-10  2:48 ` [spp] [PATCH 3/4] spp_vf: change type of port_id to uint16_t x-fn-spp
@ 2018-01-10  2:48 ` x-fn-spp
  2018-01-10  7:53 ` [spp] Patches for spp_vf on DPDK17.11 Yasufumi Ogawa
  2018-01-19  0:30 ` Yasufumi Ogawa
  5 siblings, 0 replies; 11+ messages in thread
From: x-fn-spp @ 2018-01-10  2:48 UTC (permalink / raw)
  To: spp

From: Hiroyuki Nakamura <nakamura.hioryuki@po.ntt-tx.co.jp>

Fix a bug that displays unnecessary commas
in response JSON message.

Fixes: 67467caec0e7 ("spp_vf: fix to eliminate jansson package")
Cc: watanabe.kentaro.z01@as.ntt-tx.co.jp

Signed-off-by: Kentaro Watanabe <watanabe.kentaro.z01@as.ntt-tx.co.jp>
Signed-off-by: Yasufum Ogawa <ogawa.yasufumi@lab.ntt.co.jp>
---
 src/vf/command_proc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/vf/command_proc.c b/src/vf/command_proc.c
index d7fbded..a97b9af 100644
--- a/src/vf/command_proc.c
+++ b/src/vf/command_proc.c
@@ -358,7 +358,7 @@ append_interface_array(char **output, const enum port_type type)
 		if (!spp_check_flush_port(type, i))
 			continue;
 
-		sprintf(tmp_str, "%s%d", JSON_APPEND_COMMA(i), i);
+		sprintf(tmp_str, "%s%d", JSON_APPEND_COMMA(port_cnt), i);
 
 		*output = spp_strbuf_append(*output, tmp_str, strlen(tmp_str));
 		if (unlikely(*output == NULL)) {
-- 
1.9.1

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [spp] Patches for spp_vf on DPDK17.11
  2018-01-10  2:46 [spp] Patches for spp_vf on DPDK17.11 x-fn-spp
                   ` (3 preceding siblings ...)
  2018-01-10  2:48 ` [spp] [PATCH 4/4] spp_vf: fix bug of status command x-fn-spp
@ 2018-01-10  7:53 ` Yasufumi Ogawa
  2018-01-13 13:38   ` Ferruh Yigit
  2018-01-19  0:30 ` Yasufumi Ogawa
  5 siblings, 1 reply; 11+ messages in thread
From: Yasufumi Ogawa @ 2018-01-10  7:53 UTC (permalink / raw)
  To: x-fn-spp, spp, ferruh.yigit

Hi Hiroyuki, Ferruh,

Thanks Hiroyuki for considering to update. I tried to compile and run it 
without errors or warnings for DPDK 17.11. It seems to work fine.

As Hiroyuki mentioned in previously, there are still remained warnings 
for coding style from checkpatch and we need to fix them as the next 
task. Thank you for your contributions!

Ferruh, could you merge patches from Hiroyuki?

Thanks,
Yasufumi

On 2018/01/10 11:46, x-fn-spp@sl.ntt-tx.co.jp wrote:
> Hi everyone,
> 
> Last year, we've sent some patches for spp_vf on DPDK17.08.
> In addition to these patches, we are now ready to contribute
> the patches for spp_vf on DPDK17.11.
> 
> Code changes will be posted in the following emails.
> 
> 


-- 
Yasufumi Ogawa
NTT Network Service Systems Labs

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [spp] Patches for spp_vf on DPDK17.11
  2018-01-10  7:53 ` [spp] Patches for spp_vf on DPDK17.11 Yasufumi Ogawa
@ 2018-01-13 13:38   ` Ferruh Yigit
  2018-01-15  2:08     ` Yasufumi Ogawa
  0 siblings, 1 reply; 11+ messages in thread
From: Ferruh Yigit @ 2018-01-13 13:38 UTC (permalink / raw)
  To: Yasufumi Ogawa, x-fn-spp, spp

On 1/10/2018 7:53 AM, Yasufumi Ogawa wrote:
> Hi Hiroyuki, Ferruh,
> 
> Thanks Hiroyuki for considering to update. I tried to compile and run it 
> without errors or warnings for DPDK 17.11. It seems to work fine.
> 
> As Hiroyuki mentioned in previously, there are still remained warnings 
> for coding style from checkpatch and we need to fix them as the next 
> task. Thank you for your contributions!
> 
> Ferruh, could you merge patches from Hiroyuki?

Hiroyuki thanks for the patches, and Yasufumi thank you for the review and testing.

Yasufumi,

There are two patchsets, one is this one with 4 patches and other is with 57
patches. And as far as I can this one depends the other one.

Are you OK to getting both of the patchsets?
btw, I will add your ack explicitly to all.

And another question is current head in spp tested on v17.11? Is it safe to tag
it as v17.11?

Thanks,
ferruh

> 
> Thanks,
> Yasufumi
> 
> On 2018/01/10 11:46, x-fn-spp@sl.ntt-tx.co.jp wrote:
>> Hi everyone,
>>
>> Last year, we've sent some patches for spp_vf on DPDK17.08.
>> In addition to these patches, we are now ready to contribute
>> the patches for spp_vf on DPDK17.11.
>>
>> Code changes will be posted in the following emails.
>>
>>
> 
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [spp] Patches for spp_vf on DPDK17.11
  2018-01-13 13:38   ` Ferruh Yigit
@ 2018-01-15  2:08     ` Yasufumi Ogawa
  0 siblings, 0 replies; 11+ messages in thread
From: Yasufumi Ogawa @ 2018-01-15  2:08 UTC (permalink / raw)
  To: Ferruh Yigit, x-fn-spp, spp

Hi Ferruh,

Sorry for ambiguously for my reply. I would like to merge both of series 
including later 4 patches. I will send acked-by for future patches.

 > And another question is current head in spp tested on v17.11? Is it 
safe to tag
 > it as v17.11?
Thank you for your suggestion. I have tested with DPDK 17.11 and we 
should to do tagging. Considering that Hiroyuki is going to send another 
patches for documentation, I would like to send a patch for updating 
Makefile to tag 17.11 soon after him.

Thanks,
Yasufumi

On 2018/01/13 22:38, Ferruh Yigit wrote:
> On 1/10/2018 7:53 AM, Yasufumi Ogawa wrote:
>> Hi Hiroyuki, Ferruh,
>>
>> Thanks Hiroyuki for considering to update. I tried to compile and run it
>> without errors or warnings for DPDK 17.11. It seems to work fine.
>>
>> As Hiroyuki mentioned in previously, there are still remained warnings
>> for coding style from checkpatch and we need to fix them as the next
>> task. Thank you for your contributions!
>>
>> Ferruh, could you merge patches from Hiroyuki?
> 
> Hiroyuki thanks for the patches, and Yasufumi thank you for the review and testing.
> 
> Yasufumi,
> 
> There are two patchsets, one is this one with 4 patches and other is with 57
> patches. And as far as I can this one depends the other one.
> 
> Are you OK to getting both of the patchsets?
> btw, I will add your ack explicitly to all.
> 
> And another question is current head in spp tested on v17.11? Is it safe to tag
> it as v17.11?
> 
> Thanks,
> ferruh
> 
>>
>> Thanks,
>> Yasufumi
>>
>> On 2018/01/10 11:46, x-fn-spp@sl.ntt-tx.co.jp wrote:
>>> Hi everyone,
>>>
>>> Last year, we've sent some patches for spp_vf on DPDK17.08.
>>> In addition to these patches, we are now ready to contribute
>>> the patches for spp_vf on DPDK17.11.
>>>
>>> Code changes will be posted in the following emails.
>>>
>>>
>>
>>
> 
> 
> 


-- 
Yasufumi Ogawa
NTT Network Service Systems Labs

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [spp] Patches for spp_vf on DPDK17.11
  2018-01-10  2:46 [spp] Patches for spp_vf on DPDK17.11 x-fn-spp
                   ` (4 preceding siblings ...)
  2018-01-10  7:53 ` [spp] Patches for spp_vf on DPDK17.11 Yasufumi Ogawa
@ 2018-01-19  0:30 ` Yasufumi Ogawa
  2018-01-22 14:04   ` Ferruh Yigit
  5 siblings, 1 reply; 11+ messages in thread
From: Yasufumi Ogawa @ 2018-01-19  0:30 UTC (permalink / raw)
  To: spp

On 2018/01/10 11:46, x-fn-spp@sl.ntt-tx.co.jp wrote:
> Hi everyone,
> 
> Last year, we've sent some patches for spp_vf on DPDK17.08.
> In addition to these patches, we are now ready to contribute
> the patches for spp_vf on DPDK17.11.
> 
> Code changes will be posted in the following emails.
> 
> 

Series of patches acked. Thanks

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

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [spp] [PATCH 1/4] spp_vf: fix to eliminate jansson package
  2018-01-10  2:47 ` [spp] [PATCH 1/4] spp_vf: fix to eliminate jansson package x-fn-spp
@ 2018-01-19  0:37   ` Yasufumi Ogawa
  0 siblings, 0 replies; 11+ messages in thread
From: Yasufumi Ogawa @ 2018-01-19  0:37 UTC (permalink / raw)
  To: x-fn-spp, spp, ferruh.yigit

Hi Ferruh,

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

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

Thanks,
Yasufumi


On 2018/01/10 11:47, x-fn-spp@sl.ntt-tx.co.jp wrote:
> From: Hiroyuki Nakamura <nakamura.hioryuki@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@as.ntt-tx.co.jp>
> Signed-off-by: Yasufum Ogawa <ogawa.yasufumi@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

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [spp] Patches for spp_vf on DPDK17.11
  2018-01-19  0:30 ` Yasufumi Ogawa
@ 2018-01-22 14:04   ` Ferruh Yigit
  0 siblings, 0 replies; 11+ messages in thread
From: Ferruh Yigit @ 2018-01-22 14:04 UTC (permalink / raw)
  To: Yasufumi Ogawa, spp

On 1/19/2018 12:30 AM, Yasufumi Ogawa wrote:
> On 2018/01/10 11:46, x-fn-spp@sl.ntt-tx.co.jp wrote:
>> Hi everyone,
>>
>> Last year, we've sent some patches for spp_vf on DPDK17.08.
>> In addition to these patches, we are now ready to contribute
>> the patches for spp_vf on DPDK17.11.
>>
>> Code changes will be posted in the following emails.
>>
>>
> 
> Series of patches acked. Thanks
> 
> Acked-by: Yasufumi Ogawa <ogawa.yasufumi@lab.ntt.co.jp>

Series applied.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2018-01-22 14:04 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-10  2:46 [spp] Patches for spp_vf on DPDK17.11 x-fn-spp
2018-01-10  2:47 ` [spp] [PATCH 1/4] spp_vf: fix to eliminate jansson package x-fn-spp
2018-01-19  0:37   ` Yasufumi Ogawa
2018-01-10  2:47 ` [spp] [PATCH 2/4] spp_vf: support cancel command x-fn-spp
2018-01-10  2:48 ` [spp] [PATCH 3/4] spp_vf: change type of port_id to uint16_t x-fn-spp
2018-01-10  2:48 ` [spp] [PATCH 4/4] spp_vf: fix bug of status command x-fn-spp
2018-01-10  7:53 ` [spp] Patches for spp_vf on DPDK17.11 Yasufumi Ogawa
2018-01-13 13:38   ` Ferruh Yigit
2018-01-15  2:08     ` Yasufumi Ogawa
2018-01-19  0:30 ` Yasufumi Ogawa
2018-01-22 14:04   ` Ferruh Yigit

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).