[dpdk-dev] [PATCH v5 3/3] app/testpmd: add parse options from JSON cfg file

Kuba Kozak kubax.kozak at intel.com
Thu Jul 13 12:07:50 CEST 2017


This patch shows usage of Jansson library to parse
application arguments from JSON config file.

https://github.com/akheron/jansson

If a --cfgfile-path <path> option is passed into commandline
non EAL section, then the disired JSON file is loaded and used
by app. In case when JSON doesn't exist an INI file is loaded.
The INI file can be passed also from --cfgfile-path option.

If a file called config.ini is present in current working
directory, and no --cfgfile-path option is passed in, config.ini
file will be loaded and used by app.

Signed-off-by: Kuba Kozak <kubax.kozak at intel.com>
Suggested-by: Bruce Richardson <bruce.richardson at intel.com>
---
 app/test-pmd/Makefile    |  6 ++++
 app/test-pmd/config.json | 33 +++++++++++++++++
 app/test-pmd/testpmd.c   | 94 +++++++++++++++++++++++++++++++++++++++++++++++-
 config/common_base       |  5 +++
 4 files changed, 137 insertions(+), 1 deletion(-)
 create mode 100644 app/test-pmd/config.json

diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
index c36be19..a1c84cc 100644
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -83,6 +83,12 @@ endif
 
 endif
 
+ifeq ($(CONFIG_RTE_JSON_SUPPORT),y)
+ifeq ($(CONFIG_RTE_LIBRTE_CFGFILE),y)
+LDLIBS += -ljansson
+endif
+endif
+
 CFLAGS_cmdline.o := -D_GNU_SOURCE
 
 include $(RTE_SDK)/mk/rte.app.mk
diff --git a/app/test-pmd/config.json b/app/test-pmd/config.json
new file mode 100644
index 0000000..4589dbc
--- /dev/null
+++ b/app/test-pmd/config.json
@@ -0,0 +1,33 @@
+{
+	"DPDK":
+	{
+		"v": "",
+		"l": "0-4",
+		"n": "4",
+		"master-lcore": "0",
+		"proc-type": "primary"
+	},
+	"TEST-PMD":
+	{
+		"i": "",
+		"portmask": "0xff",
+		"nb-cores": "4",
+		"port-topology": "paired"
+	},
+	"DPDK.vdev0":
+	{
+		"net_ring0": ""
+	},
+	"DPDK.vdev1":
+	{
+		"net_ring1": ""
+	},
+	"DPDK.vdev2":
+	{
+		"net_ring2": ""
+	},
+	"DPDK.vdev3":
+	{
+		"net_ring3": ""
+	}
+}
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 7b82976..014bb46 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -46,6 +46,10 @@
 
 #include <stdint.h>
 #include <unistd.h>
+
+#ifdef RTE_JSON_SUPPORT
+#include <jansson.h>
+#endif
 #include <inttypes.h>
 
 #include <rte_common.h>
@@ -2290,6 +2294,87 @@ cfgfile_load_path(int argc, char **argv)
 	}
 	return NULL;
 }
+
+#ifdef RTE_JSON_SUPPORT
+/*
+ * Decoding JSON structure to rte_cfgfile structure.
+ * Returns handler to cfgfile object, NULL if error.
+ */
+static struct
+rte_cfgfile *l3fwd_json_to_cfg(json_t *json, int flags)
+{
+	if (!json) {
+		printf("Error: JSON structure is NULL, nothing to parse\n");
+		return NULL;
+	}
+	/* create an empty instance of cfgfile structure */
+	struct rte_cfgfile *cfgfile = rte_cfgfile_create(flags);
+
+	if (!cfgfile)
+		return NULL;
+
+	const char *section;
+	json_t *entry;
+
+	/* set pointer to first section */
+	void *iter_section = json_object_iter(json);
+
+	while (iter_section) {
+
+		section = json_object_iter_key(iter_section);
+		entry = json_object_iter_value(iter_section);
+
+		/* add parsed section name of current section to cfgfile */
+		rte_cfgfile_add_section(cfgfile, section);
+
+		/* set pointer to first entry */
+		void *iter_entry = json_object_iter(entry);
+
+		while (iter_entry) {
+
+			const char *key;
+			const char *value;
+
+			key = json_object_iter_key(iter_entry);
+			value = json_string_value(
+					json_object_iter_value(iter_entry));
+
+			/* add parsed key and value of current entry */
+			/* to cfgfile */
+			rte_cfgfile_add_entry(cfgfile, section, key, value);
+
+			/* pointer to next entry */
+			iter_entry = json_object_iter_next(entry, iter_entry);
+		}
+		/* pointer to next section */
+		iter_section = json_object_iter_next(json, iter_section);
+	}
+	return cfgfile;
+}
+
+/*
+ * Check presence and load JSON file to rte_cfgfile structure.
+ * Returns handler to cfgfile object, NULL if error.
+ */
+static struct
+rte_cfgfile *l3fwd_load_json_to_cfg(const char *path)
+{
+	struct rte_cfgfile *cfgfile = NULL;
+	/* check if config file exist */
+	if (access(path, F_OK) != -1) {
+		/* parse JSON file */
+		json_error_t error;
+		json_t *json = json_load_file(path, 0, &error);
+
+		if (json)
+			cfgfile = l3fwd_json_to_cfg(json, 0);
+		else
+			fprintf(stderr, "JSON error on line %d: %s\n",
+							error.line, error.text);
+	}
+	return cfgfile;
+}
+#endif
 #endif
 
 #define APP_NAME "TEST-PMD"
@@ -2318,9 +2403,16 @@ main(int argc, char** argv)
 				"in default directory)\n");
 		config_file = strdup("config.ini");
 	}
-
+#ifndef RTE_JSON_SUPPORT
 	cfg = rte_cfgfile_load(config_file, CFG_FLAG_EMPTY_VALUES);
+#endif
 
+#ifdef RTE_JSON_SUPPORT
+	if (strstr(config_file, ".ini"))
+		cfg = rte_cfgfile_load(config_file, CFG_FLAG_EMPTY_VALUES);
+	else if (strstr(config_file, ".json"))
+		cfg = l3fwd_load_json_to_cfg(config_file);
+#endif
 	if (cfg == NULL) {
 		printf("Info: Valid cfgfile not found\n");
 	} else {
diff --git a/config/common_base b/config/common_base
index 8ae6e92..98e8fa2 100644
--- a/config/common_base
+++ b/config/common_base
@@ -744,3 +744,8 @@ CONFIG_RTE_APP_CRYPTO_PERF=y
 # Compile the eventdev application
 #
 CONFIG_RTE_APP_EVENTDEV=y
+
+#
+# Compile JSON support
+#
+CONFIG_RTE_JSON_SUPPORT=n
\ No newline at end of file
-- 
2.7.4



More information about the dev mailing list