summaryrefslogtreecommitdiffstats
path: root/src/vty/command.c
Commit message (Collapse)AuthorAgeFilesLines
* vty: track parent nodes also for telnet sessionsNeels Hofmeyr2019-11-241-30/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Keep track of parent nodes and go back hierarchically, not only for .cfg file reading, but also for telnet VTY sessions. A long time ago cfg file parsing was made strictly hierarchical: node exits go back to parent nodes exactly as they were entered. However, live telnet VTY sessions still lacked this and depended on the go_parent_cb(). From this commit on, implementing a go_parent_cb() is completely optional. The go_parent_cb() no longer has the task to determine the correct parent node, neither for cfg files (as already the case before this patch) nor for telnet VTY sessions (added by this patch). Instead, a go_parent_cb() implementation can merely take actions it requires on node exits, for example applying some config when leaving a specific node. The node value that is returned by the go_parent_cb() and the vty->node and vty->index values that might be set are completely ignored; instead the implicit parent node tracking determines the parent and node object. As a side effect, the is_config_node() callback is no longer needed, since the VTY now always implicitly knows when to exit back to the CONFIG_NODE. For example, osmo_ss7_is_config_node() could now be dropped, and the osmo_ss7_vty_go_parent() could be shortened by five switch cases, does no longer need to set vty->node nor vty->index and could thus be shortened to: int osmo_ss7_vty_go_parent(struct vty *vty) { struct osmo_ss7_asp *asp; struct osmo_xua_server *oxs; switch (vty->node) { case L_CS7_ASP_NODE: asp = vty->index; /* If no local addr was set */ if (!asp->cfg.local.host_cnt) { asp->cfg.local.host[0] = NULL; asp->cfg.local.host_cnt = 1; } osmo_ss7_asp_restart(asp); break; case L_CS7_XUA_NODE: oxs = vty->index; /* If no local addr was set, or erased after _create(): */ if (!oxs->cfg.local.host_cnt) osmo_ss7_xua_server_set_local_host(oxs, NULL); if (osmo_ss7_xua_server_bind(oxs) < 0) vty_out(vty, "%% Unable to bind xUA server to IP(s)%s", VTY_NEWLINE); break; } return 0; } Before parent tracking, every program was required to write a go_parent_cb() which has to return every node's parent node, basically a switch() statement that manually traces the way back out of child nodes. If the go_parent_cb() has errors, we may wildly jump around the node tree: a common error is to jump right out to the top config node with one exit, even though we were N levels deep. This kind of error has been eliminated for cfg files long ago, but still exists for telnet VTY sessions, which this patch fixes. This came up when I was adding multi-level config nodes to osmo-hlr to support Distributed GSM / remote MS lookup: the config file worked fine, while vty node tests failed to exit to the correct nodes. Change-Id: I2b32b4fe20732728db6e9cdac7e484d96ab86dc5
* vty: Return error if cmd returns CMD_WARNING while reading cfg filePau Espin Pedrol2019-10-281-2/+1
| | | | | | | Otherwise bad configurations can easily sneak in and produce unexpected behavior. Change-Id: Ic9c1b566ec4a459f03e6319cf369691903cf9d00
* vty: Fix go_parent_cb not called for indented nodes at end of cfg filePau Espin Pedrol2019-10-111-0/+4
| | | | | | | | | | | | | | | | | Without this patch, for instance in this cfg file below, go_parent_cb is not called for nodes such as "listen" and "cs7": """ line vty no login cs7 instance 0 xua rkm routing-key-allocation dynamic-permitted listen m3ua 2905 accept-asp-connections dynamic-permitted local-ip 127.0.0.1 """ Related: OS#3608 Change-Id: Ia6d88c0e63d94ba99e950da6efbc4c1871070012
* vty: Optionally Set/replace cfg file during cmd 'write file'Pau Espin Pedrol2019-10-071-2/+6
| | | | | | | | | | | This way if the process is started with no file associated (eg. no -c param and default cfg path doesn't exist), config can be later saved into a file by passing the parameter. Otherwise, until now this message was displayed: Can't save to configuration file, using vtysh. Related: OS#4024 Change-Id: I38edcf902a08b6bd0ebb9aa6fc1a7041421af525
* MAXPATHLEN set if not definedRuben Undheim2019-09-021-0/+5
| | | | Change-Id: I1dce8ace228814b5a7246a00b31309ab9461d266
* vty: Simplify char escaping in asciidoc outputPau Espin Pedrol2019-06-251-9/+4
| | | | Change-Id: I7df6858bb98abffc1d5bf420f991ae5854b24638
* vty: command.c: Fix: single-choice optional args are no longer passed ↵Pau Espin Pedrol2019-06-141-5/+14
| | | | | | | | | | | incomplete to vty func For instance, take command "single0 [one]": If user executes "single0 on", VTY func will receive argv[0]="one" instead of argv[0]="on". Related: OS#4045 Change-Id: I5f4e2d16c62a2d22717989c6acc77450957168cb
* vty: command.c: Fix: multi-choice args are no longer passed incomplete to ↵Pau Espin Pedrol2019-06-141-7/+44
| | | | | | | | | | | vty func For instance, take command "multi0 (one|two|three)": If user executes "multi0 tw", VTY func will receive argv[0]="two" instead of argv[0]="tw". Fixes: OS#4045 Change-Id: I91b6621ac3d87fda5412a9b415e7bfb4736c8a9a
* vty: command.c: Get rid of big indentation blockPau Espin Pedrol2019-06-141-30/+30
| | | | | | This block will become bigger in forthcoming commits. Change-Id: Ibc1494014b1e77ce10950f7268a44d2d2091a6f2
* command.c: Improve return check condition in cmd_execut_command_real()Pau Espin Pedrol2019-06-141-2/+2
| | | | | | | Check against MAX argc is changed to == since it cannot be incremented twice without passing the check. Change-Id: Ia330e475989fda863bedcc3cbf94deaf8dd83037
* vty: command.c: Get rid of huge indentation blockPau Espin Pedrol2019-06-121-91/+94
| | | | | | | | Huge conditional block inside for loop is negated in this patch together with a "continue" keyword, similar to what was already done recently in 4742526645d6137dd90ef369f0415afdb91736dc. Change-Id: I803c4ed38e9ab09bf929528c75a60e6f65da3928
* cosmetic: vty: command.c: Use upper case for enum match_type value namesPau Espin Pedrol2019-06-121-101/+101
| | | | | | | Makes code easier to follow because enum values no longer look like variables. Change-Id: Ib6e9592c5962d047869a280c10f9b557fae6f435
* vty: command.c: Fix is_cmd_ambiguous() returning always 0Pau Espin Pedrol2019-06-111-5/+5
| | | | | | | | | | inner block defined variable "enum match_type ret" was being masking outter block variable "int ret = 0". The ret variable was being given non zero values only inside the inner block, so that change was done on the inner variable and not the outer one, which is returned. Fixes: 5314c513f23688462d7f7937e5ae5e0d5cd4548e Change-Id: Iec87d7db49a096d07e38ff8a060b923a52bfd6ba
* vty: command.c: Get rid of huge indentation blockPau Espin Pedrol2019-06-111-84/+87
| | | | | | | Huge conditional block inside foor loop is negated in this patch together with a "continue" keyword. Change-Id: I9715734ed276f002fdc8c3b9742531ad36b2ef9e
* vty/command.c: cosmetic: add missing curly bracketsVadim Yanitskiy2019-06-011-2/+4
| | | | | | Otherwise it's a bit hard to read the code. Change-Id: I807ec71cfb67976251be844cdb2d2776b1837438
* vty: enable tab-completion for optional-multi-choice argsNeels Hofmeyr2019-02-041-1/+10
| | | | | | | | | | | | | | In cmd_complete_command_real(), detect and strip square braces from multi-choice arguments, to enable tab-completion for commands like > list cmd [(alpha|beta)] > cmd <TAB> alpha beta > cmd be<TAB> > cmd beta Change-Id: I8c304300b3633bb6e9b3457fcfa42121c8272ac0
* vty: enable optional-multi-choice syntax: [(one|two)]Neels Hofmeyr2019-02-041-3/+21
| | | | | | | | | | | | | | | | | | | | | | | | | | Since very recently we sensibly handle commands like cmd ([one]|[two]|[three]) as optional multi-choice arguments. In addition, support the more obvious syntax of cmd [(one|two|three)] Internally, the tokens are mangled to [one] [two] and [three], which is how the rest of the code detects optional args, and makes sense in terms of UI: > cmd ? [one] [two] [three] (i.e. optional arguments are always shown in braces in '?' listings) Before this patch, commands defined with a syntax like [(one|two)], would lead to an assertion (shows as "multiple") during program startup. Change-Id: I952b3c00f97e2447f2308b0ec6f5f1714692b5b2
* vty: enable optional-multi-choice syntax: ([one]|[two])Neels Hofmeyr2019-02-041-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add basic optional multi-choice argument support. The VTY detects optional arguments by square braces. > cmd ? [optional-arg] > cmd optional-arg ok > cmd ok However, within multi-choice args, these braces were so far not treated as optional: > list cmd2 ([one]|[two]|[three]) > cmd2 % Command incomplete In preparation for I952b3c00f97e2447f2308b0ec6f5f1714692b5b2 which will enable the more obvious syntax of cmd [(one|two)] for reasons of internal implementation, first support a syntax of cmd ([one]|[two]) The internal vty implementation always needs square braces around each option. There is currently no good way to prevent developers from defining braces inside multi-arguments, so it is easiest to allow and handle them: > list cmd2 ([one]|[two]|[three]) > cmd2 ok The VTY doesn't guard against a mix like cmd (one|[two]) With this patch, a multi-choice command is treated as optional iff the first element is in square brackets. The remaining elements' square brackets have no effect besides confusing the user. This is not explicitly checked against. In general, I would prefer to check all of these details, but the current VTY code with its endless code duplication and obscure string mangling just doesn't provide that luxury. There are numerous worse errors hidden in there. Change-Id: I9a8474bd89ddc2155c58bfca7bd038d586aaa60a
* vty: omit HIDDEN from vty referenceNeels Hofmeyr2018-09-241-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | During 'show online help', the XML vty node dump, omit all commands marked HIDDEN. These commands were already hidden from the VTY reference prior to commit I1f18e0e41da4772d092d71261b9e489dc1598923, because of broken/confusing bit and boolean logic mixup. After that commit, HIDDEN commands end up in the doc. So practically, this patch here brings back the status quo of before above commit, even though the previous code clearly "intended" to list HIDDEN commands in the reference but failed to have that effect. AFAICT the complete list of commands currently hidden is: * osmo-bsc: bts/"training_sequence_code <0-7>", * osmo-bsc: ts/"phys_chan_config PCHAN" for uppercase pchans; * osmo-bts: bts/"rtp bind-ip A.B.C.D" which actually says vty_out(vty, "%% rtp bind-ip is now deprecated%s", VTY_NEWLINE); * osmo-sgsn: 'reset sgsn state' used for SGSN testing. Note that the osmo-sgsn build was broken by including hidden commands in the vty reference, since one of its hidden commands had missing doc strings and made osmotestconfig.py signal failure. This would fix that from the hide-hidden-commands angle, and so would osmo-sgsn commit I8b6e8615e409266910f2f76a10ced9ab33e4de91 from the fix-the-doc-strings angle. Change-Id: I92c3c66ff69c186234276c64478d6342e061d25e
* vty list: fix deprecation/hidden bit logicNeels Hofmeyr2018-09-241-2/+1
| | | | | | | | | | If a command is both hidden and deprecated, still don't show it for the 'list' command. We currently have no such nodes, as it seems, though. Related: OS#3584 Change-Id: I07ec15cab057a3e09064e0420a69121ee8eb4253
* vty reference: fix deprecation bit evaluationNeels Hofmeyr2018-09-241-2/+2
| | | | | | | | | | | In vty_dump_nodes(), make sure the bitwise & is evaluated first. For the deprecation flag (0x1), the practical effect is most likely identical, assuming that the boolean ! operator flips the first bit, so I expect no visible functional difference. It still was confusing and wrong to look at. Related: OS#3584 Change-Id: I1f18e0e41da4772d092d71261b9e489dc1598923
* vty: fix use-after-free and memleaks in is_cmd_ambiguous()Neels Hofmeyr2018-07-111-20/+43
| | | | | | | | | | | | | | | | | | | | | | | vty_test: add test against ambiguous cmd causing use-after-free and memory leaks. Add this test along with the fix, because the new test triggers the memory use-after-free and leaks, causing build failures. Add cmd_deopt_with_ctx() to allow passing a specific talloc ctx. is_cmd_ambiguous(): keep all cmd_deopt() allocations until the function exits. Add a comment explaining why. Before this, if a command matched an optional "[arg]" with square brackets, we would keep it in local var 'matched', but we would free the string it points to at the end of that loop iteration; upon encountering another match, we would attempt to strcmp against the freed 'matched'. Instead of adding hard-to-read and -verify free/alloc dances to keep the 'matched' accurately freed/non-freed/..., just keep all cmd_deopt() string allocated until done. Needless to say that this should have been implemented on a lower level upon inventing optional args, but at least this is fixing a program crash. Related: OS#33903390 Change-Id: Ia71ba742108b5ff020997bfb612ad5eb30d04fcd
* vty: cosmetic: cmd_deopt(): use talloc_strndup(), not memcpy()Neels Hofmeyr2018-07-091-8/+1
| | | | Change-Id: Ibf870ae02be706f802482f7cff6589a70cde8320
* vty/command.c: talloc from tall_vty_cmd_ctx, not NULLNeels Hofmeyr2018-07-091-3/+3
| | | | Change-Id: Iaa409b4f63557c8fb028bbb322b5e7253393c05c
* vty: Don't dump deprecated commands in XML exportHarald Welte2018-06-091-2/+4
| | | | | | | we don't want to include deprecated commands in our VTY reference manuals. Change-Id: I5e179c9dca297b8c4bdbdf4e0e5b1d69eecc4232
* vty/command.c: write_config_file(): sanely compose temp pathNeels Hofmeyr2018-03-281-1/+11
| | | | | | | | | | | | | | | Fix GCC version 7.3.0 (Debian 7.3.0-12) compiler warning: ../../../../src/libosmocore/src/vty/command.c: In function ‘write_config_file’: ../../../../src/libosmocore/src/vty/command.c:2741:2: error: null destination pointer [-Werror=format-overflow=] sprintf(config_file_tmp, "%s.XXXXXX", config_file); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Check agains NULL after each _talloc_zero() in write_config_file(). While at it, add a comment explaining why we don't use talloc_asprintf() instead. Change-Id: I7bdc52afe724c1d21f419fe49a6e2ebca9420969
* vty: set name for VIEW+ENABLE nodes, for VTY referenceNeels Hofmeyr2017-12-101-0/+4
| | | | | | This leaves no unnamed chapters in future VTY reference documents. Change-Id: Iefb8b78094208a1a4c5d70bd6c69a3deca8da54f
* VTY reference: use node names as section namesNeels Hofmeyr2017-12-101-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In 'show online-help' output, add the node names (currently all derived from the prompt) as <node><name> entry, so that in the osmo-gsm-manuals, each section of node commands gets a title. So far, each section of commands has no name at all, and it is entirely up for guessing which part of the VTY the commands are about. Node section names, e.g. for OsmoHLR, will be like 1 VTY reference 1.4 config 1.5 config-log 1.6 config-line 1.7 config-ctrl 1.8 config-hlr 1.9 config-hlr-gsup Before this patch, all but '1 VTY reference' were plain empty. A better solution would be to list the actual command name that enters the node, and to nest the commands identically to VTY node nesting, but since this information is currently hidden in node command implementations, it is impossible to derive it. So we should actually make the VTY reflect the node nesting structure in its data model, which would resolve both the accurate node name problem as well as produce well-structured output to generate the VTY references from. This patch is a workaround for lack of a more profound fix of the VTY data model. At least it makes the VTY references' sections even remotely useful. Change-Id: Iaf745b2ab3d9b02fc47025a0eba3beb711068bfe
* VTY reference: do not list empty nodesNeels Hofmeyr2017-12-101-0/+2
| | | | | | | In 'show online-help' output, don't list nodes that have no commands (the 'Password' node). Change-Id: I3bd6883a87b8b893e560ceadfffbf41bc380109c
* vty XML export: avoid repeating common node commands for each nodeNeels Hofmeyr2017-12-101-0/+45
| | | | | | | | | | | We use 'show online-help' to generate VTY reference manuals. It is not helpful to include the common node commands on each and every node level, it clutters the actual useful help. Have a separate first section called 'Common Commands', but omit them elsewhere. Change-Id: Ie802eccad80887968b10269ff9c0e9797268e0d4
* Fix/Update copyright notices; Add SPDX annotationHarald Welte2017-11-131-0/+6
| | | | | | | | Let's fix some erroneous/accidential references to wrong license, update copyright information where applicable and introduce a SPDX-License-Identifier to all files. Change-Id: I39af26c6aaaf5c926966391f6565fc5936be21af
* vty: Fix bad use of vector_slot()Pau Espin Pedrol2017-11-101-1/+1
| | | | | | | | | | | | | | | | | | Commit in e9e9e427b78271941a25a63567fc2ec2bb9e4433 attempted to fix a compilation warning but introduced a regression documented in OS#2613. The commit was reverted in 4aa0258269296f078e685e21fb08b115567e814. After closer lookup and testing, it seems vector_slot(vline, index) is expected to be NULL in this case as set by vty_complete_command: /* In case of 'help \t'. */ if (isspace((int)vty->buf[vty->length - 1])) vector_set(vline, NULL); As a result, the correct fix for the compilation warning is to test against NULL instead of testing for empty string. Change-Id: Id9e02bbf89e0a94e1766b1efd236538712415c8a
* Revert "vty: Fix bad use of vector_slot()"Neels Hofmeyr2017-11-011-1/+1
| | | | | | | | | | | | | | | | | | | | | | The patch seemed sensible, but introduces a segfault when hitting tab on the interactive VTY. Reproduction example: osmo-msc telnet 127.0.0.1 4254 OsmoMSC> enable <TAB> So we need to understand what that line of code actually intends to do. Until then, revert this to avoid the segfault. The segfault happens at: Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7bc0894 in cmd_complete_command_real (vline=0x5555558d59e0, vty=0x5555558d57b0, status=0x7fffffffe024) at ../../../../src/libosmocore/src/vty/command.c:1953 1953 if (*(char *)vector_slot(vline, index) == '\0') This reverts commit e9e9e427b78271941a25a63567fc2ec2bb9e4433. Change-Id: I3fe213bdfb96de9469aae64e67000dafee59302e
* vty: Fix bad use of vector_slot()Pau Espin Pedrol2017-10-241-1/+1
| | | | | | | | | | | | | | | | | | | Fixes the compilation warning below: git/libosmocore/src/vty/command.c: In function ‘cmd_complete_command_real’: git/libosmocore/src/vty/command.c:1953:33: warning: comparison between pointer and zero character const ant [-Wpointer-compare] if (vector_slot(vline, index) == '\0') ^~ git/libosmocore/src/vty/command.c:37:0: git/libosmocore/include/osmocom/vty/vector.h:39:27: note: did you mean to dereference the pointer? #define vector_slot(V,I) ((V)->index[(I)]) ^ git/libosmocore/src/vty/command.c:1953:7: note: in expansion of macro ‘vector_slot’ if (vector_slot(vline, index) == '\0') ^~~~~~~~~~~ Change-Id: Iaba9e3450d68c51e16a7bda2fc0fc370992ca866
* vty: install 'exit', 'end',... commands on *all* nodesNeels Hofmeyr2017-09-271-13/+29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In many callers of the VTY API, we are lacking the vty_install_default() step at certain node levels. This creates nodes that lack the 'exit' command, and hence the only way to exit such a node is to restart the telnet session. Historically, the VTY looked for missing commands on the immediate parent node, and hence possibly found the parent's 'exit' command when the local node was missing it. That is why we so far did not notice the missing default commands. Furthermore, some callers call install_default() instead of vty_install_default(). Only vty_install_default() also includes the 'exit' and 'end' commands. There is no reason why there are two sets of default commands. To end this confusion, to catch all missing 'exit' commands and to prevent this from re-appearing in the future, simply *always* install all default commands implicitly when calling install_node(). In cmd_init(), there are some top-level nodes that apparently do not want the default commands installed. Keep those the way they are, by changing the invocation to new install_node_bare() ({VIEW,AUTH,AUTH_ENABLE}_NODE). Make both install_default() and vty_install_default() no-ops so that users of the API may still call them without harm. Do not yet deprecate yet, which follows in Icf5d83f641e838cebcccc635a043e94ba352abff. Drop all invocations to these two functions found in libosmocore. Change-Id: I5021c64a787b63314e0f2f1cba0b8fc7bff4f09b
* vty: derive node name from prompt, use as XML idsNeels Hofmeyr2017-09-231-1/+46
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The 'show online-help' produces XML output with <node id="..."> ids. We reference those from the osmo-gsm-manuals. Instead of numeric IDs coming from internal code, rather use a human-readable node ID -- referencing id='config-msc' is much easier than referencing id='23'. Add a char name[] to struct cmd_node, to hold this name. This may be provided upon struct definition. Since callers of the VTY API so far don't have a name yet, we would need to add names everywhere to get meaningful node IDs. There is a way to get node ID names without touching dependent code: My first idea was to find out which command entered the node, i.e. command 'msc' enters the MSC_NODE. But it is impossible to derive which command entered which node from data structs, it's hidden in the vty command definition. But in fact all (TM) known API callers indeed provide a prompt string that contains a logical and human readable string name. Thus, if the name is unset in the struct, parse the prompt string and strip all "weird" characters to obtain a node name from that. We can still set names later on, but for now will have meaningful node IDs (e.g. 'config-msc' from '%s(config-msc)# ') without touching any dependent code. When VTY nodes get identical node names, which is quite possible, the XML export de-dups these by appending _2, _3,... suffixes. The first occurence is called e.g. 'name', the second 'name_2', then 'name_3', and so forth. If a node has no name (even after parsing the prompt), it will be named merely by the suffix. The first empty node will become id='_1', then '_2', '_3', and so forth. This happens for nodes like VIEW_NODE or AUTH_NODE. If this is merged, we need to adjust the references in osmo-gsm-manuals.git. This can happen in our own time though, because we manually create the vty reference xml and copy it to the osmo-gsm-manuals.git and then update the references from the vty_additions.xml. This anyway has to happen because currently the references tend to be hopelessly out of sync anyway, placing comments at wildly unrelated VTY commands. Change-Id: I8fa555570268b231c5e01727c661da92fad265de
* vty: use internal node id for xml idsNeels Hofmeyr2017-09-231-1/+1
| | | | | | | | | | | | | The 'show online-help' produces XML output with <node id="..."> ids. We reference those from the osmo-gsm-manuals, but until now, these ids fall out of sync when the amount of VTY nodes changes. Change these ids to use the internal node ID constant (as in enum bsc_vty_node) instead of a simple counter. If this is merged, we need to adjust the references in osmo-gsm-manuals.git. Change-Id: Ib07fb9d9106e19f5be6539493e82b5d5991f8bc2
* comment: describe indent_cmp()Neels Hofmeyr2017-09-201-0/+4
| | | | Change-Id: Ia58c16d995f6751bdd69defe8a46665aee163f3d
* fix vty regression: empty parent nodeNeels Hofmeyr2017-09-201-7/+32
| | | | | | | | | | | | | | | | | | | | | | | | | | The recent exit-by-indent patch breaks a VTY case where a node is entered but directly followed by a sibling or ancestor without listing any child nodes. Regression introduced by I24cbb3f6de111f2d31110c3c484c066f1153aac9. An example is a common usage in osmo-bts, where 'phy N' / 'instance N' is a parent node that is commonly left empty: phy 0 instance 0 bts 0 band 1800 Before this patch, this case produces the error: There is no such command. Error occurred during reading the below line: bts 0 Fix indentation parsing logic in command.c to accomodate this case. Add a unit test for empty parent node. Change-Id: Ia0880a17ae55accb092ae8585cc3a1bec9986891
* VTY: implicit node exit by de-indenting, not parent lookupNeels Hofmeyr2017-09-191-24/+192
| | | | | | | | | | | | | | | | | | | | | | | | | | | |