diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2009-10-15 11:57:25 +0200 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2009-10-15 11:57:25 +0200 |
commit | 988992446d3aaaef9c19902d94cd1908a963fd80 (patch) | |
tree | 6cda0d0ac8f89b0653b9a405c6228c8fd5b3c2dc /proto/ospf/ospf.c | |
parent | b66abe8ef986698caccd08b38a991330f0791075 (diff) | |
download | bird-988992446d3aaaef9c19902d94cd1908a963fd80.tar bird-988992446d3aaaef9c19902d94cd1908a963fd80.zip |
Implement command to show LSA db.
Diffstat (limited to 'proto/ospf/ospf.c')
-rw-r--r-- | proto/ospf/ospf.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index 8a1677a..10713c9 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", |