]>
Commit | Line | Data |
---|---|---|
774ebb6d QY |
1 | .. _vtysh: |
2 | ||
3 | ***** | |
4 | VTYSH | |
5 | ***** | |
6 | ||
7 | .. seealso:: :ref:`command-line-interface` | |
8 | ||
9 | .. _vtysh-architecture: | |
10 | ||
11 | Architecture | |
12 | ============ | |
13 | ||
14 | VTYSH is a shell for FRR daemons. It amalgamates all the CLI commands defined | |
15 | in each of the daemons and presents them to the user in a single shell, which | |
16 | saves the user from having to telnet to each of the daemons and use their | |
17 | individual shells. The amalgamation is achieved by | |
18 | :ref:`extracting <vtysh-command-extraction>` commands from daemons and | |
19 | injecting them into VTYSH at build time. | |
20 | ||
21 | At runtime, VTYSH maintains an instance of a CLI mode tree just like each | |
22 | daemon. However, the mode tree in VTYSH contains (almost) all commands from | |
23 | every daemon in the same tree, whereas individual daemons have trees that only | |
24 | contain commands relevant to themselves. VTYSH also uses the library CLI | |
25 | facilities to maintain the user's current position in the tree (the current | |
26 | node). Note that this position must be synchronized with all daemons; if a | |
27 | daemon receives a command that causes it to change its current node, VTYSH must | |
28 | also change its node. Since the extraction script does not understand the | |
29 | handler code of commands, but only their definitions, this and other behaviors | |
30 | must be manually programmed into VTYSH for every case where the internal state | |
31 | of VTYSH must change in response to a command. Details on how this is done are | |
32 | discussed in the :ref:`vtysh-special-defuns` section. | |
33 | ||
34 | VTYSH also handles writing and applying the integrated configuration file, | |
35 | :file:`/etc/frr/frr.conf`. Since it has knowledge of the entire command space | |
36 | of FRR, it can intelligently distribute configuration commands only to the | |
37 | daemons that understand them. Similarly, when writing the configuration file it | |
38 | takes care of combining multiple instances of configuration blocks and | |
39 | simplifying the output. This is discussed in :ref:`vtysh-configuration`. | |
40 | ||
41 | .. _vtysh-command-extraction: | |
42 | ||
43 | Command Extraction | |
44 | ------------------ | |
45 | ||
89cb86ae DL |
46 | To build ``vtysh``, the :file:`python/xref2vtysh.py` script scans through the |
47 | :file:`frr.xref` file created earlier in the build process. This file contains | |
48 | a list of all ``DEFUN`` and ``install_element`` sites in the code, generated | |
49 | directly from the binaries (and therefore matching exactly what is really | |
50 | available.) | |
51 | ||
52 | This list is collated and transformed into ``DEFSH`` (and ``install_element``) | |
53 | statements, output to ``vtysh_cmd.c``. Each ``DEFSH`` | |
774ebb6d QY |
54 | contains the name of the command plus ``_vtysh``, as well as a flag that |
55 | indicates which daemons the command was found in. When the command is executed | |
56 | in VTYSH, this flag is inspected to determine which daemons to send the command | |
57 | to. This way, commands are only sent to the daemons that know about them, | |
58 | avoiding spurious errors from daemons that don't have the command defined. | |
59 | ||
60 | The extraction script contains lots of hardcoded knowledge about what sources | |
61 | to look at and what flags to use for certain commands. | |
62 | ||
89cb86ae DL |
63 | .. note:: |
64 | ||
65 | The ``vtysh_scan`` Makefile variable and ``#ifndef VTYSH_EXTRACT_PL`` | |
66 | checks in source files are no longer used. Remove them when rebasing older | |
67 | changes. | |
68 | ||
774ebb6d QY |
69 | .. _vtysh-special-defuns: |
70 | ||
71 | Special DEFUNs | |
72 | -------------- | |
73 | ||
74 | In addition to the vanilla ``DEFUN`` macro for defining CLI commands, there are | |
75 | several VTYSH-specific ``DEFUN`` variants that each serve different purposes. | |
76 | ||
77 | ``DEFSH`` | |
78 | Used almost exclusively by generated VTYSH code. This macro defines a | |
79 | ``cmd_element`` with no handler function; the command, when executed, is | |
80 | simply forwarded to the daemons indicated in the daemon flag. | |
81 | ||
82 | ``DEFUN_NOSH`` | |
89cb86ae | 83 | Used by daemons. Has the same expansion as a ``DEFUN``, but ``xref2vtysh.py`` |
774ebb6d QY |
84 | will skip these definitions when extracting commands. This is typically used |
85 | when VTYSH must take some special action upon receiving the command, and the | |
86 | programmer therefore needs to write VTYSH's copy of the command manually | |
87 | instead of using the generated version. | |
88 | ||
89 | ``DEFUNSH`` | |
90 | The same as ``DEFUN``, but with an argument that allows specifying the | |
91 | ``->daemon`` field of the generated ``cmd_element``. This is used by VTYSH | |
92 | to determine which daemons to send the command to. | |
93 | ||
94 | ``DEFUNSH_ATTR`` | |
95 | A version of ``DEFUNSH`` that allows setting the ``->attr`` field of the | |
96 | generated ``cmd_element``. Not used in practice. | |
97 | ||
98 | .. _vtysh-configuration: | |
99 | ||
100 | Configuration Management | |
101 | ------------------------ | |
102 | ||
103 | When integrated configuration is used, VTYSH manages writing, reading and | |
104 | applying the FRR configuration file. VTYSH can be made to read and apply an | |
105 | integrated configuration to all running daemons by launching it with ``-f | |
106 | <file>``. It sends the appropriate configuration lines to the relevant daemons | |
107 | in the same way that commands entered by the user on VTYSH's shell prompt are | |
108 | processed. | |
109 | ||
110 | Configuration writing is more complicated. VTYSH makes a best-effort attempt to | |
111 | combine and simplify the configuration as much as possible. A working example | |
112 | is best to explain this behavior. | |
113 | ||
114 | Example | |
115 | ^^^^^^^ | |
116 | ||
117 | Suppose we have just *staticd* and *zebra* running on the system, and use VTYSH | |
118 | to apply the following configuration snippet: | |
119 | ||
120 | .. code-block:: frr | |
121 | ||
122 | ! | |
123 | vrf blue | |
124 | ip protocol static route-map ExampleRoutemap | |
125 | ip route 192.168.0.0/24 192.168.0.1 | |
126 | exit-vrf | |
127 | ! | |
128 | ||
129 | Note that *staticd* defines static route commands and *zebra* defines ``ip | |
130 | protocol`` commands. Therefore if we ask only *zebra* for its configuration, we | |
131 | get the following:: | |
132 | ||
133 | (config)# do sh running-config zebra | |
134 | Building configuration... | |
135 | ||
136 | ... | |
137 | ! | |
138 | vrf blue | |
139 | ip protocol static route-map ExampleRoutemap | |
140 | exit-vrf | |
141 | ! | |
142 | ... | |
143 | ||
144 | Note that the static route doesn't show up there. Similarly, if we ask | |
503efc38 | 145 | *staticd* for its configuration, we get:: |
774ebb6d QY |
146 | |
147 | (config)# do sh running-config staticd | |
148 | ||
149 | ... | |
150 | ! | |
151 | vrf blue | |
152 | ip route 192.168.0.0/24 192.168.0.1 | |
153 | exit-vrf | |
154 | ! | |
155 | ... | |
156 | ||
157 | But when we display the configuration with VTYSH, we see:: | |
158 | ||
159 | ubuntu-bionic(config)# do sh running-config | |
160 | ||
161 | ... | |
162 | ! | |
163 | vrf blue | |
164 | ip protocol static route-map ExampleRoutemap | |
165 | ip route 192.168.0.0/24 192.168.0.1 | |
166 | exit-vrf | |
167 | ! | |
168 | ... | |
169 | ||
170 | This is because VTYSH asks each daemon for its currently running configuration, | |
171 | and combines equivalent blocks together. In the above example, it combined the | |
172 | ``vrf blue`` blocks from both *zebra* and *staticd* together into one. This is | |
173 | done in :file:`vtysh_config.c`. | |
503efc38 QY |
174 | |
175 | Protocol | |
176 | ======== | |
177 | ||
178 | VTYSH communicates with FRR daemons by way of domain socket. Each daemon | |
179 | creates its own socket, typically in :file:`/var/run/frr/<daemon>.vty`. The | |
180 | protocol is very simple. In the VTYSH to daemon direction, messages are simply | |
56f0bea7 | 181 | NUL-terminated strings, whose content are CLI commands. Here is a typical |
503efc38 QY |
182 | message from VTYSH to a daemon: |
183 | ||
184 | :: | |
185 | ||
186 | Request | |
187 | ||
188 | 00000000: 646f 2077 7269 7465 2074 6572 6d69 6e61 do write termina | |
189 | 00000010: 6c0a 00 l.. | |
190 | ||
191 | ||
56f0bea7 | 192 | The response format has some more data in it. First is a NUL-terminated string |
503efc38 QY |
193 | containing the plaintext response, which is just the output of the command that |
194 | was sent in the request. This is displayed to the user. The plaintext response | |
195 | is followed by 3 null marker bytes, followed by a 1-byte status code that | |
196 | indicates whether the command was successful or not. | |
197 | ||
198 | :: | |
199 | ||
200 | Response | |
201 | ||
202 | 0 1 2 3 | |
203 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |
204 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
205 | | Plaintext Response | | |
206 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
207 | | Marker (0x00) | Status Code | | |
208 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
209 | ||
210 | ||
211 | The first ``0x00`` byte in the marker also serves to terminate the plaintext | |
212 | response. |