]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Implements BGP 'show protocols' info details.
authorOndrej Zajicek <santiago@crfreenet.org>
Tue, 6 Apr 2010 22:19:23 +0000 (00:19 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Tue, 6 Apr 2010 22:19:23 +0000 (00:19 +0200)
nest/proto.c
nest/protocol.h
proto/bgp/bgp.c
proto/bgp/bgp.h
proto/bgp/packets.c
proto/ospf/ospf.c
proto/ospf/rt.c

index 78fca99c1dbbda6957fd6c3fa2d4d2c40b520eb2..f55def5e56ddcda15424a3220cd1fe78fcfe6de1 100644 (file)
@@ -871,6 +871,8 @@ proto_cmd_show(struct proto *p, unsigned int verbose, int cnt)
     {
       if (p->cf->dsc)
        cli_msg(-1006, "  Description:    %s", p->cf->dsc);
+      if (p->cf->router_id)
+       cli_msg(-1006, "  Router ID:      %R", p->cf->router_id);
       cli_msg(-1006, "  Preference:     %d", p->preference);
       cli_msg(-1006, "  Input filter:   %s", filter_name(p->in_filter));
       cli_msg(-1006, "  Output filter:  %s", filter_name(p->out_filter));
@@ -885,6 +887,9 @@ proto_cmd_show(struct proto *p, unsigned int verbose, int cnt)
            proto_do_show_stats(p);
        }
 
+      if (p->proto->show_proto_info)
+       p->proto->show_proto_info(p);
+
       cli_msg(-1006, "");
     }
 }
index d94873e4630f85ccee5273f7d25e4e1307a40299..5dac2a9bb1a8485d760de18950189f354f7ac771 100644 (file)
@@ -51,6 +51,7 @@ struct protocol {
   void (*get_status)(struct proto *, byte *buf); /* Get instance status (for `show protocols' command) */
   void (*get_route_info)(struct rte *, byte *buf, struct ea_list *attrs); /* Get route information (for `show route' command) */
   int (*get_attr)(struct eattr *, byte *buf, int buflen);      /* ASCIIfy dynamic attribute (returns GA_*) */
+  void (*show_proto_info)(struct proto *);     /* Show protocol info (for `show protocols all' command) */
 };
 
 void protos_build(void);
index 4410c043d350f1d6fefacb516e5f5a27c1696420..378cc85df8840a411fb5c25efa8b676d764a1f7b 100644 (file)
@@ -60,6 +60,7 @@
 #include "nest/protocol.h"
 #include "nest/route.h"
 #include "nest/locks.h"
+#include "nest/cli.h"
 #include "conf/conf.h"
 #include "lib/socket.h"
 #include "lib/resource.h"
@@ -930,39 +931,108 @@ static char *bgp_err_classes[] = { "", "Error: ", "Socket: ", "Received: ", "BGP
 static char *bgp_misc_errors[] = { "", "Neighbor lost", "Invalid next hop", "Kernel MD5 auth failed" };
 static char *bgp_auto_errors[] = { "", "Route limit exceeded"};
 
-
-static void
-bgp_get_status(struct proto *P, byte *buf)
+static const char *
+bgp_last_errmsg(struct bgp_proto *p)
 {
-  struct bgp_proto *p = (struct bgp_proto *) P;
-
-  const byte *err1 = bgp_err_classes[p->last_error_class];
-  const byte *err2 = "";
-  byte errbuf[32];
-
   switch (p->last_error_class)
     {
     case BE_MISC:
-      err2 = bgp_misc_errors[p->last_error_code];
-      break;
+      return bgp_misc_errors[p->last_error_code];
     case BE_SOCKET:
-      err2 = (p->last_error_code == 0) ? "Connection closed" : strerror(p->last_error_code);
-      break;
+      return (p->last_error_code == 0) ? "Connection closed" : strerror(p->last_error_code);
     case BE_BGP_RX:
     case BE_BGP_TX:
-      err2 = bgp_error_dsc(errbuf, p->last_error_code >> 16, p->last_error_code & 0xFF);
-      break;
+      return bgp_error_dsc(p->last_error_code >> 16, p->last_error_code & 0xFF);
     case BE_AUTO_DOWN:
-      err2 = bgp_auto_errors[p->last_error_code];
-      break;
+      return bgp_auto_errors[p->last_error_code];
+    default:
+      return "";
     }
+}
+
+static const char *
+bgp_state_dsc(struct bgp_proto *p)
+{
+  //if (p->p.proto_state == PS_DOWN)
+  //  return "Down";
+
+  int state = MAX(p->incoming_conn.state, p->outgoing_conn.state);
+  if ((state == BS_IDLE) && (p->start_state >= BSS_CONNECT) && p->cf->passive)
+    return "Passive";
+
+  return bgp_state_names[state];
+}
+
+static void
+bgp_get_status(struct proto *P, byte *buf)
+{
+  struct bgp_proto *p = (struct bgp_proto *) P;
+
+  const char *err1 = bgp_err_classes[p->last_error_class];
+  const char *err2 = bgp_last_errmsg(p);
 
   if (P->proto_state == PS_DOWN)
     bsprintf(buf, "%s%s", err1, err2);
   else
-    bsprintf(buf, "%-14s%s%s",
-            bgp_state_names[MAX(p->incoming_conn.state, p->outgoing_conn.state)],
-            err1, err2);
+    bsprintf(buf, "%-14s%s%s", bgp_state_dsc(p), err1, err2);
+}
+
+static void
+bgp_show_proto_info(struct proto *P)
+{
+  struct bgp_proto *p = (struct bgp_proto *) P;
+  struct bgp_conn *c = p->conn;
+
+  if (P->proto_state == PS_DOWN)
+    return;
+
+  cli_msg(-1006, "  BGP state:          %s", bgp_state_dsc(p));
+
+  if (P->proto_state == PS_START)
+    {
+      struct bgp_conn *oc = &p->outgoing_conn;
+
+      if ((p->start_state < BSS_CONNECT) &&
+         (p->startup_timer->expires))
+       cli_msg(-1006, "    Error wait:       %d/%d", 
+               p->startup_timer->expires - now, p->startup_delay);
+
+      if ((oc->state == BS_ACTIVE) &&
+         (oc->connect_retry_timer->expires))
+       cli_msg(-1006, "    Start delay:      %d/%d", 
+               oc->connect_retry_timer->expires - now, p->cf->start_delay_time);
+    }
+  else if (P->proto_state == PS_UP)
+    {
+      cli_msg(-1006, "    Session:          %s%s%s%s",
+             p->is_internal ? "internal" : "external",
+             p->rr_client ? " route-reflector" : "",
+             p->rs_client ? " route-server" : "",
+             p->as4_session ? " AS4" : "");
+      cli_msg(-1006, "    Neighbor AS:      %u", p->remote_as);
+      cli_msg(-1006, "    Neighbor ID:      %R", p->remote_id);
+      cli_msg(-1006, "    Neighbor address: %I", p->cf->remote_ip);
+      cli_msg(-1006, "    Nexthop address:  %I", p->next_hop);
+      cli_msg(-1006, "    Source address:   %I", p->source_addr);
+      cli_msg(-1006, "    Neighbor caps:   %s%s",
+             c->peer_refresh_support ? " refresh" : "",
+             c->peer_as4_support ? " AS4" : "");
+      if (p->cf->route_limit)
+       cli_msg(-1006, "    Route limit:      %d/%d",
+               p->p.stats.imp_routes, p->cf->route_limit);
+      cli_msg(-1006, "    Hold timer:       %d/%d", 
+             c->hold_timer->expires - now, c->hold_time);
+      cli_msg(-1006, "    Keepalive timer:  %d/%d", 
+             c->keepalive_timer->expires - now, c->keepalive_time);
+    }
+
+  if ((p->last_error_class != BE_NONE) && 
+      (p->last_error_class != BE_MAN_DOWN))
+    {
+      const char *err1 = bgp_err_classes[p->last_error_class];
+      const char *err2 = bgp_last_errmsg(p);
+      cli_msg(-1006, "    Last error:       %s%s", err1, err2);
+    }
 }
 
 static int
@@ -993,8 +1063,9 @@ struct protocol proto_bgp = {
   init:                        bgp_init,
   start:               bgp_start,
   shutdown:            bgp_shutdown,
+  reconfigure:         bgp_reconfigure,
   get_status:          bgp_get_status,
   get_attr:            bgp_get_attr,
-  reconfigure:         bgp_reconfigure,
   get_route_info:      bgp_get_route_info,
+  show_proto_info:     bgp_show_proto_info
 };
index 1a291952660f8259f9d757b3eabb84a966e300ba..39a87a61afc8b29ea0073d2c21d4fdfceaad2228 100644 (file)
@@ -196,7 +196,7 @@ void bgp_schedule_packet(struct bgp_conn *conn, int type);
 void bgp_kick_tx(void *vconn);
 void bgp_tx(struct birdsock *sk);
 int bgp_rx(struct birdsock *sk, int size);
-const byte * bgp_error_dsc(byte *buff, unsigned code, unsigned subcode);
+const char * bgp_error_dsc(unsigned code, unsigned subcode);
 void bgp_log_error(struct bgp_proto *p, u8 class, char *msg, unsigned code, unsigned subcode, byte *data, unsigned len);
 
 /* Packet types */
index 2baa6e348ec5f57c0df6543d0c67a5267b70e6a5..af7ce0c4981be0508be5e894d25abbc01173c601 100644 (file)
@@ -1077,16 +1077,16 @@ static struct {
 
 /**
  * bgp_error_dsc - return BGP error description
- * @buff: temporary buffer
  * @code: BGP error code
  * @subcode: BGP error subcode
  *
  * bgp_error_dsc() returns error description for BGP errors
  * which might be static string or given temporary buffer.
  */
-const byte *
-bgp_error_dsc(byte *buff, unsigned code, unsigned subcode)
+const char *
+bgp_error_dsc(unsigned code, unsigned subcode)
 {
+  static char buff[32];
   unsigned i;
   for (i=0; i < ARRAY_SIZE(bgp_msg_table); i++)
     if (bgp_msg_table[i].major == code && bgp_msg_table[i].minor == subcode)
@@ -1102,7 +1102,6 @@ void
 bgp_log_error(struct bgp_proto *p, u8 class, char *msg, unsigned code, unsigned subcode, byte *data, unsigned len)
 {
   const byte *name;
-  byte namebuf[32];
   byte *t, argbuf[36];
   unsigned i;
 
@@ -1110,7 +1109,7 @@ bgp_log_error(struct bgp_proto *p, u8 class, char *msg, unsigned code, unsigned
   if (code == 6 && class == BE_BGP_TX)
     return;
 
-  name = bgp_error_dsc(namebuf, code, subcode);
+  name = bgp_error_dsc(code, subcode);
   t = argbuf;
   if (len)
     {
index 5ed8abb10c9a41655afabc2c8d1b687dfe770d22..107e3a411e5bd87b69895294ce17ab25406b3687 100644 (file)
@@ -1533,15 +1533,16 @@ ospf_sh_lsadb(struct proto *p)
 
 
 struct protocol proto_ospf = {
-  name:"OSPF",
-  template:"ospf%d",
-  attr_class:EAP_OSPF,
-  init:ospf_init,
-  dump:ospf_dump,
-  start:ospf_start,
-  shutdown:ospf_shutdown,
-  get_route_info:ospf_get_route_info,
-  get_attr:ospf_get_attr,
-  get_status:ospf_get_status,
-  reconfigure:ospf_reconfigure
+  name:                        "OSPF",
+  template:            "ospf%d",
+  attr_class:          EAP_OSPF,
+  init:                        ospf_init,
+  dump:                        ospf_dump,
+  start:               ospf_start,
+  shutdown:            ospf_shutdown,
+  reconfigure:         ospf_reconfigure,
+  get_status:          ospf_get_status,
+  get_attr:            ospf_get_attr,
+  get_route_info:      ospf_get_route_info
+  // show_proto_info:  ospf_sh
 };
index 5c0b3fa20899973f4b40952d19a7f9e9a38e432f..c3798e7d10daf2a5cdb4bfaff23eaa1b532f7d68 100644 (file)
@@ -152,12 +152,11 @@ static struct ospf_iface *
 find_stub_src(struct ospf_area *oa, ip_addr px, int pxlen)
 {
   struct ospf_iface *iff;
-  struct ifa *addr;
 
   WALK_LIST(iff, oa->po->iface_list)
     if ((iff->type != OSPF_IT_VLINK) &&
        (iff->oa == oa) &&
-       ipa_equal(iff->addr->px, px) && 
+       ipa_equal(iff->addr->prefix, px) && 
        (iff->addr->pxlen == pxlen))
       return iff;