mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-08 16:42:32 +00:00
ospfd: rework BFD integration
Use new BFD API to integrate with OSPFv2. Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
This commit is contained in:
parent
cab054bfd2
commit
659f4e40dd
439
ospfd/ospf_bfd.c
439
ospfd/ospf_bfd.c
@ -23,6 +23,7 @@
|
|||||||
#include <zebra.h>
|
#include <zebra.h>
|
||||||
|
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
|
#include "json.h"
|
||||||
#include "linklist.h"
|
#include "linklist.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "prefix.h"
|
#include "prefix.h"
|
||||||
@ -44,49 +45,10 @@
|
|||||||
#include "ospf_dump.h"
|
#include "ospf_dump.h"
|
||||||
#include "ospf_vty.h"
|
#include "ospf_vty.h"
|
||||||
|
|
||||||
|
DEFINE_MTYPE_STATIC(OSPFD, BFD_CONFIG, "BFD configuration data");
|
||||||
|
|
||||||
extern struct zclient *zclient;
|
extern struct zclient *zclient;
|
||||||
|
|
||||||
/*
|
|
||||||
* ospf_bfd_info_free - Free BFD info structure
|
|
||||||
*/
|
|
||||||
void ospf_bfd_info_free(void **bfd_info)
|
|
||||||
{
|
|
||||||
bfd_info_free((struct bfd_info **)bfd_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ospf_bfd_reg_dereg_nbr - Register/Deregister a neighbor with BFD through
|
|
||||||
* zebra for starting/stopping the monitoring of
|
|
||||||
* the neighbor rechahability.
|
|
||||||
*/
|
|
||||||
static void ospf_bfd_reg_dereg_nbr(struct ospf_neighbor *nbr, int command)
|
|
||||||
{
|
|
||||||
struct ospf_interface *oi = nbr->oi;
|
|
||||||
struct interface *ifp = oi->ifp;
|
|
||||||
struct ospf_if_params *params;
|
|
||||||
struct bfd_info *bfd_info;
|
|
||||||
int cbit;
|
|
||||||
|
|
||||||
/* Check if BFD is enabled */
|
|
||||||
params = IF_DEF_PARAMS(ifp);
|
|
||||||
|
|
||||||
/* Check if BFD is enabled */
|
|
||||||
if (!params->bfd_info)
|
|
||||||
return;
|
|
||||||
bfd_info = (struct bfd_info *)params->bfd_info;
|
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
|
|
||||||
zlog_debug("%s nbr (%pI4) with BFD. OSPF vrf %s",
|
|
||||||
bfd_get_command_dbg_str(command),
|
|
||||||
&nbr->src,
|
|
||||||
ospf_vrf_id_to_name(oi->ospf->vrf_id));
|
|
||||||
|
|
||||||
cbit = CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_CBIT_ON);
|
|
||||||
|
|
||||||
bfd_peer_sendmsg(zclient, bfd_info, AF_INET, &nbr->src, NULL, ifp->name,
|
|
||||||
0, 0, cbit, command, 0, oi->ospf->vrf_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ospf_bfd_trigger_event - Neighbor is registered/deregistered with BFD when
|
* ospf_bfd_trigger_event - Neighbor is registered/deregistered with BFD when
|
||||||
* neighbor state is changed to/from 2way.
|
* neighbor state is changed to/from 2way.
|
||||||
@ -94,18 +56,68 @@ static void ospf_bfd_reg_dereg_nbr(struct ospf_neighbor *nbr, int command)
|
|||||||
void ospf_bfd_trigger_event(struct ospf_neighbor *nbr, int old_state, int state)
|
void ospf_bfd_trigger_event(struct ospf_neighbor *nbr, int old_state, int state)
|
||||||
{
|
{
|
||||||
if ((old_state < NSM_TwoWay) && (state >= NSM_TwoWay))
|
if ((old_state < NSM_TwoWay) && (state >= NSM_TwoWay))
|
||||||
ospf_bfd_reg_dereg_nbr(nbr, ZEBRA_BFD_DEST_REGISTER);
|
bfd_sess_install(nbr->bfd_session);
|
||||||
else if ((old_state >= NSM_TwoWay) && (state < NSM_TwoWay))
|
else if ((old_state >= NSM_TwoWay) && (state < NSM_TwoWay))
|
||||||
ospf_bfd_reg_dereg_nbr(nbr, ZEBRA_BFD_DEST_DEREGISTER);
|
bfd_sess_uninstall(nbr->bfd_session);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static void ospf_bfd_session_change(struct bfd_session_params *bsp,
|
||||||
* ospf_bfd_reg_dereg_all_nbr - Register/Deregister all neighbors associated
|
const struct bfd_session_status *bss,
|
||||||
* with a interface with BFD through
|
void *arg)
|
||||||
* zebra for starting/stopping the monitoring of
|
{
|
||||||
* the neighbor rechahability.
|
struct ospf_neighbor *nbr = arg;
|
||||||
*/
|
|
||||||
static int ospf_bfd_reg_dereg_all_nbr(struct interface *ifp, int command)
|
/* BFD peer went down. */
|
||||||
|
if (bss->state == BFD_STATUS_DOWN
|
||||||
|
&& bss->previous_state == BFD_STATUS_UP) {
|
||||||
|
if (IS_DEBUG_OSPF(nsm, NSM_EVENTS))
|
||||||
|
zlog_debug("NSM[%s:%pI4]: BFD Down", IF_NAME(nbr->oi),
|
||||||
|
&nbr->address.u.prefix4);
|
||||||
|
|
||||||
|
OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_InactivityTimer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BFD peer went up. */
|
||||||
|
if (bss->state == BSS_UP && bss->previous_state == BSS_DOWN)
|
||||||
|
if (IS_DEBUG_OSPF(nsm, NSM_EVENTS))
|
||||||
|
zlog_debug("NSM[%s:%pI4]: BFD Up", IF_NAME(nbr->oi),
|
||||||
|
&nbr->address.u.prefix4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ospf_neighbor_bfd_apply(struct ospf_neighbor *nbr)
|
||||||
|
{
|
||||||
|
struct ospf_interface *oi = nbr->oi;
|
||||||
|
struct ospf_if_params *oip = IF_DEF_PARAMS(oi->ifp);
|
||||||
|
|
||||||
|
/* BFD configuration was removed. */
|
||||||
|
if (oip->bfd_config == NULL) {
|
||||||
|
bfd_sess_free(&nbr->bfd_session);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* New BFD session. */
|
||||||
|
if (nbr->bfd_session == NULL) {
|
||||||
|
nbr->bfd_session = bfd_sess_new(ospf_bfd_session_change, nbr);
|
||||||
|
bfd_sess_set_ipv4_addrs(nbr->bfd_session, NULL, &nbr->src);
|
||||||
|
bfd_sess_set_interface(nbr->bfd_session, oi->ifp->name);
|
||||||
|
bfd_sess_set_vrf(nbr->bfd_session, oi->ospf->vrf_id);
|
||||||
|
bfd_sess_enable(nbr->bfd_session, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set new configuration. */
|
||||||
|
bfd_sess_set_timers(nbr->bfd_session,
|
||||||
|
oip->bfd_config->detection_multiplier,
|
||||||
|
oip->bfd_config->min_rx, oip->bfd_config->min_tx);
|
||||||
|
bfd_sess_set_profile(nbr->bfd_session, oip->bfd_config->profile);
|
||||||
|
|
||||||
|
/* Don't start sessions on down OSPF sessions. */
|
||||||
|
if (nbr->state < NSM_TwoWay)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bfd_sess_install(nbr->bfd_session);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ospf_interface_bfd_apply(struct interface *ifp)
|
||||||
{
|
{
|
||||||
struct ospf_interface *oi;
|
struct ospf_interface *oi;
|
||||||
struct route_table *nbrs;
|
struct route_table *nbrs;
|
||||||
@ -113,274 +125,82 @@ static int ospf_bfd_reg_dereg_all_nbr(struct interface *ifp, int command)
|
|||||||
struct route_node *irn;
|
struct route_node *irn;
|
||||||
struct route_node *nrn;
|
struct route_node *nrn;
|
||||||
|
|
||||||
|
/* Iterate over all interfaces and set neighbors BFD session. */
|
||||||
for (irn = route_top(IF_OIFS(ifp)); irn; irn = route_next(irn)) {
|
for (irn = route_top(IF_OIFS(ifp)); irn; irn = route_next(irn)) {
|
||||||
if ((oi = irn->info) == NULL)
|
if ((oi = irn->info) == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((nbrs = oi->nbrs) == NULL)
|
if ((nbrs = oi->nbrs) == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (nrn = route_top(nbrs); nrn; nrn = route_next(nrn)) {
|
for (nrn = route_top(nbrs); nrn; nrn = route_next(nrn)) {
|
||||||
if ((nbr = nrn->info) == NULL || nbr == oi->nbr_self)
|
if ((nbr = nrn->info) == NULL || nbr == oi->nbr_self)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (command != ZEBRA_BFD_DEST_DEREGISTER)
|
ospf_neighbor_bfd_apply(nbr);
|
||||||
ospf_bfd_info_nbr_create(oi, nbr);
|
|
||||||
else
|
|
||||||
bfd_info_free(
|
|
||||||
(struct bfd_info **)&nbr->bfd_info);
|
|
||||||
|
|
||||||
if (nbr->state < NSM_TwoWay)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ospf_bfd_reg_dereg_nbr(nbr, command);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static void ospf_interface_enable_bfd(struct interface *ifp)
|
||||||
* ospf_bfd_nbr_replay - Replay all the neighbors that have BFD enabled
|
|
||||||
* to zebra
|
|
||||||
*/
|
|
||||||
static int ospf_bfd_nbr_replay(ZAPI_CALLBACK_ARGS)
|
|
||||||
{
|
{
|
||||||
struct listnode *inode, *node, *onode;
|
struct ospf_if_params *oip = IF_DEF_PARAMS(ifp);
|
||||||
struct ospf *ospf;
|
|
||||||
struct ospf_interface *oi;
|
|
||||||
struct route_table *nbrs;
|
|
||||||
struct route_node *rn;
|
|
||||||
struct ospf_neighbor *nbr;
|
|
||||||
struct ospf_if_params *params;
|
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) {
|
if (oip->bfd_config)
|
||||||
zlog_debug("Zebra: BFD Dest replay request");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Send the client registration */
|
|
||||||
bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER, vrf_id);
|
|
||||||
|
|
||||||
/* Replay the neighbor, if BFD is enabled in OSPF */
|
|
||||||
for (ALL_LIST_ELEMENTS(om->ospf, node, onode, ospf)) {
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, inode, oi)) {
|
|
||||||
if ((nbrs = oi->nbrs) == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
params = IF_DEF_PARAMS(oi->ifp);
|
|
||||||
if (!params->bfd_info)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (rn = route_top(nbrs); rn; rn = route_next(rn)) {
|
|
||||||
if ((nbr = rn->info) == NULL
|
|
||||||
|| nbr == oi->nbr_self)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (nbr->state < NSM_TwoWay)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
|
|
||||||
zlog_debug("Replaying nbr (%pI4) to BFD",
|
|
||||||
&nbr->src);
|
|
||||||
|
|
||||||
ospf_bfd_reg_dereg_nbr(nbr,
|
|
||||||
ZEBRA_BFD_DEST_UPDATE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ospf_bfd_interface_dest_update - Find the neighbor for which the BFD status
|
|
||||||
* has changed and bring down the neighbor
|
|
||||||
* connectivity if the BFD status changed to
|
|
||||||
* down.
|
|
||||||
*/
|
|
||||||
static int ospf_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS)
|
|
||||||
{
|
|
||||||
struct interface *ifp;
|
|
||||||
struct ospf_interface *oi;
|
|
||||||
struct ospf_if_params *params;
|
|
||||||
struct ospf_neighbor *nbr = NULL;
|
|
||||||
struct route_node *node;
|
|
||||||
struct route_node *n_node;
|
|
||||||
struct prefix p, src_p;
|
|
||||||
int status;
|
|
||||||
int old_status;
|
|
||||||
struct bfd_info *bfd_info;
|
|
||||||
struct timeval tv;
|
|
||||||
|
|
||||||
ifp = bfd_get_peer_info(zclient->ibuf, &p, &src_p, &status, NULL,
|
|
||||||
vrf_id);
|
|
||||||
|
|
||||||
if ((ifp == NULL) || (p.family != AF_INET))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
|
|
||||||
zlog_debug("Zebra: interface %s bfd destination %pFX %s",
|
|
||||||
ifp->name, &p, bfd_get_status_str(status));
|
|
||||||
|
|
||||||
params = IF_DEF_PARAMS(ifp);
|
|
||||||
if (!params->bfd_info)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (node = route_top(IF_OIFS(ifp)); node; node = route_next(node)) {
|
|
||||||
if ((oi = node->info) == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* walk the neighbor list for point-to-point network */
|
|
||||||
if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
|
|
||||||
for (n_node = route_top(oi->nbrs); n_node;
|
|
||||||
n_node = route_next(n_node)) {
|
|
||||||
nbr = n_node->info;
|
|
||||||
if (nbr) {
|
|
||||||
/* skip myself */
|
|
||||||
if (nbr == oi->nbr_self) {
|
|
||||||
nbr = NULL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Found the matching neighbor */
|
|
||||||
if (nbr->src.s_addr ==
|
|
||||||
p.u.prefix4.s_addr)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
nbr = ospf_nbr_lookup_by_addr(oi->nbrs, &p.u.prefix4);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nbr || !nbr->bfd_info)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
bfd_info = (struct bfd_info *)nbr->bfd_info;
|
|
||||||
if (bfd_info->status == status)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
old_status = bfd_info->status;
|
|
||||||
BFD_SET_CLIENT_STATUS(bfd_info->status, status);
|
|
||||||
monotime(&tv);
|
|
||||||
bfd_info->last_update = tv.tv_sec;
|
|
||||||
|
|
||||||
if ((status == BFD_STATUS_DOWN)
|
|
||||||
&& (old_status == BFD_STATUS_UP)) {
|
|
||||||
if (IS_DEBUG_OSPF(nsm, NSM_EVENTS))
|
|
||||||
zlog_debug("NSM[%s:%pI4]: BFD Down",
|
|
||||||
IF_NAME(nbr->oi),
|
|
||||||
&nbr->address.u.prefix4);
|
|
||||||
|
|
||||||
OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_InactivityTimer);
|
|
||||||
}
|
|
||||||
if ((status == BFD_STATUS_UP)
|
|
||||||
&& (old_status == BFD_STATUS_DOWN)) {
|
|
||||||
if (IS_DEBUG_OSPF(nsm, NSM_EVENTS))
|
|
||||||
zlog_debug("NSM[%s:%pI4]: BFD Up",
|
|
||||||
IF_NAME(nbr->oi),
|
|
||||||
&nbr->address.u.prefix4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ospf_bfd_info_nbr_create - Create/update BFD information for a neighbor.
|
|
||||||
*/
|
|
||||||
void ospf_bfd_info_nbr_create(struct ospf_interface *oi,
|
|
||||||
struct ospf_neighbor *nbr)
|
|
||||||
{
|
|
||||||
struct bfd_info *oi_bfd_info;
|
|
||||||
struct bfd_info *nbr_bfd_info;
|
|
||||||
struct interface *ifp = oi->ifp;
|
|
||||||
struct ospf_if_params *params;
|
|
||||||
|
|
||||||
/* Check if BFD is enabled */
|
|
||||||
params = IF_DEF_PARAMS(ifp);
|
|
||||||
|
|
||||||
/* Check if BFD is enabled */
|
|
||||||
if (!params->bfd_info)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
oi_bfd_info = (struct bfd_info *)params->bfd_info;
|
/* Allocate memory for configurations and set defaults. */
|
||||||
if (!nbr->bfd_info)
|
oip->bfd_config = XCALLOC(MTYPE_BFD_CONFIG, sizeof(*oip->bfd_config));
|
||||||
nbr->bfd_info = bfd_info_create();
|
oip->bfd_config->detection_multiplier = BFD_DEF_DETECT_MULT;
|
||||||
|
oip->bfd_config->min_rx = BFD_DEF_MIN_RX;
|
||||||
|
oip->bfd_config->min_tx = BFD_DEF_MIN_TX;
|
||||||
|
}
|
||||||
|
|
||||||
nbr_bfd_info = (struct bfd_info *)nbr->bfd_info;
|
void ospf_interface_disable_bfd(struct interface *ifp,
|
||||||
nbr_bfd_info->detect_mult = oi_bfd_info->detect_mult;
|
struct ospf_if_params *oip)
|
||||||
nbr_bfd_info->desired_min_tx = oi_bfd_info->desired_min_tx;
|
{
|
||||||
nbr_bfd_info->required_min_rx = oi_bfd_info->required_min_rx;
|
XFREE(MTYPE_BFD_CONFIG, oip->bfd_config);
|
||||||
|
ospf_interface_bfd_apply(ifp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ospf_bfd_write_config - Write the interface BFD configuration.
|
* ospf_bfd_write_config - Write the interface BFD configuration.
|
||||||
*/
|
*/
|
||||||
void ospf_bfd_write_config(struct vty *vty, struct ospf_if_params *params)
|
void ospf_bfd_write_config(struct vty *vty, const struct ospf_if_params *params
|
||||||
|
__attribute__((unused)))
|
||||||
{
|
{
|
||||||
#if HAVE_BFDD == 0
|
#if HAVE_BFDD == 0
|
||||||
struct bfd_info *bfd_info;
|
|
||||||
#endif /* ! HAVE_BFDD */
|
|
||||||
|
|
||||||
if (!params->bfd_info)
|
|
||||||
return;
|
|
||||||
|
|
||||||
#if HAVE_BFDD == 0
|
|
||||||
bfd_info = (struct bfd_info *)params->bfd_info;
|
|
||||||
|
|
||||||
if (CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG))
|
if (CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG))
|
||||||
vty_out(vty, " ip ospf bfd %d %d %d\n", bfd_info->detect_mult,
|
vty_out(vty, " ip ospf bfd %d %d %d\n",
|
||||||
bfd_info->required_min_rx, bfd_info->desired_min_tx);
|
params->bfd_config->detection_multiplier,
|
||||||
|
params->bfd_config->min_rx, params->bfd_config->min_tx);
|
||||||
else
|
else
|
||||||
#endif /* ! HAVE_BFDD */
|
#endif /* ! HAVE_BFDD */
|
||||||
vty_out(vty, " ip ospf bfd\n");
|
vty_out(vty, " ip ospf bfd\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
void ospf_interface_bfd_show(struct vty *vty, const struct interface *ifp,
|
||||||
* ospf_bfd_show_info - Show BFD info structure
|
struct json_object *json)
|
||||||
*/
|
|
||||||
void ospf_bfd_show_info(struct vty *vty, void *bfd_info, json_object *json_obj,
|
|
||||||
bool use_json, int param_only)
|
|
||||||
{
|
{
|
||||||
if (param_only)
|
struct ospf_if_params *params = IF_DEF_PARAMS(ifp);
|
||||||
bfd_show_param(vty, (struct bfd_info *)bfd_info, 1, 0, use_json,
|
struct bfd_configuration *bfd_config = params->bfd_config;
|
||||||
json_obj);
|
struct json_object *json_bfd;
|
||||||
else
|
|
||||||
bfd_show_info(vty, (struct bfd_info *)bfd_info, 0, 1, use_json,
|
|
||||||
json_obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
if (bfd_config == NULL)
|
||||||
* ospf_bfd_interface_show - Show the interface BFD configuration.
|
return;
|
||||||
*/
|
|
||||||
void ospf_bfd_interface_show(struct vty *vty, struct interface *ifp,
|
|
||||||
json_object *json_interface_sub, bool use_json)
|
|
||||||
{
|
|
||||||
struct ospf_if_params *params;
|
|
||||||
|
|
||||||
params = IF_DEF_PARAMS(ifp);
|
if (json) {
|
||||||
|
json_bfd = json_object_new_object();
|
||||||
ospf_bfd_show_info(vty, params->bfd_info, json_interface_sub, use_json,
|
json_object_int_add(json_bfd, "detectionMultiplier",
|
||||||
1);
|
bfd_config->detection_multiplier);
|
||||||
}
|
json_object_int_add(json_bfd, "rxMinInterval",
|
||||||
|
bfd_config->min_rx);
|
||||||
/*
|
json_object_int_add(json_bfd, "txMinInterval",
|
||||||
* ospf_bfd_if_param_set - Set the configured BFD paramter values for
|
bfd_config->min_tx);
|
||||||
* interface.
|
json_object_object_add(json, "peerBfdInfo", json_bfd);
|
||||||
*/
|
} else
|
||||||
static void ospf_bfd_if_param_set(struct interface *ifp, uint32_t min_rx,
|
vty_out(vty,
|
||||||
uint32_t min_tx, uint8_t detect_mult,
|
" BFD: Detect Multiplier: %d, Min Rx interval: %d, Min Tx interval: %d\n",
|
||||||
int defaults)
|
bfd_config->detection_multiplier, bfd_config->min_rx,
|
||||||
{
|
bfd_config->min_tx);
|
||||||
struct ospf_if_params *params;
|
|
||||||
int command = 0;
|
|
||||||
|
|
||||||
params = IF_DEF_PARAMS(ifp);
|
|
||||||
|
|
||||||
bfd_set_param((struct bfd_info **)&(params->bfd_info), min_rx, min_tx,
|
|
||||||
detect_mult, NULL, defaults, &command);
|
|
||||||
if (command)
|
|
||||||
ospf_bfd_reg_dereg_all_nbr(ifp, command);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (ip_ospf_bfd,
|
DEFUN (ip_ospf_bfd,
|
||||||
@ -391,17 +211,8 @@ DEFUN (ip_ospf_bfd,
|
|||||||
"Enables BFD support\n")
|
"Enables BFD support\n")
|
||||||
{
|
{
|
||||||
VTY_DECLVAR_CONTEXT(interface, ifp);
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
||||||
struct ospf_if_params *params;
|
ospf_interface_enable_bfd(ifp);
|
||||||
struct bfd_info *bfd_info;
|
ospf_interface_bfd_apply(ifp);
|
||||||
|
|
||||||
assert(ifp);
|
|
||||||
params = IF_DEF_PARAMS(ifp);
|
|
||||||
bfd_info = params->bfd_info;
|
|
||||||
|
|
||||||
if (!bfd_info || !CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG))
|
|
||||||
ospf_bfd_if_param_set(ifp, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
|
|
||||||
BFD_DEF_DETECT_MULT, 1);
|
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -421,23 +232,20 @@ DEFUN(
|
|||||||
"Desired min transmit interval\n")
|
"Desired min transmit interval\n")
|
||||||
{
|
{
|
||||||
VTY_DECLVAR_CONTEXT(interface, ifp);
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
||||||
|
struct ospf_if_params *params;
|
||||||
int idx_number = 3;
|
int idx_number = 3;
|
||||||
int idx_number_2 = 4;
|
int idx_number_2 = 4;
|
||||||
int idx_number_3 = 5;
|
int idx_number_3 = 5;
|
||||||
uint32_t rx_val;
|
|
||||||
uint32_t tx_val;
|
|
||||||
uint8_t dm_val;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
assert(ifp);
|
ospf_interface_enable_bfd(ifp);
|
||||||
|
|
||||||
if ((ret = bfd_validate_param(
|
params = IF_DEF_PARAMS(ifp);
|
||||||
vty, argv[idx_number]->arg, argv[idx_number_2]->arg,
|
params->bfd_config->detection_multiplier =
|
||||||
argv[idx_number_3]->arg, &dm_val, &rx_val, &tx_val))
|
strtol(argv[idx_number]->arg, NULL, 10);
|
||||||
!= CMD_SUCCESS)
|
params->bfd_config->min_rx = strtol(argv[idx_number_2]->arg, NULL, 10);
|
||||||
return ret;
|
params->bfd_config->min_tx = strtol(argv[idx_number_3]->arg, NULL, 10);
|
||||||
|
|
||||||
ospf_bfd_if_param_set(ifp, rx_val, tx_val, dm_val, 0);
|
ospf_interface_bfd_apply(ifp);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -461,26 +269,13 @@ DEFUN (no_ip_ospf_bfd,
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
VTY_DECLVAR_CONTEXT(interface, ifp);
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
||||||
struct ospf_if_params *params;
|
ospf_interface_disable_bfd(ifp, IF_DEF_PARAMS(ifp));
|
||||||
|
|
||||||
assert(ifp);
|
|
||||||
|
|
||||||
params = IF_DEF_PARAMS(ifp);
|
|
||||||
if (params->bfd_info) {
|
|
||||||
ospf_bfd_reg_dereg_all_nbr(ifp, ZEBRA_BFD_DEST_DEREGISTER);
|
|
||||||
bfd_info_free(&(params->bfd_info));
|
|
||||||
}
|
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ospf_bfd_init(void)
|
void ospf_bfd_init(struct thread_master *tm)
|
||||||
{
|
{
|
||||||
bfd_gbl_init();
|
bfd_protocol_integration_init(zclient, tm);
|
||||||
|
|
||||||
/* Initialize BFD client functions */
|
|
||||||
zclient->interface_bfd_dest_update = ospf_bfd_interface_dest_update;
|
|
||||||
zclient->bfd_dest_replay = ospf_bfd_nbr_replay;
|
|
||||||
|
|
||||||
/* Install BFD command */
|
/* Install BFD command */
|
||||||
install_element(INTERFACE_NODE, &ip_ospf_bfd_cmd);
|
install_element(INTERFACE_NODE, &ip_ospf_bfd_cmd);
|
||||||
|
@ -23,27 +23,34 @@
|
|||||||
#ifndef _ZEBRA_OSPF_BFD_H
|
#ifndef _ZEBRA_OSPF_BFD_H
|
||||||
#define _ZEBRA_OSPF_BFD_H
|
#define _ZEBRA_OSPF_BFD_H
|
||||||
|
|
||||||
|
#include "ospfd/ospf_interface.h"
|
||||||
#include "json.h"
|
#include "json.h"
|
||||||
|
|
||||||
extern void ospf_bfd_init(void);
|
extern void ospf_bfd_init(struct thread_master *tm);
|
||||||
|
|
||||||
extern void ospf_bfd_write_config(struct vty *vty,
|
extern void ospf_bfd_write_config(struct vty *vty,
|
||||||
struct ospf_if_params *params);
|
const struct ospf_if_params *params);
|
||||||
|
|
||||||
extern void ospf_bfd_trigger_event(struct ospf_neighbor *nbr, int old_state,
|
extern void ospf_bfd_trigger_event(struct ospf_neighbor *nbr, int old_state,
|
||||||
int state);
|
int state);
|
||||||
|
|
||||||
extern void ospf_bfd_interface_show(struct vty *vty, struct interface *ifp,
|
/**
|
||||||
json_object *json_interface_sub,
|
* Legacy information: it is the peers who actually have this information
|
||||||
bool use_json);
|
* and the protocol should not need to know about timers.
|
||||||
|
*/
|
||||||
|
extern void ospf_interface_bfd_show(struct vty *vty,
|
||||||
|
const struct interface *ifp,
|
||||||
|
struct json_object *json);
|
||||||
|
|
||||||
extern void ospf_bfd_info_nbr_create(struct ospf_interface *oi,
|
/**
|
||||||
struct ospf_neighbor *nbr);
|
* Disables interface BFD configuration and remove settings from all peers.
|
||||||
|
*/
|
||||||
|
extern void ospf_interface_disable_bfd(struct interface *ifp,
|
||||||
|
struct ospf_if_params *oip);
|
||||||
|
|
||||||
extern void ospf_bfd_show_info(struct vty *vty, void *bfd_info,
|
/**
|
||||||
json_object *json_obj, bool use_json,
|
* Create/update BFD session for this OSPF neighbor.
|
||||||
int param_only);
|
*/
|
||||||
|
extern void ospf_neighbor_bfd_apply(struct ospf_neighbor *nbr);
|
||||||
extern void ospf_bfd_info_free(void **bfd_info);
|
|
||||||
|
|
||||||
#endif /* _ZEBRA_OSPF_BFD_H */
|
#endif /* _ZEBRA_OSPF_BFD_H */
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include "ldp_sync.h"
|
#include "ldp_sync.h"
|
||||||
|
|
||||||
#include "ospfd/ospfd.h"
|
#include "ospfd/ospfd.h"
|
||||||
|
#include "ospfd/ospf_bfd.h"
|
||||||
#include "ospfd/ospf_spf.h"
|
#include "ospfd/ospf_spf.h"
|
||||||
#include "ospfd/ospf_interface.h"
|
#include "ospfd/ospf_interface.h"
|
||||||
#include "ospfd/ospf_ism.h"
|
#include "ospfd/ospf_ism.h"
|
||||||
@ -545,10 +546,11 @@ static struct ospf_if_params *ospf_new_if_params(void)
|
|||||||
return oip;
|
return oip;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ospf_del_if_params(struct ospf_if_params *oip)
|
static void ospf_del_if_params(struct interface *ifp,
|
||||||
|
struct ospf_if_params *oip)
|
||||||
{
|
{
|
||||||
list_delete(&oip->auth_crypt);
|
list_delete(&oip->auth_crypt);
|
||||||
bfd_info_free(&(oip->bfd_info));
|
ospf_interface_disable_bfd(ifp, oip);
|
||||||
ldp_sync_info_free(&(oip->ldp_sync_info));
|
ldp_sync_info_free(&(oip->ldp_sync_info));
|
||||||
XFREE(MTYPE_OSPF_IF_PARAMS, oip);
|
XFREE(MTYPE_OSPF_IF_PARAMS, oip);
|
||||||
}
|
}
|
||||||
@ -582,7 +584,7 @@ void ospf_free_if_params(struct interface *ifp, struct in_addr addr)
|
|||||||
&& !OSPF_IF_PARAM_CONFIGURED(oip, auth_type)
|
&& !OSPF_IF_PARAM_CONFIGURED(oip, auth_type)
|
||||||
&& !OSPF_IF_PARAM_CONFIGURED(oip, if_area)
|
&& !OSPF_IF_PARAM_CONFIGURED(oip, if_area)
|
||||||
&& listcount(oip->auth_crypt) == 0) {
|
&& listcount(oip->auth_crypt) == 0) {
|
||||||
ospf_del_if_params(oip);
|
ospf_del_if_params(ifp, oip);
|
||||||
rn->info = NULL;
|
rn->info = NULL;
|
||||||
route_unlock_node(rn);
|
route_unlock_node(rn);
|
||||||
}
|
}
|
||||||
@ -696,10 +698,10 @@ static int ospf_if_delete_hook(struct interface *ifp)
|
|||||||
|
|
||||||
for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn))
|
for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn))
|
||||||
if (rn->info)
|
if (rn->info)
|
||||||
ospf_del_if_params(rn->info);
|
ospf_del_if_params(ifp, rn->info);
|
||||||
route_table_finish(IF_OIFS_PARAMS(ifp));
|
route_table_finish(IF_OIFS_PARAMS(ifp));
|
||||||
|
|
||||||
ospf_del_if_params((struct ospf_if_params *)IF_DEF_PARAMS(ifp));
|
ospf_del_if_params(ifp, IF_DEF_PARAMS(ifp));
|
||||||
XFREE(MTYPE_OSPF_IF_INFO, ifp->info);
|
XFREE(MTYPE_OSPF_IF_INFO, ifp->info);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#ifndef _ZEBRA_OSPF_INTERFACE_H
|
#ifndef _ZEBRA_OSPF_INTERFACE_H
|
||||||
#define _ZEBRA_OSPF_INTERFACE_H
|
#define _ZEBRA_OSPF_INTERFACE_H
|
||||||
|
|
||||||
|
#include "lib/bfd.h"
|
||||||
#include "qobj.h"
|
#include "qobj.h"
|
||||||
#include "hook.h"
|
#include "hook.h"
|
||||||
#include "ospfd/ospf_packet.h"
|
#include "ospfd/ospf_packet.h"
|
||||||
@ -104,7 +105,16 @@ struct ospf_if_params {
|
|||||||
uint32_t network_lsa_seqnum; /* Network LSA seqnum */
|
uint32_t network_lsa_seqnum; /* Network LSA seqnum */
|
||||||
|
|
||||||
/* BFD configuration */
|
/* BFD configuration */
|
||||||
struct bfd_info *bfd_info;
|
struct bfd_configuration {
|
||||||
|
/** BFD session detection multiplier. */
|
||||||
|
uint8_t detection_multiplier;
|
||||||
|
/** BFD session minimum required receive interval. */
|
||||||
|
uint32_t min_rx;
|
||||||
|
/** BFD session minimum required transmission interval. */
|
||||||
|
uint32_t min_tx;
|
||||||
|
/** BFD profile. */
|
||||||
|
char profile[BFD_PROFILE_NAME_LEN];
|
||||||
|
} * bfd_config;
|
||||||
|
|
||||||
/* MPLS LDP-IGP Sync configuration */
|
/* MPLS LDP-IGP Sync configuration */
|
||||||
struct ldp_sync_info *ldp_sync_info;
|
struct ldp_sync_info *ldp_sync_info;
|
||||||
@ -285,7 +295,6 @@ extern struct ospf_if_params *ospf_lookup_if_params(struct interface *,
|
|||||||
struct in_addr);
|
struct in_addr);
|
||||||
extern struct ospf_if_params *ospf_get_if_params(struct interface *,
|
extern struct ospf_if_params *ospf_get_if_params(struct interface *,
|
||||||
struct in_addr);
|
struct in_addr);
|
||||||
extern void ospf_del_if_params(struct ospf_if_params *);
|
|
||||||
extern void ospf_free_if_params(struct interface *, struct in_addr);
|
extern void ospf_free_if_params(struct interface *, struct in_addr);
|
||||||
extern void ospf_if_update_params(struct interface *, struct in_addr);
|
extern void ospf_if_update_params(struct interface *, struct in_addr);
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <zebra.h>
|
#include <zebra.h>
|
||||||
|
|
||||||
#include <lib/version.h>
|
#include <lib/version.h>
|
||||||
|
#include "bfd.h"
|
||||||
#include "getopt.h"
|
#include "getopt.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "prefix.h"
|
#include "prefix.h"
|
||||||
@ -98,6 +99,7 @@ static void sighup(void)
|
|||||||
static void sigint(void)
|
static void sigint(void)
|
||||||
{
|
{
|
||||||
zlog_notice("Terminating on signal");
|
zlog_notice("Terminating on signal");
|
||||||
|
bfd_protocol_integration_set_shutdown(true);
|
||||||
ospf_terminate();
|
ospf_terminate();
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
@ -214,7 +216,7 @@ int main(int argc, char **argv)
|
|||||||
ospf_vty_clear_init();
|
ospf_vty_clear_init();
|
||||||
|
|
||||||
/* OSPF BFD init */
|
/* OSPF BFD init */
|
||||||
ospf_bfd_init();
|
ospf_bfd_init(master);
|
||||||
|
|
||||||
/* OSPF LDP IGP Sync init */
|
/* OSPF LDP IGP Sync init */
|
||||||
ospf_ldp_sync_init();
|
ospf_ldp_sync_init();
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <zebra.h>
|
#include <zebra.h>
|
||||||
|
|
||||||
|
#include "lib/bfd.h"
|
||||||
#include "linklist.h"
|
#include "linklist.h"
|
||||||
#include "prefix.h"
|
#include "prefix.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
@ -99,8 +100,6 @@ struct ospf_neighbor *ospf_nbr_new(struct ospf_interface *oi)
|
|||||||
|
|
||||||
nbr->crypt_seqnum = 0;
|
nbr->crypt_seqnum = 0;
|
||||||
|
|
||||||
ospf_bfd_info_nbr_create(oi, nbr);
|
|
||||||
|
|
||||||
/* Initialize GR Helper info*/
|
/* Initialize GR Helper info*/
|
||||||
nbr->gr_helper_info.recvd_grace_period = 0;
|
nbr->gr_helper_info.recvd_grace_period = 0;
|
||||||
nbr->gr_helper_info.actual_grace_period = 0;
|
nbr->gr_helper_info.actual_grace_period = 0;
|
||||||
@ -149,7 +148,7 @@ void ospf_nbr_free(struct ospf_neighbor *nbr)
|
|||||||
/* Cancel all events. */ /* Thread lookup cost would be negligible. */
|
/* Cancel all events. */ /* Thread lookup cost would be negligible. */
|
||||||
thread_cancel_event(master, nbr);
|
thread_cancel_event(master, nbr);
|
||||||
|
|
||||||
ospf_bfd_info_free(&nbr->bfd_info);
|
bfd_sess_free(&nbr->bfd_session);
|
||||||
|
|
||||||
OSPF_NSM_TIMER_OFF(nbr->gr_helper_info.t_grace_timer);
|
OSPF_NSM_TIMER_OFF(nbr->gr_helper_info.t_grace_timer);
|
||||||
|
|
||||||
@ -458,6 +457,9 @@ static struct ospf_neighbor *ospf_nbr_add(struct ospf_interface *oi,
|
|||||||
if (ntohs(ospfh->auth_type) == OSPF_AUTH_CRYPTOGRAPHIC)
|
if (ntohs(ospfh->auth_type) == OSPF_AUTH_CRYPTOGRAPHIC)
|
||||||
nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
|
nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
|
||||||
|
|
||||||
|
/* Configure BFD if interface has it. */
|
||||||
|
ospf_neighbor_bfd_apply(nbr);
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF_EVENT)
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
zlog_debug("NSM[%s:%pI4]: start", IF_NAME(oi),
|
zlog_debug("NSM[%s:%pI4]: start", IF_NAME(oi),
|
||||||
&nbr->router_id);
|
&nbr->router_id);
|
||||||
|
@ -88,7 +88,7 @@ struct ospf_neighbor {
|
|||||||
uint32_t state_change; /* NSM state change counter */
|
uint32_t state_change; /* NSM state change counter */
|
||||||
|
|
||||||
/* BFD information */
|
/* BFD information */
|
||||||
void *bfd_info;
|
struct bfd_session_params *bfd_session;
|
||||||
|
|
||||||
/* ospf graceful restart HELPER info */
|
/* ospf graceful restart HELPER info */
|
||||||
struct ospf_helper_info gr_helper_info;
|
struct ospf_helper_info gr_helper_info;
|
||||||
|
@ -761,7 +761,8 @@ static void nsm_change_state(struct ospf_neighbor *nbr, int state)
|
|||||||
if (state == NSM_Down)
|
if (state == NSM_Down)
|
||||||
nbr->crypt_seqnum = 0;
|
nbr->crypt_seqnum = 0;
|
||||||
|
|
||||||
ospf_bfd_trigger_event(nbr, old_state, state);
|
if (nbr->bfd_session)
|
||||||
|
ospf_bfd_trigger_event(nbr, old_state, state);
|
||||||
|
|
||||||
/* Preserve old status? */
|
/* Preserve old status? */
|
||||||
}
|
}
|
||||||
|
@ -3776,7 +3776,8 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
|
|||||||
" Neighbor Count is %d, Adjacent neighbor count is %d\n",
|
" Neighbor Count is %d, Adjacent neighbor count is %d\n",
|
||||||
ospf_nbr_count(oi, 0),
|
ospf_nbr_count(oi, 0),
|
||||||
ospf_nbr_count(oi, NSM_Full));
|
ospf_nbr_count(oi, NSM_Full));
|
||||||
ospf_bfd_interface_show(vty, ifp, json_interface_sub, use_json);
|
|
||||||
|
ospf_interface_bfd_show(vty, ifp, json_interface_sub);
|
||||||
|
|
||||||
/* OSPF Authentication information */
|
/* OSPF Authentication information */
|
||||||
ospf_interface_auth_show(vty, oi, json_interface_sub, use_json);
|
ospf_interface_auth_show(vty, oi, json_interface_sub, use_json);
|
||||||
@ -5282,7 +5283,7 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty,
|
|||||||
.helper_exit_reason));
|
.helper_exit_reason));
|
||||||
}
|
}
|
||||||
|
|
||||||
ospf_bfd_show_info(vty, nbr->bfd_info, json_neigh, use_json, 0);
|
bfd_sess_show(vty, json_neigh, nbr->bfd_session);
|
||||||
|
|
||||||
if (use_json)
|
if (use_json)
|
||||||
json_object_array_add(json_neigh_array, json_neigh);
|
json_object_array_add(json_neigh_array, json_neigh);
|
||||||
@ -11716,7 +11717,7 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* bfd print. */
|
/* bfd print. */
|
||||||
if (params && params->bfd_info)
|
if (params && params->bfd_config)
|
||||||
ospf_bfd_write_config(vty, params);
|
ospf_bfd_write_config(vty, params);
|
||||||
|
|
||||||
/* MTU ignore print. */
|
/* MTU ignore print. */
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
#include "ldp_sync.h"
|
#include "ldp_sync.h"
|
||||||
|
|
||||||
#include "ospfd/ospfd.h"
|
#include "ospfd/ospfd.h"
|
||||||
|
#include "ospfd/ospf_bfd.h"
|
||||||
#include "ospfd/ospf_network.h"
|
#include "ospfd/ospf_network.h"
|
||||||
#include "ospfd/ospf_interface.h"
|
#include "ospfd/ospf_interface.h"
|
||||||
#include "ospfd/ospf_ism.h"
|
#include "ospfd/ospf_ism.h"
|
||||||
@ -1931,6 +1932,9 @@ static void ospf_nbr_nbma_add(struct ospf_nbr_nbma *nbr_nbma,
|
|||||||
|
|
||||||
nbr_nbma->nbr = nbr;
|
nbr_nbma->nbr = nbr;
|
||||||
|
|
||||||
|
/* Configure BFD if interface has it. */
|
||||||
|
ospf_neighbor_bfd_apply(nbr);
|
||||||
|
|
||||||
OSPF_NSM_EVENT_EXECUTE(nbr, NSM_Start);
|
OSPF_NSM_EVENT_EXECUTE(nbr, NSM_Start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user