summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfdd/bfd.c5
-rw-r--r--bfdd/bfd.h2
-rw-r--r--bfdd/bfdd_vty.c153
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. */