diff options
| -rw-r--r-- | doc/user/ospfd.rst | 68 | ||||
| -rw-r--r-- | ospfd/ospf_opaque.c | 23 | ||||
| -rw-r--r-- | ospfd/ospf_opaque.h | 4 | ||||
| -rw-r--r-- | ospfd/ospf_vty.c | 1012 |
4 files changed, 847 insertions, 260 deletions
diff --git a/doc/user/ospfd.rst b/doc/user/ospfd.rst index b66774ca0e..d0c1b51820 100644 --- a/doc/user/ospfd.rst +++ b/doc/user/ospfd.rst @@ -905,59 +905,63 @@ Showing Information .. _show-ip-ospf: -.. index:: show ip ospf -.. clicmd:: show ip ospf +.. index:: show ip ospf [json] +.. clicmd:: show ip ospf [json] Show information on a variety of general OSPF and area state and configuration information. -.. index:: show ip ospf interface [INTERFACE] -.. clicmd:: show ip ospf interface [INTERFACE] +.. index:: show ip ospf interface [INTERFACE] [json] +.. clicmd:: show ip ospf interface [INTERFACE] [json] Show state and configuration of OSPF the specified interface, or all interfaces if no interface is given. -.. index:: show ip ospf neighbor -.. clicmd:: show ip ospf neighbor +.. index:: show ip ospf neighbor [json] +.. clicmd:: show ip ospf neighbor [json] -.. index:: show ip ospf neighbor INTERFACE -.. clicmd:: show ip ospf neighbor INTERFACE +.. index:: show ip ospf neighbor INTERFACE [json] +.. clicmd:: show ip ospf neighbor INTERFACE [json] -.. index:: show ip ospf neighbor detail -.. clicmd:: show ip ospf neighbor detail +.. index:: show ip ospf neighbor detail [json] +.. clicmd:: show ip ospf neighbor detail [json] -.. index:: show ip ospf neighbor INTERFACE detail -.. clicmd:: show ip ospf neighbor INTERFACE detail +.. index:: show ip ospf neighbor INTERFACE detail [json] +.. clicmd:: show ip ospf neighbor INTERFACE detail [json] -.. index:: show ip ospf database -.. clicmd:: show ip ospf database + Display lsa information of LSDB. + Json o/p of this command covers base route information + i.e all LSAs except opaque lsa info. -.. index:: show ip ospf database (asbr-summary|external|network|router|summary) -.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) +.. index:: show ip ospf database [json] +.. clicmd:: show ip ospf database [json] -.. index:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID -.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID +.. index:: show ip ospf database (asbr-summary|external|network|router|summary) [json] +.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) [json] -.. index:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID adv-router ADV-ROUTER -.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID adv-router ADV-ROUTER +.. index:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID [json] +.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID [json] -.. index:: show ip ospf database (asbr-summary|external|network|router|summary) adv-router ADV-ROUTER -.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) adv-router ADV-ROUTER +.. index:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID adv-router ADV-ROUTER [json] +.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID adv-router ADV-ROUTER [json] -.. index:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID self-originate -.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID self-originate +.. index:: show ip ospf database (asbr-summary|external|network|router|summary) adv-router ADV-ROUTER [json] +.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) adv-router ADV-ROUTER [json] -.. index:: show ip ospf database (asbr-summary|external|network|router|summary) self-originate -.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) self-originate +.. index:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID self-originate [json] +.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID self-originate [json] -.. index:: show ip ospf database max-age -.. clicmd:: show ip ospf database max-age +.. index:: show ip ospf database (asbr-summary|external|network|router|summary) self-originate [json] +.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) self-originate [json] -.. index:: show ip ospf database self-originate -.. clicmd:: show ip ospf database self-originate +.. index:: show ip ospf database max-age [json] +.. clicmd:: show ip ospf database max-age [json] -.. index:: show ip ospf route -.. clicmd:: show ip ospf route +.. index:: show ip ospf database self-originate [json] +.. clicmd:: show ip ospf database self-originate [json] + +.. index:: show ip ospf route [json] +.. clicmd:: show ip ospf route [json] Show the OSPF routing table, as determined by the most recent SPF calculation. diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c index 5ba61b3184..eb0c4a949a 100644 --- a/ospfd/ospf_opaque.c +++ b/ospfd/ospf_opaque.c @@ -1159,7 +1159,8 @@ void ospf_opaque_config_write_debug(struct vty *vty) return; } -void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa) +void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa, + json_object *json) { struct lsa_header *lsah = lsa->data; uint32_t lsid = ntohl(lsah->id.s_addr); @@ -1169,13 +1170,17 @@ void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa) /* Switch output functionality by vty address. */ if (vty != NULL) { - vty_out(vty, " Opaque-Type %u (%s)\n", opaque_type, - ospf_opaque_type_name(opaque_type)); - vty_out(vty, " Opaque-ID 0x%x\n", opaque_id); - - vty_out(vty, " Opaque-Info: %u octets of data%s\n", - ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE, - VALID_OPAQUE_INFO_LEN(lsah) ? "" : "(Invalid length?)"); + if (!json) { + vty_out(vty, " Opaque-Type %u (%s)\n", opaque_type, + ospf_opaque_type_name(opaque_type)); + vty_out(vty, " Opaque-ID 0x%x\n", opaque_id); + + vty_out(vty, " Opaque-Info: %u octets of data%s\n", + ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE, + VALID_OPAQUE_INFO_LEN(lsah) + ? "" + : "(Invalid length?)"); + } } else { zlog_debug(" Opaque-Type %u (%s)", opaque_type, ospf_opaque_type_name(opaque_type)); @@ -1200,7 +1205,7 @@ void ospf_opaque_lsa_dump(struct stream *s, uint16_t length) struct ospf_lsa lsa; lsa.data = (struct lsa_header *)stream_pnt(s); - show_opaque_info_detail(NULL, &lsa); + show_opaque_info_detail(NULL, &lsa, NULL); return; } diff --git a/ospfd/ospf_opaque.h b/ospfd/ospf_opaque.h index 96155608b2..f02f34c9af 100644 --- a/ospfd/ospf_opaque.h +++ b/ospfd/ospf_opaque.h @@ -24,6 +24,7 @@ #define _ZEBRA_OSPF_OPAQUE_H #include "vty.h" +#include <lib/json.h> #define IS_OPAQUE_LSA(type) \ ((type) == OSPF_OPAQUE_LINK_LSA || (type) == OSPF_OPAQUE_AREA_LSA \ @@ -148,7 +149,8 @@ extern void ospf_opaque_nsm_change(struct ospf_neighbor *nbr, int old_status); extern void ospf_opaque_config_write_router(struct vty *vty, struct ospf *ospf); extern void ospf_opaque_config_write_if(struct vty *vty, struct interface *ifp); extern void ospf_opaque_config_write_debug(struct vty *vty); -extern void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa); +extern void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa, + json_object *json); extern void ospf_opaque_lsa_dump(struct stream *s, uint16_t length); extern void ospf_opaque_lsa_originate_schedule(struct ospf_interface *oi, diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 7e41880bca..f8ad1064b7 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -22,6 +22,7 @@ #include <zebra.h> #include <string.h> +#include "printfrr.h" #include "monotime.h" #include "memory.h" #include "thread.h" @@ -55,6 +56,7 @@ #include "ospfd/ospf_bfd.h" #include "ospfd/ospf_ldp_sync.h" + FRR_CFG_DEFAULT_BOOL(OSPF_LOG_ADJACENCY_CHANGES, { .val_bool = true, .match_profile = "datacenter", }, { .val_bool = false }, @@ -5774,27 +5776,62 @@ DEFUN (show_ip_ospf_instance_neighbor_int_detail, } /* Show functions */ -static int show_lsa_summary(struct vty *vty, struct ospf_lsa *lsa, int self) +static int show_lsa_summary(struct vty *vty, struct ospf_lsa *lsa, int self, + json_object *json_lsa) { struct router_lsa *rl; struct summary_lsa *sl; struct as_external_lsa *asel; struct prefix_ipv4 p; + char buf[PREFIX2STR_BUFFER]; if (lsa != NULL) /* If self option is set, check LSA self flag. */ if (self == 0 || IS_LSA_SELF(lsa)) { - /* LSA common part show. */ - vty_out(vty, "%-15pI4 ", &lsa->data->id); - vty_out(vty, "%-15pI4 %4d 0x%08lx 0x%04x", - &lsa->data->adv_router, LS_AGE(lsa), - (unsigned long)ntohl(lsa->data->ls_seqnum), - ntohs(lsa->data->checksum)); + + if (!json_lsa) { + /* LSA common part show. */ + vty_out(vty, "%-15pI4", + &lsa->data->id); + vty_out(vty, "%-15s %4d 0x%08lx 0x%04x", + inet_ntoa(lsa->data->adv_router), + LS_AGE(lsa), + (unsigned long)ntohl( + lsa->data->ls_seqnum), + ntohs(lsa->data->checksum)); + } else { + char seqnum[10]; + char checksum[10]; + + snprintf(seqnum, sizeof(seqnum), "%x", + ntohl(lsa->data->ls_seqnum)); + snprintf(checksum, sizeof(checksum), "%x", + ntohs(lsa->data->checksum)); + json_object_string_add( + json_lsa, "lsId", + inet_ntoa(lsa->data->id)); + json_object_string_add( + json_lsa, "advertisedRouter", + inet_ntoa(lsa->data->adv_router)); + json_object_int_add(json_lsa, "lsaAge", + LS_AGE(lsa)); + json_object_string_add( + json_lsa, "sequenceNumber", seqnum); + json_object_string_add(json_lsa, "checksum", + checksum); + } + /* LSA specific part show. */ switch (lsa->data->type) { case OSPF_ROUTER_LSA: rl = (struct router_lsa *)lsa->data; - vty_out(vty, " %-d", ntohs(rl->links)); + + if (!json_lsa) + vty_out(vty, " %-d", ntohs(rl->links)); + else + json_object_int_add(json_lsa, + "numOfRouterLinks", + ntohs(rl->links)); break; case OSPF_SUMMARY_LSA: sl = (struct summary_lsa *)lsa->data; @@ -5804,7 +5841,14 @@ static int show_lsa_summary(struct vty *vty, struct ospf_lsa *lsa, int self) p.prefixlen = ip_masklen(sl->mask); apply_mask_ipv4(&p); - vty_out(vty, " %pFX", &p); + if (!json_lsa) + vty_out(vty, " %pFX", &p); + else { + prefix2str(&p, buf, sizeof(buf)); + json_object_string_add(json_lsa, + "summaryAddress", + buf); + } break; case OSPF_AS_EXTERNAL_LSA: case OSPF_AS_NSSA_LSA: @@ -5815,13 +5859,30 @@ static int show_lsa_summary(struct vty *vty, struct ospf_lsa *lsa, int self) p.prefixlen = ip_masklen(asel->mask); apply_mask_ipv4(&p); - vty_out(vty, " %s %pFX [0x%lx]", - IS_EXTERNAL_METRIC(asel->e[0].tos) - ? "E2" - : "E1", - &p, - (unsigned long)ntohl( - asel->e[0].route_tag)); + if (!json_lsa) + vty_out(vty, " %s %pFX [0x%lx]", + IS_EXTERNAL_METRIC( + asel->e[0].tos) + ? "E2" + : "E1", + &p, + (unsigned long)ntohl( + asel->e[0].route_tag)); + else { + prefix2str(&p, buf, sizeof(buf)); + json_object_string_add( + json_lsa, "metricType", + IS_EXTERNAL_METRIC( + asel->e[0].tos) + ? "E2" + : "E1"); + json_object_string_add(json_lsa, + "route", buf); + json_object_int_add( + json_lsa, "tag", + (unsigned long)ntohl( + asel->e[0].route_tag)); + } break; case OSPF_NETWORK_LSA: case OSPF_ASBR_SUMMARY_LSA: @@ -5831,7 +5892,9 @@ static int show_lsa_summary(struct vty *vty, struct ospf_lsa *lsa, int self) default: break; } - vty_out(vty, "\n"); + + if (!json_lsa) + vty_out(vty, "\n"); } return 0; @@ -5852,6 +5915,21 @@ static const char *const show_database_desc[] = { "AS-external Opaque-LSA", }; +static const char * const show_database_desc_json[] = { + "unknown", + "routerLinkStates", + "networkLinkStates", + "summaryLinkStates", + "asbrSummaryLinkStates", + "asExternalLinkStates", + "groupMembershipLsa", + "nssaExternalLinkStates", + "type8Lsa", + "linkLocalOpaqueLsa", + "areaLocalOpaqueLsa", + "asExternalOpaqueLsa", +}; + static const char *const show_database_header[] = { "", "Link ID ADV Router Age Seq# CkSum Link count", @@ -5867,41 +5945,97 @@ static const char *const show_database_header[] = { "Opaque-Type/Id ADV Router Age Seq# CkSum", }; -static void show_ip_ospf_database_header(struct vty *vty, struct ospf_lsa *lsa) +static void show_ip_ospf_database_header(struct vty *vty, struct ospf_lsa *lsa, + json_object *json) { struct router_lsa *rlsa = (struct router_lsa *)lsa->data; - vty_out(vty, " LS age: %d\n", LS_AGE(lsa)); - vty_out(vty, " Options: 0x%-2x : %s\n", lsa->data->options, - ospf_options_dump(lsa->data->options)); - vty_out(vty, " LS Flags: 0x%-2x %s\n", lsa->flags, - ((lsa->flags & OSPF_LSA_LOCAL_XLT) ? "(Translated from Type-7)" - : "")); - - if (lsa->data->type == OSPF_ROUTER_LSA) { - vty_out(vty, " Flags: 0x%x", rlsa->flags); - - if (rlsa->flags) - vty_out(vty, " :%s%s%s%s", - IS_ROUTER_LSA_BORDER(rlsa) ? " ABR" : "", - IS_ROUTER_LSA_EXTERNAL(rlsa) ? " ASBR" : "", - IS_ROUTER_LSA_VIRTUAL(rlsa) ? " VL-endpoint" - : "", - IS_ROUTER_LSA_SHORTCUT(rlsa) ? " Shortcut" - : ""); + if (!json) { + vty_out(vty, " LS age: %d\n", LS_AGE(lsa)); + vty_out(vty, " Options: 0x%-2x : %s\n", lsa->data->options, + ospf_options_dump(lsa->data->options)); + vty_out(vty, " LS Flags: 0x%-2x %s\n", lsa->flags, + ((lsa->flags & OSPF_LSA_LOCAL_XLT) + ? "(Translated from Type-7)" + : "")); + + if (lsa->data->type == OSPF_ROUTER_LSA) { + vty_out(vty, " Flags: 0x%x", rlsa->flags); + + if (rlsa->flags) + vty_out(vty, " :%s%s%s%s", + IS_ROUTER_LSA_BORDER(rlsa) ? " ABR" + : "", + IS_ROUTER_LSA_EXTERNAL(rlsa) ? " ASBR" + : "", + IS_ROUTER_LSA_VIRTUAL(rlsa) + ? " VL-endpoint" + : "", + IS_ROUTER_LSA_SHORTCUT(rlsa) + ? " Shortcut" + : ""); - vty_out(vty, "\n"); + vty_out(vty, "\n"); + } + vty_out(vty, " LS Type: %s\n", + lookup_msg(ospf_lsa_type_msg, lsa->data->type, NULL)); + vty_out(vty, " Link State ID: %pI4 %s\n", + &lsa->data->id, + lookup_msg(ospf_link_state_id_type_msg, lsa->data->type, + NULL)); + vty_out(vty, " Advertising Router: %pI4\n", + &lsa->data->adv_router); + vty_out(vty, " LS Seq Number: %08lx\n", + (unsigned long)ntohl(lsa->data->ls_seqnum)); + vty_out(vty, " Checksum: 0x%04x\n", + ntohs(lsa->data->checksum)); + vty_out(vty, " Length: %d\n\n", ntohs(lsa->data->length)); + } else { + char seqnum[10]; + char checksum[10]; + + snprintf(seqnum, 10, "%x", ntohl(lsa->data->ls_seqnum)); + snprintf(checksum, 10, "%x", ntohs(lsa->data->checksum)); + + json_object_int_add(json, "lsaAge", LS_AGE(lsa)); + json_object_string_add(json, "options", + ospf_options_dump(lsa->data->options)); + json_object_int_add(json, "lsaFlags", lsa->flags); + + if (lsa->flags & OSPF_LSA_LOCAL_XLT) + json_object_boolean_true_add(json, + "translatedFromType7"); + + if (lsa->data->type == OSPF_ROUTER_LSA) { + json_object_int_add(json, "flags", rlsa->flags); + + if (rlsa->flags) { + if (IS_ROUTER_LSA_BORDER(rlsa)) + json_object_boolean_true_add(json, + "abr"); + if (IS_ROUTER_LSA_EXTERNAL(rlsa)) + json_object_boolean_true_add(json, + "asbr"); + if (IS_ROUTER_LSA_VIRTUAL(rlsa)) + json_object_boolean_true_add( + json, "vlEndpoint"); + if (IS_ROUTER_LSA_SHORTCUT(rlsa)) + json_object_boolean_true_add( + json, "shortcut"); + } + } + + json_object_string_add( + json, "lsaType", + lookup_msg(ospf_lsa_type_msg, lsa->data->type, NULL)); + json_object_string_add(json, "linkStateId", + inet_ntoa(lsa->data->id)); + json_object_string_add(json, "advertisingRouter", + inet_ntoa(lsa->data->adv_router)); + json_object_string_add(json, "lsaSeqNumber", seqnum); + json_object_string_add(json, "checksum", checksum); + json_object_int_add(json, "length", ntohs(lsa->data->length)); } - vty_out(vty, " LS Type: %s\n", - lookup_msg(ospf_lsa_type_msg, lsa->data->type, NULL)); - vty_out(vty, " Link State ID: %pI4 %s\n", &lsa->data->id, - lookup_msg(ospf_link_state_id_type_msg, lsa->data->type, NULL)); - vty_out(vty, " Advertising Router: %pI4\n", - &lsa->data->adv_router); - vty_out(vty, " LS Seq Number: %08lx\n", - (unsigned long)ntohl(lsa->data->ls_seqnum)); - vty_out(vty, " Checksum: 0x%04x\n", ntohs(lsa->data->checksum)); - vty_out(vty, " Length: %d\n\n", ntohs(lsa->data->length)); } static const char *const link_type_desc[] = { @@ -5922,128 +6056,240 @@ static const char *const link_data_desc[] = { "Network Mask", "Router Interface address", }; +static const char *const link_id_desc_json[] = { + "null", "neighborRouterId", "designatedRouterAddress", + "networkAddress", "neighborRouterId", +}; + +static const char *const link_data_desc_json[] = { + "null", "routerInterfaceAddress", "routerInterfaceAddress", + "networkMask", "routerInterfaceAddress", +}; + /* Show router-LSA each Link information. */ static void show_ip_ospf_database_router_links(struct vty *vty, - struct router_lsa *rl) + struct router_lsa *rl, + json_object *json) { int len, type; - unsigned int i; + unsigned short i; + json_object *json_links = NULL; + json_object *json_link = NULL; + int metric = 0; + + if (json) + json_links = json_object_new_object(); len = ntohs(rl->header.length) - 4; for (i = 0; i < ntohs(rl->links) && len > 0; len -= 12, i++) { type = rl->link[i].type; - vty_out(vty, " Link connected to: %s\n", - link_type_desc[type]); - vty_out(vty, " (Link ID) %s: %pI4\n", link_id_desc[type], - &rl->link[i].link_id); - vty_out(vty, " (Link Data) %s: %pI4\n", - link_data_desc[type], &rl->link[i].link_data); - vty_out(vty, " Number of TOS metrics: 0\n"); - vty_out(vty, " TOS 0 Metric: %d\n", - ntohs(rl->link[i].metric)); - vty_out(vty, "\n"); + if (json) { + char link[16]; + + snprintf(link, sizeof(link), "link%u", i); + json_link = json_object_new_object(); + json_object_string_add(json_link, "linkType", + link_type_desc[type]); + json_object_string_add(json_link, + link_id_desc_json[type], + inet_ntoa(rl->link[i].link_id)); + json_object_string_add( + json_link, link_data_desc_json[type], + inet_ntoa(rl->link[i].link_data)); + json_object_int_add(json_link, "numOfTosMetrics", + metric); + json_object_int_add(json_link, "tos0Metric", + ntohs(rl->link[i].metric)); + json_object_object_add(json_links, link, json_link); + } else { + vty_out(vty, " Link connected to: %s\n", + link_type_desc[type]); + vty_out(vty, " (Link ID) %s: %pI4\n", + link_id_desc[type], + &rl->link[i].link_id); + vty_out(vty, " (Link Data) %s: %pI4\n", + link_data_desc[type], + &rl->link[i].link_data); + vty_out(vty, " Number of TOS metrics: 0\n"); + vty_out(vty, " TOS 0 Metric: %d\n", + ntohs(rl->link[i].metric)); + vty_out(vty, "\n"); + } } + if (json) + json_object_object_add(json, "routerLinks", json_links); } /* Show router-LSA detail information. */ -static int show_router_lsa_detail(struct vty *vty, struct ospf_lsa *lsa) +static int show_router_lsa_detail(struct vty *vty, struct ospf_lsa *lsa, + json_object *json) { if (lsa != NULL) { struct router_lsa *rl = (struct router_lsa *)lsa->data; - show_ip_ospf_database_header(vty, lsa); + show_ip_ospf_database_header(vty, lsa, json); - vty_out(vty, " Number of Links: %d\n\n", ntohs(rl->links)); + if (!json) + vty_out(vty, " Number of Links: %d\n\n", + ntohs(rl->links)); + else + json_object_int_add(json, "numOfLinks", + ntohs(rl->links)); - show_ip_ospf_database_router_links(vty, rl); - vty_out(vty, "\n"); + show_ip_ospf_database_router_links(vty, rl, json); + + if (!json) + vty_out(vty, "\n"); } return 0; } /* Show network-LSA detail information. */ -static int show_network_lsa_detail(struct vty *vty, struct ospf_lsa *lsa) +static int show_network_lsa_detail(struct vty *vty, struct ospf_lsa *lsa, + json_object *json) { int length, i; + json_object *json_attached_rt = NULL; + json_object *json_router = NULL; + + if (json) + json_attached_rt = json_object_new_object(); if (lsa != NULL) { struct network_lsa *nl = (struct network_lsa *)lsa->data; - show_ip_ospf_database_header(vty, lsa); + show_ip_ospf_database_header(vty, lsa, json); - vty_out(vty, " Network Mask: /%d\n", ip_masklen(nl->mask)); + if (!json) + vty_out(vty, " Network Mask: /%d\n", + ip_masklen(nl->mask)); + else + json_object_int_add(json, "networkMask", + ip_masklen(nl->mask)); length = ntohs(lsa->data->length) - OSPF_LSA_HEADER_SIZE - 4; for (i = 0; length > 0; i++, length -= 4) - vty_out(vty, " Attached Router: %pI4\n", - &nl->routers[i]); - - vty_out(vty, "\n"); + if (!json) { + vty_out(vty, " Attached Router: %pI4\n", + &nl->routers[i]); + vty_out(vty, "\n"); + } else { + json_router = json_object_new_object(); + json_object_string_add( + json_router, "attachedRouterId", + inet_ntoa(nl->routers[i])); + json_object_object_add( + json_attached_rt, + inet_ntoa(nl->routers[i]), json_router); + } } + if (json) + json_object_object_add(json, "attchedRouters", + json_attached_rt); + return 0; } /* Show summary-LSA detail information. */ -static int show_summary_lsa_detail(struct vty *vty, struct ospf_lsa *lsa) +static int show_summary_lsa_detail(struct vty *vty, struct ospf_lsa *lsa, + json_object *json) { if (lsa != NULL) { struct summary_lsa *sl = (struct summary_lsa *)lsa->data; - show_ip_ospf_database_header(vty, lsa); + show_ip_ospf_database_header(vty, lsa, json); - vty_out(vty, " Network Mask: /%d\n", ip_masklen(sl->mask)); - vty_out(vty, " TOS: 0 Metric: %d\n", - GET_METRIC(sl->metric)); - vty_out(vty, "\n"); + if (!json) { + vty_out(vty, " Network Mask: /%d\n", + ip_masklen(sl->mask)); + vty_out(vty, " TOS: 0 Metric: %d\n", + GET_METRIC(sl->metric)); + vty_out(vty, "\n"); + } else { + json_object_int_add(json, "networkMask", + ip_masklen(sl->mask)); + json_object_int_add(json, "tos0Metric", + GET_METRIC(sl->metric)); + } } return 0; } /* Show summary-ASBR-LSA detail information. */ -static int show_summary_asbr_lsa_detail(struct vty *vty, struct ospf_lsa *lsa) +static int show_summary_asbr_lsa_detail(struct vty *vty, struct ospf_lsa *lsa, + json_object *json) { if (lsa != NULL) { struct summary_lsa *sl = (struct summary_lsa *)lsa->data; - show_ip_ospf_database_header(vty, lsa); + show_ip_ospf_database_header(vty, lsa, json); - vty_out(vty, " Network Mask: /%d\n", ip_masklen(sl->mask)); - vty_out(vty, " TOS: 0 Metric: %d\n", - GET_METRIC(sl->metric)); - vty_out(vty, "\n"); + if (!json) { + vty_out(vty, " Network Mask: /%d\n", + ip_masklen(sl->mask)); + vty_out(vty, " TOS: 0 Metric: %d\n", + GET_METRIC(sl->metric)); + vty_out(vty, "\n"); + } else { + json_object_int_add(json, "networkMask", + ip_masklen(sl->mask)); + json_object_int_add(json, "tos0Metric", + GET_METRIC(sl->metric)); + } } return 0; } /* Show AS-external-LSA detail information. */ -static int show_as_external_lsa_detail(struct vty *vty, struct ospf_lsa *lsa) +static int show_as_external_lsa_detail(struct vty *vty, struct ospf_lsa *lsa, + json_object *json) { + int tos = 0; + if (lsa != NULL) { struct as_external_lsa *al = (struct as_external_lsa *)lsa->data; - show_ip_ospf_database_header(vty, lsa); - - vty_out(vty, " Network Mask: /%d\n", ip_masklen(al->mask)); - vty_out(vty, " Metric Type: %s\n", - IS_EXTERNAL_METRIC(al->e[0].tos) - ? "2 (Larger than any link state path)" - : "1"); - vty_out(vty, " TOS: 0\n"); - vty_out(vty, " Metric: %d\n", - GET_METRIC(al->e[0].metric)); - vty_out(vty, " Forward Address: %pI4\n", - &al->e[0].fwd_addr); - - vty_out(vty, - " External Route Tag: %" ROUTE_TAG_PRI "\n\n", - (route_tag_t)ntohl(al->e[0].route_tag)); + show_ip_ospf_database_header(vty, lsa, json); + + if (!json) { + vty_out(vty, " Network Mask: /%d\n", + ip_masklen(al->mask)); + vty_out(vty, " Metric Type: %s\n", + IS_EXTERNAL_METRIC(al->e[0].tos) + ? "2 (Larger than any link state path)" + : "1"); + vty_out(vty, " TOS: 0\n"); + vty_out(vty, " Metric: %d\n", + GET_METRIC(al->e[0].metric)); + vty_out(vty, " Forward Address: %pI4\n", + &al->e[0].fwd_addr); + vty_out(vty, + " External Route Tag: %" ROUTE_TAG_PRI "\n\n", + (route_tag_t)ntohl(al->e[0].route_tag)); + } else { + json_object_int_add(json, "networkMask", + ip_masklen(al->mask)); + json_object_string_add( + json, "metricType", + IS_EXTERNAL_METRIC(al->e[0].tos) + ? "E2 (Larger than any link state path)" + : "E1"); + json_object_int_add(json, "tos", tos); + json_object_int_add(json, "metric", + GET_METRIC(al->e[0].metric)); + json_object_string_add(json, "forwardAddress", + inet_ntoa(al->e[0].fwd_addr)); + json_object_int_add( + json, "externalRouteTag", + (route_tag_t)ntohl(al->e[0].route_tag)); + } } return 0; @@ -6074,50 +6320,74 @@ show_as_external_lsa_stdvty (struct ospf_lsa *lsa) } #endif /* Show AS-NSSA-LSA detail information. */ -static int show_as_nssa_lsa_detail(struct vty *vty, struct ospf_lsa *lsa) +static int show_as_nssa_lsa_detail(struct vty *vty, struct ospf_lsa *lsa, + json_object *json) { + int tos = 0; + if (lsa != NULL) { struct as_external_lsa *al = (struct as_external_lsa *)lsa->data; - show_ip_ospf_database_header(vty, lsa); - - vty_out(vty, " Network Mask: /%d\n", ip_masklen(al->mask)); - vty_out(vty, " Metric Type: %s\n", - IS_EXTERNAL_METRIC(al->e[0].tos) - ? "2 (Larger than any link state path)" - : "1"); - vty_out(vty, " TOS: 0\n"); - vty_out(vty, " Metric: %d\n", - GET_METRIC(al->e[0].metric)); - vty_out(vty, " NSSA: Forward Address: %pI4\n", - &al->e[0].fwd_addr); - - vty_out(vty, - " External Route Tag: %" ROUTE_TAG_PRI "\n\n", - (route_tag_t)ntohl(al->e[0].route_tag)); + show_ip_ospf_database_header(vty, lsa, json); + + if (!json) { + vty_out(vty, " Network Mask: /%d\n", + ip_masklen(al->mask)); + vty_out(vty, " Metric Type: %s\n", + IS_EXTERNAL_METRIC(al->e[0].tos) + ? "2 (Larger than any link state path)" + : "1"); + vty_out(vty, " TOS: 0\n"); + vty_out(vty, " Metric: %d\n", + GET_METRIC(al->e[0].metric)); + vty_out(vty, " NSSA: Forward Address: %pI4\n", + &al->e[0].fwd_addr); + vty_out(vty, + " External Route Tag: %" ROUTE_TAG_PRI + "\n\n", + (route_tag_t)ntohl(al->e[0].route_tag)); + } else { + json_object_int_add(json, "networkMask", + ip_masklen(al->mask)); + json_object_string_add( + json, "metricType", + IS_EXTERNAL_METRIC(al->e[0].tos) + ? "E2 (Larger than any link state path)" + : "E1"); + json_object_int_add(json, "tos", tos); + json_object_int_add(json, "metric", + GET_METRIC(al->e[0].metric)); + json_object_string_add(json, "nssaForwardAddress", + inet_ntoa(al->e[0].fwd_addr)); + json_object_int_add( + json, "externalRouteTag", + (route_tag_t)ntohl(al->e[0].route_tag)); + } } return 0; } -static int show_func_dummy(struct vty *vty, struct ospf_lsa *lsa) +static int show_func_dummy(struct vty *vty, struct ospf_lsa *lsa, + json_object *json) { return 0; } -static int show_opaque_lsa_detail(struct vty *vty, struct ospf_lsa *lsa) +static int show_opaque_lsa_detail(struct vty *vty, struct ospf_lsa *lsa, + json_object *json) { if (lsa != NULL) { - show_ip_ospf_database_header(vty, lsa); - show_opaque_info_detail(vty, lsa); - - vty_out(vty, "\n"); + show_ip_ospf_database_header(vty, lsa, json); + show_opaque_info_detail(vty, lsa, json); + if (!json) + vty_out(vty, "\n"); } return 0; } -int (*const show_function[])(struct vty *, struct ospf_lsa *) = { +int (*show_function[])(struct vty *, struct ospf_lsa *, json_object *) = { NULL, show_router_lsa_detail, show_network_lsa_detail, @@ -6150,11 +6420,13 @@ static void show_lsa_prefix_set(struct vty *vty, struct prefix_ls *lp, } static void show_lsa_detail_proc(struct vty *vty, struct route_table *rt, - struct in_addr *id, struct in_addr *adv_router) + struct in_addr *id, struct in_addr *adv_router, + json_object *json) { struct prefix_ls lp; struct route_node *rn, *start; struct ospf_lsa *lsa; + json_object *json_lsa = NULL; show_lsa_prefix_set(vty, &lp, id, adv_router); start = route_node_get(rt, (struct prefix *)&lp); @@ -6162,9 +6434,14 @@ static void show_lsa_detail_proc(struct vty *vty, struct route_table *rt, route_lock_node(start); for (rn = start; rn; rn = route_next_until(rn, start)) if ((lsa = rn->info)) { + if (json) { + json_lsa = json_object_new_object(); + json_object_array_add(json, json_lsa); + } + if (show_function[lsa->data->type] != NULL) - show_function[lsa->data->type](vty, - lsa); + show_function[lsa->data->type]( + vty, lsa, json_lsa); } route_unlock_node(start); } @@ -6173,25 +6450,62 @@ static void show_lsa_detail_proc(struct vty *vty, struct route_table *rt, /* Show detail LSA information -- if id is NULL then show all LSAs. */ static void show_lsa_detail(struct vty *vty, struct ospf *ospf, int type, - struct in_addr *id, struct in_addr *adv_router) + struct in_addr *id, struct in_addr *adv_router, + json_object *json) { struct listnode *node; struct ospf_area *area; + json_object *json_lsa_type = NULL; + json_object *json_areas = NULL; + json_object *json_lsa_array = NULL; + + if (json) + json_lsa_type = json_object_new_object(); switch (type) { case OSPF_AS_EXTERNAL_LSA: case OSPF_OPAQUE_AS_LSA: - vty_out(vty, " %s \n\n", - show_database_desc[type]); - show_lsa_detail_proc(vty, AS_LSDB(ospf, type), id, adv_router); + if (!json) + vty_out(vty, " %s \n\n", + show_database_desc[type]); + else + json_lsa_array = json_object_new_array(); + + show_lsa_detail_proc(vty, AS_LSDB(ospf, type), id, adv_router, + json_lsa_array); + if (json) + json_object_object_add(json, + show_database_desc_json[type], + json_lsa_array); + break; default: + if (json) + json_areas = json_object_new_object(); + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { - vty_out(vty, "\n %s (Area %s)\n\n", - show_database_desc[type], - ospf_area_desc_string(area)); + if (!json) { + vty_out(vty, + "\n %s (Area %s)\n\n", + show_database_desc[type], + ospf_area_desc_string(area)); + } else { + json_lsa_array = json_object_new_array(); + json_object_object_add(json_areas, + inet_ntoa(area->area_id), + json_lsa_array); + } + show_lsa_detail_proc(vty, AREA_LSDB(area, type), id, - adv_router); + adv_router, json_lsa_array); + } + + if (json) { + json_object_object_add(json_lsa_type, "areas", + json_areas); + json_object_object_add(json, + show_database_desc_json[type], + json_lsa_type); } break; } @@ -6199,60 +6513,104 @@ static void show_lsa_detail(struct vty *vty, struct ospf *ospf, int type, static void show_lsa_detail_adv_router_proc(struct vty *vty, struct route_table *rt, - struct in_addr *adv_router) + struct in_addr *adv_router, + json_object *json) { struct route_node *rn; struct ospf_lsa *lsa; for (rn = route_top(rt); rn; rn = route_next(rn)) - if ((lsa = rn->info)) + if ((lsa = rn->info)) { + json_object *json_lsa = NULL; + if (IPV4_ADDR_SAME(adv_router, &lsa->data->adv_router)) { if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT)) continue; + if (json) + json_lsa = json_object_new_object(); + if (show_function[lsa->data->type] != NULL) - show_function[lsa->data->type](vty, - lsa); + show_function[lsa->data->type]( + vty, lsa, json_lsa); + if (json) + json_object_object_add( + json, inet_ntoa(lsa->data->id), + json_lsa); } + } } /* Show detail LSA information. */ static void show_lsa_detail_adv_router(struct vty *vty, struct ospf *ospf, - int type, struct in_addr *adv_router) + int type, struct in_addr *adv_router, + json_object *json) { struct listnode *node; struct ospf_area *area; + json_object *json_lstype = NULL; + json_object *json_area = NULL; + + if (json) + json_lstype = json_object_new_object(); switch (type) { case OSPF_AS_EXTERNAL_LSA: case OSPF_OPAQUE_AS_LSA: - vty_out(vty, " %s \n\n", - show_database_desc[type]); + if (!json) + vty_out(vty, " %s \n\n", + show_database_desc[type]); + show_lsa_detail_adv_router_proc(vty, AS_LSDB(ospf, type), - adv_router); + adv_router, json_lstype); break; default: + for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { - vty_out(vty, "\n %s (Area %s)\n\n", - show_database_desc[type], - ospf_area_desc_string(area)); - show_lsa_detail_adv_router_proc( - vty, AREA_LSDB(area, type), adv_router); + if (json) + json_area = json_object_new_object(); + else + vty_out(vty, + "\n %s (Area %s)\n\n", + show_database_desc[type], + ospf_area_desc_string(area)); + show_lsa_detail_adv_router_proc(vty, + AREA_LSDB(area, type), + adv_router, json_area); + + if (json) + json_object_object_add(json_lstype, + inet_ntoa(area->area_id), + json_area); } break; } + + if (json) + json_object_object_add(json, show_database_desc[type], + json_lstype); } static void show_ip_ospf_database_summary(struct vty *vty, struct ospf *ospf, - int self) + int self, json_object *json) { struct ospf_lsa *lsa; struct route_node *rn; struct ospf_area *area; struct listnode *node; + json_object *json_areas = NULL; + json_object *json_area = NULL; + json_object *json_lsa = NULL; int type; + json_object *json_lsa_array = NULL; + + if (json) + json_areas = json_object_new_object(); for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { + if (json) + json_area = json_object_new_object(); + for (type = OSPF_MIN_LSA; type < OSPF_MAX_LSA; type++) { switch (type) { case OSPF_AS_EXTERNAL_LSA: @@ -6264,20 +6622,49 @@ static void show_ip_ospf_database_summary(struct vty *vty, struct ospf *ospf, if (ospf_lsdb_count_self(area->lsdb, type) > 0 || (!self && ospf_lsdb_count(area->lsdb, type) > 0)) { - vty_out(vty, " %s (Area %s)\n\n", - show_database_desc[type], - ospf_area_desc_string(area)); - vty_out(vty, "%s\n", - show_database_header[type]); - LSDB_LOOP (AREA_LSDB(area, type), rn, lsa) - show_lsa_summary(vty, lsa, self); + if (!json) { + vty_out(vty, + " %s (Area %s)\n\n", + show_database_desc[type], + ospf_area_desc_string(area)); + vty_out(vty, "%s\n", + show_database_header[type]); + } else { + json_lsa_array = + json_object_new_array(); + json_object_object_add( + json_area, + show_database_desc_json[type], + json_lsa_array); + } + + LSDB_LOOP (AREA_LSDB(area, type), rn, lsa) { + if (json) { + json_lsa = + json_object_new_object(); + json_object_array_add( + json_lsa_array, + json_lsa); + } - vty_out(vty, "\n"); + show_lsa_summary(vty, lsa, self, + json_lsa); + } + + if (!json) + vty_out(vty, "\n"); } } + if (json) + json_object_object_add(json_areas, + inet_ntoa(area->area_id), + json_area); } + if (json) + json_object_object_add(json, "areas", json_areas); + for (type = OSPF_MIN_LSA; type < OSPF_MAX_LSA; type++) { switch (type) { case OSPF_AS_EXTERNAL_LSA: @@ -6288,39 +6675,82 @@ static void show_ip_ospf_database_summary(struct vty *vty, struct ospf *ospf, } if (ospf_lsdb_count_self(ospf->lsdb, type) || (!self && ospf_lsdb_count(ospf->lsdb, type))) { - vty_out(vty, " %s\n\n", - show_database_desc[type]); - vty_out(vty, "%s\n", show_database_header[type]); + if (!json) { + vty_out(vty, " %s\n\n", + show_database_desc[type]); + vty_out(vty, "%s\n", + show_database_header[type]); + } else { + json_lsa_array = json_object_new_array(); + json_object_object_add( + json, show_database_desc_json[type], + json_lsa_array); + } - LSDB_LOOP (AS_LSDB(ospf, type), rn, lsa) - show_lsa_summary(vty, lsa, self); + LSDB_LOOP (AS_LSDB(ospf, type), rn, lsa) { + if (json) { + json_lsa = json_object_new_object(); + json_object_array_add(json_lsa_array, + json_lsa); + } - vty_out(vty, "\n"); + show_lsa_summary(vty, lsa, self, json_lsa); + } + + if (!json) + vty_out(vty, "\n"); } } - vty_out(vty, "\n"); + if (!json) + vty_out(vty, "\n"); } -static void show_ip_ospf_database_maxage(struct vty *vty, struct ospf *ospf) +static void show_ip_ospf_database_maxage(struct vty *vty, struct ospf *ospf, + json_object *json) { struct route_node *rn; + json_object *json_maxage = NULL; - vty_out(vty, "\n MaxAge Link States:\n\n"); + if (!json) + vty_out(vty, "\n MaxAge Link States:\n\n"); + else + json_maxage = json_object_new_object(); for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn)) { struct ospf_lsa *lsa; + json_object *json_lsa = NULL; if ((lsa = rn->info) != NULL) { - vty_out(vty, "Link type: %d\n", lsa->data->type); - vty_out(vty, "Link State ID: %pI4\n", - &lsa->data->id); - vty_out(vty, "Advertising Router: %pI4\n", - &lsa->data->adv_router); - vty_out(vty, "LSA lock count: %d\n", lsa->lock); - vty_out(vty, "\n"); + if (!json) { + vty_out(vty, "Link type: %d\n", + lsa->data->type); + vty_out(vty, "Link State ID: %s\n", + inet_ntoa(lsa->data->id)); + vty_out(vty, "Advertising Router: %pI4\n", + &lsa->data->adv_router); + vty_out(vty, "LSA lock count: %d\n", lsa->lock); + vty_out(vty, "\n"); + } else { + json_lsa = json_object_new_object(); + json_object_int_add(json_lsa, "linkType", + lsa->data->type); + json_object_string_add( + json_lsa, "linkStateId", + inet_ntoa(lsa->data->id)); + json_object_string_add( + json_lsa, "advertisingRouter", + inet_ntoa(lsa->data->adv_router)); + json_object_int_add(json_lsa, "lsaLockCount", + lsa->lock); + json_object_object_add(json_maxage, + inet_ntoa(lsa->data->id), + json_lsa); + } } } + if (json) + json_object_object_add(json, "maxAgeLinkStates", json_maxage); } #define OSPF_LSA_TYPE_NSSA_DESC "NSSA external link state\n" @@ -6343,23 +6773,53 @@ static void show_ip_ospf_database_maxage(struct vty *vty, struct ospf *ospf) static int show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf, int arg_base, int argc, struct cmd_token **argv, - uint8_t use_vrf) + uint8_t use_vrf, json_object *json, + bool uj) { int idx_type = 4; int type, ret; struct in_addr id, adv_router; + json_object *json_vrf = NULL; - if (ospf->instance) - vty_out(vty, "\nOSPF Instance: %d\n", ospf->instance); + if (uj) { + if (use_vrf) + json_vrf = json_object_new_object(); + else + json_vrf = json; + } - ospf_show_vrf_name(ospf, vty, NULL, use_vrf); + if (ospf->instance) { + if (uj) + json_object_int_add(json_vrf, "ospfInstance", + ospf->instance); + else + vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); + } - vty_out(vty, "\n OSPF Router with ID (%pI4)\n\n", - &ospf->router_id); + ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf); + + /* Show Router ID. */ + if (uj) { + json_object_string_add(json_vrf, "routerId", + inet_ntoa(ospf->router_id)); + } else { + vty_out(vty, "\n OSPF Router with ID (%pI4)\n\n", + &ospf->router_id); + } /* Show all LSA. */ - if (argc == arg_base + 4) { - show_ip_ospf_database_summary(vty, ospf, 0); + if ((argc == arg_base + 4) || (uj && (argc == arg_base + 5))) { + show_ip_ospf_database_summary(vty, ospf, 0, json_vrf); + if (json) { + if (use_vrf) { + if (ospf->vrf_id == VRF_DEFAULT) + json_object_object_add(json, "default", + json_vrf); + else + json_object_object_add(json, ospf->name, + json_vrf); + } + } return CMD_SUCCESS; } @@ -6377,10 +6837,30 @@ static int show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf, else if (strncmp(argv[arg_base + idx_type]->text, "e", 1) == 0) type = OSPF_AS_EXTERNAL_LSA; else if (strncmp(argv[arg_base + idx_type]->text, "se", 2) == 0) { - show_ip_ospf_database_summary(vty, ospf, 1); + show_ip_ospf_database_summary(vty, ospf, 1, json_vrf); + if (json) { + if (use_vrf) { + if (ospf->vrf_id == VRF_DEFAULT) + json_object_object_add(json, "default", + json_vrf); + else + json_object_object_add(json, ospf->name, + json_vrf); + } + } return CMD_SUCCESS; } else if (strncmp(argv[arg_base + idx_type]->text, "m", 1) == 0) { - show_ip_ospf_database_maxage(vty, ospf); + show_ip_ospf_database_maxage(vty, ospf, json_vrf); + if (json) { + if (use_vrf) { + if (ospf->vrf_id == VRF_DEFAULT) + json_object_object_add(json, "default", + json_vrf); + else + json_object_object_add(json, ospf->name, + json_vrf); + } + } return CMD_SUCCESS; } else if (strncmp(argv[arg_base + idx_type]->text, "opaque-l", 8) == 0) type = OSPF_OPAQUE_LINK_LSA; @@ -6392,18 +6872,19 @@ static int show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf, return CMD_WARNING; /* `show ip ospf database LSA'. */ - if (argc == arg_base + 5) - show_lsa_detail(vty, ospf, type, NULL, NULL); + if ((argc == arg_base + 5) || (uj && (argc == arg_base + 6))) + show_lsa_detail(vty, ospf, type, NULL, NULL, json_vrf); else if (argc >= arg_base + 6) { ret = inet_aton(argv[arg_base + 5]->arg, &id); if (!ret) return CMD_WARNING; /* `show ip ospf database LSA ID'. */ - if (argc == arg_base + 6) - show_lsa_detail(vty, ospf, type, &id, NULL); + if ((argc == arg_base + 6) || (uj && (argc == arg_base + 7))) + show_lsa_detail(vty, ospf, type, &id, NULL, json_vrf); /* `show ip ospf database LSA ID adv-router ADV_ROUTER'. */ - else if (argc == arg_base + 7) { + else if ((argc == arg_base + 7) + || (uj && (argc == arg_base + 8))) { if (strncmp(argv[arg_base + 6]->text, "s", 1) == 0) adv_router = ospf->router_id; else { @@ -6412,7 +6893,19 @@ static int show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf, if (!ret) return CMD_WARNING; } - show_lsa_detail(vty, ospf, type, &id, &adv_router); + show_lsa_detail(vty, ospf, type, &id, &adv_router, + json_vrf); + } + } + + if (json) { + if (use_vrf) { + if (ospf->vrf_id == VRF_DEFAULT) + json_object_object_add(json, "default", + json_vrf); + else + json_object_object_add(json, ospf->name, + json_vrf); } } @@ -6421,7 +6914,7 @@ static int show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf, DEFUN (show_ip_ospf_database_max, show_ip_ospf_database_max_cmd, - "show ip ospf [vrf <NAME|all>] database <max-age|self-originate>", + "show ip ospf [vrf <NAME|all>] database <max-age|self-originate> [json]", SHOW_STR IP_STR "OSPF information\n" @@ -6429,7 +6922,8 @@ DEFUN (show_ip_ospf_database_max, "All VRFs\n" "Database summary\n" "LSAs in MaxAge list\n" - "Self-originated link states\n") + "Self-originated link states\n" + JSON_STR) { struct ospf *ospf = NULL; struct listnode *node = NULL; @@ -6439,6 +6933,11 @@ DEFUN (show_ip_ospf_database_max, int inst = 0; int idx_vrf = 0; uint8_t use_vrf = 0; + bool uj = use_json(argc, argv); + json_object *json = NULL; + + if (uj) + json = json_object_new_object(); OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); @@ -6454,7 +6953,7 @@ DEFUN (show_ip_ospf_database_max, ospf_output = true; ret = show_ip_ospf_database_common( vty, ospf, idx_vrf ? 2 : 0, argc, argv, - use_vrf); + use_vrf, json, uj); } if (!ospf_output) @@ -6466,8 +6965,8 @@ DEFUN (show_ip_ospf_database_max, return CMD_SUCCESS; } ret = (show_ip_ospf_database_common( - vty, ospf, idx_vrf ? 2 : 0, argc, argv, - use_vrf)); + vty, ospf, idx_vrf ? 2 : 0, argc, argv, use_vrf, + json, uj)); } } else { /* Display default ospf (instance 0) info */ @@ -6478,7 +6977,12 @@ DEFUN (show_ip_ospf_database_max, } ret = show_ip_ospf_database_common(vty, ospf, 0, argc, argv, - use_vrf); + use_vrf, json, uj); + } + + if (uj) { + vty_out(vty, "%s\n", json_object_to_json_string(json)); + json_object_free(json); } return ret; @@ -6486,7 +6990,7 @@ DEFUN (show_ip_ospf_database_max, DEFUN (show_ip_ospf_instance_database, show_ip_ospf_instance_database_cmd, - "show ip ospf [{(1-65535)|vrf NAME}] database [<asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> [A.B.C.D [<self-originate|adv-router A.B.C.D>]]]", + "show ip ospf [{(1-65535)|vrf NAME}] database [<asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> [A.B.C.D [<self-originate|adv-router A.B.C.D>]]] [json]", SHOW_STR IP_STR "OSPF information\n" @@ -6497,7 +7001,8 @@ DEFUN (show_ip_ospf_instance_database, "Link State ID (as an IP address)\n" "Self-originated link states\n" "Advertising Router link states\n" - "Advertising Router (as an IP address)\n") + "Advertising Router (as an IP address)\n" + JSON_STR) { struct ospf *ospf; unsigned short instance = 0; @@ -6508,6 +7013,11 @@ DEFUN (show_ip_ospf_instance_database, int inst = 0; int idx = 0; uint8_t use_vrf = 0; + bool uj = use_json(argc, argv); + json_object *json = NULL; + + if (uj) + json = json_object_new_object(); if (argv_find(argv, argc, "(1-65535)", &idx)) { instance = strtoul(argv[idx]->arg, NULL, 10); @@ -6517,8 +7027,8 @@ DEFUN (show_ip_ospf_instance_database, if (!ospf->oi_running) return CMD_SUCCESS; - return (show_ip_ospf_database_common(vty, ospf, idx ? 1 : 0, - argc, argv, use_vrf)); + return (show_ip_ospf_database_common( + vty, ospf, idx ? 1 : 0, argc, argv, use_vrf, json, uj)); } else if (argv_find(argv, argc, "vrf", &idx)) { vrf_name = argv[++idx]->arg; all_vrf = strmatch(vrf_name, "all"); @@ -6532,7 +7042,7 @@ DEFUN (show_ip_ospf_instance_database, continue; ret = (show_ip_ospf_database_common( vty, ospf, idx ? 2 : 0, argc, argv, - use_vrf)); + use_vrf, json, uj)); } } else { ospf = ospf_lookup_by_inst_name(inst, vrf_name); @@ -6542,7 +7052,8 @@ DEFUN (show_ip_ospf_instance_database, } ret = (show_ip_ospf_database_common( - vty, ospf, idx ? 2 : 0, argc, argv, use_vrf)); + vty, ospf, idx ? 2 : 0, argc, argv, use_vrf, + json, uj)); } } else { /* Display default ospf (instance 0) info */ @@ -6553,7 +7064,12 @@ DEFUN (show_ip_ospf_instance_database, } ret = (show_ip_ospf_database_common(vty, ospf, 0, argc, argv, - use_vrf)); + use_vrf, json, uj)); + } + + if (uj) { + vty_out(vty, "%s\n", json_object_to_json_string(json)); + json_object_free(json); } return ret; @@ -6561,18 +7077,24 @@ DEFUN (show_ip_ospf_instance_database, DEFUN (show_ip_ospf_instance_database_max, show_ip_ospf_instance_database_max_cmd, - "show ip ospf (1-65535) database <max-age|self-originate>", + "show ip ospf (1-65535) database <max-age|self-originate> [json]", SHOW_STR IP_STR "OSPF information\n" "Instance ID\n" "Database summary\n" "LSAs in MaxAge list\n" - "Self-originated link states\n") + "Self-originated link states\n" + JSON_STR) { int idx_number = 3; struct ospf *ospf; unsigned short instance = 0; + bool uj = use_json(argc, argv); + json_object *json = NULL; + + if (uj) + json = json_object_new_object(); instance = strtoul(argv[idx_number]->arg, NULL, 10); @@ -6585,7 +7107,16 @@ DEFUN (show_ip_ospf_instance_database_max, return CMD_SUCCESS; } - return show_ip_ospf_database_common(vty, ospf, 1, argc, argv, 0); + show_ip_ospf_database_common(vty, ospf, 1, argc, argv, 0, json, uj); + + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } + + return CMD_SUCCESS; } @@ -6593,19 +7124,40 @@ static int show_ip_ospf_database_type_adv_router_common(struct vty *vty, struct ospf *ospf, int arg_base, int argc, struct cmd_token **argv, - uint8_t use_vrf) + uint8_t use_vrf, + json_object *json, + bool uj) { int idx_type = 4; int type, ret; struct in_addr adv_router; + json_object *json_vrf = NULL; - if (ospf->instance) - vty_out(vty, "\nOSPF Instance: %d\n", ospf->instance); + if (uj) { + if (use_vrf) + json_vrf = json_object_new_object(); + else + json_vrf = json; + } - ospf_show_vrf_name(ospf, vty, NULL, use_vrf); + if (ospf->instance) { + if (uj) + json_object_int_add(json, "ospfInstance", + ospf->instance); + else + vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance); + } + + ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf); - vty_out(vty, "\n OSPF Router with ID (%pI4)\n\n", - &ospf->router_id); + /* Show Router ID. */ + if (uj) { + json_object_string_add(json_vrf, "routerId", + inet_ntoa(ospf->router_id)); + } else { + vty_out(vty, "\n OSPF Router with ID (%pI4)\n\n", + &ospf->router_id); + } /* Set database type to show. */ if (strncmp(argv[arg_base + idx_type]->text, "r", 1) == 0) @@ -6638,14 +7190,25 @@ static int show_ip_ospf_database_type_adv_router_common(struct vty *vty, return CMD_WARNING; } - show_lsa_detail_adv_router(vty, ospf, type, &adv_router); + show_lsa_detail_adv_router(vty, ospf, type, &adv_router, json_vrf); + + if (json) { + if (use_vrf) { + if (ospf->vrf_id == VRF_DEFAULT) + json_object_object_add(json, "default", + json_vrf); + else + json_object_object_add(json, ospf->name, + json_vrf); + } + } return CMD_SUCCESS; } DEFUN (show_ip_ospf_instance_database_type_adv_router, show_ip_ospf_instance_database_type_adv_router_cmd, - "show ip ospf [{(1-65535)|vrf NAME}] database <asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> <adv-router A.B.C.D|self-originate>", + "show ip ospf [{(1-65535)|vrf NAME}] database <asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> <adv-router A.B.C.D|self-originate> [json]", SHOW_STR IP_STR "OSPF information\n" @@ -6655,7 +7218,8 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router, OSPF_LSA_TYPES_DESC "Advertising Router link states\n" "Advertising Router (as an IP address)\n" - "Self-originated link states\n") + "Self-originated link states\n" + JSON_STR) { struct ospf *ospf = NULL; unsigned short instance = 0; @@ -6666,6 +7230,11 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router, int inst = 0; int idx = 0, idx_vrf = 0; uint8_t use_vrf = 0; + bool uj = use_json(argc, argv); + json_object *json = NULL; + + if (uj) + json = json_object_new_object(); if (argv_find(argv, argc, "(1-65535)", &idx)) { instance = strtoul(argv[idx]->arg, NULL, 10); @@ -6678,7 +7247,7 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router, } return (show_ip_ospf_database_type_adv_router_common( - vty, ospf, idx ? 1 : 0, argc, argv, use_vrf)); + vty, ospf, idx ? 1 : 0, argc, argv, use_vrf, json, uj)); } OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); @@ -6695,7 +7264,7 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router, ospf_output = true; ret = show_ip_ospf_database_type_adv_router_common( vty, ospf, idx ? 1 : 0, argc, argv, - use_vrf); + use_vrf, json, uj); } if (!ospf_output) vty_out(vty, "%% OSPF instance not found\n"); @@ -6707,7 +7276,8 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router, } ret = show_ip_ospf_database_type_adv_router_common( - vty, ospf, idx ? 1 : 0, argc, argv, use_vrf); + vty, ospf, idx ? 1 : 0, argc, argv, use_vrf, + json, uj); } } else { /* Display default ospf (instance 0) info */ @@ -6718,8 +7288,14 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router, } ret = show_ip_ospf_database_type_adv_router_common( - vty, ospf, idx ? 1 : 0, argc, argv, use_vrf); + vty, ospf, idx ? 1 : 0, argc, argv, use_vrf, json, uj); } + + if (uj) { + vty_out(vty, "%s\n", json_object_to_json_string(json)); + json_object_free(json); + } + return ret; /*return (show_ip_ospf_database_type_adv_router_common( vty, ospf, idx ? 1 : 0, argc, argv));*/ |
