Commit 98899244 authored by Ondřej Zajíček's avatar Ondřej Zajíček

Implement command to show LSA db.

parent b66abe8e
......@@ -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
......@@ -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",
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment