summaryrefslogtreecommitdiff
path: root/lib/northbound_cli.c
AgeCommit message (Collapse)Author
2021-01-18lib: Correctly set temp file permissionsDonald Sharp
Set the temp file permissions to limit who can read the file. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2020-10-23*: unify thread/event cancel macrosMark Stapp
Replace all lib/thread cancel macros, use thread_cancel() everywhere. Only the THREAD_OFF macro and thread_cancel() api are supported. Also adjust thread_cancel_async() to NULL caller's pointer (if present). Signed-off-by: Mark Stapp <mjs@voltanet.io>
2020-10-05*: add errmsg to nb rpcChirag Shah
Display human readable error message in northbound rpc transaction failure. In case of vtysh nb client, the error message will be displayed to user. Testing: bharat# clear evpn dup-addr vni 1002 ip 11.11.11.11 Error type: generic error Error description: Requested IP's associated MAC aa:aa:aa:aa:aa:aa is still in duplicate state Signed-off-by: Chirag Shah <chirag@nvidia.com>
2020-09-11lib: fix crashes with leafrefs that point to non-implemented modulesRenato Westphal
Whenever libyang loads a module that contains a leafref, it will also implicitly load the module of the referring node if it's not loaded already. That makes sense as otherwise it wouldn't be possible to validate the leafref value correctly. The problem is that loading a module implicitly violates the assumption of the northbound layer that all loaded modules are implemented (i.e. they have a northbound node associated to each schema node). This means that loading a module that isn't implemented can lead to crashes as the "priv" pointer of schema nodes is no longer guaranteed to be valid. To fix this problem, add a few null checks to ignore data nodes associated to non-implemented modules. The side effect of this change is harmless. If a daemon receives configuration it doesn't support (e.g. BFD peers on staticd), that configuration will be stored but otherwise ignored. This can only happen when using a northbound client like gRPC, as the CLI will never send to a daemon a command it doesn't support. This minor problem should go away in the long run as FRR migrates to a centralized management model, at which point the YANG-modeled configuration of all daemons will be maintained in a single place. Finally, update some daemons to stop implementing YANG modules they don't need to (i.e. revert 1b741a01c and a74b47f5). Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2020-08-31lib: silence overly verbose CLI warningRenato Westphal
When not using the transactional CLI mode, do not display a warning when a YANG-modeled commmand doesn't perform any effective configuration change. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2020-08-14lib: don't ignore error messages generated during the commit apply phaseRenato Westphal
While a configuration transaction can't be rejected once it reaches the APPLY phase, we should allow NB callbacks to generate error or warning messages when a configuration change is being applied. That should be useful, for example, to return warnings back to the user informing that the applied configuration has some kind of inconsistency or is missing something in order to be effectively activated. The infrastructure for this was already present, but the northbound layer was ignoring all errors/warnings generated during the apply/abort phases instead of returning them to the user. This commit changes that. In the gRPC plugin, extend the Commit() RPC adding a new "error_message" field to the response type. This is necessary to allow errors/warnings to be returned even when the commit operation succeeds (since grpc::Status::OK doesn't support error messages like the other status codes). Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2020-08-03lib: introduce configuration back-off timer for YANG-modeled commandsRenato Westphal
When using the default CLI mode, the northbound layer needs to create a separate transaction to process each YANG-modeled command since they are supposed to be applied immediately (there's no candidate configuration nor the "commit" command like in the transactional CLI). The problem is that configuration transactions have an overhead associated to them, in big part because of the use of some heavy libyang functions like `lyd_validate()` and `lyd_diff()`. As of now this overhead is substantial and doesn't scale well when large numbers of transactions need to be performed in sequence. As an example, loading 50k prefix-lists using a single transaction takes about 2 seconds on a modern CPU. Loading the same 50k prefix-lists using 50k transactions can take more than an hour to complete (which is unacceptable by any standard). To fix this problem, some heavy optimization work needs to be done on libyang and on the FRR northbound itself too (e.g. perform partial configuration diffs whenever possible). This, however, should be a long term effort since these optimizations shouldn't be trivial to implement and we're far from having the performance numbers we need. In the meanwhile, this commit introduces a simple but efficient workaround to alleviate the issue. In short, a new back-off timer was introduced in the CLI to monitor and detect when too many YANG-modeled commands are being received at the same time. When a certain threshold is reached (100 YANG-modeled commands within one second), the northbound starts to group all subsequent commands into a single large transaction, which allows them to be processed much faster (e.g. seconds and not hours). It's essentially a protection mechanism that creates dynamically-sized transactions when necessary to prevent performance issues from happening. This mechanism is enabled both when parsing configuration files and when reading commands from a terminal. The downside of this optimization is that, if several YANG-modeled commands are grouped into the same transaction and at least one of them fails, the whole transaction is rejected. This is undesirable since users don't expect transactional behavior when that's not enabled explicitly. To minimize this issue, the CLI will log all commands that were rejected whenever that happens, to make the user aware of what happened and have enough information to fix the problem. Commands that fail due to parsing errors or CLI-level validations in general are rejected separately. Again, this proposed workaround is intended to be temporary. The goal is to provided a quick fix to issues like #6658 while we work on better long-term solutions. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2020-05-28lib: return human-readable error messages to the northbound clientsRenato Westphal
Instead of returning only error codes (e.g. NB_ERR_VALIDATION) to the northbound clients, do better than that and also return a human-readable error message. This should make FRR more automation-friendly since operators won't need to dig into system logs to find out what went wrong in the case of an error. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2020-05-28lib: introduce the northbound context structureRenato Westphal
The new northbound context structure contains information about the client performing a configuration transaction. This information will be made available to all configuration callbacks through the args->context parameter. The usefulness of this structure comes from the fact that it can be used as a communication channel (both input and output) between the northbound callbacks and the northbound clients. This can be done through its "client_data" field which contains client-specific data. This should cover some very specific scenarios where a northbound callback should perform an action only if the configuration change is coming from a given client. An example would be sending a PCEP response to a PCE when an SR-TE policy is created or modified through the PCEP northbound client (for that to happen, the northbound callbacks need to have access to the PCEP request ID, which needs to be available). Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2020-04-16*: move CLI node names to cmd_node->nameDavid Lamparter
And again for the name. Why on earth would we centralize this, just so people can forget to update it? Signed-off-by: David Lamparter <equinox@diac24.net>
2020-04-16*: remove second parameter on install_node()David Lamparter
There is really no reason to not put this in the cmd_node. And while we're add it, rename from pointless ".func" to ".config_write". [v2: fix forgotten ldpd config_write] Signed-off-by: David Lamparter <equinox@diac24.net>
2020-04-16*: remove cmd_node->vtyshDavid Lamparter
The only nodes that have this as 0 don't have a "->func" anyway, so the entire thing is really just pointless. Signed-off-by: David Lamparter <equinox@diac24.net>
2020-04-16*: clean up cmd_node initializersDavid Lamparter
... and use named assignments everywhere (so I can change the struct.) Signed-off-by: David Lamparter <equinox@diac24.net>
2019-12-06lib: new defaults logicDavid Lamparter
Since we've been writing out "frr version" and "frr defaults" for about a year and a half now, we can now actually use them to manage defaults. Signed-off-by: David Lamparter <equinox@diac24.net>
2019-11-29lib: fix display of candidate configurationsRenato Westphal
Commit 5e6a9350c16 implemented an optimization where candidate configurations are validated only before being displayed. The validation is done only to create default child nodes (due to how libyang works) and any possible error is ignored (candidate configurations can be invalid/incomplete). The problem is that we were calling lyd_validate() only when the CLI "with-defaults" option was used. But some cli_show() callbacks assume that default nodes exist and can crash when displaying a candidate configuration that isn't validated. To fix this, call lyd_validate() before displaying candidate configuration even when "with-defaults" is not used (that was a micro-optimization that shouldn't have been done). Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2019-10-16lib, vtysh: add new libyang option to the "debug northbound" commandRenato Westphal
Guard the libyang debug messages under this command so that only people interested on those messages will see them. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2019-10-14lib: fix harmless lyd_schema_sort() warningRenato Westphal
The dnode member of the nb_config structure can be null on daemons that don't implement any YANG module. As such, update the nb_cli_show_config_prepare() function to always check if the libyang data node that is going to be displayed is null or not before operating on it. This fixes the following warning (introduced by commit 5e6a9350c1): libyang: Invalid arguments (lyd_schema_sort()) Reported-by: Donald Sharp <sharpd@cumulusnetworks.com> Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2019-10-11lib: avoid expensive operations when editing a candidate configRenato Westphal
nb_candidate_edit() was calling both the lyd_schema_sort() and lyd_validate() functions whenever a new node was added to the candidate configuration. This was done to ensure the candidate is always ready to be displayed correctly (libyang only creates default child nodes during the validation process, and data nodes aren't guaranteed to be ordered by default). The problem is that the two aforementioned functions are too expensive to be called in the northbound hot path. Instead, it makes more sense to call them only before displaying the configuration (in which case a recursive sort needs to be done). Introduce the nb_cli_show_config_prepare() to achieve that purpose. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2019-10-11lib: remove expensive error handling in the northbound CLI clientRenato Westphal
The nb_cli_apply_changes() function was creating a full copy of the candidate configuration before editing it. This excerpt from the northbond documentation explains why this was being done: "NOTE: the nb_cli_cfg_change() function clones the candidate configuration before actually editing it. This way, if any error happens during the editing, the original candidate is restored to avoid inconsistencies. Either all changes from the configuration command are performed successfully or none are. It's like a mini-transaction but happening on the candidate configuration (thus the northbound callbacks are not involved)". The problem is that this kind of error handling is just too expensive. A command should never fail to edit the candidate configuration unless there's a bug in the code (e.g. when the CLI wrapper command passes an integer value that YANG rejects due to a "range" statement). In such cases, a command might fail to be applied or applied only partially if it edits multiple YANG nodes. When that happens, just log an error to make the operator aware of the problem, but otherwise ignore it instead of rejecting the command and restoring the candidate to its previous state. We shouldn't add an extreme overhead to the northbound CLI client only to handle errors that should never happen in practice. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2019-09-18Revert "lib: introduce a read-write lock for northbound configurations"Renato Westphal
Adding a lock to protect the global running configuration doesn't help much since the FRR daemons are not prepared to process configuration changes in a pthread that is not the main one (a whole lot of new protections would be necessary to prevent race conditions). This means the lock added by commit 83981138 only adds more complexity for no benefit. Remove it now to simplify the code. All northbound clients, including the gRPC one, should either run in the main pthread or use synchronization primitives to process configuration transactions in the main pthread. This reverts commit 83981138fe8c1e0a40b8dede74eca65449dda5de.
2019-08-21lib: fix uint32_t overflow in a couple of CLI commandsRenato Westphal
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2019-06-22lib: fix northbound static analyzer warningRafael Zalamena
Make the function parameter `const` so the analyzer doesn't suspect we are trying to change its value. Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
2019-06-22lib: northbound cli support to end config nodesRafael Zalamena
Some more complex CLI usages will require northbound to support signalizing a custom configuration node end. For an example: ``` router bgp 100 bgp router-id 10.254.254.1 neighbor 10.0.0.100 remote-as 200 ! address-family ipv4 unicast network 10.0.1.0/24 network 10.0.2.0/24 network 10.0.3.0/24 exit-address-family ! address-family ipv6 unicast neighbor 10.0.0.100 activate exit-address-family ! ``` This commit implements a new callback called `cli_show_end` which complements `cli_show` and is only called at the end of processing the yang configuration node. It will be used to write the configuration node termination like: "!" or "exit-address-family". Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
2019-05-28lib: Separate out the debug_init apiDonald Sharp
Separate out the debug_init api to have 2 functions: 1) Function to register a callback 2) Function to initiate the cli. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
2019-04-26lib: introduce a read-write lock for northbound configurationsRenato Westphal
The upcoming gRPC-based northbound plugin will run on a separate pthread, and it will need to have access to the running configuration global variable. Introduce a rw-lock to control concurrent access to the running configuration. Add the lock inside the "nb_config" structure so that it can be used to protect candidate configurations as well (this might be necessary depending on the threading scheme of future northbound plugins). Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2019-04-26lib: add API to allow northbound clients to lock/unlock the running ↵Renato Westphal
configuration The ability to lock the running configuration to prevent other users from changing it is a very important one. We already supported the "configure exclusive" command but the lock was applied to the CLI users only (other clients like ConfD could still commit configuration transactions, ignoring the CLI lock). This commit introduces a global lock for the running configuration that is shared by all northbound clients, and provides a public API to manipulate it. This way other northbound clients will also be able to lock/unlock the running configuration if required (the upcoming gRPC northbound plugin will have RPCs for that). NOTE: this is a management-level lock for the running configuration, not to be confused with low-level locks used to avoid data races. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2019-04-15lib: add fine-grained debugging in the northboundRenato Westphal
Split the "debug northbound" command into the following commands: * debug northbound callbacks configuration * debug northbound callbacks state * debug northbound callbacks rpc * debug northbound notifications * debug northbound events * debug northbound client confd * debug northbound client sysrepo If "debug northbound" is entered alone, all of its suboptions are enabled. This commit also adds code to debug state/rpc callbacks and notifications (only configuration callbacks were logged before). Use the debugging infrastructure from "lib/debug.h" in order to benefit from its facilities (e.g. MT-safe debugging) and avoid code duplication. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2019-01-18lib: peform only partial YANG validation when displaying operational dataRenato Westphal
When lyd_validate() is used with the LYD_OPT_DATA option, full YANG validation is performed. As a side-effect to this, default nodes are created, which is not desirable when displaying operational data since configuration nodes can also be created. Use LYD_OPT_GET option to resolve this problem. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2019-01-14lib: fix "use of uninitialised value" valgrind warningRenato Westphal
When FRR is built without the --enable-config-rollbacks option, the nb_db_transaction_save() function does nothing and the "transaction_id" output parameter is left uninitialized. For this reason, all northbound clients should initialize the "transaction_id" argument before calling nb_candidate_commit() or nb_candidate_commit_apply() (except when a NULL pointer is given, which is the case of the confd and sysrepo plugins). Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2019-01-02lib: fix segfault on freebsd when using vsnprintf() incorrectlyRenato Westphal
FreeBSD's libc segfaults when vsnprintf() is called with a null format string. Add a null check before calling vsnprintf() to resolve this problem. Fixes #3537 Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2018-12-18lib: copy xpaths when enqueing changesEmanuele Di Pascale
Just copying th const char* of the xpath means that if we are enqueing multiple changes from a buffer, the last xpath addedd will overwrite all of the previous references. Copying the xpath to a buffer simplifies the API when retrofitting the commands. Signed-off-by: Emanuele Di Pascale <emanuele@voltanet.io>
2018-12-09Merge pull request #3442 from opensourcerouting/confirmed-commitsDonald Sharp
lib: add support for confirmed commits
2018-12-07lib: implement the "show" commandRenato Westphal
The "show" command will be available in the configuration mode and all configuration subnodes. It's used to display the section of the candidate configuration being edited, instead of displaying the entire candidate configuration like when "show configuration candidate" is used. The goal is to add more convenience when editing huge configurations. When the transactional CLI mode is not used, the candidate configuration and the running configuration are identical, hence in this case we can say that the "show" command displays the section of the running configuration being edited. Example: ripd(config)# show Configuration: ! frr version 6.1-dev frr defaults traditional ! interface eth0 ip rip split-horizon poisoned-reverse ip rip authentication mode md5 ip rip authentication string supersecret ! interface eth1 ip rip receive version 1 ip rip send version 1 ! router rip allow-ecmp route 10.0.1.0/24 route 10.0.2.0/24 ! end ripd(config)# ripd(config)# ripd(config)# interface eth0 ripd(config-if)# show ! interface eth0 ip rip split-horizon poisoned-reverse ip rip authentication mode md5 ip rip authentication string supersecret ! ripd(config-if)# exit ripd(config)# ripd(config)# ripd(config)# router rip ripd(config-router)# show ! router rip allow-ecmp route 10.0.1.0/24 route 10.0.2.0/24 ! ripd(config-router)# The "show" command only works for daemons converted to the new northbound model. vtysh support will be implemented at a later time as it will require some level of coordination between vtysh and the FRR daemons. Fixes #3148. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2018-12-07lib: add support for confirmed commitsRenato Westphal
Confirmed commits allow the user to request an automatic rollback to the previous configuration if the commit operation is not confirmed within a number of minutes. This is particularly useful when the user is accessing the CLI through the network (e.g. using SSH) and any configuration change might cause an unexpected loss of connectivity between the user and the managed device (e.g. misconfiguration of a routing protocol). By using a confirmed commit, the user can rest assured the connectivity will be restored after the given timeout expires, avoiding the need to access the router physically to fix the problem. When "commit confirmed TIMEOUT" is used, a new "commit" command is expected to confirm the previous commit before the given timeout expires. If "commit confirmed TIMEOUT" is used while there's already a confirmed-commit in progress, the confirmed-commit timeout is reset to the new value. In the current implementation, if other users perform commits while there's a confirmed-commit in progress, all commits are rolled back when the confirmed-commit timeout expires. It's recommended to use the "configure exclusive" configuration mode to prevent unexpected outcomes when using confirmed commits. When an user exits from the configuration mode while there's a confirmed-commit in progress, the commit is automatically rolled back and the user is notified about it. In the future we might want to prompt the user if he or she really wants to exit from the configuration mode when there's a pending confirmed commit. Needless to say, confirmed commit only work for configuration commands converted to the new northbound model. vtysh support will be implemented at a later time. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2018-11-30Merge pull request #3378 from opensourcerouting/remove-config-lockDonald Sharp
*: remove the configuration lock from all daemons
2018-11-29Merge pull request #3342 from opensourcerouting/nb-operational-dataRuss White
Northbound: improved support for YANG-modeled operational data
2018-11-26lib, tests: major rework in the operational-data callbacksRenato Westphal
The northbound infrastructure for operational data was subpar compared to the infrastructure for configuration data. This commit addresses most of the existing problems, making it possible to write operational-data callbacks for more complex YANG models. Summary of the changes: * Add support for nested YANG lists. * Add support for leaf-lists. * Add support for leafs of type "empty". * Introduce the "show yang operational-data XPATH" command, and write an unit test for it. The main purpose of this command is to make it easier to test the operational-data northbound callbacks. * Introduce the nb_oper_data_iterate() function, that can be used to iterate over operational data. Make the CLI and sysrepo use this function. * Since ConfD has a very peculiar API, it can't reuse the nb_oper_data_iterate() like the other northbound clients. In this case, adapt the existing ConfD callbacks to support the new features (and make some performance improvements in the process). Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2018-11-26lib, tools: use CHECK_FLAG/SET_FLAG more often in the northbound codeRenato Westphal
Cosmetic change to improve code readability a bit. No binary changes. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2018-11-26*: remove the configuration lock from all daemonsRenato Westphal
A while ago all FRR configuration commands were converted to use the QOBJ infrastructure to keep track of configuration objects. This means the configuration lock isn't necessary anymore because the QOBJ code detects when someones tries to edit a configuration object that was deleted and react accordingly (log an error and abort the command). The possibility of accessing dangling pointers doesn't exist anymore since vty->index was removed. Summary of the changes: * remove the configuration lock and the vty_config_lockless() function. * rename vty_config_unlock() to vty_config_exit() since we need to clean up a few things when exiting from the configuration mode. * rename vty_config_lock() to vty_config_enter() to remove code duplication that existed between the three different "configuration" commands (terminal, private and exclusive). Configuration commands converted to the new northbound model don't need the configuration lock either since the northbound API also detects when someone tries to edit a configuration object that doesn't exist anymore. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2018-11-26lib, ripd: rework API for converted CLI commandsRenato Westphal
When editing the candidate configuration, the northbound must ensure that either all changes made by a command are accepted or none are. This is done to prevent inconsistent states where only parts of a command are applied in the event any error happens. The previous API for converted commands, the nb_cli_cfg_change() function, required callers to pass an array containing all changes that needed to be applied in the candidate configuration. The problem with this API is that it was very inconvenient for complex commands, which change different configuration options depending on several factors. This required users to manipulate the array of configuration changes using low-level primitives, making it complicated to implement some commands. To solve this problem, introduce a new API based on the two following functions: - nb_cli_enqueue_change() - nb_cli_apply_changes() The first function is used to enqueue configuration changes, one at time. Then the nb_cli_apply_changes() function is used to apply all the enqueued configuration changes. To implement this, a static-sized array was allocated in the "vty" structure, along with a counter of enqueued changes. This eliminates the need to declare an array of configuration changes in every converted CLI command, simplifying things quite considerably. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
2018-10-27lib: introduce new northbound APIRenato Westphal
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>