]>
Commit | Line | Data |
---|---|---|
9b9cdb46 QY |
1 | FRR Command Line Interface |
2 | ========================== | |
3 | ||
4 | Definition Grammar | |
5 | ------------------ | |
6 | ||
7 | This is a reference for the syntax used when defining new CLI commands. An | |
8 | example definition is: | |
9 | ||
4e3e06d6 | 10 | ``` |
9b9cdb46 QY |
11 | DEFUN (command_name, |
12 | command_name_cmd, | |
13 | --> "example <command|line [interface]> DEFINITION...", | |
14 | <..doc strings..>) | |
4e3e06d6 | 15 | ``` |
9b9cdb46 QY |
16 | |
17 | The arrowed part is the definition string. | |
18 | ||
19 | Explicit syntax rules in Flex and Bison may be found in lib/command_lex.l and | |
20 | lib/command_parse.y, respectively. If you can read BNF and regex those will be | |
21 | more useful than this document. | |
22 | ||
23 | If the parser is throwing syntax or other errors and you can't figure out why, | |
24 | it's unlikely to be a bug in the parser. If the error message is not useful, | |
25 | please file a bug for a better error message. If all else fails, read the token | |
26 | definitions in the lexer source and the Bison BNF in the parser source. | |
27 | ||
28 | Characters allowed in each token type: | |
29 | ||
30 | Tokens | |
31 | ------ | |
4e3e06d6 DL |
32 | * `WORD` -- A token that begins with +, -, or a lowercase letter. It is |
33 | an unchanging part of the command and will only match itself. | |
34 | Example: "show ip bgp", every token is a WORD. | |
35 | * `IPV4` -- 'A.B.C.D', matches an IPv4 address. | |
36 | * `IPV6` -- 'X:X::X:X', matches an IPv6 address. | |
37 | * `IPV4_PREFIX` -- 'A.B.C.D/M', matches an IPv4 prefix in CIDR notation. | |
38 | * `IPV6_PREFIX` -- 'X:X::X:X/M', matches an IPv6 prefix in CIDR notation. | |
39 | * `VARIABLE` -- Begins with a capital letter. Matches any input. | |
40 | * `RANGE` -- Numeric range delimited by parentheses, e.g. (-100 - 100) or | |
41 | (10-20). Will only match numbers in the range. | |
9b9cdb46 QY |
42 | |
43 | Rules | |
44 | ----- | |
4e3e06d6 | 45 | * `<angle|brackets>` -- Contain sequences of tokens separated by pipes and |
9b9cdb46 | 46 | provide mutual exclusion. Sequences may contain |
4e3e06d6 DL |
47 | `<mutual|exclusion>` but not as the first token. |
48 | Disallowed: `"example <<a|b> c|d>"` | |
49 | Allowed: `"example <a c|b c|d>"` | |
50 | * `[square brackets]` -- Contains sequences of tokens that are optional (can be | |
51 | omitted). `[<a|b>]` can be shortened to `[a|b]`. | |
52 | * `{curly|braces}` -- similar to angle brackets, but instead of mutual | |
9b9cdb46 QY |
53 | exclusion, curly braces indicate that one or more of the |
54 | pipe-separated sequences may be provided in any order. | |
4e3e06d6 | 55 | * `VARIADICS...` -- Any token which accepts input (so anything except WORD) |
9b9cdb46 QY |
56 | and that occurs as the last token of a line may be |
57 | followed by an ellipsis, which indicates that input | |
58 | matching the token may be repeated an unlimited number | |
59 | of times. | |
4e3e06d6 DL |
60 | * `$name` -- Specify a variable name for the preceding token. See |
61 | "Variable Names" below. | |
9b9cdb46 QY |
62 | |
63 | Some general notes: | |
64 | ||
65 | * Options are allowed at the beginning of the command. The developer is | |
66 | entreated to use these extremely sparingly. They are most useful for | |
67 | implementing the 'no' form of configuration commands. Please think carefully | |
68 | before using them for anything else. There is usually a better solution, even | |
69 | if it is just separating out the command definition into separate ones. | |
70 | ||
71 | * The developer should judiciously apply separation of concerns when defining | |
72 | CLI. CLI definitions for two unrelated or vaguely related commands or | |
73 | configuration items should be defined in separate commands. Clarity is | |
74 | preferred over LOC (within reason). | |
75 | ||
4e3e06d6 DL |
76 | Variable Names |
77 | -------------- | |
78 | The parser tries to fill the "varname" field on each token. This can happen | |
79 | either manually or automatically. Manual specifications work by appending | |
80 | `"$name"` after the input specifier: | |
81 | ||
82 | ``` | |
83 | foo bar$cmd WORD$name A.B.C.D$ip | |
84 | ``` | |
85 | ||
86 | Note that you can also assign variable names to fixed input tokens, this can | |
87 | be useful if multiple commands share code. You can also use "$name" after a | |
88 | multiple-choice option: | |
89 | ||
90 | ``` | |
91 | foo bar <A.B.C.D|X:X::X:X>$addr [optionA|optionB]$mode | |
92 | ``` | |
93 | ||
94 | The variable name is in this case assigned to the last token in each of the | |
95 | branches. | |
96 | ||
97 | Automatic assignment of variable names works by applying the following rules: | |
98 | ||
99 | - manual names always have priority | |
100 | - a "[no]" at the beginning receives "no" as varname on the "no" token | |
32a71fd8 | 101 | - VARIABLE tokens whose text is not "WORD" or "NAME" receive a cleaned lowercase |
4e3e06d6 DL |
102 | version of the token text as varname, e.g. "ROUTE-MAP" becomes "route_map". |
103 | - other variable tokens (i.e. everything except "fixed") receive the text of | |
104 | the preceding fixed token as varname, if one can be found. E.g.: | |
105 | "ip route A.B.C.D/M INTERFACE" assigns "route" to the "A.B.C.D/M" token. | |
106 | ||
107 | These rules should make it possible to avoid manual varname assignment in 90% | |
108 | of the cases. | |
109 | ||
9b9cdb46 QY |
110 | Doc Strings |
111 | ----------- | |
112 | Each token in a command definition should be documented with a brief doc | |
113 | string that informs a user of the meaning and/or purpose of the subsequent | |
114 | command tree. These strings are provided as the last parameter to DEFUN macros, | |
115 | concatenated together and separated by an escaped newline ('\n'). These are | |
116 | best explained by example. | |
117 | ||
4e3e06d6 | 118 | ``` |
9b9cdb46 QY |
119 | DEFUN (config_terminal, |
120 | config_terminal_cmd, | |
121 | "configure terminal", | |
122 | "Configuration from vty interface\n" | |
123 | "Configuration terminal\n") | |
4e3e06d6 | 124 | ``` |
9b9cdb46 QY |
125 | |
126 | The last parameter is split into two lines for readability. Two newline | |
127 | delimited doc strings are present, one for each token in the command. The | |
128 | second string documents the functionality of the 'terminal' command in the | |
129 | 'configure' tree. | |
130 | ||
131 | Note that the first string, for 'configure' does not contain documentation for | |
132 | 'terminal'. This is because the CLI is best envisioned as a tree, with tokens | |
133 | defining branches. An imaginary 'start' token is the root of every command in a | |
134 | CLI node. Each subsequent written token descends into a subtree, so the | |
135 | documentation for that token ideally summarizes all the functionality contained | |
136 | in the subtree. | |
137 | ||
138 | A consequence of this structure is that the developer must be careful to use | |
139 | the same doc strings when defining multiple commands that are part of the same | |
140 | tree. Commands which share prefixes must share the same doc strings for those | |
141 | prefixes. On startup the parser will generate warnings if it notices | |
142 | inconsistent doc strings. Behavior is undefined; the same token may show up | |
143 | twice in completions, with different doc strings, or it may show up once with a | |
144 | random doc string. Parser warnings should be heeded and fixed to avoid | |
145 | confusing users. | |
146 | ||
147 | The number of doc strings provided must be equal to the amount of tokens | |
148 | present in the command definition, read left to right, ignoring any special | |
149 | constructs. | |
150 | ||
151 | In the examples below, each arrowed token needs a doc string. | |
152 | ||
4e3e06d6 | 153 | ``` |
9b9cdb46 QY |
154 | "show ip bgp" |
155 | ^ ^ ^ | |
156 | ||
157 | "command <foo|bar> [example]" | |
158 | ^ ^ ^ ^ | |
4e3e06d6 | 159 | ``` |
9b9cdb46 QY |
160 | |
161 | Data Structures | |
162 | --------------- | |
163 | On startup, the CLI parser sequentially parses each command string definition | |
164 | and constructs a directed graph with each token forming a node. This graph is | |
165 | the basis of the entire CLI system. It is used to match user input in order to | |
166 | generate command completions and match commands to functions. | |
167 | ||
168 | There is one graph per CLI node (not the same as a graph node in the CLI | |
169 | graph). The CLI node struct keeps a reference to its graph (see lib/command.h). | |
170 | ||
171 | While most of the graph maintains the form of a tree, special constructs | |
172 | outlined in the Rules section introduce some quirks. <>, [] and {} form | |
173 | self-contained 'subgraphs'. Each subgraph is a tree except that all of the | |
174 | 'leaves' actually share a child node. This helps with minimizing graph size and | |
175 | debugging. | |
176 | ||
177 | As an example, the subgraph generated by <foo|bar> looks like this: | |
178 | ||
179 | . | |
180 | . | |
181 | | | |
182 | +----+---+ | |
183 | +--- -+ FORK +----+ | |
184 | | +--------+ | | |
185 | +--v---+ +--v---+ | |
186 | | foo | | bar | | |
187 | +--+---+ +--+---+ | |
188 | | +------+ | | |
189 | +------> JOIN <-----+ | |
190 | +---+--+ | |
191 | | | |
192 | . | |
193 | . | |
194 | ||
195 | FORK and JOIN nodes are plumbing nodes that don't correspond to user input. | |
196 | They're necessary in order to deduplicate these constructs where applicable. | |
197 | ||
198 | Options follow the same form, except that there is an edge from the FORK node | |
199 | to the JOIN node. | |
200 | ||
201 | Keywords follow the same form, except that there is an edge from JOIN to FORK. | |
202 | Because of this the CLI graph cannot be called acyclic. There is special logic | |
203 | in the input matching code that keeps a stack of paths already taken through | |
204 | the node in order to disallow following the same path more than once. | |
205 | ||
206 | Variadics are a bit special; they have an edge back to themselves, which allows | |
207 | repeating the same input indefinitely. | |
208 | ||
209 | The leaves of the graph are nodes that have no out edges. These nodes are | |
210 | special; their data section does not contain a token, as most nodes do, or | |
211 | NULL, as in FORK/JOIN nodes, but instead has a pointer to a cmd_element. All | |
212 | paths through the graph that terminate on a leaf are guaranteed to be defined | |
213 | by that command. When a user enters a complete command, the command matcher | |
214 | tokenizes the input and executes a DFS on the CLI graph. If it is | |
215 | simultaneously able to exhaust all input (one input token per graph node), and | |
216 | then find exactly one leaf connected to the last node it reaches, then the | |
217 | input has matched the corresponding command and the command is executed. If it | |
218 | finds more than one node, then the command is ambiguous (more on this in | |
219 | deduplication). If it cannot exhaust all input, the command is unknown. If it | |
220 | exhausts all input but does not find an edge node, the command is incomplete. | |
221 | ||
222 | The parser uses an incremental strategy to build the CLI graph for a node. Each | |
223 | command is parsed into its own graph, and then this graph is merged into the | |
224 | overall graph. During this merge step, the parser makes a best-effort attempt | |
225 | to remove duplicate nodes. If it finds a node in the overall graph that is | |
226 | equal to a node in the corresponding position in the command graph, it will | |
227 | intelligently merge the properties from the node in the command graph into the | |
228 | already-existing node. Subgraphs are also checked for isomorphism and merged | |
229 | where possible. The definition of whether two nodes are 'equal' is based on the | |
230 | equality of some set of token properties; read the parser source for the most | |
231 | up-to-date definition of equality. | |
232 | ||
233 | When the parser is unable to deduplicate some complicated constructs, this | |
234 | can result in two identical paths through separate parts of the graph. If | |
235 | this occurs and the user enters input that matches these paths, they will | |
236 | receive an 'ambiguous command' error and will be unable to execute the command. | |
237 | Most of the time the parser can detect and warn about duplicate commands, but | |
238 | it will not always be able to do this. Hence care should be taken before | |
239 | defining a new command to ensure it is not defined elsewhere. | |
240 | ||
241 | ||
242 | Command handlers | |
243 | ---------------- | |
244 | The block that follows a CLI definition is executed when a user enters input | |
245 | that matches the definition. Its function signature looks like this: | |
246 | ||
247 | int (*func) (const struct cmd_element *, struct vty *, int, struct cmd_token *[]); | |
248 | ||
249 | The first argument is the command definition struct. The last argument is an | |
250 | ordered array of tokens that correspond to the path taken through the graph, | |
251 | and the argument just prior to that is the length of the array. | |
252 | ||
253 | The arrangement of the token array has changed from the prior incarnation of | |
254 | the CLI system. In the old system, missing arguments were padded with NULLs so | |
255 | that the same parts of a command would show up at the same indices regardless | |
256 | of what was entered. The new system does not perform such padding and therefore | |
257 | it is generally _incorrect_ to assume consistent indices in this array. As a | |
258 | simple example: | |
259 | ||
260 | Command definition: | |
4e3e06d6 | 261 | ``` |
9b9cdb46 | 262 | command [foo] <bar|baz> |
4e3e06d6 | 263 | ``` |
9b9cdb46 QY |
264 | |
265 | User enters: | |
4e3e06d6 | 266 | ``` |
9b9cdb46 | 267 | command foo bar |
4e3e06d6 | 268 | ``` |
9b9cdb46 QY |
269 | |
270 | Array: | |
4e3e06d6 | 271 | ``` |
9b9cdb46 QY |
272 | [0] -> command |
273 | [1] -> foo | |
274 | [2] -> bar | |
4e3e06d6 | 275 | ``` |
9b9cdb46 QY |
276 | |
277 | User enters: | |
4e3e06d6 | 278 | ``` |
9b9cdb46 | 279 | command baz |
4e3e06d6 | 280 | ``` |
9b9cdb46 QY |
281 | |
282 | Array: | |
4e3e06d6 | 283 | ``` |
9b9cdb46 QY |
284 | [0] -> command |
285 | [1] -> baz | |
4e3e06d6 | 286 | ``` |
9b9cdb46 QY |
287 | |
288 | ||
289 | ||
290 | Command abbreviation & matching priority | |
291 | ---------------------------------------- | |
292 | As in the prior implementation, it is possible for users to elide parts of | |
293 | tokens when the CLI matcher does not need them to make an unambiguous match. | |
294 | This is best explained by example. | |
295 | ||
296 | Command definitions: | |
4e3e06d6 | 297 | ``` |
9b9cdb46 QY |
298 | command dog cow |
299 | command dog crow | |
4e3e06d6 | 300 | ``` |
9b9cdb46 QY |
301 | |
302 | User input: | |
4e3e06d6 | 303 | ``` |
9b9cdb46 QY |
304 | c d c -> ambiguous command |
305 | c d co -> match "command dog cow" | |
4e3e06d6 | 306 | ``` |
9b9cdb46 QY |
307 | |
308 | In the new implementation, this functionality has improved. Where previously | |
309 | the parser would stop at the first ambiguous token, it will now look ahead and | |
310 | attempt to disambiguate based on tokens later on in the input string. | |
311 | ||
312 | Command definitions: | |
4e3e06d6 | 313 | ``` |
9b9cdb46 QY |
314 | show ip bgp A.B.C.D |
315 | show ipv6 bgp X:X::X:X | |
4e3e06d6 | 316 | ``` |
9b9cdb46 QY |
317 | |
318 | User enters: | |
4e3e06d6 | 319 | ``` |
9b9cdb46 QY |
320 | s i b 4.3.2.1 -> match "show ip bgp A.B.C.D" |
321 | s i b ::e0 -> match "show ipv6 bgp X:X::X:X" | |
4e3e06d6 | 322 | ``` |
9b9cdb46 QY |
323 | |
324 | Previously both of these commands would be ambiguous since 'i' does not | |
325 | explicitly select either 'ip' or 'ipv6'. However, since the user later provides | |
326 | a token that matches only one of the commands (an IPv4 or IPv6 address) the | |
327 | parser is able to look ahead and select the appropriate command. This has some | |
328 | implications for parsing the argv*[] that is passed to the command handler. | |
329 | ||
330 | Now consider a command definition such as: | |
4e3e06d6 | 331 | ``` |
9b9cdb46 | 332 | command <foo|VAR> |
4e3e06d6 | 333 | ``` |
9b9cdb46 QY |
334 | |
335 | 'foo' only matches the string 'foo', but 'VAR' matches any input, including | |
336 | 'foo'. Who wins? In situations like this the matcher will always choose the | |
337 | 'better' match, so 'foo' will win. | |
338 | ||
339 | Consider also: | |
4e3e06d6 | 340 | ``` |
9b9cdb46 | 341 | show <ip|ipv6> foo |
4e3e06d6 | 342 | ``` |
9b9cdb46 QY |
343 | |
344 | User input: | |
4e3e06d6 | 345 | ``` |
9b9cdb46 | 346 | show ip foo |
4e3e06d6 | 347 | ``` |
9b9cdb46 QY |
348 | |
349 | 'ip' partially matches 'ipv6' but exactly matches 'ip', so 'ip' will win. | |
350 | ||
351 | ||
352 | struct cmd_token | |
353 | ---------------- | |
354 | ||
4e3e06d6 | 355 | ``` |
9b9cdb46 QY |
356 | /* Command token struct. */ |
357 | struct cmd_token | |
358 | { | |
359 | enum cmd_token_type type; // token type | |
360 | u_char attr; // token attributes | |
361 | bool allowrepeat; // matcher allowed to match token repetitively? | |
362 | ||
363 | char *text; // token text | |
364 | char *desc; // token description | |
365 | long long min, max; // for ranges | |
366 | char *arg; // user input that matches this token | |
4e3e06d6 | 367 | char *varname; // variable name |
9b9cdb46 | 368 | }; |
4e3e06d6 | 369 | ``` |
9b9cdb46 QY |
370 | |
371 | This struct is used in the CLI graph to match input against. It is also used to | |
372 | pass user input to command handler functions, as it is frequently useful for | |
373 | handlers to have access to that information. When a command is matched, the | |
374 | sequence of cmd_tokens that form the matching path are duplicated and placed in | |
375 | order into argv*[]. Before this happens the ->arg field is set to point at the | |
376 | snippet of user input that matched it. | |
377 | ||
378 | For most nontrivial commands the handler function will need to determine which | |
379 | of the possible matching inputs was entered. Previously this was done by | |
380 | looking at the first few characters of input. This is now considered an | |
381 | anti-pattern and should be avoided. Instead, the ->type or ->text fields for | |
382 | this logic. The ->type field can be used when the possible inputs differ in | |
383 | type. When the possible types are the same, use the ->text field. This field | |
384 | has the full text of the corresponding token in the definition string and using | |
385 | it makes for much more readable code. An example is helpful. | |
386 | ||
387 | Command definition: | |
4e3e06d6 | 388 | ``` |
9b9cdb46 | 389 | command <(1-10)|foo|BAR> |
4e3e06d6 | 390 | ``` |
9b9cdb46 QY |
391 | |
392 | In this example, the user may enter any one of: | |
393 | * an integer between 1 and 10 | |
394 | * "foo" | |
395 | * anything at all | |
396 | ||
397 | If the user enters "command f", then: | |
398 | ||
4e3e06d6 | 399 | ``` |
9b9cdb46 QY |
400 | argv[1]->type == WORD_TKN |
401 | argv[1]->arg == "f" | |
402 | argv[1]->text == "foo" | |
4e3e06d6 | 403 | ``` |
9b9cdb46 QY |
404 | |
405 | Range tokens have some special treatment; a token with ->type == RANGE_TKN will | |
406 | have the ->min and ->max fields set to the bounding values of the range. | |
407 | ||
408 | ||
409 | Permutations | |
410 | ------------ | |
411 | Finally, it is sometimes useful to check all the possible combinations of input | |
412 | that would match an arbitrary definition string. There is a tool in tools/ | |
413 | called 'permutations' that reads CLI definition strings on stdin and prints out | |
414 | all matching input permutations. It also dumps a text representation of the | |
415 | graph, which is more useful for debugging than anything else. It looks like | |
416 | this: | |
417 | ||
4e3e06d6 | 418 | ``` |
9b9cdb46 QY |
419 | $ ./permutations "show [ip] bgp [<view|vrf> WORD]" |
420 | ||
421 | show ip bgp view WORD | |
422 | show ip bgp vrf WORD | |
423 | show ip bgp | |
424 | show bgp view WORD | |
425 | show bgp vrf WORD | |
426 | show bgp | |
4e3e06d6 | 427 | ``` |
9b9cdb46 QY |
428 | |
429 | This functionality is also built into VTY/VTYSH; the 'list permutations' | |
430 | command will list all possible matching input permutations in the current CLI | |
431 | node. |