]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Implement command to show LSA db.
authorOndrej Zajicek <santiago@crfreenet.org>
Thu, 15 Oct 2009 09:57:25 +0000 (11:57 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Thu, 15 Oct 2009 09:57:25 +0000 (11:57 +0200)
proto/ospf/config.Y
proto/ospf/ospf.c
proto/ospf/ospf.h

index 6acc7d246789c205be0ef87a42f69fc78f89dcf5..7b2641b2bcab55248219c5283538a171dd00db59 100644 (file)
@@ -50,7 +50,7 @@ CF_KEYWORDS(NEIGHBORS, RFC1583COMPAT, STUB, TICK, COST, RETRANSMIT)
 CF_KEYWORDS(HELLO, TRANSMIT, PRIORITY, DEAD, NONBROADCAST, POINTOPOINT, TYPE)
 CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC)
 CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, LINK)
-CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY)
+CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY, LSADB)
 
 %type <t> opttext
 
@@ -319,6 +319,9 @@ CF_CLI(SHOW OSPF TOPOLOGY, optsym opttext, [<name>], [[Show information about OS
 CF_CLI(SHOW OSPF STATE, optsym opttext, [<name>], [[Show information about OSPF network state]])
 { ospf_sh_state(proto_get_named($4, &proto_ospf), 1); };
 
+CF_CLI(SHOW OSPF LSADB, optsym opttext, [<name>], [[Show content of OSPF LSA database]])
+{ ospf_sh_lsadb(proto_get_named($4, &proto_ospf)); };
+
 CF_CODE
 
 CF_END
index 8a1677a13dea5221ac4842dcd5b6391e84db0bf3..10713c9947db2bdcefa338a4a2ce5431cf3e8c13 100644 (file)
@@ -1439,6 +1439,103 @@ ospf_sh_state(struct proto *p, int verbose)
   cli_msg(0, "");
 }
 
+
+static int
+lsa_compare_for_lsadb(const void *p1, const void *p2)
+{
+  struct top_hash_entry * he1 = * (struct top_hash_entry **) p1;
+  struct top_hash_entry * he2 = * (struct top_hash_entry **) p2;
+  struct ospf_lsa_header *lsa1 = &(he1->lsa);
+  struct ospf_lsa_header *lsa2 = &(he2->lsa);
+  int sc1 = LSA_SCOPE(lsa1);
+  int sc2 = LSA_SCOPE(lsa2);
+
+  if (sc1 != sc2)
+    return sc2 - sc1;
+
+  if (he1->domain != he2->domain)
+    return he1->domain - he2->domain;
+
+  if (lsa1->rt != lsa2->rt)
+    return lsa1->rt - lsa2->rt;
+  
+  if (lsa1->id != lsa2->id)
+    return lsa1->id - lsa2->id;
+
+  if (lsa1->type != lsa2->type)
+    return lsa1->type - lsa2->type;
+
+  return lsa1->sn - lsa2->sn;
+}
+
+void
+ospf_sh_lsadb(struct proto *p)
+{
+  struct proto_ospf *po = (struct proto_ospf *) p;
+  struct top_graph *f = po->gr;
+  unsigned int i, j;
+  int last_dscope = -1;
+  u32 last_domain = 0;
+
+  if (p->proto_state != PS_UP)
+  {
+    cli_msg(-1017, "%s: is not up", p->name);
+    cli_msg(0, "");
+    return;
+  }
+
+  struct top_hash_entry *hea[f->hash_entries];
+  struct top_hash_entry *he;
+
+  j = 0;
+  WALK_SLIST(he, po->lsal)
+    hea[j++] = he;
+
+  if (j != f->hash_entries)
+    die("Fatal mismatch");
+
+  qsort(hea, j, sizeof(struct top_hash_entry *), lsa_compare_for_lsadb);
+
+  for (i = 0; i < j; i++)
+  {
+    struct ospf_lsa_header *lsa = &(hea[i]->lsa);
+    int dscope = LSA_SCOPE(lsa);
+    
+    if ((dscope != last_dscope) || (hea[i]->domain != last_domain))
+    {
+      struct iface *ifa;
+
+      cli_msg(-1017, "");
+      switch (dscope)
+      {
+       case LSA_SCOPE_AS:
+         cli_msg(-1017, "Global");
+         break;
+       case LSA_SCOPE_AREA:
+         cli_msg(-1017, "Area %R", hea[i]->domain);
+         break;
+#ifdef OSPFv3
+       case LSA_SCOPE_LINK:
+         ifa = if_find_by_index(hea[i]->domain);
+         cli_msg(-1017, "Link %s", (ifa != NULL) ? ifa->name : "?");
+         break;
+#endif
+      }
+      cli_msg(-1017, "");
+      cli_msg(-1017,"  Router ID       LS ID          Type   Age   Sequence Checksum");
+
+      last_dscope = dscope;
+      last_domain = hea[i]->domain;
+    }
+
+
+    cli_msg(-1017,"%-15R %-15R 0x%04x %5u 0x%08x 0x%04x",
+           lsa->rt, lsa->id, lsa->type, lsa->age, lsa->sn, lsa->checksum);
+  }
+  cli_msg(0, "");
+}
+
+
 struct protocol proto_ospf = {
   name:"OSPF",
   template:"ospf%d",
index e89769df446b0303846142c0c4489a27968eaad7..d826c734236bac1355b1a23efe994b22cf94d33b 100644 (file)
@@ -347,6 +347,11 @@ struct ospf_lsa_header
 #define LSA_T_SUM_RT   4
 #define LSA_T_EXT      5
 
+#define LSA_SCOPE_AREA 0x2000
+#define LSA_SCOPE_AS   0x4000
+
+#define LSA_SCOPE(lsa) (((lsa)->type == LSA_T_EXT) ? LSA_SCOPE_AS : LSA_SCOPE_AREA)
+
 #else /* OSPFv3 */
   u16 type;