From 0684c9b12ca78d61c2ba5788175a6eaa9bb702f3 Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Mon, 13 Aug 2018 17:47:21 -0300 Subject: [PATCH] bfdd: add new counters and command to show them Added 3 new counters to BFD sessions: * Session up events count; * Session down events count; * Zebra notifications count; In addition to previosly available counters: * Count of received control packets; * Count of transmitted control packets; * Count of received echo packets; * Count of transmitted echo packets; With this count we are able to visualize the BFD activity, bandwidth usage, interface/network flapping and excess of zebra notifications. Signed-off-by: Rafael Zalamena --- bfdd/bfd.c | 8 ++- bfdd/bfd.h | 3 + bfdd/bfdd_vty.c | 139 +++++++++++++++++++++++++++++++++++++++++++++ bfdd/ptm_adapter.c | 2 + 4 files changed, 150 insertions(+), 2 deletions(-) diff --git a/bfdd/bfd.c b/bfdd/bfd.c index 28b6beadcb..b3253a14d7 100644 --- a/bfdd/bfd.c +++ b/bfdd/bfd.c @@ -185,10 +185,12 @@ void ptm_bfd_ses_up(struct bfd_session *bfd) control_notify(bfd); - if (old_state != bfd->ses_state) + if (old_state != bfd->ses_state) { + bfd->stats.session_up++; log_info("state-change: [%s] %s -> %s", bs_to_string(bfd), state_list[old_state].str, state_list[bfd->ses_state].str); + } } void ptm_bfd_ses_dn(struct bfd_session *bfd, uint8_t diag) @@ -212,11 +214,13 @@ void ptm_bfd_ses_dn(struct bfd_session *bfd, uint8_t diag) if (BFD_CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE)) ptm_bfd_echo_stop(bfd, 0); - if (old_state != bfd->ses_state) + if (old_state != bfd->ses_state) { + bfd->stats.session_down++; log_info("state-change: [%s] %s -> %s reason:%s", bs_to_string(bfd), state_list[old_state].str, state_list[bfd->ses_state].str, get_diag_str(bfd->local_diag)); + } } static int ptm_bfd_get_vrf_name(char *port_name, char *vrf_name) diff --git a/bfdd/bfd.h b/bfdd/bfd.h index 40aecaa67b..d665448abf 100644 --- a/bfdd/bfd.h +++ b/bfdd/bfd.h @@ -186,6 +186,9 @@ struct bfd_session_stats { uint64_t tx_ctrl_pkt; uint64_t rx_echo_pkt; uint64_t tx_echo_pkt; + uint64_t session_up; + uint64_t session_down; + uint64_t znotification; }; struct bfd_session_vxlan_info { diff --git a/bfdd/bfdd_vty.c b/bfdd/bfdd_vty.c index 3745658fde..ae6081f01a 100644 --- a/bfdd/bfdd_vty.c +++ b/bfdd/bfdd_vty.c @@ -66,6 +66,12 @@ static void _display_peer(struct vty *vty, struct bfd_session *bs); static void _display_all_peers(struct vty *vty, bool use_json); static void _display_peer_iter(struct hash_backet *hb, void *arg); static void _display_peer_json_iter(struct hash_backet *hb, void *arg); +static void _display_peer_counter(struct vty *vty, struct bfd_session *bs); +static struct json_object *__display_peer_counters_json(struct bfd_session *bs); +static void _display_peer_counters_json(struct vty *vty, struct bfd_session *bs); +static void _display_peer_counter_iter(struct hash_backet *hb, void *arg); +static void _display_peer_counter_json_iter(struct hash_backet *hb, void *arg); +static void _display_peers_counter(struct vty *vty, bool use_json); static struct bfd_session * _find_peer_or_error(struct vty *vty, int argc, struct cmd_token **argv, const char *label, const char *peer_str, @@ -581,6 +587,89 @@ static void _display_all_peers(struct vty *vty, bool use_json) json_object_free(jo); } +static void _display_peer_counter(struct vty *vty, struct bfd_session *bs) +{ + _display_peer_header(vty, 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", + bs->stats.tx_ctrl_pkt); + vty_out(vty, "\t\tEcho packet input: %" PRIu64 " packets\n", + bs->stats.rx_echo_pkt); + vty_out(vty, "\t\tEcho packet output: %" PRIu64 " packets\n", + bs->stats.tx_echo_pkt); + vty_out(vty, "\t\tSession up events: %" PRIu64 "\n", + bs->stats.session_up); + vty_out(vty, "\t\tSession down events: %" PRIu64 "\n", + bs->stats.session_down); + vty_out(vty, "\t\tZebra notifications: %" PRIu64 "\n", + bs->stats.znotification); + vty_out(vty, "\n"); +} + +static struct json_object *__display_peer_counters_json(struct bfd_session *bs) +{ + struct json_object *jo = _peer_json_header(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); + json_object_int_add(jo, "echo-packet-output", bs->stats.tx_echo_pkt); + json_object_int_add(jo, "session-up", bs->stats.session_up); + json_object_int_add(jo, "session-down", bs->stats.session_down); + json_object_int_add(jo, "zebra-notifications", bs->stats.znotification); + + return jo; +} + +static void _display_peer_counters_json(struct vty *vty, struct bfd_session *bs) +{ + struct json_object *jo = __display_peer_counters_json(bs); + + vty_out(vty, "%s\n", json_object_to_json_string_ext(jo, 0)); + json_object_free(jo); +} + +static void _display_peer_counter_iter(struct hash_backet *hb, void *arg) +{ + struct vty *vty = arg; + struct bfd_session *bs = hb->data; + + _display_peer_counter(vty, bs); +} + +static void _display_peer_counter_json_iter(struct hash_backet *hb, void *arg) +{ + struct json_object *jo = arg, *jon = NULL; + struct bfd_session *bs = hb->data; + + jon = __display_peer_counters_json(bs); + if (jon == NULL) { + log_warning("%s: not enough memory", __func__); + return; + } + + json_object_array_add(jo, jon); +} + +static void _display_peers_counter(struct vty *vty, bool use_json) +{ + struct json_object *jo; + + if (use_json == false) { + vty_out(vty, "BFD Peers:\n"); + bfd_id_iterate(_display_peer_counter_iter, vty); + return; + } + + jo = json_object_new_array(); + bfd_id_iterate(_display_peer_counter_json_iter, jo); + + vty_out(vty, "%s\n", json_object_to_json_string_ext(jo, 0)); + json_object_free(jo); +} + static struct bfd_session * _find_peer_or_error(struct vty *vty, int argc, struct cmd_token **argv, const char *label, const char *peer_str, @@ -681,6 +770,54 @@ DEFPY(bfd_show_peer, bfd_show_peer_cmd, return CMD_SUCCESS; } +DEFPY(bfd_show_peer_counters, bfd_show_peer_counters_cmd, + "show bfd peer $peer [{multihop|local-address $local|interface IFNAME$ifname|vrf NAME$vrfname}]> counters [json]", + SHOW_STR + "Bidirection Forwarding Detection\n" + "BFD peers status\n" + "Peer label\n" + PEER_IPV4_STR + PEER_IPV6_STR + MHOP_STR + LOCAL_STR + LOCAL_IPV4_STR + LOCAL_IPV6_STR + INTERFACE_STR + LOCAL_INTF_STR + VRF_STR + VRF_NAME_STR + "Show BFD peer counters information\n" + JSON_STR) +{ + struct bfd_session *bs; + + /* Look up the BFD peer. */ + bs = _find_peer_or_error(vty, argc, argv, label, peer_str, local_str, + ifname, vrfname); + if (bs == NULL) + return CMD_WARNING_CONFIG_FAILED; + + if (use_json(argc, argv)) + _display_peer_counters_json(vty, bs); + else + _display_peer_counter(vty, bs); + + return CMD_SUCCESS; +} + +DEFPY(bfd_show_peers_counters, bfd_show_peers_counters_cmd, + "show bfd peers counters [json]", + SHOW_STR + "Bidirection Forwarding Detection\n" + "BFD peers status\n" + "Show BFD peer counters information\n" + JSON_STR) +{ + _display_peers_counter(vty, use_json(argc, argv)); + + return CMD_SUCCESS; +} + /* * Function definitions. @@ -875,6 +1012,8 @@ struct cmd_node bfd_peer_node = { void bfdd_vty_init(void) { + install_element(ENABLE_NODE, &bfd_show_peers_counters_cmd); + install_element(ENABLE_NODE, &bfd_show_peer_counters_cmd); install_element(ENABLE_NODE, &bfd_show_peers_cmd); install_element(ENABLE_NODE, &bfd_show_peer_cmd); install_element(CONFIG_NODE, &bfd_enter_cmd); diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c index 9a2b70d36a..3e528b0d10 100644 --- a/bfdd/ptm_adapter.c +++ b/bfdd/ptm_adapter.c @@ -155,6 +155,8 @@ int ptm_bfd_notify(struct bfd_session *bs) struct stream *msg; struct sockaddr_any sac; + bs->stats.znotification++; + /* * Message format: * - header: command, vrf -- 2.39.5