Fix the following address sanitizer crash when running the command `find`:
ERROR: AddressSanitizer: dynamic-stack-buffer-overflow
WRITE of size 1 at 0x7fff4840fc1d thread T0
0 in print_cmd ../lib/command.c:1541
1 in cmd_find_cmds ../lib/command.c:2364
2 in find ../vtysh/vtysh.c:3732
3 in cmd_execute_command_real ../lib/command.c:995
4 in cmd_execute_command ../lib/command.c:1055
5 in cmd_execute ../lib/command.c:1219
6 in vtysh_execute_func ../vtysh/vtysh.c:486
7 in vtysh_execute ../vtysh/vtysh.c:671
8 in main ../vtysh/vtysh_main.c:721
9 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
10 in _start (/usr/bin/vtysh+0x21f64d)
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Currently, we output the command exactly how it is defined in DEFUN.
We shouldn't output varnames and excessive whitespace.
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
This commit is a part of #5853 that add new cmd-node for SRv6 configuration.
This commit just add cmd-node and moving node cli only, acutual SRv6 config
command isn't added. (that is added later commit. of this branch)
new cli nodes:
* SRv6
* SRv6-locators
* SRv6-locator
Signed-off-by: Hiroki Shirokura <slank.dev@gmail.com>
The backoff code assumed that yang operations always completed quickly.
It checked for > 100 YANG modeled commands happening in under 1 second
to enable batching. If 100 yang modeled commands always take longer than
1 second batching is never enabled. This is the exact opposite of what
we want to happen since batching speeds the operations up.
Here are the results for libyang2 code without and with batching.
| action | 1K rts | 2K rts | 1K rts | 2K rts | 20k rts |
| | nobatch | nobatch | batch | batch | batch |
| Add IPv4 | .881 | 1.28 | .703 | 1.04 | 8.16 |
| Add Same IPv4 | 28.7 | 113 | .590 | .860 | 6.09 |
| Rem 1/2 IPv4 | .376 | .442 | .379 | .435 | 1.44 |
| Add Same IPv4 | 28.7 | 113 | .576 | .841 | 6.02 |
| Rem All IPv4 | 17.4 | 71.8 | .559 | .813 | 5.57 |
(IPv6 numbers are basically the same as iPv4, a couple percent slower)
Clearly we need this. Please note the growth (1K to 2K) w/o batching is
non-linear and 100 times slower than batched.
Notes on code: The use of the new `nb_cli_apply_changes_clear_pending`
is to commit any pending changes (including the current one). This is
done when the code would not correctly handle a single diff that
included the current changes with possible following changes. For
example, a "no" command followed by a new value to replace it would be
merged into a change, and the code would not deal well with that. A good
example of this is BGP neighbor peer-group changing. The other use is
after entering a router level (e.g., "router bgp") where the follow-on
command handlers expect that router object to now exists. The code
eventually needs to be cleaned up to not fail in these cases, but that
is for future NB cleanup.
Signed-off-by: Christian Hopps <chopps@labn.net>
The (legacy) code for reading split configs tries to execute config
commands in parent nodes, but doesn't call the node_exit function when
it goes up to a parent node. This breaks BGP RPKI setup (and extended
syslog, which is in the next commit.)
Doing this correctly is a slight bit involved since the node_exit
callbacks should only be called if the command is actually executed on a
parent node.
Signed-off-by: David Lamparter <equinox@diac24.net>
Back when I put this together in 2015, ISO C11 was still reasonably new
and we couldn't require it just yet. Without ISO C11, there is no
"good" way (only bad hacks) to require a semicolon after a macro that
ends with a function definition. And if you added one anyway, you'd get
"spurious semicolon" warnings on some compilers...
With C11, `_Static_assert()` at the end of a macro will make it so that
the semicolon is properly required, consumed, and not warned about.
Consistently requiring semicolons after "file-level" macros matches
Linux kernel coding style and helps some editors against mis-syntax'ing
these macros.
Signed-off-by: David Lamparter <equinox@diac24.net>
This new dynamic module makes pathd behave as a PCC for dynamic candidate path
using the external library pcpelib https://github.com/volta-networks/pceplib .
The candidate paths defined as dynamic will trigger computation requests to the
configured PCE, and the PCE response will be used to update the policy.
It supports multiple PCE. The one with smaller precedence will be elected
as the master PCE, and only if the connection repeatedly fails, the PCC will
switch to another PCE.
Example of configuration:
segment-routing
traffic-eng
pcep
pce-config CONF
source-address ip 10.10.10.10
sr-draft07
!
pce PCE1
config CONF
address ip 1.1.1.1
!
pce PCE2
config CONF
address ip 2.2.2.2
!
pcc
peer PCE1 precedence 10
peer PCE2 precedence 20
!
!
!
!
Co-authored-by: Brady Johnson <brady@voltanet.io>
Co-authored-by: Emanuele Di Pascale <emanuele@voltanet.io>
Co-authored-by: GalaxyGorilla <sascha@netdef.org>
Co-authored-by: Javier Garcia <javier.garcia@voltanet.io>
Co-authored-by: Renato Westphal <renato@opensourcerouting.org>
Co-authored-by: Sebastien Merle <sebastien@netdef.org>
Signed-off-by: Sebastien Merle <sebastien@netdef.org>
This new daemon manages Segment-Routing Traffic-Engineering
(SR-TE) Policies and installs them into zebra. It provides
the usual yang support and vtysh commands to define or change
SR-TE Policies.
In a nutshell SR-TE Policies provide the possibility to steer
traffic through a (possibly dynamic) list of Segment Routing
segments to the endpoint of the policy. This list of segments
is part of a Candidate Path which again belongs to the SR-TE
Policy. SR-TE Policies are uniquely identified by their color
and endpoint. The color can be used to e.g. match BGP
communities on incoming traffic.
There can be multiple Candidate Paths for a single
policy, the active Candidate Path is chosen according to
certain conditions of which the most important is its
preference. Candidate Paths can be explicit (fixed list of
segments) or dynamic (list of segment comes from e.g. PCEP, see
below).
Configuration example:
segment-routing
traffic-eng
segment-list SL
index 10 mpls label 1111
index 20 mpls label 2222
!
policy color 4 endpoint 10.10.10.4
name POL4
binding-sid 104
candidate-path preference 100 name exp explicit segment-list SL
candidate-path preference 200 name dyn dynamic
!
!
!
There is an important connection between dynamic Candidate
Paths and the overall topic of Path Computation. Later on for
pathd a dynamic module will be introduced that is capable
of communicating via the PCEP protocol with a PCE (Path
Computation Element) which again is capable of calculating
paths according to its local TED (Traffic Engineering Database).
This dynamic module will be able to inject the mentioned
dynamic Candidate Paths into pathd based on calculated paths
from a PCE.
https://tools.ietf.org/html/draft-ietf-spring-segment-routing-policy-06
Co-authored-by: Sebastien Merle <sebastien@netdef.org>
Co-authored-by: Renato Westphal <renato@opensourcerouting.org>
Co-authored-by: GalaxyGorilla <sascha@netdef.org>
Co-authored-by: Emanuele Di Pascale <emanuele@voltanet.io>
Signed-off-by: Sebastien Merle <sebastien@netdef.org>
This implements the ability to get results out from lua scripts after
they've run.
For each C type we support passing to Lua, there is a corresponding
`struct frrscript_codec`. This struct contains a typename field - just a
string identifying the type - and two function pointers. The first
function pointer, encode, takes a lua_State and a pointer to the C value
and pushes some corresponding Lua representation onto the stack. The
second, decode, assumes there is some Lua value on the stack and decodes
it into the corresponding C value.
Each supported type's `struct frrscript_codec` is registered with the
scripting stuff in the library, which creates a mapping between the type
name (string) and the `struct frrscript_codec`. When calling a script,
you specify arguments by passing an array of `struct frrscript_env`.
Each of these structs has a void *, a type name, and a desired binding
name. The type names are used to look up the appropriate function to
encode the pointed-at value onto the Lua stack, then bind the pushed
value to the provided binding name, so that the converted value is
accessible by that name within the script.
Results work in a similar way. After a script runs, call
frrscript_get_result() with the script and a `struct frrscript_env`.
The typename and name fields are used to fetch the Lua value from the
script's environment and use the registered decoder for the typename to
convert the Lua value back into a C value, which is returned from the
function. The caller is responsible for freeing these.
frrscript_call()'s macro foo has been stripped, as the underlying
function now takes fixed arrays. varargs have awful performance
characteristics, they're hard to read, and structs are more defined than
an order sensitive list.
Signed-off-by: Quentin Young <qlyoung@nvidia.com>
Rather than let Luaisms propagate from the start, this is some generic
wrapper stuff that defines some semantics for interacting with scripts
that aren't specific to the underlying language.
The concept I have in mind for FRR's idea of a script is:
- has a name
- has some inputs, which have types
- has some outputs, which have types
I don't want to even say they have to be files; maybe we can embed
scripts in frr.conf, for example. Similarly the types of inputs and
outputs are probably going to end up being some language-specific setup.
For now, we will stick to this simple model, but the plan is to add full
object support (ie calling back into C).
This shouldn't be misconstrued as prepping for multilingual scripting
support, which is a bad idea for the following reasons:
- Each language would require different FFI methods, and specifically
different object encoders; a lot of code
- Languages have different capabilities that would have to be brought to
parity with each other; a lot of work
- Languages have *vastly* different performance characteristics; bad
impressions, lots of issues we can't do anything about
- Each language would need a dedicated maintainer for the above reasons;
pragmatically difficult
- Supporting multiple languages fractures the community and limits the
audience with which a given script can be shared
The only pro for multilingual support would be ease of use for users not
familiar with Lua but familiar with one of the other supported
languages. This is not enough to outweigh the cons.
In order to get rich scripting capabilities, we need to be able to pass
representations of internal objects to the scripts. For example, a
script that performs some computation based on information about a peer
needs access to some equivalent of `struct peer` for the peer in
question. To transfer these objects from C-space into Lua-space we need
to encode them onto the Lua stack. This patch adds a mapping from
arbitrary type names to the functions that encode objects of that type.
For example, the function that encodes `struct peer` into a Lua table
could be registered with:
bgp_peer_encoder_func(struct frrscript *fs, struct peer *peer)
{
// encode peer to Lua table, push to stack in fs->scriptinfo->L
}
frrscript_register_type_encoder("peer", bgp_peer_encoder_func);
Later on when calling a script that wants a peer, the plan is to be able
to specify the type name like so:
frrscript_call(script, "peer", peer);
Using C-style types for the type names would have been nice, it might be
possible to do this with preprocessor magic or possibly python
preprocessing later on.
Signed-off-by: Quentin Young <qlyoung@nvidia.com>
mergeme no stdlib
Signed-off-by: Quentin Young <qlyoung@nvidia.com>
As part of normal processing we allow bgp commands to walk
up the command node chain. We are experiencing this crash:
Thread 1 "bgpd" received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
assertion=0x7ffff7f3ba4f "set", file=0x7ffff7f3ba44 "lib/yang.c", line=413, function=<optimized out>)
at assert.c:92
line=413, function=0x7ffff7f3bc50 <__PRETTY_FUNCTION__.9> "yang_dnode_get") at assert.c:101
vty=0x5555561715a0, argc=3, argv=0x555558601620) at bgpd/bgp_vty.c:9568
cmd=0x0) at lib/command.c:937
at lib/command.c:997
matched=0x0, vtysh=0) at lib/command.c:1161
at lib/vty.c:517
(gdb)
9582 bgp_glb_dnode = yang_dnode_get(vty->candidate_config->dnode,
(gdb) p vty->xpath
$8 = {
"/frr-routing:routing/control-plane-protocols/control-plane-protocol[type='frr-bgp:bgp'][name='bgp'][vrf='default']/frr-bgp:bgp", '\000' <repeats 897 times>, '\000' <repeats 1023 times>, '\000' <repeats 1023 times>,
'\000' <repeats 1023 times>, '\000' <repeats 1023 times>, '\000' <repeats 1023 times>, '\000' <repeats 1023 times>,
'\000' <repeats 1023 times>}
(gdb) p vty->xpath_index
$9 = 0
(gdb)
We are effectively sending in an array index based upon vty->xpath_index( which is zero) but
the VTY_CURR_XPATH macro subtracts 1 from that value to find the appropriate xpath to use.
This of course subtracts 1 from 0 and we underflow the array.
The relevant section in a config file is this:
address-family ipv6 flowspec
bgp maxim...
Effectively we were trying to walk up the command chain for flowspec to see
if the command is entered correctly. There is a function vty_check_node_for_xpath_decrement
that was looking at bgp sub-modes to make the decision to allow us to decrement
the vty->xpath_index which did not have the v4 or v6 flowspec bgp sub modes in the
check.
Adding them in fixes the problem.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
In transactional cli mode, bgp address-family <afi> <afi>
node builds xpath on top of `router bgp` node's xpath.
When `exit` is applied under afi-safi commands, retain
xpath_index to 1 to keep using bgp global xpath.
Signed-off-by: Chirag Shah <chirag@nvidia.com>
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>
rpki vrf subnode is instantiated under the vrf subnode.
It it to be noted that this commit contains a change in vtysh.
Actually, the output of bgp daemon from show running-config is extracted
in vtysh, and reengineered ( hence the vtysh_config.c change done). This
permits having a subnode under vrf sub node.
Also, add vrf node support to bgpd, as rpki command can not be found
under vrf node.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
A new config option `--disable-version-build-config`
allows you to show short version string by dropping
"configured with:" and all of its build configs
Signed-off-by: Jafar Al-Gharaibeh <jafar@atcorp.com>
This reverts commit d741915ecd.
This is because it breaks this behavior:
router ospf6
<commands>
!
int enp39s0
<more commands>
!
This is a very legal set of commands and completely destroys the
ability to do this.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Replace all `random()` calls with a function called `frr_weak_random()`
and make it clear that it is only supposed to be used for weak random
applications.
Use the annotation described by the Coverity Scan documentation to
ignore `random()` call warnings.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Rather than doing a f*gly hack for the RPKI code, let's do an on-exit
hook in cmd_node. Also allows replacing some special-casing in the vty
code.
Signed-off-by: David Lamparter <equinox@diac24.net>
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>
Same as before, instead of shoving this into a big central list we can
just put the parent node in cmd_node.
Signed-off-by: David Lamparter <equinox@diac24.net>
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>
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>
This is a full rewrite of the "back end" logging code. It now uses a
lock-free list to iterate over logging targets, and the targets
themselves are as lock-free as possible. (syslog() may have a hidden
internal mutex in the C library; the file/fd targets use a single
write() call which should ensure atomicity kernel-side.)
Note that some functionality is lost in this patch:
- Solaris printstack() backtraces are ditched (unlikely to come back)
- the `log-filter` machinery is gone (re-added in followup commit)
- `terminal monitor` is temporarily stubbed out. The old code had a
race condition with VTYs going away. It'll likely come back rewritten
and with vtysh support.
- The `zebra_ext_log` hook is gone. Instead, it's now much easier to
add a "proper" logging target.
v2: TLS buffer to get some actual performance
Signed-off-by: David Lamparter <equinox@diac24.net>
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>
This allows to set motd from an input instead of creating a file.
Example:
root@exit2-debian-9:~/frr# telnet 127.0.0.1 2605
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Hello, this is bgpd
User Access Verification
Password:
exit2-debian-9> enable
exit2-debian-9# sh run
Current configuration:
!
frr version 7.3-dev-MyOwnFRRVersion
frr defaults traditional
!
hostname exit2-debian-9
password belekas
log file /var/log/frr/labas.log
log syslog informational
banner motd line Hello, this is bgpd
!
!
!
line vty
!
end
exit2-debian-9#
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
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>