2023-02-08 13:17:09 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2015-06-12 16:59:11 +02:00
|
|
|
/**
|
|
|
|
* bgp_bfd.c: BGP BFD handling routines
|
|
|
|
*
|
|
|
|
* @copyright Copyright (C) 2015 Cumulus Networks, Inc.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
|
|
|
#include "command.h"
|
|
|
|
#include "linklist.h"
|
|
|
|
#include "memory.h"
|
|
|
|
#include "prefix.h"
|
2023-03-07 20:22:48 +01:00
|
|
|
#include "frrevent.h"
|
2015-06-12 16:59:11 +02:00
|
|
|
#include "buffer.h"
|
|
|
|
#include "stream.h"
|
2021-02-26 20:50:51 +01:00
|
|
|
#include "vrf.h"
|
2015-06-12 16:59:11 +02:00
|
|
|
#include "zclient.h"
|
2015-07-22 21:35:37 +02:00
|
|
|
#include "bfd.h"
|
2015-08-12 15:59:18 +02:00
|
|
|
#include "lib/json.h"
|
2016-01-07 16:03:01 +01:00
|
|
|
#include "filter.h"
|
|
|
|
|
2015-06-12 16:59:11 +02:00
|
|
|
#include "bgpd/bgpd.h"
|
2015-07-22 21:35:37 +02:00
|
|
|
#include "bgp_fsm.h"
|
2015-06-12 16:59:11 +02:00
|
|
|
#include "bgpd/bgp_bfd.h"
|
|
|
|
#include "bgpd/bgp_debug.h"
|
|
|
|
#include "bgpd/bgp_vty.h"
|
2022-05-30 16:40:15 +02:00
|
|
|
#include "bgpd/bgp_packet.h"
|
2015-06-12 16:59:11 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
DEFINE_MTYPE_STATIC(BGPD, BFD_CONFIG, "BFD configuration data");
|
|
|
|
|
2015-06-12 16:59:11 +02:00
|
|
|
extern struct zclient *zclient;
|
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
static void bfd_session_status_update(struct bfd_session_params *bsp,
|
|
|
|
const struct bfd_session_status *bss,
|
|
|
|
void *arg)
|
2015-06-12 16:59:11 +02:00
|
|
|
{
|
2021-02-26 20:50:51 +01:00
|
|
|
struct peer *peer = arg;
|
2015-07-22 21:35:37 +02:00
|
|
|
|
2021-03-01 20:07:28 +01:00
|
|
|
if (BGP_DEBUG(bfd, BFD_LIB))
|
2021-02-26 20:50:51 +01:00
|
|
|
zlog_debug("%s: neighbor %s vrf %s(%u) bfd state %s -> %s",
|
|
|
|
__func__, peer->conf_if ? peer->conf_if : peer->host,
|
|
|
|
bfd_sess_vrf(bsp), bfd_sess_vrf_id(bsp),
|
|
|
|
bfd_get_status_str(bss->previous_state),
|
|
|
|
bfd_get_status_str(bss->state));
|
|
|
|
|
|
|
|
if (bss->state == BSS_DOWN && bss->previous_state == BSS_UP) {
|
|
|
|
if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_MODE)
|
|
|
|
&& bfd_sess_cbit(bsp) && !bss->remote_cbit) {
|
2021-03-01 20:07:28 +01:00
|
|
|
if (BGP_DEBUG(bfd, BFD_LIB))
|
2022-06-21 10:59:52 +02:00
|
|
|
zlog_debug(
|
2021-02-26 20:50:51 +01:00
|
|
|
"%s BFD DOWN message ignored in the process of graceful restart when C bit is cleared",
|
|
|
|
peer->host);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
peer->last_reset = PEER_DOWN_BFD_DOWN;
|
2022-05-30 16:40:15 +02:00
|
|
|
|
2023-04-01 20:56:37 +02:00
|
|
|
/* rfc9384 */
|
2021-08-10 05:43:46 +02:00
|
|
|
if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status))
|
2023-08-26 23:30:10 +02:00
|
|
|
bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE,
|
2022-05-30 16:40:15 +02:00
|
|
|
BGP_NOTIFY_CEASE_BFD_DOWN);
|
|
|
|
|
2023-08-27 00:07:04 +02:00
|
|
|
BGP_EVENT_ADD(peer->connection, BGP_Stop);
|
2021-02-26 20:50:51 +01:00
|
|
|
}
|
2015-06-12 16:59:11 +02:00
|
|
|
|
2023-08-27 00:11:07 +02:00
|
|
|
if (bss->state == BSS_UP && bss->previous_state != BSS_UP &&
|
|
|
|
!peer_established(peer->connection)) {
|
2021-02-26 20:50:51 +01:00
|
|
|
if (!BGP_PEER_START_SUPPRESSED(peer)) {
|
2023-08-28 16:47:41 +02:00
|
|
|
bgp_fsm_nht_update(peer->connection, peer, true);
|
2023-08-27 00:07:04 +02:00
|
|
|
BGP_EVENT_ADD(peer->connection, BGP_Start);
|
2021-02-26 20:50:51 +01:00
|
|
|
}
|
|
|
|
}
|
2015-06-12 16:59:11 +02:00
|
|
|
}
|
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
void bgp_peer_config_apply(struct peer *p, struct peer_group *pg)
|
2015-06-12 16:59:11 +02:00
|
|
|
{
|
2021-02-26 20:50:51 +01:00
|
|
|
struct listnode *n;
|
|
|
|
struct peer *pn;
|
|
|
|
struct peer *gconfig;
|
|
|
|
|
|
|
|
/* When called on a group, apply to all peers. */
|
|
|
|
if (CHECK_FLAG(p->sflags, PEER_STATUS_GROUP)) {
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(p->group->peer, n, pn))
|
|
|
|
bgp_peer_config_apply(pn, pg);
|
|
|
|
return;
|
|
|
|
}
|
2016-04-22 00:39:38 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
/* No group, just use current configuration. */
|
|
|
|
if (pg == NULL || pg->conf->bfd_config == NULL) {
|
|
|
|
bfd_sess_set_timers(p->bfd_config->session,
|
|
|
|
p->bfd_config->detection_multiplier,
|
|
|
|
p->bfd_config->min_rx,
|
|
|
|
p->bfd_config->min_tx);
|
|
|
|
bfd_sess_set_cbit(p->bfd_config->session, p->bfd_config->cbit);
|
|
|
|
bfd_sess_set_profile(p->bfd_config->session,
|
|
|
|
p->bfd_config->profile);
|
|
|
|
bfd_sess_install(p->bfd_config->session);
|
|
|
|
return;
|
|
|
|
}
|
2016-04-22 00:39:38 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
/*
|
|
|
|
* Check if the group configuration was overwritten or apply group
|
|
|
|
* configuration.
|
|
|
|
*/
|
|
|
|
gconfig = pg->conf;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If using default control plane independent configuration,
|
|
|
|
* then prefer group's (e.g. it means it wasn't manually configured).
|
|
|
|
*/
|
|
|
|
if (!p->bfd_config->cbit)
|
|
|
|
bfd_sess_set_cbit(p->bfd_config->session,
|
|
|
|
gconfig->bfd_config->cbit);
|
|
|
|
else
|
|
|
|
bfd_sess_set_cbit(p->bfd_config->session, p->bfd_config->cbit);
|
2016-04-22 00:39:38 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
/* If no profile was specified in peer, then use the group profile. */
|
|
|
|
if (p->bfd_config->profile[0] == 0)
|
|
|
|
bfd_sess_set_profile(p->bfd_config->session,
|
|
|
|
gconfig->bfd_config->profile);
|
2015-06-12 16:59:11 +02:00
|
|
|
else
|
2021-02-26 20:50:51 +01:00
|
|
|
bfd_sess_set_profile(p->bfd_config->session,
|
|
|
|
p->bfd_config->profile);
|
|
|
|
|
|
|
|
/* If no specific timers were configured, then use the group timers. */
|
|
|
|
if (p->bfd_config->detection_multiplier == BFD_DEF_DETECT_MULT
|
|
|
|
|| p->bfd_config->min_rx == BFD_DEF_MIN_RX
|
|
|
|
|| p->bfd_config->min_tx == BFD_DEF_MIN_TX)
|
|
|
|
bfd_sess_set_timers(p->bfd_config->session,
|
|
|
|
gconfig->bfd_config->detection_multiplier,
|
|
|
|
gconfig->bfd_config->min_rx,
|
|
|
|
gconfig->bfd_config->min_tx);
|
|
|
|
else
|
|
|
|
bfd_sess_set_timers(p->bfd_config->session,
|
|
|
|
p->bfd_config->detection_multiplier,
|
|
|
|
p->bfd_config->min_rx,
|
|
|
|
p->bfd_config->min_tx);
|
|
|
|
|
|
|
|
bfd_sess_install(p->bfd_config->session);
|
2015-06-12 16:59:11 +02:00
|
|
|
}
|
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
void bgp_peer_bfd_update_source(struct peer *p)
|
2015-06-12 16:59:11 +02:00
|
|
|
{
|
2021-02-26 20:50:51 +01:00
|
|
|
struct bfd_session_params *session = p->bfd_config->session;
|
2021-11-03 12:43:17 +01:00
|
|
|
const union sockunion *source;
|
2021-02-26 20:50:51 +01:00
|
|
|
bool changed = false;
|
|
|
|
int family;
|
|
|
|
union {
|
|
|
|
struct in_addr v4;
|
|
|
|
struct in6_addr v6;
|
|
|
|
} src, dst;
|
|
|
|
|
|
|
|
/* Nothing to do for groups. */
|
|
|
|
if (CHECK_FLAG(p->sflags, PEER_STATUS_GROUP))
|
bgpd: fix crash on daemon exit
Don't attempt to send BFD daemon a message to remove the peer
registration on daemon exit, otherwise we'll access a dangling
interface pointer and we'll crash.
This crash was not previosly possible because the function that built
the message was passing the interface pointer but not using it due to
the exit condition.
In `lib/bfd.c`:
```
void bfd_peer_sendmsg(struct zclient *zclient, struct bfd_info *bfd_info,
int family, void *dst_ip, void *src_ip, char *if_name,
int ttl, int multihop, int cbit, int command,
int set_flag, vrf_id_t vrf_id)
{
struct bfd_session_arg args = {};
size_t addrlen;
/* Individual reg/dereg messages are suppressed during shutdown. */
if (CHECK_FLAG(bfd_gbl.flags, BFD_GBL_FLAG_IN_SHUTDOWN)) {
if (bfd_debug)
zlog_debug(
"%s: Suppressing BFD peer reg/dereg messages",
__func__);
return;
}
```
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
2020-05-21 21:02:44 +02:00
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-11-03 12:43:17 +01:00
|
|
|
/* Figure out the correct source to use. */
|
2021-11-12 17:32:06 +01:00
|
|
|
if (CHECK_FLAG(p->flags, PEER_FLAG_UPDATE_SOURCE) && p->update_source)
|
2021-11-03 12:43:17 +01:00
|
|
|
source = p->update_source;
|
|
|
|
else
|
|
|
|
source = p->su_local;
|
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
/* Update peer's source/destination addresses. */
|
|
|
|
bfd_sess_addresses(session, &family, &src.v6, &dst.v6);
|
|
|
|
if (family == AF_INET) {
|
2023-09-08 18:02:05 +02:00
|
|
|
if ((source && source->sin.sin_addr.s_addr != src.v4.s_addr) ||
|
|
|
|
p->connection->su.sin.sin_addr.s_addr != dst.v4.s_addr) {
|
2021-03-01 20:07:28 +01:00
|
|
|
if (BGP_DEBUG(bfd, BFD_LIB))
|
2023-09-08 18:02:05 +02:00
|
|
|
zlog_debug("%s: address [%pI4->%pI4] to [%pI4->%pI4]",
|
|
|
|
__func__, &src.v4, &dst.v4,
|
|
|
|
source ? &source->sin.sin_addr
|
|
|
|
: &src.v4,
|
|
|
|
&p->connection->su.sin.sin_addr);
|
|
|
|
|
|
|
|
bfd_sess_set_ipv4_addrs(session,
|
|
|
|
source ? &source->sin.sin_addr
|
|
|
|
: NULL,
|
|
|
|
&p->connection->su.sin.sin_addr);
|
2021-02-26 20:50:51 +01:00
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
} else {
|
2023-09-08 18:02:05 +02:00
|
|
|
if ((source && memcmp(&source->sin6, &src.v6, sizeof(src.v6))) ||
|
|
|
|
memcmp(&p->connection->su.sin6, &dst.v6, sizeof(dst.v6))) {
|
2021-03-01 20:07:28 +01:00
|
|
|
if (BGP_DEBUG(bfd, BFD_LIB))
|
2023-09-08 18:02:05 +02:00
|
|
|
zlog_debug("%s: address [%pI6->%pI6] to [%pI6->%pI6]",
|
|
|
|
__func__, &src.v6, &dst.v6,
|
|
|
|
source ? &source->sin6.sin6_addr
|
|
|
|
: &src.v6,
|
|
|
|
&p->connection->su.sin6.sin6_addr);
|
2021-02-26 20:50:51 +01:00
|
|
|
|
2021-11-03 12:43:17 +01:00
|
|
|
bfd_sess_set_ipv6_addrs(session,
|
|
|
|
source ? &source->sin6.sin6_addr
|
|
|
|
: NULL,
|
2023-09-08 18:02:05 +02:00
|
|
|
&p->connection->su.sin6.sin6_addr);
|
2021-02-26 20:50:51 +01:00
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
/* Update interface. */
|
|
|
|
if (p->nexthop.ifp && bfd_sess_interface(session) == NULL) {
|
2021-03-01 20:07:28 +01:00
|
|
|
if (BGP_DEBUG(bfd, BFD_LIB))
|
2021-02-26 20:50:51 +01:00
|
|
|
zlog_debug("%s: interface none to %s", __func__,
|
|
|
|
p->nexthop.ifp->name);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
bfd_sess_set_interface(session, p->nexthop.ifp->name);
|
|
|
|
changed = true;
|
2016-04-22 00:39:38 +02:00
|
|
|
}
|
2021-02-26 20:50:51 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Update TTL.
|
|
|
|
*
|
|
|
|
* Two cases:
|
|
|
|
* - We detected that the peer is a hop away from us (remove multi hop).
|
|
|
|
* (this happens when `p->shared_network` is set to `true`)
|
|
|
|
* - eBGP multi hop / TTL security changed.
|
bfdd, lib, bgpd: add bfd cbit usage
bfd cbit is a value carried out in bfd messages, that permit to keep or
not, the independence between control plane and dataplane. In other
words, while most of the cases plan to flush entries, when bfd goes
down, there are some cases where that bfd event should be ignored. this
is the case with non stop forwarding mechanisms where entries may be
kept. this is the case for BGP, when graceful restart capability is
used. If BFD event down happens, and bgp is in graceful restart mode, it
is wished to ignore the BFD event while waiting for the remote router to
restart.
The changes take into account the following:
- add a config flag across zebra layer so that daemon can set or not the
cbit capability.
- ability for daemons to read the remote bfd capability associated to a bfd
notification.
- in bfdd, according to the value, the cbit value is set
- in bfdd, the received value is retrived and stored in the bfd session
context.
- by default, the local cbit announced to remote is set to 1 while
preservation of the local path is not set.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2019-04-15 17:20:25 +02:00
|
|
|
*/
|
2021-02-26 20:50:51 +01:00
|
|
|
if (!PEER_IS_MULTIHOP(p) && bfd_sess_hop_count(session) > 1) {
|
2021-03-01 20:07:28 +01:00
|
|
|
if (BGP_DEBUG(bfd, BFD_LIB))
|
2021-02-26 20:50:51 +01:00
|
|
|
zlog_debug("%s: TTL %d to 1", __func__,
|
|
|
|
bfd_sess_hop_count(session));
|
2020-05-20 01:15:20 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
bfd_sess_set_hop_count(session, 1);
|
|
|
|
changed = true;
|
2020-05-20 01:15:20 +02:00
|
|
|
}
|
2021-02-26 20:50:51 +01:00
|
|
|
if (PEER_IS_MULTIHOP(p) && p->ttl != bfd_sess_hop_count(session)) {
|
2021-03-01 20:07:28 +01:00
|
|
|
if (BGP_DEBUG(bfd, BFD_LIB))
|
2021-02-26 20:50:51 +01:00
|
|
|
zlog_debug("%s: TTL %d to %d", __func__,
|
|
|
|
bfd_sess_hop_count(session), p->ttl);
|
2020-05-20 01:15:20 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
bfd_sess_set_hop_count(session, p->ttl);
|
|
|
|
changed = true;
|
2020-05-20 01:15:20 +02:00
|
|
|
}
|
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
/* Update VRF. */
|
|
|
|
if (bfd_sess_vrf_id(session) != p->bgp->vrf_id) {
|
2021-03-01 20:07:28 +01:00
|
|
|
if (BGP_DEBUG(bfd, BFD_LIB))
|
2021-02-26 20:50:51 +01:00
|
|
|
zlog_debug(
|
|
|
|
"%s: VRF %s(%d) to %s(%d)", __func__,
|
|
|
|
bfd_sess_vrf(session), bfd_sess_vrf_id(session),
|
|
|
|
vrf_id_to_name(p->bgp->vrf_id), p->bgp->vrf_id);
|
|
|
|
|
|
|
|
bfd_sess_set_vrf(session, p->bgp->vrf_id);
|
|
|
|
changed = true;
|
2020-05-20 01:15:20 +02:00
|
|
|
}
|
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
if (changed)
|
|
|
|
bfd_sess_install(session);
|
2015-06-12 16:59:11 +02:00
|
|
|
}
|
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
/**
|
|
|
|
* Reset BFD configuration data structure to its defaults settings.
|
2015-06-12 16:59:11 +02:00
|
|
|
*/
|
2021-02-26 20:50:51 +01:00
|
|
|
static void bgp_peer_bfd_reset(struct peer *p)
|
2015-06-12 16:59:11 +02:00
|
|
|
{
|
2021-02-26 20:50:51 +01:00
|
|
|
/* Set defaults. */
|
|
|
|
p->bfd_config->detection_multiplier = BFD_DEF_DETECT_MULT;
|
|
|
|
p->bfd_config->min_rx = BFD_DEF_MIN_RX;
|
|
|
|
p->bfd_config->min_tx = BFD_DEF_MIN_TX;
|
|
|
|
p->bfd_config->cbit = false;
|
|
|
|
p->bfd_config->profile[0] = 0;
|
2015-06-12 16:59:11 +02:00
|
|
|
}
|
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
void bgp_peer_configure_bfd(struct peer *p, bool manual)
|
2015-06-12 16:59:11 +02:00
|
|
|
{
|
2021-02-26 20:50:51 +01:00
|
|
|
/* Groups should not call this. */
|
|
|
|
assert(!CHECK_FLAG(p->sflags, PEER_STATUS_GROUP));
|
2015-06-12 16:59:11 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
/* Already configured, skip it. */
|
|
|
|
if (p->bfd_config) {
|
|
|
|
/* If manually active update flag. */
|
|
|
|
if (!p->bfd_config->manual)
|
|
|
|
p->bfd_config->manual = manual;
|
2015-06-12 16:59:11 +02:00
|
|
|
|
|
|
|
return;
|
2021-02-26 20:50:51 +01:00
|
|
|
}
|
2015-06-12 16:59:11 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
/* Allocate memory for configuration overrides. */
|
|
|
|
p->bfd_config = XCALLOC(MTYPE_BFD_CONFIG, sizeof(*p->bfd_config));
|
|
|
|
p->bfd_config->manual = manual;
|
2015-06-12 16:59:11 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
/* Create new session and assign callback. */
|
|
|
|
p->bfd_config->session = bfd_sess_new(bfd_session_status_update, p);
|
|
|
|
bgp_peer_bfd_reset(p);
|
2015-06-12 16:59:11 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
/* Configure session with basic BGP peer data. */
|
2023-09-08 18:02:05 +02:00
|
|
|
if (p->connection->su.sa.sa_family == AF_INET)
|
2021-02-26 20:50:51 +01:00
|
|
|
bfd_sess_set_ipv4_addrs(p->bfd_config->session,
|
|
|
|
p->su_local ? &p->su_local->sin.sin_addr
|
|
|
|
: NULL,
|
2023-09-08 18:02:05 +02:00
|
|
|
&p->connection->su.sin.sin_addr);
|
2021-02-26 20:50:51 +01:00
|
|
|
else
|
2023-09-08 18:02:05 +02:00
|
|
|
bfd_sess_set_ipv6_addrs(p->bfd_config->session,
|
|
|
|
p->su_local
|
|
|
|
? &p->su_local->sin6.sin6_addr
|
|
|
|
: NULL,
|
|
|
|
&p->connection->su.sin6.sin6_addr);
|
2015-06-12 16:59:11 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
bfd_sess_set_vrf(p->bfd_config->session, p->bgp->vrf_id);
|
|
|
|
bfd_sess_set_hop_count(p->bfd_config->session,
|
|
|
|
PEER_IS_MULTIHOP(p) ? p->ttl : 1);
|
2015-06-12 16:59:11 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
if (p->nexthop.ifp)
|
|
|
|
bfd_sess_set_interface(p->bfd_config->session,
|
|
|
|
p->nexthop.ifp->name);
|
bgpd: reset bfd session when bgp comes up
This scenario has been seen against microtik virtual machine with
bfd enabled. When remote microtik bgp reestablishes the bgp session
after a bgp reset, the bgp establishment comes first, then bfd is
initialising.
The second point is true for microtik, but not for frrouting, as the
frrouting, when receiving bfd down messages, is not at init state.
Actually, bfd state is up, and sees the first bfd down packet from
bfd as an issue. Consequently, the BGP session is cleared.
The fix consists in resetting the BFD session, only if bfd status is
considered as up, once BGP comes up.
That permits to align state machines of both local and remote bfd.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2020-03-12 14:04:30 +01:00
|
|
|
}
|
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
static void bgp_peer_remove_bfd(struct peer *p)
|
2016-04-22 00:39:38 +02:00
|
|
|
{
|
2021-02-26 20:50:51 +01:00
|
|
|
/* Groups should not call this. */
|
|
|
|
assert(!CHECK_FLAG(p->sflags, PEER_STATUS_GROUP));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
/*
|
|
|
|
* Peer configuration was removed, however we must check if there
|
|
|
|
* is still a group configuration to keep this running.
|
|
|
|
*/
|
|
|
|
if (p->group && p->group->conf->bfd_config) {
|
|
|
|
p->bfd_config->manual = false;
|
|
|
|
bgp_peer_bfd_reset(p);
|
|
|
|
bgp_peer_config_apply(p, p->group);
|
2016-04-22 00:39:38 +02:00
|
|
|
return;
|
|
|
|
}
|
2015-06-12 16:59:11 +02:00
|
|
|
|
2021-07-14 03:46:40 +02:00
|
|
|
if (p->bfd_config)
|
|
|
|
bfd_sess_free(&p->bfd_config->session);
|
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
XFREE(MTYPE_BFD_CONFIG, p->bfd_config);
|
2015-06-12 16:59:11 +02:00
|
|
|
}
|
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
static void bgp_group_configure_bfd(struct peer *p)
|
Support of BFD status in Quagga
Ticket:CM-6802, CM-6952
Reviewed By: Donald, Kanna
Testing Done:
Double commit of b76943235e09472ec174edcf7204fc82d27fe966 from br2.5. But, manually resolved all the compilation errors. Also, modified the shows to support the json format which was not supported in br2.5.
CM-6802 – Currently, BFD session status can be monitored only through ptmctl. There is no way to check the BFD status of a peer/neighbor through Quagga. Debugging becomes easier if BFD status is shown in Quagga too. BFD status is relevant when it is shown against the BGP peer/OSPF neighbor. For, this following code changes have been done:
- Only down messages from PTM were being propagated from Zebra daemon to clients (bgpd, ospfd and ospf6d). Now, both up and down messages are redistributed to the clients from zebra. BFD status field has been added to the messaging. Handling of BFD session up messages has been added to the client code. BGP/OSPF neighbor is brought down only if the old BFD session status is ‘Up’ to handle extra/initial down messages.
- BFD status and last update timestamp fields have been added to the common BFD info structure. Also, common show functions for showing BFD information have been added to BFD lib.
- Modified the BGP neighbor show functions to call common BFD lib functions.
- For ospf and ospf6, BFD information was maintained only at interface level. To show BFD status per neighbor, BFD information has been added at neighbor level too. “show ip ospf interface”, “show ip ospf neighbor detail”, “show ipv6 ospf6 interface” and “show ipv6 ospf6 neighbor detail” output have been modified to show BFD information.
CM-6952 - IBGP peers were always assumed to be multi-hop since there was no easy way to determine whether an IBGP peer was single hop or multihop unlike EBGP. But, this is causing problem with IBGP link local peers since BFD doesn't allow multihop BFD session with link local IP addresses. Link local peers were discovered when the interface peering was enabled. Interface peering is always singlehop. So, added checks to treat all interface based peers as single hop irrespective of whether the peer is IBGP or EBGP.
2015-08-31 23:56:11 +02:00
|
|
|
{
|
2021-02-26 20:50:51 +01:00
|
|
|
struct listnode *n;
|
|
|
|
struct peer *pn;
|
Support of BFD status in Quagga
Ticket:CM-6802, CM-6952
Reviewed By: Donald, Kanna
Testing Done:
Double commit of b76943235e09472ec174edcf7204fc82d27fe966 from br2.5. But, manually resolved all the compilation errors. Also, modified the shows to support the json format which was not supported in br2.5.
CM-6802 – Currently, BFD session status can be monitored only through ptmctl. There is no way to check the BFD status of a peer/neighbor through Quagga. Debugging becomes easier if BFD status is shown in Quagga too. BFD status is relevant when it is shown against the BGP peer/OSPF neighbor. For, this following code changes have been done:
- Only down messages from PTM were being propagated from Zebra daemon to clients (bgpd, ospfd and ospf6d). Now, both up and down messages are redistributed to the clients from zebra. BFD status field has been added to the messaging. Handling of BFD session up messages has been added to the client code. BGP/OSPF neighbor is brought down only if the old BFD session status is ‘Up’ to handle extra/initial down messages.
- BFD status and last update timestamp fields have been added to the common BFD info structure. Also, common show functions for showing BFD information have been added to BFD lib.
- Modified the BGP neighbor show functions to call common BFD lib functions.
- For ospf and ospf6, BFD information was maintained only at interface level. To show BFD status per neighbor, BFD information has been added at neighbor level too. “show ip ospf interface”, “show ip ospf neighbor detail”, “show ipv6 ospf6 interface” and “show ipv6 ospf6 neighbor detail” output have been modified to show BFD information.
CM-6952 - IBGP peers were always assumed to be multi-hop since there was no easy way to determine whether an IBGP peer was single hop or multihop unlike EBGP. But, this is causing problem with IBGP link local peers since BFD doesn't allow multihop BFD session with link local IP addresses. Link local peers were discovered when the interface peering was enabled. Interface peering is always singlehop. So, added checks to treat all interface based peers as single hop irrespective of whether the peer is IBGP or EBGP.
2015-08-31 23:56:11 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
/* Peers should not call this. */
|
|
|
|
assert(CHECK_FLAG(p->sflags, PEER_STATUS_GROUP));
|
Support of BFD status in Quagga
Ticket:CM-6802, CM-6952
Reviewed By: Donald, Kanna
Testing Done:
Double commit of b76943235e09472ec174edcf7204fc82d27fe966 from br2.5. But, manually resolved all the compilation errors. Also, modified the shows to support the json format which was not supported in br2.5.
CM-6802 – Currently, BFD session status can be monitored only through ptmctl. There is no way to check the BFD status of a peer/neighbor through Quagga. Debugging becomes easier if BFD status is shown in Quagga too. BFD status is relevant when it is shown against the BGP peer/OSPF neighbor. For, this following code changes have been done:
- Only down messages from PTM were being propagated from Zebra daemon to clients (bgpd, ospfd and ospf6d). Now, both up and down messages are redistributed to the clients from zebra. BFD status field has been added to the messaging. Handling of BFD session up messages has been added to the client code. BGP/OSPF neighbor is brought down only if the old BFD session status is ‘Up’ to handle extra/initial down messages.
- BFD status and last update timestamp fields have been added to the common BFD info structure. Also, common show functions for showing BFD information have been added to BFD lib.
- Modified the BGP neighbor show functions to call common BFD lib functions.
- For ospf and ospf6, BFD information was maintained only at interface level. To show BFD status per neighbor, BFD information has been added at neighbor level too. “show ip ospf interface”, “show ip ospf neighbor detail”, “show ipv6 ospf6 interface” and “show ipv6 ospf6 neighbor detail” output have been modified to show BFD information.
CM-6952 - IBGP peers were always assumed to be multi-hop since there was no easy way to determine whether an IBGP peer was single hop or multihop unlike EBGP. But, this is causing problem with IBGP link local peers since BFD doesn't allow multihop BFD session with link local IP addresses. Link local peers were discovered when the interface peering was enabled. Interface peering is always singlehop. So, added checks to treat all interface based peers as single hop irrespective of whether the peer is IBGP or EBGP.
2015-08-31 23:56:11 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
/* Already allocated: do nothing. */
|
|
|
|
if (p->bfd_config)
|
Support of BFD status in Quagga
Ticket:CM-6802, CM-6952
Reviewed By: Donald, Kanna
Testing Done:
Double commit of b76943235e09472ec174edcf7204fc82d27fe966 from br2.5. But, manually resolved all the compilation errors. Also, modified the shows to support the json format which was not supported in br2.5.
CM-6802 – Currently, BFD session status can be monitored only through ptmctl. There is no way to check the BFD status of a peer/neighbor through Quagga. Debugging becomes easier if BFD status is shown in Quagga too. BFD status is relevant when it is shown against the BGP peer/OSPF neighbor. For, this following code changes have been done:
- Only down messages from PTM were being propagated from Zebra daemon to clients (bgpd, ospfd and ospf6d). Now, both up and down messages are redistributed to the clients from zebra. BFD status field has been added to the messaging. Handling of BFD session up messages has been added to the client code. BGP/OSPF neighbor is brought down only if the old BFD session status is ‘Up’ to handle extra/initial down messages.
- BFD status and last update timestamp fields have been added to the common BFD info structure. Also, common show functions for showing BFD information have been added to BFD lib.
- Modified the BGP neighbor show functions to call common BFD lib functions.
- For ospf and ospf6, BFD information was maintained only at interface level. To show BFD status per neighbor, BFD information has been added at neighbor level too. “show ip ospf interface”, “show ip ospf neighbor detail”, “show ipv6 ospf6 interface” and “show ipv6 ospf6 neighbor detail” output have been modified to show BFD information.
CM-6952 - IBGP peers were always assumed to be multi-hop since there was no easy way to determine whether an IBGP peer was single hop or multihop unlike EBGP. But, this is causing problem with IBGP link local peers since BFD doesn't allow multihop BFD session with link local IP addresses. Link local peers were discovered when the interface peering was enabled. Interface peering is always singlehop. So, added checks to treat all interface based peers as single hop irrespective of whether the peer is IBGP or EBGP.
2015-08-31 23:56:11 +02:00
|
|
|
return;
|
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
p->bfd_config = XCALLOC(MTYPE_BFD_CONFIG, sizeof(*p->bfd_config));
|
2019-10-21 07:53:01 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
/* Set defaults. */
|
|
|
|
p->bfd_config->detection_multiplier = BFD_DEF_DETECT_MULT;
|
|
|
|
p->bfd_config->min_rx = BFD_DEF_MIN_RX;
|
|
|
|
p->bfd_config->min_tx = BFD_DEF_MIN_TX;
|
Support of BFD status in Quagga
Ticket:CM-6802, CM-6952
Reviewed By: Donald, Kanna
Testing Done:
Double commit of b76943235e09472ec174edcf7204fc82d27fe966 from br2.5. But, manually resolved all the compilation errors. Also, modified the shows to support the json format which was not supported in br2.5.
CM-6802 – Currently, BFD session status can be monitored only through ptmctl. There is no way to check the BFD status of a peer/neighbor through Quagga. Debugging becomes easier if BFD status is shown in Quagga too. BFD status is relevant when it is shown against the BGP peer/OSPF neighbor. For, this following code changes have been done:
- Only down messages from PTM were being propagated from Zebra daemon to clients (bgpd, ospfd and ospf6d). Now, both up and down messages are redistributed to the clients from zebra. BFD status field has been added to the messaging. Handling of BFD session up messages has been added to the client code. BGP/OSPF neighbor is brought down only if the old BFD session status is ‘Up’ to handle extra/initial down messages.
- BFD status and last update timestamp fields have been added to the common BFD info structure. Also, common show functions for showing BFD information have been added to BFD lib.
- Modified the BGP neighbor show functions to call common BFD lib functions.
- For ospf and ospf6, BFD information was maintained only at interface level. To show BFD status per neighbor, BFD information has been added at neighbor level too. “show ip ospf interface”, “show ip ospf neighbor detail”, “show ipv6 ospf6 interface” and “show ipv6 ospf6 neighbor detail” output have been modified to show BFD information.
CM-6952 - IBGP peers were always assumed to be multi-hop since there was no easy way to determine whether an IBGP peer was single hop or multihop unlike EBGP. But, this is causing problem with IBGP link local peers since BFD doesn't allow multihop BFD session with link local IP addresses. Link local peers were discovered when the interface peering was enabled. Interface peering is always singlehop. So, added checks to treat all interface based peers as single hop irrespective of whether the peer is IBGP or EBGP.
2015-08-31 23:56:11 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(p->group->peer, n, pn))
|
|
|
|
bgp_peer_configure_bfd(pn, false);
|
Support of BFD status in Quagga
Ticket:CM-6802, CM-6952
Reviewed By: Donald, Kanna
Testing Done:
Double commit of b76943235e09472ec174edcf7204fc82d27fe966 from br2.5. But, manually resolved all the compilation errors. Also, modified the shows to support the json format which was not supported in br2.5.
CM-6802 – Currently, BFD session status can be monitored only through ptmctl. There is no way to check the BFD status of a peer/neighbor through Quagga. Debugging becomes easier if BFD status is shown in Quagga too. BFD status is relevant when it is shown against the BGP peer/OSPF neighbor. For, this following code changes have been done:
- Only down messages from PTM were being propagated from Zebra daemon to clients (bgpd, ospfd and ospf6d). Now, both up and down messages are redistributed to the clients from zebra. BFD status field has been added to the messaging. Handling of BFD session up messages has been added to the client code. BGP/OSPF neighbor is brought down only if the old BFD session status is ‘Up’ to handle extra/initial down messages.
- BFD status and last update timestamp fields have been added to the common BFD info structure. Also, common show functions for showing BFD information have been added to BFD lib.
- Modified the BGP neighbor show functions to call common BFD lib functions.
- For ospf and ospf6, BFD information was maintained only at interface level. To show BFD status per neighbor, BFD information has been added at neighbor level too. “show ip ospf interface”, “show ip ospf neighbor detail”, “show ipv6 ospf6 interface” and “show ipv6 ospf6 neighbor detail” output have been modified to show BFD information.
CM-6952 - IBGP peers were always assumed to be multi-hop since there was no easy way to determine whether an IBGP peer was single hop or multihop unlike EBGP. But, this is causing problem with IBGP link local peers since BFD doesn't allow multihop BFD session with link local IP addresses. Link local peers were discovered when the interface peering was enabled. Interface peering is always singlehop. So, added checks to treat all interface based peers as single hop irrespective of whether the peer is IBGP or EBGP.
2015-08-31 23:56:11 +02:00
|
|
|
}
|
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
static void bgp_group_remove_bfd(struct peer *p)
|
2015-06-12 16:59:11 +02:00
|
|
|
{
|
2021-02-26 20:50:51 +01:00
|
|
|
struct listnode *n;
|
|
|
|
struct peer *pn;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
/* Peers should not call this. */
|
|
|
|
assert(CHECK_FLAG(p->sflags, PEER_STATUS_GROUP));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
/* Already freed: do nothing. */
|
|
|
|
if (p->bfd_config == NULL)
|
|
|
|
return;
|
2020-02-14 06:14:03 +01:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
/* Free configuration and point to `NULL`. */
|
|
|
|
XFREE(MTYPE_BFD_CONFIG, p->bfd_config);
|
2020-10-18 13:33:54 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
/* Now that it is `NULL` recalculate configuration for all peers. */
|
|
|
|
for (ALL_LIST_ELEMENTS_RO(p->group->peer, n, pn)) {
|
|
|
|
if (pn->bfd_config->manual)
|
|
|
|
bgp_peer_config_apply(pn, NULL);
|
2020-10-18 13:33:54 +02:00
|
|
|
else
|
2021-02-26 20:50:51 +01:00
|
|
|
bgp_peer_remove_bfd(pn);
|
2015-07-22 21:35:37 +02:00
|
|
|
}
|
2015-06-12 16:59:11 +02:00
|
|
|
}
|
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
void bgp_peer_remove_bfd_config(struct peer *p)
|
2016-04-22 00:39:38 +02:00
|
|
|
{
|
2021-02-26 20:50:51 +01:00
|
|
|
if (CHECK_FLAG(p->sflags, PEER_STATUS_GROUP))
|
|
|
|
bgp_group_remove_bfd(p);
|
|
|
|
else
|
|
|
|
bgp_peer_remove_bfd(p);
|
2020-05-20 01:15:20 +02:00
|
|
|
}
|
|
|
|
|
2015-06-12 16:59:11 +02:00
|
|
|
/*
|
|
|
|
* bgp_bfd_peer_config_write - Write the peer BFD configuration.
|
|
|
|
*/
|
2021-02-26 20:50:51 +01:00
|
|
|
void bgp_bfd_peer_config_write(struct vty *vty, const struct peer *peer,
|
|
|
|
const char *addr)
|
2015-06-12 16:59:11 +02:00
|
|
|
{
|
2021-02-26 20:50:51 +01:00
|
|
|
/*
|
|
|
|
* Always show group BFD configuration, but peer only when explicitly
|
|
|
|
* configured.
|
|
|
|
*/
|
|
|
|
if ((!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)
|
|
|
|
&& peer->bfd_config->manual)
|
|
|
|
|| CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
|
2018-06-27 18:46:08 +02:00
|
|
|
#if HAVE_BFDD > 0
|
|
|
|
vty_out(vty, " neighbor %s bfd\n", addr);
|
|
|
|
#else
|
2017-07-13 17:49:13 +02:00
|
|
|
vty_out(vty, " neighbor %s bfd %d %d %d\n", addr,
|
2021-02-26 20:50:51 +01:00
|
|
|
peer->bfd_config->detection_multiplier,
|
|
|
|
peer->bfd_config->min_rx, peer->bfd_config->min_tx);
|
2018-06-27 18:46:08 +02:00
|
|
|
#endif /* HAVE_BFDD */
|
2020-05-20 01:15:20 +02:00
|
|
|
}
|
2019-04-16 11:50:47 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
if (peer->bfd_config->profile[0])
|
|
|
|
vty_out(vty, " neighbor %s bfd profile %s\n", addr,
|
|
|
|
peer->bfd_config->profile);
|
|
|
|
|
|
|
|
if (peer->bfd_config->cbit)
|
|
|
|
vty_out(vty, " neighbor %s bfd check-control-plane-failure\n",
|
|
|
|
addr);
|
2015-06-12 16:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* bgp_bfd_show_info - Show the peer BFD information.
|
|
|
|
*/
|
2021-02-26 20:50:51 +01:00
|
|
|
void bgp_bfd_show_info(struct vty *vty, const struct peer *peer,
|
2015-08-12 15:59:18 +02:00
|
|
|
json_object *json_neigh)
|
2015-06-12 16:59:11 +02:00
|
|
|
{
|
2021-04-08 01:14:34 +02:00
|
|
|
bfd_sess_show(vty, json_neigh, peer->bfd_config->session);
|
2015-06-12 16:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (neighbor_bfd,
|
|
|
|
neighbor_bfd_cmd,
|
2016-09-25 16:10:48 +02:00
|
|
|
"neighbor <A.B.C.D|X:X::X:X|WORD> bfd",
|
2015-06-12 16:59:11 +02:00
|
|
|
NEIGHBOR_STR
|
|
|
|
NEIGHBOR_ADDR_STR2
|
|
|
|
"Enables BFD support\n")
|
|
|
|
{
|
2016-09-26 06:59:47 +02:00
|
|
|
int idx_peer = 1;
|
2015-06-12 16:59:11 +02:00
|
|
|
struct peer *peer;
|
|
|
|
|
2016-09-26 06:59:47 +02:00
|
|
|
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
|
2015-06-12 16:59:11 +02:00
|
|
|
if (!peer)
|
2017-07-13 21:56:08 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2015-06-12 16:59:11 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
|
|
|
|
bgp_group_configure_bfd(peer);
|
|
|
|
else
|
|
|
|
bgp_peer_configure_bfd(peer, true);
|
2015-06-12 16:59:11 +02:00
|
|
|
|
2021-03-23 16:19:20 +01:00
|
|
|
bgp_peer_config_apply(peer, peer->group);
|
|
|
|
|
2015-06-12 16:59:11 +02:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2018-08-01 20:24:52 +02:00
|
|
|
#if HAVE_BFDD > 0
|
|
|
|
DEFUN_HIDDEN(
|
|
|
|
#else
|
|
|
|
DEFUN(
|
|
|
|
#endif /* HAVE_BFDD */
|
|
|
|
neighbor_bfd_param,
|
2015-06-12 16:59:11 +02:00
|
|
|
neighbor_bfd_param_cmd,
|
2016-09-25 16:10:48 +02:00
|
|
|
"neighbor <A.B.C.D|X:X::X:X|WORD> bfd (2-255) (50-60000) (50-60000)",
|
2015-06-12 16:59:11 +02:00
|
|
|
NEIGHBOR_STR
|
|
|
|
NEIGHBOR_ADDR_STR2
|
|
|
|
"Enables BFD support\n"
|
|
|
|
"Detect Multiplier\n"
|
|
|
|
"Required min receive interval\n"
|
|
|
|
"Desired min transmit interval\n")
|
|
|
|
{
|
2016-09-26 06:59:47 +02:00
|
|
|
int idx_peer = 1;
|
|
|
|
int idx_number_1 = 3;
|
|
|
|
int idx_number_2 = 4;
|
|
|
|
int idx_number_3 = 5;
|
2021-02-26 20:50:51 +01:00
|
|
|
long detection_multiplier, min_rx, min_tx;
|
2015-06-12 16:59:11 +02:00
|
|
|
struct peer *peer;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-09-26 06:59:47 +02:00
|
|
|
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
|
2015-06-12 16:59:11 +02:00
|
|
|
if (!peer)
|
2017-07-13 21:56:08 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
detection_multiplier = strtol(argv[idx_number_1]->arg, NULL, 10);
|
|
|
|
min_rx = strtol(argv[idx_number_2]->arg, NULL, 10);
|
|
|
|
min_tx = strtol(argv[idx_number_3]->arg, NULL, 10);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
|
|
|
|
bgp_group_configure_bfd(peer);
|
2016-04-22 00:39:38 +02:00
|
|
|
else
|
2021-02-26 20:50:51 +01:00
|
|
|
bgp_peer_configure_bfd(peer, true);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
peer->bfd_config->detection_multiplier = detection_multiplier;
|
|
|
|
peer->bfd_config->min_rx = min_rx;
|
|
|
|
peer->bfd_config->min_tx = min_tx;
|
|
|
|
bgp_peer_config_apply(peer, peer->group);
|
2019-04-16 11:50:47 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (neighbor_bfd_check_controlplane_failure,
|
|
|
|
neighbor_bfd_check_controlplane_failure_cmd,
|
|
|
|
"[no] neighbor <A.B.C.D|X:X::X:X|WORD> bfd check-control-plane-failure",
|
|
|
|
NO_STR
|
|
|
|
NEIGHBOR_STR
|
|
|
|
NEIGHBOR_ADDR_STR2
|
|
|
|
"BFD support\n"
|
|
|
|
"Link dataplane status with BGP controlplane\n")
|
|
|
|
{
|
|
|
|
const char *no = strmatch(argv[0]->text, "no") ? "no" : NULL;
|
|
|
|
int idx_peer = 0;
|
|
|
|
struct peer *peer;
|
|
|
|
|
|
|
|
if (no)
|
|
|
|
idx_peer = 2;
|
|
|
|
else
|
|
|
|
idx_peer = 1;
|
|
|
|
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
|
2023-01-11 14:58:10 +01:00
|
|
|
if (!peer)
|
2019-04-16 11:50:47 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2021-02-26 20:50:51 +01:00
|
|
|
|
|
|
|
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
|
|
|
|
bgp_group_configure_bfd(peer);
|
|
|
|
else
|
|
|
|
bgp_peer_configure_bfd(peer, true);
|
|
|
|
|
|
|
|
peer->bfd_config->cbit = no == NULL;
|
|
|
|
bgp_peer_config_apply(peer, peer->group);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
2019-04-16 11:50:47 +02:00
|
|
|
}
|
|
|
|
|
2015-06-12 16:59:11 +02:00
|
|
|
DEFUN (no_neighbor_bfd,
|
|
|
|
no_neighbor_bfd_cmd,
|
2018-08-01 20:24:52 +02:00
|
|
|
#if HAVE_BFDD > 0
|
|
|
|
"no neighbor <A.B.C.D|X:X::X:X|WORD> bfd",
|
|
|
|
#else
|
2016-09-26 06:59:47 +02:00
|
|
|
"no neighbor <A.B.C.D|X:X::X:X|WORD> bfd [(2-255) (50-60000) (50-60000)]",
|
2018-08-01 20:24:52 +02:00
|
|
|
#endif /* HAVE_BFDD */
|
2015-06-12 16:59:11 +02:00
|
|
|
NO_STR
|
|
|
|
NEIGHBOR_STR
|
|
|
|
NEIGHBOR_ADDR_STR2
|
2016-09-26 06:59:47 +02:00
|
|
|
"Disables BFD support\n"
|
2018-08-01 20:24:52 +02:00
|
|
|
#if HAVE_BFDD == 0
|
2016-09-26 06:59:47 +02:00
|
|
|
"Detect Multiplier\n"
|
|
|
|
"Required min receive interval\n"
|
2018-08-01 20:24:52 +02:00
|
|
|
"Desired min transmit interval\n"
|
|
|
|
#endif /* !HAVE_BFDD */
|
|
|
|
)
|
2015-06-12 16:59:11 +02:00
|
|
|
{
|
2016-09-26 06:59:47 +02:00
|
|
|
int idx_peer = 2;
|
2015-06-12 16:59:11 +02:00
|
|
|
struct peer *peer;
|
|
|
|
|
2016-09-26 06:59:47 +02:00
|
|
|
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
|
2015-06-12 16:59:11 +02:00
|
|
|
if (!peer)
|
2017-07-13 21:56:08 +02:00
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
2015-06-12 16:59:11 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
|
|
|
|
bgp_group_remove_bfd(peer);
|
|
|
|
else
|
|
|
|
bgp_peer_remove_bfd(peer);
|
2016-04-22 00:39:38 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2020-05-20 01:15:20 +02:00
|
|
|
#if HAVE_BFDD > 0
|
|
|
|
DEFUN(neighbor_bfd_profile, neighbor_bfd_profile_cmd,
|
|
|
|
"neighbor <A.B.C.D|X:X::X:X|WORD> bfd profile BFDPROF",
|
|
|
|
NEIGHBOR_STR
|
|
|
|
NEIGHBOR_ADDR_STR2
|
|
|
|
"BFD integration\n"
|
|
|
|
BFD_PROFILE_STR
|
|
|
|
BFD_PROFILE_NAME_STR)
|
|
|
|
{
|
|
|
|
int idx_peer = 1, idx_prof = 4;
|
|
|
|
struct peer *peer;
|
|
|
|
|
|
|
|
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
|
|
|
|
if (!peer)
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
|
|
|
|
bgp_group_configure_bfd(peer);
|
|
|
|
else
|
|
|
|
bgp_peer_configure_bfd(peer, true);
|
|
|
|
|
|
|
|
strlcpy(peer->bfd_config->profile, argv[idx_prof]->arg,
|
|
|
|
sizeof(peer->bfd_config->profile));
|
|
|
|
bgp_peer_config_apply(peer, peer->group);
|
2020-05-20 01:15:20 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN(no_neighbor_bfd_profile, no_neighbor_bfd_profile_cmd,
|
|
|
|
"no neighbor <A.B.C.D|X:X::X:X|WORD> bfd profile [BFDPROF]",
|
|
|
|
NO_STR
|
|
|
|
NEIGHBOR_STR
|
|
|
|
NEIGHBOR_ADDR_STR2
|
|
|
|
"BFD integration\n"
|
|
|
|
BFD_PROFILE_STR
|
|
|
|
BFD_PROFILE_NAME_STR)
|
|
|
|
{
|
|
|
|
int idx_peer = 2;
|
|
|
|
struct peer *peer;
|
|
|
|
|
|
|
|
peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
|
|
|
|
if (!peer)
|
|
|
|
return CMD_WARNING_CONFIG_FAILED;
|
|
|
|
|
2024-03-12 23:14:11 +01:00
|
|
|
if (!peer->bfd_config)
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
|
|
|
|
bgp_group_configure_bfd(peer);
|
|
|
|
else
|
|
|
|
bgp_peer_configure_bfd(peer, true);
|
2020-05-20 01:15:20 +02:00
|
|
|
|
2021-02-26 20:50:51 +01:00
|
|
|
peer->bfd_config->profile[0] = 0;
|
|
|
|
bgp_peer_config_apply(peer, peer->group);
|
2020-05-20 01:15:20 +02:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
#endif /* HAVE_BFDD */
|
|
|
|
|
2023-03-07 20:14:41 +01:00
|
|
|
void bgp_bfd_init(struct event_loop *tm)
|
2015-06-12 16:59:11 +02:00
|
|
|
{
|
|
|
|
/* Initialize BFD client functions */
|
2021-02-26 20:50:51 +01:00
|
|
|
bfd_protocol_integration_init(zclient, tm);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-06-12 16:59:11 +02:00
|
|
|
/* "neighbor bfd" commands. */
|
|
|
|
install_element(BGP_NODE, &neighbor_bfd_cmd);
|
|
|
|
install_element(BGP_NODE, &neighbor_bfd_param_cmd);
|
2019-04-16 11:50:47 +02:00
|
|
|
install_element(BGP_NODE, &neighbor_bfd_check_controlplane_failure_cmd);
|
2015-06-12 16:59:11 +02:00
|
|
|
install_element(BGP_NODE, &no_neighbor_bfd_cmd);
|
2020-05-20 01:15:20 +02:00
|
|
|
|
|
|
|
#if HAVE_BFDD > 0
|
|
|
|
install_element(BGP_NODE, &neighbor_bfd_profile_cmd);
|
|
|
|
install_element(BGP_NODE, &no_neighbor_bfd_profile_cmd);
|
|
|
|
#endif /* HAVE_BFDD */
|
2015-06-12 16:59:11 +02:00
|
|
|
}
|