2016-08-01 Israel G. Lugo OSPF: Implement new "detail" option for "show ospf lsadb". Gives more details about the LSAs, such as forwarding address and so on. Work in progress. diff -dur bird-1.6.0/proto/ospf/config.Y bird-1.6.0-lsa-detail/proto/ospf/config.Y --- bird-1.6.0/proto/ospf/config.Y 2015-04-22 15:41:44.000000000 +0100 +++ bird-1.6.0-lsa-detail/proto/ospf/config.Y 2016-08-01 12:14:19.241568453 +0100 @@ -130,7 +130,7 @@ 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, INSTANCE, REAL, NETMASK, TX, PRIORITY, LENGTH) -CF_KEYWORDS(SECONDARY, MERGE, LSA, SUPPRESSION) +CF_KEYWORDS(SECONDARY, MERGE, LSA, SUPPRESSION, DETAIL) %type opttext %type lsadb_args @@ -438,7 +438,7 @@ { ospf_sh_state(proto_get_named($5, &proto_ospf), 1, 0); }; CF_CLI_HELP(SHOW OSPF LSADB, ..., [[Show content of OSPF LSA database]]); -CF_CLI(SHOW OSPF LSADB, lsadb_args, [global | area | link] [type ] [lsid ] [self | router ] [], [[Show content of OSPF LSA database]]) +CF_CLI(SHOW OSPF LSADB, lsadb_args, [global | area | link] [type ] [lsid ] [self | router ] [] [detail], [[Show content of OSPF LSA database]]) { ospf_sh_lsadb($4); }; lsadb_args: @@ -453,6 +453,7 @@ | lsadb_args SELF { $$ = $1; $$->router = SH_ROUTER_SELF; } | lsadb_args ROUTER idval { $$ = $1; $$->router = $3; } | lsadb_args SYM { $$ = $1; $$->name = $2; } + | lsadb_args DETAIL { $$ = $1; $$->verbose = 1; } ; CF_CODE diff -dur bird-1.6.0/proto/ospf/ospf.c bird-1.6.0-lsa-detail/proto/ospf/ospf.c --- bird-1.6.0/proto/ospf/ospf.c 2016-04-29 10:13:23.000000000 +0100 +++ bird-1.6.0-lsa-detail/proto/ospf/ospf.c 2016-08-01 12:19:55.020753968 +0100 @@ -984,32 +984,32 @@ } static inline void -show_lsa_distance(struct top_hash_entry *he) +show_lsa_distance(struct top_hash_entry *he, int reply_code) { if (he->color == INSPF) - cli_msg(-1016, "\t\tdistance %u", he->dist); + cli_msg(-reply_code, "\t\tdistance %u", he->dist); else - cli_msg(-1016, "\t\tunreachable"); + cli_msg(-reply_code, "\t\tunreachable"); } static inline void -show_lsa_router(struct ospf_proto *p, struct top_hash_entry *he, int verbose) +show_lsa_router(struct ospf_proto *p, struct top_hash_entry *he, int verbose, int reply_code) { struct ospf_lsa_rt_walk rtl; - cli_msg(-1016, ""); - cli_msg(-1016, "\trouter %R", he->lsa.rt); - show_lsa_distance(he); + cli_msg(-reply_code, ""); + cli_msg(-reply_code, "\trouter %R", he->lsa.rt); + show_lsa_distance(he, reply_code); lsa_walk_rt_init(p, he, &rtl); while (lsa_walk_rt(&rtl)) if (rtl.type == LSART_VLNK) - cli_msg(-1016, "\t\tvlink %R metric %u", rtl.id, rtl.metric); + cli_msg(-reply_code, "\t\tvlink %R metric %u", rtl.id, rtl.metric); lsa_walk_rt_init(p, he, &rtl); while (lsa_walk_rt(&rtl)) if (rtl.type == LSART_PTP) - cli_msg(-1016, "\t\trouter %R metric %u", rtl.id, rtl.metric); + cli_msg(-reply_code, "\t\trouter %R metric %u", rtl.id, rtl.metric); lsa_walk_rt_init(p, he, &rtl); while (lsa_walk_rt(&rtl)) @@ -1025,15 +1025,15 @@ struct ospf_lsa_header *net_lsa = &(net_he->lsa); struct ospf_lsa_net *net_ln = net_he->lsa_body; - cli_msg(-1016, "\t\tnetwork %I/%d metric %u", + cli_msg(-reply_code, "\t\tnetwork %I/%d metric %u", ipa_from_u32(net_lsa->id & net_ln->optx), u32_masklen(net_ln->optx), rtl.metric); } else - cli_msg(-1016, "\t\tnetwork [%R] metric %u", rtl.id, rtl.metric); + cli_msg(-reply_code, "\t\tnetwork [%R] metric %u", rtl.id, rtl.metric); } else - cli_msg(-1016, "\t\tnetwork [%R-%u] metric %u", rtl.id, rtl.nif, rtl.metric); + cli_msg(-reply_code, "\t\tnetwork [%R-%u] metric %u", rtl.id, rtl.nif, rtl.metric); } if (ospf_is_v2(p) && verbose) @@ -1041,13 +1041,13 @@ lsa_walk_rt_init(p, he, &rtl); while (lsa_walk_rt(&rtl)) if (rtl.type == LSART_STUB) - cli_msg(-1016, "\t\tstubnet %I/%d metric %u", + cli_msg(-reply_code, "\t\tstubnet %I/%d metric %u", ipa_from_u32(rtl.id), u32_masklen(rtl.data), rtl.metric); } } static inline void -show_lsa_network(struct top_hash_entry *he, int ospf2) +show_lsa_network(struct top_hash_entry *he, int ospf2, int reply_code) { struct ospf_lsa_header *lsa = &(he->lsa); struct ospf_lsa_net *ln = he->lsa_body; @@ -1055,24 +1055,24 @@ if (ospf2) { - cli_msg(-1016, ""); - cli_msg(-1016, "\tnetwork %I/%d", ipa_from_u32(lsa->id & ln->optx), u32_masklen(ln->optx)); - cli_msg(-1016, "\t\tdr %R", lsa->rt); + cli_msg(-reply_code, ""); + cli_msg(-reply_code, "\tnetwork %I/%d", ipa_from_u32(lsa->id & ln->optx), u32_masklen(ln->optx)); + cli_msg(-reply_code, "\t\tdr %R", lsa->rt); } else { - cli_msg(-1016, ""); - cli_msg(-1016, "\tnetwork [%R-%u]", lsa->rt, lsa->id); + cli_msg(-reply_code, ""); + cli_msg(-reply_code, "\tnetwork [%R-%u]", lsa->rt, lsa->id); } - show_lsa_distance(he); + show_lsa_distance(he, reply_code); for (i = 0; i < lsa_net_count(lsa); i++) - cli_msg(-1016, "\t\trouter %R", ln->routers[i]); + cli_msg(-reply_code, "\t\trouter %R", ln->routers[i]); } static inline void -show_lsa_sum_net(struct top_hash_entry *he, int ospf2) +show_lsa_sum_net(struct top_hash_entry *he, int ospf2, int reply_code) { ip_addr ip; int pxlen; @@ -1080,23 +1080,23 @@ u32 metric; lsa_parse_sum_net(he, ospf2, &ip, &pxlen, &pxopts, &metric); - cli_msg(-1016, "\t\txnetwork %I/%d metric %u", ip, pxlen, metric); + cli_msg(-reply_code, "\t\txnetwork %I/%d metric %u", ip, pxlen, metric); } static inline void -show_lsa_sum_rt(struct top_hash_entry *he, int ospf2) +show_lsa_sum_rt(struct top_hash_entry *he, int ospf2, int reply_code) { u32 metric; u32 dst_rid; u32 options; lsa_parse_sum_rt(he, ospf2, &dst_rid, &metric, &options); - cli_msg(-1016, "\t\txrouter %R metric %u", dst_rid, metric); + cli_msg(-reply_code, "\t\txrouter %R metric %u", dst_rid, metric); } static inline void -show_lsa_external(struct top_hash_entry *he, int ospf2) +show_lsa_external(struct top_hash_entry *he, int ospf2, int reply_code) { struct ospf_lsa_ext_local rt; char str_via[STD_ADDRESS_P_LENGTH + 8] = ""; @@ -1113,13 +1113,13 @@ if (rt.tag) bsprintf(str_tag, " tag %08x", rt.tag); - cli_msg(-1016, "\t\t%s %I/%d metric%s %u%s%s", + cli_msg(-reply_code, "\t\t%s %I/%d metric%s %u%s%s", (he->lsa_type == LSA_T_NSSA) ? "nssa-ext" : "external", rt.ip, rt.pxlen, rt.ebit ? "2" : "", rt.metric, str_via, str_tag); } static inline void -show_lsa_prefix(struct top_hash_entry *he, struct top_hash_entry *cnode) +show_lsa_prefix(struct top_hash_entry *he, struct top_hash_entry *cnode, int reply_code) { struct ospf_lsa_prefix *px = he->lsa_body; ip_addr pxa; @@ -1145,9 +1145,42 @@ buf = lsa_get_ipv6_prefix(buf, &pxa, &pxlen, &pxopts, &metric); if (px->ref_type == LSA_T_RT) - cli_msg(-1016, "\t\tstubnet %I/%d metric %u", pxa, pxlen, metric); + cli_msg(-reply_code, "\t\tstubnet %I/%d metric %u", pxa, pxlen, metric); else - cli_msg(-1016, "\t\taddress %I/%d", pxa, pxlen); + cli_msg(-reply_code, "\t\taddress %I/%d", pxa, pxlen); + } +} + +static void +show_lsa_detail(struct ospf_proto *p, struct top_hash_entry *he, int ospf2) +{ + switch (he->lsa_type) + { + case LSA_T_RT: + show_lsa_router(p, he, 0, 1017); + break; + + case LSA_T_NET: + show_lsa_network(he, ospf2, 1017); + break; + + case LSA_T_SUM_NET: + show_lsa_sum_net(he, ospf2, 1017); + break; + + case LSA_T_SUM_RT: + show_lsa_sum_rt(he, ospf2, 1017); + break; + + case LSA_T_EXT: + case LSA_T_NSSA: + show_lsa_external(he, ospf2, 1017); + break; + + case LSA_T_PREFIX: + /* do what? */ + /*show_lsa_prefix(he, cnode);*/ + break; } } @@ -1267,30 +1300,30 @@ { case LSA_T_RT: if (he->lsa.id == cnode->lsa.id) - show_lsa_router(p, he, verbose); + show_lsa_router(p, he, verbose, 1016); break; case LSA_T_NET: - show_lsa_network(he, ospf2); + show_lsa_network(he, ospf2, 1016); break; case LSA_T_SUM_NET: if (cnode->lsa_type == LSA_T_RT) - show_lsa_sum_net(he, ospf2); + show_lsa_sum_net(he, ospf2, 1016); break; case LSA_T_SUM_RT: if (cnode->lsa_type == LSA_T_RT) - show_lsa_sum_rt(he, ospf2); + show_lsa_sum_rt(he, ospf2, 1016); break; case LSA_T_EXT: case LSA_T_NSSA: - show_lsa_external(he, ospf2); + show_lsa_external(he, ospf2, 1016); break; case LSA_T_PREFIX: - show_lsa_prefix(he, cnode); + show_lsa_prefix(he, cnode, 1016); break; } @@ -1304,7 +1337,7 @@ ix++; while ((ix < jx) && (hex[ix]->lsa.rt == cnode->lsa.rt)) - show_lsa_external(hex[ix++], ospf2); + show_lsa_external(hex[ix++], ospf2, 1016); cnode = NULL; } @@ -1338,7 +1371,7 @@ last_rt = he->lsa.rt; } - show_lsa_external(he, ospf2); + show_lsa_external(he, ospf2, 1016); } } @@ -1458,6 +1491,9 @@ cli_msg(-1017," %04x %-15R %-15R %08x %5u %04x", lsa_type, lsa->id, lsa->rt, lsa->sn, lsa->age, lsa->checksum); + + if (ld->verbose) + show_lsa_detail(p, hea[i], ospf_is_v2(p)); } cli_msg(0, ""); } diff -dur bird-1.6.0/proto/ospf/ospf.h bird-1.6.0-lsa-detail/proto/ospf/ospf.h --- bird-1.6.0/proto/ospf/ospf.h 2015-04-22 15:41:44.000000000 +0100 +++ bird-1.6.0-lsa-detail/proto/ospf/ospf.h 2016-08-01 12:16:19.709274473 +0100 @@ -809,6 +809,7 @@ u32 area; /* Specified for area scope */ u32 lsid; /* LSA ID, 0 -> all */ u32 router; /* Advertising router, 0 -> all */ + int verbose; /* Show extra details */ };