Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add extensions for vtysh #1

Open
wants to merge 1 commit into
base: hh-master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions vtysh/subdir.am
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ vtysh_vtysh_SOURCES = \
vtysh/vtysh.c \
vtysh/vtysh_user.c \
vtysh/vtysh_config.c \
vtysh/vtysh_extensions.c \
# end

noinst_HEADERS += \
vtysh/vtysh.h \
vtysh/vtysh_user.h \
vtysh/vtysh_extensions.h \
# end

vtysh_vtysh_LDADD = lib/libfrr.la $(LIBCAP) $(LIBREADLINE) $(LIBS) $(LIBPAM)
Expand Down
20 changes: 18 additions & 2 deletions vtysh/vtysh.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "json.h"
#include "ferr.h"
#include "sockopt.h"
#include "vtysh_extensions.h"

DEFINE_MTYPE_STATIC(MVTYSH, VTYSH_CMD, "Vtysh cmd copy");

Expand Down Expand Up @@ -462,7 +463,7 @@ static int vtysh_client_execute(struct vtysh_client *head_client,
}

/* Execute by name */
static int vtysh_client_execute_name(const char *name, const char *line)
int vtysh_client_execute_name(const char *name, const char *line)
{
int ret = CMD_SUCCESS;
int idx_client = -1;
Expand Down Expand Up @@ -3013,7 +3014,7 @@ static int show_per_daemon(struct vty *vty, struct cmd_token **argv, int argc,
}
#pragma GCC diagnostic pop

static int show_one_daemon(struct vty *vty, struct cmd_token **argv, int argc,
int show_one_daemon(struct vty *vty, struct cmd_token **argv, int argc,
const char *name)
{
int ret;
Expand Down Expand Up @@ -4623,6 +4624,18 @@ DEFUN_HIDDEN(show_cli_graph_vtysh,
return CMD_SUCCESS;
}

DEFUN (show_vtysh_extensions,
show_vtysh_extensions_cmd,
"show vtysh extensions",
SHOW_STR
"VTYSH\n"
"extension info\n")
{
vtysh_show_extensions(vty);
return CMD_SUCCESS;
}


static void vtysh_install_default(enum node_type node)
{
_install_element(node, &config_list_cmd);
Expand Down Expand Up @@ -5560,4 +5573,7 @@ void vtysh_init_vty(void)
install_element(CONFIG_NODE, &no_vtysh_password_cmd);
install_element(CONFIG_NODE, &vtysh_enable_password_cmd);
install_element(CONFIG_NODE, &no_vtysh_enable_password_cmd);

/* vtysh extensions */
install_element(VIEW_NODE, &show_vtysh_extensions_cmd);
}
82 changes: 82 additions & 0 deletions vtysh/vtysh_extensions.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#include <dlfcn.h>
#include <stdio.h>

#include "memory.h"
#include "vtysh_extensions.h"
#include "lib/vty.h"
#include "vtysh.h"

DEFINE_MTYPE(MVTYSH, VTYSH_EXT, "Vtysh extension");
DEFINE_MTYPE(MVTYSH, VTYSH_EXT_NAME, "Vtysh extension name");

static struct vtysh_ext *extensions = NULL;

static struct vtysh_ext *find_extension(char *name)
{
for(struct vtysh_ext *e = extensions; e != NULL; e = e->next)
if (strcmp(e->name, name) == 0)
return e;
return NULL;
}
static int vtysh_load_extension(struct vtysh_ext *e)
{
e->handle = dlopen(e->name, RTLD_GLOBAL | RTLD_NOW);
if (e->handle) {
int (*ext_load)(void);
*(void **)&ext_load = dlsym(e->handle, "vtysh_extension");
if (*ext_load) {
int r;
if ((r = (*ext_load)()) == 0)
e->loaded = true;
return r;
} else {
fprintf(stderr, " Failed to init vtysh extension '%s': %s\n", e->name, dlerror());
return -1;
}
} else {
fprintf(stderr, " Failed to load vtysh extension '%s': %s\n", e->name, dlerror());
return -1;
}
}

int vtysh_load_extensions(void)
{
struct vtysh_ext *e;
for (e = extensions; e ; e = e->next) {
if (vtysh_load_extension(e) != 0)
return -1;
}
return 0;
}
void vtysh_unload_extensions(void)
{
struct vtysh_ext *e;
for (e = extensions; e ; e = e->next) {
if (e->loaded)
dlclose(e->handle);
if (e->name)
XFREE(MTYPE_VTYSH_EXT_NAME, e->name);
XFREE(MTYPE_VTYSH_EXT, e);
}
}
void vtysh_register_extension(char *name)
{
assert(name);
if (find_extension(name) != NULL) {
fprintf(stderr, "Omitting extension %s: it appears to be already registered", name);
return;
}
struct vtysh_ext *e = XCALLOC(MTYPE_VTYSH_EXT, sizeof(*e));
e->name = XSTRDUP(MTYPE_VTYSH_EXT_NAME, name);
e->next = extensions;
extensions = e;
}

void vtysh_show_extensions(struct vty *vty)
{
struct vtysh_ext *e;
for (e = extensions; e ; e = e->next) {
vty_out(vty, " Extension: %s\n", e->name);
vty_out(vty, " status: %s\n\n", e->loaded ? "loaded" : "not-loaded");
}
}
22 changes: 22 additions & 0 deletions vtysh/vtysh_extensions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#ifndef _VTYSH_EXTENSIONS_H
#define _VTYSH_EXTENSIONS_H

#include <stdbool.h>
#include "lib/vty.h"

DECLARE_MTYPE(VTYSH_EXT);

struct vtysh_ext {
char *name;
void *handle;
bool loaded;
struct vtysh_ext *next;
};

void vtysh_register_extension(char *name);
int vtysh_load_extensions(void);
void vtysh_unload_extensions(void);

void vtysh_show_extensions(struct vty *vty);

#endif /* _VTYSH_EXTENSIONS_H */
9 changes: 8 additions & 1 deletion vtysh/vtysh_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ struct option longopts[] = {
{"user", no_argument, NULL, 'u'},
{"timestamp", no_argument, NULL, 't'},
{"no-fork", no_argument, NULL, OPTION_NOFORK},
{"extension", required_argument, NULL, 'X'},
{0}};

bool vtysh_loop_exited;
Expand Down Expand Up @@ -322,6 +323,7 @@ void suid_off(void)
}
}


/* VTY shell main routine. */
int main(int argc, char **argv, char **env)
{
Expand Down Expand Up @@ -369,7 +371,7 @@ int main(int argc, char **argv, char **env)

/* Option handling. */
while (1) {
opt = getopt_long(argc, argv, "be:c:d:nf:H:mEhCwN:ut", longopts,
opt = getopt_long(argc, argv, "be:c:d:nf:H:mEhCwN:utX:", longopts,
0);

if (opt == EOF)
Expand Down Expand Up @@ -446,6 +448,9 @@ int main(int argc, char **argv, char **env)
case 'H':
histfile = optarg;
break;
case 'X':
vtysh_register_extension(optarg);
break;
default:
usage(1);
break;
Expand Down Expand Up @@ -493,6 +498,7 @@ int main(int argc, char **argv, char **env)
vtysh_config_init();

vty_init_vtysh();
vtysh_load_extensions();

if (!user_mode) {
/* Read vtysh configuration file before connecting to daemons.
Expand Down Expand Up @@ -739,6 +745,7 @@ int main(int argc, char **argv, char **env)
vtysh_rl_run();

vtysh_uninit();
vtysh_unload_extensions();

history_truncate_file(history_file, 1000);
printf("\n");
Expand Down