aboutsummaryrefslogtreecommitdiff
path: root/helper
diff options
context:
space:
mode:
authorMatias Elo <matias.elo@nokia.com>2021-07-02 14:29:59 +0300
committerMatias Elo <matias.elo@nokia.com>2021-07-02 14:29:59 +0300
commit21689a2b95763d5c3b64b835419ddda220322fc0 (patch)
tree4181f63a3923a4c5b62feb330a5cdfd54c0cf198 /helper
parent3a7a24023021f5959dd2f00fe83cf2635bf25c2d (diff)
parentcb9c89bdd732640915cb04a4775f0e866c932de2 (diff)
Merge tag 'v1.30.0.0' of https://github.com/OpenDataPlane/odp into odp-dpdk
Signed-off-by: Matias Elo <matias.elo@nokia.com>
Diffstat (limited to 'helper')
-rw-r--r--helper/cli.c409
-rw-r--r--helper/include/odp/helper/cli.h86
-rw-r--r--helper/ipsec.c4
-rw-r--r--helper/test/cli.c12
4 files changed, 407 insertions, 104 deletions
diff --git a/helper/cli.c b/helper/cli.c
index dd4b5fe4f..ebc5b01e1 100644
--- a/helper/cli.c
+++ b/helper/cli.c
@@ -16,6 +16,7 @@
#include <errno.h>
#include <poll.h>
#include <stdio.h>
+#include <strings.h>
/* Socketpair socket roles. */
enum {
@@ -23,6 +24,15 @@ enum {
SP_WRITE = 1,
};
+#define MAX_NAME_LEN 20
+#define MAX_HELP_LEN 100
+
+typedef struct {
+ odph_cli_user_cmd_func_t fn;
+ char name[MAX_NAME_LEN];
+ char help[MAX_HELP_LEN];
+} user_cmd_t;
+
typedef struct {
volatile int cli_fd;
/* Server thread will exit if this is false. */
@@ -30,9 +40,15 @@ typedef struct {
/* Socketpair descriptors. */
int sp[2];
int listen_fd;
- /* This lock guards cli_fd and run, which must be accessed atomically. */
+ /* Guards cli_fd and run, which must be accessed atomically. */
odp_spinlock_t lock;
+ odp_spinlock_t api_lock;
odph_thread_t thr_server;
+ odp_instance_t instance;
+ struct sockaddr_in addr;
+ uint32_t max_user_commands;
+ uint32_t num_user_commands;
+ user_cmd_t user_cmd[0];
} cli_shm_t;
static const char *shm_name = "_odp_cli";
@@ -40,6 +56,7 @@ static const char *shm_name = "_odp_cli";
static const odph_cli_param_t param_default = {
.address = "127.0.0.1",
.port = 55555,
+ .max_user_commands = 50,
};
void odph_cli_param_init(odph_cli_param_t *param)
@@ -47,28 +64,114 @@ void odph_cli_param_init(odph_cli_param_t *param)
*param = param_default;
}
-static int cmd_show_cpu(struct cli_def *cli, const char *command ODP_UNUSED,
- char *argv[] ODP_UNUSED, int argc ODP_UNUSED)
+static cli_shm_t *shm_lookup(void)
+{
+ cli_shm_t *shm = NULL;
+ odp_shm_t shm_hdl = odp_shm_lookup(shm_name);
+
+ if (shm_hdl != ODP_SHM_INVALID)
+ shm = (cli_shm_t *)odp_shm_addr(shm_hdl);
+
+ return shm;
+}
+
+int odph_cli_init(odp_instance_t instance, const odph_cli_param_t *param)
{
- for (int c = 0; c < odp_cpu_count(); c++) {
- cli_print(cli, "% 4d: %s %.03f / %.03f GHz", c,
- odp_cpu_model_str_id(c),
- (float)odp_cpu_hz_id(c) / 1000000000.0,
- (float)odp_cpu_hz_max_id(c) / 1000000000.0);
+ if (odp_shm_lookup(shm_name) != ODP_SHM_INVALID) {
+ ODPH_ERR("Error: shm %s already exists\n", shm_name);
+ return -1;
}
- return CLI_OK;
+ cli_shm_t *shm = NULL;
+ int shm_size = sizeof(cli_shm_t) +
+ param->max_user_commands * sizeof(user_cmd_t);
+ odp_shm_t shm_hdl =
+ odp_shm_reserve(shm_name, shm_size, 64, ODP_SHM_SW_ONLY);
+
+ if (shm_hdl != ODP_SHM_INVALID)
+ shm = (cli_shm_t *)odp_shm_addr(shm_hdl);
+
+ if (!shm) {
+ ODPH_ERR("Error: failed to reserve shm %s\n", shm_name);
+ return -1;
+ }
+
+ memset(shm, 0, shm_size);
+ odp_spinlock_init(&shm->lock);
+ odp_spinlock_init(&shm->api_lock);
+ shm->sp[SP_READ] = -1;
+ shm->sp[SP_WRITE] = -1;
+ shm->listen_fd = -1;
+ shm->cli_fd = -1;
+ shm->instance = instance;
+
+ shm->addr.sin_family = AF_INET;
+ shm->addr.sin_port = htons(param->port);
+
+ switch (inet_pton(AF_INET, param->address, &shm->addr.sin_addr)) {
+ case -1:
+ ODPH_ERR("Error: inet_pton(): %s\n", strerror(errno));
+ return -1;
+ case 0:
+ ODPH_ERR("Error: inet_pton(): illegal address format\n");
+ return -1;
+ default:
+ break;
+ }
+
+ shm->max_user_commands = param->max_user_commands;
+
+ return 0;
}
-static int cmd_show_version(struct cli_def *cli, const char *command ODP_UNUSED,
- char *argv[] ODP_UNUSED, int argc ODP_UNUSED)
+int odph_cli_register_command(const char *name, odph_cli_user_cmd_func_t func,
+ const char *help)
{
- cli_print(cli, "ODP API version: %s", odp_version_api_str());
- cli_print(cli, "ODP implementation name: %s", odp_version_impl_name());
- cli_print(cli, "ODP implementation version: %s",
- odp_version_impl_str());
+ cli_shm_t *shm = shm_lookup();
- return CLI_OK;
+ if (!shm) {
+ ODPH_ERR("Error: shm %s not found\n", shm_name);
+ return -1;
+ }
+
+ odp_spinlock_lock(&shm->api_lock);
+
+ odp_spinlock_lock(&shm->lock);
+ if (shm->run) {
+ odp_spinlock_unlock(&shm->lock);
+ ODPH_ERR("Error: cannot register commands while cli server is running\n");
+ goto error;
+ }
+ odp_spinlock_unlock(&shm->lock);
+
+ if (shm->num_user_commands >= shm->max_user_commands) {
+ ODPH_ERR("Error: maximum number of user commands already registered\n");
+ goto error;
+ }
+
+ user_cmd_t *cmd = &shm->user_cmd[shm->num_user_commands];
+
+ cmd->fn = func;
+
+ if (strlen(name) >= MAX_NAME_LEN - 1) {
+ ODPH_ERR("Error: command name too long\n");
+ goto error;
+ }
+ strcpy(cmd->name, name);
+
+ if (strlen(help) >= MAX_HELP_LEN - 1) {
+ ODPH_ERR("Error: command help too long\n");
+ goto error;
+ }
+ strcpy(cmd->help, help);
+
+ shm->num_user_commands++;
+ odp_spinlock_unlock(&shm->api_lock);
+ return 0;
+
+error:
+ odp_spinlock_unlock(&shm->api_lock);
+ return -1;
}
/*
@@ -91,6 +194,18 @@ static int check_num_args(struct cli_def *cli, int argc, int req_argc)
return 0;
}
+static int cmd_call_odp_cls_print_all(struct cli_def *cli,
+ const char *command ODP_UNUSED,
+ char *argv[] ODP_UNUSED, int argc)
+{
+ if (check_num_args(cli, argc, 0))
+ return CLI_ERROR;
+
+ odp_cls_print_all();
+
+ return CLI_OK;
+}
+
static int cmd_call_odp_ipsec_print(struct cli_def *cli,
const char *command ODP_UNUSED,
char *argv[] ODP_UNUSED, int argc)
@@ -196,6 +311,18 @@ static int cmd_call_odp_queue_print(struct cli_def *cli,
return CLI_OK;
}
+static int cmd_call_odp_queue_print_all(struct cli_def *cli,
+ const char *command ODP_UNUSED,
+ char *argv[] ODP_UNUSED, int argc)
+{
+ if (check_num_args(cli, argc, 0))
+ return CLI_ERROR;
+
+ odp_queue_print_all();
+
+ return CLI_OK;
+}
+
static int cmd_call_odp_shm_print(struct cli_def *cli,
const char *command ODP_UNUSED, char *argv[],
int argc)
@@ -215,7 +342,27 @@ static int cmd_call_odp_shm_print(struct cli_def *cli,
return CLI_OK;
}
-static struct cli_def *create_cli(void)
+static int cmd_user_cmd(struct cli_def *cli ODP_UNUSED, const char *command,
+ char *argv[], int argc)
+{
+ cli_shm_t *shm = shm_lookup();
+
+ if (!shm) {
+ ODPH_ERR("Error: shm %s not found\n", shm_name);
+ return CLI_ERROR;
+ }
+
+ for (uint32_t i = 0; i < shm->num_user_commands; i++) {
+ if (!strcasecmp(command, shm->user_cmd[i].name)) {
+ shm->user_cmd[i].fn(argc, argv);
+ break;
+ }
+ }
+
+ return CLI_OK;
+}
+
+static struct cli_def *create_cli(cli_shm_t *shm)
{
struct cli_command *c;
struct cli_def *cli;
@@ -224,19 +371,12 @@ static struct cli_def *create_cli(void)
cli_set_banner(cli, NULL);
cli_set_hostname(cli, "ODP");
- c = cli_register_command(cli, NULL, "show", NULL,
- PRIVILEGE_UNPRIVILEGED, MODE_EXEC,
- "Show information.");
- cli_register_command(cli, c, "cpu", cmd_show_cpu,
- PRIVILEGE_UNPRIVILEGED, MODE_EXEC,
- "Show CPU information.");
- cli_register_command(cli, c, "version", cmd_show_version,
- PRIVILEGE_UNPRIVILEGED, MODE_EXEC,
- "Show version information.");
-
c = cli_register_command(cli, NULL, "call", NULL,
PRIVILEGE_UNPRIVILEGED, MODE_EXEC,
"Call ODP API function.");
+ cli_register_command(cli, c, "odp_cls_print_all",
+ cmd_call_odp_cls_print_all,
+ PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL);
cli_register_command(cli, c, "odp_ipsec_print",
cmd_call_odp_ipsec_print,
PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL);
@@ -249,6 +389,9 @@ static struct cli_def *create_cli(void)
cli_register_command(cli, c, "odp_queue_print",
cmd_call_odp_queue_print,
PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "<name>");
+ cli_register_command(cli, c, "odp_queue_print_all",
+ cmd_call_odp_queue_print_all,
+ PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL);
cli_register_command(cli, c, "odp_shm_print_all",
cmd_call_odp_shm_print_all,
PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL);
@@ -262,6 +405,12 @@ static struct cli_def *create_cli(void)
cmd_call_odp_sys_info_print,
PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL);
+ for (uint32_t i = 0; i < shm->num_user_commands; i++) {
+ cli_register_command(cli, NULL, shm->user_cmd[i].name,
+ cmd_user_cmd, PRIVILEGE_UNPRIVILEGED,
+ MODE_EXEC, shm->user_cmd[i].help);
+ }
+
return cli;
}
@@ -269,8 +418,8 @@ static struct cli_def *create_cli(void)
static struct cli_def *cli;
static char *cli_log_fn_buf;
-ODP_PRINTF_FORMAT(2, 3)
-static int cli_log_fn(odp_log_level_t level, const char *fmt, ...)
+ODP_PRINTF_FORMAT(2, 0)
+static int cli_log_va(odp_log_level_t level, const char *fmt, va_list in_args)
{
(void)level;
@@ -289,17 +438,17 @@ static int cli_log_fn(odp_log_level_t level, const char *fmt, ...)
* If the string does not end in a newline, we keep the part of the
* string after the last newline and use it the next time we're called.
*/
- va_start(args, fmt);
+ va_copy(args, in_args);
len = vsnprintf(NULL, 0, fmt, args) + 1;
va_end(args);
str = malloc(len);
if (!str) {
- ODPH_ERR("malloc failed");
- return 0;
+ ODPH_ERR("malloc failed\n");
+ return -1;
}
- va_start(args, fmt);
+ va_copy(args, in_args);
vsnprintf(str, len, fmt, args);
va_end(args);
p = str;
@@ -323,7 +472,7 @@ static int cli_log_fn(odp_log_level_t level, const char *fmt, ...)
malloc(strlen(cli_log_fn_buf) + strlen(p) + 1);
if (!buffer_new) {
- ODPH_ERR("malloc failed");
+ ODPH_ERR("malloc failed\n");
goto out;
}
@@ -335,7 +484,7 @@ static int cli_log_fn(odp_log_level_t level, const char *fmt, ...)
cli_log_fn_buf = malloc(strlen(p) + 1);
if (!cli_log_fn_buf) {
- ODPH_ERR("malloc failed");
+ ODPH_ERR("malloc failed\n");
goto out;
}
@@ -346,23 +495,47 @@ static int cli_log_fn(odp_log_level_t level, const char *fmt, ...)
out:
free(str);
- return 0;
+ return len;
}
-static int cli_server(void *arg ODP_UNUSED)
+ODP_PRINTF_FORMAT(2, 3)
+static int cli_log(odp_log_level_t level, const char *fmt, ...)
{
- cli_shm_t *shm = NULL;
- odp_shm_t shm_hdl = odp_shm_lookup(shm_name);
+ (void)level;
- if (shm_hdl != ODP_SHM_INVALID)
- shm = (cli_shm_t *)odp_shm_addr(shm_hdl);
+ int r;
+ va_list args;
+
+ va_start(args, fmt);
+ r = cli_log_va(level, fmt, args);
+ va_end(args);
+
+ return r;
+}
+
+ODP_PRINTF_FORMAT(1, 2)
+int odph_cli_log(const char *fmt, ...)
+{
+ int r;
+ va_list args;
+
+ va_start(args, fmt);
+ r = cli_log_va(ODP_LOG_PRINT, fmt, args);
+ va_end(args);
+
+ return r;
+}
+
+static int cli_server(void *arg ODP_UNUSED)
+{
+ cli_shm_t *shm = shm_lookup();
if (!shm) {
- ODPH_ERR("Error: can't start cli server (shm %s not found)\n", shm_name);
+ ODPH_ERR("Error: shm %s not found\n", shm_name);
return -1;
}
- cli = create_cli();
+ cli = create_cli(shm);
while (1) {
struct pollfd pfd[2] = {
@@ -399,26 +572,55 @@ static int cli_server(void *arg ODP_UNUSED)
break;
}
+ /*
+ * The only way to stop cli_loop() is to close the socket, after
+ * which cli_loop() gets an error on the next select() and then
+ * calls close() before returning. This is a problem because the
+ * fd may be reused before the select() or the final close().
+ *
+ * To avoid this problem, switch to a higher fd number
+ * (select() maximum). We will still run into problems if the
+ * descriptor numbers in the process reach FD_SETSIZE - 1 =
+ * 1023.
+ */
+ int newfd = dup2(fd, FD_SETSIZE - 1);
+
+ if (newfd < 0) {
+ ODPH_ERR("Error: dup2(): %s\n", strerror(errno));
+ close(fd);
+ continue;
+ }
+
+ close(fd);
+ fd = newfd;
+
odp_spinlock_lock(&shm->lock);
if (!shm->run) {
+ odp_spinlock_unlock(&shm->lock);
/*
* odph_cli_stop() has been called. Close the
* socket we just accepted and exit.
*/
close(fd);
- odp_spinlock_unlock(&shm->lock);
break;
}
shm->cli_fd = fd;
odp_spinlock_unlock(&shm->lock);
- odp_log_thread_fn_set(cli_log_fn);
+
+ odp_log_thread_fn_set(cli_log);
/*
* cli_loop() returns only when client is disconnected. One
* possible reason for disconnect is odph_cli_stop().
*/
cli_loop(cli, shm->cli_fd);
odp_log_thread_fn_set(NULL);
- close(shm->cli_fd);
+
+ odp_spinlock_lock(&shm->lock);
+ /*
+ * cli_loop() closes the socket before returning (undocumented).
+ */
+ shm->cli_fd = -1;
+ odp_spinlock_unlock(&shm->lock);
/*
* Throw away anything left in the buffer (in case the last
@@ -433,32 +635,30 @@ static int cli_server(void *arg ODP_UNUSED)
return 0;
}
-int odph_cli_start(const odp_instance_t instance,
- const odph_cli_param_t *param_in)
+int odph_cli_start(void)
{
- if (odp_shm_lookup(shm_name) != ODP_SHM_INVALID) {
- ODPH_ERR("Error: cli server already running (shm %s exists)\n", shm_name);
+ cli_shm_t *shm = shm_lookup();
+
+ if (!shm) {
+ ODPH_ERR("Error: shm %s not found\n", shm_name);
return -1;
}
- cli_shm_t *shm = NULL;
- odp_shm_t shm_hdl = odp_shm_reserve(shm_name, sizeof(cli_shm_t), 64,
- ODP_SHM_SW_ONLY);
-
- if (shm_hdl != ODP_SHM_INVALID)
- shm = (cli_shm_t *)odp_shm_addr(shm_hdl);
-
- if (!shm) {
- ODPH_ERR("Error: failed to reserve shm %s\n", shm_name);
+ odp_spinlock_lock(&shm->api_lock);
+ odp_spinlock_lock(&shm->lock);
+ if (shm->run) {
+ odp_spinlock_unlock(&shm->lock);
+ odp_spinlock_unlock(&shm->api_lock);
+ ODPH_ERR("Error: cli server has already been started\n");
return -1;
}
+ shm->run = 1;
+ shm->cli_fd = -1;
+ odp_spinlock_unlock(&shm->lock);
- memset(shm, 0, sizeof(cli_shm_t));
- odp_spinlock_init(&shm->lock);
- shm->sp[SP_READ] = shm->sp[SP_WRITE] = -1;
+ shm->sp[SP_READ] = -1;
+ shm->sp[SP_WRITE] = -1;
shm->listen_fd = -1;
- shm->cli_fd = -1;
- shm->run = 1;
if (socketpair(PF_LOCAL, SOCK_STREAM, 0, shm->sp)) {
ODPH_ERR("Error: socketpair(): %s\n", strerror(errno));
@@ -480,21 +680,8 @@ int odph_cli_start(const odp_instance_t instance,
goto error;
}
- struct sockaddr_in addr;
-
- addr.sin_family = AF_INET;
- addr.sin_port = htons(param_in->port);
-
- switch (inet_pton(AF_INET, param_in->address, &addr.sin_addr)) {
- case -1:
- ODPH_ERR("Error: inet_pton(): %s\n", strerror(errno));
- goto error;
- case 0:
- ODPH_ERR("Error: inet_pton(): illegal address format\n");
- goto error;
- }
-
- if (bind(shm->listen_fd, (struct sockaddr *)&addr, sizeof(addr))) {
+ if (bind(shm->listen_fd, (struct sockaddr *)&shm->addr,
+ sizeof(shm->addr))) {
ODPH_ERR("Error: bind(): %s\n", strerror(errno));
goto error;
}
@@ -516,7 +703,7 @@ int odph_cli_start(const odp_instance_t instance,
}
memset(&thr_common, 0, sizeof(thr_common));
- thr_common.instance = instance;
+ thr_common.instance = shm->instance;
thr_common.cpumask = &cpumask;
memset(&thr_param, 0, sizeof(thr_param));
@@ -530,36 +717,50 @@ int odph_cli_start(const odp_instance_t instance,
goto error;
}
+ odp_spinlock_unlock(&shm->api_lock);
return 0;
error:
- close(shm->sp[SP_READ]);
- close(shm->sp[SP_WRITE]);
- close(shm->listen_fd);
- close(shm->cli_fd);
shm->run = 0;
+ if (shm->sp[SP_READ] >= 0)
+ close(shm->sp[SP_READ]);
+ if (shm->sp[SP_WRITE] >= 0)
+ close(shm->sp[SP_WRITE]);
+ if (shm->listen_fd >= 0)
+ close(shm->listen_fd);
+ if (shm->cli_fd >= 0)
+ close(shm->cli_fd);
+ odp_spinlock_unlock(&shm->api_lock);
return -1;
}
int odph_cli_stop(void)
{
- cli_shm_t *shm = NULL;
- odp_shm_t shm_hdl = odp_shm_lookup(shm_name);
-
- if (shm_hdl != ODP_SHM_INVALID)
- shm = (cli_shm_t *)odp_shm_addr(shm_hdl);
+ cli_shm_t *shm = shm_lookup();
if (!shm) {
- ODPH_ERR("Error: cli server not running (shm %s not found)\n", shm_name);
+ ODPH_ERR("Error: shm %s not found\n", shm_name);
return -1;
}
+ odp_spinlock_lock(&shm->api_lock);
odp_spinlock_lock(&shm->lock);
+ if (!shm->run) {
+ odp_spinlock_unlock(&shm->lock);
+ odp_spinlock_unlock(&shm->api_lock);
+ ODPH_ERR("Error: cli server has not been started\n");
+ return -1;
+ }
shm->run = 0;
/*
- * Close the current cli connection. This stops cli_loop().
+ * Close the current cli connection. This stops cli_loop(). If cli
+ * client is disconnecting at the same time, cli_fd may already have
+ * been closed.
*/
- close(shm->cli_fd);
+ if (shm->cli_fd >= 0) {
+ close(shm->cli_fd);
+ shm->cli_fd = -1;
+ }
odp_spinlock_unlock(&shm->lock);
/*
@@ -572,17 +773,37 @@ int odph_cli_stop(void)
if (sent != sizeof(stop)) {
ODPH_ERR("Error: send() = %d: %s\n", sent, strerror(errno));
- return -1;
+ goto error;
}
if (odph_thread_join(&shm->thr_server, 1) != 1) {
ODPH_ERR("Error: odph_thread_join() failed\n");
- return -1;
+ goto error;
}
close(shm->sp[SP_READ]);
close(shm->sp[SP_WRITE]);
close(shm->listen_fd);
+ odp_spinlock_unlock(&shm->api_lock);
+ return 0;
+
+error:
+ odp_spinlock_unlock(&shm->api_lock);
+ return -1;
+}
+
+int odph_cli_term(void)
+{
+ cli_shm_t *shm = NULL;
+ odp_shm_t shm_hdl = odp_shm_lookup(shm_name);
+
+ if (shm_hdl != ODP_SHM_INVALID)
+ shm = (cli_shm_t *)odp_shm_addr(shm_hdl);
+
+ if (!shm) {
+ ODPH_ERR("Error: shm %s not found\n", shm_name);
+ return -1;
+ }
if (odp_shm_free(shm_hdl)) {
ODPH_ERR("Error: odp_shm_free() failed\n");
diff --git a/helper/include/odp/helper/cli.h b/helper/include/odp/helper/cli.h
index 41e438857..ef1c24d05 100644
--- a/helper/include/odp/helper/cli.h
+++ b/helper/include/odp/helper/cli.h
@@ -12,9 +12,6 @@
* This API allows control of ODP CLI server, which may be connected to
* using a telnet client. CLI commands may be used to get information
* from an ODP instance, for debugging purposes.
- *
- * Many CLI commands output the information to the console, or wherever
- * ODP logs have been directed to in global init.
*/
#ifndef ODPH_CLI_H_
@@ -33,6 +30,17 @@ extern "C" {
* @{
*/
+/**
+ * User defined command function type. See odph_cli_register_command().
+ *
+ * The arguments (argv) are the arguments to the command given in the CLI
+ * client. For example, having registered a command with the name "my_command",
+ * and given the command "my_command one two" in the CLI client, the user
+ * command function would be called with argc = 2, argv[0] = "one" and argv[1] =
+ * "two".
+ */
+typedef void (*odph_cli_user_cmd_func_t)(int argc, char *argv[]);
+
/** ODP CLI server parameters */
typedef struct {
/**
@@ -42,6 +50,8 @@ typedef struct {
const char *address;
/** TCP port. Default is 55555. */
uint16_t port;
+ /** Maximum number of user defined commands. Default is 50. */
+ uint32_t max_user_commands;
} odph_cli_param_t;
/**
@@ -55,19 +65,56 @@ typedef struct {
void odph_cli_param_init(odph_cli_param_t *param);
/**
+ * Initialize CLI helper
+ *
+ * This function initializes the CLI helper. It must be called before
+ * odph_cli_register_command() and odph_cli_start().
+ *
+ * @param instance ODP instance
+ * @param param CLI server parameters to use
+ * @retval 0 Success
+ * @retval <0 Failure
+ */
+int odph_cli_init(odp_instance_t instance, const odph_cli_param_t *param);
+
+/**
+ * Register a user defined command
+ *
+ * Register a command with a name, function, and an optional help text. The
+ * registered command is displayed in the output of the "help" command. When the
+ * command is invoked by the CLI client, the registered function is called with
+ * the parameters entered by the CLI client user.
+ *
+ * Command names are case-insensitive. In the CLI client, they are displayed in
+ * the case they were registered in, but they may be invoked using any case.
+ *
+ * This function should be called after odph_cli_init() and before
+ * odph_cli_start().
+ *
+ * @param name Command name (case-insensitive)
+ * @param func Command function
+ * @param help Help or description for the command. This appears in the output
+ * of the "help" command. May be NULL.
+ * @retval 0 Success
+ * @retval <0 Failure
+ */
+int odph_cli_register_command(const char *name, odph_cli_user_cmd_func_t func,
+ const char *help);
+
+/**
* Start CLI server
*
* Upon successful return from this function, the CLI server will be
* accepting client connections. This function spawns a new thread of
* type ODP_THREAD_CONTROL using odp_cpumask_default_control().
*
- * @param instance ODP instance
- * @param param CLI server parameters to use
+ * This function should be called after odph_cli_init() and after any
+ * odph_cli_register_command() calls.
+ *
* @retval 0 Success
* @retval <0 Failure
*/
-int odph_cli_start(const odp_instance_t instance,
- const odph_cli_param_t *param);
+int odph_cli_start(void);
/**
* Stop CLI server
@@ -82,6 +129,31 @@ int odph_cli_start(const odp_instance_t instance,
int odph_cli_stop(void);
/**
+ * Print to CLI
+ *
+ * A user defined command may call this function to print to the CLI client.
+ * This function should only be called in a user defined command (see
+ * odph_cli_register_command()). If called anywhere else, the behavior is
+ * undefined.
+ *
+ * @param fmt printf-style message format
+ * @return On success, the number of characters printed or buffered, without
+ * accounting for any line feed conversions. If an error is encountered,
+ * a negative value is returned.
+ */
+int odph_cli_log(const char *fmt, ...);
+
+/**
+ * Terminate CLI helper
+ *
+ * Free any resources allocated by the CLI helper.
+ *
+ * @retval 0 Success
+ * @retval <0 Failure
+ */
+int odph_cli_term(void);
+
+/**
* @}
*/
diff --git a/helper/ipsec.c b/helper/ipsec.c
index e2d24840e..41daefbfb 100644
--- a/helper/ipsec.c
+++ b/helper/ipsec.c
@@ -108,7 +108,7 @@ int odph_ipsec_alg_check(odp_ipsec_capability_t capa,
}
/* Check whether requested cipher key length is supported */
- max_capa = odp_crypto_cipher_capability(cipher_alg, NULL, 0);
+ max_capa = odp_ipsec_cipher_capability(cipher_alg, NULL, 0);
if (max_capa <= 0)
return -1;
@@ -134,7 +134,7 @@ int odph_ipsec_alg_check(odp_ipsec_capability_t capa,
}
/* Check whether requested auth key length is supported */
- max_capa = odp_crypto_auth_capability(auth_alg, NULL, 0);
+ max_capa = odp_ipsec_auth_capability(auth_alg, NULL, 0);
if (max_capa <= 0)
return max_capa;
diff --git a/helper/test/cli.c b/helper/test/cli.c
index ff3ea2f53..e7ed0e06f 100644
--- a/helper/test/cli.c
+++ b/helper/test/cli.c
@@ -38,7 +38,12 @@ int main(int argc, char *argv[])
odph_cli_param_init(&cli_param);
- if (odph_cli_start(instance, &cli_param)) {
+ if (odph_cli_init(instance, &cli_param)) {
+ ODPH_ERR("Error: odph_cli_init() failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (odph_cli_start()) {
ODPH_ERR("Error: odph_cli_start() failed.\n");
exit(EXIT_FAILURE);
}
@@ -48,6 +53,11 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
+ if (odph_cli_term()) {
+ ODPH_ERR("Error: odph_cli_term() failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
if (odp_term_local()) {
ODPH_ERR("Error: ODP local term failed.\n");
exit(EXIT_FAILURE);