summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_bfd.c98
-rw-r--r--lib/bfd.c152
-rw-r--r--lib/bfd.h22
-rw-r--r--lib/log.c2
-rw-r--r--lib/zclient.c6
-rw-r--r--lib/zclient.h2
-rw-r--r--lib/zebra.h2
-rw-r--r--ospf6d/ospf6_bfd.c95
-rw-r--r--ospf6d/ospf6_bfd.h10
-rw-r--r--ospf6d/ospf6_interface.c5
-rw-r--r--ospf6d/ospf6_interface.h2
-rw-r--r--ospf6d/ospf6_neighbor.c4
-rw-r--r--ospf6d/ospf6_neighbor.h3
-rw-r--r--ospfd/ospf_bfd.c117
-rw-r--r--ospfd/ospf_bfd.h16
-rw-r--r--ospfd/ospf_neighbor.c4
-rw-r--r--ospfd/ospf_neighbor.h3
-rw-r--r--ospfd/ospf_vty.c3
-rw-r--r--zebra/zebra_ptm.c76
-rw-r--r--zebra/zebra_ptm_null.c2
-rw-r--r--zebra/zebra_ptm_redistribute.c11
-rw-r--r--zebra/zebra_ptm_redistribute.h2
22 files changed, 497 insertions, 140 deletions
diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c
index 22b8adcdb..5505ced92 100644
--- a/bgpd/bgp_bfd.c
+++ b/bgpd/bgp_bfd.c
@@ -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. */
diff --git a/lib/bfd.c b/lib/bfd.c
index 862a95dac..613c71487 100644
--- a/lib/bfd.c
+++ b/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);
+}
diff --git a/lib/bfd.h b/lib/bfd.h
index f0051d93a..0b5743b91 100644
--- a/lib/bfd.h
+++ b/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 */
diff --git a/lib/log.c b/lib/log.c
index 64bd16458..1046f904d 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -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),
diff --git a/lib/zclient.c b/lib/zclient.c
index 39b6f8ec5..35b18cb95 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -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)
diff --git a/lib/zclient.h b/lib/zclient.h
index 26cae0434..6ed4fede4 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -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);
diff --git a/lib/zebra.h b/lib/zebra.h
index 387cd6541..41de01ec2 100644
--- a/lib/zebra.h
+++ b/lib/zebra.h
@@ -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
diff --git a/ospf6d/ospf6_bfd.c b/ospf6d/ospf6_bfd.c
index e30f4962d..5ef4ab4ca 100644
--- a/ospf6d/ospf6_bfd.c
+++ b/ospf6d/ospf6_bfd.c
@@ -46,6 +46,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
* the neighbor rechahability.
@@ -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,17 +223,57 @@ 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.
*/
void
@@ -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 */
diff --git a/ospf6d/ospf6_bfd.h b/ospf6d/ospf6_bfd.h
index eaaf15785..11b13d66f 100644
--- a/ospf6d/ospf6_bfd.h
+++ b/ospf6d/ospf6_bfd.h
@@ -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 */
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index 63783cc8f..21751656b 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -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;
}
diff --git a/ospf6d/ospf6_interface.h b/ospf6d/ospf6_interface.h
index 3f5c5f041..6ef9e3782 100644
--- a/ospf6d/ospf6_interface.h
+++ b/ospf6d/ospf6_interface.h
@@ -115,7 +115,7 @@ struct ospf6_interface
char *plist_name;
/* BFD information */
- struct bfd_info *bfd_info;
+ void *bfd_info;
};
/* interface state */
diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c
index c5edd226d..1636c2628 100644
--- a/ospf6d/ospf6_neighbor.c
+++ b/ospf6d/ospf6_neighbor.c
@@ -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,
diff --git a/ospf6d/ospf6_neighbor.h b/ospf6d/ospf6_neighbor.h
index cba2cb99d..fad7fd578 100644
--- a/ospf6d/ospf6_neighbor.h
+++ b/ospf6d/ospf6_neighbor.h
@@ -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 */
diff --git a/ospfd/ospf_bfd.c b/ospfd/ospf_bfd.c
index 054a806bb..46c1844e2 100644
--- a/ospfd/ospf_bfd.c
+++ b/ospfd/ospf_bfd.c
@@ -48,6 +48,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
* the neighbor rechahability.
@@ -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,20 +236,60 @@ 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;
+
+ bfd_info = (struct bfd_info *)nbr->bfd_info;
+ if (bfd_info->status == status)
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));
+ 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);
+ 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.
*/
void
@@ -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 */
diff --git a/ospfd/ospf_bfd.h b/ospfd/ospf_bfd.h
index 436597c0b..793962dae 100644
--- a/ospfd/ospf_bfd.h
+++ b/ospfd/ospf_bfd.h
@@ -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 */
diff --git a/ospfd/ospf_neighbor.c b/ospfd/ospf_neighbor.c
index 967ca15db..afc74d2b0 100644
--- a/ospfd/ospf_neighbor.c
+++ b/ospfd/ospf_neighbor.c
@@ -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);
}
diff --git a/ospfd/ospf_neighbor.h b/ospfd/ospf_neighbor.h
index 25f135242..7118dd021 100644
--- a/ospfd/ospf_neighbor.h
+++ b/ospfd/ospf_neighbor.h
@@ -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. */
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index 6caeda765..f2b34bab1 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -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
diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c
index 6c85eaa89..0fecd17d5 100644
--- a/zebra/zebra_ptm.c
+++ b/zebra/zebra_ptm.c
@@ -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);
- return -1;
- }
+ 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 (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;
- }
+ 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;
}
+ }
- 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)
diff --git a/zebra/zebra_ptm_null.c b/zebra/zebra_ptm_null.c
index ad48f2385..293db2e67 100644
--- a/zebra/zebra_ptm_null.c
+++ b/zebra/zebra_ptm_null.c
@@ -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)
diff --git a/zebra/zebra_ptm_redistribute.c b/zebra/zebra_ptm_redistribute.c
index 6166fc002..1a81c7985 100644
--- a/zebra/zebra_ptm_redistribute.c
+++ b/zebra/zebra_ptm_redistribute.c
@@ -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);
}
}
diff --git a/zebra/zebra_ptm_redistribute.h b/zebra/zebra_ptm_redistribute.h
index b79d122af..d78390e89 100644
--- a/zebra/zebra_ptm_redistribute.h
+++ b/zebra/zebra_ptm_redistribute.h
@@ -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 */