diff --git a/conf/confbase.Y b/conf/confbase.Y index 14893f47..b952f314 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -50,6 +50,7 @@ CF_DECLS struct f_path_mask *h; struct password_item *p; struct rt_show_data *ra; + struct lsadb_show_data *ld; struct iface *iface; void *g; bird_clock_t time; diff --git a/doc/bird.sgml b/doc/bird.sgml index 4abe706c..f5cfdfb1 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -561,6 +561,9 @@ This argument can be omitted if there exists only a single instance. link-state database. It is just a stripped-down version of 'show ospf state'. + show ospf lsadb [global | area + Show contents of an OSPF LSA database. Options could be used to filter entries. + show static [ Show detailed information about static routes. diff --git a/proto/ospf/config.Y b/proto/ospf/config.Y index 24e125a7..9c48a9b8 100644 --- a/proto/ospf/config.Y +++ b/proto/ospf/config.Y @@ -120,8 +120,10 @@ CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC) CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, CHECK, LINK) CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY, TAG, EXTERNAL) CF_KEYWORDS(WAIT, DELAY, LSADB, ECMP, LIMIT, WEIGHT, NSSA, TRANSLATOR, STABILITY) +CF_KEYWORDS(GLOBAL, LSID, ROUTER, SELF) %type opttext +%type lsadb_args CF_GRAMMAR @@ -411,8 +413,22 @@ CF_CLI(SHOW OSPF STATE, optsym opttext, [], [[Show information about reach CF_CLI(SHOW OSPF STATE ALL, optsym opttext, [], [[Show information about all OSPF network state]]) { ospf_sh_state(proto_get_named($5, &proto_ospf), 1, 0); }; -CF_CLI(SHOW OSPF LSADB, optsym opttext, [], [[Show content of OSPF LSA database]]) -{ ospf_sh_lsadb(proto_get_named($4, &proto_ospf)); }; +CF_CLI(SHOW OSPF LSADB, lsadb_args, [global | area | link] [type ] [lsid ] [self | router ] [], [[Show content of OSPF LSA database]]) +{ ospf_sh_lsadb($4); }; + +lsadb_args: + /* empty */ { + $$ = cfg_allocz(sizeof(struct lsadb_show_data)); + } + | lsadb_args GLOBAL { $$ = $1; $$->scope = LSA_SCOPE_AS; } + | lsadb_args AREA idval { $$ = $1; $$->scope = LSA_SCOPE_AREA; $$->area = $3 } + | lsadb_args LINK { $$ = $1; $$->scope = 1; /* hack, 0 is no filter */ } + | lsadb_args TYPE NUM { $$ = $1; $$->type = $3; } + | lsadb_args LSID idval { $$ = $1; $$->lsid = $3; } + | lsadb_args SELF { $$ = $1; $$->router = SH_ROUTER_SELF; } + | lsadb_args ROUTER idval { $$ = $1; $$->router = $3; } + | lsadb_args SYM { $$ = $1; $$->name = $2; } + ; CF_CODE diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index 73c06c27..9872faf2 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -1471,8 +1471,9 @@ lsa_compare_for_lsadb(const void *p1, const void *p2) } void -ospf_sh_lsadb(struct proto *p) +ospf_sh_lsadb(struct lsadb_show_data *ld) { + struct proto *p = proto_get_named(ld->name, &proto_ospf); struct proto_ospf *po = (struct proto_ospf *) p; int num = po->gr->hash_entries; unsigned int i, j; @@ -1486,6 +1487,9 @@ ospf_sh_lsadb(struct proto *p) return; } + if (ld->router == SH_ROUTER_SELF) + ld->router = po->router_id; + struct top_hash_entry *hea[num]; struct top_hash_entry *he; @@ -1502,6 +1506,22 @@ ospf_sh_lsadb(struct proto *p) { struct ospf_lsa_header *lsa = &(hea[i]->lsa); int dscope = LSA_SCOPE(lsa); + + if (ld->scope && (dscope != (ld->scope & 0xf000))) + continue; + + if ((ld->scope == LSA_SCOPE_AREA) && (hea[i]->domain != ld->area)) + continue; + + /* Ignore high nibble */ + if (ld->type && ((lsa->type & 0x0fff) != (ld->type & 0x0fff))) + continue; + + if (ld->lsid && (lsa->id != ld->lsid)) + continue; + + if (ld->router && (lsa->rt != ld->router)) + continue; if ((dscope != last_dscope) || (hea[i]->domain != last_domain)) { diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index d6961519..96da9aa7 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -846,7 +846,19 @@ void ospf_sh_neigh(struct proto *p, char *iff); void ospf_sh(struct proto *p); void ospf_sh_iface(struct proto *p, char *iff); void ospf_sh_state(struct proto *p, int verbose, int reachable); -void ospf_sh_lsadb(struct proto *p); + +#define SH_ROUTER_SELF 0xffffffff + +struct lsadb_show_data { + struct symbol *name; /* Protocol to request data from */ + u16 type; /* LSA Type, 0 -> all */ + u16 scope; /* Scope, 0 -> all, hack to handle link scope as 1 */ + u32 area; /* Specified for area scope */ + u32 lsid; /* LSA ID, 0 -> all */ + u32 router; /* Advertising router, 0 -> all */ +}; + +void ospf_sh_lsadb(struct lsadb_show_data *ld); #define EA_OSPF_METRIC1 EA_CODE(EAP_OSPF, 0)