Currently there is a single interval for both RX and TX echo functions.
This commit introduces separate RX and TX timers for echo packets.
The main advantage is to be able to set the receive interval to zero
when we don't want to receive echo packets from the remote system.
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
Currently this timer is only started when we receive the first echo
packet. If we never receive the packet, the timer is never started and
the user falsely assumes that echo function is working.
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
Current behavior is inconsistent. When the session is created by another
daemon, it is up by default. When we later configure peer in bfdd, the
session is still up, but the NB layer thinks that it is down.
More than that, even when the session is created in bfdd using peer
command, it is created in DOWN state, not ADM_DOWN. And it actually
starts sending and receiving packets. The sessions is marked with
SHUTDOWN flag only when we try to reconfigure some parameter. This
behavior is also very unexpected.
Fixes#7780.
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
RFC 5880 Section 6.8.4:
In Asynchronous mode, the Detection Time calculated in the local
system is equal to the value of Detect Mult received from the remote
system, multiplied by the agreed transmit interval of the remote
system (the greater of bfd.RequiredMinRxInterval and the last
received Desired Min TX Interval).
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
BFD key has optional fields "local" and "ifname" which can be empty when
the BFD session is created. In this case, the hash key will be calculated
with these fields filled with zeroes.
Later, when we're looking for the BFD session using the key with fields
"local" and "ifname" populated with actual values, the hash key will be
different. To work around this issue, we're doing multiple hash lookups,
first with full key, then with fields "local" and "ifname" filled with
zeroes.
But there may be another case when the initial key has the actual values
for "local" and "ifname", but the key we're using for lookup has empty
values. This case is covered for IPv4 by using additional hash walk with
bfd_key_lookup_ignore_partial_walker function but is not covered for IPv6.
Instead of introducing more hacks and workarounds, the following solution
is proposed:
- the hash key is always calculated in bfd_key_hash_do using only
required fields
- the hash data is compared in bfd_key_hash_cmp, taking into account the
fact that fields "local" and "ifname" may be empty
Using this solution, it's enough to make only one hash lookup.
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
when receiving interface and address notifications, one may be puzzled
by the information since for example, the presence of an interface is
not enough to use it in a bfd session, simply because the interface is
in the wrong vrf. add VRF information on those traces.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
The vrf interface notification and interface notifications are separated
on zapi interface between the system (zebra daemon) and other daemons
(bfd for instance). In the case of bfd, the initial code was waiting for
vrf notification to create the socket. Actually, in vrf-lite world, we
need to wait the vrf interface to be present, in order to create the
socket and bind to the vrf interface (this is the usual way to work with
vrf-lite).
On bfd, the changes consist in delaying the socket creation first, then
when interface is created, check the interface name presence instead of
checking the interface configuration.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Don't reset interface/vrf pointer everytime a session is disabled
instead only do it when it was explicitly removed.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Add hooks in the correct places so the BFD daemon uses the data plane
instead of the software packet sending implementation to monitor the
session.
This code also adds some handlers to support fallback to FRR BFD session
handling, however since this complicates the code it won't work at the
moment (the BFD sockets are disabled by default when using data plane).
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
The current distributed BFD implementantion doesn't support falling back
to software implementation in FRR, so to keep the code simple lets give
the data plane full control of the BFD packet handling (helps running a
software data plane for testing too otherwise it would fail with 'address
in use' error).
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Allows users with multiple links using same IPv6 address (same VRF) to
work.
Reported-by: Matti Suuronen
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Previously if there were two multihop peers created that had the same
peer address but different local addresses then the second peer to be
created would be merged with the first one and niether would be able to
be deleted. This was due to an issue in the function bfd_key_lookup().
When the second peer was created its key would be sent into the lookup
function and would reach the last section, even though it shouldn't
have. A check has been placed around the section so that it will not be
entered if a peer is multihop.
Signed-off-by: Tashana Mehta-Wilson <tashana.mehta-wilson@alliedtelesis.co.nz>
Experimental patch to allow us to discuss if we should
allow bfdd to work when v6 is turned off in the kernel.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Initial BFD protocol implementation had a hard coded value of maximum 5
hops, now we have a configurable hop amount with a safe default of 1
hop.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
The passive mode is briefly described in the RFC 5880 Bidirectional
Forwarding Detection (BFD), Section 6.1. Overview:
> A system may take either an Active role or a Passive role in session
> initialization. A system taking the Active role MUST send BFD
> Control packets for a particular session, regardless of whether it
> has received any BFD packets for that session. A system taking the
> Passive role MUST NOT begin sending BFD packets for a particular
> session until it has received a BFD packet for that session, and thus
> has learned the remote system's discriminator value. At least one
> system MUST take the Active role (possibly both). The role that a
> system takes is specific to the application of BFD, and is outside
> the scope of this specification.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Remove mid-string line breaks, cf. workflow doc:
.. [#tool_style_conflicts] For example, lines over 80 characters are allowed
for text strings to make it possible to search the code for them: please
see `Linux kernel style (breaking long lines and strings)
<https://www.kernel.org/doc/html/v4.10/process/coding-style.html#breaking-long-lines-and-strings>`_
and `Issue #1794 <https://github.com/FRRouting/frr/issues/1794>`_.
Scripted commit, idempotent to running:
```
python3 tools/stringmangle.py --unwrap `git ls-files | egrep '\.[ch]$'`
```
Signed-off-by: David Lamparter <equinox@diac24.net>
During the shutdown phase don't attempt to apply settings to peers
as it is useless and will crash if the peer hash is gone.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Implement the infrastructure for other protocols daemon (e.g. `bgpd`,
`ospfd`, `isisd` etc...) to communicate to BFD daemon which profile
they want to use with their peers.
It was also added the ability for protocols to change profile while
running (no need to remove the registration and then register again).
The protocols message building function was rewritten to support
multiple arguments through `struct bfd_session_arg`, so we can
implement new features without the need of changing function
prototypes. The old function was also rewritten to keep
compatibility.
The profile message part is only available for BFD daemon at the
moment.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Allow user to pre-configure peers with a profile. If a peer is using a
profile any configuration made to the peer will take precedence over
the profile configuration.
In order to track the peer configuration we have now an extra copy of
the peer configuration in `peer_profile` inside `struct bfd_session`.
This information will help the profile functions to detect user
configurations and avoid overriding what the user configured. This is
especially important for peers created via other protocols where the
default `shutdown` state is disabled (peers created manually are
`shutdown` by default).
Profiles can be used before they exist: if no profile exists then it
will use the default configuration.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
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>
Don't attempt to handle out-of-memory situations: XMALLOC/XCALLOC will
`assert` if there is no memory left.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Move most of the log messages to debug guards so they only get activated
if the user configured the proper debug level.
Current debug levels:
- Peer events.
- Zebra events.
- Network layer debugs.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
According to the RFC 5880 the transmission time should be mandated by
the slowest system.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Use the interface VRF information instead of relying on the VRF specific
socket information.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
(cherry picked from commit c05c48621c)
Always bind the created sockets to their respective VRF devices. With
this it should be possible to run BFD on VRFs without needing to weaken
the security setting `net.ipv4.udp_l3mdev_accept=1`.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Scenarios where this code change is required:
1. BFD is un-configured from BGP at remote end.
Neighbour BFD sends ADMIN_DOWN state, but BFD on local side will send
DOWN to BGP, resulting in BGP session DOWN.
Removing BFD session administratively shouldn't bring DOWN BGP session
at local or remote.
2. BFD is un-configured from BGP or shutdown locally.
BFD will send state DOWN to BGP resulting in BGP session DOWN.
(This is akin to saying do not use BFD for BGP)
Removing BFD session administratively shouldn't bring DOWN BGP session at
local or remote.
Signed-off-by: Sayed Mohd Saquib sayed.saquib@broadcom.com
Don't be selective about what to observe, always observe all possible
aspects of the session that may change on run-time (i.e. bind address,
interface and VRF existence).
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
If a session is no longer able to send/receive packets, it is very
likely it will be down in a few milliseconds so lets speed up the
process and correctly mark it as down.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Otherwise the `thread_read` will keep waking us up to handle closing
sockets which are never unregistered.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
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 83981138fe.