diff options
author | Rafael Zalamena <rzalamena@opensourcerouting.org> | 2020-08-18 22:00:33 +0200 |
---|---|---|
committer | Rafael Zalamena <rzalamena@opensourcerouting.org> | 2020-11-24 11:54:07 +0100 |
commit | 400632a9a2edbdac79befb5574480db661f33213 (patch) | |
tree | 8202fa8ee0857f701e4439a64b2f5d82bbc710a1 /bfdd | |
parent | bfdd: integrate distributed BFD (diff) | |
download | frr-400632a9a2edbdac79befb5574480db661f33213.tar.xz frr-400632a9a2edbdac79befb5574480db661f33213.zip |
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>
Diffstat (limited to 'bfdd')
-rw-r--r-- | bfdd/bfd.h | 12 | ||||
-rw-r--r-- | bfdd/bfdd_vty.c | 21 | ||||
-rw-r--r-- | bfdd/dplane.c | 118 |
3 files changed, 151 insertions, 0 deletions
diff --git a/bfdd/bfd.h b/bfdd/bfd.h index 8b06ccdd0..d6e762c52 100644 --- a/bfdd/bfd.h +++ b/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_ */ diff --git a/bfdd/bfdd_vty.c b/bfdd/bfdd_vty.c index 7a00d0a02..53e23cf6c 100644 --- a/bfdd/bfdd_vty.c +++ b/bfdd/bfdd_vty.c @@ -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); diff --git a/bfdd/dplane.c b/bfdd/dplane.c index 5785c349c..f68fd2cb2 100644 --- a/bfdd/dplane.c +++ b/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; +} |