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