mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 10:54:47 +00:00
bfdd: distributed BFD show commands
Show BFD sessions updated counters by asking the data plane for this information and show data plane statistics. Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
This commit is contained in:
parent
efd04d60ca
commit
400632a9a2
12
bfdd/bfd.h
12
bfdd/bfd.h
@ -794,4 +794,16 @@ int bfd_dplane_update_session(const struct bfd_session *bs);
|
||||
*/
|
||||
int bfd_dplane_delete_session(struct bfd_session *bs);
|
||||
|
||||
/**
|
||||
* Asks the data plane for updated counters and update the session data
|
||||
* structure.
|
||||
*
|
||||
* \param bs the BFD session that needs updating.
|
||||
*
|
||||
* \returns `0` on success otherwise `-1` on failure.
|
||||
*/
|
||||
int bfd_dplane_update_session_counters(struct bfd_session *bs);
|
||||
|
||||
void bfd_dplane_show_counters(struct vty *vty);
|
||||
|
||||
#endif /* _BFD_H_ */
|
||||
|
@ -348,6 +348,11 @@ static void _display_peer_counter(struct vty *vty, struct bfd_session *bs)
|
||||
{
|
||||
_display_peer_header(vty, bs);
|
||||
|
||||
/* Ask data plane for updated counters. */
|
||||
if (bfd_dplane_update_session_counters(bs) == -1)
|
||||
zlog_debug("%s: failed to update BFD session counters (%s)",
|
||||
__func__, bs_to_string(bs));
|
||||
|
||||
vty_out(vty, "\t\tControl packet input: %" PRIu64 " packets\n",
|
||||
bs->stats.rx_ctrl_pkt);
|
||||
vty_out(vty, "\t\tControl packet output: %" PRIu64 " packets\n",
|
||||
@ -369,6 +374,11 @@ static struct json_object *__display_peer_counters_json(struct bfd_session *bs)
|
||||
{
|
||||
struct json_object *jo = _peer_json_header(bs);
|
||||
|
||||
/* Ask data plane for updated counters. */
|
||||
if (bfd_dplane_update_session_counters(bs) == -1)
|
||||
zlog_debug("%s: failed to update BFD session counters (%s)",
|
||||
__func__, bs_to_string(bs));
|
||||
|
||||
json_object_int_add(jo, "control-packet-input", bs->stats.rx_ctrl_pkt);
|
||||
json_object_int_add(jo, "control-packet-output", bs->stats.tx_ctrl_pkt);
|
||||
json_object_int_add(jo, "echo-packet-input", bs->stats.rx_echo_pkt);
|
||||
@ -748,6 +758,16 @@ DEFPY(bfd_show_peers_brief, bfd_show_peers_brief_cmd,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFPY(show_bfd_distributed, show_bfd_distributed_cmd,
|
||||
"show bfd distributed",
|
||||
SHOW_STR
|
||||
"Bidirection Forwarding Detection\n"
|
||||
"Show BFD data plane (distributed BFD) statistics\n")
|
||||
{
|
||||
bfd_dplane_show_counters(vty);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFPY(
|
||||
bfd_debug_distributed, bfd_debug_distributed_cmd,
|
||||
"[no] debug bfd distributed",
|
||||
@ -970,6 +990,7 @@ void bfdd_vty_init(void)
|
||||
install_element(ENABLE_NODE, &bfd_show_peers_cmd);
|
||||
install_element(ENABLE_NODE, &bfd_show_peer_cmd);
|
||||
install_element(ENABLE_NODE, &bfd_show_peers_brief_cmd);
|
||||
install_element(ENABLE_NODE, &show_bfd_distributed_cmd);
|
||||
install_element(ENABLE_NODE, &show_debugging_bfd_cmd);
|
||||
|
||||
install_element(ENABLE_NODE, &bfd_debug_distributed_cmd);
|
||||
|
118
bfdd/dplane.c
118
bfdd/dplane.c
@ -244,6 +244,24 @@ static void bfd_dplane_debug_message(const struct bfddp_message *msg)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next unused non zero identification.
|
||||
*
|
||||
* \param bdc the data plane context.
|
||||
*
|
||||
* \returns next usable id.
|
||||
*/
|
||||
static uint16_t bfd_dplane_next_id(struct bfd_dplane_ctx *bdc)
|
||||
{
|
||||
bdc->last_id++;
|
||||
|
||||
/* Don't use reserved id `0`. */
|
||||
if (bdc->last_id == 0)
|
||||
bdc->last_id = 1;
|
||||
|
||||
return bdc->last_id;
|
||||
}
|
||||
|
||||
static ssize_t bfd_dplane_flush(struct bfd_dplane_ctx *bdc)
|
||||
{
|
||||
ssize_t total = 0;
|
||||
@ -717,6 +735,52 @@ static int _bfd_dplane_add_session(struct bfd_dplane_ctx *bdc,
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void _bfd_dplane_update_session_counters(struct bfddp_message *msg,
|
||||
void *arg)
|
||||
{
|
||||
struct bfd_session *bs = arg;
|
||||
|
||||
bs->stats.rx_ctrl_pkt =
|
||||
be64toh(msg->data.session_counters.control_input_packets);
|
||||
bs->stats.tx_ctrl_pkt =
|
||||
be64toh(msg->data.session_counters.control_output_packets);
|
||||
bs->stats.rx_echo_pkt =
|
||||
be64toh(msg->data.session_counters.echo_input_packets);
|
||||
bs->stats.tx_echo_pkt =
|
||||
be64toh(msg->data.session_counters.echo_output_bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send message to data plane requesting the session counters.
|
||||
*
|
||||
* \param bs the BFD session.
|
||||
*
|
||||
* \returns `0` on failure or the request id.
|
||||
*/
|
||||
static uint16_t bfd_dplane_request_counters(const struct bfd_session *bs)
|
||||
{
|
||||
struct bfddp_message msg = {};
|
||||
size_t msglen = sizeof(msg.header) + sizeof(msg.data.counters_req);
|
||||
|
||||
/* Fill header information. */
|
||||
msg.header.version = BFD_DP_VERSION;
|
||||
msg.header.length = htons(msglen);
|
||||
msg.header.type = htons(DP_REQUEST_SESSION_COUNTERS);
|
||||
msg.header.id = htons(bfd_dplane_next_id(bs->bdc));
|
||||
|
||||
/* Session to get counters. */
|
||||
msg.data.counters_req.lid = htonl(bs->discrs.my_discr);
|
||||
|
||||
/* If enqueue failed, let caller know. */
|
||||
if (bfd_dplane_enqueue(bs->bdc, &msg, msglen) == -1)
|
||||
return 0;
|
||||
|
||||
/* Flush socket. */
|
||||
bfd_dplane_flush(bs->bdc);
|
||||
|
||||
return ntohs(msg.header.id);
|
||||
}
|
||||
|
||||
/*
|
||||
* Data plane listening socket.
|
||||
*/
|
||||
@ -876,3 +940,57 @@ int bfd_dplane_delete_session(struct bfd_session *bs)
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Data plane CLI.
|
||||
*/
|
||||
void bfd_dplane_show_counters(struct vty *vty)
|
||||
{
|
||||
struct bfd_dplane_ctx *bdc;
|
||||
|
||||
#define SHOW_COUNTER(label, counter, formatter) \
|
||||
vty_out(vty, "%28s: %" formatter "\n", (label), (counter))
|
||||
|
||||
vty_out(vty, "%28s\n%28s\n", "Data plane", "==========");
|
||||
TAILQ_FOREACH (bdc, &bglobal.bg_dplaneq, entry) {
|
||||
SHOW_COUNTER("File descriptor", bdc->sock, "d");
|
||||
SHOW_COUNTER("Input bytes", bdc->in_bytes, PRIu64);
|
||||
SHOW_COUNTER("Input bytes peak", bdc->in_bytes_peak, PRIu64);
|
||||
SHOW_COUNTER("Input messages", bdc->in_msgs, PRIu64);
|
||||
SHOW_COUNTER("Input current usage", STREAM_READABLE(bdc->inbuf),
|
||||
"zu");
|
||||
SHOW_COUNTER("Output bytes", bdc->out_bytes, PRIu64);
|
||||
SHOW_COUNTER("Output bytes peak", bdc->out_bytes_peak, PRIu64);
|
||||
SHOW_COUNTER("Output messages", bdc->out_msgs, PRIu64);
|
||||
SHOW_COUNTER("Output full events", bdc->out_fullev, PRIu64);
|
||||
SHOW_COUNTER("Output current usage",
|
||||
STREAM_READABLE(bdc->inbuf), "zu");
|
||||
vty_out(vty, "\n");
|
||||
}
|
||||
#undef SHOW_COUNTER
|
||||
}
|
||||
|
||||
int bfd_dplane_update_session_counters(struct bfd_session *bs)
|
||||
{
|
||||
uint16_t id;
|
||||
int rv;
|
||||
|
||||
/* If session is not using data plane, then just return success. */
|
||||
if (bs->bdc == NULL)
|
||||
return 0;
|
||||
|
||||
/* Make the request. */
|
||||
id = bfd_dplane_request_counters(bs);
|
||||
if (id == 0) {
|
||||
zlog_debug("%s: counters request failed", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Handle interruptions. */
|
||||
do {
|
||||
rv = bfd_dplane_expect(bs->bdc, id,
|
||||
_bfd_dplane_update_session_counters, bs);
|
||||
} while (rv == -2);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user