]> git.puffer.fish Git - mirror/frr.git/commitdiff
bfdd: add new counters and command to show them
authorRafael Zalamena <rzalamena@opensourcerouting.org>
Mon, 13 Aug 2018 20:47:21 +0000 (17:47 -0300)
committerRafael Zalamena <rzalamena@opensourcerouting.org>
Wed, 15 Aug 2018 20:09:54 +0000 (17:09 -0300)
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 <rzalamena@opensourcerouting.org>
bfdd/bfd.c
bfdd/bfd.h
bfdd/bfdd_vty.c
bfdd/ptm_adapter.c

index 28b6beadcbee8c5374b1e6d8ebf584372f50b699..b3253a14d75150a26a4ed1ace5f50218c390277f 100644 (file)
@@ -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)
index 40aecaa67bf2095e573fa0349b50e4d233f4ec7a..d665448abf79f1e0791db3d7bb6fd8eea525c00a 100644 (file)
@@ -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 {
index 3745658fdea96d37585c1b565acd87dc0fc8479b..ae6081f01ad360f18c50dff55e06eddaf2f38b35 100644 (file)
@@ -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 <WORD$label|<A.B.C.D|X:X::X:X>$peer [{multihop|local-address <A.B.C.D|X:X::X:X>$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);
index 9a2b70d36a64c7fa3b320c0d44f85b0f9b0dfa89..3e528b0d10d69b265931ccef32881ee12b4a6fa4 100644 (file)
@@ -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