]> git.proxmox.com Git - mirror_frr.git/blobdiff - ospfd/ospf_vty.c
Merge pull request #12816 from gpnaveen/stc_rte_err_msg
[mirror_frr.git] / ospfd / ospf_vty.c
index af320ce4a3529605edd87dc2b505ac1321bd63bd..262f805468d1c74b9fc98964ea6502983950dd4e 100644 (file)
@@ -1,22 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /* OSPF VTY interface.
  * Copyright (C) 2005 6WIND <alain.ritoux@6wind.com>
  * Copyright (C) 2000 Toshiaki Takada
- *
- * This file is part of GNU Zebra.
- *
- * GNU Zebra is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * GNU Zebra is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <zebra.h>
@@ -3053,6 +3038,43 @@ static void show_ip_ospf_area(struct vty *vty, struct ospf_area *area,
                        ospf_lsdb_checksum(area->lsdb, OSPF_OPAQUE_AREA_LSA));
        }
 
+       if (area->fr_info.configured) {
+               if (use_json)
+                       json_object_string_add(json_area, "areaFloodReduction",
+                                              "configured");
+               else
+                       vty_out(vty, "   Flood Reduction is configured.\n");
+       }
+
+       if (area->fr_info.enabled) {
+               if (use_json) {
+                       json_object_boolean_true_add(
+                               json_area, "areaFloodReductionEnabled");
+                       if (area->fr_info.router_lsas_recv_dc_bit)
+                               json_object_boolean_true_add(
+                                       json_area, "lsasRecvDCbitSet");
+                       if (area->fr_info.area_ind_lsa_recvd)
+                               json_object_string_add(json_area,
+                                                      "areaIndicationLsaRecv",
+                                                      "received");
+                       if (area->fr_info.indication_lsa_self)
+                               json_object_string_addf(
+                                       json_area, "areaIndicationLsa", "%pI4",
+                                       &area->fr_info.indication_lsa_self->data
+                                                ->id);
+               } else {
+                       vty_out(vty, "   Flood Reduction is enabled.\n");
+                       vty_out(vty, "   No of LSAs rcv'd with DC bit set %d\n",
+                               area->fr_info.router_lsas_recv_dc_bit);
+                       if (area->fr_info.area_ind_lsa_recvd)
+                               vty_out(vty, "   Ind LSA by other abr.\n");
+                       if (area->fr_info.indication_lsa_self)
+                               vty_out(vty, "   Ind LSA generated %pI4\n",
+                                       &area->fr_info.indication_lsa_self->data
+                                                ->id);
+               }
+       }
+
        if (use_json)
                json_object_object_add(json_areas,
                                       inet_ntop(AF_INET, &area->area_id,
@@ -3288,6 +3310,14 @@ static int show_ip_ospf_common(struct vty *vty, struct ospf *ospf,
                                           : ZEBRA_OSPF_DISTANCE_DEFAULT);
        }
 
+       if (ospf->fr_configured) {
+               if (json)
+                       json_object_string_add(json_vrf, "floodReduction",
+                                              "configured");
+               else
+                       vty_out(vty, " Flood Reduction is configured.\n");
+       }
+
        /* Show ABR/ASBR flags. */
        if (CHECK_FLAG(ospf->flags, OSPF_FLAG_ABR)) {
                if (json)
@@ -4870,9 +4900,8 @@ DEFUN (show_ip_ospf_instance_neighbor_all,
 }
 
 static int show_ip_ospf_neighbor_int_common(struct vty *vty, struct ospf *ospf,
-                                           int arg_base,
-                                           struct cmd_token **argv,
-                                           bool use_json, uint8_t use_vrf)
+                                           const char *ifname, bool use_json,
+                                           uint8_t use_vrf)
 {
        struct interface *ifp;
        struct route_node *rn;
@@ -4891,7 +4920,7 @@ static int show_ip_ospf_neighbor_int_common(struct vty *vty, struct ospf *ospf,
 
        ospf_show_vrf_name(ospf, vty, json, use_vrf);
 
-       ifp = if_lookup_by_name(argv[arg_base]->arg, ospf->vrf_id);
+       ifp = if_lookup_by_name(ifname, ospf->vrf_id);
        if (!ifp) {
                if (use_json)
                        json_object_boolean_true_add(json, "noSuchIface");
@@ -4917,76 +4946,22 @@ static int show_ip_ospf_neighbor_int_common(struct vty *vty, struct ospf *ospf,
        return CMD_SUCCESS;
 }
 
-DEFUN (show_ip_ospf_neighbor_int,
-       show_ip_ospf_neighbor_int_cmd,
-       "show ip ospf [vrf <NAME>] neighbor IFNAME [json]",
-       SHOW_STR
-       IP_STR
-       "OSPF information\n"
-       VRF_CMD_HELP_STR
-       "Neighbor list\n"
-       "Interface name\n"
-       JSON_STR)
-{
-       struct ospf *ospf;
-       int idx_ifname = 0;
-       int idx_vrf = 0;
-       bool uj = use_json(argc, argv);
-       int ret = CMD_SUCCESS;
-       struct interface *ifp = NULL;
-       char *vrf_name = NULL;
-       vrf_id_t vrf_id = VRF_DEFAULT;
-       struct vrf *vrf = NULL;
-
-       if (argv_find(argv, argc, "vrf", &idx_vrf))
-               vrf_name = argv[idx_vrf + 1]->arg;
-       if (vrf_name && strmatch(vrf_name, VRF_DEFAULT_NAME))
-               vrf_name = NULL;
-       if (vrf_name) {
-               vrf = vrf_lookup_by_name(vrf_name);
-               if (vrf)
-                       vrf_id = vrf->vrf_id;
-       }
-       ospf = ospf_lookup_by_vrf_id(vrf_id);
-
-       if (!ospf || !ospf->oi_running)
-               return ret;
-
-       if (!uj)
-               show_ip_ospf_neighbour_header(vty);
-
-       argv_find(argv, argc, "IFNAME", &idx_ifname);
-
-       ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
-       if (!ifp)
-               return ret;
-
-       ret = show_ip_ospf_neighbor_int_common(vty, ospf, idx_ifname,
-                                              argv, uj, 0);
-       return ret;
-}
-
-DEFUN (show_ip_ospf_instance_neighbor_int,
-       show_ip_ospf_instance_neighbor_int_cmd,
-       "show ip ospf (1-65535) neighbor IFNAME [json]",
-       SHOW_STR
-       IP_STR
-       "OSPF information\n"
-       "Instance ID\n"
-       "Neighbor list\n"
-       "Interface name\n"
-       JSON_STR)
+DEFPY(show_ip_ospf_instance_neighbor_int,
+      show_ip_ospf_instance_neighbor_int_cmd,
+      "show ip ospf (1-65535)$instance neighbor IFNAME$ifname [json$json]",
+      SHOW_STR
+      IP_STR
+      "OSPF information\n"
+      "Instance ID\n"
+      "Neighbor list\n"
+      "Interface name\n"
+      JSON_STR)
 {
-       int idx_number = 3;
-       int idx_ifname = 5;
        struct ospf *ospf;
-       unsigned short instance = 0;
-       bool uj = use_json(argc, argv);
 
-       if (!uj)
+       if (!json)
                show_ip_ospf_neighbour_header(vty);
 
-       instance = strtoul(argv[idx_number]->arg, NULL, 10);
        if (instance != ospf_instance)
                return CMD_NOT_MY_INSTANCE;
 
@@ -4994,11 +4969,10 @@ DEFUN (show_ip_ospf_instance_neighbor_int,
        if (!ospf || !ospf->oi_running)
                return CMD_SUCCESS;
 
-       if (!uj)
+       if (!json)
                show_ip_ospf_neighbour_header(vty);
 
-       return show_ip_ospf_neighbor_int_common(vty, ospf, idx_ifname, argv, uj,
-                                               0);
+       return show_ip_ospf_neighbor_int_common(vty, ospf, ifname, !!json, 0);
 }
 
 static void show_ip_ospf_nbr_nbma_detail_sub(struct vty *vty,
@@ -5478,7 +5452,6 @@ DEFPY(show_ip_ospf_neighbor_id,
                                        vrf_name);
                        else
                                vty_json_empty(vty);
-
                        return CMD_SUCCESS;
                }
                ret = show_ip_ospf_neighbor_id_common(
@@ -5586,77 +5559,71 @@ static int show_ip_ospf_neighbor_detail_common(struct vty *vty,
        return CMD_SUCCESS;
 }
 
-DEFUN (show_ip_ospf_neighbor_detail,
-       show_ip_ospf_neighbor_detail_cmd,
-       "show ip ospf [vrf <NAME|all>] neighbor detail [json]",
-       SHOW_STR
-       IP_STR
-       "OSPF information\n"
-       VRF_CMD_HELP_STR
-       "All VRFs\n"
-       "Neighbor list\n"
-       "detail of all neighbors\n"
-       JSON_STR)
+DEFPY(show_ip_ospf_neighbor_detail,
+      show_ip_ospf_neighbor_detail_cmd,
+      "show ip ospf [vrf <NAME|all>$vrf_name] neighbor detail [json$json]",
+      SHOW_STR
+      IP_STR
+      "OSPF information\n"
+      VRF_CMD_HELP_STR
+      "All VRFs\n"
+      "Neighbor list\n"
+      "detail of all neighbors\n"
+      JSON_STR)
 {
        struct ospf *ospf;
-       bool uj = use_json(argc, argv);
        struct listnode *node = NULL;
-       char *vrf_name = NULL;
-       bool all_vrf = false;
        int ret = CMD_SUCCESS;
        int inst = 0;
-       int idx_vrf = 0;
        uint8_t use_vrf = 0;
-       json_object *json = NULL;
-
-       OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+       json_object *json_vrf = NULL;
 
-       if (uj)
-               json = json_object_new_object();
+       if (json)
+               json_vrf = json_object_new_object();
 
        /* vrf input is provided could be all or specific vrf*/
        if (vrf_name) {
                use_vrf = 1;
-               if (all_vrf) {
+               if (strmatch(vrf_name, "all")) {
                        for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
                                if (!ospf->oi_running)
                                        continue;
                                ret = show_ip_ospf_neighbor_detail_common(
-                                       vty, ospf, json, uj, use_vrf);
+                                       vty, ospf, json_vrf, !!json, use_vrf);
                        }
-                       if (uj)
-                               vty_json(vty, json);
+                       if (json)
+                               vty_json(vty, json_vrf);
 
                        return ret;
                }
                ospf = ospf_lookup_by_inst_name(inst, vrf_name);
                if (ospf == NULL || !ospf->oi_running) {
-                       if (uj)
-                               json_object_free(json);
+                       if (json)
+                               vty_json(vty, json_vrf);
+                       else
+                               vty_out(vty,
+                                       "%% OSPF is not enabled in vrf %s\n",
+                                       vrf_name);
                        return CMD_SUCCESS;
                }
        } else {
                /* Display default ospf (instance 0) info */
                ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
                if (ospf == NULL || !ospf->oi_running) {
-                       if (uj)
-                               json_object_free(json);
+                       if (json)
+                               vty_json(vty, json_vrf);
+                       else
+                               vty_out(vty, "%% OSPF is not enabled\n");
                        return CMD_SUCCESS;
                }
        }
 
-       if (ospf) {
-               ret = show_ip_ospf_neighbor_detail_common(vty, ospf, json, uj,
-                                                         use_vrf);
-               if (uj) {
-                       vty_out(vty, "%s\n",
-                               json_object_to_json_string_ext(
-                                       json, JSON_C_TO_STRING_PRETTY));
-               }
-       }
+       if (ospf)
+               ret = show_ip_ospf_neighbor_detail_common(vty, ospf, json_vrf,
+                                                         !!json, use_vrf);
 
-       if (uj)
-               json_object_free(json);
+       if (json)
+               vty_json(vty, json_vrf);
 
        return ret;
 }
@@ -5885,9 +5852,9 @@ DEFUN (show_ip_ospf_instance_neighbor_detail_all,
 
 static int show_ip_ospf_neighbor_int_detail_common(struct vty *vty,
                                                   struct ospf *ospf,
-                                                  int arg_base,
-                                                  struct cmd_token **argv,
-                                                  bool use_json)
+                                                  const char *ifname,
+                                                  bool use_json,
+                                                  json_object *json_vrf)
 {
        struct ospf_interface *oi;
        struct interface *ifp;
@@ -5895,8 +5862,15 @@ static int show_ip_ospf_neighbor_int_detail_common(struct vty *vty,
        struct ospf_neighbor *nbr;
        json_object *json = NULL;
 
-       if (use_json)
+       if (use_json) {
                json = json_object_new_object();
+               if (json_vrf)
+                       json_object_object_add(json_vrf,
+                                              (ospf->vrf_id == VRF_DEFAULT)
+                                                      ? "default"
+                                                      : ospf->name,
+                                              json);
+       }
 
        if (ospf->instance) {
                if (use_json)
@@ -5906,13 +5880,13 @@ static int show_ip_ospf_neighbor_int_detail_common(struct vty *vty,
                        vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
        }
 
-       ifp = if_lookup_by_name(argv[arg_base]->arg, ospf->vrf_id);
+       ifp = if_lookup_by_name(ifname, ospf->vrf_id);
        if (!ifp) {
-               if (!use_json)
+               if (!use_json) {
                        vty_out(vty, "No such interface.\n");
-               else {
-                       vty_out(vty, "{}\n");
-                       json_object_free(json);
+               else {
+                       if (!json_vrf)
+                               vty_json(vty, json);
                }
                return CMD_WARNING;
        }
@@ -5940,37 +5914,114 @@ static int show_ip_ospf_neighbor_int_detail_common(struct vty *vty,
                }
        }
 
-       if (use_json)
-               vty_json(vty, json);
-       else
+       if (use_json) {
+               if (!json_vrf)
+                       vty_json(vty, json);
+       } else {
                vty_out(vty, "\n");
+       }
 
        return CMD_SUCCESS;
 }
 
-DEFUN (show_ip_ospf_neighbor_int_detail,
-       show_ip_ospf_neighbor_int_detail_cmd,
-       "show ip ospf neighbor IFNAME detail [json]",
-       SHOW_STR
-       IP_STR
-       "OSPF information\n"
-       "Neighbor list\n"
-       "Interface name\n"
-       "detail of all neighbors\n"
-       JSON_STR)
+DEFPY(show_ip_ospf_neighbor_int,
+      show_ip_ospf_neighbor_int_cmd,
+      "show ip ospf [vrf NAME$vrf_name] neighbor IFNAME$ifname [json$json]",
+      SHOW_STR
+      IP_STR
+      "OSPF information\n"
+      VRF_CMD_HELP_STR
+      "Neighbor list\n"
+      "Interface name\n"
+      JSON_STR)
+{
+       struct ospf *ospf;
+       int ret = CMD_SUCCESS;
+       struct interface *ifp = NULL;
+       vrf_id_t vrf_id = VRF_DEFAULT;
+       struct vrf *vrf = NULL;
+
+       if (vrf_name && strmatch(vrf_name, VRF_DEFAULT_NAME))
+               vrf_name = NULL;
+       if (vrf_name) {
+               vrf = vrf_lookup_by_name(vrf_name);
+               if (vrf)
+                       vrf_id = vrf->vrf_id;
+       }
+       ospf = ospf_lookup_by_vrf_id(vrf_id);
+
+       if (!ospf || !ospf->oi_running) {
+               if (json)
+                       vty_json_empty(vty);
+               return ret;
+       }
+
+       if (!json)
+               show_ip_ospf_neighbour_header(vty);
+
+       ifp = if_lookup_by_name(ifname, vrf_id);
+       if (!ifp) {
+               if (json)
+                       vty_json_empty(vty);
+               else
+                       vty_out(vty, "No such interface.\n");
+               return ret;
+       }
+
+       ret = show_ip_ospf_neighbor_int_common(vty, ospf, ifname, !!json, 0);
+       return ret;
+}
+
+DEFPY(show_ip_ospf_neighbor_int_detail,
+      show_ip_ospf_neighbor_int_detail_cmd,
+      "show ip ospf [vrf NAME$vrf_name] neighbor IFNAME$ifname detail [json$json]",
+      SHOW_STR
+      IP_STR
+      "OSPF information\n"
+      VRF_CMD_HELP_STR
+      "Neighbor list\n"
+      "Interface name\n"
+      "detail of all neighbors\n"
+      JSON_STR)
 {
        struct ospf *ospf;
-       bool uj = use_json(argc, argv);
        struct listnode *node = NULL;
        int ret = CMD_SUCCESS;
        bool ospf_output = false;
 
+       if (vrf_name && !strmatch(vrf_name, "all")) {
+               int inst = 0;
+
+               ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+               if (ospf == NULL || !ospf->oi_running) {
+                       if (!json)
+                               vty_out(vty,
+                                       "%% OSPF is not enabled in vrf %s\n",
+                                       vrf_name);
+                       else
+                               vty_json_empty(vty);
+                       return CMD_SUCCESS;
+               }
+               return show_ip_ospf_neighbor_int_detail_common(
+                       vty, ospf, ifname, !!json, NULL);
+       }
+
+       json_object *json_vrf = NULL;
+
+       if (json)
+               json_vrf = json_object_new_object();
+
        for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
                if (!ospf->oi_running)
                        continue;
                ospf_output = true;
-               ret = show_ip_ospf_neighbor_int_detail_common(vty, ospf, 4,
-                                                             argv, uj);
+               ret = show_ip_ospf_neighbor_int_detail_common(vty, ospf, ifname,
+                                                             !!json, json_vrf);
+       }
+
+       if (json) {
+               vty_json(vty, json_vrf);
+               return ret;
        }
 
        if (!ospf_output)
@@ -5979,25 +6030,20 @@ DEFUN (show_ip_ospf_neighbor_int_detail,
        return ret;
 }
 
-DEFUN (show_ip_ospf_instance_neighbor_int_detail,
-       show_ip_ospf_instance_neighbor_int_detail_cmd,
-       "show ip ospf (1-65535) neighbor IFNAME detail [json]",
-       SHOW_STR
-       IP_STR
-       "OSPF information\n"
-       "Instance ID\n"
-       "Neighbor list\n"
-       "Interface name\n"
-       "detail of all neighbors\n"
-       JSON_STR)
+DEFPY(show_ip_ospf_instance_neighbor_int_detail,
+      show_ip_ospf_instance_neighbor_int_detail_cmd,
+      "show ip ospf (1-65535)$instance neighbor IFNAME$ifname detail [json$json]",
+      SHOW_STR
+      IP_STR
+      "OSPF information\n"
+      "Instance ID\n"
+      "Neighbor list\n"
+      "Interface name\n"
+      "detail of all neighbors\n"
+      JSON_STR)
 {
-       int idx_number = 3;
-       int idx_ifname = 5;
        struct ospf *ospf;
-       unsigned short instance = 0;
-       bool uj = use_json(argc, argv);
 
-       instance = strtoul(argv[idx_number]->arg, NULL, 10);
        if (instance != ospf_instance)
                return CMD_NOT_MY_INSTANCE;
 
@@ -6005,8 +6051,8 @@ DEFUN (show_ip_ospf_instance_neighbor_int_detail,
        if (!ospf || !ospf->oi_running)
                return CMD_SUCCESS;
 
-       return show_ip_ospf_neighbor_int_detail_common(vty, ospf, idx_ifname,
-                                                      argv, uj);
+       return show_ip_ospf_neighbor_int_detail_common(vty, ospf, ifname,
+                                                      !!json, NULL);
 }
 
 /* Show functions */
@@ -6018,118 +6064,109 @@ static int show_lsa_summary(struct vty *vty, struct ospf_lsa *lsa, int self,
        struct as_external_lsa *asel;
        struct prefix_ipv4 p;
 
-       if (lsa != NULL) {
-               /* If self option is set, check LSA self flag. */
-               if (self == 0 || IS_LSA_SELF(lsa)) {
-
-                       if (!json_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));
-                       } 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_addf(json_lsa, "lsId",
-                                                       "%pI4", &lsa->data->id);
-                               json_object_string_addf(
-                                       json_lsa, "advertisedRouter", "%pI4",
-                                       &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;
+       if (lsa == NULL)
+               return 0;
 
-                               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;
+       /* If self option is set, check LSA self flag. */
+       if (self == 0 || IS_LSA_SELF(lsa)) {
 
-                               p.family = AF_INET;
-                               p.prefix = sl->header.id;
-                               p.prefixlen = ip_masklen(sl->mask);
-                               apply_mask_ipv4(&p);
+               if (!json_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));
+               } 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_addf(json_lsa, "lsId", "%pI4",
+                                               &lsa->data->id);
+                       json_object_string_addf(json_lsa, "advertisedRouter",
+                                               "%pI4", &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;
 
-                               if (!json_lsa)
-                                       vty_out(vty, " %pFX", &p);
-                               else {
-                                       json_object_string_addf(
-                                               json_lsa, "summaryAddress",
-                                               "%pFX", &p);
-                               }
-                               break;
-                       case OSPF_AS_EXTERNAL_LSA:
-                       case OSPF_AS_NSSA_LSA:
-                               asel = (struct as_external_lsa *)lsa->data;
-
-                               p.family = AF_INET;
-                               p.prefix = asel->header.id;
-                               p.prefixlen = ip_masklen(asel->mask);
-                               apply_mask_ipv4(&p);
-
-                               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 {
-                                       json_object_string_add(
-                                               json_lsa, "metricType",
-                                               IS_EXTERNAL_METRIC(
-                                                       asel->e[0].tos)
-                                                       ? "E2"
-                                                       : "E1");
-                                       json_object_string_addf(
-                                               json_lsa, "route", "%pFX", &p);
-                                       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:
-                       case OSPF_OPAQUE_LINK_LSA:
-                       case OSPF_OPAQUE_AREA_LSA:
-                       case OSPF_OPAQUE_AS_LSA:
-                       default:
-                               break;
+                       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;
+
+                       p.family = AF_INET;
+                       p.prefix = sl->header.id;
+                       p.prefixlen = ip_masklen(sl->mask);
+                       apply_mask_ipv4(&p);
+
+                       if (!json_lsa)
+                               vty_out(vty, " %pFX", &p);
+                       else {
+                               json_object_string_addf(
+                                       json_lsa, "summaryAddress", "%pFX", &p);
                        }
+                       break;
+               case OSPF_AS_EXTERNAL_LSA:
+               case OSPF_AS_NSSA_LSA:
+                       asel = (struct as_external_lsa *)lsa->data;
+
+                       p.family = AF_INET;
+                       p.prefix = asel->header.id;
+                       p.prefixlen = ip_masklen(asel->mask);
+                       apply_mask_ipv4(&p);
 
                        if (!json_lsa)
-                               vty_out(vty, "\n");
+                               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 {
+                               json_object_string_add(
+                                       json_lsa, "metricType",
+                                       IS_EXTERNAL_METRIC(asel->e[0].tos)
+                                               ? "E2"
+                                               : "E1");
+                               json_object_string_addf(json_lsa, "route",
+                                                       "%pFX", &p);
+                               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:
+               case OSPF_OPAQUE_LINK_LSA:
+               case OSPF_OPAQUE_AREA_LSA:
+               case OSPF_OPAQUE_AS_LSA:
+               default:
+                       break;
                }
 
-               return 1;
+               if (!json_lsa)
+                       vty_out(vty, "\n");
        }
 
-       return 0;
+       return 1;
 }
 
 static const char *const show_database_desc[] = {
@@ -6198,7 +6235,16 @@ static void show_ip_ospf_database_header(struct vty *vty, struct ospf_lsa *lsa,
        struct router_lsa *rlsa = (struct router_lsa *)lsa->data;
 
        if (!json) {
-               vty_out(vty, "  LS age: %d\n", LS_AGE(lsa));
+               if (IS_LSA_SELF(lsa))
+                       vty_out(vty, "  LS age: %d%s\n", LS_AGE(lsa),
+                               CHECK_FLAG(lsa->data->ls_age, DO_NOT_AGE)
+                                       ? "(S-DNA)"
+                                       : "");
+               else
+                       vty_out(vty, "  LS age: %d%s\n", LS_AGE(lsa),
+                               CHECK_FLAG(lsa->data->ls_age, DO_NOT_AGE)
+                                       ? "(DNA)"
+                                       : "");
                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,
@@ -6754,31 +6800,24 @@ static void show_lsa_detail_adv_router_proc(struct vty *vty,
                                            struct in_addr *adv_router,
                                            json_object *json)
 {
-       char buf[PREFIX_STRLEN];
        struct route_node *rn;
        struct ospf_lsa *lsa;
+       json_object *json_lsa = NULL;
 
        for (rn = route_top(rt); rn; rn = route_next(rn))
                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)
+                               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, json_lsa);
-                               if (json)
-                                       json_object_object_add(
-                                               json,
-                                               inet_ntop(AF_INET,
-                                                         &lsa->data->id,
-                                                         buf, sizeof(buf)),
-                                               json_lsa);
                        }
                }
 }
@@ -6791,11 +6830,12 @@ static void show_lsa_detail_adv_router(struct vty *vty, struct ospf *ospf,
        struct listnode *node;
        struct ospf_area *area;
        char buf[PREFIX_STRLEN];
-       json_object *json_lstype = NULL;
-       json_object *json_area = NULL;
+       json_object *json_lsa_type = NULL;
+       json_object *json_areas = NULL;
+       json_object *json_lsa_array = NULL;
 
        if (json)
-               json_lstype = json_object_new_object();
+               json_lsa_type = json_object_new_object();
 
        switch (type) {
        case OSPF_AS_EXTERNAL_LSA:
@@ -6803,38 +6843,49 @@ static void show_lsa_detail_adv_router(struct vty *vty, struct ospf *ospf,
                if (!json)
                        vty_out(vty, "                %s \n\n",
                                show_database_desc[type]);
+               else
+                       json_lsa_array = json_object_new_array();
 
                show_lsa_detail_adv_router_proc(vty, AS_LSDB(ospf, type),
-                                               adv_router, json_lstype);
+                                               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)) {
-                       if (json)
-                               json_area = json_object_new_object();
-                       else
+                       if (!json) {
                                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);
+                       } else {
+                               json_lsa_array = json_object_new_array();
+                               json_object_object_add(
+                                       json_areas,
+                                       inet_ntop(AF_INET, &area->area_id, buf,
+                                                 sizeof(buf)),
+                                       json_lsa_array);
+                       }
 
-                       if (json)
-                               json_object_object_add(json_lstype,
-                                                      inet_ntop(AF_INET,
-                                                                &area->area_id,
-                                                                buf,
-                                                                sizeof(buf)),
-                                                      json_area);
+                       show_lsa_detail_adv_router_proc(
+                               vty, AREA_LSDB(area, type), 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;
        }
-
-       if (json)
-               json_object_object_add(json, show_database_desc[type],
-                                      json_lstype);
 }
 
 void show_ip_ospf_database_summary(struct vty *vty, struct ospf *ospf, int self,
@@ -7007,320 +7058,44 @@ static void show_ip_ospf_database_maxage(struct vty *vty, struct ospf *ospf,
                                        json_lsa, "advertisingRouter", "%pI4",
                                        &lsa->data->adv_router);
                                json_object_int_add(json_lsa, "lsaLockCount",
-                                                   lsa->lock);
-                               json_object_object_add(
-                                       json_maxage,
-                                       inet_ntop(AF_INET,
-                                                 &lsa->data->id,
-                                                 buf, sizeof(buf)),
-                                       json_lsa);
-                       }
-               }
-       }
-       if (json)
-               json_object_object_add(json, "maxAgeLinkStates", json_maxage);
-}
-
-#define OSPF_LSA_TYPE_NSSA_DESC      "NSSA external link state\n"
-#define OSPF_LSA_TYPE_NSSA_CMD_STR   "|nssa-external"
-
-#define OSPF_LSA_TYPE_OPAQUE_LINK_DESC "Link local Opaque-LSA\n"
-#define OSPF_LSA_TYPE_OPAQUE_AREA_DESC "Link area Opaque-LSA\n"
-#define OSPF_LSA_TYPE_OPAQUE_AS_DESC   "Link AS Opaque-LSA\n"
-#define OSPF_LSA_TYPE_OPAQUE_CMD_STR   "|opaque-link|opaque-area|opaque-as"
-
-#define OSPF_LSA_TYPES_DESC                                                    \
-       "ASBR summary link states\n"                                           \
-       "External link states\n"                                               \
-       "Network link states\n"                                                \
-       "Router link states\n"                                                 \
-       "Network summary link states\n" OSPF_LSA_TYPE_NSSA_DESC                \
-               OSPF_LSA_TYPE_OPAQUE_LINK_DESC OSPF_LSA_TYPE_OPAQUE_AREA_DESC  \
-                       OSPF_LSA_TYPE_OPAQUE_AS_DESC
-
-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, json_object *json,
-                                       bool uj)
-{
-       int idx_type = 4;
-       int type, ret;
-       struct in_addr id, adv_router;
-       json_object *json_vrf = NULL;
-
-       if (uj) {
-               if (use_vrf)
-                       json_vrf = json_object_new_object();
-               else
-                       json_vrf = json;
-       }
-
-       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);
-       }
-
-       ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
-
-       /* Show Router ID. */
-       if (uj) {
-               json_object_string_addf(json_vrf, "routerId", "%pI4",
-                                       &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) || (uj && (argc == arg_base + 5))) {
-               show_ip_ospf_database_summary(vty, ospf, 0, json_vrf);
-               if (json) {
-                       if (use_vrf)
-                               json_object_object_add(
-                                       json, ospf_get_name(ospf), json_vrf);
-               }
-               return CMD_SUCCESS;
-       }
-
-       /* Set database type to show. */
-       if (strncmp(argv[arg_base + idx_type]->text, "r", 1) == 0)
-               type = OSPF_ROUTER_LSA;
-       else if (strncmp(argv[arg_base + idx_type]->text, "ne", 2) == 0)
-               type = OSPF_NETWORK_LSA;
-       else if (strncmp(argv[arg_base + idx_type]->text, "ns", 2) == 0)
-               type = OSPF_AS_NSSA_LSA;
-       else if (strncmp(argv[arg_base + idx_type]->text, "su", 2) == 0)
-               type = OSPF_SUMMARY_LSA;
-       else if (strncmp(argv[arg_base + idx_type]->text, "a", 1) == 0)
-               type = OSPF_ASBR_SUMMARY_LSA;
-       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, json_vrf);
-               if (json) {
-                       if (use_vrf)
-                               json_object_object_add(
-                                       json, ospf_get_name(ospf), json_vrf);
-               }
-               return CMD_SUCCESS;
-       } else if (strncmp(argv[arg_base + idx_type]->text, "m", 1) == 0) {
-               show_ip_ospf_database_maxage(vty, ospf, json_vrf);
-               if (json) {
-                       if (use_vrf)
-                               json_object_object_add(
-                                       json, ospf_get_name(ospf), json_vrf);
-               }
-               return CMD_SUCCESS;
-       } else if (strncmp(argv[arg_base + idx_type]->text, "opaque-l", 8) == 0)
-               type = OSPF_OPAQUE_LINK_LSA;
-       else if (strncmp(argv[arg_base + idx_type]->text, "opaque-ar", 9) == 0)
-               type = OSPF_OPAQUE_AREA_LSA;
-       else if (strncmp(argv[arg_base + idx_type]->text, "opaque-as", 9) == 0)
-               type = OSPF_OPAQUE_AS_LSA;
-       else
-               return CMD_WARNING;
-
-       /* `show ip ospf database LSA'. */
-       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) || (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)
-                        || (uj && (argc == arg_base + 8))) {
-                       if (strncmp(argv[arg_base + 6]->text, "s", 1) == 0)
-                               adv_router = ospf->router_id;
-                       else {
-                               ret = inet_aton(argv[arg_base + 7]->arg,
-                                               &adv_router);
-                               if (!ret)
-                                       return CMD_WARNING;
-                       }
-                       show_lsa_detail(vty, ospf, type, &id, &adv_router,
-                                       json_vrf);
-               }
-       }
-
-       if (json) {
-               if (use_vrf)
-                       json_object_object_add(json, ospf_get_name(ospf),
-                                              json_vrf);
-       }
-
-       return CMD_SUCCESS;
-}
-
-DEFUN (show_ip_ospf_database_max,
-       show_ip_ospf_database_max_cmd,
-       "show ip ospf [vrf <NAME|all>] database <max-age|self-originate> [json]",
-       SHOW_STR
-       IP_STR
-       "OSPF information\n"
-       VRF_CMD_HELP_STR
-       "All VRFs\n"
-       "Database summary\n"
-       "LSAs in MaxAge list\n"
-       "Self-originated link states\n"
-       JSON_STR)
-{
-       struct ospf *ospf = NULL;
-       struct listnode *node = NULL;
-       char *vrf_name = NULL;
-       bool all_vrf = false;
-       int ret = CMD_SUCCESS;
-       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);
-
-       if (vrf_name) {
-               bool ospf_output = false;
-
-               use_vrf = 1;
-
-               if (all_vrf) {
-                       for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
-                               if (!ospf->oi_running)
-                                       continue;
-                               ospf_output = true;
-                               ret = show_ip_ospf_database_common(
-                                       vty, ospf, idx_vrf ? 2 : 0, argc, argv,
-                                       use_vrf, json, uj);
-                       }
-
-                       if (!ospf_output)
-                               vty_out(vty, "%% OSPF is not enabled\n");
-               } else {
-                       ospf = ospf_lookup_by_inst_name(inst, vrf_name);
-                       if (ospf == NULL || !ospf->oi_running) {
-                               vty_out(vty,
-                                       "%% OSPF is not enabled in vrf %s\n",
-                                       vrf_name);
-                               if (uj)
-                                       json_object_free(json);
-
-                               return CMD_SUCCESS;
-                       }
-                       ret = (show_ip_ospf_database_common(
-                               vty, ospf, idx_vrf ? 2 : 0, argc, argv, use_vrf,
-                               json, uj));
-               }
-       } else {
-               /* Display default ospf (instance 0) info */
-               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
-               if (ospf == NULL || !ospf->oi_running) {
-                       vty_out(vty, "%% OSPF is not enabled in vrf default\n");
-                       if (uj)
-                               json_object_free(json);
-
-                       return CMD_SUCCESS;
-               }
-
-               ret = show_ip_ospf_database_common(vty, ospf, 0, argc, argv,
-                                                  use_vrf, json, uj);
-       }
-
-       if (uj)
-               vty_json(vty, json);
-
-       return ret;
-}
-
-ALIAS (show_ip_ospf_database_max,
-       show_ip_ospf_database_cmd,
-       "show ip ospf [vrf <NAME|all>] 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"
-       VRF_CMD_HELP_STR
-       "All VRFs\n"
-       "Database summary\n"
-        OSPF_LSA_TYPES_DESC
-       "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"
-       JSON_STR)
-
-DEFUN (show_ip_ospf_instance_database_max,
-       show_ip_ospf_instance_database_max_cmd,
-       "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"
-       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);
-       if (instance != ospf_instance)
-               return CMD_NOT_MY_INSTANCE;
-
-       ospf = ospf_lookup_instance(instance);
-       if (!ospf || !ospf->oi_running)
-               return CMD_SUCCESS;
-
-       show_ip_ospf_database_common(vty, ospf, 1, argc, argv, 0, json, uj);
+                                                   lsa->lock);
+                               json_object_object_add(
+                                       json_maxage,
+                                       inet_ntop(AF_INET,
+                                                 &lsa->data->id,
+                                                 buf, sizeof(buf)),
+                                       json_lsa);
+                       }
+               }
+       }
+       if (json)
+               json_object_object_add(json, "maxAgeLinkStates", json_maxage);
+}
 
-       if (uj)
-               vty_json(vty, json);
+#define OSPF_LSA_TYPE_NSSA_DESC      "NSSA external link state\n"
+#define OSPF_LSA_TYPE_NSSA_CMD_STR   "|nssa-external"
 
-       return CMD_SUCCESS;
-}
+#define OSPF_LSA_TYPE_OPAQUE_LINK_DESC "Link local Opaque-LSA\n"
+#define OSPF_LSA_TYPE_OPAQUE_AREA_DESC "Link area Opaque-LSA\n"
+#define OSPF_LSA_TYPE_OPAQUE_AS_DESC   "Link AS Opaque-LSA\n"
+#define OSPF_LSA_TYPE_OPAQUE_CMD_STR   "|opaque-link|opaque-area|opaque-as"
 
-ALIAS (show_ip_ospf_instance_database_max,
-       show_ip_ospf_instance_database_cmd,
-       "show ip ospf (1-65535) 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"
-       "Instance ID\n"
-       "Database summary\n"
-        OSPF_LSA_TYPES_DESC
-       "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"
-       JSON_STR)
+#define OSPF_LSA_TYPES_DESC                                                    \
+       "ASBR summary link states\n"                                           \
+       "External link states\n"                                               \
+       "Network link states\n"                                                \
+       "Router link states\n"                                                 \
+       "Network summary link states\n" OSPF_LSA_TYPE_NSSA_DESC                \
+               OSPF_LSA_TYPE_OPAQUE_LINK_DESC OSPF_LSA_TYPE_OPAQUE_AREA_DESC  \
+                       OSPF_LSA_TYPE_OPAQUE_AS_DESC
 
-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,
-                                                       json_object *json,
-                                                       bool uj)
-{
-       int idx_type = 4;
-       int type, ret;
-       struct in_addr adv_router;
+static int
+show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf, bool maxage,
+                            bool self, bool detail, const char *type_name,
+                            struct in_addr *lsid, struct in_addr *adv_router,
+                            bool use_vrf, json_object *json, bool uj)
+{
+       int type;
        json_object *json_vrf = NULL;
 
        if (uj) {
@@ -7332,7 +7107,7 @@ static int show_ip_ospf_database_type_adv_router_common(struct vty *vty,
 
        if (ospf->instance) {
                if (uj)
-                       json_object_int_add(json, "ospfInstance",
+                       json_object_int_add(json_vrf, "ospfInstance",
                                            ospf->instance);
                else
                        vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
@@ -7349,24 +7124,79 @@ static int show_ip_ospf_database_type_adv_router_common(struct vty *vty,
                        &ospf->router_id);
        }
 
+       /* Show MaxAge LSAs */
+       if (maxage) {
+               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;
+       }
+
+       /* Show all LSAs. */
+       if (!type_name) {
+               if (detail) {
+                       for (int i = OSPF_ROUTER_LSA; i <= OSPF_OPAQUE_AS_LSA;
+                            i++) {
+                               switch (i) {
+                               case OSPF_GROUP_MEMBER_LSA:
+                               case OSPF_EXTERNAL_ATTRIBUTES_LSA:
+                                       /* ignore deprecated LSA types */
+                                       continue;
+                               default:
+                                       break;
+                               }
+
+                               if (adv_router && !lsid)
+                                       show_lsa_detail_adv_router(vty, ospf, i,
+                                                                  adv_router,
+                                                                  json_vrf);
+                               else
+                                       show_lsa_detail(vty, ospf, i, lsid,
+                                                       adv_router, json_vrf);
+                       }
+               } else
+                       show_ip_ospf_database_summary(vty, ospf, self,
+                                                     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;
+       }
+
        /* Set database type to show. */
-       if (strncmp(argv[arg_base + idx_type]->text, "r", 1) == 0)
+       if (strncmp(type_name, "r", 1) == 0)
                type = OSPF_ROUTER_LSA;
-       else if (strncmp(argv[arg_base + idx_type]->text, "ne", 2) == 0)
+       else if (strncmp(type_name, "ne", 2) == 0)
                type = OSPF_NETWORK_LSA;
-       else if (strncmp(argv[arg_base + idx_type]->text, "ns", 2) == 0)
+       else if (strncmp(type_name, "ns", 2) == 0)
                type = OSPF_AS_NSSA_LSA;
-       else if (strncmp(argv[arg_base + idx_type]->text, "s", 1) == 0)
+       else if (strncmp(type_name, "su", 2) == 0)
                type = OSPF_SUMMARY_LSA;
-       else if (strncmp(argv[arg_base + idx_type]->text, "a", 1) == 0)
+       else if (strncmp(type_name, "a", 1) == 0)
                type = OSPF_ASBR_SUMMARY_LSA;
-       else if (strncmp(argv[arg_base + idx_type]->text, "e", 1) == 0)
+       else if (strncmp(type_name, "e", 1) == 0)
                type = OSPF_AS_EXTERNAL_LSA;
-       else if (strncmp(argv[arg_base + idx_type]->text, "opaque-l", 8) == 0)
+       else if (strncmp(type_name, "opaque-l", 8) == 0)
                type = OSPF_OPAQUE_LINK_LSA;
-       else if (strncmp(argv[arg_base + idx_type]->text, "opaque-ar", 9) == 0)
+       else if (strncmp(type_name, "opaque-ar", 9) == 0)
                type = OSPF_OPAQUE_AREA_LSA;
-       else if (strncmp(argv[arg_base + idx_type]->text, "opaque-as", 9) == 0)
+       else if (strncmp(type_name, "opaque-as", 9) == 0)
                type = OSPF_OPAQUE_AS_LSA;
        else {
                if (uj) {
@@ -7376,155 +7206,119 @@ static int show_ip_ospf_database_type_adv_router_common(struct vty *vty,
                return CMD_WARNING;
        }
 
-       /* `show ip ospf database LSA adv-router ADV_ROUTER'. */
-       if (strncmp(argv[arg_base + 5]->text, "s", 1) == 0)
-               adv_router = ospf->router_id;
-       else {
-               ret = inet_aton(argv[arg_base + 6]->arg, &adv_router);
-               if (!ret) {
-                       if (uj) {
-                               if (use_vrf)
-                                       json_object_free(json_vrf);
-                       }
-                       return CMD_WARNING;
-               }
-       }
-
-       show_lsa_detail_adv_router(vty, ospf, type, &adv_router, json_vrf);
+       if (adv_router && !lsid)
+               show_lsa_detail_adv_router(vty, ospf, type, adv_router,
+                                          json_vrf);
+       else
+               show_lsa_detail(vty, ospf, type, lsid, adv_router, json_vrf);
 
        if (json) {
-               if (use_vrf)
-                       json_object_object_add(json, ospf_get_name(ospf),
-                                              json_vrf);
+               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_database_type_adv_router,
-       show_ip_ospf_database_type_adv_router_cmd,
-       "show ip ospf [vrf <NAME|all>] database <asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> <adv-router A.B.C.D|self-originate> [json]",
+DEFPY (show_ip_ospf_database,
+       show_ip_ospf_database_cmd,
+       "show ip ospf [(1-65535)$instance_id] [vrf <NAME|all>$vrf_name] database\
+         [<\
+          max-age$maxage\
+          |self-originate$selforig\
+          |<\
+            detail$detail\
+             |<asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as>$type_name\
+           >\
+           [{\
+             A.B.C.D$lsid\
+             |<adv-router A.B.C.D$adv_router|self-originate$adv_router_self>\
+           }]\
+        >]\
+        [json]",
        SHOW_STR
        IP_STR
        "OSPF information\n"
+       "Instance ID\n"
        VRF_CMD_HELP_STR
        "All VRFs\n"
        "Database summary\n"
+       "LSAs in MaxAge list\n"
+       "Self-originated link states\n"
+       "Show detailed information\n"
        OSPF_LSA_TYPES_DESC
+       "Link State ID (as an IP address)\n"
        "Advertising Router link states\n"
        "Advertising Router (as an IP address)\n"
        "Self-originated link states\n"
        JSON_STR)
 {
-       struct ospf *ospf = NULL;
-       struct listnode *node = NULL;
-       char *vrf_name = NULL;
-       bool all_vrf = false;
+       struct ospf *ospf;
        int ret = CMD_SUCCESS;
-       int inst = 0;
-       int idx_vrf = 0;
-       uint8_t use_vrf = 0;
+       bool use_vrf = !!vrf_name;
        bool uj = use_json(argc, argv);
+       struct in_addr *lsid_p = NULL;
+       struct in_addr *adv_router_p = NULL;
        json_object *json = NULL;
 
        if (uj)
                json = json_object_new_object();
+       if (lsid_str)
+               lsid_p = &lsid;
+       if (adv_router_str)
+               adv_router_p = &adv_router;
 
-       OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
-
-       if (vrf_name) {
+       if (vrf_name && strmatch(vrf_name, "all")) {
+               struct listnode *node;
                bool ospf_output = false;
 
-               use_vrf = 1;
+               for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+                       if (!ospf->oi_running)
+                               continue;
+                       if (ospf->instance != instance_id)
+                               continue;
 
-               if (all_vrf) {
-                       for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
-                               if (!ospf->oi_running)
-                                       continue;
-                               ospf_output = true;
-                               ret = show_ip_ospf_database_type_adv_router_common(
-                                       vty, ospf, 2, argc, argv, use_vrf, json,
-                                       uj);
-                       }
-                       if (!ospf_output)
-                               vty_out(vty, "%% OSPF is not enabled\n");
-               } else {
-                       ospf = ospf_lookup_by_inst_name(inst, vrf_name);
-                       if ((ospf == NULL) || !ospf->oi_running) {
-                               if (uj)
-                                       vty_json(vty, json);
-                               else
-                                       vty_out(vty,
-                                               "%% OSPF is not enabled in vrf %s\n",
-                                               vrf_name);
-                               return CMD_SUCCESS;
-                       }
+                       if (adv_router_self)
+                               adv_router_p = &ospf->router_id;
 
-                       ret = show_ip_ospf_database_type_adv_router_common(
-                               vty, ospf, 2, argc, argv, use_vrf, json, uj);
+                       ospf_output = true;
+                       ret = show_ip_ospf_database_common(
+                               vty, ospf, !!maxage, !!selforig, !!detail,
+                               type_name, lsid_p, adv_router_p, use_vrf, json,
+                               uj);
                }
+
+               if (!ospf_output && !uj)
+                       vty_out(vty, "%% OSPF is not enabled\n");
        } else {
-               /* Display default ospf (instance 0) info */
-               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+               if (!vrf_name)
+                       vrf_name = VRF_DEFAULT_NAME;
+               ospf = ospf_lookup_by_inst_name(instance_id, vrf_name);
                if (ospf == NULL || !ospf->oi_running) {
                        if (uj)
                                vty_json(vty, json);
                        else
-                               vty_out(vty,
-                                       "%% OSPF is not enabled on vrf default\n");
+                               vty_out(vty, "%% OSPF instance not found\n");
                        return CMD_SUCCESS;
                }
+               if (adv_router_self)
+                       adv_router_p = &ospf->router_id;
 
-               ret = show_ip_ospf_database_type_adv_router_common(
-                       vty, ospf, 0, argc, argv, use_vrf, json, uj);
-       }
-
-       if (uj) {
-               vty_out(vty, "%s\n", json_object_to_json_string(json));
-               json_object_free(json);
+               ret = (show_ip_ospf_database_common(
+                       vty, ospf, !!maxage, !!selforig, !!detail, type_name,
+                       lsid_p, adv_router_p, use_vrf, json, uj));
        }
 
-       return ret;
-}
-
-DEFUN (show_ip_ospf_instance_database_type_adv_router,
-       show_ip_ospf_instance_database_type_adv_router_cmd,
-       "show ip ospf (1-65535) 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"
-       "Instance ID\n"
-       "Database summary\n"
-       OSPF_LSA_TYPES_DESC
-       "Advertising Router link states\n"
-       "Advertising Router (as an IP address)\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);
-       if (instance != ospf_instance)
-               return CMD_NOT_MY_INSTANCE;
-
-       ospf = ospf_lookup_instance(instance);
-       if (!ospf || !ospf->oi_running)
-               return CMD_SUCCESS;
-
-       show_ip_ospf_database_type_adv_router_common(vty, ospf, 1, argc, argv,
-                                                    0, json, uj);
-
        if (uj)
                vty_json(vty, json);
 
-       return CMD_SUCCESS;
+       return ret;
 }
 
 DEFUN (ip_ospf_authentication_args,
@@ -12257,6 +12051,9 @@ static int config_write_ospf_area(struct vty *vty, struct ospf *ospf)
                if (PREFIX_NAME_OUT(area))
                        vty_out(vty, " area %s filter-list prefix %s out\n",
                                buf, PREFIX_NAME_OUT(area));
+
+               if (area->fr_info.configured)
+                       vty_out(vty, " area %s flood-reduction\n", buf);
        }
 
        return 0;
@@ -12634,6 +12431,9 @@ static int ospf_config_write_one(struct vty *vty, struct ospf *ospf)
        if (ospf->lsa_refresh_interval != OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
                vty_out(vty, " refresh timer %d\n", ospf->lsa_refresh_interval);
 
+       if (ospf->fr_configured)
+               vty_out(vty, " flood-reduction\n");
+
        /* Redistribute information print. */
        config_write_ospf_redistribute(vty, ospf);
 
@@ -12729,13 +12529,6 @@ void ospf_vty_show_init(void)
 
        /* "show ip ospf database" commands. */
        install_element(VIEW_NODE, &show_ip_ospf_database_cmd);
-       install_element(VIEW_NODE, &show_ip_ospf_database_max_cmd);
-       install_element(VIEW_NODE,
-                       &show_ip_ospf_database_type_adv_router_cmd);
-       install_element(VIEW_NODE,
-                       &show_ip_ospf_instance_database_type_adv_router_cmd);
-       install_element(VIEW_NODE, &show_ip_ospf_instance_database_cmd);
-       install_element(VIEW_NODE, &show_ip_ospf_instance_database_max_cmd);
 
        /* "show ip ospf interface" commands. */
        install_element(VIEW_NODE, &show_ip_ospf_interface_cmd);
@@ -13016,6 +12809,143 @@ DEFPY_HIDDEN(ospf_maxage_delay_timer, ospf_maxage_delay_timer_cmd,
        return CMD_SUCCESS;
 }
 
+/*
+ * ------------------------------------------------------------------------*
+ * Following is (vty) configuration functions for flood-reduction handling.
+ * ------------------------------------------------------------------------
+ */
+
+DEFPY(flood_reduction, flood_reduction_cmd, "flood-reduction",
+      "flood reduction feature\n")
+{
+       VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf)
+       struct ospf_area *area;
+       struct listnode *node;
+
+       /* Turn on the Flood Reduction feature for the router. */
+       if (!ospf->fr_configured) {
+               ospf->fr_configured = true;
+               OSPF_LOG_DEBUG(IS_DEBUG_OSPF_EVENT,
+                              "Flood Reduction: OFF -> ON");
+               for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
+                       if (area) {
+                               ospf_area_update_fr_state(area);
+                               ospf_refresh_area_self_lsas(area);
+                       }
+               }
+       }
+
+       return CMD_SUCCESS;
+}
+
+DEFPY(flood_reduction_area, flood_reduction_area_cmd,
+      "area <A.B.C.D|(0-4294967295)> flood-reduction",
+      "OSPF area parameters\n"
+      "OSPF area ID in IP address format\n"
+      "OSPF area ID as a decimal value\n"
+      "Enable flood reduction for area\n")
+{
+       VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf)
+       struct ospf_area *oa;
+       int idx = 1;
+       int format;
+       int ret;
+       const char *areaid;
+       struct in_addr area_id;
+
+       areaid = argv[idx]->arg;
+
+       ret = str2area_id(areaid, &area_id, &format);
+       if (ret < 0) {
+               vty_out(vty, "Please specify area by A.B.C.D|<0-4294967295>\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       oa = ospf_area_lookup_by_area_id(ospf, area_id);
+       if (!oa) {
+               vty_out(vty, "OSPF area ID not present\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       /* Turn on the Flood Reduction feature for the area. */
+       if (!oa->fr_info.configured) {
+               oa->fr_info.configured = true;
+               OSPF_LOG_DEBUG(IS_DEBUG_OSPF_EVENT,
+                              "Flood Reduction area %pI4 : OFF -> ON",
+                              &oa->area_id);
+               ospf_area_update_fr_state(oa);
+               ospf_refresh_area_self_lsas(oa);
+       }
+
+       return CMD_SUCCESS;
+}
+
+DEFPY(no_flood_reduction, no_flood_reduction_cmd, "no flood-reduction",
+      NO_STR "flood reduction feature\n")
+{
+       VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf)
+       struct listnode *node;
+       struct ospf_area *area;
+
+       /* Turn off the Flood Reduction feature for the router. */
+       if (ospf->fr_configured) {
+               ospf->fr_configured = false;
+               OSPF_LOG_DEBUG(IS_DEBUG_OSPF_EVENT,
+                              "Flood Reduction: ON -> OFF");
+               for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
+                       if (area) {
+                               ospf_area_update_fr_state(area);
+                               ospf_refresh_area_self_lsas(area);
+                       }
+               }
+       }
+
+       return CMD_SUCCESS;
+}
+
+DEFPY(no_flood_reduction_area, no_flood_reduction_area_cmd,
+      "no area <A.B.C.D|(0-4294967295)> flood-reduction",
+      NO_STR
+      "OSPF area parameters\n"
+      "OSPF area ID in IP address format\n"
+      "OSPF area ID as a decimal value\n"
+      "Disable flood reduction for area\n")
+{
+       VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf)
+       struct ospf_area *oa;
+       int idx = 2;
+       int format;
+       int ret;
+       const char *areaid;
+       struct in_addr area_id;
+
+       areaid = argv[idx]->arg;
+
+       ret = str2area_id(areaid, &area_id, &format);
+       if (ret < 0) {
+               vty_out(vty, "Please specify area by A.B.C.D|<0-4294967295>\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       oa = ospf_area_lookup_by_area_id(ospf, area_id);
+       if (!oa) {
+               vty_out(vty, "OSPF area ID not present\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       /* Turn off the Flood Reduction feature for the area. */
+       if (oa->fr_info.configured) {
+               oa->fr_info.configured = false;
+               OSPF_LOG_DEBUG(IS_DEBUG_OSPF_EVENT,
+                              "Flood Reduction area %pI4 : ON -> OFF",
+                              &oa->area_id);
+               ospf_area_update_fr_state(oa);
+               ospf_refresh_area_self_lsas(oa);
+       }
+
+       return CMD_SUCCESS;
+}
+
 void ospf_vty_clear_init(void)
 {
        install_element(ENABLE_NODE, &clear_ip_ospf_interface_cmd);
@@ -13176,6 +13106,12 @@ void ospf_vty_init(void)
        install_element(OSPF_NODE, &ospf_lsa_refresh_timer_cmd);
        install_element(OSPF_NODE, &ospf_maxage_delay_timer_cmd);
 
+       /* Flood Reduction commands */
+       install_element(OSPF_NODE, &flood_reduction_cmd);
+       install_element(OSPF_NODE, &no_flood_reduction_cmd);
+       install_element(OSPF_NODE, &flood_reduction_area_cmd);
+       install_element(OSPF_NODE, &no_flood_reduction_area_cmd);
+
        /* Init interface related vty commands. */
        ospf_vty_if_init();