pimd: pim bfd support

All PIM Neighbors for a given pim interface is registered with
BFD.
Upon receiving BFD status down event, PIM Neighbor with BFD info is deleted.
Add pim bfd configuraiton (CLI) per interface, '[no] ip pim bfd'

Testing Done:
Configure BFD under PIM interface on all neighbor routers,
check bfd sessions up, remote end unconfigure BFD, results in BFD session down.
Previous state was UP to New state DOWN, results in PIM neighbor delete behind
that particular pim interface.
Pim-smoke Results:
Ran 94 tests in 7409.680s
FAILED (SKIP=8, failures=2)

Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
This commit is contained in:
Chirag Shah 2017-04-10 18:01:53 -07:00
parent bac7b7b935
commit ba4eb1bccf
15 changed files with 536 additions and 6 deletions

View File

@ -53,7 +53,7 @@ libpim_a_SOURCES = \
pim_ssmpingd.c pim_int.c pim_rp.c \
pim_static.c pim_br.c pim_register.c pim_routemap.c \
pim_msdp.c pim_msdp_socket.c pim_msdp_packet.c \
pim_jp_agg.c pim_nht.c pim_ssm.c
pim_jp_agg.c pim_nht.c pim_ssm.c pim_bfd.c
noinst_HEADERS = \
pim_memory.h \
@ -66,7 +66,7 @@ noinst_HEADERS = \
pim_igmp_join.h pim_ssmpingd.h pim_int.h pim_rp.h \
pim_static.h pim_br.h pim_register.h \
pim_msdp.h pim_msdp_socket.h pim_msdp_packet.h pim_nht.h \
pim_jp_agg.h pim_ssm.h
pim_jp_agg.h pim_ssm.h pim_bfd.h
pimd_SOURCES = \
pim_main.c $(libpim_a_SOURCES)

360
pimd/pim_bfd.c Normal file
View File

@ -0,0 +1,360 @@
/*
* pim_bfd.c: PIM BFD handling routines
*
* Copyright (C) 2017 Cumulus Networks, Inc.
* Chirag Shah
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#include <zebra.h>
#include "lib/json.h"
#include "command.h"
#include "vty.h"
#include "zclient.h"
#include "pim_cmd.h"
#include "pim_vty.h"
#include "pim_iface.h"
#include "pim_bfd.h"
#include "bfd.h"
#include "pimd.h"
#include "pim_zebra.h"
/*
* pim_bfd_write_config - Write the interface BFD configuration.
*/
void
pim_bfd_write_config (struct vty *vty, struct interface *ifp)
{
struct pim_interface *pim_ifp = ifp->info;
struct bfd_info *bfd_info = NULL;
if (!pim_ifp)
return;
bfd_info = (struct bfd_info *) pim_ifp->bfd_info;
if (!bfd_info)
{
zlog_debug ("%s: interface %s bfd_info is NULL ", __PRETTY_FUNCTION__,
ifp->name);
return;
}
if (CHECK_FLAG (bfd_info->flags, BFD_FLAG_PARAM_CFG))
vty_out (vty, " ip pim bfd %d %d %d%s",
bfd_info->detect_mult, bfd_info->required_min_rx,
bfd_info->desired_min_tx, VTY_NEWLINE);
else
vty_out (vty, " ip pim bfd%s", VTY_NEWLINE);
}
/*
* pim_bfd_show_info - Show BFD info structure
*/
void
pim_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);
}
/*
* pim_bfd_info_nbr_create - Create/update BFD information for a neighbor.
*/
void
pim_bfd_info_nbr_create (struct pim_interface *pim_ifp,
struct pim_neighbor *neigh)
{
struct bfd_info *nbr_bfd_info = NULL;
/* Check if Pim Interface BFD is enabled */
if (!pim_ifp || !pim_ifp->bfd_info)
return;
if (!neigh->bfd_info)
neigh->bfd_info = bfd_info_create ();
if (!neigh->bfd_info)
return;
zlog_debug ("%s: bfd_info ", __PRETTY_FUNCTION__);
nbr_bfd_info = (struct bfd_info *) neigh->bfd_info;
nbr_bfd_info->detect_mult = pim_ifp->bfd_info->detect_mult;
nbr_bfd_info->desired_min_tx = pim_ifp->bfd_info->desired_min_tx;
nbr_bfd_info->required_min_rx = pim_ifp->bfd_info->required_min_rx;
}
/*
* pim_bfd_info_free - Free BFD info structure
*/
void
pim_bfd_info_free (void **bfd_info)
{
bfd_info_free ((struct bfd_info **) bfd_info);
}
static void
pim_bfd_reg_dereg_nbr (struct pim_neighbor *nbr, int command)
{
struct pim_interface *pim_ifp = NULL;
struct bfd_info *bfd_info = NULL;
struct zclient *zclient = NULL;
zclient = pim_zebra_zclient_get ();
if (!nbr)
return;
pim_ifp = nbr->interface->info;
bfd_info = (struct bfd_info *) pim_ifp->bfd_info;
if (!bfd_info)
return;
if (PIM_DEBUG_PIM_TRACE)
{
char str[INET_ADDRSTRLEN];
pim_inet4_dump ("<bfd_nbr?>", nbr->source_addr, str, sizeof (str));
zlog_debug ("%s Nbr %s %s with BFD", __PRETTY_FUNCTION__, str,
bfd_get_command_dbg_str (command));
}
bfd_peer_sendmsg (zclient, bfd_info, AF_INET,
&nbr->source_addr, NULL, nbr->interface->name,
0, 0, command, 0, VRF_DEFAULT);
}
/*
* pim_bfd_reg_dereg_all_nbr - Register/Deregister all neighbors associated
* with a interface with BFD through
* zebra for starting/stopping the monitoring of
* the neighbor rechahability.
*/
int
pim_bfd_reg_dereg_all_nbr (struct interface *ifp, int command)
{
struct pim_interface *pim_ifp = NULL;
struct listnode *node = NULL;
struct pim_neighbor *neigh = NULL;
pim_ifp = ifp->info;
if (!pim_ifp)
return -1;
if (!pim_ifp->bfd_info)
return -1;
for (ALL_LIST_ELEMENTS_RO (pim_ifp->pim_neighbor_list, node, neigh))
{
if (command != ZEBRA_BFD_DEST_DEREGISTER)
pim_bfd_info_nbr_create (pim_ifp, neigh);
else
bfd_info_free ((struct bfd_info **) &neigh->bfd_info);
pim_bfd_reg_dereg_nbr (neigh, command);
}
return 0;
}
/*
* pim_bfd_trigger_event - Neighbor is registered/deregistered with BFD when
* neighbor state is changed to/from 2way.
*/
void
pim_bfd_trigger_event (struct pim_interface *pim_ifp, struct pim_neighbor *nbr, uint8_t nbr_up)
{
if (nbr_up)
{
pim_bfd_info_nbr_create (pim_ifp, nbr);
pim_bfd_reg_dereg_nbr (nbr, ZEBRA_BFD_DEST_REGISTER);
}
else
{
pim_bfd_info_free ((void *)&nbr->bfd_info);
pim_bfd_reg_dereg_nbr (nbr, ZEBRA_BFD_DEST_DEREGISTER);
}
}
/*
* pim_bfd_if_param_set - Set the configured BFD paramter values for
* interface.
*/
void
pim_bfd_if_param_set (struct interface *ifp, u_int32_t min_rx,
u_int32_t min_tx, u_int8_t detect_mult, int defaults)
{
struct pim_interface *pim_ifp = ifp->info;
int command = 0;
bfd_set_param ((struct bfd_info **) &(pim_ifp->bfd_info), min_rx, min_tx,
detect_mult, defaults, &command);
if (pim_ifp->bfd_info)
{
if (PIM_DEBUG_PIM_TRACE)
zlog_debug ("%s: interface %s has bfd_info", __PRETTY_FUNCTION__,
ifp->name);
}
if (command)
pim_bfd_reg_dereg_all_nbr (ifp, command);
}
/*
* pim_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
pim_bfd_interface_dest_update (int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
struct interface *ifp = NULL;
struct pim_interface *pim_ifp = NULL;
struct prefix p;
int status;
char msg[100];
int old_status;
struct bfd_info *bfd_info = NULL;
struct timeval tv;
struct listnode *neigh_node = NULL;
struct listnode *neigh_nextnode = NULL;
struct pim_neighbor *neigh = NULL;
ifp = bfd_get_peer_info (zclient->ibuf, &p, NULL, &status, vrf_id);
if ((ifp == NULL) || (p.family != AF_INET))
return 0;
pim_ifp = ifp->info;
if (!pim_ifp)
return 0;
if (!pim_ifp->bfd_info)
{
if (PIM_DEBUG_PIM_TRACE)
zlog_debug ("%s: pim interface %s BFD is disabled ", __PRETTY_FUNCTION__,
ifp->name);
return 0;
}
if (PIM_DEBUG_PIM_TRACE)
{
char buf[PREFIX2STR_BUFFER];
prefix2str (&p, buf, sizeof (buf));
zlog_debug ("%s: interface %s bfd destination %s %s",
__PRETTY_FUNCTION__, ifp->name, buf,
bfd_get_status_str (status));
}
for (ALL_LIST_ELEMENTS (pim_ifp->pim_neighbor_list, neigh_node,
neigh_nextnode, neigh))
{
bfd_info = (struct bfd_info *) neigh->bfd_info;
if (bfd_info->status == status)
{
if (PIM_DEBUG_PIM_TRACE)
{
char str[INET_ADDRSTRLEN];
pim_inet4_dump ("<nht_nbr?>", neigh->source_addr, str,
sizeof (str));
zlog_debug ("%s: bfd status is same for nbr %s",
__PRETTY_FUNCTION__, str);
}
continue;
}
old_status = bfd_info->status;
bfd_info->status = status;
monotime(&tv);
bfd_info->last_update = tv.tv_sec;
if (PIM_DEBUG_PIM_TRACE)
{
zlog_debug ("%s: status %s old_status %s", __PRETTY_FUNCTION__,
bfd_get_status_str (status),
bfd_get_status_str (old_status));
}
if ((status == BFD_STATUS_DOWN) && (old_status == BFD_STATUS_UP))
{
snprintf (msg, sizeof (msg), "BFD Session Expired");
pim_neighbor_delete (ifp, neigh, msg);
}
}
return 0;
}
/*
* pim_bfd_nbr_replay - Replay all the neighbors that have BFD enabled
* to zebra
*/
static int
pim_bfd_nbr_replay (int command, struct zclient *zclient, zebra_size_t length,
vrf_id_t vrf_id)
{
struct interface *ifp = NULL;
struct pim_interface *pim_ifp = NULL;
struct pim_neighbor *neigh = NULL;
struct listnode *node;
struct listnode *neigh_node;
struct listnode *neigh_nextnode;
/* Send the client registration */
bfd_client_sendmsg (zclient, ZEBRA_BFD_CLIENT_REGISTER);
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
{
pim_ifp = ifp->info;
if (!pim_ifp)
continue;
if (pim_ifp->pim_sock_fd < 0)
continue;
for (ALL_LIST_ELEMENTS (pim_ifp->pim_neighbor_list, neigh_node,
neigh_nextnode, neigh))
{
if (!neigh->bfd_info)
continue;
if (PIM_DEBUG_PIM_TRACE)
{
char str[INET_ADDRSTRLEN];
pim_inet4_dump ("<bfd_nbr?>", neigh->source_addr, str,
sizeof (str));
zlog_debug ("%s: Replaying Pim Neigh %s to BFD",
__PRETTY_FUNCTION__, str);
}
pim_bfd_reg_dereg_nbr (neigh, ZEBRA_BFD_DEST_UPDATE);
}
}
return 0;
}
void
pim_bfd_init (void)
{
struct zclient *zclient = NULL;
zclient = pim_zebra_zclient_get ();
bfd_gbl_init ();
zclient->interface_bfd_dest_update = pim_bfd_interface_dest_update;
zclient->bfd_dest_replay = pim_bfd_nbr_replay;
}

42
pimd/pim_bfd.h Normal file
View File

@ -0,0 +1,42 @@
/*
* pim_bfd.h: PIM BFD definitions and structures
*
* Copyright (C) 2017 Cumulus Networks, Inc.
* Chirag Shah
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
#ifndef PIM_BFD_H
#define PIM_BFD_H
#include "if.h"
void pim_bfd_init (void);
void pim_bfd_write_config (struct vty *vty, struct interface *ifp);
void
pim_bfd_show_info (struct vty *vty, void *bfd_info, json_object * json_obj,
u_char use_json, int param_only);
void
pim_bfd_if_param_set (struct interface *ifp, u_int32_t min_rx,
u_int32_t min_tx, u_int8_t detect_mult, int defaults);
int pim_bfd_reg_dereg_all_nbr (struct interface *ifp, int command);
void
pim_bfd_trigger_event (struct pim_interface *pim_ifp, struct pim_neighbor *nbr, uint8_t nbr_up);
void
pim_bfd_info_nbr_create (struct pim_interface *pim_ifp, struct pim_neighbor *neigh);
void pim_bfd_info_free(void **bfd_info);
#endif /* _PIM_BFD_H */

View File

@ -57,6 +57,8 @@
#include "pim_msdp.h"
#include "pim_ssm.h"
#include "pim_nht.h"
#include "pim_bfd.h"
#include "bfd.h"
static struct cmd_node pim_global_node = {
PIM_NODE,
@ -1508,6 +1510,7 @@ static void pim_show_neighbors_single(struct vty *vty, const char *neighbor, u_c
vty_out(vty, " Hello Option - Holdtime : %s%s", option_holdtime ? "yes" : "no", VTY_NEWLINE);
vty_out(vty, " Hello Option - LAN Prune Delay : %s%s", option_lan_prune_delay ? "yes" : "no", VTY_NEWLINE);
vty_out(vty, " Hello Option - T-bit : %s%s", option_t_bit ? "yes" : "no", VTY_NEWLINE);
pim_bfd_show_info (vty, neigh->bfd_info, json_ifp, uj, 0);
vty_out(vty, "%s", VTY_NEWLINE);
}
}
@ -5927,6 +5930,99 @@ DEFUN (interface_no_pim_use_source,
return interface_pim_use_src_cmd_worker (vty, "0.0.0.0");
}
DEFUN (ip_pim_bfd,
ip_pim_bfd_cmd,
"ip pim bfd",
IP_STR
PIM_STR
"Enables BFD support\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct pim_interface *pim_ifp = NULL;
struct bfd_info *bfd_info = NULL;
if (!ifp)
return CMD_SUCCESS;
pim_ifp = ifp->info;
if (!pim_ifp)
return CMD_SUCCESS;
bfd_info = pim_ifp->bfd_info;
if (!bfd_info || !CHECK_FLAG (bfd_info->flags, BFD_FLAG_PARAM_CFG))
pim_bfd_if_param_set (ifp, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX,
BFD_DEF_DETECT_MULT, 1);
return CMD_SUCCESS;
}
DEFUN (no_ip_pim_bfd,
no_ip_pim_bfd_cmd,
"no ip pim bfd",
NO_STR
IP_STR
PIM_STR
"Disables BFD support\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
struct pim_interface *pim_ifp = NULL;
assert (ifp);
pim_ifp = ifp->info;
if (!pim_ifp)
return CMD_SUCCESS;
if (pim_ifp->bfd_info)
{
pim_bfd_reg_dereg_all_nbr (ifp, ZEBRA_BFD_DEST_DEREGISTER);
bfd_info_free (&(pim_ifp->bfd_info));
}
return CMD_SUCCESS;
}
DEFUN (ip_pim_bfd_param,
ip_pim_bfd_param_cmd,
"ip pim bfd (2-255) (50-60000) (50-60000)",
IP_STR
PIM_STR
"Enables BFD support\n"
"Detect Multiplier\n"
"Required min receive interval\n"
"Desired min transmit interval\n")
{
VTY_DECLVAR_CONTEXT(interface, ifp);
int idx_number = 3;
int idx_number_2 = 4;
int idx_number_3 = 5;
u_int32_t rx_val;
u_int32_t tx_val;
u_int8_t dm_val;
int ret;
if ((ret = bfd_validate_param (vty, argv[idx_number]->arg,
argv[idx_number_2]->arg,
argv[idx_number_3]->arg,
&dm_val, &rx_val, &tx_val)) != CMD_SUCCESS)
return ret;
pim_bfd_if_param_set (ifp, rx_val, tx_val, dm_val, 0);
return CMD_SUCCESS;
}
ALIAS (no_ip_pim_bfd,
no_ip_pim_bfd_param_cmd,
"no ip pim bfd (2-255) (50-60000) (50-60000)",
NO_STR
IP_STR
PIM_STR
"Enables BFD support\n"
"Detect Multiplier\n"
"Required min receive interval\n"
"Desired min transmit interval\n")
static int
ip_msdp_peer_cmd_worker (struct vty *vty, const char *peer, const char *local)
{
@ -6910,4 +7006,9 @@ void pim_cmd_init()
install_element (VIEW_NODE, &show_ip_pim_group_type_cmd);
install_element (INTERFACE_NODE, &interface_pim_use_source_cmd);
install_element (INTERFACE_NODE, &interface_no_pim_use_source_cmd);
/* Install BFD command */
install_element (INTERFACE_NODE, &ip_pim_bfd_cmd);
install_element (INTERFACE_NODE, &ip_pim_bfd_param_cmd);
install_element (INTERFACE_NODE, &no_ip_pim_bfd_cmd);
install_element (INTERFACE_NODE, &no_ip_pim_bfd_param_cmd);
}

View File

@ -24,9 +24,12 @@
#include "if.h"
#include "vty.h"
#include "vrf.h"
#include "zclient.h"
#include "pim_igmp.h"
#include "pim_upstream.h"
#include "bfd.h"
#define PIM_IF_MASK_PIM (1 << 0)
#define PIM_IF_MASK_IGMP (1 << 1)
@ -127,6 +130,7 @@ struct pim_interface {
uint32_t pim_ifstat_reg_stop_send;
uint32_t pim_ifstat_assert_recv;
uint32_t pim_ifstat_assert_send;
struct bfd_info *bfd_info;
};
extern struct interface *pim_regiface;

View File

@ -45,6 +45,7 @@
#include "pim_zebra.h"
#include "pim_msdp.h"
#include "pim_iface.h"
#include "pim_bfd.h"
extern struct host host;
@ -129,6 +130,7 @@ int main(int argc, char** argv, char** envp) {
* Initialize zclient "update" and "lookup" sockets
*/
pim_zebra_init();
pim_bfd_init ();
frr_config_fork();

View File

@ -38,6 +38,7 @@
#include "pim_zebra.h"
#include "pim_join.h"
#include "pim_jp_agg.h"
#include "pim_bfd.h"
static void dr_election_by_addr(struct interface *ifp)
{
@ -379,6 +380,9 @@ static struct pim_neighbor *pim_neighbor_new(struct interface *ifp,
++pim_ifp->pim_dr_num_nondrpri_neighbors;
}
//Register PIM Neighbor with BFD
pim_bfd_trigger_event (pim_ifp, neigh, 1);
return neigh;
}
@ -682,6 +686,9 @@ void pim_neighbor_delete(struct interface *ifp,
src_str, ifp->name);
}
//De-Register PIM Neighbor with BFD
pim_bfd_trigger_event (pim_ifp, neigh, 0);
listnode_delete(pim_ifp->pim_neighbor_list, neigh);
pim_neighbor_free(neigh);

View File

@ -43,6 +43,7 @@ struct pim_neighbor {
struct thread *jp_timer;
struct list *upstream_jp_agg;
struct bfd_info *bfd_info;
};
void pim_neighbor_timer_reset(struct pim_neighbor *neigh, uint16_t holdtime);

View File

@ -22,8 +22,11 @@
#include <zebra.h>
#include <prefix.h>
#include "plist.h"
#include <pimd/pim_rpf.h>
#include "pim_str.h"
#include "pim_ifchannel.h"
#define PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED (1 << 0)
#define PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED (1 << 1)

View File

@ -38,6 +38,7 @@
#include "pim_rp.h"
#include "pim_msdp.h"
#include "pim_ssm.h"
#include "pim_bfd.h"
int
pim_debug_config_write (struct vty *vty)
@ -320,6 +321,8 @@ int pim_interface_config_write(struct vty *vty)
}
vty_out(vty, "!%s", VTY_NEWLINE);
++writes;
/* PIM BFD write */
pim_bfd_write_config (vty, ifp);
}
return writes;

View File

@ -29,6 +29,7 @@
#include "network.h"
#include "vty.h"
#include "plist.h"
#include "lib/bfd.h"
#include "pimd.h"
#include "pim_pim.h"
@ -624,6 +625,9 @@ void sched_rpf_cache_refresh(void)
static void
pim_zebra_connected (struct zclient *zclient)
{
/* Send the client registration */
bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER);
zclient_send_reg_requests (zclient, VRF_DEFAULT);
}

View File

@ -27,6 +27,7 @@
#include "plist.h"
#include "hash.h"
#include "jhash.h"
#include "vrf.h"
#include "pimd.h"
#include "pim_cmd.h"

View File

@ -115,6 +115,7 @@ struct zebra_info
{ "ospf6", ZEBRA_ROUTE_OSPF6 },
{ "bgp", ZEBRA_ROUTE_BGP },
{ "nhrp", ZEBRA_ROUTE_NHRP },
{ "pim", ZEBRA_ROUTE_PIM },
{ NULL, 0 }
};

View File

@ -1026,7 +1026,7 @@ zebra_ptm_bfd_client_deregister (int proto)
int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF;
if (proto != ZEBRA_ROUTE_OSPF && proto != ZEBRA_ROUTE_BGP
&& proto != ZEBRA_ROUTE_OSPF6)
&& proto != ZEBRA_ROUTE_OSPF6 && proto != ZEBRA_ROUTE_PIM)
return;
if (IS_ZEBRA_DEBUG_EVENT)

View File

@ -78,9 +78,9 @@ zebra_interface_bfd_update (struct interface *ifp, struct prefix *dp,
for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client))
{
/* Supporting for OSPF and BGP */
/* Supporting for OSPF, BGP and PIM */
if (client->proto != ZEBRA_ROUTE_OSPF && client->proto != ZEBRA_ROUTE_BGP
&& client->proto != ZEBRA_ROUTE_OSPF6)
&& client->proto != ZEBRA_ROUTE_OSPF6 && client->proto != ZEBRA_ROUTE_PIM)
continue;
/* Notify to the protocol daemons. */
@ -117,7 +117,8 @@ zebra_bfd_peer_replay_req (void)
/* Supporting for BGP */
if ((client->proto != ZEBRA_ROUTE_BGP) &&
(client->proto != ZEBRA_ROUTE_OSPF) &&
(client->proto != ZEBRA_ROUTE_OSPF6))
(client->proto != ZEBRA_ROUTE_OSPF6) &&
(client->proto != ZEBRA_ROUTE_PIM))
continue;
/* Notify to the protocol daemons. */