]>
Commit | Line | Data |
---|---|---|
281ba953 QY |
1 | .. _command-line-interface: |
2 | ||
a42f7818 QY |
3 | Command Line Interface |
4 | ====================== | |
d1890d04 | 5 | |
a42f7818 QY |
6 | FRR features a flexible modal command line interface. Often when adding new |
7 | features or modifying existing code it is necessary to create or modify CLI | |
8 | commands. FRR has a powerful internal CLI system that does most of the heavy | |
9 | lifting for you. | |
d1890d04 | 10 | |
cb3d8153 QY |
11 | Modes |
12 | ----- | |
13 | FRR's CLI is organized by modes. Each mode is associated with some set of | |
14 | functionality, e.g. EVPN, or some underlying object such as an interface. Each | |
15 | mode contains a set of commands that control the associated functionality or | |
16 | object. Users move between the modes by entering a command, which is usually | |
17 | different for each source and destination mode. | |
18 | ||
19 | A summary of the modes is given in the following figure. | |
20 | ||
21 | .. graphviz:: ../figures/nodes.dot | |
22 | ||
23 | .. seealso:: :ref:`cli-data-structures` | |
24 | ||
25 | Walkup | |
26 | ^^^^^^ | |
27 | FRR exhibits, for historical reasons, a peculiar behavior called 'walkup'. | |
28 | Suppose a user is in ``OSPF_NODE``, which contains only OSPF-specific commands, | |
29 | and enters the following command: :: | |
30 | ||
31 | ip route 192.168.100.0/24 10.0.2.2 | |
32 | ||
33 | This command is not defined in ``OSPF_NODE``, so the matcher will fail to match | |
34 | the command in that node. The matcher will then check "parent" nodes of | |
35 | ``OSPF_NODE``. In this case the direct parent of ``OSPF_NODE`` is | |
36 | ``CONFIG_NODE``, so the current node switches to ``CONFIG_NODE`` and the command | |
37 | is tried in that node. Since static route commands are defined in | |
38 | ``CONFIG_NODE`` the command succeeds. The procedure of attempting to execute | |
39 | unmatched commands by sequentially "walking up" to parent nodes only happens in | |
40 | children (direct and indirect) below ``CONFIG_NODE`` and stops at | |
41 | ``CONFIG_NODE``. | |
42 | ||
43 | Unfortunately, the internal representation of the various modes is not actually | |
44 | a graph. Instead, there is an array. The parent-child relationships are not | |
45 | explicitly defined in any datastructure but instead are hard-coded into the | |
46 | specific commands that switch nodes. For walkup, there is a function that takes | |
47 | a node and returns the parent of the node. This interface causes all manner of | |
48 | insidious problems, even for experienced developers, and needs to be fixed at | |
49 | some point in the future. | |
50 | ||
51 | Defining Commands | |
52 | ----------------- | |
a42f7818 QY |
53 | All definitions for the CLI system are exposed in ``lib/command.h``. In this |
54 | header there are a set of macros used to define commands. These macros are | |
55 | collectively referred to as "DEFUNs", because of their syntax: | |
d1890d04 QY |
56 | |
57 | :: | |
58 | ||
a42f7818 QY |
59 | DEFUN(command_name, |
60 | command_name_cmd, | |
61 | "example command FOO...", | |
62 | "Examples\n" | |
63 | "CLI command\n" | |
64 | "Argument\n") | |
65 | { | |
66 | // ...command handler... | |
67 | } | |
68 | ||
69 | DEFUNs generally take four arguments which are expanded into the appropriate | |
70 | constructs for hooking into the CLI. In order these are: | |
71 | ||
72 | - **Function name** - the name of the handler function for the command | |
73 | - **Command name** - the identifier of the ``struct cmd_element`` for the | |
74 | command. By convention this should be the function name with ``_cmd`` | |
75 | appended. | |
76 | - **Command definition** - an expression in FRR's CLI grammar that defines the | |
77 | form of the command and its arguments, if any | |
78 | - **Doc string** - a newline-delimited string that documents each element in | |
79 | the command definition | |
80 | ||
81 | In the above example, ``command_name`` is the function name, | |
cb3d8153 QY |
82 | ``command_name_cmd`` is the command name, ``"example..."`` is the definition and |
83 | the last argument is the doc string. The block following the macro is the body | |
84 | of the handler function, details on which are presented later in this section. | |
a42f7818 QY |
85 | |
86 | In order to make the command show up to the user it must be installed into the | |
87 | CLI graph. To do this, call: | |
88 | ||
89 | ``install_element(NODE, &command_name_cmd);`` | |
90 | ||
91 | This will install the command into the specified CLI node. Usually these calls | |
cb3d8153 QY |
92 | are grouped together in a CLI initialization function for a set of commands, and |
93 | the DEFUNs themselves are grouped into the same source file to avoid cluttering | |
94 | the codebase. The names of these files follow the form ``*_vty.[ch]`` by | |
95 | convention. Please do not scatter individual CLI commands in the middle of | |
96 | source files; instead expose the necessary functions in a header and place the | |
97 | command definition in a ``*_vty.[ch]`` file. | |
d1890d04 | 98 | |
a42f7818 | 99 | Definition Grammar |
cb3d8153 | 100 | ^^^^^^^^^^^^^^^^^^ |
a42f7818 QY |
101 | FRR uses its own grammar for defining CLI commands. The grammar draws from |
102 | syntax commonly seen in \*nix manpages and should be fairly intuitive. The | |
103 | parser is implemented in Bison and the lexer in Flex. These may be found in | |
45569976 | 104 | ``lib/command_parse.y`` and ``lib/command_lex.l``, respectively. |
d1890d04 | 105 | |
a42f7818 QY |
106 | **ProTip**: if you define a new command and find that the parser is |
107 | throwing syntax or other errors, the parser is the last place you want | |
108 | to look. Bison is very stable and if it detects a syntax error, 99% of | |
109 | the time it will be a syntax error in your definition. | |
d1890d04 | 110 | |
cb3d8153 QY |
111 | The formal grammar in BNF is given below. This is the grammar implemented in the |
112 | Bison parser. At runtime, the Bison parser reads all of the CLI strings and | |
113 | builds a combined directed graph that is used to match and interpret user input. | |
e53d5853 QY |
114 | |
115 | Human-friendly explanations of how to use this grammar are given a bit later in | |
116 | this section alongside information on the :ref:`cli-data-structures` constructed | |
117 | by the parser. | |
118 | ||
119 | .. productionlist:: | |
120 | command: `cmd_token_seq` | |
121 | : `cmd_token_seq` `placeholder_token` "..." | |
122 | cmd_token_seq: *empty* | |
123 | : `cmd_token_seq` `cmd_token` | |
124 | cmd_token: `simple_token` | |
125 | : `selector` | |
126 | simple_token: `literal_token` | |
127 | : `placeholder_token` | |
128 | literal_token: WORD `varname_token` | |
129 | varname_token: "$" WORD | |
130 | placeholder_token: `placeholder_token_real` `varname_token` | |
131 | placeholder_token_real: IPV4 | |
132 | : IPV4_PREFIX | |
133 | : IPV6 | |
134 | : IPV6_PREFIX | |
135 | : VARIABLE | |
136 | : RANGE | |
137 | : MAC | |
138 | : MAC_PREFIX | |
139 | selector: "<" `selector_seq_seq` ">" `varname_token` | |
140 | : "{" `selector_seq_seq` "}" `varname_token` | |
141 | : "[" `selector_seq_seq` "]" `varname_token` | |
90c8406c | 142 | : "![" `selector_seq_seq` "]" `varname_token` |
e53d5853 QY |
143 | selector_seq_seq: `selector_seq_seq` "|" `selector_token_seq` |
144 | : `selector_token_seq` | |
145 | selector_token_seq: `selector_token_seq` `selector_token` | |
146 | : `selector_token` | |
147 | selector_token: `selector` | |
148 | : `simple_token` | |
149 | ||
d1890d04 | 150 | Tokens |
cb3d8153 | 151 | ^^^^^^ |
e53d5853 QY |
152 | The various capitalized tokens in the BNF above are in fact themselves |
153 | placeholders, but not defined as such in the formal grammar; the grammar | |
154 | provides the structure, and the tokens are actually more like a type system for | |
cb3d8153 QY |
155 | the strings you write in your CLI definitions. A CLI definition string is broken |
156 | apart and each piece is assigned a type by the lexer based on a set of regular | |
157 | expressions. The parser uses the type information to verify the string and | |
158 | determine the structure of the CLI graph; additional metadata (such as the raw | |
159 | text of each token) is encoded into the graph as it is constructed by the | |
e53d5853 QY |
160 | parser, but this is merely a dumb copy job. |
161 | ||
162 | Here is a brief summary of the various token types along with examples. | |
a42f7818 | 163 | |
f65d330c IR |
164 | +-----------------+-------------------+-------------------------------------------------------------+ |
165 | | Token type | Syntax | Description | | |
166 | +=================+===================+=============================================================+ | |
167 | | ``WORD`` | ``show ip bgp`` | Matches itself. In the given example every token is a WORD. | | |
168 | +-----------------+-------------------+-------------------------------------------------------------+ | |
169 | | ``IPV4`` | ``A.B.C.D`` | Matches an IPv4 address. | | |
170 | +-----------------+-------------------+-------------------------------------------------------------+ | |
171 | | ``IPV6`` | ``X:X::X:X`` | Matches an IPv6 address. | | |
172 | +-----------------+-------------------+-------------------------------------------------------------+ | |
173 | | ``IPV4_PREFIX`` | ``A.B.C.D/M`` | Matches an IPv4 prefix in CIDR notation. | | |
174 | +-----------------+-------------------+-------------------------------------------------------------+ | |
175 | | ``IPV6_PREFIX`` | ``X:X::X:X/M`` | Matches an IPv6 prefix in CIDR notation. | | |
176 | +-----------------+-------------------+-------------------------------------------------------------+ | |
177 | | ``MAC`` | ``X:X:X:X:X:X`` | Matches a 48-bit mac address. | | |
178 | +-----------------+-------------------+-------------------------------------------------------------+ | |
179 | | ``MAC_PREFIX`` | ``X:X:X:X:X:X/M`` | Matches a 48-bit mac address with a mask. | | |
180 | +-----------------+-------------------+-------------------------------------------------------------+ | |
181 | | ``VARIABLE`` | ``FOOBAR`` | Matches anything. | | |
182 | +-----------------+-------------------+-------------------------------------------------------------+ | |
183 | | ``RANGE`` | ``(X-Y)`` | Matches numbers in the range X..Y inclusive. | | |
184 | +-----------------+-------------------+-------------------------------------------------------------+ | |
a42f7818 QY |
185 | |
186 | When presented with user input, the parser will search over all defined | |
187 | commands in the current context to find a match. It is aware of the various | |
188 | types of user input and has a ranking system to help disambiguate commands. For | |
189 | instance, suppose the following commands are defined in the user's current | |
190 | context: | |
d1890d04 | 191 | |
a42f7818 | 192 | :: |
d1890d04 | 193 | |
cb3d8153 QY |
194 | example command FOO |
195 | example command (22-49) | |
196 | example command A.B.C.D/X | |
a42f7818 QY |
197 | |
198 | The following table demonstrates the matcher's choice for a selection of | |
199 | possible user input. | |
200 | ||
cb3d8153 QY |
201 | +---------------------------------+---------------------------+--------------------------------------------------------------------------------------------------------------+ |
202 | | Input | Matched command | Reason | | |
203 | +=================================+===========================+==============================================================================================================+ | |
204 | | ``example command eLi7eH4xx0r`` | example command FOO | ``eLi7eH4xx0r`` is not an integer or IPv4 prefix, | | |
205 | | | | but FOO is a variable and matches all input. | | |
206 | +---------------------------------+---------------------------+--------------------------------------------------------------------------------------------------------------+ | |
207 | | ``example command 42`` | example command (22-49) | ``42`` is not an IPv4 prefix. It does match both | | |
208 | | | | ``(22-49)`` and ``FOO``, but RANGE tokens are more specific and have a higher priority than VARIABLE tokens. | | |
209 | +---------------------------------+---------------------------+--------------------------------------------------------------------------------------------------------------+ | |
210 | | ``example command 10.3.3.0/24`` | example command A.B.C.D/X | The user entered an IPv4 prefix, which is best matched by the last command. | | |
211 | +---------------------------------+---------------------------+--------------------------------------------------------------------------------------------------------------+ | |
a42f7818 QY |
212 | |
213 | Rules | |
cb3d8153 QY |
214 | ^^^^^ |
215 | There are also constructs which allow optional tokens, mutual exclusion, | |
216 | one-or-more selection and repetition. | |
a42f7818 QY |
217 | |
218 | - ``<angle|brackets>`` -- Contain sequences of tokens separated by pipes and | |
219 | provide mutual exclusion. User input matches at most one option. | |
220 | - ``[square brackets]`` -- Contains sequences of tokens that can be omitted. | |
221 | ``[<a|b>]`` can be shortened to ``[a|b]``. | |
90c8406c DL |
222 | - ``![exclamation square brackets]`` -- same as ``[square brackets]``, but |
223 | only allow skipping the contents if the command input starts with ``no``. | |
224 | (For cases where the positive command needs a parameter, but the parameter | |
225 | is optional for the negative case.) | |
a42f7818 QY |
226 | - ``{curly|braces}`` -- similar to angle brackets, but instead of mutual |
227 | exclusion, curly braces indicate that one or more of the pipe-separated | |
228 | sequences may be provided in any order. | |
229 | - ``VARIADICS...`` -- Any token which accepts input (anything except WORD) | |
230 | which occurs as the last token of a line may be followed by an ellipsis, | |
231 | which indicates that input matching the token may be repeated an unlimited | |
232 | number of times. | |
d1890d04 QY |
233 | - ``$name`` -- Specify a variable name for the preceding token. See |
234 | "Variable Names" below. | |
235 | ||
236 | Some general notes: | |
237 | ||
238 | - Options are allowed at the beginning of the command. The developer is | |
239 | entreated to use these extremely sparingly. They are most useful for | |
a42f7818 QY |
240 | implementing the 'no' form of configuration commands. Please think carefully |
241 | before using them for anything else. There is usually a better solution, even | |
242 | if it is just separating out the command definition into separate ones. | |
243 | - The developer should judiciously apply separation of concerns when defining | |
244 | commands. CLI definitions for two unrelated or vaguely related commands or | |
245 | configuration items should be defined in separate commands. Clarity is | |
246 | preferred over LOC (within reason). | |
d1890d04 QY |
247 | - The maximum number of space-separated tokens that can be entered is |
248 | presently limited to 256. Please keep this limit in mind when | |
249 | implementing new CLI. | |
250 | ||
251 | Variable Names | |
cb3d8153 QY |
252 | ^^^^^^^^^^^^^^ |
253 | The parser tries to fill the "varname" field on each token. This can happen | |
254 | either manually or automatically. Manual specifications work by appending | |
255 | ``$name`` after the input specifier: | |
d1890d04 QY |
256 | |
257 | :: | |
258 | ||
cb3d8153 | 259 | foo bar$cmd WORD$name A.B.C.D$ip |
d1890d04 | 260 | |
cb3d8153 QY |
261 | Note that you can also assign variable names to fixed input tokens, this can be |
262 | useful if multiple commands share code. You can also use "$name" after a | |
263 | multiple-choice option: | |
d1890d04 QY |
264 | |
265 | :: | |
266 | ||
cb3d8153 | 267 | foo bar <A.B.C.D|X:X::X:X>$addr [optionA|optionB]$mode |
d1890d04 | 268 | |
cb3d8153 QY |
269 | The variable name is in this case assigned to the last token in each of the |
270 | branches. | |
d1890d04 | 271 | |
cb3d8153 | 272 | Automatic assignment of variable names works by applying the following rules: |
d1890d04 QY |
273 | |
274 | - manual names always have priority | |
cb3d8153 QY |
275 | - a ``[no]`` at the beginning receives ``no`` as varname on the ``no`` token |
276 | - ``VARIABLE`` tokens whose text is not ``WORD`` or ``NAME`` receive a cleaned | |
277 | lowercase version of the token text as varname, e.g. ``ROUTE-MAP`` becomes | |
278 | ``route_map``. | |
279 | - other variable tokens (i.e. everything except "fixed") receive the text of | |
280 | the preceding fixed token as varname, if one can be found. E.g. | |
281 | ``ip route A.B.C.D/M INTERFACE`` assigns "route" to the ``A.B.C.D/M`` token. | |
d1890d04 | 282 | |
cb3d8153 QY |
283 | These rules should make it possible to avoid manual varname assignment in 90% of |
284 | the cases. | |
d1890d04 | 285 | |
cb3d8153 QY |
286 | Doc Strings |
287 | ^^^^^^^^^^^ | |
288 | Each token in a command definition should be documented with a brief doc string | |
289 | that informs a user of the meaning and/or purpose of the subsequent command | |
290 | tree. These strings are provided as the last parameter to DEFUN macros, | |
291 | concatenated together and separated by an escaped newline (``\n``). These are | |
292 | best explained by example. | |
d1890d04 | 293 | |
cb3d8153 QY |
294 | :: |
295 | ||
296 | DEFUN (config_terminal, | |
297 | config_terminal_cmd, | |
298 | "configure terminal", | |
299 | "Configuration from vty interface\n" | |
300 | "Configuration terminal\n") | |
301 | ||
302 | The last parameter is split into two lines for readability. Two newline | |
303 | delimited doc strings are present, one for each token in the command. The second | |
304 | string documents the functionality of the ``terminal`` command in the | |
305 | ``configure`` subtree. | |
306 | ||
307 | Note that the first string, for ``configure`` does not contain documentation for | |
308 | 'terminal'. This is because the CLI is best envisioned as a tree, with tokens | |
309 | defining branches. An imaginary ``start`` token is the root of every command in | |
310 | a CLI node. Each subsequent written token descends into a subtree, so the | |
311 | documentation for that token ideally summarizes all the functionality contained | |
312 | in the subtree. | |
313 | ||
314 | A consequence of this structure is that the developer must be careful to use the | |
315 | same doc strings when defining multiple commands that are part of the same tree. | |
316 | Commands which share prefixes must share the same doc strings for those | |
317 | prefixes. On startup the parser will generate warnings if it notices | |
318 | inconsistent doc strings. Behavior is undefined; the same token may show up | |
319 | twice in completions, with different doc strings, or it may show up once with a | |
320 | random doc string. Parser warnings should be heeded and fixed to avoid confusing | |
321 | users. | |
322 | ||
323 | The number of doc strings provided must be equal to the amount of tokens present | |
324 | in the command definition, read left to right, ignoring any special constructs. | |
325 | ||
326 | In the examples below, each arrowed token needs a doc string. | |
d1890d04 QY |
327 | |
328 | :: | |
329 | ||
cb3d8153 QY |
330 | "show ip bgp" |
331 | ^ ^ ^ | |
332 | ||
333 | "command <foo|bar> [example]" | |
334 | ^ ^ ^ ^ | |
335 | ||
336 | DEFPY | |
337 | ^^^^^ | |
338 | ``DEFPY(...)`` is an enhanced version of ``DEFUN()`` which is preprocessed by | |
339 | :file:`python/clidef.py`. The python script parses the command definition | |
340 | string, extracts variable names and types, and generates a C wrapper function | |
341 | that parses the variables and passes them on. This means that in the CLI | |
342 | function body, you will receive additional parameters with appropriate types. | |
343 | ||
344 | This is best explained by an example. Invoking ``DEFPY`` like this: | |
345 | ||
346 | .. code-block:: c | |
347 | ||
348 | DEFPY(func, func_cmd, "[no] foo bar A.B.C.D (0-99)$num", "...help...") | |
d1890d04 | 349 | |
cb3d8153 | 350 | defines the handler function like this: |
d1890d04 | 351 | |
cb3d8153 | 352 | .. code-block:: c |
d1890d04 | 353 | |
cb3d8153 QY |
354 | func(self, vty, argc, argv, /* standard CLI arguments */ |
355 | const char *no, /* unparsed "no" */ | |
356 | struct in_addr bar, /* parsed IP address */ | |
357 | const char *bar_str, /* unparsed IP address */ | |
358 | long num, /* parsed num */ | |
359 | const char *num_str) /* unparsed num */ | |
d1890d04 | 360 | |
cb3d8153 QY |
361 | Note that as documented in the previous section, ``bar`` is automatically |
362 | applied as variable name for ``A.B.C.D``. The Python script then detects this as | |
363 | an IP address argument and generates code to parse it into a ``struct in_addr``, | |
364 | passing it in ``bar``. The raw value is passed in ``bar_str``. The range/number | |
365 | argument works in the same way with the explicitly given variable name. | |
d1890d04 QY |
366 | |
367 | Type rules | |
cb3d8153 QY |
368 | """""""""" |
369 | ||
370 | +----------------------------+--------------------------------+--------------------------+ | |
371 | | Token(s) | Type | Value if omitted by user | | |
372 | +============================+================================+==========================+ | |
373 | | ``A.B.C.D`` | ``struct in_addr`` | ``0.0.0.0`` | | |
374 | +----------------------------+--------------------------------+--------------------------+ | |
375 | | ``X:X::X:X`` | ``struct in6_addr`` | ``::`` | | |
376 | +----------------------------+--------------------------------+--------------------------+ | |
377 | | ``A.B.C.D + X:X::X:X`` | ``const union sockunion *`` | ``NULL`` | | |
378 | +----------------------------+--------------------------------+--------------------------+ | |
05c6b1e4 | 379 | | ``A.B.C.D/M`` | ``const struct prefix_ipv4 *`` | ``all-zeroes struct`` | |
cb3d8153 | 380 | +----------------------------+--------------------------------+--------------------------+ |
05c6b1e4 | 381 | | ``X:X::X:X/M`` | ``const struct prefix_ipv6 *`` | ``all-zeroes struct`` | |
cb3d8153 | 382 | +----------------------------+--------------------------------+--------------------------+ |
05c6b1e4 | 383 | | ``A.B.C.D/M + X:X::X:X/M`` | ``const struct prefix *`` | ``all-zeroes struct`` | |
cb3d8153 QY |
384 | +----------------------------+--------------------------------+--------------------------+ |
385 | | ``(0-9)`` | ``long`` | ``0`` | | |
386 | +----------------------------+--------------------------------+--------------------------+ | |
387 | | ``VARIABLE`` | ``const char *`` | ``NULL`` | | |
388 | +----------------------------+--------------------------------+--------------------------+ | |
389 | | ``word`` | ``const char *`` | ``NULL`` | | |
390 | +----------------------------+--------------------------------+--------------------------+ | |
391 | | *all other* | ``const char *`` | ``NULL`` | | |
392 | +----------------------------+--------------------------------+--------------------------+ | |
d1890d04 QY |
393 | |
394 | Note the following details: | |
395 | ||
a42f7818 | 396 | - Not all parameters are pointers, some are passed as values. |
cb3d8153 QY |
397 | - When the type is not ``const char *``, there will be an extra ``_str`` |
398 | argument with type ``const char *``. | |
399 | - You can give a variable name not only to ``VARIABLE`` tokens but also to | |
400 | ``word`` tokens (e.g. constant words). This is useful if some parts of a | |
401 | command are optional. The type will be ``const char *``. | |
d1890d04 | 402 | - ``[no]`` will be passed as ``const char *no``. |
05c6b1e4 MS |
403 | - Most pointers will be ``NULL`` when the argument is optional and the |
404 | user did not supply it. As noted in the table above, some prefix | |
405 | struct type arguments are passed as pointers to all-zeroes structs, | |
406 | not as ``NULL`` pointers. | |
cb3d8153 QY |
407 | - If a parameter is not a pointer, but is optional and the user didn't use it, |
408 | the default value will be passed. Check the ``_str`` argument if you need to | |
409 | determine whether the parameter was omitted. | |
410 | - If the definition contains multiple parameters with the same variable name, | |
411 | they will be collapsed into a single function parameter. The python code will | |
412 | detect if the types are compatible (i.e. IPv4 + IPv6 variants) and choose a | |
413 | corresponding C type. | |
414 | - The standard DEFUN parameters (``self, vty, argc, argv``) are still present | |
415 | and can be used. A DEFUN can simply be **edited into a DEFPY without further | |
416 | changes and it will still work**; this allows easy forward migration. | |
417 | - A file may contain both ``DEFUN`` and ``DEFPY`` statements. | |
d1890d04 QY |
418 | |
419 | Getting a parameter dump | |
cb3d8153 QY |
420 | """""""""""""""""""""""" |
421 | The clidef.py script can be called to get a list of DEFUNs/DEFPYs with the | |
422 | parameter name/type list: | |
d1890d04 QY |
423 | |
424 | :: | |
425 | ||
cb3d8153 | 426 | lib/clippy python/clidef.py --all-defun --show lib/plist.c > /dev/null |
d1890d04 QY |
427 | |
428 | The generated code is printed to stdout, the info dump to stderr. The | |
cb3d8153 QY |
429 | ``--all-defun`` argument will make it process DEFUN blocks as well as DEFPYs, |
430 | which is useful prior to converting some DEFUNs. **The dump does not list the | |
431 | ``_str`` arguments** to keep the output shorter. | |
d1890d04 | 432 | |
cb3d8153 QY |
433 | Note that the ``clidef.py`` script cannot be run with python directly, it needs |
434 | to be run with *clippy* since the latter makes the CLI parser available. | |
d1890d04 QY |
435 | |
436 | Include & Makefile requirements | |
cb3d8153 QY |
437 | """"""""""""""""""""""""""""""" |
438 | A source file that uses DEFPY needs to include the ``*_clippy.c`` file **before | |
439 | all DEFPY statements**: | |
d1890d04 | 440 | |
cb3d8153 | 441 | .. code-block:: c |
d1890d04 | 442 | |
cb3d8153 QY |
443 | /* GPL header */ |
444 | #include ... | |
445 | ... | |
446 | #ifndef VTYSH_EXTRACT_PL | |
447 | #include "daemon/filename_clippy.c" | |
448 | #endif | |
d1890d04 | 449 | |
cb3d8153 QY |
450 | DEFPY(...) |
451 | DEFPY(...) | |
d1890d04 | 452 | |
cb3d8153 | 453 | install_element(...) |
d1890d04 | 454 | |
cb3d8153 QY |
455 | This dependency needs to be marked in ``Makefile.am`` or ``subdir.am``: (there |
456 | is no ordering requirement) | |
d1890d04 | 457 | |
cb3d8153 | 458 | .. code-block:: make |
d1890d04 | 459 | |
cb3d8153 | 460 | # ... |
d1890d04 | 461 | |
cb3d8153 QY |
462 | # if linked into a LTLIBRARY (.la/.so): |
463 | filename.lo: filename_clippy.c | |
d1890d04 | 464 | |
cb3d8153 QY |
465 | # if linked into an executable or static library (.a): |
466 | filename.o: filename_clippy.c | |
d1890d04 | 467 | |
cb3d8153 QY |
468 | Handlers |
469 | ^^^^^^^^ | |
470 | The block that follows a CLI definition is executed when a user enters input | |
471 | that matches the definition. Its function signature looks like this: | |
d1890d04 | 472 | |
cb3d8153 | 473 | .. code-block:: c |
d1890d04 | 474 | |
cb3d8153 | 475 | int (*func) (const struct cmd_element *, struct vty *, int, struct cmd_token *[]); |
d1890d04 | 476 | |
cb3d8153 QY |
477 | The first argument is the command definition struct. The last argument is an |
478 | ordered array of tokens that correspond to the path taken through the graph, and | |
479 | the argument just prior to that is the length of the array. | |
d1890d04 | 480 | |
cb3d8153 QY |
481 | The arrangement of the token array has changed from Quagga's CLI implementation. |
482 | In the old system, missing arguments were padded with ``NULL`` so that the same | |
483 | parts of a command would show up at the same indices regardless of what was | |
484 | entered. The new system does not perform such padding and therefore it is | |
485 | generally *incorrect* to assume consistent indices in this array. As a simple | |
486 | example: | |
487 | ||
488 | Command definition: | |
d1890d04 QY |
489 | |
490 | :: | |
491 | ||
cb3d8153 | 492 | command [foo] <bar|baz> |
d1890d04 | 493 | |
cb3d8153 | 494 | User enters: |
d1890d04 | 495 | |
cb3d8153 QY |
496 | :: |
497 | ||
498 | command foo bar | |
499 | ||
500 | Array: | |
501 | ||
502 | :: | |
503 | ||
504 | [0] -> command | |
505 | [1] -> foo | |
506 | [2] -> bar | |
507 | ||
508 | User enters: | |
d1890d04 QY |
509 | |
510 | :: | |
511 | ||
cb3d8153 QY |
512 | command baz |
513 | ||
514 | Array: | |
515 | ||
516 | :: | |
517 | ||
518 | [0] -> command | |
519 | [1] -> baz | |
d1890d04 | 520 | |
d1890d04 | 521 | |
e53d5853 QY |
522 | .. _cli-data-structures: |
523 | ||
d1890d04 QY |
524 | Data Structures |
525 | --------------- | |
cb3d8153 QY |
526 | On startup, the CLI parser sequentially parses each command string definition |
527 | and constructs a directed graph with each token forming a node. This graph is | |
528 | the basis of the entire CLI system. It is used to match user input in order to | |
529 | generate command completions and match commands to functions. | |
d1890d04 | 530 | |
cb3d8153 QY |
531 | There is one graph per CLI node (not the same as a graph node in the CLI graph). |
532 | The CLI node struct keeps a reference to its graph (see :file:`lib/command.h`). | |
d1890d04 QY |
533 | |
534 | While most of the graph maintains the form of a tree, special constructs | |
cb3d8153 QY |
535 | outlined in the Rules section introduce some quirks. ``<>``, ``[]`` and ``{}`` |
536 | form self-contained 'subgraphs'. Each subgraph is a tree except that all of the | |
537 | 'leaves' actually share a child node. This helps with minimizing graph size and | |
538 | debugging. | |
d1890d04 | 539 | |
e53d5853 QY |
540 | As a working example, here is the graph of the following command: :: |
541 | ||
542 | show [ip] bgp neighbors [<A.B.C.D|X:X::X:X|WORD>] [json] | |
543 | ||
88ba7d9e | 544 | .. figure:: ../figures/cligraph.png |
e53d5853 QY |
545 | :align: center |
546 | ||
547 | Graph of example CLI command | |
d1890d04 | 548 | |
d1890d04 | 549 | |
e53d5853 | 550 | ``FORK`` and ``JOIN`` nodes are plumbing nodes that don't correspond to user |
d1890d04 QY |
551 | input. They're necessary in order to deduplicate these constructs where |
552 | applicable. | |
553 | ||
e53d5853 | 554 | Options follow the same form, except that there is an edge from the ``FORK`` |
cb3d8153 QY |
555 | node to the ``JOIN`` node. Since all of the subgraphs in the example command are |
556 | optional, all of them have this edge. | |
d1890d04 | 557 | |
e53d5853 QY |
558 | Keywords follow the same form, except that there is an edge from ``JOIN`` to |
559 | ``FORK``. Because of this the CLI graph cannot be called acyclic. There is | |
560 | special logic in the input matching code that keeps a stack of paths already | |
561 | taken through the node in order to disallow following the same path more than | |
562 | once. | |
d1890d04 | 563 | |
e53d5853 QY |
564 | Variadics are a bit special; they have an edge back to themselves, which allows |
565 | repeating the same input indefinitely. | |
d1890d04 | 566 | |
e53d5853 QY |
567 | The leaves of the graph are nodes that have no out edges. These nodes are |
568 | special; their data section does not contain a token, as most nodes do, or | |
cb3d8153 QY |
569 | ``NULL``, as in ``FORK``/``JOIN`` nodes, but instead has a pointer to a |
570 | ``cmd_element``. All paths through the graph that terminate on a leaf are | |
571 | guaranteed to be defined by that command. When a user enters a complete command, | |
572 | the command matcher tokenizes the input and executes a DFS on the CLI graph. If | |
573 | it is simultaneously able to exhaust all input (one input token per graph node), | |
574 | and then find exactly one leaf connected to the last node it reaches, then the | |
575 | input has matched the corresponding command and the command is executed. If it | |
576 | finds more than one node, then the command is ambiguous (more on this in | |
577 | deduplication). If it cannot exhaust all input, the command is unknown. If it | |
578 | exhausts all input but does not find an edge node, the command is incomplete. | |
e53d5853 QY |
579 | |
580 | The parser uses an incremental strategy to build the CLI graph for a node. Each | |
581 | command is parsed into its own graph, and then this graph is merged into the | |
cb3d8153 QY |
582 | overall graph. During this merge step, the parser makes a best-effort attempt to |
583 | remove duplicate nodes. If it finds a node in the overall graph that is equal to | |
584 | a node in the corresponding position in the command graph, it will intelligently | |
585 | merge the properties from the node in the command graph into the | |
e53d5853 QY |
586 | already-existing node. Subgraphs are also checked for isomorphism and merged |
587 | where possible. The definition of whether two nodes are 'equal' is based on the | |
588 | equality of some set of token properties; read the parser source for the most | |
d1890d04 QY |
589 | up-to-date definition of equality. |
590 | ||
e53d5853 QY |
591 | When the parser is unable to deduplicate some complicated constructs, this can |
592 | result in two identical paths through separate parts of the graph. If this | |
593 | occurs and the user enters input that matches these paths, they will receive an | |
cb3d8153 QY |
594 | 'ambiguous command' error and will be unable to execute the command. Most of the |
595 | time the parser can detect and warn about duplicate commands, but it will not | |
596 | always be able to do this. Hence care should be taken before defining a new | |
597 | command to ensure it is not defined elsewhere. | |
d1890d04 | 598 | |
cb3d8153 QY |
599 | struct cmd\_token |
600 | ^^^^^^^^^^^^^^^^^ | |
601 | ||
602 | .. code-block:: c | |
603 | ||
604 | /* Command token struct. */ | |
605 | struct cmd_token | |
606 | { | |
607 | enum cmd_token_type type; // token type | |
608 | uint8_t attr; // token attributes | |
609 | bool allowrepeat; // matcher can match token repetitively? | |
610 | ||
611 | char *text; // token text | |
612 | char *desc; // token description | |
613 | long long min, max; // for ranges | |
614 | char *arg; // user input that matches this token | |
615 | char *varname; // variable name | |
616 | }; | |
617 | ||
618 | This struct is used in the CLI graph to match input against. It is also used to | |
619 | pass user input to command handler functions, as it is frequently useful for | |
620 | handlers to have access to that information. When a command is matched, the | |
621 | sequence of ``cmd_tokens`` that form the matching path are duplicated and placed | |
622 | in order into ``*argv[]``. Before this happens the ``->arg`` field is set to | |
623 | point at the snippet of user input that matched it. | |
624 | ||
625 | For most nontrivial commands the handler function will need to determine which | |
626 | of the possible matching inputs was entered. Previously this was done by looking | |
627 | at the first few characters of input. This is now considered an anti-pattern and | |
628 | should be avoided. Instead, the ``->type`` or ``->text`` fields for this logic. | |
629 | The ``->type`` field can be used when the possible inputs differ in type. When | |
630 | the possible types are the same, use the ``->text`` field. This field has the | |
631 | full text of the corresponding token in the definition string and using it makes | |
632 | for much more readable code. An example is helpful. | |
d1890d04 | 633 | |
cb3d8153 | 634 | Command definition: |
d1890d04 | 635 | |
a42f7818 QY |
636 | :: |
637 | ||
cb3d8153 | 638 | command <(1-10)|foo|BAR> |
d1890d04 | 639 | |
cb3d8153 QY |
640 | In this example, the user may enter any one of: |
641 | - an integer between 1 and 10 | |
642 | - "foo" | |
643 | - anything at all | |
d1890d04 | 644 | |
cb3d8153 | 645 | If the user enters "command f", then: |
d1890d04 QY |
646 | |
647 | :: | |
648 | ||
cb3d8153 QY |
649 | argv[1]->type == WORD_TKN |
650 | argv[1]->arg == "f" | |
651 | argv[1]->text == "foo" | |
d1890d04 | 652 | |
cb3d8153 QY |
653 | Range tokens have some special treatment; a token with ``->type == RANGE_TKN`` |
654 | will have the ``->min`` and ``->max`` fields set to the bounding values of the | |
655 | range. | |
d1890d04 | 656 | |
cb3d8153 QY |
657 | struct cmd\_element |
658 | ^^^^^^^^^^^^^^^^^^^ | |
d1890d04 | 659 | |
cb3d8153 | 660 | .. code-block:: c |
d1890d04 | 661 | |
cb3d8153 QY |
662 | struct cmd_node { |
663 | /* Node index. */ | |
664 | enum node_type node; | |
d1890d04 | 665 | |
cb3d8153 QY |
666 | /* Prompt character at vty interface. */ |
667 | const char *prompt; | |
d1890d04 | 668 | |
cb3d8153 QY |
669 | /* Is this node's configuration goes to vtysh ? */ |
670 | int vtysh; | |
d1890d04 | 671 | |
cb3d8153 QY |
672 | /* Node's configuration write function */ |
673 | int (*func)(struct vty *); | |
d1890d04 | 674 | |
cb3d8153 QY |
675 | /* Node's command graph */ |
676 | struct graph *cmdgraph; | |
d1890d04 | 677 | |
cb3d8153 QY |
678 | /* Vector of this node's command list. */ |
679 | vector cmd_vector; | |
d1890d04 | 680 | |
cb3d8153 QY |
681 | /* Hashed index of command node list, for de-dupping primarily */ |
682 | struct hash *cmd_hash; | |
683 | }; | |
d1890d04 | 684 | |
cb3d8153 QY |
685 | This struct corresponds to a CLI mode. The last three fields are most relevant |
686 | here. | |
d1890d04 | 687 | |
cb3d8153 QY |
688 | cmdgraph |
689 | This is a pointer to the command graph that was described in the first part | |
690 | of this section. It is the datastructure used for matching user input to | |
691 | commands. | |
d1890d04 | 692 | |
cb3d8153 QY |
693 | cmd_vector |
694 | This is a list of all the ``struct cmd_element`` defined in the mode. | |
d1890d04 | 695 | |
cb3d8153 QY |
696 | cmd_hash |
697 | This is a hash table of all the ``struct cmd_element`` defined in the mode. | |
698 | When ``install_element`` is called, it checks that the element it is given is | |
699 | not already present in the hash table as a safeguard against duplicate calls | |
700 | resulting in a command being defined twice, which renders the command | |
701 | ambiguous. | |
702 | ||
703 | All ``struct cmd_node`` are themselves held in a static vector defined in | |
704 | :file:`lib/command.c` that defines the global CLI space. | |
705 | ||
706 | Command Abbreviation & Matching Priority | |
707 | ---------------------------------------- | |
708 | It is possible for users to elide parts of tokens when the CLI matcher does not | |
709 | need them to make an unambiguous match. This is best explained by example. | |
d1890d04 QY |
710 | |
711 | Command definitions: | |
712 | ||
713 | :: | |
714 | ||
cb3d8153 QY |
715 | command dog cow |
716 | command dog crow | |
d1890d04 QY |
717 | |
718 | User input: | |
719 | ||
720 | :: | |
721 | ||
cb3d8153 QY |
722 | c d c -> ambiguous command |
723 | c d co -> match "command dog cow" | |
724 | ||
d1890d04 | 725 | |
cb3d8153 QY |
726 | The parser will look ahead and attempt to disambiguate the input based on tokens |
727 | later on in the input string. | |
d1890d04 QY |
728 | |
729 | Command definitions: | |
730 | ||
731 | :: | |
732 | ||
cb3d8153 QY |
733 | show ip bgp A.B.C.D |
734 | show ipv6 bgp X:X::X:X | |
d1890d04 QY |
735 | |
736 | User enters: | |
737 | ||
738 | :: | |
739 | ||
cb3d8153 QY |
740 | s i b 4.3.2.1 -> match "show ip bgp A.B.C.D" |
741 | s i b ::e0 -> match "show ipv6 bgp X:X::X:X" | |
d1890d04 | 742 | |
cb3d8153 QY |
743 | Reading left to right, both of these commands would be ambiguous since 'i' does |
744 | not explicitly select either 'ip' or 'ipv6'. However, since the user later | |
745 | provides a token that matches only one of the commands (an IPv4 or IPv6 address) | |
746 | the parser is able to look ahead and select the appropriate command. This has | |
747 | some implications for parsing the ``*argv[]`` that is passed to the command | |
748 | handler. | |
d1890d04 QY |
749 | |
750 | Now consider a command definition such as: | |
751 | ||
752 | :: | |
753 | ||
cb3d8153 | 754 | command <foo|VAR> |
d1890d04 | 755 | |
cb3d8153 QY |
756 | 'foo' only matches the string 'foo', but 'VAR' matches any input, including |
757 | 'foo'. Who wins? In situations like this the matcher will always choose the | |
758 | 'better' match, so 'foo' will win. | |
d1890d04 QY |
759 | |
760 | Consider also: | |
761 | ||
762 | :: | |
763 | ||
8957c78a | 764 | show <ip|ipv6> foo |
d1890d04 QY |
765 | |
766 | User input: | |
767 | ||
768 | :: | |
769 | ||
8957c78a | 770 | show ip foo |
d1890d04 | 771 | |
cb3d8153 | 772 | ``ip`` partially matches ``ipv6`` but exactly matches ``ip``, so ``ip`` will |
d1890d04 QY |
773 | win. |
774 | ||
c6a3a685 PZ |
775 | Adding a CLI Node |
776 | ----------------- | |
777 | ||
778 | To add a new CLI node, you should: | |
779 | ||
780 | - define a new numerical node constant | |
781 | - define a node structure in the relevant daemon | |
782 | - call ``install_node()`` in the relevant daemon | |
783 | - define and install the new node in vtysh | |
784 | - define corresponding node entry commands in daemon and vtysh | |
d3bb30f5 | 785 | - add a new entry to the ``ctx_keywords`` dictionary in ``tools/frr-reload.py`` |
c6a3a685 PZ |
786 | |
787 | Defining the numerical node constant | |
788 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
789 | Add your new node value to the enum before ``NODE_TYPE_MAX`` in | |
790 | ``lib/command.h``: | |
791 | ||
792 | .. code-block:: c | |
793 | ||
794 | enum node_type { | |
795 | AUTH_NODE, // Authentication mode of vty interface. | |
796 | VIEW_NODE, // View node. Default mode of vty interface. | |
797 | [...] | |
798 | MY_NEW_NODE, | |
799 | NODE_TYPE_MAX, // maximum | |
800 | }; | |
801 | ||
802 | Defining a node structure | |
803 | ^^^^^^^^^^^^^^^^^^^^^^^^^ | |
804 | In your daemon-specific code where you define your new commands that | |
805 | attach to the new node, add a node definition: | |
806 | ||
807 | .. code-block:: c | |
808 | ||
809 | static struct cmd_node my_new_node = { | |
810 | .name = "my new node name", | |
811 | .node = MY_NEW_NODE, // enum node_type lib/command.h | |
812 | .parent_node = CONFIG_NODE, | |
813 | .prompt = "%s(my-new-node-prompt)# ", | |
814 | .config_write = my_new_node_config_write, | |
815 | }; | |
816 | ||
817 | You will need to define ``my_new_node_config_write(struct vty \*vty)`` | |
818 | (or omit this field if you have no relevant configuration to save). | |
819 | ||
820 | Calling ``install_node()`` | |
821 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
822 | In the daemon's initialization function, before installing your new commands | |
823 | with ``install_element()``, add a call ``install_node(&my_new_node)``. | |
824 | ||
825 | Defining and installing the new node in vtysh | |
826 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
827 | The build tools automatically collect command definitions for vtysh. | |
828 | However, new nodes must be coded in vtysh specifically. | |
829 | ||
830 | In ``vtysh/vtysh.c``, define a stripped-down node structure and | |
831 | call ``install_node()``: | |
832 | ||
833 | .. code-block:: c | |
834 | ||
835 | static struct cmd_node my_new_node = { | |
836 | .name = "my new node name", | |
837 | .node = MY_NEW_NODE, /* enum node_type lib/command.h */ | |
838 | .parent_node = CONFIG_NODE, | |
839 | .prompt = "%s(my-new-node-prompt)# ", | |
840 | }; | |
841 | [...] | |
842 | void vtysh_init_vty(void) | |
843 | { | |
844 | [...] | |
845 | install_node(&my_new_node) | |
846 | [...] | |
847 | } | |
848 | ||
849 | Defining corresponding node entry commands in daemon and vtysh | |
850 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
851 | The command that descends into the new node is typically programmed | |
852 | with ``VTY_PUSH_CONTEXT`` or equivalent in the daemon's CLI handler function. | |
d3bb30f5 PZ |
853 | (If the CLI has been updated to use the new northbound architecture, |
854 | ``VTY_PUSH_XPATH`` is used instead.) | |
855 | ||
c6a3a685 PZ |
856 | In vtysh, you must implement a corresponding node change so that vtysh |
857 | tracks the daemon's movement through the node tree. | |
858 | ||
859 | Although the build tools typically scan daemon code for CLI definitions | |
860 | to replicate their parsing in vtysh, the node-descent function in the | |
861 | daemon must be blocked from this replication so that a hand-coded | |
862 | skeleton can be written in ``vtysh.c``. | |
863 | ||
d3bb30f5 PZ |
864 | Accordingly, use one of the ``*_NOSH`` macros such as ``DEFUN_NOSH``, |
865 | ``DEFPY_NOSH``, or ``DEFUN_YANG_NOSH`` for the daemon's node-descent | |
866 | CLI definition, and use ``DEFUNSH`` in ``vtysh.c`` for the vtysh equivalent. | |
c6a3a685 PZ |
867 | |
868 | .. seealso:: :ref:`vtysh-special-defuns` | |
869 | ||
870 | Examples: | |
871 | ||
872 | ``zebra_whatever.c`` | |
873 | ||
874 | .. code-block:: c | |
875 | ||
876 | DEFPY_NOSH(my_new_node, | |
877 | my_new_node_cmd, | |
878 | "my-new-node foo", | |
879 | "New Thing\n" | |
880 | "A foo\n") | |
881 | { | |
882 | [...] | |
883 | VTY_PUSH_CONTEXT(MY_NEW_NODE, bar); | |
884 | [...] | |
885 | } | |
886 | ||
887 | ||
d3bb30f5 PZ |
888 | ``ripd_whatever.c`` |
889 | ||
890 | .. code-block:: c | |
891 | ||
892 | DEFPY_YANG_NOSH(my_new_node, | |
893 | my_new_node_cmd, | |
894 | "my-new-node foo", | |
895 | "New Thing\n" | |
896 | "A foo\n") | |
897 | { | |
898 | [...] | |
899 | VTY_PUSH_XPATH(MY_NEW_NODE, xbar); | |
900 | [...] | |
901 | } | |
902 | ||
903 | ||
c6a3a685 PZ |
904 | ``vtysh.c`` |
905 | ||
906 | .. code-block:: c | |
907 | ||
908 | DEFUNSH(VTYSH_ZEBRA, my_new_node, | |
909 | my_new_node_cmd, | |
910 | "my-new-node foo", | |
911 | "New Thing\n" | |
912 | "A foo\n") | |
913 | { | |
914 | vty->node = MY_NEW_NODE; | |
915 | return CMD_SUCCESS; | |
916 | } | |
917 | [...] | |
918 | install_element(CONFIG_NODE, &my_new_node_cmd); | |
919 | ||
920 | ||
d3bb30f5 PZ |
921 | Adding a new entry to the ``ctx_keywords`` dictionary |
922 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
923 | In file ``tools/frr-reload.py``, the ``ctx_keywords`` dictionary | |
924 | describes the various node relationships. | |
925 | Add a new node entry at the appropriate level in this dictionary. | |
926 | ||
927 | .. code-block:: python | |
928 | ||
929 | ctx_keywords = { | |
930 | [...] | |
931 | "key chain ": { | |
932 | "key ": {} | |
933 | }, | |
934 | [...] | |
935 | "my-new-node": {}, | |
936 | [...] | |
937 | } | |
938 | ||
c6a3a685 PZ |
939 | |
940 | ||
8957c78a QY |
941 | Inspection & Debugging |
942 | ---------------------- | |
943 | ||
d1890d04 | 944 | Permutations |
8957c78a QY |
945 | ^^^^^^^^^^^^ |
946 | It is sometimes useful to check all the possible combinations of input that | |
947 | would match an arbitrary definition string. There is a tool in | |
cb3d8153 QY |
948 | :file:`tools/permutations` that reads CLI definition strings on ``stdin`` and |
949 | prints out all matching input permutations. It also dumps a text representation | |
950 | of the graph, which is more useful for debugging than anything else. It looks | |
951 | like this: | |
d1890d04 | 952 | |
8957c78a | 953 | .. code-block:: shell |
d1890d04 | 954 | |
cb3d8153 | 955 | $ ./permutations "show [ip] bgp [<view|vrf> WORD]" |
d1890d04 | 956 | |
cb3d8153 QY |
957 | show ip bgp view WORD |
958 | show ip bgp vrf WORD | |
959 | show ip bgp | |
960 | show bgp view WORD | |
961 | show bgp vrf WORD | |
962 | show bgp | |
d1890d04 | 963 | |
8957c78a QY |
964 | This functionality is also built into VTY/VTYSH; :clicmd:`list permutations` |
965 | will list all possible matching input permutations in the current CLI node. | |
966 | ||
967 | Graph Inspection | |
968 | ^^^^^^^^^^^^^^^^ | |
969 | When in the Telnet or VTYSH console, :clicmd:`show cli graph` will dump the | |
970 | entire command space of the current mode in the DOT graph language. This can be | |
971 | fed into one of the various GraphViz layout engines, such as ``dot``, | |
972 | ``neato``, etc. | |
973 | ||
974 | For example, to generate an image of the entire command space for the top-level | |
975 | mode (``ENABLE_NODE``): | |
976 | ||
977 | .. code-block:: shell | |
978 | ||
979 | sudo vtysh -c 'show cli graph' | dot -Tjpg -Grankdir=LR > graph.jpg | |
980 | ||
981 | To do the same for the BGP mode: | |
982 | ||
983 | .. code-block:: shell | |
984 | ||
985 | sudo vtysh -c 'conf t' -c 'router bgp' -c 'show cli graph' | dot -Tjpg -Grankdir=LR > bgpgraph.jpg | |
986 | ||
987 | This information is very helpful when debugging command resolution, tracking | |
988 | down duplicate / ambiguous commands, and debugging patches to the CLI graph | |
989 | builder. |