diff options
-rw-r--r-- | bgpd/bgp_main.c | 21 | ||||
-rw-r--r-- | lib/Makefile.am | 4 | ||||
-rw-r--r-- | lib/command.c | 225 | ||||
-rw-r--r-- | lib/command.h | 27 | ||||
-rw-r--r-- | lib/command_queue.c | 5 | ||||
-rw-r--r-- | lib/qlib_init.c | 80 | ||||
-rw-r--r-- | lib/qlib_init.h | 41 | ||||
-rw-r--r-- | lib/vty.c | 210 | ||||
-rw-r--r-- | lib/vty.h | 10 | ||||
-rw-r--r-- | vtysh/vtysh.c | 7 | ||||
-rw-r--r-- | vtysh/vtysh_config.c | 3 |
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 */ @@ -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) @@ -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"); |