mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-03 02:22:48 +00:00
Support of BFD status in Quagga
Ticket:CM-6802, CM-6952 Reviewed By: Donald, Kanna Testing Done: Double commit of b76943235e09472ec174edcf7204fc82d27fe966 from br2.5. But, manually resolved all the compilation errors. Also, modified the shows to support the json format which was not supported in br2.5. CM-6802 – Currently, BFD session status can be monitored only through ptmctl. There is no way to check the BFD status of a peer/neighbor through Quagga. Debugging becomes easier if BFD status is shown in Quagga too. BFD status is relevant when it is shown against the BGP peer/OSPF neighbor. For, this following code changes have been done: - Only down messages from PTM were being propagated from Zebra daemon to clients (bgpd, ospfd and ospf6d). Now, both up and down messages are redistributed to the clients from zebra. BFD status field has been added to the messaging. Handling of BFD session up messages has been added to the client code. BGP/OSPF neighbor is brought down only if the old BFD session status is ‘Up’ to handle extra/initial down messages. - BFD status and last update timestamp fields have been added to the common BFD info structure. Also, common show functions for showing BFD information have been added to BFD lib. - Modified the BGP neighbor show functions to call common BFD lib functions. - For ospf and ospf6, BFD information was maintained only at interface level. To show BFD status per neighbor, BFD information has been added at neighbor level too. “show ip ospf interface”, “show ip ospf neighbor detail”, “show ipv6 ospf6 interface” and “show ipv6 ospf6 neighbor detail” output have been modified to show BFD information. CM-6952 - IBGP peers were always assumed to be multi-hop since there was no easy way to determine whether an IBGP peer was single hop or multihop unlike EBGP. But, this is causing problem with IBGP link local peers since BFD doesn't allow multihop BFD session with link local IP addresses. Link local peers were discovered when the interface peering was enabled. Interface peering is always singlehop. So, added checks to treat all interface based peers as single hop irrespective of whether the peer is IBGP or EBGP.
This commit is contained in:
parent
89ca90fad9
commit
68fe91d6c7
@ -73,7 +73,8 @@ bgp_bfd_peer_group2peer_copy(struct peer *conf, struct peer *peer)
|
||||
static int
|
||||
bgp_bfd_is_peer_multihop(struct peer *peer)
|
||||
{
|
||||
if((peer->sort == BGP_PEER_IBGP) || is_ebgp_multihop_configured(peer))
|
||||
if((peer->conf_if == NULL) && ((peer->sort == BGP_PEER_IBGP) ||
|
||||
is_ebgp_multihop_configured(peer)))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
@ -191,19 +192,46 @@ bgp_bfd_dest_replay (int command, struct zclient *client, zebra_size_t length)
|
||||
}
|
||||
|
||||
/*
|
||||
* bgp_interface_bfd_dest_down - Find the peer for which the BFD status
|
||||
* has changed and bring down the peer
|
||||
* connectivity.
|
||||
* bgp_bfd_peer_status_update - Update the BFD status if it has changed. Bring
|
||||
* down the peer if the BFD session went down from * up.
|
||||
*/
|
||||
static void
|
||||
bgp_bfd_peer_status_update (struct peer *peer, int status)
|
||||
{
|
||||
struct bfd_info *bfd_info;
|
||||
int old_status;
|
||||
|
||||
bfd_info = (struct bfd_info *)peer->bfd_info;
|
||||
|
||||
if (bfd_info->status == status)
|
||||
return;
|
||||
|
||||
old_status = bfd_info->status;
|
||||
bfd_info->status = status;
|
||||
bfd_info->last_update = bgp_clock();
|
||||
|
||||
if ((status == BFD_STATUS_DOWN) && (old_status == BFD_STATUS_UP))
|
||||
{
|
||||
peer->last_reset = PEER_DOWN_BFD_DOWN;
|
||||
BGP_EVENT_ADD (peer, BGP_Stop);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* bgp_bfd_dest_update - Find the peer for which the BFD status
|
||||
* has changed and bring down the peer
|
||||
* connectivity if the BFD session went down.
|
||||
*/
|
||||
static int
|
||||
bgp_interface_bfd_dest_down (int command, struct zclient *zclient,
|
||||
bgp_bfd_dest_update (int command, struct zclient *zclient,
|
||||
zebra_size_t length)
|
||||
{
|
||||
struct interface *ifp;
|
||||
struct prefix dp;
|
||||
struct prefix sp;
|
||||
int status;
|
||||
|
||||
ifp = bfd_get_peer_info (zclient->ibuf, &dp, &sp);
|
||||
ifp = bfd_get_peer_info (zclient->ibuf, &dp, &sp, &status);
|
||||
|
||||
if (BGP_DEBUG (zebra, ZEBRA))
|
||||
{
|
||||
@ -211,14 +239,14 @@ bgp_interface_bfd_dest_down (int command, struct zclient *zclient,
|
||||
prefix2str(&dp, buf[0], sizeof(buf[0]));
|
||||
if (ifp)
|
||||
{
|
||||
zlog_debug("Zebra: interface %s bfd destination %s down",
|
||||
ifp->name, buf[0]);
|
||||
zlog_debug("Zebra: interface %s bfd destination %s %s",
|
||||
ifp->name, buf[0], bfd_get_status_str(status));
|
||||
}
|
||||
else
|
||||
{
|
||||
prefix2str(&sp, buf[1], sizeof(buf[1]));
|
||||
zlog_debug("Zebra: source %s bfd destination %s down",
|
||||
buf[1], buf[0]);
|
||||
zlog_debug("Zebra: source %s bfd destination %s %s",
|
||||
buf[1], buf[0], bfd_get_status_str(status));
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,8 +281,7 @@ bgp_interface_bfd_dest_down (int command, struct zclient *zclient,
|
||||
|
||||
if (ifp && (ifp == peer->nexthop.ifp))
|
||||
{
|
||||
peer->last_reset = PEER_DOWN_BFD_DOWN;
|
||||
BGP_EVENT_ADD (peer, BGP_Stop);
|
||||
bgp_bfd_peer_status_update(peer, status);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -279,8 +306,7 @@ bgp_interface_bfd_dest_down (int command, struct zclient *zclient,
|
||||
else
|
||||
continue;
|
||||
|
||||
peer->last_reset = PEER_DOWN_BFD_DOWN;
|
||||
BGP_EVENT_ADD (peer, BGP_Stop);
|
||||
bgp_bfd_peer_status_update(peer, status);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -299,8 +325,8 @@ bgp_bfd_peer_param_set (struct peer *peer, u_int32_t min_rx, u_int32_t min_tx,
|
||||
struct listnode *node, *nnode;
|
||||
int command = 0;
|
||||
|
||||
bfd_set_param(&(peer->bfd_info), min_rx, min_tx, detect_mult,
|
||||
defaults, &command);
|
||||
bfd_set_param((struct bfd_info **)&(peer->bfd_info), min_rx, min_tx,
|
||||
detect_mult, defaults, &command);
|
||||
|
||||
if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
|
||||
{
|
||||
@ -308,8 +334,8 @@ bgp_bfd_peer_param_set (struct peer *peer, u_int32_t min_rx, u_int32_t min_tx,
|
||||
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
|
||||
{
|
||||
command = 0;
|
||||
bfd_set_param(&(peer->bfd_info), min_rx, min_tx, detect_mult,
|
||||
defaults, &command);
|
||||
bfd_set_param((struct bfd_info **)&(peer->bfd_info), min_rx, min_tx,
|
||||
detect_mult, defaults, &command);
|
||||
|
||||
if ((peer->status == Established) &&
|
||||
(command == ZEBRA_BFD_DEST_REGISTER))
|
||||
@ -386,38 +412,8 @@ bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr)
|
||||
void
|
||||
bgp_bfd_show_info(struct vty *vty, struct peer *peer, u_char use_json, json_object *json_neigh)
|
||||
{
|
||||
struct bfd_info *bfd_info;
|
||||
json_object *json_bfd = NULL;
|
||||
|
||||
if (!peer->bfd_info)
|
||||
return;
|
||||
|
||||
if (use_json)
|
||||
json_bfd = json_object_new_object();
|
||||
|
||||
bfd_info = (struct bfd_info *)peer->bfd_info;
|
||||
|
||||
if (use_json)
|
||||
{
|
||||
if (bgp_bfd_is_peer_multihop(peer))
|
||||
json_object_string_add(json_bfd, "bfdMultiHop", "yes");
|
||||
else
|
||||
json_object_string_add(json_bfd, "bfdMultiHop", "no");
|
||||
json_object_int_add(json_bfd, "detectMultiplier", bfd_info->detect_mult);
|
||||
json_object_int_add(json_bfd, "rxMinInterval", bfd_info->required_min_rx);
|
||||
json_object_int_add(json_bfd, "txMinInterval", bfd_info->desired_min_tx);
|
||||
json_object_object_add(json_neigh, "peerBfdInfo", json_bfd);
|
||||
}
|
||||
else
|
||||
{
|
||||
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_show_info(vty, (struct bfd_info *)peer->bfd_info,
|
||||
bgp_bfd_is_peer_multihop(peer), 0, use_json, json_neigh);
|
||||
}
|
||||
|
||||
DEFUN (neighbor_bfd,
|
||||
@ -501,7 +497,7 @@ void
|
||||
bgp_bfd_init(void)
|
||||
{
|
||||
/* Initialize BFD client functions */
|
||||
zclient->interface_bfd_dest_down = bgp_interface_bfd_dest_down;
|
||||
zclient->interface_bfd_dest_update = bgp_bfd_dest_update;
|
||||
zclient->bfd_dest_replay = bgp_bfd_dest_replay;
|
||||
|
||||
/* "neighbor bfd" commands. */
|
||||
|
152
lib/bfd.c
152
lib/bfd.c
@ -44,6 +44,8 @@ bfd_info_create(void)
|
||||
bfd_info = XCALLOC (MTYPE_BFD_INFO, sizeof (struct bfd_info));
|
||||
assert(bfd_info);
|
||||
|
||||
bfd_info->status = BFD_STATUS_UNKNOWN;
|
||||
bfd_info->last_update = 0;
|
||||
return bfd_info;
|
||||
}
|
||||
|
||||
@ -247,7 +249,8 @@ bfd_get_command_dbg_str(int command)
|
||||
* 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)
|
||||
bfd_get_peer_info (struct stream *s, struct prefix *dp, struct prefix *sp,
|
||||
int *status)
|
||||
{
|
||||
unsigned int ifindex;
|
||||
struct interface *ifp = NULL;
|
||||
@ -275,6 +278,9 @@ bfd_get_peer_info (struct stream *s, struct prefix *dp, struct prefix *sp)
|
||||
stream_get (&dp->u.prefix, s, plen);
|
||||
dp->prefixlen = stream_getc (s);
|
||||
|
||||
/* Get BFD status. */
|
||||
*status = stream_getl (s);
|
||||
|
||||
if (sp)
|
||||
{
|
||||
sp->family = stream_getc (s);
|
||||
@ -285,3 +291,147 @@ bfd_get_peer_info (struct stream *s, struct prefix *dp, struct prefix *sp)
|
||||
}
|
||||
return ifp;
|
||||
}
|
||||
|
||||
/*
|
||||
* bfd_get_status_str - Convert BFD status to a display string.
|
||||
*/
|
||||
const char *
|
||||
bfd_get_status_str(int status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case BFD_STATUS_DOWN:
|
||||
return "Down";
|
||||
case BFD_STATUS_UP:
|
||||
return "Up";
|
||||
case BFD_STATUS_UNKNOWN:
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* bfd_last_update - Calculate the last BFD update time and convert it
|
||||
* into a dd:hh:mm:ss display format.
|
||||
*/
|
||||
static void
|
||||
bfd_last_update (time_t last_update, char *buf, size_t len)
|
||||
{
|
||||
time_t curr;
|
||||
time_t diff;
|
||||
struct tm *tm;
|
||||
struct timeval tv;
|
||||
|
||||
/* If no BFD satatus update has ever been received, print `never'. */
|
||||
if (last_update == 0)
|
||||
{
|
||||
snprintf (buf, len, "never");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get current time. */
|
||||
quagga_gettime(QUAGGA_CLK_MONOTONIC, &tv);
|
||||
curr = tv.tv_sec;
|
||||
diff = curr - last_update;
|
||||
tm = gmtime (&diff);
|
||||
|
||||
snprintf (buf, len, "%d:%02d:%02d:%02d",
|
||||
tm->tm_yday, tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
}
|
||||
|
||||
/*
|
||||
* bfd_show_param - Show the BFD parameter information.
|
||||
*/
|
||||
void
|
||||
bfd_show_param(struct vty *vty, struct bfd_info *bfd_info, int bfd_tag,
|
||||
int extra_space, u_char use_json, json_object *json_obj)
|
||||
{
|
||||
json_object *json_bfd = NULL;
|
||||
|
||||
if (!bfd_info)
|
||||
return;
|
||||
|
||||
if (use_json)
|
||||
{
|
||||
if (bfd_tag)
|
||||
json_bfd = json_object_new_object();
|
||||
else
|
||||
json_bfd = json_obj;
|
||||
|
||||
json_object_int_add(json_bfd, "detectMultiplier", bfd_info->detect_mult);
|
||||
json_object_int_add(json_bfd, "rxMinInterval", bfd_info->required_min_rx);
|
||||
json_object_int_add(json_bfd, "txMinInterval", bfd_info->desired_min_tx);
|
||||
if (bfd_tag)
|
||||
json_object_object_add(json_obj, "peerBfdInfo", json_bfd);
|
||||
}
|
||||
else
|
||||
{
|
||||
vty_out (vty, " %s%sDetect Mul: %d, Min Rx interval: %d,"
|
||||
" Min Tx interval: %d%s",
|
||||
(extra_space) ? " ": "", (bfd_tag) ? "BFD: " : " ",
|
||||
bfd_info->detect_mult, bfd_info->required_min_rx,
|
||||
bfd_info->desired_min_tx, VTY_NEWLINE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* bfd_show_status - Show the BFD status information.
|
||||
*/
|
||||
static void
|
||||
bfd_show_status(struct vty *vty, struct bfd_info *bfd_info, int bfd_tag,
|
||||
int extra_space, u_char use_json, json_object *json_bfd)
|
||||
{
|
||||
char time_buf[32];
|
||||
|
||||
if (!bfd_info)
|
||||
return;
|
||||
|
||||
bfd_last_update(bfd_info->last_update, time_buf, 32);
|
||||
if (use_json)
|
||||
{
|
||||
json_object_string_add(json_bfd, "status",
|
||||
bfd_get_status_str(bfd_info->status));
|
||||
json_object_string_add(json_bfd, "lastUpdate", time_buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
vty_out (vty, " %s%sStatus: %s, Last update: %s%s",
|
||||
(extra_space) ? " ": "", (bfd_tag) ? "BFD: " : " ",
|
||||
bfd_get_status_str(bfd_info->status), time_buf, VTY_NEWLINE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* bfd_show_info - Show the BFD information.
|
||||
*/
|
||||
void
|
||||
bfd_show_info(struct vty *vty, struct bfd_info *bfd_info, int multihop,
|
||||
int extra_space, u_char use_json, json_object *json_obj)
|
||||
{
|
||||
json_object *json_bfd = NULL;
|
||||
|
||||
if (!bfd_info)
|
||||
return;
|
||||
|
||||
if (use_json)
|
||||
{
|
||||
json_bfd = json_object_new_object();
|
||||
if (multihop)
|
||||
json_object_string_add(json_bfd, "type", "multi hop");
|
||||
else
|
||||
json_object_string_add(json_bfd, "type", "single hop");
|
||||
}
|
||||
else
|
||||
{
|
||||
vty_out (vty, " %sBFD: Type: %s%s", (extra_space) ? " " : "",
|
||||
(multihop) ? "multi hop" : "single hop", VTY_NEWLINE);
|
||||
}
|
||||
|
||||
bfd_show_param(vty, bfd_info, 0, extra_space, use_json, json_bfd);
|
||||
bfd_show_status(vty, bfd_info, 0, extra_space, use_json, json_bfd);
|
||||
|
||||
if (use_json)
|
||||
json_object_object_add(json_obj, "peerBfdInfo", json_bfd);
|
||||
else
|
||||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
}
|
||||
|
22
lib/bfd.h
22
lib/bfd.h
@ -24,6 +24,8 @@
|
||||
#ifndef _ZEBRA_BFD_H
|
||||
#define _ZEBRA_BFD_H
|
||||
|
||||
#include "lib/json.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>"
|
||||
@ -41,12 +43,18 @@
|
||||
#define BFD_FLAG_PARAM_CFG (1 << 0) /* parameters have been configured */
|
||||
#define BFD_FLAG_BFD_REG (1 << 1) /* Peer registered with BFD */
|
||||
|
||||
#define BFD_STATUS_UNKNOWN (1 << 0) /* BFD session status never received */
|
||||
#define BFD_STATUS_DOWN (1 << 1) /* BFD session status is down */
|
||||
#define BFD_STATUS_UP (1 << 2) /* BFD session status is up */
|
||||
|
||||
struct bfd_info
|
||||
{
|
||||
u_int16_t flags;
|
||||
u_int8_t detect_mult;
|
||||
u_int32_t desired_min_tx;
|
||||
u_int32_t required_min_rx;
|
||||
time_t last_update;
|
||||
u_int8_t status;
|
||||
};
|
||||
|
||||
extern struct bfd_info *
|
||||
@ -72,6 +80,18 @@ 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);
|
||||
bfd_get_peer_info (struct stream *s, struct prefix *dp, struct prefix *sp,
|
||||
int *status);
|
||||
|
||||
const char *
|
||||
bfd_get_status_str(int status);
|
||||
|
||||
extern void
|
||||
bfd_show_param(struct vty *vty, struct bfd_info *bfd_info, int bfd_tag,
|
||||
int extra_space, u_char use_json, json_object *json_obj);
|
||||
|
||||
extern void
|
||||
bfd_show_info(struct vty *vty, struct bfd_info *bfd_info, int multihop,
|
||||
int extra_space, u_char use_json, json_object *json_obj);
|
||||
|
||||
#endif /* _ZEBRA_BFD_H */
|
||||
|
@ -836,7 +836,7 @@ static const struct zebra_desc_table command_types[] = {
|
||||
DESC_ENTRY (ZEBRA_INTERFACE_NBR_ADDRESS_ADD),
|
||||
DESC_ENTRY (ZEBRA_INTERFACE_NBR_ADDRESS_DELETE),
|
||||
DESC_ENTRY (ZEBRA_IMPORT_CHECK_UPDATE),
|
||||
DESC_ENTRY (ZEBRA_INTERFACE_BFD_DEST_DOWN),
|
||||
DESC_ENTRY (ZEBRA_INTERFACE_BFD_DEST_UPDATE),
|
||||
DESC_ENTRY (ZEBRA_BFD_DEST_REGISTER),
|
||||
DESC_ENTRY (ZEBRA_BFD_DEST_DEREGISTER),
|
||||
DESC_ENTRY (ZEBRA_BFD_DEST_UPDATE),
|
||||
|
@ -1208,9 +1208,9 @@ zclient_read (struct thread *thread)
|
||||
if (zclient->interface_address_delete)
|
||||
(*zclient->interface_address_delete) (command, zclient, length);
|
||||
break;
|
||||
case ZEBRA_INTERFACE_BFD_DEST_DOWN:
|
||||
if (zclient->interface_bfd_dest_down)
|
||||
(*zclient->interface_bfd_dest_down) (command, zclient, length);
|
||||
case ZEBRA_INTERFACE_BFD_DEST_UPDATE:
|
||||
if (zclient->interface_bfd_dest_update)
|
||||
(*zclient->interface_bfd_dest_update) (command, zclient, length);
|
||||
break;
|
||||
case ZEBRA_INTERFACE_NBR_ADDRESS_ADD:
|
||||
if (zclient->interface_nbr_address_add)
|
||||
|
@ -85,7 +85,7 @@ struct zclient
|
||||
int (*interface_down) (int, struct zclient *, uint16_t);
|
||||
int (*interface_address_add) (int, struct zclient *, uint16_t);
|
||||
int (*interface_address_delete) (int, struct zclient *, uint16_t);
|
||||
int (*interface_bfd_dest_down) (int, struct zclient *, uint16_t);
|
||||
int (*interface_bfd_dest_update) (int, struct zclient *, uint16_t);
|
||||
int (*interface_nbr_address_add) (int, struct zclient *, uint16_t);
|
||||
int (*interface_nbr_address_delete) (int, struct zclient *, uint16_t);
|
||||
int (*ipv4_route_add) (int, struct zclient *, uint16_t);
|
||||
|
@ -429,7 +429,7 @@ struct in_pktinfo
|
||||
#define ZEBRA_NEXTHOP_UPDATE 26
|
||||
#define ZEBRA_INTERFACE_NBR_ADDRESS_ADD 27
|
||||
#define ZEBRA_INTERFACE_NBR_ADDRESS_DELETE 28
|
||||
#define ZEBRA_INTERFACE_BFD_DEST_DOWN 29
|
||||
#define ZEBRA_INTERFACE_BFD_DEST_UPDATE 29
|
||||
#define ZEBRA_IMPORT_ROUTE_REGISTER 30
|
||||
#define ZEBRA_IMPORT_ROUTE_UNREGISTER 31
|
||||
#define ZEBRA_IMPORT_CHECK_UPDATE 32
|
||||
|
@ -45,6 +45,27 @@
|
||||
|
||||
extern struct zclient *zclient;
|
||||
|
||||
/*
|
||||
* ospf6_bfd_info_free - Free BFD info structure
|
||||
*/
|
||||
void
|
||||
ospf6_bfd_info_free(void **bfd_info)
|
||||
{
|
||||
bfd_info_free((struct bfd_info **) bfd_info);
|
||||
}
|
||||
|
||||
/*
|
||||
* ospf6_bfd_show_info - Show BFD info structure
|
||||
*/
|
||||
void
|
||||
ospf6_bfd_show_info(struct vty *vty, void *bfd_info, int param_only)
|
||||
{
|
||||
if (param_only)
|
||||
bfd_show_param(vty, bfd_info, 1, 0, 0, NULL);
|
||||
else
|
||||
bfd_show_info(vty, bfd_info, 0, 1, 0, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* ospf6_bfd_reg_dereg_nbr - Register/Deregister a neighbor with BFD through
|
||||
* zebra for starting/stopping the monitoring of
|
||||
@ -102,6 +123,11 @@ ospf6_bfd_reg_dereg_all_nbr (struct ospf6_interface *oi, int command)
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, node, on))
|
||||
{
|
||||
if (command != ZEBRA_BFD_DEST_DEREGISTER)
|
||||
ospf6_bfd_info_nbr_create(oi, on);
|
||||
else
|
||||
bfd_info_free((struct bfd_info **)&on->bfd_info);
|
||||
|
||||
if (on->state < OSPF6_NEIGHBOR_TWOWAY)
|
||||
continue;
|
||||
|
||||
@ -151,13 +177,13 @@ ospf6_bfd_nbr_replay (int command, struct zclient *client, zebra_size_t length)
|
||||
}
|
||||
|
||||
/*
|
||||
* ospf6_bfd_interface_dest_down - Find the neighbor for which the BFD status
|
||||
* has changed and bring down the neighbor
|
||||
* connectivity.
|
||||
* ospf6_bfd_interface_dest_update - Find the neighbor for which the BFD status
|
||||
* has changed and bring down the neighbor
|
||||
* connectivity if BFD down is received.
|
||||
*/
|
||||
static int
|
||||
ospf6_bfd_interface_dest_down (int command, struct zclient *zclient,
|
||||
zebra_size_t length)
|
||||
ospf6_bfd_interface_dest_update (int command, struct zclient *zclient,
|
||||
zebra_size_t length)
|
||||
{
|
||||
struct interface *ifp;
|
||||
struct ospf6_interface *oi;
|
||||
@ -166,8 +192,12 @@ ospf6_bfd_interface_dest_down (int command, struct zclient *zclient,
|
||||
struct prefix sp;
|
||||
struct listnode *node, *nnode;
|
||||
char dst[64];
|
||||
int status;
|
||||
int old_status;
|
||||
struct bfd_info *bfd_info;
|
||||
struct timeval tv;
|
||||
|
||||
ifp = bfd_get_peer_info(zclient->ibuf, &dp, &sp);
|
||||
ifp = bfd_get_peer_info(zclient->ibuf, &dp, &sp, &status);
|
||||
|
||||
if ((ifp == NULL) || (dp.family != AF_INET6))
|
||||
return 0;
|
||||
@ -176,7 +206,8 @@ ospf6_bfd_interface_dest_down (int command, struct zclient *zclient,
|
||||
{
|
||||
char buf[128];
|
||||
prefix2str(&dp, buf, sizeof(buf));
|
||||
zlog_debug("Zebra: interface %s bfd destination %s down", ifp->name, buf);
|
||||
zlog_debug("Zebra: interface %s bfd destination %s %s", ifp->name, buf,
|
||||
bfd_get_status_str(status));
|
||||
}
|
||||
|
||||
|
||||
@ -192,16 +223,56 @@ ospf6_bfd_interface_dest_down (int command, struct zclient *zclient,
|
||||
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);
|
||||
zlog_debug ("[%s:%s]: BFD %s", ifp->name, dst,
|
||||
bfd_get_status_str(status));
|
||||
}
|
||||
|
||||
THREAD_OFF (on->inactivity_timer);
|
||||
thread_add_event (master, inactivity_timer, on, 0);
|
||||
if (!on->bfd_info)
|
||||
continue;
|
||||
|
||||
bfd_info = (struct bfd_info *)on->bfd_info;
|
||||
if (bfd_info->status == status)
|
||||
continue;
|
||||
|
||||
old_status = bfd_info->status;
|
||||
bfd_info->status = status;
|
||||
quagga_gettime (QUAGGA_CLK_MONOTONIC, &tv);
|
||||
bfd_info->last_update = tv.tv_sec;
|
||||
|
||||
if ((status == BFD_STATUS_DOWN) && (old_status == BFD_STATUS_UP))
|
||||
{
|
||||
THREAD_OFF (on->inactivity_timer);
|
||||
thread_add_event (master, inactivity_timer, on, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ospf6_bfd_info_nbr_create - Create/update BFD information for a neighbor.
|
||||
*/
|
||||
void
|
||||
ospf6_bfd_info_nbr_create (struct ospf6_interface *oi,
|
||||
struct ospf6_neighbor *on)
|
||||
{
|
||||
struct bfd_info *oi_bfd_info;
|
||||
struct bfd_info *on_bfd_info;
|
||||
|
||||
if (!oi->bfd_info)
|
||||
return;
|
||||
|
||||
oi_bfd_info = (struct bfd_info *)oi->bfd_info;
|
||||
|
||||
if (!on->bfd_info)
|
||||
on->bfd_info = bfd_info_create();
|
||||
|
||||
on_bfd_info = (struct bfd_info *)on->bfd_info;
|
||||
on_bfd_info->detect_mult = oi_bfd_info->detect_mult;
|
||||
on_bfd_info->desired_min_tx = oi_bfd_info->desired_min_tx;
|
||||
on_bfd_info->required_min_rx = oi_bfd_info->required_min_rx;
|
||||
}
|
||||
|
||||
/*
|
||||
* ospf6_bfd_write_config - Write the interface BFD configuration.
|
||||
*/
|
||||
@ -321,7 +392,7 @@ DEFUN (no_ipv6_ospf6_bfd,
|
||||
if (oi->bfd_info)
|
||||
{
|
||||
ospf6_bfd_reg_dereg_all_nbr(oi, ZEBRA_BFD_DEST_DEREGISTER);
|
||||
bfd_info_free(&(oi->bfd_info));
|
||||
bfd_info_free((struct bfd_info **)&(oi->bfd_info));
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
@ -331,7 +402,7 @@ void
|
||||
ospf6_bfd_init(void)
|
||||
{
|
||||
/* Initialize BFD client functions */
|
||||
zclient->interface_bfd_dest_down = ospf6_bfd_interface_dest_down;
|
||||
zclient->interface_bfd_dest_update = ospf6_bfd_interface_dest_update;
|
||||
zclient->bfd_dest_replay = ospf6_bfd_nbr_replay;
|
||||
|
||||
/* Install BFD command */
|
||||
|
@ -33,4 +33,14 @@ 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);
|
||||
|
||||
extern void
|
||||
ospf6_bfd_info_nbr_create (struct ospf6_interface *oi,
|
||||
struct ospf6_neighbor *on);
|
||||
|
||||
extern void
|
||||
ospf6_bfd_info_free(void **bfd_info);
|
||||
|
||||
extern void
|
||||
ospf6_bfd_show_info(struct vty *vty, void *bfd_info, int param_only);
|
||||
|
||||
#endif /* OSPF6_BFD_H */
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include "prefix.h"
|
||||
#include "plist.h"
|
||||
#include "zclient.h"
|
||||
#include "bfd.h"
|
||||
|
||||
#include "ospf6_lsa.h"
|
||||
#include "ospf6_lsdb.h"
|
||||
@ -263,7 +262,7 @@ 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));
|
||||
ospf6_bfd_info_free(&(oi->bfd_info));
|
||||
|
||||
XFREE (MTYPE_OSPF6_IF, oi);
|
||||
}
|
||||
@ -977,7 +976,7 @@ ospf6_interface_show (struct vty *vty, struct interface *ifp)
|
||||
for (lsa = ospf6_lsdb_head (oi->lsack_list); lsa;
|
||||
lsa = ospf6_lsdb_next (lsa))
|
||||
vty_out (vty, " %s%s", lsa->name, VNL);
|
||||
|
||||
ospf6_bfd_show_info(vty, oi->bfd_info, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,7 @@ struct ospf6_interface
|
||||
char *plist_name;
|
||||
|
||||
/* BFD information */
|
||||
struct bfd_info *bfd_info;
|
||||
void *bfd_info;
|
||||
};
|
||||
|
||||
/* interface state */
|
||||
|
@ -103,6 +103,8 @@ ospf6_neighbor_create (u_int32_t router_id, struct ospf6_interface *oi)
|
||||
on->lsack_list = ospf6_lsdb_create (on);
|
||||
|
||||
listnode_add_sort (oi->neighbor_list, on);
|
||||
|
||||
ospf6_bfd_info_nbr_create(oi, on);
|
||||
return on;
|
||||
}
|
||||
|
||||
@ -139,6 +141,7 @@ ospf6_neighbor_delete (struct ospf6_neighbor *on)
|
||||
THREAD_OFF (on->thread_send_lsupdate);
|
||||
THREAD_OFF (on->thread_send_lsack);
|
||||
|
||||
ospf6_bfd_info_free(&on->bfd_info);
|
||||
XFREE (MTYPE_OSPF6_NEIGHBOR, on);
|
||||
}
|
||||
|
||||
@ -815,6 +818,7 @@ ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on)
|
||||
lsa = ospf6_lsdb_next (lsa))
|
||||
vty_out (vty, " %s%s", lsa->name, VNL);
|
||||
|
||||
ospf6_bfd_show_info(vty, on->bfd_info, 0);
|
||||
}
|
||||
|
||||
DEFUN (show_ipv6_ospf6_neighbor,
|
||||
|
@ -96,6 +96,9 @@ struct ospf6_neighbor
|
||||
struct thread *thread_send_lsreq;
|
||||
struct thread *thread_send_lsupdate;
|
||||
struct thread *thread_send_lsack;
|
||||
|
||||
/* BFD information */
|
||||
void *bfd_info;
|
||||
};
|
||||
|
||||
/* Neighbor state */
|
||||
|
117
ospfd/ospf_bfd.c
117
ospfd/ospf_bfd.c
@ -47,6 +47,15 @@
|
||||
|
||||
extern struct zclient *zclient;
|
||||
|
||||
/*
|
||||
* ospf_bfd_info_free - Free BFD info structure
|
||||
*/
|
||||
void
|
||||
ospf_bfd_info_free(void **bfd_info)
|
||||
{
|
||||
bfd_info_free((struct bfd_info **) bfd_info);
|
||||
}
|
||||
|
||||
/*
|
||||
* ospf_bfd_reg_dereg_nbr - Register/Deregister a neighbor with BFD through
|
||||
* zebra for starting/stopping the monitoring of
|
||||
@ -118,6 +127,11 @@ ospf_bfd_reg_dereg_all_nbr (struct interface *ifp, int command)
|
||||
if ((nbr = nrn->info) == NULL || nbr == oi->nbr_self)
|
||||
continue;
|
||||
|
||||
if (command != ZEBRA_BFD_DEST_DEREGISTER)
|
||||
ospf_bfd_info_nbr_create(oi, nbr);
|
||||
else
|
||||
bfd_info_free((struct bfd_info **)&nbr->bfd_info);
|
||||
|
||||
if (nbr->state < NSM_TwoWay)
|
||||
continue;
|
||||
|
||||
@ -179,13 +193,14 @@ ospf_bfd_nbr_replay (int command, struct zclient *client, zebra_size_t length)
|
||||
}
|
||||
|
||||
/*
|
||||
* ospf_bfd_interface_dest_down - Find the neighbor for which the BFD status
|
||||
* has changed and bring down the neighbor
|
||||
* connectivity.
|
||||
* ospf_bfd_interface_dest_update - Find the neighbor for which the BFD status
|
||||
* has changed and bring down the neighbor
|
||||
* connectivity if the BFD status changed to
|
||||
* down.
|
||||
*/
|
||||
static int
|
||||
ospf_bfd_interface_dest_down (int command, struct zclient *zclient,
|
||||
zebra_size_t length)
|
||||
ospf_bfd_interface_dest_update (int command, struct zclient *zclient,
|
||||
zebra_size_t length)
|
||||
{
|
||||
struct interface *ifp;
|
||||
struct ospf_interface *oi;
|
||||
@ -193,8 +208,12 @@ ospf_bfd_interface_dest_down (int command, struct zclient *zclient,
|
||||
struct ospf_neighbor *nbr;
|
||||
struct route_node *node;
|
||||
struct prefix p;
|
||||
int status;
|
||||
int old_status;
|
||||
struct bfd_info *bfd_info;
|
||||
struct timeval tv;
|
||||
|
||||
ifp = bfd_get_peer_info (zclient->ibuf, &p, NULL);
|
||||
ifp = bfd_get_peer_info (zclient->ibuf, &p, NULL, &status);
|
||||
|
||||
if ((ifp == NULL) || (p.family != AF_INET))
|
||||
return 0;
|
||||
@ -203,7 +222,8 @@ ospf_bfd_interface_dest_down (int command, struct zclient *zclient,
|
||||
{
|
||||
char buf[128];
|
||||
prefix2str(&p, buf, sizeof(buf));
|
||||
zlog_debug("Zebra: interface %s bfd destination %s down", ifp->name, buf);
|
||||
zlog_debug("Zebra: interface %s bfd destination %s %s", ifp->name, buf,
|
||||
bfd_get_status_str(status));
|
||||
}
|
||||
|
||||
params = IF_DEF_PARAMS (ifp);
|
||||
@ -216,19 +236,59 @@ ospf_bfd_interface_dest_down (int command, struct zclient *zclient,
|
||||
continue;
|
||||
|
||||
nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &p.u.prefix4);
|
||||
if (!nbr)
|
||||
if (!nbr || !nbr->bfd_info)
|
||||
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));
|
||||
bfd_info = (struct bfd_info *)nbr->bfd_info;
|
||||
if (bfd_info->status == status)
|
||||
continue;
|
||||
|
||||
OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_InactivityTimer);
|
||||
old_status = bfd_info->status;
|
||||
bfd_info->status = status;
|
||||
quagga_gettime (QUAGGA_CLK_MONOTONIC, &tv);
|
||||
bfd_info->last_update = tv.tv_sec;
|
||||
|
||||
if ((status == BFD_STATUS_DOWN) && (old_status == BFD_STATUS_UP))
|
||||
{
|
||||
if (IS_DEBUG_OSPF (nsm, NSM_EVENTS))
|
||||
zlog_debug ("NSM[%s:%s]: BFD Down",
|
||||
IF_NAME (nbr->oi), inet_ntoa (nbr->address.u.prefix4));
|
||||
|
||||
OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_InactivityTimer);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ospf_bfd_info_nbr_create - Create/update BFD information for a neighbor.
|
||||
*/
|
||||
void
|
||||
ospf_bfd_info_nbr_create (struct ospf_interface *oi, struct ospf_neighbor *nbr)
|
||||
{
|
||||
struct bfd_info *oi_bfd_info;
|
||||
struct bfd_info *nbr_bfd_info;
|
||||
struct interface *ifp = oi->ifp;
|
||||
struct ospf_if_params *params;
|
||||
|
||||
/* Check if BFD is enabled */
|
||||
params = IF_DEF_PARAMS (ifp);
|
||||
|
||||
/* Check if BFD is enabled */
|
||||
if (!params->bfd_info)
|
||||
return;
|
||||
|
||||
oi_bfd_info = (struct bfd_info *)params->bfd_info;
|
||||
if (!nbr->bfd_info)
|
||||
nbr->bfd_info = bfd_info_create();
|
||||
|
||||
nbr_bfd_info = (struct bfd_info *)nbr->bfd_info;
|
||||
nbr_bfd_info->detect_mult = oi_bfd_info->detect_mult;
|
||||
nbr_bfd_info->desired_min_tx = oi_bfd_info->desired_min_tx;
|
||||
nbr_bfd_info->required_min_rx = oi_bfd_info->required_min_rx;
|
||||
}
|
||||
|
||||
/*
|
||||
* ospf_bfd_write_config - Write the interface BFD configuration.
|
||||
*/
|
||||
@ -251,6 +311,32 @@ ospf_bfd_write_config(struct vty *vty, struct ospf_if_params *params)
|
||||
vty_out (vty, " ip ospf bfd%s", VTY_NEWLINE);
|
||||
}
|
||||
|
||||
/*
|
||||
* ospf_bfd_show_info - Show BFD info structure
|
||||
*/
|
||||
void
|
||||
ospf_bfd_show_info(struct vty *vty, void *bfd_info, json_object *json_obj,
|
||||
u_char use_json, int param_only)
|
||||
{
|
||||
if (param_only)
|
||||
bfd_show_param(vty, (struct bfd_info *)bfd_info, 1, 0, use_json, json_obj);
|
||||
else
|
||||
bfd_show_info(vty, (struct bfd_info *)bfd_info, 0, 1, use_json, json_obj);
|
||||
}
|
||||
|
||||
/*
|
||||
* ospf_bfd_interface_show - Show the interface BFD configuration.
|
||||
*/
|
||||
void
|
||||
ospf_bfd_interface_show(struct vty *vty, struct interface *ifp,
|
||||
json_object *json_interface_sub, u_char use_json)
|
||||
{
|
||||
struct ospf_if_params *params;
|
||||
|
||||
params = IF_DEF_PARAMS (ifp);
|
||||
|
||||
ospf_bfd_show_info(vty, params->bfd_info, json_interface_sub, use_json, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* ospf_bfd_if_param_set - Set the configured BFD paramter values for
|
||||
@ -265,13 +351,12 @@ ospf_bfd_if_param_set (struct interface *ifp, u_int32_t min_rx,
|
||||
|
||||
params = IF_DEF_PARAMS (ifp);
|
||||
|
||||
bfd_set_param(&(params->bfd_info), min_rx, min_tx, detect_mult,
|
||||
defaults, &command);
|
||||
bfd_set_param((struct bfd_info **)&(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",
|
||||
@ -342,7 +427,7 @@ void
|
||||
ospf_bfd_init(void)
|
||||
{
|
||||
/* Initialize BFD client functions */
|
||||
zclient->interface_bfd_dest_down = ospf_bfd_interface_dest_down;
|
||||
zclient->interface_bfd_dest_update = ospf_bfd_interface_dest_update;
|
||||
zclient->bfd_dest_replay = ospf_bfd_nbr_replay;
|
||||
|
||||
/* Install BFD command */
|
||||
|
@ -24,6 +24,8 @@
|
||||
#ifndef _ZEBRA_OSPF_BFD_H
|
||||
#define _ZEBRA_OSPF_BFD_H
|
||||
|
||||
#include "json.h"
|
||||
|
||||
extern void
|
||||
ospf_bfd_init(void);
|
||||
|
||||
@ -33,4 +35,18 @@ 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);
|
||||
|
||||
extern void
|
||||
ospf_bfd_interface_show(struct vty *vty, struct interface *ifp,
|
||||
json_object *json_interface_sub, u_char use_json);
|
||||
|
||||
extern void
|
||||
ospf_bfd_info_nbr_create (struct ospf_interface *oi, struct ospf_neighbor *nbr);
|
||||
|
||||
extern void
|
||||
ospf_bfd_show_info(struct vty *vty, void *bfd_info, json_object *json_obj,
|
||||
u_char use_json, int param_only);
|
||||
|
||||
extern void
|
||||
ospf_bfd_info_free(void **bfd_info);
|
||||
|
||||
#endif /* _ZEBRA_OSPF_BFD_H */
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "stream.h"
|
||||
#include "table.h"
|
||||
#include "log.h"
|
||||
#include "json.h"
|
||||
|
||||
#include "ospfd/ospfd.h"
|
||||
#include "ospfd/ospf_interface.h"
|
||||
@ -42,6 +43,7 @@
|
||||
#include "ospfd/ospf_network.h"
|
||||
#include "ospfd/ospf_flood.h"
|
||||
#include "ospfd/ospf_dump.h"
|
||||
#include "ospfd/ospf_bfd.h"
|
||||
|
||||
/* Fill in the the 'key' as appropriate to retrieve the entry for nbr
|
||||
* from the ospf_interface's nbrs table. Indexed by interface address
|
||||
@ -98,6 +100,7 @@ ospf_nbr_new (struct ospf_interface *oi)
|
||||
|
||||
nbr->crypt_seqnum = 0;
|
||||
|
||||
ospf_bfd_info_nbr_create(oi, nbr);
|
||||
return nbr;
|
||||
}
|
||||
|
||||
@ -141,6 +144,7 @@ ospf_nbr_free (struct ospf_neighbor *nbr)
|
||||
/* Cancel all events. *//* Thread lookup cost would be negligible. */
|
||||
thread_cancel_event (master, nbr);
|
||||
|
||||
ospf_bfd_info_free(&nbr->bfd_info);
|
||||
XFREE (MTYPE_OSPF_NEIGHBOR, nbr);
|
||||
}
|
||||
|
||||
|
@ -88,6 +88,9 @@ struct ospf_neighbor
|
||||
struct timeval ts_last_regress; /* last regressive NSM change */
|
||||
const char *last_regress_str; /* Event which last regressed NSM */
|
||||
u_int32_t state_change; /* NSM state change counter */
|
||||
|
||||
/* BFD information */
|
||||
void *bfd_info;
|
||||
};
|
||||
|
||||
/* Macros. */
|
||||
|
@ -3857,6 +3857,7 @@ show_ip_ospf_interface_sub (struct vty *vty, struct ospf *ospf, struct interface
|
||||
vty_out (vty, " Neighbor Count is %d, Adjacent neighbor count is %d%s",
|
||||
ospf_nbr_count (oi, 0), ospf_nbr_count (oi, NSM_Full),
|
||||
VTY_NEWLINE);
|
||||
ospf_bfd_interface_show(vty, ifp, json_interface_sub, use_json);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4622,6 +4623,8 @@ show_ip_ospf_neighbor_detail_sub (struct vty *vty, struct ospf_interface *oi,
|
||||
else
|
||||
json_object_object_add(json, inet_ntoa (nbr->router_id), json_sub);
|
||||
}
|
||||
|
||||
ospf_bfd_show_info(vty, nbr->bfd_info, json, use_json, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "ptm_lib.h"
|
||||
#include "buffer.h"
|
||||
#include "zebra/zebra_ptm_redistribute.h"
|
||||
#include "bfd.h"
|
||||
|
||||
#define ZEBRA_PTM_RECONNECT_TIME_INITIAL 1 /* initial reconnect is 1s */
|
||||
#define ZEBRA_PTM_RECONNECT_TIME_MAX 300
|
||||
@ -68,6 +69,7 @@ const char ZEBRA_PTM_BFD_CLIENT_FIELD[] = "client";
|
||||
const char ZEBRA_PTM_BFD_SEQID_FIELD[] = "seqid";
|
||||
const char ZEBRA_PTM_BFD_IFNAME_FIELD[] = "ifName";
|
||||
const char ZEBRA_PTM_BFD_MAX_HOP_CNT_FIELD[] = "maxHopCnt";
|
||||
const char ZEBRA_PTM_BFD_SEND_EVENT[] = "sendEvent";
|
||||
|
||||
extern struct zebra_t zebrad;
|
||||
|
||||
@ -341,7 +343,8 @@ zebra_ptm_install_commands (void)
|
||||
|
||||
/* BFD session goes down, send message to the protocols. */
|
||||
static void
|
||||
if_bfd_session_down (struct interface *ifp, struct prefix *dp, struct prefix *sp)
|
||||
if_bfd_session_update (struct interface *ifp, struct prefix *dp,
|
||||
struct prefix *sp, int status)
|
||||
{
|
||||
if (IS_ZEBRA_DEBUG_EVENT)
|
||||
{
|
||||
@ -349,22 +352,24 @@ if_bfd_session_down (struct interface *ifp, struct prefix *dp, struct prefix *sp
|
||||
|
||||
if (ifp)
|
||||
{
|
||||
zlog_debug ("MESSAGE: ZEBRA_INTERFACE_BFD_DEST_DOWN %s/%d on %s",
|
||||
inet_ntop (dp->family, &dp->u.prefix, buf[0],
|
||||
INET6_ADDRSTRLEN), dp->prefixlen, ifp->name);
|
||||
zlog_debug ("MESSAGE: ZEBRA_INTERFACE_BFD_DEST_UPDATE %s/%d on %s"
|
||||
" %s event",
|
||||
inet_ntop (dp->family, &dp->u.prefix, buf[0],
|
||||
INET6_ADDRSTRLEN), dp->prefixlen, ifp->name,
|
||||
bfd_get_status_str(status));
|
||||
}
|
||||
else
|
||||
{
|
||||
zlog_debug ("MESSAGE: ZEBRA_INTERFACE_BFD_DEST_DOWN %s/%d "
|
||||
"with src %s/%d",
|
||||
zlog_debug ("MESSAGE: ZEBRA_INTERFACE_BFD_DEST_UPDATE %s/%d "
|
||||
"with src %s/%d %s event",
|
||||
inet_ntop (dp->family, &dp->u.prefix, buf[0], INET6_ADDRSTRLEN),
|
||||
dp->prefixlen,
|
||||
inet_ntop (sp->family, &sp->u.prefix, buf[1], INET6_ADDRSTRLEN),
|
||||
sp->prefixlen);
|
||||
sp->prefixlen, bfd_get_status_str(status));
|
||||
}
|
||||
}
|
||||
|
||||
zebra_interface_bfd_update (ifp, dp, sp);
|
||||
zebra_interface_bfd_update (ifp, dp, sp, status);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -403,44 +408,25 @@ zebra_ptm_handle_bfd_msg(void *arg, void *in_ctxt, struct interface *ifp)
|
||||
__func__, ifp ? ifp->name : "N/A", bfdst_str,
|
||||
dest_str, src_str);
|
||||
|
||||
/* we only care if bfd session goes down */
|
||||
if (!strcmp (bfdst_str, ZEBRA_PTM_BFDSTATUS_DOWN_STR)) {
|
||||
if (inet_pton(AF_INET, dest_str, &dest_prefix.u.prefix4) > 0) {
|
||||
dest_prefix.family = AF_INET;
|
||||
dest_prefix.prefixlen = IPV4_MAX_PREFIXLEN;
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else if (inet_pton(AF_INET6, dest_str, &dest_prefix.u.prefix6) > 0) {
|
||||
dest_prefix.family = AF_INET6;
|
||||
dest_prefix.prefixlen = IPV6_MAX_PREFIXLEN;
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
else {
|
||||
zlog_err("%s: Peer addr %s not found", __func__,
|
||||
dest_str);
|
||||
if (str2prefix(dest_str, &dest_prefix) == 0) {
|
||||
zlog_err("%s: Peer addr %s not found", __func__,
|
||||
dest_str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&src_prefix, 0, sizeof(struct prefix));
|
||||
if (strcmp(ZEBRA_PTM_INVALID_SRC_IP, src_str)) {
|
||||
if (str2prefix(src_str, &src_prefix) == 0) {
|
||||
zlog_err("%s: Local addr %s not found", __func__,
|
||||
src_str);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
memset(&src_prefix, 0, sizeof(struct prefix));
|
||||
if (strcmp(ZEBRA_PTM_INVALID_SRC_IP, src_str)) {
|
||||
if (inet_pton(AF_INET, src_str, &src_prefix.u.prefix4) > 0) {
|
||||
src_prefix.family = AF_INET;
|
||||
src_prefix.prefixlen = IPV4_MAX_PREFIXLEN;
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else if (inet_pton(AF_INET6, src_str, &src_prefix.u.prefix6) > 0) {
|
||||
src_prefix.family = AF_INET6;
|
||||
src_prefix.prefixlen = IPV6_MAX_PREFIXLEN;
|
||||
}
|
||||
#endif /* HAVE_IPV6 */
|
||||
else {
|
||||
zlog_err("%s: Local addr %s not found", __func__,
|
||||
src_str);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if_bfd_session_down(ifp, &dest_prefix, &src_prefix);
|
||||
if (!strcmp (bfdst_str, ZEBRA_PTM_BFDSTATUS_DOWN_STR)) {
|
||||
if_bfd_session_update(ifp, &dest_prefix, &src_prefix, BFD_STATUS_DOWN);
|
||||
} else {
|
||||
if_bfd_session_update(ifp, &dest_prefix, &src_prefix, BFD_STATUS_UP);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -718,6 +704,10 @@ zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length,
|
||||
if_name);
|
||||
}
|
||||
|
||||
sprintf(tmp_buf, "%d", 1);
|
||||
ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEND_EVENT,
|
||||
tmp_buf);
|
||||
|
||||
ptm_lib_complete_msg(ptm_hdl, out_ctxt, ptm_cb.out_data, &data_len);
|
||||
|
||||
if (IS_ZEBRA_DEBUG_SEND)
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include "zebra_ptm_redistribute.h"
|
||||
|
||||
void zebra_interface_bfd_update (struct interface *a, struct prefix *dp,
|
||||
struct prefix *sp)
|
||||
struct prefix *sp, int status)
|
||||
{ return; }
|
||||
|
||||
void zebra_bfd_peer_replay_req (void)
|
||||
|
@ -32,7 +32,7 @@ extern struct zebra_t zebrad;
|
||||
static int
|
||||
zsend_interface_bfd_update (int cmd, struct zserv *client,
|
||||
struct interface *ifp, struct prefix *dp,
|
||||
struct prefix *sp)
|
||||
struct prefix *sp, int status)
|
||||
{
|
||||
int blen;
|
||||
struct stream *s;
|
||||
@ -56,6 +56,9 @@ zsend_interface_bfd_update (int cmd, struct zserv *client,
|
||||
stream_put (s, &dp->u.prefix, blen);
|
||||
stream_putc (s, dp->prefixlen);
|
||||
|
||||
/* BFD status */
|
||||
stream_putl(s, status);
|
||||
|
||||
/* BFD source prefix information. */
|
||||
stream_putc (s, sp->family);
|
||||
blen = prefix_blen (sp);
|
||||
@ -71,7 +74,7 @@ zsend_interface_bfd_update (int cmd, struct zserv *client,
|
||||
|
||||
void
|
||||
zebra_interface_bfd_update (struct interface *ifp, struct prefix *dp,
|
||||
struct prefix *sp)
|
||||
struct prefix *sp, int status)
|
||||
{
|
||||
struct listnode *node, *nnode;
|
||||
struct zserv *client;
|
||||
@ -84,8 +87,8 @@ zebra_interface_bfd_update (struct interface *ifp, struct prefix *dp,
|
||||
continue;
|
||||
|
||||
/* Notify to the protocol daemons. */
|
||||
zsend_interface_bfd_update (ZEBRA_INTERFACE_BFD_DEST_DOWN, client, ifp,
|
||||
dp, sp);
|
||||
zsend_interface_bfd_update (ZEBRA_INTERFACE_BFD_DEST_UPDATE, client, ifp,
|
||||
dp, sp, status);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,6 @@
|
||||
#ifndef _ZEBRA_PTM_REDISTRIBUTE_H
|
||||
#define _ZEBRA_PTM_REDISTRIBUTE_H
|
||||
extern void zebra_interface_bfd_update (struct interface *, struct prefix *,
|
||||
struct prefix *);
|
||||
struct prefix *, int);
|
||||
extern void zebra_bfd_peer_replay_req (void);
|
||||
#endif /* _ZEBRA_PTM_REDISTRIBUTE_H */
|
||||
|
Loading…
Reference in New Issue
Block a user