diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c index 6679206de9..3f5c4d0257 100644 --- a/bgpd/bgp_bfd.c +++ b/bgpd/bgp_bfd.c @@ -185,6 +185,9 @@ bgp_bfd_dest_replay (int command, struct zclient *client, zebra_size_t length, if (BGP_DEBUG (zebra, ZEBRA)) zlog_debug("Zebra: BFD Dest replay request"); + /* Send the client registration */ + bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER); + /* Replay the peer, if BFD is enabled in BGP */ for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp)) @@ -524,4 +527,7 @@ bgp_bfd_init(void) install_element (BGP_NODE, &neighbor_bfd_param_cmd); install_element (BGP_NODE, &no_neighbor_bfd_cmd); install_element (BGP_NODE, &no_neighbor_bfd_val_cmd); + + /* Send the client registration */ + bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER); } diff --git a/lib/bfd.c b/lib/bfd.c index 530086b1bd..e057bb05bf 100644 --- a/lib/bfd.c +++ b/lib/bfd.c @@ -138,6 +138,8 @@ bfd_peer_sendmsg (struct zclient *zclient, struct bfd_info *bfd_info, stream_reset (s); zclient_create_header (s, command, vrf_id); + stream_putl(s, getpid()); + stream_putw(s, family); switch (family) { @@ -436,3 +438,41 @@ bfd_show_info(struct vty *vty, struct bfd_info *bfd_info, int multihop, else vty_out (vty, "%s", VTY_NEWLINE); } + +/* + * bfd_client_sendmsg - Format and send a client register + * command to Zebra to be forwarded to BFD + */ +void +bfd_client_sendmsg (struct zclient *zclient, int command) +{ + struct stream *s; + int ret; + + /* Check socket. */ + if (!zclient || zclient->sock < 0) + { + zlog_debug("%s: Can't send BFD client register, Zebra client not " + "established", __FUNCTION__); + return; + } + + s = zclient->obuf; + stream_reset (s); + zclient_create_header (s, command, VRF_DEFAULT); + + stream_putl(s, getpid()); + + stream_putw_at (s, 0, stream_get_endp (s)); + + ret = zclient_send_message(zclient); + + if (ret < 0) + { + zlog_warn("bfd_client_sendmsg %d: zclient_send_message() failed", + getpid()); + return; + } + + return; +} diff --git a/lib/bfd.h b/lib/bfd.h index 3cae1a5219..31eb4ad9a3 100644 --- a/lib/bfd.h +++ b/lib/bfd.h @@ -95,4 +95,7 @@ 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); +extern void +bfd_client_sendmsg (struct zclient *zclient, int command); + #endif /* _ZEBRA_BFD_H */ diff --git a/lib/log.c b/lib/log.c index fefc0db526..b031206a21 100644 --- a/lib/log.c +++ b/lib/log.c @@ -875,7 +875,8 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY (ZEBRA_REDISTRIBUTE_IPV4_DEL), DESC_ENTRY (ZEBRA_REDISTRIBUTE_IPV6_ADD), DESC_ENTRY (ZEBRA_REDISTRIBUTE_IPV6_DEL), - DESC_ENTRY (ZEBRA_INTERFACE_VRF_UPDATE) + DESC_ENTRY (ZEBRA_INTERFACE_VRF_UPDATE), + DESC_ENTRY (ZEBRA_BFD_CLIENT_REGISTER) }; #undef DESC_ENTRY diff --git a/lib/zebra.h b/lib/zebra.h index 2945f15194..f49db41d26 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -446,7 +446,8 @@ struct in_pktinfo #define ZEBRA_VRF_ADD 43 #define ZEBRA_VRF_DELETE 44 #define ZEBRA_INTERFACE_VRF_UPDATE 45 -#define ZEBRA_MESSAGE_MAX 46 +#define ZEBRA_BFD_CLIENT_REGISTER 46 +#define ZEBRA_MESSAGE_MAX 47 /* Marker value used in new Zserv, in the byte location corresponding * the command value in the old zserv header. To allow old and new diff --git a/ospf6d/ospf6_bfd.c b/ospf6d/ospf6_bfd.c index 25bacd0d22..f44dd5c0e6 100644 --- a/ospf6d/ospf6_bfd.c +++ b/ospf6d/ospf6_bfd.c @@ -145,7 +145,7 @@ ospf6_bfd_reg_dereg_all_nbr (struct ospf6_interface *oi, int command) * to zebra */ static int -ospf6_bfd_nbr_replay (int command, struct zclient *client, zebra_size_t length, +ospf6_bfd_nbr_replay (int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct listnode *inode, *nnode; @@ -157,6 +157,9 @@ ospf6_bfd_nbr_replay (int command, struct zclient *client, zebra_size_t length, if (IS_OSPF6_DEBUG_ZEBRA(RECV)) zlog_debug("Zebra: BFD Dest replay request"); + /* Send the client registration */ + bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER); + /* Replay the neighbor, if BFD is enabled on the interface*/ for (ALL_LIST_ELEMENTS_RO (iflist, inode, ifp)) { @@ -415,4 +418,7 @@ ospf6_bfd_init(void) install_element (INTERFACE_NODE, &ipv6_ospf6_bfd_cmd); install_element (INTERFACE_NODE, &ipv6_ospf6_bfd_param_cmd); install_element (INTERFACE_NODE, &no_ipv6_ospf6_bfd_cmd); + + /* Send the client registration */ + bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER); } diff --git a/ospfd/ospf_bfd.c b/ospfd/ospf_bfd.c index 8e70b2479c..1a461e48b6 100644 --- a/ospfd/ospf_bfd.c +++ b/ospfd/ospf_bfd.c @@ -147,7 +147,7 @@ ospf_bfd_reg_dereg_all_nbr (struct interface *ifp, int command) * to zebra */ static int -ospf_bfd_nbr_replay (int command, struct zclient *client, zebra_size_t length, +ospf_bfd_nbr_replay (int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct listnode *inode, *node, *onode; @@ -163,6 +163,9 @@ ospf_bfd_nbr_replay (int command, struct zclient *client, zebra_size_t length, zlog_debug("Zebra: BFD Dest replay request"); } + /* Send the client registration */ + bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER); + /* Replay the neighbor, if BFD is enabled in BGP */ for (ALL_LIST_ELEMENTS (om->ospf, node, onode, ospf)) { @@ -447,4 +450,7 @@ ospf_bfd_init(void) install_element (INTERFACE_NODE, &ip_ospf_bfd_param_cmd); install_element (INTERFACE_NODE, &no_ip_ospf_bfd_cmd); install_element (INTERFACE_NODE, &no_ip_ospf_bfd_param_cmd); + + /* Send the client registration */ + bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER); } diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index 8e20226cb0..f32fedd9f6 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -45,6 +45,7 @@ const char ZEBRA_PTM_GET_STATUS_CMD[] = "get-status"; 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_CMD_STR[] = "cmd"; const char ZEBRA_PTM_CMD_STATUS_STR[] = "cmd_status"; @@ -572,6 +573,7 @@ zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length, char tmp_buf[64]; int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF; struct zebra_vrf *zvrf; + unsigned int pid; if (command == ZEBRA_BFD_DEST_UPDATE) client->bfd_peer_upd8_cnt++; @@ -592,15 +594,16 @@ zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length, ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); sprintf(tmp_buf, "%s", ZEBRA_PTM_BFD_START_CMD); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_CMD_STR, tmp_buf); - sprintf(tmp_buf, "quagga"); + sprintf(tmp_buf, "%s", zebra_route_string(client->proto)); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD, tmp_buf); - sprintf(tmp_buf, "%d", ptm_cb.pid); - ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEQID_FIELD, - tmp_buf); s = client->ibuf; + pid = stream_getl(s); + sprintf(tmp_buf, "%d", pid); + ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEQID_FIELD, tmp_buf); + dst_p.family = stream_getw(s); if (dst_p.family == AF_INET) @@ -741,6 +744,7 @@ zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock, u_short length, int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF; void *out_ctxt; struct zebra_vrf *zvrf; + unsigned int pid; client->bfd_peer_del_cnt++; @@ -760,16 +764,16 @@ zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock, u_short length, sprintf(tmp_buf, "%s", ZEBRA_PTM_BFD_STOP_CMD); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_CMD_STR, tmp_buf); - sprintf(tmp_buf, "%s", "quagga"); + sprintf(tmp_buf, "%s", zebra_route_string(client->proto)); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD, tmp_buf); - sprintf(tmp_buf, "%d", ptm_cb.pid); - ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEQID_FIELD, - tmp_buf); - s = client->ibuf; + pid = stream_getl(s); + sprintf(tmp_buf, "%d", pid); + ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEQID_FIELD, tmp_buf); + dst_p.family = stream_getw(s); if (dst_p.family == AF_INET) @@ -873,6 +877,54 @@ zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock, u_short length, return 0; } +/* BFD client register */ +int +zebra_ptm_bfd_client_register (struct zserv *client, int sock, u_short length) +{ + struct stream *s; + unsigned int pid; + void *out_ctxt; + char tmp_buf[64]; + int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF; + + client->bfd_client_reg_cnt++; + + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug("bfd_client_register msg from client %s: length=%d", + zebra_route_string(client->proto), length); + + if (ptm_cb.ptm_sock == -1) + { + ptm_cb.t_timer = thread_add_timer (zebrad.master, zebra_ptm_connect, + NULL, ptm_cb.reconnect_time); + return -1; + } + + ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); + + sprintf(tmp_buf, "%s", ZEBRA_PTM_BFD_CLIENT_REG_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); + + s = client->ibuf; + + pid = stream_getl(s); + sprintf(tmp_buf, "%d", pid); + ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEQID_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); + return 0; +} + int zebra_ptm_get_enable_state(void) { diff --git a/zebra/zebra_ptm.h b/zebra/zebra_ptm.h index 15a4228298..4914fc0351 100644 --- a/zebra/zebra_ptm.h +++ b/zebra/zebra_ptm.h @@ -62,4 +62,6 @@ int zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock, u_short length, vrf_id_t vrf_id); void zebra_ptm_show_status(struct vty *vty, struct interface *ifp); +int zebra_ptm_bfd_client_register (struct zserv *client, int sock, + u_short length); #endif diff --git a/zebra/zserv.c b/zebra/zserv.c index 3d5cbec03c..863622d4b1 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -2076,6 +2076,9 @@ zebra_client_read (struct thread *thread) case ZEBRA_VRF_UNREGISTER: zread_vrf_unregister (client, length, vrf_id); break; + case ZEBRA_BFD_CLIENT_REGISTER: + zebra_ptm_bfd_client_register(client, sock, length); + break; default: zlog_info ("Zebra received unknown command %d", command); break; diff --git a/zebra/zserv.h b/zebra/zserv.h index f3e7a3b883..0a9b2cbbd4 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -103,6 +103,7 @@ struct zserv u_int32_t vrfadd_cnt; u_int32_t vrfdel_cnt; u_int32_t if_vrfchg_cnt; + u_int32_t bfd_client_reg_cnt; time_t connect_time; time_t last_read_time;