new file mode 100644
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Marvell.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <cmdline_parse.h>
+#include <cmdline_parse_num.h>
+#include <cmdline_parse_string.h>
+#include <cmdline_socket.h>
+#include <rte_common.h>
+
+#include "module_api.h"
+
+#define CMD_MAX_TOKENS 256
+#define MAX_LINE_SIZE 2048
+
+cmdline_parse_ctx_t modules_ctx[] = {
+ NULL,
+};
+
+static struct cmdline *cl;
+
+static int
+is_comment(char *in)
+{
+ if ((strlen(in) && index("!#%;", in[0])) ||
+ (strncmp(in, "//", 2) == 0) ||
+ (strncmp(in, "--", 2) == 0))
+ return 1;
+
+ return 0;
+}
+
+void
+cli_init(void)
+{
+ cl = cmdline_stdin_new(modules_ctx, "");
+}
+
+void
+cli_exit(void)
+{
+ cmdline_stdin_exit(cl);
+}
+
+void
+cli_process(char *in, char *out, size_t out_size, __rte_unused void *obj)
+{
+ int rc;
+
+ if (is_comment(in))
+ return;
+
+ rc = cmdline_parse(cl, in);
+ if (rc == CMDLINE_PARSE_AMBIGUOUS)
+ snprintf(out, out_size, MSG_CMD_FAIL, "Ambiguous command");
+ else if (rc == CMDLINE_PARSE_NOMATCH)
+ snprintf(out, out_size, MSG_CMD_FAIL, "Command mismatch");
+ else if (rc == CMDLINE_PARSE_BAD_ARGS)
+ snprintf(out, out_size, MSG_CMD_FAIL, "Bad arguments");
+
+ return;
+
+}
+
+int
+cli_script_process(const char *file_name, size_t msg_in_len_max, size_t msg_out_len_max, void *obj)
+{
+ char *msg_in = NULL, *msg_out = NULL;
+ FILE *f = NULL;
+
+ /* Check input arguments */
+ if ((file_name == NULL) || (strlen(file_name) == 0) || (msg_in_len_max == 0) ||
+ (msg_out_len_max == 0))
+ return -EINVAL;
+
+ msg_in = malloc(msg_in_len_max + 1);
+ msg_out = malloc(msg_out_len_max + 1);
+ if ((msg_in == NULL) || (msg_out == NULL)) {
+ free(msg_out);
+ free(msg_in);
+ return -ENOMEM;
+ }
+
+ /* Open input file */
+ f = fopen(file_name, "r");
+ if (f == NULL) {
+ free(msg_out);
+ free(msg_in);
+ return -EIO;
+ }
+
+ /* Read file */
+ while (fgets(msg_in, msg_in_len_max, f) != NULL) {
+ msg_out[0] = 0;
+
+ cli_process(msg_in, msg_out, msg_out_len_max, obj);
+
+ if (strlen(msg_out))
+ printf("%s", msg_out);
+ }
+
+ /* Close file */
+ fclose(f);
+ free(msg_out);
+ free(msg_in);
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Marvell.
+ */
+
+#ifndef APP_GRAPH_CLI_H
+#define APP_GRAPH_CLI_H
+
+/* Macros */
+#define MSG_OUT_OF_MEMORY "Not enough memory.\n"
+#define MSG_CMD_UNKNOWN "Unknown command \"%s\".\n"
+#define MSG_CMD_UNIMPLEM "Command \"%s\" not implemented.\n"
+#define MSG_ARG_NOT_ENOUGH "Not enough arguments for command \"%s\".\n"
+#define MSG_ARG_TOO_MANY "Too many arguments for command \"%s\".\n"
+#define MSG_ARG_MISMATCH "Wrong number of arguments for command \"%s\".\n"
+#define MSG_ARG_NOT_FOUND "Argument \"%s\" not found.\n"
+#define MSG_ARG_INVALID "Invalid value for argument \"%s\".\n"
+#define MSG_FILE_ERR "Error in file \"%s\" at line %u.\n"
+#define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
+#define MSG_CMD_FAIL "Command \"%s\" failed.\n"
+
+#define APP_CLI_CMD_NAME_SIZE 64
+
+void cli_init(void);
+
+void cli_exit(void);
+
+void cli_process(char *in, char *out, size_t out_size, void *arg);
+
+int cli_script_process(const char *file_name, size_t msg_in_len_max, size_t msg_out_len_max,
+ void *arg);
+
+#endif
new file mode 100644
@@ -0,0 +1,127 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Marvell.
+ */
+
+#include <fcntl.h>
+#include <getopt.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <rte_eal.h>
+#include <rte_launch.h>
+
+#include "module_api.h"
+
+volatile bool force_quit;
+
+static const char usage[] = "%s EAL_ARGS -- -s SCRIPT "
+ "[--help]\n";
+
+static struct app_params {
+ char *script_name;
+} app = {
+ .script_name = NULL,
+};
+
+static void
+signal_handler(int signum)
+{
+ if (signum == SIGINT || signum == SIGTERM) {
+ printf("\n\nSignal %d received, preparing to exit...\n", signum);
+ force_quit = true;
+ }
+}
+
+static int
+app_args_parse(int argc, char **argv)
+{
+ struct option lgopts[] = {
+ {"help", 0, 0, 'H'},
+ };
+ int s_present, n_args, i;
+ char *app_name = argv[0];
+ int opt, option_index;
+
+ /* Skip EAL input args */
+ n_args = argc;
+ for (i = 0; i < n_args; i++)
+ if (strcmp(argv[i], "--") == 0) {
+ argc -= i;
+ argv += i;
+ break;
+ }
+
+ if (i == n_args)
+ return 0;
+
+ /* Parse args */
+ s_present = 0;
+
+ while ((opt = getopt_long(argc, argv, "s:", lgopts, &option_index)) != EOF) {
+ switch (opt) {
+ case 's':
+ if (s_present) {
+ printf("Error: Multiple -s arguments\n");
+ return -1;
+ }
+ s_present = 1;
+
+ if (!strlen(optarg)) {
+ printf("Error: Argument for -s not provided\n");
+ return -1;
+ }
+
+ app.script_name = strdup(optarg);
+ if (app.script_name == NULL) {
+ printf("Error: Not enough memory\n");
+ return -1;
+ }
+ break;
+
+ case 'H':
+ default:
+ printf(usage, app_name);
+ return -1;
+ }
+ }
+ optind = 1; /* reset getopt lib */
+
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ int rc;
+
+ /* Parse application arguments */
+ rc = app_args_parse(argc, argv);
+ if (rc < 0)
+ return rc;
+
+ /* EAL */
+ rc = rte_eal_init(argc, argv);
+ if (rc < 0) {
+ printf("Error: EAL initialization failed (%d)\n", rc);
+ return rc;
+ };
+
+ force_quit = false;
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
+
+ cli_init();
+
+ /* Script */
+ if (app.script_name) {
+ cli_script_process(app.script_name, 0,
+ 0, NULL);
+ }
+
+ cli_exit();
+ rte_eal_cleanup();
+ return 0;
+}
\ No newline at end of file
new file mode 100644
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2023 Marvell.
+
+# override default name to drop the hyphen
+name = 'graph'
+if not build
+ subdir_done()
+endif
+
+deps += ['bus_pci', 'graph', 'eal', 'lpm', 'ethdev', 'node', 'cmdline']
+sources = files(
+ 'cli.c',
+ 'main.c',
+)
new file mode 100644
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Marvell.
+ */
+
+#ifndef APP_GRAPH_MODULE_API_H
+#define APP_GRAPH_MODULE_API_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "cli.h"
+/*
+ * Externs
+ */
+extern volatile bool force_quit;
+
+#endif
@@ -17,6 +17,7 @@ endif
apps = [
'dumpcap',
'pdump',
+ 'graph',
'proc-info',
'test-acl',
'test-bbdev',