diff options
author | radhika <radhika@cumulusnetworks.com> | 2015-08-31 23:56:11 +0200 |
---|---|---|
committer | radhika <radhika@cumulusnetworks.com> | 2015-08-31 23:56:11 +0200 |
commit | 68fe91d6c7731fba199a7f4bd53e12a559e3b3de (patch) | |
tree | 03d95c7f20f6fa589c3b9a3a84fdff76cc58956e | |
parent | BGP: Fix MD5 authentication for unnumbered neighbors (diff) | |
download | frr-68fe91d6c7731fba199a7f4bd53e12a559e3b3de.tar.xz frr-68fe91d6c7731fba199a7f4bd53e12a559e3b3de.zip |
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.
-rw-r--r-- | bgpd/bgp_bfd.c | 98 | ||||
-rw-r--r-- | lib/bfd.c | 152 | ||||
-rw-r--r-- | lib/bfd.h | 22 | ||||
-rw-r--r-- | lib/log.c | 2 | ||||
-rw-r--r-- | lib/zclient.c | 6 | ||||
-rw-r--r-- | lib/zclient.h | 2 | ||||
-rw-r--r-- | lib/zebra.h | 2 | ||||
-rw-r--r-- | ospf6d/ospf6_bfd.c | 95 | ||||
-rw-r--r-- | ospf6d/ospf6_bfd.h | 10 | ||||
-rw-r--r-- | ospf6d/ospf6_interface.c | 5 | ||||
-rw-r--r-- | ospf6d/ospf6_interface.h | 2 | ||||
-rw-r--r-- | ospf6d/ospf6_neighbor.c | 4 | ||||
-rw-r--r-- | ospf6d/ospf6_neighbor.h | 3 | ||||
-rw-r--r-- | ospfd/ospf_bfd.c | 117 | ||||
-rw-r--r-- | ospfd/ospf_bfd.h | 16 | ||||
-rw-r--r-- | ospfd/ospf_neighbor.c | 4 | ||||
-rw-r--r-- | ospfd/ospf_neighbor.h | 3 | ||||
-rw-r--r-- | ospfd/ospf_vty.c | 3 | ||||
-rw-r--r-- | zebra/zebra_ptm.c | 76 | ||||
-rw-r--r-- | zebra/zebra_ptm_null.c | 2 | ||||
-rw-r--r-- | zebra/zebra_ptm_redistribute.c | 11 | ||||
-rw-r--r-- | zebra/zebra_ptm_redistribute.h | 2 |
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. */ @@ -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); +} @@ -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), 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 */ |