]> git.proxmox.com Git - mirror_frr.git/commitdiff
lib: add hook for preprocessing commands
authorQuentin Young <qlyoung@cumulusnetworks.com>
Sun, 13 May 2018 00:09:08 +0000 (20:09 -0400)
committerQuentin Young <qlyoung@cumulusnetworks.com>
Wed, 6 Jun 2018 16:15:34 +0000 (16:15 +0000)
This patch adds a hook point intended to allow subscribers to modify the
raw text of a CLI command before it is passed to the rest of the CLI
pipeline. To give access to the raw text of the command, a new function
for executing CLI has been defined whose only difference from
`cmd_execute_command` is that it accepts the command to execute as a
string rather than as a string vector.

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
lib/command.c
lib/command.h

index 6aae4a074cfffe4b79ccc67a38daef8bd784d3e5..97e60a5929148d8b0a078b19adc0cd6e8f716228 100644 (file)
@@ -44,6 +44,7 @@
 #include "defaults.h"
 #include "libfrr.h"
 #include "jhash.h"
+#include "hook.h"
 
 DEFINE_MTYPE(LIB, HOST, "Host config")
 DEFINE_MTYPE(LIB, COMPLETION, "Completion item")
@@ -1140,6 +1141,68 @@ int cmd_execute_command_strict(vector vline, struct vty *vty,
        return cmd_execute_command_real(vline, FILTER_STRICT, vty, cmd);
 }
 
+/*
+ * Hook for preprocessing command string before executing.
+ *
+ * All subscribers are called with the raw command string that is to be
+ * executed. If any changes are to be made, a new string should be allocated
+ * with MTYPE_TMP and *cmd_out updated to point to this new string. The caller
+ * is then responsible for freeing this string.
+ *
+ * All processing functions must be mutually exclusive in their action, i.e. if
+ * one subscriber decides to modify the command, all others must not modify it
+ * when called. Feeding the output of one processing command into a subsequent
+ * one is not supported.
+ *
+ * This hook is intentionally internal to the command processing system.
+ *
+ * cmd_in
+ *    The raw command string.
+ *
+ * cmd_out
+ *    The result of any processing.
+ */
+DECLARE_HOOK(cmd_execute,
+            (struct vty * vty, const char *cmd_in, char **cmd_out),
+            (vty, cmd_in, cmd_out));
+DEFINE_HOOK(cmd_execute, (struct vty * vty, const char *cmd_in, char **cmd_out),
+           (vty, cmd_in, cmd_out));
+
+/* Hook executed after a CLI command. */
+DECLARE_KOOH(cmd_execute_done, (struct vty * vty, const char *cmd_exec),
+            (vty, cmd_exec));
+DEFINE_KOOH(cmd_execute_done, (struct vty * vty, const char *cmd_exec),
+           (vty, cmd_exec));
+
+int cmd_execute(struct vty *vty, const char *cmd,
+               const struct cmd_element **matched, int vtysh)
+{
+       int ret;
+       char *cmd_out = NULL;
+       const char *cmd_exec;
+       vector vline;
+
+       hook_call(cmd_execute, vty, cmd, &cmd_out);
+       cmd_exec = cmd_out ? (const char *)cmd_out : cmd;
+
+       vline = cmd_make_strvec(cmd_exec);
+
+       if (vline) {
+               ret = cmd_execute_command(vline, vty, matched, vtysh);
+               cmd_free_strvec(vline);
+       } else {
+               ret = CMD_SUCCESS;
+       }
+
+       hook_call(cmd_execute_done, vty, cmd_exec);
+
+       if (cmd_out)
+               XFREE(MTYPE_TMP, cmd_out);
+
+       return ret;
+}
+
+
 /**
  * Parse one line of config, walking up the parse tree attempting to find a
  * match
index 58cc58600008c4bcbfe3d5299a8d87c6977eec6e..9bf482f41b6054c902adce326dd8839140a374fe 100644 (file)
@@ -416,6 +416,28 @@ extern int command_config_read_one_line(struct vty *vty,
                                        int use_config_node);
 extern int config_from_file(struct vty *, FILE *, unsigned int *line_num);
 extern enum node_type node_parent(enum node_type);
+/*
+ * Execute command under the given vty context.
+ *
+ * vty
+ *    The vty context to execute under.
+ *
+ * cmd
+ *    The command string to execute.
+ *
+ * matched
+ *    If non-null and a match was found, the address of the matched command is
+ *    stored here. No action otherwise.
+ *
+ * vtysh
+ *    Whether or not this is being called from vtysh. If this is nonzero,
+ *    XXX: then what?
+ *
+ * Returns:
+ *    XXX: what does it return
+ */
+extern int cmd_execute(struct vty *vty, const char *cmd,
+                      const struct cmd_element **matched, int vtysh);
 extern int cmd_execute_command(vector, struct vty *,
                               const struct cmd_element **, int);
 extern int cmd_execute_command_strict(vector, struct vty *,