This patch changes ospfd from only listening mode for BFD status updates to interactive mode of dynamically registering/deregistering neighbors discovered on BFD enabled interfaces with PTM/BFD through zebra. Neighbor is registered with BFD when 2-way adjacency is established and deregistered when adjacency goes down if the BFD is enabled on the interface through which the neighbor was discovered.

OSPF BFD command enhancement to configure BFD parameters (detect multiplier, min rx and min tx).
interface <if-name>
  ip ospf bfd <detect mult> <min rx> <min tx>

This patch also adds BFD support for IPv6 OSPF. ospf6d  will dynamically register/deregister IPv6 neighbors with BFD for monitoring the connectivity of the neighbor. Neighbor is registered with BFD when 2-way adjacency is established and deregistered when adjacency goes down if the BFD is enabled on the interface through which the neighbor was discovered.

OSPF6 BFD command added to configure BFD and parameters (detect multiplier, min rx and min tx).
interface <if-name>
  ipv6 ospf6 bfd <detect mult> <min rx> <min tx>

Signed-off-by: Radhika Mahankali <radhika@cumulusnetworks.com>
Reviewed-by:   Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by:   Kanna Rajagopal <kanna@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2015-07-22 12:35:37 -07:00
parent 7bbc6864de
commit 7f342629a9
28 changed files with 1283 additions and 429 deletions

View File

@ -32,43 +32,15 @@
#include "stream.h"
#include "zclient.h"
#include "vty.h"
#include "bgp_fsm.h"
#include "bfd.h"
#include "bgpd/bgpd.h"
#include "bgp_fsm.h"
#include "bgpd/bgp_bfd.h"
#include "bgpd/bgp_debug.h"
#include "bgpd/bgp_vty.h"
extern struct zclient *zclient;
/*
* bgp_bfd_peer_init - Allocate and initialize the peer BFD information
* with default values.
*/
void
bgp_bfd_peer_init(struct peer *peer)
{
struct bgp_bfd_peer_info *bfd_info;
peer->bfd_info = XCALLOC (MTYPE_BGP_PEER_BFD_INFO,
sizeof (struct bgp_bfd_peer_info));
bfd_info = (struct bgp_bfd_peer_info *)peer->bfd_info;
/* Set default BFD parameter values */
bfd_info->required_min_rx = BGP_BFD_DEF_MIN_RX;
bfd_info->desired_min_tx = BGP_BFD_DEF_MIN_TX;
bfd_info->detect_mult = BGP_BFD_DEF_DETECT_MULT;
}
/*
* bgp_bfd_peer_free - Free the peer BFD information.
*/
void
bgp_bfd_peer_free(struct peer *peer)
{
XFREE (MTYPE_BGP_PEER_BFD_INFO, peer->bfd_info);
}
/*
* bgp_bfd_peer_group2peer_copy - Copy the BFD information from peer group template
* to peer.
@ -76,11 +48,17 @@ bgp_bfd_peer_free(struct peer *peer)
void
bgp_bfd_peer_group2peer_copy(struct peer *conf, struct peer *peer)
{
struct bgp_bfd_peer_info *bfd_info;
struct bgp_bfd_peer_info *conf_bfd_info;
struct bfd_info *bfd_info;
struct bfd_info *conf_bfd_info;
bfd_info = (struct bgp_bfd_peer_info *)peer->bfd_info;
conf_bfd_info = (struct bgp_bfd_peer_info *)conf->bfd_info;
if (!conf->bfd_info)
return;
conf_bfd_info = (struct bfd_info *)conf->bfd_info;
if (!peer->bfd_info)
peer->bfd_info = bfd_info_create();
bfd_info = (struct bfd_info *)peer->bfd_info;
/* Copy BFD parameter values */
bfd_info->required_min_rx = conf_bfd_info->required_min_rx;
@ -101,111 +79,28 @@ bgp_bfd_is_peer_multihop(struct peer *peer)
}
/*
* sendmsg_bfd_peer - Format and send a Peer register/Unregister
* command to Zebra to be forwarded to BFD
* bgp_bfd_peer_sendmsg - Format and send a Peer register/Unregister
* command to Zebra to be forwarded to BFD
*/
static void
sendmsg_bfd_peer (struct peer *peer, int command)
bgp_bfd_peer_sendmsg (struct peer *peer, int command)
{
struct stream *s;
int ret;
int len;
struct bgp_bfd_peer_info *bfd_info;
struct bfd_info *bfd_info;
bfd_info = (struct bgp_bfd_peer_info *)peer->bfd_info;
bfd_info = (struct bfd_info *)peer->bfd_info;
/* Check socket. */
if (!zclient || zclient->sock < 0)
{
zlog_debug("%s: Can't send BFD peer register, Zebra client not established",
__FUNCTION__);
return;
}
s = zclient->obuf;
stream_reset (s);
zclient_create_header (s, command);
stream_putw(s, peer->su.sa.sa_family);
switch (peer->su.sa.sa_family)
{
case AF_INET:
stream_put_in_addr (s, &peer->su.sin.sin_addr);
break;
#ifdef HAVE_IPV6
case AF_INET6:
stream_put(s, &(peer->su.sin6.sin6_addr), 16);
break;
#endif
default:
break;
}
if (command != ZEBRA_BFD_DEST_DEREGISTER)
{
stream_putl(s, bfd_info->required_min_rx);
stream_putl(s, bfd_info->desired_min_tx);
stream_putc(s, bfd_info->detect_mult);
}
if (bgp_bfd_is_peer_multihop(peer))
{
stream_putc(s, 1);
/* Multi-hop destination send the source IP address to BFD */
if (peer->su_local)
{
stream_putw(s, peer->su_local->sa.sa_family);
switch (peer->su_local->sa.sa_family)
{
case AF_INET:
stream_put_in_addr (s, &peer->su_local->sin.sin_addr);
break;
#ifdef HAVE_IPV6
case AF_INET6:
stream_put(s, &(peer->su_local->sin6.sin6_addr), 16);
break;
#endif
default:
break;
}
}
stream_putc(s, peer->ttl);
}
else
{
stream_putc(s, 0);
#ifdef HAVE_IPV6
if ((peer->su.sa.sa_family == AF_INET6) && (peer->su_local))
{
stream_putw(s, peer->su_local->sa.sa_family);
stream_put(s, &(peer->su_local->sin6.sin6_addr), 16);
}
#endif
if (peer->nexthop.ifp)
{
len = strlen(peer->nexthop.ifp->name);
stream_putc(s, len);
stream_put(s, peer->nexthop.ifp->name, len);
}
else
{
stream_putc(s, 0);
}
}
stream_putw_at (s, 0, stream_get_endp (s));
ret = zclient_send_message(zclient);
if (ret < 0)
zlog_warn("sendmsg_bfd_peer: zclient_send_message() failed");
if (command == ZEBRA_BFD_DEST_REGISTER)
SET_FLAG(bfd_info->flags, BGP_BFD_FLAG_BFD_REG);
else if (command == ZEBRA_BFD_DEST_DEREGISTER)
UNSET_FLAG(bfd_info->flags, BGP_BFD_FLAG_BFD_REG);
return;
if (peer->su.sa.sa_family == AF_INET)
bfd_peer_sendmsg (zclient, bfd_info, AF_INET,
&peer->su.sin.sin_addr,
(peer->su_local) ? &peer->su_local->sin.sin_addr : NULL,
(peer->nexthop.ifp) ? peer->nexthop.ifp->name : NULL,
peer->ttl, bgp_bfd_is_peer_multihop(peer), command, 1);
else if (peer->su.sa.sa_family == AF_INET6)
bfd_peer_sendmsg (zclient, bfd_info, AF_INET6,
&peer->su.sin6.sin6_addr,
(peer->su_local) ? &peer->su_local->sin6.sin6_addr : NULL,
(peer->nexthop.ifp) ? peer->nexthop.ifp->name : NULL,
peer->ttl, bgp_bfd_is_peer_multihop(peer), command, 1);
}
/*
@ -215,16 +110,17 @@ sendmsg_bfd_peer (struct peer *peer, int command)
void
bgp_bfd_register_peer (struct peer *peer)
{
struct bgp_bfd_peer_info *bfd_info;
struct bfd_info *bfd_info;
bfd_info = (struct bgp_bfd_peer_info *)peer->bfd_info;
if (!peer->bfd_info)
return;
bfd_info = (struct bfd_info *)peer->bfd_info;
/* Check if BFD is enabled and peer has already been registered with BFD */
if (!CHECK_FLAG(peer->flags, PEER_FLAG_BFD) ||
CHECK_FLAG(bfd_info->flags, BGP_BFD_FLAG_BFD_REG))
if (CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_REG))
return;
sendmsg_bfd_peer(peer, ZEBRA_BFD_DEST_REGISTER);
bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_REGISTER);
}
/**
@ -235,41 +131,44 @@ bgp_bfd_register_peer (struct peer *peer)
void
bgp_bfd_deregister_peer (struct peer *peer)
{
struct bgp_bfd_peer_info *bfd_info;
struct bfd_info *bfd_info;
bfd_info = (struct bgp_bfd_peer_info *)peer->bfd_info;
if (!peer->bfd_info)
return;
bfd_info = (struct bfd_info *)peer->bfd_info;
/* Check if BFD is eanbled and peer has not been registered */
if (!CHECK_FLAG(peer->flags, PEER_FLAG_BFD) ||
!CHECK_FLAG(bfd_info->flags, BGP_BFD_FLAG_BFD_REG))
if (!CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_REG))
return;
sendmsg_bfd_peer(peer, ZEBRA_BFD_DEST_DEREGISTER);
bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_DEREGISTER);
}
/*
* bgp_bfd_update_peer - update peer with BFD with new BFD paramters
* through zebra.
*/
void
static void
bgp_bfd_update_peer (struct peer *peer)
{
struct bgp_bfd_peer_info *bfd_info;
struct bfd_info *bfd_info;
bfd_info = (struct bgp_bfd_peer_info *)peer->bfd_info;
if (!peer->bfd_info)
return;
bfd_info = (struct bfd_info *)peer->bfd_info;
/* Check if the peer has been registered with BFD*/
if (!CHECK_FLAG(bfd_info->flags, BGP_BFD_FLAG_BFD_REG))
if (!CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_REG))
return;
sendmsg_bfd_peer(peer, ZEBRA_BFD_DEST_UPDATE);
bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_UPDATE);
}
/*
* bgp_bfd_dest_replay - Replay all the peers that have BFD enabled
* to zebra
*/
int
static int
bgp_bfd_dest_replay (int command, struct zclient *client, zebra_size_t length)
{
struct listnode *mnode, *node, *nnode;
@ -284,9 +183,6 @@ bgp_bfd_dest_replay (int command, struct zclient *client, zebra_size_t length)
for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
{
if (!CHECK_FLAG (peer->flags, PEER_FLAG_BFD))
continue;
bgp_bfd_update_peer(peer);
}
@ -298,7 +194,7 @@ bgp_bfd_dest_replay (int command, struct zclient *client, zebra_size_t length)
* has changed and bring down the peer
* connectivity.
*/
int
static int
bgp_interface_bfd_dest_down (int command, struct zclient *zclient,
zebra_size_t length)
{
@ -306,7 +202,7 @@ bgp_interface_bfd_dest_down (int command, struct zclient *zclient,
struct prefix dp;
struct prefix sp;
ifp = zebra_interface_bfd_read (zclient->ibuf, &dp, &sp);
ifp = bfd_get_peer_info (zclient->ibuf, &dp, &sp);
if (BGP_DEBUG (zebra, ZEBRA))
{
@ -334,7 +230,7 @@ bgp_interface_bfd_dest_down (int command, struct zclient *zclient,
for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp))
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
{
if (!CHECK_FLAG (peer->flags, PEER_FLAG_BFD))
if (!peer->bfd_info)
continue;
if ((dp.family == AF_INET) && (peer->su.sa.sa_family == AF_INET))
@ -394,53 +290,39 @@ bgp_interface_bfd_dest_down (int command, struct zclient *zclient,
/*
* bgp_bfd_peer_param_set - Set the configured BFD paramter values for peer.
*/
int
static int
bgp_bfd_peer_param_set (struct peer *peer, u_int32_t min_rx, u_int32_t min_tx,
u_int8_t detect_mult, int reg_peer, int defaults)
u_int8_t detect_mult, int defaults)
{
struct peer_group *group;
struct listnode *node, *nnode;
int change = 0;
struct bgp_bfd_peer_info *bfd_info;
int command = 0;
bfd_info = (struct bgp_bfd_peer_info *)peer->bfd_info;
if ((bfd_info->required_min_rx != min_rx) ||
(bfd_info->desired_min_tx != min_tx) ||
(bfd_info->detect_mult != detect_mult))
change = 1;
bfd_info->required_min_rx = min_rx;
bfd_info->desired_min_tx = min_tx;
bfd_info->detect_mult = detect_mult;
if (!defaults)
SET_FLAG (bfd_info->flags, BGP_BFD_FLAG_PARAM_CFG);
else
UNSET_FLAG (bfd_info->flags, BGP_BFD_FLAG_PARAM_CFG);
bfd_set_param(&(peer->bfd_info), min_rx, min_tx, detect_mult,
defaults, &command);
if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
{
bfd_info = (struct bgp_bfd_peer_info *)peer->bfd_info;
bfd_info->required_min_rx = min_rx;
bfd_info->desired_min_tx = min_tx;
bfd_info->detect_mult = detect_mult;
SET_FLAG (bfd_info->flags, BGP_BFD_FLAG_PARAM_CFG);
command = 0;
bfd_set_param(&(peer->bfd_info), min_rx, min_tx, detect_mult,
defaults, &command);
if (reg_peer && (peer->status == Established))
if ((peer->status == Established) &&
(command == ZEBRA_BFD_DEST_REGISTER))
bgp_bfd_register_peer(peer);
else if (change)
else if (command == ZEBRA_BFD_DEST_UPDATE)
bgp_bfd_update_peer(peer);
}
}
else
else
{
if (reg_peer && (peer->status == Established))
if ((peer->status == Established) &&
(command == ZEBRA_BFD_DEST_REGISTER))
bgp_bfd_register_peer(peer);
else if (change)
else if (command == ZEBRA_BFD_DEST_UPDATE)
bgp_bfd_update_peer(peer);
}
return 0;
@ -449,35 +331,30 @@ bgp_bfd_peer_param_set (struct peer *peer, u_int32_t min_rx, u_int32_t min_tx,
/*
* bgp_bfd_peer_param_unset - Unset the configured BFD paramter values for peer.
*/
int
static int
bgp_bfd_peer_param_unset (struct peer *peer)
{
struct peer_group *group;
struct listnode *node, *nnode;
struct bgp_bfd_peer_info *bfd_info;
bfd_info = (struct bgp_bfd_peer_info *)peer->bfd_info;
bfd_info->required_min_rx = BGP_BFD_DEF_MIN_RX;
bfd_info->desired_min_tx = BGP_BFD_DEF_MIN_TX;
bfd_info->detect_mult = BGP_BFD_DEF_DETECT_MULT;
UNSET_FLAG (bfd_info->flags, BGP_BFD_FLAG_PARAM_CFG);
if (!peer->bfd_info)
return 0;
if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
bfd_info_free(&(peer->bfd_info));
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
{
bfd_info->required_min_rx = BGP_BFD_DEF_MIN_RX;
bfd_info->desired_min_tx = BGP_BFD_DEF_MIN_TX;
bfd_info->detect_mult = BGP_BFD_DEF_DETECT_MULT;
UNSET_FLAG (bfd_info->flags, BGP_BFD_FLAG_PARAM_CFG);
bgp_bfd_deregister_peer(peer);
bfd_info_free(&(peer->bfd_info));
}
}
else
bgp_bfd_deregister_peer(peer);
{
bgp_bfd_deregister_peer(peer);
bfd_info_free(&(peer->bfd_info));
}
return 0;
}
@ -487,11 +364,14 @@ bgp_bfd_peer_param_unset (struct peer *peer)
void
bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr)
{
struct bgp_bfd_peer_info *bfd_info;
struct bfd_info *bfd_info;
bfd_info = (struct bgp_bfd_peer_info *)peer->bfd_info;
if (!peer->bfd_info)
return;
if (CHECK_FLAG (bfd_info->flags, BGP_BFD_FLAG_PARAM_CFG))
bfd_info = (struct bfd_info *)peer->bfd_info;
if (CHECK_FLAG (bfd_info->flags, BFD_FLAG_PARAM_CFG))
vty_out (vty, " neighbor %s bfd %d %d %d%s", addr,
bfd_info->detect_mult, bfd_info->required_min_rx,
bfd_info->desired_min_tx, VTY_NEWLINE);
@ -505,20 +385,20 @@ bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr)
void
bgp_bfd_show_info(struct vty *vty, struct peer *peer)
{
struct bgp_bfd_peer_info *bfd_info;
struct bfd_info *bfd_info;
bfd_info = (struct bgp_bfd_peer_info *)peer->bfd_info;
if (!peer->bfd_info)
return;
if (CHECK_FLAG(peer->flags, PEER_FLAG_BFD))
{
vty_out (vty, " BFD: Multi-hop: %s%s",
(bgp_bfd_is_peer_multihop(peer)) ? "yes" : "no", VTY_NEWLINE);
vty_out (vty, " Detect Mul: %d, Min Rx interval: %d,"
" Min Tx interval: %d%s",
bfd_info->detect_mult, bfd_info->required_min_rx,
bfd_info->desired_min_tx, VTY_NEWLINE);
vty_out (vty, "%s", VTY_NEWLINE);
}
bfd_info = (struct bfd_info *)peer->bfd_info;
vty_out (vty, " BFD: Multi-hop: %s%s",
(bgp_bfd_is_peer_multihop(peer)) ? "yes" : "no", VTY_NEWLINE);
vty_out (vty, " Detect Mul: %d, Min Rx interval: %d,"
" Min Tx interval: %d%s",
bfd_info->detect_mult, bfd_info->required_min_rx,
bfd_info->desired_min_tx, VTY_NEWLINE);
vty_out (vty, "%s", VTY_NEWLINE);
}
DEFUN (neighbor_bfd,
@ -530,23 +410,13 @@ DEFUN (neighbor_bfd,
{
struct peer *peer;
int ret;
int reg_peer = 0;
peer = peer_and_group_lookup_vty (vty, argv[0]);
if (! peer)
return CMD_WARNING;
if ( !CHECK_FLAG (peer->flags, PEER_FLAG_BFD) )
{
ret = peer_flag_set (peer, PEER_FLAG_BFD);
if (ret != 0)
return bgp_vty_return (vty, ret);
reg_peer = 1;
}
ret = bgp_bfd_peer_param_set (peer, BGP_BFD_DEF_MIN_RX, BGP_BFD_DEF_MIN_TX,
BGP_BFD_DEF_DETECT_MULT, reg_peer, 1);
ret = bgp_bfd_peer_param_set (peer, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
BFD_DEF_DETECT_MULT, 1);
if (ret != 0)
return bgp_vty_return (vty, ret);
@ -556,7 +426,7 @@ DEFUN (neighbor_bfd,
DEFUN (neighbor_bfd_param,
neighbor_bfd_param_cmd,
NEIGHBOR_CMD2 "bfd <2-255> <50-60000> <50-60000>",
NEIGHBOR_CMD2 "bfd " BFD_CMD_DETECT_MULT_RANGE BFD_CMD_MIN_RX_RANGE BFD_CMD_MIN_TX_RANGE,
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Enables BFD support\n"
@ -569,26 +439,16 @@ DEFUN (neighbor_bfd_param,
u_int32_t tx_val;
u_int8_t dm_val;
int ret;
int reg_peer = 0;
peer = peer_and_group_lookup_vty (vty, argv[0]);
if (!peer)
return CMD_WARNING;
if (!CHECK_FLAG (peer->flags, PEER_FLAG_BFD))
{
ret = peer_flag_set (peer, PEER_FLAG_BFD);
if (ret != 0)
return bgp_vty_return (vty, ret);
if ((ret = bfd_validate_param (vty, argv[1], argv[2], argv[3], &dm_val,
&rx_val, &tx_val)) != CMD_SUCCESS)
return ret;
reg_peer = 1;
}
VTY_GET_INTEGER_RANGE ("detect-mul", dm_val, argv[1], 2, 255);
VTY_GET_INTEGER_RANGE ("min-rx", rx_val, argv[2], 50, 60000);
VTY_GET_INTEGER_RANGE ("min-tx", tx_val, argv[3], 50, 60000);
ret = bgp_bfd_peer_param_set (peer, rx_val, tx_val, dm_val, reg_peer, 0);
ret = bgp_bfd_peer_param_set (peer, rx_val, tx_val, dm_val, 0);
if (ret != 0)
return bgp_vty_return (vty, ret);
@ -611,18 +471,10 @@ DEFUN (no_neighbor_bfd,
if (! peer)
return CMD_WARNING;
/* Do nothing if there is no change in the flag */
if ( !CHECK_FLAG (peer->flags, PEER_FLAG_BFD) )
return CMD_SUCCESS;
ret = bgp_bfd_peer_param_unset(peer);
if (ret != 0)
return bgp_vty_return (vty, ret);
ret = peer_flag_unset (peer, PEER_FLAG_BFD);
if (ret != 0)
return bgp_vty_return (vty, ret);
return CMD_SUCCESS;
}

View File

@ -24,30 +24,9 @@
#ifndef _QUAGGA_BGP_BFD_H
#define _QUAGGA_BGP_BFD_H
#define BGP_BFD_DEF_MIN_RX 300
#define BGP_BFD_DEF_MIN_TX 300
#define BGP_BFD_DEF_DETECT_MULT 3
#define BGP_BFD_FLAG_PARAM_CFG (1 << 0) /* parameters have been configured */
#define BGP_BFD_FLAG_BFD_REG (1 << 1) /* Peer registered with BFD */
struct bgp_bfd_peer_info
{
u_int16_t flags;
u_int8_t detect_mult;
u_int32_t desired_min_tx;
u_int32_t required_min_rx;
};
extern void
bgp_bfd_init(void);
extern void
bgp_bfd_peer_init(struct peer *peer);
extern void
bgp_bfd_peer_free(struct peer *peer);
extern void
bgp_bfd_peer_group2peer_copy(struct peer *conf, struct peer *peer);
@ -57,9 +36,6 @@ bgp_bfd_register_peer (struct peer *peer);
extern void
bgp_bfd_deregister_peer (struct peer *peer);
extern void
bgp_bfd_update_peer (struct peer *peer);
extern void
bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr);

View File

@ -36,6 +36,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "linklist.h"
#include "workqueue.h"
#include "queue.h"
#include "bfd.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
@ -826,6 +827,8 @@ peer_global_config_reset (struct peer *peer)
peer->v_holdtime = peer->bgp->default_holdtime;
peer->v_keepalive = peer->bgp->default_keepalive;
bfd_info_free(&(peer->bfd_info));
/* Set back the CONFIG_NODE flag. */
SET_FLAG (peer->flags, PEER_FLAG_CONFIG_NODE);
}
@ -951,8 +954,7 @@ peer_free (struct peer *peer)
if (peer->conf_if)
XFREE (MTYPE_PEER_CONF_IF, peer->conf_if);
if (peer->bfd_info)
bgp_bfd_peer_free(peer);
bfd_info_free(&(peer->bfd_info));
memset (peer, 0, sizeof (struct peer));
@ -1298,8 +1300,6 @@ peer_create (union sockunion *su, const char *conf_if, struct bgp *bgp,
}
}
bgp_bfd_peer_init(peer);
/* Set up peer's events and timers. */
if (! active && peer_active (peer))
bgp_timer_set (peer);
@ -1905,7 +1905,6 @@ peer_group_get (struct bgp *bgp, const char *name)
group->conf->connect = 0;
SET_FLAG (group->conf->sflags, PEER_STATUS_GROUP);
listnode_add_sort (bgp->group, group);
bgp_bfd_peer_init(group->conf);
return 0;
}
@ -2251,8 +2250,7 @@ peer_group_delete (struct peer_group *group)
/* Delete from all peer_group list. */
listnode_delete (bgp->group, group);
if (group->conf->bfd_info)
bgp_bfd_peer_free(group->conf);
bfd_info_free(&(group->conf->bfd_info));
peer_group_free (group);
@ -2569,6 +2567,7 @@ peer_group_unbind (struct bgp *bgp, struct peer *peer,
}
return 0;
}
bgp_bfd_deregister_peer(peer);
peer_global_config_reset (peer);
}
@ -3234,7 +3233,6 @@ static const struct peer_flag_action peer_flag_action_list[] =
{ PEER_FLAG_DYNAMIC_CAPABILITY, 0, peer_change_reset },
{ PEER_FLAG_DISABLE_CONNECTED_CHECK, 0, peer_change_reset },
{ PEER_FLAG_CAPABILITY_ENHE, 0, peer_change_reset },
{ PEER_FLAG_BFD, 0, peer_change_none },
{ 0, 0, 0 }
};
@ -6073,9 +6071,8 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
vty_out (vty, " neighbor %s shutdown%s", addr, VTY_NEWLINE);
/* bfd. */
if (CHECK_FLAG (peer->flags, PEER_FLAG_BFD))
if (! peer_group_active (peer) ||
! CHECK_FLAG (g_peer->flags, PEER_FLAG_BFD))
if (peer->bfd_info)
if (! peer_group_active (peer) || ! g_peer->bfd_info)
{
bgp_bfd_peer_config_write(vty, peer, addr);
}

View File

@ -610,11 +610,10 @@ struct peer
#define PEER_FLAG_LOCAL_AS_REPLACE_AS (1 << 8) /* local-as no-prepend replace-as */
#define PEER_FLAG_DELETE (1 << 9) /* mark the peer for deleting */
#define PEER_FLAG_CONFIG_NODE (1 << 10) /* the node to update configs on */
#define PEER_FLAG_BFD (1 << 11) /* bfd */
#define PEER_FLAG_LONESOUL (1 << 12)
#define PEER_FLAG_DYNAMIC_NEIGHBOR (1 << 13) /* dynamic neighbor */
#define PEER_FLAG_CAPABILITY_ENHE (1 << 14) /* Extended next-hop (rfc 5549)*/
#define PEER_FLAG_IFPEER_V6ONLY (1 << 15) /* if-based peer is v6 only *
#define PEER_FLAG_LONESOUL (1 << 11)
#define PEER_FLAG_DYNAMIC_NEIGHBOR (1 << 12) /* dynamic neighbor */
#define PEER_FLAG_CAPABILITY_ENHE (1 << 13) /* Extended next-hop (rfc 5549)*/
#define PEER_FLAG_IFPEER_V6ONLY (1 << 14) /* if-based peer is v6 only *
/* NSF mode (graceful restart) */
u_char nsf[AFI_MAX][SAFI_MAX];

View File

@ -13,7 +13,7 @@ libzebra_la_SOURCES = \
filter.c routemap.c distribute.c stream.c str.c log.c plist.c \
zclient.c sockopt.c smux.c agentx.c snmp.c md5.c if_rmap.c keychain.c privs.c \
sigevent.c pqueue.c jhash.c memtypes.c workqueue.c nexthop.c json.c \
ptm_lib.c csv.c
ptm_lib.c csv.c bfd.c
BUILT_SOURCES = memtypes.h route_types.h gitversion.h
@ -29,7 +29,7 @@ pkginclude_HEADERS = \
plist.h zclient.h sockopt.h smux.h md5.h if_rmap.h keychain.h \
privs.h sigevent.h pqueue.h jhash.h zassert.h memtypes.h \
workqueue.h route_types.h libospf.h nexthop.h json.h \
ptm_lib.h csv.h
ptm_lib.h csv.h bfd.h
EXTRA_DIST = \
regex.c regex-gnu.h \

287
lib/bfd.c Normal file
View File

@ -0,0 +1,287 @@
/**
* bfd.c: BFD handling routines
*
* @copyright Copyright (C) 2015 Cumulus Networks, Inc.
*
* This file is part of GNU Zebra.
*
* GNU Zebra is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* GNU Zebra is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Zebra; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <zebra.h>
#include "command.h"
#include "memory.h"
#include "prefix.h"
#include "thread.h"
#include "stream.h"
#include "zclient.h"
#include "table.h"
#include "vty.h"
#include "bfd.h"
/*
* bfd_info_create - Allocate the BFD information
*/
struct bfd_info *
bfd_info_create(void)
{
struct bfd_info *bfd_info;
bfd_info = XCALLOC (MTYPE_BFD_INFO, sizeof (struct bfd_info));
assert(bfd_info);
return bfd_info;
}
/*
* bfd_info_free - Free the BFD information.
*/
void
bfd_info_free(void **bfd_info)
{
if (*bfd_info)
{
XFREE (MTYPE_BFD_INFO, *bfd_info);
*bfd_info = NULL;
}
}
/*
* bfd_validate_param - Validate the BFD paramter information.
*/
int
bfd_validate_param(struct vty *vty, const char *dm_str, const char *rx_str,
const char *tx_str, u_int8_t *dm_val, u_int32_t *rx_val,
u_int32_t *tx_val)
{
VTY_GET_INTEGER_RANGE ("detect-mul", *dm_val, dm_str,
BFD_MIN_DETECT_MULT, BFD_MAX_DETECT_MULT);
VTY_GET_INTEGER_RANGE ("min-rx", *rx_val, rx_str,
BFD_MIN_MIN_RX, BFD_MAX_MIN_RX);
VTY_GET_INTEGER_RANGE ("min-tx", *tx_val, tx_str,
BFD_MIN_MIN_TX, BFD_MAX_MIN_TX);
return CMD_SUCCESS;
}
/*
* bfd_set_param - Set the configured BFD paramter values
*/
void
bfd_set_param (struct bfd_info **bfd_info, u_int32_t min_rx, u_int32_t min_tx,
u_int8_t detect_mult, int defaults, int *command)
{
if (!*bfd_info)
{
*bfd_info = bfd_info_create();
*command = ZEBRA_BFD_DEST_REGISTER;
}
else
{
if (((*bfd_info)->required_min_rx != min_rx) ||
((*bfd_info)->desired_min_tx != min_tx) ||
((*bfd_info)->detect_mult != detect_mult))
*command = ZEBRA_BFD_DEST_UPDATE;
}
if (*command)
{
(*bfd_info)->required_min_rx = min_rx;
(*bfd_info)->desired_min_tx = min_tx;
(*bfd_info)->detect_mult = detect_mult;
}
if (!defaults)
SET_FLAG ((*bfd_info)->flags, BFD_FLAG_PARAM_CFG);
else
UNSET_FLAG ((*bfd_info)->flags, BFD_FLAG_PARAM_CFG);
}
/*
* bfd_peer_sendmsg - Format and send a peer register/Unregister
* command to Zebra to be forwarded to BFD
*/
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 command, int set_flag)
{
struct stream *s;
int ret;
int len;
/* Check socket. */
if (!zclient || zclient->sock < 0)
{
zlog_debug("%s: Can't send BFD peer register, Zebra client not "
"established", __FUNCTION__);
return;
}
s = zclient->obuf;
stream_reset (s);
zclient_create_header (s, command);
stream_putw(s, family);
switch (family)
{
case AF_INET:
stream_put_in_addr (s, (struct in_addr *)dst_ip);
break;
#ifdef HAVE_IPV6
case AF_INET6:
stream_put(s, dst_ip, 16);
break;
#endif
default:
break;
}
if (command != ZEBRA_BFD_DEST_DEREGISTER)
{
stream_putl(s, bfd_info->required_min_rx);
stream_putl(s, bfd_info->desired_min_tx);
stream_putc(s, bfd_info->detect_mult);
}
if (multihop)
{
stream_putc(s, 1);
/* Multi-hop destination send the source IP address to BFD */
if (src_ip)
{
stream_putw(s, family);
switch (family)
{
case AF_INET:
stream_put_in_addr (s, (struct in_addr *) src_ip);
break;
#ifdef HAVE_IPV6
case AF_INET6:
stream_put(s, src_ip, 16);
break;
#endif
default:
break;
}
}
stream_putc(s, ttl);
}
else
{
stream_putc(s, 0);
#ifdef HAVE_IPV6
if ((family == AF_INET6) && (src_ip))
{
stream_putw(s, family);
stream_put(s, src_ip, 16);
}
#endif
if (if_name)
{
len = strlen(if_name);
stream_putc(s, len);
stream_put(s, if_name, len);
}
else
{
stream_putc(s, 0);
}
}
stream_putw_at (s, 0, stream_get_endp (s));
ret = zclient_send_message(zclient);
if (ret < 0)
{
zlog_warn("bfd_peer_sendmsg: zclient_send_message() failed");
return;
}
if (set_flag)
{
if (command == ZEBRA_BFD_DEST_REGISTER)
SET_FLAG(bfd_info->flags, BFD_FLAG_BFD_REG);
else if (command == ZEBRA_BFD_DEST_DEREGISTER)
UNSET_FLAG(bfd_info->flags, BFD_FLAG_BFD_REG);
}
return;
}
/*
* bfd_get_command_dbg_str - Convert command to a debug string.
*/
const char *
bfd_get_command_dbg_str(int command)
{
switch (command)
{
case ZEBRA_BFD_DEST_REGISTER:
return "Register";
case ZEBRA_BFD_DEST_DEREGISTER:
return "Deregister";
case ZEBRA_BFD_DEST_UPDATE:
return "Update";
default:
return "Unknown";
}
}
/*
* bfd_get_peer_info - Extract the Peer information for which the BFD session
* went down from the message sent from Zebra to clients.
*/
struct interface *
bfd_get_peer_info (struct stream *s, struct prefix *dp, struct prefix *sp)
{
unsigned int ifindex;
struct interface *ifp = NULL;
int plen;
/* Get interface index. */
ifindex = stream_getl (s);
/* Lookup index. */
if (ifindex != 0)
{
ifp = if_lookup_by_index (ifindex);
if (ifp == NULL)
{
zlog_warn ("zebra_interface_bfd_read: "
"Can't find interface by ifindex: %d ", ifindex);
return NULL;
}
}
/* Fetch destination address. */
dp->family = stream_getc (s);
plen = prefix_blen (dp);
stream_get (&dp->u.prefix, s, plen);
dp->prefixlen = stream_getc (s);
if (sp)
{
sp->family = stream_getc (s);
plen = prefix_blen (sp);
stream_get (&sp->u.prefix, s, plen);
sp->prefixlen = stream_getc (s);
}
return ifp;
}

77
lib/bfd.h Normal file
View File

@ -0,0 +1,77 @@
/**
* bfd.h: BFD definitions and structures
*
* @copyright Copyright (C) 2015 Cumulus Networks, Inc.
*
* This file is part of GNU Zebra.
*
* GNU Zebra is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* GNU Zebra is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Zebra; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef _ZEBRA_BFD_H
#define _ZEBRA_BFD_H
#define BFD_CMD_DETECT_MULT_RANGE "<2-255> "
#define BFD_CMD_MIN_RX_RANGE "<50-60000> "
#define BFD_CMD_MIN_TX_RANGE "<50-60000>"
#define BFD_DEF_MIN_RX 300
#define BFD_MIN_MIN_RX 50
#define BFD_MAX_MIN_RX 60000
#define BFD_DEF_MIN_TX 300
#define BFD_MIN_MIN_TX 50
#define BFD_MAX_MIN_TX 60000
#define BFD_DEF_DETECT_MULT 3
#define BFD_MIN_DETECT_MULT 2
#define BFD_MAX_DETECT_MULT 255
#define BFD_FLAG_PARAM_CFG (1 << 0) /* parameters have been configured */
#define BFD_FLAG_BFD_REG (1 << 1) /* Peer registered with BFD */
struct bfd_info
{
u_int16_t flags;
u_int8_t detect_mult;
u_int32_t desired_min_tx;
u_int32_t required_min_rx;
};
extern struct bfd_info *
bfd_info_create(void);
extern void
bfd_info_free(void **bfd_info);
extern int
bfd_validate_param(struct vty *vty, const char *dm_str, const char *rx_str,
const char *tx_str, u_int8_t *dm_val, u_int32_t *rx_val,
u_int32_t *tx_val);
extern void
bfd_set_param (struct bfd_info **bfd_info, u_int32_t min_rx, u_int32_t min_tx,
u_int8_t detect_mult, int defaults, int *command);
extern 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 command, int set_flag);
extern const char *
bfd_get_command_dbg_str(int command);
extern struct interface *
bfd_get_peer_info (struct stream *s, struct prefix *dp, struct prefix *sp);
#endif /* _ZEBRA_BFD_H */

View File

@ -71,6 +71,7 @@ struct memory_list memory_list_lib[] =
{ MTYPE_PQUEUE, "Priority queue" },
{ MTYPE_PQUEUE_DATA, "Priority queue data" },
{ MTYPE_HOST, "Host config" },
{ MTYPE_BFD_INFO, "BFD info" },
{ -1, NULL },
};
@ -162,7 +163,6 @@ struct memory_list memory_list_bgp[] =
{ MTYPE_BGP_REGEXP, "BGP regexp" },
{ MTYPE_BGP_AGGREGATE, "BGP aggregate" },
{ MTYPE_BGP_ADDR, "BGP own address" },
{ MTYPE_BGP_PEER_BFD_INFO, "BGP peer BFD info" },
{ -1, NULL }
};

View File

@ -942,46 +942,6 @@ memconstant(const void *s, int c, size_t n)
return 1;
}
struct interface*
zebra_interface_bfd_read (struct stream *s, struct prefix *dp,
struct prefix *sp)
{
unsigned int ifindex;
struct interface *ifp = NULL;
int plen;
/* Get interface index. */
ifindex = stream_getl (s);
/* Lookup index. */
if (ifindex != 0)
{
ifp = if_lookup_by_index (ifindex);
if (ifp == NULL)
{
zlog_warn ("zebra_interface_bfd_read: "
"Can't find interface by ifindex: %d ", ifindex);
return NULL;
}
}
/* Fetch destination address. */
dp->family = stream_getc (s);
plen = prefix_blen (dp);
stream_get (&dp->u.prefix, s, plen);
dp->prefixlen = stream_getc (s);
if (sp)
{
sp->family = stream_getc (s);
plen = prefix_blen (sp);
stream_get (&sp->u.prefix, s, plen);
sp->prefixlen = stream_getc (s);
}
return ifp;
}
struct connected *
zebra_interface_address_read (int type, struct stream *s)

View File

@ -177,9 +177,6 @@ extern void zclient_create_header (struct stream *, uint16_t);
extern struct interface *zebra_interface_add_read (struct stream *);
extern struct interface *zebra_interface_state_read (struct stream *s);
extern struct connected *zebra_interface_address_read (int, struct stream *);
extern struct interface *zebra_interface_bfd_read (struct stream *s,
struct prefix *,
struct prefix *);
extern struct nbr_connected *zebra_interface_nbr_address_read (int, struct stream *);
extern void zebra_interface_if_set_value (struct stream *, struct interface *);
extern void zebra_router_id_update_read (struct stream *s, struct prefix *rid);

View File

@ -15,14 +15,14 @@ libospf6_a_SOURCES = \
ospf6_top.c ospf6_area.c ospf6_interface.c ospf6_neighbor.c \
ospf6_flood.c ospf6_route.c ospf6_intra.c ospf6_zebra.c \
ospf6_spf.c ospf6_proto.c ospf6_asbr.c ospf6_abr.c ospf6_snmp.c \
ospf6d.c
ospf6d.c ospf6_bfd.c
noinst_HEADERS = \
ospf6_network.h ospf6_message.h ospf6_lsa.h ospf6_lsdb.h \
ospf6_top.h ospf6_area.h ospf6_interface.h ospf6_neighbor.h \
ospf6_flood.h ospf6_route.h ospf6_intra.h ospf6_zebra.h \
ospf6_spf.h ospf6_proto.h ospf6_asbr.h ospf6_abr.h ospf6_snmp.h \
ospf6d.h
ospf6d.h ospf6_bfd.h
ospf6d_SOURCES = \
ospf6_main.c $(libospf6_a_SOURCES)

341
ospf6d/ospf6_bfd.c Normal file
View File

@ -0,0 +1,341 @@
/**
* ospf6_bfd.c: IPv6 OSPF BFD handling routines
*
* @copyright Copyright (C) 2015 Cumulus Networks, Inc.
*
* This file is part of GNU Zebra.
*
* GNU Zebra is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* GNU Zebra is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Zebra; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <zebra.h>
#include "command.h"
#include "linklist.h"
#include "memory.h"
#include "prefix.h"
#include "thread.h"
#include "buffer.h"
#include "stream.h"
#include "zclient.h"
#include "vty.h"
#include "table.h"
#include "bfd.h"
#include "if.h"
#include "ospf6d.h"
#include "ospf6_message.h"
#include "ospf6_neighbor.h"
#include "ospf6_interface.h"
#include "ospf6_route.h"
#include "ospf6_zebra.h"
#include "ospf6_bfd.h"
extern struct zclient *zclient;
/*
* ospf6_bfd_reg_dereg_nbr - Register/Deregister a neighbor with BFD through
* zebra for starting/stopping the monitoring of
* the neighbor rechahability.
*/
static void
ospf6_bfd_reg_dereg_nbr (struct ospf6_neighbor *on, int command)
{
struct ospf6_interface *oi = on->ospf6_if;
struct interface *ifp = oi->interface;
struct bfd_info *bfd_info;
char src[64];
if (!oi->bfd_info)
return;
bfd_info = (struct bfd_info *)oi->bfd_info;
if (IS_OSPF6_DEBUG_ZEBRA(SEND))
{
inet_ntop (AF_INET6, &on->linklocal_addr, src, sizeof (src));
zlog_debug ("%s nbr (%s) with BFD",
bfd_get_command_dbg_str(command), src);
}
bfd_peer_sendmsg (zclient, bfd_info, AF_INET6, &on->linklocal_addr,
on->ospf6_if->linklocal_addr, ifp->name,
0, 0, command, 0);
}
/*
* ospf6_bfd_trigger_event - Neighbor is registered/deregistered with BFD when
* neighbor state is changed to/from 2way.
*/
void
ospf6_bfd_trigger_event(struct ospf6_neighbor *on, int old_state, int state)
{
if ((old_state < OSPF6_NEIGHBOR_TWOWAY) && (state >= OSPF6_NEIGHBOR_TWOWAY))
ospf6_bfd_reg_dereg_nbr(on, ZEBRA_BFD_DEST_REGISTER);
else if ((old_state >= OSPF6_NEIGHBOR_TWOWAY) &&
(state < OSPF6_NEIGHBOR_TWOWAY))
ospf6_bfd_reg_dereg_nbr(on, ZEBRA_BFD_DEST_DEREGISTER);
}
/*
* ospf6_bfd_reg_dereg_all_nbr - Register/Deregister all neighbors associated
* with a interface with BFD through
* zebra for starting/stopping the monitoring of
* the neighbor rechahability.
*/
static void
ospf6_bfd_reg_dereg_all_nbr (struct ospf6_interface *oi, int command)
{
struct ospf6_neighbor *on;
struct listnode *node;
for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, node, on))
{
if (on->state < OSPF6_NEIGHBOR_TWOWAY)
continue;
ospf6_bfd_reg_dereg_nbr(on, command);
}
}
/*
* ospf6_bfd_nbr_replay - Replay all the neighbors that have BFD enabled
* to zebra
*/
static int
ospf6_bfd_nbr_replay (int command, struct zclient *client, zebra_size_t length)
{
struct listnode *inode, *nnode;
struct interface *ifp;
struct ospf6_interface *oi;
struct ospf6_neighbor *on;
char dst[64];
if (IS_OSPF6_DEBUG_ZEBRA(RECV))
zlog_debug("Zebra: BFD Dest replay request");
/* Replay the neighbor, if BFD is enabled on the interface*/
for (ALL_LIST_ELEMENTS_RO (iflist, inode, ifp))
{
oi = (struct ospf6_interface *) ifp->info;
if (!oi || !oi->bfd_info)
continue;
for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, nnode, on))
{
if (on->state < OSPF6_NEIGHBOR_TWOWAY)
continue;
if (IS_OSPF6_DEBUG_ZEBRA(SEND))
{
inet_ntop (AF_INET6, &on->linklocal_addr, dst, sizeof (dst));
zlog_debug ("Replaying nbr (%s) to BFD", dst);
}
ospf6_bfd_reg_dereg_nbr(on, ZEBRA_BFD_DEST_UPDATE);
}
}
return 0;
}
/*
* ospf6_bfd_interface_dest_down - Find the neighbor for which the BFD status
* has changed and bring down the neighbor
* connectivity.
*/
static int
ospf6_bfd_interface_dest_down (int command, struct zclient *zclient,
zebra_size_t length)
{
struct interface *ifp;
struct ospf6_interface *oi;
struct ospf6_neighbor *on;
struct prefix dp;
struct prefix sp;
struct listnode *node, *nnode;
char dst[64];
ifp = bfd_get_peer_info(zclient->ibuf, &dp, &sp);
if ((ifp == NULL) || (dp.family != AF_INET6))
return 0;
if (IS_OSPF6_DEBUG_ZEBRA (RECV))
{
char buf[128];
prefix2str(&dp, buf, sizeof(buf));
zlog_debug("Zebra: interface %s bfd destination %s down", ifp->name, buf);
}
oi = (struct ospf6_interface *) ifp->info;
if (!oi || !oi->bfd_info)
return 0;
for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
{
if (memcmp(&(on->linklocal_addr), &dp.u.prefix6, sizeof(struct in6_addr)))
continue;
if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
{
inet_ntop (AF_INET6, &on->linklocal_addr, dst, sizeof (dst));
zlog_debug ("[%s:%s]: BFD Down", ifp->name, dst);
}
THREAD_OFF (on->inactivity_timer);
thread_add_event (master, inactivity_timer, on, 0);
}
return 0;
}
/*
* ospf6_bfd_write_config - Write the interface BFD configuration.
*/
void
ospf6_bfd_write_config(struct vty *vty, struct ospf6_interface *oi)
{
struct bfd_info *bfd_info;
if (!oi->bfd_info)
return;
bfd_info = (struct bfd_info *)oi->bfd_info;
if (CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG))
vty_out (vty, " ipv6 ospf6 bfd %d %d %d%s",
bfd_info->detect_mult, bfd_info->required_min_rx,
bfd_info->desired_min_tx, VTY_NEWLINE);
else
vty_out (vty, " ipv6 ospf6 bfd%s", VTY_NEWLINE);
}
/*
* ospf6_bfd_if_param_set - Set the configured BFD paramter values for
* interface.
*/
static void
ospf6_bfd_if_param_set (struct ospf6_interface *oi, u_int32_t min_rx,
u_int32_t min_tx, u_int8_t detect_mult,
int defaults)
{
int command = 0;
bfd_set_param((struct bfd_info **)&(oi->bfd_info), min_rx, min_tx, detect_mult,
defaults, &command);
if (command)
ospf6_bfd_reg_dereg_all_nbr(oi, command);
}
DEFUN (ipv6_ospf6_bfd,
ipv6_ospf6_bfd_cmd,
"ipv6 ospf6 bfd",
IP6_STR
OSPF6_STR
"Enables BFD support\n"
)
{
struct ospf6_interface *oi;
struct interface *ifp;
ifp = (struct interface *) vty->index;
assert (ifp);
oi = (struct ospf6_interface *) ifp->info;
if (oi == NULL)
oi = ospf6_interface_create (ifp);
assert (oi);
ospf6_bfd_if_param_set (oi, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
BFD_DEF_DETECT_MULT, 1);
return CMD_SUCCESS;
}
DEFUN (ipv6_ospf6_bfd_param,
ipv6_ospf6_bfd_param_cmd,
"ipv6 ospf6 bfd " BFD_CMD_DETECT_MULT_RANGE BFD_CMD_MIN_RX_RANGE BFD_CMD_MIN_TX_RANGE,
IP6_STR
OSPF6_STR
"Enables BFD support\n"
"Detect Multiplier\n"
"Required min receive interval\n"
"Desired min transmit interval\n")
{
struct ospf6_interface *oi;
struct interface *ifp;
u_int32_t rx_val;
u_int32_t tx_val;
u_int8_t dm_val;
int ret;
ifp = (struct interface *) vty->index;
assert (ifp);
oi = (struct ospf6_interface *) ifp->info;
if (oi == NULL)
oi = ospf6_interface_create (ifp);
assert (oi);
if ((ret = bfd_validate_param (vty, argv[0], argv[1], argv[2], &dm_val,
&rx_val, &tx_val)) != CMD_SUCCESS)
return ret;
ospf6_bfd_if_param_set (oi, rx_val, tx_val, dm_val, 0);
return CMD_SUCCESS;
}
DEFUN (no_ipv6_ospf6_bfd,
no_ipv6_ospf6_bfd_cmd,
"no ipv6 ospf6 bfd",
NO_STR
IP6_STR
OSPF6_STR
"Disables BFD support\n"
)
{
struct ospf6_interface *oi;
struct interface *ifp;
ifp = (struct interface *) vty->index;
assert (ifp);
oi = (struct ospf6_interface *) ifp->info;
if (oi == NULL)
oi = ospf6_interface_create (ifp);
assert (oi);
if (oi->bfd_info)
{
ospf6_bfd_reg_dereg_all_nbr(oi, ZEBRA_BFD_DEST_DEREGISTER);
bfd_info_free(&(oi->bfd_info));
}
return CMD_SUCCESS;
}
void
ospf6_bfd_init(void)
{
/* Initialize BFD client functions */
zclient->interface_bfd_dest_down = ospf6_bfd_interface_dest_down;
zclient->bfd_dest_replay = ospf6_bfd_nbr_replay;
/* Install BFD command */
install_element (INTERFACE_NODE, &ipv6_ospf6_bfd_cmd);
install_element (INTERFACE_NODE, &ipv6_ospf6_bfd_param_cmd);
install_element (INTERFACE_NODE, &no_ipv6_ospf6_bfd_cmd);
}

36
ospf6d/ospf6_bfd.h Normal file
View File

@ -0,0 +1,36 @@
/**
* ospf6_bfd.h: OSPF6 BFD definitions and structures
*
* @copyright Copyright (C) 2015 Cumulus Networks, Inc.
*
* This file is part of GNU Zebra.
*
* GNU Zebra is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* GNU Zebra is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Zebra; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef OSPF6_BFD_H
#define OSPF6_BFD_H
extern void
ospf6_bfd_init(void);
extern void
ospf6_bfd_trigger_event(struct ospf6_neighbor *nbr, int old_state, int state);
extern void
ospf6_bfd_write_config(struct vty *vty, struct ospf6_interface *oi);
#endif /* OSPF6_BFD_H */

View File

@ -28,6 +28,7 @@
#include "thread.h"
#include "prefix.h"
#include "plist.h"
#include "bfd.h"
#include "ospf6_lsa.h"
#include "ospf6_lsdb.h"
@ -41,6 +42,7 @@
#include "ospf6_intra.h"
#include "ospf6_spf.h"
#include "ospf6d.h"
#include "ospf6_bfd.h"
unsigned char conf_debug_ospf6_interface = 0;
@ -260,6 +262,8 @@ ospf6_interface_delete (struct ospf6_interface *oi)
if (oi->plist_name)
XFREE (MTYPE_PREFIX_LIST_STR, oi->plist_name);
bfd_info_free(&(oi->bfd_info));
XFREE (MTYPE_OSPF6_IF, oi);
}
@ -1859,6 +1863,8 @@ config_write_ospf6_interface (struct vty *vty)
else if (oi->type == OSPF_IFTYPE_BROADCAST)
vty_out (vty, " ipv6 ospf6 network broadcast%s", VNL);
ospf6_bfd_write_config(vty, oi);
vty_out (vty, "!%s", VNL);
}
return 0;

View File

@ -113,6 +113,9 @@ struct ospf6_interface
/* prefix-list name to filter connected prefix */
char *plist_name;
/* BFD information */
void *bfd_info;
};
/* interface state */

View File

@ -39,6 +39,7 @@
#include "ospf6_intra.h"
#include "ospf6_flood.h"
#include "ospf6d.h"
#include "ospf6_bfd.h"
unsigned char conf_debug_ospf6_neighbor = 0;
@ -199,7 +200,7 @@ ospf6_neighbor_state_change (u_char next_state, struct ospf6_neighbor *on, int e
(next_state < prev_state))
ospf6TrapNbrStateChange (on);
#endif
ospf6_bfd_trigger_event(on, prev_state, next_state);
}
/* RFC2328 section 10.4 */

View File

@ -43,6 +43,7 @@
#include "ospf6_abr.h"
#include "ospf6_flood.h"
#include "ospf6d.h"
#include "ospf6_bfd.h"
#ifdef HAVE_SNMP
#include "ospf6_snmp.h"
@ -1780,6 +1781,7 @@ ospf6_init (void)
ospf6_snmp_init (master);
#endif /*HAVE_SNMP*/
ospf6_bfd_init();
install_node (&debug_node, config_write_ospf6_debug);
install_element_ospf6_debug_message ();

View File

@ -14,7 +14,8 @@ libospf_la_SOURCES = \
ospf_nsm.c ospf_dump.c ospf_network.c ospf_packet.c ospf_lsa.c \
ospf_spf.c ospf_route.c ospf_ase.c ospf_abr.c ospf_ia.c ospf_flood.c \
ospf_lsdb.c ospf_asbr.c ospf_routemap.c ospf_snmp.c \
ospf_opaque.c ospf_te.c ospf_vty.c ospf_api.c ospf_apiserver.c
ospf_opaque.c ospf_te.c ospf_vty.c ospf_api.c ospf_apiserver.c \
ospf_bfd.c
ospfdheaderdir = $(pkgincludedir)/ospfd
@ -25,7 +26,8 @@ ospfdheader_HEADERS = \
noinst_HEADERS = \
ospf_interface.h ospf_neighbor.h ospf_network.h ospf_packet.h \
ospf_zebra.h ospf_spf.h ospf_route.h ospf_ase.h ospf_abr.h ospf_ia.h \
ospf_flood.h ospf_snmp.h ospf_te.h ospf_vty.h ospf_apiserver.h
ospf_flood.h ospf_snmp.h ospf_te.h ospf_vty.h ospf_apiserver.h \
ospf_bfd.h
ospfd_SOURCES = ospf_main.c

352
ospfd/ospf_bfd.c Normal file
View File

@ -0,0 +1,352 @@
/**
* ospf_bfd.c: OSPF BFD handling routines
*
* @copyright Copyright (C) 2015 Cumulus Networks, Inc.
*
* This file is part of GNU Zebra.
*
* GNU Zebra is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* GNU Zebra is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Zebra; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <zebra.h>
#include "command.h"
#include "linklist.h"
#include "memory.h"
#include "prefix.h"
#include "thread.h"
#include "buffer.h"
#include "stream.h"
#include "zclient.h"
#include "vty.h"
#include "table.h"
#include "bfd.h"
#include "ospfd.h"
#include "ospf_asbr.h"
#include "ospf_lsa.h"
#include "ospf_lsdb.h"
#include "ospf_neighbor.h"
#include "ospf_interface.h"
#include "ospf_nsm.h"
#include "ospf_bfd.h"
#include "ospf_dump.h"
#include "ospf_vty.h"
extern struct zclient *zclient;
/*
* 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;
/* 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 (%s) with BFD",
bfd_get_command_dbg_str(command),
inet_ntoa (nbr->src));
bfd_peer_sendmsg (zclient, bfd_info, AF_INET,
&nbr->src, NULL, ifp->name, 0, 0, command, 0);
}
/*
* ospf_bfd_trigger_event - Neighbor is registered/deregistered with BFD when
* neighbor state is changed to/from 2way.
*/
void
ospf_bfd_trigger_event(struct ospf_neighbor *nbr, int old_state, int state)
{
if ((old_state < NSM_TwoWay) && (state >= NSM_TwoWay))
ospf_bfd_reg_dereg_nbr(nbr, ZEBRA_BFD_DEST_REGISTER);
else if ((old_state >= NSM_TwoWay) && (state < NSM_TwoWay))
ospf_bfd_reg_dereg_nbr(nbr, ZEBRA_BFD_DEST_DEREGISTER);
}
/*
* ospf_bfd_reg_dereg_all_nbr - Register/Deregister all neighbors associated
* with a interface with BFD through
* zebra for starting/stopping the monitoring of
* the neighbor rechahability.
*/
static int
ospf_bfd_reg_dereg_all_nbr (struct interface *ifp, int command)
{
struct ospf_interface *oi;
struct route_table *nbrs;
struct ospf_neighbor *nbr;
struct route_node *irn;
struct route_node *nrn;
for (irn = route_top (IF_OIFS (ifp)); irn; irn = route_next (irn))
{
if ((oi = irn->info) == NULL)
continue;
if ((nbrs = oi->nbrs) == NULL)
continue;
for (nrn = route_top (nbrs); nrn; nrn = route_next (nrn))
{
if ((nbr = nrn->info) == NULL || nbr == oi->nbr_self)
continue;
if (nbr->state < NSM_TwoWay)
continue;
ospf_bfd_reg_dereg_nbr(nbr, command);
}
}
return 0;
}
/*
* ospf_bfd_nbr_replay - Replay all the neighbors that have BFD enabled
* to zebra
*/
static int
ospf_bfd_nbr_replay (int command, struct zclient *client, zebra_size_t length)
{
struct listnode *inode, *node, *onode;
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))
{
zlog_debug("Zebra: BFD Dest replay request");
}
/* Replay the neighbor, if BFD is enabled in BGP */
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 (%s) to BFD", inet_ntoa (nbr->src));
ospf_bfd_reg_dereg_nbr(nbr, ZEBRA_BFD_DEST_UPDATE);
}
}
}
return 0;
}
/*
* ospf_bfd_interface_dest_down - Find the neighbor for which the BFD status
* has changed and bring down the neighbor
* connectivity.
*/
static int
ospf_bfd_interface_dest_down (int command, struct zclient *zclient,
zebra_size_t length)
{
struct interface *ifp;
struct ospf_interface *oi;
struct ospf_if_params *params;
struct ospf_neighbor *nbr;
struct route_node *node;
struct prefix p;
ifp = bfd_get_peer_info (zclient->ibuf, &p, NULL);
if ((ifp == NULL) || (p.family != AF_INET))
return 0;
if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
{
char buf[128];
prefix2str(&p, buf, sizeof(buf));
zlog_debug("Zebra: interface %s bfd destination %s down", ifp->name, buf);
}
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;
nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &p.u.prefix4);
if (!nbr)
continue;
if (IS_DEBUG_OSPF (nsm, NSM_EVENTS))
zlog_debug ("NSM[%s:%s]: BFD Down",
IF_NAME (nbr->oi), inet_ntoa (nbr->address.u.prefix4));
OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_InactivityTimer);
}
return 0;
}
/*
* ospf_bfd_write_config - Write the interface BFD configuration.
*/
void
ospf_bfd_write_config(struct vty *vty, struct ospf_if_params *params)
{
struct bfd_info *bfd_info;
if (!params->bfd_info)
return;
bfd_info = (struct bfd_info *)params->bfd_info;
if (CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG))
vty_out (vty, " ip ospf bfd %d %d %d%s",
bfd_info->detect_mult, bfd_info->required_min_rx,
bfd_info->desired_min_tx, VTY_NEWLINE);
else
vty_out (vty, " ip ospf bfd%s", VTY_NEWLINE);
}
/*
* ospf_bfd_if_param_set - Set the configured BFD paramter values for
* interface.
*/
static void
ospf_bfd_if_param_set (struct interface *ifp, u_int32_t min_rx,
u_int32_t min_tx, u_int8_t detect_mult, int defaults)
{
struct ospf_if_params *params;
int command = 0;
params = IF_DEF_PARAMS (ifp);
bfd_set_param(&(params->bfd_info), min_rx, min_tx, detect_mult,
defaults, &command);
if (command)
ospf_bfd_reg_dereg_all_nbr(ifp, command);
}
DEFUN (ip_ospf_bfd,
ip_ospf_bfd_cmd,
"ip ospf bfd",
"IP Information\n"
"OSPF interface commands\n"
"Enables BFD support\n")
{
struct interface *ifp = (struct interface *) vty->index;
assert (ifp);
ospf_bfd_if_param_set (ifp, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
BFD_DEF_DETECT_MULT, 1);
return CMD_SUCCESS;
}
DEFUN (ip_ospf_bfd_param,
ip_ospf_bfd_param_cmd,
"ip ospf bfd " BFD_CMD_DETECT_MULT_RANGE BFD_CMD_MIN_RX_RANGE BFD_CMD_MIN_TX_RANGE,
"IP Information\n"
"OSPF interface commands\n"
"Enables BFD support\n"
"Detect Multiplier\n"
"Required min receive interval\n"
"Desired min transmit interval\n")
{
struct interface *ifp = (struct interface *) vty->index;
u_int32_t rx_val;
u_int32_t tx_val;
u_int8_t dm_val;
int ret;
assert (ifp);
if ((ret = bfd_validate_param (vty, argv[0], argv[1], argv[2], &dm_val,
&rx_val, &tx_val)) != CMD_SUCCESS)
return ret;
ospf_bfd_if_param_set (ifp, rx_val, tx_val, dm_val, 0);
return CMD_SUCCESS;
}
DEFUN (no_ip_ospf_bfd,
no_ip_ospf_bfd_cmd,
"no ip ospf bfd",
NO_STR
"IP Information\n"
"OSPF interface commands\n"
"Disables BFD support\n")
{
struct interface *ifp = (struct interface *)vty->index;
struct ospf_if_params *params;
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;
}
void
ospf_bfd_init(void)
{
/* Initialize BFD client functions */
zclient->interface_bfd_dest_down = ospf_bfd_interface_dest_down;
zclient->bfd_dest_replay = ospf_bfd_nbr_replay;
/* Install BFD command */
install_element (INTERFACE_NODE, &ip_ospf_bfd_cmd);
install_element (INTERFACE_NODE, &ip_ospf_bfd_param_cmd);
install_element (INTERFACE_NODE, &no_ip_ospf_bfd_cmd);
}

36
ospfd/ospf_bfd.h Normal file
View File

@ -0,0 +1,36 @@
/**
* ospf_bfd.h: OSPF BFD definitions and structures
*
* @copyright Copyright (C) 2015 Cumulus Networks, Inc.
*
* This file is part of GNU Zebra.
*
* GNU Zebra is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* GNU Zebra is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Zebra; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef _ZEBRA_OSPF_BFD_H
#define _ZEBRA_OSPF_BFD_H
extern void
ospf_bfd_init(void);
extern void
ospf_bfd_write_config(struct vty *vty, struct ospf_if_params *params);
extern void
ospf_bfd_trigger_event(struct ospf_neighbor *nbr, int old_state, int state);
#endif /* _ZEBRA_OSPF_BFD_H */

View File

@ -31,6 +31,7 @@
#include "command.h"
#include "stream.h"
#include "log.h"
#include "bfd.h"
#include "ospfd/ospfd.h"
#include "ospfd/ospf_spf.h"
@ -560,6 +561,7 @@ void
ospf_del_if_params (struct ospf_if_params *oip)
{
list_delete (oip->auth_crypt);
bfd_info_free(&(oip->bfd_info));
XFREE (MTYPE_OSPF_IF_PARAMS, oip);
}

View File

@ -45,7 +45,6 @@ struct ospf_if_params
DECLARE_IF_PARAM (u_int32_t, transmit_delay); /* Interface Transmisson Delay */
DECLARE_IF_PARAM (u_int32_t, output_cost_cmd);/* Command Interface Output Cost */
DECLARE_IF_PARAM (u_int32_t, retransmit_interval); /* Retransmission Interval */
DECLARE_IF_PARAM (u_char, bfd); /* Respond to BFD events */
DECLARE_IF_PARAM (u_char, passive_interface); /* OSPF Interface is passive: no sending or receiving (no need to join multicast groups) */
DECLARE_IF_PARAM (u_char, priority); /* OSPF Interface priority */
/* Enable OSPF on this interface with area if_area */
@ -79,6 +78,9 @@ struct ospf_if_params
/* Other, non-configuration state */
u_int32_t network_lsa_seqnum; /* Network LSA seqnum */
/* BFD configuration */
void *bfd_info;
};
enum

View File

@ -49,6 +49,7 @@
#include "ospfd/ospf_dump.h"
#include "ospfd/ospf_zebra.h"
#include "ospfd/ospf_vty.h"
#include "ospfd/ospf_bfd.h"
/* ospfd privileges */
zebra_capabilities_t _caps_p [] =
@ -312,6 +313,9 @@ main (int argc, char **argv)
ospf_vty_show_init ();
ospf_vty_clear_init ();
/* OSPF BFD init */
ospf_bfd_init();
ospf_route_map_init ();
#ifdef HAVE_SNMP
ospf_snmp_init ();

View File

@ -48,6 +48,7 @@
#include "ospfd/ospf_flood.h"
#include "ospfd/ospf_abr.h"
#include "ospfd/ospf_snmp.h"
#include "ospfd/ospf_bfd.h"
static void nsm_clear_adj (struct ospf_neighbor *);
@ -811,6 +812,8 @@ nsm_change_state (struct ospf_neighbor *nbr, int state)
if (state == NSM_Down)
nbr->crypt_seqnum = 0;
ospf_bfd_trigger_event(nbr, old_state, state);
/* Preserve old status? */
}

View File

@ -50,6 +50,7 @@
/*#include "ospfd/ospf_routemap.h" */
#include "ospfd/ospf_vty.h"
#include "ospfd/ospf_dump.h"
#include "ospfd/ospf_bfd.h"
#define QUAGGA_REDIST_STR_OSPFD \
"(kernel|connected|static|rip|isis|bgp|babel)"
@ -7072,39 +7073,6 @@ ALIAS (no_ip_ospf_priority,
"OSPF interface commands\n"
"Router priority\n")
DEFUN (ip_ospf_bfd,
ip_ospf_bfd_cmd,
"ip ospf bfd",
"IP Information\n"
"OSPF interface commands\n"
"Respond to BFD session event\n")
{
struct interface *ifp = vty->index;
struct ospf_if_params *params;
params = IF_DEF_PARAMS (ifp);
SET_IF_PARAM (params, bfd);
return CMD_SUCCESS;
}
DEFUN (no_ip_ospf_bfd,
no_ip_ospf_bfd_cmd,
"no ip ospf bfd",
NO_STR
"IP Information\n"
"OSPF interface commands\n"
"Respond to BFD session event\n")
{
struct interface *ifp = vty->index;
struct ospf_if_params *params;
params = IF_DEF_PARAMS (ifp);
UNSET_IF_PARAM (params, bfd);
return CMD_SUCCESS;
}
DEFUN (ip_ospf_retransmit_interval,
ip_ospf_retransmit_interval_addr_cmd,
@ -8795,8 +8763,7 @@ config_write_interface (struct vty *vty)
}
/* bfd print. */
if (OSPF_IF_PARAM_CONFIGURED (params, bfd))
vty_out (vty, " ip ospf bfd%s", VTY_NEWLINE);
ospf_bfd_write_config(vty, params);
/* MTU ignore print. */
if (OSPF_IF_PARAM_CONFIGURED (params, mtu_ignore) &&
@ -9544,8 +9511,6 @@ ospf_vty_if_init (void)
install_element (INTERFACE_NODE, &no_ospf_retransmit_interval_cmd);
install_element (INTERFACE_NODE, &ospf_transmit_delay_cmd);
install_element (INTERFACE_NODE, &no_ospf_transmit_delay_cmd);
install_element (INTERFACE_NODE, &ip_ospf_bfd_cmd);
install_element (INTERFACE_NODE, &no_ip_ospf_bfd_cmd);
}
static void

View File

@ -327,52 +327,6 @@ ospf_interface_address_delete (int command, struct zclient *zclient,
return 0;
}
static int
ospf_interface_bfd_dest_down (int command, struct zclient *zclient,
zebra_size_t length)
{
struct interface *ifp;
struct ospf_interface *oi;
struct ospf_if_params *params;
struct ospf_neighbor *nbr;
struct route_node *node;
struct prefix p;
ifp = zebra_interface_bfd_read (zclient->ibuf, &p, NULL);
if (ifp == NULL)
return 0;
if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
{
char buf[128];
prefix2str(&p, buf, sizeof(buf));
zlog_debug("Zebra: interface %s bfd destination %s down", ifp->name, buf);
}
params = IF_DEF_PARAMS (ifp);
if (!OSPF_IF_PARAM_CONFIGURED (params, bfd))
return 0;
for (node = route_top (IF_OIFS (ifp)); node; node = route_next (node))
{
if ((oi = node->info) == NULL)
continue;
nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &p.u.prefix4);
if (!nbr)
continue;
if (IS_DEBUG_OSPF (nsm, NSM_EVENTS))
zlog_debug ("NSM[%s:%s]: BFD Down",
IF_NAME (nbr->oi), inet_ntoa (nbr->address.u.prefix4));
OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_InactivityTimer);
}
return 0;
}
void
ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or)
{
@ -1590,7 +1544,6 @@ ospf_zebra_init (u_short instance)
zclient->interface_down = ospf_interface_state_down;
zclient->interface_address_add = ospf_interface_address_add;
zclient->interface_address_delete = ospf_interface_address_delete;
zclient->interface_bfd_dest_down = ospf_interface_bfd_dest_down;
zclient->ipv4_route_add = ospf_zebra_read_ipv4;
zclient->ipv4_route_delete = ospf_zebra_read_ipv4;

View File

@ -303,8 +303,6 @@ zebra_ptm_handle_bfd_msg(void *arg, void *in_ctxt)
ptm_lib_find_key_in_msg(in_ctxt, ZEBRA_PTM_BFDSTATUS_STR, bfdst_str);
if (bfdst_str[0] == '\0') {
zlog_debug("%s: Key %s not found in PTM msg", __func__,
ZEBRA_PTM_BFDSTATUS_STR);
return -1;
}

View File

@ -78,7 +78,8 @@ zebra_interface_bfd_update (struct interface *ifp, struct prefix *dp,
for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
{
/* Supporting for OSPF and BGP */
if (client->proto != ZEBRA_ROUTE_OSPF && client->proto != ZEBRA_ROUTE_BGP)
if (client->proto != ZEBRA_ROUTE_OSPF && client->proto != ZEBRA_ROUTE_BGP
&& client->proto != ZEBRA_ROUTE_OSPF6)
continue;
/* Notify to the protocol daemons. */
@ -113,7 +114,9 @@ zebra_bfd_peer_replay_req (void)
for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
{
/* Supporting for BGP */
if (client->proto != ZEBRA_ROUTE_BGP)
if ((client->proto != ZEBRA_ROUTE_BGP) &&
(client->proto != ZEBRA_ROUTE_OSPF) &&
(client->proto != ZEBRA_ROUTE_OSPF6))
continue;
/* Notify to the protocol daemons. */