summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_main.c21
-rw-r--r--lib/Makefile.am4
-rw-r--r--lib/command.c225
-rw-r--r--lib/command.h27
-rw-r--r--lib/command_queue.c5
-rw-r--r--lib/qlib_init.c80
-rw-r--r--lib/qlib_init.h41
-rw-r--r--lib/vty.c210
-rw-r--r--lib/vty.h10
-rw-r--r--vtysh/vtysh.c7
-rw-r--r--vtysh/vtysh_config.c3
11 files changed, 444 insertions, 189 deletions
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index 668bb9a5..69767a9f 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -36,6 +36,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "filter.h"
#include "plist.h"
#include "qpnexus.h"
+#include "qlib_init.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_attr.h"
@@ -66,6 +67,7 @@ static const struct option longopts[] =
{ "version", no_argument, NULL, 'v'},
{ "dryrun", no_argument, NULL, 'C'},
{ "help", no_argument, NULL, 'h'},
+ { "threaded", no_argument, NULL, 't'},
{ 0 }
};
@@ -168,6 +170,7 @@ redistribution between different routing protocols.\n\n\
-v, --version Print program version\n\
-C, --dryrun Check configuration for validity and exit\n\
-h, --help Display this help and exit\n\
+-t, --threaded Use pthreads\n\
\n\
Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
}
@@ -320,11 +323,11 @@ bgp_exit (int status)
bgp_nexus->terminate = 1;
if (cli_nexus)
- cli_nexus->terminate = 1;
+ cli_nexus->terminate = 1; /* waste of time, its the main thread */
/* TODO: join threads ? */
- exit (status);
+ qexit (status);
}
/* Main routine of bgpd. Treatment of argument and start bgp finite
@@ -339,10 +342,13 @@ main (int argc, char **argv)
char *progname;
struct thread thread;
int tmp_port;
+ int threaded = 0;
/* Set umask before anything for security */
umask (0027);
+ qlib_init_first_stage();
+
/* Preserve name of myself. */
progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
@@ -355,7 +361,7 @@ main (int argc, char **argv)
/* Command line argument treatment. */
while (1)
{
- opt = getopt_long (argc, argv, "df:i:hp:l:A:P:rnu:g:vC", longopts, 0);
+ opt = getopt_long (argc, argv, "df:i:hp:l:A:P:rnu:g:vCt", longopts, 0);
if (opt == EOF)
break;
@@ -420,6 +426,9 @@ main (int argc, char **argv)
case 'h':
usage (progname, 0);
break;
+ case 't':
+ threaded = 1;
+ break;
default:
usage (progname, 1);
break;
@@ -460,10 +469,8 @@ main (int argc, char **argv)
/* Process ID file creation. */
pid_output (pid_file);
- /* get qpthreads_enabled from config */
- qpt_set_qpthreads_enabled(1);
-
/* stage 2 initialisation */
+ qlib_init_second_stage(threaded) ;
if (qpthreads_enabled)
{
@@ -487,7 +494,7 @@ main (int argc, char **argv)
if (qpthreads_enabled)
{
qpn_exec(bgp_nexus);
- qpn_exec(cli_nexus); /* must be last to start - on main thraed */
+ qpn_exec(cli_nexus); /* must be last to start - on main thread */
}
else
{
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 97f61e47..8f518f05 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -14,7 +14,7 @@ libzebra_la_SOURCES = \
zclient.c sockopt.c smux.c md5.c if_rmap.c keychain.c privs.c \
sigevent.c pqueue.c jhash.c memtypes.c workqueue.c symtab.c heap.c \
qtime.c qpthreads.c mqueue.c qpselect.c qtimers.c qpnexus.c \
- command_queue.c
+ command_queue.c qlib_init.c
BUILT_SOURCES = memtypes.h route_types.h
@@ -31,7 +31,7 @@ pkginclude_HEADERS = \
privs.h sigevent.h pqueue.h jhash.h zassert.h memtypes.h \
workqueue.h route_types.h symtab.h heap.h \
qtime.h qpthreads.h mqueue.h qpselect.h qtimers.h qpnexus.h \
- command_queue.h
+ command_queue.h qlib_init.h
EXTRA_DIST = regex.c regex-gnu.h memtypes.awk route_types.awk route_types.txt
diff --git a/lib/command.c b/lib/command.c
index c057c0a7..f1ec15c5 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -32,6 +32,7 @@ Boston, MA 02111-1307, USA. */
#include "vty.h"
#include "command.h"
#include "workqueue.h"
+#include "command_queue.h"
/* Command vector which includes some level of command lists. Normally
each daemon maintains each own cmdvec. */
@@ -1573,7 +1574,7 @@ cmd_try_do_shortcut (enum node_type node, char* first_word) {
/* '?' describe command support. */
static vector
-cmd_describe_command_real (vector vline, struct vty *vty, int *status)
+cmd_describe_command_real (vector vline, int node, int *status)
{
unsigned int i;
vector cmd_vector;
@@ -1595,7 +1596,7 @@ cmd_describe_command_real (vector vline, struct vty *vty, int *status)
index = vector_active (vline) - 1;
/* Make copy vector of current node's command vector. */
- cmd_vector = vector_copy (cmd_node_vector (cmdvec, vty->node));
+ cmd_vector = vector_copy (cmd_node_vector (cmdvec, node));
/* Prepare match vector */
matchvec = vector_init (INIT_MATCHVEC_SIZE);
@@ -1709,18 +1710,15 @@ cmd_describe_command_real (vector vline, struct vty *vty, int *status)
}
vector
-cmd_describe_command (vector vline, struct vty *vty, int *status)
+cmd_describe_command (vector vline, int node, int *status)
{
vector ret;
- if ( cmd_try_do_shortcut(vty->node, vector_slot(vline, 0) ) )
+ if ( cmd_try_do_shortcut(node, vector_slot(vline, 0) ) )
{
- enum node_type onode;
- vector shifted_vline;
+ vector shifted_vline;
unsigned int index;
- onode = vty->node;
- vty->node = ENABLE_NODE;
/* We can try it on enable node, cos' the vty is authenticated */
shifted_vline = vector_init (vector_count(vline));
@@ -1730,15 +1728,13 @@ cmd_describe_command (vector vline, struct vty *vty, int *status)
vector_set_index (shifted_vline, index-1, vector_lookup(vline, index));
}
- ret = cmd_describe_command_real (shifted_vline, vty, status);
+ ret = cmd_describe_command_real (shifted_vline, ENABLE_NODE, status);
vector_free(shifted_vline);
- vty->node = onode;
return ret;
}
-
- return cmd_describe_command_real (vline, vty, status);
+ return cmd_describe_command_real (vline, node, status);
}
@@ -1777,10 +1773,10 @@ cmd_lcd (char **matched)
/* Command line completion support. */
static char **
-cmd_complete_command_real (vector vline, struct vty *vty, int *status)
+cmd_complete_command_real (vector vline, int node, int *status)
{
unsigned int i;
- vector cmd_vector = vector_copy (cmd_node_vector (cmdvec, vty->node));
+ vector cmd_vector = vector_copy (cmd_node_vector (cmdvec, node));
#define INIT_MATCHVEC_SIZE 10
vector matchvec;
struct cmd_element *cmd_element;
@@ -1933,18 +1929,15 @@ cmd_complete_command_real (vector vline, struct vty *vty, int *status)
}
char **
-cmd_complete_command (vector vline, struct vty *vty, int *status)
+cmd_complete_command (vector vline, int node, int *status)
{
char **ret;
- if ( cmd_try_do_shortcut(vty->node, vector_slot(vline, 0) ) )
+ if ( cmd_try_do_shortcut(node, vector_slot(vline, 0) ) )
{
- enum node_type onode;
vector shifted_vline;
unsigned int index;
- onode = vty->node;
- vty->node = ENABLE_NODE;
/* We can try it on enable node, cos' the vty is authenticated */
shifted_vline = vector_init (vector_count(vline));
@@ -1954,15 +1947,13 @@ cmd_complete_command (vector vline, struct vty *vty, int *status)
vector_set_index (shifted_vline, index-1, vector_lookup(vline, index));
}
- ret = cmd_complete_command_real (shifted_vline, vty, status);
+ ret = cmd_complete_command_real (shifted_vline, ENABLE_NODE, status);
vector_free(shifted_vline);
- vty->node = onode;
return ret;
}
-
- return cmd_complete_command_real (vline, vty, status);
+ return cmd_complete_command_real (vline, node, status);
}
/* return parent node */
@@ -2011,7 +2002,7 @@ cmd_execute_command_real (vector vline, struct vty *vty,
char *command;
/* Make copy of command elements. */
- cmd_vector = vector_copy (cmd_node_vector (cmdvec, vty->node));
+ cmd_vector = vector_copy (cmd_node_vector (cmdvec, vty_get_node(vty)));
for (index = 0; index < vector_active (vline); index++)
if ((command = vector_slot (vline, index)))
@@ -2112,11 +2103,11 @@ cmd_execute_command_real (vector vline, struct vty *vty,
return CMD_SUCCESS_DAEMON;
/* Execute matched command. */
- if (qpthreads_enabled)
+ if (qpthreads_enabled && !(matched_element->attr & CMD_ATTR_CALL))
{
/* Don't do it now, but send to bgp qpthread */
cq_enqueue(matched_element, vty, argc, argv, bgp_nexus);
- return CMD_SUCCESS;
+ return CMD_QUEUED;
}
else
{
@@ -2130,14 +2121,14 @@ cmd_execute_command (vector vline, struct vty *vty, struct cmd_element **cmd,
int ret, saved_ret, tried = 0;
enum node_type onode, try_node;
- onode = try_node = vty->node;
+ onode = try_node = vty_get_node(vty);
- if ( cmd_try_do_shortcut(vty->node, vector_slot(vline, 0) ) )
+ if ( cmd_try_do_shortcut(vty_get_node(vty), vector_slot(vline, 0) ) )
{
vector shifted_vline;
unsigned int index;
- vty->node = ENABLE_NODE;
+ vty_set_node(vty, ENABLE_NODE);
/* We can try it on enable node, cos' the vty is authenticated */
shifted_vline = vector_init (vector_count(vline));
@@ -2150,7 +2141,7 @@ cmd_execute_command (vector vline, struct vty *vty, struct cmd_element **cmd,
ret = cmd_execute_command_real (shifted_vline, vty, cmd, bgp_nexus);
vector_free(shifted_vline);
- vty->node = onode;
+ vty_set_node(vty, onode);
return ret;
}
@@ -2162,10 +2153,10 @@ cmd_execute_command (vector vline, struct vty *vty, struct cmd_element **cmd,
/* This assumes all nodes above CONFIG_NODE are childs of CONFIG_NODE */
while ( ret != CMD_SUCCESS && ret != CMD_WARNING
- && vty->node > CONFIG_NODE )
+ && vty_get_node(vty) > CONFIG_NODE )
{
try_node = node_parent(try_node);
- vty->node = try_node;
+ vty_set_node(vty, try_node);
ret = cmd_execute_command_real (vline, vty, cmd, bgp_nexus);
tried = 1;
if (ret == CMD_SUCCESS || ret == CMD_WARNING)
@@ -2177,7 +2168,7 @@ cmd_execute_command (vector vline, struct vty *vty, struct cmd_element **cmd,
/* no command succeeded, reset the vty to the original node and
return the error for this node */
if ( tried )
- vty->node = onode;
+ vty_set_node(vty, onode);
return saved_ret;
}
@@ -2199,7 +2190,7 @@ cmd_execute_command_strict (vector vline, struct vty *vty,
char *command;
/* Make copy of command element */
- cmd_vector = vector_copy (cmd_node_vector (cmdvec, vty->node));
+ cmd_vector = vector_copy (cmd_node_vector (cmdvec, vty_get_node(vty)));
for (index = 0; index < vector_active (vline); index++)
if ((command = vector_slot (vline, index)))
@@ -2319,9 +2310,9 @@ config_from_file (struct vty *vty, FILE *fp)
/* Try again with setting node to CONFIG_NODE */
while (ret != CMD_SUCCESS && ret != CMD_WARNING
- && ret != CMD_ERR_NOTHING_TODO && vty->node != CONFIG_NODE)
+ && ret != CMD_ERR_NOTHING_TODO && vty_get_node(vty) != CONFIG_NODE)
{
- vty->node = node_parent(vty->node);
+ vty_set_node(vty, node_parent(vty_get_node(vty)));
ret = cmd_execute_command_strict (vline, vty, NULL);
}
@@ -2335,14 +2326,14 @@ config_from_file (struct vty *vty, FILE *fp)
}
/* Configration from terminal */
-DEFUN (config_terminal,
+DEFUN_CALL (config_terminal,
config_terminal_cmd,
"configure terminal",
"Configuration from vty interface\n"
"Configuration terminal\n")
{
if (vty_config_lock (vty))
- vty->node = CONFIG_NODE;
+ vty_set_node(vty, CONFIG_NODE);
else
{
vty_out (vty, "VTY configuration is locked by other VTY%s", VTY_NEWLINE);
@@ -2352,39 +2343,39 @@ DEFUN (config_terminal,
}
/* Enable command */
-DEFUN (enable,
+DEFUN_CALL (enable,
config_enable_cmd,
"enable",
"Turn on privileged mode command\n")
{
/* If enable password is NULL, change to ENABLE_NODE */
if ((host.enable == NULL && host.enable_encrypt == NULL) ||
- vty->type == VTY_SHELL_SERV)
- vty->node = ENABLE_NODE;
+ vty_get_type(vty) == VTY_SHELL_SERV)
+ vty_set_node(vty, ENABLE_NODE);
else
- vty->node = AUTH_ENABLE_NODE;
+ vty_set_node(vty, AUTH_ENABLE_NODE);
return CMD_SUCCESS;
}
/* Disable command */
-DEFUN (disable,
+DEFUN_CALL (disable,
config_disable_cmd,
"disable",
"Turn off privileged mode command\n")
{
- if (vty->node == ENABLE_NODE)
- vty->node = VIEW_NODE;
+ if (vty_get_node(vty) == ENABLE_NODE)
+ vty_set_node(vty, VIEW_NODE);
return CMD_SUCCESS;
}
/* Down vty node level. */
-DEFUN (config_exit,
+DEFUN_CALL (config_exit,
config_exit_cmd,
"exit",
"Exit current mode and down to previous mode\n")
{
- switch (vty->node)
+ switch (vty_get_node(vty))
{
case VIEW_NODE:
case ENABLE_NODE:
@@ -2392,10 +2383,10 @@ DEFUN (config_exit,
if (vty_shell (vty))
exit (0);
else
- vty->status = VTY_CLOSE;
+ vty_set_status(vty, VTY_CLOSE);
break;
case CONFIG_NODE:
- vty->node = ENABLE_NODE;
+ vty_set_node(vty, ENABLE_NODE);
vty_config_unlock (vty);
break;
case INTERFACE_NODE:
@@ -2410,17 +2401,17 @@ DEFUN (config_exit,
case MASC_NODE:
case RMAP_NODE:
case VTY_NODE:
- vty->node = CONFIG_NODE;
+ vty_set_node(vty, CONFIG_NODE);
break;
case BGP_VPNV4_NODE:
case BGP_IPV4_NODE:
case BGP_IPV4M_NODE:
case BGP_IPV6_NODE:
case BGP_IPV6M_NODE:
- vty->node = BGP_NODE;
+ vty_set_node(vty, BGP_NODE);
break;
case KEYCHAIN_KEY_NODE:
- vty->node = KEYCHAIN_NODE;
+ vty_set_node(vty, KEYCHAIN_NODE);
break;
default:
break;
@@ -2429,18 +2420,18 @@ DEFUN (config_exit,
}
/* quit is alias of exit. */
-ALIAS (config_exit,
+ALIAS_CALL (config_exit,
config_quit_cmd,
"quit",
"Exit current mode and down to previous mode\n")
/* End of configuration. */
-DEFUN (config_end,
+DEFUN_CALL (config_end,
config_end_cmd,
"end",
"End current mode and change to enable mode.")
{
- switch (vty->node)
+ switch (vty_get_node(vty))
{
case VIEW_NODE:
case ENABLE_NODE:
@@ -2467,7 +2458,7 @@ DEFUN (config_end,
case MASC_NODE:
case VTY_NODE:
vty_config_unlock (vty);
- vty->node = ENABLE_NODE;
+ vty_set_node(vty, ENABLE_NODE);
break;
default:
break;
@@ -2476,7 +2467,7 @@ DEFUN (config_end,
}
/* Show version. */
-DEFUN (show_version,
+DEFUN_CALL (show_version,
show_version_cmd,
"show version",
SHOW_STR
@@ -2490,7 +2481,7 @@ DEFUN (show_version,
}
/* Help display function for all node. */
-DEFUN (config_help,
+DEFUN_CALL (config_help,
config_help_cmd,
"help",
"Description of the interactive help system\n")
@@ -2514,26 +2505,25 @@ argument.%s\
}
/* Help display function for all node. */
-DEFUN (config_list,
+DEFUN_CALL (config_list,
config_list_cmd,
"list",
"Print command list\n")
{
unsigned int i;
- struct cmd_node *cnode = vector_slot (cmdvec, vty->node);
+ struct cmd_node *cnode = vector_slot (cmdvec, vty_get_node(vty));
struct cmd_element *cmd;
for (i = 0; i < vector_active (cnode->cmd_vector); i++)
if ((cmd = vector_slot (cnode->cmd_vector, i)) != NULL
- && !(cmd->attr == CMD_ATTR_DEPRECATED
- || cmd->attr == CMD_ATTR_HIDDEN))
+ && !(cmd->attr & (CMD_ATTR_DEPRECATED | CMD_ATTR_HIDDEN)))
vty_out (vty, " %s%s", cmd->string,
VTY_NEWLINE);
return CMD_SUCCESS;
}
/* Write current configuration into file. */
-DEFUN (config_write_file,
+DEFUN_CALL (config_write_file,
config_write_file_cmd,
"write file",
"Write running configuration to memory, network, or terminal\n"
@@ -2578,8 +2568,7 @@ DEFUN (config_write_file,
}
/* Make vty for configuration file. */
- file_vty = vty_new (fd);
- file_vty->type = VTY_FILE;
+ file_vty = vty_new (fd, VTY_FILE);
/* Config file header print. */
vty_out (file_vty, "!\n! Zebra configuration saved from vty\n! ");
@@ -2640,18 +2629,18 @@ finished:
return ret;
}
-ALIAS (config_write_file,
+ALIAS_CALL (config_write_file,
config_write_cmd,
"write",
"Write running configuration to memory, network, or terminal\n")
-ALIAS (config_write_file,
+ALIAS_CALL (config_write_file,
config_write_memory_cmd,
"write memory",
"Write running configuration to memory, network, or terminal\n"
"Write configuration to the file (same as write file)\n")
-ALIAS (config_write_file,
+ALIAS_CALL (config_write_file,
copy_runningconfig_startupconfig_cmd,
"copy running-config startup-config",
"Copy configuration\n"
@@ -2659,7 +2648,7 @@ ALIAS (config_write_file,
"Copy running config to startup config (same as write file)\n")
/* Write current configuration into the terminal. */
-DEFUN (config_write_terminal,
+DEFUN_CALL (config_write_terminal,
config_write_terminal_cmd,
"write terminal",
"Write running configuration to memory, network, or terminal\n"
@@ -2668,7 +2657,7 @@ DEFUN (config_write_terminal,
unsigned int i;
struct cmd_node *node;
- if (vty->type == VTY_SHELL_SERV)
+ if (vty_get_type(vty) == VTY_SHELL_SERV)
{
for (i = 0; i < vector_active (cmdvec); i++)
if ((node = vector_slot (cmdvec, i)) && node->func && node->vtysh)
@@ -2695,14 +2684,14 @@ DEFUN (config_write_terminal,
}
/* Write current configuration into the terminal. */
-ALIAS (config_write_terminal,
+ALIAS_CALL (config_write_terminal,
show_running_config_cmd,
"show running-config",
SHOW_STR
"running configuration\n")
/* Write startup configuration into the terminal. */
-DEFUN (show_startup_config,
+DEFUN_CALL (show_startup_config,
show_startup_config_cmd,
"show startup-config",
SHOW_STR
@@ -2736,7 +2725,7 @@ DEFUN (show_startup_config,
}
/* Hostname configuration */
-DEFUN (config_hostname,
+DEFUN_CALL (config_hostname,
hostname_cmd,
"hostname WORD",
"Set system's network name\n"
@@ -2755,7 +2744,7 @@ DEFUN (config_hostname,
return CMD_SUCCESS;
}
-DEFUN (config_no_hostname,
+DEFUN_CALL (config_no_hostname,
no_hostname_cmd,
"no hostname [HOSTNAME]",
NO_STR
@@ -2769,7 +2758,7 @@ DEFUN (config_no_hostname,
}
/* VTY interface password set. */
-DEFUN (config_password, password_cmd,
+DEFUN_CALL (config_password, password_cmd,
"password (8|) WORD",
"Assign the terminal connection password\n"
"Specifies a HIDDEN password will follow\n"
@@ -2825,13 +2814,13 @@ DEFUN (config_password, password_cmd,
return CMD_SUCCESS;
}
-ALIAS (config_password, password_text_cmd,
+ALIAS_CALL (config_password, password_text_cmd,
"password LINE",
"Assign the terminal connection password\n"
"The UNENCRYPTED (cleartext) line password\n")
/* VTY enable password set. */
-DEFUN (config_enable_password, enable_password_cmd,
+DEFUN_CALL (config_enable_password, enable_password_cmd,
"enable password (8|) WORD",
"Modify enable password parameters\n"
"Assign the privileged level password\n"
@@ -2892,7 +2881,7 @@ DEFUN (config_enable_password, enable_password_cmd,
return CMD_SUCCESS;
}
-ALIAS (config_enable_password,
+ALIAS_CALL (config_enable_password,
enable_password_text_cmd,
"enable password LINE",
"Modify enable password parameters\n"
@@ -2900,7 +2889,7 @@ ALIAS (config_enable_password,
"The UNENCRYPTED (cleartext) 'enable' password\n")
/* VTY enable password delete. */
-DEFUN (no_config_enable_password, no_enable_password_cmd,
+DEFUN_CALL (no_config_enable_password, no_enable_password_cmd,
"no enable password",
NO_STR
"Modify enable password parameters\n"
@@ -2917,7 +2906,7 @@ DEFUN (no_config_enable_password, no_enable_password_cmd,
return CMD_SUCCESS;
}
-DEFUN (service_password_encrypt,
+DEFUN_CALL (service_password_encrypt,
service_password_encrypt_cmd,
"service password-encryption",
"Set up miscellaneous service\n"
@@ -2944,7 +2933,7 @@ DEFUN (service_password_encrypt,
return CMD_SUCCESS;
}
-DEFUN (no_service_password_encrypt,
+DEFUN_CALL (no_service_password_encrypt,
no_service_password_encrypt_cmd,
"no service password-encryption",
NO_STR
@@ -2967,7 +2956,7 @@ DEFUN (no_service_password_encrypt,
return CMD_SUCCESS;
}
-DEFUN (config_terminal_length, config_terminal_length_cmd,
+DEFUN_CALL (config_terminal_length, config_terminal_length_cmd,
"terminal length <0-512>",
"Set terminal line parameters\n"
"Set number of lines on a screen\n"
@@ -2982,22 +2971,22 @@ DEFUN (config_terminal_length, config_terminal_length_cmd,
vty_out (vty, "length is malformed%s", VTY_NEWLINE);
return CMD_WARNING;
}
- vty->lines = lines;
+ vty_set_lines(vty, lines);
return CMD_SUCCESS;
}
-DEFUN (config_terminal_no_length, config_terminal_no_length_cmd,
+DEFUN_CALL (config_terminal_no_length, config_terminal_no_length_cmd,
"terminal no length",
"Set terminal line parameters\n"
NO_STR
"Set number of lines on a screen\n")
{
- vty->lines = -1;
+ vty_set_lines(vty, -1);
return CMD_SUCCESS;
}
-DEFUN (service_terminal_length, service_terminal_length_cmd,
+DEFUN_CALL (service_terminal_length, service_terminal_length_cmd,
"service terminal-length <0-512>",
"Set up miscellaneous service\n"
"System wide terminal length configuration\n"
@@ -3017,7 +3006,7 @@ DEFUN (service_terminal_length, service_terminal_length_cmd,
return CMD_SUCCESS;
}
-DEFUN (no_service_terminal_length, no_service_terminal_length_cmd,
+DEFUN_CALL (no_service_terminal_length, no_service_terminal_length_cmd,
"no service terminal-length [<0-512>]",
NO_STR
"Set up miscellaneous service\n"
@@ -3028,7 +3017,7 @@ DEFUN (no_service_terminal_length, no_service_terminal_length_cmd,
return CMD_SUCCESS;
}
-DEFUN_HIDDEN (do_echo,
+DEFUN_HID_CALL (do_echo,
echo_cmd,
"echo .MESSAGE",
"Echo a message back to the vty\n"
@@ -3043,7 +3032,7 @@ DEFUN_HIDDEN (do_echo,
return CMD_SUCCESS;
}
-DEFUN (config_logmsg,
+DEFUN_CALL (config_logmsg,
config_logmsg_cmd,
"logmsg "LOG_LEVELS" .MESSAGE",
"Send a message to enabled logging destinations\n"
@@ -3056,13 +3045,14 @@ DEFUN (config_logmsg,
if ((level = level_match(argv[0])) == ZLOG_DISABLED)
return CMD_ERR_NO_MATCH;
- zlog(NULL, level, ((message = argv_concat(argv, argc, 1)) ? message : ""));
+ message = argv_concat(argv, argc, 1);
+ zlog(NULL, level, "%s", (message ? message : ""));
if (message)
XFREE(MTYPE_TMP, message);
return CMD_SUCCESS;
}
-DEFUN (show_logging,
+DEFUN_CALL (show_logging,
show_logging_cmd,
"show logging",
SHOW_STR
@@ -3117,7 +3107,7 @@ DEFUN (show_logging,
return CMD_SUCCESS;
}
-DEFUN (config_log_stdout,
+DEFUN_CALL (config_log_stdout,
config_log_stdout_cmd,
"log stdout",
"Logging control\n"
@@ -3127,7 +3117,7 @@ DEFUN (config_log_stdout,
return CMD_SUCCESS;
}
-DEFUN (config_log_stdout_level,
+DEFUN_CALL (config_log_stdout_level,
config_log_stdout_level_cmd,
"log stdout "LOG_LEVELS,
"Logging control\n"
@@ -3142,7 +3132,7 @@ DEFUN (config_log_stdout_level,
return CMD_SUCCESS;
}
-DEFUN (no_config_log_stdout,
+DEFUN_CALL (no_config_log_stdout,
no_config_log_stdout_cmd,
"no log stdout [LEVEL]",
NO_STR
@@ -3154,7 +3144,7 @@ DEFUN (no_config_log_stdout,
return CMD_SUCCESS;
}
-DEFUN (config_log_monitor,
+DEFUN_CALL (config_log_monitor,
config_log_monitor_cmd,
"log monitor",
"Logging control\n"
@@ -3164,7 +3154,7 @@ DEFUN (config_log_monitor,
return CMD_SUCCESS;
}
-DEFUN (config_log_monitor_level,
+DEFUN_CALL (config_log_monitor_level,
config_log_monitor_level_cmd,
"log monitor "LOG_LEVELS,
"Logging control\n"
@@ -3179,7 +3169,7 @@ DEFUN (config_log_monitor_level,
return CMD_SUCCESS;
}
-DEFUN (no_config_log_monitor,
+DEFUN_CALL (no_config_log_monitor,
no_config_log_monitor_cmd,
"no log monitor [LEVEL]",
NO_STR
@@ -3241,7 +3231,7 @@ set_log_file(struct vty *vty, const char *fname, int loglevel)
return CMD_SUCCESS;
}
-DEFUN (config_log_file,
+DEFUN_CALL (config_log_file,
config_log_file_cmd,
"log file FILENAME",
"Logging control\n"
@@ -3251,7 +3241,7 @@ DEFUN (config_log_file,
return set_log_file(vty, argv[0], zlog_get_default_lvl(NULL));
}
-DEFUN (config_log_file_level,
+DEFUN_CALL (config_log_file_level,
config_log_file_level_cmd,
"log file FILENAME "LOG_LEVELS,
"Logging control\n"
@@ -3266,7 +3256,7 @@ DEFUN (config_log_file_level,
return set_log_file(vty, argv[0], level);
}
-DEFUN (no_config_log_file,
+DEFUN_CALL (no_config_log_file,
no_config_log_file_cmd,
"no log file [FILENAME]",
NO_STR
@@ -3284,7 +3274,7 @@ DEFUN (no_config_log_file,
return CMD_SUCCESS;
}
-ALIAS (no_config_log_file,
+ALIAS_CALL (no_config_log_file,
no_config_log_file_level_cmd,
"no log file FILENAME LEVEL",
NO_STR
@@ -3293,7 +3283,7 @@ ALIAS (no_config_log_file,
"Logging file name\n"
"Logging level\n")
-DEFUN (config_log_syslog,
+DEFUN_CALL (config_log_syslog,
config_log_syslog_cmd,
"log syslog",
"Logging control\n"
@@ -3303,7 +3293,7 @@ DEFUN (config_log_syslog,
return CMD_SUCCESS;
}
-DEFUN (config_log_syslog_level,
+DEFUN_CALL (config_log_syslog_level,
config_log_syslog_level_cmd,
"log syslog "LOG_LEVELS,
"Logging control\n"
@@ -3318,7 +3308,7 @@ DEFUN (config_log_syslog_level,
return CMD_SUCCESS;
}
-DEFUN_DEPRECATED (config_log_syslog_facility,
+DEFUN_DEP_CALL (config_log_syslog_facility,
config_log_syslog_facility_cmd,
"log syslog facility "LOG_FACILITIES,
"Logging control\n"
@@ -3336,7 +3326,7 @@ DEFUN_DEPRECATED (config_log_syslog_facility,
return CMD_SUCCESS;
}
-DEFUN (no_config_log_syslog,
+DEFUN_CALL (no_config_log_syslog,
no_config_log_syslog_cmd,
"no log syslog [LEVEL]",
NO_STR
@@ -3348,7 +3338,7 @@ DEFUN (no_config_log_syslog,
return CMD_SUCCESS;
}
-ALIAS (no_config_log_syslog,
+ALIAS_CALL (no_config_log_syslog,
no_config_log_syslog_facility_cmd,
"no log syslog facility "LOG_FACILITIES,
NO_STR
@@ -3357,7 +3347,7 @@ ALIAS (no_config_log_syslog,
"Facility parameter for syslog messages\n"
LOG_FACILITY_DESC)
-DEFUN (config_log_facility,
+DEFUN_CALL (config_log_facility,
config_log_facility_cmd,
"log facility "LOG_FACILITIES,
"Logging control\n"
@@ -3372,7 +3362,7 @@ DEFUN (config_log_facility,
return CMD_SUCCESS;
}
-DEFUN (no_config_log_facility,
+DEFUN_CALL (no_config_log_facility,
no_config_log_facility_cmd,
"no log facility [FACILITY]",
NO_STR
@@ -3384,7 +3374,7 @@ DEFUN (no_config_log_facility,
return CMD_SUCCESS;
}
-DEFUN_DEPRECATED (config_log_trap,
+DEFUN_DEP_CALL (config_log_trap,
config_log_trap_cmd,
"log trap "LOG_LEVELS,
"Logging control\n"
@@ -3392,7 +3382,6 @@ DEFUN_DEPRECATED (config_log_trap,
LOG_LEVEL_DESC)
{
int new_level ;
- int i;
if ((new_level = level_match(argv[0])) == ZLOG_DISABLED)
return CMD_ERR_NO_MATCH;
@@ -3401,7 +3390,7 @@ DEFUN_DEPRECATED (config_log_trap,
return CMD_SUCCESS;
}
-DEFUN_DEPRECATED (no_config_log_trap,
+DEFUN_DEP_CALL (no_config_log_trap,
no_config_log_trap_cmd,
"no log trap [LEVEL]",
NO_STR
@@ -3413,7 +3402,7 @@ DEFUN_DEPRECATED (no_config_log_trap,
return CMD_SUCCESS;
}
-DEFUN (config_log_record_priority,
+DEFUN_CALL (config_log_record_priority,
config_log_record_priority_cmd,
"log record-priority",
"Logging control\n"
@@ -3423,7 +3412,7 @@ DEFUN (config_log_record_priority,
return CMD_SUCCESS;
}
-DEFUN (no_config_log_record_priority,
+DEFUN_CALL (no_config_log_record_priority,
no_config_log_record_priority_cmd,
"no log record-priority",
NO_STR
@@ -3434,7 +3423,7 @@ DEFUN (no_config_log_record_priority,
return CMD_SUCCESS;
}
-DEFUN (config_log_timestamp_precision,
+DEFUN_CALL (config_log_timestamp_precision,
config_log_timestamp_precision_cmd,
"log timestamp precision <0-6>",
"Logging control\n"
@@ -3457,7 +3446,7 @@ DEFUN (config_log_timestamp_precision,
return CMD_SUCCESS;
}
-DEFUN (no_config_log_timestamp_precision,
+DEFUN_CALL (no_config_log_timestamp_precision,
no_config_log_timestamp_precision_cmd,
"no log timestamp precision",
NO_STR
@@ -3469,7 +3458,7 @@ DEFUN (no_config_log_timestamp_precision,
return CMD_SUCCESS;
}
-DEFUN (banner_motd_file,
+DEFUN_CALL (banner_motd_file,
banner_motd_file_cmd,
"banner motd file [FILE]",
"Set banner\n"
@@ -3484,7 +3473,7 @@ DEFUN (banner_motd_file,
return CMD_SUCCESS;
}
-DEFUN (banner_motd_default,
+DEFUN_CALL (banner_motd_default,
banner_motd_default_cmd,
"banner motd default",
"Set banner string\n"
@@ -3495,7 +3484,7 @@ DEFUN (banner_motd_default,
return CMD_SUCCESS;
}
-DEFUN (no_banner_motd,
+DEFUN_CALL (no_banner_motd,
no_banner_motd_cmd,
"no banner motd",
NO_STR
diff --git a/lib/command.h b/lib/command.h
index e4d51ee9..9cc472a7 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -126,8 +126,10 @@ struct cmd_node
enum
{
- CMD_ATTR_DEPRECATED = 1,
- CMD_ATTR_HIDDEN,
+ /* bit significant */
+ CMD_ATTR_DEPRECATED = 0x01,
+ CMD_ATTR_HIDDEN = 0x02,
+ CMD_ATTR_CALL = 0x04,
};
/* Structure of command element. */
@@ -163,6 +165,7 @@ struct desc
#define CMD_COMPLETE_MATCH 8
#define CMD_COMPLETE_LIST_MATCH 9
#define CMD_SUCCESS_DAEMON 10
+#define CMD_QUEUED 11
/* Argc max counts. */
#define CMD_ARGC_MAX 25
@@ -205,8 +208,17 @@ struct desc
#define DEFUN_HIDDEN(funcname, cmdname, cmdstr, helpstr) \
DEFUN_ATTR (funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN)
+#define DEFUN_HID_CALL(funcname, cmdname, cmdstr, helpstr) \
+ DEFUN_ATTR (funcname, cmdname, cmdstr, helpstr, (CMD_ATTR_CALL | CMD_ATTR_HIDDEN))
+
#define DEFUN_DEPRECATED(funcname, cmdname, cmdstr, helpstr) \
- DEFUN_ATTR (funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED) \
+ DEFUN_ATTR (funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED)
+
+#define DEFUN_DEP_CALL(funcname, cmdname, cmdstr, helpstr) \
+ DEFUN_ATTR (funcname, cmdname, cmdstr, helpstr, (CMD_ATTR_CALL | CMD_ATTR_DEPRECATED))
+
+#define DEFUN_CALL(funcname, cmdname, cmdstr, helpstr) \
+ DEFUN_ATTR (funcname, cmdname, cmdstr, helpstr, CMD_ATTR_CALL)
/* DEFUN_NOSH for commands that vtysh should ignore */
#define DEFUN_NOSH(funcname, cmdname, cmdstr, helpstr) \
@@ -214,7 +226,7 @@ struct desc
/* DEFSH for vtysh. */
#define DEFSH(daemon, cmdname, cmdstr, helpstr) \
- DEFUN_CMD_ELEMENT(NULL, cmdname, cmdstr, helpstr, 0, daemon) \
+ DEFUN_CMD_ELEMENT(NULL, cmdname, cmdstr, helpstr, 0, daemon)
/* DEFUN + DEFSH */
#define DEFUNSH(daemon, funcname, cmdname, cmdstr, helpstr) \
@@ -247,6 +259,9 @@ struct desc
#define ALIAS_DEPRECATED(funcname, cmdname, cmdstr, helpstr) \
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED, 0)
+#define ALIAS_CALL(funcname, cmdname, cmdstr, helpstr) \
+ DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_CALL, 0)
+
#define ALIAS_SH(daemon, funcname, cmdname, cmdstr, helpstr) \
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, daemon)
@@ -338,8 +353,8 @@ extern char *argv_concat (const char **argv, int argc, int shift);
extern vector cmd_make_strvec (const char *);
extern void cmd_free_strvec (vector);
-extern vector cmd_describe_command (vector, struct vty *, int *status);
-extern char **cmd_complete_command (vector, struct vty *, int *status);
+extern vector cmd_describe_command (vector, int, int *status);
+extern char **cmd_complete_command (vector, int, int *status);
extern const char *cmd_prompt (enum node_type);
extern int config_from_file (struct vty *, FILE *);
extern enum node_type node_parent (enum node_type);
diff --git a/lib/command_queue.c b/lib/command_queue.c
index a74398c3..902cd89c 100644
--- a/lib/command_queue.c
+++ b/lib/command_queue.c
@@ -70,7 +70,10 @@ cq_action(mqueue_block mqb)
/* Execute matched command. */
result = (*wyatt->matched_element->func)
- (wyatt->matched_element, wyatt->vty, wyatt->argc, wyatt->argv);
+ (wyatt->matched_element, wyatt->vty, wyatt->argc, (const char **)wyatt->argv);
+
+ /* report */
+ vty_queued_result(wyatt->vty, result);
/* clean up */
for (i = 0; i< wyatt->argc; ++i)
diff --git a/lib/qlib_init.c b/lib/qlib_init.c
new file mode 100644
index 00000000..83ae0fe7
--- /dev/null
+++ b/lib/qlib_init.c
@@ -0,0 +1,80 @@
+/* Quagga library initialise/closedown -- functions
+ * Copyright (C) 2009 Chris Hall (GMCH), Highwayman
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING. If not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "zassert.h"
+
+/*==============================================================================
+ * Quagga Library Initialise/Closedown
+ *
+ * This gathers together the essential initialisation and closedown for the
+ * library. This ensures that any changes in the library are contained here,
+ * and do not require changes in all users of the library.
+ *
+ * There are two stages of initialisation:
+ *
+ * 1) first stage
+ *
+ * this is expected to be called before the program does anything at all.
+ *
+ * This performs all initialisation required to support asserts, logging,
+ * basic I/O (but not the remote console), trap signals... and so on.
+ *
+ * After this has been done, the system is in good shape to deal with
+ * command line options, configuration files and so on.
+ *
+ * 2) second stage
+ *
+ * this is expected to be called before the program does any serious work.
+ *
+ * This performs all initialisation required to support socket I/O,
+ * thread handling, timers, and so on.
+ *
+ * In particular, at this stage the system is set into Pthread Mode, if
+ * required. No pthreads may be started before this. Up to this point
+ * the system operates in non-Pthread Mode -- all mutexes are implicitly
+ * free.
+ *
+ * There is one stage of closedown. This is expected to be called last, and
+ * is passed the exit code.
+ *
+ *
+ */
+
+void
+qlib_init_first_stage(void)
+{
+ ;
+}
+
+void
+qlib_init_second_stage(int pthreads)
+{
+ qpt_set_qpthreads_enabled(pthreads);
+}
+
+
+void
+qexit(int exit_code)
+{
+ exit (exit_code);
+}
+
+
diff --git a/lib/qlib_init.h b/lib/qlib_init.h
new file mode 100644
index 00000000..3ffb64db
--- /dev/null
+++ b/lib/qlib_init.h
@@ -0,0 +1,41 @@
+/* Quagga library initialise/closedown -- header
+ * Copyright (C) 2009 Chris Hall (GMCH), Highwayman
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Zebra; see the file COPYING. If not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _ZEBRA_QLIB_INIT_H
+#define _ZEBRA_QLIB_INIT_H
+
+#include "zassert.h"
+/*==============================================================================
+ * Quagga Library Initialise/Closedown
+ *
+ * This gathers together the essential initialisation and closedown for the
+ * library.
+ *
+ * See qlib_init.c.
+ */
+
+extern void qlib_init_first_stage(void) ;
+
+extern void qlib_init_second_stage(int pthreads) ;
+
+extern void qexit(int exit_code) ;
+
+#endif /* _ZEBRA_QLIB_INIT_H */
diff --git a/lib/vty.c b/lib/vty.c
index 23f9bc9c..cc3a3951 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -227,13 +227,6 @@ uty_vout(struct vty *vty, const char *format, va_list args)
XFREE (MTYPE_VTY_OUT_BUF, p);
}
- if (cli_nexus != NULL && qpt_thread_self() != cli_nexus->thread_id)
- {
- /* Wake up */
- vty_event (VTY_WRITE, vty->fd, vty);
- qpt_thread_signal(cli_nexus->thread_id, SIGMQUEUE);
- }
-
return len;
}
@@ -441,7 +434,7 @@ vty_dont_lflow_ahead (struct vty *vty)
/* Allocate new vty struct. */
struct vty *
-vty_new (int fd)
+vty_new (int fd, int type)
{
struct vty *vty = XCALLOC (MTYPE_VTY, sizeof (struct vty));
@@ -449,6 +442,7 @@ vty_new (int fd)
vty->buf = XCALLOC (MTYPE_VTY, VTY_BUFSIZ);
vty->max = VTY_BUFSIZ;
vty->fd = fd;
+ vty->type = type;
if (cli_nexus)
{
@@ -592,6 +586,24 @@ vty_command (struct vty *vty, char *buf)
return ret;
}
+/* queued command has completed */
+void
+vty_queued_result(struct vty *vty, int result)
+{
+ LOCK
+
+ vty_prompt(vty);
+
+ /* Wake up */
+ if (cli_nexus)
+ {
+ vty_event (VTY_WRITE, vty->fd, vty);
+ qpt_thread_signal(cli_nexus->thread_id, SIGMQUEUE);
+ }
+
+ UNLOCK
+}
+
static const char telnet_backward_char = 0x08;
static const char telnet_space_char = ' ';
@@ -1044,7 +1056,7 @@ vty_complete_command (struct vty *vty)
if (isspace ((int) vty->buf[vty->length - 1]))
vector_set (vline, '\0');
- matched = cmd_complete_command (vline, vty, &ret);
+ matched = cmd_complete_command (vline, vty->node, &ret);
cmd_free_strvec (vline);
@@ -1167,7 +1179,7 @@ vty_describe_command (struct vty *vty)
if (isspace ((int) vty->buf[vty->length - 1]))
vector_set (vline, '\0');
- describe = cmd_describe_command (vline, vty, &ret);
+ describe = cmd_describe_command (vline, vty->node, &ret);
uty_out (vty, "%s", VTY_NEWLINE);
@@ -1472,7 +1484,7 @@ vty_execute (struct vty *vty)
vty->cp = vty->length = 0;
vty_clear_buf (vty);
- if (vty->status != VTY_CLOSE )
+ if (vty->status != VTY_CLOSE && ret != CMD_QUEUED)
vty_prompt (vty);
return ret;
@@ -1863,8 +1875,7 @@ vty_create (int vty_sock, union sockunion *su)
ASSERTLOCKED
/* Allocate new vty structure and set up default values. */
- vty = vty_new (vty_sock);
- vty->type = VTY_TERM;
+ vty = vty_new (vty_sock, VTY_TERM);
vty->address = sockunion_su2str (su);
if (no_password_check)
{
@@ -2620,8 +2631,7 @@ vty_read_file (FILE *confp)
int ret;
struct vty *vty;
- vty = vty_new (0); /* stdout */
- vty->type = VTY_TERM;
+ vty = vty_new (0, VTY_TERM); /* stdout */
vty->node = CONFIG_NODE;
/* Execute configuration file */
@@ -3032,7 +3042,7 @@ vty_event_r (enum event event, int sock, struct vty *vty)
}
}
-DEFUN (config_who,
+DEFUN_CALL (config_who,
config_who_cmd,
"who",
"Display who is on vty\n")
@@ -3040,22 +3050,26 @@ DEFUN (config_who,
unsigned int i;
struct vty *v;
+ LOCK
for (i = 0; i < vector_active (vtyvec); i++)
if ((v = vector_slot (vtyvec, i)) != NULL)
- vty_out (vty, "%svty[%d] connected from %s.%s",
+ uty_out (vty, "%svty[%d] connected from %s.%s",
v->config ? "*" : " ",
i, v->address, VTY_NEWLINE);
+ UNLOCK
return CMD_SUCCESS;
}
/* Move to vty configuration mode. */
-DEFUN (line_vty,
+DEFUN_CALL (line_vty,
line_vty_cmd,
"line vty",
"Configure a terminal line\n"
"Virtual terminal\n")
{
+ LOCK
vty->node = VTY_NODE;
+ UNLOCK
return CMD_SUCCESS;
}
@@ -3085,7 +3099,7 @@ exec_timeout (struct vty *vty, const char *min_str, const char *sec_str)
return CMD_SUCCESS;
}
-DEFUN (exec_timeout_min,
+DEFUN_CALL (exec_timeout_min,
exec_timeout_min_cmd,
"exec-timeout <0-35791>",
"Set timeout value\n"
@@ -3094,7 +3108,7 @@ DEFUN (exec_timeout_min,
return exec_timeout (vty, argv[0], NULL);
}
-DEFUN (exec_timeout_sec,
+DEFUN_CALL (exec_timeout_sec,
exec_timeout_sec_cmd,
"exec-timeout <0-35791> <0-2147483>",
"Set the EXEC timeout\n"
@@ -3104,7 +3118,7 @@ DEFUN (exec_timeout_sec,
return exec_timeout (vty, argv[0], argv[1]);
}
-DEFUN (no_exec_timeout,
+DEFUN_CALL (no_exec_timeout,
no_exec_timeout_cmd,
"no exec-timeout",
NO_STR
@@ -3114,61 +3128,71 @@ DEFUN (no_exec_timeout,
}
/* Set vty access class. */
-DEFUN (vty_access_class,
+DEFUN_CALL (vty_access_class,
vty_access_class_cmd,
"access-class WORD",
"Filter connections based on an IP access list\n"
"IP access list\n")
{
+ LOCK
+
if (vty_accesslist_name)
XFREE(MTYPE_VTY, vty_accesslist_name);
vty_accesslist_name = XSTRDUP(MTYPE_VTY, argv[0]);
+ UNLOCK
return CMD_SUCCESS;
}
/* Clear vty access class. */
-DEFUN (no_vty_access_class,
+DEFUN_CALL (no_vty_access_class,
no_vty_access_class_cmd,
"no access-class [WORD]",
NO_STR
"Filter connections based on an IP access list\n"
"IP access list\n")
{
+ int result = CMD_SUCCESS;
+
+ LOCK
if (! vty_accesslist_name || (argc && strcmp(vty_accesslist_name, argv[0])))
{
- vty_out (vty, "Access-class is not currently applied to vty%s",
+ uty_out (vty, "Access-class is not currently applied to vty%s",
VTY_NEWLINE);
- return CMD_WARNING;
+ result = CMD_WARNING;
+ }
+ else
+ {
+ XFREE(MTYPE_VTY, vty_accesslist_name);
+ vty_accesslist_name = NULL;
}
- XFREE(MTYPE_VTY, vty_accesslist_name);
-
- vty_accesslist_name = NULL;
-
- return CMD_SUCCESS;
+ UNLOCK
+ return result;
}
#ifdef HAVE_IPV6
/* Set vty access class. */
-DEFUN (vty_ipv6_access_class,
+DEFUN_CALL (vty_ipv6_access_class,
vty_ipv6_access_class_cmd,
"ipv6 access-class WORD",
IPV6_STR
"Filter connections based on an IP access list\n"
"IPv6 access list\n")
{
+ LOCK
if (vty_ipv6_accesslist_name)
XFREE(MTYPE_VTY, vty_ipv6_accesslist_name);
vty_ipv6_accesslist_name = XSTRDUP(MTYPE_VTY, argv[0]);
+ UNLOCK
return CMD_SUCCESS;
}
/* Clear vty access class. */
-DEFUN (no_vty_ipv6_access_class,
+DEFUN_CALL (no_vty_ipv6_access_class,
no_vty_ipv6_access_class_cmd,
"no ipv6 access-class [WORD]",
NO_STR
@@ -3176,112 +3200,135 @@ DEFUN (no_vty_ipv6_access_class,
"Filter connections based on an IP access list\n"
"IPv6 access list\n")
{
+ int result = CMD_SUCCESS;
+
+ LOCK
+
if (! vty_ipv6_accesslist_name ||
(argc && strcmp(vty_ipv6_accesslist_name, argv[0])))
{
- vty_out (vty, "IPv6 access-class is not currently applied to vty%s",
+ uty_out (vty, "IPv6 access-class is not currently applied to vty%s",
VTY_NEWLINE);
- return CMD_WARNING;
+ result = CMD_WARNING;
}
+ else
+ {
+ XFREE(MTYPE_VTY, vty_ipv6_accesslist_name);
- XFREE(MTYPE_VTY, vty_ipv6_accesslist_name);
-
- vty_ipv6_accesslist_name = NULL;
+ vty_ipv6_accesslist_name = NULL;
+ }
+ UNLOCK
return CMD_SUCCESS;
}
#endif /* HAVE_IPV6 */
/* vty login. */
-DEFUN (vty_login,
+DEFUN_CALL (vty_login,
vty_login_cmd,
"login",
"Enable password checking\n")
{
+ LOCK
no_password_check = 0;
+ UNLOCK
return CMD_SUCCESS;
}
-DEFUN (no_vty_login,
+DEFUN_CALL (no_vty_login,
no_vty_login_cmd,
"no login",
NO_STR
"Enable password checking\n")
{
+ LOCK
no_password_check = 1;
+ UNLOCK
return CMD_SUCCESS;
}
/* initial mode. */
-DEFUN (vty_restricted_mode,
+DEFUN_CALL (vty_restricted_mode,
vty_restricted_mode_cmd,
"anonymous restricted",
"Restrict view commands available in anonymous, unauthenticated vty\n")
{
+ LOCK
restricted_mode = 1;
+ UNLOCK
return CMD_SUCCESS;
}
-DEFUN (vty_no_restricted_mode,
+DEFUN_CALL (vty_no_restricted_mode,
vty_no_restricted_mode_cmd,
"no anonymous restricted",
NO_STR
"Enable password checking\n")
{
+ LOCK
restricted_mode = 0;
+ UNLOCK
return CMD_SUCCESS;
}
-DEFUN (service_advanced_vty,
+DEFUN_CALL (service_advanced_vty,
service_advanced_vty_cmd,
"service advanced-vty",
"Set up miscellaneous service\n"
"Enable advanced mode vty interface\n")
{
+ LOCK
host.advanced = 1;
+ UNLOCK
return CMD_SUCCESS;
}
-DEFUN (no_service_advanced_vty,
+DEFUN_CALL (no_service_advanced_vty,
no_service_advanced_vty_cmd,
"no service advanced-vty",
NO_STR
"Set up miscellaneous service\n"
"Enable advanced mode vty interface\n")
{
+ LOCK
host.advanced = 0;
+ UNLOCK
return CMD_SUCCESS;
}
-DEFUN (terminal_monitor,
+DEFUN_CALL (terminal_monitor,
terminal_monitor_cmd,
"terminal monitor",
"Set terminal line parameters\n"
"Copy debug output to the current terminal line\n")
{
+ LOCK
vty->monitor = 1;
+ UNLOCK
return CMD_SUCCESS;
}
-DEFUN (terminal_no_monitor,
+DEFUN_CALL (terminal_no_monitor,
terminal_no_monitor_cmd,
"terminal no monitor",
"Set terminal line parameters\n"
NO_STR
"Copy debug output to the current terminal line\n")
{
+ LOCK
vty->monitor = 0;
+ UNLOCK
return CMD_SUCCESS;
}
-ALIAS (terminal_no_monitor,
+ALIAS_CALL (terminal_no_monitor,
no_terminal_monitor_cmd,
"no terminal monitor",
NO_STR
"Set terminal line parameters\n"
"Copy debug output to the current terminal line\n")
-DEFUN (show_history,
+DEFUN_CALL (show_history,
show_history_cmd,
"show history",
SHOW_STR
@@ -3289,6 +3336,8 @@ DEFUN (show_history,
{
int index;
+ LOCK
+
for (index = vty->hindex + 1; index != vty->hindex;)
{
if (index == VTY_MAXHIST)
@@ -3298,11 +3347,12 @@ DEFUN (show_history,
}
if (vty->hist[index] != NULL)
- vty_out (vty, " %s%s", vty->hist[index], VTY_NEWLINE);
+ uty_out (vty, " %s%s", vty->hist[index], VTY_NEWLINE);
index++;
}
+ UNLOCK
return CMD_SUCCESS;
}
@@ -3471,6 +3521,70 @@ vty_init_vtysh ()
UNLOCK
}
+int
+vty_get_node(struct vty *vty)
+{
+ int result;
+ LOCK
+ result = vty->node;
+ UNLOCK
+ return result;
+}
+
+void
+vty_set_node(struct vty *vty, int node)
+{
+ LOCK
+ vty->node = node;
+ UNLOCK
+}
+
+int
+vty_get_type(struct vty *vty)
+{
+ int result;
+ LOCK
+ result = vty->type;
+ UNLOCK
+ return result;
+}
+
+int
+vty_get_status(struct vty *vty)
+{
+ int result;
+ LOCK
+ result = vty->status;
+ UNLOCK
+ return result;
+}
+
+void
+vty_set_status(struct vty *vty, int status)
+{
+ LOCK
+ vty->status = status;
+ UNLOCK
+}
+
+int
+vty_get_lines(struct vty *vty)
+{
+ int result;
+ LOCK
+ result = vty->lines;
+ UNLOCK
+ return result;
+}
+
+void
+vty_set_lines(struct vty *vty, int lines)
+{
+ LOCK
+ vty->lines = lines;
+ UNLOCK
+}
+
/* qpthreads: Install vty's own commands like `who' command. */
void
vty_init_r (qpn_nexus cli_n, qpn_nexus bgp_n)
diff --git a/lib/vty.h b/lib/vty.h
index 753b8fac..3c56a0b3 100644
--- a/lib/vty.h
+++ b/lib/vty.h
@@ -225,7 +225,7 @@ extern void vty_init (struct thread_master *);
extern void vty_init_vtysh (void);
extern void vty_terminate (void);
extern void vty_reset (void);
-extern struct vty *vty_new (int);
+extern struct vty *vty_new (int, int);
extern int vty_out (struct vty *, const char *, ...) PRINTF_ATTRIBUTE(2, 3);
extern int vty_puts(struct vty* vty, const char* str) ;
extern int vty_out_newline(struct vty *vty) ;
@@ -242,6 +242,14 @@ extern int vty_config_unlock (struct vty *);
extern int vty_shell (struct vty *);
extern int vty_shell_serv (struct vty *);
extern void vty_hello (struct vty *);
+extern void vty_queued_result(struct vty *, int);
+extern int vty_get_node(struct vty *);
+extern void vty_set_node(struct vty *, int);
+extern int vty_get_type(struct vty *);
+extern int vty_get_status(struct vty *);
+extern void vty_set_status(struct vty *, int);
+extern int vty_get_lines(struct vty *);
+extern void vty_set_lines(struct vty *, int);
/* Send a fixed-size message to all vty terminal monitors; this should be
an async-signal-safe function. */
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 275e037c..c5e24546 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -568,7 +568,7 @@ vtysh_rl_describe (void)
if (rl_end && isspace ((int) rl_line_buffer[rl_end - 1]))
vector_set (vline, '\0');
- describe = cmd_describe_command (vline, vty, &ret);
+ describe = cmd_describe_command (vline, vty->node, &ret);
fprintf (stdout,"\n");
@@ -658,7 +658,7 @@ command_generator (const char *text, int state)
if (rl_end && isspace ((int) rl_line_buffer[rl_end - 1]))
vector_set (vline, '\0');
- matched = cmd_complete_command (vline, vty, &complete_status);
+ matched = cmd_complete_command (vline, vty->node, &complete_status);
}
if (matched && matched[index])
@@ -2227,8 +2227,7 @@ void
vtysh_init_vty (void)
{
/* Make vty structure. */
- vty = vty_new (0);
- vty->type = VTY_SHELL;
+ vty = vty_new (0, VTY_SHELL);
vty->node = VIEW_NODE;
/* Initialize commands. */
diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c
index f7071fc2..bfcf8e64 100644
--- a/vtysh/vtysh_config.c
+++ b/vtysh/vtysh_config.c
@@ -353,8 +353,7 @@ vtysh_read_file (FILE *confp)
int ret;
struct vty *vty;
- vty = vty_new (0); /* stdout */
- vty->type = VTY_TERM;
+ vty = vty_new (0, VTY_TERM); /* stdout */
vty->node = CONFIG_NODE;
vtysh_execute_no_pager ("enable");