back to topotato report
topotato coverage report
Current view: top level - lib - vty.h (source / functions) Hit Total Coverage
Test: test_bgp_ecmp_enhe.py::BGP_Unnumbered_ECMP Lines: 3 6 50.0 %
Date: 2023-11-16 17:19:14 Functions: 0 2 0.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-or-later
       2             : /* Virtual terminal [aka TeletYpe] interface routine
       3             :  * Copyright (C) 1997 Kunihiro Ishiguro
       4             :  */
       5             : 
       6             : #ifndef _ZEBRA_VTY_H
       7             : #define _ZEBRA_VTY_H
       8             : 
       9             : #include <sys/types.h>
      10             : #ifdef HAVE_LIBPCRE2_POSIX
      11             : #ifndef _FRR_PCRE2_POSIX
      12             : #define _FRR_PCRE2_POSIX
      13             : #include <pcre2posix.h>
      14             : #endif /* _FRR_PCRE2_POSIX */
      15             : #elif defined(HAVE_LIBPCREPOSIX)
      16             : #include <pcreposix.h>
      17             : #else
      18             : #include <regex.h>
      19             : #endif /* HAVE_LIBPCRE2_POSIX */
      20             : 
      21             : #include "frrevent.h"
      22             : #include "log.h"
      23             : #include "sockunion.h"
      24             : #include "qobj.h"
      25             : #include "compiler.h"
      26             : #include "northbound.h"
      27             : #include "zlog_live.h"
      28             : #include "libfrr.h"
      29             : #include "mgmt_fe_client.h"
      30             : 
      31             : #ifdef __cplusplus
      32             : extern "C" {
      33             : #endif
      34             : 
      35             : struct json_object;
      36             : 
      37             : #define VTY_BUFSIZ 4096
      38             : #define VTY_MAXHIST 20
      39             : #define VTY_MAXDEPTH 8
      40             : 
      41             : #define VTY_MAXCFGCHANGES 16
      42             : 
      43             : struct vty_error {
      44             :         char error_buf[VTY_BUFSIZ];
      45             :         uint32_t line_num;
      46             :         int cmd_ret;
      47             : };
      48             : 
      49             : struct vty_cfg_change {
      50             :         char xpath[XPATH_MAXLEN];
      51             :         enum nb_operation operation;
      52             :         const char *value;
      53             : };
      54             : 
      55             : PREDECL_DLIST(vtys);
      56             : 
      57             : /* VTY struct. */
      58             : struct vty {
      59             :         struct vtys_item itm;
      60             : 
      61             :         /* File descripter of this vty. */
      62             :         int fd;
      63             : 
      64             :         /* output FD, to support stdin/stdout combination */
      65             :         int wfd;
      66             : 
      67             :         /* File output, used for VTYSH only */
      68             :         FILE *of;
      69             :         FILE *of_saved;
      70             : 
      71             :         /* whether we are using pager or not */
      72             :         bool is_paged;
      73             : 
      74             :         /* Is this vty connect to file or not */
      75             :         enum { VTY_TERM,       /* telnet conn or stdin/stdout UI */
      76             :                VTY_FILE,       /* reading and writing config files */
      77             :                VTY_SHELL,      /* vtysh client side UI */
      78             :                VTY_SHELL_SERV, /* server-side vtysh connection */
      79             :         } type;
      80             : 
      81             :         /* Node status of this vty */
      82             :         int node;
      83             : 
      84             :         /* Failure count */
      85             :         int fail;
      86             : 
      87             :         /* Output filer regex */
      88             :         bool filter;
      89             :         regex_t include;
      90             : 
      91             :         /* Line buffer */
      92             :         struct buffer *lbuf;
      93             : 
      94             :         /* Output buffer. */
      95             :         struct buffer *obuf;
      96             : 
      97             :         /* Command input buffer */
      98             :         char *buf;
      99             : 
     100             :         /* Command input error buffer */
     101             :         struct list *error;
     102             : 
     103             :         /* Command cursor point */
     104             :         int cp;
     105             : 
     106             :         /* Command length */
     107             :         int length;
     108             : 
     109             :         /* Command max length. */
     110             :         int max;
     111             : 
     112             :         /* Histry of command */
     113             :         char *hist[VTY_MAXHIST];
     114             : 
     115             :         /* History lookup current point */
     116             :         int hp;
     117             : 
     118             :         /* History insert end point */
     119             :         int hindex;
     120             : 
     121             :         /* Changes enqueued to be applied in the candidate configuration. */
     122             :         size_t num_cfg_changes;
     123             :         struct nb_cfg_change cfg_changes[VTY_MAXCFGCHANGES];
     124             : 
     125             :         /* XPath of the current node */
     126             :         int xpath_index;
     127             :         char xpath[VTY_MAXDEPTH][XPATH_MAXLEN];
     128             : 
     129             :         /*
     130             :          * Keep track of how many SET_CFG requests has been sent so far that
     131             :          * has not been committed yet.
     132             :          */
     133             :         size_t mgmt_num_pending_setcfg;
     134             : 
     135             :         /* In configure mode. */
     136             :         bool config;
     137             : 
     138             :         /* Private candidate configuration mode. */
     139             :         bool private_config;
     140             : 
     141             :         /* Candidate configuration. */
     142             :         struct nb_config *candidate_config;
     143             : 
     144             :         /* Base candidate configuration. */
     145             :         struct nb_config *candidate_config_base;
     146             : 
     147             :         /* Dynamic transaction information. */
     148             :         bool pending_allowed;
     149             :         bool pending_commit;
     150             :         char *pending_cmds_buf;
     151             :         size_t pending_cmds_buflen;
     152             :         size_t pending_cmds_bufpos;
     153             : 
     154             :         /* Confirmed-commit timeout and rollback configuration. */
     155             :         struct event *t_confirmed_commit_timeout;
     156             :         struct nb_config *confirmed_commit_rollback;
     157             : 
     158             :         /* qobj object ID (replacement for "index") */
     159             :         uint64_t qobj_index;
     160             : 
     161             :         /* qobj second-level object ID (replacement for "index_sub") */
     162             :         uint64_t qobj_index_sub;
     163             : 
     164             :         /* For escape character. */
     165             :         unsigned char escape;
     166             : 
     167             :         /* Current vty status. */
     168             :         enum {
     169             :                 VTY_NORMAL,
     170             :                 VTY_CLOSE,
     171             :                 VTY_MORE,
     172             :                 VTY_MORELINE,
     173             :                 VTY_PASSFD,
     174             :         } status;
     175             : 
     176             :         /* vtysh socket/fd passing (for terminal monitor) */
     177             :         int pass_fd;
     178             : 
     179             :         /* CLI command return value (likely CMD_SUCCESS) when pass_fd != -1 */
     180             :         uint8_t pass_fd_status[4];
     181             : 
     182             :         /* live logging target / terminal monitor */
     183             :         struct zlog_live_cfg live_log;
     184             : 
     185             :         /* IAC handling: was the last character received the
     186             :            IAC (interpret-as-command) escape character (and therefore the next
     187             :            character will be the command code)?  Refer to Telnet RFC 854. */
     188             :         unsigned char iac;
     189             : 
     190             :         /* IAC SB (option subnegotiation) handling */
     191             :         unsigned char iac_sb_in_progress;
     192             : /* At the moment, we care only about the NAWS (window size) negotiation,
     193             :    and that requires just a 5-character buffer (RFC 1073):
     194             :      <NAWS char> <16-bit width> <16-bit height> */
     195             : #define TELNET_NAWS_SB_LEN 5
     196             :         unsigned char sb_buf[TELNET_NAWS_SB_LEN];
     197             :         /* How many subnegotiation characters have we received?  We just drop
     198             :            those that do not fit in the buffer. */
     199             :         size_t sb_len;
     200             : 
     201             :         /* Window width/height. */
     202             :         int width;
     203             :         int height;
     204             : 
     205             :         /* Configure lines. */
     206             :         int lines;
     207             : 
     208             :         /* Read and write thread. */
     209             :         struct event *t_read;
     210             :         struct event *t_write;
     211             : 
     212             :         /* Timeout seconds and thread. */
     213             :         unsigned long v_timeout;
     214             :         struct event *t_timeout;
     215             : 
     216             :         /* What address is this vty comming from. */
     217             :         char address[SU_ADDRSTRLEN];
     218             : 
     219             :         /* "frame" output.  This is buffered and will be printed if some
     220             :          * actual output follows, or will be discarded if the frame ends
     221             :          * without any output. */
     222             :         size_t frame_pos;
     223             :         char frame[1024];
     224             : 
     225             :         uint64_t mgmt_session_id; /* FE adapter identifies session w/ this */
     226             :         uint64_t mgmt_client_id;  /* FE vty client identifies w/ this ID */
     227             :         uint64_t mgmt_req_id;
     228             :         /* set when we have sent mgmtd a *REQ command in response to some vty
     229             :          * CLI command and we are waiting on the reply so we can respond to the
     230             :          * vty user. */
     231             :         const char *mgmt_req_pending_cmd;
     232             :         bool mgmt_locked_candidate_ds;
     233             :         bool mgmt_locked_running_ds;
     234             :         /* Need to track when we file-lock in vtysh to re-lock on end/conf t
     235             :          * workaround
     236             :          */
     237             :         bool vtysh_file_locked;
     238             : };
     239             : 
     240           2 : static inline void vty_push_context(struct vty *vty, int node, uint64_t id)
     241             : {
     242           2 :         vty->node = node;
     243           2 :         vty->qobj_index = id;
     244           0 : }
     245             : 
     246             : /* note: VTY_PUSH_CONTEXT(..., NULL) doesn't work, since it will try to
     247             :  * dereference "NULL->qobj_node.nid" */
     248             : #define VTY_PUSH_CONTEXT(nodeval, ptr)                                         \
     249             :         vty_push_context(vty, nodeval, QOBJ_ID_0SAFE(ptr))
     250             : #define VTY_PUSH_CONTEXT_NULL(nodeval) vty_push_context(vty, nodeval, 0ULL)
     251             : #define VTY_PUSH_CONTEXT_SUB(nodeval, ptr)                                     \
     252             :         do {                                                                   \
     253             :                 vty->node = nodeval;                                           \
     254             :                 /* qobj_index stays untouched */                               \
     255             :                 vty->qobj_index_sub = QOBJ_ID_0SAFE(ptr);                      \
     256             :         } while (0)
     257             : 
     258             : /* can return NULL if context is invalid! */
     259             : #define VTY_GET_CONTEXT(structname)                                            \
     260             :         QOBJ_GET_TYPESAFE(vty->qobj_index, structname)
     261             : #define VTY_GET_CONTEXT_SUB(structname)                                        \
     262             :         QOBJ_GET_TYPESAFE(vty->qobj_index_sub, structname)
     263             : 
     264             : /* will return if ptr is NULL. */
     265             : #define VTY_CHECK_CONTEXT(ptr)                                                 \
     266             :         if (!ptr) {                                                            \
     267             :                 vty_out(vty,                                                   \
     268             :                         "Current configuration object was deleted "            \
     269             :                         "by another process.\n");                              \
     270             :                 return CMD_WARNING;                                            \
     271             :         }
     272             : 
     273             : /* struct structname *ptr = <context>;   ptr will never be NULL. */
     274             : #define VTY_DECLVAR_CONTEXT(structname, ptr)                                   \
     275             :         struct structname *ptr = VTY_GET_CONTEXT(structname);                  \
     276             :         VTY_CHECK_CONTEXT(ptr);
     277             : #define VTY_DECLVAR_CONTEXT_SUB(structname, ptr)                               \
     278             :         struct structname *ptr = VTY_GET_CONTEXT_SUB(structname);              \
     279             :         VTY_CHECK_CONTEXT(ptr);
     280             : #define VTY_DECLVAR_INSTANCE_CONTEXT(structname, ptr)                          \
     281             :         if (vty->qobj_index == 0)                                              \
     282             :                 return CMD_NOT_MY_INSTANCE;                                    \
     283             :         struct structname *ptr = VTY_GET_CONTEXT(structname);                  \
     284             :         VTY_CHECK_CONTEXT(ptr);
     285             : 
     286             : #define VTY_DECLVAR_CONTEXT_VRF(vrfptr)                                        \
     287             :         struct vrf *vrfptr;                                                    \
     288             :         if (vty->node == CONFIG_NODE)                                          \
     289             :                 vrfptr = vrf_lookup_by_id(VRF_DEFAULT);                        \
     290             :         else                                                                   \
     291             :                 vrfptr = VTY_GET_CONTEXT(vrf);                                 \
     292             :         VTY_CHECK_CONTEXT(vrfptr);                                             \
     293             :         MACRO_REQUIRE_SEMICOLON() /* end */
     294             : 
     295             : /* XPath macros. */
     296             : #define VTY_PUSH_XPATH(nodeval, value)                                         \
     297             :         do {                                                                   \
     298             :                 if (vty->xpath_index >= VTY_MAXDEPTH) {                        \
     299             :                         vty_out(vty, "%% Reached maximum CLI depth (%u)\n",    \
     300             :                                 VTY_MAXDEPTH);                                 \
     301             :                         return CMD_WARNING;                                    \
     302             :                 }                                                              \
     303             :                 vty->node = nodeval;                                           \
     304             :                 strlcpy(vty->xpath[vty->xpath_index], value,                   \
     305             :                         sizeof(vty->xpath[0]));                                \
     306             :                 vty->xpath_index++;                                            \
     307             :         } while (0)
     308             : 
     309             : #define VTY_CURR_XPATH vty->xpath[vty->xpath_index - 1]
     310             : 
     311             : #define VTY_CHECK_XPATH                                                        \
     312             :         do {                                                                   \
     313             :                 if (vty->type != VTY_FILE && !vty->private_config &&           \
     314             :                     vty->xpath_index > 0 &&                                    \
     315             :                     !yang_dnode_exists(vty->candidate_config->dnode,           \
     316             :                                        VTY_CURR_XPATH)) {                      \
     317             :                         vty_out(vty,                                           \
     318             :                                 "Current configuration object was deleted "    \
     319             :                                 "by another process.\n\n");                    \
     320             :                         return CMD_WARNING;                                    \
     321             :                 }                                                              \
     322             :         } while (0)
     323             : 
     324             : struct vty_arg {
     325             :         const char *name;
     326             :         const char *value;
     327             :         const char **argv;
     328             :         int argc;
     329             : };
     330             : 
     331             : /* Integrated configuration file. */
     332             : #define INTEGRATE_DEFAULT_CONFIG "frr.conf"
     333             : 
     334             : /* Default time out value */
     335             : #define VTY_TIMEOUT_DEFAULT 600
     336             : 
     337             : /* Vty read buffer size. */
     338             : #define VTY_READ_BUFSIZ 512
     339             : 
     340             : /* Directory separator. */
     341             : #ifndef DIRECTORY_SEP
     342             : #define DIRECTORY_SEP '/'
     343             : #endif /* DIRECTORY_SEP */
     344             : 
     345             : #ifndef IS_DIRECTORY_SEP
     346             : #define IS_DIRECTORY_SEP(c) ((c) == DIRECTORY_SEP)
     347             : #endif
     348             : 
     349             : extern struct nb_config *vty_mgmt_candidate_config;
     350             : extern bool vty_log_commands;
     351             : 
     352             : extern char const *const mgmt_daemons[];
     353             : extern uint mgmt_daemons_count;
     354             : 
     355             : /* Prototypes. */
     356             : extern void vty_init(struct event_loop *m, bool do_command_logging);
     357             : extern void vty_init_vtysh(void);
     358             : extern void vty_terminate(void);
     359             : extern void vty_reset(void);
     360             : extern struct vty *vty_new(void);
     361             : extern struct vty *vty_stdio(void (*atclose)(int isexit));
     362             : 
     363             : /* - vty_frame() output goes to a buffer (for context-begin markers)
     364             :  * - vty_out() will first print this buffer, and clear it
     365             :  * - vty_endframe() clears the buffer without printing it, and prints an
     366             :  *   extra string if the buffer was empty before (for context-end markers)
     367             :  */
     368             : extern int vty_out(struct vty *, const char *, ...) PRINTFRR(2, 3);
     369             : extern void vty_frame(struct vty *, const char *, ...) PRINTFRR(2, 3);
     370             : extern void vty_endframe(struct vty *, const char *);
     371             : extern bool vty_set_include(struct vty *vty, const char *regexp);
     372             : /* returns CMD_SUCCESS so you can do a one-line "return vty_json(...)"
     373             :  * NULL check and json_object_free() is included.
     374             :  *
     375             :  * _no_pretty means do not add a bunch of newlines and dump the output
     376             :  * as densely as possible.
     377             :  */
     378             : extern int vty_json(struct vty *vty, struct json_object *json);
     379             : extern int vty_json_no_pretty(struct vty *vty, struct json_object *json);
     380             : extern void vty_json_empty(struct vty *vty, struct json_object *json);
     381             : /* post fd to be passed to the vtysh client
     382             :  * fd is owned by the VTY code after this and will be closed when done
     383             :  */
     384             : extern void vty_pass_fd(struct vty *vty, int fd);
     385             : 
     386             : extern FILE *vty_open_config(const char *config_file, char *config_default_dir);
     387             : extern bool vty_read_config(struct nb_config *config, const char *config_file,
     388             :                             char *config_default_dir);
     389             : extern void vty_read_file(struct nb_config *config, FILE *confp);
     390             : extern void vty_read_file_finish(struct vty *vty, struct nb_config *config);
     391             : extern void vty_time_print(struct vty *, int);
     392             : extern void vty_serv_start(const char *, unsigned short, const char *);
     393             : extern void vty_serv_stop(void);
     394             : extern void vty_close(struct vty *);
     395             : extern char *vty_get_cwd(void);
     396             : extern void vty_update_xpath(const char *oldpath, const char *newpath);
     397             : extern int vty_config_enter(struct vty *vty, bool private_config,
     398             :                             bool exclusive, bool file_lock);
     399             : extern void vty_config_exit(struct vty *);
     400             : extern int vty_config_node_exit(struct vty *);
     401             : extern int vty_shell(struct vty *);
     402             : extern int vty_shell_serv(struct vty *);
     403             : extern void vty_hello(struct vty *);
     404             : 
     405             : /* ^Z / SIGTSTP handling */
     406             : extern void vty_stdio_suspend(void);
     407             : extern void vty_stdio_resume(void);
     408             : extern void vty_stdio_close(void);
     409             : 
     410             : extern void vty_init_mgmt_fe(void);
     411             : extern bool vty_mgmt_fe_enabled(void);
     412             : extern bool vty_mgmt_should_process_cli_apply_changes(struct vty *vty);
     413             : 
     414             : extern bool mgmt_vty_read_configs(void);
     415             : extern int vty_mgmt_send_config_data(struct vty *vty, const char *xpath_base,
     416             :                                      bool implicit_commit);
     417             : extern int vty_mgmt_send_commit_config(struct vty *vty, bool validate_only,
     418             :                                        bool abort);
     419             : extern int vty_mgmt_send_get_req(struct vty *vty, bool is_config,
     420             :                                  Mgmtd__DatastoreId datastore,
     421             :                                  const char **xpath_list, int num_req);
     422             : extern int vty_mgmt_send_lockds_req(struct vty *vty, Mgmtd__DatastoreId ds_id,
     423             :                                     bool lock, bool scok);
     424             : extern void vty_mgmt_resume_response(struct vty *vty, bool success);
     425             : 
     426           0 : static inline bool vty_needs_implicit_commit(struct vty *vty)
     427             : {
     428           0 :         return frr_get_cli_mode() == FRR_CLI_CLASSIC && !vty->pending_allowed;
     429             : }
     430             : 
     431             : #ifdef __cplusplus
     432             : }
     433             : #endif
     434             : 
     435             : #endif /* _ZEBRA_VTY_H */

Generated by: LCOV version v1.16-topotato