void
bgp_bfd_init(void)
{
+ bfd_gbl_init();
+
/* Initialize BFD client functions */
zclient->interface_bfd_dest_update = bgp_bfd_dest_update;
zclient->bfd_dest_replay = bgp_bfd_dest_replay;
#include "stream.h"
#include "queue.h"
#include "vrf.h"
+#include "bfd.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_attr.h"
/* it only makes sense for this to be called on a clean exit */
assert (status == 0);
+ bfd_gbl_exit();
+
bgp_close();
if (retain_mode)
#include "bfd.h"
int bfd_debug = 0;
+struct bfd_gbl bfd_gbl;
+
+/*
+ * bfd_gbl_init - Initialize the BFD global structure
+ */
+void
+bfd_gbl_init(void)
+{
+ memset(&bfd_gbl, 0, sizeof (struct bfd_gbl));
+}
+
+/*
+ * bfd_gbl_exit - Called when daemon exits
+ */
+void
+bfd_gbl_exit(void)
+{
+ SET_FLAG (bfd_gbl.flags, BFD_GBL_FLAG_IN_SHUTDOWN);
+}
/*
* bfd_info_create - Allocate the BFD information
int ret;
int len;
+ /* Individual reg/dereg messages are supressed during shutdown. */
+ if (CHECK_FLAG (bfd_gbl.flags, BFD_GBL_FLAG_IN_SHUTDOWN))
+ {
+ if (bfd_debug)
+ zlog_debug("%s: Suppressing BFD peer reg/dereg messages", __FUNCTION__);
+ return;
+ }
+
/* Check socket. */
if (!zclient || zclient->sock < 0)
{
#define BFD_MIN_DETECT_MULT 2
#define BFD_MAX_DETECT_MULT 255
+#define BFD_GBL_FLAG_IN_SHUTDOWN (1 << 0) /* The daemon in shutdown */
+struct bfd_gbl
+{
+ u_int16_t flags;
+};
+
#define BFD_FLAG_PARAM_CFG (1 << 0) /* parameters have been configured */
#define BFD_FLAG_BFD_REG (1 << 1) /* Peer registered with BFD */
#define BFD_FLAG_BFD_TYPE_MULTIHOP (1 << 2) /* Peer registered with BFD as multihop */
extern void
bfd_client_sendmsg (struct zclient *zclient, int command);
+extern void
+bfd_gbl_init(void);
+
+extern void
+bfd_gbl_exit(void);
+
#endif /* _ZEBRA_BFD_H */
void
ospf6_bfd_init(void)
{
+ bfd_gbl_init();
+
/* Initialize BFD client functions */
zclient->interface_bfd_dest_update = ospf6_bfd_interface_dest_update;
zclient->bfd_dest_replay = ospf6_bfd_nbr_replay;
#include "sigevent.h"
#include "zclient.h"
#include "vrf.h"
+#include "bfd.h"
#include "ospf6d.h"
#include "ospf6_top.h"
if (ospf6)
ospf6_delete (ospf6);
+ bfd_gbl_exit();
+
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
if (ifp->info != NULL)
ospf6_interface_delete(ifp->info);
void
ospf_bfd_init(void)
{
+ bfd_gbl_init();
+
/* Initialize BFD client functions */
zclient->interface_bfd_dest_update = ospf_bfd_interface_dest_update;
zclient->bfd_dest_replay = ospf_bfd_nbr_replay;
#include "zclient.h"
#include "plist.h"
#include "sockopt.h"
+#include "bfd.h"
#include "ospfd/ospfd.h"
#include "ospfd/ospf_network.h"
if (listcount(om->ospf) == 0)
exit(0);
+ bfd_gbl_exit();
for (ALL_LIST_ELEMENTS (om->ospf, node, nnode, ospf))
ospf_finish (ospf);
#include "zebra/interface.h"
#include "zebra/debug.h"
#include "zebra/rtadv.h"
+#include "zebra/zebra_ptm.h"
#include "rt_netlink.h"
SET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
ifp->mtu6 = ifp->mtu = *(uint32_t *) RTA_DATA (tb[IFLA_MTU]);
ifp->metric = 0;
+ ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN;
/* Hardware type and address. */
ifp->hw_type = ifi->ifi_type;
SET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
ifp->metric = 0;
+ ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN;
netlink_interface_update_hw_addr (tb, ifp);
const char ZEBRA_PTM_BFD_START_CMD[] = "start-bfd-sess";
const char ZEBRA_PTM_BFD_STOP_CMD[] = "stop-bfd-sess";
const char ZEBRA_PTM_BFD_CLIENT_REG_CMD[] = "reg-bfd-client";
+const char ZEBRA_PTM_BFD_CLIENT_DEREG_CMD[] = "dereg-bfd-client";
const char ZEBRA_PTM_CMD_STR[] = "cmd";
const char ZEBRA_PTM_CMD_STATUS_STR[] = "cmd_status";
return 0;
}
+/* BFD client deregister */
+void
+zebra_ptm_bfd_client_deregister (struct zserv *client)
+{
+ void *out_ctxt;
+ char tmp_buf[64];
+ int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF;
+
+ if (client->proto != ZEBRA_ROUTE_OSPF && client->proto != ZEBRA_ROUTE_BGP
+ && client->proto != ZEBRA_ROUTE_OSPF6)
+ return;
+
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug("bfd_client_deregister msg for client %s",
+ zebra_route_string(client->proto));
+
+ if (ptm_cb.ptm_sock == -1)
+ {
+ ptm_cb.t_timer = thread_add_timer (zebrad.master, zebra_ptm_connect,
+ NULL, ptm_cb.reconnect_time);
+ return;
+ }
+
+ ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt);
+
+ sprintf(tmp_buf, "%s", ZEBRA_PTM_BFD_CLIENT_DEREG_CMD);
+ ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_CMD_STR, tmp_buf);
+
+ sprintf(tmp_buf, "%s", zebra_route_string(client->proto));
+ ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD,
+ tmp_buf);
+
+ ptm_lib_complete_msg(ptm_hdl, out_ctxt, ptm_cb.out_data, &data_len);
+
+ if (IS_ZEBRA_DEBUG_SEND)
+ zlog_debug ("%s: Sent message (%d) %s", __func__, data_len,
+ ptm_cb.out_data);
+ zebra_ptm_send_message(ptm_cb.out_data, data_len);
+}
+
int
zebra_ptm_get_enable_state(void)
{
void zebra_ptm_if_init(struct zebra_if *zebra_ifp);
void zebra_ptm_if_set_ptm_state(struct interface *ifp, struct zebra_if *zebra_ifp);
void zebra_ptm_if_write (struct vty *vty, struct zebra_if *zebra_ifp);
+void zebra_ptm_bfd_client_deregister (struct zserv *client);
#endif
static void
zebra_client_close (struct zserv *client)
{
+ /* Send client de-registration to BFD */
+ zebra_ptm_bfd_client_deregister(client);
+
/* Cleanup any registered nexthops - across all VRFs. */
zebra_client_close_cleanup_rnh (client);