diff options
| -rw-r--r-- | bfdd/bfd.c | 5 | ||||
| -rw-r--r-- | bfdd/bfd.h | 2 | ||||
| -rw-r--r-- | bfdd/bfdd_vty.c | 153 |
3 files changed, 155 insertions, 5 deletions
diff --git a/bfdd/bfd.c b/bfdd/bfd.c index cc171f2ebf..920e3fdeea 100644 --- a/bfdd/bfd.c +++ b/bfdd/bfd.c @@ -1852,3 +1852,8 @@ void bfd_session_update_vrf_name(struct bfd_session *bs, struct vrf *vrf) strlcpy(bs->key.vrfname, vrf->name, sizeof(bs->key.vrfname)); hash_get(bfd_key_hash, bs, hash_alloc_intern); } + +unsigned long bfd_get_session_count(void) +{ + return bfd_key_hash->count; +} diff --git a/bfdd/bfd.h b/bfdd/bfd.h index ac413cafc3..97702aab54 100644 --- a/bfdd/bfd.h +++ b/bfdd/bfd.h @@ -567,6 +567,8 @@ typedef void (*hash_iter_func)(struct hash_bucket *hb, void *arg); void bfd_id_iterate(hash_iter_func hif, void *arg); void bfd_key_iterate(hash_iter_func hif, void *arg); +unsigned long bfd_get_session_count(void); + /* Export callback functions for `event.c`. */ extern struct thread_master *master; diff --git a/bfdd/bfdd_vty.c b/bfdd/bfdd_vty.c index c98ae5c7b3..e6307f78a4 100644 --- a/bfdd/bfdd_vty.c +++ b/bfdd/bfdd_vty.c @@ -142,8 +142,12 @@ static void _display_peer(struct vty *vty, struct bfd_session *bs) vty_out(vty, "\t\tDiagnostics: %s\n", diag2str(bs->local_diag)); vty_out(vty, "\t\tRemote diagnostics: %s\n", diag2str(bs->remote_diag)); + vty_out(vty, "\t\tPeer Type: %s\n", + BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_CONFIG) ? "configured" : "dynamic"); vty_out(vty, "\t\tLocal timers:\n"); + vty_out(vty, "\t\t\tDetect-multiplier: %" PRIu32 "\n", + bs->detect_mult); vty_out(vty, "\t\t\tReceive interval: %" PRIu32 "ms\n", bs->timers.required_min_rx / 1000); vty_out(vty, "\t\t\tTransmission interval: %" PRIu32 "ms\n", @@ -152,6 +156,8 @@ static void _display_peer(struct vty *vty, struct bfd_session *bs) bs->timers.required_min_echo / 1000); vty_out(vty, "\t\tRemote timers:\n"); + vty_out(vty, "\t\t\tDetect-multiplier: %" PRIu32 "\n", + bs->remote_detect_mult); vty_out(vty, "\t\t\tReceive interval: %" PRIu32 "ms\n", bs->remote_timers.required_min_rx / 1000); vty_out(vty, "\t\t\tTransmission interval: %" PRIu32 "ms\n", @@ -235,12 +241,16 @@ static struct json_object *__display_peer_json(struct bfd_session *bs) else json_object_int_add(jo, "echo-interval", 0); + json_object_int_add(jo, "detect-multiplier", bs->detect_mult); + json_object_int_add(jo, "remote-receive-interval", bs->remote_timers.required_min_rx / 1000); json_object_int_add(jo, "remote-transmit-interval", bs->remote_timers.desired_min_tx / 1000); json_object_int_add(jo, "remote-echo-interval", bs->remote_timers.required_min_echo / 1000); + json_object_int_add(jo, "remote-detect-multiplier", + bs->remote_detect_mult); return jo; } @@ -254,7 +264,7 @@ static void _display_peer_json(struct vty *vty, struct bfd_session *bs) } struct bfd_vrf_tuple { - char *vrfname; + const char *vrfname; struct vty *vty; struct json_object *jo; }; @@ -305,9 +315,8 @@ static void _display_peer_json_iter(struct hash_bucket *hb, void *arg) static void _display_all_peers(struct vty *vty, char *vrfname, bool use_json) { struct json_object *jo; - struct bfd_vrf_tuple bvt; + struct bfd_vrf_tuple bvt = {0}; - memset(&bvt, 0, sizeof(bvt)); bvt.vrfname = vrfname; if (!use_json) { @@ -416,9 +425,8 @@ static void _display_peer_counter_json_iter(struct hash_bucket *hb, void *arg) static void _display_peers_counter(struct vty *vty, char *vrfname, bool use_json) { struct json_object *jo; - struct bfd_vrf_tuple bvt; + struct bfd_vrf_tuple bvt = {0}; - memset(&bvt, 0, sizeof(struct bfd_vrf_tuple)); bvt.vrfname = vrfname; if (!use_json) { bvt.vty = vty; @@ -435,6 +443,90 @@ static void _display_peers_counter(struct vty *vty, char *vrfname, bool use_json json_object_free(jo); } +static void _clear_peer_counter(struct bfd_session *bs) +{ + /* Clear only pkt stats, intention is not to loose system + events counters */ + bs->stats.rx_ctrl_pkt = 0; + bs->stats.tx_ctrl_pkt = 0; + bs->stats.rx_echo_pkt = 0; + bs->stats.tx_echo_pkt = 0; +} + +static void _display_peer_brief(struct vty *vty, struct bfd_session *bs) +{ + char addr_buf[INET6_ADDRSTRLEN]; + + if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH)) { + vty_out(vty, "%-10u", bs->discrs.my_discr); + inet_ntop(bs->key.family, &bs->key.local, addr_buf, sizeof(addr_buf)); + vty_out(vty, " %-40s", addr_buf); + inet_ntop(bs->key.family, &bs->key.peer, addr_buf, sizeof(addr_buf)); + vty_out(vty, " %-40s", addr_buf); + vty_out(vty, "%-15s\n", state_list[bs->ses_state].str); + } else { + vty_out(vty, "%-10u", bs->discrs.my_discr); + vty_out(vty, " %-40s", satostr(&bs->local_address)); + inet_ntop(bs->key.family, &bs->key.peer, addr_buf, sizeof(addr_buf)); + vty_out(vty, " %-40s", addr_buf); + + vty_out(vty, "%-15s\n", state_list[bs->ses_state].str); + } +} + +static void _display_peer_brief_iter(struct hash_backet *hb, void *arg) +{ + struct bfd_vrf_tuple *bvt = arg; + struct vty *vty; + struct bfd_session *bs = hb->data; + + if (!bvt) + return; + vty = bvt->vty; + + if (bvt->vrfname) { + if (!bs->key.vrfname[0] || + !strmatch(bs->key.vrfname, bvt->vrfname)) + return; + } + + _display_peer_brief(vty, bs); +} + +static void _display_peers_brief(struct vty *vty, const char *vrfname, bool use_json) +{ + struct json_object *jo; + struct bfd_vrf_tuple bvt = {0}; + + bvt.vrfname = vrfname; + + if (use_json == false) { + bvt.vty = vty; + + vty_out(vty, "Session count: %lu\n", bfd_get_session_count()); + vty_out(vty, "%-10s", "SessionId"); + vty_out(vty, " %-40s", "LocalAddress"); + vty_out(vty, " %-40s", "PeerAddress"); + vty_out(vty, "%-15s\n", "Status"); + + vty_out(vty, "%-10s", "========="); + vty_out(vty, " %-40s", "============"); + vty_out(vty, " %-40s", "==========="); + vty_out(vty, "%-15s\n", "======"); + + bfd_id_iterate(_display_peer_brief_iter, &bvt); + return; + } + + jo = json_object_new_array(); + bvt.jo = jo; + + bfd_id_iterate(_display_peer_json_iter, &bvt); + + 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, @@ -596,6 +688,55 @@ DEFPY(bfd_show_peers_counters, bfd_show_peers_counters_cmd, return CMD_SUCCESS; } +DEFPY(bfd_clear_peer_counters, bfd_clear_peer_counters_cmd, + "clear bfd [vrf <NAME$vrfname>] 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}]> counters", + SHOW_STR + "Bidirection Forwarding Detection\n" + VRF_CMD_HELP_STR + "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 + "clear BFD peer counters information\n") +{ + 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; + + _clear_peer_counter(bs); + + return CMD_SUCCESS; +} + +DEFPY(bfd_show_peers_brief, bfd_show_peers_brief_cmd, + "show bfd [vrf <NAME$vrfname>] peers brief [json]", + SHOW_STR + "Bidirection Forwarding Detection\n" + VRF_CMD_HELP_STR + "BFD peers status\n" + "Show BFD peer information in tabular form\n" + JSON_STR) +{ + char *vrf_name = NULL; + int idx_vrf = 0; + + if (argv_find(argv, argc, "vrf", &idx_vrf)) + vrf_name = argv[idx_vrf + 1]->arg; + + _display_peers_brief(vty, vrf_name, use_json(argc, argv)); + + return CMD_SUCCESS; +} /* * Function definitions. @@ -735,8 +876,10 @@ 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_clear_peer_counters_cmd); 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_debugging_bfd_cmd); /* Install BFD node and commands. */ |
