]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
BFD: Improve 'show bfd sessions all' command
authorOndrej Zajicek <santiago@crfreenet.org>
Fri, 1 Mar 2024 17:39:09 +0000 (18:39 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Mon, 4 Mar 2024 22:51:37 +0000 (23:51 +0100)
proto/bfd/bfd.c

index 61ceea5077ea893693929c06b1b34f670c03d541..b9461085e0a96d3a360a65ad6d917253d096ebd0 100644 (file)
@@ -117,7 +117,43 @@ static list STATIC_LIST_INIT(bfd_proto_list);
 static list STATIC_LIST_INIT(bfd_wait_list);
 
 const char *bfd_state_names[] = { "AdminDown", "Down", "Init", "Up" };
-const char *bfd_diag_names[] = { "Nothing", "Timeout", "Echo failed", "Neighbor down", "Fwd reset", "Path down", "C path down", "Admin down", "RC path down" };
+
+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);
@@ -1144,61 +1180,85 @@ bfd_copy_config(struct proto_config *dest, struct proto_config *src UNUSED)
   init_list(&d->neigh_list);
 }
 
-void bfd_show_details(struct bfd_session *s)
+void
+bfd_show_session(struct bfd_session *s, int details)
 {
-  cli_msg(-1020, "  IP address: %I", s->addr);
-  cli_msg(-1020, "  Interface: %s", (s->ifa && s->ifa->iface) ? s->ifa->iface->name : "---");
-  cli_msg(-1020, "  Role: %s", (s->passive) ? "Passive" : "Active");
-  cli_msg(-1020, "  Local session:");
-  cli_msg(-1020, "    State:  %s", bfd_state_names[s->loc_state]);
-  cli_msg(-1020, "    Session ID: %u", s->loc_id);
-  if (s->loc_diag || s->rem_diag)
-    cli_msg(-1020, "    Issue: %s", bfd_diag_names[s->loc_diag]);
-
-  cli_msg(-1020, "  Remote session:");
-  cli_msg(-1020, "    State:  %s", bfd_state_names[s->rem_state]);
-  cli_msg(-1020, "    Session ID: %u", s->loc_id, s->rem_id);
-  if (s->loc_diag || s->rem_diag)
-    cli_msg(-1020, "    Issue: %s", bfd_diag_names[s->rem_diag]);
-
-  cli_msg(-1020, "  Session mode:  %s", (s->rem_demand_mode) ? "Demand" : "Asynchronous");
-  if (!s->rem_demand_mode)
+  /* 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, "  Local intervals:");
-    cli_msg(-1020, "    Desired min tx:  %t", s->des_min_tx_int);
-    cli_msg(-1020, "    Required min rx: %t", s->req_min_rx_int);
-    cli_msg(-1020, "  Remote intervals:");
-    cli_msg(-1020, "    Desired min tx:  %t", s->rem_min_tx_int);
-    cli_msg(-1020, "    Required min rx: %t", s->rem_min_rx_int);
-    cli_msg(-1020, "  Timers:");
-    cli_msg(-1020, "    Hold timer remains %t/%t", tm_remains(s->hold_timer), MAX(s->req_min_rx_int, s->rem_min_tx_int) * s->rem_detect_mult);  // The total time is just copied from timers setings. I hope it is not (and will not) be problem.
-    cli_msg(-1020, "    TX timer remains   %t", tm_remains(s->tx_timer));
+    cli_msg(-1020, "%-25I %-10s %-10s %-12s  %7t  %7t",
+           s->addr, ifname, bfd_state_names[loc_state], tbuf, tx_int, timeout);
+
+    return;
   }
-  else if (tm_remains(s->hold_timer) > 0)
+
+  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, "    Hold timer remains %t", tm_remains(s->hold_timer));
+    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, "  Latest actions:");
-  cli_msg(-1020, "    Last received valid control packet before %t", current_time() - s->last_rx);
-  cli_msg(-1020, "    Last sent periodic control packet before  %t", current_time() - s->last_tx);
-  btime tim = (btime)(((u64) s->tx_csn_time) << 20);
-  if (tim > 0)
-    cli_msg(-1020, "    Last csn change before                    %t", current_time() - tim);
-  if (s->poll_active || s->poll_scheduled)
-    cli_msg(-1020, "  Poll %s%s", (s->poll_active) ? ", poll active" : "", (s->poll_scheduled) ? ", poll scheduled" : "");
-  else
-    cli_msg(-1020, "  Poll inactive");
+
   cli_msg(-1020, "");
 }
 
 void
 bfd_show_sessions(struct proto *P, int details, net_addr addr)
 {
-  byte tbuf[TM_DATETIME_BUFFER_SIZE];
   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)
   {
@@ -1211,31 +1271,12 @@ bfd_show_sessions(struct proto *P, int details, net_addr addr)
     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 */
-
     if (addr.type != 0 && !ipa_in_netX(s->addr, &addr))
       continue;
-    if (!details)
-    {
-      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;
-
-      state = (state < 4) ? state : 0;
-      tm_format_time(tbuf, &config->tf_proto, s->last_state_change);
-
-      cli_msg(-1020, "%-25I %-10s %-10s %-12s  %7t  %7t",
-           s->addr, ifname, bfd_state_names[state], tbuf, tx_int, timeout);
-     }
-    else
-    {
-      bfd_show_details(s);
-    }
+
+    bfd_show_session(s, details);
   }
   HASH_WALK_END;
 }