summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_bfd.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_bfd.c')
-rw-r--r--bgpd/bgp_bfd.c354
1 files changed, 103 insertions, 251 deletions
diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c
index 02047f7f0..87feebe8a 100644
--- a/bgpd/bgp_bfd.c
+++ b/bgpd/bgp_bfd.c
@@ -32,8 +32,9 @@
#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"
@@ -41,46 +42,23 @@
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;
@@ -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;
-
- 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);
}
/*
@@ -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;
-
- 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;
@@ -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;
+
+ 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);
@@ -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;
+
+ 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,
@@ -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);
-
- 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);
@@ -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;
}