]> git.puffer.fish Git - matthieu/frr.git/commitdiff
*: add ->node_exit to struct cmd_node
authorDavid Lamparter <equinox@opensourcerouting.org>
Sat, 8 Sep 2018 22:03:19 +0000 (00:03 +0200)
committerDavid Lamparter <equinox@diac24.net>
Thu, 16 Apr 2020 10:54:03 +0000 (12:54 +0200)
Rather than doing a f*gly hack for the RPKI code, let's do an on-exit
hook in cmd_node.  Also allows replacing some special-casing in the vty
code.

Signed-off-by: David Lamparter <equinox@diac24.net>
bgpd/bgp_rpki.c
lib/command.c
lib/command.h
lib/vty.c
lib/vty.h

index 11ef8563c42753f4c17d313110d38fe8fd5b1d7a..1ba07e95e629eb2275d82b1eb3b74febb6f39105 100644 (file)
@@ -104,7 +104,7 @@ static struct rtr_mgr_group *get_connected_group(void);
 static void print_prefix_table(struct vty *vty);
 static void install_cli_commands(void);
 static int config_write(struct vty *vty);
-static void overwrite_exit_commands(void);
+static int config_on_exit(struct vty *vty);
 static void free_cache(struct cache *cache);
 static struct rtr_mgr_group *get_groups(void);
 #if defined(FOUND_SSH)
@@ -149,6 +149,7 @@ static struct cmd_node rpki_node = {
        .parent_node = CONFIG_NODE,
        .prompt = "%s(config-rpki)# ",
        .config_write = config_write,
+       .node_exit = config_on_exit,
 };
 static const struct route_map_rule_cmd route_match_rpki_cmd = {
        "rpki", route_match, route_match_compile, route_match_free};
@@ -1400,35 +1401,10 @@ DEFUN (show_rpki_cache_connection,
        return CMD_SUCCESS;
 }
 
-DEFUN_NOSH (rpki_exit,
-           rpki_exit_cmd,
-           "exit",
-           "Exit rpki configuration and restart rpki session\n")
+static int config_on_exit(struct vty *vty)
 {
        reset(false);
-
-       vty->node = CONFIG_NODE;
-       return CMD_SUCCESS;
-}
-
-DEFUN_NOSH (rpki_quit,
-           rpki_quit_cmd,
-           "quit",
-           "Exit rpki configuration mode\n")
-{
-       return rpki_exit(self, vty, argc, argv);
-}
-
-DEFUN_NOSH (rpki_end,
-           rpki_end_cmd,
-           "end",
-           "End rpki configuration, restart rpki session and change to enable mode.\n")
-{
-       int ret = reset(false);
-
-       vty_config_exit(vty);
-       vty->node = ENABLE_NODE;
-       return ret == SUCCESS ? CMD_SUCCESS : CMD_WARNING;
+       return 1;
 }
 
 DEFUN (rpki_reset,
@@ -1522,32 +1498,11 @@ DEFUN (no_match_rpki,
        return CMD_SUCCESS;
 }
 
-static void overwrite_exit_commands(void)
-{
-       unsigned int i;
-       vector cmd_vector = rpki_node.cmd_vector;
-
-       for (i = 0; i < cmd_vector->active; ++i) {
-               struct cmd_element *cmd = vector_lookup(cmd_vector, i);
-
-               if (strcmp(cmd->string, "exit") == 0
-                   || strcmp(cmd->string, "quit") == 0
-                   || strcmp(cmd->string, "end") == 0) {
-                       uninstall_element(RPKI_NODE, cmd);
-               }
-       }
-
-       install_element(RPKI_NODE, &rpki_exit_cmd);
-       install_element(RPKI_NODE, &rpki_quit_cmd);
-       install_element(RPKI_NODE, &rpki_end_cmd);
-}
-
 static void install_cli_commands(void)
 {
        // TODO: make config write work
        install_node(&rpki_node);
        install_default(RPKI_NODE);
-       overwrite_exit_commands();
        install_element(CONFIG_NODE, &rpki_cmd);
        install_element(ENABLE_NODE, &rpki_cmd);
 
index 8ec93c1b336fdf137184976cd986a9abd52248ef..d51922dfa18cc484808731d3b9279d712d4cf83c 100644 (file)
@@ -99,6 +99,8 @@ const char *cmd_domainname_get(void)
        return host.domainname;
 }
 
+static int root_on_exit(struct vty *vty);
+
 /* Standard command node structures. */
 static struct cmd_node auth_node = {
        .name = "auth",
@@ -110,6 +112,7 @@ static struct cmd_node view_node = {
        .name = "view",
        .node = VIEW_NODE,
        .prompt = "%s> ",
+       .node_exit = root_on_exit,
 };
 
 static struct cmd_node auth_enable_node = {
@@ -122,6 +125,7 @@ static struct cmd_node enable_node = {
        .name = "enable",
        .node = ENABLE_NODE,
        .prompt = "%s# ",
+       .node_exit = root_on_exit,
 };
 
 static int config_write_host(struct vty *vty);
@@ -131,6 +135,7 @@ static struct cmd_node config_node = {
        .parent_node = ENABLE_NODE,
        .prompt = "%s(config)# ",
        .config_write = config_write_host,
+       .node_exit = vty_config_node_exit,
 };
 
 static const struct facility_map {
@@ -1382,28 +1387,25 @@ DEFUN (config_exit,
        return CMD_SUCCESS;
 }
 
+static int root_on_exit(struct vty *vty)
+{
+       if (vty_shell(vty))
+               exit(0);
+       else
+               vty->status = VTY_CLOSE;
+       return 0;
+}
+
 void cmd_exit(struct vty *vty)
 {
        struct cmd_node *cnode = vector_lookup(cmdvec, vty->node);
 
-       switch (vty->node) {
-       case VIEW_NODE:
-       case ENABLE_NODE:
-               if (vty_shell(vty))
-                       exit(0);
-               else
-                       vty->status = VTY_CLOSE;
-               break;
-       case CONFIG_NODE:
-               vty->node = ENABLE_NODE;
-               vty_config_exit(vty);
-               break;
-       default:
-               if (cnode->parent_node)
-                       vty->node = cnode->parent_node;
-               break;
+       if (cnode->node_exit) {
+               if (!cnode->node_exit(vty))
+                       return;
        }
-
+       if (cnode->parent_node)
+               vty->node = cnode->parent_node;
        if (vty->xpath_index > 0)
                vty->xpath_index--;
 }
index 5629eb3679582a23af0eabe4d4f7c7d01c44a17d..e7c9ff4c5285bb3a95f5ec3082a0891ca31b8673 100644 (file)
@@ -182,6 +182,11 @@ struct cmd_node {
        /* Node's configuration write function */
        int (*config_write)(struct vty *);
 
+       /* called when leaving the node on a VTY session.
+        * return 1 if normal exit processing should happen, 0 to suppress
+        */
+       int (*node_exit)(struct vty *);
+
        /* Node's command graph */
        struct graph *cmdgraph;
 
index 683c39f893bc973356a08df7a77b76e24020794c..86d0a36aa038bf575ff93bd8bdb4935b74d0405f 100644 (file)
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -2199,6 +2199,9 @@ void vty_close(struct vty *vty)
        int i;
        bool was_stdio = false;
 
+       /* Drop out of configure / transaction if needed. */
+       vty_config_exit(vty);
+
        /* Cancel threads.*/
        THREAD_OFF(vty->t_read);
        THREAD_OFF(vty->t_write);
@@ -2242,9 +2245,6 @@ void vty_close(struct vty *vty)
                list_delete(&vty->error);
        }
 
-       /* Check configure. */
-       vty_config_exit(vty);
-
        /* OK free vty. */
        XFREE(MTYPE_VTY, vty);
 
@@ -2614,14 +2614,18 @@ void vty_config_exit(struct vty *vty)
                cnode = vector_lookup(cmdvec, node);
                node = cnode->parent_node;
        }
-       if (node != CONFIG_NODE) {
-               vty_out(vty,
-                       "WARNING: vty_config_exit() from outside CONFIG_NODE!\n");
+       if (node != CONFIG_NODE)
+               /* called outside config, e.g. vty_close() in ENABLE_NODE */
                return;
-       }
 
        while (vty->node != ENABLE_NODE)
+               /* will call vty_config_node_exit() below */
                cmd_exit(vty);
+}
+
+int vty_config_node_exit(struct vty *vty)
+{
+       vty->xpath_index = 0;
 
        /* Check if there's a pending confirmed commit. */
        if (vty->t_confirmed_commit_timeout) {
@@ -2644,6 +2648,7 @@ void vty_config_exit(struct vty *vty)
        }
 
        vty->config = false;
+       return 1;
 }
 
 /* Master of the threads. */
index f90a35a260bfff2044b42eca0c87be1c11322c6b..694aac3944e1dc1fd25dba2d779f1c730208a6c2 100644 (file)
--- a/lib/vty.h
+++ b/lib/vty.h
@@ -323,6 +323,7 @@ extern void vty_log(const char *level, const char *proto, const char *msg,
 extern int vty_config_enter(struct vty *vty, bool private_config,
                            bool exclusive);
 extern void vty_config_exit(struct vty *);
+extern int vty_config_node_exit(struct vty *);
 extern int vty_shell(struct vty *);
 extern int vty_shell_serv(struct vty *);
 extern void vty_hello(struct vty *);