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