summaryrefslogtreecommitdiff
path: root/proto/bfd/bfd.c
diff options
context:
space:
mode:
Diffstat (limited to 'proto/bfd/bfd.c')
-rw-r--r--proto/bfd/bfd.c149
1 files changed, 129 insertions, 20 deletions
diff --git a/proto/bfd/bfd.c b/proto/bfd/bfd.c
index 97eb2d9b..41d8e210 100644
--- a/proto/bfd/bfd.c
+++ b/proto/bfd/bfd.c
@@ -118,6 +118,43 @@ static list STATIC_LIST_INIT(bfd_wait_list);
const char *bfd_state_names[] = { "AdminDown", "Down", "Init", "Up" };
+const char *bfd_diag_names[] = {
+ [BFD_DIAG_NOTHING] = "None",
+ [BFD_DIAG_TIMEOUT] = "Time expired",
+ [BFD_DIAG_ECHO_FAILED] = "Echo failed",
+ [BFD_DIAG_NEIGHBOR_DOWN] = "Neighbor down",
+ [BFD_DIAG_FWD_RESET] = "Fwd plane reset",
+ [BFD_DIAG_PATH_DOWN] = "Path down",
+ [BFD_DIAG_C_PATH_DOWN] = "Concat path down",
+ [BFD_DIAG_ADMIN_DOWN] = "Admin down",
+ [BFD_DIAG_RC_PATH_DOWN] = "Rev concat path down",
+};
+
+const char *bfd_auth_names[] = {
+ [BFD_AUTH_NONE] = "None",
+ [BFD_AUTH_SIMPLE] = "Simple",
+ [BFD_AUTH_KEYED_MD5] = "Keyed MD5",
+ [BFD_AUTH_METICULOUS_KEYED_MD5] = "Meticulous keyed MD5",
+ [BFD_AUTH_KEYED_SHA1] = "Keyed SHA1",
+ [BFD_AUTH_METICULOUS_KEYED_SHA1] = "Meticulous keyed SHA1",
+};
+
+#define BFD_DIAG_BUFFER_SIZE 16
+
+static inline const char *
+bfd_diag_name(u8 id, char buf[BFD_DIAG_BUFFER_SIZE])
+{
+ return (id < ARRAY_SIZE(bfd_diag_names)) ?
+ bfd_diag_names[id] :
+ (bsprintf(buf, "Error #%u", (uint) id), buf);
+}
+
+static inline const char *
+bfd_auth_name(u8 id)
+{
+ return (id < ARRAY_SIZE(bfd_auth_names)) ? bfd_auth_names[id] : "?";
+}
+
static void bfd_session_set_min_tx(struct bfd_session *s, u32 val);
static struct bfd_iface *bfd_get_iface(struct bfd_proto *p, ip_addr local, struct iface *iface);
static void bfd_free_iface(struct bfd_iface *ifa);
@@ -136,7 +173,7 @@ bfd_merge_options(const struct bfd_iface_config *cf, const struct bfd_options *o
.min_tx_int = opts->min_tx_int ?: cf->min_tx_int,
.idle_tx_int = opts->idle_tx_int ?: cf->idle_tx_int,
.multiplier = opts->multiplier ?: cf->multiplier,
- .passive = opts->passive_set ? opts->passive : cf->passive
+ .passive = opts->passive_set ? opts->passive : cf->passive,
};
}
@@ -231,7 +268,7 @@ bfd_session_control_tx_timer(struct bfd_session *s, int reset)
return;
- stop:
+stop:
tm_stop(s->tx_timer);
s->last_tx = 0;
}
@@ -548,7 +585,7 @@ static struct bfd_iface_config bfd_default_iface = {
.min_rx_int = BFD_DEFAULT_MIN_RX_INT,
.min_tx_int = BFD_DEFAULT_MIN_TX_INT,
.idle_tx_int = BFD_DEFAULT_IDLE_TX_INT,
- .multiplier = BFD_DEFAULT_MULTIPLIER
+ .multiplier = BFD_DEFAULT_MULTIPLIER,
};
static inline struct bfd_iface_config *
@@ -800,7 +837,7 @@ static struct resclass bfd_request_class = {
bfd_request_free,
bfd_request_dump,
NULL,
- NULL
+ NULL,
};
@@ -1144,13 +1181,84 @@ bfd_copy_config(struct proto_config *dest, struct proto_config *src UNUSED)
}
void
-bfd_show_sessions(struct proto *P)
+bfd_show_session(struct bfd_session *s, int details)
{
+ /* FIXME: this is thread-unsafe, but perhaps harmless */
+
+ u8 loc_state = s->loc_state;
+ u8 rem_state = s->rem_state;
+ u8 loc_diag = s->loc_diag;
+ u8 rem_diag = s->rem_diag;
+ uint loc_id = s->loc_id;
+ uint rem_id = s->rem_id;
+
+ const char *ifname = (s->ifa && s->ifa->iface) ? s->ifa->iface->name : "---";
+ btime tx_int = s->last_tx ? MAX(s->des_min_tx_int, s->rem_min_rx_int) : 0;
+ btime timeout = (btime) MAX(s->req_min_rx_int, s->rem_min_tx_int) * s->rem_detect_mult;
+ u8 auth_type = s->ifa->cf->auth_type;
+
+ loc_state = (loc_state < 4) ? loc_state : 0;
+ rem_state = (rem_state < 4) ? rem_state : 0;
+
+ byte dbuf[BFD_DIAG_BUFFER_SIZE];
byte tbuf[TM_DATETIME_BUFFER_SIZE];
+ tm_format_time(tbuf, &config->tf_proto, s->last_state_change);
+
+ if (!details)
+ {
+ cli_msg(-1020, "%-25I %-10s %-10s %-12s %7t %7t",
+ s->addr, ifname, bfd_state_names[loc_state], tbuf, tx_int, timeout);
+
+ return;
+ }
+
+ cli_msg(-1020, " %-21s %I", "Address:", s->addr);
+ cli_msg(-1020, " %-21s %s", "Interface:", ifname);
+ cli_msg(-1020, " %-21s %s", "Session type:", s->ifa->iface ? "Direct" : "Multihop");
+ cli_msg(-1020, " %-21s %s", "Session state:", bfd_state_names[loc_state]);
+ cli_msg(-1020, " %-21s %s", "Remote state:", bfd_state_names[rem_state]);
+ cli_msg(-1020, " %-21s %s", "Last state change:", tbuf);
+ cli_msg(-1020, " %-21s %s", "Local diagnostic:", bfd_diag_name(loc_diag, dbuf));
+ cli_msg(-1020, " %-21s %s", "Remote diagnostic:", bfd_diag_name(rem_diag, dbuf));
+ cli_msg(-1020, " %-21s %u", "Local discriminator:", loc_id);
+ cli_msg(-1020, " %-21s %u", "Remote discriminator:", rem_id);
+
+ if (tm_active(s->tx_timer))
+ cli_msg(-1020, " %-21s %t / %t", "Transmit timer:", tm_remains(s->tx_timer), tx_int);
+
+ if (tm_active(s->hold_timer))
+ cli_msg(-1020, " %-21s %t / %t", "Detect timer:", tm_remains(s->hold_timer), timeout);
+
+ cli_msg(-1020, " Local parameters:");
+ cli_msg(-1020, " %-19s %t", "Min TX interval:", (btime) s->des_min_tx_int);
+ cli_msg(-1020, " %-19s %t", "Min RX interval:", (btime) s->req_min_rx_int);
+ cli_msg(-1020, " %-19s %s", "Demand mode:", s->demand_mode ? "Yes" : "No");
+ cli_msg(-1020, " %-19s %i", "Multiplier:", s->detect_mult);
+ cli_msg(-1020, " Remote parameters:");
+ cli_msg(-1020, " %-19s %t", "Min TX interval:", (btime) s->rem_min_tx_int);
+ cli_msg(-1020, " %-19s %t", "Min RX interval:", (btime) s->rem_min_rx_int);
+ cli_msg(-1020, " %-19s %s", "Demand mode:", s->rem_demand_mode ? "Yes" : "No");
+ cli_msg(-1020, " %-19s %i", "Multiplier:", s->rem_detect_mult);
+
+ if (auth_type)
+ {
+ cli_msg(-1020, " Authentication:");
+ cli_msg(-1020, " %-19s %s", "Type:", bfd_auth_name(auth_type));
+
+ if (s->rx_csn_known)
+ cli_msg(-1020, " %-19s %u", "RX CSN:", s->rx_csn);
+
+ if (auth_type > BFD_AUTH_SIMPLE)
+ cli_msg(-1020, " %-19s %u", "TX CSN:", s->tx_csn);
+ }
+
+ cli_msg(-1020, "");
+}
+
+void
+bfd_show_sessions(struct proto *P, struct bfd_show_sessions_cmd *args)
+{
struct bfd_proto *p = (struct bfd_proto *) P;
- uint state, diag UNUSED;
- btime tx_int, timeout;
- const char *ifname;
if (p->p.proto_state != PS_UP)
{
@@ -1159,24 +1267,25 @@ bfd_show_sessions(struct proto *P)
}
cli_msg(-1020, "%s:", p->p.name);
- cli_msg(-1020, "%-25s %-10s %-10s %-12s %8s %8s",
+ if (!args->verbose)
+ cli_msg(-1020, "%-25s %-10s %-10s %-12s %8s %8s",
"IP address", "Interface", "State", "Since", "Interval", "Timeout");
-
HASH_WALK(p->session_hash_id, next_id, s)
{
- /* FIXME: this is thread-unsafe, but perhaps harmless */
- state = s->loc_state;
- diag = s->loc_diag;
- ifname = (s->ifa && s->ifa->iface) ? s->ifa->iface->name : "---";
- tx_int = s->last_tx ? MAX(s->des_min_tx_int, s->rem_min_rx_int) : 0;
- timeout = (btime) MAX(s->req_min_rx_int, s->rem_min_tx_int) * s->rem_detect_mult;
+ if (args->address.type && !ipa_in_netX(s->addr, &args->address))
+ continue;
- state = (state < 4) ? state : 0;
- tm_format_time(tbuf, &config->tf_proto, s->last_state_change);
+ if (args->iface && (s->ifa->iface != args->iface))
+ continue;
- cli_msg(-1020, "%-25I %-10s %-10s %-12s %7t %7t",
- s->addr, ifname, bfd_state_names[state], tbuf, tx_int, timeout);
+ if (ipa_is_ip4(s->addr) ? args->ipv6 : args->ipv4)
+ continue;
+
+ if (s->ifa->iface ? args->multihop : args->direct)
+ continue;
+
+ bfd_show_session(s, args->verbose);
}
HASH_WALK_END;
}