summaryrefslogtreecommitdiff
path: root/proto
diff options
context:
space:
mode:
Diffstat (limited to 'proto')
-rw-r--r--proto/ospf/config.Y5
-rw-r--r--proto/ospf/ospf.c97
-rw-r--r--proto/ospf/ospf.h5
3 files changed, 106 insertions, 1 deletions
diff --git a/proto/ospf/config.Y b/proto/ospf/config.Y
index 6acc7d24..7b2641b2 100644
--- a/proto/ospf/config.Y
+++ b/proto/ospf/config.Y
@@ -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
diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c
index 8a1677a1..10713c99 100644
--- a/proto/ospf/ospf.c
+++ b/proto/ospf/ospf.c
@@ -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",
diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h
index e89769df..d826c734 100644
--- a/proto/ospf/ospf.h
+++ b/proto/ospf/ospf.h
@@ -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;