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>
#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.
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;
+
+ 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 bgp_bfd_peer_info *)peer->bfd_info;
- conf_bfd_info = (struct bgp_bfd_peer_info *)conf->bfd_info;
+ bfd_info = (struct bfd_info *)peer->bfd_info;
/* Copy BFD parameter values */
bfd_info->required_min_rx = conf_bfd_info->required_min_rx;
}
/*
- * 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;
-
- bfd_info = (struct bgp_bfd_peer_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;
+ struct bfd_info *bfd_info;
+
+ bfd_info = (struct bfd_info *)peer->bfd_info;
+
+ 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);
}
/*
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);
}
/**
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;
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);
}
* 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)
{
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))
{
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))
/*
* 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;
-
- 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;
+ int command = 0;
- 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;
/*
* 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;
}
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;
+
+ bfd_info = (struct bfd_info *)peer->bfd_info;
- if (CHECK_FLAG (bfd_info->flags, BGP_BFD_FLAG_PARAM_CFG))
+ 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);
void
bgp_bfd_show_info(struct vty *vty, struct peer *peer)
{
- struct bgp_bfd_peer_info *bfd_info;
+ struct bfd_info *bfd_info;
+
+ if (!peer->bfd_info)
+ return;
- bfd_info = (struct bgp_bfd_peer_info *)peer->bfd_info;
+ bfd_info = (struct bfd_info *)peer->bfd_info;
- 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);
- }
+ 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,
{
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);
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"
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);
-
- 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);
+ if ((ret = bfd_validate_param (vty, argv[1], argv[2], argv[3], &dm_val,
+ &rx_val, &tx_val)) != CMD_SUCCESS)
+ return ret;
- 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);
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;
}
#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);
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);
#include "linklist.h"
#include "workqueue.h"
#include "queue.h"
+#include "bfd.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
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);
}
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));
}
}
- bgp_bfd_peer_init(peer);
-
/* Set up peer's events and timers. */
if (! active && peer_active (peer))
bgp_timer_set (peer);
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;
}
/* 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);
}
return 0;
}
+ bgp_bfd_deregister_peer(peer);
peer_global_config_reset (peer);
}
{ 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 }
};
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);
}
#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];
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
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 \
--- /dev/null
+/**
+ * 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;
+}
--- /dev/null
+/**
+ * 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 */
{ MTYPE_PQUEUE, "Priority queue" },
{ MTYPE_PQUEUE_DATA, "Priority queue data" },
{ MTYPE_HOST, "Host config" },
+ { MTYPE_BFD_INFO, "BFD info" },
{ -1, NULL },
};
{ 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 }
};
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)
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);
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)
--- /dev/null
+/**
+ * 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);
+}
--- /dev/null
+/**
+ * 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 */
#include "thread.h"
#include "prefix.h"
#include "plist.h"
+#include "bfd.h"
#include "ospf6_lsa.h"
#include "ospf6_lsdb.h"
#include "ospf6_intra.h"
#include "ospf6_spf.h"
#include "ospf6d.h"
+#include "ospf6_bfd.h"
unsigned char conf_debug_ospf6_interface = 0;
if (oi->plist_name)
XFREE (MTYPE_PREFIX_LIST_STR, oi->plist_name);
+ bfd_info_free(&(oi->bfd_info));
+
XFREE (MTYPE_OSPF6_IF, oi);
}
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;
/* prefix-list name to filter connected prefix */
char *plist_name;
+
+ /* BFD information */
+ void *bfd_info;
};
/* interface state */
#include "ospf6_intra.h"
#include "ospf6_flood.h"
#include "ospf6d.h"
+#include "ospf6_bfd.h"
unsigned char conf_debug_ospf6_neighbor = 0;
(next_state < prev_state))
ospf6TrapNbrStateChange (on);
#endif
-
+ ospf6_bfd_trigger_event(on, prev_state, next_state);
}
/* RFC2328 section 10.4 */
#include "ospf6_abr.h"
#include "ospf6_flood.h"
#include "ospf6d.h"
+#include "ospf6_bfd.h"
#ifdef HAVE_SNMP
#include "ospf6_snmp.h"
ospf6_snmp_init (master);
#endif /*HAVE_SNMP*/
+ ospf6_bfd_init();
install_node (&debug_node, config_write_ospf6_debug);
install_element_ospf6_debug_message ();
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
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
--- /dev/null
+/**
+ * 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);
+}
--- /dev/null
+/**
+ * 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 */
#include "command.h"
#include "stream.h"
#include "log.h"
+#include "bfd.h"
#include "ospfd/ospfd.h"
#include "ospfd/ospf_spf.h"
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);
}
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 */
/* Other, non-configuration state */
u_int32_t network_lsa_seqnum; /* Network LSA seqnum */
+
+ /* BFD configuration */
+ void *bfd_info;
};
enum
#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 [] =
ospf_vty_show_init ();
ospf_vty_clear_init ();
+ /* OSPF BFD init */
+ ospf_bfd_init();
+
ospf_route_map_init ();
#ifdef HAVE_SNMP
ospf_snmp_init ();
#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 *);
if (state == NSM_Down)
nbr->crypt_seqnum = 0;
+ ospf_bfd_trigger_event(nbr, old_state, state);
+
/* Preserve old status? */
}
/*#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)"
"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,
}
/* 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) &&
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
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)
{
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;
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;
}
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. */
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. */